数据库分析和对应不同角色页面
This commit is contained in:
196
pages/mall/delivery/doc/需求文档/数据库对比与修改建议.md
Normal file
196
pages/mall/delivery/doc/需求文档/数据库对比与修改建议.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# 配送端(自营骑手)表 vs 第三方快递轨迹表:对比与数据库修改建议
|
||||
|
||||
本文目标:
|
||||
- 整理“原先配送端(自营骑手/同城配送)”使用的核心数据表。
|
||||
- 对比“现在第三方快递配送(韵达/圆通等)”的轨迹/运单数据表。
|
||||
- 给出建议的数据库改造方案:如何在不破坏订单主表的前提下,引入第三方快递轨迹能力,并(可选)逐步弃用原先配送端表的依赖。
|
||||
|
||||
明确决策(当前结论):
|
||||
- 仅支持第三方快递轨迹(承运方运单 + 轨迹时间线)。
|
||||
- 不做自营骑手端/同城配送任务流;`ml_delivery_drivers`/`ml_delivery_tasks` 视为历史遗留表,不再作为新能力的依赖与写入目标。
|
||||
|
||||
> 说明:本对比只讨论“第三方快递轨迹/运单”与“自营骑手任务”两套模型如何在数据库层共存/迁移;二者是不同业务域,不建议强行复用同一张表。
|
||||
|
||||
---
|
||||
|
||||
## 1. 原先配送端(自营骑手)核心表(现状)
|
||||
|
||||
数据来源:主库 DDL(`mall_sql/schemas/complete_mall_database.sql`)与旧配送端文档(`pages/mall/delivery/doc/old/*`)。
|
||||
|
||||
### 1.1 `ml_delivery_drivers`(配送员信息表)
|
||||
用途:记录配送员(骑手)档案与实时工作状态;用于配送端登录后的“是否可接单/是否在线”。
|
||||
|
||||
关键字段(节选):
|
||||
- `id`:配送员 ID
|
||||
- `user_id`:关联 `ak_users.id`
|
||||
- `real_name`、`id_card`、`driver_license`
|
||||
- `vehicle_type`、`vehicle_number`
|
||||
- `service_areas`(JSONB)
|
||||
- `work_status`:1 在线 / 2 忙碌 / 3 离线
|
||||
- `current_lat` / `current_lng`
|
||||
- `rating_avg` / `rating_count` / `order_count`
|
||||
- `status`:1 正常 / 2 暂停 / 3 离职
|
||||
|
||||
### 1.2 `ml_delivery_tasks`(配送任务表,配送端“状态真源”)
|
||||
用途:描述“一个订单被分配给某个骑手并经历接单→取货→配送→送达”的任务流。
|
||||
|
||||
关键字段(节选):
|
||||
- 关联:
|
||||
- `order_id`(UUID,**唯一**,FK 到 `ml_orders.id`)
|
||||
- `driver_id`(FK 到 `ml_delivery_drivers.id`,可为空表示未接单)
|
||||
- 地址与费用:
|
||||
- `pickup_address`(JSONB)取货地址
|
||||
- `delivery_address`(JSONB)配送地址
|
||||
- `distance`、`estimated_time`、`delivery_fee`
|
||||
- 任务状态:`status`(int)
|
||||
- 1 待接单
|
||||
- 2 已接单
|
||||
- 3 取货中
|
||||
- 4 配送中
|
||||
- 5 已送达
|
||||
- 6 配送失败
|
||||
- 时间戳:`assigned_at` / `picked_at` / `delivered_at`
|
||||
- 其他:`delivery_code`(取货码)、`remark`、`failure_reason`
|
||||
|
||||
> 注意:旧页面/旧文档里常出现 `accepted_at`、`pickup_time`、`delivered_time` 等命名,和主库 DDL 的 `assigned_at/picked_at/delivered_at` 存在差异;如果你要继续使用自营配送链路,建议在代码层做统一字段映射或做一次字段对齐迁移。
|
||||
|
||||
### 1.3 与订单表的关系(旧模型的关键耦合点)
|
||||
- `ml_delivery_tasks.order_id` 强依赖 `ml_orders.id`,并且 **1 个订单只能有 1 条配送任务**(`order_id UNIQUE`)。
|
||||
- 旧实现里常尝试把 `ml_delivery_tasks.status` 同步到 `ml_orders.order_status`,容易造成口径不一致(旧文档也提到了这种冲突风险)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 现在第三方快递配送(轨迹/运单)表(目标模型)
|
||||
|
||||
数据来源:`pages/mall/delivery/doc/需求文档/express_tracking_mock_platform.sql`。
|
||||
|
||||
> 这套表的定位不是“骑手任务流”,而是“第三方承运的运单 + 轨迹事件时间线”。
|
||||
|
||||
### 2.1 `platform_express_waybills`(平台侧:运单主表)
|
||||
用途:一条运单(一个 `tracking_no`)的聚合信息;用于订单详情页展示“承运方/运单号/当前状态/最后同步时间”。
|
||||
|
||||
关键字段(节选):
|
||||
- 关联:`order_id`(可选)、`order_no`(可选)
|
||||
- 运单:`carrier`、`tracking_no`、`source`
|
||||
- 聚合状态:`current_status_code`、`current_status_text`
|
||||
- 时间:`eta`、`last_synced_at`
|
||||
- 约束:`UNIQUE (carrier, tracking_no)`
|
||||
|
||||
特点:
|
||||
- 同一个订单允许对应多条运单(拆包裹/分批发货)——因为 `order_id` 不唯一。
|
||||
|
||||
### 2.2 `platform_express_tracking_events`(平台侧:轨迹事件表)
|
||||
用途:时间线的主数据来源;用于前端展示、告警统计与排障。
|
||||
|
||||
关键字段(节选):
|
||||
- 关联:`waybill_id`(FK 到 `platform_express_waybills.id`)
|
||||
- 事件:`event_id`(第三方可能缺失)、`event_time`、`event_code`、`event_text`
|
||||
- 平台统一状态:`status_code`
|
||||
- 节点:`node_name`、`location`、`description`
|
||||
- 证据:`evidence_urls`(jsonb)
|
||||
- 原始回文:`raw_payload`(jsonb,可用于审计/排障)
|
||||
- 幂等:`dedupe_key` + `UNIQUE (waybill_id, dedupe_key)`
|
||||
|
||||
### 2.3 `platform_express_event_raw`(平台侧:原始接收表)
|
||||
用途:记录 webhook/轮询的原始请求、验签与解析错误,便于排障与审计。
|
||||
|
||||
### 2.4 `mock_*`(Mock 承运方侧表)
|
||||
这部分只用于联调/回归/故障注入,不建议进入生产主库的核心业务 schema(可以放在独立 schema 或测试库)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 两套模型的核心差异(为什么不建议“复用一张表”)
|
||||
|
||||
| 维度 | 自营骑手(旧配送端) | 第三方快递(新模型) |
|
||||
|---|---|---|
|
||||
| 业务对象 | 任务(骑手接单、取货、送达) | 运单(承运方扫描轨迹) |
|
||||
| 与订单关系 | 1 订单 = 1 任务(`order_id UNIQUE`) | 1 订单 = N 运单(拆包裹常见) |
|
||||
| 状态来源 | 平台自己驱动状态机(按钮/操作) | 第三方事件驱动(webhook/轮询) |
|
||||
| 数据颗粒度 | 少量节点(接单/取货/送达) | 高频节点(到站/发车/分拣/派送/签收…) |
|
||||
| 关键字段 | `driver_id`、地址 JSON、配送费、距离 | `carrier`、`tracking_no`、事件时间线、幂等去重 |
|
||||
| 风险点 | 并发抢单、任务状态与订单状态不同步 | 乱序/重复事件、验签、防重放、脱敏 |
|
||||
|
||||
结论:
|
||||
- 旧表(`ml_delivery_*`)适合“自营骑手/同城配送”。
|
||||
- 新表(`platform_express_*`)适合“第三方快递轨迹”。
|
||||
- 两者可以共存,但不要强行把第三方轨迹塞进 `ml_delivery_tasks`。
|
||||
|
||||
---
|
||||
|
||||
## 4. 推荐的数据库修改方案(兼容、可渐进)
|
||||
|
||||
### 4.1 方案 1(推荐):新增第三方快递表,不改旧配送表
|
||||
适用:你们当前要做第三方快递展示,且已明确“不做自营骑手”。
|
||||
|
||||
做法:
|
||||
1) 在主库新增(或通过 migration 引入)三张平台侧表:
|
||||
- `platform_express_waybills`
|
||||
- `platform_express_tracking_events`
|
||||
- `platform_express_event_raw`
|
||||
2) 商家发货时写入/绑定:创建 `platform_express_waybills` 行(填 `order_id`、`order_no`、`carrier`、`tracking_no`)。
|
||||
3) 第三方回调/轮询入库:写 `platform_express_tracking_events`,并更新 `platform_express_waybills.current_status_*` 与 `last_synced_at`。
|
||||
|
||||
建议的小幅增强(强烈建议做):
|
||||
- 给 `platform_express_waybills(order_id)` 增加索引(便于按订单查运单)。
|
||||
- 让 `platform_express_waybills.order_id` 建外键到 `ml_orders(id)`(如果你们能保证订单一定存在)。
|
||||
|
||||
### 4.2 方案 2:逐步“弃用旧配送端表”的依赖(当你们全面第三方快递时)
|
||||
适用:你们不再提供自营骑手配送,或者想把骑手端做成独立项目。
|
||||
|
||||
做法(建议按阶段,不要硬删表):
|
||||
- 阶段 A:停止业务写入 `ml_delivery_tasks`(页面/接口不再创建任务)。
|
||||
- 阶段 B:订单详情页的物流展示只依赖 `platform_express_*`。
|
||||
- 阶段 C:将 `ml_delivery_tasks` 标为 legacy(只读保留一段时间),最终再评估是否归档/删除。
|
||||
|
||||
为什么不建议立刻删:
|
||||
- 历史数据、结算对账、纠纷复盘可能仍需要旧数据。
|
||||
|
||||
在“不做自营骑手”的前提下,最小要求:
|
||||
- 新增第三方快递表后,业务代码只写入/读取 `platform_express_*`,不要再创建/更新 `ml_delivery_tasks`。
|
||||
- 旧表保留只读(或仅用于历史查询/清理脚本),后续再评估归档策略。
|
||||
|
||||
### 4.3 如果两种配送方式要并存(同城骑手 + 快递)
|
||||
建议用“履约类型”做分流,而不是混表:
|
||||
- 同城/自营:继续用 `ml_delivery_tasks`(任务流)
|
||||
- 快递:用 `platform_express_*`(运单轨迹)
|
||||
- 订单详情页按订单的履约类型选择展示模块(或同时展示多个包裹)
|
||||
|
||||
---
|
||||
|
||||
## 5. 迁移/改库执行清单(建议写成 migration)
|
||||
|
||||
### 5.1 建表落库
|
||||
- 把 `express_tracking_mock_platform.sql` 的 A 部分(platform)整理为一份 migration(放到 `mall_sql/migrations/`),避免:
|
||||
- 重复创建 `set_updated_at()`(项目若已有同名函数)
|
||||
- 把 `mock_*` 测试表混进生产 schema
|
||||
|
||||
### 5.2 对接 `ml_orders`
|
||||
- 建议:
|
||||
- `platform_express_waybills.order_id REFERENCES public.ml_orders(id)`
|
||||
- `CREATE INDEX ... ON platform_express_waybills(order_id)`
|
||||
- 不建议:
|
||||
- 把运单号/承运方直接塞进 `ml_orders`(会导致一单多包裹很难处理)
|
||||
|
||||
### 5.3 数据回填(可选)
|
||||
如果你们历史上已经保存过“承运方/运单号”在别处(例如订单扩展表/发货日志),可做一次性回填:
|
||||
- 按订单生成 waybill 行
|
||||
- 再按运单触发一次轨迹拉取
|
||||
|
||||
### 5.4 权限与隐私
|
||||
- 买家/商家/客服看到的轨迹必须“同源”,但展示要按角色脱敏;敏感字段(如手机号、原始回文)按文档约束控制。
|
||||
|
||||
---
|
||||
|
||||
## 6. 你接下来要怎么改数据库(最短路线)
|
||||
|
||||
如果你现在的目标是:商家可选承运方 + 录入运单号 + 用户能看轨迹时间线。
|
||||
|
||||
最短路线:
|
||||
1) 在主库落 `platform_express_waybills` / `platform_express_tracking_events` / `platform_express_event_raw`
|
||||
2) 发货绑定时写 `platform_express_waybills(order_id, order_no, carrier, tracking_no)`
|
||||
3) 第三方事件入库写 `platform_express_tracking_events`
|
||||
4) 订单详情页按 `order_id` 查 waybills,再查 events 渲染时间线
|
||||
|
||||
---
|
||||
|
||||
(如你确认要我进一步把“建议的小幅增强”直接写成 SQL migration 文件,我可以在 `mall_sql/migrations/` 里新增一份只包含 platform 表的 migration,并确保不引入 `mock_*` 表。)
|
||||
Reference in New Issue
Block a user