245 lines
6.9 KiB
TypeScript
245 lines
6.9 KiB
TypeScript
import { View, ScrollView } from '@tarojs/components'
|
|
import { useEffect, useState } from 'react'
|
|
import Taro, { navigateTo } from '@tarojs/taro'
|
|
import { useAppDispatch, useAppSelector } from '../../hooks/redux'
|
|
import { selectTemplates } from '../../selectors/template'
|
|
import { initTemplates } from '../../actions/template'
|
|
import { Template } from '../../store/types'
|
|
import TemplateCard from '../../components/TemplateCard'
|
|
import { useSdk, useServerSdk } from '../../hooks/index'
|
|
import { useImageDetectionTaskManager, ImageAuditResult, AuditConclusion } from '../../hooks/useImageDetectionTaskManager'
|
|
|
|
import './index.css'
|
|
|
|
// 定义详细的加载状态类型
|
|
type LoadingState = false | 'uploading' | 'auditing' | 'processing'
|
|
|
|
export default function Home() {
|
|
const dispatch = useAppDispatch()
|
|
const templates = useAppSelector(selectTemplates)
|
|
const sdk = useSdk()
|
|
const serverSdk = useServerSdk()
|
|
const { submitAuditTask } = useImageDetectionTaskManager()
|
|
const [loadingState, setLoadingState] = useState<LoadingState>(false)
|
|
const [refreshing, setRefreshing] = useState(false)
|
|
|
|
const loadTemplates = async () => {
|
|
try {
|
|
const templates = await serverSdk.getAllTemplates()
|
|
console.log(templates)
|
|
dispatch(initTemplates(templates))
|
|
} catch (error) {
|
|
console.error('加载模板失败:', error)
|
|
Taro.showToast({
|
|
title: '加载模板失败',
|
|
icon: 'error',
|
|
duration: 2000
|
|
})
|
|
}
|
|
}
|
|
|
|
// 下拉刷新处理
|
|
const handleRefresh = async () => {
|
|
setRefreshing(true)
|
|
try {
|
|
await loadTemplates()
|
|
Taro.showToast({
|
|
title: '刷新成功',
|
|
icon: 'success',
|
|
duration: 1500
|
|
})
|
|
} catch (error) {
|
|
console.error('刷新失败:', error)
|
|
} finally {
|
|
setRefreshing(false)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
// 需要先检查是否有模板配置文件
|
|
loadTemplates()
|
|
}, [dispatch])
|
|
|
|
// 获取加载状态的显示文本
|
|
const getLoadingText = (state: LoadingState): string => {
|
|
switch (state) {
|
|
default:
|
|
return '请稍后...'
|
|
}
|
|
}
|
|
|
|
// 处理审核失败
|
|
const handleAuditFailure = (auditResult: ImageAuditResult) => {
|
|
const messages: Record<AuditConclusion, string> = {
|
|
[AuditConclusion.REJECT]: '图片内容不符合规范,请重新选择符合规范的图片',
|
|
[AuditConclusion.REVIEW]: '图片需要人工审核,请稍后重试或更换其他图片',
|
|
[AuditConclusion.UNCERTAIN]: '图片审核结果不确定,请重新选择图片',
|
|
[AuditConclusion.PASS]: '图片审核通过' // 虽然不会用到,但为了类型完整性
|
|
}
|
|
|
|
const message = auditResult.conclusion ? messages[auditResult.conclusion] : '图片审核失败,请重新选择图片'
|
|
|
|
Taro.showModal({
|
|
title: '图片审核未通过',
|
|
content: message,
|
|
confirmText: '我知道了',
|
|
showCancel: false,
|
|
success: () => {
|
|
console.log('用户确认审核失败信息')
|
|
}
|
|
})
|
|
}
|
|
|
|
const handleTemplateClick = async (template: Template) => {
|
|
if (loadingState) return // 防止重复点击
|
|
|
|
try {
|
|
// 第一步:选择并上传图片
|
|
Taro.showLoading({
|
|
title: getLoadingText('uploading'),
|
|
mask: true
|
|
})
|
|
|
|
const imageUrl = await sdk.chooseAndUploadImage({
|
|
onImageSelected: () => {
|
|
console.log('用户选择了图片')
|
|
},
|
|
onProgress: () => {
|
|
Taro.showLoading({
|
|
title: `请稍后...`,
|
|
mask: true
|
|
})
|
|
}
|
|
})
|
|
|
|
// 第二步:图片内容审核
|
|
setLoadingState('auditing')
|
|
Taro.showLoading({
|
|
title: getLoadingText('auditing'),
|
|
mask: true
|
|
})
|
|
|
|
const auditResult = await new Promise<ImageAuditResult>((resolve, reject) => {
|
|
submitAuditTask(
|
|
{
|
|
imageUrl,
|
|
options: {
|
|
enableCache: true,
|
|
timeout: 30000
|
|
}
|
|
},
|
|
(status, progress) => {
|
|
console.log('审核进度:', status, progress)
|
|
},
|
|
(result) => {
|
|
console.log('审核成功:', result)
|
|
resolve(result)
|
|
},
|
|
(error) => {
|
|
console.error('审核失败:', error)
|
|
reject(error)
|
|
}
|
|
)
|
|
})
|
|
|
|
// 第三步:检查审核结果
|
|
if (auditResult.conclusion === AuditConclusion.PASS) {
|
|
// 短暂延迟后继续业务处理
|
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
// 第四步:执行业务逻辑
|
|
setLoadingState('processing')
|
|
Taro.showLoading({
|
|
title: getLoadingText('processing'),
|
|
mask: true
|
|
})
|
|
|
|
try {
|
|
const taskId = await serverSdk.executeTemplate({
|
|
imageUrl,
|
|
templateCode: template.code
|
|
})
|
|
|
|
// 隐藏loading
|
|
Taro.hideLoading()
|
|
|
|
// 跳转到生成页面
|
|
navigateTo({
|
|
url: `/pages/generate/index?taskId=${taskId}&templateCode=${template.code}`
|
|
})
|
|
|
|
} catch (businessError) {
|
|
// 业务处理失败
|
|
Taro.hideLoading()
|
|
Taro.showToast({
|
|
title: '请等待生成中的任务完成后再尝试',
|
|
icon: 'none',
|
|
duration: 2000
|
|
})
|
|
}
|
|
|
|
} else {
|
|
// 审核不通过
|
|
Taro.hideLoading()
|
|
handleAuditFailure(auditResult)
|
|
}
|
|
|
|
} catch (error) {
|
|
// 统一错误处理
|
|
Taro.hideLoading()
|
|
|
|
if (typeof loadingState === 'string' && loadingState === 'uploading') {
|
|
Taro.showToast({
|
|
title: '图片上传失败,请重试',
|
|
icon: 'error',
|
|
duration: 2000
|
|
})
|
|
} else if (typeof loadingState === 'string' && loadingState === 'auditing') {
|
|
Taro.showToast({
|
|
title: '图片审核失败,请重试',
|
|
icon: 'error',
|
|
duration: 2000
|
|
})
|
|
} else {
|
|
Taro.showToast({
|
|
title: error instanceof Error ? error.message : '处理失败',
|
|
icon: 'error',
|
|
duration: 2000
|
|
})
|
|
}
|
|
|
|
console.error('模板处理错误:', error)
|
|
} finally {
|
|
setLoadingState(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<View className='home'>
|
|
<ScrollView
|
|
className='home-scroll'
|
|
scrollY
|
|
enhanced
|
|
showScrollbar={false}
|
|
enablePassive
|
|
bounces
|
|
scrollWithAnimation={false}
|
|
refresherEnabled
|
|
refresherTriggered={refreshing}
|
|
onRefresherRefresh={handleRefresh}
|
|
refresherBackground='#f8f9fa'
|
|
refresherDefaultStyle='black'
|
|
>
|
|
<View className='template-grid'>
|
|
{templates.map((template) => (
|
|
<TemplateCard
|
|
key={template.code}
|
|
template={template}
|
|
onClick={handleTemplateClick}
|
|
/>
|
|
))}
|
|
</View>
|
|
</ScrollView>
|
|
</View>
|
|
)
|
|
}
|