Quellcode durchsuchen

crontab: indicators update

Yi vor 1 Woche
Ursprung
Commit
e8f79f43bc

+ 2 - 0
model/event_mating.go

@@ -27,6 +27,7 @@ type EventMating struct {
 	MatingTimes       int32                           `json:"matingTimes"`
 	MatingResult      pasturePb.MatingResult_Kind     `json:"matingResult"`
 	MatingResultAt    int64                           `json:"matingResultAt"`
+	RematingAt        int64                           `json:"rematingAt"`
 	ExposeEstrusType  pasturePb.ExposeEstrusType_Kind `json:"exposeEstrusType"`
 	FrozenSemenNumber string                          `json:"frozenSemenNumber"`
 	OperationId       int64                           `json:"operationId"`
@@ -62,6 +63,7 @@ func (e *EventMating) EventReMatingUpdate(matingAt int64) {
 	e.MatingResult = pasturePb.MatingResult_ReMatch
 	e.Status = pasturePb.IsShow_Ok
 	e.MatingResultAt = matingAt
+	e.RematingAt = matingAt
 }
 
 // EventMatingResultUpdate 配种结果更新

+ 20 - 16
model/indicators_data.go

@@ -8,22 +8,21 @@ import (
 )
 
 const (
-	AllCow                           = "all_cow"              // 全群牛头数
-	AdultCow                         = "adult_cow"            // 成母牛头数
-	AvgCalvingInterval               = "avg_calving_interval" // 产犊间隔
-	OutputNumber                     = "output_number"        // 出栏量(销售)
-	InputNumber                      = "input_number"         // 入栏量(购入)
-	SalesVolume                      = "sales_volume"         // 销售额
-	FattenCattleNumber               = "fatten_cattle_number" // 育肥牛头数
-	CalvingNumber                    = "calving_number"       // 产犊事件总数
-	AdultAbortionRate                = "adult_abortion_rate"  //成母牛流产率(全)
-	YouthAbortionRate                = "youth_abortion_rate"  //青年年流产率(全)
-	AllDieNumber                     = "all_die_number"
-	DiseaseNumber                    = "disease_number"
-	CureNumber                       = "cure_number"
-	OutNumber                        = "out_number"
-	CalfDieNumber                    = "calf_die_number"
-	LactationCow                     = "lactation_cow"
+	AllCow                           = "all_cow"                               // 全群牛头数
+	AdultCow                         = "adult_cow"                             // 成母牛头数
+	AvgCalvingInterval               = "avg_calving_interval"                  // 产犊间隔
+	OutputNumber                     = "output_number"                         // 出栏量(销售)
+	InputNumber                      = "input_number"                          // 入栏量(购入)
+	SalesVolume                      = "sales_volume"                          // 销售额
+	FattenCattleNumber               = "fatten_cattle_number"                  // 育肥牛头数
+	CalvingNumber                    = "calving_number"                        // 产犊事件总数
+	YouthAbortionRate                = "youth_abortion_rate"                   // 青年年流产率(全)
+	AllDieNumber                     = "all_die_number"                        // 全群牛死亡数
+	DiseaseNumber                    = "disease_number"                        // 发病头数
+	CureNumber                       = "cure_number"                           // 治愈头数
+	OutNumber                        = "out_number"                            // 淘汰头数
+	CalfDieNumber                    = "calf_die_number"                       // 犊牛死亡头数
+	LactationCow                     = "lactation_cow"                         // 泌乳牛头数
 	DryMilkCow                       = "dry_milk_cow"                          // 干奶牛头数
 	ReserveCow                       = "reserve_cow"                           // 后备牛头数
 	FirstBornSurvivalRate            = "first_born_survival_rate"              // 头胎牛接产成活率
@@ -60,6 +59,11 @@ const (
 	Day60DieRate                     = "day60_die_rate"                        // 60日龄死亡率
 	AdultPrematureBirthRate          = "adult_premature_birth_rate"            // 成母牛早产率
 	YouthPrematureBirthRate          = "youth_premature_birth_rate"            // 青年牛早产率
+	LessThan6monthCalfNumber         = "less_than_6month_calf_number"          // <6月龄犊牛头数
+	AdultCowsPregnancyRate           = "adult_cows_pregnancy_rate"             // 成母牛受胎率
+	Lact1PregnancyRate               = "lact1_pregnancy_rate"                  // 1胎受胎率
+	Lact2PregnancyRate               = "lact2_pregnancy_rate"                  // 2胎受孕率
+	Lact3PregnancyRate               = "lact3_pregnancy_rate"                  // >=3胎受孕率
 )
 
 type IndicatorsData struct {

+ 2 - 3
module/backend/calendar.go

@@ -43,8 +43,8 @@ func (s *StoreEntry) CalendarToDoHistoryList(ctx context.Context, pastureId int6
 	calendarToDoList := make([]*pasturePb.CalendarToDoList, 0)
 	sql := `SELECT a.cow_id,b.pen_name,a.calendar_type_name,a.calendar_type_kind as calendar_type,
 		DATE_FORMAT(FROM_UNIXTIME(a.plan_day), '%Y-%m-%d') AS plan_day,
-		DATE_FORMAT(FROM_UNIXTIME(a.end_day), '%Y-%m-%d') AS end_day,
-		IF(a.reality_day <= 0, '', DATE_FORMAT(FROM_UNIXTIME(a.reality_day), '%Y-%m-%d')) AS reality_day
+		IF(a.end_day <= 0, '', DATE_FORMAT(FROM_UNIXTIME(a.end_day), '%Y-%m-%d')) AS end_day,
+		IF(a.reality_day <= 0, '', DATE_FORMAT(FROM_UNIXTIME(a.reality_day), '%Y-%m-%d')) AS reality_day,
 		a.remaining_days,b.lact,b.ear_number,a.status as is_finish,a.remarks
 		FROM (
 			SELECT cow_id,plan_day,end_day,reality_day,status,remarks,'免疫' as calendar_type_name,1 as calendar_type_kind,TIMESTAMPDIFF(DAY, NOW(), FROM_UNIXTIME(end_day)) AS remaining_days 
@@ -75,7 +75,6 @@ func (s *StoreEntry) CalendarToDoHistoryList(ctx context.Context, pastureId int6
 		return nil, err
 	}
 	return calendarToDoList, nil
-
 }
 
 // CalendarToDoList 获取日历待办列表

+ 2 - 3
module/backend/calendar_more.go

@@ -307,9 +307,8 @@ func (s *StoreEntry) TaskDetail(ctx context.Context, req *pasturePb.CalendarToDo
 		return nil, xerr.WithStack(err)
 	}
 
-	calendarToDoList, total := Paginate(calendarToDoList, req, pagination)
+	calendarToDoList, _ = Paginate(calendarToDoList, req, pagination)
 	taskItemsList := make([]*pasturePb.TaskItems, 0)
-
 	for _, v := range calendarToDoList {
 		if v.CalendarType == pasturePb.CalendarType_Disease {
 			continue
@@ -348,7 +347,7 @@ func (s *StoreEntry) TaskDetail(ctx context.Context, req *pasturePb.CalendarToDo
 		Msg:  "ok",
 		Data: &pasturePb.TaskData{
 			List:     taskItemsList,
-			Total:    total,
+			Total:    int32(len(taskItemsList)),
 			Page:     pagination.Page,
 			PageSize: pagination.PageSize,
 		},

+ 4 - 4
module/backend/event_breed_more.go

@@ -349,11 +349,11 @@ func (s *StoreEntry) MatingBatch(ctx context.Context, req *pasturePb.EventMating
 			// 脖环发情揭发数据
 			if item.ExposeEstrusType == pasturePb.ExposeEstrusType_Neck_Ring {
 				// 新增发情事件数据
-				if err = s.NeckRingEstrusToMating(ctx, userModel, tx, item); err != nil {
+				if err = s.NeckRingEstrusToMating(ctx, tx, userModel, item); err != nil {
 					return xerr.WithStack(err)
 				}
 			} else {
-				if err = s.NaturalEstrusToMating(ctx, userModel, tx, item); err != nil {
+				if err = s.NaturalEstrusToMating(ctx, tx, userModel, item); err != nil {
 					return xerr.WithStack(err)
 				}
 			}
@@ -383,7 +383,7 @@ func (s *StoreEntry) MatingBatch(ctx context.Context, req *pasturePb.EventMating
 }
 
 // NeckRingEstrusToMating 脖环揭发发情去配种牛只
-func (s *StoreEntry) NeckRingEstrusToMating(ctx context.Context, userModel *model.UserModel, tx *gorm.DB, item *model.EventMatingCheckBatchModel) error {
+func (s *StoreEntry) NeckRingEstrusToMating(ctx context.Context, tx *gorm.DB, userModel *model.UserModel, item *model.EventMatingCheckBatchModel) error {
 	// 新增发情事件数据
 	newEstrus := model.NewEventEstrus(
 		userModel.AppPasture.Id, item.Cow, pasturePb.ExposeEstrusType_Neck_Ring,
@@ -407,7 +407,7 @@ func (s *StoreEntry) NeckRingEstrusToMating(ctx context.Context, userModel *mode
 }
 
 // NaturalEstrusToMating 自然发情或者同期去配种牛只
-func (s *StoreEntry) NaturalEstrusToMating(ctx context.Context, userModel *model.UserModel, tx *gorm.DB, item *model.EventMatingCheckBatchModel) error {
+func (s *StoreEntry) NaturalEstrusToMating(ctx context.Context, tx *gorm.DB, userModel *model.UserModel, item *model.EventMatingCheckBatchModel) error {
 	// 获取牛只最近一次配种信息
 	lastEventMating, err := s.FindLastEventMatingByCowId(ctx, userModel.AppPasture.Id, item.Cow.Id)
 	if err != nil {

+ 19 - 5
module/crontab/cow_cron.go

@@ -58,14 +58,20 @@ func (e *Entry) GenerateAsynqWorkOrder() error {
 
 // Indicators 月度指标维护
 func (e *Entry) Indicators() error {
+	nowTime := time.Now().Local()
+	defer func() {
+		zaplog.Info("crontab", zap.Any("Indicators", time.Now().Sub(nowTime).Seconds()))
+	}()
+	// 获取所有指标
 	indicatorsDetailsList := make([]*model.IndicatorsDetails, 0)
-	if err := e.DB.Model(new(model.IndicatorsDetails)).
-		Find(&indicatorsDetailsList).Error; err != nil {
+	if err := e.DB.Model(new(model.IndicatorsDetails)).Find(&indicatorsDetailsList).Error; err != nil {
 		return err
 	}
-
+	// 获取所有牧场
 	pastureList := e.FindPastureList()
+	// 获取当月开始时间和结束时间
 	startTime, endTime := util.GetMonthStartAndEndTimestamp()
+
 	for _, indicatorsDetail := range indicatorsDetailsList {
 		pastureIndicatorList := map[int64]string{}
 		switch indicatorsDetail.Kind {
@@ -85,8 +91,6 @@ func (e *Entry) Indicators() error {
 			pastureIndicatorList = e.FindCalvingNumber(pastureList, startTime, endTime)
 		case model.FattenCattleNumber:
 			pastureIndicatorList = e.FattenCattleNumber(pastureList, startTime, endTime)
-		case model.AdultAbortionRate:
-			pastureIndicatorList = e.FindAdultAbortionRate(pastureList, "adult", startTime, endTime)
 		case model.YouthAbortionRate:
 			pastureIndicatorList = e.FindAdultAbortionRate(pastureList, "youth", startTime, endTime)
 		case model.AllDieNumber:
@@ -173,6 +177,16 @@ func (e *Entry) Indicators() error {
 			pastureIndicatorList = e.PrematureBirthRate(pastureList, startTime, endTime, 60, true)
 		case model.YouthPrematureBirthRate:
 			pastureIndicatorList = e.PrematureBirthRate(pastureList, startTime, endTime, 60, false)
+		case model.LessThan6monthCalfNumber:
+			pastureIndicatorList = e.LessThan6monthCalfNumber(pastureList, startTime, endTime)
+		case model.AdultCowsPregnancyRate:
+			pastureIndicatorList = e.AdultCowsPregnancyRate(pastureList, startTime, endTime)
+		case model.Lact1PregnancyRate:
+			pastureIndicatorList = e.LactPregnancyRate(pastureList, "lact = 1", startTime, endTime)
+		case model.Lact2PregnancyRate:
+			pastureIndicatorList = e.LactPregnancyRate(pastureList, "lact = 2", startTime, endTime)
+		case model.Lact3PregnancyRate:
+			pastureIndicatorList = e.LactPregnancyRate(pastureList, "lact >= 3", startTime, endTime)
 		}
 
 		for pastureId, value := range pastureIndicatorList {

+ 18 - 1
module/crontab/cow_indicators_base.go

@@ -150,7 +150,7 @@ func (e *Entry) FattenCattleNumber(pastureList []*model.AppPastureList, startTim
 		if err := e.DB.Model(new(model.Cow)).
 			Select("COUNT(id) as fatten_cattle_number").
 			Where("pasture_id = ?", pasture.Id).
-			Where("purpose_kind = ?", pasturePb.Purpose_Fatten).
+			Where(e.DB.Where("purpose_kind = ?", pasturePb.Purpose_Fatten).Or("cow_type = ?", pasturePb.CowType_Fattening_Calf)).
 			Count(&fattenCattleNumber).Error; err != nil {
 			zaplog.Error("FindFattenCattleNumber", zap.Any("err", err), zap.Any("pasture", pasture))
 		}
@@ -158,6 +158,23 @@ func (e *Entry) FattenCattleNumber(pastureList []*model.AppPastureList, startTim
 	return res
 }
 
+// LessThan6monthCalfNumber <6月龄犊牛头数
+func (e *Entry) LessThan6monthCalfNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var calfNumber int64
+		if err := e.DB.Model(new(model.Cow)).
+			Select("COUNT(id) as calf_number").
+			Where("pasture_id = ?", pasture.Id).
+			Where("day_age <= ?", 170).
+			Where("lact = ?", 0).
+			Count(&calfNumber).Error; err != nil {
+			zaplog.Error("FindFattenCattleNumber", zap.Any("err", err), zap.Any("pasture", pasture))
+		}
+	}
+	return res
+}
+
 // UpdatePastureIndicators 指标收集,不存在时创建,存在时更新
 func (e *Entry) UpdatePastureIndicators(pastureId int64, indicatorsDetails *model.IndicatorsDetails, dateTime int64, value string) {
 	date := time.Unix(dateTime, 0).Local().Format(model.LayoutMonth)

+ 82 - 0
module/crontab/cow_indicators_breed_more.go

@@ -0,0 +1,82 @@
+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"
+)
+
+// AdultCowsPregnancyRate 成牛受胎率
+func (e *Entry) AdultCowsPregnancyRate(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var (
+			pregnantCount     int64 // 确认怀孕的
+			realityBreedCount int64 // 参与配种的
+		)
+
+		if err := e.DB.Model(new(model.EventMating)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where("mating_result = ?", pasturePb.MatingResult_Pregnant).
+			Where("mating_result_at BETWEEN ? AND ?", startTime, endTime).
+			Count(&pregnantCount).Error; err != nil {
+			zaplog.Error("pregnantCount", zap.Any("err", err))
+		}
+
+		if err := e.DB.Model(new(model.EventMating)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where("reality_day BETWEEN ? AND ?", startTime, endTime).
+			Count(&realityBreedCount).Error; err != nil {
+			zaplog.Error("realityBreedCount", zap.Any("err", err))
+		}
+
+		if realityBreedCount > 0 && pregnantCount > 0 {
+			res[pasture.Id] = fmt.Sprintf("%.2f", float64(pregnantCount)/float64(realityBreedCount))
+		} else {
+			res[pasture.Id] = "0"
+		}
+	}
+	return res
+}
+
+// LactPregnancyRate 母牛不同胎次受胎率
+func (e *Entry) LactPregnancyRate(pastureList []*model.AppPastureList, condition string, startTime, endTime int64) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		var (
+			pregnantCount     int64 // 确认怀孕的
+			realityBreedCount int64 // 参与配种的
+		)
+
+		if err := e.DB.Model(new(model.EventMating)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where(condition).
+			Where("mating_result = ?", pasturePb.MatingResult_Pregnant).
+			Where("mating_result_at BETWEEN ? AND ?", startTime, endTime).
+			Count(&pregnantCount).Error; err != nil {
+			zaplog.Error("pregnantCount", zap.Any("err", err))
+		}
+
+		if err := e.DB.Model(new(model.EventMating)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where(condition).
+			Where("reality_day BETWEEN ? AND ?", startTime, endTime).
+			Count(&realityBreedCount).Error; err != nil {
+			zaplog.Error("realityBreedCount", zap.Any("err", err))
+		}
+
+		if realityBreedCount > 0 && pregnantCount > 0 {
+			res[pasture.Id] = fmt.Sprintf("%.2f", float64(pregnantCount)/float64(realityBreedCount))
+		} else {
+			res[pasture.Id] = "0"
+		}
+	}
+	return res
+}