Просмотр исходного кода

statistics: 准确性分析&&过程分析

Yi 1 год назад
Родитель
Сommit
7861b9a2e2

+ 12 - 8
backend/operation/pasture.proto

@@ -195,15 +195,19 @@ message ForageEnumListResponse {
 }
 
 message ForageEnumList {
-  repeated ForageSourceEnum forage_source = 1;
-  repeated ForagePlanTypeEnum forage_plan_type = 2;
-  repeated JumpDelaTypeEnum jump_dela_type = 3;
-  repeated CattleParentCategoryEnum cattle_parent_category = 4;
-  repeated ForageParentCategoryEnum forage_parent_category = 5;
+  repeated ForageSourceEnum forage_source = 1;                    // 饲料来源
+  repeated ForagePlanTypeEnum forage_plan_type = 2;               // 饲料计划类型
+  repeated JumpDelaTypeEnum jump_dela_type = 3;                   // 跳转延迟类型
+  repeated CattleParentCategoryEnum cattle_parent_category = 4;   // 畜牧分类
+  repeated ForageParentCategoryEnum forage_parent_category = 5;   // 饲料分类
   repeated IsShowEnum is_show = 6;
-  repeated FormulaTypeEnum formula_type = 7;
-  repeated FormulaOptionEnum formula_list = 8;
-  repeated IsShowEnum confirm_start = 9;
+  repeated FormulaTypeEnum formula_type = 7;                      // 配方类型
+  repeated FormulaOptionEnum formula_list = 8;                    // 所有配方列表
+  repeated IsShowEnum confirm_start = 9;                          // 确认开始
+  repeated FormulaOptionEnum formulation_evaluation = 10;         // 配方评估查询方式
+  repeated FormulaOptionEnum use_materials_list = 11;             // 用料分析-列表显示
+  repeated FormulaOptionEnum use_materials_type = 12;             // 用料分析-统计类型
+  repeated FormulaOptionEnum price_materials_type = 13;           // 价格分析-统计类型
 }
 
 message ForageSourceEnum {

+ 115 - 1
backend/operation/statistic.proto

@@ -11,7 +11,7 @@ import "backend/operation/enum.proto";
 message SearchFormulaEstimateRequest {
   string start_time  = 1;     // 开始时间
   string end_time    = 2;     // 结束时间
-  int32 search_type = 3;      // 查询方式  1 安照配方 2 按照栏舍
+  int32 search_type = 3;      // 查询方式  0 安照配方 1 按照栏舍
   string api_name = 4;        // 牧场端接口标识名称
   int32 pasture_id = 5;       // 牧场id
   int32 template_id = 6;     // 配方模板id
@@ -41,6 +41,16 @@ message SearchUserMaterialsStatisticsRequest {
   PaginationModel pagination = 8; // 分页
 }
 
+// SearchPriceStatisticsRequest 库存管理-价格分析
+message SearchPriceStatisticsRequest {
+  string start_time  = 1;     // 开始时间
+  string end_time    = 2;     // 结束时间
+  string api_name = 3;        // 牧场端接口标识名称
+  int32 pasture_id = 4;       // 牧场id
+  string feed_name = 5;        // 名称
+  PaginationModel pagination = 6; // 分页
+}
+
 // SearchFeedStatisticsRequest 饲喂效率-效率统计
 message SearchFeedStatisticsRequest {
   string start_time  = 1;            // 开始时间
@@ -62,6 +72,110 @@ message FeedChartStatisticsRequest {
   string api_type = 5;       // mr 泌乳牛干物质采食量 sl 牛栏剩料率 hl 混料时间统计 zh 转化率 cbft 成本分析
 }
 
+// CowsAnalysisRequest 饲喂效率-牛群评估
+message CowsAnalysisRequest {
+  string start_time = 1;     // 开始时间
+  string api_name = 2;       // 牧场端接口标识名称
+  int32 pasture_id = 3;      // 牧场id
+  PaginationModel pagination = 4;   // 分页
+}
+
+// AccuracyAggStatisticsRequest 准确性分析-汇总统计
+message AccuracyAggStatisticsRequest {
+  string start_time = 1;     // 开始时间
+  string end_time = 2;       // 结束时间
+  int32 pasture_id = 3;      // 牧场id
+  string fname = 4;         // 查询名称
+  string sort = 5;
+  string status = 6;
+  int32 genre = 7;
+  int32 isdate = 8;
+  int32 hlwc1 = 9;
+  int32 hlwc2 = 10;
+  int32 hlzq1 = 11;
+  int32 hlzq2 = 12;
+  int32 hlzql1 = 13;
+  int32 hlzql2 = 14;
+  int32 slwc1 = 15;
+  int32 slwc2 = 16;
+  int32 slzq1 = 17;
+  int32 slzq2 = 18;
+  int32 slzql1 = 19;
+  int32 slzql2 = 20;
+  string projname = 21;
+  string Times = 22;
+  bool is_error = 23;
+}
+
+// MixFeedStatisticsRequest 准确性分析-混料统计
+message MixFeedStatisticsRequest {
+  string start_time  = 1;            // 开始时间
+  string end_time = 2;               // 结束时间
+  string api_name = 3;               // 牧场端接口标识名称
+  int32 pasture_id = 4;              // 牧场id
+  string equipment_name = 5;         // 设备名称
+  string train_number = 6;           // 车次
+  int32 class_number = 7;            // 班次
+  string formulation_name = 8;       // 配方名称
+  int32 jump_type = 9;               // 跳转方式 0 手动跳转 1 自动跳转
+  int32 hlwc1 = 10;                  // 混料误差值1
+  int32 hlwc2 = 11;                  // 混料误差值2
+  int32 hlzq1 = 12;                  // 混料准确率1
+  int32 hlzq2 = 13;                  // 混料准确率2
+  int32 hlzql1 = 14;                 // 混料正确率1
+  int32 hlzql2 = 15;                 // 混料正确率2
+  bool is_error = 16;                // 只看超出预设值数据
+  string button_type = 17;
+  string is_use = 18;
+  PaginationModel pagination = 19;   // 分页
+}
+
+// SprinkleStatisticsRequest 准确性分析-撒料统计
+message SprinkleStatisticsRequest {
+  string start_time  = 1;            // 开始时间
+  string end_time = 2;               // 结束时间
+  string api_name = 3;               // 牧场端接口标识名称
+  int32 pasture_id = 4;              // 牧场id
+  string equipment_name = 5;         // tmr设备名称
+  string train_number = 6;           // 车次
+  int32 class_number = 7;            // 班次
+  string formulation_name = 8;       // 配方名称
+  string barn_name = 9;              // 栏舍名称
+  int32 jump_type = 10;               // 跳转方式 0 手动跳转 1 自动跳转
+  int32 slwc1 = 11;                  // 撒料误差值1
+  int32 slwc2 = 12;                  // 撒料误差值2
+  int32 slzq1 = 13;                  // 撒料准确率1
+  int32 slzq2 = 14;                  // 撒料准确率2
+  int32 slzql1 = 15;                 // 撒料正确率1
+  int32 slzql2 = 16;                 // 撒料正确率2
+  bool is_error = 17;                // 只看超出预设值数据
+  string button_type = 18;
+  string is_use = 19;
+  PaginationModel pagination = 20;   // 分页
+}
+
+// ProcessAnalysisRequest 过程分析
+message ProcessAnalysisRequest {
+  string start_time  = 1;            // 开始时间
+  string end_time = 2;               // 结束时间
+  string api_name = 3;               // 牧场端接口标识名称
+  int32 pasture_id = 4;              // 牧场id
+  int32 plan_type = 5;               // 计划类型
+  repeated string tmr_name = 6;      // TMR名称
+  string error_range = 7;            // 误差筛选范围
+  string work_status = 8;            // 工作状态
+  string mix_feed_type = 9;          // 混料类别
+  int32 hlwc1 = 10;                  // 混料误差值1
+  int32 hlwc2 = 11;                  // 混料误差值2
+  int32 hlzq1 = 12;                  // 混料准确率1
+  int32 hlzq2 = 13;                  // 混料准确率2
+  int32 slwc1 = 14;                  // 撒料误差值1
+  int32 slwc2 = 15;                  // 撒料误差值2
+  int32 slzq1 = 16;                  // 撒料准确率1
+  int32 slzq2 = 17;                  // 撒料准确率2
+  PaginationModel pagination = 18;   // 分页
+}
+
 // 首页 dashboard 准确性分析
 message SearchAnalysisAccuracyRequest {
   CattleCategoryParent.Kind cattle_parent_category_id = 1;   // 牧畜分类id 泌乳牛

+ 1 - 2
go.mod

@@ -22,7 +22,6 @@ require (
 	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/magiconair/properties v1.8.7
 	github.com/mitchellh/mapstructure v1.5.0
-	github.com/natefinch/lumberjack v2.0.0+incompatible
 	github.com/nyaruka/phonenumbers v1.1.7
 	github.com/sirupsen/logrus v1.9.0
 	github.com/spf13/cobra v1.7.0
@@ -35,6 +34,7 @@ require (
 	google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef
 	google.golang.org/grpc v1.52.0
 	google.golang.org/protobuf v1.30.0
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1
 	gorm.io/driver/mysql v1.5.0
 	gorm.io/gorm v1.25.0
 )
@@ -93,6 +93,5 @@ require (
 	golang.org/x/sys v0.7.0 // indirect
 	golang.org/x/text v0.9.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
-	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

+ 0 - 3
go.sum

@@ -37,7 +37,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
 cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
@@ -249,8 +248,6 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
-github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
-github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
 github.com/nyaruka/phonenumbers v1.1.7 h1:5UUI9hE79Kk0dymSquXbMYB7IlNDNhvu2aNlJpm9et8=
 github.com/nyaruka/phonenumbers v1.1.7/go.mod h1:DC7jZd321FqUe+qWSNcHi10tyIyGNXGcNbfkPvdp1Vs=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=

+ 154 - 6
http/handler/statistic/analysis.go

@@ -24,7 +24,6 @@ func SearchFormulaEstimateList(c *gin.Context) {
 		valid.Field(&req.PastureId, valid.Required),
 		valid.Field(&req.StartTime, valid.Required),
 		valid.Field(&req.EndTime, valid.Required),
-		valid.Field(&req.SearchType, valid.Required, valid.Min(0), valid.Max(2)),
 	); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -89,7 +88,6 @@ func SearchUserMaterialsStatistics(c *gin.Context) {
 		valid.Field(&req.PastureId, valid.Required),
 		valid.Field(&req.StartTime, valid.Required),
 		valid.Field(&req.EndTime, valid.Required),
-		valid.Field(&req.TypeCheck, valid.Required, valid.Min(1), valid.Max(2)),
 	); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -111,7 +109,7 @@ func SearchUserMaterialsStatistics(c *gin.Context) {
 
 // SearchPriceStatistics 库存管理-价格分析
 func SearchPriceStatistics(c *gin.Context) {
-	var req operationPb.SearchUserMaterialsStatisticsRequest
+	var req operationPb.SearchPriceStatisticsRequest
 	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -122,7 +120,6 @@ func SearchPriceStatistics(c *gin.Context) {
 		valid.Field(&req.PastureId, valid.Required),
 		valid.Field(&req.StartTime, valid.Required),
 		valid.Field(&req.EndTime, valid.Required),
-		valid.Field(&req.TypeCheck, valid.Required, valid.Min(1), valid.Max(2)),
 	); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -134,7 +131,7 @@ func SearchPriceStatistics(c *gin.Context) {
 		PageOffset: int32(c.GetInt(middleware.PageOffset)),
 	}
 
-	res, err := middleware.BackendOperation(c).OpsService.SearchUserMaterialsStatistics(c, &req)
+	res, err := middleware.BackendOperation(c).OpsService.SearchPriceStatistics(c, &req)
 	if err != nil {
 		apierr.ClassifiedAbort(c, err)
 		return
@@ -173,6 +170,36 @@ func SearchFeedStatistics(c *gin.Context) {
 	c.JSON(http.StatusOK, res)
 }
 
+// SearchCowsAnalysis 饲喂效率-牛群评估
+func SearchCowsAnalysis(c *gin.Context) {
+	var req operationPb.CowsAnalysisRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.PastureId, valid.Required),
+		valid.Field(&req.StartTime, valid.Required),
+	); 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.CowsAnalysis(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
 // SearchFeedChartStatistics 饲喂效率-chart图表分析
 func SearchFeedChartStatistics(c *gin.Context) {
 	var req operationPb.FeedChartStatisticsRequest
@@ -199,7 +226,128 @@ func SearchFeedChartStatistics(c *gin.Context) {
 	c.JSON(http.StatusOK, res)
 }
 
-// AnalysisAccuracy 准备性分析
+// SearchAccuracyAggStatistics 准确性分析-汇总统计
+func SearchAccuracyAggStatistics(c *gin.Context) {
+	var req operationPb.AccuracyAggStatisticsRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.PastureId, valid.Required),
+		valid.Field(&req.StartTime, valid.Required),
+		valid.Field(&req.EndTime, valid.Required),
+	); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	res, err := middleware.BackendOperation(c).OpsService.SearchAccuracyAggStatistics(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
+// SearchMixFeedStatistics 准确性分析-混料统计
+func SearchMixFeedStatistics(c *gin.Context) {
+	var req operationPb.MixFeedStatisticsRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.ApiName, valid.Required),
+		valid.Field(&req.PastureId, valid.Required),
+		valid.Field(&req.StartTime, valid.Required),
+		valid.Field(&req.EndTime, valid.Required),
+	); 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.SearchMixFeedStatistics(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
+// SearchSprinkleStatistics 准确性分析-撒料统计
+func SearchSprinkleStatistics(c *gin.Context) {
+	var req operationPb.SprinkleStatisticsRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.PastureId, valid.Required),
+		valid.Field(&req.ApiName, valid.Required),
+		valid.Field(&req.StartTime, valid.Required),
+		valid.Field(&req.EndTime, valid.Required),
+	); 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.SearchSprinkleStatistics(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
+// SearchProcessAnalysis 过程分析
+func SearchProcessAnalysis(c *gin.Context) {
+	var req operationPb.ProcessAnalysisRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.PastureId, valid.Required),
+		valid.Field(&req.ApiName, valid.Required),
+		valid.Field(&req.StartTime, valid.Required),
+		valid.Field(&req.EndTime, valid.Required),
+	); 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.SearchProcessAnalysis(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
+// AnalysisAccuracy 首页仪表盘-准确性分析
 func AnalysisAccuracy(c *gin.Context) {
 	var req operationPb.SearchAnalysisAccuracyRequest
 	if err := c.BindJSON(&req); err != nil {

+ 8 - 2
http/route/app_api.go

@@ -109,8 +109,14 @@ func AppAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		opsRoute.POST("/inventory/user_materials_statistics", statistic.SearchUserMaterialsStatistics)
 		opsRoute.POST("/inventory/price_statistics", statistic.SearchPriceStatistics)
 		opsRoute.POST("/feed_efficiency/statistics", statistic.SearchFeedStatistics)
-		opsRoute.POST("/feed_efficiency/char_statistics", statistic.SearchFeedChartStatistics)
-
+		opsRoute.POST("/feed_efficiency/chart_statistics", statistic.SearchFeedChartStatistics)
+		opsRoute.POST("/feed_efficiency/cows_analysis", statistic.SearchCowsAnalysis)
+		opsRoute.POST("/accuracy/agg_statistics", statistic.SearchAccuracyAggStatistics)
+		opsRoute.POST("/accuracy/mixed_statistics", statistic.SearchMixFeedStatistics)
+		opsRoute.POST("/accuracy/sprinkle_statistics", statistic.SearchSprinkleStatistics)
+		opsRoute.POST("/process/analysis", statistic.SearchProcessAnalysis)
+
+		// 首页仪表盘
 		opsRoute.GET("/analysis/accuracy", statistic.AnalysisAccuracy)
 
 		// 其他

+ 107 - 73
model/formula_estimate.go

@@ -1,86 +1,22 @@
 package model
 
-/*
-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 PastureCommonRequest struct {
 	Name       string      `json:"name"`
 	Page       int32       `json:"page"`
 	Offset     int32       `json:"offset"`
 	PageCount  int32       `json:"pagecount"`
 	ReturnType string      `json:"returntype"`
-	Checked    int32       `json:"checked"`
+	Checked    int32       `json:"checked,omitempty"`
 	ParamMaps  interface{} `json:"parammaps"`
 }
 
 type FormulaEstimateParams struct {
-	PastureId     string   `json:"pastureid"`
-	StartTime     string   `json:"startTime"`
-	StopTime      string   `json:"stopTime"`
-	InputDatetime []string `json:"inputDatetime"`
-	Search        string   `json:"search"`
-	TempletId     string   `json:"templetid"`
-	Barid         string   `json:"barid"`
+	PastureId string `json:"pastureid"`
+	StartTime string `json:"startTime"`
+	StopTime  string `json:"stopTime"`
+	Search    string `json:"search"`
+	TempletId string `json:"templetid"`
+	Barid     string `json:"barid"`
 }
 
 type PastureCommonResponse struct {
@@ -91,6 +27,7 @@ type PastureCommonResponse struct {
 
 type PastureCommonData struct {
 	List     interface{} `json:"list"`
+	Data     interface{} `json:"data"`
 	PageSize int32       `json:"pageSize"`
 	Total    int32       `json:"total"`
 	PageNum  int32       `json:"pageNum"`
@@ -123,18 +60,28 @@ type UserMaterialsStatisticsParams struct {
 	Typea     string `json:"typea"`
 }
 
-type FeedStatisticsParams struct {
+type PriceStatisticsParams struct {
 	PastureId string `json:"pastureid"`
 	StartTime string `json:"startTime"`
 	StopTime  string `json:"stopTime"`
 	FeedName  string `json:"fname"`
+}
+
+// FeedStatisticsParams 饲喂效率-效率统计
+type FeedStatisticsParams struct {
+	PastureId string `json:"pastureid"`
+	StartTime string `json:"startTime"`
+	StopTime  string `json:"stopTime"`
+	Date      string `json:"date"`
+	FeedTName string `json:"ftname"`
 	BarName   string `json:"barname"`
 	CowClass  string `json:"cowclass"`
 	Times     string `json:"times"`
 }
 
+// FeedChartParams 饲喂效率-图形统计
 type FeedChartParams struct {
-	ParamMaps *ParamMaps `json:"parammaps"`
+	ParamMaps interface{} `json:"parammaps"`
 }
 
 type ParamMaps struct {
@@ -143,3 +90,90 @@ type ParamMaps struct {
 	StopTime  string `json:"stopTime"`
 	Status    int32  `json:"status"`
 }
+
+// MixFeedStatisticsParams 准确性分析-混料统计
+type MixFeedStatisticsParams struct {
+	PastureId   string `json:"pastureid"`
+	StartTime   string `json:"startTime"`
+	StopTime    string `json:"stopTime"`
+	TmrTName    string `json:"tmrTName"`
+	ProjName    string `json:"projName"`
+	Times       string `json:"times"`
+	ButtonType  string `json:"buttonType"`
+	TempletName string `json:"templetName"`
+	Isuse       string `json:"isuse"`
+	Hlwc1       int32  `json:"hlwc1,omitempty"`
+	Hlwc2       int32  `json:"hlwc2,omitempty"`
+	Hlzq1       int32  `json:"hlzq1,omitempty"`
+	Hlzq2       int32  `json:"hlzq2,omitempty"`
+	Hlzql1      int32  `json:"hlzql1,omitempty"`
+	Hlzql2      int32  `json:"hlzql2,omitempty"`
+	Error       bool   `json:"error,omitempty"`
+}
+
+// SprinkleStatisticsParams 准确性分析-撒料统计
+type SprinkleStatisticsParams struct {
+	PastureId   string `json:"pastureid"`
+	StartTime   string `json:"startTime"`
+	StopTime    string `json:"stopTime"`
+	TmrTName    string `json:"tmrTName"`
+	ProjName    string `json:"projName"`
+	Times       string `json:"times"`
+	Fname       string `json:"fname"`
+	ButtonType  string `json:"buttontype"`
+	TempletName string `json:"templetname"`
+	Isuse       string `json:"isuse,omitempty"`
+	Slwc1       int32  `json:"slwc1,omitempty"`
+	Slwc2       int32  `json:"slwc2,omitempty"`
+	Slzq1       int32  `json:"slzq1,omitempty"`
+	Slzq2       int32  `json:"slzq2,omitempty"`
+	Slzql1      int32  `json:"slzql1,omitempty"`
+	Slzql2      int32  `json:"slzql2,omitempty"`
+	Error       bool   `json:"error,omitempty"`
+}
+
+// ProcessAnalysisParams 过程分析
+type ProcessAnalysisParams struct {
+	PastureId   string   `json:"pastureid"`
+	StartTime   string   `json:"startTime"`
+	StopTime    string   `json:"stopTime"`
+	TmrTName    []string `json:"tmrTName"`
+	IsCompleted string   `json:"iscompleted"`
+	LpPlanType  string   `json:"lpplantype"`
+	FClassId    string   `json:"fclassid"`
+	Hlwc1       int32    `json:"hlwc1,omitempty"`
+	Hlwc2       int32    `json:"hlwc2,omitempty"`
+	Hlzq1       int32    `json:"hlzq1,omitempty"`
+	Hlzq2       int32    `json:"hlzq2,omitempty"`
+	Slwc1       int32    `json:"slwc1,omitempty"`
+	Slwc2       int32    `json:"slwc2,omitempty"`
+	Slzq1       int32    `json:"slzq1,omitempty"`
+	Slzq2       int32    `json:"slzq2,omitempty"`
+	Error       string   `json:"error,omitempty"`
+}
+
+// AccuracyAggParams 准确性分析-汇总统计
+type AccuracyAggParams struct {
+	PastureId string `json:"pastureid"`
+	StartTime string `json:"startTime"`
+	StopTime  string `json:"stopTime"`
+	FName     string `json:"fname"`
+	Sort      string `json:"sort"`
+	Times     string `json:"times"`
+	Status    string `json:"status"`
+	Genre     int32  `json:"genre"`
+	IsDate    int32  `json:"isdate"`
+	Hlwc1     int32  `json:"hlwc1,omitempty"`
+	Hlwc2     int32  `json:"hlwc2,omitempty"`
+	Hlzq1     int32  `json:"hlzq1,omitempty"`
+	Hlzq2     int32  `json:"hlzq2,omitempty"`
+	Hlzql1    int32  `json:"hlzql1,omitempty"`
+	Hlzql2    int32  `json:"hlzql2,omitempty"`
+	Slwc1     int32  `json:"slwc1,omitempty"`
+	Slwc2     int32  `json:"slwc2,omitempty"`
+	Slzq1     int32  `json:"slzq1,omitempty"`
+	Slzq2     int32  `json:"slzq2,omitempty"`
+	Slzql1    int32  `json:"slzql1,omitempty"`
+	Slzql2    int32  `json:"slzql2,omitempty"`
+	Error     bool   `json:"error,omitempty"`
+}

+ 22 - 10
model/group_pasture.go

@@ -4,7 +4,6 @@ import (
 	"bytes"
 	"encoding/json"
 	"fmt"
-	"go.uber.org/zap"
 	"io/ioutil"
 	"kpt-tmr-group/pkg/logger/zaplog"
 	"kpt-tmr-group/pkg/tool"
@@ -12,6 +11,8 @@ import (
 	operationPb "kpt-tmr-group/proto/go/backend/operation"
 	"net/http"
 	"time"
+
+	"go.uber.org/zap"
 )
 
 type GroupPasture struct {
@@ -39,15 +40,26 @@ const (
 	InitManagerPassword = "123456"
 	UrlDataByName       = "authdata/GetDataByName"
 	UrlReportForm       = "authdata/GetReportform"
+	UrlSummary          = "authdata/summary"
+	UrlProcess          = "authdata/processAnalysist"
 )
 
-var FeedCharUrl = map[string]string{
-	"mr":   "authdata/chart/feedEffMR",
-	"sl":   "authdata/chart/feedEffSL",
-	"hl":   "authdata/chart/feedEffHL",
-	"zh":   "authdata/chart/feedEffZH",
-	"cbft": "authdata/chart/feedEffCBFT",
-}
+var (
+	UrlChart = map[string]string{
+		"mr":    "authdata/chart/feedEffMR",     // 饲喂效率-效率统计 mr 泌乳牛干物质采食量
+		"sl":    "authdata/chart/feedEffSL",     // 饲喂效率-效率统计 sl 牛栏剩料率
+		"hl":    "authdata/chart/feedEffHL",     // 饲喂效率-效率统计 hl 混料时间统计
+		"zh":    "authdata/chart/feedEffZH",     // 饲喂效率-效率统计 zh 转化率
+		"cbft":  "authdata/chart/feedEffCBFT",   // 饲喂效率-效率统计 cbft 成本分析
+		"jh":    "authdata/chart/accuracyAllJH", // 准确性分析-汇总统计-计划统计
+		"ft":    "authdata/chart/accuracyAllFT", // 准确性分析-汇总统计-配方准确率
+		"nq":    "authdata/chart/accuracyAllNQ", // 准确性分析-汇总统计-牛群准确率
+		"cc":    "authdata/chart/accuracyAllCC", // 准确性分析-汇总统计-车辆准确率(重量)
+		"allhl": "authdata/chart/accuracyAllHL", // 准确性分析-汇总统计-混料统计
+		"qx":    "authdata/chart/accuracyAllQX", // 准确性分析-汇总统计-混料计划取消次数
+		"ls":    "authdata/chart/accuracyAllLS", // 准确性分析-汇总统计-栏舍撒料时间统计
+	}
+)
 
 type PastureTokenRequest struct {
 	UserName string `json:"username"`
@@ -117,7 +129,7 @@ func (p *PastureClient) doRequest(req *http.Request) ([]byte, error) {
 func (p *PastureClient) DoGet(url string) ([]byte, error) {
 	// 获取token
 	if err := p.GetToken(); err != nil {
-		zaplog.Error("PastureClient", zap.Any("GetToken Err", err), zap.Any("detail", p.Detail))
+		zaplog.Error("PastureClient", zap.Any("DoGet GetToken Err", err), zap.Any("detail", p.Detail))
 		return nil, xerr.WithStack(err)
 	}
 
@@ -140,7 +152,7 @@ func (p *PastureClient) DoPost(url string, body interface{}) ([]byte, error) {
 	}
 	// 获取token
 	if err = p.GetToken(); err != nil {
-		zaplog.Error("PastureClient", zap.Any("GetToken Err", err), zap.Any("detail", p.Detail))
+		zaplog.Error("PastureClient", zap.Any("DoPost GetToken Err", err), zap.Any("detail", p.Detail))
 		return nil, xerr.WithStack(err)
 	}
 	req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(b))

+ 7 - 0
module/backend/interface.go

@@ -132,8 +132,15 @@ type StatisticService interface {
 	SearchFormulaEstimateList(ctx context.Context, req *operationPb.SearchFormulaEstimateRequest) (*model.PastureCommonResponse, error)
 	SearchInventoryStatistics(ctx context.Context, req *operationPb.SearchInventoryStatisticsRequest) (*model.PastureCommonResponse, error)
 	SearchUserMaterialsStatistics(ctx context.Context, req *operationPb.SearchUserMaterialsStatisticsRequest) (*model.PastureCommonResponse, error)
+	SearchPriceStatistics(ctx context.Context, req *operationPb.SearchPriceStatisticsRequest) (*model.PastureCommonResponse, error)
 	SearchFeedStatistics(ctx context.Context, req *operationPb.SearchFeedStatisticsRequest) (*model.PastureCommonResponse, error)
 	FeedChartStatistics(ctx context.Context, req *operationPb.FeedChartStatisticsRequest) (*model.PastureCommonResponse, error)
+	CowsAnalysis(ctx context.Context, req *operationPb.CowsAnalysisRequest) (*model.PastureCommonResponse, error)
+	SearchAccuracyAggStatistics(ctx context.Context, req *operationPb.AccuracyAggStatisticsRequest) (*model.PastureCommonResponse, error)
+	SearchMixFeedStatistics(ctx context.Context, req *operationPb.MixFeedStatisticsRequest) (*model.PastureCommonResponse, error)
+	SearchSprinkleStatistics(ctx context.Context, req *operationPb.SprinkleStatisticsRequest) (*model.PastureCommonResponse, error)
+	SearchProcessAnalysis(ctx context.Context, req *operationPb.ProcessAnalysisRequest) (*model.PastureCommonResponse, error)
+
 	SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error)
 }
 

+ 152 - 2
module/backend/mock/kptservice.go

@@ -81,6 +81,21 @@ func (mr *MockKptServiceMockRecorder) Auth(arg0, arg1 interface{}) *gomock.Call
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Auth", reflect.TypeOf((*MockKptService)(nil).Auth), arg0, arg1)
 }
 
+// CowsAnalysis mocks base method.
+func (m *MockKptService) CowsAnalysis(arg0 context.Context, arg1 *operationPb.CowsAnalysisRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CowsAnalysis", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CowsAnalysis indicates an expected call of CowsAnalysis.
+func (mr *MockKptServiceMockRecorder) CowsAnalysis(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CowsAnalysis", reflect.TypeOf((*MockKptService)(nil).CowsAnalysis), arg0, arg1)
+}
+
 // CreateFeedFormula mocks base method.
 func (m *MockKptService) CreateFeedFormula(arg0 context.Context, arg1 *operationPb.AddFeedFormulaRequest) error {
 	m.ctrl.T.Helper()
@@ -506,6 +521,21 @@ func (mr *MockKptServiceMockRecorder) ExcelTemplateForage(arg0 interface{}) *gom
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExcelTemplateForage", reflect.TypeOf((*MockKptService)(nil).ExcelTemplateForage), arg0)
 }
 
+// FeedChartStatistics mocks base method.
+func (m *MockKptService) FeedChartStatistics(arg0 context.Context, arg1 *operationPb.FeedChartStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "FeedChartStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// FeedChartStatistics indicates an expected call of FeedChartStatistics.
+func (mr *MockKptServiceMockRecorder) FeedChartStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FeedChartStatistics", reflect.TypeOf((*MockKptService)(nil).FeedChartStatistics), arg0, arg1)
+}
+
 // ForageEnumList mocks base method.
 func (m *MockKptService) ForageEnumList(arg0 context.Context) *operationPb.ForageEnumListResponse {
 	m.ctrl.T.Helper()
@@ -734,6 +764,21 @@ func (mr *MockKptServiceMockRecorder) ResetPasswordSystemUser(arg0, arg1 interfa
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetPasswordSystemUser", reflect.TypeOf((*MockKptService)(nil).ResetPasswordSystemUser), arg0, arg1)
 }
 
+// SearchAccuracyAggStatistics mocks base method.
+func (m *MockKptService) SearchAccuracyAggStatistics(arg0 context.Context, arg1 *operationPb.AccuracyAggStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchAccuracyAggStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchAccuracyAggStatistics indicates an expected call of SearchAccuracyAggStatistics.
+func (mr *MockKptServiceMockRecorder) SearchAccuracyAggStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchAccuracyAggStatistics", reflect.TypeOf((*MockKptService)(nil).SearchAccuracyAggStatistics), arg0, arg1)
+}
+
 // SearchAnalysisAccuracy mocks base method.
 func (m *MockKptService) SearchAnalysisAccuracy(arg0 context.Context, arg1 *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error) {
 	m.ctrl.T.Helper()
@@ -779,6 +824,21 @@ func (mr *MockKptServiceMockRecorder) SearchFeedFormulaList(arg0, arg1 interface
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchFeedFormulaList", reflect.TypeOf((*MockKptService)(nil).SearchFeedFormulaList), arg0, arg1)
 }
 
+// SearchFeedStatistics mocks base method.
+func (m *MockKptService) SearchFeedStatistics(arg0 context.Context, arg1 *operationPb.SearchFeedStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchFeedStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchFeedStatistics indicates an expected call of SearchFeedStatistics.
+func (mr *MockKptServiceMockRecorder) SearchFeedStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchFeedStatistics", reflect.TypeOf((*MockKptService)(nil).SearchFeedStatistics), arg0, arg1)
+}
+
 // SearchForageCategoryList mocks base method.
 func (m *MockKptService) SearchForageCategoryList(arg0 context.Context, arg1 *operationPb.SearchForageCategoryRequest) (*operationPb.SearchForageCategoryResponse, error) {
 	m.ctrl.T.Helper()
@@ -810,10 +870,10 @@ func (mr *MockKptServiceMockRecorder) SearchForageList(arg0, arg1 interface{}) *
 }
 
 // SearchFormulaEstimateList mocks base method.
-func (m *MockKptService) SearchFormulaEstimateList(arg0 context.Context, arg1 *operationPb.SearchFormulaEstimateRequest) (*model.FormulaEstimateResponse, error) {
+func (m *MockKptService) SearchFormulaEstimateList(arg0 context.Context, arg1 *operationPb.SearchFormulaEstimateRequest) (*model.PastureCommonResponse, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "SearchFormulaEstimateList", arg0, arg1)
-	ret0, _ := ret[0].(*model.FormulaEstimateResponse)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
 	ret1, _ := ret[1].(error)
 	return ret0, ret1
 }
@@ -839,6 +899,36 @@ func (mr *MockKptServiceMockRecorder) SearchGroupPastureList(arg0, arg1 interfac
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchGroupPastureList", reflect.TypeOf((*MockKptService)(nil).SearchGroupPastureList), arg0, arg1)
 }
 
+// SearchInventoryStatistics mocks base method.
+func (m *MockKptService) SearchInventoryStatistics(arg0 context.Context, arg1 *operationPb.SearchInventoryStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchInventoryStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchInventoryStatistics indicates an expected call of SearchInventoryStatistics.
+func (mr *MockKptServiceMockRecorder) SearchInventoryStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchInventoryStatistics", reflect.TypeOf((*MockKptService)(nil).SearchInventoryStatistics), arg0, arg1)
+}
+
+// SearchMixFeedStatistics mocks base method.
+func (m *MockKptService) SearchMixFeedStatistics(arg0 context.Context, arg1 *operationPb.MixFeedStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchMixFeedStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchMixFeedStatistics indicates an expected call of SearchMixFeedStatistics.
+func (mr *MockKptServiceMockRecorder) SearchMixFeedStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchMixFeedStatistics", reflect.TypeOf((*MockKptService)(nil).SearchMixFeedStatistics), arg0, arg1)
+}
+
 // SearchMobileList mocks base method.
 func (m *MockKptService) SearchMobileList(arg0 context.Context, arg1 *operationPb.SearchMobileRequest) (*operationPb.SearchMobileResponse, error) {
 	m.ctrl.T.Helper()
@@ -854,6 +944,51 @@ func (mr *MockKptServiceMockRecorder) SearchMobileList(arg0, arg1 interface{}) *
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchMobileList", reflect.TypeOf((*MockKptService)(nil).SearchMobileList), arg0, arg1)
 }
 
+// SearchPriceStatistics mocks base method.
+func (m *MockKptService) SearchPriceStatistics(arg0 context.Context, arg1 *operationPb.SearchPriceStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchPriceStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchPriceStatistics indicates an expected call of SearchPriceStatistics.
+func (mr *MockKptServiceMockRecorder) SearchPriceStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchPriceStatistics", reflect.TypeOf((*MockKptService)(nil).SearchPriceStatistics), arg0, arg1)
+}
+
+// SearchProcessAnalysis mocks base method.
+func (m *MockKptService) SearchProcessAnalysis(arg0 context.Context, arg1 *operationPb.ProcessAnalysisRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchProcessAnalysis", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchProcessAnalysis indicates an expected call of SearchProcessAnalysis.
+func (mr *MockKptServiceMockRecorder) SearchProcessAnalysis(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchProcessAnalysis", reflect.TypeOf((*MockKptService)(nil).SearchProcessAnalysis), arg0, arg1)
+}
+
+// SearchSprinkleStatistics mocks base method.
+func (m *MockKptService) SearchSprinkleStatistics(arg0 context.Context, arg1 *operationPb.SprinkleStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchSprinkleStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchSprinkleStatistics indicates an expected call of SearchSprinkleStatistics.
+func (mr *MockKptServiceMockRecorder) SearchSprinkleStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchSprinkleStatistics", reflect.TypeOf((*MockKptService)(nil).SearchSprinkleStatistics), arg0, arg1)
+}
+
 // SearchSystemMenuList mocks base method.
 func (m *MockKptService) SearchSystemMenuList(arg0 context.Context, arg1 *operationPb.SearchMenuRequest) (*operationPb.SearchMenuResponse, error) {
 	m.ctrl.T.Helper()
@@ -898,3 +1033,18 @@ func (mr *MockKptServiceMockRecorder) SearchSystemUserList(arg0, arg1 interface{
 	mr.mock.ctrl.T.Helper()
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchSystemUserList", reflect.TypeOf((*MockKptService)(nil).SearchSystemUserList), arg0, arg1)
 }
+
+// SearchUserMaterialsStatistics mocks base method.
+func (m *MockKptService) SearchUserMaterialsStatistics(arg0 context.Context, arg1 *operationPb.SearchUserMaterialsStatisticsRequest) (*model.PastureCommonResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SearchUserMaterialsStatistics", arg0, arg1)
+	ret0, _ := ret[0].(*model.PastureCommonResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SearchUserMaterialsStatistics indicates an expected call of SearchUserMaterialsStatistics.
+func (mr *MockKptServiceMockRecorder) SearchUserMaterialsStatistics(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchUserMaterialsStatistics", reflect.TypeOf((*MockKptService)(nil).SearchUserMaterialsStatistics), arg0, arg1)
+}

+ 51 - 9
module/backend/pasture_service.go

@@ -497,15 +497,19 @@ func (s *StoreEntry) ForageEnumList(ctx context.Context) *operationPb.ForageEnum
 		Code: http.StatusOK,
 		Msg:  "ok",
 		Data: &operationPb.ForageEnumList{
-			JumpDelaType:         make([]*operationPb.JumpDelaTypeEnum, 0),
-			ForageSource:         make([]*operationPb.ForageSourceEnum, 0),
-			ForagePlanType:       make([]*operationPb.ForagePlanTypeEnum, 0),
-			CattleParentCategory: make([]*operationPb.CattleParentCategoryEnum, 0),
-			ForageParentCategory: make([]*operationPb.ForageParentCategoryEnum, 0),
-			IsShow:               make([]*operationPb.IsShowEnum, 0),
-			FormulaType:          make([]*operationPb.FormulaTypeEnum, 0),
-			FormulaList:          make([]*operationPb.FormulaOptionEnum, 0),
-			ConfirmStart:         make([]*operationPb.IsShowEnum, 0),
+			JumpDelaType:          make([]*operationPb.JumpDelaTypeEnum, 0),
+			ForageSource:          make([]*operationPb.ForageSourceEnum, 0),
+			ForagePlanType:        make([]*operationPb.ForagePlanTypeEnum, 0),
+			CattleParentCategory:  make([]*operationPb.CattleParentCategoryEnum, 0),
+			ForageParentCategory:  make([]*operationPb.ForageParentCategoryEnum, 0),
+			IsShow:                make([]*operationPb.IsShowEnum, 0),
+			FormulaType:           make([]*operationPb.FormulaTypeEnum, 0),
+			FormulaList:           make([]*operationPb.FormulaOptionEnum, 0),
+			ConfirmStart:          make([]*operationPb.IsShowEnum, 0),
+			FormulationEvaluation: make([]*operationPb.FormulaOptionEnum, 0),
+			UseMaterialsType:      make([]*operationPb.FormulaOptionEnum, 0),
+			UseMaterialsList:      make([]*operationPb.FormulaOptionEnum, 0),
+			PriceMaterialsType:    make([]*operationPb.FormulaOptionEnum, 0),
 		},
 	}
 
@@ -588,6 +592,14 @@ func (s *StoreEntry) ForageEnumList(ctx context.Context) *operationPb.ForageEnum
 		Label: "否",
 	})
 
+	res.Data.FormulationEvaluation = append(res.Data.FormulationEvaluation, &operationPb.FormulaOptionEnum{
+		Value: 0,
+		Label: "按配方查询",
+	}, &operationPb.FormulaOptionEnum{
+		Value: 1,
+		Label: "按栏舍查询",
+	})
+
 	res.Data.FormulaType = append(res.Data.FormulaType, &operationPb.FormulaTypeEnum{
 		Value: operationPb.FormulaType_FEED_FORMULA,
 		Label: "饲喂配方",
@@ -607,6 +619,36 @@ func (s *StoreEntry) ForageEnumList(ctx context.Context) *operationPb.ForageEnum
 		Label: "禁用",
 	})
 
+	res.Data.UseMaterialsList = append(res.Data.UseMaterialsList, &operationPb.FormulaOptionEnum{
+		Value: 1,
+		Label: "理论",
+	}, &operationPb.FormulaOptionEnum{
+		Value: 2,
+		Label: "实际",
+	})
+
+	res.Data.UseMaterialsType = append(res.Data.UseMaterialsType, &operationPb.FormulaOptionEnum{
+		Value: 1,
+		Label: "畜牧类别",
+	}, &operationPb.FormulaOptionEnum{
+		Value: 2,
+		Label: "栏舍名称",
+	}, &operationPb.FormulaOptionEnum{
+		Value: 3,
+		Label: "日期",
+	}, &operationPb.FormulaOptionEnum{
+		Value: 4,
+		Label: "TMR设备号",
+	})
+
+	res.Data.PriceMaterialsType = append(res.Data.UseMaterialsType, &operationPb.FormulaOptionEnum{
+		Value: 5,
+		Label: "TMR班次",
+	}, &operationPb.FormulaOptionEnum{
+		Value: 6,
+		Label: "车次",
+	})
+
 	res.Data.FormulaList = append(res.Data.FormulaList, &operationPb.FormulaOptionEnum{
 		Value: 0,
 		Label: "所有",

+ 202 - 11
module/backend/statistic_service.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"go.uber.org/zap"
 	"kpt-tmr-group/model"
 	"kpt-tmr-group/pkg/logger/zaplog"
 	"kpt-tmr-group/pkg/xerr"
@@ -12,6 +11,8 @@ import (
 	"net/http"
 	"strconv"
 	"strings"
+
+	"go.uber.org/zap"
 )
 
 type PastureClientHandler func(ctx context.Context, pastureId int64, body interface{}) error
@@ -27,7 +28,7 @@ func (s *StoreEntry) PastureDetailById(ctx context.Context, pastureId int64) (*m
 	return result, nil
 }
 
-func (s *StoreEntry) PastureHttpClient(ctx context.Context, apiUrl string, pastureId int64, body interface{}, response interface{}) error {
+func (s *StoreEntry) PastureHttpClient(ctx context.Context, apiUrl string, pastureId int64, body, response interface{}) error {
 	pastureDetail, err := s.PastureDetailById(ctx, pastureId)
 	if err != nil {
 		zaplog.Error("SearchFormulaEstimateList", zap.Any("Err", err), zap.Int64("pastureId", pastureId))
@@ -42,6 +43,7 @@ func (s *StoreEntry) PastureHttpClient(ctx context.Context, apiUrl string, pastu
 		return xerr.WithStack(err)
 	}
 
+	zaplog.Info("PastureHttpClient", zap.String("url", url), zap.Any("request", body), zap.String("response", string(result)))
 	if err = json.Unmarshal(result, response); err != nil {
 		return xerr.WithStack(err)
 	}
@@ -58,13 +60,12 @@ func (s *StoreEntry) SearchFormulaEstimateList(ctx context.Context, req *operati
 		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps: &model.FormulaEstimateParams{
-			PastureId:     fmt.Sprintf("%d", req.PastureId),
-			StartTime:     req.StartTime,
-			StopTime:      req.EndTime,
-			InputDatetime: nil,
-			Search:        fmt.Sprintf("%d", req.SearchType),
-			TempletId:     fmt.Sprintf("%d", req.TemplateId),
-			Barid:         fmt.Sprintf("%d", req.BarnId),
+			PastureId: fmt.Sprintf("%d", req.PastureId),
+			StartTime: req.StartTime,
+			StopTime:  req.EndTime,
+			Search:    fmt.Sprintf("%d", req.SearchType),
+			TempletId: fmt.Sprintf("%d", req.TemplateId),
+			Barid:     fmt.Sprintf("%d", req.BarnId),
 		},
 	}
 	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
@@ -124,6 +125,28 @@ func (s *StoreEntry) SearchUserMaterialsStatistics(ctx context.Context, req *ope
 	return response, nil
 }
 
+// SearchPriceStatistics 库存管理-价格分析
+func (s *StoreEntry) SearchPriceStatistics(ctx context.Context, req *operationPb.SearchPriceStatisticsRequest) (*model.PastureCommonResponse, error) {
+	body := &model.PastureCommonRequest{
+		Name:       req.ApiName,
+		Page:       req.Pagination.Page,
+		Offset:     req.Pagination.PageOffset,
+		PageCount:  req.Pagination.PageSize,
+		ReturnType: "Map",
+		ParamMaps: &model.PriceStatisticsParams{
+			PastureId: fmt.Sprintf("%d", req.PastureId),
+			StartTime: req.StartTime,
+			StopTime:  req.EndTime,
+			FeedName:  req.FeedName,
+		},
+	}
+	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
+	if err := s.PastureHttpClient(ctx, model.UrlReportForm, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
 // SearchFeedStatistics 饲喂效率-效率统计
 func (s *StoreEntry) SearchFeedStatistics(ctx context.Context, req *operationPb.SearchFeedStatisticsRequest) (*model.PastureCommonResponse, error) {
 	body := &model.PastureCommonRequest{
@@ -136,7 +159,8 @@ func (s *StoreEntry) SearchFeedStatistics(ctx context.Context, req *operationPb.
 			PastureId: fmt.Sprintf("%d", req.PastureId),
 			StartTime: req.StartTime,
 			StopTime:  req.StartTime,
-			FeedName:  req.FormulaTemplate,
+			Date:      req.StartTime,
+			FeedTName: req.FormulaTemplate,
 			BarName:   req.BarnName,
 			CowClass:  req.CattleCategoryName,
 			Times:     fmt.Sprintf("%d", req.ClassNumber),
@@ -159,7 +183,7 @@ func (s *StoreEntry) FeedChartStatistics(ctx context.Context, req *operationPb.F
 			Status:    req.Status,
 		},
 	}
-	url, ok := model.FeedCharUrl[req.ApiType]
+	url, ok := model.UrlChart[req.ApiType]
 	if !ok {
 		return nil, xerr.Customf("错误的接口类型:%s", req.ApiType)
 	}
@@ -170,6 +194,173 @@ func (s *StoreEntry) FeedChartStatistics(ctx context.Context, req *operationPb.F
 	return response, nil
 }
 
+// CowsAnalysis 饲喂效率-牛群评估
+func (s *StoreEntry) CowsAnalysis(ctx context.Context, req *operationPb.CowsAnalysisRequest) (*model.PastureCommonResponse, error) {
+	body := &model.PastureCommonRequest{
+		Name:       req.ApiName,
+		Page:       req.Pagination.Page,
+		Offset:     req.Pagination.PageOffset,
+		PageCount:  req.Pagination.PageSize,
+		ReturnType: "Map",
+		ParamMaps: &model.MixFeedStatisticsParams{
+			PastureId: fmt.Sprintf("%d", req.PastureId),
+			StartTime: req.StartTime,
+			StopTime:  req.StartTime,
+		},
+	}
+	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
+	if err := s.PastureHttpClient(ctx, model.UrlDataByName, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+// SearchAccuracyAggStatistics 准确性分析-汇总分析
+func (s *StoreEntry) SearchAccuracyAggStatistics(ctx context.Context, req *operationPb.AccuracyAggStatisticsRequest) (*model.PastureCommonResponse, error) {
+	body := &model.FeedChartParams{
+		ParamMaps: &model.AccuracyAggParams{
+			PastureId: fmt.Sprintf("%d", req.PastureId),
+			StartTime: req.StartTime,
+			StopTime:  req.EndTime,
+			FName:     req.Fname,
+			Sort:      req.Sort,
+			Status:    req.Status,
+			Times:     req.Times,
+			Genre:     req.Genre,
+			IsDate:    req.Isdate,
+			Hlwc1:     req.Hlwc1,
+			Hlwc2:     req.Hlwc2,
+			Hlzq1:     req.Hlzq1,
+			Hlzq2:     req.Hlzq2,
+			Hlzql1:    req.Hlzql1,
+			Hlzql2:    req.Hlzql2,
+			Slwc1:     req.Slwc1,
+			Slwc2:     req.Slwc2,
+			Slzq1:     req.Slzq1,
+			Slzq2:     req.Slzq2,
+			Slzql1:    req.Slzql1,
+			Slzql2:    req.Slzql2,
+			Error:     req.IsError,
+		},
+	}
+	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
+	if err := s.PastureHttpClient(ctx, model.UrlSummary, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+// SearchMixFeedStatistics 准确性分析-混料统计
+func (s *StoreEntry) SearchMixFeedStatistics(ctx context.Context, req *operationPb.MixFeedStatisticsRequest) (*model.PastureCommonResponse, error) {
+	times := ""
+	if req.ClassNumber > 0 {
+		times = fmt.Sprintf("%d", req.ClassNumber)
+	}
+	body := &model.PastureCommonRequest{
+		Name:       req.ApiName,
+		Page:       req.Pagination.Page,
+		Offset:     req.Pagination.PageOffset,
+		PageCount:  req.Pagination.PageSize,
+		ReturnType: "Map",
+		ParamMaps: &model.MixFeedStatisticsParams{
+			PastureId:   fmt.Sprintf("%d", req.PastureId),
+			StartTime:   req.StartTime,
+			StopTime:    req.StartTime,
+			TmrTName:    req.EquipmentName,
+			ProjName:    req.TrainNumber,
+			Times:       times,
+			ButtonType:  req.ButtonType,
+			TempletName: req.FormulationName,
+			Isuse:       req.IsUse,
+			Hlwc1:       req.Hlwc1,
+			Hlwc2:       req.Hlwc2,
+			Hlzq1:       req.Hlzq1,
+			Hlzq2:       req.Hlzq2,
+			Hlzql1:      req.Hlzql1,
+			Hlzql2:      req.Hlzql2,
+			Error:       req.IsError,
+		},
+	}
+	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
+	if err := s.PastureHttpClient(ctx, model.UrlDataByName, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+// SearchSprinkleStatistics 准确性分析-撒料统计
+func (s *StoreEntry) SearchSprinkleStatistics(ctx context.Context, req *operationPb.SprinkleStatisticsRequest) (*model.PastureCommonResponse, error) {
+	times := ""
+	if req.ClassNumber > 0 {
+		times = fmt.Sprintf("%d", req.ClassNumber)
+	}
+	body := &model.PastureCommonRequest{
+		Name:       req.ApiName,
+		Page:       req.Pagination.Page,
+		Offset:     req.Pagination.PageOffset,
+		PageCount:  req.Pagination.PageSize,
+		ReturnType: "Map",
+		ParamMaps: &model.SprinkleStatisticsParams{
+			PastureId:   fmt.Sprintf("%d", req.PastureId),
+			StartTime:   req.StartTime,
+			StopTime:    req.StartTime,
+			TmrTName:    req.EquipmentName,
+			ProjName:    req.TrainNumber,
+			Times:       times,
+			ButtonType:  req.ButtonType,
+			TempletName: req.FormulationName,
+			Isuse:       req.IsUse,
+			Fname:       req.BarnName,
+			Slwc1:       req.Slwc1,
+			Slwc2:       req.Slwc2,
+			Slzq2:       req.Slzq2,
+			Slzq1:       req.Slzq1,
+			Slzql1:      req.Slzql1,
+			Slzql2:      req.Slzql2,
+			Error:       req.IsError,
+		},
+	}
+	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
+	if err := s.PastureHttpClient(ctx, model.UrlDataByName, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+// SearchProcessAnalysis 过程分析
+func (s *StoreEntry) SearchProcessAnalysis(ctx context.Context, req *operationPb.ProcessAnalysisRequest) (*model.PastureCommonResponse, error) {
+	body := &model.PastureCommonRequest{
+		Name:       req.ApiName,
+		Page:       req.Pagination.Page,
+		Offset:     req.Pagination.PageOffset,
+		PageCount:  req.Pagination.PageSize,
+		ReturnType: "Map",
+		ParamMaps: &model.ProcessAnalysisParams{
+			PastureId:   fmt.Sprintf("%d", req.PastureId),
+			StartTime:   req.StartTime,
+			StopTime:    req.StartTime,
+			TmrTName:    req.TmrName,
+			IsCompleted: "",
+			LpPlanType:  fmt.Sprintf("%d", req.PlanType),
+			FClassId:    req.MixFeedType,
+			Hlzq1:       req.Hlzq1,
+			Hlzq2:       req.Hlzq2,
+			Hlwc1:       req.Hlwc1,
+			Hlwc2:       req.Hlwc2,
+			Slwc1:       req.Slwc1,
+			Slwc2:       req.Slwc2,
+			Slzq2:       req.Slzq2,
+			Slzq1:       req.Slzq1,
+			Error:       req.ErrorRange,
+		},
+	}
+	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
+	if err := s.PastureHttpClient(ctx, model.UrlProcess, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
 func (s *StoreEntry) SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error) {
 
 	dataList := &model.CommonValueRatio{

+ 18 - 22
pkg/logger/zaplog/log.go

@@ -2,20 +2,19 @@ package zaplog
 
 import (
 	"fmt"
-	"kpt-tmr-group/pkg/tool"
 	"path"
 	"runtime"
-	"time"
-
-	"github.com/natefinch/lumberjack"
+	"strings"
 
+	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
 	"go.uber.org/zap"
 	"go.uber.org/zap/zapcore"
 )
 
 var (
-	Logger      *zap.Logger
-	logFileName = fmt.Sprintf("./logger/zap-%s.log", time.Now().Format(tool.DateTime))
+	Logger          *zap.Logger
+	logInfoFileName = fmt.Sprintf("./logger/zap-info.log")
+	logErrFileName  = fmt.Sprintf("./logger/zap-err.log")
 )
 
 func init() {
@@ -26,25 +25,28 @@ func init() {
 	encoder := zapcore.NewJSONEncoder(encoderConfig)
 
 	// topicErrors := zapcore.AddSync(ioutil.Discard)  //kafka topic
-
-	fileWriteSyncer := getFileLogWriter(logFileName)
+	fileInfoWriteSyncer := getFileLogWriter(logInfoFileName)
+	fileErrWriteSyncer := getFileLogWriter(logErrFileName)
 	core := zapcore.NewTee(
 		// zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),  // 打印到控制台
 		// zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), topicErrors, zapcore.ErrorLevel),   // 打印到kafka 待验证
-		zapcore.NewCore(encoder, fileWriteSyncer, zapcore.DebugLevel), // 打印到指定的日志文件
+		zapcore.NewCore(encoder, fileInfoWriteSyncer, zapcore.InfoLevel), // 打印到指定的日志文件
+		zapcore.NewCore(encoder, fileErrWriteSyncer, zapcore.ErrorLevel), // 打印到指定的日志文件
 	)
 	Logger = zap.New(core)
 }
 
 func getFileLogWriter(logFileName string) zapcore.WriteSyncer {
-	lumberJackLogger := &lumberjack.Logger{
-		Filename:   logFileName,
-		MaxSize:    100, // 单个文件最大100M
-		MaxBackups: 10,  // 大于60个日志文件后,清理比较旧的日志文件
-		MaxAge:     1,   // 一天切割1次
-		Compress:   false,
+	lumberRotateLogs, err := rotatelogs.New(
+		strings.Replace(logFileName, ".log", "", -1)+"-%Y%m%d.log",
+		rotatelogs.WithLinkName(logFileName),
+		rotatelogs.WithRotationCount(2),        // 2天的日志
+		rotatelogs.WithRotationSize(210000000), // 一个文件200MB
+	)
+	if err != nil {
+		panic(err)
 	}
-	return zapcore.AddSync(lumberJackLogger)
+	return zapcore.AddSync(lumberRotateLogs)
 }
 
 func getCallerInfoForLog() (callerFields []zap.Field) {
@@ -76,9 +78,3 @@ func Error(message string, fields ...zap.Field) {
 	fields = append(fields, callerFields...)
 	Logger.Error(message, fields...)
 }
-
-func Warn(message string, fields ...zap.Field) {
-	callerFields := getCallerInfoForLog()
-	fields = append(fields, callerFields...)
-	Logger.Warn(message, fields...)
-}

+ 131 - 73
proto/go/backend/operation/pasture.pb.go

@@ -1803,15 +1803,19 @@ type ForageEnumList struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	ForageSource         []*ForageSourceEnum         `protobuf:"bytes,1,rep,name=forage_source,json=forageSource,proto3" json:"forage_source,omitempty"`
-	ForagePlanType       []*ForagePlanTypeEnum       `protobuf:"bytes,2,rep,name=forage_plan_type,json=foragePlanType,proto3" json:"forage_plan_type,omitempty"`
-	JumpDelaType         []*JumpDelaTypeEnum         `protobuf:"bytes,3,rep,name=jump_dela_type,json=jumpDelaType,proto3" json:"jump_dela_type,omitempty"`
-	CattleParentCategory []*CattleParentCategoryEnum `protobuf:"bytes,4,rep,name=cattle_parent_category,json=cattleParentCategory,proto3" json:"cattle_parent_category,omitempty"`
-	ForageParentCategory []*ForageParentCategoryEnum `protobuf:"bytes,5,rep,name=forage_parent_category,json=forageParentCategory,proto3" json:"forage_parent_category,omitempty"`
-	IsShow               []*IsShowEnum               `protobuf:"bytes,6,rep,name=is_show,json=isShow,proto3" json:"is_show,omitempty"`
-	FormulaType          []*FormulaTypeEnum          `protobuf:"bytes,7,rep,name=formula_type,json=formulaType,proto3" json:"formula_type,omitempty"`
-	FormulaList          []*FormulaOptionEnum        `protobuf:"bytes,8,rep,name=formula_list,json=formulaList,proto3" json:"formula_list,omitempty"`
-	ConfirmStart         []*IsShowEnum               `protobuf:"bytes,9,rep,name=confirm_start,json=confirmStart,proto3" json:"confirm_start,omitempty"`
+	ForageSource          []*ForageSourceEnum         `protobuf:"bytes,1,rep,name=forage_source,json=forageSource,proto3" json:"forage_source,omitempty"`                           // 饲料来源
+	ForagePlanType        []*ForagePlanTypeEnum       `protobuf:"bytes,2,rep,name=forage_plan_type,json=foragePlanType,proto3" json:"forage_plan_type,omitempty"`                   // 饲料计划类型
+	JumpDelaType          []*JumpDelaTypeEnum         `protobuf:"bytes,3,rep,name=jump_dela_type,json=jumpDelaType,proto3" json:"jump_dela_type,omitempty"`                         // 跳转延迟类型
+	CattleParentCategory  []*CattleParentCategoryEnum `protobuf:"bytes,4,rep,name=cattle_parent_category,json=cattleParentCategory,proto3" json:"cattle_parent_category,omitempty"` // 畜牧分类
+	ForageParentCategory  []*ForageParentCategoryEnum `protobuf:"bytes,5,rep,name=forage_parent_category,json=forageParentCategory,proto3" json:"forage_parent_category,omitempty"` // 饲料分类
+	IsShow                []*IsShowEnum               `protobuf:"bytes,6,rep,name=is_show,json=isShow,proto3" json:"is_show,omitempty"`
+	FormulaType           []*FormulaTypeEnum          `protobuf:"bytes,7,rep,name=formula_type,json=formulaType,proto3" json:"formula_type,omitempty"`                                // 配方类型
+	FormulaList           []*FormulaOptionEnum        `protobuf:"bytes,8,rep,name=formula_list,json=formulaList,proto3" json:"formula_list,omitempty"`                                // 所有配方列表
+	ConfirmStart          []*IsShowEnum               `protobuf:"bytes,9,rep,name=confirm_start,json=confirmStart,proto3" json:"confirm_start,omitempty"`                             // 确认开始
+	FormulationEvaluation []*FormulaOptionEnum        `protobuf:"bytes,10,rep,name=formulation_evaluation,json=formulationEvaluation,proto3" json:"formulation_evaluation,omitempty"` // 配方评估查询方式
+	UseMaterialsList      []*FormulaOptionEnum        `protobuf:"bytes,11,rep,name=use_materials_list,json=useMaterialsList,proto3" json:"use_materials_list,omitempty"`              // 用料分析-列表显示
+	UseMaterialsType      []*FormulaOptionEnum        `protobuf:"bytes,12,rep,name=use_materials_type,json=useMaterialsType,proto3" json:"use_materials_type,omitempty"`              // 用料分析-统计类型
+	PriceMaterialsType    []*FormulaOptionEnum        `protobuf:"bytes,13,rep,name=price_materials_type,json=priceMaterialsType,proto3" json:"price_materials_type,omitempty"`        // 价格分析-统计类型
 }
 
 func (x *ForageEnumList) Reset() {
@@ -1909,6 +1913,34 @@ func (x *ForageEnumList) GetConfirmStart() []*IsShowEnum {
 	return nil
 }
 
+func (x *ForageEnumList) GetFormulationEvaluation() []*FormulaOptionEnum {
+	if x != nil {
+		return x.FormulationEvaluation
+	}
+	return nil
+}
+
+func (x *ForageEnumList) GetUseMaterialsList() []*FormulaOptionEnum {
+	if x != nil {
+		return x.UseMaterialsList
+	}
+	return nil
+}
+
+func (x *ForageEnumList) GetUseMaterialsType() []*FormulaOptionEnum {
+	if x != nil {
+		return x.UseMaterialsType
+	}
+	return nil
+}
+
+func (x *ForageEnumList) GetPriceMaterialsType() []*FormulaOptionEnum {
+	if x != nil {
+		return x.PriceMaterialsType
+	}
+	return nil
+}
+
 type ForageSourceEnum struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -2664,7 +2696,7 @@ var file_backend_operation_pasture_proto_rawDesc = []byte{
 	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, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52,
-	0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xc8, 0x05, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65,
+	0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa5, 0x08, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65,
 	0x45, 0x6e, 0x75, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x48, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x61,
 	0x67, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
 	0x23, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,
@@ -2709,58 +2741,80 @@ var file_backend_operation_pasture_proto_rawDesc = []byte{
 	0x03, 0x28, 0x0b, 0x32, 0x1d, 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, 0x45, 0x6e,
 	0x75, 0x6d, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x72, 0x74,
-	0x22, 0x64, 0x0a, 0x10, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x45, 0x6e, 0x75, 0x6d, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70,
-	0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x6f,
-	0x75, 0x72, 0x63, 0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x68, 0x0a, 0x12, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65,
-	0x50, 0x6c, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x3c, 0x0a, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x62, 0x61,
-	0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
-	0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4b,
-	0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61,
-	0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c,
-	0x22, 0x64, 0x0a, 0x10, 0x4a, 0x75, 0x6d, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x54, 0x79, 0x70, 0x65,
-	0x45, 0x6e, 0x75, 0x6d, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70,
-	0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4a, 0x75, 0x6d, 0x70, 0x44, 0x65, 0x6c, 0x61,
-	0x54, 0x79, 0x70, 0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x74, 0x0a, 0x18, 0x43, 0x61, 0x74, 0x74, 0x6c, 0x65,
-	0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x45, 0x6e,
-	0x75, 0x6d, 0x12, 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x2c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x61, 0x74, 0x65,
-	0x67, 0x6f, 0x72, 0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52,
-	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x74, 0x0a, 0x18,
-	0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x74, 0x65,
-	0x67, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e,
-	0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x6f, 0x72, 0x61,
-	0x67, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74,
-	0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05,
-	0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62,
-	0x65, 0x6c, 0x22, 0x58, 0x0a, 0x0a, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x45, 0x6e, 0x75, 0x6d,
-	0x12, 0x34, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 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,
-	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x62, 0x0a, 0x0f,
-	0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12,
-	0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23,
+	0x12, 0x5b, 0x0a, 0x16, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
+	0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 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, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4f, 0x70, 0x74, 0x69,
+	0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x15, 0x66, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a,
+	0x12, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x6c,
+	0x69, 0x73, 0x74, 0x18, 0x0b, 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, 0x46, 0x6f,
+	0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x52,
+	0x10, 0x75, 0x73, 0x65, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x4c, 0x69, 0x73,
+	0x74, 0x12, 0x52, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
+	0x6c, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 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, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45,
+	0x6e, 0x75, 0x6d, 0x52, 0x10, 0x75, 0x73, 0x65, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c,
+	0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x56, 0x0a, 0x14, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6d,
+	0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 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, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4f,
+	0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x12, 0x70, 0x72, 0x69, 0x63, 0x65,
+	0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x54, 0x79, 0x70, 0x65, 0x22, 0x64, 0x0a,
+	0x10, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x6e, 0x75,
+	0x6d, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61,
+	0x62, 0x65, 0x6c, 0x22, 0x68, 0x0a, 0x12, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x6c, 0x61,
+	0x6e, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x3c, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65,
+	0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x6f, 0x72,
+	0x61, 0x67, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x64, 0x0a,
+	0x10, 0x4a, 0x75, 0x6d, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75,
+	0x6d, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x24, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4a, 0x75, 0x6d, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x54, 0x79, 0x70,
+	0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a,
+	0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61,
+	0x62, 0x65, 0x6c, 0x22, 0x74, 0x0a, 0x18, 0x43, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x50, 0x61, 0x72,
+	0x65, 0x6e, 0x74, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x45, 0x6e, 0x75, 0x6d, 0x12,
+	0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c,
 	0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x2e, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4b,
-	0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61,
-	0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c,
-	0x22, 0x3f, 0x0a, 0x11, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c,
-	0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65,
-	0x6c, 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,
+	0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72,
+	0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x05, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x74, 0x0a, 0x18, 0x46, 0x6f, 0x72,
+	0x61, 0x67, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72,
+	0x79, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x42, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f,
+	0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43,
+	0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x4b, 0x69,
+	0x6e, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62,
+	0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22,
+	0x58, 0x0a, 0x0a, 0x49, 0x73, 0x53, 0x68, 0x6f, 0x77, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x34, 0x0a,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 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, 0x05, 0x76, 0x61,
+	0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x62, 0x0a, 0x0f, 0x46, 0x6f, 0x72,
+	0x6d, 0x75, 0x6c, 0x61, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x39, 0x0a, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x62, 0x61,
+	0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
+	0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4b, 0x69, 0x6e, 0x64,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x22, 0x3f, 0x0a,
+	0x11, 0x46, 0x6f, 0x72, 0x6d, 0x75, 0x6c, 0x61, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e,
+	0x75, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65,
+	0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 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 (
@@ -2859,18 +2913,22 @@ var file_backend_operation_pasture_proto_depIdxs = []int32{
 	29, // 38: backend.operation.ForageEnumList.formula_type:type_name -> backend.operation.FormulaTypeEnum
 	30, // 39: backend.operation.ForageEnumList.formula_list:type_name -> backend.operation.FormulaOptionEnum
 	28, // 40: backend.operation.ForageEnumList.confirm_start:type_name -> backend.operation.IsShowEnum
-	35, // 41: backend.operation.ForageSourceEnum.value:type_name -> backend.operation.ForageSource.Kind
-	36, // 42: backend.operation.ForagePlanTypeEnum.value:type_name -> backend.operation.ForagePlanType.Kind
-	37, // 43: backend.operation.JumpDelaTypeEnum.value:type_name -> backend.operation.JumpDelaType.Kind
-	33, // 44: backend.operation.CattleParentCategoryEnum.value:type_name -> backend.operation.CattleCategoryParent.Kind
-	34, // 45: backend.operation.ForageParentCategoryEnum.value:type_name -> backend.operation.ForageCategoryParent.Kind
-	31, // 46: backend.operation.IsShowEnum.value:type_name -> backend.operation.IsShow.Kind
-	38, // 47: backend.operation.FormulaTypeEnum.value:type_name -> backend.operation.FormulaType.Kind
-	48, // [48:48] is the sub-list for method output_type
-	48, // [48:48] is the sub-list for method input_type
-	48, // [48:48] is the sub-list for extension type_name
-	48, // [48:48] is the sub-list for extension extendee
-	0,  // [0:48] is the sub-list for field type_name
+	30, // 41: backend.operation.ForageEnumList.formulation_evaluation:type_name -> backend.operation.FormulaOptionEnum
+	30, // 42: backend.operation.ForageEnumList.use_materials_list:type_name -> backend.operation.FormulaOptionEnum
+	30, // 43: backend.operation.ForageEnumList.use_materials_type:type_name -> backend.operation.FormulaOptionEnum
+	30, // 44: backend.operation.ForageEnumList.price_materials_type:type_name -> backend.operation.FormulaOptionEnum
+	35, // 45: backend.operation.ForageSourceEnum.value:type_name -> backend.operation.ForageSource.Kind
+	36, // 46: backend.operation.ForagePlanTypeEnum.value:type_name -> backend.operation.ForagePlanType.Kind
+	37, // 47: backend.operation.JumpDelaTypeEnum.value:type_name -> backend.operation.JumpDelaType.Kind
+	33, // 48: backend.operation.CattleParentCategoryEnum.value:type_name -> backend.operation.CattleCategoryParent.Kind
+	34, // 49: backend.operation.ForageParentCategoryEnum.value:type_name -> backend.operation.ForageCategoryParent.Kind
+	31, // 50: backend.operation.IsShowEnum.value:type_name -> backend.operation.IsShow.Kind
+	38, // 51: backend.operation.FormulaTypeEnum.value:type_name -> backend.operation.FormulaType.Kind
+	52, // [52:52] is the sub-list for method output_type
+	52, // [52:52] is the sub-list for method input_type
+	52, // [52:52] is the sub-list for extension type_name
+	52, // [52:52] is the sub-list for extension extendee
+	0,  // [0:52] is the sub-list for field type_name
 }
 
 func init() { file_backend_operation_pasture_proto_init() }

Разница между файлами не показана из-за своего большого размера
+ 988 - 18
proto/go/backend/operation/statistic.pb.go


Некоторые файлы не были показаны из-за большого количества измененных файлов