优惠券的最佳利用策略:如何在Java代码中优化优惠券的使用


在电商系统或其他在线交易平台中,优惠券的使用逻辑往往是影响用户体验的重要一环。今天,我们就通过一个实际的代码示例,来深入探讨如何筛选和使用用户的优惠券。

代码分步讲解

1. 初始化结果集合

List<AvailableCouponVo> availableCouponVoList = new ArrayList<>();

首先,我们创建一个空的List集合,用于存储最终可用的优惠券信息。

2. 获取用户未使用的优惠券

List<NoUseCouponVo> list = couponInfoMapper.findNoUseList(customerId);

通过customerId查询用户未使用的优惠券列表。这个方法通常会调用数据库接口,返回用户所有未使用的优惠券。

3. 筛选优惠券类型

优惠券一般分为两种:现金券折扣券。接下来,我们将根据类型分别处理。

3.1 处理现金券
List<NoUseCouponVo> typeList = list.stream().filter(item -> item.getCouponType() == 1)
                                   .collect(Collectors.toList());

这里通过流操作过滤出所有类型为“现金券”的优惠券。对于每一张现金券,我们会进一步判断是否符合使用条件。

3.1.1 无门槛现金券
if (noUseCouponVo.getConditionAmount().doubleValue() == 0 && orderAmount.subtract(reduceAmount)
                                                                        .doubleValue() >= 0) {
    availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
}

如果现金券没有使用门槛(ConditionAmount为0),并且订单金额大于等于优惠券减免的金额,则将其加入可用优惠券列表。

3.1.2 有门槛现金券
if (noUseCouponVo.getConditionAmount().doubleValue() > 0 && orderAmount.subtract(
        noUseCouponVo.getConditionAmount()).doubleValue() > 0) {
    availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
}

如果现金券有使用门槛(ConditionAmount大于0),则需检查订单金额是否满足条件,满足时同样将其加入可用列表。

3.2 处理折扣券
List<NoUseCouponVo> typeList2 = list.stream().filter(item -> item.getCouponType() == 2)
                                    .collect(Collectors.toList());

类似现金券,我们也要对折扣券进行过滤和处理。

3.2.1 无门槛折扣券
if (noUseCouponVo.getConditionAmount().doubleValue() == 0) {
    availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
}

如果折扣券没有使用门槛,直接计算折扣后的减免金额,并将其加入可用列表。

3.2.2 有门槛折扣券
if (noUseCouponVo.getConditionAmount().doubleValue() > 0 && orderAmount.subtract(
        noUseCouponVo.getConditionAmount()).doubleValue() > 0) {
    availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
}

同样,如果折扣券有门槛条件,需判断订单金额是否满足,并计算折扣后的减免金额。

4. 排序与返回结果

if (!CollectionUtils.isEmpty(availableCouponVoList)) {
    availableCouponVoList.sort((o1, o2) -> o2.getReduceAmount().compareTo(o1.getReduceAmount()));
}
return availableCouponVoList;

在获取所有符合条件的优惠券后,我们按照减免金额从大到小进行排序,并将最终结果返回给调用者。

5. 辅助方法

private AvailableCouponVo buildBestNoUseCouponVo(NoUseCouponVo noUseCouponVo, BigDecimal reduceAmount) {
    AvailableCouponVo bestNoUseCouponVo = new AvailableCouponVo();
    BeanUtils.copyProperties(noUseCouponVo, bestNoUseCouponVo);
    bestNoUseCouponVo.setCouponId(noUseCouponVo.getId());
    bestNoUseCouponVo.setReduceAmount(reduceAmount);
    return bestNoUseCouponVo;
}

这个辅助方法用于将NoUseCouponVo对象转换为AvailableCouponVo对象,并设置减免金额。

完整代码展示

@Override
public List<AvailableCouponVo> findAvailableCoupon(Long customerId, BigDecimal orderAmount) {
    List<AvailableCouponVo> availableCouponVoList = new ArrayList<>();

    // 获取用户未使用的优惠券列表
    List<NoUseCouponVo> list = couponInfoMapper.findNoUseList(customerId);

    // 处理现金券
    List<NoUseCouponVo> typeList = list.stream().filter(item -> item.getCouponType() == 1)
                                       .collect(Collectors.toList());
    for (NoUseCouponVo noUseCouponVo : typeList) {
        BigDecimal reduceAmount = noUseCouponVo.getAmount();
        if (noUseCouponVo.getConditionAmount().doubleValue() == 0 && orderAmount.subtract(reduceAmount)
                                                                                .doubleValue() >= 0) {
            availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
        }
        if (noUseCouponVo.getConditionAmount().doubleValue() > 0 && orderAmount.subtract(
                noUseCouponVo.getConditionAmount()).doubleValue() > 0) {
            availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
        }
    }

    // 处理折扣券
    List<NoUseCouponVo> typeList2 = list.stream().filter(item -> item.getCouponType() == 2)
                                        .collect(Collectors.toList());
    for (NoUseCouponVo noUseCouponVo : typeList2) {
        BigDecimal discountAmount = orderAmount.multiply(noUseCouponVo.getDiscount()).divide(new BigDecimal("10"))
                                               .setScale(2, RoundingMode.HALF_UP);
        BigDecimal reduceAmount = orderAmount.subtract(discountAmount);
        if (noUseCouponVo.getConditionAmount().doubleValue() == 0) {
            availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
        }
        if (noUseCouponVo.getConditionAmount().doubleValue() > 0 && orderAmount.subtract(
                noUseCouponVo.getConditionAmount()).doubleValue() > 0) {
            availableCouponVoList.add(this.buildBestNoUseCouponVo(noUseCouponVo, reduceAmount));
        }
    }

    // 按减免金额排序并返回
    if (!CollectionUtils.isEmpty(availableCouponVoList)) {
        availableCouponVoList.sort((o1, o2) -> o2.getReduceAmount().compareTo(o1.getReduceAmount()));
    }
    return availableCouponVoList;
}

private AvailableCouponVo buildBestNoUseCouponVo(NoUseCouponVo noUseCouponVo, BigDecimal reduceAmount) {
    AvailableCouponVo bestNoUseCouponVo = new AvailableCouponVo();
    BeanUtils.copyProperties(noUseCouponVo, bestNoUseCouponVo);
    bestNoUseCouponVo.setCouponId(noUseCouponVo.getId());
    bestNoUseCouponVo.setReduceAmount(reduceAmount);
    return bestNoUseCouponVo;
}

通过以上代码,我们实现了一个完整的优惠券筛选逻辑,该逻辑不仅考虑了现金券和折扣券的不同特点,还根据订单金额动态判断哪些优惠券可以使用。希望通过这篇博客,你对优惠券使用的实现逻辑有了更深入的理解。

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值