diff --git a/src/api/controllers/puzzle.controller.ts b/src/api/controllers/puzzle.controller.ts index c24529d..e80bff5 100644 --- a/src/api/controllers/puzzle.controller.ts +++ b/src/api/controllers/puzzle.controller.ts @@ -68,7 +68,9 @@ class PuzzleController extends BaseController { const records = (record1.concat(record2)).concat(record3) let history = new PuzzleSession({ shop, level }) history.members.set(accountid, new PuzzleStatusClass()) - history.questions = records.map(o => o._id) + for (let record of records) { + history.questions.set(record.id, record.a1) + } history.expire = Date.now() + (cfg.time || 90) * 1000 history.type = 0 history.difficultyMode = type || 0 @@ -93,23 +95,20 @@ class PuzzleController extends BaseController { if (!history) { throw new ZError(13, 'not found match info') } - let record = await Puzzle.findById(id) - if (!record) { - throw new ZError(12, 'question not found') + if (!history.members.has(accountid)) { + throw new ZError(14, 'not in current match') } - let result = record.a1 == answer ? 1 : 0 + if (!history.questions.has(id)) { + throw new ZError(16, 'current question not in current match') + } + let record = history.questions.get(id) + let result = record === answer ? 1 : 0 if (type == 1) { result = 0 } if (history.status == 9 || history.hasExpired()) { result = 0 } - if (!history.members.has(accountid)) { - throw new ZError(14, 'not in current match') - } - if (!history.questions.find(o => o == id)) { - throw new ZError(16, 'current question not in current match') - } let statMap = history.members.get(accountid) if (statMap.answer.has(id)) { throw new ZError(15, 'current question already answered') @@ -128,7 +127,7 @@ class PuzzleController extends BaseController { history.markModified('members') let gameResult = 0 await history.save() - let rspData: any = { result, answer: record.a1, stats: history.members } + let rspData: any = { result, answer: record, stats: history.members } if (mode == 1) { let score = result ? calcPvpScore(history.scheduleKey, statMap.comboCount) : 0 await broadcast(history.room, 'answer', {accountid, result, score}) @@ -184,7 +183,7 @@ class PuzzleController extends BaseController { if (!history.members.has(accountid)) { throw new ZError(14, 'not in current match') } - let ids = history.questions.map(o => new ObjectId(o)) + let ids = Array.from(history.questions.keys()) let options: any = {'_id': {$nin: ids}} if (quality) { options.quality = quality @@ -194,7 +193,9 @@ class PuzzleController extends BaseController { } let records = await Puzzle.randomQuestions(options, count) const results = transformRecord(records) - history.questions = history.questions.concat(records.map(o => o._id)) + for (let record of records) { + history.questions.set(record.id, record.a1) + } history.markModified('questions') await history.save() return results diff --git a/src/models/match/PuzzleSession.ts b/src/models/match/PuzzleSession.ts index 6c4411a..f1179e8 100644 --- a/src/models/match/PuzzleSession.ts +++ b/src/models/match/PuzzleSession.ts @@ -75,8 +75,8 @@ export class PuzzleSessionClass extends BaseModule { @prop({ _id: false, type: PuzzleStatusClass, default: new Map() }) public members: Map - @prop({ type: () => [String] }) - public questions: string[] + @prop({ _id: false, type: String, default: new Map() }) + public questions: Map @prop() public shop: string diff --git a/src/models/shop/ShopExam.ts b/src/models/shop/ShopExam.ts new file mode 100644 index 0000000..66aea19 --- /dev/null +++ b/src/models/shop/ShopExam.ts @@ -0,0 +1,135 @@ +import { dbconn } from '../../decorators/dbconn' +import { + getModelForClass, index, + modelOptions, + prop +} from '@typegoose/typegoose' +import { BaseModule } from '../Base' +import { noJson } from '../../decorators/nojson' +import { Severity } from '@typegoose/typegoose/lib/internal/constants' + +export class ExamRewardClass { + @prop() + public id: number + @prop() + public rank: number + + @prop() + public rankEnd?: number + + @prop() + public coupon: string + + @prop({default: 0}) + public count: number +} +@dbconn() +@index({ shop:1 }, { unique: false }) +@modelOptions({schemaOptions: {collection: "shop_exam", timestamps: true}, options: {allowMixed: Severity.ALLOW}}) +export class ShopExamClass extends BaseModule { + /** + * 所属店铺 + * @type {string} + */ + @prop() + public shop: string + /** + * 活动名 + * @type {string} + */ + @prop() + public name: string + /** + * 简单的说明文字 + * @type {string} + */ + @prop() + public desc: string + + /** + * 已选择的题库分类 + * @type {string[]} + */ + @prop({ type: () => [String] }) + public qtypes: string[] + /** + * 单次活动题目数量, 0为所有 + * @type {number} + */ + @prop({default: 10}) + public qcount: number + + /** + * 每道题的回答时间 + * @type {number} + */ + @prop({default: 5}) + public timePer: number + + /** + * 活动正式开始时间, 从0点开始 + * @type {number} + */ + @prop({ type: () => [Number] }) + public beginTime: number[] + + /** + * 结束时间 + * @type {number[]} + */ + @prop({ type: () => [Number] }) + public endTime: number[] + + @prop({_id: false, type: [ExamRewardClass]}) + public rewardInfo: ExamRewardClass[]; + /** + * 是否启用 + * @type {number} + */ + @prop({default: false}) + public active: boolean + + /** + * 是否删除 + * @type {boolean} + */ + @noJson() + @prop({default: false}) + public deleted: boolean + @noJson() + @prop() + public deleteTime: Date + + /** + * 创建人 + * @type {string} + */ + @prop() + public createdBy: string + + public static parseQueryParam(params) { + let {key, timeBegin, timeEnd, active, shop} = params + let opt: any = {deleted: false} + if (key) { + opt.name = {$regex: key, $options: 'i'} + } + if (timeBegin && !timeEnd) { + opt.createdAt = {$gte: timeBegin}; + } else if (timeBegin && timeEnd) { + opt['$and'] = [{createdAt: {$gte: timeBegin}}, {createdAt: {$lte: timeEnd}}]; + } else if (!timeBegin && timeEnd) { + opt.createdAt = {$lte: timeEnd}; + } + if (active != undefined) { + opt.active = active + } + if (shop) { + opt.shop = shop + } + + let sort = {_id: -1} + return { opt, sort } + } +} + +export const ShopExam = getModelForClass(ShopExamClass, { existingConnection: ShopExamClass.db }) diff --git a/src/services/GameLogic.ts b/src/services/GameLogic.ts index dacbe49..6b15223 100644 --- a/src/services/GameLogic.ts +++ b/src/services/GameLogic.ts @@ -66,7 +66,10 @@ export async function startGame(roomId: string, sessionId: string) { let history = await PuzzleSession.findById(sessionId) let records = await Puzzle.randomQuestions({status: 1, is_hide: 0, deleted: 0, dp: 1}, history.total) await beginGame(roomId, {}) - history.questions = records.map(o => o._id) + for (let record of records) { + history.questions.set(record.id, record.a1) + } + history.markModified('questions') await history.save() new Schedule().beginSchedule(BaseConst.FIST_QUESTION_DELAY, async function () { await sendOneQuestion(history) @@ -84,8 +87,8 @@ export async function sendOneQuestion(history: any) { await endGame(roomId, {closeTime: BaseConst.ROOM_AUTO_CLOSE_TIME}) return } - - let qid = history.questions[history.current] + const questions = Array.from(history.questions.keys()) + let qid = questions[history.current] let record = await Puzzle.findById(qid) let qdata: any = transformRecord([record])[0] qdata.no = history.current