疯狂的狮子li
2021-06-11 83718c61cdd544f0a0190efa775ba7aeb08fedb0
发布 v2.3.2
已修改42个文件
已添加2个文件
已删除1个文件
620 ■■■■ 文件已修改
README.md 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/MybatisPlusRedisCache.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/page/PagePlus.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SwaggerProperties.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadPoolProperties.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/TokenProperties.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/XssProperties.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/controller.java.vm 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/java/mapper.java.vm 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-generator/src/main/resources/vm/vue/index.vue.vm 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/components/Editor/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/layout/components/Navbar.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/utils/request.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/index.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/job/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/job/log.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/logininfor/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/online/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/monitor/operlog/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/config/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dept/index.vue 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dict/data.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dict/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/menu/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/notice/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/post/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/role/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/user/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/tool/gen/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -18,6 +18,9 @@
* æ–‡æ¡£æ¡†æž¶ knife4j ç¾ŽåŒ–接口文档
* ä»£ç ç”Ÿæˆå™¨ ä¸€é”®ç”Ÿæˆå‰åŽç«¯ä»£ç 
## å‚考文档
[参考文档 Wiki](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages)
## ä¿®æ”¹RuoYi功能
### ä¾èµ–改动
@@ -43,6 +46,8 @@
* é¡¹ç›®ä¿®æ”¹ä¸º maven多环境配置
* é¡¹ç›®é…ç½®ä¿®æ”¹ä¸º application.yml ç»Ÿä¸€ç®¡ç†
* æ•°æ®æƒé™ä¿®æ”¹ä¸º é€‚配支持单表、多表
* ä½¿ç”¨ redisson å®žçް spring-cache æ•´åˆ
* å¢žåŠ  mybatis-plus äºŒçº§ç¼“å­˜ redis å­˜å‚¨
### å…¶ä»–
@@ -58,38 +63,6 @@
作者为兼职做开源,平时还需要工作,如果帮到了您可以请作者吃个盒饭  
<img src="https://images.gitee.com/uploads/images/2021/0525/101654_451e4523_1766278.jpeg" width="300px" height="450px" />
<img src="https://images.gitee.com/uploads/images/2021/0525/101713_3d18b119_1766278.jpeg" width="300px" height="450px" />
## é‡ç‚¹æ³¨æ„äº‹é¡¹
若依文档对事务注解的描述 [关于事务](https://doc.ruoyi.vip/ruoyi/document/htsc.html#%E4%BA%8B%E5%8A%A1%E7%AE%A1%E7%90%86)  ä»¥ä¸‹å¯¹å¤šæ•°æ®æºäº‹åŠ¡åšè¡¥å……:
* åŒä¸€ä¸ªäº‹åŠ¡ä¸‹æ˜¯æ— æ³•åˆ‡æ¢æ•°æ®æºçš„
* ç¦æ­¢ çˆ¶æ–¹æ³•使用 @Transactional åˆ›å»ºäº‹åŠ¡ å­æ–¹æ³•使用 @DataSource åˆ‡æ¢æ•°æ®æº
* æ­£ç¡®ç”¨æ³•: å­æ–¹æ³•单独创建事务 æˆ– çˆ¶æ–¹æ³•使用 @Transactional(propagation = Propagation.REQUIRES_NEW) ä¸ºæ‰€æœ‰å­æ–¹æ³•创建新事务
关于如何使用Tomcat
* æŸ¥çœ‹ruoyi-framework模块的pom.xml文件,根据注释更改依赖
* æŸ¥çœ‹ruoyi-admin模块中的application.yml文件,根据注释更改配置
关于如何创建新模块
* å‚考ruoyi-demo模块
* éœ€è¦æ”¹åЍ: çˆ¶pom ä¸Ž admin模块pom
关于树表生成
* ç›´æŽ¥åœ¨mysql表中 æ·»åŠ  parentId orderNum ç­‰å­—段(根据需要参考 TreeEntityç±»)
* ä»£ç ç”Ÿæˆé€‰æ‹©æ ‘表生成即可
关于数据权限
* åˆ›å»ºè¡¨ éœ€é¢„ç•™ dept_id å­—段 å¦‚需用户权限 è¿˜éœ€é¢„ç•™ user_id å­—段
* æ”¯æŒ Mybatis-Plus æ–¹å¼æ³¨å…¥ å‚考 demo æ¨¡å—用法(需导入 test.sql æ–‡ä»¶)
* æ”¯æŒ XML æ–¹å¼æ³¨å…¥ å‚考 system æ¨¡å—用法
关于vue与boot整合部署
* [前端静态资源如何整合到后端访问](https://doc.ruoyi.vip/ruoyi-vue/other/faq.html#前端静态资源如何整合到后端访问)
关于修改包名
* å°†æ–‡ä»¶å¤¹å…¨éƒ¨ä¿®æ”¹ä¸º com.xxx
* ä½¿ç”¨IDEA全局替换 com.ruoyi æ›¿æ¢ä¸º com.xxx
* ä¸¥ç¦æ‰‹åŠ¨ä¿®æ”¹
## å†…置功能
pom.xml
@@ -13,7 +13,7 @@
    <description>RuoYi-Vue-Plus后台管理系统</description>
    <properties>
        <ruoyi-vue-plus.version>2.3.1</ruoyi-vue-plus.version>
        <ruoyi-vue-plus.version>2.3.2</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>
@@ -21,7 +21,6 @@
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
        <druid.version>1.2.6</druid.version>
        <knife4j.version>3.0.2</knife4j.version>
        <swagger-annotations.version>1.5.22</swagger-annotations.version>
        <fastjson.version>1.2.76</fastjson.version>
        <poi.version>4.1.2</poi.version>
        <velocity.version>1.7</velocity.version>
@@ -47,7 +46,7 @@
                <scope>import</scope>
            </dependency>
            <!--阿里数据库连接池 -->
            <!-- é˜¿é‡Œæ•°æ®åº“连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
@@ -58,18 +57,6 @@
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>${knife4j.version}</version>
                <exclusions>
                    <exclusion>
                        <artifactId>swagger-annotations</artifactId>
                        <groupId>io.swagger</groupId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
                <version>${swagger-annotations.version}</version>
            </dependency>
            <!-- excel工具 -->
@@ -79,7 +66,7 @@
                <version>${poi.version}</version>
            </dependency>
            <!--velocity代码生成使用模板 -->
            <!-- velocity代码生成使用模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity</artifactId>
@@ -93,7 +80,7 @@
                <version>${fastjson.version}</version>
            </dependency>
            <!--Token生成与解析-->
            <!-- Token生成与解析-->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
@@ -139,6 +126,13 @@
                <version>${spring-boot-admin.version}</version>
            </dependency>
            <!--redisson-->
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson-spring-boot-starter</artifactId>
                <version>${redisson.version}</version>
            </dependency>
            <!-- å®šæ—¶ä»»åŠ¡-->
            <dependency>
                <groupId>com.ruoyi</groupId>
@@ -179,13 +173,6 @@
                <groupId>com.ruoyi</groupId>
                <artifactId>ruoyi-demo</artifactId>
                <version>${ruoyi-vue-plus.version}</version>
            </dependency>
            <!--redisson-->
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson-spring-boot-starter</artifactId>
                <version>${redisson.version}</version>
            </dependency>
        </dependencies>
ruoyi-admin/src/main/resources/application.yml
@@ -288,8 +288,6 @@
        url: http://localhost:${server.port}${spring.boot.admin.context-path}
        instance:
          prefer-ip: true # æ³¨å†Œå®žä¾‹æ—¶ï¼Œä¼˜å…ˆä½¿ç”¨ IP
      #        username: ruoyi
      #        password: 123456
      # Spring Boot Admin Server æœåŠ¡ç«¯çš„ç›¸å…³é…ç½®
      context-path: /admin # é…ç½® Spring
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml
ruoyi-common/pom.xml
@@ -137,11 +137,6 @@
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
@@ -17,7 +17,7 @@
/**
 * è§’色表 sys_role
 *
 *
 * @author ruoyi
 */
@@ -51,8 +51,8 @@
    @NotBlank(message = "显示顺序不能为空")
    private String roleSort;
    /** æ•°æ®èŒƒå›´ï¼ˆ1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限) */
    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限")
    /** æ•°æ®èŒƒå›´ï¼ˆ1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
    private String dataScope;
    /** èœå•树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
ruoyi-common/src/main/java/com/ruoyi/common/core/mybatisplus/MybatisPlusRedisCache.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
package com.ruoyi.common.core.mybatisplus;
import cn.hutool.extra.spring.SpringUtil;
import com.ruoyi.common.core.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
 * mybatis-redis äºŒçº§ç¼“å­˜
 *
 * @author Lion Li
 */
@Slf4j
public class MybatisPlusRedisCache implements Cache {
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
    private RedisCache redisCache;
    private String id;
    public MybatisPlusRedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
    }
    @Override
    public String getId() {
        return this.id;
    }
    @Override
    public void putObject(Object key, Object value) {
        if (redisCache == null) {
            redisCache = SpringUtil.getBean(RedisCache.class);
        }
        if (value != null) {
            redisCache.setCacheObject(key.toString(), value);
        }
    }
    @Override
    public Object getObject(Object key) {
        if (redisCache == null) {
            //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
            redisCache = SpringUtil.getBean(RedisCache.class);
        }
        try {
            if (key != null) {
                return redisCache.getCacheObject(key.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("缓存出错");
        }
        return null;
    }
    @Override
    public Object removeObject(Object key) {
        if (redisCache == null) {
            redisCache = SpringUtil.getBean(RedisCache.class);
        }
        if (key != null) {
            redisCache.deleteObject(key.toString());
        }
        return null;
    }
    @Override
    public void clear() {
        log.debug("清空缓存");
        if (redisCache == null) {
            redisCache = SpringUtil.getBean(RedisCache.class);
        }
        Collection<String> keys = redisCache.keys("*:" + this.id + "*");
        if (!CollectionUtils.isEmpty(keys)) {
            redisCache.deleteObject(keys);
        }
    }
    @Override
    public int getSize() {
        RedisTemplate<String, Object> redisTemplate = SpringUtil.getBean("redisTemplate");
        Long size = redisTemplate.execute(RedisServerCommands::dbSize);
        return size.intValue();
    }
    @Override
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/page/PagePlus.java
@@ -10,6 +10,13 @@
import java.util.Collections;
import java.util.List;
/**
 * åˆ†é¡µ Page å¢žå¼ºå¯¹è±¡
 *
 * @param <T> æ•°æ®åº“实体
 * @param <K> vo实体
 * @author Lion Li
 */
@Data
@Accessors(chain = true)
public class PagePlus<T,K> implements IPage<T> {
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockManager.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,170 @@
package com.ruoyi.common.core.redis;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
 * redis é”ç®¡ç†ç±»
 *
 * @author shenxinquan
 */
@Component
public class RedisLockManager {
    @Autowired
    private RedissonClient redissonClient;
    /**
     * é€šç”¨é”
     */
    private final static Integer BASE_LOCK = 1;
    /**
     * å…¬å¹³é”
     */
    private final static Integer FAIR_LOCK = 2;
    /**
     * å­˜æ”¾å½“前线程获取锁的类型
     */
    private final ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
    /**
     * èŽ·å–é”
     */
    private RLock getLock(String key, Integer lockType) {
        Assert.isTrue(StrUtil.isNotBlank(key), "key不能为空");
        threadLocal.set(lockType);
        RLock lock;
        if (BASE_LOCK.equals(lockType)) {
            lock = redissonClient.getLock(key);
        } else if (FAIR_LOCK.equals(lockType)) {
            lock = redissonClient.getFairLock(key);
        } else {
            throw new RuntimeException("锁不存在!");
        }
        return lock;
    }
    /**
     * èŽ·å–é”ï¼ˆä¸ç”¨è®¾ç½®è¶…æ—¶æ—¶é—´ï¼Œä¸€ç›´ç­‰å¾…ï¼‰
     */
    public boolean getLock(String key) {
        RLock lock = getLock(key, BASE_LOCK);
        return lock.tryLock();
    }
    /**
     * è®¾ç½®è¿‡æœŸæ—¶é—´
     *
     * @param key
     * @param time       è¿‡æœŸæ—¶é—´
     * @param expireUnit æ—¶é—´å•位
     */
    public boolean getLock(String key, long time, TimeUnit expireUnit) {
        Assert.isTrue(time > 0, "过期时间必须大于0");
        Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空");
        RLock lock = getLock(key, BASE_LOCK);
        try {
            return lock.tryLock(time, expireUnit);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * è®¾ç½®è¿‡æœŸæ—¶é—´
     *
     * @param key
     * @param waitTime   èŽ·å–é”ç­‰å¾…æ—¶é—´
     * @param leaseTime  ä¿ç•™é”çš„æ—¶é—´
     * @param expireUnit æ—¶é—´å•位
     */
    public boolean getLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) {
        Assert.isTrue(waitTime > 0, "获取锁等待时间必须大于0");
        Assert.isTrue(leaseTime > 0, "保留锁的时间必须大于0");
        Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空");
        RLock lock = getLock(key, BASE_LOCK);
        try {
            return lock.tryLock(waitTime, leaseTime, expireUnit);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * èŽ·å–è®¡æ•°å™¨é”
     *
     * @param key
     * @param count countDownLatch çš„æ•°é‡
     */
    public RCountDownLatch getCountDownLatch(String key, long count) {
        Assert.isTrue(count >= 0, "count数量必须大于等于0");
        RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(key);
        rCountDownLatch.trySetCount(count);
        return rCountDownLatch;
    }
    /**
     * èŽ·å–å…¬å¹³é”
     *
     * @param key
     * @param waitTime   èŽ·å–é”ç­‰å¾…æ—¶é—´
     * @param leaseTime  æŒæœ‰é”çš„æ—¶é—´
     * @param expireUnit æ—¶é—´å•位
     * @return
     * @throws InterruptedException
     */
    public boolean getFairLock(String key, long waitTime, long leaseTime, TimeUnit expireUnit) {
        Assert.isTrue(waitTime > 0, "获取锁等待时间必须大于0");
        Assert.isTrue(leaseTime > 0, "保留锁的时间必须大于0");
        Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空");
        RLock lock = getLock(key, FAIR_LOCK);
        try {
            return lock.tryLock(waitTime, leaseTime, expireUnit);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * èŽ·å–å…¬å¹³é”
     *
     * @param key
     * @param leaseTime  æŒæœ‰é”çš„æ—¶é—´
     * @param expireUnit æ—¶é—´å•位
     */
    public boolean getFairLock(String key, long leaseTime, TimeUnit expireUnit) {
        Assert.isTrue(leaseTime > 0, "保留锁的时间必须大于0");
        Assert.isTrue(Validator.isNotEmpty(expireUnit), "时间单位不能为空");
        RLock lock = getLock(key, FAIR_LOCK);
        try {
            return lock.tryLock(leaseTime, expireUnit);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * é‡Šæ”¾é”(统一释放)
     */
    public void unLock(String key) {
        Integer lockType = threadLocal.get();
        RLock lock = getLock(key, lockType);
        lock.unlock();
        threadLocal.remove();
    }
}
ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
@@ -2,9 +2,15 @@
import com.ruoyi.common.annotation.RedisLock;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisLockManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
@@ -12,16 +18,20 @@
 *
 * @author shenxinquan
 */
@Slf4j
@RestController
@RequestMapping("/demo/redisLock")
public class RedisLockController {
    @Autowired
    private RedisLockManager redisLockManager;
    /**
     * #p0 æ ‡è¯†å–第一个参数为redis锁的key
     */
    @GetMapping("/getLock")
    @GetMapping("/testLock1")
    @RedisLock(expireTime = 10, key = "#p0")
    public AjaxResult<String> getLock(String key, String value) {
    public AjaxResult<String> testLock1(String key, String value) {
        try {
            // åŒæ—¶è¯·æ±‚排队
//            Thread.sleep(5000);
@@ -32,4 +42,34 @@
        }
        return AjaxResult.success("操作成功",value);
    }
    /**
     * æµ‹è¯•锁工具类
     */
    @GetMapping("/testLock2")
    public AjaxResult<Void> testLock(String key, Long time) {
        try {
            boolean flag = redisLockManager.getLock(key, time, TimeUnit.SECONDS);
            if (flag) {
                log.info("获取锁成功: " + key);
                Thread.sleep(3000);
                redisLockManager.unLock(key);
                log.info("释放锁成功: " + key);
            } else {
                log.error("获取锁失败: " + key);
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }
        return AjaxResult.success();
    }
    /**
     * æµ‹è¯•spring-cache注解
     */
    @Cacheable(value = "test", key = "#key")
    @GetMapping("/testCache")
    public AjaxResult<String> testCache(String key) {
        return AjaxResult.success("操作成功", key);
    }
}
ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestDemoMapper.java
@@ -1,7 +1,9 @@
package com.ruoyi.demo.mapper;
import com.ruoyi.demo.domain.TestDemo;
import com.ruoyi.common.core.mybatisplus.MybatisPlusRedisCache;
import com.ruoyi.common.core.page.BaseMapperPlus;
import com.ruoyi.demo.domain.TestDemo;
import org.apache.ibatis.annotations.CacheNamespace;
/**
 * æµ‹è¯•单表Mapper接口
@@ -9,6 +11,7 @@
 * @author Lion Li
 * @date 2021-05-30
 */
@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
public interface TestDemoMapper extends BaseMapperPlus<TestDemo> {
}
ruoyi-demo/src/main/java/com/ruoyi/demo/mapper/TestTreeMapper.java
@@ -1,7 +1,9 @@
package com.ruoyi.demo.mapper;
import com.ruoyi.demo.domain.TestTree;
import com.ruoyi.common.core.mybatisplus.MybatisPlusRedisCache;
import com.ruoyi.common.core.page.BaseMapperPlus;
import com.ruoyi.demo.domain.TestTree;
import org.apache.ibatis.annotations.CacheNamespace;
/**
 * æµ‹è¯•树表Mapper接口
@@ -9,6 +11,7 @@
 * @author Lion Li
 * @date 2021-05-30
 */
@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
public interface TestTreeMapper extends BaseMapperPlus<TestTree> {
}
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java
@@ -3,6 +3,7 @@
import com.ruoyi.common.annotation.RedisLock;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisLockManager;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
@@ -33,7 +34,7 @@
public class RedisLockAspect {
    @Autowired
    private RedissonClient redissonClient;
    private RedisLockManager redisLockManager;
    @Pointcut("@annotation(com.ruoyi.common.annotation.RedisLock)")
    public void annotationPointcut() {
@@ -70,14 +71,16 @@
        key = Constants.REDIS_LOCK_KEY + key;
        Object res;
        try {
            if (acquire(key, expireTime, TimeUnit.SECONDS)) {
            if (redisLockManager.getLock(key, expireTime, TimeUnit.SECONDS)) {
                log.info("lock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
                try {
                    res = joinPoint.proceed();
                    return res;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                } finally {
                    release(key);
                    redisLockManager.unLock(key);
                    log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
                }
            } else {
                throw new RuntimeException("redis分布式锁注解参数异常");
@@ -131,34 +134,6 @@
            }
        }
        return listPar;
    }
    /**
     * åŠ é”ï¼ˆRLock)带超时时间的
     */
    private boolean acquire(String key, long expire, TimeUnit expireUnit) {
        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) {
        //获取所对象
        RLock mylock = redissonClient.getLock(lockName);
        //释放锁(解锁)
        mylock.unlock();
        log.info("unlock => key : " + lockName + " , ThreadName : " + Thread.currentThread().getName());
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/AsyncConfig.java
@@ -11,6 +11,11 @@
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
 * å¼‚步配置
 *
 * @author Lion Li
 */
@EnableAsync
@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {
ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java
@@ -6,15 +6,20 @@
import org.redisson.api.RedissonClient;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.redisson.spring.cache.CacheConfig;
import org.redisson.spring.cache.RedissonSpringCacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
 * redis配置
@@ -67,4 +72,15 @@
            .setDnsMonitoringInterval(singleServerConfig.getDnsMonitoringInterval());
        return Redisson.create(config);
    }
    /**
     * æ•´åˆspring-cache
     */
    @Bean
    public CacheManager cacheManager(RedissonClient redissonClient) {
        Map<String, CacheConfig> config = new HashMap<>();
        config.put("redissonCacheMap", new CacheConfig(30*60*1000, 10*60*1000));
        return new RedissonSpringCacheManager(redissonClient, config, JsonJacksonCodec.INSTANCE);
    }
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
@@ -15,7 +15,7 @@
/**
 * é€šç”¨é…ç½®
 *
 *
 * @author ruoyi
 */
@Configuration
@@ -31,8 +31,7 @@
        registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
        /** swagger配置 */
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
    }
    /**
@@ -63,4 +62,4 @@
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java
@@ -3,6 +3,7 @@
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.ruoyi.framework.config.properties.SwaggerProperties;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -13,18 +14,16 @@
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
 * Swagger2的接口配置
 * Swagger æ–‡æ¡£é…ç½®
 *
 * @author Lion Li
 */
@Configuration
@EnableSwagger2
@EnableKnife4j
public class SwaggerConfig {
@@ -36,7 +35,7 @@
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
        return new Docket(DocumentationType.OAS_30)
            .enable(swaggerProperties.getEnabled())
            // ç”¨æ¥åˆ›å»ºè¯¥API的基本信息,展示在文档的页面中(自定义展示的信息)
            .apiInfo(apiInfo())
@@ -60,7 +59,7 @@
     */
    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
        apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
        return apiKeyList;
    }
@@ -72,7 +71,7 @@
        securityContexts.add(
            SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("^(?!auth).*$"))
                .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
                .build());
        return securityContexts;
    }
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SwaggerProperties.java
@@ -6,7 +6,7 @@
import org.springframework.stereotype.Component;
/**
 * éªŒè¯ç  é…ç½®å±žæ€§
 * swagger é…ç½®å±žæ€§
 *
 * @author Lion Li
 */
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadPoolProperties.java
@@ -5,7 +5,7 @@
import org.springframework.stereotype.Component;
/**
 * éªŒè¯ç  é…ç½®å±žæ€§
 * çº¿ç¨‹æ±  é…ç½®å±žæ€§
 *
 * @author Lion Li
 */
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/TokenProperties.java
@@ -4,6 +4,11 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
 * token é…ç½®å±žæ€§
 *
 * @author Lion Li
 */
@Data
@Component
@ConfigurationProperties(prefix = "token")
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/XssProperties.java
@@ -5,7 +5,7 @@
import org.springframework.stereotype.Component;
/**
 * éªŒè¯ç  é…ç½®å±žæ€§
 * xss过滤 é…ç½®å±žæ€§
 *
 * @author Lion Li
 */
ruoyi-generator/src/main/resources/vm/java/controller.java.vm
@@ -9,6 +9,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -28,7 +29,7 @@
/**
 * ${functionName}Controller
 *
 *
 * @author ${author}
 * @date ${datetime}
 */
@@ -87,6 +88,7 @@
    @ApiOperation("新增${functionName}")
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:add')")
    @Log(title = "${functionName}", businessType = BusinessType.INSERT)
    @RepeatSubmit
    @PostMapping()
    public AjaxResult<Void> add(@Validated @RequestBody ${ClassName}AddBo bo) {
        return toAjax(i${ClassName}Service.insertByAddBo(bo) ? 1 : 0);
@@ -98,6 +100,7 @@
    @ApiOperation("修改${functionName}")
    @PreAuthorize("@ss.hasPermi('${permissionPrefix}:edit')")
    @Log(title = "${functionName}", businessType = BusinessType.UPDATE)
    @RepeatSubmit
    @PutMapping()
    public AjaxResult<Void> edit(@Validated @RequestBody ${ClassName}EditBo bo) {
        return toAjax(i${ClassName}Service.updateByEditBo(bo) ? 1 : 0);
ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
@@ -2,6 +2,8 @@
import ${packageName}.domain.${ClassName};
import com.ruoyi.common.core.page.BaseMapperPlus;
import com.ruoyi.common.core.mybatisplus.MybatisPlusRedisCache;
import org.apache.ibatis.annotations.CacheNamespace;
/**
 * ${functionName}Mapper接口
@@ -9,6 +11,7 @@
 * @author ${author}
 * @date ${datetime}
 */
@CacheNamespace(implementation = MybatisPlusRedisCache.class, eviction = MybatisPlusRedisCache.class)
public interface ${ClassName}Mapper extends BaseMapperPlus<${ClassName}> {
}
ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm
@@ -541,7 +541,7 @@
          this.loading = false;
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    }
  }
};
ruoyi-generator/src/main/resources/vm/vue/index.vue.vm
@@ -599,7 +599,7 @@
          this.loading = false;
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
#if($table.sub)
    /** ${subTable.functionName}序号 */
@@ -648,7 +648,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/package.json
@@ -1,6 +1,6 @@
{
  "name": "ruoyi-vue-plus",
  "version": "2.3.1",
  "version": "2.3.2",
  "description": "RuoYi-Vue-Plus后台管理系统",
  "author": "LionLi",
  "license": "MIT",
ruoyi-ui/src/components/Editor/index.vue
@@ -75,7 +75,7 @@
            [{ color: [] }, { background: [] }],             // å­—体颜色、字体背景颜色
            [{ align: [] }],                                 // å¯¹é½æ–¹å¼
            ["clean"],                                       // æ¸…除文本格式
            ["link", "image"]                                // é“¾æŽ¥ã€å›¾ç‰‡
            ["link", "image", "video"]                       // é“¾æŽ¥ã€å›¾ç‰‡ã€è§†é¢‘
          ],
        },
        placeholder: "请输入内容",
ruoyi-ui/src/layout/components/Navbar.vue
@@ -8,7 +8,7 @@
    <div class="right-menu">
      <template v-if="device!=='mobile'">
        <search id="header-search" class="right-menu-item" />
        <el-tooltip content="源码地址" effect="dark" placement="bottom">
          <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
        </el-tooltip>
@@ -104,7 +104,7 @@
        this.$store.dispatch('LogOut').then(() => {
          location.href = '/index';
        })
      })
      }).catch(() => {});
    }
  }
}
ruoyi-ui/src/utils/request.js
@@ -63,7 +63,7 @@
        store.dispatch('LogOut').then(() => {
          location.href = '/index';
        })
      })
      }).catch(() => {});
    } else if (code === 500) {
      Message({
        message: msg,
ruoyi-ui/src/views/index.vue
@@ -80,6 +80,17 @@
            <span>更新日志</span>
          </div>
          <el-collapse accordion>
            <el-collapse-item title="v2.3.2 - 2021-6-11">
              <ol>
                <li>add redis锁工具类编写</li>
                <li>update spring-cache æ•´åˆ redisson</li>
                <li>update MybatisPlus整合Redis二级缓存</li>
                <li>update swagger å‡çº§ä¸º 3.0.0 ä½¿ç”¨ OAS_30 åè®®</li>
                <li>update ä¼˜åŒ– ä»£ç ç”Ÿæˆå™¨ å¢žåŠ è¡¨å•é˜²é‡æ³¨è§£</li>
                <li>update ä¼˜åŒ– é”åˆ‡é¢ä»£ç  key到常量类</li>
                <li>fix ä¿®å¤ç›¸å¯¹è·¯å¾„上传异常问题</li>
              </ol>
            </el-collapse-item>
            <el-collapse-item title="v2.3.1 - 2021-6-4">
              <ol>
                <li>add å¢žåŠ  redisson åˆ†å¸ƒå¼é” æ³¨è§£ä¸Ždemo案例</li>
ruoyi-ui/src/views/monitor/job/index.vue
@@ -410,7 +410,7 @@
          return runJob(row.jobId, row.jobGroup);
        }).then(() => {
          this.msgSuccess("执行成功");
        })
        }).catch(() => {});
    },
    /** ä»»åŠ¡è¯¦ç»†ä¿¡æ¯ */
    handleView(row) {
@@ -471,7 +471,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -486,7 +486,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/monitor/job/log.vue
@@ -269,7 +269,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** æ¸…空按钮操作 */
    handleClean() {
@@ -282,7 +282,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("清空成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -297,7 +297,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/monitor/logininfor/index.vue
@@ -202,7 +202,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** æ¸…空按钮操作 */
    handleClean() {
@@ -215,7 +215,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("清空成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -230,7 +230,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/monitor/online/index.vue
@@ -120,7 +120,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("强退成功");
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/monitor/operlog/index.vue
@@ -290,7 +290,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** æ¸…空按钮操作 */
    handleClean() {
@@ -303,7 +303,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("清空成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -318,7 +318,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/system/config/index.vue
@@ -338,7 +338,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -353,7 +353,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    },
    /** åˆ·æ–°ç¼“存按钮操作 */
    handleRefreshCache() {
ruoyi-ui/src/views/system/dept/index.vue
@@ -57,17 +57,17 @@
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['system:dept:edit']"
          >修改</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-plus"
          <el-button
            size="mini"
            type="text"
            icon="el-icon-plus"
            @click="handleAdd(scope.row)"
            v-hasPermi="['system:dept:add']"
          >新增</el-button>
@@ -310,8 +310,8 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    }
  }
};
</script>
</script>
ruoyi-ui/src/views/system/dict/data.vue
@@ -337,7 +337,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -352,7 +352,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/system/dict/index.vue
@@ -342,7 +342,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -357,7 +357,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    },
    /** åˆ·æ–°ç¼“存按钮操作 */
    handleRefreshCache() {
ruoyi-ui/src/views/system/menu/index.vue
@@ -163,7 +163,7 @@
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.menuType != 'M'" label="权限标识">
              <el-input v-model="form.perms" placeholder="请权限标识" maxlength="100" />
              <el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -393,7 +393,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/system/notice/index.vue
@@ -336,7 +336,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/system/post/index.vue
@@ -309,7 +309,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -324,7 +324,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/system/role/index.vue
@@ -593,7 +593,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -608,7 +608,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    }
  }
};
ruoyi-ui/src/views/system/user/index.vue
@@ -631,7 +631,7 @@
        }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        })
        }).catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
@@ -646,7 +646,7 @@
        }).then(response => {
          this.download(response.msg);
          this.exportLoading = false;
        })
        }).catch(() => {});
    },
    /** å¯¼å…¥æŒ‰é’®æ“ä½œ */
    handleImport() {
ruoyi-ui/src/views/tool/gen/index.vue
@@ -283,7 +283,7 @@
          return synchDb(tableName);
      }).then(() => {
          this.msgSuccess("同步成功");
      })
      }).catch(() => {});
    },
    /** æ‰“开导入表弹窗 */
    openImportTable() {
@@ -333,7 +333,7 @@
      }).then(() => {
          this.getList();
          this.msgSuccess("删除成功");
      })
      }).catch(() => {});
    }
  }
};