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

319 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 处方订单最小金额验证优化
## 需求说明
在创建处方订单时,如果关联的支付单总金额小于配置的最小金额(`PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT`),则不允许创建订单。
## 配置说明
**配置文件**`server/.env`
```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()`
### 修改内容
```php
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 时展示全部)。
```
## 配置管理
### 查看当前配置
```bash
# 查看 .env 文件
cat server/.env | grep PRESCRIPTION_ORDER_LINK_PAY_MIN_AMOUNT
```
### 修改配置
```bash
# 编辑 .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. 单元测试
```php
// 测试订单金额不足
$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. 更新用户文档