Summary: - Migrate backend to modules/rvw with v2 API routes (/api/v2/rvw) - Add new database fields: selectedAgents, editorialScore, methodologyStatus, picoExtract, isArchived - Create frontend module in frontend-v2/src/modules/rvw - Implement Dashboard with task list, filtering, batch operations - Implement ReportDetail with dual tabs (editorial/methodology) - Implement AgentModal for intelligent agent selection - Register RVW module in moduleRegistry.ts - Add navigation entry in TopNavigation - Update documentation for RVW module status (v3.0) - Update system status document (v2.9) Features: - User can select agents: editorial, methodology, or both - Support batch task execution - Task status filtering - Replace console.log with logger service - Maintain v1 API backward compatibility Tested: Frontend and backend verified locally Status: 85% complete (Phase 1-3 done)
144 lines
2.1 KiB
TypeScript
144 lines
2.1 KiB
TypeScript
/**
|
||
* DC模块 - 最近任务Hook
|
||
*
|
||
* 管理最近任务列表的状态和数据获取
|
||
*/
|
||
|
||
import { useState, useEffect } from 'react';
|
||
import type { Task } from '../types/portal';
|
||
|
||
// Mock数据
|
||
const mockTasks: Task[] = [
|
||
{
|
||
id: 'task-001',
|
||
name: '2025糖尿病研究数据提取',
|
||
tool: 'tool-b',
|
||
toolName: 'AI结构化',
|
||
status: 'completed',
|
||
progress: 100,
|
||
createdAt: '2025-12-01T10:30:00Z',
|
||
completedAt: '2025-12-01T11:45:00Z'
|
||
},
|
||
{
|
||
id: 'task-002',
|
||
name: '高血压病历结构化处理',
|
||
tool: 'tool-b',
|
||
toolName: 'AI结构化',
|
||
status: 'processing',
|
||
progress: 65,
|
||
createdAt: '2025-12-02T09:15:00Z'
|
||
},
|
||
{
|
||
id: 'task-003',
|
||
name: '多中心数据合并任务',
|
||
tool: 'tool-a',
|
||
toolName: '超级合并器',
|
||
status: 'pending',
|
||
progress: 0,
|
||
createdAt: '2025-12-02T13:20:00Z'
|
||
}
|
||
];
|
||
|
||
export const useRecentTasks = () => {
|
||
const [tasks, setTasks] = useState<Task[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [error, setError] = useState<string | null>(null);
|
||
|
||
// 获取任务列表
|
||
const fetchTasks = async () => {
|
||
try {
|
||
setLoading(true);
|
||
|
||
// TODO: 替换为真实API调用
|
||
// const response = await fetch('/api/v1/dc/tasks/recent');
|
||
// const data = await response.json();
|
||
|
||
// 模拟API延迟
|
||
await new Promise(resolve => setTimeout(resolve, 500));
|
||
|
||
setTasks(mockTasks);
|
||
setError(null);
|
||
} catch (err) {
|
||
setError(err instanceof Error ? err.message : '获取任务列表失败');
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
// 轮询更新(processing状态的任务每5秒更新一次)
|
||
useEffect(() => {
|
||
fetchTasks();
|
||
|
||
const hasProcessingTasks = tasks.some(t => t.status === 'processing');
|
||
|
||
if (hasProcessingTasks) {
|
||
const interval = setInterval(() => {
|
||
fetchTasks();
|
||
}, 5000); // 5秒轮询
|
||
|
||
return () => clearInterval(interval);
|
||
}
|
||
}, []);
|
||
|
||
// 刷新任务列表
|
||
const refresh = () => {
|
||
fetchTasks();
|
||
};
|
||
|
||
return {
|
||
tasks,
|
||
loading,
|
||
error,
|
||
refresh
|
||
};
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|