|
@@ -824,6 +824,61 @@ class TaskScheduler {
|
|
|
this.logInfo('adminRetryTask', '管理员已重试抢课任务', { taskId })
|
|
this.logInfo('adminRetryTask', '管理员已重试抢课任务', { taskId })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ async adminStartTask(taskId) {
|
|
|
|
|
+ const rows = await db.query('SELECT * FROM qk_task WHERE id = ?', [taskId])
|
|
|
|
|
+ if (!rows || rows.length === 0) {
|
|
|
|
|
+ throw new Error('任务不存在')
|
|
|
|
|
+ }
|
|
|
|
|
+ const task = rows[0]
|
|
|
|
|
+ if (![TASK_STATUS.PAUSED, TASK_STATUS.FAILED].includes(task.status)) {
|
|
|
|
|
+ throw new Error('仅未开始或失败的任务可开启')
|
|
|
|
|
+ }
|
|
|
|
|
+ if (task.batch_id) {
|
|
|
|
|
+ await this.requireEnabledBatch(task.batch_id)
|
|
|
|
|
+ }
|
|
|
|
|
+ const now = Date.now()
|
|
|
|
|
+ const result = await db.query(
|
|
|
|
|
+ `UPDATE qk_task SET status = ?, update_time = ?, assigned_client_id = NULL, lease_expire_at = NULL,
|
|
|
|
|
+ assigned_at = NULL, exclude_client_id = NULL, result_json = NULL, error_msg = NULL, finished_time = NULL
|
|
|
|
|
+ WHERE id = ? AND status IN (?, ?)`,
|
|
|
|
|
+ [TASK_STATUS.PENDING, now, taskId, TASK_STATUS.PAUSED, TASK_STATUS.FAILED]
|
|
|
|
|
+ )
|
|
|
|
|
+ if (!result || result.affectedRows <= 0) {
|
|
|
|
|
+ throw new Error('开启抢课任务失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.logTask(taskId, null, 'admin_started', '管理员开启抢课任务,等待分配')
|
|
|
|
|
+ this.logInfo('adminStartTask', '管理员已开启抢课任务', { taskId })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async adminPauseTask(taskId) {
|
|
|
|
|
+ const rows = await db.query('SELECT * FROM qk_task WHERE id = ?', [taskId])
|
|
|
|
|
+ if (!rows || rows.length === 0) {
|
|
|
|
|
+ throw new Error('任务不存在')
|
|
|
|
|
+ }
|
|
|
|
|
+ const task = rows[0]
|
|
|
|
|
+ if (![TASK_STATUS.PENDING, TASK_STATUS.ASSIGNED, TASK_STATUS.RUNNING].includes(task.status)) {
|
|
|
|
|
+ throw new Error('当前状态不可暂停')
|
|
|
|
|
+ }
|
|
|
|
|
+ const now = Date.now()
|
|
|
|
|
+ const wasAssigned = [TASK_STATUS.ASSIGNED, TASK_STATUS.RUNNING].includes(task.status)
|
|
|
|
|
+ if (wasAssigned && task.assigned_client_id) {
|
|
|
|
|
+ await this.decrementClientSlots(task.assigned_client_id, now)
|
|
|
|
|
+ }
|
|
|
|
|
+ const result = await db.query(
|
|
|
|
|
+ `UPDATE qk_task SET status = ?, update_time = ?, assigned_client_id = NULL, lease_expire_at = NULL,
|
|
|
|
|
+ assigned_at = NULL, exclude_client_id = NULL
|
|
|
|
|
+ WHERE id = ? AND status IN (?, ?, ?)`,
|
|
|
|
|
+ [TASK_STATUS.PAUSED, now, taskId, TASK_STATUS.PENDING, TASK_STATUS.ASSIGNED, TASK_STATUS.RUNNING]
|
|
|
|
|
+ )
|
|
|
|
|
+ if (!result || result.affectedRows <= 0) {
|
|
|
|
|
+ throw new Error('暂停抢课任务失败')
|
|
|
|
|
+ }
|
|
|
|
|
+ await this.logTask(taskId, task.assigned_client_id, 'admin_paused', wasAssigned ? '管理员暂停任务,已收回客户端' : '管理员暂停抢课任务')
|
|
|
|
|
+ this.logInfo('adminPauseTask', '管理员已暂停抢课任务', { taskId }, {
|
|
|
|
|
+ released_from_client: wasAssigned ? task.assigned_client_id : null
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
async authenticateClient(clientId, clientSecret) {
|
|
async authenticateClient(clientId, clientSecret) {
|
|
|
if (!clientId || !clientSecret) {
|
|
if (!clientId || !clientSecret) {
|
|
|
this.logWarn('authClient', '客户端认证失败:缺少凭证', { clientId: clientId || 'unknown' })
|
|
this.logWarn('authClient', '客户端认证失败:缺少凭证', { clientId: clientId || 'unknown' })
|