/* Package main 是 Go LDAP Admin 项目的主入口文件 Go LDAP Admin 是一个基于 Go + Vue 实现的 OpenLDAP 后台管理系统, 旨在为 OpenLDAP 服务端提供一个简单易用、清晰美观的现代化管理后台。 主要功能: - 用户管理:支持用户的增删改查,密码管理等 - 组织架构管理:支持部门/组的层级管理 - 权限控制:基于 RBAC 的角色权限管理 - LDAP 集成:与 OpenLDAP 服务器双向同步 - 企业 IM 集成:支持钉钉、企业微信、飞书等平台同步 - 操作审计:完整的操作日志记录 技术栈: - Web 框架:Gin - ORM:GORM - 数据库:MySQL/SQLite - 权限控制:Casbin - LDAP 客户端:go-ldap - 认证:JWT */ package main import ( "context" "fmt" "net/http" "os" "os/signal" "time" "github.com/eryajf/go-ldap-admin/logic" "github.com/eryajf/go-ldap-admin/config" "github.com/eryajf/go-ldap-admin/middleware" "github.com/eryajf/go-ldap-admin/public/common" "github.com/eryajf/go-ldap-admin/routes" "github.com/eryajf/go-ldap-admin/service/isql" ) // Swagger API 文档配置 // @title Go Ldap Admin // @version 1.0 // @description 基于Go+Vue实现的openLDAP后台管理项目 // @termsOfService https://github.com/eryajf/go-ldap-admin // @contact.name 项目作者:二丫讲梵 、 swagger作者:南宫乘风 // @contact.url https://github.com/eryajf/go-ldap-admin // @contact.email https://github.com/eryajf/go-ldap-admin // @host 127.0.0.1:8888 // @BasePath /api // @securityDefinitions.apikey ApiKeyAuth // @in header // @name Authorization // main 函数是程序的入口点,负责初始化各个组件并启动 HTTP 服务器 func main() { // ==================== 系统初始化阶段 ==================== // 1. 加载配置文件到全局配置结构体 // 从 config.yml 文件中读取系统配置,包括数据库、LDAP、JWT 等配置信息 config.InitConfig() // 2. 初始化日志系统 // 配置 zap 日志库,设置日志级别、输出格式、文件轮转等 common.InitLogger() // 3. 初始化数据库连接 // 根据配置连接 MySQL 或 SQLite 数据库,建立连接池 common.InitDB() // 4. 初始化 LDAP 连接 // 建立与 OpenLDAP 服务器的连接池,用于用户认证和数据同步 common.InitLDAP() // 5. 初始化 Casbin 策略管理器 // 加载 RBAC 权限模型,用于接口级别的权限控制 common.InitCasbinEnforcer() // 6. 初始化数据校验器 // 配置 gin 的数据校验器,用于请求参数验证 common.InitValidate() // 7. 初始化基础数据 // 如果是首次启动,会创建默认的管理员账户、角色、菜单等基础数据 common.InitData() // ==================== 后台服务启动 ==================== // 启动操作日志处理协程 // 操作日志中间件将日志发送到 channel 中,这里启动 3 个 goroutine // 异步处理 channel 中的日志并写入数据库,提高系统性能 for i := 0; i < 3; i++ { go isql.OperationLog.SaveOperationLogChannel(middleware.OperationLogChan) } // ==================== HTTP 服务器配置 ==================== // 注册所有路由 // 包括用户管理、组织架构、权限管理、系统管理等所有 API 路由 r := routes.InitRoutes() // 配置服务器监听地址和端口 host := "0.0.0.0" // 监听所有网络接口 port := config.Conf.System.Port // 从配置文件读取端口号 // 创建 HTTP 服务器实例 srv := &http.Server{ Addr: fmt.Sprintf("%s:%d", host, port), Handler: r, } // ==================== 服务器启动 ==================== // 在单独的 goroutine 中启动 HTTP 服务器 // 这样不会阻塞后续的优雅关闭处理逻辑 go func() { if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { common.Log.Fatalf("HTTP 服务器启动失败: %s\n", err) } }() // 启动定时任务调度器 // 用于执行企业 IM 同步、数据清理等定时任务 logic.InitCron() // 输出服务器启动成功信息 common.Log.Info(fmt.Sprintf("🚀 Go LDAP Admin 服务器启动成功! 访问地址: http://%s:%d", host, port)) // ==================== 优雅关闭处理 ==================== // 创建信号接收通道,用于接收系统关闭信号 quit := make(chan os.Signal, 1) // 注册信号处理 // kill (无参数) 默认发送 syscall.SIGTERM 信号 // kill -2 发送 syscall.SIGINT 信号 (Ctrl+C) // kill -9 发送 syscall.SIGKILL 信号,但无法被捕获,所以不需要处理 signal.Notify(quit, os.Interrupt) // 阻塞等待关闭信号 <-quit common.Log.Info("🛑 接收到关闭信号,开始优雅关闭服务器...") // 创建带超时的上下文,给服务器 5 秒时间完成当前正在处理的请求 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 优雅关闭服务器 if err := srv.Shutdown(ctx); err != nil { common.Log.Fatal("❌ 服务器强制关闭:", err) } common.Log.Info("✅ 服务器已安全退出!") }