diff --git a/game-server/app/servers/activity/handler/popUpShopHandler.ts b/game-server/app/servers/activity/handler/popUpShopHandler.ts index 39fad1f71..6c43175d2 100644 --- a/game-server/app/servers/activity/handler/popUpShopHandler.ts +++ b/game-server/app/servers/activity/handler/popUpShopHandler.ts @@ -1,7 +1,7 @@ import { Application, BackendSession, HandlerService, } from 'pinus'; import { resResult, splitString } from '../../../pubUtils/util'; -import { ACTIVITY_RESOURCES_TYPE, CURRENCY_BY_TYPE, STATUS, CURRENCY_TYPE, ITEM_CHANGE_REASON, } from '../../../consts'; -import { getPlayerPopUpShopData } from '../../../services/activity/popUpShopService'; +import { ACTIVITY_RESOURCES_TYPE, CURRENCY_BY_TYPE, STATUS, CURRENCY_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE, } from '../../../consts'; +import { checkPopUpCondition, getPopUpShopDataShow } from '../../../services/activity/popUpShopService'; import { ActivityModel, ActivityModelType } from '../../../db/Activity'; import { ActivityPopUpShopModel, ActivityPopUpShopModelType } from '../../../db/ActivityPopUpShop'; import { PopUpShopData } from '../../../domain/activityField/popUpShopField'; @@ -34,79 +34,96 @@ export class PopUpShopHandler { const roleId = session.get('roleId'); const serverId = session.get('serverId'); - let playerData = await getPlayerPopUpShopData(activityId, serverId, roleId) + let playerData = await getPopUpShopDataShow(activityId, serverId, roleId) if (!playerData) return resResult(STATUS.ACTIVITY_THIRTY_DAYS_END); return resResult(STATUS.SUCCESS, { playerData }); } - /** - * @description 购买礼包 - * @param {{ activityId: number, id: number, beginTimeStamp: number}} msg - * @param {BackendSession} session - * @memberof PopUpShopHandler - */ - async buyGift(msg: { activityId: number, id: number, beginTimeStamp: number }, session: BackendSession) { - const { activityId, id, beginTimeStamp } = msg; + async checkPopUpCondition(msg: { conditionType: number }, session: BackendSession) { const roleId = session.get('roleId'); const serverId = session.get('serverId'); - const sid = session.get('sid'); - const roleName = session.get('roleName'); - - let beginTime = moment(beginTimeStamp).toDate(); - - let activityData: ActivityModelType = await getActivityById(activityId); - if (!activityData) { - return resResult(STATUS.ACTIVITY_MISSING); + let { conditionType } = msg; + if( + conditionType != POP_UP_SHOP_CONDITION_TYPE.GACHA_RES_NOT_ENOUGH && + conditionType != POP_UP_SHOP_CONDITION_TYPE.TERAPH_RES_NOT_ENOUGH + ) { + return resResult(STATUS.WRONG_PARMS); } - let allTaskData: any[] = JSON.parse(activityData.data); - let taskIndex = allTaskData.findIndex(obj => { return obj && obj.id == id }); - if (taskIndex == -1) { - return resResult(STATUS.ACTIVITY_DATA_ERROR); - } + await checkPopUpCondition(serverId, roleId, conditionType, {}); - let playerData = new PopUpShopData(allTaskData[taskIndex], activityId); - - if (playerData.price) { - return resResult(STATUS.ACTIVITY_NEED_PAY); - } - - if (playerData.consume) { - return resResult(STATUS.ACTIVITY_NEED_PAY); - } - - let playerRecords: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findDataByBeginTime(serverId, activityId, roleId, id, playerData.taskType, beginTime); - if (!playerRecords) { - return resResult(STATUS.ACTIVITY_POP_UP_SHOP_EXPIRE); - } - if (playerRecords.buyCount >= playerData.count) { - return resResult(STATUS.ACTIVITY_MAX_COUNT); - } - - if (playerData.condition > playerRecords.totalCount) { - return resResult(STATUS.ACTIVITY_TASK_UNCOMPLETED); - } - - //元宝消费 - let arr = splitString(playerData.consume, '&') - if (arr[0] != ACTIVITY_RESOURCES_TYPE.GOODS || arr[1] != CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD)) { - return resResult(STATUS.ACTIVITY_GOLD_RESOURCE); - } - let price = arr[2];//数量 - let resourceResult = await handleCost(roleId, sid, [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count: price }], ITEM_CHANGE_REASON.POP_UP_BUY_GIFT); - if (!resourceResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); - - let rewardParamArr: Array = stringToRewardParam(playerData.reward); - let result = await addReward(roleId, roleName, sid, serverId, rewardParamArr, ITEM_CHANGE_REASON.POP_UP_BUY_GIFT) - - await ActivityPopUpShopModel.addRecord(serverId, activityId, roleId, id, playerData.taskType, 1, beginTime); - - playerData.buyCount += 1; - return resResult(STATUS.SUCCESS, Object.assign(result, { - param: { activityId, id }, - item: playerData - })); + return resResult(STATUS.SUCCESS); } + + // /** + // * @description 购买礼包 + // * @param {{ activityId: number, id: number, beginTimeStamp: number}} msg + // * @param {BackendSession} session + // * @memberof PopUpShopHandler + // */ + // async buyGift(msg: { activityId: number, id: number, beginTimeStamp: number }, session: BackendSession) { + // const { activityId, id, beginTimeStamp } = msg; + // const roleId = session.get('roleId'); + // const serverId = session.get('serverId'); + // const sid = session.get('sid'); + // const roleName = session.get('roleName'); + + // let beginTime = moment(beginTimeStamp).toDate(); + + // let activityData: ActivityModelType = await getActivityById(activityId); + // if (!activityData) { + // return resResult(STATUS.ACTIVITY_MISSING); + // } + + // let allTaskData: any[] = JSON.parse(activityData.data); + // let taskIndex = allTaskData.findIndex(obj => { return obj && obj.id == id }); + // if (taskIndex == -1) { + // return resResult(STATUS.ACTIVITY_DATA_ERROR); + // } + + // let playerData = new PopUpShopData(allTaskData[taskIndex], activityId); + + // if (playerData.price) { + // return resResult(STATUS.ACTIVITY_NEED_PAY); + // } + + // if (playerData.consume) { + // return resResult(STATUS.ACTIVITY_NEED_PAY); + // } + + // let playerRecords: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findDataByBeginTime(serverId, activityId, roleId, id, playerData.taskType, beginTime); + // if (!playerRecords) { + // return resResult(STATUS.ACTIVITY_POP_UP_SHOP_EXPIRE); + // } + // if (playerRecords.buyCount >= playerData.count) { + // return resResult(STATUS.ACTIVITY_MAX_COUNT); + // } + + // if (playerData.condition > playerRecords.totalCount) { + // return resResult(STATUS.ACTIVITY_TASK_UNCOMPLETED); + // } + + // //元宝消费 + // let arr = splitString(playerData.consume, '&') + // if (arr[0] != ACTIVITY_RESOURCES_TYPE.GOODS || arr[1] != CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD)) { + // return resResult(STATUS.ACTIVITY_GOLD_RESOURCE); + // } + // let price = arr[2];//数量 + // let resourceResult = await handleCost(roleId, sid, [{ id: CURRENCY_BY_TYPE.get(CURRENCY_TYPE.GOLD), count: price }], ITEM_CHANGE_REASON.POP_UP_BUY_GIFT); + // if (!resourceResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); + + // let rewardParamArr: Array = stringToRewardParam(playerData.reward); + // let result = await addReward(roleId, roleName, sid, serverId, rewardParamArr, ITEM_CHANGE_REASON.POP_UP_BUY_GIFT) + + // await ActivityPopUpShopModel.addRecord(serverId, activityId, roleId, id, playerData.taskType, 1, beginTime); + + // playerData.buyCount += 1; + // return resResult(STATUS.SUCCESS, Object.assign(result, { + // param: { activityId, id }, + // item: playerData + // })); + // } + } diff --git a/game-server/app/services/activity/activityService.ts b/game-server/app/services/activity/activityService.ts index 5b4cd09e5..0909c5155 100644 --- a/game-server/app/services/activity/activityService.ts +++ b/game-server/app/services/activity/activityService.ts @@ -12,7 +12,7 @@ import { getPlayerActivityData, } from './selfServiceShopActivityService'; import { ActivitySelfServiceGoodsModel } from '../../db/ActivitySelfServiceGoods'; import moment = require('moment'); import { getPlayerTreasureHuntData, getTreasureHuntData } from './treasureHuntService'; -import { getPlayerPopUpShopData } from './popUpShopService'; +import { getPopUpShopDataShow } from './popUpShopService'; import { getPlayerSevenDaysData } from './sevenDaysService'; import { getPlayerDailyMealData } from './dailyMealService'; import { getPlayerDailyCoinData } from './dailyCoinService'; @@ -36,9 +36,10 @@ import { getPlayerLuckyTurntableDataShow } from './luckyTurntableService'; import { getTimeLimitRankDataShow } from './timeLimitRankService'; import { ActivityTaskPointModel } from '../../db/ActivityTaskPoint'; import { getRoleOnlineInfo } from '../redisService'; -import { addTaskPassPoint } from './taskPassService'; +import { addTaskPassPoint, getTaskPassDataShow } from './taskPassService'; import { getGuildChannelSid } from '../chatService'; import { getGuildPayDataShow } from './guildPayService'; +import { PopUpShopItemShow } from '../../domain/activityField/popUpShopField'; /** * 获取活动数据 @@ -127,7 +128,7 @@ export async function getActivity(serverId: number, roleId: string, guildCode: s } case ACTIVITY_TYPE.POP_UP_SHOP://弹出商店 24 { - activityData = await getPlayerPopUpShopData(activityId, serverId, roleId); + activityData = await getPopUpShopDataShow(activityId, serverId, roleId); break; } case ACTIVITY_TYPE.VIP_RECHARGE_MONEY://vip累计充值活动 26 @@ -202,6 +203,11 @@ export async function getActivity(serverId: number, roleId: string, guildCode: s activityData = await getTimeLimitRankDataShow(activityId); break; } + case ACTIVITY_TYPE.TASK_PASS: // 限时排行 + { + activityData = await getTaskPassDataShow(activityId, serverId, roleId); + break; + } case ACTIVITY_TYPE.GUILD_PAY: { activityData = await getGuildPayDataShow(serverId, activityId, roleId, guildCode); @@ -366,6 +372,7 @@ interface pushActivityParamInter { payMemberCnt?: number; // 军团充值活动,你的军团充值的人数 payMember?: string; // 军团充值活动,充值人员名字,添加到payRecord里面 payRecord?: string[]; // 军团全部充值人名字 + popUpShopItems?: PopUpShopItemShow[]; // 弹出礼包 } export interface pushActivityInter { diff --git a/game-server/app/services/activity/popUpShopService.ts b/game-server/app/services/activity/popUpShopService.ts index 7ffa936f7..efbf1684f 100644 --- a/game-server/app/services/activity/popUpShopService.ts +++ b/game-server/app/services/activity/popUpShopService.ts @@ -1,33 +1,14 @@ -import { ACTIVITY_TYPE, ITEM_CHANGE_REASON, STATUS } from '../../consts'; +import { ACTIVITY_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE, STATUS } from '../../consts'; import { ActivityModel, ActivityModelType } from '../../db/Activity'; -import { PopUpShopData, } from '../../domain/activityField/popUpShopField'; +import { PopShopItem, PopUpConditionParamInter, PopUpShopData, PopUpShopPackage, PopUpShopItemShow, } from '../../domain/activityField/popUpShopField'; import { RewardParam } from '../../domain/activityField/rewardField'; import { addReward, stringToRewardParam } from './giftPackageService'; -import { ActivityPopUpShopModel, ActivityPopUpShopModelType } from '../../db/ActivityPopUpShop'; +import { ActivityPopUpShopModel, ActivityPopUpShopModelType, PopUpShopItem } from '../../db/ActivityPopUpShop'; import { ServerlistModel } from '../../db/Serverlist'; import moment = require('moment'); -import { getActivityById } from './activityService'; - -/** - * 获取活动数据 - * - * @param {number} serverId 区Id - * @param {number} type 活动类型 ACTIVITY_TYPE - * @param {string} roleId 角色Id - * - */ - -export async function popUpShopActivity(serverId: number, roleId: string) { - let { activityGroupId } = await ServerlistModel.findByServerId(serverId); - let activityArray: ActivityModelType[] = await ActivityModel.findOpenActivityByType(activityGroupId, ACTIVITY_TYPE.POP_UP_SHOP, new Date()) - - if (activityArray.length == 0) { - return null; - } - let activityData = activityArray[0]; - let playerData = await getPlayerPopUpShopData(activityData.activityId, serverId, roleId); - return playerData -} +import { getActivitiesByType, getActivityById, pushActivities, pushActivityInter, pushSingleActivity } from './activityService'; +import { RoleModel, RoleType } from '../../db/Role'; +import { HeroType } from '../../db/Hero'; /** * 玩家活动数据 @@ -37,28 +18,74 @@ export async function popUpShopActivity(serverId: number, roleId: string) { * @param {string} roleId 角色Id * */ -export async function getPlayerPopUpShopData(activityId: number, serverId: number, roleId: string) { - let activityData = await getActivityById(activityId); - let playerRecords: ActivityPopUpShopModelType[] = await ActivityPopUpShopModel.findAllOpenData(serverId, activityId, roleId); +export async function getPopUpShopData(activityId: number, serverId: number, roleId: string, role?: RoleType) { + if(!role) role = await RoleModel.findByRoleId(roleId, 'roleId totalPay'); - let allPlayerShop = []; - let allTaskData = JSON.parse(activityData.data); - for (let record of playerRecords) { - if (record.isPush) {//没有购买 - let index = allTaskData.findIndex(obj => { return obj && obj.id === record.id && obj.taskType === record.type }) - if (index != -1) { - let playerData = new PopUpShopData(allTaskData[index], activityData.activityId); - playerData.setPlayerRecords(record) - if (playerData.buyCount < allTaskData[index].count) { - allPlayerShop.push(playerData) + let activityData = await getActivityById(activityId); + let playerRecords = await ActivityPopUpShopModel.findAllEffectData(serverId, activityId, roleId); + let latestRecords = await ActivityPopUpShopModel.findAllLastData(serverId, activityId, roleId); + + let playerData = new PopUpShopData(activityData); + playerData.setPlayerRecords(playerRecords, latestRecords, role.totalPay); + + return playerData; +} + +export async function getPopUpShopDataShow(activityId: number, serverId: number, roleId: string, role?: RoleType) { + let playerData = await getPopUpShopData(activityId, serverId, roleId, role); + if(playerData && playerData.canShow && playerData.canShow()) { + return playerData.getShowResult(); + } + return null +} + +export async function checkPopUpConditionInCreateHero(serverId, roleId, heroes: HeroType[]) { + let conditions = heroes.map(hero => ({ conditionType: POP_UP_SHOP_CONDITION_TYPE.GET_HERO_BY_QUALITY, param: { quality: hero.quality } })); + return await checkPopUpConditions(serverId, roleId, conditions); +} + +export async function checkPopUpCondition(serverId: number, roleId: string, conditionType: POP_UP_SHOP_CONDITION_TYPE, param: PopUpConditionParamInter) { + return await checkPopUpConditions(serverId, roleId, [{ conditionType, param }]); +} + +// 弹出礼包任务 +export async function checkPopUpConditions(serverId: number, roleId: string, conditions: { conditionType: POP_UP_SHOP_CONDITION_TYPE, param: PopUpConditionParamInter }[]) { + let activities = await getActivitiesByType(serverId, ACTIVITY_TYPE.POP_UP_SHOP); + let pushData: pushActivityInter[] = []; + for(let { activityId, type: activityType } of activities) { + + let playerData = await getPopUpShopData(activityId, serverId, roleId); + let pushItems: PopUpShopItemShow[] = []; + for(let { conditionType, param } of conditions) { + for(let pkg of playerData.packages) { + console.log('##### 3', pkg.id, pkg.checkPackageCanPush(conditionType)) + if( !pkg.checkPackageCanPush(conditionType)) { // 筛选推送 + continue; + } + let items = pkg.getItemsByCondition(param); + console.log('##### 4', items, items.length) + if(items.length > 0) { + let popUpShopRec = await ActivityPopUpShopModel.createRecord({ + serverId, activityId, roleId, id: pkg.id, + ...pkg.getEffectTime(), + items: items.map(item => new PopUpShopItem(item)) + }); + let result = pkg.pushPackage(popUpShopRec); + pushItems.push(...result); } } } + console.log('##### 5', pushItems.length) + if(pushItems.length > 0) { + pushData.push({ activityId, activityType, param: { popUpShopItems: pushItems } }); + } } - allPlayerShop['canShow'] = () => true; - return allPlayerShop; + console.log('##### 6', pushData.length) + await pushActivities(pushData, roleId); + } + /** * 结算购买礼包的奖励 * @@ -69,49 +96,32 @@ export async function getPlayerPopUpShopData(activityId: number, serverId: numbe * */ export async function makePopUpShopReward(roleId: string, roleName: string, sid: string, serverId: number, - activityId: number, productID: string, paramStr: string) { + activityId: number, productID: string, paramStr: string, roleInfo: RoleType) { if (!paramStr) { return STATUS.ORDER_PARAM_ERROR; } let paramObj = JSON.parse(paramStr); - let beginTime = moment(paramObj.beginTimeStamp).toDate(); + let code = paramObj.code; - let activityData: ActivityModelType = await getActivityById(activityId); - if (!activityData) { + let playerData = await getPopUpShopData(activityId, serverId, roleId, roleInfo); + if (!playerData) { return STATUS.ACTIVITY_MISSING; } - if (activityData.type !== ACTIVITY_TYPE.POP_UP_SHOP) { + if (playerData.type !== ACTIVITY_TYPE.POP_UP_SHOP) { return STATUS.ACTIVITY_TYPE_ERROR; } - let allTaskData: any[] = JSON.parse(activityData.data); - let taskIndex = allTaskData.findIndex(obj => { return obj && obj.productID == productID }); - if (taskIndex == -1) { - return STATUS.ACTIVITY_NO_PRODUCT; - } - let playerData = new PopUpShopData(allTaskData[taskIndex], activityId); - let playerRecord: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findDataByBeginTime(serverId, activityId, roleId, playerData.id, playerData.taskType, beginTime); + + let playerRecord: ActivityPopUpShopModelType = await ActivityPopUpShopModel.addRecord(serverId, activityId, roleId, code, productID); if (!playerRecord) { return STATUS.APPLY_ORDER_ERROR; } - let curDate = new Date(); - if (curDate < playerRecord.beginTime || curDate > playerRecord.endTime) { - return STATUS.ACTIVITY_POP_UP_SHOP_CLOSED; - } - if (playerRecord.totalCount < playerData.condition) { - return STATUS.ACTIVITY_TASK_UNCOMPLETED; - } - if (playerRecord.buyCount >= playerData.count) { - return STATUS.ACTIVITY_REWARDED; - } - playerRecord = await ActivityPopUpShopModel.addRecord(serverId, activityId, roleId, playerData.id, playerData.taskType, 1, beginTime); - playerData.setPlayerRecords(playerRecord); + let item = playerData.updateRecord(playerRecord, productID); - let rewardParamArr: Array = stringToRewardParam(playerData.reward); + let rewardParamArr: Array = stringToRewardParam(item.reward); let result = await addReward(roleId, roleName, sid, serverId, rewardParamArr, ITEM_CHANGE_REASON.POP_UP_BUY_GIFT) - return { code: 0, - data: Object.assign(result, { item: playerData, activityId: activityData.activityId }) + data: Object.assign(result, { item: item, activityId }) } } \ No newline at end of file diff --git a/game-server/app/services/gmService.ts b/game-server/app/services/gmService.ts index 630fd48c8..0fb8686c7 100644 --- a/game-server/app/services/gmService.ts +++ b/game-server/app/services/gmService.ts @@ -251,10 +251,11 @@ export function getActivityProducts(activity: ActivityModelType) { case ACTIVITY_TYPE.POP_UP_SHOP://弹出礼包 { let products: { label: string, value: string }[] = []; - let allTaskData: any[] = JSON.parse(activity.data); - for(let task of allTaskData) { - let data = new PopUpShopData(task, activity.activityId); - products.push(getDicRMB(data.productID)) + let data = new PopUpShopData(activity); + for(let { items } of data.packages) { + for(let item of items) { + products.push(getDicRMB(item.productID)); + } } return products; } @@ -299,23 +300,23 @@ export async function getParamStr(activity: ActivityModelType, productID: string let task = allTaskData.find(cur => cur.productID == productID); if(!task) break; - 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); - } + // 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(); + // param['beginTimeStamp'] = playerRecord.beginTime.getTime(); break; case ACTIVITY_TYPE.REFRESH_SHOP: let { activityGroupId } = await ServerlistModel.findByServerId(role.serverId); diff --git a/game-server/app/services/normalBattleService.ts b/game-server/app/services/normalBattleService.ts index f075a87d5..c6d295b0d 100644 --- a/game-server/app/services/normalBattleService.ts +++ b/game-server/app/services/normalBattleService.ts @@ -4,7 +4,7 @@ import Role, { RoleModel, RoleType } from '../db/Role' import { getLvByExp, getExpByLv, gameData, getDicApByLv } from '../pubUtils/data'; import { updateUserInfo } from './redisService'; // import { switchOnFunc } from './funcSwitchService'; -import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE, ITEM_CHANGE_REASON } from '../consts'; +import { FUNC_OPT_TYPE, TASK_TYPE, WAR_TYPE, STATUS, KING_EXP_RATIO_TYPE, ITEM_CHANGE_REASON, POP_UP_SHOP_CONDITION_TYPE } from '../consts'; import { BackendSession, pinus } from 'pinus'; import { REDIS_KEY } from '../consts'; import { Rank } from './rankService'; @@ -16,6 +16,7 @@ import { resResult } from '../pubUtils/util'; import { LineupParam } from '../domain/rank'; import { WarStar } from '../domain/dbGeneral'; import { uniq } from 'underscore'; +import { checkPopUpCondition } from './activity/popUpShopService'; export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kingExp: number = 0, session: BackendSession) { const serverId = session.get('serverId'); @@ -47,6 +48,8 @@ export async function roleLevelup(type: KING_EXP_RATIO_TYPE, roleId: string, kin await checkTask(roleId, session.get('sid'), TASK_TYPE.ROLE_LV, newLv, false, {}); //成长任务 await checkActivityTask(serverId, session.get('sid'), roleId, TASK_TYPE.ROLE_LV, newLv); + // 弹出礼包 + await checkPopUpCondition(serverId, roleId, POP_UP_SHOP_CONDITION_TYPE.LV_TO, { oldLv: lv, newLv }) } let actordata: { lv: number, exp: number, getExp: number, mostExp: number }[] = []; diff --git a/game-server/app/services/orderService.ts b/game-server/app/services/orderService.ts index 7ab482689..1b71ceb46 100644 --- a/game-server/app/services/orderService.ts +++ b/game-server/app/services/orderService.ts @@ -88,7 +88,7 @@ export async function makeOrder(orderInfo: UserOrderModelType, sid: string) { } case ACTIVITY_TYPE.POP_UP_SHOP://弹出礼包 { - rewardResult = await makePopUpShopReward(roleId, roleInfo.roleName, sid, orderInfo.serverId, orderInfo.activityId, orderInfo.productID, orderInfo.paramStr) + rewardResult = await makePopUpShopReward(roleId, roleInfo.roleName, sid, orderInfo.serverId, orderInfo.activityId, orderInfo.productID, orderInfo.paramStr, roleInfo) break; } case ACTIVITY_TYPE.GROWTH_FUND_MAIN_VIP: //主线成长基金(高阶) diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index 8762ac1f6..2a6cbf837 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -1,4 +1,4 @@ -import { ITID, CONSUME_TYPE, ITEM_TABLE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT } from './../consts'; +import { ITID, CONSUME_TYPE, ITEM_TABLE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, ITEM_CHANGE_REASON, TA_USERSET_TYPE, TA_EVENT, POP_UP_SHOP_CONDITION_TYPE } from './../consts'; import { getRandSingleEelm, resResult } from '../pubUtils/util'; import { RoleModel, RoleType } from '../db/Role'; import { setAp } from './actionPointService'; @@ -27,6 +27,7 @@ import { reportTAEvent, reportTAUserSet } from './sdkService'; import { saveCoinChangeLog, saveFigureInfoLog, saveGoldChangeLog, saveItemChangeLog } from '../pubUtils/logUtil'; import { JewelModel, JewelType } from '../db/Jewel'; import { updateEplaces } from './equipService'; +import { checkPopUpConditionInCreateHero } from './activity/popUpShopService'; export class CheckMeterial { private roleId: string; @@ -604,6 +605,8 @@ export async function createHeroes(roleId: string, roleName: string, sid: string await createHero.updateRedisRank(Rank); heroes = createHero.getShowHeroes(); resultHeroes = createHero.getResultHeroes(); + + await checkPopUpConditionInCreateHero(serverId, roleId, resultHeroes); } if (pieces.length > 0) { diff --git a/shared/consts/constModules/activityConst.ts b/shared/consts/constModules/activityConst.ts index 65de526d2..34cb5c216 100644 --- a/shared/consts/constModules/activityConst.ts +++ b/shared/consts/constModules/activityConst.ts @@ -168,4 +168,19 @@ export const SIGNIN_CLOSE = 31;//*号晚上24点结束 export enum TASK_PASS_TYPE { STANDARD = 1, // 标准版,不付钱 VIP = 2, // 要付钱 +} + +export enum POP_UP_SHOP_CONDITION_TYPE { + LV_TO = 1, // 达到等级 + GET_HERO_BY_QUALITY = 2, // 获得某种品质的武将 + GACHA_RES_NOT_ENOUGH = 3, // 点击抽卡资源不足 + TERAPH_RES_NOT_ENOUGH = 4, // 神兽强化材料不足 +} + +export enum POP_UP_SHOP_REFRESH_TIME_TYPE { + NO = 0, // 不复现 + NATURAL_DAY = 1, // 自然日 + NATURAL_WEEK = 2, // 自然周 + NATURAL_MONTH = 3, // 自然月 + DAYS = 4, // 从beginTime开始固定日 } \ No newline at end of file diff --git a/shared/db/ActivityPopUpShop.ts b/shared/db/ActivityPopUpShop.ts index a484e7e6d..f5db9f819 100644 --- a/shared/db/ActivityPopUpShop.ts +++ b/shared/db/ActivityPopUpShop.ts @@ -1,6 +1,28 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; +import { genCode } from '../pubUtils/util'; +import { PopShopItem } from '../domain/activityField/popUpShopField'; +import { Reward } from '../domain/battleField/pvp'; +export class PopUpShopItem { + @prop({ required: true }) + id: number; // 分档礼包id + + @prop({ required: true }) + productID: string; // 商品id + + @prop({ required: true }) + hasBoughtCnt: number = 0; // 已购买次数 + + @prop({ required: true, _id: false, type: Reward }) + rewards: Reward[] = []; // 已购买次数 + + constructor(item: PopShopItem) { + this.id = item.id; + this.productID = item.productID; + this.rewards = item.rewardInter; + } +} /** * 活动系统 - 弹出商店 @@ -10,119 +32,71 @@ import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoos export default class Activity_Pop_Up_Shop extends BaseModel { @prop({ required: true }) serverId: number; // 服id + @prop({ required: true }) activityId: number; // 活动Id + @prop({ required: true }) roleId: string; // 用户Id + @prop({ required: true }) beginTime: Date; // 开始时间 + @prop({ required: true }) endTime: Date; // 结束时间 + @prop({ required: true }) - id: number; // 任务id + effectBeginTime: Date; // 刷新等生效开始时间 + @prop({ required: true }) - type: number; // 任务类型 + effectEndTime: Date; // 刷新等生效结束时间 + @prop({ required: true }) - totalCount: number; // 累计达成次数 + id: number; // 礼包id + @prop({ required: true }) - data: string; // 数据信息 + code: string; // 本礼包本次推送的唯一code + + @prop({ required: true, type: PopUpShopItem, _id: false }) + items: PopUpShopItem[]; // 礼包id + @prop({ required: true }) - buyCount: number; // 购买次数 + hasBought: boolean; // 是否购买了 + @prop({ required: true }) - isPush: boolean; // 是否推送过 + isLast: boolean; // 是否是最后一个 - //购买记录 - public static async addRecord(serverId: number, activityId: number, roleId: string, id: number, type: number, buyCount: number, beginTime: Date) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ - serverId, roleId, activityId, id, type, - beginTime: beginTime - }, - { $inc: { buyCount: buyCount } }, { upsert: true, new: true }).lean(true); - return result; + /** + * 获取自然日内的次数 + * @param roleId + * @param beginTime + * @param endTime + */ + public static async findAllEffectData(serverId: number, activityId: number, roleId: string) { + let now = new Date(); + let rec: ActivityPopUpShopModelType[] = await ActivityPopUpShopModel.find({ roleId, serverId, activityId, effectBeginTime: { $lte: now }, effectEndTime: { $gte: now } }).lean(); + return rec; } - //查询现在正在进行的活动数据 - public static async findAllOpenData(serverId: number, activityId: number, roleId: string) { - let nowDate = new Date(); - let result: ActivityPopUpShopModelType[] = await ActivityPopUpShopModel.find({ - serverId, roleId, activityId, - beginTime: { $lt: nowDate }, endTime: { $gt: nowDate }, - isBuy: { $ne: true }, - }).lean(true); - return result; + public static async findAllLastData(serverId: number, activityId: number, roleId: string) { + let rec: ActivityPopUpShopModelType[] = await ActivityPopUpShopModel.find({ roleId, serverId, activityId, isLast: true }).lean(); + return rec; } - //根据活动taskId查询现在正在进行的活动数据 - public static async findDataByTaskId(serverId: number, activityId: number, roleId: string, id: number, type: number) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOne({ - serverId, roleId, activityId, id, type, - }).lean(true); - return result; + public static async createRecord(param: ActivityPopUpShopModelTypeParam) { + let { serverId, activityId, roleId, id,} = param; + await ActivityPopUpShopModel.updateMany({ serverId, activityId, roleId, id, isLast: true }, { $set: { isLast: false } }); + let code = genCode(8); + let rec: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ code }, { $set: {...param, hasBought: false, isLast: true } }, { new: true, upsert: true }).lean(); + return rec; } - //根据活动开始时间查询现在正在开启的商店数据 - public static async findDataByBeginTime(serverId: number, activityId: number, roleId: string, id: number, type: number, beginTime: Date) { - console.log('beginTime', serverId, roleId, activityId, id, type, beginTime) - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOne({ - serverId, roleId, activityId, id, type, beginTime: beginTime - }).lean(true); - return result; - } - - - //根据活动统计完成任务次数 - public static async setTaskCount(serverId: number, activityId: number, roleId: string, id: number, type: number, count: number) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ serverId, roleId, activityId, id, type }, - { $set: { totalCount: count } }, { upsert: true, new: true }).lean(true); - return result; - } - - //根据活动统计完成任务次数 - public static async addTaskCount(serverId: number, activityId: number, roleId: string, id: number, type: number, addCount: number) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ serverId, roleId, activityId, id, type }, - { $inc: { totalCount: addCount } }, { upsert: true, new: true }).lean(true); - return result; - } - - //根据活动记录统计数据 - public static async addTaskRecord(serverId: number, activityId: number, roleId: string, id: number, type: number, data: string,) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ serverId, roleId, activityId, id, type }, - { $set: { data: data } }, { upsert: true, new: true }).lean(true); - return result; - } - - //标记push消息 - public static async pushMessage(serverId: number, activityId: number, roleId: string, id: number, type: number, beginTime: Date, endTime: Date) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ serverId, roleId, activityId, id, type }, - { $set: { isPush: true, beginTime, endTime } }, { upsert: true, new: true }).lean(true); - return result; - } - - //添加数据并标记push消息 - public static async addTaskPushMessage(serverId: number, activityId: number, roleId: string, id: number, type: number, totalCount: number, beginTime: Date, endTime: Date) { - let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ serverId, roleId, activityId, id, type, totalCount, beginTime, endTime }, - { $set: { isPush: true } }, { upsert: true, new: true }).lean(true); - return result; - } - - //添加数据并标记push消息 - public static async addTaskArrayPushMessage(serverId: number, activityId: number, roleIds: string[], id: number, type: number, totalCount: number, beginTime: Date, endTime: Date) { - let activityData = []; - for (let roleId of roleIds) { - activityData.push( - { serverId, roleId, activityId, id, type, totalCount, beginTime, endTime, isPush: true, buyCount: 0, data: JSON.stringify({ totalCount }) } - ) - } - await ActivityPopUpShopModel.insertMany(activityData); - } - - //删除活动领取记录 - public static async deleteActivity(_serverId: number, activityId: number, roleId: string, id: number) { - let nowDate = new Date(); - await ActivityPopUpShopModel.deleteMany({ - roleId, activityId, id, - beginTime: { $lt: nowDate }, endTime: { $gt: nowDate } - }); + public static async addRecord(serverId: number, activityId: number, roleId: string, code: string, productID: string) { + let rec: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate( + { serverId, activityId, roleId, code, 'items.productID': productID }, + { $set: { hasBought: true }, $inc: { 'items.$.hasBoughtCnt': 1 } }, + { new: true} ).lean(); + return rec; } } diff --git a/shared/db/ActivityPopUpShopRecord.ts b/shared/db/ActivityPopUpShopRecord.ts deleted file mode 100644 index 94ba5647d..000000000 --- a/shared/db/ActivityPopUpShopRecord.ts +++ /dev/null @@ -1,55 +0,0 @@ -import BaseModel from './BaseModel'; -import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; - - -/** - * 活动系统 - 弹出商店数据统计 -*/ -@index({ roleId: 1 }) - -export default class Activity_Pop_Up_Shop_Record extends BaseModel { - @prop({ required: true }) - serverId: number; // 服id - @prop({ required: true }) - activityId: number; // 活动Id - @prop({ required: true }) - roleId: string; // 用户Id - @prop({ required: true }) - beginTime: Date; // 开始统计时间 - @prop({ required: true }) - id: number; // 任务id - @prop({ required: true }) - type: number; // 任务类型 - @prop({ required: true }) - count: number; // 统计次数 - - - //添加统计 - public static async addRecord(serverId: number, activityId: number, roleId: string, id: number, type: number, beginTime: Date, count: number) { - let result: ActivityPopUpShopRecordModelType = await ActivityPopUpShopRecordModel.findOneAndUpdate({ - serverId, roleId, activityId, id, type, beginTime, - }, - { $inc: { count: count } }, { upsert: true, new: true }).lean(true); - return result; - } - - //查询统计数据 - public static async findRecordData(serverId: number, activityId: number, roleId: string, id: number, type: number, beginTime: Date) { - let result: ActivityPopUpShopRecordModelType = await ActivityPopUpShopRecordModel.findOne({ - serverId, roleId, activityId, id, type, beginTime, - }).lean(true); - return result; - } - - //删除活动统计记录 - public static async deleteActivity(_serverId: number, activityId: number, roleId: string, id: number, type: number,) { - await ActivityPopUpShopRecordModel.deleteMany({ - roleId, activityId, id, type - }); - } -} - -export const ActivityPopUpShopRecordModel = getModelForClass(Activity_Pop_Up_Shop_Record); - -export interface ActivityPopUpShopRecordModelType extends Pick, keyof Activity_Pop_Up_Shop_Record> { } -export type ActivityPopUpShopRecordModelTypeParam = Partial; // 将所有字段变成可选项 \ No newline at end of file diff --git a/shared/domain/activityField/popUpShopField.ts b/shared/domain/activityField/popUpShopField.ts index 0644b9d6b..3919014ca 100644 --- a/shared/domain/activityField/popUpShopField.ts +++ b/shared/domain/activityField/popUpShopField.ts @@ -1,67 +1,474 @@ import moment = require("moment"); -import { ACTIVITY_TYPE } from "../../consts"; -import { ActivityPopUpShopModelType } from "../../db/ActivityPopUpShop"; +import { POP_UP_SHOP_CONDITION_TYPE, POP_UP_SHOP_REFRESH_TIME_TYPE, REFRESH_TIME } from "../../consts"; +import { ActivityModelType } from "../../db/Activity"; +import { ActivityPopUpShopModelType, PopUpShopItem as ActivityPopUpShopItem } from "../../db/ActivityPopUpShop"; +import { RewardInter } from "../../pubUtils/interface"; +import { parseNumberList } from "../../pubUtils/util"; +import { stringToRewardInter } from "../../services/activity/giftPackageService"; +import { ActivityBase } from './activityField'; -// 弹框商店 -export class PopUpShopData { - type: number//活动类型 - activityId: number; // 活动id - id: number; // 第几个,从1开始 - name: string; //名字 - consume: string; //消耗资源(这里优先rmb的price价格,其次资源消耗) - price: number; // 商品价格 - productID: string; // 商品id支付时使用 - reward: string; //任务奖励,格式:1&3&1(类型&id&数量) 类型定义:1.英雄,2.物品 - rebate: number; // 折扣用于显示 - duration: number; // 持续时间,单位小时 - taskType: number; // 任务类型 - taskParam: number; // 任务参数 - condition: number; // 任务条件 - totalCount: number; //一共完成次数 - count: number; //最大可购买次数 +// 数据库格式 +interface PopUpShopDataInDb { + packages: PopUpShopPackageInDb[]; + vipLevel: PopUpShopVipLevelInDb[]; +} - buyCount: number = 0; //已经购买过次数 - beginTime: Date = null;//开始时间 - endTime: Date = null;//结束时间 - beginTimeStamp: number = 0;//开始时间 - endTimeStamp: number = 0;//结束时间 +interface PopUpShopPackageInDb { + id: number; // 弹出礼包id + conditionType: number; // 条件类型 + canLvUp: number; // 是否可升降 + items: PopUpShopItemInDb[]; // 礼包 + duration: number; // 礼包弹出之后,持续时间,单位小时 + keyItem: PopUpShopKeyItemIbDb[]; // 关键资源限制,refreshDay内可以获得Y个 + refreshTimeType: number; // 刷新时间类型,0-不复现 1-自然日 2-自然周 3-自然月 4-从beginTime开始固定天 + refreshDay: number; // 上面刷新时间的具体天数,refreshTimeType=0-3都不会使用这个参数,refreshTimeType=4时这个表示固定几天 + pushCnt: number; // 在自然日cd之内,总推送次数,不复现的填0,不限制这个使用其他限制的填-1(如passCnt填次数的时候,这里填-1) + passCnt: number; // 弹出了没有购买多少次之后不再推送,默认填0 +} + +interface PopUpShopItemInDb { + id: number; // 档位唯一id,升降档的时候按照id顺序排,升档id+,降档id- + conditionParam: string; // 条件类型的参数,填法根据conditionType表判断 + price: number; // 商品价格 + productID: string; // 商品id支付时使用 + consume: string; // 消耗资源(这里优先rmb的price价格,其次资源消耗) + reward: string; // 任务奖励,格式:1&3&1(类型&id&数量) 类型定义:1.英雄,2.物品 + rebate: number; // 折扣用于显示 + buyCnt: number; // 购买多少次后消失,原来的count字段 +} + +interface PopUpShopKeyItemIbDb { + gid: number; // 关键资源id + max: number; // 关键资源上限,Y +} + +interface PopUpShopVipLevelInDb { + lv: number; // 几级 + minPayMoney: number; // 最低金额 + maxPayMoney: number; // 最高金额,5000+的填-1 + price: number; // 礼包上限 +} + +/** + * 弹出商店 + */ +export class PopUpShopData extends ActivityBase { + packages: PopUpShopPackage[] = []; + vipLevel: PopUpShopVipLevel[] = []; + + private packageMap: Map = new Map(); + vipLv: number = 0; // 玩家当前等级 + maxPrice: number = 0; // 礼包上限 + + constructor(activityData: ActivityModelType) { + super(activityData, 0); + this.initData(activityData.data) + } + + public initData(data: string) { + let dataObj: PopUpShopDataInDb = JSON.parse(data); + for(let pkg of dataObj.packages) { + let obj = new PopUpShopPackage(pkg, this); + this.packages.push(obj); + this.packageMap.set(obj.id, this.packages.length - 1); + } + for(let lv of dataObj.vipLevel) { + let obj = new PopUpShopVipLevel(lv); + this.vipLevel.push(obj); + } + } //解析玩家开启的商店记录 - public setPlayerRecords(data: ActivityPopUpShopModelType) { - if (!data) { - return; + public setPlayerRecords(datas: ActivityPopUpShopModelType[], latestRecords: ActivityPopUpShopModelType[], totalPay: number) { + if (!datas) return; + + this.setVipLv(totalPay); + for(let data of datas) { + let pkg = this.findPackageById(data.id); + pkg.addPlayerRecord(data); } - this.buyCount = data.buyCount ? data.buyCount : 0; - this.beginTime = data.beginTime; - this.endTime = data.endTime; - this.beginTimeStamp = moment(data.beginTime).valueOf(); - this.endTimeStamp = moment(data.endTime).valueOf(); - this.totalCount = data.totalCount; + for(let data of latestRecords) { + let pkg = this.findPackageById(data.id); + pkg.setLatestBought(data); + } + } + + private setVipLv(totalPay: number) { + for(let { lv, minPayMoney, maxPayMoney, price } of this.vipLevel) { + if(totalPay >= minPayMoney && (maxPayMoney == -1 || totalPay < maxPayMoney)) { + this.vipLv = lv; + this.maxPrice = price; + break; + } + } + } + + private findPackageById(id: number) { + let index = this.packageMap.get(id); + return this.packages[index]; } - public initData(data: any) { - this.type = ACTIVITY_TYPE.POP_UP_SHOP; + public getShowResult() { + return new PopUpShopShow(this); + } + + public updateRecord(data: ActivityPopUpShopModelType, productID: string) { + let pkg = this.findPackageById(data.id); + let dataItem = data.items.find(cur => cur.productID == productID); + let item = pkg.findItemByProductID(productID); + return item.updateItem(dataItem); + } +} + +// 同一礼包类型为一组,共享cd,档位 +export class PopUpShopPackage { + id: number; // 弹出礼包id + conditionType: number; // 条件类型 + canLvUp: number; // 是否可升降 + duration: number; // 礼包弹出之后,持续时间,单位小时 + refreshTimeType: number; // 刷新时间类型,0-不复现 1-自然日 2-自然周 3-自然月 4-从beginTime开始固定天 + refreshDay: number; // 复现自然日cd,不复现的填0,从弹出礼包那一天的凌晨5点开始计数 + pushCnt: number; // 在自然日cd之内,总推送次数,不复现的填0,不限制这个使用其他限制的填-1(如passCnt填次数的时候,这里填-1) + passCnt: number; // 弹出了没有购买多少次之后不再推送,默认填0 + // initData的时候处理的数据 + items: PopShopItem[] = []; // 礼包 + keyItem: PopUpShopKeyItem[] = []; // 关键资源限制,refreshDay内可以获得Y个 + private itemByProductID: Map = new Map(); // productID => index + private parent: PopUpShopData; + + // setPlayerRecord的时候处理的数据 + hasPushCnt: number = 0; // 已经推过几次了 + hasPassCnt: number = 0; // 已经被连续无视过几次 + + latestItemId: number = 0; // 升降礼包,最近一次的那档id + latestBought: boolean = false; // 最近一次是否购买 + isPushing: boolean = false; // 是否有正在推送中 + + constructor(data: PopUpShopPackageInDb, parent: PopUpShopData) { + this.parent = parent this.id = data.id; - this.reward = data.reward; - this.consume = data.consume ? data.consume : ''; - this.price = data.price ? data.price : 0; - this.productID = data.productID ? data.productID : ''; - this.name = data.name; - this.rebate = data.rebate; + this.conditionType = data.conditionType; + this.canLvUp = data.canLvUp; this.duration = data.duration; - this.taskType = data.taskType; - this.taskParam = data.taskParam; - this.condition = data.condition; - this.buyCount = 0; - this.beginTime = null; - this.endTime = null; - this.totalCount = 0; - this.count = data.count; + this.refreshTimeType = data.refreshTimeType; + this.refreshDay = data.refreshDay; + this.pushCnt = data.pushCnt; + this.passCnt = data.passCnt; + for(let item of data.items) { + let obj = new PopShopItem(item, this); + this.items.push(obj); + this.itemByProductID.set(obj.productID, this.items.length - 1); + } + for(let key of data.keyItem) { + this.keyItem.push(new PopUpShopKeyItem(key)); + } } - constructor(activityData: any, activityId: number) { - this.activityId = activityId; - this.initData(activityData) + // vip分档 + public getVipMaxPrice() { + return this.parent.maxPrice; + } + + public findItemByProductID(productID: string) { + let index = this.itemByProductID.get(productID); + return this.items[index]; + } + + public addPlayerRecord(data: ActivityPopUpShopModelType) { + let now = new Date(); + this.hasPushCnt++; + for(let key of this.keyItem) { + key.addHasBoughtCnt(data.items); + } + if(data.beginTime <= now && data.endTime > now) { // 正在进行中 + for(let itemData of data.items) { + let item = this.findItemByProductID(itemData.productID); + item.setPlayerRecords(data, itemData); + this.isPushing = true; + } + } else if (data.beginTime < now && data.endTime < now) { // 已经结束了的 + if(data.hasBought) { // 是否看到了,但是没有买 + this.hasPassCnt = 0; + } else { + this.hasPassCnt ++; + } + } + + } + + public setLatestBought(data: ActivityPopUpShopModelType) { + this.latestItemId = data.items[0].id; + this.latestBought = data.items[0].hasBoughtCnt > 0; + } + + // 检查这个礼包是否可以推送 + public checkPackageCanPush(conditionType: POP_UP_SHOP_CONDITION_TYPE) { + // 1. 达成条件类型是否符合 + console.log('######### 3.5.1', this.conditionType, conditionType, this.conditionType != conditionType) + if(this.conditionType != conditionType) return false; + // 2. 判断同类型是否是已经有在持续中的 + console.log('######### 3.5.2', this.refreshTimeType, this.isPushing, this.refreshTimeType != 0 && this.isPushing) + if(this.refreshTimeType != 0 && this.isPushing) return false; + // 3. 自然日内推送次数 + console.log('######### 3.5.3', this.pushCnt, this.hasPushCnt, this.pushCnt != -1, this.hasPushCnt >= this.pushCnt) + if(this.pushCnt != -1 && this.hasPushCnt >= this.pushCnt) return false; + // 4. 连续无视次数 + console.log('######### 3.5.4', this.hasPassCnt, this.passCnt, this.passCnt > 0 && this.hasPassCnt >= this.passCnt) + if(this.passCnt > 0 && this.hasPassCnt >= this.passCnt) return false; + + return true; + } + + public getItemsByCondition(param: PopUpConditionParamInter) { + let items: PopShopItem[] = [], minItem: PopShopItem, maxItem: PopShopItem; + for(let item of this.items) { + if(!item.checkItemCanPush(this.conditionType, param)) continue; // 达成任务条件 + if(!minItem) minItem = item; + if(!maxItem || maxItem.id > item.id) maxItem = item; + + if(this.canLvUp == 1) { // 升降礼包 + if(this.latestBought && item.id == this.latestItemId + 1 ) { // 最近一次买了,升级 + items.push(item); + } else if(!this.latestBought && item.id == this.latestItemId - 1 ) { + items.push(item); + } + } else { + items.push(item); + } + } + if(!items.length && maxItem && minItem) items.push(this.latestBought? maxItem: minItem); + return items; + } + + public getEffectTime() { + let now = new Date(); + let beginTime = now; + let endTime = moment(now).add(this.duration, 'h').toDate(); + let effectBeginTime: Date, effectEndTime: Date; + switch(this.refreshTimeType) { + case POP_UP_SHOP_REFRESH_TIME_TYPE.NO: + effectBeginTime = new Date(this.parent.beginTime); + effectEndTime = new Date(this.parent.endTime); + break; + case POP_UP_SHOP_REFRESH_TIME_TYPE.NATURAL_DAY: + effectBeginTime = moment(now).startOf('d').add(REFRESH_TIME, 'h').toDate(); + effectEndTime = moment(now).endOf('d').add(REFRESH_TIME, 'h').toDate(); + break; + case POP_UP_SHOP_REFRESH_TIME_TYPE.NATURAL_WEEK: + effectBeginTime = moment(now).startOf('w').add(REFRESH_TIME, 'h').toDate(); + effectEndTime = moment(now).endOf('w').add(REFRESH_TIME, 'h').toDate(); + break; + case POP_UP_SHOP_REFRESH_TIME_TYPE.NATURAL_MONTH: + effectBeginTime = moment(now).startOf('month').add(REFRESH_TIME, 'h').toDate(); + effectEndTime = moment(now).endOf('month').add(REFRESH_TIME, 'h').toDate(); + break; + case POP_UP_SHOP_REFRESH_TIME_TYPE.DAYS: + let gap = moment(now).diff(this.parent.beginTime, 'd'); + let n = Math.floor(gap / this.refreshDay); + effectBeginTime = moment(this.parent.beginTime).startOf('d').add(n * this.refreshDay, 'd').add(REFRESH_TIME, 'h').toDate(); + effectEndTime = moment(this.parent.beginTime).startOf('d').add((n + 1) * this.refreshDay, 'd').add(REFRESH_TIME, 'h').toDate(); + break; + } + + return { + beginTime, endTime, effectBeginTime, effectEndTime + } + } + + public pushPackage(popUpShopRec: ActivityPopUpShopModelType) { + this.addPlayerRecord(popUpShopRec); + let items: PopUpShopItemShow[] = []; + for(let item of popUpShopRec.items) { + let itemObj = this.findItemByProductID(item.productID); + if(itemObj.isPushing) { + let obj = new PopUpShopItemShow(itemObj); + items.push(obj); + } + } + return items + } +} + +// 礼包,购买以此为单位 +export class PopShopItem { + id: number; // 档位唯一id,升降档的时候按照id顺序排,升档id+,降档id- + conditionParam: number[]; // 条件类型的参数,填法根据conditionType表判断 + price: number; // 商品价格 + productID: string; // 商品id支付时使用 + consume: string; // 消耗资源(这里优先rmb的price价格,其次资源消耗) + reward: string; // 任务奖励,格式:1&3&1(类型&id&数量) 类型定义:1.英雄,2.物品 + rebate: number; // 折扣用于显示 + buyCnt: number; // 购买多少次后消失,原来的count字段 + + rewardInter: RewardInter[] = []; + parent: PopUpShopPackage; + hasBoughtCnt: number = 0; + isPushing: boolean = false; // 是否有推送 + code: string = ''; // 推送唯一code + beginTime: number = 0; // 推送开始时间 + endTime: number = 0; // 推送结束时间 + + constructor(data: PopUpShopItemInDb, parent: PopUpShopPackage) { + this.id = data.id; + this.conditionParam = parseNumberList(data.conditionParam); + this.price = data.price; + this.productID = data.productID; + this.consume = data.consume; + this.reward = data.reward; + this.rewardInter = stringToRewardInter(data.reward); + this.rebate = data.rebate; + this.buyCnt = data.buyCnt; + this.parent = parent; + } + + public setPlayerRecords(data: ActivityPopUpShopModelType, item: ActivityPopUpShopItem) { + this.code = data.code; + this.beginTime = data.beginTime.getTime(); + this.endTime = data.endTime.getTime(); + this.hasBoughtCnt = item.hasBoughtCnt; + this.isPushing = true; + } + + public checkItemCanPush(conditionType: POP_UP_SHOP_CONDITION_TYPE, param: PopUpConditionParamInter) { + console.log('##### xyz?1', this.hasBoughtCnt >= this.buyCnt) + if(this.hasBoughtCnt >= this.buyCnt) return false; + console.log('##### xyz?2', this.parent.getVipMaxPrice(), this.price, this.parent.getVipMaxPrice() < this.price) + if(this.parent.getVipMaxPrice() < this.price) return false; + console.log('##### xyz?3', this.checkKeyTime()) + if(!this.checkKeyTime()) return false + + console.log('##### xyz?4', conditionType, this.conditionParam, param) + switch(conditionType) { + case POP_UP_SHOP_CONDITION_TYPE.LV_TO: + return param.oldLv < this.conditionParam[0] && param.newLv >= this.conditionParam[0]; + case POP_UP_SHOP_CONDITION_TYPE.GET_HERO_BY_QUALITY: + return param.quality == this.conditionParam[0]; + case POP_UP_SHOP_CONDITION_TYPE.GACHA_RES_NOT_ENOUGH: + case POP_UP_SHOP_CONDITION_TYPE.TERAPH_RES_NOT_ENOUGH: + return true; + default: + return false; + } + } + + public checkKeyTime() { + let keyItem = this.parent.keyItem; + console.log('####', keyItem) + for(let key of keyItem) { + let hasCurKey = this.rewardInter.find(cur => cur.id == key.gid); + console.log('#### hasCurKey', hasCurKey, key.hasBoughtCnt, key.max) + if(hasCurKey && key.hasBoughtCnt > key.max) return false; + } + return true; + } + + public updateItem(data: ActivityPopUpShopItem) { + this.hasBoughtCnt = data.hasBoughtCnt; + return new PopUpShopItemShow(this); + } +} + +// 关键道具使用次数 +export class PopUpShopKeyItem { + gid: number; // 关键资源id + max: number; // 关键资源上限,Y + + hasBoughtCnt: number = 0; // 已购买次数 + + constructor(data: PopUpShopKeyItemIbDb) { + if(data) { + this.gid = data.gid; + this.max = data.max; + } + } + + addHasBoughtCnt(items: ActivityPopUpShopItem[]) { + console.log('###### addHasBoughtCnt', items) + for(let { rewards, hasBoughtCnt } of items) { + for(let { id, count } of rewards) { + if(id == this.gid) this.hasBoughtCnt += count * hasBoughtCnt; + } + } + } +} + +export class PopUpShopVipLevel { + lv: number; // 几级 + minPayMoney: number; // 最低金额 + maxPayMoney: number; // 最高金额,5000+的填-1 + price: number; // 礼包上限 + + constructor(data: PopUpShopVipLevelInDb) { + this.lv = data.lv; + this.minPayMoney = data.minPayMoney; + this.maxPayMoney = data.maxPayMoney; + this.price = data.price; + } +} + +export interface PopUpConditionParamInter { + oldLv?: number; + newLv?: number; + quality?: number; +} + + +// 用于显示 +class PopUpShopShow { + activityId: number; // 活动id + type: number; // 活动类型 ACTIVITY_TYPE + beginTime: number; // 活动开始时间,13位时间戳 + endTime: number; // 活动开始时间,13位时间戳 + todayIndex: number; // 活动后第几天 + delayDay: number; // 延迟多少天开始 + roundIndex: number; // 如果是周期活动活动轮回第几个周期 + nextRefreshTime: number; // 如果是周期活动,下一次开始时间 + // 以上为通用属性 + items: PopUpShopItemShow[] = []; // 同一类型的礼包都在一个packages下面 + + constructor(data: PopUpShopData) { + let baseData = data.getBaseKeys(); + for(let key in baseData) { + this[key] = baseData[key]; + } + + for(let pkg of data.packages) { + for(let item of pkg.items) { + if(item.isPushing) { + let obj = new PopUpShopItemShow(item); + this.items.push(obj); + } + } + } + } +} + +export class PopUpShopItemShow { + code: string; // 本次推送的code,用于购买中传给param + packageId: number; // 礼包类型id + endTime: number; // 礼包消失时间 + + id: number; // 档位唯一id,升降档的时候按照id顺序排,升档id+,降档id- + price: number; // 商品价格 + productID: string; // 商品id支付时使用 + consume: string; // 消耗资源(这里优先rmb的price价格,其次资源消耗) + reward: string; // 任务奖励,格式:1&3&1(类型&id&数量) 类型定义:1.英雄,2.物品 + rebate: number; // 折扣用于显示 + buyCnt: number; // 需要购买的次数 + hasBoughtCnt: number; // 已购买的次数 + + constructor(data: PopShopItem) { + this.code = data.code; + this.packageId = data.parent.id; + this.endTime = data.endTime; + this.id = data.id; + this.price = data.price; + this.productID = data.productID; + this.consume = data.consume; + this.reward = data.reward; + this.rebate = data.rebate; + this.buyCnt = data.buyCnt; + this.hasBoughtCnt = data.hasBoughtCnt; } } \ No newline at end of file diff --git a/shared/pubUtils/roleUtil.ts b/shared/pubUtils/roleUtil.ts index f8c39d509..b048e8c8f 100644 --- a/shared/pubUtils/roleUtil.ts +++ b/shared/pubUtils/roleUtil.ts @@ -52,7 +52,6 @@ import { ActivityNewHeroGachaModel } from '../db/ActivityNewHeroGacha'; import { ActivityNewHeroGiftModel } from '../db/ActivityNewHeroGift'; import { ActivityNewHeroGKModel } from '../db/ActivityNewHeroGK'; import { ActivityPopUpShopModel } from '../db/ActivityPopUpShop'; -import { ActivityPopUpShopRecordModel } from '../db/ActivityPopUpShopRecord'; import { ActivityRechargeMoneyModel } from '../db/ActivityRechargeMoney'; import { ActivityRefreshShopModel } from '../db/ActivityRefreshShop'; import { ActivityRefreshTaskModel } from '../db/ActivityRefreshTask'; @@ -391,7 +390,6 @@ export async function deletRole(roleId: string) { await ActivityNewHeroGiftModel.deleteMany({ roleId }); await ActivityNewHeroGKModel.deleteMany({ roleId }); await ActivityPopUpShopModel.deleteMany({ roleId }); - await ActivityPopUpShopRecordModel.deleteMany({ roleId }); await ActivityRechargeMoneyModel.deleteMany({ roleId }); await ActivityRefreshShopModel.deleteMany({ roleId }); await ActivityRefreshTaskModel.deleteMany({ roleId }); diff --git a/shared/pubUtils/taskUtil.ts b/shared/pubUtils/taskUtil.ts index 6716b7c59..428f0de41 100644 --- a/shared/pubUtils/taskUtil.ts +++ b/shared/pubUtils/taskUtil.ts @@ -19,15 +19,11 @@ import { ActivityThirtyDaysModel, ActivityThirtyDaysModelType } from '../db/Acti import { ServerlistModel } from '../db/Serverlist'; import { ActivityGrowthFundModel, ActivityGrowthFundModelType } from '../db/ActivityGrowthFund'; import { ActivityBuyRecordsModel } from '../db/ActivityBuyRecords'; -import { PopUpShopData } from '../domain/activityField/popUpShopField'; -import { ActivityPopUpShopModel } from '../db/ActivityPopUpShop'; import { ServerTempModel, ServerTempModelType } from '../db/ServerTemp'; import { TreasureHuntData } from '../domain/activityField/treasureHuntField'; import { ActivityTreasureHuntTaskModel, ActivityTreasureHuntTaskModelType } from '../db/ActivityTreasureHuntTask'; -import { ActivityPopUpShopRecordModel, ActivityPopUpShopRecordModelType } from '../db/ActivityPopUpShopRecord'; import { SevenDaysData } from '../domain/activityField/sevenDaysField'; import moment = require("moment"); -import { GuildModel } from '../db/Guild'; import { RefreshTaskData } from '../domain/activityField/refreshTaskField'; import { ActivityRefreshTaskModel } from '../db/ActivityRefreshTask'; import { ActivityInRemote, transActivityInRemoteToModelType } from '../domain/activityField/activityField'; @@ -868,77 +864,77 @@ export async function accomplishTask(serverId: number, roleId: string, taskType: // console.log('***** popUpShop before', Date.now()); //弹出商店 - { - allActivity = await findActivitiesByTypes([ACTIVITY_TYPE.POP_UP_SHOP]); - for (let activity of allActivity) { - let allTaskData: any[] = JSON.parse(activity.data); - for (let task of allTaskData) { - if (task.taskType == taskType) { - let popShopData = new PopUpShopData(task, activity.activityId); - let beginTime = new Date(); - let endTime = moment(new Date()).add(task.duration, 'h').toDate(); - if (taskType == TASK_TYPE.ROLE_TERAPH_STAGE_UP) {//只要触发就弹出礼包商店 - //推送 - let playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, count, beginTime, endTime); - popShopData.setPlayerRecords(playerRecord) - pushMessage = pushMessage.concat(popShopData); - } else if ( taskType == TASK_TYPE.GACHA_QUALITY_COUNT || taskType == TASK_TYPE.GUILD_ACTIVITY) {//每天统计 - let recordDate = moment(new Date()).startOf('d').toDate() - let recordData: ActivityPopUpShopRecordModelType = await ActivityPopUpShopRecordModel.findRecordData(serverId, activity.activityId, roleId, task.id, task.taskType, recordDate) - let { addCount } = isComplete(roleId, task.taskType, task.taskParam, count, activity.activityId, parma, null); - let oldCount = (recordData && recordData.count) ? recordData.count : 0; - if (oldCount < task.condition && (oldCount + addCount >= task.condition)) {//完成当天任务 - let playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, oldCount + addCount, beginTime, endTime); - popShopData.setPlayerRecords(playerRecord) - pushMessage = pushMessage.concat(popShopData); - } - await ActivityPopUpShopRecordModel.addRecord(serverId, activity.activityId, roleId, task.id, task.taskType, recordDate, addCount) - } else if (taskType == TASK_TYPE.GUILD_TRAIN_COUNT) {//军团练兵场通关层数推送所有团员 - if (task.taskParam[0] == parma.trainId) { - let playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, count, beginTime, endTime); - popShopData.setPlayerRecords(playerRecord) - pushMessage = pushMessage.concat(popShopData); + // { + // allActivity = await findActivitiesByTypes([ACTIVITY_TYPE.POP_UP_SHOP]); + // for (let activity of allActivity) { + // let allTaskData: any[] = JSON.parse(activity.data); + // for (let task of allTaskData) { + // if (task.taskType == taskType) { + // let popShopData = new PopUpShopData(task, activity.activityId); + // let beginTime = new Date(); + // let endTime = moment(new Date()).add(task.duration, 'h').toDate(); + // if (taskType == TASK_TYPE.ROLE_TERAPH_STAGE_UP) {//只要触发就弹出礼包商店 + // //推送 + // let playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, count, beginTime, endTime); + // popShopData.setPlayerRecords(playerRecord) + // pushMessage = pushMessage.concat(popShopData); + // } else if ( taskType == TASK_TYPE.GACHA_QUALITY_COUNT || taskType == TASK_TYPE.GUILD_ACTIVITY) {//每天统计 + // let recordDate = moment(new Date()).startOf('d').toDate() + // let recordData: ActivityPopUpShopRecordModelType = await ActivityPopUpShopRecordModel.findRecordData(serverId, activity.activityId, roleId, task.id, task.taskType, recordDate) + // let { addCount } = isComplete(roleId, task.taskType, task.taskParam, count, activity.activityId, parma, null); + // let oldCount = (recordData && recordData.count) ? recordData.count : 0; + // if (oldCount < task.condition && (oldCount + addCount >= task.condition)) {//完成当天任务 + // let playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, oldCount + addCount, beginTime, endTime); + // popShopData.setPlayerRecords(playerRecord) + // pushMessage = pushMessage.concat(popShopData); + // } + // await ActivityPopUpShopRecordModel.addRecord(serverId, activity.activityId, roleId, task.id, task.taskType, recordDate, addCount) + // } else if (taskType == TASK_TYPE.GUILD_TRAIN_COUNT) {//军团练兵场通关层数推送所有团员 + // if (task.taskParam[0] == parma.trainId) { + // let playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, count, beginTime, endTime); + // popShopData.setPlayerRecords(playerRecord) + // pushMessage = pushMessage.concat(popShopData); - //全服推送 - let code = parma.code; - const guildData = await GuildModel.findByCode(code, serverId, 'members'); - let members = guildData.members.filter(member => { return member != roleId }) - await ActivityPopUpShopModel.addTaskArrayPushMessage(serverId, activity.activityId, members, task.id, task.taskType, count, beginTime, endTime); + // //全服推送 + // let code = parma.code; + // const guildData = await GuildModel.findByCode(code, serverId, 'members'); + // let members = guildData.members.filter(member => { return member != roleId }) + // await ActivityPopUpShopModel.addTaskArrayPushMessage(serverId, activity.activityId, members, task.id, task.taskType, count, beginTime, endTime); - } - } else { - let taskRecord = await ActivityPopUpShopModel.findDataByTaskId(serverId, activity.activityId, roleId, popShopData.id, popShopData.taskType) - let recordData = taskRecord && taskRecord.data ? JSON.parse(taskRecord.data) : null - if (!taskRecord || !taskRecord.isPush) { - let { addCount, record } = isComplete(roleId, task.taskType, task.taskParam, count, activity.activityId, parma, recordData); - if (addCount) { - if (taskType == TASK_TYPE.ROLE_LV || taskType == TASK_TYPE.ROLE_TITLE || taskType == TASK_TYPE.BATTLE_TOWER_LV) { - let playerRecord = await ActivityPopUpShopModel.setTaskCount(serverId, activity.activityId, roleId, task.id, task.taskType, addCount); - //推送 - if (task.condition <= playerRecord.totalCount) { - playerRecord = await ActivityPopUpShopModel.pushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, beginTime, endTime); - popShopData.setPlayerRecords(playerRecord) - pushMessage = pushMessage.concat(popShopData); - } - } else { - let playerRecord = await ActivityPopUpShopModel.addTaskCount(serverId, activity.activityId, roleId, task.id, task.taskType, addCount); - //推送 - if (task.condition <= playerRecord.totalCount) { - playerRecord = await ActivityPopUpShopModel.pushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, beginTime, endTime); - popShopData.setPlayerRecords(playerRecord) - pushMessage = pushMessage.concat(popShopData); - } - } - } - if (record) { - await ActivityPopUpShopModel.addTaskRecord(serverId, activity.activityId, roleId, task.id, task.taskType, JSON.stringify(record)); - } - } - } - } - } - } - } + // } + // } else { + // let taskRecord = await ActivityPopUpShopModel.findDataByTaskId(serverId, activity.activityId, roleId, popShopData.id, popShopData.taskType) + // let recordData = taskRecord && taskRecord.data ? JSON.parse(taskRecord.data) : null + // if (!taskRecord || !taskRecord.isPush) { + // let { addCount, record } = isComplete(roleId, task.taskType, task.taskParam, count, activity.activityId, parma, recordData); + // if (addCount) { + // if (taskType == TASK_TYPE.ROLE_LV || taskType == TASK_TYPE.ROLE_TITLE || taskType == TASK_TYPE.BATTLE_TOWER_LV) { + // let playerRecord = await ActivityPopUpShopModel.setTaskCount(serverId, activity.activityId, roleId, task.id, task.taskType, addCount); + // //推送 + // if (task.condition <= playerRecord.totalCount) { + // playerRecord = await ActivityPopUpShopModel.pushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, beginTime, endTime); + // popShopData.setPlayerRecords(playerRecord) + // pushMessage = pushMessage.concat(popShopData); + // } + // } else { + // let playerRecord = await ActivityPopUpShopModel.addTaskCount(serverId, activity.activityId, roleId, task.id, task.taskType, addCount); + // //推送 + // if (task.condition <= playerRecord.totalCount) { + // playerRecord = await ActivityPopUpShopModel.pushMessage(serverId, activity.activityId, roleId, task.id, task.taskType, beginTime, endTime); + // popShopData.setPlayerRecords(playerRecord) + // pushMessage = pushMessage.concat(popShopData); + // } + // } + // } + // if (record) { + // await ActivityPopUpShopModel.addTaskRecord(serverId, activity.activityId, roleId, task.id, task.taskType, JSON.stringify(record)); + // } + // } + // } + // } + // } + // } + // } // console.log('***** popUpShop after', Date.now()); // console.log('***** growthFund before', Date.now()); //主线成长基金 diff --git a/shared/resource/jsons/dic_zyz_rmb.json b/shared/resource/jsons/dic_zyz_rmb.json index 716fb197b..3c8c6521b 100644 --- a/shared/resource/jsons/dic_zyz_rmb.json +++ b/shared/resource/jsons/dic_zyz_rmb.json @@ -231,10 +231,87 @@ "gameCoin": 1 }, { - "productID": "com.bantu.sgzzyz.yb34", + "productID": "com.bantu.sgzzyz.yb34-1", + "type": 24, + "price": 30, + "message": "弹出礼包-玩家等级5级", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-2", + "type": 24, + "price": 98, + "message": "弹出礼包-玩家等级10级", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-3", "type": 24, "price": 198, - "message": "弹出礼包-图纸任选礼包", + "message": "弹出礼包-玩家等级15级", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-4", + "type": 24, + "price": 30, + "message": "弹出礼包-获得金将1", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-5", + "type": 24, + "price": 98, + "message": "弹出礼包-获得金将2", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-6", + "type": 24, + "price": 198, + "message": "弹出礼包-获得金将3", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-7", + "type": 24, + "price": 30, + "message": "弹出礼包-抽卡升降礼包1", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-8", + "type": 24, + "price": 98, + "message": "弹出礼包-抽卡升降礼包2", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-9", + "type": 24, + "price": 198, + "message": "弹出礼包-抽卡升降礼包3", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-10", + "type": 24, + "price": 30, + "message": "弹出礼包-强化神兽1", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-11", + "type": 24, + "price": 98, + "message": "弹出礼包-强化神兽2", + "gameCoin": 1 + }, + { + "productID": "com.bantu.sgzzyz.yb34-12", + "type": 24, + "price": 198, + "message": "弹出礼包-强化神兽3", "gameCoin": 1 }, {