diff --git a/bff/internal/response/user.go b/bff/internal/response/user.go index 8286970..d40b454 100644 --- a/bff/internal/response/user.go +++ b/bff/internal/response/user.go @@ -14,21 +14,41 @@ import ( type ctxKey string const ( - CtxUserId ctxKey = "X-User-Id" - CtxUserName ctxKey = "X-User-Name" - CtxRefresh ctxKey = "X-Refresh" - CtxClientIP ctxKey = "X-Client-Ip" - CtxUserAgent ctxKey = "X-User-Agent" + CtxUserId ctxKey = "X-User-Id" + CtxUserName ctxKey = "X-User-Name" + CtxRefresh ctxKey = "X-Refresh" + CtxClientIP ctxKey = "X-Client-Ip" + CtxUserAgent ctxKey = "X-User-Agent" + CtxClientCode ctxKey = "X-Client-Code" + CtxSaleId ctxKey = "X-Sale-Id" + CtxSaleName ctxKey = "X-Sale-Name" + CtxSaleMobile ctxKey = "X-Sale-Mobile" + CtxSaleProvince ctxKey = "X-Sale-Province" + CtxStoreId ctxKey = "X-Store-Id" + CtxStoreName ctxKey = "X-Store-Name" + CtxGroupId ctxKey = "X-Group-Id" + CtxGroupName ctxKey = "X-Group-Name" + CtxUserType ctxKey = "X-User-Type" ) type UserInfo struct { - ID int64 - Name string - RawUID string - Refresh string - ClientIP string - UserAgent string - Valid bool + ID int64 + Name string + RawUID string + Refresh string + ClientIP string + UserAgent string + Type string + ClientCode string + SaleId string + SaleName string + SaleMobile string + SaleProvince string + StoreId string + StoreName string + GroupId string + GroupName string + Valid bool } func GetUserInfo(ctx context.Context) UserInfo { @@ -37,13 +57,33 @@ func GetUserInfo(ctx context.Context) UserInfo { refresh, _ := ctx.Value(CtxRefresh).(string) clientIP, _ := ctx.Value(CtxClientIP).(string) userAgent, _ := ctx.Value(CtxUserAgent).(string) + userType, _ := ctx.Value(CtxUserType).(string) + clientCode, _ := ctx.Value(CtxClientCode).(string) + saleId, _ := ctx.Value(CtxSaleId).(string) + saleName, _ := ctx.Value(CtxSaleName).(string) + saleMobile, _ := ctx.Value(CtxSaleMobile).(string) + saleProvince, _ := ctx.Value(CtxSaleProvince).(string) + storeId, _ := ctx.Value(CtxStoreId).(string) + storeName, _ := ctx.Value(CtxStoreName).(string) + groupId, _ := ctx.Value(CtxGroupId).(string) + groupName, _ := ctx.Value(CtxGroupName).(string) info := UserInfo{ - RawUID: rawUID, - Name: name, - Refresh: refresh, - ClientIP: clientIP, - UserAgent: userAgent, + RawUID: rawUID, + Name: name, + Refresh: refresh, + ClientIP: clientIP, + UserAgent: userAgent, + Type: userType, + ClientCode: clientCode, + SaleId: saleId, + SaleName: saleName, + SaleMobile: saleMobile, + SaleProvince: saleProvince, + StoreId: storeId, + StoreName: storeName, + GroupId: groupId, + GroupName: groupName, } if rawUID == "" { return info @@ -58,7 +98,6 @@ func GetUserInfo(ctx context.Context) UserInfo { return info } -// getRealClientIP 获取真实客户端IP,优先 X‑Forwarded‑For,其次 X‑Real‑IP,最后 RemoteAddr func getRealClientIP(r *http.Request) string { xff := r.Header.Get("X-Forwarded-For") if xff != "" { @@ -79,10 +118,26 @@ func UserReadMiddleware(next http.HandlerFunc) http.HandlerFunc { newCtx = context.WithValue(newCtx, CtxRefresh, r.Header.Get("X-Refresh")) newCtx = context.WithValue(newCtx, CtxClientIP, getRealClientIP(r)) newCtx = context.WithValue(newCtx, CtxUserAgent, r.UserAgent()) + newCtx = context.WithValue(newCtx, CtxUserType, r.Header.Get("X-User-Type")) + newCtx = context.WithValue(newCtx, CtxClientCode, r.Header.Get("X-Client-Code")) + newCtx = context.WithValue(newCtx, CtxSaleId, r.Header.Get("X-Sale-Id")) + newCtx = context.WithValue(newCtx, CtxSaleName, r.Header.Get("X-Sale-Name")) + newCtx = context.WithValue(newCtx, CtxSaleMobile, r.Header.Get("X-Sale-Mobile")) + newCtx = context.WithValue(newCtx, CtxSaleProvince, r.Header.Get("X-Sale-Province")) + newCtx = context.WithValue(newCtx, CtxStoreId, r.Header.Get("X-Store-Id")) + newCtx = context.WithValue(newCtx, CtxStoreName, r.Header.Get("X-Store-Name")) + newCtx = context.WithValue(newCtx, CtxGroupId, r.Header.Get("X-Group-Id")) + newCtx = context.WithValue(newCtx, CtxGroupName, r.Header.Get("X-Group-Name")) next(w, r.WithContext(newCtx)) } } +func setMDIfNotEmpty(md metadata.MD, key, value string) { + if value != utils.StringEmpty { + md.Set(key, value) + } +} + func UserClientInterceptor(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { user := GetUserInfo(ctx) md := metadata.New(map[string]string{}) @@ -92,15 +147,27 @@ func UserClientInterceptor(ctx context.Context, method string, req, reply any, c md.Set("x-user-name", url.QueryEscape(user.Name)) } - if user.Refresh != utils.StringEmpty { - md.Set("x-refresh", user.Refresh) - } - if user.ClientIP != utils.StringEmpty { - md.Set("x-client-ip", user.ClientIP) - } + setMDIfNotEmpty(md, "x-refresh", user.Refresh) + setMDIfNotEmpty(md, "x-client-ip", user.ClientIP) if user.UserAgent != utils.StringEmpty { md.Set("x-user-agent", url.QueryEscape(user.UserAgent)) } + setMDIfNotEmpty(md, "x-user-type", user.Type) + setMDIfNotEmpty(md, "x-client-code", user.ClientCode) + setMDIfNotEmpty(md, "x-sale-id", user.SaleId) + if user.SaleName != utils.StringEmpty { + md.Set("x-sale-name", url.QueryEscape(user.SaleName)) + } + setMDIfNotEmpty(md, "x-sale-mobile", user.SaleMobile) + setMDIfNotEmpty(md, "x-sale-province", user.SaleProvince) + setMDIfNotEmpty(md, "x-store-id", user.StoreId) + if user.StoreName != utils.StringEmpty { + md.Set("x-store-name", url.QueryEscape(user.StoreName)) + } + setMDIfNotEmpty(md, "x-group-id", user.GroupId) + if user.GroupName != utils.StringEmpty { + md.Set("x-group-name", url.QueryEscape(user.GroupName)) + } ctx = metadata.NewOutgoingContext(ctx, md) return invoker(ctx, method, req, reply, cc, opts...) diff --git a/deploy/apisix/lua/auth.lua b/deploy/apisix/lua/auth.lua index 0ae0bea..a1656ae 100644 --- a/deploy/apisix/lua/auth.lua +++ b/deploy/apisix/lua/auth.lua @@ -109,7 +109,7 @@ function _M.access(conf, ctx) ngx.req.set_header("X-Store-Id", tostring(json.store_id)) end if json.sale_province then - ngx.req.set_header("X-Sale-Province", tostring(json.province)) + ngx.req.set_header("X-Sale-Province", tostring(json.sale_province)) end if json.sale_mobile then ngx.req.set_header("X-Sale-Mobile", tostring(json.sale_mobile)) @@ -129,6 +129,9 @@ function _M.access(conf, ctx) if json.type then ngx.req.set_header("X-User-Type", tostring(json.type)) end + if json.client_code then + ngx.req.set_header("X-Client-Code", tostring(json.client_code)) + end end ngx.req.set_header("X-Refresh", refresh or "") diff --git a/pkg/utils/jwt.go b/pkg/utils/jwt.go index 8c9871d..eee7b9e 100644 --- a/pkg/utils/jwt.go +++ b/pkg/utils/jwt.go @@ -2,76 +2,94 @@ package utils import ( "errors" - "github.com/golang-jwt/jwt/v4" + "fmt" "strconv" "time" + + "github.com/golang-jwt/jwt/v4" ) -type Jwt struct { +const ( + TokenTypeAccess = "access" + TokenTypeRefresh = "refresh" +) + +type JWT struct { Secret string - Ttl int + TTL int Issuer string } -type JwtInfo struct { - Id int `gorm:"column:id;type:int(11);primary_key;AUTO_INCREMENT" json:"id"` - NickName string `json:"nick_name"` - DepartmentId int `gorm:"column:department_id;type:int(11);default:0;comment:部门ID" json:"department_id"` - PostId int `gorm:"column:post_id;type:int(11);default:0;comment:岗位ID;NOT NULL" json:"post_id"` - LastTime CustomTime `gorm:"column:last_time;type:datetime;comment:最后一次登录时间" json:"last_time"` +func NewJWT(secret, issuer string, ttlSeconds int) (*JWT, error) { + if secret == "" { + return nil, errors.New("jwt secret empty") + } + if ttlSeconds < 1 { + return nil, errors.New("jwt ttl invalid") + } + return &JWT{ + Secret: secret, + TTL: ttlSeconds, + Issuer: issuer, + }, nil +} + +type Claims struct { + UserID int64 `json:"user_id"` + Name string `json:"name"` + Avatar string `json:"avatar"` + Mobile string `json:"mobile"` + Gender uint8 `json:"gender"` + Birthday string `json:"birthday"` + Type uint8 `json:"type"` // 1销售 2门店 3普通用户 + ClientCode string `json:"client_code"` + SaleId int64 `json:"sale_id,omitempty"` + StoreId int64 `json:"store_id,omitempty"` + TokenType string `json:"token_type"` // access | refresh jwt.RegisteredClaims } -type Token struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` -} +func (j *JWT) Sign(claims Claims) (string, error) { + if j == nil { + return "", errors.New("jwt not initialized") + } + now := time.Now() + claims.Issuer = j.Issuer + claims.IssuedAt = jwt.NewNumericDate(now) + claims.ExpiresAt = jwt.NewNumericDate(now.Add(time.Duration(j.TTL) * time.Second)) + claims.ID = strconv.FormatInt(claims.UserID, NumberTen) -// GetToken 获取token -// -// access is true 获取登录token -// access is false 获取置换token -func (j *Jwt) GetToken(user JwtInfo, access bool) (string, error) { - j.setJwtConfig(access) - // 创建 Claims - user.Issuer = j.Issuer - user.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Duration(j.Ttl) * time.Second)) // 过期时间 - user.ID = strconv.Itoa(user.Id) - // 生成token对象 - token := jwt.NewWithClaims(jwt.SigningMethodHS256, user) - // 生成签名字符串 + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(j.Secret)) } -// ParseToken 校验token -// -// access is true 校验登录token -// access is false 校验置换token -func (j *Jwt) ParseToken(tokenString string, access bool) (*JwtInfo, error) { - j.setJwtConfig(access) - // 解析token - token, err := jwt.ParseWithClaims(tokenString, &JwtInfo{}, func(token *jwt.Token) (interface{}, error) { +func (j *JWT) Parse(tokenString string) (*Claims, error) { + if j == nil { + return nil, errors.New("jwt not initialized") + } + token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } return []byte(j.Secret), nil }) - if err != nil { // 解析token失败 + if err != nil { return nil, err } - //对token对象中的Claim进行类型断言 - claims, ok := token.Claims.(*JwtInfo) - if ok && token.Valid { // 校验token - claims.LastTime = Now() - return claims, nil + claims, ok := token.Claims.(*Claims) + if !ok || !token.Valid { + return nil, errors.New("invalid token") } - return nil, errors.New("is check false") + return claims, nil } -func (j *Jwt) setJwtConfig(access bool) { - j.Ttl = GetConfigInt("jwt.access_ttl") - j.Issuer = GetConfigString("jwt.issuer") - j.Secret = GetConfigString("jwt.access_secret") - - if !access { - j.Ttl = GetConfigInt("jwt.refresh_ttl") - j.Secret = GetConfigString("jwt.refresh_secret") +func (j *JWT) ParseExpect(tokenString, expectType string) (*Claims, error) { + claims, err := j.Parse(tokenString) + if err != nil { + return nil, err } + if claims.TokenType != expectType { + return nil, fmt.Errorf("unexpected token type: %s", claims.TokenType) + } + return claims, nil } diff --git a/pkg/utils/loginInfo.go b/pkg/utils/loginInfo.go index 25a4919..5daaf57 100644 --- a/pkg/utils/loginInfo.go +++ b/pkg/utils/loginInfo.go @@ -27,78 +27,58 @@ type UserInfo struct { GroupId int64 // 分组ID GroupName string // 分组名称 Type uint8 // 用户类型 + ClientCode string Valid bool } +func firstMD(md metadata.MD, keys ...string) string { + for _, key := range keys { + vals := md.Get(key) + if len(vals) > NumberZero && vals[NumberZero] != StringEmpty { + return vals[NumberZero] + } + } + return StringEmpty +} + +func parseInt64MD(md metadata.MD, keys ...string) int64 { + raw := firstMD(md, keys...) + if raw == StringEmpty { + return NumberZero + } + v, _ := strconv.ParseInt(raw, NumberTen, NumberSixtyFourth) + return v +} + func GetUserFromCtx(ctx context.Context) UserInfo { md, ok := metadata.FromIncomingContext(ctx) if !ok { return UserInfo{Valid: false} } - uidList := md.Get("x-user-id") - nameList := md.Get("x-user-name") - refreshList := md.Get("x-refresh") - ipList := md.Get("x-client-ip") - userAgentList := md.Get("x-user-agent") - storeName := md.Get("x-store-name") - storeId := md.Get("x-store-id") - saleName := md.Get("x-sale-name") - saleId := md.Get("x-sale-id") - groupId := md.Get("x-group-id") - groupName := md.Get("x-group-name") - Type := md.Get("x-user-type") - province := md.Get("x-sale-province") - mobile := md.Get("x-sale-mobile") - - if len(refreshList) == NumberZero { - refreshList = md.Get("X-Refresh") - } - var userInfo UserInfo - if len(uidList) > NumberZero { - userInfo.RawUID = uidList[NumberZero] - } - if len(nameList) > NumberZero { - userInfo.Name = nameList[NumberZero] - } - if len(storeName) > NumberZero { - userInfo.StoreName = storeName[NumberZero] + userInfo := UserInfo{ + RawUID: firstMD(md, "x-user-id"), + Name: firstMD(md, "x-user-name"), + Refresh: firstMD(md, "x-refresh", "X-Refresh"), + ClientIP: firstMD(md, "x-client-ip"), + UserAgent: firstMD(md, "x-user-agent"), + StoreName: firstMD(md, "x-store-name"), + StoreId: parseInt64MD(md, "x-store-id"), + SaleName: firstMD(md, "x-sale-name"), + SaleId: parseInt64MD(md, "x-sale-id"), + SaleMobile: firstMD(md, "x-sale-mobile"), + SaleProvince: parseInt64MD(md, "x-sale-province"), + GroupId: parseInt64MD(md, "x-group-id"), + GroupName: firstMD(md, "x-group-name"), + ClientCode: firstMD(md, "x-client-code"), } - if len(groupName) > NumberZero { - userInfo.GroupName = groupName[NumberZero] - } - if len(Type) > NumberZero { - TypeInt, _ := strconv.ParseInt(Type[NumberZero], NumberTen, NumberSixtyFourth) - userInfo.Type = uint8(TypeInt) + if typeRaw := firstMD(md, "x-user-type"); typeRaw != StringEmpty { + typeInt, _ := strconv.ParseInt(typeRaw, NumberTen, NumberSixtyFourth) + userInfo.Type = uint8(typeInt) } - if len(storeId) > NumberZero { - userInfo.StoreId, _ = strconv.ParseInt(storeId[NumberZero], NumberTen, NumberSixtyFourth) - } - if len(saleName) > NumberZero { - userInfo.SaleName = saleName[NumberZero] - } - if len(province) > NumberZero { - userInfo.SaleProvince, _ = strconv.ParseInt(province[NumberZero], NumberTen, NumberSixtyFourth) - } - if len(mobile) > NumberZero { - userInfo.SaleMobile = mobile[NumberZero] - } - if len(saleId) > NumberZero { - userInfo.SaleId, _ = strconv.ParseInt(saleId[NumberZero], NumberTen, NumberSixtyFourth) - } - if len(groupId) > NumberZero { - userInfo.GroupId, _ = strconv.ParseInt(groupId[NumberZero], NumberTen, NumberSixtyFourth) - } - if len(refreshList) > NumberZero { - userInfo.Refresh = refreshList[NumberZero] - } - if len(ipList) > NumberZero { - userInfo.ClientIP = ipList[NumberZero] - } - if len(userAgentList) > NumberZero { - userInfo.UserAgent = userAgentList[NumberZero] + if userInfo.UserAgent != StringEmpty { userInfo.UserAgent, _ = url.QueryUnescape(userInfo.UserAgent) ua := user_agent.New(userInfo.UserAgent) userInfo.BrowserName, userInfo.BrowserVer = ua.Browser() @@ -116,6 +96,15 @@ func GetUserFromCtx(ctx context.Context) UserInfo { userName, _ := url.QueryUnescape(userInfo.Name) userInfo.ID = uid userInfo.Name = userName + if userInfo.SaleName != StringEmpty { + userInfo.SaleName, _ = url.QueryUnescape(userInfo.SaleName) + } + if userInfo.StoreName != StringEmpty { + userInfo.StoreName, _ = url.QueryUnescape(userInfo.StoreName) + } + if userInfo.GroupName != StringEmpty { + userInfo.GroupName, _ = url.QueryUnescape(userInfo.GroupName) + } userInfo.Valid = true return userInfo diff --git a/pkg/wechat/auth/client.go b/pkg/wechat/auth/client.go new file mode 100644 index 0000000..dd2be0c --- /dev/null +++ b/pkg/wechat/auth/client.go @@ -0,0 +1,13 @@ +package auth + +type Client struct { + AppID string + Secret string +} + +func NewClient(appID, secret string) *Client { + return &Client{ + AppID: appID, + Secret: secret, + } +} diff --git a/pkg/wechat/auth/phone.go b/pkg/wechat/auth/phone.go new file mode 100644 index 0000000..183cdba --- /dev/null +++ b/pkg/wechat/auth/phone.go @@ -0,0 +1,78 @@ +package auth + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + "lone-services/pkg/utils" +) + +const phoneNumberURL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber" + +type PhoneNumberRequest struct { + Code string `json:"code"` +} + +type PhoneInfo struct { + PhoneNumber string `json:"phoneNumber"` + PurePhoneNumber string `json:"purePhoneNumber"` + CountryCode string `json:"countryCode"` +} + +type PhoneNumberResult struct { + ErrCode int `json:"errcode"` + ErrMsg string `json:"errmsg"` + PhoneInfo PhoneInfo `json:"phone_info"` +} + +type APIError struct { + ErrCode int + ErrMsg string +} + +func (e *APIError) Error() string { + return fmt.Sprintf("errcode=%d errmsg=%s", e.ErrCode, e.ErrMsg) +} + +func (c *Client) GetPhoneNumber(accessToken, code string) (*PhoneInfo, error) { + if accessToken == utils.StringEmpty { + return nil, fmt.Errorf("wechat access_token empty") + } + if code == utils.StringEmpty { + return nil, fmt.Errorf("wechat phone code empty") + } + + payload, err := json.Marshal(PhoneNumberRequest{Code: code}) + if err != nil { + return nil, err + } + + url := fmt.Sprintf("%s?access_token=%s", phoneNumberURL, accessToken) + client := &http.Client{Timeout: 10 * time.Second} + resp, err := client.Post(url, "application/json", bytes.NewReader(payload)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var result PhoneNumberResult + if err := json.Unmarshal(body, &result); err != nil { + return nil, err + } + if result.ErrCode != utils.NumberZero { + return nil, &APIError{ErrCode: result.ErrCode, ErrMsg: result.ErrMsg} + } + if result.PhoneInfo.PhoneNumber == utils.StringEmpty && result.PhoneInfo.PurePhoneNumber == utils.StringEmpty { + return nil, fmt.Errorf("wechat phone number empty") + } + return &result.PhoneInfo, nil +} diff --git a/pkg/wechat/auth/session.go b/pkg/wechat/auth/session.go new file mode 100644 index 0000000..90f6633 --- /dev/null +++ b/pkg/wechat/auth/session.go @@ -0,0 +1,50 @@ +package auth + +import ( + "fmt" + + "lone-services/pkg/utils" + + jsoniter "github.com/json-iterator/go" +) + +const code2SessionURL = "https://api.weixin.qq.com/sns/jscode2session" + +type Session struct { + OpenID string `json:"openid"` + UnionID string `json:"unionid"` + SessionKey string `json:"session_key"` + ErrCode int `json:"errcode"` + ErrMsg string `json:"errmsg"` +} + +func (c *Client) Code2Session(code string) (*Session, error) { + if c == nil || c.AppID == utils.StringEmpty || c.Secret == utils.StringEmpty { + return nil, fmt.Errorf("wechat app config missing") + } + if code == utils.StringEmpty { + return nil, fmt.Errorf("wechat code empty") + } + + body, err := utils.Curl(code2SessionURL).SetData(map[string]string{ + "appid": c.AppID, + "secret": c.Secret, + "js_code": code, + "grant_type": "authorization_code", + }).Get("") + if err != nil { + return nil, err + } + + var session Session + if err := jsoniter.UnmarshalFromString(body, &session); err != nil { + return nil, err + } + if session.ErrCode != utils.NumberZero { + return nil, fmt.Errorf("wechat code2session: %d %s", session.ErrCode, session.ErrMsg) + } + if session.OpenID == utils.StringEmpty { + return nil, fmt.Errorf("wechat openid empty") + } + return &session, nil +} diff --git a/pkg/wechat/auth/token.go b/pkg/wechat/auth/token.go new file mode 100644 index 0000000..21078dc --- /dev/null +++ b/pkg/wechat/auth/token.go @@ -0,0 +1,45 @@ +package auth + +import ( + "fmt" + + "lone-services/pkg/utils" + + jsoniter "github.com/json-iterator/go" +) + +const accessTokenURL = "https://api.weixin.qq.com/cgi-bin/token" + +type AccessTokenResult struct { + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` + ErrCode int `json:"errcode"` + ErrMsg string `json:"errmsg"` +} + +func (c *Client) AccessToken() (*AccessTokenResult, error) { + if c == nil || c.AppID == utils.StringEmpty || c.Secret == utils.StringEmpty { + return nil, fmt.Errorf("wechat app config missing") + } + + body, err := utils.Curl(accessTokenURL).SetData(map[string]string{ + "grant_type": "client_credential", + "appid": c.AppID, + "secret": c.Secret, + }).Get("") + if err != nil { + return nil, err + } + + var result AccessTokenResult + if err := jsoniter.UnmarshalFromString(body, &result); err != nil { + return nil, err + } + if result.ErrCode != utils.NumberZero { + return nil, fmt.Errorf("wechat access_token: %d %s", result.ErrCode, result.ErrMsg) + } + if result.AccessToken == utils.StringEmpty { + return nil, fmt.Errorf("wechat access_token empty") + } + return &result, nil +} diff --git a/rpc/sale/pb/sale.pb.go b/rpc/sale/pb/sale.pb.go index a317eb9..1e92daf 100644 --- a/rpc/sale/pb/sale.pb.go +++ b/rpc/sale/pb/sale.pb.go @@ -774,6 +774,50 @@ func (x *InfoReq) GetId() int64 { return 0 } +type InfoByUserIdReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InfoByUserIdReq) Reset() { + *x = InfoByUserIdReq{} + mi := &file_sale_sale_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InfoByUserIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InfoByUserIdReq) ProtoMessage() {} + +func (x *InfoByUserIdReq) ProtoReflect() protoreflect.Message { + mi := &file_sale_sale_proto_msgTypes[10] + 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 InfoByUserIdReq.ProtoReflect.Descriptor instead. +func (*InfoByUserIdReq) Descriptor() ([]byte, []int) { + return file_sale_sale_proto_rawDescGZIP(), []int{10} +} + +func (x *InfoByUserIdReq) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + type Region struct { state protoimpl.MessageState `protogen:"open.v1"` Province string `protobuf:"bytes,1,opt,name=province,proto3" json:"province,omitempty"` @@ -785,7 +829,7 @@ type Region struct { func (x *Region) Reset() { *x = Region{} - mi := &file_sale_sale_proto_msgTypes[10] + mi := &file_sale_sale_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -797,7 +841,7 @@ func (x *Region) String() string { func (*Region) ProtoMessage() {} func (x *Region) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[10] + mi := &file_sale_sale_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -810,7 +854,7 @@ func (x *Region) ProtoReflect() protoreflect.Message { // Deprecated: Use Region.ProtoReflect.Descriptor instead. func (*Region) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{10} + return file_sale_sale_proto_rawDescGZIP(), []int{11} } func (x *Region) GetProvince() string { @@ -844,7 +888,7 @@ type GroupItem struct { func (x *GroupItem) Reset() { *x = GroupItem{} - mi := &file_sale_sale_proto_msgTypes[11] + mi := &file_sale_sale_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -856,7 +900,7 @@ func (x *GroupItem) String() string { func (*GroupItem) ProtoMessage() {} func (x *GroupItem) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[11] + mi := &file_sale_sale_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -869,7 +913,7 @@ func (x *GroupItem) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupItem.ProtoReflect.Descriptor instead. func (*GroupItem) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{11} + return file_sale_sale_proto_rawDescGZIP(), []int{12} } func (x *GroupItem) GetId() int64 { @@ -916,13 +960,14 @@ type InfoData struct { CreateTime string `protobuf:"bytes,26,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` UpdateTime string `protobuf:"bytes,27,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` Group *GroupItem `protobuf:"bytes,28,opt,name=group,proto3" json:"group,omitempty"` + UserId int64 `protobuf:"varint,29,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *InfoData) Reset() { *x = InfoData{} - mi := &file_sale_sale_proto_msgTypes[12] + mi := &file_sale_sale_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -934,7 +979,7 @@ func (x *InfoData) String() string { func (*InfoData) ProtoMessage() {} func (x *InfoData) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[12] + mi := &file_sale_sale_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -947,7 +992,7 @@ func (x *InfoData) ProtoReflect() protoreflect.Message { // Deprecated: Use InfoData.ProtoReflect.Descriptor instead. func (*InfoData) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{12} + return file_sale_sale_proto_rawDescGZIP(), []int{13} } func (x *InfoData) GetId() int64 { @@ -1146,6 +1191,13 @@ func (x *InfoData) GetGroup() *GroupItem { return nil } +func (x *InfoData) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + type ItemsReq struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1160,7 +1212,7 @@ type ItemsReq struct { func (x *ItemsReq) Reset() { *x = ItemsReq{} - mi := &file_sale_sale_proto_msgTypes[13] + mi := &file_sale_sale_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1172,7 +1224,7 @@ func (x *ItemsReq) String() string { func (*ItemsReq) ProtoMessage() {} func (x *ItemsReq) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[13] + mi := &file_sale_sale_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1185,7 +1237,7 @@ func (x *ItemsReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ItemsReq.ProtoReflect.Descriptor instead. func (*ItemsReq) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{13} + return file_sale_sale_proto_rawDescGZIP(), []int{14} } func (x *ItemsReq) GetName() string { @@ -1241,7 +1293,7 @@ type StatusReq struct { func (x *StatusReq) Reset() { *x = StatusReq{} - mi := &file_sale_sale_proto_msgTypes[14] + mi := &file_sale_sale_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1253,7 +1305,7 @@ func (x *StatusReq) String() string { func (*StatusReq) ProtoMessage() {} func (x *StatusReq) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[14] + mi := &file_sale_sale_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1266,7 +1318,7 @@ func (x *StatusReq) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusReq.ProtoReflect.Descriptor instead. func (*StatusReq) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{14} + return file_sale_sale_proto_rawDescGZIP(), []int{15} } func (x *StatusReq) GetId() int64 { @@ -1299,7 +1351,7 @@ type NamesByIdsReq struct { func (x *NamesByIdsReq) Reset() { *x = NamesByIdsReq{} - mi := &file_sale_sale_proto_msgTypes[15] + mi := &file_sale_sale_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1311,7 +1363,7 @@ func (x *NamesByIdsReq) String() string { func (*NamesByIdsReq) ProtoMessage() {} func (x *NamesByIdsReq) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[15] + mi := &file_sale_sale_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1324,7 +1376,7 @@ func (x *NamesByIdsReq) ProtoReflect() protoreflect.Message { // Deprecated: Use NamesByIdsReq.ProtoReflect.Descriptor instead. func (*NamesByIdsReq) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{15} + return file_sale_sale_proto_rawDescGZIP(), []int{16} } func (x *NamesByIdsReq) GetIds() []int64 { @@ -1344,7 +1396,7 @@ type NamesByIdsItem struct { func (x *NamesByIdsItem) Reset() { *x = NamesByIdsItem{} - mi := &file_sale_sale_proto_msgTypes[16] + mi := &file_sale_sale_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1356,7 +1408,7 @@ func (x *NamesByIdsItem) String() string { func (*NamesByIdsItem) ProtoMessage() {} func (x *NamesByIdsItem) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[16] + mi := &file_sale_sale_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1369,7 +1421,7 @@ func (x *NamesByIdsItem) ProtoReflect() protoreflect.Message { // Deprecated: Use NamesByIdsItem.ProtoReflect.Descriptor instead. func (*NamesByIdsItem) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{16} + return file_sale_sale_proto_rawDescGZIP(), []int{17} } func (x *NamesByIdsItem) GetId() int64 { @@ -1395,7 +1447,7 @@ type NamesByIdsData struct { func (x *NamesByIdsData) Reset() { *x = NamesByIdsData{} - mi := &file_sale_sale_proto_msgTypes[17] + mi := &file_sale_sale_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1407,7 +1459,7 @@ func (x *NamesByIdsData) String() string { func (*NamesByIdsData) ProtoMessage() {} func (x *NamesByIdsData) ProtoReflect() protoreflect.Message { - mi := &file_sale_sale_proto_msgTypes[17] + mi := &file_sale_sale_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1420,7 +1472,7 @@ func (x *NamesByIdsData) ProtoReflect() protoreflect.Message { // Deprecated: Use NamesByIdsData.ProtoReflect.Descriptor instead. func (*NamesByIdsData) Descriptor() ([]byte, []int) { - return file_sale_sale_proto_rawDescGZIP(), []int{17} + return file_sale_sale_proto_rawDescGZIP(), []int{18} } func (x *NamesByIdsData) GetItems() []*NamesByIdsItem { @@ -1503,14 +1555,16 @@ const file_sale_sale_proto_rawDesc = "" + "idCardBack\x12)\n" + "\x10business_license\x18\x15 \x01(\tR\x0fbusinessLicense\"\x19\n" + "\aInfoReq\x12\x0e\n" + - "\x02id\x18\x01 \x01(\x03R\x02id\"T\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"*\n" + + "\x0fInfoByUserIdReq\x12\x17\n" + + "\auser_id\x18\x01 \x01(\x03R\x06userId\"T\n" + "\x06Region\x12\x1a\n" + "\bprovince\x18\x01 \x01(\tR\bprovince\x12\x12\n" + "\x04city\x18\x02 \x01(\tR\x04city\x12\x1a\n" + "\bdistrict\x18\x03 \x01(\tR\bdistrict\"/\n" + "\tGroupItem\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + - "\x04name\x18\x02 \x01(\tR\x04name\"\xbf\x06\n" + + "\x04name\x18\x02 \x01(\tR\x04name\"\xd8\x06\n" + "\bInfoData\x12\x0e\n" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x17\n" + "\asale_id\x18\x02 \x01(\x03R\x06saleId\x12\x16\n" + @@ -1547,7 +1601,8 @@ const file_sale_sale_proto_rawDesc = "" + "createTime\x12\x1f\n" + "\vupdate_time\x18\x1b \x01(\tR\n" + "updateTime\x12%\n" + - "\x05group\x18\x1c \x01(\v2\x0f.sale.GroupItemR\x05group\"\x94\x01\n" + + "\x05group\x18\x1c \x01(\v2\x0f.sale.GroupItemR\x05group\x12\x17\n" + + "\auser_id\x18\x1d \x01(\x03R\x06userId\"\x94\x01\n" + "\bItemsReq\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + "\x04page\x18\x02 \x01(\rR\x04page\x12\x1b\n" + @@ -1565,7 +1620,7 @@ const file_sale_sale_proto_rawDesc = "" + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\"<\n" + "\x0eNamesByIdsData\x12*\n" + - "\x05items\x18\x01 \x03(\v2\x14.sale.NamesByIdsItemR\x05items2\xa7\a\n" + + "\x05items\x18\x01 \x03(\v2\x14.sale.NamesByIdsItemR\x05items2\xde\a\n" + "\x04Sale\x12S\n" + "\n" + "GroupItems\x12\x13.sale.GroupItemsReq\x1a\x0e.sale.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\x12\x15/admin/v3/sales/group\x12U\n" + @@ -1580,7 +1635,8 @@ const file_sale_sale_proto_rawDesc = "" + "\x04Info\x12\r.sale.InfoReq\x1a\x0e.sale.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/sales/info\x12C\n" + "\x05Items\x12\x0e.sale.ItemsReq\x1a\x0e.sale.Response\"\x1a\x82\xd3\xe4\x93\x02\x14:\x01*\x12\x0f/admin/v3/sales\x12L\n" + "\x06Status\x12\x0f.sale.StatusReq\x1a\x0e.sale.Response\"!\x82\xd3\xe4\x93\x02\x1b:\x01*\x1a\x16/admin/v3/sales/status\x12-\n" + - "\fInfoInternal\x12\r.sale.InfoReq\x1a\x0e.sale.InfoData\x127\n" + + "\fInfoInternal\x12\r.sale.InfoReq\x1a\x0e.sale.InfoData\x125\n" + + "\fInfoByUserId\x12\x15.sale.InfoByUserIdReq\x1a\x0e.sale.InfoData\x127\n" + "\n" + "NamesByIds\x12\x13.sale.NamesByIdsReq\x1a\x14.sale.NamesByIdsDataB\x18Z\x16lone-services/rpc/saleb\x06proto3" @@ -1596,32 +1652,33 @@ func file_sale_sale_proto_rawDescGZIP() []byte { return file_sale_sale_proto_rawDescData } -var file_sale_sale_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_sale_sale_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_sale_sale_proto_goTypes = []any{ - (*Response)(nil), // 0: sale.Response - (*GroupEmptyReq)(nil), // 1: sale.GroupEmptyReq - (*GroupItemsReq)(nil), // 2: sale.GroupItemsReq - (*GroupCreateReq)(nil), // 3: sale.GroupCreateReq - (*NamesReq)(nil), // 4: sale.NamesReq - (*NameItem)(nil), // 5: sale.NameItem - (*NamesData)(nil), // 6: sale.NamesData - (*CreateReq)(nil), // 7: sale.CreateReq - (*EditReq)(nil), // 8: sale.EditReq - (*InfoReq)(nil), // 9: sale.InfoReq - (*Region)(nil), // 10: sale.Region - (*GroupItem)(nil), // 11: sale.GroupItem - (*InfoData)(nil), // 12: sale.InfoData - (*ItemsReq)(nil), // 13: sale.ItemsReq - (*StatusReq)(nil), // 14: sale.StatusReq - (*NamesByIdsReq)(nil), // 15: sale.NamesByIdsReq - (*NamesByIdsItem)(nil), // 16: sale.NamesByIdsItem - (*NamesByIdsData)(nil), // 17: sale.NamesByIdsData + (*Response)(nil), // 0: sale.Response + (*GroupEmptyReq)(nil), // 1: sale.GroupEmptyReq + (*GroupItemsReq)(nil), // 2: sale.GroupItemsReq + (*GroupCreateReq)(nil), // 3: sale.GroupCreateReq + (*NamesReq)(nil), // 4: sale.NamesReq + (*NameItem)(nil), // 5: sale.NameItem + (*NamesData)(nil), // 6: sale.NamesData + (*CreateReq)(nil), // 7: sale.CreateReq + (*EditReq)(nil), // 8: sale.EditReq + (*InfoReq)(nil), // 9: sale.InfoReq + (*InfoByUserIdReq)(nil), // 10: sale.InfoByUserIdReq + (*Region)(nil), // 11: sale.Region + (*GroupItem)(nil), // 12: sale.GroupItem + (*InfoData)(nil), // 13: sale.InfoData + (*ItemsReq)(nil), // 14: sale.ItemsReq + (*StatusReq)(nil), // 15: sale.StatusReq + (*NamesByIdsReq)(nil), // 16: sale.NamesByIdsReq + (*NamesByIdsItem)(nil), // 17: sale.NamesByIdsItem + (*NamesByIdsData)(nil), // 18: sale.NamesByIdsData } var file_sale_sale_proto_depIdxs = []int32{ 5, // 0: sale.NamesData.items:type_name -> sale.NameItem - 10, // 1: sale.InfoData.region:type_name -> sale.Region - 11, // 2: sale.InfoData.group:type_name -> sale.GroupItem - 16, // 3: sale.NamesByIdsData.items:type_name -> sale.NamesByIdsItem + 11, // 1: sale.InfoData.region:type_name -> sale.Region + 12, // 2: sale.InfoData.group:type_name -> sale.GroupItem + 17, // 3: sale.NamesByIdsData.items:type_name -> sale.NamesByIdsItem 2, // 4: sale.Sale.GroupItems:input_type -> sale.GroupItemsReq 3, // 5: sale.Sale.GroupCreate:input_type -> sale.GroupCreateReq 1, // 6: sale.Sale.GroupNames:input_type -> sale.GroupEmptyReq @@ -1631,25 +1688,27 @@ var file_sale_sale_proto_depIdxs = []int32{ 7, // 10: sale.Sale.Create:input_type -> sale.CreateReq 8, // 11: sale.Sale.Edit:input_type -> sale.EditReq 9, // 12: sale.Sale.Info:input_type -> sale.InfoReq - 13, // 13: sale.Sale.Items:input_type -> sale.ItemsReq - 14, // 14: sale.Sale.Status:input_type -> sale.StatusReq + 14, // 13: sale.Sale.Items:input_type -> sale.ItemsReq + 15, // 14: sale.Sale.Status:input_type -> sale.StatusReq 9, // 15: sale.Sale.InfoInternal:input_type -> sale.InfoReq - 15, // 16: sale.Sale.NamesByIds:input_type -> sale.NamesByIdsReq - 0, // 17: sale.Sale.GroupItems:output_type -> sale.Response - 0, // 18: sale.Sale.GroupCreate:output_type -> sale.Response - 0, // 19: sale.Sale.GroupNames:output_type -> sale.Response - 0, // 20: sale.Sale.Types:output_type -> sale.Response - 0, // 21: sale.Sale.Names:output_type -> sale.Response - 6, // 22: sale.Sale.NamesInternal:output_type -> sale.NamesData - 0, // 23: sale.Sale.Create:output_type -> sale.Response - 0, // 24: sale.Sale.Edit:output_type -> sale.Response - 0, // 25: sale.Sale.Info:output_type -> sale.Response - 0, // 26: sale.Sale.Items:output_type -> sale.Response - 0, // 27: sale.Sale.Status:output_type -> sale.Response - 12, // 28: sale.Sale.InfoInternal:output_type -> sale.InfoData - 17, // 29: sale.Sale.NamesByIds:output_type -> sale.NamesByIdsData - 17, // [17:30] is the sub-list for method output_type - 4, // [4:17] is the sub-list for method input_type + 10, // 16: sale.Sale.InfoByUserId:input_type -> sale.InfoByUserIdReq + 16, // 17: sale.Sale.NamesByIds:input_type -> sale.NamesByIdsReq + 0, // 18: sale.Sale.GroupItems:output_type -> sale.Response + 0, // 19: sale.Sale.GroupCreate:output_type -> sale.Response + 0, // 20: sale.Sale.GroupNames:output_type -> sale.Response + 0, // 21: sale.Sale.Types:output_type -> sale.Response + 0, // 22: sale.Sale.Names:output_type -> sale.Response + 6, // 23: sale.Sale.NamesInternal:output_type -> sale.NamesData + 0, // 24: sale.Sale.Create:output_type -> sale.Response + 0, // 25: sale.Sale.Edit:output_type -> sale.Response + 0, // 26: sale.Sale.Info:output_type -> sale.Response + 0, // 27: sale.Sale.Items:output_type -> sale.Response + 0, // 28: sale.Sale.Status:output_type -> sale.Response + 13, // 29: sale.Sale.InfoInternal:output_type -> sale.InfoData + 13, // 30: sale.Sale.InfoByUserId:output_type -> sale.InfoData + 18, // 31: sale.Sale.NamesByIds:output_type -> sale.NamesByIdsData + 18, // [18:32] is the sub-list for method output_type + 4, // [4:18] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name 4, // [4:4] is the sub-list for extension extendee 0, // [0:4] is the sub-list for field type_name @@ -1666,7 +1725,7 @@ func file_sale_sale_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_sale_sale_proto_rawDesc), len(file_sale_sale_proto_rawDesc)), NumEnums: 0, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/sale/pb/sale_grpc.pb.go b/rpc/sale/pb/sale_grpc.pb.go index 0cdbecf..ed375a6 100644 --- a/rpc/sale/pb/sale_grpc.pb.go +++ b/rpc/sale/pb/sale_grpc.pb.go @@ -31,6 +31,7 @@ const ( Sale_Items_FullMethodName = "/sale.Sale/Items" Sale_Status_FullMethodName = "/sale.Sale/Status" Sale_InfoInternal_FullMethodName = "/sale.Sale/InfoInternal" + Sale_InfoByUserId_FullMethodName = "/sale.Sale/InfoByUserId" Sale_NamesByIds_FullMethodName = "/sale.Sale/NamesByIds" ) @@ -53,7 +54,9 @@ type SaleClient interface { Status(ctx context.Context, in *StatusReq, opts ...grpc.CallOption) (*Response, error) // 销售详情 InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) - // 按 id 批量查销售 id+name(内部) + // 按 user_id 查销售详情(内部) + InfoByUserId(ctx context.Context, in *InfoByUserIdReq, opts ...grpc.CallOption) (*InfoData, error) + // ids 批量查销售 NamesByIds(ctx context.Context, in *NamesByIdsReq, opts ...grpc.CallOption) (*NamesByIdsData, error) } @@ -185,6 +188,16 @@ func (c *saleClient) InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc return out, nil } +func (c *saleClient) InfoByUserId(ctx context.Context, in *InfoByUserIdReq, opts ...grpc.CallOption) (*InfoData, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InfoData) + err := c.cc.Invoke(ctx, Sale_InfoByUserId_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *saleClient) NamesByIds(ctx context.Context, in *NamesByIdsReq, opts ...grpc.CallOption) (*NamesByIdsData, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(NamesByIdsData) @@ -214,7 +227,9 @@ type SaleServer interface { Status(context.Context, *StatusReq) (*Response, error) // 销售详情 InfoInternal(context.Context, *InfoReq) (*InfoData, error) - // 按 id 批量查销售 id+name(内部) + // 按 user_id 查销售详情(内部) + InfoByUserId(context.Context, *InfoByUserIdReq) (*InfoData, error) + // ids 批量查销售 NamesByIds(context.Context, *NamesByIdsReq) (*NamesByIdsData, error) mustEmbedUnimplementedSaleServer() } @@ -262,6 +277,9 @@ func (UnimplementedSaleServer) Status(context.Context, *StatusReq) (*Response, e func (UnimplementedSaleServer) InfoInternal(context.Context, *InfoReq) (*InfoData, error) { return nil, status.Error(codes.Unimplemented, "method InfoInternal not implemented") } +func (UnimplementedSaleServer) InfoByUserId(context.Context, *InfoByUserIdReq) (*InfoData, error) { + return nil, status.Error(codes.Unimplemented, "method InfoByUserId not implemented") +} func (UnimplementedSaleServer) NamesByIds(context.Context, *NamesByIdsReq) (*NamesByIdsData, error) { return nil, status.Error(codes.Unimplemented, "method NamesByIds not implemented") } @@ -502,6 +520,24 @@ func _Sale_InfoInternal_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Sale_InfoByUserId_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InfoByUserIdReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SaleServer).InfoByUserId(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Sale_InfoByUserId_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SaleServer).InfoByUserId(ctx, req.(*InfoByUserIdReq)) + } + return interceptor(ctx, in, info, handler) +} + func _Sale_NamesByIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(NamesByIdsReq) if err := dec(in); err != nil { @@ -575,6 +611,10 @@ var Sale_ServiceDesc = grpc.ServiceDesc{ MethodName: "InfoInternal", Handler: _Sale_InfoInternal_Handler, }, + { + MethodName: "InfoByUserId", + Handler: _Sale_InfoByUserId_Handler, + }, { MethodName: "NamesByIds", Handler: _Sale_NamesByIds_Handler, diff --git a/rpc/sale/sale.pb b/rpc/sale/sale.pb index dfad0f3..ad77b67 100644 Binary files a/rpc/sale/sale.pb and b/rpc/sale/sale.pb differ diff --git a/rpc/sale/sale.proto b/rpc/sale/sale.proto index b57db00..cb1b34b 100644 --- a/rpc/sale/sale.proto +++ b/rpc/sale/sale.proto @@ -72,6 +72,8 @@ service Sale { // 销售详情 rpc InfoInternal(InfoReq) returns (InfoData); + // 按 user_id 查销售详情(内部) + rpc InfoByUserId(InfoByUserIdReq) returns (InfoData); // ids 批量查销售 rpc NamesByIds(NamesByIdsReq) returns (NamesByIdsData); } @@ -154,6 +156,10 @@ message InfoReq { int64 id = 1; } +message InfoByUserIdReq { + int64 user_id = 1; +} + message Region { string province = 1; string city = 2; @@ -194,6 +200,7 @@ message InfoData { string create_time = 26; string update_time = 27; GroupItem group = 28; + int64 user_id = 29; } message ItemsReq { diff --git a/rpc/user/pb/user.pb.go b/rpc/user/pb/user.pb.go index 73d4023..03be1f0 100644 --- a/rpc/user/pb/user.pb.go +++ b/rpc/user/pb/user.pb.go @@ -7,13 +7,12 @@ package user import ( - reflect "reflect" - sync "sync" - unsafe "unsafe" - _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" ) const ( @@ -83,195 +82,22 @@ func (x *Response) GetData() string { return "" } -// 小程序注册 -type RegisterReq struct { - state protoimpl.MessageState `protogen:"open.v1"` - Openid string `protobuf:"bytes,1,opt,name=openid,proto3" json:"openid,omitempty"` // 可空;空则服务端模拟 - 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_user_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_user_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_user_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 -} - -// 账号密码注册 -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_user_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_user_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_user_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 登录 +// 统一登录:grant_type = openid | password | sms type LoginReq struct { state protoimpl.MessageState `protogen:"open.v1"` - Openid string `protobuf:"bytes,1,opt,name=openid,proto3" json:"openid,omitempty"` + ClientCode string `protobuf:"bytes,1,opt,name=client_code,json=clientCode,proto3" json:"client_code,omitempty"` // 端编码,如 user_skin / user_o2 / sale_beauty + GrantType string `protobuf:"bytes,2,opt,name=grant_type,json=grantType,proto3" json:"grant_type,omitempty"` // openid | password | sms + Code string `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"` // grant_type=openid 时传微信 login code + Mobile string `protobuf:"bytes,4,opt,name=mobile,proto3" json:"mobile,omitempty"` // grant_type=password|sms + Password string `protobuf:"bytes,5,opt,name=password,proto3" json:"password,omitempty"` // grant_type=password + SmsCode string `protobuf:"bytes,6,opt,name=sms_code,json=smsCode,proto3" json:"sms_code,omitempty"` // grant_type=sms unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *LoginReq) Reset() { *x = LoginReq{} - mi := &file_user_user_proto_msgTypes[3] + mi := &file_user_user_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -283,7 +109,7 @@ func (x *LoginReq) String() string { func (*LoginReq) ProtoMessage() {} func (x *LoginReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[3] + mi := &file_user_user_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -296,12 +122,47 @@ func (x *LoginReq) ProtoReflect() protoreflect.Message { // Deprecated: Use LoginReq.ProtoReflect.Descriptor instead. func (*LoginReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{3} + return file_user_user_proto_rawDescGZIP(), []int{1} } -func (x *LoginReq) GetOpenid() string { +func (x *LoginReq) GetClientCode() string { if x != nil { - return x.Openid + return x.ClientCode + } + return "" +} + +func (x *LoginReq) GetGrantType() string { + if x != nil { + return x.GrantType + } + return "" +} + +func (x *LoginReq) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *LoginReq) GetMobile() string { + if x != nil { + return x.Mobile + } + return "" +} + +func (x *LoginReq) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *LoginReq) GetSmsCode() string { + if x != nil { + return x.SmsCode } return "" } @@ -318,7 +179,7 @@ type UserItemsReq struct { func (x *UserItemsReq) Reset() { *x = UserItemsReq{} - mi := &file_user_user_proto_msgTypes[4] + mi := &file_user_user_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -330,7 +191,7 @@ func (x *UserItemsReq) String() string { func (*UserItemsReq) ProtoMessage() {} func (x *UserItemsReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[4] + mi := &file_user_user_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -343,7 +204,7 @@ func (x *UserItemsReq) ProtoReflect() protoreflect.Message { // Deprecated: Use UserItemsReq.ProtoReflect.Descriptor instead. func (*UserItemsReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{4} + return file_user_user_proto_rawDescGZIP(), []int{2} } func (x *UserItemsReq) GetMobile() string { @@ -378,7 +239,7 @@ type UserStatusReq struct { func (x *UserStatusReq) Reset() { *x = UserStatusReq{} - mi := &file_user_user_proto_msgTypes[5] + mi := &file_user_user_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -390,7 +251,7 @@ func (x *UserStatusReq) String() string { func (*UserStatusReq) ProtoMessage() {} func (x *UserStatusReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[5] + mi := &file_user_user_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -403,7 +264,7 @@ func (x *UserStatusReq) ProtoReflect() protoreflect.Message { // Deprecated: Use UserStatusReq.ProtoReflect.Descriptor instead. func (*UserStatusReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{5} + return file_user_user_proto_rawDescGZIP(), []int{3} } func (x *UserStatusReq) GetId() int64 { @@ -427,17 +288,17 @@ type EnsureBizIdentityReq struct { Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` Gender uint32 `protobuf:"varint,4,opt,name=gender,proto3" json:"gender,omitempty"` Birthday string `protobuf:"bytes,5,opt,name=birthday,proto3" json:"birthday,omitempty"` - ClientCode string `protobuf:"bytes,6,opt,name=client_code,json=clientCode,proto3" json:"client_code,omitempty"` // 如 sale_beauty / store_beauty / store_pos - CredentialType string `protobuf:"bytes,7,opt,name=credential_type,json=credentialType,proto3" json:"credential_type,omitempty"` // password / wecom / openid ... - Identifier string `protobuf:"bytes,8,opt,name=identifier,proto3" json:"identifier,omitempty"` // 登录标识;空则默认用手机号 - Secret string `protobuf:"bytes,9,opt,name=secret,proto3" json:"secret,omitempty"` // 密码明文等,服务端哈希后入库 + ClientCode string `protobuf:"bytes,6,opt,name=client_code,json=clientCode,proto3" json:"client_code,omitempty"` + CredentialType string `protobuf:"bytes,7,opt,name=credential_type,json=credentialType,proto3" json:"credential_type,omitempty"` + Identifier string `protobuf:"bytes,8,opt,name=identifier,proto3" json:"identifier,omitempty"` + Secret string `protobuf:"bytes,9,opt,name=secret,proto3" json:"secret,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *EnsureBizIdentityReq) Reset() { *x = EnsureBizIdentityReq{} - mi := &file_user_user_proto_msgTypes[6] + mi := &file_user_user_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -449,7 +310,7 @@ func (x *EnsureBizIdentityReq) String() string { func (*EnsureBizIdentityReq) ProtoMessage() {} func (x *EnsureBizIdentityReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[6] + mi := &file_user_user_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -460,8 +321,9 @@ func (x *EnsureBizIdentityReq) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } +// Deprecated: Use EnsureBizIdentityReq.ProtoReflect.Descriptor instead. func (*EnsureBizIdentityReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{6} + return file_user_user_proto_rawDescGZIP(), []int{4} } func (x *EnsureBizIdentityReq) GetMobile() string { @@ -530,7 +392,7 @@ func (x *EnsureBizIdentityReq) GetSecret() string { type EnsureBizIdentityData struct { state protoimpl.MessageState `protogen:"open.v1"` UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - Created bool `protobuf:"varint,2,opt,name=created,proto3" json:"created,omitempty"` // 是否新建了 users + Created bool `protobuf:"varint,2,opt,name=created,proto3" json:"created,omitempty"` Mobile string `protobuf:"bytes,3,opt,name=mobile,proto3" json:"mobile,omitempty"` Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` unknownFields protoimpl.UnknownFields @@ -539,7 +401,7 @@ type EnsureBizIdentityData struct { func (x *EnsureBizIdentityData) Reset() { *x = EnsureBizIdentityData{} - mi := &file_user_user_proto_msgTypes[7] + mi := &file_user_user_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -551,7 +413,7 @@ func (x *EnsureBizIdentityData) String() string { func (*EnsureBizIdentityData) ProtoMessage() {} func (x *EnsureBizIdentityData) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[7] + mi := &file_user_user_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -564,7 +426,7 @@ func (x *EnsureBizIdentityData) ProtoReflect() protoreflect.Message { // Deprecated: Use EnsureBizIdentityData.ProtoReflect.Descriptor instead. func (*EnsureBizIdentityData) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{7} + return file_user_user_proto_rawDescGZIP(), []int{5} } func (x *EnsureBizIdentityData) GetUserId() int64 { @@ -595,7 +457,6 @@ func (x *EnsureBizIdentityData) GetName() string { return "" } -// 内部:按 ids 批量查用户基础信息 type UsersByIdsReq struct { state protoimpl.MessageState `protogen:"open.v1"` Ids []int64 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids,omitempty"` @@ -605,7 +466,7 @@ type UsersByIdsReq struct { func (x *UsersByIdsReq) Reset() { *x = UsersByIdsReq{} - mi := &file_user_user_proto_msgTypes[8] + mi := &file_user_user_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -617,7 +478,7 @@ func (x *UsersByIdsReq) String() string { func (*UsersByIdsReq) ProtoMessage() {} func (x *UsersByIdsReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[8] + mi := &file_user_user_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -630,7 +491,7 @@ func (x *UsersByIdsReq) ProtoReflect() protoreflect.Message { // Deprecated: Use UsersByIdsReq.ProtoReflect.Descriptor instead. func (*UsersByIdsReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{8} + return file_user_user_proto_rawDescGZIP(), []int{6} } func (x *UsersByIdsReq) GetIds() []int64 { @@ -655,7 +516,7 @@ type UserBriefItem struct { func (x *UserBriefItem) Reset() { *x = UserBriefItem{} - mi := &file_user_user_proto_msgTypes[9] + mi := &file_user_user_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -667,7 +528,7 @@ func (x *UserBriefItem) String() string { func (*UserBriefItem) ProtoMessage() {} func (x *UserBriefItem) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[9] + mi := &file_user_user_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -680,7 +541,7 @@ func (x *UserBriefItem) ProtoReflect() protoreflect.Message { // Deprecated: Use UserBriefItem.ProtoReflect.Descriptor instead. func (*UserBriefItem) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{9} + return file_user_user_proto_rawDescGZIP(), []int{7} } func (x *UserBriefItem) GetId() int64 { @@ -741,7 +602,7 @@ type UsersByIdsData struct { func (x *UsersByIdsData) Reset() { *x = UsersByIdsData{} - mi := &file_user_user_proto_msgTypes[10] + mi := &file_user_user_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -753,7 +614,7 @@ func (x *UsersByIdsData) String() string { func (*UsersByIdsData) ProtoMessage() {} func (x *UsersByIdsData) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[10] + mi := &file_user_user_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -766,7 +627,7 @@ func (x *UsersByIdsData) ProtoReflect() protoreflect.Message { // Deprecated: Use UsersByIdsData.ProtoReflect.Descriptor instead. func (*UsersByIdsData) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{10} + return file_user_user_proto_rawDescGZIP(), []int{8} } func (x *UsersByIdsData) GetItems() []*UserBriefItem { @@ -776,18 +637,17 @@ func (x *UsersByIdsData) GetItems() []*UserBriefItem { return nil } -// 内部:修改用户手机号(同步凭证 identifier) type UpdateMobileReq struct { state protoimpl.MessageState `protogen:"open.v1"` UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - Mobile string `protobuf:"bytes,2,opt,name=mobile,proto3" json:"mobile,omitempty"` // 新手机号明文 + Mobile string `protobuf:"bytes,2,opt,name=mobile,proto3" json:"mobile,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *UpdateMobileReq) Reset() { *x = UpdateMobileReq{} - mi := &file_user_user_proto_msgTypes[11] + mi := &file_user_user_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -799,7 +659,7 @@ func (x *UpdateMobileReq) String() string { func (*UpdateMobileReq) ProtoMessage() {} func (x *UpdateMobileReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[11] + mi := &file_user_user_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -812,7 +672,7 @@ func (x *UpdateMobileReq) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateMobileReq.ProtoReflect.Descriptor instead. func (*UpdateMobileReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{11} + return file_user_user_proto_rawDescGZIP(), []int{9} } func (x *UpdateMobileReq) GetUserId() int64 { @@ -832,14 +692,14 @@ func (x *UpdateMobileReq) GetMobile() string { type UpdateMobileData struct { state protoimpl.MessageState `protogen:"open.v1"` UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - Mobile string `protobuf:"bytes,2,opt,name=mobile,proto3" json:"mobile,omitempty"` // 加密后手机号 + Mobile string `protobuf:"bytes,2,opt,name=mobile,proto3" json:"mobile,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *UpdateMobileData) Reset() { *x = UpdateMobileData{} - mi := &file_user_user_proto_msgTypes[12] + mi := &file_user_user_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -851,7 +711,7 @@ func (x *UpdateMobileData) String() string { func (*UpdateMobileData) ProtoMessage() {} func (x *UpdateMobileData) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[12] + mi := &file_user_user_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -864,7 +724,7 @@ func (x *UpdateMobileData) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateMobileData.ProtoReflect.Descriptor instead. func (*UpdateMobileData) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{12} + return file_user_user_proto_rawDescGZIP(), []int{10} } func (x *UpdateMobileData) GetUserId() int64 { @@ -881,7 +741,6 @@ func (x *UpdateMobileData) GetMobile() string { return "" } -// 内部:撤销业务端开通(删除/禁用销售或门店时) type RevokeBizClientReq struct { state protoimpl.MessageState `protogen:"open.v1"` UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` @@ -892,7 +751,7 @@ type RevokeBizClientReq struct { func (x *RevokeBizClientReq) Reset() { *x = RevokeBizClientReq{} - mi := &file_user_user_proto_msgTypes[13] + mi := &file_user_user_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -904,7 +763,7 @@ func (x *RevokeBizClientReq) String() string { func (*RevokeBizClientReq) ProtoMessage() {} func (x *RevokeBizClientReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[13] + mi := &file_user_user_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -917,7 +776,7 @@ func (x *RevokeBizClientReq) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeBizClientReq.ProtoReflect.Descriptor instead. func (*RevokeBizClientReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{13} + return file_user_user_proto_rawDescGZIP(), []int{11} } func (x *RevokeBizClientReq) GetUserId() int64 { @@ -943,7 +802,7 @@ type RevokeBizClientData struct { func (x *RevokeBizClientData) Reset() { *x = RevokeBizClientData{} - mi := &file_user_user_proto_msgTypes[14] + mi := &file_user_user_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -955,7 +814,7 @@ func (x *RevokeBizClientData) String() string { func (*RevokeBizClientData) ProtoMessage() {} func (x *RevokeBizClientData) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[14] + mi := &file_user_user_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -968,7 +827,7 @@ func (x *RevokeBizClientData) ProtoReflect() protoreflect.Message { // Deprecated: Use RevokeBizClientData.ProtoReflect.Descriptor instead. func (*RevokeBizClientData) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{14} + return file_user_user_proto_rawDescGZIP(), []int{12} } func (x *RevokeBizClientData) GetRevoked() bool { @@ -978,6 +837,42 @@ func (x *RevokeBizClientData) GetRevoked() bool { return false } +type InfoReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InfoReq) Reset() { + *x = InfoReq{} + mi := &file_user_user_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InfoReq) ProtoMessage() {} + +func (x *InfoReq) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[13] + 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 InfoReq.ProtoReflect.Descriptor instead. +func (*InfoReq) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{13} +} + var File_user_user_proto protoreflect.FileDescriptor const file_user_user_proto_rawDesc = "" + @@ -986,24 +881,16 @@ const file_user_user_proto_rawDesc = "" + "\bResponse\x12\x12\n" + "\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\x06openid\"N\n" + + "\x04data\x18\x03 \x01(\tR\x04data\"\xad\x01\n" + + "\bLoginReq\x12\x1f\n" + + "\vclient_code\x18\x01 \x01(\tR\n" + + "clientCode\x12\x1d\n" + + "\n" + + "grant_type\x18\x02 \x01(\tR\tgrantType\x12\x12\n" + + "\x04code\x18\x03 \x01(\tR\x04code\x12\x16\n" + + "\x06mobile\x18\x04 \x01(\tR\x06mobile\x12\x1a\n" + + "\bpassword\x18\x05 \x01(\tR\bpassword\x12\x19\n" + + "\bsms_code\x18\x06 \x01(\tR\asmsCode\"N\n" + "\fUserItemsReq\x12\x16\n" + "\x06mobile\x18\x01 \x01(\tR\x06mobile\x12\x12\n" + "\x04page\x18\x02 \x01(\x05R\x04page\x12\x12\n" + @@ -1052,11 +939,11 @@ const file_user_user_proto_rawDesc = "" + "\vclient_code\x18\x02 \x01(\tR\n" + "clientCode\"/\n" + "\x13RevokeBizClientData\x12\x18\n" + - "\arevoked\x18\x01 \x01(\bR\arevoked2\xb6\x05\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/login\x12P\n" + + "\arevoked\x18\x01 \x01(\bR\arevoked\"\t\n" + + "\aInfoReq2\xc3\x04\n" + + "\x04User\x12A\n" + + "\x05Login\x12\x0e.user.LoginReq\x1a\x0e.user.Response\"\x18\x82\xd3\xe4\x93\x02\x12:\x01*\"\r/api/v3/login\x12C\n" + + "\x04Info\x12\r.user.InfoReq\x1a\x0e.user.Response\"\x1c\x82\xd3\xe4\x93\x02\x16:\x01*\x12\x11/api/v3/user/info\x12P\n" + "\tUserItems\x12\x12.user.UserItemsReq\x1a\x0e.user.Response\"\x1f\x82\xd3\xe4\x93\x02\x19:\x01*\x12\x14/admin/v3/user/items\x12S\n" + "\n" + "UserStatus\x12\x13.user.UserStatusReq\x1a\x0e.user.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\x1a\x15/admin/v3/user/status\x12L\n" + @@ -1078,46 +965,43 @@ func file_user_user_proto_rawDescGZIP() []byte { return file_user_user_proto_rawDescData } -var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_user_user_proto_goTypes = []any{ (*Response)(nil), // 0: user.Response - (*RegisterReq)(nil), // 1: user.RegisterReq - (*RegisterByUserReq)(nil), // 2: user.RegisterByUserReq - (*LoginReq)(nil), // 3: user.LoginReq - (*UserItemsReq)(nil), // 4: user.UserItemsReq - (*UserStatusReq)(nil), // 5: user.UserStatusReq - (*EnsureBizIdentityReq)(nil), // 6: user.EnsureBizIdentityReq - (*EnsureBizIdentityData)(nil), // 7: user.EnsureBizIdentityData - (*UsersByIdsReq)(nil), // 8: user.UsersByIdsReq - (*UserBriefItem)(nil), // 9: user.UserBriefItem - (*UsersByIdsData)(nil), // 10: user.UsersByIdsData - (*UpdateMobileReq)(nil), // 11: user.UpdateMobileReq - (*UpdateMobileData)(nil), // 12: user.UpdateMobileData - (*RevokeBizClientReq)(nil), // 13: user.RevokeBizClientReq - (*RevokeBizClientData)(nil), // 14: user.RevokeBizClientData + (*LoginReq)(nil), // 1: user.LoginReq + (*UserItemsReq)(nil), // 2: user.UserItemsReq + (*UserStatusReq)(nil), // 3: user.UserStatusReq + (*EnsureBizIdentityReq)(nil), // 4: user.EnsureBizIdentityReq + (*EnsureBizIdentityData)(nil), // 5: user.EnsureBizIdentityData + (*UsersByIdsReq)(nil), // 6: user.UsersByIdsReq + (*UserBriefItem)(nil), // 7: user.UserBriefItem + (*UsersByIdsData)(nil), // 8: user.UsersByIdsData + (*UpdateMobileReq)(nil), // 9: user.UpdateMobileReq + (*UpdateMobileData)(nil), // 10: user.UpdateMobileData + (*RevokeBizClientReq)(nil), // 11: user.RevokeBizClientReq + (*RevokeBizClientData)(nil), // 12: user.RevokeBizClientData + (*InfoReq)(nil), // 13: user.InfoReq } var file_user_user_proto_depIdxs = []int32{ - 9, // 0: user.UsersByIdsData.items:type_name -> user.UserBriefItem - 1, // 1: user.User.Register:input_type -> user.RegisterReq - 2, // 2: user.User.RegisterByUser:input_type -> user.RegisterByUserReq - 3, // 3: user.User.Login:input_type -> user.LoginReq - 4, // 4: user.User.UserItems:input_type -> user.UserItemsReq - 5, // 5: user.User.UserStatus:input_type -> user.UserStatusReq - 6, // 6: user.User.EnsureBizIdentity:input_type -> user.EnsureBizIdentityReq - 8, // 7: user.User.UsersByIds:input_type -> user.UsersByIdsReq - 11, // 8: user.User.UpdateMobile:input_type -> user.UpdateMobileReq - 13, // 9: user.User.RevokeBizClient:input_type -> user.RevokeBizClientReq - 0, // 10: user.User.Register:output_type -> user.Response - 0, // 11: user.User.RegisterByUser:output_type -> user.Response - 0, // 12: user.User.Login:output_type -> user.Response - 0, // 13: user.User.UserItems:output_type -> user.Response - 0, // 14: user.User.UserStatus:output_type -> user.Response - 7, // 15: user.User.EnsureBizIdentity:output_type -> user.EnsureBizIdentityData - 10, // 16: user.User.UsersByIds:output_type -> user.UsersByIdsData - 12, // 17: user.User.UpdateMobile:output_type -> user.UpdateMobileData - 14, // 18: user.User.RevokeBizClient:output_type -> user.RevokeBizClientData - 10, // [10:19] is the sub-list for method output_type - 1, // [1:10] is the sub-list for method input_type + 7, // 0: user.UsersByIdsData.items:type_name -> user.UserBriefItem + 1, // 1: user.User.Login:input_type -> user.LoginReq + 13, // 2: user.User.Info:input_type -> user.InfoReq + 2, // 3: user.User.UserItems:input_type -> user.UserItemsReq + 3, // 4: user.User.UserStatus:input_type -> user.UserStatusReq + 4, // 5: user.User.EnsureBizIdentity:input_type -> user.EnsureBizIdentityReq + 6, // 6: user.User.UsersByIds:input_type -> user.UsersByIdsReq + 9, // 7: user.User.UpdateMobile:input_type -> user.UpdateMobileReq + 11, // 8: user.User.RevokeBizClient:input_type -> user.RevokeBizClientReq + 0, // 9: user.User.Login:output_type -> user.Response + 0, // 10: user.User.Info:output_type -> user.Response + 0, // 11: user.User.UserItems:output_type -> user.Response + 0, // 12: user.User.UserStatus:output_type -> user.Response + 5, // 13: user.User.EnsureBizIdentity:output_type -> user.EnsureBizIdentityData + 8, // 14: user.User.UsersByIds:output_type -> user.UsersByIdsData + 10, // 15: user.User.UpdateMobile:output_type -> user.UpdateMobileData + 12, // 16: user.User.RevokeBizClient:output_type -> user.RevokeBizClientData + 9, // [9:17] is the sub-list for method output_type + 1, // [1:9] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name 1, // [1:1] is the sub-list for extension extendee 0, // [0:1] is the sub-list for field type_name @@ -1134,7 +1018,7 @@ func file_user_user_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_user_user_proto_rawDesc), len(file_user_user_proto_rawDesc)), NumEnums: 0, - NumMessages: 15, + NumMessages: 14, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/user/pb/user_grpc.pb.go b/rpc/user/pb/user_grpc.pb.go index fa25b04..063ab4a 100644 --- a/rpc/user/pb/user_grpc.pb.go +++ b/rpc/user/pb/user_grpc.pb.go @@ -19,9 +19,8 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - User_Register_FullMethodName = "/user.User/Register" - User_RegisterByUser_FullMethodName = "/user.User/RegisterByUser" User_Login_FullMethodName = "/user.User/Login" + User_Info_FullMethodName = "/user.User/Info" User_UserItems_FullMethodName = "/user.User/UserItems" User_UserStatus_FullMethodName = "/user.User/UserStatus" User_EnsureBizIdentity_FullMethodName = "/user.User/EnsureBizIdentity" @@ -34,18 +33,13 @@ const ( // // 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 { - 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) + Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) UserItems(ctx context.Context, in *UserItemsReq, opts ...grpc.CallOption) (*Response, error) UserStatus(ctx context.Context, in *UserStatusReq, opts ...grpc.CallOption) (*Response, error) - // 内部:业务创建销售/门店时调用 EnsureBizIdentity(ctx context.Context, in *EnsureBizIdentityReq, opts ...grpc.CallOption) (*EnsureBizIdentityData, error) - // 内部:批量查用户基础信息 UsersByIds(ctx context.Context, in *UsersByIdsReq, opts ...grpc.CallOption) (*UsersByIdsData, error) - // 内部:修改手机号 UpdateMobile(ctx context.Context, in *UpdateMobileReq, opts ...grpc.CallOption) (*UpdateMobileData, error) - // 内部:撤销业务端开通 RevokeBizClient(ctx context.Context, in *RevokeBizClientReq, opts ...grpc.CallOption) (*RevokeBizClientData, error) } @@ -57,26 +51,6 @@ func NewUserClient(cc grpc.ClientConnInterface) UserClient { return &userClient{cc} } -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_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) @@ -87,6 +61,16 @@ func (c *userClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallO return out, nil } +func (c *userClient) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_Info_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *userClient) UserItems(ctx context.Context, in *UserItemsReq, opts ...grpc.CallOption) (*Response, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(Response) @@ -151,18 +135,13 @@ func (c *userClient) RevokeBizClient(ctx context.Context, in *RevokeBizClientReq // All implementations must embed UnimplementedUserServer // for forward compatibility. type UserServer interface { - Register(context.Context, *RegisterReq) (*Response, error) - RegisterByUser(context.Context, *RegisterByUserReq) (*Response, error) Login(context.Context, *LoginReq) (*Response, error) + Info(context.Context, *InfoReq) (*Response, error) UserItems(context.Context, *UserItemsReq) (*Response, error) UserStatus(context.Context, *UserStatusReq) (*Response, error) - // 内部:业务创建销售/门店时调用 EnsureBizIdentity(context.Context, *EnsureBizIdentityReq) (*EnsureBizIdentityData, error) - // 内部:批量查用户基础信息 UsersByIds(context.Context, *UsersByIdsReq) (*UsersByIdsData, error) - // 内部:修改手机号 UpdateMobile(context.Context, *UpdateMobileReq) (*UpdateMobileData, error) - // 内部:撤销业务端开通 RevokeBizClient(context.Context, *RevokeBizClientReq) (*RevokeBizClientData, error) mustEmbedUnimplementedUserServer() } @@ -174,15 +153,12 @@ type UserServer interface { // pointer dereference when methods are called. type UnimplementedUserServer struct{} -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) Info(context.Context, *InfoReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Info not implemented") +} func (UnimplementedUserServer) UserItems(context.Context, *UserItemsReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method UserItems not implemented") } @@ -222,42 +198,6 @@ func RegisterUserServer(s grpc.ServiceRegistrar, srv UserServer) { s.RegisterService(&User_ServiceDesc, srv) } -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).Register(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: User_Register_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - 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 { @@ -276,6 +216,24 @@ func _User_Login_Handler(srv interface{}, ctx context.Context, dec func(interfac return interceptor(ctx, in, info, handler) } +func _User_Info_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).Info(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_Info_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).Info(ctx, req.(*InfoReq)) + } + return interceptor(ctx, in, info, handler) +} + func _User_UserItems_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UserItemsReq) if err := dec(in); err != nil { @@ -391,18 +349,14 @@ var User_ServiceDesc = grpc.ServiceDesc{ ServiceName: "user.User", HandlerType: (*UserServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "Register", - Handler: _User_Register_Handler, - }, - { - MethodName: "RegisterByUser", - Handler: _User_RegisterByUser_Handler, - }, { MethodName: "Login", Handler: _User_Login_Handler, }, + { + MethodName: "Info", + Handler: _User_Info_Handler, + }, { MethodName: "UserItems", Handler: _User_UserItems_Handler, diff --git a/rpc/user/user.pb b/rpc/user/user.pb index 65945de..8472f73 100644 Binary files a/rpc/user/user.pb and b/rpc/user/user.pb differ diff --git a/rpc/user/user.proto b/rpc/user/user.proto index 460e4a3..6871232 100644 --- a/rpc/user/user.proto +++ b/rpc/user/user.proto @@ -11,40 +11,21 @@ message Response { 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; + string client_code = 1; + string grant_type = 2; + string code = 3; + string mobile = 4; + string password = 5; + string sms_code = 6; } -// 管理端用户列表 message UserItemsReq { string mobile = 1; int32 page = 2; int32 size = 3; } -// 管理端修改用户状态 message UserStatusReq { int64 id = 1; int32 status = 2; @@ -87,18 +68,16 @@ message UsersByIdsData { repeated UserBriefItem items = 1; } -// 内部:修改用户手机号(同步凭证 identifier) message UpdateMobileReq { int64 user_id = 1; - string mobile = 2; // 新手机号明文 + string mobile = 2; } message UpdateMobileData { int64 user_id = 1; - string mobile = 2; // 加密后手机号 + string mobile = 2; } -// 内部:撤销业务端开通(删除/禁用销售或门店时) message RevokeBizClientReq { int64 user_id = 1; string client_code = 2; @@ -108,22 +87,18 @@ message RevokeBizClientData { bool revoked = 1; } +message InfoReq {} + service User { - 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" + post: "/api/v3/login" + body: "*" + }; + } + rpc Info(InfoReq) returns (Response) { + option (google.api.http) = { + get: "/api/v3/user/info" body: "*" }; } diff --git a/services/sale/internal/logic/helper.go b/services/sale/internal/logic/helper.go index fee9891..8056c33 100644 --- a/services/sale/internal/logic/helper.go +++ b/services/sale/internal/logic/helper.go @@ -101,13 +101,17 @@ func maskSaleMobile(info *dao.SaleInfo) { info.Mobile = utils.DecryptPhoneReplace(mobile) } -// querySaleInfo 查询销售详情并附带分组;mobile 脱敏,origin_mobile 为加密串。 -// 未找到时返回 (nil, nil)。 func querySaleInfo(id int64) (*dao.SaleInfo, error) { + return querySaleInfoByEq(map[string]string{"id": strconv.FormatInt(id, 10)}) +} + +func querySaleInfoByUserId(userId int64) (*dao.SaleInfo, error) { + return querySaleInfoByEq(map[string]string{"user_id": strconv.FormatInt(userId, 10)}) +} + +func querySaleInfoByEq(eq map[string]string) (*dao.SaleInfo, error) { var info dao.SaleInfo - if err := (model.SaleModel{}.Init().GetOne(modelbase.Params{ - Eq: map[string]string{"id": strconv.FormatInt(id, 10)}, - }, &info)); err != nil { + if err := (model.SaleModel{}.Init().GetOne(modelbase.Params{Eq: eq}, &info)); err != nil { return nil, err } if info.Id < utils.NumberOne { diff --git a/services/sale/internal/logic/infoByUserIdLogic.go b/services/sale/internal/logic/infoByUserIdLogic.go new file mode 100644 index 0000000..c12199e --- /dev/null +++ b/services/sale/internal/logic/infoByUserIdLogic.go @@ -0,0 +1,47 @@ +package logic + +import ( + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/validate" + sale "lone-services/rpc/sale/pb" + "lone-services/services/sale/internal/svc" + "lone-services/services/sale/validator" + + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type InfoByUserIdLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewInfoByUserIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InfoByUserIdLogic { + return &InfoByUserIdLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *InfoByUserIdLogic) InfoByUserId(in *sale.InfoByUserIdReq) (*sale.InfoData, error) { + var req validator.InfoByUserIdValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return nil, status.Error(codes.InvalidArgument, msg) + } + + info, err := querySaleInfoByUserId(req.UserId) + if err != nil { + l.Errorf("sale InfoByUserId: %v", err) + return nil, status.Error(codes.Internal, utils.Fail.Msg) + } + if info == nil { + return nil, status.Error(codes.NotFound, utils.ErrorNotFund.Msg) + } + + return toSaleInfoData(info), nil +} diff --git a/services/sale/internal/logic/infoInternalLogic.go b/services/sale/internal/logic/infoInternalLogic.go index 54d8e4d..2338cf4 100644 --- a/services/sale/internal/logic/infoInternalLogic.go +++ b/services/sale/internal/logic/infoInternalLogic.go @@ -50,6 +50,7 @@ func (l *InfoInternalLogic) InfoInternal(in *sale.InfoReq) (*sale.InfoData, erro func toSaleInfoData(info *dao.SaleInfo) *sale.InfoData { data := &sale.InfoData{ Id: info.Id, + UserId: info.UserId, SaleId: info.SaleId, Mobile: info.Mobile, OriginMobile: info.OriginMobile, diff --git a/services/sale/internal/server/saleServer.go b/services/sale/internal/server/saleServer.go index 04d9ff5..3b671bc 100644 --- a/services/sale/internal/server/saleServer.go +++ b/services/sale/internal/server/saleServer.go @@ -86,7 +86,13 @@ func (s *SaleServer) InfoInternal(ctx context.Context, in *sale.InfoReq) (*sale. return l.InfoInternal(in) } -// 按 id 批量查销售 id+name(内部) +// 按 user_id 查销售详情(内部) +func (s *SaleServer) InfoByUserId(ctx context.Context, in *sale.InfoByUserIdReq) (*sale.InfoData, error) { + l := logic.NewInfoByUserIdLogic(ctx, s.svcCtx) + return l.InfoByUserId(in) +} + +// ids 批量查销售 func (s *SaleServer) NamesByIds(ctx context.Context, in *sale.NamesByIdsReq) (*sale.NamesByIdsData, error) { l := logic.NewNamesByIdsLogic(ctx, s.svcCtx) return l.NamesByIds(in) diff --git a/services/sale/saleClient/sale.go b/services/sale/saleClient/sale.go index 9ab2af6..a2ca156 100644 --- a/services/sale/saleClient/sale.go +++ b/services/sale/saleClient/sale.go @@ -14,24 +14,25 @@ import ( ) type ( - CreateReq = sale.CreateReq - EditReq = sale.EditReq - GroupCreateReq = sale.GroupCreateReq - GroupEmptyReq = sale.GroupEmptyReq - GroupItem = sale.GroupItem - GroupItemsReq = sale.GroupItemsReq - InfoData = sale.InfoData - InfoReq = sale.InfoReq - ItemsReq = sale.ItemsReq - NameItem = sale.NameItem - NamesByIdsData = sale.NamesByIdsData - NamesByIdsItem = sale.NamesByIdsItem - NamesByIdsReq = sale.NamesByIdsReq - NamesData = sale.NamesData - NamesReq = sale.NamesReq - Region = sale.Region - Response = sale.Response - StatusReq = sale.StatusReq + CreateReq = sale.CreateReq + EditReq = sale.EditReq + GroupCreateReq = sale.GroupCreateReq + GroupEmptyReq = sale.GroupEmptyReq + GroupItem = sale.GroupItem + GroupItemsReq = sale.GroupItemsReq + InfoByUserIdReq = sale.InfoByUserIdReq + InfoData = sale.InfoData + InfoReq = sale.InfoReq + ItemsReq = sale.ItemsReq + NameItem = sale.NameItem + NamesByIdsData = sale.NamesByIdsData + NamesByIdsItem = sale.NamesByIdsItem + NamesByIdsReq = sale.NamesByIdsReq + NamesData = sale.NamesData + NamesReq = sale.NamesReq + Region = sale.Region + Response = sale.Response + StatusReq = sale.StatusReq Sale interface { // 销售分组 @@ -49,7 +50,9 @@ type ( Status(ctx context.Context, in *StatusReq, opts ...grpc.CallOption) (*Response, error) // 销售详情 InfoInternal(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*InfoData, error) - // 按 id 批量查销售 id+name(内部) + // 按 user_id 查销售详情(内部) + InfoByUserId(ctx context.Context, in *InfoByUserIdReq, opts ...grpc.CallOption) (*InfoData, error) + // ids 批量查销售 NamesByIds(ctx context.Context, in *NamesByIdsReq, opts ...grpc.CallOption) (*NamesByIdsData, error) } @@ -127,7 +130,13 @@ func (m *defaultSale) InfoInternal(ctx context.Context, in *InfoReq, opts ...grp return client.InfoInternal(ctx, in, opts...) } -// 按 id 批量查销售 id+name(内部) +// 按 user_id 查销售详情(内部) +func (m *defaultSale) InfoByUserId(ctx context.Context, in *InfoByUserIdReq, opts ...grpc.CallOption) (*InfoData, error) { + client := sale.NewSaleClient(m.cli.Conn()) + return client.InfoByUserId(ctx, in, opts...) +} + +// ids 批量查销售 func (m *defaultSale) NamesByIds(ctx context.Context, in *NamesByIdsReq, opts ...grpc.CallOption) (*NamesByIdsData, error) { client := sale.NewSaleClient(m.cli.Conn()) return client.NamesByIds(ctx, in, opts...) diff --git a/services/sale/validator/validator.go b/services/sale/validator/validator.go index da346e1..1797c2b 100644 --- a/services/sale/validator/validator.go +++ b/services/sale/validator/validator.go @@ -147,6 +147,17 @@ func (p InfoValidator) GetMessage() validate.ValidatorMessages { } } +type InfoByUserIdValidator struct { + UserId int64 `validate:"required,gt=0"` +} + +func (p InfoByUserIdValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "UserId.required": "用户ID不能为空", + "UserId.gt": "用户ID必须大于0", + } +} + type ItemsValidator struct { Name string `validate:"omitempty,max=256"` Page uint32 `validate:"omitempty,min=1"` diff --git a/services/user/internal/config/jwt.go b/services/user/internal/config/jwt.go new file mode 100644 index 0000000..0b7e4fc --- /dev/null +++ b/services/user/internal/config/jwt.go @@ -0,0 +1,43 @@ +package config + +import ( + "fmt" + + "lone-services/pkg/utils" +) + +// JWTAuth 由服务配置初始化的 access / refresh 两套 JWT。 +type JWTAuth struct { + Access *utils.JWT + Refresh *utils.JWT +} + +func LoadJWTAuth() (*JWTAuth, error) { + issuer := utils.GetConfigString("jwt.issuer") + if issuer == utils.StringEmpty { + issuer = "lone-user" + } + + access, err := utils.NewJWT( + utils.GetConfigString("jwt.access_secret"), + issuer, + utils.GetConfigInt("jwt.access_ttl"), + ) + if err != nil { + return nil, fmt.Errorf("jwt access: %w", err) + } + + refresh, err := utils.NewJWT( + utils.GetConfigString("jwt.refresh_secret"), + issuer, + utils.GetConfigInt("jwt.refresh_ttl"), + ) + if err != nil { + return nil, fmt.Errorf("jwt refresh: %w", err) + } + + return &JWTAuth{ + Access: access, + Refresh: refresh, + }, nil +} diff --git a/services/user/internal/config/wechat.go b/services/user/internal/config/wechat.go new file mode 100644 index 0000000..38f5a0a --- /dev/null +++ b/services/user/internal/config/wechat.go @@ -0,0 +1,18 @@ +package config + +import ( + "fmt" + + "lone-services/pkg/utils" + "lone-services/pkg/wechat/auth" +) + +func NewWechatClient(clientCode string) (*auth.Client, error) { + prefix := "wechat." + clientCode + appID := utils.GetConfigString(prefix + ".app_id") + secret := utils.GetConfigString(prefix + ".app_secret") + if appID == utils.StringEmpty || secret == utils.StringEmpty { + return nil, fmt.Errorf("wechat config missing for client %s", clientCode) + } + return auth.NewClient(appID, secret), nil +} diff --git a/services/user/internal/dao/const.go b/services/user/internal/dao/const.go index e138a67..0f43155 100644 --- a/services/user/internal/dao/const.go +++ b/services/user/internal/dao/const.go @@ -7,6 +7,20 @@ const ( CredentialTypePassword = "password" CredentialTypeWecom = "wecom" CredentialTypeOpenid = "openid" + CredentialTypeUnionid = "unionid" + + GrantTypeOpenid = "openid" + GrantTypePassword = "password" + GrantTypeSms = "sms" + + // Type* 登录身份(写入 session.type / X-User-Type),与订单侧约定一致 + TypeSale uint8 = 1 // 销售 + TypeStore uint8 = 2 // 门店 + TypeUser uint8 = 3 // 普通用户 + + SubjectTypeSale = "sale" + SubjectTypeStore = "store" + SubjectTypeUser = "user" // ExtraJsonEmpty MySQL JSON 列不能写空串,无扩展字段时用 {} ExtraJsonEmpty = "{}" diff --git a/services/user/internal/dao/session.go b/services/user/internal/dao/session.go index d0882c6..ab5ad62 100644 --- a/services/user/internal/dao/session.go +++ b/services/user/internal/dao/session.go @@ -1,20 +1,70 @@ package dao -import "lone-services/pkg/utils" - type Token struct { - Token string `json:"token"` - Refresh string `json:"refresh"` - Info UserLoginSession `json:"info"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + Info UserLoginSession `json:"info"` } type UserLoginSession struct { - Id int64 `json:"id"` - Name string `json:"name"` - Avatar string `json:"avatar"` - Mobile string `json:"mobile"` - Gender uint8 `json:"gender"` - Birthday string `json:"birthday"` - Status uint8 `json:"status"` - LastTime utils.CustomTime `json:"last_time"` + Id int64 `json:"id"` + Name string `json:"name"` + Avatar string `json:"avatar"` + Mobile string `json:"mobile"` + Gender uint8 `json:"gender"` + Birthday string `json:"birthday"` + Type uint8 `json:"type"` // 1销售 2门店 3普通用户 + ClientCode string `json:"client_code"` + SaleId int64 `json:"sale_id,omitempty"` + StoreId int64 `json:"store_id,omitempty"` +} + +// ProfileData 当前登录用户详情(按 type 填充扩展字段) +type ProfileData struct { + Type uint8 `json:"type"` + Base ProfileBase `json:"base"` + Sale *ProfileSaleData `json:"sale,omitempty"` + Store any `json:"store,omitempty"` // 门店详情暂未开放 +} + +type ProfileBase struct { + UserId int64 `json:"user_id"` + Name string `json:"name"` + Avatar string `json:"avatar"` + Mobile string `json:"mobile"` + Gender uint8 `json:"gender"` + Birthday string `json:"birthday"` + Status uint8 `json:"status"` +} + +type ProfileSaleData struct { + Id int64 `json:"id"` + SaleId int64 `json:"sale_id"` + Name string `json:"name"` + Mobile string `json:"mobile"` + OriginMobile string `json:"origin_mobile"` + Avatar string `json:"avatar"` + Account string `json:"account"` + Type uint32 `json:"type"` + Sex uint32 `json:"sex"` + BirthDate string `json:"birth_date"` + Status uint32 `json:"status"` + GroupId int64 `json:"group_id"` + GroupName string `json:"group_name"` + Address string `json:"address"` + ProvinceId int64 `json:"province_id"` + CityId int64 `json:"city_id"` + DistrictId int64 `json:"district_id"` + TerritoryId int64 `json:"territory_id"` + TerritoryName string `json:"territory_name"` + Region *ProfileSaleRegion `json:"region,omitempty"` + IdCardFront string `json:"id_card_front"` + IdCardBack string `json:"id_card_back"` + BusinessLicense string `json:"business_license"` +} + +type ProfileSaleRegion struct { + Province string `json:"province"` + City string `json:"city"` + District string `json:"district"` } diff --git a/services/user/internal/logic/authHelper.go b/services/user/internal/logic/authHelper.go new file mode 100644 index 0000000..c2f8d9b --- /dev/null +++ b/services/user/internal/logic/authHelper.go @@ -0,0 +1,227 @@ +package logic + +import ( + "context" + "errors" + "strconv" + "strings" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/services/user/internal/config" + "lone-services/services/user/internal/dao" + "lone-services/services/user/internal/model" + + jsoniter "github.com/json-iterator/go" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gorm.io/gorm" +) + +func clientAllowsGrant(allowedGrants, grantType string) bool { + if allowedGrants == utils.StringEmpty { + return false + } + var grants []string + if err := jsoniter.UnmarshalFromString(allowedGrants, &grants); err != nil { + return strings.Contains(allowedGrants, grantType) + } + for _, g := range grants { + if g == grantType { + return true + } + } + return false +} + +func loadEnabledClient(clientCode string) (*dao.Client, error) { + var client dao.Client + clientModel := model.ClientModel{}.Init() + if err := clientModel.GetOne(modelbase.Params{ + Eq: map[string]string{ + "code": clientCode, + "status": strconv.Itoa(int(dao.StatusEnabled)), + }, + }, &client); err != nil { + return nil, err + } + if client.Id < utils.NumberOne { + return nil, status.Error(codes.InvalidArgument, "端配置不存在或已禁用") + } + return &client, nil +} + +func findCredential(credentialType, identifier string) (*dao.UserCredential, error) { + var cred dao.UserCredential + credModel := model.UserCredentialModel{}.Init() + if err := credModel.GetOne(modelbase.Params{ + Eq: map[string]string{ + "credential_type": credentialType, + "identifier": identifier, + }, + }, &cred); err != nil { + return nil, err + } + if cred.Id < utils.NumberOne { + return nil, nil + } + return &cred, nil +} + +func loadEnabledUser(userId int64) (*dao.UserRow, error) { + var row dao.UserRow + userModel := model.UserModel{}.Init() + if err := userModel.GetOne(modelbase.Params{ + Eq: map[string]string{ + "id": strconv.FormatInt(userId, utils.NumberTen), + "status": strconv.Itoa(int(dao.StatusEnabled)), + }, + }, &row); err != nil { + return nil, err + } + if row.Id < utils.NumberOne { + return nil, status.Error(codes.NotFound, utils.ErrorNotFund.Msg) + } + return &row, nil +} + +func resolveOrCreateWechatUser(ctx context.Context, db *gorm.DB, openid, unionid, clientCode string) (int64, error) { + openCred, err := findCredential(dao.CredentialTypeOpenid, openid) + if err != nil { + return utils.NumberZero, err + } + if openCred != nil { + if openCred.Status == dao.StatusDisabled { + return utils.NumberZero, status.Error(codes.FailedPrecondition, "登录凭证已禁用") + } + if err := ensureUserClient(db, openCred.UserId, clientCode); err != nil { + return utils.NumberZero, err + } + return openCred.UserId, nil + } + + var userId int64 + if unionid != utils.StringEmpty { + unionCred, uErr := findCredential(dao.CredentialTypeUnionid, unionid) + if uErr != nil { + return utils.NumberZero, uErr + } + if unionCred != nil { + if unionCred.Status == dao.StatusDisabled { + return utils.NumberZero, status.Error(codes.FailedPrecondition, "登录凭证已禁用") + } + userId = unionCred.UserId + } + } + + txErr := db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + if userId < utils.NumberOne { + userModel := model.UserModel{}.Init() + userModel.Base = userModel.Base.WithTX(tx) + add := dao.UserCreate{Status: dao.StatusEnabled} + if err := userModel.Create(&add); err != nil { + return err + } + userId = add.Id + } + + if err := createWechatCredentials(tx, userId, openid, unionid); err != nil { + return err + } + return ensureUserClient(tx, userId, clientCode) + }) + if txErr != nil { + if st, ok := status.FromError(txErr); ok { + return utils.NumberZero, st.Err() + } + return utils.NumberZero, txErr + } + return userId, nil +} + +func createWechatCredentials(tx *gorm.DB, userId int64, openid, unionid string) error { + credModel := model.UserCredentialModel{}.Init() + credModel.Base = credModel.Base.WithTX(tx) + + var existOpen dao.UserCredential + if err := credModel.GetOne(modelbase.Params{ + Eq: map[string]string{ + "credential_type": dao.CredentialTypeOpenid, + "identifier": openid, + }, + }, &existOpen); err != nil { + return err + } + if existOpen.Id < utils.NumberOne { + if err := credModel.Create(&dao.UserCredential{ + UserId: userId, + CredentialType: dao.CredentialTypeOpenid, + Identifier: openid, + ExtraJson: dao.ExtraJsonEmpty, + Status: dao.StatusEnabled, + }); err != nil { + return err + } + } else if existOpen.UserId != userId { + return status.Error(codes.AlreadyExists, "openid已被其他用户占用") + } + + if unionid == utils.StringEmpty { + return nil + } + + var existUnion dao.UserCredential + if err := credModel.GetOne(modelbase.Params{ + Eq: map[string]string{ + "credential_type": dao.CredentialTypeUnionid, + "identifier": unionid, + }, + }, &existUnion); err != nil { + return err + } + if existUnion.Id < utils.NumberOne { + return credModel.Create(&dao.UserCredential{ + UserId: userId, + CredentialType: dao.CredentialTypeUnionid, + Identifier: unionid, + ExtraJson: dao.ExtraJsonEmpty, + Status: dao.StatusEnabled, + }) + } + if existUnion.UserId != userId { + return status.Error(codes.AlreadyExists, "unionid 已被其他用户占用") + } + return nil +} + +func issueLoginToken(ctx context.Context, jwtAuth *config.JWTAuth, saleSvcName string, row *dao.UserRow, client *dao.Client) (*dao.Token, error) { + if jwtAuth == nil || jwtAuth.Access == nil || jwtAuth.Refresh == nil { + return nil, errors.New("jwt not initialized") + } + mobile := decryptMobile(row.Mobile) + + var saleId int64 + userType := dao.TypeUser + if client != nil { + userType = subjectTypeToUserType(client.SubjectType) + } + if userType == dao.TypeSale { + saleInfo, err := fetchSaleByUserId(ctx, saleSvcName, row.Id) + if err != nil { + return nil, err + } + if saleInfo != nil { + saleId = saleInfo.Id + } + } + + session := toSession(*row, mobile, client, saleId) + ret, err := buildJwtToken(jwtAuth, session) + if err != nil { + return nil, err + } + if st := setLogin(jwtAuth, ret.AccessToken, ret.RefreshToken, session); st.Code != utils.Ok.Code { + return nil, errors.New(st.Msg) + } + return &ret, nil +} diff --git a/services/user/internal/logic/infoLogic.go b/services/user/internal/logic/infoLogic.go new file mode 100644 index 0000000..c12c9cb --- /dev/null +++ b/services/user/internal/logic/infoLogic.go @@ -0,0 +1,94 @@ +package logic + +import ( + "context" + + "lone-services/pkg/utils" + user "lone-services/rpc/user/pb" + "lone-services/services/user/internal/dao" + "lone-services/services/user/internal/svc" + + "github.com/zeromicro/go-zero/core/logx" +) + +type InfoLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InfoLogic { + return &InfoLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *InfoLogic) Info(in *user.InfoReq) (*user.Response, error) { + loginUser := utils.GetUserFromCtx(l.ctx) + if loginUser.ID < utils.NumberOne { + return failResponse(utils.ErrorNoLoginInfo), nil + } + + row, err := loadEnabledUser(loginUser.ID) + if err != nil { + l.Errorf("info load user: %v", err) + return failResponse(utils.ErrorNotFund), nil + } + + userType := loginUser.Type + if userType < utils.NumberOne { + userType = dao.TypeUser + } + + ret := dao.ProfileData{ + Type: userType, + Base: dao.ProfileBase{ + UserId: row.Id, + Name: row.Name, + Avatar: row.Avatar, + Mobile: decryptMobile(row.Mobile), + Gender: row.Gender, + Birthday: row.Birthday.DateString(), + Status: row.Status, + }, + } + + switch userType { + case dao.TypeUser: + return okResponse(ret), nil + case dao.TypeSale: + saleData, saleErr := l.loadSaleProfile(loginUser) + if saleErr != nil { + l.Errorf("info load sale: %v", saleErr) + return failResponse(utils.Fail), nil + } + if saleData == nil { + return outResponse(utils.ErrorNotFund, "销售信息不存在"), nil + } + ret.Sale = saleData + return okResponse(ret), nil + case dao.TypeStore: + return outResponse(utils.Fail, "门店详情暂未开放"), nil + default: + return outResponse(utils.ErrorParams, "未知的用户类型"), nil + } +} + +func (l *InfoLogic) loadSaleProfile(loginUser utils.UserInfo) (*dao.ProfileSaleData, error) { + if loginUser.SaleId > utils.NumberZero { + data, err := fetchSaleById(l.ctx, l.svcCtx.SaleSvcName, loginUser.SaleId) + if err != nil { + return nil, err + } + if data != nil { + return toProfileSale(data), nil + } + } + data, err := fetchSaleByUserId(l.ctx, l.svcCtx.SaleSvcName, loginUser.ID) + if err != nil { + return nil, err + } + return toProfileSale(data), nil +} diff --git a/services/user/internal/logic/loginLogic.go b/services/user/internal/logic/loginLogic.go index 6956b2e..f3f5870 100644 --- a/services/user/internal/logic/loginLogic.go +++ b/services/user/internal/logic/loginLogic.go @@ -2,18 +2,17 @@ package logic import ( "context" - "strconv" - "lone-services/pkg/modelbase" "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/model" "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 { @@ -31,47 +30,64 @@ func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic } func (l *LoginLogic) Login(in *user.LoginReq) (*user.Response, error) { - var v validator.LoginValidator - if msg := validate.ValidateFromProto(in, &v); msg != utils.StringEmpty { + var req validator.LoginValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { return outResponse(utils.ErrorParams, msg), nil } - var cred dao.UserCredential - credModel := model.UserCredentialModel{}.Init() - if err := credModel.GetOne(modelbase.Params{ - Eq: map[string]string{ - "credential_type": dao.CredentialTypeOpenid, - "identifier": v.Openid, - "status": utils.StringStatusOk, - }, - }, &cred); err != nil { - l.Errorf("login by openid credential: %v", err) + switch req.GrantType { + case dao.GrantTypeOpenid: + return l.loginByOpenid(req) + case dao.GrantTypePassword: + return outResponse(utils.ErrorParams, "密码登录暂未开放"), nil + 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 cred.Id < utils.NumberOne || cred.UserId < utils.NumberOne { + 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 } - var row dao.UserRow - userModel := model.UserModel{}.Init() - if err := userModel.GetOne(modelbase.Params{ - Eq: map[string]string{ - "id": strconv.FormatInt(cred.UserId, utils.NumberTen), - "status": utils.StringStatusOk, - }, - }, &row); err != nil { - l.Errorf("login by openid user: %v", err) + 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 } - if row.Id < utils.NumberOne { - return failResponse(utils.ErrorNotFund), nil - } - - mobile := decryptMobile(row.Mobile) - session := toSession(row, 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/services/user/internal/logic/registerByUserLogic.go b/services/user/internal/logic/registerByUserLogic.go deleted file mode 100644 index 144f3c2..0000000 --- a/services/user/internal/logic/registerByUserLogic.go +++ /dev/null @@ -1,135 +0,0 @@ -package logic - -import ( - "context" - "errors" - - "lone-services/pkg/modelbase" - "lone-services/pkg/redis" - "lone-services/pkg/utils" - "lone-services/pkg/validate" - user "lone-services/rpc/user/pb" - "lone-services/services/user/internal/dao" - "lone-services/services/user/internal/model" - "lone-services/services/user/internal/svc" - "lone-services/services/user/validator" - - "github.com/zeromicro/go-zero/core/logx" - "gorm.io/gorm" -) - -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 := validate.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 - } - - credModel := model.UserCredentialModel{}.Init() - var oldCred dao.UserCredential - if err := credModel.GetOne(modelbase.Params{ - Eq: map[string]string{ - "credential_type": dao.CredentialTypePassword, - "identifier": v.Account, - }, - }, &oldCred); err != nil { - l.Errorf("registerByUser check account: %v", err) - return failResponse(utils.Fail), nil - } - if oldCred.Id > utils.NumberZero { - return failResponse(utils.ErrorDataIsExist), nil - } - - secret, pErr := utils.EncryptPassword(v.Pwd) - if pErr != nil { - l.Errorf("registerByUser encrypt password: %v", pErr) - return failResponse(utils.Fail), nil - } - - encryptMobile := utils.StringEmpty - if v.Type == utils.NumberOne { - mobile, cErr := utils.EncryptPhone(v.Account) - if cErr != nil { - l.Errorf("registerByUser encrypt mobile: %v", cErr) - return failResponse(utils.ErrorEncryptAesError), nil - } - encryptMobile = mobile - } - - var userId int64 - txErr := l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { - userModel := model.UserModel{}.Init() - userModel.Base = userModel.Base.WithTX(tx) - - if encryptMobile != utils.StringEmpty { - var exist dao.UserRow - if err := userModel.GetOne(modelbase.Params{ - Eq: map[string]string{"mobile": encryptMobile}, - }, &exist); err != nil { - return err - } - if exist.Id > utils.NumberZero { - if exist.Status == dao.StatusDisabled { - return errors.New("user disabled") - } - userId = exist.Id - } - } - - if userId < utils.NumberOne { - add := dao.UserCreate{ - Mobile: encryptMobile, - Name: v.Account, - Status: dao.StatusEnabled, - } - if err := userModel.Create(&add); err != nil { - return err - } - userId = add.Id - } - - credTx := model.UserCredentialModel{}.Init() - credTx.Base = credTx.Base.WithTX(tx) - return credTx.Create(&dao.UserCredential{ - UserId: userId, - CredentialType: dao.CredentialTypePassword, - Identifier: v.Account, - Secret: secret, - ExtraJson: dao.ExtraJsonEmpty, - Status: dao.StatusEnabled, - }) - }) - if txErr != nil { - l.Errorf("registerByUser tx: %v", txErr) - return failResponse(utils.Fail), nil - } - - redis.Client.Del(l.ctx, codeKey) - return okResponse(map[string]any{"id": userId}), nil -} diff --git a/services/user/internal/logic/registerLogic.go b/services/user/internal/logic/registerLogic.go deleted file mode 100644 index 17fc750..0000000 --- a/services/user/internal/logic/registerLogic.go +++ /dev/null @@ -1,142 +0,0 @@ -package logic - -import ( - "context" - "errors" - "strconv" - - "lone-services/pkg/modelbase" - "lone-services/pkg/utils" - "lone-services/pkg/validate" - user "lone-services/rpc/user/pb" - "lone-services/services/user/internal/dao" - "lone-services/services/user/internal/model" - "lone-services/services/user/internal/svc" - "lone-services/services/user/validator" - - "github.com/zeromicro/go-zero/core/logx" - "gorm.io/gorm" -) - -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 := validate.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()) - } - - credModel := model.UserCredentialModel{}.Init() - var existCred dao.UserCredential - if err := credModel.GetOne(modelbase.Params{ - Eq: map[string]string{ - "credential_type": dao.CredentialTypeOpenid, - "identifier": openid, - }, - }, &existCred); err != nil { - l.Errorf("register check openid: %v", err) - return failResponse(utils.Fail), nil - } - if existCred.Id > utils.NumberZero { - return failResponse(utils.ErrorExist), nil - } - - encryptMobile, cErr := utils.EncryptPhone(v.Mobile) - if cErr != nil { - l.Errorf("register encrypt mobile: %v", cErr) - return failResponse(utils.ErrorEncryptAesError), nil - } - - name := v.Username - if name == utils.StringEmpty { - name = v.Nickname - } - - if _, bErr := utils.ParseDateOnly(v.Birthday); bErr != nil { - return outResponse(utils.ErrorParams, "生日格式不正确"), nil - } - - var userRow dao.UserRow - txErr := l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { - userModel := model.UserModel{}.Init() - userModel.Base = userModel.Base.WithTX(tx) - - var exist dao.UserRow - if err := userModel.GetOne(modelbase.Params{ - Eq: map[string]string{"mobile": encryptMobile}, - }, &exist); err != nil { - return err - } - - if exist.Id > utils.NumberZero { - if exist.Status == dao.StatusDisabled { - return errors.New("user disabled") - } - userRow = exist - } else { - birthday, _ := utils.ParseDateOnly(v.Birthday) - add := dao.UserCreate{ - Mobile: encryptMobile, - Name: name, - Avatar: v.Avatar, - Gender: uint8(v.Gender), - Birthday: birthday, - Status: dao.StatusEnabled, - } - if err := userModel.Create(&add); err != nil { - return err - } - userRow = dao.UserRow{ - Id: add.Id, - Mobile: add.Mobile, - Name: add.Name, - Avatar: add.Avatar, - Gender: add.Gender, - Birthday: add.Birthday, - Status: add.Status, - } - } - - credTx := model.UserCredentialModel{}.Init() - credTx.Base = credTx.Base.WithTX(tx) - extra := dao.ExtraJsonEmpty - if v.AppId > utils.NumberZero { - extra = `{"appid":` + strconv.FormatUint(uint64(v.AppId), utils.NumberTen) + `}` - } - return credTx.Create(&dao.UserCredential{ - UserId: userRow.Id, - CredentialType: dao.CredentialTypeOpenid, - Identifier: openid, - ExtraJson: extra, - Status: dao.StatusEnabled, - }) - }) - if txErr != nil { - l.Errorf("register tx: %v", txErr) - return failResponse(utils.Fail), nil - } - - session := toSession(userRow, 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/services/user/internal/logic/response.go b/services/user/internal/logic/response.go index 2392cd7..2068407 100644 --- a/services/user/internal/logic/response.go +++ b/services/user/internal/logic/response.go @@ -2,12 +2,14 @@ package logic import ( "context" + "strconv" + "time" + "lone-services/pkg/redis" "lone-services/pkg/utils" user "lone-services/rpc/user/pb" + "lone-services/services/user/internal/config" "lone-services/services/user/internal/dao" - "strconv" - "time" jsoniter "github.com/json-iterator/go" ) @@ -46,40 +48,80 @@ func decryptMobile(mobile string) string { return plain } -func toSession(info dao.UserRow, mobilePlain string) dao.UserLoginSession { +func subjectTypeToUserType(subjectType string) uint8 { + switch subjectType { + case dao.SubjectTypeSale: + return dao.TypeSale + case dao.SubjectTypeStore: + return dao.TypeStore + case dao.SubjectTypeUser: + return dao.TypeUser + default: + return dao.TypeUser + } +} + +func toSession(info dao.UserRow, mobilePlain string, client *dao.Client, saleId int64) dao.UserLoginSession { + userType := dao.TypeUser + clientCode := utils.StringEmpty + if client != nil { + clientCode = client.Code + userType = subjectTypeToUserType(client.SubjectType) + } return dao.UserLoginSession{ - Id: info.Id, - Name: info.Name, - Avatar: info.Avatar, - Mobile: mobilePlain, - Gender: info.Gender, - Birthday: info.Birthday.DateString(), - Status: info.Status, - LastTime: utils.Now(), + Id: info.Id, + Name: info.Name, + Avatar: info.Avatar, + Mobile: mobilePlain, + Gender: info.Gender, + Birthday: info.Birthday.DateString(), + Type: userType, + ClientCode: clientCode, + SaleId: saleId, } } -func buildToken(session dao.UserLoginSession) dao.Token { - seed := session.Mobile + strconv.FormatInt(session.Id, utils.NumberTen) + utils.Now().String() - token := utils.MD5Encrypt(seed) +func sessionClaims(session dao.UserLoginSession, tokenType string) utils.Claims { + return utils.Claims{ + UserID: session.Id, + Name: session.Name, + Avatar: session.Avatar, + Mobile: session.Mobile, + Gender: session.Gender, + Birthday: session.Birthday, + Type: session.Type, + ClientCode: session.ClientCode, + SaleId: session.SaleId, + StoreId: session.StoreId, + TokenType: tokenType, + } +} + +func buildJwtToken(jwtAuth *config.JWTAuth, session dao.UserLoginSession) (dao.Token, error) { + accessToken, err := jwtAuth.Access.Sign(sessionClaims(session, utils.TokenTypeAccess)) + if err != nil { + return dao.Token{}, err + } + refreshToken, err := jwtAuth.Refresh.Sign(sessionClaims(session, utils.TokenTypeRefresh)) + if err != nil { + return dao.Token{}, err + } return dao.Token{ - Token: token, - Refresh: utils.MD5Encrypt(seed + token), - Info: session, - } + AccessToken: accessToken, + RefreshToken: refreshToken, + Info: session, + }, nil } -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 +func setLogin(jwtAuth *config.JWTAuth, accessToken, refreshToken string, session dao.UserLoginSession) utils.Status { + accessExpire := time.Duration(jwtAuth.Access.TTL) * time.Second + refreshExpire := time.Duration(jwtAuth.Refresh.TTL) * time.Second 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 { + redisKey := utils.GetLoginKey(utils.LoginTypeUser, accessToken) + if err := redis.Client.Set(ctx, redisKey, userStr, accessExpire).Err(); err != nil { return utils.Fail } @@ -95,14 +137,14 @@ func setLogin(token, refresh string, session dao.UserLoginSession) utils.Status } } - loginInfo.Token = token - loginInfo.Refresh = refresh + loginInfo.Token = accessToken + loginInfo.Refresh = refreshToken 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) + refreshKey := utils.GetLoginRefreshKey(utils.LoginTypeUser, refreshToken) if err := redis.Client.Set(ctx, refreshKey, strconv.FormatInt(session.Id, utils.NumberTen), refreshExpire).Err(); err != nil { return utils.Fail } diff --git a/services/user/internal/logic/saleClient.go b/services/user/internal/logic/saleClient.go new file mode 100644 index 0000000..75a602a --- /dev/null +++ b/services/user/internal/logic/saleClient.go @@ -0,0 +1,89 @@ +package logic + +import ( + "context" + + "lone-services/pkg/rpcclient" + "lone-services/pkg/utils" + salepb "lone-services/rpc/sale/pb" + "lone-services/services/user/internal/dao" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func fetchSaleByUserId(ctx context.Context, saleSvcName string, userId int64) (*salepb.InfoData, error) { + if saleSvcName == utils.StringEmpty || userId < utils.NumberOne { + return nil, nil + } + cli, err := rpcclient.Get(saleSvcName) + if err != nil { + return nil, err + } + data, err := salepb.NewSaleClient(cli.Conn()).InfoByUserId(ctx, &salepb.InfoByUserIdReq{UserId: userId}) + if err != nil { + if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound { + return nil, nil + } + return nil, err + } + return data, nil +} + +func fetchSaleById(ctx context.Context, saleSvcName string, saleId int64) (*salepb.InfoData, error) { + if saleSvcName == utils.StringEmpty || saleId < utils.NumberOne { + return nil, nil + } + cli, err := rpcclient.Get(saleSvcName) + if err != nil { + return nil, err + } + data, err := salepb.NewSaleClient(cli.Conn()).InfoInternal(ctx, &salepb.InfoReq{Id: saleId}) + if err != nil { + if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound { + return nil, nil + } + return nil, err + } + return data, nil +} + +func toProfileSale(data *salepb.InfoData) *dao.ProfileSaleData { + if data == nil { + return nil + } + out := &dao.ProfileSaleData{ + Id: data.Id, + SaleId: data.SaleId, + Name: data.Name, + Mobile: data.Mobile, + OriginMobile: data.OriginMobile, + Avatar: data.Avatar, + Account: data.Account, + Type: data.Type, + Sex: data.Sex, + BirthDate: data.BirthDate, + Status: data.Status, + GroupId: data.GroupId, + Address: data.Address, + ProvinceId: data.ProvinceId, + CityId: data.CityId, + DistrictId: data.DistrictId, + TerritoryId: data.TerritoryId, + TerritoryName: data.TerritoryName, + IdCardFront: data.IdCardFront, + IdCardBack: data.IdCardBack, + BusinessLicense: data.BusinessLicense, + } + if data.Group != nil { + out.GroupName = data.Group.Name + } + if data.Region != nil { + out.Region = &dao.ProfileSaleRegion{ + Province: data.Region.Province, + City: data.Region.City, + District: data.Region.District, + } + } + return out +} diff --git a/services/user/internal/server/userserver.go b/services/user/internal/server/userserver.go index 6e30e12..9fe7e8a 100644 --- a/services/user/internal/server/userserver.go +++ b/services/user/internal/server/userserver.go @@ -23,21 +23,16 @@ func NewUserServer(svcCtx *svc.ServiceContext) *UserServer { } } -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) } +func (s *UserServer) Info(ctx context.Context, in *user.InfoReq) (*user.Response, error) { + l := logic.NewInfoLogic(ctx, s.svcCtx) + return l.Info(in) +} + func (s *UserServer) UserItems(ctx context.Context, in *user.UserItemsReq) (*user.Response, error) { l := logic.NewUserItemsLogic(ctx, s.svcCtx) return l.UserItems(in) @@ -48,25 +43,21 @@ func (s *UserServer) UserStatus(ctx context.Context, in *user.UserStatusReq) (*u return l.UserStatus(in) } -// 内部:业务创建销售/门店时调用 func (s *UserServer) EnsureBizIdentity(ctx context.Context, in *user.EnsureBizIdentityReq) (*user.EnsureBizIdentityData, error) { l := logic.NewEnsureBizIdentityLogic(ctx, s.svcCtx) return l.EnsureBizIdentity(in) } -// 内部:批量查用户基础信息 func (s *UserServer) UsersByIds(ctx context.Context, in *user.UsersByIdsReq) (*user.UsersByIdsData, error) { l := logic.NewUsersByIdsLogic(ctx, s.svcCtx) return l.UsersByIds(in) } -// 内部:修改手机号 func (s *UserServer) UpdateMobile(ctx context.Context, in *user.UpdateMobileReq) (*user.UpdateMobileData, error) { l := logic.NewUpdateMobileLogic(ctx, s.svcCtx) return l.UpdateMobile(in) } -// 内部:撤销业务端开通 func (s *UserServer) RevokeBizClient(ctx context.Context, in *user.RevokeBizClientReq) (*user.RevokeBizClientData, error) { l := logic.NewRevokeBizClientLogic(ctx, s.svcCtx) return l.RevokeBizClient(in) diff --git a/services/user/internal/svc/servicecontext.go b/services/user/internal/svc/servicecontext.go index b708f4b..9a3a232 100644 --- a/services/user/internal/svc/servicecontext.go +++ b/services/user/internal/svc/servicecontext.go @@ -4,19 +4,28 @@ import ( "lone-services/pkg/utils" "lone-services/services/user/internal/config" + "github.com/zeromicro/go-zero/core/logx" "gorm.io/gorm" ) type ServiceContext struct { - Config config.Config - DB *gorm.DB - Prefix string + Config config.Config + DB *gorm.DB + Prefix string + JWT *config.JWTAuth + SaleSvcName string } -func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { +func NewServiceContext(c config.Config, db *gorm.DB, jwtAuth *config.JWTAuth) *ServiceContext { + saleSvc := utils.GetConfigString("services.sale") + if saleSvc == utils.StringEmpty { + logx.Error("config services.sale empty") + } return &ServiceContext{ - Config: c, - DB: db, - Prefix: utils.GetConfigString("mysql.prefix"), + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + JWT: jwtAuth, + SaleSvcName: saleSvc, } } diff --git a/services/user/user.go b/services/user/user.go index 3390db4..b3eb305 100644 --- a/services/user/user.go +++ b/services/user/user.go @@ -121,12 +121,18 @@ func main() { debug := utils.GetConfigBool("mysql.debug") modelbase.Init(db, modelbase.Config{Prefix: utils.GetConfigString("mysql.prefix"), Debug: debug}) + jwtAuth, err := config.LoadJWTAuth() + if err != nil { + logx.Errorf("jwt init: %v", err) + os.Exit(1) + } + rpcConf := zrpc.RpcServerConf{ ListenOn: listenOn, } rpcConf.Mode = mode - ctx := svc.NewServiceContext(c, db) + ctx := svc.NewServiceContext(c, db, jwtAuth) s := zrpc.MustNewServer(rpcConf, func(grpcServer *grpc.Server) { user.RegisterUserServer(grpcServer, server.NewUserServer(ctx)) diff --git a/services/user/userClient/user.go b/services/user/userClient/user.go index 22d00d4..b50ffa9 100644 --- a/services/user/userClient/user.go +++ b/services/user/userClient/user.go @@ -16,9 +16,8 @@ import ( type ( EnsureBizIdentityData = user.EnsureBizIdentityData EnsureBizIdentityReq = user.EnsureBizIdentityReq + InfoReq = user.InfoReq LoginReq = user.LoginReq - RegisterByUserReq = user.RegisterByUserReq - RegisterReq = user.RegisterReq Response = user.Response RevokeBizClientData = user.RevokeBizClientData RevokeBizClientReq = user.RevokeBizClientReq @@ -31,18 +30,13 @@ type ( UsersByIdsReq = user.UsersByIdsReq User interface { - 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) + Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) UserItems(ctx context.Context, in *UserItemsReq, opts ...grpc.CallOption) (*Response, error) UserStatus(ctx context.Context, in *UserStatusReq, opts ...grpc.CallOption) (*Response, error) - // 内部:业务创建销售/门店时调用 EnsureBizIdentity(ctx context.Context, in *EnsureBizIdentityReq, opts ...grpc.CallOption) (*EnsureBizIdentityData, error) - // 内部:批量查用户基础信息 UsersByIds(ctx context.Context, in *UsersByIdsReq, opts ...grpc.CallOption) (*UsersByIdsData, error) - // 内部:修改手机号 UpdateMobile(ctx context.Context, in *UpdateMobileReq, opts ...grpc.CallOption) (*UpdateMobileData, error) - // 内部:撤销业务端开通 RevokeBizClient(ctx context.Context, in *RevokeBizClientReq, opts ...grpc.CallOption) (*RevokeBizClientData, error) } @@ -57,21 +51,16 @@ func NewUser(cli zrpc.Client) User { } } -func (m *defaultUser) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) { - client := user.NewUserClient(m.cli.Conn()) - 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...) } +func (m *defaultUser) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.Info(ctx, in, opts...) +} + func (m *defaultUser) UserItems(ctx context.Context, in *UserItemsReq, opts ...grpc.CallOption) (*Response, error) { client := user.NewUserClient(m.cli.Conn()) return client.UserItems(ctx, in, opts...) @@ -82,25 +71,21 @@ func (m *defaultUser) UserStatus(ctx context.Context, in *UserStatusReq, opts .. return client.UserStatus(ctx, in, opts...) } -// 内部:业务创建销售/门店时调用 func (m *defaultUser) EnsureBizIdentity(ctx context.Context, in *EnsureBizIdentityReq, opts ...grpc.CallOption) (*EnsureBizIdentityData, error) { client := user.NewUserClient(m.cli.Conn()) return client.EnsureBizIdentity(ctx, in, opts...) } -// 内部:批量查用户基础信息 func (m *defaultUser) UsersByIds(ctx context.Context, in *UsersByIdsReq, opts ...grpc.CallOption) (*UsersByIdsData, error) { client := user.NewUserClient(m.cli.Conn()) return client.UsersByIds(ctx, in, opts...) } -// 内部:修改手机号 func (m *defaultUser) UpdateMobile(ctx context.Context, in *UpdateMobileReq, opts ...grpc.CallOption) (*UpdateMobileData, error) { client := user.NewUserClient(m.cli.Conn()) return client.UpdateMobile(ctx, in, opts...) } -// 内部:撤销业务端开通 func (m *defaultUser) RevokeBizClient(ctx context.Context, in *RevokeBizClientReq, opts ...grpc.CallOption) (*RevokeBizClientData, error) { client := user.NewUserClient(m.cli.Conn()) return client.RevokeBizClient(ctx, in, opts...) diff --git a/services/user/validator/user.go b/services/user/validator/user.go index cef3e4c..99e5714 100644 --- a/services/user/validator/user.go +++ b/services/user/validator/user.go @@ -2,56 +2,25 @@ package validator import "lone-services/pkg/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"` + ClientCode string `validate:"required,max=32"` + GrantType string `validate:"required,oneof=openid password sms"` + Code string `validate:"required_if=GrantType openid,omitempty,max=128"` + Mobile string `validate:"required_if=GrantType password,omitempty,required_if=GrantType sms,omitempty,max=20"` + Password string `validate:"required_if=GrantType password,omitempty,max=64"` + SmsCode string `validate:"required_if=GrantType sms,omitempty,max=8"` } func (p LoginValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{ - "Openid.required": "Openid不能为空", + "ClientCode.required": "端编码不能为空", + "ClientCode.max": "端编码过长", + "GrantType.required": "登录方式不能为空", + "GrantType.oneof": "登录方式不正确", + "Code.required_if": "微信code不能为空", + "Mobile.required_if": "手机号不能为空", + "Password.required_if": "密码不能为空", + "SmsCode.required_if": "验证码不能为空", } }