# 订单撤回后重置处方审核状态 ## 需求说明 当用户在订单列表中点击"撤回"按钮后,除了将订单状态改为"已取消",还需要将关联的处方审核状态重置为"待审核",以便重新审核。 ## 业务场景 ### 场景描述 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. 考虑添加事务支持