439 lines
9.7 KiB
Go
439 lines
9.7 KiB
Go
package controllers
|
||
|
||
import (
|
||
"fmt"
|
||
"server/models"
|
||
"server/services"
|
||
"strconv"
|
||
"time"
|
||
|
||
"github.com/beego/beego/v2/server/web"
|
||
)
|
||
|
||
// OperationLogController 操作日志控制器
|
||
type OperationLogController struct {
|
||
web.Controller
|
||
}
|
||
|
||
// GetOperationLogs 获取操作日志列表
|
||
func (c *OperationLogController) GetOperationLogs() {
|
||
// 获取租户ID和用户ID
|
||
tenantIdData := c.Ctx.Input.GetData("tenantId")
|
||
tenantId := 0
|
||
if tenantIdData != nil {
|
||
if tid, ok := tenantIdData.(int); ok {
|
||
tenantId = tid
|
||
}
|
||
}
|
||
|
||
userIdData := c.Ctx.Input.GetData("userId")
|
||
userId := 0
|
||
if userIdData != nil {
|
||
if uid, ok := userIdData.(int); ok {
|
||
userId = uid
|
||
}
|
||
}
|
||
|
||
// 获取查询参数
|
||
pageNum, _ := c.GetInt("page_num", 1)
|
||
pageSize, _ := c.GetInt("page_size", 20)
|
||
module := c.GetString("module")
|
||
operation := c.GetString("operation")
|
||
filterUserId, _ := c.GetInt("user_id", 0)
|
||
startTimeStr := c.GetString("start_time")
|
||
endTimeStr := c.GetString("end_time")
|
||
|
||
var startTime, endTime *time.Time
|
||
|
||
if startTimeStr != "" {
|
||
if t, err := time.Parse("2006-01-02 15:04:05", startTimeStr); err == nil {
|
||
startTime = &t
|
||
}
|
||
}
|
||
|
||
if endTimeStr != "" {
|
||
if t, err := time.Parse("2006-01-02 15:04:05", endTimeStr); err == nil {
|
||
endTime = &t
|
||
}
|
||
}
|
||
|
||
// 如果指定了用户ID筛选,使用该ID,否则使用当前用户ID
|
||
queryUserId := filterUserId
|
||
if queryUserId <= 0 {
|
||
queryUserId = userId
|
||
}
|
||
|
||
logs, total, err := services.GetOperationLogs(tenantId, queryUserId, module, operation, startTime, endTime, pageNum, pageSize)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "查询日志失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
// 为每条日志批量解析模块名称(减少对菜单表的重复查询)
|
||
type LogWithModuleName struct {
|
||
*models.OperationLog
|
||
ModuleName string `json:"module_name"`
|
||
}
|
||
|
||
// 收集唯一 module 列表
|
||
moduleSet := make(map[string]struct{})
|
||
modules := make([]string, 0)
|
||
for _, l := range logs {
|
||
m := l.Module
|
||
if m == "" {
|
||
continue
|
||
}
|
||
if _, ok := moduleSet[m]; !ok {
|
||
moduleSet[m] = struct{}{}
|
||
modules = append(modules, m)
|
||
}
|
||
}
|
||
|
||
moduleNamesMap := map[string]string{}
|
||
if len(modules) > 0 {
|
||
if mm, err := services.GetModuleNames(modules); err == nil {
|
||
moduleNamesMap = mm
|
||
}
|
||
}
|
||
|
||
logsWithName := make([]*LogWithModuleName, len(logs))
|
||
for i, log := range logs {
|
||
name := ""
|
||
if v, ok := moduleNamesMap[log.Module]; ok {
|
||
name = v
|
||
} else {
|
||
// fallback 单个解析(保留老逻辑)
|
||
name = services.GetModuleName(log.Module)
|
||
}
|
||
|
||
logsWithName[i] = &LogWithModuleName{
|
||
OperationLog: log,
|
||
ModuleName: name,
|
||
}
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": logsWithName,
|
||
"total": total,
|
||
"page": pageNum,
|
||
"page_size": pageSize,
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// GetOperationLogById 根据ID获取操作日志
|
||
func (c *OperationLogController) GetOperationLogById() {
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||
if err != nil || id <= 0 {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "参数错误",
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
log, err := services.GetOperationLogById(id)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "日志不存在",
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": log,
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// GetUserStats 获取用户操作统计
|
||
func (c *OperationLogController) GetUserStats() {
|
||
userIdData := c.Ctx.Input.GetData("userId")
|
||
userId := 0
|
||
if userIdData != nil {
|
||
if uid, ok := userIdData.(int); ok {
|
||
userId = uid
|
||
}
|
||
}
|
||
|
||
tenantIdData := c.Ctx.Input.GetData("tenantId")
|
||
tenantId := 0
|
||
if tenantIdData != nil {
|
||
if tid, ok := tenantIdData.(int); ok {
|
||
tenantId = tid
|
||
}
|
||
}
|
||
|
||
days, _ := c.GetInt("days", 7)
|
||
|
||
stats, err := services.GetUserOperationStats(tenantId, userId, days)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "查询统计失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": stats,
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// GetTenantStats 获取租户操作统计
|
||
func (c *OperationLogController) GetTenantStats() {
|
||
tenantIdData := c.Ctx.Input.GetData("tenantId")
|
||
tenantId := 0
|
||
if tenantIdData != nil {
|
||
if tid, ok := tenantIdData.(int); ok {
|
||
tenantId = tid
|
||
}
|
||
}
|
||
|
||
days, _ := c.GetInt("days", 7)
|
||
|
||
stats, err := services.GetTenantOperationStats(tenantId, days)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "查询统计失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": stats,
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// ClearOldLogs 清空旧日志
|
||
func (c *OperationLogController) ClearOldLogs() {
|
||
keepDays, _ := c.GetInt("keep_days", 90)
|
||
|
||
rowsAffected, err := services.DeleteOldLogs(keepDays)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "删除日志失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"message": "删除成功",
|
||
"data": map[string]interface{}{
|
||
"deleted_count": rowsAffected,
|
||
"keep_days": keepDays,
|
||
},
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// GetAccessLogs 获取访问日志列表
|
||
func (c *OperationLogController) GetAccessLogs() {
|
||
// 获取租户ID和用户ID
|
||
tenantIdData := c.Ctx.Input.GetData("tenantId")
|
||
tenantId := 0
|
||
if tenantIdData != nil {
|
||
if tid, ok := tenantIdData.(int); ok {
|
||
tenantId = tid
|
||
}
|
||
}
|
||
|
||
userIdData := c.Ctx.Input.GetData("userId")
|
||
userId := 0
|
||
if userIdData != nil {
|
||
if uid, ok := userIdData.(int); ok {
|
||
userId = uid
|
||
}
|
||
}
|
||
|
||
// 获取查询参数
|
||
pageNum, _ := c.GetInt("page_num", 1)
|
||
pageSize, _ := c.GetInt("page_size", 20)
|
||
module := c.GetString("module")
|
||
resourceType := c.GetString("resource_type")
|
||
startTimeStr := c.GetString("start_time")
|
||
endTimeStr := c.GetString("end_time")
|
||
|
||
var startTime, endTime *time.Time
|
||
|
||
if startTimeStr != "" {
|
||
if t, err := time.Parse("2006-01-02", startTimeStr); err == nil {
|
||
startTime = &t
|
||
}
|
||
}
|
||
|
||
if endTimeStr != "" {
|
||
if t, err := time.Parse("2006-01-02", endTimeStr); err == nil {
|
||
endTime = &t
|
||
}
|
||
}
|
||
|
||
// 查询访问日志
|
||
logs, total, err := services.GetAccessLogs(tenantId, userId, module, resourceType, startTime, endTime, pageNum, pageSize)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "查询访问日志失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": map[string]interface{}{
|
||
"logs": logs,
|
||
"total": total,
|
||
},
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// GetAccessLogById 根据ID获取访问日志详情
|
||
func (c *OperationLogController) GetAccessLogById() {
|
||
idStr := c.Ctx.Input.Param(":id")
|
||
id, err := strconv.ParseInt(idStr, 10, 64)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "无效的日志ID",
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
log, err := services.GetAccessLogById(id)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "查询日志详情失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
// 获取用户信息
|
||
var user *models.User
|
||
if log.UserId > 0 {
|
||
user, _ = models.GetUserById(log.UserId)
|
||
}
|
||
|
||
// 构造返回数据
|
||
result := map[string]interface{}{
|
||
"id": log.Id,
|
||
"tenant_id": log.TenantId,
|
||
"user_id": log.UserId,
|
||
"username": log.Username,
|
||
"module": log.Module,
|
||
"resource_type": log.ResourceType,
|
||
"resource_id": log.ResourceId,
|
||
"request_url": log.RequestUrl,
|
||
"query_string": log.QueryString,
|
||
"ip_address": log.IpAddress,
|
||
"user_agent": log.UserAgent,
|
||
"request_method": log.RequestMethod,
|
||
"duration": log.Duration,
|
||
"create_time": log.CreateTime,
|
||
}
|
||
|
||
// 如果有用户信息,添加到结果中
|
||
if user != nil {
|
||
result["user_nickname"] = user.Nickname
|
||
result["user_email"] = user.Email
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": result,
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// GetUserAccessStats 获取用户访问统计
|
||
func (c *OperationLogController) GetUserAccessStats() {
|
||
userIdData := c.Ctx.Input.GetData("userId")
|
||
userId := 0
|
||
if userIdData != nil {
|
||
if uid, ok := userIdData.(int); ok {
|
||
userId = uid
|
||
}
|
||
}
|
||
|
||
tenantIdData := c.Ctx.Input.GetData("tenantId")
|
||
tenantId := 0
|
||
if tenantIdData != nil {
|
||
if tid, ok := tenantIdData.(int); ok {
|
||
tenantId = tid
|
||
}
|
||
}
|
||
|
||
days, _ := c.GetInt("days", 7)
|
||
|
||
stats, err := services.GetUserAccessStats(tenantId, userId, days)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "查询统计失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"data": stats,
|
||
}
|
||
c.ServeJSON()
|
||
}
|
||
|
||
// ClearOldAccessLogs 清空旧访问日志
|
||
func (c *OperationLogController) ClearOldAccessLogs() {
|
||
// 获取参数
|
||
var params map[string]interface{}
|
||
if err := c.ParseForm(¶ms); err != nil {
|
||
// 如果ParseForm失败,尝试解析JSON
|
||
c.Ctx.Input.Bind(¶ms, "json")
|
||
}
|
||
|
||
keepDays := 90 // 默认保留90天
|
||
if kd, ok := params["keep_days"].(float64); ok {
|
||
keepDays = int(kd)
|
||
}
|
||
|
||
rowsAffected, err := services.ClearOldAccessLogs(keepDays)
|
||
if err != nil {
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": false,
|
||
"message": "清空旧日志失败: " + err.Error(),
|
||
}
|
||
c.ServeJSON()
|
||
return
|
||
}
|
||
|
||
c.Data["json"] = map[string]interface{}{
|
||
"success": true,
|
||
"message": fmt.Sprintf("清空旧日志成功,共删除 %d 条记录", rowsAffected),
|
||
}
|
||
c.ServeJSON()
|
||
}
|