You've already forked FrameTour-BE
feat(pricing): 新增优惠券属性门槛校验功能
- 在PriceCouponConfig实体中新增requiredAttributeKeys字段,用于配置优惠券使用门槛 - 修改MyBatis Mapper SQL语句,支持新字段的插入和更新操作 - 在CouponManagementServiceImpl中增加对requiredAttributeKeys的格式校验逻辑 - 更新CouponServiceImpl的优惠券适用性检查逻辑,增加属性门槛判断 - 在PriceCalculationServiceImpl中实现商品属性Key的自动计算与填充 - 优化价格计算服务中的能力缓存与属性Key构建逻辑 - 更新CLAUDE.md文档,补充属性门槛特性的说明
This commit is contained in:
@@ -120,6 +120,7 @@ public enum CouponStatus { CLAIMED("claimed", ...), USED("used", ...), EXPIRED("
|
|||||||
|
|
||||||
#### 关键特性
|
#### 关键特性
|
||||||
- 商品类型限制:通过 JSON 字段(结合 `ProductTypeListTypeHandler`)控制适用商品
|
- 商品类型限制:通过 JSON 字段(结合 `ProductTypeListTypeHandler`)控制适用商品
|
||||||
|
- 属性门槛:通过 `requiredAttributeKeys`(JSON) 配置,要求在可折扣商品范围内任一商品出现任一属性Key(属性Key为后端与运营约定的字符串);商品属性由服务端根据商品能力配置(`ProductTypeCapability.metadata.pricingAttributeKeys`)计算写入 `ProductItem.attributeKeys`
|
||||||
- 消费限制:支持最小消费金额、最大折扣限制
|
- 消费限制:支持最小消费金额、最大折扣限制
|
||||||
- 时效性:基于时间的有效期控制
|
- 时效性:基于时间的有效期控制
|
||||||
- **用户领取数量限制**:通过 `userClaimLimit` 字段控制单个用户可领取优惠券的最大数量(v1.0.0新增)
|
- **用户领取数量限制**:通过 `userClaimLimit` 字段控制单个用户可领取优惠券的最大数量(v1.0.0新增)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.ycwl.basic.pricing.enums.ProductType;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品项DTO
|
* 商品项DTO
|
||||||
@@ -50,4 +51,9 @@ public class ProductItem {
|
|||||||
* 景区ID
|
* 景区ID
|
||||||
*/
|
*/
|
||||||
private String scenicId;
|
private String scenicId;
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* 商品属性Key列表(服务端计算填充,客户端传入会被忽略)
|
||||||
|
*/
|
||||||
|
private List<String> attributeKeys;
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ public class PriceCouponConfig {
|
|||||||
* 适用商品类型(JSON)
|
* 适用商品类型(JSON)
|
||||||
*/
|
*/
|
||||||
private String applicableProducts;
|
private String applicableProducts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券使用门槛:要求在可折扣商品范围内出现指定属性Key(JSON)
|
||||||
|
* 为空表示不限制
|
||||||
|
*/
|
||||||
|
private String requiredAttributeKeys;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发行总量
|
* 发行总量
|
||||||
@@ -104,4 +110,4 @@ public class PriceCouponConfig {
|
|||||||
private Integer deleted;
|
private Integer deleted;
|
||||||
|
|
||||||
private Date deletedAt;
|
private Date deletedAt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ public interface PriceCouponConfigMapper extends BaseMapper<PriceCouponConfig> {
|
|||||||
*/
|
*/
|
||||||
@Insert("INSERT INTO price_coupon_config (coupon_name, coupon_type, discount_value, min_amount, " +
|
@Insert("INSERT INTO price_coupon_config (coupon_name, coupon_type, discount_value, min_amount, " +
|
||||||
"max_discount, applicable_products, total_quantity, used_quantity, valid_from, valid_until, " +
|
"max_discount, applicable_products, total_quantity, used_quantity, valid_from, valid_until, " +
|
||||||
"is_active, scenic_id, create_time, update_time) VALUES " +
|
"required_attribute_keys, is_active, scenic_id, create_time, update_time) VALUES " +
|
||||||
"(#{couponName}, #{couponType}, #{discountValue}, #{minAmount}, #{maxDiscount}, " +
|
"(#{couponName}, #{couponType}, #{discountValue}, #{minAmount}, #{maxDiscount}, " +
|
||||||
"#{applicableProducts}, #{totalQuantity}, #{usedQuantity}, #{validFrom}, #{validUntil}, " +
|
"#{applicableProducts}, #{requiredAttributeKeys}, #{totalQuantity}, #{usedQuantity}, #{validFrom}, #{validUntil}, " +
|
||||||
"#{isActive}, #{scenicId}, NOW(), NOW())")
|
"#{isActive}, #{scenicId}, NOW(), NOW())")
|
||||||
int insertCoupon(PriceCouponConfig coupon);
|
int insertCoupon(PriceCouponConfig coupon);
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ public interface PriceCouponConfigMapper extends BaseMapper<PriceCouponConfig> {
|
|||||||
*/
|
*/
|
||||||
@Update("UPDATE price_coupon_config SET coupon_name = #{couponName}, coupon_type = #{couponType}, " +
|
@Update("UPDATE price_coupon_config SET coupon_name = #{couponName}, coupon_type = #{couponType}, " +
|
||||||
"discount_value = #{discountValue}, min_amount = #{minAmount}, max_discount = #{maxDiscount}, " +
|
"discount_value = #{discountValue}, min_amount = #{minAmount}, max_discount = #{maxDiscount}, " +
|
||||||
"applicable_products = #{applicableProducts}, total_quantity = #{totalQuantity}, " +
|
"applicable_products = #{applicableProducts}, required_attribute_keys = #{requiredAttributeKeys}, total_quantity = #{totalQuantity}, " +
|
||||||
"valid_from = #{validFrom}, valid_until = #{validUntil}, is_active = #{isActive}, " +
|
"valid_from = #{validFrom}, valid_until = #{validUntil}, is_active = #{isActive}, " +
|
||||||
"scenic_id = #{scenicId}, update_time = NOW() WHERE id = #{id}")
|
"scenic_id = #{scenicId}, update_time = NOW() WHERE id = #{id}")
|
||||||
int updateCoupon(PriceCouponConfig coupon);
|
int updateCoupon(PriceCouponConfig coupon);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.ycwl.basic.pricing.service.impl;
|
package com.ycwl.basic.pricing.service.impl;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import com.github.pagehelper.PageInfo;
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord;
|
import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord;
|
||||||
@@ -26,9 +28,12 @@ import java.util.Map;
|
|||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class CouponManagementServiceImpl implements ICouponManagementService {
|
public class CouponManagementServiceImpl implements ICouponManagementService {
|
||||||
|
|
||||||
|
private static final TypeReference<List<String>> STRING_LIST_TYPE = new TypeReference<>() {};
|
||||||
|
|
||||||
private final PriceCouponConfigMapper couponConfigMapper;
|
private final PriceCouponConfigMapper couponConfigMapper;
|
||||||
private final PriceCouponClaimRecordMapper claimRecordMapper;
|
private final PriceCouponClaimRecordMapper claimRecordMapper;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
// ==================== 优惠券配置管理 ====================
|
// ==================== 优惠券配置管理 ====================
|
||||||
|
|
||||||
@@ -36,6 +41,8 @@ public class CouponManagementServiceImpl implements ICouponManagementService {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public Long createCouponConfig(PriceCouponConfig config) {
|
public Long createCouponConfig(PriceCouponConfig config) {
|
||||||
log.info("创建优惠券配置: {}", config.getCouponName());
|
log.info("创建优惠券配置: {}", config.getCouponName());
|
||||||
|
|
||||||
|
validateCouponConfig(config);
|
||||||
|
|
||||||
// 设置默认值
|
// 设置默认值
|
||||||
if (config.getUsedQuantity() == null) {
|
if (config.getUsedQuantity() == null) {
|
||||||
@@ -59,6 +66,8 @@ public class CouponManagementServiceImpl implements ICouponManagementService {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public boolean updateCouponConfig(PriceCouponConfig config) {
|
public boolean updateCouponConfig(PriceCouponConfig config) {
|
||||||
log.info("更新优惠券配置,ID: {}", config.getId());
|
log.info("更新优惠券配置,ID: {}", config.getId());
|
||||||
|
|
||||||
|
validateCouponConfig(config);
|
||||||
|
|
||||||
PriceCouponConfig existing = couponConfigMapper.selectById(config.getId());
|
PriceCouponConfig existing = couponConfigMapper.selectById(config.getId());
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
@@ -75,6 +84,32 @@ public class CouponManagementServiceImpl implements ICouponManagementService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateCouponConfig(PriceCouponConfig config) {
|
||||||
|
validateRequiredAttributeKeys(config.getRequiredAttributeKeys());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateRequiredAttributeKeys(String requiredAttributeKeys) {
|
||||||
|
if (requiredAttributeKeys == null || requiredAttributeKeys.isBlank()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> keys;
|
||||||
|
try {
|
||||||
|
keys = objectMapper.readValue(requiredAttributeKeys, STRING_LIST_TYPE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("requiredAttributeKeys格式错误,必须是JSON数组字符串,例如 [\"TYPE_3\"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keys == null || keys.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasBlankKey = keys.stream().anyMatch(key -> key == null || key.trim().isEmpty());
|
||||||
|
if (hasBlankKey) {
|
||||||
|
throw new IllegalArgumentException("requiredAttributeKeys不能包含空值");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -250,4 +285,4 @@ public class CouponManagementServiceImpl implements ICouponManagementService {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,23 +118,63 @@ public class CouponServiceImpl implements ICouponService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 检查商品类型限制
|
// 3. 检查商品类型限制(用于确定可折扣商品范围)
|
||||||
if (coupon.getApplicableProducts() == null || coupon.getApplicableProducts().isEmpty()) {
|
List<ProductItem> discountableProducts = products;
|
||||||
|
if (coupon.getApplicableProducts() != null && !coupon.getApplicableProducts().isEmpty()) {
|
||||||
|
try {
|
||||||
|
List<String> applicableProductTypes = objectMapper.readValue(
|
||||||
|
coupon.getApplicableProducts(), new TypeReference<List<String>>() {});
|
||||||
|
|
||||||
|
discountableProducts = products.stream()
|
||||||
|
.filter(product -> applicableProductTypes.contains(product.getProductType().getCode()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (discountableProducts.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("解析适用商品类型失败", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查属性门槛:要求在可折扣商品范围内,任一商品出现任一属性Key
|
||||||
|
if (coupon.getRequiredAttributeKeys() == null || coupon.getRequiredAttributeKeys().isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<String> applicableProductTypes = objectMapper.readValue(
|
List<String> requiredAttributeKeys = objectMapper.readValue(
|
||||||
coupon.getApplicableProducts(), new TypeReference<List<String>>() {});
|
coupon.getRequiredAttributeKeys(), new TypeReference<List<String>>() {});
|
||||||
|
if (requiredAttributeKeys == null || requiredAttributeKeys.isEmpty()) {
|
||||||
for (ProductItem product : products) {
|
return true;
|
||||||
if (applicableProductTypes.contains(product.getProductType().getCode())) {
|
}
|
||||||
return true;
|
|
||||||
|
for (ProductItem product : discountableProducts) {
|
||||||
|
List<String> attributeKeys = product.getAttributeKeys();
|
||||||
|
if (attributeKeys == null || attributeKeys.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String requiredKey : requiredAttributeKeys) {
|
||||||
|
if (requiredKey == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = requiredKey.trim();
|
||||||
|
if (key.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attributeKeys.contains(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("解析适用商品类型失败", e);
|
log.error("解析优惠券属性门槛失败", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ import java.math.BigDecimal;
|
|||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 价格计算服务实现
|
* 价格计算服务实现
|
||||||
@@ -26,6 +30,8 @@ import java.util.List;
|
|||||||
@Service("pricingCalculationServiceImpl")
|
@Service("pricingCalculationServiceImpl")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
||||||
|
|
||||||
|
private static final String CAPABILITY_METADATA_ATTRIBUTE_KEYS = "pricingAttributeKeys";
|
||||||
|
|
||||||
private final IProductConfigService productConfigService;
|
private final IProductConfigService productConfigService;
|
||||||
private final ICouponService couponService;
|
private final ICouponService couponService;
|
||||||
@@ -46,6 +52,13 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
return capability.getPricingModeEnum() == PricingMode.QUANTITY_BASED;
|
return capability.getPricingModeEnum() == PricingMode.QUANTITY_BASED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isQuantityBasedPricing(ProductTypeCapability capability) {
|
||||||
|
if (capability == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return capability.getPricingModeEnum() == PricingMode.QUANTITY_BASED;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PriceCalculationResult calculatePrice(PriceCalculationRequest request) {
|
public PriceCalculationResult calculatePrice(PriceCalculationRequest request) {
|
||||||
if (request.getProducts() == null || request.getProducts().isEmpty()) {
|
if (request.getProducts() == null || request.getProducts().isEmpty()) {
|
||||||
@@ -166,9 +179,16 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||||
BigDecimal originalTotalAmount = BigDecimal.ZERO;
|
BigDecimal originalTotalAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
Map<String, ProductTypeCapability> capabilityCache = new HashMap<>();
|
||||||
|
Map<String, List<String>> attributeKeysCache = new HashMap<>();
|
||||||
|
|
||||||
for (ProductItem product : products) {
|
for (ProductItem product : products) {
|
||||||
|
String productTypeCode = product.getProductType().getCode();
|
||||||
|
ProductTypeCapability capability = capabilityCache.computeIfAbsent(
|
||||||
|
productTypeCode, productTypeCapabilityService::getCapability);
|
||||||
|
|
||||||
// 计算实际价格和原价(传入景区ID)
|
// 计算实际价格和原价(传入景区ID)
|
||||||
ProductPriceInfo priceInfo = calculateSingleProductPriceWithOriginal(product, scenicId);
|
ProductPriceInfo priceInfo = calculateSingleProductPriceWithOriginal(product, scenicId, capability);
|
||||||
|
|
||||||
product.setUnitPrice(priceInfo.getActualPrice());
|
product.setUnitPrice(priceInfo.getActualPrice());
|
||||||
product.setOriginalPrice(priceInfo.getOriginalPrice());
|
product.setOriginalPrice(priceInfo.getOriginalPrice());
|
||||||
@@ -176,6 +196,13 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
BigDecimal subtotal = priceInfo.getActualPrice().multiply(BigDecimal.valueOf(product.getPurchaseCount()));
|
BigDecimal subtotal = priceInfo.getActualPrice().multiply(BigDecimal.valueOf(product.getPurchaseCount()));
|
||||||
BigDecimal originalSubtotal = priceInfo.getOriginalPrice().multiply(BigDecimal.valueOf(product.getPurchaseCount()));
|
BigDecimal originalSubtotal = priceInfo.getOriginalPrice().multiply(BigDecimal.valueOf(product.getPurchaseCount()));
|
||||||
|
|
||||||
|
List<String> attributeKeys = attributeKeysCache.get(productTypeCode);
|
||||||
|
if (attributeKeys == null) {
|
||||||
|
attributeKeys = buildProductAttributeKeys(capability);
|
||||||
|
attributeKeysCache.put(productTypeCode, attributeKeys);
|
||||||
|
}
|
||||||
|
product.setAttributeKeys(attributeKeys);
|
||||||
|
|
||||||
product.setSubtotal(subtotal);
|
product.setSubtotal(subtotal);
|
||||||
|
|
||||||
totalAmount = totalAmount.add(subtotal);
|
totalAmount = totalAmount.add(subtotal);
|
||||||
@@ -187,6 +214,51 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
originalTotalAmount.setScale(2, RoundingMode.HALF_UP)
|
originalTotalAmount.setScale(2, RoundingMode.HALF_UP)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> buildProductAttributeKeys(ProductTypeCapability capability) {
|
||||||
|
if (capability == null || capability.getMetadata() == null) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
Object rawValue = capability.getMetadata().get(CAPABILITY_METADATA_ATTRIBUTE_KEYS);
|
||||||
|
if (rawValue == null) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> result = new LinkedHashSet<>();
|
||||||
|
if (rawValue instanceof List<?> rawList) {
|
||||||
|
for (Object item : rawList) {
|
||||||
|
if (item instanceof String rawKey) {
|
||||||
|
addAttributeKey(result, rawKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (rawValue instanceof String rawString) {
|
||||||
|
String[] parts = rawString.split(",");
|
||||||
|
for (String part : parts) {
|
||||||
|
addAttributeKey(result, part);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("商品类型能力metadata中{}字段类型不支持: productType={}, valueType={}",
|
||||||
|
CAPABILITY_METADATA_ATTRIBUTE_KEYS,
|
||||||
|
capability.getProductType(),
|
||||||
|
rawValue.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.isEmpty() ? List.of() : List.copyOf(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAttributeKey(Set<String> target, String rawKey) {
|
||||||
|
if (rawKey == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = rawKey.trim();
|
||||||
|
if (key.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.add(key);
|
||||||
|
}
|
||||||
|
|
||||||
private BigDecimal calculateSingleProductPrice(ProductItem product) {
|
private BigDecimal calculateSingleProductPrice(ProductItem product) {
|
||||||
ProductType productType = product.getProductType();
|
ProductType productType = product.getProductType();
|
||||||
@@ -245,7 +317,8 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
throw new PriceCalculationException("无法计算商品价格: " + productType.getDescription() + ", productId: " + productId);
|
throw new PriceCalculationException("无法计算商品价格: " + productType.getDescription() + ", productId: " + productId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ProductPriceInfo calculateSingleProductPriceWithOriginal(ProductItem product, Long scenicId) {
|
private ProductPriceInfo calculateSingleProductPriceWithOriginal(ProductItem product, Long scenicId,
|
||||||
|
ProductTypeCapability capability) {
|
||||||
ProductType productType = product.getProductType();
|
ProductType productType = product.getProductType();
|
||||||
String productId = product.getProductId() != null ? product.getProductId() : "default";
|
String productId = product.getProductId() != null ? product.getProductId() : "default";
|
||||||
|
|
||||||
@@ -269,7 +342,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
actualPrice = baseConfig.getBasePrice();
|
actualPrice = baseConfig.getBasePrice();
|
||||||
originalPrice = baseConfig.getOriginalPrice();
|
originalPrice = baseConfig.getOriginalPrice();
|
||||||
|
|
||||||
if (isQuantityBasedPricing(productType.getCode())) {
|
if (isQuantityBasedPricing(capability)) {
|
||||||
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||||
if (originalPrice != null) {
|
if (originalPrice != null) {
|
||||||
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||||
@@ -289,7 +362,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
actualPrice = defaultConfig.getBasePrice();
|
actualPrice = defaultConfig.getBasePrice();
|
||||||
originalPrice = defaultConfig.getOriginalPrice();
|
originalPrice = defaultConfig.getOriginalPrice();
|
||||||
|
|
||||||
if (isQuantityBasedPricing(productType.getCode())) {
|
if (isQuantityBasedPricing(capability)) {
|
||||||
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||||
if (originalPrice != null) {
|
if (originalPrice != null) {
|
||||||
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||||
@@ -308,7 +381,7 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
actualPrice = baseConfig.getBasePrice();
|
actualPrice = baseConfig.getBasePrice();
|
||||||
originalPrice = baseConfig.getOriginalPrice();
|
originalPrice = baseConfig.getOriginalPrice();
|
||||||
|
|
||||||
if (isQuantityBasedPricing(productType.getCode())) {
|
if (isQuantityBasedPricing(capability)) {
|
||||||
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
actualPrice = actualPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||||
if (originalPrice != null) {
|
if (originalPrice != null) {
|
||||||
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
originalPrice = originalPrice.multiply(BigDecimal.valueOf(product.getQuantity()));
|
||||||
@@ -426,4 +499,4 @@ public class PriceCalculationServiceImpl implements IPriceCalculationService {
|
|||||||
// 不抛出异常,避免影响主流程
|
// 不抛出异常,避免影响主流程
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user