2026-05-02 13:02:38 +08:00

132 lines
3.4 KiB
Go

package audit
import (
"bytes"
"encoding/csv"
"fmt"
"time"
"hyapp-admin-server/internal/model"
"hyapp-admin-server/internal/modules/shared"
"hyapp-admin-server/internal/repository"
)
type AuditService struct {
store *repository.Store
}
type CSVExport struct {
FileName string
Content []byte
Count int
}
func NewService(store *repository.Store) *AuditService {
return &AuditService{store: store}
}
func (s *AuditService) CreateOperationLog(log model.OperationLog) error {
return s.store.CreateOperationLog(log)
}
func (s *AuditService) LogOperation(event shared.OperationEvent) error {
if event.Status == "" {
event.Status = "success"
}
if event.RiskLevel == "" {
event.RiskLevel = riskLevel(event.Action, event.Method)
}
return s.store.CreateOperationLog(model.OperationLog{
RequestID: event.RequestID,
UserID: event.UserID,
Username: event.Username,
Action: event.Action,
Resource: event.Resource,
ResourceID: event.ResourceID,
Method: event.Method,
Path: event.Path,
IP: event.IP,
UserAgent: event.UserAgent,
Status: event.Status,
HTTPStatus: event.HTTPStatus,
RiskLevel: event.RiskLevel,
LatencyMS: event.LatencyMS,
Detail: event.Detail,
})
}
func (s *AuditService) ListLoginLogs(options repository.ListOptions) ([]model.LoginLog, int64, error) {
return s.store.ListLoginLogs(options)
}
func (s *AuditService) ListOperationLogs(options repository.ListOptions) ([]model.OperationLog, int64, error) {
return s.store.ListOperationLogs(options)
}
func (s *AuditService) ExportLoginLogs(options repository.ListOptions) (CSVExport, error) {
logs, err := s.store.ExportLoginLogs(options)
if err != nil {
return CSVExport{}, err
}
var buf bytes.Buffer
writer := csv.NewWriter(&buf)
_ = writer.Write([]string{"ID", "用户", "IP", "状态", "消息", "时间"})
for _, item := range logs {
_ = writer.Write([]string{
fmt.Sprintf("%d", item.ID),
item.Username,
item.IP,
item.Status,
item.Message,
item.CreatedAt.Format(time.RFC3339),
})
}
writer.Flush()
return CSVExport{FileName: "hyapp-login-logs.csv", Content: buf.Bytes(), Count: len(logs)}, writer.Error()
}
func (s *AuditService) ExportOperationLogs(options repository.ListOptions) (CSVExport, error) {
logs, err := s.store.ExportOperationLogs(options)
if err != nil {
return CSVExport{}, err
}
var buf bytes.Buffer
writer := csv.NewWriter(&buf)
_ = writer.Write([]string{"ID", "RequestID", "用户", "动作", "资源", "资源ID", "方法", "路径", "IP", "状态", "HTTP", "风险", "耗时ms", "详情", "时间"})
for _, item := range logs {
_ = writer.Write([]string{
fmt.Sprintf("%d", item.ID),
item.RequestID,
item.Username,
item.Action,
item.Resource,
item.ResourceID,
item.Method,
item.Path,
item.IP,
item.Status,
fmt.Sprintf("%d", item.HTTPStatus),
item.RiskLevel,
fmt.Sprintf("%d", item.LatencyMS),
item.Detail,
item.CreatedAt.Format(time.RFC3339),
})
}
writer.Flush()
return CSVExport{FileName: "hyapp-operation-logs.csv", Content: buf.Bytes(), Count: len(logs)}, writer.Error()
}
func riskLevel(action string, method string) string {
switch method {
case "DELETE":
return "high"
case "POST", "PUT", "PATCH":
if action == "reset-user-password" || action == "replace-role-permissions" || action == "replace-role-data-scopes" {
return "high"
}
return "normal"
default:
return "low"
}
}