Files
zyt/IM_ACCOUNT_IMPORT.md
T
2026-03-04 15:32:30 +08:00

9.1 KiB

腾讯云IM账号导入功能

问题说明

之前的实现只是在本地数据库创建了患者TRTC账号记录,但没有在腾讯云IM后台创建账号。这导致:

  • 腾讯云IM账户管理里看不到这个账户
  • 使用TUICallKit时无法找到用户
  • 无法发起音视频通话

解决方案

TUICallKit 基于腾讯云IM

TUICallKit 是基于**腾讯云IM(即时通信)**的音视频通话组件,而不是单纯的TRTC。因此需要:

  1. 生成 UserSig(本地签名)
  2. 调用IM REST API导入账号到腾讯云
  3. 账号才能在腾讯云后台看到并使用

实现流程

新增/编辑诊单
    ↓
生成 patient_id
    ↓
生成 UserSig(本地)
    ↓
保存到本地数据库
    ↓
调用腾讯云IM API导入账号 ⭐ 新增
    ↓
账号出现在腾讯云后台
    ↓
可以使用TUICallKit通话

技术实现

1. 创建IM服务类

文件: server/app/common/service/TencentImService.php

功能:

  • 生成管理员UserSig
  • 调用IM REST API导入账号
  • 支持单个和批量导入
  • 支持删除账号

核心方法:

// 导入单个账号
public function importAccount(string $userId, string $nick = '', string $faceUrl = '')

// 批量导入账号
public function batchImportAccounts(array $accounts)

// 删除账号
public function deleteAccounts(array $userIds)

2. API接口

接口地址: https://console.tim.qq.com/v4/im_open_login_svc/account_import

请求方法: POST

请求参数:

{
  "UserID": "patient_100001",
  "Nick": "张三",
  "FaceUrl": "http://example.com/avatar.jpg"
}

响应示例:

{
  "ActionStatus": "OK",
  "ErrorCode": 0,
  "ErrorInfo": ""
}

3. 自动导入逻辑

患者账号导入

触发时机: 新增或编辑诊单时

代码位置: server/app/adminapi/logic/tcm/DiagnosisLogic.php

private static function createPatientTrtcAccount(int $patientId): bool
{
    // 1. 生成UserSig并保存到数据库
    // ...
    
    // 2. 导入账号到腾讯云IM ⭐ 新增
    self::importAccountToTencentIm($patientId, $userId);
    
    return true;
}

private static function importAccountToTencentIm(int $patientId, string $userId): bool
{
    // 获取患者信息
    $diagnosis = Diagnosis::where('patient_id', $patientId)
        ->order('id', 'desc')
        ->find();
    
    $nick = $diagnosis ? $diagnosis->patient_name : '患者' . $patientId;
    
    // 调用IM服务导入账号
    $imService = new \app\common\service\TencentImService();
    $result = $imService->importAccount($userId, $nick);
    
    return $result['success'];
}

医生账号导入

触发时机: 新增或编辑管理员时

代码位置: server/app/adminapi/logic/auth/AdminLogic.php

public static function add(array $params)
{
    // 1. 创建管理员账号
    $admin = Admin::create([...]);
    
    // 2. 分配角色、部门、岗位
    // ...
    
    // 3. 导入医生账号到腾讯云IM ⭐ 新增
    self::importDoctorAccountToIm($admin['id'], $params['name']);
    
    return true;
}

public static function edit(array $params): bool
{
    // 1. 更新管理员信息
    Admin::update($data);
    
    // 2. 更新角色、部门、岗位
    // ...
    
    // 3. 导入医生账号到腾讯云IM ⭐ 新增
    self::importDoctorAccountToIm($params['id'], $params['name']);
    
    return true;
}

private static function importDoctorAccountToIm($adminId, $name)
{
    $userId = 'doctor_' . $adminId;
    
    $imService = new TencentImService();
    $result = $imService->importAccount($userId, $name);
    
    if ($result) {
        Log::info('医生IM账号导入成功 - admin_id: ' . $adminId);
    }
}

使用方式

方式1: 自动导入(推荐)

患者账号

  1. 新增或编辑诊单
  2. 系统自动:
    • 生成 patient_id
    • 生成 UserSig
    • 保存到数据库
    • 调用IM API导入账号
  3. 完成!账号已在腾讯云后台

医生账号

  1. 新增或编辑管理员
  2. 系统自动:
    • 生成 doctor_{admin_id}
    • 生成 UserSig
    • 调用IM API导入账号
  3. 完成!账号已在腾讯云后台

方式2: 手动导入(测试用)

use app\common\service\TencentImService;

$imService = new TencentImService();

// 导入单个账号
$result = $imService->importAccount('patient_100001', '张三', 'http://example.com/avatar.jpg');

// 批量导入
$accounts = [
    ['userId' => 'patient_100001', 'nick' => '张三'],
    ['userId' => 'patient_100002', 'nick' => '李四'],
];
$results = $imService->batchImportAccounts($accounts);

验证方法

1. 查看日志

# 查看导入成功日志
tail -f server/runtime/log/info.log | grep "导入.*IM账号成功"

# 应该看到:
# [info] 导入患者IM账号成功 {"patient_id":100001,"user_id":"patient_100001","nick":"张三"}
# [info] 导入医生IM账号成功 {"admin_id":1,"user_id":"doctor_1","nick":"管理员"}

2. 查看腾讯云控制台

  1. 登录腾讯云控制台
  2. 进入"即时通信IM"
  3. 选择你的应用
  4. 进入"账号管理"
  5. 应该能看到 patient_100001doctor_1 等账号

3. 测试通话

1. 医生端:点击"视频通话"
2. 患者端:打开测试页面
3. 医生端:发起通话
4. ✅ 患者端收到来电
5. ✅ 可以正常通话

日志记录

成功日志

[info] 创建患者 TRTC 账号 {"patient_id":100001,"user_id":"patient_100001"}
[info] 导入患者IM账号成功 {"patient_id":100001,"user_id":"patient_100001","nick":"张三"}
[info] 导入医生IM账号成功 {"admin_id":1,"user_id":"doctor_1","nick":"管理员"}

失败日志

[warning] 导入患者IM账号失败 {"patient_id":100001,"user_id":"patient_100001","error":"Invalid parameters"}
[error] 导入患者IM账号异常 {"patient_id":100001,"user_id":"patient_100001","error":"网络错误"}

错误处理

错误码说明

错误码 说明 解决方案
40006 服务器内部错误 稍后重试
40601 字段值超过长度限制 检查昵称长度
70169 服务器超时 稍后重试
70398 账号数量超限 升级到专业版
70402 参数无效 检查参数格式
70403 需要管理员权限 检查UserSig
70500 服务器内部错误 稍后重试

常见问题

问题1: 导入失败 - 70402 参数无效

原因: UserID格式不正确或必填参数缺失

解决:

  • 检查 UserID 是否符合规范(字母、数字、下划线)
  • 检查 UserID 长度(最多32字节)

问题2: 导入失败 - 70403 权限不足

原因: 管理员UserSig生成失败或过期

解决:

  • 检查 SDKAppID 和 SecretKey 是否正确
  • 重新生成管理员UserSig

问题3: 重复导入

说明: 重复导入同一个账号不会报错,IM会自动忽略

行为:

  • 第一次导入:创建账号
  • 后续导入:更新昵称和头像(如果提供)

配置要求

1. TRTC配置

# server/.env
[TRTC]
SDK_APP_ID = "你的SDKAppID"
SECRET_KEY = "你的密钥"
ENABLE = "true"

2. 管理员账号

默认管理员账号: administrator

如需修改,编辑 TencentImService.php:

private $adminIdentifier = 'your_admin_id';

3. 网络要求

  • 服务器需要能访问 console.tim.qq.com
  • 开放 HTTPS (443) 端口
  • 支持 cURL 扩展

性能优化

1. 异步导入

对于大量账号导入,建议使用队列异步处理:

// 添加到队列
Queue::push(ImportImAccountJob::class, [
    'userId' => 'patient_100001',
    'nick' => '张三'
]);

2. 批量导入

使用批量导入API可以提高效率:

$accounts = [
    ['userId' => 'patient_100001', 'nick' => '张三'],
    ['userId' => 'patient_100002', 'nick' => '李四'],
    // ... 最多100个
];
$imService->batchImportAccounts($accounts);

3. 缓存检查

避免重复导入已存在的账号:

// 检查是否已导入
$cache = Cache::get('im_account_' . $userId);
if (!$cache) {
    $imService->importAccount($userId, $nick);
    Cache::set('im_account_' . $userId, true, 86400);
}

安全建议

1. UserSig安全

  • 不要在前端生成UserSig
  • 在后端生成并通过API返回
  • 设置合理的过期时间

2. 管理员权限

  • 不要暴露管理员UserSig
  • 仅在服务端使用
  • 定期更换SecretKey

3. 参数验证

  • 验证UserID格式
  • 过滤特殊字符
  • 限制昵称长度

相关文档

更新日志

v1.1.0 (2024-03-02)

  • 新增腾讯云IM账号导入功能
  • 创建 TencentImService 服务类
  • 患者账号自动导入到IM
  • 医生账号自动导入到IM
  • 支持批量导入和删除
  • 完善日志记录和错误处理

现在账号会自动导入到腾讯云IM后台,可以在控制台看到并正常使用TUICallKit! 🎉