# 处方审核通过后锁定编辑和作废
## 修改说明
处方审核通过后,禁止编辑和作废操作,确保已审核通过的处方不被修改,保证处方的完整性和可追溯性。
## 修改内容
### 1. 前端修改
**文件**: `admin/src/views/consumer/prescription/index.vue`
#### 编辑按钮
**修改前**:
```vue
编辑
```
**修改后**:
```vue
编辑
```
**改进点**:
- 移除了业务订单驳回的例外情况
- 只要处方审核通过且未作废,就不显示编辑按钮
- 简化了逻辑,更加严格
#### 删除按钮
删除按钮已经使用了 `isApprovedActivePrescription(row)` 判断,无需修改:
```vue
删除
```
#### 判断函数
```typescript
/** 已通过审核且未作废:仅可查看,不可编辑/删除 */
function isApprovedActivePrescription(row: { audit_status?: number; void_status?: number }) {
return Number(row.audit_status) === 1 && Number(row.void_status) !== 1
}
```
### 2. 后端修改
**文件**: `server/app/adminapi/logic/tcm/PrescriptionLogic.php`
#### 编辑方法
**修改前**:
```php
// 已通过且未作废:不可编辑;例外:业务订单「处方审核」已驳回时允许医生改方,保存后业务订单侧审核会重置为待审
if ((int) ($prescription->audit_status ?? 1) === 1 && (int) ($prescription->void_status ?? 0) === 0) {
if (!PrescriptionOrderLogic::allowDoctorEditApprovedPrescriptionDueToBusinessReject((int) $params['id'])) {
self::setError('该处方已通过审核,不可编辑');
return false;
}
}
```
**修改后**:
```php
// 已通过且未作废:不可编辑
if ((int) ($prescription->audit_status ?? 1) === 1 && (int) ($prescription->void_status ?? 0) === 0) {
self::setError('该处方已通过审核,不可编辑');
return false;
}
```
**改进点**:
- 移除了业务订单驳回的例外情况
- 简化了逻辑,更加严格
- 不再调用 `PrescriptionOrderLogic::allowDoctorEditApprovedPrescriptionDueToBusinessReject()`
#### 删除方法
删除方法已经有正确的检查,无需修改:
```php
public static function delete(int $id): bool
{
try {
$prescription = Prescription::find($id);
if (!$prescription) {
self::setError('处方不存在');
return false;
}
if ((int) ($prescription->audit_status ?? 1) === 1 && (int) ($prescription->void_status ?? 0) === 0) {
self::setError('该处方已通过审核,不可删除');
return false;
}
$prescription->delete();
return true;
} catch (\Exception $e) {
self::setError($e->getMessage());
return false;
}
}
```
#### 审核方法(作废)
审核驳回会同时作废处方,已经有正确的状态检查:
```php
public static function audit(int $id, string $action, string $remark, int $adminId, array $adminInfo): bool
{
// ...
// 只有待审核状态才能进行审核
if ((int) ($row->audit_status ?? 1) !== 0) {
self::setError('当前状态不可审核');
return false;
}
// ...
if ($action === 'reject') {
if (trim($remark) === '') {
self::setError('驳回时请填写审核意见');
return false;
}
$row->audit_status = 2;
$row->audit_time = $now;
$row->audit_by = $adminId;
$row->audit_by_name = $name;
$row->audit_remark = $remark;
$row->void_status = 1; // 驳回时同时作废
$row->void_time = $now;
$row->void_by = $adminId;
$row->void_by_name = $name;
$ok = (bool) $row->save();
if ($ok) {
self::$lastAuditWecomNotify = self::notifyCreatorAuditResult($row, 'reject', $remark, $adminInfo);
}
return $ok;
}
// ...
}
```
## 权限规则
### 编辑权限
处方可以编辑的条件:
1. **待审核状态** (`audit_status = 0`)
2. **已驳回状态** (`audit_status = 2`),且满足以下条件:
- 该诊单当天没有其他已通过的处方
- 编辑后会清除驳回状态,重新进入待审核
处方不可编辑的条件:
1. **已通过审核且未作废** (`audit_status = 1` && `void_status = 0`)
- 即使业务订单驳回了处方审核,也不允许编辑
- 必须先撤回业务订单,处方审核状态会重置为待审核,然后才能编辑
### 删除权限
处方可以删除的条件:
1. **待审核状态** (`audit_status = 0`)
2. **已驳回状态** (`audit_status = 2`)
3. **已作废状态** (`void_status = 1`)
处方不可删除的条件:
1. **已通过审核且未作废** (`audit_status = 1` && `void_status = 0`)
### 作废权限(审核驳回)
处方可以作废的条件:
1. **待审核状态** (`audit_status = 0`)
2. 有审核权限的用户
处方不可作废的条件:
1. **已通过审核** (`audit_status = 1`)
2. **已驳回** (`audit_status = 2`)
## 业务流程
### 场景1:处方审核通过后需要修改
**旧流程**(已废弃):
1. 处方审核通过
2. 创建业务订单
3. 业务订单处方审核驳回
4. 医生可以直接编辑已通过的处方 ❌
**新流程**(推荐):
1. 处方审核通过
2. 创建业务订单
3. 业务订单处方审核驳回
4. 管理员撤回业务订单(处方审核状态重置为待审核)
5. 医生编辑处方
6. 处方重新审核
7. 创建新的业务订单
### 场景2:处方审核通过后发现错误
**解决方案**:
1. 如果已创建业务订单,先撤回业务订单
2. 处方审核状态会自动重置为待审核
3. 医生编辑处方
4. 处方重新审核
5. 创建新的业务订单
### 场景3:处方审核驳回后修改
**流程**:
1. 处方审核驳回(同时作废)
2. 医生编辑处方(编辑后会清除驳回和作废状态)
3. 处方重新进入待审核状态
4. 重新审核
## 优势
### 1. 数据完整性
- 已审核通过的处方不可修改,保证了处方的完整性
- 避免审核后的处方被随意修改,导致审核记录与实际内容不符
### 2. 可追溯性
- 每次修改都需要重新审核,留下完整的审核记录
- 便于追溯处方的修改历史和审核历史
### 3. 流程规范
- 强制执行"撤回 → 编辑 → 重新审核"的流程
- 避免绕过审核流程直接修改处方
### 4. 责任明确
- 审核人员对已审核的处方负责
- 修改处方需要重新审核,责任链清晰
## 注意事项
### 1. 业务订单撤回
如果需要修改已审核通过的处方,必须先撤回业务订单:
- 撤回业务订单会自动重置处方审核状态为待审核
- 撤回后才能编辑处方
- 编辑后需要重新审核处方
- 审核通过后可以创建新的业务订单
### 2. 处方驳回
处方驳回会同时作废处方:
- 驳回后处方状态变为"已驳回"(`audit_status = 2`)
- 同时处方会被作废(`void_status = 1`)
- 医生可以编辑已驳回的处方
- 编辑后会清除驳回和作废状态,重新进入待审核
### 3. 权限配置
确保相关权限配置正确:
- `cf.prescription/edit` - 编辑处方权限
- `cf.prescription/del` - 删除处方权限
- `cf.prescription/audit` - 审核处方权限
- `tcm.prescriptionOrder/withdraw` - 撤回业务订单权限
## 测试建议
### 1. 编辑权限测试
**测试用例 1: 待审核处方可以编辑**
- 创建处方(待审核状态)
- 点击"编辑"按钮
- 预期:可以正常编辑
**测试用例 2: 已通过处方不可编辑**
- 创建处方并审核通过
- 点击"编辑"按钮
- 预期:按钮不显示或提示"该处方已通过审核,不可编辑"
**测试用例 3: 业务订单驳回后不可直接编辑**
- 创建处方并审核通过
- 创建业务订单
- 业务订单处方审核驳回
- 点击"编辑"按钮
- 预期:按钮不显示或提示"该处方已通过审核,不可编辑"
**测试用例 4: 撤回业务订单后可以编辑**
- 创建处方并审核通过
- 创建业务订单
- 撤回业务订单
- 点击"编辑"按钮
- 预期:可以正常编辑
**测试用例 5: 已驳回处方可以编辑**
- 创建处方
- 审核驳回
- 点击"编辑"按钮
- 预期:可以正常编辑,编辑后清除驳回和作废状态
### 2. 删除权限测试
**测试用例 6: 待审核处方可以删除**
- 创建处方(待审核状态)
- 点击"删除"按钮
- 预期:可以正常删除
**测试用例 7: 已通过处方不可删除**
- 创建处方并审核通过
- 点击"删除"按钮
- 预期:按钮不显示或提示"该处方已通过审核,不可删除"
**测试用例 8: 已驳回处方可以删除**
- 创建处方
- 审核驳回
- 点击"删除"按钮
- 预期:可以正常删除
### 3. 作废权限测试
**测试用例 9: 待审核处方可以驳回作废**
- 创建处方(待审核状态)
- 点击"审核"按钮,选择"驳回"
- 预期:处方被驳回并作废
**测试用例 10: 已通过处方不可驳回作废**
- 创建处方并审核通过
- 点击"审核"按钮
- 预期:按钮不显示或提示"当前状态不可审核"
**测试用例 11: 已驳回处方不可再次驳回**
- 创建处方
- 审核驳回
- 再次点击"审核"按钮
- 预期:按钮不显示或提示"当前状态不可审核"
### 4. 业务流程测试
**测试用例 12: 完整的修改流程**
1. 创建处方并审核通过
2. 创建业务订单
3. 业务订单处方审核驳回
4. 尝试编辑处方 → 预期:不可编辑
5. 撤回业务订单
6. 编辑处方 → 预期:可以编辑
7. 处方重新审核通过
8. 创建新的业务订单 → 预期:成功
## 相关文档
- `PRESCRIPTION_ORDER_WITHDRAW_RESET_AUDIT.md` - 订单撤回重置审核状态文档
- `BUG_FIXES_SUMMARY.md` - Bug修复总结文档
## 总结
通过移除业务订单驳回的例外情况,确保了:
- ✅ 已审核通过的处方不可编辑
- ✅ 已审核通过的处方不可删除
- ✅ 已审核通过的处方不可作废(驳回)
- ✅ 强制执行"撤回 → 编辑 → 重新审核"的规范流程
- ✅ 保证处方的完整性和可追溯性
- ✅ 责任链清晰,审核记录完整
- ✅ 前后端双重校验,防止绕过限制