package service import ( "context" "gitea.youtukeji.com.cn/xiabin/douyin-openapi/cache" "gitea.youtukeji.com.cn/xiabin/youtu_ecpm/dao/model" "gitea.youtukeji.com.cn/xiabin/youtu_ecpm/dao/query" "strconv" "sync" ) type RankingList struct { q *query.Query cache cache.Cache lock sync.Mutex } func NewRankingList(q *query.Query, c cache.Cache) *RankingList { return &RankingList{q, c, sync.Mutex{}} } type RankingListData struct { Nickname string `gorm:"column:nickname;type:varchar(255);not null;comment:昵称" json:"nickname"` // 昵称 Avatar string `gorm:"column:avatar;type:varchar(255);not null;comment:头像" json:"avatar"` // 头像 Score uint32 `gorm:"column:score;type:int unsigned;not null" json:"score"` } func (s *RankingList) GetRankingList(ctx context.Context, appId uint32) (res []RankingListData, err error) { if val := s.cache.Get(strconv.Itoa(int(appId))); val != nil { res = val.([]RankingListData) return } s.lock.Lock() defer s.lock.Unlock() if val := s.cache.Get(strconv.Itoa(int(appId))); val != nil { res = val.([]RankingListData) return } //get data aui := s.q.AppUserInfo gameScore := s.q.GameScore err = gameScore.WithContext(ctx). Join(aui, gameScore.AppUserID.EqCol(aui.ID)). Select(gameScore.Score, aui.Nickname, aui.Avatar). Where(gameScore.AppAccount.Eq(appId)). Order(gameScore.Score.Desc()). Limit(20).Scan(&res) if err != nil { return } //Cache err = s.cache.Set(strconv.Itoa(int(appId)), res, 60) if err != nil { return } return } func (s *RankingList) SetScore(ctx context.Context, appId uint32, userId uint64, score uint32) (err error) { err = s.q.GameScore.WithContext(ctx).Save(&model.GameScore{ AppAccount: appId, AppUserID: userId, Score: score, }) if err != nil { return } //Cache if val := s.cache.Get(strconv.Itoa(int(appId))); val != nil { list := val.([]RankingListData) lastScore := list[len(list)-1].Score if score > lastScore { s.lock.Lock() defer s.lock.Unlock() aui := s.q.AppUserInfo user, err := aui.WithContext(ctx).Where(aui.ID.Eq(userId)).Select(aui.Nickname, aui.Avatar).Take() if err != nil { return err } rank := RankingListData{user.Nickname, user.Avatar, score} if len(list) < 20 { list = append(list, rank) } else { list[len(list)-1] = rank } err = s.cache.Set(strconv.Itoa(int(appId)), list, 60) if err != nil { return err } } } return }