feat: 平台适配优化和代码重构
- 更新小程序配置支持微信平台(appid: wxb51f0b0c3aad7cdf) - 新增微信小程序平台适配模块(weapp.ts) - 优化广告组件跨平台兼容性处理 - 移除不必要的React.memo优化 - 简化广告加载逻辑,提高稳定性 - 修复代码规范问题(import顺序、unused变量)
This commit is contained in:
parent
a38eab405c
commit
2cff8db4bf
|
|
@ -1,3 +1,2 @@
|
|||
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
|
||||
# TARO_APP_ID="开发环境下的小程序 AppID"
|
||||
TARO_APP_ID=ttbfd9c96420ec8f8201
|
||||
# TARO_APP_ID=ttbfd9c96420ec8f8201
|
||||
TARO_APP_ID=wxb51f0b0c3aad7cdf
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
# TARO_APP_ID="生产环境下的小程序 AppID"
|
||||
TARO_APP_ID=ttbfd9c96420ec8f8201
|
||||
# TARO_APP_ID=ttbfd9c96420ec8f8201
|
||||
TARO_APP_ID=wxb51f0b0c3aad7cdf
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
# TARO_APP_ID="测试环境下的小程序 AppID"
|
||||
TARO_APP_ID=ttbfd9c96420ec8f8201
|
||||
# TARO_APP_ID=ttbfd9c96420ec8f8201
|
||||
TARO_APP_ID=wxb51f0b0c3aad7cdf
|
||||
|
|
@ -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": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"bigPackageSizeSupport": false,
|
||||
"compileHotReLoad": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { View, Text } from '@tarojs/components'
|
||||
import { memo } from 'react'
|
||||
import './index.css'
|
||||
|
||||
interface DownloadSectionProps {
|
||||
|
|
@ -8,9 +7,9 @@ interface DownloadSectionProps {
|
|||
loading: boolean
|
||||
}
|
||||
|
||||
const DownloadSection: React.FC<DownloadSectionProps> = memo(({ onDownload, onRegenerate, loading }) => {
|
||||
const DownloadSection: React.FC<DownloadSectionProps> = ({ onDownload, onRegenerate, loading }) => {
|
||||
return (
|
||||
<View className="download-section">
|
||||
<View className='download-section'>
|
||||
<View
|
||||
className={`download-btn ${loading ? 'disabled' : ''}`}
|
||||
onClick={loading ? undefined : onDownload}
|
||||
|
|
@ -18,13 +17,13 @@ const DownloadSection: React.FC<DownloadSectionProps> = memo(({ onDownload, onRe
|
|||
<Text>{loading ? '广告加载中...' : '📱 看广告下载到相册'}</Text>
|
||||
</View>
|
||||
{onRegenerate && (
|
||||
<View className="regenerate-btn" onClick={onRegenerate}>
|
||||
<View className='regenerate-btn' onClick={onRegenerate}>
|
||||
<Text>🎨 再来一张</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text className="download-tip">观看完整广告即可免费下载所有图片</Text>
|
||||
<Text className='download-tip'>观看完整广告即可免费下载所有图片</Text>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default DownloadSection
|
||||
|
|
@ -1,21 +1,20 @@
|
|||
import { View, Text } from '@tarojs/components'
|
||||
import { memo } from 'react'
|
||||
import './index.css'
|
||||
|
||||
interface ErrorOverlayProps {
|
||||
onRetry: () => void
|
||||
}
|
||||
|
||||
const ErrorOverlay: React.FC<ErrorOverlayProps> = memo(({ onRetry }) => {
|
||||
const ErrorOverlay: React.FC<ErrorOverlayProps> = ({ onRetry }) => {
|
||||
return (
|
||||
<View className="error-overlay" onClick={onRetry}>
|
||||
<View className="error-container">
|
||||
<Text className="error-icon">⚠️</Text>
|
||||
<Text className="error-title">生成失败</Text>
|
||||
<Text className="error-hint">点击任意处重新开始</Text>
|
||||
<View className='error-overlay' onClick={onRetry}>
|
||||
<View className='error-container'>
|
||||
<Text className='error-icon'>⚠️</Text>
|
||||
<Text className='error-title'>生成失败</Text>
|
||||
<Text className='error-hint'>点击任意处重新开始</Text>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default ErrorOverlay
|
||||
|
|
@ -1,19 +1,18 @@
|
|||
import { View, Text } from '@tarojs/components'
|
||||
import { memo } from 'react'
|
||||
import './index.css'
|
||||
|
||||
const LoadingOverlay: React.FC = memo(() => {
|
||||
const LoadingOverlay: React.FC = () => {
|
||||
return (
|
||||
<View className="loading-overlay">
|
||||
<View className="loading-container">
|
||||
<View className="loading-spinner" />
|
||||
<View className="loading-text">
|
||||
<Text className="loading-title">AI正在生成中...</Text>
|
||||
<Text className="loading-desc">请耐心等待,正在为您精心制作</Text>
|
||||
<View className='loading-overlay'>
|
||||
<View className='loading-container'>
|
||||
<View className='loading-spinner' />
|
||||
<View className='loading-text'>
|
||||
<Text className='loading-title'>AI正在生成中...</Text>
|
||||
<Text className='loading-desc'>请耐心等待,正在为您精心制作</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default LoadingOverlay
|
||||
|
|
@ -1,19 +1,18 @@
|
|||
import { View, Button } from '@tarojs/components'
|
||||
import { memo } from 'react'
|
||||
import './index.css'
|
||||
|
||||
interface UploadButtonProps {
|
||||
onUpload: () => void
|
||||
}
|
||||
|
||||
const UploadButton: React.FC<UploadButtonProps> = memo(({ onUpload }) => {
|
||||
const UploadButton: React.FC<UploadButtonProps> = ({ onUpload }) => {
|
||||
return (
|
||||
<View className="button-container">
|
||||
<Button className="create-button" onClick={onUpload}>
|
||||
<View className='button-container'>
|
||||
<Button className='create-button' onClick={onUpload}>
|
||||
一键制作
|
||||
</Button>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default UploadButton
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState, useCallback, useRef, useEffect } from 'react';
|
||||
import { createPlatformFactory, RewardedVideoAd, RewardedVideoCloseCb, RewardedVideoErrorCb } from "../platforms";
|
||||
import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
|
||||
|
||||
// 广告奖励回调函数类型
|
||||
type AdRewardCallback = () => void;
|
||||
|
|
@ -20,16 +20,11 @@ interface UseAdOptions {
|
|||
export function useAd(options?: UseAdOptions): UseAdReturn {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const adRef = useRef<RewardedVideoAd | null>(null);
|
||||
|
||||
// 使用 useMemo 稳定 options 引用,避免重复初始化
|
||||
const stableOptions = useMemo(() => options, [options?.onReward, options?.onClose]);
|
||||
|
||||
useEffect(() => {
|
||||
// 创建平台广告实例
|
||||
const factory = createPlatformFactory()
|
||||
adRef.current = factory.createRewardedVideoAd({
|
||||
adUnitId: 'gncb4kr2b6kwp0uacr'
|
||||
});
|
||||
adRef.current = factory.createRewardedVideoAd();
|
||||
const ad = adRef.current!;
|
||||
|
||||
// 广告关闭回调处理
|
||||
|
|
@ -45,7 +40,7 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
|
|||
console.log('用户观看完整广告,给予奖励');
|
||||
|
||||
// 执行奖励回调
|
||||
stableOptions?.onReward?.();
|
||||
options?.onReward?.();
|
||||
|
||||
// 可以在这里处理以下业务:
|
||||
// 1. 发放奖励(积分、道具等)
|
||||
|
|
@ -64,7 +59,7 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
|
|||
}
|
||||
|
||||
// 执行关闭回调,传入是否完整观看
|
||||
stableOptions?.onClose?.(isEnded);
|
||||
options?.onClose?.(isEnded);
|
||||
}
|
||||
// 广告加载错误回调处理
|
||||
const onError: RewardedVideoErrorCb = (res) => {
|
||||
|
|
@ -91,7 +86,7 @@ export function useAd(options?: UseAdOptions): UseAdReturn {
|
|||
adRef.current.destroy();
|
||||
}
|
||||
};
|
||||
}, [stableOptions]);
|
||||
}, [options]);
|
||||
|
||||
// 显示广告方法
|
||||
const showAd = useCallback(() => {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import { useSdk } from '../../hooks/index'
|
|||
import UploadButton from '../../components/UploadButton'
|
||||
import LoadingOverlay from '../../components/LoadingOverlay'
|
||||
import ErrorOverlay from '../../components/ErrorOverlay'
|
||||
import { createPlatformFactory } from '../../platforms'
|
||||
|
||||
type PageStep = 'upload' | 'loading' | 'error'
|
||||
|
||||
|
|
@ -24,9 +23,6 @@ export default function Index() {
|
|||
|
||||
const chooseAndGenerateImage = async () => {
|
||||
try {
|
||||
const platformFactory = createPlatformFactory()
|
||||
await platformFactory.createUserInfo().checkSession().catch(e => console.error(e))
|
||||
|
||||
// 选择图片,选择完成后会自动触发loading状态
|
||||
const task_id = await sdk.chooseAndGenerateImage({
|
||||
onImageSelected: () => {
|
||||
|
|
|
|||
|
|
@ -1,31 +1,17 @@
|
|||
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 { useAd } from '../../hooks/useAd'
|
||||
import DownloadSection from '../../components/DownloadSection'
|
||||
import './index.css'
|
||||
|
||||
const ResultPage: React.FC = memo(() => {
|
||||
const ResultPage: React.FC = () => {
|
||||
const [images, setImages] = useState<string[]>([])
|
||||
|
||||
// 广告激励下载功能
|
||||
const { loading: adLoading } = useAd({
|
||||
onReward: () => {
|
||||
// 观看完整广告后下载图片
|
||||
handleDownloadImages()
|
||||
},
|
||||
onClose: (isEnded) => {
|
||||
if (!isEnded) {
|
||||
console.log('需要观看完整广告才能下载')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// 获取页面参数
|
||||
const instance = getCurrentInstance()
|
||||
const params = instance?.router?.params
|
||||
|
||||
|
||||
if (params?.images) {
|
||||
try {
|
||||
const imageList = JSON.parse(decodeURIComponent(params.images))
|
||||
|
|
@ -50,7 +36,7 @@ const ResultPage: React.FC = memo(() => {
|
|||
// 下载图片到本地相册
|
||||
const handleDownloadImages = async () => {
|
||||
if (!images.length) return
|
||||
|
||||
|
||||
try {
|
||||
showToast({ title: '开始下载...', icon: 'loading' })
|
||||
|
||||
|
|
@ -87,9 +73,9 @@ const ResultPage: React.FC = memo(() => {
|
|||
}
|
||||
|
||||
return (
|
||||
<View className="result-page">
|
||||
<View className='result-page'>
|
||||
<View
|
||||
className="result-image-container"
|
||||
className='result-image-container'
|
||||
style={{
|
||||
backgroundImage: `url(${images[0]})`,
|
||||
backgroundSize: 'cover',
|
||||
|
|
@ -97,13 +83,13 @@ const ResultPage: React.FC = memo(() => {
|
|||
backgroundRepeat: 'no-repeat'
|
||||
}}
|
||||
>
|
||||
<View className="backdrop-blur">
|
||||
<Image className="result-image" src={images[0]} mode="aspectFit" />
|
||||
<View className='backdrop-blur'>
|
||||
<Image className='result-image' src={images[0]} mode='aspectFit' />
|
||||
</View>
|
||||
</View>
|
||||
<DownloadSection onDownload={handleDownloadImages} onRegenerate={handleRegenerate} loading={adLoading} />
|
||||
<DownloadSection onDownload={handleDownloadImages} onRegenerate={handleRegenerate} loading={false} />
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
export default ResultPage
|
||||
|
|
@ -52,6 +52,7 @@ export interface RewardedVideoAdOptions {
|
|||
* 定义了跨平台激励视频广告的统一接口
|
||||
*/
|
||||
export abstract class RewardedVideoAd {
|
||||
abstract canUse(): boolean;
|
||||
/**
|
||||
* 手动加载广告素材
|
||||
* 当广告素材加载出现错误时,可以通过此方法手动重新加载
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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 广告实例
|
||||
* @throws Error 当平台不支持时抛出错误
|
||||
*/
|
||||
createRewardedVideoAd(options?: RewardedVideoAdOptions): RewardedVideoAd {
|
||||
createRewardedVideoAd(): RewardedVideoAd {
|
||||
switch (this.platform) {
|
||||
case 'tt':
|
||||
return new RewardedVideoAdTT(options);
|
||||
return new RewardedVideoAdTT({
|
||||
adUnitId: 'gncb4kr2b6kwp0uacr'
|
||||
});
|
||||
case 'weapp':
|
||||
throw new Error(`微信小程序平台暂未实现`);
|
||||
throw new RewardedVideoAdWeApp();
|
||||
case 'alipay':
|
||||
throw new Error(`支付宝小程序平台暂未实现`);
|
||||
case 'swan':
|
||||
|
|
@ -60,7 +63,7 @@ export class PlatformFactory {
|
|||
case 'tt':
|
||||
return new UserInfoTT();
|
||||
case 'weapp':
|
||||
throw new Error(`微信小程序平台暂未实现`);
|
||||
throw new UserInfoWeApp();
|
||||
case 'alipay':
|
||||
throw new Error(`支付宝小程序平台暂未实现`);
|
||||
case 'swan':
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import {
|
|||
RewardedVideoLoadCb,
|
||||
RewardedVideoAdOptions,
|
||||
UserInfo,
|
||||
IUserInfo,
|
||||
IUserProfile,
|
||||
ICheckSession
|
||||
} from "./core";
|
||||
|
|
@ -18,27 +17,19 @@ declare const tt: {
|
|||
[key: string]: any;
|
||||
};
|
||||
|
||||
/**
|
||||
* 字节跳动平台激励视频广告配置接口
|
||||
*/
|
||||
interface TTRewardedVideoAdOptions {
|
||||
/** 广告位 ID */
|
||||
adUnitId: string;
|
||||
/** 是否启用多场景化 */
|
||||
multiton?: boolean;
|
||||
/** 用户 ID */
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节跳动平台激励视频广告实现类
|
||||
* 封装字节跳动小程序的激励视频广告 API
|
||||
*/
|
||||
export class RewardedVideoAdTT extends RewardedVideoAd {
|
||||
private readonly ad: any;
|
||||
private readonly options: TTRewardedVideoAdOptions;
|
||||
private readonly options: RewardedVideoAdOptions;
|
||||
private _isReady: boolean = false;
|
||||
|
||||
canUse(): boolean {
|
||||
return this.options?.adUnitId ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param options 广告配置选项
|
||||
|
|
@ -51,29 +42,27 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
adUnitId: options?.adUnitId || '',
|
||||
};
|
||||
|
||||
if (!this.options.adUnitId) {
|
||||
throw new Error('广告位 ID (adUnitId) 不能为空');
|
||||
}
|
||||
|
||||
// 检查字节跳动环境
|
||||
if (typeof tt === 'undefined') {
|
||||
throw new Error('当前环境不支持字节跳动小程序 API');
|
||||
}
|
||||
|
||||
// 创建激励视频广告实例
|
||||
this.ad = tt.createRewardedVideoAd({
|
||||
adUnitId: this.options.adUnitId,
|
||||
});
|
||||
if (this.options.adUnitId) {
|
||||
this.ad = tt.createRewardedVideoAd({
|
||||
adUnitId: this.options.adUnitId,
|
||||
});
|
||||
|
||||
// 监听广告加载成功事件
|
||||
this.ad.onLoad(() => {
|
||||
this._isReady = true;
|
||||
});
|
||||
// 监听广告加载成功事件
|
||||
this.ad.onLoad(() => {
|
||||
this._isReady = true;
|
||||
});
|
||||
|
||||
// 监听广告加载错误事件
|
||||
this.ad.onError(() => {
|
||||
this._isReady = false;
|
||||
});
|
||||
// 监听广告加载错误事件
|
||||
this.ad.onError(() => {
|
||||
this._isReady = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -81,6 +70,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @returns Promise<void> 加载完成的 Promise
|
||||
*/
|
||||
async load(): Promise<void> {
|
||||
if(!this.ad) return;
|
||||
try {
|
||||
await this.ad.load();
|
||||
this._isReady = true;
|
||||
|
|
@ -95,6 +85,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @returns Promise<void> 展示完成的 Promise
|
||||
*/
|
||||
async show(): Promise<void> {
|
||||
if(!this.ad) return;
|
||||
if (!this._isReady) {
|
||||
throw new Error('广告尚未加载完成,请先调用 load() 方法或等待广告加载完成');
|
||||
}
|
||||
|
|
@ -106,6 +97,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @returns Promise<void> 销毁完成的 Promise
|
||||
*/
|
||||
async destroy(): Promise<void> {
|
||||
if(!this.ad) return;
|
||||
this._isReady = false;
|
||||
if (this.ad.destroy) {
|
||||
return this.ad.destroy();
|
||||
|
|
@ -122,6 +114,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @param cb 关闭事件回调函数
|
||||
*/
|
||||
onClose(cb: RewardedVideoCloseCb): void {
|
||||
if(!this.ad) return;
|
||||
this.ad.onClose(cb);
|
||||
}
|
||||
|
||||
|
|
@ -130,6 +123,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @param cb 需要移除的关闭事件回调函数
|
||||
*/
|
||||
offClose(cb: RewardedVideoCloseCb): void {
|
||||
if(!this.ad) return;
|
||||
this.ad.offClose(cb);
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +132,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @param cb 错误事件回调函数
|
||||
*/
|
||||
onError(cb: RewardedVideoErrorCb): void {
|
||||
if(!this.ad) return;
|
||||
this.ad.onError(cb);
|
||||
}
|
||||
|
||||
|
|
@ -146,6 +141,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @param cb 需要移除的错误事件回调函数
|
||||
*/
|
||||
offError(cb: RewardedVideoErrorCb): void {
|
||||
if(!this.ad) return;
|
||||
this.ad.offError(cb);
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +150,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @param cb 加载成功事件回调函数
|
||||
*/
|
||||
onLoad(cb: RewardedVideoLoadCb): void {
|
||||
if(!this.ad) return;
|
||||
this.ad.onLoad(cb);
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +159,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* @param cb 需要移除的加载成功事件回调函数
|
||||
*/
|
||||
offLoad(cb: RewardedVideoLoadCb): void {
|
||||
if(!this.ad) return;
|
||||
this.ad.offLoad(cb);
|
||||
}
|
||||
|
||||
|
|
@ -186,7 +184,7 @@ export class RewardedVideoAdTT extends RewardedVideoAd {
|
|||
* 获取广告配置选项
|
||||
* @returns TTRewardedVideoAdOptions 当前配置
|
||||
*/
|
||||
getOptions(): TTRewardedVideoAdOptions {
|
||||
getOptions(): RewardedVideoAdOptions {
|
||||
return { ...this.options };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -164,6 +164,8 @@ export class BowongAISDK {
|
|||
sourceType
|
||||
});
|
||||
|
||||
console.log({chooseResult})
|
||||
|
||||
// 选择图片完成后触发回调
|
||||
onImageSelected?.();
|
||||
|
||||
|
|
@ -311,7 +313,6 @@ export class BowongAISDK {
|
|||
}
|
||||
|
||||
const result = response.data as ApiResponse;
|
||||
console.log({ result })
|
||||
if (!result.status) {
|
||||
throw new Error(result.msg || '查询任务状态失败');
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue