'use client'; import { useRouter } from 'next/navigation'; import { useState, useEffect } from 'react'; import { Box, Typography, IconButton, Chip, Checkbox, Tooltip, Card, CardContent, CardActions, Dialog, DialogTitle, DialogContent, DialogActions, Button, TextField, CircularProgress } from '@mui/material'; import DeleteIcon from '@mui/icons-material/Delete'; import VisibilityIcon from '@mui/icons-material/Visibility'; import QuizIcon from '@mui/icons-material/Quiz'; import EditIcon from '@mui/icons-material/Edit'; import CleaningServicesIcon from '@mui/icons-material/CleaningServices'; import AssignmentIcon from '@mui/icons-material/Assignment'; import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; // 编辑文本块对话框组件 const EditChunkDialog = ({ open, chunk, onClose, onSave }) => { const [content, setContent] = useState(chunk?.content || ''); const { t } = useTranslation(); // 当文本块变化时更新内容 useEffect(() => { if (chunk?.content) { setContent(chunk.content); } }, [chunk]); const handleSave = () => { onSave(content); onClose(); }; return ( {t('textSplit.editChunk', { chunkId: chunk?.name })} setContent(e.target.value)} variant="outlined" sx={{ mt: 1 }} /> ); }; export default function ChunkCard({ chunk, selected, onSelect, onView, onDelete, onGenerateQuestions, onDataCleaning, onEdit, onGenerateEvalQuestions, // 新增:生成测评题目的回调 projectId, selectedModel // 添加selectedModel参数 }) { const theme = useTheme(); const { t } = useTranslation(); const router = useRouter(); const [editDialogOpen, setEditDialogOpen] = useState(false); const [chunkForEdit, setChunkForEdit] = useState(null); const [generatingQuestions, setGeneratingQuestions] = useState(false); const [generatingEval, setGeneratingEval] = useState(false); // 获取文本预览 const getTextPreview = (content, maxLength = 150) => { if (!content) return ''; return content.length > maxLength ? `${content.substring(0, maxLength)}...` : content; }; // 检查是否有已生成的问题 const hasQuestions = chunk.questions && chunk.questions.length > 0; // 处理编辑按钮点击 const handleEditClick = async () => { try { // 显示加载状态 console.log('正在获取文本块完整内容...'); console.log('projectId:', projectId, 'chunkId:', chunk.id); // 先获取完整的文本块内容,使用从外部传入的 projectId const response = await fetch(`/api/projects/${projectId}/chunks/${encodeURIComponent(chunk.id)}`); if (!response.ok) { throw new Error(t('textSplit.fetchChunkFailed')); } const data = await response.json(); console.log('获取文本块完整内容成功:', data); // 先设置完整数据,再打开对话框(与 ChunkList.js 中的实现一致) setChunkForEdit(data); setEditDialogOpen(true); } catch (error) { console.error(t('textSplit.fetchChunkError'), error); // 如果出错,使用原始预览数据 alert(t('textSplit.fetchChunkError')); } }; // 处理保存编辑内容 const handleSaveEdit = newContent => { if (onEdit) { onEdit(chunk.id, newContent); } }; // 处理生成单个问题 - 后台执行,不阻塞UI const handleGenerateQuestionsClick = async () => { setGeneratingQuestions(true); try { await onGenerateQuestions([chunk.id]); } finally { // Always release loading state, even when generation fails. setTimeout(() => { setGeneratingQuestions(false); }, 500); } }; // 处理生成测评题目 const handleGenerateEvalQuestionsClick = async () => { if (!onGenerateEvalQuestions) return; setGeneratingEval(true); try { await onGenerateEvalQuestions(chunk.id); } finally { // 延迟关闭加载状态 setTimeout(() => { setGeneratingEval(false); }, 500); } }; return ( <> {chunk.name} {chunk.Questions.length > 0 && ( {chunk.Questions.map((q, index) => ( {index + 1}. {q.question} ))} } arrow placement="top" > { if (!projectId) return; router.push(`/projects/${projectId}/questions`); }} /> )} {chunk.EvalDatasets && chunk.EvalDatasets.length > 0 && ( { if (!projectId) return; router.push(`/projects/${projectId}/eval-datasets`); }} /> )} {getTextPreview(chunk.content)} {generatingQuestions ? : } {generatingEval ? : } {/* 编辑文本块对话框 */} { setEditDialogOpen(false); setChunkForEdit(null); }} onSave={handleSaveEdit} /> ); }