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

7.2 KiB
Raw Blame History

修复管理员ID获取问题

问题描述

DiagnosisLogic.php 中,多个方法尝试通过 request()->adminInfo['user_id'] 获取当前登录管理员的ID,但这个方式获取到的值为空。

错误代码示例

// ❌ 错误的方式
$adminId = request()->adminInfo['user_id'] ?? 0;  // 返回 0

问题原因

  1. 键名错误:管理员信息中的ID键名是 admin_id,不是 user_id
  2. 访问方式错误Logic层不应该直接访问 request() 对象
  3. 架构问题:应该由Controller层传递参数到Logic层

BaseAdminController 的实现

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 方法

// 修改前
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 方法

// 修改后
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 方法

// 修改后
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 方法

// 修改前
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 方法

// 修改前
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 方法

// 修改前
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. 测试获取通话签名

# 登录管理后台
# 进入诊单详情页
# 点击"视频通话"按钮
# 查看日志
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. 测试发起通话

# 点击"发起通话"按钮
# 查看数据库
SELECT * FROM zyt_tcm_call_record ORDER BY id DESC LIMIT 1;

预期结果

  • caller_id 应该是当前管理员的ID(如:1
  • 不应该是 0

3. 测试结束通话

# 点击"结束通话"按钮
# 查看数据库
SELECT * FROM zyt_tcm_call_record WHERE status = 2 ORDER BY id DESC LIMIT 1;

预期结果

  • 通话记录的 status 应该变为 2
  • end_timeduration 应该有值

验证清单

  • 点击"视频通话"按钮,能正常获取签名
  • 日志显示正确的 admin_id(不是0)
  • 医生IM账号导入成功
  • 发起通话时,call_record 表的 caller_id 正确
  • 结束通话时,通话记录正确更新

相关文档

技术要点

1. ThinkPHP 架构最佳实践

// ✅ 推荐: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. 参数验证

// ✅ 添加参数验证
$adminId = $params['admin_id'] ?? 0;

if (!$adminId) {
    self::setError('获取管理员信息失败');
    return false;
}

3. 错误处理

// ✅ 提供明确的错误信息
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账号导入功能应该能正常工作了!