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

9.1 KiB
Raw Blame History

订单撤回后重置处方审核状态

需求说明

当用户在订单列表中点击"撤回"按钮后,除了将订单状态改为"已取消",还需要将关联的处方审核状态重置为"待审核",以便重新审核。

业务场景

场景描述

  1. 医生创建处方
  2. 处方审核通过(audit_status = 1
  3. 创建业务订单(fulfillment_status = 1 待双审通过)
  4. 用户点击"撤回"订单
  5. 期望:处方审核状态重置为"待审核"(audit_status = 0

为什么需要重置?

  1. 重新审核:撤回订单可能是因为处方有问题,需要重新审核
  2. 状态一致性:订单撤回后,处方应该回到初始状态
  3. 业务流程:允许医生修改处方后重新提交审核

数据库表结构

处方表(zyt_tcm_prescription

`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

`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()

修改内容

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

if ($prescriptionId > 0) {
    // 只有处方ID有效时才更新
}

处理:跳过处方状态更新,不报错

2. 处方已被删除

->whereNull('delete_time')

处理:不会更新已删除的处方

3. 数据库更新失败

try {
    $order->save();
    // 更新处方状态
} catch (\Throwable $e) {
    self::$error = $e->getMessage();
    return false;
}

处理:捕获异常,返回错误信息

4. 事务一致性

问题:订单保存成功,但处方更新失败怎么办?

当前实现

  • 订单和处方更新在同一个 try-catch 块中
  • 如果处方更新失败,会抛出异常
  • 异常会导致整个方法返回 false

建议优化:使用数据库事务

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. 考虑添加事务支持