892 lines
27 KiB
Go
892 lines
27 KiB
Go
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
|
||
}
|