const Redis = require('../DataBase/Redis.js') const jkesRedisKeys = require('./redisKeys.js') const { planJkesAutoRun, parseAutoDay } = require('./monthPolicy.js') const { buildAutoRunTaskFromPlan } = require('./autoRunAccountOptions.js') async function checkAutoRunBlockedToday(studentNum) { const isSuccess = await Redis.get(jkesRedisKeys.lepaoSuccess(studentNum)) if (isSuccess) { return { blocked: true, reason: '当天已乐跑成功' } } const inProgress = await Redis.get(jkesRedisKeys.lepaoProgress(studentNum)) if (inProgress) { return { blocked: true, reason: '乐跑进行中' } } return { blocked: false } } function isAutoRunDayToday(autoDayRaw) { const days = parseAutoDay(autoDayRaw) return days.length === 0 || days.includes(new Date().getDay()) } /** * 校验当日是否应投递自动乐跑,并合并月度计划距离与双倍日策略。 * @param {object} accountRow lepao_account 行(含 student_num / auto_day / token / target_count 等) */ async function prepareAutoRunTask(accountRow, options = {}) { const studentNum = accountRow?.student_num if (!studentNum) { return { run: false, reason: '缺少学号' } } const blocked = await checkAutoRunBlockedToday(studentNum) if (blocked.blocked) { return { run: false, reason: blocked.reason } } const plan = await planJkesAutoRun(studentNum, accountRow.auto_day, accountRow.token, { monthTargetKm: accountRow.target_count, stopAfterMinimum: options.stopAfterMinimum !== false }) if (!plan.run) { return plan } const task = buildAutoRunTaskFromPlan(accountRow, plan) return { run: true, plan, task } } function buildStartRunPayload(studentNum, task, options = {}) { const taskId = options.taskId || `${options.prefix || 'lepao:auto'}:${Date.now()}:${studentNum}` return { id: taskId, type: 'lepao.startRun', data: { taskId, account: studentNum, targetKm: task.targetKm, autoDoubleSlot: task.autoDoubleSlot, paceRandomMinSecPerKm: task.paceRandomMinSecPerKm, paceRandomMaxSecPerKm: task.paceRandomMaxSecPerKm }, retry: 0 } } module.exports = { checkAutoRunBlockedToday, isAutoRunDayToday, prepareAutoRunTask, buildStartRunPayload }