import { MongoBaseService } from "cgserver"; import { MongoBaseModel } from "cgserver"; import { GLog } from "cgserver"; import { ExtUserModel, GExtUserSer } from "./ExtUserService"; export class RankModel extends MongoBaseModel { key: string = "" list = new Array<{ data: number, count: number }>() } class RankUser { id = -1 nickname = "" logo = "" data = -1 } export let GRankSer: RankService = null class RankService extends MongoBaseService { protected _top = 100 protected _rank_top: { [key: string]: Array } = {} getTop(key:"rank_coin_all") { return this._rank_top[key]||[] } async init() { GLog.info("begin init rank!") this._rank_top["rank_coin_all"] = await GExtUserSer.gets({ id: 1, nickname: 1, logo: 1, coin: 1 }, {}, { coin: 1 }, 0, this._top) GLog.info("end init rank!") } protected async _getData(where):Promise { let one = await this.get({"list.$":1},where) if(!one||!one.list||one.list.length==0) { return null } return one.list[0] } async addData(key: "rank_coin_all", user_id: number, data: number, pre_data: number) { let ru = await this._getData({key: key,"list.data":data}) if(ru) { await this.updateOne({ $inc: { 'list.$.count': 1 } }, { key: key, list: { $elemMatch: { data: data } } }) } else { await this.updateOne({ $push: { list: {data:data,count:1} } }, { key: key },true) } ru = await this._getData({key: key,"list.data":pre_data}) if(ru) { await this.updateOne({ $inc: { 'list.$.count': -1 } }, { key: key, list: { $elemMatch: { data: pre_data } } }) } //之前名次小于最后一名,现在名次大于最后一名 this._rank_top[key] = this._rank_top[key] || [] let rus = this._rank_top[key] let need_push = false let need_sort = false if (rus.length > 0) { if (rus.length < this._top) { need_push = true need_sort = true } else { let index = rus.findIndex((ru) => { return ru.id == user_id }) if (index >= 0) { need_sort = true rus[index].data = data } let last = rus[rus.length - 1] if (data > last.data) { //上榜原本不在 if (index < 0) { rus.pop() need_push = true } //原本就在 need_sort = true } } } else { need_push = true need_sort = true } if (need_push) { let rn = await GExtUserSer.get({ id: 1, nickname: 1, logo: 1, coin: 1 }, { id: user_id }) rus.push(rn) } if (need_sort) { rus.sort((a, b) => { return b.data - a.data }) } } async getOneRank(key: "rank_coin_all", data: number,user_id:number) { this._rank_top[key]=this._rank_top[key]||[] let rus = this._rank_top[key] let index = rus.findIndex((ru)=> { return ru.id==user_id }) if(index>=0) { return index+1 } let agg = this.aggregate([ { "$match": { key: key } }, { "$unwind": "$list" }, { "$match": { 'list.data': { $gt: data } } }, { "$group": { _id: 0, count: { $sum: '$list.count' } } } ]) let rk = await agg.toArray() if (!rk||rk.length==0||!rk[0].list||rk[0].list.length==0) { return 1 } return rk[0].list[0].count + 1 } } GRankSer = new RankService("rank", RankModel)