Эх сурвалжийг харах

Merge branch 'release/v1.0.2' of xuyiping/kpt-tmr-group into develop

xuyiping 1 жил өмнө
parent
commit
240a5adfcd

+ 89 - 12
.drone.yml

@@ -1,16 +1,8 @@
 kind: pipeline
 type: docker
-name: kptTmrGroup
+name: test
 
-clone:
-  depth: 1
-  disable: true
 steps:
-  - name: clone
-    image: alpine/git
-    commands:
-      - git clone -b develop http://192.168.1.8:3000/xuyiping/kpt-tmr-group.git
-      - cp -R kpt-tmr-group/* ./
   - name: build
     image: plugins/docker:20.14.2
     volumes:
@@ -28,16 +20,101 @@ steps:
         from_secret: aliyuncs_password
       repo: registry.cn-hangzhou.aliyuncs.com/kpt-event/kpt-tmr-group
       registry: registry.cn-hangzhou.aliyuncs.com
-      tags: [ 1.0.3,latest ]
-
+      tags: [ test ]
+  - name: ssh commands
+    image: appleboy/drone-ssh
+    settings:
+      host: 192.168.1.70
+      username: tmrwatch
+      password:
+        from_secret: ssh_password
+      port: 22
+      script:
+        - cd /data/docker-compose/kpt-tmr-group/
+        - echo "123456" | ./restart.sh
 trigger:
   branch:
     include:
-    - develop
+    - feature/*
   event:
     include:
     - push
+volumes:
+  - name: docker-ca
+    host:
+      path: /etc/docker
+  - name: docker-sock
+    host:
+      path: /var/run/docker.sock
+---
+kind: pipeline
+type: docker
+name: product
+steps:
+  - name: build
+    image: plugins/docker:20.14.2
+    volumes:
+      - name: hosts
+        path: /etc/hosts
+      - name: docker-ca
+        path: /etc/docker
+      - name: docker-sock
+        path: /var/run/docker.sock
+    settings:
+      username:
+        from_secret: aliyuncs_username
+      password:
+        from_secret: aliyuncs_password
+      repo: registry.cn-hangzhou.aliyuncs.com/kpt-event/kpt-tmr-group
+      registry: registry.cn-hangzhou.aliyuncs.com
+      tag:
+        - latest
+        - ${DRONE_BRANCH##release/}
+trigger:
+  branch:
+    include:
+      - release/*
+  event:
+    include:
+      - push
+volumes:
+  - name: docker-ca
+    host:
+      path: /etc/docker
+  - name: docker-sock
+    host:
+      path: /var/run/docker.sock
+---
+kind: pipeline
+type: docker
+name: fix
 
+steps:
+  - name: build
+    image: plugins/docker:20.14.2
+    volumes:
+      - name: hosts
+        path: /etc/hosts
+      - name: docker-ca
+        path: /etc/docker
+      - name: docker-sock
+        path: /var/run/docker.sock
+    settings:
+      username:
+        from_secret: aliyuncs_username
+      password:
+        from_secret: aliyuncs_password
+      repo: registry.cn-hangzhou.aliyuncs.com/kpt-event/kpt-tmr-group
+      registry: registry.cn-hangzhou.aliyuncs.com
+      tag:
+        - latest
+trigger:
+  branch:
+    include:
+      - fix/*
+  event:
+    include:
+      - push
 volumes:
   - name: docker-ca
     host:

+ 3 - 2
go.mod

@@ -3,7 +3,7 @@ module kpt-tmr-group
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20230823061528-20b02d357f02
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20231129062310-bbb6722ac3a0
 	gitee.com/xuyiping_admin/pkg v0.0.0-20230822102440-0e489dd5d75a
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/getsentry/sentry-go v0.23.0
@@ -24,7 +24,6 @@ require (
 	go.uber.org/multierr v1.8.0
 	go.uber.org/zap v1.24.0
 	golang.org/x/sync v0.2.0
-	google.golang.org/protobuf v1.31.0
 	gorm.io/driver/mysql v1.5.1
 	gorm.io/gorm v1.25.2
 )
@@ -62,6 +61,7 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
 	github.com/pelletier/go-toml/v2 v2.0.8 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
@@ -89,6 +89,7 @@ require (
 	golang.org/x/text v0.9.0 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf // indirect
 	google.golang.org/grpc v1.57.0 // indirect
+	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

+ 8 - 12
go.sum

@@ -36,18 +36,12 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
 cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 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=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230822100450-307557aa568a h1:77YHuhzd5gGnNNcEahlUWNbA+QheErdLcENBFMbX8eI=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230822100450-307557aa568a/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823052817-08ac6a117982 h1:uUPyJacoMHIui/loBHus6GO2V/WV5I0dxEEYNnPLWpw=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823052817-08ac6a117982/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823054003-157f033bf025 h1:en1mDyAroXF+oD7zhtjXur+iinoRpOS8+MAP8wS/thQ=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823054003-157f033bf025/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823054257-de7a8cf59bb4 h1:9HPV7SqlxCgRKVdbF9AXubhLHgx4z93otF3pN5CUljo=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823054257-de7a8cf59bb4/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823060841-fecf079818d5 h1:5wvuR14mVWu7kEYMwTYwVksjLfoDomYbSfhfLNHIYEo=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823060841-fecf079818d5/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823061528-20b02d357f02 h1:e4BzweXQdP/RdWBeqk1sshUuxBI/jcLUCNDtv/G1mXg=
-gitee.com/xuyiping_admin/go_proto v0.0.0-20230823061528-20b02d357f02/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20231116060440-d644eee73ee6 h1:+Lah4VWetGE6dzqmOusq3212dCrVLumib9xscB85mP0=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20231116060440-d644eee73ee6/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20231116063239-b531a3099bd3 h1:JN21X8a0RJN1PBMnliQldz4YpO63IogaSVGonXo8dYw=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20231116063239-b531a3099bd3/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20231129062310-bbb6722ac3a0 h1:j/zcYZroC7tAhPSNrxgwsTkhYkn4DdjDb8ShNBcVEbw=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20231129062310-bbb6722ac3a0/go.mod h1:x47UOU+lOkZnrtAENAsOGd7mZ5I8D2JRkMKMqLLRlVw=
 gitee.com/xuyiping_admin/pkg v0.0.0-20230822102440-0e489dd5d75a h1:+SSGto+q5BKy6r9FLFQXooTNqZs4tALceFpoo2jef8w=
 gitee.com/xuyiping_admin/pkg v0.0.0-20230822102440-0e489dd5d75a/go.mod h1:vK5K2LnhWZnvZlEY9gmT6GFdq/5Y0mtxuKLNJHFJkE4=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -268,6 +262,8 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
 github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
 github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
 github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=

+ 69 - 3
http/handler/statistic/analysis.go

@@ -2,13 +2,14 @@ package statistic
 
 import (
 	"fmt"
+	"kpt-tmr-group/http/middleware"
+	"net/http"
+	"time"
+
 	operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
 	"gitee.com/xuyiping_admin/pkg/apierr"
 	"gitee.com/xuyiping_admin/pkg/ginutil"
 	"gitee.com/xuyiping_admin/pkg/valid"
-	"kpt-tmr-group/http/middleware"
-	"net/http"
-	"time"
 
 	"github.com/gin-gonic/gin"
 )
@@ -544,3 +545,68 @@ func FeedMixedAndTmrName(c *gin.Context) {
 	}
 	c.JSON(http.StatusOK, res)
 }
+
+// FeedTemplateHistory 配方修改记录
+func FeedTemplateHistory(c *gin.Context) {
+	var req operationPb.FeedTemplateHistoryRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+	res, err := middleware.BackendOperation(c).OpsService.FeedTemplateHistory(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
+// BarnHistory 栏色修改纪录
+func BarnHistory(c *gin.Context) {
+	var req operationPb.BarnHistoryRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.BarnName, valid.Required, valid.Length(1, 100)),
+		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.BarnHistory(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}
+
+// SpillageAllHistory 车次重量
+func SpillageAllHistory(c *gin.Context) {
+	var req operationPb.BarnHistoryRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.BarnName, valid.Required, valid.Length(1, 100)),
+		valid.Field(&req.StartTime, valid.Required),
+		valid.Field(&req.EndTime, valid.Required),
+		valid.Field(&req.PastureId, valid.Required),
+	); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	res, err := middleware.BackendOperation(c).OpsService.SpillageAllHistory(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
+}

+ 6 - 5
http/handler/system/user.go

@@ -1,13 +1,14 @@
 package system
 
 import (
+	"kpt-tmr-group/http/middleware"
+	"net/http"
+	"strconv"
+
 	operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
 	"gitee.com/xuyiping_admin/pkg/apierr"
 	"gitee.com/xuyiping_admin/pkg/ginutil"
 	"gitee.com/xuyiping_admin/pkg/valid"
-	"kpt-tmr-group/http/middleware"
-	"net/http"
-	"strconv"
 
 	"github.com/gin-gonic/gin"
 )
@@ -109,7 +110,7 @@ func GetUserInfo(c *gin.Context) {
 		return
 	}
 
-	res, err := middleware.BackendOperation(c).OpsService.GetUserInfo(c, token)
+	res, err := middleware.BackendOperation(c).OpsService.GetUserInfo(c)
 	if err != nil {
 		apierr.ClassifiedAbort(c, err)
 		return
@@ -234,7 +235,7 @@ func GetSystemUserPermissions(c *gin.Context) {
 		return
 	}
 
-	res, err := middleware.BackendOperation(c).OpsService.GetSystemUserPermissions(c, token)
+	res, err := middleware.BackendOperation(c).OpsService.GetSystemUserPermissions(c)
 	if err != nil {
 		apierr.ClassifiedAbort(c, err)
 		return

+ 5 - 1
http/route/ops_api.go

@@ -89,11 +89,15 @@ func OpsAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		opsRoute.POST("/accuracy/agg_statistics", statistic.SearchAccuracyAggStatistics)
 		opsRoute.POST("/accuracy/mixed_statistics", statistic.SearchMixFeedStatistics)
 		opsRoute.POST("/accuracy/sprinkle_statistics", statistic.SearchSprinkleStatistics)
-		opsRoute.POST("/accuracy/data_by_name", statistic.GetDataByName)
+
 		opsRoute.POST("/process/analysis", statistic.SearchProcessAnalysis)
 		opsRoute.POST("/process/analysis/mixed_sprinkle_detail", statistic.AnalysisMixedSprinkleDetail)
 		opsRoute.POST("/statistics/train_number", statistic.TrainNumber)
 		opsRoute.POST("/statistics/mixed_category_tmr_name", statistic.FeedMixedAndTmrName)
+		opsRoute.POST("/feed_template/history", statistic.FeedTemplateHistory)
+		opsRoute.POST("/barn/history", statistic.BarnHistory)
+		opsRoute.POST("/spillage_all/history", statistic.SpillageAllHistory)
+		opsRoute.POST("/accuracy/data_by_name", statistic.GetDataByName)
 
 		// 首页仪表盘
 		opsRoute.POST("/dashboard/accuracy", dashboard.AnalysisAccuracy)

+ 35 - 0
model/analysis_accuracy.go

@@ -27,6 +27,33 @@ func (c *AnalysisAccuracy) TableName() string {
 	return "analysis_accuracy"
 }
 
+type SearchAnalysisAccuracyResponse1 struct {
+	Code int32                  `json:"code"`
+	Msg  string                 `json:"msg"`
+	Data *AnalysisAccuracyData1 `json:"data"`
+}
+
+type AnalysisAccuracyData1 struct {
+	Table *Table  `json:"table"`
+	Chart *Chart1 `json:"chart"`
+}
+
+type Chart1 struct {
+	MixedFodderAccurateRatio    *PastureTopData1 `json:"mixed_fodder_accurate_ratio"`
+	MixedFodderCorrectRatio     *PastureTopData1 `json:"mixed_fodder_correct_ratio"`
+	SprinkleFodderAccurateRatio *PastureTopData1 `json:"sprinkle_fodder_accurate_ratio"`
+	SprinkleFodderCorrectRatio  *PastureTopData1 `json:"sprinkle_fodder_correct_ratio"`
+}
+
+type PastureTopData1 struct {
+	MaxValue    string    `json:"max_value"`    // 最高值
+	MiddleValue string    `json:"middle_value"` // 中位值
+	MinValue    string    `json:"min_value"`    // 最低值
+	TopOneName  string    `json:"top_one_name"` // 最高值牧场名称
+	Title       []string  `json:"title"`
+	Ratio       []float64 `json:"ratio"`
+}
+
 type SearchAnalysisAccuracyResponse struct {
 	Code int32                 `json:"code"`
 	Msg  string                `json:"msg"`
@@ -87,6 +114,7 @@ type PastureTop struct {
 }
 
 type PastureTopData struct {
+	PastureId   int64   `json:"pasture_id"`
 	PastureName string  `json:"pasture_name"`
 	Ratio       float64 `json:"ratio"`
 }
@@ -165,3 +193,10 @@ type SprinkleStatisticsDataList struct {
 	ProcessTime string `json:"process_time"`
 	Times       int32  `json:"times"`
 }
+
+type PastureDayTimeRatio struct {
+	PastureId   int64   `json:"pasture_id"`
+	PastureName string  `json:"pasture_name"`
+	DayTime     string  `json:"day_time"`
+	Ratio       float64 `json:"ratio"`
+}

+ 41 - 2
model/formula_estimate.go

@@ -2,6 +2,7 @@ package model
 
 import (
 	"fmt"
+
 	operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
 )
 
@@ -242,13 +243,21 @@ type ProcessAnalysisParams struct {
 }
 
 func NewProcessAnalysisParams(pastureId int64, req *operationPb.ProcessAnalysisRequest) *ProcessAnalysisParams {
+	if req.TmrName == nil {
+		req.TmrName = make([]string, 0)
+	}
+
+	lpPlanType := ""
+	if req.PlanType > 0 {
+		lpPlanType = fmt.Sprintf("%d", req.PlanType)
+	}
 	return &ProcessAnalysisParams{
 		PastureId:   fmt.Sprintf("%d", pastureId),
 		StartTime:   req.StartTime,
-		StopTime:    req.StartTime,
+		StopTime:    req.EndTime,
 		TmrTName:    req.TmrName,
 		IsCompleted: "",
-		LpPlanType:  fmt.Sprintf("%d", req.PlanType),
+		LpPlanType:  lpPlanType,
 		FClassId:    req.MixFeedType,
 		Hlzq1:       req.Hlzq1,
 		Hlzq2:       req.Hlzq2,
@@ -331,6 +340,10 @@ type GetDataByNameParams struct {
 	PastureId string `json:"pastureid"`
 	StartTime string `json:"startTime"`
 	StopTime  string `json:"stopTime"`
+	Pid       string `json:"pid"`
+	Optdevice string `json:"optdevice,omitempty"`
+	FtId      int32  `json:"ftid,omitempty"`
+	Name      string `json:"name,omitempty"`
 }
 
 type FeedStatisticsResponse struct {
@@ -385,3 +398,29 @@ func NewMixedSprinkleDetailRequest(pastureId int64, req *operationPb.ProcessMixe
 		Id:        req.Id,
 	}
 }
+
+type PastureFeedTemplateHistoryRequest struct {
+	PastureId string `json:"pastureid"`
+	FTid      int64  `json:"ftid"`
+	StartDate string `json:"startdate"`
+	EndDate   string `json:"enddate"`
+}
+
+type PastureFeedTemplateHistoryResponse struct {
+	Code int32       `json:"code"`
+	Msg  string      `json:"msg"`
+	Data interface{} `json:"data"`
+}
+
+type PastureBarnHistoryRequest struct {
+	PastureId string `json:"pastureid,omitempty"`
+	BarName   string `json:"barname"`
+	StartDate string `json:"startDate"`
+	EndDate   string `json:"endDate"`
+}
+
+type PastureBarnHistoryResponse struct {
+	Code int32       `json:"code"`
+	Msg  string      `json:"msg"`
+	Data interface{} `json:"data"`
+}

+ 9 - 6
model/group_pasture.go

@@ -18,11 +18,14 @@ import (
 )
 
 const (
-	InitManagerPassword = "123456"
-	UrlDataByName       = "authdata/GetDataByName"
-	UrlReportForm       = "authdata/GetReportform"
-	UrlSummary          = "authdata/summary"
-	UrlProcess          = "authdata/processAnalysist"
+	InitManagerPassword    = "123456"
+	UrlDataByName          = "authdata/GetDataByName"
+	UrlReportForm          = "authdata/GetReportform"
+	UrlSummary             = "authdata/summary"
+	UrlProcess             = "authdata/processAnalysist"
+	UrlFeedTemplateHistory = "authdata/feedtemplet/history"
+	UrlBarnHistory         = "authdata/feedp/history"
+	UrlSpillageAllHistory  = "authdata/spillageall/history"
 )
 
 const (
@@ -134,7 +137,7 @@ func NewPastureClient(g *GroupPasture) *PastureClient {
 	return &PastureClient{
 		Detail: g,
 		authClient: &http.Client{
-			Timeout: time.Duration(10) * time.Second,
+			Timeout: time.Duration(5) * time.Second,
 		},
 	}
 }

+ 0 - 1
model/pasture_data.go

@@ -36,7 +36,6 @@ type PastureAnalysisAccuracyResponse struct {
 	Msg  string                       `json:"msg"`
 	Data *PastureAnalysisAccuracyData `json:"data"`
 }
-
 type PastureAnalysisAccuracyData struct {
 	MixedFodderAccurateRatio    []*PastureAnalysisAccuracyDataValue `json:"mixed_fodder_accurate_ratio"`    // 混料准确率
 	MixedFodderCorrectRatio     []*PastureAnalysisAccuracyDataValue `json:"mixed_fodder_correct_ratio"`     // 混料正确率

+ 249 - 146
module/backend/dashboard_service.go

@@ -19,7 +19,9 @@ import (
 	"go.uber.org/zap"
 )
 
-const compareTime = 10 * 60
+const (
+	compareTime = 10 * 60
+)
 
 // PasturePrefAnalysisData  PasturePrefExecTimeData PastureSprinkleFeedTime TODO  后期三个函数封装一下
 func (s *StoreEntry) PasturePrefAnalysisData(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (map[int64]*model.PastureAnalysisAccuracyData, error) {
@@ -67,7 +69,6 @@ func (s *StoreEntry) PasturePrefAnalysisData(ctx context.Context, req *operation
 				return
 			}
 			res[groupPasture.Id] = response.Data
-
 		}(pastureId)
 	}
 	wg.Wait()
@@ -75,7 +76,6 @@ func (s *StoreEntry) PasturePrefAnalysisData(ctx context.Context, req *operation
 }
 
 func (s *StoreEntry) PasturePrefExecTimeData(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (map[string]*model.ExecTimeData, error) {
-
 	res := make(map[string]*model.ExecTimeData, 0)
 	wg := sync.WaitGroup{}
 	wg.Add(len(req.PastureIds))
@@ -123,16 +123,14 @@ func (s *StoreEntry) PasturePrefExecTimeData(ctx context.Context, req *operation
 	return res, nil
 }
 
-func (s *StoreEntry) PastureSprinkleFeedTime(ctx context.Context, req *operationPb.SprinkleFeedTimeRequest) (map[string][]*model.SprinkleStatisticsDataList, error) {
-
-	res := make(map[string][]*model.SprinkleStatisticsDataList, 0)
+func (s *StoreEntry) PastureSprinkleFeedTime(ctx context.Context, req *operationPb.SprinkleFeedTimeRequest) (map[int64][]*model.SprinkleStatisticsDataList, map[int64]*model.GroupPasture, error) {
+	res, pastureList := make(map[int64][]*model.SprinkleStatisticsDataList), make(map[int64]*model.GroupPasture, 0)
 	wg := sync.WaitGroup{}
 	wg.Add(len(req.PastureIds))
 	var muError error
 	for _, pasture := range req.PastureIds {
 		go func(pId int32) {
 			defer wg.Done()
-
 			groupPasture, err := s.GetGroupPastureListById(ctx, int64(pId))
 			if err != nil {
 				zaplog.Error("PastureSprinkleFeedTime", zap.Any("GetGroupPastureListById", err))
@@ -146,6 +144,7 @@ func (s *StoreEntry) PastureSprinkleFeedTime(ctx context.Context, req *operation
 				StartDate:     req.StartDate,
 				EndDate:       req.EndDate,
 			}
+
 			if err = s.PastureHttpClient(ctx, model.DashboardSprinkleFeedTimeUrl, int64(pId), body, response); err != nil {
 				muError = multierr.Append(muError, err)
 				zaplog.Error("PastureSprinkleFeedTime",
@@ -160,160 +159,172 @@ func (s *StoreEntry) PastureSprinkleFeedTime(ctx context.Context, req *operation
 			if response.Code != http.StatusOK {
 				muError = multierr.Append(muError, xerr.Custom(response.Msg))
 			}
-			res[groupPasture.Name] = response.Data
+			res[groupPasture.Id] = response.Data
+			pastureList[groupPasture.Id] = groupPasture
 		}(pasture)
 	}
 	wg.Wait()
-	return res, nil
+	return res, pastureList, nil
 }
 
-func (s *StoreEntry) SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error) {
-	res := &model.SearchAnalysisAccuracyResponse{
+// SearchAnalysisAccuracy 准确性分析
+func (s *StoreEntry) SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse1, error) {
+	res := &model.SearchAnalysisAccuracyResponse1{
 		Code: http.StatusOK,
 		Msg:  "ok",
-		Data: &model.AnalysisAccuracyData{
-			Chart: &model.Chart{},
+		Data: &model.AnalysisAccuracyData1{
 			Table: &model.Table{
 				TitleList: make([]*model.TableList, 0),
 				DataList:  &model.DataList{},
 			},
+			Chart: nil,
 		},
 	}
+
 	res.Data.Table.TitleList = append(res.Data.Table.TitleList, &model.TableList{
 		Name:  "title",
 		Value: "牧场",
 	})
-	pastureAnalysisAccuracy, err := s.PasturePrefAnalysisData(ctx, req)
+
+	dashboardTopData, pastureAnalysisAccuracy, err := s.DashboardTopPasture(ctx, req)
 	if err != nil {
 		return nil, xerr.WithStack(err)
 	}
+	res.Data.Table = s.TitleList(ctx, pastureAnalysisAccuracy)
 
-	mixedFodderAccurateRatio, mixedFodderCorrectRatio, sprinkleFodderAccurateRatio, sprinkleFodderCorrectRatio :=
-		&model.CommonValueRatio{}, &model.CommonValueRatio{}, &model.CommonValueRatio{}, &model.CommonValueRatio{}
-	maTitleValueList, mcTitleValueList, saTitleValueList, scTitleValueList := make([]float64, 0), make([]float64, 0), make([]float64, 0), make([]float64, 0)
-	dayTimeList := tool.TimeBetween(req.StartDate, req.EndDate)
-	for pastureId, data := range pastureAnalysisAccuracy {
-		groupPasture, err := s.GetGroupPastureListById(ctx, pastureId)
-		if err != nil {
-			zaplog.Error("SearchAnalysisAccuracy GetGroupPastureListById",
-				zap.Any("pastureId", pastureId), zap.Any("error", err))
-			continue
-		}
-		if data == nil {
-			continue
-		}
-
-		mixedFodderAccurateRatioDataList := make([]string, 0)
-		for _, v := range data.MixedFodderAccurateRatio {
-			mixedFodderAccurateRatioDataList = append(mixedFodderAccurateRatioDataList, fmt.Sprintf("%.2f", v.Ratio))
-			if len(mixedFodderAccurateRatio.DateDay) < len(dayTimeList) {
-				mixedFodderAccurateRatio.DateDay = append(mixedFodderAccurateRatio.DateDay, v.DayTime)
-			}
-			maTitleValueList = append(maTitleValueList, v.Ratio)
-		}
-
-		mixedFodderAccurateRatio.DataList = append(mixedFodderAccurateRatio.DataList, mixedFodderAccurateRatioDataList)
-		mixedFodderAccurateRatio.PastureIds = append(mixedFodderAccurateRatio.PastureIds, int32(pastureId))
-		mixedFodderAccurateRatio.PastureName = append(mixedFodderAccurateRatio.PastureName, groupPasture.Name)
-
-		mixedFodderCorrectRatioDataList := make([]string, 0)
-		for _, v := range data.MixedFodderCorrectRatio {
-			mixedFodderCorrectRatioDataList = append(mixedFodderCorrectRatioDataList, fmt.Sprintf("%.2f", v.Ratio))
-			if len(mixedFodderCorrectRatio.DateDay) < len(dayTimeList) {
-				mixedFodderCorrectRatio.DateDay = append(mixedFodderCorrectRatio.DateDay, v.DayTime)
-			}
-			mcTitleValueList = append(mcTitleValueList, v.Ratio)
-		}
-
-		mixedFodderCorrectRatio.DataList = append(mixedFodderCorrectRatio.DataList, mixedFodderCorrectRatioDataList)
-		mixedFodderCorrectRatio.PastureIds = append(mixedFodderCorrectRatio.PastureIds, int32(pastureId))
-		mixedFodderCorrectRatio.PastureName = append(mixedFodderCorrectRatio.PastureName, groupPasture.Name)
-
-		sprinkleFodderRatioDataList := make([]string, 0)
-		for _, v := range data.SprinkleFodderAccurateRatio {
-			sprinkleFodderRatioDataList = append(sprinkleFodderRatioDataList, fmt.Sprintf("%.2f", v.Ratio))
-			if len(sprinkleFodderAccurateRatio.DateDay) < len(dayTimeList) {
-				sprinkleFodderAccurateRatio.DateDay = append(sprinkleFodderAccurateRatio.DateDay, v.DayTime)
-			}
-			saTitleValueList = append(saTitleValueList, v.Ratio)
-		}
-
-		sprinkleFodderAccurateRatio.DataList = append(sprinkleFodderAccurateRatio.DataList, sprinkleFodderRatioDataList)
-		sprinkleFodderAccurateRatio.PastureIds = append(sprinkleFodderAccurateRatio.PastureIds, int32(pastureId))
-		sprinkleFodderAccurateRatio.PastureName = append(sprinkleFodderAccurateRatio.PastureName, groupPasture.Name)
-
-		sprinkleFodderCorrectRatioDataList := make([]string, 0)
-		for _, v := range data.SprinkleFodderCorrectRatio {
-			sprinkleFodderCorrectRatioDataList = append(sprinkleFodderCorrectRatioDataList, fmt.Sprintf("%.2f", v.Ratio))
-			if len(sprinkleFodderCorrectRatio.DateDay) < len(dayTimeList) {
-				sprinkleFodderCorrectRatio.DateDay = append(sprinkleFodderCorrectRatio.DateDay, v.DayTime)
-			}
-			scTitleValueList = append(scTitleValueList, v.Ratio)
-		}
-
-		sprinkleFodderCorrectRatio.DataList = append(sprinkleFodderCorrectRatio.DataList, sprinkleFodderCorrectRatioDataList)
-		sprinkleFodderCorrectRatio.PastureIds = append(sprinkleFodderCorrectRatio.PastureIds, int32(pastureId))
-		sprinkleFodderCorrectRatio.PastureName = append(sprinkleFodderCorrectRatio.PastureName, groupPasture.Name)
+	dashboardTopData1 := &model.Chart1{
+		MixedFodderAccurateRatio: &model.PastureTopData1{
+			Title: make([]string, 0),
+			Ratio: make([]float64, 0),
+		},
+		MixedFodderCorrectRatio: &model.PastureTopData1{
+			Title: make([]string, 0),
+			Ratio: make([]float64, 0),
+		},
+		SprinkleFodderAccurateRatio: &model.PastureTopData1{
+			Title: make([]string, 0),
+			Ratio: make([]float64, 0),
+		},
+		SprinkleFodderCorrectRatio: &model.PastureTopData1{
+			Title: make([]string, 0),
+			Ratio: make([]float64, 0),
+		},
 	}
-
-	pastureTopDataList, err := s.TopPasture(ctx, req)
-	if err != nil {
-		zaplog.Error("SearchAnalysisAccuracy", zap.Any("TopPasture", err), zap.Any("request", req))
-		return nil, xerr.WithStack(err)
+	pastureDayTimeRatioList := make(map[operationPb.DashboardTopType_Kind][]*model.PastureDayTimeRatio)
+
+	for _, v := range dashboardTopData.MixedFodderCorrectRatio {
+		pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE] =
+			append(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE],
+				&model.PastureDayTimeRatio{
+					PastureId:   v.PastureId,
+					PastureName: v.PastureName,
+					Ratio:       v.Ratio,
+				})
+		dashboardTopData1.MixedFodderCorrectRatio.Title = append(dashboardTopData1.MixedFodderCorrectRatio.Title, v.PastureName)
+		dashboardTopData1.MixedFodderCorrectRatio.Ratio = append(dashboardTopData1.MixedFodderCorrectRatio.Ratio, v.Ratio)
 	}
 
-	sort.Float64s(maTitleValueList)
-	mixedFodderAccurateRatio.MaxValue = fmt.Sprintf("%.2f", maTitleValueList[len(maTitleValueList)-1])
-	mixedFodderAccurateRatio.MinValue = fmt.Sprintf("%.2f", maTitleValueList[0])
-	mixedFodderAccurateRatio.MiddleValue = fmt.Sprintf("%.2f", tool.Median(maTitleValueList))
-	mixedFodderAccurateRatio.TopOneName = pastureTopDataList.Data.MixedFodderAccurateRatio[0].PastureName
-
-	sort.Float64s(mcTitleValueList)
-	mixedFodderCorrectRatio.MaxValue = fmt.Sprintf("%.2f", mcTitleValueList[len(mcTitleValueList)-1])
-	mixedFodderCorrectRatio.MinValue = fmt.Sprintf("%.2f", mcTitleValueList[0])
-	mixedFodderCorrectRatio.MiddleValue = fmt.Sprintf("%.2f", tool.Median(mcTitleValueList))
-	mixedFodderCorrectRatio.TopOneName = pastureTopDataList.Data.MixedFodderCorrectRatio[0].PastureName
-
-	sort.Float64s(saTitleValueList)
-	sprinkleFodderAccurateRatio.MaxValue = fmt.Sprintf("%.2f", saTitleValueList[len(saTitleValueList)-1])
-	sprinkleFodderAccurateRatio.MinValue = fmt.Sprintf("%.2f", saTitleValueList[0])
-	sprinkleFodderAccurateRatio.MiddleValue = fmt.Sprintf("%.2f", tool.Median(saTitleValueList))
-	sprinkleFodderAccurateRatio.TopOneName = pastureTopDataList.Data.SprinkleFodderAccurateRatio[0].PastureName
-
-	sort.Float64s(scTitleValueList)
-	sprinkleFodderCorrectRatio.MaxValue = fmt.Sprintf("%.2f", scTitleValueList[len(scTitleValueList)-1])
-	sprinkleFodderCorrectRatio.MinValue = fmt.Sprintf("%.2f", scTitleValueList[0])
-	sprinkleFodderCorrectRatio.MiddleValue = fmt.Sprintf("%.2f", tool.Median(scTitleValueList))
-	sprinkleFodderCorrectRatio.TopOneName = pastureTopDataList.Data.SprinkleFodderCorrectRatio[0].PastureName
+	for _, v := range dashboardTopData.MixedFodderAccurateRatio {
+		pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT] =
+			append(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT],
+				&model.PastureDayTimeRatio{
+					PastureId:   v.PastureId,
+					PastureName: v.PastureName,
+					Ratio:       v.Ratio,
+				})
+		dashboardTopData1.MixedFodderAccurateRatio.Title = append(dashboardTopData1.MixedFodderAccurateRatio.Title, v.PastureName)
+		dashboardTopData1.MixedFodderAccurateRatio.Ratio = append(dashboardTopData1.MixedFodderAccurateRatio.Ratio, v.Ratio)
+	}
 
-	chart := &model.Chart{
-		MixedFodderAccurateRatio:    mixedFodderAccurateRatio,
-		MixedFodderCorrectRatio:     mixedFodderCorrectRatio,
-		SprinkleFodderAccurateRatio: sprinkleFodderAccurateRatio,
-		SprinkleFodderCorrectRatio:  sprinkleFodderCorrectRatio,
+	for _, v := range dashboardTopData.SprinkleFodderAccurateRatio {
+		pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE] =
+			append(pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE],
+				&model.PastureDayTimeRatio{
+					PastureId:   v.PastureId,
+					PastureName: v.PastureName,
+					Ratio:       v.Ratio,
+				})
+		dashboardTopData1.SprinkleFodderAccurateRatio.Title = append(dashboardTopData1.SprinkleFodderAccurateRatio.Title, v.PastureName)
+		dashboardTopData1.SprinkleFodderAccurateRatio.Ratio = append(dashboardTopData1.SprinkleFodderAccurateRatio.Ratio, v.Ratio)
 	}
 
-	res.Data.Chart = chart
-	res.Data.Table = s.TitleList(ctx, pastureAnalysisAccuracy)
+	for _, v := range dashboardTopData.SprinkleFodderCorrectRatio {
+		pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT] =
+			append(pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT],
+				&model.PastureDayTimeRatio{
+					PastureId:   v.PastureId,
+					PastureName: v.PastureName,
+					Ratio:       v.Ratio,
+				})
+		dashboardTopData1.SprinkleFodderCorrectRatio.Title = append(dashboardTopData1.SprinkleFodderCorrectRatio.Title, v.PastureName)
+		dashboardTopData1.SprinkleFodderCorrectRatio.Ratio = append(dashboardTopData1.SprinkleFodderCorrectRatio.Ratio, v.Ratio)
+	}
+	// 排序 最大值。最小值。中位数
+	sort.Slice(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE], func(i, j int) bool {
+		return pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE][i].Ratio < pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE][j].Ratio
+	})
+	sort.Slice(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT], func(i, j int) bool {
+		return pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT][i].Ratio < pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT][j].Ratio
+	})
+	sort.Slice(pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE], func(i, j int) bool {
+		return pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE][i].Ratio < pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE][j].Ratio
+	})
+	sort.Slice(pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT], func(i, j int) bool {
+		return pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT][i].Ratio < pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT][j].Ratio
+	})
+	// 混料准确率
+	dashboardTopData1.MixedFodderAccurateRatio.MaxValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE][len(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE])-1].Ratio)
+	dashboardTopData1.MixedFodderAccurateRatio.MinValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE][0].Ratio)
+	dashboardTopData1.MixedFodderAccurateRatio.MiddleValue = fmt.Sprintf("%.2f", getPastureDayTimeRatioMiddleValue(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE]))
+	dashboardTopData1.MixedFodderAccurateRatio.TopOneName = pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE][len(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_ACCURATE])-1].PastureName
+
+	// 混料正确率
+	dashboardTopData1.MixedFodderCorrectRatio.MaxValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT][len(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT])-1].Ratio)
+	dashboardTopData1.MixedFodderCorrectRatio.MinValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT][0].Ratio)
+	dashboardTopData1.MixedFodderCorrectRatio.MiddleValue = fmt.Sprintf("%.2f", getPastureDayTimeRatioMiddleValue(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT]))
+	dashboardTopData1.MixedFodderCorrectRatio.TopOneName = pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT][len(pastureDayTimeRatioList[operationPb.DashboardTopType_MIXED_CORRECT])-1].PastureName
+
+	// 散料准确率
+	dashboardTopData1.SprinkleFodderAccurateRatio.MaxValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE][len(pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE])-1].Ratio)
+	dashboardTopData1.SprinkleFodderAccurateRatio.MinValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE][0].Ratio)
+	dashboardTopData1.SprinkleFodderAccurateRatio.MiddleValue = fmt.Sprintf("%.2f", getPastureDayTimeRatioMiddleValue(pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE]))
+	dashboardTopData1.SprinkleFodderAccurateRatio.TopOneName = pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE][len(pastureDayTimeRatioList[operationPb.DashboardTopType_SPRINKLE_ACCURATE])-1].PastureName
+
+	// 散料正确率
+	dashboardTopData1.SprinkleFodderCorrectRatio.MaxValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT][len(pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT])-1].Ratio)
+	dashboardTopData1.SprinkleFodderCorrectRatio.MinValue = fmt.Sprintf("%.2f", pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT][0].Ratio)
+	dashboardTopData1.SprinkleFodderCorrectRatio.MiddleValue = fmt.Sprintf("%.2f", getPastureDayTimeRatioMiddleValue(pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT]))
+	dashboardTopData1.SprinkleFodderCorrectRatio.TopOneName = pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT][len(pastureDayTimeRatioList[operationPb.DashboardTopType_Sprinkle_CORRECT])-1].PastureName
+
+	res.Data.Chart = dashboardTopData1
 	return res, nil
 }
 
 // TopPasture 牧场排名
 func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.GetPastureTopResponse, error) {
+	res := &model.GetPastureTopResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: nil,
+	}
+	dashboardTopData, _, err := s.DashboardTopPasture(ctx, req)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	res.Data = dashboardTopData
+	return res, nil
+}
+
+func (s *StoreEntry) DashboardTopPasture(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.PastureTop, map[int64]*model.PastureAnalysisAccuracyData, error) {
 	dashboardTopData := &model.PastureTop{
 		MixedFodderAccurateRatio:    make([]*model.PastureTopData, 0),
 		MixedFodderCorrectRatio:     make([]*model.PastureTopData, 0),
 		SprinkleFodderAccurateRatio: make([]*model.PastureTopData, 0),
 		SprinkleFodderCorrectRatio:  make([]*model.PastureTopData, 0),
 	}
-	res := &model.GetPastureTopResponse{
-		Code: http.StatusOK,
-		Msg:  "ok",
-		Data: nil,
-	}
 	analysisAccuracy, err := s.PasturePrefAnalysisData(ctx, req)
 	if err != nil {
-		return nil, xerr.WithStack(err)
+		return nil, nil, xerr.WithStack(err)
 	}
 
 	for pastureId, data := range analysisAccuracy {
@@ -322,6 +333,7 @@ func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnal
 			zaplog.Error("TopPasture", zap.Any("GetGroupPastureListById", pastureId), zap.Any("err", err))
 			continue
 		}
+
 		if data == nil {
 			continue
 		}
@@ -331,6 +343,7 @@ func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnal
 			allMaRatio += v.Ratio
 		}
 		dashboardTopData.MixedFodderAccurateRatio = append(dashboardTopData.MixedFodderAccurateRatio, &model.PastureTopData{
+			PastureId:   pastureId,
 			PastureName: groupPasture.Name,
 			Ratio:       tool.Decimal(allMaRatio / float64(len(data.MixedFodderAccurateRatio))),
 		})
@@ -339,14 +352,16 @@ func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnal
 			allMcRatio += v.Ratio
 		}
 		dashboardTopData.MixedFodderCorrectRatio = append(dashboardTopData.MixedFodderCorrectRatio, &model.PastureTopData{
+			PastureId:   pastureId,
 			PastureName: groupPasture.Name,
-			Ratio:       tool.Decimal(allMaRatio / float64(len(data.MixedFodderCorrectRatio))),
+			Ratio:       tool.Decimal(allMcRatio / float64(len(data.MixedFodderCorrectRatio))),
 		})
 
 		for _, v := range data.SprinkleFodderAccurateRatio {
 			allSaRatio += v.Ratio
 		}
 		dashboardTopData.SprinkleFodderAccurateRatio = append(dashboardTopData.SprinkleFodderAccurateRatio, &model.PastureTopData{
+			PastureId:   pastureId,
 			PastureName: groupPasture.Name,
 			Ratio:       tool.Decimal(allSaRatio / float64(len(data.SprinkleFodderAccurateRatio))),
 		})
@@ -355,6 +370,7 @@ func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnal
 			allScRatio += v.Ratio
 		}
 		dashboardTopData.SprinkleFodderCorrectRatio = append(dashboardTopData.SprinkleFodderCorrectRatio, &model.PastureTopData{
+			PastureId:   pastureId,
 			PastureName: groupPasture.Name,
 			Ratio:       tool.Decimal(allScRatio / float64(len(data.SprinkleFodderCorrectRatio))),
 		})
@@ -386,8 +402,7 @@ func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnal
 		}
 	}
 
-	res.Data = dashboardTopData
-	return res, nil
+	return dashboardTopData, analysisAccuracy, nil
 }
 
 func (s *StoreEntry) TitleList(ctx context.Context, pastureAnalysisList map[int64]*model.PastureAnalysisAccuracyData) *model.Table {
@@ -537,35 +552,49 @@ func (s *StoreEntry) SprinkleFeedTime(ctx context.Context, req *operationPb.Spri
 			TableList: make([]*model.SprinkleFeedTimeTable, 0),
 		},
 	}
-	pastureSprinkleDataList, err := s.PastureSprinkleFeedTime(ctx, req)
+	pastureSprinkleDataList, pastureList, err := s.PastureSprinkleFeedTime(ctx, req)
 	if err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
 	tableList := make([]*model.SprinkleFeedTimeTable, 0)
-	infoSprinkleNumber, errorSprinkleNumber := make([]int32, 0), make([]int32, 0)
-	for pastureName, data := range pastureSprinkleDataList {
-		sprinkleFeedTimeList := make(map[int32]map[int32][]int64, 0)
-		for _, v := range data {
-			tableList = append(tableList, &model.SprinkleFeedTimeTable{
-				PastureName:             pastureName,
-				BarnName:                v.FName,
-				ClassNumber:             fmt.Sprintf("%d", v.Times),
-				RealitySprinkleFeedTime: tool.TimeSub(v.InTime, v.ProcessTime),
-			})
-			realityTime := tool.TimeSub(v.InTime, v.ProcessTime)
-			realityTimeUnix, _ := time.Parse(model.LayoutTime, realityTime)
-			if sprinkleFeedTimeList[v.FBarId] == nil {
-				sprinkleFeedTimeList[v.FBarId] = make(map[int32][]int64, 0)
-			}
-			sprinkleFeedTimeList[v.FBarId][v.Times] = append(sprinkleFeedTimeList[v.FBarId][v.Times], realityTimeUnix.Unix())
+	infoSprinkleNumber, errorSprinkleNumber, pastureIds := make([]int32, 0), make([]int32, 0), make([]int, 0)
+
+	for pastureId, _ := range pastureSprinkleDataList {
+		pastureIds = append(pastureIds, int(pastureId))
+	}
+
+	sort.Ints(pastureIds)
+	pastureInfo := &model.GroupPasture{}
+	for _, pastureId := range pastureIds {
+		if pastureData, ok := pastureList[int64(pastureId)]; ok {
+			pastureInfo = pastureData
 		}
-		res.Data.Chart.Title = append(res.Data.Chart.Title, pastureName)
 
-		infoNumber, errNumber := sprinkleExecTimeAnalysis(sprinkleFeedTimeList)
-		infoSprinkleNumber = append(infoSprinkleNumber, infoNumber)
-		errorSprinkleNumber = append(errorSprinkleNumber, errNumber)
+		if data, ok := pastureSprinkleDataList[int64(pastureId)]; ok {
+			sprinkleFeedTimeList := make(map[int32]map[int32][]int64, 0)
+			for _, v := range data {
+				tableList = append(tableList, &model.SprinkleFeedTimeTable{
+					PastureName:             pastureInfo.Name,
+					BarnName:                v.FName,
+					ClassNumber:             fmt.Sprintf("%d", v.Times),
+					RealitySprinkleFeedTime: tool.TimeSub(v.InTime, v.ProcessTime),
+				})
+				realityTime := tool.TimeSub(v.InTime, v.ProcessTime)
+				realityTimeUnix, _ := time.Parse(model.LayoutTime, realityTime)
+				if sprinkleFeedTimeList[v.FBarId] == nil {
+					sprinkleFeedTimeList[v.FBarId] = make(map[int32][]int64, 0)
+				}
+				sprinkleFeedTimeList[v.FBarId][v.Times] = append(sprinkleFeedTimeList[v.FBarId][v.Times], realityTimeUnix.Unix())
+			}
+
+			res.Data.Chart.Title = append(res.Data.Chart.Title, pastureInfo.Name)
+			infoNumber, errNumber := sprinkleExecTimeAnalysis(sprinkleFeedTimeList)
+			infoSprinkleNumber = append(infoSprinkleNumber, infoNumber)
+			errorSprinkleNumber = append(errorSprinkleNumber, errNumber)
+		}
 	}
+
 	res.Data.Chart.SprinkleNumberList = append(res.Data.Chart.SprinkleNumberList, infoSprinkleNumber, errorSprinkleNumber)
 	res.Data.TableList = tableList
 	return res, nil
@@ -590,7 +619,69 @@ func (s *StoreEntry) FeedMixedAndTmrName(ctx context.Context, req *operationPb.M
 		},
 	}
 	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
-	if err := s.PastureHttpClient(ctx, model.UrlDataByName, int64(req.PastureId), body, response); err != nil {
+	if err = s.PastureHttpClient(ctx, model.UrlDataByName, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+func (s *StoreEntry) FeedTemplateHistory(ctx context.Context, req *operationPb.FeedTemplateHistoryRequest) (*model.PastureFeedTemplateHistoryResponse, error) {
+	groupPasture, err := s.GetGroupPastureListById(ctx, int64(req.PastureId))
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	pastureId := req.PastureId
+	if groupPasture.PastureId > 0 {
+		pastureId = int32(groupPasture.PastureId)
+	}
+
+	body := &model.PastureFeedTemplateHistoryRequest{
+		PastureId: fmt.Sprintf("%d", pastureId),
+		FTid:      int64(req.Ftid),
+		StartDate: req.StartTime,
+		EndDate:   req.EndTime,
+	}
+	response := &model.PastureFeedTemplateHistoryResponse{}
+	if err = s.PastureHttpClient(ctx, model.UrlFeedTemplateHistory, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+func (s *StoreEntry) BarnHistory(ctx context.Context, req *operationPb.BarnHistoryRequest) (*model.PastureBarnHistoryResponse, error) {
+	_, err := s.GetGroupPastureListById(ctx, int64(req.PastureId))
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	body := &model.PastureBarnHistoryRequest{
+		BarName:   req.BarnName,
+		StartDate: req.StartTime,
+		EndDate:   req.EndTime,
+	}
+	response := &model.PastureBarnHistoryResponse{}
+	if err = s.PastureHttpClient(ctx, model.UrlBarnHistory, int64(req.PastureId), body, response); err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	return response, nil
+}
+
+func (s *StoreEntry) SpillageAllHistory(ctx context.Context, req *operationPb.BarnHistoryRequest) (*model.PastureBarnHistoryResponse, error) {
+	groupPasture, err := s.GetGroupPastureListById(ctx, int64(req.PastureId))
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+	pastureId := req.PastureId
+	if groupPasture.PastureId > 0 {
+		pastureId = int32(groupPasture.PastureId)
+	}
+	body := &model.PastureBarnHistoryRequest{
+		PastureId: fmt.Sprintf("%d", pastureId),
+		BarName:   req.BarnName,
+		StartDate: req.StartTime,
+		EndDate:   req.EndTime,
+	}
+	response := &model.PastureBarnHistoryResponse{}
+	if err = s.PastureHttpClient(ctx, model.UrlSpillageAllHistory, int64(req.PastureId), body, response); err != nil {
 		return nil, xerr.WithStack(err)
 	}
 	return response, nil
@@ -631,3 +722,15 @@ func dashboardTopRand(req *operationPb.SearchAnalysisAccuracyRequest, data []*mo
 	}
 	return res
 }
+
+func getPastureDayTimeRatioMiddleValue(pastureDayTimeRatio []*model.PastureDayTimeRatio) float64 {
+	if len(pastureDayTimeRatio) <= 0 {
+		return 0
+	}
+	ratioList := make([]float64, 0)
+	for _, v := range pastureDayTimeRatio {
+		ratioList = append(ratioList, v.Ratio)
+	}
+	sort.Float64s(ratioList)
+	return tool.Median(ratioList)
+}

+ 3 - 6
module/backend/feed_service.go

@@ -122,7 +122,7 @@ func (s *StoreEntry) addFeedFormulaDetailAddRecode(ctx context.Context, req *ope
 	editRecord, _ := s.GetEditRecordLastGroupId(ctx)
 	editRecordList := make([]*model.FeedFormulaEditRecord, 0)
 
-	operationName, _ := s.GetCurrentUserName(ctx)
+	operationName := s.GetCurrentUserName(ctx)
 	for _, v := range req.List {
 		editRecordList = append(editRecordList, &model.FeedFormulaEditRecord{
 			FeedFormulaId: int64(req.FeedFormulaId),
@@ -183,11 +183,8 @@ func (s *StoreEntry) editFeedFormulaDetailAddRecode(ctx context.Context, req *op
 		Status:        operationPb.FeedFormulaEditRecordType_UPDATE,
 	}
 
-	if operationName, err := s.GetCurrentUserName(ctx); err != nil {
-		zaplog.Error("EditFeedByFeedFormula", zap.Any("GetCurrentUserName", err))
-	} else {
-		editRecordData.OperationName = operationName
-	}
+	operationName := s.GetCurrentUserName(ctx)
+	editRecordData.OperationName = operationName
 
 	lastGroupIdData := &model.FeedFormulaEditRecord{}
 	if err := s.DB.Model(new(model.FeedFormulaEditRecord)).

+ 7 - 4
module/backend/interface.go

@@ -117,8 +117,8 @@ type PastureService interface {
 type SystemService interface {
 	// Auth 系统用户相关
 	Auth(ctx context.Context, auth *operationPb.UserAuthData) (*operationPb.SystemToken, error)
-	GetCurrentUserName(ctx context.Context) (string, error)
-	GetUserInfo(ctx context.Context, token string) (*operationPb.UserAuth, error)
+	GetCurrentUserName(ctx context.Context) string
+	GetUserInfo(ctx context.Context) (*operationPb.UserAuth, error)
 	CreateSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error
 	SearchSystemUserList(ctx context.Context, req *operationPb.SearchUserRequest) (*operationPb.SearchUserResponse, error)
 	EditSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error
@@ -126,7 +126,7 @@ type SystemService interface {
 	ResetPasswordSystemUser(ctx context.Context, userId int64) error
 	DetailsSystemUser(ctx context.Context, userId int64) (*operationPb.UserDetails, error)
 	IsShowSystemUser(ctx context.Context, req *operationPb.IsShowSystemUserRequest) error
-	GetSystemUserPermissions(ctx context.Context, token string) (*operationPb.SystemUserMenuPermissions, error)
+	GetSystemUserPermissions(ctx context.Context) (*operationPb.SystemUserMenuPermissions, error)
 
 	// CreateSystemRole 系统角色相关
 	CreateSystemRole(ctx context.Context, req *operationPb.AddRoleRequest) error
@@ -167,11 +167,14 @@ type StatisticService interface {
 	GetDataByName(ctx context.Context, req *operationPb.GetDataByNameRequest) (*model.PastureCommonResponse, error)
 
 	GetTrainNumber(ctx context.Context, req *operationPb.TrainNumberRequest) (*operationPb.TrainNumberResponse, error)
-	SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error)
+	SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse1, error)
 	TopPasture(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.GetPastureTopResponse, error)
 	ExecutionTime(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.ExecTimeResponse, error)
 	SprinkleFeedTime(ctx context.Context, req *operationPb.SprinkleFeedTimeRequest) (*model.SprinkleFeedTimeResponse, error)
 	FeedMixedAndTmrName(ctx context.Context, req *operationPb.MixedCategoryTmrName) (*model.PastureCommonResponse, error)
+	FeedTemplateHistory(ctx context.Context, req *operationPb.FeedTemplateHistoryRequest) (*model.PastureFeedTemplateHistoryResponse, error)
+	BarnHistory(ctx context.Context, req *operationPb.BarnHistoryRequest) (*model.PastureBarnHistoryResponse, error)
+	SpillageAllHistory(ctx context.Context, req *operationPb.BarnHistoryRequest) (*model.PastureBarnHistoryResponse, error)
 }
 
 //go:generate mockgen -destination mock/WxAppletService.go -package kptservicemock kpt-tmr-group/module/backend WxAppletService

+ 2 - 2
module/backend/pasture_service.go

@@ -62,7 +62,7 @@ func (s *StoreEntry) PastureAccountDistribution(ctx context.Context, groupPastur
 		return xerr.WithStack(err)
 	}
 
-	if res.Code != http.StatusOK {
+	if res.Code == http.StatusOK {
 		if err := s.DB.Model(new(model.GroupPasture)).Where("id = ?", groupPasture.Id).Update("is_distribution", operationPb.IsShow_OK).Error; err != nil {
 			zaplog.Error("AccountDistribution-Update", zap.Any("url", model.PastureAccountDistributionURl), zap.Any("err", err), zap.Any("body", body), zap.Any("res", res))
 			return xerr.Customf("%s", res.Msg)
@@ -770,7 +770,7 @@ func (s *StoreEntry) ForageEnumList(ctx context.Context) *operationPb.ForageEnum
 	res.Data.CattleParentCategory = append(res.Data.CattleParentCategory,
 		&operationPb.CattleParentCategoryEnum{
 			Value: operationPb.CattleCategoryParent_INVALID,
-			Label: "畜牧类别",
+			Label: "所有类别",
 		},
 		&operationPb.CattleParentCategoryEnum{
 			Value: operationPb.CattleCategoryParent_LACTATION_CAW,

+ 8 - 0
module/backend/pasture_sync_service.go

@@ -148,6 +148,10 @@ func (s *StoreEntry) FeedFormulaSyncData(ctx context.Context, req *operationPb.F
 			if err = s.FeedFormulaInsert(ctx, groupPasture, response.Data.List); err != nil {
 				return xerr.WithStack(err)
 			}
+			if total <= (pageSize * page) {
+				break
+			}
+			page++
 		}
 
 	}
@@ -289,6 +293,10 @@ func (s *StoreEntry) FeedFormulaDetailListSyncData(ctx context.Context, req *ope
 			if response.Data.Total > 0 && response.Data.List != nil {
 				total = int(math.Ceil(float64(response.Data.Total) / float64(pageSize)))
 			}
+			if total <= (page * pageSize) {
+				break
+			}
+			page++
 			if err = s.FeedFormulaDetailInsert(ctx, groupPasture, response.Data.List); err != nil {
 				return xerr.WithStack(err)
 			}

+ 79 - 80
module/backend/statistic_service.go

@@ -71,7 +71,6 @@ func (s *StoreEntry) SearchFormulaEstimateList(ctx context.Context, req *operati
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps: &model.FormulaEstimateParams{
 			PastureId: fmt.Sprintf("%d", pastureId),
@@ -104,7 +103,6 @@ func (s *StoreEntry) SearchInventoryStatistics(ctx context.Context, req *operati
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps: &model.InventoryStatisticsParams{
 			PastureId: fmt.Sprintf("%d", pastureId),
@@ -226,7 +224,6 @@ func (s *StoreEntry) SearchUserMaterialsStatistics(ctx context.Context, req *ope
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		Checked:    req.ErrorCheck,
 		ParamMaps: &model.UserMaterialsStatisticsParams{
@@ -340,7 +337,6 @@ func (s *StoreEntry) SearchPriceStatistics(ctx context.Context, req *operationPb
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps: &model.PriceStatisticsParams{
 			PastureId: fmt.Sprintf("%d", pastureId),
@@ -399,7 +395,6 @@ func (s *StoreEntry) SearchFeedStatistics(ctx context.Context, req *operationPb.
 				Name:       req.ApiName,
 				Page:       req.Pagination.Page,
 				Offset:     req.Pagination.PageOffset,
-				PageCount:  req.Pagination.PageSize,
 				ReturnType: "Map",
 				ParamMaps:  model.NewFeedStatisticsParams(int64(pastureID), req),
 			}
@@ -417,8 +412,7 @@ func (s *StoreEntry) SearchFeedStatistics(ctx context.Context, req *operationPb.
 			}
 
 			if response.Code == http.StatusOK && response.Data.List != nil {
-				feedStatisticsConversions := FeedStatisticsConversions(response.Data.List)
-				feedStatisticsConversions.PastureName = groupPasture.Name
+				feedStatisticsConversions := FeedStatisticsConversions(response.Data.List, groupPasture.Name)
 				res.Data.List[groupPasture.Name] = feedStatisticsConversions
 			}
 		}(v)
@@ -429,74 +423,79 @@ func (s *StoreEntry) SearchFeedStatistics(ctx context.Context, req *operationPb.
 }
 
 // FeedStatisticsConversions 数据转换
-func FeedStatisticsConversions(req interface{}) *model.FeedStatisticsConversions {
-	feedStatisticsList := &model.FeedStatisticsConversions{}
+func FeedStatisticsConversions(req interface{}, pastureName string) []*model.FeedStatisticsConversions {
+	feedStatisticsList := make([]*model.FeedStatisticsConversions, 0)
 	if data, ok := req.([]interface{}); ok && len(data) > 0 {
-		value := data[0]
-		if v, yes := value.(map[string]interface{}); yes {
-			if d, t := v["TMR干物质"]; t {
-				feedStatisticsList.TmrDryMatter = d.(string)
+		for _, value := range data {
+			feedStatistics := &model.FeedStatisticsConversions{
+				PastureName: pastureName,
 			}
-			if d, t := v["barname"]; t {
-				feedStatisticsList.BarName = d.(string)
-			}
-			if d, t := v["产奶量"]; t {
-				feedStatisticsList.MilkYield = d.(string)
-			}
-			if d, t := v["今日剩料量"]; t {
-				feedStatisticsList.TodayLeftovers = d.(string)
-			}
-			if d, t := v["公斤奶饲料成本"]; t {
-				feedStatisticsList.FeedCosts = d.(float64)
-			}
-			if d, t := v["剩料率"]; t {
-				feedStatisticsList.LeftoverRate = d.(string)
-			}
-			if d, t := v["实际干物质采食量"]; t {
-				feedStatisticsList.ActualDryMatterIntake = d.(string)
-			}
-			if d, t := v["实际成本"]; t {
-				feedStatisticsList.ActualCost = d.(string)
-			}
-			if d, t := v["实际牛头数"]; t {
-				feedStatisticsList.ActualNumberOfCattle = d.(string)
-			}
-			if d, t := v["应混料量"]; t {
-				feedStatisticsList.AmountToBeMixed = d.(string)
-			}
-			if d, t := v["混料时间"]; t {
-				feedStatisticsList.MixingTime = d.(string)
-			}
-			if d, t := v["牲畜类别"]; t {
-				feedStatisticsList.CategoryCattleName = d.(string)
-			}
-			if d, t := v["理论干物质"]; t {
-				feedStatisticsList.TheoreticalDryMatter = d.(string)
-			}
-			if d, t := v["转投剩料量"]; t {
-				feedStatisticsList.LeftoverMaterial = d.(float64)
-			}
-			if d, t := v["配方干物质采食量"]; t {
-				feedStatisticsList.FormulatedDryMatterIntake = d.(string)
-			}
-			if d, t := v["配方成本"]; t {
-				feedStatisticsList.CostOfFormulation = d.(string)
-			}
-			if d, t := v["采食率"]; t {
-				feedStatisticsList.FoodIntakeRate = d.(string)
-			}
-			if d, t := v["饲料转化率"]; t {
-				feedStatisticsList.FeedConversionRatio = d.(float64)
-			}
-			if d, t := v["配方模板"]; t {
-				feedStatisticsList.FeedFormulaName = d.(string)
-			}
-			if d, t := v["实际混料量"]; t {
-				feedStatisticsList.ActualMixedVolume = d.(string)
-			}
-			if d, t := v["撒料量"]; t {
-				feedStatisticsList.SprinkleVolume = d.(string)
+			if v, yes := value.(map[string]interface{}); yes {
+				if d, t := v["TMR干物质"]; t {
+					feedStatistics.TmrDryMatter = d.(string)
+				}
+				if d, t := v["barname"]; t {
+					feedStatistics.BarName = d.(string)
+				}
+				if d, t := v["产奶量"]; t {
+					feedStatistics.MilkYield = d.(string)
+				}
+				if d, t := v["今日剩料量"]; t {
+					feedStatistics.TodayLeftovers = d.(string)
+				}
+				if d, t := v["公斤奶饲料成本"]; t {
+					feedStatistics.FeedCosts = d.(float64)
+				}
+				if d, t := v["剩料率"]; t {
+					feedStatistics.LeftoverRate = d.(string)
+				}
+				if d, t := v["实际干物质采食量"]; t {
+					feedStatistics.ActualDryMatterIntake = d.(string)
+				}
+				if d, t := v["实际成本"]; t {
+					feedStatistics.ActualCost = d.(string)
+				}
+				if d, t := v["实际牛头数"]; t {
+					feedStatistics.ActualNumberOfCattle = d.(string)
+				}
+				if d, t := v["应混料量"]; t {
+					feedStatistics.AmountToBeMixed = d.(string)
+				}
+				if d, t := v["混料时间"]; t {
+					feedStatistics.MixingTime = d.(string)
+				}
+				if d, t := v["牲畜类别"]; t {
+					feedStatistics.CategoryCattleName = d.(string)
+				}
+				if d, t := v["理论干物质"]; t {
+					feedStatistics.TheoreticalDryMatter = d.(string)
+				}
+				if d, t := v["转投剩料量"]; t {
+					feedStatistics.LeftoverMaterial = d.(float64)
+				}
+				if d, t := v["配方干物质采食量"]; t {
+					feedStatistics.FormulatedDryMatterIntake = d.(string)
+				}
+				if d, t := v["配方成本"]; t {
+					feedStatistics.CostOfFormulation = d.(string)
+				}
+				if d, t := v["采食率"]; t {
+					feedStatistics.FoodIntakeRate = d.(string)
+				}
+				if d, t := v["饲料转化率"]; t {
+					feedStatistics.FeedConversionRatio = d.(float64)
+				}
+				if d, t := v["配方模板"]; t {
+					feedStatistics.FeedFormulaName = d.(string)
+				}
+				if d, t := v["实际混料量"]; t {
+					feedStatistics.ActualMixedVolume = d.(string)
+				}
+				if d, t := v["撒料量"]; t {
+					feedStatistics.SprinkleVolume = d.(string)
+				}
 			}
+			feedStatisticsList = append(feedStatisticsList, feedStatistics)
 		}
 	}
 	return feedStatisticsList
@@ -547,7 +546,6 @@ func (s *StoreEntry) CowsAnalysis(ctx context.Context, req *operationPb.CowsAnal
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps: &model.MixFeedStatisticsParams{
 			PastureId: fmt.Sprintf("%d", pastureId),
@@ -599,7 +597,6 @@ func (s *StoreEntry) SearchMixFeedStatistics(ctx context.Context, req *operation
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps:  model.NewMixFeedStatisticsParams(int64(pastureId), req),
 	}
@@ -625,7 +622,6 @@ func (s *StoreEntry) SearchSprinkleStatistics(ctx context.Context, req *operatio
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps:  model.NewSprinkleStatisticsParams(int64(pastureId), req),
 	}
@@ -651,7 +647,6 @@ func (s *StoreEntry) SearchProcessAnalysis(ctx context.Context, req *operationPb
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps:  model.NewProcessAnalysisParams(int64(pastureId), req),
 	}
@@ -679,7 +674,6 @@ func (s *StoreEntry) AnalysisMixedSprinkleDetail(ctx context.Context, req *opera
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps:  model.NewMixedSprinkleDetailRequest(int64(pastureId), req),
 	}
@@ -707,11 +701,17 @@ func (s *StoreEntry) GetDataByName(ctx context.Context, req *operationPb.GetData
 	}
 
 	body := &model.PastureCommonRequest{
-		Name: req.ApiName,
+		Name:   req.ApiName,
+		Page:   req.Page,
+		Offset: req.Offset,
 		ParamMaps: &model.GetDataByNameParams{
 			PastureId: fmt.Sprintf("%d", pastureId),
 			StartTime: req.StartTime,
-			StopTime:  req.StartTime,
+			StopTime:  req.EndTime,
+			Pid:       req.Pid,
+			Optdevice: req.Optdevice,
+			FtId:      req.Ftid,
+			Name:      req.Name,
 		},
 	}
 	response := &model.PastureCommonResponse{Data: &model.PastureCommonData{}}
@@ -736,7 +736,6 @@ func (s *StoreEntry) GetTrainNumber(ctx context.Context, req *operationPb.TrainN
 		Name:       req.ApiName,
 		Page:       req.Pagination.Page,
 		Offset:     req.Pagination.PageOffset,
-		PageCount:  req.Pagination.PageSize,
 		ReturnType: "Map",
 		ParamMaps: &model.TrainNumberParams{
 			PastureId: fmt.Sprintf("%d", pastureId),

+ 22 - 25
module/backend/system_service.go

@@ -4,15 +4,16 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"kpt-tmr-group/model"
+	"net/http"
+	"strconv"
+	"strings"
+
 	operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
 	"gitee.com/xuyiping_admin/pkg/jwt"
 	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
 	"gitee.com/xuyiping_admin/pkg/tool"
 	"gitee.com/xuyiping_admin/pkg/xerr"
-	"kpt-tmr-group/model"
-	"net/http"
-	"strconv"
-	"strings"
 
 	"go.uber.org/zap"
 
@@ -51,28 +52,27 @@ func (s *StoreEntry) Auth(ctx context.Context, auth *operationPb.UserAuthData) (
 	}, nil
 }
 
-func (s *StoreEntry) GetCurrentUserName(ctx context.Context) (string, error) {
+func (s *StoreEntry) GetCurrentUserName(ctx context.Context) string {
 	userNameInter := ctx.Value(CurrentUserName)
 	if userNameInter == nil {
-		return "", xerr.Customf("cannot userName")
+		zaplog.Error("GetCurrentUserName", zap.String("userNameInter", "cannot userName"))
+		return ""
 	}
 
 	if userName, ok := userNameInter.(string); ok {
-		return userName, nil
+		return userName
 	} else {
-		return "", xerr.Customf("waring userName")
+		zaplog.Error("GetCurrentUserName", zap.String("userNameInter", "waring userName"))
+		return ""
 	}
 }
 
 // GetUserInfo 获取用户信息
-func (s *StoreEntry) GetUserInfo(ctx context.Context, token string) (*operationPb.UserAuth, error) {
+func (s *StoreEntry) GetUserInfo(ctx context.Context) (*operationPb.UserAuth, error) {
 	systemUser := &model.SystemUser{}
-	userName, err := s.GetCurrentUserName(ctx)
-	if err != nil {
-		return nil, xerr.WithStack(err)
-	}
+	userName := s.GetCurrentUserName(ctx)
 
-	if err = s.DB.Where("name = ?", userName).First(systemUser).Error; err != nil {
+	if err := s.DB.Where("name = ?", userName).First(systemUser).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
@@ -86,12 +86,12 @@ 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").
+		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 {
+		if err := s.DB.Find(&systemRole, roleIds).Error; err != nil {
 			return nil, xerr.WithStack(err)
 		}
 	}
@@ -101,13 +101,12 @@ func (s *StoreEntry) GetUserInfo(ctx context.Context, token string) (*operationP
 
 // CreateSystemUser 创建系统用户
 func (s *StoreEntry) CreateSystemUser(ctx context.Context, req *operationPb.AddSystemUser) error {
-
 	systemUsers := &model.SystemUser{
 		Name:         req.Name,
 		EmployeeName: req.EmployeeName,
 		Phone:        req.Phone,
 		Password:     tool.Md5String(model.InitManagerPassword),
-		CreateUser:   req.CreateUser,
+		CreateUser:   s.GetCurrentUserName(ctx),
 		IsShow:       operationPb.IsShow_OK,
 		IsDelete:     operationPb.IsShow_OK,
 	}
@@ -262,15 +261,12 @@ func (s *StoreEntry) IsShowSystemUser(ctx context.Context, req *operationPb.IsSh
 }
 
 // GetSystemUserPermissions 返回系统用户相关菜单权限
-func (s *StoreEntry) GetSystemUserPermissions(ctx context.Context, token string) (*operationPb.SystemUserMenuPermissions, error) {
+func (s *StoreEntry) GetSystemUserPermissions(ctx context.Context) (*operationPb.SystemUserMenuPermissions, error) {
 	// 解析token
-	userName, err := s.GetCurrentUserName(ctx)
-	if err != nil {
-		return nil, xerr.WithStack(err)
-	}
+	userName := s.GetCurrentUserName(ctx)
 	// 根据用户token获取用户数据
 	systemUser := &model.SystemUser{Name: userName}
-	if err = s.DB.Where("name = ?", userName).First(systemUser).Error; err != nil {
+	if err := s.DB.Where("name = ?", userName).First(systemUser).Error; err != nil {
 		if errors.Is(err, gorm.ErrRecordNotFound) {
 			return nil, xerr.Custom("该用户数据不存在")
 		}
@@ -280,7 +276,7 @@ func (s *StoreEntry) GetSystemUserPermissions(ctx context.Context, token string)
 
 	// 获取用户角色数据
 	systemRoles := make([]*model.SystemRole, 0)
-	if err = s.DB.Where("is_show = ?", operationPb.IsShow_OK).Find(&systemRoles, roleIds).Error; err != nil {
+	if err := s.DB.Where("is_show = ?", operationPb.IsShow_OK).Find(&systemRoles, roleIds).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
@@ -321,6 +317,7 @@ func (s *StoreEntry) GetSystemUserPermissions(ctx context.Context, token string)
 func (s *StoreEntry) CreateSystemRole(ctx context.Context, req *operationPb.AddRoleRequest) error {
 	if err := s.DB.Transaction(func(tx *gorm.DB) error {
 		// 创建角色数据
+		req.CreateUser = s.GetCurrentUserName(ctx)
 		role := model.NewSystemRole(req)
 		if err := tx.Create(role).Error; err != nil {
 			return xerr.WithStack(err)

+ 22 - 0
service/cache/go-cache/cache.go

@@ -0,0 +1,22 @@
+package go_cache
+
+import (
+	"time"
+
+	"github.com/patrickmn/go-cache"
+)
+
+const (
+	DefaultExpiration time.Duration = 5 * time.Minute
+	CleanupInterval   time.Duration = 10 * time.Minute
+)
+
+type GoCache struct {
+	Cache *cache.Cache
+}
+
+func NewCache() *GoCache {
+	return &GoCache{
+		Cache: cache.New(DefaultExpiration, CleanupInterval),
+	}
+}