event_breed.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. package backend
  2. import (
  3. "context"
  4. "fmt"
  5. "kpt-pasture/model"
  6. "kpt-pasture/util"
  7. "net/http"
  8. "strings"
  9. "time"
  10. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  11. "gitee.com/xuyiping_admin/pkg/xerr"
  12. "gorm.io/gorm"
  13. )
  14. func (s *StoreEntry) CalvingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchLavingEventResponse, error) {
  15. lavingList := make([]*model.EventCalvingList, 0)
  16. var count int64 = 0
  17. pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCalving).TableName())).
  18. Select(`a.*,b.name as pen_name,c.name as staff_member_name`).
  19. Joins(fmt.Sprintf("JOIN %s AS b on a.pen_id = b.id", new(model.Pen).TableName())).
  20. Joins(fmt.Sprintf("JOIN %s AS c on a.staff_member_id = c.id", new(model.SystemUser).TableName()))
  21. if len(req.CowId) > 0 {
  22. cowIds := strings.Split(req.CowId, ",")
  23. pref.Where("a.cow_id IN ?", cowIds)
  24. }
  25. if err := pref.Order("a.id desc").
  26. Count(&count).Limit(int(pagination.PageSize)).
  27. Offset(int(pagination.PageOffset)).
  28. Find(&lavingList).Error; err != nil {
  29. return nil, xerr.WithStack(err)
  30. }
  31. calvingIds := make([]int64, 0)
  32. for _, v := range lavingList {
  33. calvingIds = append(calvingIds, v.Id)
  34. }
  35. calvingCalfList := make([]*model.CalvingCalf, 0)
  36. if err := s.DB.Model(new(model.CalvingCalf)).
  37. Where("calving_id IN ?", calvingIds).
  38. Find(&calvingCalfList).Error; err != nil {
  39. return nil, xerr.WithStack(err)
  40. }
  41. return &pasturePb.SearchLavingEventResponse{
  42. Code: http.StatusOK,
  43. Message: "ok",
  44. Data: &pasturePb.SearchLavingData{
  45. List: model.EventCalvingListSlice(lavingList).ToPB(calvingCalfList),
  46. Total: int32(count),
  47. PageSize: pagination.PageSize,
  48. Page: pagination.Page,
  49. },
  50. }, nil
  51. }
  52. func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalving) error {
  53. if len(req.CowId) <= 0 {
  54. return xerr.Custom("请选择相关牛只")
  55. }
  56. cowList, err := s.ParseCowIds(ctx, req.CowId)
  57. if err != nil {
  58. return xerr.WithStack(err)
  59. }
  60. if len(cowList) <= 0 {
  61. return xerr.Custom("请选择相关牛只")
  62. }
  63. cow := cowList[0]
  64. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  65. // 母牛信息
  66. newCalving := model.NewEventCalving(cow, req)
  67. if err = tx.Create(newCalving).Error; err != nil {
  68. return xerr.WithStack(err)
  69. }
  70. // 犊牛信息
  71. newCalvingCalfList := model.NewEventCalvingCalf(cow.Id, newCalving.Id, req)
  72. for _, v := range newCalvingCalfList {
  73. if v.IsLive == pasturePb.IsShow_No || v.IsAdoption == pasturePb.IsShow_No {
  74. continue
  75. }
  76. // 留养犊牛
  77. newCow := model.NewCalfCow(cow.Id, cow.LastBullId, v)
  78. if err = tx.Create(newCow).Error; err != nil {
  79. return xerr.WithStack(err)
  80. }
  81. v.CowId = newCow.Id
  82. }
  83. if err = tx.Create(newCalvingCalfList).Error; err != nil {
  84. return xerr.WithStack(err)
  85. }
  86. if err = tx.Model(new(model.Cow)).Where("id = ?", cow.Id).Updates(map[string]interface{}{
  87. "calving_age": 0,
  88. "lact": cow.Lact + 1,
  89. "breed_status": pasturePb.BreedStatus_Calving,
  90. "is_pregnant": pasturePb.IsShow_No,
  91. "calving_at": time.Now().Unix(),
  92. "last_calving_at": time.Now().Unix(),
  93. }).Error; err != nil {
  94. return xerr.WithStack(err)
  95. }
  96. return nil
  97. }); err != nil {
  98. return xerr.WithStack(err)
  99. }
  100. return nil
  101. }
  102. func (s *StoreEntry) PregnantCheckList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.PregnantCheckEventResponse, error) {
  103. pregnantCheckList := make([]*model.EventPregnantCheck, 0)
  104. var count int64 = 0
  105. pref := s.DB.Table(new(model.EventPregnantCheck).TableName())
  106. if len(req.CowId) > 0 {
  107. cowIds := strings.Split(req.CowId, ",")
  108. pref.Where("cow_id IN ?", cowIds)
  109. }
  110. if err := pref.Order("id desc").
  111. Count(&count).Limit(int(pagination.PageSize)).
  112. Offset(int(pagination.PageOffset)).
  113. Find(&pregnantCheckList).Error; err != nil {
  114. return nil, xerr.WithStack(err)
  115. }
  116. systemUserList, _ := s.SystemUserList(ctx)
  117. pregnantCheckResult := s.PregnantCheckResultEnumList()
  118. pregnantCheckMethod := s.PregnantCheckMethodEnumList()
  119. return &pasturePb.PregnantCheckEventResponse{
  120. Code: http.StatusOK,
  121. Message: "ok",
  122. Data: &pasturePb.SearchPregnantCheckData{
  123. List: model.EventPregnantCheckSlice(pregnantCheckList).ToPB(systemUserList, pregnantCheckResult, pregnantCheckMethod),
  124. Total: int32(count),
  125. PageSize: pagination.PageSize,
  126. Page: pagination.Page,
  127. },
  128. }, nil
  129. }
  130. func (s *StoreEntry) PregnantCheckCreate(ctx context.Context, req *pasturePb.EventPregnantCheck) error {
  131. if len(req.CowId) <= 0 {
  132. return xerr.Custom("请选择相关牛只")
  133. }
  134. cowList, err := s.ParseCowIds(ctx, req.CowId)
  135. if err != nil {
  136. return xerr.WithStack(err)
  137. }
  138. eventPregnantCheckList := make([]*model.EventPregnantCheck, 0)
  139. currentUser, _ := s.GetCurrentSystemUser(ctx)
  140. // 更新怀孕牛只
  141. updatePregnantCowIds := make([]int64, 0)
  142. // 更新流产牛只
  143. updateAbortCowIds := make([]int64, 0)
  144. // 更新空怀牛只
  145. updateEmptyCowIds := make([]int64, 0)
  146. for _, cow := range cowList {
  147. // 过滤掉没有配种状态的牛只 todo 是否需要返回前端提示用户
  148. if cow.BreedStatus != pasturePb.BreedStatus_Breeding {
  149. continue
  150. }
  151. var count int64 = 0
  152. if err = s.DB.Model(new(model.EventPregnantCheck)).
  153. Where("lact = ?", cow.Lact).
  154. Where("cow_id = ?", cow.Id).
  155. Order("id desc").Limit(1).Count(&count).Error; err != nil {
  156. return xerr.WithStack(err)
  157. }
  158. pregnantCheckResult := req.PregnantCheckResult
  159. if req.PregnantCheckResult == pasturePb.PregnantCheckResult_Pregnant {
  160. if count > 0 {
  161. pregnantCheckResult = pasturePb.PregnantCheckResult_Recheck_Pregnant
  162. } else {
  163. pregnantCheckResult = pasturePb.PregnantCheckResult_InCheck_Pregnant
  164. }
  165. updatePregnantCowIds = append(updatePregnantCowIds, cow.Id)
  166. }
  167. if req.PregnantCheckResult == pasturePb.PregnantCheckResult_UnPregnant {
  168. if count > 0 {
  169. pregnantCheckResult = pasturePb.PregnantCheckResult_Recheck_UnPregnant
  170. updateAbortCowIds = append(updateAbortCowIds, cow.Id)
  171. } else {
  172. pregnantCheckResult = pasturePb.PregnantCheckResult_InCheck_UnPregnant
  173. updateEmptyCowIds = append(updateEmptyCowIds, cow.Id)
  174. }
  175. }
  176. eventPregnantCheckList = append(eventPregnantCheckList, model.NewEventPregnantCheck(cow, currentUser, req, pregnantCheckResult))
  177. }
  178. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  179. if err = tx.Create(eventPregnantCheckList).Error; err != nil {
  180. return xerr.WithStack(err)
  181. }
  182. // 抽象公共方法来更新牛只状态
  183. err = s.updateCowStatus(tx, updatePregnantCowIds, pasturePb.BreedStatus_Pregnant, pasturePb.MatingResult_Pregnant)
  184. if err != nil {
  185. return err
  186. }
  187. err = s.updateCowStatus(tx, updateAbortCowIds, pasturePb.BreedStatus_Abort, pasturePb.MatingResult_Abort)
  188. if err != nil {
  189. return err
  190. }
  191. err = s.updateCowStatus(tx, updateEmptyCowIds, pasturePb.BreedStatus_Empty, pasturePb.MatingResult_Empty)
  192. if err != nil {
  193. return err
  194. }
  195. return nil
  196. }); err != nil {
  197. return xerr.WithStack(err)
  198. }
  199. return nil
  200. }
  201. // 抽象公共方法来更新牛只状态
  202. func (s *StoreEntry) updateCowStatus(
  203. tx *gorm.DB,
  204. cowIds []int64,
  205. breedStatus pasturePb.BreedStatus_Kind,
  206. matingResult pasturePb.MatingResult_Kind,
  207. ) error {
  208. if len(cowIds) > 0 {
  209. if err := tx.Model(&model.Cow{}).Where("cow_id IN ?", cowIds).
  210. Updates(map[string]interface{}{"breed_status": breedStatus}).Error; err != nil {
  211. return xerr.WithStack(err)
  212. }
  213. if err := tx.Model(&model.EventMating{}).Where("cow_id IN ?", cowIds).
  214. Group("cow_id").Select("MAX(id) as id").
  215. Updates(map[string]interface{}{"mating_result": matingResult}).Error; err != nil {
  216. return xerr.WithStack(err)
  217. }
  218. }
  219. return nil
  220. }
  221. func (s *StoreEntry) MatingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingEventResponse, error) {
  222. matingList := make([]*model.EventMating, 0)
  223. var count int64 = 0
  224. pref := s.DB.Model(new(model.EventMating)).
  225. Where("mating_result > ?", pasturePb.MatingResult_Invalid).
  226. Where("status = ?", pasturePb.IsShow_No)
  227. if len(req.CowId) > 0 {
  228. cowIds := strings.Split(req.CowId, ",")
  229. pref.Where("cow_id IN ?", cowIds)
  230. }
  231. if err := pref.Order("id desc").
  232. Count(&count).Limit(int(pagination.PageSize)).
  233. Offset(int(pagination.PageOffset)).
  234. Find(&matingList).Error; err != nil {
  235. return nil, xerr.WithStack(err)
  236. }
  237. exposeEstrusTypeMap := s.ExposeEstrusTypeMap()
  238. return &pasturePb.MatingEventResponse{
  239. Code: http.StatusOK,
  240. Message: "ok",
  241. Data: &pasturePb.SearchMatingData{
  242. List: model.EventMatingSlice(matingList).ToPB(exposeEstrusTypeMap),
  243. Total: int32(count),
  244. PageSize: pagination.PageSize,
  245. Page: pagination.Page,
  246. },
  247. }, nil
  248. }
  249. func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMating) error {
  250. if len(req.CowId) <= 0 {
  251. return xerr.Custom("请选择相关牛只")
  252. }
  253. cowList, err := s.ParseCowIds(ctx, req.CowId)
  254. if err != nil {
  255. return xerr.WithStack(err)
  256. }
  257. systemUser, _ := s.GetSystemUserById(ctx, int64(req.StaffMemberId))
  258. eventFrozenSemenLogList := make([]*model.FrozenSemenLog, 0)
  259. frozenSemen := &model.FrozenSemen{}
  260. if err = s.DB.Where("bull_id = ?", req.FrozenSemenNumber).First(frozenSemen).Error; err != nil {
  261. return xerr.WithStack(err)
  262. }
  263. matingUpdateIds := make([]int64, 0)
  264. cowIds := make([]int64, 0)
  265. nowTime := time.Now()
  266. for _, cow := range cowList {
  267. var count int64 = 0
  268. itemEventMating := &model.EventMating{}
  269. if err = s.DB.Where("lact = ?", cow.Lact).
  270. Where("cow_id = ?", cow.Id).
  271. Order("id desc").
  272. First(itemEventMating).Count(&count).Error; err != nil {
  273. return xerr.WithStack(err)
  274. }
  275. // 判断当前输精时间距离上次输精时间是否超过2天,如果超过则更新为复配状态
  276. itemBeforeTwoDays := nowTime.Sub(time.Unix(util.TimeParseLocalUnix(itemEventMating.RealityDay), 0)).Hours()
  277. if count > 0 && itemBeforeTwoDays > 48 {
  278. matingUpdateIds = append(matingUpdateIds, itemEventMating.Id)
  279. }
  280. eventFrozenSemenLogList = append(
  281. eventFrozenSemenLogList,
  282. model.NewEventFrozenSemenLog(req.FrozenSemenNumber, cow, int64(req.StaffMemberId)),
  283. )
  284. cowIds = append(cowIds, cow.Id)
  285. }
  286. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  287. if len(cowIds) > 0 {
  288. // 如果有同期牛只,则修改为已结束状态
  289. if err = tx.Table(new(model.CowSameTime).TableName()).
  290. Where("cow_id IN ?", cowIds).
  291. UpdateColumn("status", pasturePb.SameTimeStatus_End).Error; err != nil {
  292. }
  293. // 创建配种事件数据
  294. if err = tx.Model(new(model.EventMating)).
  295. Where("cow_id IN ?", cowIds).
  296. Updates(map[string]interface{}{
  297. "mating_result": pasturePb.MatingResult_Unknown,
  298. "status": pasturePb.IsShow_Ok,
  299. "reality_day": time.Unix(int64(req.MatingAt), 0).Format(model.LayoutTime),
  300. "mating_number": 1,
  301. "frozen_semen_number": req.FrozenSemenCount,
  302. "operation_id": req.StaffMemberId,
  303. "operation_name": systemUser.Name,
  304. }).
  305. Error; err != nil {
  306. return xerr.WithStack(err)
  307. }
  308. }
  309. // 更新已配种的牛只为复配状态
  310. if len(matingUpdateIds) > 0 {
  311. if err = tx.Model(new(model.EventMating)).
  312. Where("id IN ?", matingUpdateIds).
  313. Where("mating_result = ?", pasturePb.MatingResult_Unknown).
  314. Updates(map[string]interface{}{
  315. "mating_result": pasturePb.MatingResult_ReMatch,
  316. "mating_number": 2,
  317. "frozen_semen_number": req.FrozenSemenCount,
  318. }).
  319. Error; err != nil {
  320. return xerr.WithStack(err)
  321. }
  322. }
  323. // 创建冻精使用记录日志
  324. if err = tx.Create(eventFrozenSemenLogList).Error; err != nil {
  325. return xerr.WithStack(err)
  326. }
  327. // 减去精液的数量
  328. if err = tx.Model(new(model.FrozenSemen)).
  329. Where("id = ?", frozenSemen.Id).
  330. Where("quantity > 0").
  331. UpdateColumn("quantity",
  332. gorm.Expr("quantity - ?", len(matingUpdateIds)),
  333. ).Error; err != nil {
  334. return xerr.WithStack(err)
  335. }
  336. if err = tx.Table(new(model.Cow).TableName()).
  337. Where("id IN ?", cowIds).
  338. UpdateColumn("breed_status", pasturePb.BreedStatus_Breeding).Error; err != nil {
  339. return xerr.WithStack(err)
  340. }
  341. return nil
  342. }); err != nil {
  343. return xerr.WithStack(err)
  344. }
  345. return nil
  346. }
  347. func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusEventResponse, error) {
  348. estrusList := make([]*model.EventEstrus, 0)
  349. var count int64 = 0
  350. pref := s.DB.Table(new(model.EventEstrus).TableName())
  351. if len(req.CowId) > 0 {
  352. cowIds := strings.Split(req.CowId, ",")
  353. pref.Where("cow_id IN ?", cowIds)
  354. }
  355. if err := pref.Order("id desc").
  356. Count(&count).Limit(int(pagination.PageSize)).
  357. Offset(int(pagination.PageOffset)).
  358. Find(&estrusList).Error; err != nil {
  359. return nil, xerr.WithStack(err)
  360. }
  361. systemUserList, _ := s.SystemUserList(ctx)
  362. return &pasturePb.EstrusEventResponse{
  363. Code: http.StatusOK,
  364. Message: "ok",
  365. Data: &pasturePb.SearchEstrusData{
  366. List: model.EstrusSlice(estrusList).ToPB(systemUserList),
  367. Total: int32(count),
  368. PageSize: pagination.PageSize,
  369. Page: pagination.Page,
  370. },
  371. }, nil
  372. }
  373. func (s *StoreEntry) EstrusCreate(ctx context.Context, req *pasturePb.EventEstrus) error {
  374. if len(req.CowId) <= 0 {
  375. return xerr.Custom("请选择相关牛只")
  376. }
  377. cowList, err := s.ParseCowIds(ctx, req.CowId)
  378. if err != nil {
  379. return xerr.WithStack(err)
  380. }
  381. estrusList := make([]*model.EventEstrus, 0)
  382. currentUser, _ := s.GetCurrentSystemUser(ctx)
  383. for _, cow := range cowList {
  384. estrusList = append(estrusList, model.NewEventEstrus(cow, currentUser, req))
  385. }
  386. if err := s.DB.Create(estrusList).Error; err != nil {
  387. return xerr.WithStack(err)
  388. }
  389. return nil
  390. }
  391. func (s *StoreEntry) FrozenSemenList(ctx context.Context, req *pasturePb.FrozenSemenRequest, pagination *pasturePb.PaginationModel) (*pasturePb.FrozenSemenResponse, error) {
  392. frozenSemenList := make([]*model.FrozenSemen, 0)
  393. var count int64 = 0
  394. pref := s.DB.Table(new(model.FrozenSemen).TableName())
  395. if req.BullId != "" {
  396. pref.Where("bull_id = ?", req.BullId)
  397. }
  398. if req.Producer != "" {
  399. pref.Where("producer = ?", req.Producer)
  400. }
  401. if err := pref.Order("id desc").
  402. Count(&count).Limit(int(pagination.PageSize)).
  403. Offset(int(pagination.PageOffset)).
  404. Find(&frozenSemenList).Error; err != nil {
  405. return nil, xerr.WithStack(err)
  406. }
  407. frozenSemenTypeMap := s.FrozenSemenTypeMap()
  408. unitMap := s.UnitMap()
  409. return &pasturePb.FrozenSemenResponse{
  410. Code: http.StatusOK,
  411. Message: "ok",
  412. Data: &pasturePb.SearchFrozenSemenData{
  413. List: model.FrozenSemenSlice(frozenSemenList).ToPB(frozenSemenTypeMap, unitMap),
  414. Total: int32(count),
  415. PageSize: pagination.PageSize,
  416. Page: pagination.Page,
  417. },
  418. }, nil
  419. }
  420. func (s *StoreEntry) FrozenSemenCreate(ctx context.Context, req *pasturePb.SearchFrozenSemenList) error {
  421. currentUser, _ := s.GetCurrentSystemUser(ctx)
  422. req.CowKindName = s.CowKindMap()[req.CowKind]
  423. newFrozenSemen := model.NewFrozenSemen(req, currentUser)
  424. if err := s.DB.Create(newFrozenSemen).Error; err != nil {
  425. return xerr.WithStack(err)
  426. }
  427. return nil
  428. }
  429. func (s *StoreEntry) SameTimeCreate(ctx context.Context, req *pasturePb.EventSameTime) error {
  430. if _, err := s.GetSameTimeById(ctx, int64(req.SameTimeId)); err != nil {
  431. return xerr.WithStack(err)
  432. }
  433. cowList, err := s.ParseCowIds(ctx, req.CowId)
  434. if err != nil {
  435. return xerr.WithStack(err)
  436. }
  437. cowIds := make([]int64, 0)
  438. for _, v := range cowList {
  439. cowIds = append(cowIds, v.Id)
  440. }
  441. drugs := &model.Drugs{}
  442. if req.DrugsId > 0 {
  443. if drugs, err = s.GetDrugsById(ctx, int64(req.DrugsId)); err != nil {
  444. return xerr.WithStack(err)
  445. }
  446. }
  447. systemUser, _ := s.GetSystemUserById(ctx, int64(req.StaffMemberId))
  448. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  449. if err = tx.Model(new(model.CowSameTime)).
  450. Where("cow_id IN ?", cowIds).
  451. Where("same_time_id = ?", req.SameTimeId).
  452. Update("same_time_status", pasturePb.SameTimeStatus_In_Progress).Error; err != nil {
  453. return xerr.WithStack(err)
  454. }
  455. if err = tx.Model(new(model.EventCowSameTime)).
  456. Where("cow_id IN ?", cowIds).
  457. Where("same_time_id = ?", req.SameTimeId).
  458. Where("same_time_type = ?", req.SameTimeType).
  459. Updates(map[string]interface{}{
  460. "status": pasturePb.IsShow_Ok,
  461. "drug_id": drugs.Id,
  462. "unit": drugs.Unit,
  463. "usage": req.Usage,
  464. "remarks": req.Remarks,
  465. "operation_id": req.StaffMemberId,
  466. "operation_name": systemUser.Name,
  467. }).Error; err != nil {
  468. return xerr.WithStack(err)
  469. }
  470. return nil
  471. }); err != nil {
  472. return xerr.WithStack(err)
  473. }
  474. return nil
  475. }
  476. func (s *StoreEntry) AbortionCreate(ctx context.Context, req *pasturePb.EventAbortionRequest) error {
  477. cow, err := s.GetCowInfoByCowId(ctx, int64(req.CowId))
  478. if err != nil {
  479. return xerr.WithStack(err)
  480. }
  481. systemUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
  482. if err != nil {
  483. return xerr.WithStack(err)
  484. }
  485. req.OperationName = systemUser.Name
  486. abortionReasonsMap := s.AbortionReasonsMap()
  487. newEventAbortion := model.NewEventAbortion(cow, req, abortionReasonsMap)
  488. lastCowMating := &model.EventMating{}
  489. if err = s.DB.Where("cow_id = ?", cow.Id).Order("id desc").First(lastCowMating).Error; err != nil {
  490. return xerr.WithStack(err)
  491. }
  492. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  493. // 创建牛只流产事件数据
  494. if err = tx.Create(newEventAbortion).Error; err != nil {
  495. return xerr.WithStack(err)
  496. }
  497. // 更新牛只状态
  498. if err = tx.Model(new(model.Cow)).Where("id = ?", req.CowId).
  499. Updates(map[string]interface{}{
  500. "is_pregnant": pasturePb.IsShow_No,
  501. "last_abortion_at": req.AbortionAt,
  502. "breed_status": pasturePb.BreedStatus_Abort,
  503. }).Error; err != nil {
  504. return xerr.WithStack(err)
  505. }
  506. // 更新最近一次配种结果为流产
  507. if err = tx.Model(new(model.EventMating)).Where("id = ?", lastCowMating.Id).
  508. Updates(map[string]interface{}{
  509. "mating_result": pasturePb.MatingResult_Abort,
  510. }).Error; err != nil {
  511. }
  512. return nil
  513. }); err != nil {
  514. return xerr.WithStack(err)
  515. }
  516. return nil
  517. }
  518. func (s *StoreEntry) AbortionList(
  519. ctx context.Context,
  520. req *pasturePb.SearchEventRequest,
  521. pagination *pasturePb.PaginationModel,
  522. ) (*pasturePb.EventAbortionResponse, error) {
  523. abortionList := make([]*model.EventAbortion, 0)
  524. var count int64 = 0
  525. pref := s.DB.Model(new(model.EventAbortion))
  526. if len(req.CowId) > 0 {
  527. cowIds := strings.Split(req.CowId, ",")
  528. pref.Where("cow_id IN ?", cowIds)
  529. }
  530. if err := pref.Order("id desc").
  531. Count(&count).Limit(int(pagination.PageSize)).
  532. Offset(int(pagination.PageOffset)).
  533. Find(&abortionList).Error; err != nil {
  534. return nil, xerr.WithStack(err)
  535. }
  536. return &pasturePb.EventAbortionResponse{
  537. Code: http.StatusOK,
  538. Message: "ok",
  539. Data: &pasturePb.EventAbortionData{
  540. List: model.AbortionSlice(abortionList).ToPB(),
  541. Total: int32(count),
  542. PageSize: pagination.PageSize,
  543. Page: pagination.Page,
  544. },
  545. }, nil
  546. }