军团,创建查询列表,查询个人军团信息

This commit is contained in:
luying
2021-01-19 16:18:45 +08:00
parent 71c5182926
commit ee21a21e80
8 changed files with 220 additions and 97 deletions
@@ -4,10 +4,12 @@ import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB } from '../../../consts';
import { UserGuildModel } from '../../../db/UserGuild'; import { UserGuildModel } from '../../../db/UserGuild';
import { checkAuth } from '../../../services/guildService'; import { checkAuth } from '../../../services/guildService';
import { GuildModel } from '../../../db/Guild'; import { GuildModel } from '../../../db/Guild';
import { RoleModel } from '../../../db/Role'; import { RoleModel, RoleType } from '../../../db/Role';
import { GUILD } from '../../../pubUtils/dicParam'; import { GUILD } from '../../../pubUtils/dicParam';
import { handleCost } from '../../../services/rewardService'; import { handleCost } from '../../../services/rewardService';
import { getGoldObject } from '../../../pubUtils/itemUtils'; import { getGoldObject } from '../../../pubUtils/itemUtils';
import { getSeconds } from '../../../pubUtils/timeUtil';
import { GuildListInfo } from '../../../pubUtils/interface';
export default function (app: Application) { export default function (app: Application) {
return new GuildHandler(app); return new GuildHandler(app);
@@ -17,7 +19,7 @@ export class GuildHandler {
constructor(private app: Application) { constructor(private app: Application) {
} }
//TODO创建军团 // 创建军团
async createGuild(msg: { name: string, icon: number, notice: string }, session: BackendSession) { async createGuild(msg: { name: string, icon: number, notice: string }, session: BackendSession) {
const roleId = session.get('roleId'); const roleId = session.get('roleId');
@@ -25,7 +27,7 @@ export class GuildHandler {
const { name, icon, notice } = msg; const { name, icon, notice } = msg;
// 检查权限是否够,包括是否参过团 // 检查权限是否够,包括是否参过团
const { auth } = await UserGuildModel.getMyGuild(roleId); const auth = await UserGuildModel.getMyAuth(roleId);
const checkResult = checkAuth(GUILD_OPERATE.CREATE_GUILD, auth); const checkResult = checkAuth(GUILD_OPERATE.CREATE_GUILD, auth);
if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); if(!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
@@ -42,33 +44,63 @@ export class GuildHandler {
await handleCost(roleId, sid, [getGoldObject(GUILD.GUILD_CREATE_COST)]); await handleCost(roleId, sid, [getGoldObject(GUILD.GUILD_CREATE_COST)]);
// 创建公会 // 创建公会
const guild = await GuildModel.createGuild({ name, icon, notice, leader: role._id, members: [roleId], ce: role.ce }); const guild = await GuildModel.createGuild({ name, icon, notice }, role);
if(!guild) return resResult(STATUS.GUILD_CREATE_ERROR); if(!guild) return resResult(STATUS.GUILD_CREATE_ERROR);
const userGuild = await UserGuildModel.createUserGuild({ guildCode: guild.code, roleId, role: role._id, guild: guild._id, auth: GUILD_AUTH.LEADER, job: GUILD_JOB.JIANGJUN }); const userGuild = await UserGuildModel.createUserGuild(guild.code, role, true);
if(!userGuild) return resResult(STATUS.GUILD_CREATE_ERROR); if(!userGuild) return resResult(STATUS.GUILD_CREATE_ERROR);
// TODO 加入排行 // TODO 加入排行
const rank = 0; const rank = 0;
// TODO 加入channel
// 返回 // 返回
const result = { ...guild, rank, myInfo: {...userGuild}}; const result = { ...guild, rank, myInfo: userGuild};
return resResult(STATUS.SUCCESS, result); return resResult(STATUS.SUCCESS, result);
} }
//TODO 获取军团列表 // 获取军团列表
async getGuildList(msg: { page: number, showPeopleMax: boolean, name: string }, session: BackendSession) { async getGuildList(msg: { page: number, showPeopleMax: boolean, name: string }, session: BackendSession) {
const list = [{ const roleId = session.get('roleId');
code: "code", // const sid = session.get('sid');
name: "name", const { page = 1, showPeopleMax, name } = msg;
icon: 1,
lv: 0, const guildList = await GuildModel.findByCondition(page, showPeopleMax, name);
memberCnt: 0, // TODO 加入申请列表
leader: "leader",
ceLimit: 0, const { quitGuildTime: quitTime = 0 } = await RoleModel.findByRoleId(roleId);
quitTime: 0,
hasApply: true const list = new Array<GuildListInfo>();
}]; for(let guild of guildList) {
return resResult(STATUS.SUCCESS, { list }); let info = new GuildListInfo(guild);
// TODO 查询申请
info.setApply(false);
list.push(info);
} }
return resResult(STATUS.SUCCESS, { quitTime, list });
}
// 团员获取自己军团详细信息
async getMyGuildInfo(msg: { }, session: BackendSession) {
const roleId = session.get('roleId');
//TODO 检查权限是否够 等策划表
const userGuild = await UserGuildModel.getMyGuild(roleId, 'honour job auth guildCode');
if(!userGuild) {
return resResult(STATUS.SUCCESS, { hasGuild: false })
};
const guild = await GuildModel.findByCode(userGuild.guildCode);
// TODO 获取排行榜
const rank = 0;
// 返回
const result = { hasGuild: true, ...guild, rank, myInfo: userGuild};
return resResult(STATUS.SUCCESS, result);
}
} }
+30 -27
View File
@@ -56,13 +56,38 @@ describe('军团测试', function() {
done(); done();
}); });
it('创建军团', function (done) { it('获取军团列表', function(done) {
pinusClient.request('battle.guildHandler.createGuild', { name: "test", icon: 1, notice: "notice" }, (res) => { pinusClient.request('battle.guildHandler.getGuildList', {page:1, showPeopleMax: true, name: ""} , (res) => {
console.log(JSON.stringify(res)) console.log(JSON.stringify(res))
// 消息回调 // 消息回调
expect(res).to.be.an('object'); expect(res).to.be.an('object');
expect(res.code).equal(0); expect(res.code).equal(0);
expect(res.data).to.be.an('object'); 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');
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');
expect(list).to.have.deep.property('icon').that.is.a('number');
expect(list).to.have.deep.property('lv').that.is.a('number');
expect(list).to.have.deep.property('memberCnt').that.is.a('number');
expect(list).to.have.deep.property('leader').that.is.a('string');
expect(list).to.have.deep.property('ceLimit').that.is.a('number');
expect(list).to.have.deep.property('hasApply').that.is.a('boolean');
});
done();
});
});
it('获取个人军团', function (done) {
pinusClient.request('battle.guildHandler.getMyGuildInfo', { }, (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('hasGuild').that.is.an('boolean');
if(res.data.hasGuild) {
expect(res.data).to.have.deep.property('code').that.is.an('string'); expect(res.data).to.have.deep.property('code').that.is.an('string');
expect(res.data).to.have.deep.property('name').that.is.an('string'); expect(res.data).to.have.deep.property('name').that.is.an('string');
expect(res.data).to.have.deep.property('icon').that.is.an('number'); expect(res.data).to.have.deep.property('icon').that.is.an('number');
@@ -79,15 +104,15 @@ describe('军团测试', function() {
expect(res.data).to.have.deep.property('isAuto').that.is.an('boolean'); expect(res.data).to.have.deep.property('isAuto').that.is.an('boolean');
expect(res.data).to.have.deep.property('leader').that.is.an('object'); expect(res.data).to.have.deep.property('leader').that.is.an('object');
expect(res.data.leader).to.have.deep.property('name').that.is.an('string'); expect(res.data.leader).to.have.deep.property('roleName').that.is.an('string');
expect(res.data.leader).to.have.deep.property('sHid').that.is.an('number'); expect(res.data.leader).to.have.deep.property('sHid').that.is.an('number');
expect(res.data.leader).to.have.deep.property('headHid').that.is.an('number'); expect(res.data.leader).to.have.deep.property('headHid').that.is.an('number');
expect(res.data.leader).to.have.deep.property('lv').that.is.an('number'); expect(res.data.leader).to.have.deep.property('lv').that.is.an('number');
expect(res.data.leader).to.have.deep.property('ce').that.is.an('number');
expect(res.data.leader).to.have.deep.property('loginTime').that.is.an('number'); expect(res.data.leader).to.have.deep.property('loginTime').that.is.an('number');
expect(res.data).to.have.deep.property('myInfo').that.is.an('object'); expect(res.data).to.have.deep.property('myInfo').that.is.an('object');
expect(res.data.myInfo).to.have.deep.property('honour').that.is.an('number'); expect(res.data.myInfo).to.have.deep.property('honour').that.is.an('number');
expect(res.data.myInfo).to.have.deep.property('active').that.is.an('number');
expect(res.data.myInfo).to.have.deep.property('job').that.is.an('number'); expect(res.data.myInfo).to.have.deep.property('job').that.is.an('number');
expect(res.data.myInfo).to.have.deep.property('auth').that.is.an('number'); expect(res.data.myInfo).to.have.deep.property('auth').that.is.an('number');
@@ -96,31 +121,9 @@ describe('军团测试', function() {
expect(list).to.have.deep.property('id').that.is.a('number'); expect(list).to.have.deep.property('id').that.is.a('number');
expect(list).to.have.deep.property('lv').that.is.a('number'); expect(list).to.have.deep.property('lv').that.is.a('number');
}); });
}
done(); done();
}); });
}); });
it('获取军团列表', function(done) {
pinusClient.request('battle.guildHandler.getGuildList', {page:1, showPeopleMax: true, name: ""} , (res) => {
console.log(JSON.stringify(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('code').that.is.a('string');
expect(list).to.have.deep.property('name').that.is.a('string');
expect(list).to.have.deep.property('icon').that.is.a('number');
expect(list).to.have.deep.property('lv').that.is.a('number');
expect(list).to.have.deep.property('peopleNum').that.is.a('number');
expect(list).to.have.deep.property('leader').that.is.a('string');
expect(list).to.have.deep.property('ceLimit').that.is.a('number');
expect(list).to.have.deep.property('quitTime').that.is.a('number');
expect(list).to.have.deep.property('hasApply').that.is.a('boolean');
});
done();
});
});
}); });
+3
View File
@@ -46,3 +46,6 @@ export enum USER_GUILD_STATUS {
QUIT = 2, // 退出 QUIT = 2, // 退出
DISMISSED = 3 // 解散 DISMISSED = 3 // 解散
} }
// 查询每页显示
export const GUILD_PER_PAGE = 30;
+39 -13
View File
@@ -1,8 +1,8 @@
import BaseModel from './BaseModel'; import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose'; import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
import Role from './Role'; import Role, { RoleType } from './Role';
import { genCode } from '../pubUtils/util'; import { genCode } from '../pubUtils/util';
import { GUILD_STRUCTURE, GUILD_STATUS } from '../consts'; import { GUILD_STRUCTURE, GUILD_STATUS, GUILD_PER_PAGE } from '../consts';
class Structure { class Structure {
@prop({ required: true }) @prop({ required: true })
@@ -29,6 +29,9 @@ export default class Guild extends BaseModel {
@prop({ required: true, default: 1 }) @prop({ required: true, default: 1 })
memberCnt: number; memberCnt: number;
@prop({ required: true, default: false, select: false })
isMemberMax: boolean;
@prop({ required: true, default: 1 }) @prop({ required: true, default: 1 })
managerCnt: number; managerCnt: number;
@@ -53,16 +56,19 @@ export default class Guild extends BaseModel {
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
activeDaily: number; activeDaily: number;
@prop({ required: true, default: new Date() }) @prop({ required: true, default: 0 })
refTimeDaily: number; activeWeekly: number;
@prop({ required: true, default: new Date() }) @prop({ required: true, default: new Date(), select: false })
refTimeWeekly: number; refTimeDaily: Date;
@prop({ required: true, default: new Date(), select: false })
refTimeWeekly: Date;
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
ce: number; // 总战力 ce: number; // 总战力
@prop({ required: true, type: String, default: [] }) @prop({ required: true, type: String, default: [], select: false })
members: string[]; // 军团成员的roleId,用于增加战力的时候加入总战力 members: string[]; // 军团成员的roleId,用于增加战力的时候加入总战力
@prop({ required: true, type: Structure, default: getInitStructure(), _id: false }) @prop({ required: true, type: Structure, default: getInitStructure(), _id: false })
@@ -71,31 +77,51 @@ export default class Guild extends BaseModel {
@prop({ required: true, default: GUILD_STATUS.RUNNING, enum: GUILD_STATUS }) @prop({ required: true, default: GUILD_STATUS.RUNNING, enum: GUILD_STATUS })
status: number; status: number;
public static async createGuild(params: CreateParam) { public static async createGuild(params: { name: string, icon: number, notice: string }, role: RoleType) {
const doc = new GuildModel(); const doc = new GuildModel();
const update = Object.assign(doc.toJSON(), params); const update = Object.assign(doc.toJSON(), params, { leader: role._id, members: [role.roleId], ce: role.ce });
delete update._id; delete update._id;
const code = genCode(6); const code = genCode(6);
const result: GuildType = await GuildModel.findOneAndUpdate({ code }, update, { upsert: true, new: true }) const result: GuildType = await GuildModel.findOneAndUpdate({ code }, update, { upsert: true, new: true })
.select('code name icon notice introduce lv fund memberCnt managerCnt activeDaily activeWeekly ceLimit isAuto leader structure') .populate('leader', 'roleName sHid headHid lv loginTime ce', 'Role')
.populate('leader', 'name sHid headHid lv updatedAt', 'Role')
.lean(); .lean();
return result; return result;
} }
public static async checkName(name: string) { public static async checkName(name: string) {
const result = await GuildModel.findOne({ name, status: 1 }).lean(); const result = await GuildModel.findOne({ name, status: GUILD_STATUS.RUNNING }).lean();
return !!result; return !!result;
} }
public static async findByCondition(page: number, showPeopleMax: boolean, name: string) {
const condition = {};
if(!showPeopleMax) {
condition['isMemberMax'] = false;
}
if(!!name) {
condition['name'] = { $regex: new RegExp(name, 'i') }
}
const guildList = await GuildModel.find(condition)
.limit(GUILD_PER_PAGE).skip((page - 1) * GUILD_PER_PAGE)
.select('code icon name lv memberCnt leader ceLimit isAuto')
.populate('leader', 'roleName', 'Role')
.lean();
return guildList;
}
public static async findByCode(code: string) {
const result = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING }, { _id: 0 })
.populate('leader', 'roleName sHid headHid lv loginTime ce', 'Role')
.lean();
return result;
}
} }
export const GuildModel = getModelForClass(Guild); export const GuildModel = getModelForClass(Guild);
export interface GuildType extends Pick<DocumentType<Guild>, keyof Guild> { }; export interface GuildType extends Pick<DocumentType<Guild>, keyof Guild> { };
export type GuildUpdateParam = Partial<GuildType>; // 将所有字段变成可选项 export type GuildUpdateParam = Partial<GuildType>; // 将所有字段变成可选项
type CreateParam = Pick<GuildType, 'name'|'icon'|'notice'|'leader'|'members'|'ce'>
function getInitStructure() { function getInitStructure() {
let structure = new Array<Structure>(); let structure = new Array<Structure>();
+10 -5
View File
@@ -6,6 +6,7 @@ import User from './User';
import { shouldRefresh } from '../pubUtils/util'; import { shouldRefresh } from '../pubUtils/util';
import { initRoleAtrr } from '../pubUtils/playerCe'; import { initRoleAtrr } from '../pubUtils/playerCe';
import Hero,{} from '../db/Hero'; import Hero,{} from '../db/Hero';
import { nowSeconds } from '../pubUtils/timeUtil';
interface roleUpdate { interface roleUpdate {
ce?: number; ce?: number;
_id?:number; _id?:number;
@@ -162,10 +163,10 @@ export default class Role extends BaseModel {
@prop({ required: true, default: 1 }) @prop({ required: true, default: 1 })
loginCnt: number; // 登录次数 loginCnt: number; // 登录次数
@prop({ required: true }) @prop({ required: true, default: nowSeconds() })
createTime: Date; // 创建时间 createTime: number; // 创建时间
@prop({ required: true }) @prop({ required: true, default: nowSeconds() })
loginTime: Date; // 更新 / 登录时间 loginTime: number; // 更新 / 登录时间
@prop({ required: true, type: Number, default: [], _id: false }) @prop({ required: true, type: Number, default: [], _id: false })
funcs: Array<number>; // 开启了的功能 funcs: Array<number>; // 开启了的功能
@@ -217,8 +218,12 @@ export default class Role extends BaseModel {
@prop({ required: true, type: Teraph, default: getInitialTeraph(), _id: false }) @prop({ required: true, type: Teraph, default: getInitialTeraph(), _id: false })
teraphs:Array<Teraph>; teraphs:Array<Teraph>;
// 公会
@prop({ required: true, default: 0 })
quitGuildTime: number; // 上次退出公会的时间
public static async findByUid(uid: number, serverId: number, lean = true) { public static async findByUid(uid: number, serverId: number, lean = true) {
const role: RoleType = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); const role: RoleType = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, { loginTime: nowSeconds() }, { new: true }).lean(lean);
return role; return role;
} }
+22 -11
View File
@@ -1,8 +1,9 @@
import BaseModel from './BaseModel'; import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose'; import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
import Role from './Role'; import Role, { RoleType } from './Role';
import Guild from './Guild'; import Guild from './Guild';
import { GUILD_AUTH, USER_GUILD_STATUS, GUILD_JOB } from '../consts'; import { GUILD_AUTH, USER_GUILD_STATUS, GUILD_JOB } from '../consts';
import { GUILD } from '../pubUtils/dicParam';
class ActiveRecord { class ActiveRecord {
@prop({ required: true }) @prop({ required: true })
@@ -22,9 +23,6 @@ export default class UserGuild extends BaseModel {
@prop({ required: true }) @prop({ required: true })
role: Ref<Role>; role: Ref<Role>;
@prop({ required: true })
guild: Ref<Guild>;
@prop({ required: true, default: GUILD_AUTH.MEMBER, enum: GUILD_AUTH }) @prop({ required: true, default: GUILD_AUTH.MEMBER, enum: GUILD_AUTH })
auth: number; auth: number;
@@ -46,17 +44,31 @@ export default class UserGuild extends BaseModel {
@prop({ required: true, default: new Date() }) @prop({ required: true, default: new Date() })
refTimeWeekly: number; refTimeWeekly: number;
public static async getMyGuild(roleId: string) { public static async getMyAuth(roleId: string, userGuild?: UserGuildType) {
const myGuild: UserGuildType = await UserGuildModel.findOne({ roleId, status: USER_GUILD_STATUS.ON }).populate('guild').lean(); let myGuild: UserGuildType;
return myGuild||{ auth: GUILD_AUTH.OTHERS }; if(!userGuild) {
myGuild = await this.getMyGuild(roleId, 'auth');
} else {
myGuild = userGuild;
}
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();
return myGuild;
} }
public static async createUserGuild(params: UserGuildCreateParam) { public static async createUserGuild(guildCode: string, role: RoleType, isLeader: boolean) {
const doc = new UserGuildModel(); const doc = new UserGuildModel();
const update = Object.assign(doc.toJSON(), params); let job = isLeader? GUILD_JOB.JIANGJUN: GUILD_JOB.SHIZHANG;
let auth = isLeader? GUILD_AUTH.LEADER: GUILD_AUTH.MEMBER;
const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, job, auth });
delete update._id; delete update._id;
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ guildCode: params.guildCode, status: USER_GUILD_STATUS.ON }, update, { upsert: true, new: true }) const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ guildCode, status: USER_GUILD_STATUS.ON }, update, { upsert: true, new: true })
.select('honour job auth') .select('honour job auth')
.lean(); .lean();
@@ -68,4 +80,3 @@ export const UserGuildModel = getModelForClass(UserGuild);
export interface UserGuildType extends Pick<DocumentType<UserGuild>, keyof UserGuild> { }; export interface UserGuildType extends Pick<DocumentType<UserGuild>, keyof UserGuild> { };
export type UserGuildUpdateParam = Partial<UserGuildType>; // 将所有字段变成可选项 export type UserGuildUpdateParam = Partial<UserGuildType>; // 将所有字段变成可选项
type UserGuildCreateParam = Pick<UserGuildType, 'guildCode'|'roleId'|'role'|'guild'|'auth'|'job'>;
+39
View File
@@ -2,6 +2,8 @@
import { reduceCe } from "./util"; import { reduceCe } from "./util";
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from "../db/generalField"; import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from "../db/generalField";
import { GuildType } from "../db/Guild";
import { RoleType } from "../db/Role";
export interface RewardInter { export interface RewardInter {
id: number; id: number;
@@ -166,3 +168,40 @@ export class PlayerDetail {
if(detail.rank) this.rank = detail.rank; if(detail.rank) this.rank = detail.rank;
} }
} }
// 军团返回
export class GuildMainInfo {
code: string; // 军团唯一编号
icon: number; // 头像
name: string; // 军团名
lv: number; // 等级
memberCnt: number; // 人数
isAuto: boolean; // 是否是自动加入
ceLimit: number; // 战力条件
constructor(guild: GuildType) {
this.code = guild.code;
this.icon = guild.icon;
this.name = guild.name;
this.lv = guild.lv;
this.memberCnt = guild.memberCnt;
this.ceLimit = guild.ceLimit;
this.isAuto = guild.isAuto;
}
}
// getGuildList里的返回
export class GuildListInfo extends GuildMainInfo {
leader: string; // 团长名
hasApply: boolean = false; // 是否有申请过
constructor(guild: GuildType) {
super(guild);
let leader = <RoleType>guild.leader;
this.leader = leader.roleName;
}
setApply(hasApply: boolean) {
this.hasApply = hasApply;
}
}
+4
View File
@@ -2,6 +2,10 @@
const PER_SECOND = 1 * 1000; const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60; const PER_DAY = 24 * 60 * 60;
export function getSeconds(time: Date) {
return Math.floor(time.getTime() / PER_SECOND);
}
export function nowSeconds() { export function nowSeconds() {
return Math.floor(Date.now() / PER_SECOND ); return Math.floor(Date.now() / PER_SECOND );
} }