package model import ( "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 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"` // 离场时间 DeparturePrice float32 `json:"departurePrice"` // 离场价格 DepartureAvgWeight int32 `json:"departureAvgWeight"` // 离场平均体重 FirstMatingAt int64 `json:"firstMatingAt"` // 首次配种时间 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"` // 最近一次称重时间 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() if c.DayAge == 60 { c.CowType = pasturePb.CowType_Weaned_Calf } c.WeeklyActive = weeklyActive c.LactationAge = c.GetLactationAge() c.DryMilkAge = c.GetDryMilkAge() } // 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 } // 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 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) { 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 } c.DepartureAt = eventSale.SaleAt c.NeckRingNumber = "" c.DeparturePrice = float32(eventSale.SalePrice) if eventSale.SaleCowCount > 0 { c.DepartureAvgWeight = int32(eventSale.SaleAllWeight / eventSale.SaleCowCount) } } // EventMatingUpdate 配种更新 func (c *Cow) EventMatingUpdate(matingAt int64, bullNumber string, isReMating bool) { c.LastMatingAt = matingAt if c.FirstMatingAt <= 0 { c.FirstMatingAt = matingAt } c.LastBullNumber = bullNumber c.IsPregnant = pasturePb.IsShow_No c.BreedStatus = pasturePb.BreedStatus_Breeding if !isReMating { c.MatingTimes += 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) } type CowSlice []*Cow func (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, } } 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, } 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.EarNumber, MotherNumber: matherInfo.LastBullNumber, 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 []*BarCowStruct func (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 } // GetDayAge 日龄 func (c *Cow) GetDayAge() int32 { if c.BirthAt <= 0 { return 0 } return int32(math.Floor(float64(time.Now().Local().Unix()-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 } // 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.MilkKind == pasturePb.CowMilk_Lactation { 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 } 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), } } 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 } // 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"` // 中活动量行数 }