237 lines
4.9 KiB
TypeScript
237 lines
4.9 KiB
TypeScript
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'
|
|
import { Base } from '@typegoose/typegoose/lib/defaultClasses'
|
|
import { CompactPuzzleClass } from '../match/PuzzleSession'
|
|
|
|
export class ShopPuzzleClass extends Base {
|
|
@prop()
|
|
public question: string
|
|
@prop()
|
|
public a1: string
|
|
@prop()
|
|
public a2: string
|
|
@prop()
|
|
public a3: string
|
|
@prop()
|
|
public a4: string
|
|
/**
|
|
* 题目类型: 1: 正常单选题, 2: 图片, 3: 问卷式题目
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: 1 })
|
|
public type: number
|
|
|
|
public compactRecord(withAnswer: boolean) {
|
|
let answers = []
|
|
for (let i = 1; i <= 4; i++) {
|
|
if (this[`a${i}`]) {
|
|
answers.push(this[`a${i}`])
|
|
}
|
|
}
|
|
let result = new CompactPuzzleClass()
|
|
result.id = this._id + ''
|
|
result.title = this.question
|
|
result.type = this.type
|
|
result.category = '自定义'
|
|
result.quality = 1
|
|
if (!withAnswer) {
|
|
answers.randomSort()
|
|
}
|
|
result.source = 1
|
|
result.answers = answers
|
|
return result
|
|
}
|
|
}
|
|
|
|
export class ExamRewardClass extends Base {
|
|
@prop()
|
|
public id: number
|
|
@prop()
|
|
public rank: number
|
|
|
|
@prop()
|
|
public rankEnd?: number
|
|
|
|
@prop()
|
|
public coupon: string
|
|
|
|
@prop({ default: 0 })
|
|
public count: number
|
|
|
|
/**
|
|
* 奖励类型
|
|
* @type {number} 0: 单局, 1: 累积
|
|
*/
|
|
@prop({ default: 0 })
|
|
public type: 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
|
|
|
|
@prop()
|
|
public icon: string
|
|
|
|
@prop()
|
|
public banner: string
|
|
|
|
/**
|
|
* 已选择的题库分类
|
|
* @type {string[]}
|
|
*/
|
|
@prop({ type: () => [String] })
|
|
public qtypes: string[]
|
|
/**
|
|
* 店铺自定义tag
|
|
* @type {string[]}
|
|
*/
|
|
@prop({ type: () => [String] })
|
|
public shopCates: string[]
|
|
/**
|
|
* 单次活动题目数量, 0为所有
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: 10 })
|
|
public qcount: number
|
|
|
|
/**
|
|
* 每道题的回答时间
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: 5 })
|
|
public timeone: number
|
|
|
|
/**
|
|
* 活动正式开始时间, 从0点开始
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: 0 })
|
|
public beginTime: number
|
|
|
|
/**
|
|
* 结束时间
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: 4102416001000 })
|
|
public endTime: number
|
|
|
|
@prop({ type: () => [ExamRewardClass] })
|
|
public rewardInfo: ExamRewardClass[]
|
|
/**
|
|
* 是否启用
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: false })
|
|
public active: boolean
|
|
|
|
/**
|
|
* 题目来源
|
|
* 0: 系统题目
|
|
* 1: 自定义
|
|
* 2: 店铺自定义题库
|
|
* 3: 混合题库
|
|
* @type {number}
|
|
*/
|
|
@prop({ default: 0 })
|
|
public source: number
|
|
/**
|
|
* 系统题库题目数量和自定义题库数量的比例
|
|
* @type {number}
|
|
*/
|
|
@prop()
|
|
public qrate: number
|
|
|
|
/**
|
|
* 是否删除
|
|
* @type {boolean}
|
|
*/
|
|
@noJson()
|
|
@prop({ default: false })
|
|
public deleted: boolean
|
|
@noJson()
|
|
@prop()
|
|
public deleteTime: Date
|
|
|
|
/**
|
|
* 创建人
|
|
* @type {string}
|
|
*/
|
|
@prop()
|
|
public createdBy: string
|
|
|
|
@prop({ type: [ShopPuzzleClass] })
|
|
public questions: ShopPuzzleClass[]
|
|
|
|
public static parseQueryParam(params) {
|
|
let { key, timeBegin, timeEnd, active, shop, source } = 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 (source != undefined) {
|
|
opt.source = source
|
|
}
|
|
if (shop) {
|
|
opt.shop = shop
|
|
}
|
|
|
|
let sort = { _id: -1 }
|
|
return { opt, sort }
|
|
}
|
|
|
|
public transQuestion() {
|
|
return this.questions.map(o => {
|
|
return o.compactRecord(false)
|
|
})
|
|
}
|
|
|
|
public getReward(score: number, type: number) {
|
|
if (!this.rewardInfo || this.rewardInfo.length === 0) {
|
|
return []
|
|
}
|
|
this.rewardInfo.sort((a, b) => a.rank - b.rank)
|
|
let results = []
|
|
for (let reward of this.rewardInfo) {
|
|
if (score >= reward.rank) {
|
|
results.push({ id: reward._id + '', coupon: reward.coupon, count: reward.count })
|
|
}
|
|
}
|
|
return results
|
|
}
|
|
}
|
|
|
|
export const ShopExam = getModelForClass(ShopExamClass, { existingConnection: ShopExamClass.db })
|