SingleRun.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. const API = require("../../lib/API.js")
  2. const Redis = require('../../plugin/DataBase/Redis')
  3. const db = require("../../plugin/DataBase/db.js")
  4. const { BaseStdResponse } = require("../../BaseStdResponse.js")
  5. const AccessControl = require("../../lib/AccessControl.js")
  6. const mq = require('../../plugin/mq')
  7. const {
  8. assertRunforgeTaskIngress,
  9. publishRunforgeTask
  10. } = require('../../plugin/mq/runforgeTaskMq')
  11. const { assertLepaoJwBindingOrThrow } = require('../../lib/Lepao/webvpnCookie')
  12. // 单次乐跑
  13. class SingleRun extends API {
  14. constructor() {
  15. super()
  16. this.setPath('/Lepao/SingleRun')
  17. this.setMethod('GET')
  18. }
  19. async onRequest(req, res) {
  20. let { uuid, session, student_num } = req.query
  21. if ([uuid, session, student_num].some(value => value === '' || value === null || value === undefined))
  22. return res.json({
  23. ...BaseStdResponse.MISSING_PARAMETER
  24. })
  25. if (!await AccessControl.checkSession(uuid, session))
  26. return res.status(401).json({
  27. ...BaseStdResponse.ACCESS_DENIED
  28. })
  29. let hour = new Date().getHours()
  30. if (hour < 7)
  31. return res.json({
  32. ...BaseStdResponse.ERR,
  33. msg: '当前不在有效乐跑时间范围内。请在7:00~24:00发起乐跑'
  34. })
  35. try {
  36. // 检查redis是否存在当天乐跑成功记录
  37. const isSuccess = await Redis.get(`lepaoSuccess:${student_num}`)
  38. if (isSuccess)
  39. return res.json({
  40. ...BaseStdResponse.ERR,
  41. msg: '该账号当天已乐跑成功!请勿重复乐跑'
  42. })
  43. const isProgress = await Redis.get(`lepaoProgress:${student_num}`)
  44. if (isProgress)
  45. return res.json({
  46. ...BaseStdResponse.ERR,
  47. msg: '该账号已进入乐跑任务队列,请等待乐跑完成后再进行乐跑操作'
  48. })
  49. let selectSql =
  50. 'SELECT create_user, token, uid, school_id, state FROM lepao_account WHERE student_num = ?'
  51. let selectRows = await db.query(selectSql, [student_num])
  52. if (!selectRows || selectRows.length === 0)
  53. return res.json({
  54. ...BaseStdResponse.ERR,
  55. msg: '发起乐跑失败!未找到账户信息'
  56. })
  57. if (selectRows[0].create_user !== uuid) {
  58. let permission = await AccessControl.getPermission(uuid)
  59. if (!permission.includes("admin") && !permission.includes("service"))
  60. return res.json({
  61. ...BaseStdResponse.ERR,
  62. msg: '发起乐跑失败!未找到账户信息'
  63. })
  64. }
  65. try {
  66. await assertLepaoJwBindingOrThrow(selectRows[0].create_user, student_num)
  67. } catch (jwErr) {
  68. return res.json({
  69. ...BaseStdResponse.ERR,
  70. msg: jwErr.message || '统一认证绑定校验失败'
  71. })
  72. }
  73. const accState = Number(selectRows[0].state)
  74. if (accState !== 1) {
  75. let stateMsg = '账号状态为未登录,请使用登录器更新账号信息后乐跑'
  76. if (accState === 3) {
  77. stateMsg =
  78. '统一认证登录失败,请在乐跑绑定中核对统一认证密码后重新保存,并完成教务账号激活'
  79. } else if (accState === 2) {
  80. stateMsg = '账号状态异常,请使用登录器更新账号信息或联系客服'
  81. }
  82. return res.json({
  83. ...BaseStdResponse.ERR,
  84. msg: stateMsg
  85. })
  86. }
  87. res.json({
  88. ...BaseStdResponse.OK
  89. })
  90. try {
  91. const channel = await mq.getChannel('lepao_api')
  92. await assertRunforgeTaskIngress(channel, this.logger)
  93. const taskId = `lepao:${Date.now()}:${student_num}`
  94. const payload = {
  95. id: taskId,
  96. type: 'lepao.startRun',
  97. data: {
  98. taskId,
  99. account: student_num,
  100. runMode: 'manual'
  101. },
  102. retry: 0
  103. }
  104. publishRunforgeTask(channel, payload)
  105. } catch (err) {
  106. this.logger.error(`后台乐跑任务异常:${err.stack}`)
  107. }
  108. } catch (err) {
  109. this.logger.error(`手动乐跑失败!${err.stack}`)
  110. return res.json({
  111. ...BaseStdResponse.ERR,
  112. msg: "乐跑失败!数据库异常"
  113. })
  114. }
  115. }
  116. }
  117. module.exports.SingleRun = SingleRun