Browse Source

dashboard: 执行时间

Yi 1 year ago
parent
commit
18bc219d42

+ 18 - 2
http/handler/dashboard/dashboard.go

@@ -21,7 +21,6 @@ func AnalysisAccuracy(c *gin.Context) {
 
 	if err := valid.ValidateStruct(&req,
 		valid.Field(&req.PastureIds, valid.Required),
-		valid.Field(&req.CattleParentCategoryId, valid.Required),
 	); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -45,7 +44,6 @@ func TopPasture(c *gin.Context) {
 
 	if err := valid.ValidateStruct(&req,
 		valid.Field(&req.PastureIds, valid.Required),
-		valid.Field(&req.CattleParentCategoryId, valid.Required),
 	); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
@@ -61,5 +59,23 @@ func TopPasture(c *gin.Context) {
 
 // ExecutionTime 执行时间
 func ExecutionTime(c *gin.Context) {
+	var req operationPb.SearchAnalysisAccuracyRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
 
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.PastureIds, valid.Required),
+	); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	res, err := middleware.BackendOperation(c).OpsService.ExecutionTime(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	c.JSON(http.StatusOK, res)
 }

+ 5 - 1
http/middleware/cors.go

@@ -41,7 +41,11 @@ func CORS(configs ...cors.Config) gin.HandlerFunc {
 
 		defer func() {
 			if err := recover(); err != nil {
-				zaplog.Error("cors", zap.Any("recover", err))
+				zaplog.Error("cors",
+					zap.Any("recover", err),
+					zap.Any("url", c.Request.URL),
+					zap.Any("method", method),
+				)
 			}
 		}()
 

+ 26 - 0
model/analysis_accuracy.go

@@ -90,3 +90,29 @@ type PastureTopData struct {
 	PastureName string  `json:"pasture_name"`
 	Ratio       float64 `json:"ratio"`
 }
+
+type ExecTimeResponse struct {
+	Code int32                    `json:"code"`
+	Msg  string                   `json:"msg"`
+	Data map[string]*ExecTimeData `json:"data"`
+}
+
+type PastureExecTimeData struct {
+	Code int32         `json:"code"`
+	Msg  string        `json:"msg"`
+	Data *ExecTimeData `json:"data"`
+}
+
+type ExecTimeData struct {
+	AddFeedTime  *ExecTimeDetail `json:"add_feed_time"`
+	SprinkleTime *ExecTimeDetail `json:"sprinkle_time"`
+	StirTime     *ExecTimeDetail `json:"stir_time"`
+}
+
+type ExecTimeDetail struct {
+	MaxValue        string `json:"max_value"`
+	MinValue        string `json:"min_value"`
+	MiddleValue     string `json:"middle_value"`
+	DownMiddleValue string `json:"down_middle_value"`
+	UpMiddleValue   string `json:"up_middle_value"`
+}

+ 134 - 23
module/backend/dashboard_service.go

@@ -17,7 +17,7 @@ import (
 	"go.uber.org/zap"
 )
 
-func (s *StoreEntry) SearchPrefAnalysisData(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (map[int64]*model.PastureAnalysisAccuracyData, error) {
+func (s *StoreEntry) PasturePrefAnalysisData(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (map[int64]*model.PastureAnalysisAccuracyData, error) {
 	groupPastureList, err := s.FindGroupPastureListByIds(ctx, req.PastureIds)
 	if err != nil {
 		return nil, xerr.WithStack(err)
@@ -59,6 +59,48 @@ func (s *StoreEntry) SearchPrefAnalysisData(ctx context.Context, req *operationP
 	return res, nil
 }
 
+func (s *StoreEntry) PasturePrefExecTimeData(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (map[string]*model.ExecTimeData, error) {
+	groupPastureList, err := s.FindGroupPastureListByIds(ctx, req.PastureIds)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	res := make(map[string]*model.ExecTimeData, 0)
+	wg := sync.WaitGroup{}
+	wg.Add(len(groupPastureList))
+	var muError error
+	for _, pasture := range groupPastureList {
+		go func(p *model.GroupPasture) {
+			response := &model.PastureExecTimeData{}
+			body := &model.DashboardAccuracyRequest{
+				PastureId:              int32(p.Id),
+				FeedFormulaId:          req.FeedFormulaId,
+				CattleParentCategoryId: int32(req.CattleParentCategoryId),
+				StartDate:              req.StartDate,
+				EndDate:                req.EndDate,
+			}
+			if err = s.PastureHttpClient(ctx, DashboardExecTimeUrl, p.Id, body, response); err != nil {
+				muError = multierr.Append(muError, err)
+				zaplog.Error("PasturePrefExecTimeData",
+					zap.String("url", DashboardExecTimeUrl),
+					zap.Any("pasture", p), zap.Any("body", body),
+					zap.Any("err", err), zap.Any("response", response))
+				b, _ := json.Marshal(body)
+				resB, _ := json.Marshal(response)
+				pastureDataLog := model.NewPastureDataLog(p.Id, PastureDataLogType["PasturePrefExecTimeData"], DashboardExecTimeUrl, string(b), string(resB))
+				s.DB.Create(pastureDataLog)
+			}
+			if response.Code != http.StatusOK {
+				muError = multierr.Append(muError, xerr.Custom(response.Msg))
+			}
+			res[p.Name] = response.Data
+			wg.Done()
+		}(pasture)
+	}
+	wg.Wait()
+	return res, nil
+}
+
 func (s *StoreEntry) SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error) {
 	res := &model.SearchAnalysisAccuracyResponse{
 		Code: http.StatusOK,
@@ -75,7 +117,7 @@ func (s *StoreEntry) SearchAnalysisAccuracy(ctx context.Context, req *operationP
 		Name:  "title",
 		Value: "牧场",
 	})
-	pastureAnalysisAccuracy, err := s.SearchPrefAnalysisData(ctx, req)
+	pastureAnalysisAccuracy, err := s.PasturePrefAnalysisData(ctx, req)
 	if err != nil {
 		return nil, xerr.WithStack(err)
 	}
@@ -85,14 +127,16 @@ func (s *StoreEntry) SearchAnalysisAccuracy(ctx context.Context, req *operationP
 	maTitleValueList, mcTitleValueList, saTitleValueList, scTitleValueList := make([]float64, 0), make([]float64, 0), make([]float64, 0), make([]float64, 0)
 	mTopOneName := ""
 	for pastureId, data := range pastureAnalysisAccuracy {
-		b, _ := json.Marshal(data)
-		zaplog.Info("pastureAnalysisAccuracy", zap.String("body", string(b)))
+
 		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 {
@@ -187,38 +231,76 @@ func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnal
 			SprinkleFodderCorrectRatio:  make([]*model.PastureTopData, 0),
 		},
 	}
-	analysisAccuracy, err := s.SearchPrefAnalysisData(ctx, req)
+	analysisAccuracy, err := s.PasturePrefAnalysisData(ctx, req)
 	if err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
-	fmt.Println("========analysisAccuracy=========", analysisAccuracy)
+	mixedFodderAccurateRatio := make([]*model.PastureTopData, 0)
+	mixedFodderCorrectRatio := make([]*model.PastureTopData, 0)
+	sprinkleFodderAccurateRatio := make([]*model.PastureTopData, 0)
+	sprinkleFodderCorrectRatio := make([]*model.PastureTopData, 0)
+	for pastureId, data := range analysisAccuracy {
+		groupPasture, err := s.GetGroupPastureListById(ctx, pastureId)
+		if err != nil {
+			zaplog.Error("TopPasture", zap.Any("GetGroupPastureListById", pastureId), zap.Any("err", err))
+			continue
+		}
+		if data == nil {
+			continue
+		}
+
+		allMaRatio, allMcRatio, allSaRatio, allScRatio := 0.0, 0.0, 0.0, 0.0
+		for _, v := range data.MixedFodderAccurateRatio {
+			allMaRatio += v.Ratio
+		}
+		mixedFodderAccurateRatio = append(mixedFodderAccurateRatio, &model.PastureTopData{
+			PastureName: groupPasture.Name,
+			Ratio:       allMaRatio / float64(len(data.MixedFodderAccurateRatio)),
+		})
 
-	/*time1, _ := time.ParseInLocation(model.LayoutDateFormat, req.StartDate, time.Local)
-	time2, _ := time.ParseInLocation(model.LayoutDateFormat, req.EndDate, time.Local)
-	timeLen := time2.Sub(time1).Hours() / 24
+		for _, v := range data.MixedFodderCorrectRatio {
+			allMcRatio += v.Ratio
+		}
+		mixedFodderCorrectRatio = append(mixedFodderCorrectRatio, &model.PastureTopData{
+			PastureName: groupPasture.Name,
+			Ratio:       allMaRatio / float64(len(data.MixedFodderCorrectRatio)),
+		})
 
-	mapPastureList := make(map[string][]*model.OptionsAnalysisAccuracy, 0)
-	for _, v := range analysisAccuracy {
-		mapPastureList[v.PastureName] = append(mapPastureList[v.PastureName], v)
-	}*/
+		for _, v := range data.SprinkleFodderAccurateRatio {
+			allSaRatio += v.Ratio
+		}
+		sprinkleFodderAccurateRatio = append(sprinkleFodderAccurateRatio, &model.PastureTopData{
+			PastureName: groupPasture.Name,
+			Ratio:       allSaRatio / float64(len(data.SprinkleFodderAccurateRatio)),
+		})
 
-	mixedFodderAccurateRatio := make([]*model.PastureTopData, 0)
-	/*for pastureName, data := range mapPastureList {
-		var allValueRatio float64
-		for _, v := range data {
-			allValueRatio += float64(v.AllIweight/v.AllLweight) / 100.0
+		for _, v := range data.SprinkleFodderCorrectRatio {
+			allScRatio += v.Ratio
 		}
-		average := allValueRatio / timeLen
-		mixedFodderAccurateRatio = append(mixedFodderAccurateRatio, &model.PastureTopData{
-			PastureName: pastureName,
-			Ratio:       average,
+		sprinkleFodderCorrectRatio = append(sprinkleFodderCorrectRatio, &model.PastureTopData{
+			PastureName: groupPasture.Name,
+			Ratio:       allScRatio / float64(len(data.SprinkleFodderCorrectRatio)),
 		})
-	}*/
+	}
+
 	sort.Slice(mixedFodderAccurateRatio, func(i, j int) bool {
 		return mixedFodderAccurateRatio[i].Ratio > mixedFodderAccurateRatio[j].Ratio
 	})
+	sort.Slice(mixedFodderCorrectRatio, func(i, j int) bool {
+		return mixedFodderCorrectRatio[i].Ratio > mixedFodderCorrectRatio[j].Ratio
+	})
+	sort.Slice(sprinkleFodderAccurateRatio, func(i, j int) bool {
+		return sprinkleFodderAccurateRatio[i].Ratio > sprinkleFodderAccurateRatio[j].Ratio
+	})
+	sort.Slice(sprinkleFodderCorrectRatio, func(i, j int) bool {
+		return sprinkleFodderCorrectRatio[i].Ratio > sprinkleFodderCorrectRatio[j].Ratio
+	})
+
 	res.Data.MixedFodderAccurateRatio = mixedFodderAccurateRatio
+	res.Data.MixedFodderCorrectRatio = mixedFodderCorrectRatio
+	res.Data.SprinkleFodderAccurateRatio = sprinkleFodderAccurateRatio
+	res.Data.SprinkleFodderCorrectRatio = sprinkleFodderCorrectRatio
 	return res, nil
 }
 
@@ -288,3 +370,32 @@ func (s *StoreEntry) TitleList(ctx context.Context, pastureAnalysisList map[int6
 
 	return res
 }
+
+func (s *StoreEntry) ExecutionTime(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.ExecTimeResponse, error) {
+	res := &model.ExecTimeResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: make(map[string]*model.ExecTimeData, 0),
+	}
+
+	pastureExecTime, err := s.PasturePrefExecTimeData(ctx, req)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	for pastureName, execTime := range pastureExecTime {
+		if execTime == nil {
+			continue
+		}
+
+		res.Data = map[string]*model.ExecTimeData{
+			pastureName: {
+				AddFeedTime:  execTime.AddFeedTime,
+				SprinkleTime: execTime.SprinkleTime,
+				StirTime:     execTime.StirTime,
+			},
+		}
+	}
+
+	return res, nil
+}

+ 1 - 0
module/backend/interface.go

@@ -150,6 +150,7 @@ type StatisticService interface {
 	GetTrainNumber(ctx context.Context, req *operationPb.TrainNumberRequest) (*operationPb.TrainNumberResponse, error)
 	SearchAnalysisAccuracy(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.SearchAnalysisAccuracyResponse, error)
 	TopPasture(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.GetPastureTopResponse, error)
+	ExecutionTime(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.ExecTimeResponse, error)
 }
 
 type WxAppletService interface {

+ 1 - 2
module/backend/statistic_service.go

@@ -22,10 +22,9 @@ type PastureClientHandler func(ctx context.Context, pastureId int64, body interf
 const (
 	FeedFormulaDistributeUrl = "pasture/feed_formula/distribute"
 	DashboardAccuracyUrl     = "pasture/dashboard/accuracy_data"
+	DashboardExecTimeUrl     = "pasture/dashboard/process_analysis"
 )
 
-// type eventHandler func(ev map[string]interface{}, openID string, appID string, enterpriseID int, cts int64, conn redis.Conn) error
-
 // PastureDetailById 获取指定牧场详情
 func (s *StoreEntry) PastureDetailById(ctx context.Context, pastureId int64) (*model.GroupPasture, error) {
 	result := &model.GroupPasture{Id: pastureId}