Browse Source

event: update

Yi 2 weeks ago
parent
commit
b12eb36f46

+ 7 - 8
module/backend/event_breed_more.go

@@ -7,7 +7,6 @@ import (
 	"kpt-pasture/model"
 	"kpt-pasture/util"
 	"net/http"
-	"strings"
 
 	"go.uber.org/zap"
 
@@ -30,9 +29,9 @@ func (s *StoreEntry) PregnantCheckList(ctx context.Context, req *pasturePb.Searc
 		Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())).
 		Where("a.pasture_id = ?", userModel.AppPasture.Id).
 		Where("a.status = ?", pasturePb.IsShow_Ok)
-	if len(req.CowId) > 0 {
-		cowIds := strings.Split(req.CowId, ",")
-		pref.Where("a.cow_id IN ?", cowIds)
+
+	if req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt {
+		pref.Where("a.reality_day BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt)
 	}
 
 	if req.EarNumber != "" {
@@ -289,15 +288,15 @@ func (s *StoreEntry) MatingList(ctx context.Context, req *pasturePb.SearchEventR
 		Where("mating_result > ?", pasturePb.MatingResult_Invalid).
 		Where("status = ?", pasturePb.IsShow_Ok).
 		Where("pasture_id = ?", userModel.AppPasture.Id)
-	if len(req.CowId) > 0 {
-		cowIds := strings.Split(req.CowId, ",")
-		pref.Where("cow_id IN ?", cowIds)
-	}
 
 	if req.EarNumber != "" {
 		pref.Where("ear_number = ?", req.EarNumber)
 	}
 
+	if req.StartDayAt > 0 && req.EndDayAt > 0 && req.StartDayAt <= req.EndDayAt {
+		pref.Where("reality_day BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt)
+	}
+
 	if err = pref.Order("id desc").
 		Count(&count).Limit(int(pagination.PageSize)).
 		Offset(int(pagination.PageOffset)).

+ 660 - 0
module/crontab/neck_ring_calculate.go

@@ -0,0 +1,660 @@
+package crontab
+
+import (
+	"fmt"
+	"kpt-pasture/model"
+	"math"
+	"sort"
+	"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) NeckRingCalculate() error {
+	pastureList := e.FindPastureList()
+	if pastureList == nil || len(pastureList) == 0 {
+		return nil
+	}
+
+	if calculateIsRunning {
+		return nil
+	}
+	defer func() {
+		calculateIsRunning = false
+	}()
+
+	calculateIsRunning = true
+	for _, pasture := range pastureList {
+		if err := e.EntryUpdateActiveHabit(pasture.Id); err != nil {
+			zaplog.Error("NeckRingCalculate", zap.Any("err", err), zap.Any("pasture", pasture))
+		}
+		zaplog.Info(fmt.Sprintf("NeckRingCalculate Success %d", pasture.Id))
+	}
+	return nil
+}
+
+func (e *Entry) EntryUpdateActiveHabit(pastureId int64) (err error) {
+	// 获取这段执行数据内最大日期和最小日期
+	xToday := &XToday{}
+	systemConfigureList, err := e.GetSystemNeckRingConfigure(pastureId)
+	if err != nil {
+		return xerr.WithStack(err)
+	}
+	for _, v := range systemConfigureList {
+		switch v.Name {
+		case model.MaxHabit:
+			xToday.LastMaxHabitId = v.Value
+		case model.High:
+			xToday.High = int32(v.Value)
+		case model.Rumina:
+			xToday.Rumina = int32(v.Value)
+		case model.XRuminaDisc:
+			xToday.XRuminaDisc = int32(v.Value)
+		case model.XChangeDiscount:
+			xToday.XChangeDiscount = int32(v.Value)
+		case model.WeeklyActive:
+			xToday.WeeklyActive = int32(v.Value)
+		}
+	}
+
+	currMaxHabit := &model.NeckActiveHabit{}
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id > ?", xToday.LastMaxHabitId).
+		Where("pasture_id = ?", pastureId).
+		Where("is_show = ?", pasturePb.IsShow_No).
+		Order("id desc").
+		First(currMaxHabit).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+
+	if currMaxHabit.Id <= 0 || currMaxHabit.Id <= xToday.LastMaxHabitId {
+		return nil
+	}
+
+	xToday.CurrMaxHabitId = currMaxHabit.Id
+	var processIds []int64
+	// 更新活动滤波
+	processIds, err = e.FirstFilterUpdate(pastureId, xToday)
+	if err != nil {
+		zaplog.Error("NeckRingCalculate", zap.Any("FirstFilterUpdate", err), zap.Any("xToday", xToday))
+	}
+	zaplog.Info("NeckRingCalculate", zap.Any("xToday", xToday), zap.Any("processIds", processIds))
+	if len(processIds) <= 0 {
+		return nil
+	}
+
+	if err = e.WeeklyUpdateActiveHabit(pastureId, processIds, xToday); err != nil {
+		zaplog.Error("NeckRingCalculate", zap.Any("WeeklyUpdateActiveHabit", err), zap.Any("xToday", xToday))
+	}
+
+	if err = e.Before3DaysNeckActiveHabit(pastureId, processIds, xToday); err != nil {
+		zaplog.Error("NeckRingCalculate", zap.Any("Before3DaysNeckActiveHabit", err), zap.Any("xToday", xToday))
+	}
+	// 二次更新滤波
+	if err = e.SecondUpdateChangeFilter(pastureId, xToday); err != nil {
+		zaplog.Error("NeckRingCalculate", zap.Any("SecondUpdateChangeFilter", err), zap.Any("xToday", xToday))
+	}
+
+	// 活动量校正系数和健康评分
+	if err = e.FilterCorrectAndScoreUpdate(pastureId, processIds, xToday); err != nil {
+		zaplog.Error("NeckRingCalculate", zap.Any("ActivityVolumeChanges", err), zap.Any("xToday", xToday))
+	}
+
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		Where("pasture_id = ?", pastureId).
+		Where("is_show = ?", pasturePb.IsShow_No).
+		Where("change_filter = ?", model.InitChangeFilter).
+		Updates(map[string]interface{}{
+			"change_filter": model.DefaultChangeFilter,
+			"rumina_filter": model.DefaultRuminaFilter,
+			"chew_filter":   model.DefaultChewFilter,
+		}).Error; err != nil {
+		zaplog.Error("EntryUpdateActiveHabit", zap.Any("change_filter", err), zap.Any("xToday", xToday))
+	}
+
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		Where("pasture_id = ?", pastureId).
+		Where("change_filter < ?", 0).
+		Where("filter_correct < ?", model.DefaultFilterCorrect).
+		Updates(map[string]interface{}{
+			"filter_correct": model.DefaultFilterCorrect,
+		}).Error; err != nil {
+		zaplog.Error("EntryUpdateActiveHabit", zap.Any("filter_correct", err), zap.Any("xToday", xToday))
+	}
+
+	// 插入群体校正表
+	if err = e.UpdateChangeAdJust(pastureId, xToday); err != nil {
+		zaplog.Error("EntryUpdateActiveHabit", zap.Any("UpdateChangeAdJust", err), zap.Any("xToday", xToday))
+	}
+
+	// 更新所有的显示状态为否的记录为是
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		Where("pasture_id = ?", pastureId).
+		Update("is_show", pasturePb.IsShow_Ok).Error; err != nil {
+		zaplog.Error("UpdateChangeAdJust-2", zap.Any("error", err), zap.Any("xToday", xToday))
+	}
+
+	sort.Slice(processIds, func(i, j int) bool {
+		return processIds[i] > processIds[j]
+	})
+	// 更新日志
+	if err = e.DB.Model(new(model.NeckRingConfigure)).
+		Where("name = ?", model.MaxHabit).
+		Where("pasture_id = ?", pastureId).
+		Update("value", processIds[len(processIds)-1]).Error; err != nil {
+		zaplog.Error("NeckRingCalculate", zap.Any("MaxHabit", err), zap.Any("xToday", xToday))
+	}
+
+	// 健康预警
+	if err = e.HealthWarning(pastureId, processIds); err != nil {
+		zaplog.Error("EntryUpdateActiveHabit", zap.Any("HealthWarning", err))
+	}
+	return nil
+}
+
+// FirstFilterUpdate 首次更新活动滤波
+func (e *Entry) FirstFilterUpdate(pastureId int64, xToDay *XToday) (processIds []int64, err error) {
+	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id > ?", xToDay.LastMaxHabitId).
+		Where("pasture_id = ?", pastureId).
+		Where("is_show = ?", pasturePb.IsShow_No).
+		Where("record_count = ?", model.DefaultRecordCount).
+		Where(e.DB.Where("high >= ?", xToDay.High).Or("rumina >= ?", xToDay.Rumina)).
+		Order("heat_date,neck_ring_number,frameid").
+		Limit(int(defaultLimit)).
+		Find(&newNeckActiveHabitList).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	// 活动量滤波
+	for _, v := range newNeckActiveHabitList {
+		// 过滤牛只未绑定的脖环的数据
+		cowInfo := e.GetCowInfoByNeckRingNumber(v.PastureId, v.NeckRingNumber)
+		if cowInfo == nil || cowInfo.Id <= 0 {
+			if err = e.DB.Model(new(model.NeckActiveHabit)).
+				Where("id = ?", v.Id).
+				Where("pasture_id = ?", v.PastureId).
+				Update("is_show", pasturePb.IsShow_Ok).Error; err != nil {
+				zaplog.Error("EntryUpdateActiveHabit", zap.Any("error", err))
+			}
+			continue
+		}
+
+		frameId := v.Frameid
+		heatDate := v.HeatDate
+		if v.Frameid == 0 {
+			frameId = 11
+			heatDateParse, _ := time.Parse(model.LayoutDate2, heatDate)
+			heatDate = heatDateParse.AddDate(0, 0, -1).Format(model.LayoutDate2)
+		} else {
+			frameId -= 1
+		}
+
+		firstFilterData := e.FindFirstFilter(pastureId, v.NeckRingNumber, heatDate, frameId)
+		if v.FilterHigh > 0 {
+			firstFilterData.FilterHigh = v.FilterHigh
+		} else {
+			if v.NeckRingNumber == firstFilterData.NeckRingNumber {
+				firstFilterData.FilterHigh = int32(computeIfPositiveElse(float64(v.High), float64(firstFilterData.FilterHigh), 0.23, 0.77))
+			} else {
+				firstFilterData.FilterHigh = v.High
+			}
+		}
+
+		if v.FilterRumina > 0 {
+			firstFilterData.FilterRumina = v.FilterRumina
+		} else {
+			if v.NeckRingNumber == firstFilterData.NeckRingNumber {
+				firstFilterData.FilterRumina = int32(computeIfPositiveElse(float64(v.Rumina), float64(firstFilterData.FilterRumina), 0.33, 0.67))
+			} else {
+				firstFilterData.FilterRumina = v.Rumina
+			}
+		}
+		if v.FilterChew > 0 {
+			firstFilterData.FilterChew = v.FilterChew
+		} else {
+			if v.NeckRingNumber == firstFilterData.NeckRingNumber {
+				firstFilterData.FilterChew = int32(computeIfPositiveElse(float64(v.Rumina+v.Intake), float64(firstFilterData.FilterChew), 0.33, 0.67))
+			} else {
+				firstFilterData.FilterChew = v.Rumina + v.Intake
+			}
+		}
+
+		processIds = append(processIds, v.Id)
+		// 更新过滤值 // todo 记得更新胎次为牛只胎次,现在为了测试特意改成0
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("filter_high", "filter_rumina", "filter_chew", "cow_id", "lact", "calving_age", "ear_number").
+			Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"filter_high":   firstFilterData.FilterHigh,
+				"filter_rumina": firstFilterData.FilterRumina,
+				"filter_chew":   firstFilterData.FilterChew,
+				"cow_id":        cowInfo.Id,
+				"lact":          0,
+				"calving_age":   cowInfo.CalvingAge,
+				"ear_number":    cowInfo.EarNumber,
+			}).Error; err != nil {
+			zaplog.Error("FirstFilterUpdate",
+				zap.Any("error", err),
+				zap.Any("firstFilterData", firstFilterData),
+				zap.Any("NeckActiveHabit", v),
+				zap.Any("cowInfo", cowInfo),
+				zap.Any("xToday", xToDay),
+			)
+		}
+	}
+	return processIds, nil
+}
+
+// WeeklyUpdateActiveHabit  时间点周平均值计算
+func (e *Entry) WeeklyUpdateActiveHabit(pastureId int64, processIds []int64, xToDay *XToday) (err error) {
+	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		Order("heat_date,neck_ring_number,frameid").
+		Find(&newNeckActiveHabitList).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+	for _, v := range newNeckActiveHabitList {
+		// 前七天的
+		weekHabitData := e.FindWeekHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
+		// 更新过滤值
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("week_high_habit", "week_rumina_habit", "week_chew_habit", "week_intake_habit", "week_inactive_habit").
+			Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"week_high_habit":     weekHabitData.WeekHighHabit,
+				"week_rumina_habit":   weekHabitData.WeekRuminaHabit,
+				"week_chew_habit":     weekHabitData.WeekChewHabit,
+				"week_intake_habit":   weekHabitData.WeekIntakeHabit,
+				"week_inactive_habit": weekHabitData.WeekInactiveHabit,
+			}).Error; err != nil {
+			zaplog.Error("WeeklyUpdateActiveHabit",
+				zap.Error(err),
+				zap.Any("NeckActiveHabit", v),
+				zap.Any("pastureId", pastureId),
+			)
+		}
+	}
+
+	if err = e.SumUpdateActiveHabit(pastureId, newNeckActiveHabitList, xToDay); err != nil {
+		zaplog.Error("WeeklyUpdateActiveHabit",
+			zap.Any("SumUpdateActiveHabit", err),
+			zap.Any("newNeckActiveHabitList", newNeckActiveHabitList),
+			zap.Any("pastureId", pastureId),
+		)
+	}
+
+	if err = e.ActiveChange(pastureId, processIds, xToDay); err != nil {
+		zaplog.Error("WeeklyUpdateActiveHabit",
+			zap.Any("ActiveChange", err),
+			zap.Any("processIds", processIds),
+			zap.Any("xToDay", xToDay),
+			zap.Any("pastureId", pastureId),
+		)
+	}
+
+	return nil
+}
+
+// SumUpdateActiveHabit -- 累计24小时数值
+func (e *Entry) SumUpdateActiveHabit(pastureId int64, newNeckActiveHabitList []*model.NeckActiveHabit, xToDay *XToday) (err error) {
+	for _, v := range newNeckActiveHabitList {
+		sumHabitData := e.FindSumHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
+		// 更新过滤值
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("sum_rumina", "sum_intake", "sum_inactive", "sum_active", "sum_max_high", "sum_min_high", "sum_min_chew").
+			Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"sum_rumina":   sumHabitData.SumRumina,
+				"sum_intake":   sumHabitData.SumIntake,
+				"sum_inactive": sumHabitData.SumInactive,
+				"sum_active":   sumHabitData.SumActive,
+				"sum_max_high": sumHabitData.SumMaxHigh,
+				"sum_min_high": sumHabitData.SumMinHigh,
+				"sum_min_chew": sumHabitData.SumMinChew,
+			}).Error; err != nil {
+			zaplog.Error("WeeklyUpdateActiveHabit",
+				zap.Any("err", err),
+				zap.Any("NeckActiveHabit", v),
+				zap.Any("pastureId", pastureId),
+			)
+		}
+	}
+	return err
+}
+
+// ActiveChange -- 变化百分比
+func (e *Entry) ActiveChange(pastureId int64, processIds []int64, xToDay *XToday) (err error) {
+	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		Where("week_high_habit > ?", 0).
+		Where(e.DB.Where("high >= ?", xToDay.High).Or("rumina >= ?", xToDay.Rumina)).
+		Find(&newNeckActiveHabitList).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+	for _, v := range newNeckActiveHabitList {
+		highDiff := v.FilterHigh - v.WeekHighHabit
+		denominator := float64(v.WeekHigh)*0.6 + float64(v.WeekHighHabit)*0.2 + float64(xToDay.WeeklyActive)*0.2
+		if highDiff > 0 {
+			v.ChangeHigh = int32(math.Round((float64(highDiff) / denominator / float64(v.WeekHighHabit)) * 100))
+		} else {
+			v.ChangeHigh = int32(math.Round(float64(highDiff) / float64(v.WeekHighHabit) * 100))
+		}
+
+		if v.WeekRuminaHabit != 0 {
+			v.ChangeRumina = int32(math.Round(float64(v.FilterRumina-v.WeekRuminaHabit) / float64(v.WeekRuminaHabit) * 100))
+		}
+
+		if v.WeekChewHabit != 0 {
+			v.ChangeChew = int32(math.Round(float64(v.FilterChew-v.WeekChewHabit) / float64(v.WeekChewHabit) * 100))
+		}
+
+		// 更新过滤值
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("change_high", "change_rumina", "change_chew").
+			Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"change_high":   v.ChangeHigh,
+				"change_rumina": v.ChangeRumina,
+				"change_chew":   v.ChangeChew,
+			}).Error; err != nil {
+			zaplog.Error("WeeklyUpdateActiveHabit",
+				zap.Error(err),
+				zap.Any("NeckActiveHabit", v),
+				zap.Any("pastureId", pastureId),
+			)
+		}
+	}
+	return err
+}
+
+func (e *Entry) WeeklyUpdateActiveHabitOld(pastureId int64, newNeckActiveHabitList []*model.NeckActiveHabit, xToDay *XToday) (err error) {
+	for _, v := range newNeckActiveHabitList {
+		// 前七天的
+		weekHabitData := e.FindWeekHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
+
+		highDiff := v.FilterHigh - weekHabitData.WeekHighHabit
+		denominator := float64(v.WeekHigh)*0.6 + float64(weekHabitData.WeekHighHabit)*0.2 + float64(xToDay.WeeklyActive)*0.2
+		if highDiff > 0 {
+			v.ChangeHigh = int32(math.Round((float64(highDiff) / denominator) * 100))
+		} else {
+			v.ChangeHigh = int32(math.Round(float64(highDiff) / denominator * 100))
+		}
+
+		if weekHabitData.WeekRuminaHabit != 0 {
+			v.ChangeRumina = int32(math.Round(float64(v.FilterRumina-weekHabitData.WeekRuminaHabit) / float64(weekHabitData.WeekRuminaHabit) * 100))
+		} else {
+			v.ChangeRumina = 0
+		}
+		if weekHabitData.WeekChewHabit != 0 {
+			v.ChangeChew = int32(math.Round(float64(v.FilterChew-weekHabitData.WeekChewHabit) / float64(weekHabitData.WeekChewHabit) * 100))
+		} else {
+			v.ChangeChew = 0
+		}
+
+		sumHabitData := e.FindSumHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
+		// 更新过滤值
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select(
+				"week_high_habit", "week_rumina_habit", "week_chew_habit", "week_intake_habit", "week_inactive_habit",
+				"sum_rumina", "sum_intake", "sum_inactive", "sum_active", "sum_max_high", "sum_min_high", "sum_min_chew",
+				"change_high", "change_rumina", "change_chew", "before_three_sum_rumina", "before_three_sum_intake",
+			).Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"week_high_habit":     weekHabitData.WeekHighHabit,
+				"week_rumina_habit":   weekHabitData.WeekRuminaHabit,
+				"week_chew_habit":     weekHabitData.WeekChewHabit,
+				"week_intake_habit":   weekHabitData.WeekIntakeHabit,
+				"week_inactive_habit": weekHabitData.WeekInactiveHabit,
+				"sum_rumina":          sumHabitData.SumRumina,
+				"sum_intake":          sumHabitData.SumIntake,
+				"sum_inactive":        sumHabitData.SumInactive,
+				"sum_active":          sumHabitData.SumActive,
+				"sum_max_high":        sumHabitData.SumMaxHigh,
+				"sum_min_high":        sumHabitData.SumMinHigh,
+				"sum_min_chew":        sumHabitData.SumMinChew,
+				"change_high":         v.ChangeHigh,
+				"change_rumina":       v.ChangeRumina,
+				"change_chew":         v.ChangeChew,
+			}).Error; err != nil {
+			zaplog.Error("WeeklyUpdateActiveHabit",
+				zap.Error(err),
+				zap.Any("NeckActiveHabit", v),
+				zap.Any("pastureId", pastureId),
+			)
+		}
+	}
+	return err
+}
+func (e *Entry) Before3DaysNeckActiveHabit(pastureId int64, processIds []int64, xToDay *XToday) (err error) {
+	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		Order("heat_date,neck_ring_number,frameid").
+		Find(&newNeckActiveHabitList).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+	for _, v := range newNeckActiveHabitList {
+		before3DaysNeckActiveHabit := e.FindBefore3DaysNeckActiveHabit(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid)
+		// 更新过滤值
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("before_three_sum_rumina", "before_three_sum_intake").
+			Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"before_three_sum_rumina": before3DaysNeckActiveHabit.SumRumina,
+				"before_three_sum_intake": before3DaysNeckActiveHabit.SumIntake,
+			}).Error; err != nil {
+			zaplog.Error("Before3DaysNeckActiveHabit",
+				zap.Error(err),
+				zap.Any("NeckActiveHabit", v),
+				zap.Any("pastureId", pastureId),
+			)
+		}
+	}
+	return nil
+}
+
+// SecondUpdateChangeFilter 第二次更新变化趋势滤波
+func (e *Entry) SecondUpdateChangeFilter(pastureId int64, xToday *XToday) (err error) {
+	newChangeFilterList := make([]*ChangeFilterData, 0)
+	if err = e.DB.Model(new(model.NeckActiveHabit)).
+		Select("id", "neck_ring_number", "change_high", "change_filter", "rumina_filter", "change_rumina",
+			"chew_filter", "change_chew", "heat_date", "frameid", "IF(lact = 0, 0.8, 1) as xlc_dis_count").
+		Where("id > ?", xToday.LastMaxHabitId).
+		Where("heat_date >= ?", time.Now().AddDate(0, 0, -2).Format(model.LayoutDate2)).
+		Where("pasture_id = ?", pastureId).
+		Where("change_filter = ?", model.InitChangeFilter).
+		Where("change_high > ?", MinChangeHigh).
+		Order("neck_ring_number,heat_date,frameid").
+		Limit(int(defaultLimit)).
+		Find(&newChangeFilterList).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+
+	for _, v := range newChangeFilterList {
+		secondFilterData := &SecondFilterData{}
+		frameId := v.FrameId
+		heatDate := v.HeatDate
+		if v.FrameId == 0 {
+			frameId = 11
+			heatDateParse, _ := time.Parse(model.LayoutDate2, heatDate)
+			heatDate = heatDateParse.AddDate(0, 0, -1).Format(model.LayoutDate2)
+		} else {
+			frameId -= 1
+		}
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("neck_ring_number", "filter_high", "filter_rumina", "filter_chew").
+			Where("neck_ring_number = ?", v.NeckRingNumber).
+			Where("heat_date = ?", heatDate).
+			Where("frameid = ?", frameId).
+			First(&secondFilterData).Error; err != nil {
+			zaplog.Error("EntryUpdateActiveHabit", zap.Any("FirstFilterUpdate", err))
+		}
+
+		if v.ChangeFilter > MinChangeFilter {
+			secondFilterData.ChangeFilter = float64(v.ChangeFilter)
+		} else {
+			if v.NeckRingNumber == secondFilterData.NeckRingNumber {
+				secondFilterData.ChangeFilter = secondFilterData.ChangeFilter*(1-(float64(xToday.XChangeDiscount)/10)*v.XlcDisCount) +
+					math.Min(float64(v.ChangeHigh), secondFilterData.ChangeFilter+135)*(float64(xToday.XChangeDiscount)/10)*v.XlcDisCount
+			} else {
+				secondFilterData.ChangeFilter = 0
+			}
+		}
+
+		if v.RuminaFilter > MinRuminaFilter {
+			secondFilterData.RuminaFilter = float64(v.ChangeFilter)
+		} else {
+			if v.NeckRingNumber == secondFilterData.NeckRingNumber {
+				discount := float64(xToday.XRuminaDisc) / 10 * v.XlcDisCount
+				if math.Abs(float64(v.ChangeRumina)) > 60 {
+					discount *= 0.5
+				}
+				secondFilterData.RuminaFilter = secondFilterData.RuminaFilter*(1-discount) + float64(v.ChangeRumina)*discount
+			} else {
+				secondFilterData.RuminaFilter = 0
+			}
+		}
+
+		secondFilterData.RuminaFilter = math.Min(50, secondFilterData.RuminaFilter)
+
+		if v.ChewFilter > MinChewFilter {
+			secondFilterData.ChewFilter = float64(v.ChangeChew)
+		} else {
+			if v.NeckRingNumber == secondFilterData.NeckRingNumber {
+				discount := float64(xToday.XRuminaDisc) / 10
+				if math.Abs(float64(v.ChangeChew)) > 60 {
+					discount *= 0.5
+				}
+				secondFilterData.ChewFilter = secondFilterData.ChewFilter*(1-discount) + float64(v.ChangeChew)*discount
+			} else {
+				secondFilterData.ChewFilter = 0
+			}
+		}
+
+		secondFilterData.ChewFilter = math.Min(50, secondFilterData.ChewFilter)
+		if err = e.DB.Model(new(model.NeckActiveHabit)).
+			Select("change_filter", "rumina_filter", "chew_filter").
+			Where("id = ?", v.Id).
+			Updates(map[string]interface{}{
+				"change_filter": secondFilterData.ChangeFilter,
+				"rumina_filter": secondFilterData.RuminaFilter,
+				"chew_filter":   secondFilterData.ChewFilter,
+			}).Error; err != nil {
+			zaplog.Error("SecondUpdateChangeFilter-1", zap.Any("error", err), zap.Any("xToday", xToday))
+		}
+	}
+	return nil
+}
+
+// FilterCorrectAndScoreUpdate 计算活动量变化趋势校正值(活跃度校正)和健康评分
+func (e *Entry) FilterCorrectAndScoreUpdate(pastureId int64, processIds []int64, xToday *XToday) error {
+	beginDayDate := time.Now()
+	before7DayDate := beginDayDate.AddDate(0, 0, -7).Format(model.LayoutDate2)
+	before1DayDate := beginDayDate.AddDate(0, 0, -1).Format(model.LayoutDate2)
+
+	neckActiveHabitList := make([]*model.NeckActiveHabit, 0)
+	if err := e.DB.Model(new(model.NeckActiveHabit)).
+		Where("id IN (?)", processIds).
+		//Where("heat_date >= ?", before1DayDate).
+		Where("pasture_id = ?", pastureId).
+		Where(e.DB.Where("high > ?", xToday.High).Or("rumina > ?", xToday.Rumina)).
+		Find(&neckActiveHabitList).Error; err != nil {
+		zaplog.Error("ActivityVolumeChanges-1", zap.Any("error", err), zap.Any("xToday", xToday))
+		return xerr.WithStack(err)
+	}
+
+	for _, v := range neckActiveHabitList {
+		activityVolume := &ActivityVolume{}
+		if err := e.DB.Model(new(model.NeckActiveHabit)).
+			Select("neck_ring_number", "AVG(IF(change_filter>=60, 60, change_filter)) as avg_filter",
+				"ROUND(STD(IF(change_filter>=60, 60, change_filter))) as std_filter", "COUNT(1) as nb").
+			Where("heat_date BETWEEN ? AND ?", before7DayDate, before1DayDate).
+			Where("pasture_id = ?", pastureId).
+			Where(e.DB.Where("high > ?", xToday.High).Or("rumina >= ?", xToday.Rumina)).
+			Where("active_time <= ?", beginDayDate.Add(-12*time.Hour).Format(model.LayoutTime)).
+			Where("change_filter > ?", MinChangeFilter).
+			Where("neck_ring_number = ?").
+			Having("nb > ?", DefaultNb).
+			First(&activityVolume).Error; err != nil {
+			zaplog.Error("ActivityVolumeChanges-0", zap.Any("error", err), zap.Any("xToday", xToday))
+			continue
+		}
+		if activityVolume != nil && activityVolume.NeckRingNumber != "" {
+			filterCorrect := model.DefaultFilterCorrect - int(math.Floor(activityVolume.AvgFilter/3+float64(activityVolume.StdFilter)/2))
+			// 活动量校正系数
+			if err := e.DB.Model(new(model.NeckActiveHabit)).
+				Where("id = ?", v.Id).
+				Where("neck_ring_number = ?", v.NeckRingNumber).
+				Update("filter_correct", filterCorrect).Error; err != nil {
+				zaplog.Error("ActivityVolumeChanges-2", zap.Any("error", err), zap.Any("xToday", xToday))
+				continue
+			}
+		}
+
+		cowScore := calculateScore(v)
+		if err := e.DB.Model(new(model.NeckActiveHabit)).
+			Where("id = ?", v.Id).
+			Update("score", cowScore).Error; err != nil {
+			zaplog.Error("ActivityVolumeChanges-2", zap.Any("error", err), zap.Any("xToday", xToday))
+			continue
+		}
+	}
+	return nil
+}
+
+// UpdateChangeAdJust 更新群体校正数据
+func (e *Entry) UpdateChangeAdJust(pastureId int64, xToday *XToday) error {
+	/*-- 插入群体校正表
+	INSERT INTO data_bar_change(heatdate, frameid, intCurBar, intCurBarName, nb, highchange, changefilter)
+	SELECT h.heatdate, h.frameid, c.intCurBar, c.intCurBarName, COUNT(*) nb, ROUND(AVG(h.highchange)) highchange, ROUND(AVG(h.changefilter) ) changefilter
+	FROM h_activehabit h JOIN cow c ON h.intCowId=c.intCowId
+	WHERE h.heatdate>=(CURDATE() -INTERVAL 1 DAY )
+	GROUP BY h.heatdate, h.frameid, c.intCurBar
+	ORDER BY h.heatdate, h.frameid, c.intCurBarName
+	ON DUPLICATE KEY UPDATE nb = VALUES(nb), highchange = VALUES(highchange), changefilter = VALUES(changefilter);
+
+	UPDATE h_activehabit h
+	JOIN cow c ON h.intCowId=c.intCowId
+	JOIN data_bar_change cg ON h.heatdate=cg.heatdate AND h.frameid=cg.frameid AND c.intCurBar=cg.intCurBar
+	SET h.changeadjust=cg.changefilter
+	WHERE h.id>xBeg_update_act_Id AND h.heatdate>=CURRENT_DATE() - INTERVAL 1 DAY AND ABS(cg.changefilter)>=10;
+	*/
+	res := make([]*model.NeckRingBarChange, 0)
+	oneDayAgo := time.Now().AddDate(0, 0, -1).Format(model.LayoutDate2)
+	if err := e.DB.Table(fmt.Sprintf("%s as h", new(model.NeckActiveHabit).TableName())).
+		Select("h.neck_ring_number,h.heat_date, h.frameid, c.pen_id, c.pen_name, COUNT(*) as nb, ROUND(AVG(h.change_high)) as change_high, ROUND(AVG(h.change_filter)) as change_filter").
+		Joins("JOIN cow as c ON h.neck_ring_number = c.neck_ring_number").
+		Where("h.pasture_id = ?", pastureId).
+		Where("h.heat_date >= ?", oneDayAgo).
+		Where("h.cow_id >= ?", 0).
+		Where("h.cow_id >= ?", 0).
+		Group("h.heat_date, h.frameid, c.pen_id").
+		Order("h.heat_date, h.frameid, c.pen_name").
+		Find(&res).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+
+	// todo ABS(cg.changefilter)>=10;
+	for _, v := range res {
+		if err := e.DB.Model(new(model.NeckActiveHabit)).
+			Where("id > ?", xToday.LastMaxHabitId).
+			Where("heat_date = ?", v.HeatDate).
+			Where("frameid = ?", v.FrameId).
+			Where("neck_ring_number = ?", v.NeckRingNumber).
+			Update("change_adjust", v.ChangeHigh).Error; err != nil {
+			zaplog.Error("UpdateChangeAdJust-1", zap.Any("error", err), zap.Any("xToday", xToday))
+		}
+	}
+
+	return nil
+}

+ 0 - 648
module/crontab/neck_ring_merge.go

@@ -121,654 +121,6 @@ func (e *Entry) OriginalMergeData(pastureId int64) error {
 	return nil
 }
 
-func (e *Entry) NeckRingCalculate() error {
-	pastureList := e.FindPastureList()
-	if pastureList == nil || len(pastureList) == 0 {
-		return nil
-	}
-
-	if calculateIsRunning {
-		return nil
-	}
-	defer func() {
-		calculateIsRunning = false
-	}()
-
-	calculateIsRunning = true
-	for _, pasture := range pastureList {
-		if err := e.EntryUpdateActiveHabit(pasture.Id); err != nil {
-			zaplog.Error("NeckRingCalculate", zap.Any("err", err), zap.Any("pasture", pasture))
-		}
-		zaplog.Info(fmt.Sprintf("NeckRingCalculate Success %d", pasture.Id))
-	}
-	return nil
-}
-
-func (e *Entry) EntryUpdateActiveHabit(pastureId int64) (err error) {
-	// 获取这段执行数据内最大日期和最小日期
-	xToday := &XToday{}
-	systemConfigureList, err := e.GetSystemNeckRingConfigure(pastureId)
-	if err != nil {
-		return xerr.WithStack(err)
-	}
-	for _, v := range systemConfigureList {
-		switch v.Name {
-		case model.MaxHabit:
-			xToday.LastMaxHabitId = v.Value
-		case model.High:
-			xToday.High = int32(v.Value)
-		case model.Rumina:
-			xToday.Rumina = int32(v.Value)
-		case model.XRuminaDisc:
-			xToday.XRuminaDisc = int32(v.Value)
-		case model.XChangeDiscount:
-			xToday.XChangeDiscount = int32(v.Value)
-		case model.WeeklyActive:
-			xToday.WeeklyActive = int32(v.Value)
-		}
-	}
-
-	currMaxHabit := &model.NeckActiveHabit{}
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id > ?", xToday.LastMaxHabitId).
-		Where("pasture_id = ?", pastureId).
-		Where("is_show = ?", pasturePb.IsShow_No).
-		Order("id desc").
-		First(currMaxHabit).Error; err != nil {
-		return xerr.WithStack(err)
-	}
-
-	if currMaxHabit.Id <= 0 || currMaxHabit.Id <= xToday.LastMaxHabitId {
-		return nil
-	}
-
-	xToday.CurrMaxHabitId = currMaxHabit.Id
-	var processIds []int64
-	// 更新活动滤波
-	processIds, err = e.FirstFilterUpdate(pastureId, xToday)
-	if err != nil {
-		zaplog.Error("NeckRingCalculate", zap.Any("FirstFilterUpdate", err), zap.Any("xToday", xToday))
-	}
-	zaplog.Info("NeckRingCalculate", zap.Any("xToday", xToday), zap.Any("processIds", processIds))
-	if len(processIds) <= 0 {
-		return nil
-	}
-
-	if err = e.WeeklyUpdateActiveHabit(pastureId, processIds, xToday); err != nil {
-		zaplog.Error("NeckRingCalculate", zap.Any("WeeklyUpdateActiveHabit", err), zap.Any("xToday", xToday))
-	}
-
-	if err = e.Before3DaysNeckActiveHabit(pastureId, processIds, xToday); err != nil {
-		zaplog.Error("NeckRingCalculate", zap.Any("Before3DaysNeckActiveHabit", err), zap.Any("xToday", xToday))
-	}
-	// 二次更新滤波
-	if err = e.SecondUpdateChangeFilter(pastureId, xToday); err != nil {
-		zaplog.Error("NeckRingCalculate", zap.Any("SecondUpdateChangeFilter", err), zap.Any("xToday", xToday))
-	}
-
-	// 活动量校正系数和健康评分
-	if err = e.FilterCorrectAndScoreUpdate(pastureId, xToday); err != nil {
-		zaplog.Error("NeckRingCalculate", zap.Any("ActivityVolumeChanges", err), zap.Any("xToday", xToday))
-	}
-
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id IN (?)", processIds).
-		Where("pasture_id = ?", pastureId).
-		Where("is_show = ?", pasturePb.IsShow_No).
-		Where("change_filter = ?", model.InitChangeFilter).
-		Updates(map[string]interface{}{
-			"change_filter": model.DefaultChangeFilter,
-			"rumina_filter": model.DefaultRuminaFilter,
-			"chew_filter":   model.DefaultChewFilter,
-		}).Error; err != nil {
-		zaplog.Error("EntryUpdateActiveHabit", zap.Any("change_filter", err), zap.Any("xToday", xToday))
-	}
-
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id IN (?)", processIds).
-		Where("pasture_id = ?", pastureId).
-		Where("change_filter < ?", 0).
-		Where("filter_correct < ?", model.DefaultFilterCorrect).
-		Updates(map[string]interface{}{
-			"filter_correct": model.DefaultFilterCorrect,
-		}).Error; err != nil {
-		zaplog.Error("EntryUpdateActiveHabit", zap.Any("filter_correct", err), zap.Any("xToday", xToday))
-	}
-
-	// 插入群体校正表
-	if err = e.UpdateChangeAdJust(pastureId, xToday); err != nil {
-		zaplog.Error("EntryUpdateActiveHabit", zap.Any("UpdateChangeAdJust", err), zap.Any("xToday", xToday))
-	}
-
-	// 更新所有的显示状态为否的记录为是
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id IN (?)", processIds).
-		Where("pasture_id = ?", pastureId).
-		Update("is_show", pasturePb.IsShow_Ok).Error; err != nil {
-		zaplog.Error("UpdateChangeAdJust-2", zap.Any("error", err), zap.Any("xToday", xToday))
-	}
-
-	// 更新日志
-	if err = e.DB.Model(new(model.NeckRingConfigure)).
-		Where("name = ?", model.MaxHabit).
-		Where("pasture_id = ?", pastureId).
-		Update("value", processIds[len(processIds)-1]).Error; err != nil {
-		zaplog.Error("NeckRingCalculate", zap.Any("MaxHabit", err), zap.Any("xToday", xToday))
-	}
-
-	// 健康预警
-	if err = e.HealthWarning(pastureId, processIds); err != nil {
-		zaplog.Error("EntryUpdateActiveHabit", zap.Any("HealthWarning", err))
-	}
-	return nil
-}
-
-// FirstFilterUpdate 首次更新活动滤波
-func (e *Entry) FirstFilterUpdate(pastureId int64, xToDay *XToday) (processIds []int64, err error) {
-	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id > ?", xToDay.LastMaxHabitId).
-		Where("pasture_id = ?", pastureId).
-		Where("is_show = ?", pasturePb.IsShow_No).
-		//Where("record_count = ?", model.DefaultRecordCount).
-		Where(e.DB.Where("high >= ?", xToDay.High).Or("rumina >= ?", xToDay.Rumina)).
-		Order("heat_date,neck_ring_number,frameid").
-		Limit(int(defaultLimit)).
-		Find(&newNeckActiveHabitList).Error; err != nil {
-		return nil, xerr.WithStack(err)
-	}
-
-	// 活动量滤波
-	for _, v := range newNeckActiveHabitList {
-		// 过滤牛只未绑定的脖环的数据
-		cowInfo := e.GetCowInfoByNeckRingNumber(v.PastureId, v.NeckRingNumber)
-		if cowInfo == nil || cowInfo.Id <= 0 {
-			if err = e.DB.Model(new(model.NeckActiveHabit)).
-				Where("id = ?", v.Id).
-				Where("pasture_id = ?", v.PastureId).
-				Update("is_show", pasturePb.IsShow_Ok).Error; err != nil {
-				zaplog.Error("EntryUpdateActiveHabit", zap.Any("error", err))
-			}
-			continue
-		}
-
-		frameId := v.Frameid
-		heatDate := v.HeatDate
-		if v.Frameid == 0 {
-			frameId = 11
-			heatDateParse, _ := time.Parse(model.LayoutDate2, heatDate)
-			heatDate = heatDateParse.AddDate(0, 0, -1).Format(model.LayoutDate2)
-		} else {
-			frameId -= 1
-		}
-
-		firstFilterData := e.FindFirstFilter(pastureId, v.NeckRingNumber, heatDate, frameId)
-		if v.FilterHigh > 0 {
-			firstFilterData.FilterHigh = v.FilterHigh
-		} else {
-			if v.NeckRingNumber == firstFilterData.NeckRingNumber {
-				firstFilterData.FilterHigh = int32(computeIfPositiveElse(float64(v.High), float64(firstFilterData.FilterHigh), 0.23, 0.77))
-			} else {
-				firstFilterData.FilterHigh = v.High
-			}
-		}
-
-		if v.FilterRumina > 0 {
-			firstFilterData.FilterRumina = v.FilterRumina
-		} else {
-			if v.NeckRingNumber == firstFilterData.NeckRingNumber {
-				firstFilterData.FilterRumina = int32(computeIfPositiveElse(float64(v.Rumina), float64(firstFilterData.FilterRumina), 0.33, 0.67))
-			} else {
-				firstFilterData.FilterRumina = v.Rumina
-			}
-		}
-		if v.FilterChew > 0 {
-			firstFilterData.FilterChew = v.FilterChew
-		} else {
-			if v.NeckRingNumber == firstFilterData.NeckRingNumber {
-				firstFilterData.FilterChew = int32(computeIfPositiveElse(float64(v.Rumina+v.Intake), float64(firstFilterData.FilterChew), 0.33, 0.67))
-			} else {
-				firstFilterData.FilterChew = v.Rumina + v.Intake
-			}
-		}
-
-		processIds = append(processIds, v.Id)
-		// 更新过滤值 // todo 记得更新胎次为牛只胎次,现在为了测试特意改成0
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("filter_high", "filter_rumina", "filter_chew", "cow_id", "lact", "calving_age", "ear_number").
-			Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"filter_high":   firstFilterData.FilterHigh,
-				"filter_rumina": firstFilterData.FilterRumina,
-				"filter_chew":   firstFilterData.FilterChew,
-				"cow_id":        cowInfo.Id,
-				"lact":          0,
-				"calving_age":   cowInfo.CalvingAge,
-				"ear_number":    cowInfo.EarNumber,
-			}).Error; err != nil {
-			zaplog.Error("FirstFilterUpdate",
-				zap.Any("error", err),
-				zap.Any("firstFilterData", firstFilterData),
-				zap.Any("NeckActiveHabit", v),
-				zap.Any("cowInfo", cowInfo),
-				zap.Any("xToday", xToDay),
-			)
-		}
-	}
-	return processIds, nil
-}
-
-// WeeklyUpdateActiveHabit  时间点周平均值计算
-func (e *Entry) WeeklyUpdateActiveHabit(pastureId int64, processIds []int64, xToDay *XToday) (err error) {
-	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id IN (?)", processIds).
-		Order("heat_date,neck_ring_number,frameid").
-		Find(&newNeckActiveHabitList).Error; err != nil {
-		return xerr.WithStack(err)
-	}
-	for _, v := range newNeckActiveHabitList {
-		// 前七天的
-		weekHabitData := e.FindWeekHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
-		// 更新过滤值
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("week_high_habit", "week_rumina_habit", "week_chew_habit", "week_intake_habit", "week_inactive_habit").
-			Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"week_high_habit":     weekHabitData.WeekHighHabit,
-				"week_rumina_habit":   weekHabitData.WeekRuminaHabit,
-				"week_chew_habit":     weekHabitData.WeekChewHabit,
-				"week_intake_habit":   weekHabitData.WeekIntakeHabit,
-				"week_inactive_habit": weekHabitData.WeekInactiveHabit,
-			}).Error; err != nil {
-			zaplog.Error("WeeklyUpdateActiveHabit",
-				zap.Error(err),
-				zap.Any("NeckActiveHabit", v),
-				zap.Any("pastureId", pastureId),
-			)
-		}
-	}
-
-	if err = e.SumUpdateActiveHabit(pastureId, newNeckActiveHabitList, xToDay); err != nil {
-		zaplog.Error("WeeklyUpdateActiveHabit",
-			zap.Any("SumUpdateActiveHabit", err),
-			zap.Any("newNeckActiveHabitList", newNeckActiveHabitList),
-			zap.Any("pastureId", pastureId),
-		)
-	}
-
-	if err = e.ActiveChange(pastureId, processIds, xToDay); err != nil {
-		zaplog.Error("WeeklyUpdateActiveHabit",
-			zap.Any("ActiveChange", err),
-			zap.Any("processIds", processIds),
-			zap.Any("xToDay", xToDay),
-			zap.Any("pastureId", pastureId),
-		)
-	}
-
-	return nil
-}
-
-// SumUpdateActiveHabit -- 累计24小时数值
-func (e *Entry) SumUpdateActiveHabit(pastureId int64, newNeckActiveHabitList []*model.NeckActiveHabit, xToDay *XToday) (err error) {
-	for _, v := range newNeckActiveHabitList {
-		sumHabitData := e.FindSumHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
-		// 更新过滤值
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("sum_rumina", "sum_intake", "sum_inactive", "sum_active", "sum_max_high", "sum_min_high", "sum_min_chew").
-			Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"sum_rumina":   sumHabitData.SumRumina,
-				"sum_intake":   sumHabitData.SumIntake,
-				"sum_inactive": sumHabitData.SumInactive,
-				"sum_active":   sumHabitData.SumActive,
-				"sum_max_high": sumHabitData.SumMaxHigh,
-				"sum_min_high": sumHabitData.SumMinHigh,
-				"sum_min_chew": sumHabitData.SumMinChew,
-			}).Error; err != nil {
-			zaplog.Error("WeeklyUpdateActiveHabit",
-				zap.Any("err", err),
-				zap.Any("NeckActiveHabit", v),
-				zap.Any("pastureId", pastureId),
-			)
-		}
-	}
-	return err
-}
-
-// ActiveChange -- 变化百分比
-func (e *Entry) ActiveChange(pastureId int64, processIds []int64, xToDay *XToday) (err error) {
-	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id IN (?)", processIds).
-		Where("week_high_habit > ?", 0).
-		Where(e.DB.Where("high >= ?", xToDay.High).Or("rumina >= ?", xToDay.Rumina)).
-		Find(&newNeckActiveHabitList).Error; err != nil {
-		return xerr.WithStack(err)
-	}
-	for _, v := range newNeckActiveHabitList {
-		highDiff := v.FilterHigh - v.WeekHighHabit
-		denominator := float64(v.WeekHigh)*0.6 + float64(v.WeekHighHabit)*0.2 + float64(xToDay.WeeklyActive)*0.2
-		if highDiff > 0 {
-			v.ChangeHigh = int32(math.Round((float64(highDiff) / denominator / float64(v.WeekHighHabit)) * 100))
-		} else {
-			v.ChangeHigh = int32(math.Round(float64(highDiff) / float64(v.WeekHighHabit) * 100))
-		}
-
-		if v.WeekRuminaHabit != 0 {
-			v.ChangeRumina = int32(math.Round(float64(v.FilterRumina-v.WeekRuminaHabit) / float64(v.WeekRuminaHabit) * 100))
-		}
-
-		if v.WeekChewHabit != 0 {
-			v.ChangeChew = int32(math.Round(float64(v.FilterChew-v.WeekChewHabit) / float64(v.WeekChewHabit) * 100))
-		}
-
-		// 更新过滤值
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("change_high", "change_rumina", "change_chew").
-			Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"change_high":   v.ChangeHigh,
-				"change_rumina": v.ChangeRumina,
-				"change_chew":   v.ChangeChew,
-			}).Error; err != nil {
-			zaplog.Error("WeeklyUpdateActiveHabit",
-				zap.Error(err),
-				zap.Any("NeckActiveHabit", v),
-				zap.Any("pastureId", pastureId),
-			)
-		}
-	}
-	return err
-}
-
-func (e *Entry) WeeklyUpdateActiveHabitOld(pastureId int64, newNeckActiveHabitList []*model.NeckActiveHabit, xToDay *XToday) (err error) {
-	for _, v := range newNeckActiveHabitList {
-		// 前七天的
-		weekHabitData := e.FindWeekHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
-
-		highDiff := v.FilterHigh - weekHabitData.WeekHighHabit
-		denominator := float64(v.WeekHigh)*0.6 + float64(weekHabitData.WeekHighHabit)*0.2 + float64(xToDay.WeeklyActive)*0.2
-		if highDiff > 0 {
-			v.ChangeHigh = int32(math.Round((float64(highDiff) / denominator) * 100))
-		} else {
-			v.ChangeHigh = int32(math.Round(float64(highDiff) / denominator * 100))
-		}
-
-		if weekHabitData.WeekRuminaHabit != 0 {
-			v.ChangeRumina = int32(math.Round(float64(v.FilterRumina-weekHabitData.WeekRuminaHabit) / float64(weekHabitData.WeekRuminaHabit) * 100))
-		} else {
-			v.ChangeRumina = 0
-		}
-		if weekHabitData.WeekChewHabit != 0 {
-			v.ChangeChew = int32(math.Round(float64(v.FilterChew-weekHabitData.WeekChewHabit) / float64(weekHabitData.WeekChewHabit) * 100))
-		} else {
-			v.ChangeChew = 0
-		}
-
-		sumHabitData := e.FindSumHabitData(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid, xToDay)
-		// 更新过滤值
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select(
-				"week_high_habit", "week_rumina_habit", "week_chew_habit", "week_intake_habit", "week_inactive_habit",
-				"sum_rumina", "sum_intake", "sum_inactive", "sum_active", "sum_max_high", "sum_min_high", "sum_min_chew",
-				"change_high", "change_rumina", "change_chew", "before_three_sum_rumina", "before_three_sum_intake",
-			).Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"week_high_habit":     weekHabitData.WeekHighHabit,
-				"week_rumina_habit":   weekHabitData.WeekRuminaHabit,
-				"week_chew_habit":     weekHabitData.WeekChewHabit,
-				"week_intake_habit":   weekHabitData.WeekIntakeHabit,
-				"week_inactive_habit": weekHabitData.WeekInactiveHabit,
-				"sum_rumina":          sumHabitData.SumRumina,
-				"sum_intake":          sumHabitData.SumIntake,
-				"sum_inactive":        sumHabitData.SumInactive,
-				"sum_active":          sumHabitData.SumActive,
-				"sum_max_high":        sumHabitData.SumMaxHigh,
-				"sum_min_high":        sumHabitData.SumMinHigh,
-				"sum_min_chew":        sumHabitData.SumMinChew,
-				"change_high":         v.ChangeHigh,
-				"change_rumina":       v.ChangeRumina,
-				"change_chew":         v.ChangeChew,
-			}).Error; err != nil {
-			zaplog.Error("WeeklyUpdateActiveHabit",
-				zap.Error(err),
-				zap.Any("NeckActiveHabit", v),
-				zap.Any("pastureId", pastureId),
-			)
-		}
-	}
-	return err
-}
-func (e *Entry) Before3DaysNeckActiveHabit(pastureId int64, processIds []int64, xToDay *XToday) (err error) {
-	newNeckActiveHabitList := make([]*model.NeckActiveHabit, 0)
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id IN (?)", processIds).
-		Order("heat_date,neck_ring_number,frameid").
-		Find(&newNeckActiveHabitList).Error; err != nil {
-		return xerr.WithStack(err)
-	}
-	for _, v := range newNeckActiveHabitList {
-		before3DaysNeckActiveHabit := e.FindBefore3DaysNeckActiveHabit(pastureId, v.NeckRingNumber, v.HeatDate, v.Frameid)
-		// 更新过滤值
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("before_three_sum_rumina", "before_three_sum_intake").
-			Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"before_three_sum_rumina": before3DaysNeckActiveHabit.SumRumina,
-				"before_three_sum_intake": before3DaysNeckActiveHabit.SumIntake,
-			}).Error; err != nil {
-			zaplog.Error("Before3DaysNeckActiveHabit",
-				zap.Error(err),
-				zap.Any("NeckActiveHabit", v),
-				zap.Any("pastureId", pastureId),
-			)
-		}
-	}
-	return nil
-}
-
-// SecondUpdateChangeFilter 第二次更新变化趋势滤波
-func (e *Entry) SecondUpdateChangeFilter(pastureId int64, xToday *XToday) (err error) {
-	newChangeFilterList := make([]*ChangeFilterData, 0)
-	if err = e.DB.Model(new(model.NeckActiveHabit)).
-		Select("id", "neck_ring_number", "change_high", "change_filter", "rumina_filter", "change_rumina",
-			"chew_filter", "change_chew", "heat_date", "frameid", "IF(lact = 0, 0.8, 1) as xlc_dis_count").
-		Where("id > ?", xToday.LastMaxHabitId).
-		Where("heat_date >= ?", time.Now().AddDate(0, 0, -2).Format(model.LayoutDate2)).
-		Where("pasture_id = ?", pastureId).
-		Where("change_filter = ?", model.InitChangeFilter).
-		Where("change_high > ?", MinChangeHigh).
-		Order("neck_ring_number,heat_date,frameid").
-		Limit(int(defaultLimit)).
-		Find(&newChangeFilterList).Error; err != nil {
-		return xerr.WithStack(err)
-	}
-
-	for _, v := range newChangeFilterList {
-		secondFilterData := &SecondFilterData{}
-		frameId := v.FrameId
-		heatDate := v.HeatDate
-		if v.FrameId == 0 {
-			frameId = 11
-			heatDateParse, _ := time.Parse(model.LayoutDate2, heatDate)
-			heatDate = heatDateParse.AddDate(0, 0, -1).Format(model.LayoutDate2)
-		}
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("neck_ring_number", "filter_high", "filter_rumina", "filter_chew").
-			Where("neck_ring_number = ?", v.NeckRingNumber).
-			Where("heat_date = ?", heatDate).
-			Where("frameid = ?", frameId).
-			First(&secondFilterData).Error; err != nil {
-			zaplog.Error("EntryUpdateActiveHabit", zap.Any("FirstFilterUpdate", err))
-		}
-
-		if v.ChangeFilter > MinChangeFilter {
-			secondFilterData.ChangeFilter = float64(v.ChangeFilter)
-		} else {
-			if v.NeckRingNumber == secondFilterData.NeckRingNumber {
-				secondFilterData.ChangeFilter = secondFilterData.ChangeFilter*(1-(float64(xToday.XChangeDiscount)/10)*v.XlcDisCount) +
-					math.Min(float64(v.ChangeHigh), secondFilterData.ChangeFilter+135)*(float64(xToday.XChangeDiscount)/10)*v.XlcDisCount
-			} else {
-				secondFilterData.ChangeFilter = 0
-			}
-		}
-
-		if v.RuminaFilter > MinRuminaFilter {
-			secondFilterData.RuminaFilter = float64(v.ChangeFilter)
-		} else {
-			if v.NeckRingNumber == secondFilterData.NeckRingNumber {
-				discount := float64(xToday.XRuminaDisc) / 10 * v.XlcDisCount
-				if math.Abs(float64(v.ChangeRumina)) > 60 {
-					discount *= 0.5
-				}
-				secondFilterData.RuminaFilter = secondFilterData.RuminaFilter*(1-discount) + float64(v.ChangeRumina)*discount
-			} else {
-				secondFilterData.RuminaFilter = 0
-			}
-		}
-
-		secondFilterData.RuminaFilter = math.Min(50, secondFilterData.RuminaFilter)
-
-		if v.ChewFilter > MinChewFilter {
-			secondFilterData.ChewFilter = float64(v.ChangeChew)
-		} else {
-			if v.NeckRingNumber == secondFilterData.NeckRingNumber {
-				discount := float64(xToday.XRuminaDisc) / 10
-				if math.Abs(float64(v.ChangeChew)) > 60 {
-					discount *= 0.5
-				}
-				secondFilterData.ChewFilter = secondFilterData.ChewFilter*(1-discount) + float64(v.ChangeChew)*discount
-			} else {
-				secondFilterData.ChewFilter = 0
-			}
-		}
-
-		secondFilterData.ChewFilter = math.Min(50, secondFilterData.ChewFilter)
-		if err = e.DB.Model(new(model.NeckActiveHabit)).
-			Select("change_filter", "rumina_filter", "chew_filter").
-			Where("id = ?", v.Id).
-			Updates(map[string]interface{}{
-				"change_filter": secondFilterData.ChangeFilter,
-				"rumina_filter": secondFilterData.RuminaFilter,
-				"chew_filter":   secondFilterData.ChewFilter,
-			}).Error; err != nil {
-			zaplog.Error("SecondUpdateChangeFilter-1", zap.Any("error", err), zap.Any("xToday", xToday))
-		}
-	}
-	return nil
-}
-
-// FilterCorrectAndScoreUpdate 计算活动量变化趋势校正值(活跃度校正)和健康评分
-func (e *Entry) FilterCorrectAndScoreUpdate(pastureId int64, xToday *XToday) error {
-	beginDayDate := time.Now()
-	before7DayDate := beginDayDate.AddDate(0, 0, -7).Format(model.LayoutDate2)
-	before1DayDate := beginDayDate.AddDate(0, 0, -1).Format(model.LayoutDate2)
-
-	activityVolumeList := make([]*ActivityVolume, 0)
-	activityVolumeMap := make(map[string]*ActivityVolume)
-	if err := e.DB.Model(new(model.NeckActiveHabit)).
-		Select("neck_ring_number", "AVG(IF(change_filter>=60, 60, change_filter)) as avg_filter",
-			"ROUND(STD(IF(change_filter>=60, 60, change_filter))) as std_filter", "COUNT(1) as nb").
-		Where("heat_date BETWEEN ? AND ?", before7DayDate, before1DayDate).
-		Where("pasture_id = ?", pastureId).
-		Where(e.DB.Where("high > ?", xToday.High).Or("rumina >= ?", xToday.Rumina)).
-		Where("active_time <= ?", beginDayDate.Add(-12*time.Hour).Format(model.LayoutTime)).
-		Where("change_filter > ?", MinChangeFilter).
-		Having("nb > ?", DefaultNb).
-		Group("neck_ring_number").
-		Find(&activityVolumeList).Error; err != nil {
-		zaplog.Error("ActivityVolumeChanges-0", zap.Any("error", err), zap.Any("xToday", xToday))
-	}
-
-	if len(activityVolumeList) > 0 {
-		for _, v := range activityVolumeList {
-			activityVolumeMap[v.NeckRingNumber] = v
-		}
-	}
-
-	neckActiveHabitList := make([]*model.NeckActiveHabit, 0)
-	if err := e.DB.Model(new(model.NeckActiveHabit)).
-		Where("id <= ?", xToday.CurrMaxHabitId).
-		Where("heat_date >= ?", before1DayDate).
-		Where("pasture_id = ?", pastureId).
-		Where(e.DB.Where("high > ?", xToday.High).Or("rumina > ?", xToday.Rumina)).
-		Find(&neckActiveHabitList).Error; err != nil {
-		zaplog.Error("ActivityVolumeChanges-1", zap.Any("error", err), zap.Any("xToday", xToday))
-		return xerr.WithStack(err)
-	}
-
-	for _, v := range neckActiveHabitList {
-		if filterCorrectMap, ok := activityVolumeMap[v.NeckRingNumber]; ok {
-			filterCorrect := model.DefaultFilterCorrect - int(math.Floor(filterCorrectMap.AvgFilter/3+float64(filterCorrectMap.StdFilter)/2))
-			// 活动量校正系数
-			if err := e.DB.Model(new(model.NeckActiveHabit)).
-				Where("id = ?", v.Id).
-				Where("neck_ring_number = ?", v.NeckRingNumber).
-				Update("filter_correct", filterCorrect).Error; err != nil {
-				zaplog.Error("ActivityVolumeChanges-2", zap.Any("error", err), zap.Any("xToday", xToday))
-				continue
-			}
-		}
-
-		cowScore := calculateScore(v)
-		if err := e.DB.Model(new(model.NeckActiveHabit)).
-			Where("id = ?", v.Id).
-			Update("score", cowScore).Error; err != nil {
-			zaplog.Error("ActivityVolumeChanges-2", zap.Any("error", err), zap.Any("xToday", xToday))
-			continue
-		}
-	}
-	return nil
-}
-
-// UpdateChangeAdJust 更新群体校正数据
-func (e *Entry) UpdateChangeAdJust(pastureId int64, xToday *XToday) error {
-	/*-- 插入群体校正表
-	INSERT INTO data_bar_change(heatdate, frameid, intCurBar, intCurBarName, nb, highchange, changefilter)
-	SELECT h.heatdate, h.frameid, c.intCurBar, c.intCurBarName, COUNT(*) nb, ROUND(AVG(h.highchange)) highchange, ROUND(AVG(h.changefilter) ) changefilter
-	FROM h_activehabit h JOIN cow c ON h.intCowId=c.intCowId
-	WHERE h.heatdate>=(CURDATE() -INTERVAL 1 DAY )
-	GROUP BY h.heatdate, h.frameid, c.intCurBar
-	ORDER BY h.heatdate, h.frameid, c.intCurBarName
-	ON DUPLICATE KEY UPDATE nb = VALUES(nb), highchange = VALUES(highchange), changefilter = VALUES(changefilter);
-
-	UPDATE h_activehabit h
-	JOIN cow c ON h.intCowId=c.intCowId
-	JOIN data_bar_change cg ON h.heatdate=cg.heatdate AND h.frameid=cg.frameid AND c.intCurBar=cg.intCurBar
-	SET h.changeadjust=cg.changefilter
-	WHERE h.id>xBeg_update_act_Id AND h.heatdate>=CURRENT_DATE() - INTERVAL 1 DAY AND ABS(cg.changefilter)>=10;
-	*/
-	res := make([]*model.NeckRingBarChange, 0)
-	oneDayAgo := time.Now().AddDate(0, 0, -1).Format(model.LayoutDate2)
-	if err := e.DB.Table(fmt.Sprintf("%s as h", new(model.NeckActiveHabit).TableName())).
-		Select("h.neck_ring_number,h.heat_date, h.frameid, c.pen_id, c.pen_name, COUNT(*) as nb, ROUND(AVG(h.change_high)) as change_high, ROUND(AVG(h.change_filter)) as change_filter").
-		Joins("JOIN cow as c ON h.neck_ring_number = c.neck_ring_number").
-		Where("h.pasture_id = ?", pastureId).
-		Where("h.heat_date >= ?", oneDayAgo).
-		Where("h.cow_id >= ?", 0).
-		Where("h.cow_id >= ?", 0).
-		Group("h.heat_date, h.frameid, c.pen_id").
-		Order("h.heat_date, h.frameid, c.pen_name").
-		Find(&res).Error; err != nil {
-		return xerr.WithStack(err)
-	}
-
-	// todo ABS(cg.changefilter)>=10;
-	for _, v := range res {
-		if err := e.DB.Model(new(model.NeckActiveHabit)).
-			Where("id > ?", xToday.LastMaxHabitId).
-			Where("heat_date = ?", v.HeatDate).
-			Where("frameid = ?", v.FrameId).
-			Where("neck_ring_number = ?", v.NeckRingNumber).
-			Update("change_adjust", v.ChangeHigh).Error; err != nil {
-			zaplog.Error("UpdateChangeAdJust-1", zap.Any("error", err), zap.Any("xToday", xToday))
-		}
-	}
-
-	return nil
-}
-
 func (e *Entry) UpdateNeckRingOriginalIsShow(habit *model.NeckActiveHabit) error {
 	if err := e.DB.Model(new(model.NeckRingOriginal)).
 		Where("pasture_id = ?", habit.PastureId).