97 lines
6.8 KiB
Markdown
97 lines
6.8 KiB
Markdown
# 配送端逻辑说明(概要与建议)(舍弃)
|
||
|
||
**概览**
|
||
- 本文档总结 `pages/mall/delivery` 目录下配送端主要页面的工作流与实现细节,定位到关键数据库表与状态机,列出已识别的并发/同步风险,并给出可执行的改进建议。
|
||
- 主要参考页面:
|
||
- [pages/mall/delivery/index.uvue](pages/mall/delivery/index.uvue)
|
||
- [pages/mall/delivery/order-history.uvue](pages/mall/delivery/order-history.uvue)
|
||
- [pages/mall/delivery/profile.uvue](pages/mall/delivery/profile.uvue)
|
||
- [pages/mall/delivery/order-detail.uvue](pages/mall/delivery/order-detail.uvue)
|
||
|
||
**主要数据表(后端)**
|
||
- `ml_delivery_drivers`:配送员信息与 `work_status`。
|
||
- `ml_delivery_tasks`:配送任务(配送端主要“真源”),包含 `driver_id, order_id, status, pickup_time, delivered_time` 等。
|
||
- `ml_orders`、`ml_order_items`:电商订单主表及明细(用于展示订单详情、订单号、商品列表等)。
|
||
- 其它辅助表:`ml_shops`, `ak_users`(用于 auth->ak id 回退查找)等。
|
||
|
||
**状态机(关键数值映射 — 汇总)
|
||
- ml_delivery_tasks.status(代码中使用):
|
||
- 1 = 待接取(pending)
|
||
- 2 = 已接取(accepted)
|
||
- 3 = 取货中(picking)
|
||
- 4 = 已取货(picked)
|
||
- 5 = 配送中(delivering / startDelivery 将 status 置 5)
|
||
- 6 = 已送达 / 完成(confirmDelivery 将 status 置 6)
|
||
- ml_orders.order_status(电商端状态,代码中做同步尝试):
|
||
- 2 = 已接取
|
||
- 4 = 已取货
|
||
- 5 = 已送达
|
||
- 7 = 已拒绝
|
||
- 注意:两张表的状态值并不一一对应,代码中多处采用“尝试同步”的方式更新 `ml_orders.order_status`,但没有统一映射抽象,可能造成短时不一致。
|
||
|
||
**页面职责与交互要点**
|
||
- `index.uvue`(配送端首页)
|
||
- 加载司机信息、今日统计、当前任务(查询 `ml_delivery_tasks`,`lt status < 5`)、可接订单(`driver_id IS NULL AND status = 1`)。
|
||
- 提供在线/离线切换(更新 `ml_delivery_drivers.work_status`),并禁止在存在当前任务时下线。
|
||
- 任务操作:接受(status->2)、开始取货(3)、确认取货(4)、开始配送(5)、确认送达(6)。每步都更新 `ml_delivery_tasks`,并尝试同步 `ml_orders`。
|
||
- 使用 `supaReady` 包装并设 1.5s 超时降级,避免阻塞 UI。
|
||
|
||
- `order-history.uvue`(历史订单)
|
||
- 以 `ml_delivery_tasks` 为源,查询 driver 相关任务(`gte('status', 2)`),并映射为历史条目供展示。
|
||
- 使用本地存储键 `completed_order_for_history`:确认送达时(index.confirmDelivery)会把完成的任务写入该键,历史页 onShow 时合并(仅当 status >= 4),之后删除该 key。
|
||
|
||
- `profile.uvue`(个人中心)
|
||
- 展示司机统计(今日、最近任务、任务计数),通过 `ml_delivery_tasks` 聚合计算 pending/ongoing/completed 数量。
|
||
|
||
- `order-detail.uvue`(订单/任务详情)
|
||
- 支持以订单 ID 或任务 ID 打开:优先查 `ml_orders`,若未找到则回退查 `ml_delivery_tasks` 并用任务数据回填页面。
|
||
- 对关键操作(接受/确认取货/确认送达/拒绝)会同时更新 `ml_delivery_tasks`(按 `order_id`)并尝试更新 `ml_orders.order_status`。
|
||
|
||
**已识别风险与可改进点**
|
||
- 状态不一致风险:
|
||
- `ml_delivery_tasks` 与 `ml_orders` 使用不同数值含义,且同步是“尝试式”的,短时内出现不一致或页面显示不同步的可能性高。
|
||
- 抢单竞态(race condition):
|
||
- 可接订单查询基于 `driver_id IS NULL AND status = 1`,多个司机并发接受可能造成重复接单。
|
||
- 目前接单操作没有使用条件更新(例如 `UPDATE ... WHERE id = ? AND driver_id IS NULL`),因此依赖后续 reload 作为补救,非原子性操作。
|
||
- 本地存储同步(`completed_order_for_history`):
|
||
- 以 localStorage 作为页面间同步的手段,适用于单设备单会话,但在多设备或短时间多页面切换(或 crash)场景下不可靠。
|
||
- UI 与状态覆盖差异:
|
||
- 某些页面/映射未覆盖 `status = 6`(例如历史页 getOrderStatusText 没有 `6` 的友好文本),会显示“未知状态”。
|
||
- supaReady 超时策略:
|
||
- 使用 1.5s 超时可以避免页面长时间等待,但在 session 刷新尚未完成的情况下可能读到空或旧数据;需要权衡 UX 与数据正确性。
|
||
|
||
**短期可执行修复(优先级排序)**
|
||
1. 接单使用条件更新(高优先)
|
||
- 在接单接口/前端更新时改为条件写入:
|
||
- SQL/SDK 示例:UPDATE ml_delivery_tasks SET driver_id = :driverId, status = 2 WHERE id = :taskId AND driver_id IS NULL
|
||
- 若返回表示 0 行更新,则提示“已被其他人接单”,并刷新列表。
|
||
- 目的:避免重复接单的竞态。
|
||
|
||
2. 统一状态映射抽象(中优先)
|
||
- 在前端添加一个状态映射工具函数(例如 mapTaskStatusToOrderStatus(status)),并在每处状态同步时使用该映射。集中维护会减少散落的 magic number。
|
||
|
||
3. 增强表间同步可靠性(中优先)
|
||
- 将关键同步(例如确认送达)封装为后端事务或 RPC:后端在事务中同时更新 `ml_delivery_tasks` 与 `ml_orders`,并返回原子成功/失败。前端只负责触发该 API。
|
||
|
||
4. 替换 localStorage 同步(低优先)
|
||
- 使用队列/事件或服务端记录(例如在确认送达时写入 `ml_delivery_tasks`,历史页直接查询,不依赖 localStorage 写入),或者使用 WebSocket / 推送通知触发历史刷新。
|
||
|
||
5. 补全 UI 映射(低优先)
|
||
- 为 `status = 6` 等补全友好文本和样式,避免“未知状态”展示。
|
||
|
||
**建议的具体代码调整点(快速指引)**
|
||
- 在 `index.uvue` 与 `order-detail.uvue` 的接单逻辑中替换无条件 update 为条件更新。例如:
|
||
- 当前(伪代码):
|
||
- supa.from('ml_delivery_tasks').update({ driver_id: driverId, status: 2 }).eq('id', orderId)
|
||
- 建议(伪代码):
|
||
- supa.rpc 或 SQL: UPDATE ml_delivery_tasks SET driver_id = $1, status = 2 WHERE id = $2 AND driver_id IS NULL RETURNING *
|
||
- 如果返回行数 === 0 则表示接单失败(已被抢)
|
||
- 在多个页面里抽象出 `statusMap` 函数并复用:放在 `utils/deliveryStatus.uts` 或相应工具文件。
|
||
|
||
**操作建议(下一步)**
|
||
- 我可以为你:
|
||
1. 在代码中实现“条件接单”补丁(修改 `index.uvue` 与 `order-detail.uvue` 的 `acceptOrder/acceptTask` 函数),并提交一个 patch;或者
|
||
2. 生成一个状态映射工具文件并替换当前页面中的硬编码映射;或者
|
||
3. 把本文档整理为项目 wiki 条目并打开 PR。
|
||
|
||
请选择一个你希望我继续执行的项(例如“帮我做 1:实现条件接单补丁”),我会把对应步骤加入 TODO 并实现。 |