work.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package backend
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "kpt-pasture/model"
  7. "kpt-pasture/util"
  8. "net/http"
  9. "strings"
  10. "time"
  11. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  12. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  13. "gitee.com/xuyiping_admin/pkg/xerr"
  14. "go.uber.org/zap"
  15. "gorm.io/gorm"
  16. )
  17. func (s *StoreEntry) OrderList(ctx context.Context, req *pasturePb.SearchWorkOrderRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchWorkOrderResponse, error) {
  18. workOrderList := make([]*model.WorkOrderMaster, 0)
  19. var count int64 = 0
  20. pref := s.DB.Model(new(model.WorkOrderMaster))
  21. if req.Name != "" {
  22. pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%"))
  23. }
  24. if req.Frequency > 0 {
  25. pref.Where("frequency = ?", req.Frequency)
  26. }
  27. if req.Priority > 0 {
  28. pref.Where("priority = ?", req.Priority)
  29. }
  30. if req.IsShow > 0 {
  31. pref.Where("is_show = ?", req.IsShow)
  32. }
  33. if req.SubscribeUnit > 0 {
  34. pref.Where("subscribe_unit = ?", req.SubscribeUnit)
  35. }
  36. if req.CategoryId > 0 {
  37. pref.Where("category_id = ?", req.CategoryId)
  38. }
  39. if err := pref.Order("id desc").Count(&count).Limit(int(pagination.PageSize)).Offset(int(pagination.PageOffset)).
  40. Find(&workOrderList).Error; err != nil {
  41. return nil, xerr.WithStack(err)
  42. }
  43. priorityMap := s.WorkOrderPriorityMap()
  44. frequencyMap := s.WorkOrderFrequencyMap()
  45. subscribeUnitMap := s.WorkOrderSubUnitMap()
  46. weekMap := s.WeekMap()
  47. monthMap := s.MonthMap()
  48. return &pasturePb.SearchWorkOrderResponse{
  49. Code: http.StatusOK,
  50. Message: "ok",
  51. Data: &pasturePb.SearchWorkOrderData{
  52. List: model.WorkOrderMasterSlice(workOrderList).ToPB(priorityMap, frequencyMap, subscribeUnitMap, weekMap, monthMap),
  53. Total: int32(count),
  54. PageSize: pagination.PageSize,
  55. Page: pagination.Page,
  56. },
  57. }, nil
  58. }
  59. // OrderCreateOrUpdate 创建和更新工单
  60. // 周期性工单【包括每天,每周,每月】一次性生成符合本月日期所有工单
  61. // 更新工单的时候需要重新维护子工单
  62. func (s *StoreEntry) OrderCreateOrUpdate(ctx context.Context, req *pasturePb.WorkOrderList) error {
  63. currentUser, _ := s.GetCurrentSystemUser(ctx)
  64. workOrderCategoryMap := s.WorkOrderCategoryMap()
  65. systemUserList, _ := s.SystemUserList(ctx)
  66. newWorkOrderMaster := model.NewWorkOrderMaster(req, currentUser, systemUserList, workOrderCategoryMap)
  67. if req.Id <= 0 {
  68. if err := s.DB.Transaction(func(tx *gorm.DB) error {
  69. if err := tx.Create(newWorkOrderMaster).Error; err != nil {
  70. return xerr.WithStack(err)
  71. }
  72. newWorkOrderSubList := model.NewWorkOrderSub(newWorkOrderMaster)
  73. if len(newWorkOrderSubList) > 0 {
  74. if err := tx.Create(&newWorkOrderSubList).Error; err != nil {
  75. return xerr.WithStack(err)
  76. }
  77. }
  78. return nil
  79. }); err != nil {
  80. return xerr.WithStack(err)
  81. }
  82. } else {
  83. if err := s.DB.Transaction(func(tx *gorm.DB) error {
  84. if err := tx.Model(newWorkOrderMaster).Where("id = ?", req.Id).Updates(newWorkOrderMaster).Error; err != nil {
  85. return xerr.WithStack(err)
  86. }
  87. if err := s.WorkOrderSubUpdate(tx, newWorkOrderMaster); err != nil {
  88. return xerr.WithStack(err)
  89. }
  90. return nil
  91. }); err != nil {
  92. return xerr.WithStack(err)
  93. }
  94. }
  95. return nil
  96. }
  97. // OrderIsShow 工单的开启和关闭
  98. func (s *StoreEntry) OrderIsShow(ctx context.Context, id int64) error {
  99. workOrderMaster := &model.WorkOrderMaster{Id: id}
  100. if err := s.DB.First(workOrderMaster).Error; err != nil {
  101. if errors.Is(err, gorm.ErrRecordNotFound) {
  102. return xerr.Custom("该工单不存在")
  103. }
  104. return xerr.WithStack(err)
  105. }
  106. isShow := pasturePb.IsShow_No
  107. if workOrderMaster.IsShow == pasturePb.IsShow_No {
  108. isShow = pasturePb.IsShow_Ok
  109. }
  110. if err := s.DB.Transaction(func(tx *gorm.DB) error {
  111. if err := tx.Model(workOrderMaster).Where("id = ?", id).Update("is_show", isShow).Error; err != nil {
  112. return xerr.WithStack(err)
  113. }
  114. workOrderMaster.IsShow = isShow
  115. if err := s.WorkOrderSubUpdate(tx, workOrderMaster); err != nil {
  116. return xerr.WithStack(err)
  117. }
  118. return nil
  119. }); err != nil {
  120. return xerr.WithStack(err)
  121. }
  122. return nil
  123. }
  124. // WorkOrderSubUpdate 子工单重新维护
  125. // 如果工单是开启状态,则重新生成子工单,如果工单是关闭状态,则取消子工单
  126. func (s *StoreEntry) WorkOrderSubUpdate(tx *gorm.DB, workOrderMaster *model.WorkOrderMaster) error {
  127. if workOrderMaster.IsShow == pasturePb.IsShow_Ok {
  128. newWorkOrderSubList := model.NewWorkOrderSub(workOrderMaster)
  129. if err := tx.Create(&newWorkOrderSubList).Error; err != nil {
  130. return xerr.WithStack(err)
  131. }
  132. } else {
  133. // 获取当天的零点时间
  134. zeroTime := util.TimeParseLocalUnix(time.Now().Format("2006-01-02"))
  135. // 先检查是否存在符合条件的记录
  136. var count int64
  137. if err := tx.Model(&model.WorkOrderSub{}).
  138. Where("work_order_master_id = ?", workOrderMaster.Id).
  139. Where("is_show = ?", pasturePb.IsShow_Ok).
  140. Where("exec_time > ?", zeroTime).
  141. Where("status = ?", pasturePb.WorkOrderStatus_Distribute).
  142. Count(&count).Error; err != nil {
  143. return xerr.WithStack(err)
  144. }
  145. if count <= 0 {
  146. return nil
  147. }
  148. if err := tx.Model(new(model.WorkOrderSub)).
  149. Where("work_order_master_id = ?", workOrderMaster.Id).
  150. Where("is_show = ?", pasturePb.IsShow_Ok).
  151. Where("exec_time > ?", zeroTime).
  152. Where("status = ?", pasturePb.WorkOrderStatus_Distribute).
  153. Update("status", pasturePb.WorkOrderStatus_Canceled).Error; err != nil {
  154. return xerr.WithStack(err)
  155. }
  156. }
  157. return nil
  158. }
  159. func (s *StoreEntry) SendAsynqWorkOrder(ctx context.Context, workOrder *model.WorkOrderMaster) {
  160. if workOrder.IsShow == pasturePb.IsShow_No {
  161. return
  162. }
  163. timeUnix, _ := util.ConvertParseLocalUnix(workOrder.ExecTime)
  164. nowTime := time.Now()
  165. // 过滤掉10秒内要执行的任务
  166. if timeUnix <= nowTime.Unix()+10 {
  167. return
  168. }
  169. // 判断是否是周任务,并且当前周不在执行周期内,则不执行任务
  170. if workOrder.WeekMonthValue != "" {
  171. execWeekMonth := strings.Split(workOrder.WeekMonthValue, ",")
  172. currentWeekMonth := ""
  173. if workOrder.Frequency == pasturePb.WorkOrderFrequency_Weekly {
  174. currentWeekMonth = fmt.Sprintf("%d", nowTime.Weekday())
  175. }
  176. if workOrder.Frequency == pasturePb.WorkOrderFrequency_Monthly {
  177. currentWeekMonth = fmt.Sprintf("%d", nowTime.Day())
  178. }
  179. var info bool
  180. for _, weekMonth := range execWeekMonth {
  181. if currentWeekMonth == weekMonth {
  182. info = true
  183. break
  184. }
  185. }
  186. // 如果有,则不执行任务
  187. if info {
  188. return
  189. }
  190. }
  191. execTime := time.Now().Unix() - timeUnix
  192. if _, err := s.AsynqClient.CtxEnqueue(ctx, model.NewTaskWorkOrderPayload(workOrder.Id, time.Duration(execTime)*time.Second)); err != nil {
  193. zaplog.Error("PushMessage CtxEnqueue", zap.Any("Err", err))
  194. }
  195. }
  196. // UserWorkOrderList 用户工单列表
  197. func (s *StoreEntry) UserWorkOrderList(ctx context.Context, userId int64) error {
  198. // todo: 待完善
  199. return nil
  200. }