update - 优化重复提交注解,以支持动态配置,默认的防重提交时间为 5秒
This commit is contained in:
parent
b46466d583
commit
60125059aa
@ -22,7 +22,9 @@ public @interface RepeatSubmit {
|
||||
/**
|
||||
* 间隔时间(ms),小于此时间视为重复提交
|
||||
*/
|
||||
int interval() default 3000;
|
||||
int interval() default 5000;
|
||||
|
||||
String intervalExpression() default "${workflow.repeatSubmit.interval}";
|
||||
|
||||
TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package cn.axzo.workflow.server.common.aspectj;
|
||||
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
|
||||
import cn.axzo.workflow.server.common.config.RepeatSubmitResolver;
|
||||
import cn.axzo.workflow.server.common.util.RedisUtils;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
@ -9,11 +10,13 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.http.HttpStatus;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
@ -34,17 +37,24 @@ import static cn.axzo.workflow.core.common.code.OtherRespCode.REPEAT_SUBMIT_TIME
|
||||
*
|
||||
* @author wangli
|
||||
*/
|
||||
@Component
|
||||
@Aspect
|
||||
@Slf4j
|
||||
public class RepeatSubmitAspect {
|
||||
|
||||
private final RepeatSubmitResolver repeatSubmitResolver;
|
||||
private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>();
|
||||
private static final String REPEAT_SUBMIT_KEY = "global:repeat_submit:";
|
||||
|
||||
public RepeatSubmitAspect(RepeatSubmitResolver repeatSubmitResolver) {this.repeatSubmitResolver =
|
||||
repeatSubmitResolver;}
|
||||
|
||||
@Before("@annotation(repeatSubmit)")
|
||||
public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
|
||||
// 如果注解不为0 则使用注解数值
|
||||
long interval = repeatSubmit.timeUnit().toMillis(repeatSubmit.interval());
|
||||
|
||||
// 获取注解中的 SpEL 表达式
|
||||
interval = repeatSubmitResolver.resolveExpression(repeatSubmit.intervalExpression(), interval);
|
||||
log.info("interval: {}", interval);
|
||||
if (interval < 1000) {
|
||||
throw new WorkflowEngineException(REPEAT_SUBMIT_TIME_ERROR_TIPS,
|
||||
String.valueOf((repeatSubmit.interval() / 1000)));
|
||||
|
||||
@ -70,8 +70,8 @@ public class RedisConfiguration {
|
||||
public static class IdempotentAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public RepeatSubmitAspect repeatSubmitAspect() {
|
||||
return new RepeatSubmitAspect();
|
||||
public RepeatSubmitAspect repeatSubmitAspect(RepeatSubmitResolver resolver) {
|
||||
return new RepeatSubmitAspect(resolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
package cn.axzo.workflow.server.common.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 重复提交的时间参数动态处理
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024/1/19 16:49
|
||||
*/
|
||||
@Component
|
||||
@RefreshScope
|
||||
@Slf4j
|
||||
public class RepeatSubmitResolver {
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
public RepeatSubmitResolver(Environment environment) {this.environment = environment;}
|
||||
|
||||
public long resolveExpression(String expression, long interval) {
|
||||
// 使用 Environment 解析表达式
|
||||
String resolved = environment.resolvePlaceholders(expression);
|
||||
try {
|
||||
if (Objects.equals("${workflow.repeatSubmit.interval}", resolved)) {
|
||||
return interval;
|
||||
}
|
||||
return Integer.parseInt(resolved);
|
||||
} catch (NumberFormatException e) {
|
||||
// 处理异常或使用默认值
|
||||
log.error("@RepeatSubmit 注解的 intervalExpression 属性请使用 Spel 表达式获取环境变量中的超时时间配置, 当前的表达式存在问题, 以使用默认的超时时间, " +
|
||||
"Spel= {}", expression);
|
||||
return interval; // 默认值
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,6 +138,7 @@ public class BpmnProcessInstanceController implements ProcessInstanceApi {
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
@Override
|
||||
@RepeatSubmit
|
||||
public CommonResponse<BpmnProcessInstanceVO> getProcessInstanceVO(@Validated @RequestBody BpmnProcessInstanceQueryDTO dto) {
|
||||
log.info("获得历史的流程实例 getProcessInstanceVO===>>>参数:{}", JSON.toJSONString(dto));
|
||||
BpmnProcessInstanceVO result = bpmnProcessInstanceService.getProcessInstanceVO(dto);
|
||||
|
||||
@ -10,6 +10,7 @@ import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessModelService;
|
||||
import cn.axzo.workflow.core.service.ExtAxReModelService;
|
||||
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@ -66,6 +67,7 @@ public class BpmnProcessModelController implements ProcessModelApi {
|
||||
@Operation(summary = "创建流程模型")
|
||||
@PostMapping("/create")
|
||||
@Override
|
||||
@RepeatSubmit
|
||||
public CommonResponse<String> create(@Validated @RequestBody BpmnModelCreateDTO dto) {
|
||||
log.info("创建流程createBpmModel===>>>参数:{}", JSON.toJSONString(dto));
|
||||
String result = bpmnProcessModelService.createBpmModel(dto);
|
||||
|
||||
@ -11,6 +11,7 @@ import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
|
||||
import cn.axzo.workflow.core.service.CategoryConfigService;
|
||||
import cn.axzo.workflow.core.service.CategoryService;
|
||||
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -90,6 +91,7 @@ public class ProcessCategoryController implements ProcessCategoryApi {
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
@Override
|
||||
@RepeatSubmit
|
||||
public CommonResponse<CategoryItemVO> create(@Validated @RequestBody CategoryCreateDTO req) {
|
||||
return success(categoryService.createCategory(req));
|
||||
}
|
||||
@ -113,6 +115,7 @@ public class ProcessCategoryController implements ProcessCategoryApi {
|
||||
*/
|
||||
@DeleteMapping("/delete")
|
||||
@Override
|
||||
@RepeatSubmit
|
||||
public CommonResponse<Boolean> delete(Long id) {
|
||||
categoryService.deleteCategory(id);
|
||||
return success(true);
|
||||
@ -148,6 +151,7 @@ public class ProcessCategoryController implements ProcessCategoryApi {
|
||||
*/
|
||||
@PostMapping("/config/create")
|
||||
@Override
|
||||
@RepeatSubmit
|
||||
public CommonResponse<Boolean> createConfig(@Validated @RequestBody CategoryConfigCreateDTO dto) {
|
||||
categoryConfigService.create(dto);
|
||||
return success(true);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user