package handler import ( "errors" "strconv" "time" "github.com/gin-gonic/gin" "kra/internal/biz/system" "kra/internal/service/dto" service "kra/internal/service/liveclient" ) type LiveClient struct{ service *service.Service } func NewLiveClient(service *service.Service) *LiveClient { return &LiveClient{service: service} } func (h *LiveClient) Register(c *gin.Context) { in, ok := bindJSON[dto.LiveClientRegisterRequest](c) if !ok { return } result, err := h.service.Register(c.Request.Context(), in, c.ClientIP(), c.Request.UserAgent()) if err != nil { clientAuthFail(c, err) return } setClientToken(c, result) Write(c, CodeSuccess, result, "注册成功") } func (h *LiveClient) Login(c *gin.Context) { in, ok := bindJSON[dto.LiveClientLoginRequest](c) if !ok { return } result, err := h.service.Login(c.Request.Context(), in, c.ClientIP(), c.Request.UserAgent()) if err != nil { clientAuthFail(c, err) return } setClientToken(c, result) Write(c, CodeSuccess, result, "登录成功") } func (h *LiveClient) Me(c *gin.Context) { claims := Claims(c) if claims == nil { NoAuth(c, "请登录") return } result, err := h.service.Me(c.Request.Context(), claims.ID) if err != nil { businessFail(c, err) return } OKWithData(c, result) } func (h *LiveClient) Balance(c *gin.Context) { claims := Claims(c) if claims == nil { NoAuth(c, "请登录") return } result, err := h.service.Balance(c.Request.Context(), claims.ID) if err != nil { businessFail(c, err) return } OKWithData(c, result) } func (h *LiveClient) UpdateProfile(c *gin.Context) { claims := Claims(c) if claims == nil { NoAuth(c, "请登录") return } in, ok := bindJSON[dto.LiveClientProfileRequest](c) if !ok { return } result, err := h.service.UpdateProfile(c.Request.Context(), claims.ID, in) if err != nil { businessFail(c, err) return } OKWithData(c, result) } func (h *LiveClient) ChangePassword(c *gin.Context) { claims := Claims(c) if claims == nil { NoAuth(c, "请登录") return } in, ok := bindJSON[dto.LiveClientPasswordRequest](c) if !ok { return } result, err := h.service.ChangePassword(c.Request.Context(), claims.ID, in, c.ClientIP(), c.Request.UserAgent()) if err != nil { clientAuthFail(c, err) return } setClientToken(c, result) Write(c, CodeSuccess, result, "密码修改成功") } func setClientToken(c *gin.Context, result *dto.LiveClientAuthResponse) { maxAge := int(time.UnixMilli(result.ExpiresAt).Unix() - time.Now().Unix()) SetTokenCookie(c, result.Token, maxAge) } func clientAuthFail(c *gin.Context, err error) { switch { case errors.Is(err, system.ErrAccountLocked): var locked *system.AccountLockedError errors.As(err, &locked) minutes := 0 if locked != nil { minutes = locked.Minutes } Fail(c, "账号已锁定,请 "+strconv.Itoa(minutes)+" 分钟后再试") case errors.Is(err, system.ErrInvalidCredentials): Fail(c, "用户名不存在或者密码错误") case errors.Is(err, system.ErrUserDisabled): Fail(c, "用户被禁止登录") default: businessFail(c, err) } }