package wire import ( "fmt" "log" "time" "dd_fiber_api/config" "dd_fiber_api/internal/admin" "dd_fiber_api/internal/admin/statistics" admin_auth_dao "dd_fiber_api/internal/admin_auth/dao" admin_auth_handler "dd_fiber_api/internal/admin_auth/handler" admin_auth_service "dd_fiber_api/internal/admin_auth/service" "dd_fiber_api/internal/api" "dd_fiber_api/internal/camp/dao" "dd_fiber_api/internal/camp/handler" "dd_fiber_api/internal/camp/service" document_dao "dd_fiber_api/internal/document/dao" document_handler "dd_fiber_api/internal/document/handler" document_service "dd_fiber_api/internal/document/service" order_dao "dd_fiber_api/internal/order/dao" order_handler "dd_fiber_api/internal/order/handler" order_service "dd_fiber_api/internal/order/service" "dd_fiber_api/internal/oss" "dd_fiber_api/internal/payment" question_dao "dd_fiber_api/internal/question/dao" question_handler "dd_fiber_api/internal/question/handler" question_service "dd_fiber_api/internal/question/service" "dd_fiber_api/internal/scheduler" "dd_fiber_api/pkg/database" "dd_fiber_api/pkg/snowflake" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/recover" ) // App 应用结构 type App struct { AdminApp *AdminApp APIApp *APIApp Config *config.Config MySQLClient *database.MySQLClient MongoDBClient *database.MongoDBClient RedisClient *database.RedisClient } // NewApp 创建应用 func NewApp( adminApp *AdminApp, apiApp *APIApp, cfg *config.Config, mysqlClient *database.MySQLClient, mongodbClient *database.MongoDBClient, redisClient *database.RedisClient, ) *App { return &App{ AdminApp: adminApp, APIApp: apiApp, Config: cfg, MySQLClient: mysqlClient, MongoDBClient: mongodbClient, RedisClient: redisClient, } } // Close 关闭应用资源 func (a *App) Close() { if a.MySQLClient != nil { a.MySQLClient.Close() } if a.MongoDBClient != nil { a.MongoDBClient.Close() } if a.RedisClient != nil { a.RedisClient.Close() } } // NewMySQLClient 创建 MySQL 客户端 func NewMySQLClient(cfg *config.Config) (*database.MySQLClient, error) { if cfg.MySQL.Database == "" { return nil, nil } client, err := database.NewMySQLClient(&cfg.MySQL) if err != nil { return nil, err } log.Println(" ✅ MySQL 连接成功") return client, nil } // NewRedisClient 创建 Redis 客户端 func NewRedisClient(cfg *config.Config) (*database.RedisClient, error) { if cfg.Redis.Host == "" { return nil, nil } client, err := database.NewRedisClient(&cfg.Redis) if err != nil { log.Printf(" ⚠️ Redis 连接失败,将不使用缓存: %v", err) return nil, nil // 返回 nil 而不是错误,允许应用继续运行 } log.Println(" ✅ Redis 连接成功") return client, nil } // NewMongoDBClient 创建 MongoDB 客户端 func NewMongoDBClient(cfg *config.Config) (*database.MongoDBClient, error) { log.Println(" 🔄 正在连接 MongoDB...") if cfg.MongoDB.URI == "" { log.Println(" ⚠️ MongoDB URI 未配置,跳过连接") return nil, nil } log.Printf(" 📍 MongoDB URI: %s", maskURI(cfg.MongoDB.URI)) log.Printf(" 📍 MongoDB Database: %s", cfg.MongoDB.Database) client, err := database.NewMongoDBClient(&cfg.MongoDB) if err != nil { log.Printf(" ❌ MongoDB 连接失败: %v", err) return nil, err } log.Printf(" ✅ MongoDB 连接成功 (数据库: %s)", cfg.MongoDB.Database) return client, nil } // NewOSSService 创建 OSS 服务 func NewOSSService(cfg *config.Config, redisClient *database.RedisClient) *oss.Service { if cfg.OSS.AccessKeyID == "" { return nil } service := oss.NewService(&cfg.OSS, redisClient) log.Println(" ✅ OSS 服务初始化成功") return service } // NewOSSHandler 创建 OSS 处理器 func NewOSSHandler(ossService *oss.Service) *oss.Handler { if ossService == nil { return nil } return oss.NewHandler(ossService) } // NewWechatPayV3Service 创建微信支付 V3 服务 func NewWechatPayV3Service(cfg *config.Config) (*payment.WechatPayV3Service, error) { if cfg.Wechat.APIKeyV3 == "" || (cfg.Wechat.PrivateKey == "" && cfg.Wechat.PrivateKeyPath == "") { return nil, nil } service, err := payment.NewWechatPayV3Service(&cfg.Wechat) if err != nil { log.Printf(" ⚠️ 微信支付 V3 服务初始化失败: %v", err) return nil, nil } log.Println(" ✅ 微信支付 V3 服务初始化成功") return service, nil } // NewPaymentHandler 创建支付处理器 func NewPaymentHandler( wechatPayV3Service *payment.WechatPayV3Service, orderDAO *order_dao.OrderDAO, accessDAO *dao.UserSectionAccessDAO, userCampDAO *dao.UserCampDAO, ) *payment.Handler { if wechatPayV3Service == nil { return nil } paymentHandler := payment.NewHandler(wechatPayV3Service) if orderDAO != nil { paymentHandler.SetOrderDAO(orderDAO) } if accessDAO != nil { paymentHandler.SetAccessDAO(accessDAO) } if userCampDAO != nil { paymentHandler.SetUserCampDAO(userCampDAO) } return paymentHandler } // NewSchedulerService 创建调度器服务 func NewSchedulerService(cfg *config.Config) *scheduler.Service { if cfg.Scheduler.SlotNum <= 0 { return nil } // 初始化雪花算法ID生成器 if err := snowflake.InitDefault(1, 1); err != nil { log.Printf("⚠️ 雪花算法ID生成器初始化失败: %v", err) return nil } // 解析时间轮配置 tickInterval, err := time.ParseDuration(cfg.Scheduler.TickInterval) if err != nil { log.Printf("⚠️ 时间轮配置解析失败,使用默认值: %v", err) tickInterval = 100 * time.Millisecond } slotNum := cfg.Scheduler.SlotNum if slotNum <= 0 { slotNum = 3600 } service := scheduler.NewService(tickInterval, slotNum) log.Printf(" ✅ 调度器服务初始化成功 (tick=%v, slots=%d)", tickInterval, slotNum) return service } // NewSchedulerHandler 创建调度器处理器 func NewSchedulerHandler(schedulerService *scheduler.Service) *scheduler.Handler { if schedulerService == nil { return nil } return scheduler.NewHandler(schedulerService) } // NewCategoryDAO 创建分类 DAO func NewCategoryDAO(mysqlClient *database.MySQLClient) *dao.CategoryDAO { if mysqlClient == nil { return nil } return dao.NewCategoryDAO(mysqlClient) } // NewCategoryService 创建分类服务 func NewCategoryService(categoryDAO *dao.CategoryDAO, campDAO *dao.CampDAO) *service.CategoryService { if categoryDAO == nil { return nil } return service.NewCategoryService(categoryDAO, campDAO) } // NewCategoryHandler 创建分类处理器 func NewCategoryHandler(categoryService *service.CategoryService) *handler.CategoryHandler { if categoryService == nil { return nil } return handler.NewCategoryHandler(categoryService) } // NewCampDAO 创建打卡营 DAO func NewCampDAO(mysqlClient *database.MySQLClient) *dao.CampDAO { if mysqlClient == nil { return nil } return dao.NewCampDAO(mysqlClient) } // NewCampService 创建打卡营服务 func NewCampService( campDAO *dao.CampDAO, sectionDAO *dao.SectionDAO, taskDAO *dao.TaskDAO, progressDAO *dao.ProgressDAO, userCampDAO *dao.UserCampDAO, orderDAO *order_dao.OrderDAO, answerRecordService *question_service.AnswerRecordService, paperService *question_service.PaperService, orderService *order_service.OrderService, ) *service.CampService { if campDAO == nil { return nil } campService := service.NewCampService(campDAO) if sectionDAO != nil && taskDAO != nil && progressDAO != nil && userCampDAO != nil && orderDAO != nil { campService.SetDependencies(sectionDAO, taskDAO, progressDAO, userCampDAO, orderDAO) } if answerRecordService != nil { campService.SetAnswerRecordService(answerRecordService) } if paperService != nil { campService.SetPaperService(paperService) } if orderService != nil { campService.SetOrderService(orderService) } return campService } // NewCampHandler 创建打卡营处理器(需传入 userCampService 以便列表接口返回 is_joined) func NewCampHandler(campService *service.CampService, userCampService *service.UserCampService) *handler.CampHandler { if campService == nil { return nil } h := handler.NewCampHandler(campService, userCampService) log.Println(" ✅ Camp 服务初始化成功(分类、打卡营、小节、任务、进度、用户打卡营、订单)") return h } // NewSectionDAO 创建小节 DAO func NewSectionDAO(mysqlClient *database.MySQLClient) *dao.SectionDAO { if mysqlClient == nil { return nil } return dao.NewSectionDAO(mysqlClient) } // NewSectionService 创建小节服务 func NewSectionService(sectionDAO *dao.SectionDAO, campDAO *dao.CampDAO) *service.SectionService { if sectionDAO == nil || campDAO == nil { return nil } return service.NewSectionService(sectionDAO, campDAO) } // NewSectionHandler 创建小节处理器 func NewSectionHandler( sectionService *service.SectionService, orderService *order_service.OrderService, orderDAO *order_dao.OrderDAO, userCampDAO *dao.UserCampDAO, ) *handler.SectionHandler { if sectionService == nil { return nil } sectionHandler := handler.NewSectionHandler(sectionService) if orderService != nil { sectionHandler.SetOrderService(orderService) } if orderDAO != nil { sectionHandler.SetOrderDAO(orderDAO) } if userCampDAO != nil { sectionHandler.SetUserCampDAO(userCampDAO) } return sectionHandler } // NewTaskDAO 创建任务 DAO func NewTaskDAO(mysqlClient *database.MySQLClient) *dao.TaskDAO { if mysqlClient == nil { return nil } return dao.NewTaskDAO(mysqlClient) } // NewTaskService 创建任务服务 func NewTaskService(taskDAO *dao.TaskDAO) *service.TaskService { if taskDAO == nil { return nil } return service.NewTaskService(taskDAO) } // NewTaskHandler 创建任务处理器 func NewTaskHandler(taskService *service.TaskService) *handler.TaskHandler { if taskService == nil { return nil } return handler.NewTaskHandler(taskService) } // NewProgressDAO 创建进度 DAO func NewProgressDAO(mysqlClient *database.MySQLClient) *dao.ProgressDAO { if mysqlClient == nil { return nil } return dao.NewProgressDAO(mysqlClient) } // NewProgressService 创建进度服务 func NewProgressService(progressDAO *dao.ProgressDAO, taskDAO *dao.TaskDAO, userCampDAO *dao.UserCampDAO, answerRecordService *question_service.AnswerRecordService, campService *service.CampService) *service.ProgressService { if progressDAO == nil || taskDAO == nil { return nil } return service.NewProgressService(progressDAO, taskDAO, userCampDAO, answerRecordService, campService) } // NewProgressHandler 创建进度处理器 func NewProgressHandler(progressService *service.ProgressService) *handler.ProgressHandler { if progressService == nil { return nil } return handler.NewProgressHandler(progressService) } // NewUserCampDAO 创建用户打卡营 DAO func NewUserCampDAO(mysqlClient *database.MySQLClient) *dao.UserCampDAO { if mysqlClient == nil { return nil } return dao.NewUserCampDAO(mysqlClient) } // NewResetHistoryDAO 创建打卡营重置历史 DAO func NewResetHistoryDAO(mysqlClient *database.MySQLClient) *dao.ResetHistoryDAO { if mysqlClient == nil { return nil } return dao.NewResetHistoryDAO(mysqlClient) } // NewUserCampService 创建用户打卡营服务 func NewUserCampService( userCampDAO *dao.UserCampDAO, sectionDAO *dao.SectionDAO, progressDAO *dao.ProgressDAO, taskDAO *dao.TaskDAO, resetHistoryDAO *dao.ResetHistoryDAO, answerRecordDAO question_dao.AnswerRecordDAOInterface, ) *service.UserCampService { if userCampDAO == nil || sectionDAO == nil || progressDAO == nil { return nil } return service.NewUserCampService(userCampDAO, sectionDAO, progressDAO, taskDAO, resetHistoryDAO, answerRecordDAO) } // NewUserCampHandler 创建用户打卡营处理器 func NewUserCampHandler(userCampService *service.UserCampService) *handler.UserCampHandler { if userCampService == nil { return nil } return handler.NewUserCampHandler(userCampService) } // NewUserSectionAccessDAO 创建用户小节访问记录 DAO func NewUserSectionAccessDAO(mysqlClient *database.MySQLClient) *dao.UserSectionAccessDAO { if mysqlClient == nil { return nil } return dao.NewUserSectionAccessDAO(mysqlClient) } // NewOrderDAO 创建订单 DAO func NewOrderDAO(mysqlClient *database.MySQLClient) *order_dao.OrderDAO { if mysqlClient == nil { return nil } return order_dao.NewOrderDAO(mysqlClient) } // NewOrderService 创建订单服务 func NewOrderService( orderDAO *order_dao.OrderDAO, sectionDAO *dao.SectionDAO, wechatPayV3Service *payment.WechatPayV3Service, accessDAO *dao.UserSectionAccessDAO, userCampDAO *dao.UserCampDAO, schedulerService *scheduler.Service, cfg *config.Config, ) *order_service.OrderService { if orderDAO == nil || sectionDAO == nil { return nil } orderService := order_service.NewOrderService(orderDAO, sectionDAO) if wechatPayV3Service != nil { orderService.SetPaymentService(wechatPayV3Service) } if accessDAO != nil { orderService.SetAccessDAO(accessDAO) } if userCampDAO != nil { orderService.SetUserCampDAO(userCampDAO) } if schedulerService != nil { orderService.SetSchedulerService(schedulerService) } // 构建 API base URL(用于定时任务回调) if cfg != nil { apiBaseURL := fmt.Sprintf("http://%s:%d", cfg.Service.Host, cfg.Service.APIPort) orderService.SetAPIBaseURL(apiBaseURL) } return orderService } // NewOrderHandler 创建订单处理器 func NewOrderHandler(orderService *order_service.OrderService) *order_handler.OrderHandler { if orderService == nil { return nil } return order_handler.NewOrderHandler(orderService) } // NewQuestionDAO 创建题目 DAO(MongoDB) func NewQuestionDAO(mongodbClient *database.MongoDBClient) question_dao.QuestionDAOInterface { if mongodbClient == nil { return nil } dao := question_dao.NewQuestionDAOMongo(mongodbClient) // 创建索引 if err := dao.CreateIndexes(); err != nil { log.Printf(" ⚠️ 创建题目索引失败: %v", err) } return dao } // NewQuestionService 创建题目服务 func NewQuestionService(questionDAO question_dao.QuestionDAOInterface) *question_service.QuestionService { if questionDAO == nil { return nil } return question_service.NewQuestionService(questionDAO) } // NewQuestionHandler 创建题目处理器 func NewQuestionHandler( questionService *question_service.QuestionService, knowledgeTreeService *question_service.KnowledgeTreeService, ) *question_handler.QuestionHandler { if questionService == nil { return nil } return question_handler.NewQuestionHandler(questionService, knowledgeTreeService) } // NewPaperDAO 创建试卷 DAO(MongoDB) func NewPaperDAO(mongodbClient *database.MongoDBClient, questionDAO question_dao.QuestionDAOInterface) question_dao.PaperDAOInterface { if mongodbClient == nil || questionDAO == nil { return nil } dao := question_dao.NewPaperDAOMongo(mongodbClient, questionDAO) // 创建索引 if err := dao.CreateIndexes(); err != nil { log.Printf(" ⚠️ 创建试卷索引失败: %v", err) } return dao } // NewPaperService 创建试卷服务 func NewPaperService(paperDAO question_dao.PaperDAOInterface, materialService *question_service.MaterialService) *question_service.PaperService { if paperDAO == nil { return nil } return question_service.NewPaperService(paperDAO, materialService) } // NewPaperHandler 创建试卷处理器 func NewPaperHandler(paperService *question_service.PaperService) *question_handler.PaperHandler { if paperService == nil { return nil } return question_handler.NewPaperHandler(paperService) } // NewAnswerRecordDAO 创建答题记录 DAO(MongoDB) func NewAnswerRecordDAO(mongodbClient *database.MongoDBClient) question_dao.AnswerRecordDAOInterface { if mongodbClient == nil { return nil } dao := question_dao.NewAnswerRecordDAOMongo(mongodbClient) // 创建索引 if err := dao.CreateIndexes(); err != nil { log.Printf(" ⚠️ 创建答题记录索引失败: %v", err) } return dao } // NewAnswerRecordService 创建答题记录服务 func NewAnswerRecordService(answerRecordDAO question_dao.AnswerRecordDAOInterface, questionDAO question_dao.QuestionDAOInterface) *question_service.AnswerRecordService { if answerRecordDAO == nil || questionDAO == nil { return nil } return question_service.NewAnswerRecordService(answerRecordDAO, questionDAO) } // NewAnswerRecordHandler 创建答题记录处理器 func NewAnswerRecordHandler(answerRecordService *question_service.AnswerRecordService) *question_handler.AnswerRecordHandler { if answerRecordService == nil { return nil } handler := question_handler.NewAnswerRecordHandler(answerRecordService) log.Println(" ✅ Question 服务初始化成功(题目、试卷、答题记录)") return handler } // NewMaterialDAO 创建材料 DAO(MongoDB) func NewMaterialDAO(mongodbClient *database.MongoDBClient) question_dao.MaterialDAOInterface { if mongodbClient == nil { return nil } dao := question_dao.NewMaterialDAOMongo(mongodbClient) // 创建索引 if err := dao.CreateIndexes(); err != nil { log.Printf(" ⚠️ 创建材料索引失败: %v", err) } return dao } // NewMaterialService 创建材料服务 func NewMaterialService(materialDAO question_dao.MaterialDAOInterface) *question_service.MaterialService { if materialDAO == nil { return nil } return question_service.NewMaterialService(materialDAO) } // NewMaterialHandler 创建材料处理器 func NewMaterialHandler(materialService *question_service.MaterialService) *question_handler.MaterialHandler { if materialService == nil { return nil } handler := question_handler.NewMaterialHandler(materialService) log.Println(" ✅ Material 服务初始化成功") return handler } // NewKnowledgeTreeDAO 创建知识树 DAO(MongoDB) func NewKnowledgeTreeDAO(mongodbClient *database.MongoDBClient) question_dao.KnowledgeTreeDAOInterface { if mongodbClient == nil { return nil } dao := question_dao.NewKnowledgeTreeDAOMongo(mongodbClient) return dao } // NewKnowledgeTreeService 创建知识树服务 func NewKnowledgeTreeService(knowledgeTreeDAO question_dao.KnowledgeTreeDAOInterface) *question_service.KnowledgeTreeService { if knowledgeTreeDAO == nil { return nil } return question_service.NewKnowledgeTreeService(knowledgeTreeDAO) } // NewKnowledgeTreeHandler 创建知识树处理器 func NewKnowledgeTreeHandler(knowledgeTreeService *question_service.KnowledgeTreeService) *question_handler.KnowledgeTreeHandler { if knowledgeTreeService == nil { return nil } handler := question_handler.NewKnowledgeTreeHandler(knowledgeTreeService) log.Println(" ✅ KnowledgeTree 服务初始化成功") return handler } // AdminApp Admin 应用类型 type AdminApp struct { *fiber.App } // APIApp API 应用类型 type APIApp struct { *fiber.App } // NewAdminUserDAO 创建管理员用户 DAO func NewAdminUserDAO(mysqlClient *database.MySQLClient) *admin_auth_dao.AdminUserDAO { if mysqlClient == nil { return nil } return admin_auth_dao.NewAdminUserDAO(mysqlClient) } // NewAuthService 创建认证服务 func NewAuthService(adminUserDAO *admin_auth_dao.AdminUserDAO, cfg *config.Config) *admin_auth_service.AuthService { if adminUserDAO == nil { return nil } // 解析 JWT 过期时间 jwtExpiresIn := 24 * time.Hour // 默认 24 小时 if cfg.Admin.JWTExpiresIn != "" { if parsed, err := time.ParseDuration(cfg.Admin.JWTExpiresIn); err == nil { jwtExpiresIn = parsed } } // 获取 JWT 密钥 jwtSecret := cfg.Admin.JWTSecret if jwtSecret == "" { jwtSecret = "your-secret-key-change-in-production" } service := admin_auth_service.NewAuthService(adminUserDAO, jwtSecret, jwtExpiresIn) log.Println(" ✅ Admin 认证服务初始化成功") return service } // NewAuthHandler 创建认证处理器 func NewAuthHandler(authService *admin_auth_service.AuthService) *admin_auth_handler.AuthHandler { if authService == nil { return nil } return admin_auth_handler.NewAuthHandler(authService) } // NewAdminUserService 创建管理员用户服务 func NewAdminUserService(adminUserDAO *admin_auth_dao.AdminUserDAO) *admin_auth_service.AdminUserService { if adminUserDAO == nil { return nil } return admin_auth_service.NewAdminUserService(adminUserDAO) } // NewAdminUserHandler 创建管理员用户处理器 func NewAdminUserHandler(adminUserService *admin_auth_service.AdminUserService) *admin_auth_handler.AdminUserHandler { if adminUserService == nil { return nil } return admin_auth_handler.NewAdminUserHandler(adminUserService) } // NewRoleDAO 创建角色 DAO func NewRoleDAO(mysqlClient *database.MySQLClient) *admin_auth_dao.RoleDAO { if mysqlClient == nil { return nil } return admin_auth_dao.NewRoleDAO(mysqlClient) } // NewRoleService 创建角色服务 func NewRoleService(roleDAO *admin_auth_dao.RoleDAO) *admin_auth_service.RoleService { if roleDAO == nil { return nil } return admin_auth_service.NewRoleService(roleDAO) } // NewRoleHandler 创建角色处理器 func NewRoleHandler(roleService *admin_auth_service.RoleService) *admin_auth_handler.RoleHandler { if roleService == nil { return nil } return admin_auth_handler.NewRoleHandler(roleService) } // NewPermissionDAO 创建权限 DAO func NewPermissionDAO(mysqlClient *database.MySQLClient) *admin_auth_dao.PermissionDAO { if mysqlClient == nil { return nil } return admin_auth_dao.NewPermissionDAO(mysqlClient) } // NewPermissionService 创建权限服务 func NewPermissionService(permissionDAO *admin_auth_dao.PermissionDAO) *admin_auth_service.PermissionService { if permissionDAO == nil { return nil } return admin_auth_service.NewPermissionService(permissionDAO) } // NewPermissionHandler 创建权限处理器 func NewPermissionHandler(permissionService *admin_auth_service.PermissionService) *admin_auth_handler.PermissionHandler { if permissionService == nil { return nil } return admin_auth_handler.NewPermissionHandler(permissionService) } // NewStatisticsService 创建统计服务 func NewStatisticsService( mysqlClient *database.MySQLClient, campDAO *dao.CampDAO, questionDAO question_dao.QuestionDAOInterface, paperDAO question_dao.PaperDAOInterface, ) *statistics.Service { if mysqlClient == nil || campDAO == nil || questionDAO == nil || paperDAO == nil { return nil } return statistics.NewService(mysqlClient, campDAO, questionDAO, paperDAO) } // NewStatisticsHandler 创建统计处理器 func NewStatisticsHandler(statisticsService *statistics.Service) *statistics.Handler { if statisticsService == nil { return nil } return statistics.NewHandler(statisticsService) } // Document 文档管理 func NewFolderDAO(mysqlClient *database.MySQLClient) *document_dao.FolderDAO { if mysqlClient == nil { return nil } return document_dao.NewFolderDAO(mysqlClient) } func NewFileDAO(mysqlClient *database.MySQLClient) *document_dao.FileDAO { if mysqlClient == nil { return nil } return document_dao.NewFileDAO(mysqlClient) } func NewDocumentService(folderDAO *document_dao.FolderDAO, fileDAO *document_dao.FileDAO) *document_service.DocumentService { if folderDAO == nil || fileDAO == nil { return nil } return document_service.NewDocumentService(folderDAO, fileDAO) } func NewDocumentHandler(documentService *document_service.DocumentService) *document_handler.Handler { if documentService == nil { return nil } return document_handler.NewHandler(documentService) } // NewAdminApp 创建 Admin 应用 func NewAdminApp( cfg *config.Config, ossHandler *oss.Handler, paymentHandler *payment.Handler, schedulerHandler *scheduler.Handler, campCategoryHandler *handler.CategoryHandler, campHandler *handler.CampHandler, sectionHandler *handler.SectionHandler, taskHandler *handler.TaskHandler, progressHandler *handler.ProgressHandler, userCampHandler *handler.UserCampHandler, orderHandler *order_handler.OrderHandler, questionHandler *question_handler.QuestionHandler, paperHandler *question_handler.PaperHandler, answerRecordHandler *question_handler.AnswerRecordHandler, authHandler *admin_auth_handler.AuthHandler, authService *admin_auth_service.AuthService, statisticsHandler *statistics.Handler, adminUserHandler *admin_auth_handler.AdminUserHandler, roleHandler *admin_auth_handler.RoleHandler, permissionHandler *admin_auth_handler.PermissionHandler, materialHandler *question_handler.MaterialHandler, knowledgeTreeHandler *question_handler.KnowledgeTreeHandler, documentHandler *document_handler.Handler, ) *AdminApp { app := createFiberApp("Admin", cfg) admin.SetupRoutes(app, ossHandler, paymentHandler, schedulerHandler, campCategoryHandler, campHandler, sectionHandler, taskHandler, progressHandler, userCampHandler, orderHandler, questionHandler, paperHandler, answerRecordHandler, materialHandler, knowledgeTreeHandler, documentHandler, authHandler, authService, statisticsHandler, adminUserHandler, roleHandler, permissionHandler) return &AdminApp{App: app} } // NewAPIApp 创建 API 应用 func NewAPIApp( cfg *config.Config, ossHandler *oss.Handler, paymentHandler *payment.Handler, schedulerHandler *scheduler.Handler, campCategoryHandler *handler.CategoryHandler, campHandler *handler.CampHandler, sectionHandler *handler.SectionHandler, taskHandler *handler.TaskHandler, progressHandler *handler.ProgressHandler, userCampHandler *handler.UserCampHandler, orderHandler *order_handler.OrderHandler, questionHandler *question_handler.QuestionHandler, paperHandler *question_handler.PaperHandler, answerRecordHandler *question_handler.AnswerRecordHandler, ) *APIApp { app := createFiberApp("API", cfg) api.SetupRoutes(app, ossHandler, paymentHandler, schedulerHandler, campCategoryHandler, campHandler, sectionHandler, taskHandler, progressHandler, userCampHandler, orderHandler, questionHandler, paperHandler, answerRecordHandler) return &APIApp{App: app} } // createFiberApp 创建 Fiber 应用 func createFiberApp(name string, cfg *config.Config) *fiber.App { app := fiber.New(fiber.Config{ AppName: cfg.Service.Name + " - " + name, Prefork: false, CaseSensitive: false, StrictRouting: false, ReadTimeout: 5 * time.Second, WriteTimeout: 5 * time.Second, IdleTimeout: 60 * time.Second, }) // 中间件 app.Use(recover.New()) app.Use(cors.New(cors.Config{ AllowOrigins: "*", AllowMethods: "GET,POST,PUT,DELETE,OPTIONS", AllowHeaders: "Origin,Content-Type,Accept,Authorization", })) return app } // maskURI 隐藏 URI 中的敏感信息(密码) func maskURI(uri string) string { // 简单的 URI 掩码:隐藏密码部分 // mongodb://username:password@host:port/database // 转换为: mongodb://username:***@host:port/database if len(uri) > 20 { // 查找 @ 符号的位置 atIndex := -1 for i := 0; i < len(uri); i++ { if uri[i] == '@' { atIndex = i break } } if atIndex > 0 { // 查找最后一个 : 在 @ 之前的位置 colonIndex := -1 for i := atIndex - 1; i >= 0; i-- { if uri[i] == ':' { colonIndex = i break } } if colonIndex > 0 { return uri[:colonIndex+1] + "***" + uri[atIndex:] } } } return uri }