mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
feat: redis支持zset、redis数据操作界面优化
This commit is contained in:
@@ -14,7 +14,7 @@ func InitCommonRouter(router *gin.RouterGroup) {
|
||||
// 获取公钥
|
||||
common.GET("public-key", func(g *gin.Context) {
|
||||
req.NewCtxWithGin(g).
|
||||
WithNeedToken(false).
|
||||
DontNeedToken().
|
||||
Handle(c.RasPublicKey)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,6 +13,16 @@ type Redis struct {
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type Rename struct {
|
||||
Key string `binding:"required" json:"key"`
|
||||
NewKey string `binding:"required" json:"newKey"`
|
||||
}
|
||||
|
||||
type Expire struct {
|
||||
Key string `binding:"required" json:"key"`
|
||||
Seconds int64 `binding:"required" json:"seconds"`
|
||||
}
|
||||
|
||||
type KeyInfo struct {
|
||||
Key string `binding:"required" json:"key"`
|
||||
Timed int64
|
||||
@@ -50,3 +60,27 @@ type RedisScanForm struct {
|
||||
Match string `json:"match"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
type ScanForm struct {
|
||||
Key string `json:"key"`
|
||||
Cursor uint64 `json:"cursor"`
|
||||
Match string `json:"match"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
type SmemberOption struct {
|
||||
Key string `json:"key"`
|
||||
Member any `json:"member"`
|
||||
}
|
||||
|
||||
type LRemOption struct {
|
||||
Key string `json:"key"`
|
||||
Count int64 `json:"count"`
|
||||
Member any `json:"member"`
|
||||
}
|
||||
|
||||
type ZAddOption struct {
|
||||
Key string `json:"key"`
|
||||
Score float64 `json:"score"`
|
||||
Member any `json:"member"`
|
||||
}
|
||||
|
||||
79
server/internal/redis/api/hash.go
Normal file
79
server/internal/redis/api/hash.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (r *Redis) Hscan(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
g := rc.GinCtx
|
||||
count := ginx.QueryInt(g, "count", 10)
|
||||
match := g.Query("match")
|
||||
cursor := ginx.QueryInt(g, "cursor", 0)
|
||||
contextTodo := context.TODO()
|
||||
|
||||
cmdable := ri.GetCmdable()
|
||||
keys, nextCursor, err := cmdable.HScan(contextTodo, key, uint64(cursor), match, int64(count)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hcan err: %s")
|
||||
keySize, err := cmdable.HLen(contextTodo, key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hlen err: %s")
|
||||
|
||||
rc.ResData = map[string]interface{}{
|
||||
"keys": keys,
|
||||
"cursor": nextCursor,
|
||||
"keySize": keySize,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) Hdel(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
field := rc.GinCtx.Query("field")
|
||||
|
||||
delRes, err := ri.GetCmdable().HDel(context.TODO(), key, field).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hdel err: %s")
|
||||
rc.ResData = delRes
|
||||
}
|
||||
|
||||
func (r *Redis) Hget(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
field := rc.GinCtx.Query("field")
|
||||
|
||||
res, err := ri.GetCmdable().HGet(context.TODO(), key, field).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hget err: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) Hset(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
hashValue := new(form.HashValue)
|
||||
ginx.BindJsonAndValid(g, hashValue)
|
||||
|
||||
hv := hashValue.Value[0]
|
||||
res, err := r.getRedisIns(rc).GetCmdable().HSet(context.TODO(), hashValue.Key, hv["field"].(string), hv["value"]).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hset失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) SetHashValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
hashValue := new(form.HashValue)
|
||||
ginx.BindJsonAndValid(g, hashValue)
|
||||
|
||||
ri := r.getRedisIns(rc)
|
||||
cmd := ri.GetCmdable()
|
||||
|
||||
key := hashValue.Key
|
||||
contextTodo := context.TODO()
|
||||
for _, v := range hashValue.Value {
|
||||
res := cmd.HSet(contextTodo, key, v["field"].(string), v["value"])
|
||||
biz.ErrIsNilAppendErr(res.Err(), "保存hash值失败: %s")
|
||||
}
|
||||
if hashValue.Timed != 0 && hashValue.Timed != -1 {
|
||||
cmd.Expire(context.TODO(), key, time.Second*time.Duration(hashValue.Timed))
|
||||
}
|
||||
}
|
||||
189
server/internal/redis/api/key.go
Normal file
189
server/internal/redis/api/key.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/internal/redis/api/vo"
|
||||
"mayfly-go/internal/redis/domain/entity"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
// scan获取redis的key列表信息
|
||||
func (r *Redis) Scan(rc *req.Ctx) {
|
||||
ri := r.getRedisIns(rc)
|
||||
|
||||
form := &form.RedisScanForm{}
|
||||
ginx.BindJsonAndValid(rc.GinCtx, form)
|
||||
|
||||
cmd := ri.GetCmdable()
|
||||
ctx := context.Background()
|
||||
|
||||
kis := make([]*vo.KeyInfo, 0)
|
||||
var cursorRes map[string]uint64 = make(map[string]uint64)
|
||||
|
||||
mode := ri.Info.Mode
|
||||
if mode == "" || mode == entity.RedisModeStandalone || mode == entity.RedisModeSentinel {
|
||||
redisAddr := ri.Cli.Options().Addr
|
||||
// 汇总所有的查询出来的键值
|
||||
var keys []string
|
||||
// 有通配符或空时使用scan,非模糊匹配直接匹配key
|
||||
if form.Match == "" || strings.ContainsAny(form.Match, "*") {
|
||||
cursorRes[redisAddr] = form.Cursor[redisAddr]
|
||||
for {
|
||||
ks, cursor := ri.Scan(cursorRes[redisAddr], form.Match, form.Count)
|
||||
cursorRes[redisAddr] = cursor
|
||||
if len(ks) > 0 {
|
||||
// 返回了数据则追加总集合中
|
||||
keys = append(keys, ks...)
|
||||
}
|
||||
// 匹配的数量满足用户需求退出
|
||||
if int32(len(keys)) >= int32(form.Count) {
|
||||
break
|
||||
}
|
||||
// 匹配到最后退出
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 精确匹配
|
||||
keys = append(keys, form.Match)
|
||||
}
|
||||
|
||||
var keyInfoSplit []string
|
||||
if len(keys) > 0 {
|
||||
keyInfosLua := `local result = {}
|
||||
-- KEYS[1]为第1个参数,lua数组下标从1开始
|
||||
for i = 1, #KEYS do
|
||||
local ttl = redis.call('ttl', KEYS[i]);
|
||||
local keyType = redis.call('type', KEYS[i]);
|
||||
table.insert(result, string.format("%d,%s", ttl, keyType['ok']));
|
||||
end;
|
||||
return table.concat(result, ".");`
|
||||
// 通过lua获取 ttl,type.ttl2,type2格式,以便下面切割获取ttl和type。避免多次调用ttl和type函数
|
||||
keyInfos, err := cmd.Eval(ctx, keyInfosLua, keys).Result()
|
||||
biz.ErrIsNilAppendErr(err, "执行lua脚本获取key信息失败: %s")
|
||||
keyInfoSplit = strings.Split(keyInfos.(string), ".")
|
||||
}
|
||||
|
||||
for i, k := range keys {
|
||||
ttlType := strings.Split(keyInfoSplit[i], ",")
|
||||
ttl, _ := strconv.Atoi(ttlType[0])
|
||||
// 没有存在该key,则跳过
|
||||
if ttl == -2 {
|
||||
continue
|
||||
}
|
||||
ki := &vo.KeyInfo{Key: k, Type: ttlType[1], Ttl: int64(ttl)}
|
||||
kis = append(kis, ki)
|
||||
}
|
||||
} else if mode == entity.RedisModeCluster {
|
||||
var keys []string
|
||||
// 有通配符或空时使用scan,非模糊匹配直接匹配key
|
||||
if form.Match == "" || strings.ContainsAny(form.Match, "*") {
|
||||
mu := &sync.Mutex{}
|
||||
// 遍历所有master节点,并执行scan命令,合并keys
|
||||
ri.ClusterCli.ForEachMaster(ctx, func(ctx context.Context, client *redis.Client) error {
|
||||
redisAddr := client.Options().Addr
|
||||
nowCursor := form.Cursor[redisAddr]
|
||||
for {
|
||||
ks, cursor, _ := client.Scan(ctx, nowCursor, form.Match, form.Count).Result()
|
||||
// 遍历节点的内部回调函数使用异步调用,如不加锁会导致集合并发错误
|
||||
mu.Lock()
|
||||
cursorRes[redisAddr] = cursor
|
||||
nowCursor = cursor
|
||||
if len(ks) > 0 {
|
||||
// 返回了数据则追加总集合中
|
||||
keys = append(keys, ks...)
|
||||
}
|
||||
mu.Unlock()
|
||||
// 匹配的数量满足用户需求退出
|
||||
if int32(len(keys)) >= int32(form.Count) {
|
||||
break
|
||||
}
|
||||
// 匹配到最后退出
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
} else {
|
||||
// 精确匹配
|
||||
keys = append(keys, form.Match)
|
||||
}
|
||||
|
||||
// 因为redis集群模式执行lua脚本key必须位于同一slot中,故单机获取的方式不适合
|
||||
// 使用lua获取key的ttl以及类型,减少网络调用
|
||||
keyInfoLua := `local ttl = redis.call('ttl', KEYS[1]);
|
||||
local keyType = redis.call('type', KEYS[1]);
|
||||
return string.format("%d,%s", ttl, keyType['ok'])`
|
||||
for _, k := range keys {
|
||||
keyInfo, err := cmd.Eval(ctx, keyInfoLua, []string{k}).Result()
|
||||
biz.ErrIsNilAppendErr(err, "执行lua脚本获取key信息失败: %s")
|
||||
ttlType := strings.Split(keyInfo.(string), ",")
|
||||
ttl, _ := strconv.Atoi(ttlType[0])
|
||||
// 没有存在该key,则跳过
|
||||
if ttl == -2 {
|
||||
continue
|
||||
}
|
||||
ki := &vo.KeyInfo{Key: k, Type: ttlType[1], Ttl: int64(ttl)}
|
||||
kis = append(kis, ki)
|
||||
}
|
||||
}
|
||||
|
||||
size, _ := cmd.DBSize(context.TODO()).Result()
|
||||
rc.ResData = &vo.Keys{Cursor: cursorRes, Keys: kis, DbSize: size}
|
||||
}
|
||||
|
||||
func (r *Redis) TtlKey(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
ttl, err := ri.GetCmdable().TTL(context.Background(), key).Result()
|
||||
biz.ErrIsNil(err, "ttl失败: %s")
|
||||
|
||||
if ttl == -1 {
|
||||
rc.ResData = -1
|
||||
} else {
|
||||
rc.ResData = ttl.Seconds()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) DeleteKey(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
rc.ReqParam = fmt.Sprintf("%s -> 删除key: %s", ri.Info.GetLogDesc(), key)
|
||||
ri.GetCmdable().Del(context.Background(), key)
|
||||
}
|
||||
|
||||
func (r *Redis) RenameKey(rc *req.Ctx) {
|
||||
form := &form.Rename{}
|
||||
ginx.BindJsonAndValid(rc.GinCtx, form)
|
||||
|
||||
ri := r.getRedisIns(rc)
|
||||
rc.ReqParam = fmt.Sprintf("%s -> 重命名key[%s] -> [%s]", ri.Info.GetLogDesc(), form.Key, form.NewKey)
|
||||
ri.GetCmdable().Rename(context.Background(), form.Key, form.NewKey)
|
||||
}
|
||||
|
||||
func (r *Redis) ExpireKey(rc *req.Ctx) {
|
||||
form := &form.Expire{}
|
||||
ginx.BindJsonAndValid(rc.GinCtx, form)
|
||||
|
||||
ri := r.getRedisIns(rc)
|
||||
rc.ReqParam = fmt.Sprintf("%s -> 重置key[%s]过期时间为%d", ri.Info.GetLogDesc(), form.Key, form.Seconds)
|
||||
ri.GetCmdable().Expire(context.Background(), form.Key, time.Duration(form.Seconds)*time.Second)
|
||||
}
|
||||
|
||||
// 移除过期时间
|
||||
func (r *Redis) PersistKey(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
rc.ReqParam = fmt.Sprintf("%s -> 移除key[%s]的过期时间", ri.Info.GetLogDesc(), key)
|
||||
ri.GetCmdable().Persist(context.Background(), key)
|
||||
}
|
||||
65
server/internal/redis/api/list.go
Normal file
65
server/internal/redis/api/list.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
)
|
||||
|
||||
func (r *Redis) GetListValue(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
ctx := context.TODO()
|
||||
cmdable := ri.GetCmdable()
|
||||
|
||||
len, err := cmdable.LLen(ctx, key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取list长度失败: %s")
|
||||
|
||||
g := rc.GinCtx
|
||||
start := ginx.QueryInt(g, "start", 0)
|
||||
stop := ginx.QueryInt(g, "stop", 10)
|
||||
res, err := cmdable.LRange(ctx, key, int64(start), int64(stop)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取list值失败: %s")
|
||||
|
||||
rc.ResData = map[string]interface{}{
|
||||
"len": len,
|
||||
"list": res,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) Lrem(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
option := new(form.LRemOption)
|
||||
ginx.BindJsonAndValid(g, option)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
res, err := cmd.LRem(context.TODO(), option.Key, int64(option.Count), option.Member).Result()
|
||||
biz.ErrIsNilAppendErr(err, "lrem失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) SaveListValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
listValue := new(form.ListValue)
|
||||
ginx.BindJsonAndValid(g, listValue)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
|
||||
key := listValue.Key
|
||||
ctx := context.TODO()
|
||||
for _, v := range listValue.Value {
|
||||
cmd.RPush(ctx, key, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) SetListValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
listSetValue := new(form.ListSetValue)
|
||||
ginx.BindJsonAndValid(g, listSetValue)
|
||||
|
||||
ri := r.getRedisIns(rc)
|
||||
|
||||
_, err := ri.GetCmdable().LSet(context.TODO(), listSetValue.Key, listSetValue.Index, listSetValue.Value).Result()
|
||||
biz.ErrIsNilAppendErr(err, "list set失败: %s")
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/internal/redis/api/vo"
|
||||
"mayfly-go/internal/redis/application"
|
||||
@@ -13,11 +12,9 @@ import (
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/req"
|
||||
"mayfly-go/pkg/utils"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
@@ -194,314 +191,20 @@ func (r *Redis) ClusterInfo(rc *req.Ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
// scan获取redis的key列表信息
|
||||
func (r *Redis) Scan(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
|
||||
form := &form.RedisScanForm{}
|
||||
ginx.BindJsonAndValid(rc.GinCtx, form)
|
||||
|
||||
cmd := ri.GetCmdable()
|
||||
ctx := context.Background()
|
||||
|
||||
kis := make([]*vo.KeyInfo, 0)
|
||||
var cursorRes map[string]uint64 = make(map[string]uint64)
|
||||
|
||||
mode := ri.Info.Mode
|
||||
if mode == "" || mode == entity.RedisModeStandalone || mode == entity.RedisModeSentinel {
|
||||
redisAddr := ri.Cli.Options().Addr
|
||||
// 汇总所有的查询出来的键值
|
||||
var keys []string
|
||||
// 有通配符或空时使用scan,非模糊匹配直接匹配key
|
||||
if form.Match == "" || strings.ContainsAny(form.Match, "*") {
|
||||
cursorRes[redisAddr] = form.Cursor[redisAddr]
|
||||
for {
|
||||
ks, cursor := ri.Scan(cursorRes[redisAddr], form.Match, form.Count)
|
||||
cursorRes[redisAddr] = cursor
|
||||
if len(ks) > 0 {
|
||||
// 返回了数据则追加总集合中
|
||||
keys = append(keys, ks...)
|
||||
}
|
||||
// 匹配的数量满足用户需求退出
|
||||
if int32(len(keys)) >= int32(form.Count) {
|
||||
break
|
||||
}
|
||||
// 匹配到最后退出
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 精确匹配
|
||||
keys = append(keys, form.Match)
|
||||
}
|
||||
|
||||
var keyInfoSplit []string
|
||||
if len(keys) > 0 {
|
||||
keyInfosLua := `local result = {}
|
||||
-- KEYS[1]为第1个参数,lua数组下标从1开始
|
||||
for i = 1, #KEYS do
|
||||
local ttl = redis.call('ttl', KEYS[i]);
|
||||
local keyType = redis.call('type', KEYS[i]);
|
||||
table.insert(result, string.format("%d,%s", ttl, keyType['ok']));
|
||||
end;
|
||||
return table.concat(result, ".");`
|
||||
// 通过lua获取 ttl,type.ttl2,type2格式,以便下面切割获取ttl和type。避免多次调用ttl和type函数
|
||||
keyInfos, err := cmd.Eval(ctx, keyInfosLua, keys).Result()
|
||||
biz.ErrIsNilAppendErr(err, "执行lua脚本获取key信息失败: %s")
|
||||
keyInfoSplit = strings.Split(keyInfos.(string), ".")
|
||||
}
|
||||
|
||||
for i, k := range keys {
|
||||
ttlType := strings.Split(keyInfoSplit[i], ",")
|
||||
ttl, _ := strconv.Atoi(ttlType[0])
|
||||
// 没有存在该key,则跳过
|
||||
if ttl == -2 {
|
||||
continue
|
||||
}
|
||||
ki := &vo.KeyInfo{Key: k, Type: ttlType[1], Ttl: int64(ttl)}
|
||||
kis = append(kis, ki)
|
||||
}
|
||||
} else if mode == entity.RedisModeCluster {
|
||||
var keys []string
|
||||
// 有通配符或空时使用scan,非模糊匹配直接匹配key
|
||||
if form.Match == "" || strings.ContainsAny(form.Match, "*") {
|
||||
mu := &sync.Mutex{}
|
||||
// 遍历所有master节点,并执行scan命令,合并keys
|
||||
ri.ClusterCli.ForEachMaster(ctx, func(ctx context.Context, client *redis.Client) error {
|
||||
redisAddr := client.Options().Addr
|
||||
nowCursor := form.Cursor[redisAddr]
|
||||
for {
|
||||
ks, cursor, _ := client.Scan(ctx, nowCursor, form.Match, form.Count).Result()
|
||||
// 遍历节点的内部回调函数使用异步调用,如不加锁会导致集合并发错误
|
||||
mu.Lock()
|
||||
cursorRes[redisAddr] = cursor
|
||||
nowCursor = cursor
|
||||
if len(ks) > 0 {
|
||||
// 返回了数据则追加总集合中
|
||||
keys = append(keys, ks...)
|
||||
}
|
||||
mu.Unlock()
|
||||
// 匹配的数量满足用户需求退出
|
||||
if int32(len(keys)) >= int32(form.Count) {
|
||||
break
|
||||
}
|
||||
// 匹配到最后退出
|
||||
if cursor == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
} else {
|
||||
// 精确匹配
|
||||
keys = append(keys, form.Match)
|
||||
}
|
||||
|
||||
// 因为redis集群模式执行lua脚本key必须位于同一slot中,故单机获取的方式不适合
|
||||
// 使用lua获取key的ttl以及类型,减少网络调用
|
||||
keyInfoLua := `local ttl = redis.call('ttl', KEYS[1]);
|
||||
local keyType = redis.call('type', KEYS[1]);
|
||||
return string.format("%d,%s", ttl, keyType['ok'])`
|
||||
for _, k := range keys {
|
||||
keyInfo, err := cmd.Eval(ctx, keyInfoLua, []string{k}).Result()
|
||||
biz.ErrIsNilAppendErr(err, "执行lua脚本获取key信息失败: %s")
|
||||
ttlType := strings.Split(keyInfo.(string), ",")
|
||||
ttl, _ := strconv.Atoi(ttlType[0])
|
||||
// 没有存在该key,则跳过
|
||||
if ttl == -2 {
|
||||
continue
|
||||
}
|
||||
ki := &vo.KeyInfo{Key: k, Type: ttlType[1], Ttl: int64(ttl)}
|
||||
kis = append(kis, ki)
|
||||
}
|
||||
}
|
||||
|
||||
size, _ := cmd.DBSize(context.TODO()).Result()
|
||||
rc.ResData = &vo.Keys{Cursor: cursorRes, Keys: kis, DbSize: size}
|
||||
}
|
||||
|
||||
func (r *Redis) DeleteKey(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
key := g.Query("key")
|
||||
// 校验查询参数中的key为必填项,并返回redis实例
|
||||
func (r *Redis) checkKeyAndGetRedisIns(rc *req.Ctx) (*application.RedisInstance, string) {
|
||||
key := rc.GinCtx.Query("key")
|
||||
biz.NotEmpty(key, "key不能为空")
|
||||
return r.getRedisIns(rc), key
|
||||
}
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
func (r *Redis) getRedisIns(rc *req.Ctx) *application.RedisInstance {
|
||||
ri := r.RedisApp.GetRedisInstance(getIdAndDbNum(rc.GinCtx))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
|
||||
rc.ReqParam = fmt.Sprintf("%s -> 删除key: %s", ri.Info.GetLogDesc(), key)
|
||||
ri.GetCmdable().Del(context.Background(), key)
|
||||
return ri
|
||||
}
|
||||
|
||||
func (r *Redis) checkKey(rc *req.Ctx) (*application.RedisInstance, string) {
|
||||
g := rc.GinCtx
|
||||
key := g.Query("key")
|
||||
biz.NotEmpty(key, "key不能为空")
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
|
||||
return ri, key
|
||||
}
|
||||
|
||||
func (r *Redis) GetStringValue(rc *req.Ctx) {
|
||||
ri, key := r.checkKey(rc)
|
||||
str, err := ri.GetCmdable().Get(context.TODO(), key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取字符串值失败: %s")
|
||||
rc.ResData = str
|
||||
}
|
||||
|
||||
func (r *Redis) SetStringValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
keyValue := new(form.StringValue)
|
||||
ginx.BindJsonAndValid(g, keyValue)
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
|
||||
rc.ReqParam = fmt.Sprintf("%s -> %s", ri.Info.GetLogDesc(), utils.ToString(keyValue))
|
||||
|
||||
str, err := ri.GetCmdable().Set(context.TODO(), keyValue.Key, keyValue.Value, time.Second*time.Duration(keyValue.Timed)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "保存字符串值失败: %s")
|
||||
rc.ResData = str
|
||||
}
|
||||
|
||||
func (r *Redis) Hscan(rc *req.Ctx) {
|
||||
ri, key := r.checkKey(rc)
|
||||
g := rc.GinCtx
|
||||
count := ginx.QueryInt(g, "count", 10)
|
||||
match := g.Query("match")
|
||||
cursor := ginx.QueryInt(g, "cursor", 0)
|
||||
contextTodo := context.TODO()
|
||||
|
||||
cmdable := ri.GetCmdable()
|
||||
keys, nextCursor, err := cmdable.HScan(contextTodo, key, uint64(cursor), match, int64(count)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hcan err: %s")
|
||||
keySize, err := cmdable.HLen(contextTodo, key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hlen err: %s")
|
||||
|
||||
rc.ResData = map[string]interface{}{
|
||||
"keys": keys,
|
||||
"cursor": nextCursor,
|
||||
"keySize": keySize,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) Hdel(rc *req.Ctx) {
|
||||
ri, key := r.checkKey(rc)
|
||||
field := rc.GinCtx.Query("field")
|
||||
|
||||
delRes, err := ri.GetCmdable().HDel(context.TODO(), key, field).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hdel err: %s")
|
||||
rc.ResData = delRes
|
||||
}
|
||||
|
||||
func (r *Redis) Hget(rc *req.Ctx) {
|
||||
ri, key := r.checkKey(rc)
|
||||
field := rc.GinCtx.Query("field")
|
||||
|
||||
res, err := ri.GetCmdable().HGet(context.TODO(), key, field).Result()
|
||||
biz.ErrIsNilAppendErr(err, "hget err: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) SetHashValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
hashValue := new(form.HashValue)
|
||||
ginx.BindJsonAndValid(g, hashValue)
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
|
||||
cmd := ri.GetCmdable()
|
||||
key := hashValue.Key
|
||||
contextTodo := context.TODO()
|
||||
for _, v := range hashValue.Value {
|
||||
res := cmd.HSet(contextTodo, key, v["field"].(string), v["value"])
|
||||
biz.ErrIsNilAppendErr(res.Err(), "保存hash值失败: %s")
|
||||
}
|
||||
if hashValue.Timed != 0 && hashValue.Timed != -1 {
|
||||
cmd.Expire(context.TODO(), key, time.Second*time.Duration(hashValue.Timed))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) GetSetValue(rc *req.Ctx) {
|
||||
ri, key := r.checkKey(rc)
|
||||
res, err := ri.GetCmdable().SMembers(context.TODO(), key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取set值失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) SetSetValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
keyvalue := new(form.SetValue)
|
||||
ginx.BindJsonAndValid(g, keyvalue)
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
cmd := ri.GetCmdable()
|
||||
|
||||
key := keyvalue.Key
|
||||
// 简单处理->先删除,后新增
|
||||
cmd.Del(context.TODO(), key)
|
||||
cmd.SAdd(context.TODO(), key, keyvalue.Value...)
|
||||
|
||||
if keyvalue.Timed != -1 {
|
||||
cmd.Expire(context.TODO(), key, time.Second*time.Duration(keyvalue.Timed))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) GetListValue(rc *req.Ctx) {
|
||||
ri, key := r.checkKey(rc)
|
||||
ctx := context.TODO()
|
||||
cmdable := ri.GetCmdable()
|
||||
|
||||
len, err := cmdable.LLen(ctx, key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取list长度失败: %s")
|
||||
|
||||
g := rc.GinCtx
|
||||
start := ginx.QueryInt(g, "start", 0)
|
||||
stop := ginx.QueryInt(g, "stop", 10)
|
||||
res, err := cmdable.LRange(ctx, key, int64(start), int64(stop)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取list值失败: %s")
|
||||
|
||||
rc.ResData = map[string]interface{}{
|
||||
"len": len,
|
||||
"list": res,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) SaveListValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
listValue := new(form.ListValue)
|
||||
ginx.BindJsonAndValid(g, listValue)
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
cmd := ri.GetCmdable()
|
||||
|
||||
key := listValue.Key
|
||||
ctx := context.TODO()
|
||||
for _, v := range listValue.Value {
|
||||
cmd.RPush(ctx, key, v)
|
||||
}
|
||||
|
||||
if listValue.Timed != -1 {
|
||||
cmd.Expire(context.TODO(), key, time.Second*time.Duration(listValue.Timed))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) SetListValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
listSetValue := new(form.ListSetValue)
|
||||
ginx.BindJsonAndValid(g, listSetValue)
|
||||
|
||||
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db"))
|
||||
biz.ErrIsNilAppendErr(r.TagApp.CanAccess(rc.LoginAccount.Id, ri.Info.TagPath), "%s")
|
||||
|
||||
_, err := ri.GetCmdable().LSet(context.TODO(), listSetValue.Key, listSetValue.Index, listSetValue.Value).Result()
|
||||
biz.ErrIsNilAppendErr(err, "list set失败: %s")
|
||||
// 获取redis id与要操作的库号(统一路径)
|
||||
func getIdAndDbNum(g *gin.Context) (uint64, int) {
|
||||
return uint64(ginx.PathParamInt(g, "id")), ginx.PathParamInt(g, "db")
|
||||
}
|
||||
|
||||
78
server/internal/redis/api/set.go
Normal file
78
server/internal/redis/api/set.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (r *Redis) GetSetValue(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
res, err := ri.GetCmdable().SMembers(context.TODO(), key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取set值失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) SetSetValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
keyvalue := new(form.SetValue)
|
||||
ginx.BindJsonAndValid(g, keyvalue)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
|
||||
key := keyvalue.Key
|
||||
// 简单处理->先删除,后新增
|
||||
cmd.Del(context.TODO(), key)
|
||||
cmd.SAdd(context.TODO(), key, keyvalue.Value...)
|
||||
|
||||
if keyvalue.Timed != -1 {
|
||||
cmd.Expire(context.TODO(), key, time.Second*time.Duration(keyvalue.Timed))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) Scard(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
|
||||
total, err := ri.GetCmdable().SCard(context.TODO(), key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "scard失败: %s")
|
||||
rc.ResData = total
|
||||
}
|
||||
|
||||
func (r *Redis) Sscan(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
scan := new(form.ScanForm)
|
||||
ginx.BindJsonAndValid(g, scan)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
keys, cursor, err := cmd.SScan(context.TODO(), scan.Key, scan.Cursor, scan.Match, scan.Count).Result()
|
||||
biz.ErrIsNilAppendErr(err, "sscan失败: %s")
|
||||
rc.ResData = map[string]interface{}{
|
||||
"keys": keys,
|
||||
"cursor": cursor,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) Sadd(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
option := new(form.SmemberOption)
|
||||
ginx.BindJsonAndValid(g, option)
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
|
||||
res, err := cmd.SAdd(context.TODO(), option.Key, option.Member).Result()
|
||||
biz.ErrIsNilAppendErr(err, "sadd失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) Srem(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
option := new(form.SmemberOption)
|
||||
ginx.BindJsonAndValid(g, option)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
res, err := cmd.SRem(context.TODO(), option.Key, option.Member).Result()
|
||||
biz.ErrIsNilAppendErr(err, "srem失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
33
server/internal/redis/api/string.go
Normal file
33
server/internal/redis/api/string.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
"mayfly-go/pkg/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (r *Redis) GetStringValue(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
str, err := ri.GetCmdable().Get(context.TODO(), key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "获取字符串值失败: %s")
|
||||
rc.ResData = str
|
||||
}
|
||||
|
||||
func (r *Redis) SetStringValue(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
keyValue := new(form.StringValue)
|
||||
ginx.BindJsonAndValid(g, keyValue)
|
||||
|
||||
ri := r.getRedisIns(rc)
|
||||
cmd := ri.GetCmdable()
|
||||
rc.ReqParam = fmt.Sprintf("%s -> %s", ri.Info.GetLogDesc(), utils.ToString(keyValue))
|
||||
|
||||
str, err := cmd.Set(context.TODO(), keyValue.Key, keyValue.Value, time.Second*time.Duration(keyValue.Timed)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "保存字符串值失败: %s")
|
||||
rc.ResData = str
|
||||
}
|
||||
72
server/internal/redis/api/zset.go
Normal file
72
server/internal/redis/api/zset.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"mayfly-go/internal/redis/api/form"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
func (r *Redis) ZCard(rc *req.Ctx) {
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
|
||||
total, err := ri.GetCmdable().ZCard(context.TODO(), key).Result()
|
||||
biz.ErrIsNilAppendErr(err, "zcard失败: %s")
|
||||
rc.ResData = total
|
||||
}
|
||||
|
||||
func (r *Redis) ZScan(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
|
||||
cursor := uint64(ginx.QueryInt(g, "cursor", 0))
|
||||
match := ginx.Query(g, "match", "*")
|
||||
count := ginx.QueryInt(g, "count", 50)
|
||||
|
||||
keys, cursor, err := ri.GetCmdable().ZScan(context.TODO(), key, cursor, match, int64(count)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "sscan失败: %s")
|
||||
rc.ResData = map[string]interface{}{
|
||||
"keys": keys,
|
||||
"cursor": cursor,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Redis) ZRevRange(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
ri, key := r.checkKeyAndGetRedisIns(rc)
|
||||
start := ginx.QueryInt(g, "start", 0)
|
||||
stop := ginx.QueryInt(g, "stop", 50)
|
||||
|
||||
res, err := ri.GetCmdable().ZRevRangeWithScores(context.TODO(), key, int64(start), int64(stop)).Result()
|
||||
biz.ErrIsNilAppendErr(err, "ZRevRange失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) ZRem(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
option := new(form.SmemberOption)
|
||||
ginx.BindJsonAndValid(g, option)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
res, err := cmd.ZRem(context.TODO(), option.Key, option.Member).Result()
|
||||
biz.ErrIsNilAppendErr(err, "zrem失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
|
||||
func (r *Redis) ZAdd(rc *req.Ctx) {
|
||||
g := rc.GinCtx
|
||||
option := new(form.ZAddOption)
|
||||
ginx.BindJsonAndValid(g, option)
|
||||
|
||||
cmd := r.getRedisIns(rc).GetCmdable()
|
||||
zm := redis.Z{
|
||||
Score: option.Score,
|
||||
Member: option.Member,
|
||||
}
|
||||
res, err := cmd.ZAdd(context.TODO(), option.Key, zm).Result()
|
||||
biz.ErrIsNilAppendErr(err, "zadd失败: %s")
|
||||
rc.ResData = res
|
||||
}
|
||||
@@ -49,15 +49,47 @@ func InitRedisRouter(router *gin.RouterGroup) {
|
||||
req.NewCtxWithGin(c).Handle(rs.Scan)
|
||||
})
|
||||
|
||||
// 删除key
|
||||
deleteKeyL := req.NewLogInfo("redis-删除key").WithSave(true)
|
||||
deleteKeyP := req.NewPermission("redis:data:del")
|
||||
redis.DELETE(":id/:db/key", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithLog(deleteKeyL).WithRequiredPermission(deleteKeyP).Handle(rs.DeleteKey)
|
||||
redis.GET(":id/:db/key-ttl", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.TtlKey)
|
||||
})
|
||||
|
||||
// 保存数据权限
|
||||
saveDataP := req.NewPermission("redis:data:save")
|
||||
// 删除数据权限
|
||||
deleteDataP := req.NewPermission("redis:data:del")
|
||||
|
||||
// 删除key
|
||||
deleteKeyL := req.NewLogInfo("redis-删除key").WithSave(true)
|
||||
redis.DELETE(":id/:db/key", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(deleteKeyL).
|
||||
WithRequiredPermission(deleteDataP).
|
||||
Handle(rs.DeleteKey)
|
||||
})
|
||||
|
||||
renameKeyL := req.NewLogInfo("redis-重命名key").WithSave(true)
|
||||
redis.POST(":id/:db/rename-key", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(renameKeyL).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.RenameKey)
|
||||
})
|
||||
|
||||
expireKeyL := req.NewLogInfo("redis-设置key过期时间").WithSave(true)
|
||||
redis.POST(":id/:db/expire-key", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(expireKeyL).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.ExpireKey)
|
||||
})
|
||||
|
||||
persistKeyL := req.NewLogInfo("redis-移除key过期时间").WithSave(true)
|
||||
redis.DELETE(":id/:db/persist-key", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(persistKeyL).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.PersistKey)
|
||||
})
|
||||
|
||||
// 获取string类型值
|
||||
redis.GET(":id/:db/string-value", func(c *gin.Context) {
|
||||
@@ -67,7 +99,10 @@ func InitRedisRouter(router *gin.RouterGroup) {
|
||||
// 设置string类型值
|
||||
setStringL := req.NewLogInfo("redis-setString").WithSave(true)
|
||||
redis.POST(":id/:db/string-value", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithLog(setStringL).WithRequiredPermission(saveDataP).Handle(rs.SetStringValue)
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(setStringL).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.SetStringValue)
|
||||
})
|
||||
|
||||
// hscan
|
||||
@@ -79,25 +114,60 @@ func InitRedisRouter(router *gin.RouterGroup) {
|
||||
req.NewCtxWithGin(c).Handle(rs.Hget)
|
||||
})
|
||||
|
||||
hsetL := req.NewLogInfo("redis-hset").WithSave(true)
|
||||
redis.POST(":id/:db/hset", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(hsetL).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.Hset)
|
||||
})
|
||||
|
||||
hdelL := req.NewLogInfo("redis-hdel").WithSave(true)
|
||||
redis.DELETE(":id/:db/hdel", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithLog(hdelL).WithRequiredPermission(deleteKeyP).Handle(rs.Hdel)
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(hdelL).
|
||||
WithRequiredPermission(deleteDataP).
|
||||
Handle(rs.Hdel)
|
||||
})
|
||||
|
||||
// 设置hash类型值
|
||||
setHashValueL := req.NewLogInfo("redis-setHashValue").WithSave(true)
|
||||
redis.POST(":id/:db/hash-value", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithLog(setHashValueL).WithRequiredPermission(saveDataP).Handle(rs.SetHashValue)
|
||||
req.NewCtxWithGin(c).
|
||||
WithLog(setHashValueL).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.SetHashValue)
|
||||
})
|
||||
|
||||
// 获取set类型值
|
||||
// set操作
|
||||
redis.GET(":id/:db/set-value", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.GetSetValue)
|
||||
})
|
||||
|
||||
// 设置set类型值
|
||||
redis.POST(":id/:db/set-value", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithRequiredPermission(saveDataP).Handle(rs.SetSetValue)
|
||||
req.NewCtxWithGin(c).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.SetSetValue)
|
||||
})
|
||||
|
||||
redis.GET(":id/:db/scard", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.Scard)
|
||||
})
|
||||
|
||||
redis.POST(":id/:db/sscan", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.Sscan)
|
||||
})
|
||||
|
||||
redis.POST(":id/:db/sadd", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.Sadd)
|
||||
})
|
||||
|
||||
redis.POST(":id/:db/srem", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithRequiredPermission(deleteDataP).
|
||||
Handle(rs.Srem)
|
||||
})
|
||||
|
||||
// 获取list类型值
|
||||
@@ -112,5 +182,36 @@ func InitRedisRouter(router *gin.RouterGroup) {
|
||||
redis.POST(":id/:db/list-value/lset", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.SetListValue)
|
||||
})
|
||||
|
||||
redis.POST(":id/:db/lrem", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithRequiredPermission(deleteDataP).
|
||||
Handle(rs.Lrem)
|
||||
})
|
||||
|
||||
// zset操作
|
||||
redis.GET(":id/:db/zcard", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.ZCard)
|
||||
})
|
||||
|
||||
redis.GET(":id/:db/zscan", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.ZScan)
|
||||
})
|
||||
|
||||
redis.GET(":id/:db/zrevrange", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).Handle(rs.ZRevRange)
|
||||
})
|
||||
|
||||
redis.POST(":id/:db/zrem", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithRequiredPermission(deleteDataP).
|
||||
Handle(rs.ZRem)
|
||||
})
|
||||
|
||||
redis.POST(":id/:db/zadd", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).
|
||||
WithRequiredPermission(saveDataP).
|
||||
Handle(rs.ZAdd)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func InitAccountRouter(router *gin.RouterGroup) {
|
||||
loginLog := req.NewLogInfo("用户登录").WithSave(true)
|
||||
account.POST("login", func(g *gin.Context) {
|
||||
req.NewCtxWithGin(g).
|
||||
WithNeedToken(false).
|
||||
DontNeedToken().
|
||||
WithLog(loginLog).
|
||||
Handle(a.Login)
|
||||
})
|
||||
@@ -35,7 +35,7 @@ func InitAccountRouter(router *gin.RouterGroup) {
|
||||
changePwdLog := req.NewLogInfo("用户修改密码").WithSave(true)
|
||||
account.POST("change-pwd", func(g *gin.Context) {
|
||||
req.NewCtxWithGin(g).
|
||||
WithNeedToken(false).
|
||||
DontNeedToken().
|
||||
WithLog(changePwdLog).
|
||||
Handle(a.ChangePassword)
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@ func InitCaptchaRouter(router *gin.RouterGroup) {
|
||||
captcha := router.Group("sys/captcha")
|
||||
{
|
||||
captcha.GET("", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithNeedToken(false).Handle(api.GenerateCaptcha)
|
||||
req.NewCtxWithGin(c).DontNeedToken().Handle(api.GenerateCaptcha)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ func InitSysConfigRouter(router *gin.RouterGroup) {
|
||||
})
|
||||
|
||||
db.GET("/value", func(c *gin.Context) {
|
||||
req.NewCtxWithGin(c).WithNeedToken(false).Handle(r.GetConfigValueByKey)
|
||||
req.NewCtxWithGin(c).DontNeedToken().Handle(r.GetConfigValueByKey)
|
||||
})
|
||||
|
||||
saveConfig := req.NewLogInfo("保存系统配置信息").WithSave(true)
|
||||
|
||||
Reference in New Issue
Block a user