# userId 格式检查指南 ## 🎯 核心问题 **userId 格式必须完全一致!** 如果格式不一致,会导致: - ❌ 提示"对方不在线"(错误代码 60011) - ❌ 无法接听来电 - ❌ 无法发起通话 ## 📋 正确的格式 ### 医生端(Web) ``` 登录 userId: doctor_1 呼叫目标: patient_2 ``` ### 患者端(小程序) ``` 登录 userId: patient_2 呼叫目标: doctor_1 ``` ## 🔍 检查步骤 ### 步骤 1:检查后端接口 #### 医生端获取签名接口 **接口:** `POST /api/tcm/getCallSignature` **请求:** ```json { "diagnosis_id": 1, "patient_id": 2, "admin_id": 1 } ``` **期望响应:** ```json { "code": 1, "data": { "userId": "doctor_1", // 医生自己的 userId(字符串) "patientUserId": "patient_2", // 要呼叫的患者 userId(字符串) "sdkAppId": "1400xxxxxx", // 字符串或数字都可以 "userSig": "eJw1..." } } ``` **关键检查点:** - [ ] `userId` 是字符串 `"doctor_1"`,不是数字 `1` - [ ] `patientUserId` 是字符串 `"patient_2"`,不是数字 `2` - [ ] 格式统一:都是 `prefix_number` 格式 #### 患者端获取签名接口 **接口:** `GET /api/tcm/getPatientSignature?patient_id=2` **期望响应:** ```json { "code": 1, "data": { "userId": "patient_2", // 患者自己的 userId(字符串) "sdkAppId": "1400xxxxxx", "userSig": "eJw1..." } } ``` **关键检查点:** - [ ] `userId` 是字符串 `"patient_2"`,不是数字 `2` - [ ] 格式与医生端一致:`prefix_number` ### 步骤 2:检查 Web 端日志 **登录时:** ```javascript console.log('=== 发起一对一通话 ===') console.log('后端返回的 patientUserId:', res.patientUserId) // 应该是 "patient_2" console.log('最终使用的 targetUserId:', targetUserId) // 应该是 "patient_2" ``` **关键检查点:** - [ ] `patientUserId` 是字符串 `"patient_2"` - [ ] `targetUserId` 是字符串 `"patient_2"` - [ ] 没有多余的空格或特殊字符 ### 步骤 3:检查小程序端日志 **登录时:** ```javascript console.log('=== 小程序端登录信息 ===') console.log('userId:', userId) // 应该是 "patient_2" ``` **关键检查点:** - [ ] `userId` 是字符串 `"patient_2"` - [ ] 格式与 Web 端一致 ### 步骤 4:对比验证 | 端 | 登录 userId | 呼叫目标 | 格式 | |----|------------|---------|------| | Web(医生) | `doctor_1` | `patient_2` | ✅ 一致 | | 小程序(患者) | `patient_2` | `doctor_1` | ✅ 一致 | **必须满足:** - Web 端呼叫的 `patient_2` === 小程序端登录的 `patient_2` - 小程序端呼叫的 `doctor_1` === Web 端登录的 `doctor_1` ## ⚠️ 常见错误 ### 错误 1:数字 vs 字符串 **错误示例:** ```javascript // ❌ 错误:后端返回数字 { "userId": 1, // 数字 "patientUserId": 2 // 数字 } // ✅ 正确:应该返回字符串 { "userId": "doctor_1", // 字符串 "patientUserId": "patient_2" // 字符串 } ``` **后果:** - Web 端使用 `2` 呼叫 - 小程序端登录为 `"patient_2"` - 格式不匹配,无法通话 ### 错误 2:前缀不一致 **错误示例:** ```javascript // ❌ 错误:前缀不一致 Web 端: "doctor_1" 小程序端: "patient2" // 缺少下划线 // ✅ 正确:前缀一致 Web 端: "doctor_1" 小程序端: "patient_2" // 都使用下划线 ``` ### 错误 3:大小写不一致 **错误示例:** ```javascript // ❌ 错误:大小写不一致 Web 端: "Doctor_1" 小程序端: "doctor_1" // ✅ 正确:大小写一致 Web 端: "doctor_1" 小程序端: "doctor_1" ``` ## 🛠️ 后端代码检查 ### PHP 后端示例 **医生端获取签名:** ```php public static function getCallSignature(array $params) { $adminId = $params['admin_id'] ?? 0; $patientId = $params['patient_id'] ?? 0; // ✅ 正确:使用字符串格式 $doctorUserId = 'doctor_' . $adminId; // "doctor_1" $patientUserId = 'patient_' . $patientId; // "patient_2" // ❌ 错误:不要这样做 // $doctorUserId = $adminId; // 1 // $patientUserId = $patientId; // 2 return [ 'sdkAppId' => (int)$config['sdkAppId'], 'userId' => $doctorUserId, // "doctor_1" 'userSig' => $userSig, 'patientUserId' => $patientUserId, // "patient_2" ]; } ``` **患者端获取签名:** ```php public static function getPatientSignature(int $patientId) { // ✅ 正确:使用字符串格式 $patientUserId = 'patient_' . $patientId; // "patient_2" // ❌ 错误:不要这样做 // $patientUserId = $patientId; // 2 return [ 'sdkAppId' => (int)$config['sdkAppId'], 'userId' => $patientUserId, // "patient_2" 'userSig' => $userSig, ]; } ``` ## 🧪 测试验证 ### 测试 1:打印 userId **Web 端(浏览器控制台):** ```javascript // 在发起通话前 console.log('=== userId 格式检查 ==='); console.log('类型:', typeof res.patientUserId); // 应该是 "string" console.log('值:', res.patientUserId); // 应该是 "patient_2" console.log('长度:', res.patientUserId.length); // 应该是 9 ``` **小程序端(微信开发者工具控制台):** ```javascript // 在登录后 console.log('=== userId 格式检查 ==='); console.log('类型:', typeof userId); // 应该是 "string" console.log('值:', userId); // 应该是 "patient_2" console.log('长度:', userId.length); // 应该是 9 ``` ### 测试 2:对比 userId **在 Web 端发起呼叫时:** ```javascript console.log('=== 对比检查 ==='); console.log('Web 端呼叫目标:', targetUserId); // "patient_2" console.log('小程序端应该登录为:', targetUserId); // "patient_2" console.log('是否完全相等:', targetUserId === "patient_2"); // true ``` ### 测试 3:手动验证 1. **Web 端控制台执行:** ```javascript console.log(JSON.stringify({ type: typeof res.patientUserId, value: res.patientUserId, length: res.patientUserId.length })); ``` 2. **小程序端控制台执行:** ```javascript console.log(JSON.stringify({ type: typeof userId, value: userId, length: userId.length })); ``` 3. **对比结果:** - 类型必须都是 `"string"` - 值必须完全相同 - 长度必须相同 ## 📊 诊断表 | 检查项 | Web 端 | 小程序端 | 状态 | |--------|--------|----------|------| | userId 类型 | string | string | ✅ | | userId 值 | doctor_1 | patient_2 | ✅ | | 呼叫目标类型 | string | string | ✅ | | 呼叫目标值 | patient_2 | doctor_1 | ✅ | | 格式一致性 | prefix_number | prefix_number | ✅ | ## 🔧 修复建议 ### 如果后端返回的是数字 **修改后端代码:** ```php // 在返回前确保转换为字符串 return [ 'userId' => (string)$doctorUserId, // 强制转换为字符串 'patientUserId' => (string)$patientUserId, // ... ]; ``` ### 如果前端收到的是数字 **修改前端代码:** ```javascript // Web 端 const targetUserId = String(res.patientUserId); // 确保是字符串 // 小程序端 const userId = String(signatureData.userId); // 确保是字符串 ``` ## ✅ 验证清单 在测试前,请确认: - [ ] 后端返回的 userId 是字符串格式 - [ ] 后端返回的 patientUserId 是字符串格式 - [ ] Web 端日志显示正确的 userId 格式 - [ ] 小程序端日志显示正确的 userId 格式 - [ ] Web 端呼叫目标与小程序端登录 userId 完全一致 - [ ] 小程序端呼叫目标与 Web 端登录 userId 完全一致 - [ ] 没有多余的空格或特殊字符 - [ ] 大小写完全一致 ## 📞 如果仍然有问题 请提供以下信息: 1. **后端接口响应**(隐藏 userSig): ```json { "userId": "???", "patientUserId": "???", "sdkAppId": "???" } ``` 2. **Web 端日志**: ``` 类型: ??? 值: ??? 长度: ??? ``` 3. **小程序端日志**: ``` 类型: ??? 值: ??? 长度: ??? ``` 4. **具体错误信息**: - 错误代码 - 错误提示 --- **最后更新:** 2024-03-04 **版本:** 1.0