tasks.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. package http
  2. import (
  3. "context"
  4. "encoding/json"
  5. "strconv"
  6. "strings"
  7. "time"
  8. "go-common/app/admin/main/push/model"
  9. pushmdl "go-common/app/service/main/push/model"
  10. "go-common/library/ecode"
  11. "go-common/library/log"
  12. bm "go-common/library/net/http/blademaster"
  13. xtime "go-common/library/time"
  14. )
  15. func taskList(c *bm.Context) {
  16. var (
  17. items []*model.Task
  18. types []int
  19. err error
  20. pager = new(model.Pager)
  21. )
  22. params := new(struct {
  23. Type string `form:"type"`
  24. Stime string `form:"stime"`
  25. Etime string `form:"etime"`
  26. })
  27. if err = c.Bind(params); err != nil {
  28. return
  29. }
  30. if err = c.Bind(pager); err != nil {
  31. return
  32. }
  33. for _, v := range strings.Split(params.Type, ",") {
  34. i, e := strconv.Atoi(v)
  35. if e != nil {
  36. continue
  37. }
  38. types = append(types, i)
  39. }
  40. if params.Stime == "" {
  41. params.Stime = time.Now().Add(-1 * time.Hour).Format("2006-01-02 15:04:05")
  42. }
  43. if params.Etime == "" {
  44. params.Etime = time.Now().Format("2006-01-02 15:04:05")
  45. }
  46. if err = pushSrv.DB.Model(&model.Task{}).Where("push_time between ? and ?", params.Stime, params.Etime).Where("type in(?)", types).Order("push_time desc").Find(&items).Error; err != nil {
  47. log.Error("taskList(%d,%s,%s) error(%v)", params.Type, params.Stime, params.Etime, err)
  48. c.JSON(nil, err)
  49. return
  50. }
  51. res := fmtTasks(items)
  52. total := len(res)
  53. data := map[string]interface{}{
  54. "pager": &model.Pager{
  55. Pn: pager.Pn,
  56. Ps: pager.Ps,
  57. Total: total,
  58. },
  59. "data": []*model.Task{},
  60. }
  61. start := pager.Ps * (pager.Pn - 1)
  62. if start >= total {
  63. c.JSONMap(data, nil)
  64. return
  65. }
  66. end := start + pager.Ps
  67. if len(res[start:]) < pager.Ps {
  68. end = start + len(res[start:])
  69. }
  70. data["data"] = res[start:end]
  71. c.JSONMap(data, nil)
  72. }
  73. func fmtTasks(items []*model.Task) (res []*model.Task) {
  74. var jobs []string
  75. tasks := make(map[string]*pushmdl.Task)
  76. for _, t := range items {
  77. p := &pushmdl.Progress{}
  78. if t.Progress != "" {
  79. if err := json.Unmarshal([]byte(t.Progress), &p); err != nil {
  80. log.Error("unmarshal task(%d) progress(%s) error(%v)", t.ID, t.Progress, err)
  81. continue
  82. }
  83. }
  84. extra := new(pushmdl.TaskExtra)
  85. if t.Extra != "" {
  86. if err := json.Unmarshal([]byte(t.Extra), &extra); err != nil {
  87. log.Error("unmarshal task(%d) extra(%s) error(%v)", t.ID, t.Extra, err)
  88. continue
  89. }
  90. }
  91. if v, ok := tasks[t.Job]; !ok {
  92. job, _ := strconv.ParseInt(t.Job, 10, 64)
  93. tasks[t.Job] = &pushmdl.Task{
  94. ID: t.ID,
  95. Job: job,
  96. Type: t.Type,
  97. APPID: t.AppID,
  98. BusinessID: t.BusinessID,
  99. Title: t.Title,
  100. Summary: t.Summary,
  101. LinkType: int8(t.LinkType),
  102. LinkValue: t.LinkValue,
  103. Progress: p,
  104. PushTime: xtime.Time(t.PushTime.Unix()),
  105. ExpireTime: xtime.Time(t.ExpireTime.Unix()),
  106. Status: int8(t.Status),
  107. Extra: extra,
  108. }
  109. jobs = append(jobs, t.Job)
  110. } else {
  111. v.Status = calStatus(v.Status, int8(t.Status))
  112. vp := v.Progress
  113. vp.MidTotal += p.MidTotal
  114. vp.MidValid += p.MidValid
  115. vp.TokenTotal += p.TokenTotal
  116. vp.TokenValid += p.TokenValid
  117. vp.TokenFailed += p.TokenFailed
  118. }
  119. }
  120. for _, j := range jobs {
  121. v := tasks[j]
  122. p, _ := json.Marshal(v.Progress)
  123. e, _ := json.Marshal(v.Extra)
  124. t := &model.Task{
  125. ID: v.ID,
  126. Job: strconv.FormatInt(v.Job, 10),
  127. Type: v.Type,
  128. AppID: v.APPID,
  129. BusinessID: v.BusinessID,
  130. Title: v.Title,
  131. Summary: v.Summary,
  132. LinkType: int(v.LinkType),
  133. LinkValue: v.LinkValue,
  134. Progress: string(p),
  135. PushTimeUnix: int64(v.PushTime),
  136. ExpireTimeUnix: int64(v.ExpireTime),
  137. Status: int(v.Status),
  138. Extra: string(e),
  139. }
  140. res = append(res, t)
  141. }
  142. return
  143. }
  144. func calStatus(currStatus, newStatus int8) int8 {
  145. // 聚合任务状态
  146. // 如果有进行中的任务,显示进行中
  147. // 如果没有,显示其中最小的状态(负数是异常状态)
  148. if currStatus == pushmdl.TaskStatusDoing || newStatus == pushmdl.TaskStatusDoing {
  149. return pushmdl.TaskStatusDoing
  150. }
  151. if newStatus == pushmdl.TaskStatusPrepared {
  152. return pushmdl.TaskStatusPrepared
  153. }
  154. if newStatus < currStatus {
  155. return newStatus
  156. }
  157. return currStatus
  158. }
  159. func addTask(c *bm.Context) {
  160. var (
  161. task = &model.Task{}
  162. filename = c.Request.Form.Get("filename")
  163. )
  164. if err := c.Bind(task); err != nil {
  165. return
  166. }
  167. task.PushTime = time.Unix(task.PushTimeUnix, 0)
  168. task.ExpireTime = time.Unix(task.ExpireTimeUnix, 0)
  169. job := pushmdl.JobName(time.Now().UnixNano(), task.Summary, task.LinkValue, task.Group)
  170. task.Job = strconv.FormatInt(job, 10)
  171. extra, _ := json.Marshal(pushmdl.TaskExtra{
  172. Group: task.Group,
  173. Filename: filename,
  174. })
  175. task.Extra = string(extra)
  176. task.Status = int(pushmdl.TaskStatusPending)
  177. c.JSON(nil, pushSrv.AddTask(context.Background(), task))
  178. }
  179. func taskInfo(c *bm.Context) {
  180. task := &model.Task{}
  181. id, _ := strconv.ParseInt(c.Request.Form.Get("id"), 10, 64)
  182. if id == 0 {
  183. c.JSON(nil, ecode.RequestErr)
  184. return
  185. }
  186. if err := pushSrv.DB.First(task, id).Error; err != nil {
  187. log.Error("taskInfo(%d) error(%v)", id, err)
  188. c.JSON(nil, err)
  189. return
  190. }
  191. task.PushTimeUnix = task.PushTime.Unix()
  192. task.ExpireTimeUnix = task.ExpireTime.Unix()
  193. c.JSON(task, nil)
  194. }
  195. func saveTask(c *bm.Context) {
  196. var (
  197. task = new(model.Task)
  198. filename = c.Request.Form.Get("filename")
  199. )
  200. if err := c.Bind(task); err != nil {
  201. return
  202. }
  203. if task.Job == "" {
  204. log.Warn("job is empty")
  205. c.JSON(nil, ecode.RequestErr)
  206. return
  207. }
  208. extra, _ := json.Marshal(pushmdl.TaskExtra{
  209. Group: task.Group,
  210. Filename: filename,
  211. })
  212. data := map[string]interface{}{
  213. "app_id": task.AppID,
  214. "type": task.Type,
  215. "business_id": task.BusinessID,
  216. "title": task.Title,
  217. "summary": task.Summary,
  218. "link_type": task.LinkType,
  219. "link_value": task.LinkValue,
  220. "build": task.Build,
  221. "sound": task.Sound,
  222. "vibration": task.LinkValue,
  223. "push_time": time.Unix(task.PushTimeUnix, 0),
  224. "expire_time": time.Unix(task.ExpireTimeUnix, 0),
  225. "group": task.Group,
  226. "image_url": task.ImageURL,
  227. "extra": string(extra),
  228. }
  229. if err := pushSrv.DB.Model(&model.Task{}).Where("job=?", task.Job).Updates(data).Error; err != nil {
  230. log.Error("saveTask(%+v) error(%v)", data, err)
  231. c.JSON(nil, err)
  232. return
  233. }
  234. c.JSON(nil, nil)
  235. }
  236. func delTask(c *bm.Context) {
  237. job := c.Request.Form.Get("job")
  238. if job == "" {
  239. log.Error("job is empty")
  240. c.JSON(nil, ecode.RequestErr)
  241. return
  242. }
  243. if err := pushSrv.DB.Model(&model.Task{}).Where("job=?", job).Update("dtime", time.Now().Unix()).Error; err != nil {
  244. log.Error("delTask(%s) error(%v)", job, err)
  245. c.JSON(nil, err)
  246. return
  247. }
  248. c.JSON(nil, nil)
  249. }
  250. func stopTask(c *bm.Context) {
  251. job := c.Request.Form.Get("job")
  252. if job == "" {
  253. log.Error("job is empty")
  254. c.JSON(nil, ecode.RequestErr)
  255. return
  256. }
  257. if err := pushSrv.DB.Model(&model.Task{}).Where("job=?", job).Update("status", pushmdl.TaskStatusStop).Error; err != nil {
  258. log.Error("stopTask(%s) error(%v)", job, err)
  259. c.JSON(nil, err)
  260. return
  261. }
  262. c.JSON(nil, nil)
  263. }
  264. func confirmTask(c *bm.Context) {
  265. job := c.Request.Form.Get("job")
  266. if job == "" {
  267. log.Error("job is empty")
  268. c.JSON(nil, ecode.RequestErr)
  269. return
  270. }
  271. task := &model.Task{}
  272. if err := pushSrv.DB.Model(&model.Task{}).Where("job=?", job).First(task).Error; err != nil {
  273. log.Error("confirmTask(%s) query task error(%v)", job, err)
  274. c.JSON(nil, err)
  275. return
  276. }
  277. status := pushmdl.TaskStatusPretreatmentPrepared
  278. if task.Type == pushmdl.TaskTypeDataPlatformMid || task.Type == pushmdl.TaskTypeDataPlatformToken {
  279. status = pushmdl.TaskStatusWaitDataPlatform
  280. if err := pushSrv.UpdateDpCondtionStatus(c, job, pushmdl.DpCondStatusPrepared); err != nil {
  281. log.Error("confirmTask(%s) update data platform conditions error(%v)", job, err)
  282. return
  283. }
  284. }
  285. if err := pushSrv.DB.Model(&model.Task{}).Where("job=?", job).Update("status", status).Error; err != nil {
  286. log.Error("confirmTask(%s) error(%v)", job, err)
  287. c.JSON(nil, err)
  288. return
  289. }
  290. c.JSON(nil, nil)
  291. }
  292. func testPushMid(c *bm.Context) {
  293. task := &model.Task{}
  294. if err := c.Bind(task); err != nil {
  295. return
  296. }
  297. builds := make(map[int]*pushmdl.Build)
  298. if task.Build != "" {
  299. if err := json.Unmarshal([]byte(task.Build), &builds); err != nil {
  300. c.JSON(nil, ecode.RequestErr)
  301. log.Warn("buildformat task(%+v) error(%v)", task, err)
  302. return
  303. }
  304. }
  305. var (
  306. plats []string
  307. mid = c.Request.Form.Get("mid")
  308. )
  309. for plat := range builds {
  310. plats = append(plats, strconv.Itoa(plat))
  311. }
  312. task.Platform = strings.Join(plats, ",")
  313. task.PushTime = time.Unix(task.PushTimeUnix, 0)
  314. task.ExpireTime = time.Unix(task.ExpireTimeUnix, 0)
  315. job := pushmdl.JobName(time.Now().UnixNano(), task.Summary, task.LinkValue, task.Group)
  316. task.Job = strconv.FormatInt(job, 10)
  317. extra, _ := json.Marshal(pushmdl.TaskExtra{Group: task.Group})
  318. task.Extra = string(extra)
  319. c.JSON(nil, pushSrv.TestPushMid(c, mid, task))
  320. }
  321. func testPushToken(c *bm.Context) {
  322. params := c.Request.Form
  323. appID, _ := strconv.ParseInt(params.Get("app_id"), 10, 64)
  324. if appID < 1 {
  325. c.JSON(nil, ecode.RequestErr)
  326. log.Error("app_id is wrong: %s", params.Get("app_id"))
  327. return
  328. }
  329. platform, _ := strconv.Atoi(params.Get("platform"))
  330. if platform < 1 {
  331. c.JSON(nil, ecode.RequestErr)
  332. log.Error("platform is wrong: %s", params.Get("platform"))
  333. return
  334. }
  335. alertTitle := params.Get("alert_title")
  336. if alertTitle == "" {
  337. alertTitle = pushmdl.DefaultMessageTitle
  338. }
  339. alertBody := params.Get("alert_body")
  340. if alertBody == "" {
  341. c.JSON(nil, ecode.RequestErr)
  342. log.Error("alert_body is empty")
  343. return
  344. }
  345. token := params.Get("token")
  346. if token == "" {
  347. c.JSON(nil, ecode.RequestErr)
  348. log.Error("token is empty")
  349. return
  350. }
  351. linkType, _ := strconv.Atoi(params.Get("link_type"))
  352. if linkType < 1 {
  353. c.JSON(nil, ecode.RequestErr)
  354. log.Error("link_type is wrong: %s", params.Get("link_type"))
  355. return
  356. }
  357. linkValue := params.Get("link_value")
  358. expireTime, _ := strconv.ParseInt(params.Get("expire_time"), 10, 64)
  359. if expireTime == 0 {
  360. expireTime = time.Now().Add(7 * 24 * time.Hour).Unix()
  361. }
  362. sound, vibration := pushmdl.SwitchOn, pushmdl.SwitchOn
  363. if params.Get("sound") != "" {
  364. if sd, _ := strconv.Atoi(params.Get("sound")); sd == pushmdl.SwitchOff {
  365. sound = pushmdl.SwitchOff
  366. }
  367. }
  368. if params.Get("vibration") != "" {
  369. if vr, _ := strconv.Atoi(params.Get("vibration")); vr == pushmdl.SwitchOff {
  370. vibration = pushmdl.SwitchOff
  371. }
  372. }
  373. passThrough, _ := strconv.Atoi(params.Get("pass_through"))
  374. if passThrough != pushmdl.SwitchOn {
  375. passThrough = pushmdl.SwitchOff
  376. }
  377. info := &pushmdl.PushInfo{
  378. TaskID: pushmdl.TempTaskID(),
  379. APPID: appID,
  380. Title: alertTitle,
  381. Summary: alertBody,
  382. LinkType: int8(linkType),
  383. LinkValue: linkValue,
  384. ExpireTime: xtime.Time(expireTime),
  385. PassThrough: passThrough,
  386. Sound: sound,
  387. Vibration: vibration,
  388. }
  389. c.JSON(nil, pushSrv.TestPushToken(c, info, platform, token))
  390. }