瀏覽代碼

crontab: health update

Yi 1 周之前
父節點
當前提交
06cf053b65

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20250612030131-3c8b446ca813
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20250613015007-39c38d700b04
 	gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eclipse/paho.mqtt.golang v1.4.3

+ 2 - 0
go.sum

@@ -156,6 +156,8 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20250612024540-e99718a813f5 h1:wamhokmj
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250612024540-e99718a813f5/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250612030131-3c8b446ca813 h1:ttDGhXoyHlmBy+R7WiiDU95VjVYjZfR2sx16VQ5B9KI=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250612030131-3c8b446ca813/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250613015007-39c38d700b04 h1:sl0O3loQUllFaQKpEWzLxYo6X3JSA1XkkZyG1+jAelA=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250613015007-39c38d700b04/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b h1:w05MxH7yqveRlaRbxHhbif5YjPrJFodRPfOjYhXn7Zk=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
 gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d h1:vBXmMRggF7mZVPGRDgavZ87igJgkezwX0a3v1/XtIMQ=

+ 1 - 0
model/event_cow_disease.go

@@ -150,6 +150,7 @@ func (e EventCowDiseaseSlice) ToPB(healthStatusMap map[pasturePb.HealthStatus_Ki
 			LastPrescriptionName:  v.LastPrescriptionName,
 			LastTreatedTimeFormat: lastTreatedTimeFormat,
 			OnsetDays:             onsetDays,
+			ExposeDiseaseType:     v.ExposeDiseaseType,
 		}
 	}
 	return res

+ 2 - 3
module/backend/dashboard_more.go

@@ -103,14 +103,13 @@ func (s *StoreEntry) NeckRingWarning(ctx context.Context) (*pasturePb.IndexNeckR
 	}
 
 	healthWarningNumber := int64(0)
-	// todo 待测试
-	/*if err = s.DB.Model(new(model.NeckRingHealthWarning)).
+	if err = s.DB.Model(new(model.NeckRingHealthWarning)).
 		Where("pasture_id = ?", userModel.AppPasture.Id).
 		Where("is_show = ?", pasturePb.IsShow_Ok).
 		Group("cow_id").
 		Count(&healthWarningNumber).Error; err != nil {
 		zaplog.Error("NeckRingWarning", zap.Any("estrusWarningNumber", err))
-	}*/
+	}
 
 	return &pasturePb.IndexNeckRingResponse{
 		Code: http.StatusOK,

+ 0 - 3
module/backend/neck_ring_warning.go

@@ -128,9 +128,6 @@ func (s *StoreEntry) NeckRingWarningHealthCowList(ctx context.Context, req *past
 		return nil, xerr.WithStack(err)
 	}
 
-	// Todo : 待优化
-	neckWaringHealthList = make([]*model.NeckRingHealthWarning, 0)
-
 	warningHealthLevelMap := s.WarningHealthLevelMap()
 	cowMap := make(map[int64]*model.Cow)
 	eventLogMap := make(map[int64]string)

+ 162 - 0
module/crontab/health_waning.go

@@ -0,0 +1,162 @@
+package crontab
+
+import (
+	"fmt"
+	"kpt-pasture/model"
+	"time"
+
+	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+
+	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
+	"gitee.com/xuyiping_admin/pkg/xerr"
+	"go.uber.org/zap"
+)
+
+func (e *Entry) NeckRingHealthWarning() error {
+	pastureList := e.FindPastureList()
+	if pastureList == nil || len(pastureList) == 0 {
+		return nil
+	}
+	for _, pasture := range pastureList {
+
+		e.DB.Model(new(model.NeckRingHealthWarning)).
+			Where("pasture_id = ?", pasture.Id).
+			Delete(new(model.NeckRingHealthWarning))
+
+		if err := e.UpdateNeckRingHealth(pasture.Id); err != nil {
+			zaplog.Error("NeckRingHealthWarning",
+				zap.Any("UpdateNeckRingHealth", err),
+				zap.Any("pasture", pasture),
+			)
+		}
+	}
+	return nil
+}
+
+func (e *Entry) UpdateNeckRingHealth(pastureId int64) error {
+	neckRingConfigureList, err := e.FindSystemNeckRingConfigure(pastureId)
+	if err != nil {
+		return xerr.WithStack(err)
+	}
+	healthValue := int32(0)
+	for _, v := range neckRingConfigureList {
+		if v.Name != model.HealthWarning {
+			continue
+		}
+		healthValue = int32(v.Value)
+	}
+
+	newNeckRingHealthWarningList, err := e.FindNewNeckRingHealthWarning(pastureId, healthValue)
+	if err != nil {
+		return xerr.WithStack(err)
+	}
+
+	if len(newNeckRingHealthWarningList) > 0 {
+		if err = e.DB.Model(new(model.NeckRingHealthWarning)).
+			Create(&newNeckRingHealthWarningList).Error; err != nil {
+			zaplog.Error("UpdateNeckRingHealth",
+				zap.Any("error", err),
+				zap.Any("newNeckRingHealthWarningList", newNeckRingHealthWarningList),
+			)
+		}
+	}
+	return nil
+}
+
+func (e *Entry) FindNewNeckRingHealthWarning(pastureId int64, healthValue int32) ([]*model.NeckRingHealthWarning, error) {
+	nowTime := time.Now().Local()
+	startTime := nowTime.AddDate(0, 0, -1).Format(model.LayoutDate2)
+
+	type MaxId struct {
+		Id int64
+	}
+
+	maxIds := make([]*MaxId, 0)
+	sqlQuery := fmt.Sprintf(`SELECT MAX(d.id) AS id FROM neck_ring_health d 
+		WHERE d.heat_date>= %s AND d.pasture_id = %d AND NOT EXISTS 
+		(SELECT 1 FROM neck_active_habit h WHERE h.cow_id=d.cow_id AND h.heat_date=%s AND d.heat_date=%s)
+		GROUP BY d.cow_id`, startTime, pastureId, nowTime.Format(model.LayoutDate2), startTime)
+	if err := e.DB.Raw(sqlQuery).
+		Scan(&maxIds).Error; err != nil {
+		zaplog.Error("FindNewNeckRingHealthWarning", zap.Any("error", err), zap.Any("sqlQuery", sqlQuery))
+		return nil, xerr.WithStack(err)
+	}
+
+	neckRingHealthList := make([]*model.NeckRingHealth, 0)
+	if len(maxIds) > 0 {
+		if err := e.DB.Model(new(model.NeckRingHealth)).
+			Where("pasture_id = ?", pastureId).
+			Where("heat_date >= ?", startTime).
+			Where("id IN (?)", maxIds).
+			Group("cow_id").
+			Find(&neckRingHealthList).Error; err != nil {
+			return nil, xerr.WithStack(err)
+		}
+	}
+
+	newNeckRingHealthWarningList := make([]*model.NeckRingHealthWarning, 0)
+	for _, v := range neckRingHealthList {
+		if v.HeatDate == "" {
+			continue
+		}
+		cowInfo, err := e.GetCowById(pastureId, v.CowId)
+		if err != nil || cowInfo == nil {
+			continue
+		}
+		newScore := calculateNewScore(v)
+		zaplog.Info("calculateNewScore",
+			zap.Any("newScore", newScore),
+			zap.Any("v", v),
+			zap.Any("healthValue", healthValue),
+			zap.Any("cowInfo", cowInfo),
+		)
+		if newScore > healthValue {
+			continue
+		}
+
+		if e.HistoryNeckRingHealthWarning(pastureId, cowInfo.NeckRingNumber, v.HeatDate) {
+			continue
+		}
+
+		if e.FindNeckRingError(pastureId, cowInfo.NeckRingNumber) {
+			continue
+		}
+
+		newNeckRingHealthWarning := model.NewNeckRingHealthWarning(pastureId, v, cowInfo, newScore)
+		zaplog.Info("newNeckRingHealthWarning",
+			zap.Any("newNeckRingHealthWarning", newNeckRingHealthWarning),
+			zap.Any("pastureId", pastureId),
+			zap.Any("neckRingHealth", v),
+			zap.Any("cowInfo", cowInfo),
+			zap.Any("newScore", newScore),
+		)
+		newNeckRingHealthWarningList = append(newNeckRingHealthWarningList, newNeckRingHealthWarning)
+	}
+	return newNeckRingHealthWarningList, nil
+}
+
+func (e *Entry) HistoryNeckRingHealthWarning(pastureId int64, neckRingNumber string, heatDate string) bool {
+	var count int64
+	if err := e.DB.Model(new(model.NeckRingHealthWarning)).
+		Where("pasture_id = ?", pastureId).
+		Where("neck_ring_number = ?", neckRingNumber).
+		Where("heat_date = ?", heatDate).
+		Where("is_show = ?", pasturePb.IsShow_Ok).
+		Count(&count).Error; err != nil {
+		return false
+	}
+	return count > 0
+}
+
+func (e *Entry) FindNeckRingError(pastureId int64, neckRingNumber string) bool {
+	var count int64
+	if err := e.DB.Model(new(model.NeckRing)).
+		Where("pasture_id = ?", pastureId).
+		Where("neck_ring_number = ?", neckRingNumber).
+		Where("status = ?", pasturePb.IsShow_No).
+		Where("error_kind = ?", pasturePb.NeckRingNumberError_Suspected_Fall_Off).
+		Count(&count).Error; err != nil {
+		return false
+	}
+	return count > 0
+}

+ 0 - 136
module/crontab/health_warning.go → module/crontab/neck_ring_health.go

@@ -4,12 +4,9 @@ import (
 	"kpt-pasture/model"
 	"kpt-pasture/util"
 	"math"
-	"time"
 
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 
-	"gitee.com/xuyiping_admin/pkg/xerr"
-
 	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
 	"go.uber.org/zap"
 )
@@ -113,57 +110,6 @@ func (e *Entry) isEventCowLog(pastureId int64, CowId int64, startAt, endAt int64
 	return count > 0
 }
 
-func (e *Entry) NeckRingHealthWarning() error {
-	pastureList := e.FindPastureList()
-	if pastureList == nil || len(pastureList) == 0 {
-		return nil
-	}
-	for _, pasture := range pastureList {
-
-		e.DB.Model(new(model.NeckRingHealthWarning)).
-			Where("pasture_id = ?", pasture.Id).
-			Delete(new(model.NeckRingHealthWarning))
-
-		if err := e.UpdateNeckRingHealth(pasture.Id); err != nil {
-			zaplog.Error("NeckRingHealthWarning",
-				zap.Any("UpdateNeckRingHealth", err),
-				zap.Any("pasture", pasture),
-			)
-		}
-	}
-	return nil
-}
-
-func (e *Entry) UpdateNeckRingHealth(pastureId int64) error {
-	neckRingConfigureList, err := e.FindSystemNeckRingConfigure(pastureId)
-	if err != nil {
-		return xerr.WithStack(err)
-	}
-	healthValue := int32(0)
-	for _, v := range neckRingConfigureList {
-		if v.Name != model.HealthWarning {
-			continue
-		}
-		healthValue = int32(v.Value)
-	}
-
-	newNeckRingHealthWarningList, err := e.FindNewNeckRingHealthWarning(pastureId, healthValue)
-	if err != nil {
-		return xerr.WithStack(err)
-	}
-
-	if len(newNeckRingHealthWarningList) > 0 {
-		if err = e.DB.Model(new(model.NeckRingHealthWarning)).
-			Create(&newNeckRingHealthWarningList).Error; err != nil {
-			zaplog.Error("UpdateNeckRingHealth",
-				zap.Any("error", err),
-				zap.Any("newNeckRingHealthWarningList", newNeckRingHealthWarningList),
-			)
-		}
-	}
-	return nil
-}
-
 func calculateNewScore(data *model.NeckRingHealth) int32 {
 	otherScore := int32(0)
 
@@ -206,85 +152,3 @@ func calculateMilkFilterScore(milkFilter int32, maxHigh int32) int32 {
 
 	return result
 }
-
-func (e *Entry) FindNewNeckRingHealthWarning(pastureId int64, healthValue int32) ([]*model.NeckRingHealthWarning, error) {
-	nowTime := time.Now().Local()
-	//endTime := nowTime.Format(model.LayoutDate2)
-	startTime := nowTime.AddDate(0, 0, -1).Format(model.LayoutDate2)
-	neckRingHealthList := make([]*model.NeckRingHealth, 0)
-	if err := e.DB.Model(new(model.NeckRingHealth)).
-		Select(`MAX(id) AS id,heat_date,neck_ring_number,cow_id,score,max_high,created_at,min_high,min_chew,
-		min_intake,sum_chew,before_three_sum_chew`).
-		Where("pasture_id = ?", pastureId).
-		Where("heat_date >= ?", startTime).
-		Group("cow_id").
-		Find(&neckRingHealthList).Error; err != nil {
-		return nil, xerr.WithStack(err)
-	}
-
-	newNeckRingHealthWarningList := make([]*model.NeckRingHealthWarning, 0)
-	for _, v := range neckRingHealthList {
-		if v.HeatDate == "" {
-			continue
-		}
-		cowInfo, err := e.GetCowById(pastureId, v.CowId)
-		if err != nil || cowInfo == nil {
-			continue
-		}
-		newScore := calculateNewScore(v)
-		zaplog.Info("calculateNewScore",
-			zap.Any("newScore", newScore),
-			zap.Any("v", v),
-			zap.Any("healthValue", healthValue),
-			zap.Any("cowInfo", cowInfo),
-		)
-		if newScore > healthValue {
-			continue
-		}
-
-		if e.HistoryNeckRingHealthWarning(pastureId, cowInfo.NeckRingNumber, v.HeatDate) {
-			continue
-		}
-
-		if e.FindNeckRingError(pastureId, cowInfo.NeckRingNumber) {
-			continue
-		}
-
-		newNeckRingHealthWarning := model.NewNeckRingHealthWarning(pastureId, v, cowInfo, newScore)
-		zaplog.Info("newNeckRingHealthWarning",
-			zap.Any("newNeckRingHealthWarning", newNeckRingHealthWarning),
-			zap.Any("pastureId", pastureId),
-			zap.Any("neckRingHealth", v),
-			zap.Any("cowInfo", cowInfo),
-			zap.Any("newScore", newScore),
-		)
-		newNeckRingHealthWarningList = append(newNeckRingHealthWarningList, newNeckRingHealthWarning)
-	}
-	return newNeckRingHealthWarningList, nil
-}
-
-func (e *Entry) HistoryNeckRingHealthWarning(pastureId int64, neckRingNumber string, heatDate string) bool {
-	var count int64
-	if err := e.DB.Model(new(model.NeckRingHealthWarning)).
-		Where("pasture_id = ?", pastureId).
-		Where("neck_ring_number = ?", neckRingNumber).
-		Where("heat_date = ?", heatDate).
-		Where("is_show = ?", pasturePb.IsShow_Ok).
-		Count(&count).Error; err != nil {
-		return false
-	}
-	return count > 0
-}
-
-func (e *Entry) FindNeckRingError(pastureId int64, neckRingNumber string) bool {
-	var count int64
-	if err := e.DB.Model(new(model.NeckRing)).
-		Where("pasture_id = ?", pastureId).
-		Where("neck_ring_number = ?", neckRingNumber).
-		Where("status = ?", pasturePb.IsShow_No).
-		Where("error_kind = ?", pasturePb.NeckRingNumberError_Suspected_Fall_Off).
-		Count(&count).Error; err != nil {
-		return false
-	}
-	return count > 0
-}