订单令牌防重提交开发
This commit is contained in:
parent
760dc505cc
commit
ee4dcde935
@ -10,4 +10,9 @@ public class CacheKey {
|
|||||||
* 购物车 hash 结果 , key是用户唯一标识
|
* 购物车 hash 结果 , key是用户唯一标识
|
||||||
*/
|
*/
|
||||||
public final static String CART_KEY = "cart:%s";
|
public final static String CART_KEY = "cart:%s";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交表单的token key
|
||||||
|
*/
|
||||||
|
public final static String SUBMIT_ORDER_TOKEN_KEY = "order:submit:%s";
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,12 @@ import io.swagger.annotations.ApiParam;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.jieyuu.config.AlipayConfig;
|
import net.jieyuu.config.AlipayConfig;
|
||||||
import net.jieyuu.config.PayUrlConfig;
|
import net.jieyuu.config.PayUrlConfig;
|
||||||
|
import net.jieyuu.constant.CacheKey;
|
||||||
import net.jieyuu.enums.BizCodeEnum;
|
import net.jieyuu.enums.BizCodeEnum;
|
||||||
import net.jieyuu.enums.ClientType;
|
import net.jieyuu.enums.ClientType;
|
||||||
import net.jieyuu.enums.ProductOrderPayTypeEnum;
|
import net.jieyuu.enums.ProductOrderPayTypeEnum;
|
||||||
|
import net.jieyuu.interceptor.LoginInterceptor;
|
||||||
|
import net.jieyuu.model.LoginUser;
|
||||||
import net.jieyuu.request.ConfirmOrderRequest;
|
import net.jieyuu.request.ConfirmOrderRequest;
|
||||||
import net.jieyuu.request.RepayOrderRequest;
|
import net.jieyuu.request.RepayOrderRequest;
|
||||||
import net.jieyuu.service.ProductOrderService;
|
import net.jieyuu.service.ProductOrderService;
|
||||||
@ -20,14 +23,15 @@ import net.jieyuu.utils.CommonUtil;
|
|||||||
import net.jieyuu.utils.JsonData;
|
import net.jieyuu.utils.JsonData;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@ -49,6 +53,26 @@ public class ProductOrderController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PayUrlConfig payUrlConfig;
|
private PayUrlConfig payUrlConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 避免重复下单操作
|
||||||
|
* 下单前请求接口获取令牌
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询商品列表
|
* 分页查询商品列表
|
||||||
*
|
*
|
||||||
|
@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.jieyuu.component.PayFactory;
|
import net.jieyuu.component.PayFactory;
|
||||||
import net.jieyuu.config.RabbitMQConfig;
|
import net.jieyuu.config.RabbitMQConfig;
|
||||||
|
import net.jieyuu.constant.CacheKey;
|
||||||
import net.jieyuu.constant.TimeConstant;
|
import net.jieyuu.constant.TimeConstant;
|
||||||
import net.jieyuu.enums.*;
|
import net.jieyuu.enums.*;
|
||||||
import net.jieyuu.exception.BizException;
|
import net.jieyuu.exception.BizException;
|
||||||
@ -29,6 +30,8 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -72,6 +75,9 @@ public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, Pro
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PayFactory payFactory;
|
private PayFactory payFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private StringRedisTemplate redisTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 防重提交
|
* * 防重提交
|
||||||
* * 用户微服务-确认收货地址
|
* * 用户微服务-确认收货地址
|
||||||
@ -93,6 +99,23 @@ public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, Pro
|
|||||||
@Transactional
|
@Transactional
|
||||||
public JsonData confirmOrder(ConfirmOrderRequest orderRequest) {
|
public JsonData confirmOrder(ConfirmOrderRequest orderRequest) {
|
||||||
LoginUser loginUser = LoginInterceptor.threadLocal.get();
|
LoginUser loginUser = LoginInterceptor.threadLocal.get();
|
||||||
|
|
||||||
|
|
||||||
|
String orderToken = orderRequest.getToken();
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(orderToken)) {
|
||||||
|
throw new BizException(BizCodeEnum.ORDER_CONFIRM_TOKEN_NOT_EXIST);
|
||||||
|
}
|
||||||
|
// lua原子操作校验令牌
|
||||||
|
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
|
||||||
|
|
||||||
|
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_EQUAL_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
// 32位uuid订单号
|
// 32位uuid订单号
|
||||||
String orderOutTradeNo = CommonUtil.getStringNumRandom(32);
|
String orderOutTradeNo = CommonUtil.getStringNumRandom(32);
|
||||||
// 获取收货地址
|
// 获取收货地址
|
||||||
|
Loading…
Reference in New Issue
Block a user