Files
ccdi/docs/plans/frontend/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-implementation.md

11 KiB
Raw Blame History

Project Detail Risk Overview Risk People Pagination 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.

Repo note: 本仓库 AGENTS.md 明确禁止开启 subagent执行本计划时请在当前会话使用 superpowers:executing-plans

Goal: 让项目详情“风险总览”的员工列表改为固定每页 5 条的真实后端分页,并保证翻页时只刷新该列表,不重载结果总览内其他区块。

Architecture: 前端继续以 PreliminaryCheck.vue 作为结果总览入口,首屏加载第一页风险员工数据并透传给 RiskPeopleSection.vueRiskPeopleSection.vue 接管分页状态、请求 loading 和翻页动作,直接调用 projectOverview.js 中改造后的 getOverviewRiskPeople(params),避免在翻页时重新触发整页 Promise.all

Tech Stack: Vue 2, Element UI, SCSS, axios request 封装, Node assert 结构测试


Task 1: 改造风险员工分页 API 封装

Files:

  • Modify: ruoyi-ui/src/api/ccdi/projectOverview.js

  • Test: ruoyi-ui/tests/unit/project-overview-api.test.js

  • Step 1: 先写失败测试,锁定 getOverviewRiskPeople 改为参数对象透传

[
  "getOverviewRiskPeople(params)",
  "/ccdi/project/overview/risk-people",
  "projectId: params.projectId",
  "pageNum: params.pageNum",
  "pageSize: params.pageSize",
].forEach((token) => assert(source.includes(token), token));
  • Step 2: 运行 API 契约测试,确认当前仍是旧签名

Run:

node ruoyi-ui/tests/unit/project-overview-api.test.js

Expected:

  • FAIL提示 getOverviewRiskPeople(projectId) 仍是旧写法

  • Step 3: 写最小 API 封装

export function getOverviewRiskPeople(params) {
  return request({
    url: "/ccdi/project/overview/risk-people",
    method: "get",
    params: {
      projectId: params.projectId,
      pageNum: params.pageNum,
      pageSize: params.pageSize,
    },
  });
}
  • Step 4: 回跑 API 测试

Run:

node ruoyi-ui/tests/unit/project-overview-api.test.js

Expected: PASS

  • Step 5: 提交本任务
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

  • Modify: ruoyi-ui/tests/unit/preliminary-check-api-integration.test.js

  • Create: ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination-load.test.js

  • Step 1: 先写失败测试,锁定父组件首屏请求第一页且固定 5 条

[
  "getOverviewRiskPeople({",
  "projectId: this.projectId",
  "pageNum: 1",
  "pageSize: 5",
  "riskPeopleData.rows",
].forEach((token) => assert(source.includes(token), token));
assert(source.includes("pageNum"), "riskPeople 应保存首屏页码");
assert(source.includes("pageSize"), "riskPeople 应保存首屏页长");
assert(source.includes("total"), "riskPeople 应保存总数");
  • Step 2: 运行入口页测试,确认当前还在读取 overviewList

Run:

node ruoyi-ui/tests/unit/preliminary-check-api-integration.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination-load.test.js

Expected:

  • FAIL提示首屏没有传 pageNum/pageSize

  • FAIL提示 riskPeopleData.rows 未被使用

  • Step 3: 写最小首屏加载与 mock 归一化

const [dashboardRes, riskPeopleRes, riskModelCardsRes, suspiciousRes, creditNegativeRes] = await Promise.all([
  getOverviewDashboard(this.projectId),
  getOverviewRiskPeople({ projectId: this.projectId, pageNum: 1, pageSize: 5 }),
  getOverviewRiskModelCards(this.projectId),
  getOverviewSuspiciousTransactions({ projectId: this.projectId, suspiciousType: "ALL", pageNum: 1, pageSize: 5 }),
  getOverviewEmployeeCreditNegative({ projectId: this.projectId, pageNum: 1, pageSize: 5 }),
]);
riskPeople: {
  ...mockOverviewData.riskPeople,
  rows: Array.isArray(riskPeopleData && riskPeopleData.rows) ? riskPeopleData.rows : [],
  total: riskPeopleData && riskPeopleData.total ? riskPeopleData.total : 0,
  pageNum: riskPeopleData && riskPeopleData.pageNum ? riskPeopleData.pageNum : 1,
  pageSize: riskPeopleData && riskPeopleData.pageSize ? riskPeopleData.pageSize : 5,
}
  • Step 4: 回跑入口页测试

Run:

node ruoyi-ui/tests/unit/preliminary-check-api-integration.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination-load.test.js

Expected: PASS

  • Step 5: 提交本任务
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-api-integration.test.js \
  ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination-load.test.js
git commit -m "接通风险总览员工列表首屏分页数据"

Task 3: 在 RiskPeopleSection 中接管独立翻页与局部刷新

Files:

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

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

  • Modify: ruoyi-ui/tests/unit/preliminary-check-risk-people-binding.test.js

  • Create: ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination.test.js

  • Step 1: 先写失败测试,锁定组件读取 rows、存在分页条、固定 5 条一页

[
  "sectionData.rows",
  "pageNum",
  "pageSize",
  "total",
  "<pagination",
  ':page-sizes="[5]"',
  "handlePageChange",
  "loadRiskPeoplePage",
  "getOverviewRiskPeople",
].forEach((token) => assert(source.includes(token), token));
assert(!source.includes("sectionData.overviewList"), "风险人员列表不应再绑定 overviewList");
  • Step 2: 运行风险人员组件测试,确认当前没有分页状态和独立翻页逻辑

Run:

node ruoyi-ui/tests/unit/preliminary-check-risk-people-binding.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination.test.js

Expected:

  • FAIL提示缺少 rows / total / pageNum / pageSize

  • FAIL提示缺少分页组件和翻页方法

  • Step 3: 写最小局部分页实现

PreliminaryCheck.vue 里给子组件补传 project-id

<risk-people-section
  :project-id="projectId"
  :section-data="currentData.riskPeople"
  @view-project-analysis="handleRiskPeopleProjectAnalysis"
/>

RiskPeopleSection.vue 里维护局部分页状态与请求:

data() {
  return {
    pageNum: 1,
    pageSize: 5,
    total: 0,
    tableLoading: false,
    localRows: [],
  };
},
watch: {
  sectionData: {
    immediate: true,
    deep: true,
    handler(data) {
      this.localRows = normalizeOverviewRows(data && data.rows);
      this.total = (data && data.total) || 0;
      this.pageNum = (data && data.pageNum) || 1;
      this.pageSize = (data && data.pageSize) || 5;
    },
  },
},
async loadRiskPeoplePage(pageNum) {
  this.tableLoading = true;
  const response = await getOverviewRiskPeople({
    projectId: this.projectId,
    pageNum,
    pageSize: 5,
  });
  const data = (response && response.data) || {};
  this.localRows = normalizeOverviewRows(data.rows);
  this.total = data.total || 0;
  this.pageNum = data.pageNum || pageNum;
  this.pageSize = data.pageSize || 5;
  this.tableLoading = false;
}
handlePageChange({ page }) {
  if (page === this.pageNum) {
    return;
  }
  this.loadRiskPeoplePage(page);
}
<pagination
  v-show="total > 0"
  :total="total"
  :page.sync="pageNum"
  :limit.sync="pageSize"
  :page-sizes="[5]"
  layout="total, prev, pager, next, jumper"
  @pagination="handlePageChange"
/>
  • Step 4: 回跑风险人员组件测试

Run:

node ruoyi-ui/tests/unit/preliminary-check-risk-people-binding.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination.test.js

Expected:

  • PASS

  • 核心异常点标签逻辑、风险等级标签逻辑和操作列逻辑不回归

  • Step 5: 提交本任务

git add ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue \
  ruoyi-ui/src/views/ccdiProject/components/detail/RiskPeopleSection.vue \
  ruoyi-ui/tests/unit/preliminary-check-risk-people-binding.test.js \
  ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination.test.js
git commit -m "支持风险总览员工列表独立分页翻页"

Task 4: 补齐前端验证记录与实施记录

Files:

  • Create: docs/tests/records/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-verification.md

  • Create: docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-implementation.md

  • Verify: docs/design/2026-03-29-project-detail-risk-overview-risk-people-pagination-design.md

  • Step 1: 运行本需求前端最小回归

Run:

node ruoyi-ui/tests/unit/project-overview-api.test.js
node ruoyi-ui/tests/unit/preliminary-check-api-integration.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination-load.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-binding.test.js
node ruoyi-ui/tests/unit/preliminary-check-risk-people-pagination.test.js

Expected:

  • 全部 PASS

  • 风险人员区首屏读取分页结构,翻页逻辑存在

  • Step 2: 写前端验证记录

docs/tests/records/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-verification.md 记录:

  • 执行命令

  • 执行日期

  • 测试结果

  • 结论:风险总览员工列表已固定 5 条一页,翻页仅刷新当前列表

  • Step 3: 写前端实施记录

docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-implementation.md 记录:

  • API 封装如何改造

  • PreliminaryCheck.vue 首屏如何注入分页结构

  • RiskPeopleSection.vue 如何局部翻页

  • 本次未改动风险模型区和风险明细区

  • Step 4: 检查暂存区仅包含本任务文件

Run:

git status --short
git diff --cached --name-only

Expected:

  • 暂存区只出现本任务相关前端源码、测试和文档

  • Step 5: 提交本任务

git add docs/tests/records/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-verification.md \
  docs/reports/implementation/2026-03-29-project-detail-risk-overview-risk-people-pagination-frontend-implementation.md
git commit -m "补充风险总览员工列表前端分页实施记录"

Done When

  • 首屏通过 getOverviewRiskPeople({ projectId, pageNum: 1, pageSize: 5 }) 获取第一页
  • riskPeople 数据结构改为 rows + total + pageNum + pageSize
  • RiskPeopleSection.vue 存在固定 5 条分页条
  • 翻页只刷新风险总览员工列表,不重载其他结果总览区块
  • 前端验证记录与实施记录已补齐