疯狂的狮子li
2021-05-29 e523764b0f300e5055d6f4bc680aa40d2590504f
发布 2.2.1
已修改24个文件
1179 ■■■■■ 文件已修改
README.md 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-dev.yml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java 337 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java 184 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java 374 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/config.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/api/system/dict/type.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/config/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-ui/src/views/system/dict/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md
@@ -79,6 +79,11 @@
关于vue与boot整合部署  
* [前端静态资源如何整合到后端访问](https://doc.ruoyi.vip/ruoyi-vue/other/faq.html#前端静态资源如何整合到后端访问)
关于修改包名
* 将文件夹全部修改为 com.xxx
* 使用IDEA全局替换 com.ruoyi 替换为 com.xxx
* 严禁手动修改
## 内置功能
1.  用户管理:用户是系统操作者,该功能主要完成系统用户配置。
@@ -100,6 +105,47 @@
17. 在线构建器:拖动表单元素生成相应的HTML代码。
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
## 演示图例
<table border="1" cellpadding="1" cellspacing="1" style="width:500px">
    <tbody>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-972235bcbe3518dedd351ff0e2ee7d1031c.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-5e0097702fa91e2e36391de8127676a7fa1.png" width="1920" /></td>
        </tr>
        <tr>
            <td>
            <p><img src="https://oscimg.oschina.net/oscnet/up-e56e3828f48cd9886d88731766f06d5f3c1.png" width="1920" /></p>
            </td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-0715990ea1a9f254ec2138fcd063c1f556a.png" width="1920" /></td>
        </tr>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-eaf5417ccf921bb64abb959e3d8e290467f.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-fc285cf33095ebf8318de6999af0f473861.png" width="1920" /></td>
        </tr>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-60c83fd8bd61c29df6dbf47c88355e9c272.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-7f731948c8b73c7d90f67f9e1c7a534d5c3.png" width="1920" /></td>
        </tr>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-e4de89b5e2d20c52d3c3a47f9eb88eb8526.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-8791d823a508eb90e67c604f36f57491a67.png" width="1920" /></td>
        </tr>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-4589afd99982ead331785299b894174feb6.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-8ea177cdacaea20995daf2f596b15232561.png" width="1920" /></td>
        </tr>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-32d1d04c55c11f74c9129fbbc58399728c4.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-04fa118f7631b7ae6fd72299ca0a1430a63.png" width="1920" /></td>
        </tr>
        <tr>
            <td><img src="https://oscimg.oschina.net/oscnet/up-fe7e85b65827802bfaadf3acd42568b58c7.png" width="1920" /></td>
            <td><img src="https://oscimg.oschina.net/oscnet/up-eff2b02a54f8188022d8498cfe6af6fcc06.png" width="1920" /></td>
        </tr>
    </tbody>
</table>
## 在线体验
- admin/admin123  
pom.xml
@@ -13,7 +13,7 @@
    <description>RuoYi-Vue-Plus后台管理系统</description>
    <properties>
        <ruoyi-vue-plus.version>2.2.0</ruoyi-vue-plus.version>
        <ruoyi-vue-plus.version>2.2.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>
@@ -249,6 +249,14 @@
    <profiles>
        <profile>
            <id>local</id>
            <properties>
                <!-- 环境标识,需要与配置文件的名称相对应 -->
                <profiles.active>local</profiles.active>
                <logging.level>debug</logging.level>
            </properties>
        </profile>
        <profile>
            <id>dev</id>
            <properties>
                <!-- 环境标识,需要与配置文件的名称相对应 -->
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysConfigController.java
@@ -20,7 +20,7 @@
/**
 * 参数配置 信息操作处理
 *
 *
 * @author ruoyi
 */
@RestController
@@ -110,18 +110,19 @@
    @DeleteMapping("/{configIds}")
    public AjaxResult remove(@PathVariable Long[] configIds)
    {
        return toAjax(configService.deleteConfigByIds(configIds));
        configService.deleteConfigByIds(configIds);
        return success();
    }
    /**
     * 清空缓存
     * 刷新参数缓存
     */
    @PreAuthorize("@ss.hasPermi('system:config:remove')")
    @Log(title = "参数管理", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clearCache")
    public AjaxResult clearCache()
    @DeleteMapping("/refreshCache")
    public AjaxResult refreshCache()
    {
        configService.clearCache();
        configService.resetConfigCache();
        return AjaxResult.success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictDataController.java
@@ -21,7 +21,7 @@
/**
 * 数据字典信息
 *
 *
 * @author ruoyi
 */
@RestController
@@ -107,6 +107,7 @@
    @DeleteMapping("/{dictCodes}")
    public AjaxResult remove(@PathVariable Long[] dictCodes)
    {
        return toAjax(dictDataService.deleteDictDataByIds(dictCodes));
        dictDataService.deleteDictDataByIds(dictCodes);
        return success();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDictTypeController.java
@@ -19,7 +19,7 @@
/**
 * 数据字典信息
 *
 *
 * @author ruoyi
 */
@RestController
@@ -96,18 +96,19 @@
    @DeleteMapping("/{dictIds}")
    public AjaxResult remove(@PathVariable Long[] dictIds)
    {
        return toAjax(dictTypeService.deleteDictTypeByIds(dictIds));
        dictTypeService.deleteDictTypeByIds(dictIds);
        return success();
    }
    /**
     * 清空缓存
     * 刷新字典缓存
     */
    @PreAuthorize("@ss.hasPermi('system:dict:remove')")
    @Log(title = "字典类型", businessType = BusinessType.CLEAN)
    @DeleteMapping("/clearCache")
    public AjaxResult clearCache()
    @DeleteMapping("/refreshCache")
    public AjaxResult refreshCache()
    {
        dictTypeService.clearCache();
        dictTypeService.resetDictCache();
        return AjaxResult.success();
    }
ruoyi-admin/src/main/resources/application-dev.yml
@@ -1,7 +1,3 @@
---
server:
  port: 8081
---
# 数据源配置
spring:
  datasource:
@@ -10,9 +6,9 @@
    druid:
      # 主库数据源
      master:
        url: jdbc:mysql://39.101.143.184:3306/ruoyi-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
        username: ruoyi-vue
        password: ryvue
        url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true
        username: root
        password: root
      # 从库数据源
      slave:
        # 从数据源开关/默认关闭
@@ -62,13 +58,13 @@
  # redis 配置
  redis:
    # 地址
    host: 39.101.143.184
    host: localhost
    # 端口,默认为6379
    port: 6379
    # 数据库索引
    database: 0
    # 密码
    password: ryvue
    password:
    # 连接超时时间
    timeout: 10s
    lettuce:
ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java
@@ -156,6 +156,16 @@
    }
    /**
     * 删除指定字典缓存
     *
     * @param key 字典键
     */
    public static void removeDictCache(String key)
    {
        SpringUtils.getBean(RedisCache.class).deleteObject(getCacheKey(key));
    }
    /**
     * 清空字典缓存
     */
    public static void clearDictCache()
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java
@@ -68,6 +68,7 @@
    @Before("dataScopePointCut()")
    public void doBefore(JoinPoint point) throws Throwable
    {
        clearDataScope(point);
        handleDataScope(point);
    }
@@ -144,18 +145,8 @@
        if (StrUtil.isNotBlank(sqlString.toString()))
        {
            Object params = joinPoint.getArgs()[0];
            if (Validator.isNotNull(params))
            {
                try {
                    Method getParams = params.getClass().getDeclaredMethod("getParams", null);
                    Map<String, Object> invoke = (Map<String, Object>) getParams.invoke(params, null);
                    invoke.put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
            putDataScope(joinPoint, sqlString.substring(4));
        }
    }
    /**
@@ -173,4 +164,30 @@
        }
        return null;
    }
    /**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint)
    {
        Object params = joinPoint.getArgs()[0];
        if (Validator.isNotNull(params))
        {
            putDataScope(joinPoint, "");
        }
    }
    private static void putDataScope(JoinPoint joinPoint, String sql) {
        Object params = joinPoint.getArgs()[0];
        if (Validator.isNotNull(params))
        {
            try {
                Method getParams = params.getClass().getDeclaredMethod("getParams", null);
                Map<String, Object> invoke = (Map<String, Object>) getParams.invoke(params, null);
                invoke.put(DATA_SCOPE, sql);
            } catch (Exception e) {
                // 方法未找到 不处理
            }
        }
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
@@ -1,7 +1,10 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.BaseMapperPlus;
import java.util.List;
/**
 * 字典表 数据层
@@ -10,4 +13,11 @@
 */
public interface SysDictDataMapper extends BaseMapperPlus<SysDictData> {
    default List<SysDictData> selectDictDataByType(String dictType) {
        return selectList(
            new LambdaQueryWrapper<SysDictData>()
                .eq(SysDictData::getStatus, "0")
                .eq(SysDictData::getDictType, dictType)
                .orderByAsc(SysDictData::getDictSort));
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysConfigService.java
@@ -62,12 +62,22 @@
     * @param configIds 需要删除的参数ID
     * @return 结果
     */
    public int deleteConfigByIds(Long[] configIds);
    public void deleteConfigByIds(Long[] configIds);
    /**
     * 清空缓存数据
     * 加载参数缓存数据
     */
    public void clearCache();
    public void loadingConfigCache();
    /**
     * 清空参数缓存数据
     */
    public void clearConfigCache();
    /**
     * 重置参数缓存数据
     */
    public void resetConfigCache();
    /**
     * 校验参数键名是否唯一
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
@@ -47,7 +47,7 @@
     * @param dictCodes 需要删除的字典数据ID
     * @return 结果
     */
    public int deleteDictDataByIds(Long[] dictCodes);
    public void deleteDictDataByIds(Long[] dictCodes);
    /**
     * 新增保存字典数据信息
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictTypeService.java
@@ -62,12 +62,22 @@
     * @param dictIds 需要删除的字典ID
     * @return 结果
     */
    public int deleteDictTypeByIds(Long[] dictIds);
    public void deleteDictTypeByIds(Long[] dictIds);
    /**
     * 清空缓存数据
     * 加载字典缓存数据
     */
    public void clearCache();
    public void loadingDictCache();
    /**
     * 清空字典缓存数据
     */
    public void clearDictCache();
    /**
     * 重置字典缓存数据
     */
    public void resetDictCache();
    /**
     * 新增保存字典类型信息
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
@@ -20,7 +20,6 @@
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -33,175 +32,191 @@
@Service
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements ISysConfigService {
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SysConfigMapper configMapper;
    /**
     * 项目启动时,初始化参数到缓存
     */
    @PostConstruct
    public void init() {
        List<SysConfig> configsList = baseMapper.selectList(new LambdaQueryWrapper<>());
        for (SysConfig config : configsList) {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
    }
    @Autowired
    private RedisCache redisCache;
    @Override
    public TableDataInfo<SysConfig> selectPageConfigList(SysConfig config) {
        Map<String, Object> params = config.getParams();
        LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
                .like(StrUtil.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
                .eq(StrUtil.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
                .like(StrUtil.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
                .apply(Validator.isNotEmpty(params.get("beginTime")),
                        "date_format(create_time,'%y%m%d') >= date_format(#{0},'%y%m%d')",
                        params.get("beginTime"))
                .apply(Validator.isNotEmpty(params.get("endTime")),
                        "date_format(create_time,'%y%m%d') <= date_format(#{0},'%y%m%d')",
                        params.get("endTime"));
        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
    }
    /**
     * 项目启动时,初始化参数到缓存
     */
    @PostConstruct
    public void init() {
        loadingConfigCache();
    }
    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    @DataSource(DataSourceType.MASTER)
    public SysConfig selectConfigById(Long configId) {
        return baseMapper.selectById(configId);
    }
    @Override
    public TableDataInfo<SysConfig> selectPageConfigList(SysConfig config) {
        Map<String, Object> params = config.getParams();
        LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
            .like(StrUtil.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
            .eq(StrUtil.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
            .like(StrUtil.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
            .apply(Validator.isNotEmpty(params.get("beginTime")),
                "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
                params.get("beginTime"))
            .apply(Validator.isNotEmpty(params.get("endTime")),
                "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
                params.get("endTime"));
        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
    }
    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    @Override
    public String selectConfigByKey(String configKey) {
        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
        if (Validator.isNotEmpty(configValue)) {
            return configValue;
        }
        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
                .eq(SysConfig::getConfigKey, configKey));
        if (Validator.isNotNull(retConfig)) {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StrUtil.EMPTY;
    }
    /**
     * 查询参数配置信息
     *
     * @param configId 参数配置ID
     * @return 参数配置信息
     */
    @Override
    @DataSource(DataSourceType.MASTER)
    public SysConfig selectConfigById(Long configId) {
        return baseMapper.selectById(configId);
    }
    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        Map<String, Object> params = config.getParams();
        LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
                .like(StrUtil.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
                .eq(StrUtil.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
                .like(StrUtil.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
                .apply(Validator.isNotEmpty(params.get("beginTime")),
                        "date_format(create_time,'%y%m%d') >= date_format(#{0},'%y%m%d')",
                        params.get("beginTime"))
                .apply(Validator.isNotEmpty(params.get("endTime")),
                        "date_format(create_time,'%y%m%d') >= date_format(#{0},'%y%m%d')",
                        params.get("endTime"));
        return baseMapper.selectList(lqw);
    }
    /**
     * 根据键名查询参数配置信息
     *
     * @param configKey 参数key
     * @return 参数键值
     */
    @Override
    public String selectConfigByKey(String configKey) {
        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
        if (Validator.isNotEmpty(configValue)) {
            return configValue;
        }
        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
            .eq(SysConfig::getConfigKey, configKey));
        if (Validator.isNotNull(retConfig)) {
            redisCache.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StrUtil.EMPTY;
    }
    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int insertConfig(SysConfig config) {
        int row = baseMapper.insert(config);
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
        return row;
    }
    /**
     * 查询参数配置列表
     *
     * @param config 参数配置信息
     * @return 参数配置集合
     */
    @Override
    public List<SysConfig> selectConfigList(SysConfig config) {
        Map<String, Object> params = config.getParams();
        LambdaQueryWrapper<SysConfig> lqw = new LambdaQueryWrapper<SysConfig>()
            .like(StrUtil.isNotBlank(config.getConfigName()), SysConfig::getConfigName, config.getConfigName())
            .eq(StrUtil.isNotBlank(config.getConfigType()), SysConfig::getConfigType, config.getConfigType())
            .like(StrUtil.isNotBlank(config.getConfigKey()), SysConfig::getConfigKey, config.getConfigKey())
            .apply(Validator.isNotEmpty(params.get("beginTime")),
                "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
                params.get("beginTime"))
            .apply(Validator.isNotEmpty(params.get("endTime")),
                "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
                params.get("endTime"));
        return baseMapper.selectList(lqw);
    }
    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int updateConfig(SysConfig config) {
        int row = baseMapper.updateById(config);
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
        return row;
    }
    /**
     * 新增参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int insertConfig(SysConfig config) {
        int row = baseMapper.insert(config);
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
        return row;
    }
    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     * @return 结果
     */
    @Override
    public int deleteConfigByIds(Long[] configIds) {
        for (Long configId : configIds) {
            SysConfig config = selectConfigById(configId);
            if (StrUtil.equals(UserConstants.YES, config.getConfigType())) {
                throw new CustomException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
            }
        }
        int count = baseMapper.deleteBatchIds(Arrays.asList(configIds));
        if (count > 0) {
            Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
            redisCache.deleteObject(keys);
        }
        return count;
    }
    /**
     * 修改参数配置
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public int updateConfig(SysConfig config) {
        int row = baseMapper.updateById(config);
        if (row > 0) {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
        return row;
    }
    /**
     * 清空缓存数据
     */
    @Override
    public void clearCache() {
        Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
        redisCache.deleteObject(keys);
    }
    /**
     * 批量删除参数信息
     *
     * @param configIds 需要删除的参数ID
     * @return 结果
     */
    @Override
    public void deleteConfigByIds(Long[] configIds) {
        for (Long configId : configIds) {
            SysConfig config = selectConfigById(configId);
            if (StrUtil.equals(UserConstants.YES, config.getConfigType())) {
                throw new CustomException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
            }
            configMapper.deleteById(configId);
            redisCache.deleteObject(getCacheKey(config.getConfigKey()));
        }
    }
    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config) {
        Long configId = Validator.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
        if (Validator.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    /**
     * 加载参数缓存数据
     */
    @Override
    public void loadingConfigCache() {
        List<SysConfig> configsList = selectConfigList(new SysConfig());
        for (SysConfig config : configsList) {
            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
        }
    }
    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return Constants.SYS_CONFIG_KEY + configKey;
    }
    /**
     * 清空参数缓存数据
     */
    @Override
    public void clearConfigCache() {
        Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*");
        redisCache.deleteObject(keys);
    }
    /**
     * 重置参数缓存数据
     */
    @Override
    public void resetConfigCache() {
        clearConfigCache();
        loadingConfigCache();
    }
    /**
     * 校验参数键名是否唯一
     *
     * @param config 参数配置信息
     * @return 结果
     */
    @Override
    public String checkConfigKeyUnique(SysConfig config) {
        Long configId = Validator.isNull(config.getConfigId()) ? -1L : config.getConfigId();
        SysConfig info = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getConfigKey, config.getConfigKey()));
        if (Validator.isNotNull(info) && info.getConfigId().longValue() != configId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    private String getCacheKey(String configKey) {
        return Constants.SYS_CONFIG_KEY + configKey;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
@@ -11,7 +11,6 @@
import com.ruoyi.system.service.ISysDictDataService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
/**
@@ -22,100 +21,103 @@
@Service
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData> implements ISysDictDataService {
    @Override
    public TableDataInfo<SysDictData> selectPageDictDataList(SysDictData dictData) {
        LambdaQueryWrapper<SysDictData> lqw = new LambdaQueryWrapper<SysDictData>()
                .eq(StrUtil.isNotBlank(dictData.getDictType()), SysDictData::getDictType, dictData.getDictType())
                .like(StrUtil.isNotBlank(dictData.getDictLabel()), SysDictData::getDictLabel, dictData.getDictLabel())
                .eq(StrUtil.isNotBlank(dictData.getStatus()), SysDictData::getStatus, dictData.getStatus())
                .orderByAsc(SysDictData::getDictSort);
        return PageUtils.buildDataInfo(page(PageUtils.buildPage(),lqw));
    }
    @Override
    public TableDataInfo<SysDictData> selectPageDictDataList(SysDictData dictData) {
        LambdaQueryWrapper<SysDictData> lqw = new LambdaQueryWrapper<SysDictData>()
            .eq(StrUtil.isNotBlank(dictData.getDictType()), SysDictData::getDictType, dictData.getDictType())
            .like(StrUtil.isNotBlank(dictData.getDictLabel()), SysDictData::getDictLabel, dictData.getDictLabel())
            .eq(StrUtil.isNotBlank(dictData.getStatus()), SysDictData::getStatus, dictData.getStatus())
            .orderByAsc(SysDictData::getDictSort);
        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
    }
    /**
     * 根据条件分页查询字典数据
     *
     * @param dictData 字典数据信息
     * @return 字典数据集合信息
     */
    @Override
    public List<SysDictData> selectDictDataList(SysDictData dictData) {
        return list(new LambdaQueryWrapper<SysDictData>()
                .eq(StrUtil.isNotBlank(dictData.getDictType()), SysDictData::getDictType, dictData.getDictType())
                .like(StrUtil.isNotBlank(dictData.getDictLabel()), SysDictData::getDictLabel, dictData.getDictLabel())
                .eq(StrUtil.isNotBlank(dictData.getStatus()), SysDictData::getStatus, dictData.getStatus())
                .orderByAsc(SysDictData::getDictSort));
    }
    /**
     * 根据条件分页查询字典数据
     *
     * @param dictData 字典数据信息
     * @return 字典数据集合信息
     */
    @Override
    public List<SysDictData> selectDictDataList(SysDictData dictData) {
        return list(new LambdaQueryWrapper<SysDictData>()
            .eq(StrUtil.isNotBlank(dictData.getDictType()), SysDictData::getDictType, dictData.getDictType())
            .like(StrUtil.isNotBlank(dictData.getDictLabel()), SysDictData::getDictLabel, dictData.getDictLabel())
            .eq(StrUtil.isNotBlank(dictData.getStatus()), SysDictData::getStatus, dictData.getStatus())
            .orderByAsc(SysDictData::getDictSort));
    }
    /**
     * 根据字典类型和字典键值查询字典数据信息
     *
     * @param dictType  字典类型
     * @param dictValue 字典键值
     * @return 字典标签
     */
    @Override
    public String selectDictLabel(String dictType, String dictValue) {
        return getOne(new LambdaQueryWrapper<SysDictData>()
                .select(SysDictData::getDictLabel)
                .eq(SysDictData::getDictType, dictType)
                .eq(SysDictData::getDictValue, dictValue))
                .getDictLabel();
    }
    /**
     * 根据字典类型和字典键值查询字典数据信息
     *
     * @param dictType  字典类型
     * @param dictValue 字典键值
     * @return 字典标签
     */
    @Override
    public String selectDictLabel(String dictType, String dictValue) {
        return getOne(new LambdaQueryWrapper<SysDictData>()
            .select(SysDictData::getDictLabel)
            .eq(SysDictData::getDictType, dictType)
            .eq(SysDictData::getDictValue, dictValue))
            .getDictLabel();
    }
    /**
     * 根据字典数据ID查询信息
     *
     * @param dictCode 字典数据ID
     * @return 字典数据
     */
    @Override
    public SysDictData selectDictDataById(Long dictCode) {
        return getById(dictCode);
    }
    /**
     * 根据字典数据ID查询信息
     *
     * @param dictCode 字典数据ID
     * @return 字典数据
     */
    @Override
    public SysDictData selectDictDataById(Long dictCode) {
        return getById(dictCode);
    }
    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 需要删除的字典数据ID
     * @return 结果
     */
    @Override
    public int deleteDictDataByIds(Long[] dictCodes) {
        int row = baseMapper.deleteBatchIds(Arrays.asList(dictCodes));
        if (row > 0) {
            DictUtils.clearDictCache();
        }
        return row;
    }
    /**
     * 批量删除字典数据信息
     *
     * @param dictCodes 需要删除的字典数据ID
     * @return 结果
     */
    @Override
    public void deleteDictDataByIds(Long[] dictCodes) {
        for (Long dictCode : dictCodes) {
            SysDictData data = selectDictDataById(dictCode);
            baseMapper.deleteById(dictCode);
            List<SysDictData> dictDatas = baseMapper.selectDictDataByType(data.getDictType());
            DictUtils.setDictCache(data.getDictType(), dictDatas);
        }
    }
    /**
     * 新增保存字典数据信息
     *
     * @param dictData 字典数据信息
     * @return 结果
     */
    @Override
    public int insertDictData(SysDictData dictData) {
        int row = baseMapper.insert(dictData);
        if (row > 0) {
            DictUtils.clearDictCache();
        }
        return row;
    }
    /**
     * 新增保存字典数据信息
     *
     * @param data 字典数据信息
     * @return 结果
     */
    @Override
    public int insertDictData(SysDictData data) {
        int row = baseMapper.insert(data);
        if (row > 0) {
            List<SysDictData> dictDatas = baseMapper.selectDictDataByType(data.getDictType());
            DictUtils.setDictCache(data.getDictType(), dictDatas);
        }
        return row;
    }
    /**
     * 修改保存字典数据信息
     *
     * @param dictData 字典数据信息
     * @return 结果
     */
    @Override
    public int updateDictData(SysDictData dictData) {
        int row = baseMapper.updateById(dictData);
        if (row > 0) {
            DictUtils.clearDictCache();
        }
        return row;
    }
    /**
     * 修改保存字典数据信息
     *
     * @param data 字典数据信息
     * @return 结果
     */
    @Override
    public int updateDictData(SysDictData data) {
        int row = baseMapper.updateById(data);
        if (row > 0) {
            List<SysDictData> dictDatas = baseMapper.selectDictDataByType(data.getDictType());
            DictUtils.setDictCache(data.getDictType(), dictDatas);
        }
        return row;
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
@@ -21,7 +21,6 @@
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -33,197 +32,208 @@
@Service
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {
    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Autowired
    private SysDictTypeMapper dictTypeMapper;
    /**
     * 项目启动时,初始化字典到缓存
     */
    @PostConstruct
    public void init() {
        List<SysDictType> dictTypeList = list();
        for (SysDictType dictType : dictTypeList) {
            List<SysDictData> dictDatas = dictDataMapper.selectList(
                    new LambdaQueryWrapper<SysDictData>()
                            .eq(SysDictData::getStatus, 0)
                            .eq(SysDictData::getDictType, dictType.getDictType())
                            .orderByAsc(SysDictData::getDictSort));
            DictUtils.setDictCache(dictType.getDictType(), dictDatas);
        }
    }
    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Override
    public TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType) {
        Map<String, Object> params = dictType.getParams();
        LambdaQueryWrapper<SysDictType> lqw = new LambdaQueryWrapper<SysDictType>()
                .like(StrUtil.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
                .eq(StrUtil.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
                .like(StrUtil.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
                .apply(Validator.isNotEmpty(params.get("beginTime")),
                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
                        params.get("beginTime"))
                .apply(Validator.isNotEmpty(params.get("endTime")),
                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
                        params.get("endTime"));
        return PageUtils.buildDataInfo(page(PageUtils.buildPage(),lqw));
    }
    /**
     * 项目启动时,初始化字典到缓存
     */
    @PostConstruct
    public void init() {
        loadingDictCache();
    }
    /**
     * 根据条件分页查询字典类型
     *
     * @param dictType 字典类型信息
     * @return 字典类型集合信息
     */
    @Override
    public List<SysDictType> selectDictTypeList(SysDictType dictType) {
        Map<String, Object> params = dictType.getParams();
        return list(new LambdaQueryWrapper<SysDictType>()
                .like(StrUtil.isNotBlank(dictType.getDictName()),SysDictType::getDictName, dictType.getDictName())
                .eq(StrUtil.isNotBlank(dictType.getStatus()),SysDictType::getStatus, dictType.getStatus())
                .like(StrUtil.isNotBlank(dictType.getDictType()),SysDictType::getDictType, dictType.getDictType())
                .apply(Validator.isNotEmpty(params.get("beginTime")),
                        "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
                        params.get("beginTime"))
                .apply(Validator.isNotEmpty(params.get("endTime")),
                        "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
                        params.get("endTime")));
    }
    @Override
    public TableDataInfo<SysDictType> selectPageDictTypeList(SysDictType dictType) {
        Map<String, Object> params = dictType.getParams();
        LambdaQueryWrapper<SysDictType> lqw = new LambdaQueryWrapper<SysDictType>()
            .like(StrUtil.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
            .eq(StrUtil.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
            .like(StrUtil.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
            .apply(Validator.isNotEmpty(params.get("beginTime")),
                "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
                params.get("beginTime"))
            .apply(Validator.isNotEmpty(params.get("endTime")),
                "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
                params.get("endTime"));
        return PageUtils.buildDataInfo(page(PageUtils.buildPage(), lqw));
    }
    /**
     * 根据所有字典类型
     *
     * @return 字典类型集合信息
     */
    @Override
    public List<SysDictType> selectDictTypeAll() {
        return list();
    }
    /**
     * 根据条件分页查询字典类型
     *
     * @param dictType 字典类型信息
     * @return 字典类型集合信息
     */
    @Override
    public List<SysDictType> selectDictTypeList(SysDictType dictType) {
        Map<String, Object> params = dictType.getParams();
        return list(new LambdaQueryWrapper<SysDictType>()
            .like(StrUtil.isNotBlank(dictType.getDictName()), SysDictType::getDictName, dictType.getDictName())
            .eq(StrUtil.isNotBlank(dictType.getStatus()), SysDictType::getStatus, dictType.getStatus())
            .like(StrUtil.isNotBlank(dictType.getDictType()), SysDictType::getDictType, dictType.getDictType())
            .apply(Validator.isNotEmpty(params.get("beginTime")),
                "date_format(create_time,'%y%m%d') >= date_format({0},'%y%m%d')",
                params.get("beginTime"))
            .apply(Validator.isNotEmpty(params.get("endTime")),
                "date_format(create_time,'%y%m%d') <= date_format({0},'%y%m%d')",
                params.get("endTime")));
    }
    /**
     * 根据字典类型查询字典数据
     *
     * @param dictType 字典类型
     * @return 字典数据集合信息
     */
    @Override
    public List<SysDictData> selectDictDataByType(String dictType) {
        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
        if (CollUtil.isNotEmpty(dictDatas)) {
            return dictDatas;
        }
        dictDatas = dictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>()
                .eq(SysDictData::getStatus, 0)
                .eq(SysDictData::getDictType, dictType)
                .orderByAsc(SysDictData::getDictSort));
        if (CollUtil.isNotEmpty(dictDatas)) {
            DictUtils.setDictCache(dictType, dictDatas);
            return dictDatas;
        }
        return null;
    }
    /**
     * 根据所有字典类型
     *
     * @return 字典类型集合信息
     */
    @Override
    public List<SysDictType> selectDictTypeAll() {
        return list();
    }
    /**
     * 根据字典类型ID查询信息
     *
     * @param dictId 字典类型ID
     * @return 字典类型
     */
    @Override
    public SysDictType selectDictTypeById(Long dictId) {
        return getById(dictId);
    }
    /**
     * 根据字典类型查询字典数据
     *
     * @param dictType 字典类型
     * @return 字典数据集合信息
     */
    @Override
    public List<SysDictData> selectDictDataByType(String dictType) {
        List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
        if (CollUtil.isNotEmpty(dictDatas)) {
            return dictDatas;
        }
        dictDatas = dictDataMapper.selectDictDataByType(dictType);
        if (CollUtil.isNotEmpty(dictDatas)) {
            DictUtils.setDictCache(dictType, dictDatas);
            return dictDatas;
        }
        return null;
    }
    /**
     * 根据字典类型查询信息
     *
     * @param dictType 字典类型
     * @return 字典类型
     */
    @Override
    public SysDictType selectDictTypeByType(String dictType) {
        return getOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
    }
    /**
     * 根据字典类型ID查询信息
     *
     * @param dictId 字典类型ID
     * @return 字典类型
     */
    @Override
    public SysDictType selectDictTypeById(Long dictId) {
        return getById(dictId);
    }
    /**
     * 批量删除字典类型信息
     *
     * @param dictIds 需要删除的字典ID
     * @return 结果
     */
    @Override
    public int deleteDictTypeByIds(Long[] dictIds) {
        for (Long dictId : dictIds) {
            SysDictType dictType = selectDictTypeById(dictId);
            if (dictDataMapper.selectCount(new LambdaQueryWrapper<SysDictData>()
                    .eq(SysDictData::getDictType, dictType.getDictType())) > 0) {
                throw new CustomException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
            }
        }
        int count = baseMapper.deleteBatchIds(Arrays.asList(dictIds));
        if (count > 0) {
            DictUtils.clearDictCache();
        }
        return count;
    }
    /**
     * 根据字典类型查询信息
     *
     * @param dictType 字典类型
     * @return 字典类型
     */
    @Override
    public SysDictType selectDictTypeByType(String dictType) {
        return getOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
    }
    /**
     * 清空缓存数据
     */
    @Override
    public void clearCache() {
        DictUtils.clearDictCache();
    }
    /**
     * 批量删除字典类型信息
     *
     * @param dictIds 需要删除的字典ID
     * @return 结果
     */
    @Override
    public void deleteDictTypeByIds(Long[] dictIds) {
        for (Long dictId : dictIds) {
            SysDictType dictType = selectDictTypeById(dictId);
            if (dictDataMapper.selectCount(new LambdaQueryWrapper<SysDictData>()
                .eq(SysDictData::getDictType, dictType.getDictType())) > 0) {
                throw new CustomException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
            }
            dictTypeMapper.deleteById(dictId);
            DictUtils.removeDictCache(dictType.getDictType());
        }
    }
    /**
     * 新增保存字典类型信息
     *
     * @param dictType 字典类型信息
     * @return 结果
     */
    @Override
    public int insertDictType(SysDictType dictType) {
        int row = baseMapper.insert(dictType);
        if (row > 0) {
            DictUtils.clearDictCache();
        }
        return row;
    }
    /**
     * 加载字典缓存数据
     */
    @Override
    public void loadingDictCache() {
        List<SysDictType> dictTypeList = list();
        for (SysDictType dictType : dictTypeList) {
            List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
            DictUtils.setDictCache(dictType.getDictType(), dictDatas);
        }
    }
    /**
     * 修改保存字典类型信息
     *
     * @param dictType 字典类型信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDictType(SysDictType dictType) {
        SysDictType oldDict = getById(dictType.getDictId());
        dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
                .set(SysDictData::getDictType, dictType.getDictType())
                .eq(SysDictData::getDictType, oldDict.getDictType()));
        int row = baseMapper.updateById(dictType);
        if (row > 0) {
            DictUtils.clearDictCache();
        }
        return row;
    }
    /**
     * 清空字典缓存数据
     */
    @Override
    public void clearDictCache() {
        DictUtils.clearDictCache();
    }
    /**
     * 校验字典类型称是否唯一
     *
     * @param dict 字典类型
     * @return 结果
     */
    @Override
    public String checkDictTypeUnique(SysDictType dict) {
        Long dictId = Validator.isNull(dict.getDictId()) ? -1L : dict.getDictId();
        SysDictType dictType = getOne(new LambdaQueryWrapper<SysDictType>()
                .eq(SysDictType::getDictType, dict.getDictType())
                .last("limit 1"));
        if (Validator.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    /**
     * 重置字典缓存数据
     */
    @Override
    public void resetDictCache() {
        clearDictCache();
        loadingDictCache();
    }
    /**
     * 新增保存字典类型信息
     *
     * @param dict 字典类型信息
     * @return 结果
     */
    @Override
    public int insertDictType(SysDictType dict) {
        int row = baseMapper.insert(dict);
        if (row > 0) {
            DictUtils.setDictCache(dict.getDictType(), null);
        }
        return row;
    }
    /**
     * 修改保存字典类型信息
     *
     * @param dict 字典类型信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDictType(SysDictType dict) {
        SysDictType oldDict = getById(dict.getDictId());
        dictDataMapper.update(null, new LambdaUpdateWrapper<SysDictData>()
            .set(SysDictData::getDictType, dict.getDictType())
            .eq(SysDictData::getDictType, oldDict.getDictType()));
        int row = baseMapper.updateById(dict);
        if (row > 0) {
            List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
            DictUtils.setDictCache(dict.getDictType(), dictDatas);
        }
        return row;
    }
    /**
     * 校验字典类型称是否唯一
     *
     * @param dict 字典类型
     * @return 结果
     */
    @Override
    public String checkDictTypeUnique(SysDictType dict) {
        Long dictId = Validator.isNull(dict.getDictId()) ? -1L : dict.getDictId();
        SysDictType dictType = getOne(new LambdaQueryWrapper<SysDictType>()
            .eq(SysDictType::getDictType, dict.getDictType())
            .last("limit 1"));
        if (Validator.isNotNull(dictType) && dictType.getDictId().longValue() != dictId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
}
ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml
@@ -40,7 +40,9 @@
            AND status = #{status}
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
        <if test="params.dataScope != null and params.dataScope != ''">
            AND ( ${params.dataScope} )
        </if>
        order by d.parent_id, d.order_num
    </select>
@@ -49,11 +51,10 @@
        from sys_dept d
        left join sys_role_dept rd on d.dept_id = rd.dept_id
        where rd.role_id = #{roleId}
        <if test="deptCheckStrictly">
            and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id =
            rd.dept_id and rd.role_id = #{roleId})
        </if>
            <if test="deptCheckStrictly">
                and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = #{roleId})
            </if>
        order by d.parent_id, d.order_num
    </select>
</mapper>
</mapper>
ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml
@@ -58,7 +58,9 @@
            and date_format(r.create_time,'%y%m%d') &lt;= date_format(#{role.params.endTime},'%y%m%d')
        </if>
        <!-- 数据范围过滤 -->
        ${role.params.dataScope}
        <if test="role.params.dataScope != null and role.params.dataScope != ''">
            AND ( ${role.params.dataScope} )
        </if>
        order by r.role_sort
    </select>
@@ -81,7 +83,9 @@
            and date_format(r.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
        <if test="params.dataScope != null and params.dataScope != ''">
            AND ( ${params.dataScope} )
        </if>
        order by r.role_sort
    </select>
@@ -103,4 +107,4 @@
        WHERE r.del_flag = '0' and u.user_name = #{userName}
    </select>
</mapper>
</mapper>
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -106,7 +106,9 @@
            ancestors) ))
        </if>
        <!-- 数据范围过滤 -->
        ${user.params.dataScope}
        <if test="user.params.dataScope != null and user.params.dataScope != ''">
            AND ( ${user.params.dataScope} )
        </if>
    </select>
    <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
@@ -135,7 +137,9 @@
            ancestors) ))
        </if>
        <!-- 数据范围过滤 -->
        ${params.dataScope}
        <if test="params.dataScope != null and params.dataScope != ''">
            AND ( ${params.dataScope} )
        </if>
    </select>
    <select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
@@ -149,4 +153,4 @@
    </select>
</mapper>
</mapper>
ruoyi-ui/package.json
@@ -1,6 +1,6 @@
{
  "name": "ruoyi-vue-plus",
  "version": "2.2.0",
  "version": "2.2.1",
  "description": "RuoYi-Vue-Plus后台管理系统",
  "author": "LionLi",
  "license": "MIT",
ruoyi-ui/src/api/system/config.js
@@ -51,10 +51,10 @@
  })
}
// 清理参数缓存
export function clearCache() {
// 刷新参数缓存
export function refreshCache() {
  return request({
    url: '/system/config/clearCache',
    url: '/system/config/refreshCache',
    method: 'delete'
  })
}
ruoyi-ui/src/api/system/dict/type.js
@@ -43,10 +43,10 @@
  })
}
// 清理参数缓存
export function clearCache() {
// 刷新字典缓存
export function refreshCache() {
  return request({
    url: '/system/dict/type/clearCache',
    url: '/system/dict/type/refreshCache',
    method: 'delete'
  })
}
ruoyi-ui/src/views/index.vue
@@ -80,6 +80,17 @@
            <span>更新日志</span>
          </div>
          <el-collapse accordion>
            <el-collapse-item title="v2.2.1 - 2021-5-29">
              <ol>
                <li>add 增加 security 权限框架 @Async 异步注解配置</li>
                <li>update 优化数据权限sql 解决MP apply注入附带 AND 语法问题</li>
                <li>update 优化dataScope参数防止注入</li>
                <li>update 优化参数&字典缓存操作</li>
                <li>update 增加修改包名文档</li>
                <li>update 文档增加演示图例</li>
                <li>fix 修复部门类sql符号错误</li>
              </ol>
            </el-collapse-item>
            <el-collapse-item title="v2.2.0 - 2021-5-25">
              <ol>
                <li>同步升级 RuoYi-Vue 3.5.0</li>
@@ -180,7 +191,7 @@
  data() {
    return {
      // 版本号
      version: "2.2.0",
      version: "2.2.1",
    };
  },
  methods: {
ruoyi-ui/src/views/system/config/index.vue
@@ -99,9 +99,9 @@
          plain
          icon="el-icon-refresh"
          size="mini"
          @click="handleClearCache"
          @click="handleRefreshCache"
          v-hasPermi="['system:config:remove']"
        >清理缓存</el-button>
        >刷新缓存</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
@@ -181,7 +181,7 @@
</template>
<script>
import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig, clearCache } from "@/api/system/config";
import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig, refreshCache } from "@/api/system/config";
export default {
  name: "Config",
@@ -355,10 +355,10 @@
          this.exportLoading = false;
        })
    },
    /** 清理缓存按钮操作 */
    handleClearCache() {
      clearCache().then(response => {
        this.msgSuccess("清理成功");
    /** 刷新缓存按钮操作 */
    handleRefreshCache() {
      refreshCache().then(() => {
        this.msgSuccess("刷新成功");
      });
    }
  }
ruoyi-ui/src/views/system/dict/index.vue
@@ -105,9 +105,9 @@
          plain
          icon="el-icon-refresh"
          size="mini"
          @click="handleClearCache"
          @click="handleRefreshCache"
          v-hasPermi="['system:dict:remove']"
        >清理缓存</el-button>
        >刷新缓存</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
@@ -189,7 +189,7 @@
</template>
<script>
import { listType, getType, delType, addType, updateType, exportType, clearCache } from "@/api/system/dict/type";
import { listType, getType, delType, addType, updateType, exportType, refreshCache } from "@/api/system/dict/type";
export default {
  name: "Dict",
@@ -359,10 +359,10 @@
          this.exportLoading = false;
        })
    },
    /** 清理缓存按钮操作 */
    handleClearCache() {
      clearCache().then(response => {
        this.msgSuccess("清理成功");
    /** 刷新缓存按钮操作 */
    handleRefreshCache() {
      refreshCache().then(() => {
        this.msgSuccess("刷新成功");
      });
    }
  }