123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- 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) {
- healthWarningList := make([]*model.NeckRingHealth, 0)
- sqlQuery := `SELECT aa.pasture_id,aa.cow_id,aa.ear_number,aa.neck_ring_number,aa.lact,aa.calving_age,aa.heat_date,aa.frameid,aa.active_time,
- aa.change_filter,aa.chew_filter,aa.sum_chew,aa.sum_inactive,aa.before_three_sum_chew,aa.min_high,aa.max_high,aa.min_chew,aa.score
- FROM (
- SELECT h.id,h.cow_id,h.pasture_id,h.ear_number,h.neck_ring_number,h.calving_age,h.heat_date,h.frameid,h.lact,
- IF(h.change_filter>-99, h.change_filter, 0) AS change_filter,
- IF(h.filter_chew>-99, h.filter_chew, 0) AS chew_filter,
- (h.sum_rumina +h.sum_intake) AS sum_chew,
- h.sum_inactive,
- (h.before_three_sum_rumina +h.before_three_sum_intake) AS before_three_sum_chew,
- IF(h.sum_min_high>-99, h.sum_min_high, 0) AS min_high,
- IF(h.sum_max_high>-99, h.sum_max_high, 0) AS max_high,
- IF(h.sum_min_chew>-99, h.sum_min_chew, 0) AS min_chew,
- h.score,h.active_time,
- IF(h.cow_id=@cow AND h.heat_date=@date AND h.score>=@score, 0, 1) is_worse, @cow:=h.cow_id, @date:=h.heat_date, @score:=h.score
- FROM neck_active_habit h, (SELECT @cow:=0, @date:='2001-01-01', @score:=100) aaa
- WHERE h.id IN ?
- AND h.score BETWEEN ? AND ?
- AND h.pasture_id = ?
- ) aa WHERE aa.is_worse = ?
- ORDER BY aa.id;`
- if err := e.DB.Raw(sqlQuery, processIds, model.MinScore, model.MaxScore, pastureId, pasturePb.IsShow_Ok).
- Find(&healthWarningList).Error; err != nil {
- zaplog.Error("HealthWarning", zap.Any("error", err), zap.Any("processIds", processIds))
- }
- 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
- }
|