# 修复管理员ID获取问题 ## 问题描述 在 `DiagnosisLogic.php` 中,多个方法尝试通过 `request()->adminInfo['user_id']` 获取当前登录管理员的ID,但这个方式获取到的值为空。 ### 错误代码示例 ```php // ❌ 错误的方式 $adminId = request()->adminInfo['user_id'] ?? 0; // 返回 0 ``` ## 问题原因 1. **键名错误**:管理员信息中的ID键名是 `admin_id`,不是 `user_id` 2. **访问方式错误**:Logic层不应该直接访问 `request()` 对象 3. **架构问题**:应该由Controller层传递参数到Logic层 ### BaseAdminController 的实现 ```php class BaseAdminController extends BaseLikeAdminController { protected int $adminId = 0; protected array $adminInfo = []; public function initialize() { if (isset($this->request->adminInfo) && $this->request->adminInfo) { $this->adminInfo = $this->request->adminInfo; $this->adminId = $this->request->adminInfo['admin_id']; // ✅ 正确的键名 } } } ``` ## 解决方案 ### 方案:Controller传递参数到Logic **原则**: - Controller层负责获取管理员信息 - 通过参数传递给Logic层 - Logic层不直接访问request对象 ## 修改内容 ### 1. DiagnosisController.php #### getCallSignature 方法 ```php // 修改前 public function getCallSignature() { $params = $this->request->post(); // ... 验证参数 $result = DiagnosisLogic::getCallSignature($params); // ... } // 修改后 public function getCallSignature() { $params = $this->request->post(); // ... 验证参数 // ✅ 传递当前管理员ID $params['admin_id'] = $this->adminId; $result = DiagnosisLogic::getCallSignature($params); // ... } ``` #### startCall 方法 ```php // 修改后 public function startCall() { $params = $this->request->post(); if (empty($params['diagnosis_id'])) { return $this->fail('诊单ID不能为空'); } // ✅ 传递当前管理员ID $params['admin_id'] = $this->adminId; $result = DiagnosisLogic::startCall($params); // ... } ``` #### endCall 方法 ```php // 修改后 public function endCall() { $params = $this->request->post(); if (empty($params['diagnosis_id'])) { return $this->fail('诊单ID不能为空'); } // ✅ 传递当前管理员ID $params['admin_id'] = $this->adminId; $result = DiagnosisLogic::endCall($params); // ... } ``` ### 2. DiagnosisLogic.php #### getCallSignature 方法 ```php // 修改前 public static function getCallSignature(array $params) { // ❌ 错误的获取方式 $adminId = request()->adminInfo['user_id'] ?? 0; $userId = 'doctor_' . $adminId; // ... } // 修改后 public static function getCallSignature(array $params) { // ✅ 从参数中获取 $adminId = $params['admin_id'] ?? 0; if (!$adminId) { self::setError('获取管理员信息失败'); return false; } $userId = 'doctor_' . $adminId; // ... } ``` #### startCall 方法 ```php // 修改前 public static function startCall(array $params): bool { // ❌ 错误的获取方式 $adminId = request()->adminInfo['user_id'] ?? 0; // ... } // 修改后 public static function startCall(array $params): bool { // ✅ 从参数中获取 $adminId = $params['admin_id'] ?? 0; if (!$adminId) { self::setError('获取管理员信息失败'); return false; } // ... } ``` #### endCall 方法 ```php // 修改前 public static function endCall(array $params): bool { // ❌ 错误的获取方式 $adminId = request()->adminInfo['user_id'] ?? 0; // ... } // 修改后 public static function endCall(array $params): bool { // ✅ 从参数中获取 $adminId = $params['admin_id'] ?? 0; if (!$adminId) { self::setError('获取管理员信息失败'); return false; } // ... } ``` ## 影响范围 ### 修改的文件 1. `server/app/adminapi/controller/tcm/DiagnosisController.php` 2. `server/app/adminapi/logic/tcm/DiagnosisLogic.php` ### 修改的方法 1. `getCallSignature()` - 获取通话签名 2. `startCall()` - 发起通话 3. `endCall()` - 结束通话 ### 不影响的功能 - 患者账号创建(使用的是诊单中的patient_id) - 管理员账号创建(使用的是Admin模型的ID) - 其他诊单相关功能 ## 测试方法 ### 1. 测试获取通话签名 ```bash # 登录管理后台 # 进入诊单详情页 # 点击"视频通话"按钮 # 查看日志 tail -f server/runtime/adminapi/log/当前日期.log ``` **预期日志**: ``` [info] 开始导入医生IM账号 - admin_id: 1, user_id: doctor_1, name: 管理员 [info] 医生IM账号导入成功 - admin_id: 1, user_id: doctor_1 ``` **不应该出现**: ``` [error] 获取管理员信息失败 [info] admin_id: 0 // ❌ ID为0说明获取失败 ``` ### 2. 测试发起通话 ```bash # 点击"发起通话"按钮 # 查看数据库 SELECT * FROM zyt_tcm_call_record ORDER BY id DESC LIMIT 1; ``` **预期结果**: - `caller_id` 应该是当前管理员的ID(如:1) - 不应该是 0 ### 3. 测试结束通话 ```bash # 点击"结束通话"按钮 # 查看数据库 SELECT * FROM zyt_tcm_call_record WHERE status = 2 ORDER BY id DESC LIMIT 1; ``` **预期结果**: - 通话记录的 `status` 应该变为 2 - `end_time` 和 `duration` 应该有值 ## 验证清单 - [ ] 点击"视频通话"按钮,能正常获取签名 - [ ] 日志显示正确的 admin_id(不是0) - [ ] 医生IM账号导入成功 - [ ] 发起通话时,call_record 表的 caller_id 正确 - [ ] 结束通话时,通话记录正确更新 ## 相关文档 - [DOCTOR_IM_ACCOUNT.md](./DOCTOR_IM_ACCOUNT.md) - 医生账号导入功能 - [IM_ACCOUNT_IMPORT.md](./IM_ACCOUNT_IMPORT.md) - IM账号导入完整文档 ## 技术要点 ### 1. ThinkPHP 架构最佳实践 ```php // ✅ 推荐:Controller传递参数 class Controller { public function action() { $params['admin_id'] = $this->adminId; Logic::method($params); } } class Logic { public static function method($params) { $adminId = $params['admin_id']; } } // ❌ 不推荐:Logic直接访问request class Logic { public static function method($params) { $adminId = request()->adminInfo['admin_id']; // 耦合度高 } } ``` ### 2. 参数验证 ```php // ✅ 添加参数验证 $adminId = $params['admin_id'] ?? 0; if (!$adminId) { self::setError('获取管理员信息失败'); return false; } ``` ### 3. 错误处理 ```php // ✅ 提供明确的错误信息 if (!$adminId) { self::setError('获取管理员信息失败'); return false; } // ❌ 不要静默失败 $adminId = $params['admin_id'] ?? 0; // 如果为0,后续逻辑会出错 ``` ## 更新日志 ### 2026-03-02 - ✅ 修复 `getCallSignature()` 方法获取管理员ID失败的问题 - ✅ 修复 `startCall()` 方法获取管理员ID失败的问题 - ✅ 修复 `endCall()` 方法获取管理员ID失败的问题 - ✅ 改进架构:Controller传递参数到Logic - ✅ 添加参数验证和错误处理 --- **现在管理员ID可以正确获取,医生IM账号导入功能应该能正常工作了!** ✅