yunzer_go/server/controllers/operation_log.go

439 lines
9.7 KiB
Go
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.

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(&params); err != nil {
// 如果ParseForm失败尝试解析JSON
c.Ctx.Input.Bind(&params, "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()
}