205 lines
5.0 KiB
Go
205 lines
5.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gateway/config"
|
|
"gateway/models"
|
|
"gateway/utils"
|
|
|
|
"github.com/gin-contrib/sessions"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/jinzhu/gorm"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func GetLogin(c *gin.Context) {
|
|
returnURL := c.Query("return_url")
|
|
c.HTML(http.StatusOK, "login.html", gin.H{
|
|
"return_url": returnURL,
|
|
})
|
|
}
|
|
|
|
func PostLogin(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
username := c.PostForm("username")
|
|
password := c.PostForm("password")
|
|
returnURL := c.PostForm("return_url")
|
|
|
|
var user models.User
|
|
if err := db.Where("mobile = ?", username).First(&user).Error; err != nil {
|
|
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
|
|
"error": "用户不存在或密码错误",
|
|
"return_url": returnURL,
|
|
})
|
|
return
|
|
}
|
|
|
|
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
|
|
c.HTML(http.StatusUnauthorized, "login.html", gin.H{
|
|
"error": "用户不存在或密码错误",
|
|
"return_url": returnURL,
|
|
})
|
|
return
|
|
}
|
|
|
|
session := sessions.Default(c)
|
|
session.Set("user", user.ID)
|
|
if err := session.Save(); err != nil {
|
|
utils.Logger.Errorf("Session保存失败: %v", err)
|
|
c.HTML(http.StatusInternalServerError, "login.html", gin.H{
|
|
"error": "登录状态保存失败",
|
|
"return_url": returnURL,
|
|
})
|
|
return
|
|
}
|
|
|
|
if returnURL != "" {
|
|
c.Redirect(http.StatusSeeOther, returnURL)
|
|
return
|
|
}
|
|
|
|
c.Redirect(http.StatusSeeOther, "/")
|
|
}
|
|
}
|
|
|
|
func GetRegister(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
regions, err := getRegions(db)
|
|
if err != nil {
|
|
c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"})
|
|
return
|
|
}
|
|
c.HTML(http.StatusOK, "register.html", gin.H{"regions": regions})
|
|
}
|
|
}
|
|
|
|
func PostRegister(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
regionStr, exists := c.GetPostForm("region")
|
|
if !exists {
|
|
handleRegisterError(c, db, "请选择所在地区")
|
|
return
|
|
}
|
|
|
|
regionID, err := strconv.ParseUint(regionStr, 10, 32)
|
|
if err != nil {
|
|
handleRegisterError(c, db, "无效的地区参数")
|
|
return
|
|
}
|
|
|
|
user := models.User{
|
|
FullName: c.PostForm("fullname"),
|
|
Mobile: c.PostForm("mobile"),
|
|
RegionID: uint(regionID),
|
|
}
|
|
|
|
var region models.Region
|
|
if err := db.First(®ion, user.RegionID).Error; err != nil {
|
|
handleRegisterError(c, db, "请选择有效地区")
|
|
return
|
|
}
|
|
|
|
if len(user.Mobile) != 11 {
|
|
handleRegisterError(c, db, "手机号格式不正确")
|
|
return
|
|
}
|
|
|
|
password := c.PostForm("password")
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
utils.Logger.Errorf("密码加密失败: %v", err)
|
|
handleRegisterError(c, db, "注册失败")
|
|
return
|
|
}
|
|
user.Password = string(hashedPassword)
|
|
|
|
if err := db.Create(&user).Error; err != nil {
|
|
utils.Logger.Errorf("用户创建失败: %v", err)
|
|
errorMsg := "注册失败"
|
|
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
|
|
errorMsg = "该手机号已注册"
|
|
}
|
|
handleRegisterError(c, db, errorMsg)
|
|
return
|
|
}
|
|
|
|
c.Redirect(http.StatusSeeOther, "/login")
|
|
}
|
|
}
|
|
|
|
func Logout(c *gin.Context) {
|
|
session := sessions.Default(c)
|
|
|
|
// 使用配置中的session选项
|
|
session.Options(config.GetLogoutSessionOptions())
|
|
|
|
// 清除session数据
|
|
session.Clear()
|
|
|
|
// 添加清除缓存的 HTTP 头
|
|
c.Header("Cache-Control", "no-cache, no-store, must-revalidate")
|
|
c.Header("Pragma", "no-cache")
|
|
c.Header("Expires", "0")
|
|
|
|
// 保存更改
|
|
if err := session.Save(); err != nil {
|
|
utils.Logger.Errorf("退出登录失败: %v", err)
|
|
c.HTML(http.StatusInternalServerError, "error.html", gin.H{"error": "退出登录失败"})
|
|
return
|
|
}
|
|
|
|
c.Redirect(http.StatusSeeOther, "/login")
|
|
}
|
|
|
|
func getRegions(db *gorm.DB) ([]models.Region, error) {
|
|
var regions []models.Region
|
|
if err := db.Find(®ions).Error; err != nil {
|
|
utils.Logger.Errorf("获取地区数据失败: %v", err)
|
|
return nil, err
|
|
}
|
|
return regions, nil
|
|
}
|
|
|
|
func handleRegisterError(c *gin.Context, db *gorm.DB, errorMessage string) {
|
|
regions, err := getRegions(db)
|
|
if err != nil {
|
|
c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"})
|
|
return
|
|
}
|
|
c.HTML(http.StatusBadRequest, "register.html", gin.H{
|
|
"error": errorMessage,
|
|
"regions": regions,
|
|
"form": gin.H{
|
|
"fullname": c.PostForm("fullname"),
|
|
"mobile": c.PostForm("mobile"),
|
|
},
|
|
})
|
|
}
|
|
|
|
func GetUserInfo(db *gorm.DB) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
session := sessions.Default(c)
|
|
userID := session.Get("user")
|
|
|
|
if userID == nil {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
|
|
return
|
|
}
|
|
|
|
var user models.User
|
|
if err := db.First(&user, userID).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户信息失败"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"id": user.ID,
|
|
"fullName": user.FullName,
|
|
"mobile": user.Mobile,
|
|
})
|
|
}
|
|
}
|