diff --git a/app/admin/api/monitor/cache.go b/app/admin/api/monitor/cache.go index 57131464b4ed97e9683c6a42ce0e044703e5fad8..588bd2b0ccf2cd7aecb8cb990292ecde55aed295 100644 --- a/app/admin/api/monitor/cache.go +++ b/app/admin/api/monitor/cache.go @@ -3,13 +3,15 @@ package monitor import ( "github.com/gin-gonic/gin" "net/http" + "ruoyi-go/app/admin/model/constants" "ruoyi-go/app/admin/model/monitor" + "ruoyi-go/pkg/cache/redisCache" ) func CacheHandler(context *gin.Context) { var list []monitor.SysCache list = append(list, monitor.SysCache{ - CacheName: "login_tokens:", + CacheName: constants.LoginCacheKey, Remark: "用户信息", }) list = append(list, monitor.SysCache{ @@ -17,7 +19,7 @@ func CacheHandler(context *gin.Context) { Remark: "配置信息", }) list = append(list, monitor.SysCache{ - CacheName: "sys_dict:", + CacheName: constants.SysDictCacheKey, Remark: "数据字典", }) list = append(list, monitor.SysCache{ @@ -45,23 +47,34 @@ func CacheHandler(context *gin.Context) { func GetCacheKeysHandler(context *gin.Context) { cacheName := context.Param("cacheName") - var list = []string{ - "" + cacheName + ":123456", + keys, _, err := redisCache.NewRedisCache().Scan(0, cacheName+"*", constants.ScanCountMax) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "msg": err.Error(), + "code": http.StatusInternalServerError, + }) } context.JSON(http.StatusOK, gin.H{ "msg": "操作成功", "code": http.StatusOK, - "data": list, + "data": keys, }) } func GetCacheValueHandler(context *gin.Context) { cacheName := context.Param("cacheName") cacheKey := context.Param("cacheKey") + value, err := redisCache.NewRedisCache().Get(cacheKey) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "msg": err.Error(), + "code": http.StatusInternalServerError, + }) + } var cache = monitor.SysCache{ CacheName: cacheName, CacheKey: cacheKey, - CacheValue: "123456", + CacheValue: value, } context.JSON(http.StatusOK, gin.H{ "msg": "操作成功", @@ -71,7 +84,17 @@ func GetCacheValueHandler(context *gin.Context) { } func ClearCacheNameHandler(context *gin.Context) { - + cacheName := context.Param("cacheName") + keys, _, err := redisCache.NewRedisCache().Scan(0, cacheName+"*", constants.ScanCountMax) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "msg": err.Error(), + "code": http.StatusInternalServerError, + }) + } + for i := range keys { + redisCache.NewRedisCache().Del(keys[i]) + } context.JSON(http.StatusOK, gin.H{ "msg": "操作成功", "code": http.StatusOK, @@ -79,7 +102,15 @@ func ClearCacheNameHandler(context *gin.Context) { } func ClearCacheKeyHandler(context *gin.Context) { - + cacheKey := context.Param("cacheKey") + _, err := redisCache.NewRedisCache().Del(cacheKey) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "msg": err.Error(), + "code": http.StatusInternalServerError, + }) + return + } context.JSON(http.StatusOK, gin.H{ "msg": "操作成功", "code": http.StatusOK, @@ -87,7 +118,16 @@ func ClearCacheKeyHandler(context *gin.Context) { } func ClearCacheAllHandler(context *gin.Context) { - + keys, _, err := redisCache.NewRedisCache().Scan(0, "*", constants.ScanCountMax) + if err != nil { + context.JSON(http.StatusOK, gin.H{ + "msg": err.Error(), + "code": http.StatusInternalServerError, + }) + } + for i := range keys { + redisCache.NewRedisCache().Del(keys[i]) + } context.JSON(http.StatusOK, gin.H{ "msg": "操作成功", "code": http.StatusOK, diff --git a/app/admin/api/system/dictData.go b/app/admin/api/system/dictData.go index a572c950b413fa7049a032895a26c67bf923dd69..b64cfb4dcdeff4d134d4e93c580ec05c6f053e68 100644 --- a/app/admin/api/system/dictData.go +++ b/app/admin/api/system/dictData.go @@ -2,8 +2,10 @@ package system import ( "net/http" + "ruoyi-go/app/admin/model/cache" "ruoyi-go/app/admin/model/system" "ruoyi-go/app/admin/model/tools" + "ruoyi-go/utils" "ruoyi-go/utils/R" "strconv" "time" @@ -151,9 +153,13 @@ func GetDictCode(context *gin.Context) { }) } -func DictTypeHandler(context *gin.Context) { +func GetDictDataByDictType(context *gin.Context) { dictType := context.Param("dictType") - result := system.SelectDictDataByType(dictType) + result := cache.GetDictDataCacheByType(dictType) + if result == nil { + relResult := system.SelectDictDataByType(dictType) + result = relResult + } context.JSON(http.StatusOK, gin.H{ "msg": "操作成功", "code": http.StatusOK, @@ -173,10 +179,11 @@ func SaveDictData(context *gin.Context) { dictDataParam.CreateTime = time.Now() dictDataParam.UpdateTime = time.Now() result := system.SaveDictData(dictDataParam) + cache.RefreshDictDataCache(dictDataParam.DictType) context.JSON(http.StatusOK, result) } -func UpDictData(context *gin.Context) { +func UpdateDictData(context *gin.Context) { userId, _ := context.Get("userId") var dictDataParam system.SysDictData if err := context.ShouldBind(&dictDataParam); err != nil { @@ -187,16 +194,26 @@ func UpDictData(context *gin.Context) { dictDataParam.UpdateBy = user.UserName dictDataParam.UpdateTime = time.Now() result := system.EditDictData(dictDataParam) + cache.RefreshDictDataCache(dictDataParam.DictType) context.JSON(http.StatusOK, result) } func DeleteDictData(context *gin.Context) { var dictCodes = context.Param("dictCodes") + var dictTypes []string + for _, dictCode := range utils.SplitStr(dictCodes) { + oneRow := system.FindDictCodeById(dictCode) + dictTypes = append(dictTypes, oneRow.DictType) + } result := system.DeleteDictData(dictCodes) + //刷新缓存 + for _, dictType := range dictTypes { + cache.RefreshDictDataCache(dictType) + } context.JSON(http.StatusOK, result) } -// ListDictType --------------------------------------------- +// ListDictType 分页接口 func ListDictType(context *gin.Context) { pageNum, _ := strconv.Atoi(context.DefaultQuery("pageNum", "1")) pageSize, _ := strconv.Atoi(context.DefaultQuery("pageSize", "10")) @@ -320,28 +337,45 @@ func SaveType(context *gin.Context) { return } result := system.SaveType(dictTypeParam) + cache.RefreshDictDataCache(dictTypeParam.DictType) context.JSON(http.StatusOK, result) } -func UploadType(context *gin.Context) { +func UpdateType(context *gin.Context) { var dictTypeParam system.SysDictType if err := context.ShouldBind(&dictTypeParam); err != nil { context.JSON(http.StatusOK, R.ReturnFailMsg("参数不能为空")) return } - result := system.UploadType(dictTypeParam) + result := system.UpdateType(dictTypeParam) + cache.RefreshDictDataCache(dictTypeParam.DictType) context.JSON(http.StatusOK, result) } func DeleteDataType(context *gin.Context) { dictIds := context.Param("dictIds") + var dictTypes []string + for _, dictId := range utils.SplitStr(dictIds) { + dictById := system.FindTypeDictById(dictId) + dictTypes = append(dictTypes, dictById.DictType) + } result := system.DeleteDataType(dictIds) + for _, dictType := range dictTypes { + cache.DeleteDictDataCache(dictType) + } context.JSON(http.StatusOK, result) } func RefreshCache(context *gin.Context) { - result := system.RefreshCache() - context.JSON(http.StatusOK, result) + /*删除缓存*/ + err := cache.DeleteAllDictCache() + if err != nil { + context.JSON(http.StatusOK, R.ReturnFailMsg(err.Error())) + return + } + /*重新赋值初始化参数*/ + cache.InitDictCache() + context.JSON(http.StatusOK, R.ReturnSuccess("操作成功")) } func GetOptionSelect(context *gin.Context) { diff --git a/app/admin/api/system/user.go b/app/admin/api/system/user.go index 8c211b6c89d7d30b62d59335ec15e1b2f61d4e5d..aa6819ab8f64f7f622e64598606ba1b66c159aa3 100644 --- a/app/admin/api/system/user.go +++ b/app/admin/api/system/user.go @@ -1,14 +1,17 @@ package system import ( - "fmt" + "encoding/json" "github.com/gin-gonic/gin" + "github.com/google/uuid" "github.com/xuri/excelize/v2" "net/http" "ruoyi-go/app/admin/model/constants" "ruoyi-go/app/admin/model/monitor" "ruoyi-go/app/admin/model/system" "ruoyi-go/app/admin/model/tools" + "ruoyi-go/config" + "ruoyi-go/pkg/cache/redisCache" "ruoyi-go/pkg/mysql" "ruoyi-go/utils" "ruoyi-go/utils/R" @@ -24,41 +27,35 @@ func LoginHandler(context *gin.Context) { monitor.LoginInfoAdd(context, param, "登录失败,参数为空", false) context.JSON(http.StatusOK, R.ReturnFailMsg("参数不能为空")) return - } else { - var captchaEnabled = system.SelectCaptchaEnabled() - if captchaEnabled { - isVerify := utils.VerifyCaptcha(param.Uuid, param.Code) - if isVerify { - isExist := system.IsExistUser(param.UserName) - if isExist { - findUser(param, context) - } else { - monitor.LoginInfoAdd(context, param, "登录失败,用户不存在", false) - context.JSON(http.StatusOK, gin.H{ - "msg": "用户不存在", - "code": http.StatusInternalServerError, - }) - } - } else { - monitor.LoginInfoAdd(context, param, "登录失败,验证码错误", false) - context.JSON(http.StatusOK, gin.H{ - "msg": "请输入正确的验证码", - "code": http.StatusInternalServerError, - }) - } - } else { - isExist := system.IsExistUser(param.UserName) - if isExist { - findUser(param, context) - } else { - monitor.LoginInfoAdd(context, param, "登录失败,用户不存在", false) - context.JSON(http.StatusOK, gin.H{ - "msg": "用户不存在", - "code": http.StatusInternalServerError, - }) - } - } } + if !loginBeforeCheck(param, context) { + return + } + isExist := system.IsExistUser(param.UserName) + if !isExist { + monitor.LoginInfoAdd(context, param, "登录失败,用户不存在", false) + context.JSON(http.StatusOK, gin.H{ + "msg": "用户不存在", + "code": http.StatusInternalServerError, + }) + return + } + findUser(param, context) +} +func loginBeforeCheck(param system.LoginParam, context *gin.Context) bool { + var captchaEnabled = system.SelectCaptchaEnabled() + if !captchaEnabled { + return false + } + isVerify := utils.VerifyCaptcha(param.Uuid, param.Code) + monitor.LoginInfoAdd(context, param, "登录失败,验证码错误", false) + if !isVerify { + context.JSON(http.StatusOK, gin.H{ + "msg": "请输入正确的验证码", + "code": http.StatusInternalServerError, + }) + } + return isVerify } // 判断用户是否存在 返回bool类型 @@ -74,7 +71,21 @@ func findUser(param system.LoginParam, context *gin.Context) { } // 验证 密码是否正确 if utils.PasswordVerify(pass, user.Password) { - tokenString, err := jwt.CreateToken(user.UserName, user.UserId, user.DeptId) + newUUID, _ := uuid.NewUUID() + tokenString, err := jwt.CreateToken(user.UserName, user.UserId, user.DeptId, newUUID.String()) + if err != nil { + monitor.LoginInfoAdd(context, param, "登录失败,"+err.Error(), false) + context.JSON(http.StatusOK, R.ReturnFailMsg("登录失败")) + return + } + //写入缓存 + loginUser, _ := json.Marshal(&monitor.LoginUserCache{ + UserId: user.UserId, + UserName: user.UserName, + Uuid: newUUID.String(), + DeptId: user.DeptId, + }) + err = redisCache.NewRedisCache().Put(constants.LoginCacheKey+newUUID.String(), string(loginUser), time.Duration(config.Jwt.JwtTtl)*time.Second) if err != nil { monitor.LoginInfoAdd(context, param, "登录失败,"+err.Error(), false) context.JSON(http.StatusOK, R.ReturnFailMsg("登录失败")) @@ -128,12 +139,13 @@ func GetInfoHandler(context *gin.Context) { }) } func LogoutHandler(context *gin.Context) { - userId, _ := context.Get("userId") - if userId != nil { - var user = system.FindUserById(userId) - fmt.Println(user) - } // 开始删除缓存 + jwtUuid, err := jwt.GetJwtUuid(context) + if err != nil || len(jwtUuid) <= 0 { + context.JSON(http.StatusOK, R.ReturnSuccessMsg("退出成功")) + return + } + redisCache.NewRedisCache().Del(constants.LoginCacheKey + jwtUuid) context.JSON(http.StatusOK, R.ReturnSuccessMsg("退出成功")) } diff --git a/app/admin/model/cache/cache.go b/app/admin/model/cache/cache.go new file mode 100644 index 0000000000000000000000000000000000000000..cb388d750543e024d42f0a1813d9b76cfa7ef38a --- /dev/null +++ b/app/admin/model/cache/cache.go @@ -0,0 +1,5 @@ +package cache + +func InitCache() { + InitDictCache() +} diff --git a/app/admin/model/cache/dictDataCache.go b/app/admin/model/cache/dictDataCache.go new file mode 100644 index 0000000000000000000000000000000000000000..eba700b6b474fc4a0643afc37c5791c7e3330448 --- /dev/null +++ b/app/admin/model/cache/dictDataCache.go @@ -0,0 +1,74 @@ +package cache + +import ( + "encoding/json" + "ruoyi-go/app/admin/model/constants" + "ruoyi-go/app/admin/model/system" + "ruoyi-go/app/admin/model/tools" + "ruoyi-go/pkg/cache/redisCache" +) + +// InitDicCache 初始化数据字典到redis +func InitDictCache() { + var param = tools.SearchTableDataParam{ + Other: system.SysDictType{}, + } + var typeResult = system.SelectSysDictTypeList(param, false) + var dataParam = tools.SearchTableDataParam{ + Other: system.SysDictData{}, + } + dataResult := system.SelectDictDataList(dataParam, false) + dictMap := make(map[string][]system.SysDictData) + for _, dictData := range dataResult.Rows.([]system.SysDictData) { + dictMap[dictData.DictType] = append(dictMap[dictData.DictType], dictData) + } + for _, dictType := range typeResult.Rows.([]system.SysDictType) { + SetDictDataCache(dictType.DictType, dictMap[dictType.DictType]) + } + +} + +// RefreshDictDataCache 刷新某个字典类型的所有值 +func RefreshDictDataCache(dictType string) { + dataResult := system.SelectDictDataByType(dictType) + SetDictDataCache(dictType, dataResult) + +} + +// GetDictDataCacheByType 根据字典类型来获取字典数据 +func GetDictDataCacheByType(dictType string) []system.SysDictData { + dataJson, err := redisCache.NewRedisCache().Get(constants.SysDictCacheKey + dictType) + if err != nil { + return nil + } + var dictDataList []system.SysDictData + err = json.Unmarshal([]byte(dataJson), &dictDataList) + if err != nil || len(dictDataList) <= 0 { + return nil + } + return dictDataList +} + +// SetDictDataCache 设置字典类型 值 +func SetDictDataCache(dictType string, dictDataList []system.SysDictData) { + system.OrderByDictSortAsc(dictDataList) + dataBytes, _ := json.Marshal(dictDataList) + redisCache.NewRedisCache().Put(constants.SysDictCacheKey+dictType, string(dataBytes), -1) +} + +// DeleteDictDataCache 删除字典 +func DeleteDictDataCache(dictType string) { + redisCache.NewRedisCache().Del(constants.SysDictCacheKey + dictType) + +} + +func DeleteAllDictCache() error { + keys, _, err := redisCache.NewRedisCache().Scan(0, constants.SysDictCacheKey+"*", constants.ScanCountMax) + if err != nil { + return err + } + for _, key := range keys { + redisCache.NewRedisCache().Del(key) + } + return nil +} diff --git a/app/admin/model/constants/sys_constants.go b/app/admin/model/constants/sys_constants.go index 6aaba47103dbc28569296ba208faa6e8c160db91..60d0ed431ec51a0369f434de38a8ab15205f1701 100644 --- a/app/admin/model/constants/sys_constants.go +++ b/app/admin/model/constants/sys_constants.go @@ -14,3 +14,10 @@ const ( TimeFormat = "2006-01-02 15:04:05" DateFormat = "2006-01-02" ) + +const ( + LoginCacheKey = "login_tokens:" + CaptchaCodesKey = "captcha_codes:" + SysDictCacheKey = "sys_dict:" + ScanCountMax = 1000 +) diff --git a/app/admin/model/monitor/sysCache.go b/app/admin/model/monitor/sysCache.go index 91c61f52b8ae517a046f080eb394ae80153418f3..51176a161367c423259421979aa00938066be0f5 100644 --- a/app/admin/model/monitor/sysCache.go +++ b/app/admin/model/monitor/sysCache.go @@ -6,3 +6,11 @@ type SysCache struct { CacheValue string `json:"cacheValue,omitempty"` Remark string `json:"remark,omitempty"` } + +type LoginUserCache struct { + UserId int `json:"userId"` + UserName string `json:"userName"` + Uuid string `json:"uuid"` + DeptId int `json:"deptId"` + NickName string `json:"nickName"` +} diff --git a/app/admin/model/system/sysDictData.go b/app/admin/model/system/sysDictData.go index 07fc077a64ef7ec67a1717999ff8a9f3b89ff2b6..deb8530910d0861c7c9c4eca70b2638840f9c984 100644 --- a/app/admin/model/system/sysDictData.go +++ b/app/admin/model/system/sysDictData.go @@ -6,6 +6,7 @@ import ( "ruoyi-go/pkg/mysql" "ruoyi-go/utils" "ruoyi-go/utils/R" + "sort" "time" ) @@ -27,6 +28,18 @@ type SysDictData struct { Remark string `json:"remark" gorm:"remark"` } +func OrderByDictSortAsc(dictDataList []SysDictData) { + sort.Sort(ByDictSort(dictDataList)) +} + +type ByDictSort []SysDictData + +func (d ByDictSort) Len() int { return len(d) } +func (d ByDictSort) Swap(i, j int) { d[i], d[j] = d[j], d[i] } + +// Less 正序 +func (d ByDictSort) Less(i, j int) bool { return d[i].DictSort < d[j].DictSort } + // TableName 指定数据库表名称 func (SysDictData) TableName() string { return "sys_dict_data" diff --git a/app/admin/model/system/sysDictType.go b/app/admin/model/system/sysDictType.go index 435a54b3b1d5519e4035b5e94d55bfbd2dc1e008..ba6ea20023be215a1b649312925eb28183e553c4 100644 --- a/app/admin/model/system/sysDictType.go +++ b/app/admin/model/system/sysDictType.go @@ -101,7 +101,7 @@ func SaveType(dictType SysDictType) R.Result { return R.ReturnSuccess("操作成功") } -func UploadType(dictType SysDictType) R.Result { +func UpdateType(dictType SysDictType) R.Result { err := mysql.MysqlDb().Updates(&dictType).Error if err != nil { return R.ReturnFailMsg(err.Error()) @@ -121,12 +121,6 @@ func DeleteDataType(dictIds string) R.Result { return R.ReturnSuccess("操作成功") } -func RefreshCache() R.Result { - /*删除缓存*/ - /*重新赋值初始化参数*/ - return R.ReturnSuccess("操作成功") -} - func GetOptionSelect() R.Result { var sysdictType []SysDictType err := mysql.MysqlDb().Find(&sysdictType).Error diff --git a/app/admin/model/system/sysRoles.go b/app/admin/model/system/sysRoles.go index 2141cee282f6ae25e1ea0dda12fb8234d9380d9d..9d4feecaca72214958fa6c5f8b645160ad27cc1b 100644 --- a/app/admin/model/system/sysRoles.go +++ b/app/admin/model/system/sysRoles.go @@ -376,6 +376,9 @@ func SaveRole(roles SysRolesParam) R.Result { func insertRoleMenu(roles SysRolesParam) { menuIds := roles.MenuIds + if menuIds == nil || len(menuIds) == 0 { + return + } var roleMenu []SysRoleMenu for i := 0; i < len(menuIds); i++ { menuId := menuIds[i] diff --git a/app/admin/router/system/dict.go b/app/admin/router/system/dict.go index a73f6b324a9861c2df3d050e2d25a5ed3709167f..217405b324bf3438cc26da026f4aab82efa814e2 100644 --- a/app/admin/router/system/dict.go +++ b/app/admin/router/system/dict.go @@ -17,18 +17,18 @@ func InitDict(e *gin.Engine) { auth.GET("/data/list", system.ListDict) auth.POST("/data/export", system.ExportDict) auth.GET("/data/:dictCode", system.GetDictCode) - auth.GET("/data/type/:dictType", system.DictTypeHandler) + auth.GET("/data/type/:dictType", system.GetDictDataByDictType) auth.POST("/data", system.SaveDictData) - auth.PUT("/data", system.UpDictData) + auth.PUT("/data", system.UpdateDictData) auth.DELETE("/data/:dictCodes", system.DeleteDictData) // 字典类型-字典管理 auth.GET("/type/list", system.ListDictType) auth.POST("/type/export", system.ExportType) auth.GET("/type/:dictId", system.GetTypeDict) auth.POST("/type", system.SaveType) - auth.PUT("/type", system.UploadType) + auth.PUT("/type", system.UpdateType) auth.DELETE("/type/:dictIds", system.DeleteDataType) - auth.DELETE("/refreshCache", system.RefreshCache) + auth.DELETE("/type/refreshCache", system.RefreshCache) auth.GET("/type/optionselect", system.GetOptionSelect) } } diff --git a/go.mod b/go.mod index 4d5cee24f5b84686afbf3aefdfd5eef1af065e2f..512b182da2cca7c55fbecbc02c61e283b08859c5 100644 --- a/go.mod +++ b/go.mod @@ -57,6 +57,7 @@ require ( github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/google/uuid v1.6.0 // indirect github.com/jellydator/ttlcache/v2 v2.11.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect diff --git a/go.sum b/go.sum index 7d76d94323c92d953cd7cce6732788c5c5122dba..ce032bf5e3cc4c474f83f59a714b64e328f2fa19 100644 --- a/go.sum +++ b/go.sum @@ -110,6 +110,8 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jellydator/ttlcache/v2 v2.11.1 h1:AZGME43Eh2Vv3giG6GeqeLeFXxwxn1/qHItqWZl6U64= diff --git a/main.go b/main.go index fde2c89ee6113c2942a3cba4ef11c25c51abc7de..b74cb9f2ea401d41084beda341cf81aaf20946c1 100644 --- a/main.go +++ b/main.go @@ -9,7 +9,7 @@ import ( "net/http" "os" "os/signal" - "runtime" + "ruoyi-go/app/admin/model/cache" "ruoyi-go/config" "ruoyi-go/pkg/logs" "ruoyi-go/pkg/scheduler" @@ -44,7 +44,8 @@ func main() { if config.XxlJob.Enabled { xxl_job_executor_gin.XxlJobMux(r, cron) } - + // 初始化缓存 + cache.InitCache() //打开浏览器 if runtime.GOOS == "windows" { utils.OpenWin("http://127.0.0.1:" + strconv.Itoa(config.Server.Port)) diff --git a/pkg/cache/redisCache/redisCache.go b/pkg/cache/redisCache/redisCache.go index 29287634243ff4e27335a3e9c24f27f46c3a8d82..cbbc72cac773ed3698a0935aa4828dd79324ac8e 100644 --- a/pkg/cache/redisCache/redisCache.go +++ b/pkg/cache/redisCache/redisCache.go @@ -21,6 +21,9 @@ func (r redisCache) Put(key string, value string, ttl time.Duration) error { func (r redisCache) Get(key string) (string, error) { return redis.Client().Get(context.TODO(), key).Result() } +func (r redisCache) Scan(cursor uint64, match string, count int64) (keys []string, c uint64, err error) { + return redis.Client().Scan(context.TODO(), cursor, match, count).Result() +} func (r redisCache) Del(key string) (string, error) { _, error := redis.Client().Del(context.TODO(), key).Result() diff --git a/pkg/redis/redis.go b/pkg/redis/redis.go index 2555e51959c27ba9854bc0213de6e2540e09058d..f4f95acb53554f3938ab27cf81bc54624fa648ff 100644 --- a/pkg/redis/redis.go +++ b/pkg/redis/redis.go @@ -23,8 +23,9 @@ func connectRedis() { defer cancel() conf := &redis.Options{ - Addr: config.Redis.Host + ":" + config.Redis.Port, - DB: 0, + Addr: config.Redis.Host + ":" + config.Redis.Port, + DB: config.Redis.DB, + Password: config.Redis.Password, } c := redis.NewClient(conf) diff --git a/utils/jwt/jwt.go b/utils/jwt/jwt.go index 2fb0c9901f977ddcd0ea2fa28296416a00f343b0..602c8ca1e9a4c600a8ba4a922a09ba70a3c3419f 100644 --- a/utils/jwt/jwt.go +++ b/utils/jwt/jwt.go @@ -4,18 +4,21 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt" "net/http" + "ruoyi-go/app/admin/model/constants" "ruoyi-go/config" + "ruoyi-go/pkg/cache/redisCache" "strings" "time" ) -func CreateToken(UserName string, UserId int, DeptId int) (string, error) { +func CreateToken(UserName string, UserId int, DeptId int, uuid string) (string, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "user_name": UserName, "user_id": UserId, "dept_id": DeptId, "exp": time.Now().Unix() + int64(config.Jwt.JwtTtl), "iss": "Ruoyi-Go", + "uuid": uuid, }) mySigningKey := []byte(config.Jwt.Secret) @@ -54,6 +57,16 @@ func JWTAuthMiddleware() func(ctx *gin.Context) { ctx.Abort() return } + uuid := token.Claims.(jwt.MapClaims)["uuid"] + loginUser, err := redisCache.NewRedisCache().Get(constants.LoginCacheKey + uuid.(string)) + if len(loginUser) <= 0 || err != nil { + ctx.JSON(http.StatusOK, gin.H{ + "msg": "认证失败", + "code": http.StatusUnauthorized, + }) + ctx.Abort() + return + } userId := token.Claims.(jwt.MapClaims)["user_id"] deptId := token.Claims.(jwt.MapClaims)["dept_id"] userName := token.Claims.(jwt.MapClaims)["user_name"] @@ -64,3 +77,17 @@ func JWTAuthMiddleware() func(ctx *gin.Context) { ctx.Next() } } + +func GetJwtUuid(ctx *gin.Context) (string, error) { + tokenStr := ctx.Request.Header.Get(config.HeaderSignToken) + if len(tokenStr) <= 0 { + return "", nil + } + token, err := VerifyToken(tokenStr) + if err != nil { + return "", err + } + uuid := token.Claims.(jwt.MapClaims)["uuid"] + return uuid.(string), nil + +}