fix: user

This commit is contained in:
2026-03-17 23:43:19 +08:00
parent ef8ce120bb
commit ca12e55554
8 changed files with 132 additions and 26 deletions

View File

@@ -37,7 +37,8 @@ type ContentKeys =
| 'include_flow_chart'
| 'include_timeline'
| 'include_reasons'
| 'include_inquiry';
| 'include_inquiry'
| 'include_record_qa';
const contentOptions: Array<{ key: ContentKeys; label: string; defaultOn: boolean }> = [
{ key: 'include_summary', label: '被骗金额汇总表', defaultOn: true },
@@ -46,17 +47,18 @@ const contentOptions: Array<{ key: ContentKeys; label: string; defaultOn: boolea
{ key: 'include_timeline', label: '交易时间轴', defaultOn: true },
{ key: 'include_reasons', label: '认定理由与排除说明', defaultOn: true },
{ key: 'include_inquiry', label: '笔录辅助问询建议', defaultOn: false },
{ key: 'include_record_qa', label: '笔录问答草稿', defaultOn: false },
];
const STORAGE_PREFIX = 'report-content-';
const loadContentSelection = (caseId: string): Record<ContentKeys, boolean> => {
try {
const raw = localStorage.getItem(`${STORAGE_PREFIX}${caseId}`);
if (raw) return JSON.parse(raw);
} catch { /* ignore */ }
const defaults: Record<string, boolean> = {};
contentOptions.forEach((o) => { defaults[o.key] = o.defaultOn; });
try {
const raw = localStorage.getItem(`${STORAGE_PREFIX}${caseId}`);
if (raw) return { ...defaults, ...JSON.parse(raw) };
} catch { /* ignore */ }
return defaults as Record<ContentKeys, boolean>;
};

View File

@@ -36,6 +36,7 @@ import type { ColumnsType } from 'antd/es/table';
import type { FraudAssessment, ConfidenceLevel } from '../../types';
import {
fetchAssessments,
fetchCase,
submitReview,
fetchInquirySuggestions,
triggerAnalysis,
@@ -200,6 +201,10 @@ const Review: React.FC = () => {
queryFn: () => fetchAssessments(id),
refetchInterval: () => (Date.now() < autoRefreshUntil ? 2000 : false),
});
const { data: currentCase } = useQuery({
queryKey: ['case', id],
queryFn: () => fetchCase(id),
});
const { data: suggestionsData, isLoading: suggestionsLoading, isFetching: suggestionsFetching } = useQuery({
queryKey: ['suggestions', id],
queryFn: () => fetchInquirySuggestions(id),
@@ -213,6 +218,7 @@ const Review: React.FC = () => {
const allAssessments = assessData?.items ?? [];
const suggestions = suggestionsData?.suggestions ?? [];
const reviewedByName = (currentCase?.handler || '').trim() || 'demo_user';
const hasNoAnalysisResult =
suggestions.length === 1 && suggestions[0].includes('暂无分析结果');
@@ -412,7 +418,7 @@ const Review: React.FC = () => {
body: {
review_status: action,
review_note: `操作:${aiSuggestionLabel[action]}`,
reviewed_by: 'demo_user',
reviewed_by: reviewedByName,
},
});
};
@@ -996,7 +1002,7 @@ const Review: React.FC = () => {
body: {
review_status: reviewAction,
review_note: reviewNote,
reviewed_by: 'demo_user',
reviewed_by: reviewedByName,
},
});
}}
@@ -1027,7 +1033,7 @@ const Review: React.FC = () => {
body: {
review_status: 'needs_info',
review_note: supplementNote.trim(),
reviewed_by: 'demo_user',
reviewed_by: reviewedByName,
},
});
}}

View File

@@ -32,7 +32,7 @@ import {
} from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import type { TransactionRecord, SourceApp } from '../../types';
import { fetchImageDetail, fetchTransactions, updateTransaction } from '../../services/api';
import { fetchImageDetail, fetchTransactions, triggerAnalysis, updateTransaction } from '../../services/api';
const appTag: Record<SourceApp, { label: string; color: string }> = {
wechat: { label: '微信', color: 'green' },
@@ -78,6 +78,36 @@ const Transactions: React.FC = () => {
},
onError: () => message.error('交易修改保存失败'),
});
const analysisMutation = useMutation({
mutationFn: () => triggerAnalysis(id),
onMutate: () => {
message.open({
key: 'transactions-analysis',
type: 'loading',
content: '正在执行资金分析...',
duration: 0,
});
},
onSuccess: (res) => {
message.open({
key: 'transactions-analysis',
type: 'success',
content: res.message || '资金分析任务已提交',
});
qc.invalidateQueries({ queryKey: ['transactions', id] });
qc.invalidateQueries({ queryKey: ['assessments', id] });
qc.invalidateQueries({ queryKey: ['flows', id] });
qc.invalidateQueries({ queryKey: ['case', id] });
qc.invalidateQueries({ queryKey: ['suggestions', id] });
},
onError: () => {
message.open({
key: 'transactions-analysis',
type: 'error',
content: '资金分析执行失败',
});
},
});
const allTransactions = txData?.items ?? [];
const { data: detailImage, isFetching: detailImageFetching } = useQuery({
queryKey: ['image-detail', detail?.evidenceImageId],
@@ -356,16 +386,25 @@ const Transactions: React.FC = () => {
</Space>
}
extra={
<Select
value={filterDuplicate}
onChange={setFilterDuplicate}
style={{ width: 160 }}
options={[
{ label: '全部交易', value: 'all' },
{ label: '仅有效交易', value: 'unique' },
{ label: '仅重复交易', value: 'duplicate' },
]}
/>
<Space>
<Select
value={filterDuplicate}
onChange={setFilterDuplicate}
style={{ width: 160 }}
options={[
{ label: '全部交易', value: 'all' },
{ label: '仅有效交易', value: 'unique' },
{ label: '仅重复交易', value: 'duplicate' },
]}
/>
<Button
type="primary"
loading={analysisMutation.isPending}
onClick={() => analysisMutation.mutate()}
>
{analysisMutation.isPending ? '分析中...' : '执行资金分析'}
</Button>
</Space>
}
>
<Table

View File

@@ -298,6 +298,7 @@ export async function generateReport(
include_timeline?: boolean;
include_reasons?: boolean;
include_inquiry?: boolean;
include_record_qa?: boolean;
},
): Promise<ExportReport> {
if (!(await isBackendUp())) return mockReports[0];