diff --git a/README.md b/README.md index 6c5577d..f42103e 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,6 @@ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest ``` - - ### 1. 创建 RPC 服务(goctl) 在仓库根目录执行: @@ -55,8 +53,6 @@ goctl rpc new order cd order ``` - - ### 2. 将 proto 移到 `proto/` 目录 `goctl rpc new` 默认把 proto 放在服务根目录(如 `order/order.proto`)。统一挪到 `proto/`: @@ -66,8 +62,6 @@ mkdir proto mv order.proto proto/ ``` - - ### 3. Zero 兼容 Nacos 等配置 编辑 `order/internal/config/config.go`: @@ -88,8 +82,6 @@ type NacosConf struct { } ``` - - ### 4. 配置服务名与监听端口 编辑 `order/etc/order.yaml`: @@ -104,8 +96,6 @@ Nacos: ConfigID: develop-admin ``` - - ### 5. 构建 mod 编辑 `order/go.mod` 增加本地包 pkg.local @@ -126,11 +116,11 @@ replace pkg.local => ../pkg ```go "pkg.local/discovery" -"pkg.local/log" "pkg.local/modelbase" "pkg.local/mysql" "pkg.local/redis" "pkg.local/validate" +"pkg.local/utils" ``` 增加初始化 @@ -138,133 +128,127 @@ replace pkg.local => ../pkg ```go func main() { -flag.Parse() -var c config.Config -conf.MustLoad(*configFile, &c) + flag.Parse() + var c config.Config + conf.MustLoad(*configFile, &c) -// Nacos配置拉取初始化 -nacosParam := utils.NacosConfig{ -Hosts: c.Nacos.Hosts, -NamespaceId: c.Nacos.NamespaceId, -Group: c.Nacos.Group, -ConfigID: c.Nacos.ConfigID, -} -utils.InitConfig(nacosParam) + 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)) + 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") -mode := utils.GetConfigString("base.mode") -serviceName := utils.GetConfigString("base.name") + listenOn := utils.GetConfigString("base.listenOn") + mode := utils.GetConfigString("base.mode") + 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) -} + 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) + } -port, err := listenPort(listenOn) -if err != nil { -logx.Errorf("parse ListenOn: %v", err) -os.Exit(1) -} + port, err := listenPort(listenOn) + if err != nil { + logx.Errorf("parse ListenOn: %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) -} -logx.Infof("服务注册成功: %s:%d", c.Nacos.RegisterIP, port) + 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) + } + logx.Infof("服务注册成功: %s:%d", c.Nacos.RegisterIP, port) -defer func() { -if err := discovery.Deregister(); err != nil { -logx.Errorf("nacos deregister: %v", err) -} -}() + defer func() { + if err := discovery.Deregister(); err != nil { + logx.Errorf("nacos deregister: %v", err) + } + }() -// 初始化MySQL -db, err := mysql.New(mysql.Config{ -Host: utils.GetConfigString("mysql.host"), -Port: utils.GetConfigInt("mysql.port"), -User: utils.GetConfigString("mysql.user"), -Password: utils.GetConfigString("mysql.password"), -Database: utils.GetConfigString("mysql.database"), -Charset: utils.GetConfigString("mysql.charset"), -Prefix: utils.GetConfigString("mysql.prefix"), -ReadHost: utils.GetConfigString("mysql_read.host"), -ReadPort: utils.GetConfigInt("mysql_read.port"), -ReadUser: utils.GetConfigString("mysql_read.user"), -ReadPassword: utils.GetConfigString("mysql_read.password"), -ReadDatabase: utils.GetConfigString("mysql_read.database"), -}) -if err != nil { -logx.Errorf("mysql init: %v", err) -os.Exit(1) -} + db, err := mysql.New(mysql.Config{ + Host: utils.GetConfigString("mysql.host"), + Port: utils.GetConfigInt("mysql.port"), + User: utils.GetConfigString("mysql.user"), + Password: utils.GetConfigString("mysql.password"), + Database: utils.GetConfigString("mysql.database"), + Charset: utils.GetConfigString("mysql.charset"), + Prefix: utils.GetConfigString("mysql.prefix"), + ReadHost: utils.GetConfigString("mysql_read.host"), + ReadPort: utils.GetConfigInt("mysql_read.port"), + ReadUser: utils.GetConfigString("mysql_read.user"), + ReadPassword: utils.GetConfigString("mysql_read.password"), + ReadDatabase: utils.GetConfigString("mysql_read.database"), + }) + if err != nil { + logx.Errorf("mysql init: %v", err) + os.Exit(1) + } -// 初始化Redis -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) -} + 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) + } -debug := utils.GetConfigBool("mysql.debug") -modelbase.Init(db, modelbase.Config{Prefix: utils.GetConfigString("mysql.prefix"), Debug: debug}) + debug := utils.GetConfigBool("mysql.debug") + modelbase.Init(db, modelbase.Config{Prefix: utils.GetConfigString("mysql.prefix"), Debug: debug}) -// 初始化服务信息 -rpcConf := zrpc.RpcServerConf{ -ListenOn: listenOn, -} -rpcConf.Mode = mode -ctx := svc.NewServiceContext(c, db) + rpcConf := zrpc.RpcServerConf{ + ListenOn: listenOn, + } + rpcConf.Mode = mode -s := zrpc.MustNewServer(rpcConf, func(grpcServer *grpc.Server) { -admin.RegisterAdminServer(grpcServer, server.NewAdminServer(ctx)) -if mode == service.DevMode || mode == service.TestMode { -reflection.Register(grpcServer) -} -}) -defer s.Stop() + ctx := svc.NewServiceContext(c, db) -s.AddUnaryInterceptors(validate.UnaryServerInterceptor(validate.MustNew())) + s := zrpc.MustNewServer(rpcConf, func(grpcServer *grpc.Server) { + order.RegisterOrderServer(grpcServer, server.NewOrderServer(ctx)) + if mode == service.DevMode || mode == service.TestMode { + reflection.Register(grpcServer) + } + }) + defer s.Stop() -logx.Infof("Starting rpc server at %s...", listenOn) -s.Start() + s.AddUnaryInterceptors(validate.UnaryServerInterceptor(validate.MustNew())) + + logx.Infof("Starting rpc server at %s...", listenOn) + s.Start() } func listenPort(listenOn string) (uint64, error) { -_, portStr, err := net.SplitHostPort(listenOn) -if err != nil { -return 0, err -} -return strconv.ParseUint(portStr, 10, 64) + _, portStr, err := net.SplitHostPort(listenOn) + if err != nil { + return 0, err + } + return strconv.ParseUint(portStr, 10, 64) } ``` @@ -295,8 +279,6 @@ func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { ``` - - ### 7. 接入 Docker Compose 在 `deploy/docker-compose.dev.override.yml` 增加服务: @@ -318,30 +300,14 @@ func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { - rnacos ``` - - ### 8. 生成 ProtoSet 给 BFF ```bash - protoc --include_imports --proto_path=proto --descriptor_set_out=../bff/etc/order.pb order.proto ``` - - ### 9. 在 BFF 配 Upstream(HTTP 路由写在 proto) -在对应 RPC 上声明 `google.api.http`(需 `import "google/api/annotations.proto";`): - -```protobuf -rpc Ping(Request) returns (Response) { - option (google.api.http) = { - post: "/admin/v3/order/ping" - body: "*" - }; -} -``` - 编辑 `bff/etc/bff.yaml`,在 **Upstreams** 增加一段(不必写 Mappings,gateway 会从 ProtoSet 里的 http option 注册路由): ```yaml @@ -353,7 +319,16 @@ rpc Ping(Request) returns (Response) { - etc/order.pb ``` +在对应 RPC 上声明 `google.api.http`(需 `import "google/api/annotations.proto";`): +```protobuf +rpc Ping(Request) returns (Response) { + option (google.api.http) = { + post: "/admin/v3/order/ping" + body: "*" + }; +} +``` ### 编写业务须知 @@ -364,8 +339,6 @@ rpc Ping(Request) returns (Response) { --- - - ### 命令 ①:生成服务端 pb / grpc ```bash @@ -377,8 +350,6 @@ goctl rpc protoc proto/order.proto --proto_path=. --proto_path=../pkg/third_part - 只改 **校验规则**(必填/长度/范围等)→ **只跑这条** - 增删改字段、增删 RPC → 也要跑(服务端描述符要更新) - - ### 命令 ②:生成 BFF ProtoSet ```bash @@ -391,8 +362,6 @@ protoc -I. -I../pkg/third_party --descriptor_set_out=../bff/etc/order.pb --inclu - 增删 **RPC** - 改 **google.api.http** 路由 - - ### 命令 ③:goctl 生成/更新脚手架 ```bash @@ -404,8 +373,6 @@ goctl -I. -I../pkg/third_party rpc protoc proto/order.proto --go_out=. --go-grpc - **新增 RPC**:需要生成 `internal/logic`、更新 `server` / `orderclient` 等 - 注意:可能覆盖已改过的 `order.go` 等,生成后对比合并;也可用手写 logic/server 代替 - - ## Proto 常用校验规则(protovalidate) 文档:[https://protovalidate.com/schemas/standard-rules/](https://protovalidate.com/schemas/standard-rules/) @@ -434,8 +401,6 @@ double price = 6 [(buf.validate.field).double = {gte: 0}]; int32 period_validity = 16 [(buf.validate.field).int32 = {gte: 0}]; ``` - - ### 非必填数值(0 表示未传,跳过校验) ```protobuf @@ -461,24 +426,18 @@ uint32 sales_model = 4 [(buf.validate.field) = { }]; ``` - - ### ID 必须大于 0 ```protobuf int64 id = 1 [(buf.validate.field).int64 = {gt: 0}]; ``` - - ### 无规则字段 ```protobuf uint32 number = 20; // 不做 protovalidate ``` - - ### 删除字段编号(避免复用) ```protobuf diff --git a/bff/etc/user.pb b/bff/etc/user.pb new file mode 100644 index 0000000..4c3f937 Binary files /dev/null and b/bff/etc/user.pb differ diff --git a/bff/internal/response/response.go b/bff/internal/response/response.go index c655d93..d978326 100644 --- a/bff/internal/response/response.go +++ b/bff/internal/response/response.go @@ -34,12 +34,15 @@ func (b *BaseController) OutPut(w http.ResponseWriter, code int32, data any, msg if code == utils.Ok.Code && !utils.GetConfigBool("encrypt.debug") { jsonData, err := json.Marshal(data) if err != nil { + fmt.Printf("response encrypt: json.Marshal failed: %v\n", err) msg = utils.ErrorEncryptAesError.Msg code = utils.ErrorEncryptAesError.Code } else { + key := utils.GetConfigString("encrypt.encrypt_key") res, enErr := utils.Crypto{}.Encrypt(jsonData) - fmt.Printf("res: %v\n", res) if enErr != nil { + fmt.Printf("response encrypt failed: keyLen=%d keyEmpty=%v errCode=%d errMsg=%s\n", + len(key), key == "", enErr.GetCode(), enErr.GetMsg()) msg = utils.ErrorEncryptAesError.Msg code = utils.ErrorEncryptAesError.Code } else { diff --git a/product/internal/dao/product.go b/product/internal/dao/product.go index 15f6053..ac63779 100644 --- a/product/internal/dao/product.go +++ b/product/internal/dao/product.go @@ -141,11 +141,12 @@ type ProductEditBase struct { Label string `gorm:"column:label" json:"label"` IsIndex uint8 `gorm:"column:is_index" json:"is_index"` IndexImage string `gorm:"column:index_image" json:"index_image"` - PeriodValidity int16 `gorm:"column:period_validity" json:"period_validity"` - IsBuy uint8 `gorm:"column:is_buy" json:"is_buy"` - PublishTime time.Time `gorm:"column:publish_time" json:"publish_time"` - AdminName string `gorm:"column:admin_name" json:"admin_name"` - AdminId int `gorm:"column:admin_id" json:"admin_id"` + PeriodValidity int16 `gorm:"column:period_validity" json:"period_validity"` + IsBuy uint8 `gorm:"column:is_buy" json:"is_buy"` + // Edit 经 json 序列化,time.Time 会变成 RFC3339,MySQL datetime 不认,故用字符串 + PublishTime string `gorm:"column:publish_time" json:"publish_time"` + AdminName string `gorm:"column:admin_name" json:"admin_name"` + AdminId int `gorm:"column:admin_id" json:"admin_id"` } // ProductEditSusceptible 敏感字段(查询旧值 / 写入 verify 快照) @@ -165,9 +166,9 @@ type ProductEditSusceptible struct { AdminId int `gorm:"column:admin_id" json:"admin_id"` } -// ProductVerifyFirstEditStatus 敏感编辑提交后置为一审中 +// ProductVerifyFirstEditStatus 敏感编辑提交后置为一审中(Edit 走 json→map,必须带 json tag) type ProductVerifyFirstEditStatus struct { - VerifyStatus uint8 `gorm:"column:verify_status"` + VerifyStatus uint8 `gorm:"column:verify_status" json:"verify_status"` } // ProductInfo 列表/详情查询投影 @@ -246,36 +247,36 @@ type ProductVerifyListRow struct { BoxNumber float64 `gorm:"column:box_number"` } -// ProductVerifyFirstStatus 一审后回写产品审核状态 +// ProductVerifyFirstStatus 一审后回写产品审核状态(Edit 走 json→map,必须带 json tag) type ProductVerifyFirstStatus struct { - VerifyStatus uint8 `gorm:"column:verify_status"` - VerifyId int `gorm:"column:verify_id"` - VerifyName string `gorm:"column:verify_name"` - Reason string `gorm:"column:reason"` + VerifyStatus uint8 `gorm:"column:verify_status" json:"verify_status"` + VerifyId int `gorm:"column:verify_id" json:"verify_id"` + VerifyName string `gorm:"column:verify_name" json:"verify_name"` + Reason string `gorm:"column:reason" json:"reason"` } -// ProductVerifySecondStatus 二审驳回回写 +// ProductVerifySecondStatus 二审驳回回写(Edit 走 json→map,必须带 json tag) type ProductVerifySecondStatus struct { - VerifyStatus uint8 `gorm:"column:verify_status"` - VerifySecondId int `gorm:"column:verify_second_id"` - VerifySecondName string `gorm:"column:verify_second_name"` - Reason string `gorm:"column:reason"` + VerifyStatus uint8 `gorm:"column:verify_status" json:"verify_status"` + VerifySecondId int `gorm:"column:verify_second_id" json:"verify_second_id"` + VerifySecondName string `gorm:"column:verify_second_name" json:"verify_second_name"` + Reason string `gorm:"column:reason" json:"reason"` } -// ProductVerifySecondOkStatus 二审通过:应用快照并回写审核人 +// ProductVerifySecondOkStatus 二审通过:应用快照并回写审核人(Edit 走 json→map,必须带 json tag) type ProductVerifySecondOkStatus struct { - ModelCode string `gorm:"column:model_code"` - Price float32 `gorm:"column:price"` - StorePrice float32 `gorm:"column:store_price"` - SalePrice float32 `gorm:"column:sale_price"` - SharePrice float32 `gorm:"column:share_price"` - AgentPrice float32 `gorm:"column:agent_price"` - SaleReward string `gorm:"column:sale_reward"` - Type uint8 `gorm:"column:type"` - NormsNumber uint8 `gorm:"column:norms_number"` - BoxNumber float64 `gorm:"column:box_number"` - VerifyStatus uint8 `gorm:"column:verify_status"` - VerifySecondId int `gorm:"column:verify_second_id"` - VerifySecondName string `gorm:"column:verify_second_name"` - Reason string `gorm:"column:reason"` + ModelCode string `gorm:"column:model_code" json:"model_code"` + Price float32 `gorm:"column:price" json:"price"` + StorePrice float32 `gorm:"column:store_price" json:"store_price"` + SalePrice float32 `gorm:"column:sale_price" json:"sale_price"` + SharePrice float32 `gorm:"column:share_price" json:"share_price"` + AgentPrice float32 `gorm:"column:agent_price" json:"agent_price"` + SaleReward string `gorm:"column:sale_reward" json:"sale_reward"` + Type uint8 `gorm:"column:type" json:"type"` + NormsNumber uint8 `gorm:"column:norms_number" json:"norms_number"` + BoxNumber float64 `gorm:"column:box_number" json:"box_number"` + VerifyStatus uint8 `gorm:"column:verify_status" json:"verify_status"` + VerifySecondId int `gorm:"column:verify_second_id" json:"verify_second_id"` + VerifySecondName string `gorm:"column:verify_second_name" json:"verify_second_name"` + Reason string `gorm:"column:reason" json:"reason"` } diff --git a/product/internal/dao/verify.go b/product/internal/dao/verify.go index b6f9aa0..cb15905 100644 --- a/product/internal/dao/verify.go +++ b/product/internal/dao/verify.go @@ -69,20 +69,19 @@ type VerifyStatusRow struct { VerifyTime time.Time `gorm:"column:verify_time"` } -// VerifyFirstUpdate 一审回写审核表 type VerifyFirstUpdate struct { - AdminId int `gorm:"column:admin_id"` - AdminName string `gorm:"column:admin_name"` - VerifyStatus uint8 `gorm:"column:verify_status"` - VerifyReason string `gorm:"column:verify_reason"` - VerifyTime time.Time `gorm:"column:verify_time"` + AdminId int `gorm:"column:admin_id" json:"admin_id"` + AdminName string `gorm:"column:admin_name" json:"admin_name"` + VerifyStatus uint8 `gorm:"column:verify_status" json:"verify_status"` + VerifyReason string `gorm:"column:verify_reason" json:"verify_reason"` + // Edit 经 json 序列化,time.Time 会变成 RFC3339,MySQL datetime 不认,故用字符串 + VerifyTime string `gorm:"column:verify_time" json:"verify_time"` } -// VerifySecondUpdate 二审回写审核表 type VerifySecondUpdate struct { - AdminSecondId int `gorm:"column:admin_second_id"` - AdminSecondName string `gorm:"column:admin_second_name"` - VerifyStatus uint8 `gorm:"column:verify_status"` - VerifyReason string `gorm:"column:verify_reason"` - VerifyTime time.Time `gorm:"column:verify_time"` + AdminSecondId int `gorm:"column:admin_second_id" json:"admin_second_id"` + AdminSecondName string `gorm:"column:admin_second_name" json:"admin_second_name"` + VerifyStatus uint8 `gorm:"column:verify_status" json:"verify_status"` + VerifyReason string `gorm:"column:verify_reason" json:"verify_reason"` + VerifyTime string `gorm:"column:verify_time" json:"verify_time"` } diff --git a/product/internal/logic/editbaselogic.go b/product/internal/logic/editbaselogic.go index 57cf3e0..801377e 100644 --- a/product/internal/logic/editbaselogic.go +++ b/product/internal/logic/editbaselogic.go @@ -96,7 +96,7 @@ func (l *EditBaseLogic) EditBase(in *product.EditBaseReq) (*product.Response, er IsIndex: uint8(req.IsIndex), IndexImage: req.IndexImage, Label: req.Label, - PublishTime: publishTime, + PublishTime: publishTime.Format(time.DateTime), AdminName: adminName, AdminId: adminId, IsBuy: uint8(req.IsBuy), diff --git a/product/internal/logic/verifystatuslogic.go b/product/internal/logic/verifystatuslogic.go index f5aab11..e92e154 100644 --- a/product/internal/logic/verifystatuslogic.go +++ b/product/internal/logic/verifystatuslogic.go @@ -99,7 +99,7 @@ func (l *VerifyStatusLogic) verifyStatus(expectStatus uint8, in *product.VerifyS err = l.svcCtx.DB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error { vm := model.VerifyModel{}.Init().WithTX(tx) pm := model.ProductModel{}.Init().WithTX(tx) - now := time.Now() + now := time.Now().Format(time.DateTime) if expectStatus == dao.VerifyStatusChecking { if _, err := vm.Edit(w, &dao.VerifyFirstUpdate{ diff --git a/product/proto/admin/product.proto b/product/proto/admin/product.proto index 9abea73..b9aaad3 100644 --- a/product/proto/admin/product.proto +++ b/product/proto/admin/product.proto @@ -63,7 +63,7 @@ service Product { body: "*" }; } - // 编辑申请(解锁编辑权限) + // 编辑申请 rpc EditApply(EditApplyReq) returns (Response) { option (google.api.http) = { post: "/admin/v3/product/edit/apply" @@ -77,7 +77,7 @@ service Product { body: "*" }; } - // 编辑敏感信息(进入一审) + // 编辑敏感信息(进入一审) rpc EditSusceptible(EditSusceptibleReq) returns (Response) { option (google.api.http) = { put: "/admin/v3/product/susceptible" diff --git a/user/etc/user.yaml b/user/etc/user.yaml new file mode 100644 index 0000000..aeae5fa --- /dev/null +++ b/user/etc/user.yaml @@ -0,0 +1,7 @@ +Nacos: + Hosts: + - nacos:8848 + NamespaceId: test + Group: LONE_SERVICES + RegisterIP: user + ConfigID: user \ No newline at end of file diff --git a/user/go.mod b/user/go.mod new file mode 100644 index 0000000..127a565 --- /dev/null +++ b/user/go.mod @@ -0,0 +1,153 @@ +module user + +go 1.26 + +replace pkg.local => ../pkg + +require ( + github.com/zeromicro/go-zero v1.10.3 + google.golang.org/grpc v1.83.0 + google.golang.org/protobuf v1.36.12 + pkg.local v0.0.0-00010101000000-000000000000 +) + +require ( + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717165733-d22d418d82d8.1 // indirect + buf.build/go/protovalidate v0.14.0 // indirect + cel.dev/expr v0.25.2 // indirect + filippo.io/edwards25519 v1.2.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.6 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fsnotify/fsnotify v1.10.1 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.13 // indirect + github.com/gin-contrib/sse v1.1.0 // indirect + github.com/gin-gonic/gin v1.12.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.30.3 // indirect + github.com/go-sql-driver/mysql v1.10.0 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/cel-go v0.25.0 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grafana/pyroscope-go v1.3.0 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.10 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.6 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect + github.com/pelletier/go-toml/v2 v2.4.3 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.59.0 // indirect + github.com/redis/go-redis/v9 v9.21.0 // indirect + github.com/richardlehane/mscfb v1.0.7 // indirect + github.com/richardlehane/msoleps v1.0.6 // indirect + github.com/sagikazarmark/locafero v0.11.0 // indirect + github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/spf13/afero v1.15.0 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + github.com/spf13/viper v1.21.0 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/tiendc/go-deepcopy v1.7.2 // indirect + github.com/titanous/json5 v1.0.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.3.1 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xuri/efp v0.0.1 // indirect + github.com/xuri/excelize/v2 v2.11.0 // indirect + github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect + go.etcd.io/etcd/api/v3 v3.5.21 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.21 // indirect + go.etcd.io/etcd/client/v3 v3.5.21 // indirect + go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.40.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/automaxprocs v1.6.0 // indirect + go.uber.org/mock v0.6.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + go.uber.org/zap v1.24.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/arch v0.22.0 // indirect + golang.org/x/crypto v0.53.0 // indirect + golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/term v0.44.0 // indirect + golang.org/x/text v0.38.0 // indirect + golang.org/x/time v0.14.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/driver/mysql v1.6.0 // indirect + gorm.io/gorm v1.30.0 // indirect + gorm.io/plugin/dbresolver v1.6.0 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apimachinery v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect + k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) diff --git a/user/go.sum b/user/go.sum new file mode 100644 index 0000000..64fc483 --- /dev/null +++ b/user/go.sum @@ -0,0 +1,396 @@ +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717165733-d22d418d82d8.1 h1:VahIvw/JagkamVOb0q87Az0zu2tmrzlqvO2IKIGOwnI= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717165733-d22d418d82d8.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U= +buf.build/go/protovalidate v0.14.0 h1:kr/rC/no+DtRyYX+8KXLDxNnI1rINz0imk5K44ZpZ3A= +buf.build/go/protovalidate v0.14.0/go.mod h1:+F/oISho9MO7gJQNYC2VWLzcO1fTPmaTA08SDYJZncA= +cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs= +cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= +filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= +github.com/alicebob/miniredis/v2 v2.38.0 h1:nZAzCR+Lj+Vxk4ZXzm2NuKq2O33RXj1XxJ2e2uP9jiw= +github.com/alicebob/miniredis/v2 v2.38.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= +github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= +github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= +github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= +github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= +github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= +github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8= +github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc= +github.com/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw= +github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY= +github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grafana/pyroscope-go v1.3.0 h1:t3Jehad8vvqN4oRAB0LdmfQ5ZSUXQw3asoft+K4GAT8= +github.com/grafana/pyroscope-go v1.3.0/go.mod h1:XA7I3usNx+UdjOZfQnl1WV8y924vsJo9KIVrKB+9jx4= +github.com/grafana/pyroscope-go/godeltaprof v0.1.10 h1:dvhndEbyavTb59vFCd6PsrAG5qi69/qZZtegh/TJKSY= +github.com/grafana/pyroscope-go/godeltaprof v0.1.10/go.mod h1:XnWRGg2XO5uxZdiz1rfeJH6w1eZ+YICCBVXNWOfH86g= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= +github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY= +github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= +github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= +github.com/redis/go-redis/v9 v9.21.0 h1:FPBE4hhbAke+TLmcY3WkpbDffJEomdqPn3HYiqAtL9E= +github.com/redis/go-redis/v9 v9.21.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA= +github.com/richardlehane/mscfb v1.0.7 h1:oeoiM0WE79vHwE8RpIYYvIAc8ajTH2mb6UZm55/+EB0= +github.com/richardlehane/mscfb v1.0.7/go.mod h1:pe0+IUIc0AHh0+teNzBlJCtSyZdFOGgV4ZK9bsoV+Jo= +github.com/richardlehane/msoleps v1.0.6 h1:9BvkpjvD+iUBalUY4esMwv6uBkfOip/Lzvd93jvR9gg= +github.com/richardlehane/msoleps v1.0.6/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGGF0= +github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44= +github.com/tiendc/go-deepcopy v1.7.2/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ= +github.com/titanous/json5 v1.0.0 h1:hJf8Su1d9NuI/ffpxgxQfxh/UiBFZX7bMPid0rIL/7s= +github.com/titanous/json5 v1.0.0/go.mod h1:7JH1M8/LHKc6cyP5o5g3CSaRj+mBrIimTxzpvmckH8c= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= +github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8= +github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.11.0 h1:HxaEFl6sRN2+8J5a8HaKq+0M4FsjBGMnWWtjOCPSG88= +github.com/xuri/excelize/v2 v2.11.0/go.mod h1:jxFLbzaIwGQ5ufFNvYfUOHqXhfPaNmP14KWfmNz2Uak= +github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBLbf3WdLgC29pgyhTjAT/0nuE= +github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= +github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= +github.com/zeromicro/go-zero v1.10.3 h1:fm4+jUuUF77IWtFeAyf2xVoBRcgEpF1NZJUqTvZ3dw0= +github.com/zeromicro/go-zero v1.10.3/go.mod h1:Gnac2bT/JGb9Ja79wchssVeYtJxuWWzL98DuLH11kds= +go.etcd.io/etcd/api/v3 v3.5.21 h1:A6O2/JDb3tvHhiIz3xf9nJ7REHvtEFJJ3veW3FbCnS8= +go.etcd.io/etcd/api/v3 v3.5.21/go.mod h1:c3aH5wcvXv/9dqIw2Y810LDXJfhSYdHQ0vxmP3CCHVY= +go.etcd.io/etcd/client/pkg/v3 v3.5.21 h1:lPBu71Y7osQmzlflM9OfeIV2JlmpBjqBNlLtcoBqUTc= +go.etcd.io/etcd/client/pkg/v3 v3.5.21/go.mod h1:BgqT/IXPjK9NkeSDjbzwsHySX3yIle2+ndz28nVsjUs= +go.etcd.io/etcd/client/v3 v3.5.21 h1:T6b1Ow6fNjOLOtM0xSoKNQt1ASPCLWrF9XMHcH9pEyY= +go.etcd.io/etcd/client/v3 v3.5.21/go.mod h1:mFYy67IOqmbRf/kRUvsHixzo3iG+1OF2W2+jVIQRAnU= +go.mongodb.org/mongo-driver/v2 v2.8.0 h1:CxWDGQYY8QQwNjAl/aq2sfWakdnWZynnqJ9F4DhHbP8= +go.mongodb.org/mongo-driver/v2 v2.8.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 h1:MzfofMZN8ulNqobCmCAVbqVL5syHw+eB2qPRkCMA/fQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0/go.mod h1:E73G9UFtKRXrxhBsHtG00TB5WxX57lpsQzogDkqBTz8= +go.opentelemetry.io/otel/exporters/zipkin v1.40.0 h1:zu+I4j+FdO6xIxBVPeuncQVbjxUM4LiMgv6GwGe9REE= +go.opentelemetry.io/otel/exporters/zipkin v1.40.0/go.mod h1:zS6cC4nFBYXbu18e7aLfMzubBjOiN7ZcROu477qtMf8= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI= +golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= +golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/image v0.38.0 h1:5l+q+Y9JDC7mBOMjo4/aPhMDcxEptsX+Tt3GgRQRPuE= +golang.org/x/image v0.38.0/go.mod h1:/3f6vaXC+6CEanU4KJxbcUZyEePbyKbaLoDOe4ehFYY= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= +golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= +golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= +google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ= +google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc= +google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= +gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= +gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= +gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs= +gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/plugin/dbresolver v1.6.0 h1:XvKDeOtTn1EIX6s4SrKpEH82q0gXVemhYjbYZFGFVcw= +gorm.io/plugin/dbresolver v1.6.0/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM= +k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/user/internal/config/config.go b/user/internal/config/config.go new file mode 100644 index 0000000..a1979dd --- /dev/null +++ b/user/internal/config/config.go @@ -0,0 +1,13 @@ +package config + +type Config struct { + 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/user/internal/dao/user.go b/user/internal/dao/user.go new file mode 100644 index 0000000..52842a2 --- /dev/null +++ b/user/internal/dao/user.go @@ -0,0 +1,81 @@ +package dao + +import "pkg.local/utils" + +type UserCreate struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Openid string `gorm:"column:openid" json:"openid"` + Username string `gorm:"column:username" json:"username"` + Nickname string `gorm:"column:nickname" json:"nickname"` + Avatar string `gorm:"column:avatar" json:"avatar"` + Mobile string `gorm:"column:mobile" json:"mobile"` + Gender uint8 `gorm:"column:gender" json:"gender"` + Birthday string `gorm:"column:birthday" json:"birthday"` + AppId uint32 `gorm:"column:app_id" json:"app_id"` + Status uint8 `gorm:"column:status" json:"status"` + IsRegistered uint8 `gorm:"column:is_registered" json:"is_registered"` + IsFaceVerified uint8 `gorm:"column:is_face_verified" json:"is_face_verified"` + IsProfileCompleted uint8 `gorm:"column:is_profile_completed" json:"is_profile_completed"` + OnTrialNum int `gorm:"column:on_trial_num" json:"on_trial_num"` +} + +type UserCreateByPwd struct { + Id int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` + Type uint8 `gorm:"column:type" json:"type"` + Account string `gorm:"column:account" json:"account"` + Password string `gorm:"column:password" json:"password"` + Salt string `gorm:"column:salt" json:"salt"` + Mobile string `gorm:"column:mobile" json:"mobile"` + AppId uint32 `gorm:"column:app_id" json:"app_id"` + Status uint8 `gorm:"column:status" json:"status"` + IsRegistered uint8 `gorm:"column:is_registered" json:"is_registered"` + IsFaceVerified uint8 `gorm:"column:is_face_verified" json:"is_face_verified"` + IsProfileCompleted uint8 `gorm:"column:is_profile_completed" json:"is_profile_completed"` + OnTrialNum int `gorm:"column:on_trial_num" json:"on_trial_num"` +} + +type UserExist struct { + Id int64 `gorm:"column:id" json:"id"` +} + +type UserInfo struct { + Id int64 `gorm:"column:id" json:"id"` + Openid string `gorm:"column:openid" json:"openid"` + Username string `gorm:"column:username" json:"username"` + Nickname string `gorm:"column:nickname" json:"nickname"` + Avatar string `gorm:"column:avatar" json:"avatar"` + Mobile string `gorm:"column:mobile" json:"mobile"` + Gender uint8 `gorm:"column:gender" json:"gender"` + Birthday string `gorm:"column:birthday" json:"birthday"` + Type uint8 `gorm:"column:type" json:"type"` + Account string `gorm:"column:account" json:"account"` + AppId uint32 `gorm:"column:app_id" json:"app_id"` + Status uint8 `gorm:"column:status" json:"status"` +} + +type UserLoginRow struct { + UserInfo + Salt string `gorm:"column:salt" json:"-"` + Password string `gorm:"column:password" json:"-"` +} + +type Token struct { + Token string `json:"token"` + Refresh string `json:"refresh"` + Info UserLoginSession `json:"info"` +} + +type UserLoginSession struct { + Id int64 `json:"id"` + Openid string `json:"openid"` + Username string `json:"username"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` + Mobile string `json:"mobile"` + Gender uint8 `json:"gender"` + Birthday string `json:"birthday"` + Type uint8 `json:"type"` + Account string `json:"account"` + AppId uint32 `json:"app_id"` + LastTime utils.CustomTime `json:"last_time"` +} diff --git a/user/internal/logic/loginLogic.go b/user/internal/logic/loginLogic.go new file mode 100644 index 0000000..0f928b0 --- /dev/null +++ b/user/internal/logic/loginLogic.go @@ -0,0 +1,62 @@ +package logic + +import ( + "context" + + "user/internal/dao" + "user/internal/model" + "user/internal/svc" + "user/user" + "user/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type LoginLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { + return &LoginLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *LoginLogic) Login(in *user.LoginReq) (*user.Response, error) { + var v validator.LoginValidator + if msg := validateService.ValidateFromProto(in, &v); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + var row dao.UserLoginRow + err := model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "openid": v.Openid, + "status": utils.StringStatusOk, + }, + }, &row) + if err != nil { + log.Errorf("login by openid: %v", err) + return failResponse(utils.Fail), nil + } + if row.Id < utils.NumberOne { + return failResponse(utils.ErrorNotFund), nil + } + + mobile := decryptMobile(row.Mobile) + session := toSession(row.UserInfo, mobile) + ret := buildToken(session) + if status := setLogin(ret.Token, ret.Refresh, session); status.Code != utils.Ok.Code { + return failResponse(status), nil + } + return okResponse(ret), nil +} diff --git a/user/internal/logic/registerByUserLogic.go b/user/internal/logic/registerByUserLogic.go new file mode 100644 index 0000000..d3bf55b --- /dev/null +++ b/user/internal/logic/registerByUserLogic.go @@ -0,0 +1,105 @@ +package logic + +import ( + "context" + "strconv" + + "user/internal/dao" + "user/internal/model" + "user/internal/svc" + "user/user" + "user/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/redis" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type RegisterByUserLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewRegisterByUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterByUserLogic { + return &RegisterByUserLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *RegisterByUserLogic) RegisterByUser(in *user.RegisterByUserReq) (*user.Response, error) { + var v validator.RegisterByUserValidator + if msg := validateService.ValidateFromProto(in, &v); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + codePrefix := utils.StringEmpty + if v.Type == utils.NumberTwo { + codePrefix = "1:" + } + + test := utils.GetConfigBool("sms.sms_test") + isTest := test && v.Code == utils.GetConfigString("sms.sms_test_code") + codeKey := utils.CodeKey + codePrefix + v.Account + code, err := redis.Client.Get(l.ctx, codeKey).Result() + if (err != nil || code != v.Code) && !isTest { + return outResponse(utils.ErrorMissingParams, "验证码错误"), nil + } + + var old dao.UserExist + err = model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{ + "account": v.Account, + "type": strconv.FormatUint(uint64(v.Type), utils.NumberTen), + }, + }, &old) + if err != nil { + log.Errorf("registerByUser check account: %v", err) + return failResponse(utils.Fail), nil + } + if old.Id > utils.NumberZero { + return failResponse(utils.ErrorDataIsExist), nil + } + + add := dao.UserCreateByPwd{ + Type: uint8(v.Type), + Account: v.Account, + Salt: utils.GetRandString(utils.NumberFive), + AppId: v.AppId, + Status: utils.NumberOne, + IsRegistered: utils.NumberOne, + IsFaceVerified: utils.NumberTwo, + IsProfileCompleted: utils.NumberTwo, + OnTrialNum: utils.NumberOne, + } + pwd := utils.GetSaltPassword(add.Salt, v.Pwd) + add.Password, err = utils.EncryptPassword(pwd) + if err != nil { + log.Errorf("registerByUser encrypt password: %v", err) + return failResponse(utils.Fail), nil + } + + if v.Type == utils.NumberOne { + encryptMobile, cErr := utils.Crypto{}.AESEncryptECB(v.Account) + if cErr != nil { + log.Errorf("registerByUser encrypt mobile: %v", cErr) + return failResponse(utils.ErrorEncryptAesError), nil + } + add.Mobile = encryptMobile + } + + err = model.UserModel{}.Init().CreateByPwd(&add) + if err != nil || add.Id < utils.NumberOne { + log.Errorf("registerByUser create: %v", err) + return failResponse(utils.Fail), nil + } + + redis.Client.Del(l.ctx, codeKey) + return okResponse(map[string]any{"id": add.Id}), nil +} diff --git a/user/internal/logic/registerLogic.go b/user/internal/logic/registerLogic.go new file mode 100644 index 0000000..36270c2 --- /dev/null +++ b/user/internal/logic/registerLogic.go @@ -0,0 +1,100 @@ +package logic + +import ( + "context" + + "user/internal/dao" + "user/internal/model" + "user/internal/svc" + "user/user" + "user/validator" + + "pkg.local/log" + "pkg.local/modelbase" + "pkg.local/utils" + validateService "pkg.local/validate" + + "github.com/zeromicro/go-zero/core/logx" +) + +type RegisterLogic struct { + ctx context.Context + svcCtx *svc.ServiceContext + logx.Logger +} + +func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic { + return &RegisterLogic{ + ctx: ctx, + svcCtx: svcCtx, + Logger: logx.WithContext(ctx), + } +} + +func (l *RegisterLogic) Register(in *user.RegisterReq) (*user.Response, error) { + var v validator.RegisterValidator + if msg := validateService.ValidateFromProto(in, &v); msg != utils.StringEmpty { + return outResponse(utils.ErrorParams, msg), nil + } + + openid := v.Openid + if openid == utils.StringEmpty { + openid = "mock_" + utils.MD5Encrypt(v.Mobile+utils.Now().String()) + } + + var exist dao.UserExist + err := model.UserModel{}.Init().GetOne(modelbase.Params{ + Eq: map[string]string{"openid": openid}, + }, &exist) + if err != nil { + log.Errorf("register check openid: %v", err) + return failResponse(utils.Fail), nil + } + if exist.Id > utils.NumberZero { + return failResponse(utils.ErrorExist), nil + } + + encryptMobile, cErr := utils.Crypto{}.AESEncryptECB(v.Mobile) + if cErr != nil { + log.Errorf("register encrypt mobile: %v", cErr) + return failResponse(utils.ErrorEncryptAesError), nil + } + + add := dao.UserCreate{ + Openid: openid, + Username: v.Username, + Nickname: v.Nickname, + Avatar: v.Avatar, + Mobile: encryptMobile, + Gender: uint8(v.Gender), + Birthday: v.Birthday, + AppId: v.AppId, + Status: utils.NumberOne, + IsRegistered: utils.NumberOne, + IsFaceVerified: utils.NumberTwo, + IsProfileCompleted: utils.NumberTwo, + OnTrialNum: utils.NumberOne, + } + err = model.UserModel{}.Init().Create(&add) + if err != nil { + log.Errorf("register create: %v", err) + return failResponse(utils.Fail), nil + } + + session := toSession(dao.UserInfo{ + Id: add.Id, + Openid: add.Openid, + Username: add.Username, + Nickname: add.Nickname, + Avatar: add.Avatar, + Gender: add.Gender, + Birthday: add.Birthday, + AppId: add.AppId, + Status: add.Status, + }, v.Mobile) + ret := buildToken(session) + if status := setLogin(ret.Token, ret.Refresh, session); status.Code != utils.Ok.Code { + return failResponse(status), nil + } + return okResponse(ret), nil +} diff --git a/user/internal/logic/response.go b/user/internal/logic/response.go new file mode 100644 index 0000000..547ebca --- /dev/null +++ b/user/internal/logic/response.go @@ -0,0 +1,116 @@ +package logic + +import ( + "context" + "encoding/json" + "strconv" + "time" + + "user/internal/dao" + "user/user" + + jsoniter "github.com/json-iterator/go" + "pkg.local/redis" + "pkg.local/utils" +) + +func okResponse(data any) *user.Response { + buf, _ := json.Marshal(data) + return &user.Response{ + Code: utils.Ok.Code, + Msg: utils.Ok.Msg, + Data: string(buf), + } +} + +func failResponse(status utils.Status) *user.Response { + return &user.Response{ + Code: status.Code, + Msg: status.Msg, + } +} + +func outResponse(status utils.Status, msg string) *user.Response { + return &user.Response{ + Code: status.Code, + Msg: msg, + } +} + +func decryptMobile(mobile string) string { + if mobile == utils.StringEmpty { + return utils.StringEmpty + } + plain, err := utils.Crypto{}.AESDecryptECB(mobile) + if err != nil { + return utils.StringEmpty + } + return plain +} + +func toSession(info dao.UserInfo, mobilePlain string) dao.UserLoginSession { + return dao.UserLoginSession{ + Id: info.Id, + Openid: info.Openid, + Username: info.Username, + Nickname: info.Nickname, + Avatar: info.Avatar, + Mobile: mobilePlain, + Gender: info.Gender, + Birthday: info.Birthday, + Type: info.Type, + Account: info.Account, + AppId: info.AppId, + LastTime: utils.Now(), + } +} + +func buildToken(session dao.UserLoginSession) dao.Token { + seed := session.Mobile + session.Openid + utils.Now().String() + token := utils.MD5Encrypt(seed) + return dao.Token{ + Token: token, + Refresh: utils.MD5Encrypt(seed + token), + Info: session, + } +} + +func setLogin(token, refresh string, session dao.UserLoginSession) utils.Status { + expireMin := utils.GetConfigInt("base.login_out_time") + expire := time.Duration(expireMin) * time.Minute + refreshMin := utils.GetConfigInt("base.login_refresh_out_time") + refreshExpire := time.Duration(refreshMin) * time.Minute + + ctx := context.Background() + userStr, _ := jsoniter.Marshal(session) + + redisKey := utils.GetLoginKey(utils.LoginTypeUser, token) + if err := redis.Client.Set(ctx, redisKey, userStr, expire).Err(); err != nil { + return utils.Fail + } + + redisKeysKey := utils.GetLoginKeysKey(utils.LoginTypeUser, strconv.FormatInt(session.Id, utils.NumberTen)) + var loginInfo utils.LoginRedis + if oldAuth, err := redis.Client.Get(ctx, redisKeysKey).Result(); err == nil { + _ = jsoniter.Unmarshal([]byte(oldAuth), &loginInfo) + if len(loginInfo.Token) > utils.NumberOne { + redis.Client.Del(ctx, utils.GetLoginKey(utils.LoginTypeUser, loginInfo.Token)) + } + if len(loginInfo.Refresh) > utils.NumberOne { + redis.Client.Del(ctx, utils.GetLoginRefreshKey(utils.LoginTypeUser, loginInfo.Refresh)) + } + } + + loginInfo.Token = token + loginInfo.Refresh = refresh + loginInfo.Info = userStr + newStr, _ := jsoniter.Marshal(loginInfo) + if err := redis.Client.Set(ctx, redisKeysKey, newStr, refreshExpire).Err(); err != nil { + return utils.Fail + } + refreshKey := utils.GetLoginRefreshKey(utils.LoginTypeUser, refresh) + if err := redis.Client.Set(ctx, refreshKey, strconv.FormatInt(session.Id, utils.NumberTen), refreshExpire).Err(); err != nil { + return utils.Fail + } + return utils.Ok +} diff --git a/user/internal/model/user.go b/user/internal/model/user.go new file mode 100644 index 0000000..32c7d42 --- /dev/null +++ b/user/internal/model/user.go @@ -0,0 +1,28 @@ +package model + +import ( + "user/internal/dao" + + "pkg.local/modelbase" +) + +type UserModel struct { + modelbase.Base +} + +func (m UserModel) TableName() string { + return modelbase.Prefix() + "users" +} + +func (m UserModel) Init() UserModel { + m.Table = m.TableName() + return m +} + +func (m UserModel) Create(data *dao.UserCreate) error { + return m.Base.Create(data) +} + +func (m UserModel) CreateByPwd(data *dao.UserCreateByPwd) error { + return m.Base.Create(data) +} diff --git a/user/internal/server/userserver.go b/user/internal/server/userserver.go new file mode 100644 index 0000000..4adcb90 --- /dev/null +++ b/user/internal/server/userserver.go @@ -0,0 +1,39 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: user.proto + +package server + +import ( + "context" + + "user/internal/logic" + "user/internal/svc" + "user/user" +) + +type UserServer struct { + svcCtx *svc.ServiceContext + user.UnimplementedUserServer +} + +func NewUserServer(svcCtx *svc.ServiceContext) *UserServer { + return &UserServer{ + svcCtx: svcCtx, + } +} + +func (s *UserServer) Register(ctx context.Context, in *user.RegisterReq) (*user.Response, error) { + l := logic.NewRegisterLogic(ctx, s.svcCtx) + return l.Register(in) +} + +func (s *UserServer) RegisterByUser(ctx context.Context, in *user.RegisterByUserReq) (*user.Response, error) { + l := logic.NewRegisterByUserLogic(ctx, s.svcCtx) + return l.RegisterByUser(in) +} + +func (s *UserServer) Login(ctx context.Context, in *user.LoginReq) (*user.Response, error) { + l := logic.NewLoginLogic(ctx, s.svcCtx) + return l.Login(in) +} diff --git a/user/internal/svc/servicecontext.go b/user/internal/svc/servicecontext.go new file mode 100644 index 0000000..d624003 --- /dev/null +++ b/user/internal/svc/servicecontext.go @@ -0,0 +1,22 @@ +package svc + +import ( + "user/internal/config" + + "gorm.io/gorm" + "pkg.local/utils" +) + +type ServiceContext struct { + Config config.Config + DB *gorm.DB + Prefix string +} + +func NewServiceContext(c config.Config, db *gorm.DB) *ServiceContext { + return &ServiceContext{ + Config: c, + DB: db, + Prefix: utils.GetConfigString("mysql.prefix"), + } +} diff --git a/user/proto/user.proto b/user/proto/user.proto new file mode 100644 index 0000000..8e50fb5 --- /dev/null +++ b/user/proto/user.proto @@ -0,0 +1,59 @@ +syntax = "proto3"; + +package user; +option go_package="./user"; + +import "google/api/annotations.proto"; + +message Response { + int32 code = 1; + string msg = 2; + string data = 3; +} + +// 小程序注册 +message RegisterReq { + string openid = 1; // 可空;空则服务端模拟 + string nickname = 2; + string avatar = 3; + string mobile = 4; + uint32 gender = 5; // 1男 2女 + string birthday = 6; + string username = 7; + uint32 app_id = 8; // 应用标识 +} + +// 账号密码注册 +message RegisterByUserReq { + uint32 type = 1; // 1手机号 2邮箱 + string account = 2; + string pwd = 3; + string code = 4; + uint32 app_id = 5; // 应用标识 +} + +// openid 登录 +message LoginReq { + string openid = 1; +} + +service User { + rpc Register(RegisterReq) returns (Response) { + option (google.api.http) = { + post: "/customer/v3/register" + body: "*" + }; + } + rpc RegisterByUser(RegisterByUserReq) returns (Response) { + option (google.api.http) = { + post: "/customer/v3/register/user" + body: "*" + }; + } + rpc Login(LoginReq) returns (Response) { + option (google.api.http) = { + post: "/customer/v3/login" + body: "*" + }; + } +} diff --git a/user/user.go b/user/user.go new file mode 100644 index 0000000..366e08f --- /dev/null +++ b/user/user.go @@ -0,0 +1,153 @@ +package main + +import ( + "flag" + "net" + "os" + "strconv" + + "user/internal/config" + "user/internal/server" + "user/internal/svc" + "user/user" + + "github.com/zeromicro/go-zero/core/conf" + "github.com/zeromicro/go-zero/core/logx" + "github.com/zeromicro/go-zero/core/service" + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + + "pkg.local/discovery" + "pkg.local/modelbase" + "pkg.local/mysql" + "pkg.local/redis" + "pkg.local/utils" + "pkg.local/validate" +) + +var configFile = flag.String("f", "etc/user.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") + mode := utils.GetConfigString("base.mode") + 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) + } + + port, err := listenPort(listenOn) + if err != nil { + logx.Errorf("parse ListenOn: %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) + } + logx.Infof("服务注册成功: %s:%d", c.Nacos.RegisterIP, port) + + defer func() { + if err := discovery.Deregister(); err != nil { + logx.Errorf("nacos deregister: %v", err) + } + }() + + db, err := mysql.New(mysql.Config{ + Host: utils.GetConfigString("mysql.host"), + Port: utils.GetConfigInt("mysql.port"), + User: utils.GetConfigString("mysql.user"), + Password: utils.GetConfigString("mysql.password"), + Database: utils.GetConfigString("mysql.database"), + Charset: utils.GetConfigString("mysql.charset"), + Prefix: utils.GetConfigString("mysql.prefix"), + ReadHost: utils.GetConfigString("mysql_read.host"), + ReadPort: utils.GetConfigInt("mysql_read.port"), + ReadUser: utils.GetConfigString("mysql_read.user"), + ReadPassword: utils.GetConfigString("mysql_read.password"), + ReadDatabase: utils.GetConfigString("mysql_read.database"), + }) + if err != nil { + logx.Errorf("mysql init: %v", err) + os.Exit(1) + } + + 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) + } + + debug := utils.GetConfigBool("mysql.debug") + modelbase.Init(db, modelbase.Config{Prefix: utils.GetConfigString("mysql.prefix"), Debug: debug}) + + rpcConf := zrpc.RpcServerConf{ + ListenOn: listenOn, + } + rpcConf.Mode = mode + + ctx := svc.NewServiceContext(c, db) + + s := zrpc.MustNewServer(rpcConf, func(grpcServer *grpc.Server) { + user.RegisterUserServer(grpcServer, server.NewUserServer(ctx)) + if mode == service.DevMode || mode == service.TestMode { + reflection.Register(grpcServer) + } + }) + defer s.Stop() + + s.AddUnaryInterceptors(validate.UnaryServerInterceptor(validate.MustNew())) + + logx.Infof("Starting rpc server at %s...", listenOn) + s.Start() +} + +func listenPort(listenOn string) (uint64, error) { + _, portStr, err := net.SplitHostPort(listenOn) + if err != nil { + return 0, err + } + return strconv.ParseUint(portStr, 10, 64) +} diff --git a/user/user/user.pb.go b/user/user/user.pb.go new file mode 100644 index 0000000..c438df9 --- /dev/null +++ b/user/user/user.pb.go @@ -0,0 +1,394 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v3.19.4 +// source: proto/user.proto + +package user + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Response struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Response) Reset() { + *x = Response{} + mi := &file_proto_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Response) ProtoMessage() {} + +func (x *Response) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Response.ProtoReflect.Descriptor instead. +func (*Response) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{0} +} + +func (x *Response) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Response) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +func (x *Response) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +// 小程序注册(openid),对齐 sales-service user/small/v1/add +type RegisterReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Openid string `protobuf:"bytes,1,opt,name=openid,proto3" json:"openid,omitempty"` // 可空;空则服务端模拟 openid(暂不对接微信) + Nickname string `protobuf:"bytes,2,opt,name=nickname,proto3" json:"nickname,omitempty"` + Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` + Mobile string `protobuf:"bytes,4,opt,name=mobile,proto3" json:"mobile,omitempty"` + Gender uint32 `protobuf:"varint,5,opt,name=gender,proto3" json:"gender,omitempty"` // 1男 2女 + Birthday string `protobuf:"bytes,6,opt,name=birthday,proto3" json:"birthday,omitempty"` + Username string `protobuf:"bytes,7,opt,name=username,proto3" json:"username,omitempty"` + AppId uint32 `protobuf:"varint,8,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` // 应用标识(数字) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterReq) Reset() { + *x = RegisterReq{} + mi := &file_proto_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterReq) ProtoMessage() {} + +func (x *RegisterReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterReq.ProtoReflect.Descriptor instead. +func (*RegisterReq) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{1} +} + +func (x *RegisterReq) GetOpenid() string { + if x != nil { + return x.Openid + } + return "" +} + +func (x *RegisterReq) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +func (x *RegisterReq) GetAvatar() string { + if x != nil { + return x.Avatar + } + return "" +} + +func (x *RegisterReq) GetMobile() string { + if x != nil { + return x.Mobile + } + return "" +} + +func (x *RegisterReq) GetGender() uint32 { + if x != nil { + return x.Gender + } + return 0 +} + +func (x *RegisterReq) GetBirthday() string { + if x != nil { + return x.Birthday + } + return "" +} + +func (x *RegisterReq) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *RegisterReq) GetAppId() uint32 { + if x != nil { + return x.AppId + } + return 0 +} + +// 账号密码注册,对齐 go-sale-admin-api RegisterByUser +type RegisterByUserReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type uint32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"` // 1手机号 2邮箱 + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Pwd string `protobuf:"bytes,3,opt,name=pwd,proto3" json:"pwd,omitempty"` + Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` // 验证码 + AppId uint32 `protobuf:"varint,5,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` // 应用标识(数字) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterByUserReq) Reset() { + *x = RegisterByUserReq{} + mi := &file_proto_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterByUserReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterByUserReq) ProtoMessage() {} + +func (x *RegisterByUserReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterByUserReq.ProtoReflect.Descriptor instead. +func (*RegisterByUserReq) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{2} +} + +func (x *RegisterByUserReq) GetType() uint32 { + if x != nil { + return x.Type + } + return 0 +} + +func (x *RegisterByUserReq) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *RegisterByUserReq) GetPwd() string { + if x != nil { + return x.Pwd + } + return "" +} + +func (x *RegisterByUserReq) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *RegisterByUserReq) GetAppId() uint32 { + if x != nil { + return x.AppId + } + return 0 +} + +// openid 登录,对齐 LoginByOpenid +type LoginReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + Openid string `protobuf:"bytes,1,opt,name=openid,proto3" json:"openid,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LoginReq) Reset() { + *x = LoginReq{} + mi := &file_proto_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LoginReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LoginReq) ProtoMessage() {} + +func (x *LoginReq) ProtoReflect() protoreflect.Message { + mi := &file_proto_user_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LoginReq.ProtoReflect.Descriptor instead. +func (*LoginReq) Descriptor() ([]byte, []int) { + return file_proto_user_proto_rawDescGZIP(), []int{3} +} + +func (x *LoginReq) GetOpenid() string { + if x != nil { + return x.Openid + } + return "" +} + +var File_proto_user_proto protoreflect.FileDescriptor + +const file_proto_user_proto_rawDesc = "" + + "\n" + + "\x10proto/user.proto\x12\x04user\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\x04data\"\xd8\x01\n" + + "\vRegisterReq\x12\x16\n" + + "\x06openid\x18\x01 \x01(\tR\x06openid\x12\x1a\n" + + "\bnickname\x18\x02 \x01(\tR\bnickname\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12\x16\n" + + "\x06mobile\x18\x04 \x01(\tR\x06mobile\x12\x16\n" + + "\x06gender\x18\x05 \x01(\rR\x06gender\x12\x1a\n" + + "\bbirthday\x18\x06 \x01(\tR\bbirthday\x12\x1a\n" + + "\busername\x18\a \x01(\tR\busername\x12\x15\n" + + "\x06app_id\x18\b \x01(\rR\x05appId\"~\n" + + "\x11RegisterByUserReq\x12\x12\n" + + "\x04type\x18\x01 \x01(\rR\x04type\x12\x18\n" + + "\aaccount\x18\x02 \x01(\tR\aaccount\x12\x10\n" + + "\x03pwd\x18\x03 \x01(\tR\x03pwd\x12\x12\n" + + "\x04code\x18\x04 \x01(\tR\x04code\x12\x15\n" + + "\x06app_id\x18\x05 \x01(\rR\x05appId\"\"\n" + + "\bLoginReq\x12\x16\n" + + "\x06openid\x18\x01 \x01(\tR\x06openid2\x81\x02\n" + + "\x04User\x12O\n" + + "\bRegister\x12\x11.user.RegisterReq\x1a\x0e.user.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/customer/v3/register\x12`\n" + + "\x0eRegisterByUser\x12\x17.user.RegisterByUserReq\x1a\x0e.user.Response\"%\x82\xd3\xe4\x93\x02\x1f:\x01*\"\x1a/customer/v3/register/user\x12F\n" + + "\x05Login\x12\x0e.user.LoginReq\x1a\x0e.user.Response\"\x1d\x82\xd3\xe4\x93\x02\x17:\x01*\"\x12/customer/v3/loginB\bZ\x06./userb\x06proto3" + +var ( + file_proto_user_proto_rawDescOnce sync.Once + file_proto_user_proto_rawDescData []byte +) + +func file_proto_user_proto_rawDescGZIP() []byte { + file_proto_user_proto_rawDescOnce.Do(func() { + file_proto_user_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_user_proto_rawDesc), len(file_proto_user_proto_rawDesc))) + }) + return file_proto_user_proto_rawDescData +} + +var file_proto_user_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_proto_user_proto_goTypes = []any{ + (*Response)(nil), // 0: user.Response + (*RegisterReq)(nil), // 1: user.RegisterReq + (*RegisterByUserReq)(nil), // 2: user.RegisterByUserReq + (*LoginReq)(nil), // 3: user.LoginReq +} +var file_proto_user_proto_depIdxs = []int32{ + 1, // 0: user.User.Register:input_type -> user.RegisterReq + 2, // 1: user.User.RegisterByUser:input_type -> user.RegisterByUserReq + 3, // 2: user.User.Login:input_type -> user.LoginReq + 0, // 3: user.User.Register:output_type -> user.Response + 0, // 4: user.User.RegisterByUser:output_type -> user.Response + 0, // 5: user.User.Login:output_type -> user.Response + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_user_proto_init() } +func file_proto_user_proto_init() { + if File_proto_user_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_user_proto_rawDesc), len(file_proto_user_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_user_proto_goTypes, + DependencyIndexes: file_proto_user_proto_depIdxs, + MessageInfos: file_proto_user_proto_msgTypes, + }.Build() + File_proto_user_proto = out.File + file_proto_user_proto_goTypes = nil + file_proto_user_proto_depIdxs = nil +} diff --git a/user/user/user_grpc.pb.go b/user/user/user_grpc.pb.go new file mode 100644 index 0000000..6fa4817 --- /dev/null +++ b/user/user/user_grpc.pb.go @@ -0,0 +1,197 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.2 +// - protoc v3.19.4 +// source: proto/user.proto + +package user + +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 ( + User_Register_FullMethodName = "/user.User/Register" + User_RegisterByUser_FullMethodName = "/user.User/RegisterByUser" + User_Login_FullMethodName = "/user.User/Login" +) + +// UserClient is the client API for User service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type UserClient interface { + Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) + RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) + Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) +} + +type userClient struct { + cc grpc.ClientConnInterface +} + +func NewUserClient(cc grpc.ClientConnInterface) UserClient { + return &userClient{cc} +} + +func (c *userClient) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_Register_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userClient) RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_RegisterByUser_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userClient) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(Response) + err := c.cc.Invoke(ctx, User_Login_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 { + Register(context.Context, *RegisterReq) (*Response, error) + RegisterByUser(context.Context, *RegisterByUserReq) (*Response, error) + Login(context.Context, *LoginReq) (*Response, error) + mustEmbedUnimplementedUserServer() +} + +// UnimplementedUserServer 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 UnimplementedUserServer struct{} + +func (UnimplementedUserServer) Register(context.Context, *RegisterReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Register not implemented") +} +func (UnimplementedUserServer) RegisterByUser(context.Context, *RegisterByUserReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method RegisterByUser not implemented") +} +func (UnimplementedUserServer) Login(context.Context, *LoginReq) (*Response, error) { + return nil, status.Error(codes.Unimplemented, "method Login not implemented") +} +func (UnimplementedUserServer) mustEmbedUnimplementedUserServer() {} +func (UnimplementedUserServer) testEmbeddedByValue() {} + +// UnsafeUserServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServer will +// result in compilation errors. +type UnsafeUserServer interface { + mustEmbedUnimplementedUserServer() +} + +func RegisterUserServer(s grpc.ServiceRegistrar, srv UserServer) { + // If the following call panics, it indicates UnimplementedUserServer 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(&User_ServiceDesc, srv) +} + +func _User_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).Register(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_Register_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).Register(ctx, req.(*RegisterReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _User_RegisterByUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterByUserReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).RegisterByUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_RegisterByUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).RegisterByUser(ctx, req.(*RegisterByUserReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _User_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoginReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServer).Login(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: User_Login_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServer).Login(ctx, req.(*LoginReq)) + } + return interceptor(ctx, in, info, handler) +} + +// 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) +var User_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "user.User", + HandlerType: (*UserServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Register", + Handler: _User_Register_Handler, + }, + { + MethodName: "RegisterByUser", + Handler: _User_RegisterByUser_Handler, + }, + { + MethodName: "Login", + Handler: _User_Login_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "proto/user.proto", +} diff --git a/user/userclient/user.go b/user/userclient/user.go new file mode 100644 index 0000000..e732e95 --- /dev/null +++ b/user/userclient/user.go @@ -0,0 +1,52 @@ +// Code generated by goctl. DO NOT EDIT. +// goctl 1.10.1 +// Source: user.proto + +package userClient + +import ( + "context" + + "user/user" + + "github.com/zeromicro/go-zero/zrpc" + "google.golang.org/grpc" +) + +type ( + LoginReq = user.LoginReq + RegisterByUserReq = user.RegisterByUserReq + RegisterReq = user.RegisterReq + Response = user.Response + + User interface { + Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) + RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) + Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) + } + + defaultUser struct { + cli zrpc.Client + } +) + +func NewUser(cli zrpc.Client) User { + return &defaultUser{ + cli: cli, + } +} + +func (m *defaultUser) Register(ctx context.Context, in *RegisterReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.Register(ctx, in, opts...) +} + +func (m *defaultUser) RegisterByUser(ctx context.Context, in *RegisterByUserReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.RegisterByUser(ctx, in, opts...) +} + +func (m *defaultUser) Login(ctx context.Context, in *LoginReq, opts ...grpc.CallOption) (*Response, error) { + client := user.NewUserClient(m.cli.Conn()) + return client.Login(ctx, in, opts...) +} diff --git a/user/validator/user.go b/user/validator/user.go new file mode 100644 index 0000000..7323109 --- /dev/null +++ b/user/validator/user.go @@ -0,0 +1,56 @@ +package validator + +import "pkg.local/validate" + +type RegisterValidator struct { + Openid string + Nickname string `validate:"required"` + Avatar string `validate:"required"` + Mobile string `validate:"required"` + Gender uint32 `validate:"required,oneof=1 2"` + Birthday string `validate:"required"` + Username string `validate:"required"` + AppId uint32 `validate:"required"` +} + +func (p RegisterValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Nickname.required": "昵称不能为空", + "Avatar.required": "头像不能为空", + "Mobile.required": "手机号不能为空", + "Gender.required": "性别不能为空", + "Gender.oneof": "性别传值不对", + "Birthday.required": "生日不能为空", + "Username.required": "姓名不能为空", + "AppId.required": "应用标识不能为空", + } +} + +type RegisterByUserValidator struct { + Type uint32 `validate:"required,oneof=1 2"` + Account string `validate:"required"` + Pwd string `validate:"required"` + Code string `validate:"required"` + AppId uint32 `validate:"required"` +} + +func (p RegisterByUserValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Type.required": "类型不能为空", + "Type.oneof": "类型传值不对", + "Account.required": "账号不能为空", + "Pwd.required": "密码不能为空", + "Code.required": "验证码不能为空", + "AppId.required": "应用标识不能为空", + } +} + +type LoginValidator struct { + Openid string `validate:"required"` +} + +func (p LoginValidator) GetMessage() validate.ValidatorMessages { + return validate.ValidatorMessages{ + "Openid.required": "Openid不能为空", + } +}