From 534ba7c3435bbd56f0e446110a178e1c22977742 Mon Sep 17 00:00:00 2001 From: claw_bot Date: Thu, 12 Mar 2026 05:11:50 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E8=82=A1=E7=A5=A8?= =?UTF-8?q?=E8=A1=8C=E6=83=85=E6=8E=A5=E5=8F=A3=E4=B8=BA=E4=B8=9C=E6=96=B9?= =?UTF-8?q?=E8=B4=A2=E5=AF=8C=EF=BC=9A=E8=BF=94=E5=9B=9E=E5=AE=9E=E9=99=85?= =?UTF-8?q?=E4=BA=A4=E6=98=93=E4=BB=B7=E6=A0=BC=EF=BC=8C=E4=B8=8E=E5=88=B8?= =?UTF-8?q?=E5=95=86=E6=98=BE=E7=A4=BA=E4=B8=80=E8=87=B4=EF=BC=8C=E6=97=A0?= =?UTF-8?q?=E5=A4=8D=E6=9D=83=E5=81=8F=E5=B7=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Properties/launchSettings.json | 21 ++++++- .../Services/MarketDataService.cs | 61 +++++++++++-------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/AssetManager.API/Properties/launchSettings.json b/AssetManager.API/Properties/launchSettings.json index 1e95a26..a5ef966 100644 --- a/AssetManager.API/Properties/launchSettings.json +++ b/AssetManager.API/Properties/launchSettings.json @@ -16,7 +16,12 @@ "launchUrl": "swagger", "applicationUrl": "http://localhost:5050", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "ConnectionStrings__Default": "server=localhost;database=assetmanager;user=root;password=你的数据库密码;", + "Jwt__SecretKey": "你的JWT密钥至少16位", + "Jwt__Issuer": "AssetManager", + "Jwt__Audience": "AssetManager", + "Tiingo__ApiKey": "你的TiingoAPI密钥" } }, "https": { @@ -26,7 +31,12 @@ "launchUrl": "swagger", "applicationUrl": "https://localhost:7040;http://localhost:5050", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "ConnectionStrings__Default": "server=localhost;database=assetmanager;user=root;password=你的数据库密码;", + "Jwt__SecretKey": "你的JWT密钥至少16位", + "Jwt__Issuer": "AssetManager", + "Jwt__Audience": "AssetManager", + "Tiingo__ApiKey": "你的TiingoAPI密钥" } }, "IIS Express": { @@ -34,7 +44,12 @@ "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "ConnectionStrings__Default": "server=localhost;database=assetmanager;user=root;password=你的数据库密码;", + "Jwt__SecretKey": "你的JWT密钥至少16位", + "Jwt__Issuer": "AssetManager", + "Jwt__Audience": "AssetManager", + "Tiingo__ApiKey": "你的TiingoAPI密钥" } } } diff --git a/AssetManager.Infrastructure/Services/MarketDataService.cs b/AssetManager.Infrastructure/Services/MarketDataService.cs index 4b1d40e..ec0284b 100644 --- a/AssetManager.Infrastructure/Services/MarketDataService.cs +++ b/AssetManager.Infrastructure/Services/MarketDataService.cs @@ -39,7 +39,7 @@ public class MarketDataService : IMarketDataService } /// - /// 获取股票实时价格(使用腾讯财经接口,免费无限制,支持盘前盘后) + /// 获取股票实时价格(使用东方财富接口,免费无限制,返回实际交易价格,和券商一致) /// /// 股票代码 /// 股票价格信息 @@ -47,36 +47,22 @@ public class MarketDataService : IMarketDataService { try { - _logger.LogInformation($"Requesting stock price for symbol: {symbol} (腾讯财经接口)"); + _logger.LogInformation($"Requesting stock price for symbol: {symbol} (东方财富接口)"); - // 腾讯财经美股接口:前缀us,大写代码 - var url = $"http://qt.gtimg.cn/q=us{symbol.ToUpper()}"; - var response = await _httpClient.GetStringAsync(url); + // 东方财富美股接口:secid=105.代码,105代表美股 + var url = $"https://push2.eastmoney.com/api/qt/stock/get?secid=105.{symbol.ToUpper()}&ut=fa5fd1943c7b386f172d6893dbfba10b&fields=f43,f60&np=1&fltt=2&invt=2"; + var response = await _httpClient.GetFromJsonAsync(url); - if (string.IsNullOrEmpty(response) || !response.Contains("~")) + if (response?.data == null || response.data.f43 <= 0) { - throw new Exception($"腾讯财经接口返回无效数据,标的: {symbol}"); + throw new Exception($"东方财富接口返回无效数据,标的: {symbol}"); } - // 解析返回数据 - var parts = response.Split('"')[1].Split('~'); - if (parts.Length < 36) - { - throw new Exception($"腾讯财经返回字段不足,标的: {symbol}"); - } - - // 提取字段:[3]=最新价 [4]=昨收价 - if (!decimal.TryParse(parts[3], out var currentPrice) || currentPrice <= 0) - { - throw new Exception($"解析最新价失败,标的: {symbol},返回值: {parts[3]}"); - } - - if (!decimal.TryParse(parts[4], out var prevClose) || prevClose <= 0) - { - prevClose = currentPrice; // 解析失败用当前价当昨收 - } + // 提取字段:f43=最新价 f60=昨收价,单位都是分,转成元 + var currentPrice = response.data.f43 / 100m; + var prevClose = response.data.f60 / 100m; - _logger.LogDebug("腾讯财经接口返回 {Symbol}:最新价 {CurrentPrice},昨收价 {PrevClose},涨跌额 {Change}", + _logger.LogDebug("东方财富接口返回 {Symbol}:最新价 {CurrentPrice},昨收价 {PrevClose},涨跌额 {Change}", symbol, currentPrice, prevClose, currentPrice - prevClose); return new MarketPriceResponse @@ -90,12 +76,35 @@ public class MarketDataService : IMarketDataService } catch (Exception ex) { - _logger.LogError(ex, $"腾讯财经接口获取价格失败,标的: {symbol},降级使用Tiingo接口"); + _logger.LogError(ex, $"东方财富接口获取价格失败,标的: {symbol},降级使用Tiingo接口"); // 降级使用Tiingo接口 return await GetStockPriceFromTiingoAsync(symbol); } } + /// + /// 东方财富美股接口响应模型 + /// + internal class EastMoneyStockResponse + { + public EastMoneyStockData? data { get; set; } + public int rc { get; set; } + public string? msg { get; set; } + } + + internal class EastMoneyStockData + { + /// + /// 最新价(单位:分) + /// + public decimal f43 { get; set; } + + /// + /// 昨收价(单位:分) + /// + public decimal f60 { get; set; } + } + /// /// 从Tiingo获取股票价格(降级用) /// From 57e9c69a8790f199d0dc0cc59c62d1c502705ac0 Mon Sep 17 00:00:00 2001 From: claw_bot Date: Thu, 12 Mar 2026 05:18:46 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=E5=9B=9E=E6=BB=9A=E5=88=B0=E8=85=BE?= =?UTF-8?q?=E8=AE=AF=E8=B4=A2=E7=BB=8F=E8=A1=8C=E6=83=85=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/MarketDataService.cs | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/AssetManager.Infrastructure/Services/MarketDataService.cs b/AssetManager.Infrastructure/Services/MarketDataService.cs index ec0284b..4b1d40e 100644 --- a/AssetManager.Infrastructure/Services/MarketDataService.cs +++ b/AssetManager.Infrastructure/Services/MarketDataService.cs @@ -39,7 +39,7 @@ public class MarketDataService : IMarketDataService } /// - /// 获取股票实时价格(使用东方财富接口,免费无限制,返回实际交易价格,和券商一致) + /// 获取股票实时价格(使用腾讯财经接口,免费无限制,支持盘前盘后) /// /// 股票代码 /// 股票价格信息 @@ -47,22 +47,36 @@ public class MarketDataService : IMarketDataService { try { - _logger.LogInformation($"Requesting stock price for symbol: {symbol} (东方财富接口)"); + _logger.LogInformation($"Requesting stock price for symbol: {symbol} (腾讯财经接口)"); - // 东方财富美股接口:secid=105.代码,105代表美股 - var url = $"https://push2.eastmoney.com/api/qt/stock/get?secid=105.{symbol.ToUpper()}&ut=fa5fd1943c7b386f172d6893dbfba10b&fields=f43,f60&np=1&fltt=2&invt=2"; - var response = await _httpClient.GetFromJsonAsync(url); + // 腾讯财经美股接口:前缀us,大写代码 + var url = $"http://qt.gtimg.cn/q=us{symbol.ToUpper()}"; + var response = await _httpClient.GetStringAsync(url); - if (response?.data == null || response.data.f43 <= 0) + if (string.IsNullOrEmpty(response) || !response.Contains("~")) { - throw new Exception($"东方财富接口返回无效数据,标的: {symbol}"); + throw new Exception($"腾讯财经接口返回无效数据,标的: {symbol}"); } - // 提取字段:f43=最新价 f60=昨收价,单位都是分,转成元 - var currentPrice = response.data.f43 / 100m; - var prevClose = response.data.f60 / 100m; + // 解析返回数据 + var parts = response.Split('"')[1].Split('~'); + if (parts.Length < 36) + { + throw new Exception($"腾讯财经返回字段不足,标的: {symbol}"); + } + + // 提取字段:[3]=最新价 [4]=昨收价 + if (!decimal.TryParse(parts[3], out var currentPrice) || currentPrice <= 0) + { + throw new Exception($"解析最新价失败,标的: {symbol},返回值: {parts[3]}"); + } + + if (!decimal.TryParse(parts[4], out var prevClose) || prevClose <= 0) + { + prevClose = currentPrice; // 解析失败用当前价当昨收 + } - _logger.LogDebug("东方财富接口返回 {Symbol}:最新价 {CurrentPrice},昨收价 {PrevClose},涨跌额 {Change}", + _logger.LogDebug("腾讯财经接口返回 {Symbol}:最新价 {CurrentPrice},昨收价 {PrevClose},涨跌额 {Change}", symbol, currentPrice, prevClose, currentPrice - prevClose); return new MarketPriceResponse @@ -76,35 +90,12 @@ public class MarketDataService : IMarketDataService } catch (Exception ex) { - _logger.LogError(ex, $"东方财富接口获取价格失败,标的: {symbol},降级使用Tiingo接口"); + _logger.LogError(ex, $"腾讯财经接口获取价格失败,标的: {symbol},降级使用Tiingo接口"); // 降级使用Tiingo接口 return await GetStockPriceFromTiingoAsync(symbol); } } - /// - /// 东方财富美股接口响应模型 - /// - internal class EastMoneyStockResponse - { - public EastMoneyStockData? data { get; set; } - public int rc { get; set; } - public string? msg { get; set; } - } - - internal class EastMoneyStockData - { - /// - /// 最新价(单位:分) - /// - public decimal f43 { get; set; } - - /// - /// 昨收价(单位:分) - /// - public decimal f60 { get; set; } - } - /// /// 从Tiingo获取股票价格(降级用) ///