refactor(order): 重构重复购买检查和定价逻辑

- 引入商品类型能力配置,替代硬编码的商品类型判断
- 实现策略模式处理不同商品类型的重复购买检查
- 抽象定价模式,支持固定价格和数量计价等不同方式
- 新增策略工厂自动注册各类检查器实现
- 添加缓存机制提升商品类型配置查询性能
- 解耦订单服务与具体商品类型的紧耦合关系
- 提高代码可维护性和扩展性,便于新增商品类型
This commit is contained in:
2025-11-27 09:34:10 +08:00
parent 1945639f90
commit 3ce3972875
15 changed files with 1062 additions and 139 deletions

View File

@@ -6,6 +6,9 @@ import com.ycwl.basic.pricing.entity.PriceTierConfig;
import com.ycwl.basic.pricing.enums.ProductType;
import com.ycwl.basic.pricing.exception.PriceCalculationException;
import com.ycwl.basic.pricing.service.*;
import com.ycwl.basic.product.capability.PricingMode;
import com.ycwl.basic.product.capability.ProductTypeCapability;
import com.ycwl.basic.product.service.IProductTypeCapabilityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -29,16 +32,18 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
private final IPriceBundleService bundleService;
private final IDiscountDetectionService discountDetectionService;
private final IVoucherService voucherService;
private final IProductTypeCapabilityService productTypeCapabilityService;
/**
* 判断是否为打印类商品
* 打印类商品的价格计算方式为:单价 × 数量
* 判断是否为按数量计价的商品
* 重构: 使用商品类型能力配置替代硬编码
*
* @param productType 商品类型代码
* @return true-按数量计价, false-固定价格
*/
private boolean isPrintProduct(ProductType productType) {
return productType == ProductType.PHOTO_PRINT
|| productType == ProductType.PHOTO_PRINT_MU
|| productType == ProductType.PHOTO_PRINT_FX
|| productType == ProductType.MACHINE_PRINT;
private boolean isQuantityBasedPricing(String productType) {
ProductTypeCapability capability = productTypeCapabilityService.getCapability(productType);
return capability.getPricingModeEnum() == PricingMode.QUANTITY_BASED;
}
@Override
@@ -201,7 +206,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
try {
PriceProductConfig baseConfig = productConfigService.getProductConfig(productType.getCode(), productId);
if (baseConfig != null) {
if (isPrintProduct(productType)) {
if (isQuantityBasedPricing(productType.getCode())) {
return baseConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
} else {
return baseConfig.getBasePrice();
@@ -216,7 +221,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
try {
PriceProductConfig defaultConfig = productConfigService.getProductConfig(productType.getCode(), "default");
if (defaultConfig != null) {
if (isPrintProduct(productType)) {
if (isQuantityBasedPricing(productType.getCode())) {
return defaultConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
} else {
return defaultConfig.getBasePrice();
@@ -230,7 +235,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
List<PriceProductConfig> configs = productConfigService.getProductConfig(productType.getCode());
if (!configs.isEmpty()) {
PriceProductConfig baseConfig = configs.get(0); // 使用第一个配置作为默认
if (isPrintProduct(productType)) {
if (isQuantityBasedPricing(productType.getCode())) {
return baseConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
} else {
return baseConfig.getBasePrice();
@@ -264,7 +269,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
actualPrice = baseConfig.getBasePrice();
originalPrice = baseConfig.getOriginalPrice();
if (isPrintProduct(productType)) {
if (isQuantityBasedPricing(productType.getCode())) {
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
if (originalPrice != null) {
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
@@ -284,7 +289,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
actualPrice = defaultConfig.getBasePrice();
originalPrice = defaultConfig.getOriginalPrice();
if (isPrintProduct(productType)) {
if (isQuantityBasedPricing(productType.getCode())) {
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
if (originalPrice != null) {
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
@@ -303,7 +308,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
actualPrice = baseConfig.getBasePrice();
originalPrice = baseConfig.getOriginalPrice();
if (isPrintProduct(productType)) {
if (isQuantityBasedPricing(productType.getCode())) {
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
if (originalPrice != null) {
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));