# 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** 先新增静态断言脚本,锁定页面入口必须从占位页升级为真实页面骨架: ```js 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: ```bash 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 数据: ```js export const mockOverviewData = { summary: {}, riskPeople: {}, riskModels: {}, riskDetails: {}, }; ``` 2. 将 `PreliminaryCheck.vue` 改为页面编排组件,新增: ```js data() { return { pageState: "loaded", mockData: mockOverviewData, }; } ``` 3. 在模板中预留 4 个区块组件挂载位: ```html ``` 4. 加入 `loaded / empty / loading` 三态容器骨架,但先不做完整内容。 - [ ] **Step 4: Run tests to verify they pass** Run: ```bash cd ruoyi-ui node tests/unit/preliminary-check-layout.test.js ``` Expected: - `PASS` - 说明页面入口已具备后续拆分基础 - [ ] **Step 5: Commit** ```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-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** 新增静态断言脚本,锁定原型前两块结构必须出现: ```js 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: ```bash 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` 补齐: ```js summary: { title: "风险总览", stats: [/* 5 个指标卡 */] }, riskPeople: { overviewList: [/* 风险人员总览 */], topRiskList: [/* TOP10 */] } ``` 4. 在 `PreliminaryCheck.vue` 中接入两个组件并传入对应 mock 数据。 5. 样式上按原型落实浅灰背景、白卡、蓝色操作位和紧凑表格头部。 - [ ] **Step 4: Run tests to verify they pass** Run: ```bash 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** ```bash 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** 新增静态断言脚本,锁定原型后两块结构: ```js 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: ```bash 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` 补齐: ```js riskModels: { cardList: [], filterOptions: {}, peopleList: [] }, riskDetails: { transactionList: [], abnormalAccountList: [] } ``` 4. 在入口组件中按顺序接入两个区块组件。 - [ ] **Step 4: Run tests to verify they pass** Run: ```bash 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** ```bash 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** 新增状态断言脚本,锁定加载态与空态入口: ```js 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: ```bash 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. 新增前端验证记录: ```md # 结果总览前端验证记录 ## 验证范围 - 结果总览主展示态 - 空数据态 - 加载态 - 页面构建 ``` 4. 新增实施记录,说明本次页面落地内容与验证结果。 - [ ] **Step 4: Run tests to verify they pass** Run: ```bash 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** ```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-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 "完成结果总览页面前端实现" ```