mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
refactor: code optimization
This commit is contained in:
75
server/pkg/cache/cache.go
vendored
75
server/pkg/cache/cache.go
vendored
@@ -1,25 +1,72 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
"mayfly-go/pkg/utils/jsonx"
|
||||
"time"
|
||||
|
||||
"github.com/may-fly/cast"
|
||||
)
|
||||
|
||||
type Cache interface {
|
||||
// 添加缓存,如果缓存则返回错误
|
||||
Add(k string, v any) error
|
||||
// Set 设置缓存值
|
||||
// duration == -1 则为永久缓存
|
||||
Set(key string, value any, duration time.Duration) error
|
||||
|
||||
// 如果不存在则添加缓存值,否则直接返回
|
||||
AddIfAbsent(k string, v any)
|
||||
// Set2Str 将value转为字符串后设置缓存值
|
||||
Set2Str(key string, value any, duration time.Duration) error
|
||||
|
||||
// 如果存在则直接返回,否则调用getValue回调函数获取值并添加该缓存值
|
||||
// @return 缓存值
|
||||
ComputeIfAbsent(k string, getValueFunc func(string) (any, error)) (any, error)
|
||||
|
||||
// 获取缓存值,参数1为值,参数2->是否存在该缓存
|
||||
// Get 获取缓存值
|
||||
Get(k string) (any, bool)
|
||||
|
||||
// 缓存数量
|
||||
// GetJson 获取json缓存值,并将其解析到指定的结构体指针
|
||||
GetJson(k string, valPtr any) bool
|
||||
|
||||
// GetStr 获取字符串缓存值
|
||||
GetStr(k string) (string, bool)
|
||||
|
||||
// GetInt 获取int缓存值
|
||||
GetInt(k string) (int, bool)
|
||||
|
||||
// Delete 删除缓存
|
||||
Delete(key string) error
|
||||
|
||||
// DeleteByKeyPrefix 根据key前缀删除缓存
|
||||
DeleteByKeyPrefix(keyPrefix string) error
|
||||
|
||||
// Count 缓存数量
|
||||
Count() int
|
||||
|
||||
// 删除缓存
|
||||
Delete(k string)
|
||||
|
||||
// 清空所有缓存
|
||||
// Clear 清空所有缓存
|
||||
Clear()
|
||||
}
|
||||
|
||||
type defaultCache struct {
|
||||
c Cache // 具体的缓存实现, 用于实现一些接口的通用方法
|
||||
}
|
||||
|
||||
func (dc *defaultCache) Set2Str(key string, value any, duration time.Duration) error {
|
||||
return dc.c.Set(key, anyx.ToString(value), duration)
|
||||
}
|
||||
|
||||
func (dc *defaultCache) GetStr(k string) (string, bool) {
|
||||
if val, ok := dc.c.Get(k); ok {
|
||||
return cast.ToString(val), true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (dc *defaultCache) GetInt(k string) (int, bool) {
|
||||
if val, ok := dc.c.Get(k); ok {
|
||||
return cast.ToInt(val), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (dc *defaultCache) GetJson(k string, valPtr any) bool {
|
||||
if val, ok := dc.GetStr(k); ok {
|
||||
jsonx.To(val, valPtr)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
46
server/pkg/cache/global.go
vendored
Normal file
46
server/pkg/cache/global.go
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"mayfly-go/pkg/rediscli"
|
||||
"time"
|
||||
)
|
||||
|
||||
var c Cache = NewLocalCache()
|
||||
|
||||
// SetCache 设置全局缓存实现
|
||||
func SetCache(cache Cache) {
|
||||
c = cache
|
||||
}
|
||||
|
||||
func GetStr(key string) string {
|
||||
if val, ok := c.GetStr(key); ok {
|
||||
return val
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetInt(key string) int {
|
||||
if val, ok := c.GetInt(key); ok {
|
||||
return val
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Get 获取缓存值,并使用json反序列化。返回是否获取成功。若不存在或者解析失败,则返回false
|
||||
func Get[T any](key string, valPtr T) bool {
|
||||
return c.GetJson(key, valPtr)
|
||||
}
|
||||
|
||||
// Set 设置缓存值
|
||||
func Set(key string, value any, duration time.Duration) error {
|
||||
return c.Set2Str(key, value, duration)
|
||||
}
|
||||
|
||||
// 删除指定key
|
||||
func Del(key string) {
|
||||
c.Delete(key)
|
||||
}
|
||||
|
||||
func UseRedisCache() bool {
|
||||
return rediscli.GetCli() != nil
|
||||
}
|
||||
54
server/pkg/cache/local.go
vendored
Normal file
54
server/pkg/cache/local.go
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/may-fly/cast"
|
||||
)
|
||||
|
||||
type LocalCache struct {
|
||||
defaultCache
|
||||
|
||||
tm *TimedCache
|
||||
}
|
||||
|
||||
var _ (Cache) = (*LocalCache)(nil)
|
||||
|
||||
func NewLocalCache() *LocalCache {
|
||||
lc := &LocalCache{
|
||||
tm: NewTimedCache(time.Minute*time.Duration(5), 30*time.Second),
|
||||
}
|
||||
lc.c = lc
|
||||
return lc
|
||||
}
|
||||
|
||||
func (lc *LocalCache) Set(key string, value any, duration time.Duration) error {
|
||||
return lc.tm.Add(key, value, duration)
|
||||
}
|
||||
|
||||
func (lc *LocalCache) Get(k string) (any, bool) {
|
||||
return lc.tm.Get(k)
|
||||
}
|
||||
|
||||
func (lc *LocalCache) Delete(k string) error {
|
||||
lc.tm.Delete(k)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lc *LocalCache) DeleteByKeyPrefix(keyPrefix string) error {
|
||||
for key := range lc.tm.Items() {
|
||||
if strings.HasPrefix(cast.ToString(key), keyPrefix) {
|
||||
lc.tm.Delete(key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lc *LocalCache) Count() int {
|
||||
return lc.tm.Count()
|
||||
}
|
||||
|
||||
func (lc *LocalCache) Clear() {
|
||||
lc.tm.Clear()
|
||||
}
|
||||
66
server/pkg/cache/redis.go
vendored
Normal file
66
server/pkg/cache/redis.go
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
type RedisCache struct {
|
||||
defaultCache
|
||||
|
||||
redisCli *redis.Client
|
||||
}
|
||||
|
||||
var _ (Cache) = (*RedisCache)(nil)
|
||||
|
||||
func NewRedisCache(rc *redis.Client) *RedisCache {
|
||||
rcache := &RedisCache{
|
||||
redisCli: rc,
|
||||
}
|
||||
rcache.c = rcache
|
||||
return rcache
|
||||
}
|
||||
|
||||
var _ (Cache) = (*RedisCache)(nil)
|
||||
|
||||
func (rc *RedisCache) Set(key string, value any, duration time.Duration) error {
|
||||
if _, ok := value.(string); !ok {
|
||||
return errors.New("redis cache set err -> value must be string")
|
||||
}
|
||||
return rc.redisCli.Set(context.Background(), key, anyx.ToString(value), duration).Err()
|
||||
}
|
||||
|
||||
func (rc *RedisCache) Get(k string) (any, bool) {
|
||||
if val, err := rc.redisCli.Get(context.Background(), k).Result(); err != nil {
|
||||
return "", false
|
||||
} else {
|
||||
return val, true
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *RedisCache) Delete(k string) error {
|
||||
return rc.redisCli.Del(context.Background(), k).Err()
|
||||
}
|
||||
|
||||
func (rc *RedisCache) DeleteByKeyPrefix(keyPrefix string) error {
|
||||
res, err := rc.redisCli.Keys(context.TODO(), keyPrefix+"*").Result()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, key := range res {
|
||||
Del(key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rc *RedisCache) Count() int {
|
||||
return int(rc.redisCli.DBSize(context.Background()).Val())
|
||||
}
|
||||
|
||||
func (rc *RedisCache) Clear() {
|
||||
rc.redisCli.FlushDB(context.Background())
|
||||
}
|
||||
105
server/pkg/cache/str_cache.go
vendored
105
server/pkg/cache/str_cache.go
vendored
@@ -1,105 +0,0 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/rediscli"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/may-fly/cast"
|
||||
)
|
||||
|
||||
var tm *TimedCache
|
||||
|
||||
// 如果系统有设置redis信息,则从redis获取,否则本机内存获取
|
||||
func GetStr(key string) string {
|
||||
if !UseRedisCache() {
|
||||
checkCache()
|
||||
val, _ := tm.Get(key)
|
||||
if val == nil {
|
||||
return ""
|
||||
}
|
||||
return cast.ToString(val)
|
||||
}
|
||||
|
||||
if res, err := rediscli.Get(key); err == nil {
|
||||
return res
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetInt(key string) int {
|
||||
val := GetStr(key)
|
||||
if val == "" {
|
||||
return 0
|
||||
}
|
||||
return cast.ToInt(key)
|
||||
}
|
||||
|
||||
// Get 获取缓存值,并使用json反序列化。返回是否获取成功。若不存在或者解析失败,则返回false
|
||||
func Get[T any](key string, valPtr T) bool {
|
||||
strVal := GetStr(key)
|
||||
if strVal == "" {
|
||||
return false
|
||||
}
|
||||
if err := json.Unmarshal([]byte(strVal), valPtr); err != nil {
|
||||
logx.Errorf("json转换缓存中的值失败: %v", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// SetStr 如果系统有设置redis信息,则使用redis存,否则存于本机内存。duration == -1则为永久缓存
|
||||
func SetStr(key, value string, duration time.Duration) error {
|
||||
if !UseRedisCache() {
|
||||
checkCache()
|
||||
return tm.Add(key, value, duration)
|
||||
}
|
||||
return rediscli.Set(key, value, duration)
|
||||
}
|
||||
|
||||
// Set 如果系统有设置redis信息,则使用redis存,否则存于本机内存。duration == -1则为永久缓存
|
||||
func Set(key string, value any, duration time.Duration) error {
|
||||
strVal := anyx.ToString(value)
|
||||
if !UseRedisCache() {
|
||||
checkCache()
|
||||
return tm.Add(key, strVal, duration)
|
||||
}
|
||||
return rediscli.Set(key, strVal, duration)
|
||||
}
|
||||
|
||||
// 删除指定key
|
||||
func Del(key string) {
|
||||
if !UseRedisCache() {
|
||||
checkCache()
|
||||
tm.Delete(key)
|
||||
return
|
||||
}
|
||||
rediscli.Del(key)
|
||||
}
|
||||
|
||||
// DelByKeyPrefix 根据key前缀删除满足前缀的所有缓存
|
||||
func DelByKeyPrefix(keyPrefix string) error {
|
||||
if !UseRedisCache() {
|
||||
checkCache()
|
||||
for key := range tm.Items() {
|
||||
if strings.HasPrefix(cast.ToString(key), keyPrefix) {
|
||||
tm.Delete(key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return rediscli.DelByKeyPrefix(keyPrefix)
|
||||
}
|
||||
|
||||
func UseRedisCache() bool {
|
||||
return rediscli.GetCli() != nil
|
||||
}
|
||||
|
||||
func checkCache() {
|
||||
if tm == nil {
|
||||
tm = NewTimedCache(time.Minute*time.Duration(5), 30*time.Second)
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,6 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"mayfly-go/pkg/cache"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/model"
|
||||
"os"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
@@ -106,119 +102,6 @@ func RsaDecrypt(privateKeyStr string, data []byte) ([]byte, error) {
|
||||
return rsa.DecryptPKCS1v15(rand.Reader, priv, data)
|
||||
}
|
||||
|
||||
// 使用系统默认的私钥解密
|
||||
// @param base64 字符串是否使用base64编码
|
||||
func DefaultRsaDecrypt(data string, useBase64 bool) (string, error) {
|
||||
// 空字符串不解密
|
||||
if data == "" {
|
||||
return "", nil
|
||||
}
|
||||
if useBase64 {
|
||||
if decodeBase64, err := base64.StdEncoding.DecodeString(data); err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
data = string(decodeBase64)
|
||||
}
|
||||
}
|
||||
priKey, err := GetRsaPrivateKey()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
val, err := RsaDecrypt(priKey, []byte(data))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(val), nil
|
||||
}
|
||||
|
||||
const (
|
||||
// 公钥文件路径
|
||||
publicKeyFile = "./mayfly_rsa.pub"
|
||||
// 私钥文件路径
|
||||
privateKeyFile = "./mayfly_rsa"
|
||||
|
||||
publicKeyK = "mayfly:public-key"
|
||||
privateKeyK = "mayfly:private-key"
|
||||
)
|
||||
|
||||
// 获取系统的RSA公钥
|
||||
func GetRsaPublicKey() (string, error) {
|
||||
if cache.UseRedisCache() {
|
||||
publicKey := cache.GetStr(publicKeyK)
|
||||
if publicKey != "" {
|
||||
return publicKey, nil
|
||||
}
|
||||
} else {
|
||||
content, err := os.ReadFile(publicKeyFile)
|
||||
if err != nil {
|
||||
publicKey := cache.GetStr(publicKeyK)
|
||||
if publicKey != "" {
|
||||
return publicKey, nil
|
||||
}
|
||||
} else {
|
||||
return string(content), nil
|
||||
}
|
||||
}
|
||||
|
||||
_, pubKey, err := GenerateAndSaveRSAKey()
|
||||
return pubKey, err
|
||||
}
|
||||
|
||||
// 获取系统私钥
|
||||
func GetRsaPrivateKey() (string, error) {
|
||||
if cache.UseRedisCache() {
|
||||
priKey := cache.GetStr(privateKeyK)
|
||||
if priKey != "" {
|
||||
return priKey, nil
|
||||
}
|
||||
} else {
|
||||
content, err := os.ReadFile(privateKeyFile)
|
||||
if err != nil {
|
||||
priKey := cache.GetStr(privateKeyK)
|
||||
if priKey != "" {
|
||||
return priKey, nil
|
||||
}
|
||||
} else {
|
||||
return string(content), nil
|
||||
}
|
||||
}
|
||||
|
||||
priKey, _, err := GenerateAndSaveRSAKey()
|
||||
return priKey, err
|
||||
}
|
||||
|
||||
// 生成并保存rsa key,优先保存于磁盘,若磁盘保存失败,则保存至缓存
|
||||
//
|
||||
// 依次返回 privateKey, publicKey, error
|
||||
func GenerateAndSaveRSAKey() (string, string, error) {
|
||||
privateKey, publicKey, err := GenerateRSAKey(1024)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// 如果使用了redis缓存,则优先存入redis
|
||||
if cache.UseRedisCache() {
|
||||
logx.Debug("系统配置了redis, rsa存入redis")
|
||||
cache.SetStr(privateKeyK, privateKey, -1)
|
||||
cache.SetStr(publicKeyK, publicKey, -1)
|
||||
return privateKey, publicKey, nil
|
||||
}
|
||||
|
||||
err = os.WriteFile(privateKeyFile, []byte(privateKey), 0644)
|
||||
if err != nil {
|
||||
logx.ErrorTrace("RSA私钥写入磁盘文件失败, 使用缓存存储该私钥", err)
|
||||
cache.SetStr(privateKeyK, privateKey, -1)
|
||||
}
|
||||
|
||||
err = os.WriteFile(publicKeyFile, []byte(publicKey), 0644)
|
||||
if err != nil {
|
||||
logx.ErrorTrace("RSA公钥写入磁盘文件失败, 使用缓存存储该公钥", err)
|
||||
cache.SetStr(publicKeyK, publicKey, -1)
|
||||
}
|
||||
|
||||
return privateKey, publicKey, nil
|
||||
}
|
||||
|
||||
// AesEncrypt 加密
|
||||
func AesEncrypt(data []byte, key []byte) ([]byte, error) {
|
||||
//创建加密实例
|
||||
@@ -281,12 +164,6 @@ func AesDecryptBase64(data string, key []byte) ([]byte, error) {
|
||||
return AesDecrypt(dataByte, key)
|
||||
}
|
||||
|
||||
func AesDecryptByLa(data string, la *model.LoginAccount) (string, error) {
|
||||
key := []byte(la.GetAesKey())
|
||||
res, err := AesDecryptBase64(data, key)
|
||||
return string(res), err
|
||||
}
|
||||
|
||||
// pkcs7Padding 填充
|
||||
func pkcs7Padding(data []byte, blockSize int) []byte {
|
||||
//判断缺少几位长度。最少1,最多 blockSize
|
||||
|
||||
Reference in New Issue
Block a user