库存使用记录-修复与测试报告.md
5.47 KB
库存使用记录 - 修复与测试报告
一、问题与修复概要
| 项目 | 说明 |
|---|---|
| 问题1 | 修改申请时,同一产品+门店出现多条记录 → 领用多算 |
| 修复1 | UpdateApplicationUsageRecords 按 ProductId+StoreId 合并 |
| 问题2 | 历史已有多算数据无法人工调整 |
| 修复2 | 新增 FixDuplicateUsageRecords 自动修复接口 |
| 验证点 | 作废记录不应参与领用统计 |
二、代码审查结论:作废记录是否会被统计?
✅ 结论:作废记录(IsEffective=0)不会被计入领用统计
所有涉及 totalUsage、领用数量统计的查询均包含 IsEffective == StatusEnum.有效 条件:
| 文件 | 位置 | 说明 |
|---|---|---|
| LqInventoryUsageService | GetReceivedBatchIdsAsync、MarkReceivedAsync、CalculateAveragePriceFromInventoryAsync 等 | x.IsEffective == StatusEnum.有效.GetHashCode() |
| LqInventoryService | 入库前检查、可用库存、平均单价计算 | x.IsEffective == StatusEnum.有效.GetHashCode() |
| LqProductService | 产品作废检查、库存明细 | x.IsEffective == StatusEnum.有效.GetHashCode() |
| GetStoreReceiveCostStatistics | whereConditions | u.F_IsEffective = 1 |
| LqBusinessUnitManagerSalaryService | 原生SQL | WHERE u.F_IsEffective = 1 |
| LqDirectorSalaryService | 原生SQL | WHERE u.F_IsEffective = 1 |
| LqStoreManagerSalaryService | 原生SQL | WHERE u.F_IsEffective = 1 |
领用作废后可用库存会加回去:作废使用记录后,该记录不再参与 totalUsage 统计,可用库存 = 总库存 - totalUsage 会自动增加。
三、数据库现状(MCP 查询结果)
- 有效使用记录总数:3240 条
- 存在重复数据:至少 5 组同一 UsageBatchId+ProductId+StoreId 有多条有效记录,需执行修复接口
示例重复组:
- 批次 770197935005631749,产品 763991211127080197,门店 1649328471923847172:2条,总数量6
- 批次 770807754649502981,产品 763992934394627333,门店 1649328471923847187:2条,总数量4
- …
四、测试清单
1. 修复接口测试 FixDuplicateUsageRecords
# 1) 获取 Token
TOKEN=$(curl -s -X POST "http://localhost:2011/api/oauth/Login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "account=admin&password=e10adc3949ba59abbe56e057f20f883e" | jq -r '.data.token')
# 2) 执行修复
curl -X POST "http://localhost:2011/api/Extend/LqInventoryUsage/FixDuplicateUsageRecords" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json"
验证:
- 返回
success: true,duplicateGroups、invalidatedCount合理 - 查库:同一 UsageBatchId+ProductId+StoreId 仅剩 1 条有效记录
- 查库:被合并的重复记录
F_IsEffective = 0
2. 修改申请防重复测试
- 新建申请,同一产品+门店添加两条(或修改时故意提交重复)
- 调用
UpdateApplicationUsageRecords提交 - 查库:该批次下同一产品+门店应只有 1 条有效记录,数量为合并值
3. 作废后不计入统计测试
- 记录某产品当前可用库存 A
- 新建申请并领用该产品若干数量,记领用后可用库存 B
- 作废该领用记录
- 再次查询可用库存,应恢复为 A(或接近 A,若存在其他领用)
4. 领用统计接口一致性测试
- 调用 GetStoreReceiveStatistics、GetStoreReceiveCostStatistics
- 与数据库直接 SUM 有效记录对比,结果一致
五、执行建议
- 部署后立即执行:
POST /api/Extend/LqInventoryUsage/FixDuplicateUsageRecords修复历史数据 - 接口测试:确保 API 已启动(localhost:2011),按上述 curl 执行
- 查库验证:按 mcp-mysql-and-sql-validation 规范,修复后必须查库核对
六、实际执行结果(2025-02-13)
1. 修复前数据库状态
- 有效使用记录:3240 条
- 无效使用记录:838 条
- 重复组:5 组(同一 UsageBatchId+ProductId+StoreId 有多条有效记录)
| 批次ID | 产品ID | 门店ID | 重复条数 | 总数量 |
|---|---|---|---|---|
| 784301392666821893 | 763979563993662725 | 1649328471923847179 | 2 | 20 |
| 787563597701055749 | 763987810846770437 | 1649328471923847176 | 2 | 270 |
| 770197935005631749 | 763991211127080197 | 1649328471923847172 | 2 | 6 |
| 784209727247615237 | 763991302353192197 | 1649328471923847188 | 2 | 10 |
| 770807754649502981 | 763992934394627333 | 1649328471923847187 | 2 | 4 |
2. 修复接口调用结果
{
"success": true,
"message": "修复完成,处理 5 组重复数据,作废 5 条记录",
"duplicateGroups": 5,
"invalidatedCount": 5
}
3. 修复后数据库验证
- 重复组:0 组 ✓(已清空)
- 有效记录:减少 5 条(每组保留 1 条,作废 1 条)
- 无效记录:843 条(原 838 + 新增 5)
- 合并验证:以批次 787563597701055749 为例,保留 1 条有效(F_UsageQuantity=270, F_TotalAmount=1196.10),另 1 条已作废(F_IsEffective=-1)✓
4. 幂等性验证
再次调用修复接口,返回:
{
"success": true,
"message": "未发现重复数据",
"duplicateGroups": 0,
"invalidatedCount": 0
}
✓ 幂等性正常,重复执行不会误伤数据。
5. 结论
- 修复接口工作正常
- 合并逻辑正确(数量、金额累加,保留 CreateTime 最早的一条)
- 作废记录 (F_IsEffective=-1) 不参与领用统计
- 无需后端代理修复,当前实现正确