package admin import ( "fmt" "net/http" "time" "mini-chat/configs" "mini-chat/internal/code" "mini-chat/internal/pkg/core" "mini-chat/internal/pkg/jwtoken" "mini-chat/internal/pkg/utils" "mini-chat/internal/pkg/validation" "mini-chat/internal/proposal" "gorm.io/gorm" ) type loginRequest struct { Username string `json:"username" binding:"required"` // 用户名 Password string `json:"password" binding:"required"` // 密码 (MD5加密后的密码) } type loginResponse struct { Token string `json:"token"` // 登录成功后颁发的 Token } // Login 管理员登录 // @Summary 管理员登录 // @Description 管理员登录 // @Tags 管理端.登录 // @Accept json // @Produce json // @Param RequestBody body loginRequest true "请求参数" // @Success 200 {object} loginResponse // @Failure 400 {object} code.Failure // @Router /admin/login [post] func (h *handler) Login() core.HandlerFunc { return func(ctx core.Context) { req := new(loginRequest) res := new(loginResponse) if err := ctx.ShouldBindJSON(req); err != nil { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.ParamBindError, validation.Error(err)), ) return } // 验证用户是否存在 info, err := h.readDB.Admin.WithContext(ctx.RequestContext()).Where(h.readDB.Admin.Username.Eq(req.Username)).First() if err != nil && err != gorm.ErrRecordNotFound { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.AdminLoginError, fmt.Sprintf("%s: %s", code.Text(code.AdminLoginError), err.Error())), ) return } if err == gorm.ErrRecordNotFound { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.AdminLoginError, fmt.Sprintf("%s: %s", code.Text(code.AdminLoginError), "账号不存在,请联系管理员。")), ) return } // 验证登录状态 if info.LoginStatus != 1 { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.AdminLoginError, fmt.Sprintf("%s:账号已被禁用", code.Text(code.AdminLoginError))), ) return } // 验证密码 if !utils.VerifyAdminHashedPassword(info.Password, req.Password) { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.AdminLoginError, fmt.Sprintf("%s:用户名或密码错误,请联系管理员。", code.Text(code.AdminLoginError))), ) return } // 设置 Session 信息 sessionUserInfo := proposal.SessionUserInfo{ Id: info.ID, UserName: info.Username, NickName: info.Nickname, Platform: "管理端", } // 设置载荷数据、有效期,生成 JWT Token String tokenString, err := jwtoken.New(configs.Get().JWT.AdminSecret).Sign(sessionUserInfo, 3*24*time.Hour) if err != nil { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.AdminLoginError, fmt.Sprintf("%s:token 生成失败(%s)", code.Text(code.AdminLoginError), err.Error())), ) return } info.LastLoginTime = time.Now() info.LastLoginIP = utils.GetIP(ctx.Request()) info.LastLoginHash = utils.MD5(tokenString) if err := h.writeDB.Admin.WithContext(ctx.RequestContext()).Save(info); err != nil { ctx.AbortWithError(core.Error( http.StatusBadRequest, code.AdminLoginError, fmt.Sprintf("%s:%s", code.Text(code.AdminLoginError), err.Error())), ) return } res.Token = tokenString ctx.Payload(res) } }