文章目录
在电商系统或其他在线交易平台中,优惠券的使用直接影响用户体验和平台收益。优化优惠券的选择和使用逻辑,可以提高用户满意度,并帮助商家实现更好的运营效果。本文通过一个完整的Java代码示例,详细介绍如何筛选和使用用户优惠券,并确保其能在实际场景中得到最佳应用。
1. 初始化可用优惠券列表
List<AvailableCouponVo> availableCouponVoList = new ArrayList<>();
首先,我们创建一个空的List
,用于存储筛选后的可用优惠券信息。
2. 获取用户未使用的优惠券
List<NoUseCouponVo> list = couponInfoMapper.findNoUseList(customerId);
通过用户ID查询所有未使用的优惠券。这通常是从数据库中获取的一份包含所有用户未使用优惠券的列表,包含每张优惠券的详细信息。
3. 优惠券类型筛选与处理
通常,优惠券可以分为两种主要类型:现金券和折扣券。在代码中,我们通过流操作分别处理这两类优惠券。
3.1 处理现金券
List<NoUseCouponVo> cashCouponList = list.stream()
.filter(coupon -> coupon.getCouponType() == 1)
.collect(Collectors.toList());
首先,我们通过流操作过滤出类型为“现金券”(CouponType == 1
)的优惠券,接下来针对这些现金券进行使用条件的判断。
3.1.1 无门槛现金券
if (coupon.getConditionAmount().doubleValue() == 0 && orderAmount.subtract(coupon.getAmount()).doubleValue() >= 0) {
availableCouponVoList.add(buildAvailableCouponVo(coupon, coupon.getAmount()));
}
如果现金券没有使用门槛(ConditionAmount == 0
),并且订单金额满足使用条件(订单金额减去优惠金额后不为负),则将该现金券加入可用优惠券列表。
3.1.2 有门槛现金券
if (coupon.getConditionAmount().doubleValue() > 0 && orderAmount.doubleValue() >= coupon.getConditionAmount().doubleValue()) {
availableCouponVoList.add(buildAvailableCouponVo(coupon, coupon.getAmount()));
}
有些现金券设有最低消费门槛(ConditionAmount > 0
),此时需判断订单金额是否满足最低消费门槛,满足则加入可用优惠券列表。
3.2 处理折扣券
List<NoUseCouponVo> discountCouponList = list.stream()
.filter(coupon -> coupon.getCouponType() == 2)
.collect(Collectors.toList());
折扣券(CouponType == 2
)的处理方式类似于现金券,但在计算优惠时,需要依据折扣比例动态计算减免金额。
3.2.1 无门槛折扣券
if (coupon.getConditionAmount().doubleValue() == 0) {
BigDecimal discountAmount = orderAmount.multiply(coupon.getDiscount().divide(new BigDecimal("10")));
BigDecimal reduceAmount = orderAmount.subtract(discountAmount);
availableCouponVoList.add(buildAvailableCouponVo(coupon, reduceAmount));
}
对于无门槛的折扣券,直接依据折扣比例计算折后金额,并将其加入可用优惠券列表。
3.2.2 有门槛折扣券
if (coupon.getConditionAmount().doubleValue() > 0 && orderAmount.doubleValue() >= coupon.getConditionAmount().doubleValue()) {
BigDecimal discountAmount = orderAmount.multiply(coupon.getDiscount().divide(new BigDecimal("10")));
BigDecimal reduceAmount = orderAmount.subtract(discountAmount);
availableCouponVoList.add(buildAvailableCouponVo(coupon, reduceAmount));
}
对于有门槛的折扣券,首先判断订单金额是否达到使用条件,再根据折扣比例计算减免金额,并将符合条件的折扣券加入列表。
4. 优惠券排序与返回结果
if (!availableCouponVoList.isEmpty()) {
availableCouponVoList.sort((o1, o2) -> o2.getReduceAmount().compareTo(o1.getReduceAmount()));
}
return availableCouponVoList;
在完成所有优惠券的筛选之后,我们按照优惠金额从大到小排序,这样可以确保用户优先使用优惠力度最大的券,最大化其订单优惠金额。
5. 辅助方法:构建优惠券对象
private AvailableCouponVo buildAvailableCouponVo(NoUseCouponVo coupon, BigDecimal reduceAmount) {
AvailableCouponVo availableCouponVo = new AvailableCouponVo();
BeanUtils.copyProperties(coupon, availableCouponVo);
availableCouponVo.setCouponId(coupon.getId());
availableCouponVo.setReduceAmount(reduceAmount);
return availableCouponVo;
}
该辅助方法用于将NoUseCouponVo
对象转换为AvailableCouponVo
对象,并设置对应的减免金额,以便将其返回给前端进行展示。
完整代码展示
@Override
public List<AvailableCouponVo> findAvailableCoupon(Long customerId, BigDecimal orderAmount) {
List<AvailableCouponVo> availableCouponVoList = new ArrayList<>();
// 获取用户未使用的优惠券列表
List<NoUseCouponVo> list = couponInfoMapper.findNoUseList(customerId);
// 处理现金券
List<NoUseCouponVo> cashCouponList = list.stream()
.filter(coupon -> coupon.getCouponType() == 1)
.collect(Collectors.toList());
for (NoUseCouponVo coupon : cashCouponList) {
if (coupon.getConditionAmount().doubleValue() == 0 && orderAmount.subtract(coupon.getAmount()).doubleValue() >= 0) {
availableCouponVoList.add(buildAvailableCouponVo(coupon, coupon.getAmount()));
}
if (coupon.getConditionAmount().doubleValue() > 0 && orderAmount.doubleValue() >= coupon.getConditionAmount().doubleValue()) {
availableCouponVoList.add(buildAvailableCouponVo(coupon, coupon.getAmount()));
}
}
// 处理折扣券
List<NoUseCouponVo> discountCouponList = list.stream()
.filter(coupon -> coupon.getCouponType() == 2)
.collect(Collectors.toList());
for (NoUseCouponVo coupon : discountCouponList) {
BigDecimal discountAmount = orderAmount.multiply(coupon.getDiscount().divide(new BigDecimal("10")));
BigDecimal reduceAmount = orderAmount.subtract(discountAmount);
if (coupon.getConditionAmount().doubleValue() == 0) {
availableCouponVoList.add(buildAvailableCouponVo(coupon, reduceAmount));
}
if (coupon.getConditionAmount().doubleValue() > 0 && orderAmount.doubleValue() >= coupon.getConditionAmount().doubleValue()) {
availableCouponVoList.add(buildAvailableCouponVo(coupon, reduceAmount));
}
}
// 按减免金额排序并返回
if (!availableCouponVoList.isEmpty()) {
availableCouponVoList.sort((o1, o2) -> o2.getReduceAmount().compareTo(o1.getReduceAmount()));
}
return availableCouponVoList;
}
private AvailableCouponVo buildAvailableCouponVo(NoUseCouponVo coupon, BigDecimal reduceAmount) {
AvailableCouponVo availableCouponVo = new AvailableCouponVo();
BeanUtils.copyProperties(coupon, availableCouponVo);
availableCouponVo.setCouponId(coupon.getId());
availableCouponVo.setReduceAmount(reduceAmount);
return availableCouponVo;
}
总结
通过本文,我们实现了一个完整的优惠券筛选和使用逻辑。优惠券的筛选不仅根据其类型(现金券和折扣券),还根据其使用门槛和订单金额进行动态判断。通过这种方式,用户可以自动获取到最优的优惠券组合,提升用户体验并最大化商家的优惠策略效果。