From a65b6d280360463b4673b573b99ec2ec545e9762 Mon Sep 17 00:00:00 2001 From: zzw <1464003642@qq.com> Date: Thu, 15 Oct 2026 09:23:07 +0800 Subject: [PATCH] feat: analysis user auth and ws --- bff/internal/request/user.go | 7 + deploy/apisix/apisix.yaml | 20 + deploy/apisix/lua/auth.lua | 12 +- pkg/utils/jwt.go | 3 +- pkg/utils/loginInfo.go | 2 + pkg/utils/status.go | 3 + pkg/utils/time.go | 24 +- pkg/wechat/qrcode/client.go | 10 +- pkg/wechat/qrcode/types.go | 3 +- pkg/wechat/qrcode/unlimited.go | 6 +- pkg/wechat/qrcode/wxacode.go | 10 +- pkg/ws/publish.go | 90 +++ pkg/ws/types.go | 52 ++ rpc/analysis/analysis.pb | Bin 13967 -> 15585 bytes rpc/analysis/analysis.proto | 125 +++- rpc/analysis/pb/analysis.pb.go | 703 ++++++++++++++++-- rpc/analysis/pb/analysis_grpc.pb.go | 616 ++++++++++++++- rpc/scripts/gen-rpc.sh | 12 +- rpc/user/pb/user.pb.go | 416 +++++++++-- rpc/user/pb/user_grpc.pb.go | 152 ++++ rpc/user/user.pb | Bin 17592 -> 18341 bytes rpc/user/user.proto | 45 +- services/analysis/analysis.go | 10 +- services/analysis/analysis/analysis.pb.go | 174 ----- .../analysis/analysis/analysis_grpc.pb.go | 121 --- .../analysis/analysisauth/analysisAuth.go | 38 - services/analysis/client/analysis/analysis.go | 53 ++ .../client/analysisdevice/analysisDevice.go | 24 + .../client/analysisstore/analysisStore.go | 49 ++ .../client/analysisuser/analysisUser.go | 68 ++ services/analysis/internal/config/wechat.go | 29 +- services/analysis/internal/dao/agreement.go | 20 + services/analysis/internal/dao/authorize.go | 14 + services/analysis/internal/dao/const.go | 12 + services/analysis/internal/dao/qrcode.go | 17 - services/analysis/internal/dao/user.go | 21 + .../logic/analysis/agreementInfoLogic.go | 56 ++ .../logic/analysis/internalCreateUserLogic.go | 43 ++ .../internal/logic/analysis/switchLogic.go | 50 ++ .../internal/logic/analysisdevice/doc.go | 1 + .../logic/analysisstore/storeAuthLogic.go | 87 +++ .../analysisstore/storeAuthQrcodeLogic.go | 126 ++++ .../logic/analysisuser/faceBindLogic.go | 65 ++ .../logic/analysisuser/userAuthLogic.go | 77 ++ .../logic/analysisuser/userDeleteLogic.go | 48 ++ .../logic/analysisuser/userImproveLogic.go | 147 ++++ .../logic/analysisuser/userRegisterLogic.go | 107 +++ .../internal/logic/common/authorize.go | 59 ++ .../analysis/internal/logic/common/helper.go | 61 ++ .../internal/logic/{ => common}/response.go | 8 +- services/analysis/internal/model/agreement.go | 16 + services/analysis/internal/model/authorize.go | 23 + services/analysis/internal/model/user.go | 23 + .../server/analysis/analysisServer.go | 39 + .../internal/server/analysisAuthServer.go | 29 - .../analysisdevice/analysisDeviceServer.go | 21 + .../analysisstore/analysisStoreServer.go | 36 + .../server/analysisuser/analysisUserServer.go | 50 ++ .../analysis/internal/svc/servicecontext.go | 32 +- services/analysis/run.toml | 12 +- services/analysis/validator/user.go | 106 +++ services/chore/internal/logic/testLogic.go | 33 +- .../internal/logic/userItemsLogic.go | 4 +- .../product/internal/logic/apiInfoLogic.go | 9 +- .../internal/logic/applyVerifyStatusLogic.go | 8 +- services/store/internal/logic/createLogic.go | 10 +- services/store/internal/logic/editLogic.go | 10 +- .../store/internal/logic/getInfoByIdLogic.go | 4 +- .../store/internal/logic/verifyEditLogic.go | 12 +- .../store/internal/logic/verifyStatusLogic.go | 6 +- services/user/internal/config/wechat.go | 51 +- services/user/internal/dao/session.go | 52 +- services/user/internal/dao/user.go | 16 +- services/user/internal/logic/authHelper.go | 71 +- services/user/internal/logic/bizUser.go | 75 ++ .../internal/logic/generateQrcodeLogic.go | 51 +- .../user/internal/logic/getOpenidLogic.go | 4 +- services/user/internal/logic/infoLogic.go | 8 +- .../internal/logic/internalCreateLogic.go | 20 +- .../logic/internalVerifyPasswordLogic.go | 84 +++ services/user/internal/logic/loginLogic.go | 18 +- .../user/internal/logic/qrcodeLoginLogic.go | 97 +++ .../user/internal/logic/qrcodeScanLogic.go | 46 ++ services/user/internal/logic/response.go | 18 +- services/user/internal/logic/storeClient.go | 34 + services/user/internal/server/userServer.go | 20 + services/user/internal/svc/rpcclient.go | 68 ++ services/user/internal/svc/servicecontext.go | 26 +- services/user/userClient/user.go | 29 + services/user/validator/user.go | 54 ++ services/ws/etc/ws.yaml | 7 + services/ws/internal/config/config.go | 16 + .../ws/internal/handler/connectHandler.go | 26 + services/ws/internal/handler/routes.go | 24 + services/ws/internal/logic/connectLogic.go | 126 ++++ services/ws/internal/svc/hub.go | 62 ++ services/ws/internal/svc/serviceContext.go | 31 + services/ws/internal/svc/subscriber.go | 78 ++ services/ws/internal/types/types.go | 8 + services/ws/run.toml | 27 + services/ws/ws.api | 14 + services/ws/ws.go | 112 +++ 102 files changed, 4966 insertions(+), 786 deletions(-) create mode 100644 pkg/ws/publish.go create mode 100644 pkg/ws/types.go delete mode 100644 services/analysis/analysis/analysis.pb.go delete mode 100644 services/analysis/analysis/analysis_grpc.pb.go delete mode 100644 services/analysis/analysisauth/analysisAuth.go create mode 100644 services/analysis/client/analysis/analysis.go create mode 100644 services/analysis/client/analysisdevice/analysisDevice.go create mode 100644 services/analysis/client/analysisstore/analysisStore.go create mode 100644 services/analysis/client/analysisuser/analysisUser.go create mode 100644 services/analysis/internal/dao/agreement.go create mode 100644 services/analysis/internal/dao/authorize.go create mode 100644 services/analysis/internal/dao/const.go delete mode 100644 services/analysis/internal/dao/qrcode.go create mode 100644 services/analysis/internal/dao/user.go create mode 100644 services/analysis/internal/logic/analysis/agreementInfoLogic.go create mode 100644 services/analysis/internal/logic/analysis/internalCreateUserLogic.go create mode 100644 services/analysis/internal/logic/analysis/switchLogic.go create mode 100644 services/analysis/internal/logic/analysisdevice/doc.go create mode 100644 services/analysis/internal/logic/analysisstore/storeAuthLogic.go create mode 100644 services/analysis/internal/logic/analysisstore/storeAuthQrcodeLogic.go create mode 100644 services/analysis/internal/logic/analysisuser/faceBindLogic.go create mode 100644 services/analysis/internal/logic/analysisuser/userAuthLogic.go create mode 100644 services/analysis/internal/logic/analysisuser/userDeleteLogic.go create mode 100644 services/analysis/internal/logic/analysisuser/userImproveLogic.go create mode 100644 services/analysis/internal/logic/analysisuser/userRegisterLogic.go create mode 100644 services/analysis/internal/logic/common/authorize.go create mode 100644 services/analysis/internal/logic/common/helper.go rename services/analysis/internal/logic/{ => common}/response.go (68%) create mode 100644 services/analysis/internal/model/agreement.go create mode 100644 services/analysis/internal/model/authorize.go create mode 100644 services/analysis/internal/model/user.go create mode 100644 services/analysis/internal/server/analysis/analysisServer.go delete mode 100644 services/analysis/internal/server/analysisAuthServer.go create mode 100644 services/analysis/internal/server/analysisdevice/analysisDeviceServer.go create mode 100644 services/analysis/internal/server/analysisstore/analysisStoreServer.go create mode 100644 services/analysis/internal/server/analysisuser/analysisUserServer.go create mode 100644 services/analysis/validator/user.go create mode 100644 services/user/internal/logic/bizUser.go rename services/{analysis => user}/internal/logic/generateQrcodeLogic.go (65%) create mode 100644 services/user/internal/logic/internalVerifyPasswordLogic.go create mode 100644 services/user/internal/logic/qrcodeLoginLogic.go create mode 100644 services/user/internal/logic/qrcodeScanLogic.go create mode 100644 services/user/internal/logic/storeClient.go create mode 100644 services/user/internal/svc/rpcclient.go create mode 100644 services/ws/etc/ws.yaml create mode 100644 services/ws/internal/config/config.go create mode 100644 services/ws/internal/handler/connectHandler.go create mode 100644 services/ws/internal/handler/routes.go create mode 100644 services/ws/internal/logic/connectLogic.go create mode 100644 services/ws/internal/svc/hub.go create mode 100644 services/ws/internal/svc/serviceContext.go create mode 100644 services/ws/internal/svc/subscriber.go create mode 100644 services/ws/internal/types/types.go create mode 100644 services/ws/run.toml create mode 100644 services/ws/ws.api create mode 100644 services/ws/ws.go diff --git a/bff/internal/request/user.go b/bff/internal/request/user.go index b69a977..b04f3ea 100644 --- a/bff/internal/request/user.go +++ b/bff/internal/request/user.go @@ -33,6 +33,7 @@ const ( CtxGroupId ctxKey = "X-Group-Id" CtxGroupName ctxKey = "X-Group-Name" CtxUserType ctxKey = "X-User-Type" + CtxBizId ctxKey = "X-Biz-Id" CtxRawBody ctxKey = "X-Raw-Body" ) @@ -59,6 +60,7 @@ type UserInfo struct { StoreName string GroupId string GroupName string + BizId string RawBody string Valid bool } @@ -79,6 +81,7 @@ func GetUserInfo(ctx context.Context) UserInfo { storeName, _ := ctx.Value(CtxStoreName).(string) groupId, _ := ctx.Value(CtxGroupId).(string) groupName, _ := ctx.Value(CtxGroupName).(string) + bizId, _ := ctx.Value(CtxBizId).(string) rawBody, _ := ctx.Value(CtxRawBody).(string) info := UserInfo{ @@ -97,6 +100,7 @@ func GetUserInfo(ctx context.Context) UserInfo { StoreName: storeName, GroupId: groupId, GroupName: groupName, + BizId: bizId, RawBody: rawBody, } if rawUID == "" { @@ -151,6 +155,7 @@ func UserReadMiddleware(next http.HandlerFunc) http.HandlerFunc { 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")) + newCtx = context.WithValue(newCtx, CtxBizId, r.Header.Get("X-Biz-Id")) next(w, r.WithContext(newCtx)) } } @@ -201,6 +206,7 @@ func UserClientInterceptor(ctx context.Context, method string, req, reply any, c if user.GroupName != utils.StringEmpty { md.Set("x-group-name", url.QueryEscape(user.GroupName)) } + setMDIfNotEmpty(md, "x-biz-id", user.BizId) ctx = metadata.NewOutgoingContext(ctx, md) return invoker(ctx, method, req, reply, cc, opts...) @@ -238,6 +244,7 @@ func UserStreamInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc. if user.GroupName != utils.StringEmpty { md.Set("x-group-name", url.QueryEscape(user.GroupName)) } + setMDIfNotEmpty(md, "x-biz-id", user.BizId) newCtx := metadata.NewOutgoingContext(ctx, md) return streamer(newCtx, desc, cc, method, opts...) diff --git a/deploy/apisix/apisix.yaml b/deploy/apisix/apisix.yaml index 669455e..73c63f1 100644 --- a/deploy/apisix/apisix.yaml +++ b/deploy/apisix/apisix.yaml @@ -50,4 +50,24 @@ routes: type: roundrobin nodes: "bff:10001": 1 + + - id: ws + name: ws + priority: 30 + uris: + - /ws + methods: + - GET + enable_websocket: true + plugins: + cors: + allow_origins: "*" + allow_methods: "GET" + allow_headers: "Authorization,Authorization-Type,Authorization-Auth,Refresh,X-Refresh,X-Service-Code,Sec-WebSocket-Key,Sec-WebSocket-Version,Sec-WebSocket-Accept,Connection,Upgrade" + max_age: 86400 + upstream: + type: roundrobin + nodes: + "ws:10002": 1 + #END diff --git a/deploy/apisix/lua/auth.lua b/deploy/apisix/lua/auth.lua index 4b3a5dc..307b0f8 100644 --- a/deploy/apisix/lua/auth.lua +++ b/deploy/apisix/lua/auth.lua @@ -24,7 +24,12 @@ function _M.access(conf, ctx) ["/api/v3/chore/oss/upload"] = true, - ["/api/v2/analysis/qrcode/generate"] = true, + ["/api/v3/user/qrcode/generate"] = true, + ["/api/v3/user/qrcode/scan"] = true, + + ["/api/v2/analysis/agreement/info"] = true, + ["/api/v2/analysis/switch"] = true, + ["/api/v2/analysis/user/delete"] = true, } local user_key = core.request.header(ctx, "authorization") @@ -71,7 +76,7 @@ function _M.access(conf, ctx) end local res, err = red:get(redis_key) - core.log.error("AUTH_DEBUG host=", redis_host, + core.log.info("AUTH_DEBUG host=", redis_host, " port=", redis_port, " password=", redis_password, " db=", redis_db, @@ -143,6 +148,9 @@ function _M.access(conf, ctx) if json.client_code then ngx.req.set_header("X-Client-Code", tostring(json.client_code)) end + if json.biz_id then + ngx.req.set_header("X-Biz-Id", tostring(json.biz_id)) + end end ngx.req.set_header("X-Refresh", refresh or "") diff --git a/pkg/utils/jwt.go b/pkg/utils/jwt.go index eee7b9e..73a9292 100644 --- a/pkg/utils/jwt.go +++ b/pkg/utils/jwt.go @@ -43,8 +43,7 @@ type Claims struct { 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"` + BizId int64 `json:"biz_id,omitempty"` TokenType string `json:"token_type"` // access | refresh jwt.RegisteredClaims } diff --git a/pkg/utils/loginInfo.go b/pkg/utils/loginInfo.go index 9c3d25b..9ca3d78 100644 --- a/pkg/utils/loginInfo.go +++ b/pkg/utils/loginInfo.go @@ -29,6 +29,7 @@ type UserInfo struct { GroupName string // 分组名称 Type uint8 // 用户类型 ClientCode string + BizId int64 Valid bool } @@ -72,6 +73,7 @@ func GetUserFromCtx(ctx context.Context) UserInfo { GroupId: parseInt64MD(md, "x-group-id"), GroupName: firstMD(md, "x-group-name"), ClientCode: firstMD(md, "x-client-code"), + BizId: parseInt64MD(md, "x-biz-id"), } if typeRaw := firstMD(md, "x-user-type"); typeRaw != StringEmpty { diff --git a/pkg/utils/status.go b/pkg/utils/status.go index de2a004..b7a8960 100644 --- a/pkg/utils/status.go +++ b/pkg/utils/status.go @@ -129,6 +129,9 @@ var ( // 参数类 ErrorReasonParams = Status{Code: 10012, Msg: "原因不能为空"} ErrorMobileError = Status{Code: 10013, Msg: "手机号格式错误"} + ErrorQRcodeExp = Status{Code: 10015, Msg: "二维码已过期"} + ErrorNotFace = Status{Code: 10016, Msg: "未检测到人脸"} + ErrorFileUpFailed = Status{Code: 10017, Msg: "文件上传失败"} // ErrorNotFund 数据类 ErrorFormatDataError = Status{Code: 11014, Msg: "格式化数据出错"} diff --git a/pkg/utils/time.go b/pkg/utils/time.go index 1011801..abab91f 100644 --- a/pkg/utils/time.go +++ b/pkg/utils/time.go @@ -73,15 +73,12 @@ func (ct CustomTime) MarshalJSON() ([]byte, error) { // UnmarshalJSON 实现 JSON 反序列化 func (ct *CustomTime) UnmarshalJSON(data []byte) error { - str := string(data) - if str == "null" || str == `""` { + str := strings.Trim(string(data), `"`) + if str == "" || str == "null" || isZeroDate(str) { ct.Time = time.Time{} return nil } - // 去除引号 - str = strings.Trim(str, `"`) - // 尝试解析多种格式 formats := []string{ "2006-01-02", @@ -122,14 +119,27 @@ func (ct *CustomTime) Scan(value interface{}) error { ct.Time = v return nil case []byte: - return ct.UnmarshalJSON(v) + return ct.scanString(string(v)) case string: - return ct.UnmarshalJSON([]byte(v)) + return ct.scanString(v) default: return fmt.Errorf("unsupported type: %T", value) } } +func (ct *CustomTime) scanString(s string) error { + s = strings.TrimSpace(s) + if s == "" || isZeroDate(s) { + ct.Time = time.Time{} + return nil + } + return ct.UnmarshalJSON([]byte(`"` + s + `"`)) +} + +func isZeroDate(s string) bool { + return s == "0000-00-00" || s == "0000-00-00 00:00:00" +} + // GormDataType 定义 GORM 数据库类型 func (CustomTime) GormDataType() string { return "datetime" diff --git a/pkg/wechat/qrcode/client.go b/pkg/wechat/qrcode/client.go index 6a3e333..26d0930 100644 --- a/pkg/wechat/qrcode/client.go +++ b/pkg/wechat/qrcode/client.go @@ -1,13 +1,13 @@ package qrcode +import "lone-services/pkg/wechat/auth" + type Client struct { - AppID string - Secret string + Auth *auth.Client } -func NewClient(appID, secret string) *Client { +func NewClient(authCli *auth.Client) *Client { return &Client{ - AppID: appID, - Secret: secret, + Auth: authCli, } } diff --git a/pkg/wechat/qrcode/types.go b/pkg/wechat/qrcode/types.go index 7527cf3..a73c2a4 100644 --- a/pkg/wechat/qrcode/types.go +++ b/pkg/wechat/qrcode/types.go @@ -17,10 +17,9 @@ type UnlimitedRequest struct { IsHyaline bool `json:"is_hyaline,omitempty"` } -// WxaCodeRequest 有数量限制的小程序码(getwxacode),path 可带 query。 type WxaCodeRequest struct { Path string `json:"path"` - EnvVersion string `json:"env_version,omitempty"` + EnvVersion string `json:"env_version,omitempty"` // release / trial / develop Width int `json:"width,omitempty"` AutoColor bool `json:"auto_color,omitempty"` LineColor *LineColor `json:"line_color,omitempty"` diff --git a/pkg/wechat/qrcode/unlimited.go b/pkg/wechat/qrcode/unlimited.go index d9ab7d6..1ad8d56 100644 --- a/pkg/wechat/qrcode/unlimited.go +++ b/pkg/wechat/qrcode/unlimited.go @@ -13,7 +13,6 @@ import ( "time" "lone-services/pkg/utils" - "lone-services/pkg/wechat/auth" ) const unlimitedURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit" @@ -54,7 +53,10 @@ func (c *Client) GetUnlimited(accessToken string, req *UnlimitedRequest) ([]byte } func (c *Client) CreateUnlimited(ctx context.Context, req *UnlimitedRequest) ([]byte, error) { - token, err := auth.NewClient(c.AppID, c.Secret).AccessToken(ctx) + if c == nil || c.Auth == nil { + return nil, fmt.Errorf("wechat qrcode auth client nil") + } + token, err := c.Auth.AccessToken(ctx) if err != nil { return nil, err } diff --git a/pkg/wechat/qrcode/wxacode.go b/pkg/wechat/qrcode/wxacode.go index e42d855..5048f5d 100644 --- a/pkg/wechat/qrcode/wxacode.go +++ b/pkg/wechat/qrcode/wxacode.go @@ -11,13 +11,10 @@ import ( "time" "lone-services/pkg/utils" - "lone-services/pkg/wechat/auth" ) -// 小程序码(有数量限制):https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getQRCode.html const wxaCodeURL = "https://api.weixin.qq.com/wxa/getwxacode" -// BuildPath 拼小程序 path,如 pagesB/userLogin/index?session_id=xxx func BuildPath(page string, params map[string]string) string { if len(params) == 0 { return page @@ -29,7 +26,6 @@ func BuildPath(page string, params map[string]string) string { return page + "?" + query.Encode() } -// GetWxaCode 使用已有 access_token 生成有限小程序码,成功返回图片二进制。 func (c *Client) GetWxaCode(accessToken string, req *WxaCodeRequest) ([]byte, error) { if accessToken == utils.StringEmpty { return nil, fmt.Errorf("wechat access_token empty") @@ -65,9 +61,11 @@ func (c *Client) GetWxaCode(accessToken string, req *WxaCodeRequest) ([]byte, er return body, nil } -// CreateWxaCode 通过 auth 拉取 access_token 后生成有限小程序码。 func (c *Client) CreateWxaCode(ctx context.Context, req *WxaCodeRequest) ([]byte, error) { - token, err := auth.NewClient(c.AppID, c.Secret).AccessToken(ctx) + if c == nil || c.Auth == nil { + return nil, fmt.Errorf("wechat qrcode auth client nil") + } + token, err := c.Auth.AccessToken(ctx) if err != nil { return nil, err } diff --git a/pkg/ws/publish.go b/pkg/ws/publish.go new file mode 100644 index 0000000..2533752 --- /dev/null +++ b/pkg/ws/publish.go @@ -0,0 +1,90 @@ +package ws + +import ( + "context" + "fmt" + + "lone-services/pkg/redis" + + jsoniter "github.com/json-iterator/go" +) + +func Publish(ctx context.Context, sessionID string, resp Response) error { + if redis.Client == nil { + return fmt.Errorf("ws: redis not initialized") + } + if sessionID == "" { + return fmt.Errorf("ws: session_id empty") + } + + var dataRaw []byte + if resp.Data != nil { + b, err := jsoniter.Marshal(resp.Data) + if err != nil { + return err + } + dataRaw = b + } + + evt := Event{ + SessionID: sessionID, + Code: resp.Code, + Message: resp.Message, + Data: dataRaw, + } + payload, err := jsoniter.Marshal(evt) + if err != nil { + return err + } + return redis.Client.Publish(ctx, RedisChannelQRPush, payload).Err() +} + +func UpdateSessionAndPublish(ctx context.Context, sessionID string, status int, data interface{}) error { + if redis.Client == nil { + return fmt.Errorf("ws: redis not initialized") + } + if sessionID == "" { + return fmt.Errorf("ws: session_id empty") + } + + sess := Session{Status: status} + if old, err := GetSession(ctx, sessionID); err == nil && old != nil { + sess.ClientCode = old.ClientCode + } + if data != nil { + b, err := jsoniter.Marshal(data) + if err != nil { + return err + } + sess.Data = b + } + + raw, err := jsoniter.Marshal(sess) + if err != nil { + return err + } + key := RedisKeyQRSession + sessionID + if err := redis.Client.Set(ctx, key, raw, SessionTTL).Err(); err != nil { + return err + } + return Publish(ctx, sessionID, Success(data)) +} + +func GetSession(ctx context.Context, sessionID string) (*Session, error) { + if redis.Client == nil { + return nil, fmt.Errorf("ws: redis not initialized") + } + if sessionID == "" { + return nil, fmt.Errorf("ws: session_id empty") + } + + val, err := redis.Client.Get(ctx, RedisKeyQRSession+sessionID).Result() + if err != nil { + return nil, err + } + var sess Session + if err := jsoniter.UnmarshalFromString(val, &sess); err != nil { + return nil, err + } + return &sess, nil +} diff --git a/pkg/ws/types.go b/pkg/ws/types.go new file mode 100644 index 0000000..a7f3718 --- /dev/null +++ b/pkg/ws/types.go @@ -0,0 +1,52 @@ +package ws + +import ( + "encoding/json" + "time" +) + +const ( + RedisKeyQRSession = "qr:session:" + RedisChannelQRPush = "ws:qr:push" + + StatusPending = 1 // 待扫码 + StatusScanned = 2 // 已扫码未登录 + StatusLogined = 3 // 已扫码已登录 + + WsTypeLogin = 1 // 同意登录 + WsTypeScanned = 2 // 拒绝授权 / 拒绝登录 + WsTypeScan = 3 // 进入扫码页通知 + + SessionTTL = 5 * time.Minute + + CodeOK = 200 + MsgOK = "success" + CodeErr = 500 +) + +type Session struct { + Status int `json:"status"` + ClientCode string `json:"client_code,omitempty"` + Data json.RawMessage `json:"data,omitempty"` +} + +type Response struct { + Code int `json:"code"` + Message string `json:"message"` + Data interface{} `json:"data"` +} + +type Event struct { + SessionID string `json:"session_id"` + Code int `json:"code"` + Message string `json:"message"` + Data json.RawMessage `json:"data"` +} + +func Success(data interface{}) Response { + return Response{Code: CodeOK, Message: MsgOK, Data: data} +} + +func Fail(msg string) Response { + return Response{Code: CodeErr, Message: msg, Data: nil} +} diff --git a/rpc/analysis/analysis.pb b/rpc/analysis/analysis.pb index 03dafbea4061ec94720a95f5337c479ab4655de5..816f373dc0e1c3b45e4ca572a15d86330f906756 100644 GIT binary patch delta 1814 zcma)6%Wl&^6jjn!GEE;EXzQkdl!4< zI=u7R6!2W`|@w9jJ1}=`zVm+sJHZ4reU*W4|+G8E@6PeYZCdaG9=?c|L%% zu0EExLW>qj&XLWw!@I)B0)U^lVh08r(p4>+4~-cJLM*Zou-j|Mjxc6*B(%_fB^+D0 z#vJ(Ptk6QNKKH!ao@*QP0aj#V%$A;VWmEaaLJ*7`)F2Dowq4owM{mE0ZPUu8NLOI>8TXP$v2FTdA6@X$WmnI9EMaoZcvX29j{&2_NbX zrNCN3w!xw8vFu@)AQoqDhb#?vN7_;i>q^4qpj3s(`2l?FF`+Trdlz#A?_!)RqKfDV zAk=@Tlx~uohwrRIiy`%lwV>^qP5+0v@;ys(r_jtpPkQttq3Ir``PcF`(CSmMJibU&>!JQARB06);Cz6u+-0Dd!->#SOY5*rqGdtX6H&2q8s)xD+&0@vNzy}XA}14BoAYn(BM(vloe*q-IPJ#dc delta 182 zcmaD@*`K??$&~3d(_|M@Ckb&bQTNom)S|?a)WD+T{FKz7)WXu#;*!a&rf&5{O^jST zj(LeWmBpFGj-@3TLPcDBsLF-p^%9{9^iXA>21yAa6a=Lf7v$#^rz&YTU4Al|NmWTf hKd~TFzsyJv<8USULL1+K~ diff --git a/rpc/analysis/analysis.proto b/rpc/analysis/analysis.proto index 767ba1a..7a08293 100644 --- a/rpc/analysis/analysis.proto +++ b/rpc/analysis/analysis.proto @@ -1,23 +1,136 @@ syntax = "proto3"; package analysis; -import "google/api/annotations.proto"; option go_package = "lone-services/rpc/analysis"; -service AnalysisAuth { - rpc GenerateQrcode(GenerateQrcodeRequest) returns(Response){ +import "google/api/annotations.proto"; + +service Analysis { + rpc InternalCreateUser(InternalCreateUserReq) returns (InternalCreateUserData); + + rpc AgreementInfo(AgreementInfoReq) returns (Response) { option (google.api.http) = { - post: "/api/v2/analysis/qrcode/generate" + post: "/api/v2/analysis/agreement/info" body: "*" }; - }; + } + + rpc Switch(SwitchReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/switch" + body: "*" + }; + } } -message GenerateQrcodeRequest { +service AnalysisUser { + rpc UserRegister(UserRegisterReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/user/register" + body: "*" + }; + } + + rpc FaceBind(FaceBindReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/face/bind" + body: "*" + }; + } + + rpc UserImprove(UserImproveReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/user/improve" + body: "*" + }; + } + + rpc UserDelete(UserDeleteReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/user/delete" + body: "*" + }; + } + + rpc UserAuth(UserAuthReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/user/auth" + body: "*" + }; + } } +service AnalysisStore { + rpc StoreAuth(StoreAuthReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/store/auth" + body: "*" + }; + } + + rpc StoreAuthQrcode(StoreAuthQrcodeReq) returns (Response) { + option (google.api.http) = { + post: "/api/v2/analysis/store/auth/qrcode" + body: "*" + }; + } +} + +service AnalysisDevice {} + message Response { int32 code = 1; string msg = 2; string data = 3; } + +message InternalCreateUserReq {} + +message InternalCreateUserData { + int64 id = 1; +} + +message UserImproveReq { + string avatar = 1; + string nickname = 2; + string birthday = 3; + string mobile = 4; + int32 gender = 5; + string password = 6; + string district = 7; + string address = 8; +} + +message UserRegisterReq { + string code = 1; +} + +message FaceBindReq { + string face_path = 1; +} + +message AgreementInfoReq { + int32 type = 1; +} + +message UserDeleteReq { + int64 id = 1; +} + +message SwitchReq { + int32 type = 1; +} + +message StoreAuthReq { + string username = 1; + string password = 2; + string validity_time = 3; +} + +message StoreAuthQrcodeReq {} + +message UserAuthReq { + int32 type = 1; + int64 store_id = 2; + string validity_time = 3; +} diff --git a/rpc/analysis/pb/analysis.pb.go b/rpc/analysis/pb/analysis.pb.go index 7c2c7b8..b2b90b1 100644 --- a/rpc/analysis/pb/analysis.pb.go +++ b/rpc/analysis/pb/analysis.pb.go @@ -22,42 +22,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type GenerateQrcodeRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GenerateQrcodeRequest) Reset() { - *x = GenerateQrcodeRequest{} - mi := &file_analysis_analysis_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GenerateQrcodeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GenerateQrcodeRequest) ProtoMessage() {} - -func (x *GenerateQrcodeRequest) ProtoReflect() protoreflect.Message { - mi := &file_analysis_analysis_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GenerateQrcodeRequest.ProtoReflect.Descriptor instead. -func (*GenerateQrcodeRequest) Descriptor() ([]byte, []int) { - return file_analysis_analysis_proto_rawDescGZIP(), []int{0} -} - type Response struct { state protoimpl.MessageState `protogen:"open.v1"` Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` @@ -69,7 +33,7 @@ type Response struct { func (x *Response) Reset() { *x = Response{} - mi := &file_analysis_analysis_proto_msgTypes[1] + mi := &file_analysis_analysis_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -81,7 +45,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_analysis_analysis_proto_msgTypes[1] + mi := &file_analysis_analysis_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -94,7 +58,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_analysis_analysis_proto_rawDescGZIP(), []int{1} + return file_analysis_analysis_proto_rawDescGZIP(), []int{0} } func (x *Response) GetCode() int32 { @@ -118,18 +82,617 @@ func (x *Response) GetData() string { return "" } +type InternalCreateUserReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InternalCreateUserReq) Reset() { + *x = InternalCreateUserReq{} + mi := &file_analysis_analysis_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InternalCreateUserReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InternalCreateUserReq) ProtoMessage() {} + +func (x *InternalCreateUserReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_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 InternalCreateUserReq.ProtoReflect.Descriptor instead. +func (*InternalCreateUserReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{1} +} + +type InternalCreateUserData struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InternalCreateUserData) Reset() { + *x = InternalCreateUserData{} + mi := &file_analysis_analysis_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InternalCreateUserData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InternalCreateUserData) ProtoMessage() {} + +func (x *InternalCreateUserData) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_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 InternalCreateUserData.ProtoReflect.Descriptor instead. +func (*InternalCreateUserData) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{2} +} + +func (x *InternalCreateUserData) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type UserImproveReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Avatar string `protobuf:"bytes,1,opt,name=avatar,proto3" json:"avatar,omitempty"` + Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` + Birthday string `protobuf:"bytes,3,opt,name=birthday,proto3" json:"birthday,omitempty"` + Mobile string `protobuf:"bytes,4,opt,name=mobile,proto3" json:"mobile,omitempty"` + Gender int32 `protobuf:"varint,5,opt,name=gender,proto3" json:"gender,omitempty"` + Password string `protobuf:"bytes,6,opt,name=password,proto3" json:"password,omitempty"` + District string `protobuf:"bytes,7,opt,name=district,proto3" json:"district,omitempty"` + Address string `protobuf:"bytes,8,opt,name=address,proto3" json:"address,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserImproveReq) Reset() { + *x = UserImproveReq{} + mi := &file_analysis_analysis_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserImproveReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserImproveReq) ProtoMessage() {} + +func (x *UserImproveReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UserImproveReq.ProtoReflect.Descriptor instead. +func (*UserImproveReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{3} +} + +func (x *UserImproveReq) GetAvatar() string { + if x != nil { + return x.Avatar + } + return "" +} + +func (x *UserImproveReq) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +func (x *UserImproveReq) GetBirthday() string { + if x != nil { + return x.Birthday + } + return "" +} + +func (x *UserImproveReq) GetMobile() string { + if x != nil { + return x.Mobile + } + return "" +} + +func (x *UserImproveReq) GetGender() int32 { + if x != nil { + return x.Gender + } + return 0 +} + +func (x *UserImproveReq) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *UserImproveReq) GetDistrict() string { + if x != nil { + return x.District + } + return "" +} + +func (x *UserImproveReq) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type UserRegisterReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserRegisterReq) Reset() { + *x = UserRegisterReq{} + mi := &file_analysis_analysis_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserRegisterReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserRegisterReq) ProtoMessage() {} + +func (x *UserRegisterReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[4] + 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 UserRegisterReq.ProtoReflect.Descriptor instead. +func (*UserRegisterReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{4} +} + +func (x *UserRegisterReq) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +type FaceBindReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + FacePath string `protobuf:"bytes,1,opt,name=face_path,json=facePath,proto3" json:"face_path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FaceBindReq) Reset() { + *x = FaceBindReq{} + mi := &file_analysis_analysis_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FaceBindReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FaceBindReq) ProtoMessage() {} + +func (x *FaceBindReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[5] + 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 FaceBindReq.ProtoReflect.Descriptor instead. +func (*FaceBindReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{5} +} + +func (x *FaceBindReq) GetFacePath() string { + if x != nil { + return x.FacePath + } + return "" +} + +type AgreementInfoReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type int32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgreementInfoReq) Reset() { + *x = AgreementInfoReq{} + mi := &file_analysis_analysis_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgreementInfoReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgreementInfoReq) ProtoMessage() {} + +func (x *AgreementInfoReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[6] + 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 AgreementInfoReq.ProtoReflect.Descriptor instead. +func (*AgreementInfoReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{6} +} + +func (x *AgreementInfoReq) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + +type UserDeleteReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserDeleteReq) Reset() { + *x = UserDeleteReq{} + mi := &file_analysis_analysis_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserDeleteReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserDeleteReq) ProtoMessage() {} + +func (x *UserDeleteReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[7] + 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 UserDeleteReq.ProtoReflect.Descriptor instead. +func (*UserDeleteReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{7} +} + +func (x *UserDeleteReq) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type SwitchReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type int32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SwitchReq) Reset() { + *x = SwitchReq{} + mi := &file_analysis_analysis_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SwitchReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwitchReq) ProtoMessage() {} + +func (x *SwitchReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[8] + 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 SwitchReq.ProtoReflect.Descriptor instead. +func (*SwitchReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{8} +} + +func (x *SwitchReq) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + +type StoreAuthReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + ValidityTime string `protobuf:"bytes,3,opt,name=validity_time,json=validityTime,proto3" json:"validity_time,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StoreAuthReq) Reset() { + *x = StoreAuthReq{} + mi := &file_analysis_analysis_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StoreAuthReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreAuthReq) ProtoMessage() {} + +func (x *StoreAuthReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[9] + 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 StoreAuthReq.ProtoReflect.Descriptor instead. +func (*StoreAuthReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{9} +} + +func (x *StoreAuthReq) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *StoreAuthReq) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *StoreAuthReq) GetValidityTime() string { + if x != nil { + return x.ValidityTime + } + return "" +} + +type StoreAuthQrcodeReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StoreAuthQrcodeReq) Reset() { + *x = StoreAuthQrcodeReq{} + mi := &file_analysis_analysis_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StoreAuthQrcodeReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoreAuthQrcodeReq) ProtoMessage() {} + +func (x *StoreAuthQrcodeReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_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 StoreAuthQrcodeReq.ProtoReflect.Descriptor instead. +func (*StoreAuthQrcodeReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{10} +} + +type UserAuthReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type int32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` + StoreId int64 `protobuf:"varint,2,opt,name=store_id,json=storeId,proto3" json:"store_id,omitempty"` + ValidityTime string `protobuf:"bytes,3,opt,name=validity_time,json=validityTime,proto3" json:"validity_time,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UserAuthReq) Reset() { + *x = UserAuthReq{} + mi := &file_analysis_analysis_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UserAuthReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UserAuthReq) ProtoMessage() {} + +func (x *UserAuthReq) ProtoReflect() protoreflect.Message { + mi := &file_analysis_analysis_proto_msgTypes[11] + 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 UserAuthReq.ProtoReflect.Descriptor instead. +func (*UserAuthReq) Descriptor() ([]byte, []int) { + return file_analysis_analysis_proto_rawDescGZIP(), []int{11} +} + +func (x *UserAuthReq) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *UserAuthReq) GetStoreId() int64 { + if x != nil { + return x.StoreId + } + return 0 +} + +func (x *UserAuthReq) GetValidityTime() string { + if x != nil { + return x.ValidityTime + } + return "" +} + var File_analysis_analysis_proto protoreflect.FileDescriptor const file_analysis_analysis_proto_rawDesc = "" + "\n" + - "\x17analysis/analysis.proto\x12\banalysis\x1a\x1cgoogle/api/annotations.proto\"\x17\n" + - "\x15GenerateQrcodeRequest\"D\n" + + "\x17analysis/analysis.proto\x12\banalysis\x1a\x1cgoogle/api/annotations.proto\"D\n" + "\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\x04data2\x82\x01\n" + - "\fAnalysisAuth\x12r\n" + - "\x0eGenerateQrcode\x12\x1f.analysis.GenerateQrcodeRequest\x1a\x12.analysis.Response\"+\x82\xd3\xe4\x93\x02%:\x01*\" /api/v2/analysis/qrcode/generateB\x1cZ\x1alone-services/rpc/analysisb\x06proto3" + "\x04data\x18\x03 \x01(\tR\x04data\"\x17\n" + + "\x15InternalCreateUserReq\"(\n" + + "\x16InternalCreateUserData\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"\xe2\x01\n" + + "\x0eUserImproveReq\x12\x16\n" + + "\x06avatar\x18\x01 \x01(\tR\x06avatar\x12\x1a\n" + + "\bnickname\x18\x02 \x01(\tR\bnickname\x12\x1a\n" + + "\bbirthday\x18\x03 \x01(\tR\bbirthday\x12\x16\n" + + "\x06mobile\x18\x04 \x01(\tR\x06mobile\x12\x16\n" + + "\x06gender\x18\x05 \x01(\x05R\x06gender\x12\x1a\n" + + "\bpassword\x18\x06 \x01(\tR\bpassword\x12\x1a\n" + + "\bdistrict\x18\a \x01(\tR\bdistrict\x12\x18\n" + + "\aaddress\x18\b \x01(\tR\aaddress\"%\n" + + "\x0fUserRegisterReq\x12\x12\n" + + "\x04code\x18\x01 \x01(\tR\x04code\"*\n" + + "\vFaceBindReq\x12\x1b\n" + + "\tface_path\x18\x01 \x01(\tR\bfacePath\"&\n" + + "\x10AgreementInfoReq\x12\x12\n" + + "\x04type\x18\x01 \x01(\x05R\x04type\"\x1f\n" + + "\rUserDeleteReq\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"\x1f\n" + + "\tSwitchReq\x12\x12\n" + + "\x04type\x18\x01 \x01(\x05R\x04type\"k\n" + + "\fStoreAuthReq\x12\x1a\n" + + "\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\x12#\n" + + "\rvalidity_time\x18\x03 \x01(\tR\fvalidityTime\"\x14\n" + + "\x12StoreAuthQrcodeReq\"a\n" + + "\vUserAuthReq\x12\x12\n" + + "\x04type\x18\x01 \x01(\x05R\x04type\x12\x19\n" + + "\bstore_id\x18\x02 \x01(\x03R\astoreId\x12#\n" + + "\rvalidity_time\x18\x03 \x01(\tR\fvalidityTime2\xa7\x02\n" + + "\bAnalysis\x12W\n" + + "\x12InternalCreateUser\x12\x1f.analysis.InternalCreateUserReq\x1a .analysis.InternalCreateUserData\x12k\n" + + "\rAgreementInfo\x12\x1a.analysis.AgreementInfoReq\x1a\x12.analysis.Response\"*\x82\xd3\xe4\x93\x02$:\x01*\"\x1f/api/v2/analysis/agreement/info\x12U\n" + + "\x06Switch\x12\x13.analysis.SwitchReq\x1a\x12.analysis.Response\"\"\x82\xd3\xe4\x93\x02\x1c:\x01*\"\x17/api/v2/analysis/switch2\xff\x03\n" + + "\fAnalysisUser\x12h\n" + + "\fUserRegister\x12\x19.analysis.UserRegisterReq\x1a\x12.analysis.Response\")\x82\xd3\xe4\x93\x02#:\x01*\"\x1e/api/v2/analysis/user/register\x12\\\n" + + "\bFaceBind\x12\x15.analysis.FaceBindReq\x1a\x12.analysis.Response\"%\x82\xd3\xe4\x93\x02\x1f:\x01*\"\x1a/api/v2/analysis/face/bind\x12e\n" + + "\vUserImprove\x12\x18.analysis.UserImproveReq\x1a\x12.analysis.Response\"(\x82\xd3\xe4\x93\x02\":\x01*\"\x1d/api/v2/analysis/user/improve\x12b\n" + + "\n" + + "UserDelete\x12\x17.analysis.UserDeleteReq\x1a\x12.analysis.Response\"'\x82\xd3\xe4\x93\x02!:\x01*\"\x1c/api/v2/analysis/user/delete\x12\\\n" + + "\bUserAuth\x12\x15.analysis.UserAuthReq\x1a\x12.analysis.Response\"%\x82\xd3\xe4\x93\x02\x1f:\x01*\"\x1a/api/v2/analysis/user/auth2\xe4\x01\n" + + "\rAnalysisStore\x12_\n" + + "\tStoreAuth\x12\x16.analysis.StoreAuthReq\x1a\x12.analysis.Response\"&\x82\xd3\xe4\x93\x02 :\x01*\"\x1b/api/v2/analysis/store/auth\x12r\n" + + "\x0fStoreAuthQrcode\x12\x1c.analysis.StoreAuthQrcodeReq\x1a\x12.analysis.Response\"-\x82\xd3\xe4\x93\x02':\x01*\"\"/api/v2/analysis/store/auth/qrcode2\x10\n" + + "\x0eAnalysisDeviceB\x1cZ\x1alone-services/rpc/analysisb\x06proto3" var ( file_analysis_analysis_proto_rawDescOnce sync.Once @@ -143,19 +706,47 @@ func file_analysis_analysis_proto_rawDescGZIP() []byte { return file_analysis_analysis_proto_rawDescData } -var file_analysis_analysis_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_analysis_analysis_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_analysis_analysis_proto_goTypes = []any{ - (*GenerateQrcodeRequest)(nil), // 0: analysis.GenerateQrcodeRequest - (*Response)(nil), // 1: analysis.Response + (*Response)(nil), // 0: analysis.Response + (*InternalCreateUserReq)(nil), // 1: analysis.InternalCreateUserReq + (*InternalCreateUserData)(nil), // 2: analysis.InternalCreateUserData + (*UserImproveReq)(nil), // 3: analysis.UserImproveReq + (*UserRegisterReq)(nil), // 4: analysis.UserRegisterReq + (*FaceBindReq)(nil), // 5: analysis.FaceBindReq + (*AgreementInfoReq)(nil), // 6: analysis.AgreementInfoReq + (*UserDeleteReq)(nil), // 7: analysis.UserDeleteReq + (*SwitchReq)(nil), // 8: analysis.SwitchReq + (*StoreAuthReq)(nil), // 9: analysis.StoreAuthReq + (*StoreAuthQrcodeReq)(nil), // 10: analysis.StoreAuthQrcodeReq + (*UserAuthReq)(nil), // 11: analysis.UserAuthReq } var file_analysis_analysis_proto_depIdxs = []int32{ - 0, // 0: analysis.AnalysisAuth.GenerateQrcode:input_type -> analysis.GenerateQrcodeRequest - 1, // 1: analysis.AnalysisAuth.GenerateQrcode:output_type -> analysis.Response - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: analysis.Analysis.InternalCreateUser:input_type -> analysis.InternalCreateUserReq + 6, // 1: analysis.Analysis.AgreementInfo:input_type -> analysis.AgreementInfoReq + 8, // 2: analysis.Analysis.Switch:input_type -> analysis.SwitchReq + 4, // 3: analysis.AnalysisUser.UserRegister:input_type -> analysis.UserRegisterReq + 5, // 4: analysis.AnalysisUser.FaceBind:input_type -> analysis.FaceBindReq + 3, // 5: analysis.AnalysisUser.UserImprove:input_type -> analysis.UserImproveReq + 7, // 6: analysis.AnalysisUser.UserDelete:input_type -> analysis.UserDeleteReq + 11, // 7: analysis.AnalysisUser.UserAuth:input_type -> analysis.UserAuthReq + 9, // 8: analysis.AnalysisStore.StoreAuth:input_type -> analysis.StoreAuthReq + 10, // 9: analysis.AnalysisStore.StoreAuthQrcode:input_type -> analysis.StoreAuthQrcodeReq + 2, // 10: analysis.Analysis.InternalCreateUser:output_type -> analysis.InternalCreateUserData + 0, // 11: analysis.Analysis.AgreementInfo:output_type -> analysis.Response + 0, // 12: analysis.Analysis.Switch:output_type -> analysis.Response + 0, // 13: analysis.AnalysisUser.UserRegister:output_type -> analysis.Response + 0, // 14: analysis.AnalysisUser.FaceBind:output_type -> analysis.Response + 0, // 15: analysis.AnalysisUser.UserImprove:output_type -> analysis.Response + 0, // 16: analysis.AnalysisUser.UserDelete:output_type -> analysis.Response + 0, // 17: analysis.AnalysisUser.UserAuth:output_type -> analysis.Response + 0, // 18: analysis.AnalysisStore.StoreAuth:output_type -> analysis.Response + 0, // 19: analysis.AnalysisStore.StoreAuthQrcode:output_type -> analysis.Response + 10, // [10:20] is the sub-list for method output_type + 0, // [0:10] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_analysis_analysis_proto_init() } @@ -169,9 +760,9 @@ func file_analysis_analysis_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_analysis_analysis_proto_rawDesc), len(file_analysis_analysis_proto_rawDesc)), NumEnums: 0, - NumMessages: 2, + NumMessages: 12, NumExtensions: 0, - NumServices: 1, + NumServices: 4, }, GoTypes: file_analysis_analysis_proto_goTypes, DependencyIndexes: file_analysis_analysis_proto_depIdxs, diff --git a/rpc/analysis/pb/analysis_grpc.pb.go b/rpc/analysis/pb/analysis_grpc.pb.go index 760a40c..45d27e7 100644 --- a/rpc/analysis/pb/analysis_grpc.pb.go +++ b/rpc/analysis/pb/analysis_grpc.pb.go @@ -19,103 +19,639 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - AnalysisAuth_GenerateQrcode_FullMethodName = "/analysis.AnalysisAuth/GenerateQrcode" + Analysis_InternalCreateUser_FullMethodName = "/analysis.Analysis/InternalCreateUser" + Analysis_AgreementInfo_FullMethodName = "/analysis.Analysis/AgreementInfo" + Analysis_Switch_FullMethodName = "/analysis.Analysis/Switch" ) -// AnalysisAuthClient is the client API for AnalysisAuth service. +// AnalysisClient is the client API for Analysis service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type AnalysisAuthClient interface { - GenerateQrcode(ctx context.Context, in *GenerateQrcodeRequest, opts ...grpc.CallOption) (*Response, error) +type AnalysisClient interface { + InternalCreateUser(ctx context.Context, in *InternalCreateUserReq, opts ...grpc.CallOption) (*InternalCreateUserData, error) + AgreementInfo(ctx context.Context, in *AgreementInfoReq, opts ...grpc.CallOption) (*Response, error) + Switch(ctx context.Context, in *SwitchReq, opts ...grpc.CallOption) (*Response, error) } -type analysisAuthClient struct { +type analysisClient struct { cc grpc.ClientConnInterface } -func NewAnalysisAuthClient(cc grpc.ClientConnInterface) AnalysisAuthClient { - return &analysisAuthClient{cc} +func NewAnalysisClient(cc grpc.ClientConnInterface) AnalysisClient { + return &analysisClient{cc} } -func (c *analysisAuthClient) GenerateQrcode(ctx context.Context, in *GenerateQrcodeRequest, opts ...grpc.CallOption) (*Response, error) { +func (c *analysisClient) InternalCreateUser(ctx context.Context, in *InternalCreateUserReq, opts ...grpc.CallOption) (*InternalCreateUserData, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(Response) - err := c.cc.Invoke(ctx, AnalysisAuth_GenerateQrcode_FullMethodName, in, out, cOpts...) + out := new(InternalCreateUserData) + err := c.cc.Invoke(ctx, Analysis_InternalCreateUser_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -// AnalysisAuthServer is the server API for AnalysisAuth service. -// All implementations must embed UnimplementedAnalysisAuthServer -// for forward compatibility. -type AnalysisAuthServer interface { - GenerateQrcode(context.Context, *GenerateQrcodeRequest) (*Response, error) - mustEmbedUnimplementedAnalysisAuthServer() +func (c *analysisClient) AgreementInfo(ctx context.Context, in *AgreementInfoReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Analysis_AgreementInfo_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil } -// UnimplementedAnalysisAuthServer must be embedded to have +func (c *analysisClient) Switch(ctx context.Context, in *SwitchReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, Analysis_Switch_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AnalysisServer is the server API for Analysis service. +// All implementations must embed UnimplementedAnalysisServer +// for forward compatibility. +type AnalysisServer interface { + InternalCreateUser(context.Context, *InternalCreateUserReq) (*InternalCreateUserData, error) + AgreementInfo(context.Context, *AgreementInfoReq) (*Response, error) + Switch(context.Context, *SwitchReq) (*Response, error) + mustEmbedUnimplementedAnalysisServer() +} + +// UnimplementedAnalysisServer must be embedded to have // forward compatible implementations. // // NOTE: this should be embedded by value instead of pointer to avoid a nil // pointer dereference when methods are called. -type UnimplementedAnalysisAuthServer struct{} +type UnimplementedAnalysisServer struct{} -func (UnimplementedAnalysisAuthServer) GenerateQrcode(context.Context, *GenerateQrcodeRequest) (*Response, error) { - return nil, status.Error(codes.Unimplemented, "method GenerateQrcode not implemented") +func (UnimplementedAnalysisServer) InternalCreateUser(context.Context, *InternalCreateUserReq) (*InternalCreateUserData, error) { + return nil, status.Error(codes.Unimplemented, "method InternalCreateUser not implemented") } -func (UnimplementedAnalysisAuthServer) mustEmbedUnimplementedAnalysisAuthServer() {} -func (UnimplementedAnalysisAuthServer) testEmbeddedByValue() {} +func (UnimplementedAnalysisServer) AgreementInfo(context.Context, *AgreementInfoReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method AgreementInfo not implemented") +} +func (UnimplementedAnalysisServer) Switch(context.Context, *SwitchReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Switch not implemented") +} +func (UnimplementedAnalysisServer) mustEmbedUnimplementedAnalysisServer() {} +func (UnimplementedAnalysisServer) testEmbeddedByValue() {} -// UnsafeAnalysisAuthServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to AnalysisAuthServer will +// UnsafeAnalysisServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AnalysisServer will // result in compilation errors. -type UnsafeAnalysisAuthServer interface { - mustEmbedUnimplementedAnalysisAuthServer() +type UnsafeAnalysisServer interface { + mustEmbedUnimplementedAnalysisServer() } -func RegisterAnalysisAuthServer(s grpc.ServiceRegistrar, srv AnalysisAuthServer) { - // If the following call panics, it indicates UnimplementedAnalysisAuthServer was +func RegisterAnalysisServer(s grpc.ServiceRegistrar, srv AnalysisServer) { + // If the following call panics, it indicates UnimplementedAnalysisServer was // embedded by pointer and is nil. This will cause panics if an // unimplemented method is ever invoked, so we test this at initialization // time to prevent it from happening at runtime later due to I/O. if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { t.testEmbeddedByValue() } - s.RegisterService(&AnalysisAuth_ServiceDesc, srv) + s.RegisterService(&Analysis_ServiceDesc, srv) } -func _AnalysisAuth_GenerateQrcode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GenerateQrcodeRequest) +func _Analysis_InternalCreateUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InternalCreateUserReq) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(AnalysisAuthServer).GenerateQrcode(ctx, in) + return srv.(AnalysisServer).InternalCreateUser(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: AnalysisAuth_GenerateQrcode_FullMethodName, + FullMethod: Analysis_InternalCreateUser_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AnalysisAuthServer).GenerateQrcode(ctx, req.(*GenerateQrcodeRequest)) + return srv.(AnalysisServer).InternalCreateUser(ctx, req.(*InternalCreateUserReq)) } return interceptor(ctx, in, info, handler) } -// AnalysisAuth_ServiceDesc is the grpc.ServiceDesc for AnalysisAuth service. +func _Analysis_AgreementInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AgreementInfoReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisServer).AgreementInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Analysis_AgreementInfo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisServer).AgreementInfo(ctx, req.(*AgreementInfoReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Analysis_Switch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SwitchReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisServer).Switch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Analysis_Switch_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisServer).Switch(ctx, req.(*SwitchReq)) + } + return interceptor(ctx, in, info, handler) +} + +// Analysis_ServiceDesc is the grpc.ServiceDesc for Analysis service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) -var AnalysisAuth_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "analysis.AnalysisAuth", - HandlerType: (*AnalysisAuthServer)(nil), +var Analysis_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "analysis.Analysis", + HandlerType: (*AnalysisServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "GenerateQrcode", - Handler: _AnalysisAuth_GenerateQrcode_Handler, + MethodName: "InternalCreateUser", + Handler: _Analysis_InternalCreateUser_Handler, + }, + { + MethodName: "AgreementInfo", + Handler: _Analysis_AgreementInfo_Handler, + }, + { + MethodName: "Switch", + Handler: _Analysis_Switch_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "analysis/analysis.proto", } + +const ( + AnalysisUser_UserRegister_FullMethodName = "/analysis.AnalysisUser/UserRegister" + AnalysisUser_FaceBind_FullMethodName = "/analysis.AnalysisUser/FaceBind" + AnalysisUser_UserImprove_FullMethodName = "/analysis.AnalysisUser/UserImprove" + AnalysisUser_UserDelete_FullMethodName = "/analysis.AnalysisUser/UserDelete" + AnalysisUser_UserAuth_FullMethodName = "/analysis.AnalysisUser/UserAuth" +) + +// AnalysisUserClient is the client API for AnalysisUser service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AnalysisUserClient interface { + UserRegister(ctx context.Context, in *UserRegisterReq, opts ...grpc.CallOption) (*Response, error) + FaceBind(ctx context.Context, in *FaceBindReq, opts ...grpc.CallOption) (*Response, error) + UserImprove(ctx context.Context, in *UserImproveReq, opts ...grpc.CallOption) (*Response, error) + UserDelete(ctx context.Context, in *UserDeleteReq, opts ...grpc.CallOption) (*Response, error) + // 用户扫码确认/拒绝授权 + UserAuth(ctx context.Context, in *UserAuthReq, opts ...grpc.CallOption) (*Response, error) +} + +type analysisUserClient struct { + cc grpc.ClientConnInterface +} + +func NewAnalysisUserClient(cc grpc.ClientConnInterface) AnalysisUserClient { + return &analysisUserClient{cc} +} + +func (c *analysisUserClient) UserRegister(ctx context.Context, in *UserRegisterReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisUser_UserRegister_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *analysisUserClient) FaceBind(ctx context.Context, in *FaceBindReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisUser_FaceBind_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *analysisUserClient) UserImprove(ctx context.Context, in *UserImproveReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisUser_UserImprove_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *analysisUserClient) UserDelete(ctx context.Context, in *UserDeleteReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisUser_UserDelete_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *analysisUserClient) UserAuth(ctx context.Context, in *UserAuthReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisUser_UserAuth_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AnalysisUserServer is the server API for AnalysisUser service. +// All implementations must embed UnimplementedAnalysisUserServer +// for forward compatibility. +type AnalysisUserServer interface { + UserRegister(context.Context, *UserRegisterReq) (*Response, error) + FaceBind(context.Context, *FaceBindReq) (*Response, error) + UserImprove(context.Context, *UserImproveReq) (*Response, error) + UserDelete(context.Context, *UserDeleteReq) (*Response, error) + // 用户扫码确认/拒绝授权 + UserAuth(context.Context, *UserAuthReq) (*Response, error) + mustEmbedUnimplementedAnalysisUserServer() +} + +// UnimplementedAnalysisUserServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAnalysisUserServer struct{} + +func (UnimplementedAnalysisUserServer) UserRegister(context.Context, *UserRegisterReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method UserRegister not implemented") +} +func (UnimplementedAnalysisUserServer) FaceBind(context.Context, *FaceBindReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method FaceBind not implemented") +} +func (UnimplementedAnalysisUserServer) UserImprove(context.Context, *UserImproveReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method UserImprove not implemented") +} +func (UnimplementedAnalysisUserServer) UserDelete(context.Context, *UserDeleteReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method UserDelete not implemented") +} +func (UnimplementedAnalysisUserServer) UserAuth(context.Context, *UserAuthReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method UserAuth not implemented") +} +func (UnimplementedAnalysisUserServer) mustEmbedUnimplementedAnalysisUserServer() {} +func (UnimplementedAnalysisUserServer) testEmbeddedByValue() {} + +// UnsafeAnalysisUserServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AnalysisUserServer will +// result in compilation errors. +type UnsafeAnalysisUserServer interface { + mustEmbedUnimplementedAnalysisUserServer() +} + +func RegisterAnalysisUserServer(s grpc.ServiceRegistrar, srv AnalysisUserServer) { + // If the following call panics, it indicates UnimplementedAnalysisUserServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AnalysisUser_ServiceDesc, srv) +} + +func _AnalysisUser_UserRegister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UserRegisterReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisUserServer).UserRegister(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisUser_UserRegister_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisUserServer).UserRegister(ctx, req.(*UserRegisterReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _AnalysisUser_FaceBind_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FaceBindReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisUserServer).FaceBind(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisUser_FaceBind_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisUserServer).FaceBind(ctx, req.(*FaceBindReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _AnalysisUser_UserImprove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UserImproveReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisUserServer).UserImprove(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisUser_UserImprove_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisUserServer).UserImprove(ctx, req.(*UserImproveReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _AnalysisUser_UserDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UserDeleteReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisUserServer).UserDelete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisUser_UserDelete_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisUserServer).UserDelete(ctx, req.(*UserDeleteReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _AnalysisUser_UserAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UserAuthReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisUserServer).UserAuth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisUser_UserAuth_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisUserServer).UserAuth(ctx, req.(*UserAuthReq)) + } + return interceptor(ctx, in, info, handler) +} + +// AnalysisUser_ServiceDesc is the grpc.ServiceDesc for AnalysisUser service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AnalysisUser_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "analysis.AnalysisUser", + HandlerType: (*AnalysisUserServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UserRegister", + Handler: _AnalysisUser_UserRegister_Handler, + }, + { + MethodName: "FaceBind", + Handler: _AnalysisUser_FaceBind_Handler, + }, + { + MethodName: "UserImprove", + Handler: _AnalysisUser_UserImprove_Handler, + }, + { + MethodName: "UserDelete", + Handler: _AnalysisUser_UserDelete_Handler, + }, + { + MethodName: "UserAuth", + Handler: _AnalysisUser_UserAuth_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "analysis/analysis.proto", +} + +const ( + AnalysisStore_StoreAuth_FullMethodName = "/analysis.AnalysisStore/StoreAuth" + AnalysisStore_StoreAuthQrcode_FullMethodName = "/analysis.AnalysisStore/StoreAuthQrcode" +) + +// AnalysisStoreClient is the client API for AnalysisStore service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AnalysisStoreClient interface { + // 门店账号密码授权用户 + StoreAuth(ctx context.Context, in *StoreAuthReq, opts ...grpc.CallOption) (*Response, error) + // 门店获取扫码授权二维码 + StoreAuthQrcode(ctx context.Context, in *StoreAuthQrcodeReq, opts ...grpc.CallOption) (*Response, error) +} + +type analysisStoreClient struct { + cc grpc.ClientConnInterface +} + +func NewAnalysisStoreClient(cc grpc.ClientConnInterface) AnalysisStoreClient { + return &analysisStoreClient{cc} +} + +func (c *analysisStoreClient) StoreAuth(ctx context.Context, in *StoreAuthReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisStore_StoreAuth_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *analysisStoreClient) StoreAuthQrcode(ctx context.Context, in *StoreAuthQrcodeReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, AnalysisStore_StoreAuthQrcode_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AnalysisStoreServer is the server API for AnalysisStore service. +// All implementations must embed UnimplementedAnalysisStoreServer +// for forward compatibility. +type AnalysisStoreServer interface { + // 门店账号密码授权用户 + StoreAuth(context.Context, *StoreAuthReq) (*Response, error) + // 门店获取扫码授权二维码 + StoreAuthQrcode(context.Context, *StoreAuthQrcodeReq) (*Response, error) + mustEmbedUnimplementedAnalysisStoreServer() +} + +// UnimplementedAnalysisStoreServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAnalysisStoreServer struct{} + +func (UnimplementedAnalysisStoreServer) StoreAuth(context.Context, *StoreAuthReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method StoreAuth not implemented") +} +func (UnimplementedAnalysisStoreServer) StoreAuthQrcode(context.Context, *StoreAuthQrcodeReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method StoreAuthQrcode not implemented") +} +func (UnimplementedAnalysisStoreServer) mustEmbedUnimplementedAnalysisStoreServer() {} +func (UnimplementedAnalysisStoreServer) testEmbeddedByValue() {} + +// UnsafeAnalysisStoreServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AnalysisStoreServer will +// result in compilation errors. +type UnsafeAnalysisStoreServer interface { + mustEmbedUnimplementedAnalysisStoreServer() +} + +func RegisterAnalysisStoreServer(s grpc.ServiceRegistrar, srv AnalysisStoreServer) { + // If the following call panics, it indicates UnimplementedAnalysisStoreServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AnalysisStore_ServiceDesc, srv) +} + +func _AnalysisStore_StoreAuth_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoreAuthReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisStoreServer).StoreAuth(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisStore_StoreAuth_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisStoreServer).StoreAuth(ctx, req.(*StoreAuthReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _AnalysisStore_StoreAuthQrcode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoreAuthQrcodeReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AnalysisStoreServer).StoreAuthQrcode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AnalysisStore_StoreAuthQrcode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AnalysisStoreServer).StoreAuthQrcode(ctx, req.(*StoreAuthQrcodeReq)) + } + return interceptor(ctx, in, info, handler) +} + +// AnalysisStore_ServiceDesc is the grpc.ServiceDesc for AnalysisStore service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AnalysisStore_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "analysis.AnalysisStore", + HandlerType: (*AnalysisStoreServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "StoreAuth", + Handler: _AnalysisStore_StoreAuth_Handler, + }, + { + MethodName: "StoreAuthQrcode", + Handler: _AnalysisStore_StoreAuthQrcode_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "analysis/analysis.proto", +} + +// AnalysisDeviceClient is the client API for AnalysisDevice service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AnalysisDeviceClient interface { +} + +type analysisDeviceClient struct { + cc grpc.ClientConnInterface +} + +func NewAnalysisDeviceClient(cc grpc.ClientConnInterface) AnalysisDeviceClient { + return &analysisDeviceClient{cc} +} + +// AnalysisDeviceServer is the server API for AnalysisDevice service. +// All implementations must embed UnimplementedAnalysisDeviceServer +// for forward compatibility. +type AnalysisDeviceServer interface { + mustEmbedUnimplementedAnalysisDeviceServer() +} + +// UnimplementedAnalysisDeviceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAnalysisDeviceServer struct{} + +func (UnimplementedAnalysisDeviceServer) mustEmbedUnimplementedAnalysisDeviceServer() {} +func (UnimplementedAnalysisDeviceServer) testEmbeddedByValue() {} + +// UnsafeAnalysisDeviceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AnalysisDeviceServer will +// result in compilation errors. +type UnsafeAnalysisDeviceServer interface { + mustEmbedUnimplementedAnalysisDeviceServer() +} + +func RegisterAnalysisDeviceServer(s grpc.ServiceRegistrar, srv AnalysisDeviceServer) { + // If the following call panics, it indicates UnimplementedAnalysisDeviceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&AnalysisDevice_ServiceDesc, srv) +} + +// AnalysisDevice_ServiceDesc is the grpc.ServiceDesc for AnalysisDevice service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AnalysisDevice_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "analysis.AnalysisDevice", + HandlerType: (*AnalysisDeviceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{}, + Metadata: "analysis/analysis.proto", +} diff --git a/rpc/scripts/gen-rpc.sh b/rpc/scripts/gen-rpc.sh index 4eb31be..9221ec8 100644 --- a/rpc/scripts/gen-rpc.sh +++ b/rpc/scripts/gen-rpc.sh @@ -24,6 +24,15 @@ function gen_one() { # 关键:只删除server.go,logic、dao、etc全部保留不动 rm -f "${ZRPC_OUT}/internal/server/${svc}server.go" + rm -f "${ZRPC_OUT}/internal/server/${svc}Server.go" + + MULTI_FLAG="" + if grep -Eq '^service[[:space:]]+' "${PROTO}"; then + svc_count=$(grep -Ec '^service[[:space:]]+' "${PROTO}" || true) + if [ "${svc_count}" -gt 1 ]; then + MULTI_FLAG="-m" + fi + fi goctl rpc protoc "${PROTO}" \ --proto_path="${THIRD_PARTY}" \ @@ -34,7 +43,8 @@ function gen_one() { --go_opt=M"${svc}/${svc}.proto"="./" \ --go-grpc_opt=M"${svc}/${svc}.proto"="./" \ --zrpc_out="${ZRPC_OUT}" \ - --style=goZero + --style=goZero \ + ${MULTI_FLAG} # rm -rf "${PB_OUT}/lone-services" diff --git a/rpc/user/pb/user.pb.go b/rpc/user/pb/user.pb.go index 7debed4..0a36259 100644 --- a/rpc/user/pb/user.pb.go +++ b/rpc/user/pb/user.pb.go @@ -397,7 +397,6 @@ func (x *InternalCreateReq) GetBizId() int64 { type InternalCreateData 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"` 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 @@ -441,13 +440,6 @@ func (x *InternalCreateData) GetUserId() int64 { return 0 } -func (x *InternalCreateData) GetCreated() bool { - if x != nil { - return x.Created - } - return false -} - func (x *InternalCreateData) GetMobile() string { if x != nil { return x.Mobile @@ -1386,6 +1378,126 @@ func (x *InternalGetUserInfoData) GetCredentialType() string { return "" } +type InternalVerifyPasswordReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + SubjectType string `protobuf:"bytes,3,opt,name=subject_type,json=subjectType,proto3" json:"subject_type,omitempty"` + ClientCode string `protobuf:"bytes,4,opt,name=client_code,json=clientCode,proto3" json:"client_code,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InternalVerifyPasswordReq) Reset() { + *x = InternalVerifyPasswordReq{} + mi := &file_user_user_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InternalVerifyPasswordReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InternalVerifyPasswordReq) ProtoMessage() {} + +func (x *InternalVerifyPasswordReq) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[21] + 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 InternalVerifyPasswordReq.ProtoReflect.Descriptor instead. +func (*InternalVerifyPasswordReq) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{21} +} + +func (x *InternalVerifyPasswordReq) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *InternalVerifyPasswordReq) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *InternalVerifyPasswordReq) GetSubjectType() string { + if x != nil { + return x.SubjectType + } + return "" +} + +func (x *InternalVerifyPasswordReq) GetClientCode() string { + if x != nil { + return x.ClientCode + } + return "" +} + +type InternalVerifyPasswordData struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + BizId int64 `protobuf:"varint,2,opt,name=biz_id,json=bizId,proto3" json:"biz_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *InternalVerifyPasswordData) Reset() { + *x = InternalVerifyPasswordData{} + mi := &file_user_user_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *InternalVerifyPasswordData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InternalVerifyPasswordData) ProtoMessage() {} + +func (x *InternalVerifyPasswordData) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[22] + 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 InternalVerifyPasswordData.ProtoReflect.Descriptor instead. +func (*InternalVerifyPasswordData) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{22} +} + +func (x *InternalVerifyPasswordData) GetUserId() int64 { + if x != nil { + return x.UserId + } + return 0 +} + +func (x *InternalVerifyPasswordData) GetBizId() int64 { + if x != nil { + return x.BizId + } + return 0 +} + type GetOpenidReq struct { state protoimpl.MessageState `protogen:"open.v1"` Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` @@ -1395,7 +1507,7 @@ type GetOpenidReq struct { func (x *GetOpenidReq) Reset() { *x = GetOpenidReq{} - mi := &file_user_user_proto_msgTypes[21] + mi := &file_user_user_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1407,7 +1519,7 @@ func (x *GetOpenidReq) String() string { func (*GetOpenidReq) ProtoMessage() {} func (x *GetOpenidReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[21] + mi := &file_user_user_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1420,7 +1532,7 @@ func (x *GetOpenidReq) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOpenidReq.ProtoReflect.Descriptor instead. func (*GetOpenidReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{21} + return file_user_user_proto_rawDescGZIP(), []int{23} } func (x *GetOpenidReq) GetCode() string { @@ -1438,7 +1550,7 @@ type InfoReq struct { func (x *InfoReq) Reset() { *x = InfoReq{} - mi := &file_user_user_proto_msgTypes[22] + mi := &file_user_user_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1450,7 +1562,7 @@ func (x *InfoReq) String() string { func (*InfoReq) ProtoMessage() {} func (x *InfoReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[22] + mi := &file_user_user_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1463,7 +1575,7 @@ func (x *InfoReq) ProtoReflect() protoreflect.Message { // Deprecated: Use InfoReq.ProtoReflect.Descriptor instead. func (*InfoReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{22} + return file_user_user_proto_rawDescGZIP(), []int{24} } type PasswordReq struct { @@ -1476,7 +1588,7 @@ type PasswordReq struct { func (x *PasswordReq) Reset() { *x = PasswordReq{} - mi := &file_user_user_proto_msgTypes[23] + mi := &file_user_user_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1488,7 +1600,7 @@ func (x *PasswordReq) String() string { func (*PasswordReq) ProtoMessage() {} func (x *PasswordReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[23] + mi := &file_user_user_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1501,7 +1613,7 @@ func (x *PasswordReq) ProtoReflect() protoreflect.Message { // Deprecated: Use PasswordReq.ProtoReflect.Descriptor instead. func (*PasswordReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{23} + return file_user_user_proto_rawDescGZIP(), []int{25} } func (x *PasswordReq) GetOldPassword() string { @@ -1529,7 +1641,7 @@ type ClientReq struct { func (x *ClientReq) Reset() { *x = ClientReq{} - mi := &file_user_user_proto_msgTypes[24] + mi := &file_user_user_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1541,7 +1653,7 @@ func (x *ClientReq) String() string { func (*ClientReq) ProtoMessage() {} func (x *ClientReq) ProtoReflect() protoreflect.Message { - mi := &file_user_user_proto_msgTypes[24] + mi := &file_user_user_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1554,7 +1666,7 @@ func (x *ClientReq) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientReq.ProtoReflect.Descriptor instead. func (*ClientReq) Descriptor() ([]byte, []int) { - return file_user_user_proto_rawDescGZIP(), []int{24} + return file_user_user_proto_rawDescGZIP(), []int{26} } func (x *ClientReq) GetName() string { @@ -1578,6 +1690,146 @@ func (x *ClientReq) GetSubjectType() uint32 { return 0 } +type GenerateQrcodeReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + ClientCode string `protobuf:"bytes,1,opt,name=client_code,json=clientCode,proto3" json:"client_code,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GenerateQrcodeReq) Reset() { + *x = GenerateQrcodeReq{} + mi := &file_user_user_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenerateQrcodeReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateQrcodeReq) ProtoMessage() {} + +func (x *GenerateQrcodeReq) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[27] + 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 GenerateQrcodeReq.ProtoReflect.Descriptor instead. +func (*GenerateQrcodeReq) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{27} +} + +func (x *GenerateQrcodeReq) GetClientCode() string { + if x != nil { + return x.ClientCode + } + return "" +} + +type QrcodeScanReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QrcodeScanReq) Reset() { + *x = QrcodeScanReq{} + mi := &file_user_user_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QrcodeScanReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QrcodeScanReq) ProtoMessage() {} + +func (x *QrcodeScanReq) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[28] + 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 QrcodeScanReq.ProtoReflect.Descriptor instead. +func (*QrcodeScanReq) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{28} +} + +func (x *QrcodeScanReq) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +type QrcodeLoginReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Type int32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *QrcodeLoginReq) Reset() { + *x = QrcodeLoginReq{} + mi := &file_user_user_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *QrcodeLoginReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QrcodeLoginReq) ProtoMessage() {} + +func (x *QrcodeLoginReq) ProtoReflect() protoreflect.Message { + mi := &file_user_user_proto_msgTypes[29] + 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 QrcodeLoginReq.ProtoReflect.Descriptor instead. +func (*QrcodeLoginReq) Descriptor() ([]byte, []int) { + return file_user_user_proto_rawDescGZIP(), []int{29} +} + +func (x *QrcodeLoginReq) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *QrcodeLoginReq) GetType() int32 { + if x != nil { + return x.Type + } + return 0 +} + var File_user_user_proto protoreflect.FileDescriptor const file_user_user_proto_rawDesc = "" + @@ -1617,10 +1869,9 @@ const file_user_user_proto_rawDesc = "" + "identifier\x12\x16\n" + "\x06secret\x18\t \x01(\tR\x06secret\x12\x15\n" + "\x06biz_id\x18\n" + - " \x01(\x03R\x05bizId\"s\n" + + " \x01(\x03R\x05bizId\"Y\n" + "\x12InternalCreateData\x12\x17\n" + - "\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x18\n" + - "\acreated\x18\x02 \x01(\bR\acreated\x12\x16\n" + + "\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x16\n" + "\x06mobile\x18\x03 \x01(\tR\x06mobile\x12\x12\n" + "\x04name\x18\x04 \x01(\tR\x04name\")\n" + "\x15InternalUsersByIdsReq\x12\x10\n" + @@ -1692,7 +1943,16 @@ const file_user_user_proto_rawDesc = "" + "\n" + "identifier\x18\b \x01(\tR\n" + "identifier\x12'\n" + - "\x0fcredential_type\x18\t \x01(\tR\x0ecredentialType\"\"\n" + + "\x0fcredential_type\x18\t \x01(\tR\x0ecredentialType\"\x97\x01\n" + + "\x19InternalVerifyPasswordReq\x12\x1a\n" + + "\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\x12!\n" + + "\fsubject_type\x18\x03 \x01(\tR\vsubjectType\x12\x1f\n" + + "\vclient_code\x18\x04 \x01(\tR\n" + + "clientCode\"L\n" + + "\x1aInternalVerifyPasswordData\x12\x17\n" + + "\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x15\n" + + "\x06biz_id\x18\x02 \x01(\x03R\x05bizId\"\"\n" + "\fGetOpenidReq\x12\x12\n" + "\x04code\x18\x01 \x01(\tR\x04code\"\t\n" + "\aInfoReq\"L\n" + @@ -1702,9 +1962,23 @@ const file_user_user_proto_rawDesc = "" + "\tClientReq\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + "\x04type\x18\x02 \x01(\tR\x04type\x12!\n" + - "\fsubject_type\x18\x03 \x01(\rR\vsubjectType2\xb1\t\n" + + "\fsubject_type\x18\x03 \x01(\rR\vsubjectType\"4\n" + + "\x11GenerateQrcodeReq\x12\x1f\n" + + "\vclient_code\x18\x01 \x01(\tR\n" + + "clientCode\".\n" + + "\rQrcodeScanReq\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\"C\n" + + "\x0eQrcodeLoginReq\x12\x1d\n" + + "\n" + + "session_id\x18\x01 \x01(\tR\tsessionId\x12\x12\n" + + "\x04type\x18\x02 \x01(\x05R\x04type2\xa5\f\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" + + "\x05Login\x12\x0e.user.LoginReq\x1a\x0e.user.Response\"\x18\x82\xd3\xe4\x93\x02\x12:\x01*\"\r/api/v3/login\x12b\n" + + "\x0eGenerateQrcode\x12\x17.user.GenerateQrcodeReq\x1a\x0e.user.Response\"'\x82\xd3\xe4\x93\x02!:\x01*\"\x1c/api/v3/user/qrcode/generate\x12V\n" + + "\n" + + "QrcodeScan\x12\x13.user.QrcodeScanReq\x1a\x0e.user.Response\"#\x82\xd3\xe4\x93\x02\x1d:\x01*\"\x18/api/v3/user/qrcode/scan\x12Y\n" + + "\vQrcodeLogin\x12\x14.user.QrcodeLoginReq\x1a\x0e.user.Response\"$\x82\xd3\xe4\x93\x02\x1e:\x01*\"\x19/api/v3/user/qrcode/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\x12O\n" + "\bPassword\x12\x11.user.PasswordReq\x1a\x0e.user.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\x1a\x15/api/v3/user/password\x12N\n" + "\tGetOpenid\x12\x12.user.GetOpenidReq\x1a\x0e.user.Response\"\x1d\x82\xd3\xe4\x93\x02\x17:\x01*\"\x12/api/v3/getuseroid\x12K\n" + @@ -1719,7 +1993,8 @@ const file_user_user_proto_rawDesc = "" + "\x12InternalUsersByIds\x12\x1b.user.InternalUsersByIdsReq\x1a\x1c.user.InternalUsersByIdsData\x12U\n" + "\x14InternalUpdateMobile\x12\x1d.user.InternalUpdateMobileReq\x1a\x1e.user.InternalUpdateMobileData\x12^\n" + "\x17InternalRevokeBizClient\x12 .user.InternalRevokeBizClientReq\x1a!.user.InternalRevokeBizClientData\x12R\n" + - "\x13InternalGetUserInfo\x12\x1c.user.InternalGetUserInfoReq\x1a\x1d.user.InternalGetUserInfoDataB\x18Z\x16lone-services/rpc/userb\x06proto3" + "\x13InternalGetUserInfo\x12\x1c.user.InternalGetUserInfoReq\x1a\x1d.user.InternalGetUserInfoData\x12[\n" + + "\x16InternalVerifyPassword\x12\x1f.user.InternalVerifyPasswordReq\x1a .user.InternalVerifyPasswordDataB\x18Z\x16lone-services/rpc/userb\x06proto3" var ( file_user_user_proto_rawDescOnce sync.Once @@ -1733,7 +2008,7 @@ func file_user_user_proto_rawDescGZIP() []byte { return file_user_user_proto_rawDescData } -var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 25) +var file_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_user_user_proto_goTypes = []any{ (*Response)(nil), // 0: user.Response (*LoginReq)(nil), // 1: user.LoginReq @@ -1756,45 +2031,58 @@ var file_user_user_proto_goTypes = []any{ (*InternalUpdateData)(nil), // 18: user.InternalUpdateData (*InternalGetUserInfoReq)(nil), // 19: user.InternalGetUserInfoReq (*InternalGetUserInfoData)(nil), // 20: user.InternalGetUserInfoData - (*GetOpenidReq)(nil), // 21: user.GetOpenidReq - (*InfoReq)(nil), // 22: user.InfoReq - (*PasswordReq)(nil), // 23: user.PasswordReq - (*ClientReq)(nil), // 24: user.ClientReq + (*InternalVerifyPasswordReq)(nil), // 21: user.InternalVerifyPasswordReq + (*InternalVerifyPasswordData)(nil), // 22: user.InternalVerifyPasswordData + (*GetOpenidReq)(nil), // 23: user.GetOpenidReq + (*InfoReq)(nil), // 24: user.InfoReq + (*PasswordReq)(nil), // 25: user.PasswordReq + (*ClientReq)(nil), // 26: user.ClientReq + (*GenerateQrcodeReq)(nil), // 27: user.GenerateQrcodeReq + (*QrcodeScanReq)(nil), // 28: user.QrcodeScanReq + (*QrcodeLoginReq)(nil), // 29: user.QrcodeLoginReq } var file_user_user_proto_depIdxs = []int32{ 7, // 0: user.InternalUsersByIdsData.items:type_name -> user.UserBriefItem 1, // 1: user.User.Login:input_type -> user.LoginReq - 22, // 2: user.User.Info:input_type -> user.InfoReq - 23, // 3: user.User.Password:input_type -> user.PasswordReq - 21, // 4: user.User.GetOpenid:input_type -> user.GetOpenidReq - 24, // 5: user.User.Client:input_type -> user.ClientReq - 2, // 6: user.User.UserItems:input_type -> user.UserItemsReq - 3, // 7: user.User.UserStatus:input_type -> user.UserStatusReq - 4, // 8: user.User.InternalCreate:input_type -> user.InternalCreateReq - 13, // 9: user.User.InternalCheckCreate:input_type -> user.InternalCheckCreateReq - 15, // 10: user.User.InternalCheckUpdate:input_type -> user.InternalCheckUpdateReq - 17, // 11: user.User.InternalUpdate:input_type -> user.InternalUpdateReq - 6, // 12: user.User.InternalUsersByIds:input_type -> user.InternalUsersByIdsReq - 9, // 13: user.User.InternalUpdateMobile:input_type -> user.InternalUpdateMobileReq - 11, // 14: user.User.InternalRevokeBizClient:input_type -> user.InternalRevokeBizClientReq - 19, // 15: user.User.InternalGetUserInfo:input_type -> user.InternalGetUserInfoReq - 0, // 16: user.User.Login:output_type -> user.Response - 0, // 17: user.User.Info:output_type -> user.Response - 0, // 18: user.User.Password:output_type -> user.Response - 0, // 19: user.User.GetOpenid:output_type -> user.Response - 0, // 20: user.User.Client:output_type -> user.Response - 0, // 21: user.User.UserItems:output_type -> user.Response - 0, // 22: user.User.UserStatus:output_type -> user.Response - 5, // 23: user.User.InternalCreate:output_type -> user.InternalCreateData - 14, // 24: user.User.InternalCheckCreate:output_type -> user.InternalCheckCreateData - 16, // 25: user.User.InternalCheckUpdate:output_type -> user.InternalCheckUpdateData - 18, // 26: user.User.InternalUpdate:output_type -> user.InternalUpdateData - 8, // 27: user.User.InternalUsersByIds:output_type -> user.InternalUsersByIdsData - 10, // 28: user.User.InternalUpdateMobile:output_type -> user.InternalUpdateMobileData - 12, // 29: user.User.InternalRevokeBizClient:output_type -> user.InternalRevokeBizClientData - 20, // 30: user.User.InternalGetUserInfo:output_type -> user.InternalGetUserInfoData - 16, // [16:31] is the sub-list for method output_type - 1, // [1:16] is the sub-list for method input_type + 27, // 2: user.User.GenerateQrcode:input_type -> user.GenerateQrcodeReq + 28, // 3: user.User.QrcodeScan:input_type -> user.QrcodeScanReq + 29, // 4: user.User.QrcodeLogin:input_type -> user.QrcodeLoginReq + 24, // 5: user.User.Info:input_type -> user.InfoReq + 25, // 6: user.User.Password:input_type -> user.PasswordReq + 23, // 7: user.User.GetOpenid:input_type -> user.GetOpenidReq + 26, // 8: user.User.Client:input_type -> user.ClientReq + 2, // 9: user.User.UserItems:input_type -> user.UserItemsReq + 3, // 10: user.User.UserStatus:input_type -> user.UserStatusReq + 4, // 11: user.User.InternalCreate:input_type -> user.InternalCreateReq + 13, // 12: user.User.InternalCheckCreate:input_type -> user.InternalCheckCreateReq + 15, // 13: user.User.InternalCheckUpdate:input_type -> user.InternalCheckUpdateReq + 17, // 14: user.User.InternalUpdate:input_type -> user.InternalUpdateReq + 6, // 15: user.User.InternalUsersByIds:input_type -> user.InternalUsersByIdsReq + 9, // 16: user.User.InternalUpdateMobile:input_type -> user.InternalUpdateMobileReq + 11, // 17: user.User.InternalRevokeBizClient:input_type -> user.InternalRevokeBizClientReq + 19, // 18: user.User.InternalGetUserInfo:input_type -> user.InternalGetUserInfoReq + 21, // 19: user.User.InternalVerifyPassword:input_type -> user.InternalVerifyPasswordReq + 0, // 20: user.User.Login:output_type -> user.Response + 0, // 21: user.User.GenerateQrcode:output_type -> user.Response + 0, // 22: user.User.QrcodeScan:output_type -> user.Response + 0, // 23: user.User.QrcodeLogin:output_type -> user.Response + 0, // 24: user.User.Info:output_type -> user.Response + 0, // 25: user.User.Password:output_type -> user.Response + 0, // 26: user.User.GetOpenid:output_type -> user.Response + 0, // 27: user.User.Client:output_type -> user.Response + 0, // 28: user.User.UserItems:output_type -> user.Response + 0, // 29: user.User.UserStatus:output_type -> user.Response + 5, // 30: user.User.InternalCreate:output_type -> user.InternalCreateData + 14, // 31: user.User.InternalCheckCreate:output_type -> user.InternalCheckCreateData + 16, // 32: user.User.InternalCheckUpdate:output_type -> user.InternalCheckUpdateData + 18, // 33: user.User.InternalUpdate:output_type -> user.InternalUpdateData + 8, // 34: user.User.InternalUsersByIds:output_type -> user.InternalUsersByIdsData + 10, // 35: user.User.InternalUpdateMobile:output_type -> user.InternalUpdateMobileData + 12, // 36: user.User.InternalRevokeBizClient:output_type -> user.InternalRevokeBizClientData + 20, // 37: user.User.InternalGetUserInfo:output_type -> user.InternalGetUserInfoData + 22, // 38: user.User.InternalVerifyPassword:output_type -> user.InternalVerifyPasswordData + 20, // [20:39] is the sub-list for method output_type + 1, // [1:20] 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 @@ -1811,7 +2099,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: 25, + NumMessages: 30, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/user/pb/user_grpc.pb.go b/rpc/user/pb/user_grpc.pb.go index e25bc02..5a5da2c 100644 --- a/rpc/user/pb/user_grpc.pb.go +++ b/rpc/user/pb/user_grpc.pb.go @@ -20,6 +20,9 @@ const _ = grpc.SupportPackageIsVersion9 const ( User_Login_FullMethodName = "/user.User/Login" + User_GenerateQrcode_FullMethodName = "/user.User/GenerateQrcode" + User_QrcodeScan_FullMethodName = "/user.User/QrcodeScan" + User_QrcodeLogin_FullMethodName = "/user.User/QrcodeLogin" User_Info_FullMethodName = "/user.User/Info" User_Password_FullMethodName = "/user.User/Password" User_GetOpenid_FullMethodName = "/user.User/GetOpenid" @@ -34,6 +37,7 @@ const ( User_InternalUpdateMobile_FullMethodName = "/user.User/InternalUpdateMobile" User_InternalRevokeBizClient_FullMethodName = "/user.User/InternalRevokeBizClient" User_InternalGetUserInfo_FullMethodName = "/user.User/InternalGetUserInfo" + User_InternalVerifyPassword_FullMethodName = "/user.User/InternalVerifyPassword" ) // UserClient is the client API for User service. @@ -41,6 +45,9 @@ 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 { Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) + GenerateQrcode(ctx context.Context, in *GenerateQrcodeReq, opts ...grpc.CallOption) (*Response, error) + QrcodeScan(ctx context.Context, in *QrcodeScanReq, opts ...grpc.CallOption) (*Response, error) + QrcodeLogin(ctx context.Context, in *QrcodeLoginReq, opts ...grpc.CallOption) (*Response, error) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) Password(ctx context.Context, in *PasswordReq, opts ...grpc.CallOption) (*Response, error) GetOpenid(ctx context.Context, in *GetOpenidReq, opts ...grpc.CallOption) (*Response, error) @@ -55,6 +62,7 @@ type UserClient interface { InternalUpdateMobile(ctx context.Context, in *InternalUpdateMobileReq, opts ...grpc.CallOption) (*InternalUpdateMobileData, error) InternalRevokeBizClient(ctx context.Context, in *InternalRevokeBizClientReq, opts ...grpc.CallOption) (*InternalRevokeBizClientData, error) InternalGetUserInfo(ctx context.Context, in *InternalGetUserInfoReq, opts ...grpc.CallOption) (*InternalGetUserInfoData, error) + InternalVerifyPassword(ctx context.Context, in *InternalVerifyPasswordReq, opts ...grpc.CallOption) (*InternalVerifyPasswordData, error) } type userClient struct { @@ -75,6 +83,36 @@ func (c *userClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallO return out, nil } +func (c *userClient) GenerateQrcode(ctx context.Context, in *GenerateQrcodeReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_GenerateQrcode_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userClient) QrcodeScan(ctx context.Context, in *QrcodeScanReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_QrcodeScan_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userClient) QrcodeLogin(ctx context.Context, in *QrcodeLoginReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_QrcodeLogin_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + 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) @@ -215,11 +253,24 @@ func (c *userClient) InternalGetUserInfo(ctx context.Context, in *InternalGetUse return out, nil } +func (c *userClient) InternalVerifyPassword(ctx context.Context, in *InternalVerifyPasswordReq, opts ...grpc.CallOption) (*InternalVerifyPasswordData, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(InternalVerifyPasswordData) + err := c.cc.Invoke(ctx, User_InternalVerifyPassword_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // UserServer is the server API for User service. // All implementations must embed UnimplementedUserServer // for forward compatibility. type UserServer interface { Login(context.Context, *LoginReq) (*Response, error) + GenerateQrcode(context.Context, *GenerateQrcodeReq) (*Response, error) + QrcodeScan(context.Context, *QrcodeScanReq) (*Response, error) + QrcodeLogin(context.Context, *QrcodeLoginReq) (*Response, error) Info(context.Context, *InfoReq) (*Response, error) Password(context.Context, *PasswordReq) (*Response, error) GetOpenid(context.Context, *GetOpenidReq) (*Response, error) @@ -234,6 +285,7 @@ type UserServer interface { InternalUpdateMobile(context.Context, *InternalUpdateMobileReq) (*InternalUpdateMobileData, error) InternalRevokeBizClient(context.Context, *InternalRevokeBizClientReq) (*InternalRevokeBizClientData, error) InternalGetUserInfo(context.Context, *InternalGetUserInfoReq) (*InternalGetUserInfoData, error) + InternalVerifyPassword(context.Context, *InternalVerifyPasswordReq) (*InternalVerifyPasswordData, error) mustEmbedUnimplementedUserServer() } @@ -247,6 +299,15 @@ type UnimplementedUserServer struct{} func (UnimplementedUserServer) Login(context.Context, *LoginReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Login not implemented") } +func (UnimplementedUserServer) GenerateQrcode(context.Context, *GenerateQrcodeReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method GenerateQrcode not implemented") +} +func (UnimplementedUserServer) QrcodeScan(context.Context, *QrcodeScanReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method QrcodeScan not implemented") +} +func (UnimplementedUserServer) QrcodeLogin(context.Context, *QrcodeLoginReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method QrcodeLogin not implemented") +} func (UnimplementedUserServer) Info(context.Context, *InfoReq) (*Response, error) { return nil, status.Error(codes.Unimplemented, "method Info not implemented") } @@ -289,6 +350,9 @@ func (UnimplementedUserServer) InternalRevokeBizClient(context.Context, *Interna func (UnimplementedUserServer) InternalGetUserInfo(context.Context, *InternalGetUserInfoReq) (*InternalGetUserInfoData, error) { return nil, status.Error(codes.Unimplemented, "method InternalGetUserInfo not implemented") } +func (UnimplementedUserServer) InternalVerifyPassword(context.Context, *InternalVerifyPasswordReq) (*InternalVerifyPasswordData, error) { + return nil, status.Error(codes.Unimplemented, "method InternalVerifyPassword not implemented") +} func (UnimplementedUserServer) mustEmbedUnimplementedUserServer() {} func (UnimplementedUserServer) testEmbeddedByValue() {} @@ -328,6 +392,60 @@ func _User_Login_Handler(srv interface{}, ctx context.Context, dec func(interfac return interceptor(ctx, in, info, handler) } +func _User_GenerateQrcode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateQrcodeReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).GenerateQrcode(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_GenerateQrcode_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).GenerateQrcode(ctx, req.(*GenerateQrcodeReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _User_QrcodeScan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QrcodeScanReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).QrcodeScan(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_QrcodeScan_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).QrcodeScan(ctx, req.(*QrcodeScanReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _User_QrcodeLogin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QrcodeLoginReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).QrcodeLogin(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_QrcodeLogin_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).QrcodeLogin(ctx, req.(*QrcodeLoginReq)) + } + 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 { @@ -580,6 +698,24 @@ func _User_InternalGetUserInfo_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _User_InternalVerifyPassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InternalVerifyPasswordReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).InternalVerifyPassword(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_InternalVerifyPassword_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).InternalVerifyPassword(ctx, req.(*InternalVerifyPasswordReq)) + } + return interceptor(ctx, in, info, handler) +} + // User_ServiceDesc is the grpc.ServiceDesc for User service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -591,6 +727,18 @@ var User_ServiceDesc = grpc.ServiceDesc{ MethodName: "Login", Handler: _User_Login_Handler, }, + { + MethodName: "GenerateQrcode", + Handler: _User_GenerateQrcode_Handler, + }, + { + MethodName: "QrcodeScan", + Handler: _User_QrcodeScan_Handler, + }, + { + MethodName: "QrcodeLogin", + Handler: _User_QrcodeLogin_Handler, + }, { MethodName: "Info", Handler: _User_Info_Handler, @@ -647,6 +795,10 @@ var User_ServiceDesc = grpc.ServiceDesc{ MethodName: "InternalGetUserInfo", Handler: _User_InternalGetUserInfo_Handler, }, + { + MethodName: "InternalVerifyPassword", + Handler: _User_InternalVerifyPassword_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "user/user.proto", diff --git a/rpc/user/user.pb b/rpc/user/user.pb index e9bdd62c1a90af42db3da91170e6f629072cd8ec..cb83558dfdc13032c4b9389d8d04b56237ed3bda 100644 GIT binary patch delta 665 zcmdnd$+)ziaf6d7(?gZbE~a;w7$YYuTIfxVv*p@cY%!b7aylcIq-S19YEfQdPFQMD zW?E%HVsUYKeo;zLYN3!67e{F^NG>;3f>D7{gEI)upPXkeGkL$g=;U9veAYtpT-?by znW=dt@yYoqsS+$;wOkM(XP}6Z50?~nYbG07$cc$^u_a|z#b>5SFadQk2eATqo+*=g z?XL6up1qO)FPcLDs4f!{ z*8>HY9;)bMMh6jh^`^^DCNn82$>=8*Wa^h0>w^^P7lJ*cpAPk(6{D6=7#A19UqZqV z1K}c*97G+J!A8j{NnkUo7#JELVg$>TIfkgaIq&Br6!i7rbsX;FlulFLAjfKEta!Q azGHud*=Qr@ analysis.Request - 1, // 1: analysis.Analysis.Ping:output_type -> analysis.Response - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_analysis_proto_init() } -func file_analysis_proto_init() { - if File_analysis_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_analysis_proto_rawDesc), len(file_analysis_proto_rawDesc)), - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_analysis_proto_goTypes, - DependencyIndexes: file_analysis_proto_depIdxs, - MessageInfos: file_analysis_proto_msgTypes, - }.Build() - File_analysis_proto = out.File - file_analysis_proto_goTypes = nil - file_analysis_proto_depIdxs = nil -} diff --git a/services/analysis/analysis/analysis_grpc.pb.go b/services/analysis/analysis/analysis_grpc.pb.go deleted file mode 100644 index 788c7f3..0000000 --- a/services/analysis/analysis/analysis_grpc.pb.go +++ /dev/null @@ -1,121 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.6.2 -// - protoc v3.19.4 -// source: analysis.proto - -package analysis - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - Analysis_Ping_FullMethodName = "/analysis.Analysis/Ping" -) - -// AnalysisClient is the client API for Analysis service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type AnalysisClient interface { - Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) -} - -type analysisClient struct { - cc grpc.ClientConnInterface -} - -func NewAnalysisClient(cc grpc.ClientConnInterface) AnalysisClient { - return &analysisClient{cc} -} - -func (c *analysisClient) Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(Response) - err := c.cc.Invoke(ctx, Analysis_Ping_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// AnalysisServer is the server API for Analysis service. -// All implementations must embed UnimplementedAnalysisServer -// for forward compatibility. -type AnalysisServer interface { - Ping(context.Context, *Request) (*Response, error) - mustEmbedUnimplementedAnalysisServer() -} - -// UnimplementedAnalysisServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedAnalysisServer struct{} - -func (UnimplementedAnalysisServer) Ping(context.Context, *Request) (*Response, error) { - return nil, status.Error(codes.Unimplemented, "method Ping not implemented") -} -func (UnimplementedAnalysisServer) mustEmbedUnimplementedAnalysisServer() {} -func (UnimplementedAnalysisServer) testEmbeddedByValue() {} - -// UnsafeAnalysisServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to AnalysisServer will -// result in compilation errors. -type UnsafeAnalysisServer interface { - mustEmbedUnimplementedAnalysisServer() -} - -func RegisterAnalysisServer(s grpc.ServiceRegistrar, srv AnalysisServer) { - // If the following call panics, it indicates UnimplementedAnalysisServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&Analysis_ServiceDesc, srv) -} - -func _Analysis_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AnalysisServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Analysis_Ping_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AnalysisServer).Ping(ctx, req.(*Request)) - } - return interceptor(ctx, in, info, handler) -} - -// Analysis_ServiceDesc is the grpc.ServiceDesc for Analysis service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Analysis_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "analysis.Analysis", - HandlerType: (*AnalysisServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Ping", - Handler: _Analysis_Ping_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "analysis.proto", -} diff --git a/services/analysis/analysisauth/analysisAuth.go b/services/analysis/analysisauth/analysisAuth.go deleted file mode 100644 index 255d0f7..0000000 --- a/services/analysis/analysisauth/analysisAuth.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by goctl. DO NOT EDIT. -// goctl 1.10.1 -// Source: analysis.proto - -package analysisauth - -import ( - "context" - - "lone-services/rpc/analysis/pb" - - "github.com/zeromicro/go-zero/zrpc" - "google.golang.org/grpc" -) - -type ( - GenerateQrcodeRequest = analysis.GenerateQrcodeRequest - Response = analysis.Response - - AnalysisAuth interface { - GenerateQrcode(ctx context.Context, in *GenerateQrcodeRequest, opts ...grpc.CallOption) (*Response, error) - } - - defaultAnalysisAuth struct { - cli zrpc.Client - } -) - -func NewAnalysisAuth(cli zrpc.Client) AnalysisAuth { - return &defaultAnalysisAuth{ - cli: cli, - } -} - -func (m *defaultAnalysisAuth) GenerateQrcode(ctx context.Context, in *GenerateQrcodeRequest, opts ...grpc.CallOption) (*Response, error) { - client := analysis.NewAnalysisAuthClient(m.cli.Conn()) - return client.GenerateQrcode(ctx, in, opts...) -} diff --git a/services/analysis/client/analysis/analysis.go b/services/analysis/client/analysis/analysis.go new file mode 100644 index 0000000..2cfb18e --- /dev/null +++ b/services/analysis/client/analysis/analysis.go @@ -0,0 +1,53 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package analysis + +import ( + "context" + + "lone-services/rpc/analysis/pb" + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + AgreementInfoReq = analysis.AgreementInfoReq + InternalCreateUserData = analysis.InternalCreateUserData + InternalCreateUserReq = analysis.InternalCreateUserReq + Response = analysis.Response + SwitchReq = analysis.SwitchReq + + Analysis interface { + InternalCreateUser(ctx context.Context, in *InternalCreateUserReq, opts ...grpc.CallOption) (*InternalCreateUserData, error) + AgreementInfo(ctx context.Context, in *AgreementInfoReq, opts ...grpc.CallOption) (*Response, error) + Switch(ctx context.Context, in *SwitchReq, opts ...grpc.CallOption) (*Response, error) + } + + defaultAnalysis struct { + cli zrpc.Client + } +) + +func NewAnalysis(cli zrpc.Client) Analysis { + return &defaultAnalysis{ + cli: cli, + } +} + +func (m *defaultAnalysis) InternalCreateUser(ctx context.Context, in *InternalCreateUserReq, opts ...grpc.CallOption) (*InternalCreateUserData, error) { + client := analysis.NewAnalysisClient(m.cli.Conn()) + return client.InternalCreateUser(ctx, in, opts...) +} + +func (m *defaultAnalysis) AgreementInfo(ctx context.Context, in *AgreementInfoReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisClient(m.cli.Conn()) + return client.AgreementInfo(ctx, in, opts...) +} + +func (m *defaultAnalysis) Switch(ctx context.Context, in *SwitchReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisClient(m.cli.Conn()) + return client.Switch(ctx, in, opts...) +} diff --git a/services/analysis/client/analysisdevice/analysisDevice.go b/services/analysis/client/analysisdevice/analysisDevice.go new file mode 100644 index 0000000..eb8a0bf --- /dev/null +++ b/services/analysis/client/analysisdevice/analysisDevice.go @@ -0,0 +1,24 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package analysisdevice + +import ( + "github.com/zeromicro/go-zero/zrpc" +) + +type ( + AnalysisDevice interface { + } + + defaultAnalysisDevice struct { + cli zrpc.Client + } +) + +func NewAnalysisDevice(cli zrpc.Client) AnalysisDevice { + return &defaultAnalysisDevice{ + cli: cli, + } +} diff --git a/services/analysis/client/analysisstore/analysisStore.go b/services/analysis/client/analysisstore/analysisStore.go new file mode 100644 index 0000000..df0f4ea --- /dev/null +++ b/services/analysis/client/analysisstore/analysisStore.go @@ -0,0 +1,49 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package analysisstore + +import ( + "context" + + "lone-services/rpc/analysis/pb" + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + Response = analysis.Response + StoreAuthQrcodeReq = analysis.StoreAuthQrcodeReq + StoreAuthReq = analysis.StoreAuthReq + + AnalysisStore interface { + // 门店账号密码授权用户 + StoreAuth(ctx context.Context, in *StoreAuthReq, opts ...grpc.CallOption) (*Response, error) + // 门店获取扫码授权二维码 + StoreAuthQrcode(ctx context.Context, in *StoreAuthQrcodeReq, opts ...grpc.CallOption) (*Response, error) + } + + defaultAnalysisStore struct { + cli zrpc.Client + } +) + +func NewAnalysisStore(cli zrpc.Client) AnalysisStore { + return &defaultAnalysisStore{ + cli: cli, + } +} + +// 门店账号密码授权用户 +func (m *defaultAnalysisStore) StoreAuth(ctx context.Context, in *StoreAuthReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisStoreClient(m.cli.Conn()) + return client.StoreAuth(ctx, in, opts...) +} + +// 门店获取扫码授权二维码 +func (m *defaultAnalysisStore) StoreAuthQrcode(ctx context.Context, in *StoreAuthQrcodeReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisStoreClient(m.cli.Conn()) + return client.StoreAuthQrcode(ctx, in, opts...) +} diff --git a/services/analysis/client/analysisuser/analysisUser.go b/services/analysis/client/analysisuser/analysisUser.go new file mode 100644 index 0000000..12991fb --- /dev/null +++ b/services/analysis/client/analysisuser/analysisUser.go @@ -0,0 +1,68 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package analysisuser + +import ( + "context" + + "lone-services/rpc/analysis/pb" + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + FaceBindReq = analysis.FaceBindReq + Response = analysis.Response + UserAuthReq = analysis.UserAuthReq + UserDeleteReq = analysis.UserDeleteReq + UserImproveReq = analysis.UserImproveReq + UserRegisterReq = analysis.UserRegisterReq + + AnalysisUser interface { + UserRegister(ctx context.Context, in *UserRegisterReq, opts ...grpc.CallOption) (*Response, error) + FaceBind(ctx context.Context, in *FaceBindReq, opts ...grpc.CallOption) (*Response, error) + UserImprove(ctx context.Context, in *UserImproveReq, opts ...grpc.CallOption) (*Response, error) + UserDelete(ctx context.Context, in *UserDeleteReq, opts ...grpc.CallOption) (*Response, error) + // 用户扫码确认/拒绝授权 + UserAuth(ctx context.Context, in *UserAuthReq, opts ...grpc.CallOption) (*Response, error) + } + + defaultAnalysisUser struct { + cli zrpc.Client + } +) + +func NewAnalysisUser(cli zrpc.Client) AnalysisUser { + return &defaultAnalysisUser{ + cli: cli, + } +} + +func (m *defaultAnalysisUser) UserRegister(ctx context.Context, in *UserRegisterReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisUserClient(m.cli.Conn()) + return client.UserRegister(ctx, in, opts...) +} + +func (m *defaultAnalysisUser) FaceBind(ctx context.Context, in *FaceBindReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisUserClient(m.cli.Conn()) + return client.FaceBind(ctx, in, opts...) +} + +func (m *defaultAnalysisUser) UserImprove(ctx context.Context, in *UserImproveReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisUserClient(m.cli.Conn()) + return client.UserImprove(ctx, in, opts...) +} + +func (m *defaultAnalysisUser) UserDelete(ctx context.Context, in *UserDeleteReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisUserClient(m.cli.Conn()) + return client.UserDelete(ctx, in, opts...) +} + +// 用户扫码确认/拒绝授权 +func (m *defaultAnalysisUser) UserAuth(ctx context.Context, in *UserAuthReq, opts ...grpc.CallOption) (*Response, error) { + client := analysis.NewAnalysisUserClient(m.cli.Conn()) + return client.UserAuth(ctx, in, opts...) +} diff --git a/services/analysis/internal/config/wechat.go b/services/analysis/internal/config/wechat.go index 1ca72d3..ba200e9 100644 --- a/services/analysis/internal/config/wechat.go +++ b/services/analysis/internal/config/wechat.go @@ -4,19 +4,20 @@ import ( "fmt" "lone-services/pkg/utils" + "lone-services/pkg/wechat/auth" "lone-services/pkg/wechat/qrcode" ) -type WechatQrcodeConfig struct { +type WechatConfig struct { AppID string Secret string Page string + AuthPage string Width int EnvVersion string } -func LoadWechatQrcodeConfig() (*WechatQrcodeConfig, error) { - +func LoadWechatConfig() (*WechatConfig, error) { appID := utils.GetConfigString("wechat.appid") secret := utils.GetConfigString("wechat.secret") if appID == utils.StringEmpty || secret == utils.StringEmpty { @@ -24,22 +25,36 @@ func LoadWechatQrcodeConfig() (*WechatQrcodeConfig, error) { } page := utils.GetConfigString("wechat.page") - + if page == utils.StringEmpty { + page = "pages/index/index" + } + authPage := utils.GetConfigString("wechat.auth_page") + if authPage == utils.StringEmpty { + authPage = "pagesB/authorize/scan" + } width := utils.GetConfigInt("wechat.width") + if width <= 0 { + width = 430 + } envVersion := utils.GetConfigString("wechat.env_version") if envVersion == utils.StringEmpty { envVersion = "trial" } - return &WechatQrcodeConfig{ + return &WechatConfig{ AppID: appID, Secret: secret, Page: page, + AuthPage: authPage, Width: width, EnvVersion: envVersion, }, nil } -func (c *WechatQrcodeConfig) NewQrcodeClient() *qrcode.Client { - return qrcode.NewClient(c.AppID, c.Secret) +func (c *WechatConfig) NewAuthClient() *auth.Client { + return auth.NewClient(c.AppID, c.Secret) +} + +func (c *WechatConfig) NewQrcodeClient() *qrcode.Client { + return qrcode.NewClient(c.NewAuthClient()) } diff --git a/services/analysis/internal/dao/agreement.go b/services/analysis/internal/dao/agreement.go new file mode 100644 index 0000000..28f9ecf --- /dev/null +++ b/services/analysis/internal/dao/agreement.go @@ -0,0 +1,20 @@ +package dao + +import "lone-services/pkg/utils" + +type Agreement struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + TypeId int32 `gorm:"column:type_id" json:"type_id"` + Title string `gorm:"column:title" json:"title"` + Content string `gorm:"column:content" json:"content"` + Status int8 `gorm:"column:status" json:"status"` + CreatedAt utils.CustomTime `gorm:"column:created_at" json:"created_at"` + UpdatedAt utils.CustomTime `gorm:"column:updated_at" json:"updated_at"` +} + +type AgreementInfo struct { + Id int64 `json:"id"` + TypeId int32 `json:"type_id"` + Content string `json:"content"` + CreatedAt utils.CustomTime `json:"created_at"` +} diff --git a/services/analysis/internal/dao/authorize.go b/services/analysis/internal/dao/authorize.go new file mode 100644 index 0000000..29c7cb1 --- /dev/null +++ b/services/analysis/internal/dao/authorize.go @@ -0,0 +1,14 @@ +package dao + +import "lone-services/pkg/utils" + +type UserStoreAuth struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + UserId int64 `gorm:"column:user_id" json:"user_id"` + ObjId int64 `gorm:"column:obj_id" json:"obj_id"` + StoreId int64 `gorm:"column:store_id" json:"store_id"` + ValidityTime utils.CustomTime `gorm:"column:validity_time" json:"validity_time"` + Status uint8 `gorm:"column:status" json:"status"` + IP string `gorm:"column:ip" json:"ip"` + CreateTime utils.CustomTime `gorm:"column:create_time" json:"create_time"` +} diff --git a/services/analysis/internal/dao/const.go b/services/analysis/internal/dao/const.go new file mode 100644 index 0000000..1cec92b --- /dev/null +++ b/services/analysis/internal/dao/const.go @@ -0,0 +1,12 @@ +package dao + +const ( + TypeSale uint8 = 1 + TypeStore uint8 = 2 + TypeUser uint8 = 3 + + ClientCodeUserSkin = "user_skin" + + StatusEnabled uint8 = 1 + StatusDisabled uint8 = 2 +) diff --git a/services/analysis/internal/dao/qrcode.go b/services/analysis/internal/dao/qrcode.go deleted file mode 100644 index 5aced9c..0000000 --- a/services/analysis/internal/dao/qrcode.go +++ /dev/null @@ -1,17 +0,0 @@ -package dao - -import "time" - -const ( - RedisKeyQRSession = "qr:session:" - - QrcodeSessionPending = 1 // 待扫码 - QrcodeSessionScanned = 2 // 已扫码未登录 - QrcodeSessionLogined = 3 // 已扫码已登录 - - QrcodeSessionTTL = 5 * time.Minute -) - -type QrcodeSessionStatus struct { - Status int `json:"status"` -} diff --git a/services/analysis/internal/dao/user.go b/services/analysis/internal/dao/user.go new file mode 100644 index 0000000..cd146a9 --- /dev/null +++ b/services/analysis/internal/dao/user.go @@ -0,0 +1,21 @@ +package dao + +import "lone-services/pkg/utils" + +type User struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + FacePath string `gorm:"column:face_path" json:"face_path"` + IsRegistered uint8 `gorm:"column:is_registered" json:"is_registered"` + IsFaceVerified uint8 `gorm:"column:is_face_verified" json:"is_face_verified"` + IsProfileCompleted uint8 `gorm:"column:is_profile_completed" json:"is_profile_completed"` + CreatedAt utils.CustomTime `gorm:"column:created_at" json:"created_at"` + UpdatedAt utils.CustomTime `gorm:"column:updated_at" json:"updated_at"` +} + +type UserCreate struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + FacePath string `gorm:"column:face_path" json:"face_path"` + IsRegistered uint8 `gorm:"column:is_registered" json:"is_registered"` + IsFaceVerified uint8 `gorm:"column:is_face_verified" json:"is_face_verified"` + IsProfileCompleted uint8 `gorm:"column:is_profile_completed" json:"is_profile_completed"` +} diff --git a/services/analysis/internal/logic/analysis/agreementInfoLogic.go b/services/analysis/internal/logic/analysis/agreementInfoLogic.go new file mode 100644 index 0000000..bf907d2 --- /dev/null +++ b/services/analysis/internal/logic/analysis/agreementInfoLogic.go @@ -0,0 +1,56 @@ +package analysislogic + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/dao" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/model" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type AgreementInfoLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewAgreementInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AgreementInfoLogic { + return &AgreementInfoLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *AgreementInfoLogic) AgreementInfo(in *analysis.AgreementInfoReq) (*analysis.Response, error) { + var req validator.AgreementInfoValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + var info dao.AgreementInfo + err := model.AgreementModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "type_id": strconv.Itoa(int(req.Type)), + "status": strconv.Itoa(utils.StatusOk), + }, + }, &info) + if err != nil { + l.Errorf("agreement info: %v", err) + return common.FailResponse(utils.Fail), nil + } + if info.Id < utils.NumberOne { + return common.FailResponse(utils.ErrorNotFund), nil + } + + return common.OkResponse(info), nil +} diff --git a/services/analysis/internal/logic/analysis/internalCreateUserLogic.go b/services/analysis/internal/logic/analysis/internalCreateUserLogic.go new file mode 100644 index 0000000..ac71542 --- /dev/null +++ b/services/analysis/internal/logic/analysis/internalCreateUserLogic.go @@ -0,0 +1,43 @@ +package analysislogic + +import ( + "context" + + "lone-services/pkg/utils" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/dao" + "lone-services/services/analysis/internal/model" + "lone-services/services/analysis/internal/svc" + + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type InternalCreateUserLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewInternalCreateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InternalCreateUserLogic { + return &InternalCreateUserLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *InternalCreateUserLogic) InternalCreateUser(in *analysis.InternalCreateUserReq) (*analysis.InternalCreateUserData, error) { + add := dao.UserCreate{ + IsRegistered: uint8(utils.StatusFail), + IsFaceVerified: uint8(utils.StatusFail), + IsProfileCompleted: uint8(utils.StatusFail), + } + err := model.UserModel{}.Init().Create(&add) + if err != nil { + l.Errorf("internal create user: %v", err) + return nil, status.Error(codes.Internal, utils.Fail.Msg) + } + return &analysis.InternalCreateUserData{Id: add.Id}, nil +} diff --git a/services/analysis/internal/logic/analysis/switchLogic.go b/services/analysis/internal/logic/analysis/switchLogic.go new file mode 100644 index 0000000..06bbc1c --- /dev/null +++ b/services/analysis/internal/logic/analysis/switchLogic.go @@ -0,0 +1,50 @@ +package analysislogic + +import ( + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type SwitchLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewSwitchLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SwitchLogic { + return &SwitchLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *SwitchLogic) Switch(in *analysis.SwitchReq) (*analysis.Response, error) { + var req validator.SwitchValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + t := req.Type + if t < utils.NumberOne { + t = utils.NumberOne + } + + var result int + switch t { + case utils.NumberOne: + result = utils.GetConfigInt("switch.wechat") + default: + result = utils.NumberOne + } + + return common.OkResponse(result), nil +} diff --git a/services/analysis/internal/logic/analysisdevice/doc.go b/services/analysis/internal/logic/analysisdevice/doc.go new file mode 100644 index 0000000..71202ca --- /dev/null +++ b/services/analysis/internal/logic/analysisdevice/doc.go @@ -0,0 +1 @@ +package analysisdevicelogic diff --git a/services/analysis/internal/logic/analysisstore/storeAuthLogic.go b/services/analysis/internal/logic/analysisstore/storeAuthLogic.go new file mode 100644 index 0000000..3a69739 --- /dev/null +++ b/services/analysis/internal/logic/analysisstore/storeAuthLogic.go @@ -0,0 +1,87 @@ +package analysisstorelogic + +import ( + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + userpb "lone-services/rpc/user/pb" + "lone-services/services/analysis/internal/dao" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type StoreAuthLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewStoreAuthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StoreAuthLogic { + return &StoreAuthLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *StoreAuthLogic) StoreAuth(in *analysis.StoreAuthReq) (*analysis.Response, error) { + var req validator.StoreAuthValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + storeId, _, fail := common.RequireStoreId(l.ctx) + if fail != nil { + return fail, nil + } + + if l.svcCtx.UserSvcName == utils.StringEmpty { + return common.FailResponse(utils.Fail), nil + } + cli, err := svc.GetRpcClient(l.svcCtx.UserSvcName) + if err != nil { + l.Errorf("store auth get user rpc: %v", err) + return common.FailResponse(utils.Fail), nil + } + + verified, err := userpb.NewUserClient(cli.Conn()).InternalVerifyPassword(l.ctx, &userpb.InternalVerifyPasswordReq{ + Username: req.Username, + Password: req.Password, + SubjectType: "user", + ClientCode: dao.ClientCodeUserSkin, + }) + if err != nil { + l.Errorf("store auth verify password: %v", err) + if st, ok := status.FromError(err); ok { + switch st.Code() { + case codes.NotFound: + return common.FailResponse(utils.ErrorNotFund), nil + case codes.InvalidArgument: + return common.FailResponse(utils.ErrorPwdError), nil + case codes.FailedPrecondition: + return common.OutResponse(utils.Fail, st.Message()), nil + } + } + return common.FailResponse(utils.Fail), nil + } + if verified == nil || verified.UserId < utils.NumberOne { + return common.FailResponse(utils.ErrorNotFund), nil + } + if verified.BizId < utils.NumberOne { + return common.OutResponse(utils.ErrorParams, "用户未开通"), nil + } + + if err := common.BindStoreAuth(verified.UserId, verified.BizId, storeId, req.ValidityTime); err != nil { + l.Errorf("store auth bind: %v", err) + return common.FailResponse(utils.Fail), nil + } + + return common.OkResponse(map[string]int64{"user_id": verified.UserId}), nil +} diff --git a/services/analysis/internal/logic/analysisstore/storeAuthQrcodeLogic.go b/services/analysis/internal/logic/analysisstore/storeAuthQrcodeLogic.go new file mode 100644 index 0000000..55f2bca --- /dev/null +++ b/services/analysis/internal/logic/analysisstore/storeAuthQrcodeLogic.go @@ -0,0 +1,126 @@ +package analysisstorelogic + +import ( + "context" + "fmt" + "strconv" + + "lone-services/pkg/redis" + "lone-services/pkg/utils" + "lone-services/pkg/wechat/qrcode" + pkgws "lone-services/pkg/ws" + analysis "lone-services/rpc/analysis/pb" + chore "lone-services/rpc/chore/pb" + analysisconfig "lone-services/services/analysis/internal/config" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/svc" + + "github.com/google/uuid" + jsoniter "github.com/json-iterator/go" + "github.com/zeromicro/go-zero/core/logx" +) + +type StoreAuthQrcodeLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewStoreAuthQrcodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StoreAuthQrcodeLogic { + return &StoreAuthQrcodeLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *StoreAuthQrcodeLogic) StoreAuthQrcode(in *analysis.StoreAuthQrcodeReq) (*analysis.Response, error) { + storeId, _, fail := common.RequireStoreId(l.ctx) + if fail != nil { + return fail, nil + } + + wxCfg, err := analysisconfig.LoadWechatConfig() + if err != nil { + l.Errorf("store auth qrcode wechat config: %v", err) + return common.OutResponse(utils.Fail, "微信配置缺失"), nil + } + + sessionID, err := l.createSession() + if err != nil { + l.Errorf("store auth qrcode session: %v", err) + return common.OutResponse(utils.Fail, "create qrcode session failed"), nil + } + + storeKey := pkgws.RedisKeyQRSession + strconv.FormatInt(storeId, utils.NumberTen) + if err := redis.Client.Set(l.ctx, storeKey, sessionID, pkgws.SessionTTL).Err(); err != nil { + l.Errorf("store auth qrcode store mapping: %v", err) + return common.FailResponse(utils.Fail), nil + } + + img, err := wxCfg.NewQrcodeClient().CreateWxaCode(l.ctx, &qrcode.WxaCodeRequest{ + Path: qrcode.BuildPath(wxCfg.AuthPage, map[string]string{ + "store_id": strconv.FormatInt(storeId, utils.NumberTen), + "session_id": sessionID, + }), + Width: wxCfg.Width, + EnvVersion: wxCfg.EnvVersion, + AutoColor: false, + LineColor: &qrcode.LineColor{R: 255, G: 255, B: 255}, + IsHyaline: true, + }) + if err != nil { + l.Errorf("store auth qrcode wechat: %v", err) + return common.OutResponse(utils.Fail, err.Error()), nil + } + + qrURL, err := l.uploadQrcode(img) + if err != nil { + l.Errorf("store auth qrcode upload: %v", err) + return common.OutResponse(utils.Fail, "upload qrcode failed"), nil + } + + return common.OkResponse(map[string]string{ + "qrcode": qrURL, + "session_id": sessionID, + }), nil +} + +func (l *StoreAuthQrcodeLogic) createSession() (string, error) { + if redis.Client == nil { + return "", fmt.Errorf("redis not initialized") + } + sessionID := uuid.New().String() + payload, err := jsoniter.MarshalToString(pkgws.Session{ + Status: pkgws.StatusPending, + }) + if err != nil { + return "", err + } + key := pkgws.RedisKeyQRSession + sessionID + if err := redis.Client.Set(l.ctx, key, payload, pkgws.SessionTTL).Err(); err != nil { + return "", err + } + return sessionID, nil +} + +func (l *StoreAuthQrcodeLogic) uploadQrcode(content []byte) (string, error) { + if l.svcCtx.ChoreSvcName == utils.StringEmpty { + return "", fmt.Errorf("chore service name empty") + } + cli, err := svc.GetRpcClient(l.svcCtx.ChoreSvcName) + if err != nil { + return "", err + } + res, err := chore.NewChoreClient(cli.Conn()).InternalUpload(l.ctx, &chore.InternalUploadReq{ + Filename: uuid.New().String() + ".png", + Content: content, + }) + if err != nil { + return "", err + } + if res == nil || res.Url == utils.StringEmpty { + return "", fmt.Errorf("chore upload empty url") + } + return res.Url, nil +} diff --git a/services/analysis/internal/logic/analysisuser/faceBindLogic.go b/services/analysis/internal/logic/analysisuser/faceBindLogic.go new file mode 100644 index 0000000..dda80b0 --- /dev/null +++ b/services/analysis/internal/logic/analysisuser/faceBindLogic.go @@ -0,0 +1,65 @@ +package analysisuserlogic + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/model" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type FaceBindLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewFaceBindLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FaceBindLogic { + return &FaceBindLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *FaceBindLogic) FaceBind(in *analysis.FaceBindReq) (*analysis.Response, error) { + var req validator.FaceBindValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + bizId, _, fail := common.RequireBizUserId(l.ctx) + if fail != nil { + return fail, nil + } + + row, err := common.LoadAnalysisUser(bizId) + if err != nil { + l.Errorf("face bind load user: %v", err) + return common.FailResponse(utils.Fail), nil + } + if row == nil { + return common.FailResponse(utils.ErrorNotFund), nil + } + + _, err = model.UserModel{}.Init().Edit(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(bizId, utils.NumberTen)}, + }, map[string]interface{}{ + "face_path": req.FacePath, + "is_face_verified": uint8(utils.StatusOk), + }) + if err != nil { + l.Errorf("face bind update: %v", err) + return common.FailResponse(utils.Fail), nil + } + + return common.OkResponse(nil), nil +} diff --git a/services/analysis/internal/logic/analysisuser/userAuthLogic.go b/services/analysis/internal/logic/analysisuser/userAuthLogic.go new file mode 100644 index 0000000..aebf40a --- /dev/null +++ b/services/analysis/internal/logic/analysisuser/userAuthLogic.go @@ -0,0 +1,77 @@ +package analysisuserlogic + +import ( + "context" + "strconv" + + "lone-services/pkg/redis" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + pkgws "lone-services/pkg/ws" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UserAuthLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUserAuthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserAuthLogic { + return &UserAuthLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UserAuthLogic) UserAuth(in *analysis.UserAuthReq) (*analysis.Response, error) { + var req validator.UserAuthValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + loginUser, fail := common.RequireUserLogin(l.ctx) + if fail != nil { + return fail, nil + } + + storeKey := pkgws.RedisKeyQRSession + strconv.FormatInt(req.StoreId, utils.NumberTen) + sessionID, err := redis.Client.Get(l.ctx, storeKey).Result() + if err != nil && err != redis.Nil { + l.Errorf("user auth redis get session: %v", err) + return common.FailResponse(utils.Fail), nil + } + if err == redis.Nil { + sessionID = utils.StringEmpty + } + + if req.Type == int32(utils.StoreAuthBind) { + bizId := loginUser.BizId + if bizId < utils.NumberOne { + return common.OutResponse(utils.ErrorParams, "业务用户不存在"), nil + } + if err := common.BindStoreAuth(loginUser.ID, bizId, req.StoreId, req.ValidityTime); err != nil { + l.Errorf("user auth bind: %v", err) + return common.FailResponse(utils.Fail), nil + } + } + + if sessionID == utils.StringEmpty { + return common.OkResponse(nil), nil + } + + if pubErr := pkgws.Publish(l.ctx, sessionID, pkgws.Success(map[string]interface{}{ + "ws_type": req.Type, + })); pubErr != nil { + l.Errorf("user auth publish: %v", pubErr) + } + _ = redis.Client.Del(l.ctx, storeKey).Err() + + return common.OkResponse(nil), nil +} diff --git a/services/analysis/internal/logic/analysisuser/userDeleteLogic.go b/services/analysis/internal/logic/analysisuser/userDeleteLogic.go new file mode 100644 index 0000000..43e408a --- /dev/null +++ b/services/analysis/internal/logic/analysisuser/userDeleteLogic.go @@ -0,0 +1,48 @@ +package analysisuserlogic + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/model" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UserDeleteLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUserDeleteLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserDeleteLogic { + return &UserDeleteLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UserDeleteLogic) UserDelete(in *analysis.UserDeleteReq) (*analysis.Response, error) { + var req validator.UserDeleteValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + _, err := model.UserModel{}.Init().Del(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(req.Id, utils.NumberTen)}, + }, map[string]string{}) + if err != nil { + l.Errorf("user delete: %v", err) + return common.FailResponse(utils.Fail), nil + } + + return common.OkResponse(nil), nil +} diff --git a/services/analysis/internal/logic/analysisuser/userImproveLogic.go b/services/analysis/internal/logic/analysisuser/userImproveLogic.go new file mode 100644 index 0000000..f8107e0 --- /dev/null +++ b/services/analysis/internal/logic/analysisuser/userImproveLogic.go @@ -0,0 +1,147 @@ +package analysisuserlogic + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + userpb "lone-services/rpc/user/pb" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/model" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UserImproveLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUserImproveLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserImproveLogic { + return &UserImproveLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UserImproveLogic) UserImprove(in *analysis.UserImproveReq) (*analysis.Response, error) { + var req validator.UserImproveValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + bizId, loginUser, fail := common.RequireBizUserId(l.ctx) + if fail != nil { + return fail, nil + } + + row, err := common.LoadAnalysisUser(bizId) + if err != nil { + l.Errorf("improve load user: %v", err) + return common.FailResponse(utils.Fail), nil + } + if row == nil { + return common.FailResponse(utils.ErrorNotFund), nil + } + + if req.Nickname != utils.StringEmpty || req.Avatar != utils.StringEmpty || + req.Birthday != utils.StringEmpty || req.Gender > utils.NumberZero || + req.Mobile != utils.StringEmpty || req.Password != utils.StringEmpty { + if st := l.updatePlatformUser(loginUser, bizId, req); st.Code != utils.Ok.Code { + if st.Code == utils.ErrorParams.Code { + return common.OutResponse(utils.ErrorParams, "请先完成手机号注册"), nil + } + return common.FailResponse(st), nil + } + } + + _, err = model.UserModel{}.Init().Edit(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(bizId, utils.NumberTen)}, + }, map[string]interface{}{ + "is_profile_completed": uint8(utils.StatusOk), + }) + if err != nil { + l.Errorf("improve update flag: %v", err) + return common.FailResponse(utils.Fail), nil + } + + return common.OkResponse(nil), nil +} + +func (l *UserImproveLogic) updatePlatformUser(loginUser utils.UserInfo, bizId int64, req validator.UserImproveValidator) utils.Status { + if l.svcCtx.UserSvcName == utils.StringEmpty { + return utils.Fail + } + cli, err := svc.GetRpcClient(l.svcCtx.UserSvcName) + if err != nil { + l.Errorf("improve get user rpc: %v", err) + return utils.Fail + } + + userClient := userpb.NewUserClient(cli.Conn()) + info, err := userClient.InternalGetUserInfo(l.ctx, &userpb.InternalGetUserInfoReq{ + UserId: loginUser.ID, + SubjectType: "user", + }) + if err != nil { + l.Errorf("improve get user info: %v", err) + return utils.Fail + } + + mobile := req.Mobile + if mobile == utils.StringEmpty && info.Mobile != utils.StringEmpty { + plain, decErr := utils.DecryptPhone(info.Mobile) + if decErr == nil { + mobile = plain + } + } + if mobile == utils.StringEmpty || len(mobile) != utils.NumberEleven { + return utils.ErrorParams + } + + name := req.Nickname + if name == utils.StringEmpty { + name = info.Name + } + avatar := req.Avatar + if avatar == utils.StringEmpty { + avatar = info.Avatar + } + gender := uint32(req.Gender) + if gender == utils.NumberZero { + gender = info.Gender + } + birthday := req.Birthday + if birthday == utils.StringEmpty { + birthday = info.Birthday + } + + updateReq := &userpb.InternalUpdateReq{ + BizId: bizId, + SubjectType: "user", + Mobile: mobile, + Name: name, + Avatar: avatar, + Gender: gender, + Birthday: birthday, + ClientCode: []string{loginUser.ClientCode}, + } + if req.Password != utils.StringEmpty { + updateReq.CredentialType = []string{"password"} + updateReq.Secret = req.Password + updateReq.Identifier = mobile + } + + if _, err = userClient.InternalUpdate(l.ctx, updateReq); err != nil { + l.Errorf("improve internal update: %v", err) + return utils.Fail + } + return utils.Ok +} diff --git a/services/analysis/internal/logic/analysisuser/userRegisterLogic.go b/services/analysis/internal/logic/analysisuser/userRegisterLogic.go new file mode 100644 index 0000000..f6c361a --- /dev/null +++ b/services/analysis/internal/logic/analysisuser/userRegisterLogic.go @@ -0,0 +1,107 @@ +package analysisuserlogic + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + analysis "lone-services/rpc/analysis/pb" + userpb "lone-services/rpc/user/pb" + analysisconfig "lone-services/services/analysis/internal/config" + "lone-services/services/analysis/internal/logic/common" + "lone-services/services/analysis/internal/model" + "lone-services/services/analysis/internal/svc" + "lone-services/services/analysis/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type UserRegisterLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewUserRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserRegisterLogic { + return &UserRegisterLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *UserRegisterLogic) UserRegister(in *analysis.UserRegisterReq) (*analysis.Response, error) { + var req validator.UserRegisterValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return common.OutResponse(utils.ErrorParams, msg), nil + } + + bizId, loginUser, fail := common.RequireBizUserId(l.ctx) + if fail != nil { + return fail, nil + } + + row, err := common.LoadAnalysisUser(bizId) + if err != nil { + l.Errorf("register load user: %v", err) + return common.FailResponse(utils.Fail), nil + } + if row == nil { + return common.FailResponse(utils.ErrorNotFund), nil + } + + wxCfg, cfgErr := analysisconfig.LoadWechatConfig() + if cfgErr != nil { + l.Errorf("register wechat config: %v", cfgErr) + return common.OutResponse(utils.Fail, "微信配置缺失"), nil + } + + token, tokenErr := wxCfg.NewAuthClient().AccessToken(l.ctx) + if tokenErr != nil { + l.Errorf("register access token: %v", tokenErr) + return common.FailResponse(utils.Fail), nil + } + phone, phoneErr := wxCfg.NewAuthClient().GetPhoneNumber(token.AccessToken, req.Code) + if phoneErr != nil { + l.Errorf("register get phone: %v", phoneErr) + return common.FailResponse(utils.Fail), nil + } + + mobile := phone.PhoneNumber + if mobile == utils.StringEmpty { + mobile = phone.PurePhoneNumber + } + if mobile == utils.StringEmpty { + return common.FailResponse(utils.Fail), nil + } + + if l.svcCtx.UserSvcName == utils.StringEmpty { + return common.FailResponse(utils.Fail), nil + } + cli, err := svc.GetRpcClient(l.svcCtx.UserSvcName) + if err != nil { + l.Errorf("register get user rpc: %v", err) + return common.FailResponse(utils.Fail), nil + } + if _, err = userpb.NewUserClient(cli.Conn()).InternalUpdateMobile(l.ctx, &userpb.InternalUpdateMobileReq{ + UserId: loginUser.ID, + Mobile: mobile, + }); err != nil { + l.Errorf("register update mobile: %v", err) + return common.FailResponse(utils.Fail), nil + } + + _, err = model.UserModel{}.Init().Edit(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(bizId, utils.NumberTen)}, + }, map[string]interface{}{ + "is_registered": uint8(utils.StatusOk), + }) + if err != nil { + l.Errorf("register update flag: %v", err) + return common.FailResponse(utils.Fail), nil + } + + return common.OkResponse(nil), nil +} diff --git a/services/analysis/internal/logic/common/authorize.go b/services/analysis/internal/logic/common/authorize.go new file mode 100644 index 0000000..e160a4b --- /dev/null +++ b/services/analysis/internal/logic/common/authorize.go @@ -0,0 +1,59 @@ +package common + +import ( + "strconv" + "time" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + "lone-services/services/analysis/internal/dao" + "lone-services/services/analysis/internal/model" +) + +func parseValidityTime(date string) (utils.CustomTime, error) { + timeStr := date + if len(date) == len("2006-01-02 15:04") { + timeStr = date + ":00" + } + t, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local) + if err != nil { + return utils.CustomTime{}, err + } + return utils.CustomTime{Time: t}, nil +} + +func BindStoreAuth(userId, objId, storeId int64, validityTime string) error { + vt, err := parseValidityTime(validityTime) + if err != nil { + return err + } + + authModel := model.UserStoreAuthModel{}.Init() + w := modelbase.Params{ + Eq: map[string]string{ + "user_id": strconv.FormatInt(userId, utils.NumberTen), + "store_id": strconv.FormatInt(storeId, utils.NumberTen), + "status": strconv.Itoa(int(dao.StatusEnabled)), + }, + } + var oldList []dao.UserStoreAuth + if err := authModel.Items(w, &oldList); err != nil { + return err + } + if len(oldList) > 0 { + if _, err := authModel.Edit(w, map[string]interface{}{ + "status": dao.StatusDisabled, + }); err != nil { + return err + } + } + + return authModel.Create(&dao.UserStoreAuth{ + UserId: userId, + ObjId: objId, + StoreId: storeId, + ValidityTime: vt, + Status: dao.StatusEnabled, + CreateTime: utils.Now(), + }) +} diff --git a/services/analysis/internal/logic/common/helper.go b/services/analysis/internal/logic/common/helper.go new file mode 100644 index 0000000..1298d4b --- /dev/null +++ b/services/analysis/internal/logic/common/helper.go @@ -0,0 +1,61 @@ +package common + +import ( + "context" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/dao" + "lone-services/services/analysis/internal/model" +) + +func RequireBizUserId(ctx context.Context) (int64, utils.UserInfo, *analysis.Response) { + user := utils.GetUserFromCtx(ctx) + if user.BizId < utils.NumberOne { + return utils.NumberZero, user, OutResponse(utils.ErrorParams, "业务用户不存在") + } + return user.BizId, user, nil +} + +func RequireStoreId(ctx context.Context) (int64, utils.UserInfo, *analysis.Response) { + user := utils.GetUserFromCtx(ctx) + if !user.Valid { + return utils.NumberZero, user, FailResponse(utils.ErrorNoLogin) + } + if user.Type != dao.TypeStore { + return utils.NumberZero, user, FailResponse(utils.ErrorAuthority) + } + + storeId := user.BizId + if storeId < utils.NumberOne { + return utils.NumberZero, user, OutResponse(utils.ErrorParams, "门店信息不存在") + } + return storeId, user, nil +} + +func RequireUserLogin(ctx context.Context) (utils.UserInfo, *analysis.Response) { + user := utils.GetUserFromCtx(ctx) + if !user.Valid { + return user, FailResponse(utils.ErrorNoLogin) + } + if user.Type != dao.TypeUser { + return user, FailResponse(utils.ErrorAuthority) + } + return user, nil +} + +func LoadAnalysisUser(id int64) (*dao.User, error) { + var row dao.User + err := model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(id, utils.NumberTen)}, + }, &row) + if err != nil { + return nil, err + } + if row.Id < utils.NumberOne { + return nil, nil + } + return &row, nil +} diff --git a/services/analysis/internal/logic/response.go b/services/analysis/internal/logic/common/response.go similarity index 68% rename from services/analysis/internal/logic/response.go rename to services/analysis/internal/logic/common/response.go index 8fa2c0e..d9d5d18 100644 --- a/services/analysis/internal/logic/response.go +++ b/services/analysis/internal/logic/common/response.go @@ -1,4 +1,4 @@ -package logic +package common import ( "lone-services/pkg/utils" @@ -7,7 +7,7 @@ import ( jsoniter "github.com/json-iterator/go" ) -func okResponse(data any) *analysis.Response { +func OkResponse(data any) *analysis.Response { buf, _ := jsoniter.Marshal(data) return &analysis.Response{ Code: utils.Ok.Code, @@ -16,14 +16,14 @@ func okResponse(data any) *analysis.Response { } } -func failResponse(status utils.Status) *analysis.Response { +func FailResponse(status utils.Status) *analysis.Response { return &analysis.Response{ Code: status.Code, Msg: status.Msg, } } -func outResponse(status utils.Status, msg string) *analysis.Response { +func OutResponse(status utils.Status, msg string) *analysis.Response { return &analysis.Response{ Code: status.Code, Msg: msg, diff --git a/services/analysis/internal/model/agreement.go b/services/analysis/internal/model/agreement.go new file mode 100644 index 0000000..c31c16c --- /dev/null +++ b/services/analysis/internal/model/agreement.go @@ -0,0 +1,16 @@ +package model + +import "lone-services/pkg/modelbase" + +type AgreementModel struct { + modelbase.Base +} + +func (m AgreementModel) TableName() string { + return modelbase.Prefix() + "skin_agreements" +} + +func (m AgreementModel) Init() AgreementModel { + m.Table = m.TableName() + return m +} diff --git a/services/analysis/internal/model/authorize.go b/services/analysis/internal/model/authorize.go new file mode 100644 index 0000000..27c7cac --- /dev/null +++ b/services/analysis/internal/model/authorize.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/analysis/internal/dao" +) + +type UserStoreAuthModel struct { + modelbase.Base +} + +func (m UserStoreAuthModel) TableName() string { + return modelbase.Prefix() + "skin_user_images_authorize" +} + +func (m UserStoreAuthModel) Init() UserStoreAuthModel { + m.Table = m.TableName() + return m +} + +func (m UserStoreAuthModel) Create(data *dao.UserStoreAuth) error { + return m.Base.Create(data) +} diff --git a/services/analysis/internal/model/user.go b/services/analysis/internal/model/user.go new file mode 100644 index 0000000..1e0ab1b --- /dev/null +++ b/services/analysis/internal/model/user.go @@ -0,0 +1,23 @@ +package model + +import ( + "lone-services/pkg/modelbase" + "lone-services/services/analysis/internal/dao" +) + +type UserModel struct { + modelbase.Base +} + +func (m UserModel) TableName() string { + return modelbase.Prefix() + "users" +} + +func (m UserModel) Init() UserModel { + m.Table = m.TableName() + return m +} + +func (m UserModel) Create(data *dao.UserCreate) error { + return m.Base.Create(data) +} diff --git a/services/analysis/internal/server/analysis/analysisServer.go b/services/analysis/internal/server/analysis/analysisServer.go new file mode 100644 index 0000000..9995257 --- /dev/null +++ b/services/analysis/internal/server/analysis/analysisServer.go @@ -0,0 +1,39 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package server + +import ( + "context" + + "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/analysis" + "lone-services/services/analysis/internal/svc" +) + +type AnalysisServer struct { + svcCtx *svc.ServiceContext + analysis.UnimplementedAnalysisServer +} + +func NewAnalysisServer(svcCtx *svc.ServiceContext) *AnalysisServer { + return &AnalysisServer{ + svcCtx: svcCtx, + } +} + +func (s *AnalysisServer) InternalCreateUser(ctx context.Context, in *analysis.InternalCreateUserReq) (*analysis.InternalCreateUserData, error) { + l := analysislogic.NewInternalCreateUserLogic(ctx, s.svcCtx) + return l.InternalCreateUser(in) +} + +func (s *AnalysisServer) AgreementInfo(ctx context.Context, in *analysis.AgreementInfoReq) (*analysis.Response, error) { + l := analysislogic.NewAgreementInfoLogic(ctx, s.svcCtx) + return l.AgreementInfo(in) +} + +func (s *AnalysisServer) Switch(ctx context.Context, in *analysis.SwitchReq) (*analysis.Response, error) { + l := analysislogic.NewSwitchLogic(ctx, s.svcCtx) + return l.Switch(in) +} diff --git a/services/analysis/internal/server/analysisAuthServer.go b/services/analysis/internal/server/analysisAuthServer.go deleted file mode 100644 index 05dd613..0000000 --- a/services/analysis/internal/server/analysisAuthServer.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by goctl. DO NOT EDIT. -// goctl 1.10.1 -// Source: analysis.proto - -package server - -import ( - "context" - - "lone-services/rpc/analysis/pb" - "lone-services/services/analysis/internal/logic" - "lone-services/services/analysis/internal/svc" -) - -type AnalysisAuthServer struct { - svcCtx *svc.ServiceContext - analysis.UnimplementedAnalysisAuthServer -} - -func NewAnalysisAuthServer(svcCtx *svc.ServiceContext) *AnalysisAuthServer { - return &AnalysisAuthServer{ - svcCtx: svcCtx, - } -} - -func (s *AnalysisAuthServer) GenerateQrcode(ctx context.Context, in *analysis.GenerateQrcodeRequest) (*analysis.Response, error) { - l := logic.NewGenerateQrcodeLogic(ctx, s.svcCtx) - return l.GenerateQrcode(in) -} diff --git a/services/analysis/internal/server/analysisdevice/analysisDeviceServer.go b/services/analysis/internal/server/analysisdevice/analysisDeviceServer.go new file mode 100644 index 0000000..5531483 --- /dev/null +++ b/services/analysis/internal/server/analysisdevice/analysisDeviceServer.go @@ -0,0 +1,21 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package server + +import ( + analysis "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/svc" +) + +type AnalysisDeviceServer struct { + svcCtx *svc.ServiceContext + analysis.UnimplementedAnalysisDeviceServer +} + +func NewAnalysisDeviceServer(svcCtx *svc.ServiceContext) *AnalysisDeviceServer { + return &AnalysisDeviceServer{ + svcCtx: svcCtx, + } +} diff --git a/services/analysis/internal/server/analysisstore/analysisStoreServer.go b/services/analysis/internal/server/analysisstore/analysisStoreServer.go new file mode 100644 index 0000000..fada4e1 --- /dev/null +++ b/services/analysis/internal/server/analysisstore/analysisStoreServer.go @@ -0,0 +1,36 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package server + +import ( + "context" + + "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/analysisstore" + "lone-services/services/analysis/internal/svc" +) + +type AnalysisStoreServer struct { + svcCtx *svc.ServiceContext + analysis.UnimplementedAnalysisStoreServer +} + +func NewAnalysisStoreServer(svcCtx *svc.ServiceContext) *AnalysisStoreServer { + return &AnalysisStoreServer{ + svcCtx: svcCtx, + } +} + +// 门店账号密码授权用户 +func (s *AnalysisStoreServer) StoreAuth(ctx context.Context, in *analysis.StoreAuthReq) (*analysis.Response, error) { + l := analysisstorelogic.NewStoreAuthLogic(ctx, s.svcCtx) + return l.StoreAuth(in) +} + +// 门店获取扫码授权二维码 +func (s *AnalysisStoreServer) StoreAuthQrcode(ctx context.Context, in *analysis.StoreAuthQrcodeReq) (*analysis.Response, error) { + l := analysisstorelogic.NewStoreAuthQrcodeLogic(ctx, s.svcCtx) + return l.StoreAuthQrcode(in) +} diff --git a/services/analysis/internal/server/analysisuser/analysisUserServer.go b/services/analysis/internal/server/analysisuser/analysisUserServer.go new file mode 100644 index 0000000..01e3e11 --- /dev/null +++ b/services/analysis/internal/server/analysisuser/analysisUserServer.go @@ -0,0 +1,50 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: analysis.proto + +package server + +import ( + "context" + + "lone-services/rpc/analysis/pb" + "lone-services/services/analysis/internal/logic/analysisuser" + "lone-services/services/analysis/internal/svc" +) + +type AnalysisUserServer struct { + svcCtx *svc.ServiceContext + analysis.UnimplementedAnalysisUserServer +} + +func NewAnalysisUserServer(svcCtx *svc.ServiceContext) *AnalysisUserServer { + return &AnalysisUserServer{ + svcCtx: svcCtx, + } +} + +func (s *AnalysisUserServer) UserRegister(ctx context.Context, in *analysis.UserRegisterReq) (*analysis.Response, error) { + l := analysisuserlogic.NewUserRegisterLogic(ctx, s.svcCtx) + return l.UserRegister(in) +} + +func (s *AnalysisUserServer) FaceBind(ctx context.Context, in *analysis.FaceBindReq) (*analysis.Response, error) { + l := analysisuserlogic.NewFaceBindLogic(ctx, s.svcCtx) + return l.FaceBind(in) +} + +func (s *AnalysisUserServer) UserImprove(ctx context.Context, in *analysis.UserImproveReq) (*analysis.Response, error) { + l := analysisuserlogic.NewUserImproveLogic(ctx, s.svcCtx) + return l.UserImprove(in) +} + +func (s *AnalysisUserServer) UserDelete(ctx context.Context, in *analysis.UserDeleteReq) (*analysis.Response, error) { + l := analysisuserlogic.NewUserDeleteLogic(ctx, s.svcCtx) + return l.UserDelete(in) +} + +// 用户扫码确认/拒绝授权 +func (s *AnalysisUserServer) UserAuth(ctx context.Context, in *analysis.UserAuthReq) (*analysis.Response, error) { + l := analysisuserlogic.NewUserAuthLogic(ctx, s.svcCtx) + return l.UserAuth(in) +} diff --git a/services/analysis/internal/svc/servicecontext.go b/services/analysis/internal/svc/servicecontext.go index 4fd2d4e..11f51b9 100644 --- a/services/analysis/internal/svc/servicecontext.go +++ b/services/analysis/internal/svc/servicecontext.go @@ -21,7 +21,7 @@ type rpcClientCacheEntry struct { expireAt time.Time } -const rpcClientCacheTTL = 30 * time.Second //缓存过期时间 +const rpcClientCacheTTL = 30 * time.Second var ( rpcCacheLock sync.Mutex @@ -35,15 +35,13 @@ func GetRpcClient(serviceName string) (zrpc.Client, error) { return nil, err } - cacheKey := serviceName - rpcCacheLock.Lock() - entry, ok := rpcCache[cacheKey] + entry, ok := rpcCache[serviceName] if ok && time.Now().Before(entry.expireAt) { rpcCacheLock.Unlock() return entry.cli, nil } - delete(rpcCache, cacheKey) + delete(rpcCache, serviceName) rpcCacheLock.Unlock() inst, err := discovery.Pick(serviceName) @@ -54,14 +52,13 @@ func GetRpcClient(serviceName string) (zrpc.Client, error) { } target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen)) - cli := zrpc.MustNewClient(zrpc.RpcClientConf{ Target: target, - Timeout: utils.RpcTimeOut, //rpc调用超时5s + Timeout: utils.RpcTimeOut, }) rpcCacheLock.Lock() - rpcCache[cacheKey] = &rpcClientCacheEntry{ + rpcCache[serviceName] = &rpcClientCacheEntry{ cli: cli, target: target, expireAt: time.Now().Add(rpcClientCacheTTL), @@ -75,23 +72,24 @@ type ServiceContext struct { Config config.Config DB *gorm.DB Prefix string + UserSvcName string ChoreSvcName string } func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { - //启动仅读取配置,不建立rpc连接 多个服务就多个 - ChoreSvc := utils.GetConfigString("services.chore") - - if ChoreSvc == utils.StringEmpty { + userSvc := utils.GetConfigString("services.user") + if userSvc == utils.StringEmpty { + logx.Error("config services.user empty") + } + choreSvc := utils.GetConfigString("services.chore") + if choreSvc == utils.StringEmpty { logx.Error("config services.chore empty") } - - svcCtx := &ServiceContext{ + return &ServiceContext{ Config: c, DB: db, Prefix: utils.GetConfigString("mysql.prefix"), - ChoreSvcName: ChoreSvc, + UserSvcName: userSvc, + ChoreSvcName: choreSvc, } - - return svcCtx } diff --git a/services/analysis/run.toml b/services/analysis/run.toml index 090d0de..fc66190 100644 --- a/services/analysis/run.toml +++ b/services/analysis/run.toml @@ -50,12 +50,14 @@ [wechat] appid = 'wxa6f5d68dcbc955c7' secret = '657bc95ab1eb4462913c056802b677c1' - login_page = 'pagesB/userLogin/index' - width = 430 env_version = 'trial' + width = 430 + auth_page = 'pagesB/authorize/scan' [services] + user = "user-service" chore = "chore-service" - -[encrypt] - data_key = "u2t9T3luZtoRfhBstkFN6TiIMW38BA8a" \ No newline at end of file +[switch] + wechat = 1 + facepp = 1 + analysis = 1 \ No newline at end of file diff --git a/services/analysis/validator/user.go b/services/analysis/validator/user.go new file mode 100644 index 0000000..44db928 --- /dev/null +++ b/services/analysis/validator/user.go @@ -0,0 +1,106 @@ +package validator + +import "lone-services/pkg/validate" + +type UserImproveValidator struct { + Avatar string + Nickname string + Birthday string + Mobile string + Gender int32 `validate:"omitempty,oneof=0 1 2 3"` + Password string + District string + Address string +} + +func (p UserImproveValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Gender.oneof": "性别不正确", + } +} + +type UserRegisterValidator struct { + Code string `validate:"required,max=128"` +} + +func (p UserRegisterValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Code.required": "code 不能为空", + "Code.max": "code 过长", + } +} + +type FaceBindValidator struct { + FacePath string `validate:"required,max=512"` +} + +func (p FaceBindValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "FacePath.required": "face_path 不能为空", + "FacePath.max": "face_path 过长", + } +} + +type AgreementInfoValidator struct { + Type int32 `validate:"required,gt=0"` +} + +func (p AgreementInfoValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Type.required": "type 必传", + "Type.gt": "type 必传", + } +} + +type UserDeleteValidator struct { + Id int64 `validate:"required,gt=0"` +} + +func (p UserDeleteValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Id.required": "id 不能为空", + "Id.gt": "id 必须大于0", + } +} + +type SwitchValidator struct { + Type int32 `validate:"omitempty,gte=0"` +} + +func (p SwitchValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{} +} + +type StoreAuthValidator struct { + Username string `validate:"required,max=32"` + Password string `validate:"required,max=64"` + ValidityTime string `validate:"required,max=32"` +} + +func (p StoreAuthValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Username.required": "账号必传", + "Username.max": "账号过长", + "Password.required": "密码必传", + "Password.max": "密码过长", + "ValidityTime.required": "有效时间必传", + "ValidityTime.max": "有效时间过长", + } +} + +type UserAuthValidator struct { + Type int32 `validate:"required,oneof=1 2"` + StoreId int64 `validate:"required,gt=0"` + ValidityTime string `validate:"required_if=Type 1,omitempty,max=32"` +} + +func (p UserAuthValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Type.required": "类型必传", + "Type.oneof": "类型只能是1或2", + "StoreId.required": "门店id必传", + "StoreId.gt": "门店id必传", + "ValidityTime.required": "有效时间必传", + "ValidityTime.max": "有效时间过长", + } +} diff --git a/services/chore/internal/logic/testLogic.go b/services/chore/internal/logic/testLogic.go index fb55378..4f12511 100644 --- a/services/chore/internal/logic/testLogic.go +++ b/services/chore/internal/logic/testLogic.go @@ -2,12 +2,11 @@ package logic import ( "context" - "fmt" "lone-services/pkg/rpcclient" "lone-services/pkg/utils" chore "lone-services/rpc/chore/pb" - product "lone-services/rpc/product/pb" + user "lone-services/rpc/user/pb" "lone-services/services/chore/internal/svc" "github.com/zeromicro/go-zero/core/logx" @@ -32,9 +31,9 @@ func NewTestLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TestLogic { } func (l *TestLogic) Test(in *chore.TestReq) (*chore.Response, error) { - cli, err := rpcclient.Get(l.svcCtx.ProductSvcName) + // cli, err := rpcclient.Get(l.svcCtx.ProductSvcName) // cli, err := rpcclient.Get(l.svcCtx.SaleSvcName) - // cli, err := rpcclient.Get(l.svcCtx.UserSvcName) + cli, err := rpcclient.Get(l.svcCtx.UserSvcName) if err != nil { l.Errorf("get rpc: %v", err) @@ -121,21 +120,21 @@ func (l *TestLogic) Test(in *chore.TestReq) (*chore.Response, error) { // }) // fmt.Println(res.GetResult()) - // res, err := user.NewUserClient(cli.Conn()).InternalCreate(l.ctx, &user.InternalCreateReq{ - // BizId: 10086, - // Mobile: in.GetChar(), - // ClientCode: []string{"user_skin", "user_o2"}, - // CredentialType: []string{"password", "sms"}, - // Identifier: in.GetChar(), - // Secret: "123123", - // }) - - res, err := product.NewProductClient(cli.Conn()).InternalItems(l.ctx, &product.InternalItemsReq{ - Status: []uint32{}, - Type: []uint32{}, + res, err := user.NewUserClient(cli.Conn()).InternalCreate(l.ctx, &user.InternalCreateReq{ + BizId: 128, + Mobile: in.GetChar(), + Name: "zzw", + ClientCode: []string{"store_skin"}, + CredentialType: []string{"password", "sms"}, + Identifier: in.GetChar(), + Secret: "123123", }) - fmt.Println(res.GetItems()) + // res, err := product.NewProductClient(cli.Conn()).InternalItems(l.ctx, &product.InternalItemsReq{ + // Status: []uint32{}, + // Type: []uint32{}, + // }) + if err != nil { l.Errorf("XXXXXX: %v", err) return failResponse(utils.ErrorInternalServer), nil diff --git a/services/percutaneous/internal/logic/userItemsLogic.go b/services/percutaneous/internal/logic/userItemsLogic.go index 9564312..a05dd4e 100644 --- a/services/percutaneous/internal/logic/userItemsLogic.go +++ b/services/percutaneous/internal/logic/userItemsLogic.go @@ -10,7 +10,7 @@ import ( "lone-services/services/percutaneous/validator" "strconv" - "lone-services/rpc/percutaneous/pb" + percutaneous "lone-services/rpc/percutaneous/pb" "lone-services/services/percutaneous/internal/svc" "github.com/zeromicro/go-zero/core/logx" @@ -101,6 +101,4 @@ func (l *UserItemsLogic) setUserItems(info *[]dao.GroupInfo, ids []int64) { (*info)[key].UserName = names[item.UserId].Name (*info)[key].UserAvatar = names[item.UserId].Avatar } - - return } diff --git a/services/product/internal/logic/apiInfoLogic.go b/services/product/internal/logic/apiInfoLogic.go index 39fbb59..e1d1e1c 100644 --- a/services/product/internal/logic/apiInfoLogic.go +++ b/services/product/internal/logic/apiInfoLogic.go @@ -57,9 +57,12 @@ func (l *ApiInfoLogic) ApiInfo(in *product.ApiInfoReq) (*product.Response, error return failResponse(utils.ErrorNotFund), nil } - // 试用资格仅门店登录时计算 - if userInfo.StoreId >= utils.NumberOne { - if err := l.fillStorePermit(&info, userInfo.StoreId); err != nil { + storeId := userInfo.BizId + if storeId < utils.NumberOne { + storeId = userInfo.StoreId + } + if storeId >= utils.NumberOne { + if err := l.fillStorePermit(&info, storeId); err != nil { l.Errorf("api product info permit: %v", err) return failResponse(utils.Fail), nil } diff --git a/services/store/internal/logic/applyVerifyStatusLogic.go b/services/store/internal/logic/applyVerifyStatusLogic.go index 4ffc086..df47d6b 100644 --- a/services/store/internal/logic/applyVerifyStatusLogic.go +++ b/services/store/internal/logic/applyVerifyStatusLogic.go @@ -7,7 +7,7 @@ import ( "lone-services/pkg/validate" order "lone-services/rpc/order/pb" sale "lone-services/rpc/sale/pb" - "lone-services/rpc/store/pb" + store "lone-services/rpc/store/pb" user "lone-services/rpc/user/pb" "lone-services/services/store/internal/dao" "lone-services/services/store/internal/model" @@ -204,8 +204,8 @@ func (l *ApplyVerifyStatusLogic) updateUser(info dao.StoreNewCreate) utils.Statu client := user.NewUserClient(cli.Conn()) - mobile, sErr := utils.EncryptPhone(info.UserMobile) - if sErr != nil { + mobile, dErr := utils.DecryptPhone(info.UserMobile) + if dErr != nil { return utils.ErrorEncryptAesError } data := user.InternalUpdateReq{ @@ -215,7 +215,7 @@ func (l *ApplyVerifyStatusLogic) updateUser(info dao.StoreNewCreate) utils.Statu Name: info.UserName, ClientCode: strings.Split(info.StoreType, utils.DecollatorComma), //哪端 CredentialType: []string{dao.LoginTypePassword, dao.LoginTypeSms}, - Identifier: mobile, //手机号 + Identifier: mobile, } _, err = client.InternalUpdate(context.Background(), &data) if err != nil { diff --git a/services/store/internal/logic/createLogic.go b/services/store/internal/logic/createLogic.go index 8212932..6e2a7d8 100644 --- a/services/store/internal/logic/createLogic.go +++ b/services/store/internal/logic/createLogic.go @@ -4,7 +4,7 @@ import ( "context" "lone-services/pkg/utils" sale "lone-services/rpc/sale/pb" - "lone-services/rpc/store/pb" + store "lone-services/rpc/store/pb" user "lone-services/rpc/user/pb" "lone-services/services/store/internal/dao" "lone-services/services/store/internal/model" @@ -112,7 +112,7 @@ func (l *CreateLogic) Create(in *store.CreateRequest) (*store.Response, error) { modelObj.Rollback() return l.fail(utils.ErrorInternalServer) } - uErr = l.createUser(data, in.Password) + uErr = l.createUser(data, in.UserMobile, in.Password) if uErr != utils.Ok { modelObj.Rollback() return l.fail(uErr) @@ -138,7 +138,7 @@ func (l *CreateLogic) getSaleInfo(id int64) (int64, utils.Status) { return info.GroupId, utils.Ok } -func (l *CreateLogic) createUser(info dao.StoreCreate, password string) utils.Status { +func (l *CreateLogic) createUser(info dao.StoreCreate, mobile, password string) utils.Status { cli, err := svc.GetRpcClient(l.svcCtx.UserName) if err != nil { logx.Errorf("get user err: %v", err) @@ -147,10 +147,6 @@ func (l *CreateLogic) createUser(info dao.StoreCreate, password string) utils.St client := user.NewUserClient(cli.Conn()) - mobile, sErr := utils.EncryptPhone(info.UserMobile) - if sErr != nil { - return utils.ErrorEncryptAesError - } data := user.InternalCreateReq{ BizId: info.Id, Mobile: mobile, diff --git a/services/store/internal/logic/editLogic.go b/services/store/internal/logic/editLogic.go index cefff7e..ee3aad2 100644 --- a/services/store/internal/logic/editLogic.go +++ b/services/store/internal/logic/editLogic.go @@ -139,7 +139,7 @@ func (l *EditLogic) Edit(in *store.EditRequest) (*store.Response, error) { } if (oldMobile != in.UserMobile && oldMobile2 != in.UserMobile) || in.UserName != info.UserName { - uErr = l.updateUser(info) + uErr = l.updateUser(info, in.UserMobile) if uErr != utils.Ok { return l.fail(uErr) } @@ -161,7 +161,7 @@ func (l *EditLogic) Edit(in *store.EditRequest) (*store.Response, error) { return l.ok(utils.NumberOne) } -func (l *EditLogic) updateUser(info dao.StoreCreate) utils.Status { +func (l *EditLogic) updateUser(info dao.StoreCreate, mobile string) utils.Status { cli, err := svc.GetRpcClient(l.svcCtx.OrderName) if err != nil { logx.Errorf("get user err: %v", err) @@ -170,10 +170,6 @@ func (l *EditLogic) updateUser(info dao.StoreCreate) utils.Status { client := user.NewUserClient(cli.Conn()) - mobile, sErr := utils.EncryptPhone(info.UserMobile) - if sErr != nil { - return utils.ErrorEncryptAesError - } data := user.InternalUpdateReq{ BizId: info.Id, SubjectType: dao.UserTypeName, @@ -181,7 +177,7 @@ func (l *EditLogic) updateUser(info dao.StoreCreate) utils.Status { Name: info.UserName, ClientCode: strings.Split(info.StoreType, utils.DecollatorComma), //哪端 CredentialType: []string{dao.LoginTypePassword, dao.LoginTypeSms}, - Identifier: mobile, //手机号 + Identifier: mobile, } _, err = client.InternalUpdate(context.Background(), &data) if err != nil { diff --git a/services/store/internal/logic/getInfoByIdLogic.go b/services/store/internal/logic/getInfoByIdLogic.go index be7790f..349d915 100644 --- a/services/store/internal/logic/getInfoByIdLogic.go +++ b/services/store/internal/logic/getInfoByIdLogic.go @@ -8,7 +8,7 @@ import ( "lone-services/services/store/internal/model" "strconv" - "lone-services/rpc/store/pb" + store "lone-services/rpc/store/pb" "lone-services/services/store/internal/svc" "github.com/zeromicro/go-zero/core/logx" @@ -46,7 +46,7 @@ func (l *GetInfoByIdLogic) GetInfoById(in *store.IdRequest) (*store.InfoResponse if info.Id > utils.NumberZero { mobile, dErr := utils.DecryptPhone(info.UserMobile) - if dErr == nil { + if dErr != nil { return nil, status.Error(codes.Internal, utils.ErrorEncryptAesError.Msg) } info.UserMobile = mobile diff --git a/services/store/internal/logic/verifyEditLogic.go b/services/store/internal/logic/verifyEditLogic.go index 3486e76..ba3a560 100644 --- a/services/store/internal/logic/verifyEditLogic.go +++ b/services/store/internal/logic/verifyEditLogic.go @@ -11,7 +11,7 @@ import ( "strconv" "strings" - "lone-services/rpc/store/pb" + store "lone-services/rpc/store/pb" "lone-services/services/store/internal/svc" "github.com/zeromicro/go-zero/core/logx" @@ -113,7 +113,7 @@ func (l *VerifyEditLogic) VerifyEdit(in *store.EditRequest) (*store.Response, er modelObj.Begin() if oldMobile != in.UserMobile && encryptMobile != info.UserMobile { - uErr := l.updateUser(info) + uErr := l.updateUser(info, in.UserMobile) if uErr != utils.Ok { modelObj.Rollback() return l.fail(uErr) @@ -139,7 +139,7 @@ func (l *VerifyEditLogic) VerifyEdit(in *store.EditRequest) (*store.Response, er return l.ok(utils.NumberOne) } -func (l *VerifyEditLogic) updateUser(info dao.StoreCreate) utils.Status { +func (l *VerifyEditLogic) updateUser(info dao.StoreCreate, mobile string) utils.Status { cli, err := svc.GetRpcClient(l.svcCtx.OrderName) if err != nil { logx.Errorf("get user err: %v", err) @@ -148,10 +148,6 @@ func (l *VerifyEditLogic) updateUser(info dao.StoreCreate) utils.Status { client := user.NewUserClient(cli.Conn()) - mobile, sErr := utils.EncryptPhone(info.UserMobile) - if sErr != nil { - return utils.ErrorEncryptAesError - } data := user.InternalUpdateReq{ BizId: info.Id, SubjectType: dao.UserTypeName, @@ -159,7 +155,7 @@ func (l *VerifyEditLogic) updateUser(info dao.StoreCreate) utils.Status { Name: info.UserName, ClientCode: strings.Split(info.StoreType, utils.DecollatorComma), //哪端 CredentialType: []string{dao.LoginTypePassword, dao.LoginTypeSms}, - Identifier: mobile, //手机号 + Identifier: mobile, } _, err = client.InternalUpdate(context.Background(), &data) if err != nil { diff --git a/services/store/internal/logic/verifyStatusLogic.go b/services/store/internal/logic/verifyStatusLogic.go index 202ce5a..852405e 100644 --- a/services/store/internal/logic/verifyStatusLogic.go +++ b/services/store/internal/logic/verifyStatusLogic.go @@ -139,8 +139,8 @@ func (l *VerifyStatusLogic) updateUserPwd(info dao.StoreCreate) utils.Status { client := user.NewUserClient(cli.Conn()) - mobile, sErr := utils.EncryptPhone(info.UserMobile) - if sErr != nil { + mobile, dErr := utils.DecryptPhone(info.UserMobile) + if dErr != nil { return utils.ErrorEncryptAesError } data := user.InternalUpdateReq{ @@ -150,7 +150,7 @@ func (l *VerifyStatusLogic) updateUserPwd(info dao.StoreCreate) utils.Status { Name: info.UserName, ClientCode: strings.Split(info.StoreType, utils.DecollatorComma), //哪端 CredentialType: []string{dao.LoginTypePassword, dao.LoginTypeSms}, - Identifier: mobile, //手机号 + Identifier: mobile, } _, err = client.InternalUpdate(context.Background(), &data) if err != nil { diff --git a/services/user/internal/config/wechat.go b/services/user/internal/config/wechat.go index 38f5a0a..964ae9c 100644 --- a/services/user/internal/config/wechat.go +++ b/services/user/internal/config/wechat.go @@ -5,14 +5,57 @@ import ( "lone-services/pkg/utils" "lone-services/pkg/wechat/auth" + "lone-services/pkg/wechat/qrcode" ) -func NewWechatClient(clientCode string) (*auth.Client, error) { +type WechatConfig struct { + AppID string + Secret string + Page string + Width int + EnvVersion string +} + +func LoadWechatConfig(clientCode string) (*WechatConfig, error) { + if clientCode == utils.StringEmpty { + return nil, fmt.Errorf("client_code empty") + } prefix := "wechat." + clientCode - appID := utils.GetConfigString(prefix + ".app_id") - secret := utils.GetConfigString(prefix + ".app_secret") + + appID := utils.GetConfigString(prefix + ".appid") + secret := utils.GetConfigString(prefix + ".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 + + page := utils.GetConfigString(prefix + ".page") + if page == utils.StringEmpty { + page = "pages/index/index" + } + width := utils.GetConfigInt(prefix + ".width") + if width <= 0 { + width = 430 + } + envVersion := utils.GetConfigString(prefix + ".env_version") + + if envVersion == utils.StringEmpty { + envVersion = "trial" + } + + return &WechatConfig{ + AppID: appID, + Secret: secret, + Page: page, + Width: width, + EnvVersion: envVersion, + }, nil +} + +func (c *WechatConfig) NewAuthClient() *auth.Client { + return auth.NewClient(c.AppID, c.Secret) +} + +func (c *WechatConfig) NewQrcodeClient() *qrcode.Client { + return qrcode.NewClient(c.NewAuthClient()) } diff --git a/services/user/internal/dao/session.go b/services/user/internal/dao/session.go index 62e0e38..7fbaec3 100644 --- a/services/user/internal/dao/session.go +++ b/services/user/internal/dao/session.go @@ -18,18 +18,16 @@ type UserLoginSession struct { Mobile string `json:"mobile"` Gender uint8 `json:"gender"` Birthday string `json:"birthday"` - Type uint8 `json:"type"` // 1销售 2门店 3普通用户 + Type uint8 `json:"type"` // 1:销售 2:门店 3:普通用户 ClientCode string `json:"client_code"` - SaleId int64 `json:"sale_id,omitempty"` - StoreId int64 `json:"store_id,omitempty"` + BizId int64 `json:"biz_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"` // 门店详情暂未开放 + Store any `json:"store,omitempty"` } type ProfileBase struct { @@ -43,29 +41,29 @@ type ProfileBase struct { } 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"` + 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"` + IdCardFront string `json:"id_card_front"` + IdCardBack string `json:"id_card_back"` + BusinessLicense string `json:"business_license"` } type ProfileSaleRegion struct { diff --git a/services/user/internal/dao/user.go b/services/user/internal/dao/user.go index 3c28d64..844f158 100644 --- a/services/user/internal/dao/user.go +++ b/services/user/internal/dao/user.go @@ -2,7 +2,6 @@ package dao import "lone-services/pkg/utils" -// UserRow 主用户(表 users) type UserRow struct { Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` Mobile string `gorm:"column:mobile" json:"mobile"` @@ -15,15 +14,14 @@ type UserRow struct { UpdatedAt utils.CustomTime `gorm:"column:updated_at" json:"updated_at"` } -// UserCreate 新建用户 type UserCreate struct { - Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` - Mobile string `gorm:"column:mobile" json:"mobile"` - Name string `gorm:"column:name" json:"name"` - Avatar string `gorm:"column:avatar" json:"avatar"` - Gender uint8 `gorm:"column:gender" json:"gender"` - Birthday utils.CustomTime `gorm:"column:birthday;type:date" json:"birthday"` - Status uint8 `gorm:"column:status" json:"status"` + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Mobile string `gorm:"column:mobile" json:"mobile"` + Name string `gorm:"column:name" json:"name"` + Avatar string `gorm:"column:avatar" json:"avatar"` + Gender uint8 `gorm:"column:gender" json:"gender"` + Birthday string `gorm:"column:birthday;type:date" json:"birthday"` + Status uint8 `gorm:"column:status" json:"status"` } type UserListItem struct { diff --git a/services/user/internal/logic/authHelper.go b/services/user/internal/logic/authHelper.go index 167797d..4b3c760 100644 --- a/services/user/internal/logic/authHelper.go +++ b/services/user/internal/logic/authHelper.go @@ -214,24 +214,30 @@ func createWechatCredentials(tx *gorm.DB, userId int64, openid, unionid, subject return nil } -func issueLoginToken(ctx context.Context, jwtAuth *config.JWTAuth, saleSvcName string, row *dao.UserRow, client *dao.Client) (*dao.Token, error) { +func loadUserClientBizId(userId int64, clientCode string) (int64, error) { + var row dao.UserClient + err := model.UserClientModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "user_id": strconv.FormatInt(userId, utils.NumberTen), + "client_code": clientCode, + "status": strconv.Itoa(int(dao.StatusEnabled)), + }, + }, &row) + if err != nil { + return utils.NumberZero, err + } + return row.BizId, nil +} + +func issueLoginToken(ctx context.Context, jwtAuth *config.JWTAuth, 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 - if client.Type == dao.TypeSale { - saleInfo, err := fetchSaleByUserId(ctx, saleSvcName, row.Id) - if err != nil { - return nil, err - } - if saleInfo != nil { - saleId = saleInfo.Id - } + mobile, _ := utils.DecryptPhone(row.Mobile) + session := toSession(*row, mobile, client) + if err := fillSessionBizIds(ctx, &session, row.Id, client); err != nil { + return nil, err } - - session := toSession(*row, mobile, client, saleId) ret, err := buildJwtToken(jwtAuth, session) if err != nil { return nil, err @@ -241,3 +247,40 @@ func issueLoginToken(ctx context.Context, jwtAuth *config.JWTAuth, saleSvcName s } return &ret, nil } + +func fillSessionBizIds(ctx context.Context, session *dao.UserLoginSession, userId int64, client *dao.Client) error { + switch { + case client.Type == dao.TypeSale: + saleInfo, err := fetchSaleByUserId(ctx, utils.GetConfigString("services.sale"), userId) + if err != nil { + return err + } + if saleInfo != nil { + session.BizId = saleInfo.Id + } + case client.Type == dao.TypeStore: + bizId, err := loadUserClientBizId(userId, client.Code) + if err != nil { + return err + } + if bizId < utils.NumberOne { + return nil + } + storeInfo, err := fetchStoreById(ctx, utils.GetConfigString("services.store"), bizId) + if err != nil { + return err + } + if storeInfo != nil { + session.BizId = storeInfo.Id + } + default: + bizId, err := loadUserClientBizId(userId, client.Code) + if err != nil { + return err + } + if bizId > utils.NumberZero { + session.BizId = bizId + } + } + return nil +} diff --git a/services/user/internal/logic/bizUser.go b/services/user/internal/logic/bizUser.go new file mode 100644 index 0000000..b6f0f8a --- /dev/null +++ b/services/user/internal/logic/bizUser.go @@ -0,0 +1,75 @@ +package logic + +import ( + "context" + "fmt" + "strconv" + + "lone-services/pkg/modelbase" + "lone-services/pkg/utils" + analysispb "lone-services/rpc/analysis/pb" + "lone-services/services/user/internal/dao" + "lone-services/services/user/internal/model" + "lone-services/services/user/internal/svc" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func ensureClientBizUser(ctx context.Context, userId int64, clientCode string) error { + var row dao.UserClient + err := model.UserClientModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "user_id": strconv.FormatInt(userId, utils.NumberTen), + "client_code": clientCode, + }, + }, &row) + if err != nil { + return err + } + if row.Id < utils.NumberOne { + return status.Error(codes.FailedPrecondition, "用户端关联不存在") + } + if row.BizId > utils.NumberZero { + return nil + } + + bizId, err := createBizUser(ctx, clientCode) + if err != nil { + return err + } + if bizId < utils.NumberOne { + return status.Error(codes.Internal, "业务用户创建失败") + } + + _, err = model.UserClientModel{}.Init().Edit(modelbase.Params{ + Eq: map[string]string{"id": strconv.FormatInt(row.Id, utils.NumberTen)}, + }, map[string]interface{}{ + "biz_id": bizId, + }) + return err +} + +func createBizUser(ctx context.Context, serviceKey string) (int64, error) { + switch serviceKey { + case "user_skin": + return createAnalysisBizUser(ctx, "analysis") + default: + return utils.NumberZero, status.Error(codes.InvalidArgument, fmt.Sprintf("unsupported biz_user service: %s", serviceKey)) + } +} + +func createAnalysisBizUser(ctx context.Context, svcName string) (int64, error) { + cli, err := svc.GetRpcClient(svcName) + if err != nil { + return utils.NumberZero, err + } + res, err := analysispb.NewAnalysisClient(cli.Conn()).InternalCreateUser(ctx, &analysispb.InternalCreateUserReq{}) + if err != nil { + return utils.NumberZero, err + } + if res == nil || res.Id < utils.NumberOne { + return utils.NumberZero, status.Error(codes.Internal, "analysis create user empty id") + } + return res.Id, nil +} diff --git a/services/analysis/internal/logic/generateQrcodeLogic.go b/services/user/internal/logic/generateQrcodeLogic.go similarity index 65% rename from services/analysis/internal/logic/generateQrcodeLogic.go rename to services/user/internal/logic/generateQrcodeLogic.go index 588fc1a..306eaef 100644 --- a/services/analysis/internal/logic/generateQrcodeLogic.go +++ b/services/user/internal/logic/generateQrcodeLogic.go @@ -6,12 +6,14 @@ import ( "lone-services/pkg/redis" "lone-services/pkg/utils" + "lone-services/pkg/validate" "lone-services/pkg/wechat/qrcode" - analysis "lone-services/rpc/analysis/pb" + pkgws "lone-services/pkg/ws" chore "lone-services/rpc/chore/pb" - "lone-services/services/analysis/internal/config" - "lone-services/services/analysis/internal/dao" - "lone-services/services/analysis/internal/svc" + user "lone-services/rpc/user/pb" + userconfig "lone-services/services/user/internal/config" + "lone-services/services/user/internal/svc" + "lone-services/services/user/validator" "github.com/google/uuid" jsoniter "github.com/json-iterator/go" @@ -32,19 +34,29 @@ func NewGenerateQrcodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Ge } } -func (l *GenerateQrcodeLogic) GenerateQrcode(in *analysis.GenerateQrcodeRequest) (*analysis.Response, error) { - sessionID, err := l.createSession() +func (l *GenerateQrcodeLogic) GenerateQrcode(in *user.GenerateQrcodeReq) (*user.Response, error) { + var req validator.GenerateQrcodeValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + if _, err := loadEnabledClient(req.ClientCode); err != nil { + l.Errorf("generate qrcode load client: %v", err) + return outResponse(utils.ErrorParams, "端配置不存在或已禁用"), nil + } + + wxCfg, err := userconfig.LoadWechatConfig(req.ClientCode) + if err != nil { + l.Errorf("generate qrcode wechat config: %v", err) + return outResponse(utils.Fail, "微信配置缺失"), nil + } + + sessionID, err := l.createSession(req.ClientCode) if err != nil { l.Errorf("generate qrcode session: %v", err) return outResponse(utils.Fail, "create qrcode session failed"), nil } - wxCfg, err := config.LoadWechatQrcodeConfig() - if err != nil { - l.Errorf("generate qrcode wechat config: %v", err) - return outResponse(utils.Fail, "wechat config missing"), nil - } - img, err := wxCfg.NewQrcodeClient().CreateWxaCode(l.ctx, &qrcode.WxaCodeRequest{ Path: qrcode.BuildPath(wxCfg.Page, map[string]string{ "session_id": sessionID, @@ -72,19 +84,20 @@ func (l *GenerateQrcodeLogic) GenerateQrcode(in *analysis.GenerateQrcodeRequest) }), nil } -func (l *GenerateQrcodeLogic) createSession() (string, error) { +func (l *GenerateQrcodeLogic) createSession(clientCode string) (string, error) { if redis.Client == nil { return "", fmt.Errorf("redis not initialized") } - sessionID := uuid.New().String() - payload, err := jsoniter.MarshalToString(dao.QrcodeSessionStatus{Status: dao.QrcodeSessionPending}) + payload, err := jsoniter.MarshalToString(pkgws.Session{ + Status: pkgws.StatusPending, + ClientCode: clientCode, + }) if err != nil { return "", err } - - key := dao.RedisKeyQRSession + sessionID - if err := redis.Client.Set(l.ctx, key, payload, dao.QrcodeSessionTTL).Err(); err != nil { + key := pkgws.RedisKeyQRSession + sessionID + if err := redis.Client.Set(l.ctx, key, payload, pkgws.SessionTTL).Err(); err != nil { return "", err } return sessionID, nil @@ -94,12 +107,10 @@ func (l *GenerateQrcodeLogic) uploadQrcode(content []byte) (string, error) { if l.svcCtx.ChoreSvcName == utils.StringEmpty { return "", fmt.Errorf("chore service name empty") } - cli, err := svc.GetRpcClient(l.svcCtx.ChoreSvcName) if err != nil { return "", err } - res, err := chore.NewChoreClient(cli.Conn()).InternalUpload(l.ctx, &chore.InternalUploadReq{ Filename: uuid.New().String() + ".png", Content: content, diff --git a/services/user/internal/logic/getOpenidLogic.go b/services/user/internal/logic/getOpenidLogic.go index b3af848..a45150e 100644 --- a/services/user/internal/logic/getOpenidLogic.go +++ b/services/user/internal/logic/getOpenidLogic.go @@ -47,13 +47,13 @@ func (l *GetOpenidLogic) GetOpenid(in *user.GetOpenidReq) (*user.Response, error return failResponse(utils.Fail), nil } - wxClient, cfgErr := userconfig.NewWechatClient(loginUser.ClientCode) + wxCfg, cfgErr := userconfig.LoadWechatConfig(loginUser.ClientCode) if cfgErr != nil { l.Errorf("get openid wechat config: %v", cfgErr) return outResponse(utils.Fail, "微信配置缺失"), nil } - session, wxErr := wxClient.Code2Session(req.Code) + session, wxErr := wxCfg.NewAuthClient().Code2Session(req.Code) if wxErr != nil { l.Errorf("get openid code2session: %v", wxErr) return outResponse(utils.Fail, "获取openid失败"), nil diff --git a/services/user/internal/logic/infoLogic.go b/services/user/internal/logic/infoLogic.go index c12c9cb..e1d42cd 100644 --- a/services/user/internal/logic/infoLogic.go +++ b/services/user/internal/logic/infoLogic.go @@ -41,14 +41,14 @@ func (l *InfoLogic) Info(in *user.InfoReq) (*user.Response, error) { if userType < utils.NumberOne { userType = dao.TypeUser } - + mobile, _ := utils.DecryptPhone(row.Mobile) ret := dao.ProfileData{ Type: userType, Base: dao.ProfileBase{ UserId: row.Id, Name: row.Name, Avatar: row.Avatar, - Mobile: decryptMobile(row.Mobile), + Mobile: mobile, Gender: row.Gender, Birthday: row.Birthday.DateString(), Status: row.Status, @@ -77,8 +77,8 @@ func (l *InfoLogic) Info(in *user.InfoReq) (*user.Response, error) { } 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 loginUser.BizId > utils.NumberZero { + data, err := fetchSaleById(l.ctx, l.svcCtx.SaleSvcName, loginUser.BizId) if err != nil { return nil, err } diff --git a/services/user/internal/logic/internalCreateLogic.go b/services/user/internal/logic/internalCreateLogic.go index e3096d4..dd543a3 100644 --- a/services/user/internal/logic/internalCreateLogic.go +++ b/services/user/internal/logic/internalCreateLogic.go @@ -77,9 +77,8 @@ func (l *InternalCreateLogic) InternalCreate(in *user.InternalCreateReq) (*user. } var ( - userId int64 - created bool - name = req.Name + userId int64 + name = req.Name ) credentialTypes := uniqueNonEmpty(req.CredentialType) @@ -104,23 +103,19 @@ func (l *InternalCreateLogic) InternalCreate(in *user.InternalCreateReq) (*user. return status.Error(codes.FailedPrecondition, "用户已禁用") } } else { - birthday, bErr := utils.ParseDateOnly(req.Birthday) - if bErr != nil { - return status.Error(codes.InvalidArgument, "生日格式不正确") - } + add := dao.UserCreate{ Mobile: encryptMobile, Name: req.Name, Avatar: req.Avatar, Gender: uint8(req.Gender), - Birthday: birthday, + Birthday: req.Birthday, Status: dao.StatusEnabled, } if err := userModel.Create(&add); err != nil { return err } userId = add.Id - created = true } for _, subjectType := range subjectTypes { @@ -147,10 +142,9 @@ func (l *InternalCreateLogic) InternalCreate(in *user.InternalCreateReq) (*user. } return &user.InternalCreateData{ - UserId: userId, - Created: created, - Mobile: encryptMobile, - Name: name, + UserId: userId, + Mobile: encryptMobile, + Name: name, }, nil } diff --git a/services/user/internal/logic/internalVerifyPasswordLogic.go b/services/user/internal/logic/internalVerifyPasswordLogic.go new file mode 100644 index 0000000..bd99ab3 --- /dev/null +++ b/services/user/internal/logic/internalVerifyPasswordLogic.go @@ -0,0 +1,84 @@ +package logic + +import ( + "context" + + "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/svc" + "lone-services/services/user/validator" + + "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type InternalVerifyPasswordLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewInternalVerifyPasswordLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InternalVerifyPasswordLogic { + return &InternalVerifyPasswordLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *InternalVerifyPasswordLogic) InternalVerifyPassword(in *user.InternalVerifyPasswordReq) (*user.InternalVerifyPasswordData, error) { + var req validator.InternalVerifyPasswordValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return nil, status.Error(codes.InvalidArgument, msg) + } + + subjectType := req.SubjectType + if subjectType == utils.StringEmpty { + subjectType = dao.SubjectTypeUser + } + + mobile := req.Username + if len(mobile) != utils.NumberEleven { + return nil, status.Error(codes.NotFound, utils.ErrorNotFund.Msg) + } + encryptMobile, encErr := utils.EncryptPhone(mobile) + if encErr != nil { + l.Errorf("internal verify password encrypt: %v", encErr) + return nil, status.Error(codes.Internal, utils.Fail.Msg) + } + + cred, credErr := findCredential(dao.CredentialTypePassword, encryptMobile, subjectType) + if credErr != nil { + l.Errorf("internal verify password find credential: %v", credErr) + return nil, status.Error(codes.Internal, utils.Fail.Msg) + } + if cred == nil { + return nil, status.Error(codes.NotFound, utils.ErrorNotFund.Msg) + } + if cred.Status == dao.StatusDisabled { + return nil, status.Error(codes.FailedPrecondition, "登录凭证已禁用") + } + if !utils.EqualsPassword(req.Password, cred.Secret) { + return nil, status.Error(codes.InvalidArgument, utils.ErrorPwdError.Msg) + } + + row, userErr := loadEnabledUser(cred.UserId) + if userErr != nil { + l.Errorf("internal verify password load user: %v", userErr) + return nil, status.Error(codes.NotFound, utils.ErrorNotFund.Msg) + } + + out := &user.InternalVerifyPasswordData{UserId: row.Id} + if req.ClientCode != utils.StringEmpty { + bizId, bizErr := loadUserClientBizId(row.Id, req.ClientCode) + if bizErr != nil { + l.Errorf("internal verify password load biz: %v", bizErr) + return nil, status.Error(codes.Internal, utils.Fail.Msg) + } + out.BizId = bizId + } + return out, nil +} diff --git a/services/user/internal/logic/loginLogic.go b/services/user/internal/logic/loginLogic.go index 46c5c1e..1b0a26e 100644 --- a/services/user/internal/logic/loginLogic.go +++ b/services/user/internal/logic/loginLogic.go @@ -59,13 +59,13 @@ func (l *LoginLogic) loginByOpenid(req validator.LoginValidator) (*user.Response return outResponse(utils.ErrorParams, "该端不支持微信登录"), nil } - wxClient, cfgErr := userconfig.NewWechatClient(req.ClientCode) + wxCfg, cfgErr := userconfig.LoadWechatConfig(req.ClientCode) if cfgErr != nil { l.Errorf("login wechat config: %v", cfgErr) return outResponse(utils.Fail, "微信配置缺失"), nil } - session, wxErr := wxClient.Code2Session(req.Code) + session, wxErr := wxCfg.NewAuthClient().Code2Session(req.Code) if wxErr != nil { l.Errorf("login code2session: %v", wxErr) return outResponse(utils.Fail, "微信登录失败"), nil @@ -80,13 +80,21 @@ func (l *LoginLogic) loginByOpenid(req validator.LoginValidator) (*user.Response return failResponse(utils.Fail), nil } + if bizErr := ensureClientBizUser(l.ctx, userId, req.ClientCode); bizErr != nil { + l.Errorf("login ensure biz user: %v", bizErr) + if st, ok := status.FromError(bizErr); ok { + return outResponse(utils.Fail, st.Message()), nil + } + return failResponse(utils.Fail), nil + } + row, userErr := loadEnabledUser(userId) if userErr != nil { l.Errorf("login load user: %v", userErr) return failResponse(utils.ErrorNotFund), nil } - ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client) + ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, row, client) if tokenErr != nil { l.Errorf("login issue token: %v", tokenErr) return failResponse(utils.Fail), nil @@ -143,7 +151,7 @@ func (l *LoginLogic) loginByPassword(req validator.LoginValidator) (*user.Respon return failResponse(utils.ErrorNotFund), nil } - ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client) + ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, row, client) if tokenErr != nil { l.Errorf("login issue token: %v", tokenErr) return failResponse(utils.Fail), nil @@ -207,7 +215,7 @@ func (l *LoginLogic) loginBySms(req validator.LoginValidator) (*user.Response, e return failResponse(utils.ErrorNotFund), nil } - ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, l.svcCtx.SaleSvcName, row, client) + ret, tokenErr := issueLoginToken(l.ctx, l.svcCtx.JWT, row, client) if tokenErr != nil { l.Errorf("login issue token: %v", tokenErr) return failResponse(utils.Fail), nil diff --git a/services/user/internal/logic/qrcodeLoginLogic.go b/services/user/internal/logic/qrcodeLoginLogic.go new file mode 100644 index 0000000..ec75a16 --- /dev/null +++ b/services/user/internal/logic/qrcodeLoginLogic.go @@ -0,0 +1,97 @@ +package logic + +import ( + "context" + + "lone-services/pkg/redis" + "lone-services/pkg/utils" + "lone-services/pkg/validate" + pkgws "lone-services/pkg/ws" + user "lone-services/rpc/user/pb" + "lone-services/services/user/internal/svc" + "lone-services/services/user/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +const qrcodeLoginTypeScanned = 2 + +type QrcodeLoginLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewQrcodeLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QrcodeLoginLogic { + return &QrcodeLoginLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *QrcodeLoginLogic) QrcodeLogin(in *user.QrcodeLoginReq) (*user.Response, error) { + var req validator.QrcodeLoginValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + loginUser := utils.GetUserFromCtx(l.ctx) + if !loginUser.Valid { + return failResponse(utils.ErrorNoLoginInfo), nil + } + + sess, err := pkgws.GetSession(l.ctx, req.SessionId) + if err != nil { + l.Errorf("qrcode login session: %v", err) + return failResponse(utils.ErrorQRcodeExp), nil + } + + if req.Type == qrcodeLoginTypeScanned { + data := map[string]int{"ws_type": pkgws.WsTypeScanned} + if pubErr := pkgws.UpdateSessionAndPublish(l.ctx, req.SessionId, pkgws.StatusScanned, data); pubErr != nil { + l.Errorf("qrcode login scanned publish: %v", pubErr) + } + return okResponse(data), nil + } + + clientCode := sess.ClientCode + if clientCode == utils.StringEmpty { + clientCode = loginUser.ClientCode + } + if clientCode == utils.StringEmpty { + return outResponse(utils.ErrorParams, "端编码缺失"), nil + } + + client, err := loadEnabledClient(clientCode) + if err != nil { + l.Errorf("qrcode login load client: %v", err) + return outResponse(utils.ErrorParams, "端配置不存在或已禁用"), nil + } + + row, err := loadEnabledUser(loginUser.ID) + if err != nil { + l.Errorf("qrcode login load user: %v", err) + return failResponse(utils.ErrorNotFund), nil + } + + token, err := issueLoginToken(l.ctx, l.svcCtx.JWT, row, client) + if err != nil { + l.Errorf("qrcode login issue token: %v", err) + return failResponse(utils.Fail), nil + } + + pushData := map[string]interface{}{ + "ws_type": pkgws.WsTypeLogin, + "access_token": token.AccessToken, + "refresh_token": token.RefreshToken, + "info": token.Info, + } + if pubErr := pkgws.UpdateSessionAndPublish(l.ctx, req.SessionId, pkgws.StatusLogined, pushData); pubErr != nil { + l.Errorf("qrcode login publish: %v", pubErr) + } + + _ = redis.Client.Del(l.ctx, pkgws.RedisKeyQRSession+req.SessionId).Err() + + return okResponse(nil), nil +} diff --git a/services/user/internal/logic/qrcodeScanLogic.go b/services/user/internal/logic/qrcodeScanLogic.go new file mode 100644 index 0000000..25c4032 --- /dev/null +++ b/services/user/internal/logic/qrcodeScanLogic.go @@ -0,0 +1,46 @@ +package logic + +import ( + "context" + + "lone-services/pkg/utils" + "lone-services/pkg/validate" + pkgws "lone-services/pkg/ws" + user "lone-services/rpc/user/pb" + "lone-services/services/user/internal/svc" + "lone-services/services/user/validator" + + "github.com/zeromicro/go-zero/core/logx" +) + +type QrcodeScanLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewQrcodeScanLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QrcodeScanLogic { + return &QrcodeScanLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *QrcodeScanLogic) QrcodeScan(in *user.QrcodeScanReq) (*user.Response, error) { + var req validator.QrcodeScanValidator + if msg := validate.ValidateFromProto(in, &req); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + if _, err := pkgws.GetSession(l.ctx, req.SessionId); err != nil { + l.Errorf("qrcode scan session: %v", err) + return failResponse(utils.ErrorQRcodeExp), nil + } + + data := map[string]int{"ws_type": pkgws.WsTypeScan} + if err := pkgws.Publish(l.ctx, req.SessionId, pkgws.Success(data)); err != nil { + l.Errorf("qrcode scan publish: %v", err) + } + return okResponse(nil), nil +} diff --git a/services/user/internal/logic/response.go b/services/user/internal/logic/response.go index c354e1b..33733f7 100644 --- a/services/user/internal/logic/response.go +++ b/services/user/internal/logic/response.go @@ -37,19 +37,7 @@ func outResponse(status utils.Status, msg string) *user.Response { } } -func decryptMobile(mobile string) string { - if mobile == utils.StringEmpty { - return utils.StringEmpty - } - plain, err := utils.DecryptPhone(mobile) - if err != nil { - return utils.StringEmpty - } - return plain -} - -func toSession(info dao.UserRow, mobilePlain string, client *dao.Client, saleId int64) dao.UserLoginSession { - +func toSession(info dao.UserRow, mobilePlain string, client *dao.Client) dao.UserLoginSession { return dao.UserLoginSession{ Id: info.Id, Name: info.Name, @@ -59,7 +47,6 @@ func toSession(info dao.UserRow, mobilePlain string, client *dao.Client, saleId Birthday: info.Birthday.DateString(), Type: client.Type, ClientCode: client.Code, - SaleId: saleId, } } @@ -73,8 +60,7 @@ func sessionClaims(session dao.UserLoginSession, tokenType string) utils.Claims Birthday: session.Birthday, Type: session.Type, ClientCode: session.ClientCode, - SaleId: session.SaleId, - StoreId: session.StoreId, + BizId: session.BizId, TokenType: tokenType, } } diff --git a/services/user/internal/logic/storeClient.go b/services/user/internal/logic/storeClient.go new file mode 100644 index 0000000..c76d721 --- /dev/null +++ b/services/user/internal/logic/storeClient.go @@ -0,0 +1,34 @@ +package logic + +import ( + "context" + + "lone-services/pkg/rpcclient" + "lone-services/pkg/utils" + storepb "lone-services/rpc/store/pb" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func fetchStoreById(ctx context.Context, storeSvcName string, storeId int64) (*storepb.InfoResponse, error) { + if storeSvcName == utils.StringEmpty || storeId < utils.NumberOne { + return nil, nil + } + cli, err := rpcclient.Get(storeSvcName) + if err != nil { + return nil, err + } + data, err := storepb.NewStoreClient(cli.Conn()).GetInfoById(ctx, &storepb.IdRequest{Id: storeId}) + if err != nil { + if st, ok := status.FromError(err); ok && + (st.Code() == codes.NotFound || st.Message() == utils.ErrorNotFund.Msg) { + return nil, nil + } + return nil, err + } + if data == nil || data.Id < utils.NumberOne { + return nil, nil + } + return data, nil +} diff --git a/services/user/internal/server/userServer.go b/services/user/internal/server/userServer.go index e676eec..b9ca5db 100644 --- a/services/user/internal/server/userServer.go +++ b/services/user/internal/server/userServer.go @@ -28,6 +28,21 @@ func (s *UserServer) Login(ctx context.Context, in *user.LoginReq) (*user.Respon return l.Login(in) } +func (s *UserServer) GenerateQrcode(ctx context.Context, in *user.GenerateQrcodeReq) (*user.Response, error) { + l := logic.NewGenerateQrcodeLogic(ctx, s.svcCtx) + return l.GenerateQrcode(in) +} + +func (s *UserServer) QrcodeScan(ctx context.Context, in *user.QrcodeScanReq) (*user.Response, error) { + l := logic.NewQrcodeScanLogic(ctx, s.svcCtx) + return l.QrcodeScan(in) +} + +func (s *UserServer) QrcodeLogin(ctx context.Context, in *user.QrcodeLoginReq) (*user.Response, error) { + l := logic.NewQrcodeLoginLogic(ctx, s.svcCtx) + return l.QrcodeLogin(in) +} + func (s *UserServer) Info(ctx context.Context, in *user.InfoReq) (*user.Response, error) { l := logic.NewInfoLogic(ctx, s.svcCtx) return l.Info(in) @@ -97,3 +112,8 @@ func (s *UserServer) InternalGetUserInfo(ctx context.Context, in *user.InternalG l := logic.NewInternalGetUserInfoLogic(ctx, s.svcCtx) return l.InternalGetUserInfo(in) } + +func (s *UserServer) InternalVerifyPassword(ctx context.Context, in *user.InternalVerifyPasswordReq) (*user.InternalVerifyPasswordData, error) { + l := logic.NewInternalVerifyPasswordLogic(ctx, s.svcCtx) + return l.InternalVerifyPassword(in) +} diff --git a/services/user/internal/svc/rpcclient.go b/services/user/internal/svc/rpcclient.go new file mode 100644 index 0000000..19ece8a --- /dev/null +++ b/services/user/internal/svc/rpcclient.go @@ -0,0 +1,68 @@ +package svc + +import ( + "fmt" + "net" + "strconv" + "sync" + "time" + + "lone-services/pkg/discovery" + "lone-services/pkg/utils" + + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/zrpc" +) + +type rpcClientCacheEntry struct { + cli zrpc.Client + target string + expireAt time.Time +} + +const rpcClientCacheTTL = 30 * time.Second + +var ( + rpcCacheLock sync.Mutex + rpcCache = make(map[string]*rpcClientCacheEntry) +) + +func GetRpcClient(serviceName string) (zrpc.Client, error) { + if serviceName == utils.StringEmpty { + err := fmt.Errorf("rpc serviceName is empty") + logx.Error(err) + return nil, err + } + + rpcCacheLock.Lock() + entry, ok := rpcCache[serviceName] + if ok && time.Now().Before(entry.expireAt) { + rpcCacheLock.Unlock() + return entry.cli, nil + } + delete(rpcCache, serviceName) + rpcCacheLock.Unlock() + + inst, err := discovery.Pick(serviceName) + if err != nil { + err = fmt.Errorf("discovery pick %s failed: %w", serviceName, err) + logx.Error(err) + return nil, err + } + + target := net.JoinHostPort(inst.IP, strconv.FormatUint(inst.Port, utils.NumberTen)) + cli := zrpc.MustNewClient(zrpc.RpcClientConf{ + Target: target, + Timeout: utils.RpcTimeOut, + }) + + rpcCacheLock.Lock() + rpcCache[serviceName] = &rpcClientCacheEntry{ + cli: cli, + target: target, + expireAt: time.Now().Add(rpcClientCacheTTL), + } + rpcCacheLock.Unlock() + + return cli, nil +} diff --git a/services/user/internal/svc/servicecontext.go b/services/user/internal/svc/servicecontext.go index 2a11323..77b2831 100644 --- a/services/user/internal/svc/servicecontext.go +++ b/services/user/internal/svc/servicecontext.go @@ -9,11 +9,12 @@ import ( ) type ServiceContext struct { - Config config.Config - DB *gorm.DB - Prefix string - JWT *config.JWTAuth - SaleSvcName string + Config config.Config + DB *gorm.DB + Prefix string + JWT *config.JWTAuth + SaleSvcName string + ChoreSvcName string } func NewServiceContext(c config.Config, db *gorm.DB, jwtAuth *config.JWTAuth) *ServiceContext { @@ -21,12 +22,17 @@ func NewServiceContext(c config.Config, db *gorm.DB, jwtAuth *config.JWTAuth) *S if saleSvc == utils.StringEmpty { logx.Error("config services.sale empty") } + choreSvc := utils.GetConfigString("services.chore") + if choreSvc == utils.StringEmpty { + logx.Error("config services.chore empty") + } return &ServiceContext{ - Config: c, - DB: db, - Prefix: utils.GetConfigString("mysql.prefix"), - JWT: jwtAuth, - SaleSvcName: saleSvc, + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + JWT: jwtAuth, + SaleSvcName: saleSvc, + ChoreSvcName: choreSvc, } } diff --git a/services/user/userClient/user.go b/services/user/userClient/user.go index d52bc04..ab50fb6 100644 --- a/services/user/userClient/user.go +++ b/services/user/userClient/user.go @@ -15,6 +15,7 @@ import ( type ( ClientReq = user.ClientReq + GenerateQrcodeReq = user.GenerateQrcodeReq GetOpenidReq = user.GetOpenidReq InfoReq = user.InfoReq InternalCheckCreateData = user.InternalCheckCreateData @@ -33,8 +34,12 @@ type ( InternalUpdateReq = user.InternalUpdateReq InternalUsersByIdsData = user.InternalUsersByIdsData InternalUsersByIdsReq = user.InternalUsersByIdsReq + InternalVerifyPasswordData = user.InternalVerifyPasswordData + InternalVerifyPasswordReq = user.InternalVerifyPasswordReq LoginReq = user.LoginReq PasswordReq = user.PasswordReq + QrcodeLoginReq = user.QrcodeLoginReq + QrcodeScanReq = user.QrcodeScanReq Response = user.Response UserBriefItem = user.UserBriefItem UserItemsReq = user.UserItemsReq @@ -42,6 +47,9 @@ type ( User interface { Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) + GenerateQrcode(ctx context.Context, in *GenerateQrcodeReq, opts ...grpc.CallOption) (*Response, error) + QrcodeScan(ctx context.Context, in *QrcodeScanReq, opts ...grpc.CallOption) (*Response, error) + QrcodeLogin(ctx context.Context, in *QrcodeLoginReq, opts ...grpc.CallOption) (*Response, error) Info(ctx context.Context, in *InfoReq, opts ...grpc.CallOption) (*Response, error) Password(ctx context.Context, in *PasswordReq, opts ...grpc.CallOption) (*Response, error) GetOpenid(ctx context.Context, in *GetOpenidReq, opts ...grpc.CallOption) (*Response, error) @@ -56,6 +64,7 @@ type ( InternalUpdateMobile(ctx context.Context, in *InternalUpdateMobileReq, opts ...grpc.CallOption) (*InternalUpdateMobileData, error) InternalRevokeBizClient(ctx context.Context, in *InternalRevokeBizClientReq, opts ...grpc.CallOption) (*InternalRevokeBizClientData, error) InternalGetUserInfo(ctx context.Context, in *InternalGetUserInfoReq, opts ...grpc.CallOption) (*InternalGetUserInfoData, error) + InternalVerifyPassword(ctx context.Context, in *InternalVerifyPasswordReq, opts ...grpc.CallOption) (*InternalVerifyPasswordData, error) } defaultUser struct { @@ -74,6 +83,21 @@ func (m *defaultUser) Login(ctx context.Context, in *LoginReq, opts ...grpc.Call return client.Login(ctx, in, opts...) } +func (m *defaultUser) GenerateQrcode(ctx context.Context, in *GenerateQrcodeReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.GenerateQrcode(ctx, in, opts...) +} + +func (m *defaultUser) QrcodeScan(ctx context.Context, in *QrcodeScanReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.QrcodeScan(ctx, in, opts...) +} + +func (m *defaultUser) QrcodeLogin(ctx context.Context, in *QrcodeLoginReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.QrcodeLogin(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...) @@ -143,3 +167,8 @@ func (m *defaultUser) InternalGetUserInfo(ctx context.Context, in *InternalGetUs client := user.NewUserClient(m.cli.Conn()) return client.InternalGetUserInfo(ctx, in, opts...) } + +func (m *defaultUser) InternalVerifyPassword(ctx context.Context, in *InternalVerifyPasswordReq, opts ...grpc.CallOption) (*InternalVerifyPasswordData, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.InternalVerifyPassword(ctx, in, opts...) +} diff --git a/services/user/validator/user.go b/services/user/validator/user.go index b1aed2b..ef8903e 100644 --- a/services/user/validator/user.go +++ b/services/user/validator/user.go @@ -2,6 +2,42 @@ package validator import "lone-services/pkg/validate" +type GenerateQrcodeValidator struct { + ClientCode string `validate:"required,max=32"` +} + +func (p GenerateQrcodeValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "ClientCode.required": "端编码不能为空", + "ClientCode.max": "端编码过长", + } +} + +type QrcodeScanValidator struct { + SessionId string `validate:"required,max=64"` +} + +func (p QrcodeScanValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "SessionId.required": "session_id 不能为空", + "SessionId.max": "session_id 过长", + } +} + +type QrcodeLoginValidator struct { + SessionId string `validate:"required,max=64"` + Type int32 `validate:"required,oneof=1 2"` +} + +func (p QrcodeLoginValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "SessionId.required": "session_id 不能为空", + "SessionId.max": "session_id 过长", + "Type.required": "type 不能为空", + "Type.oneof": "type 传值不对", + } +} + type LoginValidator struct { ClientCode string `validate:"required,max=32"` GrantType string `validate:"required,oneof=openid password sms"` @@ -197,6 +233,24 @@ type InternalUpdateValidator struct { SubjectType string `validate:"required,oneof=sale store user"` } +type InternalVerifyPasswordValidator struct { + Username string `validate:"required,max=32"` + Password string `validate:"required,max=64"` + SubjectType string `validate:"omitempty,oneof=sale store user"` + ClientCode string `validate:"omitempty,max=32"` +} + +func (p InternalVerifyPasswordValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Username.required": "账号不能为空", + "Username.max": "账号过长", + "Password.required": "密码不能为空", + "Password.max": "密码过长", + "SubjectType.oneof": "主体类型不正确", + "ClientCode.max": "端编码过长", + } +} + func (p InternalUpdateValidator) GetMessage() validate.ValidatorMessages { return validate.ValidatorMessages{ "Mobile.required": "手机号不能为空", diff --git a/services/ws/etc/ws.yaml b/services/ws/etc/ws.yaml new file mode 100644 index 0000000..35ad868 --- /dev/null +++ b/services/ws/etc/ws.yaml @@ -0,0 +1,7 @@ +Nacos: + Hosts: + - rnacos:8848 + NamespaceId: test + Group: LONE_SERVICES + RegisterIP: ws + ConfigID: ws diff --git a/services/ws/internal/config/config.go b/services/ws/internal/config/config.go new file mode 100644 index 0000000..0a67d2a --- /dev/null +++ b/services/ws/internal/config/config.go @@ -0,0 +1,16 @@ +package config + +import "github.com/zeromicro/go-zero/rest" + +type Config struct { + rest.RestConf `json:",optional"` + Nacos NacosConf +} + +type NacosConf struct { + Hosts []string + NamespaceId string `json:",optional"` + Group string `json:",optional"` + RegisterIP string `json:",optional"` + ConfigID string `json:",optional"` +} diff --git a/services/ws/internal/handler/connectHandler.go b/services/ws/internal/handler/connectHandler.go new file mode 100644 index 0000000..3e8de35 --- /dev/null +++ b/services/ws/internal/handler/connectHandler.go @@ -0,0 +1,26 @@ +package handler + +import ( + "net/http" + + "lone-services/services/ws/internal/logic" + "lone-services/services/ws/internal/svc" + "lone-services/services/ws/internal/types" + + "github.com/zeromicro/go-zero/rest/httpx" +) + +func ConnectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req types.ConnectReq + if err := httpx.Parse(r, &req); err != nil { + httpx.ErrorCtx(r.Context(), w, err) + return + } + + l := logic.NewConnectLogic(r.Context(), svcCtx) + if err := l.Connect(w, r, &req); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } +} diff --git a/services/ws/internal/handler/routes.go b/services/ws/internal/handler/routes.go new file mode 100644 index 0000000..88c2cb7 --- /dev/null +++ b/services/ws/internal/handler/routes.go @@ -0,0 +1,24 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 + +package handler + +import ( + "net/http" + + "lone-services/services/ws/internal/svc" + + "github.com/zeromicro/go-zero/rest" +) + +func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { + server.AddRoutes( + []rest.Route{ + { + Method: http.MethodGet, + Path: "/ws", + Handler: ConnectHandler(serverCtx), + }, + }, + ) +} diff --git a/services/ws/internal/logic/connectLogic.go b/services/ws/internal/logic/connectLogic.go new file mode 100644 index 0000000..5ecef8a --- /dev/null +++ b/services/ws/internal/logic/connectLogic.go @@ -0,0 +1,126 @@ +package logic + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "lone-services/pkg/redis" + pkgws "lone-services/pkg/ws" + "lone-services/services/ws/internal/svc" + "lone-services/services/ws/internal/types" + + "github.com/gorilla/websocket" + jsoniter "github.com/json-iterator/go" + "github.com/zeromicro/go-zero/core/logx" +) + +var upgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + CheckOrigin: func(r *http.Request) bool { + return true + }, +} + +type ConnectLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +func NewConnectLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ConnectLogic { + return &ConnectLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *ConnectLogic) Connect(w http.ResponseWriter, r *http.Request, req *types.ConnectReq) error { + if req.SessionId == "" { + return fmt.Errorf("missing session_id") + } + + sess, err := pkgws.GetSession(l.ctx, req.SessionId) + if err != nil { + if errors.Is(err, redis.Nil) { + return fmt.Errorf("qrcode session expired") + } + l.Errorf("get session: %v", err) + return fmt.Errorf("qrcode session invalid") + } + + conn, err := upgrader.Upgrade(w, r, nil) + if err != nil { + return err + } + + client := &svc.Client{SessionID: req.SessionId, Conn: conn} + l.svcCtx.Hub.Add(client) + + if err := l.pushSnapshot(client, sess); err != nil { + l.Errorf("push snapshot session=%s: %v", req.SessionId, err) + l.svcCtx.Hub.Remove(req.SessionId, conn) + _ = conn.Close() + return nil + } + + go l.readLoop(client) + go l.autoClose(client) + return nil +} + +func (l *ConnectLogic) pushSnapshot(c *svc.Client, sess *pkgws.Session) error { + var data interface{} + switch sess.Status { + case pkgws.StatusPending: + data = nil + case pkgws.StatusScanned, pkgws.StatusLogined: + if len(sess.Data) > 0 && string(sess.Data) != "null" { + var parsed any + if err := jsoniter.Unmarshal(sess.Data, &parsed); err != nil { + data = jsoniter.RawMessage(sess.Data) + } else { + data = parsed + } + } else if sess.Status == pkgws.StatusScanned { + data = map[string]int{"ws_type": pkgws.WsTypeScanned} + } else { + data = nil + } + default: + data = nil + } + + payload, err := jsoniter.Marshal(pkgws.Success(data)) + if err != nil { + return err + } + l.svcCtx.Hub.Send(c.SessionID, payload) + return nil +} + +func (l *ConnectLogic) readLoop(c *svc.Client) { + defer func() { + _ = c.Conn.Close() + l.svcCtx.Hub.Remove(c.SessionID, c.Conn) + }() + + for { + if _, _, err := c.Conn.ReadMessage(); err != nil { + return + } + } +} + +func (l *ConnectLogic) autoClose(c *svc.Client) { + timer := time.NewTimer(pkgws.SessionTTL) + defer timer.Stop() + <-timer.C + l.Infof("timeout close session=%s", c.SessionID) + _ = c.Conn.Close() + l.svcCtx.Hub.Remove(c.SessionID, c.Conn) +} diff --git a/services/ws/internal/svc/hub.go b/services/ws/internal/svc/hub.go new file mode 100644 index 0000000..cc6487b --- /dev/null +++ b/services/ws/internal/svc/hub.go @@ -0,0 +1,62 @@ +package svc + +import ( + "sync" + + "github.com/gorilla/websocket" +) + +type Client struct { + SessionID string + Conn *websocket.Conn + sendMu sync.Mutex +} + +type Hub struct { + mu sync.RWMutex + clients map[string]*Client +} + +func NewHub() *Hub { + return &Hub{clients: make(map[string]*Client)} +} + +func (h *Hub) Add(c *Client) { + h.mu.Lock() + defer h.mu.Unlock() + if old, ok := h.clients[c.SessionID]; ok && old.Conn != c.Conn { + _ = old.Conn.Close() + } + h.clients[c.SessionID] = c +} + +func (h *Hub) Remove(sessionID string, conn *websocket.Conn) { + h.mu.Lock() + defer h.mu.Unlock() + cur, ok := h.clients[sessionID] + if !ok { + return + } + if conn != nil && cur.Conn != conn { + return + } + delete(h.clients, sessionID) +} + +func (h *Hub) Send(sessionID string, payload []byte) bool { + h.mu.RLock() + c, ok := h.clients[sessionID] + h.mu.RUnlock() + if !ok { + return false + } + + c.sendMu.Lock() + defer c.sendMu.Unlock() + if err := c.Conn.WriteMessage(websocket.TextMessage, payload); err != nil { + _ = c.Conn.Close() + h.Remove(sessionID, c.Conn) + return false + } + return true +} diff --git a/services/ws/internal/svc/serviceContext.go b/services/ws/internal/svc/serviceContext.go new file mode 100644 index 0000000..34feea7 --- /dev/null +++ b/services/ws/internal/svc/serviceContext.go @@ -0,0 +1,31 @@ +package svc + +import ( + "context" + + "lone-services/services/ws/internal/config" +) + +type ServiceContext struct { + Config config.Config + Hub *Hub + cancel context.CancelFunc +} + +func NewServiceContext(c config.Config) *ServiceContext { + h := NewHub() + ctx, cancel := context.WithCancel(context.Background()) + go NewSubscriber(h).Run(ctx) + + return &ServiceContext{ + Config: c, + Hub: h, + cancel: cancel, + } +} + +func (s *ServiceContext) Close() { + if s.cancel != nil { + s.cancel() + } +} diff --git a/services/ws/internal/svc/subscriber.go b/services/ws/internal/svc/subscriber.go new file mode 100644 index 0000000..5cd6fdb --- /dev/null +++ b/services/ws/internal/svc/subscriber.go @@ -0,0 +1,78 @@ +package svc + +import ( + "context" + + "lone-services/pkg/redis" + pkgws "lone-services/pkg/ws" + + jsoniter "github.com/json-iterator/go" + "github.com/zeromicro/go-zero/core/logx" +) + +type Subscriber struct { + hub *Hub +} + +func NewSubscriber(h *Hub) *Subscriber { + return &Subscriber{hub: h} +} + +func (s *Subscriber) Run(ctx context.Context) { + if redis.Client == nil { + logx.Error("ws pubsub: redis not initialized") + return + } + + sub := redis.Client.Subscribe(ctx, pkgws.RedisChannelQRPush) + defer sub.Close() + + ch := sub.Channel() + logx.Infof("ws pubsub: subscribed %s", pkgws.RedisChannelQRPush) + + for { + select { + case <-ctx.Done(): + return + case msg, ok := <-ch: + if !ok { + return + } + s.handle([]byte(msg.Payload)) + } + } +} + +func (s *Subscriber) handle(raw []byte) { + var evt pkgws.Event + if err := jsoniter.Unmarshal(raw, &evt); err != nil { + logx.Errorf("ws pubsub: unmarshal event: %v", err) + return + } + if evt.SessionID == "" { + return + } + + resp := pkgws.Response{ + Code: evt.Code, + Message: evt.Message, + Data: nil, + } + if len(evt.Data) > 0 && string(evt.Data) != "null" { + var data any + if err := jsoniter.Unmarshal(evt.Data, &data); err != nil { + resp.Data = jsoniter.RawMessage(evt.Data) + } else { + resp.Data = data + } + } + + payload, err := jsoniter.Marshal(resp) + if err != nil { + logx.Errorf("ws pubsub: marshal response: %v", err) + return + } + if !s.hub.Send(evt.SessionID, payload) { + logx.Infof("ws pubsub: no local conn for session=%s", evt.SessionID) + } +} diff --git a/services/ws/internal/types/types.go b/services/ws/internal/types/types.go new file mode 100644 index 0000000..191f26b --- /dev/null +++ b/services/ws/internal/types/types.go @@ -0,0 +1,8 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 + +package types + +type ConnectReq struct { + SessionId string `form:"session_id"` +} diff --git a/services/ws/run.toml b/services/ws/run.toml new file mode 100644 index 0000000..6069829 --- /dev/null +++ b/services/ws/run.toml @@ -0,0 +1,27 @@ +[base] + name = "ws-service" + listenOn = "0.0.0.0:10002" + mode = "dev" + +[log] + path = "logs" + serviceName = "ws-service" + mode = "file" + encoding = "plain" + level = "info" + keepDays = 7 + maxSize = 50 + maxBackups = 5 + compress = false + +[redis] + host = '39.106.171.204' + password = 'lLMLcuPpzSj' + port = 6379 + db = 0 + +[log-redis] + host = '39.106.171.204' + password = 'lLMLcuPpzSj' + port = 6379 + db = 3 \ No newline at end of file diff --git a/services/ws/ws.api b/services/ws/ws.api new file mode 100644 index 0000000..a8e0dc6 --- /dev/null +++ b/services/ws/ws.api @@ -0,0 +1,14 @@ +syntax = "v1" + +type ConnectReq { + SessionId string `form:"session_id"` +} + +@server ( + prefix: / + group: ws +) +service ws-api { + @handler ConnectHandler + get /ws (ConnectReq) +} diff --git a/services/ws/ws.go b/services/ws/ws.go new file mode 100644 index 0000000..a80567d --- /dev/null +++ b/services/ws/ws.go @@ -0,0 +1,112 @@ +package main + +import ( + "flag" + "net" + "os" + "strconv" + + "lone-services/pkg/discovery" + "lone-services/pkg/redis" + "lone-services/pkg/utils" + "lone-services/services/ws/internal/config" + "lone-services/services/ws/internal/handler" + "lone-services/services/ws/internal/svc" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/rest" +) + +var configFile = flag.String("f", "etc/ws.yaml", "the config file") + +func main() { + flag.Parse() + var c config.Config + conf.MustLoad(*configFile, &c) + + nacosParam := utils.NacosConfig{ + Hosts: c.Nacos.Hosts, + NamespaceId: c.Nacos.NamespaceId, + Group: c.Nacos.Group, + ConfigID: c.Nacos.ConfigID, + } + utils.InitConfig(nacosParam) + + logConf := logx.LogConf{ + ServiceName: utils.GetConfigString("log.serviceName"), + Mode: utils.GetConfigString("log.mode"), + Encoding: utils.GetConfigString("log.encoding"), + Level: utils.GetConfigString("log.level"), + Path: utils.GetConfigString("log.path"), + KeepDays: utils.GetConfigInt("log.keepDays"), + MaxSize: utils.GetConfigInt("log.maxSize"), + MaxBackups: utils.GetConfigInt("log.maxBackups"), + Compress: utils.GetConfigBool("log.compress"), + } + logx.SetUp(logConf) + logx.AddWriter(logx.NewWriter(os.Stdout)) + + listenOn := utils.GetConfigString("base.listenOn") + serviceName := utils.GetConfigString("base.name") + + if err := discovery.Init(discovery.Config{ + Hosts: c.Nacos.Hosts, + NamespaceId: c.Nacos.NamespaceId, + Group: c.Nacos.Group, + }); err != nil { + logx.Errorf("nacos init: %v", err) + os.Exit(1) + } + + _, portStr, err := net.SplitHostPort(listenOn) + if err != nil { + logx.Errorf("parse ListenOn: %v", err) + os.Exit(1) + } + port, err := strconv.ParseUint(portStr, 10, 64) + if err != nil { + logx.Errorf("parse port: %v", err) + os.Exit(1) + } + + if err := discovery.Register(discovery.Instance{ + ServiceName: serviceName, + IP: c.Nacos.RegisterIP, + Port: port, + Group: c.Nacos.Group, + }); err != nil { + logx.Errorf("nacos register: %v", err) + os.Exit(1) + } + defer func() { + if err := discovery.Deregister(); err != nil { + logx.Errorf("nacos deregister: %v", err) + } + }() + + if err := redis.Init(redis.Config{ + Host: utils.GetConfigString("redis.host"), + Port: utils.GetConfigInt("redis.port"), + Password: utils.GetConfigString("redis.password"), + DB: utils.GetConfigInt("redis.db"), + }); err != nil { + logx.Errorf("redis init: %v", err) + os.Exit(1) + } + + c.Host = "0.0.0.0" + c.Port = int(port) + c.Name = serviceName + + server := rest.MustNewServer(c.RestConf) + defer server.Stop() + + ctx := svc.NewServiceContext(c) + defer ctx.Close() + + handler.RegisterHandlers(server, ctx) + logx.Infof("Starting ws-api at %s...", listenOn) + + server.Start() +}