5.8 KiB
5.8 KiB
派单失败问题修复指南
问题概述
用户下单支付后,派单返回 ALL_ELIGIBLE_STAFF_BUSY(当前可服务人员均在忙),导致无法成功派单。
根本原因
原因 1:订单缺少服务经纬度(已修复)
问题:createServiceOrder 函数在创建订单时,没有将地址的经纬度写入 service_lat 和 service_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_at 或 scheduled_end_at 为 NULL 时,时间冲突检查条件会跳过比较,但 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
重点关注:
- 问题订单的
service_lat/service_lng是否为NULL - 有哪些服务人员在忙(有活跃派单记录)
第二步:修复历史订单的经纬度
在 Supabase SQL Editor 中执行:
mall_sql/migrations/20260610_fix_service_order_coordinates.sql
此脚本会:
- 统计有多少订单缺少经纬度
- 从
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. 前端测试流程
- 重新下单支付
- 查看控制台日志,应看到:
[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 |
后续优化建议
- 订单创建时设置预约时间范围:将
appointment_time转换为scheduled_start_at和scheduled_end_at - 服务人员位置实时更新:确保 delivery 端定期上报当前位置
- 派单失败重试策略:增加指数退避重试,避免频繁调用
- 监控告警:当派单失败率超过阈值时发送告警