package backend import ( "context" "encoding/json" "fmt" "kpt-tmr-group/model" "kpt-tmr-group/pkg/logger/zaplog" "kpt-tmr-group/pkg/tool" "kpt-tmr-group/pkg/xerr" operationPb "kpt-tmr-group/proto/go/backend/operation" "net/http" "sort" "sync" "time" "go.uber.org/multierr" "go.uber.org/zap" ) const compareTime = 10 * 60 // PasturePrefAnalysisData PasturePrefExecTimeData PastureSprinkleFeedTime TODO 后期三个函数封装一下 func (s *StoreEntry) PasturePrefAnalysisData(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (map[int64]*model.PastureAnalysisAccuracyData, error) { res := make(map[int64]*model.PastureAnalysisAccuracyData, 0) wg := sync.WaitGroup{} wg.Add(len(req.PastureIds)) for _, pastureId := range req.PastureIds { go func(pId int32) { defer wg.Done() response := &model.PastureAnalysisAccuracyResponse{} groupPasture, err := s.GetGroupPastureListById(ctx, int64(pId)) if err != nil { zaplog.Error("PasturePrefAnalysisData", zap.Any("GetGroupPastureListById", err), zap.Any("pId", pId)) return } body := &model.DashboardAccuracyRequest{ PastureId: int32(groupPasture.PastureId), FeedFormulaId: req.FeedFormulaId, CattleParentCategoryId: int32(req.CattleParentCategoryId), StartDate: req.StartDate, EndDate: req.EndDate, } _, err = s.PastureHttpClient(ctx, model.DashboardAccuracyUrl, int64(pId), body, response) if err != nil { zaplog.Error("DistributeFeedFormula", zap.String("url", model.DashboardAccuracyUrl), zap.Any("pasture", groupPasture), zap.Any("body", body), zap.Any("err", err), zap.Any("response", response)) b, _ := json.Marshal(body) resB, _ := json.Marshal(response) pastureDataLog := model.NewPastureDataLog(groupPasture.Id, PastureDataLogType["FeedFormula_Distribute"], model.DashboardAccuracyUrl, string(b), string(resB)) s.DB.Create(pastureDataLog) return } if response.Code != http.StatusOK { zaplog.Error("DistributeFeedFormula-response", zap.String("url", model.DashboardAccuracyUrl), zap.Any("pasture", groupPasture), zap.Any("body", body), zap.Any("response", response), zap.Any("response", response)) return } res[groupPasture.Id] = response.Data }(pastureId) } wg.Wait() return res, nil } 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)) for _, pastureId := range req.PastureIds { go func(pId int32) { defer wg.Done() groupPasture, err := s.GetGroupPastureListById(ctx, int64(pId)) if err != nil { return } response := &model.PastureExecTimeData{} body := &model.DashboardAccuracyRequest{ PastureId: int32(groupPasture.PastureId), FeedFormulaId: req.FeedFormulaId, CattleParentCategoryId: int32(req.CattleParentCategoryId), StartDate: req.StartDate, EndDate: req.EndDate, } if _, err = s.PastureHttpClient(ctx, model.DashboardExecTimeUrl, int64(pId), body, response); err != nil { zaplog.Error("PasturePrefExecTimeData", zap.String("url", model.DashboardExecTimeUrl), zap.Any("pasture", groupPasture), zap.Any("body", body), zap.Any("err", err), zap.Any("response", response)) b, _ := json.Marshal(body) resB, _ := json.Marshal(response) pastureDataLog := model.NewPastureDataLog(groupPasture.Id, PastureDataLogType["PasturePrefExecTimeData"], model.DashboardExecTimeUrl, string(b), string(resB)) s.DB.Create(pastureDataLog) return } if response.Code != http.StatusOK { zaplog.Error("PasturePrefExecTimeData-response", zap.String("url", model.DashboardExecTimeUrl), zap.Any("pasture", groupPasture), zap.Any("body", body), zap.Any("err", err), zap.Any("response", response)) return } res[groupPasture.Name] = response.Data }(pastureId) } wg.Wait() 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) 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)) return } response := &model.PastureSprinkleStatisticsDataList{} body := &model.DashboardAccuracyRequest{ PastureId: int32(groupPasture.PastureId), FeedFormulaId: req.FeedFormulaId, 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", zap.String("url", model.DashboardSprinkleFeedTimeUrl), zap.Any("pasture", groupPasture), zap.Any("body", body), zap.Any("err", err), zap.Any("response", response)) b, _ := json.Marshal(body) resB, _ := json.Marshal(response) pastureDataLog := model.NewPastureDataLog(groupPasture.Id, PastureDataLogType["PasturePrefExecTimeData"], model.DashboardSprinkleFeedTimeUrl, string(b), string(resB)) s.DB.Create(pastureDataLog) } if response.Code != http.StatusOK { muError = multierr.Append(muError, xerr.Custom(response.Msg)) } res[groupPasture.Name] = response.Data }(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, Msg: "ok", Data: &model.AnalysisAccuracyData{ Chart: &model.Chart{}, Table: &model.Table{ TitleList: make([]*model.TableList, 0), DataList: &model.DataList{}, }, }, } res.Data.Table.TitleList = append(res.Data.Table.TitleList, &model.TableList{ Name: "title", Value: "牧场", }) pastureAnalysisAccuracy, err := s.PasturePrefAnalysisData(ctx, req) if err != nil { return nil, xerr.WithStack(err) } 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) mTopOneName := "" 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) } 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 = mTopOneName 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 = mTopOneName 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 = mTopOneName 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 = mTopOneName chart := &model.Chart{ MixedFodderAccurateRatio: mixedFodderAccurateRatio, MixedFodderCorrectRatio: mixedFodderCorrectRatio, SprinkleFodderAccurateRatio: sprinkleFodderAccurateRatio, SprinkleFodderCorrectRatio: sprinkleFodderCorrectRatio, } res.Data.Chart = chart res.Data.Table = s.TitleList(ctx, pastureAnalysisAccuracy) return res, nil } // TopPasture 牧场排名 func (s *StoreEntry) TopPasture(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.GetPastureTopResponse, 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) } 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 } dashboardTopData.MixedFodderAccurateRatio = append(dashboardTopData.MixedFodderAccurateRatio, &model.PastureTopData{ PastureName: groupPasture.Name, Ratio: tool.Decimal(allMaRatio / float64(len(data.MixedFodderAccurateRatio))), }) for _, v := range data.MixedFodderCorrectRatio { allMcRatio += v.Ratio } dashboardTopData.MixedFodderCorrectRatio = append(dashboardTopData.MixedFodderCorrectRatio, &model.PastureTopData{ PastureName: groupPasture.Name, Ratio: tool.Decimal(allMaRatio / float64(len(data.MixedFodderCorrectRatio))), }) for _, v := range data.SprinkleFodderAccurateRatio { allSaRatio += v.Ratio } dashboardTopData.SprinkleFodderAccurateRatio = append(dashboardTopData.SprinkleFodderAccurateRatio, &model.PastureTopData{ PastureName: groupPasture.Name, Ratio: tool.Decimal(allSaRatio / float64(len(data.SprinkleFodderAccurateRatio))), }) for _, v := range data.SprinkleFodderCorrectRatio { allScRatio += v.Ratio } dashboardTopData.SprinkleFodderCorrectRatio = append(dashboardTopData.SprinkleFodderCorrectRatio, &model.PastureTopData{ PastureName: groupPasture.Name, Ratio: tool.Decimal(allScRatio / float64(len(data.SprinkleFodderCorrectRatio))), }) } sort.Slice(dashboardTopData.MixedFodderAccurateRatio, func(i, j int) bool { return dashboardTopData.MixedFodderAccurateRatio[i].Ratio > dashboardTopData.MixedFodderAccurateRatio[j].Ratio }) sort.Slice(dashboardTopData.MixedFodderCorrectRatio, func(i, j int) bool { return dashboardTopData.MixedFodderCorrectRatio[i].Ratio > dashboardTopData.MixedFodderCorrectRatio[j].Ratio }) sort.Slice(dashboardTopData.SprinkleFodderAccurateRatio, func(i, j int) bool { return dashboardTopData.SprinkleFodderAccurateRatio[i].Ratio > dashboardTopData.SprinkleFodderAccurateRatio[j].Ratio }) sort.Slice(dashboardTopData.SprinkleFodderCorrectRatio, func(i, j int) bool { return dashboardTopData.SprinkleFodderCorrectRatio[i].Ratio > dashboardTopData.SprinkleFodderCorrectRatio[j].Ratio }) if req.DashboardTopType > 0 { switch req.DashboardTopType { case operationPb.DashboardTopType_MIXED_ACCURATE: dashboardTopData.MixedFodderAccurateRatio = dashboardTopRand(req, dashboardTopData.MixedFodderAccurateRatio) case operationPb.DashboardTopType_MIXED_CORRECT: dashboardTopData.MixedFodderCorrectRatio = dashboardTopRand(req, dashboardTopData.MixedFodderCorrectRatio) case operationPb.DashboardTopType_SPRINKLE_ACCURATE: dashboardTopData.SprinkleFodderAccurateRatio = dashboardTopRand(req, dashboardTopData.SprinkleFodderAccurateRatio) case operationPb.DashboardTopType_Sprinkle_CORRECT: dashboardTopData.SprinkleFodderCorrectRatio = dashboardTopRand(req, dashboardTopData.SprinkleFodderCorrectRatio) } } res.Data = dashboardTopData return res, nil } func (s *StoreEntry) TitleList(ctx context.Context, pastureAnalysisList map[int64]*model.PastureAnalysisAccuracyData) *model.Table { res := &model.Table{ TitleList: make([]*model.TableList, 0), DataList: &model.DataList{ MixedFodderAccurateRatio: make([]map[string]string, 0), MixedFodderCorrectRatio: make([]map[string]string, 0), SprinkleFodderAccurateRatio: make([]map[string]string, 0), SprinkleFodderCorrectRatio: make([]map[string]string, 0), }, } for pastureId, data := range pastureAnalysisList { groupPasture, err := s.GetGroupPastureListById(ctx, pastureId) if err != nil { zaplog.Info("TitleList", zap.Any("GetGroupPastureListById", pastureId), zap.Any("err", err)) continue } if len(res.TitleList) <= len(data.MixedFodderAccurateRatio) { res.TitleList = append(res.TitleList, &model.TableList{ Name: "title", Value: "牧场", }) } maMap := map[string]string{ "title": groupPasture.Name, } for i, v := range data.MixedFodderCorrectRatio { maMap[fmt.Sprintf("data%d", i+1)] = fmt.Sprintf("%.2f", v.Ratio) if len(res.TitleList) <= len(data.MixedFodderAccurateRatio) { res.TitleList = append(res.TitleList, &model.TableList{ Name: fmt.Sprintf("data%d", i+1), Value: v.DayTime, }) } } res.DataList.MixedFodderAccurateRatio = append(res.DataList.MixedFodderAccurateRatio, maMap) mcMap := map[string]string{ "title": groupPasture.Name, } for i, v := range data.MixedFodderCorrectRatio { mcMap[fmt.Sprintf("data%d", i+1)] = fmt.Sprintf("%.2f", v.Ratio) } res.DataList.MixedFodderCorrectRatio = append(res.DataList.MixedFodderCorrectRatio, mcMap) saMap := map[string]string{ "title": groupPasture.Name, } for i, v := range data.SprinkleFodderAccurateRatio { saMap[fmt.Sprintf("data%d", i+1)] = fmt.Sprintf("%.2f", v.Ratio) } res.DataList.SprinkleFodderAccurateRatio = append(res.DataList.SprinkleFodderAccurateRatio, saMap) scMap := map[string]string{ "title": groupPasture.Name, } for i, v := range data.SprinkleFodderCorrectRatio { scMap[fmt.Sprintf("data%d", i+1)] = fmt.Sprintf("%.2f", v.Ratio) } res.DataList.SprinkleFodderCorrectRatio = append(res.DataList.SprinkleFodderCorrectRatio, scMap) } return res } func (s *StoreEntry) ExecutionTime(ctx context.Context, req *operationPb.SearchAnalysisAccuracyRequest) (*model.ExecTimeResponse, error) { res := &model.ExecTimeResponse{ Code: http.StatusOK, Msg: "ok", Data: &model.ExecTimeDataList{ Chart: &model.ExecTimeDataListChart{ Title: make([]string, 0), AddFeedTime: make([][]string, 0), SprinkleTime: make([][]string, 0), StirTime: make([][]string, 0), }, TableList: make([]map[string]string, 0), }, } pastureExecTime, err := s.PasturePrefExecTimeData(ctx, req) if err != nil { return nil, xerr.WithStack(err) } for pastureName, execTime := range pastureExecTime { res.Data.Chart.Title = append(res.Data.Chart.Title, pastureName) addFeedTimeStr, sprinkleTimeStr, stirTimeStr := make([]string, 0), make([]string, 0), make([]string, 0) if execTime != nil { addFeedTimeStr = append(addFeedTimeStr, execTime.AddFeedTime.MaxValue, execTime.AddFeedTime.UpMiddleValue, execTime.AddFeedTime.MiddleValue, execTime.AddFeedTime.DownMiddleValue, execTime.AddFeedTime.MinValue) sprinkleTimeStr = append(sprinkleTimeStr, execTime.SprinkleTime.MaxValue, execTime.SprinkleTime.UpMiddleValue, execTime.SprinkleTime.MiddleValue, execTime.SprinkleTime.DownMiddleValue, execTime.SprinkleTime.MinValue) stirTimeStr = append(stirTimeStr, execTime.StirTime.MaxValue, execTime.StirTime.UpMiddleValue, execTime.StirTime.MiddleValue, execTime.StirTime.DownMiddleValue, execTime.StirTime.MinValue) } res.Data.Chart.AddFeedTime = append(res.Data.Chart.AddFeedTime, addFeedTimeStr) res.Data.Chart.SprinkleTime = append(res.Data.Chart.SprinkleTime, sprinkleTimeStr) res.Data.Chart.StirTime = append(res.Data.Chart.StirTime, stirTimeStr) if execTime == nil { continue } tableList := map[string]string{ "title": pastureName, "add_feed_time": "加料时间", "add_feed_time_max_value": execTime.AddFeedTime.MaxValue, "add_feed_time_up_middle_value": execTime.AddFeedTime.UpMiddleValue, "add_feed_time_middle_value": execTime.AddFeedTime.MiddleValue, "add_feed_time_down_middle_value": execTime.AddFeedTime.DownMiddleValue, "add_feed_time_min_value": execTime.AddFeedTime.MinValue, "sprinkle_time": "撒料时间", "sprinkle_time_max_value": execTime.SprinkleTime.MaxValue, "sprinkle_time_up_middle_value": execTime.SprinkleTime.UpMiddleValue, "sprinkle_time_middle_value": execTime.SprinkleTime.MiddleValue, "sprinkle_time_down_middle_value": execTime.SprinkleTime.DownMiddleValue, "sprinkle_time_min_value": execTime.SprinkleTime.MinValue, "stir_time": "搅拌延迟时间", "stir_time_max_value": execTime.StirTime.MaxValue, "stir_time_up_middle_value": execTime.StirTime.UpMiddleValue, "stir_time_middle_value": execTime.StirTime.MiddleValue, "stir_time_down_middle_value": execTime.StirTime.DownMiddleValue, "stir_time_min_value": execTime.StirTime.MinValue, } res.Data.TableList = append(res.Data.TableList, tableList) } return res, nil } func (s *StoreEntry) SprinkleFeedTime(ctx context.Context, req *operationPb.SprinkleFeedTimeRequest) (*model.SprinkleFeedTimeResponse, error) { res := &model.SprinkleFeedTimeResponse{ Code: http.StatusOK, Msg: "ok", Data: &model.SprinkleFeedTimeData{ Chart: &model.SprinkleFeedTimeChart{ Title: make([]string, 0), SprinkleNumberList: make([][]int32, 0), }, TableList: make([]*model.SprinkleFeedTimeTable, 0), }, } pastureSprinkleDataList, 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()) } res.Data.Chart.Title = append(res.Data.Chart.Title, pastureName) 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 } func (s *StoreEntry) FeedMixedAndTmrName(ctx context.Context, req *operationPb.MixedCategoryTmrName) (*model.PastureCommonResponse, 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.PastureCommonRequest{ Name: req.ApiName, ReturnType: "Map", ParamMaps: &model.MixedCategoryTmrNameParams{ PastureId: fmt.Sprintf("%d", pastureId), StartTime: req.StartTime, EndTime: req.EndTime, }, } 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 } func sprinkleExecTimeAnalysis(sprinkleFeedTimeList map[int32]map[int32][]int64) (int32, int32) { var infoSprinkleNumber, errorSprinkleNumber int32 = 0, 0 if len(sprinkleFeedTimeList) <= 0 { return infoSprinkleNumber, errorSprinkleNumber } else { for _, value := range sprinkleFeedTimeList { for _, execTimeList := range value { middleValue := tool.MedianInt64(execTimeList) for _, v := range execTimeList { if v >= middleValue-int64(compareTime) && v <= middleValue+int64(compareTime) { infoSprinkleNumber += 1 } else { errorSprinkleNumber += 1 } } } } } return infoSprinkleNumber, errorSprinkleNumber } func dashboardTopRand(req *operationPb.SearchAnalysisAccuracyRequest, data []*model.PastureTopData) []*model.PastureTopData { if req.TopRandStart < 0 || req.TopRandEnd < 0 || req.TopRandStart > req.TopRandEnd { return data } res := make([]*model.PastureTopData, 0) for _, v := range data { if float64(req.TopRandStart) <= v.Ratio || v.Ratio <= float64(req.TopRandEnd) { res = append(res, v) } } return res }