123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- 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"`
- PastureId int64 `json:"pastureId"` // 牧场id
- Sex pasturePb.Genders_Kind `json:"sex"` // 性别
- NeckRingNumber string `json:"neckRingNumber"` // 脖环号
- EarNumber string `json:"earNumber"` // 耳标号
- 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"` // 流产天数
- 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"` // 入场时间
- DepartureAt int64 `json:"departureAt"` // 离场时间
- FirstMatingAt int64 `json:"firstMatingAt"` // 首次配种时间
- MatingTimes int32 `json:"matingTimes"` // 配种次数
- AbortionTimes int32 `json:"abortionTimes"` // 流产次数
- 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"` // 最近一次干奶日期
- 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"
- }
- func (c *Cow) EventInfoUpdate() {
- 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
- }
- }
- // 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
- }
- // 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) {
- c.BreedStatus = breedStatus
- c.LastPregnantCheckAt = pregnantCheckAt
- c.IsPregnant = isPregnant
- }
- // EventAbortionUpdate 流产更新
- func (c *Cow) EventAbortionUpdate(abortionAt int64) {
- c.IsPregnant = pasturePb.IsShow_No
- c.LastAbortionAt = abortionAt
- c.BreedStatus = pasturePb.BreedStatus_Abort
- c.AbortionTimes += 1
- }
- // EventWeightUpdate 称重更新
- func (c *Cow) EventWeightUpdate(weight int64, weightAt int64) {
- c.LastSecondWeight = c.CurrentWeight
- c.LastSecondWeightAt = c.LastWeightAt
- c.LastWeightAt = weightAt
- c.CurrentWeight = weight
- }
- // 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
- }
- // EventDepartureUpdate 更新牛只离场信息
- func (c *Cow) EventDepartureUpdate(departureAt int64, departureType pasturePb.DepartureType_Kind) {
- if departureType == pasturePb.DepartureType_Death {
- c.AdmissionStatus = pasturePb.AdmissionStatus_Die
- c.HealthStatus = pasturePb.HealthStatus_Dead
- }
- if departureType == pasturePb.DepartureType_Out {
- c.AdmissionStatus = pasturePb.AdmissionStatus_Out
- c.HealthStatus = pasturePb.HealthStatus_Out
- }
- c.DepartureAt = departureAt
- }
- // 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
- }
- }
- 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)
- }
- lastAbortionAtFormat := ""
- if v.LastAbortionAt > 0 {
- lastAbortionAtFormat = time.Unix(v.LastAbortionAt, 0).Format(LayoutDate2)
- }
- lastSecondWeightAtFormat := ""
- if v.LastSecondWeightAt > 0 {
- lastSecondWeightAtFormat = time.Unix(v.LastSecondWeightAt, 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],
- MotherNumber: v.MotherNumber,
- FatherNumber: v.FatherNumber,
- AdmissionStatusName: admissionStatusMap[v.AdmissionStatus],
- HealthStatusName: healthStatusMap[v.HealthStatus],
- IsPregnantName: isPregnantName,
- AdmissionAtFormat: admissionAtFormat,
- BirthAtFormat: birthAtFormat,
- WeaningAtFormat: weaningAtFormat,
- CalvingAge: v.GetCalvingAge(),
- AbortionAge: v.AbortionAge,
- MatingTimes: v.MatingTimes,
- FirstMatingAtFormat: firstMatingAtFormat,
- LastMatingAtFormat: lastMatingAtFormat,
- LastBullNumber: v.LastBullNumber,
- LastPregnantCheckAtFormat: lastPregnantCheckAtFormat,
- LastWeightAtFormat: lastWeightAtFormat,
- LastCalvingAtFormat: lastCalvingAtFormat,
- LastAbortionAtFormat: lastAbortionAtFormat,
- LastSecondWeight: float32(v.LastSecondWeight) / 1000,
- LastSecondWeightAtFormat: lastSecondWeightAtFormat,
- }
- }
- 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: v.AdmissionAge,
- AdmissionWeight: float32(v.AbortionAge) / 1000,
- PreviousStageDailyWeight: previousStageDailyWeight,
- PenAvgWeight: penAvgWeight,
- CowPenAvgWeightDiffValue: cowPenAvgWeightDiffValue,
- }
- }
- return res
- }
- func NewCow(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)
- }
- return &Cow{
- PastureId: pastureId,
- Sex: req.Sex,
- EarNumber: req.EarNumber,
- PenId: req.PenId,
- PenName: penMap[req.PenId].Name,
- 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: admissionAt,
- BirthWeight: int64(req.Weight * 1000),
- LastWeightAt: int64(req.EstrusAt),
- CurrentWeight: int64(req.Weight * 1000),
- }
- }
- func NewCalfCow(motherNumber, fatherNumber string, 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: calf.CowKind, // 牛只品种
- BirthWeight: calf.BirthWeight,
- BirthAt: calf.BirthAt,
- SourceId: pasturePb.CowSource_Calving, // 产犊方式
- FatherNumber: fatherNumber,
- MotherNumber: motherNumber,
- 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() int32 {
- if c.LastCalvingAt <= 0 {
- return 0
- }
- return int32(math.Floor(float64(time.Now().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().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 float64(c.CurrentWeight - c.LastSecondWeight)
- }
- 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
- }
- // 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小时数据
- DateTimeList []string `json:"dateTimeList"` // 时间数据
- EstrusList map[pasturePb.EstrusLevel_Kind][]string `json:"estrusList"` // 发情预警
- EventList map[string][]string `json:"eventList"` // 事件数据
- EventMap map[pasturePb.EventType_Kind]string `json:"eventMap"` // 所有事件
- }
|