# 配送模块文档目录(Mock 三通一达后台联调) 本目录聚焦“模拟三通一达后台(Mock 承运方 Server)”的联调与测试需求,用于在未签约真实承运方前验证平台侧的 Webhook 接收、验签、幂等、入库与前端时间线展示。 ## 文档分层(先看什么、后看什么) - 需求(做什么):[配送模块需求文档.md](配送模块需求文档.md) - 页面(后台长什么样):[后台页面设计说明.md](后台页面设计说明.md) - 接口(怎么对接):[接口规范.md](接口规范.md) - 映射(状态怎么统一):[状态映射表.md](状态映射表.md) - 前端契约(怎么展示):[前端字段清单.md](前端字段清单.md) - 补齐清单(还缺什么):[缺口与待补充清单.md](缺口与待补充清单.md) - 数据库(旧表 vs 新表):[数据库对比与修改建议.md](数据库对比与修改建议.md) - 数据库(生产表字段说明):[生产表说明_platform_express.md](生产表说明_platform_express.md) - 移动端推送联调(uni-push2):[uni-push2_安卓联调与取CID说明.md](uni-push2_安卓联调与取CID说明.md) ## 先读这个:这套文档在解决什么 你现在要做的是一个“像三通一达一样会产生物流节点并回调的平台外部系统”。真实承运方接口通常需要签约与联调周期,因此先通过 Mock 承运方 Server 把平台侧能力跑通: - 事件接收:平台接收并处理 Webhook 回调 - 安全与可靠性:验签、防重放、幂等去重、乱序/重复/延迟处理 - 数据闭环:事件入库 -> 前端按时间线展示(类似京东/淘宝订单物流关键节点) 说明:本目录文档服务于“平台系统的一部分”(订单详情页的物流区块、客服/履约排障与对接联调)。 - 平台端通常需要在订单详情中查看与履约相关的信息(订单号、运单号、承运方、物流时间线、异常记录等)。 - 本目录不展开订单商品/支付/营销等业务字段,仅覆盖“订单详情里的物流子模块”与其对接/入库/展示规范。 ## 核心思想(设计原则) - 以“事件流”为中心:物流展示本质就是一组按时间发生的事件(揽收/中转/在途/派送/签收/异常)。 - Webhook + 控制面分层:Webhook 用来模拟“承运方回调”,控制面 API 用来“造数据/控节奏/注入故障”。 - 统一状态码 + 原文并存:平台用 `status_code` 做标签/统计/告警;用 `event_text` 展示承运方原文,并保留 `raw_payload` 便于客服核查。 - 故障注入必须:重复推送、乱序、延迟、签名错误、缺字段等是外部对接最常见问题,必须在联调阶段覆盖。 ## 阅读顺序(推荐) 1) 先看 [配送模块需求文档.md](配送模块需求文档.md):理解 Mock Server 要做什么、有哪些验收与故障注入。 2) 再看 [后台页面设计说明.md](后台页面设计说明.md):明确平台后台/商家后台需要哪些页面与最小展示/权限要求。 3) 再看 [接口规范.md](接口规范.md): - Mock Server -> 平台:Webhook 推送格式与验签 - 平台/测试工具 -> Mock Server:控制面 API(创建运单/追加事件/跑场景/触发推送) 4) 看 [状态映射表.md](状态映射表.md):明确 `event_code` 如何映射到平台统一 `status_code`。 5) 看 [前端字段清单.md](前端字段清单.md):前端时间线组件到底需要哪些字段(以及 `source` 如何标注)。 6) 最后看 [缺口与待补充清单.md](缺口与待补充清单.md):把联调验收所需材料补齐,避免漏项。 ## 快速上手(联调路径) 1) 平台准备一个 Webhook 接收地址:`/webhook/express/status`,并实现 `X-Signature` 验签与幂等去重(按 `event_id`)。 2) 使用 Mock Server 控制面配置目标:设置 `target_webhook_url`、`client_id`、`secret`。 3) 创建运单(tracking_no)并运行场景(例如 `standard_delivered`),选择是否立即推送。 4) 在平台查看:事件是否按预期入库、时间线是否按 `event_time` 展示、异常注入是否触发告警/日志。 ## 常见问题(为什么这么设计) - 为什么不直接做真实韵达/圆通对接?因为联调成本高且不可控,Mock 能让你先把平台侧工程能力打牢。 - 为什么需要控制面 API?因为测试需要“可复现/可回放/可注入”,而不是只等外部推送。 - 为什么要状态映射?因为不同承运方文案与事件码不稳定,统一状态才能做稳定 UI 与统计。 文件列表: - [配送模块需求文档.md](配送模块需求文档.md):Mock 承运方 Server 的目标、范围、流程与验收。 - [后台页面设计说明.md](后台页面设计说明.md):后台页面结构、权限与最小交互。 - [接口规范.md](接口规范.md):Mock Server 控制面 API + Mock -> 平台 Webhook 推送规范。 - [状态映射表.md](状态映射表.md):Mock 事件码到平台统一状态映射建议。 - [前端字段清单.md](前端字段清单.md):时间线组件所需字段契约与展示规则。 - [缺口与待补充清单.md](缺口与待补充清单.md):联调/验收需要补齐的资料与决策项。 - [数据库对比与修改建议.md](数据库对比与修改建议.md):旧自营骑手表 vs 第三方快递表的改库建议。 - [生产表说明_platform_express.md](生产表说明_platform_express.md):生产环境 `platform_express_*` 三表用途、字段、约束/索引与写入查询建议。 - [uni-push2_安卓联调与取CID说明.md](uni-push2_安卓联调与取CID说明.md):安卓端 uni-push2 联调、CID 归属与推送验证闭环。 数据库: - 生产环境(推荐执行):[express_tracking_platform_upgrade.sql](express_tracking_platform_upgrade.sql) - 仅包含平台侧 `platform_express_*` 三张表,供生产代码使用。 - 联调/设计参考(不要用于生产直接落库):[express_tracking_mock_platform.sql](express_tracking_mock_platform.sql) - 包含平台侧表 + `mock_*` 测试表(故障注入/回放用),仅用于联调与文档说明。 测试/预发环境(不使用 mock_* 表也能联调): - 仍然执行 [express_tracking_platform_upgrade.sql](express_tracking_platform_upgrade.sql) 创建“生产同款”三表。 - 再执行 [seed_platform_express_test_data.sql](seed_platform_express_test_data.sql) 向 `platform_express_*` 写入少量示例数据(大多数运单号以 `TEST_` 开头),用于页面联调与排障演示(可随时清理)。 - 说明:当前脚本会插入 10 条示例运单:其中 9 条 `tracking_no` 以 `TEST_` 开头,另 1 条 `ORDER_PLACED/已下单` 示例运单号为空;并为每条运单插入 1~3 条不等的轨迹事件(幂等,可重复执行)。 ### Ubuntu 上的 Supabase(测试/预发)怎么执行 目标:在 Supabase 上只使用“生产同款”三表进行联调,不创建/不依赖任何 `mock_*` 表。 执行顺序(必须按顺序): 1) 执行建表脚本:[express_tracking_platform_upgrade.sql](express_tracking_platform_upgrade.sql) 2) 执行种子数据脚本:[seed_platform_express_test_data.sql](seed_platform_express_test_data.sql) 方式 A:Supabase Dashboard(推荐) - 打开 Supabase 项目 -> SQL Editor - 分别粘贴并执行以上两个 SQL 文件内容(先建表、后种子) - 建议使用具备 DDL 权限的角色执行(通常 SQL Editor 以高权限执行) 方式 B:Ubuntu 通过 psql 执行(适合自动化/脚本化) 1) 安装客户端:`sudo apt-get update && sudo apt-get install -y postgresql-client` 2) 从 Supabase 项目设置里复制连接串(Database -> Connection string),导出环境变量(示例): `export DATABASE_URL='postgresql://USER:PASSWORD@HOST:6543/postgres?sslmode=require'` 3) 在仓库根目录执行: - `psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f pages/mall/delivery/doc/需求文档/express_tracking_platform_upgrade.sql` - `psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f pages/mall/delivery/doc/需求文档/seed_platform_express_test_data.sql` 清理测试数据: - 种子脚本底部自带清理 SQL(按 `tracking_no LIKE 'TEST_%'` + raw `body->>'order_no'` 删除),需要时复制执行即可。 ### 执行成功后的校验 SQL(建议) 在 Supabase SQL Editor 执行以下查询,确认数据是否写入成功、事件是否按时间线可查: 1) 查看全部示例运单(应看到 10 条): ```sql select carrier, tracking_no, current_status_code, current_status_text, last_event_time, last_synced_at, created_at from public.platform_express_waybills where order_no like 'ORD_TEST_%' order by created_at desc; ``` 2) 按运单统计事件数量(确认每单都有事件): ```sql select w.carrier, w.tracking_no, count(e.id) as event_count, min(e.event_time) as first_event_time, max(e.event_time) as last_event_time from public.platform_express_waybills w left join public.platform_express_tracking_events e on e.waybill_id = w.id where w.order_no like 'ORD_TEST_%' group by w.carrier, w.tracking_no order by last_event_time desc nulls last; ``` 3) 查看单个运单时间线(按 event_time 升序): ```sql select event_time, event_code, event_text, status_code, node_name, node_location, source, dedupe_key from public.platform_express_tracking_events where tracking_no = 'TEST_YT_20260206_0002' order by event_time asc; ``` 4) 查看原始接收留痕(可选,用于排障/审计): ```sql select received_at, source, carrier, tracking_no, body, signature_valid, request_id, dedupe_key from public.platform_express_event_raw where tracking_no like 'TEST_%' or (body->>'order_no') like 'ORD_TEST_%' order by received_at desc limit 50; ``` ### 如何“伪造第三方推送到数据库”(无需后端) 如果你暂时没有 webhook 接收服务,但希望测试环境表现得像“第三方已经推送了轨迹”,可以直接写数据库: - 使用脚本 [simulate_third_party_to_db.sql](simulate_third_party_to_db.sql) - 会同时写入: - `platform_express_event_raw`(原始请求留痕/验签/排障) - `platform_express_tracking_events`(时间线事件) - `platform_express_waybills`(运单摘要) - 用法:在 Supabase SQL Editor 打开脚本,修改顶部【参数区】后执行整段。 - 建议:运单号使用 `TEST_` 前缀,便于按脚本底部清理 SQL 一键删除。 ### 与数据库其他表是否“相通”(关联与校验) 这套三表与平台业务表的关键“相通点”是: - `public.platform_express_waybills.order_id` 外键引用 `public.ml_orders(id)`(订单主表)。 因此: - 如果你的 Supabase(测试/预发)数据库里已经部署了完整商城库(包含 `public.ml_orders`),那么这三表可以直接和订单表联查/联动。 - 如果你的 Supabase 只是一个“独立的轨迹联调库”,没有 `public.ml_orders`,那么执行建表脚本时会因为外键依赖缺失而失败;此时建议先导入/执行商城主库迁移(让 `ml_orders` 存在),或临时改为仅使用 `order_no` 关联(不建外键),待接入完整主库后再补外键。 在 Supabase SQL Editor 里可执行以下校验: 1) 检查订单表是否存在: ```sql select to_regclass('public.ml_orders') as ml_orders; ``` 2) 检查外键是否创建成功(应该能看到 `platform_express_waybills_order_id_fkey` 或类似名称): ```sql select conname as fk_name, pg_get_constraintdef(c.oid) as fk_def from pg_constraint c join pg_class t on t.oid = c.conrelid join pg_namespace n on n.oid = t.relnamespace where c.contype = 'f' and n.nspname = 'public' and t.relname = 'platform_express_waybills'; ``` 3) 联查示例(有真实订单时): ```sql select o.id as order_id, o.order_no, w.carrier, w.tracking_no, w.current_status_code, w.last_synced_at from public.ml_orders o left join public.platform_express_waybills w on w.order_id = o.id order by o.created_at desc limit 20; ``` 建议下一步:在平台侧实现一个可切换的“Mock 数据源”开关(仅测试环境),并在 QA 用例中覆盖重复/乱序/验签失败等注入场景。