AuditLog.java 7.3 KB
package com.aigeo.audit.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;

/**
 * 审计日志实体类
 * 对应数据库表:ai_audit_logs
 * 
 * 用于记录系统中所有重要操作的审计信息,包括:
 * - 用户操作记录(登录、创建、修改、删除等)
 * - 系统操作记录(任务执行、状态变更等)
 * - 数据变更记录(前后值对比)
 * - 安全相关操作记录
 *
 * @author AIGEO Team
 * @since 1.0.0
 */
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "ai_audit_logs", indexes = {
    @Index(name = "idx_audit_company_action", columnList = "company_id, action"),
    @Index(name = "idx_audit_user_time", columnList = "user_id, created_at"),
    @Index(name = "idx_audit_resource", columnList = "resource_type, resource_id"),
    @Index(name = "idx_audit_time", columnList = "created_at")
})
public class AuditLog {
    
    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, updatable = false)
    private Integer id;

    /**
     * 公司ID(多租户字段)
     */
    @NotNull(message = "公司ID不能为空")
    @Column(name = "company_id", nullable = false)
    private Integer companyId;

    /**
     * 执行操作的用户ID(NULL表示系统操作)
     */
    @Column(name = "user_id")
    private Integer userId;

    /**
     * 操作动作(如:CREATE, UPDATE, DELETE, LOGIN, EXPORT等)
     */
    @NotBlank(message = "操作动作不能为空")
    @Column(name = "action", nullable = false, length = 50)
    private String action;

    /**
     * 操作的资源类型(如:User, Article, Keyword等)
     */
    @Column(name = "resource_type", length = 50)
    private String resourceType;

    /**
     * 操作的资源ID
     */
    @Column(name = "resource_id")
    private Integer resourceId;

    /**
     * 操作描述
     */
    @Column(name = "description", length = 500)
    private String description;

    /**
     * 操作前的数据(JSON格式)
     */
    @Column(name = "old_values", columnDefinition = "JSON")
    private String oldValues;

    /**
     * 操作后的数据(JSON格式)
     */
    @Column(name = "new_values", columnDefinition = "JSON")
    private String newValues;

    /**
     * 客户端IP地址
     */
    @Column(name = "ip_address", length = 45)
    private String ipAddress;

    /**
     * 用户代理字符串
     */
    @Column(name = "user_agent", length = 500)
    private String userAgent;

    /**
     * 请求路径
     */
    @Column(name = "request_path", length = 200)
    private String requestPath;

    /**
     * HTTP请求方法
     */
    @Column(name = "http_method", length = 10)
    private String httpMethod;

    /**
     * 操作结果状态(SUCCESS, FAILED, PARTIAL等)
     */
    @Column(name = "status", length = 20)
    @Builder.Default
    private String status = "SUCCESS";

    /**
     * 错误信息(操作失败时记录)
     */
    @Column(name = "error_message", length = 1000)
    private String errorMessage;

    /**
     * 操作耗时(毫秒)
     */
    @Column(name = "duration_ms")
    private Long durationMs;

    /**
     * 会话ID
     */
    @Column(name = "session_id", length = 100)
    private String sessionId;

    /**
     * 附加数据(JSON格式,存储额外的上下文信息)
     */
    @Column(name = "additional_data", columnDefinition = "JSON")
    private String additionalData;

    /**
     * 创建时间(操作发生时间)
     */
    @CreationTimestamp
    @Column(name = "created_at", updatable = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdAt;

    /**
     * 实体创建前的处理
     */
    @PrePersist
    protected void onCreate() {
        if (status == null) status = "SUCCESS";
    }

    /**
     * 检查操作是否成功
     */
    public boolean isSuccess() {
        return "SUCCESS".equals(status);
    }

    /**
     * 检查是否为用户操作(非系统操作)
     */
    public boolean isUserAction() {
        return userId != null;
    }

    /**
     * 检查是否为数据变更操作
     */
    public boolean isDataModification() {
        return "CREATE".equals(action) || 
               "UPDATE".equals(action) || 
               "DELETE".equals(action);
    }

    /**
     * 检查是否为敏感操作
     */
    public boolean isSensitiveAction() {
        return "DELETE".equals(action) || 
               "LOGIN".equals(action) || 
               "LOGOUT".equals(action) ||
               "PASSWORD_CHANGE".equals(action) ||
               "PERMISSION_CHANGE".equals(action) ||
               "EXPORT".equals(action);
    }

    /**
     * 获取操作类型的中文描述
     */
    public String getActionDescription() {
        switch (action) {
            case "CREATE": return "创建";
            case "UPDATE": return "更新";
            case "DELETE": return "删除";
            case "LOGIN": return "登录";
            case "LOGOUT": return "登出";
            case "EXPORT": return "导出";
            case "IMPORT": return "导入";
            case "PUBLISH": return "发布";
            case "ARCHIVE": return "归档";
            case "ACTIVATE": return "激活";
            case "DEACTIVATE": return "停用";
            case "PASSWORD_CHANGE": return "修改密码";
            case "PERMISSION_CHANGE": return "权限变更";
            case "CONFIG_CHANGE": return "配置变更";
            default: return action;
        }
    }

    /**
     * 获取资源类型的中文描述
     */
    public String getResourceTypeDescription() {
        if (resourceType == null) return null;
        
        switch (resourceType) {
            case "User": return "用户";
            case "Company": return "公司";
            case "Article": return "文章";
            case "Keyword": return "关键词";
            case "Topic": return "话题";
            case "Platform": return "发布平台";
            case "Template": return "模板";
            case "Project": return "项目";
            case "Task": return "任务";
            case "Config": return "配置";
            default: return resourceType;
        }
    }

    /**
     * 获取完整的操作描述
     */
    public String getFullDescription() {
        StringBuilder sb = new StringBuilder();
        
        if (userId != null) {
            sb.append("用户[").append(userId).append("]");
        } else {
            sb.append("系统");
        }
        
        sb.append("执行了").append(getActionDescription()).append("操作");
        
        if (resourceType != null) {
            sb.append(",涉及").append(getResourceTypeDescription());
            if (resourceId != null) {
                sb.append("[").append(resourceId).append("]");
            }
        }
        
        if (description != null && !description.trim().isEmpty()) {
            sb.append(":").append(description);
        }
        
        return sb.toString();
    }
}