Files
medical-mall/pages/mall/delivery/doc/需求文档/物流消息推送方案_用户端与商家端.md
not-like-juvenile 9c96f4666f 消息推送
2026-02-11 10:37:49 +08:00

10 KiB
Raw Blame History

物流消息推送方案(用户端 + 商家端)

日期2026-02-11

0. 文档定位

本方案用于把“第三方快递轨迹platform_express_*”与移动端推送uni-push2结合

  • 用户端C 端):推送订单物流节点更新,并在消息中心可回溯、可标记已读。
  • 商家端B 端):推送与发货/履约强相关的物流节点更新(重点关注异常/签收等),并在商家消息中心可回溯。

约束与口径继承自本目录既有文档:

  • 统一事件模型、字段契约、状态映射:见接口与字段相关文档。
  • 敏感信息raw_payload、完整手机号/地址、POD 等)必须按角色授权,不得通过推送明文下发

1. 背景与目标

1.1 背景

配送模块的事实数据源是第三方轨迹事件流Webhook/轮询接收后入库到 platform_express_* 三表。

1.2 目标

  1. 及时性:当运单产生关键节点时,用户/商家能收到提醒。
  2. 一致性:推送只是“变更通知”,最终展示以平台查询接口返回的 status_history 为准。
  3. 可追溯:所有推送对应的“物流消息”可在消息中心列表查询,并可已读/未读统计。
  4. 合规与隐私:推送 payload 与通知文案不包含敏感信息,不透传 raw。

1.3 不在本方案范围

  • 自营骑手/同城配送任务(ml_delivery_*)的接单/导航/送达链路。
  • 厂商通道(小米/华为等)离线能力细节(可在 uni-push2 联调文档基础上扩展)。

2. 数据源与现有模型复用

2.1 事实数据表(生产口径)

  • platform_express_waybills运单摘要current_status_*、last_synced_at
  • platform_express_tracking_events轨迹事件事实表event_time/event_text/status_code 等)。
  • platform_express_event_raw:原始留痕与验签审计(仅运维/客服可见)。

结论:

  • 消息生成以 platform_express_tracking_events 的新增事件为触发
  • 通知展示以 platform_express_waybills.current_status_code/text + 最新事件摘要为基础

2.2 统一状态码(必须遵循)

使用平台统一 status_code ORDER_PLACED / SHIPPED / IN_TRANSIT / OUT_FOR_DELIVERY / READY_FOR_PICKUP / DELIVERED / EXCEPTION / RETURNED

映射规则来自“状态映射表”,平台内部应保证确定性。

3. 总体架构(事件驱动 + 推送唤醒刷新)

3.1 核心原则

  • Push ≠ 数据源Push 仅承载“发生了什么/在哪里看”,不承载完整时间线。
  • App 打开详情页时以接口/DB查询为准:避免推送丢失、乱序导致前端状态不一致。

3.2 推荐链路

  1. 第三方回调/轮询到达平台Webhook handler / polling job
  2. 平台:验签、防重放、幂等去重、乱序入库
  3. 平台:基于“新插入事件”计算是否需要生成物流消息(对 C/B 端分别判断)
  4. 平台:写入“物流消息表”(用于消息中心/未读)
  5. 平台:按收件人设备 CID 列表调用 uni-push2 发送通知/透传
  6. 客户端:收到推送 -> 更新消息中心未读角标/缓存 -> 用户点击进入订单/物流详情 -> 拉取最新时间线

4. 推送场景清单C 端 + B 端)

4.1 场景分级(建议最小可用)

为了避免 IN_TRANSIT 等高频节点造成骚扰MVP 建议:

  • 只对“状态级别变化”或“关键状态”推送,并允许后续配置化扩展。

4.2 用户端C 端)推送场景

对单个订单/运单,建议推送:

  • SHIPPED:商家已发货/已绑定运单
  • OUT_FOR_DELIVERY:派送中
  • READY_FOR_PICKUP:待取件
  • DELIVERED:已签收
  • EXCEPTION:异常(破损/拒收/地址不详等)
  • RETURNED:退回/退件

可选(非必须、后续再做):

  • IN_TRANSIT:仅在“跨天/关键节点”或“长时间无更新后恢复更新”时推送。

4.3 商家端B 端)推送场景

商家端更关注履约风险与闭环结果,建议推送:

  • SHIPPED:发货成功(用于确认运单绑定成功/进入履约)
  • DELIVERED:已签收(用于完成售后风险关闭)
  • EXCEPTION:异常(优先级最高)
  • RETURNED:退回/退件

可选(按业务需要):

  • OUT_FOR_DELIVERY:派送中(对高价值订单可能有意义)

4.4 同一事件对不同端的文案差异

  • 同一事件事实字段同源event_time/event_text/status_code
  • C 端文案可更贴近用户体验(避免网点内部信息、避免电话明文)。
  • B 端文案以进度/风险为主(异常/退回明确提示)。

5. 消息生成规则(幂等 + 去噪)

5.1 生成触发点

在平台完成 platform_express_tracking_events 插入成功后触发(建议异步队列/任务)。

5.2 幂等与去重

事件表已有 (waybill_id, dedupe_key) 唯一约束;消息层建议再做一层幂等:

  • 推荐幂等键:recipient_scope + recipient_id + waybill_id + status_code + event_time
  • 若第三方提供 event_id,可用:recipient_scope + recipient_id + waybill_id + event_id

保证:同一条事件重试/重复推送不会造成消息中心重复。

5.3 去噪MVP

  • 默认仅对 4.2/4.3 列出的状态集合生成消息。
  • 同状态多事件:只推“最新 event_time”对应的一条或按节点去重

6. Push payload 规范(建议)

6.1 设计目标

  • 足够定位:能让客户端知道要刷新哪个订单/运单、点击去哪里。
  • 不泄露敏感:不含手机号/地址/raw_payload。
  • 可审计:含平台侧 message_id / request_id。

6.2 字段建议(透传/通知通用)

{
  "biz": "express",
  "aud": "user", 
  "message_id": "msg_xxx",
  "order_no": "ORD_2026...",
  "carrier": "YTO",
  "tracking_no": "YT123...",
  "status_code": "OUT_FOR_DELIVERY",
  "event_time": "2026-02-05T14:32:00+08:00",
  "event_text": "快件正在派送中",
  "deeplink": {
    "path": "/pages/order/detail",
    "query": {"order_no":"ORD_2026...", "tab":"logistics"}
  }
}

说明:

  • event_text 推荐使用“清洗后的文案”(避免把第三方原文中的手机号明文透传)。
  • aud:区分用户端/商家端,有利于同一 App 多角色或同一推送通道多消费方。

6.3 通知栏标题/摘要建议(示例)

  • 用户端:
    • 标题:物流更新 / 订单物流更新
    • 内容:【派送中】快件正在派送中
  • 商家端:
    • 标题:订单履约提醒
    • 内容:【异常】包裹地址不详正在退回(异常优先级最高)

7. 消息中心与未读(服务端为准)

7.1 为什么需要消息中心

  • Push 可能丢失/被系统拦截;消息中心提供可回溯记录。
  • 多设备登录需要统一未读。

7.2 建议的数据模型(平台侧新增)

建议新增两类表(命名仅示例):

  1. 设备注册表 push_devices
  • id
  • user_id / merchant_id(二选一或用统一 subject
  • cid
  • platformandroid/ios/web
  • appid(用于区分环境)
  • last_seen_atis_active
  1. 物流消息表 express_notifications
  • idmessage_id
  • auduser/merchant
  • recipient_id
  • order_id/order_nowaybill_idtracking_nocarrier
  • status_codeevent_timeevent_text_safe
  • read_at(或拆到 read 表做多端多设备)
  • created_at
  • 幂等键unique

7.3 API建议

  • 设备注册:POST /api/v1/push/register(登录后上报 CID绑定到账号
  • 设备解绑:POST /api/v1/push/unregister
  • 消息列表:GET /api/v1/notifications?biz=express&aud=user|merchant&page=...
  • 标记已读:POST /api/v1/notifications/read(按 message_id 或按订单批量)
  • 未读数:GET /api/v1/notifications/unread-count?biz=express&aud=...

8.1 跳转原则

  • 点击通知后进入“订单详情-物流区块”或“物流详情页”。
  • 页面打开后必须调用平台查询接口刷新 status_history

8.2 跳转目标建议

  • 用户端:订单详情页(展示物流时间线)
  • 商家端:订单详情页(展示物流时间线 + 发货信息)
  • 平台后台:不通过 App push 跳转(后台有自己的排障页)

9. 安全、权限与隐私

9.1 收件人权限校验

  • 用户端:仅能收到/查看自己订单的物流消息。
  • 商家端:仅能收到/查看自己店铺订单的物流消息。

服务端生成消息时必须校验:order_no -> 订单归属 -> recipient

9.2 敏感字段控制(强约束)

  • 禁止通过 push payload/通知文案下发完整手机号、完整地址、raw_payload、签名/密钥。
  • raw_payload 仅允许客服/运维在后台折叠查看,并记录审计。

9.3 CID 绑定安全

  • CID 必须在登录态下上报并绑定到账号。
  • 更换设备/卸载重装CID 可能变化,需更新绑定。
  • 退出登录时建议解绑或标记设备 inactive。

10. 失败与补偿

  • 推送失败CID 失效/不属于应用):标记设备 inactive 并等待下次登录刷新。
  • Webhook 入库成功但推送失败:不影响事实数据;消息中心仍可查询到记录(若已写入消息表)。
  • 客户端未收到 push用户进入订单详情时仍能通过查询接口看到最新轨迹。

11. 验收清单(与联调口径一致)

  1. 插入一条轨迹事件(模拟 webhook
  • waybill current_status_code/text 更新
  • events 表新增且幂等
  • 消息中心新增 1 条(不重复)
  • 目标端(用户/商家)收到推送
  1. 乱序/重复推送:
  • 事件表不重复、消息中心不重复
  • 当前状态不回退(按平台选定算法)
  1. 隐私校验:
  • push 文案与 payload 无手机号明文/无 raw
  1. 点击跳转:
  • 落到订单/物流详情页并刷新出最新时间线

12. 与本目录文档的对应关系(索引)

  • 统一模型与 Webhook 约束:接口规范
  • 状态映射:状态映射表
  • 展示字段与隐私规则:前端字段清单
  • 生产表结构与幂等/乱序生产表说明_platform_express
  • 移动端 push 联调与 CID 归属uni-push2 安卓联调与取 CID 说明