diff --git a/game-server/app/servers/gm/handler/gmHandler.ts b/game-server/app/servers/gm/handler/gmHandler.ts index 1d929233b..a6ab0c204 100644 --- a/game-server/app/servers/gm/handler/gmHandler.ts +++ b/game-server/app/servers/gm/handler/gmHandler.ts @@ -74,7 +74,8 @@ export class GmHandler { let needSend = false; if(isPass) { if(timeType == MAIL_TIME_TYPE.CIRCLE) { - let refTime = moment(moment().format(`YYYY-MM-DD ${REF_CIRCLE_MAIL_TIME}:00:00`)).unix(); + let refTimeStr = REF_CIRCLE_MAIL_TIME >= 10? `${REF_CIRCLE_MAIL_TIME}`: `0${REF_CIRCLE_MAIL_TIME}`; + let refTime = moment(moment().format(`YYYY-MM-DD ${refTimeStr}:00:00`)).unix(); let sendTime = moment(moment().format('YYYY-MM-DD '+circleHour)).unix(); if(sendTime < refTime) sendTime += 86400; let now = nowSeconds(); @@ -87,15 +88,20 @@ export class GmHandler { } if(needSend) { let f = new SendMailFun(); - await f.setWithGmMail(gmmail); + let code = await f.setWithGmMail(gmmail); if (mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) { let roleIds = receivers.filter(cur => cur.env == this.app.get('env')).map(cur => cur.roleId); - await f.sendToUsers(mailType, roleIds); + if(mailType == GM_MAIL_TYPE.SINGLE) { + await f.createSingleMails(code, roleIds); + } else { + await f.createGroupMails(code, roleIds); + } } else { let serverIds = receivers.filter(cur => cur.env == this.app.get('env')).map(cur => cur.serverId); - await f.sendToServer(serverIds); + await f.createServerMails(code, serverIds); } + await f.pushToUsers(); // await f.saveRecord(uid); } let sendTime = ''; diff --git a/game-server/app/servers/guild/handler/guildHandler.ts b/game-server/app/servers/guild/handler/guildHandler.ts index fe7121441..af56c31c0 100644 --- a/game-server/app/servers/guild/handler/guildHandler.ts +++ b/game-server/app/servers/guild/handler/guildHandler.ts @@ -14,7 +14,7 @@ import { GuildLeader } from '../../../domain/rank'; import { UserGuildApplyModel } from '../../../db/UserGuildApply'; import { hasStructureConsume, getStructureConsume, gameData } from '../../../pubUtils/data'; import { GuildRecModel } from '../../../db/GuildRec'; -import { sendMailByContent, SendMailFun } from '../../../services/mailService'; +import { sendMailByContent, SendMailFun, sendMailToGuildByContent } from '../../../services/mailService'; import { updateUserInfo, isRoleOnline, getRoleOnlineInfo } from '../../../services/redisService'; import { openGuildRefine } from '../../../services/guildRefineService'; @@ -814,9 +814,7 @@ export class GuildHandler { const { members } = guild; //下发邮件 - let f = new SendMailFun(); - f.setWithContentId(MAIL_TYPE.SEND_MAIL, { sendName: roleName, params: [info] }); - await f.sendToGuild(code, members); + await sendMailToGuildByContent(MAIL_TYPE.SEND_MAIL, code, { sendName: roleName, params: [info] }, guild); return resResult(STATUS.SUCCESS, { isSuccess: true }); } diff --git a/game-server/app/servers/systimer/remote/systimerRemote.ts b/game-server/app/servers/systimer/remote/systimerRemote.ts index 38b83a909..29faf583a 100644 --- a/game-server/app/servers/systimer/remote/systimerRemote.ts +++ b/game-server/app/servers/systimer/remote/systimerRemote.ts @@ -1,5 +1,5 @@ import { Application, ChannelService } from 'pinus'; -import { resetPvpSeasonTime, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer } from '../../../services/timeTaskService'; +import { resetPvpSeasonTime, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule } from '../../../services/timeTaskService'; import PvpDefenseType from '../../../db/PvpDefense'; import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity'; import { reloadResources } from '../../../pubUtils/data'; @@ -11,6 +11,9 @@ import { MarqueeType } from '../../../db/Marquee'; import { taflush } from '../../../services/sdkService'; import { RegionType } from '../../../db/Region'; import { errlogger } from '../../../util/logger'; +import { MailType } from '../../../db/Mail'; +import { GroupMailType } from '../../../db/GroupMail'; +import { ServerMailType } from '../../../db/ServerMail'; export default function (app: Application) { return new SystimerRemote(app); @@ -178,4 +181,12 @@ export class SystimerRemote { errlogger.error(`remote ${__filename} \n ${e.stack}`); } } + + public async addMailsToSchedule(mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) { + try { + await addMailsToSchedule(mails, groupMails, serverMails); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } } diff --git a/game-server/app/services/gmService.ts b/game-server/app/services/gmService.ts index 341b17487..ccf19318d 100644 --- a/game-server/app/services/gmService.ts +++ b/game-server/app/services/gmService.ts @@ -163,8 +163,9 @@ export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: St } if(needSend) { let f = new SendMailFun(); - await f.setWithGmMail(gmmail); - await f.sendToServer([newServer.id]); + let code = await f.setWithGmMail(gmmail); + await f.createServerMails(code, [newServer.id]); + await f.pushToUsers(); } return true; } diff --git a/game-server/app/services/guildService.ts b/game-server/app/services/guildService.ts index eccfaca97..ffb1b9d59 100644 --- a/game-server/app/services/guildService.ts +++ b/game-server/app/services/guildService.ts @@ -223,14 +223,14 @@ export async function addActive(roleId: string, serverId: number, id: number, ty * @param roleId 用户id * @param select 筛选字段 */ -export async function getUserGuildWithRefActive(roleId: string, select?: string, notPush?: boolean) { +export async function getUserGuildWithRefActive(roleId: string, select?: string) { let userGuild = await UserGuildModel.getMyGuild(roleId, select ? select + ' wishGoods +refTimeDaily' : '+refTimeDaily'); // console.log(JSON.stringify(userGuild)) if (!userGuild) return false; - return await refreshUserGuild(userGuild, roleId, notPush); + return await refreshUserGuild(userGuild, roleId); } -export async function refreshUserGuild(userGuild: UserGuildType, roleId: string, notPush?: boolean) { +export async function refreshUserGuild(userGuild: UserGuildType, roleId: string) { if(!userGuild) return false; let { receivedActive, refTimeDaily, activeDaily, activeRecord, wishGoods, receivedWishPool } = userGuild; @@ -245,8 +245,7 @@ export async function refreshUserGuild(userGuild: UserGuildType, roleId: string, let donateName = donateNames[donateNames.length - i - 1]; await sendMailByContent(MAIL_TYPE.WISH_POOL_REWARD, roleId, { params: [donateName, goodInfo.name], - goods: [{ id: goodId, count: drawCnt }], - notPush + goods: [{ id: goodId, count: drawCnt }] }); } }); diff --git a/game-server/app/services/mailService.ts b/game-server/app/services/mailService.ts index 520078a4a..094dfb860 100644 --- a/game-server/app/services/mailService.ts +++ b/game-server/app/services/mailService.ts @@ -7,7 +7,7 @@ import { pinus } from "pinus"; import { gameData } from "../pubUtils/data"; import { nowSeconds } from '../pubUtils/timeUtil'; import { STATUS } from '../consts/statusCode'; -import { resResult } from '../pubUtils/util'; +import { genCode, resResult } from '../pubUtils/util'; import { GM_MAIL_TYPE, ITID, MAIL_STATUS, MAIL_TIME_TYPE, MAIL_TYPE, SEND_NAME, SEND_TITLE } from "../consts"; import { MailParam } from '../domain/roleField/mail'; import { GMMailType, GMMailModel, GMMailTypeParam } from "../db/GMMail"; @@ -53,26 +53,25 @@ function getMailInfos(roleId: string, mails: MailType[], groupMails: GroupMailTy return list; } -export async function sendMailByContent(contentId: MAIL_TYPE, hisRoleId: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[], notPush?: boolean }) { +export async function sendMailByContent(contentId: MAIL_TYPE, hisRoleId: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[] }) { let f = new SendMailFun(); - f.setWithContentId(contentId, params); - await f.sendToUsers(GM_MAIL_TYPE.SINGLE, [hisRoleId]); + let code = f.setWithContentId(contentId, params); + await f.createSingleMails(code, [hisRoleId]); + await f.pushToUsers(); } -export async function sendMailToGuildByContent(contentId: MAIL_TYPE, guildCode: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[], notPush?: boolean }, guild?: GuildType) { +export async function sendMailToGuildByContent(contentId: MAIL_TYPE, guildCode: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[] }, guild?: GuildType) { if(!guild) guild = await GuildModel.findByCode(guildCode, null, '+members'); if(!guild) return false; let f = new SendMailFun(); - f.setWithContentId(contentId, params); - await f.sendToGuild(guildCode, guild.members); + let code = f.setWithContentId(contentId, params); + await f.createGroupMails(code, guild.members, guildCode); + await f.pushToUsers(); return true; } -/** - * 发送邮件方法类 - */ -export class SendMailFun { - private mailType: GM_MAIL_TYPE = GM_MAIL_TYPE.SINGLE; // 邮件类型 1-单人 2-多人 3-全服 +class MailTemp { + public code: string; private contentId: MAIL_TYPE = MAIL_TYPE.SEND_MAIL; // 0-读GmMail,1以上读dicMail private sendName: string = SEND_NAME; private title: string = SEND_TITLE; @@ -82,13 +81,10 @@ export class SendMailFun { private goods: RewardInter[] = []; // 发送的奖励 private sendTime: number; private endTime: number; - private notPush: boolean = false; - private mails: MailType[] = []; - private groupMails: GroupMailType[] = []; - private serverMails: ServerMailType[] = []; // 从dicMail读取数据 public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, params?: string[], goods?: RewardInter[] }) { + this.code = genCode(8); let dicMail = gameData.mail.get(contentId); this.contentId = contentId; this.sendTime = nowSeconds(); @@ -100,16 +96,8 @@ export class SendMailFun { this.goods = params.goods||[]; } - getContent(content: string, params: string[] = []) { - if(!content) content = '%d'; - for(let p of params) { - content = content.replace(/%d/, p); - } - return content - } - - // 从GMMail表读取数据 public async setWithGmMail(gmmail: GMMailType) { + this.code = genCode(8); this.gmmail = gmmail; this.contentId = 0; if(gmmail.timeType == MAIL_TIME_TYPE.IMMEDIATE) { @@ -128,7 +116,15 @@ export class SendMailFun { return gmmail; } - private getCreateMailParams() { + private getContent(content: string, params: string[] = []) { + if(!content) content = '%d'; + for(let p of params) { + content = content.replace(/%d/, p); + } + return content + } + + public getCreateMailParams() { return { contentId: this.contentId, mail: this.gmmail?._id, @@ -141,94 +137,146 @@ export class SendMailFun { hasGoods: this.hasGoods } } +} + +/** + * 发送邮件方法类 + */ +export class SendMailFun { + private mailTemps = new Map(); + private mails: MailType[] = []; + private groupMails: GroupMailType[] = []; + private serverMails: ServerMailType[] = []; + + // 从dicMail读取数据 + public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, params?: string[], goods?: RewardInter[] }) { + let mailTemp = new MailTemp(); + mailTemp.setWithContentId(contentId, params); + this.mailTemps.set(mailTemp.code, mailTemp); + return mailTemp.code; + } + + // 从GMMail表读取数据 + public async setWithGmMail(gmmail: GMMailType) { + let mailTemp = new MailTemp(); + mailTemp.setWithGmMail(gmmail); + this.mailTemps.set(mailTemp.code, mailTemp); + return mailTemp.code; + } // 生成单人邮件 - private async createSingleMails(roleIds: string[]) { - let mails = new Map(); + public async createSingleMails(code: string, roleIds: string[]) { + let mapTemp = this.mailTemps.get(code); for(let roleId of roleIds) { - let originMail = await MailModel.addMail({ roleId, ...this.getCreateMailParams() }); + let originMail = await MailModel.addMail({ roleId, ...mapTemp.getCreateMailParams() }); this.mails.push(originMail); - let mail = new MailParam(this.mailType, originMail); - mails.set(roleId, mail); } - - return mails; } // 生成多人邮件 - private async createGroupMails(roleIds: string[]) { + public async createGroupMails(code: string, roleIds: string[], guildCode?: string) { + let mapTemp = this.mailTemps.get(code); let roleStatus = roleIds.map(roleId => { return { roleId, status: MAIL_STATUS.CREATE } }) - let originMail = await GroupMailModel.addMail({ roleStatus, ...this.getCreateMailParams() }); + let originMail = await GroupMailModel.addMail({ roleStatus, guildCode, ...mapTemp.getCreateMailParams() }); this.groupMails.push(originMail); - return new MailParam(this.mailType, originMail); } // 生成全服邮件 - private async createServerMails(serverIds: number[]) { - let mails = new Map(); + public async createServerMails(code: string, serverIds: number[]) { + let mapTemp = this.mailTemps.get(code); for(let serverId of serverIds) { - let originMail = await ServerMailModel.addMail({ serverId, ...this.getCreateMailParams() }); - mails.set(serverId, new MailParam(this.mailType, originMail)); + let originMail = await ServerMailModel.addMail({ serverId, ...mapTemp.getCreateMailParams() }); this.serverMails.push(originMail); } - return mails } - // 向某几个玩家推送 - public async sendToUsers(mailType: GM_MAIL_TYPE.SINGLE|GM_MAIL_TYPE.GROUP,roleIds: string[], myRoleId?: string, mySid?: string) { - this.mailType = mailType; - let uids: { uid: string, sid: string }[] = [] - for(let roleId of roleIds) { - let sid = ''; - if(roleId == myRoleId) { - sid = mySid; - } else { - let hisOnlineInfo = await getRoleOnlineInfo(roleId); - if(hisOnlineInfo.isOnline) { - sid = hisOnlineInfo.sid; + public async setMails(mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) { + this.mails.push(...mails); + this.groupMails.push(...groupMails); + this.serverMails.push(...serverMails); + } + + // 将存储的邮件发出 + public async pushToUsers(myRoleId?: string, mySid?: string) { + // 将可以发的邮件发出 + let pushByRoleId = new Map(); + let pushByGuildCode = new Map(); + let pushByServerId = new Map(); + + for(let mail of this.mails) { + console.log('#####', mail.sendTime) + if(mail.sendTime <= nowSeconds() && mail.endTime > nowSeconds()) { + let mailParam = new MailParam(GM_MAIL_TYPE.SINGLE, mail); + if(!pushByRoleId.has(mail.roleId)) pushByRoleId.set(mail.roleId, []); + pushByRoleId.get(mail.roleId).push(mailParam); + } + } + console.log('#####pushByRoleId', pushByRoleId) + for(let mail of this.groupMails) { + if(mail.sendTime <= nowSeconds() && mail.endTime > nowSeconds()) { + let mailParam = new MailParam(GM_MAIL_TYPE.GROUP, mail); + if(!!mail.guildCode) { + if(!pushByGuildCode.has(mail.guildCode)) pushByGuildCode.set(mail.guildCode, []); + pushByGuildCode.get(mail.guildCode).push(mailParam); + } else { + for(let { roleId } of mail.roleStatus) { + if(!pushByRoleId.has(roleId)) pushByRoleId.set(roleId, []); + pushByRoleId.get(roleId).push(mailParam); + } } } - if(sid) { - uids.push({ uid: roleId, sid }); + } + for(let mail of this.serverMails) { + if(mail.sendTime <= nowSeconds() && mail.endTime > nowSeconds()) { + let mailParam = new MailParam(GM_MAIL_TYPE.SERVER, mail); + if(!pushByServerId.has(mail.serverId)) pushByServerId.set(mail.serverId, []); + pushByServerId.get(mail.serverId).push(mailParam); } } - if(mailType == GM_MAIL_TYPE.SINGLE) { - let mails = await this.createSingleMails(roleIds); - for(let { uid, sid } of uids) { - let mail = mails.get(uid); - if(uids.length > 0 && mail && !this.notPush) pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: [mail] }), [{ uid, sid }]); + for(let [roleId, mails ] of pushByRoleId) { + let uids = await this.getUids(roleId, myRoleId, mySid); + console.log('###### onMailsAdd', uids, mails); + if(uids.length > 0 && mails.length > 0) { + pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails }), uids); } - } else if (mailType == GM_MAIL_TYPE.GROUP) { - let mail = await this.createGroupMails(roleIds); - if(uids.length > 0 && !this.notPush) pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: [mail] }), uids); - } else { // mailType错误 - return false; } - return true; + + for(let [guildCode, mails] of pushByGuildCode) { + let chatSid = await getGuildChannelSid(guildCode); + if(!!chatSid && mails.length > 0) { + pinus.app.rpc.chat.guildRemote.sendMailToGuild.toServer(chatSid, guildCode, 'onMailsAdd', { mails }); + } + } + + for(let [serverId, mails] of pushByServerId) { + let chatSid = await getWorldChannelSid(serverId); + if(!!chatSid && mails.length > 0) { + pinus.app.rpc.chat.chatRemote.sendMail.toServer(chatSid, serverId, 'onMailsAdd', { mails }); + } + } + + // 延时邮件,设置定时器 + pinus.app.rpc.systimer.systimerRemote.addMailsToSchedule.broadcast(this.mails, this.groupMails, this.serverMails); } - // 向军团推送 - public async sendToGuild(guildCode: string, members: string[]) { - this.mailType = GM_MAIL_TYPE.GROUP; - let mails = await this.createGroupMails(members); - let chatSid = await getGuildChannelSid(guildCode); - if(!this.notPush) pinus.app.rpc.chat.guildRemote.sendMailToGuild.toServer(chatSid, guildCode, 'onMailsAdd', { mails }); - } - - // 向全服推送 - public async sendToServer(serverIds: number[]) { - this.mailType = GM_MAIL_TYPE.SERVER; - let mails = await this.createServerMails(serverIds); - for(let serverId of serverIds) { - let mail = mails.get(serverId); - if(mail && !this.notPush) { - let chatSid = await getWorldChannelSid(serverId); - pinus.app.rpc.chat.chatRemote.sendMail.toServer(chatSid, serverId, 'onMailsAdd', { mails: [mail] }); + private async getUids(roleId: string, myRoleId?: string, mySid?: string) { + let uids: { uid: string, sid: string }[] = []; + let sid = ''; + if(roleId == myRoleId) { + sid = mySid; + } else { + let hisOnlineInfo = await getRoleOnlineInfo(roleId); + if(hisOnlineInfo.isOnline) { + sid = hisOnlineInfo.sid; } } + if(!!sid) { + uids.push({ uid: roleId, sid }); + } + return uids; } public async saveRecord(createUid: number) { diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index 0c1e120f4..25ad9df1d 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -544,7 +544,7 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer, * @param seasonNum * @param oldSeasonEndTime */ -export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime: number, notPush?: boolean) { +export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum: number, seasonEndTime: number) { //检查并返回排名结算以及武将功勋结算 let pvpSeasonResult = await savePvpSeasonResult(pvpDefense, seasonNum, seasonEndTime); let { rankGoods, heroGoods, rankLv } = pvpSeasonResult; @@ -552,12 +552,12 @@ export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum: if (!!rankGoods.length) //排名奖励 await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, pvpDefense.roleId, { params: [JSON.stringify(seasonNum), (rankLv > 1000 ? '999+' : JSON.stringify(rankLv))], - goods: rankGoods, notPush + goods: rankGoods }); if (!!heroGoods.length) //武将功勋奖励 await sendMailByContent(MAIL_TYPE.PVP_RESULT, pvpDefense.roleId, { params: [JSON.stringify(seasonNum)], - goods: heroGoods, notPush + goods: heroGoods }); return { diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index 8feefc6d9..f6d0d039d 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -32,6 +32,9 @@ import { createMarqueeMsg, pushMarqueeMsg } from './sysChatService'; import { RegionModel, RegionType } from '../db/Region'; import { CreateServerParam } from '../domain/backEndField/params'; import { infologger } from '../util/logger'; +import { MailModel, MailType } from '../db/Mail'; +import { GroupMailModel, GroupMailType } from '../db/GroupMail'; +import { ServerMailModel, ServerMailType } from '../db/ServerMail'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; @@ -65,6 +68,8 @@ export async function init() { // 每天邮件 scheduleJob('circleMail', '0 0 3 * * ?', sendCircleMail); + // 每小时查询邮件推送 + checkMailByHour(); // 军团活动排行榜 guildActivitySchedule(); @@ -400,19 +405,90 @@ function clearAuctionSchedule() { // —————————————— 邮件 —————————————— // async function sendCircleMail() { let gmmails = await GMMailModel.findCircleMails(pinus.app.get('env')); + let f = new SendMailFun(); for(let gmmail of gmmails) { let { receivers, mailType } = gmmail; - let f = new SendMailFun(); - await f.setWithGmMail(gmmail); - - if (mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) { - let roleIds = receivers.map(cur => cur.roleId); - await f.sendToUsers(mailType, roleIds); - } else { - let serverIds = receivers.map(cur => cur.serverId); - await f.sendToServer(serverIds); + let code = await f.setWithGmMail(gmmail); + if(mailType == GM_MAIL_TYPE.SINGLE) { + await f.createSingleMails(code, receivers.map(cur => cur.roleId)); + } else if (mailType == GM_MAIL_TYPE.GROUP) { + await f.createGroupMails(code, receivers.map(cur => cur.roleId)); + } else if (mailType == GM_MAIL_TYPE.SERVER) { + await f.createServerMails(code, receivers.map(cur => cur.serverId)); } } + await f.pushToUsers(); +} + +let mailByHourJob: Job; +async function checkMailByHour() { + if(mailByHourJob) { + mailByHourJob.cancel(); + } + // 每小时一次,为了和每天循环邮件任务不重复,设在每小时05分 + mailByHourJob = scheduleJob('setMailTimerByHour', '0 5 0/1 * * ?', async () => { + await setMailSchedule(false) + }); + setMailSchedule(true); // 初始时候启动一次 +} + +async function setMailSchedule(isInit: boolean) { + console.log('####### setMailSchedule') + let minuteNow = moment().minute(); + let beforeTime = minuteNow >= 5? moment().minute(5).unix(): moment().minute(5).add(-1, 'h').unix(); + let time = minuteNow >= 5? moment().minute(5).add(1, 'h').unix(): moment().minute(5).unix(); + + let mails = await MailModel.findByTimeGap(beforeTime, time); + let groupMails = await GroupMailModel.findByTimeGap(beforeTime, time); + let serverMails = await ServerMailModel.findByTimeGap(beforeTime, time); + + let times: number[] = []; + for(let { sendTime } of [...mails, ...groupMails, ...serverMails]) { + if(times.indexOf(sendTime) == -1) times.push(sendTime); + } + + for(let time of times) { + if(Date.now() > time * 1000) { + if(!isInit) await pushMailSchedule(time); + } else { + scheduleJob(`mailPush${time}`, time * 1000, async () => { + await pushMailSchedule(time); + }); + } + } +} + +// 当前时间到下一次定时器之间的定时器 +export async function addMailsToSchedule(mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) { + console.log('####### addMailsToSchedule') + let minuteNow = moment().minute(); + let time = minuteNow >= 5? moment().minute(5).add(1, 'h').unix(): moment().minute(5).unix(); + + let times: number[] = []; + for(let { sendTime } of [...mails, ...groupMails, ...serverMails]) { + if(sendTime * 1000 > Date.now() && sendTime < time && times.indexOf(sendTime) == -1) times.push(sendTime); + } + + console.log('#######', times); + for(let time of times) { + if(!scheduledJobs[`mailPush${time}`]) { + scheduleJob(`mailPush${time}`, time * 1000, async () => { + await pushMailSchedule(time); + }) + } + } +} + +async function pushMailSchedule(time: number) { + if(scheduledJobs[`mailPush${time}`]) scheduledJobs[`mailPush${time}`].cancel(); + + let mails = await MailModel.findBySendTime(time); + let groupMails = await GroupMailModel.findBySendTime(time); + let serverMails = await ServerMailModel.findBySendTime(time); + + let f = new SendMailFun(); + f.setMails(mails, groupMails, serverMails); + await f.pushToUsers(); } // —————————————— 邮件 end —————————————— // diff --git a/shared/db/GroupMail.ts b/shared/db/GroupMail.ts index 147b4140b..9ba13e6f4 100644 --- a/shared/db/GroupMail.ts +++ b/shared/db/GroupMail.ts @@ -20,6 +20,9 @@ export default class GroupMail extends MailTemp { @prop({ required: true, type: RoleStatus }) roleStatus: RoleStatus[]; + @prop({ required: false }) + guildCode: string; + /** * @description 根据玩家id获得所有有效邮件 * @param {String} roleId 玩家id @@ -113,6 +116,16 @@ export default class GroupMail extends MailTemp { 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; diff --git a/shared/db/Mail.ts b/shared/db/Mail.ts index 5b7256428..fba9d8e57 100644 --- a/shared/db/Mail.ts +++ b/shared/db/Mail.ts @@ -111,7 +111,15 @@ export default class Mail extends MailTemp { return result; } + public static async findByTimeGap(beforeTime: number, time: number) { + const result: MailType[] = await MailModel.find({ sendTime: { $gt: beforeTime, $lte: time } }).lean(); + return result; + } + public static async findBySendTime(time: number) { + const result: MailType[] = await MailModel.find({ sendTime: time }).lean(); + return result; + } /** * 查询有奖励的邮件 diff --git a/shared/db/ServerMail.ts b/shared/db/ServerMail.ts index eb8e7b596..61ee895d6 100644 --- a/shared/db/ServerMail.ts +++ b/shared/db/ServerMail.ts @@ -43,6 +43,16 @@ export default class ServerMail extends MailTemp { 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