Add server components
build-winui / winui (push) Has been cancelled

This commit is contained in:
QWQLwToo
2026-06-26 13:28:09 +08:00
parent 7ecc6a8923
commit 079ee4eaeb
168 changed files with 37475 additions and 0 deletions
+263
View File
@@ -0,0 +1,263 @@
package handlers
import (
"fmt"
"net/http"
"software-download-center/database"
"software-download-center/models"
"software-download-center/utils"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// RegisterRequest 注册请求
type RegisterRequest struct {
Username string `json:"username" binding:"required,min=3,max=50"`
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=8"`
}
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
// Register 用户注册
func Register(c *gin.Context) {
var req RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "请求参数错误: " + err.Error(),
})
return
}
// 验证密码强度
if err := utils.ValidatePasswordStrength(req.Password); err != nil {
AddLog("WARN", fmt.Sprintf("注册失败(密码强度不足): 用户名=%s, IP=%s", req.Username, c.ClientIP()))
c.JSON(http.StatusBadRequest, gin.H{
"error": err.Error(),
})
return
}
// 检查用户名是否已存在
var existingUser models.User
if err := database.DB.Where("username = ?", req.Username).First(&existingUser).Error; err == nil {
AddLog("WARN", fmt.Sprintf("注册失败(用户名已存在): 用户名=%s, IP=%s", req.Username, c.ClientIP()))
c.JSON(http.StatusConflict, gin.H{
"error": "用户名已存在",
})
return
}
// 检查邮箱是否已存在
if err := database.DB.Where("email = ?", req.Email).First(&existingUser).Error; err == nil {
AddLog("WARN", fmt.Sprintf("注册失败(邮箱已被注册): 邮箱=%s, IP=%s", req.Email, c.ClientIP()))
c.JSON(http.StatusConflict, gin.H{
"error": "邮箱已被注册",
})
return
}
// 检查是否是第一个用户(自动成为管理员)
var userCount int64
database.DB.Model(&models.User{}).Count(&userCount)
isAdmin := userCount == 0
// 加密密码
hashedPassword, err := utils.HashPassword(req.Password)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "密码加密失败",
})
return
}
// 创建用户
user := models.User{
Username: req.Username,
Email: req.Email,
Password: hashedPassword,
IsAdmin: isAdmin,
IsActive: true,
}
if err := database.DB.Create(&user).Error; err != nil {
AddLog("ERROR", fmt.Sprintf("创建用户数据库错误: 用户名=%s - %s, IP=%s", req.Username, err.Error(), c.ClientIP()))
c.JSON(http.StatusInternalServerError, gin.H{
"error": "创建用户失败",
})
return
}
AddLog("INFO", fmt.Sprintf("用户注册成功: 用户名=%s, 邮箱=%s, 管理员=%v, IP=%s", user.Username, user.Email, user.IsAdmin, c.ClientIP()))
// 生成 token
token, err := utils.GenerateToken(user.ID, user.Username, user.IsAdmin)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "生成 token 失败",
})
return
}
// 设置 cookie
c.SetCookie("token", token, 24*3600, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{
"message": "注册成功",
"token": token,
"user": gin.H{
"id": user.ID,
"username": user.Username,
"email": user.Email,
"is_admin": user.IsAdmin,
},
})
}
// Login 用户登录
func Login(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": "请求参数错误",
})
return
}
// 检查数据库是否已初始化
if !database.IsDBInitialized() {
// 使用默认管理员账号
if req.Username == "admin" && req.Password == "admin123456" {
// 生成临时 token(用于安装页面)
token, err := utils.GenerateToken(0, "admin", true)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "生成 token 失败",
})
return
}
AddLog("INFO", fmt.Sprintf("默认管理员登录成功: 用户名=%s, IP=%s", req.Username, c.ClientIP()))
c.SetCookie("token", token, 24*3600, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{
"message": "登录成功,请配置数据库",
"token": token,
"user": gin.H{
"id": 0,
"username": "admin",
"is_admin": true,
"is_setup": false, // 标记需要安装
},
})
return
}
c.JSON(http.StatusUnauthorized, gin.H{
"error": "数据库未初始化,请使用默认管理员账号登录(admin/admin123456",
})
return
}
// 查找用户
var user models.User
if err := database.DB.Where("username = ?", req.Username).First(&user).Error; err != nil {
if err == gorm.ErrRecordNotFound {
AddLog("WARN", fmt.Sprintf("登录失败(用户不存在): 用户名=%s, IP=%s", req.Username, c.ClientIP()))
c.JSON(http.StatusUnauthorized, gin.H{
"error": "用户名或密码错误",
})
return
}
AddLog("ERROR", fmt.Sprintf("查询用户失败: 用户名=%s - %s, IP=%s", req.Username, err.Error(), c.ClientIP()))
c.JSON(http.StatusInternalServerError, gin.H{
"error": "查询用户失败",
})
return
}
// 检查用户是否激活
if !user.IsActive {
AddLog("WARN", fmt.Sprintf("登录失败(账户已禁用): 用户名=%s, IP=%s", req.Username, c.ClientIP()))
c.JSON(http.StatusForbidden, gin.H{
"error": "账户已被禁用",
})
return
}
// 验证密码
if !utils.CheckPassword(req.Password, user.Password) {
AddLog("WARN", fmt.Sprintf("登录失败(密码错误): 用户名=%s, IP=%s", req.Username, c.ClientIP()))
c.JSON(http.StatusUnauthorized, gin.H{
"error": "用户名或密码错误",
})
return
}
AddLog("INFO", fmt.Sprintf("用户登录成功: 用户名=%s, 管理员=%v, IP=%s", user.Username, user.IsAdmin, c.ClientIP()))
// 生成 token
token, err := utils.GenerateToken(user.ID, user.Username, user.IsAdmin)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "生成 token 失败",
})
return
}
// 设置 cookie
c.SetCookie("token", token, 24*3600, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{
"message": "登录成功",
"token": token,
"user": gin.H{
"id": user.ID,
"username": user.Username,
"email": user.Email,
"is_admin": user.IsAdmin,
},
})
}
// Logout 用户登出
func Logout(c *gin.Context) {
c.SetCookie("token", "", -1, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{
"message": "登出成功",
})
}
// GetCurrentUser 获取当前用户信息
func GetCurrentUser(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{
"error": "未授权",
})
return
}
var user models.User
if err := database.DB.First(&user, userID).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{
"error": "用户不存在",
})
return
}
c.JSON(http.StatusOK, gin.H{
"user": gin.H{
"id": user.ID,
"username": user.Username,
"email": user.Email,
"is_admin": user.IsAdmin,
"is_active": user.IsActive,
},
})
}