/** * 服务端 API:行情域(2026-08-31 拆分;2026-09-01 精简) * * 端点: * market-snapshot → 按 code 查询行情缓存(miss 自动补拉在 MarketDataHub 内部,此处只做编排) * qmt-health → QMT 连接健康检查(读服务端缓存;refresh=true 触发即时探测) * * 2026-09-01:QMT health 改为「服务端定时探测(5 分钟)+ 缓存」机制(QmtHealthMonitor), * 前端打开读缓存秒回,点击/悬停传 refresh=true 触发即时探测。 */ import { resolveActiveBaseUrl } from './common.js'; /** 行情端点方法表 */ export const MARKET_METHODS = new Set([ 'market-snapshot', 'qmt-health', 'market-stats', // 临时诊断:WS/REST 通道统计 ]); /** * 处理行情端点 * @param {string} method * @param {object} args * @param {object} runtime { settings, dataSource, marketHub, marketFeed, qmtHealthMonitor } */ export async function handleMarket(method, args, { ctx, settings, dataSource, marketHub, marketFeed, qmtHealthMonitor }) { switch (method) { case 'market-snapshot': { const codes = Array.isArray(args.codes) ? args.codes : []; if (!marketHub) return {}; return await marketHub.getByCodes(codes, { settings, dataSource }); } case 'qmt-health': { // QMT 连接健康检查(服务端缓存 + 即时探测,2026-09-01) if (!qmtHealthMonitor) { return { healthy: null, baseUrl: resolveActiveBaseUrl(settings, dataSource), fromCache: false }; } if (args.refresh) { // 前端点击/悬停触发即时探测(刷新缓存) return await qmtHealthMonitor.probe(); } // 默认读缓存(秒回) return qmtHealthMonitor.getStatus(); } case 'market-stats': { // 临时诊断:WS 推送 vs REST 拉取 计数(确认 WS 是否生效) return { stats: marketHub?.stats ?? null, cacheSize: marketHub?.size ?? 0, watchSize: marketHub?.watchCodes?.size ?? 0, serverTime: Date.now(), }; } default: throw Object.assign(new Error('unknown market method: ' + method), { code: 'not-found' }); } }