package controllers import ( "encoding/json" "fmt" "shudao-chat-go/models" "shudao-chat-go/utils" "github.com/beego/beego/v2/server/web" "golang.org/x/crypto/bcrypt" ) // LocalAuthController 本地认证控制器 type LocalAuthController struct { web.Controller } // LocalLoginRequest 本地登录请求结构 type LocalLoginRequest struct { Username string `json:"username"` Password string `json:"password"` } // LocalLoginResponse 本地登录响应结构 type LocalLoginResponse struct { StatusCode int `json:"statusCode"` Msg string `json:"msg"` Token string `json:"token,omitempty"` UserInfo *LocalUserInfo `json:"userInfo,omitempty"` } // LocalUserInfo 本地用户信息 type LocalUserInfo struct { ID uint `json:"id"` Username string `json:"username"` Nickname string `json:"nickname"` Role string `json:"role"` Email string `json:"email"` } // LocalLogin 本地登录接口 func (c *LocalAuthController) LocalLogin() { // 检查是否启用本地登录 enableLocalLogin, err := web.AppConfig.Bool("enable_local_login") if err != nil || !enableLocalLogin { c.Data["json"] = LocalLoginResponse{ StatusCode: 403, Msg: "本地登录功能未启用", } c.ServeJSON() return } // 解析请求体 var req LocalLoginRequest if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil { c.Data["json"] = LocalLoginResponse{ StatusCode: 400, Msg: "请求参数解析失败", } c.ServeJSON() return } // 验证必填字段 if req.Username == "" || req.Password == "" { c.Data["json"] = LocalLoginResponse{ StatusCode: 400, Msg: "用户名和密码不能为空", } c.ServeJSON() return } fmt.Printf("🔐 [本地登录] 用户 %s 尝试登录\n", req.Username) // 查询用户 var user models.User result := models.DB.Where("username = ? AND is_deleted = 0", req.Username).First(&user) if result.Error != nil { fmt.Printf("❌ [本地登录] 用户不存在: %s\n", req.Username) c.Data["json"] = LocalLoginResponse{ StatusCode: 401, Msg: "用户名或密码错误", } c.ServeJSON() return } // 检查用户状态 if user.Status != 1 { fmt.Printf("❌ [本地登录] 用户已被禁用: %s\n", req.Username) c.Data["json"] = LocalLoginResponse{ StatusCode: 403, Msg: "用户已被禁用", } c.ServeJSON() return } // 验证密码 err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)) if err != nil { fmt.Printf("❌ [本地登录] 密码错误: %s\n", req.Username) c.Data["json"] = LocalLoginResponse{ StatusCode: 401, Msg: "用户名或密码错误", } c.ServeJSON() return } // 生成本地token token, err := utils.GenerateLocalToken(user.ID, user.Username, user.Role) if err != nil { fmt.Printf("❌ [本地登录] 生成token失败: %v\n", err) c.Data["json"] = LocalLoginResponse{ StatusCode: 500, Msg: "生成token失败", } c.ServeJSON() return } fmt.Printf("✅ [本地登录] 用户 %s 登录成功\n", req.Username) // 返回成功响应 c.Data["json"] = LocalLoginResponse{ StatusCode: 200, Msg: "登录成功", Token: token, UserInfo: &LocalUserInfo{ ID: user.ID, Username: user.Username, Nickname: user.Nickname, Role: user.Role, Email: user.Email, }, } c.ServeJSON() }