@quicktvui/tv-ad-unlock 1.1.0 → 1.1.2

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/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @quicktvui/tv-ad-unlock
2
2
 
3
- TV广告解锁组件,用于QuickTVUI框架的电视端广告解锁功能。
3
+ TV 广告解锁组件 — 用于 QuickTVUI 框架的电视端广告解锁功能。
4
4
 
5
5
  ## 功能特性
6
6
 
7
- - 生成电视端广告二维码
8
- - 轮询广告观看状态
9
- - 自动管理解锁状态
10
- - 支持自定义配置
7
+ - 电视端扫码观看广告,自动解锁
8
+ - 内置广告弹窗页面(二维码 + 状态展示)
9
+ - 积分信用体系(每日解锁 / 永久解锁 / 按次扣费)
10
+ - 通过 Vue 插件注册,零配置路由
11
11
 
12
12
  ## 安装
13
13
 
@@ -15,139 +15,212 @@ TV广告解锁组件,用于QuickTVUI框架的电视端广告解锁功能。
15
15
  pnpm add @quicktvui/tv-ad-unlock
16
16
  ```
17
17
 
18
- ## 使用方法
18
+ **Peer Dependencies**(需项目已安装):
19
19
 
20
- ### 1. 基础使用
20
+ - `vue ^3.0.0`
21
+ - `@extscreen/es3-core >=3.0.0`
22
+ - `@extscreen/es3-router >=3.0.0`
21
23
 
22
- ```vue
23
- <template>
24
- <TVAdUnlock
25
- :config="adConfig"
26
- :storageKeys="storageKeys"
27
- :requestManager="requestManager"
28
- @unlockSuccess="onUnlockSuccess"
29
- @unlockFailed="onUnlockFailed"
30
- />
31
- </template>
32
-
33
- <script setup lang="ts">
34
- import { TVAdUnlock, useTVAdUnlockStorage } from '@quicktvui/tv-ad-unlock'
35
- import type { TVAdUnlockConfig, TVAdUnlockStorageKeys, RequestManager } from '@quicktvui/tv-ad-unlock'
36
-
37
- const adConfig: TVAdUnlockConfig = {
38
- packageName: 'com.example.app',
39
- superRequestBaseUrl: 'https://superapi.extscreen.com/extscreenapi/api',
40
- invalidTimeout: 300000,
41
- pollInterval: 1000
42
- }
24
+ ## 快速开始
43
25
 
44
- const storageKeys: TVAdUnlockStorageKeys = {
45
- playCountKey: 'app_play_count',
46
- unlockDateKey: 'app_ad_unlock_date',
47
- unlockedTodayKey: 'app_ad_unlocked_today'
48
- }
26
+ ### 1. 注册插件 & 路由(main-native.ts)
49
27
 
50
- const requestManager: RequestManager = {
51
- post: async (url, data) => { /* 实现请求逻辑 */ },
52
- get: async (url, data) => { /* 实现请求逻辑 */ }
53
- }
28
+ ```typescript
29
+ import { createESRouter } from '@extscreen/es3-router'
30
+ import { createESApp } from '@extscreen/es3-core'
31
+ import { tvAdUnlockPlugin, createTVAdRoute } from '@quicktvui/tv-ad-unlock'
32
+ import routes from './routes'
33
+
34
+ // 将广告路由加入路由表
35
+ const adRoute = createTVAdRoute()
36
+ routes.push({ ...adRoute, launchMode: 'standard' })
37
+
38
+ const router = createESRouter({ main: 'index', error: 'error', limit: 10, routes })
39
+ const app = createESApp(App, router)
40
+
41
+ // 注册广告解锁插件
42
+ app.use(tvAdUnlockPlugin, {
43
+ requestManager: myRequestManager, // 必填,实现 post/get 的请求管理器
44
+ // superRequestBaseUrl: 'https://superapi.extscreen.com/extscreenapi/api', // 可选,这是默认值
45
+ pageConfig: {
46
+ scanTitle: '观看广告获得积分',
47
+ scanContent: '观看广告后可获得5积分,用于游戏提示',
48
+ scanToast: '积分已发放,请返回游戏'
49
+ }
50
+ })
51
+ ```
54
52
 
55
- function onUnlockSuccess() {
56
- console.log('解锁成功')
57
- }
53
+ ### 2. 在页面中使用(页面 setup 中调用)
58
54
 
59
- function onUnlockFailed(error: Error) {
60
- console.error('解锁失败', error)
61
- }
55
+ ```vue
56
+ <script lang="ts">
57
+ import { defineComponent } from 'vue'
58
+ import { useTVAdNavigator } from '@quicktvui/tv-ad-unlock'
59
+
60
+ export default defineComponent({
61
+ setup() {
62
+ const adNavigator = useTVAdNavigator({
63
+ packageName: 'com.example.myapp',
64
+ initialCredits: 0, // 初始积分(默认 5)
65
+ creditsPerAd: 5, // 每次看广告获得积分(默认 5)
66
+ dailyUnlockEnabled: true, // 每日解锁开关(默认 true)
67
+ permanentUnlockAfterTotalAds: 10 // 看满N次广告永久解锁(默认 10,设0关闭)
68
+ })
69
+
70
+ // 在需要弹广告的地方调用
71
+ async function onNeedFeature() {
72
+ const showedAd = await adNavigator.consumeAndNavigate()
73
+ if (!showedAd) {
74
+ // 未弹广告(有积分或已解锁),直接执行业务逻辑
75
+ }
76
+ // showedAd === true 表示已跳转广告页,广告观看完成后会自动返回
77
+ }
78
+
79
+ return { onNeedFeature }
80
+ }
81
+ })
62
82
  </script>
63
83
  ```
64
84
 
65
- ### 2. 使用 Composable
85
+ ## API 参考
66
86
 
67
- ```typescript
68
- import { useTVAdUnlock, useTVAdUnlockStorage } from '@quicktvui/tv-ad-unlock'
69
- import { useESLocalStorage } from '@extscreen/es3-core'
87
+ ### 插件选项 `TVAdUnlockPluginOptions`
70
88
 
71
- const storage = useESLocalStorage()
89
+ `app.use(tvAdUnlockPlugin, options)` 的第二个参数:
72
90
 
73
- const storageKeys = {
74
- playCountKey: 'app_play_count',
75
- unlockDateKey: 'app_ad_unlock_date',
76
- unlockedTodayKey: 'app_ad_unlocked_today'
77
- }
91
+ | 字段 | 类型 | 必填 | 默认值 | 说明 |
92
+ |------|------|------|--------|------|
93
+ | `requestManager` | `RequestManager` | 是 | - | 请求管理器,需实现 `post` 和 `get` |
94
+ | `superRequestBaseUrl` | `string` | 否 | `https://superapi.extscreen.com/extscreenapi/api` | 广告接口基地址 |
95
+ | `pageConfig` | `TVAdUnlockPageConfig` | 否 | 见下方 | 广告弹窗页面 UI 文案配置 |
96
+ | `trackEvent` | `(event) => void` | 否 | - | 埋点回调 |
78
97
 
79
- const adStorage = useTVAdUnlockStorage(storage, storageKeys, 32)
98
+ ### 页面文案配置 `TVAdUnlockPageConfig`
80
99
 
81
- async function checkNeedShowAd() {
82
- const needAd = await adStorage.checkNeedAd()
83
- if (needAd) {
84
- router.push({ name: 'ad' })
85
- }
86
- }
100
+ | 字段 | 默认值 | 说明 |
101
+ |------|--------|------|
102
+ | `title` | `'观看30秒广告 当日解锁'` | 弹窗标题 |
103
+ | `subTitle` | `'手机打开【微信】扫码'` | 弹窗副标题 |
104
+ | `scanTitle` | `'观看奖励'` | 手机端扫码页标题 |
105
+ | `scanContent` | `'观看广告后可获得奖励'` | 手机端扫码页内容 |
106
+ | `scanToast` | `'奖励已获得,请前往电视端观看'` | 手机端观看后提示 |
107
+ | `invalidCodeImage` | 内置图片 | 二维码失效时展示的图片 URL |
108
+ | `scannedCodeImage` | 内置图片 | 已扫码状态展示的图片 URL |
109
+
110
+ ### 路由配置 `createTVAdRoute()`
111
+
112
+ 返回一条广告弹窗路由对象,需推入路由表:
113
+
114
+ ```typescript
115
+ const adRoute = createTVAdRoute()
116
+ // 返回: { path: '/ad', name: 'ad', component: TVAdUnlockView, type: 1 }
117
+ routes.push({ ...adRoute, launchMode: 'standard' })
87
118
  ```
88
119
 
89
- ### 3. 路由配置
120
+ ### 导航器 `useTVAdNavigator(config)`
121
+
122
+ 在页面 `setup()` 中调用,按规则自动判断是否需要弹广告:
90
123
 
91
124
  ```typescript
92
- import { ESRouteType } from '@extscreen/es3-router'
93
-
94
- const routes = [
95
- {
96
- path: '/ad',
97
- name: 'ad',
98
- component: () => import('./views/ad/index.vue'),
99
- type: ESRouteType.ES_ROUTE_TYPE_DIALOG
100
- }
101
- ]
125
+ const adNavigator = useTVAdNavigator({
126
+ packageName: string // 必填,应用包名
127
+ initialCredits?: number // 初始积分,默认 5
128
+ creditsPerAd?: number // 每次广告获得积分,默认 5
129
+ dailyUnlockEnabled?: boolean // 每日解锁,默认 true
130
+ permanentUnlockAfterTotalAds?: number // 永久解锁阈值,默认 10
131
+ })
102
132
  ```
103
133
 
104
- ## API
134
+ **判断规则(按优先级)**:
105
135
 
106
- ### Props
136
+ 1. 永久解锁 → 放行(不弹广告)
137
+ 2. 今日已解锁 → 放行
138
+ 3. 积分 > 0 → 扣 1 分,放行
139
+ 4. 兜底 → 跳转广告页
107
140
 
108
- | 属性 | 类型 | 必填 | 默认值 | 说明 |
109
- |------|------|------|--------|------|
110
- | config | TVAdUnlockConfig | 是 | - | 广告配置 |
111
- | storageKeys | TVAdUnlockStorageKeys | 是 | - | 存储键名配置 |
112
- | requestManager | RequestManager | 是 | - | 请求管理器 |
113
- | title | string | 否 | '观看30秒广告 当日解锁' | 标题文字 |
114
- | subTitle | string | 否 | '手机打开【微信】扫码' | 副标题文字 |
115
- | invalidCodeImage | string | 否 | '' | 二维码失效图片 |
116
- | scannedCodeImage | string | 否 | '' | 已扫码图片 |
117
- | scanTitle | string | 否 | '观看奖励' | 扫码标题 |
118
- | scanContent | string | 否 | '观看广告后可获得奖励' | 扫码内容 |
119
- | scanToast | string | 否 | '奖励已获得,请前往电视端观看' | 扫码提示 |
120
-
121
- ### Events
122
-
123
- | 事件名 | 参数 | 说明 |
124
- |--------|------|------|
125
- | unlockSuccess | - | 解锁成功 |
126
- | unlockFailed | error: Error | 解锁失败 |
127
- | qrCodeInvalid | - | 二维码失效 |
128
- | qrCodeScanned | - | 二维码已扫码 |
129
-
130
- ### Types
141
+ **返回方法**:
131
142
 
132
- ```typescript
133
- interface TVAdUnlockConfig {
134
- packageName: string
135
- superRequestBaseUrl: string
136
- trackBaseUrl?: string
137
- invalidTimeout?: number
138
- pollInterval?: number
139
- }
143
+ | 方法 | 返回类型 | 说明 |
144
+ |------|----------|------|
145
+ | `consumeAndNavigate()` | `Promise<boolean>` | 核心方法。返回 `true` 表示已跳转广告页,`false` 表示放行 |
146
+ | `consume(amount)` | `Promise<{success, consumed}>` | 手动扣减指定积分 |
147
+ | `consumeAll()` | `Promise<number>` | 扣减全部积分,返回扣减值 |
148
+ | `addCredits(amount)` | `Promise<void>` | 增加积分 |
149
+ | `getCredits()` | `Promise<number>` | 查询当前积分 |
150
+ | `isPermanentlyUnlocked()` | `Promise<boolean>` | 是否已永久解锁 |
151
+ | `getTodayAdCount()` | `Promise<number>` | 今日已看广告次数 |
140
152
 
141
- interface TVAdUnlockStorageKeys {
142
- playCountKey: string
143
- unlockDateKey: string
144
- unlockedTodayKey: string
145
- }
153
+ ### 存储管理 `useTVAdUnlockStorage(storage, keys, initialCredits?)`
146
154
 
155
+ 底层存储操作,一般不直接使用。高级场景可通过 `createStorageKeys(packageName)` 生成 key 集合后手动操作。
156
+
157
+ ### 类型定义
158
+
159
+ ```typescript
147
160
  interface RequestManager {
148
161
  post(url: string, data: Record<string, any>): Promise<any>
149
162
  get(url: string, data: string): Promise<any>
150
163
  }
164
+
165
+ interface TVAdUnlockTrackEvent {
166
+ type: 'page' | 'click'
167
+ name: string
168
+ assetId?: string
169
+ assetName?: string
170
+ fromId?: string
171
+ fromName?: string
172
+ }
173
+ ```
174
+
175
+ ## 完整示例
176
+
177
+ ```typescript
178
+ // main-native.ts
179
+ import { tvAdUnlockPlugin, createTVAdRoute } from '@quicktvui/tv-ad-unlock'
180
+ import { createRequestManager } from './api/request/RequestManager'
181
+ import routes from './routes'
182
+
183
+ const adRoute = createTVAdRoute()
184
+ routes.push({ ...adRoute, launchMode: 'standard' })
185
+
186
+ const requestManager = createRequestManager()
187
+ app.use(tvAdUnlockPlugin, {
188
+ requestManager,
189
+ pageConfig: {
190
+ title: '观看广告 解锁功能',
191
+ scanTitle: '观看广告获得积分',
192
+ scanContent: '观看广告后可获得5积分',
193
+ scanToast: '积分已发放,请返回游戏'
194
+ }
195
+ })
196
+ ```
197
+
198
+ ```vue
199
+ <!-- 页面中使用 -->
200
+ <script lang="ts">
201
+ import { defineComponent } from 'vue'
202
+ import { useTVAdNavigator } from '@quicktvui/tv-ad-unlock'
203
+
204
+ export default defineComponent({
205
+ setup() {
206
+ const adNavigator = useTVAdNavigator({
207
+ packageName: 'com.example.app',
208
+ initialCredits: 0,
209
+ creditsPerAd: 5
210
+ })
211
+
212
+ function onShowHint() {
213
+ adNavigator.consumeAndNavigate().then(showedAd => {
214
+ if (!showedAd) {
215
+ // 直接显示提示
216
+ }
217
+ })
218
+ }
219
+
220
+ return { onShowHint }
221
+ }
222
+ })
223
+ </script>
151
224
  ```
152
225
 
153
226
  ## License
@@ -0,0 +1,4 @@
1
+ import type { InjectionKey } from 'vue';
2
+ import type { TVAdUnlockPluginProvided } from './types';
3
+ export declare const TV_AD_UNLOCK_KEY: InjectionKey<TVAdUnlockPluginProvided>;
4
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAA;AACvC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAEvD,eAAO,MAAM,gBAAgB,EAAE,YAAY,CAAC,wBAAwB,CAAwB,CAAA"}