fix: 产品 V2 编辑两项修复(里程被覆盖 + 儿童售价=0)
PR #2067 (commit d30bd995): - #2064 行程编排日里程手动改后保存被高德自动计算覆盖 - #2066 价格日历批量设置允许儿童售价等于 0(儿童免费) 测试服 admin token round-trip 4 case 全过(2026-05-12 10:14-10:15)。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
这个提交包含在:
父节点
0745ea7a85
当前提交
3fccc2381b
@ -0,0 +1,100 @@
|
||||
# 后端 fix 通知 — 产品 V2 编辑两项修复(里程被覆盖 + 儿童售价=0)
|
||||
|
||||
**日期**: 2026-05-12
|
||||
**类型**: 后端修复 (PR #2067, merge commit `d30bd995`)
|
||||
**模块**: 产品 V2 编辑 → 行程编排 / 价格日历批量
|
||||
**通知**: @mmg
|
||||
**前端是否需改动**: **可选**(后端兼容现有前端行为, 修复后即生效; 若要支持"取消手动锁回到自动计算"则需小调整, 见下)
|
||||
**严重性**: P1(行程里程) + P2(儿童售价=0)
|
||||
|
||||
---
|
||||
|
||||
## 修复 1: 行程编排「当日里程」手动改后保存被高德覆盖 (Closes #2064)
|
||||
|
||||
### 现象
|
||||
产品 V2 编辑页 → 第 2 步「行程编排」→ DAY N → 修改「里程」输入框为某个值(如 180 km)→ 保存 → 刷新页面 → 里程又变回了高德自动计算的数字。
|
||||
|
||||
### 根因
|
||||
后端有 `mileageManualOverride` 开关字段标记是否人工覆盖。前端编辑 `dailyMileage` 时只传数值未带 override=true, 后端 MP `updateById` NOT_NULL 策略跳过 null 字段, DB 中 override 保持 0, 事务提交后 `ItineraryAutoCalculator` 调高德 API 重新覆盖用户输入。
|
||||
|
||||
### 修复
|
||||
后端 `ProductItineraryService.convertDay` 兜底: 当前端传了 `dailyMileage` 但未显式传 `mileageManualOverride` 时, 自动视为手动覆盖(置为 TRUE), 阻断 autocalc 覆盖。
|
||||
|
||||
### 前端 mmg 完全无需改动
|
||||
前端继续按当前逻辑只提交 `dailyMileage` 即可, 后端兜底已覆盖。
|
||||
|
||||
### 如果要支持「重置回自动计算」(可选, 不是必做)
|
||||
若想加一个"刷新/重置"按钮让用户撤销手动锁、回到高德自动值, 需:
|
||||
1. 该天 SaveReqVO 显式传 `dailyMileage: null` **且** `mileageManualOverride: false`
|
||||
2. 保存后等 1-2 秒, 后端 autocalc 会重算并填入
|
||||
|
||||
截图里看到里程字段旁有圆形刷新图标和 × 按钮, 如果这两个图标已绑此语义, 检查一下提交时是否真的清空 dailyMileage + 显式 override=false。
|
||||
|
||||
---
|
||||
|
||||
## 修复 2: 价格日历批量设置允许儿童售价 = 0 (Closes #2066)
|
||||
|
||||
### 现象
|
||||
价格日历批量设置中, 儿童售价填 `0` 报「儿童售价必须大于0」无法保存。业务上 `0` 表示儿童免费应允许。
|
||||
|
||||
### 修复
|
||||
后端 4 处放宽:
|
||||
1. `PriceCalendarBatchReqVO.childSellPrice` `@DecimalMin` 0.01 → 0.00, 文案改"儿童售价不能为负数"
|
||||
2. `ProductPricingService` 第一道校验拆分: null → 原 REQUIRED 错误码; <0 → 新错误码 `PRICE_CHILD_SELL_PRICE_NEGATIVE` (410112)
|
||||
3. `ProductPricingService` 固定订金模式: `childSellPrice=0` 时跳过"必须>订金"校验
|
||||
4. `ProductBasicService` 反向校验对称处理: 调订金时若现存价格日历/班期 `childPrice=0` 视为免费跳过, 避免"正向能设 0、反向改订金又被卡"
|
||||
|
||||
成人售价校验维持 `>0` 不变, 不允许成人售价 0。
|
||||
|
||||
### 前端 mmg 行为变化
|
||||
- 儿童售价输入框: 现在允许填 `0`(免费)
|
||||
- 儿童售价 = 负数: 仍报错, 文案变成「儿童售价不能为负数」(原"必须大于0")
|
||||
- 成人售价: 维持 `>0`, 不可填 0
|
||||
|
||||
如果前端有"儿童售价 ≥ 0.01"的本地校验, **请放宽到 ≥ 0**(允许 0.00, 不允许负数)。
|
||||
|
||||
---
|
||||
|
||||
## ✅ 测试服真测(2026-05-12 10:04 部署, 10:14-10:15 真测)
|
||||
|
||||
测试服 admin token (test_admin) 经网关 `api.test.1814.love:9443` 真测, 用产品 `2053662735618506754`:
|
||||
|
||||
### Case 1: BUG #2064 修复验证
|
||||
|
||||
| 步骤 | 操作 | 结果 |
|
||||
|------|------|------|
|
||||
| baseline | DAY 2 (dayId=2053662735677227011) `daily_mileage=140.0` `override=1` | — |
|
||||
| 改动 | PUT `/admin/product/item/{id}/itinerary` DAY 2 `dailyMileage=888.0`, **不传 override** | HTTP 200, code=200, msg="行程保存成功" |
|
||||
| 等 8s | autocalc 在 10:14:11 跑完 `自动计算每日里程完成, 天数=7` | — |
|
||||
| 验证 | SQL `daily_mileage=888.0` `mileage_manual_override=1` | ✅ 888 未被高德覆盖 |
|
||||
|
||||
### Case 2: BUG #2066 修复验证
|
||||
|
||||
| 步骤 | 操作 | 结果 |
|
||||
|------|------|------|
|
||||
| 改动 | POST `/admin/product/item/{id}/price-calendar/batch`, `childSellPrice=0, adultSellPrice=1999, date=2026-12-15, tier=1, NORMAL` | HTTP 200, code=200, msg="价格日历设置成功" |
|
||||
| 验证 | SQL `child_sell_price=0.00, adult_sell_price=1999.00, price_type=NORMAL` | ✅ child=0 落库 |
|
||||
|
||||
### Case 3: 边界 — 儿童售价 = -1 仍拦
|
||||
|
||||
- POST 同上 `childSellPrice=-1` → HTTP 200, **code=400** msg="**儿童售价不能为负数**" success=false ✅
|
||||
|
||||
### Case 4: 旁证 — autocalc 在 override=false 时正常生效
|
||||
|
||||
- DAY 3 显式传 `mileageManualOverride=false` 且不传 `dailyMileage` → 8s 后 SQL `daily_mileage=0.0 override=0`, 日志 10:15:36 `自动计算每日里程完成` — autocalc 正常生效(该天集散坐标相同高德返 0km, 是预期结果)
|
||||
|
||||
---
|
||||
|
||||
## 影响面 / 兼容性
|
||||
|
||||
- 接口签名零变化 — 任何前端代码不改也能直接用
|
||||
- 已部署: 测试服 product-v2 双实例(8083 + 8183) 已是含修复的版本
|
||||
- 历史已被高德覆盖的天: 下次用户手动改并保存即可锁住, 无需脏数据修复
|
||||
- 已有 `mileage_manual_override=1` 的天不受影响
|
||||
- 历史已有 `childSellPrice` 数据不受影响, 仅前向允许 0 入库
|
||||
|
||||
## 关联
|
||||
|
||||
- PR: https://git.1814.love:8443/wx/HL/pulls/2067
|
||||
- Issue #2064: https://git.1814.love:8443/wx/HL/issues/2064
|
||||
- Issue #2066: https://git.1814.love:8443/wx/HL/issues/2066
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户