From 9d7e32fb073842eb9d346878b49ce5bacfa3b51c Mon Sep 17 00:00:00 2001 From: RuoYi <yzz_ivy@163.com> Date: 星期六, 25 六月 2022 09:39:39 +0800 Subject: [PATCH] 新增缓存列表菜单功能 --- ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java | 4 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 | 39 +++ ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java | 66 ++++++ ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java | 6 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java | 3 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java | 81 ++++++++ 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 | 4 sql/ry_20220625.sql | 8 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java | 5 ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java | 6 ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java | 32 --- ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CaptchaController.java | 5 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java | 3 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java | 16 18 files changed, 522 insertions(+), 69 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 955c784..e8800b9 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,12 +6,13 @@ import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; -import com.ruoyi.common.config.RuoYiConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.FastByteArrayOutputStream; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.google.code.kaptcha.Producer; +import com.ruoyi.common.config.RuoYiConfig; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.redis.RedisCache; @@ -54,7 +55,7 @@ // 保存验证码信息 String uuid = IdUtils.simpleUUID(); - String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; String capStr = null, code = null; BufferedImage image = null; 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 fa9c623..cbd2061 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,19 +1,25 @@ package com.ruoyi.web.controller.monitor; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.domain.SysCache; /** * 缓存监控 @@ -26,6 +32,16 @@ { @Autowired private RedisTemplate<String, String> redisTemplate; + + private final static List<SysCache> caches = new ArrayList<SysCache>(); + { + caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); + 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, "限流处理")); + } @PreAuthorize("@ss.hasPermi('monitor:cache:list')") @GetMapping() @@ -50,4 +66,54 @@ result.put("commandStats", pieList); return AjaxResult.success(result); } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getNames") + public AjaxResult cache() + { + return AjaxResult.success(caches); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getKeys/{cacheName}") + public AjaxResult getCacheKeys(@PathVariable String cacheName) + { + Set<String> cacheKyes = redisTemplate.keys(cacheName + "*"); + return AjaxResult.success(cacheKyes); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping("/getValue/{cacheName}/{cacheKey}") + public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) + { + String cacheValue = redisTemplate.opsForValue().get(cacheKey); + SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); + return AjaxResult.success(sysCache); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheName/{cacheName}") + public AjaxResult clearCacheName(@PathVariable String cacheName) + { + Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheKey/{cacheKey}") + public AjaxResult clearCacheKey(@PathVariable String cacheKey) + { + redisTemplate.delete(cacheKey); + return AjaxResult.success(); + } + + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @DeleteMapping("/clearCacheAll") + public AjaxResult clearCacheAll() + { + Collection<String> cacheKeys = redisTemplate.keys("*"); + redisTemplate.delete(cacheKeys); + return AjaxResult.success(); + } } 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 4ca306d..6c2b3be 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 @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; 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.AjaxResult; import com.ruoyi.common.core.domain.model.LoginUser; @@ -42,7 +42,7 @@ @GetMapping("/list") public TableDataInfo list(String ipaddr, String userName) { - Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*"); + Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>(); for (String key : keys) { @@ -86,7 +86,7 @@ @DeleteMapping("/{tokenId}") public AjaxResult forceLogout(@PathVariable String tokenId) { - redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); return AjaxResult.success(); } } 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 5642038..050ac2d 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 @@ -5,7 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.enums.LimitType; /** @@ -21,7 +21,7 @@ /** * 限流key */ - public String key() default Constants.RATE_LIMIT_KEY; + public String key() default CacheConstants.RATE_LIMIT_KEY; /** * 限流时间,单位秒 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..7ea15aa --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java @@ -0,0 +1,39 @@ +package com.ruoyi.common.constant; + +/** + * 缓存的key 常量 + * + * @author ruoyi + */ +public class CacheConstants +{ + /** + * 登录用户 redis key + */ + public static final String LOGIN_TOKEN_KEY = "login_tokens:"; + + /** + * 验证码 redis key + */ + public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; + + /** + * 参数管理 cache key + */ + public static final String SYS_CONFIG_KEY = "sys_config:"; + + /** + * 字典管理 cache key + */ + public static final String SYS_DICT_KEY = "sys_dict:"; + + /** + * 防重提交 redis key + */ + public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; + + /** + * 限流 redis key + */ + public static final 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 6deff23..2dbdbe6 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,27 +58,7 @@ * 登录失败 */ public static final String LOGIN_FAIL = "Error"; - - /** - * 验证码 redis key - */ - public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; - - /** - * 登录用户 redis key - */ - public static final String LOGIN_TOKEN_KEY = "login_tokens:"; - - /** - * 防重提交 redis key - */ - public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; - - /** - * 限流 redis key - */ - public static final String RATE_LIMIT_KEY = "rate_limit:"; - + /** * 验证码有效期(分钟) */ @@ -123,16 +103,6 @@ * 用户权限 */ public static final String JWT_AUTHORITIES = "authorities"; - - /** - * 参数管理 cache key - */ - public static final String SYS_CONFIG_KEY = "sys_config:"; - - /** - * 字典管理 cache key - */ - public static final String SYS_DICT_KEY = "sys_dict:"; /** * 资源映射路径 前缀 diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java index 5a8554b..39ad84a 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DictUtils.java @@ -3,7 +3,7 @@ import java.util.Collection; import java.util.List; import com.alibaba.fastjson2.JSONArray; -import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.spring.SpringUtils; @@ -169,7 +169,7 @@ */ public static void clearDictCache() { - Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(Constants.SYS_DICT_KEY + "*"); + Collection<String> keys = SpringUtils.getBean(RedisCache.class).keys(CacheConstants.SYS_DICT_KEY + "*"); SpringUtils.getBean(RedisCache.class).deleteObject(keys); } @@ -181,6 +181,6 @@ */ public static String getCacheKey(String configKey) { - return Constants.SYS_DICT_KEY + configKey; + return CacheConstants.SYS_DICT_KEY + configKey; } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java index 0c5a40d..316a370 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; import com.alibaba.fastjson2.JSON; import com.ruoyi.common.annotation.RepeatSubmit; -import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.filter.RepeatedlyRequestWrapper; import com.ruoyi.common.utils.StringUtils; @@ -63,7 +63,7 @@ String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); // 唯一标识(指定key + url + 消息头) - String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + url + submitKey; + String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); if (sessionObj != null) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 6f8b9aa..5776c52 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -7,6 +7,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; @@ -17,8 +18,8 @@ import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.MessageUtils; -import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.factory.AsyncFactory; @@ -103,7 +104,7 @@ */ public void validateCaptcha(String username, String code, String uuid) { - String verifyKey = Constants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); String captcha = redisCache.getCacheObject(verifyKey); redisCache.deleteObject(verifyKey); if (captcha == null) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java index c7de444..43b1ce3 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java @@ -2,6 +2,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +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; @@ -100,7 +101,7 @@ */ public void validateCaptcha(String username, String code, String uuid) { - String verifyKey = Constants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); + String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); String captcha = redisCache.getCacheObject(verifyKey); redisCache.deleteObject(verifyKey); if (captcha == null) diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java index 5b4c414..cadeb4e 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.redis.RedisCache; @@ -220,6 +221,6 @@ private String getTokenKey(String uuid) { - return Constants.LOGIN_TOKEN_KEY + uuid; + return CacheConstants.LOGIN_TOKEN_KEY + uuid; } } 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..2ee8212 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysCache.java @@ -0,0 +1,81 @@ +package com.ruoyi.system.domain; + +import com.ruoyi.common.utils.StringUtils; + +/** + * 缓存信息 + * + * @author ruoyi + */ +public class SysCache +{ + /** 缓存名称 */ + private String cacheName = ""; + + /** 缓存键名 */ + private String cacheKey = ""; + + /** 缓存内容 */ + private String cacheValue = ""; + + /** 备注 */ + private String remark = ""; + + public SysCache() + { + + } + + 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; + } + + public String getCacheName() + { + return cacheName; + } + + public void setCacheName(String cacheName) + { + this.cacheName = cacheName; + } + + public String getCacheKey() + { + return cacheKey; + } + + public void setCacheKey(String cacheKey) + { + this.cacheKey = cacheKey; + } + + public String getCacheValue() + { + return cacheValue; + } + + public void setCacheValue(String cacheValue) + { + this.cacheValue = cacheValue; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } +} 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 c258a48..1017d23 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 @@ -1,7 +1,12 @@ package com.ruoyi.system.service.impl; +import java.util.Collection; +import java.util.List; +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import com.ruoyi.common.annotation.DataSource; -import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.text.Convert; @@ -11,11 +16,6 @@ import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.mapper.SysConfigMapper; import com.ruoyi.system.service.ISysConfigService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; -import java.util.Collection; -import java.util.List; /** * 参数配置 服务层实现 @@ -181,7 +181,7 @@ @Override public void clearConfigCache() { - Collection<String> keys = redisCache.keys(Constants.SYS_CONFIG_KEY + "*"); + Collection<String> keys = redisCache.keys(CacheConstants.SYS_CONFIG_KEY + "*"); redisCache.deleteObject(keys); } @@ -221,6 +221,6 @@ */ private String getCacheKey(String configKey) { - return Constants.SYS_CONFIG_KEY + configKey; + return CacheConstants.SYS_CONFIG_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("正在加载缓存监控数据,请稍候!"); - }, - }, + } + } }; </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..4e52b31 --- /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="form"> + <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/sql/ry_20220613.sql b/sql/ry_20220625.sql similarity index 98% rename from sql/ry_20220613.sql rename to sql/ry_20220625.sql index 36ba936..e9e6580 100644 --- a/sql/ry_20220613.sql +++ b/sql/ry_20220625.sql @@ -176,9 +176,10 @@ 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', '4', 'server', 'monitor/server/index', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', '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', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); -insert into sys_menu values('116', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); +insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单'); +insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); +insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); +insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); -- 三级菜单 insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); @@ -308,6 +309,7 @@ insert into sys_role_menu values ('2', '114'); insert into sys_role_menu values ('2', '115'); insert into sys_role_menu values ('2', '116'); +insert into sys_role_menu values ('2', '117'); insert into sys_role_menu values ('2', '500'); insert into sys_role_menu values ('2', '501'); insert into sys_role_menu values ('2', '1000'); -- Gitblit v1.9.2