mirror of
https://github.com/pure-admin/pure-admin-backend.git
synced 2025-04-24 23:37:17 +08:00
log记录完善
This commit is contained in:
parent
e45c367e15
commit
75e663f74e
@ -44,17 +44,19 @@ const userRole = `
|
||||
|
||||
/** 创建操作日志表 */
|
||||
const operationLogs = `
|
||||
CREATE TABLE IF NOT EXISTS operation_logs (
|
||||
CREATE TABLE IF NOT EXISTS operation_logs (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
username VARCHAR(255),
|
||||
action VARCHAR(255) NOT NULL COMMENT '操作类型:新增、修改、删除等',
|
||||
module VARCHAR(255) NOT NULL COMMENT '操作模块:用户管理、角色管理等',
|
||||
description TEXT COMMENT '操作详细描述',
|
||||
operator_id INT NOT NULL COMMENT '操作者ID',
|
||||
operator_name VARCHAR(100) NOT NULL COMMENT '操作者名称',
|
||||
target_id INT COMMENT '被操作对象ID',
|
||||
target_type VARCHAR(50) COMMENT '被操作对象类型(如:user, role等)',
|
||||
action VARCHAR(50) NOT NULL COMMENT '操作类型:CREATE, UPDATE, DELETE等',
|
||||
module VARCHAR(50) NOT NULL COMMENT '操作模块:用户管理、角色管理等',
|
||||
content TEXT COMMENT '操作内容(可以存储详细的修改信息)',
|
||||
ip VARCHAR(50) COMMENT '操作IP',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表'
|
||||
FOREIGN KEY (operator_id) REFERENCES users(id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';
|
||||
`;
|
||||
|
||||
export { operationLogs, role, user, userRole };
|
||||
|
@ -7,10 +7,10 @@ import { OkPacket } from 'mysql2';
|
||||
import { createMathExpr } from "svg-captcha";
|
||||
import secret from "../config";
|
||||
import Logger from "../loaders/logger";
|
||||
import { getOperator } from "../utils/auth";
|
||||
import { Message } from "../utils/enums";
|
||||
import { connection } from "../utils/mysql";
|
||||
import { logOperation, ModuleType, OperationType } from "../utils/operationLog";
|
||||
|
||||
const utils = require("@pureadmin/utils");
|
||||
|
||||
/** 保存验证码 */
|
||||
@ -84,11 +84,11 @@ const login = async (req: Request, res: Response) => {
|
||||
if (data.length === 0) {
|
||||
// 记录登录失败日志
|
||||
logOperation({
|
||||
userId: 0,
|
||||
username: username,
|
||||
operatorId: 0, // 改为 operatorId
|
||||
operatorName: username, // 改为 operatorName
|
||||
action: OperationType.LOGIN,
|
||||
module: ModuleType.AUTH,
|
||||
description: `用户登录失败:用户不存在 (${username})`,
|
||||
content: `用户登录失败:数据库错误`, // 改为 content
|
||||
ip: req.ip || ''
|
||||
});
|
||||
|
||||
@ -102,15 +102,15 @@ const login = async (req: Request, res: Response) => {
|
||||
// 验证密码
|
||||
const hashedPassword = createHash("md5").update(password).digest("hex");
|
||||
if (hashedPassword !== user.password) {
|
||||
// 记录登录失败日志
|
||||
logOperation({
|
||||
userId: 0,
|
||||
username: username,
|
||||
action: OperationType.LOGIN,
|
||||
module: ModuleType.AUTH,
|
||||
description: `用户登录失败:密码错误 (${username})`,
|
||||
ip: req.ip || ''
|
||||
});
|
||||
// 记录用户不存在日志
|
||||
logOperation({
|
||||
operatorId: 0,
|
||||
operatorName: username,
|
||||
action: OperationType.LOGIN,
|
||||
module: ModuleType.AUTH,
|
||||
content: `用户登录失败:用户不存在`,
|
||||
ip: req.ip || ''
|
||||
});
|
||||
return res.json({
|
||||
success: false,
|
||||
data: { message: "密码错误" }
|
||||
@ -128,11 +128,11 @@ const login = async (req: Request, res: Response) => {
|
||||
);
|
||||
// 记录登录成功日志
|
||||
logOperation({
|
||||
userId: user.id,
|
||||
username: user.username,
|
||||
operatorId: user.id,
|
||||
operatorName: user.username,
|
||||
action: OperationType.LOGIN,
|
||||
module: ModuleType.AUTH,
|
||||
description: `用户登录成功 (${username})`,
|
||||
content: `用户登录成功 (${username})`,
|
||||
ip: req.ip || ''
|
||||
});
|
||||
await res.json({
|
||||
@ -412,6 +412,9 @@ const updateList = async (req: Request, res: Response) => {
|
||||
const updateFields = [];
|
||||
const updateValues = [];
|
||||
|
||||
|
||||
|
||||
|
||||
// 检查并添加每个可更新字段
|
||||
if (userData.username) {
|
||||
updateFields.push("username = ?");
|
||||
@ -471,16 +474,18 @@ const updateList = async (req: Request, res: Response) => {
|
||||
data: { message: "更新用户失败" }
|
||||
});
|
||||
}
|
||||
// 直接使用更新的用户信息记录日志
|
||||
const operator = getOperator(req);
|
||||
// 记录操作日志
|
||||
logOperation({
|
||||
userId: Number(id), // 转换为数字
|
||||
username: userData.username || userData.name, // 使用更新的用户信息
|
||||
action: OperationType.UPDATE,
|
||||
module: ModuleType.USER,
|
||||
description: `更新用户信息:ID=${id}, 字段:${updateFields.join(', ')}`,
|
||||
operatorId: operator.id, // 使用 decoded 而不是 operator
|
||||
operatorName: operator.name, // 使用 decoded 而不是 operator
|
||||
targetId: Number(id), // 被更新用户的ID
|
||||
targetType: 'user', // 被操作对象类型
|
||||
action: OperationType.UPDATE, // 操作类型
|
||||
module: ModuleType.USER, // 模块
|
||||
content: `更新用户信息:${JSON.stringify(userData)}`, // 操作内容
|
||||
ip: req.ip || ''
|
||||
});
|
||||
|
||||
// 如果有角色信息,更新用户角色
|
||||
if (userData.roles && userData.roles.length > 0) {
|
||||
// 先删除原有角色
|
||||
@ -590,6 +595,7 @@ const deleteList = async (req: Request, res: Response) => {
|
||||
});
|
||||
});
|
||||
}
|
||||
// 记录删除操作日志
|
||||
|
||||
// 提交事务
|
||||
connection.commit(function(err) {
|
||||
@ -602,11 +608,23 @@ const deleteList = async (req: Request, res: Response) => {
|
||||
});
|
||||
});
|
||||
}
|
||||
const operator = getOperator(req);
|
||||
logOperation({
|
||||
operatorId: operator.id,
|
||||
operatorName: operator.name,
|
||||
targetId: Number(id),
|
||||
targetType: 'user',
|
||||
action: OperationType.DELETE,
|
||||
module: ModuleType.USER,
|
||||
content: `删除用户:${id}`,
|
||||
ip: req.ip || ''
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
data: { message: Message[8] }
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import * as dayjs from "dayjs";
|
||||
import * as multer from "multer";
|
||||
import config from "./config";
|
||||
import Logger from "./loaders/logger";
|
||||
// import { operationLogs, role, user, userRole } from "./models/mysql";
|
||||
import { importUsersFromLocalExcel } from "./router/excel";
|
||||
import { getRoleList, getUserList } from "./router/http";
|
||||
// import { queryTable } from "./utils/mysql";
|
||||
|
26
src/utils/auth.ts
Normal file
26
src/utils/auth.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Request } from "express";
|
||||
import * as jwt from "jsonwebtoken";
|
||||
import secret from "../config";
|
||||
|
||||
export interface TokenPayload {
|
||||
id: number;
|
||||
username: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
// 获取操作者信息
|
||||
export const getOperator = (req: Request): TokenPayload => {
|
||||
const authHeader = req.get("Authorization");
|
||||
if (!authHeader) {
|
||||
throw new Error("未提供 token");
|
||||
}
|
||||
|
||||
const token = authHeader.replace("Bearer ", "");
|
||||
const decoded = jwt.verify(token, secret.jwtSecret) as TokenPayload;
|
||||
|
||||
return {
|
||||
id: decoded.id,
|
||||
username: decoded.username,
|
||||
name: decoded.name
|
||||
};
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
import { connection } from "./mysql";
|
||||
import Logger from "../loaders/logger";
|
||||
import { connection } from "./mysql";
|
||||
|
||||
// 定义操作类型
|
||||
export enum OperationType {
|
||||
@ -21,25 +21,29 @@ export enum ModuleType {
|
||||
|
||||
// 记录操作日志
|
||||
export const logOperation = (params: {
|
||||
userId: number;
|
||||
username: string;
|
||||
action: OperationType;
|
||||
module: ModuleType;
|
||||
description: string;
|
||||
ip: string;
|
||||
operatorId: number; // 操作者ID
|
||||
operatorName: string; // 操作者名称
|
||||
targetId?: number; // 被操作对象ID
|
||||
targetType?: string; // 被操作对象类型
|
||||
action: OperationType; // 操作类型(使用枚举)
|
||||
module: ModuleType; // 模块(使用枚举)
|
||||
content: string; // 操作内容
|
||||
ip: string; // IP地址
|
||||
}) => {
|
||||
const sql = `
|
||||
INSERT INTO operation_logs
|
||||
(user_id, username, action, module, description, ip)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
(operator_id, operator_name, target_id, target_type, action, module, content, ip)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`;
|
||||
|
||||
const values = [
|
||||
params.userId,
|
||||
params.username,
|
||||
params.operatorId,
|
||||
params.operatorName,
|
||||
params.targetId || null,
|
||||
params.targetType || null,
|
||||
params.action,
|
||||
params.module,
|
||||
params.description,
|
||||
params.content,
|
||||
params.ip
|
||||
];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user