feat: 添加安装向导功能
- 后端:安装状态检测API、数据库连接测试、配置文件生成 - 后端:支持SQLite/MySQL数据库选择 - 后端:JWT密钥自动生成或手动设置 - 前端:安装向导界面(数据库配置、安全配置、管理员账号) - 前端:路由守卫检测安装状态,未安装自动跳转安装页面
This commit is contained in:
@@ -30,15 +30,92 @@ var (
|
||||
RDB *redis.Client
|
||||
)
|
||||
|
||||
// Init 初始化数据库连接
|
||||
func Init() {
|
||||
initMySQL()
|
||||
initDatabase()
|
||||
initRedis()
|
||||
}
|
||||
|
||||
// initMySQL 初始化MySQL连接
|
||||
func initMySQL() {
|
||||
// 尝试连接MySQL
|
||||
func initDatabase() {
|
||||
dbType := config.GetString("database.type")
|
||||
if dbType == "" {
|
||||
dbType = "auto"
|
||||
}
|
||||
|
||||
switch dbType {
|
||||
case "sqlite":
|
||||
initSQLite()
|
||||
case "mysql":
|
||||
initMySQLExplicit()
|
||||
default:
|
||||
initAutoDetect()
|
||||
}
|
||||
}
|
||||
|
||||
func initSQLite() {
|
||||
dbPath := "verification_platform.db"
|
||||
absPath, err := filepath.Abs(dbPath)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get absolute path:", err.Error())
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err == nil && filepath.Base(wd) == "cmd" {
|
||||
absPath = filepath.Join(filepath.Dir(wd), "verification_platform.db")
|
||||
}
|
||||
|
||||
var errOpen error
|
||||
DB, errOpen = gorm.Open(sqlite.Open(absPath), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
if errOpen != nil {
|
||||
log.Fatal("Failed to create SQLite database:", errOpen.Error())
|
||||
}
|
||||
log.Printf("Using SQLite database: %s\n", absPath)
|
||||
|
||||
if sqlDB, err := DB.DB(); err == nil {
|
||||
sqlDB.SetMaxIdleConns(10)
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
}
|
||||
|
||||
runMigrations()
|
||||
}
|
||||
|
||||
func initMySQLExplicit() {
|
||||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local",
|
||||
config.GetString("database.username"),
|
||||
config.GetString("database.password"),
|
||||
config.GetString("database.host"),
|
||||
config.GetString("database.port"),
|
||||
config.GetString("database.name"),
|
||||
config.GetString("database.charset"),
|
||||
)
|
||||
|
||||
var err error
|
||||
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to MySQL:", err.Error())
|
||||
}
|
||||
log.Printf("Connected to MySQL: %s@%s:%s/%s\n",
|
||||
config.GetString("database.username"),
|
||||
config.GetString("database.host"),
|
||||
config.GetString("database.port"),
|
||||
config.GetString("database.name"))
|
||||
|
||||
if sqlDB, err := DB.DB(); err == nil {
|
||||
sqlDB.SetMaxIdleConns(config.GetInt("database.max_idle_conns"))
|
||||
sqlDB.SetMaxOpenConns(config.GetInt("database.max_open_conns"))
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
}
|
||||
|
||||
runMigrations()
|
||||
}
|
||||
|
||||
func initAutoDetect() {
|
||||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local",
|
||||
config.GetString("database.username"),
|
||||
config.GetString("database.password"),
|
||||
@@ -54,28 +131,18 @@ func initMySQL() {
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
|
||||
// 如果MySQL连接失败,创建一个SQLite数据库用于开发
|
||||
if err != nil {
|
||||
log.Println("Failed to connect to MySQL, using SQLite database for development:", err.Error())
|
||||
|
||||
log.Println("Using file database for development")
|
||||
|
||||
dbPath := "verification_platform.db"
|
||||
|
||||
absPath, err := filepath.Abs(dbPath)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get absolute path:", err.Error())
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get working directory:", err.Error())
|
||||
}
|
||||
log.Printf("Working directory: %s, basename: %s\n", wd, filepath.Base(wd))
|
||||
|
||||
if filepath.Base(wd) == "cmd" {
|
||||
dbPath = filepath.Join(filepath.Dir(wd), "verification_platform.db")
|
||||
absPath = dbPath
|
||||
if err == nil && filepath.Base(wd) == "cmd" {
|
||||
absPath = filepath.Join(filepath.Dir(wd), "verification_platform.db")
|
||||
}
|
||||
|
||||
DB, err = gorm.Open(sqlite.Open(absPath), &gorm.Config{
|
||||
@@ -88,14 +155,16 @@ func initMySQL() {
|
||||
log.Printf("Database file path: %s\n", absPath)
|
||||
}
|
||||
|
||||
// 设置连接池(仅对非内存数据库有效)
|
||||
if sqlDB, err := DB.DB(); err == nil {
|
||||
sqlDB.SetMaxIdleConns(config.GetInt("database.max_idle_conns"))
|
||||
sqlDB.SetMaxOpenConns(config.GetInt("database.max_open_conns"))
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
}
|
||||
|
||||
// 检查applications表结构
|
||||
runMigrations()
|
||||
}
|
||||
|
||||
func runMigrations() {
|
||||
var columns []struct {
|
||||
CID int
|
||||
Name string
|
||||
@@ -126,7 +195,7 @@ func initMySQL() {
|
||||
}
|
||||
|
||||
// 自动迁移数据库表
|
||||
err = DB.AutoMigrate(
|
||||
if err := DB.AutoMigrate(
|
||||
&model.User{},
|
||||
&model.AppUser{},
|
||||
&model.UserLevel{},
|
||||
@@ -180,8 +249,7 @@ func initMySQL() {
|
||||
&model.EmailTemplate{},
|
||||
&model.VersionFile{},
|
||||
&model.CloudVariableRecord{},
|
||||
)
|
||||
if err != nil {
|
||||
); err != nil {
|
||||
log.Println("Failed to migrate database:", err.Error())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user