diff --git a/internal/consts/consts.go b/internal/consts/consts.go index d709a2b..0d60042 100644 --- a/internal/consts/consts.go +++ b/internal/consts/consts.go @@ -1 +1,12 @@ package consts + +const ( + BASE_TTL = 600 + RANDOM_RANGE = 60 +) + +const ( + VOTE_DETAIL = "voteDetail" //投票名单查询 + ARTICLE = "article" //文章查询 + EXPORT_FILE = "exportFile" //导出数据查询 +) diff --git a/internal/logic/vote_record/add_record.go b/internal/logic/vote_record/add_record.go index 3499b32..b94f1c2 100644 --- a/internal/logic/vote_record/add_record.go +++ b/internal/logic/vote_record/add_record.go @@ -2,10 +2,13 @@ package vote_record import ( "context" + "fmt" "github.com/gogf/gf/v2/os/gtime" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" "practice_ArticleVote_Go/internal/model/do" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) AddRecord(ctx context.Context, req *v1.AddRecordReq) (res *v1.AddRecordRes, err error) { @@ -22,19 +25,13 @@ func (l *VoteRecordLogic) AddRecord(ctx context.Context, req *v1.AddRecordReq) ( }) } _, err = dao.VoteRecord.Ctx(ctx).Data(records).Insert() - //_, err = dao.VoteRecord. - // Ctx(ctx). - // Data(do.VoteRecord{ - // UserId: req.UserId, - // VoteId: req.VoteId, - // OptionId: req.OptionId, - // VoteIndex: req.VoteIndex, - // CreateTime: gtime.Now(), - // UpdateTime: gtime.Now(), - // }).Insert() if err != nil { return nil, err } + voteDetailpattern := fmt.Sprintf(consts.VOTE_DETAIL+":%d:*", req.VoteId) + _, err = utils.DeleteKeys(ctx, voteDetailpattern) + ExportFilepattern := fmt.Sprintf(consts.EXPORT_FILE+":%d:*", req.VoteId) + _, err = utils.DeleteKeys(ctx, ExportFilepattern) res = &v1.AddRecordRes{} return res, nil } diff --git a/internal/logic/vote_record/get_export_file.go b/internal/logic/vote_record/get_export_file.go index eed0e03..59ad9c2 100644 --- a/internal/logic/vote_record/get_export_file.go +++ b/internal/logic/vote_record/get_export_file.go @@ -2,11 +2,29 @@ package vote_record import ( "context" + "encoding/json" + "fmt" "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) ExportVoteDetail(ctx context.Context, req *v1.GetExportFileReq) (res *v1.GetExportFileRes, err error) { + redis := g.Redis() + cacheKey := fmt.Sprintf( + consts.EXPORT_FILE+":%d:%s:%s:%s:%s", + req.VoteId, req.Username, req.Account, req.Area, req.OptionContent, + ) + data, _ := redis.Get(ctx, cacheKey) + fmt.Println("data", data) + if data != nil { + var cached v1.GetExportFileRes + err = json.Unmarshal([]byte(data.String()), &cached) + if err == nil { + return &cached, nil + } + } query := ` SELECT u.username, @@ -60,5 +78,10 @@ func (l *VoteRecordLogic) ExportVoteDetail(ctx context.Context, req *v1.GetExpor res = &v1.GetExportFileRes{ VoteList: voteList, } + buf, err := json.Marshal(res) + if err == nil { + ttl := utils.GetCacheTTL() + _ = redis.SetEX(ctx, cacheKey, string(buf), int64(ttl)) + } return res, err } diff --git a/internal/logic/vote_record/get_index.go b/internal/logic/vote_record/get_index.go index 6b09099..387759b 100644 --- a/internal/logic/vote_record/get_index.go +++ b/internal/logic/vote_record/get_index.go @@ -2,8 +2,6 @@ package vote_record import ( "context" - "fmt" - "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" @@ -13,14 +11,6 @@ import ( func (l *VoteRecordLogic) GetIndex(ctx context.Context, req *v1.GetIndexReq) (res *v1.GetIndexRes, err error) { today := time.Now().Format("2006-01-02") - redis := g.Redis() - _, err = redis.Set(ctx, "key", "Hello, GoFrame!") - value, err := redis.Get(ctx, "key") - fmt.Println(value) - if err != nil { - fmt.Println("Set error:", err) - return - } record, err := dao.VoteRecord. Ctx(ctx). Fields("vote_index"). diff --git a/internal/logic/vote_record/get_vote.go b/internal/logic/vote_record/get_vote.go index d5b11ce..f6a4397 100644 --- a/internal/logic/vote_record/get_vote.go +++ b/internal/logic/vote_record/get_vote.go @@ -2,15 +2,34 @@ package vote_record import ( "context" + "encoding/json" + "fmt" "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" "practice_ArticleVote_Go/internal/dao" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) GetVote(ctx context.Context, req *v1.GetVoteReq) (res *v1.GetVoteRes, err error) { + redis := g.Redis() + cacheKey := fmt.Sprintf( + consts.ARTICLE+":%d", + req.ArticleId, + ) + fmt.Println(cacheKey) + data, _ := redis.Get(ctx, cacheKey) + fmt.Println("data", data) + if data != nil { + var cached v1.GetVoteRes + err = json.Unmarshal([]byte(data.String()), &cached) + if err == nil { + return &cached, nil + } + } articleRow, err := dao.Article.Ctx(ctx). Fields( dao.Article.Columns().ArticleTitle, @@ -87,5 +106,10 @@ func (l *VoteRecordLogic) GetVote(ctx context.Context, req *v1.GetVoteReq) (res OrderAsc(dao.VoteOption.Columns().OptionIndex). Scan(&res.OptionList) } + buf, err := json.Marshal(res) + if err == nil { + ttl := utils.GetCacheTTL() + _ = redis.SetEX(ctx, cacheKey, string(buf), int64(ttl)) + } return res, nil } diff --git a/internal/logic/vote_record/get_vote_detail.go b/internal/logic/vote_record/get_vote_detail.go index c30bb8a..2ce2f40 100644 --- a/internal/logic/vote_record/get_vote_detail.go +++ b/internal/logic/vote_record/get_vote_detail.go @@ -2,9 +2,12 @@ package vote_record import ( "context" + "encoding/json" "fmt" "github.com/gogf/gf/v2/frame/g" v1 "practice_ArticleVote_Go/api/vote_record/v1" + "practice_ArticleVote_Go/internal/consts" + "practice_ArticleVote_Go/internal/utils" ) func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDetailReq) (res *v1.GetVoteDetailListRes, err error) { @@ -42,6 +45,22 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta // return nil, err //} //return res, nil + redis := g.Redis() + cacheKey := fmt.Sprintf( + consts.VOTE_DETAIL+":%d:%d:%d:%s:%s:%s:%s", + req.VoteId, req.Page, req.Size, + req.Username, req.Account, req.Area, req.OptionContent, + ) + fmt.Println(cacheKey) + data, _ := redis.Get(ctx, cacheKey) + fmt.Println("data", data) + if data != nil { + var cached v1.GetVoteDetailListRes + err = json.Unmarshal([]byte(data.String()), &cached) + if err == nil { + return &cached, nil + } + } query := ` SELECT u.username, @@ -65,9 +84,7 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta JOIN user u ON u.id = uv.user_id WHERE 1=1 ` - conditions := []interface{}{req.VoteId} - if req.OptionContent != "" { query += " AND uv.option_contents LIKE ?" conditions = append(conditions, "%"+req.OptionContent+"%") @@ -102,5 +119,10 @@ func (l *VoteRecordLogic) GetVoteDetail(ctx context.Context, req *v1.GetVoteDeta return nil, err } res.VoteList = voteList + buf, merr := json.Marshal(res) + if merr == nil { + ttl := utils.GetCacheTTL() + _ = redis.SetEX(ctx, cacheKey, string(buf), int64(ttl)) + } return res, nil } diff --git a/internal/utils/cachettl.go b/internal/utils/cachettl.go new file mode 100644 index 0000000..7f7df19 --- /dev/null +++ b/internal/utils/cachettl.go @@ -0,0 +1,13 @@ +package utils + +import ( + "math/rand" + "practice_ArticleVote_Go/internal/consts" + "time" +) + +func GetCacheTTL() time.Duration { + baseTTL := consts.BASE_TTL + randomNumber := rand.Intn(consts.RANDOM_RANGE) + return time.Duration(baseTTL+randomNumber) * time.Second +} diff --git a/internal/utils/delete_keys.go b/internal/utils/delete_keys.go new file mode 100644 index 0000000..d71fdec --- /dev/null +++ b/internal/utils/delete_keys.go @@ -0,0 +1,45 @@ +package utils + +import ( + "context" + "fmt" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/util/gconv" +) + +func DeleteKeys(ctx context.Context, pattern string) (int, error) { + redis := g.Redis() + var ( + cursor uint64 + totalKeys int + batchSize = 100 + ) + g.Log().Debugf(ctx, "开始删除匹配模式 %q 的缓存键", pattern) + for { + result, err := redis.Do(ctx, "SCAN", cursor, "MATCH", pattern, "COUNT", batchSize) + if err != nil { + return totalKeys, fmt.Errorf("SCAN 失败: %v", err) + } + arr := result.Array() + fmt.Println("arr:", arr) + cursor = gconv.Uint64(arr[0]) + rawKeys := gconv.Strings(arr[1]) + var keys []string + for _, k := range rawKeys { + keys = append(keys, k) + } + fmt.Println("keys:", keys) + if len(keys) > 0 { + deleted, err := redis.Del(ctx, keys...) + if err != nil { + g.Log().Warningf(ctx, "缓存删除异常: %v", err) + } + totalKeys += int(deleted) + g.Log().Debugf(ctx, "本次删除 %d/%d 个键", deleted, len(keys)) + } + if cursor == 0 { + break + } + } + return totalKeys, nil +} diff --git a/main.go b/main.go index dcf78da..81c91e5 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,8 @@ import ( "github.com/gogf/gf/v2/os/gctx" + _ "github.com/gogf/gf/contrib/nosql/redis/v2" + "practice_ArticleVote_Go/internal/cmd" )