package pub import ( "context" "time" "perms-system-server/internal/middleware" "perms-system-server/internal/response" "perms-system-server/internal/svc" "perms-system-server/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type LoginLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { return &LoginLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // Login 产品端登录。产品成员通过用户名密码 + productCode 登录指定产品,返回 JWT 令牌对及用户权限信息。 // 当 cap.js 未启用时,需同时携带 captchaId/captchaCode 进行图片验证码校验。 func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) { // cap.js 未启用时强制校验图片验证码 cfg := l.svcCtx.Config.Capjs if cfg.Enable != 1 { if req.CaptchaId == "" || req.CaptchaCode == "" { return nil, response.ErrBadRequest("验证码不能为空") } if !VerifyCaptcha(req.CaptchaId, req.CaptchaCode) { return nil, response.ErrBadRequest("验证码错误或已过期") } } clientIP := middleware.GetClientIP(l.ctx) result, err := ValidateProductLogin(l.ctx, l.svcCtx, req.Username, req.Password, req.ProductCode, clientIP) if err != nil { if le, ok := err.(*LoginError); ok { switch le.Code { case 400: return nil, response.ErrBadRequest(le.Message) case 401: return nil, response.ErrUnauthorized(le.Message) case 403: return nil, response.ErrForbidden(le.Message) case 429: return nil, response.NewCodeError(429, le.Message) } } return nil, err } ud := result.UserDetails return &types.LoginResp{ AccessToken: result.AccessToken, RefreshToken: result.RefreshToken, Expires: time.Now().Unix() + l.svcCtx.Config.Auth.AccessExpire, UserInfo: types.UserInfo{ UserId: ud.UserId, Username: ud.Username, Nickname: ud.Nickname, Avatar: ud.Avatar, Email: ud.Email, Phone: ud.Phone, IsSuperAdmin: ud.IsSuperAdminRaw, MustChangePassword: ud.MustChangePwdRaw, MemberType: ud.MemberType, Perms: ud.Perms, }, }, nil }