cow_cron.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. package crontab
  2. import (
  3. "context"
  4. "fmt"
  5. "kpt-pasture/model"
  6. "kpt-pasture/module/backend"
  7. "kpt-pasture/util"
  8. "time"
  9. "gorm.io/gorm"
  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. )
  22. // GenerateAsynqWorkOrder 异步生成工作单
  23. func (e *Entry) GenerateAsynqWorkOrder() error {
  24. if ok := e.IsExistCrontabLog(WorkOrderMaster); ok {
  25. return nil
  26. }
  27. defer func() {
  28. e.CreateCrontabLog(WorkOrderMaster)
  29. }()
  30. workOrderList := make([]*model.WorkOrderMaster, 0)
  31. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&workOrderList).Error; err != nil {
  32. return err
  33. }
  34. for _, workOrder := range workOrderList {
  35. timeUnix, err := util.ConvertParseLocalUnix(workOrder.ExecTime)
  36. if timeUnix <= 0 || err != nil {
  37. zaplog.Error("crontab", zap.Any("GenerateWorkOrder", err), zap.Any("execTime", workOrder.ExecTime))
  38. continue
  39. }
  40. nowTime := time.Now().Unix()
  41. if timeUnix < nowTime {
  42. continue
  43. }
  44. execTime := timeUnix - nowTime
  45. task := model.NewTaskWorkOrderPayload(workOrder.Id, time.Duration(execTime)*time.Second)
  46. if _, err = e.AsynqClient.CtxEnqueue(context.Background(), task); err != nil {
  47. zaplog.Error("PushMessage CtxEnqueue", zap.Any("Err", err))
  48. }
  49. }
  50. return nil
  51. }
  52. // UpdateCowInfo 牛只基本信息维护
  53. func (e *Entry) UpdateCowInfo() error {
  54. cowList := make([]*model.Cow, 0)
  55. if err := e.DB.Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).Find(&cowList).Error; err != nil {
  56. return err
  57. }
  58. if ok := e.IsExistCrontabLog(UpdateCowInfo); ok {
  59. return nil
  60. }
  61. defer func() {
  62. e.CreateCrontabLog(UpdateCowInfo)
  63. }()
  64. for _, cow := range cowList {
  65. if err := e.DB.Model(new(model.Cow)).
  66. Where("id = ?", cow.Id).
  67. Updates(map[string]interface{}{
  68. "day_age": cow.GetDayAge(),
  69. "calving_at": cow.GetCalvingAge(),
  70. "pregnancy_age": cow.GetDaysPregnant(),
  71. "admission_age": cow.GetAdmissionAge(),
  72. "abortion_age": cow.GetAbortionAge(),
  73. // todo 牛只类型待完善
  74. }).Error; err != nil {
  75. zaplog.Error("Crontab", zap.Any("UpdateCowDayAge", err))
  76. }
  77. }
  78. return nil
  79. }
  80. // ImmunizationPlan 免疫计划,生成工作单
  81. func (e *Entry) ImmunizationPlan() error {
  82. if ok := e.IsExistCrontabLog(ImmunizationPlan); ok {
  83. return nil
  84. }
  85. planList := make([]*model.ImmunizationPlan, 0)
  86. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&planList).Error; err != nil {
  87. return xerr.WithStack(err)
  88. }
  89. var todayCount int32 = 0
  90. defer func() {
  91. var count int64 = 0
  92. if err := e.DB.Model(new(model.EventImmunizationPlan)).
  93. Where("status = ?", pasturePb.IsShow_Ok).
  94. Count(&count).Error; err != nil {
  95. zaplog.Error("Crontab", zap.Any("ImmunizationPlanDefer", err))
  96. }
  97. todayCount += int32(count)
  98. if todayCount > 0 {
  99. e.CreatedCalendar(pasturePb.CalendarType_Immunisation, todayCount)
  100. }
  101. e.CreateCrontabLog(ImmunizationPlan)
  102. }()
  103. for _, plan := range planList {
  104. cowList := make([]*model.Cow, 0)
  105. pref := e.DB.Table(fmt.Sprintf("%s as a", new(model.Cow).TableName())).
  106. Select("a.*").
  107. Where("a.admission_status = ?", pasturePb.AdmissionStatus_Admission)
  108. if plan.CowType > 0 {
  109. pref.Where("a.cow_type = ?", plan.CowType)
  110. }
  111. switch plan.Conditions {
  112. case pasturePb.ImmunizationConditions_Days_Age:
  113. pref.Where("a.day_age = ?", plan.Value)
  114. case pasturePb.ImmunizationConditions_Days_After_Delivery:
  115. pref.Where("a.calving_age = ?", plan.Value)
  116. case pasturePb.ImmunizationConditions_Days_Of_Pregnancy:
  117. pref.Where("a.pregnancy_age = ?", plan.Value).
  118. Where("a.is_pregnant = ?", pasturePb.IsShow_Ok)
  119. case pasturePb.ImmunizationConditions_Month:
  120. // todo 待实现月份
  121. case pasturePb.ImmunizationConditions_Admission_Days:
  122. pref.Where("a.admission_age = ?", plan.Value)
  123. case pasturePb.ImmunizationConditions_Other_Vaccine_After:
  124. if plan.ImmunizationPlanId > 0 {
  125. pref.Joins("INNER JOIN event_immunization_plan as b ON b.immunization_plan_id = ? ", plan.ImmunizationPlanId).
  126. Where("b.cow_id = a.id").
  127. Where("DATE_ADD(b.reality_time, INTERVAL ? DAY) = ?", plan.Value, time.Now().Format(model.LayoutDate2)).
  128. Where("b.status = ?", pasturePb.IsShow_Ok)
  129. }
  130. }
  131. if err := pref.Find(&cowList).Error; err != nil {
  132. return xerr.WithStack(err)
  133. }
  134. if len(cowList) <= 0 {
  135. continue
  136. }
  137. todayCount += int32(len(cowList))
  138. penList, _ := e.GetPenMapList()
  139. newImmunizationPlanCowList := model.NewCowImmunizationPlanList(cowList, penList, plan)
  140. newEventItemList := model.NewEventItemList(cowList, pasturePb.CalendarType_Immunisation)
  141. if err := e.DB.Transaction(func(tx *gorm.DB) error {
  142. if err := tx.Create(newImmunizationPlanCowList).Error; err != nil {
  143. return xerr.WithStack(err)
  144. }
  145. if err := tx.Create(newEventItemList).Error; err != nil {
  146. return xerr.WithStack(err)
  147. }
  148. return nil
  149. }); err != nil {
  150. zaplog.Error("ImmunizationPlan", zap.Any("newImmunizationPlanCowList", err), zap.Any("plan", plan), zap.Any("cowList", cowList))
  151. }
  152. }
  153. zaplog.Info("ImmunizationPlan", zap.Any("todayCount", todayCount))
  154. return nil
  155. }
  156. // SameTimePlan 同期计划,生成工作单
  157. func (e *Entry) SameTimePlan() error {
  158. if ok := e.IsExistCrontabLog(SameTimePlan); ok {
  159. return nil
  160. }
  161. sameTimeList := make([]*model.SameTime, 0)
  162. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&sameTimeList).Error; err != nil {
  163. return xerr.WithStack(err)
  164. }
  165. // 更新日历里面的数据
  166. var todayCount int32 = 0
  167. defer func() {
  168. if todayCount > 0 {
  169. e.CreatedCalendar(pasturePb.CalendarType_Immunisation, todayCount)
  170. }
  171. e.CreateCrontabLog(SameTimePlan)
  172. }()
  173. currWeek := time.Now().Weekday()
  174. for _, sameTime := range sameTimeList {
  175. if sameTime == nil {
  176. continue
  177. }
  178. if time.Weekday(sameTime.WeekType) != currWeek {
  179. continue
  180. }
  181. cowList := make([]*model.Cow, 0)
  182. pref := e.DB.Model(new(model.Cow)).
  183. Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
  184. Where("sex = ?", pasturePb.Genders_Male)
  185. switch sameTime.CowType {
  186. case pasturePb.SameTimeCowType_Breeding_Calf:
  187. pref.Where("calving_age >= ?", sameTime.PostpartumDaysStart).
  188. Where("calving_age <= ?", sameTime.PostpartumDaysEnd).
  189. Where("is_pregnant = ?", pasturePb.IsShow_No)
  190. case pasturePb.SameTimeCowType_Empty:
  191. pref.Where(
  192. e.DB.Where("breed_status = ?", pasturePb.BreedStatus_Empty).
  193. Or("breed_status = ?", pasturePb.BreedStatus_Abort),
  194. ).Where("is_pregnant = ?", pasturePb.IsShow_No)
  195. default:
  196. continue
  197. }
  198. if err := pref.Find(&cowList).Error; err != nil {
  199. zaplog.Error("crontab", zap.Any("err", err), zap.Any("sameTime", sameTime))
  200. return xerr.WithStack(err)
  201. }
  202. if len(cowList) <= 0 {
  203. continue
  204. }
  205. currCount, err := e.GenerateCalendarBySameTimePlan(cowList, sameTime)
  206. if err != nil {
  207. zaplog.Error("crontab",
  208. zap.Any("GenerateCalendarBySameTimePlan", err),
  209. zap.Any("cowList", cowList),
  210. zap.Any("plan", sameTime),
  211. )
  212. continue
  213. }
  214. todayCount += currCount
  215. }
  216. return nil
  217. }
  218. // UpdateSameTime 更新每天同情数据
  219. func (e *Entry) UpdateSameTime() error {
  220. calendarTypeList := backend.CalendarTypeEnumList("")
  221. showDay := time.Now().Format(model.LayoutDate2)
  222. for _, v := range calendarTypeList {
  223. count := int64(0)
  224. if err := e.DB.Model(new(model.EventCowSameTime)).
  225. Where("same_time_type = ?", v.Value).
  226. Where("status = ?", pasturePb.IsShow_No).
  227. Count(&count).Error; err != nil {
  228. zaplog.Error("crontab", zap.Any("UpdateSameTime", err), zap.Any("count", count))
  229. }
  230. if count >= 0 {
  231. continue
  232. }
  233. isExist := int64(0)
  234. if err := e.DB.Model(new(model.Calendar)).
  235. Where("calendar_type = ?", v.Value).
  236. Where("show_day = ?", showDay).
  237. Count(&isExist).Error; err != nil {
  238. continue
  239. }
  240. if isExist <= 0 {
  241. continue
  242. }
  243. if err := e.DB.Model(new(model.Calendar)).
  244. Where("calendar_type = ?", v.Value).
  245. Where("show_day = ?", showDay).
  246. Updates(map[string]interface{}{
  247. "count": count,
  248. }).Error; err != nil {
  249. continue
  250. }
  251. }
  252. return nil
  253. }
  254. // SystemBasicCrontab 基础配置计划任务
  255. func (e *Entry) SystemBasicCrontab() error {
  256. if ok := e.IsExistCrontabLog(SystemBasicCrontab); ok {
  257. return nil
  258. }
  259. defer func() {
  260. e.CreateCrontabLog(SystemBasicCrontab)
  261. }()
  262. systemBasicList := make([]*model.SystemBasic, 0)
  263. if err := e.DB.Model(new(model.SystemBasic)).
  264. Where("is_show = ?", pasturePb.IsShow_Ok).
  265. Where("name IN ?", []string{
  266. model.PregnantCheckForFirst,
  267. model.PregnantCheckForSecond,
  268. model.WeaningAge,
  269. model.PregnancyAge,
  270. }).Find(&systemBasicList).Error; err != nil {
  271. zaplog.Error("crontab", zap.Any("PregnancyCheck", err))
  272. return xerr.WithStack(err)
  273. }
  274. currWeekValue := time.Now().Weekday()
  275. for _, v := range systemBasicList {
  276. // 周执行
  277. if v.WeekValue >= 0 && time.Weekday(v.WeekValue) != currWeekValue {
  278. continue
  279. }
  280. cowList := make([]*model.Cow, 0)
  281. pref := e.DB.Model(new(model.Cow)).Where("admission_status = ? ", pasturePb.AdmissionStatus_Admission)
  282. switch v.Name {
  283. case model.PregnantCheckForFirst:
  284. pref.Where("breed_status = ?", pasturePb.BreedStatus_Breeding)
  285. case model.PregnantCheckForSecond: // 过滤初检空怀的牛只
  286. pref.Where("breed_status = ?", pasturePb.BreedStatus_Pregnant)
  287. case model.WeaningAge:
  288. pref.Where("day_age = ?", v.MinValue)
  289. case model.PregnancyAge:
  290. pref.Where("pregnancy_age >= ?", v.MinValue).
  291. Where("breed_status = ?", pasturePb.BreedStatus_Pregnant)
  292. default:
  293. continue
  294. }
  295. if v.ValueType == model.ValueTypeFixed {
  296. pref.Where("day_age = ?", v.MinValue)
  297. }
  298. if v.ValueType == model.ValueTypeRange {
  299. pref.Where("day_age >= ?", v.MinValue).Where("day_age <= ?", v.MaxValue)
  300. }
  301. if err := pref.Find(&cowList).Error; err != nil {
  302. zaplog.Error("crontab", zap.Any("PregnancyCheck", err), zap.Any("cowList", cowList))
  303. continue
  304. }
  305. if len(cowList) <= 0 {
  306. continue
  307. }
  308. e.InitEventData(cowList, v.Name)
  309. }
  310. return nil
  311. }
  312. func (e *Entry) InitEventData(cowList []*model.Cow, systemBasicName string) {
  313. switch systemBasicName {
  314. case model.PregnantCheckForFirst, model.PregnantCheckForSecond:
  315. penMap, _ := e.GetPenMapList()
  316. eventPregnantCheckDataList := model.NewEventPregnantCheckList(cowList, penMap, systemBasicName)
  317. if err := e.DB.Create(eventPregnantCheckDataList).Error; err != nil {
  318. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventPregnantCheckDataList", eventPregnantCheckDataList))
  319. }
  320. case model.WeaningAge:
  321. eventWeaningDataList := model.NewEventWeaningList(cowList)
  322. if err := e.DB.Create(eventWeaningDataList).Error; err != nil {
  323. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventWeaningDataList", eventWeaningDataList))
  324. }
  325. case model.PregnancyAge:
  326. eventCalvingList := model.NewEventCalvingList(cowList)
  327. if err := e.DB.Create(eventCalvingList).Error; err != nil {
  328. zaplog.Error("crontab", zap.Any("InitEventData", err), zap.Any("eventCalvingList", eventCalvingList))
  329. }
  330. }
  331. }
  332. // DiseaseCheck 疾病检查
  333. func (e *Entry) DiseaseCheck() error {
  334. return nil
  335. }