| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- const API = require("../../lib/API");
- const db = require('../../plugin/DataBase/db')
- const Redis = require('../../plugin/DataBase/Redis')
- const mq = require('../../plugin/mq')
- const { assertRunforgeTaskIngress, publishRunforgeTask } = require('../../plugin/mq/runforgeTaskMq')
- const { scheduleDelayedRunforgeTask } = require('../../plugin/mq/lepaoAutoScheduleRedis')
- const { BaseStdResponse } = require("../../BaseStdResponse");
- class StartAutoLepao extends API {
- constructor() {
- super();
- this.noEncrypt()
- this.setPath('/Corn/StartAutoLepao');
- this.setMethod('GET');
- }
- async onRequest(req, res) {
- try {
- res.json({
- ...BaseStdResponse.OK
- })
- const day = new Date().getDay()
- const hour = new Date().getHours()
- this.logger.info('开始执行自动乐跑任务')
- let sql = `
- SELECT name, create_user, student_num, token, uid, school_id, state
- FROM lepao_account
- WHERE auto_run = 1
- AND (auto_time = ? OR (auto_time = -1 AND today_auto_time = ?))
- AND JSON_CONTAINS(auto_day, CAST(? AS JSON))
- `
- let r = await db.query(sql, [hour, hour, day])
- if (!r)
- return this.logger.error('获取自动乐跑账号失败!')
- // 为本小时内随机打散投递时间,减轻瞬时并发(0 ~ 当前小时剩余毫秒数)
- const nowMs = Date.now()
- const hourEnd = new Date()
- hourEnd.setHours(hourEnd.getHours() + 1, 0, 0, 0)
- const spreadWindowMs = Math.max(0, hourEnd.getTime() - nowMs)
- let channel
- try {
- channel = await mq.getChannel('lepao_corn')
- await assertRunforgeTaskIngress(channel, this.logger)
- } catch (err) {
- this.logger.error(`自动乐跑:连接 MQ 或声明拓扑失败:${err.message || err}`)
- return
- }
- for (const item of r) {
- const { name, create_user, student_num, token, uid, school_id, state } = item
- const isSuccess = await Redis.get(`lepaoSuccess:${student_num}`)
- if (isSuccess) {
- this.logger.info(`${name}(${student_num})当天已乐跑成功,不执行自动乐跑`)
- continue
- }
- const delayMs = spreadWindowMs > 0 ? Math.floor(Math.random() * spreadWindowMs) : 0
- const fireAt = nowMs + delayMs
- const taskId = `lepao:auto:${fireAt}:${student_num}`
- const payload = {
- id: taskId,
- type: 'lepao.startRun',
- data: {
- taskId,
- account: student_num
- },
- retry: 0
- }
- if (delayMs > 0) {
- try {
- await scheduleDelayedRunforgeTask(fireAt, payload, {
- name,
- account: student_num,
- delayMs
- })
- this.logger.info(
- `${name}(${student_num})已写入 Redis 调度(约 ${Math.round(delayMs / 1000)}s 后进 MQ 主队列)`
- )
- } catch (err) {
- this.logger.error(`${name}(${student_num})Redis 调度失败:${err.message || err}`)
- }
- continue
- }
- try {
- publishRunforgeTask(channel, payload)
- this.logger.info(`${name}(${student_num})已投递自动乐跑任务`)
- } catch (err) {
- this.logger.error(`${name}(${student_num})乐跑投递失败:${err.message || err}`)
- }
- }
- } catch (error) {
- this.logger.error(error)
- }
- }
- }
- module.exports.StartAutoLepao = StartAutoLepao;
|