package handlers import ( "fmt" "net/http" "strings" "software-download-center/database" "software-download-center/utils" "github.com/gin-gonic/gin" ) // GetDatabaseInfo 获取数据库信息 func GetDatabaseInfo(c *gin.Context) { dbType := database.GetDBType() osInfo := utils.GetOSInfo() var dbInfo gin.H if dbType == "mysql" { dbInfo = gin.H{ "type": "MySQL", "status": "connected", } } else { dbInfo = gin.H{ "type": "SQLite", "status": "connected", "file": "data/app.db", "cgo_support": osInfo.IsCGO, } } c.JSON(http.StatusOK, gin.H{ "database": dbInfo, "os": gin.H{ "os": osInfo.OS, "arch": osInfo.Arch, }, }) } // ConvertDatabaseRequest 数据库转换请求 type ConvertDatabaseRequest struct { TargetType string `json:"target_type" binding:"required,oneof=sqlite mysql"` } // ConvertDatabase 转换数据库 func ConvertDatabase(c *gin.Context) { var req ConvertDatabaseRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "请求参数错误: " + err.Error(), }) return } logger := utils.NewLogger() if err := database.ConvertDatabase(req.TargetType, logger); err != nil { AddLog("ERROR", fmt.Sprintf("数据库转换失败: %s", err.Error())) c.JSON(http.StatusInternalServerError, gin.H{ "error": "数据库转换失败: " + err.Error(), }) return } AddLog("INFO", fmt.Sprintf("数据库转换成功: %s", req.TargetType)) c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("数据库已成功转换为 %s", strings.ToUpper(req.TargetType)), "type": req.TargetType, }) } // UpdateDatabasePasswordRequest 更新数据库密码请求 type UpdateDatabasePasswordRequest struct { CurrentPassword string `json:"current_password" binding:"required"` NewPassword string `json:"new_password" binding:"required,min=1"` ConfirmPassword string `json:"confirm_password" binding:"required"` } // UpdateDatabasePassword 更新数据库 root 密码 func UpdateDatabasePassword(c *gin.Context) { var req UpdateDatabasePasswordRequest if err := c.ShouldBindJSON(&req); err != nil { AddLog("WARN", fmt.Sprintf("更新数据库密码请求参数错误: %s (IP: %s)", err.Error(), c.ClientIP())) c.JSON(http.StatusBadRequest, gin.H{ "error": "请求参数错误: " + err.Error(), }) return } // 验证新密码和确认密码是否一致 if req.NewPassword != req.ConfirmPassword { AddLog("WARN", fmt.Sprintf("更新数据库密码失败(密码不一致)(IP: %s)", c.ClientIP())) c.JSON(http.StatusBadRequest, gin.H{ "error": "新密码和确认密码不一致", }) return } // 检查当前数据库类型 dbType := database.GetDBType() if dbType != "mysql" { AddLog("WARN", fmt.Sprintf("更新数据库密码失败(当前数据库不是 MySQL)(IP: %s)", c.ClientIP())) c.JSON(http.StatusBadRequest, gin.H{ "error": "当前数据库类型不是 MySQL,无法修改密码", }) return } // 验证当前密码 if err := database.VerifyMySQLPassword(req.CurrentPassword); err != nil { AddLog("WARN", fmt.Sprintf("更新数据库密码失败(当前密码验证失败)(IP: %s)", c.ClientIP())) c.JSON(http.StatusUnauthorized, gin.H{ "error": "当前密码错误", }) return } // 更新密码 if err := database.UpdateMySQLPassword(req.NewPassword); err != nil { AddLog("ERROR", fmt.Sprintf("更新数据库密码失败: %s (IP: %s)", err.Error(), c.ClientIP())) c.JSON(http.StatusInternalServerError, gin.H{ "error": "更新密码失败: " + err.Error(), }) return } AddLog("INFO", fmt.Sprintf("数据库 root 密码更新成功 (IP: %s)", c.ClientIP())) c.JSON(http.StatusOK, gin.H{ "message": "数据库密码更新成功!请更新环境变量 DB_PASSWORD 并重启服务器以使新密码生效。", }) } // GetDatabaseConfig 获取数据库配置信息(不包含敏感信息) func GetDatabaseConfig(c *gin.Context) { config := database.GetDatabaseConfig() // 隐藏敏感信息 safeConfig := gin.H{ "type": config.Type, "host": config.Host, "port": config.Port, "user": config.User, "database": config.Database, "table_prefix": config.TablePrefix, "has_password": config.Password != "", } c.JSON(http.StatusOK, gin.H{ "config": safeConfig, }) } // UpdateDatabaseConfigRequest 更新数据库配置请求 type UpdateDatabaseConfigRequest struct { Type string `json:"type" binding:"required,oneof=sqlite mysql"` Host string `json:"host"` Port string `json:"port"` User string `json:"user"` Password string `json:"password"` Database string `json:"database"` TablePrefix string `json:"table_prefix"` DSN string `json:"dsn"` } // UpdateDatabaseConfig 更新数据库配置(需要重新连接) func UpdateDatabaseConfig(c *gin.Context) { var req UpdateDatabaseConfigRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "请求参数错误: " + err.Error(), }) return } // 验证必填字段 if req.Type == "mysql" { if req.Host == "" || req.Port == "" || req.User == "" || req.Database == "" { c.JSON(http.StatusBadRequest, gin.H{ "error": "MySQL 配置不完整:需要 host, port, user, database", }) return } } else if req.Type == "sqlite" { if req.DSN == "" { req.DSN = "data" } } // 构建数据库配置 config := &database.DatabaseConfig{ Type: req.Type, Host: req.Host, Port: req.Port, User: req.User, Password: req.Password, Database: req.Database, TablePrefix: req.TablePrefix, DSN: req.DSN, } // 测试连接 if err := database.InitDBWithConfig(config); err != nil { AddLog("ERROR", fmt.Sprintf("数据库配置更新失败: %s (IP: %s)", err.Error(), c.ClientIP())) c.JSON(http.StatusInternalServerError, gin.H{ "error": "数据库连接失败: " + err.Error(), }) return } AddLog("INFO", fmt.Sprintf("数据库配置更新成功: 类型=%s (IP: %s)", req.Type, c.ClientIP())) c.JSON(http.StatusOK, gin.H{ "message": "数据库配置已更新,请重启服务器以应用更改", "type": req.Type, }) }