import { DividendModel } from './../../../db/Dividend'; import { Application, BackendSession, ChannelService } from "pinus"; import { AUCTION_STAGE, DEBUG_MAGIC_WORD, STATUS, OFFER_RATIO, CURRENCY_BY_TYPE, CURRENCY_TYPE, DATA_NAME, LOT_STATUS } from "../../../consts"; import { LotModel } from "../../../db/Lot"; import { ItemReward } from "../../../domain/dbGeneral"; import { resResult } from "../../../pubUtils/util"; import { auctionStage, calculateDividend, genAuction, todayGuildBegin } from "../../../services/auctionService"; import { addItems, handleCost } from '../../../services/rewardService'; import { getSimpleRoleInfo } from '../../../services/roleService'; import { getRoleOnlineInfo } from '../../../services/redisService'; import { lockData } from '../../../services/redLockService'; export default function (app: Application) { return new AuctionHandler(app); } export class AuctionHandler { channelService: ChannelService; constructor(private app: Application) { this.channelService = app.get('channelService'); } async getAuction(msg: {}, session: BackendSession) { const guildCode = session.get('guildCode'); const serverId = session.get('serverId'); if (!guildCode) return resResult(STATUS.GUILD_NOT_FOUND); const begin = todayGuildBegin(); const stage = auctionStage(); let lots = []; if (stage === AUCTION_STAGE.DEFAULT || stage === AUCTION_STAGE.GUILD) { lots = await LotModel.findGuildLotsByBegin(guildCode, begin); } else if (stage === AUCTION_STAGE.WORLD) { lots = await LotModel.findWorldLotsByBegin(serverId, begin); } const dividends = await DividendModel.findGuildDividendsByBegin(guildCode, begin); return resResult(STATUS.SUCCESS, { lots, dividends }); } async offer(msg: { code: string, max: boolean }, session: BackendSession) { const { code, max } = msg; const roleId = session.get('roleId'); const roleName = session.get('roleName'); const sid = session.get('sid'); const serverId = session.get('serverId'); let res: any = await lockData(serverId, DATA_NAME.AUCTION_LOT, code);// 加锁 try { if (!res) { return resResult(STATUS.REDLOCK_ERR); } const lot = await LotModel.findLot(code); if (!lot || lot.status === LOT_STATUS.SOLD) { res.releaseCallback(); return resResult(STATUS.GUILD_LOT_NOT_FOUND); } const { curBuyer, curPrice, maxPrice, gid, count, bidRoles, watchingRoles } = lot; if (curBuyer === roleId) { res.releaseCallback(); return resResult(STATUS.LOT_OFFER_SERIAL); } let newPrice = parseInt((curPrice * OFFER_RATIO).toFixed(0)); let maxFlag = max; if (newPrice >= maxPrice) { newPrice = maxPrice; maxFlag = true; } const costRes = await handleCost(roleId, sid, [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count: newPrice }]); if (!costRes) { res.releaseCallback(); return resResult(STATUS.ROLE_COIN_NOT_ENOUGH); } if (curBuyer) { const { roleName: buyerName } = await getSimpleRoleInfo(curBuyer); const { sid: buyerSid } = await getRoleOnlineInfo(buyerName); await addItems(curBuyer, buyerName, buyerSid, [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count: curPrice }]); } // TODO 元宝返还纪录 if (maxFlag) { newPrice = maxPrice; await addItems(roleId, roleName, sid, [{ id: gid, count }]); } bidRoles.push({roleId, price: newPrice, time: new Date()}); const newLot = await LotModel.updateLot({ code, curBuyer: roleId, curPrice: newPrice, bidRoles, status: maxFlag ? LOT_STATUS.SOLD : LOT_STATUS.ING, watchingRoles: Array.from(new Set([...watchingRoles, roleId])) }); res.releaseCallback(); const incPrice = newPrice - (curBuyer ? curPrice : 0); const dividend = await DividendModel.updateLot(code, gid, newPrice, incPrice); const newDividend = await calculateDividend(dividend); return resResult(STATUS.SUCCESS, { lot: newLot, dividend: newDividend }); } catch (e) { console.log('offer got err:', e); res.releaseCallback(); return resResult(STATUS.INTERNAL_ERR); } } async watchLot(msg: { code: string }, session: BackendSession) { const roleId = session.get('roleId'); const { code } = msg; const lot = await LotModel.watchLot(code, roleId); if (!lot) return resResult(STATUS.WRONG_PARMS); return resResult(STATUS.SUCCESS, { lot }); } async unWatchLot(msg: { code: string }, session: BackendSession) { const roleId = session.get('roleId'); const { code } = msg; const lot = await LotModel.unWatchLot(code, roleId); if (!lot) return resResult(STATUS.WRONG_PARMS); return resResult(STATUS.SUCCESS, { lot }); } async checkDividend(msg: {}, session: BackendSession) { const begin = todayGuildBegin(); const guildCode = session.get('guildCode'); if (!guildCode) return resResult(STATUS.GUILD_NOT_FOUND); const dividends = await DividendModel.findGuildDividendsByBegin(guildCode, begin); return resResult(STATUS.SUCCESS, { dividends }); } async getDividend(msg: { sourceType: number }, session: BackendSession) { return resResult(STATUS.SUCCESS); } async myOffers(msg: {}, session: BackendSession) { return resResult(STATUS.SUCCESS); } async offerRecs(msg: { count: number }, session: BackendSession) { return resResult(STATUS.SUCCESS); } // ! 测试接口 async debugAddLots(msg: { magicWord: string, sourceType: number, sourceCode: string, rewards: ItemReward[]}, session: BackendSession) { const { magicWord, sourceType, sourceCode, rewards } = msg; if (magicWord !== DEBUG_MAGIC_WORD) { return resResult(STATUS.TOKEN_ERR); } const guildCode: string = session.get('guildCode'); const serverId: number = session.get('serverId'); if (!guildCode) return resResult(STATUS.GUILD_NOT_FOUND) const result = await genAuction(guildCode, sourceType, sourceCode, serverId, rewards); if (!result) { return resResult(STATUS.WRONG_PARMS); } return resResult(STATUS.SUCCESS, result); } }