refactor: 优化用户体验和代码清理

- 简化生成页面流程,成功后直接跳转到结果页
- 优化首页加载状态和错误处理逻辑
- 移除结果页面多余的调试日志
- 提升整体用户体验流畅度
This commit is contained in:
imeepos 2025-09-09 17:38:02 +08:00
parent dd97b8b439
commit be157d0bcb
3 changed files with 16 additions and 142 deletions

View File

@ -1,4 +1,4 @@
import { View, Text, Button, Image, Video } from '@tarojs/components' import { View, Text, Button } from '@tarojs/components'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import Taro, { switchTab, navigateTo } from '@tarojs/taro' import Taro, { switchTab, navigateTo } from '@tarojs/taro'
import { useServerSdk } from '../../hooks/index' import { useServerSdk } from '../../hooks/index'
@ -44,7 +44,10 @@ export default function Generate() {
if (result.status === 'completed') { if (result.status === 'completed') {
setStatus('success') setStatus('success')
setResult({ success: true, imageUrl: result.outputUrl, thumbnailUrl: result.thumbnailUrl }) navigateTo({
url: `/pages/result/index?images=${encodeURIComponent(JSON.stringify([result.outputUrl]))}`
})
return;
} else if (result.status === 'failed') { } else if (result.status === 'failed') {
setStatus('error') setStatus('error')
setResult({ success: false, error: result.error || '处理失败' }) setResult({ success: false, error: result.error || '处理失败' })
@ -98,73 +101,6 @@ export default function Generate() {
</View> </View>
) )
const renderSuccess = () => {
const isVideo = result?.imageUrl && (result.imageUrl.includes('.mp4') || result.imageUrl.includes('video'))
const mediaUrl = result?.imageUrl
return (
<View className='generate-success'>
<View className='success-header'>
<View className='success-badge'>
<Text className='success-icon'></Text>
<Text className='success-title'></Text>
</View>
<Text className='success-subtitle'></Text>
</View>
{mediaUrl && (
<View className='result-preview'>
<View className='preview-container'>
{isVideo ? (
<Video
className='preview-video'
src={mediaUrl}
autoplay
muted
loop
objectFit='cover'
showPlayBtn={false}
showCenterPlayBtn={false}
showFullscreenBtn={false}
controls={false}
poster={result?.thumbnailUrl}
/>
) : (
<Image
className='preview-image'
src={mediaUrl}
mode='aspectFit'
onClick={() => {
navigateTo({
url: `/pages/result/index?images=${encodeURIComponent(JSON.stringify([mediaUrl]))}`
})
}}
/>
)}
</View>
</View>
)}
<View className='success-actions'>
<View className='action-buttons'>
<Button className='btn-primary' onClick={handleTryAgain}>
<Text className='btn-text'></Text>
</Button>
<Button className='btn-secondary' onClick={handleViewHistory}>
<Text className='btn-text'></Text>
</Button>
</View>
{mediaUrl && (
<View className='result-tips'>
<Text className='tips-text'></Text>
</View>
)}
</View>
</View>
)
}
const renderError = () => ( const renderError = () => (
<View className='generate-error'> <View className='generate-error'>
<View className='error-container'> <View className='error-container'>
@ -185,7 +121,6 @@ export default function Generate() {
return ( return (
<View className='generate'> <View className='generate'>
{status === 'loading' && renderLoading()} {status === 'loading' && renderLoading()}
{status === 'success' && renderSuccess()}
{status === 'error' && renderError()} {status === 'error' && renderError()}
</View> </View>
) )

View File

@ -95,14 +95,14 @@ export default function Home() {
try { try {
// 第一步:选择并上传图片 // 第一步:选择并上传图片
Taro.showLoading({
title: getLoadingText('uploading'),
mask: true
})
const imageUrl = await sdk.chooseAndUploadImage({ const imageUrl = await sdk.chooseAndUploadImage({
onImageSelected: () => { onImageSelected: () => {
console.log('用户选择了图片') Taro.showLoading({
title: getLoadingText('uploading'),
mask: true,
})
}, },
onProgress: () => { onProgress: () => {
Taro.showLoading({ Taro.showLoading({
@ -111,14 +111,6 @@ export default function Home() {
}) })
} }
}) })
// 第二步:图片内容审核
setLoadingState('auditing')
Taro.showLoading({
title: getLoadingText('auditing'),
mask: true
})
const auditResult = await new Promise<ImageAuditResult>((resolve, reject) => { const auditResult = await new Promise<ImageAuditResult>((resolve, reject) => {
submitAuditTask( submitAuditTask(
{ {
@ -147,26 +139,17 @@ export default function Home() {
// 短暂延迟后继续业务处理 // 短暂延迟后继续业务处理
await new Promise(resolve => setTimeout(resolve, 1000)) await new Promise(resolve => setTimeout(resolve, 1000))
// 第四步:执行业务逻辑 // 第四步:执行业务逻辑
setLoadingState('processing')
Taro.showLoading({
title: getLoadingText('processing'),
mask: true
})
try { try {
const taskId = await serverSdk.executeTemplate({ const taskId = await serverSdk.executeTemplate({
imageUrl, imageUrl,
templateCode: template.code templateCode: template.code
}) })
// 隐藏loading // 隐藏loading
Taro.hideLoading() Taro.hideLoading()
// 跳转到生成页面 // 跳转到生成页面
navigateTo({ navigateTo({
url: `/pages/generate/index?taskId=${taskId}&templateCode=${template.code}` url: `/pages/generate/index?taskId=${taskId}&templateCode=${template.code}`
}) })
} catch (businessError) { } catch (businessError) {
// 业务处理失败 // 业务处理失败
Taro.hideLoading() Taro.hideLoading()
@ -176,40 +159,20 @@ export default function Home() {
duration: 2000 duration: 2000
}) })
} }
} else { } else {
// 审核不通过 // 审核不通过
Taro.hideLoading()
handleAuditFailure(auditResult) handleAuditFailure(auditResult)
} }
} catch (error) { } catch (error) {
// 统一错误处理 // 统一错误处理
Taro.hideLoading() Taro.hideLoading()
Taro.showToast({
if (typeof loadingState === 'string' && loadingState === 'uploading') { title: '图片审核失败,请重试',
Taro.showToast({ icon: 'error',
title: '图片上传失败,请重试', duration: 2000
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 { } finally {
setLoadingState(false)
} }
} }

View File

@ -167,7 +167,6 @@ const ResultPage: React.FC = () => {
} }
const fileInfo = getFileInfoFromUrl(mediaUrl) const fileInfo = getFileInfoFromUrl(mediaUrl)
console.log('文件信息:', fileInfo)
// 根据文件类型确定正确的扩展名 // 根据文件类型确定正确的扩展名
let finalExtension = fileInfo.extension let finalExtension = fileInfo.extension
@ -176,11 +175,6 @@ const ResultPage: React.FC = () => {
finalExtension = mediaType === 'video' ? 'mp4' : 'jpg' finalExtension = mediaType === 'video' ? 'mp4' : 'jpg'
} }
// 构造带扩展名的文件名
const baseFileName = fileInfo.fileName.includes('.')
? fileInfo.fileName
: `${fileInfo.fileName}.${finalExtension}`
// 先下载文件到临时目录,指定文件路径 // 先下载文件到临时目录,指定文件路径
showToast({ title: '下载中...', icon: 'loading', duration: 1000 * 60 }) showToast({ title: '下载中...', icon: 'loading', duration: 1000 * 60 })
const downloadRes = await downloadFile({ const downloadRes = await downloadFile({
@ -191,27 +185,9 @@ const ResultPage: React.FC = () => {
} }
}) })
hideToast() hideToast()
console.log('下载完成:', downloadRes.tempFilePath || downloadRes.filePath)
console.log('下载响应头:', JSON.stringify(downloadRes.header, null, 2))
// 使用实际的文件路径 // 使用实际的文件路径
const filePath = downloadRes.tempFilePath const filePath = downloadRes.tempFilePath
// 更准确的文件类型判断:优先使用扩展名,其次使用 mediaType
const isVideoFile = finalExtension && ['mp4', 'webm', 'ogg', 'mov', 'avi', 'mkv', 'flv'].includes(finalExtension) ||
mediaType === 'video'
const isImageFile = finalExtension && ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(finalExtension) ||
mediaType === 'image'
console.log('文件类型判断:', {
mediaUrl,
filePath,
finalExtension,
isVideoFile,
isImageFile,
mediaType,
baseFileName
})
showToast({ title: '保存中...', icon: 'loading' }) showToast({ title: '保存中...', icon: 'loading' })
// 根据实际文件类型选择保存方法 // 根据实际文件类型选择保存方法
if (mediaType === 'video') { if (mediaType === 'video') {