模拟用户领卷功能

本文详细描述了用户通过优惠券id领取优惠券的过程,包括获取优惠券、验证领取条件、库存扣减以及逻辑检查。同时提到了在压力测试中发现的问题。

目录

1.用户根据优惠卷id领取优惠卷

2.领取优惠卷逻辑

3.提出问题


1.用户根据优惠卷id领取优惠卷

1.获取优惠卷的id

2.调用service层方法

   @ApiOperation("领取优惠卷")
    @GetMapping("/getCouponById/{coupon_id}")
    public JsonData getCouponById(@ApiParam(value = "优惠卷id", required = true) @PathVariable("coupon_id") int couponId) {
        JsonData jsonData = couponService.getCouponBuId(couponId, CouponCategoryEnum.PROMOTION);
        return JsonData.buildSuccess(jsonData);
    }

2.领取优惠卷逻辑

1.根据拦截器获取登录者信息

2.查找要领取的优惠卷是否存在

3.判断优惠劵是否可以领取

4.编写查看优惠卷领取规则,不为空、发布状态、领取时间、库存

5.构建领卷记录

6.使用对象拷贝,将查找到的优惠卷拷贝到优惠卷和登录者关联中

7.扣减库存

8.判断库存是否扣减成功

9.若扣减成功,则将领取的优惠卷添加到数据库中

10.否则抛出异常

    /**
     * 根据id获取优惠卷
     *
     * @param couponId:优惠劵id
     * @param category:优惠卷类型
     * @return
     */
    @Override
    public JsonData getCouponBuId(int couponId, CouponCategoryEnum category) {
        //1.获取登录者信息
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        //2.查找优惠卷是否存在
        CouponDO couponDO = couponMapper.selectOne(new QueryWrapper<CouponDO>()
                //判断优惠卷id
                .eq("id", couponId)
                //判断优惠卷类型
                .eq("category", category.name()));

        //3.判断优惠卷是否可以领取
        this.checkCoupon(couponDO, loginUser.getId());

        //4.构建领卷记录
        CouponRecordDO couponRecordDO = new CouponRecordDO();
        BeanUtils.copyProperties(couponDO,couponRecordDO);
        //设置创建时间
        couponRecordDO.setCreateTime(new Date());
        //设置使用状态
        couponRecordDO.setUseState(CouponUseStatusEnum.NEW.name());
        //设置登录者id
        couponRecordDO.setUserId(loginUser.getId());
        //设置登录者姓名
        couponRecordDO.setUserName(loginUser.getName());
        //设置优惠劵id
        couponRecordDO.setCouponId(couponDO.getId());
        //避免拷贝时,id也拷贝
        couponRecordDO.setId(null);

        //5.库存扣减
        //TODO int rows=couponMapper.reduceStock(couponId);
        int rows=1;

        if (rows==1){
            //新增库存扣减成功才保存记录
            couponRecordMapper.insert(couponRecordDO);
        }else {
            log.error("库存扣减失败");
            throw new MyException(CodeEnum.COUPON_NO_STOCK);
        }
        return JsonData.buildResult(CodeEnum.COUPON_GET_SUCCESS);
    }

    /**
     * 校验是否可以领取优惠卷
     *
     * @param couponDO:优惠卷
     * @param userId:登录者id
     */
    private void checkCoupon(CouponDO couponDO, Long userId) {
        //判断优惠卷是否为空
        if (couponDO == null) {
            throw new MyException(CodeEnum.COUPON_NO_EXITS);
        }

        //库存是否充足
        if (couponDO.getStock() <= 0) {
            throw new MyException(CodeEnum.COUPON_NO_STOCK);
        }

        //判断是否在领取时间范围
        //获取当前时间戳
        Long time = CommonUtil.getCurrentTimestamp();
        //优惠卷开始时间,获取时间戳
        long startTime = couponDO.getStartTime().getTime();
        //优惠卷结束时间,获取时间戳
        long endTime = couponDO.getEndTime().getTime();

        if (time < startTime || time > endTime) {
            throw new MyException(CodeEnum.COUPON_OUT_OFF_TIME);
        }

        //判断用户是否超过限制
        //获取用户的总优惠卷数
        Integer totalNumber = couponRecordMapper.selectCount(new QueryWrapper<CouponRecordDO>()
                .eq("coupon_id", couponDO.getId())
                .eq("user_id", userId));

        if (totalNumber > couponDO.getUserLimit()) {
            throw new MyException(CodeEnum.COUPON_OUT_OFF_LIMIT);
        }

        //判断发布状态
        if (!couponDO.getPublish().equals(CouponPublishEnum.PUBLISH.name())) {
            throw new MyException(CodeEnum.COUPON_GET_FAIL);
        }
    }

3.提出问题

上面代码逻辑通过postman测试,是没有问题的

但是通过压测可以发现问题大大的多~

欲听后事如何,且听下回分解!!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会敲代码的小张

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值