后台:添加操作日志

This commit is contained in:
luying
2021-12-22 17:10:10 +08:00
parent 5573faafb1
commit 8c488ea710
14 changed files with 273 additions and 28 deletions

View File

@@ -4,7 +4,7 @@ import { EventRecordModel } from '../../../db/EventRecord';
import { getEvent } from '../../../services/eventSercive';
import { getRandSingleEelm, resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import { GMMailModel } from '../../../db/GMMail';
import { GMMailModel, GMMailType } from '../../../db/GMMail';
import { delGuildActivityRank, getRoleOnlineInfo } from '../../../services/redisService';
import { SendMailFun } from '../../../services/mailService';
import { GM_MAIL_STATUS, GM_MAIL_TYPE, MAIL_TIME_TYPE, REF_CIRCLE_MAIL_TIME } from '../../../consts';
@@ -31,13 +31,41 @@ export class GmHandler {
constructor(private app: Application) {
}
//对接gm后台下发邮件
async sendMail(msg: { id: string, isPass: boolean }, session: BackendSession) {
async sendSingleMail(msg: { id: string, isPass: boolean }, session: BackendSession) {
const uid: number = session.get('uid')
let { id, isPass } = msg;
let gmmail = await GMMailModel.getGmMailById(id);
let gmmail = await GMMailModel.getGmMailByIdAndType(id, GM_MAIL_TYPE.SINGLE, true);
if(!gmmail) return resResult(STATUS.GM_MAIL_NOT_FOUND);
return await this.sendMail(gmmail, isPass, uid);
}
async sendSingleMailTxt(msg: { id: string, isPass: boolean }, session: BackendSession) {
const uid: number = session.get('uid')
let { id, isPass } = msg;
let gmmail = await GMMailModel.getGmMailByIdAndType(id, GM_MAIL_TYPE.SINGLE, false);
if(!gmmail) return resResult(STATUS.GM_MAIL_NOT_FOUND);
return await this.sendMail(gmmail, isPass, uid);
}
async sendServerMail(msg: { id: string, isPass: boolean }, session: BackendSession) {
const uid: number = session.get('uid')
let { id, isPass } = msg;
let gmmail = await GMMailModel.getGmMailByIdAndType(id, GM_MAIL_TYPE.SERVER, true);
if(!gmmail) return resResult(STATUS.GM_MAIL_NOT_FOUND);
return await this.sendMail(gmmail, isPass, uid);
}
async sendSserverMailTxt(msg: { id: string, isPass: boolean }, session: BackendSession) {
const uid: number = session.get('uid')
let { id, isPass } = msg;
let gmmail = await GMMailModel.getGmMailByIdAndType(id, GM_MAIL_TYPE.SERVER, false);
if(!gmmail) return resResult(STATUS.GM_MAIL_NOT_FOUND);
return await this.sendMail(gmmail, isPass, uid);
}
//对接gm后台下发邮件
async sendMail(gmmail: GMMailType, isPass: boolean, uid: number) {
let id = gmmail._id;
let { receivers, mailType, status, timeType, startTime, circleHour, circleDay } = gmmail;
if(status != GM_MAIL_STATUS.CREATE) {
return resResult(STATUS.GM_MAIL_HAS_SENT);

View File

@@ -0,0 +1,11 @@
import { Controller } from 'egg';
export default class LogController extends Controller {
public async getGmLog() {
const { ctx } = this;
const { pageSize, page, form } = ctx.request.body;
ctx.body = await ctx.service.log.getGmLog(page, pageSize, form);
}
}

View File

@@ -94,4 +94,6 @@ export default (app: Application) => {
router.post('/api/mail/updatesinglemailtxt', tokenParser, controller.mail.updateGMMail);
router.post('/api/mail/updateservermail', tokenParser, controller.mail.updateGMMail);
router.post('/api/mail/updateservermailtxt', tokenParser, controller.mail.updateGMMail);
router.post('/api/log/getgmlog', controller.log.getGmLog);
};

View File

@@ -101,6 +101,7 @@ export default class GMUsers extends Service {
return this.ctx.service.utils.resResult(STATUS.INTERNAL_ERR);
}
}
/**
* 创建后台账号
*/

View File

@@ -0,0 +1,21 @@
import { Service } from 'egg';
import { STATUS } from '@consts';
import { SearchLogParam } from '@domain/backEndField/search';
import { GMRecordModel } from '@db/GMRecord';
/**
* Test Service
*/
export default class Log extends Service {
/**
* 修改用户组
*/
public async getGmLog(page: number, pageSize: number, form: SearchLogParam) {
const {ctx} = this;
let list = await GMRecordModel.findByCondition(page, pageSize, form);
return ctx.service.utils.resResult(STATUS.SUCCESS, { list });
}
}

View File

@@ -6,6 +6,7 @@ import ExportActivity from '../../../app/controller/activity';
import ExportGame from '../../../app/controller/game';
import ExportGmaccount from '../../../app/controller/gmaccount';
import ExportHome from '../../../app/controller/home';
import ExportLog from '../../../app/controller/log';
import ExportLogin from '../../../app/controller/login';
import ExportMail from '../../../app/controller/mail';
import ExportUpload from '../../../app/controller/upload';
@@ -17,6 +18,7 @@ declare module 'egg' {
game: ExportGame;
gmaccount: ExportGmaccount;
home: ExportHome;
log: ExportLog;
login: ExportLogin;
mail: ExportMail;
upload: ExportUpload;

View File

@@ -9,6 +9,7 @@ type AutoInstanceType<T, U = T extends CanExportFunc ? T : T extends AnyFunc ? R
import ExportActivity from '../../../app/service/Activity';
import ExportGame from '../../../app/service/Game';
import ExportGmUser from '../../../app/service/GmUser';
import ExportLog from '../../../app/service/Log';
import ExportMail from '../../../app/service/Mail';
import ExportTest from '../../../app/service/Test';
import ExportUtils from '../../../app/service/Utils';
@@ -19,6 +20,7 @@ declare module 'egg' {
activity: AutoInstanceType<typeof ExportActivity>;
game: AutoInstanceType<typeof ExportGame>;
gmUser: AutoInstanceType<typeof ExportGmUser>;
log: AutoInstanceType<typeof ExportLog>;
mail: AutoInstanceType<typeof ExportMail>;
test: AutoInstanceType<typeof ExportTest>;
utils: AutoInstanceType<typeof ExportUtils>;

View File

@@ -980,4 +980,18 @@ export enum GM_API_TYPE {
del = 'del', // 删
update = 'update', // 改
find = 'find', // 查
}
export enum LOG_TYPE {
LOGIN = 'login', // 登录
LOGINOUT = 'logout', // 登出
CE_CHANGE = 'ceChange', // 战力变化
PAY = 'pay', // 充值
ITEM_CHANGE = 'itemChange', // 道具变动
RECEIVE_MAIL = 'receiveMail', // 领取邮件
}
export enum CE_CHANGE_REASON {
HERO = 'hero', // 武将
}

View File

@@ -140,6 +140,11 @@ export default class GMMail extends BaseModel {
return result;
}
public static async getGmMailByIdAndType(_id: string, mailType: GM_MAIL_TYPE, hasGoods: boolean) {
const result: GMMailType = await GMMailModel.findOne({ _id, mailType, hasGoods }).lean();
return result;
}
private static getSearchObj(form: SearchMailParam) {
let searchObj = {};
if(form.createTimeStart) searchObj['createdAt'] = { $gt: new Date(form.createTimeStart * 1000) };

View File

@@ -1,6 +1,7 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, ReturnModelType, mongoose } from '@typegoose/typegoose';
import { gameData } from '../pubUtils/data';
import { SearchLogParam } from '../domain/backEndField/search';
/**
* GM用户组接口
@@ -22,6 +23,9 @@ export default class GMRecord extends BaseModel {
@prop({ required: true })
apiName: string;
@prop({ required: true })
apiModule: string;
@prop({ required: true })
body: string;
@@ -30,10 +34,28 @@ export default class GMRecord extends BaseModel {
public static async createRecord(uid: number, env: string, api: string, body: string, result: string) {
let dicApi = gameData.apiByUrl.get(api);
const r = await GMRecordModel.insertMany({uid, env, api, apiName: dicApi?.name, body, result});
const r = await GMRecordModel.insertMany({uid, env, api, apiName: dicApi?.name, apiModule: dicApi?.module, body, result});
return r;
}
private static getSearchObj(form: SearchLogParam) {
let searchObj = {};
if (form.env) searchObj['env'] = form.env;
if (form.uid) searchObj['uid'] = form.uid;
if (form.apiModule) searchObj['apiModule'] = form.apiModule;
if (form.api) searchObj['api'] = form.api;
if (form.createTimeStart && form.createTimeEnd) {
searchObj['createdAt'] = { $lte: new Date(form.createTimeEnd * 1000), $gte: new Date(form.createTimeStart * 100) };
}
return searchObj
}
public static async findByCondition(page: number, pageSize: number, form: SearchLogParam = {}) {
let searchObj = GMRecordModel.getSearchObj(form);
const result: GMRecordType[] = await GMRecordModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort({ createdAt: -1 }).select('-_id').lean({ getters: true, virtuals: true });
return result;
}
}
export let GMRecordModel: ReturnModelType<typeof GMRecord, {}>;

104
shared/db/UserLog.ts Normal file
View File

@@ -0,0 +1,104 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
class Reward {
@prop({ required: true })
id: number;
@prop({ required: true })
count: number;
}
/**
* 玩家充值订单
*/
@index({ localOrderID: 1 })
export default class UserLog extends BaseModel {
@prop({ required: true })
type: string; // 类型 LOG_TYPE
@prop({ required: true })
uid: number; // uid
@prop({ required: true })
roleId: string; // 角色id
@prop({ required: true })
roleName: string; // 角色名
@prop({ required: false })
ip: string; // ip
// 战力相关
@prop({ required: false })
inc: number; // 改变值 战力改变/道具数量改变
@prop({ required: false })
count: number; // 变化后的值 战力改变/道具数量改变
@prop({ required: false })
ceChangeReason: number; // 战力变化原因
@prop({ required: false })
ceChangeReasonInfo: string; // 战力变化原因信息如武将id等
// 充值相关
@prop({ required: false })
productId: string; // 商品id
@prop({ required: false })
productName: string; // 商品名字
@prop({ required: false })
price: number; // 充值金额
@prop({ required: false })
isYuanbao: boolean; // 是否为代币
@prop({ required: false })
localOrderId: string; // 订单id
@prop({ required: false })
totalPay: number; // 总充值金额
@prop({ required: false })
orderStatus: number; // 订单状态
// 道具相关
@prop({ required: false })
itemId: number; // 道具id
@prop({ required: false })
itemName: string; // 道具名
@prop({ required: false })
itid: number; // 道具类型
@prop({ required: false })
itemChangeModule: string; // 道具变更模块
@prop({ required: false })
itemChangeReason: number; // 道具变更来源
// 邮件日志
@prop({ required: false })
mailId: string; // 邮件id
@prop({ required: false, type: Reward, _id: false })
goods: Reward[]; // 邮件附带道具
@prop({ required: false })
mailContent: string; // 邮件正文
@prop({ required: false })
mailTitle: string; // 邮件标题
@prop({ required: false })
mailSendName: string; // 邮件发件人
}
export const UserLogModel = getModelForClass(UserLog);
export interface UserLogModelType extends Pick<DocumentType<UserLog>, keyof UserLog> { }
export type UserLogModelTypeParam = Partial<UserLogModelType>; // 将所有字段变成可选项

View File

@@ -71,4 +71,13 @@ export interface SearchGiftCodeDetailParam {
code?: string;
roleId?: string;
roleName?: string;
}
export interface SearchLogParam {
env?: string;
apiModule?: string;
api?: string;
createTimeStart?: number;
createTimeEnd?: number;
uid?: number;
}

View File

@@ -0,0 +1,3 @@
export function saveUserLog() {
}

View File

@@ -471,7 +471,7 @@
{
"id": 68,
"api": "/api/mail/getcreatesinglemailtxt",
"name": "获取火箭单人无道具邮件列表",
"name": "获取创建单人无道具邮件列表",
"module": "mail",
"type": "find"
},
@@ -554,146 +554,167 @@
},
{
"id": 80,
"api": "gm.gmHandler.sendMail",
"name": "发送邮件",
"api": "gm.gmHandler.sendSingleMail",
"name": "审批单人有道具邮件",
"module": "mail",
"type": "update"
},
{
"id": 81,
"api": "gm.gmHandler.sendSingleMailTxt",
"name": "审批单人无道具邮件",
"module": "mail",
"type": "update"
},
{
"id": 82,
"api": "gm.gmHandler.sendServerMail",
"name": "审批全服有道具邮件",
"module": "mail",
"type": "update"
},
{
"id": 83,
"api": "gm.gmHandler.sendServerMailTxt",
"name": "审批全服无道具邮件",
"module": "mail",
"type": "update"
},
{
"id": 84,
"api": "gm.gmHandler.setGuildActivityDebug",
"name": "开启军团活动",
"module": "guildactivity",
"type": "update"
},
{
"id": 82,
"id": 85,
"api": "gm.gmHandler.cancelGuildActivityDebug",
"name": "取消军团活动",
"module": "guildactivity",
"type": "update"
},
{
"id": 83,
"id": 86,
"api": "/api/game/getregions",
"name": "获取所有大区",
"module": "server",
"type": "find"
},
{
"id": 84,
"id": 87,
"api": "/api/game/getservers",
"name": "获取所有小区",
"module": "server",
"type": "find"
},
{
"id": 85,
"id": 88,
"api": "/api/game/getregionstategy",
"name": "获取大区策略",
"module": "server",
"type": "find"
},
{
"id": 86,
"id": 89,
"api": "/api/game/getwhitelist",
"name": "获取白名单",
"module": "server",
"type": "find"
},
{
"id": 87,
"id": 90,
"api": "/api/game/updatewhitelist",
"name": "更新白名单",
"module": "server",
"type": "update"
},
{
"id": 88,
"id": 91,
"api": "/api/game/deletewhitelist",
"name": "删除白名单",
"module": "server",
"type": "delete"
},
{
"id": 89,
"id": 92,
"api": "/api/game/stopserverregister",
"name": "小区停止注册",
"module": "server",
"type": "update"
},
{
"id": 90,
"id": 93,
"api": "/api/game/swicthserverstatus",
"name": "切换服务器状态",
"module": "server",
"type": "update"
},
{
"id": 91,
"id": 94,
"api": "gm.gmServerHandler.saveRegionConf",
"name": "保存大区设置",
"module": "server",
"type": "update"
},
{
"id": 92,
"id": 95,
"api": "gm.gmServerHandler.createNewServer",
"name": "手动开服",
"module": "server",
"type": "update"
},
{
"id": 93,
"id": 96,
"api": "gm.gmServerHandler.startMaintenance",
"name": "开始维护",
"module": "server",
"type": "update"
},
{
"id": 94,
"id": 97,
"api": "gm.gmServerHandler.startRegionMaintenance",
"name": "开始大区维护",
"module": "server",
"type": "update"
},
{
"id": 95,
"id": 98,
"api": "gm.gmServerHandler.stopMaintenance",
"name": "停止维护",
"module": "server",
"type": "update"
},
{
"id": 96,
"id": 99,
"api": "/api/upload/hotupdate",
"name": "上传热更新",
"module": "upload",
"type": "update"
},
{
"id": 97,
"id": 100,
"api": "/api/upload/uploadjson",
"name": "上传json",
"module": "upload",
"type": "update"
},
{
"id": 98,
"id": 101,
"api": "/web/reloadresource",
"name": "加载资源(web)",
"module": "upload",
"type": "update"
},
{
"id": 99,
"id": 102,
"api": "/api/upload/reloadresource",
"name": "加载资源(后台)",
"module": "upload",
"type": "update"
},
{
"id": 100,
"id": 103,
"api": "gm.gmHandler.reloadResource",
"name": "加载资源(游戏)",
"module": "upload",