diff --git a/game-server/app/servers/battle/handler/guildHandler.ts b/game-server/app/servers/battle/handler/guildHandler.ts index 7042d428a..c4d91e2f2 100644 --- a/game-server/app/servers/battle/handler/guildHandler.ts +++ b/game-server/app/servers/battle/handler/guildHandler.ts @@ -14,7 +14,7 @@ import { GuildLeader } from '../../../domain/rank'; import { UserGuildApplyModel } from '../../../db/UserGuildApply'; import { hasStructureConsume, getStructureConsume, gameData } from '../../../pubUtils/data'; import { GuildRecModel } from '../../../db/GuildRec'; -import { 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 }); } diff --git a/game-server/app/servers/chat/remote/chatRemote.ts b/game-server/app/servers/chat/remote/chatRemote.ts index 07eecd942..e5900a5db 100644 --- a/game-server/app/servers/chat/remote/chatRemote.ts +++ b/game-server/app/servers/chat/remote/chatRemote.ts @@ -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)); + } } diff --git a/game-server/app/servers/chat/remote/guildRemote.ts b/game-server/app/servers/chat/remote/guildRemote.ts index 327df2816..e9517d0b1 100644 --- a/game-server/app/servers/chat/remote/guildRemote.ts +++ b/game-server/app/servers/chat/remote/guildRemote.ts @@ -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, {}); + } + } \ No newline at end of file diff --git a/game-server/app/servers/gate/remote/gateRemote.ts b/game-server/app/servers/gate/remote/gateRemote.ts index 5b9bed929..a65e16bd6 100644 --- a/game-server/app/servers/gate/remote/gateRemote.ts +++ b/game-server/app/servers/gate/remote/gateRemote.ts @@ -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); } diff --git a/game-server/app/servers/gm/handler/gmHandler.ts b/game-server/app/servers/gm/handler/gmHandler.ts index a38c8d5a7..f197ca062 100644 --- a/game-server/app/servers/gm/handler/gmHandler.ts +++ b/game-server/app/servers/gm/handler/gmHandler.ts @@ -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) { diff --git a/game-server/app/servers/gm/remote/gmRemote.ts b/game-server/app/servers/gm/remote/gmRemote.ts index ce1ff7cfa..2eed86f87 100644 --- a/game-server/app/servers/gm/remote/gmRemote.ts +++ b/game-server/app/servers/gm/remote/gmRemote.ts @@ -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邮件的content,sendName 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邮件的content,sendName 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 diff --git a/game-server/app/servers/role/handler/mailHandler.ts b/game-server/app/servers/role/handler/mailHandler.ts index e92db31b9..d19561a3d 100644 --- a/game-server/app/servers/role/handler/mailHandler.ts +++ b/game-server/app/servers/role/handler/mailHandler.ts @@ -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 }); } } \ No newline at end of file diff --git a/game-server/app/servers/role/remote/roleRemote.ts b/game-server/app/servers/role/remote/roleRemote.ts index 255b81361..49a072944 100644 --- a/game-server/app/servers/role/remote/roleRemote.ts +++ b/game-server/app/servers/role/remote/roleRemote.ts @@ -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资源 diff --git a/game-server/app/services/activity/monthlyTicketService.ts b/game-server/app/services/activity/monthlyTicketService.ts index dd6a73ae8..741f0be73 100644 --- a/game-server/app/services/activity/monthlyTicketService.ts +++ b/game-server/app/services/activity/monthlyTicketService.ts @@ -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(); - let pushMessage = new Array(); 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; } diff --git a/game-server/app/services/auctionService.ts b/game-server/app/services/auctionService.ts index 13a965be9..5823c042e 100644 --- a/game-server/app/services/auctionService.ts +++ b/game-server/app/services/auctionService.ts @@ -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) { diff --git a/game-server/app/services/guildActivityService.ts b/game-server/app/services/guildActivityService.ts index c1dba7a28..79cbe2418 100644 --- a/game-server/app/services/guildActivityService.ts +++ b/game-server/app/services/guildActivityService.ts @@ -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); diff --git a/game-server/app/services/guildBossService.ts b/game-server/app/services/guildBossService.ts index 8d3014a6b..43fd8be4b 100644 --- a/game-server/app/services/guildBossService.ts +++ b/game-server/app/services/guildBossService.ts @@ -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); diff --git a/game-server/app/services/guildService.ts b/game-server/app/services/guildService.ts index ce02db2a5..d4b17c2a0 100644 --- a/game-server/app/services/guildService.ts +++ b/game-server/app/services/guildService.ts @@ -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(); - let pushMessage = new Array(); 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 }); } diff --git a/game-server/app/services/guildTrainService.ts b/game-server/app/services/guildTrainService.ts index e0272de9a..f47ba171e 100644 --- a/game-server/app/services/guildTrainService.ts +++ b/game-server/app/services/guildTrainService.ts @@ -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(); - 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);//重置玩家的挑战次数和购买挑战次数 diff --git a/game-server/app/services/mailService.ts b/game-server/app/services/mailService.ts index d8ccabb19..d1dfe47e4 100644 --- a/game-server/app/services/mailService.ts +++ b/game-server/app/services/mailService.ts @@ -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-读GmMail,1以上读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(); + 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(); + 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); - });//下发邮件,对应前端红点提示 } \ No newline at end of file diff --git a/game-server/app/services/pvpService.ts b/game-server/app/services/pvpService.ts index e65ca1d1b..80d13d4b1 100644 --- a/game-server/app/services/pvpService.ts +++ b/game-server/app/services/pvpService.ts @@ -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; } diff --git a/game-server/app/services/refreshService.ts b/game-server/app/services/refreshService.ts index 473cd4fc1..80663faae 100644 --- a/game-server/app/services/refreshService.ts +++ b/game-server/app/services/refreshService.ts @@ -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); } diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index ee3bcd7bd..6ad06b463 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -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(); - let pushMessage = new Array(); 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, pushMessage:Array) { +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; } /** diff --git a/shared/consts/constModules/mailConst.ts b/shared/consts/constModules/mailConst.ts index 8312790ed..3b2fe5d2e 100644 --- a/shared/consts/constModules/mailConst.ts +++ b/shared/consts/constModules/mailConst.ts @@ -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 = '系统'; \ No newline at end of file diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index e0ffa5d18..65a532e40 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -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 { diff --git a/shared/consts/index.ts b/shared/consts/index.ts index aaf78e7a7..7e1b2022c 100644 --- a/shared/consts/index.ts +++ b/shared/consts/index.ts @@ -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'; \ No newline at end of file diff --git a/shared/db/GMMail.ts b/shared/db/GMMail.ts index 7d150aa0b..eedbcc3e2 100644 --- a/shared/db/GMMail.ts +++ b/shared/db/GMMail.ts @@ -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, keyof GMMail> { }; \ No newline at end of file +export interface GMMailType extends Pick, keyof GMMail> { }; + +export type GMMailTypeParam = Partial; // 将所有字段变成可选项 \ No newline at end of file diff --git a/shared/db/GroupMail.ts b/shared/db/GroupMail.ts index 32e411afe..8616bb73f 100644 --- a/shared/db/GroupMail.ts +++ b/shared/db/GroupMail.ts @@ -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) { - 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, 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; } } diff --git a/shared/db/Mail.ts b/shared/db/Mail.ts index 4191936af..d21469a09 100644 --- a/shared/db/Mail.ts +++ b/shared/db/Mail.ts @@ -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; - - @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) { - 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, 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; } } diff --git a/shared/db/MailTemp.ts b/shared/db/MailTemp.ts new file mode 100644 index 000000000..fa28fe40b --- /dev/null +++ b/shared/db/MailTemp.ts @@ -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; + + @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; + +} \ No newline at end of file diff --git a/shared/db/PvpSeasonResult.ts b/shared/db/PvpSeasonResult.ts index d93f680a8..8323da385 100644 --- a/shared/db/PvpSeasonResult.ts +++ b/shared/db/PvpSeasonResult.ts @@ -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; + rankGoods?:Array; oldSeasonData?: SeasonData; show?: boolean; - heroGoods?:Array; + heroGoods?:Array; } 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; + @prop({ required: true, type: HeroReward, default: [], _id: false}) + heroGoods: Array; - @prop({ required: true, type: RewardInter, default: [], _id: false}) - rankGoods: Array; + @prop({ required: true, type: Reward, default: [], _id: false}) + rankGoods: Array; 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); diff --git a/shared/db/ServerMail.ts b/shared/db/ServerMail.ts new file mode 100644 index 000000000..4f8223e95 --- /dev/null +++ b/shared/db/ServerMail.ts @@ -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, keyof ServerMail>{} +export type ServerMailTypeParam = Partial; // 将所有字段变成可选项 diff --git a/shared/domain/roleField/mail.ts b/shared/domain/roleField/mail.ts new file mode 100644 index 000000000..2a2d3487e --- /dev/null +++ b/shared/domain/roleField/mail.ts @@ -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(mail, roleId); + } else if (mailType == GM_MAIL_TYPE.GROUP) { + this.setGroupMail(mail, roleId); + } else if (mailType == GM_MAIL_TYPE.SERVER) { + this.setServerMail(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 + } +} \ No newline at end of file diff --git a/shared/pubUtils/dictionary/DicMail.ts b/shared/pubUtils/dictionary/DicMail.ts index ee2420029..7d043c1e9 100644 --- a/shared/pubUtils/dictionary/DicMail.ts +++ b/shared/pubUtils/dictionary/DicMail.ts @@ -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;