package crontab import ( "fmt" "kpt-pasture/model" "kpt-pasture/util" "time" 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 } // MatingPregnancyRate 第1次配种受胎率/第2次配种受胎率 func (e *Entry) MatingPregnancyRate(pastureList []*model.AppPastureList, kind string, startTime, endTime int64) map[int64]string { res := make(map[int64]string) for _, pasture := range pastureList { if kind != model.FirstMatingPregnancyRate && kind != model.SecondMatingPregnancyRate { res[pasture.Id] = "0" continue } var ( pregnantCount int64 // 确认怀孕的 realityBreedCount int64 // 参与配种的 ) pref1 := 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) if kind == model.FirstMatingPregnancyRate { pref1 = pref1.Where("remating_at = ?", 0) } if kind == model.SecondMatingPregnancyRate { pref1 = pref1.Where("remating_at > ?", 0) } if err := pref1.Count(&pregnantCount).Error; err != nil { zaplog.Error("pregnantCount", zap.Any("err", err)) } pref2 := e.DB.Model(new(model.EventMating)). Where("pasture_id = ?", pasture.Id). Where("status = ?", pasturePb.IsShow_Ok). Where("reality_day BETWEEN ? AND ?", startTime, endTime) if kind == model.FirstMatingPregnancyRate { pref2 = pref2.Where("remating_at = ?", 0) } if kind == model.SecondMatingPregnancyRate { pref2 = pref2.Where("remating_at > ?", 0) } if err := pref2.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 } // Day75DayMatingRate 75天配种率(在群) func (e *Entry) Day75DayMatingRate(pastureList []*model.AppPastureList) map[int64]string { res := make(map[int64]string) for _, pasture := range pastureList { cowList := make([]*model.Cow, 0) if err := e.DB.Model(new(model.Cow)). Where("pasture_id = ?", pasture.Id). Where("calving_age >= ?", 75). Find(&cowList).Error; err != nil { zaplog.Error("matingCount", zap.Any("err", err)) } cowIds := make([]int64, 0) for _, cow := range cowList { cowIds = append(cowIds, cow.Id) } var matingCowCount int64 if err := e.DB.Model(new(model.EventMating)). Where("pasture_id = ?", pasture.Id). Where("status = ?", pasturePb.IsShow_Ok). Where("cow_id IN ?", cowIds). Where("calving_age < ?", 75). Count(&matingCowCount).Error; err != nil { zaplog.Error("matingCount", zap.Any("err", err)) } if len(cowIds) > 0 && matingCowCount > 0 { res[pasture.Id] = fmt.Sprintf("%.2f", float64(matingCowCount)/float64(len(cowIds))) } else { res[pasture.Id] = "0" } } return res } // Day75MonthMatingRate 75天配种率(月度) func (e *Entry) Day75MonthMatingRate(pastureList []*model.AppPastureList, indicatorsId int64) map[int64]string { res := make(map[int64]string) nowTime := time.Now().Local() monthStartAt, monthEndAt := util.GetMonthStartAndEndTimestamp() nowTimeFormat := nowTime.Format(model.LayoutDate2) monthStartAtFormat := time.Unix(monthStartAt, 0).Local().Format(model.LayoutDate2) monthEndAtFormat := time.Unix(monthEndAt, 0).Local().Format(model.LayoutDate2) if nowTimeFormat != monthStartAtFormat || nowTimeFormat != monthEndAtFormat { for _, pasture := range pastureList { res[pasture.Id] = "0" } return res } if nowTimeFormat == monthStartAtFormat { for _, pasture := range pastureList { cowList := make([]*model.Cow, 0) if err := e.DB.Model(new(model.Cow)).Where("pasture_id = ?", pasture.Id). Where("calving_age < ?", 75). Where("sex = ?", pasturePb.Genders_Female). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Find(&cowList).Error; err != nil { zaplog.Error("Day75MonthMatingRate", zap.Any("err", err)) } if len(cowList) > 0 { newIndicatorsCowList := model.NewIndicatorsCowList(pasture.Id, indicatorsId, nowTimeFormat, cowList) if err := e.DB.Model(new(model.IndicatorsCow)). Create(newIndicatorsCowList).Error; err != nil { zaplog.Error("Day75MonthMatingRate", zap.Any("err", err)) } } res[pasture.Id] = "0" } return res } if nowTimeFormat == monthEndAtFormat { for _, pasture := range pastureList { indicatorsCowList := make([]*model.IndicatorsCow, 0) if err := e.DB.Model(new(model.IndicatorsCow)). Where("pasture_id = ?", pasture.Id). Where("indicators_id = ?", indicatorsId). Where("date_time = ?", monthStartAtFormat). Find(&indicatorsCowList).Error; err != nil { zaplog.Error("Day75MonthMatingRate", zap.Any("err", err)) } cowIds := make([]int64, 0) for _, indicatorsCow := range indicatorsCowList { cowIds = append(cowIds, indicatorsCow.CowId) } var historyCowCount int64 if err := e.DB.Table(fmt.Sprintf("%s as cow as a", new(model.Cow).TableName())). Joins("LEFT JOIN %s as b on a.id = b.cow_id", new(model.EventMating).TableName()). Where("a.pasture_id = ?", pasture.Id). Where("a.id IN ?", cowIds). Where("b.status = ?", pasturePb.IsShow_Ok). Where("b.calving_age < ?", 75). Where("a.calving_age >= ?", 75). Count(&historyCowCount).Error; err != nil { zaplog.Error("Day75MonthMatingRate", zap.Any("err", err)) } var currentCowCount int64 if err := e.DB.Model(new(model.Cow)). Where("pasture_id = ?", pasture.Id). Where("calving_age >= ?", 75). Where("sex = ?", pasturePb.Genders_Female). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Count(¤tCowCount).Error; err != nil { zaplog.Error("Day75MonthMatingRate", zap.Any("err", err)) } if currentCowCount > 0 && historyCowCount > 0 { res[pasture.Id] = fmt.Sprintf("%.2f", float64(historyCowCount)/float64(currentCowCount)) } else { res[pasture.Id] = "0" } } } return res } // AvgAdultCowEmptyNumber 成母牛平均空怀天数 func (e *Entry) AvgAdultCowEmptyNumber(pastureList []*model.AppPastureList, startTime, endTime int64) map[int64]string { res := make(map[int64]string) for _, pasture := range pastureList { var v = struct { EmptyDays int64 CowCount int64 }{ EmptyDays: 0, CowCount: 0, } if err := e.DB.Model(new(model.Cow)). Select(` SUM( CASE -- 未孕牛只:空怀天数 = 当前日期 - 产犊日期 WHEN is_pregnant = 2 AND last_calving_at > 0 THEN DATEDIFF( FROM_UNIXTIME(UNIX_TIMESTAMP()), FROM_UNIXTIME(last_calving_at) ) -- 已孕牛只:空怀天数 = 配种结果为怀孕的配种日期 - 产犊日期 WHEN is_pregnant = 1 AND last_mating_at > 0 AND last_calving_at > 0 THEN DATEDIFF( FROM_UNIXTIME(last_mating_at), FROM_UNIXTIME(last_calving_at) ) ELSE 0 END ) AS empty_days,count(*) AS cow_count`). Where("pasture_id = ?", pasture.Id). Where("sex = ?", pasturePb.Genders_Female). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Where("lact >= ?", 1). First(&v). Error; err != nil { zaplog.Error("AvgAdultCowEmptyNumber", zap.Any("err", err)) } if v.CowCount > 0 && v.EmptyDays > 0 { res[pasture.Id] = fmt.Sprintf("%d", v.EmptyDays/v.CowCount) } else { res[pasture.Id] = "0" } } return res } // CowPregnantCheckOkRate 牛孕检怀孕比 func (e *Entry) CowPregnantCheckOkRate(pastureList []*model.AppPastureList, condition string, startTime, endTime int64) map[int64]string { res := make(map[int64]string) for _, pasture := range pastureList { var pregnantCheckOkCount int64 eventPregnantCheckList := make([]*model.EventPregnantCheck, 0) if err := e.DB.Model(new(model.EventPregnantCheck)). Where("pasture_id = ?", pasture.Id). Where("status = ?", pasturePb.IsShow_Ok). Where("reality_day BETWEEN ? AND ?", startTime, endTime). Where(condition). Find(&eventPregnantCheckList).Error; err != nil { zaplog.Error("CowPregnantCheckOkRate", zap.Any("err", err)) } for _, eventPregnantCheck := range eventPregnantCheckList { if eventPregnantCheck.PregnantCheckResult != pasturePb.PregnantCheckResult_Pregnant { continue } pregnantCheckOkCount++ } if pregnantCheckOkCount > 0 && len(eventPregnantCheckList) > 0 { res[pasture.Id] = fmt.Sprintf("%.2f", float64(pregnantCheckOkCount)/float64(len(eventPregnantCheckList))) } else { res[pasture.Id] = "0" } } return res } // CowForbiddenMatingRate 禁配占比 func (e *Entry) CowForbiddenMatingRate(pastureList []*model.AppPastureList, condition string, startTime, endTime int64) map[int64]string { res := make(map[int64]string) for _, pasture := range pastureList { var ( forbiddenMatingCount int64 cowCount int64 ) if err := e.DB.Model(new(model.Cow)). Where("pasture_id = ?", pasture.Id). Where("sex = ?", pasturePb.Genders_Female). Where("admission_status = ?", pasturePb.AdmissionStatus_Admission). Where(condition). Where("lact >= ?", 1). Count(&cowCount).Error; err != nil { zaplog.Error("AdultCowForbiddenMatingRate", zap.Any("err", err)) } if cowCount > 0 { if err := e.DB.Model(new(model.EventForbiddenMating)). Where("pasture_id = ?", pasture.Id). Where("status = ?", pasturePb.IsShow_Ok). Where("lact >= ?", 1). Where("reality_day BETWEEN ? AND ?", startTime, endTime). Count(&forbiddenMatingCount).Error; err != nil { zaplog.Error("AdultCowForbiddenMatingRate", zap.Any("err", err)) } if forbiddenMatingCount > 0 { res[pasture.Id] = fmt.Sprintf("%.2f", float64(forbiddenMatingCount)/float64(cowCount)) } else { res[pasture.Id] = "0" } } else { res[pasture.Id] = "0" } } return res } // CowForbiddenMatingNumber 禁配牛头数 func (e *Entry) CowForbiddenMatingNumber(pastureList []*model.AppPastureList, condition string, startTime, endTime int64) map[int64]string { res := make(map[int64]string) for _, pasture := range pastureList { var forbiddenMatingCount int64 if err := e.DB.Model(new(model.EventForbiddenMating)). Where("pasture_id = ?", pasture.Id). Where("status = ?", pasturePb.IsShow_Ok). Where(condition). Where("reality_day BETWEEN ? AND ?", startTime, endTime). Count(&forbiddenMatingCount).Error; err != nil { zaplog.Error("AdultCowForbiddenMatingRate", zap.Any("err", err)) } if forbiddenMatingCount > 0 { res[pasture.Id] = fmt.Sprintf("%d", forbiddenMatingCount) } else { res[pasture.Id] = "0" } } return res }