From 2027dae30b82365a84988d057c2a9240d233971c Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期五, 04 六月 2021 16:12:43 +0800 Subject: [PATCH] !49 同步dev分支 Merge pull request !49 from 疯狂的狮子Li/dev --- ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java | 4 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java | 167 +++++++++++++++++++++++++++++++++ ruoyi-ui/package.json | 2 ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java | 27 +++++ ruoyi-ui/src/views/index.vue | 16 +++ ruoyi-generator/src/main/resources/vm/java/vo.java.vm | 2 pom.xml | 2 ruoyi-admin/src/main/resources/application.yml | 4 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java | 35 +++++++ 9 files changed, 251 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index a178974..f50e460 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ <description>RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺</description> <properties> - <ruoyi-vue-plus.version>2.3.0</ruoyi-vue-plus.version> + <ruoyi-vue-plus.version>2.3.1</ruoyi-vue-plus.version> <spring-boot.version>2.3.11.RELEASE</spring-boot.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3838ff5..3ea04c7 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -8,8 +8,8 @@ copyrightYear: 2021 # 瀹炰緥婕旂ず寮�鍏� demoEnabled: true - # 鏂囦欢璺緞,浣跨敤jvm绯荤粺鍙橀噺,鍏煎windows鍜宭inux; - profile: ${user.dir}/ruoyi/uploadPath + # 鏂囦欢璺緞 + profile: ./ruoyi/uploadPath # 鑾峰彇ip鍦板潃寮�鍏� addressEnabled: false diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java new file mode 100644 index 0000000..7b3c912 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java @@ -0,0 +1,27 @@ +package com.ruoyi.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 鍒嗗竷寮忛攣锛堟敞瑙fā寮忥紝涓嶆帹鑽愪娇鐢紝鏈�濂界敤閿佺殑宸ュ叿绫伙級 + * + * @author shenxinquan + */ + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface RedisLock { + + /** + * 閿佽繃鏈熸椂闂� 榛樿30绉� + */ + int expireTime() default 30; + + /** + * 閿乲ey鍊� + */ + String key() default "redisLockKey"; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java index cf3f886..d5b72f7 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java @@ -43,9 +43,9 @@ public static final int DEFAULT_PAGE_NUM = 1; /** - * 姣忛〉鏄剧ず璁板綍鏁� 榛樿鍊� + * 姣忛〉鏄剧ず璁板綍鏁� 榛樿鍊� 榛樿鏌ュ叏閮� */ - public static final int DEFAULT_PAGE_SIZE = 10; + public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE; /** * 鏋勫缓 plus 鍒嗛〉瀵硅薄 diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java new file mode 100644 index 0000000..7792784 --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java @@ -0,0 +1,35 @@ +package com.ruoyi.demo.controller; + +import com.ruoyi.common.annotation.RedisLock; +import com.ruoyi.common.core.domain.AjaxResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * 娴嬭瘯鍒嗗竷寮忛攣鐨勬牱渚� + * + * @author shenxinquan + */ +@RestController +@RequestMapping("/demo/redisLock") +public class RedisLockController { + + /** + * #p0 鏍囪瘑鍙栫涓�涓弬鏁颁负redis閿佺殑key + */ + @GetMapping("/getLock") + @RedisLock(expireTime = 10, key = "#p0") + public AjaxResult<String> getLock(String key, String value) { + try { + // 鍚屾椂璇锋眰鎺掗槦 +// Thread.sleep(5000); + // 閿佽秴鏃舵祴璇� + Thread.sleep(11000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return AjaxResult.success("鎿嶄綔鎴愬姛",value); + } +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java new file mode 100644 index 0000000..0ff695f --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java @@ -0,0 +1,167 @@ +package com.ruoyi.framework.aspectj; + + +import com.ruoyi.common.annotation.RedisLock; +import lombok.extern.slf4j.Slf4j; +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.aspectj.lang.reflect.MethodSignature; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * 鍒嗗竷寮忛攣锛堟敞瑙e疄鐜扮増鏈級 + * + * @author shenxinquan + */ + +@Slf4j +@Aspect +@Order(9) +@Component +public class RedisLockAspect { + + @Autowired + private RedissonClient redissonClient; + + private static final String LOCK_TITLE = "RedisLock_"; + + @Pointcut("@annotation(com.ruoyi.common.annotation.RedisLock)") + public void annotationPointcut() { + } + + @Around("annotationPointcut()") + public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { + // 鑾峰緱褰撳墠璁块棶鐨刢lass + Class<?> className = joinPoint.getTarget().getClass(); + // 鑾峰緱璁块棶鐨勬柟娉曞悕 + String methodName = joinPoint.getSignature().getName(); + // 寰楀埌鏂规硶鐨勫弬鏁扮殑绫诲瀷 + Class<?>[] argClass = ((MethodSignature) joinPoint.getSignature()).getParameterTypes(); + Object[] args = joinPoint.getArgs(); + String key = ""; + // 榛樿30绉掕繃鏈熸椂闂� + int expireTime = 30; + + try { + // 寰楀埌璁块棶鐨勬柟娉曞璞� + Method method = className.getMethod(methodName, argClass); + method.setAccessible(true); + // 鍒ゆ柇鏄惁瀛樺湪@RedisLock娉ㄨВ + if (method.isAnnotationPresent(RedisLock.class)) { + RedisLock annotation = method.getAnnotation(RedisLock.class); + key = getRedisKey(args, annotation.key()); + expireTime = getExpireTime(annotation); + } + } catch (Exception e) { + throw new RuntimeException("redis鍒嗗竷寮忛攣娉ㄨВ鍙傛暟寮傚父", e); + } + + Object res; + try { + if (acquire(key, expireTime, TimeUnit.SECONDS)) { + try { + res = joinPoint.proceed(); + return res; + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + release(key); + } + } else { + throw new RuntimeException("redis鍒嗗竷寮忛攣娉ㄨВ鍙傛暟寮傚父"); + } + } catch (IllegalMonitorStateException e) { + log.error("lock timeout => key : " + key + " , ThreadName : " + Thread.currentThread().getName()); + throw new RuntimeException("lock timeout => key : " + key); + } catch (Exception e) { + throw new Exception("redis鍒嗗竷寮忔湭鐭ュ紓甯�", e); + } + } + + private int getExpireTime(RedisLock annotation) { + return annotation.expireTime(); + } + + private String getRedisKey(Object[] args, String primalKey) { + if (args.length == 0) { + return primalKey; + } + // 鑾峰彇#p0...闆嗗悎 + List<String> keyList = getKeyParsList(primalKey); + for (String keyName : keyList) { + int keyIndex = Integer.parseInt(keyName.toLowerCase().replace("#p", "")); + Object parValue = args[keyIndex]; + primalKey = primalKey.replace(keyName, String.valueOf(parValue)); + } + return primalKey.replace("+", "").replace("'", ""); + } + + /** + * 鑾峰彇key涓�#p0涓殑鍙傛暟鍚嶇О + */ + private static List<String> getKeyParsList(String key) { + List<String> listPar = new ArrayList<>(); + if (key.contains("#")) { + int plusIndex = key.substring(key.indexOf("#")).indexOf("+"); + int indexNext = 0; + String parName; + int indexPre = key.indexOf("#"); + if (plusIndex > 0) { + indexNext = key.indexOf("#") + plusIndex; + parName = key.substring(indexPre, indexNext); + } else { + parName = key.substring(indexPre); + } + listPar.add(parName.trim()); + key = key.substring(indexNext + 1); + if (key.contains("#")) { + listPar.addAll(getKeyParsList(key)); + } + } + return listPar; + } + + /** + * 鍔犻攣锛圧Lock锛夊甫瓒呮椂鏃堕棿鐨� + */ + private boolean acquire(String key, long expire, TimeUnit expireUnit) { + //澹版槑key瀵硅薄 + key = LOCK_TITLE + key; + try { + //鑾峰彇閿佸璞� + RLock mylock = redissonClient.getLock(key); + //鍔犻攣锛屽苟涓旇缃攣杩囨湡鏃堕棿锛岄槻姝㈡閿佺殑浜х敓 + mylock.tryLock(expire, expire, expireUnit); + } catch (InterruptedException e) { + return false; + } + log.info("lock => key : " + key + " , ThreadName : " + Thread.currentThread().getName()); + //鍔犻攣鎴愬姛 + return true; + } + + /** + * 閿佺殑閲婃斁 + */ + private void release(String lockName) { + //蹇呴』鏄拰鍔犻攣鏃剁殑鍚屼竴涓猭ey + String key = LOCK_TITLE + lockName; + //鑾峰彇鎵�瀵硅薄 + RLock mylock = redissonClient.getLock(key); + //閲婃斁閿侊紙瑙i攣锛� + mylock.unlock(); + log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName()); + } + +} diff --git a/ruoyi-generator/src/main/resources/vm/java/vo.java.vm b/ruoyi-generator/src/main/resources/vm/java/vo.java.vm index 87f7209..4641d78 100644 --- a/ruoyi-generator/src/main/resources/vm/java/vo.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/vo.java.vm @@ -29,7 +29,7 @@ private ${pkColumn.javaType} ${pkColumn.javaField}; #foreach ($column in $columns) -#if($column.isList) +#if($column.isList && $column.isPk!=1) /** $column.columnComment */ #set($parentheseIndex=$column.columnComment.indexOf("锛�")) #if($parentheseIndex != -1) diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 2fc1921..52551a4 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -1,6 +1,6 @@ { "name": "ruoyi-vue-plus", - "version": "2.3.0", + "version": "2.3.1", "description": "RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺", "author": "LionLi", "license": "MIT", diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue index 29d4dbb..d904f30 100644 --- a/ruoyi-ui/src/views/index.vue +++ b/ruoyi-ui/src/views/index.vue @@ -80,6 +80,18 @@ <span>鏇存柊鏃ュ織</span> </div> <el-collapse accordion> + <el-collapse-item title="v2.3.1 - 2021-6-4"> + <ol> + <li>add 澧炲姞 redisson 鍒嗗竷寮忛攣 娉ㄨВ涓巇emo妗堜緥</li> + <li>add 澧炲姞 Oracle 鍒嗘敮</li> + <li>update 浼樺寲 redis 绌哄瘑鐮佸吋瀹规��</li> + <li>update 浼樺寲鍓嶇浠g爜鐢熸垚鎸夐挳澧炲姞 loading</li> + <li>fix 淇 redisson 涓嶈兘鎵归噺鍒犻櫎鐨刡ug</li> + <li>fix 淇琛ㄥ崟鏋勫缓閫夋嫨涓嬫媺閫夋嫨鎺у埗鍙版姤閿欓棶棰�</li> + <li>fix 淇 vo 浠g爜鐢熸垚 涓婚敭鍒楄〃鏄剧ず 閲嶅鐢熸垚bug</li> + <li>fix 淇涓婁紶璺緞 win 鎵撳寘缂栬瘧涓� win 璺緞, linux 鎶ラ敊bug</li> + </ol> + </el-collapse-item> <el-collapse-item title="v2.3.0 - 2021-6-1"> <ol> <li>add 鍗囩骇 luttuce 涓� redisson 鎬ц兘鏇村己 宸ュ叿鏇村叏</li> @@ -195,12 +207,14 @@ </template> <script> +import config from '../../package.json' + export default { name: "index", data() { return { // 鐗堟湰鍙� - version: "2.3.0", + version: config.version, }; }, methods: { -- Gitblit v1.9.3