From 18ef3f2bce12518893483a856d5b677cbd0aa154 Mon Sep 17 00:00:00 2001 From: Havoc412 <2993167370@qq.com> Date: Mon, 18 Nov 2024 18:35:10 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20class=20RedisClient=20in=20singl?= =?UTF-8?q?e=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/http/controller/web/animal_controller.go | 26 +++------- app/model/encounter.go | 48 +++++++++++++++--- app/model_redis/selectedAnimal4Prefer.go | 51 ++++++++++++++++++-- 3 files changed, 96 insertions(+), 29 deletions(-) diff --git a/app/http/controller/web/animal_controller.go b/app/http/controller/web/animal_controller.go index 9c0be16..fad0f3d 100644 --- a/app/http/controller/web/animal_controller.go +++ b/app/http/controller/web/animal_controller.go @@ -11,9 +11,7 @@ import ( "catface/app/service/animals/curd" "catface/app/service/upload_file" "catface/app/utils/query_handler" - "catface/app/utils/redis_factory" "catface/app/utils/response" - "encoding/json" "os" "path/filepath" "strconv" @@ -39,23 +37,17 @@ func (a *Animals) List(context *gin.Context) { mode := context.GetString(consts.ValidatorPrefix + "mode") // TAG prefer MODE 查询模式。 - var key int64 var redis_selctedCatsId model_redis.SelectedAnimal4Prefer var animalsWithLike []model.AnimalWithLikeList if mode == consts.AnimalPreferMode { - key = int64(context.GetFloat64(consts.ValidatorPrefix + "key")) - redis_selctedCatsId.Key = key + key := int64(context.GetFloat64(consts.ValidatorPrefix + "key")) - redisClient := redis_factory.GetOneRedisClient() - defer redisClient.ReleaseOneRedisClient() if key != 0 { - if res, err := redisClient.String(redisClient.Execute("get", key)); err == nil { - json.Unmarshal([]byte(res), &redis_selctedCatsId) - } else { - _ = err + if ok, err := redis_selctedCatsId.GetDataByKey(key); !ok { + _ = err // TODO } } else { - key = variable.SnowFlake.GetId() + redis_selctedCatsId.GenerateKey() } if redis_selctedCatsId.Length() == skip { @@ -65,10 +57,8 @@ func (a *Animals) List(context *gin.Context) { } // TODO 刷新 Redis 有效期 - if value, err := json.Marshal(redis_selctedCatsId); err == nil { - if _, err := redisClient.String(redisClient.Execute("set", key, string(value))); err != nil { - // TODO - } + if ok, err := redis_selctedCatsId.SetDataByKey(); !ok { + _ = err // TODO } } } @@ -85,7 +75,7 @@ func (a *Animals) List(context *gin.Context) { if animalsWithLike != nil { response.Success(context, consts.CurdStatusOkMsg, gin.H{ "animals": animalsWithLike, - "key": key, + "key": redis_selctedCatsId.GetKey(), }) } else { response.Fail(context, errcode.AnimalNoFind, errcode.ErrMsg[errcode.AnimalNoFind], errcode.ErrMsgForUser[errcode.AnimalNoFind]) @@ -106,7 +96,7 @@ func getPreferCats(userId, num int, attrs string, redis *model_redis.SelectedAni // STAGE #2 获取近期新增的毛茸茸;只在第一次操作 && 数量不够时 启用。 var idsNew []int64 - if !redis.PassNew() && len(ids) < num { + if redis.NotPassNew() { // UPDATE && len(ids) < num 调整为第一次访问时一定会次优先返回 NewCats 的推荐。 // 获取近期新增的毛茸茸 newCats, _ := model.CreateAnimalFactory("").NewCatsId(3, 0) // INFO 硬编码获取最新的 3 个。 diff --git a/app/model/encounter.go b/app/model/encounter.go index b9fd45f..14fcd1c 100644 --- a/app/model/encounter.go +++ b/app/model/encounter.go @@ -180,15 +180,47 @@ func (e *Encounter) ShowByIDs(ids []int64, attrs ...string) (temp []Encounter) { * @return {*} */ func (e *Encounter) EncounteredCatsId(user_id, num, skip int, notInIds []int64) ([]int64, error) { - sql := `SELECT DISTINCT eal.animal_id - FROM encounter_animal_links eal - JOIN encounters e - ON e.id = eal.encounter_id AND e.user_id = ? - WHERE e.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) - ORDER BY e.updated_at DESC - LIMIT ? OFFSET ?` + var sqlBuilder strings.Builder - rows, err := e.Raw(sql, user_id, num, skip).Rows() + sqlBuilder.WriteString(` +SELECT DISTINCT eal.animal_id +FROM encounter_animal_links eal +JOIN encounters e + ON e.id = eal.encounter_id +WHERE e.user_id = ? + AND e.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) + `) + + if len(notInIds) > 0 { + sqlBuilder.WriteString(` +AND eal.animal_id NOT IN (?) + `) + } + + sqlBuilder.WriteString(` +ORDER BY e.updated_at DESC +LIMIT ? OFFSET ? + `) + + // sql := `SELECT DISTINCT eal.animal_id + // FROM encounter_animal_links eal + // JOIN encounters e + // ON e.id = eal.encounter_id AND e.user_id = ? + // WHERE e.updated_at >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) + // ORDER BY e.updated_at DESC + // LIMIT ? OFFSET ?` + + // Exe SQL + sql := sqlBuilder.String() + + var rowsRaw *gorm.DB + if len(notInIds) > 0 { + rowsRaw = e.Raw(sql, user_id, notInIds, num, skip) + } else { + rowsRaw = e.Raw(sql, user_id, num, skip) + } + + rows, err := rowsRaw.Rows() if err != nil { log.Println("查询失败:", err) return nil, err diff --git a/app/model_redis/selectedAnimal4Prefer.go b/app/model_redis/selectedAnimal4Prefer.go index 329b93b..5cff22e 100644 --- a/app/model_redis/selectedAnimal4Prefer.go +++ b/app/model_redis/selectedAnimal4Prefer.go @@ -1,15 +1,23 @@ package model_redis +import ( + "catface/app/global/variable" + "catface/app/utils/redis_factory" + "encoding/json" +) + // INFO 辅助 animal - list - prefer 模式下的查询特化。 type SelectedAnimal4Prefer struct { - Key int64 `json:"-"` // redis 的 key 值 EncounteredCatsId []int64 `json:"encountered_cats_id"` // #1 对应第一阶段:近期路遇关联 NewCatsId []int64 `json:"new_cats_id"` // #2 对应第二阶段:近期新增 + + key int64 `json:"-"` // redis 的 key 值 + notPassNewCat bool `json:"-"` } -func (s *SelectedAnimal4Prefer) PassNew() bool { - return s.Key != 0 +func (s *SelectedAnimal4Prefer) NotPassNew() bool { + return s.notPassNewCat } func (s *SelectedAnimal4Prefer) Length() int { @@ -29,3 +37,40 @@ func (s *SelectedAnimal4Prefer) AppendEncIds(ids []int64) { s.EncounteredCatsId = append(s.EncounteredCatsId, int64(id)) } } + +// BASE CURD +func (s *SelectedAnimal4Prefer) GenerateKey() int64 { // TODO 之后迁移到 model_redis 的基类去。 + s.key = variable.SnowFlake.GetId() + s.notPassNewCat = true + return s.key +} + +func (s *SelectedAnimal4Prefer) GetKey() int64 { // TODO 同上 + return s.key +} + +func (s *SelectedAnimal4Prefer) GetDataByKey(key int64) (bool, error) { + s.key = key + + redisClient := redis_factory.GetOneRedisClient() + defer redisClient.ReleaseOneRedisClient() + + if res, err := redisClient.String(redisClient.Execute("get", key)); err == nil { + json.Unmarshal([]byte(res), s) + return true, nil + } else { + return false, err + } +} + +func (s *SelectedAnimal4Prefer) SetDataByKey() (bool, error) { + redisClient := redis_factory.GetOneRedisClient() + defer redisClient.ReleaseOneRedisClient() + + data, _ := json.Marshal(s) + if _, err := redisClient.Execute("set", s.key, data); err == nil { + return true, nil + } else { + return false, err + } +}