neck_ring_health.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package crontab
  2. import (
  3. "kpt-pasture/model"
  4. "kpt-pasture/util"
  5. "math"
  6. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  7. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  8. "go.uber.org/zap"
  9. )
  10. // HealthWarning 健康预警 create_jbq_update_2024
  11. func (e *Entry) HealthWarning(pastureId int64, processIds []int64) {
  12. newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
  13. if err := e.DB.Model(new(model.NeckActiveHabit)).
  14. Where("pasture_id = ?", pastureId).
  15. Where("id IN (?)", processIds).
  16. Where("score BETWEEN ? AND ?", model.MinScore, model.MaxScore).
  17. Order("neck_ring_number,heat_date,frameid").
  18. Find(&newNeckActiveHabitList).Error; err != nil {
  19. zaplog.Error("HealthWarning", zap.Any("error", err), zap.Any("processIds", processIds))
  20. }
  21. var (
  22. lastCowID int64 = 0
  23. lastHeatDate string = "2001-01-01"
  24. lastScore int32 = 100
  25. healthWarningList []*model.NeckRingHealth
  26. )
  27. for _, habit := range newNeckActiveHabitList {
  28. if habit.ChangeFilter <= -99 {
  29. habit.ChangeFilter = 0
  30. }
  31. if habit.ChewFilter <= -99 {
  32. habit.ChewFilter = 0
  33. }
  34. if habit.SumMinHigh <= -99 {
  35. habit.SumMinHigh = 0
  36. }
  37. if habit.SumMaxHigh <= -99 {
  38. habit.SumMaxHigh = 0
  39. }
  40. if habit.SumMinChew <= -99 {
  41. habit.SumMinChew = 0
  42. }
  43. sumChew := habit.SumRumina + habit.SumIntake
  44. chew3dago := habit.BeforeThreeSumRumina + habit.BeforeThreeSumIntake
  45. isWorse := 1
  46. if habit.CowId == lastCowID && habit.HeatDate == lastHeatDate && habit.Score >= lastScore {
  47. isWorse = 0
  48. }
  49. lastCowID = habit.CowId
  50. lastHeatDate = habit.HeatDate
  51. lastScore = habit.Score
  52. if isWorse == 1 {
  53. newHealthWarning := model.NewNeckRingHealth(habit, sumChew, chew3dago)
  54. healthWarningList = append(healthWarningList, newHealthWarning)
  55. }
  56. }
  57. if len(healthWarningList) > 0 {
  58. e.updateNeckRingHealth(pastureId, healthWarningList)
  59. }
  60. }
  61. func (e *Entry) updateNeckRingHealth(pastureId int64, healthWarningList []*model.NeckRingHealth) {
  62. for _, v := range healthWarningList {
  63. startAt := util.TimeParseLocalUnix(v.HeatDate)
  64. endAt := util.TimeParseLocalEndUnix(v.HeatDate)
  65. isMove := e.isEventCowLog(pastureId, v.CowId, startAt, endAt, pasturePb.EventType_Transfer_Ben)
  66. if isMove {
  67. v.IsTransferGroup = pasturePb.IsShow_Ok
  68. }
  69. isDryMilk := e.isEventCowLog(pastureId, v.CowId, startAt, endAt, pasturePb.EventType_Dry_Milk)
  70. if isDryMilk {
  71. v.IsDryMilk = pasturePb.IsShow_Ok
  72. }
  73. isImmunization := e.isEventCowLog(pastureId, v.CowId, startAt, endAt, pasturePb.EventType_Immunication)
  74. if isImmunization {
  75. v.IsImmunization = pasturePb.IsShow_Ok
  76. }
  77. }
  78. zaplog.Info("HealthWarning", zap.Any("healthWarningList", healthWarningList))
  79. if err := e.DB.Model(new(model.NeckRingHealth)).
  80. Create(&healthWarningList).Error; err != nil {
  81. zaplog.Error("HealthWarning", zap.Any("error", err), zap.Any("healthWarningList", healthWarningList))
  82. }
  83. }
  84. func (e *Entry) isEventCowLog(pastureId int64, CowId int64, startAt, endAt int64, eventType pasturePb.EventType_Kind) bool {
  85. var count int64
  86. eventCowLog := &model.EventCowLog{CowId: CowId}
  87. if err := e.DB.Table(eventCowLog.TableName()).
  88. Where("pasture_id = ?", pastureId).
  89. Where("cow_id = ?", CowId).
  90. Where("event_at BETWEEN ? AND ?", startAt, endAt).
  91. Where("event_type = ?", eventType).
  92. Count(&count).Error; err != nil {
  93. return false
  94. }
  95. return count > 0
  96. }
  97. func calculateNewScore(data *model.NeckRingHealth) int32 {
  98. otherScore := int32(0)
  99. otherScore += calculateMilkFilterScore(data.FilterMilk, data.MaxHigh)
  100. if data.IsTransferGroup == pasturePb.IsShow_Ok {
  101. otherScore += 3
  102. }
  103. if data.IsDryMilk == pasturePb.IsShow_Ok {
  104. otherScore += 5
  105. }
  106. if data.IsImmunization == pasturePb.IsShow_Ok {
  107. otherScore += 12
  108. }
  109. return data.Score + otherScore
  110. }
  111. func calculateMilkFilterScore(milkFilter int32, maxHigh int32) int32 {
  112. // 处理NULL值,默认为0
  113. milkFilterValue := int32(0)
  114. if milkFilter != 0 {
  115. milkFilterValue = milkFilter
  116. }
  117. // 计算系数:如果maxHigh>50则为0.5,否则为1
  118. coefficient := 1.0
  119. if maxHigh > 50 {
  120. coefficient = 0.5
  121. }
  122. // 计算中间值:milkFilterValue * 0.3 * coefficient
  123. intermediateValue := float64(milkFilterValue) * 0.3 * coefficient
  124. // 四舍五入
  125. roundedValue := math.Round(intermediateValue)
  126. // 取最小值(roundedValue和0中的较小值)
  127. result := int32(math.Min(roundedValue, 0))
  128. return result
  129. }