This commit is contained in:
xujiang
2025-07-10 18:09:11 +08:00
parent 5cbdc5af73
commit 604b9e59ba
95 changed files with 23709 additions and 19 deletions

View File

@ -0,0 +1,147 @@
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"photography-backend/internal/config"
"photography-backend/internal/database"
"photography-backend/internal/repository/postgres"
"photography-backend/internal/service"
"photography-backend/internal/service/auth"
"photography-backend/internal/api/handlers"
"photography-backend/internal/api/middleware"
"photography-backend/internal/api/routes"
"photography-backend/pkg/logger"
)
func main() {
// 加载配置
cfg, err := config.LoadConfig("configs/config.yaml")
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
// 初始化日志
zapLogger, err := logger.InitLogger(&cfg.Logger)
if err != nil {
log.Fatalf("Failed to initialize logger: %v", err)
}
defer zapLogger.Sync()
// 初始化数据库
db, err := database.New(cfg)
if err != nil {
zapLogger.Fatal("Failed to connect to database", zap.Error(err))
}
defer db.Close()
// 自动迁移数据库
if err := db.AutoMigrate(); err != nil {
zapLogger.Fatal("Failed to migrate database", zap.Error(err))
}
// 填充种子数据
if err := db.Seed(); err != nil {
zapLogger.Warn("Failed to seed database", zap.Error(err))
}
// 初始化仓库
userRepo := postgres.NewUserRepository(db.GetDB())
photoRepo := postgres.NewPhotoRepository(db.GetDB())
categoryRepo := postgres.NewCategoryRepository(db.GetDB())
tagRepo := postgres.NewTagRepository(db.GetDB())
// 初始化服务
jwtService := auth.NewJWTService(&cfg.JWT)
authService := auth.NewAuthService(userRepo, jwtService)
photoService := service.NewPhotoService(photoRepo)
categoryService := service.NewCategoryService(categoryRepo)
tagService := service.NewTagService(tagRepo)
userService := service.NewUserService(userRepo)
// 初始化处理器
authHandler := handlers.NewAuthHandler(authService)
photoHandler := handlers.NewPhotoHandler(photoService)
categoryHandler := handlers.NewCategoryHandler(categoryService)
tagHandler := handlers.NewTagHandler(tagService)
userHandler := handlers.NewUserHandler(userService)
// 初始化中间件
authMiddleware := middleware.NewAuthMiddleware(jwtService)
// 设置Gin模式
if cfg.IsProduction() {
gin.SetMode(gin.ReleaseMode)
}
// 创建Gin引擎
r := gin.New()
// 添加中间件
r.Use(middleware.RequestIDMiddleware())
r.Use(middleware.LoggerMiddleware(zapLogger))
r.Use(middleware.CORSMiddleware(&cfg.CORS))
r.Use(gin.Recovery())
// 健康检查
r.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"timestamp": time.Now().Unix(),
"version": cfg.App.Version,
})
})
// 设置路由
routes.SetupRoutes(r, &routes.Handlers{
AuthHandler: authHandler,
PhotoHandler: photoHandler,
CategoryHandler: categoryHandler,
TagHandler: tagHandler,
UserHandler: userHandler,
}, authMiddleware, zapLogger)
// 创建HTTP服务器
server := &http.Server{
Addr: cfg.GetServerAddr(),
Handler: r,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
// 启动服务器
go func() {
zapLogger.Info("Starting server", zap.String("addr", server.Addr))
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
zapLogger.Fatal("Failed to start server", zap.Error(err))
}
}()
// 等待中断信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
zapLogger.Info("Shutting down server...")
// 优雅关闭
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
zapLogger.Fatal("Server forced to shutdown", zap.Error(err))
}
zapLogger.Info("Server exited")
}