Files
sanguo_vnpy_v2/_retired/sanguo_web/static/js/api.js
T
claude_dev bf57aed17a retire(web): sanguo_web legacy 平行后端归档——用户拍板「代码保留归档,服务删」 [nas]
- git mv sanguo_web → _retired/sanguo_web/(git 历史保全+墓碑 README:
  归档原因/拍板记录/现役=sanguo_api)
- 退出启动面三处: promote.sh ALL_MODS 白名单(15→14 模块)+docker/Dockerfile:63
  COPY+docker/Dockerfile.nas:16 COPY——不可再被部署或启动为服务
- 背景(架构审计 P0-3): 硬编码 SECRET_KEY/admin123 默认口令/CORS 全开/可下
  真实订单/零测试/与 sanguo_api 路由冲突; 生产从未部署为服务, 纯误启动风险
  (README 旧「生产模式 uvicorn sanguo_web」指引已于 f6ca85e 勘误)
- three-env §3.1 模块清单+§12 矩阵行同步; session-guide §5 角色表前端行
  勘误(旧表把 sanguo_web 当前端模块推——实为 legacy 后端, 前端=frontend/)
- 零外部 import(runuweb/tests/packages 全 grep 实证), pytest testpaths=tests
  不受影响

Co-Authored-By: Claude Code <notify@anthropic.com>
2026-10-01 09:46:21 +08:00

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();