feat: 添加 TickerController 股票代码模糊搜索接口

This commit is contained in:
虾球 2026-03-06 09:42:44 +00:00
parent 0a053906ef
commit e96547107f

View File

@ -0,0 +1,96 @@
using AssetManager.Data;
using AssetManager.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
namespace AssetManager.API.Controllers;
/// <summary>
/// 股票代码查询接口
/// </summary>
[ApiController]
[Route("api/v1/ticker")]
[Authorize]
public class TickerController : ControllerBase
{
private readonly ILogger<TickerController> _logger;
private readonly ISqlSugarClient _db;
public TickerController(ILogger<TickerController> logger, ISqlSugarClient db)
{
_logger = logger;
_db = db;
}
/// <summary>
/// 模糊搜索股票代码
/// </summary>
/// <param name="keyword">搜索关键词ticker 或 exchange</param>
/// <param name="limit">返回数量上限(默认 20</param>
/// <returns>匹配的股票代码列表</returns>
[HttpGet("search")]
public async Task<ActionResult<ApiResponse<List<TickerSearchResult>>>> SearchTicker(
[FromQuery] string keyword,
[FromQuery] int limit = 20)
{
try
{
_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
var results = await _db.Queryable<TiingoTicker>()
.Where(t => t.Ticker.Contains(keyword) || t.Exchange.Contains(keyword))
.Take(limit)
.OrderBy(t => t.Ticker)
.Select(t => new TickerSearchResult
{
Ticker = t.Ticker,
Exchange = t.Exchange,
AssetType = t.AssetType,
PriceCurrency = t.PriceCurrency
})
.ToListAsync();
return Ok(new ApiResponse<List<TickerSearchResult>>
{
code = AssetManager.Models.StatusCodes.Success,
data = results,
message = "Success"
});
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error searching ticker with keyword: {keyword}");
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<List<TickerSearchResult>>
{
code = AssetManager.Models.StatusCodes.InternalServerError,
data = null,
message = ex.Message
});
}
}
}
/// <summary>
/// 股票代码搜索结果
/// </summary>
public class TickerSearchResult
{
public string? Ticker { get; set; }
public string? Exchange { get; set; }
public string? AssetType { get; set; }
public string? PriceCurrency { get; set; }
}