From 083693c7e8aff1dc70807a50634f9c5ba527a981 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Fri, 27 Feb 2026 17:22:22 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E7=BB=9F=E8=AE=A1=E4=BF=AE=E5=A4=8D=E5=AE=9E?= =?UTF-8?q?=E6=96=BD=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-02-27-project-status-counts-fix.md | 578 ++++++++++++++++++ 1 file changed, 578 insertions(+) create mode 100644 docs/plans/2026-02-27-project-status-counts-fix.md diff --git a/docs/plans/2026-02-27-project-status-counts-fix.md b/docs/plans/2026-02-27-project-status-counts-fix.md new file mode 100644 index 0000000..7dcfacb --- /dev/null +++ b/docs/plans/2026-02-27-project-status-counts-fix.md @@ -0,0 +1,578 @@ +# 项目管理状态统计修复实施计划 + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** 修复项目管理标签页状态统计功能,使标签页显示数据库中所有该状态的项目总数,而非当前页的数量。 + +**Architecture:** 后端新增独立的状态统计接口 `/ccdi/project/statusCounts`,前端在加载列表时并行调用统计接口,使用 `Promise.all` 同时获取列表数据和统计数据。 + +**Tech Stack:** Java 17, Spring Boot 3.5.8, MyBatis Plus 3.5.10, Vue.js 2.6.12, Element UI 2.15.14 + +--- + +## Task 1: 创建状态统计 VO 类 + +**Files:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectStatusCountsVO.java` + +**Step 1: 创建 VO 类文件** + +创建新文件 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectStatusCountsVO.java`: + +```java +package com.ruoyi.ccdi.project.domain.vo; + +import lombok.Data; + +/** + * 项目状态统计VO + * + * @author ruoyi + */ +@Data +public class CcdiProjectStatusCountsVO { + /** 全部项目总数 */ + private Long all; + + /** 进行中项目数(状态0) */ + private Long status0; + + /** 已完成项目数(状态1) */ + private Long status1; + + /** 已归档项目数(状态2) */ + private Long status2; +} +``` + +**Step 2: 验证文件创建** + +Run: `ls ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectStatusCountsVO.java` + +Expected: 文件存在 + +**Step 3: Commit** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectStatusCountsVO.java +git commit -m "feat: 添加项目状态统计 VO 类" +``` + +--- + +## Task 2: 添加 Service 接口方法 + +**Files:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectService.java` + +**Step 1: 读取当前 Service 接口** + +Run: Read `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectService.java` + +Expected: 看到现有方法列表 + +**Step 2: 添加统计方法声明** + +在 `ICcdiProjectService.java` 文件末尾(类定义的最后一个方法之后)添加: + +```java +/** + * 查询各状态的项目总数(不受搜索条件影响) + * + * @return 状态统计 + */ +CcdiProjectStatusCountsVO getStatusCounts(); +``` + +**Step 3: 验证语法** + +Run: `cd ccdi-project && mvn compile` + +Expected: BUILD SUCCESS + +**Step 4: Commit** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectService.java +git commit -m "feat: Service 接口添加状态统计方法声明" +``` + +--- + +## Task 3: 实现 Service 统计方法 + +**Files:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImpl.java` + +**Step 1: 读取当前 Service 实现类** + +Run: Read `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImpl.java` + +Expected: 看到现有实现和依赖 + +**Step 2: 确认需要的 import** + +检查文件顶部是否已有以下 import: +- `com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper` +- `com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO` + +如果没有,添加它们。 + +**Step 3: 实现 getStatusCounts 方法** + +在 Service 实现类末尾添加方法实现: + +```java +@Override +public CcdiProjectStatusCountsVO getStatusCounts() { + CcdiProjectStatusCountsVO vo = new CcdiProjectStatusCountsVO(); + + // 统计全部项目 + Long totalCount = ccdiProjectMapper.selectCount(null); + vo.setAll(totalCount); + + // 统计进行中项目(状态0) + Long status0Count = ccdiProjectMapper.selectCount( + new LambdaQueryWrapper() + .eq(CcdiProject::getStatus, "0") + ); + vo.setStatus0(status0Count); + + // 统计已完成项目(状态1) + Long status1Count = ccdiProjectMapper.selectCount( + new LambdaQueryWrapper() + .eq(CcdiProject::getStatus, "1") + ); + vo.setStatus1(status1Count); + + // 统计已归档项目(状态2) + Long status2Count = ccdiProjectMapper.selectCount( + new LambdaQueryWrapper() + .eq(CcdiProject::getStatus, "2") + ); + vo.setStatus2(status2Count); + + return vo; +} +``` + +**Step 4: 验证编译** + +Run: `cd ccdi-project && mvn compile` + +Expected: BUILD SUCCESS + +**Step 5: Commit** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImpl.java +git commit -m "feat: 实现项目状态统计方法" +``` + +--- + +## Task 4: 添加 Controller 接口 + +**Files:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectController.java` + +**Step 1: 读取当前 Controller** + +Run: Read `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectController.java` + +Expected: 看到现有接口定义 + +**Step 2: 添加状态统计接口** + +在 Controller 类的最后一个方法之后添加: + +```java +/** + * 查询项目状态统计 + */ +@GetMapping("/statusCounts") +@Operation(summary = "查询项目状态统计") +@PreAuthorize("@ss.hasPermi('ccdi:project:list')") +public AjaxResult getStatusCounts() { + CcdiProjectStatusCountsVO counts = projectService.getStatusCounts(); + return AjaxResult.success(counts); +} +``` + +**Step 3: 验证编译** + +Run: `cd ccdi-project && mvn compile` + +Expected: BUILD SUCCESS + +**Step 4: Commit** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiProjectController.java +git commit -m "feat: 添加项目状态统计接口" +``` + +--- + +## Task 5: 测试后端接口 + +**Files:** +- None (测试验证) + +**Step 1: 启动后端服务** + +Run: `mvn spring-boot:run` 或 `ry.bat` + +Expected: 服务启动成功,看到 "Started RuoYiApplication" 日志 + +**Step 2: 获取访问令牌** + +Run (使用 curl 或浏览器): + +```bash +curl -X POST "http://localhost:8080/login/test?username=admin&password=admin123" +``` + +Expected: 返回 JSON 包含 token + +**Step 3: 测试状态统计接口** + +在 Swagger UI 中测试: +1. 访问: http://localhost:8080/swagger-ui/index.html +2. 找到: "纪检初核项目管理" → "GET /ccdi/project/statusCounts" +3. 点击 "Try it out" → "Execute" + +或使用 curl (替换 YOUR_TOKEN): + +```bash +curl -X GET "http://localhost:8080/ccdi/project/statusCounts" \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +Expected: 返回类似以下的响应: + +```json +{ + "code": 200, + "msg": "操作成功", + "data": { + "all": 30, + "status0": 10, + "status1": 15, + "status2": 5 + } +} +``` + +**Step 4: 验证数据正确性** + +使用数据库工具连接 MySQL,执行: + +```sql +SELECT + status, + COUNT(*) as count +FROM ccdi_project +GROUP BY status; +``` + +Expected: 统计数字与接口返回一致 + +--- + +## Task 6: 添加前端 API 方法 + +**Files:** +- Modify: `ruoyi-ui/src/api/ccdiProject.js` + +**Step 1: 读取当前 API 文件** + +Run: Read `ruoyi-ui/src/api/ccdiProject.js` + +Expected: 看到现有的 API 方法定义 + +**Step 2: 添加状态统计 API 方法** + +在文件末尾(最后一个 export 函数之后)添加: + +```javascript +// 查询项目状态统计 +export function getStatusCounts() { + return request({ + url: '/ccdi/project/statusCounts', + method: 'get' + }) +} +``` + +**Step 3: 验证语法** + +Run: `cd ruoyi-ui && npm run lint -- --fix src/api/ccdiProject.js` + +Expected: No errors + +**Step 4: Commit** + +```bash +git add ruoyi-ui/src/api/ccdiProject.js +git commit -m "feat: 前端 API 添加状态统计方法" +``` + +--- + +## Task 7: 修改前端页面组件 + +**Files:** +- Modify: `ruoyi-ui/src/views/ccdiProject/index.vue` + +**Step 1: 读取当前页面组件** + +Run: Read `ruoyi-ui/src/views/ccdiProject/index.vue` + +Expected: 看到现有代码结构 + +**Step 2: 修改 import 语句** + +找到第 64 行左右的 import 语句: + +```javascript +import {listProject} from '@/api/ccdiProject' +``` + +修改为: + +```javascript +import {listProject, getStatusCounts} from '@/api/ccdiProject' +``` + +**Step 3: 重构 getList 方法** + +找到 `getList()` 方法(大约第 122-134 行),完全替换为: + +```javascript +/** 查询项目列表 */ +getList() { + this.loading = true + + // 并行请求列表数据和状态统计 + Promise.all([ + listProject(this.queryParams), + getStatusCounts() + ]).then(([listResponse, countsResponse]) => { + // 处理列表数据 + this.projectList = listResponse.rows + this.total = listResponse.total + + // 处理状态统计 + const counts = countsResponse.data + this.tabCounts = { + all: counts.all, + '0': counts.status0, + '1': counts.status1, + '2': counts.status2 + } + + this.loading = false + }).catch(() => { + this.loading = false + }) +} +``` + +**Step 4: 删除旧的统计方法** + +找到并删除 `calculateTabCounts()` 方法(大约第 135-145 行): + +```javascript +// 删除这个方法 +/** 计算标签页数量 */ +calculateTabCounts() { + // 注意:这里需要后端API返回所有状态的数量统计 + // 目前暂时使用当前页的数据进行计算 + this.tabCounts = { + all: this.total, + '0': this.projectList.filter(p => p.status === '0').length, + '1': this.projectList.filter(p => p.status === '1').length, + '2': this.projectList.filter(p => p.status === '2').length + } +} +``` + +**Step 5: 验证语法** + +Run: `cd ruoyi-ui && npm run lint -- --fix src/views/ccdiProject/index.vue` + +Expected: No errors + +**Step 6: Commit** + +```bash +git add ruoyi-ui/src/views/ccdiProject/index.vue +git commit -m "refactor: 使用后端统计接口替换前端计算" +``` + +--- + +## Task 8: 测试前端功能 + +**Files:** +- None (测试验证) + +**Step 1: 确保后端服务运行** + +确认后端服务在运行中。 + +**Step 2: 启动前端开发服务器** + +Run: + +```bash +cd ruoyi-ui +npm run dev +``` + +Expected: 服务启动,看到 "App running at" 消息 + +**Step 3: 测试页面加载** + +1. 打开浏览器访问: http://localhost:80 +2. 登录系统 (admin/admin123) +3. 导航到 "项目管理" 页面 + +Expected: +- 页面正常加载 +- 标签页显示正确的统计数字(例如:全部项目(30)) +- 标签页数字不随分页变化 + +**Step 4: 测试搜索功能** + +1. 在搜索框输入项目名称 +2. 点击搜索按钮或按回车 + +Expected: +- 列表正确过滤 +- 标签页数字保持不变(显示总数) + +**Step 5: 测试分页功能** + +1. 点击分页组件切换到第 2 页 + +Expected: +- 列表切换到第 2 页 +- 标签页数字保持不变 + +**Step 6: 测试状态切换功能** + +1. 点击"进行中"标签 + +Expected: +- 列表只显示进行中的项目 +- 标签页数字保持不变(仍显示总数) + +**Step 7: 测试浏览器控制台** + +打开浏览器开发者工具的 Console 标签 + +Expected: +- 没有 JavaScript 错误 +- 看到两个 API 请求成功(list 和 statusCounts) + +--- + +## Task 9: 最终提交和文档更新 + +**Files:** +- Modify: `docs/plans/2026-02-27-project-status-counts-fix-design.md` + +**Step 1: 更新设计文档状态** + +修改设计文档的状态部分: + +```markdown +## 文档信息 + +- **创建日期**: 2026-02-27 +- **作者**: Claude Code +- **状态**: ✅ 已完成 +``` + +**Step 2: 验收清单** + +对照设计文档的验收标准,确认: + +- [ ] 后端 `/statusCounts` 接口返回正确的统计数字 +- [ ] 前端标签页显示数据库中的完整统计 +- [ ] 搜索不影响标签页统计数字 +- [ ] 分页不影响标签页统计数字 +- [ ] 状态过滤不影响标签页统计数字 +- [ ] 统计接口响应时间 < 100ms +- [ ] 页面加载时间无明显增加 + +**Step 3: 提交文档更新** + +```bash +git add docs/plans/2026-02-27-project-status-counts-fix-design.md +git commit -m "docs: 更新项目状态统计修复设计文档状态为已完成" +``` + +**Step 4: 推送所有提交** + +```bash +git push origin dev +``` + +--- + +## 验收清单 + +在完成所有任务后,验证以下内容: + +### 功能验收 +- [ ] 后端接口正确返回统计数字 +- [ ] 前端标签页显示正确统计 +- [ ] 搜索不影响统计数字 +- [ ] 分页不影响统计数字 +- [ ] 状态过滤不影响统计数字 + +### 性能验收 +- [ ] 统计接口响应时间 < 100ms +- [ ] 页面加载流畅 + +### 代码质量 +- [ ] 后端代码符合规范 +- [ ] 前端代码符合规范 +- [ ] 提交信息清晰 + +--- + +## 注意事项 + +1. **测试数据准备**: 如果数据库中没有足够的项目数据,可以先插入一些测试数据以验证统计功能 +2. **错误处理**: 当前实现中,如果统计接口失败,会在控制台显示错误但不阻塞列表加载 +3. **性能考虑**: 如果项目数量很大(> 10000),建议后续优化为 GROUP BY 单次查询 + +--- + +## 回滚方案 + +如果实施后发现问题,可以通过以下步骤回滚: + +1. **回滚前端代码**: + ```bash + git revert + ``` + +2. **回滚后端代码**: + ```bash + git revert + ``` + +3. **重新部署服务** + +--- + +## 相关文档 + +- 设计文档: `docs/plans/2026-02-27-project-status-counts-fix-design.md` +- 若依框架文档: 项目根目录的 `CLAUDE.md` +- MyBatis Plus 文档: https://baomidou.com/