diff --git a/game-server/app/servers/activity/handler/popUpShopHandler.ts b/game-server/app/servers/activity/handler/popUpShopHandler.ts new file mode 100644 index 000000000..914f8dd99 --- /dev/null +++ b/game-server/app/servers/activity/handler/popUpShopHandler.ts @@ -0,0 +1,58 @@ +import { Application, BackendSession } from 'pinus'; +import { resResult } from '../../../pubUtils/util'; +import { STATUS, } from '../../../consts'; +import { getPlayerPopUpShopData, makeDailyRMBGiftsReward } from '../../../services/popUpShopService'; + +export default function (app: Application) { + return new PopUpShopHandler(app); +} + +export class PopUpShopHandler { + constructor(private app: Application) { + } + + /************************弹出式商店****************************/ + + /** + * @description 获取弹出式商店数据 + * @param {{ }} msg + * @param {{ activityId: number}} msg + * @param {BackendSession} session + * @memberof PopUpShopHandler + */ + async getPopUpShopActivity(msg: { activityId: number }, session: BackendSession) { + const { activityId } = msg; + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + + let playerData = await getPlayerPopUpShopData(activityId, serverId, roleId) + if (!playerData) return resResult(STATUS.ACTIVITY_THIRTY_DAYS_END); + + return resResult(STATUS.SUCCESS, { playerData }); + } + + /** + * @description 购买礼包 + * @param {{ activityId: number}} msg + * @param {BackendSession} session + * @memberof PopUpShopHandler + */ + async buyGift(msg: { activityId: number }, session: BackendSession) { + const { activityId } = msg; + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const sid = session.get('sid'); + const roleName = session.get('roleName'); + const funcs: number[] = session.get('funcs'); + + let playerData = await getPlayerPopUpShopData(activityId, serverId, roleId) + if (!playerData) return resResult(STATUS.ACTIVITY_THIRTY_DAYS_END); + // let item = playerData.findTodayItem(); + // let productID = item.productID; + // let resulet = await makeDailyRMBGiftsReward(roleId, roleName, sid, serverId, funcs, + // activityId, productID) + + return resResult(STATUS.SUCCESS, {}); + } + +} diff --git a/game-server/app/services/popUpShopService.ts b/game-server/app/services/popUpShopService.ts new file mode 100644 index 000000000..185bc53e4 --- /dev/null +++ b/game-server/app/services/popUpShopService.ts @@ -0,0 +1,82 @@ +import { ACTIVITY_TYPE, TASK_TYPE } from '../consts'; +import { ActivityModel, ActivityModelType } from '../db/Activity'; +import { ActivityDailyRMBGiftsModel, ActivityDailyRMBGiftsModelType } from '../db/ActivityDailyRMBGifts'; +import { PopUpShopData, PopUpShopItem } from '../domain/activityField/PopUpSHopField'; +import { RoleModel } from '../db/Role'; +import moment = require('moment'); +import { UserOrderModel, UserOrderModelType } from '../db/UserOrder'; +import { RewardParam } from '../domain/activityField/rewardField'; +import { addReward, stringToRewardParam } from './giftPackageService'; +import { ActivityPopUpShopModel, ActivityPopUpShopModelType } from '../db/ActivityPopUpShop'; + +/** + * 获取活动数据 + * + * @param {number} serverId 区Id + * @param {number} type 活动类型 ACTIVITY_TYPE + * @param {string} roleId 角色Id + * + */ + +export async function popUpShopActivity(serverId: number, roleId: string) { + let activityArray: ActivityModelType[] = await ActivityModel.findOpenActivityByType(ACTIVITY_TYPE.POP_UP_SHOP, new Date()) + activityArray = activityArray.sort((a, b) => { + return b.activityId - a.activityId + }); + if (activityArray.length == 0) { + return null; + } + let activityData = activityArray[0]; + let playerData = await getPlayerPopUpShopData(activityData.activityId, serverId, roleId); + return playerData +} + +/** + * 玩家活动数据 + * + * @param {number} serverId 区Id + * @param {number} activityId 活动Id + * @param {string} roleId 角色Id + * + */ +export async function getPlayerPopUpShopData(activityId: number, serverId: number, roleId: string) { + let activityData: ActivityModelType = await ActivityModel.findActivity(activityId, true); + let playerRecords: ActivityPopUpShopModelType[] = await ActivityPopUpShopModel.findAllOpenData(serverId, activityId, roleId); + + let allPlayerShop = []; + let allTaskData = JSON.parse(activityData.data); + for (let taskData of allTaskData) { + let playerData = new PopUpShopData(taskData); + let taskId = playerData.taskId; + let index = playerRecords.findIndex(obj => { return obj && obj.taskId == taskId }); + if (index != -1) { + playerData.setPlayerRecords(playerRecords[index]) + } + allPlayerShop.push(playerData) + } + return allPlayerShop; +} + +/** + * 结算购买礼包的奖励 + * + * @param {number} serverId 区Id + * @param {number} activityId 活动Id + * @param {string} roleId 角色Id + * @param {string} productID 商品ID + * + */ +export async function makeDailyRMBGiftsReward(roleId: string, roleName: string, sid: string, serverId: number, funcs: number[], + activityId: number, productID: string) { + // let activityData: ActivityModelType = await ActivityModel.findActivity(activityId, true); + // let playerData = new popUpSHopField(activityData); + // let bigGiftProductID = playerData.productID; + // if (bigGiftProductID == productID) {//一次性购买7天礼包 + // return { goods: [], addHeros: [] } + // } else { + // let item = playerData.findProduct(productID); + // let rewardParamArr: Array = stringToRewardParam(item.reward); + // let result = await addReward(roleId, roleName, sid, serverId, funcs, rewardParamArr) + // return result + // } +} diff --git a/shared/db/ActivityPopUpShop.ts b/shared/db/ActivityPopUpShop.ts new file mode 100644 index 000000000..d4b574237 --- /dev/null +++ b/shared/db/ActivityPopUpShop.ts @@ -0,0 +1,81 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; + + +/** + * 购买记录 +*/ + +export class BuyRecord { + @prop({ required: true }) + id: number; //物品id标识 + @prop({ required: true }) + time: Date; //购买时间 +} + +/** + * 活动系统 - 弹出商店 +*/ +@index({ roleId: 1 }) + +export default class ActivityPopUpShop 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 }) + taskId: number; // 任务id + @prop({ required: true }) + records: BuyRecord[]; // 购买记录 + + //购买奖励的记录 + public static async addRecord(serverId: number, activityId: number, roleId: string, taskId: number, id: number) { + let nowDate = new Date(); + let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOneAndUpdate({ + serverId, roleId, activityId, taskId, + beginTime: { $lt: nowDate }, endTime: { $gt: nowDate } + }, + { $push: { records: { id, time: new Date() } } }, { upsert: true, new: true }).lean(true); + return result; + } + + //查询现在正在进行的活动数据 + 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 } + }).lean(true); + return result; + } + + //根据活动taskId查询现在正在进行的活动数据 + public static async findOpenDataByTaskId(serverId: number, activityId: number, roleId: string, taskId: number) { + let nowDate = new Date(); + let result: ActivityPopUpShopModelType = await ActivityPopUpShopModel.findOne({ + serverId, roleId, activityId, taskId, + beginTime: { $lt: nowDate }, endTime: { $gt: nowDate } + }).lean(true); + return result; + } + + //删除活动领取记录 + public static async deleteActivity(serverId: number, activityId: number, roleId: string, taskId: number) { + let nowDate = new Date(); + await ActivityPopUpShopModel.deleteMany({ + roleId, activityId, taskId, + beginTime: { $lt: nowDate }, endTime: { $gt: nowDate } + }); + } +} + +export const ActivityPopUpShopModel = getModelForClass(ActivityPopUpShop); + +export interface ActivityPopUpShopModelType extends Pick, keyof ActivityPopUpShop> { } +export type ActivityPopUpShopModelTypeParam = Partial; // 将所有字段变成可选项 \ No newline at end of file diff --git a/shared/domain/activityField/popUpShopField.ts b/shared/domain/activityField/popUpShopField.ts new file mode 100644 index 000000000..d2475be93 --- /dev/null +++ b/shared/domain/activityField/popUpShopField.ts @@ -0,0 +1,72 @@ +import { DAILYRMBGIFTS_DAYS } from '../../consts'; +import { ActivityModelType } from '../../db/Activity'; +import { ActivityPopUpShopModelType } from '../../db/ActivityPopUpShop'; +import { deltaDays } from '../../pubUtils/util'; +import { ActivityBase } from './activityField'; + +// 商品数据 +export class PopUpShopItem { + id: number; // 第几个,从1开始 + productID: string; // 商品id支付时使用 + reward: string; //任务奖励,格式:1&3&1(类型&id&数量) 类型定义:1.英雄,2.物品 + countMax: number = 0; //可购买的最大次数,0表示不限制 + name: string; //名字 + + buyCount: number = 0; //购买过的次数 + + constructor(data: any) { + this.id = data.id; + this.reward = data.reward; + this.countMax = data.countMax; + this.productID = data.productID; + this.name = data.name; + } +} + +// 弹框商店 +export class PopUpShopData { + name: string = '';//活动名称 + taskId: number = 0;//id + list: Array = [];//每件商品信息 + + + public findItem(id: number) { + let index = this.list.findIndex(obj => { return obj && obj.id === id }); + return (index != -1) ? this.list[index] : null + } + + //全部领取完成 + public isComplete() { + for (let item of this.list) { + if (item.countMax == 0 || + (item.countMax > 0 && item.buyCount < item.countMax)) { + return false + } + } + return true; + } + + //解析玩家购买记录 + public setPlayerRecords(data: ActivityPopUpShopModelType) { + if (!data) { + return; + } + for (let item of this.list) { + let buyRecords = data.records.filter(obj => { return obj && obj.id === item.id }); + item.buyCount = buyRecords.length; + } + } + + + public initData(data: any) { + this.taskId = data.taskId; + let arr = data.data; + for (let obj of arr) { + this.list.push(new PopUpShopItem(obj)) + } + } + + constructor(activityData: any) { + this.initData(activityData) + } +} \ No newline at end of file