From a1754ea4f1ef6f0999aac1cb75340e8db7ef2339 Mon Sep 17 00:00:00 2001 From: jettjia Date: Tue, 26 Sep 2023 14:02:39 +0800 Subject: [PATCH] init --- .gitignore | 13 + Makefile | 29 + README-DDD.md | 152 +++ README.md | 7 + common/README.md | 2 + common/go.mod | 62 ++ common/go.sum | 154 ++++ common/pkg/conf/conf.go | 85 ++ common/pkg/conf/config_st.go | 84 ++ common/pkg/data/data.go | 21 + common/pkg/data/transaction.go | 37 + common/pkg/database/db/mysql.go | 94 ++ common/pkg/database/db/plugin.go | 60 ++ common/pkg/event/.gitkeep | 0 common/pkg/httpclient/.gitkeep | 0 common/pkg/log/log_server.go | 115 +++ common/pkg/log/option.go | 39 + common/pkg/mongo/.gitkeep | 0 common/pkg/otel/.gitkeep | 0 common/pkg/redis/README.md | 13 + common/pkg/redis/redis.go | 77 ++ common/pkg/redis/redis_redsync.go | 117 +++ common/pkg/redis/redis_test.go | 141 +++ common/pkg/response/error_info.go | 87 ++ common/pkg/response/gcode.go | 39 + common/pkg/response/gerror_def.go | 34 + common/pkg/response/gresponse.go | 82 ++ common/pkg/util/ulid.go | 7 + common/pkg/util/util.go | 27 + common/pkg/validate/validate.go | 86 ++ common/pkg/validate/validate_test.go | 39 + common/types/gorm_plugin.go | 53 ++ common/types/page_data.go | 15 + common/types/sql_query.go | 56 ++ deploy/docker-compose/.gitkeep | 0 deploy/framework_tool/.gitkeep | 0 deploy/k8s/.gitkeep | 0 go.work | 6 + go.work.sum | 316 +++++++ system/.dockerignore | 17 + system/.gitignore | 17 + system/.golangci.yml | 118 +++ system/Dockerfile | 51 ++ system/Makefile | 70 ++ system/README.md | 2 + system/application/assembler/ps.go | 5 + system/application/assembler/sys_menu_req.go | 47 + system/application/assembler/sys_menu_rsp.go | 50 + system/application/dto/sys_menu_dto.go | 92 ++ system/application/service/ps.go | 5 + system/application/service/sys_menu_svc.go | 98 ++ system/cmd/server.go | 18 + system/cmd/wire.go | 31 + system/cmd/wire_gen.go | 41 + system/config/config.go | 45 + system/domain/aggregate/ps.go | 5 + system/domain/aggregate/sys_menu_agg.go | 86 ++ system/domain/entity/jwt.go | 108 +++ system/domain/entity/sys_log_entity.go | 8 + system/domain/entity/sys_menu_entity.go | 19 + system/domain/event/.gitkeep | 0 system/domain/irepository/i_sys_log_repo.go | 25 + system/domain/irepository/i_sys_menu_repo.go | 24 + system/domain/srv/ps.go | 5 + system/domain/srv/sys_log_svc.go | 76 ++ system/domain/srv/sys_menu_svc.go | 76 ++ system/go.mod | 50 + system/go.sum | 224 +++++ system/infra/consts/public_consts.go | 5 + .../repository/converter/sys_log_conv.go | 64 ++ .../repository/converter/sys_menu_conv.go | 66 ++ system/infra/repository/po/sys_log_po.go | 24 + system/infra/repository/po/sys_menu_po.go | 31 + system/infra/repository/repo/ps.go | 9 + system/infra/repository/repo/repo.go | 71 ++ system/infra/repository/repo/sys_log_impl.go | 146 +++ system/infra/repository/repo/sys_menu_impl.go | 148 +++ system/interface/event/event.go | 5 + system/interface/event/subscribe/.gitkeep | 0 system/interface/facade/.gitkeep | 0 system/interface/grpc/ghandler/base.go | 11 + .../grpc/ghandler/g_sys_menu_handler.go | 142 +++ system/interface/grpc/ginit/g_ainit.go | 12 + system/interface/grpc/ginit/g_grpc_client.go | 30 + .../grpc/ginit/g_init_grpc_server.go | 16 + system/interface/grpc/grpc.go | 46 + system/interface/grpc/middleware/auth.go | 36 + system/interface/grpc/middleware/recover.go | 21 + system/interface/grpc/proto/goods/auto.bat | 1 + .../interface/grpc/proto/goods/common.pb.go | 449 +++++++++ .../interface/grpc/proto/goods/common.proto | 33 + system/interface/grpc/proto/goods/goods.pb.go | 331 +++++++ system/interface/grpc/proto/goods/goods.proto | 14 + .../interface/grpc/proto/goods/sys_menu.pb.go | 862 ++++++++++++++++++ .../interface/grpc/proto/goods/sys_menu.proto | 66 ++ .../interface/http/handler/private/handler.go | 8 + .../http/handler/private/internal_handler.go | 14 + .../interface/http/handler/public/handler.go | 15 + .../http/handler/public/sys_menu_handler.go | 239 +++++ system/interface/http/http.go | 74 ++ system/interface/http/middleware/auth.go | 46 + system/interface/http/middleware/cors.go | 24 + system/interface/http/middleware/recover.go | 72 ++ .../http/router/private/internal_router.go | 14 + .../http/router/public/sys_menu_router.go | 18 + system/interface/http/router/router.go | 31 + system/interface/job/job.go | 4 + system/main.go | 56 ++ system/manifest/config/config-debug.yaml | 62 ++ system/manifest/config/config-release.yaml | 51 ++ system/manifest/config/config-test.yaml | 54 ++ system/manifest/i18n/en/error.toml | 6 + system/manifest/i18n/zh-CN/error.toml | 6 + system/manifest/i18n/zh-TW/error.toml | 6 + 114 files changed, 7001 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README-DDD.md create mode 100644 README.md create mode 100644 common/README.md create mode 100644 common/go.mod create mode 100644 common/go.sum create mode 100644 common/pkg/conf/conf.go create mode 100644 common/pkg/conf/config_st.go create mode 100644 common/pkg/data/data.go create mode 100644 common/pkg/data/transaction.go create mode 100644 common/pkg/database/db/mysql.go create mode 100644 common/pkg/database/db/plugin.go create mode 100644 common/pkg/event/.gitkeep create mode 100644 common/pkg/httpclient/.gitkeep create mode 100644 common/pkg/log/log_server.go create mode 100644 common/pkg/log/option.go create mode 100644 common/pkg/mongo/.gitkeep create mode 100644 common/pkg/otel/.gitkeep create mode 100644 common/pkg/redis/README.md create mode 100644 common/pkg/redis/redis.go create mode 100644 common/pkg/redis/redis_redsync.go create mode 100644 common/pkg/redis/redis_test.go create mode 100644 common/pkg/response/error_info.go create mode 100644 common/pkg/response/gcode.go create mode 100644 common/pkg/response/gerror_def.go create mode 100644 common/pkg/response/gresponse.go create mode 100644 common/pkg/util/ulid.go create mode 100644 common/pkg/util/util.go create mode 100644 common/pkg/validate/validate.go create mode 100644 common/pkg/validate/validate_test.go create mode 100644 common/types/gorm_plugin.go create mode 100644 common/types/page_data.go create mode 100644 common/types/sql_query.go create mode 100644 deploy/docker-compose/.gitkeep create mode 100644 deploy/framework_tool/.gitkeep create mode 100644 deploy/k8s/.gitkeep create mode 100644 go.work create mode 100644 go.work.sum create mode 100644 system/.dockerignore create mode 100644 system/.gitignore create mode 100644 system/.golangci.yml create mode 100644 system/Dockerfile create mode 100644 system/Makefile create mode 100644 system/README.md create mode 100644 system/application/assembler/ps.go create mode 100644 system/application/assembler/sys_menu_req.go create mode 100644 system/application/assembler/sys_menu_rsp.go create mode 100644 system/application/dto/sys_menu_dto.go create mode 100644 system/application/service/ps.go create mode 100644 system/application/service/sys_menu_svc.go create mode 100644 system/cmd/server.go create mode 100644 system/cmd/wire.go create mode 100644 system/cmd/wire_gen.go create mode 100644 system/config/config.go create mode 100644 system/domain/aggregate/ps.go create mode 100644 system/domain/aggregate/sys_menu_agg.go create mode 100644 system/domain/entity/jwt.go create mode 100644 system/domain/entity/sys_log_entity.go create mode 100644 system/domain/entity/sys_menu_entity.go create mode 100644 system/domain/event/.gitkeep create mode 100644 system/domain/irepository/i_sys_log_repo.go create mode 100644 system/domain/irepository/i_sys_menu_repo.go create mode 100644 system/domain/srv/ps.go create mode 100644 system/domain/srv/sys_log_svc.go create mode 100644 system/domain/srv/sys_menu_svc.go create mode 100644 system/go.mod create mode 100644 system/go.sum create mode 100644 system/infra/consts/public_consts.go create mode 100644 system/infra/repository/converter/sys_log_conv.go create mode 100644 system/infra/repository/converter/sys_menu_conv.go create mode 100644 system/infra/repository/po/sys_log_po.go create mode 100644 system/infra/repository/po/sys_menu_po.go create mode 100644 system/infra/repository/repo/ps.go create mode 100644 system/infra/repository/repo/repo.go create mode 100644 system/infra/repository/repo/sys_log_impl.go create mode 100644 system/infra/repository/repo/sys_menu_impl.go create mode 100644 system/interface/event/event.go create mode 100644 system/interface/event/subscribe/.gitkeep create mode 100644 system/interface/facade/.gitkeep create mode 100644 system/interface/grpc/ghandler/base.go create mode 100644 system/interface/grpc/ghandler/g_sys_menu_handler.go create mode 100644 system/interface/grpc/ginit/g_ainit.go create mode 100644 system/interface/grpc/ginit/g_grpc_client.go create mode 100644 system/interface/grpc/ginit/g_init_grpc_server.go create mode 100644 system/interface/grpc/grpc.go create mode 100644 system/interface/grpc/middleware/auth.go create mode 100644 system/interface/grpc/middleware/recover.go create mode 100644 system/interface/grpc/proto/goods/auto.bat create mode 100644 system/interface/grpc/proto/goods/common.pb.go create mode 100644 system/interface/grpc/proto/goods/common.proto create mode 100644 system/interface/grpc/proto/goods/goods.pb.go create mode 100644 system/interface/grpc/proto/goods/goods.proto create mode 100644 system/interface/grpc/proto/goods/sys_menu.pb.go create mode 100644 system/interface/grpc/proto/goods/sys_menu.proto create mode 100644 system/interface/http/handler/private/handler.go create mode 100644 system/interface/http/handler/private/internal_handler.go create mode 100644 system/interface/http/handler/public/handler.go create mode 100644 system/interface/http/handler/public/sys_menu_handler.go create mode 100644 system/interface/http/http.go create mode 100644 system/interface/http/middleware/auth.go create mode 100644 system/interface/http/middleware/cors.go create mode 100644 system/interface/http/middleware/recover.go create mode 100644 system/interface/http/router/private/internal_router.go create mode 100644 system/interface/http/router/public/sys_menu_router.go create mode 100644 system/interface/http/router/router.go create mode 100644 system/interface/job/job.go create mode 100644 system/main.go create mode 100644 system/manifest/config/config-debug.yaml create mode 100644 system/manifest/config/config-release.yaml create mode 100644 system/manifest/config/config-test.yaml create mode 100644 system/manifest/i18n/en/error.toml create mode 100644 system/manifest/i18n/zh-CN/error.toml create mode 100644 system/manifest/i18n/zh-TW/error.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10130b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +.buildpath +.hgignore.swp +.project +.orig +.swp +.idea/ +.settings/ +.vscode/ +vender/ +gitpush.sh +bin/ +cbuild +*/.DS_Store \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..eff91c6 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +# helm +## helm地址 +HELM_TEMP_DIR := "manifest/framework_tool/k8s/temp_helm" # 进入helm地址 +HELM_IMAGE := "go-ddd-demo.tgz" +HELM_DIR := "go-ddd-demo" +HELM_IMAGE_REPO := "go-ddd-demo-helm" # helm远程仓库地址 + +.PHONY: init-helm +init-helm: ## 安装helm环境 + @cd /tmp && wget https://get.helm.sh/helm-v3.8.2-linux-amd64.tar.gz \ + && tar -zxvf helm-v3.8.2-linux-amd64.tar.gz \ + && cp linux-amd64/helm /usr/local/bin \ + && helm version + +.PHONY: install-rds +install-rds: ## 安装项目依赖的db + @docker-compose -f deploy/framework_tool/mysql/docker-compose.yaml up -d + +.PHONY: uninstall-rds +uninstall-rds: ## 卸载项目依赖的db + @docker-compose -f deploy/framework_tool/mysql/docker-compose.yaml down + +.PHONY: install-otel +install-otel: ## 安装项目的可观测性 + @docker-compose -f deploy/framework_tool/otel-jaeger/docker-compose.yaml up -d + +.PHONY: uninstall-otel +uninstall-otel: ## 协助项目的可观测性 + @docker-compose -f deploy/framework_tool/otel-jaeger/docker-compose.yaml down \ No newline at end of file diff --git a/README-DDD.md b/README-DDD.md new file mode 100644 index 0000000..c2dd36b --- /dev/null +++ b/README-DDD.md @@ -0,0 +1,152 @@ +# DDD 项目 + +## 层级说明 +```base +├── interfaces 接入层 【http/grpc适配, 这一层调用application层; 比如interfaces层定义了输入层的相关方法,以使用gin提供http接口为例,这里的handler等为使用gin提供的一些http接口,这一层调用application层】 +│ ├── grpc +│ └── http +│ └── facade 引用其他微服务(接口防腐层) +│ ├── event 事件 +│ │ └── subscribe mq消费入口 +│ ├── job 定时任务 +├── application 应用层 【主要是调用domain层与infrastructure层来实现功能】 +│ ├── assembler 负责将内部领域模型转化为可对外的DTO +│ └── dto Application层的所有接口返回值为DTO -- 入参/出参 +│ └── service 负责业务流程的编排,但本身不负责任何业务逻辑 +├── domain 领域层 【主要是定义了entity,以及repository接口;entity里头会包含一些领域逻辑,Domain模块仅依赖Types模块】 +│ ├── aggregate 聚合 【对于需要两个repo一起操作的,可以进行聚合,比如创建用户的时候有userRepo,还有日志的userLogRepo】 +│ ├── entity 实体 业务逻辑。也可以参数校验,扩展一些简单方法,减轻service的压力 +│ ├── event 事件 +│ │ ├── publish 所有发送mq在此处理 +│ │ └── subscribe 所有接受到mq处理逻辑在此处理 +│ ├── irepository 接口 +│ ├── srv 领域服务 【单一操作,比如查看用户信息。没有聚合的操作的时候,在此实现】 +└── infrastructure 基础设施层 【这里提供了针对domain层的repository接口的实现,还有其他一些基础的组件,提供给application层或者interfaces层使用】 +│ ├── config 配置文件 +│ ├── consts 系统常量 +│ ├── pkg 常用工具类封装(DB,log,util等) +│ └── repository 针对domain层的repository接口的实现 +│ │ └── converter domain内对象转化 po {互转} +│ │ └── repo 针对domain层的repository接口的具体实现 +│ │ └── po 数据库映射对象 +└── types 完全独立的模块(DP),封装自定义的参数类型,例如 phone 相关的类型,校验合法、区号等。 +``` + +## DDD小结 +DDD一般分为interfaces、application、domain、infrastructure这几层; + +其中domain层不依赖其他层,它定义repository接口,infrastructure层会实现; + +application层会调用domain、infrastructure层; + +interfaces层一般调用application层或者infrastructure层。 + + +## 相关概念 + +- DDD等相关概念:https://domain-driven-design.org/zh/ddd-concept-reference.html + +- VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。 +- DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。 +- DO(Domain Object):领域对象(entity),就是从现实世界中抽象出来的有形或无形的业务实体。 +- PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。 + +> ``` +> 用户发出请求(可能是填写表单),表单的数据在展示层被匹配为VO。 +> 展示层把VO转换为服务层对应方法所要求的DTO,传送给服务层。 +> 服务层首先根据DTO的数据构造(或重建)一个DO,调用DO的业务方法完成具体业务。 +> 服务层把DO转换为持久层对应的PO(可以使用ORM工具,也可以不用),调用持久层的持久化方法,把PO传递给它,完成持久化操作。 +> 对于一个逆向操作,如读取数据,也是用类似的方式转换和传递 +> ``` + + + +# 项目运行 + +## 配置 + +manifest/config/config.yaml + +```yaml +# HTTP Server. +server: + lang: zh-CN # "zh-CN", "zh-TW", "en" + public_port: 21800 # 对外端口 + private_port: 21801 # 对内端口 + server_name: "AitextGoDdd" + mode: "debug" # gin的模式配置 debug, test, release + dev: true # true,false;校验token等,开发模式的时候打开 + enable_event: false # 是否开启事件 + enable_job: false # 是否开启任务 + enable_grpc: true # 是否开启grpc + +# GRPC Server. +gserver: + host: "0.0.0.0" # 当前服务 + public_port: 21802 # 当前服务 + max_msg_size: 1024 # 最大发送接收字节数,单位 m + client_goods_host: "0.0.0.0" # goods服务的host + client_goods_port: 18080 # goods服务的port + +# Database. +mysql: + username: "root" + password: "admin123" + db_host: "10.4.7.71" + db_port: 3306 + db_name: "go_demo" + charset: "utf8mb4" + max_open_conn: 50 # 设置数据库连接池最大连接数 + max_idle_conn: 10 # 连接池最大允许的空闲连接数 + conn_max_lifetime: 500 # 设置连接可复用的最大时间 + log_mode: 4 # gorm错误级别; 1: Silent, 2:Error,3:Warn,4:Info + slow_threshold: 10 # 慢查询 + +# Log. +log: + log_file_dir: "/tmp/logs/" + max_size: 512 + max_backups: 64 + max_age: 7 + log_level: "debug" #自定义日志; trace, debug, info,panic, fatal, error, warn + log_out: "console" # console, file + +# nsq. +nsq: + nsq_producer_host: "10.4.7.71" + nsq_producer_port: 4150 # tcp + nsq_subscribe_host: "10.4.7.71" + nsq_subscribe_port: 4150 # tcp + +# otel +otel: + enable: false + export_endpoint: "10.4.7.71:4317" + +``` + +## 运行 +- 直接运行: go run main.go +- 指定环境运行: go run main.go -env test +- 编译:go build + + +# 更多 + +## 支持多配置运行 + +``` +go run main.go # 会使用默认的开发配置,即 debug模式 +go run main.go -env test # 会使用test的配置,即测试环境 +go run main.go -env release # 会使用release的配置,即正式环境 +``` + +## 支持多协议并存 + +程序可以支持:http协议,又分为内部接口、外部接口。比如 + +外部接口: http://127.0.0.1:21800/api/pc/v1/sys/menu/1 + +内部接口:http://127.0.0.1:21801/private/pc/v1/sys/demo + +grpc接口:127.0.0.1:21802 diff --git a/README.md b/README.md new file mode 100644 index 0000000..518e678 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# aitext-go-ddd-multi + +## 介绍 + +go-ddd-multi ,是实现ddd的多模块的案例。在业务开发中,会分common、biz1、biz2等等; + +因此此项目是参考java的设计,然后汇集而成。 \ No newline at end of file diff --git a/common/README.md b/common/README.md new file mode 100644 index 0000000..8dd7e94 --- /dev/null +++ b/common/README.md @@ -0,0 +1,2 @@ +# common +公共模块 \ No newline at end of file diff --git a/common/go.mod b/common/go.mod new file mode 100644 index 0000000..b2c23e1 --- /dev/null +++ b/common/go.mod @@ -0,0 +1,62 @@ +module jettjia/go-ddd-demo-multi-common + +go 1.20 + +require ( + github.com/BurntSushi/toml v1.3.2 + github.com/dtm-labs/rockscache v0.1.1 + github.com/gin-gonic/gin v1.9.1 + github.com/go-playground/validator/v10 v10.15.4 + github.com/gogf/gf/v2 v2.5.4 + github.com/oklog/ulid/v2 v2.1.0 + github.com/pkg/errors v0.9.1 + github.com/redis/go-redis/v9 v9.2.0 + github.com/sirupsen/logrus v1.9.3 + gopkg.in/natefinch/lumberjack.v2 v2.2.1 + gopkg.in/yaml.v3 v3.0.1 + gorm.io/driver/mysql v1.5.1 + gorm.io/gorm v1.25.4 +) + +require ( + github.com/bytedance/sonic v1.9.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/clbanning/mxj/v2 v2.7.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/lithammer/shortuuid v3.0.0+incompatible // indirect + github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + go.opentelemetry.io/otel v1.14.0 // indirect + go.opentelemetry.io/otel/sdk v1.14.0 // indirect + go.opentelemetry.io/otel/trace v1.14.0 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect +) diff --git a/common/go.sum b/common/go.sum new file mode 100644 index 0000000..fadb933 --- /dev/null +++ b/common/go.sum @@ -0,0 +1,154 @@ +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +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/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dtm-labs/rockscache v0.1.1 h1:6S1vgaHvGqrLd8Ka4hRTKeKPV7v+tT0MSkTIX81LRyA= +github.com/dtm-labs/rockscache v0.1.1/go.mod h1:c76WX0kyIibmQ2ACxUXvDvaLykoPakivMqIxt+UzE7A= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +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-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +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.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs= +github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gogf/gf/v2 v2.5.4 h1:UBCSw8mInkHmEqL0E1LYc6QhSpaNFY/wHcFrTI/rzTk= +github.com/gogf/gf/v2 v2.5.4/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= +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/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lithammer/shortuuid v3.0.0+incompatible h1:NcD0xWW/MZYXEHa6ITy6kaXN5nwm/V115vj2YXfhS0w= +github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +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.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +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 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= +github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +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/redis/go-redis/v9 v9.2.0 h1:zwMdX0A4eVzse46YN18QhuDiM4uf3JmkOB4VZrdt5uI= +github.com/redis/go-redis/v9 v9.2.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +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.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= +go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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/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.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= +gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= +gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/common/pkg/conf/conf.go b/common/pkg/conf/conf.go new file mode 100644 index 0000000..9614d75 --- /dev/null +++ b/common/pkg/conf/conf.go @@ -0,0 +1,85 @@ +package conf + +import ( + "encoding/json" + "errors" + "flag" + "fmt" + "io/ioutil" + "reflect" + + "github.com/BurntSushi/toml" + "gopkg.in/yaml.v3" +) + +const ( + _Json = iota + 1 + _Yaml + _Toml +) + +var confPath string + +func init() { + flag.StringVar(&confPath, "conf", "", "conf path, example: -conf /conf.yaml") +} + +// ParseYaml 解析配置文件 +// +// c: 需要解析的相对应的结构体指针,例:conf_test.go +func ParseYaml(confPtr interface{}) error { + return parse(_Yaml, confPtr) +} + +// ParseToml 解析配置文件 +// +// 需要解析的相对应的结构体指针,例:conf_test.go +func ParseToml(confPtr interface{}) error { + return parse(_Toml, confPtr) +} + +// ParseJson 解析配置文件 +// +// c: 需要解析的相对应的结构体指针,例:conf_test.go +func ParseJson(confPtr interface{}) error { + return parse(_Json, confPtr) +} + +func parse(cType int, confPtr interface{}) error { + if confPtr == nil { + return errors.New("c struct ptr can not be nil") + } + + beanValue := reflect.ValueOf(confPtr) + if beanValue.Kind() != reflect.Ptr { + return errors.New("c must be ptr") + } + if beanValue.Elem().Kind() != reflect.Struct { + return errors.New("c must be struct ptr") + } + flag.Parse() + if confPath == "" { + return errors.New("load conf file path failed, add arguments -conf ") + } + fileBs, err := ioutil.ReadFile(confPath) + if err != nil { + return fmt.Errorf("read conf file error: %w", err) + } + switch cType { + case _Json: + if err = json.Unmarshal(fileBs, confPtr); err != nil { + return fmt.Errorf("parse conf file [%s] error: %w", string(fileBs), err) + } + case _Yaml: + if err = yaml.Unmarshal(fileBs, confPtr); err != nil { + return fmt.Errorf("parse conf file [%s] error: %w", string(fileBs), err) + } + case _Toml: + if _, err = toml.Decode(string(fileBs), confPtr); err != nil { + return fmt.Errorf("parse conf file [%s] error: %w", string(fileBs), err) + } + default: + return errors.New("conf file only support: yaml、json、toml") + } + return nil +} diff --git a/common/pkg/conf/config_st.go b/common/pkg/conf/config_st.go new file mode 100644 index 0000000..32e0af7 --- /dev/null +++ b/common/pkg/conf/config_st.go @@ -0,0 +1,84 @@ +package conf + +type Config struct { + Server ServerConf + Gserver GServerConf + Mysql MysqlConf + Log LogConf + Nsq NsqConf + Otel OtelConf + Redis RedisConf +} + +// ServerConf http服务 +type ServerConf struct { + Lang string `yaml:"lang"` + PublicPort int `yaml:"public_port"` + PrivatePort int `yaml:"private_port"` + PublicMetricPort int `yaml:"public_metric_port"` + PrivateMetricPort int `yaml:"private_metric_port"` + ServerName string `yaml:"server_name"` + Mode string `yaml:"mode"` + Dev bool `yaml:"dev"` + EnableEvent bool `yaml:"enable_event"` + EnableJob bool `yaml:"enable_job"` + EnableGrpc bool `yaml:"enable_grpc"` +} + +// GServerConf grpc服务 +type GServerConf struct { + Host string `yaml:"host"` + PublicPort int `yaml:"public_port"` + MaxMsgSize int `yaml:"max_msg_size"` + ClientGoodsHost string `yaml:"client_goods_host"` + ClientGoodsPort int `yaml:"client_goods_port"` +} + +// MysqlConf mysql +type MysqlConf struct { + Username string `yaml:"username"` + Password string `yaml:"password"` + DbHost string `yaml:"db_host"` + DbPort int `yaml:"db_port"` + DbName string `yaml:"db_name"` + Charset string `yaml:"charset"` + MaxIdleConn int `yaml:"max_idle_conn"` + MaxOpenConn int `yaml:"max_open_conn"` + ConnMaxLifetime int `yaml:"conn_max_lifetime"` + LogMode int `yaml:"log_mode"` + SlowThreshold int `yaml:"slow_threshold"` +} + +// RedisConf redis +type RedisConf struct { + RedisType string `yaml:"redis_type"` // redis使用模式:alone, sentinel,cluster + Addr string `yaml:"addr"` + Password string `yaml:"password"` + MasterName string `yaml:"master_name"` + PoolSize int `yaml:"pool_size"` +} + +// LogConf log +type LogConf struct { + LogFileDir string `yaml:"log_file_dir"` // 日志目录 + AppName string `yaml:"app_name"` //日志名称 + MaxSize int `yaml:"max_size"` //文件多大开始切分 + MaxBackups int `yaml:"max_backups"` //保留文件个数 + MaxAge int `yaml:"max_age"` //文件保留最大实际 + LogLevel string `yaml:"log_level"` // 日志级别 + LogOut string `yaml:"log_out"` // 日志输出位置 +} + +// NsqConf nsq +type NsqConf struct { + NsqProducerHost string `yaml:"nsq_producer_host"` + NsqProducerPort string `yaml:"nsq_producer_port"` + NsqSubscribeHost string `yaml:"nsq_subscribe_host"` + NsqSubscribePort string `yaml:"nsq_subscribe_port"` +} + +// OtelConf otel +type OtelConf struct { + Enable bool `yaml:"enable"` + ExportEndpoint string `yaml:"export_endpoint"` +} diff --git a/common/pkg/data/data.go b/common/pkg/data/data.go new file mode 100644 index 0000000..1c65086 --- /dev/null +++ b/common/pkg/data/data.go @@ -0,0 +1,21 @@ +package data + +import ( + "github.com/dtm-labs/rockscache" + "github.com/redis/go-redis/v9" + "gorm.io/gorm" +) + +type Data struct { + Mysql *gorm.DB + RedisCli redis.UniversalClient + RocksCache *rockscache.Client +} + +func NewData(mysqlDB *gorm.DB, redisCli redis.UniversalClient, rocksCli *rockscache.Client) (*Data, error) { + return &Data{ + Mysql: mysqlDB, + RedisCli: redisCli, + RocksCache: rocksCli, + }, nil +} diff --git a/common/pkg/data/transaction.go b/common/pkg/data/transaction.go new file mode 100644 index 0000000..4c0b681 --- /dev/null +++ b/common/pkg/data/transaction.go @@ -0,0 +1,37 @@ +package data + +import ( + "context" + + "gorm.io/gorm" +) + +// Transaction 事务管理 +type Transaction interface { + ExecTx(context.Context, func(ctx context.Context) error) error +} + +// 用来承载事务的上下文 +type contextTxKey struct{} + +// NewTransaction . +func NewTransaction(d *Data) Transaction { + return d +} + +// ExecTx gorm Transaction +func (d *Data) ExecTx(ctx context.Context, fn func(ctx context.Context) error) error { + return d.Mysql.WithContext(ctx).Transaction(func(tx *gorm.DB) error { + ctx = context.WithValue(ctx, contextTxKey{}, tx) + return fn(ctx) + }) +} + +// DB 根据此方法来判断当前的 db 是不是使用 事务的 DB +func (d *Data) DB(ctx context.Context) *gorm.DB { + tx, ok := ctx.Value(contextTxKey{}).(*gorm.DB) + if ok { + return tx + } + return d.Mysql +} diff --git a/common/pkg/database/db/mysql.go b/common/pkg/database/db/mysql.go new file mode 100644 index 0000000..4650371 --- /dev/null +++ b/common/pkg/database/db/mysql.go @@ -0,0 +1,94 @@ +package db + +import ( + "fmt" + "log" + "os" + "sync" + "time" + + "gorm.io/driver/mysql" + "gorm.io/gorm" + "gorm.io/gorm/logger" + "gorm.io/gorm/schema" +) + +type DB struct { + Conf *DBConfig + Conn *gorm.DB +} + +var ( + dbOnce sync.Once + dbImpl *DB +) + +func NewDBClient(cfg *DBConfig) *DB { + + dbOnce.Do(func() { + dbImpl = &DB{ + Conf: cfg, + } + dbImpl.getConn() + }) + + return dbImpl +} + +type DBConfig struct { + Host string // 服务器地址 + Port int // 端口 + DbType string // db类型 + User string // 数据库用户名 + Password string // 数据库密码 + Db string // 数据名 + DbChar string // 字符集 + MaxIdleConn int // 最大空闲连接 + MaxOpenConn int // 最大连接数 + MaxLifetime int // 最大生存时间(s) + LogMode int // 是否打印日志 + SlowThreshold int // 慢sql的起始时间 +} + +// getConn 链接数据库 +func (db *DB) getConn() *gorm.DB { + var ( + dsn string + err error + ) + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local", db.Conf.User, db.Conf.Password, db.Conf.Host, db.Conf.Port, db.Conf.Db, db.Conf.DbChar) + + // gorm logger 配置 + loggerDefault := logger.New( + log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer + logger.Config{ + SlowThreshold: time.Duration(db.Conf.SlowThreshold) * time.Second, // 慢 SQL 阈值 + LogLevel: logger.LogLevel(db.Conf.LogMode), // Log level + Colorful: true, // 彩色打印 + IgnoreRecordNotFoundError: true, // 关闭 not found错误 + }, + ) + + cfg := &gorm.Config{ + NamingStrategy: schema.NamingStrategy{ + SingularTable: true, // 使用单数表名 + }, + Logger: loggerDefault, // gorm的log设置 + } + + if db.Conn, err = gorm.Open(mysql.Open(dsn), cfg); err != nil { + panic(err) + } + + sqlDB, _ := db.Conn.DB() + sqlDB.SetMaxIdleConns(db.Conf.MaxOpenConn) //连接池最大允许的空闲连接数,如果没有sql任务需要执行的连接数大于20,超过的连接会被连接池关闭。 + sqlDB.SetMaxOpenConns(db.Conf.MaxOpenConn) //设置数据库连接池最大连接数 + sqlDB.SetConnMaxLifetime(time.Duration(db.Conf.MaxLifetime) * time.Second) + + // 使用插件 + if err = db.Conn.Use(&TracePlugin{}); err != nil { + panic(err) + } + + return db.Conn +} diff --git a/common/pkg/database/db/plugin.go b/common/pkg/database/db/plugin.go new file mode 100644 index 0000000..1beee93 --- /dev/null +++ b/common/pkg/database/db/plugin.go @@ -0,0 +1,60 @@ +package db + +import ( + "errors" + "time" + + "gorm.io/gorm" +) + +const ( + callBackBeforeName = "core:before" + callBackAfterName = "core:after" + startTime = "_start_time" +) + +type TracePlugin struct{} + +func (op *TracePlugin) Name() string { + return "tracePlugin" +} + +func (op *TracePlugin) Initialize(db *gorm.DB) (err error) { + // 开始前 + _ = db.Callback().Create().Before("gorm:before_create").Register(callBackBeforeName, before) + _ = db.Callback().Query().Before("gorm:query").Register(callBackBeforeName, before) + _ = db.Callback().Delete().Before("gorm:before_delete").Register(callBackBeforeName, before) + _ = db.Callback().Update().Before("gorm:setup_reflect_value").Register(callBackBeforeName, before) + _ = db.Callback().Row().Before("gorm:row").Register(callBackBeforeName, before) + _ = db.Callback().Raw().Before("gorm:raw").Register(callBackBeforeName, before) + + // 忽略 gorm not found错误 + db.Callback().Query().Before("gorm:query").Register("disable_raise_record_not_found", func(d *gorm.DB) { + d.Statement.RaiseErrorOnNotFound = false + }) + + // 结束后 + _ = db.Callback().Create().After("gorm:after_create").Register(callBackAfterName, after) + _ = db.Callback().Query().After("gorm:after_query").Register(callBackAfterName, after) + _ = db.Callback().Delete().After("gorm:after_delete").Register(callBackAfterName, after) + _ = db.Callback().Update().After("gorm:after_update").Register(callBackAfterName, after) + _ = db.Callback().Row().After("gorm:row").Register(callBackAfterName, after) + _ = db.Callback().Raw().After("gorm:raw").Register(callBackAfterName, after) + return +} + +var _ gorm.Plugin = &TracePlugin{} + +func before(db *gorm.DB) { + db.InstanceSet(startTime, time.Now()) +} + +func after(db *gorm.DB) { + err := db.Statement.Error + if errors.Is(err, gorm.ErrRecordNotFound) { + return + } + if err != nil { + panic(err) + } +} diff --git a/common/pkg/event/.gitkeep b/common/pkg/event/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/common/pkg/httpclient/.gitkeep b/common/pkg/httpclient/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/common/pkg/log/log_server.go b/common/pkg/log/log_server.go new file mode 100644 index 0000000..8a21fb6 --- /dev/null +++ b/common/pkg/log/log_server.go @@ -0,0 +1,115 @@ +package log + +import ( + "io" + "os" + "path" + "sync" + "time" + + "github.com/sirupsen/logrus" + "gopkg.in/natefinch/lumberjack.v2" +) + +type LoggerConfig struct { + LogPath string // 日志路径 + MaxSize int // 日志文件大小,单位是 MB + MaxBackups int // 最大过期日志保留个数 + MaxAge int // 保留过期文件最大时间,单位 天 + LogLevel string // 日志级别 panic, fatal, error, warn, info, debug,trace + LogOut string // console, file +} + +var ( + once sync.Once + l *logrus.Logger +) + +func NewLogger(options ...func(*LoggerConfig)) *logrus.Logger { + once.Do(func() { + cfg := LoggerConfig{ + LogPath: "/tmp/logs/", + MaxSize: 128, + MaxBackups: 255, + MaxAge: 7, + LogLevel: "error", + LogOut: "console", + } + + for _, option := range options { + option(&cfg) + } + + l = initLogger(&cfg) + }) + return l +} + +func initLogger(cfg *LoggerConfig) *logrus.Logger { + logHandle := logrus.New() + logHandle.SetLevel(logLevel(cfg.LogLevel)) + logHandle.SetFormatter(&logrus.JSONFormatter{}) + + var output io.Writer + if cfg.LogOut == "console" { + output = os.Stdout + } else { + output = &lumberjack.Logger{ + Filename: logFileNamePath(cfg.LogPath), + MaxSize: cfg.MaxSize, // 日志文件大小,单位是 MB + MaxBackups: cfg.MaxBackups, // 最大过期日志保留个数 + MaxAge: cfg.MaxAge, // 保留过期文件最大时间,单位 天 + Compress: true, // 是否压缩日志,默认是不压缩。这里设置为true,压缩日志 + } + } + + logHandle.SetOutput(output) + + return logHandle +} + +func logLevel(logLevel string) (level logrus.Level) { + switch logLevel { + case "panic": + return logrus.PanicLevel + case "fatal": + return logrus.FatalLevel + case "error": + return logrus.ErrorLevel + case "warn": + return logrus.WarnLevel + case "info": + return logrus.InfoLevel + case "debug": + return logrus.DebugLevel + case "trace": + return logrus.TraceLevel + } + + return logrus.DebugLevel +} + +func logFileNamePath(settingPath string) string { + var ( + logFilePath string + ) + logFilePath = settingPath + if logFilePath == "" { + logFilePath = "/tmp/logs/" + } + + if err := os.MkdirAll(logFilePath, 0o777); err != nil { + panic(err) + } + + // Set filename to date + logFileName := time.Now().Format("2006-01-02") + ".log" + fileName := path.Join(logFilePath, logFileName) + if _, err := os.Stat(fileName); err != nil { + if _, err := os.Create(fileName); err != nil { + panic(err) + } + } + + return fileName +} diff --git a/common/pkg/log/option.go b/common/pkg/log/option.go new file mode 100644 index 0000000..96709bb --- /dev/null +++ b/common/pkg/log/option.go @@ -0,0 +1,39 @@ +package log + +type Option func(p *LoggerConfig) + +func WithLogPath(logPath string) Option { + return func(s *LoggerConfig) { + s.LogPath = logPath + } +} + +func WithMaxSize(maxSize int) Option { + return func(s *LoggerConfig) { + s.MaxSize = maxSize + } +} + +func WithMaxBackups(maxBackups int) Option { + return func(s *LoggerConfig) { + s.MaxBackups = maxBackups + } +} + +func WithMaxAge(maxAge int) Option { + return func(s *LoggerConfig) { + s.MaxAge = maxAge + } +} + +func WithLogLevel(logLevel string) Option { + return func(s *LoggerConfig) { + s.LogLevel = logLevel + } +} + +func WithLogOut(logOut string) Option { + return func(s *LoggerConfig) { + s.LogOut = logOut + } +} diff --git a/common/pkg/mongo/.gitkeep b/common/pkg/mongo/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/common/pkg/otel/.gitkeep b/common/pkg/otel/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/common/pkg/redis/README.md b/common/pkg/redis/README.md new file mode 100644 index 0000000..e083faf --- /dev/null +++ b/common/pkg/redis/README.md @@ -0,0 +1,13 @@ +# redis + +将支持下面的三种模式,分布依赖的包如图介绍 + +alone 单机模式 + +sentinel 哨兵模式 + +cluster 集群模式 + + +redis文档地址: +https://redis.uptrace.dev/guide/ \ No newline at end of file diff --git a/common/pkg/redis/redis.go b/common/pkg/redis/redis.go new file mode 100644 index 0000000..b73b1f3 --- /dev/null +++ b/common/pkg/redis/redis.go @@ -0,0 +1,77 @@ +package redis + +import ( + "sync" + + "github.com/redis/go-redis/v9" +) + +type RedisDB struct { + Conn redis.UniversalClient +} + +type RedisConfig struct { + RedisType string // redis使用模式:alone, sentinel,cluster + Addrs []string + Password string + MasterName string + PoolSize int +} + +var ( + once sync.Once + rdConn *RedisDB +) + +// NewRedisClient 获取redis的链接 +func NewRedisClient(cfg *RedisConfig) *RedisDB { + + once.Do(func() { + rdConn = &RedisDB{} + + rdConn.Conn = getConn(cfg) + }) + + return rdConn +} + +func getConn(cfg *RedisConfig) redis.UniversalClient { + var ( + rdb redis.UniversalClient + typ string + ) + + typ = cfg.RedisType + + switch typ { + case "alone": + rdb = redis.NewUniversalClient(&redis.UniversalOptions{ + Addrs: cfg.Addrs, + Password: cfg.Password, + PoolSize: cfg.PoolSize, + }) + case "sentinel": + rdb = redis.NewUniversalClient(&redis.UniversalOptions{ + Addrs: cfg.Addrs, + MasterName: cfg.MasterName, + Password: cfg.Password, + // To route commands by latency or randomly, enable one of the following. + RouteByLatency: true, + RouteRandomly: true, + PoolSize: cfg.PoolSize, + }) + case "cluster": + rdb = redis.NewUniversalClient(&redis.UniversalOptions{ + Addrs: cfg.Addrs, + Password: cfg.Password, + // To route commands by latency or randomly, enable one of the following. + RouteByLatency: true, + RouteRandomly: true, + PoolSize: cfg.PoolSize, + }) + default: + panic("redis link type error, Link type must be:alone,sentinel,cluster") + } + + return rdb +} diff --git a/common/pkg/redis/redis_redsync.go b/common/pkg/redis/redis_redsync.go new file mode 100644 index 0000000..4941eea --- /dev/null +++ b/common/pkg/redis/redis_redsync.go @@ -0,0 +1,117 @@ +package redis + +import ( + "context" + "math/rand" + "strconv" + "sync/atomic" + "time" + + "github.com/gogf/gf/v2/os/glog" + red "github.com/redis/go-redis/v9" +) + +const ( + letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + lockCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then + redis.call("SET", KEYS[1], ARGV[1], "PX", ARGV[2]) + return "OK" +else + return redis.call("SET", KEYS[1], ARGV[1], "NX", "PX", ARGV[2]) +end` + delCommand = `if redis.call("GET", KEYS[1]) == ARGV[1] then + return redis.call("DEL", KEYS[1]) +else + return 0 +end` + randomLen = 16 + // 默认超时时间,防止死锁 + tolerance = 500 // milliseconds + millisPerSecond = 1000 +) + +// A RedisLock is a redis lock. +type RedisLock struct { + // redis客户端 + store red.UniversalClient + // 超时时间 + seconds uint32 + // 锁key + key string + // 锁value,防止锁被别人获取到 + id string +} + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// NewRedisLock returns a RedisLock. +func NewRedisLock(store red.UniversalClient, key string) *RedisLock { + return &RedisLock{ + store: store, + key: key, + // 获取锁时,锁的值通过随机字符串生成 + // 实际上go-zero提供更加高效的随机字符串生成方式 + // 见core/stringx/random.go:Randn + id: randomStr(randomLen), + } +} + +// Acquire acquires the lock. +// 加锁 +func (rl *RedisLock) Acquire() (bool, error) { + // 获取过期时间 + seconds := atomic.LoadUint32(&rl.seconds) + // 默认锁过期时间为500ms,防止死锁 + resp, err := rl.store.Eval(context.TODO(), lockCommand, []string{rl.key}, []string{ + rl.id, strconv.Itoa(int(seconds)*millisPerSecond + tolerance), + }).Result() + if err == red.Nil { + return false, nil + } else if err != nil { + glog.Error(context.TODO(), "Error on acquiring lock for %s, %s", rl.key, err) + return false, err + } else if resp == nil { + return false, nil + } + + reply, ok := resp.(string) + if ok && reply == "OK" { + return true, nil + } + + glog.Error(context.TODO(), "Unknown reply when acquiring lock for %s: %v", rl.key, resp) + return false, nil +} + +// Release releases the lock. +// 释放锁 +func (rl *RedisLock) Release() (bool, error) { + resp, err := rl.store.Eval(context.TODO(), delCommand, []string{rl.key}, []string{rl.id}).Result() + if err != nil { + return false, err + } + + reply, ok := resp.(int64) + if !ok { + return false, nil + } + + return reply == 1, nil +} + +// SetExpire sets the expire. +// 需要注意的是需要在Acquire()之前调用 +// 不然默认为500ms自动释放 +func (rl *RedisLock) SetExpire(seconds int) { + atomic.StoreUint32(&rl.seconds, uint32(seconds)) +} + +func randomStr(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} diff --git a/common/pkg/redis/redis_test.go b/common/pkg/redis/redis_test.go new file mode 100644 index 0000000..5e0d5fe --- /dev/null +++ b/common/pkg/redis/redis_test.go @@ -0,0 +1,141 @@ +package redis + +import ( + "context" + "fmt" + "testing" +) + +func Test_Alone(t *testing.T) { + var ( + err error + resp string + ) + + cfg := &RedisConfig{ + RedisType: "alone", + Addrs: []string{ + "10.4.7.71:6379", + }, + Password: "admin123", + PoolSize: 100, + } + client := NewRedisClient(cfg).Conn + defer client.Close() + + // call commands on it + if _, err = client.Set(context.TODO(), "some-key", "2222", 0).Result(); err != nil { + t.Errorf("SET failed: %v", err) + } + + if resp, err = client.Get(context.TODO(), "some-key").Result(); err != nil { + t.Errorf("GET failed: %v", err) + } + + fmt.Println(resp) +} + +func Test_Cluster(t *testing.T) { + var ( + err error + resp string + ) + + cfg := &RedisConfig{ + RedisType: "cluster", + Addrs: []string{ + "10.4.7.71:6371", + "10.4.7.71:6372", + "10.4.7.71:6373", + "10.4.7.71:6374", + "10.4.7.71:6375", + "10.4.7.71:6376", + }, + Password: "admin123", + PoolSize: 100, + } + client := NewRedisClient(cfg).Conn + defer client.Close() + + // call commands on it + if _, err = client.Set(context.TODO(), "some-key", "2222", 0).Result(); err != nil { + t.Errorf("SET failed: %v", err) + } + + if resp, err = client.Get(context.TODO(), "some-key").Result(); err != nil { + t.Errorf("GET failed: %v", err) + } + + fmt.Println(resp) +} + +func Test_Sentinel(t *testing.T) { + var ( + err error + resp string + ) + + cfg := &RedisConfig{ + RedisType: "sentinel", + Addrs: []string{ + "10.4.7.71:26379", + "10.4.7.71:26380", + "10.4.7.71:26381", + }, + Password: "admin123", + PoolSize: 100, + MasterName: "mymaster", + } + client := NewRedisClient(cfg).Conn + defer client.Close() + + // call commands on it + if _, err = client.Set(context.TODO(), "some-key", "2222", 0).Result(); err != nil { + t.Errorf("SET failed: %v", err) + } + + if resp, err = client.Get(context.TODO(), "some-key").Result(); err != nil { + t.Errorf("GET failed: %v", err) + } + + fmt.Println(resp) +} + +// 分布式锁 +func TestRedisRedsync(t *testing.T) { + cfg := &RedisConfig{ + RedisType: "cluster", + Addrs: []string{ + "10.4.7.71:6371", + "10.4.7.71:6372", + "10.4.7.71:6373", + "10.4.7.71:6374", + "10.4.7.71:6375", + "10.4.7.71:6376", + }, + Password: "admin123", + PoolSize: 100, + } + + client := NewRedisClient(cfg).Conn + defer client.Close() + + redisLockClient := NewRedisLock(client, "my-mutex") + + var ( + boolFlag bool + err error + ) + + // 增加锁 + if boolFlag, err = redisLockClient.Acquire(); err != nil { + panic(err) + } + fmt.Println("增加锁resp:", boolFlag) + + // 释放锁 + if boolFlag, err = redisLockClient.Release(); err != nil { + panic(err) + } + fmt.Println("释放锁resp:", boolFlag) +} diff --git a/common/pkg/response/error_info.go b/common/pkg/response/error_info.go new file mode 100644 index 0000000..035b71c --- /dev/null +++ b/common/pkg/response/error_info.go @@ -0,0 +1,87 @@ +package response + +import ( + "path/filepath" + "runtime" + "strings" +) + +// ErrorInfo 堆栈错误信息 +type ( + ErrorInfo struct { + Internal []frameErrorInfo `json:"stacks"` + } + + frameErrorInfo struct { + Filename string `json:"filename"` + Line int `json:"line"` + FuncName string `json:"func_name"` + } +) + +// 记录到日志的错误信息 +type logErr struct { + Stack []frameErrorInfo `json:"stack"` + Sql string `json:"sql,omitempty"` +} + +// Panic 异常 +func Panic(err interface{}) ErrorInfo { + var logErr logErr + errInfo := alarm() + logErr.Stack = errInfo.Internal + + return errInfo +} + +// GrpcPanic 异常 +func GrpcPanic(err interface{}) ErrorInfo { + var logErr logErr + errInfo := alarm() + logErr.Stack = errInfo.Internal + + return errInfo +} + +func alarm() (err ErrorInfo) { + pc := make([]uintptr, 10) // at least 1 entry needed + n := runtime.Callers(0, pc) + frames := runtime.CallersFrames(pc[:n]) + + var frameErrorInfosInternal []frameErrorInfo + + for { + frame, more := frames.Next() + if strings.Contains(frame.File, "runtime/") { + continue + } + if strings.Contains(frame.File, "gin-gonic/") { + continue + } + if strings.Contains(frame.File, "response") { + continue + } + if strings.Contains(frame.File, "infrastructure/pkg") { + continue + } + + // 记录具体的错误到日日志中 + var ( + frameErrorInfo frameErrorInfo + ) + + _, fileName := filepath.Split(frame.File) + frameErrorInfo.Filename = fileName + frameErrorInfo.Line = frame.Line + _, function := filepath.Split(frame.Function) + frameErrorInfo.FuncName = function + frameErrorInfosInternal = append(frameErrorInfosInternal, frameErrorInfo) + + if !more { + break + } + } + + err.Internal = frameErrorInfosInternal + return +} diff --git a/common/pkg/response/gcode.go b/common/pkg/response/gcode.go new file mode 100644 index 0000000..746cb43 --- /dev/null +++ b/common/pkg/response/gcode.go @@ -0,0 +1,39 @@ +package response + +import "github.com/gogf/gf/v2/errors/gcode" + +type BizCode struct { + code int + message string + detail BizCodeDetail +} + +type BizCodeDetail struct { + SubCode int +} + +func (c BizCode) BizDetail() BizCodeDetail { + return c.detail +} + +func (c BizCode) Code() int { + return c.code +} + +func (c BizCode) Message() string { + return c.message +} + +func (c BizCode) Detail() interface{} { + return c.detail +} + +func NewCode(httpCode int, subCode int, message string) gcode.Code { + return BizCode{ + code: httpCode, + message: message, + detail: BizCodeDetail{ + SubCode: subCode, + }, + } +} diff --git a/common/pkg/response/gerror_def.go b/common/pkg/response/gerror_def.go new file mode 100644 index 0000000..05b0922 --- /dev/null +++ b/common/pkg/response/gerror_def.go @@ -0,0 +1,34 @@ +package response + +import "net/http" + +// 通用异常 +var ( + ErrorNil = 200000000 + BadRequest = 400000000 + Unauthorized = 401000000 + Forbidden = 403000000 + NotFound = 404000000 + Conflict = 409000000 + InternalServerError = 500000000 +) + +var ( + CommErr = 100000 + CommErrBadRequest = BadRequest + CommErr + CommErrUnauthorized = Unauthorized + CommErr + CommErrForbidden = Forbidden + CommErr + CommErrNotFound = NotFound + CommErr + CommErrConflict = Conflict + CommErr + CommErrInternalServer = InternalServerError + CommErr +) + +var ( + CodeNil = NewCode(http.StatusOK, ErrorNil, "") + CommBadRequest = NewCode(http.StatusBadRequest, CommErrBadRequest, "Invalid parameter") + CommUnauthorized = NewCode(http.StatusUnauthorized, CommErrUnauthorized, "Unauthorized") + CommForbidden = NewCode(http.StatusForbidden, CommErrForbidden, "Forbidden") + CommNotFound = NewCode(http.StatusNotFound, CommErrNotFound, "Record does not exist") + CommConflict = NewCode(http.StatusConflict, CommErrConflict, "The request is conflicts") + CommInternalServer = NewCode(http.StatusInternalServerError, CommErrInternalServer, "Internal Server Error") +) diff --git a/common/pkg/response/gresponse.go b/common/pkg/response/gresponse.go new file mode 100644 index 0000000..604d15b --- /dev/null +++ b/common/pkg/response/gresponse.go @@ -0,0 +1,82 @@ +package response + +import ( + "context" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/i18n/gi18n" +) + +type rspErrorData struct { + SubCode int `json:"sub_code"` + Message string `json:"message"` + Cause interface{} `json:"cause"` +} + +func RspOk(c *gin.Context, code int, any interface{}) { + switch code { + case 200: + c.JSON( + http.StatusOK, + any, + ) + case 201: + c.JSON( + http.StatusCreated, + any, + ) + case 204: + c.AbortWithStatus( + http.StatusNoContent, + ) + + default: + c.JSON( + http.StatusOK, + any, + ) + } +} + +func RspErr(c *gin.Context, err error) { + code := gerror.Code(err) + subCode := code.(BizCode).BizDetail().SubCode + msg := msg(code.Code()) + rspError(c, code.Code(), subCode, msg, err) +} + +func rspError(c *gin.Context, code int, subCode int, message string, err error) { + c.JSON( + code, + rspErrorData{ + SubCode: subCode, // error sub code + Message: message, // error message + Cause: err, // stack error + }, + ) +} + +func msg(code int) (msg string) { + lang := "en" + i18n := gi18n.New() + ctx := gi18n.WithLanguage(context.TODO(), lang) + + switch code { + case http.StatusBadRequest: + msg = i18n.Translate(ctx, "{#BadRequest}") + case http.StatusUnauthorized: + msg = i18n.Translate(ctx, "{#Unauthorized}") + case http.StatusForbidden: + msg = i18n.Translate(ctx, "{#Forbidden}") + case http.StatusNotFound: + msg = i18n.Translate(ctx, "{#NotFound}") + case http.StatusConflict: + msg = i18n.Translate(ctx, "{#Conflict}") + case http.StatusInternalServerError: + msg = i18n.Translate(ctx, "{#InternalServerError}") + } + + return +} diff --git a/common/pkg/util/ulid.go b/common/pkg/util/ulid.go new file mode 100644 index 0000000..5915248 --- /dev/null +++ b/common/pkg/util/ulid.go @@ -0,0 +1,7 @@ +package util + +import "github.com/oklog/ulid/v2" + +func Ulid() string { + return ulid.Make().String() +} diff --git a/common/pkg/util/util.go b/common/pkg/util/util.go new file mode 100644 index 0000000..71a8bda --- /dev/null +++ b/common/pkg/util/util.go @@ -0,0 +1,27 @@ +package util + +import ( + "bytes" + "encoding/json" + "fmt" + "math" +) + +// CeilPageNum 分页数目计算 +func CeilPageNum(total int64, pageSize int) int64 { + return int64(int(math.Ceil(float64(total) / float64(pageSize)))) +} + +// PrintJson 打印Json +func PrintJson(args interface{}) string { + b, err := json.Marshal(args) + if err != nil { + return fmt.Sprintf("%+v", args) + } + var out bytes.Buffer + err = json.Indent(&out, b, "", " ") + if err != nil { + return fmt.Sprintf("%+v", args) + } + return out.String() +} diff --git a/common/pkg/validate/validate.go b/common/pkg/validate/validate.go new file mode 100644 index 0000000..38fe369 --- /dev/null +++ b/common/pkg/validate/validate.go @@ -0,0 +1,86 @@ +package validate + +import ( + "reflect" + "regexp" + + "github.com/go-playground/validator/v10" + "github.com/pkg/errors" +) + +var validate *validator.Validate + +var ( + // customDataTag is default data tag name + customDataTag = "json" + // customErrTag is default custom tag name + customErrTag = "err_info" +) + +func init() { + validate = validator.New() + // 注册自定义错误 + if err := validate.RegisterValidation("checkSpecialChar", checkSpecialChar); err != nil { + panic(any(err)) + } +} + +// SetCustomDataTag set custom data tag name +func SetCustomDataTag(tag string) { + customDataTag = tag +} + +// SetCustomErrTag set custom err tag name +func SetCustomErrTag(tag string) { + customErrTag = tag +} + +// Validate is validate a struct exposed fields +func Validate(val interface{}) error { + err := validate.Struct(val) + if err == nil { + return nil + } + + for _, err := range err.(validator.ValidationErrors) { + return wrapErr(val, err) + } + + return nil +} + +// wrapErr is wrap err +func wrapErr(val interface{}, err validator.FieldError) error { + t := reflect.TypeOf(val) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + f, ok := t.FieldByName(err.Field()) + if !ok { + return errors.Errorf("param %s must %s %s", err.Field(), err.Tag(), err.Param()) + } + + errTag := f.Tag.Get(customErrTag) + if errTag == "" { + return errors.Errorf("param %s must %s %s", f.Tag.Get(customDataTag), err.Tag(), err.Param()) + } + + return errors.Errorf("%s:%s", f.Tag.Get(customDataTag), errTag) +} + +// checkSpecialChar 校验特殊字符 +func checkSpecialChar(f validator.FieldLevel) bool { + value := f.Field().String() + if value == "" { + return true + } + + flag, err := regexp.MatchString("^([A-Za-z0-9]{1,32})$", value) + + if err != nil { + return false + } + + return flag +} diff --git a/common/pkg/validate/validate_test.go b/common/pkg/validate/validate_test.go new file mode 100644 index 0000000..d0c0343 --- /dev/null +++ b/common/pkg/validate/validate_test.go @@ -0,0 +1,39 @@ +package validate + +import ( + "fmt" + "testing" +) + +func Test_CheckSpecialCharacters(t *testing.T) { + type User struct { + UserName string `json:"user_name"` //通过reg_error_info标签记录 + //reg_error_info也可以是标记错误的唯一标识,通过传入的local_language 从库中或者缓存中找到对应国家的错误提示信息 + Password string `json:"password" validate:"specialChara" err_info:"密码至少6个字符"` + } + + var list []User + + user1 := User{UserName: "zzzzzz", Password: "xxxx."} + user2 := User{UserName: "zzzzzz", Password: "xxxx@"} + user3 := User{UserName: "zzzzzz", Password: "xxxx-"} + user4 := User{UserName: "zzzzzz", Password: "xxxx_"} + user5 := User{UserName: "zzzzzz", Password: "xxxx.@"} + user6 := User{UserName: "zzzzzz", Password: "xxxx.中"} + user7 := User{UserName: "zzzzzz", Password: "xxxx*"} + user8 := User{UserName: "zzzzzz", Password: "xxxx$"} + user9 := User{UserName: "zzzzzz", Password: "capp"} + user10 := User{UserName: "zzzzzz", Password: "capp_01"} + + list = append(list, user1, user2, user3, user4, user5, user6, user7, user8, user9, user10) + + for _, v := range list { + err := Validate(v) //校验 + + if err != nil { + fmt.Println(fmt.Sprintf("当前校验单字符串是:【%s】, 错误是:%s", v.Password, err.Error())) + } else { + fmt.Println(fmt.Sprintf("当前校验单字符串是:【%s】, 成功", v.Password)) + } + } +} diff --git a/common/types/gorm_plugin.go b/common/types/gorm_plugin.go new file mode 100644 index 0000000..b20cbb5 --- /dev/null +++ b/common/types/gorm_plugin.go @@ -0,0 +1,53 @@ +package types + +import ( + "fmt" + "strconv" + + "gorm.io/gorm" +) + +// GenerateQueryCondition assembly search, currently only supports the and method +func GenerateQueryCondition(conditions []*Query) string { + var condition string + for k, v := range conditions { + if k > 0 { + condition += " and " + } + + if v.Operator == Operator_LIKE { + condition += fmt.Sprintf("%v%s'%%%v%%'", v.Key, OperatorMap[v.Operator], v.Value) + } else if v.Operator == Operator_IN { + condition += fmt.Sprintf(` %s %s (%s)`, v.Key, OperatorMap[v.Operator], v.Value) + } else { + //bool string int + _, err := strconv.ParseBool(v.Value) + if err != nil { + condition += fmt.Sprintf("%v%s'%v'", v.Key, OperatorMap[v.Operator], v.Value) + } else { + condition += fmt.Sprintf("%v%s%v", v.Key, OperatorMap[v.Operator], v.Value) + } + } + } + + return condition +} + +// Paginate gorm page +func Paginate(page, pageSize int) func(db *gorm.DB) *gorm.DB { + return func(db *gorm.DB) *gorm.DB { + if page == 0 { + page = 1 + } + + switch { + case pageSize > 100: + pageSize = 100 + case pageSize <= 0: + pageSize = 10 + } + + offset := (page - 1) * pageSize + return db.Offset(offset).Limit(pageSize) + } +} diff --git a/common/types/page_data.go b/common/types/page_data.go new file mode 100644 index 0000000..2a90aa2 --- /dev/null +++ b/common/types/page_data.go @@ -0,0 +1,15 @@ +package types + +// PageData 分页 +type PageData struct { + PageNum int `json:"page_num"` // 页码 + PageSize int `json:"page_size"` // 每页显示行数 + TotalNumber int64 `json:"total_number"` // 共多少条 + TotalPage int64 `json:"total_page"` // 共多少页 +} + +// SortData 排序 +type SortData struct { + Sort string `json:"sort"` // 排序字段 + Direction string `json:"direction"` // asc:升序;desc:降序 +} diff --git a/common/types/sql_query.go b/common/types/sql_query.go new file mode 100644 index 0000000..d2fb3c8 --- /dev/null +++ b/common/types/sql_query.go @@ -0,0 +1,56 @@ +package types + +// Query 搜索 +type Query struct { + Key string `json:"key"` // 搜索关键词的键 + Value string `json:"value"` // 搜索关键词的值 + Operator Operator `json:"operator"` // 判断条件 +} + +type Operator int32 + +const ( + Operator_GT Operator = 0 //大于 + Operator_EQUAL Operator = 1 //等于 + Operator_LT Operator = 2 //小于 + Operator_NEQ Operator = 3 //不等于 + Operator_LIKE Operator = 4 //模糊查询 + Operator_GTE Operator = 5 // 大于等于 + Operator_LTE Operator = 6 // 小于等于 + Operator_IN Operator = 7 // in +) + +// Enum value maps for Operator. +var ( + Operator_name = map[int32]string{ + 0: "GT", + 1: "EQUAL", + 2: "LT", + 3: "NEQ", + 4: "LIKE", + 5: "GTE", + 6: "LTE", + 7: "IN", + } + Operator_value = map[string]int32{ + "GT": 0, + "EQUAL": 1, + "LT": 2, + "NEQ": 3, + "LIKE": 4, + "GTE": 5, + "LTE": 6, + "IN": 7, + } +) + +var OperatorMap = map[Operator]string{ + Operator_GT: " > ", + Operator_EQUAL: " = ", + Operator_LT: " < ", + Operator_NEQ: " != ", + Operator_LIKE: " like ", + Operator_GTE: " >= ", + Operator_LTE: " <= ", + Operator_IN: " in ", +} diff --git a/deploy/docker-compose/.gitkeep b/deploy/docker-compose/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/deploy/framework_tool/.gitkeep b/deploy/framework_tool/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/deploy/k8s/.gitkeep b/deploy/k8s/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/go.work b/go.work new file mode 100644 index 0000000..26eaaff --- /dev/null +++ b/go.work @@ -0,0 +1,6 @@ +go 1.20 + +use ( + ./common + ./system +) diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 0000000..d0ab226 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,316 @@ +cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go/accessapproval v1.5.0 h1:/nTivgnV/n1CaAeo+ekGexTYUsKEU9jUVkoY5359+3Q= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accesscontextmanager v1.4.0 h1:CFhNhU7pcD11cuDkQdrE6PQJgv0EXNKNv06jIzbLlCU= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/aiplatform v1.27.0 h1:DBi3Jk9XjCJ4pkkLM4NqKgj3ozUL1wq4l+d3/jTGXAI= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/analytics v0.12.0 h1:NKw6PpQi6V1O+KsjuTd+bhip9d0REYu4NevC45vtGp8= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/apigateway v1.4.0 h1:IIoXKR7FKrEAQhMTz5hK2wiDz2WNFHS7eVr/L1lE/rM= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigeeconnect v1.4.0 h1:AONoTYJviyv1vS4IkvWzq69gEVdvHx35wKXc+e6wjZQ= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/appengine v1.5.0 h1:lmG+O5oaR9xNwaRBwE2XoMhwQHsHql5IoiGr1ptdDwU= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/area120 v0.6.0 h1:TCMhwWEWhCn8d44/Zs7UCICTWje9j3HuV6nVGMjdpYw= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.9.0 h1:3d0LRAU1K6vfqCahhl9fx2oGHcq+s5gftdix4v8Ibrc= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/asset v1.10.0 h1:aCrlaLGJWTODJX4G56ZYzJefITKEWNfbjjtHSzWpxW0= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/assuredworkloads v1.9.0 h1:hhIdCOowsT1GG5eMCIA0OwK6USRuYTou/1ZeNxCSRtA= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/automl v1.8.0 h1:BMioyXSbg7d7xLibn47cs0elW6RT780IUWr42W8rp2Q= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/baremetalsolution v0.4.0 h1:g9KO6SkakcYPcc/XjAzeuUrEOXlYPnMpuiaywYaGrmQ= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/batch v0.4.0 h1:1jvEBY55OH4Sd2FxEXQfxGExFWov1A/IaRe+Z5Z71Fw= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/beyondcorp v0.3.0 h1:w+4kThysgl0JiKshi2MKDCg2NZgOyqOI0wq2eBZyrzA= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= +cloud.google.com/go/bigquery v1.44.0 h1:Wi4dITi+cf9VYp4VH2T9O41w0kCW0uQTELq2Z6tukN0= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/billing v1.7.0 h1:Xkii76HWELHwBtkQVZvqmSo9GTr0O+tIbRNnMcGdlg4= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/binaryauthorization v1.4.0 h1:pL70vXWn9TitQYXBWTK2abHl2JHLwkFRjYw6VflRqEA= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/certificatemanager v1.4.0 h1:tzbR4UHBbgsewMWUD93JHi8EBi/gHBoSAcY1/sThFGk= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/channel v1.9.0 h1:pNuUlZx0Jb0Ts9P312bmNMuH5IiFWIR4RUtLb70Ke5s= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/cloudbuild v1.4.0 h1:TAAmCmAlOJ4uNBu6zwAjwhyl/7fLHHxIEazVhr3QBbQ= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/clouddms v1.4.0 h1:UhzHIlgFfMr6luVYVNydw/pl9/U5kgtjCMJHnSvoVws= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/cloudtasks v1.8.0 h1:faUiUgXjW8yVZ7XMnKHKm1WE4OldPBUWWfIRN/3z1dc= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.4.0 h1:tTQLI/ZvguUf9Hv+36BkG2+/PeC8Ol1q4pBW+tgCx0A= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/container v1.7.0 h1:nbEK/59GyDRKKlo1SqpohY1TK8LmJ2XNcvS9Gyom2A0= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/containeranalysis v0.6.0 h1:2824iym832ljKdVpCBnpqm5K94YT/uHTVhNF+dRTXPI= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.8.0 h1:6kZ4RIOW/uT7QWC5SfPfq/G8sYzr/v+UOmOAxy4Z1TE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/dataflow v0.7.0 h1:CW3541Fm7KPTyZjJdnX6NtaGXYFn5XbFC5UcjgALKvU= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.5.0 h1:vLwowLF2ZB5J5gqiZCzv076lDI/Rd7zYQQFu5XO1PSg= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/datafusion v1.5.0 h1:j5m2hjWovTZDTQak4MJeXAR9yN7O+zMfULnjGw/OOLg= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datalabeling v0.6.0 h1:dp8jOF21n/7jwgo/uuA0RN8hvLcKO4q6s/yvwevs2ZM= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataplex v1.4.0 h1:cNxeA2DiWliQGi21kPRqnVeQ5xFhNoEjPRt1400Pm8Y= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataproc v1.8.0 h1:gVOqNmElfa6n/ccG/QDlfurMWwrK3ezvy2b2eDoCmS0= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataqna v0.6.0 h1:gx9jr41ytcA3dXkbbd409euEaWtofCVXYBvJz3iYm18= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.10.0 h1:4siQRf4zTiAVt/oeH4GureGkApgb2vtPQAtOmhpqQwE= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastream v1.5.0 h1:PgIgbhedBtYBU6POGXFMn2uSl9vpqubc3ewTNdcU8Mk= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/deploy v1.5.0 h1:kI6dxt8Ml0is/x7YZjLveTvR7YPzXAUD/8wQZ2nH5zA= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/dialogflow v1.19.0 h1:HYHVOkoxQ9bSfNIelSZYNAtUi4CeSrCnROyOsbOqPq8= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dlp v1.7.0 h1:9I4BYeJSVKoSKgjr70fLdRDumqcUeVmHV4fd5f9LR6Y= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/documentai v1.10.0 h1:jfq09Fdjtnpnmt/MLyf6A3DM3ynb8B2na0K+vSXvpFM= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/domains v0.7.0 h1:pu3JIgC1rswIqi5romW0JgNO6CTUydLYX8zyjiAvO1c= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.2.0 h1:hd6J2n5dBBRuAqnNUEsKWrp6XNPKsaxwwIyzOPZTokk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.4.0 h1:b6csrQXCHKQmfo9h3dG/pHyoEh+fQG1Yg78a53LAviY= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/eventarc v1.8.0 h1:AgCqrmMMIcel5WWKkzz5EkCUKC3Rl5LNMMYsS+LvsI0= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/filestore v1.4.0 h1:yjKOpzvqtDmL5AXbKttLc8j0hL20kuC1qPdy5HPcxp0= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.9.0 h1:35tgv1fQOtvKqH/uxJMzX3w6usneJ0zXpsFr9KAVhNE= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/gaming v1.8.0 h1:97OAEQtDazAJD7yh/kvQdSCQuTKdR0O+qWAJBZJ4xiA= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gkebackup v0.3.0 h1:4K+jiv4ocqt1niN8q5Imd8imRoXBHTrdnJVt/uFFxF4= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkeconnect v0.6.0 h1:zAcvDa04tTnGdu6TEZewaLN2tdMtUOJJ7fEceULjguA= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.10.0 h1:JTcTaYQRGsVm+qkah7WzHb6e9sf1C0laYdRPn9aN+vg= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkemulticloud v0.4.0 h1:8F1NhJj8ucNj7lK51UZMtAjSWTgP1zO18XF6vkfiPPU= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/gsuiteaddons v1.4.0 h1:TGT2oGmO5q3VH6SjcrlgPUWI0njhYv4kywLm6jag0to= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= +cloud.google.com/go/iam v0.8.0 h1:E2osAkZzxI/+8pZcxVLcDtAQx/u+hZXVryUaYQ5O0Kk= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iap v1.5.0 h1:BGEXovwejOCt1zDk8hXq0bOhhRu9haXKWXXXp2B4wBM= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/ids v1.2.0 h1:LncHK4HHucb5Du310X8XH9/ICtMwZ2PCfK0ScjWiJoY= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/iot v1.4.0 h1:Y9+oZT9jD4GUZzORXTU45XsnQrhxmDT+TFbPil6pRVQ= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/kms v1.6.0 h1:OWRZzrPmOZUzurjI2FBGtgY2mB1WaJkqhw6oIwSj0Yg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/language v1.8.0 h1:3Wa+IUMamL4JH3Zd3cDZUHpwyqplTACt6UZKRD2eCL4= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/lifesciences v0.6.0 h1:tIqhivE2LMVYkX0BLgG7xL64oNpDaFFI7teunglt1tI= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/logging v1.6.1 h1:ZBsZK+JG+oCDT+vaxwqF2egKNRjz8soXiS6Xv79benI= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/managedidentities v1.4.0 h1:3Kdajn6X25yWQFhFCErmKSYTSvkEd3chJROny//F1A0= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/maps v0.1.0 h1:kLReRbclTgJefw2fcCbdLPLhPj0U6UUWN10ldG8sdOU= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/mediatranslation v0.6.0 h1:qAJzpxmEX+SeND10Y/4868L5wfZpo4Y3BIEnIieP4dk= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.7.0 h1:yLxUzJkZVSH2kPaHut7k+7sbIBFpvSh1LW9qjM2JDjA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/metastore v1.8.0 h1:3KcShzqWdqxrDEXIBWpYJpOOrgpDj+HlBi07Grot49Y= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/monitoring v1.8.0 h1:c9riaGSPQ4dUKWB+M1Fl0N+iLxstMbCktdEwYSPGDvA= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/networkconnectivity v1.7.0 h1:BVdIKaI68bihnXGdCVL89Jsg9kq2kg+II30fjVqo62E= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkmanagement v1.5.0 h1:mDHA3CDW00imTvC5RW6aMGsD1bH+FtKwZm/52BxaiMg= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networksecurity v0.6.0 h1:qDEX/3sipg9dS5JYsAY+YvgTjPR63cozzAWop8oZS94= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.5.0 h1:AC8RPjNvel3ExgXjO1YOAz+teg9+j+89TNxa7pIZfww= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/optimization v1.2.0 h1:7PxOq9VTT7TMib/6dMoWpMvWS2E4dJEvtYzjvBreaec= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/orchestration v1.4.0 h1:39d6tqvNjd/wsSub1Bn4cEmrYcet5Ur6xpaN+SxOxtY= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orgpolicy v1.5.0 h1:erF5PHqDZb6FeFrUHiYj2JK2BMhsk8CyAg4V4amJ3rE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/osconfig v1.10.0 h1:NO0RouqCOM7M2S85Eal6urMSSipWwHU8evzwS+siqUI= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/oslogin v1.7.0 h1:pKGDPfeZHDybtw48WsnVLjoIPMi9Kw62kUE5TXCLCN4= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/phishingprotection v0.6.0 h1:OrwHLSRSZyaiOt3tnY33dsKSedxbMzsXvqB21okItNQ= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/policytroubleshooter v1.4.0 h1:NQklJuOUoz1BPP+Epjw81COx7IISWslkZubz/1i0UN8= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/privatecatalog v0.6.0 h1:Vz86uiHCtNGm1DeC32HeG2VXmOq5JRYA3VRPf8ZEcSg= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/pubsub v1.27.1 h1:q+J/Nfr6Qx4RQeu3rJcnN48SNC0qzlYzSeqkPq93VHs= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsublite v1.5.0 h1:iqrD8vp3giTb7hI1q4TQQGj77cj8zzgmMPsTZtLnprM= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0 h1:UqzFfb/WvhwXGDF1eQtdHLrmni+iByZXY4h3w9Kdyv8= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recommendationengine v0.6.0 h1:6w+WxPf2LmUEqX0YyvfCoYb8aBYOcbIV25Vg6R0FLGw= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.8.0 h1:9kMZQGeYfcOD/RtZfcNKGKtoex3DdoB4zRgYU/WaIwE= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/redis v1.10.0 h1:/zTwwBKIAD2DEWTrXZp8WD9yD/gntReF/HkPssVYd0U= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/resourcemanager v1.4.0 h1:NDao6CHMwEZIaNsdWy+tuvHaavNeGP06o1tgrR0kLvU= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcesettings v1.4.0 h1:eTzOwB13WrfF0kuzG2ZXCfB3TLunSHBur4s+HFU6uSM= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/retail v1.11.0 h1:N9fa//ecFUOEPsW/6mJHfcapPV0wBSwIUwpVZB7MQ3o= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/run v0.3.0 h1:AWPuzU7Xtaj3Jf+QarDWIs6AJ5hM1VFQ+F6Q+VZ6OT4= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/scheduler v1.7.0 h1:K/mxOewgHGeKuATUJNGylT75Mhtjmx1TOkKukATqMT8= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/secretmanager v1.9.0 h1:xE6uXljAC1kCR8iadt9+/blg1fvSbmenlsDN4fT9gqw= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/security v1.10.0 h1:KSKzzJMyUoMRQzcz7azIgqAUqxo7rmQ5rYvimMhikqg= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/securitycenter v1.16.0 h1:QTVtk/Reqnx2bVIZtJKm1+mpfmwRwymmNvlaFez7fQY= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/servicecontrol v1.5.0 h1:ImIzbOu6y4jL6ob65I++QzvqgFaoAKgHOG+RU9/c4y8= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicedirectory v1.7.0 h1:f7M8IMcVzO3T425AqlZbP3yLzeipsBHtRza8vVFYMhQ= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicemanagement v1.5.0 h1:TpkCO5M7dhKSy1bKUD9o/sSEW/U1Gtx7opA1fsiMx0c= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/serviceusage v1.4.0 h1:b0EwJxPJLpavSljMQh0RcdHsUrr5DQ+Nelt/3BAs5ro= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/shell v1.4.0 h1:b1LFhFBgKsG252inyhtmsUUZwchqSz3WTvAIf3JFo4g= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/spanner v1.41.0 h1:NvdTpRwf7DTegbfFdPjAWyD7bOVu0VeMqcvR9aCQCAc= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/speech v1.9.0 h1:yK0ocnFH4Wsf0cMdUyndJQ/hPv02oTJOxzi6AgpBy4s= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= +cloud.google.com/go/storagetransfer v1.6.0 h1:fUe3OydbbvHcAYp07xY+2UpH4AermGbmnm7qdEj3tGE= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/talent v1.4.0 h1:MrekAGxLqAeAol4Sc0allOVqUGO8j+Iim8NMvpiD7tM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/texttospeech v1.5.0 h1:ccPiHgTewxgyAeCWgQWvZvrLmbfQSFABTMAfrSPLPyY= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/tpu v1.4.0 h1:ztIdKoma1Xob2qm6QwNh4Xi9/e7N3IfvtwG5AcNsj1g= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/trace v1.4.0 h1:qO9eLn2esajC9sxpqp1YKX37nXC3L4BfGnPS0Cx9dYo= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/translate v1.4.0 h1:AOYOH3MspzJ/bH1YXzB+xTE8fMpn3mwhLjugwGXvMPI= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/video v1.9.0 h1:ttlvO4J5c1VGq6FkHqWPD/aH6PfdxujHt+muTJlW1Zk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/videointelligence v1.9.0 h1:RPFgVVXbI2b5vnrciZjtsUgpNKVtHO/WIyXUhEfuMhA= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/vision/v2 v2.5.0 h1:TQHxRqvLMi19azwm3qYuDbEzZWmiKJNTpGbkNsfRCik= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vmmigration v1.3.0 h1:A2Tl2ZmwMRpvEmhV2ibISY85fmQR+Y5w9a0PlRz5P3s= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmwareengine v0.1.0 h1:JMPZaOT/gIUxVlTqSl/QQ32Y2k+r0stNeM1NSqhVP9o= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vpcaccess v1.5.0 h1:woHXXtnW8b9gLFdWO9HLPalAddBQ9V4LT+1vjKwR3W8= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/webrisk v1.7.0 h1:ypSnpGlJnZSXbN9a13PDmAYvVekBLnGKxQ3Q9SMwnYY= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/websecurityscanner v1.4.0 h1:y7yIFg/h/mO+5Y5aCOtVAnpGUOgqCH5rXQ2Oc8Oq2+g= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/workflows v1.9.0 h1:7Chpin9p50NTU8Tb7qk+I11U/IwVXmDhEoSsdccvInE= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= +github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= +github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b h1:ACGZRIr7HsgBKHsueQ1yM4WaVaXh21ynwqsF8M8tXhA= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/envoyproxy/go-control-plane v0.10.3 h1:xdCVXxEe0Y3FQith+0cj2irwZudqGYvecuLB1HtdexY= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/protoc-gen-validate v0.9.1 h1:PS7VIOgmSVhWUEeZwTe7z7zouA22Cr590PzXKbZHOVY= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= +github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b h1:NVD8gBK33xpdqCaZVVtd6OFJp+3dxkXuz7+U7KaVN6s= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= diff --git a/system/.dockerignore b/system/.dockerignore new file mode 100644 index 0000000..1043fed --- /dev/null +++ b/system/.dockerignore @@ -0,0 +1,17 @@ +.buildpath +.hgignore.swp +.project +.orig +.swp +.idea/ +.settings/ +.vscode/ + +**/*.md +**/*.txt +**/build + +doc/ +test/ + +**/*.tgz \ No newline at end of file diff --git a/system/.gitignore b/system/.gitignore new file mode 100644 index 0000000..bee3e6a --- /dev/null +++ b/system/.gitignore @@ -0,0 +1,17 @@ +.buildpath +.hgignore.swp +.project +.orig +.swp +.idea/ +.settings/ +.vscode/ +vender/ +gitpush.sh +bin/ +cbuild +*/.DS_Store +main +tmp/ +report/ +**/*.tgz \ No newline at end of file diff --git a/system/.golangci.yml b/system/.golangci.yml new file mode 100644 index 0000000..826e9ce --- /dev/null +++ b/system/.golangci.yml @@ -0,0 +1,118 @@ +# 运行环境 +run: + timeout: 10m + issues-exit-code: 0 + tests: true + # 不检测的目录列表,在vscode中虽然有错误提示,但不会出现在错误报告中 + skip-dirs: + - tapi + +# 检测输出 +output: + format: checkstyle + +# 检查配置 +linters-settings: + depguard: + list-type: blacklist + # 黑名单,列举公司禁用的组件 + packages: + # 黑名单错误提示 + packages-with-error-message: + # 函数检测(最大行数和声明最大长度) + funlen: + lines: 200 + statements: 80 + # 常量检测(出现指定次数的字符串使用常量表达) + goconst: + min-len: 3 + min-occurrences: 3 + # 诊断组件集 + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + - dupImport # https://github.com/go-critic/go-critic/issues/845 + - ifElseChain + - octalLiteral + - whyNoLint + - wrapperFunc + # 检测循环复杂度 + gocyclo: + min-complexity: 15 + # goimports配置需求 + goimports: + local-prefixes: github.com/golangci/golangci-lint + # golint最小置信度 + golint: + min-confidence: 1 + # 检测参数、条件语句和返回值 + gomnd: + settings: + mnd: + # don't include the "operation" and "assign" + checks: argument,case,condition,return + # 类型转换检测 + govet: + check-shadowing: true + settings: + printf: + funcs: + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf + - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf + # 代码长度检测 + lll: + line-length: 200 + # 拼写检测 + misspell: + locale: US + # 检测不规范或不充分的注释 + nolintlint: + allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space) + allow-unused: false # report any unused nolint directives + require-explanation: false # don't require an explanation for nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + +# 检测组件使能 +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + # 不能使能的组件 + # - asciicheck + # - gochecknoglobals + # - gocognit + # - godot + # - godox + # - goerr113 + # - maligned + # - nestif + # - prealloc + # - testpackage + # - wsl + +issues: + # equivalent CLI flag: --exclude-use-default + # + # see: + # atc0005/brick#92 + # golangci-lint/golangci-lint#1249 + # golangci-lint/golangci-lint#413 + exclude-use-default: false diff --git a/system/Dockerfile b/system/Dockerfile new file mode 100644 index 0000000..716733d --- /dev/null +++ b/system/Dockerfile @@ -0,0 +1,51 @@ +# Relying on Alpine go version 1.20 +FROM --platform=$TARGETPLATFORM golang:1.20-alpine AS builder +MAINTAINER jettjia + +# Pull private repo go-lib +RUN apk add --no-cache git +RUN echo "machine github.com login jettjia password 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" >> ~/.netrc + +ENV GO111MODULE=on \ + CGO_ENABLED=0 \ + GOOS=linux \ + GOARCH=amd64 \ + GOPROXY="https://goproxy.cn,direct" + +# 移动到工作目录:/build +WORKDIR /build + +# 复制项目中的 go.mod 和 go.sum文件并下载依赖信息 +COPY ../../go.mod . +COPY ../../go.sum . +RUN go mod download + +# 将代码复制到容器中 +COPY ../.. . + +# 将我们的代码编译成二进制可执行文件 GoDddDemo +RUN go build -o GoDddDemo . + +################### +# 接下来创建一个小镜像 +################### +FROM busybox +COPY --from=builder /build/GoDddDemo /GoDddDemo + +# 拷贝配置文件到容器中 +ENV WORKDIR /app +COPY ../../manifest/config $WORKDIR/manifest/config +ADD ../../manifest/i18n $WORKDIR/i18n + +# 暴露端口 +EXPOSE 21800 +EXPOSE 21801 +EXPOSE 21802 + +# 设置时区为上海 +RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime +RUN echo 'Asia/Shanghai' >/etc/timezone + +## 运行golang程序的命令 +WORKDIR $WORKDIR +ENTRYPOINT ["/GoDddDemo", "-env", "debug"] \ No newline at end of file diff --git a/system/Makefile b/system/Makefile new file mode 100644 index 0000000..2b67564 --- /dev/null +++ b/system/Makefile @@ -0,0 +1,70 @@ +PKG := "jettjia/go-ddd-demo" # go mod 项目名称 +PKG_LIST := $(shell go list ${PKG}/...) + +# docker +## 镜像仓库+镜像名称,其中jidi-docker.pkg.coding.net/gas/go-ddd-demo/ 是镜像仓库; demo 是镜像名称 +DOCKER_IMAGE_REPO := "jidi-docker.pkg.coding.net/gas/go-ddd-demo/demo:v1.0.0" +APP := "GoDddDemo" #go build后的可执行文件名称,和dockerfile保持一致 + +init: # 初始化安装 go的校验包 + @go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + @go install github.com/jstemmer/go-junit-report/v2@latest + @go install github.com/matm/gocov-html/cmd/gocov-html@latest + +.PHONY: tidy +tidy: + $(eval files=$(shell find . -name go.mod)) + @set -e; \ + for file in ${files}; do \ + goModPath=$$(dirname $$file); \ + cd $$goModPath; \ + go mod tidy; \ + cd -; \ + done + +.PHONY: fmt +fmt: + @go fmt ${PKG_LIST} + +.PHONY: generate +vet: ## generate the files + @go generate ./... + +.PHONY: test +test: + @go test -cover ./... + +.PHONY: race +race: ## Run tests with data race detector + @go test -race ${PKG_LIST} + +.PHONY: test-coverage +test-coverage: ## Generate a single test report file in HTML format + @go test ./... -v -coverprofile=report/cover 2>&1 | go-junit-report > report/ut_report.xml + @gocov convert report/cover | gocov-html > report/coverage.html + +.PHONY: golangci +golangci: + @golangci-lint run --config .golangci.yml + +.PHONY: build +build: + @go build -o ${APP} + +.PHONY: docker-build +docker-build: ## docker-build build项目镜像 + @docker build -t ${DOCKER_IMAGE_REPO} . + +.PHONY: docker-push +docker-push: ## docker-push push项目镜像到远程仓库 + @docker push ${DOCKER_IMAGE_REPO} + +.PHONY: helm-build +helm-build: ## 打包helm + @cd ${HELM_TEMP_DIR} \ + && tar zcvf ${HELM_IMAGE} ${HELM_DIR} + +.PHONY: helm-push +helm-push: ## 推送helm到远程仓库 + @cd ${HELM_TEMP_DIR} \ + && helm push ${HELM_IMAGE} ${HELM_IMAGE_REPO} \ No newline at end of file diff --git a/system/README.md b/system/README.md new file mode 100644 index 0000000..bfb4976 --- /dev/null +++ b/system/README.md @@ -0,0 +1,2 @@ +# system +系统模块 \ No newline at end of file diff --git a/system/application/assembler/ps.go b/system/application/assembler/ps.go new file mode 100644 index 0000000..f5492b1 --- /dev/null +++ b/system/application/assembler/ps.go @@ -0,0 +1,5 @@ +package assembler + +import "github.com/google/wire" + +var AsseProviderSet = wire.NewSet(NewSysMenuReq, NewSysMenuRsp) diff --git a/system/application/assembler/sys_menu_req.go b/system/application/assembler/sys_menu_req.go new file mode 100644 index 0000000..9f65cdb --- /dev/null +++ b/system/application/assembler/sys_menu_req.go @@ -0,0 +1,47 @@ +package assembler + +import ( + "github.com/jinzhu/copier" + + "jettjia/go-ddd-demo-multi-system/application/dto" + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +// SysMenuReq 请求参数 +type SysMenuReq struct { +} + +// NewSysMenuReq NewUSysMenuReq +func NewSysMenuReq() *SysMenuReq { + return &SysMenuReq{} +} + +// D2ECreateSysMenu dto转换成entity +func (a *SysMenuReq) D2ECreateSysMenu(dto *dto.CreateSysMenuReq) *entity.SysMenu { + var rspEn entity.SysMenu + + if err := copier.Copy(&rspEn, &dto); err != nil { + panic(any(err)) + } + + return &rspEn +} + +// D2EDeleteSysMenu dto转换成entity +func (a *SysMenuReq) D2EDeleteSysMenu(dto *dto.DelSysMenusReq) *entity.SysMenu { + var rspEn entity.SysMenu + + rspEn.Ulid = dto.Ulid + + return &rspEn +} + +// D2EUpdateSysMenu dto转换成entity +func (a *SysMenuReq) D2EUpdateSysMenu(dto *dto.UpdateSysMenuReq) *entity.SysMenu { + var rspEn entity.SysMenu + + if err := copier.Copy(&rspEn, &dto); err != nil { + panic(any(err)) + } + return &rspEn +} diff --git a/system/application/assembler/sys_menu_rsp.go b/system/application/assembler/sys_menu_rsp.go new file mode 100644 index 0000000..38c9048 --- /dev/null +++ b/system/application/assembler/sys_menu_rsp.go @@ -0,0 +1,50 @@ +package assembler + +import ( + "github.com/jinzhu/copier" + + "jettjia/go-ddd-demo-multi-system/application/dto" + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +// SysMenuRsp 请求参数 +type SysMenuRsp struct { +} + +// NewSysMenuRsp NewUSysMenuRsp +func NewSysMenuRsp() *SysMenuRsp { + return &SysMenuRsp{} +} + +// D2ECreateSysMenu dto转换成entity +func (a *SysMenuRsp) D2ECreateSysMenu(en *entity.SysMenu) (dto *dto.CreateSysMenuRsp) { + dto.Ulid = en.Ulid + + return +} + +// E2DFindSysMenuRsp entity转换成dto +func (a *SysMenuRsp) E2DFindSysMenuRsp(en *entity.SysMenu) *dto.FindSysMenuRsp { + var rspDto dto.FindSysMenuRsp + + if err := copier.Copy(&rspDto, &en); err != nil { + panic(any(err)) + } + + return &rspDto +} + +// E2DGetSysMenus entity转换成dto +func (a *SysMenuRsp) E2DGetSysMenus(ens []*entity.SysMenu) []*dto.FindSysMenuRsp { + if len(ens) == 0 { + return []*dto.FindSysMenuRsp{} + } + + var SysMenusRsp []*dto.FindSysMenuRsp + for _, v := range ens { + cfg := a.E2DFindSysMenuRsp(v) + SysMenusRsp = append(SysMenusRsp, cfg) + } + + return SysMenusRsp +} diff --git a/system/application/dto/sys_menu_dto.go b/system/application/dto/sys_menu_dto.go new file mode 100644 index 0000000..ef200d3 --- /dev/null +++ b/system/application/dto/sys_menu_dto.go @@ -0,0 +1,92 @@ +package dto + +import "jettjia/go-ddd-demo-multi-common/types" + +// 请求对象 +type ( + // CreateSysMenuReq 创建SysMenu 请求对象 + CreateSysMenuReq struct { + CreatedBy string `json:"created_by"` // 创建者 + MenuName string `validate:"required,min=1,max=4" err_info:"长度在1-4个字符" json:"menu_name"` // menu名称 【校验说明:肯定会校验,长度在1-4】 + Desc string `validate:"omitempty,min=1,max=32" json:"desc"` // 描述 【校验说明:有就会校验,长度在1-32】 + Route string `validate:"required,checkSpecialChar" json:"route"` // 菜单路由 【校验说明:自定义校验规则】 + State uint `validate:"required,oneof=1 2" json:"state"` // 1显示,2否 【校验说明:肯定校验,并且值只能是1或者2】 + Pid string `json:"pid"` // 父id + Pname string `json:"pname"` // 父路由名称 + SortOrder int `json:"sort_order"` // 排序 + BackendType int `json:"backend_type"` // 1总后台,2运营后台 + } + + // DelSysMenusReq 删除 请求对象 + DelSysMenusReq struct { + Ulid string `validate:"required" uri:"ulid" json:"ulid"` // ID + DeletedBy string `json:"deleted_by"` // 删除者 + } + + // UpdateSysMenuReq 修改SysMenu 请求对象 + UpdateSysMenuReq struct { + Ulid string `validate:"required" uri:"ulid" json:"ulid"` // ID + UpdatedBy string `json:"updated_by"` // 修改者 + MenuName string `json:"menu_name"` // menu名称 + Desc string `json:"desc"` // 描述 + Route string `json:"route"` // 菜单路由 + State uint `json:"state"` // 1显示,2否 + Pid string `json:"pid"` // 父id + Pname string `json:"pname"` // 父路由名称 + SortOrder int `json:"sort_order"` // 排序 + BackendType int `json:"backend_type"` // 1总后台,2运营后台 + } + + // FindSysMenuByIdReq 查询 请求对象 + FindSysMenuByIdReq struct { + Ulid string ` validate:"required" uri:"ulid" json:"ulid"` // ID + } + + // FindSysMenuByQueryReq 查询 请求对象 + FindSysMenuByQueryReq struct { + Query []*types.Query `json:"query"` + } + + // FindSysMenuAllReq 查询 请求对象 + FindSysMenuAllReq struct { + Query []*types.Query `json:"query"` + } + + // FindSysMenuPageReq 分页查询 请求对象 + FindSysMenuPageReq struct { + Query []*types.Query `json:"query"` + PageData *types.PageData `json:"page_data"` + SortData *types.SortData `json:"sort_data"` + } +) + +// 输出对象 +type ( + // CreateSysMenuRsp 创建SysMenu 返回对象 + CreateSysMenuRsp struct { + Ulid string `json:"ulid"` // ID + } + + // FindSysMenuPageRsp 列表查询 返回对象 + FindSysMenuPageRsp struct { + Entries []*FindSysMenuRsp `json:"entries"` + PageData *types.PageData `json:"page_data"` + } + + // FindSysMenuRsp 查询SysMenu 返回对象 + FindSysMenuRsp struct { + Ulid string `json:"ulid"` // ID + CreatedAt int64 `json:"created_at"` // 创建时间 + UpdatedAt int64 `json:"updated_at"` // 修改时间 + CreatedBy string `json:"created_by"` // 创建者 + UpdatedBy string `json:"updated_by"` // 修改者 + MenuName string `json:"menu_name"` // menu名称 + Desc string `json:"desc"` // 描述 + Route string `json:"route"` // 菜单路由 + State uint `json:"state"` // 1显示,2否 + Pid string `json:"pid"` // 父id + Pname string `json:"pname"` // 父路由名称 + SortOrder int `json:"sort_order"` // 排序 + BackendType int `json:"backend_type"` // 1总后台,2运营后台 + } +) diff --git a/system/application/service/ps.go b/system/application/service/ps.go new file mode 100644 index 0000000..382046b --- /dev/null +++ b/system/application/service/ps.go @@ -0,0 +1,5 @@ +package service + +import "github.com/google/wire" + +var ServiceProviderSet = wire.NewSet(NewSysMenuService) diff --git a/system/application/service/sys_menu_svc.go b/system/application/service/sys_menu_svc.go new file mode 100644 index 0000000..b410f8c --- /dev/null +++ b/system/application/service/sys_menu_svc.go @@ -0,0 +1,98 @@ +package service + +import ( + "context" + + "jettjia/go-ddd-demo-multi-system/application/assembler" + "jettjia/go-ddd-demo-multi-system/application/dto" + "jettjia/go-ddd-demo-multi-system/domain/aggregate" + "jettjia/go-ddd-demo-multi-system/domain/srv" +) + +type SysMenuService struct { + sysMenuReq *assembler.SysMenuReq + sysMenuRsp *assembler.SysMenuRsp + sysMenuAgg *aggregate.SysMenu + sysMenuSvc *srv.SysMenu +} + +func NewSysMenuService(sysMenuReq *assembler.SysMenuReq, sysMenuRsp *assembler.SysMenuRsp, sysMenuAgg *aggregate.SysMenu, sysMenuSvc *srv.SysMenu) *SysMenuService { + return &SysMenuService{ + sysMenuReq: sysMenuReq, + sysMenuRsp: sysMenuRsp, + sysMenuAgg: sysMenuAgg, + sysMenuSvc: sysMenuSvc, + } +} + +func (s *SysMenuService) CreateSysMenu(ctx context.Context, req *dto.CreateSysMenuReq) (*dto.CreateSysMenuRsp, error) { + var rsp dto.CreateSysMenuRsp + en := s.sysMenuReq.D2ECreateSysMenu(req) + + ulid, err := s.sysMenuAgg.CreateSysMenu(ctx, en) + if err != nil { + return nil, err + } + rsp.Ulid = ulid + + return &rsp, nil +} + +func (s *SysMenuService) DeleteSysMenu(ctx context.Context, req *dto.DelSysMenusReq) error { + en := s.sysMenuReq.D2EDeleteSysMenu(req) + + return s.sysMenuAgg.DeleteSysMenu(ctx, en) +} + +func (s *SysMenuService) UpdateSysMenu(ctx context.Context, req *dto.UpdateSysMenuReq) error { + en := s.sysMenuReq.D2EUpdateSysMenu(req) + + return s.sysMenuAgg.UpdateSysMenu(ctx, en) +} + +func (s *SysMenuService) FindSysMenuById(ctx context.Context, req *dto.FindSysMenuByIdReq) (dto *dto.FindSysMenuRsp, err error) { + en, err := s.sysMenuSvc.FindSysMenuById(ctx, req.Ulid) + if err != nil { + return nil, err + } + + dto = s.sysMenuRsp.E2DFindSysMenuRsp(en) + + return dto, nil +} + +func (s *SysMenuService) FindSysMenuByQuery(ctx context.Context, req *dto.FindSysMenuByQueryReq) (dto *dto.FindSysMenuRsp, err error) { + en, err := s.sysMenuSvc.FindSysMenuByQuery(ctx, req.Query) + if err != nil { + return nil, err + } + + dto = s.sysMenuRsp.E2DFindSysMenuRsp(en) + + return dto, nil +} + +func (s *SysMenuService) FindSysMenuAll(ctx context.Context, req *dto.FindSysMenuAllReq) (entries []*dto.FindSysMenuRsp, err error) { + ens, err := s.sysMenuSvc.FindSysMenuAll(ctx, req.Query) + if err != nil { + return nil, err + } + + entries = s.sysMenuRsp.E2DGetSysMenus(ens) + + return entries, nil +} + +func (s *SysMenuService) FindSysMenuPage(ctx context.Context, req *dto.FindSysMenuPageReq) (*dto.FindSysMenuPageRsp, error) { + var rsp dto.FindSysMenuPageRsp + ens, pageData, err := s.sysMenuSvc.FindSysMenuPage(ctx, req.Query, req.PageData, req.SortData) + if err != nil { + return nil, err + } + + entries := s.sysMenuRsp.E2DGetSysMenus(ens) + rsp.Entries = entries + rsp.PageData = pageData + + return &rsp, nil +} diff --git a/system/cmd/server.go b/system/cmd/server.go new file mode 100644 index 0000000..7ce8951 --- /dev/null +++ b/system/cmd/server.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "jettjia/go-ddd-demo-multi-common/pkg/conf" + "jettjia/go-ddd-demo-multi-system/application/service" +) + +type Server struct { + Cfg *conf.Config + Sys *service.SysMenuService +} + +func NewServer(sys *service.SysMenuService, cfg *conf.Config) *Server { + return &Server{ + Cfg: cfg, + Sys: sys, + } +} diff --git a/system/cmd/wire.go b/system/cmd/wire.go new file mode 100644 index 0000000..cb09368 --- /dev/null +++ b/system/cmd/wire.go @@ -0,0 +1,31 @@ +//go:build wireinject +// +build wireinject + +package cmd + +import ( + "github.com/google/wire" + + "jettjia/go-ddd-demo-multi-system/application/assembler" + "jettjia/go-ddd-demo-multi-system/application/service" + "jettjia/go-ddd-demo-multi-system/config" + "jettjia/go-ddd-demo-multi-system/domain/aggregate" + "jettjia/go-ddd-demo-multi-system/domain/srv" + "jettjia/go-ddd-demo-multi-system/infra/repository/repo" +) + +//go:generate wire +func InitServer() (*Server, error) { + panic(wire.Build( + config.CfgProvider, + + repo.RepoProviderSet, + aggregate.AggProviderSet, + srv.SvcProviderSet, + assembler.AsseProviderSet, + service.ServiceProviderSet, + + NewServer, + ), + ) +} diff --git a/system/cmd/wire_gen.go b/system/cmd/wire_gen.go new file mode 100644 index 0000000..797a2af --- /dev/null +++ b/system/cmd/wire_gen.go @@ -0,0 +1,41 @@ +// Code generated by Wire. DO NOT EDIT. + +//go:generate go run github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject + +package cmd + +import ( + "jettjia/go-ddd-demo-multi-common/pkg/data" + "jettjia/go-ddd-demo-multi-system/application/assembler" + "jettjia/go-ddd-demo-multi-system/application/service" + "jettjia/go-ddd-demo-multi-system/config" + "jettjia/go-ddd-demo-multi-system/domain/aggregate" + "jettjia/go-ddd-demo-multi-system/domain/srv" + "jettjia/go-ddd-demo-multi-system/infra/repository/repo" +) + +// Injectors from wire.go: + +//go:generate wire +func InitServer() (*Server, error) { + sysMenuReq := assembler.NewSysMenuReq() + sysMenuRsp := assembler.NewSysMenuRsp() + confConfig := config.NewConfig() + db := repo.NewDB(confConfig) + universalClient := repo.NewRedis(confConfig) + client := repo.NewRocksCache(universalClient) + dataData, err := data.NewData(db, universalClient, client) + if err != nil { + return nil, err + } + transaction := data.NewTransaction(dataData) + sysMenu := repo.NewSysMenuImpl(dataData) + sysLog := repo.NewSysLogImpl(dataData) + aggregateSysMenu := aggregate.NewSysMenuAgg(transaction, sysMenu, sysLog) + srvSysMenu := srv.NewSysMenuSvc(sysMenu) + sysMenuService := service.NewSysMenuService(sysMenuReq, sysMenuRsp, aggregateSysMenu, srvSysMenu) + server := NewServer(sysMenuService, confConfig) + return server, nil +} diff --git a/system/config/config.go b/system/config/config.go new file mode 100644 index 0000000..fd593c7 --- /dev/null +++ b/system/config/config.go @@ -0,0 +1,45 @@ +package config + +import ( + "flag" + "os" + "sync" + + "github.com/google/wire" + + "jettjia/go-ddd-demo-multi-common/pkg/conf" +) + +var CfgProvider = wire.NewSet(NewConfig) + +func NewConfig() (conf *conf.Config) { + conf = initConfig() + return +} + +var ( + configOnce sync.Once + cfg *conf.Config +) + +// InitConfig 读取配置 +func initConfig() *conf.Config { + env := os.Getenv("env") + + if len(env) == 0 { + env = "debug" + } + configOnce.Do(func() { + + file := "./manifest/config/config-" + env + ".yaml" + + cfg = &conf.Config{} + flag.Set("conf", file) + if err := conf.ParseYaml(cfg); err != nil { + panic(err) + return + } + }) + + return cfg +} diff --git a/system/domain/aggregate/ps.go b/system/domain/aggregate/ps.go new file mode 100644 index 0000000..496c76c --- /dev/null +++ b/system/domain/aggregate/ps.go @@ -0,0 +1,5 @@ +package aggregate + +import "github.com/google/wire" + +var AggProviderSet = wire.NewSet(NewSysMenuAgg) diff --git a/system/domain/aggregate/sys_menu_agg.go b/system/domain/aggregate/sys_menu_agg.go new file mode 100644 index 0000000..5826a8b --- /dev/null +++ b/system/domain/aggregate/sys_menu_agg.go @@ -0,0 +1,86 @@ +package aggregate + +import ( + "context" + "jettjia/go-ddd-demo-multi-common/pkg/data" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + "jettjia/go-ddd-demo-multi-system/infra/repository/repo" +) + +// SysMenuAgg sys_menu_agg +// +//go:generate mockgen --source ./sys_menu_agg.go --destination ./mock/mock_sys_menu_agg.go --package mock +type SysMenuAgg interface { + CreateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (ulid string, err error) // 创建 + DeleteSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) // 删除 + UpdateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) // 修改 +} + +type SysMenu struct { + tx data.Transaction + sysMenuRepo *repo.SysMenu + sysLogRepo *repo.SysLog +} + +func NewSysMenuAgg(tx data.Transaction, sysMenuRepo *repo.SysMenu, sysLogRepo *repo.SysLog) *SysMenu { + return &SysMenu{ + tx: tx, + sysMenuRepo: sysMenuRepo, + sysLogRepo: sysLogRepo, + } +} + +func (a *SysMenu) CreateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (ulid string, err error) { + + var ( + sysLogEn entity.SysLog + ) + + // 调用事务实例 + err = a.tx.ExecTx(ctx, func(ctx context.Context) error { + ulid, err = a.sysMenuRepo.Create(ctx, sysMenuEn) + if err != nil { + return err + } + + sysLogEn.CreatedBy = sysMenuEn.CreatedBy + sysLogEn.Msg = "SysMenu.Create" + ",ulid" + ulid + _, err = a.sysLogRepo.Create(ctx, &sysLogEn) + + return err + }) + + return +} + +func (a *SysMenu) DeleteSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) { + if err = a.sysMenuRepo.Delete(ctx, sysMenuEn); err != nil { + return err + } + var ( + sysLogEn entity.SysLog + ) + + sysLogEn.CreatedBy = sysMenuEn.DeletedBy + sysLogEn.Msg = "SysMenu.Delete" + _, err = a.sysLogRepo.Create(ctx, &sysLogEn) + + return +} + +func (a *SysMenu) UpdateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) { + if err = a.sysMenuRepo.Update(ctx, sysMenuEn); err != nil { + return err + } + + var ( + sysLogEn entity.SysLog + ) + + sysLogEn.CreatedBy = sysMenuEn.UpdatedBy + sysLogEn.Msg = "SysMenu.Update" + _, err = a.sysLogRepo.Create(ctx, &sysLogEn) + + return +} diff --git a/system/domain/entity/jwt.go b/system/domain/entity/jwt.go new file mode 100644 index 0000000..f60272c --- /dev/null +++ b/system/domain/entity/jwt.go @@ -0,0 +1,108 @@ +package entity + +import ( + "github.com/pkg/errors" + "strings" + "time" + + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v4" +) + +var jwtSecret = []byte("wUk7E@fwowuyek") + +// CustomerInfo 返回给前端的数据内容 +type CustomerInfo struct { + UserId uint64 `json:"user_id"` // ID + Phone string `json:"phone"` // 手机号码 + Username string `json:"username"` // username +} + +// CustomClaims jwtClaims定义 +type CustomClaims struct { + *jwt.StandardClaims + TokenType string + CustomerInfo +} + +// Token 返回给客户端的token内容 +type Token struct { + AccessToken string `json:"access_token"` // token + ExpiresIn int64 `json:"expires_in"` // 过期时间 + Username string `json:"username"` // 用户名 + Phone string `json:"phone"` // 手机号码 + UserId uint64 `json:"user_id"` // 用户id +} + +// CreateToken 获取jwt token +func CreateToken(info CustomerInfo) (*Token, error) { + expiresAt := time.Now().Add(time.Minute * 60).Unix() + + claims := &CustomClaims{ + &jwt.StandardClaims{ + + ExpiresAt: expiresAt, + Issuer: "GasPc", + }, + "level1", + info, + } + + tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + + jwtTokenStr, err := tokenClaims.SignedString(jwtSecret) //该方法内部生成签名字符串,再用于获取完整、已签名的token + + var token Token + if err != nil { + return &token, err + } + + token.AccessToken = jwtTokenStr + token.ExpiresIn = expiresAt + token.Username = info.Username + token.Phone = info.Phone + token.UserId = info.UserId + + return &token, nil +} + +// ParseToken token 校验 +func ParseToken(tokenString string) (*CustomClaims, error) { + //用于解析鉴权的声明,方法内部主要是具体的解码和校验的过程,最终返回*Token + tokenClaims, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { + return jwtSecret, nil + }) + + if tokenClaims != nil { + // 从tokenClaims中获取到Claims对象,并使用断言,将该对象转换为我们自己定义的Claims + // 要传入指针,项目中结构体都是用指针传递,节省空间。 + if claims, ok := tokenClaims.Claims.(*CustomClaims); ok && tokenClaims.Valid { + return claims, nil + } + } + return nil, err +} + +func GinParse(c *gin.Context) (*CustomClaims, error) { + auth := c.GetHeader("Authorization") + token := strings.TrimPrefix(auth, "Bearer ") + + if token == "" { + return nil, errors.New("Parsing Bearer Token failed") + } + + //用于解析鉴权的声明,方法内部主要是具体的解码和校验的过程,最终返回*Token + tokenClaims, err := jwt.ParseWithClaims(token, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { + return jwtSecret, nil + }) + + if tokenClaims != nil { + // 从tokenClaims中获取到Claims对象,并使用断言,将该对象转换为我们自己定义的Claims + // 要传入指针,项目中结构体都是用指针传递,节省空间。 + if claims, ok := tokenClaims.Claims.(*CustomClaims); ok && tokenClaims.Valid { + return claims, nil + } + } + + return nil, err +} diff --git a/system/domain/entity/sys_log_entity.go b/system/domain/entity/sys_log_entity.go new file mode 100644 index 0000000..b3f46a5 --- /dev/null +++ b/system/domain/entity/sys_log_entity.go @@ -0,0 +1,8 @@ +package entity + +type SysLog struct { + Ulid string `json:"ulid"` // ulid + CreatedAt int64 `json:"created_at"` // 创建时间 + CreatedBy string `json:"created_by"` // 创建者 + Msg string `json:"msg"` // msg +} diff --git a/system/domain/entity/sys_menu_entity.go b/system/domain/entity/sys_menu_entity.go new file mode 100644 index 0000000..8ddc914 --- /dev/null +++ b/system/domain/entity/sys_menu_entity.go @@ -0,0 +1,19 @@ +package entity + +type SysMenu struct { + Ulid string `json:"ulid"` // ulid + CreatedAt int64 `json:"created_at"` // 创建时间 + UpdatedAt int64 `json:"updated_at"` // 修改时间 + DeletedAt int64 `json:"deleted_at"` // 删除时间 + CreatedBy string `json:"created_by"` // 创建者 + UpdatedBy string `json:"updated_by"` // 修改者 + DeletedBy string `json:"deleted_by"` // 删除者 + MenuName string `json:"menu_name"` // menu名称 + Desc string `json:"desc"` // 描述 + Route string `json:"route"` // 菜单路由 + State uint `json:"state"` // 1显示,2否 + Pid string `json:"pid"` // 父id + Pname string `json:"pname"` // 父路由名称 + SortOrder int `json:"sort_order"` // 排序 + BackendType int `json:"backend_type"` // 1总后台,2运营后台 +} diff --git a/system/domain/event/.gitkeep b/system/domain/event/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/system/domain/irepository/i_sys_log_repo.go b/system/domain/irepository/i_sys_log_repo.go new file mode 100644 index 0000000..66c0b1c --- /dev/null +++ b/system/domain/irepository/i_sys_log_repo.go @@ -0,0 +1,25 @@ +package irepository + +import ( + "context" + + "jettjia/go-ddd-demo-multi-common/types" + + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +// ISysLogRepo sys_log +// +//go:generate mockgen --source ./i_sys_log_repo.go --destination ./mock/mock_i_sys_log_repo.go --package mock +type ISysLogRepo interface { + Create(ctx context.Context, sysLogEn *entity.SysLog) (ulid string, err error) // 创建 + Delete(ctx context.Context, sysLogEn *entity.SysLog) (err error) // 删除 + Update(ctx context.Context, sysLogEn *entity.SysLog) (err error) // 修改 + FindById(ctx context.Context, ulid string) (sysLogEn *entity.SysLog, err error) // 查看byId + FindByQuery(ctx context.Context, queries []*types.Query) (sysLogEn *entity.SysLog, err error) // 查看byQuery + FindAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysLog, err error) // 所有 + FindPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) ([]*entity.SysLog, *types.PageData, error) // 列表 + ExecSql(ctx context.Context, sql string) error // 执行sql + FindOneExecSql(ctx context.Context, sql string) (sysLogEn *entity.SysLog, err error) // 原生sql查询单个 + FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysLog, err error) // 原生sql查询多个 +} diff --git a/system/domain/irepository/i_sys_menu_repo.go b/system/domain/irepository/i_sys_menu_repo.go new file mode 100644 index 0000000..773f20e --- /dev/null +++ b/system/domain/irepository/i_sys_menu_repo.go @@ -0,0 +1,24 @@ +package irepository + +import ( + "context" + + "jettjia/go-ddd-demo-multi-common/types" + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +// ISysMenuRepo sys_menu +// +//go:generate mockgen --source ./i_sys_menu_repo.go --destination ./mock/mock_i_sys_menu_repo.go --package mock +type ISysMenuRepo interface { + Create(ctx context.Context, sysMenuEn *entity.SysMenu) (ulid string, err error) // 创建 + Delete(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) // 删除 + Update(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) // 修改 + FindById(ctx context.Context, ulid string) (sysMenuEn *entity.SysMenu, err error) // 查看byId + FindByQuery(ctx context.Context, queries []*types.Query) (sysMenuEn *entity.SysMenu, err error) // 查看byQuery + FindAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysMenu, err error) // 所有 + FindPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) ([]*entity.SysMenu, *types.PageData, error) // 列表 + ExecSql(ctx context.Context, sql string) error // 执行sql + FindOneExecSql(ctx context.Context, sql string) (sysMenuEn *entity.SysMenu, err error) // 原生sql查询单个 + FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysMenu, err error) // 原生sql查询多个 +} diff --git a/system/domain/srv/ps.go b/system/domain/srv/ps.go new file mode 100644 index 0000000..7f2c52b --- /dev/null +++ b/system/domain/srv/ps.go @@ -0,0 +1,5 @@ +package srv + +import "github.com/google/wire" + +var SvcProviderSet = wire.NewSet(NewSysMenuSvc, NewSysLogSvc) diff --git a/system/domain/srv/sys_log_svc.go b/system/domain/srv/sys_log_svc.go new file mode 100644 index 0000000..5ff2c76 --- /dev/null +++ b/system/domain/srv/sys_log_svc.go @@ -0,0 +1,76 @@ +package srv + +import ( + "context" + + "jettjia/go-ddd-demo-multi-common/types" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + "jettjia/go-ddd-demo-multi-system/infra/repository/repo" +) + +// SysLogSvc sys_log_svc +// +//go:generate mockgen --source ./sys_log_svc.go --destination ./mock/mock_sys_log_svc.go --package mock +type SysLogSvc interface { + CreateSysLog(ctx context.Context, sysLogEn *entity.SysLog) (ulid string, err error) // 创建 + DeleteSysLog(ctx context.Context, sysLogEn *entity.SysLog) (err error) // 删除 + UpdateSysLog(ctx context.Context, sysLogEn *entity.SysLog) (err error) // 修改 + FindSysLogById(ctx context.Context, ulid string) (sysLogEn *entity.SysLog, err error) // 查看byId + FindSysLogByQuery(ctx context.Context, queries []*types.Query) (sysLogEn *entity.SysLog, err error) // 查看byQuery + FindSysLogAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysLog, err error) // 所有 + FindSysLogPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) (entries []*entity.SysLog, pageData *types.PageData, err error) // 列表 + ExecSql(ctx context.Context, sql string) error // 执行sql + FindOneExecSql(sql string) (ctx context.Context, sysLogEn *entity.SysLog, err error) // 原生sql查询单个 + FindManyExecSql(sql string) (ctx context.Context, entries []*entity.SysLog, err error) // 原生sql查询多个 +} + +type SysLog struct { + sysLogRepo *repo.SysLog +} + +func NewSysLogSvc(sysLogRepo *repo.SysLog) *SysLog { + return &SysLog{ + sysLogRepo: sysLogRepo, + } +} + +func (a *SysLog) CreateSysLog(ctx context.Context, sysLogEn *entity.SysLog) (ulid string, err error) { + return a.sysLogRepo.Create(ctx, sysLogEn) +} + +func (a *SysLog) DeleteSysLog(ctx context.Context, sysLogEn *entity.SysLog) (err error) { + return a.sysLogRepo.Delete(ctx, sysLogEn) +} + +func (a *SysLog) UpdateSysLog(ctx context.Context, sysLogEn *entity.SysLog) (err error) { + return a.sysLogRepo.Update(ctx, sysLogEn) +} + +func (a *SysLog) FindSysLogById(ctx context.Context, ulid string) (sysLogEn *entity.SysLog, err error) { + return a.sysLogRepo.FindById(ctx, ulid) +} + +func (a *SysLog) FindSysLogByQuery(ctx context.Context, queries []*types.Query) (sysLogEn *entity.SysLog, err error) { + return a.sysLogRepo.FindByQuery(ctx, queries) +} + +func (a *SysLog) FindSysLogAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysLog, err error) { + return a.sysLogRepo.FindAll(ctx, queries) +} + +func (a *SysLog) FindSysLogPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) (entries []*entity.SysLog, pageData *types.PageData, err error) { + return a.sysLogRepo.FindPage(ctx, queries, reqPage, reqSort) +} + +func (a *SysLog) ExecSql(ctx context.Context, sql string) error { + return a.sysLogRepo.ExecSql(ctx, sql) +} + +func (a *SysLog) FindOneExecSql(ctx context.Context, sql string) (sysLogEn *entity.SysLog, err error) { + return a.sysLogRepo.FindOneExecSql(ctx, sql) +} + +func (a *SysLog) FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysLog, err error) { + return a.sysLogRepo.FindManyExecSql(ctx, sql) +} diff --git a/system/domain/srv/sys_menu_svc.go b/system/domain/srv/sys_menu_svc.go new file mode 100644 index 0000000..0cf191e --- /dev/null +++ b/system/domain/srv/sys_menu_svc.go @@ -0,0 +1,76 @@ +package srv + +import ( + "context" + + "jettjia/go-ddd-demo-multi-common/types" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + "jettjia/go-ddd-demo-multi-system/infra/repository/repo" +) + +// SysMenuSvc sys_menu_svc +// +//go:generate mockgen --source ./sys_menu_svc.go --destination ./mock/mock_sys_menu_svc.go --package mock +type SysMenuSvc interface { + CreateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (ulid string, err error) // 创建 + DeleteSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) // 删除 + UpdateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) // 修改 + FindSysMenuById(ctx context.Context, ulid string) (sysMenuEn *entity.SysMenu, err error) // 查看byId + FindSysMenuByQuery(ctx context.Context, queries []*types.Query) (sysMenuEn *entity.SysMenu, err error) // 查看byQuery + FindSysMenuAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysMenu, err error) // 所有 + FindSysMenuPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) (entries []*entity.SysMenu, pageData *types.PageData, err error) // 列表 + ExecSql(ctx context.Context, sql string) error // 执行sql + FindOneExecSql(ctx context.Context, sql string) (sysMenuEn *entity.SysMenu, err error) // 原生sql查询单个 + FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysMenu, err error) // 原生sql查询多个 +} + +type SysMenu struct { + sysMenuRepo *repo.SysMenu +} + +func NewSysMenuSvc(sysMenuRepo *repo.SysMenu) *SysMenu { + return &SysMenu{ + sysMenuRepo: sysMenuRepo, + } +} + +func (a *SysMenu) CreateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (ulid string, err error) { + return a.sysMenuRepo.Create(ctx, sysMenuEn) +} + +func (a *SysMenu) DeleteSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) { + return a.sysMenuRepo.Delete(ctx, sysMenuEn) +} + +func (a *SysMenu) UpdateSysMenu(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) { + return a.sysMenuRepo.Update(ctx, sysMenuEn) +} + +func (a *SysMenu) FindSysMenuById(ctx context.Context, ulid string) (sysMenuEn *entity.SysMenu, err error) { + return a.sysMenuRepo.FindById(ctx, ulid) +} + +func (a *SysMenu) FindSysMenuByQuery(ctx context.Context, queries []*types.Query) (sysMenuEn *entity.SysMenu, err error) { + return a.sysMenuRepo.FindByQuery(ctx, queries) +} + +func (a *SysMenu) FindSysMenuAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysMenu, err error) { + return a.sysMenuRepo.FindAll(ctx, queries) +} + +func (a *SysMenu) FindSysMenuPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) (entries []*entity.SysMenu, pageData *types.PageData, err error) { + return a.sysMenuRepo.FindPage(ctx, queries, reqPage, reqSort) +} + +func (a *SysMenu) ExecSql(ctx context.Context, sql string) error { + return a.sysMenuRepo.ExecSql(ctx, sql) +} + +func (a *SysMenu) FindOneExecSql(ctx context.Context, sql string) (sysMenuEn *entity.SysMenu, err error) { + return a.sysMenuRepo.FindOneExecSql(ctx, sql) +} + +func (a *SysMenu) FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysMenu, err error) { + return a.sysMenuRepo.FindManyExecSql(ctx, sql) +} diff --git a/system/go.mod b/system/go.mod new file mode 100644 index 0000000..455878a --- /dev/null +++ b/system/go.mod @@ -0,0 +1,50 @@ +module jettjia/go-ddd-demo-multi-system + +go 1.20 + +require ( + github.com/gin-gonic/gin v1.9.1 + github.com/go-sql-driver/mysql v1.7.1 + github.com/gogf/gf/v2 v2.5.4 + github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/google/wire v0.5.0 + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/jinzhu/copier v0.4.0 + github.com/pkg/errors v0.9.1 + github.com/sirupsen/logrus v1.9.3 + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f + google.golang.org/grpc v1.54.0 + google.golang.org/protobuf v1.30.0 + gopkg.in/yaml.v3 v3.0.1 + gorm.io/gorm v1.25.4 + gorm.io/plugin/soft_delete v1.2.1 +) + +require ( + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/bytedance/sonic v1.9.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gin-contrib/sse v0.1.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.14.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect +) diff --git a/system/go.sum b/system/go.sum new file mode 100644 index 0000000..3b967ca --- /dev/null +++ b/system/go.sum @@ -0,0 +1,224 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= +cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= +github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +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.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gogf/gf/v2 v2.5.4 h1:UBCSw8mInkHmEqL0E1LYc6QhSpaNFY/wHcFrTI/rzTk= +github.com/gogf/gf/v2 v2.5.4/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= +github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +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.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +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/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.3 h1:j7a/xn1U6TKA/PHHxqZuzh64CdtRc7rU9M+AvkOl5bA= +github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= +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 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +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.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +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.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +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.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +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/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= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +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/sqlite v1.1.3 h1:BYfdVuZB5He/u9dt4qDpZqiqDJ6KhPqs5QUqsr/Eeuc= +gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c= +gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= +gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/plugin/soft_delete v1.2.1 h1:qx9D/c4Xu6w5KT8LviX8DgLcB9hkKl6JC9f44Tj7cGU= +gorm.io/plugin/soft_delete v1.2.1/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/system/infra/consts/public_consts.go b/system/infra/consts/public_consts.go new file mode 100644 index 0000000..4b397bb --- /dev/null +++ b/system/infra/consts/public_consts.go @@ -0,0 +1,5 @@ +package consts + +const ( + UnitM = 1024 * 1024 //单位M +) diff --git a/system/infra/repository/converter/sys_log_conv.go b/system/infra/repository/converter/sys_log_conv.go new file mode 100644 index 0000000..e8fc687 --- /dev/null +++ b/system/infra/repository/converter/sys_log_conv.go @@ -0,0 +1,64 @@ +package converter + +import ( + "time" + + "github.com/jinzhu/copier" + "gorm.io/plugin/soft_delete" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + "jettjia/go-ddd-demo-multi-system/infra/repository/po" +) + +// E2PSysLogAdd entity数据转换成数据库po +func E2PSysLogAdd(en *entity.SysLog) *po.SysLog { + var sysLog po.SysLog + if err := copier.Copy(&sysLog, &en); err != nil { + panic(any(err)) + } + sysLog.CreatedAt = time.Now().UnixMilli() + + return &sysLog +} + +// E2PSysLogDel entity数据转换成数据库po +func E2PSysLogDel(en *entity.SysLog) *po.SysLog { + var sysLog po.SysLog + sysLog.DeletedAt = soft_delete.DeletedAt(time.Now().UnixNano()) + + return &sysLog +} + +// E2PSysLogUpdate entity数据转换成数据库po +func E2PSysLogUpdate(en *entity.SysLog) *po.SysLog { + var sysLog po.SysLog + if err := copier.Copy(&sysLog, &en); err != nil { + panic(any(err)) + } + + return &sysLog +} + +// P2ESysLog 数据库po转换成entity +func P2ESysLog(po *po.SysLog) *entity.SysLog { + var sysLog entity.SysLog + if err := copier.Copy(&sysLog, &po); err != nil { + panic(any(err)) + } + + return &sysLog +} + +func P2ESysLogs(pos []*po.SysLog) []*entity.SysLog { + ens := make([]*entity.SysLog, 0) + if len(pos) == 0 { + return ens + } + + for _, val := range pos { + cfg := P2ESysLog(val) + ens = append(ens, cfg) + } + + return ens +} diff --git a/system/infra/repository/converter/sys_menu_conv.go b/system/infra/repository/converter/sys_menu_conv.go new file mode 100644 index 0000000..61ba254 --- /dev/null +++ b/system/infra/repository/converter/sys_menu_conv.go @@ -0,0 +1,66 @@ +package converter + +import ( + "time" + + "github.com/jinzhu/copier" + "gorm.io/plugin/soft_delete" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + "jettjia/go-ddd-demo-multi-system/infra/repository/po" +) + +// E2PSysMenuAdd entity数据转换成数据库po +func E2PSysMenuAdd(en *entity.SysMenu) *po.SysMenu { + var sysMenu po.SysMenu + sysMenu.CreatedAt = time.Now().UnixNano() + if err := copier.Copy(&sysMenu, &en); err != nil { + panic(any(err)) + } + + return &sysMenu +} + +// E2PSysMenuDel entity数据转换成数据库po +func E2PSysMenuDel(en *entity.SysMenu) *po.SysMenu { + var sysMenu po.SysMenu + sysMenu.DeletedBy = en.DeletedBy + sysMenu.DeletedAt = soft_delete.DeletedAt(time.Now().UnixNano()) + + return &sysMenu +} + +// E2PSysMenuUpdate entity数据转换成数据库po +func E2PSysMenuUpdate(en *entity.SysMenu) *po.SysMenu { + var sysMenu po.SysMenu + if err := copier.Copy(&sysMenu, &en); err != nil { + panic(any(err)) + } + + sysMenu.UpdatedAt = time.Now().UnixNano() + return &sysMenu +} + +// P2ESysMenu 数据库po转换成entity +func P2ESysMenu(po *po.SysMenu) *entity.SysMenu { + var sysMenu entity.SysMenu + if err := copier.Copy(&sysMenu, &po); err != nil { + panic(any(err)) + } + + return &sysMenu +} + +func P2ESysMenus(pos []*po.SysMenu) []*entity.SysMenu { + ens := make([]*entity.SysMenu, 0) + if len(pos) == 0 { + return ens + } + + for _, val := range pos { + cfg := P2ESysMenu(val) + ens = append(ens, cfg) + } + + return ens +} diff --git a/system/infra/repository/po/sys_log_po.go b/system/infra/repository/po/sys_log_po.go new file mode 100644 index 0000000..f459c46 --- /dev/null +++ b/system/infra/repository/po/sys_log_po.go @@ -0,0 +1,24 @@ +package po + +import ( + "gorm.io/gorm" + "gorm.io/plugin/soft_delete" + + "jettjia/go-ddd-demo-multi-common/pkg/util" +) + +type SysLog struct { + Ulid string `gorm:"column:ulid;primaryKey;type:varchar(32);comment:ulid;" json:"ulid"` // ulid + CreatedAt int64 `gorm:"column:created_at;type:bigint(20);comment:创建时间;" json:"created_at"` // 创建时间 + UpdatedAt int64 `gorm:"column:updated_at;type:bigint(20);comment:修改时间;" json:"updated_at"` // 修改时间 + DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;type:bigint(20);comment:删除时间;" json:"deleted_at"` // 删除时间 + CreatedBy string `gorm:"column:created_by;type:varchar(32);comment:创建者;" json:"created_by"` // 创建者 + UpdatedBy string `gorm:"column:updated_by;type:varchar(32);comment:修改者;" json:"updated_by"` // 修改者 + DeletedBy string `gorm:"column:deleted_by;type:varchar(32);comment:删除者;" json:"deleted_by"` // 删除者 + Msg string `gorm:"column:msg;type:varchar(255); uniqueIndex;comment:msg;" json:"msg"` // msg +} + +func (po *SysLog) BeforeCreate(tx *gorm.DB) (err error) { + po.Ulid = util.Ulid() + return +} diff --git a/system/infra/repository/po/sys_menu_po.go b/system/infra/repository/po/sys_menu_po.go new file mode 100644 index 0000000..257ce39 --- /dev/null +++ b/system/infra/repository/po/sys_menu_po.go @@ -0,0 +1,31 @@ +package po + +import ( + "gorm.io/gorm" + "gorm.io/plugin/soft_delete" + + "jettjia/go-ddd-demo-multi-common/pkg/util" +) + +type SysMenu struct { + Ulid string `gorm:"column:ulid;primaryKey;type:varchar(32);comment:ulid;" json:"ulid"` // ulid + CreatedAt int64 `gorm:"column:created_at;type:bigint(20);comment:创建时间;" json:"created_at"` // 创建时间 + UpdatedAt int64 `gorm:"column:updated_at;type:bigint(20);comment:修改时间;" json:"updated_at"` // 修改时间 + DeletedAt soft_delete.DeletedAt `gorm:"column:deleted_at;type:bigint(20);comment:删除时间;" json:"deleted_at"` // 删除时间 + CreatedBy string `gorm:"column:created_by;type:varchar(32);comment:创建者;" json:"created_by"` // 创建者 + UpdatedBy string `gorm:"column:updated_by;type:varchar(32);comment:修改者;" json:"updated_by"` // 修改者 + DeletedBy string `gorm:"column:deleted_by;type:varchar(32);comment:删除者;" json:"deleted_by"` // 删除者 + MenuName string `gorm:"uniqueIndex:uqx_name;column:menu_name;type:varchar(32);comment:menu名称;" json:"menu_name"` // menu名称 + Desc string `gorm:"column:desc;type:varchar(255);comment:描述;" json:"desc"` // 描述 + Route string `gorm:"column:route;type:varchar(128);comment:菜单路由;" json:"route"` // 菜单路由 + State uint `gorm:"column:state;type:int(1) unsigned;default: 1;comment:1显示,2否;" json:"state"` // 1显示,2否 + Pid string `gorm:"column:pid;type:varchar(32);comment:父id;" json:"pid"` // 父id + Pname string `gorm:"column:pname;type:varchar(32);comment:父路由名称;" json:"pname"` // 父路由名称 + SortOrder int `gorm:"column:sort_order;type:smallint(6);default: 50;comment:排序;" json:"sort_order"` // 排序 + BackendType int `gorm:"column:backend_type;type:tinyint(1);default: 1;comment:1总后台,2运营后台;" json:"backend_type"` // 1总后台,2运营后台 +} + +func (po *SysMenu) BeforeCreate(tx *gorm.DB) (err error) { + po.Ulid = util.Ulid() + return +} diff --git a/system/infra/repository/repo/ps.go b/system/infra/repository/repo/ps.go new file mode 100644 index 0000000..eecdfbb --- /dev/null +++ b/system/infra/repository/repo/ps.go @@ -0,0 +1,9 @@ +package repo + +import ( + "github.com/google/wire" + + "jettjia/go-ddd-demo-multi-common/pkg/data" +) + +var RepoProviderSet = wire.NewSet(data.NewData, NewDB, NewRedis, NewRocksCache, data.NewTransaction, NewSysMenuImpl, NewSysLogImpl) diff --git a/system/infra/repository/repo/repo.go b/system/infra/repository/repo/repo.go new file mode 100644 index 0000000..df24327 --- /dev/null +++ b/system/infra/repository/repo/repo.go @@ -0,0 +1,71 @@ +package repo + +import ( + "time" + + "github.com/dtm-labs/rockscache" + "github.com/redis/go-redis/v9" + "gorm.io/gorm" + + "jettjia/go-ddd-demo-multi-common/pkg/conf" + "jettjia/go-ddd-demo-multi-common/pkg/database/db" + redis2 "jettjia/go-ddd-demo-multi-common/pkg/redis" +) + +// NewDB gorm Connecting to a Database +func NewDB(conf *conf.Config) *gorm.DB { + + var cfg db.DBConfig + cfg.Host = conf.Mysql.DbHost + cfg.Port = conf.Mysql.DbPort + cfg.User = conf.Mysql.Username + cfg.Password = conf.Mysql.Password + cfg.Db = conf.Mysql.DbName + cfg.DbChar = conf.Mysql.Charset + cfg.MaxIdleConn = conf.Mysql.MaxIdleConn + cfg.MaxOpenConn = conf.Mysql.MaxOpenConn + cfg.MaxLifetime = conf.Mysql.ConnMaxLifetime + cfg.LogMode = conf.Mysql.LogMode + cfg.SlowThreshold = conf.Mysql.SlowThreshold + + return db.NewDBClient(&cfg).Conn +} + +func NewRedis(conf *conf.Config) redis.UniversalClient { + cfg := &redis2.RedisConfig{ + RedisType: conf.Redis.RedisType, + Addrs: []string{ + conf.Redis.Addr, + }, + Password: conf.Redis.Password, + PoolSize: conf.Redis.PoolSize, + } + return redis2.NewRedisClient(cfg).Conn +} + +func NewRocksCache(rdb redis.UniversalClient) *rockscache.Client { + var dc = rockscache.NewClient(rdb, rockscache.NewDefaultOptions()) + // 常用参数设置 + // 1、强一致性(默认关闭强一致性,如果开启的话会影响性能) + dc.Options.StrongConsistency = false + + // 2、redis出现问题需要缓存降级时设置为true + dc.Options.DisableCacheRead = false // 关闭缓存读,默认false;如果打开,那么Fetch就不从缓存读取数据,而是直接调用fn获取数据 + dc.Options.DisableCacheDelete = false // 关闭缓存删除,默认false;如果打开,那么TagAsDeleted就什么操作都不做,直接返回 + + // 3、其他设置 + // 标记删除的延迟时间,默认10秒,设置为13秒表示:被删除的key在13秒后才从redis中彻底清除 + dc.Options.Delay = time.Second * time.Duration(13) + // 防穿透: 若fn返回空字符串,空结果在缓存中的缓存时间,默认60秒 + dc.Options.EmptyExpire = time.Second * time.Duration(120) + // 防雪崩: 默认0.1,当前设置为0.1的话,如果设定为600的过期时间,那么过期时间会被设定为540s - 600s中间的一个随机数,避免数据出现同时到期 + dc.Options.RandomExpireAdjustment = 0.1 // 设置为默认或不设置就行 + + // 锁相关参数,这里配置的默认值,没有特殊情况建议默认 + // 是更新缓存时分配的锁的过期时间。默认为 3s。设置为下级计算数据时间的最大值。 + dc.Options.LockExpire = time.Second * time.Duration(3) + // 锁失败后的重试等待时间 100ms + dc.Options.LockSleep = time.Millisecond * time.Duration(100) + + return dc +} diff --git a/system/infra/repository/repo/sys_log_impl.go b/system/infra/repository/repo/sys_log_impl.go new file mode 100644 index 0000000..07e325b --- /dev/null +++ b/system/infra/repository/repo/sys_log_impl.go @@ -0,0 +1,146 @@ +package repo + +import ( + "context" + "jettjia/go-ddd-demo-multi-common/pkg/data" + "jettjia/go-ddd-demo-multi-common/pkg/util" + "jettjia/go-ddd-demo-multi-common/types" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + isysLog "jettjia/go-ddd-demo-multi-system/domain/irepository" + "jettjia/go-ddd-demo-multi-system/infra/repository/converter" + "jettjia/go-ddd-demo-multi-system/infra/repository/po" +) + +var _ isysLog.ISysLogRepo = (*SysLog)(nil) + +type SysLog struct { + data *data.Data +} + +func NewSysLogImpl(data *data.Data) *SysLog { + return &SysLog{ + data: data, + } +} + +func (r *SysLog) Create(ctx context.Context, sysLogEn *entity.SysLog) (ulid string, err error) { + sysLogPo := converter.E2PSysLogAdd(sysLogEn) + err = r.data.DB(ctx).Create(&sysLogPo).Error + if err != nil { + return + } + + return sysLogPo.Ulid, nil +} + +func (r SysLog) Delete(ctx context.Context, sysLogEn *entity.SysLog) (err error) { + sysLogPo := converter.E2PSysLogDel(sysLogEn) + + return r.data.DB(ctx).Model(&po.SysLog{}).Where("ulid = ? ", sysLogEn.Ulid).Updates(sysLogPo).Error +} + +func (r *SysLog) Update(ctx context.Context, sysLogEn *entity.SysLog) (err error) { + sysLogPo := converter.E2PSysLogUpdate(sysLogEn) + + return r.data.DB(ctx).Model(&po.SysLog{}).Where("ulid = ? ", sysLogEn.Ulid).Updates(sysLogPo).Error +} + +func (r *SysLog) FindById(ctx context.Context, ulid string) (sysLogEn *entity.SysLog, err error) { + var sysLogPo po.SysLog + err = r.data.DB(ctx).Limit(1).Find(&sysLogPo, "ulid = ? ", ulid).Error + if err != nil { + return sysLogEn, err + } + sysLogEn = converter.P2ESysLog(&sysLogPo) + + return +} + +func (r *SysLog) FindByQuery(ctx context.Context, queries []*types.Query) (sysLogEn *entity.SysLog, err error) { + var sysLogPo po.SysLog + condition := types.GenerateQueryCondition(queries) + err = r.data.DB(ctx).Where(condition).Find(1).First(&sysLogPo).Error + if err != nil { + return sysLogEn, err + } + sysLogEn = converter.P2ESysLog(&sysLogPo) + + return +} + +func (r *SysLog) FindAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysLog, err error) { + sysLogPos := make([]*po.SysLog, 0) + condition := types.GenerateQueryCondition(queries) + + err = r.data.DB(ctx).Find(&sysLogPos, condition).Error + if err != nil { + return entries, err + } + entries = converter.P2ESysLogs(sysLogPos) + + return +} + +func (r *SysLog) FindPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) ([]*entity.SysLog, *types.PageData, error) { + var condition string + var total int64 + sysLogPos := make([]*po.SysLog, 0) + var rspPag types.PageData + var entries []*entity.SysLog + + condition = types.GenerateQueryCondition(queries) + + dbQuery := r.data.DB(ctx).Model(&po.SysLog{}).Where(condition) + + err := dbQuery.Count(&total).Error + if err != nil { + return entries, &rspPag, err + } + + if total != 0 { + err = dbQuery. + Select("sys_log.*"). + Order(reqSort.Sort + " " + reqSort.Direction). + Scopes(types.Paginate(reqPage.PageNum, reqPage.PageSize)). + Find(&sysLogPos).Error + if err != nil { + return entries, &rspPag, err + } + } + + rspPag.PageNum = reqPage.PageNum + rspPag.PageSize = reqPage.PageSize + rspPag.TotalNumber = total + rspPag.TotalPage = util.CeilPageNum(total, reqPage.PageSize) + + entries = converter.P2ESysLogs(sysLogPos) + + return entries, &rspPag, nil +} + +func (r *SysLog) ExecSql(ctx context.Context, sql string) error { + return r.data.DB(ctx).Exec(sql).Error +} + +func (r *SysLog) FindOneExecSql(ctx context.Context, sql string) (sysLogEn *entity.SysLog, err error) { + var sysLogPo po.SysLog + err = r.data.DB(ctx).Raw(sql).Scan(&sysLogPo).Error + if err != nil { + return nil, err + } + sysLogEn = converter.P2ESysLog(&sysLogPo) + + return +} + +func (r *SysLog) FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysLog, err error) { + sysLogPos := make([]*po.SysLog, 0) + err = r.data.DB(ctx).Raw(sql).Scan(&sysLogPos).Error + if err != nil { + return nil, err + } + entries = converter.P2ESysLogs(sysLogPos) + + return +} diff --git a/system/infra/repository/repo/sys_menu_impl.go b/system/infra/repository/repo/sys_menu_impl.go new file mode 100644 index 0000000..a429d18 --- /dev/null +++ b/system/infra/repository/repo/sys_menu_impl.go @@ -0,0 +1,148 @@ +package repo + +import ( + "context" + + "jettjia/go-ddd-demo-multi-common/pkg/data" + "jettjia/go-ddd-demo-multi-common/pkg/util" + "jettjia/go-ddd-demo-multi-common/types" + + "jettjia/go-ddd-demo-multi-system/domain/entity" + isysMenu "jettjia/go-ddd-demo-multi-system/domain/irepository" + "jettjia/go-ddd-demo-multi-system/infra/repository/converter" + "jettjia/go-ddd-demo-multi-system/infra/repository/po" +) + +var _ isysMenu.ISysMenuRepo = (*SysMenu)(nil) + +type SysMenu struct { + data *data.Data +} + +func NewSysMenuImpl(data *data.Data) *SysMenu { + return &SysMenu{ + data: data, + } +} + +func (r *SysMenu) Create(ctx context.Context, sysMenuEn *entity.SysMenu) (ulid string, err error) { + sysMenuPo := converter.E2PSysMenuAdd(sysMenuEn) + err = r.data.DB(ctx).Create(&sysMenuPo).Error + if err != nil { + return + } + + return sysMenuPo.Ulid, nil +} + +func (r SysMenu) Delete(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) { + sysMenuPo := converter.E2PSysMenuDel(sysMenuEn) + + return r.data.DB(ctx).Model(&po.SysMenu{}).Where("ulid = ? ", sysMenuEn.Ulid).Updates(sysMenuPo).Error +} + +func (r *SysMenu) Update(ctx context.Context, sysMenuEn *entity.SysMenu) (err error) { + sysMenuPo := converter.E2PSysMenuUpdate(sysMenuEn) + + return r.data.DB(ctx).Model(&po.SysMenu{}).Where("ulid = ? ", sysMenuEn.Ulid).Updates(sysMenuPo).Error +} + +func (r *SysMenu) FindById(ctx context.Context, ulid string) (sysMenuEn *entity.SysMenu, err error) { + var sysMenuPo po.SysMenu + err = r.data.DB(ctx).Limit(1).Find(&sysMenuPo, "ulid = ? ", ulid).Error + if err != nil { + return sysMenuEn, err + } + sysMenuEn = converter.P2ESysMenu(&sysMenuPo) + + return +} + +func (r *SysMenu) FindByQuery(ctx context.Context, queries []*types.Query) (sysMenuEn *entity.SysMenu, err error) { + var sysMenuPo po.SysMenu + condition := types.GenerateQueryCondition(queries) + err = r.data.DB(ctx).Where(condition).Limit(1).Find(&sysMenuPo).Error + if err != nil { + return sysMenuEn, err + } + sysMenuEn = converter.P2ESysMenu(&sysMenuPo) + + return +} + +func (r *SysMenu) FindAll(ctx context.Context, queries []*types.Query) (entries []*entity.SysMenu, err error) { + sysMenuPos := make([]*po.SysMenu, 0) + condition := types.GenerateQueryCondition(queries) + + err = r.data.DB(ctx).Find(&sysMenuPos, condition).Error + if err != nil { + return entries, err + } + entries = converter.P2ESysMenus(sysMenuPos) + + return +} + +func (r *SysMenu) FindPage(ctx context.Context, queries []*types.Query, reqPage *types.PageData, reqSort *types.SortData) ([]*entity.SysMenu, *types.PageData, error) { + var condition string + var total int64 + sysMenuPos := make([]*po.SysMenu, 0) + var rspPag types.PageData + var entries []*entity.SysMenu + + condition = types.GenerateQueryCondition(queries) + + dbQuery := r.data.DB(ctx).Model(&po.SysMenu{}).Where(condition) + + err := dbQuery.Count(&total).Error + if err != nil { + return entries, &rspPag, err + } + + if total != 0 { + err = dbQuery. + Select("sys_menu.*"). + Order(reqSort.Sort + " " + reqSort.Direction). + Scopes(types.Paginate(reqPage.PageNum, reqPage.PageSize)). + Find(&sysMenuPos).Error + + if err != nil { + return entries, &rspPag, err + } + } + + rspPag.PageNum = reqPage.PageNum + rspPag.PageSize = reqPage.PageSize + rspPag.TotalNumber = total + rspPag.TotalPage = util.CeilPageNum(total, reqPage.PageSize) + + entries = converter.P2ESysMenus(sysMenuPos) + + return entries, &rspPag, nil +} + +func (r *SysMenu) ExecSql(ctx context.Context, sql string) error { + return r.data.DB(ctx).Exec(sql).Error +} + +func (r *SysMenu) FindOneExecSql(ctx context.Context, sql string) (sysMenuEn *entity.SysMenu, err error) { + var sysMenuPo po.SysMenu + err = r.data.DB(ctx).Raw(sql).Scan(&sysMenuPo).Error + if err != nil { + return nil, err + } + sysMenuEn = converter.P2ESysMenu(&sysMenuPo) + + return +} + +func (r *SysMenu) FindManyExecSql(ctx context.Context, sql string) (entries []*entity.SysMenu, err error) { + sysMenuPos := make([]*po.SysMenu, 0) + err = r.data.DB(ctx).Raw(sql).Scan(&sysMenuPos).Error + if err != nil { + return nil, err + } + entries = converter.P2ESysMenus(sysMenuPos) + + return +} diff --git a/system/interface/event/event.go b/system/interface/event/event.go new file mode 100644 index 0000000..54d1494 --- /dev/null +++ b/system/interface/event/event.go @@ -0,0 +1,5 @@ +package event + +// InitEvent 消息事件 +func InitEvent() { +} diff --git a/system/interface/event/subscribe/.gitkeep b/system/interface/event/subscribe/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/system/interface/facade/.gitkeep b/system/interface/facade/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/system/interface/grpc/ghandler/base.go b/system/interface/grpc/ghandler/base.go new file mode 100644 index 0000000..868ce5d --- /dev/null +++ b/system/interface/grpc/ghandler/base.go @@ -0,0 +1,11 @@ +package ghandler + +import ( + sysSvc "jettjia/go-ddd-demo-multi-system/application/service" + grpcGoodsProto "jettjia/go-ddd-demo-multi-system/interface/grpc/proto/goods" +) + +type GrpcGoodsServer struct { + grpcGoodsProto.UnimplementedGoodsServer + SysMenuSrv *sysSvc.SysMenuService +} diff --git a/system/interface/grpc/ghandler/g_sys_menu_handler.go b/system/interface/grpc/ghandler/g_sys_menu_handler.go new file mode 100644 index 0000000..91f9204 --- /dev/null +++ b/system/interface/grpc/ghandler/g_sys_menu_handler.go @@ -0,0 +1,142 @@ +package ghandler + +import ( + "context" + + "github.com/jinzhu/copier" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "jettjia/go-ddd-demo-multi-common/pkg/log" + "jettjia/go-ddd-demo-multi-common/pkg/validate" + + "jettjia/go-ddd-demo-multi-system/application/dto" + grpcGoodsProto "jettjia/go-ddd-demo-multi-system/interface/grpc/proto/goods" +) + +func (s *GrpcGoodsServer) CreateSysMenu(ctx context.Context, req *grpcGoodsProto.CreateSysMenuReq) (rsp *grpcGoodsProto.CreateSysMenuRsp, err error) { + var ( + reqDto dto.CreateSysMenuReq + rspDto *dto.CreateSysMenuRsp + ) + // 参数解析 + if err = copier.Copy(&reqDto, &req); err != nil { + log.NewLogger().Error("CreateSysMenu:copier.Copy:err:", err) + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + // 参数过滤 + err = validate.Validate(reqDto) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + // 业务处理 + if rspDto, err = s.SysMenuSrv.CreateSysMenu(ctx, &reqDto); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &grpcGoodsProto.CreateSysMenuRsp{Ulid: rspDto.Ulid}, nil +} + +func (s *GrpcGoodsServer) DeleteSysMenu(ctx context.Context, req *grpcGoodsProto.DeleteSysMenuReq) (*grpcGoodsProto.Empty, error) { + var ( + reqDto dto.DelSysMenusReq + err error + rspPb grpcGoodsProto.Empty + ) + + // 参数解析 + if err = copier.Copy(&reqDto, &req); err != nil { + log.NewLogger().Error("DeleteSysMenu:copier.Copy:err:", err) + return &rspPb, status.Error(codes.InvalidArgument, err.Error()) + } + + // 业务处理 + err = s.SysMenuSrv.DeleteSysMenu(ctx, &reqDto) + if err != nil { + return &rspPb, status.Error(codes.NotFound, "DeleteSysMenu id "+req.Ulid+" not exists") + } + + return &rspPb, nil +} + +func (s *GrpcGoodsServer) UpdateSysMenu(ctx context.Context, req *grpcGoodsProto.UpdateSysMenuReq) (*grpcGoodsProto.Empty, error) { + var ( + reqDto dto.UpdateSysMenuReq + err error + rspPb grpcGoodsProto.Empty + ) + + // 参数解析 + if err = copier.Copy(&reqDto, &req); err != nil { + log.NewLogger().Error("UpdateSysMenu:copier.Copy:err:", err) + return &rspPb, status.Error(codes.InvalidArgument, err.Error()) + } + + // 业务处理 + err = s.SysMenuSrv.UpdateSysMenu(ctx, &reqDto) + if err != nil { + return &rspPb, status.Error(codes.NotFound, "UpdateProductLog id "+req.Ulid+" not exists") + } + + return &rspPb, nil +} + +func (s *GrpcGoodsServer) FindSysMenuById(ctx context.Context, req *grpcGoodsProto.FindSysMenuByIdReq) (*grpcGoodsProto.FindSysMenuRsp, error) { + var ( + reqDto dto.FindSysMenuByIdReq + rspDto *dto.FindSysMenuRsp + err error + rspPb grpcGoodsProto.FindSysMenuRsp + ) + // 参数解析 + if err = copier.Copy(&reqDto, &req); err != nil { + log.NewLogger().Error("FindSysMenuById:copier.Copy:err:", err) + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + // 业务处理 + if rspDto, err = s.SysMenuSrv.FindSysMenuById(ctx, &reqDto); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + err = copier.Copy(&rspPb, &rspDto) + if err != nil { + log.NewLogger().Error("FindSysMenuById:rspPb:copier.Copy:err:", err) + return nil, status.Error(codes.Internal, err.Error()) + } + return &rspPb, nil +} + +func (s *GrpcGoodsServer) FindSysMenuPage(ctx context.Context, req *grpcGoodsProto.FindSysMenuPageReq) (*grpcGoodsProto.FindSysMenuPageRsp, error) { + var ( + reqDto dto.FindSysMenuPageReq + rspDto *dto.FindSysMenuPageRsp + err error + rspPb grpcGoodsProto.FindSysMenuPageRsp + ) + // 参数解析 + if err = copier.Copy(&reqDto, &req); err != nil { + log.NewLogger().Error("FindSysMenuPage:copier.Copy:err:", err) + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + // 参数过滤 + err = validate.Validate(reqDto) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + // 业务处理 + if rspDto, err = s.SysMenuSrv.FindSysMenuPage(ctx, &reqDto); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + err = copier.Copy(&rspPb, &rspDto) + if err != nil { + log.NewLogger().Error("FindSysMenuPage:rspPb:copier.Copy:err:", err) + return nil, status.Error(codes.Internal, err.Error()) + } + return &rspPb, nil +} diff --git a/system/interface/grpc/ginit/g_ainit.go b/system/interface/grpc/ginit/g_ainit.go new file mode 100644 index 0000000..d9e8352 --- /dev/null +++ b/system/interface/grpc/ginit/g_ainit.go @@ -0,0 +1,12 @@ +package ginit + +import ( + "google.golang.org/grpc" + + "jettjia/go-ddd-demo-multi-system/cmd" +) + +func GInit(server *grpc.Server, serverApp *cmd.Server) { + RegisterGrpcSrv(server, serverApp) // 注册服务 + InitGrpcClient(serverApp) // 初始化client +} diff --git a/system/interface/grpc/ginit/g_grpc_client.go b/system/interface/grpc/ginit/g_grpc_client.go new file mode 100644 index 0000000..a6fce5c --- /dev/null +++ b/system/interface/grpc/ginit/g_grpc_client.go @@ -0,0 +1,30 @@ +package ginit + +import ( + "fmt" + + "google.golang.org/grpc" + + "jettjia/go-ddd-demo-multi-system/cmd" + "jettjia/go-ddd-demo-multi-system/infra/consts" + grpcGoodsProto "jettjia/go-ddd-demo-multi-system/interface/grpc/proto/goods" +) + +var ( + // GoodsClient grpc客户端,goods服务 + GoodsClient grpcGoodsProto.GoodsClient +) + +// InitGrpcClient 初始化链接其他服务的client +func InitGrpcClient(serverApp *cmd.Server) { + conf := serverApp.Cfg.Gserver + conn, err := grpc.Dial(fmt.Sprintf("%s:%d", conf.ClientGoodsHost, conf.ClientGoodsPort), + grpc.WithInsecure(), + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(conf.MaxMsgSize*consts.UnitM)), + ) + if err != nil { + panic("InitGrpcClient:err:" + err.Error()) + } + + GoodsClient = grpcGoodsProto.NewGoodsClient(conn) +} diff --git a/system/interface/grpc/ginit/g_init_grpc_server.go b/system/interface/grpc/ginit/g_init_grpc_server.go new file mode 100644 index 0000000..66505de --- /dev/null +++ b/system/interface/grpc/ginit/g_init_grpc_server.go @@ -0,0 +1,16 @@ +package ginit + +import ( + "google.golang.org/grpc" + + "jettjia/go-ddd-demo-multi-system/cmd" + "jettjia/go-ddd-demo-multi-system/interface/grpc/ghandler" + grpcGoodsProto "jettjia/go-ddd-demo-multi-system/interface/grpc/proto/goods" +) + +// RegisterGrpcSrv 初始化grpc的服务 +func RegisterGrpcSrv(server *grpc.Server, serverApp *cmd.Server) { + grpcGoodsProto.RegisterGoodsServer(server, &ghandler.GrpcGoodsServer{ + SysMenuSrv: serverApp.Sys, + }) +} diff --git a/system/interface/grpc/grpc.go b/system/interface/grpc/grpc.go new file mode 100644 index 0000000..1a012ec --- /dev/null +++ b/system/interface/grpc/grpc.go @@ -0,0 +1,46 @@ +package grpc + +import ( + "fmt" + + "net" + + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth" + grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" + "google.golang.org/grpc" + + "jettjia/go-ddd-demo-multi-system/cmd" + "jettjia/go-ddd-demo-multi-system/interface/grpc/ginit" + "jettjia/go-ddd-demo-multi-system/interface/grpc/middleware" +) + +func InitGrpc(serverApp *cmd.Server) { + if !serverApp.Cfg.Server.EnableGrpc { + return + } + server := grpc.NewServer( + grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( + grpc_auth.StreamServerInterceptor(middleware.AuthInterceptor), + grpc_recovery.StreamServerInterceptor(middleware.RecoverInterceptor()), + )), + grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( + grpc_auth.UnaryServerInterceptor(middleware.AuthInterceptor), + grpc_recovery.UnaryServerInterceptor(middleware.RecoverInterceptor()), + )), + ) + + ginit.GInit(server, serverApp) // 初始化 + + listener, _ := net.Listen("tcp", fmt.Sprintf("%s:%d", serverApp.Cfg.Gserver.Host, serverApp.Cfg.Gserver.PublicPort)) + + // 启动grpc服务 + go func() { + err := server.Serve(listener) + if err != nil { + panic("InitGrpc:failed to start grpc:" + err.Error()) + } + }() + + fmt.Printf("[Grpc-debug] Listening and serving RPC on :%d \r\n", serverApp.Cfg.Gserver.PublicPort) +} diff --git a/system/interface/grpc/middleware/auth.go b/system/interface/grpc/middleware/auth.go new file mode 100644 index 0000000..a5c85a7 --- /dev/null +++ b/system/interface/grpc/middleware/auth.go @@ -0,0 +1,36 @@ +package middleware + +import ( + "context" + "strings" + + "google.golang.org/grpc/metadata" + + "jettjia/go-ddd-demo-multi-common/pkg/log" + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +// AuthInterceptor 认证拦截器,对以authorization为头部,形式为`bearer token`的Token进行验证 +func AuthInterceptor(ctx context.Context) (context.Context, error) { + var ( + err error + ) + + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + log.NewLogger().Error("AuthInterceptor:metadata:error") + } + + if len(md.Get("authorization")) == 0 { + return ctx, err + } + + token := md.Get("authorization")[0] + token = strings.TrimPrefix(token, "Bearer ") + claims, _ := entity.ParseToken(token) // 这里token校验已经关闭,只解析了token + if claims == nil { + return ctx, err + } + + return ctx, nil +} diff --git a/system/interface/grpc/middleware/recover.go b/system/interface/grpc/middleware/recover.go new file mode 100644 index 0000000..c37f368 --- /dev/null +++ b/system/interface/grpc/middleware/recover.go @@ -0,0 +1,21 @@ +package middleware + +import ( + "fmt" + "jettjia/go-ddd-demo-multi-common/pkg/log" + "jettjia/go-ddd-demo-multi-common/pkg/response" + + grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" + "github.com/sirupsen/logrus" + spb "google.golang.org/genproto/googleapis/rpc/status" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func RecoverInterceptor() grpc_recovery.Option { + return grpc_recovery.WithRecoveryHandler(func(p interface{}) (err error) { + errorInfo := response.GrpcPanic(err) // 全局错误信息 + log.NewLogger().WithFields(logrus.Fields{"error_detail": errorInfo.Internal}).Errorln(fmt.Sprintf("%v", p)) + return status.ErrorProto(&spb.Status{Code: int32(codes.Internal), Message: fmt.Sprintf("%v", p), Details: nil}) + }) +} diff --git a/system/interface/grpc/proto/goods/auto.bat b/system/interface/grpc/proto/goods/auto.bat new file mode 100644 index 0000000..130a024 --- /dev/null +++ b/system/interface/grpc/proto/goods/auto.bat @@ -0,0 +1 @@ +protoc --go_out=plugins=grpc:./ ./*.proto \ No newline at end of file diff --git a/system/interface/grpc/proto/goods/common.pb.go b/system/interface/grpc/proto/goods/common.pb.go new file mode 100644 index 0000000..202a31e --- /dev/null +++ b/system/interface/grpc/proto/goods/common.pb.go @@ -0,0 +1,449 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.3 +// source: common.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 Operator int32 + +const ( + Operator_GT Operator = 0 //大于 + Operator_EQUAL Operator = 1 //等于 + Operator_LT Operator = 2 //小于 + Operator_NEQ Operator = 3 //不等于 + Operator_LIKE Operator = 4 //模糊查询 + Operator_GTE Operator = 5 // 大于等于 + Operator_LTE Operator = 6 // 小于等于 + Operator_IN Operator = 7 // in +) + +// Enum value maps for Operator. +var ( + Operator_name = map[int32]string{ + 0: "GT", + 1: "EQUAL", + 2: "LT", + 3: "NEQ", + 4: "LIKE", + 5: "GTE", + 6: "LTE", + 7: "IN", + } + Operator_value = map[string]int32{ + "GT": 0, + "EQUAL": 1, + "LT": 2, + "NEQ": 3, + "LIKE": 4, + "GTE": 5, + "LTE": 6, + "IN": 7, + } +) + +func (x Operator) Enum() *Operator { + p := new(Operator) + *p = x + return p +} + +func (x Operator) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Operator) Descriptor() protoreflect.EnumDescriptor { + return file_common_proto_enumTypes[0].Descriptor() +} + +func (Operator) Type() protoreflect.EnumType { + return &file_common_proto_enumTypes[0] +} + +func (x Operator) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Operator.Descriptor instead. +func (Operator) EnumDescriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{0} +} + +type Query struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` //表字段名称 + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` //表字段值 + Operator Operator `protobuf:"varint,3,opt,name=operator,proto3,enum=Operator" json:"operator,omitempty"` //判断条件 +} + +func (x *Query) Reset() { + *x = Query{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Query) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Query) ProtoMessage() {} + +func (x *Query) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Query.ProtoReflect.Descriptor instead. +func (*Query) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{1} +} + +func (x *Query) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Query) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *Query) GetOperator() Operator { + if x != nil { + return x.Operator + } + return Operator_GT +} + +type PageData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PageNum uint32 `protobuf:"varint,1,opt,name=page_num,json=pageNum,proto3" json:"page_num,omitempty"` // 页码 + PageSize uint32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` // 每页显示行数 + TotalNumber uint32 `protobuf:"varint,3,opt,name=total_number,json=totalNumber,proto3" json:"total_number,omitempty"` // 共多少条 + TotalPage uint32 `protobuf:"varint,4,opt,name=total_page,json=totalPage,proto3" json:"total_page,omitempty"` // 共多少页 +} + +func (x *PageData) Reset() { + *x = PageData{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PageData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PageData) ProtoMessage() {} + +func (x *PageData) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PageData.ProtoReflect.Descriptor instead. +func (*PageData) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{2} +} + +func (x *PageData) GetPageNum() uint32 { + if x != nil { + return x.PageNum + } + return 0 +} + +func (x *PageData) GetPageSize() uint32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *PageData) GetTotalNumber() uint32 { + if x != nil { + return x.TotalNumber + } + return 0 +} + +func (x *PageData) GetTotalPage() uint32 { + if x != nil { + return x.TotalPage + } + return 0 +} + +type SortData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Sort string `protobuf:"bytes,1,opt,name=sort,proto3" json:"sort,omitempty"` // 排序字段 + Direction string `protobuf:"bytes,2,opt,name=direction,proto3" json:"direction,omitempty"` // asc:升序;desc:降序 +} + +func (x *SortData) Reset() { + *x = SortData{} + if protoimpl.UnsafeEnabled { + mi := &file_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SortData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SortData) ProtoMessage() {} + +func (x *SortData) ProtoReflect() protoreflect.Message { + mi := &file_common_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SortData.ProtoReflect.Descriptor instead. +func (*SortData) Descriptor() ([]byte, []int) { + return file_common_proto_rawDescGZIP(), []int{3} +} + +func (x *SortData) GetSort() string { + if x != nil { + return x.Sort + } + return "" +} + +func (x *SortData) GetDirection() string { + if x != nil { + return x.Direction + } + return "" +} + +var File_common_proto protoreflect.FileDescriptor + +var file_common_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, + 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x56, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, + 0x84, 0x01, 0x0a, 0x08, 0x50, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x19, 0x0a, 0x08, + 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, + 0x70, 0x61, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x5f, 0x70, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x50, 0x61, 0x67, 0x65, 0x22, 0x3c, 0x0a, 0x08, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x52, 0x0a, 0x08, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, + 0x12, 0x06, 0x0a, 0x02, 0x47, 0x54, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x51, 0x55, 0x41, + 0x4c, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x4e, + 0x45, 0x51, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x4b, 0x45, 0x10, 0x04, 0x12, 0x07, + 0x0a, 0x03, 0x47, 0x54, 0x45, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x54, 0x45, 0x10, 0x06, + 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4e, 0x10, 0x07, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_common_proto_rawDescOnce sync.Once + file_common_proto_rawDescData = file_common_proto_rawDesc +) + +func file_common_proto_rawDescGZIP() []byte { + file_common_proto_rawDescOnce.Do(func() { + file_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_common_proto_rawDescData) + }) + return file_common_proto_rawDescData +} + +var file_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_common_proto_goTypes = []interface{}{ + (Operator)(0), // 0: Operator + (*Empty)(nil), // 1: Empty + (*Query)(nil), // 2: Query + (*PageData)(nil), // 3: PageData + (*SortData)(nil), // 4: SortData +} +var file_common_proto_depIdxs = []int32{ + 0, // 0: Query.operator:type_name -> Operator + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_common_proto_init() } +func file_common_proto_init() { + if File_common_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Query); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PageData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_common_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SortData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_common_proto_rawDesc, + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_common_proto_goTypes, + DependencyIndexes: file_common_proto_depIdxs, + EnumInfos: file_common_proto_enumTypes, + MessageInfos: file_common_proto_msgTypes, + }.Build() + File_common_proto = out.File + file_common_proto_rawDesc = nil + file_common_proto_goTypes = nil + file_common_proto_depIdxs = nil +} diff --git a/system/interface/grpc/proto/goods/common.proto b/system/interface/grpc/proto/goods/common.proto new file mode 100644 index 0000000..01f5b59 --- /dev/null +++ b/system/interface/grpc/proto/goods/common.proto @@ -0,0 +1,33 @@ +syntax = "proto3"; +option go_package = ".;proto"; + +message Empty {} + +message Query { + string key = 1; //表字段名称 + string value = 2; //表字段值 + Operator operator = 3; //判断条件 +} + +enum Operator { + GT = 0; //大于 + EQUAL = 1; //等于 + LT = 2; //小于 + NEQ = 3; //不等于 + LIKE = 4; //模糊查询 + GTE = 5; // 大于等于 + LTE = 6; // 小于等于 + IN = 7; // in +} + +message PageData { + uint32 page_num = 1; // 页码 + uint32 page_size = 2; // 每页显示行数 + uint32 total_number = 3; // 共多少条 + uint32 total_page = 4; // 共多少页 +} + +message SortData { + string sort = 1; // 排序字段 + string direction = 2; // asc:升序;desc:降序 +} \ No newline at end of file diff --git a/system/interface/grpc/proto/goods/goods.pb.go b/system/interface/grpc/proto/goods/goods.pb.go new file mode 100644 index 0000000..466ac1b --- /dev/null +++ b/system/interface/grpc/proto/goods/goods.pb.go @@ -0,0 +1,331 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.3 +// source: goods.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" +) + +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) +) + +var File_goods_proto protoreflect.FileDescriptor + +var file_goods_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x67, 0x6f, 0x6f, 0x64, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x63, + 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0e, 0x73, 0x79, 0x73, + 0x5f, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x8c, 0x02, 0x0a, 0x05, + 0x47, 0x6f, 0x6f, 0x64, 0x73, 0x12, 0x35, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x12, 0x11, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x73, 0x70, 0x12, 0x2a, 0x0a, 0x0d, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x12, 0x11, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, + 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x12, 0x11, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x1a, 0x06, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, + 0x65, 0x6e, 0x75, 0x42, 0x79, 0x49, 0x64, 0x12, 0x13, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, + 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x46, + 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x73, 0x70, 0x12, 0x3b, 0x0a, + 0x0f, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x50, 0x61, 0x67, 0x65, + 0x12, 0x13, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x50, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, + 0x65, 0x6e, 0x75, 0x50, 0x61, 0x67, 0x65, 0x52, 0x73, 0x70, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_goods_proto_goTypes = []interface{}{ + (*CreateSysMenuReq)(nil), // 0: CreateSysMenuReq + (*DeleteSysMenuReq)(nil), // 1: DeleteSysMenuReq + (*UpdateSysMenuReq)(nil), // 2: UpdateSysMenuReq + (*FindSysMenuByIdReq)(nil), // 3: FindSysMenuByIdReq + (*FindSysMenuPageReq)(nil), // 4: FindSysMenuPageReq + (*CreateSysMenuRsp)(nil), // 5: CreateSysMenuRsp + (*Empty)(nil), // 6: Empty + (*FindSysMenuRsp)(nil), // 7: FindSysMenuRsp + (*FindSysMenuPageRsp)(nil), // 8: FindSysMenuPageRsp +} +var file_goods_proto_depIdxs = []int32{ + 0, // 0: Goods.CreateSysMenu:input_type -> CreateSysMenuReq + 1, // 1: Goods.DeleteSysMenu:input_type -> DeleteSysMenuReq + 2, // 2: Goods.UpdateSysMenu:input_type -> UpdateSysMenuReq + 3, // 3: Goods.FindSysMenuById:input_type -> FindSysMenuByIdReq + 4, // 4: Goods.FindSysMenuPage:input_type -> FindSysMenuPageReq + 5, // 5: Goods.CreateSysMenu:output_type -> CreateSysMenuRsp + 6, // 6: Goods.DeleteSysMenu:output_type -> Empty + 6, // 7: Goods.UpdateSysMenu:output_type -> Empty + 7, // 8: Goods.FindSysMenuById:output_type -> FindSysMenuRsp + 8, // 9: Goods.FindSysMenuPage:output_type -> FindSysMenuPageRsp + 5, // [5:10] is the sub-list for method output_type + 0, // [0:5] 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_goods_proto_init() } +func file_goods_proto_init() { + if File_goods_proto != nil { + return + } + file_common_proto_init() + file_sys_menu_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_goods_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_goods_proto_goTypes, + DependencyIndexes: file_goods_proto_depIdxs, + }.Build() + File_goods_proto = out.File + file_goods_proto_rawDesc = nil + file_goods_proto_goTypes = nil + file_goods_proto_depIdxs = nil +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion6 + +// GoodsClient is the client API for Goods srv. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type GoodsClient interface { + // sys_menu + CreateSysMenu(ctx context.Context, in *CreateSysMenuReq, opts ...grpc.CallOption) (*CreateSysMenuRsp, error) + DeleteSysMenu(ctx context.Context, in *DeleteSysMenuReq, opts ...grpc.CallOption) (*Empty, error) + UpdateSysMenu(ctx context.Context, in *UpdateSysMenuReq, opts ...grpc.CallOption) (*Empty, error) + FindSysMenuById(ctx context.Context, in *FindSysMenuByIdReq, opts ...grpc.CallOption) (*FindSysMenuRsp, error) + FindSysMenuPage(ctx context.Context, in *FindSysMenuPageReq, opts ...grpc.CallOption) (*FindSysMenuPageRsp, error) +} + +type goodsClient struct { + cc grpc.ClientConnInterface +} + +func NewGoodsClient(cc grpc.ClientConnInterface) GoodsClient { + return &goodsClient{cc} +} + +func (c *goodsClient) CreateSysMenu(ctx context.Context, in *CreateSysMenuReq, opts ...grpc.CallOption) (*CreateSysMenuRsp, error) { + out := new(CreateSysMenuRsp) + err := c.cc.Invoke(ctx, "/Goods/CreateSysMenu", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *goodsClient) DeleteSysMenu(ctx context.Context, in *DeleteSysMenuReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/Goods/DeleteSysMenu", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *goodsClient) UpdateSysMenu(ctx context.Context, in *UpdateSysMenuReq, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/Goods/UpdateSysMenu", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *goodsClient) FindSysMenuById(ctx context.Context, in *FindSysMenuByIdReq, opts ...grpc.CallOption) (*FindSysMenuRsp, error) { + out := new(FindSysMenuRsp) + err := c.cc.Invoke(ctx, "/Goods/FindSysMenuById", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *goodsClient) FindSysMenuPage(ctx context.Context, in *FindSysMenuPageReq, opts ...grpc.CallOption) (*FindSysMenuPageRsp, error) { + out := new(FindSysMenuPageRsp) + err := c.cc.Invoke(ctx, "/Goods/FindSysMenuPage", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GoodsServer is the server API for Goods srv. +type GoodsServer interface { + // sys_menu + CreateSysMenu(context.Context, *CreateSysMenuReq) (*CreateSysMenuRsp, error) + DeleteSysMenu(context.Context, *DeleteSysMenuReq) (*Empty, error) + UpdateSysMenu(context.Context, *UpdateSysMenuReq) (*Empty, error) + FindSysMenuById(context.Context, *FindSysMenuByIdReq) (*FindSysMenuRsp, error) + FindSysMenuPage(context.Context, *FindSysMenuPageReq) (*FindSysMenuPageRsp, error) +} + +// UnimplementedGoodsServer can be embedded to have forward compatible implementations. +type UnimplementedGoodsServer struct { +} + +func (*UnimplementedGoodsServer) CreateSysMenu(context.Context, *CreateSysMenuReq) (*CreateSysMenuRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSysMenu not implemented") +} +func (*UnimplementedGoodsServer) DeleteSysMenu(context.Context, *DeleteSysMenuReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteSysMenu not implemented") +} +func (*UnimplementedGoodsServer) UpdateSysMenu(context.Context, *UpdateSysMenuReq) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateSysMenu not implemented") +} +func (*UnimplementedGoodsServer) FindSysMenuById(context.Context, *FindSysMenuByIdReq) (*FindSysMenuRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindSysMenuById not implemented") +} +func (*UnimplementedGoodsServer) FindSysMenuPage(context.Context, *FindSysMenuPageReq) (*FindSysMenuPageRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method FindSysMenuPage not implemented") +} + +func RegisterGoodsServer(s *grpc.Server, srv GoodsServer) { + s.RegisterService(&_Goods_serviceDesc, srv) +} + +func _Goods_CreateSysMenu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateSysMenuReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GoodsServer).CreateSysMenu(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Goods/CreateSysMenu", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GoodsServer).CreateSysMenu(ctx, req.(*CreateSysMenuReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Goods_DeleteSysMenu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteSysMenuReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GoodsServer).DeleteSysMenu(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Goods/DeleteSysMenu", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GoodsServer).DeleteSysMenu(ctx, req.(*DeleteSysMenuReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Goods_UpdateSysMenu_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateSysMenuReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GoodsServer).UpdateSysMenu(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Goods/UpdateSysMenu", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GoodsServer).UpdateSysMenu(ctx, req.(*UpdateSysMenuReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Goods_FindSysMenuById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindSysMenuByIdReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GoodsServer).FindSysMenuById(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Goods/FindSysMenuById", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GoodsServer).FindSysMenuById(ctx, req.(*FindSysMenuByIdReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Goods_FindSysMenuPage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FindSysMenuPageReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GoodsServer).FindSysMenuPage(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Goods/FindSysMenuPage", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GoodsServer).FindSysMenuPage(ctx, req.(*FindSysMenuPageReq)) + } + return interceptor(ctx, in, info, handler) +} + +var _Goods_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Goods", + HandlerType: (*GoodsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateSysMenu", + Handler: _Goods_CreateSysMenu_Handler, + }, + { + MethodName: "DeleteSysMenu", + Handler: _Goods_DeleteSysMenu_Handler, + }, + { + MethodName: "UpdateSysMenu", + Handler: _Goods_UpdateSysMenu_Handler, + }, + { + MethodName: "FindSysMenuById", + Handler: _Goods_FindSysMenuById_Handler, + }, + { + MethodName: "FindSysMenuPage", + Handler: _Goods_FindSysMenuPage_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "goods.proto", +} diff --git a/system/interface/grpc/proto/goods/goods.proto b/system/interface/grpc/proto/goods/goods.proto new file mode 100644 index 0000000..ca285ed --- /dev/null +++ b/system/interface/grpc/proto/goods/goods.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +import "common.proto"; +import "sys_menu.proto"; + +option go_package = ".;proto"; + +service Goods { + // sys_menu + rpc CreateSysMenu (CreateSysMenuReq) returns (CreateSysMenuRsp); // 创建 + rpc DeleteSysMenu (DeleteSysMenuReq) returns (Empty); // 删除 + rpc UpdateSysMenu (UpdateSysMenuReq) returns (Empty); // 修改 + rpc FindSysMenuById (FindSysMenuByIdReq) returns (FindSysMenuRsp); // 根据id查找 + rpc FindSysMenuPage (FindSysMenuPageReq) returns (FindSysMenuPageRsp); // 分页 +} \ No newline at end of file diff --git a/system/interface/grpc/proto/goods/sys_menu.pb.go b/system/interface/grpc/proto/goods/sys_menu.pb.go new file mode 100644 index 0000000..c0a59db --- /dev/null +++ b/system/interface/grpc/proto/goods/sys_menu.pb.go @@ -0,0 +1,862 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v4.24.3 +// source: sys_menu.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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 CreateSysMenuReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MenuName string `protobuf:"bytes,1,opt,name=menuName,proto3" json:"menuName,omitempty"` // menu名称 + Desc string `protobuf:"bytes,2,opt,name=desc,proto3" json:"desc,omitempty"` // 描述 + Route string `protobuf:"bytes,3,opt,name=route,proto3" json:"route,omitempty"` // 菜单路由 + State uint32 `protobuf:"varint,4,opt,name=state,proto3" json:"state,omitempty"` // 1显示,2否 + Pid uint64 `protobuf:"varint,5,opt,name=pid,proto3" json:"pid,omitempty"` // 父id + Pname string `protobuf:"bytes,6,opt,name=pname,proto3" json:"pname,omitempty"` // 父路由名称 + SortOrder int32 `protobuf:"varint,7,opt,name=sortOrder,proto3" json:"sortOrder,omitempty"` // 排序 + BackendType int32 `protobuf:"varint,8,opt,name=backendType,proto3" json:"backendType,omitempty"` // 1总后台,2运营后台 +} + +func (x *CreateSysMenuReq) Reset() { + *x = CreateSysMenuReq{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateSysMenuReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSysMenuReq) ProtoMessage() {} + +func (x *CreateSysMenuReq) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateSysMenuReq.ProtoReflect.Descriptor instead. +func (*CreateSysMenuReq) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{0} +} + +func (x *CreateSysMenuReq) GetMenuName() string { + if x != nil { + return x.MenuName + } + return "" +} + +func (x *CreateSysMenuReq) GetDesc() string { + if x != nil { + return x.Desc + } + return "" +} + +func (x *CreateSysMenuReq) GetRoute() string { + if x != nil { + return x.Route + } + return "" +} + +func (x *CreateSysMenuReq) GetState() uint32 { + if x != nil { + return x.State + } + return 0 +} + +func (x *CreateSysMenuReq) GetPid() uint64 { + if x != nil { + return x.Pid + } + return 0 +} + +func (x *CreateSysMenuReq) GetPname() string { + if x != nil { + return x.Pname + } + return "" +} + +func (x *CreateSysMenuReq) GetSortOrder() int32 { + if x != nil { + return x.SortOrder + } + return 0 +} + +func (x *CreateSysMenuReq) GetBackendType() int32 { + if x != nil { + return x.BackendType + } + return 0 +} + +type CreateSysMenuRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ulid string `protobuf:"bytes,1,opt,name=ulid,proto3" json:"ulid,omitempty"` +} + +func (x *CreateSysMenuRsp) Reset() { + *x = CreateSysMenuRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateSysMenuRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateSysMenuRsp) ProtoMessage() {} + +func (x *CreateSysMenuRsp) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateSysMenuRsp.ProtoReflect.Descriptor instead. +func (*CreateSysMenuRsp) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateSysMenuRsp) GetUlid() string { + if x != nil { + return x.Ulid + } + return "" +} + +type DeleteSysMenuReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ulid string `protobuf:"bytes,1,opt,name=ulid,proto3" json:"ulid,omitempty"` +} + +func (x *DeleteSysMenuReq) Reset() { + *x = DeleteSysMenuReq{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteSysMenuReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteSysMenuReq) ProtoMessage() {} + +func (x *DeleteSysMenuReq) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteSysMenuReq.ProtoReflect.Descriptor instead. +func (*DeleteSysMenuReq) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{2} +} + +func (x *DeleteSysMenuReq) GetUlid() string { + if x != nil { + return x.Ulid + } + return "" +} + +type UpdateSysMenuReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ulid string `protobuf:"bytes,1,opt,name=ulid,proto3" json:"ulid,omitempty"` // ID + MenuName string `protobuf:"bytes,2,opt,name=menuName,proto3" json:"menuName,omitempty"` // menu名称 + Desc string `protobuf:"bytes,3,opt,name=desc,proto3" json:"desc,omitempty"` // 描述 + Route string `protobuf:"bytes,4,opt,name=route,proto3" json:"route,omitempty"` // 菜单路由 + State uint32 `protobuf:"varint,5,opt,name=state,proto3" json:"state,omitempty"` // 1显示,2否 + Pid uint64 `protobuf:"varint,6,opt,name=pid,proto3" json:"pid,omitempty"` // 父id + Pname string `protobuf:"bytes,7,opt,name=pname,proto3" json:"pname,omitempty"` // 父路由名称 + SortOrder int32 `protobuf:"varint,8,opt,name=sortOrder,proto3" json:"sortOrder,omitempty"` // 排序 + BackendType int32 `protobuf:"varint,9,opt,name=backendType,proto3" json:"backendType,omitempty"` // 1总后台,2运营后台 +} + +func (x *UpdateSysMenuReq) Reset() { + *x = UpdateSysMenuReq{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSysMenuReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSysMenuReq) ProtoMessage() {} + +func (x *UpdateSysMenuReq) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateSysMenuReq.ProtoReflect.Descriptor instead. +func (*UpdateSysMenuReq) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{3} +} + +func (x *UpdateSysMenuReq) GetUlid() string { + if x != nil { + return x.Ulid + } + return "" +} + +func (x *UpdateSysMenuReq) GetMenuName() string { + if x != nil { + return x.MenuName + } + return "" +} + +func (x *UpdateSysMenuReq) GetDesc() string { + if x != nil { + return x.Desc + } + return "" +} + +func (x *UpdateSysMenuReq) GetRoute() string { + if x != nil { + return x.Route + } + return "" +} + +func (x *UpdateSysMenuReq) GetState() uint32 { + if x != nil { + return x.State + } + return 0 +} + +func (x *UpdateSysMenuReq) GetPid() uint64 { + if x != nil { + return x.Pid + } + return 0 +} + +func (x *UpdateSysMenuReq) GetPname() string { + if x != nil { + return x.Pname + } + return "" +} + +func (x *UpdateSysMenuReq) GetSortOrder() int32 { + if x != nil { + return x.SortOrder + } + return 0 +} + +func (x *UpdateSysMenuReq) GetBackendType() int32 { + if x != nil { + return x.BackendType + } + return 0 +} + +type FindSysMenuByIdReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ulid string `protobuf:"bytes,1,opt,name=ulid,proto3" json:"ulid,omitempty"` +} + +func (x *FindSysMenuByIdReq) Reset() { + *x = FindSysMenuByIdReq{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindSysMenuByIdReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindSysMenuByIdReq) ProtoMessage() {} + +func (x *FindSysMenuByIdReq) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindSysMenuByIdReq.ProtoReflect.Descriptor instead. +func (*FindSysMenuByIdReq) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{4} +} + +func (x *FindSysMenuByIdReq) GetUlid() string { + if x != nil { + return x.Ulid + } + return "" +} + +type FindSysMenuRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ulid string `protobuf:"bytes,1,opt,name=ulid,proto3" json:"ulid,omitempty"` // ID + CreatedBy string `protobuf:"bytes,4,opt,name=createdBy,proto3" json:"createdBy,omitempty"` // 创建者 + DeletedBy string `protobuf:"bytes,5,opt,name=deletedBy,proto3" json:"deletedBy,omitempty"` // 删除者 + MenuName string `protobuf:"bytes,6,opt,name=menuName,proto3" json:"menuName,omitempty"` // menu名称 + Desc string `protobuf:"bytes,7,opt,name=desc,proto3" json:"desc,omitempty"` // 描述 + Route string `protobuf:"bytes,8,opt,name=route,proto3" json:"route,omitempty"` // 菜单路由 + State uint32 `protobuf:"varint,9,opt,name=state,proto3" json:"state,omitempty"` // 1显示,2否 + Pid uint64 `protobuf:"varint,10,opt,name=pid,proto3" json:"pid,omitempty"` // 父id + Pname string `protobuf:"bytes,11,opt,name=pname,proto3" json:"pname,omitempty"` // 父路由名称 + SortOrder int32 `protobuf:"varint,12,opt,name=sortOrder,proto3" json:"sortOrder,omitempty"` // 排序 + BackendType int32 `protobuf:"varint,13,opt,name=backendType,proto3" json:"backendType,omitempty"` // 1总后台,2运营后台 +} + +func (x *FindSysMenuRsp) Reset() { + *x = FindSysMenuRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindSysMenuRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindSysMenuRsp) ProtoMessage() {} + +func (x *FindSysMenuRsp) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindSysMenuRsp.ProtoReflect.Descriptor instead. +func (*FindSysMenuRsp) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{5} +} + +func (x *FindSysMenuRsp) GetUlid() string { + if x != nil { + return x.Ulid + } + return "" +} + +func (x *FindSysMenuRsp) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *FindSysMenuRsp) GetDeletedBy() string { + if x != nil { + return x.DeletedBy + } + return "" +} + +func (x *FindSysMenuRsp) GetMenuName() string { + if x != nil { + return x.MenuName + } + return "" +} + +func (x *FindSysMenuRsp) GetDesc() string { + if x != nil { + return x.Desc + } + return "" +} + +func (x *FindSysMenuRsp) GetRoute() string { + if x != nil { + return x.Route + } + return "" +} + +func (x *FindSysMenuRsp) GetState() uint32 { + if x != nil { + return x.State + } + return 0 +} + +func (x *FindSysMenuRsp) GetPid() uint64 { + if x != nil { + return x.Pid + } + return 0 +} + +func (x *FindSysMenuRsp) GetPname() string { + if x != nil { + return x.Pname + } + return "" +} + +func (x *FindSysMenuRsp) GetSortOrder() int32 { + if x != nil { + return x.SortOrder + } + return 0 +} + +func (x *FindSysMenuRsp) GetBackendType() int32 { + if x != nil { + return x.BackendType + } + return 0 +} + +type FindSysMenuPageReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query []*Query `protobuf:"bytes,1,rep,name=query,proto3" json:"query,omitempty"` + PageData *PageData `protobuf:"bytes,2,opt,name=page_data,json=pageData,proto3" json:"page_data,omitempty"` + SortData *SortData `protobuf:"bytes,3,opt,name=sort_data,json=sortData,proto3" json:"sort_data,omitempty"` +} + +func (x *FindSysMenuPageReq) Reset() { + *x = FindSysMenuPageReq{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindSysMenuPageReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindSysMenuPageReq) ProtoMessage() {} + +func (x *FindSysMenuPageReq) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindSysMenuPageReq.ProtoReflect.Descriptor instead. +func (*FindSysMenuPageReq) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{6} +} + +func (x *FindSysMenuPageReq) GetQuery() []*Query { + if x != nil { + return x.Query + } + return nil +} + +func (x *FindSysMenuPageReq) GetPageData() *PageData { + if x != nil { + return x.PageData + } + return nil +} + +func (x *FindSysMenuPageReq) GetSortData() *SortData { + if x != nil { + return x.SortData + } + return nil +} + +type FindSysMenuPageRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entries []*FindSysMenuRsp `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` + PageData *PageData `protobuf:"bytes,2,opt,name=page_data,json=pageData,proto3" json:"page_data,omitempty"` +} + +func (x *FindSysMenuPageRsp) Reset() { + *x = FindSysMenuPageRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_sys_menu_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FindSysMenuPageRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FindSysMenuPageRsp) ProtoMessage() {} + +func (x *FindSysMenuPageRsp) ProtoReflect() protoreflect.Message { + mi := &file_sys_menu_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FindSysMenuPageRsp.ProtoReflect.Descriptor instead. +func (*FindSysMenuPageRsp) Descriptor() ([]byte, []int) { + return file_sys_menu_proto_rawDescGZIP(), []int{7} +} + +func (x *FindSysMenuPageRsp) GetEntries() []*FindSysMenuRsp { + if x != nil { + return x.Entries + } + return nil +} + +func (x *FindSysMenuPageRsp) GetPageData() *PageData { + if x != nil { + return x.PageData + } + return nil +} + +var File_sys_menu_proto protoreflect.FileDescriptor + +var file_sys_menu_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x73, 0x79, 0x73, 0x5f, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd6, + 0x01, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, + 0x52, 0x65, 0x71, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, + 0x65, 0x73, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x26, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x75, + 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6c, 0x69, 0x64, 0x22, + 0x26, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, + 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x75, 0x6c, 0x69, 0x64, 0x22, 0xea, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, + 0x75, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6c, 0x69, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, 0x63, + 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x70, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, + 0x54, 0x79, 0x70, 0x65, 0x22, 0x28, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, + 0x65, 0x6e, 0x75, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6c, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x6c, 0x69, 0x64, 0x22, 0xa4, + 0x02, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x73, + 0x70, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x75, 0x6c, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x42, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x42, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x79, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, + 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x65, 0x73, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x65, 0x73, + 0x63, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x70, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, + 0x14, 0x0a, 0x05, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, 0x64, + 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, + 0x64, 0x54, 0x79, 0x70, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, + 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x1c, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x09, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, + 0x50, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x26, 0x0a, 0x09, 0x73, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x73, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x22, 0x67, 0x0a, 0x12, 0x46, 0x69, + 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x50, 0x61, 0x67, 0x65, 0x52, 0x73, 0x70, + 0x12, 0x29, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x53, 0x79, 0x73, 0x4d, 0x65, 0x6e, 0x75, 0x52, + 0x73, 0x70, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x09, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, + 0x2e, 0x50, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x44, + 0x61, 0x74, 0x61, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_sys_menu_proto_rawDescOnce sync.Once + file_sys_menu_proto_rawDescData = file_sys_menu_proto_rawDesc +) + +func file_sys_menu_proto_rawDescGZIP() []byte { + file_sys_menu_proto_rawDescOnce.Do(func() { + file_sys_menu_proto_rawDescData = protoimpl.X.CompressGZIP(file_sys_menu_proto_rawDescData) + }) + return file_sys_menu_proto_rawDescData +} + +var file_sys_menu_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_sys_menu_proto_goTypes = []interface{}{ + (*CreateSysMenuReq)(nil), // 0: CreateSysMenuReq + (*CreateSysMenuRsp)(nil), // 1: CreateSysMenuRsp + (*DeleteSysMenuReq)(nil), // 2: DeleteSysMenuReq + (*UpdateSysMenuReq)(nil), // 3: UpdateSysMenuReq + (*FindSysMenuByIdReq)(nil), // 4: FindSysMenuByIdReq + (*FindSysMenuRsp)(nil), // 5: FindSysMenuRsp + (*FindSysMenuPageReq)(nil), // 6: FindSysMenuPageReq + (*FindSysMenuPageRsp)(nil), // 7: FindSysMenuPageRsp + (*Query)(nil), // 8: Query + (*PageData)(nil), // 9: PageData + (*SortData)(nil), // 10: SortData +} +var file_sys_menu_proto_depIdxs = []int32{ + 8, // 0: FindSysMenuPageReq.query:type_name -> Query + 9, // 1: FindSysMenuPageReq.page_data:type_name -> PageData + 10, // 2: FindSysMenuPageReq.sort_data:type_name -> SortData + 5, // 3: FindSysMenuPageRsp.entries:type_name -> FindSysMenuRsp + 9, // 4: FindSysMenuPageRsp.page_data:type_name -> PageData + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_sys_menu_proto_init() } +func file_sys_menu_proto_init() { + if File_sys_menu_proto != nil { + return + } + file_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_sys_menu_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateSysMenuReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateSysMenuRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteSysMenuReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateSysMenuReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindSysMenuByIdReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindSysMenuRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindSysMenuPageReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sys_menu_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FindSysMenuPageRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_sys_menu_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_sys_menu_proto_goTypes, + DependencyIndexes: file_sys_menu_proto_depIdxs, + MessageInfos: file_sys_menu_proto_msgTypes, + }.Build() + File_sys_menu_proto = out.File + file_sys_menu_proto_rawDesc = nil + file_sys_menu_proto_goTypes = nil + file_sys_menu_proto_depIdxs = nil +} diff --git a/system/interface/grpc/proto/goods/sys_menu.proto b/system/interface/grpc/proto/goods/sys_menu.proto new file mode 100644 index 0000000..63c7b6b --- /dev/null +++ b/system/interface/grpc/proto/goods/sys_menu.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; +option go_package = ".;proto"; +import "common.proto"; + +message CreateSysMenuReq { + string menuName = 1; // menu名称 + string desc = 2; // 描述 + string route = 3; // 菜单路由 + uint32 state = 4; // 1显示,2否 + uint64 pid = 5; // 父id + string pname = 6; // 父路由名称 + int32 sortOrder = 7; // 排序 + int32 backendType = 8; // 1总后台,2运营后台 + +} + +message CreateSysMenuRsp { + string ulid = 1; +} + +message DeleteSysMenuReq { + string ulid = 1; +} + +message UpdateSysMenuReq { + string ulid = 1; // ID + string menuName = 2; // menu名称 + string desc = 3; // 描述 + string route = 4; // 菜单路由 + uint32 state = 5; // 1显示,2否 + uint64 pid = 6; // 父id + string pname = 7; // 父路由名称 + int32 sortOrder = 8; // 排序 + int32 backendType = 9; // 1总后台,2运营后台 + +} + +message FindSysMenuByIdReq { + string ulid = 1; +} + +message FindSysMenuRsp { + string ulid = 1; // ID + string createdBy = 4; // 创建者 + string deletedBy = 5; // 删除者 + string menuName = 6; // menu名称 + string desc = 7; // 描述 + string route = 8; // 菜单路由 + uint32 state = 9; // 1显示,2否 + uint64 pid = 10; // 父id + string pname = 11; // 父路由名称 + int32 sortOrder = 12; // 排序 + int32 backendType = 13; // 1总后台,2运营后台 + +} + +message FindSysMenuPageReq{ + repeated Query query = 1; + PageData page_data = 2; + SortData sort_data = 3; +} + +message FindSysMenuPageRsp { + repeated FindSysMenuRsp entries = 1; + PageData page_data = 2; +} \ No newline at end of file diff --git a/system/interface/http/handler/private/handler.go b/system/interface/http/handler/private/handler.go new file mode 100644 index 0000000..6ba0a2d --- /dev/null +++ b/system/interface/http/handler/private/handler.go @@ -0,0 +1,8 @@ +package private + +type PrivateHandler struct { +} + +func NewPrivateHandler() *PrivateHandler { + return &PrivateHandler{} +} diff --git a/system/interface/http/handler/private/internal_handler.go b/system/interface/http/handler/private/internal_handler.go new file mode 100644 index 0000000..e6aca69 --- /dev/null +++ b/system/interface/http/handler/private/internal_handler.go @@ -0,0 +1,14 @@ +package private + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "jettjia/go-ddd-demo-multi-common/pkg/log" +) + +func (h *PrivateHandler) Demo(c *gin.Context) { + log.NewLogger().Infoln("aitext-go-ddd") // 自定义Log,建议使用 + c.JSON(http.StatusOK, "i am internal api") +} diff --git a/system/interface/http/handler/public/handler.go b/system/interface/http/handler/public/handler.go new file mode 100644 index 0000000..21e5502 --- /dev/null +++ b/system/interface/http/handler/public/handler.go @@ -0,0 +1,15 @@ +package public + +import ( + "jettjia/go-ddd-demo-multi-system/application/service" +) + +type Handler struct { + SysMenuSrv *service.SysMenuService +} + +func NewHandler(sysMenuSrv *service.SysMenuService) *Handler { + return &Handler{ + SysMenuSrv: sysMenuSrv, + } +} diff --git a/system/interface/http/handler/public/sys_menu_handler.go b/system/interface/http/handler/public/sys_menu_handler.go new file mode 100644 index 0000000..3fcd6ff --- /dev/null +++ b/system/interface/http/handler/public/sys_menu_handler.go @@ -0,0 +1,239 @@ +package public + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/gogf/gf/v2/errors/gerror" + + "jettjia/go-ddd-demo-multi-common/pkg/response" + "jettjia/go-ddd-demo-multi-common/pkg/validate" + + "jettjia/go-ddd-demo-multi-system/application/dto" + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +func (h *Handler) CreateSysMenu(c *gin.Context) { + // 参数解析 + dtoReq := dto.CreateSysMenuReq{} + err := c.BindJSON(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + tokenData, _ := entity.GinParse(c) + if tokenData != nil { + dtoReq.CreatedBy = tokenData.Username + } + + // 业务处理 + res, err := h.SysMenuSrv.CreateSysMenu(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + + response.RspOk(c, http.StatusCreated, res) +} + +func (h *Handler) DeleteSysMenu(c *gin.Context) { + // 参数解析 + dtoReq := dto.DelSysMenusReq{} + err := c.ShouldBindUri(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + tokenData, _ := entity.GinParse(c) + if tokenData != nil { + dtoReq.DeletedBy = tokenData.Username + } + + // 业务处理 + err = h.SysMenuSrv.DeleteSysMenu(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + + response.RspOk(c, http.StatusNoContent, nil) +} + +func (h *Handler) UpdateSysMenu(c *gin.Context) { + // 参数解析 + dtoReq := dto.UpdateSysMenuReq{} + err := c.ShouldBindUri(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + err = c.BindJSON(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + tokenData, _ := entity.GinParse(c) + if tokenData != nil { + dtoReq.UpdatedBy = tokenData.Username + } + + // 业务处理 + err = h.SysMenuSrv.UpdateSysMenu(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + + response.RspOk(c, http.StatusNoContent, nil) +} + +func (h *Handler) FindSysMenuById(c *gin.Context) { + // 参数解析 + dtoReq := dto.FindSysMenuByIdReq{} + err := c.ShouldBindUri(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 业务处理 + rsp, err := h.SysMenuSrv.FindSysMenuById(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + + if rsp.Ulid == "" { + err = gerror.NewCode(response.CommNotFound) + _ = c.Error(err) + return + } + + response.RspOk(c, http.StatusOK, rsp) +} + +func (h *Handler) FindSysMenuByQuery(c *gin.Context) { + // 参数解析 + dtoReq := dto.FindSysMenuByQueryReq{} + err := c.BindJSON(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 业务处理 + rsp, err := h.SysMenuSrv.FindSysMenuByQuery(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + + if rsp.Ulid == "" { + err = gerror.NewCode(response.CommNotFound) + _ = c.Error(err) + return + } + + response.RspOk(c, http.StatusOK, rsp) +} + +func (h *Handler) FindSysMenuAll(c *gin.Context) { + // 参数解析 + dtoReq := dto.FindSysMenuAllReq{} + err := c.BindJSON(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 业务处理 + rsp, err := h.SysMenuSrv.FindSysMenuAll(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + response.RspOk(c, http.StatusOK, rsp) +} + +func (h *Handler) FindSysMenuPage(c *gin.Context) { + // 参数解析 + dtoReq := dto.FindSysMenuPageReq{} + err := c.BindJSON(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 参数过滤 + err = validate.Validate(&dtoReq) + if err != nil { + err = gerror.NewCode(response.CommBadRequest, err.Error()) + _ = c.Error(err) + return + } + + // 业务处理 + rsp, err := h.SysMenuSrv.FindSysMenuPage(c, &dtoReq) + if err != nil { + _ = c.Error(err) + return + } + + response.RspOk(c, http.StatusOK, rsp) +} diff --git a/system/interface/http/http.go b/system/interface/http/http.go new file mode 100644 index 0000000..9184d9d --- /dev/null +++ b/system/interface/http/http.go @@ -0,0 +1,74 @@ +package http + +import ( + "fmt" + + "net/http" + "sync" + + "github.com/gin-gonic/gin" + + "jettjia/go-ddd-demo-multi-system/cmd" + "jettjia/go-ddd-demo-multi-system/interface/http/middleware" + "jettjia/go-ddd-demo-multi-system/interface/http/router" +) + +var wg sync.WaitGroup + +func InitHttp(server *cmd.Server) { + wg.Add(2) + // open api + go func() { + defer wg.Done() + runHttp(server, "public", true) + }() + + // private api + go func() { + defer wg.Done() + runHttp(server, "private", false) + }() + + wg.Wait() +} + +func runHttp(server *cmd.Server, portType string, jwtEnable bool) { + var ( + engine *gin.Engine + port int + ) + engineDefault := gin.Default() + gin.SetMode(server.Cfg.Server.Mode) + + // 配置跨域 + engineDefault.Use(middleware.Cors()) + // auth jwt + if jwtEnable { + engineDefault.Use(middleware.TokenAuthorization()) + } + // 全局recover + engineDefault.Use(middleware.CatchError()) + + // 健康检查 + engineDefault.GET("/health/ready", func(c *gin.Context) { + c.Writer.Header().Set("Content-Type", "application/json") + c.String(http.StatusOK, "ready") + }) + engineDefault.GET("/health/alive", func(c *gin.Context) { + c.Writer.Header().Set("Content-Type", "application/json") + c.String(http.StatusOK, "alive") + }) + + if portType == "public" { + engine = router.Routers(engineDefault, server) + port = server.Cfg.Server.PublicPort + } else { + engine = router.RoutersPrivate(engineDefault, server) + port = server.Cfg.Server.PrivatePort + } + + err := engine.Run(fmt.Sprintf(":%d", port)) // 启动web + if err != nil { + panic(err) + } +} diff --git a/system/interface/http/middleware/auth.go b/system/interface/http/middleware/auth.go new file mode 100644 index 0000000..fa5dcf4 --- /dev/null +++ b/system/interface/http/middleware/auth.go @@ -0,0 +1,46 @@ +package middleware + +import ( + "strings" + "time" + + "github.com/gin-gonic/gin" + "github.com/gogf/gf/v2/errors/gerror" + + "jettjia/go-ddd-demo-multi-common/pkg/response" + "jettjia/go-ddd-demo-multi-system/config" + "jettjia/go-ddd-demo-multi-system/domain/entity" +) + +func TokenAuthorization() gin.HandlerFunc { + return func(c *gin.Context) { + + conf := config.NewConfig() + if conf.Server.Dev { + return + } + + auth := c.GetHeader("Authorization") + token := strings.TrimPrefix(auth, "Bearer ") + if token == "" { + err := gerror.NewCode(response.CommUnauthorized, "Unauthorized") + response.RspErr(c, err) + c.Abort() + return + } + + // 校验token + claims, err := entity.ParseToken(token) + if err != nil { + err = gerror.NewCode(response.CommUnauthorized, "Unauthorized") + response.RspErr(c, err) + c.Abort() + return + } else if time.Now().Unix() > claims.ExpiresAt { + err = gerror.NewCode(response.CommUnauthorized, "Token expired") + response.RspErr(c, err) + c.Abort() + return + } + } +} diff --git a/system/interface/http/middleware/cors.go b/system/interface/http/middleware/cors.go new file mode 100644 index 0000000..7dd0b0e --- /dev/null +++ b/system/interface/http/middleware/cors.go @@ -0,0 +1,24 @@ +package middleware + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +// Cors 跨域 +func Cors() gin.HandlerFunc { + return func(c *gin.Context) { + method := c.Request.Method + + c.Header("Access-Control-Allow-Origin", "*") + c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token, x-token") + c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PATCH, PUT") + c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type") + c.Header("Access-Control-Allow-Credentials", "true") + + if method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + } + } +} diff --git a/system/interface/http/middleware/recover.go b/system/interface/http/middleware/recover.go new file mode 100644 index 0000000..332b51e --- /dev/null +++ b/system/interface/http/middleware/recover.go @@ -0,0 +1,72 @@ +package middleware + +import ( + "fmt" + "github.com/pkg/errors" + + "github.com/gin-gonic/gin" + "github.com/go-sql-driver/mysql" + "github.com/gogf/gf/v2/errors/gerror" + "github.com/sirupsen/logrus" + + "jettjia/go-ddd-demo-multi-common/pkg/log" + "jettjia/go-ddd-demo-multi-common/pkg/response" +) + +func CatchError() gin.HandlerFunc { + return func(c *gin.Context) { + defer func() { + // 捕获panic错误,比如 panic() + if errAny := recover(); errAny != nil { + // 记录到log + log.NewLogger().WithFields(logrus.Fields{"url": c.Request.URL.Path}). + WithFields(logrus.Fields{"method": c.Request.Method}). + Errorln(errAny) + + switch errAny.(type) { + case error: + // 统一处理 mysql 1062 错误,sql内容冲突 + var mysqlErr *mysql.MySQLError + if errors.As(errAny.(error), &mysqlErr) && mysqlErr.Number == 1062 { + response.RspErr(c, gerror.NewCode(response.CommConflict, mysqlErr.Message)) + c.Abort() + return + } + + // 统一处理 mysql 1054 错误,sql字段错误 + if errors.As(errAny.(error), &mysqlErr) && mysqlErr.Number == 1054 { + response.RspErr(c, gerror.NewCode(response.CommForbidden, mysqlErr.Message)) + c.Abort() + return + } + + // 统一处理 gorm NotFound + if errAny.(error).Error() == "record not found" { + response.RspErr(c, gerror.NewCode(response.CommNotFound, mysqlErr.Message)) + c.Abort() + return + } + + default: + // 统一处理 其他错误 + errorInfo := response.Panic(errAny) + response.RspErr(c, gerror.NewCode(response.CommInternalServer, fmt.Sprintf("errMsg:%+v; errStack:%+v", errAny, errorInfo.Internal))) // 前端返回 + c.Abort() + return + } + } + + // 手动抛出的错误,比如 errors.New() + if len(c.Errors) != 0 { + for _, errAny := range c.Errors { + // 统一处理 其他错误 + errorInfo := response.Panic(errAny) + response.RspErr(c, gerror.NewCode(response.CommInternalServer, fmt.Sprintf("errMsg:%+v; errStack:%+v", errAny, errorInfo.Internal))) // 前端返回 + c.Abort() + return + } + } + }() + c.Next() + } +} diff --git a/system/interface/http/router/private/internal_router.go b/system/interface/http/router/private/internal_router.go new file mode 100644 index 0000000..962c9c4 --- /dev/null +++ b/system/interface/http/router/private/internal_router.go @@ -0,0 +1,14 @@ +package private + +import ( + "github.com/gin-gonic/gin" + + handler "jettjia/go-ddd-demo-multi-system/interface/http/handler/private" +) + +func SetPrivateRouter(Router *gin.RouterGroup, hand *handler.PrivateHandler) { + UserRouter := Router.Group("/sys") + { + UserRouter.GET("/demo", hand.Demo) // demo + } +} diff --git a/system/interface/http/router/public/sys_menu_router.go b/system/interface/http/router/public/sys_menu_router.go new file mode 100644 index 0000000..3a52b29 --- /dev/null +++ b/system/interface/http/router/public/sys_menu_router.go @@ -0,0 +1,18 @@ +package public + +import ( + "github.com/gin-gonic/gin" + + handler "jettjia/go-ddd-demo-multi-system/interface/http/handler/public" +) + +func SetPublicRouter(Router *gin.RouterGroup, hand *handler.Handler) { + UserRouter := Router.Group("/sys") + { + UserRouter.POST("/menu", hand.CreateSysMenu) // 创建 + UserRouter.DELETE("/menu/:ulid", hand.DeleteSysMenu) // 删除 + UserRouter.PUT("/menu/:ulid", hand.UpdateSysMenu) // 修改 + UserRouter.GET("/menu/:ulid", hand.FindSysMenuById) // 查询ByID + UserRouter.POST("/menuPage", hand.FindSysMenuPage) // 查询分页 + } +} diff --git a/system/interface/http/router/router.go b/system/interface/http/router/router.go new file mode 100644 index 0000000..bee9b8e --- /dev/null +++ b/system/interface/http/router/router.go @@ -0,0 +1,31 @@ +package router + +import ( + "github.com/gin-gonic/gin" + + "jettjia/go-ddd-demo-multi-system/cmd" + "jettjia/go-ddd-demo-multi-system/interface/http/handler/private" + "jettjia/go-ddd-demo-multi-system/interface/http/handler/public" + privateRouter "jettjia/go-ddd-demo-multi-system/interface/http/router/private" + publicRouter "jettjia/go-ddd-demo-multi-system/interface/http/router/public" +) + +func Routers(engine *gin.Engine, server *cmd.Server) *gin.Engine { + // 注册路由 + ApiGroup := engine.Group("/api/pc/v1") + hand := public.NewHandler(server.Sys) + + publicRouter.SetPublicRouter(ApiGroup, hand) // sys + + return engine +} + +func RoutersPrivate(engine *gin.Engine, server *cmd.Server) *gin.Engine { + // 注册路由 + hand := private.NewPrivateHandler() + + ApiGroup := engine.Group("/private/pc/v1") + privateRouter.SetPrivateRouter(ApiGroup, hand) // sys + + return engine +} diff --git a/system/interface/job/job.go b/system/interface/job/job.go new file mode 100644 index 0000000..0711182 --- /dev/null +++ b/system/interface/job/job.go @@ -0,0 +1,4 @@ +package job + +func InitJob() { +} diff --git a/system/main.go b/system/main.go new file mode 100644 index 0000000..1a03911 --- /dev/null +++ b/system/main.go @@ -0,0 +1,56 @@ +package main + +import ( + "flag" + "os" + "os/signal" + "sync" + "syscall" + + "jettjia/go-ddd-demo-multi-system/cmd" + "jettjia/go-ddd-demo-multi-system/interface/event" + "jettjia/go-ddd-demo-multi-system/interface/grpc" + "jettjia/go-ddd-demo-multi-system/interface/http" + "jettjia/go-ddd-demo-multi-system/interface/job" +) + +var wg sync.WaitGroup + +func main() { + // 系统环境变量 + env := flag.String("env", "debug", "configure environment reading") + flag.Parse() + + os.Setenv("env", *env) + + // 依赖注入 + server, err := cmd.InitServer() + if err != nil { + panic(err) + } + + wg.Add(2) + // start http + go func() { + defer wg.Done() + http.InitHttp(server) + }() + + // start grpc + go func() { + defer wg.Done() + grpc.InitGrpc(server) + }() + + // start event mq + event.InitEvent() + + // start InitJob + job.InitJob() + + wg.Wait() + + quit := make(chan os.Signal) + signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) + <-quit +} diff --git a/system/manifest/config/config-debug.yaml b/system/manifest/config/config-debug.yaml new file mode 100644 index 0000000..97e1a97 --- /dev/null +++ b/system/manifest/config/config-debug.yaml @@ -0,0 +1,62 @@ +# HTTP Server. +server: + lang: zh-CN # "zh-CN", "zh-TW", "en" + public_port: 21800 # 对外端口 + private_port: 21801 # 对内端口 + server_name: "AitextGoDdd" + mode: "debug" # gin的模式配置 debug, test, release + dev: true # true,false;校验token等,开发模式的时候打开 + enable_event: false # 是否开启事件 + enable_job: false # 是否开启任务 + enable_grpc: true # 是否开启grpc + +# GRPC Server. +gserver: + host: "0.0.0.0" # 当前服务 + public_port: 21802 # 当前服务 + max_msg_size: 1024 # 最大发送接收字节数,单位 m + client_goods_host: "0.0.0.0" # goods服务的host + client_goods_port: 18080 # goods服务的port + +# Database. +mysql: + username: "root" + password: "admin123" + db_host: "10.4.7.71" + db_port: 3306 + db_name: "go_demo" + charset: "utf8mb4" + max_open_conn: 50 # 设置数据库连接池最大连接数 + max_idle_conn: 10 # 连接池最大允许的空闲连接数 + conn_max_lifetime: 500 # 设置连接可复用的最大时间 + log_mode: 4 # gorm错误级别; 1: Silent, 2:Error,3:Warn,4:Info + slow_threshold: 10 # 慢查询 + +# Log. +log: + log_file_dir: "/tmp/logs/" + max_size: 512 + max_backups: 64 + max_age: 7 + log_level: "debug" #自定义日志; trace, debug, info,panic, fatal, error, warn + log_out: "console" # console, file + +# nsq. +nsq: + nsq_producer_host: "10.4.7.71" + nsq_producer_port: 4150 # tcp + nsq_subscribe_host: "10.4.7.71" + nsq_subscribe_port: 4150 # tcp + +# otel +otel: + enable: false + export_endpoint: "10.4.7.71:4317" + +# redis +redis: + redis_type: "alone" # redis使用模式:alone, sentinel,cluster + addr: "10.4.7.71:6379" + password: "admin123" + master_name: "" + pool_size: 10 \ No newline at end of file diff --git a/system/manifest/config/config-release.yaml b/system/manifest/config/config-release.yaml new file mode 100644 index 0000000..4e4f1fe --- /dev/null +++ b/system/manifest/config/config-release.yaml @@ -0,0 +1,51 @@ +# HTTP Server. +server: + lang: zh-CN # "zh-CN", "zh-TW", "en" + public_port: 21800 # 对外端口 + private_port: 21801 # 对内端口 + server_name: "GoDddDemo" + mode: "debug" # gin的模式配置 debug, test, release + dev: "true" # true,false + +# GRPC Server. +gserver: + host: "0.0.0.0" # 当前服务 + public_port: 21802 # 当前服务 + max_msg_size: 1024 # 最大发送接收字节数,单位 m + client_goods_host: "0.0.0.0" # goods服务的host + client_goods_port: 18080 # goods服务的port + +# Database. +mysql: + username: "root" + password: "123456" + db_host: "10.4.7.71" + db_port: 3306 + db_name: "go_demo" + charset: "utf8mb4" + max_open_conn: 50 # 设置数据库连接池最大连接数 + max_idle_conn: 10 # 连接池最大允许的空闲连接数 + conn_max_lifetime: 500 # 设置连接可复用的最大时间 + log_mode: 4 # gorm错误级别; 1: Silent, 2:Error,3:Warn,4:Info + slow_threshold: 10 # 慢查询 + +# Log. +log: + log_file_dir: "./tmp/" + max_size: 512 + max_backups: 64 + max_age: 7 + log_level: "debug" # panic, fatal, error, warn, info, debug, trace + log_out: "file" # console, file + +# nsq. +nsq: + nsq_producer_host: "10.4.7.71" + nsq_producer_port: 4150 # tcp + nsq_subscribe_host: "10.4.7.71" + nsq_subscribe_port: 4150 # tcp + +# otel +otel: + enable: false + export_endpoint: "10.4.7.71:4317" \ No newline at end of file diff --git a/system/manifest/config/config-test.yaml b/system/manifest/config/config-test.yaml new file mode 100644 index 0000000..c1609c9 --- /dev/null +++ b/system/manifest/config/config-test.yaml @@ -0,0 +1,54 @@ +# HTTP Server. +server: + lang: zh-CN # "zh-CN", "zh-TW", "en" + public_port: 21800 # 对外端口 + private_port: 21801 # 对内端口 + server_name: "AitextGoDdd" + mode: "debug" # gin的模式配置 debug, test, release + dev: true # true,false;校验token等,开发模式的时候打开 + enable_event: false # 是否开启事件 + enable_job: false # 是否开启任务 + enable_grpc: false # 是否开启grpc + +# GRPC Server. +gserver: + host: "0.0.0.0" # 当前服务 + public_port: 21802 # 当前服务 + max_msg_size: 1024 # 最大发送接收字节数,单位 m + client_goods_host: "0.0.0.0" # goods服务的host + client_goods_port: 18080 # goods服务的port + +# Database. +mysql: + username: "root" + password: "admin123" + db_host: "10.4.7.71" + db_port: 3306 + db_name: "go_demo" + charset: "utf8mb4" + max_open_conn: 50 # 设置数据库连接池最大连接数 + max_idle_conn: 10 # 连接池最大允许的空闲连接数 + conn_max_lifetime: 500 # 设置连接可复用的最大时间 + log_mode: 4 # gorm错误级别; 1: Silent, 2:Error,3:Warn,4:Info + slow_threshold: 10 # 慢查询 + +# Log. +log: + log_file_dir: "/tmp/logs/" + max_size: 512 + max_backups: 64 + max_age: 7 + log_level: "debug" #自定义日志; trace, debug, info,panic, fatal, error, warn + log_out: "console" # console, file + +# nsq. +nsq: + nsq_producer_host: "10.4.7.71" + nsq_producer_port: 4150 # tcp + nsq_subscribe_host: "10.4.7.71" + nsq_subscribe_port: 4150 # tcp + +# otel +otel: + enable: false + export_endpoint: "10.4.7.71:4317" \ No newline at end of file diff --git a/system/manifest/i18n/en/error.toml b/system/manifest/i18n/en/error.toml new file mode 100644 index 0000000..95af95c --- /dev/null +++ b/system/manifest/i18n/en/error.toml @@ -0,0 +1,6 @@ +BadRequest = "Invalid parameter" +Unauthorized = "Unauthorized" +Forbidden = "Forbidden" +NotFound = "Record does not exist" +Conflict = "The request is conflicts" +InternalServerError = "Internal Server Error" \ No newline at end of file diff --git a/system/manifest/i18n/zh-CN/error.toml b/system/manifest/i18n/zh-CN/error.toml new file mode 100644 index 0000000..771c95c --- /dev/null +++ b/system/manifest/i18n/zh-CN/error.toml @@ -0,0 +1,6 @@ +BadRequest = "参数不合法" +Unauthorized = "授权无效" +Forbidden = "禁止访问" +NotFound = "资源不存在" +Conflict = "请求冲突" +InternalServerError = "内部错误" \ No newline at end of file diff --git a/system/manifest/i18n/zh-TW/error.toml b/system/manifest/i18n/zh-TW/error.toml new file mode 100644 index 0000000..7c01c06 --- /dev/null +++ b/system/manifest/i18n/zh-TW/error.toml @@ -0,0 +1,6 @@ +BadRequest = "參數不合法" +Unauthorized = "授權無效" +Forbidden = "禁止訪問" +NotFound = "資源不存在" +Conflict = "請求沖突" +InternalServerError = "內部錯誤" \ No newline at end of file