# 配送端"待接单"Tab 修复验收清单 ## 修复内容总结 ### 1. 后端 SQL 修复 (20260610_fix_delivery_pending_blank.sql) - ✅ 为 `hss_service_orders` 表添加缺失列:`request_id`, `service_category`, `price`, `staff_income`, `elder_name`, `elder_phone`, `duration_minutes` 等 - ✅ 扩展 CHECK 约束,允许 `pending_assignment` 和 `pending_accept` 状态 - ✅ 重写 `delivery_build_order_json()` 函数,所有展示字段都有兜底值 - ✅ 重写 `delivery_get_legacy_order_json()` 函数 - ✅ 重写 `rpc_delivery_order_list()` 函数 ### 2. 历史数据回填 (20260610_backfill_pending_orders_core_fields.sql) - ✅ 安全回填 `pending_assignment` 和 `pending_accept` 订单的核心字段 - ✅ 使用 COALESCE/NULLIF 防止覆盖已有非空字段 - ✅ 包含预检查和后检查 SQL 查询 ### 3. 未来订单链路修复 (医疗-consumer/services/serviceOrderService.uts) - ✅ `createServiceOrder()` 插入 `hss_service_orders` 时添加以下字段: - `service_category`: 使用 `params.service.category`,默认为 '居家服务' - `elder_name`: 使用 `params.recipientName` - `elder_phone`: 使用 `params.recipientPhone` - `price`: 使用 `payableAmount` - `staff_income`: 使用 `payableAmount` - `duration_minutes`: 固定为 90 - `scheduled_at`: 使用 `appointmentTime` - `request_id`: 空字符串 ### 4. 前端展示兜底 (医疗-delivery/api/delivery.uts) - ✅ `mapRpcOrderItemCompat()` 函数添加安全兜底: - `serviceName` 为空 → 显示 '居家服务订单' - `elderName` 为空 → 显示 `contactName` 或 '服务对象待补充' - `address` 为空 → 显示 '地址待补充' - `appointmentTime` 为空 → 使用 `createdAt` 或 '时间待补充' - `staffIncome` 为空 → 显示 0 - ✅ `enrichOrderWithRequestFallback()` 限制日志输出:只输出前3个缺少 `request_id` 的订单警告日志 --- ## 验收步骤 ### 步骤 1:执行 SQL 迁移文件 在 Supabase SQL Editor 中按顺序执行以下文件: ```sql -- 1. 修复表结构和 RPC 函数 -- 文件:mall_sql/migrations/20260610_fix_delivery_pending_blank.sql -- 说明:添加缺失列、扩展 CHECK 约束、重写 RPC 函数 -- 2. 回填历史数据 -- 文件:mall_sql/migrations/20260610_backfill_pending_orders_core_fields.sql -- 说明:安全回填 pending_assignment 和 pending_accept 订单的核心字段 ``` **验证查询:** ```sql -- 检查表结构 SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'hss_service_orders' AND column_name IN ('request_id', 'service_category', 'price', 'staff_income', 'elder_name', 'elder_phone', 'duration_minutes') ORDER BY column_name; -- 检查 CHECK 约束 SELECT conname, pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = 'hss_service_orders'::regclass AND contype = 'c'; -- 检查 RPC 函数是否存在 SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'public' AND routine_name LIKE 'delivery_%' ORDER BY routine_name; -- 检查待接单订单数量 SELECT COUNT(*) as pending_count FROM hss_service_orders WHERE status IN ('pending_assignment', 'pending_accept') AND deleted_at IS NULL; ``` ### 步骤 2:测试待接单 Tab 显示 1. 打开配送端 App 2. 登录服务人员账号 3. 进入"订单"页面 4. 切换到"待接单"Tab 5. **预期结果:** - 订单卡片显示完整信息: - 服务名称:显示具体服务名称或 '居家服务订单' - 服务对象:显示姓名或 '服务对象待补充' - 预约时间:显示具体时间或 '时间待补充' - 地址:显示详细地址或 '地址待补充' - 预计收入:显示具体金额(不再显示 ¥0) - 联系电话:显示联系人电话 - 控制台不再大量输出 "request fallback skipped: missing request_id" 日志 - 最多只输出前3条此类警告日志 ### 步骤 3:测试其他 Tab 功能 1. **今天订单 Tab**:确保仍然正常工作 2. **历史订单 Tab**:确保仍然正常工作 3. **全部订单 Tab**:确保仍然正常工作 ### 步骤 4:测试订单操作功能 1. **接单**:点击"接单"按钮,验证功能正常 2. **拒单**:点击"拒单"按钮,验证功能正常 3. **签到**:到达服务地点后签到,验证功能正常 4. **开始服务**:点击"开始服务",验证功能正常 5. **完成服务**:点击"完成服务",验证功能正常 ### 步骤 5:测试新订单创建链路 1. 在 consumer 端创建一个新的居家服务订单 2. 等待自动派单(或手动派单) 3. 在配送端查看该订单 4. **预期结果:** - 订单信息显示完整,不再缺失核心字段 - 控制台无异常日志 ### 步骤 6:验证数据一致性 ```sql -- 检查 pending_assignment 订单的核心字段填充情况 SELECT id, service_name, service_category, elder_name, contact_name, price, staff_income, duration_minutes, appointment_time, status FROM hss_service_orders WHERE status IN ('pending_assignment', 'pending_accept') AND deleted_at IS NULL ORDER BY created_at DESC LIMIT 10; -- 检查是否有订单仍然缺少核心字段 SELECT COUNT(*) as missing_core_info FROM hss_service_orders WHERE status IN ('pending_assignment', 'pending_accept') AND deleted_at IS NULL AND ( service_name = '' OR service_name IS NULL OR elder_name = '' OR elder_name IS NULL OR price IS NULL OR price = 0 ); ``` --- ## 注意事项 1. **不要修改页面样式**:本次修复只涉及数据层面,不改变任何 UI 样式 2. **不要删除现有功能**:确保"今天订单"、"历史订单"、"接单"、"拒单"、"签到"、"开始服务"等功能正常工作 3. **RLS 策略**:不要修改已有的 RLS 策略,除非发现明确的安全问题 4. **向后兼容**:确保修复不影响已有的订单数据 5. **日志控制**:控制台日志输出受到限制,避免刷屏 --- ## 回滚方案 如果修复后出现问题,可以按以下步骤回滚: 1. **回滚 SQL 变更:** ```sql -- 删除添加的列(如果列存在) ALTER TABLE public.hss_service_orders DROP COLUMN IF EXISTS request_id, DROP COLUMN IF EXISTS service_category, DROP COLUMN IF EXISTS price, DROP COLUMN IF EXISTS staff_income, DROP COLUMN IF EXISTS elder_name, DROP COLUMN IF EXISTS elder_phone, DROP COLUMN IF EXISTS duration_minutes; -- 恢复原始 CHECK 约束 ALTER TABLE public.hss_service_orders DROP CONSTRAINT IF EXISTS chk_hss_service_orders_status; ALTER TABLE public.hss_service_orders ADD CONSTRAINT chk_hss_service_orders_status_original CHECK ( status IN ( 'created', 'paid', 'assigned', 'accepted', 'rejected', 'departed', 'arrived', 'in_service', 'completed', 'pending_acceptance', 'accepted_by_user', 'reviewed', 'settled', 'cancelled', 'exception' ) ); ``` 2. **回滚前端代码:** - 使用 Git 回滚 `医疗-delivery/api/delivery.uts` 的修改 - 使用 Git 回滚 `医疗-consumer/services/serviceOrderService.uts` 的修改 3. **重启服务:** - 重启配送端 App - 清除缓存并重新登录 --- ## 常见问题 ### Q1: 为什么待接单 Tab 显示空白? **A:** 根因是 `hss_service_orders` 表缺少 `service_category`、`price`、`staff_income`、`elder_name` 等列,导致 RPC 函数返回的订单数据核心字段为空。 ### Q2: 为什么控制台大量输出 "request fallback skipped: missing request_id"? **A:** 因为 `hss_service_orders` 表没有 `request_id` 列,前端尝试从 `ec_service_requests` 表回填数据时失败。修复后已限制日志输出,最多只显示前3条警告。 ### Q3: 为什么价格显示为 ¥0? **A:** 因为 `price` 和 `staff_income` 字段不存在,RPC 函数返回默认值 0。修复后会在创建订单时写入正确的价格。 ### Q4: 回填 SQL 会覆盖已有数据吗? **A:** 不会。回填 SQL 使用 `COALESCE` 和 `NULLIF` 函数,只填充 NULL 或空字符串的字段,不会覆盖已有的非空数据。 ### Q5: 修复后旧订单会显示正常吗? **A:** 会。通过执行回填 SQL,历史订单的核心字段会被安全填充。即使不执行回填,前端展示兜底也会显示友好的提示信息(如'地址待补充')。 --- ## 完成标志 ✅ 所有验收步骤通过 ✅ 待接单 Tab 显示完整订单信息 ✅ 控制台无大量重复警告日志 ✅ 其他 Tab 和功能正常工作 ✅ 新创建的订单信息完整 ✅ 数据一致性验证通过 --- **最后更新**: 2026-06-10 **负责人**: AI 编码助手 **状态**: 待验收