diff --git a/bff/etc/user.pb b/bff/etc/user.pb index 779c9dc..4c3f937 100644 Binary files a/bff/etc/user.pb and b/bff/etc/user.pb differ diff --git a/bff/internal/config/config.go b/bff/internal/config/config.go index 2eb8302..99e450c 100644 --- a/bff/internal/config/config.go +++ b/bff/internal/config/config.go @@ -15,6 +15,7 @@ type NacosConf struct { NamespaceId string `json:",optional"` Group string `json:",optional"` RegisterIP string `json:",optional"` + ConfigID string `json:",optional"` } type ResponseConf struct { diff --git a/user/etc/user.yaml b/user/etc/user.yaml index 4788d3f..aeae5fa 100644 --- a/user/etc/user.yaml +++ b/user/etc/user.yaml @@ -4,4 +4,4 @@ Nacos: NamespaceId: test Group: LONE_SERVICES RegisterIP: user - ConfigID: develop-user \ No newline at end of file + ConfigID: user \ No newline at end of file diff --git a/user/internal/dao/user.go b/user/internal/dao/user.go new file mode 100644 index 0000000..52842a2 --- /dev/null +++ b/user/internal/dao/user.go @@ -0,0 +1,81 @@ +package dao + +import "pkg.local/utils" + +type UserCreate struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Openid string `gorm:"column:openid" json:"openid"` + Username string `gorm:"column:username" json:"username"` + Nickname string `gorm:"column:nickname" json:"nickname"` + Avatar string `gorm:"column:avatar" json:"avatar"` + Mobile string `gorm:"column:mobile" json:"mobile"` + Gender uint8 `gorm:"column:gender" json:"gender"` + Birthday string `gorm:"column:birthday" json:"birthday"` + AppId uint32 `gorm:"column:app_id" json:"app_id"` + Status uint8 `gorm:"column:status" json:"status"` + IsRegistered uint8 `gorm:"column:is_registered" json:"is_registered"` + IsFaceVerified uint8 `gorm:"column:is_face_verified" json:"is_face_verified"` + IsProfileCompleted uint8 `gorm:"column:is_profile_completed" json:"is_profile_completed"` + OnTrialNum int `gorm:"column:on_trial_num" json:"on_trial_num"` +} + +type UserCreateByPwd struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Type uint8 `gorm:"column:type" json:"type"` + Account string `gorm:"column:account" json:"account"` + Password string `gorm:"column:password" json:"password"` + Salt string `gorm:"column:salt" json:"salt"` + Mobile string `gorm:"column:mobile" json:"mobile"` + AppId uint32 `gorm:"column:app_id" json:"app_id"` + Status uint8 `gorm:"column:status" json:"status"` + IsRegistered uint8 `gorm:"column:is_registered" json:"is_registered"` + IsFaceVerified uint8 `gorm:"column:is_face_verified" json:"is_face_verified"` + IsProfileCompleted uint8 `gorm:"column:is_profile_completed" json:"is_profile_completed"` + OnTrialNum int `gorm:"column:on_trial_num" json:"on_trial_num"` +} + +type UserExist struct { + Id int64 `gorm:"column:id" json:"id"` +} + +type UserInfo struct { + Id int64 `gorm:"column:id" json:"id"` + Openid string `gorm:"column:openid" json:"openid"` + Username string `gorm:"column:username" json:"username"` + Nickname string `gorm:"column:nickname" json:"nickname"` + Avatar string `gorm:"column:avatar" json:"avatar"` + Mobile string `gorm:"column:mobile" json:"mobile"` + Gender uint8 `gorm:"column:gender" json:"gender"` + Birthday string `gorm:"column:birthday" json:"birthday"` + Type uint8 `gorm:"column:type" json:"type"` + Account string `gorm:"column:account" json:"account"` + AppId uint32 `gorm:"column:app_id" json:"app_id"` + Status uint8 `gorm:"column:status" json:"status"` +} + +type UserLoginRow struct { + UserInfo + Salt string `gorm:"column:salt" json:"-"` + Password string `gorm:"column:password" json:"-"` +} + +type Token struct { + Token string `json:"token"` + Refresh string `json:"refresh"` + Info UserLoginSession `json:"info"` +} + +type UserLoginSession struct { + Id int64 `json:"id"` + Openid string `json:"openid"` + Username string `json:"username"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` + Mobile string `json:"mobile"` + Gender uint8 `json:"gender"` + Birthday string `json:"birthday"` + Type uint8 `json:"type"` + Account string `json:"account"` + AppId uint32 `json:"app_id"` + LastTime utils.CustomTime `json:"last_time"` +} diff --git a/user/internal/logic/loginLogic.go b/user/internal/logic/loginLogic.go new file mode 100644 index 0000000..0f928b0 --- /dev/null +++ b/user/internal/logic/loginLogic.go @@ -0,0 +1,62 @@ +package logic + +import ( + "context" + + "user/internal/dao" + "user/internal/model" + "user/internal/svc" + "user/user" + "user/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +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 v validator.LoginValidator + if msg := validateService.ValidateFromProto(in, &v); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + var row dao.UserLoginRow + err := model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "openid": v.Openid, + "status": utils.StringStatusOk, + }, + }, &row) + if err != nil { + log.Errorf("login by openid: %v", err) + return failResponse(utils.Fail), nil + } + if row.Id < utils.NumberOne { + return failResponse(utils.ErrorNotFund), nil + } + + mobile := decryptMobile(row.Mobile) + session := toSession(row.UserInfo, mobile) + ret := buildToken(session) + if status := setLogin(ret.Token, ret.Refresh, session); status.Code != utils.Ok.Code { + return failResponse(status), nil + } + return okResponse(ret), nil +} diff --git a/user/internal/logic/pinglogic.go b/user/internal/logic/pinglogic.go deleted file mode 100644 index efa5110..0000000 --- a/user/internal/logic/pinglogic.go +++ /dev/null @@ -1,30 +0,0 @@ -package logic - -import ( - "context" - - "user/internal/svc" - "user/user" - - "github.com/zeromicro/go-zero/core/logx" -) - -type PingLogic struct { - ctx context.Context - svcCtx *svc.ServiceContext - logx.Logger -} - -func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic { - return &PingLogic{ - ctx: ctx, - svcCtx: svcCtx, - Logger: logx.WithContext(ctx), - } -} - -func (l *PingLogic) Ping(in *user.Request) (*user.Response, error) { - // todo: add your logic here and delete this line - - return &user.Response{}, nil -} diff --git a/user/internal/logic/registerByUserLogic.go b/user/internal/logic/registerByUserLogic.go new file mode 100644 index 0000000..d3bf55b --- /dev/null +++ b/user/internal/logic/registerByUserLogic.go @@ -0,0 +1,105 @@ +package logic + +import ( + "context" + "strconv" + + "user/internal/dao" + "user/internal/model" + "user/internal/svc" + "user/user" + "user/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/redis" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type RegisterByUserLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewRegisterByUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterByUserLogic { + return &RegisterByUserLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *RegisterByUserLogic) RegisterByUser(in *user.RegisterByUserReq) (*user.Response, error) { + var v validator.RegisterByUserValidator + if msg := validateService.ValidateFromProto(in, &v); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + codePrefix := utils.StringEmpty + if v.Type == utils.NumberTwo { + codePrefix = "1:" + } + + test := utils.GetConfigBool("sms.sms_test") + isTest := test && v.Code == utils.GetConfigString("sms.sms_test_code") + codeKey := utils.CodeKey + codePrefix + v.Account + code, err := redis.Client.Get(l.ctx, codeKey).Result() + if (err != nil || code != v.Code) && !isTest { + return outResponse(utils.ErrorMissingParams, "验证码错误"), nil + } + + var old dao.UserExist + err = model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "account": v.Account, + "type": strconv.FormatUint(uint64(v.Type), utils.NumberTen), + }, + }, &old) + if err != nil { + log.Errorf("registerByUser check account: %v", err) + return failResponse(utils.Fail), nil + } + if old.Id > utils.NumberZero { + return failResponse(utils.ErrorDataIsExist), nil + } + + add := dao.UserCreateByPwd{ + Type: uint8(v.Type), + Account: v.Account, + Salt: utils.GetRandString(utils.NumberFive), + AppId: v.AppId, + Status: utils.NumberOne, + IsRegistered: utils.NumberOne, + IsFaceVerified: utils.NumberTwo, + IsProfileCompleted: utils.NumberTwo, + OnTrialNum: utils.NumberOne, + } + pwd := utils.GetSaltPassword(add.Salt, v.Pwd) + add.Password, err = utils.EncryptPassword(pwd) + if err != nil { + log.Errorf("registerByUser encrypt password: %v", err) + return failResponse(utils.Fail), nil + } + + if v.Type == utils.NumberOne { + encryptMobile, cErr := utils.Crypto{}.AESEncryptECB(v.Account) + if cErr != nil { + log.Errorf("registerByUser encrypt mobile: %v", cErr) + return failResponse(utils.ErrorEncryptAesError), nil + } + add.Mobile = encryptMobile + } + + err = model.UserModel{}.Init().CreateByPwd(&add) + if err != nil || add.Id < utils.NumberOne { + log.Errorf("registerByUser create: %v", err) + return failResponse(utils.Fail), nil + } + + redis.Client.Del(l.ctx, codeKey) + return okResponse(map[string]any{"id": add.Id}), nil +} diff --git a/user/internal/logic/registerLogic.go b/user/internal/logic/registerLogic.go new file mode 100644 index 0000000..36270c2 --- /dev/null +++ b/user/internal/logic/registerLogic.go @@ -0,0 +1,100 @@ +package logic + +import ( + "context" + + "user/internal/dao" + "user/internal/model" + "user/internal/svc" + "user/user" + "user/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type RegisterLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic { + return &RegisterLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *RegisterLogic) Register(in *user.RegisterReq) (*user.Response, error) { + var v validator.RegisterValidator + if msg := validateService.ValidateFromProto(in, &v); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + openid := v.Openid + if openid == utils.StringEmpty { + openid = "mock_" + utils.MD5Encrypt(v.Mobile+utils.Now().String()) + } + + var exist dao.UserExist + err := model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{"openid": openid}, + }, &exist) + if err != nil { + log.Errorf("register check openid: %v", err) + return failResponse(utils.Fail), nil + } + if exist.Id > utils.NumberZero { + return failResponse(utils.ErrorExist), nil + } + + encryptMobile, cErr := utils.Crypto{}.AESEncryptECB(v.Mobile) + if cErr != nil { + log.Errorf("register encrypt mobile: %v", cErr) + return failResponse(utils.ErrorEncryptAesError), nil + } + + add := dao.UserCreate{ + Openid: openid, + Username: v.Username, + Nickname: v.Nickname, + Avatar: v.Avatar, + Mobile: encryptMobile, + Gender: uint8(v.Gender), + Birthday: v.Birthday, + AppId: v.AppId, + Status: utils.NumberOne, + IsRegistered: utils.NumberOne, + IsFaceVerified: utils.NumberTwo, + IsProfileCompleted: utils.NumberTwo, + OnTrialNum: utils.NumberOne, + } + err = model.UserModel{}.Init().Create(&add) + if err != nil { + log.Errorf("register create: %v", err) + return failResponse(utils.Fail), nil + } + + session := toSession(dao.UserInfo{ + Id: add.Id, + Openid: add.Openid, + Username: add.Username, + Nickname: add.Nickname, + Avatar: add.Avatar, + Gender: add.Gender, + Birthday: add.Birthday, + AppId: add.AppId, + Status: add.Status, + }, v.Mobile) + ret := buildToken(session) + if status := setLogin(ret.Token, ret.Refresh, session); status.Code != utils.Ok.Code { + return failResponse(status), nil + } + return okResponse(ret), nil +} diff --git a/user/internal/logic/response.go b/user/internal/logic/response.go new file mode 100644 index 0000000..547ebca --- /dev/null +++ b/user/internal/logic/response.go @@ -0,0 +1,116 @@ +package logic + +import ( + "context" + "encoding/json" + "strconv" + "time" + + "user/internal/dao" + "user/user" + + jsoniter "github.com/json-iterator/go" + "pkg.local/redis" + "pkg.local/utils" +) + +func okResponse(data any) *user.Response { + buf, _ := json.Marshal(data) + return &user.Response{ + Code: utils.Ok.Code, + Msg: utils.Ok.Msg, + Data: string(buf), + } +} + +func failResponse(status utils.Status) *user.Response { + return &user.Response{ + Code: status.Code, + Msg: status.Msg, + } +} + +func outResponse(status utils.Status, msg string) *user.Response { + return &user.Response{ + Code: status.Code, + Msg: msg, + } +} + +func decryptMobile(mobile string) string { + if mobile == utils.StringEmpty { + return utils.StringEmpty + } + plain, err := utils.Crypto{}.AESDecryptECB(mobile) + if err != nil { + return utils.StringEmpty + } + return plain +} + +func toSession(info dao.UserInfo, mobilePlain string) dao.UserLoginSession { + return dao.UserLoginSession{ + Id: info.Id, + Openid: info.Openid, + Username: info.Username, + Nickname: info.Nickname, + Avatar: info.Avatar, + Mobile: mobilePlain, + Gender: info.Gender, + Birthday: info.Birthday, + Type: info.Type, + Account: info.Account, + AppId: info.AppId, + LastTime: utils.Now(), + } +} + +func buildToken(session dao.UserLoginSession) dao.Token { + seed := session.Mobile + session.Openid + utils.Now().String() + token := utils.MD5Encrypt(seed) + return dao.Token{ + Token: token, + Refresh: utils.MD5Encrypt(seed + token), + Info: session, + } +} + +func setLogin(token, refresh string, session dao.UserLoginSession) utils.Status { + expireMin := utils.GetConfigInt("base.login_out_time") + expire := time.Duration(expireMin) * time.Minute + refreshMin := utils.GetConfigInt("base.login_refresh_out_time") + refreshExpire := time.Duration(refreshMin) * time.Minute + + ctx := context.Background() + userStr, _ := jsoniter.Marshal(session) + + redisKey := utils.GetLoginKey(utils.LoginTypeUser, token) + if err := redis.Client.Set(ctx, redisKey, userStr, expire).Err(); err != nil { + return utils.Fail + } + + redisKeysKey := utils.GetLoginKeysKey(utils.LoginTypeUser, strconv.FormatInt(session.Id, utils.NumberTen)) + var loginInfo utils.LoginRedis + if oldAuth, err := redis.Client.Get(ctx, redisKeysKey).Result(); err == nil { + _ = jsoniter.Unmarshal([]byte(oldAuth), &loginInfo) + if len(loginInfo.Token) > utils.NumberOne { + redis.Client.Del(ctx, utils.GetLoginKey(utils.LoginTypeUser, loginInfo.Token)) + } + if len(loginInfo.Refresh) > utils.NumberOne { + redis.Client.Del(ctx, utils.GetLoginRefreshKey(utils.LoginTypeUser, loginInfo.Refresh)) + } + } + + loginInfo.Token = token + loginInfo.Refresh = refresh + loginInfo.Info = userStr + newStr, _ := jsoniter.Marshal(loginInfo) + if err := redis.Client.Set(ctx, redisKeysKey, newStr, refreshExpire).Err(); err != nil { + return utils.Fail + } + refreshKey := utils.GetLoginRefreshKey(utils.LoginTypeUser, refresh) + if err := redis.Client.Set(ctx, refreshKey, strconv.FormatInt(session.Id, utils.NumberTen), refreshExpire).Err(); err != nil { + return utils.Fail + } + return utils.Ok +} diff --git a/user/internal/model/user.go b/user/internal/model/user.go new file mode 100644 index 0000000..32c7d42 --- /dev/null +++ b/user/internal/model/user.go @@ -0,0 +1,28 @@ +package model + +import ( + "user/internal/dao" + + "pkg.local/modelbase" +) + +type UserModel struct { + modelbase.Base +} + +func (m UserModel) TableName() string { + return modelbase.Prefix() + "users" +} + +func (m UserModel) Init() UserModel { + m.Table = m.TableName() + return m +} + +func (m UserModel) Create(data *dao.UserCreate) error { + return m.Base.Create(data) +} + +func (m UserModel) CreateByPwd(data *dao.UserCreateByPwd) error { + return m.Base.Create(data) +} diff --git a/user/internal/server/userserver.go b/user/internal/server/userserver.go index 4ac991a..4adcb90 100644 --- a/user/internal/server/userserver.go +++ b/user/internal/server/userserver.go @@ -23,7 +23,17 @@ func NewUserServer(svcCtx *svc.ServiceContext) *UserServer { } } -func (s *UserServer) Ping(ctx context.Context, in *user.Request) (*user.Response, error) { - l := logic.NewPingLogic(ctx, s.svcCtx) - return l.Ping(in) +func (s *UserServer) Register(ctx context.Context, in *user.RegisterReq) (*user.Response, error) { + l := logic.NewRegisterLogic(ctx, s.svcCtx) + return l.Register(in) +} + +func (s *UserServer) RegisterByUser(ctx context.Context, in *user.RegisterByUserReq) (*user.Response, error) { + l := logic.NewRegisterByUserLogic(ctx, s.svcCtx) + return l.RegisterByUser(in) +} + +func (s *UserServer) Login(ctx context.Context, in *user.LoginReq) (*user.Response, error) { + l := logic.NewLoginLogic(ctx, s.svcCtx) + return l.Login(in) } diff --git a/user/proto/user.proto b/user/proto/user.proto index 02cf0a5..8e50fb5 100644 --- a/user/proto/user.proto +++ b/user/proto/user.proto @@ -5,17 +5,55 @@ option go_package="./user"; import "google/api/annotations.proto"; +message Response { + int32 code = 1; + string msg = 2; + string data = 3; +} + +// 小程序注册 +message RegisterReq { + string openid = 1; // 可空;空则服务端模拟 + string nickname = 2; + string avatar = 3; + string mobile = 4; + uint32 gender = 5; // 1男 2女 + string birthday = 6; + string username = 7; + uint32 app_id = 8; // 应用标识 +} + +// 账号密码注册 +message RegisterByUserReq { + uint32 type = 1; // 1手机号 2邮箱 + string account = 2; + string pwd = 3; + string code = 4; + uint32 app_id = 5; // 应用标识 +} + +// openid 登录 +message LoginReq { + string openid = 1; +} + service User { - rpc Create(CreateReq) returns (Response) { - option (google.api.http) = { - post: "/customer/v3/login" - body: "*" - }; - } rpc Register(RegisterReq) returns (Response) { option (google.api.http) = { post: "/customer/v3/register" body: "*" }; } + rpc RegisterByUser(RegisterByUserReq) returns (Response) { + option (google.api.http) = { + post: "/customer/v3/register/user" + body: "*" + }; + } + rpc Login(LoginReq) returns (Response) { + option (google.api.http) = { + post: "/customer/v3/login" + body: "*" + }; + } } diff --git a/user/user.go b/user/user.go index f276687..366e08f 100644 --- a/user/user.go +++ b/user/user.go @@ -58,7 +58,6 @@ func main() { listenOn := utils.GetConfigString("base.listenOn") mode := utils.GetConfigString("base.mode") serviceName := utils.GetConfigString("base.name") - registerIP := utils.GetConfigString("base.registerIP") if err := discovery.Init(discovery.Config{ Hosts: c.Nacos.Hosts, @@ -77,13 +76,14 @@ func main() { if err := discovery.Register(discovery.Instance{ ServiceName: serviceName, - IP: registerIP, + IP: c.Nacos.RegisterIP, Port: port, Group: c.Nacos.Group, }); err != nil { logx.Errorf("nacos register: %v", err) os.Exit(1) } + logx.Infof("服务注册成功: %s:%d", c.Nacos.RegisterIP, port) defer func() { if err := discovery.Deregister(); err != nil { diff --git a/user/user/user.pb.go b/user/user/user.pb.go index 92a110b..c438df9 100644 --- a/user/user/user.pb.go +++ b/user/user/user.pb.go @@ -2,11 +2,12 @@ // versions: // protoc-gen-go v1.36.11 // protoc v3.19.4 -// source: user.proto +// source: proto/user.proto package user import ( + _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -21,60 +22,18 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Request struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ping string `protobuf:"bytes,1,opt,name=ping,proto3" json:"ping,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Request) Reset() { - *x = Request{} - mi := &file_user_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Request) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Request) ProtoMessage() {} - -func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_user_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Request.ProtoReflect.Descriptor instead. -func (*Request) Descriptor() ([]byte, []int) { - return file_user_proto_rawDescGZIP(), []int{0} -} - -func (x *Request) GetPing() string { - if x != nil { - return x.Ping - } - return "" -} - type Response struct { state protoimpl.MessageState `protogen:"open.v1"` - Pong string `protobuf:"bytes,1,opt,name=pong,proto3" json:"pong,omitempty"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Response) Reset() { *x = Response{} - mi := &file_user_proto_msgTypes[1] + mi := &file_proto_user_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -86,7 +45,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_user_proto_msgTypes[1] + mi := &file_proto_user_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -99,76 +58,337 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_user_proto_rawDescGZIP(), []int{1} + return file_proto_user_proto_rawDescGZIP(), []int{0} } -func (x *Response) GetPong() string { +func (x *Response) GetCode() int32 { if x != nil { - return x.Pong + return x.Code + } + return 0 +} + +func (x *Response) GetMsg() string { + if x != nil { + return x.Msg } return "" } -var File_user_proto protoreflect.FileDescriptor +func (x *Response) GetData() string { + if x != nil { + return x.Data + } + return "" +} -const file_user_proto_rawDesc = "" + +// 小程序注册(openid),对齐 sales-service user/small/v1/add +type RegisterReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Openid string `protobuf:"bytes,1,opt,name=openid,proto3" json:"openid,omitempty"` // 可空;空则服务端模拟 openid(暂不对接微信) + Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` + Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` + Mobile string `protobuf:"bytes,4,opt,name=mobile,proto3" json:"mobile,omitempty"` + Gender uint32 `protobuf:"varint,5,opt,name=gender,proto3" json:"gender,omitempty"` // 1男 2女 + Birthday string `protobuf:"bytes,6,opt,name=birthday,proto3" json:"birthday,omitempty"` + Username string `protobuf:"bytes,7,opt,name=username,proto3" json:"username,omitempty"` + AppId uint32 `protobuf:"varint,8,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` // 应用标识(数字) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterReq) Reset() { + *x = RegisterReq{} + mi := &file_proto_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterReq) ProtoMessage() {} + +func (x *RegisterReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterReq.ProtoReflect.Descriptor instead. +func (*RegisterReq) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{1} +} + +func (x *RegisterReq) GetOpenid() string { + if x != nil { + return x.Openid + } + return "" +} + +func (x *RegisterReq) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +func (x *RegisterReq) GetAvatar() string { + if x != nil { + return x.Avatar + } + return "" +} + +func (x *RegisterReq) GetMobile() string { + if x != nil { + return x.Mobile + } + return "" +} + +func (x *RegisterReq) GetGender() uint32 { + if x != nil { + return x.Gender + } + return 0 +} + +func (x *RegisterReq) GetBirthday() string { + if x != nil { + return x.Birthday + } + return "" +} + +func (x *RegisterReq) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *RegisterReq) GetAppId() uint32 { + if x != nil { + return x.AppId + } + return 0 +} + +// 账号密码注册,对齐 go-sale-admin-api RegisterByUser +type RegisterByUserReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type uint32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` // 1手机号 2邮箱 + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Pwd string `protobuf:"bytes,3,opt,name=pwd,proto3" json:"pwd,omitempty"` + Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` // 验证码 + AppId uint32 `protobuf:"varint,5,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` // 应用标识(数字) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterByUserReq) Reset() { + *x = RegisterByUserReq{} + mi := &file_proto_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterByUserReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterByUserReq) ProtoMessage() {} + +func (x *RegisterByUserReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterByUserReq.ProtoReflect.Descriptor instead. +func (*RegisterByUserReq) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{2} +} + +func (x *RegisterByUserReq) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *RegisterByUserReq) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *RegisterByUserReq) GetPwd() string { + if x != nil { + return x.Pwd + } + return "" +} + +func (x *RegisterByUserReq) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *RegisterByUserReq) GetAppId() uint32 { + if x != nil { + return x.AppId + } + return 0 +} + +// openid 登录,对齐 LoginByOpenid +type LoginReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Openid string `protobuf:"bytes,1,opt,name=openid,proto3" json:"openid,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LoginReq) Reset() { + *x = LoginReq{} + mi := &file_proto_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LoginReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LoginReq) ProtoMessage() {} + +func (x *LoginReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LoginReq.ProtoReflect.Descriptor instead. +func (*LoginReq) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{3} +} + +func (x *LoginReq) GetOpenid() string { + if x != nil { + return x.Openid + } + return "" +} + +var File_proto_user_proto protoreflect.FileDescriptor + +const file_proto_user_proto_rawDesc = "" + "\n" + - "\n" + - "user.proto\x12\x04user\"\x1d\n" + - "\aRequest\x12\x12\n" + - "\x04ping\x18\x01 \x01(\tR\x04ping\"\x1e\n" + + "\x10proto/user.proto\x12\x04user\x1a\x1cgoogle/api/annotations.proto\"D\n" + "\bResponse\x12\x12\n" + - "\x04pong\x18\x01 \x01(\tR\x04pong2-\n" + - "\x04User\x12%\n" + - "\x04Ping\x12\r.user.Request\x1a\x0e.user.ResponseB\bZ\x06./userb\x06proto3" + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x10\n" + + "\x03msg\x18\x02 \x01(\tR\x03msg\x12\x12\n" + + "\x04data\x18\x03 \x01(\tR\x04data\"\xd8\x01\n" + + "\vRegisterReq\x12\x16\n" + + "\x06openid\x18\x01 \x01(\tR\x06openid\x12\x1a\n" + + "\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12\x16\n" + + "\x06mobile\x18\x04 \x01(\tR\x06mobile\x12\x16\n" + + "\x06gender\x18\x05 \x01(\rR\x06gender\x12\x1a\n" + + "\bbirthday\x18\x06 \x01(\tR\bbirthday\x12\x1a\n" + + "\busername\x18\a \x01(\tR\busername\x12\x15\n" + + "\x06app_id\x18\b \x01(\rR\x05appId\"~\n" + + "\x11RegisterByUserReq\x12\x12\n" + + "\x04type\x18\x01 \x01(\rR\x04type\x12\x18\n" + + "\aaccount\x18\x02 \x01(\tR\aaccount\x12\x10\n" + + "\x03pwd\x18\x03 \x01(\tR\x03pwd\x12\x12\n" + + "\x04code\x18\x04 \x01(\tR\x04code\x12\x15\n" + + "\x06app_id\x18\x05 \x01(\rR\x05appId\"\"\n" + + "\bLoginReq\x12\x16\n" + + "\x06openid\x18\x01 \x01(\tR\x06openid2\x81\x02\n" + + "\x04User\x12O\n" + + "\bRegister\x12\x11.user.RegisterReq\x1a\x0e.user.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/customer/v3/register\x12`\n" + + "\x0eRegisterByUser\x12\x17.user.RegisterByUserReq\x1a\x0e.user.Response\"%\x82\xd3\xe4\x93\x02\x1f:\x01*\"\x1a/customer/v3/register/user\x12F\n" + + "\x05Login\x12\x0e.user.LoginReq\x1a\x0e.user.Response\"\x1d\x82\xd3\xe4\x93\x02\x17:\x01*\"\x12/customer/v3/loginB\bZ\x06./userb\x06proto3" var ( - file_user_proto_rawDescOnce sync.Once - file_user_proto_rawDescData []byte + file_proto_user_proto_rawDescOnce sync.Once + file_proto_user_proto_rawDescData []byte ) -func file_user_proto_rawDescGZIP() []byte { - file_user_proto_rawDescOnce.Do(func() { - file_user_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_user_proto_rawDesc), len(file_user_proto_rawDesc))) +func file_proto_user_proto_rawDescGZIP() []byte { + file_proto_user_proto_rawDescOnce.Do(func() { + file_proto_user_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_user_proto_rawDesc), len(file_proto_user_proto_rawDesc))) }) - return file_user_proto_rawDescData + return file_proto_user_proto_rawDescData } -var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_user_proto_goTypes = []any{ - (*Request)(nil), // 0: user.Request - (*Response)(nil), // 1: user.Response +var file_proto_user_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_proto_user_proto_goTypes = []any{ + (*Response)(nil), // 0: user.Response + (*RegisterReq)(nil), // 1: user.RegisterReq + (*RegisterByUserReq)(nil), // 2: user.RegisterByUserReq + (*LoginReq)(nil), // 3: user.LoginReq } -var file_user_proto_depIdxs = []int32{ - 0, // 0: user.User.Ping:input_type -> user.Request - 1, // 1: user.User.Ping:output_type -> user.Response - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type +var file_proto_user_proto_depIdxs = []int32{ + 1, // 0: user.User.Register:input_type -> user.RegisterReq + 2, // 1: user.User.RegisterByUser:input_type -> user.RegisterByUserReq + 3, // 2: user.User.Login:input_type -> user.LoginReq + 0, // 3: user.User.Register:output_type -> user.Response + 0, // 4: user.User.RegisterByUser:output_type -> user.Response + 0, // 5: user.User.Login:output_type -> user.Response + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name } -func init() { file_user_proto_init() } -func file_user_proto_init() { - if File_user_proto != nil { +func init() { file_proto_user_proto_init() } +func file_proto_user_proto_init() { + if File_proto_user_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_proto_rawDesc), len(file_user_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_user_proto_rawDesc), len(file_proto_user_proto_rawDesc)), NumEnums: 0, - NumMessages: 2, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_user_proto_goTypes, - DependencyIndexes: file_user_proto_depIdxs, - MessageInfos: file_user_proto_msgTypes, + GoTypes: file_proto_user_proto_goTypes, + DependencyIndexes: file_proto_user_proto_depIdxs, + MessageInfos: file_proto_user_proto_msgTypes, }.Build() - File_user_proto = out.File - file_user_proto_goTypes = nil - file_user_proto_depIdxs = nil + File_proto_user_proto = out.File + file_proto_user_proto_goTypes = nil + file_proto_user_proto_depIdxs = nil } diff --git a/user/user/user_grpc.pb.go b/user/user/user_grpc.pb.go index deb39c8..6fa4817 100644 --- a/user/user/user_grpc.pb.go +++ b/user/user/user_grpc.pb.go @@ -2,7 +2,7 @@ // versions: // - protoc-gen-go-grpc v1.6.2 // - protoc v3.19.4 -// source: user.proto +// source: proto/user.proto package user @@ -19,14 +19,18 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - User_Ping_FullMethodName = "/user.User/Ping" + User_Register_FullMethodName = "/user.User/Register" + User_RegisterByUser_FullMethodName = "/user.User/RegisterByUser" + User_Login_FullMethodName = "/user.User/Login" ) // UserClient is the client API for User service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type UserClient interface { - Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) + Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) + RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) + Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) } type userClient struct { @@ -37,10 +41,30 @@ func NewUserClient(cc grpc.ClientConnInterface) UserClient { return &userClient{cc} } -func (c *userClient) Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { +func (c *userClient) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Response) - err := c.cc.Invoke(ctx, User_Ping_FullMethodName, in, out, cOpts...) + err := c.cc.Invoke(ctx, User_Register_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userClient) RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_RegisterByUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_Login_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -51,7 +75,9 @@ func (c *userClient) Ping(ctx context.Context, in *Request, opts ...grpc.CallOpt // All implementations must embed UnimplementedUserServer // for forward compatibility. type UserServer interface { - Ping(context.Context, *Request) (*Response, error) + Register(context.Context, *RegisterReq) (*Response, error) + RegisterByUser(context.Context, *RegisterByUserReq) (*Response, error) + Login(context.Context, *LoginReq) (*Response, error) mustEmbedUnimplementedUserServer() } @@ -62,8 +88,14 @@ type UserServer interface { // pointer dereference when methods are called. type UnimplementedUserServer struct{} -func (UnimplementedUserServer) Ping(context.Context, *Request) (*Response, error) { - return nil, status.Error(codes.Unimplemented, "method Ping not implemented") +func (UnimplementedUserServer) Register(context.Context, *RegisterReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Register not implemented") +} +func (UnimplementedUserServer) RegisterByUser(context.Context, *RegisterByUserReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method RegisterByUser not implemented") +} +func (UnimplementedUserServer) Login(context.Context, *LoginReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Login not implemented") } func (UnimplementedUserServer) mustEmbedUnimplementedUserServer() {} func (UnimplementedUserServer) testEmbeddedByValue() {} @@ -86,20 +118,56 @@ func RegisterUserServer(s grpc.ServiceRegistrar, srv UserServer) { s.RegisterService(&User_ServiceDesc, srv) } -func _User_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) +func _User_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(UserServer).Ping(ctx, in) + return srv.(UserServer).Register(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: User_Ping_FullMethodName, + FullMethod: User_Register_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UserServer).Ping(ctx, req.(*Request)) + return srv.(UserServer).Register(ctx, req.(*RegisterReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _User_RegisterByUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterByUserReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).RegisterByUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_RegisterByUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).RegisterByUser(ctx, req.(*RegisterByUserReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _User_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).Login(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_Login_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).Login(ctx, req.(*LoginReq)) } return interceptor(ctx, in, info, handler) } @@ -112,10 +180,18 @@ var User_ServiceDesc = grpc.ServiceDesc{ HandlerType: (*UserServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "Ping", - Handler: _User_Ping_Handler, + MethodName: "Register", + Handler: _User_Register_Handler, + }, + { + MethodName: "RegisterByUser", + Handler: _User_RegisterByUser_Handler, + }, + { + MethodName: "Login", + Handler: _User_Login_Handler, }, }, Streams: []grpc.StreamDesc{}, - Metadata: "user.proto", + Metadata: "proto/user.proto", } diff --git a/user/userclient/user.go b/user/userclient/user.go index a2396df..e732e95 100644 --- a/user/userclient/user.go +++ b/user/userclient/user.go @@ -2,7 +2,7 @@ // goctl 1.10.1 // Source: user.proto -package userclient +package userClient import ( "context" @@ -14,11 +14,15 @@ import ( ) type ( - Request = user.Request - Response = user.Response + LoginReq = user.LoginReq + RegisterByUserReq = user.RegisterByUserReq + RegisterReq = user.RegisterReq + Response = user.Response User interface { - Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) + Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) + RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) + Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) } defaultUser struct { @@ -32,7 +36,17 @@ func NewUser(cli zrpc.Client) User { } } -func (m *defaultUser) Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { +func (m *defaultUser) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) { client := user.NewUserClient(m.cli.Conn()) - return client.Ping(ctx, in, opts...) + return client.Register(ctx, in, opts...) +} + +func (m *defaultUser) RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.RegisterByUser(ctx, in, opts...) +} + +func (m *defaultUser) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.Login(ctx, in, opts...) } diff --git a/user/validator/user.go b/user/validator/user.go new file mode 100644 index 0000000..7323109 --- /dev/null +++ b/user/validator/user.go @@ -0,0 +1,56 @@ +package validator + +import "pkg.local/validate" + +type RegisterValidator struct { + Openid string + Nickname string `validate:"required"` + Avatar string `validate:"required"` + Mobile string `validate:"required"` + Gender uint32 `validate:"required,oneof=1 2"` + Birthday string `validate:"required"` + Username string `validate:"required"` + AppId uint32 `validate:"required"` +} + +func (p RegisterValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Nickname.required": "昵称不能为空", + "Avatar.required": "头像不能为空", + "Mobile.required": "手机号不能为空", + "Gender.required": "性别不能为空", + "Gender.oneof": "性别传值不对", + "Birthday.required": "生日不能为空", + "Username.required": "姓名不能为空", + "AppId.required": "应用标识不能为空", + } +} + +type RegisterByUserValidator struct { + Type uint32 `validate:"required,oneof=1 2"` + Account string `validate:"required"` + Pwd string `validate:"required"` + Code string `validate:"required"` + AppId uint32 `validate:"required"` +} + +func (p RegisterByUserValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Type.required": "类型不能为空", + "Type.oneof": "类型传值不对", + "Account.required": "账号不能为空", + "Pwd.required": "密码不能为空", + "Code.required": "验证码不能为空", + "AppId.required": "应用标识不能为空", + } +} + +type LoginValidator struct { + Openid string `validate:"required"` +} + +func (p LoginValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Openid.required": "Openid不能为空", + } +}