From 8830dd17aeaba448ac723f32b45a38493c7a1d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=BE=E7=90=83?= Date: Fri, 6 Mar 2026 10:06:31 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=9E=B6=E6=9E=84=E6=95=B4?= =?UTF-8?q?=E6=94=B9=20-=20Ticker=20=E9=80=BB=E8=BE=91=E7=A7=BB=E5=88=B0?= =?UTF-8?q?=20Service=20=E5=B1=82=EF=BC=8CDTO=20=E7=8B=AC=E7=AB=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/TickerController.cs | 49 +++--------------- AssetManager.API/Program.cs | 1 + AssetManager.Models/DTOs/TickerDTO.cs | 13 +++++ AssetManager.Services/ITickerService.cs | 17 +++++++ AssetManager.Services/TickerService.cs | 51 +++++++++++++++++++ 5 files changed, 89 insertions(+), 42 deletions(-) create mode 100644 AssetManager.Models/DTOs/TickerDTO.cs create mode 100644 AssetManager.Services/ITickerService.cs create mode 100644 AssetManager.Services/TickerService.cs diff --git a/AssetManager.API/Controllers/TickerController.cs b/AssetManager.API/Controllers/TickerController.cs index f7f174f..022c79e 100644 --- a/AssetManager.API/Controllers/TickerController.cs +++ b/AssetManager.API/Controllers/TickerController.cs @@ -1,9 +1,9 @@ -using AssetManager.Data; using AssetManager.Models; +using AssetManager.Models.DTOs; +using AssetManager.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; -using SqlSugar; namespace AssetManager.API.Controllers; @@ -16,18 +16,18 @@ namespace AssetManager.API.Controllers; public class TickerController : ControllerBase { private readonly ILogger _logger; - private readonly ISqlSugarClient _db; + private readonly ITickerService _tickerService; - public TickerController(ILogger logger, ISqlSugarClient db) + public TickerController(ILogger logger, ITickerService tickerService) { _logger = logger; - _db = db; + _tickerService = tickerService; } /// /// 模糊搜索股票代码 /// - /// 搜索关键词(ticker 或 exchange) + /// 搜索关键词(ticker 或 exchange 或 name) /// 返回数量上限(默认 20) /// 匹配的股票代码列表 [HttpGet("search")] @@ -39,30 +39,7 @@ public class TickerController : ControllerBase { _logger.LogInformation($"Search ticker with keyword: {keyword}, limit: {limit}"); - if (string.IsNullOrWhiteSpace(keyword)) - { - return Ok(new ApiResponse> - { - code = AssetManager.Models.StatusCodes.Success, - data = new List(), - message = "Keyword is empty" - }); - } - - // 模糊搜索:ticker 包含 keyword 或者 exchange 包含 keyword 或者 name 包含 keyword - var results = await _db.Queryable() - .Where(t => t.Ticker.Contains(keyword) || t.Exchange.Contains(keyword) || (t.Name != null && t.Name.Contains(keyword))) - .Take(limit) - .OrderBy(t => t.Ticker) - .Select(t => new TickerSearchResult - { - Ticker = t.Ticker, - Name = t.Name, - Exchange = t.Exchange, - AssetType = t.AssetType, - PriceCurrency = t.PriceCurrency - }) - .ToListAsync(); + var results = await _tickerService.SearchTickerAsync(keyword, limit); return Ok(new ApiResponse> { @@ -84,15 +61,3 @@ public class TickerController : ControllerBase } } } - -/// -/// 股票代码搜索结果 -/// -public class TickerSearchResult -{ - public string? Ticker { get; set; } - public string? Name { get; set; } - public string? Exchange { get; set; } - public string? AssetType { get; set; } - public string? PriceCurrency { get; set; } -} diff --git a/AssetManager.API/Program.cs b/AssetManager.API/Program.cs index f285134..058f981 100644 --- a/AssetManager.API/Program.cs +++ b/AssetManager.API/Program.cs @@ -68,6 +68,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); // 市场数据服务:开发环境用 Mock,生产环境用 Alpaca if (builder.Environment.IsDevelopment()) diff --git a/AssetManager.Models/DTOs/TickerDTO.cs b/AssetManager.Models/DTOs/TickerDTO.cs new file mode 100644 index 0000000..51152e1 --- /dev/null +++ b/AssetManager.Models/DTOs/TickerDTO.cs @@ -0,0 +1,13 @@ +namespace AssetManager.Models.DTOs; + +/// +/// 股票代码搜索结果 +/// +public class TickerSearchResult +{ + public string? Ticker { get; set; } + public string? Name { get; set; } + public string? Exchange { get; set; } + public string? AssetType { get; set; } + public string? PriceCurrency { get; set; } +} diff --git a/AssetManager.Services/ITickerService.cs b/AssetManager.Services/ITickerService.cs new file mode 100644 index 0000000..416ec0a --- /dev/null +++ b/AssetManager.Services/ITickerService.cs @@ -0,0 +1,17 @@ +using AssetManager.Models.DTOs; + +namespace AssetManager.Services; + +/// +/// 股票代码服务接口 +/// +public interface ITickerService +{ + /// + /// 模糊搜索股票代码 + /// + /// 搜索关键词 + /// 返回数量上限 + /// 匹配的股票代码列表 + Task> SearchTickerAsync(string keyword, int limit = 20); +} diff --git a/AssetManager.Services/TickerService.cs b/AssetManager.Services/TickerService.cs new file mode 100644 index 0000000..f779840 --- /dev/null +++ b/AssetManager.Services/TickerService.cs @@ -0,0 +1,51 @@ +using AssetManager.Data; +using AssetManager.Models.DTOs; +using Microsoft.Extensions.Logging; +using SqlSugar; + +namespace AssetManager.Services; + +/// +/// 股票代码服务实现 +/// +public class TickerService : ITickerService +{ + private readonly ILogger _logger; + private readonly ISqlSugarClient _db; + + public TickerService(ILogger logger, ISqlSugarClient db) + { + _logger = logger; + _db = db; + } + + /// + /// 模糊搜索股票代码 + /// + public async Task> SearchTickerAsync(string keyword, int limit = 20) + { + _logger.LogInformation($"Search ticker with keyword: {keyword}, limit: {limit}"); + + if (string.IsNullOrWhiteSpace(keyword)) + { + return new List(); + } + + // 模糊搜索:ticker 包含 keyword 或者 exchange 包含 keyword 或者 name 包含 keyword + var results = await _db.Queryable() + .Where(t => t.Ticker.Contains(keyword) || t.Exchange.Contains(keyword) || (t.Name != null && t.Name.Contains(keyword))) + .Take(limit) + .OrderBy(t => t.Ticker) + .Select(t => new TickerSearchResult + { + Ticker = t.Ticker, + Name = t.Name, + Exchange = t.Exchange, + AssetType = t.AssetType, + PriceCurrency = t.PriceCurrency + }) + .ToListAsync(); + + return results; + } +}