新增功能
This commit is contained in:
@@ -0,0 +1,351 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user