打折服务
折扣分为多种,拼团项目中含有的折扣类型有:
- 有门槛满减
- 无门槛满减
- N元购(无论原价多少,直接按N元购买)
- 打折
策略模式实现

首先定义打折服务接口 含有根据用户ID、商品原价、折扣计划配置计算商品优惠价格的方法
java
public interface IDiscountCalculateService {
/**
* 折扣计算
*
* @param userId 用户ID
* @param originalPrice 商品原始价格
* @param groupBuyDiscount 折扣计划配置
* @return 商品优惠价格
*/
BigDecimal calculate(String userId, BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount);
}
考虑到只有特定用户才能享受打折服务,因此需要一个抽象类实现该接口,并添加筛选用户的方法
java
public abstract class AbstractDiscountCalculateService implements IDiscountCalculateService {
@Override
public BigDecimal calculate(String userId, BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
// 1. 人群标签过滤
if (DiscountTypeEnum.TAG.equals(groupBuyDiscount.getDiscountType())){
boolean isCrowdRange = filterTagId(userId, groupBuyDiscount.getTagId());
if (!isCrowdRange) return originalPrice;
}
// 2. 折扣优惠计算
return doCalculate(originalPrice, groupBuyDiscount);
}
// 人群过滤 - 限定人群优惠
private boolean filterTagId(String userId, String tagId) {
// todo 后续开发这部分
return true;
}
protected abstract BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount);
}
然后实现具体的打折服务类,继承抽象类并实现doCalculate方法
java
@Slf4j
@Service("MJ") // 给service添加名称 后续可以根据名称获取对应的打折服务
public class MJCalculateService extends AbstractDiscountCalculateService {
@Override
public BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
log.info("优惠策略折扣计算:{}", groupBuyDiscount.getDiscountType().getCode());
// 折扣表达式 - 100,10 满100减10元
String marketExpr = groupBuyDiscount.getMarketExpr();
String[] split = marketExpr.split(Constants.SPLIT);
BigDecimal x = new BigDecimal(split[0].trim());
BigDecimal y = new BigDecimal(split[1].trim());
// 不满足最低满减约束,则按照原价
if (originalPrice.compareTo(x) < 0) {
return originalPrice;
}
// 折扣价格
BigDecimal deductionPrice = originalPrice.subtract(y);
// 判断折扣后金额,最低支付1分钱
if (deductionPrice.compareTo(BigDecimal.ZERO) <= 0) {
return new BigDecimal("0.01");
}
return deductionPrice;
}
}
其他服务有些重复,这里省略
在使用时 可以通过Map<String, IDiscountCalculateService>
来存储所有的打折服务
java
@Resource
private Map<String, IDiscountCalculateService> discountCalculateServiceMap;
public BigDecimal calculateDiscountPrice(String userId, BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
// 获取打折服务
IDiscountCalculateService discountCalculateService = discountCalculateServiceMap.get(groupBuyDiscount.getDiscountType().getCode());
if (discountCalculateService == null) {
throw new IllegalArgumentException("不支持的折扣类型: " + groupBuyDiscount.getDiscountType().getCode());
}
// 调用打折服务计算价格
return discountCalculateService.calculate(userId, originalPrice, groupBuyDiscount);
}