# 第一期 BUG 批量修复（4-20 部署）

**日期**：2026-04-20
**PR**：#956、#957、#958、#959、#960 + gateway #966、ddl hotfix #965/#967

本批次共修复 9 个后端 BUG 并部署测试环境，同时列出 6 个纯前端 BUG 需前端同学跟进。

---

## ✅ 后端已修（前端大多无需改动）

### BUG 11 — 价格日历报 "month: 月份格式错误"（前端无感）
`@Pattern` 正则从 `\d{4}-\d{2}` 放宽为 `\d{4}-(0?[1-9]|1[0-2])`，后端 `YearMonth.parse(month, "yyyy-M")` 容错。
**前端**：传 `month=2026-5` 或 `2026-05` 都可，**自动兼容**。

### BUG 16 — "数据操作违反约束"不给字段信息
`GlobalExceptionHandler` 对 `DataIntegrityViolationException` 5 种模式关键字匹配：
- `Column 'xxx' cannot be null` → `字段 【xxx】 不能为空`
- `Data too long for column 'xxx'` → `字段 【xxx】 长度超限`
- `Duplicate entry ... for key 'xxx'` → `数据重复，索引: xxx`
- `Unknown column 'xxx'` → `数据库字段 【xxx】 不存在（schema drift）`
- 外键失败 → `外键约束失败：关联数据不存在`

**前端**：错误 message 字段更友好，可直接透传给用户。

### BUG 17 — 小蒙马上架报 "至少需要1个未来有效价格"
`ProductValidationService.validatePublish` 按 `productType` 分流：
- CORE/CUSTOM → 走 `product_price_calendar` 校验（原逻辑）
- GROUP → 走 `group_tour_batch.adult_price` 校验（匹配"班期表价格"语义）

**前端**：无改动。小蒙马产品上架流程可正常走通。

### BUG 3 — 小蒙马小程序详情 startPrice=null 导致预订按钮灰
`MpProductDetailAssembler` 同步分流。GROUP 产品走 `groupTourBatchService.findMinAdultPriceFuture`。

**前端**：无改动。小蒙马产品详情 `startPrice` 现在会正确返回班期最低成人价。

### BUG 7 — 里程自动计算偏短
根因：
1. 白名单只认 SCENIC/ACTIVITY/HOTEL，自定义节点被静默过滤
2. 集合地/解散地坐标从未参与

修复：
- `AmapDrivingService.COORD_NODE_TYPES` 重构：新增 `BYO_COORD_NODE_TYPES={CUSTOM,NOTE,TRANSPORT,PHOTOGRAPHY,FREE}`，自带 lng/lat 才参与
- `ItineraryAutoCalculator.autoCalculateDailyMileage` 入参加 `List<DayItem>`，按 dayNumber 抽 gather/dismissal 透传

**前端**：`DailyMileageCalcReqVO` 新增可选字段：
- `NodeRef.lng/lat`（BigDecimal 可空，BYO 节点带坐标才参与计算）
- `DayNodes.gatherPlace/dismissalPlace`（Object 可空，同高德行政区 JSON `{name,adcode,center,level}`）

**前端 TODO**：行程编排页保存"计算里程"接口时，把每天的 `gatherPlace`/`dismissalPlace` 和各节点的 `lng/lat` 一并传，里程会更准确。不传也向下兼容。

### BUG 9 — 添加/编辑景区保存报 500
schema drift：Entity 有 `photographyGuide` 字段，DB 无 `photography_guide` 列。
修复：DDL 加列（独立迁移脚本 `sql/alter_scenic_spot_add_photography_guide.sql`，测试环境已执行）。

**前端**：无改动。景区创建/编辑接口正常。

### BUG 13 — 定制师看不见自己建的主题
`ProductLineService.saveLine` 创建分支加 `setCreatedBy` 兜底：若请求头缺 `X-Admin-Id` → 抛 `BusinessException("未识别到管理员身份")`，避免 `createdBy` 落 NULL。

**前端**：管理端创建产品线时**务必确保** HTTP 请求头带 `X-Admin-Id`（或 `Authorization: Bearer <token>` 让后端从中提取）。

### BUG 14 — 新建产品版本后小程序端看不到（缓存）
`ProductHelperService.registerAfterCommitInternal` 的 afterCommit 回调改调 `evictAllMpCache`，除产品详情缓存外，额外清：
- `mp:product-line:detail:*`（产品线详情）
- `mp:products-by-line:*`（产品线下产品列表）

**前端**：无改动。新建/上架/下架产品后小程序端立即可见，不再需要等 10 分钟缓存过期。

### BUG 18 — 产品线封面改了小程序端不更新
`ProductLineService.saveLine/deleteLine` 加 afterCommit 清缓存（同 BUG 14 的 evictAllMpCache 无参版）。

**前端**：无改动。产品线封面/描述改动立即在小程序端可见。

---

## 🔵 需前端跟进的 BUG

### BUG 1 — 主题页产品名错（前端取字段错误）
现状：主题页显示"6 天 5 晚 · 亲子游"，应为后台配置的 `name="带孩子，看一次真正的草原。"`。

**后端确认**：`MpProductService:387-399` 的 `name` 字段取自 `product.name`，值正确。**前端取错了字段**（可能把 `subtitle` 或拼接字符串当标题）。

**前端 TODO**：确认主题页产品标题读的是 `product.name` 而非 `subtitle` 或其他拼接逻辑。

### BUG 2 — 产品详情页第一屏没有标签
后端 `MpProductDetailRespVO.tags` 字段存在，DB 实际数据都有（如 `["亲子", "研学", "摄影"]`）。测试环境已查明：DB 数据完整，后端正确返回。**前端未渲染**。

**前端 TODO**：检查产品详情首屏的 tags 渲染逻辑。

### BUG 5 — 用户端第二页面卡片缺 icon
`BrandCard` DTO 只有 `title/subtitle/coverUrl`，**无 `iconUrl` 字段**。

**前端 TODO + 确认**：前端是否**必需**独立的 icon 字段（而非复用 coverUrl 缩略图）？
- 如确需：后端需改 common-core DTO（影响全服务重部署，成本高），请明确反馈
- 如可不加：复用 coverUrl 即可

### BUG 6 — 发布产品弹窗仍报"未配置实际用车车型"
测试 jar 反编译已验证 PR #932 的新文案已生效。**浏览器缓存问题**。

**前端 TODO / 用户**：Ctrl+Shift+R 硬刷后重试。

### BUG 8 — 资源库添加酒店区域分类无法使用
后端 `HotelQueryRequest` 无 `district` 筛选字段，无"按 city 列 district"字典接口。

**前端 TODO**：在 F12 Network 看这个下拉实际调的是哪个接口（带什么参数），反馈后再判断是否需要后端补接口。

### BUG 12 — 每日集合地/解散地不用必填
后端 `ProductItinerarySaveReqVO.DayItem.gatherPlace/dismissalPlace` 是 `Object` 且无任何校验注解，**后端不强制必填**。前端 `*` 号只是 UI 装饰。

**前端 TODO**：去掉这两个字段 UI 上的 `*` 号。副作用：空集合地时后端不生成首尾路线点和线路概览（已 null-safe 不报错）。

### BUG 19 — 产品选定金比例后小程序没返回定金金额
后端 `product_basic` 表有 `deposit_ratio` 和 `deposit_amount` 列，`MpProductDetailRespVO.depositRatio`/`depositAmount` 字段存在，`MpProductService.calculateQuote` 完整计算定金。**测试环境验证后端字段完整**。

**前端 TODO**：小程序端检查是否正确解析/展示 `depositRatio` 和 `depositAmount` 两个字段。

---

## DDL 执行清单（生产部署前运维参考）

| 脚本 | 库 | 必要性 |
|---|---|---|
| `sql/alter_scenic_spot_add_photography_guide.sql` | hl_resource_service | BUG 9 必须 |
| `sql/alter_product_route_info_add_map_mode.sql` | hl_product_service | BUG 10 必须 |
| `sql/alter_product_supplies_add_from_combo_id.sql` | hl_product_service | BUG 15 可选（审计用） |
| `sql/supplies_schema.sql`（新增 supplies_combo+item 两张表） | hl_resource_service | BUG 15 必须 |
| `hl-order-service-v2/sql/migrations/20260420_bug20_early_bird_multi_plan.sql` | hl_order_service_v2 | BUG 20 必须 |

**部署顺序**：先 DDL → 再重启相关服务。
