153 lines
4.4 KiB
JavaScript
153 lines
4.4 KiB
JavaScript
const app = require('j7/app');
|
||
const utils = require('j7/utils');
|
||
const constant = require('../constant');
|
||
const Redis = require('../services/redis');
|
||
|
||
const RANKING_KEY = 'game2006api:';
|
||
const LAST_IDX = 'userLastIdx';
|
||
|
||
class Rankings {
|
||
|
||
async start() {
|
||
console.log('Rankings.start');
|
||
while (true) {
|
||
await this.doRanking();
|
||
const sleepTime = 60*60*2
|
||
console.log('sleepTime:' + sleepTime, new Date(), sleepTime /60);
|
||
await utils.sleep(sleepTime * 1000);
|
||
}
|
||
|
||
}
|
||
|
||
async doRanking() {
|
||
try {
|
||
const {err, conn} = await app.getDbConn("GameDb20060");
|
||
if (err){
|
||
throw err
|
||
}
|
||
if (await Redis.exists(RANKING_KEY + "account")){
|
||
await Redis.del(RANKING_KEY + 'account')
|
||
await Redis.del(RANKING_KEY + 'ranking')
|
||
await this.calcRanking();
|
||
console.log("跟新rank榜单")
|
||
}else {
|
||
await this.calcRanking();
|
||
console.log("生成rank榜单")
|
||
}
|
||
}catch (err){
|
||
console.log(err);
|
||
}
|
||
}
|
||
|
||
//计算用户排行榜
|
||
async calcRanking() {
|
||
console.log("calc ranking...");
|
||
const {err, conn} = await app.getDbConn("GameDb20060");
|
||
if (err) {
|
||
throw err;
|
||
}
|
||
if (!err && conn) {
|
||
// 从user表中遍历所有用户,每次取1000个用户,逐步加入到排序表中
|
||
let sorted = [];
|
||
let lastIdx = 0;
|
||
while(lastIdx>=0) {
|
||
const result = await this.getRecords(conn, lastIdx, 1000);
|
||
lastIdx = result.lastIdx;
|
||
|
||
if (lastIdx != -1) {
|
||
this.recordsSort(sorted, result.records)
|
||
}
|
||
}
|
||
await this.pushResultToRedis(sorted);
|
||
|
||
// let rankList = await this.pushRankingResult(sorted);
|
||
// console.log(rankList);
|
||
|
||
//存储到redis中
|
||
// let listJson = JSON.stringify(rankList);
|
||
// Redis.set(RANKING_KEY + "rank",listJson);
|
||
console.log("calc ranking end");
|
||
|
||
}
|
||
}
|
||
|
||
//增加排名列
|
||
async pushResultToRedis(sorted) {
|
||
let rankingList = [];
|
||
await utils.serial(
|
||
sorted,
|
||
(value , index) =>{
|
||
value.ranking = index+1
|
||
Redis.hset(RANKING_KEY + "ranking",value.ranking,value.account_id)
|
||
Redis.hset(RANKING_KEY + "account",value.account_id,value.ranking)
|
||
}
|
||
)
|
||
}
|
||
|
||
//获取用户记录
|
||
async getRecords(conn, lastIdx, limit) {
|
||
const {err, rows} = await conn.execQuery(
|
||
'select idx,account_id,channel,convert(`name` using utf8) as name,head_id,head_frame,rank,history_best_rank,score,history_best_score,createtime, score_modifytime from t_user where idx > ? order by idx LIMIT ?',
|
||
[
|
||
lastIdx,
|
||
limit
|
||
]
|
||
);
|
||
if (err) {
|
||
throw err;
|
||
}
|
||
if (rows.length==0) {
|
||
return {
|
||
lastIdx: -1,
|
||
records: []
|
||
};
|
||
}
|
||
// Redis.set(LAST_IDX,rows[rows.length-1].idx)
|
||
return {
|
||
lastIdx: rows[rows.length-1].idx,
|
||
records: rows
|
||
};
|
||
}
|
||
|
||
//给记录按分数排序
|
||
recordsSort(sorted, records) {
|
||
// 根据分数加入到排序表中
|
||
for (let element of records) {
|
||
if (element.score>2800) {
|
||
if (sorted.length >= 10000){
|
||
if (element.score >= sorted[sorted.length - 1].score){
|
||
sorted.pop()
|
||
this._recordsSort(sorted,element)
|
||
}
|
||
} else {
|
||
this._recordsSort(sorted,element)
|
||
}
|
||
}
|
||
}
|
||
// if (sorted.length>10000) {
|
||
// sorted.length = 10000;
|
||
// }
|
||
}
|
||
|
||
_recordsSort(sorted,element){
|
||
sorted.push(element);
|
||
sorted.sort(function(a,b) {
|
||
let r = b.score - a.score;
|
||
if (r==0) {
|
||
r = a.score_modifytime - b.score_modifytime;
|
||
}
|
||
if (r==0) {
|
||
r = a.idx - b.idx;
|
||
}
|
||
return r;
|
||
});
|
||
}
|
||
|
||
}
|
||
|
||
function init() {
|
||
(new Rankings()).start();
|
||
}
|
||
|
||
exports.init = init;
|