crontab.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package crontab
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "kpt-pasture/model"
  7. "kpt-pasture/module/backend"
  8. "kpt-pasture/util"
  9. "time"
  10. "gorm.io/gorm"
  11. "gitee.com/xuyiping_admin/pkg/xerr"
  12. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  13. "go.uber.org/zap"
  14. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  15. )
  16. // UpdateCowInfo 牛只基本信息维护
  17. func (e *Entry) UpdateCowInfo() error {
  18. cowList := make([]*model.Cow, 0)
  19. if err := e.DB.Where("is_remove = ?", pasturePb.IsShow_Ok).Find(&cowList).Error; err != nil {
  20. return err
  21. }
  22. for _, cow := range cowList {
  23. dayAge := cow.GetDayAge()
  24. calvingAge := cow.GetCalvingAge()
  25. pregnancyAge := cow.GetDaysPregnant()
  26. admissionAge := cow.GetAdmissionAge()
  27. if err := e.DB.Model(new(model.Cow)).Where("id = ?", cow.Id).Updates(map[string]interface{}{
  28. "day_age": dayAge,
  29. "calving_at": calvingAge,
  30. "pregnancy_age": pregnancyAge,
  31. "admission_age": admissionAge,
  32. }).Error; err != nil {
  33. zaplog.Error("Crontab", zap.Any("UpdateCowDayAge", err))
  34. }
  35. }
  36. return nil
  37. }
  38. // GenerateAsynqWorkOrder 异步生成工作单
  39. func (e *Entry) GenerateAsynqWorkOrder() error {
  40. workOrderList := make([]*model.WorkOrderMaster, 0)
  41. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&workOrderList).Error; err != nil {
  42. return err
  43. }
  44. for _, workOrder := range workOrderList {
  45. timeUnix, err := util.ConvertParseLocalUnix(workOrder.ExecTime)
  46. if timeUnix <= 0 || err != nil {
  47. zaplog.Error("crontab", zap.Any("GenerateWorkOrder", err), zap.Any("execTime", workOrder.ExecTime))
  48. continue
  49. }
  50. execTime := time.Now().Unix() - timeUnix
  51. if _, err = e.AsynqClient.CtxEnqueue(
  52. context.Background(),
  53. model.NewTaskWorkOrderPayload(workOrder.Id, time.Duration(execTime)*time.Second),
  54. ); err != nil {
  55. zaplog.Error("PushMessage CtxEnqueue", zap.Any("Err", err))
  56. }
  57. }
  58. return nil
  59. }
  60. // ImmunizationPlan 免疫计划,生成工作单
  61. func (e *Entry) ImmunizationPlan() error {
  62. planList := make([]*model.ImmunizationPlan, 0)
  63. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&planList).Error; err != nil {
  64. return xerr.WithStack(err)
  65. }
  66. for _, plan := range planList {
  67. cowList := make([]*model.Cow, 0)
  68. pref := e.DB.Select("id").Where("is_remove = ?", pasturePb.IsShow_Ok).
  69. Where("cow_type = ?", plan.CowType)
  70. switch plan.Conditions {
  71. case pasturePb.ImmunizationConditions_Days_Age:
  72. pref.Where("day_age >= ?", plan.Value).
  73. Where("day_age <= ?", plan.Value2)
  74. case pasturePb.ImmunizationConditions_Days_After_Delivery:
  75. pref.Where("calving_age >= ?", plan.Value).
  76. Where("calving_age <= ?", plan.Value2)
  77. case pasturePb.ImmunizationConditions_Days_Of_Pregnancy:
  78. pref.Where("pregnancy_age >= ?", plan.Value).
  79. Where("pregnancy_age <= ?", plan.Value2).
  80. Where("is_pregnant = ?", pasturePb.IsShow_Ok)
  81. case pasturePb.ImmunizationConditions_Month:
  82. // todo 待实现月份
  83. case pasturePb.ImmunizationConditions_Admission_Days:
  84. pref.Where("admission_age >= ?", plan.Value).
  85. Where("admission_age <= ?", plan.Value2)
  86. }
  87. if err := pref.Find(&cowList).Error; err != nil {
  88. return xerr.WithStack(err)
  89. }
  90. if len(cowList) <= 0 {
  91. continue
  92. }
  93. if err := e.GenerateCalendarByImmunization(cowList, plan); err != nil {
  94. zaplog.Error("crontab", zap.Any("GenerateWorkOrderCalendar", err), zap.Any("cowList", cowList))
  95. }
  96. }
  97. return nil
  98. }
  99. // SameTimePlan 同期计划,生成工作单
  100. func (e *Entry) SameTimePlan() error {
  101. sameTimeList := make([]*model.SameTime, 0)
  102. if err := e.DB.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&sameTimeList).Error; err != nil {
  103. return xerr.WithStack(err)
  104. }
  105. pref := e.DB.Select("id").
  106. Where("is_remove = ?", pasturePb.IsShow_Ok).
  107. Where("is_pregnant = ?", pasturePb.IsShow_No)
  108. for _, plan := range sameTimeList {
  109. cowList := make([]*model.Cow, 0)
  110. pref.Where("calving_age >= ?", plan.PostpartumDaysStart).
  111. Where("calving_age <= ?", plan.PostpartumDaysEnd)
  112. if err := pref.Find(&cowList).Error; err != nil {
  113. zaplog.Error("crontab", zap.Any("SameTimePlan", err), zap.Any("plan", plan))
  114. return xerr.WithStack(err)
  115. }
  116. if len(cowList) <= 0 {
  117. continue
  118. }
  119. if err := e.GenerateCalendarBySameTimePlan(cowList, plan); err != nil {
  120. zaplog.Error("crontab", zap.Any("GenerateCalendarBySameTimePlan", err), zap.Any("cowList", cowList), zap.Any("plan", plan))
  121. continue
  122. }
  123. }
  124. return nil
  125. }
  126. // GenerateCalendarBySameTimePlan 生成同期计划工作单
  127. func (e *Entry) GenerateCalendarBySameTimePlan(cowList []*model.Cow, sameTime *model.SameTime) error {
  128. if len(cowList) <= 0 {
  129. return nil
  130. }
  131. cowSameTimeList := make([]*model.SameTimeCow, 0)
  132. for _, cow := range cowList {
  133. newCowSameTime, err := e.createNewCowSameTime(cow, sameTime)
  134. if err != nil {
  135. zaplog.Error("crontab", zap.Any("GenerateCalendarBySameTimePlan", err), zap.Any("cow", cow))
  136. }
  137. cowSameTimeList = append(cowSameTimeList, newCowSameTime)
  138. }
  139. if len(cowSameTimeList) <= 0 {
  140. return nil
  141. }
  142. workOrderCalendarList := make([]*model.WorkOrderCalendar, 0)
  143. calendarMap := backend.CalendarTypeMap()
  144. workOrderCalendarList = append(workOrderCalendarList,
  145. model.NewWorkOrderCalendar(
  146. calendarMap[pasturePb.CalendarType_Immunisation],
  147. pasturePb.CalendarType_Immunisation,
  148. int32(len(cowSameTimeList)),
  149. ))
  150. if len(sameTime.CollateNodes) > 0 {
  151. for _, collateNode := range sameTime.CollateNodes {
  152. workOrderCalendarList = append(workOrderCalendarList, nil)
  153. // todo 待实现待实现待实现
  154. fmt.Println("==collateNode==", collateNode)
  155. }
  156. }
  157. if err := e.DB.Transaction(func(tx *gorm.DB) error {
  158. // 创建新的牛只同期计划详情
  159. if err := tx.Create(cowSameTimeList).Error; err != nil {
  160. return xerr.WithStack(err)
  161. }
  162. return nil
  163. }); err != nil {
  164. return xerr.WithStack(err)
  165. }
  166. return nil
  167. }
  168. func (e *Entry) createNewCowSameTime(cow *model.Cow, sameTime *model.SameTime) (*model.SameTimeCow, error) {
  169. cowSameTime := &model.SameTimeCow{}
  170. if err := e.DB.Where("cow_id = ?", cow.Id).Where("lact = ?", cow.Lact).First(cowSameTime).Error; err != nil {
  171. if errors.Is(err, gorm.ErrRecordNotFound) {
  172. return &model.SameTimeCow{
  173. CowId: cow.Id,
  174. SameTimeId: sameTime.Id,
  175. Status: pasturePb.IsShow_Ok,
  176. StartAt: time.Now().Unix(),
  177. EndAt: 0,
  178. }, nil
  179. } else {
  180. zaplog.Error("crontab", zap.Error(err), zap.Any("GenerateCalendarBySameTimePlan", "error"), zap.Any("cow", cow.Id), zap.Any("lact", cow.Lact))
  181. return nil, xerr.WithStack(err)
  182. }
  183. }
  184. return cowSameTime, nil
  185. }
  186. func (e *Entry) GenerateCalendarByImmunization(cowList []*model.Cow, plan *model.ImmunizationPlan) error {
  187. workOrderCalendarList := e.getWorkOrderCalendar(plan.Name)
  188. newCowList := make([]*model.Cow, 0)
  189. if len(workOrderCalendarList) > 0 {
  190. // 过滤已经存在的牛只数据,避免重复生成工作单
  191. calendarIds := make([]int64, 0)
  192. if err := e.DB.Model(&model.WorkOrderCalendar{}).Select("id").
  193. Where("name = ?", plan.Name).
  194. Where("is_show = ?", pasturePb.IsShow_Ok).
  195. Order("id DESC").
  196. Limit(100). // todo 默认取100条数据
  197. Find(&calendarIds).Error; err != nil {
  198. return xerr.WithStack(err)
  199. }
  200. workOrderList := make([]*model.WorkOrderList, 0)
  201. if err := e.DB.Where("calendar_id IN ?", calendarIds).
  202. Where("is_show = ?", pasturePb.IsShow_Ok).
  203. Where("is_completion = ?", pasturePb.IsShow_No).
  204. Find(&workOrderList).Error; err != nil {
  205. return xerr.WithStack(err)
  206. }
  207. if len(workOrderList) > 0 {
  208. for _, cow := range cowList {
  209. for _, workOrder := range workOrderList {
  210. if workOrder.CowId == cow.Id {
  211. continue
  212. }
  213. }
  214. newCowList = append(newCowList, cow)
  215. }
  216. }
  217. }
  218. count := len(newCowList)
  219. if err := e.DB.Transaction(func(tx *gorm.DB) error {
  220. calendarTypeMap := backend.CalendarTypeMap()
  221. newWorkOrderCalendar := model.NewWorkOrderCalendar(
  222. calendarTypeMap[pasturePb.CalendarType_Immunisation],
  223. pasturePb.CalendarType_Immunisation,
  224. int32(count),
  225. )
  226. if err := tx.Create(newWorkOrderCalendar).Error; err != nil {
  227. return xerr.WithStack(err)
  228. }
  229. newWorkOrderList := make([]*model.WorkOrderList, 0)
  230. for _, cow := range newCowList {
  231. newWorkOrderList = append(newWorkOrderList, model.NewWorkOrderList(plan.Name, newWorkOrderCalendar.Id, cow.Id))
  232. }
  233. if err := tx.Create(newWorkOrderList).Error; err != nil {
  234. return xerr.WithStack(err)
  235. }
  236. return nil
  237. }); err != nil {
  238. return xerr.WithStack(err)
  239. }
  240. return nil
  241. }
  242. func (e *Entry) getWorkOrderCalendar(name string) []*model.WorkOrderCalendar {
  243. res := make([]*model.WorkOrderCalendar, 0)
  244. if err := e.DB.Where("name = ?", name).
  245. Where("is_show = ?", pasturePb.IsShow_Ok).
  246. Find(&res).Error; err != nil {
  247. zaplog.Error("getWorkOrderCalendar", zap.Any("err", err))
  248. }
  249. return res
  250. }