pen_behavior.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package crontab
  2. import (
  3. "fmt"
  4. "kpt-pasture/model"
  5. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  6. "go.uber.org/zap"
  7. )
  8. // PenBehavior 栏舍行为曲线
  9. func (e *Entry) PenBehavior(pastureId int64, processIds []int64) error {
  10. // 1. 获取颈环原始数据
  11. neckRingOriginalList, err := e.getNeckRingOriginalList(pastureId, processIds)
  12. if err != nil {
  13. return fmt.Errorf("获取颈环原始数据失败: %w", err)
  14. }
  15. // 2. 获取牛只信息
  16. cowMap, err := e.getCowMap(pastureId, neckRingOriginalList)
  17. if err != nil {
  18. return fmt.Errorf("获取牛只信息失败: %w", err)
  19. }
  20. // 3. 处理栏舍行为数据
  21. penData := e.processPenBehaviorData(neckRingOriginalList, cowMap)
  22. // 4. 计算平均值
  23. e.calculateAverages(penData)
  24. return nil
  25. }
  26. // getNeckRingOriginalList 获取颈环原始数据
  27. func (e *Entry) getNeckRingOriginalList(pastureId int64, processIds []int64) ([]*model.NeckRingOriginal, error) {
  28. var neckRingOriginalList []*model.NeckRingOriginal
  29. if err := e.DB.Model(new(model.NeckRingOriginal)).
  30. Where("id IN (?) AND pasture_id = ?", processIds, pastureId).
  31. Order("heat_date,neck_ring_number,frameid").
  32. Find(&neckRingOriginalList).Error; err != nil {
  33. return nil, err
  34. }
  35. return neckRingOriginalList, nil
  36. }
  37. // getCowMap 获取牛只信息映射
  38. func (e *Entry) getCowMap(pastureId int64, neckRingOriginalList []*model.NeckRingOriginal) (map[string]*model.Cow, error) {
  39. // 提取牛只ID
  40. cowIds := make([]int64, 0, len(neckRingOriginalList))
  41. for _, v := range neckRingOriginalList {
  42. cowIds = append(cowIds, v.Id)
  43. }
  44. // 获取牛只信息
  45. cowInfoList, err := e.GetCowByIds(pastureId, cowIds)
  46. if err != nil {
  47. return nil, err
  48. }
  49. // 构建牛只信息映射
  50. cowMap := make(map[string]*model.Cow, len(cowInfoList))
  51. for _, v := range cowInfoList {
  52. if v.NeckRingNumber == "" {
  53. continue
  54. }
  55. cowMap[v.NeckRingNumber] = v
  56. }
  57. return cowMap, nil
  58. }
  59. // processPenBehaviorData 处理栏舍行为数据
  60. func (e *Entry) processPenBehaviorData(neckRingOriginalList []*model.NeckRingOriginal, cowMap map[string]*model.Cow) map[string]*model.PenBehaviorData {
  61. penData := make(map[string]*model.PenBehaviorData, len(neckRingOriginalList))
  62. for _, v := range neckRingOriginalList {
  63. cowInfo, ok := cowMap[v.NeckRingNumber]
  64. if !ok {
  65. zaplog.Error("PenBehavior", zap.Any("neckRingNumber", v.NeckRingNumber))
  66. continue
  67. }
  68. key := fmt.Sprintf("%s_%d_%d", v.ActiveDate, cowInfo.PenId, v.Frameid)
  69. if data, exists := penData[key]; exists {
  70. data.CowCount++
  71. data.AvgHigh += v.High
  72. data.SumRumina += ifThenElse(v.Rumina >= 8, 1, 0)
  73. data.SumIntake += ifThenElse(v.Intake >= 8, 1, 0)
  74. data.SumRest += ifThenElse(v.Inactive >= 8, 1, 0)
  75. data.SumGasp += ifThenElse(v.Gasp >= 8, 1, 0)
  76. } else {
  77. penData[key] = &model.PenBehaviorData{
  78. PastureId: cowInfo.PastureId,
  79. PenId: cowInfo.PenId,
  80. PenName: cowInfo.PenName,
  81. HeatDate: v.ActiveDate,
  82. Frameid: v.Frameid,
  83. CowCount: 1,
  84. AvgHigh: v.High,
  85. }
  86. }
  87. }
  88. return penData
  89. }
  90. // calculateAverages 计算平均值
  91. func (e *Entry) calculateAverages(penData map[string]*model.PenBehaviorData) {
  92. for _, data := range penData {
  93. data.AvgHigh = data.AvgHigh / data.CowCount
  94. }
  95. }
  96. // ifThenElse 条件判断函数
  97. func ifThenElse(condition bool, a, b int32) int32 {
  98. if condition {
  99. return a
  100. }
  101. return b
  102. }