package controller import ( "encoding/json" "fmt" "be.ems/src/framework/constants" "be.ems/src/framework/database/redis" "be.ems/src/framework/i18n" "be.ems/src/framework/reqctx" "be.ems/src/framework/resp" "be.ems/src/modules/monitor/model" "github.com/gin-gonic/gin" ) // 实例化控制层 SysCacheController 结构体 var NewSysCache = &SysCacheController{} // 缓存监控信息 // // PATH /monitor/cache type SysCacheController struct{} // Redis信息 // // GET / // // @Tags monitor/cache // @Accept json // @Produce json // @Success 200 {object} object "Response Results" // @Security TokenAuth // @Summary Cache Service Information // @Description Cache Service Information // @Router /monitor/cache [get] func (s *SysCacheController) Info(c *gin.Context) { c.JSON(200, resp.OkData(map[string]any{ "info": redis.Info(""), "dbSize": redis.KeySize(""), "commandStats": redis.CommandStats(""), })) } // Names 缓存名称列表 // // GET /names func (s SysCacheController) Names(c *gin.Context) { language := reqctx.AcceptLanguage(c) caches := []model.SysCache{ model.NewNames(i18n.TKey(language, "cache.name.token"), constants.CACHE_TOKEN_DEVICE), model.NewNames(i18n.TKey(language, "cache.name.sys_config"), constants.CACHE_SYS_CONFIG), model.NewNames(i18n.TKey(language, "cache.name.sys_dict"), constants.CACHE_SYS_DICT), model.NewNames(i18n.TKey(language, "cache.name.captcha_codes"), constants.CACHE_CAPTCHA_CODE), model.NewNames(i18n.TKey(language, "cache.name.repeat_submit"), constants.CACHE_REPEAT_SUBMIT), model.NewNames(i18n.TKey(language, "cache.name.rate_limit"), constants.CACHE_RATE_LIMIT), model.NewNames(i18n.TKey(language, "cache.name.pwd_err_cnt"), constants.CACHE_PWD_ERR_COUNT), model.NewNames(i18n.TKey(language, "cache.name.oauth2_codes"), constants.CACHE_OAUTH2_CODE), model.NewNames(i18n.TKey(language, "cache.name.oauth2_devices"), constants.CACHE_OAUTH2_DEVICE), model.NewNames(i18n.TKey(language, "cache.name.i18n"), constants.CACHE_I18N), model.NewNames(i18n.TKey(language, "cache.name.ne_info"), constants.CACHE_NE_INFO), model.NewNames(i18n.TKey(language, "cache.name.ne_data"), constants.CACHE_NE_DATA), } c.JSON(200, resp.OkData(caches)) } // Keys 缓存名称下键名列表 // // GET /keys?cacheName=xxx func (s SysCacheController) Keys(c *gin.Context) { var query struct { CacheName string `form:"cacheName" binding:"required"` // 键名列表中得到的缓存名称 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } caches := []model.SysCache{} cacheKeys, _ := redis.GetKeys("", query.CacheName+":*") for _, key := range cacheKeys { caches = append(caches, model.NewKeys(query.CacheName, key)) } c.JSON(200, resp.OkData(caches)) } // Value 缓存内容信息 // // GET /value?cacheName=xxx&cacheKey=xxx func (s SysCacheController) Value(c *gin.Context) { var query struct { CacheName string `form:"cacheName" binding:"required"` // 键名列表中得到的缓存名称 CacheKey string `form:"cacheKey" binding:"required"` // 键名列表中得到的缓存键名 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } key := query.CacheName + ":" + query.CacheKey var cacheValue string var err error if constants.CACHE_I18N == query.CacheName { // i18n 多语言的hash对象 m, err := redis.GetHashBatch("", []string{key}) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } b, err := json.Marshal(m[key]) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } cacheValue = string(b) } else { // 其他的字符串对象 cacheValue, err = redis.Get("", query.CacheName+":"+query.CacheKey) if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } } sysCache := model.NewValue(query.CacheName, query.CacheKey, cacheValue) c.JSON(200, resp.OkData(sysCache)) } // CleanNames 缓存名称列表安全删除 // // DELETE /names func (s SysCacheController) CleanNames(c *gin.Context) { language := reqctx.AcceptLanguage(c) caches := []model.SysCache{ model.NewNames(i18n.TKey(language, "cache.name.sys_config"), constants.CACHE_SYS_CONFIG), model.NewNames(i18n.TKey(language, "cache.name.sys_dict"), constants.CACHE_SYS_DICT), model.NewNames(i18n.TKey(language, "cache.name.repeat_submit"), constants.CACHE_REPEAT_SUBMIT), model.NewNames(i18n.TKey(language, "cache.name.rate_limit"), constants.CACHE_RATE_LIMIT), model.NewNames(i18n.TKey(language, "cache.name.pwd_err_cnt"), constants.CACHE_PWD_ERR_COUNT), model.NewNames(i18n.TKey(language, "cache.name.i18n"), constants.CACHE_I18N), model.NewNames(i18n.TKey(language, "cache.name.ne_info"), constants.CACHE_NE_INFO), model.NewNames(i18n.TKey(language, "cache.name.ne_data"), constants.CACHE_NE_DATA), } for _, v := range caches { cacheKeys, err := redis.GetKeys("", v.CacheName+":*") if err != nil { continue } _ = redis.DelKeys("", cacheKeys) } c.JSON(200, resp.Ok(nil)) } // CleanKeys 缓存名称下键名删除 // // DELETE /keys?cacheName=xxx func (s SysCacheController) CleanKeys(c *gin.Context) { var query struct { CacheName string `form:"cacheName" binding:"required"` // 键名列表中得到的缓存名称 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } if constants.CACHE_TOKEN_DEVICE == query.CacheName { c.JSON(200, resp.ErrMsg("Cannot delete user information cache")) return } cacheKeys, err := redis.GetKeys("", query.CacheName+":*") if err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } if err = redis.DelKeys("", cacheKeys); err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } c.JSON(200, resp.Ok(nil)) } // CleanValue 缓存内容删除 // // DELETE /value?cacheName=xxx&cacheKey=xxx func (s SysCacheController) CleanValue(c *gin.Context) { var query struct { CacheName string `form:"cacheName" binding:"required"` // 键名列表中得到的缓存名称 CacheKey string `form:"cacheKey" binding:"required"` // 键名列表中得到的缓存键名 } if err := c.ShouldBindQuery(&query); err != nil { errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err)) c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs)) return } if err := redis.Del("", query.CacheName+":"+query.CacheKey); err != nil { c.JSON(200, resp.ErrMsg(err.Error())) return } c.JSON(200, resp.Ok(nil)) }