Files
sanguo_vnpy_v2/sanguo_web/static/js/api.js
T
claude_dev 918bbed0fc fix: 修复登录500错误和移除明文密码提示
- 修复 deps.py 中 get_vn_service 的引用错误 (vn_service.vn_service -> vn_service)
- 移除登录页面上的明文密码提示
- 改进前端错误处理,避免数据加载失败导致登录显示错误
2026-07-02 12:23:55 +08:00

374 lines
8.0 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 getGateways() {
return await this.get('/gateway/list');
}
/**
* 获取网关状态
*/
async getGatewayStatus(name) {
return await this.get(`/gateway/${name}/status`);
}
// ============================================
// 行情 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 客户端实例
const api = new ApiClient();