Browse Source

statistic: 配方评估

Yi 1 year ago
parent
commit
921c1e172b

+ 4 - 1
README.md

@@ -32,4 +32,7 @@ lint:
 - make generate
 
 TODO 列表
-- proto3 int64 jsonpb处理后自动转成string,目前是把int64类型改成uint32或者int32类型
+- proto3 int64 jsonpb处理后自动转成string
+  * 现在处理的方式是把int64类型改成int32类型
+- 用户登出没有用redis做缓存,所以后端没有提供登出接口,有以下弊端
+  * 用户的token没有过期,如被人劫持,会被使用到直到token过期

+ 5 - 0
backend/operation/pasture.proto

@@ -40,6 +40,11 @@ message SearchPastureData {
   repeated AddPastureRequest list = 4;
 }
 
+message UserPasture {
+  int32 id = 1;
+  string name = 2;
+}
+
 message IsShowGroupPasture {
   int32 pasture_id = 1;    // 牧场id
   IsShow.Kind is_show = 2;     // 是否开启

+ 86 - 0
backend/operation/statistic.proto

@@ -0,0 +1,86 @@
+syntax = "proto3";
+package backend.operation;
+
+option go_package = ".;operationPb";
+
+
+import "backend/operation/pagination.proto";
+
+// 添加配方评估 具体字段含义参照formula_estimate表对应的字段
+message AddFormulaEstimateRequest {
+  int32 id = 1;
+  int32 pasture_id = 2;
+  string pasture_name = 3;
+  int32 barn_id = 4;
+  int32 feed_formula_id = 5;
+  string feed_formula_name = 6;
+  int32 cow_number = 7;
+  int32 dry_formula_number = 8;
+  int32 dry_tmr_feed = 9;
+  int32 dry_food_intake = 10;
+  int32 mj_formula_number = 11;
+  int32 mj_tmr_feed = 12;
+  int32 mj_food_intake = 13;
+  int32 nnd_formula_number = 14;
+  int32 nnd_tmr_feed = 15;
+  int32 nnd_food_intake = 16;
+  int32 cpg_formula_number = 17;
+  int32 cpg_tmr_feed = 18;
+  int32 cpg_food_intake = 19;
+  int32 pg_formula_number = 20;
+  int32 pg_tmr_feed = 21;
+  int32 pg_food_intake = 22;
+  int32 dm_formula_number = 23;
+  int32 dm_tmr_feed = 24;
+  int32 dm_food_intake = 25;
+  int32 cpdm_formula_number = 26;
+  int32 cpdm_tmr_feed = 27;
+  int32 cpdm_food_intake = 28;
+  int32 fat_formula_number = 29;
+  int32 fat_tmr_feed = 30;
+  int32 fat_food_intake = 31;
+  int32 starch_formula_number = 32;
+  int32 starch_tmr_feed = 33;
+  int32 starch_food_intake = 34;
+  int32 ndf_formula_number = 35;
+  int32 ndf_tmr_feed = 36;
+  int32 ndf_food_intake = 37;
+  int32 cp_ndf_formula_number = 38;
+  int32 cp_ndf_tmr_feed = 39;
+  int32 cp_ndf_food_intake = 40;
+  int32 adf_formula_number = 41;
+  int32 adf_tmr_feed = 42;
+  int32 adf_food_intake = 43;
+  int32 calcium_formula_number = 44;
+  int32 calcium_tmr_feed = 45;
+  int32 calcium_food_intake = 46;
+  int32 pdm_formula_number = 47;
+  int32 pdm_tmr_feed = 48;
+  int32 pdm_food_intake = 49;
+  int32 cf_ratio_formula_number = 50;
+  int32 cf_ratio_tmr_feed = 51;
+  int32 cf_ratio_food_intake = 52;
+  int32 created_at = 53;
+  string created_at_format = 54;
+}
+
+message SearchFormulaEstimateRequest {
+  string start_time  = 1;     // 开始时间
+  string end_time    = 2;     // 结束时间
+  int32 search_type = 3;      // 查询方式  1 安照配方 2 按照栏舍
+  string name = 4;            // 名称
+  PaginationModel pagination = 5; // 分页
+}
+
+message SearchFormulaEstimateResponse {
+  int32 code = 1;
+  string msg = 2;
+  SearchFormulaEstimate data = 3;
+}
+
+message SearchFormulaEstimate {
+  int32 page = 1;
+  int32 total = 2;
+  int32 page_size = 3;
+  repeated AddFormulaEstimateRequest list = 4;
+}

+ 1 - 0
backend/operation/system.proto

@@ -90,6 +90,7 @@ message UserAuthData {
   string phone = 3;       // 用户手机号
   repeated UserRole roles  = 4;    // 用户角色
   string employee_name = 5;    // 员工名称
+  repeated UserPasture pastures = 6; // 用户角色牧场牧场
 }
 
 message UserRole {

+ 33 - 0
http/handler/statistic/analysis.go

@@ -0,0 +1,33 @@
+package statistic
+
+import (
+	"kpt-tmr-group/http/middleware"
+	"kpt-tmr-group/pkg/apierr"
+	"kpt-tmr-group/pkg/ginutil"
+	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+)
+
+// SearchFormulaEstimateList 配方评估
+func SearchFormulaEstimateList(c *gin.Context) {
+	req := &operationPb.SearchFormulaEstimateRequest{}
+	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)),
+	}
+
+	res, err := middleware.BackendOperation(c).OpsService.SearchFormulaEstimateList(c, req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}

+ 4 - 0
http/route/app_api.go

@@ -5,6 +5,7 @@ import (
 	"kpt-tmr-group/http/handler/feed"
 	"kpt-tmr-group/http/handler/mobile"
 	"kpt-tmr-group/http/handler/pasture"
+	"kpt-tmr-group/http/handler/statistic"
 	"kpt-tmr-group/http/handler/system"
 	"kpt-tmr-group/http/middleware"
 
@@ -99,6 +100,9 @@ func AppAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		opsRoute.POST("/feed_formula/excel_export", feed.ExcelExportFeedFormula)
 		opsRoute.POST("/feed_formula/excel_import", feed.ExcelImportFeedFormula)
 		opsRoute.POST("/feed_formula/excel_template", feed.ExcelTemplateFeedFormula)
+
+		//统计分析 statistic analysis
+		opsRoute.POST("/feed_estimate/list", statistic.SearchFormulaEstimateList)
 	}
 }
 

+ 3 - 0
model/cattle_category.go

@@ -16,6 +16,7 @@ type CattleCategory struct {
 	IsShow      operationPb.IsShow_Kind               `json:"is_show"`
 	IsDelete    operationPb.IsShow_Kind               `json:"is_delete"`
 	DataSource  operationPb.DataSource_Kind           `json:"data_source"`
+	Remarks     string                                `json:"remarks"`
 	CreatedAt   int64                                 `json:"created_at"`
 	UpdatedAt   int64                                 `json:"updated_at"`
 }
@@ -32,6 +33,8 @@ func NewCattleCategory(req *operationPb.AddCattleCategoryRequest) *CattleCategor
 		Number:     req.Number,
 		IsShow:     operationPb.IsShow_OK,
 		IsDelete:   operationPb.IsShow_OK,
+		DataSource: operationPb.DataSource_BACKGROUND_ADD,
+		Remarks:    "集团新增数据",
 	}
 }
 

+ 3 - 0
model/forage_category.go

@@ -16,6 +16,7 @@ type ForageCategory struct {
 	IsShow      operationPb.IsShow_Kind               `json:"is_show"`
 	IsDelete    operationPb.IsShow_Kind               `json:"is_delete"`
 	DataSource  operationPb.DataSource_Kind           `json:"data_source"`
+	Remarks     string                                `json:"remarks"`
 	CreatedAt   int64                                 `json:"created_at"`
 	UpdatedAt   int64                                 `json:"updated_at"`
 }
@@ -32,6 +33,8 @@ func NewForageCategory(req *operationPb.AddForageCategoryRequest) *ForageCategor
 		Number:     req.Number,
 		IsShow:     operationPb.IsShow_OK,
 		IsDelete:   operationPb.IsShow_OK,
+		DataSource: operationPb.DataSource_BACKGROUND_ADD,
+		Remarks:    "集团新增数据",
 	}
 }
 

+ 132 - 0
model/formula_estimate.go

@@ -0,0 +1,132 @@
+package model
+
+import (
+	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"time"
+)
+
+type FormulaEstimate struct {
+	Id                   int32  `json:"id"`
+	PastureId            int32  `json:"pasture_id"`
+	PastureName          string `json:"pasture_name"`
+	BarnId               int32  `json:"barn_id"`
+	FeedFormulaId        int32  `json:"feed_formula_id"`
+	FeedFormulaName      string `json:"feed_formula_name"`
+	CowNumber            int32  `json:"cow_number"`
+	DryFormulaNumber     int32  `json:"dry_formula_number"`
+	DryTmrFeed           int32  `json:"dry_tmr_feed"`
+	DryFoodIntake        int32  `json:"dry_food_intake"`
+	MjFormulaNumber      int32  `json:"mj_formula_number"`
+	MjTmrFeed            int32  `json:"mj_tmr_feed"`
+	MjFoodIntake         int32  `json:"mj_food_intake"`
+	NndFormulaNumber     int32  `json:"nnd_formula_number"`
+	NndTmrFeed           int32  `json:"nnd_tmr_feed"`
+	NndFoodIntake        int32  `json:"nnd_food_intake"`
+	CpgFormulaNumber     int32  `json:"cpg_formula_number"`
+	CpgTmrFeed           int32  `json:"cpg_tmr_feed"`
+	CpgFoodIntake        int32  `json:"cpg_food_intake"`
+	PgFormulaNumber      int32  `json:"pg_formula_number"`
+	PgTmrFeed            int32  `json:"pg_tmr_feed"`
+	PgFoodIntake         int32  `json:"pg_food_intake"`
+	DmFormulaNumber      int32  `json:"dm_formula_number"`
+	DmTmrFeed            int32  `json:"dm_tmr_feed"`
+	DmFoodIntake         int32  `json:"dm_food_intake"`
+	CpdmFormulaNumber    int32  `json:"cpdm_formula_number"`
+	CpdmTmrFeed          int32  `json:"cpdm_tmr_feed"`
+	CpdmFoodIntake       int32  `json:"cpdm_food_intake"`
+	FatFormulaNumber     int32  `json:"fat_formula_number"`
+	FatTmrFeed           int32  `json:"fat_tmr_feed"`
+	FatFoodIntake        int32  `json:"fat_food_intake"`
+	StarchFormulaNumber  int32  `json:"starch_formula_number"`
+	StarchTmrFeed        int32  `json:"starch_tmr_feed"`
+	StarchFoodIntake     int32  `json:"starch_food_intake"`
+	NdfFormulaNumber     int32  `json:"ndf_formula_number"`
+	NdfTmrFeed           int32  `json:"ndf_tmr_feed"`
+	NdfFoodIntake        int32  `json:"ndf_food_intake"`
+	CpNdfFormulaNumber   int32  `json:"cp_ndf_formula_number"`
+	CpNdfTmrFeed         int32  `json:"cp_ndf_tmr_feed"`
+	CpNdfFoodIntake      int32  `json:"cp_ndf_food_intake"`
+	AdfFormulaNumber     int32  `json:"adf_formula_number"`
+	AdfTmrFeed           int32  `json:"adf_tmr_feed"`
+	AdfFoodIntake        int32  `json:"adf_food_intake"`
+	CalciumFormulaNumber int32  `json:"calcium_formula_number"`
+	CalciumTmrFeed       int32  `json:"calcium_tmr_feed"`
+	CalciumFoodIntake    int32  `json:"calcium_food_intake"`
+	PdmFormulaNumber     int32  `json:"pdm_formula_number"`
+	PdmTmrFeed           int32  `json:"pdm_tmr_feed"`
+	PdmFoodIntake        int32  `json:"pdm_food_intake"`
+	CfRatioFormulaNumber int32  `json:"cf_ratio_formula_number"`
+	CfRatioTmrFeed       int32  `json:"cf_ratio_tmr_feed"`
+	CfRatioFoodIntake    int32  `json:"cf_ratio_food_intake"`
+	CreatedAt            int32  `json:"created_at"`
+	UpdatedAt            int32  `json:"updated_at"`
+}
+
+func (f *FormulaEstimate) TableName() string {
+	return "formula_estimate"
+}
+
+type FormulaEstimateSlice []*FormulaEstimate
+
+func (f FormulaEstimateSlice) ToPB() []*operationPb.AddFormulaEstimateRequest {
+	res := make([]*operationPb.AddFormulaEstimateRequest, len(f))
+	for i, v := range f {
+		res[i] = &operationPb.AddFormulaEstimateRequest{
+			Id:                   v.Id,
+			PastureId:            v.PastureId,
+			PastureName:          v.PastureName,
+			BarnId:               v.BarnId,
+			FeedFormulaId:        v.FeedFormulaId,
+			FeedFormulaName:      v.FeedFormulaName,
+			CowNumber:            v.CowNumber,
+			DryFoodIntake:        v.DryFoodIntake,
+			DryFormulaNumber:     v.DryFormulaNumber,
+			DryTmrFeed:           v.DryTmrFeed,
+			MjFoodIntake:         v.MjFoodIntake,
+			MjFormulaNumber:      v.MjFormulaNumber,
+			MjTmrFeed:            v.MjTmrFeed,
+			NndFoodIntake:        v.NndFoodIntake,
+			NndFormulaNumber:     v.NndFormulaNumber,
+			NndTmrFeed:           v.NndTmrFeed,
+			CpgFoodIntake:        v.CpgFoodIntake,
+			CpgFormulaNumber:     v.CpgFormulaNumber,
+			CpgTmrFeed:           v.CpgTmrFeed,
+			PgFoodIntake:         v.PgFoodIntake,
+			PgFormulaNumber:      v.PgFormulaNumber,
+			PgTmrFeed:            v.PgTmrFeed,
+			DmFoodIntake:         v.DmFoodIntake,
+			DmFormulaNumber:      v.DmFormulaNumber,
+			DmTmrFeed:            v.DmTmrFeed,
+			CpdmFoodIntake:       v.CpdmFoodIntake,
+			CpdmFormulaNumber:    v.CpdmFormulaNumber,
+			CpdmTmrFeed:          v.CpdmTmrFeed,
+			FatFoodIntake:        v.FatFoodIntake,
+			FatFormulaNumber:     v.FatFormulaNumber,
+			FatTmrFeed:           v.FatTmrFeed,
+			StarchFoodIntake:     v.StarchFoodIntake,
+			StarchFormulaNumber:  v.StarchFormulaNumber,
+			StarchTmrFeed:        v.StarchTmrFeed,
+			NdfFoodIntake:        v.NdfFoodIntake,
+			NdfFormulaNumber:     v.NdfFormulaNumber,
+			NdfTmrFeed:           v.NdfTmrFeed,
+			CpNdfFoodIntake:      v.CpNdfFoodIntake,
+			CpNdfFormulaNumber:   v.CpNdfFormulaNumber,
+			CpNdfTmrFeed:         v.CpNdfTmrFeed,
+			AdfFoodIntake:        v.AdfFoodIntake,
+			AdfFormulaNumber:     v.AdfFormulaNumber,
+			AdfTmrFeed:           v.AdfTmrFeed,
+			CalciumFoodIntake:    v.CalciumFoodIntake,
+			CalciumFormulaNumber: v.CalciumFormulaNumber,
+			CalciumTmrFeed:       v.CalciumTmrFeed,
+			PdmFoodIntake:        v.PdmFoodIntake,
+			PdmFormulaNumber:     v.PdmFormulaNumber,
+			PdmTmrFeed:           v.PdmTmrFeed,
+			CfRatioFoodIntake:    v.CfRatioFoodIntake,
+			CfRatioFormulaNumber: v.CfRatioFormulaNumber,
+			CfRatioTmrFeed:       v.CfRatioTmrFeed,
+			CreatedAt:            v.CreatedAt,
+			CreatedAtFormat:      time.Unix(int64(v.CreatedAt), 0).Format(LayoutTime),
+		}
+	}
+	return res
+}

+ 2 - 1
model/system_user.go

@@ -27,7 +27,7 @@ func (s *SystemUser) TableName() string {
 	return "system_user"
 }
 
-func (s *SystemUser) SystemUserFormat(userRoles []*SystemRole) *operationPb.UserAuth {
+func (s *SystemUser) SystemUserFormat(userRoles []*SystemRole, pastures []*operationPb.UserPasture) *operationPb.UserAuth {
 	roles := make([]*operationPb.UserRole, len(userRoles))
 	for k, v := range userRoles {
 		roles[k] = &operationPb.UserRole{
@@ -44,6 +44,7 @@ func (s *SystemUser) SystemUserFormat(userRoles []*SystemRole) *operationPb.User
 			Phone:        s.Phone,
 			EmployeeName: s.EmployeeName,
 			Roles:        roles,
+			Pastures:     pastures,
 		},
 	}
 }

+ 9 - 4
module/backend/interface.go

@@ -36,12 +36,13 @@ func NewStore(store StoreEntry) KptService {
 }
 
 type KptService interface {
-	Operation
-	SystemOperation
-	WxAppletService
+	PastureService   // 牧场相关操作
+	SystemOperation  // 系统相关操作
+	WxAppletService  // 小程序相关
+	StatisticService // 统计分析
 }
 
-type Operation interface {
+type PastureService interface {
 	// CreateGroupPasture 牧场管理相关
 	CreateGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error
 	EditGroupPasture(ctx context.Context, req *operationPb.AddPastureRequest) error
@@ -119,6 +120,10 @@ type SystemOperation interface {
 	SearchMobileList(ctx context.Context, req *operationPb.SearchMobileRequest) (*operationPb.SearchMobileResponse, error)
 }
 
+type StatisticService interface {
+	SearchFormulaEstimateList(ctx context.Context, req *operationPb.SearchFormulaEstimateRequest) (*operationPb.SearchFormulaEstimateResponse, error)
+}
+
 type WxAppletService interface {
 	GetOpenId(ctx context.Context, jsCode string) (*operationPb.WxOpenId, error)
 }

+ 59 - 0
module/backend/statistic_service.go

@@ -0,0 +1,59 @@
+package backend
+
+import (
+	"context"
+	"fmt"
+	"kpt-tmr-group/model"
+	"kpt-tmr-group/pkg/xerr"
+	operationPb "kpt-tmr-group/proto/go/backend/operation"
+	"net/http"
+	"time"
+)
+
+func (s *StoreEntry) SearchFormulaEstimateList(ctx context.Context, req *operationPb.SearchFormulaEstimateRequest) (*operationPb.SearchFormulaEstimateResponse, error) {
+	startTime, err := time.Parse(model.LayoutTime, req.StartTime)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	endTime, err := time.Parse(model.LayoutTime, req.EndTime)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	startTimeUnix := startTime.Unix()
+	endTimeUnix := endTime.Unix()
+
+	formulaEstimate := make([]*model.FormulaEstimate, 0)
+	var count int64 = 0
+
+	pref := s.DB.Model(new(model.FormulaEstimate))
+	if req.Name != "" {
+		pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%"))
+	}
+	if startTimeUnix > 0 && endTimeUnix > 0 && endTimeUnix >= startTimeUnix {
+		pref.Where("created_at BETWEEN ? AND ?", startTimeUnix, endTimeUnix)
+	}
+
+	if req.SearchType == 1 {
+		pref.Where("feed_formula_name = ?", req.Name)
+	} else {
+		pref.Where("barn_id = ?", req.Name)
+	}
+
+	if err = pref.Order("id desc").Count(&count).Limit(int(req.Pagination.PageSize)).Offset(int(req.Pagination.PageOffset)).
+		Find(&formulaEstimate).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	return &operationPb.SearchFormulaEstimateResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.SearchFormulaEstimate{
+			Page:     req.Pagination.Page,
+			Total:    int32(count),
+			PageSize: req.Pagination.PageSize,
+			List:     model.FormulaEstimateSlice(formulaEstimate).ToPB(),
+		},
+	}, nil
+}

+ 7 - 2
module/backend/system_service.go

@@ -58,7 +58,7 @@ func (s *StoreEntry) GetUserInfo(ctx context.Context, token string) (*operationP
 	}
 
 	systemRole := make([]*model.SystemRole, 0)
-
+	pastureList := make([]*operationPb.UserPasture, 0)
 	roleIdStr := strings.Split(systemUser.RoleIds, ",")
 	if len(roleIdStr) > 0 {
 		roleIds := make([]int, 0)
@@ -67,12 +67,17 @@ func (s *StoreEntry) GetUserInfo(ctx context.Context, token string) (*operationP
 			roleIds = append(roleIds, roleId)
 		}
 
+		if err = s.DB.Model(new(model.SystemGroupPasturePermissions)).Select("DISTINCT(group_pasture.id) AS did, group_pasture.id as id,group_pasture.name as name").
+			Where("system_group_pasture_permissions.role_id IN ?", roleIds).Where("system_group_pasture_permissions.is_show = ?", operationPb.IsShow_OK).
+			Joins("right join group_pasture  on system_group_pasture_permissions.pasture_id = group_pasture.id").Find(&pastureList).Debug().Error; err != nil {
+		}
+
 		if err = s.DB.Find(&systemRole, roleIds).Error; err != nil {
 			return nil, xerr.WithStack(err)
 		}
 	}
 
-	return systemUser.SystemUserFormat(systemRole), nil
+	return systemUser.SystemUserFormat(systemRole, pastureList), nil
 }
 
 // CreateSystemUser 创建系统用户

+ 2 - 3
pkg/jwt/jwt.go

@@ -3,7 +3,6 @@ package jwt
 import (
 	"fmt"
 	"kpt-tmr-group/config"
-	"kpt-tmr-group/pkg/tool"
 	"reflect"
 	"time"
 
@@ -20,11 +19,11 @@ type Claims struct {
 
 func GenerateToken(username, password string) (string, error) {
 	nowTime := time.Now()
-	expireTime := nowTime.Add(2 * time.Hour)
+	expireTime := nowTime.Add(4 * time.Hour)
 
 	claims := Claims{
 		username,
-		tool.Md5String(password),
+		password,
 		jwt.StandardClaims{
 			ExpiresAt: expireTime.Unix(),
 			Issuer:    "https://github.com/kptyun/go-admin/",

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


+ 995 - 0
proto/go/backend/operation/statistic.pb.go

@@ -0,0 +1,995 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.21.9
+// source: backend/operation/statistic.proto
+
+package operationPb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// 添加配方评估 具体字段含义参照formula_estimate表对应的字段
+type AddFormulaEstimateRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id                   int32  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+	PastureId            int32  `protobuf:"varint,2,opt,name=pasture_id,json=pastureId,proto3" json:"pasture_id,omitempty"`
+	PastureName          string `protobuf:"bytes,3,opt,name=pasture_name,json=pastureName,proto3" json:"pasture_name,omitempty"`
+	BarnId               int32  `protobuf:"varint,4,opt,name=barn_id,json=barnId,proto3" json:"barn_id,omitempty"`
+	FeedFormulaId        int32  `protobuf:"varint,5,opt,name=feed_formula_id,json=feedFormulaId,proto3" json:"feed_formula_id,omitempty"`
+	FeedFormulaName      string `protobuf:"bytes,6,opt,name=feed_formula_name,json=feedFormulaName,proto3" json:"feed_formula_name,omitempty"`
+	CowNumber            int32  `protobuf:"varint,7,opt,name=cow_number,json=cowNumber,proto3" json:"cow_number,omitempty"`
+	DryFormulaNumber     int32  `protobuf:"varint,8,opt,name=dry_formula_number,json=dryFormulaNumber,proto3" json:"dry_formula_number,omitempty"`
+	DryTmrFeed           int32  `protobuf:"varint,9,opt,name=dry_tmr_feed,json=dryTmrFeed,proto3" json:"dry_tmr_feed,omitempty"`
+	DryFoodIntake        int32  `protobuf:"varint,10,opt,name=dry_food_intake,json=dryFoodIntake,proto3" json:"dry_food_intake,omitempty"`
+	MjFormulaNumber      int32  `protobuf:"varint,11,opt,name=mj_formula_number,json=mjFormulaNumber,proto3" json:"mj_formula_number,omitempty"`
+	MjTmrFeed            int32  `protobuf:"varint,12,opt,name=mj_tmr_feed,json=mjTmrFeed,proto3" json:"mj_tmr_feed,omitempty"`
+	MjFoodIntake         int32  `protobuf:"varint,13,opt,name=mj_food_intake,json=mjFoodIntake,proto3" json:"mj_food_intake,omitempty"`
+	NndFormulaNumber     int32  `protobuf:"varint,14,opt,name=nnd_formula_number,json=nndFormulaNumber,proto3" json:"nnd_formula_number,omitempty"`
+	NndTmrFeed           int32  `protobuf:"varint,15,opt,name=nnd_tmr_feed,json=nndTmrFeed,proto3" json:"nnd_tmr_feed,omitempty"`
+	NndFoodIntake        int32  `protobuf:"varint,16,opt,name=nnd_food_intake,json=nndFoodIntake,proto3" json:"nnd_food_intake,omitempty"`
+	CpgFormulaNumber     int32  `protobuf:"varint,17,opt,name=cpg_formula_number,json=cpgFormulaNumber,proto3" json:"cpg_formula_number,omitempty"`
+	CpgTmrFeed           int32  `protobuf:"varint,18,opt,name=cpg_tmr_feed,json=cpgTmrFeed,proto3" json:"cpg_tmr_feed,omitempty"`
+	CpgFoodIntake        int32  `protobuf:"varint,19,opt,name=cpg_food_intake,json=cpgFoodIntake,proto3" json:"cpg_food_intake,omitempty"`
+	PgFormulaNumber      int32  `protobuf:"varint,20,opt,name=pg_formula_number,json=pgFormulaNumber,proto3" json:"pg_formula_number,omitempty"`
+	PgTmrFeed            int32  `protobuf:"varint,21,opt,name=pg_tmr_feed,json=pgTmrFeed,proto3" json:"pg_tmr_feed,omitempty"`
+	PgFoodIntake         int32  `protobuf:"varint,22,opt,name=pg_food_intake,json=pgFoodIntake,proto3" json:"pg_food_intake,omitempty"`
+	DmFormulaNumber      int32  `protobuf:"varint,23,opt,name=dm_formula_number,json=dmFormulaNumber,proto3" json:"dm_formula_number,omitempty"`
+	DmTmrFeed            int32  `protobuf:"varint,24,opt,name=dm_tmr_feed,json=dmTmrFeed,proto3" json:"dm_tmr_feed,omitempty"`
+	DmFoodIntake         int32  `protobuf:"varint,25,opt,name=dm_food_intake,json=dmFoodIntake,proto3" json:"dm_food_intake,omitempty"`
+	CpdmFormulaNumber    int32  `protobuf:"varint,26,opt,name=cpdm_formula_number,json=cpdmFormulaNumber,proto3" json:"cpdm_formula_number,omitempty"`
+	CpdmTmrFeed          int32  `protobuf:"varint,27,opt,name=cpdm_tmr_feed,json=cpdmTmrFeed,proto3" json:"cpdm_tmr_feed,omitempty"`
+	CpdmFoodIntake       int32  `protobuf:"varint,28,opt,name=cpdm_food_intake,json=cpdmFoodIntake,proto3" json:"cpdm_food_intake,omitempty"`
+	FatFormulaNumber     int32  `protobuf:"varint,29,opt,name=fat_formula_number,json=fatFormulaNumber,proto3" json:"fat_formula_number,omitempty"`
+	FatTmrFeed           int32  `protobuf:"varint,30,opt,name=fat_tmr_feed,json=fatTmrFeed,proto3" json:"fat_tmr_feed,omitempty"`
+	FatFoodIntake        int32  `protobuf:"varint,31,opt,name=fat_food_intake,json=fatFoodIntake,proto3" json:"fat_food_intake,omitempty"`
+	StarchFormulaNumber  int32  `protobuf:"varint,32,opt,name=starch_formula_number,json=starchFormulaNumber,proto3" json:"starch_formula_number,omitempty"`
+	StarchTmrFeed        int32  `protobuf:"varint,33,opt,name=starch_tmr_feed,json=starchTmrFeed,proto3" json:"starch_tmr_feed,omitempty"`
+	StarchFoodIntake     int32  `protobuf:"varint,34,opt,name=starch_food_intake,json=starchFoodIntake,proto3" json:"starch_food_intake,omitempty"`
+	NdfFormulaNumber     int32  `protobuf:"varint,35,opt,name=ndf_formula_number,json=ndfFormulaNumber,proto3" json:"ndf_formula_number,omitempty"`
+	NdfTmrFeed           int32  `protobuf:"varint,36,opt,name=ndf_tmr_feed,json=ndfTmrFeed,proto3" json:"ndf_tmr_feed,omitempty"`
+	NdfFoodIntake        int32  `protobuf:"varint,37,opt,name=ndf_food_intake,json=ndfFoodIntake,proto3" json:"ndf_food_intake,omitempty"`
+	CpNdfFormulaNumber   int32  `protobuf:"varint,38,opt,name=cp_ndf_formula_number,json=cpNdfFormulaNumber,proto3" json:"cp_ndf_formula_number,omitempty"`
+	CpNdfTmrFeed         int32  `protobuf:"varint,39,opt,name=cp_ndf_tmr_feed,json=cpNdfTmrFeed,proto3" json:"cp_ndf_tmr_feed,omitempty"`
+	CpNdfFoodIntake      int32  `protobuf:"varint,40,opt,name=cp_ndf_food_intake,json=cpNdfFoodIntake,proto3" json:"cp_ndf_food_intake,omitempty"`
+	AdfFormulaNumber     int32  `protobuf:"varint,41,opt,name=adf_formula_number,json=adfFormulaNumber,proto3" json:"adf_formula_number,omitempty"`
+	AdfTmrFeed           int32  `protobuf:"varint,42,opt,name=adf_tmr_feed,json=adfTmrFeed,proto3" json:"adf_tmr_feed,omitempty"`
+	AdfFoodIntake        int32  `protobuf:"varint,43,opt,name=adf_food_intake,json=adfFoodIntake,proto3" json:"adf_food_intake,omitempty"`
+	CalciumFormulaNumber int32  `protobuf:"varint,44,opt,name=calcium_formula_number,json=calciumFormulaNumber,proto3" json:"calcium_formula_number,omitempty"`
+	CalciumTmrFeed       int32  `protobuf:"varint,45,opt,name=calcium_tmr_feed,json=calciumTmrFeed,proto3" json:"calcium_tmr_feed,omitempty"`
+	CalciumFoodIntake    int32  `protobuf:"varint,46,opt,name=calcium_food_intake,json=calciumFoodIntake,proto3" json:"calcium_food_intake,omitempty"`
+	PdmFormulaNumber     int32  `protobuf:"varint,47,opt,name=pdm_formula_number,json=pdmFormulaNumber,proto3" json:"pdm_formula_number,omitempty"`
+	PdmTmrFeed           int32  `protobuf:"varint,48,opt,name=pdm_tmr_feed,json=pdmTmrFeed,proto3" json:"pdm_tmr_feed,omitempty"`
+	PdmFoodIntake        int32  `protobuf:"varint,49,opt,name=pdm_food_intake,json=pdmFoodIntake,proto3" json:"pdm_food_intake,omitempty"`
+	CfRatioFormulaNumber int32  `protobuf:"varint,50,opt,name=cf_ratio_formula_number,json=cfRatioFormulaNumber,proto3" json:"cf_ratio_formula_number,omitempty"`
+	CfRatioTmrFeed       int32  `protobuf:"varint,51,opt,name=cf_ratio_tmr_feed,json=cfRatioTmrFeed,proto3" json:"cf_ratio_tmr_feed,omitempty"`
+	CfRatioFoodIntake    int32  `protobuf:"varint,52,opt,name=cf_ratio_food_intake,json=cfRatioFoodIntake,proto3" json:"cf_ratio_food_intake,omitempty"`
+	CreatedAt            int32  `protobuf:"varint,53,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
+	CreatedAtFormat      string `protobuf:"bytes,54,opt,name=created_at_format,json=createdAtFormat,proto3" json:"created_at_format,omitempty"`
+}
+
+func (x *AddFormulaEstimateRequest) Reset() {
+	*x = AddFormulaEstimateRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_backend_operation_statistic_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *AddFormulaEstimateRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AddFormulaEstimateRequest) ProtoMessage() {}
+
+func (x *AddFormulaEstimateRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_backend_operation_statistic_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AddFormulaEstimateRequest.ProtoReflect.Descriptor instead.
+func (*AddFormulaEstimateRequest) Descriptor() ([]byte, []int) {
+	return file_backend_operation_statistic_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *AddFormulaEstimateRequest) GetId() int32 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPastureId() int32 {
+	if x != nil {
+		return x.PastureId
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPastureName() string {
+	if x != nil {
+		return x.PastureName
+	}
+	return ""
+}
+
+func (x *AddFormulaEstimateRequest) GetBarnId() int32 {
+	if x != nil {
+		return x.BarnId
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetFeedFormulaId() int32 {
+	if x != nil {
+		return x.FeedFormulaId
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetFeedFormulaName() string {
+	if x != nil {
+		return x.FeedFormulaName
+	}
+	return ""
+}
+
+func (x *AddFormulaEstimateRequest) GetCowNumber() int32 {
+	if x != nil {
+		return x.CowNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetDryFormulaNumber() int32 {
+	if x != nil {
+		return x.DryFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetDryTmrFeed() int32 {
+	if x != nil {
+		return x.DryTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetDryFoodIntake() int32 {
+	if x != nil {
+		return x.DryFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetMjFormulaNumber() int32 {
+	if x != nil {
+		return x.MjFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetMjTmrFeed() int32 {
+	if x != nil {
+		return x.MjTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetMjFoodIntake() int32 {
+	if x != nil {
+		return x.MjFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetNndFormulaNumber() int32 {
+	if x != nil {
+		return x.NndFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetNndTmrFeed() int32 {
+	if x != nil {
+		return x.NndTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetNndFoodIntake() int32 {
+	if x != nil {
+		return x.NndFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpgFormulaNumber() int32 {
+	if x != nil {
+		return x.CpgFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpgTmrFeed() int32 {
+	if x != nil {
+		return x.CpgTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpgFoodIntake() int32 {
+	if x != nil {
+		return x.CpgFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPgFormulaNumber() int32 {
+	if x != nil {
+		return x.PgFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPgTmrFeed() int32 {
+	if x != nil {
+		return x.PgTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPgFoodIntake() int32 {
+	if x != nil {
+		return x.PgFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetDmFormulaNumber() int32 {
+	if x != nil {
+		return x.DmFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetDmTmrFeed() int32 {
+	if x != nil {
+		return x.DmTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetDmFoodIntake() int32 {
+	if x != nil {
+		return x.DmFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpdmFormulaNumber() int32 {
+	if x != nil {
+		return x.CpdmFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpdmTmrFeed() int32 {
+	if x != nil {
+		return x.CpdmTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpdmFoodIntake() int32 {
+	if x != nil {
+		return x.CpdmFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetFatFormulaNumber() int32 {
+	if x != nil {
+		return x.FatFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetFatTmrFeed() int32 {
+	if x != nil {
+		return x.FatTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetFatFoodIntake() int32 {
+	if x != nil {
+		return x.FatFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetStarchFormulaNumber() int32 {
+	if x != nil {
+		return x.StarchFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetStarchTmrFeed() int32 {
+	if x != nil {
+		return x.StarchTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetStarchFoodIntake() int32 {
+	if x != nil {
+		return x.StarchFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetNdfFormulaNumber() int32 {
+	if x != nil {
+		return x.NdfFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetNdfTmrFeed() int32 {
+	if x != nil {
+		return x.NdfTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetNdfFoodIntake() int32 {
+	if x != nil {
+		return x.NdfFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpNdfFormulaNumber() int32 {
+	if x != nil {
+		return x.CpNdfFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpNdfTmrFeed() int32 {
+	if x != nil {
+		return x.CpNdfTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCpNdfFoodIntake() int32 {
+	if x != nil {
+		return x.CpNdfFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetAdfFormulaNumber() int32 {
+	if x != nil {
+		return x.AdfFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetAdfTmrFeed() int32 {
+	if x != nil {
+		return x.AdfTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetAdfFoodIntake() int32 {
+	if x != nil {
+		return x.AdfFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCalciumFormulaNumber() int32 {
+	if x != nil {
+		return x.CalciumFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCalciumTmrFeed() int32 {
+	if x != nil {
+		return x.CalciumTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCalciumFoodIntake() int32 {
+	if x != nil {
+		return x.CalciumFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPdmFormulaNumber() int32 {
+	if x != nil {
+		return x.PdmFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPdmTmrFeed() int32 {
+	if x != nil {
+		return x.PdmTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetPdmFoodIntake() int32 {
+	if x != nil {
+		return x.PdmFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCfRatioFormulaNumber() int32 {
+	if x != nil {
+		return x.CfRatioFormulaNumber
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCfRatioTmrFeed() int32 {
+	if x != nil {
+		return x.CfRatioTmrFeed
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCfRatioFoodIntake() int32 {
+	if x != nil {
+		return x.CfRatioFoodIntake
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCreatedAt() int32 {
+	if x != nil {
+		return x.CreatedAt
+	}
+	return 0
+}
+
+func (x *AddFormulaEstimateRequest) GetCreatedAtFormat() string {
+	if x != nil {
+		return x.CreatedAtFormat
+	}
+	return ""
+}
+
+type SearchFormulaEstimateRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	StartTime  string           `protobuf:"bytes,1,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`     // 开始时间
+	EndTime    string           `protobuf:"bytes,2,opt,name=end_time,json=endTime,proto3" json:"end_time,omitempty"`           // 结束时间
+	SearchType int32            `protobuf:"varint,3,opt,name=search_type,json=searchType,proto3" json:"search_type,omitempty"` // 查询方式  1 安照配方 2 按照栏舍
+	Name       string           `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`                                // 名称
+	Pagination *PaginationModel `protobuf:"bytes,5,opt,name=pagination,proto3" json:"pagination,omitempty"`                    // 分页
+}
+
+func (x *SearchFormulaEstimateRequest) Reset() {
+	*x = SearchFormulaEstimateRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_backend_operation_statistic_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SearchFormulaEstimateRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SearchFormulaEstimateRequest) ProtoMessage() {}
+
+func (x *SearchFormulaEstimateRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_backend_operation_statistic_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SearchFormulaEstimateRequest.ProtoReflect.Descriptor instead.
+func (*SearchFormulaEstimateRequest) Descriptor() ([]byte, []int) {
+	return file_backend_operation_statistic_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *SearchFormulaEstimateRequest) GetStartTime() string {
+	if x != nil {
+		return x.StartTime
+	}
+	return ""
+}
+
+func (x *SearchFormulaEstimateRequest) GetEndTime() string {
+	if x != nil {
+		return x.EndTime
+	}
+	return ""
+}
+
+func (x *SearchFormulaEstimateRequest) GetSearchType() int32 {
+	if x != nil {
+		return x.SearchType
+	}
+	return 0
+}
+
+func (x *SearchFormulaEstimateRequest) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *SearchFormulaEstimateRequest) GetPagination() *PaginationModel {
+	if x != nil {
+		return x.Pagination
+	}
+	return nil
+}
+
+type SearchFormulaEstimateResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code int32                  `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
+	Msg  string                 `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"`
+	Data *SearchFormulaEstimate `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"`
+}
+
+func (x *SearchFormulaEstimateResponse) Reset() {
+	*x = SearchFormulaEstimateResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_backend_operation_statistic_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SearchFormulaEstimateResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SearchFormulaEstimateResponse) ProtoMessage() {}
+
+func (x *SearchFormulaEstimateResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_backend_operation_statistic_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 SearchFormulaEstimateResponse.ProtoReflect.Descriptor instead.
+func (*SearchFormulaEstimateResponse) Descriptor() ([]byte, []int) {
+	return file_backend_operation_statistic_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *SearchFormulaEstimateResponse) GetCode() int32 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *SearchFormulaEstimateResponse) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *SearchFormulaEstimateResponse) GetData() *SearchFormulaEstimate {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type SearchFormulaEstimate 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     []*AddFormulaEstimateRequest `protobuf:"bytes,4,rep,name=list,proto3" json:"list,omitempty"`
+}
+
+func (x *SearchFormulaEstimate) Reset() {
+	*x = SearchFormulaEstimate{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_backend_operation_statistic_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SearchFormulaEstimate) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SearchFormulaEstimate) ProtoMessage() {}
+
+func (x *SearchFormulaEstimate) ProtoReflect() protoreflect.Message {
+	mi := &file_backend_operation_statistic_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SearchFormulaEstimate.ProtoReflect.Descriptor instead.
+func (*SearchFormulaEstimate) Descriptor() ([]byte, []int) {
+	return file_backend_operation_statistic_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *SearchFormulaEstimate) GetPage() int32 {
+	if x != nil {
+		return x.Page
+	}
+	return 0
+}
+
+func (x *SearchFormulaEstimate) GetTotal() int32 {
+	if x != nil {
+		return x.Total
+	}
+	return 0
+}
+
+func (x *SearchFormulaEstimate) GetPageSize() int32 {
+	if x != nil {
+		return x.PageSize
+	}
+	return 0
+}
+
+func (x *SearchFormulaEstimate) GetList() []*AddFormulaEstimateRequest {
+	if x != nil {
+		return x.List
+	}
+	return nil
+}
+
+var File_backend_operation_statistic_proto protoreflect.FileDescriptor
+
+var file_backend_operation_statistic_proto_rawDesc = []byte{
+	0x0a, 0x21, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x12, 0x11, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65,
+	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x22, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f,
+	0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x11, 0x0a, 0x19, 0x41,
+	0x64, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x74,
+	0x75, 0x72, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x70, 0x61,
+	0x73, 0x74, 0x75, 0x72, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x73, 0x74, 0x75,
+	0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70,
+	0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61,
+	0x72, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x61, 0x72,
+	0x6e, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x65, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d,
+	0x75, 0x6c, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x66, 0x65,
+	0x65, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x66,
+	0x65, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x66, 0x65, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x6d,
+	0x75, 0x6c, 0x61, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x77, 0x5f, 0x6e,
+	0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6f, 0x77,
+	0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x72, 0x79, 0x5f, 0x66, 0x6f,
+	0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x10, 0x64, 0x72, 0x79, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75,
+	0x6d, 0x62, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x64, 0x72, 0x79, 0x5f, 0x74, 0x6d, 0x72, 0x5f,
+	0x66, 0x65, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x64, 0x72, 0x79, 0x54,
+	0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x64, 0x72, 0x79, 0x5f, 0x66, 0x6f,
+	0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x0d, 0x64, 0x72, 0x79, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x2a,
+	0x0a, 0x11, 0x6d, 0x6a, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d,
+	0x62, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x6d, 0x6a, 0x46, 0x6f, 0x72,
+	0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0b, 0x6d, 0x6a,
+	0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x09, 0x6d, 0x6a, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x6a,
+	0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x0d, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x0c, 0x6d, 0x6a, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65,
+	0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x6e, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f,
+	0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6e, 0x6e,
+	0x64, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x20,
+	0x0a, 0x0c, 0x6e, 0x6e, 0x64, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x0f,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6e, 0x6e, 0x64, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64,
+	0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x6e, 0x64, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74,
+	0x61, 0x6b, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x6e, 0x64, 0x46, 0x6f,
+	0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x70, 0x67, 0x5f,
+	0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x11,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x63, 0x70, 0x67, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61,
+	0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x63, 0x70, 0x67, 0x5f, 0x74, 0x6d,
+	0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x70,
+	0x67, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x70, 0x67, 0x5f,
+	0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x0d, 0x63, 0x70, 0x67, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65,
+	0x12, 0x2a, 0x0a, 0x11, 0x70, 0x67, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e,
+	0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x70, 0x67, 0x46,
+	0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0b,
+	0x70, 0x67, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x09, 0x70, 0x67, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0e,
+	0x70, 0x67, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x16,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, 0x67, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61,
+	0x6b, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x64, 0x6d, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61,
+	0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x64,
+	0x6d, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1e,
+	0x0a, 0x0b, 0x64, 0x6d, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x18, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x6d, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x24,
+	0x0a, 0x0e, 0x64, 0x6d, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65,
+	0x18, 0x19, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x64, 0x6d, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e,
+	0x74, 0x61, 0x6b, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x70, 0x64, 0x6d, 0x5f, 0x66, 0x6f, 0x72,
+	0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x1a, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x11, 0x63, 0x70, 0x64, 0x6d, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75,
+	0x6d, 0x62, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x63, 0x70, 0x64, 0x6d, 0x5f, 0x74, 0x6d, 0x72,
+	0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x70, 0x64,
+	0x6d, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x70, 0x64, 0x6d,
+	0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x1c, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x0e, 0x63, 0x70, 0x64, 0x6d, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61,
+	0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x66, 0x61, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c,
+	0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10,
+	0x66, 0x61, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72,
+	0x12, 0x20, 0x0a, 0x0c, 0x66, 0x61, 0x74, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64,
+	0x18, 0x1e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x66, 0x61, 0x74, 0x54, 0x6d, 0x72, 0x46, 0x65,
+	0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x66, 0x61, 0x74, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69,
+	0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x66, 0x61, 0x74,
+	0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x74,
+	0x61, 0x72, 0x63, 0x68, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d,
+	0x62, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x73, 0x74, 0x61, 0x72, 0x63,
+	0x68, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x26,
+	0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65,
+	0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x63, 0x68, 0x54,
+	0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x72, 0x63, 0x68,
+	0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x22, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x10, 0x73, 0x74, 0x61, 0x72, 0x63, 0x68, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e,
+	0x74, 0x61, 0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x64, 0x66, 0x5f, 0x66, 0x6f, 0x72, 0x6d,
+	0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x23, 0x20, 0x01, 0x28, 0x05,
+	0x52, 0x10, 0x6e, 0x64, 0x66, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62,
+	0x65, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x6e, 0x64, 0x66, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65,
+	0x65, 0x64, 0x18, 0x24, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6e, 0x64, 0x66, 0x54, 0x6d, 0x72,
+	0x46, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x64, 0x66, 0x5f, 0x66, 0x6f, 0x6f, 0x64,
+	0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6e,
+	0x64, 0x66, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x31, 0x0a, 0x15,
+	0x63, 0x70, 0x5f, 0x6e, 0x64, 0x66, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e,
+	0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x26, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x63, 0x70, 0x4e,
+	0x64, 0x66, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12,
+	0x25, 0x0a, 0x0f, 0x63, 0x70, 0x5f, 0x6e, 0x64, 0x66, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65,
+	0x65, 0x64, 0x18, 0x27, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x63, 0x70, 0x4e, 0x64, 0x66, 0x54,
+	0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x12, 0x63, 0x70, 0x5f, 0x6e, 0x64, 0x66,
+	0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x28, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x0f, 0x63, 0x70, 0x4e, 0x64, 0x66, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74,
+	0x61, 0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x64, 0x66, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75,
+	0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x29, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x10, 0x61, 0x64, 0x66, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65,
+	0x72, 0x12, 0x20, 0x0a, 0x0c, 0x61, 0x64, 0x66, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65,
+	0x64, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x61, 0x64, 0x66, 0x54, 0x6d, 0x72, 0x46,
+	0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x64, 0x66, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f,
+	0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x64,
+	0x66, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x63,
+	0x61, 0x6c, 0x63, 0x69, 0x75, 0x6d, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e,
+	0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x63, 0x61, 0x6c,
+	0x63, 0x69, 0x75, 0x6d, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65,
+	0x72, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x61, 0x6c, 0x63, 0x69, 0x75, 0x6d, 0x5f, 0x74, 0x6d, 0x72,
+	0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x61, 0x6c,
+	0x63, 0x69, 0x75, 0x6d, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x63,
+	0x61, 0x6c, 0x63, 0x69, 0x75, 0x6d, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61,
+	0x6b, 0x65, 0x18, 0x2e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x61, 0x6c, 0x63, 0x69, 0x75,
+	0x6d, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x70,
+	0x64, 0x6d, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65,
+	0x72, 0x18, 0x2f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x70, 0x64, 0x6d, 0x46, 0x6f, 0x72, 0x6d,
+	0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x70, 0x64, 0x6d,
+	0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18, 0x30, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x0a, 0x70, 0x64, 0x6d, 0x54, 0x6d, 0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x70,
+	0x64, 0x6d, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x31,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x70, 0x64, 0x6d, 0x46, 0x6f, 0x6f, 0x64, 0x49, 0x6e, 0x74,
+	0x61, 0x6b, 0x65, 0x12, 0x35, 0x0a, 0x17, 0x63, 0x66, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x5f,
+	0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x32,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x63, 0x66, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x46, 0x6f, 0x72,
+	0x6d, 0x75, 0x6c, 0x61, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x11, 0x63, 0x66,
+	0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x5f, 0x74, 0x6d, 0x72, 0x5f, 0x66, 0x65, 0x65, 0x64, 0x18,
+	0x33, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x63, 0x66, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x54, 0x6d,
+	0x72, 0x46, 0x65, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x14, 0x63, 0x66, 0x5f, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x5f, 0x66, 0x6f, 0x6f, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x18, 0x34, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x66, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x46, 0x6f, 0x6f, 0x64,
+	0x49, 0x6e, 0x74, 0x61, 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x64, 0x5f, 0x61, 0x74, 0x18, 0x35, 0x20, 0x01, 0x28, 0x05, 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, 0x36, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61,
+	0x74, 0x22, 0xd1, 0x01, 0x0a, 0x1c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x6f, 0x72, 0x6d,
+	0x75, 0x6c, 0x61, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d,
+	0x65, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b,
+	0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x12, 0x42, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
+	0x05, 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, 0x83, 0x01, 0x0a, 0x1d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
+	0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x3c, 0x0a,
+	0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 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, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x45, 0x73, 0x74,
+	0x69, 0x6d, 0x61, 0x74, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa0, 0x01, 0x0a, 0x15,
+	0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x45, 0x73, 0x74,
+	0x69, 0x6d, 0x61, 0x74, 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, 0x40, 0x0a, 0x04,
+	0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x62, 0x61, 0x63,
+	0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41,
+	0x64, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x45, 0x73, 0x74, 0x69, 0x6d, 0x61, 0x74,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 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 (
+	file_backend_operation_statistic_proto_rawDescOnce sync.Once
+	file_backend_operation_statistic_proto_rawDescData = file_backend_operation_statistic_proto_rawDesc
+)
+
+func file_backend_operation_statistic_proto_rawDescGZIP() []byte {
+	file_backend_operation_statistic_proto_rawDescOnce.Do(func() {
+		file_backend_operation_statistic_proto_rawDescData = protoimpl.X.CompressGZIP(file_backend_operation_statistic_proto_rawDescData)
+	})
+	return file_backend_operation_statistic_proto_rawDescData
+}
+
+var file_backend_operation_statistic_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_backend_operation_statistic_proto_goTypes = []interface{}{
+	(*AddFormulaEstimateRequest)(nil),     // 0: backend.operation.AddFormulaEstimateRequest
+	(*SearchFormulaEstimateRequest)(nil),  // 1: backend.operation.SearchFormulaEstimateRequest
+	(*SearchFormulaEstimateResponse)(nil), // 2: backend.operation.SearchFormulaEstimateResponse
+	(*SearchFormulaEstimate)(nil),         // 3: backend.operation.SearchFormulaEstimate
+	(*PaginationModel)(nil),               // 4: backend.operation.PaginationModel
+}
+var file_backend_operation_statistic_proto_depIdxs = []int32{
+	4, // 0: backend.operation.SearchFormulaEstimateRequest.pagination:type_name -> backend.operation.PaginationModel
+	3, // 1: backend.operation.SearchFormulaEstimateResponse.data:type_name -> backend.operation.SearchFormulaEstimate
+	0, // 2: backend.operation.SearchFormulaEstimate.list:type_name -> backend.operation.AddFormulaEstimateRequest
+	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_statistic_proto_init() }
+func file_backend_operation_statistic_proto_init() {
+	if File_backend_operation_statistic_proto != nil {
+		return
+	}
+	file_backend_operation_pagination_proto_init()
+	if !protoimpl.UnsafeEnabled {
+		file_backend_operation_statistic_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AddFormulaEstimateRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_backend_operation_statistic_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SearchFormulaEstimateRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_backend_operation_statistic_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SearchFormulaEstimateResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_backend_operation_statistic_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SearchFormulaEstimate); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_backend_operation_statistic_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_backend_operation_statistic_proto_goTypes,
+		DependencyIndexes: file_backend_operation_statistic_proto_depIdxs,
+		MessageInfos:      file_backend_operation_statistic_proto_msgTypes,
+	}.Build()
+	File_backend_operation_statistic_proto = out.File
+	file_backend_operation_statistic_proto_rawDesc = nil
+	file_backend_operation_statistic_proto_goTypes = nil
+	file_backend_operation_statistic_proto_depIdxs = nil
+}

+ 197 - 183
proto/go/backend/operation/system.pb.go

@@ -793,11 +793,12 @@ type UserAuthData struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	UserName     string      `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`             // 用户名称
-	Password     string      `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`                             // 用户密码
-	Phone        string      `protobuf:"bytes,3,opt,name=phone,proto3" json:"phone,omitempty"`                                   // 用户手机号
-	Roles        []*UserRole `protobuf:"bytes,4,rep,name=roles,proto3" json:"roles,omitempty"`                                   // 用户角色
-	EmployeeName string      `protobuf:"bytes,5,opt,name=employee_name,json=employeeName,proto3" json:"employee_name,omitempty"` // 员工名称
+	UserName     string         `protobuf:"bytes,1,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`             // 用户名称
+	Password     string         `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`                             // 用户密码
+	Phone        string         `protobuf:"bytes,3,opt,name=phone,proto3" json:"phone,omitempty"`                                   // 用户手机号
+	Roles        []*UserRole    `protobuf:"bytes,4,rep,name=roles,proto3" json:"roles,omitempty"`                                   // 用户角色
+	EmployeeName string         `protobuf:"bytes,5,opt,name=employee_name,json=employeeName,proto3" json:"employee_name,omitempty"` // 员工名称
+	Pastures     []*UserPasture `protobuf:"bytes,6,rep,name=pastures,proto3" json:"pastures,omitempty"`                             // 用户角色牧场牧场
 }
 
 func (x *UserAuthData) Reset() {
@@ -867,6 +868,13 @@ func (x *UserAuthData) GetEmployeeName() string {
 	return ""
 }
 
+func (x *UserAuthData) GetPastures() []*UserPasture {
+	if x != nil {
+		return x.Pastures
+	}
+	return nil
+}
+
 type UserRole struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -2083,7 +2091,7 @@ var file_backend_operation_system_proto_rawDesc = []byte{
 	0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65,
 	0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65,
 	0x72, 0x41, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22,
-	0xb5, 0x01, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61,
+	0xf1, 0x01, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61,
 	0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
 	0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a,
 	0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
@@ -2094,170 +2102,174 @@ var file_backend_operation_system_proto_rawDesc = []byte{
 	0x6f, 0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c,
 	0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x5f, 0x6e,
 	0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6d, 0x70, 0x6c, 0x6f,
-	0x79, 0x65, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x2e, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52,
-	0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
-	0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x69, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x44,
-	0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x05, 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, 0x34, 0x0a, 0x04,
-	0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63,
-	0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41,
-	0x64, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x64, 0x61,
-	0x74, 0x61, 0x22, 0xfe, 0x02, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
-	0x55, 0x73, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
-	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, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e,
-	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x31,
-	0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
+	0x79, 0x65, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x74, 0x75,
+	0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b,
+	0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73,
+	0x65, 0x72, 0x50, 0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x08, 0x70, 0x61, 0x73, 0x74, 0x75,
+	0x72, 0x65, 0x73, 0x22, 0x2e, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x12,
+	0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x22, 0x69, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69,
+	0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
+	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, 0x34, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
+	0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x79,
+	0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xfe,
+	0x02, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72,
+	0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x72, 0x6f,
+	0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x63, 0x6b,
+	0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x73,
+	0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a,
+	0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e,
+	0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x06,
+	0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79,
+	0x65, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65,
+	0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a,
+	0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05,
+	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, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41,
+	0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f,
+	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65,
+	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x73,
+	0x18, 0x0b, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x65, 0x49, 0x64, 0x73, 0x22,
+	0xa1, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d, 0x70,
+	0x6c, 0x6f, 0x79, 0x65, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0c, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37,
+	0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52,
+	0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x2c, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x72,
+	0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
+	0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12,
+	0x42, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 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, 0x71, 0x0a, 0x12, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65,
+	0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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,
+	0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
 	0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65,
-	0x73, 0x12, 0x37, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x05, 0x20, 0x01,
+	0x6e, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8d, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63,
+	0x68, 0x55, 0x73, 0x65, 0x72, 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, 0x34, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20,
+	0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72,
+	0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x6b, 0x0a, 0x17, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77,
+	0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x07, 0x69, 0x73,
+	0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x62, 0x61,
+	0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
+	0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x06, 0x69, 0x73, 0x53,
+	0x68, 0x6f, 0x77, 0x22, 0x87, 0x04, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6e, 0x75, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x05, 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, 0x1b, 0x0a, 0x09, 0x70, 0x61,
+	0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70,
+	0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6e, 0x75, 0x5f,
+	0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75,
+	0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61,
+	0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37,
+	0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52,
+	0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f,
+	0x6e, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70,
+	0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x09, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x72,
+	0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a,
+	0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 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, 0x0d, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x46, 0x6f,
+	0x72, 0x6d, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x0e, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x68,
+	0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62,
+	0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
+	0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x66, 0x66,
+	0x69, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x66, 0x66, 0x69, 0x78, 0x12,
+	0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x11, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x22, 0x6b, 0x0a,
+	0x17, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x6e,
+	0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x65, 0x6e, 0x75,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d, 0x65, 0x6e, 0x75, 0x49,
+	0x64, 0x12, 0x37, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01,
 	0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65,
 	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b, 0x69,
-	0x6e, 0x64, 0x52, 0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6d,
-	0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x07,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
-	0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08,
-	0x20, 0x01, 0x28, 0x05, 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, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x64, 0x41, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x72,
-	0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
-	0x72, 0x6f, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x6f, 0x6c, 0x65,
-	0x5f, 0x69, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x05, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x65,
-	0x49, 0x64, 0x73, 0x22, 0xa1, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73,
-	0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a,
-	0x0d, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x4e, 0x61,
-	0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70,
-	0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b,
-	0x69, 0x6e, 0x64, 0x52, 0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x2c, 0x0a, 0x12, 0x63,
-	0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d,
-	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
-	0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x72, 0x65,
-	0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20,
-	0x01, 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x54,
-	0x69, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e,
+	0x6e, 0x64, 0x52, 0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x22, 0x6b, 0x0a, 0x11, 0x53, 0x65,
+	0x61, 0x72, 0x63, 0x68, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 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, 0x71, 0x0a, 0x12, 0x53, 0x65, 0x61, 0x72, 0x63,
-	0x68, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a,
+	0x68, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a,
 	0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28,
 	0x0b, 0x32, 0x21, 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, 0x55, 0x73, 0x65, 0x72,
-	0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x8d, 0x01, 0x0a, 0x0e, 0x53,
-	0x65, 0x61, 0x72, 0x63, 0x68, 0x55, 0x73, 0x65, 0x72, 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, 0x34, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x04, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65,
-	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d,
-	0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x6b, 0x0a, 0x17, 0x49, 0x73,
-	0x53, 0x68, 0x6f, 0x77, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x37,
-	0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52,
-	0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x22, 0x87, 0x04, 0x0a, 0x0e, 0x41, 0x64, 0x64, 0x4d,
-	0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x1b,
-	0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x05, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d,
-	0x65, 0x6e, 0x75, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08,
-	0x6d, 0x65, 0x6e, 0x75, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c,
-	0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x12,
-	0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
-	0x74, 0x68, 0x12, 0x37, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77, 0x18, 0x07, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70,
-	0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x2e, 0x4b,
-	0x69, 0x6e, 0x64, 0x52, 0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1c, 0x0a, 0x09, 0x63,
-	0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
-	0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f,
-	0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x12, 0x0a,
-	0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x6f, 0x72,
-	0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x0b, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a,
-	0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28,
-	0x05, 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, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
-	0x41, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65,
-	0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x3d,
-	0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x21, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x12, 0x14, 0x0a,
-	0x05, 0x61, 0x66, 0x66, 0x69, 0x78, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x66,
-	0x66, 0x69, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65,
-	0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69, 0x76,
-	0x65, 0x22, 0x6b, 0x0a, 0x17, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x53, 0x79, 0x73, 0x74, 0x65,
-	0x6d, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07,
-	0x6d, 0x65, 0x6e, 0x75, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d,
-	0x65, 0x6e, 0x75, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x73, 0x68, 0x6f, 0x77,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64,
-	0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x49, 0x73, 0x53, 0x68, 0x6f,
-	0x77, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x06, 0x69, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x22, 0x6b,
-	0x0a, 0x11, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x71, 0x0a, 0x12, 0x53,
-	0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x35, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 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, 0x65, 0x6e, 0x75, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x71,
-	0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x65, 0x6e, 0x75, 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, 0x35, 0x0a, 0x04, 0x6c, 0x69,
-	0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4d, 0x65, 0x6e, 0x75,
+	0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x71, 0x0a, 0x0e, 0x53, 0x65,
+	0x61, 0x72, 0x63, 0x68, 0x4d, 0x65, 0x6e, 0x75, 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, 0x35, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6e, 0x75,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x7c, 0x0a,
+	0x19, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6e, 0x75, 0x50,
+	0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f,
+	0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x39, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25,
+	0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6e,
+	0x75, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xe3, 0x01, 0x0a, 0x12,
+	0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6e, 0x75, 0x44, 0x61,
+	0x74, 0x61, 0x12, 0x47, 0x0a, 0x0c, 0x70, 0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6c, 0x69,
+	0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65,
 	0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64,
-	0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x6c, 0x69, 0x73,
-	0x74, 0x22, 0x7c, 0x0a, 0x19, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x4d,
-	0x65, 0x6e, 0x75, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12,
-	0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 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, 0x39, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x25, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65,
-	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65,
-	0x72, 0x4d, 0x65, 0x6e, 0x75, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22,
-	0xe3, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65,
-	0x6e, 0x75, 0x44, 0x61, 0x74, 0x61, 0x12, 0x47, 0x0a, 0x0c, 0x70, 0x61, 0x73, 0x74, 0x75, 0x72,
-	0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x62,
-	0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x2e, 0x41, 0x64, 0x64, 0x50, 0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x52, 0x0b, 0x70, 0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12,
-	0x3e, 0x0a, 0x09, 0x6d, 0x65, 0x6e, 0x75, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65,
-	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4c, 0x69, 0x73, 0x74, 0x12,
-	0x44, 0x0a, 0x0b, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f,
-	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x62, 0x69,
-	0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x6d, 0x6f, 0x62, 0x69, 0x6c,
-	0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x36, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x62, 0x69,
-	0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 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,
+	0x50, 0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0b,
+	0x70, 0x61, 0x73, 0x74, 0x75, 0x72, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x09, 0x6d,
+	0x65, 0x6e, 0x75, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21,
+	0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6e, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x52, 0x08, 0x6d, 0x65, 0x6e, 0x75, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x44, 0x0a, 0x0b, 0x6d,
+	0x6f, 0x62, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73,
+	0x74, 0x22, 0x36, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 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 (
@@ -2304,7 +2316,8 @@ var file_backend_operation_system_proto_goTypes = []interface{}{
 	(*AddMobileRequest)(nil),          // 27: backend.operation.AddMobileRequest
 	(IsShow_Kind)(0),                  // 28: backend.operation.IsShow.Kind
 	(*PaginationModel)(nil),           // 29: backend.operation.PaginationModel
-	(*AddPastureRequest)(nil),         // 30: backend.operation.AddPastureRequest
+	(*UserPasture)(nil),               // 30: backend.operation.UserPasture
+	(*AddPastureRequest)(nil),         // 31: backend.operation.AddPastureRequest
 }
 var file_backend_operation_system_proto_depIdxs = []int32{
 	1,  // 0: backend.operation.CommonOK.data:type_name -> backend.operation.Success
@@ -2316,29 +2329,30 @@ var file_backend_operation_system_proto_depIdxs = []int32{
 	10, // 6: backend.operation.SystemToken.data:type_name -> backend.operation.TokenData
 	12, // 7: backend.operation.UserAuth.data:type_name -> backend.operation.UserAuthData
 	13, // 8: backend.operation.UserAuthData.roles:type_name -> backend.operation.UserRole
-	15, // 9: backend.operation.UserDetails.data:type_name -> backend.operation.AddSystemUser
-	13, // 10: backend.operation.AddSystemUser.roles:type_name -> backend.operation.UserRole
-	28, // 11: backend.operation.AddSystemUser.is_show:type_name -> backend.operation.IsShow.Kind
-	28, // 12: backend.operation.SearchUserRequest.is_show:type_name -> backend.operation.IsShow.Kind
-	29, // 13: backend.operation.SearchUserRequest.pagination:type_name -> backend.operation.PaginationModel
-	18, // 14: backend.operation.SearchUserResponse.data:type_name -> backend.operation.SearchUserData
-	15, // 15: backend.operation.SearchUserData.list:type_name -> backend.operation.AddSystemUser
-	28, // 16: backend.operation.IsShowSystemUserRequest.is_show:type_name -> backend.operation.IsShow.Kind
-	28, // 17: backend.operation.AddMenuRequest.is_show:type_name -> backend.operation.IsShow.Kind
-	20, // 18: backend.operation.AddMenuRequest.children:type_name -> backend.operation.AddMenuRequest
-	28, // 19: backend.operation.IsShowSystemMenuRequest.is_show:type_name -> backend.operation.IsShow.Kind
-	29, // 20: backend.operation.SearchMenuRequest.pagination:type_name -> backend.operation.PaginationModel
-	24, // 21: backend.operation.SearchMenuResponse.data:type_name -> backend.operation.SearchMenuData
-	20, // 22: backend.operation.SearchMenuData.list:type_name -> backend.operation.AddMenuRequest
-	26, // 23: backend.operation.SystemUserMenuPermissions.data:type_name -> backend.operation.SystemUserMenuData
-	30, // 24: backend.operation.SystemUserMenuData.pasture_list:type_name -> backend.operation.AddPastureRequest
-	20, // 25: backend.operation.SystemUserMenuData.menu_list:type_name -> backend.operation.AddMenuRequest
-	27, // 26: backend.operation.SystemUserMenuData.mobile_list:type_name -> backend.operation.AddMobileRequest
-	27, // [27:27] is the sub-list for method output_type
-	27, // [27:27] is the sub-list for method input_type
-	27, // [27:27] is the sub-list for extension type_name
-	27, // [27:27] is the sub-list for extension extendee
-	0,  // [0:27] is the sub-list for field type_name
+	30, // 9: backend.operation.UserAuthData.pastures:type_name -> backend.operation.UserPasture
+	15, // 10: backend.operation.UserDetails.data:type_name -> backend.operation.AddSystemUser
+	13, // 11: backend.operation.AddSystemUser.roles:type_name -> backend.operation.UserRole
+	28, // 12: backend.operation.AddSystemUser.is_show:type_name -> backend.operation.IsShow.Kind
+	28, // 13: backend.operation.SearchUserRequest.is_show:type_name -> backend.operation.IsShow.Kind
+	29, // 14: backend.operation.SearchUserRequest.pagination:type_name -> backend.operation.PaginationModel
+	18, // 15: backend.operation.SearchUserResponse.data:type_name -> backend.operation.SearchUserData
+	15, // 16: backend.operation.SearchUserData.list:type_name -> backend.operation.AddSystemUser
+	28, // 17: backend.operation.IsShowSystemUserRequest.is_show:type_name -> backend.operation.IsShow.Kind
+	28, // 18: backend.operation.AddMenuRequest.is_show:type_name -> backend.operation.IsShow.Kind
+	20, // 19: backend.operation.AddMenuRequest.children:type_name -> backend.operation.AddMenuRequest
+	28, // 20: backend.operation.IsShowSystemMenuRequest.is_show:type_name -> backend.operation.IsShow.Kind
+	29, // 21: backend.operation.SearchMenuRequest.pagination:type_name -> backend.operation.PaginationModel
+	24, // 22: backend.operation.SearchMenuResponse.data:type_name -> backend.operation.SearchMenuData
+	20, // 23: backend.operation.SearchMenuData.list:type_name -> backend.operation.AddMenuRequest
+	26, // 24: backend.operation.SystemUserMenuPermissions.data:type_name -> backend.operation.SystemUserMenuData
+	31, // 25: backend.operation.SystemUserMenuData.pasture_list:type_name -> backend.operation.AddPastureRequest
+	20, // 26: backend.operation.SystemUserMenuData.menu_list:type_name -> backend.operation.AddMenuRequest
+	27, // 27: backend.operation.SystemUserMenuData.mobile_list:type_name -> backend.operation.AddMobileRequest
+	28, // [28:28] is the sub-list for method output_type
+	28, // [28:28] is the sub-list for method input_type
+	28, // [28:28] is the sub-list for extension type_name
+	28, // [28:28] is the sub-list for extension extendee
+	0,  // [0:28] is the sub-list for field type_name
 }
 
 func init() { file_backend_operation_system_proto_init() }

+ 0 - 3
service/wechat/http.go

@@ -23,9 +23,6 @@ func NewClientService(appid, secret string) *ClientService {
 		AppID:  appid,
 		Secret: secret,
 		authClient: &http.Client{
-			/*Transport: &http.Transport{
-				MaxIdleConnsPerHost: 50,
-			},*/
 			Timeout: time.Duration(5) * time.Second,
 		},
 	}

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