feat: 平台适配优化和代码重构

- 更新小程序配置支持微信平台(appid: wxb51f0b0c3aad7cdf)
- 新增微信小程序平台适配模块(weapp.ts)
- 优化广告组件跨平台兼容性处理
- 移除不必要的React.memo优化
- 简化广告加载逻辑,提高稳定性
- 修复代码规范问题(import顺序、unused变量)
This commit is contained in:
imeepos
2025-09-02 17:40:45 +08:00
parent a38eab405c
commit 2cff8db4bf
17 changed files with 371 additions and 110 deletions

View File

@@ -1,3 +1,2 @@
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config # TARO_APP_ID=ttbfd9c96420ec8f8201
# TARO_APP_ID="开发环境下的小程序 AppID" TARO_APP_ID=wxb51f0b0c3aad7cdf
TARO_APP_ID=ttbfd9c96420ec8f8201

View File

@@ -1,2 +1,2 @@
# TARO_APP_ID="生产环境下的小程序 AppID" # TARO_APP_ID=ttbfd9c96420ec8f8201
TARO_APP_ID=ttbfd9c96420ec8f8201 TARO_APP_ID=wxb51f0b0c3aad7cdf

View File

@@ -1,2 +1,2 @@
# TARO_APP_ID="测试环境下的小程序 AppID" # TARO_APP_ID=ttbfd9c96420ec8f8201
TARO_APP_ID=ttbfd9c96420ec8f8201 TARO_APP_ID=wxb51f0b0c3aad7cdf

View File

@@ -1 +1,39 @@
{"miniprogramRoot":"./dist","projectname":"bw-mini-app","description":"图生图 风格转换 ","appid":"ttbfd9c96420ec8f8201","setting":{"urlCheck":true,"es6":true,"enhance":false,"compileHotReLoad":false,"postcss":false,"minified":false},"compileType":"miniprogram"} {
"miniprogramRoot": "dist/",
"projectname": "bw-mini-app",
"description": "图生图 风格转换 ",
"appid": "wxb51f0b0c3aad7cdf",
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"compileHotReLoad": false,
"postcss": false,
"minified": true,
"compileWorklet": false,
"uglifyFileName": false,
"uploadWithSourceMap": true,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"minifyWXML": true,
"localPlugins": false,
"disableUseStrict": false,
"useCompilerPlugins": false,
"condition": false,
"swc": false,
"disableSWC": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"compileType": "miniprogram",
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [],
"include": []
},
"editorSetting": {}
}

View File

@@ -0,0 +1,7 @@
{
"setting": {
"urlCheck": true,
"bigPackageSizeSupport": false,
"compileHotReLoad": true
}
}

View File

@@ -1,5 +1,4 @@
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'
import { memo } from 'react'
import './index.css' import './index.css'
interface DownloadSectionProps { interface DownloadSectionProps {
@@ -8,9 +7,9 @@ interface DownloadSectionProps {
loading: boolean loading: boolean
} }
const DownloadSection: React.FC<DownloadSectionProps> = memo(({ onDownload, onRegenerate, loading }) => { const DownloadSection: React.FC<DownloadSectionProps> = ({ onDownload, onRegenerate, loading }) => {
return ( return (
<View className="download-section"> <View className='download-section'>
<View <View
className={`download-btn ${loading ? 'disabled' : ''}`} className={`download-btn ${loading ? 'disabled' : ''}`}
onClick={loading ? undefined : onDownload} onClick={loading ? undefined : onDownload}
@@ -18,13 +17,13 @@ const DownloadSection: React.FC<DownloadSectionProps> = memo(({ onDownload, onRe
<Text>{loading ? '广告加载中...' : '📱 看广告下载到相册'}</Text> <Text>{loading ? '广告加载中...' : '📱 看广告下载到相册'}</Text>
</View> </View>
{onRegenerate && ( {onRegenerate && (
<View className="regenerate-btn" onClick={onRegenerate}> <View className='regenerate-btn' onClick={onRegenerate}>
<Text>🎨 </Text> <Text>🎨 </Text>
</View> </View>
)} )}
<Text className="download-tip">广</Text> <Text className='download-tip'>广</Text>
</View> </View>
) )
}) }
export default DownloadSection export default DownloadSection

View File

@@ -1,21 +1,20 @@
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'
import { memo } from 'react'
import './index.css' import './index.css'
interface ErrorOverlayProps { interface ErrorOverlayProps {
onRetry: () => void onRetry: () => void
} }
const ErrorOverlay: React.FC<ErrorOverlayProps> = memo(({ onRetry }) => { const ErrorOverlay: React.FC<ErrorOverlayProps> = ({ onRetry }) => {
return ( return (
<View className="error-overlay" onClick={onRetry}> <View className='error-overlay' onClick={onRetry}>
<View className="error-container"> <View className='error-container'>
<Text className="error-icon"></Text> <Text className='error-icon'></Text>
<Text className="error-title"></Text> <Text className='error-title'></Text>
<Text className="error-hint"></Text> <Text className='error-hint'></Text>
</View> </View>
</View> </View>
) )
}) }
export default ErrorOverlay export default ErrorOverlay

View File

@@ -1,19 +1,18 @@
import { View, Text } from '@tarojs/components' import { View, Text } from '@tarojs/components'
import { memo } from 'react'
import './index.css' import './index.css'
const LoadingOverlay: React.FC = memo(() => { const LoadingOverlay: React.FC = () => {
return ( return (
<View className="loading-overlay"> <View className='loading-overlay'>
<View className="loading-container"> <View className='loading-container'>
<View className="loading-spinner" /> <View className='loading-spinner' />
<View className="loading-text"> <View className='loading-text'>
<Text className="loading-title">AI正在生成中...</Text> <Text className='loading-title'>AI正在生成中...</Text>
<Text className="loading-desc"></Text> <Text className='loading-desc'></Text>
</View> </View>
</View> </View>
</View> </View>
) )
}) }
export default LoadingOverlay export default LoadingOverlay

View File

@@ -1,19 +1,18 @@
import { View, Button } from '@tarojs/components' import { View, Button } from '@tarojs/components'
import { memo } from 'react'
import './index.css' import './index.css'
interface UploadButtonProps { interface UploadButtonProps {
onUpload: () => void onUpload: () => void
} }
const UploadButton: React.FC<UploadButtonProps> = memo(({ onUpload }) => { const UploadButton: React.FC<UploadButtonProps> = ({ onUpload }) => {
return ( return (
<View className="button-container"> <View className='button-container'>
<Button className="create-button" onClick={onUpload}> <Button className='create-button' onClick={onUpload}>
</Button> </Button>
</View> </View>
) )
}) }
export default UploadButton export default UploadButton

View File

@@ -1,5 +1,5 @@
import { useState, useCallback, useRef, useEffect } from 'react';
import { createPlatformFactory, RewardedVideoAd, RewardedVideoCloseCb, RewardedVideoErrorCb } from "../platforms"; import { createPlatformFactory, RewardedVideoAd, RewardedVideoCloseCb, RewardedVideoErrorCb } from "../platforms";
import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
// 广告奖励回调函数类型 // 广告奖励回调函数类型
type AdRewardCallback = () => void; type AdRewardCallback = () => void;
@@ -20,16 +20,11 @@ interface UseAdOptions {
export function useAd(options?: UseAdOptions): UseAdReturn { export function useAd(options?: UseAdOptions): UseAdReturn {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const adRef = useRef<RewardedVideoAd | null>(null); const adRef = useRef<RewardedVideoAd | null>(null);
// 使用 useMemo 稳定 options 引用,避免重复初始化
const stableOptions = useMemo(() => options, [options?.onReward, options?.onClose]);
useEffect(() => { useEffect(() => {
// 创建平台广告实例 // 创建平台广告实例
const factory = createPlatformFactory() const factory = createPlatformFactory()
adRef.current = factory.createRewardedVideoAd({ adRef.current = factory.createRewardedVideoAd();
adUnitId: 'gncb4kr2b6kwp0uacr'
});
const ad = adRef.current!; const ad = adRef.current!;
// 广告关闭回调处理 // 广告关闭回调处理
@@ -45,7 +40,7 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
console.log('用户观看完整广告,给予奖励'); console.log('用户观看完整广告,给予奖励');
// 执行奖励回调 // 执行奖励回调
stableOptions?.onReward?.(); options?.onReward?.();
// 可以在这里处理以下业务: // 可以在这里处理以下业务:
// 1. 发放奖励(积分、道具等) // 1. 发放奖励(积分、道具等)
@@ -64,7 +59,7 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
} }
// 执行关闭回调,传入是否完整观看 // 执行关闭回调,传入是否完整观看
stableOptions?.onClose?.(isEnded); options?.onClose?.(isEnded);
} }
// 广告加载错误回调处理 // 广告加载错误回调处理
const onError: RewardedVideoErrorCb = (res) => { const onError: RewardedVideoErrorCb = (res) => {
@@ -91,7 +86,7 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
adRef.current.destroy(); adRef.current.destroy();
} }
}; };
}, [stableOptions]); }, [options]);
// 显示广告方法 // 显示广告方法
const showAd = useCallback(() => { const showAd = useCallback(() => {

View File

@@ -6,7 +6,6 @@ import { useSdk } from '../../hooks/index'
import UploadButton from '../../components/UploadButton' import UploadButton from '../../components/UploadButton'
import LoadingOverlay from '../../components/LoadingOverlay' import LoadingOverlay from '../../components/LoadingOverlay'
import ErrorOverlay from '../../components/ErrorOverlay' import ErrorOverlay from '../../components/ErrorOverlay'
import { createPlatformFactory } from '../../platforms'
type PageStep = 'upload' | 'loading' | 'error' type PageStep = 'upload' | 'loading' | 'error'
@@ -24,9 +23,6 @@ export default function Index() {
const chooseAndGenerateImage = async () => { const chooseAndGenerateImage = async () => {
try { try {
const platformFactory = createPlatformFactory()
await platformFactory.createUserInfo().checkSession().catch(e => console.error(e))
// 选择图片选择完成后会自动触发loading状态 // 选择图片选择完成后会自动触发loading状态
const task_id = await sdk.chooseAndGenerateImage({ const task_id = await sdk.chooseAndGenerateImage({
onImageSelected: () => { onImageSelected: () => {

View File

@@ -1,31 +1,17 @@
import { View, Image } from '@tarojs/components' import { View, Image } from '@tarojs/components'
import { memo, useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { saveImageToPhotosAlbum, downloadFile, showToast, navigateBack, getCurrentInstance } from '@tarojs/taro' import { saveImageToPhotosAlbum, downloadFile, showToast, navigateBack, getCurrentInstance } from '@tarojs/taro'
import { useAd } from '../../hooks/useAd'
import DownloadSection from '../../components/DownloadSection' import DownloadSection from '../../components/DownloadSection'
import './index.css' import './index.css'
const ResultPage: React.FC = memo(() => { const ResultPage: React.FC = () => {
const [images, setImages] = useState<string[]>([]) const [images, setImages] = useState<string[]>([])
// 广告激励下载功能
const { loading: adLoading } = useAd({
onReward: () => {
// 观看完整广告后下载图片
handleDownloadImages()
},
onClose: (isEnded) => {
if (!isEnded) {
console.log('需要观看完整广告才能下载')
}
}
})
useEffect(() => { useEffect(() => {
// 获取页面参数 // 获取页面参数
const instance = getCurrentInstance() const instance = getCurrentInstance()
const params = instance?.router?.params const params = instance?.router?.params
if (params?.images) { if (params?.images) {
try { try {
const imageList = JSON.parse(decodeURIComponent(params.images)) const imageList = JSON.parse(decodeURIComponent(params.images))
@@ -50,7 +36,7 @@ const ResultPage: React.FC = memo(() => {
// 下载图片到本地相册 // 下载图片到本地相册
const handleDownloadImages = async () => { const handleDownloadImages = async () => {
if (!images.length) return if (!images.length) return
try { try {
showToast({ title: '开始下载...', icon: 'loading' }) showToast({ title: '开始下载...', icon: 'loading' })
@@ -87,9 +73,9 @@ const ResultPage: React.FC = memo(() => {
} }
return ( return (
<View className="result-page"> <View className='result-page'>
<View <View
className="result-image-container" className='result-image-container'
style={{ style={{
backgroundImage: `url(${images[0]})`, backgroundImage: `url(${images[0]})`,
backgroundSize: 'cover', backgroundSize: 'cover',
@@ -97,13 +83,13 @@ const ResultPage: React.FC = memo(() => {
backgroundRepeat: 'no-repeat' backgroundRepeat: 'no-repeat'
}} }}
> >
<View className="backdrop-blur"> <View className='backdrop-blur'>
<Image className="result-image" src={images[0]} mode="aspectFit" /> <Image className='result-image' src={images[0]} mode='aspectFit' />
</View> </View>
</View> </View>
<DownloadSection onDownload={handleDownloadImages} onRegenerate={handleRegenerate} loading={adLoading} /> <DownloadSection onDownload={handleDownloadImages} onRegenerate={handleRegenerate} loading={false} />
</View> </View>
) )
}) }
export default ResultPage export default ResultPage

View File

@@ -52,6 +52,7 @@ export interface RewardedVideoAdOptions {
* 定义了跨平台激励视频广告的统一接口 * 定义了跨平台激励视频广告的统一接口
*/ */
export abstract class RewardedVideoAd { export abstract class RewardedVideoAd {
abstract canUse(): boolean;
/** /**
* 手动加载广告素材 * 手动加载广告素材
* 当广告素材加载出现错误时,可以通过此方法手动重新加载 * 当广告素材加载出现错误时,可以通过此方法手动重新加载

View File

@@ -1,5 +1,6 @@
import { RewardedVideoAdTT, UserInfoTT } from "./tt"; import { RewardedVideoAdTT, UserInfoTT } from "./tt";
import { RewardedVideoAd, RewardedVideoAdOptions, UserInfo } from "./core"; import { RewardedVideoAd, UserInfo } from "./core";
import { RewardedVideoAdWeApp, UserInfoWeApp } from "./weapp";
/** /**
* 小程序平台全局对象类型声明 * 小程序平台全局对象类型声明
@@ -37,12 +38,14 @@ export class PlatformFactory {
* @returns RewardedVideoAd 广告实例 * @returns RewardedVideoAd 广告实例
* @throws Error 当平台不支持时抛出错误 * @throws Error 当平台不支持时抛出错误
*/ */
createRewardedVideoAd(options?: RewardedVideoAdOptions): RewardedVideoAd { createRewardedVideoAd(): RewardedVideoAd {
switch (this.platform) { switch (this.platform) {
case 'tt': case 'tt':
return new RewardedVideoAdTT(options); return new RewardedVideoAdTT({
adUnitId: 'gncb4kr2b6kwp0uacr'
});
case 'weapp': case 'weapp':
throw new Error(`微信小程序平台暂未实现`); throw new RewardedVideoAdWeApp();
case 'alipay': case 'alipay':
throw new Error(`支付宝小程序平台暂未实现`); throw new Error(`支付宝小程序平台暂未实现`);
case 'swan': case 'swan':
@@ -60,7 +63,7 @@ export class PlatformFactory {
case 'tt': case 'tt':
return new UserInfoTT(); return new UserInfoTT();
case 'weapp': case 'weapp':
throw new Error(`微信小程序平台暂未实现`); throw new UserInfoWeApp();
case 'alipay': case 'alipay':
throw new Error(`支付宝小程序平台暂未实现`); throw new Error(`支付宝小程序平台暂未实现`);
case 'swan': case 'swan':

View File

@@ -5,7 +5,6 @@ import {
RewardedVideoLoadCb, RewardedVideoLoadCb,
RewardedVideoAdOptions, RewardedVideoAdOptions,
UserInfo, UserInfo,
IUserInfo,
IUserProfile, IUserProfile,
ICheckSession ICheckSession
} from "./core"; } from "./core";
@@ -18,27 +17,19 @@ declare const tt: {
[key: string]: any; [key: string]: any;
}; };
/**
* 字节跳动平台激励视频广告配置接口
*/
interface TTRewardedVideoAdOptions {
/** 广告位 ID */
adUnitId: string;
/** 是否启用多场景化 */
multiton?: boolean;
/** 用户 ID */
userId?: string;
}
/** /**
* 字节跳动平台激励视频广告实现类 * 字节跳动平台激励视频广告实现类
* 封装字节跳动小程序的激励视频广告 API * 封装字节跳动小程序的激励视频广告 API
*/ */
export class RewardedVideoAdTT extends RewardedVideoAd { export class RewardedVideoAdTT extends RewardedVideoAd {
private readonly ad: any; private readonly ad: any;
private readonly options: TTRewardedVideoAdOptions; private readonly options: RewardedVideoAdOptions;
private _isReady: boolean = false; private _isReady: boolean = false;
canUse(): boolean {
return this.options?.adUnitId ? true : false;
}
/** /**
* 构造函数 * 构造函数
* @param options 广告配置选项 * @param options 广告配置选项
@@ -51,29 +42,27 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
adUnitId: options?.adUnitId || '', adUnitId: options?.adUnitId || '',
}; };
if (!this.options.adUnitId) {
throw new Error('广告位 ID (adUnitId) 不能为空');
}
// 检查字节跳动环境 // 检查字节跳动环境
if (typeof tt === 'undefined') { if (typeof tt === 'undefined') {
throw new Error('当前环境不支持字节跳动小程序 API'); throw new Error('当前环境不支持字节跳动小程序 API');
} }
// 创建激励视频广告实例 // 创建激励视频广告实例
this.ad = tt.createRewardedVideoAd({ if (this.options.adUnitId) {
adUnitId: this.options.adUnitId, this.ad = tt.createRewardedVideoAd({
}); adUnitId: this.options.adUnitId,
});
// 监听广告加载成功事件 // 监听广告加载成功事件
this.ad.onLoad(() => { this.ad.onLoad(() => {
this._isReady = true; this._isReady = true;
}); });
// 监听广告加载错误事件 // 监听广告加载错误事件
this.ad.onError(() => { this.ad.onError(() => {
this._isReady = false; this._isReady = false;
}); });
}
} }
/** /**
@@ -81,6 +70,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @returns Promise<void> 加载完成的 Promise * @returns Promise<void> 加载完成的 Promise
*/ */
async load(): Promise<void> { async load(): Promise<void> {
if(!this.ad) return;
try { try {
await this.ad.load(); await this.ad.load();
this._isReady = true; this._isReady = true;
@@ -95,6 +85,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @returns Promise<void> 展示完成的 Promise * @returns Promise<void> 展示完成的 Promise
*/ */
async show(): Promise<void> { async show(): Promise<void> {
if(!this.ad) return;
if (!this._isReady) { if (!this._isReady) {
throw new Error('广告尚未加载完成,请先调用 load() 方法或等待广告加载完成'); throw new Error('广告尚未加载完成,请先调用 load() 方法或等待广告加载完成');
} }
@@ -106,6 +97,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @returns Promise<void> 销毁完成的 Promise * @returns Promise<void> 销毁完成的 Promise
*/ */
async destroy(): Promise<void> { async destroy(): Promise<void> {
if(!this.ad) return;
this._isReady = false; this._isReady = false;
if (this.ad.destroy) { if (this.ad.destroy) {
return this.ad.destroy(); return this.ad.destroy();
@@ -122,6 +114,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @param cb 关闭事件回调函数 * @param cb 关闭事件回调函数
*/ */
onClose(cb: RewardedVideoCloseCb): void { onClose(cb: RewardedVideoCloseCb): void {
if(!this.ad) return;
this.ad.onClose(cb); this.ad.onClose(cb);
} }
@@ -130,6 +123,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @param cb 需要移除的关闭事件回调函数 * @param cb 需要移除的关闭事件回调函数
*/ */
offClose(cb: RewardedVideoCloseCb): void { offClose(cb: RewardedVideoCloseCb): void {
if(!this.ad) return;
this.ad.offClose(cb); this.ad.offClose(cb);
} }
@@ -138,6 +132,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @param cb 错误事件回调函数 * @param cb 错误事件回调函数
*/ */
onError(cb: RewardedVideoErrorCb): void { onError(cb: RewardedVideoErrorCb): void {
if(!this.ad) return;
this.ad.onError(cb); this.ad.onError(cb);
} }
@@ -146,6 +141,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @param cb 需要移除的错误事件回调函数 * @param cb 需要移除的错误事件回调函数
*/ */
offError(cb: RewardedVideoErrorCb): void { offError(cb: RewardedVideoErrorCb): void {
if(!this.ad) return;
this.ad.offError(cb); this.ad.offError(cb);
} }
@@ -154,6 +150,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @param cb 加载成功事件回调函数 * @param cb 加载成功事件回调函数
*/ */
onLoad(cb: RewardedVideoLoadCb): void { onLoad(cb: RewardedVideoLoadCb): void {
if(!this.ad) return;
this.ad.onLoad(cb); this.ad.onLoad(cb);
} }
@@ -162,6 +159,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* @param cb 需要移除的加载成功事件回调函数 * @param cb 需要移除的加载成功事件回调函数
*/ */
offLoad(cb: RewardedVideoLoadCb): void { offLoad(cb: RewardedVideoLoadCb): void {
if(!this.ad) return;
this.ad.offLoad(cb); this.ad.offLoad(cb);
} }
@@ -186,7 +184,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
* 获取广告配置选项 * 获取广告配置选项
* @returns TTRewardedVideoAdOptions 当前配置 * @returns TTRewardedVideoAdOptions 当前配置
*/ */
getOptions(): TTRewardedVideoAdOptions { getOptions(): RewardedVideoAdOptions {
return { ...this.options }; return { ...this.options };
} }

241
src/platforms/weapp.ts Normal file
View File

@@ -0,0 +1,241 @@
import {
RewardedVideoAd,
RewardedVideoCloseCb,
RewardedVideoErrorCb,
RewardedVideoLoadCb,
RewardedVideoAdOptions,
UserInfo,
IUserProfile,
ICheckSession
} from "./core";
/**
* 字节跳动小程序全局对象类型声明
*/
declare const wx: {
createRewardedVideoAd: (options: any) => any;
[key: string]: any;
};
/**
* 字节跳动平台激励视频广告实现类
* 封装字节跳动小程序的激励视频广告 API
*/
export class RewardedVideoAdWeApp extends RewardedVideoAd {
private readonly ad: any;
private readonly options: RewardedVideoAdOptions;
private _isReady: boolean = false;
canUse(): boolean {
return this.options?.adUnitId ? true : false;
}
/**
* 构造函数
* @param options 广告配置选项
*/
constructor(options?: RewardedVideoAdOptions) {
super();
// 设置默认配置
this.options = {
adUnitId: options?.adUnitId || '',
};
// 检查字节跳动环境
if (typeof wx === 'undefined') {
throw new Error('当前环境不支持字节跳动小程序 API');
}
// 创建激励视频广告实例
if (this.options.adUnitId) {
this.ad = wx.createRewardedVideoAd({
adUnitId: this.options.adUnitId,
});
// 监听广告加载成功事件
this.ad.onLoad(() => {
this._isReady = true;
});
// 监听广告加载错误事件
this.ad.onError(() => {
this._isReady = false;
});
}
}
/**
* 手动加载广告素材
* @returns Promise<void> 加载完成的 Promise
*/
async load(): Promise<void> {
if (!this.ad) return;
try {
await this.ad.load();
this._isReady = true;
} catch (error) {
this._isReady = false;
throw error;
}
}
/**
* 展示激励视频广告
* @returns Promise<void> 展示完成的 Promise
*/
async show(): Promise<void> {
if (!this.ad) return;
if (!this._isReady) {
throw new Error('广告尚未加载完成,请先调用 load() 方法或等待广告加载完成');
}
return this.ad.show();
}
/**
* 销毁激励视频广告实例
* @returns Promise<void> 销毁完成的 Promise
*/
async destroy(): Promise<void> {
if (!this.ad) return;
this._isReady = false;
if (this.ad.destroy) {
return this.ad.destroy();
}
// 兼容性处理:某些版本可能使用 destory (拼写错误)
if (this.ad.destory) {
return this.ad.destory();
}
return Promise.resolve();
}
/**
* 绑定广告关闭事件监听器
* @param cb 关闭事件回调函数
*/
onClose(cb: RewardedVideoCloseCb): void {
if (!this.ad) return;
this.ad.onClose(cb);
}
/**
* 解除绑定广告关闭事件监听器
* @param cb 需要移除的关闭事件回调函数
*/
offClose(cb: RewardedVideoCloseCb): void {
if (!this.ad) return;
this.ad.offClose(cb);
}
/**
* 绑定广告错误事件监听器
* @param cb 错误事件回调函数
*/
onError(cb: RewardedVideoErrorCb): void {
if (!this.ad) return;
this.ad.onError(cb);
}
/**
* 解除绑定广告错误事件监听器
* @param cb 需要移除的错误事件回调函数
*/
offError(cb: RewardedVideoErrorCb): void {
if (!this.ad) return;
this.ad.offError(cb);
}
/**
* 绑定广告加载成功事件监听器
* @param cb 加载成功事件回调函数
*/
onLoad(cb: RewardedVideoLoadCb): void {
if (!this.ad) return;
this.ad.onLoad(cb);
}
/**
* 解除绑定广告加载成功事件监听器
* @param cb 需要移除的加载成功事件回调函数
*/
offLoad(cb: RewardedVideoLoadCb): void {
if (!this.ad) return;
this.ad.offLoad(cb);
}
/**
* 获取广告是否准备就绪
* @returns boolean 广告是否可以播放
*/
isReady(): boolean {
return this._isReady;
}
/**
* 预加载广告
* 在合适的时机预先加载广告,提高用户体验
* @returns Promise<void> 预加载完成的 Promise
*/
async preload(): Promise<void> {
return this.load();
}
/**
* 获取广告配置选项
* @returns TTRewardedVideoAdOptions 当前配置
*/
getOptions(): RewardedVideoAdOptions {
return { ...this.options };
}
/**
* 获取原生广告实例
* 用于访问平台特有的方法和属性
* @returns any 原生广告实例
*/
getNativeAd(): any {
return this.ad;
}
}
export class UserInfoWeApp extends UserInfo {
getUserProfile(): Promise<IUserProfile> {
return new Promise((resolve, reject) => {
wx.getUserProfile({
success: (res: any) => {
console.log({ res })
resolve(res)
},
fail: (res: any) => {
console.log({ res })
reject(res)
}
})
})
}
login(): Promise<any> {
return new Promise((resolve, reject) => {
wx.login({
success: (res: any) => {
resolve(res)
},
fail: (res: any) => {
reject(res)
}
})
})
}
checkSession(): Promise<ICheckSession> {
return new Promise((resolve, reject) => {
wx.checkSession({
success: (res: any) => {
resolve(res)
},
fail: (res: any) => {
reject(res)
}
})
})
}
}

View File

@@ -164,6 +164,8 @@ export class BowongAISDK {
sourceType sourceType
}); });
console.log({chooseResult})
// 选择图片完成后触发回调 // 选择图片完成后触发回调
onImageSelected?.(); onImageSelected?.();
@@ -311,7 +313,6 @@ export class BowongAISDK {
} }
const result = response.data as ApiResponse; const result = response.data as ApiResponse;
console.log({ result })
if (!result.status) { if (!result.status) {
throw new Error(result.msg || '查询任务状态失败'); throw new Error(result.msg || '查询任务状态失败');
} }