You've already forked FrameTour-BE
feat(pricing): 添加查询接口并优化配置管理
- 新增多个查询接口,包括商品配置、阶梯配置和一口价配置的查询- 优化配置管理逻辑,支持 default 配置的创建和使用 - 重构部分代码,提高可维护性和可扩展性
This commit is contained in:
@@ -34,6 +34,13 @@ public interface IPriceBundleService {
|
||||
*/
|
||||
List<PriceBundleConfig> getActiveBundles();
|
||||
|
||||
/**
|
||||
* 获取所有一口价配置(仅启用的)
|
||||
*
|
||||
* @return 一口价配置列表
|
||||
*/
|
||||
List<PriceBundleConfig> getAllBundles();
|
||||
|
||||
// ==================== 管理端接口(包含禁用的配置) ====================
|
||||
|
||||
/**
|
||||
|
@@ -44,6 +44,13 @@ public interface IProductConfigService {
|
||||
*/
|
||||
List<PriceProductConfig> getActiveProductConfigs();
|
||||
|
||||
/**
|
||||
* 获取所有商品配置(仅启用的)
|
||||
*
|
||||
* @return 商品配置列表
|
||||
*/
|
||||
List<PriceProductConfig> getAllProductConfigs();
|
||||
|
||||
/**
|
||||
* 根据商品类型获取所有阶梯配置
|
||||
*
|
||||
|
@@ -2,6 +2,7 @@ package com.ycwl.basic.pricing.service.impl;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ycwl.basic.pricing.dto.BundleProductItem;
|
||||
import com.ycwl.basic.pricing.dto.ProductItem;
|
||||
import com.ycwl.basic.pricing.entity.PriceBundleConfig;
|
||||
import com.ycwl.basic.pricing.enums.ProductType;
|
||||
@@ -76,6 +77,12 @@ public class PriceBundleServiceImpl implements IPriceBundleService {
|
||||
return bundleConfigMapper.selectActiveBundles();
|
||||
}
|
||||
|
||||
@Override
|
||||
// @Cacheable(value = "all-bundles")
|
||||
public List<PriceBundleConfig> getAllBundles() {
|
||||
return bundleConfigMapper.selectActiveBundles();
|
||||
}
|
||||
|
||||
// ==================== 管理端接口(包含禁用的配置) ====================
|
||||
|
||||
@Override
|
||||
@@ -85,23 +92,27 @@ public class PriceBundleServiceImpl implements IPriceBundleService {
|
||||
|
||||
private boolean isProductsMatchBundle(Set<String> productTypes, PriceBundleConfig bundle) {
|
||||
try {
|
||||
List<String> includedProducts = objectMapper.readValue(
|
||||
bundle.getIncludedProducts(), new TypeReference<List<String>>() {});
|
||||
|
||||
Set<String> requiredProducts = new HashSet<>(includedProducts);
|
||||
// 检查包含的商品
|
||||
if (bundle.getIncludedProducts() != null && !bundle.getIncludedProducts().isEmpty()) {
|
||||
Set<String> requiredProducts = new HashSet<>();
|
||||
for (BundleProductItem item : bundle.getIncludedProducts()) {
|
||||
requiredProducts.add(item.getType());
|
||||
}
|
||||
if (!productTypes.containsAll(requiredProducts)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查排除的商品
|
||||
if (bundle.getExcludedProducts() != null && !bundle.getExcludedProducts().isEmpty()) {
|
||||
List<String> excludedProducts = objectMapper.readValue(
|
||||
bundle.getExcludedProducts(), new TypeReference<List<String>>() {});
|
||||
|
||||
for (String excludedProduct : excludedProducts) {
|
||||
if (productTypes.contains(excludedProduct)) {
|
||||
for (BundleProductItem item : bundle.getExcludedProducts()) {
|
||||
if (productTypes.contains(item.getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return productTypes.containsAll(requiredProducts);
|
||||
return true;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("解析一口价配置失败: bundleId={}", bundle.getId(), e);
|
||||
|
@@ -163,7 +163,21 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
||||
productType, productId);
|
||||
}
|
||||
|
||||
// 兜底:使用通用配置(向后兼容)
|
||||
// 兜底:使用default配置
|
||||
try {
|
||||
PriceProductConfig defaultConfig = productConfigService.getProductConfig(productType.getCode(), "default");
|
||||
if (defaultConfig != null) {
|
||||
if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
|
||||
return defaultConfig.getBasePrice().multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
} else {
|
||||
return defaultConfig.getBasePrice();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("未找到default配置: productType={}", productType.getCode());
|
||||
}
|
||||
|
||||
// 最后兜底:使用通用配置(向后兼容)
|
||||
List<PriceProductConfig> configs = productConfigService.getProductConfig(productType.getCode());
|
||||
if (!configs.isEmpty()) {
|
||||
PriceProductConfig baseConfig = configs.get(0); // 使用第一个配置作为默认
|
||||
@@ -214,21 +228,41 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
||||
log.warn("未找到具体商品配置: productType={}, productId={}, 尝试使用通用配置",
|
||||
productType, productId);
|
||||
|
||||
// 兜底:使用通用配置(向后兼容)
|
||||
List<PriceProductConfig> configs = productConfigService.getProductConfig(productType.getCode());
|
||||
if (!configs.isEmpty()) {
|
||||
PriceProductConfig baseConfig = configs.getFirst(); // 使用第一个配置作为默认
|
||||
actualPrice = baseConfig.getBasePrice();
|
||||
originalPrice = baseConfig.getOriginalPrice();
|
||||
|
||||
if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
|
||||
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
if (originalPrice != null) {
|
||||
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
// 兜底:使用default配置
|
||||
try {
|
||||
PriceProductConfig defaultConfig = productConfigService.getProductConfig(productType.getCode(), "default");
|
||||
if (defaultConfig != null) {
|
||||
actualPrice = defaultConfig.getBasePrice();
|
||||
originalPrice = defaultConfig.getOriginalPrice();
|
||||
|
||||
if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
|
||||
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
if (originalPrice != null) {
|
||||
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new PriceCalculationException("无法找到default配置");
|
||||
}
|
||||
} catch (Exception defaultEx) {
|
||||
log.warn("未找到default配置: productType={}", productType.getCode());
|
||||
|
||||
// 最后兜底:使用通用配置(向后兼容)
|
||||
List<PriceProductConfig> configs = productConfigService.getProductConfig(productType.getCode());
|
||||
if (!configs.isEmpty()) {
|
||||
PriceProductConfig baseConfig = configs.getFirst(); // 使用第一个配置作为默认
|
||||
actualPrice = baseConfig.getBasePrice();
|
||||
originalPrice = baseConfig.getOriginalPrice();
|
||||
|
||||
if (productType == ProductType.PHOTO_PRINT || productType == ProductType.MACHINE_PRINT) {
|
||||
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
if (originalPrice != null) {
|
||||
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new PriceCalculationException("无法计算商品价格: " + productType.getDescription() + ", productId: " + productId);
|
||||
}
|
||||
} else {
|
||||
throw new PriceCalculationException("无法计算商品价格: " + productType.getDescription() + ", productId: " + productId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -27,6 +27,14 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
|
||||
@Override
|
||||
@Transactional
|
||||
public Long createProductConfig(PriceProductConfig config) {
|
||||
// 校验:如果是default配置,确保该商品类型只能有一个default配置
|
||||
if ("default".equals(config.getProductId())) {
|
||||
int existingCount = productConfigMapper.countDefaultConfigsByProductType(config.getProductType());
|
||||
if (existingCount > 0) {
|
||||
throw new IllegalArgumentException("商品类型 " + config.getProductType() + " 的default配置已存在,每种商品类型只能有一个default配置");
|
||||
}
|
||||
}
|
||||
|
||||
config.setCreatedTime(LocalDateTime.now());
|
||||
config.setUpdatedTime(LocalDateTime.now());
|
||||
productConfigMapper.insertProductConfig(config);
|
||||
@@ -43,6 +51,13 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
|
||||
@Override
|
||||
@Transactional
|
||||
public Long createTierConfig(PriceTierConfig config) {
|
||||
// 校验:如果是default配置,检查是否可以创建
|
||||
if ("default".equals(config.getProductId())) {
|
||||
// 对于阶梯配置,可以有多个default配置(不同数量区间),不需要限制
|
||||
log.info("创建default阶梯配置: productType={}, quantity range: {}-{}",
|
||||
config.getProductType(), config.getMinQuantity(), config.getMaxQuantity());
|
||||
}
|
||||
|
||||
config.setCreatedTime(LocalDateTime.now());
|
||||
config.setUpdatedTime(LocalDateTime.now());
|
||||
tierConfigMapper.insertTierConfig(config);
|
||||
|
@@ -44,6 +44,18 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
||||
// @Cacheable(value = "tier-config", key = "#productType + '_' + #productId + '_' + #quantity")
|
||||
public PriceTierConfig getTierConfig(String productType, String productId, Integer quantity) {
|
||||
PriceTierConfig config = tierConfigMapper.selectByProductTypeAndQuantity(productType, productId, quantity);
|
||||
|
||||
// 如果没有找到特定商品的阶梯配置,尝试使用default配置
|
||||
if (config == null && !"default".equals(productId)) {
|
||||
log.warn("阶梯定价配置未找到: productType={}, productId={}, quantity={}, 尝试使用default配置",
|
||||
productType, productId, quantity);
|
||||
config = tierConfigMapper.selectByProductTypeAndQuantity(productType, "default", quantity);
|
||||
if (config != null) {
|
||||
log.debug("使用default阶梯配置: productType={}, quantity={}, price={}",
|
||||
productType, quantity, config.getPrice());
|
||||
}
|
||||
}
|
||||
|
||||
if (config == null) {
|
||||
log.warn("阶梯定价配置未找到: productType={}, productId={}, quantity={}",
|
||||
productType, productId, quantity);
|
||||
@@ -57,6 +69,12 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
||||
return productConfigMapper.selectActiveConfigs();
|
||||
}
|
||||
|
||||
@Override
|
||||
// @Cacheable(value = "all-product-configs")
|
||||
public List<PriceProductConfig> getAllProductConfigs() {
|
||||
return productConfigMapper.selectActiveConfigs();
|
||||
}
|
||||
|
||||
@Override
|
||||
// @Cacheable(value = "tier-configs", key = "#productType")
|
||||
public List<PriceTierConfig> getTierConfigs(String productType) {
|
||||
|
Reference in New Issue
Block a user