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

7.4 KiB
Raw Blame History

处方订单最小金额验证优化

需求说明

在创建处方订单时,如果关联的支付单总金额小于配置的最小金额(PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT),则不允许创建订单。

配置说明

配置文件server/.env

PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT="100"

说明

  • 单位:元(人民币)
  • 默认值:0(不校验)
  • 当前配置:100元

验证规则

修改前(原逻辑)

1. 订单金额 >= 最小金额 ✓
2. 每个关联支付单金额 >= 最小金额 ✓

问题

  • 要求每个支付单都必须 >= 100元
  • 不允许多个小额支付单组合(如 60元 + 50元 = 110元)

修改后(新逻辑)

1. 订单金额 >= 最小金额 ✓
2. 必须关联至少一个支付单 ✓
3. 关联支付单总金额 >= 最小金额 ✓

优势

  • 允许多个小额支付单组合
  • 更灵活的支付方式
  • 总金额达标即可

代码修改

文件server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php

方法assertDepositAndLinkPayRules()

修改内容

public static function assertDepositAndLinkPayRules(float $orderAmount, array $payOrderIds): ?string
{
    $min = self::depositMinAmount();
    if ($min <= 0) {
        return null;
    }
    
    // 1. 检查订单金额
    if ($orderAmount < $min) {
        return '订单金额须大于等于定金门槛 ¥' . $min . '(当前 ¥' . $orderAmount . '';
    }
    
    // 2. 检查是否关联支付单
    if ($payOrderIds === []) {
        return '未关联支付单,关联支付单总金额须大于等于定金门槛 ¥' . $min;
    }
    
    // 3. 检查关联支付单的总金额
    $rows = Order::whereIn('id', $payOrderIds)->whereNull('delete_time')->column('amount', 'id');
    $totalAmount = 0.0;
    foreach ($payOrderIds as $pid) {
        $pid = (int) $pid;
        if ($pid <= 0) {
            continue;
        }
        $amt = round((float) ($rows[$pid] ?? 0), 2);
        $totalAmount += $amt;
    }
    
    if ($totalAmount < $min) {
        return '关联支付单总金额须大于等于定金门槛 ¥' . $min . '(当前总金额 ¥' . $totalAmount . '';
    }

    return null;
}

验证场景

场景1:订单金额不足

配置:最小金额 = 100元

输入

  • 订单金额:80元
  • 关联支付单:[100元]

结果 失败 错误信息:订单金额须大于等于定金门槛 ¥100(当前 ¥80)


场景2:未关联支付单

配置:最小金额 = 100元

输入

  • 订单金额:150元
  • 关联支付单:[]

结果 失败 错误信息:未关联支付单,关联支付单总金额须大于等于定金门槛 ¥100


场景3:关联支付单总金额不足

配置:最小金额 = 100元

输入

  • 订单金额:150元
  • 关联支付单:[30元, 40元, 20元]
  • 总金额:90元

结果 失败 错误信息:关联支付单总金额须大于等于定金门槛 ¥100(当前总金额 ¥90)


场景4:多个小额支付单组合达标

配置:最小金额 = 100元

输入

  • 订单金额:150元
  • 关联支付单:[60元, 50元]
  • 总金额:110元

结果 成功 说明:虽然单个支付单都小于100元,但总金额达标


场景5:单个大额支付单

配置:最小金额 = 100元

输入

  • 订单金额:150元
  • 关联支付单:[120元]
  • 总金额:120元

结果 成功


场景6:配置为0(不校验)

配置:最小金额 = 0元

输入

  • 订单金额:10元
  • 关联支付单:[]

结果 成功 说明:最小金额为0时,不进行任何校验


场景7:多个支付单,总金额刚好达标

配置:最小金额 = 100元

输入

  • 订单金额:150元
  • 关联支付单:[30元, 30元, 40元]
  • 总金额:100元

结果 成功 说明:总金额刚好等于最小金额,符合"大于等于"的要求

前端提示优化

文件admin/src/views/consumer/prescription/order_list.vue

当前提示

支付单审核时可对照此处关联的收款记录。
列表仅展示金额大于等于定金门槛的收款单(门槛为 0 时展示全部)。

建议修改为

支付单审核时可对照此处关联的收款记录。
关联支付单总金额须大于等于定金门槛(当前门槛:¥100)。
列表仅展示金额大于等于定金门槛的收款单(门槛为 0 时展示全部)。

配置管理

查看当前配置

# 查看 .env 文件
cat server/.env | grep PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT

修改配置

# 编辑 .env 文件
vim server/.env

# 修改为 200 元
PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT="200"

# 修改为 0(不校验)
PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT="0"

配置生效

修改 .env 文件后,配置会立即生效,无需重启服务。

业务逻辑说明

为什么需要最小金额限制?

  1. 定金机制:确保客户已支付足够的定金
  2. 风险控制:避免小额订单的履约风险
  3. 业务规范:统一订单金额标准

为什么改为总金额验证?

  1. 灵活性:允许客户分多次支付
  2. 用户体验:不强制单次支付大额
  3. 实际需求:多次小额支付也能达到定金要求

为什么必须关联支付单?

  1. 资金确认:确保订单有对应的收款记录
  2. 审核依据:支付单审核时需要对照
  3. 财务管理:便于对账和统计

测试建议

1. 单元测试

// 测试订单金额不足
$result = PrescriptionOrderLogic::assertDepositAndLinkPayRules(80, [1]);
assert($result !== null);

// 测试未关联支付单
$result = PrescriptionOrderLogic::assertDepositAndLinkPayRules(150, []);
assert($result !== null);

// 测试总金额不足
$result = PrescriptionOrderLogic::assertDepositAndLinkPayRules(150, [1, 2]); // 假设总金额 < 100
assert($result !== null);

// 测试总金额达标
$result = PrescriptionOrderLogic::assertDepositAndLinkPayRules(150, [3, 4]); // 假设总金额 >= 100
assert($result === null);

2. 集成测试

  1. 创建多个小额支付单(如 60元、50元)
  2. 创建订单,关联这些支付单
  3. 验证是否能成功创建
  4. 验证错误提示是否正确

3. 边界测试

  • 总金额刚好等于最小金额(100元)
  • 总金额略小于最小金额(99.99元)
  • 总金额略大于最小金额(100.01元)
  • 最小金额为0
  • 最小金额为负数(应该按0处理)

相关文件

配置文件

  • server/.env - 环境配置
  • server/config/prescription_order.php - 订单配置

后端文件

  • server/app/adminapi/logic/tcm/PrescriptionOrderLogic.php - 订单逻辑
  • server/app/adminapi/validate/tcm/PrescriptionOrderValidate.php - 订单验证

前端文件

  • admin/src/views/consumer/prescription/order_list.vue - 订单列表页面

总结

修改验证逻辑:从"每个支付单"改为"支付单总金额" 添加必须关联支付单的验证 优化错误提示信息,显示当前总金额 支持多个小额支付单组合 保持订单金额验证不变 配置为0时不进行校验

优势

  • 更灵活的支付方式
  • 更好的用户体验
  • 更清晰的错误提示
  • 更符合实际业务需求

下一步

  1. 测试各种场景
  2. 更新前端提示文字
  3. 编写单元测试
  4. 更新用户文档