StartAutoLepao.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. const API = require("../../lib/API");
  2. const db = require('../../plugin/DataBase/db')
  3. const Redis = require('../../plugin/DataBase/Redis')
  4. const mq = require('../../plugin/mq')
  5. const { assertRunforgeTaskIngress, publishRunforgeTask } = require('../../plugin/mq/runforgeTaskMq')
  6. const { scheduleDelayedRunforgeTask } = require('../../plugin/mq/lepaoAutoScheduleRedis')
  7. const jkesRedisKeys = require('../../plugin/jkes/redisKeys')
  8. const { BaseStdResponse } = require("../../BaseStdResponse");
  9. const { planJkesAutoRun } = require('../../plugin/jkes/monthPolicy')
  10. const { buildAutoRunTaskExtrasFromAccountRow } = require('../../plugin/jkes/autoRunAccountOptions')
  11. class StartAutoLepao extends API {
  12. constructor() {
  13. super();
  14. this.noEncrypt()
  15. this.setPath('/Corn/StartAutoLepao');
  16. this.setMethod('GET');
  17. }
  18. async onRequest(req, res) {
  19. try {
  20. res.json({
  21. ...BaseStdResponse.OK
  22. })
  23. const day = new Date().getDay()
  24. const hour = new Date().getHours()
  25. this.logger.info('开始执行自动乐跑任务')
  26. let sql = `
  27. SELECT name, student_num, auto_day, token, target_count,
  28. auto_run_distance_min_km, auto_run_distance_max_km, pace_min_sec_per_km, pace_max_sec_per_km
  29. FROM lepao_account
  30. WHERE auto_run = 1
  31. AND (auto_time = ? OR (auto_time = -1 AND today_auto_time = ?))
  32. AND JSON_CONTAINS(auto_day, CAST(? AS JSON))
  33. `
  34. let r = await db.query(sql, [hour, hour, day])
  35. if (!r)
  36. return this.logger.error('获取自动乐跑账号失败!')
  37. const nowMs = Date.now()
  38. const hourEnd = new Date()
  39. hourEnd.setHours(hourEnd.getHours() + 1, 0, 0, 0)
  40. const spreadWindowMs = Math.max(0, hourEnd.getTime() - nowMs)
  41. let channel
  42. try {
  43. channel = await mq.getChannel('lepao_corn')
  44. await assertRunforgeTaskIngress(channel, this.logger)
  45. } catch (err) {
  46. this.logger.error(`自动乐跑:连接 MQ 或声明拓扑失败:${err.message || err}`)
  47. return
  48. }
  49. for (const item of r) {
  50. const { name, student_num, auto_day, token, target_count } = item
  51. const runExtras = buildAutoRunTaskExtrasFromAccountRow(item)
  52. const isSuccess = await Redis.get(jkesRedisKeys.lepaoSuccess(student_num))
  53. if (isSuccess) {
  54. this.logger.info(`${name}(${student_num})当天已乐跑成功,不执行自动乐跑,如仍需跑步请手动发起`)
  55. continue
  56. }
  57. const plan = await planJkesAutoRun(student_num, auto_day, token, {
  58. monthTargetKm: target_count,
  59. stopAfterMinimum: true
  60. })
  61. if (!plan.run) {
  62. this.logger.info(`${name}(${student_num}) JKES 自动乐跑跳过:${plan.reason}`)
  63. continue
  64. }
  65. const delayMs = spreadWindowMs > 0 ? Math.floor(Math.random() * spreadWindowMs) : 0
  66. const fireAt = nowMs + delayMs
  67. const taskId = `lepao:auto:${fireAt}:${student_num}`
  68. const payload = {
  69. id: taskId,
  70. type: 'lepao.startRun',
  71. data: {
  72. taskId,
  73. account: student_num,
  74. targetKm: runExtras.targetKm,
  75. autoDoubleSlot: runExtras.autoDoubleSlot,
  76. paceRandomMinSecPerKm: runExtras.paceRandomMinSecPerKm,
  77. paceRandomMaxSecPerKm: runExtras.paceRandomMaxSecPerKm
  78. },
  79. retry: 0
  80. }
  81. if (delayMs > 0) {
  82. try {
  83. await scheduleDelayedRunforgeTask(fireAt, payload, {
  84. name,
  85. account: student_num,
  86. delayMs
  87. })
  88. this.logger.info(
  89. `${name}(${student_num})已写入 Redis 调度(约 ${Math.round(delayMs / 1000)}s 后进 MQ)`
  90. )
  91. } catch (err) {
  92. this.logger.error(`${name}(${student_num})Redis 调度失败:${err.message || err}`)
  93. }
  94. continue
  95. }
  96. try {
  97. publishRunforgeTask(channel, payload)
  98. this.logger.info(`${name}(${student_num})已投递自动乐跑任务`)
  99. } catch (err) {
  100. this.logger.error(`${name}(${student_num})乐跑投递失败:${err.message || err}`)
  101. }
  102. }
  103. } catch (error) {
  104. this.logger.error(error)
  105. }
  106. }
  107. }
  108. module.exports.StartAutoLepao = StartAutoLepao;