const API = require('../../../lib/API') const { BaseStdResponse } = require('../../../BaseStdResponse') const { TaskScheduler } = require('../../../lib/QK/TaskScheduler') const scheduler = new TaskScheduler() function getClientCredentials(body) { return { clientId: body.client_id, clientSecret: body.client_secret } } function fail(res, err, fallback = '客户端请求失败') { return res.json({ ...BaseStdResponse.ERR, msg: err?.message || fallback }) } class RegisterClient extends API { constructor() { super() this.setPath('/QK/Client/Register') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const result = await scheduler.registerClient(clientId, clientSecret, req.body) this.logger.info(`[QK][API][Register] 客户端注册成功 clientId=${result.client_id} max_slots=${result.max_slots}`) return res.json({ ...BaseStdResponse.OK, data: result }) } catch (err) { this.logger.error(`抢课客户端注册失败:${err.stack || err}`) return fail(res, err, '抢课客户端注册失败') } } } class HeartbeatClient extends API { constructor() { super() this.setPath('/QK/Client/Heartbeat') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const result = await scheduler.heartbeat(clientId, clientSecret, req.body) return res.json({ ...BaseStdResponse.OK, data: result }) } catch (err) { this.logger.error(`抢课客户端心跳失败:${err.stack || err}`) return fail(res, err, '抢课客户端心跳失败') } } } class PullTasks extends API { constructor() { super() this.setPath('/QK/Client/PullTasks') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const tasks = await scheduler.pullTasks(clientId, clientSecret, req.body.count) if (tasks.length > 0) { this.logger.info(`[QK][API][PullTasks] clientId=${clientId} 拉取到 ${tasks.length} 个任务 taskIds=${tasks.map(t => t.id).join(',')}`) } return res.json({ ...BaseStdResponse.OK, data: tasks }) } catch (err) { this.logger.error(`抢课客户端拉取任务失败:${err.stack || err}`) return fail(res, err, '抢课客户端拉取任务失败') } } } class ReclaimTasks extends API { constructor() { super() this.setPath('/QK/Client/ReclaimTasks') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const tasks = await scheduler.reclaimTasks(clientId, clientSecret) if (tasks.length > 0) { this.logger.info(`[QK][API][ReclaimTasks] clientId=${clientId} 回收 ${tasks.length} 个任务 taskIds=${tasks.map(t => t.id).join(',')}`) } return res.json({ ...BaseStdResponse.OK, data: tasks }) } catch (err) { this.logger.error(`抢课客户端回收任务失败:${err.stack || err}`) return fail(res, err, '抢课客户端回收任务失败') } } } class ReleaseTasks extends API { constructor() { super() this.setPath('/QK/Client/ReleaseTasks') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const result = await scheduler.releaseTasks(clientId, clientSecret, req.body) if (result.released > 0) { this.logger.info(`[QK][API][ReleaseTasks] clientId=${clientId} 释放 ${result.released} 个任务 taskIds=${result.task_ids.join(',')}`) } return res.json({ ...BaseStdResponse.OK, data: result }) } catch (err) { this.logger.error(`抢课客户端释放任务失败:${err.stack || err}`) return fail(res, err, '抢课客户端释放任务失败') } } } class ReportResult extends API { constructor() { super() this.setPath('/QK/Client/ReportResult') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const result = await scheduler.reportResult(clientId, clientSecret, req.body) this.logger.info(`[QK][API][ReportResult] clientId=${clientId} taskId=${result.task_id} status=${result.status}`) return res.json({ ...BaseStdResponse.OK, data: result }) } catch (err) { this.logger.error(`抢课客户端上报结果失败:${err.stack || err}`) return fail(res, err, '抢课客户端上报结果失败') } } } class ReportProgress extends API { constructor() { super() this.setPath('/QK/Client/ReportProgress') this.setMethod('POST') } async onRequest(req, res) { try { const { clientId, clientSecret } = getClientCredentials(req.body) const result = await scheduler.reportProgress(clientId, clientSecret, req.body) return res.json({ ...BaseStdResponse.OK, data: result }) } catch (err) { this.logger.error(`抢课客户端上报进度失败:${err.stack || err}`) return fail(res, err, '抢课客户端上报进度失败') } } } module.exports = { RegisterClient, HeartbeatClient, PullTasks, ReclaimTasks, ReleaseTasks, ReportResult, ReportProgress }