diff --git a/changelogs/2026-05/16_fix_mp_product_detail_supplies_cover_url.md b/changelogs/2026-05/16_fix_mp_product_detail_supplies_cover_url.md new file mode 100644 index 0000000..24171a1 --- /dev/null +++ b/changelogs/2026-05/16_fix_mp_product_detail_supplies_cover_url.md @@ -0,0 +1,94 @@ +# 小程序产品详情备品图片不显示修复 + +> **服务**: hl-product-service-v2 (端口 8083) + hl-resource-service (端口 8082) +> **PR**: #2421 +> **Issue**: #2420 +> **日期**: 2026-05-16 +> **影响范围**: 小程序产品详情「出行备品」section 的封面图 + +--- + +## ⚠️ 关键变化 + +之前小程序产品详情「出行备品」**所有备品图片都不显示**(灰色占位)。本 PR 后: +- 正式存量 85 条 `product_supplies.cover_url` 已立即手动回填(用户无需等部署),刷新小程序即可看到图 +- 编辑产品 Step3 备品保存后,新增/修改的备品会自动写入封面快照 + +--- + +## 一、根因 + +`ProductRouteService.saveRoute` Step3 备品保存逻辑历来未走 Feign 回填封面快照: +- `SuppliesItem` 请求 VO 不含 coverUrl 字段(前端不应该传) +- `BeanUtil.toBean(SuppliesItem, ProductSuppliesDO.class)` 拷贝出来 `coverUrl` 必然 null +- 哪怕走 `ProductSuppliesComboExpander` 组合展开路径,也会被中间的 DO→VO→DO 反复拷贝丢字段 + +结果: 正式 `product_supplies.cover_url` 全表 85/85 全 NULL。C 端 `SuppliesVO.coverUrl` 直接来自该列,前端必然渲染空图。 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 批量获取备品封面图 | GET | `/internal/supplies/covers/batch` | 新增内部接口 | 资源服务暴露,产品服务 Feign 调用 | +| 2 | Step3 路线与备品保存 | POST | `/admin/product-v2/{id}/route` | 行为修复 | 保存后自动回填 cover_url,前端 payload 不变 | +| 3 | C 端产品详情 | GET | `/mp/product/{id}/detail` | 行为修复 | `supplies[].coverUrl` 不再为 null | + +前端接口契约**完全不变**,前端无需修改任何代码。 + +--- + +## 三、数据库变更 + +```sql +-- V20260516_002__backfill_supplies_cover_url.sql +-- 跨库 JOIN, hl_app 账号对两个库都有权限 +UPDATE product_supplies ps +JOIN hl_resource_service.supplies_item si ON si.supplies_id = ps.supplies_resource_id +JOIN hl_resource_service.material m ON m.material_id = si.cover_material_id +SET ps.cover_url = m.oss_url +WHERE ps.cover_url IS NULL + AND ps.supplies_resource_id IS NOT NULL + AND m.oss_url IS NOT NULL + AND m.oss_url <> ''; +``` + +- 正式 RDS 已于 2026-05-16 13:41 手动跑过相同 SQL, affected=85,补全后 null_or_empty=0 +- 测试服: 下次部署跑 Flyway 自动生效(幂等 WHERE IS NULL) + +--- + +## 四、边界行为 + +- **自定义备品(suppliesResourceId=NULL)**: 不会调 Feign,coverUrl 保持 NULL(本来就没有资源库材料可拷) +- **资源服务不可用**: Feign Fallback 降级返空列表,本次保存 cover_url 保持 NULL,**不阻断产品保存**,下次保存重试。区别于 ComboExpander 失败必须阻断保存。 +- **资源库材料已软删 / 无封面材料**: 服务端 `batchGetCoverUrls` 自动过滤,消费方按 ID 取不到即视为无封面,DO.coverUrl 保持 null。 + +--- + +## 五、不影响范围 + +- **仅影响**: 管理端 Step3 备品保存 + 小程序产品详情 supplies[].coverUrl +- **零影响**: + - 其它管理端步骤(step1/2/4/5) + - 订单 / 商家 / 用户服务 + - 备品组合 (`supplies_combo`) 自身的 cover_url(走 ComboFeignClient,不变) + - `product_supplies` 表其它列(supplies_name / category / billing_type 等) + - 自定义备品(无资源库 ID 那种) + +--- + +## 六、测试环境已验证 + +- [x] hl-resource-service / hl-product-service-v2 mvn compile SUCCESS +- [x] 正式 RDS DESC product_supplies + 抽查 22 条 cover_url 全 OSS URL +- [x] 复现产品 `2055092537149804545` 备品 22 条 (车上拖鞋成人/儿童/指甲刀/晕车贴等) cover_url 全部 OSS URL +- [ ] 测试服部署后小程序详情备品图片可见 (待 mmg 部署后回归) + +--- + +## 七、相关文档 + +- 关联 Issue: [wx/HL#2420](https://git.1814.love:8443/wx/HL/issues/2420) +- 关联 PR: [wx/HL#2421](https://git.1814.love:8443/wx/HL/pulls/2421)