修复订单商品没有排序字段的bug

This commit is contained in:
2025-07-30 15:41:45 +08:00
parent 77713e9ad8
commit 2b761eb4b9
6 changed files with 321 additions and 22 deletions

View File

@@ -156,6 +156,9 @@ public class OrderCreateRequest {
@NotNull(message = "商品ID不能为空")
private Integer goodsId;
@Schema(description = "商品SKU ID")
private Integer skuId;
@Schema(description = "商品数量", required = true)
@NotNull(message = "商品数量不能为空")
@Min(value = 1, message = "商品数量必须大于0")
@@ -163,5 +166,8 @@ public class OrderCreateRequest {
@Schema(description = "支付类型")
private Integer payType;
@Schema(description = "规格信息,如:颜色:红色|尺寸:L")
private String specInfo;
}
}

View File

@@ -35,9 +35,15 @@ public class ShopCart implements Serializable {
@Schema(description = "商品ID")
private Long goodsId;
@Schema(description = "商品SKU ID")
private Integer skuId;
@Schema(description = "商品规格")
private String spec;
@Schema(description = "规格信息,如:颜色:红色|尺寸:L")
private String specInfo;
@Schema(description = "商品价格")
private BigDecimal price;

View File

@@ -11,12 +11,10 @@ import java.util.List;
import com.gxwebsoft.bszx.entity.BszxBm;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.constraints.*;
import javax.validation.groups.Default;
/**
* 订单
@@ -273,5 +271,4 @@ public class ShopOrder implements Serializable {
@Schema(description = "报名信息")
@TableField(exist = false)
private BszxBm bm;
}

View File

@@ -37,9 +37,16 @@ public class ShopCartParam extends BaseParam {
@Schema(description = "商品ID")
private Long goodsId;
@Schema(description = "商品SKU ID")
@QueryField(type = QueryType.EQ)
private Integer skuId;
@Schema(description = "商品规格")
private String spec;
@Schema(description = "规格信息,如:颜色:红色|尺寸:L")
private String specInfo;
@Schema(description = "商品价格")
@QueryField(type = QueryType.EQ)
private BigDecimal price;

View File

@@ -6,6 +6,7 @@ import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.config.OrderConfigProperties;
import com.gxwebsoft.shop.dto.OrderCreateRequest;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.entity.ShopGoodsSku;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.entity.ShopOrderGoods;
import lombok.extern.slf4j.Slf4j;
@@ -40,6 +41,9 @@ public class OrderBusinessService {
@Resource
private ShopGoodsService shopGoodsService;
@Resource
private ShopGoodsSkuService shopGoodsSkuService;
@Resource
private OrderConfigProperties orderConfig;
@@ -146,28 +150,56 @@ public class OrderBusinessService {
throw new BusinessException("商品已下架:" + goods.getName());
}
// 验证商品价格
if (goods.getPrice() == null || goods.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
throw new BusinessException("商品价格异常:" + goods.getName());
// 处理多规格商品价格和库存验证
BigDecimal actualPrice = goods.getPrice(); // 默认使用商品价格
Integer actualStock = goods.getStock(); // 默认使用商品库存
String productName = goods.getName();
if (item.getSkuId() != null) {
// 多规格商品获取SKU信息
ShopGoodsSku sku = shopGoodsSkuService.getById(item.getSkuId());
if (sku == null) {
throw new BusinessException("商品规格不存在SKU ID" + item.getSkuId());
}
// 验证SKU是否属于该商品
if (!sku.getGoodsId().equals(item.getGoodsId())) {
throw new BusinessException("商品规格不匹配");
}
// 验证SKU状态
if (sku.getStatus() == null || sku.getStatus() != 0) {
throw new BusinessException("商品规格已下架");
}
// 使用SKU的价格和库存
actualPrice = sku.getPrice();
actualStock = sku.getStock();
productName = goods.getName() + "(" + (item.getSpecInfo() != null ? item.getSpecInfo() : sku.getSku()) + ")";
}
// 验证库存(如果商品有库存管理)
if (goods.getStock() != null && goods.getStock() < item.getQuantity()) {
throw new BusinessException("商品库存不足" + goods.getName() + ",当前库存:" + goods.getStock());
// 验证实际价格
if (actualPrice == null || actualPrice.compareTo(BigDecimal.ZERO) <= 0) {
throw new BusinessException("商品价格异常" + productName);
}
// 验证购买数量限制
// 验证库存
if (actualStock != null && actualStock < item.getQuantity()) {
throw new BusinessException("商品库存不足:" + productName + ",当前库存:" + actualStock);
}
// 验证购买数量限制(使用商品级别的限制)
if (goods.getCanBuyNumber() != null && goods.getCanBuyNumber() > 0 &&
item.getQuantity() > goods.getCanBuyNumber()) {
throw new BusinessException("商品购买数量超过限制:" + goods.getName() + ",最大购买数量:" + goods.getCanBuyNumber());
throw new BusinessException("商品购买数量超过限制:" + productName + ",最大购买数量:" + goods.getCanBuyNumber());
}
// 计算商品小计
BigDecimal itemTotal = goods.getPrice().multiply(new BigDecimal(item.getQuantity()));
// 计算商品小计(使用实际价格)
BigDecimal itemTotal = actualPrice.multiply(new BigDecimal(item.getQuantity()));
total = total.add(itemTotal);
log.debug("商品验证通过 - ID{},名称:{},单价:{},数量:{},小计:{}",
goods.getGoodsId(), goods.getName(), goods.getPrice(), item.getQuantity(), itemTotal);
log.debug("商品验证通过 - ID{}SKU ID{}名称:{},单价:{},数量:{},小计:{}",
goods.getGoodsId(), item.getSkuId(), productName, actualPrice, item.getQuantity(), itemTotal);
}
log.info("订单商品验证完成,总金额:{}", total);
@@ -298,6 +330,45 @@ public class OrderBusinessService {
throw new BusinessException("商品已下架:" + goods.getName());
}
// 处理多规格商品
ShopGoodsSku sku = null;
BigDecimal actualPrice = goods.getPrice(); // 默认使用商品价格
Integer actualStock = goods.getStock(); // 默认使用商品库存
String specInfo = item.getSpecInfo(); // 规格信息
if (item.getSkuId() != null) {
// 多规格商品获取SKU信息
sku = shopGoodsSkuService.getById(item.getSkuId());
if (sku == null) {
throw new BusinessException("商品规格不存在SKU ID" + item.getSkuId());
}
// 验证SKU是否属于该商品
if (!sku.getGoodsId().equals(item.getGoodsId())) {
throw new BusinessException("商品规格不匹配");
}
// 验证SKU状态
if (sku.getStatus() == null || sku.getStatus() != 0) {
throw new BusinessException("商品规格已下架");
}
// 使用SKU的价格和库存
actualPrice = sku.getPrice();
actualStock = sku.getStock();
// 如果前端没有传规格信息使用SKU的规格信息
if (specInfo == null || specInfo.trim().isEmpty()) {
specInfo = sku.getSku(); // 使用SKU的规格描述
}
}
// 验证库存
if (actualStock == null || actualStock < item.getQuantity()) {
String stockMsg = sku != null ? "商品规格库存不足" : "商品库存不足";
throw new BusinessException(stockMsg + ",当前库存:" + (actualStock != null ? actualStock : 0));
}
ShopOrderGoods orderGoods = new ShopOrderGoods();
// 设置订单关联信息
@@ -310,18 +381,17 @@ public class OrderBusinessService {
// 设置商品信息(使用后台查询的真实数据)
orderGoods.setGoodsId(item.getGoodsId());
orderGoods.setSkuId(item.getSkuId()); // 设置SKU ID
orderGoods.setGoodsName(goods.getName());
orderGoods.setImage(goods.getImage());
orderGoods.setPrice(goods.getPrice()); // 使用后台查询的价格
orderGoods.setImage(sku != null && sku.getImage() != null ? sku.getImage() : goods.getImage()); // 优先使用SKU图片
orderGoods.setPrice(actualPrice); // 使用实际价格SKU价格或商品价格
orderGoods.setTotalNum(item.getQuantity());
// 计算商品小计(用于日志记录)
BigDecimal itemTotal = goods.getPrice().multiply(new BigDecimal(item.getQuantity()));
BigDecimal itemTotal = actualPrice.multiply(new BigDecimal(item.getQuantity()));
// 设置商品规格信息(如果有的话)
if (goods.getCode() != null) {
orderGoods.setSpec(goods.getCode()); // 使用商品编码作为规格
}
// 设置商品规格信息
orderGoods.setSpec(specInfo);
// 设置支付相关信息
orderGoods.setPayStatus(0); // 0 未付款
@@ -346,9 +416,48 @@ public class OrderBusinessService {
throw new BusinessException("保存订单商品失败");
}
// 扣减库存
deductStock(request);
log.info("成功保存订单商品,订单号:{},商品数量:{}", shopOrder.getOrderNo(), orderGoodsList.size());
}
/**
* 扣减库存
*/
private void deductStock(OrderCreateRequest request) {
for (OrderCreateRequest.OrderGoodsItem item : request.getGoodsItems()) {
if (item.getSkuId() != null) {
// 多规格商品扣减SKU库存
ShopGoodsSku sku = shopGoodsSkuService.getById(item.getSkuId());
if (sku != null && sku.getStock() != null) {
int newStock = sku.getStock() - item.getQuantity();
if (newStock < 0) {
throw new BusinessException("SKU库存不足无法完成扣减");
}
sku.setStock(newStock);
shopGoodsSkuService.updateById(sku);
log.debug("扣减SKU库存 - SKU ID{},扣减数量:{},剩余库存:{}",
item.getSkuId(), item.getQuantity(), newStock);
}
} else {
// 单规格商品,扣减商品库存
ShopGoods goods = shopGoodsService.getById(item.getGoodsId());
if (goods != null && goods.getStock() != null) {
int newStock = goods.getStock() - item.getQuantity();
if (newStock < 0) {
throw new BusinessException("商品库存不足,无法完成扣减");
}
goods.setStock(newStock);
shopGoodsService.updateById(goods);
log.debug("扣减商品库存 - 商品ID{},扣减数量:{},剩余库存:{}",
item.getGoodsId(), item.getQuantity(), newStock);
}
}
}
log.info("库存扣减完成");
}
/**
* 检查是否为测试账号
*/