diff --git a/changelogs/2026-05/12_fix_product_v2_schedule_child_zero_deposit_bypass.md b/changelogs/2026-05/12_fix_product_v2_schedule_child_zero_deposit_bypass.md new file mode 100644 index 0000000..fd820f3 --- /dev/null +++ b/changelogs/2026-05/12_fix_product_v2_schedule_child_zero_deposit_bypass.md @@ -0,0 +1,63 @@ +--- +date: 2026-05-12 +type: backend-fix +service: hl-product-service-v2 +priority: medium +notify: ["@mmg"] +status: verified +--- + +# 班期创建: 儿童价=0 时跳过订金校验 (与价格日历对齐) + +> **PR**: [#2117](https://git.1814.love:8443/wx/HL/pulls/2117) — 已合并 dev + 部署测试服 +> **Issue**: [#2116](https://git.1814.love:8443/wx/HL/issues/2116) +> **接口**: `POST /admin/product/item/{id}/schedule` (POST 新增 / PUT 修改, 同一 Service 方法) +> **状态**: ✅ **测试服已验证** — 3 case curl 真测 + +--- + +## 背景 + +价格日历 `validatePriceCalendarReq` 早已加 child=0 视为儿童免费 → 跳过订金校验的逻辑。**班期 `doSaveSchedule` 路径漏改**, 同一固定订金产品下: + +- 价格日历批量保存 child=0: ✓ 通过 +- 班期创建 child=0: ❌ 报 `儿童售价(0元)必须大于产品订金` + +两路径校验不一致, 用户感知为 BUG。 + +## 修复 + +`ProductPricingService.doSaveSchedule` 加 `> 0` 守卫: + +```java +if (req.getChildPrice() != null + && req.getChildPrice().compareTo(BigDecimal.ZERO) > 0 // ← 新增 + && req.getChildPrice().compareTo(fixedDeposit) <= 0) { + throw new BusinessException(PRICE_CHILD_BELOW_DEPOSIT, ...); +} +``` + +**成人价校验保持不变** (成人不允许免费 / 必须大于订金, 该规则与价格日历一致)。 + +## 测试服真测 (硬性凭证) + +产品 2053059685258309633 (DEPOSIT mode, deposit_amount=500) + +``` +Scenario 1: child=0 + adult=600 + → 200 OK, batchId=2054124392056590337 ✓ (修复前 410106) + +Scenario 2: child=300 + adult=600 (300 < 500 deposit) + → 410106 "儿童售价(300元)必须大于产品订金(500.00元/人)" ✓ (回归 child