hl-api-changelog/changelogs/2026-05/21_fix_mp_message_summary_field_misalign.md

4.8 KiB

GET /mp/message/summary 字段错位修复 — 消息中心 4 个分类入口恢复正常显示

仓库: HL (后端 hl-mp-service) 关联 PR/Issue: PR #2817, Closes #2813 日期: 2026-05-21 影响范围: 小程序「消息」tab(消息中心首页 4 个分类入口) 接收方: mmg (小程序前端) 前端: 无需改动(本来契约就是 code/name/icon/description/unreadCount/latestTitle/latestTime,只是后端 BFF 之前没返对) 测试服 round-trip: 通过(已用真 mp 用户 token 在 https://api.test.1814.love:9443/mp/message/summary 实测,7 字段全部就位)


一、修了什么

PR #2479 (refactor(mp): BFF Map<String,Object> 透传清理, 2026-05-18 合并) 把 MpMessageControllerMap<String,Object> 改成强类型 VO,但 BFF 端 MpMessageSummaryVO / MpMessageVO 字段命名与 user 服务实际返回的 CategorySummaryVO / UserMessageVO 完全错位,Feign 反序列化拿不到值,小程序消息 tab 出现:

  • 4 个分类入口全部显示默认喇叭图标(因 icon=null 走前端 fallback)
  • 4 个分类入口标题为空(因 name 字段不存在)
  • 只有 latestTitle 这个字段名巧合一致的内容能显示
  • 点击分类跳转 detail 时弹「缺少消息类型」(router 校验 type 必填,而 code=null)

本次修复让 BFF VO 字段严格对齐 user 端,Feign 反序列化恢复正常。


二、字段对照(供前端核对)

GET /mp/message/summary 返回的每个分类对象

字段名 类型 改前(BUG) 改后(本次修复)
code String category (错位 → null) code (例 "ORDER")
name String 字段不存在 → null name (例 "订单消息")
icon String 字段不存在 → null icon (例 "order")
description String 字段不存在 → null description (例 "订单状态变更通知")
unreadCount int Integer 包装类型 int(无包装,默认 0)
latestTitle String OK 无变化
latestTime Long String 类型错 Long 时间戳毫秒

GET /mp/message/list 返回的每条消息对象(本次顺手对齐,前端目前未调用)

字段名 类型 改前 改后
id String Long (JS Long 精度风险) String
title String OK 无变化
content String OK 无变化
link String 字段不存在 新增(跳转链接)
createTime Long createdAt: LocalDateTime createTime 时间戳毫秒
isRead Boolean OK 无变化
bizId String Long (JS Long 精度风险) String
bizType String OK 无变化
categoryCode String category 字段名错 categoryCode
eventCode String 字段不存在 新增(事件编码)

三、测试服真测结果

curl -sk "https://api.test.1814.love:9443/mp/message/summary" -H "Authorization: Bearer <mp用户token>"

返回:

[
  {"code":"SYSTEM","name":"系统消息","icon":"system","description":"系统公告与通知","unreadCount":0,"latestTitle":null,"latestTime":null},
  {"code":"ORDER","name":"订单消息","icon":"order","description":"订单状态变更通知","unreadCount":0,"latestTitle":"定金支付成功","latestTime":1778298480000},
  {"code":"TRIP","name":"行程消息","icon":"trip","description":"出发提醒与行程动态","unreadCount":0,"latestTitle":"行程已开始","latestTime":1778295333000},
  {"code":"PROMO","name":"优惠促销","icon":"promo","description":"优惠活动与促销信息","unreadCount":0,"latestTitle":null,"latestTime":null}
]

4 个分类的 7 个字段全部就位,符合 hl-mini/api/index.js:1118 注释里写的契约。


四、单元测试覆盖

新增 3 个测试类(本次工单):

  • MpMessageSummaryVOFieldsTest — 反射验字段集合/类型(latestTime=Long/unreadCount=int)
  • MpMessageVOFieldsTest — 反射验字段集合/类型(id/bizId=String/createTime=Long)
  • MpMessageVoDeserializationContractTestJackson ObjectMapper 模拟 Feign 真实路径,user JSON → mp VO 反序列化,7 + 10 字段全部断言 + 字段错位回归保护

加上重写的 MpMessageControllerTest,本次目标 4 个测试类 15/15 全绿。后续如果 BFF VO 字段被人改回错位,会被这 3 个契约测试立刻拦下。


五、不需要前端配合

  • 无接口字段变更(前端 _renderFromStore 期望的字段名一直是这 7 个,本次只是让后端真正返出来)
  • 无新增接口
  • 无网关路由变更
  • 无 Flyway V*.sql 数据库迁移
  • 无业务逻辑变更

mmg 不需要发版。等测试服部署稳定后,小程序刷新消息 tab 就能看到 4 个分类入口正常显示(标题/图标/描述/未读数/最新预览/时间)。