diff --git a/game-server/app/servers/activity/handler/monthlyFundHandler.ts b/game-server/app/servers/activity/handler/monthlyFundHandler.ts index 514836816..29023c4dc 100644 --- a/game-server/app/servers/activity/handler/monthlyFundHandler.ts +++ b/game-server/app/servers/activity/handler/monthlyFundHandler.ts @@ -5,6 +5,8 @@ import { getMonthlyFundData, getMonthlyFundDataShow } from '../../../services/ac import { ActivityWeeklyFundModel } from '../../../db/ActivityWeeklyFund'; import { addReward, stringToRewardParam } from '../../../services/activity/giftPackageService'; import { ActivityMonthlyFundModel } from '../../../db/ActivityMonthlyFund'; +import { monthlyFundSchedule } from '../../../services/timeTaskService'; +import moment = require('moment'); export default function (app: Application) { @@ -63,6 +65,11 @@ export class MonthlyFundHandler { let record = await ActivityMonthlyFundModel.sign(serverId, activityId, roleId, playerData.roundIndex, pageIndex, dayIndex, playerData.todayIndex); if(!record) return resResult(STATUS.ACTIVITY_MONTHLY_FUND_HAS_SIGN); + pageData.setPlayerRecord(record); + if(pageData.hasReceivedAll()) { + await ActivityMonthlyFundModel.setReceivedAll(serverId, activityId, roleId, playerData.roundIndex, pageIndex); + } + let rewardParamArr = stringToRewardParam(signReward.reward); let { goods, addHeros } = await addReward(roleId, roleName, sid, serverId, rewardParamArr, ITEM_CHANGE_REASON.ACT_MONTHLY_FUND_SIGN); @@ -70,4 +77,10 @@ export class MonthlyFundHandler { activityId, dayIndex, pageIndex, goods, addHeros }); } + + async debugSendMonthlyFundReward(msg: {}, session: BackendSession) { + + await monthlyFundSchedule(parseInt(moment().format('YYYYMM'))); + return resResult(STATUS.SUCCESS); + } } diff --git a/game-server/app/services/activity/activityService.ts b/game-server/app/services/activity/activityService.ts index fc872f83b..c624d236f 100644 --- a/game-server/app/services/activity/activityService.ts +++ b/game-server/app/services/activity/activityService.ts @@ -444,6 +444,7 @@ export function shouldReplace(activityType: ACTIVITY_TYPE) { // case ACTIVITY_TYPE.GROWTH_FUND_TOWER_VIP: // 高阶镇念塔成长基金 9 // case ACTIVITY_TYPE.GROWTH_FUND_MAIN_ELITE: // 精英成长基金 10 // case ACTIVITY_TYPE.GROWTH_FUND_MAIN_ELITE_VIP:// 高阶精英成长基金 11 + case ACTIVITY_TYPE.MONTHLY_FUND:// 月基金 return true; default: return false; diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index c8b43977b..4ccd6b448 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -2066,6 +2066,7 @@ export function checkRouteParam(route: string, msg: any) { case "guild.gvgBattleHandler.debugMoveRobots": case "guild.gvgBattleHandler.debugStopMoveRobot": case "chat.chatHandler.debugPushMessage": + case "activity.monthlyFundHandler.debugSendMonthlyFundReward": { if (msg.magicWord !== DEBUG_MAGIC_WORD || !isDevelopEnv()) return false; diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index 1d93ec3d1..2e0b3d6a5 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -5,10 +5,10 @@ import { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil'; import { getTodayGuildActivity, gameData } from '../pubUtils/data'; import { pvpSeasonEnd } from './pvpService'; import { getAllOnlineRoles, getAllServers, delGuildActivityRank, getServerCreateTime } from './redisService'; -import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_TIMER, ACTIVITY_TYPE, PUSH_ROUTE, STATUS, LADDER_STATUS, LADDER_SERVER_GAP_TIME, GVG_PERIOD, SDK_PUSH_MSG_TYPE } from '../consts'; +import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_TIMER, ACTIVITY_TYPE, PUSH_ROUTE, STATUS, LADDER_STATUS, LADDER_SERVER_GAP_TIME, GVG_PERIOD, SDK_PUSH_MSG_TYPE, MAIL_TYPE } from '../consts'; import { pinus } from 'pinus'; import { settleGuildWeekly } from './guildService'; -import { SendMailFun, sendMailsByGmMail, } from './mailService'; +import { sendMailByContent, SendMailFun, sendMailsByGmMail, } from './mailService'; import { sendEndMsgToAllServer, sendGuildActivityStatus, setPreDayActiveData, incCurGuildActivityIndex } from './guildActivity/guildActivityService'; import { sendUngotDividendJob, startGuildAuction, startWorldAuction, stopAuction } from './auctionService'; import { DicGuildActivity } from '../pubUtils/dictionary/DicGuildActivity'; @@ -46,6 +46,11 @@ import { GVGConfigModel } from '../db/GVGConfig'; import { createNewGVGConfig, initLeaguePrepare } from './gvg/gvgService'; import { getFightTimeByPeriod, saveVestigeRankSchedule, gvgBattlePeriodSchedule } from './gvg/gvgFightService'; import { gvgBattleEnd } from './gvg/gvgBattleService'; +import { ActivityMonthlyFundModel } from '../db/ActivityMonthlyFund'; +import { getActivityById } from './activity/activityService'; +import { MonthlyFundData } from "../domain/activityField/monthlyFundField"; +import { RewardInter } from '../pubUtils/interface'; +import { stringToRewardInter } from './activity/giftPackageService'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; @@ -116,6 +121,9 @@ export async function init() { // 定时推送消息 initPushMsgSchedule(); + + // 月基金每月未领取 + initMonthlyFundSchedule(); } // 每日刷新 @@ -1011,4 +1019,38 @@ async function initPushMsgSchedule() { scheduleJob('sendAfkPlayers', '0 0 12 * * ?', async () => { pushClientMsg(SDK_PUSH_MSG_TYPE.AP_LUNCH); }); +} + +// 月基金未领取的发送到邮件,每月发送 +async function initMonthlyFundSchedule() { + scheduleJob('initMonthlyFundSchedule', '0 0 5 1 * ?', async () => { + let roundIndex = parseInt(moment().add(-1, 'M').format('YYYYMM')); + await monthlyFundSchedule(roundIndex); + }); +} + +export async function monthlyFundSchedule(roundIndex: number) { + let activityMap = new Map(); + let playerDatas = await ActivityMonthlyFundModel.findNotReceivedReward(roundIndex); + let _ids: string[] = []; + for(let playerData of playerDatas) { + if(!activityMap.has(playerData.activityId)) { + let activity = await getActivityById(playerData.activityId); + activityMap.set(playerData.activityId, activity); + } + let activityData = activityMap.get(playerData.activityId); + if(!activityData) continue; + let data = new MonthlyFundData(activityData, 0, 0); + let page = data.findPage(playerData.pageIndex); + page.setPlayerRecord(playerData); + let rewards: RewardInter[] = []; + for(let { reward, hasReceived } of page.rewards) { + if(!hasReceived) rewards.push(...stringToRewardInter(reward)); + } + if(rewards.length > 0) { + await sendMailByContent(MAIL_TYPE.MONTHLY_FUND, playerData.roleId, { goods: rewards }); + } + _ids.push(playerData._id); + } + await ActivityMonthlyFundModel.updateHasReceivedAll(_ids); } \ No newline at end of file diff --git a/shared/consts/constModules/mailConst.ts b/shared/consts/constModules/mailConst.ts index d0e29eb6c..a756c2658 100644 --- a/shared/consts/constModules/mailConst.ts +++ b/shared/consts/constModules/mailConst.ts @@ -73,6 +73,7 @@ export enum MAIL_TYPE { LEAGUE_MAIL = 42, // 联军邮件 VESTIGE_REWARD = 43, // 补发遗迹邮件 GVG_BOX_REWARD = 44, // 云台补发 + MONTHLY_FUND = 45, // 补发月基金奖励 }; export const SEND_NAME = '系统'; diff --git a/shared/db/ActivityMonthlyFund.ts b/shared/db/ActivityMonthlyFund.ts index 8a709dc5a..bc45f4f2d 100644 --- a/shared/db/ActivityMonthlyFund.ts +++ b/shared/db/ActivityMonthlyFund.ts @@ -44,13 +44,16 @@ export default class Activity_Monthly_Fund extends BaseModel { @prop({ required: true, type: SignRecord, _id: false }) record: SignRecord[]; // 铸造记录 + @prop({ required: true }) + hasReceivedAll: boolean; // 铸造记录 + public static async findData(serverId: number, activityId: number, roundIndex: number, roleId: string) { let result: ActivityMonthlyFundModelType[] = await ActivityMonthlyFundModel.find({ serverId, roleId, activityId, roundIndex }).lean(); return result; } public static async buy(serverId: number, activityId: number, roleId: string, roundIndex: number, pageIndex: number, productID: string) { - let result: ActivityMonthlyFundModelType = await ActivityMonthlyFundModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex, pageIndex }, { $setOnInsert: { record: [], productID } }, { new: true, upsert: true }).lean(); + let result: ActivityMonthlyFundModelType = await ActivityMonthlyFundModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex, pageIndex }, { $setOnInsert: { record: [], productID, hasReceivedAll: false } }, { new: true, upsert: true }).lean(); return result; } @@ -58,6 +61,20 @@ export default class Activity_Monthly_Fund extends BaseModel { let result: ActivityMonthlyFundModelType = await ActivityMonthlyFundModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex, pageIndex, 'record.dayIndex': { $ne: dayIndex } }, { $push: { record: new SignRecord(dayIndex, todayIndex)} }, { new: true }).lean(); return result; } + + public static async setReceivedAll(serverId: number, activityId: number, roleId: string, roundIndex: number, pageIndex: number) { + let result: ActivityMonthlyFundModelType = await ActivityMonthlyFundModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex, pageIndex }, { $set: { hasReceivedAll: true }}, { new: true }).lean(); + return result; + } + + public static async findNotReceivedReward(roundIndex: number) { + let result: ActivityMonthlyFundModelType[] = await ActivityMonthlyFundModel.find({ roundIndex, hasReceivedAll: false }).lean(); + return result; + } + + public static async updateHasReceivedAll(_ids: string[]) { + await ActivityMonthlyFundModel.updateMany({ _id: { $in: _ids }}, { $set: { hasReceivedAll: true } }); + } } export const ActivityMonthlyFundModel = getModelForClass(Activity_Monthly_Fund); diff --git a/shared/domain/activityField/monthlyFundField.ts b/shared/domain/activityField/monthlyFundField.ts index 6ce6b7c47..3eb63751f 100644 --- a/shared/domain/activityField/monthlyFundField.ts +++ b/shared/domain/activityField/monthlyFundField.ts @@ -1,6 +1,10 @@ // 周基金 +import moment = require('moment'); +import { SHOP_REFRESH_TYPE } from '../../consts'; import { ActivityModelType } from '../../db/Activity'; import { ActivityMonthlyFundModelType } from '../../db/ActivityMonthlyFund'; +import { getZeroPointD } from '../../pubUtils/timeUtil'; +import { deltaDays } from '../../pubUtils/util'; import { ActivityBase } from './activityField'; interface MonthlyFundRewardInDb { @@ -68,7 +72,7 @@ class MonthlyFundPage { this.hasBought = true; for(let { dayIndex } of playerData.record) { let reward = this.rewards.find(cur => cur.dayIndex == dayIndex); - if(reward) reward.setHasReceived(); + if(reward || playerData.hasReceivedAll) reward.setHasReceived(); } } @@ -76,7 +80,7 @@ class MonthlyFundPage { return this.rewards.find(cur => cur.dayIndex == dayIndex); } - private hasReceivedAll() { + public hasReceivedAll() { return !this.rewards.find(cur => !cur.hasReceived); } @@ -103,6 +107,8 @@ export class MonthlyFundData extends ActivityBase { let obj = new MonthlyFundPage(data, this.beginTime); if(obj) this.list.push(obj); } + this.roundIndex = parseInt(moment(this.beginTime).format('YYYYMM')); + this.todayIndex = deltaDays(getZeroPointD(SHOP_REFRESH_TYPE.MONTHLY), new Date) + 1; } public setPlayerRecords(playerDatas: ActivityMonthlyFundModelType[]) { diff --git a/shared/resource/jsons/dic_email_content.json b/shared/resource/jsons/dic_email_content.json index 378d2e2bf..467ffebc6 100644 --- a/shared/resource/jsons/dic_email_content.json +++ b/shared/resource/jsons/dic_email_content.json @@ -313,5 +313,12 @@ "sendName": "学宫驿使", "content": "亲爱的百家传人,逐鹿中原本轮备战期已结束,您在联军云台中的宝箱奖励尚未领取,现已发送至邮箱,请查收", "time": 720 + }, + { + "id": 45, + "title": "&", + "sendName": "学宫驿使", + "content": "月基金", + "time": 720 } ] \ No newline at end of file