当前位置: 首页 > article >正文

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

文章目录

    • 代码分步讲解
      • 1. 初始化结果集合
      • 2. 获取用户未使用的优惠券
      • 3. 筛选优惠券类型
        • 3.1 处理现金券
          • 3.1.1 无门槛现金券
          • 3.1.2 有门槛现金券
        • 3.2 处理折扣券
          • 3.2.1 无门槛折扣券
          • 3.2.2 有门槛折扣券
      • 4. 排序与返回结果
      • 5. 辅助方法
    • 完整代码展示

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

代码分步讲解

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;
}

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


http://www.kler.cn/a/285935.html

相关文章:

  • SpringSecurity Oauth2 - 密码模式完成身份认证获取令牌 [自定义UserDetailsService]
  • 9千含读音文件的中文汉语学习ACCESS\EXCEL数据库
  • 《JavaEE进阶》----6.<SpringMVC实践项目:【简易两整数加法计算器】>
  • 网络安全总结②
  • 远程调用以及注册中心Nacos
  • JavaScript初级——键盘事件
  • 前端面试模拟:常见的3个JavaScript经典考题
  • uniapp分包
  • ElasticSearch7.12.1详细安装
  • 【XR】SDK的接口规划与设计
  • C++ 求1+2+3+......+n__有限制(牛客网)
  • 机器学习-SVM方法
  • Linux系统性能调优技巧
  • C#按引用传递参数
  • HTML中自定义属性并通过JS获取属性值
  • Nginx负载均衡中动态资源缓存配置指南
  • esp8266根据httpserver状态,调用网络唤醒,实现一键开机
  • 深入学习电路基础:从理论到实践
  • 《外国教育研究》
  • (每日一问)计算机网络:HTTP 与 HTTPS 的区别