Jelajahi Sumber

analysis: 流产率统计优化

Yi 5 bulan lalu
induk
melakukan
0f036bf86d
3 mengubah file dengan 75 tambahan dan 18 penghapusan
  1. 25 18
      module/backend/analysis.go
  2. 7 0
      util/util.go
  3. 43 0
      util/util_test.go

+ 25 - 18
module/backend/analysis.go

@@ -211,15 +211,16 @@ func (s *StoreEntry) MatingTimely(ctx context.Context, req *pasturePb.MatingTime
 		}, nil
 	}
 	for _, v := range matingTimelyChart {
+		t, _ := time.Parse(model.LayoutDate2, v.RealityDay)
 		switch v.LactGroup {
 		case "0":
-			chart.Lact0 = append(chart.Lact0, []string{fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
+			chart.Lact0 = append(chart.Lact0, []string{fmt.Sprintf("%d", t.Day()), fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
 		case "1":
-			chart.Lact1 = append(chart.Lact1, []string{fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
+			chart.Lact1 = append(chart.Lact1, []string{fmt.Sprintf("%d", t.Day()), fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
 		case "2":
-			chart.Lact2 = append(chart.Lact2, []string{fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
+			chart.Lact2 = append(chart.Lact2, []string{fmt.Sprintf("%d", t.Day()), fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
 		case "3+":
-			chart.Lact3 = append(chart.Lact3, []string{fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
+			chart.Lact3 = append(chart.Lact3, []string{fmt.Sprintf("%d", t.Day()), fmt.Sprintf("%d", v.CalvingAge), v.RealityDay})
 		}
 	}
 
@@ -328,26 +329,33 @@ func (s *StoreEntry) AbortionRate(ctx context.Context, req *pasturePb.AbortionRa
 	}
 	// 历史每月怀孕牛头数量
 	cowPregnantMonthList := make([]*model.CowPregnantMonth, 0)
-	if err = s.DB.Model(new(model.Cow)).
+	pref := s.DB.Model(new(model.CowPregnant)).
 		Select(`
 			COUNT(cow_id) AS cow_count,
-			DATE_FORMAT(FROM_UNIXTIME(updated_at),'%Y-%m-%d') as month`,
-		).Where("status = ?", pasturePb.IsShow_Ok).
-		Where("cow_type = ?", req.CowType).
-		Where("DATE_FORMAT(FROM_UNIXTIME(`created_at`),'%Y-%m-%d') IN ?", lastDayForMonth).
-		Group("month").Find(&cowPregnantMonthList).Error; err != nil {
+			DATE_FORMAT(FROM_UNIXTIME(created_at),'%Y-%m') as month`,
+		).Where("cow_type = ?", req.CowType).
+		Where("DATE_FORMAT(FROM_UNIXTIME(`created_at`),'%Y-%m-%d') IN ?", lastDayForMonth)
+
+	if req.Lact >= 0 {
+		pref.Where("lact = ?", req.Lact)
+	}
+	if err = pref.Group("month").
+		Find(&cowPregnantMonthList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 	// 历史每月流产牛头数量
 	cowAbortionMonthList := make([]*model.CowPregnantMonth, 0)
-	if err = s.DB.Model(new(model.EventAbortion)).
+	pref2 := s.DB.Model(new(model.EventAbortion)).
 		Select(`
 			COUNT(cow_id) AS cow_count,
 			DATE_FORMAT(FROM_UNIXTIME(abortion_at),'%Y-%m') as month`,
-		).Where("status = ?", pasturePb.IsShow_Ok).
-		Where("cow_type = ?", req.CowType).
-		Where("DATE_FORMAT(FROM_UNIXTIME(`created_at`),'%Y-%m') IN = ?", dayTimeList).
-		Group("month").Find(&cowAbortionMonthList).Error; err != nil {
+		).Where("cow_type = ?", req.CowType).
+		Where("DATE_FORMAT(FROM_UNIXTIME(`abortion_at`),'%Y-%m') IN ?", dayTimeList)
+
+	if req.Lact >= 0 {
+		pref2.Where("lact = ?", req.Lact)
+	}
+	if err = pref2.Group("month").Find(&cowAbortionMonthList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
 
@@ -363,14 +371,13 @@ func (s *StoreEntry) AbortionRate(ctx context.Context, req *pasturePb.AbortionRa
 		pregnantCountMonth := int32(0)
 		for _, v := range cowPregnantMonthList {
 			if v.Month == v2.Month {
-				v.CowCount = v2.CowCount
 				pregnantCountMonth = v.CowCount
 			}
 		}
-
 		abortionRateMonth := float64(0)
 		if pregnantCountMonth > 0 && v2.CowCount > 0 {
-			abortionRateMonth = util.Ceil(float64(pregnantCountMonth) / float64(v2.CowCount) * 100)
+			abortionRateMonth = util.RoundToTwoDecimals(float64(v2.CowCount) / float64(pregnantCountMonth) * 100)
+
 		}
 
 		chart.Header = append(chart.Header, v2.Month)

+ 7 - 0
util/util.go

@@ -120,3 +120,10 @@ func GetMonthsInRange(startMonth, endMonth string) ([]string, error) {
 
 	return months, nil
 }
+
+// RoundToTwoDecimals 四舍五入并保留两位小数
+func RoundToTwoDecimals(num float64) float64 {
+	// 使用 math.Round 函数进行四舍五入
+	// 先乘以 100,然后四舍五入,最后除以 100
+	return math.Round(num*100) / 100
+}

+ 43 - 0
util/util_test.go

@@ -130,3 +130,46 @@ func TestGetMonthsInRange(t *testing.T) {
 		})
 	}
 }
+
+func TestRoundToTwoDecimals(t *testing.T) {
+	tests := []struct {
+		exp float64
+		got float64
+	}{
+		{
+			exp: 123.456,
+			got: 123.46,
+		},
+		{
+			exp: 123.455,
+			got: 123.46,
+		},
+		{
+			exp: 123.444,
+			got: 123.44,
+		},
+		{
+			exp: 123.4551,
+			got: 123.46,
+		},
+		{
+			exp: 123.4449,
+			got: 123.44,
+		},
+		{
+			exp: 0,
+			got: 0,
+		},
+		{
+			exp: 0.2,
+			got: 0.2,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run("TestRoundToTwoDecimals", func(t *testing.T) {
+			got := RoundToTwoDecimals(tt.exp)
+			assert.Equal(t, tt.got, got)
+		})
+	}
+}