feat: 添加图片生视频功能
- 在结果页面添加图片生视频按钮,仅在图片结果时显示 - 集成serverSdk调用executeTemplate接口生成视频 - 实现加载状态和错误处理机制 - 生成成功后跳转到生成页面查看进度 - 扩展DownloadSection组件支持新功能
This commit is contained in:
parent
be157d0bcb
commit
9e39ca842c
|
|
@ -4,12 +4,23 @@ import './index.css'
|
|||
interface DownloadSectionProps {
|
||||
onDownload: () => void
|
||||
onRegenerate?: () => void
|
||||
onImageToVideo?: () => void
|
||||
loading: boolean
|
||||
hasWatchedAd?: boolean
|
||||
adAvailable?: boolean
|
||||
showImageToVideo?: boolean
|
||||
imageToVideoLoading?: boolean
|
||||
}
|
||||
|
||||
const DownloadSection: React.FC<DownloadSectionProps> = ({ onDownload, onRegenerate, loading, adAvailable = true }) => {
|
||||
const DownloadSection: React.FC<DownloadSectionProps> = ({
|
||||
onDownload,
|
||||
onRegenerate,
|
||||
onImageToVideo,
|
||||
loading,
|
||||
adAvailable = true,
|
||||
showImageToVideo = false,
|
||||
imageToVideoLoading = false
|
||||
}) => {
|
||||
const getButtonText = () => {
|
||||
if (loading) {
|
||||
return '广告加载中...'
|
||||
|
|
@ -40,6 +51,14 @@ const DownloadSection: React.FC<DownloadSectionProps> = ({ onDownload, onRegener
|
|||
<Text>🎨 再来一张</Text>
|
||||
</View>
|
||||
)}
|
||||
{showImageToVideo && onImageToVideo && (
|
||||
<View
|
||||
className={`regenerate-btn ${imageToVideoLoading ? 'disabled' : ''}`}
|
||||
onClick={imageToVideoLoading ? undefined : onImageToVideo}
|
||||
>
|
||||
<Text>{imageToVideoLoading ? '🎬 生成中...' : '🎬 图片生视频'}</Text>
|
||||
</View>
|
||||
)}
|
||||
<Text className='download-tip'>{getTipText()}</Text>
|
||||
</View>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
import { View, Image, Video } from '@tarojs/components'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { saveImageToPhotosAlbum, saveVideoToPhotosAlbum, downloadFile, showToast, navigateBack, getCurrentInstance, hideToast } from '@tarojs/taro'
|
||||
import { saveImageToPhotosAlbum, saveVideoToPhotosAlbum, navigateTo, downloadFile, showToast, navigateBack, getCurrentInstance, hideToast } from '@tarojs/taro'
|
||||
import DownloadSection from '../../components/DownloadSection'
|
||||
import { useAd } from '../../hooks/useAd'
|
||||
import { useServerSdk } from '../../hooks/index'
|
||||
import './index.css'
|
||||
|
||||
const ResultPage: React.FC = () => {
|
||||
const [images, setImages] = useState<string[]>([])
|
||||
const [mediaType, setMediaType] = useState<'image' | 'video'>('image')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const serverSdk = useServerSdk()
|
||||
// 集成广告钩子
|
||||
const { showAd, loading: adLoading, adAvailable } = useAd({
|
||||
onReward: () => {
|
||||
|
|
@ -162,7 +165,7 @@ const ResultPage: React.FC = () => {
|
|||
// 提取扩展名
|
||||
const extensionMatch = fileName.match(/\.([^.]+)$/)
|
||||
const extension = extensionMatch ? extensionMatch[1].toLowerCase() : ''
|
||||
|
||||
|
||||
return { fileName, extension, cleanUrl }
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +190,7 @@ const ResultPage: React.FC = () => {
|
|||
hideToast()
|
||||
// 使用实际的文件路径
|
||||
const filePath = downloadRes.tempFilePath
|
||||
|
||||
|
||||
showToast({ title: '保存中...', icon: 'loading' })
|
||||
// 根据实际文件类型选择保存方法
|
||||
if (mediaType === 'video') {
|
||||
|
|
@ -249,6 +252,49 @@ const ResultPage: React.FC = () => {
|
|||
navigateBack()
|
||||
}
|
||||
|
||||
// 图片生视频
|
||||
const handleImageToVideo = async () => {
|
||||
if (mediaType !== 'image' || !images[0]) {
|
||||
showToast({
|
||||
title: '仅支持图片生成视频',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
setLoading(true)
|
||||
showToast({
|
||||
title: '正在生成视频...',
|
||||
icon: 'loading',
|
||||
duration: 60000
|
||||
})
|
||||
|
||||
const taskId = await serverSdk.executeTemplate({
|
||||
imageUrl: images[0],
|
||||
templateCode: 'character_figurine_v1'
|
||||
})
|
||||
|
||||
hideToast()
|
||||
|
||||
// 跳转到生成页面
|
||||
navigateTo({
|
||||
url: `/pages/generate/index?taskId=${taskId}&templateCode=character_figurine_v1`
|
||||
})
|
||||
} catch (error) {
|
||||
hideToast()
|
||||
console.error('图片生视频失败:', error)
|
||||
showToast({
|
||||
title: '生成失败,请重试',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
})
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 兼容原有的多图片显示
|
||||
if (!images.length) {
|
||||
|
|
@ -287,8 +333,11 @@ const ResultPage: React.FC = () => {
|
|||
<DownloadSection
|
||||
onDownload={showAd}
|
||||
onRegenerate={handleRegenerate}
|
||||
onImageToVideo={handleImageToVideo}
|
||||
loading={adLoading}
|
||||
adAvailable={adAvailable}
|
||||
showImageToVideo={mediaType === 'image'}
|
||||
imageToVideoLoading={loading}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue