8.1 KiB
8.1 KiB
Supabase Auth ID 与业务用户 ID 映射修复
问题根因
前端和后端混用了两套 ID:
| ID 类型 | 来源 | 示例 | 用途 |
|---|---|---|---|
| Supabase Auth ID | session.user.id / auth.uid() |
311860b5-d99f-478f-b1ac-3ef1cc55ae07 |
Supabase 认证系统 |
| 业务用户 ID | public.ak_users.id |
2a97a39f-4efc-40c6-a065-55a2484e3784 |
所有业务表 |
所有业务表都应该使用业务用户 ID:
ec_care_tasks.assigned_tohc_dispatch_assignments.worker_idhc_worker_locations.worker_idhc_evidence_files.uploader_idhss_service_orders.current_staff_id
数据库映射关系
-- ak_users 表结构
SELECT id, auth_id, username, email, role, user_type, status
FROM public.ak_users;
-- 示例数据
-- id: 2a97a39f-4efc-40c6-a065-55a2484e3784 (业务用户 ID)
-- auth_id: 311860b5-d99f-478f-b1ac-3ef1cc55ae07 (Supabase Auth ID)
-- username: 居家服务员
-- email: homecare_worker@test.com
-- role: delivery
修改文件清单
1. 新增文件
utils/akUserMapping.uts
- 作用:管理 Supabase Auth ID 到业务用户 ID 的映射
- 核心函数:
loadCurrentAkUser()- 登录后加载 ak_users 映射getCurrentAkUserId()- 获取当前业务用户 IDgetCurrentAkUser()- 获取当前业务用户完整信息getCurrentAuthUserId()- 获取当前 Supabase Auth IDdebugCurrentUser()- 调试输出当前用户信息
2. 修改文件
utils/homecareAuth.uts
修改前:
const session = supa.getSession()
const workerId = session != null && session.user != null ? session.user.getString('id') : ''
修改后:
import { getCurrentAkUserId } from '@/utils/akUserMapping.uts'
const workerId = await getCurrentAkUserId()
原因:签到预校验 RPC 需要业务用户 ID,不是 Supabase Auth ID
pages/user/login.uvue
新增:
import { loadCurrentAkUser } from '@/utils/akUserMapping.uts'
// 登录成功后
await loadCurrentAkUser()
原因:登录后立即加载 ak_users 映射,存储到本地缓存
pages/mall/delivery/orders/checkin.uvue
新增:
import { debugCurrentUser } from '@/utils/akUserMapping.uts'
// 预校验前
debugCurrentUser()
原因:调试输出当前 ak_user 信息,方便排查问题
types/delivery.uts
新增字段:
export type DeliveryOrderType = {
// ... existing fields ...
acceptedBy: string // 接单人员 ID(业务用户 ID)
acceptedByName: string // 接单人员姓名
// ... existing fields ...
}
api/delivery.uts
修改:在 mapRpcOrderItemCompat 函数中添加接单人员信息提取:
// 从 statusLog 中提取接单人员信息
order.acceptedBy = ''
order.acceptedByName = ''
const statusLog = order.statusLog
for (let i = 0; i < statusLog.length; i++) {
if (statusLog[i].toStatus == 'accepted' || statusLog[i].toStatus == 'pending_accept') {
order.acceptedBy = statusLog[i].operatorId != '' ? statusLog[i].operatorId : order.deliveryStaffId
order.acceptedByName = statusLog[i].operatorRole != '' ? statusLog[i].operatorRole : order.deliveryStaffName
break
}
}
pages/mall/delivery/orders/index.uvue
新增:订单卡片上显示接单人员
<text v-if="item.acceptedByName != ''" class="meta-text accepted-by"
>接单人:{{ item.acceptedByName }}</text
>
pages/mall/delivery/orders/detail.uvue
新增:服务人员信息卡片
<view class="card">
<text class="section-title">服务人员</text>
<text class="row-text">配送员:{{ order.deliveryStaffName }}</text>
<text v-if="order.acceptedByName != ''" class="row-text"
>接单人:{{ order.acceptedByName }} (ID: {{ order.acceptedBy }})</text
>
<text v-if="order.acceptTime != ''" class="row-text"
>接单时间:{{ formatDateTime(order.acceptTime) }}</text
>
</view>
数据流
登录流程
1. 用户输入邮箱/密码登录
↓
2. Supabase Auth 验证,返回 session (authUserId = 311860b5...)
↓
3. 调用 loginDelivery() 获取 token 和用户信息
↓
4. 调用 loadCurrentAkUser():
- 从 session 获取 authUserId
- 查询 ak_users WHERE auth_id = authUserId
- 获取业务用户 ID (akUserId = 2a97a39f...)
- 存储到本地缓存
↓
5. 登录完成
签到流程
1. 用户点击"距离预校验"
↓
2. checkinPrecheck() 调用 getCurrentAkUserId()
- 从缓存读取 akUserId
- 如果缓存不存在,自动加载
↓
3. 调用 RPC rpc_homecare_checkin_precheck:
p_worker_id = akUserId (2a97a39f...)
↓
4. 后端验证:
- 查询 ec_care_tasks WHERE id = workOrderId
- 检查 assigned_to = p_worker_id
- 如果匹配,返回 canCheckin = true
↓
5. 签到成功
测试步骤
1. 清除旧缓存
在微信开发者工具中:
控制台 -> Storage -> 清除所有缓存
2. 重新登录
- 打开配送端
- 使用测试账号登录:
- 账号:
homecare_worker@test.com - 密码:
Homecare123!
- 账号:
- 登录成功后,控制台应该显示:
[akUserMapping] 加载业务用户成功: { authUserId: '311860b5-d99f-478f-b1ac-3ef1cc55ae07', akUserId: '2a97a39f-4efc-40c6-a065-55a2484e3784', username: '居家服务员', role: 'delivery' }
3. 测试签到
- 进入"待接单"列表
- 点击任意订单接单
- 进入订单详情
- 点击"到达签到"
- 点击"距离预校验"
- 控制台应该显示:
[akUserMapping] ========== 当前用户调试信息 ========== [akUserMapping] authUserId: 311860b5-d99f-478f-b1ac-3ef1cc55ae07 [akUserMapping] akUserId: 2a97a39f-4efc-40c6-a065-55a2484e3784 [akUserMapping] profile: { id: '2a97a39f...', ... } [akUserMapping] ====================================== [CHECKIN RPC] workerId (ak_user_id): 2a97a39f-4efc-40c6-a065-55a2484e3784 - 如果
workerId显示的是2a97a39f...而不是311860b5...,说明修复成功
4. 验证订单列表
- 订单卡片上应该显示接单人员姓名
- 例如:
接单人:居家服务员
验收标准
- 登录后 storage 中同时存在:
auth_user_id=311860b5...ak_user_id=2a97a39f...
checkin.uvue获取定位时使用 gcj02- precheck 调用时
p_worker_id传ak_user_id(2a97a39f...) - 后端返回
reasonCode不再是WORKER_NOT_MATCHED - 数据库
hc_worker_locations.worker_id写入的是2a97a39f...,不是311860b5... - 正式签到 submit 成功后,
hc_work_order_confirmations生成 ARRIVAL / PENDING 记录 - 现场图片
hc_evidence_files.uploader_id使用ak_users.id - 订单列表显示接单人员姓名
注意事项
-
不要使用
session.user.id作为业务用户 ID- 错误:
session.user.id→311860b5... - 正确:
getCurrentAkUserId()→2a97a39f...
- 错误:
-
所有业务表都使用业务用户 ID
ec_care_tasks.assigned_to=2a97a39f...hc_dispatch_assignments.worker_id=2a97a39f...
-
如果 ak_users 映射加载失败
- 不影响登录流程
- 但签到功能会失败
- 需要联系管理员在
ak_users.auth_id字段绑定 Supabase Auth ID
-
配送员 vs 居家服务员
- 配送员:负责配送医药商城的药品、器械
- 居家服务员:负责居家医疗服务
- 当前
ak_users中 username 是"居家服务员",role = delivery 只是 delivery 端角色 - 不等于商城配送员
回滚方案
如果修复后出现问题,可以:
-
清除本地缓存:
微信开发者工具 -> Storage -> 清除所有缓存 -
回滚代码:
git checkout HEAD -- utils/akUserMapping.uts git checkout HEAD -- utils/homecareAuth.uts git checkout HEAD -- pages/user/login.uvue git checkout HEAD -- pages/mall/delivery/orders/checkin.uvue -
重新编译