feat: 平台适配优化和代码重构
- 更新小程序配置支持微信平台(appid: wxb51f0b0c3aad7cdf) - 新增微信小程序平台适配模块(weapp.ts) - 优化广告组件跨平台兼容性处理 - 移除不必要的React.memo优化 - 简化广告加载逻辑,提高稳定性 - 修复代码规范问题(import顺序、unused变量)
This commit is contained in:
@@ -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
|
|
||||||
@@ -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": {}
|
||||||
|
}
|
||||||
7
project.private.config.json
Normal file
7
project.private.config.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": true,
|
||||||
|
"bigPackageSizeSupport": false,
|
||||||
|
"compileHotReLoad": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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(() => {
|
||||||
|
|||||||
@@ -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: () => {
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -52,6 +52,7 @@ export interface RewardedVideoAdOptions {
|
|||||||
* 定义了跨平台激励视频广告的统一接口
|
* 定义了跨平台激励视频广告的统一接口
|
||||||
*/
|
*/
|
||||||
export abstract class RewardedVideoAd {
|
export abstract class RewardedVideoAd {
|
||||||
|
abstract canUse(): boolean;
|
||||||
/**
|
/**
|
||||||
* 手动加载广告素材
|
* 手动加载广告素材
|
||||||
* 当广告素材加载出现错误时,可以通过此方法手动重新加载
|
* 当广告素材加载出现错误时,可以通过此方法手动重新加载
|
||||||
|
|||||||
@@ -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':
|
||||||
|
|||||||
@@ -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
241
src/platforms/weapp.ts
Normal 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 || '查询任务状态失败');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user