@quicktvui/tv-ad-unlock 1.0.0 → 1.0.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.
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export { useTVAdUnlock, useTVAdUnlockStorage } from './useTVAdUnlock';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './types';
2
+ export { useTVAdUnlock, useTVAdUnlockStorage } from './useTVAdUnlock';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,51 @@
1
+ export interface TVAdUnlockConfig {
2
+ packageName: string;
3
+ superRequestBaseUrl: string;
4
+ trackBaseUrl?: string;
5
+ invalidTimeout?: number;
6
+ pollInterval?: number;
7
+ }
8
+ export interface TVAdUnlockParams {
9
+ assetId?: string;
10
+ assetName?: string;
11
+ fromId?: string;
12
+ fromName?: string;
13
+ }
14
+ export interface TVAdUnlockCallbacks {
15
+ onUnlockSuccess?: () => void;
16
+ onUnlockFailed?: (error: Error) => void;
17
+ onQrCodeInvalid?: () => void;
18
+ onQrCodeScanned?: () => void;
19
+ }
20
+ export interface TVAdUnlockState {
21
+ adQrCode: string;
22
+ isInvalid: boolean;
23
+ qrCodeState: number;
24
+ isLoading: boolean;
25
+ }
26
+ export interface TVAdUnlockStorageKeys {
27
+ playCountKey: string;
28
+ unlockDateKey: string;
29
+ unlockedTodayKey: string;
30
+ }
31
+ export interface TVAdUnlockOptions {
32
+ config: TVAdUnlockConfig;
33
+ storageKeys: TVAdUnlockStorageKeys;
34
+ freePlayCount?: number;
35
+ callbacks?: TVAdUnlockCallbacks;
36
+ }
37
+ export interface RequestManager {
38
+ post(url: string, data: Record<string, any>): Promise<any>;
39
+ get(url: string, data: string): Promise<any>;
40
+ }
41
+ export interface TrackEventParams {
42
+ id: string;
43
+ name: string;
44
+ pageId?: string;
45
+ pageName?: string;
46
+ pageSourceId?: string;
47
+ pageSourceName?: string;
48
+ contentId?: string;
49
+ contentName?: string;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAA;IACnB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IACvC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,gBAAgB,CAAA;IACxB,WAAW,EAAE,qBAAqB,CAAA;IAClC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,mBAAmB,CAAA;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IAC1D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import type { TVAdUnlockConfig, TVAdUnlockStorageKeys, TVAdUnlockCallbacks, RequestManager } from './types';
2
+ export declare function useTVAdUnlock(config: TVAdUnlockConfig, storageKeys: TVAdUnlockStorageKeys, requestManager: RequestManager, callbacks?: TVAdUnlockCallbacks): {
3
+ adQrCode: import("vue").Ref<string, string>;
4
+ isInvalid: import("vue").Ref<boolean, boolean>;
5
+ qrCodeState: import("vue").Ref<number, number>;
6
+ isLoading: import("vue").Ref<boolean, boolean>;
7
+ isShowConfirmToast: import("vue").Ref<boolean, boolean>;
8
+ getAdQrCode: (deviceId: string, scanTitle?: string, scanContent?: string, scanToast?: string) => Promise<string>;
9
+ startPollTvADStatusTimer: (deviceId: string) => void;
10
+ stopPollTvADStatusTimer: () => void;
11
+ startInvalidTimer: () => void;
12
+ stopInvalidTimer: () => void;
13
+ invalidQrCode: () => void;
14
+ reset: () => void;
15
+ isTodayUnlocked: (storage: {
16
+ getString: (key: string, defaultValue?: string) => Promise<string>;
17
+ }) => Promise<boolean>;
18
+ getTodayPlayCount: (storage: {
19
+ getString: (key: string, defaultValue?: string) => Promise<string>;
20
+ putString: (key: string, value: string) => Promise<void>;
21
+ }) => Promise<number>;
22
+ incrementPlayCount: (storage: {
23
+ getString: (key: string, defaultValue?: string) => Promise<string>;
24
+ putString: (key: string, value: string) => Promise<void>;
25
+ }) => Promise<number>;
26
+ checkNeedAd: (storage: {
27
+ getString: (key: string, defaultValue?: string) => Promise<string>;
28
+ putString: (key: string, value: string) => Promise<void>;
29
+ }, freePlayCount: number) => Promise<boolean>;
30
+ };
31
+ export declare function useTVAdUnlockStorage(storage: {
32
+ getString: (key: string, defaultValue?: string) => Promise<string>;
33
+ putString: (key: string, value: string) => Promise<void>;
34
+ }, storageKeys: TVAdUnlockStorageKeys, freePlayCount?: number): {
35
+ isTodayUnlocked: () => Promise<boolean>;
36
+ getTodayPlayCount: () => Promise<number>;
37
+ incrementPlayCount: () => Promise<number>;
38
+ checkNeedAd: () => Promise<boolean>;
39
+ setTodayUnlocked: () => Promise<void>;
40
+ };
41
+ //# sourceMappingURL=useTVAdUnlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTVAdUnlock.d.ts","sourceRoot":"","sources":["../src/useTVAdUnlock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAGhB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACf,MAAM,SAAS,CAAA;AAKhB,wBAAgB,aAAa,CAC3B,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,qBAAqB,EAClC,cAAc,EAAE,cAAc,EAC9B,SAAS,CAAC,EAAE,mBAAmB;;;;;;4BA4FM,MAAM,cAAa,MAAM,gBAAwB,MAAM,cAA4B,MAAM,KAAsB,OAAO,CAAC,MAAM,CAAC;yCAkCvH,MAAM,KAAG,IAAI;mCAQrB,IAAI;6BAeV,IAAI;4BAPL,IAAI;yBAeP,IAAI;iBAMZ,IAAI;+BArIkB;QAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;KAAE,KAAG,OAAO,CAAC,OAAO,CAAC;iCAMvF;QAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,KAAG,OAAO,CAAC,MAAM,CAAC;kCAcjJ;QAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,KAAG,OAAO,CAAC,MAAM,CAAC;2BAOzJ;QAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,iBAAiB,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;EA4I/M;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE;IAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,EACzI,WAAW,EAAE,qBAAqB,EAClC,aAAa,GAAE,MAAW;2BAOQ,OAAO,CAAC,OAAO,CAAC;6BAMd,OAAO,CAAC,MAAM,CAAC;8BAcd,OAAO,CAAC,MAAM,CAAC;uBAOtB,OAAO,CAAC,OAAO,CAAC;4BASX,OAAO,CAAC,IAAI,CAAC;EAcjD"}
@@ -0,0 +1,228 @@
1
+ import { ref, watch, onUnmounted } from 'vue';
2
+ const DEFAULT_INVALID_TIMEOUT = 300000;
3
+ const DEFAULT_POLL_INTERVAL = 1000;
4
+ export function useTVAdUnlock(config, storageKeys, requestManager, callbacks) {
5
+ const adQrCode = ref('');
6
+ const isInvalid = ref(false);
7
+ const qrCodeState = ref(0);
8
+ const isLoading = ref(false);
9
+ const isStopPoll = ref(false);
10
+ const isShowConfirmToast = ref(false);
11
+ let invalidTimer = null;
12
+ let pollTimer = null;
13
+ const invalidTimeout = config.invalidTimeout ?? DEFAULT_INVALID_TIMEOUT;
14
+ const pollInterval = config.pollInterval ?? DEFAULT_POLL_INTERVAL;
15
+ const urlGetDeviceCode = config.superRequestBaseUrl + '/superc/ad/open/v2/tv/getAdUrl';
16
+ const urlPollTVADStatus = config.superRequestBaseUrl + '/superc/ad/open/v2/tv/pollTVADStatus';
17
+ watch(() => qrCodeState.value, (newVal, oldVal) => {
18
+ if (newVal === 1 && oldVal === 0) {
19
+ startInvalidTimer();
20
+ callbacks?.onQrCodeScanned?.();
21
+ }
22
+ });
23
+ function getTodayString() {
24
+ const today = new Date();
25
+ return `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;
26
+ }
27
+ async function isTodayUnlocked(storage) {
28
+ const today = getTodayString();
29
+ const unlockedDate = await storage.getString(storageKeys.unlockedTodayKey, '');
30
+ return unlockedDate === today;
31
+ }
32
+ async function getTodayPlayCount(storage) {
33
+ const today = getTodayString();
34
+ const savedDate = await storage.getString(storageKeys.unlockDateKey, '');
35
+ if (savedDate !== today) {
36
+ await storage.putString(storageKeys.unlockDateKey, today);
37
+ await storage.putString(storageKeys.playCountKey, '0');
38
+ return 0;
39
+ }
40
+ const count = await storage.getString(storageKeys.playCountKey, '0');
41
+ return parseInt(count) || 0;
42
+ }
43
+ async function incrementPlayCount(storage) {
44
+ const count = await getTodayPlayCount(storage);
45
+ const newCount = count + 1;
46
+ await storage.putString(storageKeys.playCountKey, String(newCount));
47
+ return newCount;
48
+ }
49
+ async function checkNeedAd(storage, freePlayCount) {
50
+ const unlocked = await isTodayUnlocked(storage);
51
+ if (unlocked) {
52
+ return false;
53
+ }
54
+ const count = await getTodayPlayCount(storage);
55
+ return count >= freePlayCount;
56
+ }
57
+ async function pollTVADStatus(deviceId) {
58
+ try {
59
+ const res = await requestManager.post(urlPollTVADStatus, {
60
+ data: { deviceId }
61
+ });
62
+ if (isStopPoll.value) {
63
+ return;
64
+ }
65
+ qrCodeState.value = parseInt(`${res}`);
66
+ if (qrCodeState.value === 2) {
67
+ callbacks?.onUnlockSuccess?.();
68
+ }
69
+ else {
70
+ pollTimer = setTimeout(() => {
71
+ pollTVADStatus(deviceId);
72
+ }, pollInterval);
73
+ }
74
+ }
75
+ catch {
76
+ pollTimer = setTimeout(() => {
77
+ pollTVADStatus(deviceId);
78
+ }, pollInterval);
79
+ }
80
+ }
81
+ async function getAdQrCode(deviceId, scanTitle = '观看奖励', scanContent = '观看广告后可获得奖励', scanToast = '奖励已获得,请前往电视端观看') {
82
+ isLoading.value = true;
83
+ isInvalid.value = false;
84
+ qrCodeState.value = 0;
85
+ try {
86
+ const res = await requestManager.post(urlGetDeviceCode, {
87
+ data: {
88
+ deviceId,
89
+ scanTitle,
90
+ scanContent,
91
+ scanToast
92
+ }
93
+ });
94
+ if (res) {
95
+ adQrCode.value = res;
96
+ isInvalid.value = false;
97
+ startPollTvADStatusTimer(deviceId);
98
+ startInvalidTimer();
99
+ isLoading.value = false;
100
+ return res;
101
+ }
102
+ else {
103
+ isLoading.value = false;
104
+ callbacks?.onUnlockFailed?.(new Error('获取二维码失败'));
105
+ return '';
106
+ }
107
+ }
108
+ catch (e) {
109
+ isLoading.value = false;
110
+ callbacks?.onUnlockFailed?.(e);
111
+ return '';
112
+ }
113
+ }
114
+ function startPollTvADStatusTimer(deviceId) {
115
+ stopPollTvADStatusTimer();
116
+ isStopPoll.value = false;
117
+ pollTimer = setTimeout(() => {
118
+ pollTVADStatus(deviceId);
119
+ }, pollInterval);
120
+ }
121
+ function stopPollTvADStatusTimer() {
122
+ if (pollTimer) {
123
+ clearTimeout(pollTimer);
124
+ pollTimer = null;
125
+ isStopPoll.value = true;
126
+ }
127
+ }
128
+ function stopInvalidTimer() {
129
+ if (invalidTimer) {
130
+ clearTimeout(invalidTimer);
131
+ invalidTimer = null;
132
+ }
133
+ }
134
+ function startInvalidTimer() {
135
+ stopInvalidTimer();
136
+ invalidTimer = setTimeout(() => {
137
+ invalidQrCode();
138
+ invalidTimer = null;
139
+ }, invalidTimeout);
140
+ }
141
+ function invalidQrCode() {
142
+ isInvalid.value = true;
143
+ stopPollTvADStatusTimer();
144
+ callbacks?.onQrCodeInvalid?.();
145
+ }
146
+ function reset() {
147
+ adQrCode.value = '';
148
+ isInvalid.value = false;
149
+ qrCodeState.value = 0;
150
+ isLoading.value = false;
151
+ isStopPoll.value = false;
152
+ isShowConfirmToast.value = false;
153
+ stopPollTvADStatusTimer();
154
+ stopInvalidTimer();
155
+ }
156
+ onUnmounted(() => {
157
+ stopPollTvADStatusTimer();
158
+ stopInvalidTimer();
159
+ });
160
+ return {
161
+ adQrCode,
162
+ isInvalid,
163
+ qrCodeState,
164
+ isLoading,
165
+ isShowConfirmToast,
166
+ getAdQrCode,
167
+ startPollTvADStatusTimer,
168
+ stopPollTvADStatusTimer,
169
+ startInvalidTimer,
170
+ stopInvalidTimer,
171
+ invalidQrCode,
172
+ reset,
173
+ isTodayUnlocked,
174
+ getTodayPlayCount,
175
+ incrementPlayCount,
176
+ checkNeedAd
177
+ };
178
+ }
179
+ export function useTVAdUnlockStorage(storage, storageKeys, freePlayCount = 32) {
180
+ function getTodayString() {
181
+ const today = new Date();
182
+ return `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;
183
+ }
184
+ async function isTodayUnlocked() {
185
+ const today = getTodayString();
186
+ const unlockedDate = await storage.getString(storageKeys.unlockedTodayKey, '');
187
+ return unlockedDate === today;
188
+ }
189
+ async function getTodayPlayCount() {
190
+ const today = getTodayString();
191
+ const savedDate = await storage.getString(storageKeys.unlockDateKey, '');
192
+ if (savedDate !== today) {
193
+ await storage.putString(storageKeys.unlockDateKey, today);
194
+ await storage.putString(storageKeys.playCountKey, '0');
195
+ return 0;
196
+ }
197
+ const count = await storage.getString(storageKeys.playCountKey, '0');
198
+ return parseInt(count) || 0;
199
+ }
200
+ async function incrementPlayCount() {
201
+ const count = await getTodayPlayCount();
202
+ const newCount = count + 1;
203
+ await storage.putString(storageKeys.playCountKey, String(newCount));
204
+ return newCount;
205
+ }
206
+ async function checkNeedAd() {
207
+ const unlocked = await isTodayUnlocked();
208
+ if (unlocked) {
209
+ return false;
210
+ }
211
+ const count = await getTodayPlayCount();
212
+ return count >= freePlayCount;
213
+ }
214
+ async function setTodayUnlocked() {
215
+ const today = getTodayString();
216
+ await storage.putString(storageKeys.unlockedTodayKey, today);
217
+ await storage.putString(storageKeys.playCountKey, '0');
218
+ await storage.putString(storageKeys.unlockDateKey, today);
219
+ }
220
+ return {
221
+ isTodayUnlocked,
222
+ getTodayPlayCount,
223
+ incrementPlayCount,
224
+ checkNeedAd,
225
+ setTodayUnlocked
226
+ };
227
+ }
228
+ //# sourceMappingURL=useTVAdUnlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTVAdUnlock.js","sourceRoot":"","sources":["../src/useTVAdUnlock.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@quicktvui/tv-ad-unlock",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "TV广告解锁组件 - 用于QuickTVUI框架的电视端广告解锁功能",
5
- "main": "src/index.ts",
6
- "types": "src/index.ts",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
7
  "files": [
8
- "src"
8
+ "dist",
9
+ "src/TVAdUnlock.vue"
9
10
  ],
10
11
  "keywords": [
11
12
  "quicktvui",
@@ -21,8 +22,15 @@
21
22
  "@extscreen/es3-core": ">=3.0.0",
22
23
  "@extscreen/es3-router": ">=3.0.0"
23
24
  },
25
+ "devDependencies": {
26
+ "typescript": "^5.0.0",
27
+ "vue": "^3.0.0"
28
+ },
24
29
  "repository": {
25
30
  "type": "git",
26
31
  "url": ""
32
+ },
33
+ "scripts": {
34
+ "build": "tsc"
27
35
  }
28
36
  }
package/src/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './types'
2
- export { useTVAdUnlock, useTVAdUnlockStorage } from './useTVAdUnlock'
3
- export { default as TVAdUnlock } from './TVAdUnlock.vue'
package/src/types.ts DELETED
@@ -1,57 +0,0 @@
1
- export interface TVAdUnlockConfig {
2
- packageName: string
3
- superRequestBaseUrl: string
4
- trackBaseUrl?: string
5
- invalidTimeout?: number
6
- pollInterval?: number
7
- }
8
-
9
- export interface TVAdUnlockParams {
10
- assetId?: string
11
- assetName?: string
12
- fromId?: string
13
- fromName?: string
14
- }
15
-
16
- export interface TVAdUnlockCallbacks {
17
- onUnlockSuccess?: () => void
18
- onUnlockFailed?: (error: Error) => void
19
- onQrCodeInvalid?: () => void
20
- onQrCodeScanned?: () => void
21
- }
22
-
23
- export interface TVAdUnlockState {
24
- adQrCode: string
25
- isInvalid: boolean
26
- qrCodeState: number
27
- isLoading: boolean
28
- }
29
-
30
- export interface TVAdUnlockStorageKeys {
31
- playCountKey: string
32
- unlockDateKey: string
33
- unlockedTodayKey: string
34
- }
35
-
36
- export interface TVAdUnlockOptions {
37
- config: TVAdUnlockConfig
38
- storageKeys: TVAdUnlockStorageKeys
39
- freePlayCount?: number
40
- callbacks?: TVAdUnlockCallbacks
41
- }
42
-
43
- export interface RequestManager {
44
- post(url: string, data: Record<string, any>): Promise<any>
45
- get(url: string, data: string): Promise<any>
46
- }
47
-
48
- export interface TrackEventParams {
49
- id: string
50
- name: string
51
- pageId?: string
52
- pageName?: string
53
- pageSourceId?: string
54
- pageSourceName?: string
55
- contentId?: string
56
- contentName?: string
57
- }
@@ -1,277 +0,0 @@
1
- import { ref, watch, onUnmounted } from 'vue'
2
- import type {
3
- TVAdUnlockConfig,
4
- TVAdUnlockParams,
5
- TVAdUnlockState,
6
- TVAdUnlockStorageKeys,
7
- TVAdUnlockCallbacks,
8
- RequestManager
9
- } from './types'
10
-
11
- const DEFAULT_INVALID_TIMEOUT = 300000
12
- const DEFAULT_POLL_INTERVAL = 1000
13
-
14
- export function useTVAdUnlock(
15
- config: TVAdUnlockConfig,
16
- storageKeys: TVAdUnlockStorageKeys,
17
- requestManager: RequestManager,
18
- callbacks?: TVAdUnlockCallbacks
19
- ) {
20
- const adQrCode = ref('')
21
- const isInvalid = ref(false)
22
- const qrCodeState = ref(0)
23
- const isLoading = ref(false)
24
- const isStopPoll = ref(false)
25
- const isShowConfirmToast = ref(false)
26
-
27
- let invalidTimer: ReturnType<typeof setTimeout> | null = null
28
- let pollTimer: ReturnType<typeof setTimeout> | null = null
29
-
30
- const invalidTimeout = config.invalidTimeout ?? DEFAULT_INVALID_TIMEOUT
31
- const pollInterval = config.pollInterval ?? DEFAULT_POLL_INTERVAL
32
-
33
- const urlGetDeviceCode = config.superRequestBaseUrl + '/superc/ad/open/v2/tv/getAdUrl'
34
- const urlPollTVADStatus = config.superRequestBaseUrl + '/superc/ad/open/v2/tv/pollTVADStatus'
35
-
36
- watch(() => qrCodeState.value, (newVal, oldVal) => {
37
- if (newVal === 1 && oldVal === 0) {
38
- startInvalidTimer()
39
- callbacks?.onQrCodeScanned?.()
40
- }
41
- })
42
-
43
- function getTodayString(): string {
44
- const today = new Date()
45
- return `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`
46
- }
47
-
48
- async function isTodayUnlocked(storage: { getString: (key: string, defaultValue?: string) => Promise<string> }): Promise<boolean> {
49
- const today = getTodayString()
50
- const unlockedDate = await storage.getString(storageKeys.unlockedTodayKey, '')
51
- return unlockedDate === today
52
- }
53
-
54
- async function getTodayPlayCount(storage: { getString: (key: string, defaultValue?: string) => Promise<string>; putString: (key: string, value: string) => Promise<void> }): Promise<number> {
55
- const today = getTodayString()
56
- const savedDate = await storage.getString(storageKeys.unlockDateKey, '')
57
-
58
- if (savedDate !== today) {
59
- await storage.putString(storageKeys.unlockDateKey, today)
60
- await storage.putString(storageKeys.playCountKey, '0')
61
- return 0
62
- }
63
-
64
- const count = await storage.getString(storageKeys.playCountKey, '0')
65
- return parseInt(count) || 0
66
- }
67
-
68
- async function incrementPlayCount(storage: { getString: (key: string, defaultValue?: string) => Promise<string>; putString: (key: string, value: string) => Promise<void> }): Promise<number> {
69
- const count = await getTodayPlayCount(storage)
70
- const newCount = count + 1
71
- await storage.putString(storageKeys.playCountKey, String(newCount))
72
- return newCount
73
- }
74
-
75
- async function checkNeedAd(storage: { getString: (key: string, defaultValue?: string) => Promise<string>; putString: (key: string, value: string) => Promise<void> }, freePlayCount: number): Promise<boolean> {
76
- const unlocked = await isTodayUnlocked(storage)
77
- if (unlocked) {
78
- return false
79
- }
80
- const count = await getTodayPlayCount(storage)
81
- return count >= freePlayCount
82
- }
83
-
84
- async function pollTVADStatus(deviceId: string): Promise<void> {
85
- try {
86
- const res = await requestManager.post(urlPollTVADStatus, {
87
- data: { deviceId }
88
- })
89
-
90
- if (isStopPoll.value) {
91
- return
92
- }
93
-
94
- qrCodeState.value = parseInt(`${res}`)
95
-
96
- if (qrCodeState.value === 2) {
97
- callbacks?.onUnlockSuccess?.()
98
- } else {
99
- pollTimer = setTimeout(() => {
100
- pollTVADStatus(deviceId)
101
- }, pollInterval)
102
- }
103
- } catch {
104
- pollTimer = setTimeout(() => {
105
- pollTVADStatus(deviceId)
106
- }, pollInterval)
107
- }
108
- }
109
-
110
- async function getAdQrCode(deviceId: string, scanTitle: string = '观看奖励', scanContent: string = '观看广告后可获得奖励', scanToast: string = '奖励已获得,请前往电视端观看'): Promise<string> {
111
- isLoading.value = true
112
- isInvalid.value = false
113
- qrCodeState.value = 0
114
-
115
- try {
116
- const res = await requestManager.post(urlGetDeviceCode, {
117
- data: {
118
- deviceId,
119
- scanTitle,
120
- scanContent,
121
- scanToast
122
- }
123
- })
124
-
125
- if (res) {
126
- adQrCode.value = res
127
- isInvalid.value = false
128
- startPollTvADStatusTimer(deviceId)
129
- startInvalidTimer()
130
- isLoading.value = false
131
- return res
132
- } else {
133
- isLoading.value = false
134
- callbacks?.onUnlockFailed?.(new Error('获取二维码失败'))
135
- return ''
136
- }
137
- } catch (e) {
138
- isLoading.value = false
139
- callbacks?.onUnlockFailed?.(e as Error)
140
- return ''
141
- }
142
- }
143
-
144
- function startPollTvADStatusTimer(deviceId: string): void {
145
- stopPollTvADStatusTimer()
146
- isStopPoll.value = false
147
- pollTimer = setTimeout(() => {
148
- pollTVADStatus(deviceId)
149
- }, pollInterval)
150
- }
151
-
152
- function stopPollTvADStatusTimer(): void {
153
- if (pollTimer) {
154
- clearTimeout(pollTimer)
155
- pollTimer = null
156
- isStopPoll.value = true
157
- }
158
- }
159
-
160
- function stopInvalidTimer(): void {
161
- if (invalidTimer) {
162
- clearTimeout(invalidTimer)
163
- invalidTimer = null
164
- }
165
- }
166
-
167
- function startInvalidTimer(): void {
168
- stopInvalidTimer()
169
- invalidTimer = setTimeout(() => {
170
- invalidQrCode()
171
- invalidTimer = null
172
- }, invalidTimeout)
173
- }
174
-
175
- function invalidQrCode(): void {
176
- isInvalid.value = true
177
- stopPollTvADStatusTimer()
178
- callbacks?.onQrCodeInvalid?.()
179
- }
180
-
181
- function reset(): void {
182
- adQrCode.value = ''
183
- isInvalid.value = false
184
- qrCodeState.value = 0
185
- isLoading.value = false
186
- isStopPoll.value = false
187
- isShowConfirmToast.value = false
188
- stopPollTvADStatusTimer()
189
- stopInvalidTimer()
190
- }
191
-
192
- onUnmounted(() => {
193
- stopPollTvADStatusTimer()
194
- stopInvalidTimer()
195
- })
196
-
197
- return {
198
- adQrCode,
199
- isInvalid,
200
- qrCodeState,
201
- isLoading,
202
- isShowConfirmToast,
203
- getAdQrCode,
204
- startPollTvADStatusTimer,
205
- stopPollTvADStatusTimer,
206
- startInvalidTimer,
207
- stopInvalidTimer,
208
- invalidQrCode,
209
- reset,
210
- isTodayUnlocked,
211
- getTodayPlayCount,
212
- incrementPlayCount,
213
- checkNeedAd
214
- }
215
- }
216
-
217
- export function useTVAdUnlockStorage(
218
- storage: { getString: (key: string, defaultValue?: string) => Promise<string>; putString: (key: string, value: string) => Promise<void> },
219
- storageKeys: TVAdUnlockStorageKeys,
220
- freePlayCount: number = 32
221
- ) {
222
- function getTodayString(): string {
223
- const today = new Date()
224
- return `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`
225
- }
226
-
227
- async function isTodayUnlocked(): Promise<boolean> {
228
- const today = getTodayString()
229
- const unlockedDate = await storage.getString(storageKeys.unlockedTodayKey, '')
230
- return unlockedDate === today
231
- }
232
-
233
- async function getTodayPlayCount(): Promise<number> {
234
- const today = getTodayString()
235
- const savedDate = await storage.getString(storageKeys.unlockDateKey, '')
236
-
237
- if (savedDate !== today) {
238
- await storage.putString(storageKeys.unlockDateKey, today)
239
- await storage.putString(storageKeys.playCountKey, '0')
240
- return 0
241
- }
242
-
243
- const count = await storage.getString(storageKeys.playCountKey, '0')
244
- return parseInt(count) || 0
245
- }
246
-
247
- async function incrementPlayCount(): Promise<number> {
248
- const count = await getTodayPlayCount()
249
- const newCount = count + 1
250
- await storage.putString(storageKeys.playCountKey, String(newCount))
251
- return newCount
252
- }
253
-
254
- async function checkNeedAd(): Promise<boolean> {
255
- const unlocked = await isTodayUnlocked()
256
- if (unlocked) {
257
- return false
258
- }
259
- const count = await getTodayPlayCount()
260
- return count >= freePlayCount
261
- }
262
-
263
- async function setTodayUnlocked(): Promise<void> {
264
- const today = getTodayString()
265
- await storage.putString(storageKeys.unlockedTodayKey, today)
266
- await storage.putString(storageKeys.playCountKey, '0')
267
- await storage.putString(storageKeys.unlockDateKey, today)
268
- }
269
-
270
- return {
271
- isTodayUnlocked,
272
- getTodayPlayCount,
273
- incrementPlayCount,
274
- checkNeedAd,
275
- setTodayUnlocked
276
- }
277
- }