refactor: 架构整改 - Ticker 逻辑移到 Service 层,DTO 独立
This commit is contained in:
parent
86e073add7
commit
8830dd17ae
@ -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<TickerController> _logger;
|
||||
private readonly ISqlSugarClient _db;
|
||||
private readonly ITickerService _tickerService;
|
||||
|
||||
public TickerController(ILogger<TickerController> logger, ISqlSugarClient db)
|
||||
public TickerController(ILogger<TickerController> logger, ITickerService tickerService)
|
||||
{
|
||||
_logger = logger;
|
||||
_db = db;
|
||||
_tickerService = tickerService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模糊搜索股票代码
|
||||
/// </summary>
|
||||
/// <param name="keyword">搜索关键词(ticker 或 exchange)</param>
|
||||
/// <param name="keyword">搜索关键词(ticker 或 exchange 或 name)</param>
|
||||
/// <param name="limit">返回数量上限(默认 20)</param>
|
||||
/// <returns>匹配的股票代码列表</returns>
|
||||
[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<List<TickerSearchResult>>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = new List<TickerSearchResult>(),
|
||||
message = "Keyword is empty"
|
||||
});
|
||||
}
|
||||
|
||||
// 模糊搜索:ticker 包含 keyword 或者 exchange 包含 keyword 或者 name 包含 keyword
|
||||
var results = await _db.Queryable<TiingoTicker>()
|
||||
.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<List<TickerSearchResult>>
|
||||
{
|
||||
@ -84,15 +61,3 @@ public class TickerController : ControllerBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 股票代码搜索结果
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ builder.Services.AddScoped<AssetManager.Services.Services.WechatService>();
|
||||
builder.Services.AddScoped<AssetManager.Services.Services.JwtService>();
|
||||
builder.Services.AddScoped<AssetManager.Services.IPortfolioService, AssetManager.Services.PortfolioService>();
|
||||
builder.Services.AddScoped<AssetManager.Services.IStrategyService, AssetManager.Services.StrategyService>();
|
||||
builder.Services.AddScoped<AssetManager.Services.ITickerService, AssetManager.Services.TickerService>();
|
||||
|
||||
// 市场数据服务:开发环境用 Mock,生产环境用 Alpaca
|
||||
if (builder.Environment.IsDevelopment())
|
||||
|
||||
13
AssetManager.Models/DTOs/TickerDTO.cs
Normal file
13
AssetManager.Models/DTOs/TickerDTO.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace AssetManager.Models.DTOs;
|
||||
|
||||
/// <summary>
|
||||
/// 股票代码搜索结果
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
17
AssetManager.Services/ITickerService.cs
Normal file
17
AssetManager.Services/ITickerService.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using AssetManager.Models.DTOs;
|
||||
|
||||
namespace AssetManager.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 股票代码服务接口
|
||||
/// </summary>
|
||||
public interface ITickerService
|
||||
{
|
||||
/// <summary>
|
||||
/// 模糊搜索股票代码
|
||||
/// </summary>
|
||||
/// <param name="keyword">搜索关键词</param>
|
||||
/// <param name="limit">返回数量上限</param>
|
||||
/// <returns>匹配的股票代码列表</returns>
|
||||
Task<List<TickerSearchResult>> SearchTickerAsync(string keyword, int limit = 20);
|
||||
}
|
||||
51
AssetManager.Services/TickerService.cs
Normal file
51
AssetManager.Services/TickerService.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using AssetManager.Data;
|
||||
using AssetManager.Models.DTOs;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SqlSugar;
|
||||
|
||||
namespace AssetManager.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 股票代码服务实现
|
||||
/// </summary>
|
||||
public class TickerService : ITickerService
|
||||
{
|
||||
private readonly ILogger<TickerService> _logger;
|
||||
private readonly ISqlSugarClient _db;
|
||||
|
||||
public TickerService(ILogger<TickerService> logger, ISqlSugarClient db)
|
||||
{
|
||||
_logger = logger;
|
||||
_db = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模糊搜索股票代码
|
||||
/// </summary>
|
||||
public async Task<List<TickerSearchResult>> SearchTickerAsync(string keyword, int limit = 20)
|
||||
{
|
||||
_logger.LogInformation($"Search ticker with keyword: {keyword}, limit: {limit}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(keyword))
|
||||
{
|
||||
return new List<TickerSearchResult>();
|
||||
}
|
||||
|
||||
// 模糊搜索:ticker 包含 keyword 或者 exchange 包含 keyword 或者 name 包含 keyword
|
||||
var results = await _db.Queryable<TiingoTicker>()
|
||||
.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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user