Files
medical-mall/pages/mall/delivery/doc/old(弃用)/DELIVERY_LOGIC.md
2026-03-17 11:06:26 +08:00

6.8 KiB
Raw Blame History

配送端逻辑说明(概要与建议)(舍弃)

概览

主要数据表(后端)

  • ml_delivery_drivers:配送员信息与 work_status
  • ml_delivery_tasks:配送任务(配送端主要“真源”),包含 driver_id, order_id, status, pickup_time, delivered_time 等。
  • ml_ordersml_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_taskslt 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_tasksml_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_tasksml_orders,并返回原子成功/失败。前端只负责触发该 API。
  4. 替换 localStorage 同步(低优先)

    • 使用队列/事件或服务端记录(例如在确认送达时写入 ml_delivery_tasks,历史页直接查询,不依赖 localStorage 写入),或者使用 WebSocket / 推送通知触发历史刷新。
  5. 补全 UI 映射(低优先)

    • status = 6 等补全友好文本和样式,避免“未知状态”展示。

建议的具体代码调整点(快速指引)

  • index.uvueorder-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.uvueorder-detail.uvueacceptOrder/acceptTask 函数),并提交一个 patch或者
    2. 生成一个状态映射工具文件并替换当前页面中的硬编码映射;或者
    3. 把本文档整理为项目 wiki 条目并打开 PR。

请选择一个你希望我继续执行的项(例如“帮我做 1实现条件接单补丁”我会把对应步骤加入 TODO 并实现。