feat(rvw): Complete Phase 4-5 - Bug fixes and Word export
Summary: - Fix methodology score display issue in task list (show score instead of 'warn') - Add methodology_score field to database schema - Fix report display when only methodology agent is selected - Implement Word document export using docx library - Update documentation to v3.0/v3.1 Backend changes: - Add methodologyScore to Prisma schema and TaskSummary type - Update reviewWorker to save methodologyScore - Update getTaskList to return methodologyScore Frontend changes: - Install docx and file-saver libraries - Implement handleExportReport with Word generation - Fix activeTab auto-selection based on available data - Add proper imports for docx components Documentation: - Update RVW module status to 90% (Phase 1-5 complete) - Update system status document to v3.0 Tested: All review workflows verified, Word export functional
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
BatchToolbar,
|
||||
AgentModal,
|
||||
ReportDetail,
|
||||
TaskDetail,
|
||||
} from './components';
|
||||
import * as api from './api';
|
||||
import type { ReviewTask, ReviewReport, TaskFilters, AgentType } from './types';
|
||||
@@ -28,6 +29,10 @@ export default function Dashboard() {
|
||||
|
||||
// 报告详情
|
||||
const [reportDetail, setReportDetail] = useState<ReviewReport | null>(null);
|
||||
|
||||
// 任务详情(支持进度显示)
|
||||
const [viewingTask, setViewingTask] = useState<ReviewTask | null>(null);
|
||||
const [currentJobId, setCurrentJobId] = useState<string | null>(null);
|
||||
|
||||
// ==================== 数据加载 ====================
|
||||
const loadTasks = useCallback(async () => {
|
||||
@@ -114,12 +119,25 @@ export default function Dashboard() {
|
||||
};
|
||||
|
||||
const handleConfirmRun = async (agents: AgentType[]) => {
|
||||
// 🔥 保存到局部变量,避免onClose后丢失
|
||||
const taskToRun = pendingTaskForRun;
|
||||
|
||||
// 立即关闭弹窗
|
||||
setAgentModalVisible(false);
|
||||
setPendingTaskForRun(null);
|
||||
|
||||
try {
|
||||
if (pendingTaskForRun) {
|
||||
// 单个任务
|
||||
if (taskToRun) {
|
||||
// 单个任务 - 启动后跳转到详情页显示进度
|
||||
message.loading({ content: '正在启动审查...', key: 'run' });
|
||||
await api.runTask(pendingTaskForRun.id, agents);
|
||||
const { jobId } = await api.runTask(taskToRun.id, agents);
|
||||
message.success({ content: '审查已启动', key: 'run', duration: 2 });
|
||||
|
||||
// 更新任务状态后跳转到详情页(传递jobId)
|
||||
const updatedTask = await api.getTask(taskToRun.id);
|
||||
setCurrentJobId(jobId);
|
||||
setViewingTask(updatedTask);
|
||||
return;
|
||||
} else {
|
||||
// 批量任务
|
||||
const pendingIds = selectedIds.filter(id => {
|
||||
@@ -145,13 +163,22 @@ export default function Dashboard() {
|
||||
};
|
||||
|
||||
const handleViewReport = async (task: ReviewTask) => {
|
||||
// 直接使用TaskDetail视图(支持进度和报告)
|
||||
setViewingTask(task);
|
||||
};
|
||||
|
||||
const handleDeleteTask = async (task: ReviewTask) => {
|
||||
if (!window.confirm(`确定要删除 "${task.fileName}" 吗?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
message.loading({ content: '加载报告中...', key: 'report' });
|
||||
const report = await api.getTaskReport(task.id);
|
||||
setReportDetail(report);
|
||||
message.destroy('report');
|
||||
message.loading({ content: '正在删除...', key: 'delete' });
|
||||
await api.deleteTask(task.id);
|
||||
message.success({ content: '删除成功', key: 'delete', duration: 2 });
|
||||
loadTasks();
|
||||
} catch (error: any) {
|
||||
message.error({ content: '加载报告失败', key: 'report', duration: 3 });
|
||||
message.error({ content: error.message || '删除失败', key: 'delete', duration: 3 });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -159,9 +186,29 @@ export default function Dashboard() {
|
||||
setReportDetail(null);
|
||||
};
|
||||
|
||||
// 返回列表并刷新
|
||||
const handleBackFromDetail = () => {
|
||||
setViewingTask(null);
|
||||
setCurrentJobId(null);
|
||||
loadTasks();
|
||||
};
|
||||
|
||||
// ==================== 渲染 ====================
|
||||
|
||||
// 报告详情视图
|
||||
// 任务详情视图(支持进度显示)
|
||||
if (viewingTask) {
|
||||
return (
|
||||
<div className="h-full flex overflow-hidden bg-slate-50">
|
||||
<Sidebar
|
||||
currentView={currentView}
|
||||
onViewChange={setCurrentView}
|
||||
/>
|
||||
<TaskDetail task={viewingTask} jobId={currentJobId} onBack={handleBackFromDetail} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 报告详情视图(旧版,保留兼容)
|
||||
if (reportDetail) {
|
||||
return (
|
||||
<div className="h-full flex overflow-hidden bg-slate-50">
|
||||
@@ -207,6 +254,7 @@ export default function Dashboard() {
|
||||
onSelectChange={setSelectedIds}
|
||||
onViewReport={handleViewReport}
|
||||
onRunTask={handleRunTask}
|
||||
onDeleteTask={handleDeleteTask}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -234,3 +282,4 @@ export default function Dashboard() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user