Browse Source

project: 框架接口输入输出封装

Yi 1 year ago
parent
commit
cc0d2804ac

+ 7 - 0
backend/operation/mobile.proto

@@ -11,12 +11,19 @@ message SearchMobileRequest {
 }
 
 message SearchMobileResponse {
+  int64 code = 1;
+  string msg = 2;
+  SearchMobileData data = 3;
+}
+
+message SearchMobileData {
   int32 page = 1;
   int32 total = 2;
   int32 page_size = 3;
   repeated  MobileData list = 4;
 }
 
+
 message MobileData {
   int64  id = 1;
   string name = 2;

+ 18 - 0
backend/operation/pasture.proto

@@ -28,6 +28,12 @@ message SearchPastureRequest {
 }
 
 message SearchPastureResponse {
+  int64 code = 1;
+  string msg = 2;
+  SearchPastureData data = 3;
+}
+
+message SearchPastureData {
   int32 page = 1;
   int32 total = 2;
   repeated AddPastureRequest list = 3;
@@ -71,6 +77,12 @@ message SearchCattleCategoryRequest {
 }
 
 message SearchCattleCategoryResponse {
+  int64 code = 1;
+  string msg = 2;
+  SearchCattleCategoryData data = 3;
+}
+
+message SearchCattleCategoryData {
   int32 page = 1;
   int32 total = 2;
   repeated AddCattleCategoryRequest list = 3;
@@ -103,6 +115,12 @@ message SearchForageCategoryRequest {
 }
 
 message SearchForageCategoryResponse {
+  int64 code = 1;
+  string msg = 2;
+    SearchForageCategoryData data = 3;
+}
+
+message SearchForageCategoryData {
   int32 page = 1;
   int32 total = 2;
   repeated AddForageCategoryRequest list = 3;

+ 50 - 7
backend/operation/system.proto

@@ -6,6 +6,17 @@ option go_package = ".;operationPb";
 import "backend/operation/enum.proto";
 import "backend/operation/pagination.proto";
 import "backend/operation/pasture.proto";
+
+message CommonOK {
+  int64 code = 1;
+  string msg = 2;
+  Success data = 3;
+}
+
+message Success {
+  bool success = 1;
+}
+
 // 用户角色
 message AddRoleRequest {
   int64 id = 1;
@@ -41,11 +52,23 @@ message RolePermissionsList {
 
 // 用户token
 message SystemToken {
+  int64 code =  1;
+  string msg = 2;
+  TokenData data = 3;
+}
+
+message TokenData {
   string token = 1;
 }
 
 // 用户登录
 message UserAuth {
+  int64 code = 1;
+  string msg = 2;
+  UserAuthData data = 3;
+}
+
+message UserAuthData {
   string user_name = 1;   // 用户名称
   string password = 2;    // 用户密码
   string phone = 3;       // 用户手机号
@@ -68,6 +91,7 @@ message AddSystemUser {
   string create_user = 7;          // 创建人
   int64 created_at = 8;            // 创建时间
   string created_at_format = 9;      // 创建时间格式化
+  string role_name = 10;            // 角色名称
 }
 
 // 查询用户
@@ -81,9 +105,16 @@ message SearchUserRequest {
 }
 
 message SearchUserResponse {
+    int32 code = 1;
+    string msg = 2;
+    SearchUserData data = 3;
+}
+
+message SearchUserData  {
   int32 page = 1;
   int32 total = 2;
-  repeated AddSystemUser list = 3;
+  int32 page_size = 3;
+  repeated AddSystemUser list = 4;
 }
 
 message IsShowSystemUserRequest {
@@ -94,11 +125,11 @@ message IsShowSystemUserRequest {
 // 系统菜单权限
 message AddMenuRequest {
   int64 id = 1;
-  string name = 2;       // 名称
-  int64 parent_id = 3;   // 父id
-  int32 menu_type = 4;  // 菜单类型 1 菜单 2 按钮
-  string title = 5;      // 标题
-  string path = 6;       // 路径 path
+  string name = 2;           // 名称
+  int64 parent_id = 3;       // 父id
+  int32 menu_type = 4;       // 菜单类型 1 菜单 2 按钮
+  string title = 5;          // 标题
+  string path = 6;           // 路径 path
   IsShow.Kind is_show = 7;   // 是否显示
   string component = 8;      // 组件
   string icon = 9;           // 图标
@@ -106,7 +137,7 @@ message AddMenuRequest {
   string redirect = 11;      // 重定向
   int64 created_at = 12;     // 创建时间
   string created_at_format = 13;      // 创建时间格式化
-  int32 level = 14;      // 菜单等级
+  int32 level = 14;                   // 菜单等级
   repeated AddMenuRequest children = 15;   // 子分类
   bool affix = 16;
   bool keepAlive = 17;
@@ -124,6 +155,12 @@ message SearchMenuRequest {
 }
 
 message SearchMenuResponse {
+  int64 code = 1;
+  string msg = 2;
+  SearchMenuData data = 3;
+}
+
+message SearchMenuData {
   int32 page = 1;
   int32 total = 2;
   repeated AddMenuRequest list = 3;
@@ -131,6 +168,12 @@ message SearchMenuResponse {
 
 // 系统用户权限相关
 message SystemUserMenuPermissions {
+  int64 code = 1;
+  string msg = 2;
+  SystemUserMenuData data = 3;
+}
+
+message SystemUserMenuData {
   repeated AddPastureRequest pasture_list = 1;    // 牧场列表
   repeated AddMenuRequest menu_list = 2;          // 菜单列表
   repeated AddMobileRequest mobile_list = 3;      // 移动端权限

+ 7 - 0
config/app.go

@@ -28,6 +28,13 @@ type AppConfig struct {
 	// redis 配置
 	RedisSetting RedisSetting `json:"RedisSetting" yaml:"redis_setting"`
 	JwtSecret    string       `json:"jwtSecret" yaml:"jwt_secret"`
+
+	ExcelSetting ExcelSetting `json:"excelSetting" yaml:"excel_setting"`
+}
+
+type ExcelSetting struct {
+	SheetName string  `yaml:"sheet_name"` // = "Sheet1" //默认Sheet名称
+	Height    float64 `yaml:"height"`     // = 25.0     //默认行高度
 }
 
 // StoreSetting 数据库配置

+ 5 - 1
config/app.test.yaml

@@ -17,4 +17,8 @@ redis_setting:
     requirepass: ""
     expiry: 120
 
-jwt_secret: "sUd7j%UfJMt59ywh"
+jwt_secret: "sUd7j%UfJMt59ywh"
+
+excel_setting:
+  sheet_name: "Sheet1"
+  height: 25.0

+ 2 - 0
dep/dep.go

@@ -4,6 +4,7 @@ import (
 	"kpt-tmr-group/config"
 	"kpt-tmr-group/module/backend"
 	"kpt-tmr-group/pkg/di"
+	"kpt-tmr-group/service/excel"
 	"kpt-tmr-group/service/sso"
 	"kpt-tmr-group/store/kptstore"
 )
@@ -25,5 +26,6 @@ func Options() []di.HubOption {
 		kptstore.Module,
 		backend.Module,
 		sso.Module,
+		excel.Module,
 	}
 }

+ 19 - 4
go.mod

@@ -27,8 +27,11 @@ require (
 	github.com/spf13/cobra v1.7.0
 	github.com/spf13/viper v1.15.0
 	github.com/stretchr/testify v1.8.2
+	github.com/xuri/excelize/v2 v2.7.1
 	go.uber.org/dig v1.15.0
 	go.uber.org/zap v1.21.0
+	golang.org/x/oauth2 v0.5.0
+	google.golang.org/api v0.107.0
 	google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef
 	google.golang.org/grpc v1.52.0
 	google.golang.org/protobuf v1.30.0
@@ -37,6 +40,8 @@ require (
 )
 
 require (
+	cloud.google.com/go/compute v1.14.0 // indirect
+	cloud.google.com/go/compute/metadata v0.2.3 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/bytedance/sonic v1.8.0 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
@@ -49,7 +54,10 @@ require (
 	github.com/go-playground/validator/v10 v10.11.2 // indirect
 	github.com/go-sql-driver/mysql v1.7.0 // indirect
 	github.com/goccy/go-json v0.10.0 // indirect
+	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/google/uuid v1.3.0 // indirect
+	github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect
+	github.com/googleapis/gax-go/v2 v2.7.0 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
@@ -63,6 +71,7 @@ require (
 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.6 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
@@ -70,6 +79,8 @@ require (
 	github.com/prometheus/client_model v0.3.0 // indirect
 	github.com/prometheus/common v0.42.0 // indirect
 	github.com/prometheus/procfs v0.9.0 // indirect
+	github.com/richardlehane/mscfb v1.0.4 // indirect
+	github.com/richardlehane/msoleps v1.0.3 // indirect
 	github.com/spf13/afero v1.9.3 // indirect
 	github.com/spf13/cast v1.5.0 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
@@ -77,13 +88,17 @@ require (
 	github.com/subosito/gotenv v1.4.2 // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.9 // indirect
+	github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
+	github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
+	go.opencensus.io v0.24.0 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.8.0 // indirect
 	golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
-	golang.org/x/crypto v0.7.0 // indirect
-	golang.org/x/net v0.8.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/text v0.8.0 // indirect
+	golang.org/x/crypto v0.8.0 // indirect
+	golang.org/x/net v0.9.0 // indirect
+	golang.org/x/sys v0.7.0 // indirect
+	golang.org/x/text v0.9.0 // indirect
+	google.golang.org/appengine v1.6.7 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect

+ 62 - 8
go.sum

@@ -17,14 +17,20 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
 cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
 cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
 cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
+cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
 cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0=
+cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
+cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
+cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -123,6 +129,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
@@ -157,6 +165,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 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=
@@ -179,8 +188,12 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 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/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg=
+github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
+github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
@@ -246,6 +259,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
 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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
 github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
 github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
 github.com/nyaruka/phonenumbers v1.1.7 h1:5UUI9hE79Kk0dymSquXbMYB7IlNDNhvu2aNlJpm9et8=
@@ -276,6 +291,11 @@ github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI
 github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
 github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
 github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
+github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
+github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
+github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
+github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
+github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
@@ -319,17 +339,26 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6
 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
 github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
 github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c=
+github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
+github.com/xuri/excelize/v2 v2.7.1 h1:gm8q0UCAyaTt3MEF5wWMjVdmthm2EHAWesGSKS9tdVI=
+github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZOmcF4nTpY=
+github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
+github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
+go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
 go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@@ -353,9 +382,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -368,6 +398,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
+golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
 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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -390,6 +422,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -420,12 +454,15 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -435,6 +472,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
 golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
+golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
 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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -446,6 +485,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -488,12 +529,18 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/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-20220722155257-8c9f86f7a55f/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 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -501,8 +548,10 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -557,6 +606,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 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=
@@ -580,12 +631,15 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
 google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
 google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU=
+google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
 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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=

+ 1 - 2
http/handler/mobile/mobile_list.go

@@ -3,7 +3,6 @@ package mobile
 import (
 	"kpt-tmr-group/http/middleware"
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
 	"kpt-tmr-group/pkg/ginutil"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
 	"net/http"
@@ -30,5 +29,5 @@ func SearchMobileList(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }

+ 54 - 21
http/handler/pasture/cattle_forage_category.go

@@ -3,7 +3,7 @@ package pasture
 import (
 	"kpt-tmr-group/http/middleware"
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
+	"kpt-tmr-group/pkg/ginutil"
 	"kpt-tmr-group/pkg/valid"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
 	"net/http"
@@ -12,15 +12,16 @@ import (
 	"github.com/gin-gonic/gin"
 )
 
-// ParentCattleCategoryList 牲畜父类列表
+/*// ParentCattleCategoryList 牲畜父类列表
 func ParentCattleCategoryList(c *gin.Context) {
 	res := middleware.BackendOperation(c).OpsService.ParentCattleCategoryList(c)
 	c.JSON(http.StatusOK, apiok.CommonResponse(res))
 }
+*/
 
 func AddCattleCategory(c *gin.Context) {
 	var req operationPb.AddCattleCategoryRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -39,12 +40,16 @@ func AddCattleCategory(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func EditCattleCategory(c *gin.Context) {
 	var req operationPb.AddCattleCategoryRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -64,12 +69,16 @@ func EditCattleCategory(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func IsShowCattleCategory(c *gin.Context) {
 	var req operationPb.IsShowCattleCategory
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -86,7 +95,11 @@ func IsShowCattleCategory(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func DeleteCattleCategory(c *gin.Context) {
@@ -103,12 +116,16 @@ func DeleteCattleCategory(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func SearchCattleCategory(c *gin.Context) {
 	req := &operationPb.SearchCattleCategoryRequest{}
-	if err := c.BindJSON(req); err != nil {
+	if err := ginutil.BindProto(c, req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -125,18 +142,18 @@ func SearchCattleCategory(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(res.ToPB()))
+	ginutil.JSONResp(c, res)
 }
 
-// ParentForageCategoryList 饲料父类列表
+/*// ParentForageCategoryList 饲料父类列表
 func ParentForageCategoryList(c *gin.Context) {
 	res := middleware.BackendOperation(c).OpsService.ParentForageCategoryList(c)
 	c.JSON(http.StatusOK, apiok.CommonResponse(res))
-}
+}*/
 
 func AddForageCategory(c *gin.Context) {
 	var req operationPb.AddForageCategoryRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -155,12 +172,16 @@ func AddForageCategory(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func EditForageCategory(c *gin.Context) {
 	var req operationPb.AddForageCategoryRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -180,12 +201,16 @@ func EditForageCategory(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func IsShowForageCategory(c *gin.Context) {
 	var req operationPb.IsShowForageCategory
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -202,7 +227,11 @@ func IsShowForageCategory(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func DeleteForageCategory(c *gin.Context) {
@@ -219,7 +248,11 @@ func DeleteForageCategory(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func SearchForageCategory(c *gin.Context) {
@@ -241,5 +274,5 @@ func SearchForageCategory(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(res.ToPB()))
+	ginutil.JSONResp(c, res)
 }

+ 74 - 10
http/handler/pasture/forage_list.go

@@ -3,7 +3,7 @@ package pasture
 import (
 	"kpt-tmr-group/http/middleware"
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
+	"kpt-tmr-group/pkg/ginutil"
 	"kpt-tmr-group/pkg/valid"
 	"kpt-tmr-group/pkg/xerr"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
@@ -35,7 +35,11 @@ func AddForage(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func EditForage(c *gin.Context) {
@@ -62,12 +66,16 @@ func EditForage(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func SearchForageList(c *gin.Context) {
 	req := &operationPb.SearchForageListRequest{}
-	if err := c.BindJSON(req); err != nil {
+	if err := ginutil.BindProto(c, req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -83,14 +91,13 @@ func SearchForageList(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }
 
 // SearchForageEnumList 饲料列表公共枚举
 func SearchForageEnumList(c *gin.Context) {
 	res := middleware.BackendOperation(c).OpsService.ForageEnumList(c)
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }
 
 func DeleteForageList(c *gin.Context) {
@@ -109,8 +116,11 @@ func DeleteForageList(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
-
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func IsShowForage(c *gin.Context) {
@@ -132,5 +142,59 @@ func IsShowForage(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
+}
+
+func ImportForage(c *gin.Context) {
+	if err := func(c *gin.Context) error {
+		if c.ContentType() != "application/octet-stream" {
+			return xerr.Custom("invalid Content-Type")
+		}
+		if c.Request.Body == nil || int(c.Request.ContentLength) <= 0 {
+			return xerr.Custom("invalid body")
+		}
+		return nil
+	}(c); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := middleware.BackendOperation(c).OpsService.ImportForage(c); err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
+}
+
+func ExportForage(c *gin.Context) {
+	req := &operationPb.SearchForageListRequest{}
+	if err := c.BindJSON(req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	req.Pagination = &operationPb.PaginationModel{
+		Page:       int32(c.GetInt(middleware.Page)),
+		PageSize:   int32(c.GetInt(middleware.PageSize)),
+		PageOffset: int32(c.GetInt(middleware.PageOffset)),
+	}
+
+	if err := middleware.BackendOperation(c).OpsService.ExportForage(c, req); err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }

+ 31 - 12
http/handler/pasture/pasture_list.go

@@ -3,7 +3,7 @@ package pasture
 import (
 	"kpt-tmr-group/http/middleware"
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
+	"kpt-tmr-group/pkg/ginutil"
 	"kpt-tmr-group/pkg/valid"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
 	"net/http"
@@ -14,7 +14,7 @@ import (
 
 func AddGroupPasture(c *gin.Context) {
 	var req operationPb.AddPastureRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -34,12 +34,16 @@ func AddGroupPasture(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func EditGroupPasture(c *gin.Context) {
 	var req operationPb.AddPastureRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -60,7 +64,11 @@ func EditGroupPasture(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func SearchGroupPastureList(c *gin.Context) {
@@ -81,8 +89,7 @@ func SearchGroupPastureList(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-
-	c.JSON(http.StatusOK, apiok.CommonResponse(res.ToPB()))
+	ginutil.JSONResp(c, res)
 }
 
 func DeleteGroupPasture(c *gin.Context) {
@@ -99,12 +106,16 @@ func DeleteGroupPasture(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func ResetPasswordGroupPasture(c *gin.Context) {
 	var req operationPb.RestPasswordGroupPasture
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -121,12 +132,16 @@ func ResetPasswordGroupPasture(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 func IsShowGroupPasture(c *gin.Context) {
 	var req operationPb.IsShowGroupPasture
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -143,5 +158,9 @@ func IsShowGroupPasture(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }

+ 27 - 12
http/handler/system/menu.go

@@ -3,7 +3,7 @@ package system
 import (
 	"kpt-tmr-group/http/middleware"
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
+	"kpt-tmr-group/pkg/ginutil"
 	"kpt-tmr-group/pkg/valid"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
 	"net/http"
@@ -15,7 +15,7 @@ import (
 // AddSystemMenu 添加系统菜单权限
 func AddSystemMenu(c *gin.Context) {
 	var req operationPb.AddMenuRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -43,13 +43,17 @@ func AddSystemMenu(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // EditSystemMenu 编辑系统菜单权限
 func EditSystemMenu(c *gin.Context) {
 	var req operationPb.AddMenuRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -76,14 +80,17 @@ func EditSystemMenu(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // IsShowSystemMenu 是否启动
 func IsShowSystemMenu(c *gin.Context) {
 	var req operationPb.IsShowSystemMenuRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -100,13 +107,17 @@ func IsShowSystemMenu(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // SearchSystemMenuList 菜单列表查询
 func SearchSystemMenuList(c *gin.Context) {
 	var req operationPb.SearchMenuRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -122,7 +133,7 @@ func SearchSystemMenuList(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }
 
 // DeleteSystemMenu 删除菜单
@@ -135,10 +146,14 @@ func DeleteSystemMenu(c *gin.Context) {
 		return
 	}
 
-	if err := middleware.BackendOperation(c).OpsService.DeleteSystemRole(c, int64(menuId)); err != nil {
+	if err := middleware.BackendOperation(c).OpsService.DeleteSystemMenu(c, int64(menuId)); err != nil {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }

+ 31 - 16
http/handler/system/user.go

@@ -3,7 +3,7 @@ package system
 import (
 	"kpt-tmr-group/http/middleware"
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
+	"kpt-tmr-group/pkg/ginutil"
 	"kpt-tmr-group/pkg/valid"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
 	"net/http"
@@ -14,8 +14,8 @@ import (
 
 // Auth 用户登录
 func Auth(c *gin.Context) {
-	var req operationPb.UserAuth
-	if err := c.BindJSON(&req); err != nil {
+	var req operationPb.UserAuthData
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -33,13 +33,13 @@ func Auth(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }
 
 // AddSystemUser 创建系统用户
 func AddSystemUser(c *gin.Context) {
 	var req operationPb.AddSystemUser
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -60,7 +60,11 @@ func AddSystemUser(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // GetUserInfo 获取用户信息
@@ -75,13 +79,13 @@ func GetUserInfo(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }
 
 // SearchSystemUserList 查询系统用户列表
 func SearchSystemUserList(c *gin.Context) {
 	var req operationPb.SearchUserRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -104,13 +108,13 @@ func SearchSystemUserList(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }
 
 // EditSystemUser 编辑系统用户
 func EditSystemUser(c *gin.Context) {
 	var req operationPb.AddSystemUser
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -131,7 +135,11 @@ func EditSystemUser(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // DeleteUser 删除系统用户
@@ -149,13 +157,17 @@ func DeleteUser(c *gin.Context) {
 		return
 	}
 
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // IsShowSystemUser 系统用户启动开关
 func IsShowSystemUser(c *gin.Context) {
 	var req operationPb.IsShowSystemUserRequest
-	if err := c.BindJSON(&req); err != nil {
+	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
@@ -172,7 +184,11 @@ func IsShowSystemUser(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(apiok.NewApiOk(true)))
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
 }
 
 // GetSystemUserPermissions 获取系统用户菜单权限
@@ -188,6 +204,5 @@ func GetSystemUserPermissions(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-
-	c.JSON(http.StatusOK, apiok.CommonResponse(res))
+	ginutil.JSONResp(c, res)
 }

+ 2 - 0
http/route/app_api.go

@@ -81,6 +81,8 @@ func AppAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		opsRoute.POST("/forage/list", pasture.SearchForageList)
 		opsRoute.POST("forage/delete", pasture.DeleteForageList)
 		opsRoute.POST("forage/is_show", pasture.IsShowForage)
+		opsRoute.POST("forage/import", pasture.ImportForage)
+		opsRoute.POST("forage/export", pasture.ExportForage)
 		opsRoute.GET("/forage/enum/list", pasture.SearchForageEnumList)
 	}
 }

+ 0 - 14
model/cattle_category.go

@@ -62,17 +62,3 @@ func (c *CattleCategory) ToPb() *operationPb.AddCattleCategoryRequest {
 		CreatedAt:  c.CreatedAt,
 	}
 }
-
-type CattleCategoryResponse struct {
-	Page  int32                                   `json:"page"`
-	Total int32                                   `json:"total"`
-	List  []*operationPb.AddCattleCategoryRequest `json:"list"`
-}
-
-func (c *CattleCategoryResponse) ToPB() *operationPb.SearchCattleCategoryResponse {
-	return &operationPb.SearchCattleCategoryResponse{
-		Page:  c.Page,
-		Total: c.Total,
-		List:  c.List,
-	}
-}

+ 0 - 14
model/forage_category.go

@@ -62,17 +62,3 @@ func (c *ForageCategory) ToPb() *operationPb.AddForageCategoryRequest {
 		CreatedAt:  c.CreatedAt,
 	}
 }
-
-type ForageCategoryResponse struct {
-	Page  int32                                   `json:"page"`
-	Total int32                                   `json:"total"`
-	List  []*operationPb.AddForageCategoryRequest `json:"list"`
-}
-
-func (c *ForageCategoryResponse) ToPB() *operationPb.SearchForageCategoryResponse {
-	return &operationPb.SearchForageCategoryResponse{
-		Page:  c.Page,
-		Total: c.Total,
-		List:  c.List,
-	}
-}

+ 0 - 14
model/group_pasture.go

@@ -69,17 +69,3 @@ func (g *GroupPasture) ToPb() *operationPb.AddPastureRequest {
 		CreatedAt:    g.CreatedAt,
 	}
 }
-
-type GroupPastureResponse struct {
-	Page  int32                            `json:"page"`
-	Total int32                            `json:"total"`
-	List  []*operationPb.AddPastureRequest `json:"list"`
-}
-
-func (g *GroupPastureResponse) ToPB() *operationPb.SearchPastureResponse {
-	return &operationPb.SearchPastureResponse{
-		Page:  g.Page,
-		Total: g.Total,
-		List:  g.List,
-	}
-}

+ 1 - 14
model/system_menu.go

@@ -37,6 +37,7 @@ func NewSystemMenu(req *operationPb.AddMenuRequest) *SystemMenu {
 	return &SystemMenu{
 		Name:      req.Name,
 		MenuType:  req.MenuType,
+		Level:     req.Level,
 		Title:     req.Title,
 		Path:      req.Path,
 		Component: req.Component,
@@ -120,17 +121,3 @@ func (s *SystemMenu) ToPb() *operationPb.AddMenuRequest {
 		CreatedAt: s.CreatedAt,
 	}
 }
-
-type SystemMenuResponse struct {
-	Page  int32                         `json:"page"`
-	Total int32                         `json:"total"`
-	List  []*operationPb.AddMenuRequest `json:"list"`
-}
-
-func (s *SystemMenuResponse) ToPB() *operationPb.SearchMenuResponse {
-	return &operationPb.SearchMenuResponse{
-		Page:  s.Page,
-		Total: s.Total,
-		List:  s.List,
-	}
-}

+ 25 - 19
model/system_user.go

@@ -3,6 +3,7 @@ package model
 import (
 	"fmt"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"net/http"
 	"strconv"
 	"strings"
 	"time"
@@ -36,10 +37,14 @@ func (s *SystemUser) SystemUserFormat(userRoles []*SystemRole) *operationPb.User
 	}
 
 	return &operationPb.UserAuth{
-		UserName:     s.Name,
-		Phone:        s.Phone,
-		EmployeeName: s.EmployeeName,
-		Roles:        roles,
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.UserAuthData{
+			UserName:     s.Name,
+			Phone:        s.Phone,
+			EmployeeName: s.EmployeeName,
+			Roles:        roles,
+		},
 	}
 }
 
@@ -68,7 +73,7 @@ func (s *SystemUser) SystemUserRoleToSlice() []int {
 
 type SystemUserSlice []*SystemUser
 
-func (s SystemUserSlice) ToPB() []*operationPb.AddSystemUser {
+func (s SystemUserSlice) ToPB(roleList []*SystemRole) []*operationPb.AddSystemUser {
 	res := make([]*operationPb.AddSystemUser, len(s))
 	for i, v := range s {
 		res[i] = &operationPb.AddSystemUser{
@@ -80,11 +85,26 @@ func (s SystemUserSlice) ToPB() []*operationPb.AddSystemUser {
 			IsShow:          v.IsShow,
 			CreatedAt:       v.CreatedAt,
 			CreatedAtFormat: time.Unix(v.CreatedAt, 0).Format(LayoutTime),
+			RoleName:        strings.TrimRight(v.UserRoleFormat(roleList), ","),
 		}
 	}
 	return res
 }
 
+func (s *SystemUser) UserRoleFormat(roleList []*SystemRole) string {
+	ids := strings.Split(s.RoleIds, ",")
+	roleListName := ""
+	for _, id := range ids {
+		for _, r := range roleList {
+			if fmt.Sprintf("%d", r.Id) != id {
+				continue
+			}
+			roleListName += fmt.Sprintf("%s,", r.Name)
+		}
+	}
+	return roleListName
+}
+
 func (s *SystemUser) ToPb() *operationPb.AddSystemUser {
 	return &operationPb.AddSystemUser{
 		Id:           s.Id,
@@ -96,17 +116,3 @@ func (s *SystemUser) ToPb() *operationPb.AddSystemUser {
 		CreatedAt:    s.CreatedAt,
 	}
 }
-
-type SystemUserResponse struct {
-	Page  int32                        `json:"page"`
-	Total int32                        `json:"total"`
-	List  []*operationPb.AddSystemUser `json:"list"`
-}
-
-func (s *SystemUserResponse) ToPB() *operationPb.SearchUserResponse {
-	return &operationPb.SearchUserResponse{
-		Page:  s.Page,
-		Total: s.Total,
-		List:  s.List,
-	}
-}

+ 12 - 7
module/backend/interface.go

@@ -3,11 +3,13 @@ package backend
 import (
 	"context"
 	"kpt-tmr-group/config"
-	"kpt-tmr-group/model"
 	"kpt-tmr-group/pkg/di"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"kpt-tmr-group/service/excel"
 	"kpt-tmr-group/store/kptstore"
 
+	"github.com/gin-gonic/gin"
+
 	"go.uber.org/dig"
 )
 
@@ -26,6 +28,7 @@ type StoreEntry struct {
 	//SSO *sso.Cache
 	// AsynqClient asynqsvc.Client
 	// Cache *redis.Client
+	ExcelClient *excel.ExcelServer
 }
 
 func NewStore(store StoreEntry) KptService {
@@ -41,7 +44,7 @@ type Operation interface {
 	// CreateGroupPasture 牧场管理相关
 	CreateGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error
 	EditGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error
-	SearchGroupPastureList(ctx context.Context, req *operationPb.SearchPastureRequest) (*model.GroupPastureResponse, error)
+	SearchGroupPastureList(ctx context.Context, req *operationPb.SearchPastureRequest) (*operationPb.SearchPastureResponse, error)
 	DeleteGroupPasture(ctx context.Context, pastureId int64) error
 	ResetPasswordGroupPasture(ctx context.Context, req *operationPb.RestPasswordGroupPasture) error
 	IsShowGroupPasture(ctx context.Context, req *operationPb.IsShowGroupPasture) error
@@ -52,7 +55,7 @@ type Operation interface {
 	EditCattleCategory(ctx context.Context, req *operationPb.AddCattleCategoryRequest) error
 	IsShowCattleCategory(ctx context.Context, req *operationPb.IsShowCattleCategory) error
 	DeleteCattleCategory(ctx context.Context, cattleCategoryId int64) error
-	SearchCattleCategoryList(ctx context.Context, req *operationPb.SearchCattleCategoryRequest) (*model.CattleCategoryResponse, error)
+	SearchCattleCategoryList(ctx context.Context, req *operationPb.SearchCattleCategoryRequest) (*operationPb.SearchCattleCategoryResponse, error)
 
 	// ParentForageCategoryList 饲料类别相关
 	ParentForageCategoryList(ctx context.Context) map[operationPb.ForageCategoryParent_Kind]string
@@ -60,7 +63,7 @@ type Operation interface {
 	EditForageCategory(ctx context.Context, req *operationPb.AddForageCategoryRequest) error
 	IsShowForageCategory(ctx context.Context, req *operationPb.IsShowForageCategory) error
 	DeleteForageCategory(ctx context.Context, cattleCategoryId int64) error
-	SearchForageCategoryList(ctx context.Context, req *operationPb.SearchForageCategoryRequest) (*model.ForageCategoryResponse, error)
+	SearchForageCategoryList(ctx context.Context, req *operationPb.SearchForageCategoryRequest) (*operationPb.SearchForageCategoryResponse, error)
 
 	// CreateForage 饲料相关
 	CreateForage(ctx context.Context, req *operationPb.AddForageRequest) error
@@ -69,14 +72,16 @@ type Operation interface {
 	ForageEnumList(ctx context.Context) *ForageEnumList
 	DeleteForageList(ctx context.Context, ids []int64) error
 	IsShowForage(ctx context.Context, req *operationPb.IsShowForage) error
+	ImportForage(ctx context.Context) error
+	ExportForage(ctx *gin.Context, req *operationPb.SearchForageListRequest) error
 }
 
 type SystemOperation interface {
 	// Auth 系统用户相关
-	Auth(ctx context.Context, auth *operationPb.UserAuth) (*operationPb.SystemToken, error)
+	Auth(ctx context.Context, auth *operationPb.UserAuthData) (*operationPb.SystemToken, error)
 	GetUserInfo(ctx context.Context, token string) (*operationPb.UserAuth, error)
 	CreateSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error
-	SearchSystemUserList(ctx context.Context, req *operationPb.SearchUserRequest) (*model.SystemUserResponse, error)
+	SearchSystemUserList(ctx context.Context, req *operationPb.SearchUserRequest) (*operationPb.SearchUserResponse, error)
 	EditSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error
 	DeleteSystemUser(ctx context.Context, userId int64) error
 	IsShowSystemUser(ctx context.Context, req *operationPb.IsShowSystemUserRequest) error
@@ -93,7 +98,7 @@ type SystemOperation interface {
 	CreateSystemMenu(ctx context.Context, req *operationPb.AddMenuRequest) error
 	EditSystemMenu(ctx context.Context, req *operationPb.AddMenuRequest) error
 	IsShowSystemMenu(ctx context.Context, req *operationPb.IsShowSystemMenuRequest) error
-	SearchSystemMenuList(ctx context.Context, req *operationPb.SearchMenuRequest) (*model.SystemMenuResponse, error)
+	SearchSystemMenuList(ctx context.Context, req *operationPb.SearchMenuRequest) (*operationPb.SearchMenuResponse, error)
 	DeleteSystemMenu(ctx context.Context, menuId int64) error
 
 	// SearchMobileList 移动端

+ 57 - 16
module/backend/pasture_service.go

@@ -7,6 +7,9 @@ import (
 	"kpt-tmr-group/model"
 	"kpt-tmr-group/pkg/xerr"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
 
 	"gorm.io/gorm"
 )
@@ -92,7 +95,7 @@ func (s *StoreEntry) EditGroupPasture(ctx context.Context, req *operationPb.AddP
 }
 
 // SearchGroupPastureList 查询牧场列表
-func (s *StoreEntry) SearchGroupPastureList(ctx context.Context, req *operationPb.SearchPastureRequest) (*model.GroupPastureResponse, error) {
+func (s *StoreEntry) SearchGroupPastureList(ctx context.Context, req *operationPb.SearchPastureRequest) (*operationPb.SearchPastureResponse, error) {
 	groupPasture := make([]*model.GroupPasture, 0)
 	var count int64 = 0
 
@@ -117,10 +120,14 @@ func (s *StoreEntry) SearchGroupPastureList(ctx context.Context, req *operationP
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.GroupPastureResponse{
-		Page:  req.Pagination.Page,
-		Total: int32(count),
-		List:  model.GroupPastureSlice(groupPasture).ToPB(),
+	return &operationPb.SearchPastureResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchPastureData{
+			Page:  req.Pagination.Page,
+			Total: int32(count),
+			List:  model.GroupPastureSlice(groupPasture).ToPB(),
+		},
 	}, nil
 }
 
@@ -246,7 +253,7 @@ func (s *StoreEntry) DeleteCattleCategory(ctx context.Context, cattleCategoryId
 }
 
 // SearchCattleCategoryList 牧畜分类类别列表
-func (s *StoreEntry) SearchCattleCategoryList(ctx context.Context, req *operationPb.SearchCattleCategoryRequest) (*model.CattleCategoryResponse, error) {
+func (s *StoreEntry) SearchCattleCategoryList(ctx context.Context, req *operationPb.SearchCattleCategoryRequest) (*operationPb.SearchCattleCategoryResponse, error) {
 	cattleCategory := make([]*model.CattleCategory, 0)
 	var count int64 = 0
 
@@ -268,10 +275,14 @@ func (s *StoreEntry) SearchCattleCategoryList(ctx context.Context, req *operatio
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.CattleCategoryResponse{
-		Page:  req.Pagination.Page,
-		Total: int32(count),
-		List:  model.CattleCategorySlice(cattleCategory).ToPB(),
+	return &operationPb.SearchCattleCategoryResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchCattleCategoryData{
+			Page:  req.Pagination.Page,
+			Total: int32(count),
+			List:  model.CattleCategorySlice(cattleCategory).ToPB(),
+		},
 	}, nil
 }
 
@@ -346,7 +357,7 @@ func (s *StoreEntry) DeleteForageCategory(ctx context.Context, forageCategoryId
 }
 
 // SearchForageCategoryList 饲料分类类别列表
-func (s *StoreEntry) SearchForageCategoryList(ctx context.Context, req *operationPb.SearchForageCategoryRequest) (*model.ForageCategoryResponse, error) {
+func (s *StoreEntry) SearchForageCategoryList(ctx context.Context, req *operationPb.SearchForageCategoryRequest) (*operationPb.SearchForageCategoryResponse, error) {
 	forageCategory := make([]*model.ForageCategory, 0)
 	var count int64 = 0
 
@@ -368,10 +379,14 @@ func (s *StoreEntry) SearchForageCategoryList(ctx context.Context, req *operatio
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.ForageCategoryResponse{
-		Page:  req.Pagination.Page,
-		Total: int32(count),
-		List:  model.ForageCategorySlice(forageCategory).ToPB(),
+	return &operationPb.SearchForageCategoryResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchForageCategoryData{
+			Page:  req.Pagination.Page,
+			Total: int32(count),
+			List:  model.ForageCategorySlice(forageCategory).ToPB(),
+		},
 	}, nil
 }
 
@@ -460,7 +475,7 @@ func (s *StoreEntry) SearchForageList(ctx context.Context, req *operationPb.Sear
 	}
 
 	if err := pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)).
-		Find(&forage).Debug().Error; err != nil {
+		Find(&forage).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
@@ -506,3 +521,29 @@ func (s *StoreEntry) IsShowForage(ctx context.Context, req *operationPb.IsShowFo
 	}
 	return nil
 }
+
+func (s *StoreEntry) ImportForage(ctx context.Context) error {
+
+	return nil
+}
+
+func (s *StoreEntry) ExportForage(ctx *gin.Context, req *operationPb.SearchForageListRequest) error {
+	res, err := s.SearchForageList(context.Background(), req)
+	if err != nil {
+		return xerr.WithStack(err)
+	}
+	if len(res.List) <= 0 {
+		return nil
+	}
+	titleList := []string{
+		"a",
+		"b",
+		"c",
+	}
+
+	data := make([]interface{}, 0)
+	for _, v := range res.List {
+		data = append(data, v)
+	}
+	return s.ExcelClient.ExportExcelByStruct(titleList, data, "demo", "sheet1", ctx)
+}

+ 11 - 6
module/backend/system_permissions.go

@@ -6,6 +6,7 @@ import (
 	"kpt-tmr-group/pkg/logger/zaplog"
 	"kpt-tmr-group/pkg/xerr"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"net/http"
 	"sync"
 	"time"
 
@@ -65,9 +66,13 @@ func (s *SystemAllPermissionsList) SystemUserMenuPermissionsUnDuplicate() {
 
 func (s *StoreEntry) SystemPermissionsFormatPb(pastureList []*model.GroupPasture, mobileList []*model.SystemMobile, menuList []*model.SystemMenu) *operationPb.SystemUserMenuPermissions {
 	systemUserMenuPermissions := &operationPb.SystemUserMenuPermissions{
-		PastureList: make([]*operationPb.AddPastureRequest, 0),
-		MenuList:    make([]*operationPb.AddMenuRequest, 0),
-		MobileList:  make([]*operationPb.AddMobileRequest, 0),
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SystemUserMenuData{
+			PastureList: make([]*operationPb.AddPastureRequest, 0),
+			MenuList:    make([]*operationPb.AddMenuRequest, 0),
+			MobileList:  make([]*operationPb.AddMobileRequest, 0),
+		},
 	}
 
 	wg := sync.WaitGroup{}
@@ -75,7 +80,7 @@ func (s *StoreEntry) SystemPermissionsFormatPb(pastureList []*model.GroupPasture
 
 	go func() {
 		for _, v := range pastureList {
-			systemUserMenuPermissions.PastureList = append(systemUserMenuPermissions.PastureList,
+			systemUserMenuPermissions.Data.PastureList = append(systemUserMenuPermissions.Data.PastureList,
 				&operationPb.AddPastureRequest{
 					Id:   v.Id,
 					Name: v.Name,
@@ -135,13 +140,13 @@ func (s *StoreEntry) SystemPermissionsFormatPb(pastureList []*model.GroupPasture
 			}
 		}
 
-		systemUserMenuPermissions.MenuList = level[model.Level1]
+		systemUserMenuPermissions.Data.MenuList = level[model.Level1]
 		wg.Done()
 	}()
 
 	go func() {
 		for _, v := range mobileList {
-			systemUserMenuPermissions.MobileList = append(systemUserMenuPermissions.MobileList,
+			systemUserMenuPermissions.Data.MobileList = append(systemUserMenuPermissions.Data.MobileList,
 				&operationPb.AddMobileRequest{
 					Id:   v.Id,
 					Name: v.Name,

+ 49 - 18
module/backend/system_service.go

@@ -9,6 +9,7 @@ import (
 	"kpt-tmr-group/pkg/tool"
 	"kpt-tmr-group/pkg/xerr"
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"net/http"
 	"strconv"
 	"strings"
 
@@ -16,7 +17,7 @@ import (
 )
 
 // Auth 用户登录
-func (s *StoreEntry) Auth(ctx context.Context, auth *operationPb.UserAuth) (*operationPb.SystemToken, error) {
+func (s *StoreEntry) Auth(ctx context.Context, auth *operationPb.UserAuthData) (*operationPb.SystemToken, error) {
 	systemUser := &model.SystemUser{}
 
 	if err := s.DB.Where("name = ?", auth.UserName).Find(systemUser).Error; err != nil {
@@ -35,7 +36,9 @@ func (s *StoreEntry) Auth(ctx context.Context, auth *operationPb.UserAuth) (*ope
 	}
 
 	return &operationPb.SystemToken{
-		Token: token,
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.TokenData{Token: token},
 	}, nil
 }
 
@@ -92,8 +95,8 @@ func (s *StoreEntry) CreateSystemUser(ctx context.Context, req *operationPb.AddS
 }
 
 // SearchSystemUserList 查询系统用户
-func (s *StoreEntry) SearchSystemUserList(ctx context.Context, req *operationPb.SearchUserRequest) (*model.SystemUserResponse, error) {
-	systemUser := make([]*model.SystemUser, 0)
+func (s *StoreEntry) SearchSystemUserList(ctx context.Context, req *operationPb.SearchUserRequest) (*operationPb.SearchUserResponse, error) {
+	systemUserList := make([]*model.SystemUser, 0)
 	var count int64 = 0
 
 	pref := s.DB.Model(new(model.SystemUser)).Where("is_delete = ?", operationPb.IsShow_OK)
@@ -109,14 +112,24 @@ func (s *StoreEntry) SearchSystemUserList(ctx context.Context, req *operationPb.
 	}
 
 	if err := pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)).
-		Find(&systemUser).Debug().Error; err != nil {
+		Find(&systemUserList).Debug().Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.SystemUserResponse{
-		Page:  req.Pagination.Page,
-		Total: int32(count),
-		List:  model.SystemUserSlice(systemUser).ToPB(),
+	roleList, err := s.SearchSystemRoleListByIds(ctx, []int64{})
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	return &operationPb.SearchUserResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchUserData{
+			Page:     req.Pagination.Page,
+			Total:    int32(count),
+			PageSize: req.Pagination.PageSize,
+			List:     model.SystemUserSlice(systemUserList).ToPB(roleList),
+		},
 	}, nil
 }
 
@@ -342,6 +355,16 @@ func (s *StoreEntry) SearchSystemRoleList(ctx context.Context, req *operationPb.
 	}, nil
 }
 
+// SearchSystemRoleListByIds 根据id查询角色列表
+func (s *StoreEntry) SearchSystemRoleListByIds(ctx context.Context, ids []int64) ([]*model.SystemRole, error) {
+	systemRoleList := make([]*model.SystemRole, 0)
+	if err := s.DB.Model(new(model.SystemRole)).Where("is_show = ?", operationPb.IsShow_OK).Find(&systemRoleList, ids).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	return systemRoleList, nil
+}
+
 // GetRolePermissions 查询系统角色权限
 func (s *StoreEntry) GetRolePermissions(ctx context.Context, roleId int64) (*operationPb.RolePermissionsList, error) {
 	systemRole := &model.SystemRole{
@@ -425,7 +448,7 @@ func (s *StoreEntry) IsShowSystemMenu(ctx context.Context, req *operationPb.IsSh
 }
 
 // SearchSystemMenuList 菜单列表查询
-func (s *StoreEntry) SearchSystemMenuList(ctx context.Context, req *operationPb.SearchMenuRequest) (*model.SystemMenuResponse, error) {
+func (s *StoreEntry) SearchSystemMenuList(ctx context.Context, req *operationPb.SearchMenuRequest) (*operationPb.SearchMenuResponse, error) {
 	systemMenu := make([]*model.SystemMenu, 0)
 	var count int64 = 0
 
@@ -439,10 +462,14 @@ func (s *StoreEntry) SearchSystemMenuList(ctx context.Context, req *operationPb.
 		return nil, xerr.WithStack(err)
 	}
 
-	return &model.SystemMenuResponse{
-		Page:  req.Pagination.Page,
-		Total: int32(count),
-		List:  model.SystemMenuSlice(systemMenu).ToPB(),
+	return &operationPb.SearchMenuResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchMenuData{
+			Page:  req.Pagination.Page,
+			Total: int32(count),
+			List:  model.SystemMenuSlice(systemMenu).ToPB(),
+		},
 	}, nil
 }
 
@@ -478,9 +505,13 @@ func (s *StoreEntry) SearchMobileList(ctx context.Context, req *operationPb.Sear
 	}
 
 	return &operationPb.SearchMobileResponse{
-		Page:     req.Pagination.Page,
-		Total:    int32(count),
-		PageSize: req.Pagination.PageSize,
-		List:     model.SystemMobileSlice(systemMobile).ToPB(),
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchMobileData{
+			Page:     req.Pagination.Page,
+			Total:    int32(count),
+			PageSize: req.Pagination.PageSize,
+			List:     model.SystemMobileSlice(systemMobile).ToPB(),
+		},
 	}, nil
 }

+ 2 - 2
pkg/apiok/common.go

@@ -1,6 +1,6 @@
 package apiok
 
-type OkResponse struct {
+/*type OkResponse struct {
 	Code int         `json:"code"`
 	Msg  string      `json:"msg"`
 	Data interface{} `json:"data"`
@@ -13,7 +13,7 @@ func CommonResponse(data interface{}) *OkResponse {
 		Data: data,
 	}
 }
-
+*/
 type ApiOk struct {
 	Success bool `json:"success"`
 }

+ 1 - 3
pkg/ginutil/json_proto_response.go

@@ -2,7 +2,6 @@ package ginutil
 
 import (
 	"kpt-tmr-group/pkg/apierr"
-	"kpt-tmr-group/pkg/apiok"
 	"kpt-tmr-group/pkg/jsonpb"
 	"net/http"
 
@@ -16,6 +15,5 @@ func JSONResp(c *gin.Context, pb proto.Message) {
 		apierr.AbortInternalError(c, http.StatusInternalServerError, err)
 		return
 	}
-	c.JSON(http.StatusOK, apiok.CommonResponse(bs))
-	//c.Data(http.StatusOK, "application/json", bs)
+	c.Data(http.StatusOK, "application/json", bs)
 }

+ 1 - 1
pkg/jsonpb/encode.go

@@ -8,7 +8,7 @@ import (
 	"github.com/golang/protobuf/proto"
 )
 
-var marshaller = &jsonpb.Marshaler{EmitDefaults: true}
+var marshaller = &jsonpb.Marshaler{EmitDefaults: true, OrigName: true, EnumsAsInts: true}
 
 func Marshal(pb proto.Message) (string, error) {
 	e := newEncodeState()

+ 126 - 41
proto/go/backend/operation/mobile.pb.go

@@ -80,10 +80,9 @@ type SearchMobileResponse struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Page     int32         `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
-	Total    int32         `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"`
-	PageSize int32         `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
-	List     []*MobileData `protobuf:"bytes,4,rep,name=list,proto3" json:"list,omitempty"`
+	Code int64             `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	Msg  string            `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"`
+	Data *SearchMobileData `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
 }
 
 func (x *SearchMobileResponse) Reset() {
@@ -118,28 +117,92 @@ func (*SearchMobileResponse) Descriptor() ([]byte, []int) {
 	return file_backend_operation_mobile_proto_rawDescGZIP(), []int{1}
 }
 
-func (x *SearchMobileResponse) GetPage() int32 {
+func (x *SearchMobileResponse) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *SearchMobileResponse) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *SearchMobileResponse) GetData() *SearchMobileData {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type SearchMobileData struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Page     int32         `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
+	Total    int32         `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"`
+	PageSize int32         `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
+	List     []*MobileData `protobuf:"bytes,4,rep,name=list,proto3" json:"list,omitempty"`
+}
+
+func (x *SearchMobileData) Reset() {
+	*x = SearchMobileData{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_backend_operation_mobile_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SearchMobileData) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SearchMobileData) ProtoMessage() {}
+
+func (x *SearchMobileData) ProtoReflect() protoreflect.Message {
+	mi := &file_backend_operation_mobile_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 SearchMobileData.ProtoReflect.Descriptor instead.
+func (*SearchMobileData) Descriptor() ([]byte, []int) {
+	return file_backend_operation_mobile_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SearchMobileData) GetPage() int32 {
 	if x != nil {
 		return x.Page
 	}
 	return 0
 }
 
-func (x *SearchMobileResponse) GetTotal() int32 {
+func (x *SearchMobileData) GetTotal() int32 {
 	if x != nil {
 		return x.Total
 	}
 	return 0
 }
 
-func (x *SearchMobileResponse) GetPageSize() int32 {
+func (x *SearchMobileData) GetPageSize() int32 {
 	if x != nil {
 		return x.PageSize
 	}
 	return 0
 }
 
-func (x *SearchMobileResponse) GetList() []*MobileData {
+func (x *SearchMobileData) GetList() []*MobileData {
 	if x != nil {
 		return x.List
 	}
@@ -160,7 +223,7 @@ type MobileData struct {
 func (x *MobileData) Reset() {
 	*x = MobileData{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_backend_operation_mobile_proto_msgTypes[2]
+		mi := &file_backend_operation_mobile_proto_msgTypes[3]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -173,7 +236,7 @@ func (x *MobileData) String() string {
 func (*MobileData) ProtoMessage() {}
 
 func (x *MobileData) ProtoReflect() protoreflect.Message {
-	mi := &file_backend_operation_mobile_proto_msgTypes[2]
+	mi := &file_backend_operation_mobile_proto_msgTypes[3]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -186,7 +249,7 @@ func (x *MobileData) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use MobileData.ProtoReflect.Descriptor instead.
 func (*MobileData) Descriptor() ([]byte, []int) {
-	return file_backend_operation_mobile_proto_rawDescGZIP(), []int{2}
+	return file_backend_operation_mobile_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *MobileData) GetId() int64 {
@@ -232,25 +295,33 @@ var file_backend_operation_mobile_proto_rawDesc = []byte{
 	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
 	0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x67, 0x69, 0x6e,
 	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69,
-	0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x90, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x61, 0x72, 0x63,
-	0x68, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70,
-	0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67,
-	0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61,
-	0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f,
-	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x44,
-	0x61, 0x74, 0x61, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x7b, 0x0a, 0x0a, 0x4d, 0x6f, 0x62,
-	0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
-	0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x72,
-	0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
-	0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x3b, 0x6f, 0x70, 0x65, 0x72,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x75, 0x0a, 0x14, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
+	0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12,
+	0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f,
+	0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x03, 0x6d, 0x73, 0x67, 0x12, 0x37, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65,
+	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x6f, 0x62,
+	0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8c, 0x01,
+	0x0a, 0x10, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x44, 0x61,
+	0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09,
+	0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x31, 0x0a, 0x04, 0x6c, 0x69, 0x73,
+	0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e,
+	0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x6f, 0x62, 0x69,
+	0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x7b, 0x0a, 0x0a,
+	0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x2a, 0x0a,
+	0x11, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x6d,
+	0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x64, 0x41, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x3b, 0x6f,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x33,
 }
 
 var (
@@ -265,21 +336,23 @@ func file_backend_operation_mobile_proto_rawDescGZIP() []byte {
 	return file_backend_operation_mobile_proto_rawDescData
 }
 
-var file_backend_operation_mobile_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_backend_operation_mobile_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
 var file_backend_operation_mobile_proto_goTypes = []interface{}{
 	(*SearchMobileRequest)(nil),  // 0: backend.operation.SearchMobileRequest
 	(*SearchMobileResponse)(nil), // 1: backend.operation.SearchMobileResponse
-	(*MobileData)(nil),           // 2: backend.operation.MobileData
-	(*PaginationModel)(nil),      // 3: backend.operation.PaginationModel
+	(*SearchMobileData)(nil),     // 2: backend.operation.SearchMobileData
+	(*MobileData)(nil),           // 3: backend.operation.MobileData
+	(*PaginationModel)(nil),      // 4: backend.operation.PaginationModel
 }
 var file_backend_operation_mobile_proto_depIdxs = []int32{
-	3, // 0: backend.operation.SearchMobileRequest.pagination:type_name -> backend.operation.PaginationModel
-	2, // 1: backend.operation.SearchMobileResponse.list:type_name -> backend.operation.MobileData
-	2, // [2:2] is the sub-list for method output_type
-	2, // [2:2] is the sub-list for method input_type
-	2, // [2:2] is the sub-list for extension type_name
-	2, // [2:2] is the sub-list for extension extendee
-	0, // [0:2] is the sub-list for field type_name
+	4, // 0: backend.operation.SearchMobileRequest.pagination:type_name -> backend.operation.PaginationModel
+	2, // 1: backend.operation.SearchMobileResponse.data:type_name -> backend.operation.SearchMobileData
+	3, // 2: backend.operation.SearchMobileData.list:type_name -> backend.operation.MobileData
+	3, // [3:3] is the sub-list for method output_type
+	3, // [3:3] is the sub-list for method input_type
+	3, // [3:3] is the sub-list for extension type_name
+	3, // [3:3] is the sub-list for extension extendee
+	0, // [0:3] is the sub-list for field type_name
 }
 
 func init() { file_backend_operation_mobile_proto_init() }
@@ -314,6 +387,18 @@ func file_backend_operation_mobile_proto_init() {
 			}
 		}
 		file_backend_operation_mobile_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SearchMobileData); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_backend_operation_mobile_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*MobileData); i {
 			case 0:
 				return &v.state
@@ -332,7 +417,7 @@ func file_backend_operation_mobile_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_backend_operation_mobile_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   3,
+			NumMessages:   4,
 			NumExtensions: 0,
 			NumServices:   0,
 		},

File diff suppressed because it is too large
+ 489 - 276
proto/go/backend/operation/pasture.pb.go


File diff suppressed because it is too large
+ 521 - 80
proto/go/backend/operation/system.pb.go


+ 177 - 0
service/excel/excel.go

@@ -0,0 +1,177 @@
+package excel
+
+import (
+	"fmt"
+	"net/url"
+	"reflect"
+	"strconv"
+
+	"github.com/gin-gonic/gin"
+	"github.com/xuri/excelize/v2"
+)
+
+type ExcelServer struct {
+	File      *excelize.File
+	SheetName string  // 可定义默认sheet名称
+	Height    float64 // 默认行高度
+}
+
+// ExportToPath 导出基本的表格
+func (l *ExcelServer) ExportToPath(params []map[string]string, data []map[string]interface{}, path string) (string, error) {
+	l.Export(params, data)
+	name := createFileName()
+	filePath := path + "/" + name
+	err := l.File.SaveAs(filePath)
+	return filePath, err
+}
+
+// ExportToWeb 导出到浏览器。此处使用的gin框架 其他框架可自行修改ctx
+func (l *ExcelServer) ExportToWeb(params []map[string]string, data []map[string]interface{}, c *gin.Context) {
+	l.Export(params, data)
+	buffer, _ := l.File.WriteToBuffer()
+	//设置文件类型
+	c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8")
+	//设置文件名称
+	c.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(createFileName()))
+	_, _ = c.Writer.Write(buffer.Bytes())
+}
+
+//设置首行
+func (l *ExcelServer) writeTop(params []map[string]string) {
+	topStyle, _ := l.File.NewStyle(&excelize.Style{
+		Font: &excelize.Font{Bold: true},
+		Alignment: &excelize.Alignment{
+			Horizontal: "center",
+			Vertical:   "center",
+		},
+		Protection:    nil,
+		NumFmt:        0,
+		DecimalPlaces: 0,
+		CustomNumFmt:  nil,
+		Lang:          "",
+		NegRed:        false,
+	})
+	var word = 'A'
+	//首行写入
+	for _, conf := range params {
+		title := conf["title"]
+		width, _ := strconv.ParseFloat(conf["width"], 64)
+		line := fmt.Sprintf("%c1", word)
+		//设置标题
+		_ = l.File.SetCellValue(l.SheetName, line, title)
+		//列宽
+		_ = l.File.SetColWidth(l.SheetName, fmt.Sprintf("%c", word), fmt.Sprintf("%c", word), width)
+		//设置样式
+		_ = l.File.SetCellStyle(l.SheetName, line, line, topStyle)
+		word++
+	}
+}
+
+//写入数据
+func (l *ExcelServer) writeData(params []map[string]string, data []map[string]interface{}) {
+	lineStyle, _ := l.File.NewStyle(&excelize.Style{Alignment: &excelize.Alignment{
+		Horizontal: "center",
+		Vertical:   "center",
+	}})
+	//数据写入
+	var j = 2 //数据开始行数
+	for i, val := range data {
+		//设置行高
+		_ = l.File.SetRowHeight(l.SheetName, i+1, l.Height)
+		//逐列写入
+		var word = 'A'
+		for _, conf := range params {
+			valKey := conf["key"]
+			line := fmt.Sprintf("%c%v", word, j)
+			isNum := conf["is_num"]
+
+			//设置值
+			if isNum != "0" {
+				valNum := fmt.Sprintf("'%v", val[valKey])
+				_ = l.File.SetCellValue(l.SheetName, line, valNum)
+			} else {
+				_ = l.File.SetCellValue(l.SheetName, line, val[valKey])
+			}
+
+			//设置样式
+			_ = l.File.SetCellStyle(l.SheetName, line, line, lineStyle)
+			word++
+		}
+		j++
+	}
+	//设置行高 尾行
+	_ = l.File.SetRowHeight(l.SheetName, len(data)+1, l.Height)
+}
+
+func (l *ExcelServer) Export(params []map[string]string, data []map[string]interface{}) {
+	l.writeTop(params)
+	l.writeData(params, data)
+}
+
+// ExportExcelByStruct excel导出(数据源为Struct) []interface{}
+func (l *ExcelServer) ExportExcelByStruct(titleList []string, data []interface{}, fileName string, sheetName string, c *gin.Context) error {
+	l.File.SetSheetName("Sheet1", sheetName)
+	header := make([]string, 0)
+	for _, v := range titleList {
+		header = append(header, v)
+	}
+	rowStyleID, _ := l.File.NewStyle(&excelize.Style{
+		Font: &excelize.Font{
+			Family: "arial",
+			Size:   13,
+			Color:  "#666666",
+		},
+		Alignment: &excelize.Alignment{
+			Horizontal: "center",
+			Vertical:   "center",
+		},
+	})
+	_ = l.File.SetSheetRow(sheetName, "A1", &header)
+	_ = l.File.SetRowHeight("Sheet1", 1, 30)
+	length := len(titleList)
+	headStyle := Letter(length)
+	var lastRow string
+	var widthRow string
+	for k, v := range headStyle {
+		if k == length-1 {
+			lastRow = fmt.Sprintf("%s1", v)
+			widthRow = v
+		}
+	}
+	if err := l.File.SetColWidth(sheetName, "A", widthRow, 30); err != nil {
+		fmt.Print("错误--", err.Error())
+	}
+	rowNum := 1
+	for _, v := range data {
+		t := reflect.TypeOf(v)
+		fmt.Print("--ttt--", t.NumField())
+		value := reflect.ValueOf(v)
+		row := make([]interface {
+		}, 0)
+		for l := 0; l < t.NumField(); l++ {
+			val := value.Field(l).Interface()
+			row = append(row, val)
+		}
+		rowNum++
+		err := l.File.SetSheetRow(sheetName, "A"+strconv.Itoa(rowNum), &row)
+		_ = l.File.SetCellStyle(sheetName, fmt.Sprintf("A%d", rowNum), fmt.Sprintf("%s", lastRow), rowStyleID)
+		if err != nil {
+			return err
+		}
+	}
+	disposition := fmt.Sprintf("attachment; filename=%s.xlsx", url.QueryEscape(fileName))
+	c.Writer.Header().Set("Content-Type", "application/octet-stream")
+	c.Writer.Header().Set("Content-Disposition", disposition)
+	c.Writer.Header().Set("Content-Transfer-Encoding", "binary")
+	c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
+	return l.File.Write(c.Writer)
+}
+
+// Letter 遍历a-z
+func Letter(length int) []string {
+	var str []string
+	for i := 0; i < length; i++ {
+		str = append(str, string(rune('A'+i)))
+	}
+	return str
+}

+ 120 - 0
service/excel/interface.go

@@ -0,0 +1,120 @@
+package excel
+
+import (
+	"fmt"
+	"kpt-tmr-group/config"
+	"kpt-tmr-group/model"
+	"kpt-tmr-group/pkg/di"
+	"math/rand"
+	"time"
+
+	"github.com/gin-gonic/gin"
+
+	"github.com/xuri/excelize/v2"
+)
+
+type SheetService interface {
+	ExportToPath(params []map[string]string, data []map[string]interface{}, path string) (string, error)
+	ExportToWeb(params []map[string]string, data []map[string]interface{}, c *gin.Context)
+	writeTop(params []map[string]string)
+	writeData(params []map[string]string, data []map[string]interface{})
+	Export(params []map[string]string, data []map[string]interface{})
+}
+
+var Module = di.Provide(NewMyExcel)
+
+func NewMyExcel(cfg *config.AppConfig) *ExcelServer {
+	return &ExcelServer{File: createFile(cfg), SheetName: cfg.ExcelSetting.SheetName}
+}
+
+func createFile(cfg *config.AppConfig) *excelize.File {
+	f := excelize.NewFile()
+	// 创建一个默认工作表
+	index, _ := f.NewSheet(cfg.ExcelSetting.SheetName)
+	// 设置工作簿的默认工作表
+	f.SetActiveSheet(index)
+	return f
+}
+
+func createFileName() string {
+	name := time.Now().Format(model.LayoutTime)
+	rand.Seed(time.Now().UnixNano())
+	return fmt.Sprintf("excle-%v-%v.xlsx", name, rand.Int63n(time.Now().Unix()))
+}
+
+/*import (
+"go-excel/app/excelize"
+"go-excel/app/model"
+config "go-excel/common"
+"github.com/gin-gonic/gin"
+)
+
+
+
+//获取所有用户数据-excel
+func GetAllUserExportToWeb(ctx *gin.Context) {
+	var users []model.TUser
+	db := config.GetDB()
+	db.Find(&users)
+
+	//定义首行标题
+	dataKey := make([]map[string]string, 0)
+	dataKey = append(dataKey, map[string]string{
+		"key":    "id",
+		"title":  "索引",
+		"width":  "20",
+		"is_num": "0",
+	})
+	dataKey = append(dataKey, map[string]string{
+		"key":    "username",
+		"title":  "用户名",
+		"width":  "20",
+		"is_num": "0",
+	})
+	dataKey = append(dataKey, map[string]string{
+		"key":    "remark",
+		"title":  "备注",
+		"width":  "20",
+		"is_num": "0",
+	})
+
+	//填充数据
+	data := make([]map[string]interface{}, 0)
+	if len(users) > 0 {
+		for _, v := range users {
+			data = append(data, map[string]interface{}{
+				"id":       v.ID,
+				"username": v.Username,
+				"remark":   v.Remark,
+			})
+		}
+	}
+	ex := excelize.NewMyExcel()
+
+	// ex.ExportToWeb(dataKey, data, ctx)
+
+	//保存到D盘
+	ex.ExportToPath(dataKey, data, "D:/")
+}
+
+//excel 导出
+func GetUserExcelByMap(ctx *gin.Context) {
+	var users []model.TUser
+	db := config.GetDB()
+	db.Find(&users)
+
+	titles := []string{"ID", "用户名", "备注"}
+
+	ex := excelize.NewMyExcel()
+
+	var datas []interface{}
+	for _, v := range users {
+		//这里最好新建一个struct 和titles一致,不然users里面的多余的字段也会写进去
+		datas = append(datas, model.TUser{
+			ID:       v.ID,
+			Username: v.Username,
+			Remark:   v.Remark,
+		})
+	}
+	ex.ExportExcelByStruct(titles, datas, "用户数据", "用户", ctx)
+}*/

Some files were not shown because too many files changed in this diff