3 changed files with 217 additions and 2 deletions
@ -0,0 +1,149 @@ |
|||
# 订单数据库字段缺失默认值修复指南 |
|||
|
|||
## 问题描述 |
|||
|
|||
在提交订单时遇到以下数据库错误: |
|||
|
|||
``` |
|||
{"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` 方法中添加完整的字段默认值设置,成功解决了订单提交时的数据库字段缺失问题。这个修复不仅解决了当前的错误,还提高了系统的健壮性,确保订单数据的完整性和一致性。 |
Loading…
Reference in new issue