红点:添加每日5点定时刷新推送

This commit is contained in:
luying
2021-06-03 12:04:32 +08:00
parent 9eb82321c4
commit e29344072f
6 changed files with 156 additions and 81 deletions

View File

@@ -23,7 +23,7 @@ import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leav
import { reportOneOnline } from '../../../services/timeTaskService';
import { Rank } from '../../../services/rankService';
import { checkTaskWithRole, getCurTask } from '../../../services/taskService';
import { pushData } from '../../../services/connectorService';
import { pushData, everydayRefresh } from '../../../services/connectorService';
export default function (app: Application) {
return new EntryHandler(app);
@@ -174,6 +174,34 @@ export class EntryHandler {
session.on('closed', this.onUserLeave.bind(this));
}
/**
* 每天5点时的刷新数据.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async refresh(msg: { }, session: FrontendSession) {
let self = this;
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, null, true, true);
if (!role) {
return resResult(STATUS.ROLE_NOT_FOUND);
}
let { serverId } = role;
// 任务
checkTaskWithRole(serverId, role.roleId, self.app.get('serverId'), role.funcs, TASK_TYPE.LOGIN_SUM, role);
checkTaskWithRole(serverId, role.roleId, self.app.get('serverId'), role.funcs, TASK_TYPE.LOGIN_SERIES, role);
// 推送数据
pushData(role, session, 'refresh');
let todayZeroPoint = getZeroPoint();
return resResult(STATUS.SUCCESS, { todayZeroPoint });
}
/**
* User log out handler
*
@@ -295,4 +323,15 @@ export class EntryHandler {
console.log('debugQueryTokenById got user:', user);
return resResult(STATUS.SUCCESS, { user });
}
async debugPushRefToOnlineUsers(msg: { magicWord: string }, session: FrontendSession) {
const { magicWord } = msg;
console.log('debugQueryTokenById msg:', msg);
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
await everydayRefresh();
return resResult(STATUS.SUCCESS);
}
}

View File

@@ -8,7 +8,7 @@ import { getCurTask } from './taskService';
import { RoleType } from '../db/Role';
import { FrontendOrBackendSession, pinus } from 'pinus';
import { resResult } from '../pubUtils/util';
import { STATUS, USER_GUILD_SELECT, GUILD_SELECT } from '../consts';
import { STATUS, PUSH_BATCH, PUSH_INTERVAL } from '../consts';
import { getAllShopList } from './shopService';
import { getGeneralRank } from './rankService';
import { getFriendList, getApplyList } from './friendService';
@@ -18,7 +18,7 @@ import { getTowerStatus, getHungupRewards, getTasks } from './battleService';
import { getAllAssistCnt } from './comBattleService';
import { getDungeonData } from './dungeonService';
import { PvpSeasonResultModel } from '../db/PvpSeasonResult';
import { nowSeconds } from '../pubUtils/timeUtil';
import { nowSeconds, getZeroPoint } from '../pubUtils/timeUtil';
import { getGachaList } from './gachaService';
import { getSchoolList } from './roleService';
import { addRoleToGuildChannel } from './chatChannelService';
@@ -29,93 +29,106 @@ import { BossInstanceModel } from '../db/BossInstance';
import { getBossInstanceInfo } from './guildBossService';
import { getEvent } from './eventSercive';
import { getBattleListOfMain } from './normalBattleService';
import { GuildType } from '../db/Guild';
import UserGuild, { UserGuildType } from '../db/UserGuild';
import { setMedianCe } from './guildActivityService';
import { getAllOnlineRoles } from './redisService';
export async function pushData(role: RoleType, session: FrontendOrBackendSession) {
export async function pushData(role: RoleType, session: FrontendOrBackendSession, pushType: 'entry'|'refresh' = 'entry') {
try{
const { roleId, serverId, roleName, guildCode } = role;
const { roleId } = role;
const sid = session.get('sid');
pushEntryStart(roleId, sid);
// 商店
const shop = await getAllShopList(roleId);
pushEntryData('shop', roleId, sid, shop);
// 排行榜
const rank = await getGeneralRank(role, serverId);
pushEntryData('rank', roleId, sid, rank);
// 邮件
const mails = await getMails(roleId, serverId);
pushEntryData('mail', roleId, sid, mails);
// 好友
const friendList = await getFriendList(role);
const applyList = await getApplyList(roleId);
pushEntryData('friend', roleId, sid, { friendList, applyList });
// 每日关卡
const daily = await getDailyBattleList(role);
pushEntryData('daily', roleId, sid, daily);
// 远征
const expedition = await getExpeditionStatus(roleId, roleName);
pushEntryData('expedition', roleId, sid, expedition);
// 镇念塔
const tower = await getTowerEntryData(role);
pushEntryData('tower', roleId, sid, tower);
// 寻宝
const assistCnt = await getAllAssistCnt(roleId);
pushEntryData('comBattle', roleId, sid, { assistCnt })
// 秘境
const dungeon = await getDungeonData(role);
pushEntryData('dungeon', roleId, sid, dungeon);
// PVP
const hasSeasonReward = await getPvpEntryData(roleId);
pushEntryData('pvp', roleId, sid, { hasSeasonReward });
// 招募
const gacha = await getGachaList(roleId);
pushEntryData('gacha', roleId, sid, gacha);
// 百家学宫
const school = await getSchoolList(roleId);
pushEntryData('school', roleId, sid, school);
// 军团
const { hasGuild, guild, userGuild, guildResult } = await getGuildEntryData(role, sid, session);
if(hasGuild) {
pushEntryData('guild', roleId, sid, guildResult);
// 拍卖
const auction = await getAuction(guildCode, session);
pushEntryData('auction', roleId, sid, auction);
// 练兵场
const train = await getGuildTrainInstance(roleId, guild, userGuild);
pushEntryData('train', roleId, sid, train);
// 演武台boss
const bossInstance = await BossInstanceModel.findBossInstance(guild.code);
if(bossInstance) {
const boss = await getBossInstanceInfo(bossInstance, roleId);
pushEntryData('boss', roleId, sid, boss);
}
// 许愿池
const wishPool = await getWishPool(userGuild);
pushEntryData('wishPool', roleId, sid, wishPool);
const guildData = await getGuildEntryData(role, sid, session);
let modules = ['shop', 'rank', 'mail', 'friend', 'daily', 'expedition', 'tower', 'comBattle', 'dungeon', 'pvp', 'gacha', 'school', 'task', 'chat', 'event', 'battle'];
if(guildData.hasGuild) {
modules.push('guild', 'auction', 'train', 'boss', 'wishPool');
}
let notIncludeModule: string[] = [];
if(pushType == 'refresh') {
notIncludeModule = ['rank', 'mail', 'school', 'auction', 'train', 'chat', 'battle'];
}
// 任务
const { mainTask, dailyTask, achievement } = await getCurTask(role.roleId, session);
pushEntryData('task', roleId, sid, { mainTask, dailyTask, achievement });
// 聊天
const worldMsgs = await recentWorldMsgs(serverId);
const sysMsgs = await recentSysMsgs(serverId);
const guildMsgs = await recentGuildMsgs(guildCode);
const recentPrivateChats = await recentPrivateChatInfos(roleId, roleName);
pushEntryData('chat', roleId, sid, { worldMsgs, sysMsgs, guildMsgs, recentPrivateChats });
// 奇遇
const event = await getEvent(role.eventStatus, roleId, roleName);
pushEntryData('event', roleId, sid, event);
// 主线关卡列表
const battle = await getBattleListOfMain(role);
pushEntryData('battle', roleId, sid, battle);
for(let type of modules) {
if(notIncludeModule.indexOf(type) == -1) {
let data = await getModuleData(type, { role, session }, guildData);
pushEntryData(type, roleId, sid, data);
}
}
pushEntryEnd(roleId, sid);
}catch(e) {
console.error(e.stack);
}
}
async function getModuleData(type: string, data: {role: RoleType, session: FrontendOrBackendSession}, guildData: { hasGuild: boolean, guild?: GuildType, userGuild?: UserGuildType, guildResult?: any} = { hasGuild: false }) {
let { role, session } = data;
const { roleId, serverId, roleName, guildCode } = role;
let { hasGuild, guild, userGuild, guildResult } = guildData;
switch(type) {
case 'shop': // 商店
return await getAllShopList(roleId);
case 'rank': // 排名
return await getGeneralRank(role, serverId);
case 'mail': // 邮件
return await getMails(roleId, serverId);
case 'friend': // 好友
const friendList = await getFriendList(role);
const applyList = await getApplyList(roleId);
return { friendList, applyList }
case 'daily': // 每日
return await getDailyBattleList(role);
case 'expedition': // 远征
return await getExpeditionStatus(roleId, roleName);
case 'tower': // 镇念塔
return await getTowerEntryData(role);
case 'comBattle': // 寻宝
const assistCnt = await getAllAssistCnt(roleId);
return { assistCnt }
case 'dungeon': // 秘境
return await getDungeonData(role);
case 'pvp': // pvp
const hasSeasonReward = await getPvpEntryData(roleId);
return { hasSeasonReward }
case 'gacha':
return await getGachaList(roleId);
case 'school':
return await getSchoolList(roleId);
case 'guild':
return hasGuild? await guildResult: null;
case 'auction':
return hasGuild? await getAuction(guildCode, session): null;
case 'train':
return hasGuild? await getGuildTrainInstance(roleId, guild, userGuild): null;
case 'boss':
if(hasGuild) {
const bossInstance = await BossInstanceModel.findBossInstance(guild.code);
if(bossInstance) {
return await getBossInstanceInfo(bossInstance, roleId);
}
}
return null;
case 'wishPool':
return hasGuild? await getWishPool(userGuild): null;
case 'task':
return await getCurTask(role.roleId, session);
case 'chat':
const worldMsgs = await recentWorldMsgs(serverId);
const sysMsgs = await recentSysMsgs(serverId);
const guildMsgs = await recentGuildMsgs(guildCode);
const recentPrivateChats = await recentPrivateChatInfos(roleId, roleName);
return { worldMsgs, sysMsgs, guildMsgs, recentPrivateChats };
case 'event':
return await getEvent(role.eventStatus, roleId, roleName);
case 'battle':
return await getBattleListOfMain(role);
default:
return null;
}
}
function pushEntryData<T>(type: string, roleId: string, sid: string, param: T) {
let uids = [{ uid: roleId, sid }];
let data = { type };
@@ -185,3 +198,24 @@ async function getGuildEntryData(role: RoleType, sid: string, session: FrontendO
}
return { hasGuild: false }
}
export async function everydayRefresh() {
let allOnlineUsers = await getAllOnlineRoles();
let todayZeroPoint = getZeroPoint();
let n = Math.ceil(allOnlineUsers.length / PUSH_BATCH); // 一共多少批
console.log(n)
let i = -1;
let interval = setInterval(() => {
if(++i < n) {
let users = allOnlineUsers.slice(i * PUSH_BATCH, (i + 1) * PUSH_BATCH - 1);
for(let { roleId, sid } of users) {
pinus.app.channelService.pushMessageByUids('onRefreshTime', resResult(STATUS.SUCCESS, {
todayZeroPoint
} ), [{uid: roleId, sid: sid}]);
}
} else {
clearInterval(interval);
}
}, PUSH_INTERVAL)
setMedianCe();
}

View File

@@ -26,6 +26,7 @@ import { GuildModel } from '../db/Guild';
import { dispatch } from '../util/dispatcher';
import { Rank } from './rankService';
import { checkTask } from './taskService';
import { everydayRefresh } from './connectorService';
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
@@ -75,12 +76,13 @@ export async function init() {
// 军团活动排行榜
guildActivitySchedule();
// 每天0点计算前一天活跃玩家中位数战力
scheduleJob('setMedian', '0 0 5 * * ?', setMedianCe);
// 拍卖行刷新:拍卖阶段刷新,分红发放
auctionSchedule();
// 每天5点推送刷新时间消息
// 顺便每天0点计算前一天活跃玩家中位数战力
scheduleJob('everyDayRefresh', `0 0 ${REFRESH_TIME} * * ?`, everydayRefresh);
}
function setPvpSeasonSchdule() {

View File

@@ -17,6 +17,8 @@ export const GUEST_MAX_TIME = 60 * 60; // 游客体验时间
export const GUEST_DAY = 15; // 同一设备15天内不得重复体验游客模式
export const REFRESH_TIME = 5; // 统一一天刷新时间
export const PUSH_BATCH = 100; // 推送分批人数
export const PUSH_INTERVAL = 5 * 1000; // 分批时间5秒一批
export enum TIME_OUTPUT_TYPE {
DATE = 1,
STAMP_10 = 2,

View File

@@ -1,5 +1,5 @@
import moment = require('moment');
import { ACTIVITY_RESOURCES_TYPE, ACTIVITY_TYPE, SERVER_OPEN_TIME, SIGNIN_CLOSE, SIGNIN_OPEN } from '../../consts';
import { ACTIVITY_TYPE, SERVER_OPEN_TIME, SIGNIN_CLOSE, SIGNIN_OPEN } from '../../consts';
import { ActivityModelType } from '../../db/Activity';
import { ActivitySignInModelType } from '../../db/ActivitySignIn';
import { deltaDays } from '../../pubUtils/util';

View File

@@ -1,5 +1,3 @@
import moment = require('moment');
import { random } from 'underscore';
import { ActivityModelType } from '../../db/Activity';
import { ActivityVipRechargeMoneyModelType } from '../../db/ActivityVipRechargeMoney';
import { ActivityBase } from './activityField';