拍卖行:定时刷新、结算和简单测试,个别bug修复

This commit is contained in:
liangtongchuan
2021-03-19 15:23:56 +08:00
parent f7c665f206
commit 7324556852
8 changed files with 186 additions and 11 deletions

View File

@@ -5,7 +5,7 @@ import { AUCTION_STAGE, DEBUG_MAGIC_WORD, STATUS, OFFER_RATIO, CURRENCY_BY_TYPE,
import { LotModel } from "../../../db/Lot";
import { ItemReward } from "../../../domain/dbGeneral";
import { resResult } from "../../../pubUtils/util";
import { auctionStage, calculateDividend, genAuction, todayGuildBegin } from "../../../services/auctionService";
import { auctionStage, calculateDividend, genAuction, sendUngotDividend, startGuildAuction, startWorldAuction, stopAuction, todayGuildBegin } from "../../../services/auctionService";
import { addItems, handleCost } from '../../../services/rewardService';
import { getSimpleRoleInfo } from '../../../services/roleService';
import { getRoleOnlineInfo } from '../../../services/redisService';
@@ -143,7 +143,8 @@ export class AuctionHandler {
const serverId = session.get('serverId');
const begin = todayGuildBegin();
const lots = await LotModel.watchingLotsByBegin(serverId, roleId, begin);
return resResult(STATUS.SUCCESS, { lots });
const stage = auctionStage();
return resResult(STATUS.SUCCESS, { lots: stage === AUCTION_STAGE.END ? [] : lots });
}
async offerRecs(msg: { count: number }, session: BackendSession) {
@@ -199,4 +200,40 @@ export class AuctionHandler {
return resResult(STATUS.SUCCESS, result);
}
// ! 测试接口
async debugScheduleStartGuild(msg: { magicWord: string }, session: BackendSession) {
const result = await startGuildAuction();
if (result === true) {
return resResult(STATUS.SUCCESS);
}
return resResult(STATUS.INTERNAL_ERR);
}
// ! 测试接口
async debugScheduleStartWorld(msg: { magicWord: string }, session: BackendSession) {
const result = await startWorldAuction();
if (result === true) {
return resResult(STATUS.SUCCESS);
}
return resResult(STATUS.INTERNAL_ERR);
}
// ! 测试接口
async debugScheduleStopAuction(msg: { magicWord: string }, session: BackendSession) {
const result = await stopAuction();
if (result === true) {
return resResult(STATUS.SUCCESS);
}
return resResult(STATUS.INTERNAL_ERR);
}
// ! 测试接口
async debugScheduleSendUngotDividend(msg: { magicWord: string }, session: BackendSession) {
const result = await sendUngotDividend();
if (result === true) {
return resResult(STATUS.SUCCESS);
}
return resResult(STATUS.INTERNAL_ERR);
}
}

View File

@@ -1,13 +1,16 @@
import { DIVIDENDWEEKENDRATE, DIVIDENDMAXRATIO, DIVIDENDPOSITIONMAXRATIO } from './../consts/constModules/auctionConst';
import { MailModel, MailType } from './../db/Mail';
import { DividendModel } from './../db/Dividend';
import { LOT_CODE_LEN, AUCTION_STAGE, AUCTION_TIME, DIVIDEND_CODE_LEN, DIVIDEND_STATUS, LOT_STATUS } from './../consts';
import { LOT_CODE_LEN, AUCTION_STAGE, AUCTION_TIME, DIVIDEND_CODE_LEN, DIVIDEND_STATUS, LOT_STATUS, MAIL_TYPE, CURRENCY_BY_TYPE, CURRENCY_TYPE, STATUS, DIVIDENDWEEKENDRATE, DIVIDENDMAXRATIO, DIVIDENDPOSITIONMAXRATIO, ROLE_RECEIVE_STATUS } from './../consts';
import { DividendRec, ItemReward } from "../domain/dbGeneral";
import { genCode } from '../pubUtils/util';
import { genCode, resResult } from '../pubUtils/util';
import { LotModel, LotParam } from '../db/Lot';
import { getNextTime, getTodayZeroDate } from '../pubUtils/timeUtil';
import { getNextTime, getTodayZeroDate, getZeroDateByDeltaDay } from '../pubUtils/timeUtil';
import { gameData, getGoodById } from '../pubUtils/data';
import { DividendParam, DividendType } from '../db/Dividend';
import { RolePosition } from '../domain/battleField/guild';
import { pushMail } from '../pubUtils/interface';
import { getMailContent } from './mailService';
import { pinus } from 'pinus';
// ! 获取底价,假数据
function getBasePrice(gid: number, count: number) {
@@ -41,6 +44,10 @@ export function todayGuildBegin() {
return getNextTime(getTodayZeroDate(), AUCTION_TIME.GUILD_BEGIN_HOUR, AUCTION_TIME.GUILD_BEGIN_MIN);
}
export function yestodayGuildBegin() {
return getNextTime(getZeroDateByDeltaDay(-1), AUCTION_TIME.GUILD_BEGIN_HOUR, AUCTION_TIME.GUILD_BEGIN_MIN);
}
export function todayWorldBegin() {
return getNextTime(getTodayZeroDate(), AUCTION_TIME.WORLD_BEGIN_HOUR, AUCTION_TIME.WORLD_BEGIN_MIN);
}
@@ -147,3 +154,73 @@ export async function calculateDividend(dividend: DividendType) {
});
return await DividendModel.updateDividend(code, { dividends });
}
export async function startGuildAuction() {
try {
console.log('schedule startGuildAuction called:', new Date());
const begin = todayGuildBegin();
await LotModel.updateLotsStageByBegin(begin, AUCTION_STAGE.GUILD);
await DividendModel.updateDividendsStatus(begin, DIVIDEND_STATUS.ING);
return true;
} catch (e) {
console.error('startGuildAuction err: ', e);
return false;
}
}
export async function startWorldAuction() {
try {
console.log('schedule startWorldAuction called:', new Date());
const begin = todayGuildBegin();
await LotModel.updateLotsStageByBegin(begin, AUCTION_STAGE.WORLD);
return true;
} catch (e) {
console.error('startWorldAuction err: ', e);
return false;
}
}
export async function stopAuction() {
try {
console.log('schedule stopAuction called:', new Date());
const begin = todayGuildBegin();
await LotModel.updateLotsStageByBegin(begin, AUCTION_STAGE.END);
await DividendModel.updateDividendsStatus(begin, DIVIDEND_STATUS.END);
return true;
} catch (e) {
console.error('stopAuction err: ', e);
return false;
}
}
export async function sendUngotDividend() {
try {
console.log('schedule sendUngotDividend called:', new Date());
const begin = yestodayGuildBegin();
const dividends = await DividendModel.findDividendsByBegin(begin);
const rewards = new Map<string, number>();
for (let dividend of dividends) {
if (!dividend.dividends) continue;
for (let dividendRec of dividend.dividends) {
if (dividendRec.status === ROLE_RECEIVE_STATUS.YES) continue;
const sum = rewards.get(dividendRec.roleId) || 0;
rewards.set(dividendRec.roleId, sum + dividendRec.total);
}
}
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 MailModel.addMails(mails);
pushMessage.forEach(({route, data, uids })=>{
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails: data }), uids);
});
return true;
} catch (e) {
console.error('sendUngotDividend err: ', e);
return false;
}
}

View File

@@ -21,6 +21,7 @@ import { getMailContent, sendMail } from './mailService';
import { reportOnline } from '../pubUtils/httpUtil';
import User, { UserModel } from '../db/User';
import { getGuildActivityByDic, getGuildActivityRank } from './guildActivityService';
import { sendUngotDividend, startGuildAuction, startWorldAuction, stopAuction } from './auctionService';
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
const SETTLE_DIFF = 29 * 60;
@@ -68,6 +69,8 @@ export async function init() {
scheduleJob('reportOnline', '0 0/5 * * * *', reportOnlineSchedule);
guildActivitySchedule();
// 拍卖行刷新:拍卖阶段刷新,分红发放
auctionSchedule();
}
function setPvpSeasonSchdule() {
@@ -389,4 +392,11 @@ export async function guildActivitySeconds() {
for(let { id } of servers) {
await pinus.app.rpc.guild.guildActivityRemote.sendRankToGuilds.toServer(id);
}
}
}
function auctionSchedule() {
scheduleJob('startGuildAuction', '0 0 20 20 * ?', startGuildAuction);
scheduleJob('startWorldAuction', '0 0 20 30 * ?', startWorldAuction);
scheduleJob('stopAuction', '0 0 22 00 * ?', stopAuction);
scheduleJob('sendUngotDividend', '0 0 5 00 * ?', sendUngotDividend);
}

View File

@@ -198,7 +198,7 @@ describe('拍卖行测试', function() {
expect(info.id).to.be.equal(CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD));
}
});
pinusClient.request('battle.auctionHandler.debugSetDividendStatus', { magicWord: DEBUG_MAGIC_WORD, sourceType: AUCTION_SOURCE.GATE, status: DIVIDEND_STATUS.ING }, (res) => {
pinusClient.request('battle.auctionHandler.debugSetDividendStatus', { magicWord: DEBUG_MAGIC_WORD, sourceType: AUCTION_SOURCE.GATE, status: DIVIDEND_STATUS.END }, (res) => {
checkSuccessResponse(res);
checkDividend(res.data.dividend);
pinusClient.request('battle.auctionHandler.getDividend', { sourceType: AUCTION_SOURCE.GATE }, (res) => {
@@ -277,4 +277,32 @@ describe('拍卖行测试', function() {
done();
});
});
it('测试接口,军团拍卖定时', function(done) {
pinusClient.request('battle.auctionHandler.debugScheduleStartGuild', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
checkSuccessResponse(res, false);
done();
});
});
it('测试接口,世界拍卖定时', function(done) {
pinusClient.request('battle.auctionHandler.debugScheduleStartWorld', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
checkSuccessResponse(res, false);
done();
});
});
it('测试接口,拍卖结束定时', function(done) {
pinusClient.request('battle.auctionHandler.debugScheduleStopAuction', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
checkSuccessResponse(res, false);
done();
});
});
it('测试接口,结算分红定时', function(done) {
pinusClient.request('battle.auctionHandler.debugScheduleSendUngotDividend', { magicWord: DEBUG_MAGIC_WORD }, (res) => {
checkSuccessResponse(res, false);
done();
});
});
});

View File

@@ -380,7 +380,8 @@ export const MAIL_TYPE = {
GUILD_TRAIN_REWARD: 10,
WISH_POOL_REWARD: 11,
PVP_RESULT: 12,
PVP_RANK_REWARD: 13
PVP_RANK_REWARD: 13,
GUILD_DIVIDEND: 14, // 拍卖行分红
};
export const CHAT_SERVER = 'chat-server-1';

View File

@@ -56,6 +56,11 @@ export default class Dividend extends BaseModel {
return results;
}
public static async findDividendsByBegin(begin: Date) {
const results = await DividendModel.find({ begin }).select('-_id -__v').lean();
return results;
}
public static async updateDividend(code: string, update: DividendParam) {
const result = await DividendModel.findOneAndUpdate({ code }, { ...update }, { new: true }).select('-_id -__v').lean();
return result;
@@ -67,12 +72,12 @@ export default class Dividend extends BaseModel {
}
public static async findReadyDividend(guildCode: string, sourceType: number) {
const result: DividendType = await DividendModel.findOne({ guildCode, sourceType, status: DIVIDEND_STATUS.ING }).select('-_id -__v').lean();
const result: DividendType = await DividendModel.findOne({ guildCode, sourceType, status: DIVIDEND_STATUS.END }).select('-_id -__v').lean();
return result;
}
public static async updateReceiveStatus(code: string, roleId: string) {
const result: DividendType = await DividendModel.findOneAndUpdate({ code, status: DIVIDEND_STATUS.END, 'lots.roleId': roleId }, { 'lots.status': ROLE_RECEIVE_STATUS.YES }, { new: true }).select('-_id -__v').lean();
const result: DividendType = await DividendModel.findOneAndUpdate({ code, status: DIVIDEND_STATUS.END, 'lodividendsts.roleId': roleId }, { 'dividends.$.status': ROLE_RECEIVE_STATUS.YES }, { new: true }).select('-_id -__v').lean();
return result;
}
@@ -80,6 +85,10 @@ export default class Dividend extends BaseModel {
const result: DividendType = await DividendModel.findOneAndUpdate({ guildCode, sourceType }, { status }, { new: true }).select('-_id -__v').lean();
return result;
}
public static async updateDividendsStatus(begin: Date, status: number) {
await DividendModel.updateMany({ begin }, { status });
}
}
export const DividendModel = getModelForClass(Dividend);

View File

@@ -107,6 +107,11 @@ export default class Lot extends BaseModel {
const result: LotType = await LotModel.findOneAndUpdate({ code }, { auctionStage }).select('-_id -__v').lean();
return result;
}
public static async updateLotsStageByBegin(begin: Date, auctionStage: number) {
const results = await LotModel.updateMany({ begin }, { auctionStage }).select('-_id -__v').lean();
return results;
}
}
export const LotModel = getModelForClass(Lot);

View File

@@ -112,6 +112,14 @@ export function getTodayZeroDate() {
return date;
}
export function getZeroDateByDeltaDay(delta: number) {
var date = new Date(new Date().getTime() + delta * PER_DAY * PER_SECOND);
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
return date;
}
export function getAge(birthday: string) {
let d = new Date(birthday + ' 00:00:00');
let _year = d.getFullYear();