5.7 KiB
5.7 KiB
mp 收藏 / 浏览足迹接口: 字段全回填 + 新增产品类型字段 + 修复浏览记录保存后查不出
服务: hl-mp-service (端口 8085) PR: #1338 Issue: 无关联工单(Gitea API 异常未能建单,已对齐口头确认) 日期: 2026-04-24 影响范围: 小程序 收藏列表 + 浏览足迹列表 + 浏览记录保存接口
⚠️ 关键变化
- 前一版
/mp/user/favorite和/mp/user/footprint的records中targetType=PRODUCT(或resourceType=PRODUCT)的行,name/coverUrl/tags全是null。本版修复后全部正确回填。 FavoriteItemVO和FootprintItemVO新增productType+productTypeLabel两字段(仅 PRODUCT 类型有值,其它类型null)。前端若展示收藏/足迹卡片带产品类型(核心/小蒙马/私人定制)角标,直接用productTypeLabel即可,不用自己查字典。- 保存足迹接口
POST /mp/user/footprint修复隐性失败:原实现下,用户"清空浏览记录"后再次访问同一资源时,接口返 200 但 DB 实际未保存记录,导致"保存成功却查不出来"。现在会正确复活已软删的记录。 footprintId/favoriteId在响应 JSON 中全栈改为 String 序列化(此前是 number,19 位雪花 ID 会被 JS 精度截断)。前端若以字符串接收,无感知;若以 number 运算需调整。
一、背景
MpProductFeignClient.getProductBrief Feign 路径历史写错,指向 /internal/product/batch-brief(班期摘要接口,返回 BatchBriefVO 只有 batchId/batchCode/departureDate 等班期字段),没有 name/coverUrl/tags。导致 mp BFF FavoriteAggregationService 拿到空 list → 字段全 null。资源类型(SCENIC/RESTAURANT/ACTIVITY)的三个 brief 端点无此问题。
浏览记录的问题则是 addFootprint 服务方法缺软删复活逻辑:清空浏览走 @TableLogic 把 deleted_at 置 NOW,下次访问时 getOne 自动加 WHERE deleted_at IS NULL 查不到 existing,进入 save 分支后撞上 DB 唯一索引(不含 deleted_at)冲突被静默吞。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 收藏列表 | GET | /mp/user/favorite |
响应字段补全 + 新增 | PRODUCT 行 name/coverUrl/tags 不再为 null;新增 productType + productTypeLabel |
| 2 | 浏览足迹列表 | GET | /mp/user/footprint |
响应字段补全 + 新增 | 同上 |
| 3 | 保存浏览记录 | POST | /mp/user/footprint |
行为修复 | 清空浏览后再次访问同资源不再静默失败 |
路径/方法/参数无变化。
三、字段变化详情
3.1 /mp/user/favorite 响应 records[*] 字段
| 字段 | 类型 | 之前 | 之后 | 备注 |
|---|---|---|---|---|
favoriteId |
String | String | String | 无变 |
targetType |
String | String | String | 无变,枚举 PRODUCT / SCENIC / RESTAURANT / ACTIVITY |
targetId |
String | String | String | 无变 |
name |
String | PRODUCT 时为 null |
全类型正确返回 | PRODUCT 取产品名称;其它类型取资源名称 |
coverUrl |
String | PRODUCT 时为 null |
全类型正确返回 | PRODUCT 取产品封面图;其它类型取资源封面图 |
tags |
List<String> | PRODUCT 时为 null |
全类型正确返回 | 仅存在标签时有值 |
productType |
String | 不存在 | 新增 | 仅 PRODUCT 有值,枚举 CORE / GROUP / CUSTOM(字典 product_type) |
productTypeLabel |
String | 不存在 | 新增 | 仅 PRODUCT 有值,中文,如 核心产品 / 小蒙马 / 私人定制 |
createdAt |
String | String | String | 无变 |
3.2 /mp/user/footprint 响应 records[*] 字段
同 /mp/user/favorite,除主键字段叫 footprintId、业务类型字段叫 resourceType/resourceId。
3.3 POST /mp/user/footprint 响应
响应结构未变(仍为 Result<void> 或 Result<Footprint>,视既有契约)。仅内部实现行为修复。
四、示例
4.1 修复前(已观察实际响应)
{
"code": 200,
"data": {
"records": [
{
"favoriteId": "2047265158492815361",
"targetType": "PRODUCT",
"targetId": "2044306857534636034",
"name": null,
"coverUrl": null,
"tags": null,
"createdAt": "2026-04-23 18:43:45"
}
],
"total": 1
}
}
4.2 修复后
{
"code": 200,
"data": {
"records": [
{
"favoriteId": "2047265158492815361",
"targetType": "PRODUCT",
"targetId": "2044306857534636034",
"name": "冻干粉发短信给",
"coverUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/xxx.jpg",
"tags": ["亲子", "研学", "露营"],
"productType": "GROUP",
"productTypeLabel": "小蒙马",
"createdAt": "2026-04-23 18:43:45"
}
],
"total": 1
}
}
五、前端建议
- 卡片 UI 如展示产品类型角标(核心/小蒙马/定制),直接用
productTypeLabel,不用前端再拉字典翻译。 productType/productTypeLabel在非 PRODUCT 类型(SCENIC/RESTAURANT/ACTIVITY)上是null,渲染需判空。- 原本用
name?.trim() || "加载中..."等兜底文案的地方可以简化;字段现在一定不为 null(除非产品已被删除,此时 brief 返空 → 仍为 null,需保留兜底)。 productTypeLabel来自字典product_type,字典 value→label 映射:CORE→核心产品、GROUP→小蒙马、CUSTOM→私人定制。若字典中文名称后续调整,后端会自动跟随,前端无需改动。