update: docs
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
Divider,
|
||||
Descriptions,
|
||||
Checkbox,
|
||||
Alert,
|
||||
message,
|
||||
Result,
|
||||
} from 'antd';
|
||||
@@ -21,7 +22,6 @@ import {
|
||||
FileTextOutlined,
|
||||
FileExcelOutlined,
|
||||
FilePdfOutlined,
|
||||
FileWordOutlined,
|
||||
DownloadOutlined,
|
||||
PrinterOutlined,
|
||||
HistoryOutlined,
|
||||
@@ -36,8 +36,7 @@ type ContentKeys =
|
||||
| 'include_flow_chart'
|
||||
| 'include_timeline'
|
||||
| 'include_reasons'
|
||||
| 'include_inquiry'
|
||||
| 'include_screenshots';
|
||||
| 'include_inquiry';
|
||||
|
||||
const contentOptions: Array<{ key: ContentKeys; label: string; defaultOn: boolean }> = [
|
||||
{ key: 'include_summary', label: '被骗金额汇总表', defaultOn: true },
|
||||
@@ -46,7 +45,6 @@ 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_screenshots', label: '原始截图附件', defaultOn: false },
|
||||
];
|
||||
|
||||
const STORAGE_PREFIX = 'report-content-';
|
||||
@@ -80,7 +78,7 @@ const Reports: React.FC = () => {
|
||||
const { id = '1' } = useParams();
|
||||
const qc = useQueryClient();
|
||||
const [generated, setGenerated] = useState(false);
|
||||
const [selectedFormats, setSelectedFormats] = useState<Array<'excel' | 'pdf' | 'word'>>([
|
||||
const [selectedFormats, setSelectedFormats] = useState<Array<'excel' | 'pdf'>>([
|
||||
'excel',
|
||||
'pdf',
|
||||
]);
|
||||
@@ -114,7 +112,7 @@ const Reports: React.FC = () => {
|
||||
);
|
||||
|
||||
const genMutation = useMutation({
|
||||
mutationFn: async (reportTypes: Array<'excel' | 'pdf' | 'word'>) => {
|
||||
mutationFn: async (reportTypes: Array<'excel' | 'pdf'>) => {
|
||||
const result = await Promise.all(
|
||||
reportTypes.map((reportType) =>
|
||||
generateReport(id, { report_type: reportType, ...contentSel }),
|
||||
@@ -150,7 +148,6 @@ const Reports: React.FC = () => {
|
||||
const map: Record<string, { icon: React.ReactNode; label: string; color: string }> = {
|
||||
pdf: { icon: <FilePdfOutlined />, label: 'PDF', color: 'red' },
|
||||
excel: { icon: <FileExcelOutlined />, label: 'Excel', color: 'green' },
|
||||
word: { icon: <FileWordOutlined />, label: 'Word', color: 'blue' },
|
||||
};
|
||||
const cfg = map[t] || map.pdf;
|
||||
return <Tag icon={cfg.icon} color={cfg.color}>{cfg.label}</Tag>;
|
||||
@@ -322,35 +319,17 @@ const Reports: React.FC = () => {
|
||||
</Checkbox>
|
||||
</div>
|
||||
</Card>
|
||||
<Card
|
||||
hoverable
|
||||
style={{ width: 140, textAlign: 'center' }}
|
||||
styles={{ body: { padding: 16 } }}
|
||||
>
|
||||
<FileWordOutlined style={{ fontSize: 32, color: '#1677ff' }} />
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<Typography.Text>Word 文书</Typography.Text>
|
||||
</div>
|
||||
<div>
|
||||
<Checkbox
|
||||
checked={selectedFormats.includes('word')}
|
||||
onChange={(e) => {
|
||||
setSelectedFormats((prev) =>
|
||||
e.target.checked
|
||||
? Array.from(new Set([...prev, 'word']))
|
||||
: prev.filter((x) => x !== 'word'),
|
||||
);
|
||||
}}
|
||||
>
|
||||
选择
|
||||
</Checkbox>
|
||||
</div>
|
||||
</Card>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Typography.Text strong>报告内容:</Typography.Text>
|
||||
<div style={{ margin: '12px 0 24px' }}>
|
||||
<Alert
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: 12 }}
|
||||
message="PDF 报告不包含原始截图附件,仅保留证据索引。"
|
||||
/>
|
||||
<Space direction="vertical">
|
||||
{contentOptions.map((opt) => (
|
||||
<Checkbox
|
||||
@@ -406,15 +385,6 @@ const Reports: React.FC = () => {
|
||||
>
|
||||
下载 PDF
|
||||
</Button>,
|
||||
<Button
|
||||
key="word"
|
||||
icon={<DownloadOutlined />}
|
||||
href={latestReportByType.word ? getReportDownloadUrl(latestReportByType.word.id) : undefined}
|
||||
target="_blank"
|
||||
disabled={!latestReportByType.word}
|
||||
>
|
||||
下载 Word
|
||||
</Button>,
|
||||
<Button
|
||||
key="print"
|
||||
icon={<PrinterOutlined />}
|
||||
|
||||
@@ -440,7 +440,11 @@ const Review: React.FC = () => {
|
||||
onClick={() => {
|
||||
setReviewModal(r);
|
||||
setEditableTx({ ...r.transaction });
|
||||
setReviewAction(getAiSuggestedAction(r, allAssessments));
|
||||
setReviewAction(
|
||||
r.reviewStatus === 'pending'
|
||||
? getAiSuggestedAction(r, allAssessments)
|
||||
: (r.reviewStatus as ReviewAction),
|
||||
);
|
||||
setReviewNote('');
|
||||
}}
|
||||
>
|
||||
@@ -788,34 +792,32 @@ const Review: React.FC = () => {
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{reviewModal.reviewStatus === 'pending' && (
|
||||
<>
|
||||
<Divider />
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Typography.Text strong>复核决定:</Typography.Text>
|
||||
<Typography.Text type="secondary">
|
||||
已默认选中 AI 建议:{aiSuggestionLabel[getAiSuggestedAction(reviewModal, allAssessments)]}
|
||||
</Typography.Text>
|
||||
<Select
|
||||
value={reviewAction}
|
||||
onChange={setReviewAction}
|
||||
style={{ width: '100%' }}
|
||||
options={[
|
||||
{ label: '确认 - 该笔计入被骗金额', value: 'confirmed' },
|
||||
{ label: '排除 - 该笔不计入被骗金额', value: 'rejected' },
|
||||
{ label: '需补充 - 需进一步调查确认', value: 'needs_info' },
|
||||
]}
|
||||
/>
|
||||
<Typography.Text strong>备注说明:</Typography.Text>
|
||||
<Input.TextArea
|
||||
rows={3}
|
||||
value={reviewNote}
|
||||
onChange={(e) => setReviewNote(e.target.value)}
|
||||
placeholder="请输入复核意见或备注..."
|
||||
/>
|
||||
</Space>
|
||||
</>
|
||||
)}
|
||||
<Divider />
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Typography.Text strong>复核决定:</Typography.Text>
|
||||
<Typography.Text type="secondary">
|
||||
{reviewModal.reviewStatus === 'pending'
|
||||
? `已默认选中 AI 建议:${aiSuggestionLabel[getAiSuggestedAction(reviewModal, allAssessments)]}`
|
||||
: '当前可修改复核状态并重新提交。'}
|
||||
</Typography.Text>
|
||||
<Select
|
||||
value={reviewAction}
|
||||
onChange={setReviewAction}
|
||||
style={{ width: '100%' }}
|
||||
options={[
|
||||
{ label: '确认 - 该笔计入被骗金额', value: 'confirmed' },
|
||||
{ label: '排除 - 该笔不计入被骗金额', value: 'rejected' },
|
||||
{ label: '需补充 - 需进一步调查确认', value: 'needs_info' },
|
||||
]}
|
||||
/>
|
||||
<Typography.Text strong>备注说明:</Typography.Text>
|
||||
<Input.TextArea
|
||||
rows={3}
|
||||
value={reviewNote}
|
||||
onChange={(e) => setReviewNote(e.target.value)}
|
||||
placeholder="请输入复核意见或备注..."
|
||||
/>
|
||||
</Space>
|
||||
|
||||
{reviewModal.reviewStatus !== 'pending' && reviewModal.reviewedBy && (
|
||||
<Descriptions column={2} size="small" style={{ marginTop: 16 }}>
|
||||
@@ -839,24 +841,22 @@ const Review: React.FC = () => {
|
||||
>
|
||||
关闭
|
||||
</Button>
|
||||
{reviewModal.reviewStatus === 'pending' && (
|
||||
<Button
|
||||
type="primary"
|
||||
loading={reviewMutation.isPending}
|
||||
onClick={() => {
|
||||
reviewMutation.mutate({
|
||||
assessmentId: reviewModal.id,
|
||||
body: {
|
||||
review_status: reviewAction,
|
||||
review_note: reviewNote,
|
||||
reviewed_by: 'demo_user',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
提交复核
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
type="primary"
|
||||
loading={reviewMutation.isPending}
|
||||
onClick={() => {
|
||||
reviewMutation.mutate({
|
||||
assessmentId: reviewModal.id,
|
||||
body: {
|
||||
review_status: reviewAction,
|
||||
review_note: reviewNote,
|
||||
reviewed_by: 'demo_user',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
提交复核
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -509,6 +509,23 @@ const Transactions: React.FC = () => {
|
||||
)}
|
||||
</Space>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="标记修改">
|
||||
<Select
|
||||
style={{ width: '100%' }}
|
||||
value={getEffectiveMark(detail)}
|
||||
options={[
|
||||
{ label: '重复', value: 'duplicate' },
|
||||
{ label: '中转', value: 'transit' },
|
||||
{ label: '有效', value: 'valid' },
|
||||
]}
|
||||
onChange={(val) =>
|
||||
setMarkOverrides((prev) => ({
|
||||
...prev,
|
||||
[detail.id]: val as 'duplicate' | 'transit' | 'valid',
|
||||
}))
|
||||
}
|
||||
/>
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -250,7 +250,6 @@ export async function generateReport(
|
||||
include_timeline?: boolean;
|
||||
include_reasons?: boolean;
|
||||
include_inquiry?: boolean;
|
||||
include_screenshots?: boolean;
|
||||
},
|
||||
): Promise<ExportReport> {
|
||||
if (!(await isBackendUp())) return mockReports[0];
|
||||
|
||||
@@ -93,7 +93,7 @@ export interface FundFlowEdge {
|
||||
export interface ExportReport {
|
||||
id: string;
|
||||
caseId: string;
|
||||
reportType: 'pdf' | 'excel' | 'word';
|
||||
reportType: 'pdf' | 'excel';
|
||||
filePath: string;
|
||||
createdAt: string;
|
||||
version: number;
|
||||
|
||||
Reference in New Issue
Block a user