plat_task_cron.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. // 固定日期提醒
  68. if task.ReminderRule != "" {
  69. rules := strings.Split(task.ReminderRule, " ")
  70. if len(rules) != 5 {
  71. glog.Error(fmt.Sprintf("%v督办Id为%v提醒规则格式不正确", task.TaskTitle, task.Id))
  72. } else {
  73. if rules[3] == "*" { // 每天提醒
  74. // 校验当前时间
  75. remindTime := gtime.NewFromStr(fmt.Sprintf("%v %v:%v:%v", now.Format("Y-m-d"), rules[2], rules[1], rules[0]))
  76. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  77. if (remindTime.Nanosecond()-now.Nanosecond())/(1*60*1e9) <= 10 {
  78. taskNotifyMessage(task.MainUserId, task.OwnerUserId, task.TaskTitle+"督办需要处理,请前往执行")
  79. }
  80. } else if rules[3] == "?" { // 每周提醒
  81. // 校验周选项是否匹配
  82. weekDays := strings.Split(rules[4], ",")
  83. isMatch := false
  84. for _, day := range weekDays {
  85. if day == transferWeekday(now.Weekday()) {
  86. isMatch = true
  87. break
  88. }
  89. }
  90. if isMatch {
  91. // 校验当前时间
  92. remindTime := gtime.NewFromStr(fmt.Sprintf("%v %v:%v:%v", now.Format("Y-m-d"), rules[2], rules[1], rules[0]))
  93. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  94. if (remindTime.Nanosecond()-now.Nanosecond())/(1*60*1e9) <= 10 {
  95. taskNotifyMessage(task.MainUserId, task.OwnerUserId, task.TaskTitle+"督办需要处理,请前往执行")
  96. }
  97. }
  98. } else { // 每月提醒
  99. monthDays := strings.Split(rules[3], ",")
  100. isMatch := false
  101. for _, day := range monthDays {
  102. if gconv.Int(day) == now.Day() {
  103. isMatch = true
  104. break
  105. }
  106. }
  107. if isMatch {
  108. // 校验当前时间
  109. remindTime := gtime.NewFromStr(fmt.Sprintf("%v %v:%v:%v", now.Format("Y-m-d"), rules[2], rules[1], rules[0]))
  110. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  111. if (remindTime.Nanosecond()-now.Nanosecond())/(1*60*1e9) <= 10 {
  112. taskNotifyMessage(task.MainUserId, task.OwnerUserId, task.TaskTitle+"督办需要处理,请前往执行")
  113. }
  114. }
  115. }
  116. }
  117. }
  118. // 超期提醒,差10分(定时任务每10分钟执行一次)一天之时进行提醒
  119. if task.TaskEndDate != nil {
  120. // 超期前提醒
  121. beforeDate := task.TaskEndDate.AddDate(0, 0, before)
  122. if beforeDate.After(now) {
  123. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  124. if (beforeDate.UnixNano()-now.UnixNano())/(1*60*1e9) <= 10 {
  125. taskNotifyMessage(task.MainUserId, task.OwnerUserId, task.TaskTitle+"督办即将超期,请前往执行")
  126. }
  127. }
  128. // 超期后提醒
  129. afterDate := task.TaskEndDate.AddDate(0, 0, -after)
  130. if now.After(afterDate) {
  131. // 10分钟一次定时循环,两者相差在10分钟之内(纳秒转换1e9)
  132. if (now.UnixNano()-afterDate.UnixNano())/(1*60*1e9) <= 10 {
  133. taskNotifyMessage(task.MainUserId, task.OwnerUserId, task.TaskTitle+"督办已超期,请确认")
  134. }
  135. }
  136. }
  137. }
  138. }
  139. // 督办人任务的消息通知
  140. func taskNotifyMessage(mainId int, ownerIds, message string) {
  141. // 协作人包含负责人的情况
  142. ids := ownerIds
  143. ownerIdArray := strings.Split(ownerIds, ",")
  144. isCon := false
  145. for _, id := range ownerIdArray {
  146. if id == gconv.String(mainId) {
  147. isCon = true
  148. break
  149. }
  150. }
  151. if !isCon {
  152. if ids == "" {
  153. ids = gconv.String(mainId)
  154. } else {
  155. ids += "," + gconv.String(mainId)
  156. }
  157. }
  158. // 调用统一的消息通知方式
  159. notifyMessage(ids, message)
  160. }
  161. // notifyMessage 发送消息通知
  162. func notifyMessage(ids, message string) {
  163. msg := g.MapStrStr{
  164. "msgTitle": "督办任务提醒",
  165. "msgContent": fmt.Sprintf("<p>%v</p>", message),
  166. "msgType": "20",
  167. "recvUserIds": ids,
  168. "msgStatus": "10",
  169. "sendType": "10",
  170. }
  171. if err := service.CreateSystemMessage(msg); err != nil {
  172. glog.Error("消息提醒异常:", err)
  173. }
  174. }
  175. // 英文周转换为中文周
  176. func transferWeekday(day time.Weekday) string {
  177. switch day {
  178. case time.Monday:
  179. return "1"
  180. case time.Tuesday:
  181. return "2"
  182. case time.Wednesday:
  183. return "3"
  184. case time.Thursday:
  185. return "4"
  186. case time.Friday:
  187. return "5"
  188. case time.Saturday:
  189. return "6"
  190. case time.Sunday:
  191. return "7"
  192. default:
  193. return "-1"
  194. }
  195. }