import React, { useCallback, useEffect, useState } from 'react'; import { useApi } from '@/hooks/useApi'; import { api } from '@/lib/api'; import type { VideoDataPaginationRequest } from '@/api/models/VideoDataPaginationRequest'; import type { PaginationResponse } from '@/api/models/PaginationResponse'; import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell } from '@/components/ui/table'; import { Button } from '@/components/ui/button'; import { Skeleton } from '@/components/ui/skeleton'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; import { Checkbox } from '@/components/ui/checkbox'; import { ACTION_PROMPTS } from '@/lib/prompt'; import { toast } from 'sonner'; import { addVideoTasks } from '@/lib/indexeddb'; import type { BatchVideoTaskRequest } from '@/api'; const PAGE_SIZE = 10; const promptGetter = (list: string[]) => { let index = 0; return () => { index++; return list[index % list.length]; }; }; const TryOnTasksPage: React.FC = () => { const [page, setPage] = useState(1); const [previewImg, setPreviewImg] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); const [selectedRows, setSelectedRows] = useState<{ id: number; img_url: string; task_id: string }[]>([]); const [createDialogOpen, setCreateDialogOpen] = useState(false); const [selectedPrompts, setSelectedPrompts] = useState([]); const [creating, setCreating] = useState(false); const r = useCallback(async (params: VideoDataPaginationRequest) => { const res = await api.DefaultService.getImageDataListApiImageDataListPost({ requestBody: params }); return res; }, []); const { data, loading, error, execute } = useApi(r, null); useEffect(() => { execute({ page, page_size: PAGE_SIZE }); }, [page, execute]); const handlePrev = () => setPage(p => Math.max(1, p - 1)); const handleNext = () => setPage(p => p + 1); // 判断某行是否被选中 const isRowSelected = (id: number) => selectedRows.some(row => row.id === id); // 当前页所有可选行id const currentPageIds = data?.data?.map(item => item.id) || []; // 当前页是否全选 const isAllCurrentPageSelected = currentPageIds.length > 0 && currentPageIds.every(id => isRowSelected(id)); // 单行选择 const handleRowSelect = (item: { id: number; img_url?: string; task_id?: string }) => { setSelectedRows(prev => { if (isRowSelected(item.id)) { return prev.filter(row => row.id !== item.id); } else { return [...prev, { id: item.id, img_url: item.img_url || '', task_id: item.task_id || '' }]; } }); }; // 当前页全选/取消 const handleSelectAllCurrentPage = () => { if (isAllCurrentPageSelected) { setSelectedRows(prev => prev.filter(row => !currentPageIds.includes(row.id))); } else { const toAdd = (data?.data || []) .filter(item => !isRowSelected(item.id)) .map(item => ({ id: item.id, img_url: item.img_url || '', task_id: item.task_id || '' })); setSelectedRows(prev => [...prev, ...toAdd]); } }; // 创建视频任务提交 const handleCreateTask = async () => { if (!selectedRows.length || !selectedPrompts.length) return; setCreating(true); const getPrompt = promptGetter(selectedPrompts); try { const tasks: BatchVideoTaskRequest['tasks'] = selectedRows.map(row => ({ prompt: getPrompt(), img_url: row.img_url, task_id: row.task_id, })); const res = (await api.Service.submitVideoTaskApiJmSubmitTaskPost({ requestBody: { tasks } })) as { status: boolean; data: { success: { task_id: string; img_url: string }[]; failed: string[] }; msg: string; }; // 只存储成功的任务 const successList = res?.data?.success || []; // 用于 prompt 匹配 const promptMap = new Map(); tasks.forEach(t => { if (!promptMap.has(t.img_url)) promptMap.set(t.img_url, []); promptMap.get(t.img_url).push(t.prompt); }); const localTasks = successList.map((item: any) => { // 取出 prompt(如有多 prompt,依次取出) let prompt = ''; if (promptMap.has(item.img_url)) { const arr = promptMap.get(item.img_url); prompt = arr.shift(); if (arr.length === 0) promptMap.delete(item.img_url); } return { id: `${item.task_id}`, img_url: item.img_url, prompt, create_time: new Date().toISOString(), job_id: item.job_id, task_id: item.task_id, }; }); await addVideoTasks(localTasks); toast.success('任务提交成功'); setCreateDialogOpen(false); setSelectedPrompts([]); setSelectedRows([]); } catch (e: any) { toast.error(e?.message || '任务提交失败'); } finally { setCreating(false); } }; return (
{/* 创建视频任务弹窗 */} 选择提示词
{ACTION_PROMPTS.map(prompt => ( ))}
{/* 图片预览 Dialog */} {previewImg && 预览图片}

任务列表

{loading ? ( ) : error ? (
{error}
) : ( 图片 ID 任务ID 图片状态 视频状态 创建时间 {data?.data?.length ? ( data.data.map(item => ( handleRowSelect(item)} /> {item.img_url ? ( img { setPreviewImg(item.img_url!); setDialogOpen(true); }} /> ) : ( )} {item.id} {item.task_id} {item.img_status || '-'} {item.video_status || '-'} {item.create_time || '-'} )) ) : ( 暂无数据 )}
)}
第 {page} 页
); }; export default TryOnTasksPage;