防止重复提交表单数据

下单键防止一直点击 

1、获取提交表单令牌token

 @ApiOperation("获取提交订单令牌")
    @GetMapping("get_token")
    public JsonData getOrderToken(){
        LoginUser loginUser = LoginInterceptor.threadLocal.get();
        String key = String.format(CacheKey.SUBMIT_ORDER_TOKEN_KEY,loginUser.getId());

        String token = CommonUtil.getStringNumRandom(32);
        redisTemplate.opsForValue().set(key,token,30, TimeUnit.MINUTES);
        return JsonData.buildSuccess(token);
    }

2、执行下单接口

  @ApiOperation("提交订单")
    @PostMapping("confirm")
    public void confirmOrder(
            @ApiParam("订单对象")
            @RequestBody ConfirmOrderRequet orderRequet, HttpServletResponse response) throws AlipayApiException {

        JsonData jsonData = orderService.confirmOrder(orderRequet);
        if (jsonData.getCode() == 0) {
           String client = orderRequet.getClientType();
           String payType = orderRequet.getPayType();
           // 如果是支付宝支付,都是跳转网页APP除外
           if(payType.equalsIgnoreCase(ProductOrderPayTypeEnum.ALIPAY.name())){
               log.info("创建订单成功:{}",orderRequet.toString());
               // 支付宝支付就是将一串html返回给前端
               if(client.equalsIgnoreCase(ClientType.H5.name())){
                   writeDate(response,jsonData);
               }else if(client.equalsIgnoreCase(ClientType.APP.name())){
                   // APP SDK支付  TODO
               }

           }else if(payType.equalsIgnoreCase(ProductOrderPayTypeEnum.WECHAT.name())){
               // 微信支付 TODO
            }
        }else{
            log.info("创建订单失败{}",jsonData.toString());
        }
    }

3、下单接口confirm会去调用service层的,而service层会首先会去校验redis中的token,校验完后会删除,因此第二次再次下单的时候,token不存在了;

 @Override
    public JsonData confirmOrder(ConfirmOrderRequet orderRequet) throws AlipayApiException {

        LoginUser loginUser = LoginInterceptor.threadLocal.get();

        String  orderToken = orderRequet.getToken();
        if(StringUtils.isBlank(orderToken)){
            throw new BizException(BizCodeEnum.ORDER_CONFIRM_TOKEN_NOT_EXTIS);
        }

            // 原子操作,校验令牌,删除令牌
            String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";

            // 操作成功就返回1
           Long result =  redisTemplate.execute(new DefaultRedisScript<>(script,Long.class),
                    Arrays.asList(String.format(CacheKey.SUBMIT_ORDER_TOKEN_KEY,loginUser.getId())),
                    orderToken);
           if(result == 0L){
               throw  new BizException(BizCodeEnum.ORDER_CONFIRM_TOKEN_NOT_EXTIS);
           }


        // 获取一个订单号

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zero _s

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

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

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

打赏作者

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

抵扣说明:

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

余额充值