From c7712e57bb4171c979c7649406b6d032e007ffaa Mon Sep 17 00:00:00 2001 From: OpenClaw Agent Date: Sun, 15 Mar 2026 23:51:32 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BB=84=E5=90=88=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=8A=E6=97=A5=E6=B6=A8=E8=B7=8C=E9=A2=9D?= =?UTF-8?q?=E5=92=8C=E6=8C=81=E4=BB=93=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PortfolioListItem 新增 TodayProfit、TodayProfitCurrency 字段 - GetPortfolios 计算今日盈亏(从净值历史) - Tags 显示持仓数量(如 '运行中 · USD · 3只') --- AssetManager.Models/DTOs/PortfolioDTO.cs | 2 + AssetManager.Services/PortfolioService.cs | 62 ++++++++++++++++++----- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/AssetManager.Models/DTOs/PortfolioDTO.cs b/AssetManager.Models/DTOs/PortfolioDTO.cs index 031d3ea..d00cddc 100755 --- a/AssetManager.Models/DTOs/PortfolioDTO.cs +++ b/AssetManager.Models/DTOs/PortfolioDTO.cs @@ -176,6 +176,8 @@ public class PortfolioListItem public string? Currency { get; set; } public double ReturnRate { get; set; } public string? ReturnType { get; set; } + public double TodayProfit { get; set; } + public string? TodayProfitCurrency { get; set; } } /// diff --git a/AssetManager.Services/PortfolioService.cs b/AssetManager.Services/PortfolioService.cs index e088c24..9a6eeda 100755 --- a/AssetManager.Services/PortfolioService.cs +++ b/AssetManager.Services/PortfolioService.cs @@ -172,21 +172,55 @@ public class PortfolioService : IPortfolioService .Where(p => p.UserId == userId) .ToList(); - return portfolios.Select(p => new PortfolioListItem + var result = new List(); + + foreach (var p in portfolios) { - Id = p.Id, - Name = p.Name, - Tags = $"{p.Status} · {p.Currency}", - Status = p.Status, - StatusType = p.Status == "运行中" ? "green" : "gray", - IconChar = p.Name?.Substring(0, 1).ToUpper() ?? "P", - IconBgClass = "bg-blue-100", - IconTextClass = "text-blue-700", - Value = (double)p.TotalValue, - Currency = p.Currency, - ReturnRate = (double)p.ReturnRate, - ReturnType = p.ReturnRate >= 0 ? "positive" : "negative" - }).ToList(); + // 获取持仓数量 + var positionCount = _db.Queryable() + .Where(pos => pos.PortfolioId == p.Id) + .Count(); + + // 获取今日盈亏(从净值历史) + var todayNav = _db.Queryable() + .Where(n => n.PortfolioId == p.Id && n.NavDate == DateTime.Today) + .First(); + + double todayProfit = 0; + if (todayNav != null && p.TotalValue > 0) + { + // 今日盈亏 = 今日市值 - 昨日市值 + var yesterdayNav = _db.Queryable() + .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, + Name = p.Name, + Tags = $"{p.Status} · {p.Currency}" + (positionCount > 0 ? $" · {positionCount}只" : ""), + Status = p.Status, + StatusType = p.Status == "运行中" ? "green" : p.Status == "已暂停" ? "yellow" : "gray", + IconChar = p.Name?.Substring(0, 1).ToUpper() ?? "P", + IconBgClass = "bg-blue-100", + IconTextClass = "text-blue-700", + Value = (double)p.TotalValue, + Currency = p.Currency, + ReturnRate = (double)p.ReturnRate, + ReturnType = p.ReturnRate >= 0 ? "positive" : "negative", + TodayProfit = todayProfit, + TodayProfitCurrency = p.Currency + }); + } + + return result; } public async Task GetTotalAssetsAsync(string userId)