import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; import { TASK_FUN_TYPE } from '../consts'; import { genCode } from '../pubUtils/util'; import { getZeroPointD } from '../pubUtils/timeUtil'; /** * 玩家任务记录表 **/ @modelOptions({ schemaOptions: { id: false } }) @index({ code: 1 }) @index({ roleId: 1, type: 1, taskType: 1, group: 1 }) export default class UserTaskRec extends BaseModel { @prop({ required: true }) code: string; // 该记录唯一标识 @prop({ required: true }) roleId: string; // 玩家id @prop({ required: true, enum: TASK_FUN_TYPE }) type: number; // 任务类型 @prop({ required: true }) taskType: number; // 行为类型 @prop({ required: true }) group: number; // 行为类型下的分组 @prop({ required: true }) count: number; // 达成次数 @prop({ required: true, type: Number, default: [] }) received: number[]; // 是否已领取 private static getRefreshCondition(type: number) { let today = getZeroPointD(); if(type == TASK_FUN_TYPE.DAILY || type == TASK_FUN_TYPE.PVP) { return { type, createdAt: { $gte: today } }; } else { return { type }; } } public static async setTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) { let condition = this.getRefreshCondition(type); let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $set: { count } }, { new: true, upsert: true }).lean(); return rec; } public static async incTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) { let condition = this.getRefreshCondition(type); let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $inc: { count } }, { new: true, upsert: true }).lean(); return rec; } public static async checkHistoryAndSetTaskRec(roleId: string, type: number, taskType: number, group: number, count: number) { let rec: UserTaskRecType = await UserTaskRecModel.findByRoleAndGroup(roleId, type, group, taskType); if(rec) { if(rec.count < count) { rec = await UserTaskRecModel.setTaskRec(roleId, type, taskType, group, count); } } else { rec = await UserTaskRecModel.setTaskRec(roleId, type, taskType, group, count); } return rec; } public static async findByRoleAndType(roleId: string, type: number) { let condition = this.getRefreshCondition(type); let rec: UserTaskRecType[] = await UserTaskRecModel.find({ roleId, ...condition }).lean(); let map = new Map>(); // taskType => group => userTask for(let userTaskRec of rec) { let { taskType, group } = userTaskRec; if(!map.has(taskType)) { map.set(taskType, new Map()); } map.get(taskType).set(group, userTaskRec); } return map; } public static async findByRoleAndGroup(roleId: string, type: number, taskType: number, group: number) { let condition = this.getRefreshCondition(type); let rec: UserTaskRecType = await UserTaskRecModel.findOne({ roleId, taskType, group, ...condition }).lean(); return rec; } public static async receiveTask(roleId: string, type: number, taskType: number, group: number, id: number) { let condition = this.getRefreshCondition(type); let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, taskType, group, ...condition }, { $push: { received: id } }, { new: true }).lean(); return rec; } public static async getReceiveRec(roleId: string, type: number) { let condition = this.getRefreshCondition(type); let rec = await UserTaskRecModel.find({ roleId, ...condition }).lean(); return rec } public static async getHistoryRec(roleId: string, type: number, today?: Date) { if(!today) today = getZeroPointD(); let rec: UserTaskRecType[] = await UserTaskRecModel.find({ roleId, type, createdAt: { $lt: today } }).lean(); return rec } public static async deleteHistory(history: UserTaskRecType[]) { let codes = history.map(cur => cur.code); let result = await UserTaskRecModel.deleteMany({ code: { $in: codes } }); return result; } } export const UserTaskRecModel = getModelForClass(UserTaskRec); export interface UserTaskRecType extends Pick, keyof UserTaskRec> { } export type UserTaskRecParam = Partial;