feat: 迭代03-05 交易记录接入、行情实时、QMT连接配置、data store 标准化
- R-004 QMT连接配置:多配置管理 + 会话头部快捷切换(03-QMT连接配置) - R-005 WS盘中价格实时更新:服务端中转+缓存+前端轮询(04-WS盘中价格实时更新) - R-006 策略数据 JSON data store 标准化(store.json/market.json/schema.json) - R-007 交易记录接入:当日订单+成交单表合并(委托主行+展开成交明细)、时间段查询(今日/本周/本月+手动起止)、费用计算(佣金费率万m_dCommission+最低5元、印花税卖出万5、过户费双向万0.1) - 架构治理:api 按领域拆分、component 目录、QmtHealthMonitor
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* 服务端 HTTP API 公共工具
|
||||
*
|
||||
* 为什么不用 RPC(connection.rpc.intercept('/api')):
|
||||
* DSH 的 /api 通道只能有一个 interceptor(api-gateway 已占用),
|
||||
* 再 intercept 会抛 "already has an interceptor" 导致插件 apply 失败。
|
||||
* 因此改用 webServer 自开路由(与 dsh-better-sidebar 的 /sidebar/api 同模式)。
|
||||
*/
|
||||
|
||||
export const API_PREFIX = '/odl/api/';
|
||||
|
||||
/** 响应 JSON */
|
||||
export function writeJson(res, status, data) {
|
||||
res.writeHead(status, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify(data));
|
||||
}
|
||||
|
||||
/** 读取 JSON body */
|
||||
export async function readJsonBody(req) {
|
||||
const chunks = [];
|
||||
for await (const chunk of req) chunks.push(chunk);
|
||||
const raw = Buffer.concat(chunks).toString('utf8');
|
||||
if (!raw) return {};
|
||||
try {
|
||||
return JSON.parse(raw);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/** 从激活配置解析 baseUrl(连接列表为空时回退数据源当前 baseUrl) */
|
||||
export function resolveActiveBaseUrl(settings, dataSource) {
|
||||
const state = getQmtConnections(settings);
|
||||
const active = getActiveQmtConnection(state);
|
||||
return String(active?.baseUrl ?? dataSource?.baseUrl ?? '').replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
// 延迟引入 settings 函数避免循环依赖
|
||||
import {
|
||||
getQmtConnections,
|
||||
getActiveQmtConnection,
|
||||
} from '../settings.js';
|
||||
Reference in New Issue
Block a user