From d931ac185dbb0323be696f80bd1995e1e29b631d Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Fri, 27 Mar 2026 14:09:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E9=A1=B9=E7=9B=AE=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=87=8D=E6=96=B0=E5=88=86=E6=9E=90=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...t-list-reanalyze-confirm-refresh-design.md | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 docs/design/2026-03-27-project-list-reanalyze-confirm-refresh-design.md diff --git a/docs/design/2026-03-27-project-list-reanalyze-confirm-refresh-design.md b/docs/design/2026-03-27-project-list-reanalyze-confirm-refresh-design.md new file mode 100644 index 00000000..dccedffb --- /dev/null +++ b/docs/design/2026-03-27-project-list-reanalyze-confirm-refresh-design.md @@ -0,0 +1,195 @@ +# 项目管理列表重新分析确认与刷新设计文档 + +## 背景 + +项目管理列表页已经接入“重新分析”真实调用链路: + +- 前端通过 `POST /ccdi/project/tags/rebuild` 提交项目级重打标 +- 成功后提示“已开始重新分析” +- 随后调用 `getList()` 刷新列表与状态统计 + +当前缺口主要有两个: + +1. 用户点击“重新分析”后会立即发起请求,缺少二次确认 +2. 需要明确本轮仍然沿用成功后的全列表刷新策略,不做局部行补丁更新 + +本次需求是在现有真实调用能力之上补齐交互确认,并保持最短路径实现。 + +## 目标 + +- 为项目列表中的“重新分析”按钮增加确认弹窗 +- 用户确认后才触发 `rebuildProjectTags` +- 调用成功后继续刷新项目列表与顶部状态统计 +- 保持现有失败提示、按钮提交态和状态驱动展示逻辑 + +## 范围 + +### In Scope + +- `ruoyi-ui/src/views/ccdiProject/index.vue` 中“重新分析”交互链路补充确认弹窗 +- 沿用现有 `reAnalyzeLoadingMap` 防重复点击 +- 成功后沿用 `getList()` 刷新列表和状态统计 +- 取消确认、调用成功、调用失败三类前端行为收口 +- 补充对应前端验证与实施文档 + +### Out of Scope + +- 不新增后端接口 +- 不新增轮询、进度提示、消息推送 +- 不做局部列表行更新或乐观更新 +- 不调整“重新分析”按钮显示条件 +- 不变更后端重打标、风险人数计算或状态流转逻辑 + +## 现状分析 + +### 前端现状 + +`ruoyi-ui/src/views/ccdiProject/index.vue` 中的 `handleReAnalyze(row)` 当前流程为: + +1. 判断当前项目是否处于重新分析提交中 +2. 设置按钮 loading +3. 调用 `rebuildProjectTags({ projectId })` +4. 成功提示“已开始重新分析” +5. 调用 `getList()` 刷新列表 +6. 失败时弹出错误提示 + +当前缺少用户确认步骤,因此点击即执行。 + +### 后端现状 + +后端现有 `/ccdi/project/tags/rebuild` 能力已满足本轮需求: + +- 支持按 `projectId` 提交项目级重打标 +- 会按既有流程更新项目状态 +- 完成后由现有链路刷新结果与风险人数 + +因此本轮仍然只做前端交互补充,不引入后端源码改造。 + +## 方案选择 + +### 推荐方案 + +在列表页现有 `handleReAnalyze(row)` 中补充确认弹窗,确认后继续执行当前请求和刷新逻辑。 + +执行顺序: + +1. 用户点击“重新分析” +2. 前端弹出确认框 +3. 用户点击“确定”后再进入接口调用 +4. 调用成功后提示“已开始重新分析” +5. 继续调用 `getList()` 刷新列表与统计 + +采用该方案的原因: + +- 改动最小,符合最短路径要求 +- 保持 `ProjectTable.vue` 只负责事件透传,不下沉业务交互逻辑 +- 与当前页面级操作风格一致,便于复用现有 loading 和刷新逻辑 + +### 不采用的方案 + +#### 方案一:在 `ProjectTable.vue` 内直接处理确认弹窗 + +不采用原因: + +- 表格组件职责变重 +- 确认逻辑与接口逻辑分散在父子组件之间 +- 不利于后续维护同类页面级操作 + +#### 方案二:抽象通用确认执行器 + +不采用原因: + +- 对当前需求属于过度设计 +- 只为单个按钮增加抽象,收益低于额外复杂度 + +## 详细设计 + +## 1. 交互设计 + +点击“重新分析”后,前端先弹出确认框,文案为: + +`确认对项目“{项目名称}”重新分析吗?重新分析将重新计算项目标签。` + +交互约束: + +- 点击“确定”才继续发起请求 +- 点击“取消”直接结束,不提示失败,不刷新列表 +- 弹窗只承担确认职责,不展示额外解释信息 + +## 2. 数据流与状态设计 + +确认后的请求链路保持现有实现: + +1. 读取 `projectId` +2. 设置当前项目按钮 loading +3. 调用 `rebuildProjectTags({ projectId })` +4. 成功后提示 `已开始重新分析` +5. 调用 `getList()` 刷新列表和顶部统计 +6. 在 `finally` 中清理 loading + +说明: + +- `getList()` 已并行请求项目列表和状态统计,继续复用即可保证界面一致性 +- 不做局部行状态修改,避免列表和顶部统计出现时序不一致 + +## 3. 异常与边界设计 + +### 取消确认 + +- 用户主动取消时,不发请求 +- 不设置 loading +- 不弹错误提示 + +### 接口失败 + +- 优先展示后端返回的 `error.message` +- 无明确业务文案时,统一提示 `重新分析失败,请稍后重试` +- 失败时不刷新列表,保持当前数据稳定 + +### 防重复提交 + +- 保持单项目维度的 `reAnalyzeLoadingMap` +- 只有在用户确认后才进入 loading +- 提交结束后恢复按钮状态 + +## 4. 测试设计 + +前端验证聚焦以下场景: + +1. 点击“重新分析”先出现确认弹窗 +2. 点击“取消”时不发请求、不刷新列表 +3. 点击“确定”后发起接口调用 +4. 请求成功时提示“已开始重新分析”并刷新列表 +5. 请求失败时提示失败信息,按钮恢复可点击 + +回归重点: + +- 重新分析按钮仍只在既有状态条件下显示 +- 成功刷新后项目状态和顶部统计继续由后端返回结果驱动 + +## 5. 后端影响说明 + +本轮后端无需改造。 + +原因: + +- 现有 `/ccdi/project/tags/rebuild` 已满足提交能力 +- 现有 `getList()` 刷新结果已经满足页面回显需要 +- 本次变更仅增加用户确认,不改变接口语义 + +## 6. 风险与约束 + +- 本轮仍然是“提交后刷新一次”的模式,不展示任务进度 +- 如果后端异步处理时间较长,用户看到项目进入处理中状态属于预期 +- 方案依赖现有后端重打标链路稳定可用,不额外建设旁路能力 + +## 7. 本次设计结论 + +本次需求采用“列表页现有重新分析链路上补确认弹窗,并在成功后继续全列表刷新”的方案。 + +该方案满足以下要求: + +- 最短路径实现 +- 不引入补丁式旁路方案 +- 前后端职责边界清晰 +- 列表数据与统计刷新保持一致