Files
medical-mall/docs/home-service/FIX_dispatch_failure_guide.md

5.8 KiB
Raw Blame History

派单失败问题修复指南

问题概述

用户下单支付后,派单返回 ALL_ELIGIBLE_STAFF_BUSY(当前可服务人员均在忙),导致无法成功派单。

根本原因

原因 1订单缺少服务经纬度已修复

问题createServiceOrder 函数在创建订单时,没有将地址的经纬度写入 service_latservice_lng 字段。

影响

  • 派单 RPC 无法计算人员距离
  • 距离筛选条件失效
  • 可能匹配到远距离人员

修复serviceOrderService.uts 第 1181-1182 行新增:

service_lat: params.address.latitude != null ? params.address.latitude : null,
service_lng: params.address.longitude != null ? params.address.longitude : null,

原因 2时间冲突检查过于严格待数据库执行

问题:原 RPC 函数中,当订单 scheduled_start_atscheduled_end_atNULL 时,时间冲突检查条件会跳过比较,但 NOT EXISTS 子查询仍然会排除任何有活跃任务的人员。

原逻辑(第 633-655 行):

AND NOT EXISTS (
    SELECT 1
    FROM hss_service_assignments existing_assignment
    JOIN hss_service_orders existing_order
      ON existing_order.id = existing_assignment.order_id
    WHERE existing_assignment.staff_id::TEXT = s.id::TEXT
      AND existing_assignment.deleted_at IS NULL
      AND existing_assignment.status IN ('assigned', 'accepted', ...)
      AND (
          v_order.scheduled_start_at IS NULL  -- 如果订单没有时间
          OR v_order.scheduled_end_at IS NULL -- 则跳过比较
          OR ...时间重叠判断...
      )
  )

问题:当 v_order.scheduled_start_at IS NULL 时,整个 AND 条件变为 TRUE,导致所有有活跃任务的人员都被排除

修复:新增优化版 RPC rpc_homecare_auto_dispatch_optimized,只有当订单有明确时间范围时才检查时间冲突。

修复步骤

第一步:执行诊断脚本(可选,用于确认问题)

在 Supabase SQL Editor 中执行:

mall_sql/diagnostics/dispatch_failure_diagnosis.sql

重点关注:

  1. 问题订单的 service_lat/service_lng 是否为 NULL
  2. 有哪些服务人员在忙(有活跃派单记录)

第二步:修复历史订单的经纬度

在 Supabase SQL Editor 中执行:

mall_sql/migrations/20260610_fix_service_order_coordinates.sql

此脚本会:

  1. 统计有多少订单缺少经纬度
  2. address_snapshot_json 中提取经纬度并更新到主表字段

第三步:部署优化版派单 RPC

在 Supabase SQL Editor 中执行:

mall_sql/migrations/20260610_optimize_dispatch_conflict_check.sql

此脚本会创建新的 RPC 函数 rpc_homecare_auto_dispatch_optimized

第四步:切换使用优化版 RPC 已完成

修改前端调用优化版 RPC 函数。

文件serviceOrderService.uts 第 1015 行

修改前

const { data, error } = await supa.rpc('rpc_homecare_auto_dispatch', {
    p_order_id: orderId
} as any)

修改后

const { data, error } = await supa.rpc('rpc_homecare_auto_dispatch_optimized', {
    p_order_id: orderId
} as any)

此步骤已完成,前端已切换使用优化版 RPC。

验证方法

1. 检查订单经纬度是否已填充

SELECT 
    id,
    service_lat,
    service_lng,
    address_snapshot_json->>'latitude' as address_lat,
    address_snapshot_json->>'longitude' as address_lng
FROM public.hss_service_orders
WHERE id = 'so-1781054320183-35441';

2. 查看在线服务人员状态

SELECT 
    id,
    online_status,
    station_id,
    current_lat,
    current_lng,
    (SELECT COUNT(*) 
     FROM hss_service_assignments sa
     JOIN hss_service_orders so ON so.id = sa.order_id
     WHERE sa.staff_id::TEXT = s.id::TEXT
       AND sa.deleted_at IS NULL
       AND sa.status IN ('assigned', 'accepted', 'departed', 'arrived', 'serving', 'in_service')
    ) as active_tasks
FROM ml_delivery_staff s
WHERE deleted_at IS NULL
  AND status = 1
  AND COALESCE(is_active, TRUE) = TRUE
ORDER BY online_status DESC, active_tasks ASC;

3. 前端测试流程

  1. 重新下单支付
  2. 查看控制台日志,应看到:
    • [homecare-dispatch] RPC response: - RPC 原始返回
    • [homecare-dispatch] Parsed result: - 解析后的结果
    • [confirmPayment] 派单结果: - 支付页派单结果

4. 预期结果

修复前

code: "ALL_ELIGIBLE_STAFF_BUSY"
message: "当前可服务人员均在忙,请稍后重新派单"

修复后(如果有在线空闲人员):

code: "DISPATCH_ASSIGNED"
message: "系统已为您匹配服务人员"
dispatch_status: "assigned"

文件清单

文件 说明
services/serviceOrderService.uts 已修改:订单创建时填充经纬度
pages/mall/consumer/payment.uvue 已修改:增加派单日志
pages/mall/consumer/home-service/order-detail.uvue 已修改:增加派单日志
pages/mall/consumer/orders.uvue 已修改:增加派单日志
services/serviceOrderService.uts 已修改区分显示5种失败原因
mall_sql/diagnostics/dispatch_failure_diagnosis.sql 📋 诊断脚本(可选执行)
mall_sql/migrations/20260610_fix_service_order_coordinates.sql 🔧 修复历史订单经纬度
mall_sql/migrations/20260610_optimize_dispatch_conflict_check.sql 🔧 优化版派单 RPC

后续优化建议

  1. 订单创建时设置预约时间范围:将 appointment_time 转换为 scheduled_start_atscheduled_end_at
  2. 服务人员位置实时更新:确保 delivery 端定期上报当前位置
  3. 派单失败重试策略:增加指数退避重试,避免频繁调用
  4. 监控告警:当派单失败率超过阈值时发送告警