diff --git a/game-server/app/servers/battle/handler/guildHandler.ts b/game-server/app/servers/battle/handler/guildHandler.ts index 34a403c81..9ede19458 100644 --- a/game-server/app/servers/battle/handler/guildHandler.ts +++ b/game-server/app/servers/battle/handler/guildHandler.ts @@ -3,7 +3,7 @@ import { resResult, getRefTime, getRandEelm, reduceCe } from '../../../pubUtils/ import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB, GUILD_APPLY_TYPE } from '../../../consts'; import { UserGuildModel } from '../../../db/UserGuild'; import { checkAuth, joinGuild } from '../../../services/guildService'; -import { GuildModel } from '../../../db/Guild'; +import { GuildModel, GuildType } from '../../../db/Guild'; import Role, { RoleModel, RoleType } from '../../../db/Role'; import { GUILD } from '../../../pubUtils/dicParam'; import { handleCost } from '../../../services/rewardService'; @@ -146,9 +146,10 @@ export class GuildHandler { if(ceLimit > reduceCe(role.ce)) { return resResult(STATUS.GUILD_NOT_REACH_CONDI); } - if(nowSeconds() - role.quitGuildTime < 3600) { // TODO 时间系统参数表配置 - return resResult(STATUS.GUILD_QUIT_TIME); - } + // TODO 暂时关闭 + // if(nowSeconds() - role.quitGuildTime < 3600) { // TODO 时间系统参数表配置 + // return resResult(STATUS.GUILD_QUIT_TIME); + // } let hasGuild = false; if(isAuto) { // 自动加入 @@ -179,6 +180,7 @@ export class GuildHandler { const result = await UserGuildApplyModel.getListByGuild(code, lastApplyCode); const list = result.map(cur => { let role = cur.role; + delete cur.role; return { applyCode: cur.applyCode, ...role, ce: reduceCe(role.ce) }; }); @@ -222,6 +224,7 @@ export class GuildHandler { async getInviteMemberList(msg: { }, session: BackendSession) { const roleId = session.get('roleId'); + const serverId = session.get('serverId'); // 检查权限 const checkResult = await checkAuth(GUILD_OPERATE.GET_INIVATION_MEMBER_LIST, roleId); if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); @@ -231,21 +234,104 @@ export class GuildHandler { const day = getRefTime(new Date(), 0, -3); const d = getSeconds(day); - const allList = await RoleModel.getInviteList(d); + const allList = await RoleModel.getInviteList(d, serverId); let list = getRandEelm(allList, 10); if(!list.length) list = allList; - list = list.map(cur => reduceCe(cur)); + list = list.map(cur => { + return {...cur, ce: reduceCe(cur.ce)} + }); + return resResult(STATUS.SUCCESS, { list }); + + } + + // 团长(一键)邀请人 + async inviteMember(msg: { code: string, roleIds: string[] }, session: BackendSession) { + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const { code, roleIds } = msg; + + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.INVATE_MEMBER, roleId, code); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const guild = await GuildModel.findByCode(code, serverId); + if(guild.isMemberMax) return resResult(STATUS.GUILD_MEMBER_MAX); + + const roleList = await RoleModel.findRoleByField('roleId', roleIds); + let result = new Array(); + for(let role of roleList) { + if(!role.hasGuild) { + await UserGuildApplyModel.createUserGuildApply(role, guild, GUILD_APPLY_TYPE.INVITE); + result.push(role.roleId); + } + } + + return resResult(STATUS.SUCCESS, { roleIds: result }); + + } + + // 成员收到邀请列表 + async getInvitationList(msg: { lastApplyCode: string }, session: BackendSession) { + + const roleId = session.get('roleId'); + const { lastApplyCode } = msg; + + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.GET_INVITATION_LIST, roleId); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const result = await UserGuildApplyModel.getListByRole(roleId, lastApplyCode); + const list = result.map(cur => { + let guild = cur.guild; + let leader = guild.leader; + delete guild.leader; + delete cur.guild; + return { applyCode: cur.applyCode, ...guild, leader: leader.roleName }; + }); + return resResult(STATUS.SUCCESS, { list }); } + // 成员同意/拒绝邀请 + async receiveInvitation(msg: { applyCode: string, isReceived: boolean }, session: BackendSession) { + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const { applyCode, isReceived } = msg; + + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.RECEIVE_INVITAION, roleId); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const invite = await UserGuildApplyModel.findByCode(applyCode); + if(!invite) return resResult(STATUS.GUILD_INVITE_NOT_FOUND); + + let code: string; + if(isReceived) { // 同意申请,加入 + const { guildCode } = invite; + const guild = await GuildModel.findByCode(guildCode, serverId); + + const joinResult = await joinGuild(guildCode, guild.lv, roleId, serverId); + if(joinResult.status == 0) { + return joinResult.resResult; + } + + code = guild.code; + } + await UserGuildApplyModel.deleteApplyByApplyCode([applyCode]); // 删除这条邀请 + + return resResult(STATUS.SUCCESS, { applyCode, code, isReceived, hasGuild: isReceived }); + } + // 获取军团成员 - async getGuildMember(msg: { code: string }, session: BackendSession) { + async getGuildMember(msg: { code: string, sort: string }, session: BackendSession) { const roleId = session.get('roleId'); // const serverId = session.get('serverId'); - const { code } = msg; + const { code, sort } = msg; // 检查权限 const checkResult = await checkAuth(GUILD_OPERATE.GET_MEMBER_LIST_MAIN, roleId, code); @@ -262,6 +348,14 @@ export class GuildHandler { delete role._id; delete cur.role; return { ...cur, ...role, ce: reduceCe(role.ce) }; + }).sort((a, b) => { + if(sort == 'honour') { + return b.honourWeekly - a.honourWeekly; + } else if (sort == 'loginTime') { + return b.loginTime - a.loginTime; + } else { + return b.ce - a.ce; + } }); return resResult(STATUS.SUCCESS, { list: result }); diff --git a/game-server/test/guild.test.ts b/game-server/test/guild.test.ts index 69e22f376..5d075954d 100644 --- a/game-server/test/guild.test.ts +++ b/game-server/test/guild.test.ts @@ -12,6 +12,7 @@ describe('军团测试', function() { // }); var pinusClient; var roleInfo; + let guildList; beforeEach(function(done) { pinusClient = new PinusWSClient(); @@ -65,6 +66,7 @@ describe('军团测试', function() { expect(res.data).to.be.an('object'); expect(res.data).to.have.deep.property('list').that.is.an('array'); expect(res.data).to.have.deep.property('quitTime').that.is.an('number'); + guildList = res.data.list; res.data.list.forEach(list => { expect(list).to.have.deep.property('code').that.is.a('string'); expect(list).to.have.deep.property('name').that.is.a('string'); @@ -169,4 +171,32 @@ describe('军团测试', function() { }); }); + it('查看军团成员列表', function (done) { + let index = Math.floor(Math.random() * guildList.length); + if(guildList[index]) { + let code = guildList[index].code; + + pinusClient.request('battle.guildHandler.getGuildMember', { code }, (res) => { + // 消息回调 + expect(res).to.be.an('object'); + expect(res.code).equal(0); + expect(res.data).to.be.an('object'); + expect(res.data).to.have.deep.property('list').that.is.an('array'); + res.data.list.forEach(list => { + expect(list).to.have.deep.property('roleId').that.is.a('string'); + expect(list).to.have.deep.property('roleName').that.is.a('string'); + expect(list).to.have.deep.property('ce').that.is.a('number'); + expect(list).to.have.deep.property('headHid').that.is.a('number'); + expect(list).to.have.deep.property('sHid').that.is.a('number'); + expect(list).to.have.deep.property('lv').that.is.a('number'); + expect(list).to.have.deep.property('title').that.is.a('number'); + expect(list).to.have.deep.property('loginTime').that.is.a('number'); + expect(list).to.have.deep.property('job').that.is.a('number'); + // expect(list).to.have.deep.property('auth').that.is.a('number'); + // expect(list).to.have.deep.property('honourWeekly').that.is.a('number'); + }); + done(); + }); + } + }); }); diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index ccece20e7..bc22d9c72 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -134,6 +134,7 @@ export const STATUS = { GUILD_QUIT_ERROR: { code: 20907, simStr: '退出公会失败' }, GUILD_KICK_ERROR: { code: 20908, simStr: '未找到该成员或该成员已退出' }, GUILD_QUIT_TIME: { code: 20909, simStr: '退出军团1小时后才可以申请' }, + GUILD_INVITE_NOT_FOUND: { code: 20910, simStr: '该邀请未找到' }, // 通用 30000 - 30099 DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' }, diff --git a/shared/db/PvpHistoryOpp.ts b/shared/db/PvpHistoryOpp.ts index c57cf1e9c..587e05edc 100644 --- a/shared/db/PvpHistoryOpp.ts +++ b/shared/db/PvpHistoryOpp.ts @@ -1,7 +1,7 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; -import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from './generalField'; +import { PvpEnemies, PvpOtherHeroes } from './generalField'; export class HeroScores { @prop({ required: true }) diff --git a/shared/db/Role.ts b/shared/db/Role.ts index 9c573ab87..3b9512554 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -413,9 +413,10 @@ export default class Role extends BaseModel { } // 获取未加入公会且登录时间在三天内的人 - public static async getInviteList(time: number) { - const result = await RoleModel.find({ loginTime: { $gt: time }, hasGuild: false }) + public static async getInviteList(time: number, serverId: number) { + const result = await RoleModel.find({ loginTime: { $gt: time }, hasGuild: false, serverId }) .select('roleId roleName ce headHid sHid lv title job loginTime') + .sort({loginTime: -1, lv: -1, ce: -1}) .limit(100).lean(); return result; } diff --git a/shared/db/UserGuild.ts b/shared/db/UserGuild.ts index c3dfa8a23..7dc0f162d 100644 --- a/shared/db/UserGuild.ts +++ b/shared/db/UserGuild.ts @@ -1,9 +1,7 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose'; import Role, { RoleType } from './Role'; -import Guild from './Guild'; import { GUILD_AUTH, USER_GUILD_STATUS, GUILD_JOB } from '../consts'; -import { GUILD } from '../pubUtils/dicParam'; class ActiveRecord { @prop({ required: true }) diff --git a/shared/db/UserGuildApply.ts b/shared/db/UserGuildApply.ts index 08de6f6e7..af4993611 100644 --- a/shared/db/UserGuildApply.ts +++ b/shared/db/UserGuildApply.ts @@ -2,7 +2,7 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose'; import Role, { RoleType } from './Role'; import Guild, { GuildType } from './Guild'; -import { GUILD_AUTH, USER_GUILD_STATUS, GUILD_JOB, GUILD_APPLY_STATUS, GUILD_APPLY_TYPE, GUILD_PER_PAGE, GUILD_STATUS } from '../consts'; +import { GUILD_APPLY_TYPE, GUILD_PER_PAGE } from '../consts'; import { genCode } from '../pubUtils/util'; @index({ roleId: 1 }) @@ -25,6 +25,7 @@ export default class UserGuildApply extends BaseModel { @prop({ required: true, enum: GUILD_APPLY_TYPE, select: false}) type: number; + // 创建申请或邀请 public static async createUserGuildApply(role: RoleType, guild: GuildType, type: number) { const applyCode = genCode(10); const doc = new UserGuildApplyModel(); @@ -35,36 +36,43 @@ export default class UserGuildApply extends BaseModel { return result; } + // 删除玩家发出的所有申请 public static async deleteApply(roleId: string) { const result = await UserGuildApplyModel.deleteMany({ roleId, type: GUILD_APPLY_TYPE.APPLY }); return result; } + // 删除公会收到的所有申请 public static async deleteApplyByGuild(guildCode: string) { const result = await UserGuildApplyModel.deleteMany({ guildCode, type: GUILD_APPLY_TYPE.APPLY }); return result; } + // 根据唯一code批量删除 public static async deleteApplyByApplyCode(applyCodeList: string[]) { const result = await UserGuildApplyModel.deleteMany({ applyCode: { $in: applyCodeList}, type: GUILD_APPLY_TYPE.APPLY }); return result; } + // 根绝唯一code查询申请或邀请 public static async findByCode(applyCode: string) { const userGuildApply: UserGuildApplyType = await UserGuildApplyModel.findOne({ applyCode }).lean(); return userGuildApply; } + // 查询用户的申请列表 public static async findApplyByRole(roleId: string) { const userGuildApply: UserGuildApplyType[] = await UserGuildApplyModel.find({ roleId, type: GUILD_APPLY_TYPE.APPLY }).lean(); return userGuildApply; } + // 根据唯一code查询申请或邀请 public static async getListByApplyCode(applyCodeList: string[]) { const userGuildApply: UserGuildApplyType[] = await UserGuildApplyModel.find({ applyCode: { $in: applyCodeList}, type: GUILD_APPLY_TYPE.APPLY }).lean(); return userGuildApply; } + // 查询公会收到的申请 public static async getListByGuild(code: string, lastApplyCode: string) { let condition = { guildCode: code, type: GUILD_APPLY_TYPE.APPLY }; if(lastApplyCode) { @@ -78,6 +86,30 @@ export default class UserGuildApply extends BaseModel { .limit(GUILD_PER_PAGE).lean(); return list } + + // 查询玩家的邀请列表 + public static async getListByRole(roleId: string, lastApplyCode: string) { + let condition = { roleId, type: GUILD_APPLY_TYPE.INVITE }; + if(lastApplyCode) { + const lastApply = await this.findByCode(lastApplyCode); + condition["createdAt"] = { $lt: lastApply.createdAt }; + } + const list: UserGuildApplyType[] = await UserGuildApplyModel.find(condition) + .sort({ createdAt: -1 }) + .select('applyCode guild') + .populate({ + path: 'guild', + select: 'code icon name lv memberCnt leader ceLimit', + model: 'Guild', + populate: { + path: 'leader', + select: 'roleName', + model: 'Role' + } + }) + .limit(GUILD_PER_PAGE).lean(); + return list + } } export const UserGuildApplyModel = getModelForClass(UserGuildApply); diff --git a/shared/pubUtils/interface.ts b/shared/pubUtils/interface.ts index 63269861c..923ce8f15 100644 --- a/shared/pubUtils/interface.ts +++ b/shared/pubUtils/interface.ts @@ -1,7 +1,7 @@ // 一些通用的interface定义 import { reduceCe } from "./util"; -import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from "../db/generalField"; +import { PvpEnemies, PvpOtherHeroes } from "../db/generalField"; import { GuildType } from "../db/Guild"; import { RoleType } from "../db/Role";