| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889 | package modelimport (	"fmt"	"math"	"time"	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow")type Cow struct {	Id                    int64                          `json:"id"`	PastureId             int64                          `json:"pastureId"`             // 牧场id	Sex                   pasturePb.Genders_Kind         `json:"sex"`                   // 性别	NeckRingNumber        string                         `json:"neckRingNumber"`        // 脖环号	EarNumber             string                         `json:"earNumber"`             // 耳标号	EleEarNumber          string                         `json:"eleEarNumber"`          // 电子耳标号	EarOldNumber          string                         `json:"earOldNumber"`          // 旧耳标号	PenId                 int32                          `json:"penId"`                 // 栏舍id	PenName               string                         `json:"penName"`               // 栏舍名称	Lact                  int32                          `json:"lact"`                  // 胎次	DayAge                int32                          `json:"dayAge"`                // 日龄	CalvingAge            int32                          `json:"calvingAge"`            // 产后天使	PregnancyAge          int32                          `json:"pregnancyAge"`          // 怀孕天数 孕检结果有阳性更新,产犊后至0	MatingAge             int32                          `json:"matingAge"`             // 配种天数	AdmissionAge          int32                          `json:"admissionAge"`          // 入场日龄	AbortionAge           int32                          `json:"abortionAge"`           // 流产天数	LactationAge          int32                          `json:"lactationAge"`          // 泌乳天数	DryMilkAge            int32                          `json:"dryMilkAge"`            // 干奶天数	CowType               pasturePb.CowType_Kind         `json:"cowType"`               // 牛只类型	MilkKind              pasturePb.CowMilk_Kind         `json:"milkKind"`              // 牛只奶属性	BreedStatus           pasturePb.BreedStatus_Kind     `json:"breedStatus"`           // 繁殖状态	CowKind               pasturePb.CowKind_Kind         `json:"cowKind"`               // 牛只品种	BirthWeight           int64                          `json:"birthWeight"`           // 出生体重	CurrentWeight         int64                          `json:"currentWeight"`         // 当前体重	CurrentHeight         int64                          `json:"currentHeight"`         // 当前身高	AdmissionWeight       int64                          `json:"admissionWeight"`       // 入场体重	AdmissionPrice        float32                        `json:"admissionPrice"`        // 入场价格	SourceKind            pasturePb.CowSource_Kind       `json:"sourceKind"`            // 来源哪里	PurposeKind           pasturePb.Purpose_Kind         `json:"purposeKind"`           // 用途	FatherNumber          string                         `json:"fatherNumber"`          // 父号	MotherNumber          string                         `json:"motherNumber"`          // 母号	AdmissionStatus       pasturePb.AdmissionStatus_Kind `json:"admissionStatus"`       // 在场状态	IsPregnant            pasturePb.IsShow_Kind          `json:"isPregnant"`            // 是否怀孕	IsForbiddenMating     pasturePb.IsShow_Kind          `json:"isForbiddenMating"`     // 是否禁配 1 是 2 否	HealthStatus          pasturePb.HealthStatus_Kind    `json:"healthStatus"`          // 健康状态	WeaningAt             int64                          `json:"weaningAt"`             // 断奶时间	BirthAt               int64                          `json:"birthAt"`               // 出生时间	AdmissionAt           int64                          `json:"admissionAt"`           // 入场时间	DepartureAt           int64                          `json:"departureAt"`           // 离场时间	WeaningWeight         int64                          `json:"weaningWeight"`         // 断奶体重	DeparturePrice        float32                        `json:"departurePrice"`        // 离场价格	DepartureAvgWeight    int32                          `json:"departureAvgWeight"`    // 离场平均体重	FirstMatingAt         int64                          `json:"firstMatingAt"`         // 首次配种时间	AllMatingTimes        int32                          `json:"allMatingTimes"`        // 总配次	AllAbortionTimes      int32                          `json:"allAbortionTimes"`      // 总流产次数	MatingTimes           int32                          `json:"matingTimes"`           // 配种次数	AbortionTimes         int32                          `json:"abortionTimes"`         // 流产次数	PregnancyCheckName    string                         `json:"pregnancyCheckName"`    // 孕检名称	WeeklyActive          int32                          `json:"weeklyActive"`          // 每周活跃度	LastEstrusAt          int64                          `json:"lastEstrusAt"`          // 最后一次发情时间	LastCalvingAt         int64                          `json:"lastCalvingAt"`         // 最后一次产犊时间	LastMatingAt          int64                          `json:"lastMatingAt"`          // 最后一次配种时间	LastBullNumber        string                         `json:"lastBullNumber"`        // 最后一次配种牛号	LastPregnantCheckAt   int64                          `json:"lastPregnantCheckAt"`   // 最后一次孕检时间	LastDryMilkAt         int64                          `json:"lastDryMilkAt"`         // 最近一次干奶日期	LastForbiddenMatingAt int64                          `json:"lastForbiddenMatingAt"` // 最近一次禁配时间	LastSecondWeight      int64                          `json:"lastSecondWeight"`      // 最后第二次称重	LastSecondWeightAt    int64                          `json:"lastSecondWeightAt"`    // 最后第二次称重时间	LastAbortionAt        int64                          `json:"lastAbortionAt"`        // 最近一次流产时间	LastWeightAt          int64                          `json:"lastWeightAt"`          // 最近一次称重时间	BatchNumber           string                         `json:"batchNumber"`           // 批次号	CreatedAt             int64                          `json:"createdAt"`	UpdatedAt             int64                          `json:"updatedAt"`}func (c *Cow) TableName() string {	return "cow"}// EventUpdate 牛只基本信息维护func (c *Cow) EventUpdate(weeklyActive int32) {	c.DayAge = c.GetDayAge()             // 日龄	c.CalvingAge = c.GetCalvingAge()     // 产后天数	c.PregnancyAge = c.GetDaysPregnant() // 怀孕天数	c.AdmissionAge = c.GetAdmissionAge() // 入场天数	c.AbortionAge = c.GetAbortionAge()   // 流产天数	c.WeeklyActive = weeklyActive        // 周活动量	c.LactationAge = c.GetLactationAge() // 泌乳天数	c.DryMilkAge = c.GetDryMilkAge()     // 干奶天数	c.MatingAge = c.GetMatingAge()       // 配后天数	if c.DayAge == 60 {		c.CowType = pasturePb.CowType_Weaned_Calf	}}// EventCalvingUpdate 产犊更新func (c *Cow) EventCalvingUpdate(calvingAt int64) {	c.Lact += 1	c.MatingTimes = 0	c.PregnancyAge = 0	c.AbortionTimes = 0	c.BreedStatus = pasturePb.BreedStatus_Calving	c.IsPregnant = pasturePb.IsShow_No	c.LastCalvingAt = calvingAt	c.CalvingAge = c.GetCalvingAge()	c.CowType = pasturePb.CowType_Breeding_Calf	c.MilkKind = pasturePb.CowMilk_Lactation}// EventWeaningUpdate 断奶更新func (c *Cow) EventWeaningUpdate(weaningAt int64, penId int32, currentWeight int64) {	c.PenId = penId	c.WeaningAt = weaningAt	c.CurrentWeight = currentWeight	c.LastWeightAt = weaningAt	c.WeaningWeight = currentWeight}// EventPregnantCheckUpdate 孕检更新func (c *Cow) EventPregnantCheckUpdate(breedStatus pasturePb.BreedStatus_Kind, pregnantCheckAt int64,	isPregnant pasturePb.IsShow_Kind, pregnancyCheckName string) {	c.BreedStatus = breedStatus	c.LastPregnantCheckAt = pregnantCheckAt	c.IsPregnant = isPregnant	c.PregnancyCheckName = pregnancyCheckName}// EventAbortionUpdate 流产更新func (c *Cow) EventAbortionUpdate(abortionAt int64, isLact pasturePb.IsShow_Kind) {	c.IsPregnant = pasturePb.IsShow_No	c.LastAbortionAt = abortionAt	c.BreedStatus = pasturePb.BreedStatus_Abort	c.AbortionTimes += 1	c.AllAbortionTimes += 1	c.PregnancyAge = 0	if isLact == pasturePb.IsShow_Ok {		c.Lact += 1	}}// EventWeightUpdate 称重更新func (c *Cow) EventWeightUpdate(weight, height, weightAt int64) {	c.LastSecondWeight = c.CurrentWeight	c.LastSecondWeightAt = c.LastWeightAt	c.LastWeightAt = weightAt	c.CurrentWeight = weight	c.CurrentHeight = height}// EventHealthStatusUpdate 健康状态更新func (c *Cow) EventHealthStatusUpdate(healthStatus pasturePb.HealthStatus_Kind) {	c.HealthStatus = healthStatus}// EventPenUpdate 更新栏舍func (c *Cow) EventPenUpdate(pen *Pen) {	c.PenId = pen.Id	c.PenName = pen.Name}// EventEarNumberUpdate 更新耳标号func (c *Cow) EventEarNumberUpdate(newEarNumber string) {	c.EarOldNumber = c.EarNumber	c.EarNumber = newEarNumber}// EventDeathUpdate 更新牛只死亡信息func (c *Cow) EventDeathUpdate(eventAt int64) {	c.AdmissionStatus = pasturePb.AdmissionStatus_Die	c.HealthStatus = pasturePb.HealthStatus_Dead	c.DepartureAt = eventAt	c.NeckRingNumber = ""}// EventSaleUpdate 更新牛只销售信息func (c *Cow) EventSaleUpdate(eventSale *EventSale) {	c.DepartureAt = eventSale.SaleAt	c.NeckRingNumber = ""	c.DeparturePrice = float32(eventSale.SalePrice)	if eventSale.SaleKind == pasturePb.SalesType_Out {		c.HealthStatus = pasturePb.HealthStatus_Out		c.AdmissionStatus = pasturePb.AdmissionStatus_Out	}	if eventSale.SaleKind == pasturePb.SalesType_Sales {		c.AdmissionStatus = pasturePb.AdmissionStatus_Sale	}	if eventSale.SaleCowCount > 0 {		c.DepartureAvgWeight = eventSale.SaleAllWeight / eventSale.SaleCowCount	}}// EventMatingUpdate 配种更新func (c *Cow) EventMatingUpdate(matingAt int64, bullNumber string, isReMating bool) {	c.LastMatingAt = matingAt	c.LastBullNumber = bullNumber	c.IsPregnant = pasturePb.IsShow_No	c.BreedStatus = pasturePb.BreedStatus_Breeding	if c.FirstMatingAt <= 0 {		c.FirstMatingAt = matingAt	}	if !isReMating {		c.MatingTimes += 1		c.AllMatingTimes += 1	}	if c.Lact == 0 {		c.CowType = pasturePb.CowType_Reserve_Calf	}}// EstrusUpdate 发情更新func (c *Cow) EstrusUpdate(estrusAt int64) {	c.LastEstrusAt = estrusAt}// EventDryMilkUpdate 干奶更新func (c *Cow) EventDryMilkUpdate(dryMilkAt int64, pen *Pen) {	c.LastDryMilkAt = dryMilkAt	c.MilkKind = pasturePb.CowMilk_Dry_Milk	c.PenId = pen.Id	c.PenName = pen.Name}// ForbiddenMatingUpdate 禁配更新func (c *Cow) ForbiddenMatingUpdate(forbiddenMatingAt int64) {	c.IsForbiddenMating = pasturePb.IsShow_Ok	c.LastForbiddenMatingAt = forbiddenMatingAt	c.BreedStatus = pasturePb.BreedStatus_No_Mating}// UnForbiddenMatingUpdate 解禁配更新func (c *Cow) UnForbiddenMatingUpdate() {	c.IsForbiddenMating = pasturePb.IsShow_No	c.LastForbiddenMatingAt = 0	c.BreedStatus = pasturePb.BreedStatus_UnBreed}// GetAvgDailyWeight 牛只平均日增重func (c *Cow) GetAvgDailyWeight() float32 {	if c.AdmissionAge <= 0 {		c.AdmissionAge = c.GetAdmissionAge()	}	if c.AdmissionAge <= 0 {		return 0	}	return float32(c.CurrentWeight-c.AdmissionWeight) / 1000 / float32(c.AdmissionAge)}// GetDayAge 日龄func (c *Cow) GetDayAge() int32 {	if c.BirthAt <= 0 {		return 0	}	return int32(math.Floor(float64(time.Now().Local().Unix()-c.BirthAt) / 86400))}// GetEventDayAge 获取事件发生的日龄func (c *Cow) GetEventDayAge(eventAt int64) int32 {	if c.BirthAt <= 0 {		return 0	}	return int32(math.Floor(float64(eventAt-c.BirthAt) / 86400))}// GetCalvingAge 产后天数func (c *Cow) GetCalvingAge() int32 {	if c.LastCalvingAt <= 0 {		return 0	}	return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastCalvingAt) / 86400))}// GetDaysPregnant 怀孕天数func (c *Cow) GetDaysPregnant() int32 {	if c.BreedStatus == pasturePb.BreedStatus_Pregnant &&		c.AdmissionStatus == pasturePb.AdmissionStatus_Admission &&		c.IsPregnant == pasturePb.IsShow_Ok {		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastMatingAt) / 86400))	}	return 0}// GetDaysPregnancy 牛只预产日期func (c *Cow) GetDaysPregnancy(pregnancyAgeValue int32) int32 {	if c.BreedStatus == pasturePb.BreedStatus_Pregnant &&		c.AdmissionStatus == pasturePb.AdmissionStatus_Admission &&		c.IsPregnant == pasturePb.IsShow_Ok {		return int32(math.Floor(float64(c.LastMatingAt + int64(pregnancyAgeValue)*86400)))	}	return 0}// GetLactationDays 泌乳天数func (c *Cow) GetLactationDays() int32 {	if c.BreedStatus == pasturePb.BreedStatus_Calving && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastCalvingAt) / 86400))	}	return 0}// GetAdmissionAge 入场天数func (c *Cow) GetAdmissionAge() int32 {	if c.AdmissionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {		return int32(math.Floor(float64(time.Now().Local().Unix()-c.AdmissionAt) / 86400))	}	return 0}func (c *Cow) GetEventAdmissionAge(eventAt int64) int32 {	if eventAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {		return int32(math.Floor(float64(eventAt-c.AdmissionAt) / 86400))	}	return 0}// GetAverageDailyWeight 平均日增重(最后一次称重 - 入场体重)÷在群天数func (c *Cow) GetAverageDailyWeight() float64 {	if c.AdmissionAge <= 0 {		c.AdmissionAge = c.GetAdmissionAge()	}	if c.AdmissionAge <= 0 {		return 0	}	if c.CurrentWeight-c.AdmissionWeight <= 0 {		return 0	}	return float64(c.CurrentWeight-c.AdmissionWeight) / 1000 / float64(c.AdmissionAge)}// GetPreviousStageDailyWeight 上一个阶段日增重func (c *Cow) GetPreviousStageDailyWeight() float64 {	if c.CurrentWeight-c.LastSecondWeight > 0 && c.LastWeightAt-c.LastSecondWeightAt > 0 {		days := int32(math.Floor(float64(c.LastWeightAt-c.LastSecondWeightAt) / 86400))		if days <= 0 {			return float64(c.CurrentWeight - c.LastSecondWeight)		}		dayWeight := math.Round(1.0 * float64(c.CurrentWeight-c.LastSecondWeight) / float64(days))		return dayWeight / 1000	}	return 0}// GetAbortionAge 流产天数func (c *Cow) GetAbortionAge() int32 {	if c.LastAbortionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastAbortionAt) / 86400))	}	return 0}// GetLactationAge 泌乳天数func (c *Cow) GetLactationAge() int32 {	if c.LastCalvingAt <= 0 {		return 0	}	if c.MilkKind == pasturePb.CowMilk_Lactation ||		c.BreedStatus == pasturePb.BreedStatus_Calving ||		c.BreedStatus == pasturePb.BreedStatus_Abort {		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastCalvingAt) / 86400))	}	return c.LactationAge}// GetDryMilkAge 干奶天数func (c *Cow) GetDryMilkAge() int32 {	if c.MilkKind == pasturePb.CowMilk_Dry_Milk {		return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastDryMilkAt) / 86400))	}	return c.DryMilkAge}func (c *Cow) GetMatingAge() int32 {	if c.LastMatingAt <= 0 {		return 0	}	return int32(math.Floor(float64(time.Now().Local().Unix()-c.LastMatingAt) / 86400))}type CowSlice []*Cowfunc (c CowSlice) ToPB(	cowTypeMap map[pasturePb.CowType_Kind]string,	breedStatusMap map[pasturePb.BreedStatus_Kind]string,	cowKindMap map[pasturePb.CowKind_Kind]string,	cowSourceMap map[pasturePb.CowSource_Kind]string,	admissionStatusMap map[pasturePb.AdmissionStatus_Kind]string,	healthStatusMap map[pasturePb.HealthStatus_Kind]string,	purposeMap map[pasturePb.Purpose_Kind]string,	pregnancyAge int32,) []*pasturePb.CowDetails {	res := make([]*pasturePb.CowDetails, len(c))	for i, v := range c {		sex := "公"		if v.Sex == pasturePb.Genders_Female {			sex = "母"		}		lastWeightAtFormat := ""		if v.LastWeightAt > 0 {			lastWeightAtFormat = time.Unix(v.LastWeightAt, 0).Local().Format(LayoutDate2)		}		isPregnantName := ""		if v.IsPregnant == pasturePb.IsShow_Ok {			isPregnantName = "已孕"		} else {			isPregnantName = "未孕"		}		admissionAtFormat := ""		if v.AdmissionAt > 0 {			admissionAtFormat = time.Unix(v.AdmissionAt, 0).Local().Format(LayoutDate2)		}		birthAtFormat := ""		if v.BirthAt > 0 {			birthAtFormat = time.Unix(v.BirthAt, 0).Local().Format(LayoutDate2)		}		weaningAtFormat := ""		if v.WeaningAt > 0 {			weaningAtFormat = time.Unix(v.WeaningAt, 0).Local().Format(LayoutDate2)		}		firstMatingAtFormat := ""		if v.FirstMatingAt > 0 {			firstMatingAtFormat = time.Unix(v.FirstMatingAt, 0).Local().Format(LayoutDate2)		}		lastMatingAtFormat := ""		if v.LastMatingAt > 0 {			lastMatingAtFormat = time.Unix(v.LastMatingAt, 0).Local().Format(LayoutDate2)		}		lastPregnantCheckAtFormat := ""		if v.LastPregnantCheckAt > 0 {			lastPregnantCheckAtFormat = time.Unix(v.LastPregnantCheckAt, 0).Local().Format(LayoutDate2)		}		lastCalvingAtFormat := ""		if v.LastCalvingAt > 0 {			lastCalvingAtFormat = time.Unix(v.LastCalvingAt, 0).Local().Format(LayoutDate2)		}		lastAbortionAtFormat := ""		if v.LastAbortionAt > 0 {			lastAbortionAtFormat = time.Unix(v.LastAbortionAt, 0).Local().Format(LayoutDate2)		}		lastSecondWeightAtFormat := ""		if v.LastSecondWeightAt > 0 {			lastSecondWeightAtFormat = time.Unix(v.LastSecondWeightAt, 0).Local().Format(LayoutDate2)		}		departureAtFormat := ""		if v.DepartureAt > 0 {			departureAtFormat = time.Unix(v.DepartureAt, 0).Local().Format(LayoutDate2)		}		lastForbiddenMatingAtFormat := ""		if v.LastForbiddenMatingAt > 0 {			lastForbiddenMatingAtFormat = time.Unix(v.LastForbiddenMatingAt, 0).Local().Format(LayoutDate2)		}		lastEstrusAtFormat := ""		if v.LastEstrusAt > 0 {			lastEstrusAtFormat = time.Unix(v.LastEstrusAt, 0).Local().Format(LayoutDate2)		}		cowTypeName := ""		if cn, ok := cowTypeMap[v.CowType]; ok {			cowTypeName = cn		}		breedStatusName := ""		if bs, ok := breedStatusMap[v.BreedStatus]; ok {			breedStatusName = bs		}		cowKindName := ""		if ck, ok := cowKindMap[v.CowKind]; ok {			cowKindName = ck		}		sourceName := ""		if sn, ok := cowSourceMap[v.SourceKind]; ok {			sourceName = sn		}		admissionStatusName := ""		if as, ok := admissionStatusMap[v.AdmissionStatus]; ok {			admissionStatusName = as		}		healthStatusName := ""		if hs, ok := healthStatusMap[v.HealthStatus]; ok {			healthStatusName = hs		}		pregnancyDate := ""		if pregnancyAgeAt := v.GetDaysPregnancy(pregnancyAge); pregnancyAgeAt > 0 {			pregnancyDate = time.Unix(int64(pregnancyAge), 0).Local().Format(LayoutDate2)		}		purposeName := ""		if pn, ok := purposeMap[v.PurposeKind]; ok {			purposeName = pn		}		pregnancyCheckTimes := "初检"		if v.PregnancyCheckName == PregnantCheckForSecond {			pregnancyCheckTimes = "复检"		}		res[i] = &pasturePb.CowDetails{			CowId:                       int32(v.Id),			Sex:                         sex,			NeckRingNumber:              v.NeckRingNumber,			PenName:                     v.PenName,			Lact:                        v.Lact,			CowTypeName:                 cowTypeName,			CowType:                     v.CowType,			BreedStatusName:             breedStatusName,			BreedStatus:                 v.BreedStatus,			CowKindName:                 cowKindName,			EarNumber:                   v.EarNumber,			BirthWeight:                 float32(v.BirthWeight) / 1000,			CurrentWeight:               float32(v.CurrentWeight) / 1000,			CurrentHeight:               int32(v.CurrentHeight),			DayAge:                      v.DayAge,			AdmissionAge:                v.AdmissionAge,			SourceName:                  sourceName,			MotherNumber:                v.MotherNumber,			FatherNumber:                v.FatherNumber,			AdmissionStatusName:         admissionStatusName,			HealthStatusName:            healthStatusName,			IsPregnantName:              isPregnantName,			AdmissionAtFormat:           admissionAtFormat,			BirthAtFormat:               birthAtFormat,			WeaningAtFormat:             weaningAtFormat,			CalvingAge:                  v.GetCalvingAge(),			AbortionAge:                 v.AbortionAge,			MatingTimes:                 v.MatingTimes,			AbortionTimes:               v.AbortionTimes,			FirstMatingAtFormat:         firstMatingAtFormat,			LastMatingAtFormat:          lastMatingAtFormat,			LastBullNumber:              v.LastBullNumber,			LastPregnantCheckAtFormat:   lastPregnantCheckAtFormat,			LastWeightAtFormat:          lastWeightAtFormat,			LastCalvingAtFormat:         lastCalvingAtFormat,			LastAbortionAtFormat:        lastAbortionAtFormat,			LastSecondWeight:            float32(v.LastSecondWeight) / 1000,			LastSecondWeightAtFormat:    lastSecondWeightAtFormat,			DepartureAtFormat:           departureAtFormat,			DeparturePrice:              v.DeparturePrice,			DepartureWeight:             float32(v.DepartureAvgWeight / 1000),			LastForbiddenMatingAtFormat: lastForbiddenMatingAtFormat,			LastEstrusAtFormat:          lastEstrusAtFormat,			PregnancyDate:               pregnancyDate,			PregnancyCheckTimes:         pregnancyCheckTimes,			AvgDailyWeight:              float32(v.GetAverageDailyWeight()),			EleEarNumber:                v.EleEarNumber,			AdmissionPrice:              v.AdmissionPrice,			PurposeName:                 purposeName,			BatchNumber:                 v.BatchNumber,			AdmissionWeight:             float32(v.AdmissionWeight / 1000),			DepartureAvgWeight:          float32(v.DepartureAvgWeight / 1000),			WeaningWeight:               float32(v.WeaningWeight / 1000),		}	}	return res}func (c CowSlice) ToPB2(penWeightSlice PenWeightSlice) []*pasturePb.CowList {	res := make([]*pasturePb.CowList, len(c))	for i, v := range c {		penWeight := penWeightSlice.GetPenWeight(v.PenId)		penAvgWeight := float32(0)		cowPenAvgWeightDiffValue := float32(0)		if penWeight != nil {			penAvgWeight = float32(penWeight.AvgWeight) / 1000			cowPenAvgWeightDiffValue = float32(v.CurrentWeight-int64(penWeight.AvgWeight)) / 1000		}		res[i] = &pasturePb.CowList{			CowId:                    int32(v.Id),			DayAge:                   v.DayAge,			AverageDailyWeightGain:   float32(v.GetAverageDailyWeight()),			EarNumber:                v.EarNumber,			PenName:                  v.PenName,			BirthAt:                  int32(v.BirthAt),			BirthWeight:              float32(v.BirthWeight) / 1000,			CurrentWeight:            float32(v.CurrentWeight) / 1000,			LastWeightAt:             int32(v.LastWeightAt),			AdmissionAge:             v.AdmissionAge,			AdmissionWeight:          float32(v.AbortionAge) / 1000,			PreviousStageDailyWeight: float32(v.GetPreviousStageDailyWeight()),			PenAvgWeight:             penAvgWeight,			CowPenAvgWeightDiffValue: cowPenAvgWeightDiffValue,		}	}	return res}// NewEnterCow 入场新增牛只func NewEnterCow(pastureId int64, req *pasturePb.EventEnterRequest, penMap map[int32]*Pen) *Cow {	var isPregnant = pasturePb.IsShow_No	if req.BreedStatus == pasturePb.BreedStatus_Pregnant {		isPregnant = pasturePb.IsShow_Ok	}	admissionAt := int64(0)	switch req.CowSource {	case pasturePb.CowSource_Calving:		admissionAt = int64(req.BirthAt)	case pasturePb.CowSource_Transfer_In:		admissionAt = int64(req.EnterAt)	case pasturePb.CowSource_Buy:		admissionAt = int64(req.EnterAt)	}	breedStatus := pasturePb.BreedStatus_Invalid	isForbiddenMating := pasturePb.IsShow_No	cowType := pasturePb.CowType_Invalid	if req.Sex == pasturePb.Genders_Female {		if req.Lact == 0 && req.MatingAt <= 0 {			breedStatus = pasturePb.BreedStatus_UnBreed			cowType = pasturePb.CowType_Reserve_Calf		}		if req.MatingAt > 0 && (req.PregnantCheckResult != pasturePb.PregnantCheckResult_Pregnant &&			req.PregnantCheckResult != pasturePb.PregnantCheckResult_UnPregnant) &&			req.MatingAt >= req.CalvingAt && req.MatingAt >= req.AbortionAt {			breedStatus = pasturePb.BreedStatus_Breeding			if req.Lact == 0 {				cowType = pasturePb.CowType_Reserve_Calf			} else {				cowType = pasturePb.CowType_Breeding_Calf			}		}		if req.MatingAt > 0 && req.PregnantCheckResult == pasturePb.PregnantCheckResult_Pregnant &&			req.MatingAt >= req.CalvingAt && req.MatingAt >= req.AbortionAt {			breedStatus = pasturePb.BreedStatus_Pregnant			if req.Lact == 0 {				cowType = pasturePb.CowType_Reserve_Calf			} else {				cowType = pasturePb.CowType_Breeding_Calf			}		}		if req.MatingAt > 0 && req.PregnantCheckResult == pasturePb.PregnantCheckResult_UnPregnant &&			req.MatingAt >= req.CalvingAt && req.MatingAt >= req.AbortionAt {			breedStatus = pasturePb.BreedStatus_Empty			if req.Lact == 0 {				cowType = pasturePb.CowType_Reserve_Calf			} else {				cowType = pasturePb.CowType_Breeding_Calf			}		}		if req.CalvingAt > 0 && req.CalvingAt >= req.MatingAt && req.CalvingAt >= req.AbortionAt {			breedStatus = pasturePb.BreedStatus_Calving			cowType = pasturePb.CowType_Breeding_Calf		}		if req.AbortionAt > 0 && req.AbortionAt >= req.CalvingAt && req.AbortionAt >= req.MatingAt {			breedStatus = pasturePb.BreedStatus_Abort			cowType = pasturePb.CowType_Breeding_Calf		}	}	if breedStatus == pasturePb.BreedStatus_No_Mating {		isForbiddenMating = pasturePb.IsShow_Ok	}	cow := &Cow{		PastureId:           pastureId,		Sex:                 req.Sex,		EarNumber:           req.EarNumber,		PenId:               req.PenId,		PenName:             penMap[req.PenId].Name,		Lact:                req.Lact,		CowType:             cowType,		BreedStatus:         breedStatus,		CowKind:             req.CowKind,		SourceKind:          req.CowSource,		FatherNumber:        req.FatherNumber,		MotherNumber:        req.MotherNumber,		AdmissionStatus:     pasturePb.AdmissionStatus_Admission,		HealthStatus:        pasturePb.HealthStatus_Health,		PurposeKind:         req.PurposeKind,		EleEarNumber:        req.EleEarNumber,		IsPregnant:          isPregnant,		IsForbiddenMating:   isForbiddenMating,		WeaningAt:           int64(req.WeaningAt),		BirthAt:             int64(req.BirthAt),		AdmissionWeight:     int64(req.Weight * 1000),		FirstMatingAt:       int64(req.MatingAt),		LastMatingAt:        int64(req.MatingAt),		LastPregnantCheckAt: int64(req.PregnancyCheckAt),		AdmissionAt:         admissionAt,		BirthWeight:         int64(req.Weight * 1000),		LastWeightAt:        int64(req.EstrusAt),		CurrentWeight:       int64(req.Weight * 1000),		LastDryMilkAt:       int64(req.DryMilkAt),		MatingTimes:         req.MatingTimes,		LastCalvingAt:       int64(req.CalvingAt),		LastBullNumber:      req.BullNumber,		LastAbortionAt:      int64(req.AbortionAt),		AdmissionPrice:      req.Price,		BatchNumber:         req.BatchNumber,		NeckRingNumber:      req.NeckRingNumber,	}	cow.AdmissionAge = cow.GetAdmissionAge()	cow.DayAge = cow.GetDayAge()	return cow}// NewCalfCow 产犊新增func NewCalfCow(matherInfo *Cow, calf *CalvingCalf) *Cow {	return &Cow{		PastureId:       calf.PastureId,		Sex:             calf.Sex,		EarNumber:       calf.EarNumber,		PenId:           calf.PenId,		PenName:         calf.PenName,		CowType:         pasturePb.CowType_Lactating_Calf, // 哺乳犊牛		BreedStatus:     pasturePb.BreedStatus_UnBreed,    // 未配		CowKind:         matherInfo.CowKind,               // 牛只品种		BirthWeight:     calf.BirthWeight,		BirthAt:         calf.BirthAt,		SourceKind:      pasturePb.CowSource_Calving, // 产犊方式		FatherNumber:    matherInfo.LastBullNumber,		MotherNumber:    matherInfo.EarNumber,		AdmissionStatus: pasturePb.AdmissionStatus_Admission,		IsPregnant:      pasturePb.IsShow_No,		AdmissionAt:     calf.BirthAt,	}}type BarCowStruct struct {	Number int32                  `json:"number"`	TypeId pasturePb.CowType_Kind `json:"type_id"`}// BarCowStructSlice 首页牛群结构type BarCowStructSlice []*BarCowStructfunc (b BarCowStructSlice) ToPB(cowTypeMap map[pasturePb.CowType_Kind]string, count int32) []*pasturePb.BarCowStruct {	var pb []*pasturePb.BarCowStruct	for _, v := range b {		name := fmt.Sprintf("%s", cowTypeMap[v.TypeId])		pb = append(pb, &pasturePb.BarCowStruct{Name: name, Value: v.Number})	}	return pb}type CowWeightRange struct {	WeightRange string `json:"weight_range"`	Count       int32  `json:"count"`}func (c CowSlice) WeightRangeToPB(penMap map[int32]*Pen) []*pasturePb.CowList {	res := make([]*pasturePb.CowList, len(c))	for i, v := range c {		penName := ""		if pen, ok := penMap[v.PenId]; ok {			penName = pen.Name		}		res[i] = &pasturePb.CowList{			CowId:                    int32(v.Id),			DayAge:                   v.DayAge,			AverageDailyWeightGain:   float32(v.GetAverageDailyWeight()),			PreviousStageDailyWeight: float32(v.GetPreviousStageDailyWeight()),			EarNumber:                v.EarNumber,			PenName:                  penName,			BirthAt:                  int32(v.BirthAt),			BirthWeight:              float32(v.BirthWeight) / 1000,			CurrentWeight:            float32(v.CurrentWeight) / 1000,			LastWeightAt:             int32(v.LastWeightAt),			AdmissionAge:             v.AdmissionAge,		}	}	return res}func (c CowSlice) LongTermInfertilityToPB(breedStatusMap map[pasturePb.BreedStatus_Kind]string) []*pasturePb.LongTermInfertility {	res := make([]*pasturePb.LongTermInfertility, len(c))	for i, v := range c {		breedStatusName := ""		if breedStatus, ok := breedStatusMap[v.BreedStatus]; ok {			breedStatusName = breedStatus		}		lastCalvingAtFormat := ""		if v.LastCalvingAt > 0 {			lastCalvingAtFormat = time.Unix(v.LastCalvingAt, 0).Local().Format(LayoutDate2)		}		lastAbortionAtFormat := ""		if v.LastAbortionAt > 0 {			lastAbortionAtFormat = time.Unix(v.LastAbortionAt, 0).Local().Format(LayoutDate2)		}		lastMatingAtFormat := ""		if v.LastMatingAt > 0 {			lastMatingAtFormat = time.Unix(v.LastMatingAt, 0).Local().Format(LayoutDate2)		}		res[i] = &pasturePb.LongTermInfertility{			CowId:                int32(v.Id),			EarNumber:            v.EarNumber,			Lact:                 v.Lact,			PenId:                v.PenId,			CalvingAge:           v.CalvingAge,			PenName:              v.PenName,			BreedStatusName:      breedStatusName,			BreedStatus:          v.BreedStatus,			LastCalvingAtFormat:  lastCalvingAtFormat,			LastAbortionAtFormat: lastAbortionAtFormat,			LastMatingAtFormat:   lastMatingAtFormat,			MatingTimes:          v.MatingTimes,			LastBullNumber:       v.LastBullNumber,			AbortionTimes:        v.AbortionTimes,		}	}	return res}func (c CowSlice) CanSaleToPB(cowKindMap map[pasturePb.CowKind_Kind]string) []*pasturePb.CanSalesReport {	res := make([]*pasturePb.CanSalesReport, len(c))	for i, v := range c {		cowKindName, lastWeightAtFormat, admissionAtFormat := "", "", ""		if name, ok := cowKindMap[v.CowKind]; ok {			cowKindName = name		}		if v.LastWeightAt > 0 {			lastWeightAtFormat = time.Unix(v.LastWeightAt, 0).Local().Format(LayoutDate2)		}		if v.AdmissionAt > 0 {			admissionAtFormat = time.Unix(v.AdmissionAt, 0).Local().Format(LayoutDate2)		}		res[i] = &pasturePb.CanSalesReport{			CowId:              int32(v.Id),			EarNumber:          v.EarNumber,			BatchNumber:        v.BatchNumber,			CowKindName:        cowKindName,			PenName:            v.PenName,			Weight:             float32(v.CurrentWeight) / 1000,			AdmissionAge:       v.AdmissionAge,			EnterWeight:        0,			EnterPrice:         0,			LastWeightAtFormat: lastWeightAtFormat,			DayAvgFeedCost:     0,			AllFeedCost:        0,			AllMedicalCharge:   0,			OtherCost:          0,			ProfitAndLoss:      0,			AdmissionAtFormat:  admissionAtFormat,			DayAvgWeight:       0,		}	}	return res}// CowBehaviorCurveResponse 脖环行为数据type CowBehaviorCurveResponse struct {	Code int32                 `json:"code"`	Msg  string                `json:"msg"`	Data *CowBehaviorCurveData `json:"data"`}type CowBehaviorCurveData struct {	OriginalDateList []int32                                 `json:"originalDateList"` // 原始行为数据	ChangeDateList   []int32                                 `json:"changeDateList"`   // 变化数据	SumDateList      []int32                                 `json:"sumDateList"`      // 累计24小时数据	SumChewList      []int32                                 `json:"sumChewList"`      // 累计24小时咀嚼	DateTimeList     []string                                `json:"dateTimeList"`     // 时间数据	EstrusList       map[pasturePb.EstrusLevel_Kind][]string `json:"estrusList"`       // 发情预警	EventList        []*pasturePb.CowEvent                   `json:"eventList"`        // 事件数据	EventMap         map[pasturePb.EventType_Kind]string     `json:"eventMap"`         // 所有事件	RuminaChange     []int32                                 `json:"ruminaChange"`     // 反刍变化	LowActivity      int32                                   `json:"lowActivity"`      // 低活动量参数	MiddleActivity   int32                                   `json:"middleActivity"`   // 中活动量行数	IQR1             []int32                                 `json:"IQR1"`             // 1IQR	IQR3             []int32                                 `json:"IQR3"`             // 3IQR}
 |