'use client'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Box, Typography, Checkbox, IconButton, Chip, Tooltip, Pagination, Divider, Paper, CircularProgress, TextField } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'; import EditIcon from '@mui/icons-material/Edit'; import ChatIcon from '@mui/icons-material/Chat'; import { useGenerateDataset } from '@/hooks/useGenerateDataset'; import { toast } from 'sonner'; import { useAtomValue } from 'jotai'; import { selectedModelInfoAtom } from '@/lib/store'; export default function QuestionListView({ questions = [], currentPage, totalQuestions = 0, handlePageChange, selectedQuestions = [], onSelectQuestion, onDeleteQuestion, projectId, onEditQuestion, refreshQuestions }) { const { t } = useTranslation(); // 处理状态 const [processingQuestions, setProcessingQuestions] = useState({}); const { generateSingleDataset } = useGenerateDataset(); // 获取当前选中的模型 const selectedModelInfo = useAtomValue(selectedModelInfoAtom); // 获取文本块的标题 const getChunkTitle = content => { const firstLine = content ? content.split('\n')[0].trim() : ''; if (firstLine.startsWith('# ')) { return firstLine.substring(2); } else if (firstLine.length > 0) { return firstLine.length > 200 ? firstLine.substring(0, 200) + '...' : firstLine; } return ''; }; // 检查问题是否被选中 const isQuestionSelected = questionId => { return selectedQuestions.includes(questionId); }; // 处理生成数据集 const handleGenerateDataset = async (questionId, questionInfo, imageId, imageName) => { // 设置处理状态 setProcessingQuestions(prev => ({ ...prev, [questionId]: true })); await generateSingleDataset({ projectId, questionId, questionInfo, imageId, imageName }); // 重置处理状态 setProcessingQuestions(prev => ({ ...prev, [questionId]: false })); refreshQuestions(); }; // 处理生成多轮对话数据集 const handleGenerateMultiTurnDataset = async (questionId, questionInfo) => { try { // 设置处理状态 setProcessingQuestions(prev => ({ ...prev, [`${questionId}_multi`]: true })); // 首先检查项目是否配置了多轮对话设置 const configResponse = await fetch(`/api/projects/${projectId}/tasks`); if (!configResponse.ok) { throw new Error('获取项目配置失败'); } const config = await configResponse.json(); const multiTurnConfig = { systemPrompt: config.multiTurnSystemPrompt, scenario: config.multiTurnScenario, rounds: config.multiTurnRounds, roleA: config.multiTurnRoleA, roleB: config.multiTurnRoleB }; console.log('multiTurnConfig:', multiTurnConfig); // 检查是否已配置必要的多轮对话设置 // 系统提示词是可选的,但场景、角色A、角色B和轮数是必需的 if ( !multiTurnConfig.scenario || !multiTurnConfig.roleA || !multiTurnConfig.roleB || !multiTurnConfig.rounds || multiTurnConfig.rounds < 1 ) { toast.error(t('questions.multiTurnNotConfigured', '请先在项目设置中配置多轮对话相关参数')); return; } // 检查是否选中了模型 if (!selectedModelInfo) { toast.error(t('datasets.selectModelFirst', '请先选择模型')); return; } // 调用多轮对话生成API const response = await fetch(`/api/projects/${projectId}/dataset-conversations`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ questionId, ...multiTurnConfig, model: selectedModelInfo }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || '生成多轮对话数据集失败'); } const result = await response.json(); toast.success(t('questions.multiTurnGenerated', '多轮对话数据集生成成功!')); } catch (error) { console.error('生成多轮对话数据集失败:', error); toast.error(error.message || '生成多轮对话数据集失败'); } finally { // 重置处理状态 setProcessingQuestions(prev => ({ ...prev, [`${questionId}_multi`]: false })); } }; return ( {/* 问题列表 */} {t('datasets.question')} {t('common.label')} {t('common.dataSource')} {t('common.actions')} {questions.map((question, index) => { const isSelected = isQuestionSelected(question.id); const questionKey = question.id; return ( { onSelectQuestion(questionKey); }} size="small" /> {question.question} {question.datasetCount > 0 ? ( ) : null} {question.label || t('datasets.noTag')} • ID: {(question.question || '').substring(0, 8)} {question.label ? ( ) : ( {t('datasets.noTag')} )} onEditQuestion(question)} disabled={processingQuestions[questionKey]} > handleGenerateDataset(question.id, question.question, question.imageId, question.imageName) } disabled={processingQuestions[questionKey]} > {processingQuestions[questionKey] ? ( ) : ( )} {!question.imageId && ( handleGenerateMultiTurnDataset(question.id, question.question)} disabled={processingQuestions[`${questionKey}_multi`]} > {processingQuestions[`${questionKey}_multi`] ? ( ) : ( )} )} onDeleteQuestion(question.id)} disabled={processingQuestions[questionKey]} > {index < questions.length - 1 && } ); })} {/* 分页 */} {totalQuestions > 1 && ( {t('common.jumpTo')}: { if (e.key === 'Enter') { const pageNum = parseInt(e.target.value, 10); if (pageNum >= 1 && pageNum <= totalQuestions) { handlePageChange(null, pageNum); e.target.value = ''; } } }} /> )} ); }