From e96547107f16390e5c7b5510cd5049d748ced18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=99=BE=E7=90=83?= Date: Fri, 6 Mar 2026 09:42:44 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20TickerController?= =?UTF-8?q?=20=E8=82=A1=E7=A5=A8=E4=BB=A3=E7=A0=81=E6=A8=A1=E7=B3=8A?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/TickerController.cs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 AssetManager.API/Controllers/TickerController.cs diff --git a/AssetManager.API/Controllers/TickerController.cs b/AssetManager.API/Controllers/TickerController.cs new file mode 100644 index 0000000..4b024f1 --- /dev/null +++ b/AssetManager.API/Controllers/TickerController.cs @@ -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; + +/// +/// 股票代码查询接口 +/// +[ApiController] +[Route("api/v1/ticker")] +[Authorize] +public class TickerController : ControllerBase +{ + private readonly ILogger _logger; + private readonly ISqlSugarClient _db; + + public TickerController(ILogger logger, ISqlSugarClient db) + { + _logger = logger; + _db = db; + } + + /// + /// 模糊搜索股票代码 + /// + /// 搜索关键词(ticker 或 exchange) + /// 返回数量上限(默认 20) + /// 匹配的股票代码列表 + [HttpGet("search")] + public async Task>>> 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> + { + code = AssetManager.Models.StatusCodes.Success, + data = new List(), + message = "Keyword is empty" + }); + } + + // 模糊搜索:ticker 包含 keyword 或者 exchange 包含 keyword + var results = await _db.Queryable() + .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> + { + 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> + { + code = AssetManager.Models.StatusCodes.InternalServerError, + data = null, + message = ex.Message + }); + } + } +} + +/// +/// 股票代码搜索结果 +/// +public class TickerSearchResult +{ + public string? Ticker { get; set; } + public string? Exchange { get; set; } + public string? AssetType { get; set; } + public string? PriceCurrency { get; set; } +}