Files
be.ems/src/modules/monitor/controller/sys_cache.go
2025-06-07 16:32:04 +08:00

209 lines
6.6 KiB
Go

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))
}