diff --git a/game-server/app/servers/gm/handler/gmOrderHandler.ts b/game-server/app/servers/gm/handler/gmOrderHandler.ts new file mode 100644 index 000000000..de22f7a2b --- /dev/null +++ b/game-server/app/servers/gm/handler/gmOrderHandler.ts @@ -0,0 +1,119 @@ +import { Application, BackendSession, pinus } from 'pinus'; +import { genCode, getRandSingleEelm, resResult } from '../../../pubUtils/util'; +import { STATUS } from '../../../consts/statusCode'; +import { PAY_TYPE } from '../../../consts'; +import _ = require('underscore'); +import { dicRMB } from '../../../pubUtils/dictionary/DicRMB'; +import { getActivityById } from '../../../services/activity/activityService'; +import { UserOrderModel } from '../../../db/UserOrder'; +import { makeOrder, settleOrder, settleOrderAli, settleOrderWx } from '../../../services/orderService'; +import { getActivityProducts } from '../../../services/gmService'; +import { ActivityGroupModel } from '../../../db/ActivityGroup'; + +export interface Cascader { + value: number|string; + label: number|string; + children?: Cascader[]; +} + +export default function (app: Application) { + return new GmOrderHandler(app); +} + +export class GmOrderHandler { + constructor(private app: Application) { + } + + async getActivitiesCanBuy(msg: { serverId: number }, session: BackendSession) { + const { serverId } = msg; + + let groups = await ActivityGroupModel.findByServerId(serverId); + let result: Cascader[] = []; + for (let groupData of groups) { + let activities: Cascader[] = []; + for (let activityId of groupData.activities) { + let activityData = await getActivityById(activityId); + let products = getActivityProducts(activityData); + if(products) { + let children = products.filter(cur => !!cur); + if(children.length > 0) { + activities.push({ + value: activityData.activityId, + label: activityData.name, + children + }); + } + } + } + if(activities.length > 0) { + result.push({ + value: groupData.groupId, + label: groupData.groupName, + children: activities + }); + } + } + + return resResult(STATUS.SUCCESS, result); + } + + getParamStr(beginTimeStamp: number, monopolyActivityId: number) { + let param = {}; + if(beginTimeStamp) { + param['beginTimeStamp'] = beginTimeStamp; + } + if(monopolyActivityId) { + param['monopolyActivityId'] = monopolyActivityId; + } + return JSON.stringify(param); + } + + /** + * @description 虚拟充值 + * @param {{productID:string, magicWord:string, paramStr: string }} msg + * @param {BackendSession} session + * @memberof orderHandler + */ + async applyOrder(msg: { productID: string, activityId: number, beginTimeStamp: number, monopolyActivityId: number }, session: BackendSession) { + const { productID, activityId, beginTimeStamp, monopolyActivityId } = msg; + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const sid = session.get('sid'); + const roleName = session.get('roleName'); + + + let payType = PAY_TYPE.TEST + //如果有特殊情况,activityId可为0 + if (!productID || !_.isString(productID)) { + return resResult(STATUS.WRONG_PARMS); + } + + //商品价格信息 + let productInfo = dicRMB.get(productID) + if (!productInfo) { + console.log('productID', productID) + return resResult(STATUS.NO_PRODUCT_ID); + } + + let price = productInfo.price;//价格 + let productType = productInfo.type;//类型 + let message = productInfo.message;//商品信息 + let localOrderID = genCode(32);//本地订单号 + let orderID = '';//平台订单号 + let sdkOrderInfo = null;//客户端需要的平台订单信息 + + let activityData = await getActivityById(activityId); + if (!activityData) return resResult(STATUS.ACTIVITY_MISSING); + let orderInfo = await UserOrderModel.applyOrder(serverId, roleId, productID, localOrderID, orderID, price, payType, activityId, this.getParamStr(beginTimeStamp, monopolyActivityId), message); + + //订单成功 + if(!orderInfo) { + return resResult(STATUS.NO_ORDER); + } + let result = await settleOrder(orderInfo, serverId, sid); + orderInfo = await UserOrderModel.success(roleId, localOrderID, JSON.stringify(result)); + console.log(`测试支付完成!!!!!!!!!!!!! serverId:${serverId}, productID:${productID}, productType:${productType}, roleId:${roleId}, localOrderID:${localOrderID}, payType:${payType}`) + return resResult(STATUS.SUCCESS, result); + } +} \ No newline at end of file diff --git a/game-server/app/services/gmService.ts b/game-server/app/services/gmService.ts index 6add1c61a..c3b239b9d 100644 --- a/game-server/app/services/gmService.ts +++ b/game-server/app/services/gmService.ts @@ -1,5 +1,5 @@ import Marquee, { MarqueeType, MarqueeModel } from "../db/Marquee"; -import { GM_MAIL_STATUS, GM_MAIL_TYPE, MAIL_TIME_TYPE, MARQUEE_SHOW_TYPE, MARQUEE_TIME_TYPE, REF_CIRCLE_MAIL_TIME, SERVER_STATUS } from "../consts"; +import { ACTIVITY_TYPE, GM_MAIL_STATUS, GM_MAIL_TYPE, MAIL_TIME_TYPE, MARQUEE_SHOW_TYPE, MARQUEE_TIME_TYPE, REF_CIRCLE_MAIL_TIME, SERVER_STATUS } from "../consts"; import { scheduleJob, scheduledJobs, Job } from 'node-schedule'; import { createMarqueeMsg as sysCreateMarqueeMsg, pushMarqueeMsg as sysPushMarqueeMsg } from './sysChatService'; import { GroupMessageType } from "../db/GroupMessage"; @@ -12,9 +12,20 @@ import GMMail, { GMMailModel, GMMailType } from '../db/GMMail'; import moment = require("moment"); import { getSeconds, nowSeconds } from "../pubUtils/timeUtil"; import { CreateServerParam } from "../domain/backEndField/params"; +import { SignInData } from "../domain/activityField/signInField"; import { RegionModel, RegionType } from "../db/Region"; import { GMMail as StategyMail } from "../db/ServerStategy"; import { uniq } from "underscore"; +import { ActivityModelType } from "../db/Activity"; +import { dicRMB } from "../pubUtils/dictionary/DicRMB"; +import { LimitShopData } from "../domain/activityField/limitShopField"; +import { YuanBaoShopData } from "../domain/activityField/yuanBaoShopField"; +import { MonthlyTicketData } from "../domain/activityField/monthlyTicketField"; +import { DailyRMBGiftsData } from "../domain/activityField/dailyRMBGiftsField"; +import { PopUpShopData } from "../domain/activityField/popUpShopField"; +import { GrowthFundData } from "../domain/activityField/growthFundField"; +import { TreasureHuntData } from "../domain/activityField/treasureHuntField"; +import { RefreshShopData } from "../domain/activityField/refreshShopField"; // —————————————— 跑马灯 —————————————— // // 初始 @@ -188,4 +199,85 @@ export async function createNewServer(region: RegionType ,serverId: number, para if(params.openMail) await sendOpenServerMail('openMail', params.openMail, newServer, uid); if(params.circleMail) await sendOpenServerMail('circleMail', params.circleMail, newServer, uid); await RegionModel.newServer(region.id, newServer); +} + +function getDicRMB(productID: string) { + let dic = dicRMB.get(productID); + if(!dic) return null + return { + value: dic.productID, + label: `${dic.message}(${dic.productID})`, + } +}; + +export function getActivityProducts(activity: ActivityModelType) { + switch(activity.type) { + case ACTIVITY_TYPE.SIGN_IN_VIP: // 高级签到 + { + let data = new SignInData(activity, 0); + return [getDicRMB(data.productID)]; + } + case ACTIVITY_TYPE.NEW_PLAYER_LIMIT_PACKAGE: // 新手限定RMB购买礼包 + case ACTIVITY_TYPE.LIMIT_PACKAGE_SHOP_DAILY: // 日限购 + case ACTIVITY_TYPE.LIMIT_PACKAGE_SHOP_WEEKLY: // 周限购 + { + let data = new LimitShopData(activity, 0); + return data.list.map(item => { + return getDicRMB(item.productID); + }); + } + case ACTIVITY_TYPE.YUAN_BAO_SHOP: // 元宝 + { + let data = new YuanBaoShopData(activity, 0); + return data.list.map(item => { + return getDicRMB(item.productID); + }); + } + case ACTIVITY_TYPE.MONTHLY_TICKET_1: + case ACTIVITY_TYPE.MONTHLY_TICKET_2: + { + let data = new MonthlyTicketData(activity, 0); + return [getDicRMB(data.productID)]; + } + case ACTIVITY_TYPE.DAILY_RMB_GIFTS: + { + let data = new DailyRMBGiftsData(activity, 0); + return [getDicRMB(data.productID)]; + } + case ACTIVITY_TYPE.POP_UP_SHOP://弹出礼包 + { + let data = new PopUpShopData(activity, 0); + return [getDicRMB(data.productID)]; + } + case ACTIVITY_TYPE.GROWTH_FUND_MAIN_VIP: //主线成长基金(高阶) + case ACTIVITY_TYPE.GROWTH_FUND_TOWER_VIP://镇念塔成长基金(高阶) + case ACTIVITY_TYPE.GROWTH_FUND_MAIN_ELITE_VIP://精英成长基金(高阶) + { + let data = new GrowthFundData(activity, 0); + return data.list.map(item => { + return getDicRMB(item.productID); + }); + } + case ACTIVITY_TYPE.TREASURE_HUNT: + { + let data = new TreasureHuntData(activity, 0); + let shop = data.shop; + return shop.list.map(item => { + return getDicRMB(item.productID); + }); + } + case ACTIVITY_TYPE.REFRESH_SHOP: + { + let data = new RefreshShopData(activity, 0); + let products: { label: string, value: string }[] = []; + for(let shop of data.list) { + for(let item of shop.items) { + products.push(getDicRMB(item.productID)); + } + } + return products; + } + + } + return false } \ No newline at end of file diff --git a/game-server/app/services/rankService.ts b/game-server/app/services/rankService.ts index ddec25271..fdf4296c0 100644 --- a/game-server/app/services/rankService.ts +++ b/game-server/app/services/rankService.ts @@ -720,6 +720,7 @@ export class Rank { let myId = this.decodeFields(this.key, field); const scores = this.decodeScore(rankFromDb[ii + 1]); const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId)); + if(!info) continue; const userInfo = JSON.parse(info); let param: RoleRankInfo | GuildRankInfo; diff --git a/shared/db/Activity.ts b/shared/db/Activity.ts index 1b24de4cc..d75969775 100644 --- a/shared/db/Activity.ts +++ b/shared/db/Activity.ts @@ -22,7 +22,8 @@ export default class Activity extends BaseModel { type: number; // 活动类型 @prop({ required: true }) data: string; // 活动表中的数据 - + @prop({ required: true }) + name: string; // 活动名 @prop({ required: true }) timeType: number; // 活动时间类型 ACTIVITY_TIME_TYPE 1.服务器开启时间 2.角色创建时间 3.指定开启时间(beginTime,endTime) diff --git a/shared/db/ActivityGroup.ts b/shared/db/ActivityGroup.ts index 771bb4d70..283c7bd15 100644 --- a/shared/db/ActivityGroup.ts +++ b/shared/db/ActivityGroup.ts @@ -36,6 +36,11 @@ export default class Activity_Group extends BaseModel { return result; } + public static async findByServerId(serverId: number) { + let result: ActivityGroupModelType[] = await ActivityGroupModel.find({ serverIds: serverId }).lean(); + return result; + } + //查询组 public static async findGroupsData(groupIds: number[]) { let result: ActivityGroupModelType[] = await ActivityGroupModel.find({ groupId: { $in: groupIds } }).lean(); diff --git a/shared/domain/activityField/activityField.ts b/shared/domain/activityField/activityField.ts index 06f12eaac..54c2892b4 100644 --- a/shared/domain/activityField/activityField.ts +++ b/shared/domain/activityField/activityField.ts @@ -96,6 +96,7 @@ export class ActivityInRemote { days: number; // 活动持续天数 timeType=1、2 delayDay: number; // 迟几天开启活动,0表示按照规定时间开启 interval: number; // 周期性活动时间间隔,秒 + name: string; constructor(activity?: ActivityModelType) { this.groupId = activity.groupId; @@ -108,6 +109,7 @@ export class ActivityInRemote { this.days = activity.days; this.delayDay = activity.delayDay; this.interval = activity.interval; + this.name = activity.name; } } diff --git a/shared/resource/jsons/dic_api.json b/shared/resource/jsons/dic_api.json index 2ffe223ca..5317d1982 100644 --- a/shared/resource/jsons/dic_api.json +++ b/shared/resource/jsons/dic_api.json @@ -775,5 +775,19 @@ "name": "设置武将", "module": "user", "type": "update" + }, + { + "id": 112, + "api": "gm.gmOrderHandler.getActivitiesCanBuy", + "name": "获取可以购买的活动", + "module": "order", + "type": "get" + }, + { + "id": 113, + "api": "gm.gmOrderHandler.applyOrder", + "name": "虚拟充值", + "module": "order", + "type": "update" } ] \ No newline at end of file