'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 (
);
};
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}
/>
>
);
}