新增项目归档功能设计文档
This commit is contained in:
292
docs/design/2026-03-24-project-archive-design.md
Normal file
292
docs/design/2026-03-24-project-archive-design.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# 项目列表归档功能设计文档
|
||||
|
||||
## 背景
|
||||
|
||||
项目管理列表中的“归档”按钮当前仅有前端入口,尚未接通真实后端归档逻辑。
|
||||
|
||||
现状包括:
|
||||
|
||||
- 项目列表页已在“已完成”项目上展示“归档”按钮
|
||||
- 前端 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 访问受限页签时会自动跳转到“结果总览”
|
||||
- 已归档项目仍可正常查看“结果总览”“专项排查”“流水明细查询”
|
||||
Reference in New Issue
Block a user