Files
nxxmdata/backend/routes/operationLogs.js
2025-09-12 20:08:42 +08:00

447 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 操作日志路由
* @file operationLogs.js
* @description 定义操作日志相关的API路由
*/
const express = require('express');
const router = express.Router();
const { body, query, param, validationResult } = require('express-validator');
const operationLogController = require('../controllers/operationLogController');
const { verifyToken } = require('../middleware/auth');
const { checkOperationLogPermission } = require('../middleware/operationLogAuth');
// 验证中间件
const validateRequest = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: '请求参数验证失败',
errors: errors.array()
});
}
next();
};
/**
* @swagger
* components:
* schemas:
* OperationLog:
* type: object
* properties:
* id:
* type: integer
* description: 主键ID
* user_id:
* type: integer
* description: 操作用户ID
* username:
* type: string
* description: 操作用户名
* user_role:
* type: string
* description: 操作用户角色
* operation_type:
* type: string
* enum: [CREATE, UPDATE, DELETE]
* description: 操作类型
* module_name:
* type: string
* description: 操作模块名称
* table_name:
* type: string
* description: 操作的数据表名
* record_id:
* type: integer
* description: 操作的记录ID
* operation_desc:
* type: string
* description: 操作描述
* old_data:
* type: object
* description: 操作前的数据
* new_data:
* type: object
* description: 操作后的数据
* ip_address:
* type: string
* description: 操作IP地址
* user_agent:
* type: string
* description: 用户代理信息
* request_url:
* type: string
* description: 请求URL
* request_method:
* type: string
* description: 请求方法
* response_status:
* type: integer
* description: 响应状态码
* execution_time:
* type: integer
* description: 执行时间(毫秒)
* error_message:
* type: string
* description: 错误信息
* created_at:
* type: string
* format: date-time
* description: 创建时间
*/
/**
* @swagger
* /api/operation-logs:
* get:
* summary: 获取操作日志列表
* tags: [OperationLogs]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: page
* schema:
* type: integer
* default: 1
* description: 页码
* - in: query
* name: pageSize
* schema:
* type: integer
* default: 20
* description: 每页记录数
* - in: query
* name: userId
* schema:
* type: integer
* description: 用户ID
* - in: query
* name: username
* schema:
* type: string
* description: 用户名
* - in: query
* name: operationType
* schema:
* type: string
* enum: [CREATE, UPDATE, DELETE]
* description: 操作类型
* - in: query
* name: moduleName
* schema:
* type: string
* description: 模块名称
* - in: query
* name: tableName
* schema:
* type: string
* description: 数据表名
* - in: query
* name: startDate
* schema:
* type: string
* format: date
* description: 开始日期
* - in: query
* name: endDate
* schema:
* type: string
* format: date
* description: 结束日期
* - in: query
* name: sortBy
* schema:
* type: string
* default: created_at
* description: 排序字段
* - in: query
* name: sortOrder
* schema:
* type: string
* enum: [ASC, DESC]
* default: DESC
* description: 排序方向
* responses:
* 200:
* description: 获取操作日志列表成功
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* data:
* type: array
* items:
* $ref: '#/components/schemas/OperationLog'
* pagination:
* type: object
* properties:
* total:
* type: integer
* page:
* type: integer
* pageSize:
* type: integer
* totalPages:
* type: integer
* hasMore:
* type: boolean
* message:
* type: string
* 500:
* description: 服务器内部错误
*/
router.get('/',
verifyToken,
checkOperationLogPermission,
query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
query('pageSize').optional().isInt({ min: 1, max: 100 }).withMessage('每页记录数必须是1-100之间的整数'),
query('username').optional().isLength({ min: 0, max: 50 }).withMessage('用户名长度必须在0-50个字符之间'),
query('operationType').optional().isIn(['CREATE', 'UPDATE', 'DELETE']).withMessage('操作类型必须是CREATE、UPDATE或DELETE'),
query('moduleName').optional().isLength({ min: 1, max: 100 }).withMessage('模块名称长度必须在1-100个字符之间'),
query('tableName').optional().isLength({ min: 1, max: 100 }).withMessage('数据表名长度必须在1-100个字符之间'),
query('startDate').optional().isISO8601().withMessage('开始日期格式不正确'),
query('endDate').optional().isISO8601().withMessage('结束日期格式不正确'),
query('sortBy').optional().isIn(['id', 'user_id', 'username', 'operation_type', 'module_name', 'table_name', 'created_at']).withMessage('排序字段无效'),
query('sortOrder').optional().isIn(['ASC', 'DESC']).withMessage('排序方向必须是ASC或DESC'),
validateRequest,
operationLogController.getOperationLogs
);
/**
* @swagger
* /api/operation-logs/{id}:
* get:
* summary: 获取操作日志详情
* tags: [OperationLogs]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: integer
* description: 操作日志ID
* responses:
* 200:
* description: 获取操作日志详情成功
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* data:
* $ref: '#/components/schemas/OperationLog'
* message:
* type: string
* 404:
* description: 操作日志不存在
* 500:
* description: 服务器内部错误
*/
router.get('/export',
verifyToken,
checkOperationLogPermission,
operationLogController.exportOperationLogs
);
router.get('/:id',
verifyToken,
checkOperationLogPermission,
operationLogController.getOperationLogById
);
/**
* @swagger
* /api/operation-logs/stats/overview:
* get:
* summary: 获取操作统计
* tags: [OperationLogs]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: type
* schema:
* type: string
* enum: [user, module, overall]
* default: overall
* description: 统计类型
* - in: query
* name: userId
* schema:
* type: integer
* description: 用户IDtype为user时必填
* - in: query
* name: moduleName
* schema:
* type: string
* description: 模块名称type为module时必填
* - in: query
* name: startDate
* schema:
* type: string
* format: date
* description: 开始日期
* - in: query
* name: endDate
* schema:
* type: string
* format: date
* description: 结束日期
* responses:
* 200:
* description: 获取操作统计成功
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* data:
* type: object
* properties:
* CREATE:
* type: integer
* UPDATE:
* type: integer
* DELETE:
* type: integer
* message:
* type: string
* 500:
* description: 服务器内部错误
*/
router.get('/stats/overview',
verifyToken,
checkOperationLogPermission,
operationLogController.getOperationStats
);
/**
* @swagger
* /api/operation-logs/stats/chart:
* get:
* summary: 获取操作日志图表数据
* tags: [OperationLogs]
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: type
* schema:
* type: string
* enum: [hourly, daily, monthly]
* default: daily
* description: 图表类型
* - in: query
* name: startDate
* schema:
* type: string
* format: date
* description: 开始日期
* - in: query
* name: endDate
* schema:
* type: string
* format: date
* description: 结束日期
* responses:
* 200:
* description: 获取操作日志图表数据成功
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* data:
* type: object
* properties:
* dates:
* type: array
* items:
* type: string
* series:
* type: object
* properties:
* CREATE:
* type: array
* items:
* type: integer
* UPDATE:
* type: array
* items:
* type: integer
* DELETE:
* type: array
* items:
* type: integer
* message:
* type: string
* 500:
* description: 服务器内部错误
*/
router.get('/stats/chart',
verifyToken,
checkOperationLogPermission,
operationLogController.getOperationChartData
);
/**
* @swagger
* /api/operation-logs/clean:
* post:
* summary: 清理过期日志
* tags: [OperationLogs]
* security:
* - bearerAuth: []
* requestBody:
* required: false
* content:
* application/json:
* schema:
* type: object
* properties:
* daysToKeep:
* type: integer
* default: 90
* description: 保留天数
* responses:
* 200:
* description: 清理过期日志成功
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* data:
* type: object
* properties:
* deletedCount:
* type: integer
* message:
* type: string
* 500:
* description: 服务器内部错误
*/
router.post('/clean',
verifyToken,
checkOperationLogPermission,
operationLogController.cleanExpiredLogs
);
module.exports = router;