158 lines
5.0 KiB
Go
158 lines
5.0 KiB
Go
/*
|
||
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("✅ 服务器已安全退出!")
|
||
}
|