const API = require('../../lib/API.js') const db = require('../../plugin/DataBase/db.js') const { BaseStdResponse } = require('../../BaseStdResponse.js') const AccessControl = require('../../lib/AccessControl.js') const { fetchJkesMonthKm, fetchJkesTotalKm } = require('../../plugin/jkes/stats') const { readState, DOUBLE_RUNS_CAP, refreshMonthKmFromApi, normalizeMonthTargetKm } = require('../../plugin/jkes/monthPolicy') /** * 从 JKES 官方接口拉取本月/累计里程,并返回本地月度缓存。 * monthTargetKm 为学校要求的「本月最低」参考,非可跑里程上限。 */ class GetJkesRunOverview extends API { constructor() { super() this.setPath('/Lepao/JkesRunOverview') this.setMethod('GET') } async onRequest(req, res) { const { uuid, session, student_num } = req.query if ([uuid, session, student_num].some((v) => v === '' || v == null)) return res.json({ ...BaseStdResponse.MISSING_PARAMETER }) if (!await AccessControl.checkSession(uuid, session)) return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED }) try { const rows = await db.query( `SELECT student_num, token, create_user, target_count FROM lepao_account WHERE student_num = ?`, [student_num] ) if (!rows || rows.length === 0) return res.json({ ...BaseStdResponse.ERR, msg: '未找到乐跑账号' }) const acc = rows[0] if (acc.create_user !== uuid) { const permission = await AccessControl.getPermission(uuid) if (!permission.includes('admin') && !permission.includes('service')) return res.json({ ...BaseStdResponse.ERR, msg: '无权查看该账号' }) } if (!acc.token) return res.json({ ...BaseStdResponse.ERR, msg: '账号未登录或 token 无效,请先更新账号' }) const now = new Date() const y = now.getFullYear() const m = now.getMonth() + 1 await refreshMonthKmFromApi(student_num, acc.token, now) const monthKm = await fetchJkesMonthKm(acc.token, y, m) const totalKm = await fetchJkesTotalKm(acc.token) const local = await readState(student_num, now) const monthTargetKm = normalizeMonthTargetKm(acc.target_count) return res.json({ ...BaseStdResponse.OK, data: { student_num, monthKmOfficial: monthKm, totalKmOfficial: totalKm, monthKmCached: local.km, doubleRunsUsed: local.doubles, monthTargetKm, monthTargetIsMinimumNotCap: true, plannedDoubleRunDays: DOUBLE_RUNS_CAP } }) } catch (e) { this.logger.error(`JkesRunOverview ${e.stack || e}`) return res.json({ ...BaseStdResponse.ERR, msg: '获取 JKES 跑步数据失败' }) } } } module.exports.GetJkesRunOverview = GetJkesRunOverview