239 lines
8.5 KiB
Markdown
239 lines
8.5 KiB
Markdown
# 配送端"待接单"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 编码助手
|
||
**状态**: 待验收
|