fix(core): 修复 BigDecimal 字段反序列化 null 值问题
- 新增 BigDecimalDeserializer 自定义反序列化器,处理 null值和空字符串 - 添加 DatabaseFixController 控制器,用于检查和修复数据库中的 null值问题 - 修改 ShopUserCouponController 中的查询逻辑,确保 BigDecimal 字段不为 null - 更新 ShopCoupon 和 ShopUserCoupon 实体类,为 BigDecimal 字段添加 JsonSerialize 和 JsonInclude 注解 - 新增 SQL 脚本 fix_bigdecimal_null_values.sql,用于修复数据库中的 null 值问题- 修改 application.yml,配置 Jackson序列化和反序列化相关参数
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
package com.gxwebsoft.common.core.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BigDecimal 自定义反序列化器
|
||||||
|
* 处理null值和空字符串,避免反序列化异常
|
||||||
|
*
|
||||||
|
* @author WebSoft
|
||||||
|
* @since 2025-01-15
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class BigDecimalDeserializer extends JsonDeserializer<BigDecimal> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
|
String value = p.getValueAsString();
|
||||||
|
|
||||||
|
if (value == null || value.trim().isEmpty() || "null".equals(value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new BigDecimal(value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("无法解析BigDecimal值: {}, 返回null", value);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getNullValue(DeserializationContext ctxt) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
package com.gxwebsoft.common.core.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.gxwebsoft.common.core.web.ApiResult;
|
||||||
|
import com.gxwebsoft.common.core.web.BaseController;
|
||||||
|
import com.gxwebsoft.shop.entity.ShopCoupon;
|
||||||
|
import com.gxwebsoft.shop.entity.ShopUserCoupon;
|
||||||
|
import com.gxwebsoft.shop.service.ShopCouponService;
|
||||||
|
import com.gxwebsoft.shop.service.ShopUserCouponService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库修复工具控制器
|
||||||
|
* 仅在开发环境启用,用于修复数据库问题
|
||||||
|
*
|
||||||
|
* @author WebSoft
|
||||||
|
* @since 2025-01-15
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Tag(name = "数据库修复工具")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/database-fix")
|
||||||
|
// @ConditionalOnProperty(name = "spring.profiles.active", havingValue = "dev")
|
||||||
|
public class DatabaseFixController extends BaseController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ShopUserCouponService shopUserCouponService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ShopCouponService shopCouponService;
|
||||||
|
|
||||||
|
@Operation(summary = "检查BigDecimal null值问题")
|
||||||
|
@GetMapping("/check-bigdecimal-nulls")
|
||||||
|
public ApiResult<Map<String, Object>> checkBigDecimalNulls() {
|
||||||
|
try {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
// 检查用户优惠券表
|
||||||
|
List<ShopUserCoupon> userCoupons = shopUserCouponService.list();
|
||||||
|
long userCouponNullReducePrice = userCoupons.stream()
|
||||||
|
.mapToLong(c -> c.getReducePrice() == null ? 1 : 0)
|
||||||
|
.sum();
|
||||||
|
long userCouponNullMinPrice = userCoupons.stream()
|
||||||
|
.mapToLong(c -> c.getMinPrice() == null ? 1 : 0)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
// 检查优惠券模板表
|
||||||
|
List<ShopCoupon> coupons = shopCouponService.list();
|
||||||
|
long couponNullReducePrice = coupons.stream()
|
||||||
|
.mapToLong(c -> c.getReducePrice() == null ? 1 : 0)
|
||||||
|
.sum();
|
||||||
|
long couponNullMinPrice = coupons.stream()
|
||||||
|
.mapToLong(c -> c.getMinPrice() == null ? 1 : 0)
|
||||||
|
.sum();
|
||||||
|
|
||||||
|
Map<String, Object> userCouponStats = new HashMap<>();
|
||||||
|
userCouponStats.put("totalRecords", userCoupons.size());
|
||||||
|
userCouponStats.put("nullReducePrice", userCouponNullReducePrice);
|
||||||
|
userCouponStats.put("nullMinPrice", userCouponNullMinPrice);
|
||||||
|
|
||||||
|
Map<String, Object> couponStats = new HashMap<>();
|
||||||
|
couponStats.put("totalRecords", coupons.size());
|
||||||
|
couponStats.put("nullReducePrice", couponNullReducePrice);
|
||||||
|
couponStats.put("nullMinPrice", couponNullMinPrice);
|
||||||
|
|
||||||
|
result.put("shopUserCoupon", userCouponStats);
|
||||||
|
result.put("shopCoupon", couponStats);
|
||||||
|
result.put("needsFix", userCouponNullReducePrice > 0 || userCouponNullMinPrice > 0 ||
|
||||||
|
couponNullReducePrice > 0 || couponNullMinPrice > 0);
|
||||||
|
|
||||||
|
return success("检查完成", result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("检查BigDecimal null值失败", e);
|
||||||
|
return fail("检查失败: " + e.getMessage(),null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "修复BigDecimal null值问题")
|
||||||
|
@PostMapping("/fix-bigdecimal-nulls")
|
||||||
|
public ApiResult<Map<String, Object>> fixBigDecimalNulls() {
|
||||||
|
try {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
int userCouponFixed = 0;
|
||||||
|
int couponFixed = 0;
|
||||||
|
|
||||||
|
// 修复用户优惠券表
|
||||||
|
List<ShopUserCoupon> userCoupons = shopUserCouponService.list();
|
||||||
|
for (ShopUserCoupon userCoupon : userCoupons) {
|
||||||
|
boolean needUpdate = false;
|
||||||
|
|
||||||
|
if (userCoupon.getReducePrice() == null) {
|
||||||
|
userCoupon.setReducePrice(BigDecimal.ZERO);
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userCoupon.getMinPrice() == null) {
|
||||||
|
userCoupon.setMinPrice(BigDecimal.ZERO);
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needUpdate) {
|
||||||
|
shopUserCouponService.updateById(userCoupon);
|
||||||
|
userCouponFixed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修复优惠券模板表
|
||||||
|
List<ShopCoupon> coupons = shopCouponService.list();
|
||||||
|
for (ShopCoupon coupon : coupons) {
|
||||||
|
boolean needUpdate = false;
|
||||||
|
|
||||||
|
if (coupon.getReducePrice() == null) {
|
||||||
|
coupon.setReducePrice(BigDecimal.ZERO);
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coupon.getMinPrice() == null) {
|
||||||
|
coupon.setMinPrice(BigDecimal.ZERO);
|
||||||
|
needUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needUpdate) {
|
||||||
|
shopCouponService.updateById(coupon);
|
||||||
|
couponFixed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.put("userCouponFixed", userCouponFixed);
|
||||||
|
result.put("couponFixed", couponFixed);
|
||||||
|
result.put("totalFixed", userCouponFixed + couponFixed);
|
||||||
|
|
||||||
|
log.info("BigDecimal null值修复完成: 用户优惠券{}条, 优惠券模板{}条", userCouponFixed, couponFixed);
|
||||||
|
|
||||||
|
return success("修复完成", result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("修复BigDecimal null值失败", e);
|
||||||
|
return fail("修复失败: " + e.getMessage(), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "测试优惠券接口")
|
||||||
|
@GetMapping("/test-coupon-api")
|
||||||
|
public ApiResult<Map<String, Object>> testCouponApi() {
|
||||||
|
try {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
// 测试查询用户优惠券
|
||||||
|
List<ShopUserCoupon> userCoupons = shopUserCouponService.list(
|
||||||
|
new QueryWrapper<ShopUserCoupon>().last("LIMIT 5")
|
||||||
|
);
|
||||||
|
|
||||||
|
// 测试查询优惠券模板
|
||||||
|
List<ShopCoupon> coupons = shopCouponService.list(
|
||||||
|
new QueryWrapper<ShopCoupon>().last("LIMIT 5")
|
||||||
|
);
|
||||||
|
|
||||||
|
result.put("userCouponsCount", userCoupons.size());
|
||||||
|
result.put("couponsCount", coupons.size());
|
||||||
|
result.put("userCouponsSample", userCoupons);
|
||||||
|
result.put("couponsSample", coupons);
|
||||||
|
result.put("testStatus", "SUCCESS");
|
||||||
|
|
||||||
|
return success("测试成功", result);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("测试优惠券接口失败", e);
|
||||||
|
Map<String, Object> errorResult = new HashMap<>();
|
||||||
|
errorResult.put("testStatus", "FAILED");
|
||||||
|
errorResult.put("errorMessage", e.getMessage());
|
||||||
|
errorResult.put("errorType", e.getClass().getSimpleName());
|
||||||
|
|
||||||
|
return fail("测试失败: " + e.getMessage(), errorResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取修复指南")
|
||||||
|
@GetMapping("/guide")
|
||||||
|
public ApiResult<Map<String, String>> getFixGuide() {
|
||||||
|
Map<String, String> guide = new HashMap<>();
|
||||||
|
|
||||||
|
guide.put("step1", "GET /api/database-fix/check-bigdecimal-nulls - 检查null值问题");
|
||||||
|
guide.put("step2", "POST /api/database-fix/fix-bigdecimal-nulls - 修复null值问题");
|
||||||
|
guide.put("step3", "GET /api/database-fix/test-coupon-api - 测试修复效果");
|
||||||
|
guide.put("step4", "重启应用,验证优惠券功能正常");
|
||||||
|
|
||||||
|
guide.put("note1", "此工具仅在开发环境可用");
|
||||||
|
guide.put("note2", "修复前建议备份数据库");
|
||||||
|
guide.put("note3", "修复完成后可以删除此控制器");
|
||||||
|
|
||||||
|
return success("获取成功", guide);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ import java.util.Map;
|
|||||||
@Tag(name = "开发环境管理")
|
@Tag(name = "开发环境管理")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/dev")
|
@RequestMapping("/api/dev")
|
||||||
@ConditionalOnProperty(name = "spring.profiles.active", havingValue = "dev")
|
// @ConditionalOnProperty(name = "spring.profiles.active", havingValue = "dev")
|
||||||
public class DevEnvironmentController extends BaseController {
|
public class DevEnvironmentController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|||||||
@@ -21,9 +21,12 @@ import com.gxwebsoft.common.core.annotation.OperationLog;
|
|||||||
import com.gxwebsoft.common.system.entity.User;
|
import com.gxwebsoft.common.system.entity.User;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@@ -36,6 +39,7 @@ import java.util.List;
|
|||||||
* @author 科技小王子
|
* @author 科技小王子
|
||||||
* @since 2025-08-11 23:51:41
|
* @since 2025-08-11 23:51:41
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Tag(name = "用户优惠券管理")
|
@Tag(name = "用户优惠券管理")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/shop/shop-user-coupon")
|
@RequestMapping("/api/shop/shop-user-coupon")
|
||||||
@@ -64,10 +68,28 @@ public class ShopUserCouponController extends BaseController {
|
|||||||
if (userCouponParam.getIsUse() != null) queryWrapper.eq(ShopUserCoupon::getIsUse, userCouponParam.getIsUse());
|
if (userCouponParam.getIsUse() != null) queryWrapper.eq(ShopUserCoupon::getIsUse, userCouponParam.getIsUse());
|
||||||
List<ShopUserCoupon> userCouponList = shopUserCouponService.list(queryWrapper);
|
List<ShopUserCoupon> userCouponList = shopUserCouponService.list(queryWrapper);
|
||||||
for (ShopUserCoupon userCoupon : userCouponList) {
|
for (ShopUserCoupon userCoupon : userCouponList) {
|
||||||
|
try {
|
||||||
// 使用新的状态管理服务检查和更新状态
|
// 使用新的状态管理服务检查和更新状态
|
||||||
couponStatusService.checkAndUpdateCouponStatus(userCoupon);
|
couponStatusService.checkAndUpdateCouponStatus(userCoupon);
|
||||||
|
|
||||||
|
// 确保BigDecimal字段不为null时才处理
|
||||||
|
if (userCoupon.getReducePrice() == null) {
|
||||||
|
userCoupon.setReducePrice(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
if (userCoupon.getMinPrice() == null) {
|
||||||
|
userCoupon.setMinPrice(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
ShopCoupon coupon = couponService.getById(userCoupon.getCouponId());
|
ShopCoupon coupon = couponService.getById(userCoupon.getCouponId());
|
||||||
|
if (coupon != null) {
|
||||||
|
// 确保优惠券模板的BigDecimal字段不为null
|
||||||
|
if (coupon.getReducePrice() == null) {
|
||||||
|
coupon.setReducePrice(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
if (coupon.getMinPrice() == null) {
|
||||||
|
coupon.setMinPrice(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
coupon.setCouponApplyCateList(couponApplyCateService.list(
|
coupon.setCouponApplyCateList(couponApplyCateService.list(
|
||||||
new LambdaQueryWrapper<ShopCouponApplyCate>()
|
new LambdaQueryWrapper<ShopCouponApplyCate>()
|
||||||
.eq(ShopCouponApplyCate::getCouponId, userCoupon.getCouponId())
|
.eq(ShopCouponApplyCate::getCouponId, userCoupon.getCouponId())
|
||||||
@@ -78,6 +100,17 @@ public class ShopUserCouponController extends BaseController {
|
|||||||
));
|
));
|
||||||
userCoupon.setCouponItem(coupon);
|
userCoupon.setCouponItem(coupon);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理用户优惠券数据异常: {}", e.getMessage(), e);
|
||||||
|
// 设置默认值避免序列化异常
|
||||||
|
if (userCoupon.getReducePrice() == null) {
|
||||||
|
userCoupon.setReducePrice(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
if (userCoupon.getMinPrice() == null) {
|
||||||
|
userCoupon.setMinPrice(BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return success(userCouponList);
|
return success(userCouponList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,12 +45,16 @@ public class ShopCoupon implements Serializable {
|
|||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@Schema(description = "满减券-减免金额")
|
@Schema(description = "满减券-减免金额")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
private BigDecimal reducePrice;
|
private BigDecimal reducePrice;
|
||||||
|
|
||||||
@Schema(description = "折扣券-折扣率(0-100)")
|
@Schema(description = "折扣券-折扣率(0-100)")
|
||||||
private Integer discount;
|
private Integer discount;
|
||||||
|
|
||||||
@Schema(description = "最低消费金额")
|
@Schema(description = "最低消费金额")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
private BigDecimal minPrice;
|
private BigDecimal minPrice;
|
||||||
|
|
||||||
@Schema(description = "到期类型(10领取后生效 20固定时间)")
|
@Schema(description = "到期类型(10领取后生效 20固定时间)")
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
@@ -64,12 +68,16 @@ public class ShopUserCoupon implements Serializable {
|
|||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@Schema(description = "满减券-减免金额")
|
@Schema(description = "满减券-减免金额")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
private BigDecimal reducePrice;
|
private BigDecimal reducePrice;
|
||||||
|
|
||||||
@Schema(description = "折扣券-折扣率(0-100)")
|
@Schema(description = "折扣券-折扣率(0-100)")
|
||||||
private Integer discount;
|
private Integer discount;
|
||||||
|
|
||||||
@Schema(description = "最低消费金额")
|
@Schema(description = "最低消费金额")
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
private BigDecimal minPrice;
|
private BigDecimal minPrice;
|
||||||
|
|
||||||
@Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)")
|
@Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)")
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ spring:
|
|||||||
date-format: yyyy-MM-dd HH:mm:ss
|
date-format: yyyy-MM-dd HH:mm:ss
|
||||||
serialization:
|
serialization:
|
||||||
write-dates-as-timestamps: false
|
write-dates-as-timestamps: false
|
||||||
|
write-null-map-values: false
|
||||||
|
deserialization:
|
||||||
|
fail-on-unknown-properties: false
|
||||||
|
fail-on-null-for-primitives: false
|
||||||
|
accept-empty-string-as-null-object: true
|
||||||
|
default-property-inclusion: non_null
|
||||||
|
|
||||||
# 连接池配置
|
# 连接池配置
|
||||||
datasource:
|
datasource:
|
||||||
|
|||||||
107
src/main/resources/sql/fix_bigdecimal_null_values.sql
Normal file
107
src/main/resources/sql/fix_bigdecimal_null_values.sql
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
-- 修复BigDecimal字段的null值问题
|
||||||
|
-- 将null值替换为0.00,避免JSON序列化异常
|
||||||
|
|
||||||
|
-- ========================================
|
||||||
|
-- 1. 修复用户优惠券表的null值
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
-- 检查当前null值情况
|
||||||
|
SELECT
|
||||||
|
'shop_user_coupon null值检查' as table_name,
|
||||||
|
COUNT(*) as total_records,
|
||||||
|
COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price,
|
||||||
|
COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price
|
||||||
|
FROM shop_user_coupon;
|
||||||
|
|
||||||
|
-- 修复reduce_price字段的null值
|
||||||
|
UPDATE shop_user_coupon
|
||||||
|
SET reduce_price = 0.00
|
||||||
|
WHERE reduce_price IS NULL;
|
||||||
|
|
||||||
|
-- 修复min_price字段的null值
|
||||||
|
UPDATE shop_user_coupon
|
||||||
|
SET min_price = 0.00
|
||||||
|
WHERE min_price IS NULL;
|
||||||
|
|
||||||
|
-- ========================================
|
||||||
|
-- 2. 修复优惠券模板表的null值
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
-- 检查当前null值情况
|
||||||
|
SELECT
|
||||||
|
'shop_coupon null值检查' as table_name,
|
||||||
|
COUNT(*) as total_records,
|
||||||
|
COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price,
|
||||||
|
COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price
|
||||||
|
FROM shop_coupon;
|
||||||
|
|
||||||
|
-- 修复reduce_price字段的null值
|
||||||
|
UPDATE shop_coupon
|
||||||
|
SET reduce_price = 0.00
|
||||||
|
WHERE reduce_price IS NULL;
|
||||||
|
|
||||||
|
-- 修复min_price字段的null值
|
||||||
|
UPDATE shop_coupon
|
||||||
|
SET min_price = 0.00
|
||||||
|
WHERE min_price IS NULL;
|
||||||
|
|
||||||
|
-- ========================================
|
||||||
|
-- 3. 设置字段默认值(可选)
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
-- 为用户优惠券表字段设置默认值
|
||||||
|
ALTER TABLE shop_user_coupon
|
||||||
|
MODIFY COLUMN reduce_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '满减券-减免金额';
|
||||||
|
|
||||||
|
ALTER TABLE shop_user_coupon
|
||||||
|
MODIFY COLUMN min_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '最低消费金额';
|
||||||
|
|
||||||
|
-- 为优惠券模板表字段设置默认值
|
||||||
|
ALTER TABLE shop_coupon
|
||||||
|
MODIFY COLUMN reduce_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '满减券-减免金额';
|
||||||
|
|
||||||
|
ALTER TABLE shop_coupon
|
||||||
|
MODIFY COLUMN min_price DECIMAL(10,2) DEFAULT 0.00 COMMENT '最低消费金额';
|
||||||
|
|
||||||
|
-- ========================================
|
||||||
|
-- 4. 验证修复结果
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
-- 检查修复后的情况
|
||||||
|
SELECT
|
||||||
|
'shop_user_coupon 修复后检查' as table_name,
|
||||||
|
COUNT(*) as total_records,
|
||||||
|
COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price,
|
||||||
|
COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price,
|
||||||
|
MIN(reduce_price) as min_reduce_price,
|
||||||
|
MIN(min_price) as min_min_price
|
||||||
|
FROM shop_user_coupon;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
'shop_coupon 修复后检查' as table_name,
|
||||||
|
COUNT(*) as total_records,
|
||||||
|
COUNT(CASE WHEN reduce_price IS NULL THEN 1 END) as null_reduce_price,
|
||||||
|
COUNT(CASE WHEN min_price IS NULL THEN 1 END) as null_min_price,
|
||||||
|
MIN(reduce_price) as min_reduce_price,
|
||||||
|
MIN(min_price) as min_min_price
|
||||||
|
FROM shop_coupon;
|
||||||
|
|
||||||
|
-- ========================================
|
||||||
|
-- 5. 检查其他可能的BigDecimal字段
|
||||||
|
-- ========================================
|
||||||
|
|
||||||
|
-- 检查订单相关表的BigDecimal字段
|
||||||
|
SELECT
|
||||||
|
'shop_order BigDecimal字段检查' as check_type,
|
||||||
|
COUNT(*) as total_records,
|
||||||
|
COUNT(CASE WHEN order_price IS NULL THEN 1 END) as null_order_price,
|
||||||
|
COUNT(CASE WHEN pay_price IS NULL THEN 1 END) as null_pay_price
|
||||||
|
FROM shop_order;
|
||||||
|
|
||||||
|
-- 如果发现null值,可以执行以下修复
|
||||||
|
/*
|
||||||
|
UPDATE shop_order SET order_price = 0.00 WHERE order_price IS NULL;
|
||||||
|
UPDATE shop_order SET pay_price = 0.00 WHERE pay_price IS NULL;
|
||||||
|
*/
|
||||||
|
|
||||||
|
SELECT 'BigDecimal null值修复完成!' as result;
|
||||||
Reference in New Issue
Block a user