Files
java-10561/docs/ORDER_DATABASE_FIELDS_FIX.md
2025-09-06 11:58:18 +08:00

150 lines
5.9 KiB
Markdown
Raw Permalink 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.

# 订单数据库字段缺失默认值修复指南
## 问题描述
在提交订单时遇到以下数据库错误:
```
{"code":1,"message":"\n### Error updating database. Cause: java.sql.SQLException: Field 'pay_price' doesn't have a default value\n### The error may exist in com/gxwebsoft/shop/mapper/ShopOrderMapper.java (best guess)\n### The error may involve com.gxwebsoft.shop.mapper.ShopOrderMapper.insert-Inline\n### The error occurred while setting parameters\n### SQL: INSERT INTO shop_order (order_no, delivery_type, address_id, total_price, price, pay_user_id, pay_type, pay_status, user_id, comments, tenant_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 10550)\n### Cause: java.sql.SQLException: Field 'pay_price' doesn't have a default value\n; Field 'pay_price' doesn't have a default value; nested exception is java.sql.SQLException: Field 'pay_price' doesn't have a default value"}
```
## 根本原因
数据库表 `shop_order` 中的 `pay_price` 字段没有设置默认值,而在插入订单记录时没有为该字段提供值,导致 SQL 插入失败。
## 解决方案
### 1. 修改 `buildShopOrder` 方法
`OrderBusinessService.buildShopOrder()` 方法中添加了所有必需字段的默认值设置:
```java
// 设置价格相关字段(解决数据库字段没有默认值的问题)
if (shopOrder.getPayPrice() == null) {
shopOrder.setPayPrice(shopOrder.getTotalPrice()); // 实际付款默认等于订单总额
}
if (shopOrder.getPrice() == null) {
shopOrder.setPrice(shopOrder.getTotalPrice()); // 用于统计的价格默认等于订单总额
}
if (shopOrder.getReducePrice() == null) {
shopOrder.setReducePrice(BigDecimal.ZERO); // 减少金额默认为0
}
if (shopOrder.getMoney() == null) {
shopOrder.setMoney(shopOrder.getTotalPrice()); // 用于积分赠送的价格默认等于订单总额
}
// 设置默认状态
shopOrder.setPayStatus(false); // 未付款
shopOrder.setOrderStatus(0); // 未使用
shopOrder.setDeliveryStatus(10); // 未发货
shopOrder.setIsInvoice(0); // 未开发票
shopOrder.setIsSettled(0); // 未结算
shopOrder.setCheckBill(0); // 未对账
shopOrder.setVersion(0); // 当前版本
// 设置默认支付类型(如果没有指定)
if (shopOrder.getPayType() == null) {
shopOrder.setPayType(1); // 默认微信支付
}
```
### 2. 修改 `applyBusinessRules` 方法
确保测试账号逻辑也正确设置所有相关字段:
```java
// 测试账号处理
if (orderConfig.isTestAccount(loginUser.getPhone())) {
BigDecimal testAmount = orderConfig.getTestAccount().getTestPayAmount();
shopOrder.setPrice(testAmount);
shopOrder.setTotalPrice(testAmount);
shopOrder.setPayPrice(testAmount); // 确保实际付款也设置为测试金额
shopOrder.setMoney(testAmount); // 确保积分计算金额也设置为测试金额
log.info("应用测试账号规则,用户:{},测试金额:{}", loginUser.getPhone(), testAmount);
}
```
## 修复的字段列表
| 字段名 | 默认值 | 说明 |
|--------|--------|------|
| `payPrice` | `totalPrice` | 实际付款金额,默认等于订单总额 |
| `price` | `totalPrice` | 用于统计的价格,默认等于订单总额 |
| `reducePrice` | `BigDecimal.ZERO` | 减少的金额(优惠券、折扣等) |
| `money` | `totalPrice` | 用于积分赠送的价格 |
| `payStatus` | `false` | 支付状态,默认未付款 |
| `orderStatus` | `0` | 订单状态,默认未使用 |
| `deliveryStatus` | `10` | 发货状态,默认未发货 |
| `isInvoice` | `0` | 发票状态,默认未开发票 |
| `isSettled` | `0` | 结算状态,默认未结算 |
| `checkBill` | `0` | 对账状态,默认未对账 |
| `version` | `0` | 系统版本,默认当前版本 |
| `payType` | `1` | 支付类型,默认微信支付 |
## 测试验证
创建了专门的测试用例 `testBuildShopOrder_RequiredFields` 来验证所有必需字段都正确设置:
```java
@Test
void testBuildShopOrder_RequiredFields() throws Exception {
// 验证必需字段都已设置
assertNotNull(result.getPayPrice(), "payPrice 不能为空");
assertNotNull(result.getPrice(), "price 不能为空");
assertNotNull(result.getReducePrice(), "reducePrice 不能为空");
assertNotNull(result.getMoney(), "money 不能为空");
// ... 其他字段验证
// 验证默认值
assertEquals(testRequest.getTotalPrice(), result.getPayPrice());
assertEquals(testRequest.getTotalPrice(), result.getPrice());
assertEquals(BigDecimal.ZERO, result.getReducePrice());
// ... 其他默认值验证
}
```
## 业务逻辑说明
### 价格字段关系
1. **totalPrice**: 订单总额,由商品价格计算得出
2. **payPrice**: 实际付款金额,通常等于 totalPrice但可能因优惠而不同
3. **price**: 用于统计的价格,通常等于 totalPrice
4. **money**: 用于积分赠送计算的价格
5. **reducePrice**: 优惠减免的金额优惠券、VIP折扣等
### 计算公式
```
payPrice = totalPrice - reducePrice
```
在没有优惠的情况下:
```
payPrice = totalPrice
reducePrice = 0
```
## 影响范围
这个修复解决了以下问题:
1.**数据库插入错误**: 解决了 `pay_price` 等字段缺少默认值的问题
2.**订单状态完整性**: 确保所有状态字段都有正确的初始值
3.**价格计算一致性**: 保证各个价格字段的逻辑关系正确
4.**测试账号兼容性**: 确保测试账号逻辑正常工作
## 注意事项
1. **向后兼容**: 修改保持了向后兼容性,不会影响现有功能
2. **数据完整性**: 所有必需字段都有合理的默认值
3. **业务逻辑**: 默认值符合业务逻辑,不会产生异常数据
4. **测试覆盖**: 有完整的测试用例覆盖修改的功能
## 总结
通过在 `buildShopOrder` 方法中添加完整的字段默认值设置,成功解决了订单提交时的数据库字段缺失问题。这个修复不仅解决了当前的错误,还提高了系统的健壮性,确保订单数据的完整性和一致性。