# 订单管理员角色配置修复 ## 问题描述 编辑业务订单时,关联支付单失败,提示"无权限关联所选支付单"。 **错误信息**: ```json { "code": 0, "show": 1, "msg": "无权限关联所选支付单", "data": [] } ``` **接口**: `/adminapi/tcm.prescriptionOrder/edit` ## 问题原因 `OrderLogic::isOrderListSupervisor()` 方法中硬编码了管理员角色 `[0, 3]`,没有读取配置文件中的 `order_edit_all_roles` 配置。 ### 配置文件 **文件**: `server/config/project.php` ```php 'order_edit_all_roles' => [0, 3, 6], // 0=超级管理员, 3=管理员, 6=药师 ``` ### 代码问题 **文件**: `server/app/adminapi/logic/order/OrderLogic.php` **修改前**: ```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()` 方法,从配置文件读取管理员角色列表。 **修改后**: ```php 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` 匹配) - 只能关联自己创建的支付单 ### 权限检查逻辑 ```php 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` ### 配置项 ```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:药师关联支付单 **配置前**: ```php 'order_edit_all_roles' => [0, 3], // 药师(角色6)无权限 ``` **问题**: - 药师无法关联其他人创建的支付单 - 提示"无权限关联所选支付单" **配置后**: ```php 'order_edit_all_roles' => [0, 3, 6], // 药师(角色6)有权限 ``` **效果**: - 药师可以关联所有支付单 - 可以正常编辑业务订单 ### 场景2:医生关联支付单 **情况1:医生是支付单创建人** - 可以关联自己创建的支付单 - 不需要管理员权限 **情况2:医生不是支付单创建人** - 如果医生是诊单医助,可以关联该诊单的所有支付单 - 如果医生不是诊单医助,无法关联其他人创建的支付单 **情况3:医生是管理员角色** - 如果医生同时拥有管理员角色(如角色3),可以关联所有支付单 ### 场景3:管理员关联支付单 **配置**: ```php '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` 中,还有其他相关的权限配置: ```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], ]; ``` ### 配置建议 根据实际业务需求配置角色权限: **推荐配置**: ```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], // 管理员可以审核支付单 ]; ``` ## 总结 通过修改 `isOrderListSupervisor()` 方法,确保了: - ✅ 从配置文件读取管理员角色列表 - ✅ 支持动态配置管理员角色 - ✅ 药师(角色6)可以关联所有支付单 - ✅ 保持向后兼容(默认值为 `[0, 3]`) - ✅ 统一权限管理,避免硬编码 现在,只需要在配置文件中添加角色ID,就可以赋予该角色管理员权限,无需修改代码。