package handlers import ( "log" "net/http" "tonav-go/database" "tonav-go/models" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" ) // LoginHandler 处理登录请求 func LoginHandler(c *gin.Context) { var input struct { Username string `form:"username" binding:"required"` Password string `form:"password" binding:"required"` } if err := c.ShouldBind(&input); err != nil { c.HTML(http.StatusOK, "login.html", gin.H{"error": "用户名和密码不能为空"}) return } var user models.User if err := database.DB.Where("username = ?", input.Username).First(&user).Error; err != nil { c.HTML(http.StatusOK, "login.html", gin.H{"error": "用户名或密码错误"}) return } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.Password)); err != nil { c.HTML(http.StatusOK, "login.html", gin.H{"error": "用户名或密码错误"}) return } session := sessions.Default(c) session.Set("user_id", int(user.ID)) session.Set("username", user.Username) session.Set("must_change", user.MustChangePassword) if err := session.Save(); err != nil { log.Printf("Session save error: %v", err) c.HTML(http.StatusOK, "login.html", gin.H{"error": "登录失败,请重试"}) return } if user.MustChangePassword { c.Redirect(http.StatusFound, "/admin/change-password") return } c.Redirect(http.StatusFound, "/admin/dashboard") } // LogoutHandler 处理退出登录 func LogoutHandler(c *gin.Context) { session := sessions.Default(c) session.Clear() session.Save() c.Redirect(http.StatusFound, "/admin/login") } // ChangePasswordHandler 修改密码 func ChangePasswordHandler(c *gin.Context) { if c.Request.Method == "GET" { c.HTML(http.StatusOK, "change_password.html", nil) return } var input struct { OldPassword string `form:"old_password" binding:"required"` NewPassword string `form:"new_password" binding:"required"` ConfirmPassword string `form:"confirm_password" binding:"required"` } if err := c.ShouldBind(&input); err != nil { c.HTML(http.StatusOK, "change_password.html", gin.H{"error": "所有字段均为必填"}) return } if input.NewPassword != input.ConfirmPassword { c.HTML(http.StatusOK, "change_password.html", gin.H{"error": "两次输入的新密码不一致"}) return } if len(input.NewPassword) < 6 { c.HTML(http.StatusOK, "change_password.html", gin.H{"error": "新密码长度不能少于6位"}) return } session := sessions.Default(c) userID, err := getSessionUserID(session) if err != nil { c.Redirect(http.StatusFound, "/admin/login") return } var user models.User if err := database.DB.First(&user, userID).Error; err != nil { c.HTML(http.StatusOK, "change_password.html", gin.H{"error": "用户不存在"}) return } if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(input.OldPassword)); err != nil { c.HTML(http.StatusOK, "change_password.html", gin.H{"error": "旧密码错误"}) return } hashedPassword, err := bcrypt.GenerateFromPassword([]byte(input.NewPassword), bcrypt.DefaultCost) if err != nil { c.HTML(http.StatusOK, "change_password.html", gin.H{"error": "密码加密失败"}) return } user.Password = string(hashedPassword) user.MustChangePassword = false database.DB.Save(&user) session.Set("must_change", false) session.Save() c.Redirect(http.StatusFound, "/admin/dashboard") }