package pagoda import ( "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/log" "go_dreamfactory/lego/sys/redis" "go_dreamfactory/modules" "go_dreamfactory/pb" "sort" "time" "go.mongodb.org/mongo-driver/bson/primitive" ) var floorRankKey = "pagoda:floor" type ModelRank struct { modules.MCompModel modulePagoda *Pagoda } func (this *ModelRank) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) { this.TableName = comm.TablePagodaRecord err = this.MCompModel.Init(service, module, comp, options) this.modulePagoda = module.(*Pagoda) return } func (this *ModelRank) AddRank(uId string, data *pb.DBPagodaRecord) (err error) { if err = this.Add(uId, data); err != nil { //this.Errorf("err:%v", err) return } return nil } //获取用户通过扩展表 func (this *ModelRank) GetUserRandData(uid string) (result *pb.DBPagodaRecord, err error) { result = &pb.DBPagodaRecord{} if err = this.Get(uid, result); err != nil && redis.RedisNil != err { return } err = nil return result, err } func (this *ModelRank) ChangeUserRank(uid string, value map[string]interface{}) (err error) { if len(value) == 0 { return nil } return this.Change(uid, value) } func (this *ModelRank) GetRankData() (data []*pb.DBPagodaRecord, err error) { data = make([]*pb.DBPagodaRecord, 0) err = this.Redis.LRange(comm.TablePagodaRankList, 0, -1, &data) return } func (this *ModelRank) getPagodaRankList(uid string) []*pb.DBPagodaRecord { pagodaRank := make([]*pb.DBPagodaRecord, 0) err := this.GetList(uid, &pagodaRank) if err != nil { return nil } return pagodaRank } func (this *ModelRank) addPagodaList(session comm.IUserSession, data *pb.DBPagoda, Leadpos int32, line []*pb.LineUp, costTime int32) { userinfo := this.modulePagoda.ModuleUser.GetUser(session.GetUserId()) new := &pb.DBPagodaRecord{ Id: primitive.NewObjectID().Hex(), Uid: session.GetUserId(), PagodaId: data.PagodaId, Type: data.Type, Nickname: userinfo.Name, Icon: "", // icon 暂无 Lv: userinfo.Lv, CostTime: costTime, Line: line, } this.AddList(session.GetUserId(), new.Id, new) //写爬塔记录 // 查询本层是否上榜 rankData, ilen, err1 := this.GetFloorLastRankData(data.PagodaId) if err1 == nil { if ilen < comm.MaxRankNum || rankData.CostTime < costTime { this.ChangeFloorRankList(session, data.PagodaId, new) } } return } // 插入新的排行数据 func (this *ModelRank) addPagodaRankList(session comm.IUserSession, data *pb.DBSeasonPagoda, Leadpos int32, line []*pb.LineUp, costTime int32) { userinfo := this.modulePagoda.ModuleUser.GetUser(session.GetUserId()) new := &pb.DBPagodaRecord{ Id: primitive.NewObjectID().Hex(), Uid: session.GetUserId(), PagodaId: data.PagodaId, Type: data.Type, Nickname: userinfo.Name, Icon: "", // icon 暂无 Lv: userinfo.Lv, CostTime: costTime, } this.AddList(session.GetUserId(), new.Id, new) //写爬塔记录 // 查询本层是否上榜 rankData, ilen, err1 := this.GetFloorLastRankData(data.PagodaId) if err1 != nil { if rankData.CostTime < costTime || ilen < comm.MaxRankNum { this.ChangeFloorRankList(session, data.PagodaId, new) } } return } // 读取某一层排行数据 func (this *ModelRank) GetFloorRankList(floor int32) (result []*pb.DBPagodaRecord, err error) { key := fmt.Sprintf("%s-%d-rank", floorRankKey, floor) temp := make([]*pb.DBPagodaRecord, 0) if err = this.Redis.LRange(key, 0, -1, &temp); err != nil { this.modulePagoda.Errorf("err:%v", err) return } result = make([]*pb.DBPagodaRecord, len(temp)) for n, v := range temp { result[n] = v //n++ } return } // 获取排行榜最后一个元素 func (this *ModelRank) GetFloorLastRankData(floor int32) (curData *pb.DBPagodaRecord, len int, err error) { key := fmt.Sprintf("%s-%d-rank", floorRankKey, floor) len, err = this.Redis.Llen(key) if this.Redis.Lindex(key, -1, curData); err != nil { this.modulePagoda.Errorf("err:%v", err) return } return } // 修改某一层排行数据 func (this *ModelRank) ChangeFloorRankList(session comm.IUserSession, floor int32, curData *pb.DBPagodaRecord) (err error) { key := fmt.Sprintf("%s-%d-rank", floorRankKey, floor) lockkey := fmt.Sprintf("%s-%d-lock", floorRankKey, floor) this.Redis.Lock(lockkey, time.Now().Second()*5) defer this.Redis.UnLock(lockkey) if this.Redis.RPush(key, curData); err != nil { this.modulePagoda.Errorf("err:%v", err) return } temp := make([]*pb.DBPagodaRecord, 0) if err = this.Redis.LRange(key, 0, -1, &temp); err != nil { this.modulePagoda.Errorf("err:%v", err) return } // 排序 sort.SliceStable(temp, func(i, j int) bool { return temp[i].CostTime < temp[j].CostTime }) iLne := len(temp) if this.Redis.RPush(key, temp); err != nil { this.modulePagoda.Errorf("err:%v", err) return } if iLne > comm.MaxRankNum { iLne = comm.MaxRankNum } err = this.Redis.Ltrim(key, -1*iLne, -1) //对一个列表进行修剪 if err != nil { log.Errorf("delete failed") } return } func (this *ModelRank) getPagodaRankListByFloorid(uid string, floorid int32) *pb.DBPagodaRecord { pagodaRank := make([]*pb.DBPagodaRecord, 0) err := this.GetList(uid, &pagodaRank) if err != nil { return nil } for _, v := range pagodaRank { if v.PagodaId == floorid { return v } } return nil }