import React, { useState, useEffect } from 'react'; import { Button, Form, Input, Select, message, Modal, Row, Col, Table, Space } from 'antd'; import { EyeOutlined } from '@ant-design/icons'; import { queryDatasetsUsingGet } from "@/pages/DataManagement/dataset.api.ts"; import { mapDataset } from "@/pages/DataManagement/dataset.const.tsx"; import { queryModelListUsingGet } from "@/pages/SettingsPage/settings.apis.ts"; import { ModelI } from "@/pages/SettingsPage/ModelAccess.tsx"; import { createEvaluationTaskUsingPost } from "@/pages/DataEvaluation/evaluation.api.ts"; import { queryPromptTemplatesUsingGet } from "@/pages/DataEvaluation/evaluation.api.ts"; import PreviewPromptModal from "@/pages/DataEvaluation/Create/PreviewPrompt.tsx"; import { EVAL_METHODS, TASK_TYPES } from "@/pages/DataEvaluation/evaluation.const.tsx"; interface Dataset { id: string; name: string; fileCount: number; size: string; } interface Dimension { key: string; dimension: string; description: string; } interface PromptTemplate { evalType: string; prompt: string; defaultDimensions: Dimension[]; } interface CreateTaskModalProps { visible: boolean; onCancel: () => void; onSuccess: () => void; } const DEFAULT_EVAL_METHOD = 'AUTO'; const DEFAULT_TASK_TYPE = 'QA'; const CreateTaskModal: React.FC = ({ visible, onCancel, onSuccess }) => { const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const [datasets, setDatasets] = useState([]); const [models, setModels] = useState([]); const [dimensions, setDimensions] = useState([]); const [newDimension, setNewDimension] = useState>({ dimension: '', description: '' }); const [taskType, setTaskType] = useState(DEFAULT_TASK_TYPE); const [promptTemplates, setPromptTemplates] = useState([]); const [previewVisible, setPreviewVisible] = useState(false); const [evaluationPrompt, setEvaluationPrompt] = useState(''); const handleAddDimension = () => { if (!newDimension.dimension.trim()) { message.warning('请输入维度名称'); return; } setDimensions([...dimensions, { ...newDimension, key: `dim-${Date.now()}` }]); setNewDimension({ dimension: '', description: '' }); }; const handleDeleteDimension = (key: string) => { if (dimensions.length <= 1) { message.warning('至少需要保留一个评估维度'); return; } setDimensions(dimensions.filter(item => item.key !== key)); }; useEffect(() => { if (visible) { fetchDatasets().then(); fetchModels().then(); fetchPromptTemplates().then(); // sync form with local taskType default form.setFieldsValue({ taskType: DEFAULT_TASK_TYPE }); } }, [visible]); // when promptTemplates or taskType change, switch dimensions to template defaults (COT/QA) useEffect(() => { if (!promptTemplates || promptTemplates.length === 0) return; const template = promptTemplates.find(t => t.evalType === taskType); if (template && template.defaultDimensions) { setDimensions(template.defaultDimensions.map((dim: any, index: number) => ({ key: `dim-${index}`, dimension: dim.dimension, description: dim.description }))); } }, [taskType, promptTemplates]); const fetchDatasets = async () => { try { const { data } = await queryDatasetsUsingGet({ page: 1, size: 1000 }); setDatasets(data.content.map(mapDataset) || []); } catch (error) { console.error('Error fetching datasets:', error); message.error('获取数据集列表失败'); } }; const fetchModels = async () => { try { const { data } = await queryModelListUsingGet({ page: 0, size: 1000 }); setModels(data.content || []); } catch (error) { console.error('Error fetching models:', error); message.error('获取模型列表失败'); } }; const formatDimensionsForPrompt = (dimensions: Dimension[]) => { let result = ""; dimensions.forEach((dim, index) => { if (index > 0) { result += "\n"; } result += `### ${index + 1}. ${dim.dimension}\n**评估标准:**\n${dim.description}`; if (index < dimensions.length - 1) { result += "\n"; } }); return result; }; const formatResultExample = (dimensions: Dimension[]) => { let result = ""; dimensions.forEach((dim, index) => { if (index > 0) { result += "\n "; } result += `"${dim.dimension}": "Y"`; if (index < dimensions.length - 1) { result += ","; } }); return result; }; const fetchPromptTemplates = async () => { try { const response = await queryPromptTemplatesUsingGet(); const templates: PromptTemplate[] = response.data?.templates || []; setPromptTemplates(templates); // if a template exists for current taskType, initialize dimensions (handled also by useEffect) const template = templates.find(t => t.evalType === taskType); if (template) { setDimensions(template.defaultDimensions.map((dim: any, index: number) => ({ key: `dim-${index}`, dimension: dim.dimension, description: dim.description }))); } } catch (error) { console.error('Error fetching prompt templates:', error); message.error('获取评估维度失败'); } }; const generateEvaluationPrompt = () => { if (dimensions.length === 0) { message.warning('请先添加评估维度'); return; } const template = promptTemplates.find(t => t.evalType === taskType); const basePrompt = template?.prompt || ''; const filled = basePrompt .replace('{dimensions}', formatDimensionsForPrompt(dimensions)) .replace('{result_example}', formatResultExample(dimensions)); setEvaluationPrompt(filled); setPreviewVisible(true); }; const chatModelOptions = models .filter((model) => model.type === "CHAT") .map((model) => ({ label: `${model.modelName} (${model.provider})`, value: model.id, })); const handleSubmit = async (values: any) => { if (dimensions.length === 0) { message.warning('请至少添加一个评估维度'); return; } try { setLoading(true); const { datasetId, modelId, ...rest } = values; const selectedDataset = datasets.find(d => d.id === datasetId); const selectedModel = models.find(d => d.id === modelId); const payload = { ...rest, sourceType: 'DATASET', sourceId: datasetId, sourceName: selectedDataset?.name, evalConfig: { modelId: selectedModel?.id, dimensions: dimensions.map(d => ({ dimension: d.dimension, description: d.description })) } }; await createEvaluationTaskUsingPost(payload); message.success('评估任务创建成功'); onSuccess(); form.resetFields(); onCancel(); } catch (error: any) { console.error('Error creating task:', error); message.error(error.response?.data?.message || '创建评估任务失败'); } finally { setLoading(false); } }; const columns = [ { title: '维度', dataIndex: 'dimension', key: 'dimension', width: '30%', }, { title: '描述', dataIndex: 'description', key: 'description', width: '60%', }, { title: '操作', key: 'action', width: '10%', render: (_: any, record: any) => ( handleDeleteDimension(record.key)} style={{ color: dimensions.length <= 1 ? '#ccc' : '#ff4d4f' }} className={dimensions.length <= 1 ? 'disabled-link' : ''} > 删除 ), }, ]; return (
{ if (changed.taskType) { setTaskType(changed.taskType); setEvaluationPrompt(''); setPreviewVisible(false); } }} > {datasets.map((dataset) => (
{dataset.name} {dataset.size}
))}
setNewDimension({...newDimension, dimension: e.target.value})} style={{ flex: 1 }} /> setNewDimension({...newDimension, description: e.target.value})} style={{ flex: 2 }} />
)}
setPreviewVisible(false)} evaluationPrompt={evaluationPrompt} /> ); }; export default CreateTaskModal;