388 lines
9.1 KiB
Markdown
388 lines
9.1 KiB
Markdown
# 订单撤回后重置处方审核状态
|
||
|
||
## 需求说明
|
||
|
||
当用户在订单列表中点击"撤回"按钮后,除了将订单状态改为"已取消",还需要将关联的处方审核状态重置为"待审核",以便重新审核。
|
||
|
||
## 业务场景
|
||
|
||
### 场景描述
|
||
|
||
1. 医生创建处方
|
||
2. 处方审核通过(`audit_status = 1`)
|
||
3. 创建业务订单(`fulfillment_status = 1` 待双审通过)
|
||
4. 用户点击"撤回"订单
|
||
5. **期望**:处方审核状态重置为"待审核"(`audit_status = 0`)
|
||
|
||
### 为什么需要重置?
|
||
|
||
1. **重新审核**:撤回订单可能是因为处方有问题,需要重新审核
|
||
2. **状态一致性**:订单撤回后,处方应该回到初始状态
|
||
3. **业务流程**:允许医生修改处方后重新提交审核
|
||
|
||
## 数据库表结构
|
||
|
||
### 处方表(zyt_tcm_prescription)
|
||
|
||
```sql
|
||
`audit_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '审核:0待审核 1已通过 2已驳回(同时作废)'
|
||
`audit_time` int(10) unsigned DEFAULT NULL COMMENT '审核时间'
|
||
`audit_by` int(11) unsigned DEFAULT NULL COMMENT '审核人ID'
|
||
`audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '审核意见'
|
||
```
|
||
|
||
**审核状态**:
|
||
- 0 = 待审核
|
||
- 1 = 已通过
|
||
- 2 = 已驳回(同时作废)
|
||
|
||
### 业务订单表(zyt_tcm_prescription_order)
|
||
|
||
```sql
|
||
`prescription_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '消费者处方ID'
|
||
`fulfillment_status` tinyint(2) unsigned NOT NULL DEFAULT 1 COMMENT '1待双审通过 2履约中 3已完成 4已取消'
|
||
```
|
||
|
||
**履约状态**:
|
||
- 1 = 待双审通过
|
||
- 2 = 履约中
|
||
- 3 = 已完成
|
||
- 4 = 已取消(撤回)
|
||
|
||
## 代码修改
|
||
|
||
**文件**:`server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php`
|
||
|
||
**方法**:`withdraw()`
|
||
|
||
### 修改内容
|
||
|
||
```php
|
||
public static function withdraw(int $id, int $adminId, array $adminInfo)
|
||
{
|
||
self::$error = '';
|
||
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
|
||
if (!$order) {
|
||
self::$error = '订单不存在';
|
||
return false;
|
||
}
|
||
if (!self::canWithdrawOrder($order, $adminId, $adminInfo)) {
|
||
self::$error = '无权限撤回';
|
||
return false;
|
||
}
|
||
if ((int) $order->fulfillment_status !== 1) {
|
||
self::$error = '仅「待双审通过」状态可撤回;双审通过后请走履约/完成流程';
|
||
return false;
|
||
}
|
||
|
||
$order->fulfillment_status = 4;
|
||
self::clearPayOrderLinks($order);
|
||
|
||
try {
|
||
$order->save();
|
||
|
||
// 撤回订单后,将关联的处方审核状态改回"待审核"
|
||
$prescriptionId = (int) $order->prescription_id;
|
||
if ($prescriptionId > 0) {
|
||
Prescription::where('id', $prescriptionId)
|
||
->whereNull('delete_time')
|
||
->update([
|
||
'audit_status' => 0, // 0=待审核
|
||
'audit_time' => null,
|
||
'audit_by' => null,
|
||
'audit_remark' => '',
|
||
'update_time' => time(),
|
||
]);
|
||
}
|
||
} catch (\Throwable $e) {
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
|
||
$out = $order->toArray();
|
||
self::maskInternalCostIfNeeded($out, $adminInfo);
|
||
self::attachLinkedPayOrders($out);
|
||
|
||
return $out;
|
||
}
|
||
```
|
||
|
||
### 修改说明
|
||
|
||
1. **保存订单状态**:`$order->save()`
|
||
2. **获取处方ID**:`$prescriptionId = (int) $order->prescription_id`
|
||
3. **重置处方审核状态**:
|
||
- `audit_status = 0`(待审核)
|
||
- `audit_time = null`(清空审核时间)
|
||
- `audit_by = null`(清空审核人)
|
||
- `audit_remark = ''`(清空审核意见)
|
||
- `update_time = time()`(更新时间)
|
||
|
||
## 工作流程
|
||
|
||
### 完整流程
|
||
|
||
```
|
||
用户点击"撤回"按钮
|
||
↓
|
||
调用 withdraw() 方法
|
||
↓
|
||
验证权限和状态
|
||
↓
|
||
更新订单状态为"已取消"(4)
|
||
↓
|
||
清除支付单关联
|
||
↓
|
||
保存订单
|
||
↓
|
||
获取关联的处方ID
|
||
↓
|
||
重置处方审核状态为"待审核"(0)
|
||
↓
|
||
清空审核时间、审核人、审核意见
|
||
↓
|
||
返回成功
|
||
```
|
||
|
||
### 前端显示
|
||
|
||
**订单列表页面**:
|
||
- 订单状态:已取消
|
||
- 撤回按钮:消失(只有"待双审通过"状态才显示)
|
||
|
||
**处方列表页面**:
|
||
- 审核状态:待审核
|
||
- 可以重新审核
|
||
|
||
## 测试场景
|
||
|
||
### 场景1:正常撤回
|
||
|
||
**初始状态**:
|
||
- 处方审核状态:已通过(1)
|
||
- 订单履约状态:待双审通过(1)
|
||
|
||
**操作**:点击"撤回"按钮
|
||
|
||
**预期结果**:
|
||
- 订单履约状态:已取消(4)
|
||
- 处方审核状态:待审核(0)
|
||
- 审核时间:null
|
||
- 审核人:null
|
||
- 审核意见:空
|
||
|
||
---
|
||
|
||
### 场景2:撤回后重新审核
|
||
|
||
**步骤**:
|
||
1. 撤回订单(处方状态变为"待审核")
|
||
2. 医生修改处方
|
||
3. 重新提交审核
|
||
4. 审核通过
|
||
5. 创建新订单
|
||
|
||
**预期结果**:流程正常,可以重新审核和创建订单
|
||
|
||
---
|
||
|
||
### 场景3:无权限撤回
|
||
|
||
**初始状态**:
|
||
- 当前用户:非创建人、非医助
|
||
|
||
**操作**:点击"撤回"按钮
|
||
|
||
**预期结果**:
|
||
- 错误提示:"无权限撤回"
|
||
- 处方状态不变
|
||
|
||
---
|
||
|
||
### 场景4:非待双审状态撤回
|
||
|
||
**初始状态**:
|
||
- 订单履约状态:履约中(2)或已完成(3)
|
||
|
||
**操作**:点击"撤回"按钮
|
||
|
||
**预期结果**:
|
||
- 错误提示:"仅「待双审通过」状态可撤回;双审通过后请走履约/完成流程"
|
||
- 处方状态不变
|
||
|
||
---
|
||
|
||
### 场景5:处方不存在
|
||
|
||
**初始状态**:
|
||
- 订单关联的处方已被删除
|
||
|
||
**操作**:点击"撤回"按钮
|
||
|
||
**预期结果**:
|
||
- 订单状态:已取消(4)
|
||
- 不会报错(因为有 `if ($prescriptionId > 0)` 判断)
|
||
|
||
## 边界情况处理
|
||
|
||
### 1. 处方ID为0或null
|
||
|
||
```php
|
||
if ($prescriptionId > 0) {
|
||
// 只有处方ID有效时才更新
|
||
}
|
||
```
|
||
|
||
**处理**:跳过处方状态更新,不报错
|
||
|
||
### 2. 处方已被删除
|
||
|
||
```php
|
||
->whereNull('delete_time')
|
||
```
|
||
|
||
**处理**:不会更新已删除的处方
|
||
|
||
### 3. 数据库更新失败
|
||
|
||
```php
|
||
try {
|
||
$order->save();
|
||
// 更新处方状态
|
||
} catch (\Throwable $e) {
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
```
|
||
|
||
**处理**:捕获异常,返回错误信息
|
||
|
||
### 4. 事务一致性
|
||
|
||
**问题**:订单保存成功,但处方更新失败怎么办?
|
||
|
||
**当前实现**:
|
||
- 订单和处方更新在同一个 try-catch 块中
|
||
- 如果处方更新失败,会抛出异常
|
||
- 异常会导致整个方法返回 false
|
||
|
||
**建议优化**:使用数据库事务
|
||
|
||
```php
|
||
Db::startTrans();
|
||
try {
|
||
$order->save();
|
||
|
||
// 更新处方状态
|
||
Prescription::where('id', $prescriptionId)
|
||
->whereNull('delete_time')
|
||
->update([...]);
|
||
|
||
Db::commit();
|
||
} catch (\Throwable $e) {
|
||
Db::rollback();
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
```
|
||
|
||
## 相关影响
|
||
|
||
### 1. 处方列表页面
|
||
|
||
**文件**:`admin/src/views/consumer/prescription/index.vue`
|
||
|
||
**影响**:
|
||
- 撤回后,处方审核状态显示为"待审核"
|
||
- 可以重新点击"审核"按钮
|
||
|
||
### 2. 订单列表页面
|
||
|
||
**文件**:`admin/src/views/consumer/prescription/order_list.vue`
|
||
|
||
**影响**:
|
||
- 撤回后,订单状态显示为"已取消"
|
||
- "撤回"按钮消失(只有"待双审通过"状态才显示)
|
||
|
||
### 3. 业务流程
|
||
|
||
**影响**:
|
||
- 允许撤回后重新审核处方
|
||
- 允许重新创建订单
|
||
- 支付单关联被清除,可以重新关联
|
||
|
||
## 注意事项
|
||
|
||
### 1. 权限控制
|
||
|
||
只有以下用户可以撤回订单:
|
||
- 订单创建人
|
||
- 诊单医助
|
||
- 主管角色
|
||
|
||
### 2. 状态限制
|
||
|
||
只有"待双审通过"状态的订单可以撤回:
|
||
- 待双审通过(1):✅ 可以撤回
|
||
- 履约中(2):❌ 不可撤回
|
||
- 已完成(3):❌ 不可撤回
|
||
- 已取消(4):❌ 不可撤回
|
||
|
||
### 3. 数据一致性
|
||
|
||
撤回操作会:
|
||
- 更新订单状态
|
||
- 清除支付单关联
|
||
- 重置处方审核状态
|
||
|
||
建议使用数据库事务确保一致性。
|
||
|
||
### 4. 审核历史
|
||
|
||
当前实现会清空审核历史(审核时间、审核人、审核意见)。
|
||
|
||
如果需要保留审核历史,可以考虑:
|
||
- 不清空这些字段
|
||
- 或者创建审核历史表记录
|
||
|
||
## 相关文件
|
||
|
||
### 后端文件
|
||
- `server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php` - 订单逻辑
|
||
- `server/app/common/model/tcm/Prescription.php` - 处方模型
|
||
- `server/app/common/model/tcm/PrescriptionOrder.php` - 订单模型
|
||
|
||
### 前端文件
|
||
- `admin/src/views/consumer/prescription/order_list.vue` - 订单列表
|
||
- `admin/src/views/consumer/prescription/index.vue` - 处方列表
|
||
|
||
### 数据库文件
|
||
- `server/database/migrations/2026_03_30_prescription_visible_roles_audit.sql` - 处方审核字段
|
||
- `server/database/migrations/2026_04_07_create_tcm_prescription_order.sql` - 订单表
|
||
|
||
## 总结
|
||
|
||
✅ 撤回订单时重置处方审核状态为"待审核"
|
||
✅ 清空审核时间、审核人、审核意见
|
||
✅ 更新处方的 update_time
|
||
✅ 保持订单状态为"已取消"
|
||
✅ 清除支付单关联
|
||
✅ 异常处理和错误提示
|
||
|
||
**优势**:
|
||
- 支持撤回后重新审核
|
||
- 状态一致性
|
||
- 业务流程完整
|
||
- 用户体验友好
|
||
|
||
**建议优化**:
|
||
- 使用数据库事务确保一致性
|
||
- 考虑保留审核历史记录
|
||
- 添加操作日志
|
||
|
||
**下一步**:
|
||
1. 测试撤回功能
|
||
2. 验证处方状态变化
|
||
3. 测试重新审核流程
|
||
4. 考虑添加事务支持
|