package handlers import ( "errors" "platform/web/models" q "platform/web/queries" "platform/web/services" "time" "github.com/gofiber/fiber/v2" "gorm.io/gorm" ) type LoginReq struct { Username string `json:"username"` Password string `json:"password"` Remember bool `json:"remember"` } type LoginResp struct { Token string `json:"token"` Expires int64 `json:"expires"` } func Login(c *fiber.Ctx) error { // 验证请求参数 req := new(LoginReq) if err := c.BodyParser(req); err != nil { return err } if req.Username == "" { return fiber.NewError(fiber.StatusBadRequest, "手机号不能为空") } if req.Password == "" { return fiber.NewError(fiber.StatusBadRequest, "验证码不能为空") } return loginByPhone(c, req) } func loginByPhone(c *fiber.Ctx, req *LoginReq) error { // 验证验证码 err := services.Verifier.VerifySms(c.Context(), req.Username, req.Password) if err != nil { if errors.Is(err, services.ErrVerifierServiceInvalid) { return fiber.NewError(fiber.StatusBadRequest, "验证码错误") } return err } // 查找用户 todo 获取权限信息 var tx = q.Q.Begin() var user *models.User user, err = tx.User. Where(tx.User.Phone.Eq(req.Username)). Take() if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return err } // 如果用户不存在,初始化用户 todo 保存默认权限信息 if user == nil { user = &models.User{ Phone: req.Username, } } // 更新用户的登录时间 user.LastLogin = time.Now() user.LastLoginHost = c.IP() user.LastLoginAgent = c.Get("User-Agent") if err := tx.User.Omit(q.User.AdminID).Save(user); err != nil { return err } err = tx.Commit() if err != nil { return err } // 保存到会话 auth := services.AuthContext{ Permissions: map[string]struct{}{ "user": {}, }, Payload: services.Payload{ Type: services.PayloadUser, Id: user.ID, }, } duration := time.Hour * 24 if req.Remember { duration *= 7 } token, err := services.Session.Create(c.Context(), auth) if err != nil { return err } return c.JSON(LoginResp{ Token: token.AccessToken, Expires: token.AccessTokenExpires.Unix(), }) }