package crontab import ( "kpt-pasture/model" "kpt-pasture/util" "math" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" "gitee.com/xuyiping_admin/pkg/logger/zaplog" "go.uber.org/zap" ) // HealthWarning 健康预警 create_jbq_update_2024 func (e *Entry) HealthWarning(pastureId int64, processIds []int64) { newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0) if err := e.DB.Model(new(model.NeckActiveHabit)). Where("pasture_id = ?", pastureId). Where("id IN (?)", processIds). Where("score BETWEEN ? AND ?", model.MinScore, model.MaxScore). Order("neck_ring_number,heat_date,frameid"). Find(&newNeckActiveHabitList).Error; err != nil { zaplog.Error("HealthWarning", zap.Any("error", err), zap.Any("processIds", processIds)) } var ( lastCowID int64 = 0 lastHeatDate string = "2001-01-01" lastScore int32 = 100 healthWarningList []*model.NeckRingHealth ) for _, habit := range newNeckActiveHabitList { if habit.ChangeFilter <= -99 { habit.ChangeFilter = 0 } if habit.ChewFilter <= -99 { habit.ChewFilter = 0 } if habit.SumMinHigh <= -99 { habit.SumMinHigh = 0 } if habit.SumMaxHigh <= -99 { habit.SumMaxHigh = 0 } if habit.SumMinChew <= -99 { habit.SumMinChew = 0 } sumChew := habit.SumRumina + habit.SumIntake chew3dago := habit.BeforeThreeSumRumina + habit.BeforeThreeSumIntake isWorse := 1 if habit.CowId == lastCowID && habit.HeatDate == lastHeatDate && habit.Score >= lastScore { isWorse = 0 } lastCowID = habit.CowId lastHeatDate = habit.HeatDate lastScore = habit.Score if isWorse == 1 { newHealthWarning := model.NewNeckRingHealth(habit, sumChew, chew3dago) healthWarningList = append(healthWarningList, newHealthWarning) } } if len(healthWarningList) > 0 { e.updateNeckRingHealth(pastureId, healthWarningList) } } func (e *Entry) updateNeckRingHealth(pastureId int64, healthWarningList []*model.NeckRingHealth) { for _, v := range healthWarningList { startAt := util.TimeParseLocalUnix(v.HeatDate) endAt := util.TimeParseLocalEndUnix(v.HeatDate) isMove := e.isEventCowLog(pastureId, v.CowId, startAt, endAt, pasturePb.EventType_Transfer_Ben) if isMove { v.IsTransferGroup = pasturePb.IsShow_Ok } isDryMilk := e.isEventCowLog(pastureId, v.CowId, startAt, endAt, pasturePb.EventType_Dry_Milk) if isDryMilk { v.IsDryMilk = pasturePb.IsShow_Ok } isImmunization := e.isEventCowLog(pastureId, v.CowId, startAt, endAt, pasturePb.EventType_Immunication) if isImmunization { v.IsImmunization = pasturePb.IsShow_Ok } } zaplog.Info("HealthWarning", zap.Any("healthWarningList", healthWarningList)) if err := e.DB.Model(new(model.NeckRingHealth)). Create(&healthWarningList).Error; err != nil { zaplog.Error("HealthWarning", zap.Any("error", err), zap.Any("healthWarningList", healthWarningList)) } } func (e *Entry) isEventCowLog(pastureId int64, CowId int64, startAt, endAt int64, eventType pasturePb.EventType_Kind) bool { var count int64 eventCowLog := &model.EventCowLog{CowId: CowId} if err := e.DB.Table(eventCowLog.TableName()). Where("pasture_id = ?", pastureId). Where("cow_id = ?", CowId). Where("event_at BETWEEN ? AND ?", startAt, endAt). Where("event_type = ?", eventType). Count(&count).Error; err != nil { return false } return count > 0 } func calculateNewScore(data *model.NeckRingHealth) int32 { otherScore := int32(0) otherScore += calculateMilkFilterScore(data.FilterMilk, data.MaxHigh) if data.IsTransferGroup == pasturePb.IsShow_Ok { otherScore += 3 } if data.IsDryMilk == pasturePb.IsShow_Ok { otherScore += 5 } if data.IsImmunization == pasturePb.IsShow_Ok { otherScore += 12 } return data.Score + otherScore } func calculateMilkFilterScore(milkFilter int32, maxHigh int32) int32 { // 处理NULL值,默认为0 milkFilterValue := int32(0) if milkFilter != 0 { milkFilterValue = milkFilter } // 计算系数:如果maxHigh>50则为0.5,否则为1 coefficient := 1.0 if maxHigh > 50 { coefficient = 0.5 } // 计算中间值:milkFilterValue * 0.3 * coefficient intermediateValue := float64(milkFilterValue) * 0.3 * coefficient // 四舍五入 roundedValue := math.Round(intermediateValue) // 取最小值(roundedValue和0中的较小值) result := int32(math.Min(roundedValue, 0)) return result }