diff --git a/doc/api.md b/doc/api.md index a8c6630..d75a3d1 100644 --- a/doc/api.md +++ b/doc/api.md @@ -114,6 +114,7 @@ result: 1, //答题结果 1: 正确, 0 : 错误 gameResult: 0, // 当前局游戏结果 0: 未完成, -1: 失败, 1: 胜利 answer: '正确答案', + over: 0.1222, // 超越玩家值, 显示时x100 "stats": { // 当局的状态 "1111": { "answer": {// 每一题的结果, key为题目的id, 值为answer在答案中的index值, 0为正确值, -1为超时, 其他都为错误 @@ -303,6 +304,7 @@ gameResult: 0, // 当前局游戏结果 0: 未完成, -1: 失败, 1: 胜利 overtime: 0, // 当前回答是否超时 0: 未超时, 1: 超时 answer: '正确答案', + over: 0.1222, // 超越玩家值, 显示时x100 "stats": { // 当局的状态 "1111": { "answer": {// 每一题的结果, key为题目的id, 值为answer在答案中的index值, 0为正确值, -1为超时, 其他都为错误 diff --git a/src/api/controllers/exam.controller.ts b/src/api/controllers/exam.controller.ts index 67a5e02..35d9bf6 100644 --- a/src/api/controllers/exam.controller.ts +++ b/src/api/controllers/exam.controller.ts @@ -174,7 +174,7 @@ class ExamController extends BaseController { session: history.id, } await history.save() - const { total } = await updateExamRank(rankObj) + const { total, over } = await updateExamRank(rankObj) let { rankList, userRank, rankTotal } = await getRank({ shop: history.shop, level: history.activityId, @@ -183,6 +183,7 @@ class ExamController extends BaseController { skip: 0, limit: 20, }) + rspData.over = over rspData.rankList = rankList rspData.userRank = userRank rspData.rankTotal = rankTotal diff --git a/src/api/controllers/puzzle.controller.ts b/src/api/controllers/puzzle.controller.ts index 8b41431..37b1567 100644 --- a/src/api/controllers/puzzle.controller.ts +++ b/src/api/controllers/puzzle.controller.ts @@ -162,7 +162,8 @@ class PuzzleController extends BaseController { mode: 0, session: history.id, } - await updateSingleRank(rankObj) + const { over } = await updateSingleRank(rankObj) + rspData.over = over } history.markModified('members') await history.save() diff --git a/src/redis/RedisClient.ts b/src/redis/RedisClient.ts index 3cb84dc..545adae 100644 --- a/src/redis/RedisClient.ts +++ b/src/redis/RedisClient.ts @@ -193,6 +193,17 @@ export class RedisClient { }) } + public async zcount(key: string, min: number, max: number) { + return new Promise((resolve, reject) => { + this.pub.zcount(key, min, max, (err, data) => { + if (err) { + return reject(err) + } + resolve(data) + }) + }) + } + public async zrevrank(key: string, member: string) { return new Promise((resolve, reject) => { this.pub.zrevrank(key, member, (err, data) => { diff --git a/src/services/GameLogic.ts b/src/services/GameLogic.ts index 28f4cf6..46b6270 100644 --- a/src/services/GameLogic.ts +++ b/src/services/GameLogic.ts @@ -169,7 +169,7 @@ export async function updateSingleRank({ session: string }) { const key = rankKey(shop, level, mode) - await updateRank(accountId, score, key) + const { over } = await updateRank(accountId, score, key) let record = (await PuzzleRank.findOrCreate({ shop, level, accountId, mode })).doc if (record.score < score) { @@ -180,6 +180,7 @@ export async function updateSingleRank({ let scoreTotal = await PuzzleRank.fetchTotalScore(shop, accountId, mode) const totalKey = rankKey(shop, 'total', mode) await updateRank(accountId, scoreTotal, totalKey) + return { over } } export async function updateExamRank({ @@ -198,10 +199,10 @@ export async function updateExamRank({ session: string }) { const singleKey = rankKey(shop, level, mode) - let single = await updateRank(accountId, score, singleKey) + let { scoreReal, over } = await updateRank(accountId, score, singleKey) const totalKey = rankKey(shop, level + '_total', mode) let total = await updateTotalRank(accountId, score, totalKey) - return { single, total } + return { single: scoreReal, total, over } } export async function getRank({ diff --git a/src/services/Rank.ts b/src/services/Rank.ts index cf003e4..093aecf 100644 --- a/src/services/Rank.ts +++ b/src/services/Rank.ts @@ -19,11 +19,30 @@ function generateRankKey(subKey?: string) { */ export async function updateRank(accountId: string, score: number, subKey?: string) { let scoreOld = await getAccountScore(accountId, subKey) + let scoreL = parseFloat(`${score | 0}.${MAX_TIME - Date.now()}`) + const key = generateRankKey(subKey) if (score > scoreOld) { - let scoreL = parseFloat(`${score | 0}.${MAX_TIME - Date.now()}`) - await new RedisClient().zadd(generateRankKey(subKey), scoreL, accountId) + await new RedisClient().zadd(key, scoreL, accountId) } - return Math.max(score, scoreOld) + const countTotal = (await new RedisClient().zcard(key)) as number + const countOver = (await new RedisClient().zcount(key, 0, scoreL)) as number + const over = countTotal ? countOver / countTotal : 0.99 + return { scoreReal: Math.max(score, scoreOld), over } +} + +/** + * 获取超越只 + * @param {string} accountId + * @param {number} score + * @param {string} subKey + * @return {Promise} + */ +export async function currentIdx(accountId: string, score: number, subKey?: string) { + const key = generateRankKey(subKey) + let countTotal = (await new RedisClient().zcard(key)) as number + let scoreL = parseFloat(`${score | 0}.${MAX_TIME - Date.now()}`) + let countOver = (await new RedisClient().zcount(key, 0, scoreL)) as number + return countOver / countTotal } /**