package logic import ( "context" "lone-services/pkg/utils" "lone-services/pkg/validate" user "lone-services/rpc/user/pb" userconfig "lone-services/services/user/internal/config" "lone-services/services/user/internal/dao" "lone-services/services/user/internal/svc" "lone-services/services/user/validator" "github.com/zeromicro/go-zero/core/logx" "google.golang.org/grpc/status" ) type LoginLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { return &LoginLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *LoginLogic) Login(in *user.LoginReq) (*user.Response, error) { var req validator.LoginValidator if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { return outResponse(utils.ErrorParams, msg), nil } switch req.GrantType { case dao.GrantTypeOpenid: return l.loginByOpenid(req) case dao.GrantTypePassword: return l.loginByPassword(req) case dao.GrantTypeSms: return outResponse(utils.ErrorParams, "验证码登录暂未开放"), nil default: return outResponse(utils.ErrorParams, "不支持的登录方式"), nil } } func (l *LoginLogic) loginByOpenid(req validator.LoginValidator) (*user.Response, error) { client, err := loadEnabledClient(req.ClientCode) if err != nil { l.Errorf("login load client: %v", err) return failResponse(utils.Fail), nil } if !clientAllowsGrant(client.AllowedGrants, dao.GrantTypeOpenid) { return outResponse(utils.ErrorParams, "该端不支持微信登录"), nil } wxClient, cfgErr := userconfig.NewWechatClient(req.ClientCode) if cfgErr != nil { l.Errorf("login wechat config: %v", cfgErr) return outResponse(utils.Fail, "微信配置缺失"), nil } session, wxErr := wxClient.Code2Session(req.Code) if wxErr != nil { l.Errorf("login code2session: %v", wxErr) return outResponse(utils.Fail, "微信登录失败"), nil } userId, resolveErr := resolveOrCreateWechatUser(l.ctx, l.svcCtx.DB, session.OpenID, session.UnionID, req.ClientCode) if resolveErr != nil { l.Errorf("login resolve wechat user: %v", resolveErr) if st, ok := status.FromError(resolveErr); ok { return outResponse(utils.Fail, st.Message()), nil } return failResponse(utils.Fail), nil } row, userErr := loadEnabledUser(userId) if userErr != nil { l.Errorf("login load user: %v", userErr) return failResponse(utils.ErrorNotFund), nil } ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client) if tokenErr != nil { l.Errorf("login issue token: %v", tokenErr) return failResponse(utils.Fail), nil } return okResponse(ret), nil } func (l *LoginLogic) loginByPassword(req validator.LoginValidator) (*user.Response, error) { client, err := loadEnabledClient(req.ClientCode) if err != nil { l.Errorf("login load client: %v", err) return failResponse(utils.Fail), nil } if !clientAllowsGrant(client.AllowedGrants, dao.GrantTypePassword) { return outResponse(utils.ErrorParams, "该端不支持密码登录"), nil } if len(req.Mobile) != utils.NumberEleven { return failResponse(utils.ErrorMobileError), nil } encryptMobile, encErr := utils.EncryptPhone(req.Mobile) if encErr != nil { l.Errorf("login encrypt mobile: %v", encErr) return failResponse(utils.ErrorEncryptAesError), nil } cred, credErr := findCredential(dao.CredentialTypePassword, encryptMobile) if credErr != nil { l.Errorf("login find credential: %v", credErr) return failResponse(utils.Fail), nil } if cred == nil { return failResponse(utils.ErrorNotFund), nil } if cred.Status == dao.StatusDisabled { return outResponse(utils.Fail, "登录凭证已禁用"), nil } if !utils.EqualsPassword(req.Password, cred.Secret) { return failResponse(utils.ErrorPwdError), nil } hasClient, clientErr := userHasEnabledClient(cred.UserId, req.ClientCode) if clientErr != nil { l.Errorf("login check user client: %v", clientErr) return failResponse(utils.Fail), nil } if !hasClient { return outResponse(utils.ErrorParams, "该端未开通或已禁用"), nil } row, userErr := loadEnabledUser(cred.UserId) if userErr != nil { l.Errorf("login load user: %v", userErr) return failResponse(utils.ErrorNotFund), nil } ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client) if tokenErr != nil { l.Errorf("login issue token: %v", tokenErr) return failResponse(utils.Fail), nil } return okResponse(ret), nil }