import { gameData, getShopType } from "../pubUtils/data"; import { ShopData, ShopDicExtendData, ShopReturnData } from '../domain/roleField/shop'; import { UserShopModel, UserShopType } from "../db/UserShop"; import { getActivitiesByType, getActivityById } from "./activity/activityService"; import { ACTIVITY_TYPE, ITEM_CHANGE_REASON, STATUS } from "../consts"; import { getRoleCreateTime, getServerCreateTime } from "./redisService"; import { decodeArrayListStr } from "../pubUtils/util"; import { UserShopTypeModel, UserShopTypeType } from "../db/UserShopType"; import { GuildModel } from "../db/Guild"; import { RoleModel } from "../db/Role"; import { DicShop } from "../pubUtils/dictionary/DicShop"; import { BackendSession } from "pinus"; import { ActivityModelType } from "../db/Activity"; import { addItems } from "./role/rewardService"; export async function getAllShopList(roleId: string, serverId: number) { let userShopRecs = await UserShopModel.findByRoleId(roleId); let userShopTypeRecs = await UserShopTypeModel.findByRoleId(roleId); let activities = await getShopActivityDatas(roleId, serverId); let shops: ShopReturnData[] = []; for(let [_, { shop, type } ] of gameData.shopType) { let activity = activities.find(cur => cur.shop == shop && cur.type == type); let readRecord = userShopTypeRecs.find(cur => cur.shop == shop && cur.type == type); let shopData = await getShopListByData(shop, type, userShopRecs, activity, readRecord); shops.push(shopData); } return shops; } export async function getShopListByType(shop: number, type: number, roleId: string, serverId: number) { let userShopRecs = await UserShopModel.findByShopType(roleId, shop, type); let activities = await getShopActivityDatas(roleId, serverId); let activity = activities.find(cur => cur.shop == shop && cur.type == type); let readRecord = await UserShopTypeModel.findByType(roleId, shop, type); return await getShopListByData(shop, type, userShopRecs, activity, readRecord); } async function getShopListByData(shop: number, type: number, userShopRecs: UserShopType[], activity: ShopData, readRecord: UserShopTypeType) { let result = new ShopReturnData(shop, type); let dicShopType = getShopType(shop, type); if(dicShopType && dicShopType.isLimit) { if(activity) result.setDicByActivity(activity); result.setReadRecord(readRecord); } for(let userShop of userShopRecs) { result.addUserRecords(userShop); } return result; } export async function getShopDicById(activityId: number, itemId: number, roleId: string, serverId: number) { if(!activityId || activityId == 0) { return gameData.shopItem.get(itemId); } else { let activityData = await getShopActivityById(roleId, serverId, activityId); return activityData.findByItemId(itemId); } } export async function getShopActivityDatas(roleId: string, serverId: number) { let createTime = await getRoleCreateTime(roleId); let serverTime = await getServerCreateTime(serverId); let activities = await getActivitiesByType(serverId, ACTIVITY_TYPE.SHOP); return activities.map(activity => { return new ShopData(activity, createTime, serverTime); }); } export async function getShopActivityById(roleId: string, serverId: number, activityId: number) { let createTime = await getRoleCreateTime(roleId); let serverTime = await getServerCreateTime(serverId); let activity = await getActivityById(activityId); return new ShopData(activity, createTime, serverTime); } /** * * @param goodId 物品 * @param count 本次购买次数 * @param buyCount 上次购买到多少次 * @param str 字典 */ export function getShopPrice(goodId: number, count: number, buyCount: number, str: string) { let arr = parseShopPrice(str); let result = 0; for(let i = 0; i < count; i++) { let curPrice = 0; for(let { times, price } of arr) { curPrice = price; if(buyCount + i <= times) break; } result += curPrice; } return [{ id: goodId, count: result }] } function parseShopPrice(str: string) { let result = new Array<{ times: number, price: number }>(); if (!str) return result; let decodeArr = decodeArrayListStr(str); for (let [times, price] of decodeArr) { if (isNaN(parseInt(times)) || isNaN(parseInt(price))) { throw new Error('data table format wrong'); } result.push({ times: parseInt(times), price: parseInt(price) }); } return result } export async function checkShopInPurchase(session: BackendSession, activityId: number, count: number, buyCount: number, dicShopItem: DicShop|ShopDicExtendData) { let roleId = session.get('roleId'); let guildCode = session.get('guildCode'); let serverId = session.get('serverId'); let vipStartTime: number = session.get('vipStartTime'); return await checkShopItemCanBuy(activityId, dicShopItem.id, roleId, serverId, guildCode, vipStartTime, count, buyCount, dicShopItem) } export async function checkShopCanBuyInOrder(roleId: string, serverId: number, activity: ActivityModelType, productID: string) { let role = await RoleModel.findByRoleId(roleId, 'guildCode createTime vipStartTime'); let { createTime, guildCode, vipStartTime } = role; let serverTime = await getServerCreateTime(serverId); let shopData = new ShopData(activity, createTime, serverTime); if(!shopData) return false; let dicItem = shopData.findByProductID(productID); if(!dicItem) return false; let userShop = await UserShopModel.findByRoleAndItem(roleId, activity.activityId, dicItem); let result = await checkShopItemCanBuy(activity.activityId, dicItem.id, roleId, serverId, guildCode, vipStartTime, 1, userShop?.count||0, dicItem); return result.code == STATUS.SUCCESS.code; } export async function checkShopItemCanBuy(activityId: number, shopItemId: number, roleId: string, serverId: number, guildCode: string, vipStartTime: number, count: number, buyCount: number, dicShopItem?: DicShop|ShopDicExtendData) { if(!dicShopItem) { dicShopItem = await getShopDicById(activityId, shopItemId, roleId, serverId); } if(!dicShopItem) return STATUS.DIC_DATA_NOT_FOUND; if(dicShopItem.guildLvLimit) { let myGuild = await GuildModel.findByCode(guildCode, serverId); if(!myGuild || myGuild.lv < dicShopItem.guildLvLimit) return STATUS.GUILD_LV_LIMIT; } if(dicShopItem.lvLimit) { let role = await RoleModel.findByRoleId(roleId, 'lv'); if(role.lv < dicShopItem.lvLimit) { return STATUS.LV_LIMIT; } } if(dicShopItem.purchaseLimit != -1) { if(vipStartTime > 0 && dicShopItem.vipPurchaseLimit != -1) { if(buyCount + count > dicShopItem.purchaseLimit + dicShopItem.vipPurchaseLimit) { return STATUS.BUY_COUNT_OVER; } } else { if(buyCount + count > dicShopItem.purchaseLimit) { return STATUS.BUY_COUNT_OVER; } } } return STATUS.SUCCESS } /** * rmb购买 * * @param {number} serverId 区Id * @param {number} activityId 活动Id * @param {string} roleId 角色Id * @param {string} productID 商品ID * */ export async function makeShopOrder(roleId: string, roleName: string, sid: string, serverId: number, activityId: number, productID: string) { let activityData: ActivityModelType = await getActivityById(activityId); if (!activityData) { return STATUS.ACTIVITY_MISSING; } if (activityData.type !== ACTIVITY_TYPE.SHOP) { return STATUS.ACTIVITY_TYPE_ERROR; } let createTime = await getRoleCreateTime(roleId); let serverTime = await getServerCreateTime(serverId); let shopData = new ShopData(activityData, createTime, serverTime); let dicItem = shopData.findByProductID(productID); if(!dicItem) return STATUS.DIC_DATA_NOT_FOUND; let reward = [{ id: dicItem.goodId, count: 1 }]; await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.SHOP_PURCHASE); await UserShopModel.purchase(roleId, roleName, activityId, dicItem, 1); return { code: 0, data: Object.assign({}, { item: { shop: dicItem.shop, type: dicItem.type, shopItemId: dicItem.id }, activityId: activityId }) } }