7.4 KiB
7.4 KiB
处方订单最小金额验证优化
需求说明
在创建处方订单时,如果关联的支付单总金额小于配置的最小金额(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. 单元测试
// 测试订单金额不足
$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. 集成测试
- 创建多个小额支付单(如 60元、50元)
- 创建订单,关联这些支付单
- 验证是否能成功创建
- 验证错误提示是否正确
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时不进行校验
优势:
- 更灵活的支付方式
- 更好的用户体验
- 更清晰的错误提示
- 更符合实际业务需求
下一步:
- 测试各种场景
- 更新前端提示文字
- 编写单元测试
- 更新用户文档