邮件:定时邮件优化

This commit is contained in:
luying
2022-02-23 19:06:31 +08:00
parent 38a4c41953
commit 0436215f3a
11 changed files with 281 additions and 111 deletions
@@ -74,7 +74,8 @@ export class GmHandler {
let needSend = false; let needSend = false;
if(isPass) { if(isPass) {
if(timeType == MAIL_TIME_TYPE.CIRCLE) { 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(); let sendTime = moment(moment().format('YYYY-MM-DD '+circleHour)).unix();
if(sendTime < refTime) sendTime += 86400; if(sendTime < refTime) sendTime += 86400;
let now = nowSeconds(); let now = nowSeconds();
@@ -87,15 +88,20 @@ export class GmHandler {
} }
if(needSend) { if(needSend) {
let f = new SendMailFun(); 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) { 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); 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 { } else {
let serverIds = receivers.filter(cur => cur.env == this.app.get('env')).map(cur => cur.serverId); 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); // await f.saveRecord(uid);
} }
let sendTime = ''; let sendTime = '';
@@ -14,7 +14,7 @@ import { GuildLeader } from '../../../domain/rank';
import { UserGuildApplyModel } from '../../../db/UserGuildApply'; import { UserGuildApplyModel } from '../../../db/UserGuildApply';
import { hasStructureConsume, getStructureConsume, gameData } from '../../../pubUtils/data'; import { hasStructureConsume, getStructureConsume, gameData } from '../../../pubUtils/data';
import { GuildRecModel } from '../../../db/GuildRec'; 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 { updateUserInfo, isRoleOnline, getRoleOnlineInfo } from '../../../services/redisService';
import { openGuildRefine } from '../../../services/guildRefineService'; import { openGuildRefine } from '../../../services/guildRefineService';
@@ -814,9 +814,7 @@ export class GuildHandler {
const { members } = guild; const { members } = guild;
//下发邮件 //下发邮件
let f = new SendMailFun(); await sendMailToGuildByContent(MAIL_TYPE.SEND_MAIL, code, { sendName: roleName, params: [info] }, guild);
f.setWithContentId(MAIL_TYPE.SEND_MAIL, { sendName: roleName, params: [info] });
await f.sendToGuild(code, members);
return resResult(STATUS.SUCCESS, { isSuccess: true }); return resResult(STATUS.SUCCESS, { isSuccess: true });
} }
@@ -1,5 +1,5 @@
import { Application, ChannelService } from 'pinus'; 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 PvpDefenseType from '../../../db/PvpDefense';
import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity'; import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity';
import { reloadResources } from '../../../pubUtils/data'; import { reloadResources } from '../../../pubUtils/data';
@@ -11,6 +11,9 @@ import { MarqueeType } from '../../../db/Marquee';
import { taflush } from '../../../services/sdkService'; import { taflush } from '../../../services/sdkService';
import { RegionType } from '../../../db/Region'; import { RegionType } from '../../../db/Region';
import { errlogger } from '../../../util/logger'; 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) { export default function (app: Application) {
return new SystimerRemote(app); return new SystimerRemote(app);
@@ -178,4 +181,12 @@ export class SystimerRemote {
errlogger.error(`remote ${__filename} \n ${e.stack}`); 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}`);
}
}
} }
+3 -2
View File
@@ -163,8 +163,9 @@ export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: St
} }
if(needSend) { if(needSend) {
let f = new SendMailFun(); let f = new SendMailFun();
await f.setWithGmMail(gmmail); let code = await f.setWithGmMail(gmmail);
await f.sendToServer([newServer.id]); await f.createServerMails(code, [newServer.id]);
await f.pushToUsers();
} }
return true; return true;
} }
+4 -5
View File
@@ -223,14 +223,14 @@ export async function addActive(roleId: string, serverId: number, id: number, ty
* @param roleId 用户id * @param roleId 用户id
* @param select 筛选字段 * @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'); let userGuild = await UserGuildModel.getMyGuild(roleId, select ? select + ' wishGoods +refTimeDaily' : '+refTimeDaily');
// console.log(JSON.stringify(userGuild)) // console.log(JSON.stringify(userGuild))
if (!userGuild) return false; 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; if(!userGuild) return false;
let { receivedActive, refTimeDaily, activeDaily, activeRecord, wishGoods, receivedWishPool } = userGuild; 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]; let donateName = donateNames[donateNames.length - i - 1];
await sendMailByContent(MAIL_TYPE.WISH_POOL_REWARD, roleId, { await sendMailByContent(MAIL_TYPE.WISH_POOL_REWARD, roleId, {
params: [donateName, goodInfo.name], params: [donateName, goodInfo.name],
goods: [{ id: goodId, count: drawCnt }], goods: [{ id: goodId, count: drawCnt }]
notPush
}); });
} }
}); });
+131 -83
View File
@@ -7,7 +7,7 @@ import { pinus } from "pinus";
import { gameData } from "../pubUtils/data"; import { gameData } from "../pubUtils/data";
import { nowSeconds } from '../pubUtils/timeUtil'; import { nowSeconds } from '../pubUtils/timeUtil';
import { STATUS } from '../consts/statusCode'; 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 { GM_MAIL_TYPE, ITID, MAIL_STATUS, MAIL_TIME_TYPE, MAIL_TYPE, SEND_NAME, SEND_TITLE } from "../consts";
import { MailParam } from '../domain/roleField/mail'; import { MailParam } from '../domain/roleField/mail';
import { GMMailType, GMMailModel, GMMailTypeParam } from "../db/GMMail"; import { GMMailType, GMMailModel, GMMailTypeParam } from "../db/GMMail";
@@ -53,26 +53,25 @@ function getMailInfos(roleId: string, mails: MailType[], groupMails: GroupMailTy
return list; 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(); let f = new SendMailFun();
f.setWithContentId(contentId, params); let code = f.setWithContentId(contentId, params);
await f.sendToUsers(GM_MAIL_TYPE.SINGLE, [hisRoleId]); 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) guild = await GuildModel.findByCode(guildCode, null, '+members');
if(!guild) return false; if(!guild) return false;
let f = new SendMailFun(); let f = new SendMailFun();
f.setWithContentId(contentId, params); let code = f.setWithContentId(contentId, params);
await f.sendToGuild(guildCode, guild.members); await f.createGroupMails(code, guild.members, guildCode);
await f.pushToUsers();
return true; return true;
} }
/** class MailTemp {
* 发送邮件方法类 public code: string;
*/
export class SendMailFun {
private mailType: GM_MAIL_TYPE = GM_MAIL_TYPE.SINGLE; // 邮件类型 1-单人 2-多人 3-全服
private contentId: MAIL_TYPE = MAIL_TYPE.SEND_MAIL; // 0-读GmMail,1以上读dicMail private contentId: MAIL_TYPE = MAIL_TYPE.SEND_MAIL; // 0-读GmMail,1以上读dicMail
private sendName: string = SEND_NAME; private sendName: string = SEND_NAME;
private title: string = SEND_TITLE; private title: string = SEND_TITLE;
@@ -82,13 +81,10 @@ export class SendMailFun {
private goods: RewardInter[] = []; // 发送的奖励 private goods: RewardInter[] = []; // 发送的奖励
private sendTime: number; private sendTime: number;
private endTime: number; private endTime: number;
private notPush: boolean = false;
private mails: MailType[] = [];
private groupMails: GroupMailType[] = [];
private serverMails: ServerMailType[] = [];
// 从dicMail读取数据 // 从dicMail读取数据
public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, params?: string[], goods?: RewardInter[] }) { public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, params?: string[], goods?: RewardInter[] }) {
this.code = genCode(8);
let dicMail = gameData.mail.get(contentId); let dicMail = gameData.mail.get(contentId);
this.contentId = contentId; this.contentId = contentId;
this.sendTime = nowSeconds(); this.sendTime = nowSeconds();
@@ -100,16 +96,8 @@ export class SendMailFun {
this.goods = params.goods||[]; 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) { public async setWithGmMail(gmmail: GMMailType) {
this.code = genCode(8);
this.gmmail = gmmail; this.gmmail = gmmail;
this.contentId = 0; this.contentId = 0;
if(gmmail.timeType == MAIL_TIME_TYPE.IMMEDIATE) { if(gmmail.timeType == MAIL_TIME_TYPE.IMMEDIATE) {
@@ -128,7 +116,15 @@ export class SendMailFun {
return gmmail; 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 { return {
contentId: this.contentId, contentId: this.contentId,
mail: this.gmmail?._id, mail: this.gmmail?._id,
@@ -141,94 +137,146 @@ export class SendMailFun {
hasGoods: this.hasGoods hasGoods: this.hasGoods
} }
} }
}
/**
* 发送邮件方法类
*/
export class SendMailFun {
private mailTemps = new Map<string, MailTemp>();
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[]) { public async createSingleMails(code: string, roleIds: string[]) {
let mails = new Map<string, MailParam>(); let mapTemp = this.mailTemps.get(code);
for(let roleId of roleIds) { 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); 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 => { let roleStatus = roleIds.map(roleId => {
return { roleId, status: MAIL_STATUS.CREATE } 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); this.groupMails.push(originMail);
return new MailParam(this.mailType, originMail);
} }
// 生成全服邮件 // 生成全服邮件
private async createServerMails(serverIds: number[]) { public async createServerMails(code: string, serverIds: number[]) {
let mails = new Map<number, MailParam>(); let mapTemp = this.mailTemps.get(code);
for(let serverId of serverIds) { for(let serverId of serverIds) {
let originMail = await ServerMailModel.addMail({ serverId, ...this.getCreateMailParams() }); let originMail = await ServerMailModel.addMail({ serverId, ...mapTemp.getCreateMailParams() });
mails.set(serverId, new MailParam(this.mailType, originMail));
this.serverMails.push(originMail); this.serverMails.push(originMail);
} }
return mails
} }
// 向某几个玩家推送 public async setMails(mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) {
public async sendToUsers(mailType: GM_MAIL_TYPE.SINGLE|GM_MAIL_TYPE.GROUP,roleIds: string[], myRoleId?: string, mySid?: string) { this.mails.push(...mails);
this.mailType = mailType; this.groupMails.push(...groupMails);
let uids: { uid: string, sid: string }[] = [] this.serverMails.push(...serverMails);
for(let roleId of roleIds) { }
let sid = '';
if(roleId == myRoleId) { // 将存储的邮件发出
sid = mySid; public async pushToUsers(myRoleId?: string, mySid?: string) {
} else { // 将可以发的邮件发出
let hisOnlineInfo = await getRoleOnlineInfo(roleId); let pushByRoleId = new Map<string, MailParam[]>();
if(hisOnlineInfo.isOnline) { let pushByGuildCode = new Map<string, MailParam[]>();
sid = hisOnlineInfo.sid; let pushByServerId = new Map<number, MailParam[]>();
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) { for(let [roleId, mails ] of pushByRoleId) {
let mails = await this.createSingleMails(roleIds); let uids = await this.getUids(roleId, myRoleId, mySid);
for(let { uid, sid } of uids) { console.log('###### onMailsAdd', uids, mails);
let mail = mails.get(uid); if(uids.length > 0 && mails.length > 0) {
if(uids.length > 0 && mail && !this.notPush) pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: [mail] }), [{ uid, sid }]); 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);
} }
// 向军团推送 private async getUids(roleId: string, myRoleId?: string, mySid?: string) {
public async sendToGuild(guildCode: string, members: string[]) { let uids: { uid: string, sid: string }[] = [];
this.mailType = GM_MAIL_TYPE.GROUP; let sid = '';
let mails = await this.createGroupMails(members); if(roleId == myRoleId) {
let chatSid = await getGuildChannelSid(guildCode); sid = mySid;
if(!this.notPush) pinus.app.rpc.chat.guildRemote.sendMailToGuild.toServer(chatSid, guildCode, 'onMailsAdd', { mails }); } else {
} let hisOnlineInfo = await getRoleOnlineInfo(roleId);
if(hisOnlineInfo.isOnline) {
// 向全服推送 sid = hisOnlineInfo.sid;
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] });
} }
} }
if(!!sid) {
uids.push({ uid: roleId, sid });
}
return uids;
} }
public async saveRecord(createUid: number) { public async saveRecord(createUid: number) {
+3 -3
View File
@@ -544,7 +544,7 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer,
* @param seasonNum * @param seasonNum
* @param oldSeasonEndTime * @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 pvpSeasonResult = await savePvpSeasonResult(pvpDefense, seasonNum, seasonEndTime);
let { rankGoods, heroGoods, rankLv } = pvpSeasonResult; let { rankGoods, heroGoods, rankLv } = pvpSeasonResult;
@@ -552,12 +552,12 @@ export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum:
if (!!rankGoods.length) //排名奖励 if (!!rankGoods.length) //排名奖励
await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, pvpDefense.roleId, { await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, pvpDefense.roleId, {
params: [JSON.stringify(seasonNum), (rankLv > 1000 ? '999+' : JSON.stringify(rankLv))], params: [JSON.stringify(seasonNum), (rankLv > 1000 ? '999+' : JSON.stringify(rankLv))],
goods: rankGoods, notPush goods: rankGoods
}); });
if (!!heroGoods.length) //武将功勋奖励 if (!!heroGoods.length) //武将功勋奖励
await sendMailByContent(MAIL_TYPE.PVP_RESULT, pvpDefense.roleId, { await sendMailByContent(MAIL_TYPE.PVP_RESULT, pvpDefense.roleId, {
params: [JSON.stringify(seasonNum)], params: [JSON.stringify(seasonNum)],
goods: heroGoods, notPush goods: heroGoods
}); });
return { return {
+85 -9
View File
@@ -32,6 +32,9 @@ import { createMarqueeMsg, pushMarqueeMsg } from './sysChatService';
import { RegionModel, RegionType } from '../db/Region'; import { RegionModel, RegionType } from '../db/Region';
import { CreateServerParam } from '../domain/backEndField/params'; import { CreateServerParam } from '../domain/backEndField/params';
import { infologger } from '../util/logger'; 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_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60; const PER_DAY = 24 * 60 * 60;
@@ -65,6 +68,8 @@ export async function init() {
// 每天邮件 // 每天邮件
scheduleJob('circleMail', '0 0 3 * * ?', sendCircleMail); scheduleJob('circleMail', '0 0 3 * * ?', sendCircleMail);
// 每小时查询邮件推送
checkMailByHour();
// 军团活动排行榜 // 军团活动排行榜
guildActivitySchedule(); guildActivitySchedule();
@@ -400,19 +405,90 @@ function clearAuctionSchedule() {
// —————————————— 邮件 —————————————— // // —————————————— 邮件 —————————————— //
async function sendCircleMail() { async function sendCircleMail() {
let gmmails = await GMMailModel.findCircleMails(pinus.app.get('env')); let gmmails = await GMMailModel.findCircleMails(pinus.app.get('env'));
let f = new SendMailFun();
for(let gmmail of gmmails) { for(let gmmail of gmmails) {
let { receivers, mailType } = gmmail; let { receivers, mailType } = gmmail;
let f = new SendMailFun(); let code = await f.setWithGmMail(gmmail);
await f.setWithGmMail(gmmail); if(mailType == GM_MAIL_TYPE.SINGLE) {
await f.createSingleMails(code, receivers.map(cur => cur.roleId));
if (mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) { } else if (mailType == GM_MAIL_TYPE.GROUP) {
let roleIds = receivers.map(cur => cur.roleId); await f.createGroupMails(code, receivers.map(cur => cur.roleId));
await f.sendToUsers(mailType, roleIds); } else if (mailType == GM_MAIL_TYPE.SERVER) {
} else { await f.createServerMails(code, receivers.map(cur => cur.serverId));
let serverIds = receivers.map(cur => cur.serverId);
await f.sendToServer(serverIds);
} }
} }
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 —————————————— // // —————————————— 邮件 end —————————————— //
+13
View File
@@ -20,6 +20,9 @@ export default class GroupMail extends MailTemp {
@prop({ required: true, type: RoleStatus }) @prop({ required: true, type: RoleStatus })
roleStatus: RoleStatus[]; roleStatus: RoleStatus[];
@prop({ required: false })
guildCode: string;
/** /**
* @description 根据玩家id获得所有有效邮件 * @description 根据玩家id获得所有有效邮件
* @param {String} roleId 玩家id * @param {String} roleId 玩家id
@@ -113,6 +116,16 @@ export default class GroupMail extends MailTemp {
return result; 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) { 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(); const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId, sendTime:{$lte: nowSeconds()} }, {$set:{ 'roleStatus.$.status': status }}, { new: true }).lean();
return result; return result;
+8
View File
@@ -111,7 +111,15 @@ export default class Mail extends MailTemp {
return result; 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;
}
/** /**
* 查询有奖励的邮件 * 查询有奖励的邮件
+10
View File
@@ -43,6 +43,16 @@ export default class ServerMail extends MailTemp {
return result; 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 创建邮件 * @description 创建邮件
* @param params * @param params