plat_task_cron.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package plat
  2. import (
  3. model "dashoo.cn/micro/app/model/plat"
  4. "dashoo.cn/micro/app/service"
  5. "database/sql"
  6. "fmt"
  7. "github.com/gogf/gf/frame/g"
  8. "github.com/gogf/gf/os/glog"
  9. "github.com/gogf/gf/os/gtime"
  10. "github.com/gogf/gf/util/gconv"
  11. "github.com/robfig/cron"
  12. "strings"
  13. "time"
  14. )
  15. // 初始化,创建每10分钟执行一次的定时任务
  16. func init() {
  17. // 定时任务
  18. c := cron.New()
  19. spec := "1 0/10 * * * ?" // 每天10分钟执行一次
  20. if err := c.AddJob(spec, taskCron{}); err != nil {
  21. glog.Error(err)
  22. }
  23. c.Start()
  24. }
  25. // 督办任务定时任务定义
  26. type taskCron struct {
  27. }
  28. // Run 督办定时任务逻辑
  29. func (c taskCron) Run() {
  30. tenant := g.Config().GetString("micro_srv.tenant")
  31. if tenant == "" {
  32. glog.Error("督办定时任务租户码未设置,请前往配置")
  33. return
  34. }
  35. // 从配置中获取消息提醒设置
  36. configs, err := g.DB(tenant).Model("sys_config").Where("config_key IN ('TaskOverdueBefore','TaskOverdueAfter')").FindAll()
  37. if err != nil && err != sql.ErrNoRows {
  38. glog.Error(err)
  39. return
  40. }
  41. before := -1
  42. after := -1
  43. // 获取
  44. for _, config := range configs {
  45. if config["config_key"].String() == "TaskOverdueBefore" {
  46. before = gconv.Int(config["config_value"].String())
  47. } else if config["config_key"].String() == "TaskOverdueAfter" {
  48. after = gconv.Int(config["config_value"].String())
  49. }
  50. }
  51. // 校验
  52. if before == -1 || after == -1 {
  53. glog.Error("督办定时任务超期提醒参数未配置,请前往配置")
  54. return
  55. }
  56. // 查询数据,启用定时任务
  57. var tasks []*model.PlatTask
  58. err = g.DB(tenant).Model("plat_task").Where("task_status='10' OR task_status='20'").Scan(&tasks)
  59. if err != nil && err != sql.ErrNoRows {
  60. glog.Error(err)
  61. return
  62. }
  63. // 当前时间
  64. now := gtime.Now()
  65. // 生成提醒数据
  66. for _, task := range tasks {
  67. TaskTitle := task.TaskTitle + "(须接受督办)"
  68. if task.IsOverdue == "20" {
  69. TaskTitle = task.TaskTitle + "(超期)"
  70. }
  71. // 固定日期提醒
  72. if task.ReminderRule != "" {
  73. rules := strings.Split(task.ReminderRule, " ")
  74. if len(rules) != 5 {
  75. glog.Error(fmt.Sprintf("%v督办Id为%v提醒规则格式不正确", task.TaskTitle, task.Id))
  76. } else {
  77. if rules[3] == "*" { // 每天提醒
  78. // 校验当前时间
  79. remindTime := gtime.NewFromStr(fmt.Sprintf("%v %v:%v:%v", now.Format("Y-m-d"), rules[2], rules[1], rules[0]))
  80. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  81. if (now.Nanosecond()-remindTime.Nanosecond())/(1*60*1e9) <= 10 && now.Nanosecond() > remindTime.Nanosecond() {
  82. taskNotifyMessage(task.MainUserId, task.OwnerUserId, TaskTitle+"督办需要处理,请前往执行")
  83. }
  84. } else if rules[3] == "?" { // 每周提醒
  85. // 校验周选项是否匹配
  86. weekDays := strings.Split(rules[4], ",")
  87. isMatch := false
  88. for _, day := range weekDays {
  89. if day == transferWeekday(now.Weekday()) {
  90. isMatch = true
  91. break
  92. }
  93. }
  94. if isMatch {
  95. // 校验当前时间
  96. remindTime := gtime.NewFromStr(fmt.Sprintf("%v %v:%v:%v", now.Format("Y-m-d"), rules[2], rules[1], rules[0]))
  97. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  98. if (now.Nanosecond()-remindTime.Nanosecond())/(1*60*1e9) <= 10 && now.Nanosecond() > remindTime.Nanosecond() {
  99. taskNotifyMessage(task.MainUserId, task.OwnerUserId, TaskTitle+"督办需要处理,请前往执行")
  100. }
  101. }
  102. } else { // 每月提醒
  103. monthDays := strings.Split(rules[3], ",")
  104. isMatch := false
  105. for _, day := range monthDays {
  106. if gconv.Int(day) == now.Day() {
  107. isMatch = true
  108. break
  109. }
  110. }
  111. if isMatch {
  112. // 校验当前时间
  113. remindTime := gtime.NewFromStr(fmt.Sprintf("%v %v:%v:%v", now.Format("Y-m-d"), rules[2], rules[1], rules[0]))
  114. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  115. if (now.Nanosecond()-remindTime.Nanosecond())/(1*60*1e9) <= 10 && now.Nanosecond() > remindTime.Nanosecond() {
  116. taskNotifyMessage(task.MainUserId, task.OwnerUserId, TaskTitle+"督办需要处理,请前往执行")
  117. }
  118. }
  119. }
  120. }
  121. }
  122. // 超期提醒,差10分(定时任务每10分钟执行一次)一天之时进行提醒
  123. if task.TaskEndDate != nil {
  124. // 超期前提醒
  125. beforeDate := task.TaskEndDate.AddDate(0, 0, before)
  126. if beforeDate.After(now) {
  127. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  128. if (beforeDate.UnixNano()-now.UnixNano())/(1*60*1e9) <= 10 {
  129. taskNotifyMessage(task.MainUserId, task.OwnerUserId, TaskTitle+"督办即将超期,请前往执行")
  130. }
  131. }
  132. // 超期后提醒
  133. afterDate := task.TaskEndDate.AddDate(0, 0, -after)
  134. if now.After(afterDate) {
  135. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  136. if (now.UnixNano()-afterDate.UnixNano())/(1*60*1e9) <= 10 {
  137. taskNotifyMessage(task.MainUserId, task.OwnerUserId, TaskTitle+"督办已超期,请确认")
  138. }
  139. }
  140. }
  141. }
  142. }
  143. // 督办人任务的消息通知
  144. func taskNotifyMessage(mainId int, ownerIds, message string) {
  145. // 协作人包含负责人的情况
  146. ids := ownerIds
  147. ownerIdArray := strings.Split(ownerIds, ",")
  148. isCon := false
  149. for _, id := range ownerIdArray {
  150. if id == gconv.String(mainId) {
  151. isCon = true
  152. break
  153. }
  154. }
  155. if !isCon {
  156. if ids == "" {
  157. ids = gconv.String(mainId)
  158. } else {
  159. ids += "," + gconv.String(mainId)
  160. }
  161. }
  162. // 调用统一的消息通知方式
  163. notifyMessage(ids, message)
  164. }
  165. // notifyMessage 发送消息通知
  166. func notifyMessage(ids, message string) {
  167. msg := g.MapStrStr{
  168. "msgTitle": "督办任务提醒",
  169. "msgContent": fmt.Sprintf("<p>%v</p>", message),
  170. "msgType": "20",
  171. "recvUserIds": ids,
  172. "msgStatus": "10",
  173. "sendType": "10",
  174. }
  175. if err := service.CreateSystemMessage(msg); err != nil {
  176. glog.Error("消息提醒异常:", err)
  177. }
  178. }
  179. // 英文周转换为中文周
  180. func transferWeekday(day time.Weekday) string {
  181. switch day {
  182. case time.Monday:
  183. return "1"
  184. case time.Tuesday:
  185. return "2"
  186. case time.Wednesday:
  187. return "3"
  188. case time.Thursday:
  189. return "4"
  190. case time.Friday:
  191. return "5"
  192. case time.Saturday:
  193. return "6"
  194. case time.Sunday:
  195. return "7"
  196. default:
  197. return "-1"
  198. }
  199. }