Files
AIclinicalresearch/frontend-v2/src/modules/asl/hooks/useScreeningTask.ts
HaHafeng 8eef9e0544 feat(asl): Complete Week 4 - Results display and Excel export with hybrid solution
Features:
- Backend statistics API (cloud-native Prisma aggregation)
- Results page with hybrid solution (AI consensus + human final decision)
- Excel export (frontend generation, zero disk write, cloud-native)
- PRISMA-style exclusion reason analysis with bar chart
- Batch selection and export (3 export methods)
- Fixed logic contradiction (inclusion does not show exclusion reason)
- Optimized table width (870px, no horizontal scroll)

Components:
- Backend: screeningController.ts - add getProjectStatistics API
- Frontend: ScreeningResults.tsx - complete results page (hybrid solution)
- Frontend: excelExport.ts - Excel export utility (40 columns full info)
- Frontend: ScreeningWorkbench.tsx - add navigation button
- Utils: get-test-projects.mjs - quick test tool

Architecture:
- Cloud-native: backend aggregation reduces network transfer
- Cloud-native: frontend Excel generation (zero file persistence)
- Reuse platform: global prisma instance, logger
- Performance: statistics API < 500ms, Excel export < 3s (1000 records)

Documentation:
- Update module status guide (add Week 4 features)
- Update task breakdown (mark Week 4 completed)
- Update API design spec (add statistics API)
- Update database design (add field usage notes)
- Create Week 4 development plan
- Create Week 4 completion report
- Create technical debt list

Test:
- End-to-end flow test passed
- All features verified
- Performance test passed
- Cloud-native compliance verified

Ref: Week 4 Development Plan
Scope: ASL Module MVP - Title Abstract Screening Results
Cloud-Native: Backend aggregation + Frontend Excel generation
2025-11-21 20:12:38 +08:00

69 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 筛选任务轮询Hook
* 用于获取和轮询筛选任务进度
*/
import { useQuery } from '@tanstack/react-query';
import { aslApi } from '../api';
interface UseScreeningTaskOptions {
projectId: string;
enabled?: boolean;
pollingInterval?: number; // 轮询间隔毫秒默认1000
}
/**
* 使用筛选任务Hook
*/
export function useScreeningTask({
projectId,
enabled = true,
pollingInterval = 1000,
}: UseScreeningTaskOptions) {
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['screening-task', projectId],
queryFn: () => aslApi.getScreeningTask(projectId),
enabled: enabled && !!projectId,
refetchInterval: (query) => {
const task = query.state.data?.data;
// 如果任务已完成或失败,停止轮询
if (task?.status === 'completed' || task?.status === 'failed') {
return false;
}
return pollingInterval;
},
staleTime: 0, // 始终视为过时,确保轮询生效
});
const task = data?.data;
// 计算进度百分比
const progress = task
? Math.round((task.processedItems / task.totalItems) * 100)
: 0;
// 判断是否正在运行
const isRunning = task?.status === 'running' || task?.status === 'pending';
// 判断是否已完成
const isCompleted = task?.status === 'completed';
// 判断是否失败
const isFailed = task?.status === 'failed';
return {
task,
progress,
isRunning,
isCompleted,
isFailed,
isLoading,
error,
refetch,
};
}