refactor(PortfolioService): 重构组合服务方法并优化事务处理

- 将同步方法改为异步方法
- 移除冗余注释并优化代码结构
- 统一事务处理方法调用
- 调整参数命名以提高可读性
This commit is contained in:
niannian zheng 2026-03-25 15:23:09 +08:00
parent 02e199faf2
commit 7d37ef5561
2 changed files with 13 additions and 21 deletions

View File

@ -102,7 +102,8 @@ public class PortfolioFacade : IPortfolioFacade
public async Task<List<TransactionItem>> GetTransactionsAsync(string portfolioId, GetTransactionsRequest request, string userId) public async Task<List<TransactionItem>> GetTransactionsAsync(string portfolioId, GetTransactionsRequest request, string userId)
{ {
_logger.LogInformation("获取交易列表: {PortfolioId}", portfolioId); _logger.LogInformation("获取交易列表: {PortfolioId}", portfolioId);
return await _portfolioService.GetTransactionsAsync(portfolioId, request, userId); var response = await _portfolioService.GetTransactionsAsync(portfolioId, userId, request.Limit, request.Offset);
return response.Items ?? new List<TransactionItem>();
} }
public async Task<StrategySignalResponse> GetStrategySignalAsync(string portfolioId, string userId) public async Task<StrategySignalResponse> GetStrategySignalAsync(string portfolioId, string userId)

View File

@ -28,7 +28,7 @@ public class PortfolioService : IPortfolioService
_logger = logger; _logger = logger;
} }
public CreatePortfolioResponse CreatePortfolio(CreatePortfolioRequest request, string userId) public async Task<CreatePortfolioResponse> CreatePortfolioAsync(CreatePortfolioRequest request, string userId)
{ {
var portfolio = new Portfolio var portfolio = new Portfolio
{ {
@ -79,8 +79,8 @@ public class PortfolioService : IPortfolioService
{ {
Code = asset.Symbol, Code = asset.Symbol,
Name = asset.Symbol, Name = asset.Symbol,
Price = 0, // 价格留空,用户后续填写 Price = 0,
Amount = 0, // 数量留空,用户后续填写 Amount = 0,
Currency = request.Currency, Currency = request.Currency,
AssetType = "Stock" AssetType = "Stock"
}); });
@ -88,7 +88,6 @@ public class PortfolioService : IPortfolioService
} }
} }
} }
// 其他策略类型可以在这里扩展
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -108,7 +107,6 @@ public class PortfolioService : IPortfolioService
continue; continue;
} }
// 解析实际买入时间,如果解析失败则用当前时间
DateTime buyTime = DateTime.Now; DateTime buyTime = DateTime.Now;
if (!string.IsNullOrEmpty(stock.Date)) if (!string.IsNullOrEmpty(stock.Date))
{ {
@ -127,8 +125,8 @@ public class PortfolioService : IPortfolioService
AssetType = string.IsNullOrEmpty(stock.AssetType) ? "Stock" : stock.AssetType, AssetType = string.IsNullOrEmpty(stock.AssetType) ? "Stock" : stock.AssetType,
Shares = (decimal)stock.Amount, Shares = (decimal)stock.Amount,
AvgPrice = (decimal)stock.Price, AvgPrice = (decimal)stock.Price,
TotalCost = (decimal)(stock.Price * stock.Amount), // 初始成本 = 价格 × 数量 TotalCost = (decimal)(stock.Price * stock.Amount),
Currency = stock.Currency ?? request.Currency, // 使用持仓币种,而非组合本位币 Currency = stock.Currency ?? request.Currency,
CreatedAt = buyTime, CreatedAt = buyTime,
UpdatedAt = DateTime.Now UpdatedAt = DateTime.Now
}; };
@ -138,12 +136,10 @@ public class PortfolioService : IPortfolioService
_db.Insertable(position).ExecuteCommand(); _db.Insertable(position).ExecuteCommand();
// 创建交易记录(保存汇率信息)
decimal totalAmount = (decimal)(stock.Price * stock.Amount); decimal totalAmount = (decimal)(stock.Price * stock.Amount);
decimal? exchangeRate = null; decimal? exchangeRate = null;
decimal? totalAmountBase = null; decimal? totalAmountBase = null;
// 如果持仓币种与组合币种不同,需要保存汇率
if (!string.IsNullOrEmpty(stock.Currency) && !stock.Currency.Equals(request.Currency, StringComparison.OrdinalIgnoreCase)) if (!string.IsNullOrEmpty(stock.Currency) && !stock.Currency.Equals(request.Currency, StringComparison.OrdinalIgnoreCase))
{ {
exchangeRate = await _exchangeRateService.GetExchangeRateAsync(stock.Currency, request.Currency); exchangeRate = await _exchangeRateService.GetExchangeRateAsync(stock.Currency, request.Currency);
@ -459,10 +455,10 @@ public class PortfolioService : IPortfolioService
}; };
} }
public async Task<PortfolioDetailResponse> GetPortfolioByIdAsync(string id, string userId) public async Task<PortfolioDetailResponse> GetPortfolioDetailAsync(string portfolioId, string userId)
{ {
var portfolio = _db.Queryable<Portfolio>() var portfolio = _db.Queryable<Portfolio>()
.Where(p => p.Id == id && p.UserId == userId) .Where(p => p.Id == portfolioId && p.UserId == userId)
.First(); .First();
if (portfolio == null) if (portfolio == null)
@ -471,7 +467,7 @@ public class PortfolioService : IPortfolioService
} }
var Positions = _db.Queryable<Position>() var Positions = _db.Queryable<Position>()
.Where(pos => pos.PortfolioId == id) .Where(pos => pos.PortfolioId == portfolioId)
.ToList(); .ToList();
// 获取每个持仓的实时价格并转换为组合本位币 // 获取每个持仓的实时价格并转换为组合本位币
@ -723,7 +719,7 @@ public class PortfolioService : IPortfolioService
// 使用事务包裹所有数据库操作 // 使用事务包裹所有数据库操作
try try
{ {
_db.BeginTran(); _db.Ado.BeginTran();
// 1. 插入交易记录 // 1. 插入交易记录
_db.Insertable(transaction).ExecuteCommand(); _db.Insertable(transaction).ExecuteCommand();
@ -737,7 +733,6 @@ public class PortfolioService : IPortfolioService
{ {
if (request.Type == "buy") if (request.Type == "buy")
{ {
// 计算新的平均价格和总成本
var buyAmount = (decimal)request.Amount * (decimal)request.Price; var buyAmount = (decimal)request.Amount * (decimal)request.Price;
var newTotalShares = position.Shares + (decimal)request.Amount; var newTotalShares = position.Shares + (decimal)request.Amount;
var newTotalCost = position.TotalCost + buyAmount; var newTotalCost = position.TotalCost + buyAmount;
@ -753,7 +748,6 @@ public class PortfolioService : IPortfolioService
} }
else if (request.Type == "sell") else if (request.Type == "sell")
{ {
// 按比例减少成本
var sellRatio = (decimal)request.Amount / position.Shares; var sellRatio = (decimal)request.Amount / position.Shares;
var costToReduce = position.TotalCost * sellRatio; var costToReduce = position.TotalCost * sellRatio;
@ -776,7 +770,6 @@ public class PortfolioService : IPortfolioService
} }
else if (request.Type == "buy") else if (request.Type == "buy")
{ {
// 创建新持仓
position = new Position position = new Position
{ {
Id = "pos-" + Guid.NewGuid().ToString().Substring(0, 8), Id = "pos-" + Guid.NewGuid().ToString().Substring(0, 8),
@ -811,7 +804,6 @@ public class PortfolioService : IPortfolioService
continue; continue;
} }
// 获取实时价格(异步调用),失败则降级使用成本价
decimal CurrentPrice = pos.AvgPrice; decimal CurrentPrice = pos.AvgPrice;
try try
{ {
@ -833,12 +825,11 @@ public class PortfolioService : IPortfolioService
portfolio.UpdatedAt = DateTime.Now; portfolio.UpdatedAt = DateTime.Now;
_db.Updateable(portfolio).ExecuteCommand(); _db.Updateable(portfolio).ExecuteCommand();
// 提交事务 _db.Ado.CommitTran();
_db.CommitTran();
} }
catch (Exception ex) catch (Exception ex)
{ {
_db.RollbackTran(); _db.Ado.RollbackTran();
_logger.LogError(ex, "创建交易失败,已回滚: {PortfolioId}, {StockCode}", request.PortfolioId, request.StockCode); _logger.LogError(ex, "创建交易失败,已回滚: {PortfolioId}, {StockCode}", request.PortfolioId, request.StockCode);
throw; throw;
} }