docs: record billing water zero fix evidence

This commit is contained in:
tangweijie 2026-07-31 11:12:00 +08:00
parent b614332e78
commit 719f75f8c7

View File

@ -0,0 +1,104 @@
# 开账后账单开账水量为零修复验证
## 基本信息
- 日期2026-07-31
- 范围REV-002 抄表开账 / 抄表录入
- 前端基线:`7e0f9b49`
- 后端基线:`5d856e4e8`
- 变更仓库:`water-frontend``water-backend`
## 根因
账单开账水量来自后端 `ReadingDataDO.checkWater`,普通开账时直接写入 `biz_charge.bill_water`
抄表录入页面保存单条手工抄表时,提交参数使用 `checkWater: row.checkWater || 0`。录入页在保存前只更新 `readWater`,未同步维护 `row.checkWater`,导致普通正水量记录会把空开账水量转换成 `0` 提交到后端。
后端复核逻辑只在 `checkWater == null` 时回退到 `readWater`;当请求已显式传入 `0` 时,会把 `0` 当作有效开账水量保留,最终普通开账将该值写入 `biz_charge.bill_water`
历史提交定位:
- 前端污染源:`0101ef433a2c4a2fcaeaa790ad143de25bc94c48`,作者/提交者 `Linxx``2026-06-09 16:20:04 +0800``checkWater: row.checkWater || 0`
- 后端复核保留逻辑:`7fed0d25b812a20cc3179b4eaabe03498f21bf35`,作者/提交者 `tangweijie``2026-07-28 17:22:55 +0800`,非空 `checkWater` 原样保留。
- 账单赋值旧逻辑:`076c1759462c05a7624fbf7e7e1d60d152fbf2ed`,作者/提交者 `Shaco-C``2025-10-18 23:38:12 +0800``charge.setBillWater(readingData.getCheckWater())`
## 修复
- `src/views/meterRead/meterEnter/index.vue`
- 新增 `calcManualCheckWater(row)`,按 `readWater + replaceWater + refundWater` 计算提交用开账水量。
- `buildManualMeterReadingInfo` 改为提交 `checkWater: calcManualCheckWater(row)`,不再把空值直接置为 `0`
- `tests/meterRead/meterEnterOverCircleRule.test.mjs`
- 增加契约测试,禁止回退到 `checkWater: row.checkWater || 0`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/readingdata/impl/ReadingDataServiceImpl.java`
- 保存手工抄表记录时不再信任请求中的 `checkWater`,统一按 `readWater + replaceWater + refundWater` 写入。
- 复核时如果 `checkWater == 0``readWater + replaceWater + refundWater` 为正数,则修正为计算后的水量。
- 保留真实零水量场景,例如 `readWater + replaceWater + refundWater == 0`
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/readingdata/ReadingCheckWaterHelper.java`
- 集中封装开账水量计算与“污染 0 修复”规则,避免保存、复核、开账各写一套公式。
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/charge/ChargeServiceImpl.java`
- 开账生成账单前增加兜底修正:同样只修复“计算水量为正但 `checkWater` 为 0”的异常记录。
- 修正后同步 `ReadingDataDO.checkWater`,再继续生成 `ChargeDO.billWater`
- 通用新建/修改营业账入口增加保护:`readWater + replaceWater` 为正但 `billWater` 为空或 0 时拒绝写入。
- `sw-business/sw-business-server/src/main/java/cn/com/emsoft/sw/business/service/counteraddreading/CounterAddReadingApplicationServiceImpl.java`
- 柜台加抄持久化前增加保护:计算水量为正但 `checkWater` 为空、负数或 0 时拒绝写入。
- 后端新增回归用例:
- `ReadingDataServiceImplManualReadingTest.processSingleReadingData_shouldCalculateCheckWaterInsteadOfTrustingSubmittedZero`
- `ChargeServiceBillingValidationTest.generateChargeBatch_shouldRepairZeroCheckWaterBeforeCreatingChargeWhenReadWaterIsPositive`
- `ReadingDataServiceImplCheckValidationTest.batchReCheckReadingData_shouldRepairZeroCheckWaterWhenReadWaterIsPositive`
- `ChargeLateFeeBeginDateWiringTest.createCharge_shouldRejectZeroBillWaterWhenReadWaterIsPositive`
- `CounterAddReadingApplicationServiceImplTest.validateCounterAddReadingCheckWater_shouldRejectZeroCheckWaterWhenReadWaterIsPositive`
## 验证
前端:
```bash
node --test tests/meterRead/meterEnterOverCircleRule.test.mjs src/views/meterRead/meterCheck/zero-water-validation.contract.test.mjs
```
结果11 个测试全部通过0 失败。
补充执行:
```bash
node --test tests/meterRead/*.test.mjs src/views/meterRead/meterCheck/zero-water-validation.contract.test.mjs
```
结果18 个测试通过1 个既有失败。失败用例为 `tests/meterRead/bookAdjustBehavior.test.mjs` 的册本调整取消用户过滤契约,与本次开账水量提交链路无关。
后端:
```bash
mvn -pl sw-business/sw-business-server -Dtest=ChargeServiceBillingValidationTest#generateChargeBatch_shouldRepairZeroCheckWaterBeforeCreatingChargeWhenReadWaterIsPositive test
```
结果:未进入目标测试,模块编译被既有错误阻塞:
- `CustApiImpl.java:[348,30] cannot find symbol getWorkerOrderId()`
- `OpenApiConfiguration.java:[24,53] cannot find symbol OPEN_API_AUTHENTICATION_FILTER`
```bash
mvn -pl sw-business/sw-business-server -Dtest=ReadingDataServiceImplCheckValidationTest#batchReCheckReadingData_shouldRepairZeroCheckWaterWhenReadWaterIsPositive test
```
结果:同样被上述模块编译错误阻塞。
```bash
mvn -pl sw-business/sw-business-server -Dtest=ReadingDataServiceImplManualReadingTest#processSingleReadingData_shouldCalculateCheckWaterInsteadOfTrustingSubmittedZero test
```
结果:同样被上述模块编译错误阻塞。
```bash
mvn -pl sw-business/sw-business-server -Dtest=ReadingDataServiceImplManualReadingTest#processSingleReadingData_shouldCalculateCheckWaterInsteadOfTrustingSubmittedZero,ReadingDataServiceImplCheckValidationTest#batchReCheckReadingData_shouldRepairZeroCheckWaterWhenReadWaterIsPositive,ChargeServiceBillingValidationTest#generateChargeBatch_shouldRepairZeroCheckWaterBeforeCreatingChargeWhenReadWaterIsPositive,ChargeLateFeeBeginDateWiringTest#createCharge_shouldRejectZeroBillWaterWhenReadWaterIsPositive,CounterAddReadingApplicationServiceImplTest#validateCounterAddReadingCheckWater_shouldRejectZeroCheckWaterWhenReadWaterIsPositive test
```
结果:同样未进入目标测试,模块编译仍被上述 2 个既有错误阻塞;未出现本次新增 helper 或校验相关的新编译错误。
空白检查:
```bash
git diff --check -- <本次触及文件>
```
结果:无输出。