Files
ccdi/docs/plans/frontend/2026-03-19-results-overview-frontend-implementation.md

12 KiB

Results Overview Frontend 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.

Goal: 在项目详情页 结果总览 页签下实现一版基于原型图的高保真静态前端页面,覆盖主展示态、空数据态和加载态。

Architecture: 保持 detail.vue 现有挂载链路不变,以 PreliminaryCheck.vue 作为页面编排入口,新增顶部总览、风险人员、风险模型、风险明细 4 个内容区组件,并由同目录 mock 数据文件统一驱动页面状态。测试继续沿用仓库当前前端做法,优先补静态 source 断言脚本,再跑 npm run build:prod 做构建回归。

Tech Stack: Vue 2, Element UI, SCSS, Node.js, npm


Task 1: 搭建结果总览页面骨架与静态断言

Files:

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue

  • Create: ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js

  • Create: ruoyi-ui/tests/unit/preliminary-check-layout.test.js

  • Step 1: Write the failing test

先新增静态断言脚本,锁定页面入口必须从占位页升级为真实页面骨架:

const assert = require("assert");
const fs = require("fs");
const path = require("path");

const componentPath = path.resolve(
  __dirname,
  "../../src/views/ccdiProject/components/detail/PreliminaryCheck.vue"
);
const source = fs.readFileSync(componentPath, "utf8");

[
  "OverviewStats",
  "RiskPeopleSection",
  "RiskModelSection",
  "RiskDetailSection",
  "pageState",
  "mockOverviewData",
].forEach((token) => {
  assert(source.includes(token), `结果总览入口缺少结构: ${token}`);
});
  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-layout.test.js

Expected:

  • FAIL

  • 原因是当前 PreliminaryCheck.vue 仍然只有占位文案

  • Step 3: Write minimal implementation

做最小范围骨架改造:

  1. preliminaryCheck.mock.js 中导出统一 mock 数据:
export const mockOverviewData = {
  summary: {},
  riskPeople: {},
  riskModels: {},
  riskDetails: {},
};
  1. PreliminaryCheck.vue 改为页面编排组件,新增:
data() {
  return {
    pageState: "loaded",
    mockData: mockOverviewData,
  };
}
  1. 在模板中预留 4 个区块组件挂载位:
<overview-stats v-if="pageState === 'loaded'" :summary="mockData.summary" />
<risk-people-section v-if="pageState === 'loaded'" :section-data="mockData.riskPeople" />
<risk-model-section v-if="pageState === 'loaded'" :section-data="mockData.riskModels" />
<risk-detail-section v-if="pageState === 'loaded'" :section-data="mockData.riskDetails" />
  1. 加入 loaded / empty / loading 三态容器骨架,但先不做完整内容。
  • Step 4: Run tests to verify they pass

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-layout.test.js

Expected:

  • PASS

  • 说明页面入口已具备后续拆分基础

  • Step 5: Commit

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-layout.test.js
git commit -m "搭建结果总览页面骨架"

Task 2: 实现顶部总览区与风险人员区

Files:

  • Create: ruoyi-ui/src/views/ccdiProject/components/detail/OverviewStats.vue

  • Create: ruoyi-ui/src/views/ccdiProject/components/detail/RiskPeopleSection.vue

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue

  • Create: ruoyi-ui/tests/unit/preliminary-check-summary-and-people.test.js

  • Step 1: Write the failing test

新增静态断言脚本,锁定原型前两块结构必须出现:

const assert = require("assert");
const fs = require("fs");
const path = require("path");

const entry = fs.readFileSync(path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/PreliminaryCheck.vue"), "utf8");
const stats = fs.readFileSync(path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/OverviewStats.vue"), "utf8");
const people = fs.readFileSync(path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/RiskPeopleSection.vue"), "utf8");

["风险总览", "overview-stats"].forEach((token) => assert(stats.includes(token), token));
["风险人员总览", "中高风险人员TOP10", "查看详情"].forEach((token) => assert(people.includes(token), token));
assert(entry.includes("risk-people-section"), "入口应挂载风险人员区");
  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-summary-and-people.test.js

Expected:

  • FAIL

  • 原因是两个区块组件还不存在或仍未包含目标结构

  • Step 3: Write minimal implementation

按原型补齐前两块:

  1. OverviewStats.vue 实现标题行、右侧操作位和顶部统计卡。
  2. RiskPeopleSection.vue 实现两个白卡表格区:
    • 风险人员总览
    • 中高风险人员 TOP10
  3. preliminaryCheck.mock.js 补齐:
summary: {
  title: "风险总览",
  stats: [/* 5 个指标卡 */]
},
riskPeople: {
  overviewList: [/* 风险人员总览 */],
  topRiskList: [/* TOP10 */]
}
  1. PreliminaryCheck.vue 中接入两个组件并传入对应 mock 数据。
  2. 样式上按原型落实浅灰背景、白卡、蓝色操作位和紧凑表格头部。
  • Step 4: Run tests to verify they pass

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-layout.test.js
node tests/unit/preliminary-check-summary-and-people.test.js

Expected:

  • 2 个脚本都 PASS

  • 页面入口和前两块结构都已稳定

  • Step 5: Commit

git add ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue ruoyi-ui/src/views/ccdiProject/components/detail/OverviewStats.vue ruoyi-ui/src/views/ccdiProject/components/detail/RiskPeopleSection.vue ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js ruoyi-ui/tests/unit/preliminary-check-layout.test.js ruoyi-ui/tests/unit/preliminary-check-summary-and-people.test.js
git commit -m "实现结果总览前两块静态页面"

Task 3: 实现风险模型区与风险明细区

Files:

  • Create: ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue

  • Create: ruoyi-ui/src/views/ccdiProject/components/detail/RiskDetailSection.vue

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue

  • Create: ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js

  • Step 1: Write the failing test

新增静态断言脚本,锁定原型后两块结构:

const assert = require("assert");
const fs = require("fs");
const path = require("path");

const model = fs.readFileSync(path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/RiskModelSection.vue"), "utf8");
const detail = fs.readFileSync(path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/RiskDetailSection.vue"), "utf8");

["模型预警次数统计", "命中模型涉及人员", "筛查模型", "预警类型"].forEach((token) => assert(model.includes(token), token));
["涉险交易明细", "异常账户人员信息", "查看详情"].forEach((token) => assert(detail.includes(token), token));
  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-model-and-detail.test.js

Expected:

  • FAIL

  • 原因是风险模型区和风险明细区组件尚未实现

  • Step 3: Write minimal implementation

按原型补齐后两块:

  1. RiskModelSection.vue 实现:
    • 模型摘要卡列表
    • 筛选条
    • 命中模型涉及人员表格与分页
  2. RiskDetailSection.vue 实现:
    • 涉险交易明细表
    • 异常账户人员信息表
    • 金额正负值颜色区分
  3. preliminaryCheck.mock.js 补齐:
riskModels: {
  cardList: [],
  filterOptions: {},
  peopleList: []
},
riskDetails: {
  transactionList: [],
  abnormalAccountList: []
}
  1. 在入口组件中按顺序接入两个区块组件。
  • Step 4: Run tests to verify they pass

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-model-and-detail.test.js
node tests/unit/preliminary-check-summary-and-people.test.js

Expected:

  • PASS

  • 说明四大区块模板结构齐备,且新增区块没有破坏前两块

  • Step 5: Commit

git add ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue ruoyi-ui/src/views/ccdiProject/components/detail/RiskDetailSection.vue ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js ruoyi-ui/tests/unit/preliminary-check-summary-and-people.test.js
git commit -m "实现结果总览模型与明细区块"

Task 4: 补齐三种页面状态、构建验证与实施记录

Files:

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue

  • Modify: ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js

  • Create: ruoyi-ui/tests/unit/preliminary-check-states.test.js

  • Create: docs/tests/records/2026-03-19-results-overview-frontend-verification.md

  • Create: docs/reports/implementation/2026-03-19-results-overview-frontend-implementation.md

  • Step 1: Write the failing test

新增状态断言脚本,锁定加载态与空态入口:

const assert = require("assert");
const fs = require("fs");
const path = require("path");

const source = fs.readFileSync(
  path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/PreliminaryCheck.vue"),
  "utf8"
);

["pageState === 'loading'", "pageState === 'empty'", "el-skeleton", "el-empty"].forEach((token) => {
  assert(source.includes(token), `缺少页面状态结构: ${token}`);
});
  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-states.test.js

Expected:

  • FAIL

  • 原因是三种页面状态尚未完整落地

  • Step 3: Write minimal implementation

补齐收尾内容:

  1. PreliminaryCheck.vue 中实现:
    • 加载态骨架屏
    • 空态容器
    • 主展示态切换
  2. preliminaryCheck.mock.js 中补齐 loaded / empty / loading 三套数据组织。
  3. 新增前端验证记录:
# 结果总览前端验证记录

## 验证范围
- 结果总览主展示态
- 空数据态
- 加载态
- 页面构建
  1. 新增实施记录,说明本次页面落地内容与验证结果。
  • Step 4: Run tests to verify they pass

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-layout.test.js
node tests/unit/preliminary-check-summary-and-people.test.js
node tests/unit/preliminary-check-model-and-detail.test.js
node tests/unit/preliminary-check-states.test.js
npm run build:prod

Expected:

  • 4 个静态脚本全部 PASS

  • npm run build:prod 成功

  • 说明页面结构、状态和样式未引入构建错误

  • Step 5: Commit

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-layout.test.js ruoyi-ui/tests/unit/preliminary-check-summary-and-people.test.js ruoyi-ui/tests/unit/preliminary-check-model-and-detail.test.js ruoyi-ui/tests/unit/preliminary-check-states.test.js docs/tests/records/2026-03-19-results-overview-frontend-verification.md docs/reports/implementation/2026-03-19-results-overview-frontend-implementation.md
git commit -m "完成结果总览页面前端实现"