cow_cron.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. package crontab
  2. import (
  3. "context"
  4. "fmt"
  5. "kpt-pasture/model"
  6. "kpt-pasture/module/backend"
  7. "kpt-pasture/util"
  8. "strings"
  9. "time"
  10. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  11. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  12. "gitee.com/xuyiping_admin/pkg/xerr"
  13. "go.uber.org/zap"
  14. )
  15. const (
  16. UpdateCowInfo = "UpdateCowInfo"
  17. ImmunizationPlan = "ImmunizationPlan"
  18. SameTimePlan = "SameTimePlan"
  19. WorkOrderMaster = "WorkOrderMaster"
  20. SystemBasicCrontab = "SystemBasicCrontab"
  21. NeckRingOriginal = "NeckRingOriginal"
  22. )
  23. // GenerateAsynqWorkOrder 异步生成工作单
  24. func (e *Entry) GenerateAsynqWorkOrder() error {
  25. if ok := e.IsExistCrontabLog(WorkOrderMaster); ok {
  26. return nil
  27. }
  28. defer func() {
  29. e.CreateCrontabLog(WorkOrderMaster)
  30. }()
  31. workOrderList := make([]*model.WorkOrderMaster, 0)
  32. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&workOrderList).Error; err != nil {
  33. return err
  34. }
  35. for _, workOrder := range workOrderList {
  36. timeUnix, err := util.ConvertParseLocalUnix(workOrder.ExecTime)
  37. if timeUnix <= 0 || err != nil {
  38. zaplog.Error("crontab", zap.Any("GenerateWorkOrder", err), zap.Any("execTime", workOrder.ExecTime))
  39. continue
  40. }
  41. nowTime := time.Now().Local().Unix()
  42. if timeUnix < nowTime {
  43. continue
  44. }
  45. execTime := timeUnix - nowTime
  46. task := model.NewTaskWorkOrderPayload(workOrder.Id, time.Duration(execTime)*time.Second)
  47. if _, err = e.AsynqClient.CtxEnqueue(context.Background(), task); err != nil {
  48. zaplog.Error("PushMessage CtxEnqueue", zap.Any("Err", err))
  49. }
  50. }
  51. return nil
  52. }
  53. // Indicators 月度指标维护
  54. func (e *Entry) Indicators() error {
  55. nowTime := time.Now().Local()
  56. defer func() {
  57. zaplog.Info("crontab", zap.Any("Indicators", time.Now().Sub(nowTime).Seconds()))
  58. }()
  59. // 获取所有指标
  60. indicatorsDetailsList := make([]*model.IndicatorsDetails, 0)
  61. if err := e.DB.Model(new(model.IndicatorsDetails)).
  62. Where("is_show = ?", pasturePb.IsShow_Ok).
  63. Find(&indicatorsDetailsList).Error; err != nil {
  64. return err
  65. }
  66. // 获取所有牧场
  67. pastureList := e.FindPastureList()
  68. // 获取当月开始时间和结束时间
  69. startTime, endTime := util.GetMonthStartAndEndTimestamp()
  70. for _, indicatorsDetail := range indicatorsDetailsList {
  71. pastureIndicatorList := map[int64]string{}
  72. switch indicatorsDetail.Kind {
  73. case model.AllCow:
  74. pastureIndicatorList = e.FindPastureAllCow(pastureList)
  75. case model.AdultCow:
  76. pastureIndicatorList = e.FindPastureAdultCow(pastureList)
  77. case model.AvgCalvingInterval:
  78. pastureIndicatorList = e.FindAvgCalvingInterval(pastureList, startTime, endTime)
  79. case model.OutputNumber:
  80. pastureIndicatorList = e.FindOutputNumber(pastureList, startTime, endTime)
  81. case model.InputNumber:
  82. pastureIndicatorList = e.FindInputNumber(pastureList, startTime, endTime)
  83. case model.SalesVolume:
  84. pastureIndicatorList = e.FindSalesVolume(pastureList, startTime, endTime)
  85. case model.CalvingNumber:
  86. pastureIndicatorList = e.FindCalvingNumber(pastureList, startTime, endTime)
  87. case model.FattenCattleNumber:
  88. pastureIndicatorList = e.FattenCattleNumber(pastureList, startTime, endTime)
  89. case model.YouthAbortionRate:
  90. pastureIndicatorList = e.FindAdultAbortionRate(pastureList, "youth", startTime, endTime)
  91. case model.AllDieNumber:
  92. pastureIndicatorList = e.FindDeathNumber(pastureList, startTime, endTime, false)
  93. case model.DiseaseNumber:
  94. pastureIndicatorList = e.FindDiseaseNumber(pastureList, startTime, endTime)
  95. case model.CureNumber:
  96. pastureIndicatorList = e.FindCureNumber(pastureList, startTime, endTime)
  97. case model.OutNumber:
  98. pastureIndicatorList = e.FindDepartureNumber(pastureList, pasturePb.SalesType_Out, startTime, endTime)
  99. case model.CalfDieNumber:
  100. pastureIndicatorList = e.FindDeathNumber(pastureList, startTime, endTime, true)
  101. case model.LactationCow:
  102. pastureIndicatorList = e.LactationCow(pastureList, pasturePb.CowMilk_Lactation)
  103. case model.DryMilkCow:
  104. pastureIndicatorList = e.LactationCow(pastureList, pasturePb.CowMilk_Dry_Milk)
  105. case model.ReserveCow:
  106. pastureIndicatorList = e.LactationCow(pastureList, pasturePb.CowMilk_Reserve)
  107. case model.FirstBornSurvivalRate:
  108. pastureIndicatorList = e.FirstBornSurvivalRate(pastureList, startTime, endTime)
  109. case model.FirstBornDeathRate:
  110. pastureIndicatorList = e.FirstBornDeathRate(pastureList, startTime, endTime)
  111. case model.MultiparitySurvivalRate:
  112. pastureIndicatorList = e.MultiparitySurvivalRate(pastureList, startTime, endTime)
  113. case model.MultiparityDeathRate:
  114. pastureIndicatorList = e.MultiparityDeathRate(pastureList, startTime, endTime)
  115. case model.AvgAgeFirstMate:
  116. pastureIndicatorList = e.AvgAgeFirstMate(pastureList, startTime, endTime)
  117. case model.YouthPregnantRate:
  118. pastureIndicatorList = e.CowPregnantRate(pastureList, indicatorsDetail.Kind)
  119. case model.MultiparityPregnantRate:
  120. pastureIndicatorList = e.CowPregnantRate(pastureList, indicatorsDetail.Kind)
  121. case model.MultipartyFirstCheckRate:
  122. pastureIndicatorList = e.PregnantCheckRate(pastureList, startTime, endTime, true, model.PregnantCheckForFirst)
  123. case model.MultipartySecondCheckRate:
  124. pastureIndicatorList = e.PregnantCheckRate(pastureList, startTime, endTime, true, model.PregnantCheckForSecond)
  125. case model.YouthFirstCheckRate:
  126. pastureIndicatorList = e.PregnantCheckRate(pastureList, startTime, endTime, false, model.PregnantCheckForFirst)
  127. case model.YouthSecondCheckRate:
  128. pastureIndicatorList = e.PregnantCheckRate(pastureList, startTime, endTime, false, model.PregnantCheckForSecond)
  129. case model.ForbiddenCowNumber:
  130. pastureIndicatorList = e.ForbiddenCowNumber(pastureList, startTime, endTime)
  131. case model.AvgRegistrationDays:
  132. pastureIndicatorList = e.AvgRegistrationDays(pastureList)
  133. case model.AvgPregnancyDays:
  134. pastureIndicatorList = e.AvgPregnancyDays(pastureList, startTime, endTime)
  135. case model.AvgGestationalAge:
  136. pastureIndicatorList = e.AvgGestationalAge(pastureList)
  137. case model.Month17UnPregnancyRate:
  138. pastureIndicatorList = e.MonthUnPregnancyRate(pastureList, 17)
  139. case model.Month20UnPregnancyRate:
  140. pastureIndicatorList = e.MonthUnPregnancyRate(pastureList, 20)
  141. case model.Multiparty150DaysUnPregnancyRate:
  142. pastureIndicatorList = e.Multiparty150DaysUnPregnancyRate(pastureList, 150)
  143. case model.MultipartyAbortionNumber:
  144. pastureIndicatorList = e.MultipartyAbortionNumber(pastureList, startTime, endTime, pasturePb.IsShow_No)
  145. case model.MultipartyPregnancyNumber:
  146. pastureIndicatorList = e.MultipartyPregnancyNumber(pastureList)
  147. case model.MultipartyAbortionRate:
  148. pastureIndicatorList = e.MultipartyAbortionRate(pastureList, startTime, endTime)
  149. case model.MultipartyOutNumber:
  150. pastureIndicatorList = e.MultipartyOutNumber(pastureList, startTime, endTime)
  151. case model.MultipartyDieNumber:
  152. pastureIndicatorList = e.MultipartyDieNumber(pastureList, startTime, endTime)
  153. case model.Calving60DieRate:
  154. pastureIndicatorList = e.CalvingDieRate(pastureList, startTime, endTime, 60)
  155. case model.Calving60OutRate:
  156. pastureIndicatorList = e.CalvingOutRate(pastureList, startTime, endTime, 60)
  157. case model.AvgDepartureWeight:
  158. pastureIndicatorList = e.AvgDepartureWeight(pastureList, startTime, endTime)
  159. case model.AvgSlaughterCycle:
  160. pastureIndicatorList = e.AvgSlaughterCycle(pastureList, startTime, endTime)
  161. case model.SurvivalLiveRate:
  162. pastureIndicatorList = e.SurvivalLiveRate(pastureList, startTime, endTime, 262)
  163. case model.StillbirthRate:
  164. pastureIndicatorList = e.StillbirthRate(pastureList, startTime, endTime)
  165. case model.FemaleCalfRate:
  166. pastureIndicatorList = e.FemaleCalfRate(pastureList, startTime, endTime)
  167. case model.WeaningDailyWeight:
  168. pastureIndicatorList = e.WeaningDailyWeight(pastureList, startTime, endTime)
  169. case model.Day60DieRate:
  170. pastureIndicatorList = e.DayDieRate(pastureList, startTime, endTime, 60)
  171. case model.AdultPrematureBirthRate:
  172. pastureIndicatorList = e.PrematureBirthRate(pastureList, startTime, endTime, 60, true)
  173. case model.YouthPrematureBirthRate:
  174. pastureIndicatorList = e.PrematureBirthRate(pastureList, startTime, endTime, 60, false)
  175. case model.LessThan6monthCalfNumber:
  176. pastureIndicatorList = e.LessThan6monthCalfNumber(pastureList, startTime, endTime)
  177. case model.AdultCowsPregnancyRate:
  178. pastureIndicatorList = e.AdultCowsPregnancyRate(pastureList, startTime, endTime)
  179. case model.Lact1PregnancyRate:
  180. pastureIndicatorList = e.LactPregnancyRate(pastureList, "lact = 1", startTime, endTime)
  181. case model.Lact2PregnancyRate:
  182. pastureIndicatorList = e.LactPregnancyRate(pastureList, "lact = 2", startTime, endTime)
  183. case model.Lact3PregnancyRate:
  184. pastureIndicatorList = e.LactPregnancyRate(pastureList, "lact >= 3", startTime, endTime)
  185. case model.FirstMatingPregnancyRate:
  186. pastureIndicatorList = e.MatingPregnancyRate(pastureList, model.FirstMatingPregnancyRate, startTime, endTime)
  187. case model.SecondMatingPregnancyRate:
  188. pastureIndicatorList = e.MatingPregnancyRate(pastureList, model.SecondMatingPregnancyRate, startTime, endTime)
  189. case model.Day75DayMatingRate:
  190. pastureIndicatorList = e.Day75DayMatingRate(pastureList)
  191. case model.Day75DMonthMatingRate:
  192. pastureIndicatorList = e.Day75MonthMatingRate(pastureList, indicatorsDetail.Id)
  193. case model.AvgAdultCowEmptyNumber:
  194. pastureIndicatorList = e.AvgAdultCowEmptyNumber(pastureList, startTime, endTime)
  195. case model.AdultCowPregnantCheckOkRate:
  196. pastureIndicatorList = e.CowPregnantCheckOkRate(pastureList, "lact >= 1", startTime, endTime)
  197. case model.YouthCowPregnantCheckOkRate:
  198. pastureIndicatorList = e.CowPregnantCheckOkRate(pastureList, "lact = 0", startTime, endTime)
  199. case model.AdultCowForbiddenMatingRate:
  200. pastureIndicatorList = e.CowForbiddenMatingRate(pastureList, "calving_age >=", startTime, endTime)
  201. case model.YouthCowForbiddenMatingRate:
  202. pastureIndicatorList = e.CowForbiddenMatingRate(pastureList, "day_age >= 395", startTime, endTime)
  203. case model.AdultCowForbiddenMatingNumber:
  204. pastureIndicatorList = e.CowForbiddenMatingNumber(pastureList, "lact >= 1", startTime, endTime)
  205. case model.YouthCowForbiddenMatingNumber:
  206. pastureIndicatorList = e.CowForbiddenMatingNumber(pastureList, "lact = 0", startTime, endTime)
  207. }
  208. for pastureId, value := range pastureIndicatorList {
  209. e.UpdatePastureIndicators(pastureId, indicatorsDetail, startTime, value)
  210. }
  211. }
  212. return nil
  213. }
  214. // UpdateCowInfo 牛只基本信息维护
  215. func (e *Entry) UpdateCowInfo() error {
  216. pastureList := e.FindPastureList()
  217. for _, pasture := range pastureList {
  218. e.UpdateCowInfoByPasture(pasture.Id)
  219. }
  220. e.CreateCrontabLog(UpdateCowInfo)
  221. return nil
  222. }
  223. func (e *Entry) UpdateCowInfoByPasture(pastureId int64) {
  224. if ok := e.IsExistCrontabLog(UpdateCowInfo); ok {
  225. return
  226. }
  227. cowList := make([]*model.Cow, 0)
  228. if err := e.DB.Model(new(model.Cow)).
  229. Where("pasture_id = ?", pastureId).
  230. Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
  231. Find(&cowList).Error; err != nil {
  232. zaplog.Error("crontab", zap.Any("UpdateCowInfoByPasture", err))
  233. return
  234. }
  235. dateTime := time.Now().Local().Format(model.LayoutMonth)
  236. for _, cow := range cowList {
  237. // 周活动量
  238. weeklyActive := e.UpdateCowWeeklyHigh(pastureId, cow)
  239. zaplog.Info("crontab", zap.Any("weeklyActive", weeklyActive), zap.Any("cow", cow))
  240. cow.EventUpdate(weeklyActive)
  241. if err := e.DB.Model(new(model.Cow)).
  242. Select("day_age", "calving_age", "pregnancy_age", "admission_age", "abortion_age", "cow_type", "weekly_active", "lactation_age", "dry_milk_age", "mating_age").
  243. Where("id = ?", cow.Id).
  244. Updates(cow).Error; err != nil {
  245. zaplog.Error("Crontab", zap.Any("UpdateCowDayAge", err))
  246. }
  247. // 每月怀孕数据
  248. cowPregnantList := make([]*model.CowPregnant, 0)
  249. if cow.IsPregnant == pasturePb.IsShow_Ok || cow.BreedStatus == pasturePb.BreedStatus_Pregnant {
  250. cowPregnantList = append(cowPregnantList, model.NewCowPregnant(pastureId, cow, dateTime))
  251. }
  252. if len(cowPregnantList) > 0 {
  253. if err := e.DB.Model(new(model.CowPregnant)).
  254. Where("pasture_id = ?", pastureId).
  255. Where("date_time = ?", dateTime).
  256. Delete(new(model.CowPregnant)).Error; err != nil {
  257. zaplog.Error("Crontab", zap.Any("UpdateCowPregnant", err))
  258. }
  259. if err := e.DB.Model(new(model.CowPregnant)).
  260. Create(&cowPregnantList).Error; err != nil {
  261. zaplog.Error("Crontab", zap.Any("UpdateCowPregnant", err))
  262. }
  263. }
  264. }
  265. }
  266. // ImmunizationPlan 免疫计划,生成工作单
  267. func (e *Entry) ImmunizationPlan() error {
  268. if ok := e.IsExistCrontabLog(ImmunizationPlan); ok {
  269. return nil
  270. }
  271. planList := make([]*model.ImmunizationPlan, 0)
  272. if err := e.DB.Model(new(model.ImmunizationPlan)).
  273. Where("is_show = ?", pasturePb.IsShow_Ok).
  274. Order("pasture_id").
  275. Find(&planList).Error; err != nil {
  276. return xerr.WithStack(err)
  277. }
  278. var todayCount int32 = 0
  279. nowTime := time.Now().Local()
  280. for _, plan := range planList {
  281. cowList := make([]*model.Cow, 0)
  282. pref := e.DB.Table(fmt.Sprintf("%s as a", new(model.Cow).TableName())).
  283. Select("a.*").
  284. Where("a.pasture_id = ?", plan.PastureId).
  285. Where("a.admission_status = ?", pasturePb.AdmissionStatus_Admission).
  286. Where("NOT EXISTS ( select 1 from event_immunization_plan b where b.pen_id = a.id and b.status = ? and b.plan_day > ?)", pasturePb.IsShow_No, nowTime.Unix())
  287. if plan.CowType > 0 {
  288. pref.Where("a.cow_type = ?", plan.CowType)
  289. }
  290. switch plan.Conditions {
  291. case pasturePb.ImmunizationConditions_Days_Age:
  292. pref.Where("a.day_age = ?", plan.Value)
  293. case pasturePb.ImmunizationConditions_Days_After_Delivery:
  294. pref.Where("a.calving_age = ?", plan.Value)
  295. case pasturePb.ImmunizationConditions_Days_Of_Pregnancy:
  296. pref.Where("a.pregnancy_age = ?", plan.Value).
  297. Where("a.is_pregnant = ?", pasturePb.IsShow_Ok)
  298. case pasturePb.ImmunizationConditions_Month:
  299. continue
  300. case pasturePb.ImmunizationConditions_Admission_Days:
  301. pref.Where("a.admission_age = ?", plan.Value)
  302. case pasturePb.ImmunizationConditions_Other_Vaccine_After:
  303. if plan.ImmunizationPlanId > 0 {
  304. pref.Joins("INNER JOIN event_immunization_plan as b ON b.plan_id = ? ", plan.ImmunizationPlanId).
  305. Where("b.cow_id = a.id").
  306. Where("DATE_ADD(b.reality_day, INTERVAL ? DAY) = ?", plan.Value, time.Now().Local().Format(model.LayoutDate2)).
  307. Where("b.status = ?", pasturePb.IsShow_Ok)
  308. }
  309. }
  310. if err := pref.Find(&cowList).Debug().Error; err != nil {
  311. return xerr.WithStack(err)
  312. }
  313. if len(cowList) <= 0 {
  314. continue
  315. }
  316. newImmunizationPlanCowList := model.NewCowImmunizationPlanList(cowList, plan)
  317. if err := e.DB.Model(new(model.EventImmunizationPlan)).Create(newImmunizationPlanCowList).Error; err != nil {
  318. zaplog.Error("ImmunizationPlan",
  319. zap.Any("err", err),
  320. zap.Any("plan", plan),
  321. zap.Any("cowList", cowList),
  322. zap.Any("newImmunizationPlanCowList", newImmunizationPlanCowList),
  323. )
  324. return xerr.WithStack(err)
  325. }
  326. todayCount = int32(len(newImmunizationPlanCowList))
  327. if todayCount > 0 {
  328. endDay := nowTime.AddDate(0, 0, model.CalendarTypeEndDaysMap[pasturePb.CalendarType_Immunisation])
  329. e.CreatedCalendar(plan.PastureId, pasturePb.CalendarType_Immunisation, nowTime.Format(model.LayoutDate2), endDay.Format(model.LayoutDate2), todayCount)
  330. }
  331. e.CreateCrontabLog(ImmunizationPlan)
  332. }
  333. return nil
  334. }
  335. // SameTimePlan 同期计划,生成工作单
  336. func (e *Entry) SameTimePlan() error {
  337. if ok := e.IsExistCrontabLog(SameTimePlan); ok {
  338. return nil
  339. }
  340. sameTimeList := make([]*model.SameTime, 0)
  341. if err := e.DB.Model(new(model.SameTime)).
  342. Where("is_show = ?", pasturePb.IsShow_Ok).
  343. Order("pasture_id").
  344. Find(&sameTimeList).Error; err != nil {
  345. return xerr.WithStack(err)
  346. }
  347. if len(sameTimeList) < 0 {
  348. return nil
  349. }
  350. defer func() {
  351. e.CreateCrontabLog(SameTimePlan)
  352. }()
  353. currWeek := time.Now().Local().Weekday()
  354. for _, sameTime := range sameTimeList {
  355. if len(sameTime.WeekType) <= 0 {
  356. continue
  357. }
  358. wts := strings.Split(sameTime.WeekType, model.WeekTypeSeparator)
  359. if len(wts) <= 0 {
  360. continue
  361. }
  362. var info bool
  363. for _, wt := range wts {
  364. if time.Weekday(int(pasturePb.Week_Kind_value[wt])) == currWeek {
  365. info = true
  366. break
  367. }
  368. }
  369. if !info {
  370. continue
  371. }
  372. cowList := make([]*model.Cow, 0)
  373. pref := e.DB.Model(new(model.Cow)).
  374. Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
  375. Where("sex = ?", pasturePb.Genders_Female).
  376. Where("pasture_id = ?", sameTime.PastureId).
  377. Where("is_pregnant = ?", pasturePb.IsShow_No)
  378. switch sameTime.CowType {
  379. case pasturePb.SameTimeCowType_Breeding_Calf:
  380. pref.Where("calving_age BETWEEN ? AND ?", sameTime.PostpartumDaysStart, sameTime.PostpartumDaysEnd).
  381. Where("lact > ?", 0)
  382. case pasturePb.SameTimeCowType_Empty:
  383. pref.Where(
  384. e.DB.Where("breed_status = ?", pasturePb.BreedStatus_Empty).
  385. Or("breed_status = ?", pasturePb.BreedStatus_Abort),
  386. )
  387. default:
  388. continue
  389. }
  390. if err := pref.Where(`NOT EXISTS (SELECT 1 FROM event_cow_same_time WHERE event_cow_same_time.cow_id = cow.id
  391. AND event_cow_same_time.status = ?)`, pasturePb.IsShow_No).
  392. Find(&cowList).Error; err != nil {
  393. zaplog.Error("crontab", zap.Any("err", err), zap.Any("sameTime", sameTime))
  394. return xerr.WithStack(err)
  395. }
  396. if len(cowList) <= 0 {
  397. continue
  398. }
  399. if err := e.GenerateCalendarBySameTimePlan(cowList, sameTime); err != nil {
  400. zaplog.Error("crontab",
  401. zap.Any("GenerateCalendarBySameTimePlan", err),
  402. zap.Any("cowList", cowList),
  403. zap.Any("plan", sameTime),
  404. )
  405. continue
  406. }
  407. }
  408. return nil
  409. }
  410. // UpdateSameTime 更新每天同期数据
  411. func (e *Entry) UpdateSameTime() error {
  412. calendarTypeList := backend.CalendarTypeEnumList("")
  413. showDay := time.Now().Local().Format(model.LayoutDate2)
  414. for _, v := range calendarTypeList {
  415. count := int64(0)
  416. if err := e.DB.Model(new(model.EventCowSameTime)).
  417. Where("same_time_type = ?", v.Value).
  418. Where("status = ?", pasturePb.IsShow_No).
  419. Count(&count).Error; err != nil {
  420. zaplog.Error("crontab", zap.Any("UpdateSameTime", err), zap.Any("count", count))
  421. }
  422. if count >= 0 {
  423. continue
  424. }
  425. isExist := int64(0)
  426. if err := e.DB.Model(new(model.Calendar)).
  427. Where("calendar_type = ?", v.Value).
  428. Where("show_day = ?", showDay).
  429. Count(&isExist).Error; err != nil {
  430. continue
  431. }
  432. if isExist <= 0 {
  433. continue
  434. }
  435. if err := e.DB.Model(new(model.Calendar)).
  436. Where("calendar_type = ?", v.Value).
  437. Where("show_day = ?", showDay).
  438. Updates(map[string]interface{}{
  439. "count": count,
  440. }).Error; err != nil {
  441. continue
  442. }
  443. }
  444. return nil
  445. }
  446. // SystemBasicCrontab 基础配置计划任务
  447. func (e *Entry) SystemBasicCrontab() error {
  448. if ok := e.IsExistCrontabLog(SystemBasicCrontab); ok {
  449. return nil
  450. }
  451. defer func() {
  452. e.CreateCrontabLog(SystemBasicCrontab)
  453. }()
  454. systemBasicList := make([]*model.SystemBasic, 0)
  455. if err := e.DB.Model(new(model.SystemBasic)).
  456. Where("is_show = ?", pasturePb.IsShow_Ok).
  457. Where("name IN ?", []string{
  458. model.PregnantCheckForFirst,
  459. model.PregnantCheckForSecond,
  460. model.WeaningAge,
  461. model.PregnancyAge,
  462. model.DryMilkAge,
  463. }).Order("pasture_id").
  464. Find(&systemBasicList).Error; err != nil {
  465. zaplog.Error("crontab", zap.Any("PregnancyCheck", err))
  466. return xerr.WithStack(err)
  467. }
  468. currWeekValue := time.Now().Local().Weekday()
  469. for _, systemBasic := range systemBasicList {
  470. // 周执行
  471. if systemBasic.Name == model.PregnantCheckForFirst && systemBasic.WeekValue >= 0 &&
  472. time.Weekday(systemBasic.WeekValue) != currWeekValue {
  473. continue
  474. }
  475. cowList := make([]*model.Cow, 0)
  476. pref := e.DB.Model(new(model.Cow)).
  477. Where("admission_status = ? ", pasturePb.AdmissionStatus_Admission).
  478. Where("pasture_id = ?", systemBasic.PastureId)
  479. switch systemBasic.Name {
  480. case model.PregnantCheckForFirst: // 初检清单
  481. pref.Where("breed_status = ?", pasturePb.BreedStatus_Breeding).
  482. Where("last_mating_at > ?", 0).
  483. Where("DATE(FROM_UNIXTIME(last_mating_at)) BETWEEN DATE_SUB(CURDATE(), INTERVAL ? DAY) AND DATE_SUB(CURDATE(), INTERVAL ? DAY)", systemBasic.MaxValue, systemBasic.MinValue).
  484. Where(`NOT EXISTS (SELECT 1 FROM event_pregnant_check WHERE event_pregnant_check.cow_id = cow.id
  485. AND event_pregnant_check.status = ? AND event_pregnant_check.pregnant_check_name = ?)`, pasturePb.IsShow_No, model.PregnantCheckForFirst)
  486. case model.PregnantCheckForSecond: // 复检清单 过滤初检空怀的牛只
  487. pref.Where("breed_status IN (?)", []pasturePb.BreedStatus_Kind{pasturePb.BreedStatus_Pregnant}).
  488. Where("last_mating_at > ?", 0).
  489. Where("DATE(FROM_UNIXTIME(last_mating_at)) = DATE_SUB(CURDATE(), INTERVAL ? DAY)", systemBasic.MinValue).
  490. Where(`NOT EXISTS (SELECT 1 FROM event_pregnant_check WHERE event_pregnant_check.cow_id = cow.id
  491. AND event_pregnant_check.status = ? AND event_pregnant_check.pregnant_check_name = ? )`, pasturePb.IsShow_No, model.PregnantCheckForSecond)
  492. case model.WeaningAge: // 断奶清单
  493. pref.Where("day_age = ?", systemBasic.MinValue).
  494. Where("NOT EXISTS (SELECT 1 FROM event_weaning WHERE event_weaning.cow_id = cow.id AND event_weaning.status = ?)", pasturePb.IsShow_No)
  495. case model.PregnancyAge: // 产犊清单
  496. pref.Where("pregnancy_age BETWEEN ? AND ?", systemBasic.MinValue, systemBasic.MaxValue).
  497. Where("breed_status = ?", pasturePb.BreedStatus_Pregnant).
  498. Where("NOT EXISTS (SELECT 1 FROM event_calving WHERE event_calving.cow_id = cow.id AND event_calving.status = ?)", pasturePb.IsShow_No)
  499. case model.DryMilkAge: // 干奶清单
  500. pref.Where("pregnancy_age BETWEEN ? AND ?", systemBasic.MinValue, systemBasic.MaxValue).
  501. Where("breed_status = ?", pasturePb.BreedStatus_Pregnant).
  502. Where("is_pregnant = ?", pasturePb.IsShow_Ok).
  503. Where("NOT EXISTS (SELECT 1 FROM event_dry_milk WHERE event_dry_milk.cow_id = cow.id AND event_dry_milk.status = ?)", pasturePb.IsShow_No)
  504. default:
  505. continue
  506. }
  507. if err := pref.Find(&cowList).Error; err != nil {
  508. zaplog.Error("crontab", zap.Any("PregnancyCheck", err), zap.Any("cowList", cowList))
  509. continue
  510. }
  511. if len(cowList) <= 0 {
  512. continue
  513. }
  514. e.InitEventData(cowList, systemBasic)
  515. }
  516. return nil
  517. }
  518. func (e *Entry) DeleteOldOriginal() error {
  519. if err := e.DB.Model(new(model.NeckRingOriginal)).
  520. Where("active_date <= ?", time.Now().Local().AddDate(0, 0, -15).Format(model.LayoutDate2)).
  521. Delete(&model.NeckRingOriginal{}).Error; err != nil {
  522. zaplog.Error("crontab", zap.Any("DeleteOldOriginal", err))
  523. }
  524. if err := e.DB.Model(new(model.NeckActiveHabit)).
  525. Where("heat_date <= ?", time.Now().Local().AddDate(0, -3, 0).Format(model.LayoutDate2)).
  526. Delete(&model.NeckActiveHabit{}).Error; err != nil {
  527. zaplog.Error("crontab", zap.Any("DeleteNeckActiveHabit", err))
  528. }
  529. return nil
  530. }
  531. // UpdateDiseaseToCalendar 更新每天治疗中牛头数到日历表中
  532. func (e *Entry) UpdateDiseaseToCalendar() error {
  533. pastureList := e.FindPastureList()
  534. for _, pasture := range pastureList {
  535. // 更新每天治疗中牛头数到日历表中
  536. var count int64
  537. if err := e.DB.Model(new(model.EventCowDisease)).
  538. Where("pasture_id = ?", pasture.Id).
  539. Where("health_status IN (?)", []pasturePb.HealthStatus_Kind{pasturePb.HealthStatus_Disease, pasturePb.HealthStatus_Treatment}).
  540. Count(&count).Error; err != nil {
  541. zaplog.Error("crontab", zap.Any("UpdateDisease", err))
  542. }
  543. if count > 0 {
  544. calendarTypeName := backend.CalendarTypeMap()[pasturePb.CalendarType_Disease]
  545. startDay := time.Now().Local().Format(model.LayoutDate2)
  546. newCalendar := model.NewCalendar(pasture.Id, calendarTypeName, pasturePb.CalendarType_Disease, startDay, startDay, int32(count))
  547. if err := e.DB.Model(new(model.Calendar)).
  548. Create(newCalendar).Error; err != nil {
  549. zaplog.Error("crontab", zap.Any("UpdateDisease", err))
  550. }
  551. }
  552. }
  553. return nil
  554. }
  555. func (e *Entry) InitEventData(cowList []*model.Cow, systemBasic *model.SystemBasic) {
  556. calendarType := pasturePb.CalendarType_Invalid
  557. nowTime := time.Now().Local()
  558. startDay, endDay := "", ""
  559. switch systemBasic.Name {
  560. case model.PregnantCheckForFirst, model.PregnantCheckForSecond:
  561. penMap, _ := e.GetPenMapList(systemBasic.PastureId)
  562. calendarType = pasturePb.CalendarType_Pregnancy_Check
  563. startDay, endDay = nowTime.Format(model.LayoutDate2), nowTime.AddDate(0, 0, model.CalendarTypeEndDaysMap[calendarType]).Format(model.LayoutDate2)
  564. eventPregnantCheckDataList := model.NewEventPregnantCheckList(systemBasic.PastureId, cowList, penMap, systemBasic.Name, startDay, endDay)
  565. if err := e.DB.Model(new(model.EventPregnantCheck)).Create(eventPregnantCheckDataList).Error; err != nil {
  566. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventPregnantCheckDataList", eventPregnantCheckDataList))
  567. return
  568. }
  569. case model.WeaningAge:
  570. calendarType = pasturePb.CalendarType_Weaning
  571. startDay, endDay = nowTime.Format(model.LayoutDate2), nowTime.AddDate(0, 0, model.CalendarTypeEndDaysMap[calendarType]).Format(model.LayoutDate2)
  572. eventWeaningDataList := model.NewEventWeaningList(systemBasic.PastureId, cowList, startDay, endDay)
  573. if err := e.DB.Model(new(model.EventWeaning)).
  574. Create(eventWeaningDataList).Error; err != nil {
  575. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventWeaningDataList", eventWeaningDataList))
  576. return
  577. }
  578. case model.PregnancyAge:
  579. calendarType = pasturePb.CalendarType_Calving
  580. startDay, endDay = nowTime.Format(model.LayoutDate2), nowTime.AddDate(0, 0, model.CalendarTypeEndDaysMap[calendarType]).Format(model.LayoutDate2)
  581. eventCalvingList := model.NewEventCalvingList(systemBasic.PastureId, cowList, startDay, endDay)
  582. if err := e.DB.Model(new(model.EventCalving)).Create(eventCalvingList).Error; err != nil {
  583. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventCalvingList", eventCalvingList))
  584. return
  585. }
  586. case model.DryMilkAge:
  587. calendarType = pasturePb.CalendarType_DryMilk
  588. startDay, endDay = nowTime.Format(model.LayoutDate2), nowTime.AddDate(0, 0, model.CalendarTypeEndDaysMap[calendarType]).Format(model.LayoutDate2)
  589. eventCalvingList := model.NewEventDryMilkList(systemBasic.PastureId, cowList, startDay, endDay)
  590. if err := e.DB.Model(new(model.EventDryMilk)).Create(eventCalvingList).Error; err != nil {
  591. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventCalvingList", eventCalvingList))
  592. return
  593. }
  594. }
  595. e.CreatedCalendar(systemBasic.PastureId, calendarType, startDay, endDay, int32(len(cowList)))
  596. }