import { useState } from "react"; import { Button, Card, Input, Select, Badge, Progress, Checkbox, Switch, Form, Divider, message, } from "antd"; import { ArrowLeft, Play, Search as SearchIcon, Database, BarChart3, Shuffle, PieChart, } from "lucide-react"; import type { RatioConfig, RatioTask } from "@/pages/RatioTask/ratio"; import { mockRatioTasks } from "@/mock/ratio"; import type { Dataset } from "@/pages/DataManagement/dataset.model"; import { useNavigate } from "react-router"; import DevelopmentInProgress from "@/components/DevelopmentInProgress"; const { TextArea } = Input; const { Option } = Select; export default function CreateRatioTask() { return ; const navigate = useNavigate(); const [form] = Form.useForm(); // 配比任务相关状态 const [ratioTaskForm, setRatioTaskForm] = useState({ name: "", description: "", ratioType: "dataset" as "dataset" | "label", selectedDatasets: [] as string[], ratioConfigs: [] as RatioConfig[], totalTargetCount: 10000, autoStart: true, }); const [tasks, setTasks] = useState(mockRatioTasks); const [datasets] = useState([]); const handleCreateRatioTask = async () => { try { const values = await form.validateFields(); if (!ratioTaskForm.ratioConfigs.length) { message.error("请配置配比项"); return; } const newTask: RatioTask = { id: Date.now(), name: values.name, status: ratioTaskForm.autoStart ? "pending" : "paused", progress: 0, sourceDatasets: ratioTaskForm.selectedDatasets, targetCount: values.totalTargetCount, generatedCount: 0, createdAt: new Date().toISOString().split("T")[0], ratioType: ratioTaskForm.ratioType, estimatedTime: "预计 20 分钟", ratioConfigs: ratioTaskForm.ratioConfigs, }; setTasks([newTask, ...tasks]); setRatioTaskForm({ name: "", description: "", ratioType: "dataset", selectedDatasets: [], ratioConfigs: [], totalTargetCount: 10000, autoStart: true, }); form.resetFields(); message.success("配比任务创建成功"); navigate("/data/ratio-task"); } catch { // 校验失败 } }; const handleDatasetSelection = (datasetId: string, checked: boolean) => { if (checked) { setRatioTaskForm((prev) => ({ ...prev, selectedDatasets: [...prev.selectedDatasets, datasetId], })); } else { setRatioTaskForm((prev) => ({ ...prev, selectedDatasets: prev.selectedDatasets.filter( (id) => id !== datasetId ), ratioConfigs: prev.ratioConfigs.filter( (config) => config.source !== datasetId ), })); } }; const updateRatioConfig = (source: string, quantity: number) => { setRatioTaskForm((prev) => { const existingIndex = prev.ratioConfigs.findIndex( (config) => config.source === source ); const totalOtherQuantity = prev.ratioConfigs .filter((config) => config.source !== source) .reduce((sum, config) => sum + config.quantity, 0); const newConfig: RatioConfig = { id: source, name: source, type: prev.ratioType, quantity: Math.min( quantity, prev.totalTargetCount - totalOtherQuantity ), percentage: Math.round((quantity / prev.totalTargetCount) * 100), source, }; if (existingIndex >= 0) { const newConfigs = [...prev.ratioConfigs]; newConfigs[existingIndex] = newConfig; return { ...prev, ratioConfigs: newConfigs }; } else { return { ...prev, ratioConfigs: [...prev.ratioConfigs, newConfig] }; } }); }; const generateAutoRatio = () => { const selectedCount = ratioTaskForm.selectedDatasets.length; if (selectedCount === 0) return; const baseQuantity = Math.floor( ratioTaskForm.totalTargetCount / selectedCount ); const remainder = ratioTaskForm.totalTargetCount % selectedCount; const newConfigs: RatioConfig[] = ratioTaskForm.selectedDatasets.map( (datasetId, index) => { const quantity = baseQuantity + (index < remainder ? 1 : 0); return { id: datasetId, name: datasetId, type: ratioTaskForm.ratioType, quantity, percentage: Math.round( (quantity / ratioTaskForm.totalTargetCount) * 100 ), source: datasetId, }; } ); setRatioTaskForm((prev) => ({ ...prev, ratioConfigs: newConfigs })); }; const handleValuesChange = (_, allValues) => { setRatioTaskForm({ ...ratioTaskForm, ...allValues }); }; return ( {/* Header */} navigate("/data/synthesis/ratio-task")} > 创建配比任务 {/* 左侧:数据集选择 */} 数据集选择 配比方式: setRatioTaskForm({ ...ratioTaskForm, ratioType: value, ratioConfigs: [], }) } > 按数据集 按标签 } placeholder="搜索数据集" style={{ width: 180 }} // 可加搜索逻辑 /> {datasets.map((dataset) => ( handleDatasetSelection( dataset.id, !ratioTaskForm.selectedDatasets.includes(dataset.id) ) } > handleDatasetSelection(dataset.id, e.target.checked) } /> {dataset.name} {dataset.type} {dataset.description} {dataset.records?.toLocaleString()}条 {dataset.size} {dataset.format} {ratioTaskForm.ratioType === "label" && dataset.labels && ( {dataset.labels.map((label, index) => ( {label} ))} )} ))} 已选择 {ratioTaskForm.selectedDatasets.length} 个数据集 setRatioTaskForm({ ...ratioTaskForm, selectedDatasets: [], ratioConfigs: [], }) } > 清空选择 {/* 右侧:配比配置 */} 配比配置 配比设置 设置每个数据集的配比数量 } size="small" onClick={generateAutoRatio} disabled={ratioTaskForm.selectedDatasets.length === 0} > 平均分配 配比设置 已配置:{" "} {ratioTaskForm.ratioConfigs.reduce( (sum, config) => sum + config.quantity, 0 )}{" "} / {ratioTaskForm.totalTargetCount} {ratioTaskForm.selectedDatasets.length === 0 ? ( 请先选择数据集 ) : ( {ratioTaskForm.selectedDatasets.map((datasetId) => { const dataset = datasets.find( (d) => d.id === datasetId ); const config = ratioTaskForm.ratioConfigs.find( (c) => c.source === datasetId ); const currentQuantity = config?.quantity || 0; if (!dataset) return null; return ( {dataset.name} {dataset.records.toLocaleString()}条 {config?.percentage || 0}% {ratioTaskForm.ratioType === "dataset" ? ( 数量: updateRatioConfig( datasetId, Number(e.target.value) ) } style={{ width: 80 }} min={0} max={ratioTaskForm.totalTargetCount} /> 条 ) : ( {dataset.labels?.map((label, index) => { const labelConfig = ratioTaskForm.ratioConfigs.find( (c) => c.source === `${datasetId}_${label}` ); const labelQuantity = labelConfig?.quantity || 0; return ( {label} updateRatioConfig( `${datasetId}_${label}`, Number(e.target.value) ) } style={{ width: 70 }} min={0} /> 条 {Math.round( (labelQuantity / ratioTaskForm.totalTargetCount) * 100 )} % ); })} )} ); })} )} {/* 配比预览 */} {ratioTaskForm.ratioConfigs.length > 0 && ( 配比预览 总配比数量: {ratioTaskForm.ratioConfigs .reduce((sum, config) => sum + config.quantity, 0) .toLocaleString()} 目标数量: {ratioTaskForm.totalTargetCount.toLocaleString()} 配比项目: {ratioTaskForm.ratioConfigs.length}个 预计时间: 约 20 分钟 )} 创建后自动开始 任务创建完成后立即开始执行 setRatioTaskForm({ ...ratioTaskForm, autoStart: checked, }) } /> navigate("/data/synthesis/ratio-task")} > 取消 创建任务 ); }
请先选择数据集