Files
zyt/ORDER_SUPERVISOR_ROLE_CONFIG_FIX.md
T
2026-04-10 14:43:58 +08:00

8.1 KiB
Raw Blame History

订单管理员角色配置修复

问题描述

编辑业务订单时,关联支付单失败,提示"无权限关联所选支付单"。

错误信息:

{
    "code": 0,
    "show": 1,
    "msg": "无权限关联所选支付单",
    "data": []
}

接口: /adminapi/tcm.prescriptionOrder/edit

问题原因

OrderLogic::isOrderListSupervisor() 方法中硬编码了管理员角色 [0, 3],没有读取配置文件中的 order_edit_all_roles 配置。

配置文件

文件: server/config/project.php

'order_edit_all_roles' => [0, 3, 6],  // 0=超级管理员, 3=管理员, 6=药师

代码问题

文件: server/app/adminapi/logic/order/OrderLogic.php

修改前:

public static function isOrderListSupervisor(int $adminId, array $adminInfo): bool
{
    if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
        return true;
    }
    $supervisorRoles = [0, 3];  // 硬编码,没有读取配置
    $myRoles = array_map('intval', $adminInfo['role_id'] ?? []);

    return count(array_intersect($myRoles, $supervisorRoles)) > 0;
}

问题:

  • 硬编码了 [0, 3],即使配置文件中设置了 [0, 3, 6],角色 6(药师)也无法获得管理员权限
  • 导致药师无法关联其他人创建的支付单

解决方案

修改 isOrderListSupervisor() 方法,从配置文件读取管理员角色列表。

修改后:

public static function isOrderListSupervisor(int $adminId, array $adminInfo): bool
{
    if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
        return true;
    }
    $supervisorRoles = config('project.order_edit_all_roles', [0, 3]);  // 从配置读取
    $myRoles = array_map('intval', $adminInfo['role_id'] ?? []);

    return count(array_intersect($myRoles, $supervisorRoles)) > 0;
}

改进点:

  • 从配置文件读取 order_edit_all_roles
  • 支持动态配置管理员角色
  • 默认值为 [0, 3],保持向后兼容

权限规则

支付单关联权限

在关联支付单到业务订单时,需要满足以下条件之一:

  1. 超级管理员 (root = 1)

    • 可以关联所有支付单
  2. 管理员角色 (order_edit_all_roles 配置的角色)

    • 默认:[0, 3](超级管理员、管理员)
    • 可配置:[0, 3, 6](超级管理员、管理员、药师)
    • 可以关联所有支付单
  3. 诊单医助 (assistant_id 匹配)

    • 可以关联该诊单的所有支付单
  4. 支付单创建人 (creator_id 匹配)

    • 只能关联自己创建的支付单

权限检查逻辑

public static function assertPayOrdersLinkable(array $ids, int $diagnosisId, int $adminId, array $adminInfo): ?string
{
    // ... 其他检查 ...
    
    $supervisor = self::isOrderListSupervisor($adminId, $adminInfo);
    $assistantId = (int) Diagnosis::where('id', $diagnosisId)->value('assistant_id');
    $isDiagAssistant = $assistantId === $adminId;

    foreach ($orders as $o) {
        // 检查权限
        if (! $supervisor && ! $isDiagAssistant && (int) $o->creator_id !== $adminId) {
            return '无权限关联所选支付单';
        }
    }

    return null;
}

配置说明

配置文件位置

server/config/project.php

配置项

return [
    // 订单管理全部权限角色(可以查看和编辑所有订单)
    'order_edit_all_roles' => [0, 3, 6],
    
    // 其他相关配置
    'prescription_library_manage_all_roles' => [0, 3],  // 处方库管理全部权限角色
    'prescription_audit_roles' => [0, 3, 6],            // 处方审核权限角色
    'prescription_order_finance_roles' => [0, 3],       // 处方订单财务权限角色
    'prescription_order_payment_audit_roles' => [0, 3], // 处方订单支付审核权限角色
];

角色ID说明

角色ID 角色名称 说明
0 超级管理员 拥有所有权限
1 医生 开方、诊断等医疗权限
2 医助 协助医生工作
3 管理员 管理订单、审核等权限
6 药师 审核处方、管理药品等权限

使用场景

场景1:药师关联支付单

配置前:

'order_edit_all_roles' => [0, 3],  // 药师(角色6)无权限

问题:

  • 药师无法关联其他人创建的支付单
  • 提示"无权限关联所选支付单"

配置后:

'order_edit_all_roles' => [0, 3, 6],  // 药师(角色6)有权限

效果:

  • 药师可以关联所有支付单
  • 可以正常编辑业务订单

场景2:医生关联支付单

情况1:医生是支付单创建人

  • 可以关联自己创建的支付单
  • 不需要管理员权限

情况2:医生不是支付单创建人

  • 如果医生是诊单医助,可以关联该诊单的所有支付单
  • 如果医生不是诊单医助,无法关联其他人创建的支付单

情况3:医生是管理员角色

  • 如果医生同时拥有管理员角色(如角色3),可以关联所有支付单

场景3:管理员关联支付单

配置:

'order_edit_all_roles' => [0, 3, 6],

效果:

  • 超级管理员(角色0):可以关联所有支付单
  • 管理员(角色3):可以关联所有支付单
  • 药师(角色6):可以关联所有支付单

测试建议

测试用例 1: 药师关联支付单

前提条件:

  • 配置 order_edit_all_roles 包含角色 6
  • 用户角色为药师(角色6

测试步骤:

  1. 创建一个业务订单
  2. 选择其他人创建的支付单
  3. 点击保存

预期结果:

  • 保存成功
  • 支付单成功关联到业务订单

测试用例 2: 医生关联自己的支付单

前提条件:

  • 用户角色为医生(角色1
  • 支付单由该医生创建

测试步骤:

  1. 创建一个业务订单
  2. 选择自己创建的支付单
  3. 点击保存

预期结果:

  • 保存成功
  • 支付单成功关联到业务订单

测试用例 3: 医生关联其他人的支付单(无权限)

前提条件:

  • 用户角色为医生(角色1
  • 支付单由其他人创建
  • 医生不是诊单医助

测试步骤:

  1. 创建一个业务订单
  2. 选择其他人创建的支付单
  3. 点击保存

预期结果:

  • 保存失败
  • 提示"无权限关联所选支付单"

测试用例 4: 诊单医助关联支付单

前提条件:

  • 用户是该诊单的医助
  • 支付单由其他人创建

测试步骤:

  1. 创建一个业务订单
  2. 选择该诊单的支付单(其他人创建)
  3. 点击保存

预期结果:

  • 保存成功
  • 支付单成功关联到业务订单

相关配置

其他权限配置

server/config/project.php 中,还有其他相关的权限配置:

return [
    // 订单管理全部权限角色
    'order_edit_all_roles' => [0, 3, 6],
    
    // 处方库管理全部权限角色(可以查看所有处方)
    'prescription_library_manage_all_roles' => [0, 3],
    
    // 处方审核权限角色
    'prescription_audit_roles' => [0, 3, 6],
    
    // 处方订单财务权限角色(可以查看内部成本)
    'prescription_order_finance_roles' => [0, 3],
    
    // 处方订单支付审核权限角色
    'prescription_order_payment_audit_roles' => [0, 3],
];

配置建议

根据实际业务需求配置角色权限:

推荐配置:

return [
    'order_edit_all_roles' => [0, 3, 6],                // 管理员和药师可以管理所有订单
    'prescription_library_manage_all_roles' => [0, 3],  // 管理员可以查看所有处方
    'prescription_audit_roles' => [0, 3, 6],            // 管理员和药师可以审核处方
    'prescription_order_finance_roles' => [0, 3],       // 管理员可以查看财务数据
    'prescription_order_payment_audit_roles' => [0, 3], // 管理员可以审核支付单
];

总结

通过修改 isOrderListSupervisor() 方法,确保了:

  • 从配置文件读取管理员角色列表
  • 支持动态配置管理员角色
  • 药师(角色6)可以关联所有支付单
  • 保持向后兼容(默认值为 [0, 3]
  • 统一权限管理,避免硬编码

现在,只需要在配置文件中添加角色ID,就可以赋予该角色管理员权限,无需修改代码。