修改过时文档,优化文档内容

This commit is contained in:
not-like-juvenile
2026-03-17 11:06:26 +08:00
parent dac730474b
commit f33efe6ec8
45 changed files with 162 additions and 236 deletions

View File

@@ -0,0 +1,234 @@
# 物流消息推送方案(用户端 + 商家端)
日期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 字段建议(透传/通知通用)
```json
{
"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`
- `platform`android/ios/web
- `appid`(用于区分环境)
- `last_seen_at``is_active`
2) 物流消息表 `express_notifications`
- `id`message_id
- `aud`user/merchant
- `recipient_id`
- `order_id/order_no``waybill_id``tracking_no``carrier`
- `status_code``event_time``event_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. 点击跳转deeplink
### 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 条(不重复)
- 目标端(用户/商家)收到推送
2) 乱序/重复推送:
- 事件表不重复、消息中心不重复
- 当前状态不回退(按平台选定算法)
3) 隐私校验:
- push 文案与 payload 无手机号明文/无 raw
4) 点击跳转:
- 落到订单/物流详情页并刷新出最新时间线
---
## 12. 与本目录文档的对应关系(索引)
- 统一模型与 Webhook 约束:接口规范
- 状态映射:状态映射表
- 展示字段与隐私规则:前端字段清单
- 生产表结构与幂等/乱序生产表说明_platform_express
- 移动端 push 联调与 CID 归属uni-push2 安卓联调与取 CID 说明