邮件:修改邮件逻辑

This commit is contained in:
luying
2021-06-28 13:31:29 +08:00
parent 2ffe0f7890
commit 3b1d458a87
29 changed files with 932 additions and 626 deletions

View File

@@ -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 { sendMail } from '../../../services/mailService';
import { sendMailByContent, SendMailFun } from '../../../services/mailService';
import { updateUserInfo, isRoleOnline, getRoleOnlineInfo } from '../../../services/redisService';
import { openGuildRefine } from '../../../services/guildRefineService';
@@ -231,17 +231,15 @@ export class GuildHandler {
const rec = await GuildRecModel.createGuildRec(roleId, code, GUILD_REC_TYPE.SET_MANAGER, [role.roleName]);
this.app.rpc.chat.guildRemote.updateInfo.toServer(chatSid, code, { managerCnt: guild.managerCnt });
this.app.rpc.chat.guildRemote.addRec.toServer(chatSid, rec);
await sendMail(MAIL_TYPE.GUILD_BE_SET_MANAGER, memberRoleId, roleName, [guild.name]);
await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_MANAGER, memberRoleId, { sendName: roleName, params: [guild.name] });
} else if (auth == GUILD_AUTH.LEADER) {
const rec = await GuildRecModel.createGuildRec(roleId, code, GUILD_REC_TYPE.SET_LEADER, [roleName, role.roleName]);
this.app.rpc.chat.guildRemote.changeLeader.toServer(chatSid, code, guild.managerCnt, role, roleId);
this.app.rpc.chat.guildRemote.addRec.toServer(chatSid, rec);
await sendMail(MAIL_TYPE.GUILD_BE_SET_LEADER, memberRoleId, roleName, [guild.name]);
await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_LEADER, memberRoleId, { sendName: roleName, params: [guild.name] });
} else {
this.app.rpc.chat.guildRemote.updateInfo.toServer(chatSid,code, { managerCnt: guild.managerCnt });
await sendMail(MAIL_TYPE.GUILD_BE_SET_MEMBER, memberRoleId, roleName, [guild.name]);
await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_MEMBER, memberRoleId, { sendName: roleName, params: [guild.name] });
}
@@ -383,7 +381,7 @@ export class GuildHandler {
}
} else { // 拒绝申请,删除申请
for(let { roleId } of applyList) {
await sendMail(MAIL_TYPE.GUILD_APPLY_REFUSE, roleId, roleName, [guild.name]);
await sendMailByContent(MAIL_TYPE.GUILD_APPLY_REFUSE, roleId, { sendName: roleName, params: [guild.name] });
}
await UserGuildApplyModel.deleteByApplyCode(applyCodeList);
@@ -678,7 +676,7 @@ export class GuildHandler {
// 添加动态
const rec = await GuildRecModel.createGuildRec(roleId, code, GUILD_REC_TYPE.QUIT_GUILD, [role.roleName]);
this.app.rpc.chat.guildRemote.addRec.toServer(chatSid,rec);
await sendMail(MAIL_TYPE.GUILD_BE_KICK, memberRoleId, roleName, [guild.name]);
await sendMailByContent(MAIL_TYPE.GUILD_BE_KICK, memberRoleId, { sendName: roleName, params: [guild.name] });
return resResult(STATUS.SUCCESS, { memberCnt: guild.memberCnt });
}
@@ -733,8 +731,8 @@ export class GuildHandler {
this.app.rpc.chat.guildRemote.addRec.toServer(chatSid,rec);
this.app.rpc.chat.guildRemote.changeLeader.toServer(chatSid,code, guild.managerCnt, topUser, leaderRoleId);
await sendMail(MAIL_TYPE.GUILD_BE_IMPEACH, leaderRoleId, roleName, [guild.name]);
await sendMail(MAIL_TYPE.GUILD_BE_SET_LEADER, topUser.roleId, roleName, [guild.name]);
await sendMailByContent(MAIL_TYPE.GUILD_BE_IMPEACH, leaderRoleId, { sendName: roleName, params: [guild.name] });
await sendMailByContent(MAIL_TYPE.GUILD_BE_SET_LEADER, topUser.roleId, { sendName: roleName, params: [guild.name] });
await updateUserInfo(REDIS_KEY.GUILD_INFO, code, [{field: 'leader', value: new GuildLeader(topUser) } ]);
@@ -837,9 +835,9 @@ export class GuildHandler {
const { members } = guild;
//下发邮件
for(let roleId of members) {
await sendMail(MAIL_TYPE.SEND_MAIL, roleId, roleName, [info]);
}
let f = new SendMailFun();
f.setWithContentId(MAIL_TYPE.SEND_MAIL, { sendName: roleName, params: [info] });
await f.sendToGuild(code, members);
return resResult(STATUS.SUCCESS, { isSuccess: true });
}

View File

@@ -9,6 +9,7 @@ import { getWorldChannelSid, groupRoomId } from '../../../services/chatService';
import { reloadResources } from '../../../pubUtils/data';
import { GeneralRankParamRole, GeneralRankParamBattle } from '../../../domain/rank';
import { getAllGuildActivityStatus } from '../../../services/guildActivityService';
import { MailParam } from '../../../domain/roleField/mail';
export default function (app: Application) {
return new ChatRemote(app);
@@ -225,4 +226,17 @@ export class ChatRemote {
let guildActivities = getAllGuildActivityStatus();
channel.pushMessage(this.GUILD_ACTIVITY_STATUS_UPDATE, resResult(STATUS.SUCCESS, { guildActivities }));
}
/**
* 向全服推送邮件
* @param serverId 服务器id
* @param path 推送地址
* @param mails 邮件内容
*/
public async sendMail(serverId: number, path: string, data: { mails: MailParam[] }) {
let roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
let channel = this.channelService.getChannel(roomId, false);
if (!channel) return;
channel.pushMessage(path, resResult(STATUS.SUCCESS, data));
}
}

View File

@@ -6,6 +6,7 @@ import { RoleType } from '../../../db/Role';
import { GuildRecType } from '../../../db/GuildRec';
import { leaveGuildChannel, groupRoomId } from '../../../services/chatService';
import { GuildRankParams, WoodenHorse, Event } from '../../../domain/battleField/guildActivity';
import { MailParam } from '../../../domain/roleField/mail';
export default function (app: Application) {
return new GuildRemote(app);
@@ -35,6 +36,7 @@ export class GuildRemote {
private GUILD_RACE_UPDATE = 'onRaceHorseUpdate'; /// 更新木牛流马
private GUILD_RACE_EVENT = 'onRaceEventUpdate'; /// 更新木牛流马
private GUILD_POP_UP_ACTIVITY = 'onActivityUpdate'; /// 向军团成员发送弹窗礼包
private GUILD_TRAIN_RESET = 'onGuildTainReset'; // 试炼场重置
/**
* 封装军团相关channel名: 'guild'+guildCode
@@ -285,11 +287,26 @@ export class GuildRemote {
}
/**
* @description 向军团推送弹窗礼包数据活动
* @param guildCode
*/
* @description 向军团推送弹窗礼包数据活动
* @param guildCode
*/
public async sendPopUpActivity(guildCode: string, data: any[]) {
console.log("sendPopUpActivity")
this.pushMessage(guildCode, this.GUILD_POP_UP_ACTIVITY, data);
}
/**
* @description 军团邮件
* @param guildCode 军团code
* @param path 推送地址
* @param data 军团内容
*/
public async sendMailToGuild(guildCode: string, path: string, data: { mails: MailParam[]}) {
this.pushMessage(guildCode, path, data);
}
public async sendTrainReset(guildCode: string) {
this.pushMessage(guildCode, this.GUILD_TRAIN_RESET, {});
}
}

View File

@@ -1,9 +1,4 @@
import { Application, ChannelService, FrontendSession, RemoterClass } from 'pinus';
import { setGmMails, getGmMailById, getGmMails } from '../../../pubUtils/gmData/gmDataUtil';
import { MAIL_TYPE, MAIL_TEM_TYPE } from "../../../consts/constModules/mailConst";
import { mailData } from "../../../pubUtils/interface";
import { getContent } from '../../../services/mailService';
import { findWhere } from 'underscore';
export default function (app: Application) {
return new GateRemote(app);
}

View File

@@ -8,6 +8,9 @@ import { GMMailModel } from '../../../db/GMMail';
import { setGmMails } from '../../../pubUtils/gmData/gmDataUtil';
import { getRoleOnlineInfo } from '../../../services/redisService';
import { dispatch } from '../../../util/dispatcher';
import { SendMailFun } from '../../../services/mailService';
import { GM_MAIL_TYPE } from '../../../consts';
import { RewardInter } from '../../../pubUtils/interface';
export default function(app: Application) {
return new GmHandler(app);
}
@@ -75,11 +78,34 @@ export class GmHandler {
}
//对接gm后台下发邮件
async addMail(msg: { endTime: number, serverId: number, sendName: string, content: string, goods, sendRoles:[{roleId: string, status: number}], gmMailType: number, sendTime: number }) {
let {sendRoles, endTime, content, sendName, gmMailType, sendTime, goods, serverId} = msg;
let mail = await GMMailModel.addMail({serverId, sendRoles, sendName, endTime, content, gmMailType, sendTime, goods});
setGmMails([mail]);//更新邮件缓存
this.app.rpc.role.roleRemote.sendGmMailsToRoles.toServer('role-server-1',[mail]);//检查是否是群体邮件并下发群体邮件非群体邮件通过Filter刷新下发
async addMail(msg: { endTime: number, sendName: string, content: string, goods: RewardInter[], sendTime: number }) {
let {endTime, content, sendName, sendTime, goods } = msg;
let mail = await GMMailModel.addMail({endTime, content, sendName, sendTime, goods});
return resResult(STATUS.SUCCESS, { mail });
}
async sendMail(msg: { id: string, mailType: number, roleIds?: string[], serverIds?: number[] }, session: BackendSession) {
let { id, mailType, roleIds, serverIds } = msg;
let f = new SendMailFun();
await f.setWithGmMail(id);
if(mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) {
await f.sendToUsers(mailType, roleIds);
} else {
await f.sendToServer(serverIds);
}
return resResult(STATUS.SUCCESS);
}
async sendWithContent(msg: { contentId: number, mailType: number, params: { params?: string[], sendName?: string, goods?: RewardInter[], endTime?: number}, roleIds?: string[], serverIds?: number[] }, session: BackendSession) {
let { contentId, mailType, roleIds, serverIds, params } = msg;
let f = new SendMailFun();
f.setWithContentId(contentId, params);
if(mailType == GM_MAIL_TYPE.SINGLE || mailType == GM_MAIL_TYPE.GROUP) {
await f.sendToUsers(mailType, roleIds);
} else {
await f.sendToServer(serverIds);
}
return resResult(STATUS.SUCCESS);
}
async reloadResource(msg: {}, session: BackendSession) {

View File

@@ -4,7 +4,6 @@ import { STATUS } from '../../../consts';
import { setGmMails, getGmMailById, getGmMails, getGmUseMails } from '../../../pubUtils/gmData/gmDataUtil';
import { MAIL_TYPE, MAIL_TEM_TYPE, MAIL_STATUS } from "../../../consts/constModules/mailConst";
import { mailData } from "../../../pubUtils/interface";
import { getContent } from '../../../services/mailService';
import { findWhere } from 'underscore';
import { nowSeconds } from '../../../pubUtils/timeUtil';
import { GroupMailType } from '../../../db/GroupMail';
@@ -104,53 +103,7 @@ export class GMRemote {
public refreshGmMails(mails:[any]) {
setGmMails(mails);
}
/**
* 获得邮件详情信息
* @param roleId
* @param serverId
* @param mails
* @param groupMails
*/
public getMailInfos(roleId: string, serverId: number, mails: [any], groupMails: [any]) {
let list: mailData[] = [];
let nowTime = nowSeconds();
//单个邮件
mails.map(function({ mailId, goods, sendTime, params, status, _id, mailTemType, sendName, endTime}) {
if (mailTemType == MAIL_TEM_TYPE.GAMEMAIL) { //gm邮件检查是否超时并获得gm邮件的contentsendName endTime sendTime goods等信息
if (endTime < nowTime)
return;
let { content } = getContent(parseInt(mailId), params);
if (!content)
return;
list.push({ id: _id, goods, sendTime, endTime, content, status, mailType: MAIL_TYPE.SINGLEMAIL, sendName });
} else if (mailTemType == MAIL_TEM_TYPE.GMTYPE) { //系统邮件
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail)
return;
let { goods, sendTime, content, endTime, sendName } = gmMail;
list.push({ id: _id, goods, sendTime, endTime, content, status, mailType: MAIL_TYPE.SINGLEMAIL, sendName });
}
});
//群体邮件
groupMails.map(function({ mailId, goods, sendTime, endTime, params, sendRoles, _id, mailTemType, sendName }) {
let { status } = findWhere(sendRoles, {roleId});
if (mailTemType == MAIL_TEM_TYPE.GAMEMAIL) { //gm邮件检查是否超时并获得gm邮件的contentsendName endTime sendTime goods等信息
if (endTime < nowTime)
return;
let { content } = getContent( parseInt(mailId), params);
if (!content)
return;
list.push({ id: _id, goods, sendTime, content, endTime, status, mailType: MAIL_TYPE.GROUPMAIL, sendName });
} else if (mailTemType == MAIL_TEM_TYPE.GMTYPE) { //系统邮件
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail)
return;
let { goods, sendTime, content, endTime, sendName } = gmMail;
list.push({ id: _id, goods, sendTime, endTime, content, status, mailType: MAIL_TYPE.GROUPMAIL, sendName });
}
});
return list;
}
/**
* 获得据上次刷新后,可以加入的邮件
* @param updatedMailAt
@@ -160,50 +113,50 @@ export class GMRemote {
let gmMails = getGmMails(updatedMailAt, serverId);
return gmMails;
}
/**
* 获得可以领取的邮件奖
* @param serverId
* @param groupMailRewards
* @param mailRewards
*/
public getUseMails(serverId: number, groupMailRewards: GroupMailType[], mailRewards: MailType[]) {
let nowTime = nowSeconds();
let mailGoods = [];
let mails = [];
let mailIds = [];
let groupMailIds = [];
groupMailRewards.map(({_id, goods, mailId, mailTemType})=>{
if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {//gm邮件检查是否有奖励以及是否可以领取
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail || !gmMail.goods.length|| gmMail.endTime < nowSeconds()) {
return;
}
mailGoods.push(...gmMail.goods);
} else {
if (!goods.length)//系统邮件,检查是否有奖励
return;
mailGoods.push(...goods);
}
mails.push({id: _id, status: MAIL_STATUS.RECEIVED, mailType: MAIL_TYPE.GROUPMAIL});
groupMailIds.push(_id);
});
mailRewards.map(({_id, goods, mailId, mailTemType})=>{
if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {//gm邮件检查是否有奖励以及是否可以领取
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail || !gmMail.goods.length|| gmMail.endTime < nowSeconds()) {
return;
}
mailGoods.push(...gmMail.goods);
} else {
if (!goods.length)//系统邮件,检查是否有奖励
return;
mailGoods.push(...goods);
}
mails.push({id: _id, status: MAIL_STATUS.RECEIVED, mailType: MAIL_TYPE.SINGLEMAIL});
mailIds.push(_id);
});
return {mailIds, groupMailIds, mails, mailGoods};
}
// /**
// * 获得可以领取的邮件奖
// * @param serverId
// * @param groupMailRewards
// * @param mailRewards
// */
// public getUseMails(serverId: number, groupMailRewards: GroupMailType[], mailRewards: MailType[]) {
// let nowTime = nowSeconds();
// let mailGoods = [];
// let mails = [];
// let mailIds = [];
// let groupMailIds = [];
// groupMailRewards.map(({_id, goods, mailId, mailTemType})=>{
// if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {//gm邮件检查是否有奖励以及是否可以领取
// let gmMail = getGmMailById(mailId, serverId, nowTime);
// if (!gmMail || !gmMail.goods.length|| gmMail.endTime < nowSeconds()) {
// return;
// }
// mailGoods.push(...gmMail.goods);
// } else {
// if (!goods.length)//系统邮件,检查是否有奖励
// return;
// mailGoods.push(...goods);
// }
// mails.push({id: _id, status: MAIL_STATUS.RECEIVED, mailType: MAIL_TYPE.GROUPMAIL});
// groupMailIds.push(_id);
// });
// mailRewards.map(({_id, goods, mailId, mailTemType})=>{
// if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {//gm邮件检查是否有奖励以及是否可以领取
// let gmMail = getGmMailById(mailId, serverId, nowTime);
// if (!gmMail || !gmMail.goods.length|| gmMail.endTime < nowSeconds()) {
// return;
// }
// mailGoods.push(...gmMail.goods);
// } else {
// if (!goods.length)//系统邮件,检查是否有奖励
// return;
// mailGoods.push(...goods);
// }
// mails.push({id: _id, status: MAIL_STATUS.RECEIVED, mailType: MAIL_TYPE.SINGLEMAIL});
// mailIds.push(_id);
// });
// return {mailIds, groupMailIds, mails, mailGoods};
// }
/**
* 通过模板mailId获得gm邮件
* @param mailId

View File

@@ -1,12 +1,15 @@
import {Application, BackendSession, ChannelService} from 'pinus';
import { MailModel } from '../../../db/Mail';
import { GroupMailModel } from '../../../db/GroupMail';
import { MailModel, MailType } from '../../../db/Mail';
import { GroupMailModel, GroupMailType } from '../../../db/GroupMail';
import { resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import { MAIL_STATUS, MAIL_TEM_TYPE, MAIL_TYPE } from '../../../consts/constModules/mailConst';
import { MAIL_STATUS, MAIL_TEM_TYPE, GM_MAIL_TYPE } from '../../../consts/constModules/mailConst';
import { addItems } from '../../../services/rewardService';
import { nowSeconds } from '../../../pubUtils/timeUtil';
import { getMails } from '../../../services/mailService';
import { ServerMailModel, ServerMailType } from '../../../db/ServerMail';
import { MailParam } from '../../../domain/roleField/mail';
import { RewardInter } from '../../../pubUtils/interface';
export default function(app: Application) {
return new MailHandler(app);
}
@@ -32,47 +35,47 @@ export class MailHandler {
let roleId: string = session.get('roleId');
let { id, mailType } = msg;
let mail;
if (mailType == MAIL_TYPE.SINGLEMAIL) {
mail = await MailModel.updateMailByStatus(id, [MAIL_STATUS.CREATE], { status: MAIL_STATUS.READ });
} else if (mailType == MAIL_TYPE.GROUPMAIL) {
mail = await GroupMailModel.updateMailByStatus(id, roleId, MAIL_STATUS.READ, [MAIL_STATUS.CREATE]);
}
if (!mail)
return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS, { mails: [{ id, status: MAIL_STATUS.READ, mailType }] });
if (mailType == GM_MAIL_TYPE.SINGLE) {
mail = await MailModel.updateStatusWithCondition(id, MAIL_STATUS.READ, [MAIL_STATUS.CREATE]);
} else if (mailType == GM_MAIL_TYPE.GROUP) {
mail = await GroupMailModel.updateStatusWithCondition(id, roleId, MAIL_STATUS.READ, [MAIL_STATUS.CREATE]);
} else if (mailType == GM_MAIL_TYPE.SERVER) {
mail = await ServerMailModel.updateStatusWithCondition(id, roleId, MAIL_STATUS.READ, [MAIL_STATUS.CREATE])
}
// if (!mail)
// return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS, { mails: mail?[{ id, status: MAIL_STATUS.READ, mailType }]:[] });
}
public async delMails(msg: { id: string, mailType: number, type: number }, session: BackendSession) {
let roleId: string = session.get('roleId');
let { id, type, mailType } = msg;
if (type == 1) {//单个删除
if (mailType == MAIL_TYPE.SINGLEMAIL) {
let mail = await MailModel.delMail(id);
if (!mail)
return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS, { mails: [{ id, status: MAIL_STATUS.DELETE, mailType }] });
} else if (mailType == MAIL_TYPE.GROUPMAIL) {
let mail = await GroupMailModel.delMail(id, roleId);
if (!mail)
return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS, { mails: [{ id, status: MAIL_STATUS.DELETE, mailType }] });
} else {
return resResult(STATUS.WRONG_PARMS);
let mail: MailType|GroupMailType|ServerMailType;
if (mailType == GM_MAIL_TYPE.SINGLE) {
mail = await MailModel.delMailById(id);
} else if (mailType == GM_MAIL_TYPE.GROUP) {
mail = await GroupMailModel.delMailById(id, roleId);
} else if (mailType == GM_MAIL_TYPE.SERVER) {
mail = await ServerMailModel.delMailById(id, roleId);
}
if (!mail) return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS, { mails: [{ id: mail._id, mailType, status: MAIL_STATUS.DELETE}] });
} else {//一键删除
let mails = [];
let resGroupMailIds = await GroupMailModel.findReadAndRewardsMails(roleId);
let groupMailIds = resGroupMailIds.map(({_id})=>{
mails.push({id:_id, status: MAIL_STATUS.DELETE, mailType: MAIL_TYPE.GROUPMAIL});
return _id;
});
await GroupMailModel.updateMailStatus(groupMailIds, MAIL_STATUS.DELETE, roleId);
let resMailIds = await MailModel.findReadAndRewardsMails(roleId);
let mailIds = resMailIds.map(({_id})=>{
mails.push({id: _id, status: MAIL_STATUS.DELETE, mailType: MAIL_TYPE.SINGLEMAIL});
return _id;
});
await MailModel.updateMailStatus(mailIds, MAIL_STATUS.DELETE);
let singlemails = await MailModel.delMailsByRoleId(roleId);
let groupMails = await GroupMailModel.delMailsByRoleId(roleId);
let servermails = await ServerMailModel.delMailsByRoleId(roleId);
let mails: { id: string, mailType: GM_MAIL_TYPE, status: MAIL_STATUS }[] = [];
for(let mail of singlemails) {
mails.push({ id: mail._id, mailType: GM_MAIL_TYPE.SINGLE, status: MAIL_STATUS.DELETE });
}
for(let mail of groupMails) {
mails.push({ id: mail._id, mailType: GM_MAIL_TYPE.GROUP, status: MAIL_STATUS.DELETE });
}
for(let mail of servermails) {
mails.push({ id: mail._id, mailType: GM_MAIL_TYPE.SERVER, status: MAIL_STATUS.DELETE });
}
return resResult(STATUS.SUCCESS, { mails });
}
}
@@ -83,44 +86,42 @@ export class MailHandler {
let sid: string = session.get('sid');
let serverId: number = session.get('serverId');
let { id, type, mailType } = msg;
let mailGoods = [];
let mails = [];
let nowTime: number = nowSeconds();
let mails: MailParam[] = [];
if (type == 1) {//单个领取
let mail;
if (mailType == MAIL_TYPE.SINGLEMAIL) {
mail = await MailModel.updateMailByStatus(id, [MAIL_STATUS.READ, MAIL_STATUS.CREATE], { status: MAIL_STATUS.RECEIVED });
if (!mail)
return resResult(STATUS.WRONG_PARMS);
} else if (mailType == MAIL_TYPE.GROUPMAIL) {
mail = await GroupMailModel.updateMailByStatus(id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
if (!mail)
return resResult(STATUS.WRONG_PARMS);
} else {
return resResult(STATUS.WRONG_PARMS);
}
mails.push({ id, status: MAIL_STATUS.RECEIVED, mailType });
if (mail.mailTemType == MAIL_TEM_TYPE.GMTYPE) {
let gmMail = await this.app.rpc.gm.gmRemote.getUseGmMailById.toServer('gm-server-1', mail.mailId, serverId, nowTime);
if (!gmMail)
return resResult(STATUS.WRONG_PARMS);
mailGoods.push(...gmMail.goods);
} else {
mailGoods.push(...mail.goods);
let mail: MailType|GroupMailType|ServerMailType;
if (mailType == GM_MAIL_TYPE.SINGLE) {
mail = await MailModel.updateStatusWithCondition(id, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
} else if (mailType == GM_MAIL_TYPE.GROUP) {
mail = await GroupMailModel.updateStatusWithCondition(id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
} else if (mailType == GM_MAIL_TYPE.SERVER) {
mail = await ServerMailModel.updateStatusWithCondition(id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
}
if (!mail) return resResult(STATUS.WRONG_PARMS);
mails.push(new MailParam(mailType, mail, roleId));
} else {//一键领取
let groupMailRewards = await GroupMailModel.findRewardsMails(roleId);
let mailRewards = await MailModel.findRewardsMails(roleId);
let { mailGoods: goods, mailIds, groupMailIds} = await this.app.rpc.gm.gmRemote.getUseMails.toServer('gm-server-1', serverId, groupMailRewards, mailRewards);
mailGoods = goods;
if (!!groupMailIds.length) //领取群体邮件
mails = await GroupMailModel.updateMailStatus(groupMailIds, MAIL_STATUS.RECEIVED, roleId);
if (!!mailIds.length) //领取单个邮件
mails = await MailModel.updateMailStatus(mailIds, MAIL_STATUS.RECEIVED);
let singlemails = await MailModel.findRewardsMails(roleId);
let groupMails = await GroupMailModel.findRewardsMails(roleId);
let servermails = await ServerMailModel.findRewardsMails(serverId, roleId);
for(let mail of singlemails) {
mail = await MailModel.updateStatusWithCondition(mail._id, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
if(mail) mails.push(new MailParam(GM_MAIL_TYPE.SINGLE, mail, roleId));
}
for(let mail of groupMails) {
mail = await GroupMailModel.updateStatusWithCondition(mail._id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
if(mail) mails.push(new MailParam(GM_MAIL_TYPE.GROUP, mail, roleId));
}
for(let mail of servermails) {
mail = await ServerMailModel.updateStatusWithCondition(mail._id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]);
if(mail) mails.push(new MailParam(GM_MAIL_TYPE.SERVER, mail, roleId));
}
}
let resGoods = [];
if (!!mailGoods && !!mailGoods.length)
resGoods = await addItems(roleId, roleName, sid, mailGoods);
let mailGoods: RewardInter[] = [];
for(let mail of mails) {
mailGoods.push(...mail.goods)
}
let resGoods = await addItems(roleId, roleName, sid, mailGoods);
return resResult(STATUS.SUCCESS, { mails, goods: resGoods });
}
}

View File

@@ -1,7 +1,7 @@
import { Application, ChannelService, FrontendSession, RemoterClass } from 'pinus';
import { STATUS } from '../../../consts/statusCode';
import { resResult } from '../../../pubUtils/util';
import { sendRolesMails } from '../../../services/mailService';
// import { sendRolesMails } from '../../../services/mailService';
import { reloadResources } from '../../../pubUtils/data';
export default function (app: Application) {
return new RoleRemote(app);
@@ -16,9 +16,9 @@ export class RoleRemote {
private channelService: ChannelService;
sendGmMailsToRoles(mails) {
sendRolesMails(mails)
}
// sendGmMailsToRoles(mails) {
// sendRolesMails(mails)
// }
/**
* 重载json资源

View File

@@ -6,11 +6,7 @@ import { MonthlyTicketData } from '../../domain/activityField/monthlyTicketField
import { addReward, stringToRewardInter, stringToRewardParam } from './giftPackageService';
import moment = require('moment');
import { ServerlistModel } from '../../db/Serverlist';
import { getMailContent } from './../mailService';
import { MailModel, MailType } from '../../db/Mail';
import { pushMail } from '../../pubUtils/interface';
import { pinus } from 'pinus';
import { resResult } from '../../pubUtils/util';
import { sendMailByContent } from './../mailService';
/**
* 获取活动数据
@@ -38,17 +34,10 @@ export async function monthlyTicketActivity(serverId: number, roleId: string, ty
if ((playerData.price > 0 && playerData.isOpen) || playerData.price === 0) {
if (playerData.todayIndex - 1 > playerData.dayIndex) {//过期还没领取
//下发邮件奖励
let mails = new Array<MailType>();
let pushMessage = new Array<pushMail>();
for (let i = playerData.dayIndex + 1; i < playerData.todayIndex; i++) {
let goods = stringToRewardInter(playerData.baseReward)
await getMailContent(roleId, MAIL_TYPE.MONTHLY_REWARD, [], goods, mails, pushMessage);
await sendMailByContent(MAIL_TYPE.MONTHLY_REWARD, roleId, { params: [], goods });
}
await MailModel.addMails(mails);
pushMessage.forEach(({ route, data, uids }) => {
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails: data }), uids);
});
await ActivityMonthlyTicketModel.setDayIndex(serverId, roleId, playerData.activityId, playerData.todayIndex - 1);
playerData.dayIndex = playerData.todayIndex - 1;
}

View File

@@ -8,7 +8,7 @@ import { getZeroPointD, getTimeFunD } from '../pubUtils/timeUtil';
import { gameData, getGoodById } from '../pubUtils/data';
import { DividendParam, DividendType } from '../db/Dividend';
import { pushMail } from '../pubUtils/interface';
import { getMailContent } from './mailService';
import { sendMailByContent } from './mailService';
import { pinus, BackendSession, FrontendOrBackendSession } from 'pinus';
import { participants } from './guildActivityService';
import { Member } from '../domain/battleField/guildActivity';
@@ -261,16 +261,14 @@ export async function sendUngotDividend(debug = false) {
}
}
let mails: MailType[] = [];
let pushMessage: pushMail[] = [];
for (let [roleId, count] of rewards) {
// TODO: 邮件类型修改
await getMailContent(roleId, MAIL_TYPE.GUILD_BOSS_REWARD, [JSON.stringify(count)], [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count }], mails, pushMessage);
await sendMailByContent(MAIL_TYPE.GUILD_BOSS_REWARD, roleId, {
params: [JSON.stringify(count)],
goods: [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count }]
});
}
await MailModel.addMails(mails);
pushMessage.forEach(({route, data, uids })=>{
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails: data }), uids);
});
debug === true ? await updateDebugDividendsStatus(DIVIDEND_STATUS.SENT) : await updateOfficialDividendsStatus(DIVIDEND_STATUS.SENT);
return true;
} catch (e) {

View File

@@ -14,7 +14,7 @@ import { getGuildChannelSid, getWorldChannelSid, getCityChannelSid } from "./cha
import { pinus } from "pinus";
import { GuildActivityRecordModel } from "../db/GuildActivityRec";
import { genAuction } from "./auctionService";
import { sendMail } from "./mailService";
import { sendMailByContent } from "./mailService";
import { getHonourObject } from '../pubUtils/itemUtils';
import { GuildActivityCityType, GuildActivityCityModel } from "../db/GuildActivityCity";
import { DicCityActivity } from "../pubUtils/dictionary/DicCityActivity";
@@ -417,7 +417,7 @@ export async function gateActivitySettleReward(guildCode: string, serverId: numb
async function updateUserRecAndSendHonour(honour: number, myScore: number, rank: number, roleId: string, members: Member[]) {
let honourObj = getHonourObject(Math.floor(honour));
await sendMail(MAIL_TYPE.GUILD_ACTIVITY_REWARD, roleId, '系统', [], [honourObj])
await sendMailByContent(MAIL_TYPE.GUILD_ACTIVITY_REWARD, roleId, { goods: [honourObj] })
await UserGuildActivityRecModel.updateInfoByRoleId(roleId, { score: myScore, rank });
let index = members.findIndex(cur => cur.roleId == roleId);

View File

@@ -2,14 +2,14 @@ import { BossInstanceType, BossInstanceModel } from '../db/BossInstance';
import { getZeroPoint } from '../pubUtils/timeUtil';
import { lockData } from '../services/redLockService';
import { findIndex } from 'underscore';
import { MailModel, MailType } from '../db/Mail';
import { MailType } from '../db/Mail';
import { sismemberAsync, smembersAsync, saddAsync, delAsync, getRoleOnlineInfo } from '../services/redisService';
import { pinus } from 'pinus';
import { STATUS } from '../consts/statusCode';
import { deepCopy, resResult } from '../pubUtils/util';
import { BattleRecordModel } from '../db/BattleRecord';
import { getArmyBossRank, gameData } from '../pubUtils/data';
import { getMailContent } from '../services/mailService';
import { sendMailByContent } from '../services/mailService';
import { pushMail } from '../pubUtils/interface';
import { MAIL_TYPE, AUCTION_SOURCE } from '../consts';
import { GUILD_BOSS_STATUS } from '../consts/constModules/guildConst';
@@ -133,11 +133,9 @@ export async function bossResult(code: string, serverId: number, dataName: strin
let goods = getArmyBossRankReward(rankLv);
if (!goods || !goods.length)
return;
await getMailContent(roleId, MAIL_TYPE.GUILD_BOSS_REWARD, [JSON.stringify(rankLv)], goods, mails, pushMessage);
});
await MailModel.addMails(mails);
pushMessage.forEach(({route, data, uids })=>{
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails: data }), uids);
await sendMailByContent(MAIL_TYPE.GUILD_BOSS_REWARD, roleId, {
params: [JSON.stringify(rankLv)], goods
})
});
// 加入拍卖行
let dicBossBase = gameData.bossBaseByBossLv.get(bossLv);

View File

@@ -9,14 +9,10 @@ import { SystemConfigModel } from "../db/SystemConfig";
import { nowSeconds } from "../pubUtils/timeUtil";
import { pinus, BackendSession, FrontendOrBackendSession } from "pinus";
import { ARMY } from "../pubUtils/dicParam";
import { sendMail } from "./mailService";
import { sendMailByContent } from "./mailService";
import { initSingleRank, getRoleOnlineInfo, updateUserInfo, isRoleOnline } from "./redisService";
import { GuildRankParam, GuildLeader } from "../domain/rank";
import { lockData, lockDataNoRetry } from '../services/redLockService';
import { ErrLogModel } from '../db/ErrLog';
import { MailType, MailModel } from '../db/Mail';
import { pushMail } from '../pubUtils/interface';
import { getMailContent } from '../services/mailService';
import { DATA_NAME } from '../consts/dataName';
import { addRoleToGuildChannel } from "./chatService";
import { Rank } from "./rankService";
@@ -223,25 +219,20 @@ export async function getUserGuildWithRefActive(roleId: string, select?: string,
const now = new Date();
let isRefDaily = shouldRefresh(refTimeDaily, now);
if (isRefDaily) {
let mails = new Array<MailType>();
let pushMessage = new Array<pushMail>();
wishGoods.map(async function ({ donateNames, goodId, drawCnt }) {
let goodInfo = getGoodById(goodId)
if (!goodInfo)
return;
for (let i = 0; i < drawCnt; i++) {
let donateName = donateNames[donateNames.length - i - 1];
await getMailContent(roleId, MAIL_TYPE.WISH_POOL_REWARD, [donateName, goodInfo.name], [{ id: goodId, count: drawCnt }], mails, pushMessage);
}
});
if (!!mails.length) {
await MailModel.addMails(mails);
if (!notPush) {
pushMessage.forEach(({ route, data, uids }) => {
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails: data }), uids);
await sendMailByContent(MAIL_TYPE.WISH_POOL_REWARD, roleId, {
params: [donateName, goodInfo.name],
goods: [{ id: goodId, count: drawCnt }],
notPush
});
}
}
});
receivedActive = []; refTimeDaily = now; activeDaily = 0; activeRecord = []; wishGoods = [];
let receiveBoxs = [], wishDntCnt = 0, donateCnt = 0;
userGuild = await UserGuildModel.updateInfo(roleId, { receivedActive, refTimeDaily, activeDaily, activeRecord, wishGoods, receiveBoxs, wishDntCnt, donateCnt }, {}, select);
@@ -304,7 +295,7 @@ export async function settleGuildWeekly() {
count: Math.ceil(cur.count * jobActiveRatio)
}
});
await sendMail(MAIL_TYPE.GUILD_ACTIVE_REWARD, roleId, '系统', [], reward);
await sendMailByContent(MAIL_TYPE.GUILD_ACTIVE_REWARD, roleId, { goods: reward });
// 任务
await checkTask(roleId, null, null, TASK_TYPE.GUILD_JOB, 1, false, { job });
}

View File

@@ -13,8 +13,9 @@ import { resResult, getRandSingleEelm } from '../pubUtils/util';
import { STATUS } from '../consts/statusCode';
import { GuildTrainReportModel } from '../db/GuildTrainReport';
import { DATA_NAME } from '../consts/dataName';
import { getMailContent } from './mailService';
import { sendMailByContent } from './mailService';
import { MAIL_TYPE } from '../consts';
import { getGuildChannelSid } from './chatChannelService';
/**
* 获得userGuild并检查是否需要每日重置购买挑战次数和今日挑战次数已经检查是否需要每周重置练兵场
* @param roleId
@@ -151,8 +152,7 @@ export async function resetTrain(code: string, serverId: number) {
}
const userGuildList = await UserGuildModel.getListByGuild(code, 'trainRewards', {});
const guildTrains = await GuildTrainModel.getGuildTrainBoxs(code);
let mails = new Array<MailType>();
let pushMessage = [];
let { shilianRewardRatio } = getTrainBaseByLv(GUILD_STRUCTURE.TRAIN);
//结算未领取的宝箱奖励发送到邮件中
userGuildList.forEach(async function ({roleId, trainRewards}) {
@@ -177,14 +177,15 @@ export async function resetTrain(code: string, serverId: number) {
}
}
if (!!goods.length) {
await getMailContent(roleId, MAIL_TYPE.GUILD_TRAIN_REWARD, [], goods, mails, pushMessage);
await sendMailByContent(MAIL_TYPE.GUILD_TRAIN_REWARD, roleId, {
params: [], goods
});
}
});
await MailModel.addMails(mails);
pushMessage.forEach(({route, data, uids })=>{
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails:data }), uids);
pinus.app.channelService.pushMessageByUids('onGuildTainReset', resResult(STATUS.SUCCESS, {}), uids);//通知在线玩家练兵场重置,
});
let chatSid = await getGuildChannelSid(code);
pinus.app.rpc.chat.guildRemote.sendTrainReset.toServer(chatSid, code);
await GuildTrainModel.resetGuildTrain(code);//将开启的练兵场锁定
await unlockTrain(code, 1);//开启练兵场1级
await UserGuildModel.resetTrainUserGuild(code);//重置玩家的挑战次数和购买挑战次数

View File

@@ -1,190 +1,206 @@
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 { nowSeconds } from '../pubUtils/timeUtil';
import { STATUS } from '../consts/statusCode';
import { resResult } from '../pubUtils/util';
import { GroupMailModel, GroupMailType } from "../db/GroupMail";
import { findWhere } from "underscore";
import { MAIL_TYPE, MAIL_TEM_TYPE, GM_MAIL_TYPE, MAIL_STATUS } from "../consts/constModules/mailConst";
import { DATA_NAME } from '../consts/dataName';
import { lockData } from './redLockService';
import { GM_MAIL_TYPE, MAIL_STATUS, MAIL_TYPE, SEND_NAME } from "../consts";
import { MailParam } from '../domain/roleField/mail';
import { GMMailType, GMMailModel } from "../db/GMMail";
import { getGuildChannelSid, getWorldChannelSid } from "./chatChannelService";
/**
* 下发邮件
* @param operate
* @param toRoleId
* @param sendName
* @param params
* @param goods
* @param sendTime
*/
export async function sendMail(operate: number, toRoleId: string, sendName: string = '系统', params: string[] = [], goods: RewardInter[] = [], sendTime: number = nowSeconds()) {
let { content, time } = getContent(operate, params);
if (!content)
return;
let mail = await MailModel.addMail({roleId: toRoleId, sendTime, goods, sendName, mailId: JSON.stringify(operate), endTime: time + nowSeconds(), mailTemType: MAIL_TEM_TYPE.GAMEMAIL, params});
let hisOnlineInfo = await getRoleOnlineInfo(toRoleId);
if(hisOnlineInfo.isOnline) {
let sid = hisOnlineInfo.sid;
if (!!sid) {//下发邮件,对应前端红点提示
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails:[{
id: mail._id, goods, sendTime: mail.sendTime, endTime: mail.endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName
}]}), [{uid: toRoleId, sid}]);
}
}
}
/**
* 封装玩家的邮件内容
* @param operate
* @param params
*/
export function getContent(operate: number, params: string[]) {
let mail = gameData.mail.get(operate);
if (!mail)
return {};
let { content, time } = mail;
content = content||'%d';
for(let p of params) {
content = content.replace(/%d/, p);
}
return { content, time }
}
/**
* 封装获得邮件的下发信息,以及需要添加的邮件信息
* @param roleId
* @param operate
* @param params
* @param goods
* @param mails
* @param pushMessage
* @param sendTime
* @param sendName
*/
export async function getMailContent(roleId: string, operate: number, params: string[], goods: RewardInter[], mails: MailType[], pushMessage: pushMail[], sendTime?:number, sendName: string = '系统') {
const doc = new MailModel();
let { content, time } = getContent(operate, params);
if (!content)
return;
const mail = Object.assign(doc.toJSON(), { roleId, goods, sendName, mailId: operate, sendTime: sendTime||nowSeconds(), mailTemType: MAIL_TEM_TYPE.GAMEMAIL, endTime: time + nowSeconds(), params });
mails.push(mail);
let hisOnlineInfo = await getRoleOnlineInfo(roleId);
if(hisOnlineInfo.isOnline) {
let sid = hisOnlineInfo.sid;
if (!!sid) {
pushMessage.push({route: 'onMailsAdd', data:[{
id: mail._id, goods, sendTime: mail.sendTime, endTime: mail.endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName
}], uids: [{ uid: roleId, sid }]});
}
}
}
/**
* 检查上次刷新过后至今 gm后台是否有新邮件下发给玩家
* @param roleId
* @param sid
* @param serverId
* @param updatedMailAt
*/
export async function refreshMails(roleId: string, sid: string, serverId: number, updatedMailAt: number) {
let res:any = await lockData(serverId, DATA_NAME.GAMEMAIL, roleId);//加锁
let gmMails = await pinus.app.rpc.gm.gmRemote.getMailsByTime.toServer('gm-server-1', updatedMailAt, serverId);
let addGroupMails: GroupMailType[] = [];
let addMails: MailType[] = [];
let updateMails: mailData[] = [];
let pushMails: mailData[] = [];
for (let { gmMailType, id: mailId, sendRoles, endTime, content, goods, sendTime, sendName } of gmMails) {
if (gmMailType == GM_MAIL_TYPE.GROUPMAIL) { //检查gm群体邮件是否需要加入
let mail = await GroupMailModel.getMail(mailId, MAIL_TEM_TYPE.GMTYPE);
if (!mail) {
const doc = new GroupMailModel();
const mail = Object.assign(doc.toJSON(), { mailId, mailTemType: MAIL_TEM_TYPE.GMTYPE, sendRoles, sendName });
addGroupMails.push(mail);
pushMails.push({ id: mail._id, goods, sendTime, endTime, content, status: mail.status, mailType: MAIL_TYPE.GROUPMAIL, sendName });
} else {
let { sendRoles } = mail;
let sendRole = findWhere(sendRoles, {roleId});
if (!sendRole) {
await GroupMailModel.pushRoleMail(roleId, mailId, MAIL_TEM_TYPE.GMTYPE);
pushMails.push({ id: mail._id, goods, sendTime, endTime, content, status: MAIL_STATUS.CREATE, mailType: MAIL_TYPE.GROUPMAIL, sendName });
}
}
} else if (gmMailType == GM_MAIL_TYPE.SERVER) { //检查gm服邮件是否需要加入
let mail = await MailModel.getMail(roleId, mailId, MAIL_TEM_TYPE.GMTYPE);
if (!mail) {
const doc = new MailModel();
const mail = Object.assign(doc.toJSON(), { mailId, mailTemType: MAIL_TEM_TYPE.GMTYPE, roleId, sendName });
addMails.push(mail);
pushMails.push({ id: mail._id, goods, sendTime, endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName });
} else {
//若加入过,可能修改过奖励内容等信息,更新一下邮件的内容
updateMails.push({ id: mail._id, goods, sendTime, endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName })
}
}
}
if (!!updateMails.length) {//下发邮件修改推送
pinus.app.channelService.pushMessageByUids('onMailsUpdate', resResult(STATUS.SUCCESS, { mails: updateMails }), [{uid: roleId, sid}]);
}
if (!!addGroupMails.length) {
await GroupMailModel.addGroupMails(addGroupMails);
}
if (!!addMails.length) {
await MailModel.addMails(addMails);
}
if (!!pushMails.length) {
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: pushMails}), [{uid: roleId, sid}]);//下发邮件,对应前端红点提示
}//下发邮件,对应前端红点提示
res.releaseCallback();
return nowSeconds();
}
/**
* 获取邮件信息gm邮件需要从gm-server-1缓存中读取
* @param roleId
* @param serverId
* 获取邮件信息
* @param {String} roleId 玩家id
* @param {Number} serverId 服务器id
*/
export async function getMails(roleId: string, serverId: number) {
let mails = await MailModel.getMailsByRoleId(roleId)||[];
let groupMails = await GroupMailModel.getGroupMailsByRoleId(roleId)||[];
let list: mailData[] = await pinus.app.rpc.gm.gmRemote.getMailInfos.toServer('gm-server-1', roleId, serverId, mails, groupMails);
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;
}
/**
* 下发gm邮件的群体邮件
* @param mails
* 根据数据库数据,生成返回数据
* @param {String} roleId 玩家id
* @param {MailType[]} mails 单人邮件
* @param {GroupMailType[]} groupMails 多人邮件
* @param {ServerMailType[]} serverMails 全服邮件
*/
export async function sendRolesMails(mails) {
let addGroupMails: GroupMailType[] = [];
let pushMessage: pushMail[] = [];
for (let { gmMailType, id: mailId, sendRoles, endTime, content, goods, sendTime, sendName } of mails) {
let uids = [];
if (endTime < nowSeconds()|| sendTime > nowSeconds())
continue;
if (gmMailType != GM_MAIL_TYPE.GROUPMAIL) //不是群体邮件说明是全服邮件,不进行下发
return;
let mail = await GroupMailModel.getMail(mailId, MAIL_TEM_TYPE.GMTYPE);
if (!mail) {
const doc = new GroupMailModel();
mail = Object.assign(doc.toJSON(), { mailId, mailTemType: MAIL_TEM_TYPE.GMTYPE, sendRoles, sendName });
addGroupMails.push(mail);
} else {
return;
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[], notPush?: boolean }) {
let f = new SendMailFun();
f.setWithContentId(contentId, params);
await f.sendToUsers(GM_MAIL_TYPE.SINGLE, [hisRoleId]);
}
/**
* 发送邮件方法类
*/
export class SendMailFun {
private mailType: GM_MAIL_TYPE = GM_MAIL_TYPE.SINGLE; // 邮件类型 1-单人 2-多人 3-全服
private contentId: MAIL_TYPE = MAIL_TYPE.SEND_MAIL; // 0-读GmMail1以上读dicMail
private params: string[] = [];
private sendName: string = SEND_NAME;
private gmmail: GMMailType;
private hasGoods: boolean = false; // 是否内含奖励
private goods: RewardInter[] = []; // 发送的奖励
private sendTime: number;
private endTime: number;
private notPush: boolean = false;
// 从dicMail读取数据
public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[] }) {
let dicMail = gameData.mail.get(contentId);
this.contentId = contentId;
this.sendTime = nowSeconds();
this.endTime = this.sendTime + dicMail?.time||0;
this.setParam({ ...params });
}
// 从GMMail表读取数据
public async setWithGmMail(gmmailId: string) {
let gmmail = await GMMailModel.getGmMailById(gmmailId);
if(gmmail) {
this.gmmail = gmmail;
this.sendTime = gmmail.sendTime;
this.endTime = gmmail.endTime;
this.setParam({ ...gmmail });
}
for (let { roleId } of sendRoles) {
let hisOnlineInfo = await getRoleOnlineInfo(roleId);
if(hisOnlineInfo.isOnline && hisOnlineInfo.sid) {
uids.push({sid: hisOnlineInfo.sid, uid: roleId});
}
private setParam(params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[], content?: string }) {
if(params.sendName) this.sendName = params.sendName;
if(params.endTime) this.endTime = params.endTime;
if(params.content) {
this.params.push(params.content);
}
if(params.params) this.params = params.params;
if(params.goods) {
this.hasGoods = params.goods.length > 0;
this.goods = params.goods;
}
}
private getCreateMailParams() {
return {
contentId: this.contentId,
mail: this.gmmail?._id,
sendTime: this.sendTime,
endTime: this.endTime,
params: this.params,
goods: this.goods,
sendName: this.sendName,
hasGoods: this.hasGoods
}
}
// 生成单人邮件
private async createSingleMails(roleIds: string[]) {
let mails = new Map<string, MailParam>();
for(let roleId of roleIds) {
let originMail = await MailModel.addMail({ roleId, ...this.getCreateMailParams() });
let mail = new MailParam(this.mailType, originMail);
mails.set(roleId, mail);
}
return mails;
}
// 生成多人邮件
private async createGroupMails(roleIds: string[]) {
let roleStatus = roleIds.map(roleId => {
return { roleId, status: MAIL_STATUS.CREATE }
})
let originMail = await GroupMailModel.addMail({ roleStatus, ...this.getCreateMailParams() });
return new MailParam(this.mailType, originMail);
}
// 生成全服邮件
private async createServerMails(serverIds: number[]) {
let mails = new Map<number, MailParam>();
for(let serverId of serverIds) {
let originMail = await ServerMailModel.addMail({ serverId, ...this.getCreateMailParams() });
mails.set(serverId, new MailParam(this.mailType, 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;
}
}
if(sid) {
uids.push({ uid: roleId, sid });
}
}
pushMessage.push({route: 'onMailsAdd', data:[{
id: mail._id, goods, sendTime: mail.sendTime, endTime: mail.endTime, content, status: MAIL_STATUS.CREATE, mailType: MAIL_TYPE.SINGLEMAIL, sendName
}], uids});
if (uids.length > 0) {//下发邮件,对应前端红点提示
if(mailType == GM_MAIL_TYPE.SINGLE) {
let mails = await this.createSingleMails(roleIds);
for(let { uid, sid } of uids) {
let mail = mails.get(uid);
if(mail && !this.notPush) pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: [mail] }), [{ uid, sid }]);
}
} else if (mailType == GM_MAIL_TYPE.GROUP) {
let mail = await this.createGroupMails(roleIds);
if(!this.notPush) pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: [mail] }), uids);
} else { // mailType错误
return false;
}
}
return true;
}
if (!!addGroupMails.length) {
await GroupMailModel.addGroupMails(addGroupMails);
// 向军团推送
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] });
}
}
}
pushMessage.forEach( message=> {
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: message.data }), message.uids);
});//下发邮件,对应前端红点提示
}

View File

@@ -346,7 +346,9 @@ export function getLvByScore(heroScores: HeroScores[]) {
}
export async function defaultHeroes ( role:RoleType, challengeCnt?:number, challengeRefTime?:number, isUpdate?: boolean) {
let { heroes, isDefaultHero } = await PvpDefenseModel.findByRoleId(role.roleId);
let pvpDefense = await PvpDefenseModel.findByRoleId(role.roleId);
if(!pvpDefense) return;
let { heroes, isDefaultHero } = pvpDefense;
if (!isUpdate && !isDefaultHero) {
return;
}

View File

@@ -1,9 +1,8 @@
import { FrontendOrBackendSession, pinus } from "pinus";
import { refreshMails } from './mailService';
import { STATUS } from '../consts/statusCode';
import { resResult, shouldRefresh, shouldRefreshWeek } from '../pubUtils/util';
import { nowSeconds } from "../pubUtils/timeUtil";
import { RoleModel } from '../db/Role';
// import { RoleModel } from '../db/Role';
import { refDailyTask, refDailyTaskBox } from './taskService'
/**
@@ -13,17 +12,8 @@ import { refDailyTask, refDailyTaskBox } from './taskService'
export async function refresh(session: FrontendOrBackendSession) {
const roleId = session.get('roleId');
const sid = session.get('sid');
const serverId: number = parseInt(session.get('serverId'));
let updatedMailAt: number = parseInt(session.get('updatedMailAt')); //记录上次更新gm邮件的时间
let uids = [{uid: roleId, sid}];
pinus.app.get('channelService').pushMessageByUids('onPushCurrentTime', resResult(STATUS.SUCCESS, {time: Date.now()}), uids);
let nowTime = nowSeconds();
if (!!roleId && updatedMailAt < nowTime - 5) { //保持最少5秒间隙
session.set('updatedMailAt', nowTime);
session.push('updatedMailAt', () => {});
RoleModel.updatedRoleMailAt(roleId, nowTime);
await refreshMails(roleId, sid, serverId, updatedMailAt);
}
await refreshDaily(session);
}

View File

@@ -8,7 +8,7 @@ import { getPvpGkWarIds, getPvpRankRewards, getPvpHeroRewards, getResultMaxRank,
import { deepCopy, resResult, getRandSingleEelm } from '../pubUtils/util';
import { getLvByScore } from './pvpService';
import { getAllOnlineRoles, getAllServers, initSingleRank, delGuildActivityRank } from './redisService';
import { MAIL_TYPE, REDIS_KEY, ADULT_AGE, GUEST_MAX_TIME, ADDICTION_PREVENTION_CODE, GUILD_ACTIVITY_STATUS, GUILD_ACTIVITY_TYPE, TASK_TYPE, TIME_OUTPUT_TYPE, REFRESH_TIME } from '../consts';
import { MAIL_TYPE, REDIS_KEY, ADULT_AGE, GUEST_MAX_TIME, ADDICTION_PREVENTION_CODE, GUILD_ACTIVITY_STATUS, GUILD_ACTIVITY_TYPE, TASK_TYPE, TIME_OUTPUT_TYPE, REFRESH_TIME, SEND_NAME } from '../consts';
import { RoleModel } from '../db/Role';
import { MailModel, MailType } from '../db/Mail';
import { pinus } from 'pinus';
@@ -16,7 +16,7 @@ import { indexOf } from 'underscore';
import { PvpSeasonResultModel } from '../db/PvpSeasonResult';
import { settleGuildWeekly } from './guildService';
import { STATUS } from '../consts/statusCode';
import { getMailContent, sendMail } from './mailService';
import { sendMailByContent } from './mailService';
import { reportOnline } from '../pubUtils/httpUtil';
import { UserModel } from '../db/User';
import { getGuildActivityByDic, setMedianCe, sendEndMsgToAll, autoDeclare, sendGuildActivityStatus } from './guildActivityService';
@@ -101,20 +101,11 @@ export async function setPvpSeasonResult(obj?:{ name:string, notSetNext?: boolea
let lastPageNum = resultMaxRank.min % pageNum;
for (let page = 0; page < maxPage + 1; page++) {
let pvpDefenses = await PvpDefenseModel.getPvpDef(pageNum, page == maxPage?lastPageNum:page);
let addMails = new Array<MailType>();
let pushMessage = new Array<any>();
for (let pvpDefense of pvpDefenses) {
if (pvpDefense.seasonNum !== seasonNum) {
await setPvpDefResultOnTime(pvpDefense, seasonNum, oldSeasonEndTime, addMails, pushMessage);
await setPvpDefResultOnTime(pvpDefense, seasonNum, oldSeasonEndTime, obj?.notPush);
}
}
await MailModel.addMails(addMails);
if (obj?.notPush) {
continue;
}
for (let message of pushMessage) {
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: message.data }), [{uid: message.uid, sid: message.sid}]);
}
}
return { seasonNum, seasonEndTime, oldSeasonEndTime};
}
@@ -123,18 +114,22 @@ export async function setPvpSeasonResult(obj?:{ name:string, notSetNext?: boolea
* @param pvpDefense
* @param seasonNum
* @param oldSeasonEndTime
* @param addMails
* @param pushMessage
*/
export async function setPvpDefResultOnTime(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime: number, addMails: Array<MailType>, pushMessage:Array<any>) {
export async function setPvpDefResultOnTime(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime: number, notPush?: boolean) {
//检查并返回排名结算以及武将功勋结算
let { score, pLv, heroScores, challengeCnt, challengeRefTime, rankGoods, heroGoods, rankLv } = await checkResult(pvpDefense, seasonNum, oldSeasonEndTime);
pvpDefense = await PvpDefenseModel.updateInfo(pvpDefense.roleId, {score, pLv, heroScores, seasonNum, challengeCnt, challengeRefTime});
//下发邮件
if (!!rankGoods.length) //排名奖励
await getMailContent(pvpDefense.roleId, MAIL_TYPE.PVP_RANK_REWARD, [JSON.stringify(seasonNum), (rankLv>1000?'999+':JSON.stringify(rankLv))], rankGoods, addMails, pushMessage, oldSeasonEndTime);
await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, pvpDefense.roleId, {
params: [JSON.stringify(seasonNum), (rankLv>1000?'999+':JSON.stringify(rankLv))],
goods: rankGoods, endTime: oldSeasonEndTime, notPush
});
if (!!heroGoods.length) //武将功勋奖励
await getMailContent(pvpDefense.roleId, MAIL_TYPE.PVP_RESULT, [JSON.stringify(seasonNum)], heroGoods, addMails, pushMessage, oldSeasonEndTime);
await sendMailByContent(MAIL_TYPE.PVP_RESULT, pvpDefense.roleId, {
params: [JSON.stringify(seasonNum)],
goods: heroGoods, endTime: oldSeasonEndTime, notPush
});
return pvpDefense;
}
/**
@@ -214,9 +209,9 @@ export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: num
r.setRankWithRoleInfo(pvpDefense.roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role, true);
//下发邮件
if (!!rankGoods.length)
await sendMail(MAIL_TYPE.PVP_RANK_REWARD, roleId, '系统', [JSON.stringify(seasonNum), '999+'], rankGoods, oldSeasonEndTime);
await sendMailByContent(MAIL_TYPE.PVP_RANK_REWARD, roleId, { params: [JSON.stringify(seasonNum), '999+'], goods: rankGoods, endTime: oldSeasonEndTime });
if (!!heroGoods.length)
await sendMail(MAIL_TYPE.PVP_RESULT, roleId, '系统', [JSON.stringify(seasonNum)], heroGoods, oldSeasonEndTime);
await sendMailByContent(MAIL_TYPE.PVP_RESULT, roleId, { params: [JSON.stringify(seasonNum)], goods: heroGoods, endTime: oldSeasonEndTime });
return pvpDefense;
}
/**

View File

@@ -1,18 +1,41 @@
export const MAIL_STATUS = {
DELETE: -1,
CREATE: 0,
READ: 1,
RECEIVED: 2,
};
export const MAIL_TYPE = {
SINGLEMAIL: 1,
GROUPMAIL: 2,
export enum MAIL_STATUS {
DELETE = -1,
CREATE = 0,
READ = 1,
RECEIVED = 2,
};
export const MAIL_TEM_TYPE = {
GAMEMAIL: 1,
GMTYPE: 2,
};
export const GM_MAIL_TYPE = {
GROUPMAIL: 1, //1:群体邮件
SERVER: 2, //2分服务器邮件
export enum GM_MAIL_TYPE {
SINGLE = 1, // 单人邮件
GROUP = 2, // 多人邮件
SERVER = 3, // 全服邮件
};
// 邮件内容类型
export enum MAIL_TYPE {
SEND_MAIL = 0,
GUILD_APPLY_REFUSE = 1,
GUILD_BE_IMPEACH = 2,
GUILD_BE_SET_LEADER = 3,
GUILD_BE_KICK = 4,
GUILD_ACTIVE_REWARD = 5,
GUILD_BE_SET_MANAGER = 6,
GUILD_BE_SET_MEMBER = 7,
GUILD_BOSS_OPEN = 8,
GUILD_BOSS_REWARD = 9,
GUILD_TRAIN_REWARD = 10,
WISH_POOL_REWARD = 11,
PVP_RESULT = 12,
PVP_RANK_REWARD = 13,
GUILD_ACTIVITY_REWARD = 14,
GUILD_DIVIDEND = 15, // 拍卖行分红
MONTHLY_REWARD = 16, // 月卡奖品
AUTION_REWARD = 17, // 拍卖行忘领取奖励
};
export const SEND_NAME = '系统';

View File

@@ -476,27 +476,6 @@ export const EQUIP_STRENGTHEN_TYPE = {
ALL_QUICK: 3 // 武将全部装备栏一键强化
}
// 邮件内容类型
export const MAIL_TYPE = {
SEND_MAIL: 0,
GUILD_APPLY_REFUSE: 1,
GUILD_BE_IMPEACH: 2,
GUILD_BE_SET_LEADER: 3,
GUILD_BE_KICK: 4,
GUILD_ACTIVE_REWARD: 5,
GUILD_BE_SET_MANAGER: 6,
GUILD_BE_SET_MEMBER: 7,
GUILD_BOSS_OPEN: 8,
GUILD_BOSS_REWARD: 9,
GUILD_TRAIN_REWARD: 10,
WISH_POOL_REWARD: 11,
PVP_RESULT: 12,
PVP_RANK_REWARD: 13,
GUILD_ACTIVITY_REWARD: 14,
GUILD_DIVIDEND: 15, // 拍卖行分红
MONTHLY_REWARD: 16, // 月卡奖品
};
export const CHAT_SERVER = 'chat-server-1';
export enum FRIEND_RELATION_TYPE {

View File

@@ -10,5 +10,6 @@ export * from './constModules/selectConst';
export * from './constModules/chatConst';
export * from './constModules/httpConst';
export * from './constModules/auctionConst';
export * from './constModules/mailConst';
export * from './statusCode';
export * from './dataName';

View File

@@ -1,29 +1,22 @@
/**
* 邮件的模板在GM后台能看到的邮件列表
*/
import BaseModel from './BaseModel';
import { getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { GM_MAIL_TYPE } from '../consts/constModules/mailConst';
class RewardInter {
class Reward {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
class SendRole {
@prop({ required: true })
roleId: string;
}
export default class GMMail extends BaseModel {
@prop({ required: true })
serverId: number;
@prop({ required: true, type: SendRole, default:[], _id: false })
sendRoles: SendRole[];
@prop({ required: true, type: RewardInter, default: [], _id: false })
goods: RewardInter[];
@prop({ required: true, type: Reward, default: [], _id: false })
goods: Reward[];
@prop({ required: true, default: nowSeconds() })
sendTime: number;
@@ -37,13 +30,13 @@ export default class GMMail extends BaseModel {
@prop({ required: true })
sendName: string;
@prop({ required: true })
gmMailType: number; //1:群体邮件2分服务器邮件
@prop({ required: true, enum: GM_MAIL_TYPE })
mailType: GM_MAIL_TYPE; // 1-单人邮件 2-多人邮件 3-全服邮件
public static async addMail(params: {serverId: number, sendRoles: SendRole[], sendName: string, endTime: number, content: string, gmMailType: number, sendTime?: number, goods?: RewardInter[] }, lean = true) {
public static async addMail(params: GMMailTypeParam) {
const doc = new GMMailModel();
let mail = Object.assign(doc.toJSON(), params);
mail = await GMMailModel.findOneAndUpdate({ _id: mail._id }, { $set: mail }, {upsert: true, new: true}).lean(lean);
mail = await GMMailModel.findOneAndUpdate({ _id: mail._id }, { $set: mail }, {upsert: true, new: true}).lean();
return mail;
}
@@ -66,4 +59,6 @@ export default class GMMail extends BaseModel {
export const GMMailModel = getModelForClass(GMMail);
export interface GMMailType extends Pick<DocumentType<GMMail>, keyof GMMail> { };
export interface GMMailType extends Pick<DocumentType<GMMail>, keyof GMMail> { };
export type GMMailTypeParam = Partial<GMMailType>; // 将所有字段变成可选项

View File

@@ -1,61 +1,94 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
/**
* 多人邮件
*/
import MailTemp from './MailTemp';
import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { MAIL_STATUS, MAIL_TYPE } from '../consts/constModules/mailConst';
import { findWhere } from 'underscore';
class RewardInter {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
class SendRole {
class RoleStatus {
@prop({ required: true })
roleId: string;
@prop({ required: true })
status: number;
}
@index({ sendRoles: 1 })
@index({ mailId: 1, type: 1 })
export default class GroupMail extends BaseModel {
@prop({ required: true, type: SendRole, default: [], _id: false })
sendRoles: SendRole[];
@index({ 'roleStatus.roleId': 1 })
export default class GroupMail extends MailTemp {
@prop({ required: true })
mailId: string;
@prop({ required: true, type:RewardInter, default: [], _id: false})
goods: RewardInter[];
@prop({ required: true, type: RoleStatus })
roleStatus: RoleStatus[];
@prop({ required: true, default: nowSeconds() })
sendTime: number;
@prop({ required: true, default: nowSeconds() })
endTime: number;
@prop({ required: true })
params: string[];
@prop({ required: true })
mailTemType: number; //1:表示模板邮件2表示系统邮件
@prop({ required: true })
sendName: string;
public static async addGroupMails(mails: Array<GroupMailType>) {
await GroupMailModel.insertMany(mails);
/**
* @description 根据玩家id获得所有有效邮件
* @param {String} roleId 玩家id
*/
public static async findByRoleId(roleId: string) {
const result: GroupMailType[] = await GroupMailModel.find({
'roleStatus.roleId': roleId,
'roleStatus.status': { $in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ, MAIL_STATUS.RECEIVED ] },
sendTime:{ $lte: nowSeconds() }, endTime: { $gte: nowSeconds() }
}).populate('mail').lean();
return result;
}
public static async addGroupMail(params:{ sendRoles: SendRole[],mailId: string, mailTemType:number, goods?: Array<RewardInter>, sendName?: string, endTime?:number, sendTime?: number, params?:string[] }) {
/**
* @description 创建邮件
* @param params
*/
public static async addMail(params: GroupMailTypeParam) {
const doc = new GroupMailModel();
const mail = Object.assign(doc.toJSON(), params);
await GroupMailModel.create(mail);
return mail;
delete mail._id;
let rec: GroupMailType = await GroupMailModel.findByIdAndUpdate(doc._id, mail, { new: true, upsert: true }).populate('mail').lean();
return rec;
}
/**
* 根据id删除单条邮件
* @param _id
*/
public static async delMailById(_id: string, roleId: string) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate(
{
_id, sendTime:{ $lte: nowSeconds() },
$or: [{
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.READ}}, hasGoods:false
}, {
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.RECEIVED}}, hasGoods: true
}]
},
{ $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE } },
{ new: true }
).lean();
return result;
}
/**
* 根据玩家id批量删除
* @param _id
* @param roleId
*/
public static async delMailsByRoleId(roleId: string) {
const ids: { _id: string }[] = await GroupMailModel.find( {
sendTime:{ $lte: nowSeconds() },
$or: [{
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.READ}}, hasGoods:false
}, {
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.RECEIVED}}, hasGoods: true
}]
},).select('_id').lean();
const result: GroupMailType[] = [];
for(let _id of ids) {
let rec = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId }, { $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE }}, { new: true }).lean();
result.push(rec);
}
return result;
}
public static async getGroupMailsByRoleId(roleId: string, lean = true) {
const result: GroupMailType[] = await GroupMailModel.find({ 'sendRoles.roleId': roleId, 'sendRoles.status': { $ne: -1}, sendTime:{$lte: nowSeconds()} }).lean(lean);
const result: GroupMailType[] = await GroupMailModel.find({ 'roleStatus.roleId': roleId, 'roleStatus.status': { $ne: -1}, sendTime:{$lte: nowSeconds()} }).lean(lean);
return result;
}
@@ -65,7 +98,7 @@ export default class GroupMail extends BaseModel {
}
public static async pushRoleMail( roleId: string, mailId: string, mailTemType: number, lean = true) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ mailId, mailTemType, sendTime:{$lte: nowSeconds()} }, {$push: {sendRoles: {roleId, status: 0}}}).lean(lean);
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ mailId, mailTemType, sendTime:{$lte: nowSeconds()} }, {$push: {roleStatus: {roleId, status: 0}}}).lean(lean);
return result;
}
@@ -74,40 +107,38 @@ export default class GroupMail extends BaseModel {
return result;
}
public static async updateMailByStatus(_id: string, roleId: string, status: number, conditions: number[], lean = true) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'sendRoles.roleId': roleId,sendTime:{$lte: nowSeconds()}, 'sendRoles.status': {$in: conditions} }, {$set:{ 'sendRoles.$.status': status }}, { new: true }).lean(lean);
public static async updateStatusWithCondition(_id: string, roleId: string, status: number, conditions: number[], lean = true) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId, sendTime:{$lte: nowSeconds()}, 'roleStatus.status': {$in: conditions} }, {$set:{ 'roleStatus.$.status': status }}, { new: true }).lean(lean);
return result;
}
public static async deleteMail(_id: string, roleId: string, status: number, lean = true) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'sendRoles.roleId': roleId, sendTime:{$lte: nowSeconds()}}, {$set:{ 'sendRoles.$.status': status }}, { new: true }).lean(lean);
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId, sendTime:{$lte: nowSeconds()}}, {$set:{ 'roleStatus.$.status': status }}, { new: true }).lean(lean);
return result;
}
public static async findReadAndRewardsMails(roleId: string, lean = true) {
const ids: GroupMailType[] = await GroupMailModel.find({ sendTime:{$lte: nowSeconds()}, sendRoles: { $elemMatch: { roleId, $or:[ {$and: [{status: MAIL_STATUS.READ}, {goods: []}]},{status: MAIL_STATUS.RECEIVED} ] } } }).select('_id').lean(lean);
const ids: GroupMailType[] = await GroupMailModel.find({ sendTime:{$lte: nowSeconds()}, roleStatus: { $elemMatch: { roleId, $or:[ {$and: [{status: MAIL_STATUS.READ}, { hasGoods: true }]},{status: MAIL_STATUS.RECEIVED} ] } } }).select('_id').lean(lean);
return ids;
}
public static async updateMailStatus(ids: string[], status: number, roleId: string, lean = true) {
public static async updateStatusByIds(ids: string[], status: number, roleId: string, lean = true) {
let mails = [];
for(let id of ids) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({_id: id, "sendRoles.roleId": roleId}, { $set:{ 'sendRoles.$.status': status } }, { new: true }).lean(lean);
let { status: resStatus } = findWhere(result.sendRoles, { roleId });
mails.push({id: result._id, status: resStatus, mailType: MAIL_TYPE.GROUPMAIL});
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({_id: id, "roleStatus.roleId": roleId}, { $set:{ 'roleStatus.$.status': status } }, { new: true }).lean(lean);
let { status: resStatus } = findWhere(result.roleStatus, { roleId });
mails.push({id: result._id, status: resStatus, /*mailType: MAIL_TYPE.GROUPMAIL*/});
}
return mails;
}
public static async delMail(_id: string, roleId: string, lean = true) {
const result: GroupMailType = await GroupMailModel.findOneAndUpdate({ _id, sendTime:{ $lte: nowSeconds() },
sendRoles: { $elemMatch: { roleId, $or:[ {$and: [{status: MAIL_STATUS.READ}, {goods: []}]},{status: MAIL_STATUS.RECEIVED} ] } } },
{ $set:{ 'sendRoles.$.status': MAIL_STATUS.DELETE } }, { new: true }).lean(lean);
return result;
}
/**
* 查询有奖励的邮件
* @param roleId
* @param lean
*/
public static async findRewardsMails(roleId: string, lean = true) {
const result: GroupMailType[] = await GroupMailModel.find({ sendRoles: { $elemMatch:{roleId, status:{ $in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ ] }} }, sendTime:{$lte: nowSeconds()} }).select('_id goods mailId mailTemType status').lean(lean);
const result: GroupMailType[] = await GroupMailModel.find({ roleStatus: { $elemMatch:{roleId, status:{ $in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ ] }} }, sendTime:{$lte: nowSeconds()} }).lean(lean);
return result;
}
}

View File

@@ -1,59 +1,97 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import MailTemp from './MailTemp';
import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { MAIL_STATUS, MAIL_TYPE } from '../consts/constModules/mailConst';
class RewardInter {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
@index({ roleId: 1 })
@index({ roleId: 1, mailId: 1, type: 1 })
export default class Mail extends BaseModel {
export default class Mail extends MailTemp {
@prop({ required: true })
roleId: string;
@prop({ required: true })
mailId: string;
@prop({ required: true, type: RewardInter, default: [], _id: false })
goods: Array<RewardInter>;
@prop({ required: true, default: nowSeconds() })
sendTime: number;
@prop({ required: true, type: String, _id: false})
params: string[];
@prop({ required: true, default: MAIL_STATUS.CREATE })
status: number;
@prop({ required: true })
mailTemType: number; //1:表示从gm下发的邮件2表示系统邮件
@prop({ required: true })
sendName: string;
@prop({ required: true })
endTime: number;
public static async addMails(mails: Array<MailType>) {
await MailModel.insertMany(mails);
/**
* @description 根据玩家id获得所有有效邮件
* @param {String} roleId 玩家id
*/
public static async findByRoleId(roleId: string) {
const result: MailType[] = await MailModel.find({
roleId,
status: { $in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ, MAIL_STATUS.RECEIVED ] },
sendTime:{ $lte: nowSeconds() }, endTime: { $gte: nowSeconds() }
}).populate('mail').lean();
return result;
}
public static async addMail(params: { roleId: string, goods: Array<RewardInter>, sendName: string, mailId: string, endTime: number, mailTemType: number, params?: string[], sendTime?: number }) {
/**
* @description 创建邮件
* @param {MailTypeParam} params 邮件内容
*/
public static async addMail(params: MailTypeParam) {
const doc = new MailModel();
const mail = Object.assign(doc.toJSON(), params);
await MailModel.create(mail);
return mail;
delete mail._id;
let rec: MailType = await MailModel.findByIdAndUpdate(doc._id, mail, { new: true, upsert: true }).lean();
return rec;
}
public static async getMailsByRoleId(roleId: string, lean = true) {
const result: MailType[] = await MailModel.find({ roleId, status: { $ne: -1 }, sendTime:{$lte: nowSeconds()} }).lean(lean);
/**
* 根据id更新单个邮件状态
* @param _id
* @param status 邮件状态
* @param conditions 可更新邮件状态
*/
public static async updateStatusWithCondition(_id: string, status: MAIL_STATUS, conditions: MAIL_STATUS[]) {
const result: MailType = await MailModel.findOneAndUpdate(
{ _id, status: { $in: conditions }, sendTime:{$lte: nowSeconds()} },
{ $set: { status } }, { new: true }
).lean();
return result;
}
/**
* 根据id更新多条邮件状态
* @param ids
* @param status
* @param lean
*/
public static async updateStatusByIds(ids: string[], status: number, lean = true) {
let mails = [];
for(let id of ids) {
const result: MailType = await MailModel.findOneAndUpdate({_id: id}, { $set:{ 'status': status } }, { new: true }).lean(lean);
mails.push({id: result._id, status: result.status, /* mailType: MAIL_TYPE.SINGLEMAIL */});
}
return mails;
}
/**
* 根据id删除单条邮件
* @param _id
*/
public static async delMailById(_id: string) {
const result: MailType = await MailModel.findOneAndUpdate(
{ _id, $or: [{ $and: [{ status: MAIL_STATUS.READ, hasGoods: false }] }, { status: MAIL_STATUS.RECEIVED }], sendTime:{$lte: nowSeconds()} },
{ $set: { status: MAIL_STATUS.DELETE } },
{ new: true }
).lean();
return result;
}
/**
* 根据玩家id批量删除
* @param _id
* @param roleId
*/
public static async delMailsByRoleId(roleId: string) {
const ids: { _id: string }[] = await MailModel.find({ roleId, $or: [{ $and: [{ status: MAIL_STATUS.READ, hasGoods: false }] }, { status: MAIL_STATUS.RECEIVED }], sendTime:{$lte: nowSeconds()} }).select('_id').lean();
let result: MailType[] = [];
for(let _id of ids) {
let rec = await MailModel.findByIdAndUpdate(_id, { $set:{ status: MAIL_STATUS.DELETE }}, { new: true }).lean();
result.push(rec);
}
return result;
}
@@ -67,37 +105,21 @@ export default class Mail extends BaseModel {
return result;
}
public static async updateMailByStatus(_id: string, conditions: number[], update: MailTypeParam, lean = true) {
const result: MailType = await MailModel.findOneAndUpdate({ _id, status: { $in: conditions }, sendTime:{$lte: nowSeconds()} }, { $set: update }, { new: true }).lean(lean);
return result;
}
public static async updateMail(_id: string, update: MailTypeParam, lean = true) {
const result: MailType = await MailModel.findOneAndUpdate({ _id, sendTime:{$lte: nowSeconds()} }, { $set: update }, { new: true }).lean(lean);
return result;
}
public static async findReadAndRewardsMails(roleId: string, lean = true) {
const ids: MailType[] = await MailModel.find({ roleId, $or: [{ $and: [{ status: MAIL_STATUS.READ, goods: [] }] }, { status: MAIL_STATUS.RECEIVED }], sendTime:{$lte: nowSeconds()} }).select('_id').lean(lean);
return ids;
}
public static async updateMailStatus(ids: string[], status: number, lean = true) {
let mails = [];
for(let id of ids) {
const result: MailType = await MailModel.findOneAndUpdate({_id: id}, { $set:{ 'status': status } }, { new: true }).lean(lean);
mails.push({id: result._id, status: result.status, mailType: MAIL_TYPE.SINGLEMAIL});
}
return mails;
}
public static async delMail(_id: string, lean = true) {
const result: MailType = await MailModel.findOneAndUpdate({ _id, $or: [{ $and: [{ status: MAIL_STATUS.READ, goods: [] }] }, { status: MAIL_STATUS.RECEIVED }], sendTime:{$lte: nowSeconds()} }, { $set: { status: MAIL_STATUS.DELETE } }, { new: true }).lean(lean);
return result;
}
/**
* 查询有奖励的邮件
* @param roleId
* @param lean
*/
public static async findRewardsMails(roleId: string, lean = true) {
const result: MailType[] = await MailModel.find({ roleId, status: {$in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ ] }, sendTime:{$lte: nowSeconds()} }).select('_id goods mailId mailTemType status').lean(lean);
const result: MailType[] = await MailModel.find({ roleId, status: {$in: [ MAIL_STATUS.CREATE, MAIL_STATUS.READ ] }, sendTime:{$lte: nowSeconds()} }).lean(lean);
return result;
}
}

38
shared/db/MailTemp.ts Normal file
View File

@@ -0,0 +1,38 @@
import BaseModel from './BaseModel';
import { prop, Ref, mongoose } from '@typegoose/typegoose';
import GMMail from './GMMail';
class Reward {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
export default class MailTemp extends BaseModel {
@prop({ required: true })
contentId: number; // dic_email_content.json中的id
@prop({ ref: 'GMMail', type: mongoose.Schema.Types.ObjectId })
mail: Ref<GMMail>;
@prop({ required: true })
sendTime: number;
@prop({ required: true })
endTime: number;
@prop({ required: true, type: String, _id: false})
params: string[];
@prop({ required: true })
sendName: string; // 发件人
@prop({ required: true })
hasGoods: boolean;
@prop({ required: true, type: Reward, default: [], _id: false })
goods: Array<Reward>;
}

View File

@@ -1,13 +1,13 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
class RewardInter {
class Reward {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
class HeroRewardInter {
class HeroReward {
@prop({ required: true })
hid: number;
@prop({ required: true })
@@ -27,10 +27,10 @@ export class HeroScores {
}
export interface pvpUpdate {
rankGoods?:Array<RewardInter>;
rankGoods?:Array<Reward>;
oldSeasonData?: SeasonData;
show?: boolean;
heroGoods?:Array<HeroRewardInter>;
heroGoods?:Array<HeroReward>;
}
class SeasonData {
@@ -73,11 +73,11 @@ export default class PvpSeasonResult extends BaseModel {
@prop({ required: true, default: true })
show: boolean;
@prop({ required: true, type: HeroRewardInter, default: [], _id: false})
heroGoods: Array<HeroRewardInter>;
@prop({ required: true, type: HeroReward, default: [], _id: false})
heroGoods: Array<HeroReward>;
@prop({ required: true, type: RewardInter, default: [], _id: false})
rankGoods: Array<RewardInter>;
@prop({ required: true, type: Reward, default: [], _id: false})
rankGoods: Array<Reward>;
public static async updatePvpSeasonResult(roleId: string, update: pvpUpdate , lean = true) {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOneAndUpdate({roleId}, {$set: update}, {upsert: true, new: true}).lean(lean);

138
shared/db/ServerMail.ts Normal file
View File

@@ -0,0 +1,138 @@
/**
* 全服邮件
*/
import MailTemp from './MailTemp';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { MAIL_STATUS } from '../consts/constModules/mailConst';
class RoleStatus {
@prop({ required: true })
roleId: string;
@prop({ required: true })
status: number;
}
@index({ sendRoles: 1 })
export default class ServerMail extends MailTemp {
@prop({ required: true })
serverId: number;
@prop({ required: true, type: RoleStatus })
roleStatus: RoleStatus[];
@prop({ required: true, type: String })
delRoles: string[];
/**
* @description 根据玩家id获得所有有效邮件
* @param {String} roleId 玩家id
* @param {Number} serverId 服务器id
*/
public static async findByRoleId(roleId: string, serverId: number) {
const result: ServerMailType[] = await ServerMailModel.find({
serverId,
delRoles: { $ne: roleId },
sendTime:{ $lte: nowSeconds() }, endTime: { $gte: nowSeconds() }
}).populate('mail').lean();
return result;
}
/**
* @description 创建邮件
* @param params
*/
public static async addMail(params: ServerMailTypeParam) {
const doc = new ServerMailModel();
const mail = Object.assign(doc.toJSON(), params);
delete mail._id;
let rec: ServerMailType = await ServerMailModel.findByIdAndUpdate(doc._id, mail, { new: true, upsert: true }).lean();
return rec;
}
/**
* 根据id删除单条邮件
* @param _id
* @param lean
*/
public static async delMailById(_id: string, roleId: string) {
const result: ServerMailType = await ServerMailModel.findOneAndUpdate(
{
sendTime:{ $lte: nowSeconds() },
$or: [{
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.READ}}, hasGoods:false
}, {
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.RECEIVED}}, hasGoods: true
}]
},
{ $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE, $push: { 'delRoles': roleId } } },
{ new: true }
).lean();
return result;
}
/**
* 根据玩家id批量删除
* @param _id
* @param roleId
*/
public static async delMailsByRoleId(roleId: string) {
const ids: { _id: string }[] = await ServerMailModel.find(
{
sendTime:{ $lte: nowSeconds() },
$or: [{
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.READ}}, hasGoods:false
}, {
roleStatus: {$elemMatch: {roleId, status: MAIL_STATUS.RECEIVED}}, hasGoods: true
}]
}
).select('_id').lean();
let result: ServerMailType[] = [];
for(let _id of ids) {
let rec = await ServerMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId }, { $set:{ 'roleStatus.$.status': MAIL_STATUS.DELETE }, $push: { delRoles: roleId }}, { new: true }).lean();
result.push(rec);
}
return result;
}
public static async updateStatusWithCondition(_id: string, roleId: string, status: number, conditions: number[], servermail?: ServerMailType) {
if(!servermail) servermail = await ServerMailModel.findById(_id).lean();
let { roleStatus } = servermail;
let hasRole = roleStatus.find(cur => cur.roleId == roleId);
let myStatus = hasRole?hasRole.status: MAIL_STATUS.CREATE;
if(conditions.indexOf(myStatus) == -1) return null;
if(hasRole) {
servermail = await ServerMailModel.findOneAndUpdate({ _id, 'roleStatus.roleId': roleId }, { $set: { 'roleStatus.$.status': status } }, {new: true}).lean();
} else {
servermail = await ServerMailModel.findByIdAndUpdate(_id, { $push: { roleStatus: { roleId, status } } }, {new: true}).lean();
}
return servermail
}
/**
* 查询有奖励的邮件
* @param roleId
* @param lean
*/
public static async findRewardsMails(serverId: number, roleId: string, lean = true) {
const allMails: ServerMailType[] = await ServerMailModel.find({ serverId, sendTime:{$lte: nowSeconds()} }).lean(lean);
let result: ServerMailType[] = [];
for(let mail of allMails) {
let { roleStatus } = mail;
let hasRole = roleStatus.find(cur => cur.roleId == roleId);
if(hasRole) {
if(hasRole.status == MAIL_STATUS.CREATE || hasRole.status == MAIL_STATUS.READ) {
result.push(mail);
}
} else {
result.push(mail);
}
}
return result;
}
}
export const ServerMailModel = getModelForClass(ServerMail);
export interface ServerMailType extends Pick<DocumentType<ServerMail>, keyof ServerMail>{}
export type ServerMailTypeParam = Partial<ServerMailType>; // 将所有字段变成可选项

View File

@@ -0,0 +1,95 @@
import { GM_MAIL_TYPE, MAIL_TYPE, MAIL_STATUS, SEND_NAME } from "../../consts";
import { ItemReward } from '../dbGeneral';
import { MailType } from "../../db/Mail";
import { GroupMailType } from "../../db/GroupMail";
import { ServerMailType } from '../../db/ServerMail';
import { GMMailType } from "../../db/GMMail";
import { gameData } from "../../pubUtils/data";
export class MailParam {
id: string; // mongodb生成objectId
mailType: GM_MAIL_TYPE; // 邮件类型
sendName: string = ''; // 发件人
content: string = ''; // 内容
sendTime: number = 0; // 发送时间
endTime: number = 0; // 过期时间
goods: ItemReward[] = []; // 奖励
status: MAIL_STATUS = MAIL_STATUS.CREATE; // 状态
constructor(mailType: GM_MAIL_TYPE, mail: MailType|GroupMailType|ServerMailType, roleId?: string) {
this.setMail(mailType, mail);
if(mailType == GM_MAIL_TYPE.SINGLE) {
this.setSingleMail(<MailType>mail, roleId);
} else if (mailType == GM_MAIL_TYPE.GROUP) {
this.setGroupMail(<GroupMailType>mail, roleId);
} else if (mailType == GM_MAIL_TYPE.SERVER) {
this.setServerMail(<ServerMailType>mail, roleId);
}
}
setMail(mailType: GM_MAIL_TYPE, mail: MailType|GroupMailType|ServerMailType) {
this.id = mail._id;
this.mailType = mailType;
this.sendTime = mail.sendTime;
this.endTime = mail.endTime;
}
setSingleMail(mail: MailType, roleId?: string) {
this.setContent(mail);
if(roleId != undefined) {
if(mail.roleId == roleId) {
this.status = mail.status;
} else {
this.status = MAIL_STATUS.DELETE;
}
}
}
setGroupMail(mail: GroupMailType, roleId?: string) {
this.setContent(mail);
if(roleId != undefined) {
let { roleStatus } = mail;
let myRoleStatus = roleStatus.find(cur => cur.roleId == roleId);
if(myRoleStatus) {
this.status = myRoleStatus.status;
} else {
this.status = MAIL_STATUS.DELETE;
}
}
}
setServerMail(mail: ServerMailType, roleId?: string) {
this.setContent(mail);
if(roleId != undefined) {
let { delRoles, roleStatus } = mail;
if(delRoles.indexOf(roleId) == -1) {
let myRoleStatus = roleStatus.find(cur => cur.roleId == roleId);
if(myRoleStatus) {
this.status = myRoleStatus.status;
} else {
this.status = MAIL_STATUS.CREATE;
}
} else {
this.status = MAIL_STATUS.DELETE;
}
}
}
setContent(mail: MailType|GroupMailType|ServerMailType) {
let { contentId = 0, params, goods, sendName } = mail;
let dicMail = gameData.mail.get(contentId);
if(!dicMail) dicMail = gameData.mail.get(0);
this.content = this.getContent(dicMail.content, params);
this.sendName = sendName||SEND_NAME;
this.goods = goods;
}
getContent(content: string, params: string[]) {
if(!content) content = '%d';
for(let p of params) {
content = content.replace(/%d/, p);
}
return content
}
}

View File

@@ -15,7 +15,7 @@ export function loadMail() {
let arr = readFileAndParse(FILENAME.DIC_MAIL);
arr.forEach(o => {
o.time = o.time * 24 * 60 * 60;
o.time = o.time * 60 * 60;
dicMail.set(o.id, o);
});
arr = undefined;