Browse Source

crontab: estrusIsPeak update

Yi 4 ngày trước cách đây
mục cha
commit
b494f923c6

+ 6 - 3
module/backend/calendar.go

@@ -70,7 +70,7 @@ func (s *StoreEntry) CalendarToDoHistoryList(ctx context.Context, pastureId int6
 		) as a 
 	JOIN cow b ON a.cow_id = b.id `
 
-	completeSql := fmt.Sprintf("%s ORDER BY a.plan_day DESC", sql)
+	completeSql := fmt.Sprintf("%s WHERE b.admission_status = %d ORDER BY a.plan_day DESC", sql, pasturePb.AdmissionStatus_Admission)
 	if err := s.DB.Raw(completeSql).Find(&calendarToDoList).Error; err != nil {
 		return nil, err
 	}
@@ -259,7 +259,9 @@ func (s *StoreEntry) ImmunisationCowList(ctx context.Context, req *pasturePb.Ite
 		Select("a.id,a.cow_id,a.plan_day,a.plan_name,b.pen_name,b.day_age,b.ear_number,a.plan_id").
 		Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())).
 		Where("a.status = ?", pasturePb.IsShow_No).
-		Where("a.pasture_id = ?", userModel.AppPasture.Id)
+		Where("a.pasture_id = ?", userModel.AppPasture.Id).
+		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission)
+
 	if req.StartDay != "" && req.EndDay != "" {
 		startTime := util.TimeParseLocalUnix(req.StartDay)
 		endTime := util.TimeParseLocalEndUnix(req.EndDay)
@@ -545,7 +547,8 @@ func (s *StoreEntry) MatingCowList(ctx context.Context, req *pasturePb.ItemsRequ
 		b.breed_status,b.cow_type,b.pen_id,b.day_age,b.calving_age,b.abortion_age,b.pen_name`).
 		Joins("left join cow as b on a.cow_id = b.id").
 		Where("a.pasture_id = ?", userModel.AppPasture.Id).
-		Where("a.status = ?", pasturePb.IsShow_No)
+		Where("a.status = ?", pasturePb.IsShow_No).
+		Where("b.admission_status = ?", pasturePb.AdmissionStatus_Admission)
 
 	if req.EndDay != "" {
 		dateTime := util.TimeParseLocalEndUnix(req.EndDay)

+ 1 - 1
module/backend/cow.go

@@ -297,7 +297,7 @@ func (s *StoreEntry) BehaviorCurve(ctx context.Context, req *pasturePb.CowBehavi
 	// 发情数据
 	estrusList := make([]*model.NeckRingEstrus, 0)
 	if err = s.DB.Model(new(model.NeckRingEstrus)).
-		Select("max(id) as id,active_level,active_time,is_peak").
+		Select("id,active_level,active_time,is_peak").
 		Where("cow_id = ?", cowInfo.Id).
 		Where("pasture_id = ?", userModel.AppPasture.Id).
 		Where("active_time BETWEEN ? AND ?", fmt.Sprintf("%s 00:00:00", startDataTime), fmt.Sprintf("%s 23:59:59", endDataTime)).

+ 2 - 1
module/backend/event_health.go

@@ -29,7 +29,8 @@ func (s *StoreEntry) CowDiseaseList(ctx context.Context, req *pasturePb.SearchEv
 		Joins(fmt.Sprintf("JOIN %s AS b on a.cow_id = b.id", new(model.Cow).TableName())).
 		Select("a.*,b.pen_name").
 		Where("a.pasture_id = ?", userModel.AppPasture.Id).
-		Where("a.health_status != ?", pasturePb.HealthStatus_Curable)
+		Where("a.health_status != ?", pasturePb.HealthStatus_Curable).
+		Where("b.admission_status != ?", pasturePb.AdmissionStatus_Admission)
 
 	if len(req.CowIds) > 0 {
 		pref.Where("a.cow_id IN ?", req.CowIds)

+ 1 - 1
module/backend/event_health_more.go

@@ -161,7 +161,7 @@ func (s *StoreEntry) CowDiseaseCurable(ctx context.Context, req *pasturePb.Event
 				return xerr.WithStack(err)
 			}
 
-			cow, err := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, eventCowDisease.CowId)
+			cow, err := s.GetCowInfoByEarNumber(ctx, userModel.AppPasture.Id, eventCowDisease.EarNumber)
 			if err != nil {
 				return xerr.WithStack(err)
 			}

+ 1 - 0
module/crontab/cow_neck_ring_error.go

@@ -313,6 +313,7 @@ func (e *Entry) NeckRingLastDate(pastureId int64) {
 	if err := e.DB.Model(new(model.DataNotice)).
 		Where("pasture_id = ?", pastureId).
 		Where("notice_kind = ?", pasturePb.NoticeType_Neck_Ring_Data_Latency).
+		Where("start_date = ?", nowTime.Format(model.LayoutDate2)).
 		First(&historyData).Error; err != nil {
 		if !errors.Is(err, gorm.ErrRecordNotFound) {
 			return

+ 73 - 33
module/crontab/neck_ring_estrus.go

@@ -181,7 +181,8 @@ func (e *Entry) CowEstrusWarning(pastureId int64, xToday *XToday, nowTime time.T
 
 	zaplog.Info("CowEstrusWarning", zap.Any("neckRingEstrusList", neckRingEstrusList))
 	if len(neckRingEstrusList) > 0 {
-		if err := e.DB.Model(new(model.NeckRingEstrus)).Create(neckRingEstrusList).Error; err != nil {
+		if err := e.DB.Model(new(model.NeckRingEstrus)).
+			Create(neckRingEstrusList).Error; err != nil {
 			zaplog.Error("CowEstrusWarningNew", zap.Any("eventEstrusList", neckRingEstrusList), zap.Any("err", err))
 		}
 	}
@@ -189,17 +190,18 @@ func (e *Entry) CowEstrusWarning(pastureId int64, xToday *XToday, nowTime time.T
 
 // UpdateNewNeckRingEstrus 更新牛只首次发情时间和是否是高峰期
 func (e *Entry) UpdateNewNeckRingEstrus(pastureId int64, xToday *XToday, nowTime time.Time) {
-	e.UpdateEstrusFirstTime1(pastureId, nowTime)
-	e.UpdateEstrusIsPeak(pastureId, nowTime)
+	e.UpdateEstrusFirstTime1(pastureId)
+	e.UpdateEstrusIsPeak(pastureId)
 	e.UpdateEstrusFirstTime2(pastureId, xToday, nowTime)
 	e.UpdateEstrusFirstTime3(pastureId, nowTime)
 }
 
 // UpdateEstrusFirstTime1 更新牛只首次发情时间
-func (e *Entry) UpdateEstrusFirstTime1(pastureId int64, xToday time.Time) {
+func (e *Entry) UpdateEstrusFirstTime1(pastureId int64) {
+	// 获取牛只首次发情时间为空的记录
 	neckRingEstrusList := e.FindNeckRingEstrusByFirstTimeEmpty(pastureId)
 	for _, v := range neckRingEstrusList {
-		cowEstrusStartData := e.FindCowEstrusFirstTime1(pastureId, v.CowId, xToday)
+		cowEstrusStartData := e.FindCowEstrusFirstTime1(pastureId, v.CowId)
 		if cowEstrusStartData != nil && cowEstrusStartData.FirstTime != "" {
 			if err := e.DB.Model(new(model.NeckRingEstrus)).
 				Where("id = ?", v.Id).
@@ -259,54 +261,92 @@ func (e *Entry) UpdateEstrusFirstTime3(pastureId int64, xToday time.Time) {
 	}
 }
 
-func (e *Entry) UpdateEstrusIsPeak(pastureId int64, xToday time.Time) {
+func (e *Entry) UpdateEstrusIsPeak(pastureId int64) {
 	neckRingEstrusList := make([]*model.NeckRingEstrus, 0)
 	if err := e.DB.Model(new(model.NeckRingEstrus)).
-		Where("first_time != ?", "").
-		Where("is_peak = ?", pasturePb.IsShow_Ok).
-		Where("is_show = ?", pasturePb.IsShow_Ok).
+		Where("first_time >= ?", time.Now().Local().AddDate(0, 0, -3).Format(model.LayoutTime)).
+		Where("active_time != ?", "").
 		Where("pasture_id = ?", pastureId).
+		Order("cow_id,first_time,active_time ASC").
 		Find(&neckRingEstrusList).Error; err != nil {
 		zaplog.Error("UpdateEstrusIsPeak", zap.Any("Find", err))
 	}
 
-	for _, estrus := range neckRingEstrusList {
-		activeTime, _ := util.TimeParseLocal(model.LayoutTime, estrus.ActiveTime)
-		if activeTime.Before(xToday) || activeTime.After(xToday.AddDate(0, 0, 1)) {
-			continue
+	if len(neckRingEstrusList) <= 0 {
+		return
+	}
+
+	neckRingEstrusFirstMap := make(map[string][]*model.NeckRingEstrus)
+	for _, v := range neckRingEstrusList {
+		if neckRingEstrusFirstMap[fmt.Sprintf("%s_%d", v.FirstTime, v.CowId)] == nil {
+			neckRingEstrusFirstMap[fmt.Sprintf("%s_%d", v.FirstTime, v.CowId)] = make([]*model.NeckRingEstrus, 0)
 		}
+		neckRingEstrusFirstMap[fmt.Sprintf("%s_%d", v.FirstTime, v.CowId)] = append(neckRingEstrusFirstMap[fmt.Sprintf("%s_%d", v.FirstTime, v.CowId)], v)
+	}
 
-		var exists bool
-		if err := e.DB.Model(new(model.NeckRingEstrus)).
-			Where("cow_id = ?", estrus.CowId).
-			Where("first_time != ?", "").
-			Where("active_time BETWEEN ? AND ?", xToday, xToday.AddDate(0, 0, 1)).
-			Where("active_time BETWEEN ? AND ?", estrus.FirstTime, activeTime.Add(-2*time.Hour)).
-			Select("1").
-			Limit(1).
-			Scan(&exists).Error; err != nil {
-			zaplog.Error("UpdateEstrusIsPeak", zap.Any("exists", err))
+	nowTime := time.Now().Local()
+	peakIsShow := make([]int64, 0)
+	peakIsNo := make([]int64, 0)
+	for _, estrusItems := range neckRingEstrusFirstMap {
+		eLen := len(estrusItems)
+		if eLen <= 0 {
 			continue
 		}
-		if exists {
-			if err := e.DB.Model(estrus).
-				Update("is_peak", pasturePb.IsShow_No).Error; err != nil {
-				zaplog.Error("UpdateEstrusIsPeak", zap.Any("v", estrus), zap.Any("err", err))
+		// 判断是否是高峰期,和当前时间相比,如果超过2个小就是高峰期
+		lastItem := estrusItems[eLen-1]
+		lastActiveTime, err := time.Parse(model.LayoutTime, lastItem.ActiveTime)
+		if err != nil {
+			zaplog.Error("UpdateEstrusIsPeak", zap.Any("Parse", err), zap.Any("lastItem", lastItem))
+			continue
+		}
+		sub := nowTime.Sub(lastActiveTime.Local()).Hours()
+		if sub > 2 {
+			peakIsShow = append(peakIsShow, lastItem.Id)
+			for i := 0; i < eLen-1; i++ {
+				peakIsNo = append(peakIsNo, estrusItems[i].Id)
 			}
+		} else {
+			peakIsNo = append(peakIsNo, lastItem.Id)
+		}
+	}
+
+	zaplog.Info("UpdateEstrusIsPeak",
+		zap.Any("pastureId", pastureId),
+		zap.Any("peakIsShow", peakIsShow),
+		zap.Any("peakIsNo", peakIsNo),
+	)
+
+	if len(peakIsShow) > 0 {
+		if err := e.DB.Model(new(model.NeckRingEstrus)).
+			Where("id IN ?", peakIsShow).
+			Where("pasture_id = ?", pastureId).
+			Update("is_peak", pasturePb.IsShow_Ok).Error; err != nil {
+			zaplog.Error("UpdateEstrusIsPeak", zap.Any("Update", err))
+		}
+	}
+
+	if len(peakIsNo) > 0 {
+		if err := e.DB.Model(new(model.NeckRingEstrus)).
+			Where("id IN ?", peakIsNo).
+			Where("pasture_id = ?", pastureId).
+			Update("is_peak", pasturePb.IsShow_No).Error; err != nil {
+			zaplog.Error("UpdateEstrusIsPeak", zap.Any("Update", err))
 		}
 	}
 }
 
 // FindCowEstrusFirstTime1 查找牛只昨天是否有发情数据
-func (e *Entry) FindCowEstrusFirstTime1(pastureId, cowId int64, xToday time.Time) *EstrusStartData {
+func (e *Entry) FindCowEstrusFirstTime1(pastureId, cowId int64) *EstrusStartData {
 	firstTimeEventEstrus := &EstrusStartData{}
+	nowTime := time.Now().Local()
+	startDate := fmt.Sprintf("%s 00:00:00", nowTime.AddDate(0, 0, -1).Format(model.LayoutDate2))
+	endDate := fmt.Sprintf("%s 23:59:59", nowTime.Format(model.LayoutDate2))
 	if err := e.DB.Model(new(model.NeckRingEstrus)).
-		Select("cow_id,MIN(STR_TO_DATE(first_time, '%Y-%m-%d %H:%i:%s')) as first_time").
-		Where("active_time BETWEEN ? AND ?",
-			fmt.Sprintf("%s 00:00:00", xToday.AddDate(0, 0, -1).Format(model.LayoutDate2)),
-			fmt.Sprintf("%s 23:59:59", xToday.Format(model.LayoutDate2)),
-		).Where("pasture_id = ?", pastureId).
+		Select("cow_id,first_time").
+		Where("active_time BETWEEN ? AND ?", startDate, endDate).
+		Where("pasture_id = ?", pastureId).
 		Where("cow_id = ?", cowId).
+		Order("first_time ASC").
 		First(&firstTimeEventEstrus).Error; err != nil {
 		return nil
 	}

+ 0 - 1
module/mqtt/mqtt_handle.go

@@ -43,7 +43,6 @@ func (e *Entry) InitReceiverMapUpdater() {
 			receiverMutex.Lock()
 			receiverMap = e.FindAppPastureReceiver()
 			receiverMutex.Unlock()
-			zaplog.Info("ReceiverMap updated successfully")
 		}
 	}
 }

+ 8 - 0
util/util_test.go

@@ -548,4 +548,12 @@ func Test_demo(t *testing.T) {
 	}
 
 	fmt.Println(strings.TrimRight(str1, ","))
+
+	xToday := time.Now().Local()
+	activeTime, _ := TimeParseLocal(LayoutTime, "2025-06-18 03:00:00")
+	if activeTime.Before(xToday) || activeTime.After(xToday.AddDate(0, 0, 1)) {
+		fmt.Println("1")
+	} else {
+		fmt.Println("2")
+	}
 }