Add SQLite support and install page
This commit is contained in:
+75
-4
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -38,8 +39,23 @@ func main() {
|
||||
}
|
||||
defer logger.Sync()
|
||||
|
||||
// 检查是否已安装
|
||||
if !cfg.Install.Installed {
|
||||
logger.Info("系统未安装,启动安装模式")
|
||||
startInstallMode(cfg, logger)
|
||||
return
|
||||
}
|
||||
|
||||
// 连接数据库
|
||||
db, err := gorm.Open(postgres.Open(cfg.Database.DSN()), &gorm.Config{})
|
||||
var db *gorm.DB
|
||||
if cfg.Database.Type == "sqlite" {
|
||||
// SQLite 连接
|
||||
db, err = gorm.Open(sqlite.Open(cfg.Database.DSN()), &gorm.Config{})
|
||||
} else {
|
||||
// PostgreSQL 连接
|
||||
db, err = gorm.Open(postgres.Open(cfg.Database.DSN()), &gorm.Config{})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Fatal("连接数据库失败", zap.Error(err))
|
||||
}
|
||||
@@ -53,6 +69,7 @@ func main() {
|
||||
&models.IPChangeLog{},
|
||||
&models.ConnectionLog{},
|
||||
&models.IPRefreshRule{},
|
||||
&models.InstallStatus{},
|
||||
); err != nil {
|
||||
logger.Fatal("数据库迁移失败", zap.Error(err))
|
||||
}
|
||||
@@ -100,7 +117,7 @@ func main() {
|
||||
go startHealthCheck(ctx, repos.Node, healthChecker, logger, time.Duration(cfg.Scheduler.HealthCheckInterval)*time.Second)
|
||||
|
||||
// 启动 API 服务器
|
||||
apiServer := NewAPIServer(cfg, repos, logger)
|
||||
apiServer := NewAPIServer(cfg, repos, db, logger)
|
||||
go func() {
|
||||
if err := apiServer.Start(); err != nil && err != http.ErrServerClosed {
|
||||
logger.Error("API 服务器错误", zap.Error(err))
|
||||
@@ -128,6 +145,51 @@ func main() {
|
||||
logger.Info("服务器已关闭")
|
||||
}
|
||||
|
||||
// startInstallMode 启动安装模式
|
||||
func startInstallMode(cfg *config.Config, logger *zap.Logger) {
|
||||
gin.SetMode("release")
|
||||
router := gin.New()
|
||||
router.Use(gin.Recovery())
|
||||
|
||||
// 安装相关路由
|
||||
api := router.Group("/api/v1")
|
||||
{
|
||||
api.GET("/install/check", handler.CheckInstall())
|
||||
api.POST("/install", handler.DoInstall(logger))
|
||||
api.GET("/install/status", handler.GetInstallStatus(nil))
|
||||
}
|
||||
|
||||
// 静态文件服务(前端)
|
||||
router.Static("/assets", "web/dist/assets")
|
||||
router.StaticFile("/", "web/dist/index.html")
|
||||
router.StaticFile("/favicon.ico", "web/dist/favicon.ico")
|
||||
|
||||
// 前端路由回退
|
||||
router.NoRoute(func(c *gin.Context) {
|
||||
c.File("web/dist/index.html")
|
||||
})
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port),
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
logger.Info("安装模式启动", zap.String("addr", server.Addr))
|
||||
|
||||
// 等待中断信号
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
go func() {
|
||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
logger.Error("服务器错误", zap.Error(err))
|
||||
}
|
||||
}()
|
||||
|
||||
<-quit
|
||||
logger.Info("安装模式关闭")
|
||||
}
|
||||
|
||||
// SimpleAuthenticator 简单认证器
|
||||
type SimpleAuthenticator struct {
|
||||
userRepo *repository.UserRepository
|
||||
@@ -253,18 +315,20 @@ func startHealthCheck(ctx context.Context, nodeRepo *repository.NodeRepository,
|
||||
type APIServer struct {
|
||||
cfg *config.Config
|
||||
repos *repository.Repositories
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
server *http.Server
|
||||
router *gin.Engine
|
||||
}
|
||||
|
||||
func NewAPIServer(cfg *config.Config, repos *repository.Repositories, logger *zap.Logger) *APIServer {
|
||||
func NewAPIServer(cfg *config.Config, repos *repository.Repositories, db *gorm.DB, logger *zap.Logger) *APIServer {
|
||||
gin.SetMode(cfg.Server.Mode)
|
||||
router := gin.New()
|
||||
|
||||
server := &APIServer{
|
||||
cfg: cfg,
|
||||
repos: repos,
|
||||
db: db,
|
||||
logger: logger,
|
||||
router: router,
|
||||
server: &http.Server{
|
||||
@@ -288,6 +352,13 @@ func (s *APIServer) setupRoutes() {
|
||||
// API 路由组
|
||||
api := s.router.Group("/api/v1")
|
||||
{
|
||||
// 安装相关
|
||||
install := api.Group("/install")
|
||||
{
|
||||
install.GET("/check", handler.CheckInstall())
|
||||
install.GET("/status", handler.GetInstallStatus(s.db))
|
||||
}
|
||||
|
||||
// 用户相关
|
||||
users := api.Group("/users")
|
||||
{
|
||||
@@ -342,4 +413,4 @@ func (s *APIServer) Start() error {
|
||||
|
||||
func (s *APIServer) Shutdown(ctx context.Context) {
|
||||
s.server.Shutdown(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user