军团:修改个人功勋→个人活跃

This commit is contained in:
luying
2021-01-25 09:43:03 +08:00
parent bb2f17089e
commit c4a106745b
11 changed files with 130 additions and 53 deletions
@@ -1,8 +1,8 @@
import { Application, BackendSession, pinus, ChannelService } from 'pinus'; import { Application, BackendSession, pinus, ChannelService } from 'pinus';
import { resResult, getRandEelm, reduceCe } from '../../../pubUtils/util'; import { resResult, getRandEelm, reduceCe, getRefTime } from '../../../pubUtils/util';
import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB, GUILD_APPLY_TYPE, GUILD_STRUCTURE, GUILD_REC_TYPE, GUILD_STRUCTURE_NAME, MAIL_TYPE } from '../../../consts'; import { STATUS, GUILD_OPERATE, GUILD_AUTH, GUILD_JOB, GUILD_APPLY_TYPE, GUILD_STRUCTURE, GUILD_REC_TYPE, GUILD_STRUCTURE_NAME, MAIL_TYPE } from '../../../consts';
import { UserGuildModel } from '../../../db/UserGuild'; import { UserGuildModel } from '../../../db/UserGuild';
import { checkAuth, joinGuild, getGuildWithRefActive, getUserGuildWithRefActive, addGuildActive, message } from '../../../services/guildService'; import { checkAuth, joinGuild, getGuildWithRefActive, getUserGuildWithRefActive, addGuildActive, message, settleGuildWeekly } from '../../../services/guildService';
import { GuildModel, GuildType } from '../../../db/Guild'; import { GuildModel, GuildType } from '../../../db/Guild';
import { RoleModel, RoleType } from '../../../db/Role'; import { RoleModel, RoleType } from '../../../db/Role';
import { ARMY } from '../../../pubUtils/dicParam'; import { ARMY } from '../../../pubUtils/dicParam';
@@ -227,7 +227,7 @@ export class GuildHandler {
const serverId = session.get('serverId'); const serverId = session.get('serverId');
const sid = session.get('sid'); const sid = session.get('sid');
let userGuild = await getUserGuildWithRefActive(roleId, 'honour job auth guildCode receivedActive'); let userGuild = await getUserGuildWithRefActive(roleId, 'job auth guildCode receivedActive activeRecord activeDaily activeWeekly');
if(!userGuild) { if(!userGuild) {
return resResult(STATUS.SUCCESS, { hasGuild: false }) return resResult(STATUS.SUCCESS, { hasGuild: false })
}; };
@@ -495,7 +495,7 @@ export class GuildHandler {
let select = ['role', 'job']; let select = ['role', 'job'];
const checkDetailResult = await checkAuth(GUILD_OPERATE.GET_MEMBER_LIST_DETAIL, roleId, code); const checkDetailResult = await checkAuth(GUILD_OPERATE.GET_MEMBER_LIST_DETAIL, roleId, code);
if(checkDetailResult) { if(checkDetailResult) {
select.push('auth', 'honourWeekly honourUpdateTime'); select.push('auth', 'activeWeekly activeUpdateTime');
} }
let list = await UserGuildModel.getListByGuild(code, select.join(' '), { auth: 1 }); let list = await UserGuildModel.getListByGuild(code, select.join(' '), { auth: 1 });
console.log('**', JSON.stringify(list)) console.log('**', JSON.stringify(list))
@@ -508,11 +508,11 @@ export class GuildHandler {
let leader = result.shift(); let leader = result.shift();
result.sort((a, b) => { result.sort((a, b) => {
if(sort == 'honour') { if(sort == 'active') {
if(b.honourWeekly == a.honourWeekly) { if(b.activeWeekly == a.activeWeekly) {
return a.honourUpdateTime - b.honourUpdateTime return a.activeUpdateTime - b.activeUpdateTime
} else { } else {
return b.honourWeekly - a.honourWeekly return b.activeWeekly - a.activeWeekly
} }
} else if (sort == 'loginTime') { } else if (sort == 'loginTime') {
return b.loginTime - a.loginTime; return b.loginTime - a.loginTime;
@@ -640,7 +640,7 @@ export class GuildHandler {
return resResult(STATUS.GUILD_LEADER_LOGIN); return resResult(STATUS.GUILD_LEADER_LOGIN);
} }
// 上周周功勋最高的人 // 上周周功勋最高的人
const topUserGuild = await UserGuildModel.findTopHonour(code, 'auth role roleId'); const topUserGuild = await UserGuildModel.findTopActive(code, 'auth role roleId');
if (!topUserGuild) { if (!topUserGuild) {
return resResult(STATUS.GUILD_MEMBER_NOT_FOUND); return resResult(STATUS.GUILD_MEMBER_NOT_FOUND);
} }
@@ -740,7 +740,8 @@ export class GuildHandler {
const checkResult = await checkAuth(GUILD_OPERATE.GET_REC, roleId, code); const checkResult = await checkAuth(GUILD_OPERATE.GET_REC, roleId, code);
if (!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH); if (!checkResult) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
const list = await GuildRecModel.getGuildRec(code); let startTime = getRefTime(new Date(), 0, -3);
const list = await GuildRecModel.getGuildRec(code, startTime.getTime());
return resResult(STATUS.SUCCESS, { list }); return resResult(STATUS.SUCCESS, { list });
} }
@@ -826,16 +827,33 @@ export class GuildHandler {
// debug接口: 添加公会活跃值 // debug接口: 添加公会活跃值
async debugAddActive(msg: { code: string, active: number }, session: BackendSession) { async debugAddActive(msg: { code: string, active: number, id: number }, session: BackendSession) {
const roleId = session.get('roleId');
const serverId = session.get('serverId'); const serverId = session.get('serverId');
const { code, active } = msg; const { code, active, id } = msg;
const guild = await addGuildActive(code, serverId, active); const guild = await addGuildActive(code, serverId, active);
if(!guild) return resResult(STATUS.GUILD_NOT_FOUND); if(!guild) return resResult(STATUS.GUILD_NOT_FOUND);
let userGuild = await UserGuildModel.getMyGuild(roleId, 'activeRecord receivedActive');
let {activeRecord} = userGuild;
let curActiveRecord = activeRecord.find(cur => cur.id == id);
if( curActiveRecord ) {
curActiveRecord.count ++;
} else {
activeRecord.push({id, count: 1});
}
userGuild = await UserGuildModel.updateInfo(roleId, { activeRecord, activeDaily: userGuild.activeDaily + active, activeWeekly: userGuild.activeWeekly + active})
let { activeDaily, activeWeekly } = guild; let { activeDaily, activeWeekly } = guild;
return resResult(STATUS.SUCCESS, { activeDaily, activeWeekly }); return resResult(STATUS.SUCCESS, { activeDaily, activeWeekly, myInfo: userGuild });
} }
// debug接口: 调用定时任务
async debugWeeklyRask(msg: { }, session: BackendSession) {
await settleGuildWeekly();
return resResult(STATUS.SUCCESS);
}
} }
+63 -8
View File
@@ -1,7 +1,7 @@
import { gameData } from "../pubUtils/data"; import { gameData, getGuildActiveWeekReward } from "../pubUtils/data";
import { GuildModel, GuildType } from "../db/Guild"; import { GuildModel, GuildType } from "../db/Guild";
import { resResult, shouldRefreshWeek, shouldRefresh } from "../pubUtils/util"; import { resResult, shouldRefreshWeek, shouldRefresh } from "../pubUtils/util";
import { STATUS, GUILD_OPERATE, MAIL_TYPE } from "../consts"; import { STATUS, GUILD_OPERATE, MAIL_TYPE, GUILD_AUTH, GUILD_JOB } from "../consts";
import { RoleModel, RoleType } from "../db/Role"; import { RoleModel, RoleType } from "../db/Role";
import { UserGuildModel, UserGuildType } from "../db/UserGuild"; import { UserGuildModel, UserGuildType } from "../db/UserGuild";
import { UserGuildApplyModel } from "../db/UserGuildApply"; import { UserGuildApplyModel } from "../db/UserGuildApply";
@@ -12,6 +12,8 @@ import { GuildRecType } from "../db/GuildRec";
import { MailModel } from "../db/Mail"; import { MailModel } from "../db/Mail";
import { RewardInter } from "../pubUtils/interface"; import { RewardInter } from "../pubUtils/interface";
import { getRedis } from "./redisService"; import { getRedis } from "./redisService";
import { ARMY } from "../pubUtils/dicParam";
import { sendMail } from "./mailService";
/** /**
* @description 检查该玩家是否有权限做操作 * @description 检查该玩家是否有权限做操作
@@ -121,14 +123,14 @@ export async function addGuildActive(guildCode: string, serverId: number, active
export async function getUserGuildWithRefActive(roleId: string, select: string) { export async function getUserGuildWithRefActive(roleId: string, select: string) {
let userGuild = await UserGuildModel.getMyGuild(roleId, select? select + ' +refTimeDaily': '+refTimeDaily'); let userGuild = await UserGuildModel.getMyGuild(roleId, select? select + ' +refTimeDaily': '+refTimeDaily');
if(!userGuild) return false; if(!userGuild) return false;
let { receivedActive, refTimeDaily } = userGuild; let { receivedActive, refTimeDaily, activeDaily, activeRecord } = userGuild;
const now = new Date(); const now = new Date();
let isRefDaily = shouldRefresh(refTimeDaily, now, 0); let isRefDaily = shouldRefresh(refTimeDaily, now, 0);
if(isRefDaily) { if(isRefDaily) {
receivedActive = 0; refTimeDaily = now; receivedActive = 0; refTimeDaily = now; activeDaily = 0; activeRecord = [];
userGuild = await UserGuildModel.updateInfo(roleId, { receivedActive, refTimeDaily }, select); userGuild = await UserGuildModel.updateInfo(roleId, { receivedActive, refTimeDaily, activeDaily, activeRecord }, select);
if(!userGuild) return false; if(!userGuild) return false;
} }
@@ -141,15 +143,68 @@ export async function getUserGuildWithRefActive(roleId: string, select: string)
*/ */
export async function settleGuildWeekly() { export async function settleGuildWeekly() {
console.log('————— settleGuildWeekly —————'); console.log('————— settleGuildWeekly —————');
const guildList = await GuildModel.findAllGuild('code activeWeekly'); const guildList = await GuildModel.findAllGuild('code activeWeekly memberCnt');
for(let { code, activeWeekly, memberCnt } of guildList) {
const userGuildList = await UserGuildModel.getListByGuild(code, 'roleId auth activeWeekly', { activeWeekly: -1, activeUpdateTime: 1 });
let activeMemberCnt = 0; // 活跃度高于100的成员人数
let otherMemberNum = 0; // 除了大将军以外从活跃高到底成员人数,用户计算活跃排名百分比
let jobCnt = new Map<number, number>();
let members = new Map<string, {job: number, active: boolean}>();
for(let {roleId, auth, activeWeekly} of userGuildList) {
let active = false;
let job = 0;
if(activeWeekly > 100) {
activeMemberCnt ++;
active = true;
}
if(auth == GUILD_AUTH.LEADER) {
job = GUILD_JOB.DAJIANGJUN;
} else if (activeWeekly <= 100) {
job = GUILD_JOB.SHIBING;
} else {
otherMemberNum++;
for(let [id, {rankProportion}] of gameData.guildPosition) {
let rankCnt = Math.ceil(memberCnt * rankProportion / 100);
console.log('*', id, memberCnt, rankProportion, otherMemberNum, rankCnt)
job = id;
if(otherMemberNum < rankCnt) break;
}
}
await UserGuildModel.updateInfo(roleId, { job, activeWeekly: 0 });
if(!jobCnt.has(job)) jobCnt.set(job, 0);
jobCnt.set(job, jobCnt.get(job) + 1);
members.set(roleId, {job, active});
}
for(let { code, activeWeekly } of guildList) {
// 转换周活跃奖励 // 转换周活跃奖励
const userGuildList = await UserGuildModel.getListByGuild(code, 'honourWeekly', { honourWeekly: -1, honourUpdateTime: 1 }); let allWeeklyReward = getGuildActiveWeekReward(activeWeekly);
let ratio = 1;
let averageBase = ratio * ( 1- ARMY.ARMY_POSITION_WEEKREWARD) / 100; // 70% 活跃值高于100均分
let positionBase = ratio * ARMY.ARMY_POSITION_WEEKREWARD / 100; // 30% 职位均分
for(let [roleId, {job, active}] of members) {
let myAverageRatio = active? (averageBase / activeMemberCnt): 0;
let jobActiveRatio = gameData.guildPosition.get(job).activeRatio / 100;
let myJobRewardRatio = positionBase * jobActiveRatio / jobCnt.get(job);
let reward = allWeeklyReward.map(cur => {
return {
id: cur.id,
count: Math.ceil(cur.count * (myAverageRatio + myJobRewardRatio))
}
});
await sendMail(MAIL_TYPE.GUILD_ACTIVE_REWARD, roleId, '系统', [], reward);
}
await GuildModel.updateInfo(code, { activeWeekly: 0 }, {});
} }
await SystemConfigModel.updateSystemConfig({settleGuildWeeklyTime: nowSeconds()}); // 记录一下 await SystemConfigModel.updateSystemConfig({settleGuildWeeklyTime: nowSeconds()}); // 记录一下
console.log('————— settleGuildWeekly结束 —————');
} }
export const message = { export const message = {
+1 -1
View File
@@ -4,7 +4,7 @@ import { getRedis } from "./redisService";
import { pinus } from "pinus"; import { pinus } from "pinus";
import { gameData } from "../pubUtils/data"; import { gameData } from "../pubUtils/data";
export async function sendMail(operate: number, toRoleId: string, sendName: string, params: string[], goods: RewardInter[] = []) { export async function sendMail(operate: number, toRoleId: string, sendName: string = '系统', params: string[] = [], goods: RewardInter[] = []) {
let content = getContent( operate, params); let content = getContent( operate, params);
let mail = await MailModel.addMail({roleId: toRoleId, goods, sendName, mailId: 1, content}); let mail = await MailModel.addMail({roleId: toRoleId, goods, sendName, mailId: 1, content});
+2 -2
View File
@@ -32,8 +32,8 @@ export enum GUILD_AUTH {
// 职位 // 职位
export enum GUILD_JOB { export enum GUILD_JOB {
JIANGJUN = 1, DAJIANGJUN = 1,
FUJIANGJUN = 2, JIANGJUN = 2,
XIAOWEI = 3, XIAOWEI = 3,
SHIZHANG = 4, SHIZHANG = 4,
WUZHANG = 5, WUZHANG = 5,
+2 -2
View File
@@ -34,8 +34,8 @@ export default class GuildRec extends BaseModel {
return result; return result;
} }
public static async getGuildRec(guildCode: string) { public static async getGuildRec(guildCode: string, time: number) {
const result: GuildRecType[] = await GuildRecModel.find({ guildCode }).sort({createTime: -1}).lean(); const result: GuildRecType[] = await GuildRecModel.find({ guildCode, createTime: { $gte: time } }).sort({createTime: -1}).lean();
return result; return result;
} }
} }
+10 -12
View File
@@ -28,10 +28,13 @@ export default class UserGuild extends BaseModel {
job: number; job: number;
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
honourWeekly: number; activeWeekly: number;
@prop({ required: true, default: 0 })
activeDaily: number;
@prop({ required: true, default: Date.now() }) @prop({ required: true, default: Date.now() })
honourUpdateTime: number; activeUpdateTime: number;
@prop({ required: true, default: USER_GUILD_STATUS.ON, enum: USER_GUILD_STATUS}) @prop({ required: true, default: USER_GUILD_STATUS.ON, enum: USER_GUILD_STATUS})
status: number; status: number;
@@ -76,7 +79,7 @@ export default class UserGuild extends BaseModel {
return myGuild; return myGuild;
} }
public static async getListByGuild(guildCode: string, select?: string, sort: { auth?: number, honourWeekly?: number, honourUpdateTime?: number } = {auth: 1}) { public static async getListByGuild(guildCode: string, select?: string, sort: { auth?: number, activeWeekly?: number, activeUpdateTime?: number } = {auth: 1}) {
const userGuilds: UserGuildType[] = await UserGuildModel.find({ guildCode, status: USER_GUILD_STATUS.ON }) const userGuilds: UserGuildType[] = await UserGuildModel.find({ guildCode, status: USER_GUILD_STATUS.ON })
.select(select) .select(select)
.sort(sort) .sort(sort)
@@ -85,9 +88,9 @@ export default class UserGuild extends BaseModel {
return userGuilds; return userGuilds;
} }
public static async findTopHonour(guildCode: string, select?: string) { public static async findTopActive(guildCode: string, select?: string) {
const userGuilds: UserGuildType = await UserGuildModel.findOne({ guildCode, status: USER_GUILD_STATUS.ON, auth: { $ne: GUILD_AUTH.LEADER } }) const userGuilds: UserGuildType = await UserGuildModel.findOne({ guildCode, status: USER_GUILD_STATUS.ON, auth: { $ne: GUILD_AUTH.LEADER } })
.sort({ honourWeekly: -1, honourUpdateTime: 1 }) .sort({ activeWeekly: -1, activeUpdateTime: 1 })
.select(select) .select(select)
.populate('role', 'roleId roleName ce headHid sHid lv title loginTime', 'Role') .populate('role', 'roleId roleName ce headHid sHid lv title loginTime', 'Role')
.lean(); .lean();
@@ -96,12 +99,12 @@ export default class UserGuild extends BaseModel {
public static async createUserGuild(guildCode: string, role: RoleType, isLeader: boolean) { public static async createUserGuild(guildCode: string, role: RoleType, isLeader: boolean) {
const doc = new UserGuildModel(); const doc = new UserGuildModel();
let job = isLeader? GUILD_JOB.JIANGJUN: GUILD_JOB.SHIZHANG; let job = isLeader? GUILD_JOB.DAJIANGJUN: GUILD_JOB.SHIBING;
let auth = isLeader? GUILD_AUTH.LEADER: GUILD_AUTH.MEMBER; let auth = isLeader? GUILD_AUTH.LEADER: GUILD_AUTH.MEMBER;
const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, role: role._id, job, auth }); const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, role: role._id, job, auth });
delete update._id; delete update._id;
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId: role.roleId, 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 honourUpdateTime job auth receivedActive') .select('activeDaily activeRecord activeWeekly activeUpdateTime job auth receivedActive')
.lean(); .lean();
return result; return result;
@@ -124,11 +127,6 @@ export default class UserGuild extends BaseModel {
return result; return result;
} }
public static async addHonourWeekly(roleId: string, inc: number, select?: string) {
const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON }, { $inc: { honourWeekly: inc } }, { new: true }).select(select).lean();
return result;
}
public static async receiveTrainRewards(roleId: string, trainId: number, lean = true) { public static async receiveTrainRewards(roleId: string, trainId: number, lean = true) {
const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON, 'trainRewards':{$ne: trainId }}, const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON, 'trainRewards':{$ne: trainId }},
{$push:{trainRewards: trainId} },{new: true}).lean(lean); {$push:{trainRewards: trainId} },{new: true}).lean(lean);
+10
View File
@@ -51,6 +51,7 @@ import { dicGuildPosition } from "./dictionary/DicGuildPosition";
import { dicMail } from "./dictionary/DicMail"; import { dicMail } from "./dictionary/DicMail";
import { dicArmyTrainJuDian } from './dictionary/dicArmyTrainJuDian'; import { dicArmyTrainJuDian } from './dictionary/dicArmyTrainJuDian';
import { dicTrainSoloReward } from './dictionary/dicTrainSoloReward'; import { dicTrainSoloReward } from './dictionary/dicTrainSoloReward';
import { RewardInter } from "./interface";
export const gameData = { export const gameData = {
blurprtCompose: dicBlueprtCompose, blurprtCompose: dicBlueprtCompose,
@@ -350,3 +351,12 @@ export function getTrainBaseByLv(lv: number) {
} }
export function getGuildActiveWeekReward(point: number) {
let result = gameData.guildActiveWeekReward.find(cur => {
let {weekPointMax, weekPointMin} = cur;
return point >= weekPointMin && point <= (weekPointMax || weekPointMax == -1);
});
let reward = new Array<RewardInter>();
if(result) reward = result.reward;
return reward;
}
@@ -19,10 +19,10 @@ export interface DicGuildActiveWeekReward {
const str = readJsonFile(FILENAME.DIC_ACTIVE_DAY_REWARD); const str = readJsonFile(FILENAME.DIC_ACTIVE_DAY_REWARD);
let arr = JSON.parse(str); let arr = JSON.parse(str);
export const dicGuildActiveWeekReward = new Map<number, DicGuildActiveWeekReward>(); export const dicGuildActiveWeekReward = new Array<DicGuildActiveWeekReward>();
arr.forEach(o => { arr.forEach(o => {
o.reward = parseGoodStr(o.Reward) o.reward = parseGoodStr(o.Reward)
dicGuildActiveWeekReward.set(o.id, o); dicGuildActiveWeekReward.push(o);
}); });
arr = undefined; arr = undefined;
@@ -16,7 +16,7 @@ export interface DicGuildPosition {
readonly activeRatio: number; readonly activeRatio: number;
} }
const str = readJsonFile(FILENAME.DIC_BLUEPRT_COMPOSE); const str = readJsonFile(FILENAME.DIC_GUILD_POSITION);
let arr = JSON.parse(str); let arr = JSON.parse(str);
export const dicGuildPosition = new Map<number, DicGuildPosition>(); export const dicGuildPosition = new Map<number, DicGuildPosition>();
+6 -6
View File
@@ -102,7 +102,7 @@ export interface DicDonateBase {
// 捐献值 // 捐献值
readonly donateValue: {type: number, count: number}[]; readonly donateValue: {type: number, count: number}[];
// 捐献奖励 // 捐献奖励
readonly donateReward: {fund: number, honour: number}[]; readonly donateReward: {fund: number, active: number}[];
// 今日捐献宝箱领取奖励系数 // 今日捐献宝箱领取奖励系数
readonly boxRewardRatio: number; readonly boxRewardRatio: number;
} }
@@ -259,16 +259,16 @@ export function parseDonateValue(str: string) {
return result return result
} }
// {"fund": number, "honour": number} // {"fund": number, "active": number}
export function parseDonateReward(str: string) { export function parseDonateReward(str: string) {
let result = new Array<{ fund: number, honour: number }>(); let result = new Array<{ fund: number, active: number }>();
if (!str) return result; if (!str) return result;
let decodeArr = decodeArrayListStr(str); let decodeArr = decodeArrayListStr(str);
for (let [fund, honour] of decodeArr) { for (let [fund, active] of decodeArr) {
if (isNaN(parseInt(fund)) || isNaN(parseInt(honour))) { if (isNaN(parseInt(fund)) || isNaN(parseInt(active))) {
throw new Error('data table format wrong'); throw new Error('data table format wrong');
} }
result.push({ fund: parseInt(fund), honour: parseInt(honour) }); result.push({ fund: parseInt(fund), active: parseInt(active) });
} }
return result return result
} }
-4
View File
@@ -28,10 +28,6 @@ export async function addSkins(roleId: string, id: number) {
export async function addBags(roleId: string, roleName: string, data: BagInter) { export async function addBags(roleId: string, roleName: string, data: BagInter) {
let { id, count, itemName, type, hid } = data; let { id, count, itemName, type, hid } = data;
let item = await ItemModel.increaseItem(roleId, id, count, { roleId, roleName, itemName, id, type, hid }); let item = await ItemModel.increaseItem(roleId, id, count, { roleId, roleName, itemName, id, type, hid });
if(item.id == CURRENCY_BY_TYPE.get(CURRENCY_TYPE.HONOUR) ) {
await UserGuildModel.addHonourWeekly(roleId, count);
}
return { id: item.id, count: item.count }; return { id: item.id, count: item.count };
} }