切面+注解防重复提交,@NoRepeatSubmit默认10秒内只能提交1次
This commit is contained in:
parent
6352c0186a
commit
4501480a00
@ -0,0 +1,19 @@
|
|||||||
|
package com.xhpc.common.core.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface NoRepeatSubmit {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 防止重复提交标记注解
|
||||||
|
* 设置请求锁定时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int lockTime() default 10;
|
||||||
|
|
||||||
|
}
|
||||||
@ -4,12 +4,14 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import com.xhpc.common.api.PileOrderService;
|
import com.xhpc.common.api.PileOrderService;
|
||||||
import com.xhpc.common.redis.service.RedisService;
|
import com.xhpc.common.redis.service.RedisService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
|
||||||
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
|
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class StaticBeanUtil {
|
public class StaticBeanUtil {
|
||||||
@ -30,6 +32,20 @@ public class StaticBeanUtil {
|
|||||||
REDIS = redisService;
|
REDIS = redisService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Boolean tryLock(String key, long expr) {
|
||||||
|
|
||||||
|
System.out.println("try lock...");
|
||||||
|
RedisAtomicInteger counter = new RedisAtomicInteger(key, REDIS.redisTemplate.getConnectionFactory());
|
||||||
|
counter.expire(expr, TimeUnit.SECONDS);
|
||||||
|
long result = counter.incrementAndGet();
|
||||||
|
return result == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean releaseLock(String key) {
|
||||||
|
|
||||||
|
return REDIS.deleteObject(key);
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized static String seqHex(String key) {
|
public synchronized static String seqHex(String key) {
|
||||||
|
|
||||||
String upperCode = "";
|
String upperCode = "";
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.xhpc.common.util;
|
||||||
|
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
public class RequestUtils {
|
||||||
|
|
||||||
|
public static HttpServletRequest getRequest() {
|
||||||
|
|
||||||
|
ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
return ra.getRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package com.xhpc.payment.aspect;
|
||||||
|
|
||||||
|
import com.xhpc.common.core.annotation.NoRepeatSubmit;
|
||||||
|
import com.xhpc.common.core.web.domain.AjaxResult;
|
||||||
|
import com.xhpc.common.data.redis.StaticBeanUtil;
|
||||||
|
import com.xhpc.common.util.RequestUtils;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class RepeatSubmitAspect {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(RepeatSubmitAspect.class);
|
||||||
|
|
||||||
|
|
||||||
|
@Pointcut("@annotation(noRepeatSubmit)")
|
||||||
|
public void pointCut(NoRepeatSubmit noRepeatSubmit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Around("pointCut(noRepeatSubmit)")
|
||||||
|
public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {
|
||||||
|
|
||||||
|
int lockSeconds = noRepeatSubmit.lockTime();
|
||||||
|
|
||||||
|
HttpServletRequest request = RequestUtils.getRequest();
|
||||||
|
Assert.notNull(request, "request can't be null");
|
||||||
|
|
||||||
|
// 此处可以用token或者JSessionId
|
||||||
|
String token = request.getHeader("Authorization");
|
||||||
|
String path = request.getServletPath();
|
||||||
|
String key = getKey(token, path);
|
||||||
|
|
||||||
|
boolean isSuccess = StaticBeanUtil.tryLock(key, lockSeconds);
|
||||||
|
LOGGER.info("tryLock key = [{}]", key);
|
||||||
|
// 主要逻辑
|
||||||
|
if (isSuccess) {
|
||||||
|
LOGGER.info("tryLock success, key = [{}]", key);
|
||||||
|
// 获取锁成功
|
||||||
|
Object result;
|
||||||
|
// try {
|
||||||
|
// 执行进程
|
||||||
|
result = pjp.proceed();
|
||||||
|
// } finally {
|
||||||
|
// 解锁
|
||||||
|
// StaticBeanUtil.releaseLock(key);
|
||||||
|
// LOGGER.info("releaseLock success, key = [{}]", key);
|
||||||
|
// }
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
// 获取锁失败,认为是重复提交的请求。
|
||||||
|
LOGGER.info("tryLock fail, key = [{}]", key);
|
||||||
|
return new AjaxResult(200, "重复请求,请稍后再试", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getKey(String token, String path) {
|
||||||
|
|
||||||
|
return "lock".concat(path.replace("/", ":").concat(token.replaceAll(" ", "")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package com.xhpc.payment.controller;
|
package com.xhpc.payment.controller;
|
||||||
|
|
||||||
import com.xhpc.common.api.UserTypeService;
|
import com.xhpc.common.core.annotation.NoRepeatSubmit;
|
||||||
import com.xhpc.common.core.constant.HttpStatus;
|
import com.xhpc.common.core.constant.HttpStatus;
|
||||||
import com.xhpc.common.core.constant.StatusConstants;
|
import com.xhpc.common.core.constant.StatusConstants;
|
||||||
import com.xhpc.common.core.utils.StringUtils;
|
import com.xhpc.common.core.utils.StringUtils;
|
||||||
@ -8,8 +8,6 @@ import com.xhpc.common.core.web.controller.BaseController;
|
|||||||
import com.xhpc.common.core.web.domain.AjaxResult;
|
import com.xhpc.common.core.web.domain.AjaxResult;
|
||||||
import com.xhpc.common.core.web.page.TableDataInfo;
|
import com.xhpc.common.core.web.page.TableDataInfo;
|
||||||
import com.xhpc.common.security.service.TokenService;
|
import com.xhpc.common.security.service.TokenService;
|
||||||
import com.xhpc.common.util.UserTypeUtil;
|
|
||||||
import com.xhpc.payment.service.IXhpcCommonPayment;
|
|
||||||
import com.xhpc.payment.service.IXhpcRefundOrderService;
|
import com.xhpc.payment.service.IXhpcRefundOrderService;
|
||||||
import com.xhpc.system.api.model.LoginUser;
|
import com.xhpc.system.api.model.LoginUser;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
@ -33,30 +31,22 @@ public class XhpcRefundOrderController extends BaseController {
|
|||||||
private IXhpcRefundOrderService iXhpcRefundOrderService;
|
private IXhpcRefundOrderService iXhpcRefundOrderService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private TokenService tokenService;
|
private TokenService tokenService;
|
||||||
@Autowired
|
|
||||||
private IXhpcCommonPayment xhpcCommonPayment;
|
|
||||||
@Autowired
|
|
||||||
private UserTypeService userTypeService;
|
|
||||||
/**
|
/**
|
||||||
* 申请退款
|
* 申请退款
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@NoRepeatSubmit
|
||||||
@PostMapping("/checkOut")
|
@PostMapping("/checkOut")
|
||||||
@ApiOperation(value = "申请退款")
|
@ApiOperation(value = "申请退款")
|
||||||
public AjaxResult enterpriseCheckOut(HttpServletRequest request,@RequestBody Map<String, Object> map) {
|
public AjaxResult enterpriseCheckOut(@RequestBody Map<String, Object> map) {
|
||||||
LoginUser loginUser = tokenService.getLoginUser(request);
|
|
||||||
Long userid = loginUser.getUserid();
|
|
||||||
Integer userType = loginUser.getUserType();
|
|
||||||
String tenantId = loginUser.getTenantId();
|
|
||||||
if(UserTypeUtil.CUSTOMERS_TYPE.equals(userType)){
|
|
||||||
return AjaxResult.error(HttpStatus.ERROR_STATUS, "大客户不支持退款");
|
|
||||||
}
|
|
||||||
String amount = StringUtils.valueOf(map.get("amount"));
|
String amount = StringUtils.valueOf(map.get("amount"));
|
||||||
if (StringUtils.isEmpty(amount)) {
|
if (StringUtils.isEmpty(amount)) {
|
||||||
return AjaxResult.error(HttpStatus.NOT_NULL, "退款金额不能为空");
|
return AjaxResult.error(HttpStatus.NOT_NULL, "退款金额不能为空");
|
||||||
}else{
|
} else {
|
||||||
if(new BigDecimal(1).compareTo(new BigDecimal(amount))==1){
|
if (new BigDecimal(1).compareTo(new BigDecimal(amount)) == 1) {
|
||||||
return AjaxResult.error(HttpStatus.NOT_NULL, "退款金额不能少于1元");
|
return AjaxResult.error(HttpStatus.NOT_NULL, "退款金额不能少于1元");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,20 +64,23 @@ public class XhpcRefundOrderController extends BaseController {
|
|||||||
if (StringUtils.isEmpty(type)) {
|
if (StringUtils.isEmpty(type)) {
|
||||||
return AjaxResult.error(HttpStatus.NOT_NULL, "退款渠道不能为空");
|
return AjaxResult.error(HttpStatus.NOT_NULL, "退款渠道不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
//是否有实时数据
|
//是否有实时数据
|
||||||
int i =iXhpcRefundOrderService.countXhpcRealTimeOrder(userid,userType,tenantId);
|
int i = iXhpcRefundOrderService.countXhpcRealTimeOrder(Long.valueOf(userId));
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
return AjaxResult.error(1103, "车辆正在充电,不能退款");
|
return AjaxResult.error(1103, "车辆正在充电,不能退款");
|
||||||
}
|
}
|
||||||
// 是否有异常订单
|
// 是否有异常订单
|
||||||
int j =iXhpcRefundOrderService.countXhpcChargeOrder(userid,userType,tenantId);
|
int j = iXhpcRefundOrderService.countXhpcChargeOrder(Long.valueOf(userId));
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
return AjaxResult.error(1103, "你有异常订单未解决,请拨打客服电话进行解决");
|
return AjaxResult.error(1103, "你有异常订单未解决,请拨打客服电话进行解决");
|
||||||
}
|
}
|
||||||
|
|
||||||
//生成退款订单
|
//生成退款订单
|
||||||
String orderOutNumber = StringUtils.numFormat(userid, Integer.parseInt(type), StatusConstants.FLOWING_WATER_REFUND_TYPE);
|
String orderOutNumber = StringUtils.numFormat(Long.parseLong(userId), Integer.parseInt(type),
|
||||||
|
StatusConstants.FLOWING_WATER_REFUND_TYPE);
|
||||||
String remark = StringUtils.valueOf(map.get("remark"));
|
String remark = StringUtils.valueOf(map.get("remark"));
|
||||||
return iXhpcRefundOrderService.addRefundOrder(""+userid, BigDecimal.valueOf(Double.parseDouble(amount)), type, orderOutNumber, openid, remark,userType,tenantId);
|
return iXhpcRefundOrderService.addRefundOrder(userId, BigDecimal.valueOf(Double.parseDouble(amount)), type, orderOutNumber, openid, remark);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user