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() }