package wire import ( "time" "with_you/internal/cache" "with_you/internal/config" "with_you/internal/grpc/runner" "with_you/internal/pkg/email" "with_you/internal/pkg/hook" "with_you/internal/pkg/jpush" "with_you/internal/pkg/openai" "with_you/internal/pkg/redis" "with_you/internal/pkg/s3" "with_you/internal/pkg/tencent" "with_you/internal/pkg/ws" "with_you/internal/repository" "with_you/internal/service" "github.com/google/wire" redisPkg "github.com/redis/go-redis/v9" "go.uber.org/zap" "gorm.io/gorm" ) // ServiceSet Service 层 Provider Set var ServiceSet = wire.NewSet( // JWT 服务(需要配置参数) ProvideJWTService, // 会话服务(令牌撤销支持) ProvideSessionService, // 基础服务 ProvideEmailService, ProvidePostAIService, // 核心服务(按依赖顺序) ProvidePushService, ProvideSystemMessageService, ProvidePostService, ProvideCommentService, ProvideMessageService, ProvideNotificationService, ProvideUserService, ProvideStickerService, ProvideVoteService, ProvideChannelService, ProvideChatService, ProvideScheduleService, ProvideScheduleSyncService, ProvideGradeSyncService, ProvideExamSyncService, ProvideEmptyClassroomSyncService, ProvideGroupService, ProvideUploadService, ProvideUserActivityService, ProvideRoleService, ProvideAdminUserService, ProvideAdminPostService, ProvideAdminCommentService, ProvideAdminGroupService, ProvideAdminDashboardService, ProvideQRCodeLoginService, ProvideHotRankWorker, ProvideFileCleanupWorker, ProvideDeviceCleanupWorker, ProvideMaterialService, ProvideCallService, ProvideLiveKitService, ProvideReportService, ProvideAdminReportService, ProvideVerificationService, ProvideAdminVerificationService, ProvideSensitiveService, ProvideUserProfileAuditService, ProvideSetupService, // 帖子内链引用 ProvidePostRefService, // 二手交易 ProvideTradeService, // 日志服务 ProvideAsyncLogManager, ProvideOperationLogService, ProvideLoginLogService, ProvideDataChangeLogService, ProvideLogCleanupService, ProvideLogService, ) // ProvideJWTService 提供 JWT 服务 func ProvideJWTService(cfg *config.Config) service.JWTService { return service.NewJWTService( cfg.JWT.Secret, int64(cfg.JWT.AccessTokenExpire.Seconds()), int64(cfg.JWT.RefreshTokenExpire.Seconds()), ) } // ProvideSessionService 提供会话服务(用于令牌撤销)。 func ProvideSessionService( sessionRepo repository.SessionRepository, jwtService service.JWTService, ) service.SessionService { return service.NewSessionService(sessionRepo, jwtService) } // ProvideEmailService 提供邮件服务 func ProvideEmailService(client email.Client) service.EmailService { return service.NewEmailService(client) } // ProvidePostAIService 提供 AI 服务 func ProvidePostAIService(openAIClient openai.Client, tencentClient tencent.Client, cfg *config.Config) service.PostAIService { return service.NewPostAIService(openAIClient, tencentClient, cfg.OpenAI.StrictModeration) } // ProvidePushService 提供推送服务 func ProvidePushService( pushRepo repository.PushRecordRepository, deviceTokenRepo repository.DeviceTokenRepository, messageRepo repository.MessageRepository, publisher ws.MessagePublisher, jpushClient *jpush.Client, cfg *config.Config, ) service.PushService { return service.NewPushService(pushRepo, deviceTokenRepo, messageRepo, publisher, jpushClient, cfg.JPush.Channel) } // ProvideSystemMessageService 提供系统消息服务 func ProvideSystemMessageService( notifyRepo repository.SystemNotificationRepository, pushService service.PushService, userRepo repository.UserRepository, postRepo repository.PostRepository, cacheBackend cache.Cache, ) service.SystemMessageService { return service.NewSystemMessageService(notifyRepo, pushService, userRepo, postRepo, cacheBackend) } func ProvidePostService( postRepo repository.PostRepository, systemMessageService service.SystemMessageService, postAIService service.PostAIService, cacheBackend cache.Cache, txManager repository.TransactionManager, hookManager *hook.Manager, _ *hook.ModerationHooks, _ *hook.BuiltinHooks, logService *service.LogService, ) service.PostService { return service.NewPostService(postRepo, systemMessageService, postAIService, cacheBackend, txManager, hookManager, logService) } func ProvideCommentService( commentRepo repository.CommentRepository, postRepo repository.PostRepository, systemMessageService service.SystemMessageService, postAIService service.PostAIService, cacheBackend cache.Cache, hookManager *hook.Manager, logService *service.LogService, ) service.CommentService { return service.NewCommentService(commentRepo, postRepo, systemMessageService, postAIService, cacheBackend, hookManager, logService) } // ProvideMessageService 提供消息服务 func ProvideMessageService( messageRepo repository.MessageRepository, cacheBackend cache.Cache, uploadService service.UploadService, ) service.MessageService { return service.NewMessageService(messageRepo, cacheBackend, uploadService) } // ProvideNotificationService 提供通知服务 func ProvideNotificationService( notificationRepo repository.NotificationRepository, cacheBackend cache.Cache, ) service.NotificationService { return service.NewNotificationService(notificationRepo, cacheBackend) } // ProvideUserService 提供用户服务 func ProvideUserService( userRepo repository.UserRepository, systemMessageService service.SystemMessageService, emailService service.EmailService, cacheBackend cache.Cache, logService *service.LogService, sessionService service.SessionService, ) service.UserService { return service.NewUserService(userRepo, systemMessageService, emailService, cacheBackend, logService, sessionService) } // ProvideStickerService 提供表情服务 func ProvideStickerService( stickerRepo repository.StickerRepository, ) service.StickerService { return service.NewStickerService(stickerRepo) } // ProvideVoteService 提供投票服务 func ProvideVoteService( voteRepo repository.VoteRepository, postRepo repository.PostRepository, cache cache.Cache, postAIService service.PostAIService, systemMessageService service.SystemMessageService, hookManager *hook.Manager, logService *service.LogService, ) service.VoteService { return service.NewVoteService(voteRepo, postRepo, cache, postAIService, systemMessageService, hookManager, logService) } func ProvideChannelService(channelRepo repository.ChannelRepository, cacheBackend cache.Cache) service.ChannelService { return service.NewChannelService(channelRepo, cacheBackend) } // ProvideChatService 提供聊天服务 // Note: sensitiveService 传 nil,与 main.go 保持一致 func ProvideChatService( messageRepo repository.MessageRepository, userRepo repository.UserRepository, publisher ws.MessagePublisher, cacheBackend cache.Cache, uploadService service.UploadService, pushService service.PushService, seqBufferMgr *cache.SeqBufferManager, pushWorker *service.PushWorker, redisClient *redis.Client, versionLogRepo repository.ConversationVersionLogRepository, cfg *config.Config, groupService service.GroupService, ) service.ChatService { var vlogOpt []repository.ConversationVersionLogRepository if cfg.VersionLog.Enabled { vlogOpt = []repository.ConversationVersionLogRepository{versionLogRepo} } var rdb *redisPkg.Client if redisClient != nil { rdb = redisClient.GetClient() } // 注入 GroupAbility:群消息发送前校验成员/禁言。 groupAbility := service.NewGroupAbility(groupService) return service.NewChatService(messageRepo, userRepo, nil, publisher, cacheBackend, uploadService, pushService, seqBufferMgr, pushWorker, rdb, groupAbility, vlogOpt...) } // ProvideScheduleService 提供日程服务 func ProvideScheduleService( scheduleRepo repository.ScheduleRepository, ) service.ScheduleService { return service.NewScheduleService(scheduleRepo) } // ProvideScheduleSyncService 提供课表同步服务 func ProvideScheduleSyncService( taskManager *runner.TaskManager, scheduleRepo repository.ScheduleRepository, logger *zap.Logger, ) service.ScheduleSyncService { return service.NewScheduleSyncService(taskManager, scheduleRepo, logger) } // ProvideGradeSyncService 提供成绩同步服务 func ProvideGradeSyncService( taskManager *runner.TaskManager, gradeRepo repository.GradeRepository, logger *zap.Logger, ) service.GradeSyncService { return service.NewGradeSyncService(taskManager, gradeRepo, logger) } // ProvideExamSyncService 提供考试安排同步服务 func ProvideExamSyncService( taskManager *runner.TaskManager, examRepo repository.ExamRepository, logger *zap.Logger, ) service.ExamSyncService { return service.NewExamSyncService(taskManager, examRepo, logger) } // ProvideEmptyClassroomSyncService 提供空教室同步服务 func ProvideEmptyClassroomSyncService( taskManager *runner.TaskManager, classroomRepo repository.EmptyClassroomRepository, logger *zap.Logger, ) service.EmptyClassroomSyncService { return service.NewEmptyClassroomSyncService(taskManager, classroomRepo, logger) } // ProvideGroupService 提供群组服务 func ProvideGroupService( groupRepo repository.GroupRepository, userRepo repository.UserRepository, messageRepo repository.MessageRepository, requestRepo repository.GroupJoinRequestRepository, notifyRepo repository.SystemNotificationRepository, publisher ws.MessagePublisher, cacheBackend cache.Cache, ) service.GroupService { return service.NewGroupService(groupRepo, userRepo, messageRepo, requestRepo, notifyRepo, publisher, cacheBackend) } // ProvideUploadService 提供上传服务 func ProvideUploadService( s3Client *s3.Client, userService service.UserService, uploadedRepo repository.UploadedFileRepository, ) service.UploadService { return service.NewUploadService(s3Client, userService, uploadedRepo) } // ProvideFileCleanupWorker 提供聊天文件过期清理 worker func ProvideFileCleanupWorker( cfg *config.Config, uploadedRepo repository.UploadedFileRepository, s3Client *s3.Client, redisClient *redis.Client, ) *service.FileCleanupWorker { var rdb *redisPkg.Client if redisClient != nil { rdb = redisClient.GetClient() } return service.NewFileCleanupWorker(cfg, uploadedRepo, s3Client, rdb) } // ProvideDeviceCleanupWorker 提供设备 registration_id 清理 worker func ProvideDeviceCleanupWorker( cfg *config.Config, deviceRepo repository.DeviceTokenRepository, redisClient *redis.Client, ) *service.DeviceCleanupWorker { var rdb *redisPkg.Client if redisClient != nil { rdb = redisClient.GetClient() } return service.NewDeviceCleanupWorker(cfg, deviceRepo, rdb) } // ProvideUserActivityService 提供用户活跃统计服务 func ProvideUserActivityService(repo repository.UserActivityRepository) service.UserActivityService { return service.NewUserActivityService(repo) } // ProvideRoleService 提供角色管理服务 func ProvideRoleService( roleRepo repository.RoleRepository, casbinSvc service.CasbinService, ) service.RoleService { return service.NewRoleService(roleRepo, casbinSvc) } // ProvideAdminUserService 提供管理端用户服务 // // 注入 SessionService 与 cache:封禁/停用用户时撤销其全部登录会话并失效 Principal 缓存。 func ProvideAdminUserService( userRepo repository.UserRepository, sessionService service.SessionService, cacheBackend cache.Cache, ) service.AdminUserService { return service.NewAdminUserService(userRepo, sessionService, cacheBackend) } // ProvideAdminPostService 提供管理端帖子服务 func ProvideAdminPostService(postRepo repository.PostRepository, cacheBackend cache.Cache, logService *service.LogService) service.AdminPostService { return service.NewAdminPostService(postRepo, cacheBackend, logService) } // ProvideAdminCommentService 提供管理端评论服务 func ProvideAdminCommentService(commentRepo repository.CommentRepository, postRepo repository.PostRepository, cacheBackend cache.Cache) service.AdminCommentService { return service.NewAdminCommentService(commentRepo, postRepo, cacheBackend) } // ProvideAdminGroupService 提供管理端群组服务 func ProvideAdminGroupService( groupRepo repository.GroupRepository, userRepo repository.UserRepository, ) service.AdminGroupService { return service.NewAdminGroupService(groupRepo, userRepo) } // ProvideAdminDashboardService 提供管理端仪表盘服务 func ProvideAdminDashboardService( db *gorm.DB, userRepo repository.UserRepository, postRepo repository.PostRepository, commentRepo repository.CommentRepository, groupRepo repository.GroupRepository, activityRepo repository.UserActivityRepository, ) service.AdminDashboardService { return service.NewAdminDashboardService(db, userRepo, postRepo, commentRepo, groupRepo, activityRepo) } // ProvideAsyncLogManager 提供异步日志管理器 func ProvideAsyncLogManager( operationRepo repository.OperationLogRepository, loginRepo repository.LoginLogRepository, dataChangeRepo repository.DataChangeLogRepository, logger *zap.Logger, cfg *config.Config, ) *service.AsyncLogManager { asyncCfg := &service.AsyncLogConfig{ BufferSize: cfg.Log.Async.BufferSize, BatchSize: cfg.Log.Async.BatchSize, WorkerCount: cfg.Log.Async.WorkerCount, EnableFallback: cfg.Log.Async.EnableFallback, FallbackPath: cfg.Log.Async.FallbackPath, } // 解析刷新间隔 if duration, err := parseDuration(cfg.Log.Async.FlushInterval); err == nil { asyncCfg.FlushInterval = duration } else { asyncCfg.FlushInterval = 3 * time.Second } return service.NewAsyncLogManager(operationRepo, loginRepo, dataChangeRepo, logger, asyncCfg) } // ProvideOperationLogService 提供操作日志服务 func ProvideOperationLogService( asyncManager *service.AsyncLogManager, operationRepo repository.OperationLogRepository, ) service.OperationLogService { return service.NewOperationLogService(asyncManager, operationRepo) } // ProvideLoginLogService 提供登录日志服务 func ProvideLoginLogService( asyncManager *service.AsyncLogManager, loginRepo repository.LoginLogRepository, ) service.LoginLogService { return service.NewLoginLogService(asyncManager, loginRepo) } // ProvideDataChangeLogService 提供数据变更日志服务 func ProvideDataChangeLogService( asyncManager *service.AsyncLogManager, dataChangeRepo repository.DataChangeLogRepository, ) service.DataChangeLogService { return service.NewDataChangeLogService(asyncManager, dataChangeRepo) } // ProvideLogCleanupService 提供日志清理服务 func ProvideLogCleanupService( operationRepo repository.OperationLogRepository, loginRepo repository.LoginLogRepository, dataChangeRepo repository.DataChangeLogRepository, logger *zap.Logger, cfg *config.Config, ) service.LogCleanupService { cleanupCfg := &service.LogCleanupConfig{ Enabled: true, OperationLog: cfg.Log.Retention.OperationLog, LoginLog: cfg.Log.Retention.LoginLog, DataChangeLog: cfg.Log.Retention.DataChange, CleanupTime: "02:00", } return service.NewLogCleanupService(operationRepo, loginRepo, dataChangeRepo, cleanupCfg, logger) } // ProvideLogService 提供日志服务组合 func ProvideLogService( operationLogService service.OperationLogService, loginLogService service.LoginLogService, dataChangeLogService service.DataChangeLogService, ) *service.LogService { return service.NewLogService(operationLogService, loginLogService, dataChangeLogService) } // ProvideQRCodeLoginService 提供二维码登录服务 func ProvideHotRankWorker(cfg *config.Config, postRepo repository.PostRepository, channelRepo repository.ChannelRepository, cacheBackend cache.Cache, redisClient *redis.Client) *service.HotRankWorker { var rdb *redisPkg.Client if redisClient != nil { rdb = redisClient.GetClient() } return service.NewHotRankWorker(cfg, postRepo, channelRepo, cacheBackend, rdb) } func ProvideQRCodeLoginService( redisClient *redis.Client, publisher ws.MessagePublisher, jwtService service.JWTService, userService service.UserService, activityService service.UserActivityService, logService *service.LogService, ) service.QRCodeLoginService { return service.NewQRCodeLoginService(redisClient, publisher, jwtService, userService, activityService, logService) } // ProvideMaterialService 提供学习资料服务 func ProvideMaterialService( subjectRepo repository.MaterialSubjectRepository, fileRepo repository.MaterialFileRepository, ) service.MaterialService { return service.NewMaterialService(subjectRepo, fileRepo) } // parseDuration 解析时长字符串 func parseDuration(s string) (time.Duration, error) { return time.ParseDuration(s) } // ProvideCallService 提供通话服务 func ProvideCallService( callRepo repository.CallRepository, publisher ws.MessagePublisher, cfg *config.Config, db *gorm.DB, redisClient *redis.Client, groupService service.GroupService, ) service.CallService { return service.NewCallService(callRepo, publisher, cfg, db, redisClient, groupService) } // ProvideLiveKitService 提供 LiveKit 服务 func ProvideLiveKitService( cfg *config.Config, logger *zap.Logger, ) service.LiveKitService { return service.NewLiveKitService(cfg, logger) } // ProvideReportService 提供举报服务 func ProvideReportService( reportRepo repository.ReportRepository, postRepo repository.PostRepository, commentRepo repository.CommentRepository, messageRepo repository.MessageRepository, userRepo repository.UserRepository, notifyRepo repository.SystemNotificationRepository, pushService service.PushService, txManager repository.TransactionManager, logService service.OperationLogService, cfg *config.Config, ) service.ReportService { return service.NewReportService(reportRepo, postRepo, commentRepo, messageRepo, userRepo, notifyRepo, pushService, txManager, logService, cfg) } // ProvideAdminReportService 提供管理端举报服务 func ProvideAdminReportService( reportRepo repository.ReportRepository, postRepo repository.PostRepository, commentRepo repository.CommentRepository, messageRepo repository.MessageRepository, userRepo repository.UserRepository, notifyRepo repository.SystemNotificationRepository, pushService service.PushService, txManager repository.TransactionManager, logService service.OperationLogService, ) service.AdminReportService { return service.NewAdminReportService(reportRepo, postRepo, commentRepo, messageRepo, userRepo, notifyRepo, pushService, txManager, logService) } // ProvideVerificationService 提供身份认证服务 func ProvideVerificationService( verificationRepo repository.VerificationRepository, userRepo repository.UserRepository, ) service.VerificationService { return service.NewVerificationService(verificationRepo, userRepo) } // ProvideAdminVerificationService 提供管理端身份认证服务 func ProvideAdminVerificationService( verificationRepo repository.VerificationRepository, userRepo repository.UserRepository, ) service.AdminVerificationService { return service.NewAdminVerificationService(verificationRepo, userRepo) } // ProvideSensitiveService 提供敏感词服务 func ProvideSensitiveService( sensitiveWordRepo repository.SensitiveWordRepository, redisClient *redis.Client, cfg *config.Config, ) service.SensitiveService { sensitiveCfg := &service.SensitiveConfig{ Enabled: cfg.Sensitive.Enabled, ReplaceStr: cfg.Sensitive.ReplaceStr, MinMatchLen: cfg.Sensitive.MinMatchLen, LoadFromDB: cfg.Sensitive.LoadFromDB, LoadFromRedis: cfg.Sensitive.LoadFromRedis, RedisKeyPrefix: cfg.Sensitive.RedisKeyPrefix, } return service.NewSensitiveService(sensitiveWordRepo, redisClient, sensitiveCfg) } func ProvideUserProfileAuditService( auditRepo repository.UserProfileAuditRepository, userRepo repository.UserRepository, hookManager *hook.Manager, moderationHooks *hook.ModerationHooks, ) service.UserProfileAuditService { return service.NewUserProfileAuditService(auditRepo, userRepo, hookManager, moderationHooks) } func ProvideSetupService( userRepo repository.UserRepository, roleRepo repository.RoleRepository, casbinSvc service.CasbinService, cfg *config.Config, ) service.SetupService { return service.NewSetupService(userRepo, roleRepo, casbinSvc, cfg.SetupSecret) } func ProvidePostRefService( refRepo repository.PostRefRepository, postRepo repository.PostRepository, ) service.PostRefService { return service.NewPostRefService(refRepo, postRepo) } func ProvideTradeService(tradeRepo repository.TradeRepository) service.TradeService { return service.NewTradeService(tradeRepo) }