diff --git a/gm-server/app/controller/game.ts b/gm-server/app/controller/game.ts index 1e2eecdd2..1ed1a2e9d 100644 --- a/gm-server/app/controller/game.ts +++ b/gm-server/app/controller/game.ts @@ -16,7 +16,39 @@ export default class GameController extends Controller { public async getServerList() { const { ctx } = this; - ctx.body = await ctx.service.game.getServerList(); + const { page, pageSize, sortField, sortOrder, form } = ctx.request.body; + + ctx.body = await ctx.service.game.getServerList(page, pageSize, sortField, sortOrder, form); + return + } + + public async getServerStategyList() { + const { ctx } = this; + const { page, pageSize, sortField, sortOrder, form } = ctx.request.body; + + ctx.body = await ctx.service.game.getServerStategyList(page, pageSize, sortField, sortOrder, form); + return + } + + public async updateServerStategy() { + const { ctx } = this; + const { values } = ctx.request.body; + + ctx.body = await ctx.service.game.updateServerStategy(values); + return + } + + public async createNewServer() { + const { ctx } = this; + const { name, openTime, serverType, stategyId } = ctx.request.body; + ctx.body = await ctx.service.game.createNewServer(name, openTime, serverType, stategyId); + return + } + + public async updateServer() { + const { ctx } = this; + const { id, name, groupName, serverStatus, } = ctx.request.body; + ctx.body = await ctx.service.game.updateServer(id, name, groupName, serverStatus); return } diff --git a/gm-server/app/router.ts b/gm-server/app/router.ts index f1ee981bb..668a0081e 100644 --- a/gm-server/app/router.ts +++ b/gm-server/app/router.ts @@ -52,6 +52,11 @@ export default (app: Application) => { router.post('/api/game/getdicactivitytype', tokenParser, controller.game.getDicActivityType); router.post('/api/game/getdictasktype', tokenParser, controller.game.getDicTaskType); + router.post('/api/game/getserverstategylist', controller.game.getServerStategyList); + router.post('/api/game/updateserverstategy', controller.game.updateServerStategy); + router.post('/api/game/createnewserver', controller.game.createNewServer); + router.post('/api/game/updateserver', controller.game.updateServer); + router.post('/api/activity/getactivitylist', tokenParser, controller.activity.getActivityList); router.post('/api/activity/updateactivity', tokenParser, controller.activity.updateActivity); router.post('/api/activity/deleteactivity', tokenParser, controller.activity.deleteActivity); diff --git a/gm-server/app/service/Game.ts b/gm-server/app/service/Game.ts index 02499cc97..622d89d40 100644 --- a/gm-server/app/service/Game.ts +++ b/gm-server/app/service/Game.ts @@ -1,12 +1,13 @@ import { Service } from 'egg'; import { STATUS } from '@consts'; import { GameModel } from '@db/Game'; -import { ServerlistModel } from '@db/Serverlist'; +import { ServerlistModel, ServerlistUpdate } from '@db/Serverlist'; import { gameData } from '@pubUtils/data'; import { DicHero } from '@pubUtils/dictionary/DicHero'; import { DicRMB } from '@pubUtils/dictionary/DicRMB'; import { DicActivityType } from '@pubUtils/dictionary/DicActivityType'; import { DicTaskType } from '@pubUtils/dictionary/DicTaskType'; +import { ServerStategyModel, ServerStategyTypeParam } from '@db/ServerStategy'; /** * Test Service @@ -39,9 +40,8 @@ export default class Game extends Service { } - public async getServerList() { + public async getServerList(page: number, pageSize: number, sortField: string, sortOrder: string, form: { id?: number, serverId?: string|number, name?: string, groupName?: string, groupId?: number, serverType?: string } = {}) { const { ctx } = this; - const { page, pageSize, sortField, sortOrder, form } = ctx.request.body; const list = await ServerlistModel.findByCondition(page, pageSize, sortField, sortOrder, form); const total = await ServerlistModel.countByCondition( form ) @@ -50,6 +50,66 @@ export default class Game extends Service { }); } + public async getServerStategyList(page: number, pageSize: number, sortField: string, sortOrder: string, form: { id?: number, name?: string }) { + const { ctx } = this; + + const list = await ServerStategyModel.findByCondition(page, pageSize, sortField, sortOrder, form); + const total = await ServerStategyModel.countByCondition( form ) + return ctx.service.utils.resResult(STATUS.SUCCESS, { + list, total + }); + } + + public async updateServerStategy(values: ServerStategyTypeParam & {id: string|number}) { + const { ctx } = this; + + try { + await ServerStategyModel.updateServerStategy(values, ctx.user?.uid); + + } catch(e) { + return ctx.service.utils.resResult(STATUS.INTERNAL_ERR, null, e.stack); + } + return ctx.service.utils.resResult(STATUS.SUCCESS); + } + + public async createNewServer(name: string, openTime: number, serverType: string, stategyId: number ) { + const { ctx } = this; + + try { + let stategy = await ServerStategyModel.findBySId(stategyId); + if(!stategy) return ctx.service.utils.resResult(STATUS.GM_STATEGY_NOT_FOUND); + + await ServerlistModel.newServer({ name, openTime: new Date(openTime), serverType }, stategy, ctx.user?.uid); + + } catch(e) { + return ctx.service.utils.resResult(STATUS.INTERNAL_ERR, null, e.stack); + } + return ctx.service.utils.resResult(STATUS.SUCCESS); + } + + public async updateServer(id: number, name: string, groupName: string, serverStatus: number ) { + const { ctx } = this; + + try { + let server = await ServerlistModel.findByServerId(id); + if(!server) return ctx.service.utils.resResult(STATUS.GM_SERVER_NOT_FOUND); + + if(server.groupName != groupName) { + await ServerlistModel.updateGroupName(server.groupId, groupName); + } + let update: ServerlistUpdate = {}; + if(name) update['name'] = name; + if(groupName) update['groupName'] = groupName; + if(serverStatus) update['serverStatus'] = serverStatus; + + await ServerlistModel.updateByServerId(id, update); + + } catch(e) { + return ctx.service.utils.resResult(STATUS.INTERNAL_ERR, null, e.stack); + } + return ctx.service.utils.resResult(STATUS.SUCCESS); + } + public async getDicHero() { let list: DicHero[] = []; for(let [heroId, hero] of gameData.hero) { diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 317849ff9..beb501da0 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -34,7 +34,11 @@ export const COUNTER = { EID: { name: 'eid', def: 1 }, ROLE: { name: 'role', def: 1 }, ACTIVITY: { name: 'aid', def: 1 }, - ACTIVITY_GROUP: { name: 'agid', def: 1 } + ACTIVITY_GROUP: { name: 'agid', def: 1 }, + SERVER_STATEGY: { name: 'stategy', def: 1 }, + SERVER_GROUP: { name: 'group', def: 1 }, + SERVER_BY_TYPE: { name: 'serverby', def: 1 }, + SERVER: { name: 'server', def: 1 } }; export const DEFAULT_HEROES = [19, 53, 46, 40, 22, 56, 32, 28, 18]; diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 10c6ff72f..56eec27c5 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -377,9 +377,11 @@ export const STATUS = { GM_HERO_NOT_FOUND: { code: 60011, simStr: '未找到武将' }, GM_PVP_DEFENSE_NOT_FOUND: { code: 60012, simStr: '该玩家未保存防守阵' }, GM_PVP_DEFENSE_HERO_NOT_FOUND: { code: 60013, simStr: '该守阵没有该武将' }, - GM_JSON_FORMAT_ERR: { code: 60005, simStr: 'json格式错误' }, - GM_CAN_NOT_DEL_ACT_GROUP: { code: 60006, simStr: '活动组有指向的服务器或活动,不可删除' }, - GM_CAN_NOT_EDIT_ACT: { code: 60007, simStr: '活动期间不可编辑活动' }, + GM_JSON_FORMAT_ERR: { code: 60014, simStr: 'json格式错误' }, + GM_CAN_NOT_DEL_ACT_GROUP: { code: 60015, simStr: '活动组有指向的服务器或活动,不可删除' }, + GM_CAN_NOT_EDIT_ACT: { code: 60016, simStr: '活动期间不可编辑活动' }, + GM_STATEGY_NOT_FOUND: { code: 60017, simStr: '未找到该策略' }, + GM_SERVER_NOT_FOUND: { code: 60018, simStr: '未找到该服' }, // 支付相关状态 70000 - 79999 NO_PRODUCT_ID: { code: 70001, simStr: '无效商品' }, NO_PAY_TYPE: { code: 70002, simStr: '无效支付类型' }, diff --git a/shared/db/Activity.ts b/shared/db/Activity.ts index eac5a75ba..6e08d0021 100644 --- a/shared/db/Activity.ts +++ b/shared/db/Activity.ts @@ -29,11 +29,6 @@ export default class Activity extends BaseModel { @prop({ required: true }) days: number; // 活动持续天数 timeType=1、2 - @prop({ required: true }) - createdBy: number; // 后台创建人 - @prop({ required: true }) - updatedBy: number; // 最近更新人 - //根据活动类型查询开启的活动数据 public static async findOpenActivityByType(activityGroupId: number[], type: number, date: Date) { diff --git a/shared/db/BaseModel.ts b/shared/db/BaseModel.ts index ec9a6b90e..b0a8f371e 100644 --- a/shared/db/BaseModel.ts +++ b/shared/db/BaseModel.ts @@ -28,4 +28,10 @@ export default class BaseModel extends TimeStamps { @prop() updatedAt: Date + + @prop() + createdBy: number; // 后台创建人 + + @prop() + updatedBy: number; // 最近更新人 } diff --git a/shared/db/Counter.ts b/shared/db/Counter.ts index 6f4f7fc64..6ac266312 100644 --- a/shared/db/Counter.ts +++ b/shared/db/Counter.ts @@ -22,6 +22,12 @@ export default class Counter extends BaseModel { return counter?.seq; } + public static async getCounter(param:{name: string, def: number}, lean = true) { + let {name, def:defaultVal} = param; + let counter: CounterType = await CounterModel.findOne({ name }).lean(lean); + return counter?.seq||defaultVal; + } + } export const CounterModel = getModelForClass(Counter); diff --git a/shared/db/ServerStategy.ts b/shared/db/ServerStategy.ts new file mode 100644 index 000000000..21ad797ca --- /dev/null +++ b/shared/db/ServerStategy.ts @@ -0,0 +1,91 @@ +import BaseModel from './BaseModel'; +import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; +import { CounterModel } from './Counter'; +import { COUNTER } from '../consts'; + +/** + * 开服策略 +*/ +@index({ id: 1 }) + +export default class ServerStategy extends BaseModel { + @prop({ required: true }) + id: number; // 策略唯一id + @prop({ required: true }) + name: string; // 策略名 + + @prop({ required: true, default: false }) + isDefault: boolean; // 是否是自动开服默认使用的策略 + @prop({ required: true, default: 0 }) + maxPlayerCnt: number; // 人数上限 + + @prop({ required: true, type: Number }) + activityGroupId: number[]; // 选择活动组 + @prop({ required: true, type: Number }) + mails: number[]; // 选择邮件模板 + @prop({ required: true, type: Number }) + marquees: number[]; // 选择跑马灯 + @prop({ required: true, type: Number }) + notices: number[]; // 选择公告 + + public static async findBySId(id: number) { + const result: ServerStategyType = await ServerStategyModel.findOne({ id }, { _id: 0 }).lean({ getters: true, virtuals: true }); + return result; + + } + + private static getSearchObj(form: { id?: number, name?: string, isDefault?: boolean }) { + let searchObj = {}; + if (form.id != undefined) searchObj['id'] = form.id; + if (form.name != undefined) searchObj['name'] = { $regex: new RegExp(form.name.toString(), 'i') }; + if (form.isDefault != undefined) searchObj['isDefault'] = form.isDefault; + return searchObj + } + + public static async findByCondition(page: number, pageSize: number, sortField: string, sortOrder: string, form: { id?: number, name?: string, isDefault?: boolean } = {}) { + + let searchObj = ServerStategyModel.getSearchObj(form); + let sort = {}; + if (sortField && sortOrder) { + if (sortOrder == 'ascend') { + sort[sortField] = 1; + } else if (sortOrder == 'descend') { + sort[sortField] = -1; + } + } + const result: ServerStategyType[] = await ServerStategyModel.find(searchObj, { _id: 0 }).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true }); + return result; + + } + + public static async countByCondition(form: { id?: number, name?: string, isDefault?: boolean } = {}) { + + let searchObj = ServerStategyModel.getSearchObj(form); + const result = await ServerStategyModel.count(searchObj); + return result; + } + + private static async unsetDefault() { + const rec = await ServerStategyModel.updateMany({ isDefault: true }, { $set: { isDefault: false } }); + return rec; + } + + public static async updateServerStategy(values: ServerStategyTypeParam & {id: string|number}, uid = 1) { + let id = values.id; + if(id == 'new') { + id = await CounterModel.getNewCounter(COUNTER.SERVER_STATEGY); + } + if(values.isDefault) { + await ServerStategyModel.unsetDefault(); + } + delete values.id; + let rec: ServerStategyType = await ServerStategyModel.findOneAndUpdate({ id }, { $set: {...values, updatedBy: uid}, $setOnInsert: { createdBy: uid } }, + { new: true, upsert: true }).lean(true); + return rec; + } +} + +export const ServerStategyModel = getModelForClass(ServerStategy); + +export interface ServerStategyType extends Pick, keyof ServerStategy> { } +export type ServerStategyTypeParam = Partial; // 将所有字段变成可选项 \ No newline at end of file diff --git a/shared/db/Serverlist.ts b/shared/db/Serverlist.ts index d53219ba0..200943e8e 100644 --- a/shared/db/Serverlist.ts +++ b/shared/db/Serverlist.ts @@ -1,5 +1,9 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; +import { GameModel } from './Game'; +import { CounterModel } from './Counter'; +import { COUNTER } from '../consts'; +import { ServerStategyTypeParam } from './ServerStategy'; // 暂时服务器列表是从game表取的,之后会转移到使用这张表,目前用作查询该服战力中位数 @@ -31,10 +35,10 @@ export default class Serverlist extends BaseModel { @prop({ required: true }) host: string; // pinus连接地址 - @prop({ required: false }) + @prop({ required: false, default: 3014 }) port: number; // pinus端口 - @prop({ required: true }) + @prop({ required: true, default: 1 }) serverStatus: number; // 服务器状态 @prop({ required: true, type: Number }) @@ -52,12 +56,12 @@ export default class Serverlist extends BaseModel { @prop({ required: true }) openTime: Date; - @prop({ required: true }) - createTime: Date; - @prop({ required: true }) serverType: string; + @prop({ required: true, default: 0 }) + maxPlayerCnt: number; // 最大玩家人数 + @prop({ required: true, default: 0 }) medianCe: number; // 中位数武将战力、缩小10000倍后的结果 @@ -76,10 +80,35 @@ export default class Serverlist extends BaseModel { return server; } - public static async newServer(serverId: number, serverType: string, params: ServerlistUpdate) { + public static async updateGroupName(groupId: number, groupName: string) { + let server = await ServerlistModel.updateMany({ groupId }, { $set: { groupName } }); + return server; + } + + public static async newServer(params: { serverType: string, openTime: Date, name?: string }, stategy: ServerStategyTypeParam, uid = 1 ) { + let { serverType, name } = params; + + let serverEnvs = await GameModel.getServerEnvList(); + let curEnv = serverEnvs.find(cur => cur.serverType == serverType); + if(!curEnv) return false; + let { gameHost: host } = curEnv; + + // 分大区 + let groupId = await CounterModel.getCounter(COUNTER.SERVER_GROUP); + let groupServerCount = await ServerlistModel.countByCondition({ serverType, groupId }); + if(groupServerCount > 10) { + groupId = await CounterModel.getNewCounter(COUNTER.SERVER_GROUP); + } + let groupName = '逍遥津' + groupId; + + let serverId = await CounterModel.getNewCounter({ name: `${COUNTER.SERVER_BY_TYPE.name}_${serverType}`, def: COUNTER.SERVER_BY_TYPE.def }); + let id = await CounterModel.getNewCounter(COUNTER.SERVER); + if(!name) name = '出师表' + id + const doc = new ServerlistModel(); - const update = Object.assign(doc.toJSON(), { id: serverId, serverType }, params); - let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id: serverId, serverType }, { $setOnInsert: update }, { new: true, upsert: true }).lean({ getters: true, virtuals: true }); + const update = Object.assign(doc.toJSON(), params, { id, serverId, host, groupId, groupName, name, createdBy: uid, updatedBy: uid }, { activityGroupId: stategy.activityGroupId, maxPlayerCnt: stategy.maxPlayerCnt}); + + let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id }, { $setOnInsert: update }, { new: true, upsert: true }).lean({ getters: true, virtuals: true }); return server; } @@ -95,7 +124,8 @@ export default class Serverlist extends BaseModel { private static getSearchObj(form: { id?: number, serverId?: string|number, name?: string, groupName?: string, groupId?: number, serverType?: string }) { let searchObj = {}; if (form.id != undefined) searchObj['id'] = form.id; - if (form.serverId != undefined) searchObj['groupId'] = form.groupId; + if (form.serverId != undefined) searchObj['serverId'] = form.serverId; + if (form.groupId != undefined) searchObj['groupId'] = form.groupId; if (form.name != undefined) searchObj['name'] = { $regex: new RegExp(form.name.toString(), 'i') }; if (form.groupName != undefined) searchObj['groupName'] = { $regex: new RegExp(form.groupName.toString(), 'i') }; if (form.serverType != undefined) searchObj['serverType'] = form.serverType; @@ -105,7 +135,6 @@ export default class Serverlist extends BaseModel { public static async findByCondition(page: number, pageSize: number, sortField: string, sortOrder: string, form: { id?: number, serverId?: string|number, name?: string, groupName?: string, groupId?: number, serverType?: string } = {}) { let searchObj = ServerlistModel.getSearchObj(form); - console.log(searchObj, form) let sort = {}; if(sortField && sortOrder) { if(sortOrder == 'ascend') { @@ -114,7 +143,7 @@ export default class Serverlist extends BaseModel { sort[sortField] = -1; } } - const result: ServerlistType[] = await ServerlistModel.find(searchObj, { _id: 0 }).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean(); + const result: ServerlistType[] = await ServerlistModel.find(searchObj, { _id: 0 }).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true }); return result; }