Admin.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. const API = require('../../../lib/API')
  2. const { BaseStdResponse } = require('../../../BaseStdResponse')
  3. const { TaskScheduler } = require('../../../lib/QK/TaskScheduler')
  4. const scheduler = new TaskScheduler()
  5. function fail(res, err, fallback = '后台抢课管理操作失败') {
  6. return res.json({
  7. ...BaseStdResponse.ERR,
  8. msg: err?.message || fallback
  9. })
  10. }
  11. class ListClient extends API {
  12. constructor() {
  13. super()
  14. this.setPath('/Admin/QK/Client/List')
  15. this.setMethod('GET')
  16. }
  17. async onRequest(req, res) {
  18. try {
  19. const list = await scheduler.listClients()
  20. return res.json({ ...BaseStdResponse.OK, data: list })
  21. } catch (err) {
  22. this.logger.error(`获取抢课客户端列表失败:${err.stack || err}`)
  23. return fail(res, err, '获取抢课客户端列表失败')
  24. }
  25. }
  26. }
  27. class DeleteClient extends API {
  28. constructor() {
  29. super()
  30. this.setPath('/Admin/QK/Client/Delete')
  31. this.setMethod('DELETE')
  32. }
  33. async onRequest(req, res) {
  34. try {
  35. const { client_id } = req.body
  36. if (!client_id) {
  37. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  38. }
  39. await scheduler.deleteClient(client_id)
  40. this.logger.info(`[QK][API][DeleteClient] 已禁用客户端 clientId=${client_id}`)
  41. return res.json({ ...BaseStdResponse.OK })
  42. } catch (err) {
  43. this.logger.error(`禁用抢课客户端失败:${err.stack || err}`)
  44. return fail(res, err, '禁用抢课客户端失败')
  45. }
  46. }
  47. }
  48. class EnableClient extends API {
  49. constructor() {
  50. super()
  51. this.setPath('/Admin/QK/Client/Enable')
  52. this.setMethod('POST')
  53. }
  54. async onRequest(req, res) {
  55. try {
  56. const { client_id } = req.body
  57. if (!client_id) {
  58. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  59. }
  60. await scheduler.enableClient(client_id)
  61. this.logger.info(`[QK][API][EnableClient] 已解禁客户端 clientId=${client_id}`)
  62. return res.json({ ...BaseStdResponse.OK })
  63. } catch (err) {
  64. this.logger.error(`解禁抢课客户端失败:${err.stack || err}`)
  65. return fail(res, err, '解禁抢课客户端失败')
  66. }
  67. }
  68. }
  69. class ListTask extends API {
  70. constructor() {
  71. super()
  72. this.setPath('/Admin/QK/Task/List')
  73. this.setMethod('GET')
  74. }
  75. async onRequest(req, res) {
  76. try {
  77. const result = await scheduler.listAdminTasks(req.query)
  78. return res.json({ ...BaseStdResponse.OK, data: result })
  79. } catch (err) {
  80. this.logger.error(`获取抢课任务列表失败:${err.stack || err}`)
  81. return fail(res, err, '获取抢课任务列表失败')
  82. }
  83. }
  84. }
  85. class GetTask extends API {
  86. constructor() {
  87. super()
  88. this.setPath('/Admin/QK/Task/Detail')
  89. this.setMethod('GET')
  90. }
  91. async onRequest(req, res) {
  92. try {
  93. const { id } = req.query
  94. if (!id) {
  95. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  96. }
  97. const task = await scheduler.getAdminTask(id)
  98. if (!task) {
  99. return res.json({ ...BaseStdResponse.ERR, msg: '任务不存在' })
  100. }
  101. return res.json({ ...BaseStdResponse.OK, data: task })
  102. } catch (err) {
  103. this.logger.error(`获取抢课任务详情失败:${err.stack || err}`)
  104. return fail(res, err, '获取抢课任务详情失败')
  105. }
  106. }
  107. }
  108. class UpdateTask extends API {
  109. constructor() {
  110. super()
  111. this.setPath('/Admin/QK/Task/Update')
  112. this.setMethod('POST')
  113. }
  114. async onRequest(req, res) {
  115. try {
  116. const { id } = req.body
  117. if (!id) {
  118. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  119. }
  120. await scheduler.adminUpdateTask(id, req.body)
  121. this.logger.info(`[QK][API][AdminUpdateTask] 管理员更新任务 taskId=${id}`)
  122. return res.json({ ...BaseStdResponse.OK })
  123. } catch (err) {
  124. this.logger.error(`管理员更新抢课任务失败:${err.stack || err}`)
  125. return fail(res, err, '更新抢课任务失败')
  126. }
  127. }
  128. }
  129. class CancelTask extends API {
  130. constructor() {
  131. super()
  132. this.setPath('/Admin/QK/Task/Cancel')
  133. this.setMethod('DELETE')
  134. }
  135. async onRequest(req, res) {
  136. try {
  137. const { id } = req.body
  138. if (!id) {
  139. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  140. }
  141. await scheduler.adminCancelTask(id)
  142. this.logger.info(`[QK][API][AdminCancelTask] 管理员取消任务 taskId=${id}`)
  143. return res.json({ ...BaseStdResponse.OK })
  144. } catch (err) {
  145. this.logger.error(`管理员取消抢课任务失败:${err.stack || err}`)
  146. return fail(res, err, '取消抢课任务失败')
  147. }
  148. }
  149. }
  150. class RetryTask extends API {
  151. constructor() {
  152. super()
  153. this.setPath('/Admin/QK/Task/Retry')
  154. this.setMethod('POST')
  155. }
  156. async onRequest(req, res) {
  157. try {
  158. const { id } = req.body
  159. if (!id) {
  160. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  161. }
  162. await scheduler.adminRetryTask(id)
  163. this.logger.info(`[QK][API][AdminRetryTask] 管理员重试任务 taskId=${id}`)
  164. return res.json({ ...BaseStdResponse.OK })
  165. } catch (err) {
  166. this.logger.error(`管理员重试抢课任务失败:${err.stack || err}`)
  167. return fail(res, err, '重试抢课任务失败')
  168. }
  169. }
  170. }
  171. class StartTask extends API {
  172. constructor() {
  173. super()
  174. this.setPath('/Admin/QK/Task/Start')
  175. this.setMethod('POST')
  176. }
  177. async onRequest(req, res) {
  178. try {
  179. const { id } = req.body
  180. if (!id) {
  181. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  182. }
  183. await scheduler.adminStartTask(id)
  184. this.logger.info(`[QK][API][AdminStartTask] 管理员开启任务 taskId=${id}`)
  185. return res.json({ ...BaseStdResponse.OK })
  186. } catch (err) {
  187. this.logger.error(`管理员开启抢课任务失败:${err.stack || err}`)
  188. return fail(res, err, '开启抢课任务失败')
  189. }
  190. }
  191. }
  192. class PauseTask extends API {
  193. constructor() {
  194. super()
  195. this.setPath('/Admin/QK/Task/Pause')
  196. this.setMethod('POST')
  197. }
  198. async onRequest(req, res) {
  199. try {
  200. const { id } = req.body
  201. if (!id) {
  202. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  203. }
  204. await scheduler.adminPauseTask(id)
  205. this.logger.info(`[QK][API][AdminPauseTask] 管理员暂停任务 taskId=${id}`)
  206. return res.json({ ...BaseStdResponse.OK })
  207. } catch (err) {
  208. this.logger.error(`管理员暂停抢课任务失败:${err.stack || err}`)
  209. return fail(res, err, '暂停抢课任务失败')
  210. }
  211. }
  212. }
  213. class ListReport extends API {
  214. constructor() {
  215. super()
  216. this.setPath('/Admin/QK/Report/List')
  217. this.setMethod('GET')
  218. }
  219. async onRequest(req, res) {
  220. try {
  221. const result = await scheduler.listAdminReports(req.query)
  222. return res.json({ ...BaseStdResponse.OK, data: result })
  223. } catch (err) {
  224. this.logger.error(`获取抢课回报记录失败:${err.stack || err}`)
  225. return fail(res, err, '获取抢课回报记录失败')
  226. }
  227. }
  228. }
  229. class ListBatch extends API {
  230. constructor() {
  231. super()
  232. this.setPath('/Admin/QK/Batch/List')
  233. this.setMethod('GET')
  234. }
  235. async onRequest(req, res) {
  236. try {
  237. const list = await scheduler.listBatches()
  238. return res.json({ ...BaseStdResponse.OK, data: list })
  239. } catch (err) {
  240. this.logger.error(`获取抢课批次列表失败:${err.stack || err}`)
  241. return fail(res, err, '获取抢课批次列表失败')
  242. }
  243. }
  244. }
  245. class SaveBatch extends API {
  246. constructor() {
  247. super()
  248. this.setPath('/Admin/QK/Batch/Save')
  249. this.setMethod('POST')
  250. }
  251. async onRequest(req, res) {
  252. try {
  253. const { id, name, jx0502zbid, enabled } = req.body
  254. if (!name || !jx0502zbid) {
  255. return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
  256. }
  257. if (id) {
  258. await scheduler.updateBatch(id, req.body)
  259. this.logger.info(`[QK][API][SaveBatch] 更新批次 batchId=${id}`)
  260. return res.json({ ...BaseStdResponse.OK, data: { id } })
  261. }
  262. const batchId = await scheduler.createBatch({ name, jx0502zbid, enabled })
  263. this.logger.info(`[QK][API][SaveBatch] 创建批次 batchId=${batchId}`)
  264. return res.json({ ...BaseStdResponse.OK, data: { id: batchId } })
  265. } catch (err) {
  266. this.logger.error(`保存抢课批次失败:${err.stack || err}`)
  267. return fail(res, err, '保存抢课批次失败')
  268. }
  269. }
  270. }
  271. module.exports = {
  272. ListClient,
  273. DeleteClient,
  274. EnableClient,
  275. ListTask,
  276. GetTask,
  277. UpdateTask,
  278. CancelTask,
  279. RetryTask,
  280. StartTask,
  281. PauseTask,
  282. ListReport,
  283. ListBatch,
  284. SaveBatch
  285. }