Files
xujiang 72414d0979 feat: 完成后端-管理后台集成及部署配置
🚀 主要功能:
- 完善后端API服务层,实现完整的CRUD操作
- 开发管理后台所有核心页面 (仪表板、照片、分类、标签、用户、设置)
- 完成前后端完全集成,所有API接口正常对接
- 配置完整的CI/CD流水线,支持自动化部署

🎯 后端完善:
- 实现PhotoService, CategoryService, TagService, UserService
- 添加完整的API处理器和路由配置
- 支持Docker容器化部署
- 添加数据库迁移和健康检查

🎨 管理后台完成:
- 仪表板: 实时统计数据展示
- 照片管理: 完整的CRUD操作,支持批量处理
- 分类管理: 树形结构展示和管理
- 标签管理: 颜色标签和统计信息
- 用户管理: 角色权限控制
- 系统设置: 多标签配置界面
- 添加pre-commit代码质量检查

🔧 部署配置:
- Docker Compose完整配置
- 后端CI/CD流水线 (Docker部署)
- 管理后台CI/CD流水线 (静态文件部署)
- 前端CI/CD流水线优化
- 自动化脚本: 部署、备份、监控
- 完整的部署文档和运维指南

 集成完成:
- 所有API接口正常连接
- 认证系统完整集成
- 数据获取和状态管理
- 错误处理和用户反馈
- 响应式设计优化
2025-07-09 16:23:18 +08:00

141 lines
3.6 KiB
Go

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/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 := postgres.NewDatabase(&cfg.Database)
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))
}
// 初始化仓库
userRepo := postgres.NewUserRepository(db.DB)
photoRepo := postgres.NewPhotoRepository(db.DB)
categoryRepo := postgres.NewCategoryRepository(db.DB)
tagRepo := postgres.NewTagRepository(db.DB)
// 初始化服务
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{
Auth: authHandler,
Photo: photoHandler,
Category: categoryHandler,
Tag: tagHandler,
User: userHandler,
}, authMiddleware)
// 创建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")
}