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

309 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 订单管理员角色配置修复
## 问题描述
编辑业务订单时,关联支付单失败,提示"无权限关联所选支付单"。
**错误信息**:
```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,就可以赋予该角色管理员权限,无需修改代码。