149 lines
5.7 KiB
C#
149 lines
5.7 KiB
C#
using Bitget_Server.Api.Dtos;
|
|
using Bitget_Server.Application.Services;
|
|
using Bitget_Server.Infrastructure.Utils;
|
|
using Bitget_Server.Domain.Enums;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace Bitget_Server.Api.Controllers;
|
|
|
|
/// <summary>
|
|
/// 기존 WinForms MainForm 의 ComboBox / 텍스트박스 / API 선택 라디오버튼을 REST 화.
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/settings")]
|
|
[Produces("application/json")]
|
|
public class SettingsController : ControllerBase
|
|
{
|
|
private readonly SettingsService _settings;
|
|
|
|
public SettingsController(SettingsService settings)
|
|
{
|
|
_settings = settings;
|
|
}
|
|
|
|
// ===== 캔들 간격 =====
|
|
|
|
/// <summary>현재 선택된 캔들 간격(분)을 반환.</summary>
|
|
[HttpGet("candle-interval")]
|
|
[ProducesResponseType(typeof(CandleIntervalDto), StatusCodes.Status200OK)]
|
|
public ActionResult<CandleIntervalDto> GetCandleInterval()
|
|
{
|
|
var minutes = _settings.GetCandleIntervalMinutes();
|
|
var interval = (MCandleTimeType)minutes;
|
|
return Ok(new CandleIntervalDto(minutes, Convertor.GetEnumDescription(interval)));
|
|
}
|
|
|
|
/// <summary>캔들 간격을 변경.</summary>
|
|
[HttpPut("candle-interval")]
|
|
[ProducesResponseType(typeof(CandleIntervalDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
|
public ActionResult<CandleIntervalDto> UpdateCandleInterval([FromBody] UpdateCandleIntervalRequest req)
|
|
{
|
|
try
|
|
{
|
|
_settings.SetCandleIntervalMinutes(req.Minutes);
|
|
var interval = (MCandleTimeType)req.Minutes;
|
|
return Ok(new CandleIntervalDto(req.Minutes, Convertor.GetEnumDescription(interval)));
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
return Problem(detail: ex.Message, statusCode: StatusCodes.Status400BadRequest, title: "Invalid candle interval");
|
|
}
|
|
}
|
|
|
|
/// <summary>지원되는 캔들 간격 목록.</summary>
|
|
[HttpGet("candle-interval/options")]
|
|
[ProducesResponseType(typeof(IEnumerable<object>), StatusCodes.Status200OK)]
|
|
public ActionResult<IEnumerable<object>> ListCandleIntervals()
|
|
=> Ok(_settings.ListCandleIntervals());
|
|
|
|
// ===== 선택 코인 =====
|
|
|
|
[HttpGet("selected-coin")]
|
|
[ProducesResponseType(typeof(SelectedCoinDto), StatusCodes.Status200OK)]
|
|
public ActionResult<SelectedCoinDto> GetSelectedCoin()
|
|
=> Ok(new SelectedCoinDto(_settings.GetSelectedCoin()));
|
|
|
|
[HttpPut("selected-coin")]
|
|
[ProducesResponseType(typeof(SelectedCoinDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
|
public ActionResult<SelectedCoinDto> UpdateSelectedCoin([FromBody] UpdateSelectedCoinRequest req)
|
|
{
|
|
try
|
|
{
|
|
_settings.SetSelectedCoin(req.MarketName);
|
|
return Ok(new SelectedCoinDto(req.MarketName));
|
|
}
|
|
catch (ArgumentException ex)
|
|
{
|
|
return Problem(detail: ex.Message, statusCode: StatusCodes.Status400BadRequest, title: "Invalid coin");
|
|
}
|
|
}
|
|
|
|
// ===== 레버리지 =====
|
|
|
|
[HttpGet("leverage")]
|
|
[ProducesResponseType(typeof(LeverageDto), StatusCodes.Status200OK)]
|
|
public ActionResult<LeverageDto> GetLeverage()
|
|
=> Ok(new LeverageDto(_settings.GetLeverage()));
|
|
|
|
[HttpPut("leverage")]
|
|
[ProducesResponseType(typeof(LeverageDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
|
public ActionResult<LeverageDto> UpdateLeverage([FromBody] UpdateLeverageRequest req)
|
|
{
|
|
if (req.Leverage <= 0)
|
|
return Problem(detail: "Leverage must be > 0", statusCode: StatusCodes.Status400BadRequest, title: "Invalid leverage");
|
|
|
|
_settings.SetLeverage(req.Leverage);
|
|
return Ok(new LeverageDto(req.Leverage));
|
|
}
|
|
|
|
// ===== 주문 수량 =====
|
|
|
|
[HttpGet("order-amount")]
|
|
[ProducesResponseType(typeof(OrderAmountDto), StatusCodes.Status200OK)]
|
|
public ActionResult<OrderAmountDto> GetOrderAmount()
|
|
=> Ok(new OrderAmountDto(_settings.GetOrderAmount()));
|
|
|
|
[HttpPut("order-amount")]
|
|
[ProducesResponseType(typeof(OrderAmountDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
|
|
public ActionResult<OrderAmountDto> UpdateOrderAmount([FromBody] UpdateOrderAmountRequest req)
|
|
{
|
|
if (req.OrderAmount <= 0)
|
|
return Problem(detail: "OrderAmount must be > 0", statusCode: StatusCodes.Status400BadRequest, title: "Invalid order amount");
|
|
|
|
_settings.SetOrderAmount(req.OrderAmount);
|
|
return Ok(new OrderAmountDto(req.OrderAmount));
|
|
}
|
|
|
|
// ===== Selected API 키 =====
|
|
|
|
[HttpGet("api-key")]
|
|
[ProducesResponseType(typeof(SelectedApiDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
|
public ActionResult<SelectedApiDto> GetSelectedApi()
|
|
{
|
|
var id = _settings.GetSelectedApiId();
|
|
if (id == null) return NoContent();
|
|
return Ok(new SelectedApiDto(id.Value, string.Empty));
|
|
}
|
|
|
|
[HttpPut("api-key")]
|
|
[ProducesResponseType(typeof(SelectedApiDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
|
public ActionResult<SelectedApiDto> UpdateSelectedApi([FromBody] UpdateSelectedApiRequest req)
|
|
{
|
|
try
|
|
{
|
|
_settings.SetSelectedApiId(req.Id);
|
|
return Ok(new SelectedApiDto(req.Id, string.Empty));
|
|
}
|
|
catch (KeyNotFoundException ex)
|
|
{
|
|
return Problem(detail: ex.Message, statusCode: StatusCodes.Status404NotFound, title: "API key not found");
|
|
}
|
|
}
|
|
}
|