event_mating.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. package model
  2. import (
  3. "kpt-pasture/util"
  4. "time"
  5. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  6. )
  7. type EventMating struct {
  8. Id int64 `json:"id"`
  9. PastureId int64 `json:"pastureId"`
  10. CowId int64 `json:"cowId"`
  11. EarNumber string `json:"earNumber"`
  12. DayAge int32 `json:"dayAge"`
  13. Lact int32 `json:"lact"`
  14. PenId int32 `json:"penId"`
  15. PenName string `json:"penName"`
  16. CowType pasturePb.CowType_Kind `json:"cowType"`
  17. CowKind pasturePb.CowKind_Kind `json:"cowKind"`
  18. CalvingAge int32 `json:"calvingAge"`
  19. PlanDay int64 `json:"planDay"`
  20. EndDay int64 `json:"endDay"`
  21. CalvingAt int64 `json:"calvingAt"`
  22. RealityDay int64 `json:"realityDay"`
  23. Status pasturePb.IsShow_Kind `json:"status"`
  24. MatingTimes int32 `json:"matingTimes"`
  25. MatingResult pasturePb.MatingResult_Kind `json:"matingResult"`
  26. MatingResultAt int64 `json:"matingResultAt"`
  27. RematingAt int64 `json:"rematingAt"`
  28. ExposeEstrusType pasturePb.ExposeEstrusType_Kind `json:"exposeEstrusType"`
  29. FrozenSemenNumber string `json:"frozenSemenNumber"`
  30. OperationId int64 `json:"operationId"`
  31. OperationName string `json:"operationName"`
  32. MessageId int64 `json:"messageId"`
  33. MessageName string `json:"messageName"`
  34. Remarks string `json:"remarks"`
  35. CreatedAt int64 `json:"createdAt"`
  36. UpdatedAt int64 `json:"updatedAt"`
  37. }
  38. func (e *EventMating) TableName() string {
  39. return "event_mating"
  40. }
  41. func (e *EventMating) EventUpdate(cowInfo *Cow, matingAt int64, bullNumber string, isReMating bool, operationUser, currentUser *SystemUser) {
  42. e.MatingResult = pasturePb.MatingResult_Unknown
  43. e.Status = pasturePb.IsShow_Ok
  44. e.RealityDay = matingAt
  45. e.FrozenSemenNumber = bullNumber
  46. e.OperationName = operationUser.Name
  47. e.OperationId = operationUser.Id
  48. e.MessageName = currentUser.Name
  49. e.MessageId = currentUser.Id
  50. if !isReMating {
  51. e.MatingTimes += 1
  52. }
  53. e.DayAge = cowInfo.GetEventDayAge(matingAt)
  54. }
  55. // EventReMatingUpdate 复配更新
  56. func (e *EventMating) EventReMatingUpdate(matingAt int64) {
  57. e.MatingResult = pasturePb.MatingResult_ReMatch
  58. e.Status = pasturePb.IsShow_Ok
  59. e.MatingResultAt = matingAt
  60. e.RematingAt = matingAt
  61. }
  62. // EventMatingResultUpdate 配种结果更新
  63. func (e *EventMating) EventMatingResultUpdate(matingResult pasturePb.MatingResult_Kind, resultAt int64) {
  64. e.MatingResult = matingResult
  65. e.MatingResultAt = resultAt
  66. }
  67. // IsReMating 判断是不是复配
  68. func (e *EventMating) IsReMating(cow *Cow, matingAt int64) bool {
  69. lastMatingAt := time.Unix(cow.LastMatingAt, 0).Local()
  70. currentMatingAt := time.Unix(matingAt, 0).Local()
  71. daysBetween := util.DaysBetween(currentMatingAt.Unix(), lastMatingAt.Unix())
  72. if (daysBetween == 1 || daysBetween == 0) && e.Status == pasturePb.IsShow_Ok && e.MatingResult == pasturePb.MatingResult_Unknown {
  73. return true
  74. }
  75. return false
  76. }
  77. // IsMatingUpdate 判断是不是更新配种信息
  78. func (e *EventMating) IsMatingUpdate() bool {
  79. if e.Status == pasturePb.IsShow_No && e.MatingResult == pasturePb.MatingResult_Unknown {
  80. return true
  81. }
  82. return false
  83. }
  84. // IsEmptyMating 判断上次配种结果是不是空怀
  85. func (e *EventMating) IsEmptyMating(cow *Cow, matingAt int64) bool {
  86. lastMatingAt := time.Unix(cow.LastMatingAt, 0).Local()
  87. currentMatingAt := time.Unix(matingAt, 0).Local()
  88. daysBetween := util.DaysBetween(currentMatingAt.Unix(), lastMatingAt.Unix())
  89. if (e.MatingResult == pasturePb.MatingResult_Unknown || e.MatingResult == pasturePb.MatingResult_ReMatch) && daysBetween >= 2 {
  90. return true
  91. }
  92. return false
  93. }
  94. func NewEventMating(pastureId int64, cow *Cow, planDay int64, exposeEstrusType pasturePb.ExposeEstrusType_Kind) *EventMating {
  95. return &EventMating{
  96. PastureId: pastureId,
  97. CowId: cow.Id,
  98. EarNumber: cow.EarNumber,
  99. Lact: cow.Lact,
  100. PenId: cow.PenId,
  101. PenName: cow.PenName,
  102. CowType: cow.CowType,
  103. CowKind: cow.CowKind,
  104. DayAge: cow.DayAge,
  105. CalvingAt: cow.LastMatingAt,
  106. PlanDay: planDay,
  107. EndDay: planDay + 86399,
  108. MatingResult: pasturePb.MatingResult_Unknown,
  109. ExposeEstrusType: exposeEstrusType,
  110. Status: pasturePb.IsShow_No,
  111. }
  112. }
  113. // NewEventMatingNaturalEstrus 自然发情的牛只
  114. func NewEventMatingNaturalEstrus(pastureId int64, item *EventMatingCheckBatchModel, currentUser *SystemUser) *EventMating {
  115. return &EventMating{
  116. PastureId: pastureId,
  117. CowId: item.Cow.Id,
  118. EarNumber: item.Cow.EarNumber,
  119. Lact: item.Cow.Lact,
  120. DayAge: item.Cow.GetDayAge(),
  121. CowType: item.Cow.CowType,
  122. CowKind: item.Cow.CowKind,
  123. CalvingAt: item.Cow.LastMatingAt,
  124. PlanDay: item.MatingAt,
  125. RealityDay: item.MatingAt,
  126. EndDay: item.MatingAt,
  127. MatingResult: pasturePb.MatingResult_Unknown,
  128. ExposeEstrusType: pasturePb.ExposeEstrusType_Natural_Estrus,
  129. Status: pasturePb.IsShow_Ok,
  130. OperationId: item.OperationUser.Id,
  131. OperationName: item.OperationUser.Name,
  132. MessageId: currentUser.Id,
  133. MessageName: currentUser.Name,
  134. FrozenSemenNumber: item.FrozenSemen.BullId,
  135. Remarks: item.Remarks,
  136. MatingTimes: item.Cow.MatingTimes + 1,
  137. }
  138. }
  139. // NewEventMatingList 同期配种
  140. func NewEventMatingList(pastureId int64, cowList []*Cow, planDay int64, exposeEstrusType pasturePb.ExposeEstrusType_Kind) []*EventMating {
  141. var matingList []*EventMating
  142. for _, cow := range cowList {
  143. matingList = append(matingList, NewEventMating(pastureId, cow, planDay, exposeEstrusType))
  144. }
  145. return matingList
  146. }
  147. type EventMatingSlice []*EventMating
  148. func (e EventMatingSlice) ToPB(exposeEstrusTypeMap map[pasturePb.ExposeEstrusType_Kind]string) []*pasturePb.SearchMatingList {
  149. res := make([]*pasturePb.SearchMatingList, len(e))
  150. for i, v := range e {
  151. res[i] = &pasturePb.SearchMatingList{
  152. Id: int32(v.Id),
  153. CowId: int32(v.CowId),
  154. EarNumber: v.EarNumber,
  155. DayAge: v.DayAge,
  156. Lact: v.Lact,
  157. CalvingAge: v.CalvingAge,
  158. PlanDay: time.Unix(v.PlanDay, 0).Local().Format(LayoutDate2),
  159. RealityDay: time.Unix(v.RealityDay, 0).Local().Format(LayoutDate2),
  160. ExposeEstrusType: v.ExposeEstrusType,
  161. ExposeEstrusTypeName: exposeEstrusTypeMap[v.ExposeEstrusType],
  162. FrozenSemenNumber: v.FrozenSemenNumber,
  163. Remarks: v.Remarks,
  164. OperationId: int32(v.OperationId),
  165. OperationName: v.OperationName,
  166. CreatedAt: int32(v.CreatedAt),
  167. UpdatedAt: int32(v.UpdatedAt),
  168. }
  169. }
  170. return res
  171. }
  172. func (e EventMatingSlice) ToPB2() []*pasturePb.CowList {
  173. res := make([]*pasturePb.CowList, len(e))
  174. for i, v := range e {
  175. calvingAt, matingAtFormat := "", ""
  176. if v.CalvingAt > 0 {
  177. calvingAt = time.Unix(v.CalvingAt, 0).Local().Format(LayoutDate2)
  178. }
  179. if v.RealityDay > 0 {
  180. matingAtFormat = time.Unix(v.RealityDay, 0).Local().Format(LayoutDate2)
  181. }
  182. res[i] = &pasturePb.CowList{
  183. CowId: int32(v.CowId),
  184. DayAge: int32(v.DayAge),
  185. CalvingAge: v.CalvingAge,
  186. MatingAtFormat: matingAtFormat,
  187. CalvingAtFormat: calvingAt,
  188. Lact: int32(v.Lact),
  189. }
  190. }
  191. return res
  192. }
  193. func (e EventMatingSlice) ToPB3(isMating bool, cowTypeMap map[pasturePb.CowType_Kind]string) []*pasturePb.TwentyOnePregnantItems {
  194. res := make([]*pasturePb.TwentyOnePregnantItems, 0)
  195. for _, v := range e {
  196. if !isMating {
  197. continue
  198. }
  199. res = append(res, &pasturePb.TwentyOnePregnantItems{
  200. CowId: int32(v.CowId),
  201. EarNumber: v.EarNumber,
  202. CowTypeName: cowTypeMap[v.CowType],
  203. Lact: v.Lact,
  204. })
  205. }
  206. return res
  207. }
  208. func (e EventMatingSlice) ToPB4(cowTypeMap map[pasturePb.CowType_Kind]string) []*pasturePb.TwentyOnePregnantItems {
  209. res := make([]*pasturePb.TwentyOnePregnantItems, 0)
  210. for _, v := range e {
  211. if v.MatingResult != pasturePb.MatingResult_Abort {
  212. continue
  213. }
  214. res = append(res, &pasturePb.TwentyOnePregnantItems{
  215. CowId: int32(v.CowId),
  216. EarNumber: v.EarNumber,
  217. CowTypeName: cowTypeMap[v.CowType],
  218. Lact: v.Lact,
  219. })
  220. }
  221. return res
  222. }
  223. type CowMatingBody struct {
  224. Id int64 `json:"id"`
  225. CowId int64 `json:"cowId"`
  226. BreedStatus pasturePb.BreedStatus_Kind `json:"breedStatus"`
  227. BreedStatusName string `json:"breedStatusName"`
  228. CowType pasturePb.CowType_Kind `json:"cowType"`
  229. CowTypeName string `json:"cowTypeName"`
  230. PenId int32 `json:"penId"`
  231. PenName string `json:"penName"`
  232. Lact int32 `json:"lact"`
  233. CalvingAge int32 `json:"calvingAge"`
  234. AbortionAge int32 `json:"abortionAge"`
  235. DayAge int32 `json:"dayAge"`
  236. Status pasturePb.IsShow_Kind `json:"status"`
  237. }
  238. type CowMatingBodySlice []*CowMatingBody
  239. func (s CowMatingBodySlice) ToPB(
  240. cowTypeMap map[pasturePb.CowType_Kind]string,
  241. breedStatusMap map[pasturePb.BreedStatus_Kind]string,
  242. penMap map[int32]*Pen,
  243. ) []*CowMatingBody {
  244. res := make([]*CowMatingBody, len(s))
  245. for i, v := range s {
  246. res[i] = &CowMatingBody{
  247. Id: v.Id,
  248. CowId: v.CowId,
  249. CowType: v.CowType,
  250. CowTypeName: cowTypeMap[v.CowType],
  251. BreedStatus: v.BreedStatus,
  252. BreedStatusName: breedStatusMap[v.BreedStatus],
  253. PenName: penMap[v.PenId].Name,
  254. PenId: v.PenId,
  255. Lact: v.Lact,
  256. CalvingAge: v.CalvingAge,
  257. AbortionAge: v.AbortionAge,
  258. DayAge: v.DayAge,
  259. Status: v.Status,
  260. }
  261. }
  262. return res
  263. }
  264. type MatingTimelyChart struct {
  265. CalvingAge int32 `json:"calvingAge"`
  266. RealityDay string `json:"realityDay"`
  267. LactGroup string `json:"lactGroup"`
  268. }
  269. type MatingTimelyResponse struct {
  270. Code int32 `json:"code"`
  271. Msg string `json:"msg"`
  272. Data *MatingTimelyData `json:"data"`
  273. }
  274. type MatingTimelyData struct {
  275. CowList []*pasturePb.CowList `json:"cowList"`
  276. Chart *CowMatingChart `json:"chart"`
  277. }
  278. type CowMatingChart struct {
  279. Lact0 [][]string `json:"lact0"`
  280. Lact1 [][]string `json:"lact1"`
  281. Lact2 [][]string `json:"lact2"`
  282. Lact3 [][]string `json:"lact3"`
  283. }
  284. // MultiFactorPregnancyRateResponse 多维度受胎率
  285. type MultiFactorPregnancyRateResponse struct {
  286. Code int32 `json:"code"`
  287. Msg string `json:"msg"`
  288. Data *MultiFactorPregnancyRateData `json:"data"`
  289. }
  290. // MultiFactorPregnancyRateList 多维度受胎率分析
  291. type MultiFactorPregnancyRateList struct {
  292. StatisticMethod1 string `json:"statisticMethod1"` // 统计方式名称1 (月度、品种)
  293. StatisticMethod2 string `json:"statisticMethod2"` // 统计方式名称2 (月度、品种)
  294. PregnantRate float32 `json:"pregnantRate"` // 受胎率%(怀孕数 / 怀孕数 + 空怀数)
  295. PregnantCount int32 `json:"pregnantCount"` // 怀孕总数
  296. EmptyPregnantCount int32 `json:"emptyPregnantCount"` // 空怀数
  297. OtherCount int32 `json:"otherCount"` // 其他数 (配种后结果未知的个数,小于等于三次配种后,尚未孕检已经淘汰的个数)
  298. AbortionCount int32 `json:"abortionCount"` // 流产数 (已经怀孕后流产的个数)
  299. TotalCount int32 `json:"totalCount"` // 合计( 怀孕总数+空怀数+其他数)
  300. SpcRate float32 `json:"spcRate"` // spc(1 / 受胎率)
  301. Months string `json:"months"` // 月份
  302. OperationName string `json:"operationName"` // 配种员名称
  303. Bull string `json:"bull"` // 公牛
  304. Lact string `json:"lact"` // 胎次
  305. MatingTimes string `json:"matingTimes"` // 配次
  306. ExposeEstrusType string `json:"exposeEstrusType"` // 发情揭发方式
  307. Week string `json:"week"` // 周
  308. }
  309. type MultiFactorPregnancyRateData struct {
  310. Total int32 `json:"total"`
  311. PageSize int32 `json:"pageSize"`
  312. Page int32 `json:"page"`
  313. List []*MultiFactorPregnancyRateList `json:"list"`
  314. Chart *MultiFactorPregnancyRateChart `json:"chart"`
  315. }
  316. type MultiFactorPregnancyRateChart struct {
  317. Header []string `json:"header"` // 标题头
  318. PregnantRateMap map[string]map[string]string `json:"pregnantRateMap"`
  319. KepMap []string `json:"kepMap"`
  320. }
  321. // EventMatingCheckBatchModel 批量配种
  322. type EventMatingCheckBatchModel struct {
  323. Cow *Cow
  324. FrozenSemen *FrozenSemen
  325. OperationUser *SystemUser
  326. MatingAt int64
  327. FrozenSemenCount int32
  328. Remarks string
  329. ExposeEstrusType pasturePb.ExposeEstrusType_Kind
  330. }