Files
ccdi/docs/design/2026-03-24-project-archive-design.md

293 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目列表归档功能设计文档
## 背景
项目管理列表中的“归档”按钮当前仅有前端入口,尚未接通真实后端归档逻辑。
现状包括:
- 项目列表页已在“已完成”项目上展示“归档”按钮
- 前端 API 已预留 `archiveProject(projectId)` 调用
- 项目详情页已经存在“上传数据”“参数配置”“结果总览”“专项排查”“流水明细查询”五个页签
- 后端项目状态常量已定义 `2-已归档`
但当前仍存在两个缺口:
1. 点击“归档”后不会真正更新项目状态
2. 已归档项目进入详情页后,仍可进入“上传数据”和“参数配置”页签
因此需要补齐“列表归档”到“详情只读导航”的完整闭环。
## 目标
- 让项目列表中的“归档”按钮真正触发项目归档
- 归档成功后将项目状态更新为 `2-已归档`
- 已归档项目在详情页中不可点击“上传数据”“参数配置”页签
- 已归档项目仍可查看结果总览、专项排查和流水明细查询
## 非目标
- 不新增“取消归档”或“恢复归档”能力
- 不新增“归档库”页面或独立归档路由
- 不实现“归档时删除项目相关数据”
- 不实现“归档时自动生成 PDF 报告”
- 不改动项目打标、结果计算、文件上传、参数保存的既有业务逻辑
## 方案对比
### 方案一:列表归档后,详情页禁用指定页签
- 做法:归档后将项目状态切换为 `2`,详情页基于项目状态禁用“上传数据”“参数配置”,并对旧链接做路由拦截
- 优点:完全贴合需求,复用现有状态体系,改动范围集中
- 缺点:需要同时覆盖列表入口、详情页导航和 URL 直达场景
### 方案二:只在上传页和参数页内部禁用操作
- 做法:详情页页签仍可点击,但进入页面后所有按钮和输入框禁用
- 优点:实现较快
- 缺点:与“页签本身不可点击”的需求不符,用户感知不一致
### 方案三:新增归档态详情壳子或独立归档路由
- 做法:已归档项目进入不同的详情结构
- 优点:后续扩展空间更大
- 缺点:明显超出当前需求,引入额外维护成本
## 最终方案
采用方案一。
在项目列表页完成真实归档后,后端将项目状态更新为 `2-已归档`,前端详情页根据项目状态禁用“上传数据”“参数配置”两个页签;若用户通过旧链接或手动拼接 URL 访问 `tab=upload``tab=config`,页面自动切换到 `overview`
## 现状分析
### 列表页现状
[`ProjectTable.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue) 已实现以下操作显示规则:
- `status === '1'` 时显示“查看结果”“重新分析”“归档”
- `status === '2'` 时只显示“查看结果”
这意味着列表操作层已经具备归档后的展示约束,本次无需新增额外状态分支,只需将归档动作接入真实后端。
### 归档弹窗现状
[`ArchiveConfirmDialog.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/ArchiveConfirmDialog.vue) 当前仍包含以下超范围内容:
- 删除项目相关数据
- 自动生成项目报告 PDF
- 归档库查看和恢复
这些内容不在本次需求内,且会让确认语义偏离“仅归档状态变更”,需要收敛。
### 后端现状
[`CcdiProjectController.java`](/Users/wkc/Desktop/ccdi/ccdi/ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectController.java) 当前没有归档接口。
[`CcdiProjectServiceImpl.java`](/Users/wkc/Desktop/ccdi/ccdi/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImpl.java) 已具备:
- 项目状态常量管理
- 项目状态更新能力
- 已归档项目禁止重新进入打标流程的约束
说明后端状态体系已经具备归档语义,本次只需补齐专门的归档入口和归档校验。
### 详情页现状
[`detail.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/detail.vue) 当前会:
- 通过 `route.query.tab` 决定默认页签
- 通过 `getProject(projectId)` 拉取项目详情
- 根据项目状态处理“打标中”轮询
但尚未基于“已归档”状态限制页签可达性,因此需要在导航层和路由初始化层同时补齐控制。
## 详细设计
## 1. 后端接口设计
新增归档接口:
- URL`POST /ccdi/project/{projectId}/archive`
- 入参:路径参数 `projectId`
- 返回:`AjaxResult.success("项目归档成功")`
设计原则:
- 不新增请求体
- 不复用“更新项目”接口承载归档语义
- 归档作为独立动作,单独由项目服务处理
## 2. 后端服务设计
在项目服务中新增 `archiveProject(Long projectId, String operator)` 方法。
执行逻辑:
1. 查询项目
2. 校验项目存在
3. 校验当前状态必须为 `1-已完成`
4. 写入归档状态
5. 更新操作人和更新时间
归档写入规则:
- `status = "2"`
- `isArchived = 1`
- `updateBy` 更新为当前操作人
- `updateTime` 更新为当前时间
### 状态校验规则
只允许“已完成”项目归档。
禁止归档的状态包括:
- `0-进行中`
- `2-已归档`
- `3-打标中`
这样可以保证:
- 与列表页“仅已完成项目展示归档按钮”的规则一致
- 避免通过绕过前端直接调用接口导致非法状态流转
## 3. 列表页交互设计
[`index.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/index.vue) 中的 `handleConfirmArchive` 改为真实调用归档接口。
执行顺序:
1. 用户在列表点击“归档”
2. 打开归档确认弹窗
3. 用户确认后调用 `archiveProject(projectId)`
4. 成功后关闭弹窗并刷新列表
5. 刷新后项目状态显示为“已归档”
6. 列表操作区自然收敛为仅显示“查看结果”
失败时:
- 保持弹窗打开
- 展示后端返回的业务错误或统一失败提示
- 不刷新列表
## 4. 归档确认弹窗设计
[`ArchiveConfirmDialog.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/ArchiveConfirmDialog.vue) 收敛为纯确认弹窗。
保留内容:
- 项目名称确认文案
- “确认后项目状态将变更为已归档”的说明
- 取消 / 确认归档按钮
- 提交中的 loading 状态
移除内容:
- “同时删除项目相关数据”
- “自动生成项目报告 PDF”
- “归档库查看和恢复”
这样可以确保弹窗所表达的业务含义与本次真实实现完全一致。
## 5. 详情页签禁用设计
[`detail.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/detail.vue) 增加“已归档”状态判断。
当项目为已归档时:
- “上传数据”页签禁用
- “参数配置”页签禁用
- “结果总览”页签可点击
- “专项排查”页签可点击
- “流水明细查询”页签可点击
本次控制点放在页签本身,而不是仅在子页面内部禁用操作,以满足“页签本身不可点击”的交互要求。
## 6. 路由初始化与地址直达拦截
为防止用户通过旧链接访问受限页签,需要在 `initActiveTabFromRoute()` 中增加归档态判断。
规则如下:
-`tab``upload``config` 且项目已归档,则目标页签改为 `overview`
- 其他页签保持原逻辑
该规则同时覆盖:
- 刷新页面
- 手动输入 URL
- 从外部链接进入详情页
这样可以保证归档态限制不仅体现在视觉层,也体现在路由可达性层。
## 7. 子组件保护设计
虽然本次核心要求是“页签不可点击”,但仍建议在以下组件中补充归档态保护:
- [`UploadData.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue)
- [`ParamConfig.vue`](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue)
保护方式:
- 在现有“打标中禁用”判断基础上,增加“已归档禁用”判断
- 若未来这些组件被其他入口复用,也不会绕过归档限制
这不是新增业务方案,而是对同一条归档约束链路的补强。
## 8. 异常处理设计
### 后端业务异常
后端直接返回明确业务提示,例如:
- 项目不存在
- 仅已完成项目允许归档
- 项目已归档,无需重复操作
前端优先展示后端消息,不自行改写业务文案。
### 前端请求异常
当请求失败但没有明确业务提示时,列表页统一提示:
- `项目归档失败,请稍后重试`
失败时不刷新列表,也不修改当前行本地状态。
## 9. 测试设计
### 后端验证
至少验证以下场景:
1. 已完成项目调用归档接口成功,状态更新为 `2``isArchived` 更新为 `1`
2. 进行中项目调用归档接口被拒绝
3. 打标中项目调用归档接口被拒绝
4. 已归档项目重复归档被拒绝
### 前端验证
至少验证以下场景:
1. 列表点击“归档”后会调用真实接口
2. 归档成功后关闭弹窗并刷新列表
3. 已归档项目列表中不再显示“归档”和“重新分析”
4. 已归档项目详情页中“上传数据”“参数配置”页签不可点击
5. 手动访问 `?tab=upload``?tab=config` 时自动切换到 `overview`
6. 结果总览、专项排查、流水明细查询在归档态下仍可正常进入
## 10. 风险与约束
- 本次不提供“取消归档”,因此归档操作一旦成功,只能按当前产品规则进入只读查看路径。
- 详情页禁用页签依赖项目详情接口返回正确的状态字段;若后端返回口径不一致,需要以前端当前统一使用的 `projectStatus/status` 兼容逻辑处理。
- 当前项目详情在首次进入时先按路由参数设置页签,再异步加载项目详情,因此实现时需要注意在拿到项目状态后再次校正受限页签,避免短暂展示错误页签。
## 验收标准
- 项目列表中“已完成”项目点击“归档”后,确认即可将项目状态改为“已归档”
- 项目归档成功后,列表刷新且该项目只保留“查看结果”操作
- 已归档项目进入详情页后,“上传数据”“参数配置”页签不可点击
- 用户通过 URL 访问受限页签时会自动跳转到“结果总览”
- 已归档项目仍可正常查看“结果总览”“专项排查”“流水明细查询”