/** * 全服邮件 */ import MailTemp from './MailTemp'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; import { nowSeconds } from '../pubUtils/timeUtil'; import { MAIL_STATUS } from '../consts/constModules/mailConst'; class RoleStatus { @prop({ required: true }) roleId: string; @prop({ required: true }) status: number; } @index({ sendTime: 1 }) export default class ServerMail extends MailTemp { @prop({ required: true }) serverId: number; @prop({ required: true, type: RoleStatus }) roleStatus: RoleStatus[]; @prop({ required: true, type: String }) delRoles: string[]; /** * @description 根据玩家id获得所有有效邮件 * @param {String} roleId 玩家id * @param {Number} serverId 服务器id */ public static async findByRoleId(roleId: string, serverId: number) { const result: ServerMailType[] = await ServerMailModel.find({ serverId, delRoles: { $ne: roleId }, sendTime: { $lte: nowSeconds() } , endTime: { $gte: nowSeconds() } }).populate('mail').lean(); return result; } public static async getMailById(_id: string, lean = true) { const result: ServerMailType = await ServerMailModel.findOne({ _id }).lean(lean); return result; } public static async findByTimeGap(beforeTime: number, time: number) { const result: ServerMailType[] = await ServerMailModel.find({ sendTime: { $gt: beforeTime, $lte: time } }).lean(); return result; } public static async findBySendTime(time: number) { const result: ServerMailType[] = await ServerMailModel.find({ sendTime: time }).lean(); return result; } /** * @description 创建邮件 * @param params */ public static async addMail(params: ServerMailTypeParam) { const doc = new ServerMailModel(); const mail = Object.assign(doc.toJSON(), params); delete mail._id; let rec: ServerMailType = await ServerMailModel.findByIdAndUpdate(doc._id, mail, { new: true, upsert: true }).lean(); return rec; } /** * 根据id删除单条邮件 * @param _id * @param lean */ public static async delMailById(id: string, roleId: string) { const result: ServerMailType = await ServerMailModel.findOneAndUpdate( { _id: id, sendTime:{ $lte: nowSeconds() }, 'roleStatus.roleId': roleId, $or: [{ 'roleStatus.status': MAIL_STATUS.READ, hasGoods:false }, { 'roleStatus.status': MAIL_STATUS.RECEIVED }] }, { $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE}, $push: { delRoles: roleId } }, { new: true } ).lean(); // console.log('*******', result) return result; } /** * 根据玩家id批量删除 * @param _id * @param roleId */ public static async delMailsByRoleId(roleId: string) { const ids: { _id: string }[] = await ServerMailModel.find( { sendTime:{ $lte: nowSeconds() }, $or: [{ roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.READ}}, hasGoods:false }, { roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.RECEIVED}} }] } ).select('_id').lean(); let result: ServerMailType[] = []; for(let _id of ids) { let rec = await ServerMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId }, { $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE }, $push: { delRoles: roleId }}, { new: true }).lean(); result.push(rec); } return result; } public static async updateStatusWithCondition(_id: string, roleId: string, status: number, servermail?: ServerMailType) { if(!servermail) servermail = await ServerMailModel.findById(_id).lean(); let { roleStatus } = servermail; let hasRole = roleStatus.find(cur => cur.roleId == roleId); if(hasRole) { servermail = await ServerMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId }, { $set: { 'roleStatus.$.status': status } }, {new: true}).lean(); } else { servermail = await ServerMailModel.findByIdAndUpdate(_id, { $push: { roleStatus: { roleId, status } } }, {new: true}).lean(); } return servermail } /** * 查询有奖励的邮件 * @param roleId * @param lean */ public static async findRewardsMails(serverId: number, roleId: string, lean = true) { const allMails: ServerMailType[] = await ServerMailModel.find({ serverId, sendTime:{$lte: nowSeconds()} }).lean(lean); let result: ServerMailType[] = []; for(let mail of allMails) { let { roleStatus } = mail; let hasRole = roleStatus.find(cur => cur.roleId == roleId); if(hasRole) { if(hasRole.status == MAIL_STATUS.CREATE || hasRole.status == MAIL_STATUS.READ) { result.push(mail); } } else { result.push(mail); } } return result; } } export const ServerMailModel = getModelForClass(ServerMail); export interface ServerMailType extends Pick, keyof ServerMail>{} export type ServerMailTypeParam = Partial; // 将所有字段变成可选项