/** * 邮件的模板,在GM后台能看到的邮件列表 */ import BaseModel from './BaseModel'; import { getModelForClass, prop, DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose'; import { GM_MAIL_STATUS, GM_MAIL_TYPE, MAIL_TIME_TYPE } from '../consts'; import { SearchMailParam } from '../domain/backEndField/search'; import { getCurDay, nowSeconds } from '../pubUtils/timeUtil'; import { GMMail as StategyMail } from './ServerStategy'; import { ServerlistType } from './Serverlist'; import moment = require('moment'); class MailReward { @prop({ required: true }) id: number; @prop({ required: true }) count: number; } export class Receiver { @prop({ required: true }) env: string; @prop({ required: true }) serverId: number; @prop({ required: true }) roleId?: string; @prop({ required: true }) roleName?: string; @prop({ required: true, type: MailReward, _id: false }) rewards?: MailReward[]; } export default class GMMail extends BaseModel { @prop({ required: false}) hasGoods: boolean; // 有效时间,单位小时 @prop({ required: true, type: MailReward, default: [], _id: false }) goods: MailReward[]; @prop({ required: true, default: true }) timeType: MAIL_TIME_TYPE; // 邮件时间类型 @prop({ required: false}) expire: number; // 有效时间,单位小时 @prop({ required: true }) startTime: number; // 发送时间,延时邮件使用 @prop({ required: true }) circleStart: number; // 循环邮件开始循环时间 @prop({ required: true }) circleEnd: number; // 循环邮件结束循环时间 @prop({ required: true }) circleDay: number; // 循环时间,每周几,0表示每天 @prop({ required: true }) circleHour: string; // 几点发送 @prop({ required: true }) title: string; @prop({ required: true }) content: string; @prop({ required: true }) sendName: string; @prop({ required: true }) mailType: GM_MAIL_TYPE; // 收件人类型 @prop({ required: true, type: Receiver, _id: false }) receivers: Receiver[]; @prop({ required: true }) reason: string; // 原因 @prop({ required: true, default: false }) isSp: boolean; // 特殊邮件 @prop({ required: true, default: 0 }) status: GM_MAIL_STATUS; // 邮件状态 @prop({ required: true }) viewBy: number; // 审核人 @prop({ required: true }) viewAt: Date; // 审核时间 @prop({ required: true, type: Number }) sendTimes: number[]; // 是否已经发件 @prop({ required: true }) sendTime: string; // 发送时间 public setByRegionStategy(type: 'openMail'|'circleMail', gmmail: StategyMail, newServer: ServerlistType, uid) { this.hasGoods = !!gmmail.goods?.length; this.goods = gmmail.goods; this.timeType = type == 'openMail'? MAIL_TIME_TYPE.DELAY: MAIL_TIME_TYPE.CIRCLE; this.expire = gmmail.expire; if(type == 'openMail') { this.startTime = nowSeconds(); } else { this.circleStart = nowSeconds(); this.circleEnd = nowSeconds() + gmmail.circleContinueDay * 24 * 60 * 60; this.circleDay = gmmail.circleDay; this.circleHour = gmmail.circleHour; } this.title = gmmail.title; this.content = gmmail.content; this.sendName = gmmail.sendName; this.mailType = GM_MAIL_TYPE.SERVER; this.receivers = [{ env: newServer.env, serverId: newServer.id }]; this.reason = gmmail.reason; this.isSp = gmmail.isSp; this.status = GM_MAIL_STATUS.PASS; this.viewBy = uid; this.viewAt = new Date(); if (type == 'openMail') { this.sendTime = moment(this.startTime * 1000).format('YYYY-MM-DD HH:mm:ss'); } else { this.sendTime = (this.circleDay == 0?'每天': '每周'+this.circleDay) + ' ' + this.circleHour; } } public static async addMail(params: GMMailTypeParam, uid = 1) { const doc = new GMMailModel(); let mail = Object.assign(doc.toJSON(), params); let result: GMMailType = await GMMailModel.findOneAndUpdate({ _id: mail._id }, { $set: {...mail, updatedBy: uid}, $setOnInsert: { createdBy: uid } }, {upsert: true, new: true}).lean(); return result; } public static async updateMailById(_id: string, params: GMMailTypeParam, uid: number = 1) { let mail: GMMailType = await GMMailModel.findByIdAndUpdate(_id, { $set: {...params, updatedBy: uid}}, {new: true}).lean(); return mail; } public static async getGmMailById(_id: string, lean = true) { const result: GMMailType = await GMMailModel.findOne({ _id }).lean(lean); return result; } public static async getGmMailByIdAndType(_id: string, mailType: GM_MAIL_TYPE, hasGoods: boolean) { const result: GMMailType = await GMMailModel.findOne({ _id, mailType, hasGoods }).lean(); return result; } private static getSearchObj(form: SearchMailParam) { let searchObj = {}; if(form.createTimeStart) searchObj['createdAt'] = { $gt: new Date(form.createTimeStart * 1000) }; if(form.createTimeEnd) searchObj['createdAt'] = { $lt: new Date(form.createTimeEnd * 1000) }; if(form.serverId) searchObj['receivers.serverId'] = form.serverId; if(form.roleId) searchObj['receivers.roleId'] = form.roleId; if(form.roleName) searchObj['receivers.roleName'] = { $regex: new RegExp(form.roleName.toString(), 'i') } if(form.status) searchObj['status'] = form.status; if(form.mailType) searchObj['mailType'] = form.mailType; if(form.hasGoods != undefined) searchObj['hasGoods'] = form.hasGoods; if(form.title) searchObj['title'] = { $regex: new RegExp(form.title.toString(), 'i') } return searchObj } public static async findByCondition(page: number, pageSize: number, sortField: string, sortOrder: string, form: SearchMailParam = {}) { let searchObj = this.getSearchObj(form); let sort = {}; if(sortField && sortOrder) { if(sortOrder == 'ascend') { sort[sortField] = 1; } else if (sortOrder == 'descend') { sort[sortField] = -1; } } const result: GMMailType[] = await GMMailModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true }); return result; } public static async countByCondition(form: SearchMailParam = {}) { let searchObj = this.getSearchObj(form); const result = await GMMailModel.count(searchObj); return result; } public static async findCircleMails(env: string) { const result: GMMailType[] = await GMMailModel.find({ timeType: MAIL_TIME_TYPE.CIRCLE, circleStart: { $lt: nowSeconds() }, circleEnd: { $gte: nowSeconds() }, circleDay: { $in: [0, getCurDay(true)] }, 'receivers.env': env, status: GM_MAIL_STATUS.PASS }); return result; } public static async sendMail(id: string, time: number) { const result: GMMailType = await GMMailModel.findByIdAndUpdate(id, { $push: { sendTimes: time}}, {new: true}).lean(); return result; } } export let GMMailModel: ReturnModelType; export function loadGMMailModel(connect: mongoose.Connection) { GMMailModel = getModelForClass(GMMail, { existingConnection: connect }); } export interface GMMailType extends Pick, keyof GMMail> { }; export type GMMailTypeParam = Partial; // 将所有字段变成可选项