/** * 多人邮件 */ import MailTemp from './MailTemp'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; import { nowSeconds } from '../pubUtils/timeUtil'; import { MAIL_STATUS } from '../consts/constModules/mailConst'; import { findWhere } from 'underscore'; class RoleStatus { @prop({ required: true }) roleId: string; @prop({ required: true }) status: number; } @index({ 'roleStatus.roleId': 1 }) export default class GroupMail extends MailTemp { @prop({ required: true, type: RoleStatus }) roleStatus: RoleStatus[]; @prop({ required: false }) guildCode: string; /** * @description 根据玩家id获得所有有效邮件 * @param {String} roleId 玩家id */ public static async findByRoleId(roleId: string) { const result: GroupMailType[] = await GroupMailModel.find({ $and: [ {'roleStatus.roleId': roleId}, {'roleStatus.status': { $in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ, MAIL_STATUS.RECEIVED ] }} ], sendTime: { $lte: nowSeconds() } , endTime: { $gte: nowSeconds() } }).populate('mail').lean(); return result; } /** * @description 创建邮件 * @param params */ public static async addMail(params: GroupMailTypeParam) { const doc = new GroupMailModel(); const mail = Object.assign(doc.toJSON(), params); delete mail._id; let rec: GroupMailType = await GroupMailModel.findByIdAndUpdate(doc._id, mail, { new: true, upsert: true }).populate('mail').lean(); return rec; } /** * 根据id删除单条邮件 * @param _id */ public static async delMailById(_id: string, roleId: string) { const result: GroupMailType = await GroupMailModel.findOneAndUpdate( { _id, sendTime:{ $lte: nowSeconds() }, $and: [{ 'roleStatus.roleId': roleId, },{ $or: [{ 'roleStatus.status': MAIL_STATUS.READ, hasGoods:false }, { 'roleStatus.status': MAIL_STATUS.RECEIVED }] }], }, { $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE } }, { new: true } ).lean(); return result; } /** * 根据玩家id批量删除 * @param _id * @param roleId */ public static async delMailsByRoleId(roleId: string) { const ids: { _id: string }[] = await GroupMailModel.find( { sendTime:{ $lte: nowSeconds() }, $or: [{ roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.READ}}, hasGoods:false }, { roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.RECEIVED}} }] },).select('_id').lean(); const result: GroupMailType[] = []; for(let _id of ids) { let rec = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId }, { $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE }}, { new: true }).lean(); result.push(rec); } return result; } public static async getGroupMailsByRoleId(roleId: string, lean = true) { const result: GroupMailType[] = await GroupMailModel.find({ $and:[{'roleStatus.roleId': roleId}, { 'roleStatus.status': { $ne: -1}}], sendTime:{$lte: nowSeconds()} }).lean(lean); return result; } public static async getMail( mailId: string, mailTemType: number, lean = true) { const result: GroupMailType = await GroupMailModel.findOne({ mailId, mailTemType, sendTime:{$lte: nowSeconds()} }).lean(lean); return result; } public static async pushRoleMail( roleId: string, mailId: string, mailTemType: number, lean = true) { const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ mailId, mailTemType, sendTime:{$lte: nowSeconds()} }, {$push: {roleStatus: {roleId, status: 0}}}).lean(lean); return result; } public static async getMailById(_id: string, lean = true) { const result: GroupMailType = await GroupMailModel.findOne({ _id, sendTime:{$lte: nowSeconds()} }).lean(lean); return result; } public static async findByTimeGap(beforeTime: number, time: number) { const result: GroupMailType[] = await GroupMailModel.find({ sendTime: { $gt: beforeTime, $lte: time } }).lean(); return result; } public static async findBySendTime(time: number) { const result: GroupMailType[] = await GroupMailModel.find({ sendTime: time }).lean(); return result; } public static async updateStatusWithCondition(_id: string, roleId: string, status: number) { const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId, sendTime:{$lte: nowSeconds()} }, {$set:{ 'roleStatus.$.status': status }}, { new: true }).lean(); return result; } public static async deleteMail(_id: string, roleId: string, status: number, lean = true) { const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId, sendTime:{$lte: nowSeconds()}}, {$set:{ 'roleStatus.$.status': status }}, { new: true }).lean(lean); return result; } public static async findReadAndRewardsMails(roleId: string, lean = true) { const ids: GroupMailType[] = await GroupMailModel.find({ sendTime:{$lte: nowSeconds()}, roleStatus: { $elemMatch: { roleId, $or:[ {$and: [{status: MAIL_STATUS.READ}, { hasGoods: false }]},{status: MAIL_STATUS.RECEIVED} ] } } }).select('_id').lean(lean); return ids; } public static async updateStatusByIds(ids: string[], status: number, roleId: string, lean = true) { let mails = []; for(let id of ids) { const result: GroupMailType = await GroupMailModel.findOneAndUpdate({_id: id, "roleStatus.roleId": roleId}, { $set:{ 'roleStatus.$.status': status } }, { new: true }).lean(lean); let { status: resStatus } = findWhere(result.roleStatus, { roleId }); mails.push({id: result._id, status: resStatus, /*mailType: MAIL_TYPE.GROUPMAIL*/}); } return mails; } /** * 查询有奖励的邮件 * @param roleId * @param lean */ public static async findRewardsMails(roleId: string, lean = true) { const result: GroupMailType[] = await GroupMailModel.find({ roleStatus: { $elemMatch:{roleId, status:{ $in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ ] }} }, sendTime:{$lte: nowSeconds()} }).lean(lean); return result; } } export const GroupMailModel = getModelForClass(GroupMail); export interface GroupMailType extends Pick, keyof GroupMail>{} export type GroupMailTypeParam = Partial; // 将所有字段变成可选项