Files
ccdi/docs/plans/frontend/2026-03-27-development-risk-suspicious-transaction-detail-frontend-implementation.md

303 lines
9.6 KiB
Markdown
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.
# 开发风险明细涉疑交易明细前端 Implementation Plan
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
>
> **Repo note:** 本仓库 `AGENTS.md` 明确禁止开启 subagent执行本计划时请在当前会话使用 `superpowers:executing-plans`。
**Goal:** 在结果总览页的“风险明细”区块内实现真实“涉疑交易明细”表格,支持来源切换、导出和查看详情,并保持表格与流水详情样式和“流水明细查询”页面一致。
**Architecture:** 前端继续以 `PreliminaryCheck.vue` 作为结果总览入口,通过 `projectOverview.js` 新增结果总览涉疑交易接口封装,在父组件加载后将数据注入 `RiskDetailSection.vue``RiskDetailSection.vue` 负责呈现筛选下拉、真实业务列、详情弹窗与导出按钮;详情接口直接复用 `ccdiProjectBankStatement.js` 中已有的 `getBankStatementDetail`
**Tech Stack:** Vue 2, Element UI, RuoYi 全局 `download`, Node `assert` 单测, axios request 封装
---
### Task 1: 新增结果总览涉疑交易前端 API 契约
**Files:**
- Modify: `ruoyi-ui/src/api/ccdi/projectOverview.js`
- Test: `ruoyi-ui/tests/unit/project-overview-api.test.js`
- [ ] **Step 1: 先补 API 契约测试,锁定新接口名和参数透传**
```js
[
"getOverviewSuspiciousTransactions",
"/ccdi/project/overview/suspicious-transactions",
"projectId: params.projectId",
"suspiciousType: params.suspiciousType",
"pageNum: params.pageNum",
"pageSize: params.pageSize",
].forEach((token) => assert(source.includes(token), token));
```
- [ ] **Step 2: 运行测试,确认新接口尚未接入**
Run:
```bash
node ruoyi-ui/tests/unit/project-overview-api.test.js
```
Expected: FAIL提示缺少 `getOverviewSuspiciousTransactions`
- [ ] **Step 3: 写最小 API 封装**
```js
export function getOverviewSuspiciousTransactions(params) {
return request({
url: "/ccdi/project/overview/suspicious-transactions",
method: "get",
params: {
projectId: params.projectId,
suspiciousType: params.suspiciousType,
pageNum: params.pageNum,
pageSize: params.pageSize,
},
});
}
```
- [ ] **Step 4: 回跑 API 契约测试**
Run:
```bash
node ruoyi-ui/tests/unit/project-overview-api.test.js
```
Expected: PASS
- [ ] **Step 5: 提交本任务**
```bash
git add ruoyi-ui/src/api/ccdi/projectOverview.js \
ruoyi-ui/tests/unit/project-overview-api.test.js
git commit -m "新增结果总览涉疑交易前端接口"
```
### Task 2: 把结果总览父组件接到真实涉疑交易数据
**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue`
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js`
- Create: `ruoyi-ui/tests/unit/preliminary-check-suspicious-transaction-load.test.js`
- [ ] **Step 1: 先写失败测试,锁定父组件加载新接口和风险明细数据结构**
```js
assert(source.includes("getOverviewSuspiciousTransactions"), "结果总览应加载涉疑交易接口");
assert(source.includes("riskDetails"), "结果总览应继续向 RiskDetailSection 注入 riskDetails");
assert(source.includes("suspiciousTransactionList"), "mock 归一化应保留涉疑交易列表");
```
- [ ] **Step 2: 运行测试,确认当前仍是 mock 空数组**
Run:
```bash
node ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js
node ruoyi-ui/tests/unit/preliminary-check-suspicious-transaction-load.test.js
```
Expected:
- 旧测试仍只认“涉险交易明细”
- 新测试提示未加载涉疑交易接口
- [ ] **Step 3: 在父组件中并行加载涉疑交易接口,并改造 mock 归一化函数**
```js
const [dashboardRes, riskPeopleRes, riskModelCardsRes, suspiciousRes] = await Promise.all([
getOverviewDashboard(this.projectId),
getOverviewRiskPeople(this.projectId),
getOverviewRiskModelCards(this.projectId),
getOverviewSuspiciousTransactions({
projectId: this.projectId,
suspiciousType: "ALL",
pageNum: 1,
pageSize: 10,
}),
]);
```
```js
riskDetails: {
suspiciousTransactionList: normalizeSuspiciousTransactions(suspiciousData && suspiciousData.rows),
suspiciousType: "ALL",
total: suspiciousData && suspiciousData.total ? suspiciousData.total : 0,
abnormalAccountList: [],
}
```
- [ ] **Step 4: 回跑父组件相关测试**
Run:
```bash
node ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js
node ruoyi-ui/tests/unit/preliminary-check-suspicious-transaction-load.test.js
```
Expected: PASS
- [ ] **Step 5: 提交本任务**
```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue \
ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js \
ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js \
ruoyi-ui/tests/unit/preliminary-check-suspicious-transaction-load.test.js
git commit -m "接通结果总览涉疑交易数据加载"
```
### Task 3: 重写 RiskDetailSection 的涉疑交易表格列和筛选交互
**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/RiskDetailSection.vue`
- Test: `ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js`
- Create: `ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js`
- [ ] **Step 1: 先写失败测试,锁定下拉项、业务列和新标题**
```js
[
"涉疑交易明细",
"全部可疑人员类型",
"名单库命中",
"模型规则命中",
"可疑人员",
"关联人",
"关联员工",
"关系",
"摘要/交易类型",
].forEach((token) => assert(source.includes(token), token));
```
- [ ] **Step 2: 运行测试,确认当前仍是旧占位表格**
Run:
```bash
node ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js
```
Expected: FAIL提示仍存在“涉险交易明细 / 对手方 / 方向 / 账号”
- [ ] **Step 3: 写最小 UI 改造**
```vue
<el-dropdown @command="handleSuspiciousTypeChange">
<span class="el-dropdown-link">{{ currentSuspiciousTypeLabel }}</span>
</el-dropdown>
<el-table-column prop="trxDate" label="交易时间" />
<el-table-column prop="suspiciousPersonName" label="可疑人员" />
<el-table-column prop="relatedPersonName" label="关联人" />
<el-table-column label="关联员工">
<template slot-scope="scope">{{ formatRelatedStaff(scope.row) }}</template>
</el-table-column>
```
- [ ] **Step 4: 回跑布局测试**
Run:
```bash
node ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js
```
Expected: PASS
- [ ] **Step 5: 提交本任务**
```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/RiskDetailSection.vue \
ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js \
ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js
git commit -m "改造结果总览涉疑交易表格结构"
```
### Task 4: 复用流水详情弹窗与导出能力,并做前端回归
**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/RiskDetailSection.vue`
- Modify: `ruoyi-ui/src/api/ccdi/projectOverview.js`
- Reuse: `ruoyi-ui/src/api/ccdiProjectBankStatement.js`
- Test: `ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js`
- Create: `ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-detail-dialog.test.js`
- [ ] **Step 1: 先写失败测试,锁定详情复用与导出路径**
```js
[
"getBankStatementDetail",
"detailVisible",
"handleViewDetail",
"this.download(",
"ccdi/project/overview/suspicious-transactions/export",
].forEach((token) => assert(source.includes(token), token));
```
- [ ] **Step 2: 运行测试,确认详情与导出还未接通**
Run:
```bash
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-detail-dialog.test.js
```
Expected: FAIL提示未复用 `getBankStatementDetail` 或未指向新导出路径
- [ ] **Step 3: 在 RiskDetailSection 中复用 DetailQuery 的详情弹窗结构和金额/标签格式化**
```js
import { getBankStatementDetail } from "@/api/ccdiProjectBankStatement";
async handleViewDetail(row) {
const response = await getBankStatementDetail(row.bankStatementId);
this.detailData = normalizeDetailData(response.data);
this.detailVisible = true;
}
handleExport() {
this.download(
"ccdi/project/overview/suspicious-transactions/export",
{ projectId: this.projectId, suspiciousType: this.currentSuspiciousType },
`涉疑交易明细_${new Date().getTime()}.xlsx`
);
}
```
- [ ] **Step 4: 跑前端回归检查**
Run:
```bash
node ruoyi-ui/tests/unit/project-overview-api.test.js
node ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js
node ruoyi-ui/tests/unit/preliminary-check-suspicious-transaction-load.test.js
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-detail-dialog.test.js
cd ruoyi-ui && npm run build:prod
```
Expected:
- 所有 Node 断言测试 PASS
- `npm run build:prod` 成功产出构建结果
- [ ] **Step 5: 提交本任务**
```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/RiskDetailSection.vue \
ruoyi-ui/src/api/ccdi/projectOverview.js \
ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js \
ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-detail-dialog.test.js
git commit -m "接通结果总览涉疑交易详情与导出"
```