import { RewardInter, pushMail, mailData } from "../pubUtils/interface"; import { MailModel, MailType } from "../db/Mail"; import { GroupMailModel, GroupMailType } from "../db/GroupMail"; import { ServerMailModel, ServerMailType } from '../db/ServerMail'; import { getRoleOnlineInfo } from "./redisService"; import { pinus } from "pinus"; import { gameData } from "../pubUtils/data"; import { getCurDay, nowSeconds } from '../pubUtils/timeUtil'; import { STATUS } from '../consts/statusCode'; import { genCode, resResult } from '../pubUtils/util'; import { GM_MAIL_TYPE, ITID, MAIL_STATUS, MAIL_TIME_TYPE, MAIL_TYPE, PUSH_ROUTE, SEND_NAME, SEND_TITLE } from "../consts"; import { MailParam } from '../domain/roleField/mail'; import { GMMailType, GMMailModel, GMMailTypeParam } from "../db/GMMail"; import { getGuildChannelSid, getWorldChannelSid } from "./chatChannelService"; import { GMMailRecordModel } from "../db/GMMailRecord"; import { BAG } from "../pubUtils/dicParam"; import { GuildModel, GuildType } from "../db/Guild"; import moment = require("moment"); import { sendMessageToGuildWithSuc, sendMessageToServerWithSuc, sendMessageToUsersWithSuc } from "./pushService"; /** * 获取邮件信息 * @param {String} roleId 玩家id * @param {Number} serverId 服务器id */ export async function getMails(roleId: string, serverId: number) { let mails = await MailModel.findByRoleId(roleId)||[]; let groupMails = await GroupMailModel.findByRoleId(roleId)||[]; let serverMails = await ServerMailModel.findByRoleId(roleId, serverId)||[]; let list = getMailInfos(roleId, mails, groupMails, serverMails); list.sort((a, b) => a.sendTime - b.sendTime); return list; } /** * 根据数据库数据,生成返回数据 * @param {String} roleId 玩家id * @param {MailType[]} mails 单人邮件 * @param {GroupMailType[]} groupMails 多人邮件 * @param {ServerMailType[]} serverMails 全服邮件 */ function getMailInfos(roleId: string, mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) { let list: MailParam[] = []; // 结果 for(let mail of mails) { list.push(new MailParam( GM_MAIL_TYPE.SINGLE, mail, roleId)); } for(let mail of groupMails) { list.push(new MailParam(GM_MAIL_TYPE.GROUP, mail, roleId)); } for(let mail of serverMails) { list.push(new MailParam(GM_MAIL_TYPE.SERVER, mail, roleId)); } return list; } export async function sendMailByContent(contentId: MAIL_TYPE, hisRoleId: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[] }) { let f = new SendMailFun(); 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[] }, guild?: GuildType) { if(!guild) guild = await GuildModel.findByCode(guildCode, null, '+members'); if(!guild) return false; let f = new SendMailFun(); let code = f.setWithContentId(contentId, params); await f.createGroupMails(code, guild.members, guildCode); await f.pushToUsers(); return true; } export async function sendMailsByGmMail(gmmails: GMMailType[]) { let f = new SendMailFun(); for(let gmmail of gmmails) { let { receivers, mailType, sendTimes } = gmmail; let code = await f.setWithGmMail(gmmail); if(!code) continue; let mapTemp = f.getMailTemp(code); if(sendTimes.indexOf(mapTemp.sendTime) == -1 && checkCanSend(gmmail, mapTemp)) { 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(); } function checkCanSend(gmmail: GMMailType, mapTemp: MailTemp ) { let { circleStart, circleEnd, timeType } = gmmail; if(timeType == MAIL_TIME_TYPE.CIRCLE) { if(circleStart > mapTemp.sendTime || circleEnd < mapTemp.sendTime) return false; } return true; } class MailTemp { public code: string; public gmmail: GMMailTypeParam; private contentId: MAIL_TYPE = MAIL_TYPE.SEND_MAIL; // 0-读GmMail,1以上读dicMail private sendName: string = SEND_NAME; private title: string = SEND_TITLE; private content: string = ''; private hasGoods: boolean = false; // 是否内含奖励 private goods: RewardInter[] = []; // 发送的奖励 public sendTime: number; private endTime: number; // 从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(); this.endTime = this.sendTime + dicMail?.time||0; this.content = this.getContent(dicMail.content, params.params); if(dicMail.title) this.title = dicMail.title; if(dicMail.sendName) this.sendName = dicMail.sendName; this.hasGoods = params.goods?.length > 0; this.goods = params.goods||[]; } public async setWithGmMail(gmmail: GMMailType) { if(gmmail.timeType == MAIL_TIME_TYPE.IMMEDIATE) { this.sendTime = nowSeconds(); } else if (gmmail.timeType == MAIL_TIME_TYPE.DELAY) { this.sendTime = gmmail.startTime; } else if (gmmail.timeType == MAIL_TIME_TYPE.CIRCLE) { let time = moment(moment().format('YYYY-MM-DD ' + gmmail.circleHour)).unix(); if(time < nowSeconds()) { if(gmmail.circleDay == 0) { time += 86400; } else { let date = getCurDay(true); // 今天星期几 if(date < gmmail.circleDay) { time += (gmmail.circleDay - date) * 86400; } else { time += (7 + date - gmmail.circleDay) * 86400; } } } this.sendTime = time; } this.code = genCode(8); this.gmmail = gmmail; this.contentId = 0; this.endTime = this.sendTime + gmmail.expire * 60 * 60; this.sendName = gmmail.sendName; this.title = gmmail.title; this.content = gmmail.content; this.hasGoods = gmmail.hasGoods; this.goods = gmmail.goods; return true; } 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, gmmailId: this.gmmail?._id, sendTime: this.sendTime, endTime: this.endTime, goods: this.goods, title: this.title, sendName: this.sendName, content: this.content, hasGoods: this.hasGoods } } } /** * 发送邮件方法类 */ export class SendMailFun { private mailTemps = new Map(); private mails: MailType[] = []; private groupMails: GroupMailType[] = []; private serverMails: ServerMailType[] = []; public getMailTemp(code: string) { return this.mailTemps.get(code); } // 从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(); let canSet = mailTemp.setWithGmMail(gmmail); if(!canSet) return false this.mailTemps.set(mailTemp.code, mailTemp); return mailTemp.code; } // 生成单人邮件 public async createSingleMails(code: string, roleIds: string[]) { let mapTemp = this.mailTemps.get(code); if(mapTemp.sendTime < nowSeconds()) return; for(let roleId of roleIds) { let originMail = await MailModel.addMail({ roleId, ...mapTemp.getCreateMailParams() }); this.mails.push(originMail); } if(mapTemp.gmmail) await GMMailModel.sendMail(mapTemp.gmmail._id, mapTemp.sendTime); } // 生成多人邮件 public async createGroupMails(code: string, roleIds: string[], guildCode?: string) { let mapTemp = this.mailTemps.get(code); if(mapTemp.sendTime < nowSeconds()) return; let roleStatus = roleIds.map(roleId => { return { roleId, status: MAIL_STATUS.CREATE } }) let originMail = await GroupMailModel.addMail({ roleStatus, guildCode, ...mapTemp.getCreateMailParams() }); if(mapTemp.gmmail) await GMMailModel.sendMail(mapTemp.gmmail._id, mapTemp.sendTime); this.groupMails.push(originMail); } // 生成全服邮件 public async createServerMails(code: string, serverIds: number[]) { let mapTemp = this.mailTemps.get(code); // console.log('###### createServerMails 1', code, this.mailTemps, mapTemp) if(mapTemp.sendTime < nowSeconds()) return; for(let serverId of serverIds) { let originMail = await ServerMailModel.addMail({ serverId, ...mapTemp.getCreateMailParams() }); this.serverMails.push(originMail); } if(mapTemp.gmmail) await GMMailModel.sendMail(mapTemp.gmmail._id, mapTemp.sendTime); } 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) { 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); } } 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); } } } } 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); } } for(let [roleId, mails ] of pushByRoleId) { let uids = await this.getUids(roleId, myRoleId, mySid); if(uids.length > 0 && mails.length > 0) { sendMessageToUsersWithSuc(PUSH_ROUTE.MAILS_ADD, { mails }, uids); } } for(let [guildCode, mails] of pushByGuildCode) { if(mails.length > 0) { await sendMessageToGuildWithSuc(guildCode, PUSH_ROUTE.MAILS_ADD, { mails }); } } for(let [serverId, mails] of pushByServerId) { if( mails.length > 0) { await sendMessageToServerWithSuc(serverId, PUSH_ROUTE.MAILS_ADD, { mails }, true); } } // 延时邮件,设置定时器 pinus.app.rpc.systimer.systimerRemote.addMailsToSchedule.broadcast(this.mails, this.groupMails, this.serverMails); } 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) { for(let mail of this.mails) { await GMMailRecordModel.createRecord(GM_MAIL_TYPE.SINGLE, mail, createUid); } for(let mail of this.groupMails) { await GMMailRecordModel.createRecord(GM_MAIL_TYPE.GROUP, mail, createUid); } for(let mail of this.serverMails) { await GMMailRecordModel.createRecord(GM_MAIL_TYPE.SERVER, mail, createUid); } } } export function checkMailGoods(mail: MailType | GroupMailType | ServerMailType, jewelCount: number) { let isEquipOver = false; for (let good of mail.goods) { let dicGoods = gameData.goods.get(good.id); let dicItid = ITID.get(dicGoods.itid); if (dicItid.table == 'jewel') { // 装备 if (++jewelCount > BAG.BAG_EQUIP_UPLIMITED) { isEquipOver = true; break; } } } return { isEquipOver, jewelCount } }