refactor: 将结果预览重构为独立页面

- 创建新的pages/result页面用于图片预览
- 修改index页面改用页面跳转替换组件调用
- 通过URL参数传递图片数据
- 在app.config.ts中注册新页面路由
- 删除ImageResultViewer组件,功能迁移至result页面
- 优化页面状态管理,简化index页面逻辑
This commit is contained in:
imeepos
2025-09-01 18:57:52 +08:00
parent 52b4786459
commit cef1c697a5
5 changed files with 70 additions and 49 deletions

View File

@@ -1,6 +1,7 @@
export default defineAppConfig({
pages: [
'pages/index/index'
'pages/index/index',
'pages/result/index'
],
window: {
backgroundTextStyle: 'light',

View File

@@ -1,17 +1,16 @@
import { View } from '@tarojs/components'
import { useState } from 'react'
import { navigateTo } from '@tarojs/taro'
import './index.css'
import { useSdk } from '../../hooks/index'
import UploadButton from '../../components/UploadButton'
import LoadingOverlay from '../../components/LoadingOverlay'
import ImageResultViewer from '../../components/ImageResultViewer'
import ErrorOverlay from '../../components/ErrorOverlay'
type PageStep = 'upload' | 'loading' | 'result' | 'error'
type PageStep = 'upload' | 'loading' | 'error'
interface AppState {
step: PageStep;
images: string[];
error: string | null;
}
@@ -19,7 +18,6 @@ export default function Index() {
const sdk = useSdk()
const [state, setState] = useState<AppState>({
step: 'upload',
images: [],
error: null
})
@@ -29,7 +27,7 @@ export default function Index() {
const task_id = await sdk.chooseAndGenerateImage({
onImageSelected: () => {
// 选择图片完成后立即显示loading
setState({ step: 'loading', images: [], error: null })
setState({ step: 'loading', error: null })
}
})
@@ -37,15 +35,21 @@ export default function Index() {
await new Promise((resolve) => setTimeout(resolve, 5000))
const urls = await sdk.getTaskStatus(task_id)
setState({ step: 'result', images: urls, error: null })
// 跳转到结果页面
navigateTo({
url: `/pages/result/index?images=${encodeURIComponent(JSON.stringify(urls))}`
})
// 重置状态
setState({ step: 'upload', error: null })
} catch (error) {
const errorMsg = error instanceof Error ? error.message : '生成失败'
setState({ step: 'error', images: [], error: errorMsg })
setState({ step: 'error', error: errorMsg })
}
}
const resetToUpload = () => {
setState({ step: 'upload', images: [], error: null })
setState({ step: 'upload', error: null })
}
const renderCurrentStep = () => {
@@ -54,8 +58,6 @@ export default function Index() {
return <UploadButton onUpload={chooseAndGenerateImage} />
case 'loading':
return <LoadingOverlay />
case 'result':
return <ImageResultViewer images={state.images} onClose={resetToUpload} />
case 'error':
return <ErrorOverlay onRetry={resetToUpload} />
default:

View File

@@ -0,0 +1,8 @@
export default definePageConfig({
navigationBarTitleText: '图片预览',
navigationBarBackgroundColor: '#2c3e50',
navigationBarTextStyle: 'white',
backgroundColorTop: '#2c3e50',
backgroundColorBottom: '#34495e',
backgroundColor: '#2c3e50'
})

View File

@@ -1,16 +1,12 @@
.fullscreen-container {
position: fixed;
top: 0;
left: 0;
.result-page {
width: 100%;
height: 100%;
height: 100vh;
background: black;
z-index: 999;
display: flex;
flex-direction: column;
}
.fullscreen-header {
.result-header {
display: flex;
justify-content: space-between;
align-items: center;
@@ -25,7 +21,7 @@
border-bottom: 2rpx solid rgba(255, 255, 255, 0.1);
}
.fullscreen-title {
.result-title {
font-size: 36rpx;
font-weight: bold;
}
@@ -42,7 +38,7 @@
text-align: center;
}
.fullscreen-image-container {
.result-image-container {
flex: 1;
width: 100%;
position: relative;
@@ -80,7 +76,7 @@
z-index: 1;
}
.fullscreen-image {
.result-image {
max-width: 100%;
max-height: 100%;
width: 100%;

View File

@@ -1,16 +1,13 @@
import { View, Text, Button, Image } from '@tarojs/components'
import { memo } from 'react'
import { saveImageToPhotosAlbum, downloadFile, showToast } from '@tarojs/taro'
import { View, Image } from '@tarojs/components'
import { memo, useEffect, useState } from 'react'
import { saveImageToPhotosAlbum, downloadFile, showToast, navigateBack, getCurrentInstance } from '@tarojs/taro'
import { useAd } from '../../hooks/useAd'
import DownloadSection from '../DownloadSection'
import DownloadSection from '../../components/DownloadSection'
import './index.css'
interface ImageResultViewerProps {
images: string[]
onClose: () => void
}
const ImageResultViewer: React.FC<ImageResultViewerProps> = memo(({ images, onClose }) => {
const ResultPage: React.FC = memo(() => {
const [images, setImages] = useState<string[]>([])
// 广告激励下载功能
const { loading: adLoading } = useAd({
onReward: () => {
@@ -24,8 +21,36 @@ const ImageResultViewer: React.FC<ImageResultViewerProps> = memo(({ images, onCl
}
})
useEffect(() => {
// 获取页面参数
const instance = getCurrentInstance()
const params = instance?.router?.params
if (params?.images) {
try {
const imageList = JSON.parse(decodeURIComponent(params.images))
setImages(imageList)
} catch (error) {
console.error('解析图片参数失败:', error)
showToast({
title: '参数错误',
icon: 'error'
})
navigateBack()
}
} else {
showToast({
title: '缺少图片参数',
icon: 'error'
})
navigateBack()
}
}, [])
// 下载图片到本地相册
const handleDownloadImages = async () => {
if (!images.length) return
try {
showToast({ title: '开始下载...', icon: 'loading' })
@@ -52,25 +77,14 @@ const ImageResultViewer: React.FC<ImageResultViewerProps> = memo(({ images, onCl
}
}
// 触发看广告下载
// const handleWatchAdToDownload = () => {
// if (adLoading) {
// showToast({ title: '广告加载中...', icon: 'loading' })
// return
// }
// showAd()
// }
if (!images.length) {
return null
}
return (
<View className="fullscreen-container">
<View className="fullscreen-header">
<Text className="fullscreen-title"></Text>
<View className="close-btn" onClick={onClose}>
</View>
</View>
<View className="result-page">
<View
className="fullscreen-image-container"
className="result-image-container"
style={{
backgroundImage: `url(${images[0]})`,
backgroundSize: 'cover',
@@ -79,7 +93,7 @@ const ImageResultViewer: React.FC<ImageResultViewerProps> = memo(({ images, onCl
}}
>
<View className="backdrop-blur">
<Image className="fullscreen-image" src={images[0]} mode="aspectFit" />
<Image className="result-image" src={images[0]} mode="aspectFit" />
</View>
</View>
<DownloadSection onDownload={handleDownloadImages} loading={adLoading} />
@@ -87,4 +101,4 @@ const ImageResultViewer: React.FC<ImageResultViewerProps> = memo(({ images, onCl
)
})
export default ImageResultViewer
export default ResultPage