feat: 接入激励视频

This commit is contained in:
richarjiang
2026-06-29 19:55:40 +08:00
parent 411ca8c772
commit e2fd4eeda3
16 changed files with 9215 additions and 73 deletions

View File

@@ -34,6 +34,9 @@ export interface WxPrivacySettingResult {
* 封装微信平台相关 API非微信环境下静默降级
*/
export class WxSDK {
/** 默认激励视频广告位 */
private static readonly DEFAULT_REWARDED_VIDEO_AD_UNIT_ID = 'adunit-52a53828d4b91fe2';
/** 隐私授权请求进行中时复用同一个 Promise避免启动链路重复弹窗 */
private static _privacyAuthorizePromise: Promise<boolean> | null = null;
@@ -315,6 +318,12 @@ export class WxSDK {
/** 激励视频广告实例(复用) */
private static _rewardedVideoAd: any = null;
/** 当前复用实例对应的广告位 */
private static _rewardedVideoAdUnitId: string = '';
/** 激励视频广告展示中的 Promise避免重复拉起 */
private static _rewardedVideoAdPromise: Promise<boolean> | null = null;
/**
* 展示激励视频广告
* 用户看完广告后返回 true中途退出或失败返回 false
@@ -322,68 +331,98 @@ export class WxSDK {
* @param adUnitId 广告单元 ID默认使用项目配置的 ID
* @returns Promise<boolean> 是否看完广告
*/
static showRewardedVideoAd(adUnitId: string = ''): Promise<boolean> {
return new Promise((resolve) => {
const wxApi = WxSDK.getWx();
if (!wxApi) {
console.log('[WxSDK] 非微信环境,跳过激励视频广告');
resolve(true);
return;
}
static showRewardedVideoAd(adUnitId: string = WxSDK.DEFAULT_REWARDED_VIDEO_AD_UNIT_ID): Promise<boolean> {
if (WxSDK._rewardedVideoAdPromise) {
return WxSDK._rewardedVideoAdPromise;
}
if (typeof wxApi.createRewardedVideoAd !== 'function') {
console.warn('[WxSDK] 当前微信版本不支持激励视频广告');
resolve(true);
return;
}
const wxApi = WxSDK.getWx();
if (!wxApi) {
console.log('[WxSDK] 非微信环境,跳过激励视频广告');
return Promise.resolve(true);
}
if (typeof wxApi.createRewardedVideoAd !== 'function') {
console.warn('[WxSDK] 当前微信版本不支持激励视频广告');
return Promise.resolve(true);
}
const resolvedAdUnitId = adUnitId || WxSDK.DEFAULT_REWARDED_VIDEO_AD_UNIT_ID;
if (!resolvedAdUnitId) {
console.warn('[WxSDK] 激励视频广告位未配置');
return Promise.resolve(false);
}
WxSDK._rewardedVideoAdPromise = new Promise((resolve) => {
let ad: any = null;
let finished = false;
const cleanup = () => {
if (!ad) return;
if (typeof ad.offClose === 'function') {
ad.offClose(onClose);
}
if (typeof ad.offError === 'function') {
ad.offError(onError);
}
};
const finish = (result: boolean) => {
if (finished) return;
finished = true;
cleanup();
WxSDK._rewardedVideoAdPromise = null;
resolve(result);
};
const onClose = (res: any) => {
const isEnded = res === undefined || !!res?.isEnded;
if (isEnded) {
console.log('[WxSDK] 激励视频广告观看完成');
finish(true);
} else {
console.log('[WxSDK] 激励视频广告中途退出');
finish(false);
}
};
const onError = (err: any) => {
console.error('[WxSDK] 激励视频广告错误:', err);
finish(false);
};
try {
// 复用或创建广告实例
if (!WxSDK._rewardedVideoAd) {
WxSDK._rewardedVideoAd = wxApi.createRewardedVideoAd({
adUnitId: adUnitId,
});
}
const ad = WxSDK._rewardedVideoAd;
// 定义关闭回调(一次性)
const onClose = (res: any) => {
ad.offClose(onClose);
if (res && res.isEnded) {
console.log('[WxSDK] 激励视频广告观看完成');
resolve(true);
} else {
console.log('[WxSDK] 激励视频广告中途退出');
resolve(false);
}
};
// 定义错误回调(一次性)
const onError = (err: any) => {
ad.offError(onError);
ad.offClose(onClose);
console.error('[WxSDK] 激励视频广告错误:', err);
resolve(false);
};
ad = WxSDK.getRewardedVideoAd(wxApi, resolvedAdUnitId);
ad.onClose(onClose);
ad.onError(onError);
// 先尝试 show如果广告未加载则先 load
ad.show().catch(() => {
ad.load().then(() => ad.show()).catch((loadErr: any) => {
ad.offClose(onClose);
ad.offError(onError);
Promise.resolve(ad.show()).catch(() => {
Promise.resolve(ad.load()).then(() => ad.show()).catch((loadErr: any) => {
console.error('[WxSDK] 激励视频广告加载失败:', loadErr);
resolve(false);
finish(false);
});
});
} catch (err) {
console.error('[WxSDK] 激励视频广告异常:', err);
resolve(false);
finish(false);
}
});
return WxSDK._rewardedVideoAdPromise;
}
private static getRewardedVideoAd(wxApi: any, adUnitId: string): any {
if (WxSDK._rewardedVideoAd && WxSDK._rewardedVideoAdUnitId === adUnitId) {
return WxSDK._rewardedVideoAd;
}
if (WxSDK._rewardedVideoAd && typeof WxSDK._rewardedVideoAd.destroy === 'function') {
WxSDK._rewardedVideoAd.destroy();
}
WxSDK._rewardedVideoAd = wxApi.createRewardedVideoAd({ adUnitId });
WxSDK._rewardedVideoAdUnitId = adUnitId;
return WxSDK._rewardedVideoAd;
}
// ==================== 启动参数 ====================