Files
medical-mall/docs/AUTH_ID_MAPPING_FIX.md
2026-06-12 10:16:27 +08:00

297 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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_to`
- `hc_dispatch_assignments.worker_id`
- `hc_worker_locations.worker_id`
- `hc_evidence_files.uploader_id`
- `hss_service_orders.current_staff_id`
## 数据库映射关系
```sql
-- 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()` - 获取当前业务用户 ID
- `getCurrentAkUser()` - 获取当前业务用户完整信息
- `getCurrentAuthUserId()` - 获取当前 Supabase Auth ID
- `debugCurrentUser()` - 调试输出当前用户信息
### 2. 修改文件
#### `utils/homecareAuth.uts`
**修改前**
```uts
const session = supa.getSession()
const workerId = session != null && session.user != null ? session.user.getString('id') : ''
```
**修改后**
```uts
import { getCurrentAkUserId } from '@/utils/akUserMapping.uts'
const workerId = await getCurrentAkUserId()
```
**原因**:签到预校验 RPC 需要业务用户 ID不是 Supabase Auth ID
#### `pages/user/login.uvue`
**新增**
```uts
import { loadCurrentAkUser } from '@/utils/akUserMapping.uts'
// 登录成功后
await loadCurrentAkUser()
```
**原因**:登录后立即加载 ak_users 映射,存储到本地缓存
#### `pages/mall/delivery/orders/checkin.uvue`
**新增**
```uts
import { debugCurrentUser } from '@/utils/akUserMapping.uts'
// 预校验前
debugCurrentUser()
```
**原因**:调试输出当前 ak_user 信息,方便排查问题
#### `types/delivery.uts`
**新增字段**
```uts
export type DeliveryOrderType = {
// ... existing fields ...
acceptedBy: string // 接单人员 ID业务用户 ID
acceptedByName: string // 接单人员姓名
// ... existing fields ...
}
```
#### `api/delivery.uts`
**修改**:在 `mapRpcOrderItemCompat` 函数中添加接单人员信息提取:
```uts
// 从 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`
**新增**:订单卡片上显示接单人员
```html
<text v-if="item.acceptedByName != ''" class="meta-text accepted-by"
>接单人:{{ item.acceptedByName }}</text
>
```
#### `pages/mall/delivery/orders/detail.uvue`
**新增**:服务人员信息卡片
```html
<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. 重新登录
1. 打开配送端
2. 使用测试账号登录:
- 账号:`homecare_worker@test.com`
- 密码:`Homecare123!`
3. 登录成功后,控制台应该显示:
```
[akUserMapping] 加载业务用户成功: {
authUserId: '311860b5-d99f-478f-b1ac-3ef1cc55ae07',
akUserId: '2a97a39f-4efc-40c6-a065-55a2484e3784',
username: '居家服务员',
role: 'delivery'
}
```
### 3. 测试签到
1. 进入"待接单"列表
2. 点击任意订单接单
3. 进入订单详情
4. 点击"到达签到"
5. 点击"距离预校验"
6. 控制台应该显示:
```
[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
```
7. 如果 `workerId` 显示的是 `2a97a39f...` 而不是 `311860b5...`,说明修复成功
### 4. 验证订单列表
1. 订单卡片上应该显示接单人员姓名
2. 例如:`接单人:居家服务员`
## 验收标准
- [ ] 登录后 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`
- [ ] 订单列表显示接单人员姓名
## 注意事项
1. **不要使用 `session.user.id` 作为业务用户 ID**
- 错误:`session.user.id` → `311860b5...`
- 正确:`getCurrentAkUserId()` → `2a97a39f...`
2. **所有业务表都使用业务用户 ID**
- `ec_care_tasks.assigned_to` = `2a97a39f...`
- `hc_dispatch_assignments.worker_id` = `2a97a39f...`
3. **如果 ak_users 映射加载失败**
- 不影响登录流程
- 但签到功能会失败
- 需要联系管理员在 `ak_users.auth_id` 字段绑定 Supabase Auth ID
4. **配送员 vs 居家服务员**
- 配送员:负责配送医药商城的药品、器械
- 居家服务员:负责居家医疗服务
- 当前 `ak_users` 中 username 是"居家服务员"role = delivery 只是 delivery 端角色
- 不等于商城配送员
## 回滚方案
如果修复后出现问题,可以:
1. 清除本地缓存:
```
微信开发者工具 -> Storage -> 清除所有缓存
```
2. 回滚代码:
```bash
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
```
3. 重新编译