【后端】- 打折服务实现

25 年 7 月 26 日 星期六 (已编辑)
531 字
3 分钟

打折服务

折扣分为多种,拼团项目中含有的折扣类型有:

  • 有门槛满减
  • 无门槛满减
  • 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);
}

文章标题:【后端】- 打折服务实现

文章作者:Blank

文章链接:https://blankxiao.github.io/posts/backend/simple-market/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。