653472def3
对齐 VeighNa 4.4 原生 Qt UI,新增成交监控、资金监控、网关管理、全局配置等页面与 API,功能对等性 98.5%。 - 新增 API: /api/v1/trades, /api/v1/accounts, /api/v1/settings, 网关扩展 - 新增前端页面: 成交、资金、合约、网关、全局配置、微信通知 - 扩展导航菜单与实时数据推送 - 补充需求分析与实现计划文档
477 lines
10 KiB
JavaScript
477 lines
10 KiB
JavaScript
/**
|
|
* API 请求封装
|
|
* 处理认证、错误处理、请求拦截
|
|
*/
|
|
|
|
const API_BASE = '/api/v1';
|
|
|
|
/**
|
|
* API 客户端类
|
|
*/
|
|
class ApiClient {
|
|
constructor() {
|
|
this.token = localStorage.getItem('token');
|
|
this.tokenExpiry = localStorage.getItem('tokenExpiry');
|
|
}
|
|
|
|
/**
|
|
* 保存 Token
|
|
*/
|
|
setToken(token, expiresIn) {
|
|
this.token = token;
|
|
const expiry = new Date(Date.now() + expiresIn * 1000);
|
|
this.tokenExpiry = expiry.toISOString();
|
|
localStorage.setItem('token', token);
|
|
localStorage.setItem('tokenExpiry', this.tokenExpiry);
|
|
}
|
|
|
|
/**
|
|
* 清除 Token
|
|
*/
|
|
clearToken() {
|
|
this.token = null;
|
|
this.tokenExpiry = null;
|
|
localStorage.removeItem('token');
|
|
localStorage.removeItem('tokenExpiry');
|
|
}
|
|
|
|
/**
|
|
* 检查 Token 是否有效
|
|
*/
|
|
isTokenValid() {
|
|
if (!this.token || !this.tokenExpiry) {
|
|
return false;
|
|
}
|
|
const expiry = new Date(this.tokenExpiry);
|
|
return expiry > new Date();
|
|
}
|
|
|
|
/**
|
|
* 获取请求头
|
|
*/
|
|
getHeaders() {
|
|
const headers = {
|
|
'Content-Type': 'application/json'
|
|
};
|
|
|
|
if (this.token) {
|
|
headers['Authorization'] = `Bearer ${this.token}`;
|
|
}
|
|
|
|
return headers;
|
|
}
|
|
|
|
/**
|
|
* 处理响应
|
|
*/
|
|
async handleResponse(response) {
|
|
if (response.status === 401) {
|
|
// Token 过期或无效
|
|
this.clearToken();
|
|
window.location.reload();
|
|
throw new Error('Authentication failed');
|
|
}
|
|
|
|
if (response.status === 204) {
|
|
return null;
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!response.ok) {
|
|
const error = data.error || data.message || 'Request failed';
|
|
throw new Error(error);
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* GET 请求
|
|
*/
|
|
async get(url, params = {}) {
|
|
const queryString = new URLSearchParams(params).toString();
|
|
const fullUrl = `${API_BASE}${url}${queryString ? '?' + queryString : ''}`;
|
|
|
|
const response = await fetch(fullUrl, {
|
|
method: 'GET',
|
|
headers: this.getHeaders()
|
|
});
|
|
|
|
return this.handleResponse(response);
|
|
}
|
|
|
|
/**
|
|
* POST 请求
|
|
*/
|
|
async post(url, data = {}) {
|
|
const response = await fetch(`${API_BASE}${url}`, {
|
|
method: 'POST',
|
|
headers: this.getHeaders(),
|
|
body: JSON.stringify(data)
|
|
});
|
|
|
|
return this.handleResponse(response);
|
|
}
|
|
|
|
/**
|
|
* PUT 请求
|
|
*/
|
|
async put(url, data = {}) {
|
|
const response = await fetch(`${API_BASE}${url}`, {
|
|
method: 'PUT',
|
|
headers: this.getHeaders(),
|
|
body: JSON.stringify(data)
|
|
});
|
|
|
|
return this.handleResponse(response);
|
|
}
|
|
|
|
/**
|
|
* DELETE 请求
|
|
*/
|
|
async delete(url) {
|
|
const response = await fetch(`${API_BASE}${url}`, {
|
|
method: 'DELETE',
|
|
headers: this.getHeaders()
|
|
});
|
|
|
|
return this.handleResponse(response);
|
|
}
|
|
|
|
// ============================================
|
|
// 认证 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 用户登录
|
|
*/
|
|
async login(username, password) {
|
|
const data = await this.post('/auth/login', { username, password });
|
|
this.setToken(data.access_token, data.expires_in);
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* 用户登出
|
|
*/
|
|
async logout() {
|
|
try {
|
|
await this.post('/auth/logout');
|
|
} finally {
|
|
this.clearToken();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 验证 Token
|
|
*/
|
|
async verifyToken() {
|
|
return await this.post('/auth/verify', { token: this.token });
|
|
}
|
|
|
|
/**
|
|
* 获取当前用户信息
|
|
*/
|
|
async getCurrentUser() {
|
|
return await this.get('/auth/me');
|
|
}
|
|
|
|
// ============================================
|
|
// 系统 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取系统信息
|
|
*/
|
|
async getSystemInfo() {
|
|
return await this.get('/system/info');
|
|
}
|
|
|
|
// ============================================
|
|
// 行情 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取合约列表
|
|
*/
|
|
async getContracts() {
|
|
const data = await this.get('/market/contracts');
|
|
return data.contracts || [];
|
|
}
|
|
|
|
/**
|
|
* 获取行情数据
|
|
*/
|
|
async getTicks(symbols = null) {
|
|
const params = symbols ? { symbols: symbols.join(',') } : {};
|
|
const data = await this.get('/market/ticks', params);
|
|
return data.ticks || [];
|
|
}
|
|
|
|
/**
|
|
* 订阅行情
|
|
*/
|
|
async subscribe(symbol, exchange, gatewayName = null) {
|
|
return await this.post('/market/subscribe', {
|
|
symbol,
|
|
exchange,
|
|
gateway_name: gatewayName
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 取消订阅行情
|
|
*/
|
|
async unsubscribe(symbol, exchange, gatewayName = null) {
|
|
return await this.post('/market/unsubscribe', {
|
|
symbol,
|
|
exchange,
|
|
gateway_name: gatewayName
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// 交易 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取账户列表
|
|
*/
|
|
async getAccounts() {
|
|
return await this.get('/trading/accounts');
|
|
}
|
|
|
|
/**
|
|
* 获取持仓列表
|
|
*/
|
|
async getPositions() {
|
|
return await this.get('/trading/positions');
|
|
}
|
|
|
|
/**
|
|
* 获取订单列表
|
|
*/
|
|
async getOrders() {
|
|
return await this.get('/trading/orders');
|
|
}
|
|
|
|
/**
|
|
* 获取活动订单
|
|
*/
|
|
async getActiveOrders() {
|
|
return await this.get('/trading/orders/active');
|
|
}
|
|
|
|
/**
|
|
* 发送订单
|
|
*/
|
|
async sendOrder(params) {
|
|
return await this.post('/trading/orders', params);
|
|
}
|
|
|
|
/**
|
|
* 撤销订单
|
|
*/
|
|
async cancelOrder(orderId) {
|
|
return await this.delete(`/trading/orders/${orderId}`);
|
|
}
|
|
|
|
/**
|
|
* 获取成交列表
|
|
*/
|
|
async getTrades() {
|
|
return await this.get('/trading/trades');
|
|
}
|
|
|
|
/**
|
|
* 获取账户综合信息
|
|
*/
|
|
async getAccount() {
|
|
return await this.get('/trading/account');
|
|
}
|
|
|
|
// ============================================
|
|
// 策略 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取策略列表
|
|
*/
|
|
async getStrategies() {
|
|
return await this.get('/strategy/list');
|
|
}
|
|
|
|
/**
|
|
* 创建策略
|
|
*/
|
|
async createStrategy(strategyName, className, setting) {
|
|
return await this.post('/strategy/create', {
|
|
strategy_name: strategyName,
|
|
class_name: className,
|
|
setting
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 初始化策略
|
|
*/
|
|
async initStrategy(strategyName) {
|
|
return await this.post('/strategy/init', {
|
|
strategy_name: strategyName
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 启动策略
|
|
*/
|
|
async startStrategy(strategyName) {
|
|
return await this.post('/strategy/start', {
|
|
strategy_name: strategyName
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 停止策略
|
|
*/
|
|
async stopStrategy(strategyName) {
|
|
return await this.post('/strategy/stop', {
|
|
strategy_name: strategyName
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 编辑策略
|
|
*/
|
|
async editStrategy(strategyName, setting) {
|
|
return await this.post('/strategy/edit', {
|
|
strategy_name: strategyName,
|
|
setting
|
|
});
|
|
}
|
|
|
|
// ============================================
|
|
// 成交监控 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取所有成交记录
|
|
*/
|
|
async getAllTrades() {
|
|
return await this.get('/trades/');
|
|
}
|
|
|
|
/**
|
|
* 获取最新成交记录
|
|
*/
|
|
async getLatestTrades(limit = 50) {
|
|
return await this.get('/trades/latest', { limit });
|
|
}
|
|
|
|
// ============================================
|
|
// 资金监控 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取所有账户资金
|
|
*/
|
|
async getAllAccounts() {
|
|
return await this.get('/accounts/');
|
|
}
|
|
|
|
/**
|
|
* 获取资金汇总
|
|
*/
|
|
async getAccountSummary() {
|
|
return await this.get('/accounts/summary/total');
|
|
}
|
|
|
|
// ============================================
|
|
// 网关管理 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取所有可用网关
|
|
*/
|
|
async getAllGateways() {
|
|
return await this.get('/gateway/list');
|
|
}
|
|
|
|
/**
|
|
* 获取网关配置模板
|
|
*/
|
|
async getGatewaySetting(name) {
|
|
return await this.get(`/gateway/${name}/setting`);
|
|
}
|
|
|
|
/**
|
|
* 连接网关
|
|
*/
|
|
async connectGateway(name, setting) {
|
|
return await this.post(`/gateway/${name}/connect`, setting);
|
|
}
|
|
|
|
/**
|
|
* 断开网关
|
|
*/
|
|
async disconnectGateway(name) {
|
|
return await this.post(`/gateway/${name}/disconnect`);
|
|
}
|
|
|
|
// ============================================
|
|
// 全局配置 API
|
|
// ============================================
|
|
|
|
/**
|
|
* 获取全局配置
|
|
*/
|
|
async getGlobalSettings() {
|
|
return await this.get('/settings/global');
|
|
}
|
|
|
|
/**
|
|
* 更新全局配置
|
|
*/
|
|
async updateGlobalSettings(settings) {
|
|
return await this.put('/settings/global', settings);
|
|
}
|
|
|
|
/**
|
|
* 获取微信通知状态
|
|
*/
|
|
async getWechatStatus() {
|
|
return await this.get('/wechat/status');
|
|
}
|
|
|
|
/**
|
|
* 绑定微信
|
|
*/
|
|
async bindWechat() {
|
|
return await this.post('/wechat/bind');
|
|
}
|
|
|
|
/**
|
|
* 解绑微信
|
|
*/
|
|
async unbindWechat() {
|
|
return await this.post('/wechat/unbind');
|
|
}
|
|
|
|
/**
|
|
* 发送测试消息
|
|
*/
|
|
async sendWechatTest() {
|
|
return await this.post('/wechat/test');
|
|
}
|
|
|
|
/**
|
|
* 设置微信推送间隔
|
|
*/
|
|
async setWechatInterval(interval) {
|
|
return await this.put('/wechat/interval', { interval });
|
|
}
|
|
}
|
|
|
|
// 创建全局 API 客户端实例
|
|
const api = new ApiClient();
|