一、前台
1. main.js添加全局参数
import Vue from ‘vue’
const preventReClick = Vue.directive(‘preventReClick’, {
inserted (el, binding) {
el.addEventListener(‘click’, () => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 3000)
}
})
}
})
export { preventReClick }
Vue.use(preventReClick);
2. 在el-button标签中使用v-preventReClick
<el-button v-preventReClick @click="save()">保存</el-button>
二、后台
1. 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
2. 自定义锁注解
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface LocalLock {
String key() default "";
}
3. 配置类
import com.community.common.model.ErrorCode;
import com.community.manage.model.Public.BoardMessage;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
@Aspect
@Configuration
public class LockMethodInterceptor {
private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(20, TimeUnit.SECONDS)
.build();
@Around("execution(public * *(..)) && @annotation(LocalLock)")
public Object interceptor(ProceedingJoinPoint pjp){
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
LocalLock localLock = method.getAnnotation(LocalLock.class);
String key = getKey(localLock.key(), pjp.getArgs());
if (!StringUtils.isEmpty(key)) {
if (CACHES.getIfPresent(key) != null) {
return new BoardMessage(ErrorCode.getFail(),"请勿重复请求");
}
CACHES.put(key, key);
}
try {
return pjp.proceed();
} catch (Throwable throwable) {
throw new RuntimeException("服务器异常");
} finally {
CACHES.invalidate(key);
}
}
private String getKey(String keyExpress, Object[] args) {
for (int i = 0; i < args.length; i++) {
keyExpress = keyExpress.replace("arg[" + i + "]", args[i].toString());
}
return keyExpress;
}
}
4. 在controller方法上用@LocalLock
@PostMapping
@LocalLock(key="arg[0]")
public BoardMessage saveDepartment(VueDepartment vueDepartment) {
}