| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 | package modelimport (	"kpt-pasture/util"	"time"	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow")type NeckRingEstrusWarning struct {	Id               int64                      `json:"id"`	NeckRingEstrusId int64                      `json:"neckRingEstrusId"`	PastureId        int64                      `json:"pastureId"`	CowId            int64                      `json:"cowId"`	EarNumber        string                     `json:"earNumber"`	NeckRingNumber   string                     `json:"neckRingNumber"`	FirstTime        string                     `json:"firstTime"`	DateTime         string                     `json:"dateTime"`	LastTime         string                     `json:"lastTime"`	IsPeak           pasturePb.IsShow_Kind      `json:"isPeak"`	WarningKind      pasturePb.Warning_Kind     `json:"warningKind"`	Level            pasturePb.EstrusLevel_Kind `json:"level"`	HighChange       string                     `json:"highChange"`	IsShow           pasturePb.IsShow_Kind      `json:"isShow"`	CreatedAt        int64                      `json:"createdAt"`	UpdatedAt        int64                      `json:"updatedAt"`}func (n *NeckRingEstrusWarning) TableName() string {	return "neck_ring_estrus_warning"}func NewNeckRingEstrusWarning(	neckRingEstrusId, pastureId, cowId int64,	earNumber, neckRingNumber, firstTime, dateTime, lastTime string,	warningKind pasturePb.Warning_Kind,	level pasturePb.EstrusLevel_Kind,) *NeckRingEstrusWarning {	return &NeckRingEstrusWarning{		NeckRingEstrusId: neckRingEstrusId,		PastureId:        pastureId,		CowId:            cowId,		EarNumber:        earNumber,		NeckRingNumber:   neckRingNumber,		FirstTime:        firstTime,		DateTime:         dateTime,		LastTime:         lastTime,		WarningKind:      warningKind,		Level:            level,		IsShow:           pasturePb.IsShow_Ok,	}}// CalculatePzHour 计算最佳配置时间func (n *NeckRingEstrusWarning) CalculatePzHour(lact int32) time.Time {	var pzHour time.Time	dateTime, _ := util.TimeParseLocal(LayoutTime, n.DateTime)	firstTime, _ := util.TimeParseLocal(LayoutTime, n.FirstTime)	// 条件判断	if n.IsPeak == pasturePb.IsShow_Ok || dateTime.Sub(firstTime).Hours() >= 8 {		pzHour = dateTime.Add(8 * time.Hour) // v.datetime + INTERVAL 8 HOUR	} else {		pzHour = firstTime.Add(16 * time.Hour) // v.firsttime + INTERVAL 16 HOUR	}	// 胎次调整	if lact >= 3 {		pzHour = pzHour.Add(-1 * time.Hour) // 减去 1 小时	}	return pzHour}type NeckRingEstrusWarningSlice []*NeckRingEstrusWarningfunc (n NeckRingEstrusWarningSlice) ToPB(cowMap map[int64]*Cow, eventLogMap map[int64]string, matingWindowPeriodKind pasturePb.MatingWindowPeriod_Kind) []*pasturePb.EstrusItem {	res := make([]*pasturePb.EstrusItem, 0)	nowTime := time.Now().Local()	for _, v := range n {		cow, ok := cowMap[v.CowId]		if !ok {			cow = &Cow{Id: v.CowId}		}		lastBreedEventDetails := ""		desc, ok := eventLogMap[cow.Id]		if ok {			lastBreedEventDetails = desc		}		pzHour := v.CalculatePzHour(cow.Lact)		estrusInterval := int32(0)		if v.LastTime != "" {			lastTime, _ := util.TimeParseLocal(LayoutTime, v.LastTime)			diff := pzHour.Sub(lastTime)			estrusInterval = int32(diff.Hours() / 24)		}		optimumMatingStartTime := pzHour.Add(-4 * time.Hour)		optimumMatingEndTime := pzHour.Add(4 * time.Hour)		switch matingWindowPeriodKind {		case pasturePb.MatingWindowPeriod_Front:			if !nowTime.Before(optimumMatingStartTime) {				continue			}		case pasturePb.MatingWindowPeriod_Middle:			if !(nowTime.After(optimumMatingStartTime) && nowTime.Before(optimumMatingEndTime)) {				continue			}		case pasturePb.MatingWindowPeriod_Behind:			if !nowTime.After(optimumMatingEndTime) {				continue			}		}		firstTimeParseLocal, _ := util.TimeParseLocal(LayoutTime, v.FirstTime)		afterAlarmTimeForHours := int32(nowTime.Sub(firstTimeParseLocal).Hours())		postPeakTimeForHours := int32(0)		if v.IsPeak == pasturePb.IsShow_Ok {			dateTimeParseLocal, _ := util.TimeParseLocal(LayoutTime, v.DateTime)			postPeakTimeForHours = int32(nowTime.Sub(dateTimeParseLocal).Hours())		}		data := &pasturePb.EstrusItem{			Id:                     int32(v.Id),			CowId:                  int32(v.CowId),			EarNumber:              v.EarNumber,			PenId:                  cow.PenId,			PenName:                cow.PenName,			MatingTimes:            cow.MatingTimes,			Lact:                   cow.Lact,			CalvingAge:             cow.CalvingAge,			AbortionAge:            cow.AbortionAge,			OptimumMatingStartTime: optimumMatingStartTime.Format(LayoutTime),			OptimumMatingEndTime:   optimumMatingEndTime.Format(LayoutTime),			LastBreedEventDetails:  lastBreedEventDetails,			Level:                  v.Level,			EstrusInterval:         estrusInterval,			BestMatingTime:         pzHour.Format(LayoutTime),			EstrusStartTime:        pzHour.Add(-8 * time.Hour).Format(LayoutTime),			EstrusEndTime:          pzHour.Add(8 * time.Hour).Format(LayoutTime),			AfterAlarmTimeForHours: afterAlarmTimeForHours,			PostPeakTimeForHours:   postPeakTimeForHours,		}		res = append(res, data)	}	return res}const (	Nb1    = 12	Nb2    = 8	MinNb1 = 10)type EstrusWarning struct {	NeckRingEstrusId int64  `json:"neckRingEstrusId"`	HighChange       string `json:"highChange"`	CowId            int64  `json:"cowId"`	DateTime         string `json:"dateTime"`	Nb1              int32  `json:"nb1"`	Nb2              int32  `json:"nb2"`}
 |