plat_task_cron.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 := "0 0 20 * * ?" // 每晚8点定时提醒
  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. var handles []*model.PlatTaskHandle
  59. needReceiveMap := make(map[int]int)
  60. err = g.DB(tenant).Model("plat_task").Where("task_status='10' OR task_status='20'").Scan(&tasks)
  61. if err != nil && err != sql.ErrNoRows {
  62. glog.Error(err)
  63. return
  64. }
  65. err = g.DB(tenant).Model("plat_task_handle").Where("task_status='10' AND step='10'").Scan(&handles)
  66. if err != nil && err != sql.ErrNoRows {
  67. glog.Error(err)
  68. return
  69. }
  70. for _, handle := range handles {
  71. needReceiveMap[handle.TaskId] = 1
  72. }
  73. receiveData := make(map[int]string)
  74. feedbackData := make(map[int]string)
  75. beforeOverdueData := make(map[int]string)
  76. afterOverdueData := make(map[int]string)
  77. // 当前时间
  78. now := gtime.Now()
  79. nowStr := gtime.Now().Format("Y-m-d")
  80. // 生成提醒数据
  81. for _, task := range tasks {
  82. // 任务接收提醒
  83. if task.ReceiveDate == nil {
  84. if _, ok := needReceiveMap[task.Id]; ok {
  85. generateData(&receiveData, task.MainUserId, task.OwnerUserId, task.TaskTitle)
  86. }
  87. }
  88. // 定期反馈提醒
  89. // 固定日期提醒
  90. if task.ReminderRule != "" {
  91. rules := strings.Split(task.ReminderRule, " ")
  92. if len(rules) != 5 {
  93. glog.Error(fmt.Sprintf("%v督办Id为%v提醒规则格式不正确", task.TaskTitle, task.Id))
  94. } else {
  95. if rules[3] == "*" { // 每天提醒
  96. generateData(&feedbackData, task.MainUserId, task.OwnerUserId, task.TaskTitle)
  97. } else if rules[3] == "?" { // 每周提醒
  98. // 校验周选项是否匹配
  99. weekDays := strings.Split(rules[4], ",")
  100. isMatch := false
  101. for _, day := range weekDays {
  102. if day == transferWeekday(now.Weekday()) {
  103. isMatch = true
  104. break
  105. }
  106. }
  107. if isMatch {
  108. generateData(&feedbackData, task.MainUserId, task.OwnerUserId, task.TaskTitle)
  109. }
  110. } else { // 每月提醒
  111. monthDays := strings.Split(rules[3], ",")
  112. isMatch := false
  113. for _, day := range monthDays {
  114. if gconv.Int(day) == now.Day() {
  115. isMatch = true
  116. break
  117. }
  118. }
  119. if isMatch {
  120. generateData(&feedbackData, task.MainUserId, task.OwnerUserId, task.TaskTitle)
  121. }
  122. }
  123. }
  124. }
  125. // 超期提醒
  126. if task.TaskEndDate != nil {
  127. // 超期前提醒
  128. beforeDate := task.TaskEndDate.AddDate(0, 0, before)
  129. if beforeDate.Format("Y-m-d") == nowStr {
  130. generateData(&beforeOverdueData, task.MainUserId, task.OwnerUserId, task.TaskTitle)
  131. }
  132. // 超期后提醒
  133. afterDate := task.TaskEndDate.AddDate(0, 0, -after)
  134. if afterDate.Format("Y-m-d") == nowStr {
  135. generateData(&afterOverdueData, task.MainUserId, task.OwnerUserId, task.TaskTitle)
  136. }
  137. }
  138. }
  139. for key, val := range receiveData {
  140. notifyMessage(gconv.String(key), val+"督办未接收,请前往处理")
  141. }
  142. for key, val := range feedbackData {
  143. notifyMessage(gconv.String(key), val+"督办需要处理,请前往处理")
  144. }
  145. for key, val := range beforeOverdueData {
  146. notifyMessage(gconv.String(key), val+"督办即将超期,请前往处理")
  147. }
  148. for key, val := range afterOverdueData {
  149. notifyMessage(gconv.String(key), val+"督办已超期,请确认")
  150. }
  151. }
  152. // 督办人任务的消息通知
  153. func taskNotifyMessage(mainId int, ownerIds, message string) {
  154. // 协作人包含负责人的情况
  155. ids := ownerIds
  156. ownerIdArray := strings.Split(ownerIds, ",")
  157. isCon := false
  158. for _, id := range ownerIdArray {
  159. if id == gconv.String(mainId) {
  160. isCon = true
  161. break
  162. }
  163. }
  164. if !isCon {
  165. if ids == "" {
  166. ids = gconv.String(mainId)
  167. } else {
  168. ids += "," + gconv.String(mainId)
  169. }
  170. }
  171. // 调用统一的消息通知方式
  172. notifyMessage(ids, message)
  173. }
  174. func generateData(data *map[int]string, mainId int, ownerIds, info string) {
  175. isCon := false
  176. ownerIdArray := strings.Split(ownerIds, ",")
  177. for _, id := range ownerIdArray {
  178. if id == gconv.String(mainId) {
  179. isCon = true
  180. break
  181. }
  182. }
  183. if !isCon {
  184. if _, ok := (*data)[mainId]; !ok {
  185. (*data)[mainId] = info
  186. } else {
  187. (*data)[mainId] += "," + info
  188. }
  189. }
  190. for _, id := range ownerIdArray {
  191. if id == "" {
  192. continue
  193. }
  194. if _, ok := (*data)[gconv.Int(id)]; !ok {
  195. (*data)[gconv.Int(id)] = info
  196. } else {
  197. (*data)[gconv.Int(id)] += "," + info
  198. }
  199. }
  200. }
  201. // notifyMessage 发送消息通知
  202. func notifyMessage(ids, message string) {
  203. msg := g.MapStrStr{
  204. "msgTitle": "督办任务提醒",
  205. "msgContent": fmt.Sprintf("%v", message),
  206. "msgType": "20",
  207. "recvUserIds": ids,
  208. "msgStatus": "10",
  209. "sendType": "30",
  210. }
  211. if err := service.CreateSystemMessage(msg); err != nil {
  212. glog.Error("消息提醒异常:", err)
  213. }
  214. }
  215. // 英文周转换为中文周
  216. func transferWeekday(day time.Weekday) string {
  217. switch day {
  218. case time.Monday:
  219. return "1"
  220. case time.Tuesday:
  221. return "2"
  222. case time.Wednesday:
  223. return "3"
  224. case time.Thursday:
  225. return "4"
  226. case time.Friday:
  227. return "5"
  228. case time.Saturday:
  229. return "6"
  230. case time.Sunday:
  231. return "7"
  232. default:
  233. return "-1"
  234. }
  235. }