P0 实现全局异常处理中间件:移除所有Controller重复try-catch,统一异常响应
This commit is contained in:
parent
949fa8e85b
commit
89244fc078
@ -52,88 +52,74 @@ public class PortfolioController : ControllerBase
|
||||
[HttpPost]
|
||||
public ActionResult<ApiResponse<CreatePortfolioResponse>> CreatePortfolio([FromBody] CreatePortfolioRequest request)
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to create portfolio");
|
||||
_logger.LogInformation("Request to create portfolio");
|
||||
|
||||
// 1. 获取用户默认币种
|
||||
var db = _databaseService.GetDb();
|
||||
var user = db.Queryable<User>().Where(u => u.Id == userId).First();
|
||||
if (user == null)
|
||||
// 1. 获取用户默认币种
|
||||
var db = _databaseService.GetDb();
|
||||
var user = db.Queryable<User>().Where(u => u.Id == userId).First();
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
return NotFound(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "用户不存在"
|
||||
});
|
||||
}
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "用户不存在"
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 校验组合币种,如果没传则用用户默认币种
|
||||
if (string.IsNullOrEmpty(request.currency))
|
||||
// 2. 校验组合币种,如果没传则用用户默认币种
|
||||
if (string.IsNullOrEmpty(request.currency))
|
||||
{
|
||||
request.currency = user.DefaultCurrency;
|
||||
}
|
||||
if (!CurrencyHelper.IsSupported(request.currency))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
request.currency = user.DefaultCurrency;
|
||||
}
|
||||
if (!CurrencyHelper.IsSupported(request.currency))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的组合币种: {request.currency},支持的币种: {string.Join(", ", CurrencyHelper.GetSupportedCurrencies())}"
|
||||
});
|
||||
}
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的组合币种: {request.currency},支持的币种: {string.Join(", ", CurrencyHelper.GetSupportedCurrencies())}"
|
||||
});
|
||||
}
|
||||
|
||||
// 3. 校验持仓币种
|
||||
if (request.stocks != null)
|
||||
// 3. 校验持仓币种
|
||||
if (request.stocks != null)
|
||||
{
|
||||
foreach (var stock in request.stocks)
|
||||
{
|
||||
foreach (var stock in request.stocks)
|
||||
if (!string.IsNullOrEmpty(stock.currency) && !CurrencyHelper.IsSupported(stock.currency))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(stock.currency) && !CurrencyHelper.IsSupported(stock.currency))
|
||||
return BadRequest(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的持仓币种: {stock.currency}(标的: {stock.code}),支持的币种: {string.Join(", ", CurrencyHelper.GetSupportedCurrencies())}"
|
||||
});
|
||||
}
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的持仓币种: {stock.currency}(标的: {stock.code}),支持的币种: {string.Join(", ", CurrencyHelper.GetSupportedCurrencies())}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var response = _portfolioService.CreatePortfolio(request, userId);
|
||||
}
|
||||
|
||||
var response = _portfolioService.CreatePortfolio(request, userId);
|
||||
|
||||
_logger.LogInformation("Portfolio created successfully");
|
||||
|
||||
return Ok(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
_logger.LogInformation("Portfolio created successfully");
|
||||
|
||||
return Ok(new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
_logger.LogError(ex, "Error creating portfolio");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<CreatePortfolioResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
});
|
||||
}
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -143,43 +129,29 @@ public class PortfolioController : ControllerBase
|
||||
[HttpGet]
|
||||
public ActionResult<ApiResponse<GetPortfoliosResponse>> GetPortfolios()
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<GetPortfoliosResponse>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<GetPortfoliosResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to get portfolios");
|
||||
|
||||
var response = _portfolioService.GetPortfolios(userId);
|
||||
|
||||
_logger.LogInformation("Portfolios retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<GetPortfoliosResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = new GetPortfoliosResponse { items = response },
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error retrieving portfolios");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<GetPortfoliosResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to get portfolios");
|
||||
|
||||
var response = _portfolioService.GetPortfolios(userId);
|
||||
|
||||
_logger.LogInformation("Portfolios retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<GetPortfoliosResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = new GetPortfoliosResponse { items = response },
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -189,43 +161,29 @@ public class PortfolioController : ControllerBase
|
||||
[HttpGet("assets")]
|
||||
public ActionResult<ApiResponse<TotalAssetsResponse>> GetTotalAssets()
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<TotalAssetsResponse>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<TotalAssetsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to get total assets");
|
||||
|
||||
var response = _portfolioService.GetTotalAssets(userId);
|
||||
|
||||
_logger.LogInformation("Total assets retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<TotalAssetsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error retrieving total assets");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<TotalAssetsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to get total assets");
|
||||
|
||||
var response = _portfolioService.GetTotalAssets(userId);
|
||||
|
||||
_logger.LogInformation("Total assets retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<TotalAssetsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -236,43 +194,29 @@ public class PortfolioController : ControllerBase
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<PortfolioDetailResponse>>> GetPortfolioById(string id)
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<PortfolioDetailResponse>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<PortfolioDetailResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Request to get portfolio by id: {id}");
|
||||
|
||||
var response = await _portfolioService.GetPortfolioByIdAsync(id, userId);
|
||||
|
||||
_logger.LogInformation("Portfolio retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<PortfolioDetailResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error retrieving portfolio");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<PortfolioDetailResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Request to get portfolio by id: {id}");
|
||||
|
||||
var response = await _portfolioService.GetPortfolioByIdAsync(id, userId);
|
||||
|
||||
_logger.LogInformation("Portfolio retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<PortfolioDetailResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -285,43 +229,29 @@ public class PortfolioController : ControllerBase
|
||||
[HttpGet("transactions")]
|
||||
public ActionResult<ApiResponse<GetTransactionsResponse>> GetTransactions([FromQuery] string portfolioId, [FromQuery] int limit = 10, [FromQuery] int offset = 0)
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<GetTransactionsResponse>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<GetTransactionsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Request to get transactions for portfolio: {portfolioId}");
|
||||
|
||||
var response = _portfolioService.GetTransactions(portfolioId, userId, limit, offset);
|
||||
|
||||
_logger.LogInformation("Transactions retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<GetTransactionsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error retrieving transactions");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<GetTransactionsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Request to get transactions for portfolio: {portfolioId}");
|
||||
|
||||
var response = _portfolioService.GetTransactions(portfolioId, userId, limit, offset);
|
||||
|
||||
_logger.LogInformation("Transactions retrieved successfully");
|
||||
|
||||
return Ok(new ApiResponse<GetTransactionsResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -332,90 +262,76 @@ public class PortfolioController : ControllerBase
|
||||
[HttpPost("transactions")]
|
||||
public ActionResult<ApiResponse<CreateTransactionResponse>> CreateTransaction([FromBody] CreateTransactionRequest request)
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to create transaction");
|
||||
|
||||
// 校验交易币种
|
||||
if (!string.IsNullOrEmpty(request.currency) && !CurrencyHelper.IsSupported(request.currency))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的交易币种: {request.currency},支持的币种: {string.Join(", ", CurrencyHelper.GetSupportedCurrencies())}"
|
||||
});
|
||||
}
|
||||
|
||||
// 校验交易币种必须和组合本位币一致
|
||||
var portfolio = _databaseService.GetDb().Queryable<Portfolio>().Where(p => p.Id == request.portfolioId && p.UserId == userId).First();
|
||||
if (portfolio == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "投资组合不存在"
|
||||
});
|
||||
}
|
||||
if (!string.IsNullOrEmpty(request.currency) && !request.currency.Equals(portfolio.Currency, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"该组合本位币为 {portfolio.Currency},只能添加相同币种的标的"
|
||||
});
|
||||
}
|
||||
|
||||
// 校验资产类型
|
||||
if (!string.IsNullOrEmpty(request.assetType))
|
||||
{
|
||||
var validAssetTypes = new[] { "Stock", "Crypto" };
|
||||
if (!validAssetTypes.Contains(request.assetType, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的资产类型: {request.assetType},支持的类型: {string.Join(", ", validAssetTypes)}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var response = _portfolioService.CreateTransaction(request, userId);
|
||||
|
||||
_logger.LogInformation("Transaction created successfully");
|
||||
|
||||
return Ok(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error creating transaction");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to create transaction");
|
||||
|
||||
// 校验交易币种
|
||||
if (!string.IsNullOrEmpty(request.currency) && !CurrencyHelper.IsSupported(request.currency))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的交易币种: {request.currency},支持的币种: {string.Join(", ", CurrencyHelper.GetSupportedCurrencies())}"
|
||||
});
|
||||
}
|
||||
|
||||
// 校验交易币种必须和组合本位币一致
|
||||
var portfolio = _databaseService.GetDb().Queryable<Portfolio>().Where(p => p.Id == request.portfolioId && p.UserId == userId).First();
|
||||
if (portfolio == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "投资组合不存在"
|
||||
});
|
||||
}
|
||||
if (!string.IsNullOrEmpty(request.currency) && !request.currency.Equals(portfolio.Currency, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"该组合本位币为 {portfolio.Currency},只能添加相同币种的标的"
|
||||
});
|
||||
}
|
||||
|
||||
// 校验资产类型
|
||||
if (!string.IsNullOrEmpty(request.assetType))
|
||||
{
|
||||
var validAssetTypes = new[] { "Stock", "Crypto" };
|
||||
if (!validAssetTypes.Contains(request.assetType, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
return BadRequest(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.BadRequest,
|
||||
data = null,
|
||||
message = $"不支持的资产类型: {request.assetType},支持的类型: {string.Join(", ", validAssetTypes)}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var response = _portfolioService.CreateTransaction(request, userId);
|
||||
|
||||
_logger.LogInformation("Transaction created successfully");
|
||||
|
||||
return Ok(new ApiResponse<CreateTransactionResponse>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = response,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -426,80 +342,66 @@ public class PortfolioController : ControllerBase
|
||||
[HttpGet("{id}/signal")]
|
||||
public async Task<ActionResult<ApiResponse<StrategySignal>>> GetPortfolioSignal(string id)
|
||||
{
|
||||
try
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
return Unauthorized(new ApiResponse<StrategySignal>
|
||||
{
|
||||
return Unauthorized(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to get portfolio signal: {PortfolioId}", id);
|
||||
|
||||
// 1. 获取投资组合
|
||||
var portfolio = _databaseService.GetPortfolioById(id, userId);
|
||||
if (portfolio == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "投资组合不存在"
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 获取策略
|
||||
if (portfolio.StrategyId == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "策略ID不存在"
|
||||
});
|
||||
}
|
||||
var strategy = _strategyService.GetStrategyById(portfolio.StrategyId, userId);
|
||||
if (strategy == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "策略不存在"
|
||||
});
|
||||
}
|
||||
|
||||
// 3. 获取持仓
|
||||
var positions = _databaseService.GetPositionsByPortfolioId(id);
|
||||
|
||||
// 4. 计算策略信号
|
||||
var signal = await _strategyEngine.CalculateSignalAsync(strategy, positions);
|
||||
|
||||
_logger.LogInformation("Portfolio signal retrieved successfully: {PortfolioId}", id);
|
||||
|
||||
return Ok(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = signal,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error getting portfolio signal: {PortfolioId}", id);
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = null,
|
||||
message = ex.Message
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation("Request to get portfolio signal: {PortfolioId}", id);
|
||||
|
||||
// 1. 获取投资组合
|
||||
var portfolio = _databaseService.GetPortfolioById(id, userId);
|
||||
if (portfolio == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "投资组合不存在"
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 获取策略
|
||||
if (portfolio.StrategyId == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "策略ID不存在"
|
||||
});
|
||||
}
|
||||
var strategy = _strategyService.GetStrategyById(portfolio.StrategyId, userId);
|
||||
if (strategy == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = null,
|
||||
message = "策略不存在"
|
||||
});
|
||||
}
|
||||
|
||||
// 3. 获取持仓
|
||||
var positions = _databaseService.GetPositionsByPortfolioId(id);
|
||||
|
||||
// 4. 计算策略信号
|
||||
var signal = await _strategyEngine.CalculateSignalAsync(strategy, positions);
|
||||
|
||||
_logger.LogInformation("Portfolio signal retrieved successfully: {PortfolioId}", id);
|
||||
|
||||
return Ok(new ApiResponse<StrategySignal>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = signal,
|
||||
message = "success"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -510,85 +412,71 @@ public class PortfolioController : ControllerBase
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<ActionResult<ApiResponse<bool>>> DeletePortfolio(string id)
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
return Unauthorized(new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = false,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Request to delete portfolio: {id}");
|
||||
|
||||
var db = _databaseService.GetDb();
|
||||
|
||||
// 校验组合是否存在且属于当前用户
|
||||
var portfolio = db.Queryable<Portfolio>()
|
||||
.Where(p => p.Id == id && p.UserId == userId)
|
||||
.First();
|
||||
|
||||
if (portfolio == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = false,
|
||||
message = "投资组合不存在或无权限删除"
|
||||
});
|
||||
}
|
||||
|
||||
// 开启事务删除相关数据
|
||||
db.Ado.BeginTran();
|
||||
try
|
||||
{
|
||||
var userId = GetCurrentUserId();
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
return Unauthorized(new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Unauthorized,
|
||||
data = false,
|
||||
message = "用户未授权"
|
||||
});
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Request to delete portfolio: {id}");
|
||||
// 删除交易记录
|
||||
db.Deleteable<Transaction>()
|
||||
.Where(t => t.PortfolioId == id)
|
||||
.ExecuteCommand();
|
||||
|
||||
var db = _databaseService.GetDb();
|
||||
// 删除持仓
|
||||
db.Deleteable<Position>()
|
||||
.Where(p => p.PortfolioId == id)
|
||||
.ExecuteCommand();
|
||||
|
||||
// 校验组合是否存在且属于当前用户
|
||||
var portfolio = db.Queryable<Portfolio>()
|
||||
.Where(p => p.Id == id && p.UserId == userId)
|
||||
.First();
|
||||
// 删除组合本身
|
||||
db.Deleteable<Portfolio>()
|
||||
.Where(p => p.Id == id)
|
||||
.ExecuteCommand();
|
||||
|
||||
if (portfolio == null)
|
||||
{
|
||||
return NotFound(new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.NotFound,
|
||||
data = false,
|
||||
message = "投资组合不存在或无权限删除"
|
||||
});
|
||||
}
|
||||
|
||||
// 开启事务删除相关数据
|
||||
db.Ado.BeginTran();
|
||||
try
|
||||
{
|
||||
// 删除交易记录
|
||||
db.Deleteable<Transaction>()
|
||||
.Where(t => t.PortfolioId == id)
|
||||
.ExecuteCommand();
|
||||
|
||||
// 删除持仓
|
||||
db.Deleteable<Position>()
|
||||
.Where(p => p.PortfolioId == id)
|
||||
.ExecuteCommand();
|
||||
|
||||
// 删除组合本身
|
||||
db.Deleteable<Portfolio>()
|
||||
.Where(p => p.Id == id)
|
||||
.ExecuteCommand();
|
||||
|
||||
db.Ado.CommitTran();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
db.Ado.RollbackTran();
|
||||
_logger.LogError(ex, "删除投资组合事务失败");
|
||||
throw;
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Portfolio {id} deleted successfully");
|
||||
|
||||
return Ok(new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = true,
|
||||
message = "删除成功"
|
||||
});
|
||||
db.Ado.CommitTran();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error deleting portfolio");
|
||||
|
||||
return StatusCode(AssetManager.Models.StatusCodes.InternalServerError, new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.InternalServerError,
|
||||
data = false,
|
||||
message = ex.Message
|
||||
});
|
||||
db.Ado.RollbackTran();
|
||||
_logger.LogError(ex, "删除投资组合事务失败");
|
||||
throw;
|
||||
}
|
||||
|
||||
_logger.LogInformation($"Portfolio {id} deleted successfully");
|
||||
|
||||
return Ok(new ApiResponse<bool>
|
||||
{
|
||||
code = AssetManager.Models.StatusCodes.Success,
|
||||
data = true,
|
||||
message = "删除成功"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
80
AssetManager.API/Middleware/GlobalExceptionMiddleware.cs
Normal file
80
AssetManager.API/Middleware/GlobalExceptionMiddleware.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using AssetManager.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AssetManager.API.Middleware;
|
||||
|
||||
/// <summary>
|
||||
/// 全局异常处理中间件:统一捕获所有API异常,返回标准格式响应
|
||||
/// </summary>
|
||||
public class GlobalExceptionMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ILogger<GlobalExceptionMiddleware> _logger;
|
||||
|
||||
public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger)
|
||||
{
|
||||
_next = next;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "请求处理异常: {Path}", context.Request.Path);
|
||||
await HandleExceptionAsync(context, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
|
||||
{
|
||||
context.Response.ContentType = "application/json";
|
||||
var response = new ApiResponse<object>
|
||||
{
|
||||
code = StatusCodes.Status500InternalServerError,
|
||||
data = null,
|
||||
message = exception.Message
|
||||
};
|
||||
|
||||
// 根据异常类型设置不同的状态码
|
||||
switch (exception)
|
||||
{
|
||||
case UnauthorizedAccessException _:
|
||||
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
response.code = StatusCodes.Status401Unauthorized;
|
||||
response.message = "未授权访问";
|
||||
break;
|
||||
case ArgumentException _:
|
||||
case InvalidOperationException _:
|
||||
context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
|
||||
response.code = StatusCodes.Status400BadRequest;
|
||||
break;
|
||||
case KeyNotFoundException _:
|
||||
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
response.code = StatusCodes.Status404NotFound;
|
||||
break;
|
||||
default:
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
response.code = StatusCodes.Status500InternalServerError;
|
||||
// 生产环境可以隐藏具体错误信息,避免泄露敏感信息
|
||||
// response.message = "服务器内部错误";
|
||||
break;
|
||||
}
|
||||
|
||||
var result = JsonSerializer.Serialize(response, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
});
|
||||
|
||||
return context.Response.WriteAsync(result);
|
||||
}
|
||||
}
|
||||
@ -115,6 +115,9 @@ var app = builder.Build();
|
||||
// 初始化数据库
|
||||
app.Services.InitializeDatabase();
|
||||
|
||||
// 全局异常处理中间件(必须放在最前面)
|
||||
app.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user