查询发放中的优惠券

文章目录

概要

需求分析以及接口设计

这里要查询的是发放中的,并且领取方式是手动领取的优惠券。这就是一个简单的带条件的批量查询接口。因此按照Restful风格来设计即可,我们要分析的核心就是请求参数和返回值类型。

之前也说过,这里的查询条件包含两个:

  • 发放中的优惠券

  • 领取方式是手动领取的

不过这都是一些状态信息,不需要前端传递,我们自己在业务中判断即可。也就是说这个查询是无参的。

返回值首先肯定是优惠券集合,而优惠券数据就相对复杂一些,结合页面原型可以发现首先是一些基本字段:

  • 优惠券id:领取的时候使用

  • 优惠券名称

  • 优惠的详细信息,包含四个字段:

    • 优惠的折扣类型

    • 优惠门槛

    • 优惠值

    • 最大优惠值

  • 是否限定了范围

  • 有效期的结束时间:页面写的是有效期至xxx,也就是说不关心有效期的开始时间,只关心结束时间

  • 有效天数:券的使用有效期有两种方式,一种是到期时间;一种是固定天数,也就是自领取之日起算起。

OK,优惠券的基本信息就这么多。但是这里有一些隐含的内容在原型中没有显示出来:大家思考一下,如果这个优惠券我点击过立即领取,并且领取成功以后,页面该如何显示?

难道还是显示立即领取吗?这显然不行,一般优惠券领取完后应该显示为立即使用,提醒用户赶紧去买东西。

另外,如果这个券全部领完了呢?还展示立即领取吗?显然不行,这种应该显示为已领完。

因此,我们应该在返回值中标示优惠券的这些状态:

  • 是否可以领取:也就是优惠券还有剩余并且用户已领取数量未超过限领数量。如果为false,展示为已抢完

  • 是否已经领取:也就是用户是否有已经领取,尚未使用的券。如果有,则显示为去使用

如果以上都不成立,则展示为立即领取

综上,结合Restful的风格,查询发放中的优惠券的接口规范如下:

 

技术细节

1.Controller层

@ApiOperation("查询发放中的优惠券列表")
@GetMapping("/list")
public List<CouponVO> queryIssuingCoupons(){
    return couponService.queryIssuingCoupons();
}

2.Service层:


@Override
public List<CouponVO> queryIssuingCoupons() {
    // 1.查询发放中的优惠券列表
    List<Coupon> coupons = lambdaQuery()
            .eq(Coupon::getStatus, ISSUING)
            .eq(Coupon::getObtainWay, ObtainType.PUBLIC)
            .list();
    if (CollUtils.isEmpty(coupons)) {
        return CollUtils.emptyList();
    }
    // 2.统计当前用户已经领取的优惠券的信息
    List<Long> couponIds = coupons.stream().map(Coupon::getId).collect(Collectors.toList());
    // 2.1.查询当前用户已经领取的优惠券的数据
    List<UserCoupon> userCoupons = userCouponService.lambdaQuery()
            .eq(UserCoupon::getUserId, UserContext.getUser())
            .in(UserCoupon::getCouponId, couponIds)
            .list();
    // 2.2.统计当前用户对优惠券的已经领取数量
    Map<Long, Long> issuedMap = userCoupons.stream()
            .collect(Collectors.groupingBy(UserCoupon::getCouponId, Collectors.counting()));
    // 2.3.统计当前用户对优惠券的已经领取并且未使用的数量
    Map<Long, Long> unusedMap = userCoupons.stream()
            .filter(uc -> uc.getStatus() == UserCouponStatus.UNUSED)
            .collect(Collectors.groupingBy(UserCoupon::getCouponId, Collectors.counting()));
    // 3.封装VO结果
    List<CouponVO> list = new ArrayList<>(coupons.size());
    for (Coupon c : coupons) {
        // 3.1.拷贝PO属性到VO
        CouponVO vo = BeanUtils.copyBean(c, CouponVO.class);
        list.add(vo);
        // 3.2.是否可以领取:已经被领取的数量 < 优惠券总数量 && 当前用户已经领取的数量 < 每人限领数量
        vo.setAvailable(
                c.getIssueNum() < c.getTotalNum()
                && issuedMap.getOrDefault(c.getId(), 0L) < c.getUserLimit()
        );
        // 3.3.是否可以使用:当前用户已经领取并且未使用的优惠券数量 > 0
        vo.setReceived(unusedMap.getOrDefault(c.getId(),  0L) > 0);
    }
    return list;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值