diff --git a/src/components/DownloadSection/index.tsx b/src/components/DownloadSection/index.tsx index 674e78f..58da191 100644 --- a/src/components/DownloadSection/index.tsx +++ b/src/components/DownloadSection/index.tsx @@ -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 = ({ onDownload, onRegenerate, loading, adAvailable = true }) => { +const DownloadSection: React.FC = ({ + onDownload, + onRegenerate, + onImageToVideo, + loading, + adAvailable = true, + showImageToVideo = false, + imageToVideoLoading = false +}) => { const getButtonText = () => { if (loading) { return '广告加载中...' @@ -40,6 +51,14 @@ const DownloadSection: React.FC = ({ onDownload, onRegener 🎨 再来一张 )} + {showImageToVideo && onImageToVideo && ( + + {imageToVideoLoading ? '🎬 生成中...' : '🎬 图片生视频'} + + )} {getTipText()} ) diff --git a/src/pages/result/index.tsx b/src/pages/result/index.tsx index 33617ca..c8c133e 100644 --- a/src/pages/result/index.tsx +++ b/src/pages/result/index.tsx @@ -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([]) 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 = () => { )