|
@@ -0,0 +1,290 @@
|
|
|
+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"
|
|
|
+
|
|
|
+ "go.uber.org/multierr"
|
|
|
+ "go.uber.org/zap"
|
|
|
+)
|
|
|
+
|
|
|
+func (s *StoreEntry) SearchPrefAnalysisData(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)
|
|
|
+ }
|
|
|
+
|
|
|
+ res := make(map[int64]*model.PastureAnalysisAccuracyData, 0)
|
|
|
+ wg := sync.WaitGroup{}
|
|
|
+ wg.Add(len(groupPastureList))
|
|
|
+ var muError error
|
|
|
+ for _, pasture := range groupPastureList {
|
|
|
+ go func(p *model.GroupPasture) {
|
|
|
+ response := &model.PastureAnalysisAccuracyResponse{}
|
|
|
+ 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, DashboardAccuracyUrl, p.Id, body, response); err != nil {
|
|
|
+ muError = multierr.Append(muError, err)
|
|
|
+ zaplog.Error("DistributeFeedFormula",
|
|
|
+ zap.String("url", DashboardAccuracyUrl),
|
|
|
+ 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["FeedFormula_Distribute"], FeedFormulaDistributeUrl, string(b), string(resB))
|
|
|
+ s.DB.Create(pastureDataLog)
|
|
|
+ }
|
|
|
+ if response.Code != http.StatusOK {
|
|
|
+ muError = multierr.Append(muError, xerr.Custom(response.Msg))
|
|
|
+ }
|
|
|
+ res[p.Id] = 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,
|
|
|
+ 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.SearchPrefAnalysisData(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 := ""
|
|
|
+ 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
|
|
|
+ }
|
|
|
+
|
|
|
+ mixedFodderAccurateRatioDataList := make([]string, 0)
|
|
|
+ for _, v := range data.MixedFodderAccurateRatio {
|
|
|
+ mixedFodderAccurateRatioDataList = append(mixedFodderAccurateRatioDataList, fmt.Sprintf("%.2f", v.Ratio))
|
|
|
+ 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))
|
|
|
+ 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))
|
|
|
+ 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))
|
|
|
+ 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) {
|
|
|
+ res := &model.GetPastureTopResponse{
|
|
|
+ Code: http.StatusOK,
|
|
|
+ Msg: "ok",
|
|
|
+ Data: &model.PastureTop{
|
|
|
+ MixedFodderAccurateRatio: make([]*model.PastureTopData, 0),
|
|
|
+ MixedFodderCorrectRatio: make([]*model.PastureTopData, 0),
|
|
|
+ SprinkleFodderAccurateRatio: make([]*model.PastureTopData, 0),
|
|
|
+ SprinkleFodderCorrectRatio: make([]*model.PastureTopData, 0),
|
|
|
+ },
|
|
|
+ }
|
|
|
+ analysisAccuracy, err := s.SearchPrefAnalysisData(ctx, req)
|
|
|
+ if err != nil {
|
|
|
+ return nil, xerr.WithStack(err)
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println("========analysisAccuracy=========", analysisAccuracy)
|
|
|
+
|
|
|
+ /*time1, _ := time.ParseInLocation(model.LayoutDateFormat, req.StartDate, time.Local)
|
|
|
+ time2, _ := time.ParseInLocation(model.LayoutDateFormat, req.EndDate, time.Local)
|
|
|
+ timeLen := time2.Sub(time1).Hours() / 24
|
|
|
+
|
|
|
+ mapPastureList := make(map[string][]*model.OptionsAnalysisAccuracy, 0)
|
|
|
+ for _, v := range analysisAccuracy {
|
|
|
+ mapPastureList[v.PastureName] = append(mapPastureList[v.PastureName], v)
|
|
|
+ }*/
|
|
|
+
|
|
|
+ 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
|
|
|
+ }
|
|
|
+ average := allValueRatio / timeLen
|
|
|
+ mixedFodderAccurateRatio = append(mixedFodderAccurateRatio, &model.PastureTopData{
|
|
|
+ PastureName: pastureName,
|
|
|
+ Ratio: average,
|
|
|
+ })
|
|
|
+ }*/
|
|
|
+ sort.Slice(mixedFodderAccurateRatio, func(i, j int) bool {
|
|
|
+ return mixedFodderAccurateRatio[i].Ratio > mixedFodderAccurateRatio[j].Ratio
|
|
|
+ })
|
|
|
+ res.Data.MixedFodderAccurateRatio = mixedFodderAccurateRatio
|
|
|
+ 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
|
|
|
+}
|