diff --git a/game-server/app/servers/battle/handler/guildHandler.ts b/game-server/app/servers/battle/handler/guildHandler.ts index 245adceba..cd1281455 100644 --- a/game-server/app/servers/battle/handler/guildHandler.ts +++ b/game-server/app/servers/battle/handler/guildHandler.ts @@ -1,14 +1,14 @@ import { Application, BackendSession, pinus } from 'pinus'; -import { resResult } from '../../../pubUtils/util'; +import { resResult, getRefTime, getRandEelm, reduceCe } from '../../../pubUtils/util'; 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 { RoleModel, RoleType } from '../../../db/Role'; +import Role, { RoleModel, RoleType } from '../../../db/Role'; import { GUILD } from '../../../pubUtils/dicParam'; import { handleCost } from '../../../services/rewardService'; import { getGoldObject } from '../../../pubUtils/itemUtils'; -import { getSeconds } from '../../../pubUtils/timeUtil'; +import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil'; import { GuildListInfo } from '../../../pubUtils/interface'; import { UserGuildApplyModel } from '../../../db/UserGuildApply'; @@ -25,15 +25,15 @@ export class GuildHandler { const roleId = session.get('roleId'); const sid = session.get('sid'); + const serverId = session.get('serverId'); const { name, icon, notice } = msg; // 检查权限是否够,包括是否参过团 - const auth = await UserGuildModel.getMyAuth(roleId); - const checkResult = checkAuth(GUILD_OPERATE.CREATE_GUILD, auth); + const checkResult = await checkAuth(GUILD_OPERATE.CREATE_GUILD, roleId); if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); // 检查名字是否重 - const checkNameResult = await GuildModel.checkName(name); + const checkNameResult = await GuildModel.checkName(name, serverId); if(checkNameResult) return resResult(STATUS.GUILD_NAME_DUP); // 检查元宝是否够 @@ -45,11 +45,17 @@ export class GuildHandler { await handleCost(roleId, sid, [getGoldObject(GUILD.GUILD_CREATE_COST)]); // 创建公会 - const guild = await GuildModel.createGuild({ name, icon, notice }, role); + const guild = await GuildModel.createGuild({ name, icon, notice }, role, serverId); if(!guild) return resResult(STATUS.GUILD_CREATE_ERROR); + guild.guildCe = reduceCe(guild.guildCe); + guild.leader = guild.leader; + guild.leader.ce = reduceCe(guild.leader.ce); + const userGuild = await UserGuildModel.createUserGuild(guild.code, role, true); if(!userGuild) return resResult(STATUS.GUILD_CREATE_ERROR); + await RoleModel.joinGuild(roleId); + // TODO 加入排行 const rank = 0; // TODO 加入channel @@ -64,10 +70,14 @@ export class GuildHandler { const roleId = session.get('roleId'); // const sid = session.get('sid'); + const serverId = session.get('serverId'); const { page = 1, showPeopleMax, name } = msg; - const guildList = await GuildModel.findByCondition(page, showPeopleMax, name); - // TODO 加入申请列表 + const checkResult = await checkAuth(GUILD_OPERATE.GET_GUILD_LIST, roleId); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const guildList = await GuildModel.findByCondition(page, showPeopleMax, name, serverId); + const applyList = await UserGuildApplyModel.findApplyByRole(roleId); const { quitGuildTime: quitTime = 0 } = await RoleModel.findByRoleId(roleId); @@ -75,8 +85,8 @@ export class GuildHandler { for(let guild of guildList) { let info = new GuildListInfo(guild); - // TODO 查询申请 - info.setApply(false); + let hasApply = applyList.find(cur => cur.guildCode == guild.code); + info.setApply(!!hasApply); list.push(info); } return resResult(STATUS.SUCCESS, { quitTime, list }); @@ -86,14 +96,22 @@ export class GuildHandler { async getMyGuildInfo(msg: { }, session: BackendSession) { const roleId = session.get('roleId'); - - //TODO 检查权限是否够 等策划表 + const serverId = session.get('serverId'); const userGuild = await UserGuildModel.getMyGuild(roleId, 'honour job auth guildCode'); if(!userGuild) { return resResult(STATUS.SUCCESS, { hasGuild: false }) }; - let guild = await GuildModel.findByCode(userGuild.guildCode); + + const checkResult = await checkAuth(GUILD_OPERATE.GET_MY_GUILD_INFO, roleId, userGuild.guildCode, userGuild); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + let guild = await GuildModel.findByCode(userGuild.guildCode, serverId); + if(!guild) return resResult(STATUS.GUILD_NOT_FOUND); + + guild.guildCe = reduceCe(guild.guildCe); + guild.leader = guild.leader; + guild.leader.ce = reduceCe(guild.leader.ce); // TODO 刷新日活跃,周活跃 @@ -109,24 +127,32 @@ export class GuildHandler { async applyGuild(msg: { code: string }, session: BackendSession) { const roleId = session.get('roleId'); + const serverId = session.get('serverId'); const { code } = msg; - //TODO 检查权限是否够 等策划表 + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.APPLY_GUILD, roleId); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const guild = await GuildModel.findByCode(code, serverId); + if(!guild) return resResult(STATUS.GUILD_NOT_FOUND); - const guild = await GuildModel.findByCode(code); const { isMemberMax, isAuto, ceLimit, lv } = guild; if(isMemberMax) { return resResult(STATUS.GUILD_MEMBER_MAX); } const role = await RoleModel.findByRoleId(roleId); - if(ceLimit > role.ce) { + if(ceLimit > reduceCe(role.ce)) { return resResult(STATUS.GUILD_NOT_REACH_CONDI); } + if(nowSeconds() - role.quitGuildTime < 3600) { // TODO 时间系统参数表配置 + return resResult(STATUS.GUILD_QUIT_TIME); + } let hasGuild = false; if(isAuto) { // 自动加入 - const joinResult = await joinGuild(code, lv, roleId); + const joinResult = await joinGuild(code, lv, roleId, serverId); if(joinResult.status == 0) { return joinResult.resResult; } @@ -146,12 +172,14 @@ export class GuildHandler { const roleId = session.get('roleId'); const { code, lastApplyCode } = msg; - // TODO 查询权限 等策划表 + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.GET_APPLY_LIST, roleId); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); const result = await UserGuildApplyModel.getListByGuild(code, lastApplyCode); const list = result.map(cur => { let role = cur.role; - return { applyCode: cur.applyCode, ...role }; + return { applyCode: cur.applyCode, ...role, ce: reduceCe(role.ce) }; }); return resResult(STATUS.SUCCESS, { list }); @@ -161,24 +189,158 @@ export class GuildHandler { async receiveApply(msg: { code: string, applyCodeList: [string], isReceived: boolean }, session: BackendSession) { const roleId = session.get('roleId'); + const serverId = session.get('serverId'); const { code, applyCodeList, isReceived } = msg; - // TODO 查询权限 等策划表 + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.RECEIVE_APPLY, roleId, code); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const applyList = await UserGuildApplyModel.getListByApplyCode(applyCodeList); let roleIds = new Array(); if(isReceived) { // 同意申请,加入 - const guild = await GuildModel.findByCode(code); - const applyList = await UserGuildApplyModel.getListByApplyCode(applyCodeList); + const guild = await GuildModel.findByCode(code, serverId); for(let { roleId } of applyList) { - const joinResult = await joinGuild(code, guild.lv, roleId); - if(joinResult.status == 0) break; + const joinResult = await joinGuild(code, guild.lv, roleId, serverId); + if(joinResult.status == 0) continue; roleIds.push(roleId); } } else { // 拒绝申请,删除申请 + for(let { roleId } of applyList) { + // TODO 发送邮件 + } + await UserGuildApplyModel.deleteApplyByApplyCode(applyCodeList); } return resResult(STATUS.SUCCESS, { roleIds }); } + + // 团长查看(刷新)可邀请人列表 + async getInviteMemberList(msg: { }, session: BackendSession) { + + const roleId = session.get('roleId'); + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.GET_INIVATION_MEMBER_LIST, roleId); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + // 离线时间,三天内在线且尚未加入军团。按以下规则排序 离线时间 玩家等级 玩家战力 + + const day = getRefTime(new Date(), 0, -3); + const d = getSeconds(day); + + const allList = await RoleModel.getInviteList(d); + let list = getRandEelm(allList, 10); + if(!list.length) list = allList; + list = list.map(cur => reduceCe(cur)); + return resResult(STATUS.SUCCESS, { list }); + + } + + + // 获取军团成员 + async getGuildMember(msg: { code: string }, session: BackendSession) { + + const roleId = session.get('roleId'); + // const serverId = session.get('serverId'); + const { code } = msg; + + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.GET_MEMBER_LIST_MAIN, roleId, code); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + let select = ['role', 'job']; + const checkDetailResult = await checkAuth(GUILD_OPERATE.GET_MEMBER_LIST_DETAIL, roleId, code); + if(checkDetailResult) { + select.push('auth', 'honourWeekly'); + } + const list = await UserGuildModel.getListByGuild(code, select.join(' ')); + const result = list.map(cur => { + let role = cur.role; + delete role._id; + delete cur.role; + return { ...cur, ...role }; + }); + + return resResult(STATUS.SUCCESS, { list: result }); + } + + // 团长解散军团 + async dismiss(msg: { code: string }, session: BackendSession) { + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const { code } = msg; + + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.DISMISS, roleId, code); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const guild = await GuildModel.dismiss(code, serverId); + if(!guild) return resResult(STATUS.GUILD_DELETE_ERROR); + + await UserGuildModel.dismiss(code); + const { members } = guild; + await RoleModel.dissmissGuild(members); + await UserGuildApplyModel.deleteApplyByGuild(code); + + // 删除channel + + return resResult(STATUS.SUCCESS, { code, status: guild.status }); + } + + // 成员退出军团 + async quit(msg: { code: string }, session: BackendSession) { + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const { code } = msg; + + // 检查权限 + const checkResult = await checkAuth(GUILD_OPERATE.QUIT, roleId, code); + if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + const userGuild = await UserGuildModel.quit(code, roleId); + if(!userGuild) return resResult(STATUS.GUILD_QUIT_ERROR); + + const role = await RoleModel.quitGuild(roleId, nowSeconds()); + if(!role) return resResult(STATUS.GUILD_QUIT_ERROR); + + const guild = await GuildModel.quit(code, roleId, serverId); + if(!guild) return resResult(STATUS.GUILD_QUIT_ERROR); + + return resResult(STATUS.SUCCESS, { hasGuild: role.hasGuild }); + } + + // 团长踢退出军团 + async kick(msg: { code: string, roleId: string }, session: BackendSession) { + + const roleId = session.get('roleId'); + const serverId = session.get('serverId'); + const { code, roleId: memberRoleId } = msg; + + // 检查权限 + const checkMyAuth = await checkAuth(GUILD_OPERATE.KICK, roleId, code); + if(!checkMyAuth) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + // 被踢出的权限 + const checkHisAuth = await checkAuth(GUILD_OPERATE.BE_KICKED, memberRoleId, code); + if(!checkHisAuth) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); + + + const userGuild = await UserGuildModel.quit(code, memberRoleId); + if(!userGuild) return resResult(STATUS.GUILD_KICK_ERROR); + + const role = await RoleModel.quitGuild(memberRoleId, nowSeconds()); + if(!role) return resResult(STATUS.GUILD_KICK_ERROR); + + const guild = await GuildModel.quit(code, memberRoleId, serverId); + if(!guild) return resResult(STATUS.GUILD_KICK_ERROR); + + // TODO 发送邮件,发送推送 + + return resResult(STATUS.SUCCESS, { memberCnt: guild.memberCnt }); + } } \ No newline at end of file diff --git a/game-server/app/services/guildService.ts b/game-server/app/services/guildService.ts index d2ed011eb..8044d38e6 100644 --- a/game-server/app/services/guildService.ts +++ b/game-server/app/services/guildService.ts @@ -3,7 +3,7 @@ import { GuildModel } from "../db/Guild"; import { resResult } from "../pubUtils/util"; import { STATUS } from "../consts"; import { RoleModel } from "../db/Role"; -import { UserGuildModel } from "../db/UserGuild"; +import { UserGuildModel, UserGuildType } from "../db/UserGuild"; import { UserGuildApplyModel } from "../db/UserGuildApply"; /** @@ -11,9 +11,11 @@ import { UserGuildApplyModel } from "../db/UserGuildApply"; * @param func 操作id * @param auth 权限 */ -export function checkAuth(func: number, auth: number) { +export async function checkAuth(func: number, roleId: string, code?: string, userGuild?: UserGuildType) { + const auth = await UserGuildModel.getMyAuth(roleId, code, userGuild); const dicGuildAuth = gameData.guildAuth.get(func); if(!dicGuildAuth) return false; + return dicGuildAuth.includes(auth); } @@ -23,16 +25,18 @@ export function checkAuth(func: number, auth: number) { * @param lv 公会当前等级,判断人数用 * @param roleId 加入的玩家 */ -export async function joinGuild(code: string, lv: number, roleId: string) { +export async function joinGuild(code: string, lv: number, roleId: string, serverId: number) { - const hasGuild = await UserGuildModel.getMyGuild(roleId); - if(!!hasGuild) { + // TODO 加redlock + + const result = await RoleModel.joinGuild(roleId); + if(!result) { return { status: 0, resResult: resResult(STATUS.GUILD_HAS_JOIN) }; } // TODO 读策划表获取最大人数 const maxMemberCnt = 10; - const guild = await GuildModel.addGuild(code, roleId, maxMemberCnt); + const guild = await GuildModel.addGuild(code, roleId, maxMemberCnt, serverId); if(!guild) { return { status: 0, resResult: resResult(STATUS.GUILD_MEMBER_MAX) }; } diff --git a/game-server/test/guild.test.ts b/game-server/test/guild.test.ts index 7a25b9626..69e22f376 100644 --- a/game-server/test/guild.test.ts +++ b/game-server/test/guild.test.ts @@ -141,10 +141,32 @@ describe('军团测试', function() { 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('string'); + expect(list).to.have.deep.property('title').that.is.a('number'); expect(list).to.have.deep.property('loginTime').that.is.a('number'); }); done(); }); }); + + it('团长查看可邀请列表', function (done) { + pinusClient.request('battle.guildHandler.getInviteMemberList', { }, (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'); + }); + done(); + }); + }); + }); diff --git a/shared/consts/constModules/guildConst.ts b/shared/consts/constModules/guildConst.ts index ed076c46e..80423c991 100644 --- a/shared/consts/constModules/guildConst.ts +++ b/shared/consts/constModules/guildConst.ts @@ -31,7 +31,32 @@ export enum GUILD_JOB { // 操作 export enum GUILD_OPERATE { - CREATE_GUILD = 1, // 创建公会 + CREATE_GUILD = 1, // 创建公会 + GET_GUILD_LIST = 2, // 显示所有军团列表 + APPLY_GUILD = 3, // 申请加入军团 + GET_GUILD_INFO = 4, // 查看军团详细 + GET_MY_GUILD_INFO = 5, // 查看自己军团详情 + GET_INVITATION_LIST = 6, // 查看自己被邀请的军团 + RECEIVE_INVITAION = 7, // 接受邀请 + GET_MEMBER_LIST_MAIN = 8, // 查看成员主要信息 + GET_MEMBER_LIST_DETAIL = 9, // 查看团内成员信息 + GET_MEMBER_LIST_MANAGE = 10, // 管理信息 + SET_INFO = 11, // 修改军团信息 + GET_APPLY_LIST = 12, // 查看申请列表 + RECEIVE_APPLY = 13, // 接受申请 + GET_INIVATION_MEMBER_LIST = 14, // 获取可邀请列表 + INVATE_MEMBER = 15, // 邀请某人 + SEND_MAIL = 16, // 发送邮件 + RECRUIT = 17, // 招募 + KICK = 18, // 踢人 + DISMISS = 19, // 解散军团 + QUIT = 20, // 退出军团 + IMPEACH = 21, // 弹劾团长 + UP_STRUCTURE = 22, // 建筑物升级 + GET_REC = 23, // 获得动态 + OPEN_BOSS = 24, // 开启演武台 + EQUIP_PRODUCE = 25, // 炼器堂研发 + BE_KICKED = 26, // 被踢出军团 } // 军团状态 diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index ca599a43c..ccece20e7 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -129,6 +129,11 @@ export const STATUS = { GUILD_MEMBER_MAX: { code: 20903, simStr: '军团人员已满' }, GUILD_NOT_REACH_CONDI: { code: 20903, simStr: '您未达到申请军团条件' }, GUILD_HAS_JOIN: { code: 20904, simStr: '已加入过其他军团' }, + GUILD_NOT_FOUND: { code: 20905, simStr: '未获取到该军团' }, + GUILD_DELETE_ERROR: { code: 20906, simStr: '公会已解散' }, + GUILD_QUIT_ERROR: { code: 20907, simStr: '退出公会失败' }, + GUILD_KICK_ERROR: { code: 20908, simStr: '未找到该成员或该成员已退出' }, + GUILD_QUIT_TIME: { code: 20909, simStr: '退出军团1小时后才可以申请' }, // 通用 30000 - 30099 DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' }, diff --git a/shared/db/Guild.ts b/shared/db/Guild.ts index 1705747b8..908593e84 100644 --- a/shared/db/Guild.ts +++ b/shared/db/Guild.ts @@ -66,7 +66,7 @@ export default class Guild extends BaseModel { refTimeWeekly: Date; @prop({ required: true, default: 0 }) - ce: number; // 总战力 + guildCe: number; // 总战力 @prop({ required: true, type: String, default: [], select: false }) members: string[]; // 军团成员的roleId,用于增加战力的时候加入总战力 @@ -77,9 +77,12 @@ export default class Guild extends BaseModel { @prop({ required: true, default: GUILD_STATUS.RUNNING, enum: GUILD_STATUS }) status: number; - public static async createGuild(params: { name: string, icon: number, notice: string }, role: RoleType) { + @prop({ required: true, default: 1, select: false }) + serverId: number; // 分服 + + public static async createGuild(params: { name: string, icon: number, notice: string }, role: RoleType, serverId: number) { const doc = new GuildModel(); - const update = Object.assign(doc.toJSON(), params, { leader: role._id, members: [role.roleId], ce: role.ce }); + const update = Object.assign(doc.toJSON(), params, { leader: role._id, members: [role.roleId], guildCe: role.ce, serverId }); delete update._id; const code = genCode(6); const result: GuildType = await GuildModel.findOneAndUpdate({ code }, update, { upsert: true, new: true }) @@ -89,13 +92,13 @@ export default class Guild extends BaseModel { return result; } - public static async checkName(name: string) { - const result = await GuildModel.findOne({ name, status: GUILD_STATUS.RUNNING }).lean(); + public static async checkName(name: string, serverId: number) { + const result = await GuildModel.findOne({ name, status: GUILD_STATUS.RUNNING, serverId }).lean(); return !!result; } - public static async findByCondition(page: number, showPeopleMax: boolean, name: string) { - const condition = { status: GUILD_STATUS.RUNNING }; + public static async findByCondition(page: number, showPeopleMax: boolean, name: string, serverId: number) { + const condition = { status: GUILD_STATUS.RUNNING, serverId }; if(!showPeopleMax) { condition['isMemberMax'] = false; } @@ -103,7 +106,7 @@ export default class Guild extends BaseModel { condition['name'] = { $regex: new RegExp(name, 'i') } } const guildList = await GuildModel.find(condition) - .sort({ lv: -1, ce: -1 }) + .sort({ lv: -1, guildCe: -1 }) .limit(GUILD_PER_PAGE).skip((page - 1) * GUILD_PER_PAGE) .select('code icon name lv memberCnt leader ceLimit isAuto') .populate('leader', 'roleName', 'Role') @@ -111,20 +114,33 @@ export default class Guild extends BaseModel { return guildList; } - public static async findByCode(code: string) { - const result = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING }) + public static async findByCode(code: string, serverId: number) { + const result = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING, serverId }) .populate('leader', 'roleName sHid headHid lv loginTime ce', 'Role') .lean(); return result; } - public static async addGuild(code: string, roleId: string, maxMemberCnt: number) { - let result = await GuildModel.findOneAndUpdate({ code, memberCnt: {$lt: maxMemberCnt } }, { $inc: { memberCnt: 1 }, $push: { members: roleId } }, { new: true }).lean(); + public static async addGuild(code: string, roleId: string, maxMemberCnt: number, serverId: number) { + let result = await GuildModel.findOneAndUpdate({ code, memberCnt: {$lt: maxMemberCnt }, serverId }, { $inc: { memberCnt: 1 }, $push: { members: roleId } }, { new: true }).lean(); if(result && result.memberCnt >= maxMemberCnt) { result = await GuildModel.findOneAndUpdate({ code }, { $set: { isMemberMax: true } }).lean(); } return result; } + + public static async dismiss(code: string, serverId: number) { + const result = await GuildModel.findOneAndUpdate({ code, status: GUILD_STATUS.RUNNING, serverId }, { status: GUILD_STATUS.DISMISSED }, { new: true }) + .select('+members') + .lean(); + return result; + } + + public static async quit(code: string, roleId: string, serverId: number) { + const result = await GuildModel.findOneAndUpdate({ code, serverId }, { $inc: { memberCnt: -1}, $pull: { members: roleId }, isMemberMax: false }, { new: true }) + .lean(); + return result; + } } export const GuildModel = getModelForClass(Guild); diff --git a/shared/db/Role.ts b/shared/db/Role.ts index ee73e4656..9c573ab87 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -7,19 +7,6 @@ import { shouldRefresh } from '../pubUtils/util'; import { initRoleAtrr } from '../pubUtils/playerCe'; import Hero,{} from '../db/Hero'; import { nowSeconds } from '../pubUtils/timeUtil'; -interface roleUpdate { - ce?: number; - _id?:number; - coin?: number; - gold?:number; - frdCnt?: number; - expeditionPoint?:number; - globalCeAttr?:CeAttrRole; - title?:number; - teraphs?: Teraph[]; - topFive?: TopHero[]; - topFiveCe?: number; -} class TopHero { @prop({ required: true }) @@ -219,8 +206,10 @@ export default class Role extends BaseModel { teraphs:Array; // 公会 + @prop({ required: true, default: false }) + hasGuild: boolean; // 是否加入过公会 @prop({ required: true, default: 0 }) - quitGuildTime: number; // 上次退出公会的时间 + quitGuildTime: number; // 上次退出公会的时间 public static async findByUid(uid: number, serverId: number, lean = true) { const role: RoleType = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, { loginTime: nowSeconds() }, { new: true }).lean(lean); @@ -416,8 +405,35 @@ export default class Role extends BaseModel { let result: RoleType = await RoleModel.findOneAndUpdate({roleId}, {$set:roleUpdate}, {new: true}).lean(lean); return result; } + + // 记录加入公会 + public static async joinGuild(roleId: string) { + const result = await RoleModel.findOneAndUpdate({ roleId, hasGuild: false }, { hasGuild: true }, { new: true }).lean(); + return result; + } + + // 获取未加入公会且登录时间在三天内的人 + public static async getInviteList(time: number) { + const result = await RoleModel.find({ loginTime: { $gt: time }, hasGuild: false }) + .select('roleId roleName ce headHid sHid lv title job loginTime') + .limit(100).lean(); + return result; + } + + // 公会解散 + public static async dissmissGuild(members: string[]) { + const result = await RoleModel.updateMany({ roleId: { $in: members } }, { hasGuild: false }).lean(); + return result; + } + + // 退出公会 + public static async quitGuild(roleId: string, now: number) { + const result = await RoleModel.findOneAndUpdate({ roleId, hasGuild: true }, { hasGuild: false, quitGuildTime: now }, { new: true }).lean(); + return result; + } } export const RoleModel = getModelForClass(Role); export interface RoleType extends Pick, keyof Role>{}; +type roleUpdate = Partial; // 将所有字段变成可选项 diff --git a/shared/db/UserGuild.ts b/shared/db/UserGuild.ts index f28d33cf2..4d63a510a 100644 --- a/shared/db/UserGuild.ts +++ b/shared/db/UserGuild.ts @@ -41,23 +41,35 @@ export default class UserGuild extends BaseModel { @prop({ required: true, default: new Date() }) refTimeWeekly: number; - public static async getMyAuth(roleId: string, userGuild?: UserGuildType) { + public static async getMyAuth(roleId: string, guildCode?: string, userGuild?: UserGuildType) { let myGuild: UserGuildType; if(!userGuild) { myGuild = await this.getMyGuild(roleId, 'auth'); } else { myGuild = userGuild; } + + if(guildCode && userGuild && userGuild.guildCode != guildCode) { + return GUILD_AUTH.OTHERS; + } + return myGuild?myGuild.auth: GUILD_AUTH.OTHERS; } public static async getMyGuild(roleId: string, select?: string) { + const myGuild: UserGuildType = await UserGuildModel.findOne({ roleId, status: USER_GUILD_STATUS.ON }) - .select(select) - .lean(); + .select(select).lean(); return myGuild; } + public static async getListByGuild(guildCode: string, select?: string) { + const userGuilds: UserGuildType[] = await UserGuildModel.find({ guildCode, status: USER_GUILD_STATUS.ON }) + .select(select) + .populate('role', 'roleId roleName ce headHid sHid lv title', 'Role') + .lean(); + return userGuilds; + } public static async createUserGuild(guildCode: string, role: RoleType, isLeader: boolean) { const doc = new UserGuildModel(); @@ -65,12 +77,24 @@ export default class UserGuild extends BaseModel { let auth = isLeader? GUILD_AUTH.LEADER: GUILD_AUTH.MEMBER; const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, role: role._id, job, auth }); delete update._id; - const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ guildCode, status: USER_GUILD_STATUS.ON }, update, { upsert: true, new: true }) + const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId: role.roleId, guildCode, status: USER_GUILD_STATUS.ON }, update, { upsert: true, new: true }) .select('honourWeekly job auth') .lean(); return result; } + + public static async dismiss(guildCode: string) { + const result = await UserGuildModel.updateMany({guildCode}, {status: USER_GUILD_STATUS.DISMISSED}); + + return result; + } + + // 玩家退出公会 + public static async quit(guildCode: string, roleId: string) { + const result = await UserGuildModel.findOneAndUpdate({ guildCode, roleId, status: USER_GUILD_STATUS.ON }, {status: USER_GUILD_STATUS.QUIT}, {new: true}); + return result; + } } export const UserGuildModel = getModelForClass(UserGuild); diff --git a/shared/db/UserGuildApply.ts b/shared/db/UserGuildApply.ts index 868986cd5..08de6f6e7 100644 --- a/shared/db/UserGuildApply.ts +++ b/shared/db/UserGuildApply.ts @@ -40,6 +40,11 @@ export default class UserGuildApply extends BaseModel { return result; } + public static async deleteApplyByGuild(guildCode: string) { + const result = await UserGuildApplyModel.deleteMany({ guildCode, type: GUILD_APPLY_TYPE.APPLY }); + return result; + } + public static async deleteApplyByApplyCode(applyCodeList: string[]) { const result = await UserGuildApplyModel.deleteMany({ applyCode: { $in: applyCodeList}, type: GUILD_APPLY_TYPE.APPLY }); return result; @@ -50,6 +55,11 @@ export default class UserGuildApply extends BaseModel { return userGuildApply; } + public static async findApplyByRole(roleId: string) { + const userGuildApply: UserGuildApplyType[] = await UserGuildApplyModel.find({ roleId, type: GUILD_APPLY_TYPE.APPLY }).lean(); + return userGuildApply; + } + public static async getListByApplyCode(applyCodeList: string[]) { const userGuildApply: UserGuildApplyType[] = await UserGuildApplyModel.find({ applyCode: { $in: applyCodeList}, type: GUILD_APPLY_TYPE.APPLY }).lean(); return userGuildApply; diff --git a/shared/pubUtils/timeUtil.ts b/shared/pubUtils/timeUtil.ts index 27579b301..0a0267a84 100644 --- a/shared/pubUtils/timeUtil.ts +++ b/shared/pubUtils/timeUtil.ts @@ -29,4 +29,25 @@ export function checkTodayTime(seasonEndTime: number) { export function getBeforeDayDate(day: number) { let time = getTodayZeroPoint() - day * PER_DAY; return time; +} + +/** + * 获取 x天后的y点 + * @param curTime 现在时间 + * @param hour 几点刷新 + */ +export function getRefTime(now = new Date(), checkHour: number, day = 0) { + let curTime = new Date(now.getTime()); + if (checkHour < 0) { + checkHour = 24 + checkHour; + if (curTime.getHours() >= checkHour) { + curTime.setDate(curTime.getDate() + 1); + } + } else { + if (curTime.getHours() < checkHour) { + curTime.setDate(curTime.getDate() - 1); + } + } + let today = curTime.setHours(checkHour, 0, 0, 0);; + return new Date(today + day * 24 * 60 * 60 * 1000); } \ No newline at end of file diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index 40b5968cc..cdd29e33a 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -229,10 +229,8 @@ export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay = * @param curTime 现在时间 * @param hour 几点刷新 */ -export function getRefTime(now = new Date(), hour: number, day = 0) { +export function getRefTime(now = new Date(), checkHour: number, day = 0) { let curTime = new Date(now.getTime()); - let offset = curTime.getTimezoneOffset(); // 时差,单位分 - let checkHour = hour - 8 + offset / 60; if (checkHour < 0) { checkHour = 24 + checkHour; if (curTime.getHours() >= checkHour) { @@ -243,7 +241,7 @@ export function getRefTime(now = new Date(), hour: number, day = 0) { curTime.setDate(curTime.getDate() - 1); } } - let today = curTime.setHours(hour, 0, 0, 0);; + let today = curTime.setHours(checkHour, 0, 0, 0);; return new Date(today + day * 24 * 60 * 60 * 1000); } diff --git a/shared/resource/jsons/auth.json b/shared/resource/jsons/auth.json index 2970b607c..038aa8fb8 100644 --- a/shared/resource/jsons/auth.json +++ b/shared/resource/jsons/auth.json @@ -1 +1,26 @@ -[{"id": 1, "auths": "4"}] \ No newline at end of file +[ + {"id": 1, "auths": "4"}, + {"id": 2, "auths": "1&2&3&4"}, + {"id": 3, "auths": "4"}, + {"id": 4, "auths": "1&2&3&4"}, + {"id": 5, "auths": "1&2&3"}, + {"id": 6, "auths": "4"}, + {"id": 7, "auths": "4"}, + {"id": 8, "auths": "1&2&3&4"}, + {"id": 9, "auths": "1&2&3"}, + {"id": 10, "auths": "1&2"}, + {"id": 11, "auths": "1&2"}, + {"id": 12, "auths": "1&2"}, + {"id": 13, "auths": "1&2"}, + {"id": 14, "auths": "1&2"}, + {"id": 15, "auths": "1&2"}, + {"id": 16, "auths": "1&2"}, + {"id": 17, "auths": "1&2"}, + {"id": 18, "auths": "1"}, + {"id": 19, "auths": "1"}, + {"id": 20, "auths": "2&3"}, + {"id": 21, "auths": "2&3"}, + {"id": 22, "auths": "1&2"}, + {"id": 23, "auths": "1&2&3"}, + {"id": 26, "auths": "2&3"} +] \ No newline at end of file