feat(order): 优化订单创建逻辑,增加商品价格和名称计算

- 新增 calculateProductItemPriceAndName 方法,用于重新计算商品价格信息并获取商品名称
- 更新订单创建流程,使用计算后的商品价格和名称信息
- 引入 IProductConfigService 接口,用于获取商品配置信息
- 优化异常处理,确保在价格计算失败时有兜底方案
This commit is contained in:
2025-08-29 17:39:52 +08:00
parent 98ae9f2930
commit 93a424058a

View File

@@ -25,7 +25,11 @@ import com.ycwl.basic.pricing.dto.PriceCalculationResult;
import com.ycwl.basic.pricing.dto.ProductItem;
import com.ycwl.basic.pricing.dto.VoucherInfo;
import com.ycwl.basic.pricing.dto.CouponUseRequest;
import com.ycwl.basic.pricing.entity.PriceProductConfig;
import com.ycwl.basic.pricing.entity.PriceTierConfig;
import com.ycwl.basic.pricing.exception.PriceCalculationException;
import com.ycwl.basic.pricing.service.ICouponService;
import com.ycwl.basic.pricing.service.IProductConfigService;
import com.ycwl.basic.pricing.service.IVoucherService;
import com.ycwl.basic.pay.adapter.IPayAdapter;
import com.ycwl.basic.pay.entity.CreateOrderRequest;
@@ -63,6 +67,7 @@ public class OrderServiceImpl implements IOrderService {
private final MemberMapper memberMapper;
private final ICouponService couponService;
private final IVoucherService voucherService;
private final IProductConfigService productConfigService;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -104,15 +109,18 @@ public class OrderServiceImpl implements IOrderService {
// 3. 保存订单商品明细
for (ProductItem product : request.getProducts()) {
// 重新计算商品价格信息并获取商品名称
ProductPriceAndNameInfo priceInfo = calculateProductItemPriceAndName(product);
OrderItemV2 orderItem = new OrderItemV2();
orderItem.setOrderId(orderId);
orderItem.setProductType(product.getProductType().name());
orderItem.setProductId(product.getProductId());
orderItem.setProductName(getProductName(product)); // 根据商品类型和ID获取商品名称
orderItem.setProductName(priceInfo.getProductName()); // 使用配置中的商品名称
orderItem.setQuantity(product.getQuantity() != null ? product.getQuantity() : 1);
orderItem.setUnitPrice(product.getUnitPrice() != null ? product.getUnitPrice() : BigDecimal.ZERO);
orderItem.setOriginalAmount(product.getOriginalPrice() != null ? product.getOriginalPrice() : BigDecimal.ZERO);
orderItem.setFinalAmount(product.getSubtotal() != null ? product.getSubtotal() : BigDecimal.ZERO);
orderItem.setUnitPrice(product.getUnitPrice());
orderItem.setOriginalAmount(product.getOriginalPrice());
orderItem.setFinalAmount(product.getSubtotal());
orderItem.setCreateTime(now);
orderItem.setUpdateTime(now);
@@ -256,14 +264,6 @@ public class OrderServiceImpl implements IOrderService {
return "ORDER" + timestamp + random;
}
/**
* 根据商品类型和ID获取商品名称
* TODO: 实际应该从商品配置表或其他数据源获取
*/
private String getProductName(ProductItem product) {
return product.getProductType().getDescription() + "-" + product.getProductId();
}
// ====== 新增方法实现 ======
@Override
@@ -769,4 +769,116 @@ public class OrderServiceImpl implements IOrderService {
default -> "景区商品";
};
}
/**
* 商品价格和名称信息内部DTO
*/
private static class ProductPriceAndNameInfo {
private BigDecimal unitPrice;
private BigDecimal originalPrice;
private String productName;
public ProductPriceAndNameInfo(BigDecimal unitPrice, BigDecimal originalPrice, String productName) {
this.unitPrice = unitPrice;
this.originalPrice = originalPrice;
this.productName = productName;
}
public BigDecimal getUnitPrice() { return unitPrice; }
public BigDecimal getOriginalPrice() { return originalPrice; }
public String getProductName() { return productName; }
}
/**
* 重新计算商品价格信息并获取商品名称
* 基于定价配置重新计算商品的单价、原价和商品名称
*/
private ProductPriceAndNameInfo calculateProductItemPriceAndName(ProductItem product) {
String productTypeCode = product.getProductType().getCode();
String productId = product.getProductId() != null ? product.getProductId() : "default";
BigDecimal unitPrice;
BigDecimal originalPrice;
String productName;
try {
// 1. 优先使用基于product_id的阶梯定价
PriceTierConfig tierConfig = productConfigService.getTierConfig(
productTypeCode, productId, product.getQuantity());
if (tierConfig != null) {
unitPrice = tierConfig.getPrice();
originalPrice = tierConfig.getOriginalPrice();
// 阶梯定价没有商品名称,需要从基础配置获取
PriceProductConfig baseConfig = productConfigService.getProductConfig(productTypeCode, productId);
productName = (baseConfig != null && baseConfig.getProductName() != null)
? baseConfig.getProductName()
: getProductTypeName(product.getProductType().name());
log.debug("使用阶梯定价: productType={}, productId={}, quantity={}, price={}, originalPrice={}, productName={}",
productTypeCode, productId, product.getQuantity(), unitPrice, originalPrice, productName);
} else {
// 2. 使用基于product_id的基础配置
PriceProductConfig baseConfig;
try {
baseConfig = productConfigService.getProductConfig(productTypeCode, productId);
} catch (Exception e) {
log.warn("未找到具体商品配置: productType={}, productId={}, 使用default配置",
productTypeCode, productId);
baseConfig = productConfigService.getProductConfig(productTypeCode, "default");
}
if (baseConfig == null) {
throw new PriceCalculationException(
String.format("未找到商品价格配置: productType=%s, productId=%s", productTypeCode, productId));
}
unitPrice = baseConfig.getBasePrice();
originalPrice = baseConfig.getOriginalPrice();
productName = (baseConfig.getProductName() != null)
? baseConfig.getProductName()
: getProductTypeName(product.getProductType().name());
// 3. 处理按数量计价的商品类型
if (product.getProductType() == com.ycwl.basic.pricing.enums.ProductType.PHOTO_PRINT ||
product.getProductType() == com.ycwl.basic.pricing.enums.ProductType.MACHINE_PRINT) {
if (product.getQuantity() != null && product.getQuantity() > 0) {
unitPrice = unitPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
if (originalPrice != null) {
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
}
}
}
}
// 4. 设置计算后的价格到ProductItem
product.setUnitPrice(unitPrice);
product.setOriginalPrice(originalPrice != null ? originalPrice : unitPrice);
// 5. 计算小计(单价 × 购买数量)
int purchaseCount = product.getPurchaseCount() != null ? product.getPurchaseCount() : 1;
BigDecimal subtotal = unitPrice.multiply(BigDecimal.valueOf(purchaseCount));
product.setSubtotal(subtotal);
log.debug("商品价格和名称计算完成: productType={}, productId={}, unitPrice={}, originalPrice={}, subtotal={}, productName={}",
productTypeCode, productId, unitPrice, originalPrice, subtotal, productName);
return new ProductPriceAndNameInfo(unitPrice, originalPrice != null ? originalPrice : unitPrice, productName);
} catch (Exception e) {
log.error("计算商品价格失败: productType={}, productId={}, error={}",
productTypeCode, productId, e.getMessage(), e);
// 兜底处理:使用默认价格和类型名称
BigDecimal defaultPrice = BigDecimal.ZERO;
String fallbackName = getProductTypeName(product.getProductType().name());
product.setUnitPrice(defaultPrice);
product.setOriginalPrice(defaultPrice);
product.setSubtotal(defaultPrice);
return new ProductPriceAndNameInfo(defaultPrice, defaultPrice, fallbackName);
}
}
}