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

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

View File

@@ -4,10 +4,12 @@ import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB } from '../../../consts';
import { UserGuildModel } from '../../../db/UserGuild';
import { checkAuth } from '../../../services/guildService';
import { GuildModel } from '../../../db/Guild';
import { RoleModel } from '../../../db/Role';
import { 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 { GuildListInfo } from '../../../pubUtils/interface';
export default function (app: Application) {
return new GuildHandler(app);
@@ -17,7 +19,7 @@ export class GuildHandler {
constructor(private app: Application) {
}
//TODO创建军团
// 创建军团
async createGuild(msg: { name: string, icon: number, notice: string }, session: BackendSession) {
const roleId = session.get('roleId');
@@ -25,7 +27,7 @@ export class GuildHandler {
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);
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)]);
// 创建公会
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);
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);
// TODO 加入排行
const rank = 0;
// TODO 加入channel
// 返回
const result = { ...guild, rank, myInfo: {...userGuild}};
const result = { ...guild, rank, myInfo: userGuild};
return resResult(STATUS.SUCCESS, result);
}
//TODO 获取军团列表
// 获取军团列表
async getGuildList(msg: { page: number, showPeopleMax: boolean, name: string }, session: BackendSession) {
const roleId = session.get('roleId');
// const sid = session.get('sid');
const { page = 1, showPeopleMax, name } = msg;
const list = [{
code: "code",
name: "name",
icon: 1,
lv: 0,
memberCnt: 0,
leader: "leader",
ceLimit: 0,
quitTime: 0,
hasApply: true
}];
return resResult(STATUS.SUCCESS, { list });
const guildList = await GuildModel.findByCondition(page, showPeopleMax, name);
// TODO 加入申请列表
const { quitGuildTime: quitTime = 0 } = await RoleModel.findByRoleId(roleId);
const list = new Array<GuildListInfo>();
for(let guild of guildList) {
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);
}
}

View File

@@ -56,51 +56,6 @@ describe('军团测试', function() {
done();
});
it('创建军团', function (done) {
pinusClient.request('battle.guildHandler.createGuild', { name: "test", icon: 1, notice: "notice" }, (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('code').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('notice').that.is.an('string');
expect(res.data).to.have.deep.property('introduce').that.is.an('string');
expect(res.data).to.have.deep.property('rank').that.is.an('number');
expect(res.data).to.have.deep.property('lv').that.is.an('number');
expect(res.data).to.have.deep.property('fund').that.is.an('number');
expect(res.data).to.have.deep.property('memberCnt').that.is.an('number');
expect(res.data).to.have.deep.property('managerCnt').that.is.an('number');
expect(res.data).to.have.deep.property('activeDaily').that.is.an('number');
expect(res.data).to.have.deep.property('activeWeekly').that.is.an('number');
expect(res.data).to.have.deep.property('ceLimit').that.is.an('number');
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.leader).to.have.deep.property('name').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('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('loginTime').that.is.an('number');
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('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('auth').that.is.an('number');
expect(res.data).to.have.deep.property('structure').that.is.an('array');
res.data.structure.forEach(list => {
expect(list).to.have.deep.property('id').that.is.a('number');
expect(list).to.have.deep.property('lv').that.is.a('number');
});
done();
});
});
it('获取军团列表', function(done) {
pinusClient.request('battle.guildHandler.getGuildList', {page:1, showPeopleMax: true, name: ""} , (res) => {
console.log(JSON.stringify(res))
@@ -109,18 +64,66 @@ describe('军团测试', function() {
expect(res.code).equal(0);
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('peopleNum').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('quitTime').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('name').that.is.an('string');
expect(res.data).to.have.deep.property('icon').that.is.an('number');
expect(res.data).to.have.deep.property('notice').that.is.an('string');
expect(res.data).to.have.deep.property('introduce').that.is.an('string');
expect(res.data).to.have.deep.property('rank').that.is.an('number');
expect(res.data).to.have.deep.property('lv').that.is.an('number');
expect(res.data).to.have.deep.property('fund').that.is.an('number');
expect(res.data).to.have.deep.property('memberCnt').that.is.an('number');
expect(res.data).to.have.deep.property('managerCnt').that.is.an('number');
expect(res.data).to.have.deep.property('activeDaily').that.is.an('number');
expect(res.data).to.have.deep.property('activeWeekly').that.is.an('number');
expect(res.data).to.have.deep.property('ceLimit').that.is.an('number');
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.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('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('ce').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.myInfo).to.have.deep.property('honour').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).to.have.deep.property('structure').that.is.an('array');
res.data.structure.forEach(list => {
expect(list).to.have.deep.property('id').that.is.a('number');
expect(list).to.have.deep.property('lv').that.is.a('number');
});
}
done();
});
});
});

View File

@@ -45,4 +45,7 @@ export enum USER_GUILD_STATUS {
ON = 1, // 成员
QUIT = 2, // 退出
DISMISSED = 3 // 解散
}
}
// 查询每页显示
export const GUILD_PER_PAGE = 30;

View File

@@ -1,8 +1,8 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
import Role from './Role';
import Role, { RoleType } from './Role';
import { genCode } from '../pubUtils/util';
import { GUILD_STRUCTURE, GUILD_STATUS } from '../consts';
import { GUILD_STRUCTURE, GUILD_STATUS, GUILD_PER_PAGE } from '../consts';
class Structure {
@prop({ required: true })
@@ -29,6 +29,9 @@ export default class Guild extends BaseModel {
@prop({ required: true, default: 1 })
memberCnt: number;
@prop({ required: true, default: false, select: false })
isMemberMax: boolean;
@prop({ required: true, default: 1 })
managerCnt: number;
@@ -53,16 +56,19 @@ export default class Guild extends BaseModel {
@prop({ required: true, default: 0 })
activeDaily: number;
@prop({ required: true, default: new Date() })
refTimeDaily: number;
@prop({ required: true, default: 0 })
activeWeekly: number;
@prop({ required: true, default: new Date() })
refTimeWeekly: number;
@prop({ required: true, default: new Date(), select: false })
refTimeDaily: Date;
@prop({ required: true, default: new Date(), select: false })
refTimeWeekly: Date;
@prop({ required: true, default: 0 })
ce: number; // 总战力
@prop({ required: true, type: String, default: [] })
@prop({ required: true, type: String, default: [], select: false })
members: string[]; // 军团成员的roleId用于增加战力的时候加入总战力
@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 })
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 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;
const code = genCode(6);
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', 'name sHid headHid lv updatedAt', 'Role')
.populate('leader', 'roleName sHid headHid lv loginTime ce', 'Role')
.lean();
return result;
}
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;
}
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 interface GuildType extends Pick<DocumentType<Guild>, keyof Guild> { };
export type GuildUpdateParam = Partial<GuildType>; // 将所有字段变成可选项
type CreateParam = Pick<GuildType, 'name'|'icon'|'notice'|'leader'|'members'|'ce'>
function getInitStructure() {
let structure = new Array<Structure>();

View File

@@ -6,6 +6,7 @@ import User from './User';
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;
@@ -162,10 +163,10 @@ export default class Role extends BaseModel {
@prop({ required: true, default: 1 })
loginCnt: number; // 登录次数
@prop({ required: true })
createTime: Date; // 创建时间
@prop({ required: true })
loginTime: Date; // 更新 / 登录时间
@prop({ required: true, default: nowSeconds() })
createTime: number; // 创建时间
@prop({ required: true, default: nowSeconds() })
loginTime: number; // 更新 / 登录时间
@prop({ required: true, type: Number, default: [], _id: false })
funcs: Array<number>; // 开启了的功能
@@ -217,8 +218,12 @@ export default class Role extends BaseModel {
@prop({ required: true, type: Teraph, default: getInitialTeraph(), _id: false })
teraphs:Array<Teraph>;
// 公会
@prop({ required: true, default: 0 })
quitGuildTime: number; // 上次退出公会的时间
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;
}

View File

@@ -1,8 +1,9 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
import Role from './Role';
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 })
@@ -22,9 +23,6 @@ export default class UserGuild extends BaseModel {
@prop({ required: true })
role: Ref<Role>;
@prop({ required: true })
guild: Ref<Guild>;
@prop({ required: true, default: GUILD_AUTH.MEMBER, enum: GUILD_AUTH })
auth: number;
@@ -45,18 +43,32 @@ export default class UserGuild extends BaseModel {
@prop({ required: true, default: new Date() })
refTimeWeekly: number;
public static async getMyGuild(roleId: string) {
const myGuild: UserGuildType = await UserGuildModel.findOne({ roleId, status: USER_GUILD_STATUS.ON }).populate('guild').lean();
return myGuild||{ auth: GUILD_AUTH.OTHERS };
public static async getMyAuth(roleId: string, userGuild?: UserGuildType) {
let myGuild: UserGuildType;
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 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;
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')
.lean();
@@ -68,4 +80,3 @@ export const UserGuildModel = getModelForClass(UserGuild);
export interface UserGuildType extends Pick<DocumentType<UserGuild>, keyof UserGuild> { };
export type UserGuildUpdateParam = Partial<UserGuildType>; // 将所有字段变成可选项
type UserGuildCreateParam = Pick<UserGuildType, 'guildCode'|'roleId'|'role'|'guild'|'auth'|'job'>;

View File

@@ -2,6 +2,8 @@
import { reduceCe } from "./util";
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from "../db/generalField";
import { GuildType } from "../db/Guild";
import { RoleType } from "../db/Role";
export interface RewardInter {
id: number;
@@ -165,4 +167,41 @@ export class PlayerDetail {
if(detail.heroes) this.heroes = detail.heroes;
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;
}
}

View File

@@ -2,6 +2,10 @@
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
export function getSeconds(time: Date) {
return Math.floor(time.getTime() / PER_SECOND);
}
export function nowSeconds() {
return Math.floor(Date.now() / PER_SECOND );
}