package service import ( "time" "gorm.io/gorm" "filestoragesystem/internal/config" "filestoragesystem/internal/model" "filestoragesystem/internal/repository" ) // OpLogContext 操作日志上下文(由controller从请求中提取) type OpLogContext struct { UserID *uint Username string IP string UserAgent string Path string Method string } // Services 服务容器 type Services struct { cfg *config.Config db *gorm.DB Auth *AuthService User *UserService Project *ProjectService File *FileService Role *RoleService Admin *AdminService Stats *StatsService Webhook *WebhookService opLogRepo *repository.OpLogRepo } // NewServices 创建服务容器并初始化各服务 func NewServices(cfg *config.Config, db *gorm.DB) *Services { userRepo := &repository.UserRepo{DB: db} roleRepo := &repository.RoleRepo{DB: db} permRepo := &repository.PermissionRepo{DB: db} projectRepo := &repository.ProjectRepo{DB: db} fileRepo := &repository.FileRepo{DB: db} tempLinkRepo := &repository.TempLinkRepo{DB: db} trafficRepo := &repository.TrafficRepo{DB: db} settingRepo := &repository.SettingRepo{DB: db} opLogRepo := &repository.OpLogRepo{DB: db} sysLogRepo := &repository.SysLogRepo{DB: db} webhookRepo := &repository.WebhookRepo{DB: db} apiKeyRepo := &repository.APIKeyRepo{DB: db} s := &Services{cfg: cfg, db: db, opLogRepo: opLogRepo} s.Auth = &AuthService{ cfg: cfg, userRepo: userRepo, apiKeyRepo: apiKeyRepo, roleRepo: roleRepo, settingRepo: settingRepo, opLogRepo: opLogRepo, } s.User = &UserService{ cfg: cfg, userRepo: userRepo, roleRepo: roleRepo, settingRepo: settingRepo, opLogRepo: opLogRepo, fileRepo: fileRepo, projectRepo: projectRepo, } s.Project = &ProjectService{ cfg: cfg, projectRepo: projectRepo, fileRepo: fileRepo, settingRepo: settingRepo, opLogRepo: opLogRepo, webhookSvc: nil, } s.Webhook = &WebhookService{cfg: cfg, webhookRepo: webhookRepo, settingRepo: settingRepo} s.File = &FileService{ cfg: cfg, fileRepo: fileRepo, projectRepo: projectRepo, userRepo: userRepo, tempLinkRepo: tempLinkRepo, trafficRepo: trafficRepo, settingRepo: settingRepo, opLogRepo: opLogRepo, webhookSvc: s.Webhook, } s.Role = &RoleService{roleRepo: roleRepo, permRepo: permRepo} s.Admin = &AdminService{ cfg: cfg, db: db, settingRepo: settingRepo, opLogRepo: opLogRepo, sysLogRepo: sysLogRepo, } s.Stats = &StatsService{ cfg: cfg, userRepo: userRepo, projectRepo: projectRepo, fileRepo: fileRepo, trafficRepo: trafficRepo, } s.Project.webhookSvc = s.Webhook return s } // RecordOpLog 记录操作日志(异步容忍失败) func (s *Services) RecordOpLog(ctx *OpLogContext, action, resourceType string, resourceID uint, resourceName string, success bool, errMsg string) { log := model.OperationLog{ Action: action, ResourceType: resourceType, ResourceID: resourceID, ResourceName: resourceName, IP: ctx.IP, UserAgent: truncate(ctx.UserAgent, 500), RequestPath: truncate(ctx.Path, 500), RequestMethod: ctx.Method, Status: 1, ErrorMessage: errMsg, CreatedAt: time.Now(), } if ctx.UserID != nil { log.UserID = ctx.UserID } log.Username = ctx.Username if !success { log.Status = 0 } _ = s.opLogRepo.Create(&log) } func truncate(s string, n int) string { if len(s) <= n { return s } return s[:n] }