From de5ad203755d991d022427466ec49b80069976b2 Mon Sep 17 00:00:00 2001 From: Lxy Date: Sat, 21 Feb 2026 00:01:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=AD=89=E8=B0=83=E6=95=B4=E5=AE=8C=E6=AF=95=EF=BC=9B=E5=BD=93?= =?UTF-8?q?=E5=89=8Dtqsdk=E4=BD=BF=E7=94=A8=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/api/config.ts | 4 +- backend/src/config/index.ts | 111 ++++++++++++------ .../services/datasource/DataSourceFactory.ts | 1 + .../src/services/datasource/TQDataSource.ts | 9 +- backend/src/services/marketService.ts | 6 +- backend/config.json => config.json | 0 6 files changed, 88 insertions(+), 43 deletions(-) rename backend/config.json => config.json (100%) diff --git a/backend/src/api/config.ts b/backend/src/api/config.ts index a85e4d9..5c929be 100644 --- a/backend/src/api/config.ts +++ b/backend/src/api/config.ts @@ -136,7 +136,7 @@ router.post('/save', async (req, res) => { // 保存配置到文件 const fs = require('fs'); const path = require('path'); - const configPath = path.join(__dirname, '../../config.json'); + const configPath = path.join(__dirname, '../../../config.json'); fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); @@ -153,7 +153,7 @@ router.get('/get', async (req, res) => { // 从文件读取配置 const fs = require('fs'); const path = require('path'); - const configPath = path.join(__dirname, '../../config.json'); + const configPath = path.join(__dirname, '../../../config.json'); let config = {}; if (fs.existsSync(configPath)) { diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 8f8d593..e323633 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -4,13 +4,44 @@ import path from 'path'; dotenv.config(); +// 配置文件类型定义 +interface ConfigFile { + server?: { + port?: number; + }; + security?: { + jwtSecret?: string; + rateLimit?: { + windowMs?: number; + max?: number; + }; + cors?: { + origin?: string; + methods?: string[]; + allowedHeaders?: string[]; + }; + }; + database?: { + postgreSQL?: { + host?: string; + port?: string; + username?: string; + password?: string; + database?: string; + }; + }; + dataSource?: any; +} + // 从文件读取配置 -let fileConfig = {}; +let fileConfig: ConfigFile = {}; try { const configPath = path.join(__dirname, '../../../config.json'); if (fs.existsSync(configPath)) { const configData = fs.readFileSync(configPath, 'utf8'); fileConfig = JSON.parse(configData); + console.log('已读取配置文件:', configPath); + console.log('配置文件内容:', fileConfig); } } catch (error) { console.error('读取配置文件失败:', error); @@ -43,38 +74,48 @@ export const config = { methods: fileConfig.security?.cors?.methods || ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: fileConfig.security?.cors?.allowedHeaders || ['Content-Type', 'Authorization'] }, - dataSource: fileConfig.dataSource || { - test: { - enabled: true, - timeout: 10000, - retries: 3, - refreshInterval: 60000 - }, - tqsdk: { - enabled: true, - apiKey: '', - apiSecret: '', - username: '', - password: '', - timeout: 30000, - retries: 3, - maxConnections: 5 - }, - wind: { - enabled: false, - apiKey: '', - apiSecret: '', - url: 'https://api.wind.com.cn', - timeout: 30000, - retries: 3 - }, - sina: { - enabled: false, - url: 'https://finance.sina.com.cn', - timeout: 10000, - retries: 3, - refreshInterval: 60000 - }, - defaultDataSource: 'tqsdk' - } + dataSource: (() => { + const dataSourceConfig = fileConfig.dataSource || { + test: { + enabled: true, + timeout: 10000, + retries: 3, + refreshInterval: 60000 + }, + tqsdk: { + enabled: true, + apiKey: '', + apiSecret: '', + username: '', + password: '', + timeout: 30000, + retries: 3, + maxConnections: 5 + }, + wind: { + enabled: false, + apiKey: '', + apiSecret: '', + url: 'https://api.wind.com.cn', + timeout: 30000, + retries: 3 + }, + sina: { + enabled: false, + url: 'https://finance.sina.com.cn', + timeout: 10000, + retries: 3, + refreshInterval: 60000 + }, + defaultDataSource: 'tqsdk' + }; + console.log('数据源配置初始化完成:', { + hasFileConfig: !!fileConfig.dataSource, + enabledDataSources: Object.keys(dataSourceConfig).filter(key => + key !== 'defaultDataSource' && dataSourceConfig[key].enabled + ), + defaultDataSource: dataSourceConfig.defaultDataSource + }); + return dataSourceConfig; + })() }; \ No newline at end of file diff --git a/backend/src/services/datasource/DataSourceFactory.ts b/backend/src/services/datasource/DataSourceFactory.ts index 30d8e1b..ce98356 100644 --- a/backend/src/services/datasource/DataSourceFactory.ts +++ b/backend/src/services/datasource/DataSourceFactory.ts @@ -16,6 +16,7 @@ export class DataSourceFactory { // 获取数据源实例 static async getDataSource(type: DataSourceType = DataSourceType.TQSDK, config: any = {}): Promise { + console.log('获取数据源实例:', type); if (!this.dataSources.has(type)) { let dataSource: DataSource; diff --git a/backend/src/services/datasource/TQDataSource.ts b/backend/src/services/datasource/TQDataSource.ts index ce8c777..6da52c9 100644 --- a/backend/src/services/datasource/TQDataSource.ts +++ b/backend/src/services/datasource/TQDataSource.ts @@ -1,9 +1,10 @@ // TQSDK数据源实现 import { DataSource } from './DataSource'; -import { TqSdk, TqAccount } from 'tqsdk'; +import TqSdk from 'tqsdk'; +import TqAccount from 'tqsdk'; export class TQDataSource implements DataSource { - private tq: TqSdk | null = null; + private tq: any = null; private initialized: boolean = false; private config: { username?: string; @@ -174,7 +175,9 @@ export class TQDataSource implements DataSource { async close(): Promise { if (this.tq) { - this.tq.close(); + if (typeof this.tq.close === 'function') { + this.tq.close(); + } this.tq = null; this.initialized = false; console.log('TQSDK数据源已关闭'); diff --git a/backend/src/services/marketService.ts b/backend/src/services/marketService.ts index 75435e2..fd3b308 100644 --- a/backend/src/services/marketService.ts +++ b/backend/src/services/marketService.ts @@ -14,7 +14,7 @@ export const fetchMarketOverview = async () => { try { // 获取数据源配置 const dataSourceConfig = getDataSourceConfig(); - + console.log('获取数据源配置:', dataSourceConfig); // 检查是否有可用的数据源 const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled; if (!hasAvailableDataSource) { @@ -43,7 +43,7 @@ export const fetchMarketOverview = async () => { winRate: Math.floor(Math.random() * 50) + 30, // 模拟胜率 atr: +(Math.random() * 5 + 0.5).toFixed(2), // 模拟ATR adx: Math.floor(Math.random() * 60) + 10, // 模拟ADX - adxStatus: adx => { + adxStatus: (adx: number) => { if (adx < 20) return '无趋势/震荡'; if (adx < 40) return '弱趋势'; return '强趋势'; @@ -156,7 +156,7 @@ export const fetchMarketDetail = async (symbol: string) => { winRate: Math.floor(Math.random() * 50) + 30, atr: +(Math.random() * 5 + 0.5).toFixed(2), adx: Math.floor(Math.random() * 60) + 10, - adxStatus: adx => { + adxStatus: (adx: number) => { if (adx < 20) return '无趋势/震荡'; if (adx < 40) return '弱趋势'; return '强趋势'; diff --git a/backend/config.json b/config.json similarity index 100% rename from backend/config.json rename to config.json