Files
QWQLwToo 079ee4eaeb
build-winui / winui (push) Has been cancelled
Add server components
2026-06-26 13:28:09 +08:00

220 lines
6.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
})
}