Files
AIclinicalresearch/frontend-v2/src/modules/asl/hooks/useFulltextResults.ts
HaHafeng 75ceeb0653 hotfix(dc/tool-c): Fix compute formula validation and binning NaN serialization
Critical fixes:
1. Compute column: Add Chinese comma support in formula validation
   - Problem: Formula with Chinese comma failed validation
   - Fix: Add Chinese comma character to allowed_chars regex
   - Example: Support formulas like 'col1(kg)+ col2,col3'

2. Binning operation: Fix NaN serialization error
   - Problem: 'Out of range float values are not JSON compliant: nan'
   - Fix: Enhanced NaN/inf handling in binning endpoint
   - Added np.inf/-np.inf replacement before JSON serialization
   - Added manual JSON serialization with NaN->null conversion

3. Enhanced all operation endpoints for consistency
   - Updated conditional, dropna endpoints with same NaN/inf handling
   - Ensures all operations return JSON-compliant data

Modified files:
- extraction_service/operations/compute.py: Add Chinese comma to regex
- extraction_service/main.py: Enhanced NaN handling in binning/conditional/dropna

Status: Hotfix complete, ready for testing
2025-12-09 08:45:27 +08:00

120 lines
2.2 KiB
TypeScript

/**
* 全文复筛结果Hook
*
* 功能:
* 1. 获取结果列表
* 2. 分页支持
* 3. 筛选支持
* 4. 人工复核
*/
import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { message } from 'antd';
import { aslApi } from '../api';
interface UseFulltextResultsOptions {
taskId: string;
page?: number;
pageSize?: number;
filter?: 'all' | 'conflict' | 'pending' | 'reviewed';
enabled?: boolean;
}
export function useFulltextResults({
taskId,
page = 1,
pageSize = 20,
filter = 'all',
enabled = true,
}: UseFulltextResultsOptions) {
const queryClient = useQueryClient();
// 获取结果列表
const {
data,
isLoading,
error,
refetch,
} = useQuery({
queryKey: ['fulltextResults', taskId, page, pageSize, filter],
queryFn: async () => {
const response = await aslApi.getFulltextTaskResults(taskId, {
page,
pageSize,
filter,
});
return response.data;
},
enabled: enabled && !!taskId,
retry: 1,
});
// 人工复核Mutation
const reviewMutation = useMutation({
mutationFn: async ({
resultId,
decision,
note,
}: {
resultId: string;
decision: 'include' | 'exclude';
note?: string;
}) => {
const exclusionReason = decision === 'exclude' ? note || '未提供原因' : undefined;
await aslApi.updateFulltextDecision(resultId, {
finalDecision: decision,
exclusionReason,
reviewNotes: note,
});
},
onSuccess: () => {
message.success('复核提交成功');
// 刷新结果列表
queryClient.invalidateQueries({ queryKey: ['fulltextResults', taskId] });
},
onError: (error: Error) => {
message.error('复核提交失败: ' + error.message);
},
});
const results = data?.results || [];
const total = data?.total || 0;
const summary = data?.summary || {
totalResults: 0,
conflictCount: 0,
pendingReview: 0,
reviewed: 0,
};
return {
results,
total,
summary,
isLoading,
error,
refetch,
review: reviewMutation.mutate,
isReviewing: reviewMutation.isPending,
};
}