feat(pricing): 添加商品一口价优惠支持检查

- 在 PriceProductConfig 实体中新增 canUseOnePrice 字段
- 更新数据库插入和更新语句,支持 canUseOnePrice 字段持久化- 在 OnePricePurchaseDiscountProvider 中实现商品一口价优惠支持检查逻辑
- 新增 areAllProductsSupportOnePrice 方法,验证购物车商品是否支持一口价优惠
- 支持查询具体商品配置和默认配置的一口价优惠设置
- 添加日志记录和异常处理,确保检查过程不影响主流程
This commit is contained in:
2025-09-25 10:40:10 +08:00
parent 019b9ffca6
commit 59baf8811b
3 changed files with 68 additions and 5 deletions

View File

@@ -69,6 +69,11 @@ public class PriceProductConfig {
*/ */
private Boolean canUseVoucher; private Boolean canUseVoucher;
/**
* 是否可使用一口价优惠
*/
private Boolean canUseOnePrice;
@TableField("create_time") @TableField("create_time")
private Date createTime; private Date createTime;

View File

@@ -57,15 +57,15 @@ public interface PriceProductConfigMapper extends BaseMapper<PriceProductConfig>
/** /**
* 插入商品价格配置 * 插入商品价格配置
*/ */
@Insert("INSERT INTO price_product_config (product_type, product_id, scenic_id, product_name, base_price, original_price, unit, is_active, can_use_coupon, can_use_voucher, create_time, update_time) " + @Insert("INSERT INTO price_product_config (product_type, product_id, scenic_id, product_name, base_price, original_price, unit, is_active, can_use_coupon, can_use_voucher, can_use_one_price, create_time, update_time) " +
"VALUES (#{productType}, #{productId}, #{scenicId}, #{productName}, #{basePrice}, #{originalPrice}, #{unit}, #{isActive}, #{canUseCoupon}, #{canUseVoucher}, NOW(), NOW())") "VALUES (#{productType}, #{productId}, #{scenicId}, #{productName}, #{basePrice}, #{originalPrice}, #{unit}, #{isActive}, #{canUseCoupon}, #{canUseVoucher}, #{canUseOnePrice}, NOW(), NOW())")
int insertProductConfig(PriceProductConfig config); int insertProductConfig(PriceProductConfig config);
/** /**
* 更新商品价格配置 * 更新商品价格配置
*/ */
@Update("UPDATE price_product_config SET product_id = #{productId}, scenic_id = #{scenicId}, product_name = #{productName}, base_price = #{basePrice}, " + @Update("UPDATE price_product_config SET product_id = #{productId}, scenic_id = #{scenicId}, product_name = #{productName}, base_price = #{basePrice}, " +
"original_price = #{originalPrice}, unit = #{unit}, is_active = #{isActive}, can_use_coupon = #{canUseCoupon}, can_use_voucher = #{canUseVoucher}, update_time = NOW() WHERE id = #{id}") "original_price = #{originalPrice}, unit = #{unit}, is_active = #{isActive}, can_use_coupon = #{canUseCoupon}, can_use_voucher = #{canUseVoucher}, can_use_one_price = #{canUseOnePrice}, update_time = NOW() WHERE id = #{id}")
int updateProductConfig(PriceProductConfig config); int updateProductConfig(PriceProductConfig config);
/** /**

View File

@@ -4,8 +4,11 @@ import com.ycwl.basic.pricing.dto.DiscountDetectionContext;
import com.ycwl.basic.pricing.dto.DiscountInfo; import com.ycwl.basic.pricing.dto.DiscountInfo;
import com.ycwl.basic.pricing.dto.DiscountResult; import com.ycwl.basic.pricing.dto.DiscountResult;
import com.ycwl.basic.pricing.dto.OnePriceInfo; import com.ycwl.basic.pricing.dto.OnePriceInfo;
import com.ycwl.basic.pricing.dto.ProductItem;
import com.ycwl.basic.pricing.entity.PriceProductConfig;
import com.ycwl.basic.pricing.service.IDiscountProvider; import com.ycwl.basic.pricing.service.IDiscountProvider;
import com.ycwl.basic.pricing.service.IOnePricePurchaseService; import com.ycwl.basic.pricing.service.IOnePricePurchaseService;
import com.ycwl.basic.pricing.service.IProductConfigService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -23,6 +26,7 @@ import java.util.List;
public class OnePricePurchaseDiscountProvider implements IDiscountProvider { public class OnePricePurchaseDiscountProvider implements IDiscountProvider {
private final IOnePricePurchaseService onePricePurchaseService; private final IOnePricePurchaseService onePricePurchaseService;
private final IProductConfigService productConfigService;
@Override @Override
public String getProviderType() { public String getProviderType() {
@@ -50,6 +54,12 @@ public class OnePricePurchaseDiscountProvider implements IDiscountProvider {
return discounts; return discounts;
} }
// 检查商品是否支持一口价优惠
if (!areAllProductsSupportOnePrice(context.getProducts())) {
log.debug("存在不支持一口价优惠的商品,跳过一口价检测");
return discounts;
}
// 获取一口价信息 // 获取一口价信息
OnePriceInfo onePriceInfo = onePricePurchaseService.getOnePriceInfo( OnePriceInfo onePriceInfo = onePricePurchaseService.getOnePriceInfo(
context.getScenicId(), context.getCurrentAmount()); context.getScenicId(), context.getCurrentAmount());
@@ -170,6 +180,54 @@ public class OnePricePurchaseDiscountProvider implements IDiscountProvider {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
/**
* 检查购物车中的所有商品是否都支持一口价优惠
*/
private boolean areAllProductsSupportOnePrice(List<ProductItem> products) {
if (products == null || products.isEmpty()) {
return true; // 空购物车时默认支持
}
for (ProductItem product : products) {
try {
// 查询商品配置
PriceProductConfig productConfig = productConfigService.getProductConfig(
product.getProductType().getCode(), product.getProductId());
if (productConfig != null) {
// 检查商品是否支持一口价优惠
if (Boolean.FALSE.equals(productConfig.getCanUseOnePrice())) {
log.debug("商品 {}({}) 不支持一口价优惠",
product.getProductType().getCode(), product.getProductId());
return false;
}
} else {
// 如果找不到具体商品配置,尝试查询 default 配置
PriceProductConfig defaultConfig = productConfigService.getProductConfig(
product.getProductType().getCode(), "default");
if (defaultConfig != null) {
if (Boolean.FALSE.equals(defaultConfig.getCanUseOnePrice())) {
log.debug("商品类型 {} 的默认配置不支持一口价优惠",
product.getProductType().getCode());
return false;
}
} else {
// 如果既没有具体配置也没有默认配置,默认支持一口价优惠
log.debug("商品 {}({}) 未找到价格配置,默认支持一口价优惠",
product.getProductType().getCode(), product.getProductId());
}
}
} catch (Exception e) {
log.warn("检查商品 {}({}) 一口价优惠支持情况时发生异常,默认支持",
product.getProductType().getCode(), product.getProductId(), e);
// 异常情况下默认支持,避免影响正常业务流程
}
}
return true;
}
/** /**
* 检查优惠叠加规则 * 检查优惠叠加规则
*/ */