Forráskód Böngészése

indicators: 指标收集

Yi 1 hónapja
szülő
commit
ca950480f1

+ 2 - 1
module/backend/analysis_other.go

@@ -76,7 +76,8 @@ func (s *StoreEntry) CalvingReport(ctx context.Context, req *pasturePb.CalvingRe
 			SUM(CASE WHEN pregnancy_age <= %d THEN 1 ELSE 0 END) AS premature_labor_count,
 			SUM(CASE WHEN pregnancy_age >= %d THEN 1 ELSE 0 END) AS late_labor_count,
 			count(*) as total_count`, req.PrematureLabor, req.LateLabor),
-		).Where("reality_day BETWEEN  ? AND ? ", startDayTimeUnix, endDayTimeUnix)
+		).Where("status = ?", pasturePb.IsShow_Ok).
+		Where("reality_day BETWEEN  ? AND ? ", startDayTimeUnix, endDayTimeUnix)
 
 	if req.AnalysisMethod > 0 {
 		switch req.AnalysisMethod {

+ 34 - 9
module/crontab/cow_cron.go

@@ -56,24 +56,50 @@ func (e *Entry) GenerateAsynqWorkOrder() error {
 	return nil
 }
 
-// Indicators 指标维护
+// Indicators 月度指标维护
 func (e *Entry) Indicators() error {
 	indicatorsDetailsList := make([]*model.IndicatorsDetails, 0)
 	if err := e.DB.Model(new(model.IndicatorsDetails)).
 		Find(&indicatorsDetailsList).Error; err != nil {
 		return err
 	}
-	nowTime := time.Now().Format(model.LayoutMonth)
-	zaplog.Info("Indicators", zap.Any("nowTime", nowTime), zap.Any("indicatorsDetailsList", indicatorsDetailsList))
+
+	pastureList := e.FindPastureList()
+	startTime, endTime := util.GetMonthStartAndEndTimestamp()
+	zaplog.Info("Indicators", zap.Any("startTime", startTime), zap.Any("indicatorsDetailsList", indicatorsDetailsList))
 	for _, indicatorsDetail := range indicatorsDetailsList {
+		pastureIndicatorList := map[int64]string{}
 		switch indicatorsDetail.Kind {
 		case "all_cow":
-			pastureIdAllCow := e.FindPastureAllCow()
-			for pastureId, value := range pastureIdAllCow {
-				e.UpdatePastureIndicators(pastureId, indicatorsDetail, nowTime, fmt.Sprintf("%d", value))
-			}
+			pastureIndicatorList = e.FindPastureAllCow(pastureList)
 		case "calving_interval":
-
+			pastureIndicatorList = e.FindCalvingInterval(pastureList, startTime, endTime)
+		case "output_number":
+			pastureIndicatorList = e.FindOutputNumber(pastureList, startTime, endTime)
+		case "input_number":
+			pastureIndicatorList = e.FindInputNumber(pastureList, startTime, endTime)
+		case "sales_volume":
+			pastureIndicatorList = e.FindSalesVolume(pastureList, startTime, endTime)
+		case "calving_number":
+			pastureIndicatorList = e.FindCalvingNumber(pastureList, startTime, endTime)
+		case "adult_abortion_rate":
+			pastureIndicatorList = e.FindAdultAbortionRate(pastureList, "adult", startTime, endTime)
+		case "youth_abortion_rate":
+			pastureIndicatorList = e.FindAdultAbortionRate(pastureList, "youth", startTime, endTime)
+		case "all_die_number":
+			pastureIndicatorList = e.FindDepartureNumber(pastureList, pasturePb.DepartureType_Death, startTime, endTime)
+		case "disease_number":
+			pastureIndicatorList = e.FindDiseaseNumber(pastureList, startTime, endTime)
+		case "cure_number":
+			pastureIndicatorList = e.FindCureNumber(pastureList, startTime, endTime)
+		case "out_number":
+			pastureIndicatorList = e.FindDepartureNumber(pastureList, pasturePb.DepartureType_Out, startTime, endTime)
+		case "calf_die_number":
+			pastureIndicatorList = e.FindCalfDieNumber(pastureList, pasturePb.DepartureType_Death, startTime, endTime)
+		}
+
+		for pastureId, value := range pastureIndicatorList {
+			e.UpdatePastureIndicators(pastureId, indicatorsDetail, startTime, fmt.Sprintf("%d", value))
 		}
 	}
 
@@ -141,7 +167,6 @@ func (e *Entry) ImmunizationPlan() error {
 			pref.Where("a.pregnancy_age = ?", plan.Value).
 				Where("a.is_pregnant = ?", pasturePb.IsShow_Ok)
 		case pasturePb.ImmunizationConditions_Month:
-			// todo 待实现月份
 			continue
 		case pasturePb.ImmunizationConditions_Admission_Days:
 			pref.Where("a.admission_age = ?", plan.Value)

+ 0 - 65
module/crontab/cow_indicators.go

@@ -1,65 +0,0 @@
-package crontab
-
-import (
-	"errors"
-	"kpt-pasture/model"
-
-	"gorm.io/gorm"
-
-	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
-
-	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
-	"go.uber.org/zap"
-)
-
-// FindPastureAllCow 查询所有牧场牛只总数
-func (e *Entry) FindPastureAllCow() map[int64]int32 {
-	pastureList := e.FindPastureList()
-	res := make(map[int64]int32)
-	for _, pasture := range pastureList {
-		var count int64
-		if err := e.DB.Model(&model.Cow{}).
-			Where("pasture_id = ?", pasture.Id).
-			Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
-			Count(&count).Error; err != nil {
-			zaplog.Error("FindAllCow", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
-		}
-		res[pasture.Id] = int32(count)
-	}
-	return res
-}
-
-func (e *Entry) UpdatePastureIndicators(pastureId int64, indicatorsDetails *model.IndicatorsDetails, date, value string) {
-	where := &model.IndicatorsData{
-		PastureId: pastureId,
-		Date:      date,
-		Kind:      indicatorsDetails.Kind,
-	}
-	data := &model.IndicatorsData{
-		PastureId:    pastureId,
-		CategoryType: indicatorsDetails.CategoryType,
-		CategoryName: indicatorsDetails.CategoryName,
-		Date:         date,
-		Kind:         indicatorsDetails.Kind,
-		Value:        value,
-	}
-
-	var existData model.IndicatorsData
-	if err := e.DB.Model(new(model.IndicatorsData)).
-		Where(where).First(&existData).Error; err != nil {
-		if errors.Is(err, gorm.ErrRecordNotFound) {
-			if err = e.DB.Model(new(model.IndicatorsData)).Create(data).Error; err != nil {
-				zaplog.Error("UpdatePastureIndicators", zap.Any("Create", err))
-			}
-		} else {
-			zaplog.Error("UpdatePastureIndicators", zap.Any("Find", err))
-			return
-		}
-	}
-
-	if err := e.DB.Model(new(model.IndicatorsData)).
-		Where("id = ?", existData.Id).
-		Update("value", value).Error; err != nil {
-		zaplog.Error("UpdatePastureIndicators", zap.Any("Update", err))
-	}
-}

+ 161 - 0
module/crontab/cow_indicators_base.go

@@ -0,0 +1,161 @@
+package crontab
+
+import (
+	"errors"
+	"fmt"
+	"kpt-pasture/model"
+	"time"
+
+	"gorm.io/gorm"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+
+	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
+	"go.uber.org/zap"
+)
+
+// FindPastureAllCow 查询所有牧场牛只总数
+func (e *Entry) FindPastureAllCow(pastureList []*model.AppPastureList) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(&model.Cow{}).
+			Where("pasture_id = ?", pasture.Id).
+			Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindAllCow", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+// FindCalvingInterval 产犊间隔
+func (e *Entry) FindCalvingInterval(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		eventCalvingList := make([]*model.EventCalving, 0)
+		if err := e.DB.Model(new(model.EventCalving)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where("reality_day BETWEEN ? AND ?", startTime, endTime).
+			Find(&eventCalvingList).Error; err != nil {
+			zaplog.Error("FindCalvingInterval", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		cowInterval := make(map[int64]int64)
+		allInterval := int64(0)
+		for _, v := range eventCalvingList {
+			preEventCalving := &model.EventCalving{}
+			if err := e.DB.Model(new(model.EventCalving)).
+				Where("pasture_id = ?", pasture.Id).
+				Where("cow_id = ?", v.CowId).
+				Where("status = ?", pasturePb.IsShow_Ok).
+				Where("reality_day < ?", v.RealityDay).
+				Order("reality_day DESC").
+				First(&preEventCalving).Error; err != nil {
+				if errors.Is(err, gorm.ErrRecordNotFound) {
+					continue
+				} else {
+					zaplog.Error("FindCalvingInterval", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+				}
+			}
+			if preEventCalving.RealityDay > 0 {
+				interval := v.RealityDay - preEventCalving.RealityDay
+				cowInterval[v.CowId] = interval
+				allInterval += interval
+			}
+		}
+		if len(cowInterval) > 0 {
+			res[pasture.Id] = fmt.Sprintf("%d", int32(allInterval/int64(len(cowInterval))))
+		}
+	}
+	return res
+}
+
+// FindOutputNumber 本月销售牛只
+func (e *Entry) FindOutputNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventSale)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("sale_at BETWEEN ? AND ?", startTime, endTime).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindOutputNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+func (e *Entry) FindInputNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventEnter)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("cow_source = ?", pasturePb.CowSource_Buy).
+			Where("enter_at BETWEEN ? AND ?", startTime, endTime).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindInputNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+func (e *Entry) FindSalesVolume(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		saleAllAmount := struct {
+			SaleAllAmount int64 `json:"sale_all_amount"`
+		}{
+			SaleAllAmount: 0,
+		}
+		if err := e.DB.Model(new(model.EventSale)).
+			Select("SUM(sale_all_amount) as sale_all_amount").
+			Where("pasture_id = ?", pasture.Id).
+			Where("sale_at BETWEEN ? AND ?", startTime, endTime).
+			First(&saleAllAmount).Error; err != nil {
+			zaplog.Error("FindSalesVolume", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", saleAllAmount.SaleAllAmount)
+	}
+	return res
+}
+
+func (e *Entry) UpdatePastureIndicators(pastureId int64, indicatorsDetails *model.IndicatorsDetails, dateTime int64, value string) {
+	date := time.Unix(dateTime, 0).Format(model.LayoutDate2)
+	where := &model.IndicatorsData{
+		PastureId: pastureId,
+		Date:      date,
+		Kind:      indicatorsDetails.Kind,
+	}
+	data := &model.IndicatorsData{
+		PastureId:    pastureId,
+		CategoryType: indicatorsDetails.CategoryType,
+		CategoryName: indicatorsDetails.CategoryName,
+		Date:         date,
+		Kind:         indicatorsDetails.Kind,
+		Value:        value,
+	}
+
+	var existData model.IndicatorsData
+	if err := e.DB.Model(new(model.IndicatorsData)).
+		Where(where).First(&existData).Error; err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			if err = e.DB.Model(new(model.IndicatorsData)).Create(data).Error; err != nil {
+				zaplog.Error("UpdatePastureIndicators", zap.Any("Create", err))
+			}
+		} else {
+			zaplog.Error("UpdatePastureIndicators", zap.Any("Find", err))
+			return
+		}
+	}
+
+	if err := e.DB.Model(new(model.IndicatorsData)).
+		Where("id = ?", existData.Id).
+		Update("value", value).Error; err != nil {
+		zaplog.Error("UpdatePastureIndicators", zap.Any("Update", err))
+	}
+}

+ 27 - 0
module/crontab/cow_indicators_breed.go

@@ -0,0 +1,27 @@
+package crontab
+
+import (
+	"fmt"
+	"kpt-pasture/model"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+
+	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
+	"go.uber.org/zap"
+)
+
+func (e *Entry) FindCalvingNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventSale)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where("reality_day BETWEEN ? AND ?", startTime, endTime).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindCalvingNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}

+ 97 - 0
module/crontab/cow_indicators_health.go

@@ -0,0 +1,97 @@
+package crontab
+
+import (
+	"fmt"
+	"kpt-pasture/model"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
+	"go.uber.org/zap"
+)
+
+func (e *Entry) FindAdultAbortionRate(pastureList []*model.AppPastureList, cowType string, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		pref := e.DB.Model(new(model.EventAbortion)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("abortion_at BETWEEN ? AND ?", startTime, endTime).
+			Where("is_append = ?", pasturePb.IsShow_Ok)
+		if cowType == "youth" {
+			pref.Where("lact = ?", 0)
+		}
+		if cowType == "adult" {
+			pref.Where("lact > ?", 0)
+		}
+		if err := pref.Count(&count).Error; err != nil {
+			zaplog.Error("FindAdultAbortionRate", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+func (e *Entry) FindDepartureNumber(pastureList []*model.AppPastureList, departureType pasturePb.DepartureType_Kind, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventDeparture)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("departure_at BETWEEN ? AND ?", startTime, endTime).
+			Where("departure_type = ?", departureType).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindAllDieNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+func (e *Entry) FindDiseaseNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventCowDisease)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("disease_at BETWEEN ? AND ?", startTime, endTime).
+			Where("diagnosed_result = ?", pasturePb.IsShow_Ok).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindDiseaseNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+func (e *Entry) FindCureNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventCowDisease)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("curable_at BETWEEN ? AND ?", startTime, endTime).
+			Where("diagnosed_result = ?", pasturePb.IsShow_Ok).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindCureNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}
+
+func (e *Entry) FindCalfDieNumber(pastureList []*model.AppPastureList, departureType pasturePb.DepartureType_Kind, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var count int64
+		if err := e.DB.Model(new(model.EventDeparture)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("departure_at BETWEEN ? AND ?", startTime, endTime).
+			Where("departure_type = ?", departureType).
+			Where("day_age <= ?", 60).
+			Count(&count).Error; err != nil {
+			zaplog.Error("FindAllDieNumber", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+		res[pasture.Id] = fmt.Sprintf("%d", count)
+	}
+	return res
+}

+ 18 - 0
util/util.go

@@ -492,3 +492,21 @@ func ArrayInt32ToStrings(cowIds []int32, cutset string) string {
 	}
 	return strings.TrimRight(cows, cutset)
 }
+
+// GetMonthStartAndEndTimestamp 获取当前月份的开始时间戳和结束时间戳
+func GetMonthStartAndEndTimestamp() (startTimestamp, endTimestamp int64) {
+	// 获取当前时间
+	now := time.Now()
+
+	// 获取当前月份的第一天
+	startOfMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
+
+	// 获取下一个月份的第一天,然后减去一秒,得到当前月份的最后一天
+	endOfMonth := startOfMonth.AddDate(0, 1, 0).Add(-time.Second)
+
+	// 转换为时间戳
+	startTimestamp = startOfMonth.Unix()
+	endTimestamp = endOfMonth.Unix()
+
+	return startTimestamp, endTimestamp
+}