import { Application, BackendSession, pinus } from "pinus"; import { gameData, hasShopType } from "../../../pubUtils/data"; import { arrToMap, parseGoodStr, resResult } from "../../../pubUtils/util"; import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GROW_MAX, ITEM_CHANGE_REASON } from "../../../consts"; import { UserShopModel } from "../../../db/UserShop"; import { handleCost, addItems } from "../../../services/role/rewardService"; import { SHOP } from "../../../pubUtils/dicParam"; import { HeroModel, HeroType } from "../../../db/Hero"; import { checkShopInPurchase, getShopDicById, getShopListByType, getShopPrice } from "../../../services/shopService"; import { RewardInter, recycleSoulFastPara } from "../../../pubUtils/interface"; import { UserShopTypeModel } from "../../../db/UserShopType"; import { nowSeconds } from "../../../pubUtils/timeUtil"; import { isGoodsHidden, isHeroHidden } from "../../../services/dataService"; import { RoleModel } from './../../../db/Role'; import { calUpSixColorsResidueFragment } from "../../../services/role/checkMaterial"; import { ItemModel } from "../../../db/Item"; export default function (app: Application) { return new ShopHandler(app); } export class ShopHandler { constructor(private app: Application) { } // 获得商品列表 async getShopList(msg: { shop: number, type: number }, session: BackendSession) { let roleId = session.get('roleId'); let serverId = session.get('serverId'); let { shop, type } = msg; if (!hasShopType(shop, type)) { return resResult(STATUS.WRONG_PARMS); } const result = await getShopListByType(shop, type, roleId, serverId); return resResult(STATUS.SUCCESS, result); } // 读取红点 async readShop(msg: { shop: number, type: number }, session: BackendSession) { let roleId = session.get('roleId'); let { shop, type } = msg; if (!hasShopType(shop, type)) { return resResult(STATUS.WRONG_PARMS); } await UserShopTypeModel.read(roleId, shop, type); return resResult(STATUS.SUCCESS); } // 购买商品 async purchase(msg: { activityId: number, shopItemId: number, count: number }, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); let serverId = session.get('serverId'); let seasonNum = pinus.app.get('pvpSeasonNum'); let { activityId = 0, shopItemId, count } = msg; let dicShopItem = await getShopDicById(activityId, shopItemId, roleId, serverId); if (!dicShopItem) return resResult(STATUS.DIC_DATA_NOT_FOUND); if (dicShopItem['productID'] && dicShopItem['productID'] != '&') return resResult(STATUS.CAN_NOT_PURCHASE); if (dicShopItem['beginTime'] && dicShopItem['beginTime'] > nowSeconds()) return resResult(STATUS.SHOP_CLOSED); if (dicShopItem['endTime'] && dicShopItem['endTime'] < nowSeconds()) return resResult(STATUS.SHOP_CLOSED); let userShop = await UserShopModel.findByRoleAndItem(roleId, dicShopItem, seasonNum); let checkResult = await checkShopInPurchase(session, activityId, count, userShop?.count || 0, dicShopItem); if (checkResult.code != STATUS.SUCCESS.code) { return resResult(checkResult); } // 总计可买次数(从配置表读取) const totalCanBuyTimes = dicShopItem.purchaseLimit; if (!totalCanBuyTimes || totalCanBuyTimes <= 0) { return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); } // 消耗 let cost = getShopPrice(dicShopItem.money, count, userShop?.count || 0, dicShopItem.price); let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.SHOP_PURCHASE); if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); // 次数 userShop = await UserShopModel.purchase(roleId, roleName, activityId, dicShopItem, count, seasonNum); if (!userShop || (userShop && userShop.count > totalCanBuyTimes)) { // rollback 消耗 let role = await RoleModel.findByRoleId(roleId); addItems(roleId, role.roleName, sid, cost, ITEM_CHANGE_REASON.SHOP_PURCHASE); // rollback 购买次数 await UserShopModel.updateCount(roleId, dicShopItem, -count, seasonNum) return resResult(STATUS.BUY_COUNT_OVER); } // 获得 let reward = [{ id: dicShopItem.goodId, count: count * (dicShopItem.num || 1) }]; let goods = await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.SHOP_PURCHASE); return resResult(STATUS.SUCCESS, { shopItemId, count, goods }); } // 将魂回收 async recycleSoul(msg: { goodsId: number, count: number }, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); let { goodsId, count } = msg; if (isGoodsHidden(goodsId)) return resResult(STATUS.ITEM_IS_HIDDEN); let dicGoods = gameData.goods.get(goodsId); if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND); let dicItid = ITID.get(dicGoods.itid); if (!dicItid) return resResult(STATUS.DIC_DATA_NOT_FOUND); if (dicItid.type != CONSUME_TYPE.SOUL) { return resResult(STATUS.ITEM_NOT_SOUL); } let hero = await HeroModel.findByHidAndRole(dicGoods.hid, roleId); if (!hero) return resResult(STATUS.HERO_NOT_MAX); if (hero.colorStar != HERO_GROW_MAX.COLORSTAR) { let residueFragment = await calUpSixColorsResidueFragment(roleId, hero, dicGoods.hid); if (!residueFragment || count > residueFragment) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); // return resResult(STATUS.HERO_NOT_MAX); } // 检查自己的数量 let cost = [{ id: goodsId, count }]; let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.RECYCLE_SOUL); if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); let reward: RewardInter[] = []; switch (dicGoods.quality) { case HERO_QUALITY_TYPE.BLUE: reward = parseGoodStr(SHOP.HERO_SOUL_BULE); break; case HERO_QUALITY_TYPE.PURPLE: reward = parseGoodStr(SHOP.HERO_SOUL_PURPLE); break; case HERO_QUALITY_TYPE.GOLD: reward = parseGoodStr(SHOP.HERO_SOUL_GOLDEN); break; case HERO_QUALITY_TYPE.UR: reward = parseGoodStr(SHOP.HERO_SOUL_UR); break; } // 增加货币 let goods = await addItems(roleId, roleName, sid, reward.map(cur => { return { id: cur.id, count: cur.count * count } }), ITEM_CHANGE_REASON.RECYCLE_SOUL); return resResult(STATUS.SUCCESS, { goodsId, count, goods }); } /** * 将魂一键回收 * @param msg * @param session * @returns */ async recycleSoulFast(msg: { recycleSoulFastPara: recycleSoulFastPara[] }, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); let { recycleSoulFastPara } = msg; // 检测参数,防止hid重复 let checkHid = new Map(); for (let { hid, count } of recycleSoulFastPara) { if (checkHid.get(hid)) return resResult(STATUS.WRONG_PARMS); checkHid.set(hid, 1); } // 从db获取所有武将数据 const dbHeros = await HeroModel.findByHidsAndRole(roleId, recycleSoulFastPara.map(obj => obj.hid)) as HeroType[]; let heroesMap = new Map(); let items = [] for (const val of dbHeros) { let hid = val.hid heroesMap.set(hid, val); let dicHero = gameData.hero.get(hid); if (!dicHero || !dicHero.pieceId) continue; items.push(dicHero.pieceId); } // 从db获取相关碎片道具数据 if (!items || items.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); const dbItems = await ItemModel.findbyRoleAndIds(roleId, items); if (!dbItems || dbItems.length == 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); const itemsMap = arrToMap(dbItems, obj => obj.id); let allAddItem = []; let allCostItem = []; for (let { hid, count } of recycleSoulFastPara) { let residueFragment = 0; let goodsId = gameData.hero.get(hid)?.pieceId || 0; const curItemCount = itemsMap.get(goodsId)?.count || 0; if (curItemCount <= 0) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); let hero = heroesMap.get(hid); if (!hero) return resResult(STATUS.HERO_IS_HIDDEN); if (hero.colorStar != HERO_GROW_MAX.COLORSTAR) { residueFragment = await calUpSixColorsResidueFragment(roleId, hero, hid, curItemCount); if (!residueFragment || count > residueFragment) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); } allCostItem.push({ id: goodsId, count: count }); let dicGoods = gameData.goods.get(goodsId); if (!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND) let reward: RewardInter[] = []; switch (dicGoods.quality) { case HERO_QUALITY_TYPE.BLUE: reward = parseGoodStr(SHOP.HERO_SOUL_BULE); break; case HERO_QUALITY_TYPE.PURPLE: reward = parseGoodStr(SHOP.HERO_SOUL_PURPLE); break; case HERO_QUALITY_TYPE.GOLD: reward = parseGoodStr(SHOP.HERO_SOUL_GOLDEN); break; case HERO_QUALITY_TYPE.UR: reward = parseGoodStr(SHOP.HERO_SOUL_UR); break; } allAddItem.push(...reward.map(cur => { return { id: cur.id, count: cur.count * count } })); } let costResult = await handleCost(roleId, sid, allCostItem, ITEM_CHANGE_REASON.RECYCLE_SOUL); if (!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); // 增加货币 let goods = await addItems(roleId, roleName, sid, allAddItem, ITEM_CHANGE_REASON.RECYCLE_SOUL); return resResult(STATUS.SUCCESS, { goods }); } // !测试接口。 去除限购次数 async debugClearPurchaseLimit(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); await UserShopModel.deleteAccount(roleId); return resResult(STATUS.SUCCESS); } }