feat: 添加操作日志、危险操作确认和业务关联功能
1. 新增操作日志记录功能,记录关键操作 2. 实现危险操作确认对话框,防止误删 3. 添加业务和库房管理模块 4. 支持设备标记为空闲状态 5. 完善API文档和健康检查 6. 优化前端删除操作的确认流程 7. 添加Swagger API文档支持 8. 实现设备与业务的关联功能 9. 改进设备模型,添加空闲相关字段 10. 优化用户、角色管理操作日志
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
const OperationLog = require('../models/OperationLog');
|
||||
|
||||
const generateRecordId = () => {
|
||||
return `OPLOG_${Date.now().toString(36)}_${Math.random().toString(36).substr(2, 9)}`;
|
||||
};
|
||||
|
||||
const getOperatorInfo = (req) => {
|
||||
if (!req || !req.user) {
|
||||
return {
|
||||
operatorId: 'system',
|
||||
operatorName: '系统',
|
||||
operatorRole: null
|
||||
};
|
||||
}
|
||||
return {
|
||||
operatorId: req.user.userId || req.user.id || 'unknown',
|
||||
operatorName: req.user.realName || req.user.username || '未知用户',
|
||||
operatorRole: req.user.roleName || req.user.role || null
|
||||
};
|
||||
};
|
||||
|
||||
const getClientInfo = (req) => {
|
||||
if (!req) {
|
||||
return { ipAddress: null, userAgent: null };
|
||||
}
|
||||
const ipAddress = req.headers['x-forwarded-for'] ||
|
||||
req.headers['x-real-ip'] ||
|
||||
req.connection?.remoteAddress ||
|
||||
req.ip ||
|
||||
null;
|
||||
const userAgent = req.headers['user-agent'] || null;
|
||||
return { ipAddress, userAgent };
|
||||
};
|
||||
|
||||
async function logOperation({
|
||||
module,
|
||||
operationType,
|
||||
operationDescription,
|
||||
targetId,
|
||||
targetName,
|
||||
beforeState,
|
||||
afterState,
|
||||
result = 'success',
|
||||
req,
|
||||
metadata = {}
|
||||
}) {
|
||||
try {
|
||||
const operatorInfo = getOperatorInfo(req);
|
||||
const clientInfo = getClientInfo(req);
|
||||
|
||||
await OperationLog.create({
|
||||
recordId: generateRecordId(),
|
||||
module,
|
||||
operationType,
|
||||
operationDescription,
|
||||
targetId: targetId || null,
|
||||
targetName: targetName || null,
|
||||
operatorId: operatorInfo.operatorId,
|
||||
operatorName: operatorInfo.operatorName,
|
||||
operatorRole: operatorInfo.operatorRole,
|
||||
beforeState: beforeState || null,
|
||||
afterState: afterState || null,
|
||||
result,
|
||||
ipAddress: clientInfo.ipAddress,
|
||||
userAgent: clientInfo.userAgent,
|
||||
metadata
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('记录操作日志失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function logDeviceOperation(operationType, operationDescription, { targetId, targetName, beforeState, afterState, result, req, metadata = {} }) {
|
||||
return logOperation({
|
||||
module: 'device',
|
||||
operationType,
|
||||
operationDescription,
|
||||
targetId,
|
||||
targetName,
|
||||
beforeState,
|
||||
afterState,
|
||||
result,
|
||||
req,
|
||||
metadata
|
||||
});
|
||||
}
|
||||
|
||||
async function logUserOperation(operationType, operationDescription, { targetId, targetName, beforeState, afterState, result, req, metadata = {} }) {
|
||||
return logOperation({
|
||||
module: 'user',
|
||||
operationType,
|
||||
operationDescription,
|
||||
targetId,
|
||||
targetName,
|
||||
beforeState,
|
||||
afterState,
|
||||
result,
|
||||
req,
|
||||
metadata
|
||||
});
|
||||
}
|
||||
|
||||
async function logRoleOperation(operationType, operationDescription, { targetId, targetName, beforeState, afterState, result, req, metadata = {} }) {
|
||||
return logOperation({
|
||||
module: 'role',
|
||||
operationType,
|
||||
operationDescription,
|
||||
targetId,
|
||||
targetName,
|
||||
beforeState,
|
||||
afterState,
|
||||
result,
|
||||
req,
|
||||
metadata
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
logOperation,
|
||||
logDeviceOperation,
|
||||
logUserOperation,
|
||||
logRoleOperation
|
||||
};
|
||||
Reference in New Issue
Block a user