import { dbconn } from '../../decorators/dbconn' import { getModelForClass, modelOptions, prop } from '@typegoose/typegoose' import { BaseModule } from '../Base' import { Severity } from '@typegoose/typegoose/lib/internal/constants' import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses' export class CompactPuzzleClass { @prop() id: string @prop() title: string @prop({ type: () => [String] }) public answers: string[] //1: 普通的文字选择题, 2: 图形, 3: 问卷式题目 @prop() public type: number @prop() public category: string @prop() public quality: number /** * 题目来源 * 0: 系统题库 * 1: 自定义 * @type {number} */ @prop() public source: number public toJson() { let answers = this.answers.slice(0) answers.randomSort() return { id: this.id, title: this.title, answers: answers, type: this.type, category: this.category, quality: this.quality, } } } @modelOptions({ options: { allowMixed: Severity.ALLOW }, }) export class PuzzleStatusClass { @prop({ type: Number, default: new Map() }) answer: Map @prop({ default: 0 }) total: number /** * 打对数量 * @type {number} */ @prop({ default: 0 }) rightCount: number /** * 答错数量 * @type {number} */ @prop({ default: 0 }) errorCount: number /** * 当前连击数 * @type {number} */ @prop({ default: 0 }) comboCount: number /** * 最大连击数 * @type {number} */ @prop({ default: 0 }) maxCombo: number /** * 多人模式中, 该玩家在房间中的sessionId, 用于重连 * @type {string} */ @prop() sessionId: string /** * 游戏胜利后的得分 * @type {number} */ @prop({ default: 0 }) score: number @prop({ default: 0 }) star: number @prop() timeLeft: number /** * 最后一次答题时间 * @type {number} */ @prop() timeLast: number /** * 游戏结果 * @type {number} */ @prop({ default: 0 }) public gameResult: number } // @ts-ignore export interface PuzzleSessionClass extends Base, TimeStamps {} @dbconn() @modelOptions({ schemaOptions: { collection: 'puzzle_session', timestamps: true } }) export class PuzzleSessionClass extends BaseModule { @prop({ _id: false, type: PuzzleStatusClass, default: new Map() }) public members: Map @prop({ _id: false, type: CompactPuzzleClass, default: new Map() }) public questions: Map @prop() public shop: string @prop() public level: number /** * 活动或者挑战, 可将相关的id存入该字段 * @type {string} */ @prop() public activityId: string @prop() public room: string /** * 类型 * 0: 单人 * 1: 多人 * 2: 测验 * @type {number} */ @prop({ default: 0 }) public type: number /** * 模式 * 0: 普通 * 1: 减低难度 * @type {number} */ @prop({ default: 0 }) public difficultyMode: number /** * 当前的问题 * @type {number} */ @prop({ default: 0 }) public current: number /** * 一共多少问题 * @type {number} */ @prop() public total: number /** * 每一题回答时间 * @type {number} */ @prop() public timeone: number /** * 比赛状态 * 0: 未开始答题 * 1: 答题进行中 * 9: 结束 * @type {number} */ @prop({ default: 0 }) public status: number /** * 已选择的题库分类 * @type {string[]} */ @prop({ type: () => [String] }) public qtypes: string[] /** * 开始时间 * 对于多人比赛来说, 需要一个自动开始时间 * @type {number} */ @prop() public begin: number @prop() public expire: number /** * 获取正确答案次数, 只针对单人模式 * @type {number} */ @prop({ default: 0 }) public helpCount: number public hasExpired(): boolean { return this.expire < Date.now() } public get scheduleKey() { // @ts-ignore return this.room + this._id } public static parseQueryParam(params) { let { exam, timeBegin, timeEnd, shop } = params let opt: any = { type: 2 } if (shop) { opt.shop = shop } if (exam) { opt.activityId = exam } if (timeBegin && !timeEnd) { opt.createdAt = { $gte: new Date(timeBegin) } } else if (timeBegin && timeEnd) { opt['$and'] = [{ createdAt: { $gte: new Date(timeBegin) } }, { createdAt: { $lte: new Date(timeEnd) } }] } else if (!timeBegin && timeEnd) { opt.createdAt = { $lte: new Date(timeEnd) } } let sort = { _id: 1 } return { opt, sort } } public toPartnerJson() { const exportKeys = ['_id', 'status', 'createdAt', 'type', 'activityId'] let result: any = {} for (let key of exportKeys) { result[key] = this[key] } result.qcount = this.questions.size let questions: any = [] const accountId = this.members.keys().next().value const udata = this.members.get(accountId) result.accountId = accountId for (let [key, data] of this.questions) { let obj = { title: data.title, answers: data.answers, answer: udata.answer.has(key) ? udata.answer.get(key) : -1, } questions.push(obj) } result.questions = questions return result } } export const PuzzleSession = getModelForClass(PuzzleSessionClass, { existingConnection: PuzzleSessionClass.db })