@bi-nova/ui-weapp 1.1.1-beta.202605161224
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -0
- package/src/ad/README.md +287 -0
- package/src/ad/banner/index.js +243 -0
- package/src/ad/banner/index.json +3 -0
- package/src/ad/banner/index.wxml +38 -0
- package/src/ad/banner/index.wxss +132 -0
- package/src/ad/display/index.js +496 -0
- package/src/ad/display/index.json +7 -0
- package/src/ad/display/index.wxml +30 -0
- package/src/ad/display/index.wxss +1 -0
- package/src/ad/splash/index.js +782 -0
- package/src/ad/splash/index.json +3 -0
- package/src/ad/splash/index.wxml +74 -0
- package/src/ad/splash/index.wxss +257 -0
- package/src/ad/utils.js +139 -0
- package/src/bi-ad-card/index.js +17 -0
- package/src/bi-ad-card/index.json +4 -0
- package/src/bi-ad-card/index.wxml +8 -0
package/package.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bi-nova/ui-weapp",
|
|
3
|
+
"version": "1.1.1-beta.202605161224",
|
|
4
|
+
"description": "BI Nova SDK WeChat Mini Program Components",
|
|
5
|
+
"miniprogram": "src",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"files": [
|
|
8
|
+
"src"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"registry": "https://registry.npmjs.org",
|
|
12
|
+
"access": "public"
|
|
13
|
+
}
|
|
14
|
+
}
|
package/src/ad/README.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# WeApp 广告组件
|
|
2
|
+
|
|
3
|
+
`packages/ui-weapp/src/ad` 提供微信小程序广告展示能力。业务侧统一使用 `bi-display-ad` 接入,并通过我方提供的广告位 ID 获取广告内容;组件内部会根据广告类型渲染 Banner 或开屏广告。
|
|
4
|
+
|
|
5
|
+
## 组件说明
|
|
6
|
+
|
|
7
|
+
| 组件 | 路径 | 说明 |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `bi-display-ad` | `ad/display/index` | 广告统一接入组件,根据 `type` 渲染 Banner 或开屏广告,并通过 `adId` 获取广告位配置。 |
|
|
10
|
+
|
|
11
|
+
## 接入方式
|
|
12
|
+
|
|
13
|
+
业务页面只需要接入 `bi-display-ad`,并传入由我方分配的 `ad-id`。广告形态由 `type` 控制,组件会根据 `ad-id` 自动获取并展示对应广告。
|
|
14
|
+
|
|
15
|
+
### 安装依赖
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @bi-nova/core @bi-nova/services @bi-nova/ui-weapp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
如果项目使用 pnpm 或 yarn,也可以按项目包管理器安装:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm add @bi-nova/core @bi-nova/services @bi-nova/ui-weapp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add @bi-nova/core @bi-nova/services @bi-nova/ui-weapp
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 标准接入
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"usingComponents": {
|
|
36
|
+
"bi-display-ad": "/miniprogram_npm/@bi-nova/ui-weapp/ad/display/index"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```xml
|
|
42
|
+
<bi-display-ad
|
|
43
|
+
ad-id="ad_123456"
|
|
44
|
+
type="banner"
|
|
45
|
+
bind:load="handleAdLoad"
|
|
46
|
+
bind:error="handleAdError"
|
|
47
|
+
bind:close="handleAdClose"
|
|
48
|
+
bind:action="handleAdAction"
|
|
49
|
+
bind:openWebview="handleAdOpenWebview"
|
|
50
|
+
/>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> 具体组件路径以项目构建后的 `miniprogram_npm` 目录为准。如果项目采用源码复制或 monorepo 直接引用方式,请按实际目录调整 `usingComponents` 路径。
|
|
54
|
+
|
|
55
|
+
## 组件属性
|
|
56
|
+
|
|
57
|
+
`bi-display-ad` 是广告组件的标准接入入口。业务侧仅需关注广告位 ID、广告类型和必要的展示控制参数。
|
|
58
|
+
|
|
59
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
60
|
+
| --- | --- | --- | --- |
|
|
61
|
+
| `ad-id` | `string` | `''` | 我方分配的广告位 ID。组件会根据该 ID 获取广告位配置并展示广告。 |
|
|
62
|
+
| `type` | `'banner' \| 'splash'` | `'banner'` | 广告类型。仅支持 `banner` 和 `splash`。 |
|
|
63
|
+
| `show` | `boolean` | `true` | 是否展示广告。对开屏广告的显隐控制更常用。 |
|
|
64
|
+
| `z-index` | `number` | `999` | 开屏广告容器层级。 |
|
|
65
|
+
| `picture-in-picture` | `boolean` | `false` | 开屏广告跳过后是否进入画中画状态。 |
|
|
66
|
+
| `check-native-splash` | `boolean` | `true` | 开屏广告是否先检查微信系统开屏广告状态,设置为 `false` 可用于真机调试或强制展示远程开屏广告。 |
|
|
67
|
+
| `native-splash-cache` | `boolean` | `true` | 是否缓存微信系统开屏广告承接记录,用于短时间内连续扫码时跳过残留的微信开屏状态检查。 |
|
|
68
|
+
| `jump-seconds` | `number` | `5` | 开屏广告倒计时秒数。 |
|
|
69
|
+
|
|
70
|
+
## 广告位配置
|
|
71
|
+
|
|
72
|
+
接入前需要先向我方申请广告位,并获取对应的 `ad-id`。业务页面传入 `ad-id` 后,组件会通过已注入的业务 SDK 获取该广告位的展示配置。
|
|
73
|
+
|
|
74
|
+
广告位配置由我方维护,通常包含实际投放渠道、广告素材、展示开关等信息。业务方一般不需要关心底层配置结构,只需要确保传入的 `ad-id` 与投放场景一致。
|
|
75
|
+
|
|
76
|
+
使用 `ad-id` 前,请确认 SDK 已完成以下初始化:
|
|
77
|
+
|
|
78
|
+
1. 通过 `createNova` 创建 SDK 实例,并在微信小程序环境开启 `autoEnv: true`。
|
|
79
|
+
2. 通过 `createServices` 注册服务插件,广告位配置能力由该插件提供。
|
|
80
|
+
3. 在广告组件渲染前,将 SDK 实例挂载到 `app.biNova`。
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
const { createNova } = require('@bi-nova/core')
|
|
84
|
+
const { createServices } = require('@bi-nova/services')
|
|
85
|
+
|
|
86
|
+
App({
|
|
87
|
+
onLaunch() {
|
|
88
|
+
const biNova = createNova({
|
|
89
|
+
appId: 'your-app-id',
|
|
90
|
+
autoEnv: true
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
biNova.use(createServices({
|
|
94
|
+
env: 'prod',
|
|
95
|
+
debug: false
|
|
96
|
+
}))
|
|
97
|
+
|
|
98
|
+
this.biNova = biNova
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 登录态说明
|
|
104
|
+
|
|
105
|
+
`bi-display-ad` 获取广告位配置不需要 token。仅接入广告组件时,业务方只需要创建并注入全局 `biNova` 实例,不需要等待用户登录。
|
|
106
|
+
|
|
107
|
+
如果同一个 `biNova` 实例还会调用 `handleJdjrCashLoanFlow` 等需要登录态的服务,请在用户登录成功后写入 token:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
getApp().globalData.biNova.setToken(loginResult.token)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
用户退出登录或 token 失效时清理:
|
|
114
|
+
|
|
115
|
+
```js
|
|
116
|
+
getApp().globalData.biNova.clearToken()
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
广告组件不会因为未写入 token 而阻塞广告配置请求。
|
|
120
|
+
|
|
121
|
+
> `createNova` 中的 `appId` 用于 SDK 和小程序运行上下文初始化,广告配置请求以组件传入的 `ad-id` 为准。
|
|
122
|
+
|
|
123
|
+
## Banner 广告
|
|
124
|
+
|
|
125
|
+
通过 `bi-display-ad` 设置 `type="banner"` 即可展示 Banner 广告。
|
|
126
|
+
|
|
127
|
+
```xml
|
|
128
|
+
<bi-display-ad
|
|
129
|
+
ad-id="ad_123456"
|
|
130
|
+
type="banner"
|
|
131
|
+
bind:load="handleAdLoad"
|
|
132
|
+
bind:error="handleAdError"
|
|
133
|
+
bind:close="handleAdClose"
|
|
134
|
+
bind:action="handleAdAction"
|
|
135
|
+
bind:openWebview="handleAdOpenWebview"
|
|
136
|
+
/>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`ad-id` 需要使用 Banner 类型广告位,具体广告位 ID 请向我方获取。
|
|
140
|
+
|
|
141
|
+
## 开屏广告
|
|
142
|
+
|
|
143
|
+
通过 `bi-display-ad` 设置 `type="splash"` 即可展示开屏广告。
|
|
144
|
+
|
|
145
|
+
```xml
|
|
146
|
+
<bi-display-ad
|
|
147
|
+
ad-id="launch_splash"
|
|
148
|
+
type="splash"
|
|
149
|
+
show="{{showSplash}}"
|
|
150
|
+
z-index="{{999}}"
|
|
151
|
+
picture-in-picture="{{true}}"
|
|
152
|
+
jump-seconds="{{5}}"
|
|
153
|
+
bind:load="handleAdLoad"
|
|
154
|
+
bind:error="handleAdError"
|
|
155
|
+
bind:close="handleAdClose"
|
|
156
|
+
bind:hide="handleAdHide"
|
|
157
|
+
bind:action="handleAdAction"
|
|
158
|
+
bind:openWebview="handleAdOpenWebview"
|
|
159
|
+
/>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
开屏广告支持微信原生广告、自定义图片广告、自定义视频广告,并提供倒计时跳过和画中画能力。
|
|
163
|
+
|
|
164
|
+
建议承载开屏广告的页面在页面配置中设置 `"navigationStyle": "custom"`,隐藏默认导航栏后开屏广告展示更完整,整体视觉效果更好。
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"navigationStyle": "custom"
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`ad-id` 需要使用开屏类型广告位,具体广告位 ID 请向我方获取。
|
|
173
|
+
|
|
174
|
+
## 广告素材能力
|
|
175
|
+
|
|
176
|
+
以下字段由广告位配置生成,业务方通常不需要在页面中直接传入。这里仅用于说明广告素材支持的配置能力,便于和我方确认广告位需求。
|
|
177
|
+
|
|
178
|
+
### 通用字段
|
|
179
|
+
|
|
180
|
+
| 字段 | 类型 | 说明 |
|
|
181
|
+
| --- | --- | --- |
|
|
182
|
+
| `image` / `imageUrl` | `string` | 图片素材地址。Banner 广告和开屏图片广告使用。 |
|
|
183
|
+
| `title` | `string` | 广告标题。 |
|
|
184
|
+
| `description` | `string` | 广告描述。 |
|
|
185
|
+
| `buttonText` | `string` | 操作按钮文案。 |
|
|
186
|
+
| `badgeText` / `adLabel` | `string` | 广告角标文案,默认 `广告`。 |
|
|
187
|
+
| `loadTimeout` / `timeout` | `number` | 自定义素材加载超时时间,单位毫秒,最小值为 `1000`,默认 `5000`。 |
|
|
188
|
+
|
|
189
|
+
### 开屏扩展字段
|
|
190
|
+
|
|
191
|
+
| 字段 | 类型 | 说明 |
|
|
192
|
+
| --- | --- | --- |
|
|
193
|
+
| `video` / `videoUrl` | `string` | 视频素材地址。存在时开屏广告按视频广告渲染。 |
|
|
194
|
+
| `poster` | `string` | 视频封面地址。未传时优先使用 `image`。 |
|
|
195
|
+
| `muted` | `boolean` | 视频是否静音。默认静音,传 `false` 可开启声音。 |
|
|
196
|
+
| `jumpSeconds` | `number` | 当前广告独立倒计时秒数,优先级高于组件 `jump-seconds`。 |
|
|
197
|
+
| `adSpec` / `spec` | `1 \| 2` | 广告规格,`1` 为横版,`2` 为竖版。 |
|
|
198
|
+
| `width` / `videoWidth` | `number` | 素材宽度,用于推断广告规格。 |
|
|
199
|
+
| `height` / `videoHeight` | `number` | 素材高度,用于推断广告规格。 |
|
|
200
|
+
|
|
201
|
+
### 跳转字段
|
|
202
|
+
|
|
203
|
+
| 跳转类型 | 字段 | 说明 |
|
|
204
|
+
| --- | --- | --- |
|
|
205
|
+
| 跳转其他小程序 | `appId` / `miniProgramAppId` / `jumpAppId` | 目标小程序 appId。 |
|
|
206
|
+
| 跳转小程序内部页面 | `path` / `pagePath` / `jumpPath` / `targetUrl` | 当前小程序页面路径。 |
|
|
207
|
+
| 打开 WebView | `url` / `webUrl` / `h5Url` / `jumpUrl` | H5 地址。组件不会直接打开 WebView,会触发 `openWebview` 事件交给业务处理。 |
|
|
208
|
+
|
|
209
|
+
跳转优先级为:其他小程序 > 小程序内部页面 > WebView。
|
|
210
|
+
|
|
211
|
+
### 示例
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
Page({
|
|
215
|
+
data: {
|
|
216
|
+
bannerAdId: 'ad_123456',
|
|
217
|
+
splashAdId: 'launch_splash'
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## 事件
|
|
223
|
+
|
|
224
|
+
### 通用事件
|
|
225
|
+
|
|
226
|
+
| 事件名 | 说明 | 事件详情 |
|
|
227
|
+
| --- | --- | --- |
|
|
228
|
+
| `load` | 广告加载完成 | `{ provider, type, adId? }` |
|
|
229
|
+
| `error` | 广告加载、配置或跳转失败 | `{ provider?, type, adId?, errCode, errMsg }` |
|
|
230
|
+
| `close` | 广告关闭 | `{ provider, type, adId? }` |
|
|
231
|
+
| `action` | 自定义广告点击 | `{ provider, type, adId? }` |
|
|
232
|
+
| `openWebview` | 自定义广告命中 WebView 跳转 | `{ provider, type, adId?, url }` |
|
|
233
|
+
|
|
234
|
+
### 统一广告组件扩展事件
|
|
235
|
+
|
|
236
|
+
| 事件名 | 说明 | 事件详情 |
|
|
237
|
+
| --- | --- | --- |
|
|
238
|
+
| `configload` | 广告位配置加载成功 | `{ type, adId, requestOptions, data }` |
|
|
239
|
+
| `configerror` | 广告位配置加载失败或 SDK 未就绪 | `{ type, adId, errCode, errMsg }` |
|
|
240
|
+
|
|
241
|
+
### 开屏广告扩展事件
|
|
242
|
+
|
|
243
|
+
| 事件名 | 说明 | 事件详情 |
|
|
244
|
+
| --- | --- | --- |
|
|
245
|
+
| `hide` | 开屏广告进入画中画状态 | `{ provider, type }` |
|
|
246
|
+
|
|
247
|
+
## WebView 跳转处理
|
|
248
|
+
|
|
249
|
+
自定义广告配置 Web 地址时,组件只负责识别并抛出 `openWebview` 事件,业务侧需要自行跳转到承载 H5 的 WebView 页面。
|
|
250
|
+
|
|
251
|
+
```js
|
|
252
|
+
Page({
|
|
253
|
+
handleAdOpenWebview(event) {
|
|
254
|
+
const url = encodeURIComponent(event.detail.url)
|
|
255
|
+
|
|
256
|
+
wx.navigateTo({
|
|
257
|
+
url: `/pages/webview/index?url=${url}`
|
|
258
|
+
})
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## 错误码
|
|
264
|
+
|
|
265
|
+
| 错误码 | 说明 |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| `DISPLAY_AD_SDK_NOT_READY` | 使用 `ad-id` 获取广告位配置时,未获取到可用的全局 SDK 实例。 |
|
|
268
|
+
| `DISPLAY_AD_REMOTE_CONFIG_FAIL` | 广告位配置接口返回失败。 |
|
|
269
|
+
| `DISPLAY_AD_REMOTE_CONFIG_EXCEPTION` | 广告位配置请求异常。 |
|
|
270
|
+
| `UNSUPPORTED_DISPLAY_AD_TYPE` | `type` 不是 `banner` 或 `splash`。 |
|
|
271
|
+
| `BI_BANNER_CUSTOM_MEDIA_LOAD_TIMEOUT` | Banner 自定义图片加载超时。 |
|
|
272
|
+
| `BI_BANNER_CUSTOM_MEDIA_LOAD_FAIL` | Banner 自定义图片加载失败。 |
|
|
273
|
+
| `BI_BANNER_NAVIGATE_MINI_PROGRAM_FAIL` | Banner 自定义广告跳转其他小程序失败。 |
|
|
274
|
+
| `BI_BANNER_NAVIGATE_FAIL` | Banner 自定义广告跳转内部页面失败。 |
|
|
275
|
+
| `BI_SPLASH_WECHAT_AD_LOAD_FAIL` | 微信开屏广告加载失败。 |
|
|
276
|
+
| `BI_SPLASH_CUSTOM_MEDIA_LOAD_TIMEOUT` | 开屏自定义素材加载超时。 |
|
|
277
|
+
| `BI_SPLASH_CUSTOM_MEDIA_LOAD_FAIL` | 开屏自定义素材加载失败。 |
|
|
278
|
+
| `BI_SPLASH_NAVIGATE_MINI_PROGRAM_FAIL` | 开屏自定义广告跳转其他小程序失败。 |
|
|
279
|
+
| `BI_SPLASH_NAVIGATE_FAIL` | 开屏自定义广告跳转内部页面失败。 |
|
|
280
|
+
|
|
281
|
+
## 注意事项
|
|
282
|
+
|
|
283
|
+
1. `ad-id` 由我方统一分配,请确保广告位类型与组件 `type` 保持一致。
|
|
284
|
+
2. 开屏广告会优先检查微信系统开屏广告状态,避免和系统开屏广告重复展示。
|
|
285
|
+
3. WebView 地址不会由组件直接打开,必须由业务页面监听 `openWebview` 后处理。
|
|
286
|
+
4. 使用 `ad-id` 前,需要先把业务 SDK 实例挂载到 `app.biNova`。
|
|
287
|
+
5. 开屏广告页面推荐设置 `"navigationStyle": "custom"`,避免默认导航栏占用展示空间,提升开屏展示效果。
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Description Banner 广告组件
|
|
3
|
+
* @Author wutao
|
|
4
|
+
* @Date 2026-04-10
|
|
5
|
+
* @LastEditors wutao
|
|
6
|
+
* @LastEditTime 2026-04-17
|
|
7
|
+
*/
|
|
8
|
+
const {
|
|
9
|
+
navigateCustomAd
|
|
10
|
+
} = require('../utils')
|
|
11
|
+
|
|
12
|
+
Component({
|
|
13
|
+
properties: {
|
|
14
|
+
unitId: { type: String, value: '' },
|
|
15
|
+
customAd: { type: Object, value: null },
|
|
16
|
+
adIntervals: { type: Number, value: 30 }
|
|
17
|
+
},
|
|
18
|
+
data: {
|
|
19
|
+
isWechatAd: false,
|
|
20
|
+
customLoaded: false,
|
|
21
|
+
customFailed: false
|
|
22
|
+
},
|
|
23
|
+
lifetimes: {
|
|
24
|
+
attached() {
|
|
25
|
+
this.syncProvider(this.properties.unitId)
|
|
26
|
+
this.resetCustomLoadState()
|
|
27
|
+
},
|
|
28
|
+
detached() {
|
|
29
|
+
this.clearCustomLoadTimeout()
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
observers: {
|
|
33
|
+
'unitId, customAd'(nextUnitId) {
|
|
34
|
+
this.syncProvider(nextUnitId)
|
|
35
|
+
this.resetCustomLoadState()
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
methods: {
|
|
39
|
+
/**
|
|
40
|
+
* 创建 Banner 事件基础数据
|
|
41
|
+
* @param {'wechat' | 'custom'} provider 广告提供方
|
|
42
|
+
* @returns {{provider: 'wechat' | 'custom', type: 'banner'}}
|
|
43
|
+
*/
|
|
44
|
+
createEventDetail(provider) {
|
|
45
|
+
return {
|
|
46
|
+
provider,
|
|
47
|
+
type: 'banner'
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 合并广告事件数据
|
|
53
|
+
* @param {'wechat' | 'custom'} provider 广告提供方
|
|
54
|
+
* @param {Record<string, any>} [event] 原始事件对象
|
|
55
|
+
* @returns {Record<string, any>}
|
|
56
|
+
*/
|
|
57
|
+
resolveEventDetail(provider, event, extraDetail) {
|
|
58
|
+
const baseDetail = this.createEventDetail(provider)
|
|
59
|
+
const detail = event && event.detail && typeof event.detail === 'object' ? event.detail : null
|
|
60
|
+
|
|
61
|
+
if (detail) {
|
|
62
|
+
return {
|
|
63
|
+
...baseDetail,
|
|
64
|
+
...detail,
|
|
65
|
+
...extraDetail
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (event && typeof event === 'object') {
|
|
70
|
+
return {
|
|
71
|
+
...baseDetail,
|
|
72
|
+
...event,
|
|
73
|
+
...extraDetail
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
...baseDetail,
|
|
79
|
+
...extraDetail
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 根据 `unitId` 同步广告来源
|
|
85
|
+
* @param {string} unitId 微信广告位 ID
|
|
86
|
+
* @returns {void}
|
|
87
|
+
*/
|
|
88
|
+
syncProvider(unitId) {
|
|
89
|
+
this.setData({ isWechatAd: Boolean(unitId) })
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* 获取自定义广告素材加载超时时间
|
|
94
|
+
* @returns {number}
|
|
95
|
+
*/
|
|
96
|
+
getCustomLoadTimeout() {
|
|
97
|
+
/** @type {Record<string, any> | null} 自定义广告数据 */
|
|
98
|
+
const customAd = this.properties.customAd
|
|
99
|
+
/** 自定义超时时间,单位毫秒 */
|
|
100
|
+
const timeout = customAd && (customAd.loadTimeout || customAd.timeout)
|
|
101
|
+
|
|
102
|
+
return Math.max(1000, Number(timeout) || 5000)
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 重置自定义广告加载状态
|
|
107
|
+
* @returns {void}
|
|
108
|
+
*/
|
|
109
|
+
resetCustomLoadState() {
|
|
110
|
+
this.clearCustomLoadTimeout()
|
|
111
|
+
this.setData({
|
|
112
|
+
customLoaded: false,
|
|
113
|
+
customFailed: false
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
if (this.properties.unitId || !this.properties.customAd || !this.properties.customAd.image) return
|
|
117
|
+
|
|
118
|
+
this.customLoadTimer = setTimeout(() => {
|
|
119
|
+
this.handleCustomLoadTimeout()
|
|
120
|
+
}, this.getCustomLoadTimeout())
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 清理自定义广告加载超时定时器
|
|
125
|
+
* @returns {void}
|
|
126
|
+
*/
|
|
127
|
+
clearCustomLoadTimeout() {
|
|
128
|
+
if (this.customLoadTimer) {
|
|
129
|
+
clearTimeout(this.customLoadTimer)
|
|
130
|
+
this.customLoadTimer = null
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 处理广告加载完成事件
|
|
136
|
+
* @param {Record<string, any>} event 广告加载事件
|
|
137
|
+
* @returns {void}
|
|
138
|
+
*/
|
|
139
|
+
handleLoad(event) {
|
|
140
|
+
this.triggerEvent('load', this.resolveEventDetail('wechat', event))
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* 处理广告错误事件
|
|
145
|
+
* @param {Record<string, any>} event 广告错误事件
|
|
146
|
+
* @returns {void}
|
|
147
|
+
*/
|
|
148
|
+
handleError(event) {
|
|
149
|
+
this.triggerEvent('error', this.resolveEventDetail('wechat', event))
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 处理广告关闭事件
|
|
154
|
+
* @param {Record<string, any>} event 广告关闭事件
|
|
155
|
+
* @returns {void}
|
|
156
|
+
*/
|
|
157
|
+
handleClose(event) {
|
|
158
|
+
this.triggerEvent('close', this.resolveEventDetail('wechat', event))
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 处理自定义广告加载完成事件
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
165
|
+
handleCustomLoad() {
|
|
166
|
+
if (this.data.customLoaded) return
|
|
167
|
+
|
|
168
|
+
this.clearCustomLoadTimeout()
|
|
169
|
+
this.setData({ customLoaded: true })
|
|
170
|
+
this.triggerEvent('load', this.createEventDetail('custom'))
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 处理自定义广告素材加载超时事件
|
|
175
|
+
* @returns {void}
|
|
176
|
+
*/
|
|
177
|
+
handleCustomLoadTimeout() {
|
|
178
|
+
if (this.data.customLoaded || this.data.customFailed) return
|
|
179
|
+
|
|
180
|
+
this.setData({ customFailed: true })
|
|
181
|
+
this.triggerEvent('error', this.resolveEventDetail('custom', null, {
|
|
182
|
+
errCode: 'BI_BANNER_CUSTOM_MEDIA_LOAD_TIMEOUT',
|
|
183
|
+
errMsg: 'Banner 广告素材加载超时'
|
|
184
|
+
}))
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 处理自定义广告素材加载失败事件
|
|
189
|
+
* @param {Record<string, any>} event 素材错误事件
|
|
190
|
+
* @returns {void}
|
|
191
|
+
*/
|
|
192
|
+
handleCustomMediaError(event) {
|
|
193
|
+
if (this.data.customFailed) return
|
|
194
|
+
|
|
195
|
+
this.clearCustomLoadTimeout()
|
|
196
|
+
this.setData({ customFailed: true })
|
|
197
|
+
this.triggerEvent('error', this.resolveEventDetail('custom', event, {
|
|
198
|
+
errCode: 'BI_BANNER_CUSTOM_MEDIA_LOAD_FAIL',
|
|
199
|
+
errMsg: 'Banner 广告素材加载失败'
|
|
200
|
+
}))
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 处理自定义广告点击事件
|
|
205
|
+
* @returns {void}
|
|
206
|
+
*/
|
|
207
|
+
handleCustomAction() {
|
|
208
|
+
const actionDetail = this.createEventDetail('custom')
|
|
209
|
+
|
|
210
|
+
this.triggerEvent('action', actionDetail)
|
|
211
|
+
this.handleCustomNavigation(actionDetail)
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 处理自定义广告关闭事件
|
|
216
|
+
* @returns {void}
|
|
217
|
+
*/
|
|
218
|
+
handleCustomClose() {
|
|
219
|
+
this.triggerEvent('close', this.createEventDetail('custom'))
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 处理自定义广告跳转逻辑
|
|
224
|
+
* @param {Record<string, any>} actionDetail 点击事件载荷
|
|
225
|
+
* @returns {void}
|
|
226
|
+
*/
|
|
227
|
+
handleCustomNavigation(actionDetail) {
|
|
228
|
+
navigateCustomAd({
|
|
229
|
+
customAd: this.properties.customAd,
|
|
230
|
+
actionDetail,
|
|
231
|
+
onOpenWebview: (detail) => {
|
|
232
|
+
this.triggerEvent('openWebview', detail)
|
|
233
|
+
},
|
|
234
|
+
onError: (detail) => {
|
|
235
|
+
this.triggerEvent('error', detail)
|
|
236
|
+
},
|
|
237
|
+
resolveEventDetail: (provider, event, extraDetail) => this.resolveEventDetail(provider, event, extraDetail),
|
|
238
|
+
miniProgramErrorCode: 'BI_BANNER_NAVIGATE_MINI_PROGRAM_FAIL',
|
|
239
|
+
navigateErrorCode: 'BI_BANNER_NAVIGATE_FAIL'
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<ad-custom
|
|
2
|
+
wx:if="{{isWechatAd && unitId}}"
|
|
3
|
+
unit-id="{{unitId}}"
|
|
4
|
+
ad-intervals="{{adIntervals}}"
|
|
5
|
+
bind:load="handleLoad"
|
|
6
|
+
bind:error="handleError"
|
|
7
|
+
bind:close="handleClose"
|
|
8
|
+
/>
|
|
9
|
+
|
|
10
|
+
<view
|
|
11
|
+
wx:elif="{{customAd && customAd.image && !customFailed}}"
|
|
12
|
+
class="bi-banner-ad"
|
|
13
|
+
>
|
|
14
|
+
<view class="bi-banner-ad__surface" bindtap="handleCustomAction">
|
|
15
|
+
<view class="bi-banner-ad__media">
|
|
16
|
+
<text class="bi-banner-ad__badge bi-banner-ad__badge--overlay">{{customAd.badgeText || '广告'}}</text>
|
|
17
|
+
<image
|
|
18
|
+
class="bi-banner-ad__image"
|
|
19
|
+
src="{{customAd.image}}"
|
|
20
|
+
mode="aspectFill"
|
|
21
|
+
bindload="handleCustomLoad"
|
|
22
|
+
binderror="handleCustomMediaError"
|
|
23
|
+
/>
|
|
24
|
+
</view>
|
|
25
|
+
<view class="bi-banner-ad__content">
|
|
26
|
+
<view class="bi-banner-ad__body">
|
|
27
|
+
<text wx:if="{{customAd.title}}" class="bi-banner-ad__title">{{customAd.title}}</text>
|
|
28
|
+
</view>
|
|
29
|
+
<view class="bi-banner-ad__footer">
|
|
30
|
+
<text wx:if="{{customAd.description}}" class="bi-banner-ad__description">{{customAd.description}}</text>
|
|
31
|
+
<button class="bi-banner-ad__button" catchtap="handleCustomAction">
|
|
32
|
+
{{customAd.buttonText || '立即查看'}}
|
|
33
|
+
</button>
|
|
34
|
+
</view>
|
|
35
|
+
</view>
|
|
36
|
+
</view>
|
|
37
|
+
<button class="bi-banner-ad__close" catchtap="handleCustomClose">×</button>
|
|
38
|
+
</view>
|