Files
ccdi/docs/plans/frontend/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-implementation.md

14 KiB

Results Overview Project Analysis Dialog Real Detail Frontend Implementation Plan

For agentic workers: REQUIRED: Use superpowers:executing-plans to implement this plan. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 将结果总览“项目分析”弹窗从静态高保真壳子升级为真实详情工作台,支持加宽弹窗、请求真实详情接口、展示员工基础信息、按类型渲染流水表格与对象摘要卡。

Architecture: 保持 PreliminaryCheck.vue 为结果总览唯一入口,不新增路由。projectOverview.js 新增详情接口方法,PreliminaryCheck.vue 继续统一维护弹窗开关、来源上下文和外层命中模型摘要;ProjectAnalysisDialog.vue 负责请求详情、处理加载与错误态,ProjectAnalysisSidebar.vue 只消费“真实基础信息 + 外层透传模型摘要”,ProjectAnalysisAbnormalTab.vueBANK_STATEMENT / OBJECT 两种分组类型拆分展示。

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


Task 1: 先锁定 API 契约与入口状态流

Files:

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

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

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

  • Test: ruoyi-ui/tests/unit/preliminary-check-project-analysis-source-context.test.js

  • Step 1: Write the failing test

补充断言,锁定以下内容:

  • projectOverview.js 新增 getOverviewPersonAnalysisDetail
  • 请求路径为 /ccdi/project/overview/person-analysis/detail
  • PreliminaryCheck.vue 在打开弹窗时仍会保存:
    • 当前人员
    • 当前来源
    • 外层命中模型摘要
  • 详情请求所需的 projectIdstaffIdCard 可从入口上下文中拿到

示例断言片段:

assert(source.includes('getOverviewPersonAnalysisDetail'), '缺少详情 API');
assert(source.includes('/ccdi/project/overview/person-analysis/detail'), '详情接口路径错误');
assert(source.includes('projectAnalysisSource'), '缺少弹窗来源状态');
  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-api-integration.test.js
node tests/unit/preliminary-check-project-analysis-source-context.test.js

Expected:

  • FAIL

  • Step 3: Write minimal implementation

projectOverview.js 中新增:

export function getOverviewPersonAnalysisDetail(params) {
  return request({
    url: '/ccdi/project/overview/person-analysis/detail',
    method: 'get',
    params: {
      projectId: params.projectId,
      staffIdCard: params.staffIdCard
    }
  })
}

PreliminaryCheck.vue 中:

  • 保持现有打开弹窗入口不变

  • 明确存储 projectAnalysisPersonprojectAnalysisSource

  • 新增或整理 projectAnalysisModelSummary

  • Step 4: Run test to verify it passes

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-api-integration.test.js
node tests/unit/preliminary-check-project-analysis-source-context.test.js

Expected:

  • PASS

  • Step 5: Commit

git add ruoyi-ui/src/api/ccdi/projectOverview.js ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue ruoyi-ui/tests/unit/preliminary-check-api-integration.test.js ruoyi-ui/tests/unit/preliminary-check-project-analysis-source-context.test.js
git commit -m "补充结果总览详情弹窗前端接线"

Task 2: 锁定弹窗宽度、加载态和错误态

Files:

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

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-layout.test.js

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-default-tab.test.js

  • Step 1: Write the failing test

在现有弹窗测试中补充断言,锁定:

  • 弹窗宽度由 1280px 调整为 1440px
  • 侧栏宽度调到 340px
  • 弹窗打开时触发详情请求
  • 存在详情加载态
  • 存在错误提示与重试入口
  • 再次打开时仍回到 异常明细

示例断言片段:

assert(source.includes('width="1440px"'), '弹窗未加宽到 1440px');
assert(source.includes('fetchDetailData'), '缺少详情请求方法');
assert(source.includes('detailLoading'), '缺少详情加载态');
assert(source.includes('handleRetryDetail'), '缺少重试方法');
  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/project-analysis-dialog-layout.test.js
node tests/unit/project-analysis-dialog-default-tab.test.js

Expected:

  • FAIL

  • Step 3: Write minimal implementation

ProjectAnalysisDialog.vue 中完成:

  • 宽度调为 1440px

  • 新增 detailLoadingdetailError

  • 打开弹窗时调用 fetchDetailData

  • 重试时再次调用同一详情接口

  • 关闭时重置 activeTabdetailLoadingdetailErrordetailData

  • Step 4: Run test to verify it passes

Run:

cd ruoyi-ui
node tests/unit/project-analysis-dialog-layout.test.js
node tests/unit/project-analysis-dialog-default-tab.test.js

Expected:

  • PASS

  • Step 5: Commit

git add ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisDialog.vue ruoyi-ui/tests/unit/project-analysis-dialog-layout.test.js ruoyi-ui/tests/unit/project-analysis-dialog-default-tab.test.js
git commit -m "完善结果总览详情弹窗状态"

Task 3: 将侧栏改为真实基础信息 + 外层模型摘要

Files:

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

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

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

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-sidebar.test.js

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-empty-field.test.js

  • Step 1: Write the failing test

锁定侧栏展示边界:

  • 人员基础信息 来自真实详情接口返回的 basicInfo

  • 命中模型摘要 来自外层透传,不依赖详情接口

  • 排查记录摘要 仍为占位文案

  • 基础信息缺失时统一展示 -

  • 异常标签为空时展示“暂无异常标签”

  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/project-analysis-dialog-sidebar.test.js
node tests/unit/project-analysis-dialog-empty-field.test.js

Expected:

  • FAIL

  • Step 3: Write minimal implementation

ProjectAnalysisDialog.vue 中把弹窗数据源拆成两部分:

  • detailData.basicInfo
  • sourceSummary/modelSummary

ProjectAnalysisSidebar.vue 中只负责渲染:

  • 真实 basicInfo
  • 外层传入的 modelSummary
  • 静态 recordSummary

preliminaryCheck.mock.js 中保留:

  • 占位页签
  • 默认空结构

移除对真实基础信息和异常明细的 mock 拼装依赖。

  • Step 4: Run test to verify it passes

Run:

cd ruoyi-ui
node tests/unit/project-analysis-dialog-sidebar.test.js
node tests/unit/project-analysis-dialog-empty-field.test.js

Expected:

  • PASS

  • Step 5: Commit

git add ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisSidebar.vue ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisDialog.vue ruoyi-ui/src/views/ccdiProject/components/detail/preliminaryCheck.mock.js ruoyi-ui/tests/unit/project-analysis-dialog-sidebar.test.js ruoyi-ui/tests/unit/project-analysis-dialog-empty-field.test.js
git commit -m "改造结果总览详情弹窗侧栏数据源"

Task 4: 把异常明细主视图改为分组渲染

Files:

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

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

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-abnormal-tab.test.js

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-source-highlight.test.js

  • Test: ruoyi-ui/tests/unit/detail-query-hit-tags-list.test.js

  • Step 1: Write the failing test

锁定异常明细渲染规则:

  • 遍历 abnormalDetail.groups

  • BANK_STATEMENT 分组渲染表格

  • 表格字段贴近流水明细查询:

    • 交易时间
    • 本方账户
    • 对方账户
    • 摘要 / 交易类型
    • 异常标签
    • 交易金额
  • OBJECT 分组渲染摘要卡

  • 来源于模型列表时仍显示“当前命中模型”强调,但异常明细不按当前模型过滤

  • Step 2: Run test to verify it fails

Run:

cd ruoyi-ui
node tests/unit/project-analysis-dialog-abnormal-tab.test.js
node tests/unit/project-analysis-dialog-source-highlight.test.js
node tests/unit/detail-query-hit-tags-list.test.js

Expected:

  • FAIL

  • Step 3: Write minimal implementation

ProjectAnalysisAbnormalTab.vue 中按类型拆分渲染:

  • BANK_STATEMENT
    • 复用 DetailQuery.vue 里的表格字段节奏和金额/标签展示样式
  • OBJECT
    • 输出卡片列表
    • 每张卡只展示 title/subtitle/riskTags/summary/extraFields

若某个分组没有记录:

  • 不单独渲染空壳卡片

若全部分组为空:

  • 渲染统一空态

  • Step 4: Run test to verify it passes

Run:

cd ruoyi-ui
node tests/unit/project-analysis-dialog-abnormal-tab.test.js
node tests/unit/project-analysis-dialog-source-highlight.test.js
node tests/unit/detail-query-hit-tags-list.test.js

Expected:

  • PASS

  • Step 5: Commit

git add ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisAbnormalTab.vue ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisDialog.vue ruoyi-ui/tests/unit/project-analysis-dialog-abnormal-tab.test.js ruoyi-ui/tests/unit/project-analysis-dialog-source-highlight.test.js ruoyi-ui/tests/unit/detail-query-hit-tags-list.test.js
git commit -m "实现结果总览详情弹窗异常分组展示"

Task 5: 做前端回归、手工验证和文档沉淀

Files:

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

  • Test: ruoyi-ui/tests/unit/preliminary-check-model-linkage-flow.test.js

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

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-layout.test.js

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-sidebar.test.js

  • Test: ruoyi-ui/tests/unit/project-analysis-dialog-abnormal-tab.test.js

  • Create: docs/tests/records/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-verification.md

  • Create: docs/reports/implementation/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-implementation.md

  • Verify: docs/design/2026-03-25-results-overview-project-analysis-dialog-real-detail-design.md

  • Step 1: Run focused regression

Run:

cd ruoyi-ui
node tests/unit/preliminary-check-summary-and-people.test.js
node tests/unit/preliminary-check-model-linkage-flow.test.js
node tests/unit/preliminary-check-model-and-detail.test.js
node tests/unit/project-analysis-dialog-layout.test.js
node tests/unit/project-analysis-dialog-sidebar.test.js
node tests/unit/project-analysis-dialog-abnormal-tab.test.js

Expected:

  • 全部 PASS

  • Step 2: Run production build

Run:

cd ruoyi-ui
npm run build:prod

Expected:

  • BUILD SUCCESS 或等价成功输出

  • Step 3: Manual verification

Run:

cd ruoyi-ui
npm run dev

手工检查:

  • 结果总览两个入口都能打开同一个弹窗
  • 弹窗宽度已加宽
  • 打开时先看到加载态,再展示真实数据
  • 基础信息为真实员工信息
  • 模型摘要仍取自外层入口
  • 流水型异常显示表格
  • OBJECT 型异常显示摘要卡

验证完成后主动关闭前端开发进程。

  • Step 4: Write verification and implementation records

docs/tests/records/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-verification.md 记录:

  • 单测命令
  • build 命令
  • 手工验证步骤与结果

docs/reports/implementation/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-implementation.md 记录:

  • API 接线

  • 弹窗状态改造

  • 侧栏真实数据与外层摘要拆分

  • 分组展示实现

  • Step 5: Review changed files and commit

Run:

git diff --name-only

Expected:

  • 只包含本次前端实现、测试和文档文件

Commit:

git add ruoyi-ui/src/api/ccdi/projectOverview.js ruoyi-ui/src/views/ccdiProject/components/detail/PreliminaryCheck.vue ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisDialog.vue ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisSidebar.vue ruoyi-ui/src/views/ccdiProject/components/detail/ProjectAnalysisAbnormalTab.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-project-analysis-source-context.test.js ruoyi-ui/tests/unit/project-analysis-dialog-layout.test.js ruoyi-ui/tests/unit/project-analysis-dialog-default-tab.test.js ruoyi-ui/tests/unit/project-analysis-dialog-sidebar.test.js ruoyi-ui/tests/unit/project-analysis-dialog-empty-field.test.js ruoyi-ui/tests/unit/project-analysis-dialog-abnormal-tab.test.js ruoyi-ui/tests/unit/project-analysis-dialog-source-highlight.test.js ruoyi-ui/tests/unit/detail-query-hit-tags-list.test.js docs/tests/records/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-verification.md docs/reports/implementation/2026-03-25-results-overview-project-analysis-dialog-real-detail-frontend-implementation.md
git commit -m "实现结果总览详情弹窗前端接线"