Files
ZYZ/shared/db/UserTaskRec.ts
2022-05-07 21:12:46 +08:00

149 lines
6.7 KiB
TypeScript

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';
import { UpdateTaskParam } from '../domain/roleField/task';
/**
* 玩家任务记录表
**/
@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: string; // 行为类型下的分组
@prop({ required: true })
count: number; // 达成次数
@prop({ required: true, type: Number, default: [] })
received: number[]; // 是否已领取
@prop({ required: true, type: String, default: [] })
records: string[]; // 历史记录
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: string, count: number, records?: string[]) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $set: { count, records: records||[] } }, { new: true, upsert: true }).lean();
return rec;
}
public static async incTaskRec(roleId: string, type: number, taskType: number, group: string, count: number, records?: string[]) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $inc: { count }, $set: { records: records||[] } }, { new: true, upsert: true }).lean();
return rec;
}
public static async recordTaskRec(roleId: string, type: number, taskType: number, group: string, records?: string[]) {
let condition = this.getRefreshCondition(type);
let rec: UserTaskRecType = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [], count: 0 }, $set: { records: records||[] } }, { new: true, upsert: true }).lean();
return rec;
}
public static async setOrIncTask(roleId: string, type: number, taskType: number, group: string, param: UpdateTaskParam) {
if(param.set) {
return await this.setTaskRec(roleId, type, taskType, group, param.set, param.records);
} else if (param.inc) {
return await this.incTaskRec(roleId, type, taskType, group, param.inc, param.records);
} else if (param.records) {
return await this.recordTaskRec(roleId, type, taskType, group, param.records);
}
}
public static async checkHistoryAndSetTaskRec(roleId: string, type: number, taskType: number, group: string, count: number) {
let rec: UserTaskRecType = await UserTaskRecModel.findByRoleAndGroup(roleId, type, taskType, group);
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 checkRecordAndIncTaskRec(roleId: string, type: number, taskType: number, group: string, count: number, record: string) {
let rec: UserTaskRecType = await UserTaskRecModel.findByRoleAndGroup(roleId, type, taskType, group);
if(!rec || rec.records.indexOf(record) == -1) {
let condition = this.getRefreshCondition(type);
rec = await UserTaskRecModel.findOneAndUpdate({ roleId, group, taskType, ...condition }, { $setOnInsert: { code: genCode(8), received: [] }, $inc: { count }, $push: { records: record } }, { new: true, upsert: true }).lean();
}
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<number, Map<string, UserTaskRecType>>(); // taskType => group => userTask
for(let userTaskRec of rec) {
let { taskType, group } = userTaskRec;
if(!map.has(taskType)) {
map.set(taskType, new Map<string, UserTaskRecType>());
}
map.get(taskType).set(group, userTaskRec);
}
return map;
}
public static async findByRoleAndGroup(roleId: string, type: number, taskType: number, group: string) {
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: string, 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<DocumentType<UserTaskRec>, keyof UserTaskRec> { }
export type UserTaskRecParam = Partial<UserTaskRecType>;