361 lines
14 KiB
TypeScript
361 lines
14 KiB
TypeScript
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 || params.sendName) this.sendName = params.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<string, MailTemp>();
|
||
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<string, MailParam[]>();
|
||
let pushByGuildCode = new Map<string, MailParam[]>();
|
||
let pushByServerId = new Map<number, MailParam[]>();
|
||
|
||
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
|
||
}
|
||
} |