309 lines
8.1 KiB
Markdown
309 lines
8.1 KiB
Markdown
# 订单管理员角色配置修复
|
||
|
||
## 问题描述
|
||
|
||
编辑业务订单时,关联支付单失败,提示"无权限关联所选支付单"。
|
||
|
||
**错误信息**:
|
||
```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,就可以赋予该角色管理员权限,无需修改代码。
|