# 账务日志统计字段对齐 Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 修复 `getLogStat` 返回字段与前端 `AccountingAdjustStatRespVO` 不匹配的问题,使账务日志统计面板正确显示金额汇总、各状态笔数。 **Architecture:** 后端已有 `AccountingAdjustLogController`(含 `log-page`/`log-stat`/`log-detail`)和 `AccountingAdjustActionController`(含 `log-refund`/`log-prestorage`/`log-revoke`/`log-process`/`log-attachments`/`log-export`),6 个操作端点均已存在。唯一缺口是 `log-stat` 返回的 `AccountingAdjustLogStatRespVO` 使用 `totalAmount`/`completedCount` 等旧字段名,而前端期望 `totalActionAmount`/`successCount`/`failCount` 等 8 个新字段。 **Tech Stack:** Java 17, Spring Boot, MyBatis-Plus, JUnit 5 + Mockito, Lombok --- ## 前置说明:端点已存在 前端调用的 6 个操作端点均已在 `AccountingAdjustActionController` 中实现,路径对比如下: | 前端 API | 后端 Controller | 状态 | |---|---|---| | `GET log-export` | `ActionController.exportLog()` | ✅ | | `GET log-process` | `ActionController.getLogProcess()` | ✅ | | `GET log-attachments` | `ActionController.getLogAttachments()` | ✅ | | `POST log-refund` | `ActionController.createLogRefund()` | ✅ | | `POST log-prestorage` | `ActionController.createLogPrestorage()` | ✅ | | `POST log-revoke` | `ActionController.revokeLog()` | ✅ | 本次只修 **统计字段对齐** 一个问题。 --- ### Task 1: 扩展 StatRespVO 字段 **Files:** - Modify: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/vo/AccountingAdjustLogStatRespVO.java` - Reference: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImpl.java:95-107` (current `getLogStat`) **当前字段(6个,与前端不匹配):** ```java private Long totalCount; // 总条数 → 保留 private BigDecimal totalAmount; // 调整金额 → 改为 totalActionAmount private BigDecimal totalWaterVolume; // 调整水量 → 保留兼容 private Long completedCount; // 已完成数量 → 替换 private Long pendingCount; // 未完成数量 → 替换 private Long cancelledCount; // 已撤销数量 → 替换 ``` **前端期望字段(需新增):** ```java private BigDecimal totalActionAmount; // 金额汇总 private Long totalCount; // 总笔数 (已有) private Long successCount; // 成功笔数 private Long failCount; // 失败笔数 private Long pendingApprovalCount; // 待审批笔数 private Long approvalRequiredCount; // 需要审批笔数 private Long approvedCount; // 审批通过笔数 private Long rejectedCount; // 审批驳回笔数 ``` - [ ] **Step 1: 修改 VO 字段** 用以下完整内容替换 `AccountingAdjustLogStatRespVO.java`: ```java package cn.com.emsoft.sw.business.controller.admin.accountingadjust.accountProcess.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; @Schema(description = "管理后台 - 账务日志兼容统计 Response VO") @Data public class AccountingAdjustLogStatRespVO { @Schema(description = "金额汇总(所有记录 actionAmount 求和)") private BigDecimal totalActionAmount; @Schema(description = "总笔数") private Long totalCount; @Schema(description = "成功笔数 (resultStatus == SUCCESS)") private Long successCount; @Schema(description = "失败笔数 (resultStatus == FAIL)") private Long failCount; @Schema(description = "待审批笔数 (approvalStatus == PENDING_APPROVAL)") private Long pendingApprovalCount; @Schema(description = "需要审批笔数 (approvalRequired == true)") private Long approvalRequiredCount; @Schema(description = "审批通过笔数 (approvalStatus == APPROVED)") private Long approvedCount; @Schema(description = "审批驳回笔数 (approvalStatus == REJECTED)") private Long rejectedCount; // 保留旧字段兼容已有调用方(如单元测试中的 getTotalAmount()) @Schema(description = "调整金额(兼容别名,等同于 totalActionAmount)") private BigDecimal totalAmount; @Schema(description = "调整水量") private BigDecimal totalWaterVolume; @Schema(description = "已完成数量(兼容别名,等同于 successCount)") private Long completedCount; @Schema(description = "未完成数量(兼容别名,等同于 pendingApprovalCount)") private Long pendingCount; @Schema(description = "已撤销数量(兼容别名,等同于 failCount + rejectedCount)") private Long cancelledCount; } ``` **设计要点:保留旧字段 `totalAmount`/`completedCount`/`pendingCount`/`cancelledCount` 作为兼容别名,Service 中同时设置新旧两套字段,避免破坏已有单元测试。** --- ### Task 2: 更新 getLogStat 实现 **Files:** - Modify: `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImpl.java:95-107` - Test: `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImplTest.java` - [ ] **Step 1: 替换 getLogStat 方法体** 将 `AccountingAdjustLogProcessServiceImpl.java` 中 `getLogStat` 方法(当前约 12 行)替换为: ```java @Override public AccountingAdjustLogStatRespVO getLogStat(AccountingAdjustLogPageReqVO reqVO) { List records = loadRecords(reqVO); AccountingAdjustLogStatRespVO respVO = new AccountingAdjustLogStatRespVO(); // 新字段:前端直接使用 respVO.setTotalActionAmount(records.stream() .map(record -> nvl(record.actionAmount)) .reduce(BigDecimal.ZERO, BigDecimal::add)); respVO.setTotalCount((long) records.size()); respVO.setSuccessCount(records.stream() .filter(record -> "SUCCESS".equals(record.resultStatus)).count()); respVO.setFailCount(records.stream() .filter(record -> "FAIL".equals(record.resultStatus)).count()); respVO.setPendingApprovalCount(records.stream() .filter(record -> "PENDING_APPROVAL".equals(record.approvalStatus)).count()); respVO.setApprovalRequiredCount(records.stream() .filter(record -> Boolean.TRUE.equals(record.approvalRequired)).count()); respVO.setApprovedCount(records.stream() .filter(record -> "APPROVED".equals(record.approvalStatus)).count()); respVO.setRejectedCount(records.stream() .filter(record -> "REJECTED".equals(record.approvalStatus)).count()); // 旧字段兼容(供已有单元测试和未迁移调用方使用) respVO.setTotalAmount(respVO.getTotalActionAmount()); respVO.setTotalWaterVolume(records.stream() .map(record -> nvl(record.waterVolumeChange)) .reduce(BigDecimal.ZERO, BigDecimal::add)); respVO.setCompletedCount(respVO.getSuccessCount()); respVO.setPendingCount(respVO.getPendingApprovalCount()); respVO.setCancelledCount(respVO.getFailCount() + respVO.getRejectedCount()); return respVO; } ``` **注意:`LegacyLogRecord` 中 `actionAmount`、`resultStatus`、`approvalStatus`、`approvalRequired`、`waterVolumeChange` 字段已在 Service 内部类中定义,无需额外 import。** - [ ] **Step 2: 编译验证** ```bash cd /Volumes/Dpan/github/water-workspace/water-backend mvn compile -pl sw-business/sw-business-server -am -q 2>&1 | tail -10 ``` 预期:`BUILD SUCCESS` --- ### Task 3: 更新单元测试 **Files:** - Modify: `sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImplTest.java` - [ ] **Step 1: 在已有测试中添加新字段断言** 在 `getLogDetailAndStat_shouldReturnMergedDetailsAndCounts` 测试方法末尾(`assertEquals(new BigDecimal("5.00"), stat.getTotalAmount());` 之后),追加新字段断言: ```java // 新统计字段断言 assertEquals(new BigDecimal("5.00"), stat.getTotalActionAmount()); assertEquals(1L, stat.getSuccessCount()); assertEquals(0L, stat.getFailCount()); assertEquals(1L, stat.getPendingApprovalCount()); assertEquals(1L, stat.getApprovalRequiredCount()); assertEquals(0L, stat.getApprovedCount()); assertEquals(0L, stat.getRejectedCount()); // 保持旧字段兼容断言 assertEquals(new BigDecimal("5.00"), stat.getTotalAmount()); assertEquals(1L, stat.getCompletedCount()); assertEquals(1L, stat.getPendingCount()); assertEquals(0L, stat.getCancelledCount()); ``` - [ ] **Step 2: 运行测试验证** ```bash cd /Volumes/Dpan/github/water-workspace/water-backend mvn test -pl sw-business/sw-business-server -Dtest=AccountingAdjustLogProcessServiceImplTest -q 2>&1 | tail -15 ``` 预期所有测试通过(4 个 test case,含新增断言)。 --- ### Task 4: 全量编译 + 提交 - [ ] **Step 1: 全量编译** ```bash cd /Volumes/Dpan/github/water-workspace/water-backend mvn compile -pl sw-business/sw-business-server -am -q 2>&1 | tail -10 ``` - [ ] **Step 2: 提交** ```bash cd /Volumes/Dpan/github/water-workspace/water-backend git add sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/controller/admin/accountingadjust/accountProcess/vo/AccountingAdjustLogStatRespVO.java git add sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImpl.java git add sw-business/sw-business-server/src/test/java/cn/com/emsoft/sw/business/service/accountingadjust/accountProcess/AccountingAdjustLogProcessServiceImplTest.java git commit -m "fix: align log-stat response fields with frontend AccountingAdjustStatRespVO - Add totalActionAmount, successCount, failCount, pendingApprovalCount, approvalRequiredCount, approvedCount, rejectedCount to StatRespVO - Update getLogStat() to compute new fields from loaded records - Keep legacy fields (totalAmount, completedCount, pendingCount, cancelledCount) as compatibility aliases - Update unit test with new field assertions" ``` --- ## Self-Review **1. Spec coverage:** 统计字段对齐是唯一的后端缺口,Task 1-3 完整覆盖。 **2. Placeholder scan:** 无 TBD/TODO/占位符,所有步骤都有具体代码和命令。 **3. Type consistency:** - `LegacyLogRecord` 内部类字段 `actionAmount`(BigDecimal)、`resultStatus`(String)、`approvalStatus`(String)、`approvalRequired`(Boolean)、`waterVolumeChange`(BigDecimal)均在 ServiceImpl 中定义,与 `getLogStat` 新实现一致。 - `AccountingAdjustLogStatRespVO` 新旧字段并存,旧测试 `getTotalAmount()` 等调用不受影响。 - 前端 `AccountingAdjustStatRespVO` 的 8 个字段名与新增 VO 字段名完全一致(驼峰命名)。