增加获取正确答案的接口

This commit is contained in:
zhl 2021-06-10 15:09:22 +08:00
parent 20fcd3d163
commit 7cc642e2ae
5 changed files with 99 additions and 27 deletions

View File

@ -736,3 +736,31 @@
| 字段 | 说明 | | 字段 | 说明 |
| -------- | -------------------------------------- | | -------- | -------------------------------------- |
| ids | 邮件id数组 | | ids | 邮件id数组 |
### 21. 显示正确答案
1. Method: POST
2. <span id="215">URI: /api/:accountId/puzzle/help</span>
| 字段 | 说明 |
| -------- | -------------------------------------- |
| accountid | 帐号id |
> POST参数
| 字段 | 说明 |
| -------- | -------------------------------------- |
| id | 题目id |
| session | 当局的id, 从关卡题目列表中获取 |
3. Response: JSON
```js
{
answer: '1123123'
}
```
> 说明, 这里获取的answer是使用 当前比赛session_当前题目的id_答案_jcfw中的sessionid, 计算md5

View File

@ -25,6 +25,8 @@ import { Shop, validShopId } from '../../models/shop/Shop'
import { ShopActivity } from '../../models/shop/ShopActivity' import { ShopActivity } from '../../models/shop/ShopActivity'
import { GameUser } from '../../models/user/GameUser' import { GameUser } from '../../models/user/GameUser'
import { isObjectId } from '../../utils/string.util' import { isObjectId } from '../../utils/string.util'
import { SINGLE_HELP_COUNT } from '../../constants/BaseConst'
import { md5 } from '../../utils/security.util'
class PuzzleController extends BaseController { class PuzzleController extends BaseController {
@role('anon') @role('anon')
@ -44,9 +46,9 @@ class PuzzleController extends BaseController {
} }
@role('anon') @role('anon')
@router('post /api/:accountid/puzzle/list') @router('post /api/:accountId/puzzle/list')
async list(req, res) { async list(req, res) {
let { shop, level, accountid, type } = req.params let { shop, level, accountId, type } = req.params
level = +level || 1 level = +level || 1
if (!shop || !validShopId(shop)) { if (!shop || !validShopId(shop)) {
throw new ZError(10, `type: ${type} level:${level} 没有店铺id或者店铺id格式不正确, ${shop}`) throw new ZError(10, `type: ${type} level:${level} 没有店铺id或者店铺id格式不正确, ${shop}`)
@ -62,7 +64,7 @@ class PuzzleController extends BaseController {
let record3 = await Puzzle.randomQuestions(Object.assign(params, { quality: 3 }), 5) let record3 = await Puzzle.randomQuestions(Object.assign(params, { quality: 3 }), 5)
const records = record1.concat(record2).concat(record3) const records = record1.concat(record2).concat(record3)
let history = new PuzzleSession({ shop: shopId, level }) let history = new PuzzleSession({ shop: shopId, level })
history.members.set(accountid, new PuzzleStatusClass()) history.members.set(accountId, new PuzzleStatusClass())
for (let record of records) { for (let record of records) {
history.questions.set(record.id, record.compactRecord(true)) history.questions.set(record.id, record.compactRecord(true))
} }
@ -79,9 +81,9 @@ class PuzzleController extends BaseController {
} }
@role('anon') @role('anon')
@router('post /api/:accountid/puzzle/answer') @router('post /api/:accountId/puzzle/answer')
async report(req, res) { async report(req, res) {
let { id, answer, type, session, accountid, mode, debug } = req.params let { id, answer, type, session, accountId, mode, debug } = req.params
mode = mode || 0 mode = mode || 0
if (!id || !session) { if (!id || !session) {
throw new ZError(11, 'param mismatch') throw new ZError(11, 'param mismatch')
@ -90,7 +92,7 @@ class PuzzleController extends BaseController {
if (!history) { if (!history) {
throw new ZError(13, 'not found match info') throw new ZError(13, 'not found match info')
} }
if (!history.members.has(accountid)) { if (!history.members.has(accountId)) {
throw new ZError(14, 'not in current match') throw new ZError(14, 'not in current match')
} }
if (!history.questions.has(id)) { if (!history.questions.has(id)) {
@ -105,7 +107,7 @@ class PuzzleController extends BaseController {
if (history.status == 9 || history.hasExpired()) { if (history.status == 9 || history.hasExpired()) {
result = -1 result = -1
} }
let statMap = history.members.get(accountid) let statMap = history.members.get(accountId)
if (statMap.answer.has(id)) { if (statMap.answer.has(id)) {
throw new ZError(15, 'current question already answered') throw new ZError(15, 'current question already answered')
} }
@ -136,8 +138,8 @@ class PuzzleController extends BaseController {
if (record.type === 3) { if (record.type === 3) {
score = 0 score = 0
} }
await broadcast(history.room, 'answer', { accountid, result, score }) await broadcast(history.room, 'answer', { accountid: accountId, result, score })
await updateScore(history.room, [{ accountid, score }]) await updateScore(history.room, [{ accountid: accountId, score }])
if (checkSubFinish(history, id)) { if (checkSubFinish(history, id)) {
if (new Schedule().getLeftTime(history.scheduleKey) > 1000) { if (new Schedule().getLeftTime(history.scheduleKey) > 1000) {
@ -154,15 +156,15 @@ class PuzzleController extends BaseController {
await sendOneQuestion(history) await sendOneQuestion(history)
} }
} else if (mode == 0) { } else if (mode == 0) {
gameResult = checkSingleFinish(history, accountid) gameResult = checkSingleFinish(history, accountId)
if (gameResult) { if (gameResult) {
history.status = 9 history.status = 9
if (gameResult === 1) { if (gameResult === 1) {
let { score } = calcSingleScore(history, accountid) let { score } = calcSingleScore(history, accountId)
let rankObj = { let rankObj = {
shop: history.shop, shop: history.shop,
level: history.level, level: history.level,
accountId: accountid, accountId: accountId,
score, score,
mode: 0, mode: 0,
session: history.id, session: history.id,
@ -174,7 +176,7 @@ class PuzzleController extends BaseController {
let { rankList, userRank } = await getRank({ let { rankList, userRank } = await getRank({
shop: history.shop, shop: history.shop,
level: history.level, level: history.level,
accountId: accountid, accountId: accountId,
mode: 0, mode: 0,
skip: 0, skip: 0,
limit: 20, limit: 20,
@ -188,9 +190,9 @@ class PuzzleController extends BaseController {
} }
@role('anon') @role('anon')
@router('post /api/:accountid/puzzle/more') @router('post /api/:accountId/puzzle/more')
async moreLevelQuestions(req, res) { async moreLevelQuestions(req, res) {
let { session, accountid, count, quality } = req.params let { session, accountId, count, quality } = req.params
count = count ? +count : 10 count = count ? +count : 10
if (!session) { if (!session) {
throw new ZError(11, 'param mismatch') throw new ZError(11, 'param mismatch')
@ -204,7 +206,7 @@ class PuzzleController extends BaseController {
await history.save() await history.save()
throw new ZError(17, 'match end') throw new ZError(17, 'match end')
} }
if (!history.members.has(accountid)) { if (!history.members.has(accountId)) {
throw new ZError(14, 'not in current match') throw new ZError(14, 'not in current match')
} }
let ids = Array.from(history.questions.keys()) let ids = Array.from(history.questions.keys())
@ -226,10 +228,10 @@ class PuzzleController extends BaseController {
} }
@role('anon') @role('anon')
@router('post /api/:accountid/puzzle/match') @router('post /api/:accountId/puzzle/match')
async joinMultipleGame(req, res) { async joinMultipleGame(req, res) {
let { shop, aid, accountid, debug_begin_sec, debug_qcount } = req.params let { shop, aid, accountId, debug_begin_sec, debug_qcount } = req.params
let data: any = { shop, maxTime: 3600, accountid } let data: any = { shop, maxTime: 3600, accountid: accountId }
let beginSecond = debug_begin_sec ? +debug_begin_sec : 10 let beginSecond = debug_begin_sec ? +debug_begin_sec : 10
beginSecond = Math.max(2, beginSecond) * 1000 beginSecond = Math.max(2, beginSecond) * 1000
/** /**
@ -247,7 +249,7 @@ class PuzzleController extends BaseController {
} }
let activity = await ShopActivity.findById(aid) let activity = await ShopActivity.findById(aid)
let shopData = await Shop.fetchByID(shop) let shopData = await Shop.fetchByID(shop)
let gameUser = await GameUser.getByAccountID(accountid) let gameUser = await GameUser.getByAccountID(accountId)
if (gameUser) { if (gameUser) {
data.nickname = gameUser.nickname data.nickname = gameUser.nickname
data.avatar = gameUser.avatar data.avatar = gameUser.avatar
@ -277,7 +279,7 @@ class PuzzleController extends BaseController {
if (history && !history.hasExpired()) { if (history && !history.hasExpired()) {
beginTime = history.begin beginTime = history.begin
sessionMatch = history.id sessionMatch = history.id
if (!history.members.has(accountid)) { if (!history.members.has(accountId)) {
let rsp = await joinRoom(Object.assign(data, { roomId: history.room })) let rsp = await joinRoom(Object.assign(data, { roomId: history.room }))
if (rsp.status != 200) { if (rsp.status != 200) {
new RoomState().unlock(shop) new RoomState().unlock(shop)
@ -286,13 +288,13 @@ class PuzzleController extends BaseController {
let memberData = new PuzzleStatusClass() let memberData = new PuzzleStatusClass()
sessionId = rsp.data?.sessionId sessionId = rsp.data?.sessionId
memberData.sessionId = sessionId memberData.sessionId = sessionId
history.members.set(accountid, memberData) history.members.set(accountId, memberData)
history.markModified('members') history.markModified('members')
await history.save() await history.save()
new RoomState().unlock(shop) new RoomState().unlock(shop)
return (roomId = history.room) return (roomId = history.room)
} else { } else {
let memberData = history.members.get(accountid) let memberData = history.members.get(accountId)
sessionId = memberData.sessionId sessionId = memberData.sessionId
roomId = history.room roomId = history.room
new RoomState().unlock(shop) new RoomState().unlock(shop)
@ -310,7 +312,7 @@ class PuzzleController extends BaseController {
history.activityId = aid history.activityId = aid
let memberData = new PuzzleStatusClass() let memberData = new PuzzleStatusClass()
memberData.sessionId = sessionId memberData.sessionId = sessionId
history.members.set(accountid, memberData) history.members.set(accountId, memberData)
history.room = roomId history.room = roomId
//TODO: 根据配置赋值 //TODO: 根据配置赋值
history.total = debug_qcount || activity.qcount history.total = debug_qcount || activity.qcount
@ -363,4 +365,38 @@ class PuzzleController extends BaseController {
let { rankList, userRank, rankTotal } = await getRank({ shop, level, accountId, mode, skip, limit }) let { rankList, userRank, rankTotal } = await getRank({ shop, level, accountId, mode, skip, limit })
return { rankList, userRank, rankTotal } return { rankList, userRank, rankTotal }
} }
@role('anon')
@router('post /api/:accountId/puzzle/help')
async help(req) {
let { id, session, accountId, sessionid } = req.params
if (!id || !session) {
throw new ZError(11, 'param mismatch')
}
let history = await PuzzleSession.findById(session)
if (!history) {
throw new ZError(13, 'not found match info')
}
if (!history.hasExpired()) {
throw new ZError(18, 'match has expired')
}
if (history.type !== 0) {
throw new ZError(18, 'only available in single mode')
}
if (history.helpCount >= SINGLE_HELP_COUNT) {
throw new ZError(17, 'reach max count')
}
if (!history.members.has(accountId)) {
throw new ZError(14, 'not in current match')
}
if (!history.questions.has(id)) {
throw new ZError(16, 'current question not in current match')
}
let record = history.questions.get(id)
history.helpCount += 1
await history.save()
let hashStr = `${session}_${id}_${record.answers[0]}_${sessionid}`
let hash = md5(hashStr)
return { answer: hash }
}
} }

View File

@ -13,3 +13,5 @@ export class BaseConst {
// 抽奖券的物品id // 抽奖券的物品id
export const LOTTERY_TICKET = 'lottery_ticket' export const LOTTERY_TICKET = 'lottery_ticket'
export const EMPTY = 'empty' export const EMPTY = 'empty'
// 单人模式使用显示答案次数
export const SINGLE_HELP_COUNT = 999

View File

@ -1,6 +1,6 @@
import { FindOrCreate } from '@typegoose/typegoose/lib/defaultClasses' import { FindOrCreate } from '@typegoose/typegoose/lib/defaultClasses'
import { checkJson, noJson } from '../decorators/nojson' import { checkJson } from '../decorators/nojson'
import { plugin, prop, ReturnModelType } from '@typegoose/typegoose' import { plugin, ReturnModelType } from '@typegoose/typegoose'
// @ts-ignore // @ts-ignore
import findOrCreate from 'mongoose-findorcreate' import findOrCreate from 'mongoose-findorcreate'
@ -8,7 +8,6 @@ import { Connection } from 'mongoose'
import { ObjectId } from 'bson' import { ObjectId } from 'bson'
import { isTrue } from '../utils/string.util' import { isTrue } from '../utils/string.util'
import { AnyParamConstructor } from '@typegoose/typegoose/lib/types' import { AnyParamConstructor } from '@typegoose/typegoose/lib/types'
import { SysMail } from './content/SysMail'
const jsonExcludeKeys = ['updatedAt', '__v'] const jsonExcludeKeys = ['updatedAt', '__v']
const saveExcludeKeys = ['createdAt', 'updatedAt', '__v', '_id'] const saveExcludeKeys = ['createdAt', 'updatedAt', '__v', '_id']

View File

@ -197,6 +197,13 @@ export class PuzzleSessionClass extends BaseModule {
@prop() @prop()
public expire: number public expire: number
/**
* ,
* @type {number}
*/
@prop({ default: 0 })
public helpCount: number
public hasExpired(): boolean { public hasExpired(): boolean {
return this.expire < Date.now() return this.expire < Date.now()
} }