Files
ccdi/docs/plans/frontend/2026-03-24-project-archive-frontend-implementation.md

353 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.
# Project Archive 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.
**Goal:** 让项目管理列表中的“归档”按钮真正触发归档,并让已归档项目在详情页中无法点击“上传数据”“参数配置”页签。
**Architecture:** 前端复用现有 `ruoyi-ui/src/api/ccdiProject.js` 中已预留的归档接口,在列表页 `index.vue` 接入真实异步提交,并收敛 `ArchiveConfirmDialog.vue` 的超范围文案。详情页 `detail.vue` 负责归档态页签禁用和 URL 直达拦截,`UploadData.vue``ParamConfig.vue` 再补一层归档态禁用保护,确保页面状态和组件行为一致。
**Tech Stack:** Vue 2, Element UI, Axios request wrapper, Node, npm
## 前端验收清单
- 列表页点击“归档”后会调用真实归档接口
- 归档成功后关闭弹窗并刷新列表
- 已归档项目在详情页中“上传数据”“参数配置”页签不可点击
- 直接访问 `?tab=upload` / `?tab=config` 时会自动切到 `overview`
- 归档确认弹窗不再出现删数据、生成 PDF、归档库等超需求文案
---
### Task 1: 先锁定列表页归档动作与弹窗文案契约
**Files:**
- Modify: `ruoyi-ui/tests/unit/project-list-archive-flow.test.js`
- Modify: `ruoyi-ui/src/views/ccdiProject/index.vue`
- Modify: `ruoyi-ui/src/views/ccdiProject/components/ArchiveConfirmDialog.vue`
- [ ] **Step 1: Write the failing source-based test**
新增 `ruoyi-ui/tests/unit/project-list-archive-flow.test.js`,至少锁定以下行为:
```javascript
assert(
pageSource.includes("await archiveProject(data.projectId)"),
"确认归档后应调用真实归档接口"
);
assert(
pageSource.includes("this.$modal.msgSuccess(\"项目归档成功\")") ||
pageSource.includes("this.$modal.msgSuccess('项目归档成功')"),
"归档成功后应提示项目归档成功"
);
assert(
!dialogSource.includes("自动生成项目报告PDF"),
"归档弹窗不应保留超范围 PDF 文案"
);
```
- [ ] **Step 2: Run test to verify it fails**
Run:
```bash
cd ruoyi-ui
node tests/unit/project-list-archive-flow.test.js
```
Expected:
- `FAIL`
- 原因是当前 `handleConfirmArchive` 仍然只有本地提示,弹窗还保留旧文案
- [ ] **Step 3: Implement the minimal list action and dialog cleanup**
`ruoyi-ui/src/views/ccdiProject/index.vue` 中:
1.`@/api/ccdiProject` 引入 `archiveProject`
2.`handleConfirmArchive(data)` 改为真实异步提交:
```javascript
async handleConfirmArchive(data) {
try {
await archiveProject(data.projectId)
this.$modal.msgSuccess("项目归档成功")
this.archiveDialogVisible = false
this.currentArchiveProject = null
this.getList()
} catch (error) {
const message = error && error.message ? error.message : "项目归档失败,请稍后重试"
this.$modal.msgError(message)
}
}
```
`ArchiveConfirmDialog.vue` 中:
- 删除 `deleteData`
- 删除“自动生成项目报告PDF”“归档库”“恢复”“同时删除数据”等文案和交互
- 仅保留“确认后状态变更为已归档”的说明和 loading 提交态
- [ ] **Step 4: Run test to verify it passes**
Run:
```bash
cd ruoyi-ui
node tests/unit/project-list-archive-flow.test.js
```
Expected:
- `PASS`
- [ ] **Step 5: Commit**
```bash
git add ruoyi-ui/src/views/ccdiProject/index.vue ruoyi-ui/src/views/ccdiProject/components/ArchiveConfirmDialog.vue ruoyi-ui/tests/unit/project-list-archive-flow.test.js
git commit -m "实现项目列表归档前端交互"
```
### Task 2: 实现详情页签禁用与 URL 直达拦截
**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
- Modify: `ruoyi-ui/tests/unit/project-detail-archive-tab-lock.test.js`
- [ ] **Step 1: Write the failing detail-page test**
新增 `ruoyi-ui/tests/unit/project-detail-archive-tab-lock.test.js`,锁定以下关键代码痕迹:
```javascript
assert(
source.includes('index="upload"') && source.includes(':disabled="isArchiveLockedTab(\'upload\')"'),
"上传数据页签应支持归档态禁用"
);
assert(
/initActiveTabFromRoute\(\)\s*\{[\s\S]*?this\.resolveAccessibleTab/.test(source),
"详情页应在路由初始化时校正归档态不可访问页签"
);
assert(
/handleMenuSelect\(index\)\s*\{[\s\S]*?if\s*\(this\.isArchiveLockedTab\(index\)\)\s*return/.test(source),
"点击禁用页签时不应切换"
);
```
- [ ] **Step 2: Run test to verify it fails**
Run:
```bash
cd ruoyi-ui
node tests/unit/project-detail-archive-tab-lock.test.js
```
Expected:
- `FAIL`
- 原因是当前详情页还没有归档态页签禁用逻辑
- [ ] **Step 3: Implement the minimal tab lock**
`ruoyi-ui/src/views/ccdiProject/detail.vue` 中增加:
```javascript
computed: {
isProjectArchived() {
return String(this.projectInfo.projectStatus) === "2";
}
}
```
以及两个辅助方法:
```javascript
isArchiveLockedTab(tab) {
return this.isProjectArchived && ["upload", "config"].includes(tab);
},
resolveAccessibleTab(tab) {
if (this.isArchiveLockedTab(tab)) {
return "overview";
}
return tab;
}
```
并修改:
- `initActiveTabFromRoute()`:先取 tab再调用 `resolveAccessibleTab(tab)`
- `handleMenuSelect(index)`:若禁用则直接 `return`
- 顶部两个 `el-menu-item`:加 `:disabled="isArchiveLockedTab('upload')"``:disabled="isArchiveLockedTab('config')"`
- [ ] **Step 4: Run tests to verify the tab lock passes**
Run:
```bash
cd ruoyi-ui
node tests/unit/project-detail-archive-tab-lock.test.js
node tests/unit/project-detail-tagging-polling.test.js
```
Expected:
- 两条测试都 `PASS`
- 说明归档页签禁用未破坏现有打标轮询结构
- [ ] **Step 5: Commit**
```bash
git add ruoyi-ui/src/views/ccdiProject/detail.vue ruoyi-ui/tests/unit/project-detail-archive-tab-lock.test.js
git commit -m "实现项目详情归档页签禁用"
```
### Task 3: 给上传页和参数页补一层归档态保护
**Files:**
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue`
- Modify: `ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js`
- Create: `ruoyi-ui/tests/unit/project-archive-readonly-guard.test.js`
- [ ] **Step 1: Extend the failing tests for archive guard**
`upload-data-disabled-cards.test.js` 中补充归档态断言:
```javascript
assert(
/disabled:\s*this\.isProjectTagging\s*\|\|\s*this\.isProjectArchived/.test(source),
"流水导入卡片应在项目已归档时同步置灰"
);
```
再新增 `project-archive-readonly-guard.test.js` 锁定:
```javascript
assert(uploadSource.includes('return String(this.projectInfo.projectStatus) === "2"'));
assert(paramSource.includes('return String(this.projectInfo.projectStatus) === "2"'));
assert(paramSource.includes("已归档项目暂不可修改参数"));
```
- [ ] **Step 2: Run tests to verify they fail**
Run:
```bash
cd ruoyi-ui
node tests/unit/upload-data-disabled-cards.test.js
node tests/unit/project-archive-readonly-guard.test.js
```
Expected:
- `FAIL`
- 原因是当前组件只处理“打标中”禁用
- [ ] **Step 3: Implement the minimal archived guard**
`UploadData.vue` 中补充:
```javascript
isProjectArchived() {
return String(this.projectInfo.projectStatus) === "2";
}
```
并把以下禁用逻辑扩展为归档态也成立:
- 顶部“拉取本行信息”“征信导入”
- 流水上传卡片 `disabled`
- 相关上传/拉取方法中的前置 `return`
`ParamConfig.vue` 中补充:
```javascript
isProjectArchived() {
return String(this.projectInfo.projectStatus) === "2";
}
```
并同步修改:
- 顶部提示文案:归档态显示“已归档项目暂不可修改参数”
- 输入框和保存按钮禁用条件改为 `isProjectTagging || isProjectArchived`
- `handleSaveAll()` 中增加归档态前置拦截
- [ ] **Step 4: Run frontend regression tests**
Run:
```bash
cd ruoyi-ui
node tests/unit/project-list-archive-flow.test.js
node tests/unit/project-detail-archive-tab-lock.test.js
node tests/unit/upload-data-disabled-cards.test.js
node tests/unit/project-archive-readonly-guard.test.js
```
Expected:
- 全部 `PASS`
- [ ] **Step 5: Commit**
```bash
git add ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue ruoyi-ui/tests/unit/upload-data-disabled-cards.test.js ruoyi-ui/tests/unit/project-archive-readonly-guard.test.js
git commit -m "补充项目归档前端只读保护"
```
### Task 4: 沉淀前端实施与验证记录
**Files:**
- Create: `docs/tests/records/2026-03-24-project-archive-frontend-verification.md`
- Create: `docs/reports/implementation/2026-03-24-project-archive-frontend-record.md`
- [ ] **Step 1: Write the verification skeleton**
验证记录至少包含:
```markdown
# 项目归档前端验证记录
## 验证范围
- 列表归档按钮接入真实接口
- 归档确认弹窗文案已收敛
- 详情页上传数据与参数配置页签不可点击
- 归档态下上传页与参数页有组件级保护
```
- [ ] **Step 2: Record exact frontend test commands**
把实际执行命令写入记录:
```bash
cd ruoyi-ui
node tests/unit/project-list-archive-flow.test.js
node tests/unit/project-detail-archive-tab-lock.test.js
node tests/unit/upload-data-disabled-cards.test.js
node tests/unit/project-archive-readonly-guard.test.js
```
Expected:
- 记录通过结果,或失败原因
- [ ] **Step 3: Write the frontend implementation record**
在实施记录中说明:
- 为什么弹窗文案需要收敛
- 为什么页签禁用和 URL 拦截需要同时做
- 为什么组件级归档保护仍要保留
- 本次前端改动覆盖了哪些文件与测试
- [ ] **Step 4: Commit**
```bash
git add docs/tests/records/2026-03-24-project-archive-frontend-verification.md docs/reports/implementation/2026-03-24-project-archive-frontend-record.md
git commit -m "补充项目归档前端实施记录"
```