feat: 组合列表增加今日涨跌额和持仓数量

- PortfolioListItem 新增 TodayProfit、TodayProfitCurrency 字段
- GetPortfolios 计算今日盈亏(从净值历史)
- Tags 显示持仓数量(如 '运行中 · USD · 3只')
This commit is contained in:
OpenClaw Agent 2026-03-15 23:51:32 +00:00
parent dcd212efa7
commit c7712e57bb
2 changed files with 50 additions and 14 deletions

View File

@ -176,6 +176,8 @@ public class PortfolioListItem
public string? Currency { get; set; } public string? Currency { get; set; }
public double ReturnRate { get; set; } public double ReturnRate { get; set; }
public string? ReturnType { get; set; } public string? ReturnType { get; set; }
public double TodayProfit { get; set; }
public string? TodayProfitCurrency { get; set; }
} }
/// <summary> /// <summary>

View File

@ -172,21 +172,55 @@ public class PortfolioService : IPortfolioService
.Where(p => p.UserId == userId) .Where(p => p.UserId == userId)
.ToList(); .ToList();
return portfolios.Select(p => new PortfolioListItem var result = new List<PortfolioListItem>();
foreach (var p in portfolios)
{
// 获取持仓数量
var positionCount = _db.Queryable<Position>()
.Where(pos => pos.PortfolioId == p.Id)
.Count();
// 获取今日盈亏(从净值历史)
var todayNav = _db.Queryable<PortfolioNavHistory>()
.Where(n => n.PortfolioId == p.Id && n.NavDate == DateTime.Today)
.First();
double todayProfit = 0;
if (todayNav != null && p.TotalValue > 0)
{
// 今日盈亏 = 今日市值 - 昨日市值
var yesterdayNav = _db.Queryable<PortfolioNavHistory>()
.Where(n => n.PortfolioId == p.Id && n.NavDate < DateTime.Today)
.OrderByDescending(n => n.NavDate)
.First();
if (yesterdayNav != null)
{
todayProfit = (double)(todayNav.TotalValue - yesterdayNav.TotalValue);
}
}
result.Add(new PortfolioListItem
{ {
Id = p.Id, Id = p.Id,
Name = p.Name, Name = p.Name,
Tags = $"{p.Status} · {p.Currency}", Tags = $"{p.Status} · {p.Currency}" + (positionCount > 0 ? $" · {positionCount}只" : ""),
Status = p.Status, Status = p.Status,
StatusType = p.Status == "运行中" ? "green" : "gray", StatusType = p.Status == "运行中" ? "green" : p.Status == "已暂停" ? "yellow" : "gray",
IconChar = p.Name?.Substring(0, 1).ToUpper() ?? "P", IconChar = p.Name?.Substring(0, 1).ToUpper() ?? "P",
IconBgClass = "bg-blue-100", IconBgClass = "bg-blue-100",
IconTextClass = "text-blue-700", IconTextClass = "text-blue-700",
Value = (double)p.TotalValue, Value = (double)p.TotalValue,
Currency = p.Currency, Currency = p.Currency,
ReturnRate = (double)p.ReturnRate, ReturnRate = (double)p.ReturnRate,
ReturnType = p.ReturnRate >= 0 ? "positive" : "negative" ReturnType = p.ReturnRate >= 0 ? "positive" : "negative",
}).ToList(); TodayProfit = todayProfit,
TodayProfitCurrency = p.Currency
});
}
return result;
} }
public async Task<TotalAssetsResponse> GetTotalAssetsAsync(string userId) public async Task<TotalAssetsResponse> GetTotalAssetsAsync(string userId)