380 lines
15 KiB
TypeScript
380 lines
15 KiB
TypeScript
import Marquee, { MarqueeType, MarqueeModel } from "../db/Marquee";
|
|
import { ACTIVITY_TYPE, GM_MAIL_STATUS, GM_MAIL_TYPE, MAIL_TIME_TYPE, MARQUEE_SHOW_TYPE, MARQUEE_TIME_TYPE, REF_CIRCLE_MAIL_TIME, SERVER_STATUS, SURVEY_SELECT } from "../consts";
|
|
import { scheduleJob, scheduledJobs, Job } from 'node-schedule';
|
|
import { createMarqueeMsg as sysCreateMarqueeMsg, pushMarqueeMsg as sysPushMarqueeMsg } from './sysChatService';
|
|
import { GroupMessageType } from "../db/GroupMessage";
|
|
import { pinus } from "pinus";
|
|
import { getWorldChannelSid } from "./chatChannelService";
|
|
import { ServerlistModel, ServerlistType } from "../db/Serverlist";
|
|
import { NoticeModel, NoticeType } from "../db/Notice";
|
|
import { SendMailFun } from "./mailService";
|
|
import GMMail, { GMMailModel, GMMailType } from '../db/GMMail';
|
|
import moment = require("moment");
|
|
import { getSeconds, nowSeconds } from "../pubUtils/timeUtil";
|
|
import { CreateServerParam } from "../domain/backEndField/params";
|
|
import { SignInData } from "../domain/activityField/signInField";
|
|
import { RegionModel, RegionType } from "../db/Region";
|
|
import { GMMail as StategyMail } from "../db/ServerStategy";
|
|
import { uniq } from "underscore";
|
|
import { ActivityModel, ActivityModelType } from "../db/Activity";
|
|
import { dicRMB } from "../pubUtils/dictionary/DicRMB";
|
|
import { LimitShopData } from "../domain/activityField/limitShopField";
|
|
import { YuanBaoShopData } from "../domain/activityField/yuanBaoShopField";
|
|
import { MonthlyTicketData } from "../domain/activityField/monthlyTicketField";
|
|
import { DailyRMBGiftsData } from "../domain/activityField/dailyRMBGiftsField";
|
|
import { PopShopItem, PopUpShopData, PopUpShopPackage } from "../domain/activityField/popUpShopField";
|
|
import { GrowthFundData } from "../domain/activityField/growthFundField";
|
|
import { TreasureHuntData } from "../domain/activityField/treasureHuntField";
|
|
import { RefreshShopData } from "../domain/activityField/refreshShopField";
|
|
import { RoleType } from "../db/Role";
|
|
import { MonopolyData } from "../domain/activityField/monopolyField";
|
|
import { ActivityPopUpShopModel, ActivityPopUpShopModelType, PopUpShopItem } from "../db/ActivityPopUpShop";
|
|
import { getActivitiesByType } from "./activity/activityService";
|
|
import { SurveyModel } from "../db/Survery";
|
|
import { SurveyRecModel } from "../db/SurveyRec";
|
|
import { getPopUpShopData } from "./activity/popUpShopService";
|
|
import { TaskPassData } from "../domain/activityField/taskPassField";
|
|
|
|
// —————————————— 跑马灯 —————————————— //
|
|
// 初始
|
|
export async function initMarquee() {
|
|
const marquees = await MarqueeModel.findEffectiveMarque(pinus.app.get('env'));
|
|
for(let marquee of marquees) {
|
|
await generateMarqueeSchedule(marquee);
|
|
}
|
|
}
|
|
|
|
export async function setMarquee(marquee: MarqueeType) {
|
|
console.log('******', marquee.timeType, marquee)
|
|
if(marquee.timeType == MARQUEE_TIME_TYPE.INSTANT) {
|
|
await startMarquee(marquee);
|
|
return true;
|
|
} else {
|
|
return await generateMarqueeSchedule(marquee);
|
|
}
|
|
}
|
|
|
|
async function generateMarqueeSchedule(marquee: MarqueeType) {
|
|
// 定时发送
|
|
let setSecondsMarquee = scheduledJobs[`setSeconds${marquee.code}`];
|
|
if(setSecondsMarquee) return false; // 已经在运行中了
|
|
|
|
if(marquee.timeType != MARQUEE_TIME_TYPE.SCHEDULE) return false;
|
|
if(marquee.endTime && marquee.endTime < nowSeconds()) return false;
|
|
if(marquee.startTime > nowSeconds()) {
|
|
let startJob = scheduleJob(`start${marquee.code}`, marquee.startTime * 1000, async () => {
|
|
await startMarquee(marquee, startJob)
|
|
});
|
|
} else {
|
|
await startMarquee(marquee)
|
|
}
|
|
return true;
|
|
}
|
|
|
|
async function startMarquee(marquee: MarqueeType, startJob?: Job) {
|
|
console.log('************', `跑马灯定时器 ${marquee.code}开始`, '************');
|
|
let msgDatas = await createMarqueeMsg(marquee);
|
|
if(marquee.showType == MARQUEE_SHOW_TYPE.ONCE) { // 一次性发送
|
|
await pushMarqueeMsg(msgDatas);
|
|
if(startJob) {
|
|
startJob.cancel();
|
|
startJob = undefined;
|
|
}
|
|
} else {
|
|
if(marquee.endTime > nowSeconds()) {
|
|
await pushMarqueeMsg(msgDatas);
|
|
console.log('***', marquee.interval)
|
|
let secondsJob = scheduleJob(`setSeconds${marquee.code}`, `*/${marquee.interval} * * * * *`, async () => {
|
|
console.log(`*****setSeconds${marquee.code}****`)
|
|
await pushMarqueeMsg(msgDatas);
|
|
});
|
|
let endJob = scheduleJob(`end${marquee.code}`, marquee.endTime * 1000, async () => {
|
|
if(startJob) {
|
|
startJob.cancel();
|
|
startJob = undefined;
|
|
}
|
|
if(secondsJob) {
|
|
secondsJob.cancel();
|
|
secondsJob = undefined;
|
|
}
|
|
if(endJob) {
|
|
endJob.cancel();
|
|
endJob = undefined;
|
|
}
|
|
});
|
|
} else {
|
|
if(startJob) {
|
|
startJob.cancel();
|
|
startJob = undefined;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async function createMarqueeMsg(marquee: MarqueeType) {
|
|
let { receivers, content } = marquee;
|
|
let msgDatas: GroupMessageType[] = [];
|
|
let serverIds: number[] = [];
|
|
for(let { env, serverId } of receivers) {
|
|
if(serverId == 0) {
|
|
let servers = await ServerlistModel.findByEnv(env);
|
|
for(let { serverId } of servers) {
|
|
serverIds.push(serverId);
|
|
}
|
|
} else {
|
|
serverIds.push(serverId);
|
|
}
|
|
}
|
|
for(let serverId of uniq(serverIds)) {
|
|
let msgData = await sysCreateMarqueeMsg('', '系统', serverId, content);
|
|
msgDatas.push(msgData);
|
|
}
|
|
|
|
return msgDatas;
|
|
}
|
|
|
|
async function pushMarqueeMsg(msgDatas: GroupMessageType[]) {
|
|
for(let msgData of msgDatas) {
|
|
await sysPushMarqueeMsg(msgData);
|
|
}
|
|
}
|
|
|
|
export async function cancelMarquee(code: string) {
|
|
let startMarquee = scheduledJobs[`start${code}`];
|
|
let setSecondsMarquee = scheduledJobs[`setSeconds${code}`];
|
|
let endMarquee = scheduledJobs[`end${code}`];
|
|
if(startMarquee) startMarquee.cancel();
|
|
if(setSecondsMarquee) setSecondsMarquee.cancel();
|
|
if(endMarquee) endMarquee.cancel();
|
|
return true
|
|
}
|
|
|
|
export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: StategyMail, newServer: ServerlistType, uid: number) {
|
|
let addParam = new GMMail();
|
|
addParam.setByRegionStategy(type, mail, newServer, uid);
|
|
let gmmail = await GMMailModel.addMail(addParam, uid);
|
|
let needSend = false;
|
|
if(mail.timeType == MAIL_TIME_TYPE.CIRCLE) {
|
|
let refTimeStr = REF_CIRCLE_MAIL_TIME >= 10? `${REF_CIRCLE_MAIL_TIME}`: `0${REF_CIRCLE_MAIL_TIME}`;
|
|
let refTime = moment(moment().format(`YYYY-MM-DD ${refTimeStr}:00:00`)).unix();
|
|
let sendTime = moment(moment().format('YYYY-MM-DD '+ mail.circleHour)).unix();
|
|
if(sendTime < refTime) sendTime += 86400;
|
|
let now = nowSeconds();
|
|
if(refTime < now && sendTime > now) {
|
|
needSend = true;
|
|
}
|
|
} else {
|
|
needSend = true;
|
|
}
|
|
if(needSend) {
|
|
let f = new SendMailFun();
|
|
let code = await f.setWithGmMail(gmmail);
|
|
await f.createServerMails(code, [newServer.id]);
|
|
await f.pushToUsers();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
export function setServerMainten(serverIds: number[], startTime: number, endTime: number) {
|
|
let maintenServers = pinus.app.get('maintenServers')||new Map();
|
|
for(let id of serverIds) {
|
|
if(!maintenServers.has(id)) {
|
|
maintenServers.set(id, { startTime, endTime });
|
|
} else {
|
|
maintenServers.get(id).startTime = startTime;
|
|
maintenServers.get(id).endTime = endTime;
|
|
}
|
|
}
|
|
pinus.app.set('maintenServers', maintenServers);
|
|
}
|
|
|
|
export function stopServerMainten(serverIds: number[]) {
|
|
let maintenServers = pinus.app.get('maintenServers')||new Map();
|
|
for(let id of serverIds) {
|
|
if(maintenServers.has(id)) {
|
|
maintenServers.delete(id);
|
|
}
|
|
}
|
|
pinus.app.set('maintenServers', maintenServers);
|
|
}
|
|
|
|
export function getServerMainten(serverId: number) {
|
|
let maintenServers = pinus.app.get('maintenServers')||new Map();
|
|
return maintenServers.get(serverId);
|
|
}
|
|
|
|
export async function createNewServer(region: RegionType ,serverId: number, params: CreateServerParam, uid?: number) {
|
|
let newServer = await ServerlistModel.newServer(params, region, serverId, uid);
|
|
if(params.openMail) await sendOpenServerMail('openMail', params.openMail, newServer, uid);
|
|
if(params.circleMail) await sendOpenServerMail('circleMail', params.circleMail, newServer, uid);
|
|
await RegionModel.newServer(region.id, newServer);
|
|
}
|
|
|
|
function getDicRMB(productID: string) {
|
|
let dic = dicRMB.get(productID);
|
|
if(!dic) return null
|
|
return {
|
|
value: dic.productID,
|
|
label: `${dic.message}(${dic.productID})`,
|
|
}
|
|
};
|
|
|
|
export function getActivityProducts(activity: ActivityModelType) {
|
|
switch(activity.type) {
|
|
case ACTIVITY_TYPE.SIGN_IN_VIP: // 高级签到
|
|
{
|
|
let data = new SignInData(activity, 0, 0);
|
|
return [getDicRMB(data.productID)];
|
|
}
|
|
case ACTIVITY_TYPE.NEW_PLAYER_LIMIT_PACKAGE: // 新手限定RMB购买礼包
|
|
case ACTIVITY_TYPE.LIMIT_PACKAGE_SHOP_DAILY: // 日限购
|
|
case ACTIVITY_TYPE.LIMIT_PACKAGE_SHOP_WEEKLY: // 周限购
|
|
{
|
|
let data = new LimitShopData(activity, 0, 0);
|
|
return data.list.map(item => {
|
|
return getDicRMB(item.productID);
|
|
});
|
|
}
|
|
case ACTIVITY_TYPE.YUAN_BAO_SHOP: // 元宝
|
|
{
|
|
let data = new YuanBaoShopData(activity, 0, 0);
|
|
return data.list.map(item => {
|
|
return getDicRMB(item.productID);
|
|
});
|
|
}
|
|
case ACTIVITY_TYPE.MONTHLY_TICKET_1:
|
|
case ACTIVITY_TYPE.MONTHLY_TICKET_2:
|
|
{
|
|
let data = new MonthlyTicketData(activity, 0, 0);
|
|
return [getDicRMB(data.productID)];
|
|
}
|
|
case ACTIVITY_TYPE.DAILY_RMB_GIFTS:
|
|
{
|
|
let data = new DailyRMBGiftsData(activity, 0, 0);
|
|
return [getDicRMB(data.productID)];
|
|
}
|
|
case ACTIVITY_TYPE.POP_UP_SHOP://弹出礼包
|
|
{
|
|
let products: { label: string, value: string }[] = [];
|
|
let data = new PopUpShopData(activity);
|
|
for(let { items } of data.packages) {
|
|
for(let item of items) {
|
|
products.push(getDicRMB(item.productID));
|
|
}
|
|
}
|
|
return products;
|
|
}
|
|
case ACTIVITY_TYPE.GROWTH_FUND_MAIN_VIP: //主线成长基金(高阶)
|
|
case ACTIVITY_TYPE.GROWTH_FUND_TOWER_VIP://镇念塔成长基金(高阶)
|
|
case ACTIVITY_TYPE.GROWTH_FUND_MAIN_ELITE_VIP://精英成长基金(高阶)
|
|
{
|
|
let data = new GrowthFundData(activity, 0, 0);
|
|
return data.list.map(item => {
|
|
return getDicRMB(item.productID);
|
|
});
|
|
}
|
|
case ACTIVITY_TYPE.TREASURE_HUNT:
|
|
{
|
|
let data = new TreasureHuntData(activity, 0, 0);
|
|
let shop = data.shop;
|
|
return shop.list.map(item => {
|
|
return getDicRMB(item.productID);
|
|
});
|
|
}
|
|
case ACTIVITY_TYPE.REFRESH_SHOP:
|
|
{
|
|
let data = new RefreshShopData(activity, 0, 0);
|
|
let products: { label: string, value: string }[] = [];
|
|
for(let shop of data.list) {
|
|
for(let item of shop.items) {
|
|
products.push(getDicRMB(item.productID));
|
|
}
|
|
}
|
|
return products;
|
|
}
|
|
case ACTIVITY_TYPE.TASK_PASS:
|
|
{
|
|
let data = new TaskPassData(activity, 0, 0);
|
|
let products: { label: string, value: string }[] = [];
|
|
for(let reward of data.rewards) {
|
|
products.push(getDicRMB(reward.productID));
|
|
}
|
|
return products;
|
|
}
|
|
|
|
}
|
|
return false
|
|
}
|
|
|
|
export async function getParamStr(activity: ActivityModelType, productID: string, role: RoleType) {
|
|
let param = {};
|
|
switch(activity.type) {
|
|
case ACTIVITY_TYPE.POP_UP_SHOP:
|
|
const roleId = role.roleId;
|
|
let serverId = role.serverId;
|
|
let playerData = await getPopUpShopData(activity.activityId, serverId, roleId, role);
|
|
let item: PopShopItem, pkg: PopUpShopPackage;
|
|
for(let _pkg of playerData.packages) {
|
|
let _item = _pkg.findItemByProductID(productID);
|
|
if(_item) {
|
|
pkg = _pkg; item = _item;
|
|
}
|
|
}
|
|
console.log('&&&&&', item)
|
|
if(item.isPushing) {
|
|
param['code'] = item.code;
|
|
} else {
|
|
let popUpShopRec = await ActivityPopUpShopModel.createRecord({
|
|
serverId, activityId: activity.activityId, roleId, id: pkg.id,
|
|
...pkg.getEffectTime(),
|
|
items: pkg.items.map(item => new PopUpShopItem(item))
|
|
});
|
|
param['code'] = popUpShopRec.code;
|
|
}
|
|
|
|
|
|
// let playerRecords = await ActivityPopUpShopModel.findAllOpenData(role.serverId, activity.activityId, role.roleId);
|
|
// let playerRecord: ActivityPopUpShopModelType;
|
|
// for(let record of playerRecords) {
|
|
// let playerData = new PopUpShopData(task, activity.activityId);
|
|
// playerData.setPlayerRecords(record);
|
|
// if (record && playerData.buyCount < task.count) {
|
|
// playerRecord = record; break;
|
|
// }
|
|
// }
|
|
// console.log('####', playerRecord, task)
|
|
// if(!playerRecord) {
|
|
// let beginTime = new Date();
|
|
// let endTime = moment(new Date()).add(task.duration, 'h').toDate();
|
|
// playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(role.serverId, activity.activityId, role.roleId, task.id, task.taskType, task.condition, beginTime, endTime);
|
|
// }
|
|
|
|
// param['beginTimeStamp'] = playerRecord.beginTime.getTime();
|
|
break;
|
|
case ACTIVITY_TYPE.REFRESH_SHOP:
|
|
let monopolyActivitys = await getActivitiesByType(role.serverId, ACTIVITY_TYPE.MONOPOLY);
|
|
let parentActivity = monopolyActivitys.find(activity => {
|
|
let data = new MonopolyData(activity, 0, 0);
|
|
let curShop = data.list.find(land => { // 找到关联活动
|
|
return land.shopActivityId == activity.activityId;
|
|
});
|
|
return !!curShop;
|
|
});
|
|
|
|
if(parentActivity) {
|
|
param['monopolyActivityId'] = parentActivity.activityId;
|
|
}
|
|
break;
|
|
}
|
|
return JSON.stringify(param);
|
|
}
|
|
|
|
|
|
export async function getSurvey(roleId: string, lv: number) {
|
|
let surveys = await SurveyModel.findEnableSurvey(lv, SURVEY_SELECT.FIND);
|
|
let recs = await SurveyRecModel.findByRole(roleId);
|
|
return surveys.filter(survey => {
|
|
let index = recs.findIndex(rec => rec.surveyId == survey.surveyId);
|
|
return index == -1
|
|
});
|
|
} |