cow.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. package model
  2. import (
  3. "fmt"
  4. "math"
  5. "time"
  6. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  7. )
  8. type Cow struct {
  9. Id int64 `json:"id"`
  10. PastureId int64 `json:"pastureId"` // 牧场id
  11. Sex pasturePb.Genders_Kind `json:"sex"` // 性别
  12. NeckRingNumber string `json:"neckRingNumber"` // 脖环号
  13. EarNumber string `json:"earNumber"` // 耳标号
  14. EleEarNumber string `json:"eleEarNumber"` // 电子耳标号
  15. EarOldNumber string `json:"earOldNumber"` // 旧耳标号
  16. PenId int32 `json:"penId"` // 栏舍id
  17. PenName string `json:"penName"` // 栏舍名称
  18. Lact int32 `json:"lact"` // 胎次
  19. DayAge int32 `json:"dayAge"` // 日龄
  20. CalvingAge int32 `json:"calvingAge"` // 产后天使
  21. PregnancyAge int32 `json:"pregnancyAge"` // 怀孕天数 孕检结果有阳性更新,产犊后至0
  22. AdmissionAge int32 `json:"admissionAge"` // 入场日龄
  23. AbortionAge int32 `json:"abortionAge"` // 流产天数
  24. LactationAge int32 `json:"lactationAge"` // 泌乳天数
  25. DryMilkAge int32 `json:"dryMilkAge"` // 干奶天数
  26. CowType pasturePb.CowType_Kind `json:"cowType"` // 牛只类型
  27. MilkKind pasturePb.CowMilk_Kind `json:"milkKind"` // 牛只奶属性
  28. BreedStatus pasturePb.BreedStatus_Kind `json:"breedStatus"` // 繁殖状态
  29. CowKind pasturePb.CowKind_Kind `json:"cowKind"` // 牛只品种
  30. BirthWeight int64 `json:"birthWeight"` // 出生体重
  31. CurrentWeight int64 `json:"currentWeight"` // 当前体重
  32. CurrentHeight int64 `json:"currentHeight"` // 当前身高
  33. AdmissionWeight int64 `json:"admissionWeight"` // 入场体重
  34. SourceKind pasturePb.CowSource_Kind `json:"sourceKind"` // 来源哪里
  35. PurposeKind pasturePb.Purpose_Kind `json:"purposeKind"` // 用途
  36. FatherNumber string `json:"fatherNumber"` // 父号
  37. MotherNumber string `json:"motherNumber"` // 母号
  38. AdmissionStatus pasturePb.AdmissionStatus_Kind `json:"admissionStatus"` // 在场状态
  39. IsPregnant pasturePb.IsShow_Kind `json:"isPregnant"` // 是否怀孕
  40. IsForbiddenMating pasturePb.IsShow_Kind `json:"isForbiddenMating"` // 是否禁配 1 是 2 否
  41. HealthStatus pasturePb.HealthStatus_Kind `json:"healthStatus"` // 健康状态
  42. WeaningAt int64 `json:"weaningAt"` // 断奶时间
  43. BirthAt int64 `json:"birthAt"` // 出生时间
  44. AdmissionAt int64 `json:"admissionAt"` // 入场时间
  45. DepartureAt int64 `json:"departureAt"` // 离场时间
  46. FirstMatingAt int64 `json:"firstMatingAt"` // 首次配种时间
  47. MatingTimes int32 `json:"matingTimes"` // 配种次数
  48. AbortionTimes int32 `json:"abortionTimes"` // 流产次数
  49. WeeklyActive int32 `json:"weeklyActive"` // 每周活跃度
  50. LastEstrusAt int64 `json:"lastEstrusAt"` // 最后一次发情时间
  51. LastCalvingAt int64 `json:"lastCalvingAt"` // 最后一次产犊时间
  52. LastMatingAt int64 `json:"lastMatingAt"` // 最后一次配种时间
  53. LastBullNumber string `json:"lastBullNumber"` // 最后一次配种牛号
  54. LastPregnantCheckAt int64 `json:"lastPregnantCheckAt"` // 最后一次孕检时间
  55. LastDryMilkAt int64 `json:"lastDryMilkAt"` // 最近一次干奶日期
  56. LastForbiddenMatingAt int64 `json:"lastForbiddenMatingAt"` // 最近一次禁配时间
  57. LastSecondWeight int64 `json:"lastSecondWeight"` // 最后第二次称重
  58. LastSecondWeightAt int64 `json:"lastSecondWeightAt"` // 最后第二次称重时间
  59. LastAbortionAt int64 `json:"lastAbortionAt"` // 最近一次流产时间
  60. LastWeightAt int64 `json:"lastWeightAt"` // 最近一次称重时间
  61. CreatedAt int64 `json:"createdAt"`
  62. UpdatedAt int64 `json:"updatedAt"`
  63. }
  64. func (c *Cow) TableName() string {
  65. return "cow"
  66. }
  67. // EventUpdate 牛只基本信息维护
  68. func (c *Cow) EventUpdate(weeklyActive int32) {
  69. c.DayAge = c.GetDayAge()
  70. c.CalvingAge = c.GetCalvingAge()
  71. c.PregnancyAge = c.GetDaysPregnant()
  72. c.AdmissionAge = c.GetAdmissionAge()
  73. c.AbortionAge = c.GetAbortionAge()
  74. if c.DayAge == 60 {
  75. c.CowType = pasturePb.CowType_Weaned_Calf
  76. }
  77. c.WeeklyActive = weeklyActive
  78. c.LactationAge = c.GetLactationAge()
  79. c.DryMilkAge = c.GetDryMilkAge()
  80. }
  81. // EventCalvingUpdate 产犊更新
  82. func (c *Cow) EventCalvingUpdate(calvingAt int64) {
  83. c.Lact += 1
  84. c.MatingTimes = 0
  85. c.PregnancyAge = 0
  86. c.AbortionTimes = 0
  87. c.BreedStatus = pasturePb.BreedStatus_Calving
  88. c.IsPregnant = pasturePb.IsShow_No
  89. c.LastCalvingAt = calvingAt
  90. c.CalvingAge = c.GetCalvingAge()
  91. c.CowType = pasturePb.CowType_Breeding_Calf
  92. c.MilkKind = pasturePb.CowMilk_Lactation
  93. }
  94. // EventWeaningUpdate 断奶更新
  95. func (c *Cow) EventWeaningUpdate(weaningAt int64, penId int32, currentWeight int64) {
  96. c.PenId = penId
  97. c.WeaningAt = weaningAt
  98. c.CurrentWeight = currentWeight
  99. c.LastWeightAt = weaningAt
  100. }
  101. // EventPregnantCheckUpdate 孕检更新
  102. func (c *Cow) EventPregnantCheckUpdate(breedStatus pasturePb.BreedStatus_Kind, pregnantCheckAt int64, isPregnant pasturePb.IsShow_Kind) {
  103. c.BreedStatus = breedStatus
  104. c.LastPregnantCheckAt = pregnantCheckAt
  105. c.IsPregnant = isPregnant
  106. }
  107. // EventAbortionUpdate 流产更新
  108. func (c *Cow) EventAbortionUpdate(abortionAt int64, isLact pasturePb.IsShow_Kind) {
  109. c.IsPregnant = pasturePb.IsShow_No
  110. c.LastAbortionAt = abortionAt
  111. c.BreedStatus = pasturePb.BreedStatus_Abort
  112. c.AbortionTimes += 1
  113. if isLact == pasturePb.IsShow_Ok {
  114. c.Lact += 1
  115. }
  116. }
  117. // EventWeightUpdate 称重更新
  118. func (c *Cow) EventWeightUpdate(weight, height, weightAt int64) {
  119. c.LastSecondWeight = c.CurrentWeight
  120. c.LastSecondWeightAt = c.LastWeightAt
  121. c.LastWeightAt = weightAt
  122. c.CurrentWeight = weight
  123. c.CurrentHeight = height
  124. }
  125. // EventHealthStatusUpdate 健康状态更新
  126. func (c *Cow) EventHealthStatusUpdate(healthStatus pasturePb.HealthStatus_Kind) {
  127. c.HealthStatus = healthStatus
  128. }
  129. // EventPenUpdate 更新栏舍
  130. func (c *Cow) EventPenUpdate(pen *Pen) {
  131. c.PenId = pen.Id
  132. c.PenName = pen.Name
  133. }
  134. // EventEarNumberUpdate 更新耳标号
  135. func (c *Cow) EventEarNumberUpdate(newEarNumber string) {
  136. c.EarOldNumber = c.EarNumber
  137. c.EarNumber = newEarNumber
  138. }
  139. // EventDeathUpdate 更新牛只死亡信息
  140. func (c *Cow) EventDeathUpdate(eventAt int64) {
  141. c.AdmissionStatus = pasturePb.AdmissionStatus_Die
  142. c.HealthStatus = pasturePb.HealthStatus_Dead
  143. c.DepartureAt = eventAt
  144. c.NeckRingNumber = ""
  145. }
  146. // EventSaleUpdate 更新牛只销售信息
  147. func (c *Cow) EventSaleUpdate(eventAt int64, salesType pasturePb.SalesType_Kind) {
  148. if salesType == pasturePb.SalesType_Out {
  149. c.HealthStatus = pasturePb.HealthStatus_Out
  150. c.AdmissionStatus = pasturePb.AdmissionStatus_Out
  151. }
  152. if salesType == pasturePb.SalesType_Sales {
  153. c.AdmissionStatus = pasturePb.AdmissionStatus_Sale
  154. }
  155. c.DepartureAt = eventAt
  156. c.NeckRingNumber = ""
  157. }
  158. // EventMatingUpdate 配种更新
  159. func (c *Cow) EventMatingUpdate(matingAt int64, bullNumber string, isReMating bool) {
  160. c.LastMatingAt = matingAt
  161. if c.FirstMatingAt <= 0 {
  162. c.FirstMatingAt = matingAt
  163. }
  164. c.LastBullNumber = bullNumber
  165. c.IsPregnant = pasturePb.IsShow_No
  166. c.BreedStatus = pasturePb.BreedStatus_Breeding
  167. if !isReMating {
  168. c.MatingTimes += 1
  169. }
  170. if c.Lact == 0 {
  171. c.CowType = pasturePb.CowType_Reserve_Calf
  172. }
  173. }
  174. // EstrusUpdate 发情更新
  175. func (c *Cow) EstrusUpdate(estrusAt int64) {
  176. c.LastEstrusAt = estrusAt
  177. }
  178. // EventDryMilkUpdate 干奶更新
  179. func (c *Cow) EventDryMilkUpdate(dryMilkAt int64, pen *Pen) {
  180. c.LastDryMilkAt = dryMilkAt
  181. c.MilkKind = pasturePb.CowMilk_Dry_Milk
  182. c.PenId = pen.Id
  183. c.PenName = pen.Name
  184. }
  185. // ForbiddenMatingUpdate 禁配更新
  186. func (c *Cow) ForbiddenMatingUpdate(forbiddenMatingAt int64) {
  187. c.IsForbiddenMating = pasturePb.IsShow_Ok
  188. c.LastForbiddenMatingAt = forbiddenMatingAt
  189. c.BreedStatus = pasturePb.BreedStatus_No_Mating
  190. }
  191. // UnForbiddenMatingUpdate 解禁配更新
  192. func (c *Cow) UnForbiddenMatingUpdate() {
  193. c.IsForbiddenMating = pasturePb.IsShow_No
  194. c.LastForbiddenMatingAt = 0
  195. c.BreedStatus = pasturePb.BreedStatus_UnBreed
  196. }
  197. type CowSlice []*Cow
  198. func (c CowSlice) ToPB(
  199. cowTypeMap map[pasturePb.CowType_Kind]string,
  200. breedStatusMap map[pasturePb.BreedStatus_Kind]string,
  201. cowKindMap map[pasturePb.CowKind_Kind]string,
  202. cowSourceMap map[pasturePb.CowSource_Kind]string,
  203. admissionStatusMap map[pasturePb.AdmissionStatus_Kind]string,
  204. healthStatusMap map[pasturePb.HealthStatus_Kind]string,
  205. ) []*pasturePb.CowDetails {
  206. res := make([]*pasturePb.CowDetails, len(c))
  207. for i, v := range c {
  208. sex := "公"
  209. if v.Sex == pasturePb.Genders_Female {
  210. sex = "母"
  211. }
  212. lastWeightAtFormat := ""
  213. if v.LastWeightAt > 0 {
  214. lastWeightAtFormat = time.Unix(v.LastWeightAt, 0).Format(LayoutDate2)
  215. }
  216. isPregnantName := ""
  217. if v.IsPregnant == pasturePb.IsShow_Ok {
  218. isPregnantName = "已孕"
  219. } else {
  220. isPregnantName = "未孕"
  221. }
  222. admissionAtFormat := ""
  223. if v.AdmissionAt > 0 {
  224. admissionAtFormat = time.Unix(v.AdmissionAt, 0).Format(LayoutDate2)
  225. }
  226. birthAtFormat := ""
  227. if v.BirthAt > 0 {
  228. birthAtFormat = time.Unix(v.BirthAt, 0).Format(LayoutDate2)
  229. }
  230. weaningAtFormat := ""
  231. if v.WeaningAt > 0 {
  232. weaningAtFormat = time.Unix(v.WeaningAt, 0).Format(LayoutDate2)
  233. }
  234. firstMatingAtFormat := ""
  235. if v.FirstMatingAt > 0 {
  236. firstMatingAtFormat = time.Unix(v.FirstMatingAt, 0).Format(LayoutDate2)
  237. }
  238. lastMatingAtFormat := ""
  239. if v.LastMatingAt > 0 {
  240. lastMatingAtFormat = time.Unix(v.LastMatingAt, 0).Format(LayoutDate2)
  241. }
  242. lastPregnantCheckAtFormat := ""
  243. if v.LastPregnantCheckAt > 0 {
  244. lastPregnantCheckAtFormat = time.Unix(v.LastPregnantCheckAt, 0).Format(LayoutDate2)
  245. }
  246. lastCalvingAtFormat := ""
  247. if v.LastCalvingAt > 0 {
  248. lastCalvingAtFormat = time.Unix(v.LastCalvingAt, 0).Format(LayoutDate2)
  249. }
  250. lastAbortionAtFormat := ""
  251. if v.LastAbortionAt > 0 {
  252. lastAbortionAtFormat = time.Unix(v.LastAbortionAt, 0).Format(LayoutDate2)
  253. }
  254. lastSecondWeightAtFormat := ""
  255. if v.LastSecondWeightAt > 0 {
  256. lastSecondWeightAtFormat = time.Unix(v.LastSecondWeightAt, 0).Format(LayoutDate2)
  257. }
  258. res[i] = &pasturePb.CowDetails{
  259. CowId: int32(v.Id),
  260. Sex: sex,
  261. NeckRingNumber: v.NeckRingNumber,
  262. PenName: v.PenName,
  263. Lact: v.Lact,
  264. CowTypeName: cowTypeMap[v.CowType],
  265. CowType: v.CowType,
  266. BreedStatusName: breedStatusMap[v.BreedStatus],
  267. BreedStatus: v.BreedStatus,
  268. CowKindName: cowKindMap[v.CowKind],
  269. EarNumber: v.EarNumber,
  270. BirthWeight: float32(v.BirthWeight) / 1000,
  271. CurrentWeight: float32(v.CurrentWeight) / 1000,
  272. CurrentHeight: int32(v.CurrentHeight),
  273. DayAge: v.DayAge,
  274. AdmissionAge: v.AdmissionAge,
  275. SourceName: cowSourceMap[v.SourceKind],
  276. MotherNumber: v.MotherNumber,
  277. FatherNumber: v.FatherNumber,
  278. AdmissionStatusName: admissionStatusMap[v.AdmissionStatus],
  279. HealthStatusName: healthStatusMap[v.HealthStatus],
  280. IsPregnantName: isPregnantName,
  281. AdmissionAtFormat: admissionAtFormat,
  282. BirthAtFormat: birthAtFormat,
  283. WeaningAtFormat: weaningAtFormat,
  284. CalvingAge: v.GetCalvingAge(),
  285. AbortionAge: v.AbortionAge,
  286. MatingTimes: v.MatingTimes,
  287. FirstMatingAtFormat: firstMatingAtFormat,
  288. LastMatingAtFormat: lastMatingAtFormat,
  289. LastBullNumber: v.LastBullNumber,
  290. LastPregnantCheckAtFormat: lastPregnantCheckAtFormat,
  291. LastWeightAtFormat: lastWeightAtFormat,
  292. LastCalvingAtFormat: lastCalvingAtFormat,
  293. LastAbortionAtFormat: lastAbortionAtFormat,
  294. LastSecondWeight: float32(v.LastSecondWeight) / 1000,
  295. LastSecondWeightAtFormat: lastSecondWeightAtFormat,
  296. }
  297. }
  298. return res
  299. }
  300. func (c CowSlice) ToPB2(penWeightSlice PenWeightSlice) []*pasturePb.CowList {
  301. res := make([]*pasturePb.CowList, len(c))
  302. for i, v := range c {
  303. penWeight := penWeightSlice.GetPenWeight(v.PenId)
  304. penAvgWeight := float32(0)
  305. cowPenAvgWeightDiffValue := float32(0)
  306. if penWeight != nil {
  307. penAvgWeight = float32(penWeight.AvgWeight) / 1000
  308. cowPenAvgWeightDiffValue = float32(v.CurrentWeight-int64(penWeight.AvgWeight)) / 1000
  309. }
  310. res[i] = &pasturePb.CowList{
  311. CowId: int32(v.Id),
  312. DayAge: v.DayAge,
  313. AverageDailyWeightGain: float32(v.GetAverageDailyWeight()),
  314. EarNumber: v.EarNumber,
  315. PenName: v.PenName,
  316. BirthAt: int32(v.BirthAt),
  317. BirthWeight: float32(v.BirthWeight) / 1000,
  318. CurrentWeight: float32(v.CurrentWeight) / 1000,
  319. LastWeightAt: int32(v.LastWeightAt),
  320. AdmissionAge: v.AdmissionAge,
  321. AdmissionWeight: float32(v.AbortionAge) / 1000,
  322. PreviousStageDailyWeight: float32(v.GetPreviousStageDailyWeight()),
  323. PenAvgWeight: penAvgWeight,
  324. CowPenAvgWeightDiffValue: cowPenAvgWeightDiffValue,
  325. }
  326. }
  327. return res
  328. }
  329. // NewEnterCow 入场新增牛只
  330. func NewEnterCow(pastureId int64, req *pasturePb.EventEnterRequest, penMap map[int32]*Pen) *Cow {
  331. var isPregnant = pasturePb.IsShow_No
  332. if req.BreedStatus == pasturePb.BreedStatus_Pregnant {
  333. isPregnant = pasturePb.IsShow_Ok
  334. }
  335. admissionAt := int64(0)
  336. switch req.CowSource {
  337. case pasturePb.CowSource_Calving:
  338. admissionAt = int64(req.BirthAt)
  339. case pasturePb.CowSource_Transfer_In:
  340. admissionAt = int64(req.EnterAt)
  341. case pasturePb.CowSource_Buy:
  342. admissionAt = int64(req.EnterAt)
  343. }
  344. isForbiddenMating := pasturePb.IsShow_No
  345. if req.BreedStatus == pasturePb.BreedStatus_No_Mating {
  346. isForbiddenMating = pasturePb.IsShow_Ok
  347. }
  348. if req.PregnantCheckResult == pasturePb.PregnantCheckResult_Pregnant {
  349. req.BreedStatus = pasturePb.BreedStatus_Pregnant
  350. }
  351. cow := &Cow{
  352. PastureId: pastureId,
  353. Sex: req.Sex,
  354. EarNumber: req.EarNumber,
  355. PenId: req.PenId,
  356. PenName: penMap[req.PenId].Name,
  357. Lact: req.Lact,
  358. CowType: req.CowType,
  359. BreedStatus: req.BreedStatus,
  360. CowKind: req.CowKind,
  361. SourceKind: req.CowSource,
  362. FatherNumber: req.FatherNumber,
  363. MotherNumber: req.MotherNumber,
  364. AdmissionStatus: pasturePb.AdmissionStatus_Admission,
  365. HealthStatus: pasturePb.HealthStatus_Health,
  366. PurposeKind: req.PurposeKind,
  367. EleEarNumber: req.EleEarNumber,
  368. IsPregnant: isPregnant,
  369. IsForbiddenMating: isForbiddenMating,
  370. WeaningAt: int64(req.WeaningAt),
  371. BirthAt: int64(req.BirthAt),
  372. AdmissionWeight: int64(req.Weight * 1000),
  373. FirstMatingAt: int64(req.MatingAt),
  374. LastMatingAt: int64(req.MatingAt),
  375. LastPregnantCheckAt: int64(req.PregnancyCheckAt),
  376. AdmissionAt: admissionAt,
  377. BirthWeight: int64(req.Weight * 1000),
  378. LastWeightAt: int64(req.EstrusAt),
  379. CurrentWeight: int64(req.Weight * 1000),
  380. LastDryMilkAt: int64(req.DryMilkAt),
  381. MatingTimes: req.MatingTimes,
  382. LastCalvingAt: int64(req.CalvingAt),
  383. LastBullNumber: req.BullNumber,
  384. LastAbortionAt: int64(req.AbortionAt),
  385. }
  386. cow.AdmissionAge = cow.GetAdmissionAge()
  387. cow.DayAge = cow.GetDayAge()
  388. return cow
  389. }
  390. // NewCalfCow 产犊新增
  391. func NewCalfCow(matherInfo *Cow, calf *CalvingCalf) *Cow {
  392. return &Cow{
  393. PastureId: calf.PastureId,
  394. Sex: calf.Sex,
  395. EarNumber: calf.EarNumber,
  396. PenId: calf.PenId,
  397. PenName: calf.PenName,
  398. CowType: pasturePb.CowType_Lactating_Calf, // 哺乳犊牛
  399. BreedStatus: pasturePb.BreedStatus_UnBreed, // 未配
  400. CowKind: matherInfo.CowKind, // 牛只品种
  401. BirthWeight: calf.BirthWeight,
  402. BirthAt: calf.BirthAt,
  403. SourceKind: pasturePb.CowSource_Calving, // 产犊方式
  404. FatherNumber: matherInfo.EarNumber,
  405. MotherNumber: matherInfo.LastBullNumber,
  406. AdmissionStatus: pasturePb.AdmissionStatus_Admission,
  407. IsPregnant: pasturePb.IsShow_No,
  408. AdmissionAt: calf.BirthAt,
  409. }
  410. }
  411. type BarCowStruct struct {
  412. Number int32 `json:"number"`
  413. TypeId pasturePb.CowType_Kind `json:"type_id"`
  414. }
  415. // BarCowStructSlice 首页牛群结构
  416. type BarCowStructSlice []*BarCowStruct
  417. func (b BarCowStructSlice) ToPB(cowTypeMap map[pasturePb.CowType_Kind]string, count int32) []*pasturePb.BarCowStruct {
  418. var pb []*pasturePb.BarCowStruct
  419. for _, v := range b {
  420. name := fmt.Sprintf("%s", cowTypeMap[v.TypeId])
  421. pb = append(pb, &pasturePb.BarCowStruct{Name: name, Value: v.Number})
  422. }
  423. return pb
  424. }
  425. // GetDayAge 日龄
  426. func (c *Cow) GetDayAge() int32 {
  427. if c.BirthAt <= 0 {
  428. return 0
  429. }
  430. return int32(math.Floor(float64(time.Now().Unix()-c.BirthAt) / 86400))
  431. }
  432. // GetCalvingAge 产后天数
  433. func (c *Cow) GetCalvingAge() int32 {
  434. if c.LastCalvingAt <= 0 {
  435. return 0
  436. }
  437. return int32(math.Floor(float64(time.Now().Unix()-c.LastCalvingAt) / 86400))
  438. }
  439. // GetDaysPregnant 怀孕天数
  440. func (c *Cow) GetDaysPregnant() int32 {
  441. if c.BreedStatus == pasturePb.BreedStatus_Pregnant &&
  442. c.AdmissionStatus == pasturePb.AdmissionStatus_Admission &&
  443. c.IsPregnant == pasturePb.IsShow_Ok {
  444. return int32(math.Floor(float64(time.Now().Unix()-c.LastMatingAt) / 86400))
  445. }
  446. return 0
  447. }
  448. // GetLactationDays 泌乳天数
  449. func (c *Cow) GetLactationDays() int32 {
  450. if c.BreedStatus == pasturePb.BreedStatus_Calving && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {
  451. return int32(math.Floor(float64(time.Now().Unix()-c.LastCalvingAt) / 86400))
  452. }
  453. return 0
  454. }
  455. // GetAdmissionAge 入场天数
  456. func (c *Cow) GetAdmissionAge() int32 {
  457. if c.AdmissionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {
  458. return int32(math.Floor(float64(time.Now().Unix()-c.AdmissionAt) / 86400))
  459. }
  460. return 0
  461. }
  462. // GetAverageDailyWeight 平均日增重 (最后一次称重 - 第一次称重 ) ÷ 在群天数
  463. func (c *Cow) GetAverageDailyWeight() float64 {
  464. if c.CurrentWeight <= 0 || c.AdmissionAge <= 0 {
  465. return 0
  466. }
  467. firstWeight := c.BirthWeight
  468. if c.SourceKind == pasturePb.CowSource_Buy {
  469. firstWeight = c.AdmissionWeight
  470. }
  471. res := math.Round(1.0 * float64(c.CurrentWeight-firstWeight) / float64(c.AdmissionAge))
  472. return res / 1000
  473. }
  474. // GetPreviousStageDailyWeight 上一个阶段日增重
  475. func (c *Cow) GetPreviousStageDailyWeight() float64 {
  476. if c.CurrentWeight-c.LastSecondWeight > 0 && c.LastWeightAt-c.LastSecondWeightAt > 0 {
  477. days := int32(math.Floor(float64(c.LastWeightAt-c.LastSecondWeightAt) / 86400))
  478. if days <= 0 {
  479. return float64(c.CurrentWeight - c.LastSecondWeight)
  480. }
  481. dayWeight := math.Round(1.0 * float64(c.CurrentWeight-c.LastSecondWeight) / float64(days))
  482. return dayWeight / 1000
  483. }
  484. return 0
  485. }
  486. // GetAbortionAge 流产天数
  487. func (c *Cow) GetAbortionAge() int32 {
  488. if c.LastAbortionAt > 0 && c.AdmissionStatus == pasturePb.AdmissionStatus_Admission {
  489. return int32(math.Floor(float64(time.Now().Unix()-c.LastAbortionAt) / 86400))
  490. }
  491. return 0
  492. }
  493. // GetLactationAge 泌乳天数
  494. func (c *Cow) GetLactationAge() int32 {
  495. if c.MilkKind == pasturePb.CowMilk_Lactation {
  496. return int32(math.Floor(float64(time.Now().Unix()-c.LastCalvingAt) / 86400))
  497. }
  498. return c.LactationAge
  499. }
  500. // GetDryMilkAge 干奶天数
  501. func (c *Cow) GetDryMilkAge() int32 {
  502. if c.MilkKind == pasturePb.CowMilk_Dry_Milk {
  503. return int32(math.Floor(float64(time.Now().Unix()-c.LastDryMilkAt) / 86400))
  504. }
  505. return c.DryMilkAge
  506. }
  507. type CowWeightRange struct {
  508. WeightRange string `json:"weight_range"`
  509. Count int32 `json:"count"`
  510. }
  511. func (c CowSlice) WeightRangeToPB(penMap map[int32]*Pen) []*pasturePb.CowList {
  512. res := make([]*pasturePb.CowList, len(c))
  513. for i, v := range c {
  514. penName := ""
  515. if pen, ok := penMap[v.PenId]; ok {
  516. penName = pen.Name
  517. }
  518. res[i] = &pasturePb.CowList{
  519. CowId: int32(v.Id),
  520. DayAge: v.DayAge,
  521. AverageDailyWeightGain: float32(v.GetAverageDailyWeight()),
  522. PreviousStageDailyWeight: float32(v.GetPreviousStageDailyWeight()),
  523. EarNumber: v.EarNumber,
  524. PenName: penName,
  525. BirthAt: int32(v.BirthAt),
  526. BirthWeight: float32(v.BirthWeight) / 1000,
  527. CurrentWeight: float32(v.CurrentWeight) / 1000,
  528. LastWeightAt: int32(v.LastWeightAt),
  529. }
  530. }
  531. return res
  532. }
  533. func (c CowSlice) LongTermInfertilityToPB(breedStatusMap map[pasturePb.BreedStatus_Kind]string) []*pasturePb.LongTermInfertility {
  534. res := make([]*pasturePb.LongTermInfertility, len(c))
  535. for i, v := range c {
  536. breedStatusName := ""
  537. if breedStatus, ok := breedStatusMap[v.BreedStatus]; ok {
  538. breedStatusName = breedStatus
  539. }
  540. lastCalvingAtFormat := ""
  541. if v.LastCalvingAt > 0 {
  542. lastCalvingAtFormat = time.Unix(v.LastCalvingAt, 0).Format(LayoutDate2)
  543. }
  544. lastAbortionAtFormat := ""
  545. if v.LastAbortionAt > 0 {
  546. lastAbortionAtFormat = time.Unix(v.LastAbortionAt, 0).Format(LayoutDate2)
  547. }
  548. lastMatingAtFormat := ""
  549. if v.LastMatingAt > 0 {
  550. lastMatingAtFormat = time.Unix(v.LastMatingAt, 0).Format(LayoutDate2)
  551. }
  552. res[i] = &pasturePb.LongTermInfertility{
  553. CowId: int32(v.Id),
  554. EarNumber: v.EarNumber,
  555. Lact: v.Lact,
  556. PenId: v.PenId,
  557. CalvingAge: v.CalvingAge,
  558. PenName: v.PenName,
  559. BreedStatusName: breedStatusName,
  560. LastCalvingAtFormat: lastCalvingAtFormat,
  561. LastAbortionAtFormat: lastAbortionAtFormat,
  562. LastMatingAtFormat: lastMatingAtFormat,
  563. MatingTimes: v.MatingTimes,
  564. LastBullNumber: v.LastBullNumber,
  565. AbortionTimes: v.AbortionTimes,
  566. }
  567. }
  568. return res
  569. }
  570. // CowBehaviorCurveResponse 脖环行为数据
  571. type CowBehaviorCurveResponse struct {
  572. Code int32 `json:"code"`
  573. Msg string `json:"msg"`
  574. Data *CowBehaviorCurveData `json:"data"`
  575. }
  576. type CowBehaviorCurveData struct {
  577. OriginalDateList []int32 `json:"originalDateList"` // 原始行为数据
  578. ChangeDateList []int32 `json:"changeDateList"` // 变化数据
  579. SumDateList []int32 `json:"sumDateList"` // 累计24小时数据
  580. SumChewList []int32 `json:"sumChewList"` // 累计24小时咀嚼
  581. DateTimeList []string `json:"dateTimeList"` // 时间数据
  582. EstrusList map[pasturePb.EstrusLevel_Kind][]string `json:"estrusList"` // 发情预警
  583. EventList map[string][]string `json:"eventList"` // 事件数据
  584. EventMap map[pasturePb.EventType_Kind]string `json:"eventMap"` // 所有事件
  585. RuminaChange []int32 `json:"ruminaChange"` // 反刍变化
  586. LowActivity int32 `json:"lowActivity"` // 低活动量参数
  587. MiddleActivity int32 `json:"middleActivity"` // 中活动量行数
  588. }