From c33aa5c9698d9b3e15660fa4719bc5583b07dd49 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期三, 06 七月 2022 15:42:45 +0800
Subject: [PATCH] add 同步ruoyi 新增缓存列表菜单功能

---
 script/sql/update/sqlserver/update-4.1-4.2.sql                                          |   27 --
 ruoyi-ui/src/views/monitor/cache/index.vue                                              |   22 
 ruoyi-ui/src/api/monitor/cache.js                                                       |   48 +++
 ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java                |   49 +++
 script/sql/ry_vue_4.X.sql                                                               |    1 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java         |   70 +++++
 ruoyi-ui/src/assets/icons/svg/redis-list.svg                                            |    2 
 ruoyi-ui/src/views/monitor/cache/list.vue                                               |  241 ++++++++++++++++++
 ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java                 |   72 ++--
 ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java                     |   32 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java                |    7 
 script/sql/postgres/postgres_ry_vue_4.X.sql                                             |    1 
 script/sql/sqlserver/sqlserver_ry_vue_4.X.sql                                           |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java    |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java |    6 
 ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java                     |   45 ---
 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java       |    4 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java    |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java      |    6 
 ruoyi-ui/src/views/system/dict/data.vue                                                 |    3 
 script/sql/update/oracle/update-4.2-4.3.sql                                             |    1 
 ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java             |    3 
 sql/ry_20220613.sql                                                                     |    0 
 ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java      |   10 
 script/sql/update/postgres/update-4.2-4.3.sql                                           |    1 
 ruoyi-ui/vue.config.js                                                                  |    1 
 script/sql/update/update-4.2-4.3.sql                                                    |    2 
 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java                        |   54 ++++
 script/sql/update/sqlserver/update-4.2-4.3.sql                                          |    1 
 script/sql/oracle/oracle_ry_vue_4.X.sql                                                 |    1 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java        |    5 
 31 files changed, 581 insertions(+), 146 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
index 0889aab..3bfe35a 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java
@@ -6,6 +6,7 @@
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.RandomUtil;
 import com.ruoyi.common.annotation.Anonymous;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.enums.CaptchaType;
@@ -60,7 +61,7 @@
         if (smsProperties.getEnabled()) {
             R.fail("褰撳墠绯荤粺娌℃湁寮�鍚煭淇″姛鑳斤紒");
         }
-        String key = Constants.CAPTCHA_CODE_KEY + phonenumber;
+        String key = CacheConstants.CAPTCHA_CODE_KEY + phonenumber;
         String code = RandomUtil.randomNumbers(4);
         RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION));
         // 楠岃瘉鐮佹ā鏉縤d 鑷澶勭悊 (鏌ユ暟鎹簱鎴栧啓姝诲潎鍙�)
@@ -90,7 +91,7 @@
         }
         // 淇濆瓨楠岃瘉鐮佷俊鎭�
         String uuid = IdUtil.simpleUUID();
-        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
         // 鐢熸垚楠岃瘉鐮�
         CaptchaType captchaType = captchaProperties.getType();
         boolean isMath = CaptchaType.MATH == captchaType;
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
index 21fbd20..e84f60d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
@@ -1,17 +1,17 @@
 package com.ruoyi.web.controller.monitor;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.domain.SysCache;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.data.redis.connection.RedisServerCommands;
 import org.springframework.data.redis.core.RedisCallback;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.*;
 
@@ -27,6 +27,19 @@
 public class CacheController {
 
     private final RedisTemplate<String, String> redisTemplate;
+
+    private final static List<SysCache> CACHES = new ArrayList<>();
+
+    static {
+        CACHES.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "鐢ㄦ埛淇℃伅"));
+        CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "鍦ㄧ嚎鐢ㄦ埛"));
+        CACHES.add(new SysCache(CacheConstants.LOGIN_ERROR, "鐧婚檰閿欒"));
+        CACHES.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "閰嶇疆淇℃伅"));
+        CACHES.add(new SysCache(CacheConstants.SYS_DICT_KEY, "鏁版嵁瀛楀吀"));
+        CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "楠岃瘉鐮�"));
+        CACHES.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "闃查噸鎻愪氦"));
+        CACHES.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "闄愭祦澶勭悊"));
+    }
 
     @ApiOperation("鑾峰彇缂撳瓨鐩戞帶璇︾粏淇℃伅")
     @SaCheckPermission("monitor:cache:list")
@@ -53,4 +66,55 @@
         result.put("commandStats", pieList);
         return R.ok(result);
     }
+
+    @ApiOperation("鑾峰彇缂撳瓨鍚嶇О鍒楄〃")
+    @SaCheckPermission("monitor:cache:list")
+    @GetMapping("/getNames")
+    public R<List<SysCache>> cache() {
+        return R.ok(CACHES);
+    }
+
+    @ApiOperation("鑾峰彇KEYS鍩轰簬缂撳瓨鍚�")
+    @SaCheckPermission("monitor:cache:list")
+    @GetMapping("/getKeys/{cacheName}")
+    public R<Set<String>> getCacheKeys(@PathVariable String cacheName) {
+        Set<String> cacheKyes = redisTemplate.keys(cacheName + "*");
+        return R.ok(cacheKyes);
+    }
+
+    @ApiOperation("鑾峰彇鍊煎熀浜庣紦瀛樺悕涓嶬EY")
+    @SaCheckPermission("monitor:cache:list")
+    @GetMapping("/getValue/{cacheName}/{cacheKey}")
+    public R<SysCache> getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) {
+        String cacheValue = redisTemplate.opsForValue().get(cacheKey);
+        SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
+        return R.ok(sysCache);
+    }
+
+    @ApiOperation("娓呯┖缂撳瓨鍚�")
+    @SaCheckPermission("monitor:cache:list")
+    @DeleteMapping("/clearCacheName/{cacheName}")
+    public R<Void> clearCacheName(@PathVariable String cacheName) {
+        Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
+        redisTemplate.delete(cacheKeys);
+        return R.ok();
+    }
+
+    @ApiOperation("娓呯┖缂撳瓨KEY")
+    @SaCheckPermission("monitor:cache:list")
+    @DeleteMapping("/clearCacheKey/{cacheKey}")
+    public R<Void> clearCacheKey(@PathVariable String cacheKey) {
+        redisTemplate.delete(cacheKey);
+        return R.ok();
+    }
+
+    @ApiOperation("娓呯┖鎵�鏈夌紦瀛�")
+    @SaCheckPermission("monitor:cache:list")
+    @DeleteMapping("/clearCacheAll")
+    public R<Void> clearCacheAll() {
+        Collection<String> cacheKeys = redisTemplate.keys("*");
+        redisTemplate.delete(cacheKeys);
+        return R.ok();
+    }
+
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
index 82fdf88..a1ea81f 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java
@@ -5,7 +5,7 @@
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import com.ruoyi.common.annotation.Log;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
@@ -43,12 +43,12 @@
         List<String> keys = StpUtil.searchTokenValue("", -1, 0);
         List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
         for (String key : keys) {
-            String token = key.replace(Constants.LOGIN_TOKEN_KEY, "");
+            String token = key.replace(CacheConstants.LOGIN_TOKEN_KEY, "");
             // 濡傛灉宸茬粡杩囨湡鍒欒涪涓嬬嚎
             if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < 0) {
                 continue;
             }
-            userOnlineDTOList.add(RedisUtils.getCacheObject(Constants.ONLINE_TOKEN_KEY + token));
+            userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
         }
         if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
             userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java
index 90db9d7..2e3ff7a 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RateLimiter.java
@@ -1,36 +1,36 @@
-package com.ruoyi.common.annotation;
-
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.enums.LimitType;
-
-import java.lang.annotation.*;
-
-/**
- * 闄愭祦娉ㄨВ
- *
- * @author Lion Li
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface RateLimiter {
-    /**
-     * 闄愭祦key
-     */
-    String key() default Constants.RATE_LIMIT_KEY;
-
-    /**
-     * 闄愭祦鏃堕棿,鍗曚綅绉�
-     */
-    int time() default 60;
-
-    /**
-     * 闄愭祦娆℃暟
-     */
-    int count() default 100;
-
-    /**
-     * 闄愭祦绫诲瀷
-     */
-    LimitType limitType() default LimitType.DEFAULT;
-}
+package com.ruoyi.common.annotation;
+
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.enums.LimitType;
+
+import java.lang.annotation.*;
+
+/**
+ * 闄愭祦娉ㄨВ
+ *
+ * @author Lion Li
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RateLimiter {
+    /**
+     * 闄愭祦key
+     */
+    String key() default CacheConstants.RATE_LIMIT_KEY;
+
+    /**
+     * 闄愭祦鏃堕棿,鍗曚綅绉�
+     */
+    int time() default 60;
+
+    /**
+     * 闄愭祦娆℃暟
+     */
+    int count() default 100;
+
+    /**
+     * 闄愭祦绫诲瀷
+     */
+    LimitType limitType() default LimitType.DEFAULT;
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
new file mode 100644
index 0000000..478887d
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
@@ -0,0 +1,49 @@
+package com.ruoyi.common.constant;
+
+/**
+ * 缂撳瓨鐨刱ey 甯搁噺
+ *
+ * @author ruoyi
+ */
+public interface CacheConstants {
+
+    /**
+     * 鐧诲綍鐢ㄦ埛 redis key
+     */
+    String LOGIN_TOKEN_KEY = "Authorization:login:token:";
+
+    /**
+     * 鍦ㄧ嚎鐢ㄦ埛 redis key
+     */
+    String ONLINE_TOKEN_KEY = "online_tokens:";
+
+    /**
+     * 鐧婚檰閿欒 redis key
+     */
+    String LOGIN_ERROR = "login_error:";
+
+    /**
+     * 楠岃瘉鐮� redis key
+     */
+    String CAPTCHA_CODE_KEY = "captcha_codes:";
+
+    /**
+     * 鍙傛暟绠$悊 cache key
+     */
+    String SYS_CONFIG_KEY = "sys_config:";
+
+    /**
+     * 瀛楀吀绠$悊 cache key
+     */
+    String SYS_DICT_KEY = "sys_dict:";
+
+    /**
+     * 闃查噸鎻愪氦 redis key
+     */
+    String REPEAT_SUBMIT_KEY = "repeat_submit:";
+
+    /**
+     * 闄愭祦 redis key
+     */
+    String RATE_LIMIT_KEY = "rate_limit:";
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index e2ffebd..8c3b13c 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -58,39 +58,9 @@
     String LOGIN_FAIL = "Error";
 
     /**
-     * 楠岃瘉鐮� redis key
-     */
-    String CAPTCHA_CODE_KEY = "captcha_codes:";
-
-    /**
-     * 鐧诲綍鐢ㄦ埛 redis key
-     */
-    String LOGIN_TOKEN_KEY = "Authorization:login:token:";
-
-    /**
-     * 鍦ㄧ嚎鐢ㄦ埛 redis key
-     */
-    String ONLINE_TOKEN_KEY = "online_tokens:";
-
-    /**
-     * 闃查噸鎻愪氦 redis key
-     */
-    String REPEAT_SUBMIT_KEY = "repeat_submit:";
-
-    /**
-     * 闄愭祦 redis key
-     */
-    String RATE_LIMIT_KEY = "rate_limit:";
-
-    /**
      * 楠岃瘉鐮佹湁鏁堟湡锛堝垎閽燂級
      */
     Integer CAPTCHA_EXPIRATION = 2;
-
-    /**
-     * 鐧婚檰閿欒 redis key
-     */
-    String LOGIN_ERROR = "login_error:";
 
     /**
      * 鐧诲綍閿欒娆℃暟
@@ -106,21 +76,6 @@
      * 浠ょ墝
      */
     String TOKEN = "token";
-
-    /**
-     * 浠ょ墝鍓嶇紑
-     */
-    String LOGIN_USER_KEY = "login_user_key";
-
-    /**
-     * 鍙傛暟绠$悊 cache key
-     */
-    String SYS_CONFIG_KEY = "sys_config:";
-
-    /**
-     * 瀛楀吀绠$悊 cache key
-     */
-    String SYS_DICT_KEY = "sys_dict:";
 
 }
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
index 84079c4..7012a01 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
@@ -3,6 +3,7 @@
 import cn.hutool.core.convert.Convert;
 import cn.hutool.extra.servlet.ServletUtil;
 import cn.hutool.http.HttpStatus;
+import com.ruoyi.common.constant.Constants;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.springframework.http.MediaType;
@@ -14,6 +15,9 @@
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 
 /**
@@ -139,4 +143,32 @@
         return getClientIP(getRequest());
     }
 
+    /**
+     * 鍐呭缂栫爜
+     *
+     * @param str 鍐呭
+     * @return 缂栫爜鍚庣殑鍐呭
+     */
+    public static String urlEncode(String str) {
+        try {
+            return URLEncoder.encode(str, Constants.UTF8);
+        } catch (UnsupportedEncodingException e) {
+            return StringUtils.EMPTY;
+        }
+    }
+
+    /**
+     * 鍐呭瑙g爜
+     *
+     * @param str 鍐呭
+     * @return 瑙g爜鍚庣殑鍐呭
+     */
+    public static String urlDecode(String str) {
+        try {
+            return URLDecoder.decode(str, Constants.UTF8);
+        } catch (UnsupportedEncodingException e) {
+            return StringUtils.EMPTY;
+        }
+    }
+
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
index b77acb4..66827cb 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RepeatSubmitAspect.java
@@ -4,7 +4,7 @@
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.crypto.SecureUtil;
 import com.ruoyi.common.annotation.RepeatSubmit;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.JsonUtils;
@@ -63,7 +63,7 @@
 
         submitKey = SecureUtil.md5(submitKey + ":" + nowParams);
         // 鍞竴鏍囪瘑锛堟寚瀹歬ey + url + 娑堟伅澶达級
-        String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + url + submitKey;
+        String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey;
         String key = RedisUtils.getCacheObject(cacheRepeatKey);
         if (key == null) {
             RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval));
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java
index dcb9b19..1e3c22c 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/listener/UserActionListener.java
@@ -5,7 +5,7 @@
 import cn.dev33.satoken.stp.SaLoginModel;
 import cn.hutool.http.useragent.UserAgent;
 import cn.hutool.http.useragent.UserAgentUtil;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.enums.UserType;
@@ -50,7 +50,7 @@
             dto.setTokenId(tokenValue);
             dto.setUserName(user.getUsername());
             dto.setDeptName(user.getDeptName());
-            RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
+            RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
             log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
         } else if (userType == UserType.APP_USER) {
             // app绔� 鑷鏍规嵁涓氬姟缂栧啓
@@ -62,7 +62,7 @@
      */
     @Override
     public void doLogout(String loginType, Object loginId, String tokenValue) {
-        RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue);
+        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
         log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
     }
 
@@ -71,7 +71,7 @@
      */
     @Override
     public void doKickout(String loginType, Object loginId, String tokenValue) {
-        RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue);
+        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
         log.info("user doLogoutByLoginId, userId:{}, token:{}", loginId, tokenValue);
     }
 
@@ -80,7 +80,7 @@
      */
     @Override
     public void doReplaced(String loginType, Object loginId, String tokenValue) {
-        RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue);
+        RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
         log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
     }
 
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java
new file mode 100644
index 0000000..632c71a
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java
@@ -0,0 +1,54 @@
+package com.ruoyi.system.domain;
+
+import com.ruoyi.common.utils.StringUtils;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 缂撳瓨淇℃伅
+ *
+ * @author Lion Li
+ */
+@Data
+@NoArgsConstructor
+@ApiModel("缂撳瓨淇℃伅")
+public class SysCache {
+
+    /**
+     * 缂撳瓨鍚嶇О
+     */
+    @ApiModelProperty(value = "缂撳瓨鍚嶇О")
+    private String cacheName = "";
+
+    /**
+     * 缂撳瓨閿悕
+     */
+    @ApiModelProperty(value = "缂撳瓨閿悕")
+    private String cacheKey = "";
+
+    /**
+     * 缂撳瓨鍐呭
+     */
+    @ApiModelProperty(value = "缂撳瓨鍐呭")
+    private String cacheValue = "";
+
+    /**
+     * 澶囨敞
+     */
+    @ApiModelProperty(value = "澶囨敞")
+    private String remark = "";
+
+    public SysCache(String cacheName, String remark) {
+        this.cacheName = cacheName;
+        this.remark = remark;
+    }
+
+    public SysCache(String cacheName, String cacheKey, String cacheValue) {
+        this.cacheName = StringUtils.replace(cacheName, ":", "");
+        this.cacheKey = StringUtils.replace(cacheKey, cacheName, "");
+        this.cacheValue = cacheValue;
+    }
+
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
index 540708f..5a43203 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java
@@ -5,6 +5,7 @@
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.dto.RoleDTO;
 import com.ruoyi.common.core.domain.entity.SysUser;
@@ -130,7 +131,7 @@
      * 鏍¢獙鐭俊楠岃瘉鐮�
      */
     private boolean validateSmsCode(String phonenumber, String smsCode, HttpServletRequest request) {
-        String code = RedisUtils.getCacheObject(Constants.CAPTCHA_CODE_KEY + phonenumber);
+        String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phonenumber);
         if (StringUtils.isBlank(code)) {
             asyncService.recordLogininfor(phonenumber, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"), request);
             throw new CaptchaExpireException();
@@ -146,7 +147,7 @@
      * @param uuid     鍞竴鏍囪瘑
      */
     public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) {
-        String verifyKey = Constants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
         String captcha = RedisUtils.getCacheObject(verifyKey);
         RedisUtils.deleteObject(verifyKey);
         if (captcha == null) {
@@ -242,7 +243,7 @@
      */
     private void checkLogin(LoginType loginType, String username, Supplier<Boolean> supplier) {
         HttpServletRequest request = ServletUtils.getRequest();
-        String errorKey = Constants.LOGIN_ERROR + username;
+        String errorKey = CacheConstants.LOGIN_ERROR + username;
         Integer errorLimitTime = Constants.LOGIN_ERROR_LIMIT_TIME;
         Integer setErrorNumber = Constants.LOGIN_ERROR_NUMBER;
         String loginFail = Constants.LOGIN_FAIL;
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java
index 8c7274e..cefe4f7 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysRegisterService.java
@@ -1,6 +1,7 @@
 package com.ruoyi.system.service;
 
 import cn.dev33.satoken.secure.BCrypt;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysUser;
@@ -72,7 +73,7 @@
      * @return 缁撴灉
      */
     public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) {
-        String verifyKey = Constants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
+        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
         String captcha = RedisUtils.getCacheObject(verifyKey);
         RedisUtils.deleteObject(verifyKey);
         if (captcha == null) {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
index 070d1da..ab6a826 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java
@@ -5,7 +5,7 @@
 import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.PageQuery;
 import com.ruoyi.common.core.page.TableDataInfo;
@@ -182,7 +182,7 @@
      */
     @Override
     public void clearConfigCache() {
-        Collection<String> keys = RedisUtils.keys(Constants.SYS_CONFIG_KEY + "*");
+        Collection<String> keys = RedisUtils.keys(CacheConstants.SYS_CONFIG_KEY + "*");
         RedisUtils.deleteObject(keys);
     }
 
@@ -234,6 +234,6 @@
      * @return 缂撳瓨閿甼ey
      */
     private String getCacheKey(String configKey) {
-        return Constants.SYS_CONFIG_KEY + configKey;
+        return CacheConstants.SYS_CONFIG_KEY + configKey;
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
index 03de7c5..71a8305 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
@@ -2,7 +2,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.domain.PageQuery;
 import com.ruoyi.common.core.domain.entity.SysDictData;
 import com.ruoyi.common.core.page.TableDataInfo;
@@ -133,6 +133,6 @@
      * @return 缂撳瓨閿甼ey
      */
     String getCacheKey(String configKey) {
-        return Constants.SYS_DICT_KEY + configKey;
+        return CacheConstants.SYS_DICT_KEY + configKey;
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
index 1877780..04e4f4e 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
@@ -5,7 +5,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.PageQuery;
 import com.ruoyi.common.core.domain.entity.SysDictData;
@@ -157,7 +157,7 @@
      */
     @Override
     public void clearDictCache() {
-        Collection<String> keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*");
+        Collection<String> keys = RedisUtils.keys(CacheConstants.SYS_DICT_KEY + "*");
         RedisUtils.deleteObject(keys);
     }
 
@@ -294,6 +294,6 @@
      * @return 缂撳瓨閿甼ey
      */
     String getCacheKey(String configKey) {
-        return Constants.SYS_DICT_KEY + configKey;
+        return CacheConstants.SYS_DICT_KEY + configKey;
     }
 }
diff --git a/ruoyi-ui/src/api/monitor/cache.js b/ruoyi-ui/src/api/monitor/cache.js
index 2ffaf7a..e1f2c87 100644
--- a/ruoyi-ui/src/api/monitor/cache.js
+++ b/ruoyi-ui/src/api/monitor/cache.js
@@ -7,3 +7,51 @@
     method: 'get'
   })
 }
+
+// 鏌ヨ缂撳瓨鍚嶇О鍒楄〃
+export function listCacheName() {
+  return request({
+    url: '/monitor/cache/getNames',
+    method: 'get'
+  })
+}
+
+// 鏌ヨ缂撳瓨閿悕鍒楄〃
+export function listCacheKey(cacheName) {
+  return request({
+    url: '/monitor/cache/getKeys/' + cacheName,
+    method: 'get'
+  })
+}
+
+// 鏌ヨ缂撳瓨鍐呭
+export function getCacheValue(cacheName, cacheKey) {
+  return request({
+    url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey,
+    method: 'get'
+  })
+}
+
+// 娓呯悊鎸囧畾鍚嶇О缂撳瓨
+export function clearCacheName(cacheName) {
+  return request({
+    url: '/monitor/cache/clearCacheName/' + cacheName,
+    method: 'delete'
+  })
+}
+
+// 娓呯悊鎸囧畾閿悕缂撳瓨
+export function clearCacheKey(cacheKey) {
+  return request({
+    url: '/monitor/cache/clearCacheKey/' + cacheKey,
+    method: 'delete'
+  })
+}
+
+// 娓呯悊鍏ㄩ儴缂撳瓨
+export function clearCacheAll() {
+  return request({
+    url: '/monitor/cache/clearCacheAll',
+    method: 'delete'
+  })
+}
diff --git a/ruoyi-ui/src/assets/icons/svg/redis-list.svg b/ruoyi-ui/src/assets/icons/svg/redis-list.svg
new file mode 100644
index 0000000..98a15b2
--- /dev/null
+++ b/ruoyi-ui/src/assets/icons/svg/redis-list.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1656035183065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3395" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff2?t=1630033759944") format("woff2"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.woff?t=1630033759944") format("woff"), url("//at.alicdn.com/t/font_1031158_u69w8yhxdu.ttf?t=1630033759944") format("truetype"); }
+</style></defs><path d="M958.88 730.06H65.12c-18.28 0-33.12-14.82-33.12-33.12V68.91c0-18.29 14.83-33.12 33.12-33.12h893.77c18.28 0 33.12 14.82 33.12 33.12v628.03c-0.01 18.3-14.84 33.12-33.13 33.12zM98.23 663.83h827.53v-561.8H98.23v561.8z" p-id="3396"></path><path d="M512 954.55c-18.28 0-33.12-14.82-33.12-33.12V733.92c0-18.29 14.83-33.12 33.12-33.12s33.12 14.82 33.12 33.12v187.51c0 18.3-14.84 33.12-33.12 33.12z" p-id="3397"></path><path d="M762.01 988.21H261.99c-18.28 0-33.12-14.82-33.12-33.12 0-18.29 14.83-33.12 33.12-33.12h500.03c18.28 0 33.12 14.82 33.12 33.12-0.01 18.29-14.84 33.12-33.13 33.12zM514.74 578.55c-21.63 0-43.31-3.87-64.21-11.65-45.95-17.13-82.49-51.13-102.86-95.74-5.07-11.08-0.19-24.19 10.89-29.26 11.08-5.09 24.19-0.18 29.26 10.91 15.5 33.88 43.25 59.7 78.14 72.71 34.93 12.99 72.79 11.64 106.66-3.85 33.22-15.17 58.8-42.26 72.03-76.3 4.42-11.37 17.21-17.01 28.57-12.58 11.36 4.42 16.99 17.22 12.57 28.58-17.42 44.82-51.1 80.5-94.82 100.47-24.34 11.12-50.25 16.71-76.23 16.71z" p-id="3398"></path><path d="M325.27 528.78c-1.66 0-3.34-0.18-5.02-0.57-11.88-2.77-19.28-14.63-16.49-26.51l18.84-81c1.34-5.82 5-10.84 10.13-13.92 5.09-3.09 11.3-3.96 17.03-2.41l80.51 21.43c11.79 3.14 18.8 15.23 15.67 27.02-3.15 11.79-15.42 18.75-27.02 15.65l-58.49-15.57-13.69 58.81c-2.37 10.2-11.45 17.07-21.47 17.07zM360.8 351.01c-2.65 0-5.37-0.49-8-1.51-11.36-4.41-16.99-17.21-12.59-28.57 17.4-44.79 51.06-80.47 94.8-100.48 92.15-42.06 201.25-1.39 243.31 90.68 5.07 11.08 0.19 24.19-10.89 29.26-11.13 5.07-24.19 0.17-29.26-10.91-31.97-69.91-114.9-100.82-184.79-68.86-33.22 15.19-58.8 42.28-71.99 76.29-3.41 8.74-11.75 14.1-20.59 14.1z" p-id="3399"></path><path d="M684.68 376.74c-1.47 0-2.95-0.15-4.42-0.44l-81.61-16.68c-11.94-2.45-19.64-14.11-17.21-26.06 2.44-11.96 14.1-19.64 26.04-17.22l59.29 12.12 10.23-59.5c2.05-12 13.52-20.19 25.48-18.01 12.03 2.06 20.09 13.48 18.02 25.5l-14.08 81.96a22.089 22.089 0 0 1-9.29 14.49c-3.7 2.51-8.03 3.84-12.45 3.84z" p-id="3400"></path></svg>
\ No newline at end of file
diff --git a/ruoyi-ui/src/views/monitor/cache/index.vue b/ruoyi-ui/src/views/monitor/cache/index.vue
index cafa28c..cfef20d 100644
--- a/ruoyi-ui/src/views/monitor/cache/index.vue
+++ b/ruoyi-ui/src/views/monitor/cache/index.vue
@@ -71,7 +71,7 @@
 import echarts from "echarts";
 
 export default {
-  name: "Server",
+  name: "Cache",
   data() {
     return {
       // 缁熻鍛戒护淇℃伅
@@ -79,8 +79,8 @@
       // 浣跨敤鍐呭瓨
       usedmemory: null,
       // cache淇℃伅
-      cache: [],
-    };
+      cache: []
+    }
   },
   created() {
     this.getList();
@@ -109,8 +109,8 @@
               data: response.data.commandStats,
               animationEasing: "cubicInOut",
               animationDuration: 1000,
-            },
-          ],
+            }
+          ]
         });
         this.usedmemory = echarts.init(this.$refs.usedmemory, "macarons");
         this.usedmemory.setOption({
@@ -130,17 +130,17 @@
                 {
                   value: parseFloat(this.cache.info.used_memory_human),
                   name: "鍐呭瓨娑堣��",
-                },
-              ],
-            },
-          ],
+                }
+              ]
+            }
+          ]
         });
       });
     },
     // 鎵撳紑鍔犺浇灞�
     openLoading() {
       this.$modal.loading("姝e湪鍔犺浇缂撳瓨鐩戞帶鏁版嵁锛岃绋嶅�欙紒");
-    },
-  },
+    }
+  }
 };
 </script>
diff --git a/ruoyi-ui/src/views/monitor/cache/list.vue b/ruoyi-ui/src/views/monitor/cache/list.vue
new file mode 100644
index 0000000..a1e7955
--- /dev/null
+++ b/ruoyi-ui/src/views/monitor/cache/list.vue
@@ -0,0 +1,241 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="10">
+      <el-col :span="8">
+        <el-card style="height: calc(100vh - 125px)">
+          <div slot="header">
+            <span>缂撳瓨鍒楄〃</span>
+            <el-button
+              style="float: right; padding: 3px 0"
+              type="text"
+              icon="el-icon-refresh-right"
+              @click="refreshCacheNames()"
+            ></el-button>
+          </div>
+          <el-table
+            v-loading="loading"
+            :data="cacheNames"
+            :height="tableHeight"
+            highlight-current-row
+            @row-click="getCacheKeys"
+            style="width: 100%"
+          >
+            <el-table-column
+              label="搴忓彿"
+              width="60"
+              type="index"
+            ></el-table-column>
+
+            <el-table-column
+              label="缂撳瓨鍚嶇О"
+              align="center"
+              prop="cacheName"
+              :show-overflow-tooltip="true"
+              :formatter="nameFormatter"
+            ></el-table-column>
+
+            <el-table-column
+              label="澶囨敞"
+              align="center"
+              prop="remark"
+              :show-overflow-tooltip="true"
+            />
+            <el-table-column
+              label="鎿嶄綔"
+              width="60"
+              align="center"
+              class-name="small-padding fixed-width"
+            >
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleClearCacheName(scope.row)"
+                ></el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card style="height: calc(100vh - 125px)">
+          <div slot="header">
+            <span>閿悕鍒楄〃</span>
+            <el-button
+              style="float: right; padding: 3px 0"
+              type="text"
+              icon="el-icon-refresh-right"
+              @click="refreshCacheKeys()"
+            ></el-button>
+          </div>
+          <el-table
+            v-loading="subLoading"
+            :data="cacheKeys"
+            :height="tableHeight"
+            highlight-current-row
+            @row-click="handleCacheValue"
+            style="width: 100%"
+          >
+            <el-table-column
+              label="搴忓彿"
+              width="60"
+              type="index"
+            ></el-table-column>
+            <el-table-column
+              label="缂撳瓨閿悕"
+              align="center"
+              :show-overflow-tooltip="true"
+              :formatter="keyFormatter"
+            >
+            </el-table-column>
+            <el-table-column
+              label="鎿嶄綔"
+              width="60"
+              align="center"
+              class-name="small-padding fixed-width"
+            >
+              <template slot-scope="scope">
+                <el-button
+                  size="mini"
+                  type="text"
+                  icon="el-icon-delete"
+                  @click="handleClearCacheKey(scope.row)"
+                ></el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+
+      <el-col :span="8">
+        <el-card :bordered="false" style="height: calc(100vh - 125px)">
+          <div slot="header">
+            <span>缂撳瓨鍐呭</span>
+            <el-button
+              style="float: right; padding: 3px 0"
+              type="text"
+              icon="el-icon-refresh-right"
+              @click="handleClearCacheAll()"
+              >娓呯悊鍏ㄩ儴</el-button
+            >
+          </div>
+          <el-form :model="cacheForm">
+            <el-row :gutter="32">
+              <el-col :offset="1" :span="22">
+                <el-form-item label="缂撳瓨鍚嶇О:" prop="cacheName">
+                  <el-input v-model="cacheForm.cacheName" :readOnly="true" />
+                </el-form-item>
+              </el-col>
+              <el-col :offset="1" :span="22">
+                <el-form-item label="缂撳瓨閿悕:" prop="cacheKey">
+                  <el-input v-model="cacheForm.cacheKey" :readOnly="true" />
+                </el-form-item>
+              </el-col>
+              <el-col :offset="1" :span="22">
+                <el-form-item label="缂撳瓨鍐呭:" prop="cacheValue">
+                  <el-input
+                    v-model="cacheForm.cacheValue"
+                    type="textarea"
+                    :rows="8"
+                    :readOnly="true"
+                  />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { listCacheName, listCacheKey, getCacheValue, clearCacheName, clearCacheKey, clearCacheAll } from "@/api/monitor/cache";
+
+export default {
+  name: "CacheList",
+  data() {
+    return {
+      cacheNames: [],
+      cacheKeys: [],
+      cacheForm: {},
+      loading: true,
+      subLoading: false,
+      nowCacheName: "",
+      tableHeight: window.innerHeight - 200
+    };
+  },
+  created() {
+    this.getCacheNames();
+  },
+  methods: {
+    /** 鏌ヨ缂撳瓨鍚嶇О鍒楄〃 */
+    getCacheNames() {
+      this.loading = true;
+      listCacheName().then(response => {
+        this.cacheNames = response.data;
+        this.loading = false;
+      });
+    },
+    /** 鍒锋柊缂撳瓨鍚嶇О鍒楄〃 */
+    refreshCacheNames() {
+      this.getCacheNames();
+      this.$modal.msgSuccess("鍒锋柊缂撳瓨鍒楄〃鎴愬姛");
+    },
+    /** 娓呯悊鎸囧畾鍚嶇О缂撳瓨 */
+    handleClearCacheName(row) {
+      clearCacheName(row.cacheName).then(response => {
+        this.$modal.msgSuccess("娓呯悊缂撳瓨鍚嶇О[" + this.nowCacheName + "]鎴愬姛");
+        this.getCacheKeys();
+      });
+    },
+    /** 鏌ヨ缂撳瓨閿悕鍒楄〃 */
+    getCacheKeys(row) {
+      const cacheName = row !== undefined ? row.cacheName : this.nowCacheName;
+      if (cacheName === "") {
+        return;
+      }
+      this.subLoading = true;
+      listCacheKey(cacheName).then(response => {
+        this.cacheKeys = response.data;
+        this.subLoading = false;
+        this.nowCacheName = cacheName;
+      });
+    },
+    /** 鍒锋柊缂撳瓨閿悕鍒楄〃 */
+    refreshCacheKeys() {
+      this.getCacheKeys();
+      this.$modal.msgSuccess("鍒锋柊閿悕鍒楄〃鎴愬姛");
+    },
+    /** 娓呯悊鎸囧畾閿悕缂撳瓨 */
+    handleClearCacheKey(cacheKey) {
+      clearCacheKey(cacheKey).then(response => {
+        this.$modal.msgSuccess("娓呯悊缂撳瓨閿悕[" + cacheKey + "]鎴愬姛");
+        this.getCacheKeys();
+      });
+    },
+    /** 鍒楄〃鍓嶇紑鍘婚櫎 */
+    nameFormatter(row) {
+      return row.cacheName.replace(":", "");
+    },
+    /** 閿悕鍓嶇紑鍘婚櫎 */
+    keyFormatter(cacheKey) {
+      return cacheKey.replace(this.nowCacheName, "");
+    },
+    /** 鏌ヨ缂撳瓨鍐呭璇︾粏 */
+    handleCacheValue(cacheKey) {
+      getCacheValue(this.nowCacheName, cacheKey).then(response => {
+        this.cacheForm = response.data;
+      });
+    },
+    /** 娓呯悊鍏ㄩ儴缂撳瓨 */
+    handleClearCacheAll() {
+      clearCacheAll().then(response => {
+        this.$modal.msgSuccess("娓呯悊鍏ㄩ儴缂撳瓨鎴愬姛");
+      });
+    }
+  },
+};
+</script>
diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue
index bdd0952..985781f 100644
--- a/ruoyi-ui/src/views/system/dict/data.vue
+++ b/ruoyi-ui/src/views/system/dict/data.vue
@@ -163,7 +163,7 @@
             <el-option
               v-for="item in listClassOptions"
               :key="item.value"
-              :label="item.label"
+              :label="item.label + '(' + item.value + ')'"
               :value="item.value"
             ></el-option>
           </el-select>
@@ -397,3 +397,4 @@
   }
 };
 </script>
+
diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js
index a96dff0..0921752 100644
--- a/ruoyi-ui/vue.config.js
+++ b/ruoyi-ui/vue.config.js
@@ -61,6 +61,7 @@
     plugins: [
       // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#浣跨敤gzip瑙e帇缂╅潤鎬佹枃浠�
       new CompressionPlugin({
+        cache: false,                   // 涓嶅惎鐢ㄦ枃浠剁紦瀛�
         test: /\.(js|css|html)?$/i,     // 鍘嬬缉鏂囦欢鏍煎紡
         filename: '[path].gz[query]',   // 鍘嬬缉鍚庣殑鏂囦欢鍚�
         algorithm: 'gzip',              // 浣跨敤gzip鍘嬬缉
diff --git a/script/sql/oracle/oracle_ry_vue_4.X.sql b/script/sql/oracle/oracle_ry_vue_4.X.sql
index eabf919..f53ca82 100644
--- a/script/sql/oracle/oracle_ry_vue_4.X.sql
+++ b/script/sql/oracle/oracle_ry_vue_4.X.sql
@@ -258,6 +258,7 @@
 insert into sys_menu values('108',  '鏃ュ織绠$悊', '1',   '9', 'log',        '',                         '', 1, 0, 'M', '0', '0', '',                        'log',           'admin', sysdate, '', null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛', '2',   '1', 'online',     'monitor/online/index',     '', 1, 0, 'C', '0', '0', 'monitor:online:list',     'online',        'admin', sysdate, '', null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
 insert into sys_menu values('111',  '鏁版嵁鐩戞帶', '2',   '3', 'druid',      'monitor/druid/index',      '', 1, 0, 'C', '0', '0', 'monitor:druid:list',      'druid',         'admin', sysdate, '', null, '鏁版嵁鐩戞帶鑿滃崟');
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', sysdate, '', null, '缂撳瓨鍒楄〃鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶', '2',   '5', 'cache',      'monitor/cache/index',      '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis',         'admin', sysdate, '', null, '缂撳瓨鐩戞帶鑿滃崟');
 insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓', '3',   '1', 'build',      'tool/build/index',         '', 1, 0, 'C', '0', '0', 'tool:build:list',         'build',         'admin', sysdate, '', null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚', '3',   '2', 'gen',        'tool/gen/index',           '', 1, 0, 'C', '0', '0', 'tool:gen:list',           'code',          'admin', sysdate, '', null, '浠g爜鐢熸垚鑿滃崟');
diff --git a/script/sql/postgres/postgres_ry_vue_4.X.sql b/script/sql/postgres/postgres_ry_vue_4.X.sql
index 316d3bb..ad49672 100644
--- a/script/sql/postgres/postgres_ry_vue_4.X.sql
+++ b/script/sql/postgres/postgres_ry_vue_4.X.sql
@@ -261,6 +261,7 @@
 insert into sys_menu values('108',  '鏃ュ織绠$悊', '1',   '9', 'log',        '',                         '', '1', '0', 'M', '0', '0', '',                        'log',           'admin', now(), '', null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛', '2',   '1', 'online',     'monitor/online/index',     '', '1', '0', 'C', '0', '0', 'monitor:online:list',     'online',        'admin', now(), '', null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
 insert into sys_menu values('111',  '鏁版嵁鐩戞帶', '2',   '3', 'druid',      'monitor/druid/index',      '', '1', '0', 'C', '0', '0', 'monitor:druid:list',      'druid',         'admin', now(), '', null, '鏁版嵁鐩戞帶鑿滃崟');
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', '1', '0', 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', now(), '', null, '缂撳瓨鍒楄〃鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶', '2',   '5', 'cache',      'monitor/cache/index',      '', '1', '0', 'C', '0', '0', 'monitor:cache:list',      'redis',         'admin', now(), '', null, '缂撳瓨鐩戞帶鑿滃崟');
 insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓', '3',   '1', 'build',      'tool/build/index',         '', '1', '0', 'C', '0', '0', 'tool:build:list',         'build',         'admin', now(), '', null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚', '3',   '2', 'gen',        'tool/gen/index',           '', '1', '0', 'C', '0', '0', 'tool:gen:list',           'code',          'admin', now(), '', null, '浠g爜鐢熸垚鑿滃崟');
diff --git a/script/sql/ry_vue_4.X.sql b/script/sql/ry_vue_4.X.sql
index 560f3fc..b10eacb 100644
--- a/script/sql/ry_vue_4.X.sql
+++ b/script/sql/ry_vue_4.X.sql
@@ -173,6 +173,7 @@
 insert into sys_menu values('108',  '鏃ュ織绠$悊', '1',   '9', 'log',        '',                         '', 1, 0, 'M', '0', '0', '',                        'log',           'admin', sysdate(), '', null, '鏃ュ織绠$悊鑿滃崟');
 insert into sys_menu values('109',  '鍦ㄧ嚎鐢ㄦ埛', '2',   '1', 'online',     'monitor/online/index',     '', 1, 0, 'C', '0', '0', 'monitor:online:list',     'online',        'admin', sysdate(), '', null, '鍦ㄧ嚎鐢ㄦ埛鑿滃崟');
 insert into sys_menu values('111',  '鏁版嵁鐩戞帶', '2',   '3', 'druid',      'monitor/druid/index',      '', 1, 0, 'C', '0', '0', 'monitor:druid:list',      'druid',         'admin', sysdate(), '', null, '鏁版嵁鐩戞帶鑿滃崟');
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', sysdate(), '', null, '缂撳瓨鍒楄〃鑿滃崟');
 insert into sys_menu values('113',  '缂撳瓨鐩戞帶', '2',   '5', 'cache',      'monitor/cache/index',      '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis',         'admin', sysdate(), '', null, '缂撳瓨鐩戞帶鑿滃崟');
 insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓', '3',   '1', 'build',      'tool/build/index',         '', 1, 0, 'C', '0', '0', 'tool:build:list',         'build',         'admin', sysdate(), '', null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚', '3',   '2', 'gen',        'tool/gen/index',           '', 1, 0, 'C', '0', '0', 'tool:gen:list',           'code',          'admin', sysdate(), '', null, '浠g爜鐢熸垚鑿滃崟');
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql
index 97b8be1..9d8e1ee 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_4.X.sql
@@ -1078,6 +1078,8 @@
 GO
 INSERT [sys_menu] ([menu_id], [menu_name], [parent_id], [order_num], [path], [component], [query_param], [is_frame], [is_cache], [menu_type], [visible], [status], [perms], [icon], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (111, N'鏁版嵁鐩戞帶', 2, 3, N'druid', N'monitor/druid/index', N'', 1, 0, N'C', N'0', N'0', N'monitor:druid:list', N'druid', N'admin', getdate(), N'', NULL, N'鏁版嵁鐩戞帶鑿滃崟')
 GO
+INSERT [sys_menu] ([menu_id], [menu_name], [parent_id], [order_num], [path], [component], [query_param], [is_frame], [is_cache], [menu_type], [visible], [status], [perms], [icon], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (112, N'缂撳瓨鍒楄〃', 2, 6, N'cacheList', N'monitor/cache/list', N'', 1, 0, N'C', N'0', N'0', N'monitor:cache:list', N'redis-list', N'admin', getdate(), N'', NULL, N'缂撳瓨鍒楄〃鑿滃崟')
+GO
 INSERT [sys_menu] ([menu_id], [menu_name], [parent_id], [order_num], [path], [component], [query_param], [is_frame], [is_cache], [menu_type], [visible], [status], [perms], [icon], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (113, N'缂撳瓨鐩戞帶', 2, 5, N'cache', N'monitor/cache/index', N'', 1, 0, N'C', N'0', N'0', N'monitor:cache:list', N'redis', N'admin', getdate(), N'', NULL, N'缂撳瓨鐩戞帶鑿滃崟')
 GO
 INSERT [sys_menu] ([menu_id], [menu_name], [parent_id], [order_num], [path], [component], [query_param], [is_frame], [is_cache], [menu_type], [visible], [status], [perms], [icon], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (114, N'琛ㄥ崟鏋勫缓', 3, 1, N'build', N'tool/build/index', N'', 1, 0, N'C', N'0', N'0', N'tool:build:list', N'build', N'admin', getdate(), N'', NULL, N'琛ㄥ崟鏋勫缓鑿滃崟')
diff --git a/script/sql/update/oracle/update-4.2-4.3.sql b/script/sql/update/oracle/update-4.2-4.3.sql
new file mode 100644
index 0000000..a995acc
--- /dev/null
+++ b/script/sql/update/oracle/update-4.2-4.3.sql
@@ -0,0 +1 @@
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', sysdate, '', null, '缂撳瓨鍒楄〃鑿滃崟');
diff --git a/script/sql/update/postgres/update-4.2-4.3.sql b/script/sql/update/postgres/update-4.2-4.3.sql
new file mode 100644
index 0000000..9a3c41b
--- /dev/null
+++ b/script/sql/update/postgres/update-4.2-4.3.sql
@@ -0,0 +1 @@
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', '1', '0', 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', now(), '', null, '缂撳瓨鍒楄〃鑿滃崟');
diff --git a/script/sql/update/sqlserver/update-4.1-4.2.sql b/script/sql/update/sqlserver/update-4.1-4.2.sql
index 9e217ec..fd42238 100644
--- a/script/sql/update/sqlserver/update-4.1-4.2.sql
+++ b/script/sql/update/sqlserver/update-4.1-4.2.sql
@@ -1,27 +1,2 @@
-ALTER TABLE [sys_oss_config] ADD [domain] nvarchar(255) DEFAULT '' NULL
-GO
-
-EXEC sp_addextendedproperty
-'MS_Description', N'鑷畾涔夊煙鍚�',
-'SCHEMA', N'dbo',
-'TABLE', N'sys_oss_config',
-'COLUMN', N'domain'
-GO
-
-UPDATE [sys_oss_config] SET [access_key] = N'ruoyi', [secret_key] = N'ruoyi123', [endpoint] = N'127.0.0.1:9000' WHERE [oss_config_id] = 1
-GO
-
-UPDATE [sys_oss_config] SET [endpoint] = N's3-cn-north-1.qiniucs.com' WHERE [oss_config_id] = 2
-GO
-
-UPDATE [sys_oss_config] SET [endpoint] = N'oss-cn-beijing.aliyuncs.com' WHERE [oss_config_id] = 3
-GO
-
-UPDATE [sys_oss_config] SET [endpoint] = N'cos.ap-beijing.myqcloud.com' WHERE [oss_config_id] = 4
-GO
-
-INSERT INTO [sys_oss_config] ([oss_config_id], [config_key], [access_key], [secret_key], [bucket_name], [prefix], [endpoint], [domain], [is_https], [region], [status], [ext1], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (N'5', N'image',  N'ruoyi', N'ruoyi123', N'ruoyi', N'image', N'127.0.0.1:9000', N'',N'N', N'', N'1', N'', N'admin', getdate(), N'admin', getdate(), NULL)
-GO
-
-ALTER TABLE [gen_table_column] ALTER COLUMN [table_id] bigint NULL
+INSERT [sys_menu] ([menu_id], [menu_name], [parent_id], [order_num], [path], [component], [query_param], [is_frame], [is_cache], [menu_type], [visible], [status], [perms], [icon], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (112, N'缂撳瓨鍒楄〃', 2, 6, N'cacheList', N'monitor/cache/list', N'', 1, 0, N'C', N'0', N'0', N'monitor:cache:list', N'redis-list', N'admin', getdate(), N'', NULL, N'缂撳瓨鍒楄〃鑿滃崟')
 GO
diff --git a/script/sql/update/sqlserver/update-4.2-4.3.sql b/script/sql/update/sqlserver/update-4.2-4.3.sql
new file mode 100644
index 0000000..9a3c41b
--- /dev/null
+++ b/script/sql/update/sqlserver/update-4.2-4.3.sql
@@ -0,0 +1 @@
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', '1', '0', 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', now(), '', null, '缂撳瓨鍒楄〃鑿滃崟');
diff --git a/script/sql/update/update-4.2-4.3.sql b/script/sql/update/update-4.2-4.3.sql
new file mode 100644
index 0000000..8486c38
--- /dev/null
+++ b/script/sql/update/update-4.2-4.3.sql
@@ -0,0 +1,2 @@
+insert into sys_menu values('112',  '缂撳瓨鍒楄〃', '2',   '6', 'cacheList',  'monitor/cache/list',       '', 1, 0, 'C', '0', '0', 'monitor:cache:list',      'redis-list',    'admin', sysdate(), '', null, '缂撳瓨鍒楄〃鑿滃崟');
+
diff --git a/sql/ry_20220613.sql b/sql/ry_20220613.sql
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/sql/ry_20220613.sql

--
Gitblit v1.9.3