293 lines
7.6 KiB
Markdown
293 lines
7.6 KiB
Markdown
# Project List Reanalyze 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` 作为 API 收口点,在 `ruoyi-ui/src/views/ccdiProject/index.vue` 中把 `handleReAnalyze` 从本地提示改为真实异步提交逻辑,并将按钮级提交态透传到 `ProjectTable.vue`。测试采用现有前端仓库里“读取源码断言文案/调用痕迹”的轻量风格,补充一条接口接线测试和一条交互状态测试。
|
|
|
|
**Tech Stack:** Vue 2, Element UI, Axios request wrapper, Node, npm
|
|
|
|
---
|
|
|
|
### Task 1: 先锁定“重新分析”接口契约
|
|
|
|
**Files:**
|
|
- Modify: `ruoyi-ui/src/api/ccdiProject.js`
|
|
- Test: `ruoyi-ui/tests/unit/project-list-reanalyze-api.test.js`
|
|
|
|
- [ ] **Step 1: Write the failing test**
|
|
|
|
新增一个轻量源码契约测试,锁定新增接口会调用正确的后端地址和请求方式:
|
|
|
|
```javascript
|
|
const assert = require("assert");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const apiPath = path.resolve(__dirname, "../../src/api/ccdiProject.js");
|
|
const source = fs.readFileSync(apiPath, "utf8");
|
|
|
|
assert(
|
|
source.includes("export function rebuildProjectTags(data)"),
|
|
"应新增项目重新分析接口封装"
|
|
);
|
|
|
|
assert(
|
|
source.includes("url: '/ccdi/project/tags/rebuild'"),
|
|
"重新分析接口应指向项目标签重打标地址"
|
|
);
|
|
|
|
assert(
|
|
source.includes("method: 'post'"),
|
|
"重新分析接口应使用 POST 请求"
|
|
);
|
|
```
|
|
|
|
- [ ] **Step 2: Run test to verify it fails**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
cd ruoyi-ui
|
|
node tests/unit/project-list-reanalyze-api.test.js
|
|
```
|
|
|
|
Expected:
|
|
|
|
- `FAIL`
|
|
- 原因是当前 `ccdiProject.js` 还没有 `rebuildProjectTags` 接口
|
|
|
|
- [ ] **Step 3: Write minimal implementation**
|
|
|
|
在 `ruoyi-ui/src/api/ccdiProject.js` 中新增:
|
|
|
|
```javascript
|
|
export function rebuildProjectTags(data) {
|
|
return request({
|
|
url: '/ccdi/project/tags/rebuild',
|
|
method: 'post',
|
|
data
|
|
})
|
|
}
|
|
```
|
|
|
|
约束:
|
|
|
|
- 不新建独立 API 文件
|
|
- 不改动现有其他接口命名和返回处理方式
|
|
|
|
- [ ] **Step 4: Run test to verify it passes**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
cd ruoyi-ui
|
|
node tests/unit/project-list-reanalyze-api.test.js
|
|
```
|
|
|
|
Expected:
|
|
|
|
- `PASS`
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add ruoyi-ui/src/api/ccdiProject.js ruoyi-ui/tests/unit/project-list-reanalyze-api.test.js
|
|
git commit -m "新增项目列表重新分析前端接口"
|
|
```
|
|
|
|
### Task 2: 将列表页重新分析按钮接入真实异步流程
|
|
|
|
**Files:**
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/index.vue`
|
|
- Modify: `ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue`
|
|
- Test: `ruoyi-ui/tests/unit/project-list-reanalyze-flow.test.js`
|
|
|
|
- [ ] **Step 1: Write the failing test**
|
|
|
|
新增一条交互接线测试,至少锁定以下行为:
|
|
|
|
```javascript
|
|
const assert = require("assert");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const pagePath = path.resolve(__dirname, "../../src/views/ccdiProject/index.vue");
|
|
const tablePath = path.resolve(__dirname, "../../src/views/ccdiProject/components/ProjectTable.vue");
|
|
const pageSource = fs.readFileSync(pagePath, "utf8");
|
|
const tableSource = fs.readFileSync(tablePath, "utf8");
|
|
|
|
assert(
|
|
pageSource.includes("rebuildProjectTags({ projectId: row.projectId })"),
|
|
"重新分析应调用真实重打标接口"
|
|
);
|
|
|
|
assert(
|
|
pageSource.includes("this.$modal.msgSuccess(\"已开始重新分析\")") ||
|
|
pageSource.includes("this.$modal.msgSuccess('已开始重新分析')"),
|
|
"重新分析成功提示应统一为已开始重新分析"
|
|
);
|
|
|
|
assert(
|
|
/finally\\s*\\(.*?this\\.getList\\(/s.test(pageSource) || pageSource.includes("this.getList()"),
|
|
"重新分析成功后应刷新列表"
|
|
);
|
|
|
|
assert(
|
|
tableSource.includes(":loading=\"reAnalyzeLoadingMap[String(scope.row.projectId)]\"") ||
|
|
tableSource.includes(":loading=\"reAnalyzeLoadingMap[scope.row.projectId]\""),
|
|
"表格中的重新分析按钮应支持提交态"
|
|
);
|
|
```
|
|
|
|
- [ ] **Step 2: Run test to verify it fails**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
cd ruoyi-ui
|
|
node tests/unit/project-list-reanalyze-flow.test.js
|
|
```
|
|
|
|
Expected:
|
|
|
|
- `FAIL`
|
|
- 原因是当前 `handleReAnalyze` 仍然只是 `console.log` 加本地提示
|
|
|
|
- [ ] **Step 3: Write minimal implementation**
|
|
|
|
在 `ruoyi-ui/src/views/ccdiProject/index.vue` 中:
|
|
|
|
1. 引入 `rebuildProjectTags`
|
|
2. 在 `data()` 中新增按钮级提交态,例如:
|
|
|
|
```javascript
|
|
reAnalyzeLoadingMap: {}
|
|
```
|
|
|
|
3. 将 `handleReAnalyze(row)` 改为:
|
|
|
|
```javascript
|
|
async handleReAnalyze(row) {
|
|
const projectKey = String(row.projectId)
|
|
if (this.reAnalyzeLoadingMap[projectKey]) {
|
|
return
|
|
}
|
|
this.$set(this.reAnalyzeLoadingMap, projectKey, true)
|
|
try {
|
|
await rebuildProjectTags({ projectId: row.projectId })
|
|
this.$modal.msgSuccess("已开始重新分析")
|
|
this.getList()
|
|
} catch (error) {
|
|
const message = error && error.message ? error.message : "重新分析失败,请稍后重试"
|
|
this.$modal.msgError(message)
|
|
} finally {
|
|
this.$set(this.reAnalyzeLoadingMap, projectKey, false)
|
|
}
|
|
}
|
|
```
|
|
|
|
在 `ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue` 中:
|
|
|
|
1. 新增 `reAnalyzeLoadingMap` 属性
|
|
2. 给“重新分析”按钮增加:
|
|
|
|
```vue
|
|
:loading="reAnalyzeLoadingMap[String(scope.row.projectId)]"
|
|
:disabled="reAnalyzeLoadingMap[String(scope.row.projectId)]"
|
|
```
|
|
|
|
约束:
|
|
|
|
- 只对“重新分析”按钮加提交态
|
|
- 不引入轮询
|
|
- 不新增确认弹窗
|
|
- 不修改按钮显示范围,仍只在 `status === '1'` 时显示
|
|
|
|
- [ ] **Step 4: Run test to verify it passes**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
cd ruoyi-ui
|
|
node tests/unit/project-list-reanalyze-flow.test.js
|
|
```
|
|
|
|
Expected:
|
|
|
|
- `PASS`
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add ruoyi-ui/src/views/ccdiProject/index.vue ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue ruoyi-ui/tests/unit/project-list-reanalyze-flow.test.js
|
|
git commit -m "实现项目列表重新分析交互"
|
|
```
|
|
|
|
### Task 3: 补齐失败提示与回归验证
|
|
|
|
**Files:**
|
|
- Modify: `ruoyi-ui/tests/unit/project-list-reanalyze-flow.test.js`
|
|
- Create: `docs/reports/implementation/2026-03-24-project-list-reanalyze-frontend-record.md`
|
|
|
|
- [ ] **Step 1: Extend the failing test for error handling**
|
|
|
|
在 `project-list-reanalyze-flow.test.js` 中继续锁定以下文案与行为:
|
|
|
|
```javascript
|
|
assert(
|
|
pageSource.includes("重新分析失败,请稍后重试"),
|
|
"重新分析失败时应有统一兜底提示"
|
|
);
|
|
|
|
assert(
|
|
pageSource.includes("error.message"),
|
|
"有明确业务异常时应优先透传后端返回文案"
|
|
);
|
|
```
|
|
|
|
- [ ] **Step 2: Run tests to verify the final contract**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
cd ruoyi-ui
|
|
node tests/unit/project-list-reanalyze-api.test.js
|
|
node tests/unit/project-list-reanalyze-flow.test.js
|
|
```
|
|
|
|
Expected:
|
|
|
|
- 两条测试都 `PASS`
|
|
|
|
- [ ] **Step 3: Run frontend build smoke check**
|
|
|
|
Run:
|
|
|
|
```bash
|
|
cd ruoyi-ui
|
|
npm run build:prod
|
|
```
|
|
|
|
Expected:
|
|
|
|
- 构建成功
|
|
- 不引入新的 ESLint 或模板编译错误
|
|
|
|
- [ ] **Step 4: Write the implementation record**
|
|
|
|
新增实施记录 `docs/reports/implementation/2026-03-24-project-list-reanalyze-frontend-record.md`,覆盖:
|
|
|
|
- 新增项目重分析 API 封装
|
|
- 列表页“重新分析”按钮接入真实接口
|
|
- 按钮提交态与成功/失败提示
|
|
- 执行过的测试命令和结果
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add ruoyi-ui/tests/unit/project-list-reanalyze-flow.test.js docs/reports/implementation/2026-03-24-project-list-reanalyze-frontend-record.md
|
|
git commit -m "补充项目列表重新分析前端实施记录"
|
|
```
|