package model import ( "fmt" "kpt-pasture/util" "math" "time" pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow" ) type Cow struct { Id int64 `json:"id"` Sex pasturePb.Genders_Kind `json:"sex"` NeckRingNumber string `json:"neckRingNumber"` EarNumber string `json:"earNumber"` EarOldNumber string `json:"earOldNumber"` PenId int32 `json:"penId"` Lact int32 `json:"lact"` DayAge int32 `json:"dayAge"` CalvingAge int64 `json:"calvingAge"` PregnancyAge int32 `json:"pregnancyAge"` // 怀孕天数 孕检结果有阳性更新,产犊后至0 AdmissionAge int32 `json:"admissionAge"` AbortionAge int64 `json:"abortionAge"` // 流产天数 CowType pasturePb.CowType_Kind `json:"cowType"` BreedStatus pasturePb.BreedStatus_Kind `json:"breedStatus"` CowKind pasturePb.CowKind_Kind `json:"cowKind"` BirthWeight int64 `json:"birthWeight"` CurrentWeight int64 `json:"currentWeight"` AdmissionWeight int64 `json:"admissionWeight"` SourceId pasturePb.CowSource_Kind `json:"sourceId"` FatherNumber string `json:"fatherNumber"` MotherNumber string `json:"motherNumber"` AdmissionStatus pasturePb.AdmissionStatus_Kind `json:"admissionStatus"` IsPregnant pasturePb.IsShow_Kind `json:"isPregnant"` HealthStatus pasturePb.HealthStatus_Kind `json:"healthStatus"` WeaningAt int64 `json:"weaningAt"` BirthAt int64 `json:"birthAt"` AdmissionAt int64 `json:"admissionAt"` FirstMatingAt int64 `json:"firstMatingAt"` MatingTimes int32 `json:"matingTimes"` LastEstrusAt int64 `json:"lastEstrusAt"` LastCalvingAt int64 `json:"lastCalvingAt"` LastMatingAt int64 `json:"lastMatingAt"` LastBullNumber string `json:"lastBullNumber"` LastPregnantCheckAt int64 `json:"lastPregnantCheckAt"` LastDryMilkAt int64 `json:"lastDryMilkAt"` 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" } type CowSlice []*Cow func (c CowSlice) ToPB( penMap map[int32]*Pen, 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, ) []*pasturePb.CowDetails { res := make([]*pasturePb.CowDetails, len(c)) for i, v := range c { penName := "" if pen, ok := penMap[v.PenId]; ok { penName = pen.Name } sex := "公" if v.Sex == pasturePb.Genders_Female { sex = "母" } lastWeightAtFormat := "" if v.LastWeightAt > 0 { lastWeightAtFormat = time.Unix(v.LastWeightAt, 0).Format(LayoutDate2) } isPregnantName := "" if v.IsPregnant == pasturePb.IsShow_Ok { isPregnantName = "已孕" } else { isPregnantName = "未孕" } admissionAtFormat := "" if v.AdmissionAt > 0 { admissionAtFormat = time.Unix(v.AdmissionAt, 0).Format(LayoutDate2) } birthAtFormat := "" if v.BirthAt > 0 { birthAtFormat = time.Unix(v.BirthAt, 0).Format(LayoutDate2) } weaningAtFormat := "" if v.WeaningAt > 0 { weaningAtFormat = time.Unix(v.WeaningAt, 0).Format(LayoutDate2) } firstMatingAtFormat := "" if v.FirstMatingAt > 0 { firstMatingAtFormat = time.Unix(v.FirstMatingAt, 0).Format(LayoutDate2) } lastMatingAtFormat := "" if v.LastMatingAt > 0 { lastMatingAtFormat = time.Unix(v.LastMatingAt, 0).Format(LayoutDate2) } lastPregnantCheckAtFormat := "" if v.LastPregnantCheckAt > 0 { lastPregnantCheckAtFormat = time.Unix(v.LastPregnantCheckAt, 0).Format(LayoutDate2) } lastCalvingAtFormat := "" if v.LastCalvingAt > 0 { lastCalvingAtFormat = time.Unix(v.LastCalvingAt, 0).Format(LayoutDate2) } res[i] = &pasturePb.CowDetails{ CowId: int32(v.Id), Sex: sex, NeckRingNumber: v.NeckRingNumber, PenName: penName, Lact: v.Lact, CowTypeName: cowTypeMap[v.CowType], BreedStatusName: breedStatusMap[v.BreedStatus], CowKindName: cowKindMap[v.CowKind], EarNumber: v.EarNumber, BirthWeight: float32(v.BirthWeight) / 1000, CurrentWeight: float32(v.CurrentWeight) / 1000, DayAge: v.DayAge, SourceName: cowSourceMap[v.SourceId], MontherNumber: v.MotherNumber, FatherNumber: v.FatherNumber, AdmissionStatusName: admissionStatusMap[v.AdmissionStatus], HealthStatusName: healthStatusMap[v.HealthStatus], IsPregnantName: isPregnantName, AdmissionAtFormat: admissionAtFormat, BirthAtFormat: birthAtFormat, WeaningAtFormat: weaningAtFormat, CalvingAge: int32(v.GetCalvingAge()), AbortionAge: int32(v.AbortionAge), MatingTimes: v.MatingTimes, FirstMatingAtFormat: firstMatingAtFormat, LastMatingAtFormat: lastMatingAtFormat, LastBullNumber: v.LastBullNumber, LastPregnantCheckAtFormat: lastPregnantCheckAtFormat, LastWeightAtFormat: lastWeightAtFormat, LastCalvingAtFormat: lastCalvingAtFormat, //PregnancyAge: v.PregnancyAge, } } return res } func (c CowSlice) ToPB2(penMap map[int32]*Pen, penWeightSlice PenWeightSlice) []*pasturePb.CowList { res := make([]*pasturePb.CowList, len(c)) for i, v := range c { penName := "" if pen, ok := penMap[v.PenId]; ok { penName = pen.Name } penWeight := penWeightSlice.GetPenWeight(v.PenId) lastWeightDay := util.Ceil(float64(v.LastWeightAt-v.LastSecondWeightAt) / 86400) penAvgWeight := float32(0) previousStageDailyWeight := float32(0) cowPenAvgWeightDiffValue := float32(0) if penWeight != nil { penAvgWeight = float32(penWeight.AvgWeight) / 1000 cowPenAvgWeightDiffValue = float32(v.CurrentWeight-int64(penWeight.AvgWeight)) / 1000 if lastWeightDay > 0 { previousStageDailyWeight = float32(v.CurrentWeight-v.LastSecondWeight) / 1000 / float32(lastWeightDay) } } res[i] = &pasturePb.CowList{ CowId: int32(v.Id), DayAge: v.DayAge, DailyWeightGain: float32(v.GetDayWeight()), AverageDailyWeightGain: float32(v.GetAverageDailyWeight()), EarNumber: v.EarNumber, PenName: penName, BirthAt: int32(v.BirthAt), BirthWeight: float32(v.BirthWeight) / 1000, CurrentWeight: float32(v.CurrentWeight) / 1000, LastWeightAt: int32(v.LastWeightAt), AdmissionAge: int32(v.AdmissionAge), AdmissionWeight: float32(v.AbortionAge) / 1000, PreviousStageDailyWeight: previousStageDailyWeight, PenAvgWeight: penAvgWeight, CowPenAvgWeightDiffValue: cowPenAvgWeightDiffValue, } } return res } func NewCow(req *pasturePb.EventEnterRequest) *Cow { var isPregnant = pasturePb.IsShow_No if req.BreedStatus == pasturePb.BreedStatus_Pregnant { isPregnant = pasturePb.IsShow_Ok } return &Cow{ Sex: req.Sex, EarNumber: req.EarNumber, PenId: req.PenId, Lact: req.Lact, CowType: req.CowType, BreedStatus: req.BreedStatus, CowKind: req.CowKind, SourceId: req.CowSource, FatherNumber: req.FatherNumber, MotherNumber: req.MotherNumber, AdmissionStatus: pasturePb.AdmissionStatus_Admission, HealthStatus: pasturePb.HealthStatus_Health, IsPregnant: isPregnant, 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: time.Now().Unix(), } } func NewCalfCow(motherId int64, fatherNumber string, calf *CalvingCalf) *Cow { return &Cow{ Sex: calf.Sex, EarNumber: calf.EarNumber, PenId: calf.PenId, CowType: pasturePb.CowType_Lactating_Calf, // 哺乳犊牛 BreedStatus: pasturePb.BreedStatus_UnBreed, // 未配 CowKind: calf.CowKind, // 牛只品种 BirthWeight: calf.BirthWeight, BirthAt: calf.BirthAt, SourceId: pasturePb.CowSource_Calving, // 产犊方式 FatherNumber: fatherNumber, MotherNumber: fmt.Sprintf("%d", motherId), 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().Unix()-c.BirthAt) / 86400)) } // GetCalvingAge 产后天数 func (c *Cow) GetCalvingAge() int64 { if c.LastMatingAt <= 0 { return 0 } return int64(math.Floor(float64(time.Now().Unix()-c.LastMatingAt) / 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().Unix()-c.LastMatingAt) / 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().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().Unix()-c.AdmissionAt) / 86400)) } return 0 } // GetDayWeight 日增重 func (c *Cow) GetDayWeight() float64 { if c.CurrentWeight-c.LastSecondWeight > 0 && c.LastWeightAt > c.LastSecondWeightAt { days := int32(math.Floor(float64(c.LastWeightAt-c.LastSecondWeightAt) / 86400)) if days <= 0 { return 0 } dayWeight := math.Round(1.0 * float64(c.CurrentWeight-c.LastSecondWeight) / float64(days)) return dayWeight / 1000 } return 0 } // GetAverageDailyWeight 平均日增重 func (c *Cow) GetAverageDailyWeight() float64 { if c.CurrentWeight-c.BirthWeight > 0 && c.LastWeightAt > c.BirthAt { days := int32(math.Floor(float64(c.LastWeightAt-c.BirthAt) / 86400)) if days <= 0 { return 0 } dailyWeight := math.Round(1.0 * float64(c.CurrentWeight-c.BirthWeight) / float64(days)) return dailyWeight / 1000 } return 0 } func (c *Cow) GetAbortionAge() int32 { if c.LastAbortionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission { return int32(math.Floor(float64(time.Now().Unix()-c.LastAbortionAt) / 86400)) } return 0 } 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, DailyWeightGain: float32(v.GetDayWeight()), AverageDailyWeightGain: float32(v.GetAverageDailyWeight()), 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 }