From 99ec356fbb482979a735a55a31a8c677e67c32e4 Mon Sep 17 00:00:00 2001
From: hzm <934585316@qq.com>
Date: Fri, 6 Mar 2026 08:42:30 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=BB=BC=E5=90=88?=
=?UTF-8?q?=E6=B6=A8=E5=B9=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/components/Announcement.jsx | 9 +++---
app/components/MobileFundTable.jsx | 47 +++++++++++++++++++++++++++++-
app/components/PcFundTable.jsx | 46 +++++++++++++++++++++++++++++
app/page.jsx | 2 ++
4 files changed, 99 insertions(+), 5 deletions(-)
diff --git a/app/components/Announcement.jsx b/app/components/Announcement.jsx
index 0b9b2f2..a670587 100644
--- a/app/components/Announcement.jsx
+++ b/app/components/Announcement.jsx
@@ -67,11 +67,12 @@ export default function Announcement() {
v0.2.1 版本更新内容如下:
1. 改进拍照识别基金准确度。
-
2. 拍照导入支持识别持仓金额、持仓收益。
+
2. 拍照导入支持选择分组,识别持仓金额、持仓收益。
+
3. 个性化设置新增展示完整基金名称。
+
4. 表格列新增综合涨幅(估值涨幅+持有收益涨幅)。
以下功能将会在下一个版本上线:
-
1. 列表页查看基金详情。
-
2. 大盘走势数据。
-
3. 关联板块。
+
1. 大盘走势数据。
+
2. 关联板块。
diff --git a/app/components/MobileFundTable.jsx b/app/components/MobileFundTable.jsx
index 6901a02..6e03df7 100644
--- a/app/components/MobileFundTable.jsx
+++ b/app/components/MobileFundTable.jsx
@@ -29,6 +29,7 @@ import { ExitIcon, SettingsIcon, StarIcon } from './Icons';
const MOBILE_NON_FROZEN_COLUMN_IDS = [
'yesterdayChangePercent',
'estimateChangePercent',
+ 'totalChangePercent',
'todayProfit',
'holdingProfit',
'latestNav',
@@ -39,6 +40,7 @@ const MOBILE_COLUMN_HEADERS = {
estimateNav: '估算净值',
yesterdayChangePercent: '昨日涨幅',
estimateChangePercent: '估值涨幅',
+ totalChangePercent: '综合涨幅',
todayProfit: '当日收益',
holdingProfit: '持有收益',
};
@@ -294,6 +296,7 @@ export default function MobileFundTable({
estimateNav: 64,
yesterdayChangePercent: 72,
estimateChangePercent: 80,
+ totalChangePercent: 80,
todayProfit: 80,
holdingProfit: 80,
};
@@ -523,6 +526,48 @@ export default function MobileFundTable({
},
meta: { align: 'right', cellClassName: 'est-change-cell', width: columnWidthMap.estimateChangePercent },
},
+ {
+ accessorKey: 'totalChangePercent',
+ header: '综合涨幅',
+ cell: (info) => {
+ const original = info.row.original || {};
+ const estimateValue = original.estimateChangeValue;
+ const hasTodayEstimate = original.hasTodayEstimate;
+ const holdingProfitPercentStr = original.holdingProfitPercent ?? '';
+
+ let holdingProfitPercentValue = null;
+ if (holdingProfitPercentStr && holdingProfitPercentStr !== '') {
+ const numStr = holdingProfitPercentStr.replace(/[+%]/g, '');
+ holdingProfitPercentValue = parseFloat(numStr);
+ }
+
+ const hasEstimate = hasTodayEstimate && estimateValue != null;
+ const hasHolding = holdingProfitPercentValue != null && !isNaN(holdingProfitPercentValue);
+
+ if (!hasEstimate && !hasHolding) {
+ return (
+
+
+ —
+
+
+ );
+ }
+
+ const total = (hasEstimate ? estimateValue : 0) + (hasHolding ? holdingProfitPercentValue : 0);
+ const cls = total > 0 ? 'up' : total < 0 ? 'down' : '';
+ const displayValue = `${total > 0 ? '+' : ''}${total.toFixed(2)}%`;
+
+ return (
+
+
+ {displayValue}
+
+
+ );
+ },
+ meta: { align: 'right', cellClassName: 'total-change-cell', width: columnWidthMap.totalChangePercent },
+ },
{
accessorKey: 'todayProfit',
header: '当日收益',
@@ -689,7 +734,7 @@ export default function MobileFundTable({
const getAlignClass = (columnId) => {
if (columnId === 'fundName') return '';
- if (['latestNav', 'estimateNav', 'yesterdayChangePercent', 'estimateChangePercent', 'todayProfit', 'holdingProfit'].includes(columnId)) return 'text-right';
+ if (['latestNav', 'estimateNav', 'yesterdayChangePercent', 'estimateChangePercent', 'totalChangePercent', 'todayProfit', 'holdingProfit'].includes(columnId)) return 'text-right';
return 'text-right';
};
diff --git a/app/components/PcFundTable.jsx b/app/components/PcFundTable.jsx
index 98f6f21..655b5d0 100644
--- a/app/components/PcFundTable.jsx
+++ b/app/components/PcFundTable.jsx
@@ -30,6 +30,7 @@ import { DragIcon, ExitIcon, SettingsIcon, StarIcon, TrashIcon } from './Icons';
const NON_FROZEN_COLUMN_IDS = [
'yesterdayChangePercent',
'estimateChangePercent',
+ 'totalChangePercent',
'holdingAmount',
'todayProfit',
'holdingProfit',
@@ -41,6 +42,7 @@ const COLUMN_HEADERS = {
estimateNav: '估算净值',
yesterdayChangePercent: '昨日涨幅',
estimateChangePercent: '估值涨幅',
+ totalChangePercent: '综合涨幅',
holdingAmount: '持仓金额',
todayProfit: '当日收益',
holdingProfit: '持有收益',
@@ -512,6 +514,49 @@ export default function PcFundTable({
cellClassName: 'est-change-cell',
},
},
+ {
+ accessorKey: 'totalChangePercent',
+ header: '综合涨幅',
+ size: 135,
+ minSize: 100,
+ cell: (info) => {
+ const original = info.row.original || {};
+ const estimateValue = original.estimateChangeValue;
+ const hasTodayEstimate = original.hasTodayEstimate;
+ const holdingProfitPercentStr = original.holdingProfitPercent ?? '';
+
+ let holdingProfitPercentValue = null;
+ if (holdingProfitPercentStr && holdingProfitPercentStr !== '') {
+ const numStr = holdingProfitPercentStr.replace(/[+%]/g, '');
+ holdingProfitPercentValue = parseFloat(numStr);
+ }
+
+ const hasEstimate = hasTodayEstimate && estimateValue != null;
+ const hasHolding = holdingProfitPercentValue != null && !isNaN(holdingProfitPercentValue);
+
+ if (!hasEstimate && !hasHolding) {
+ return (
+
+ —
+
+ );
+ }
+
+ const total = (hasEstimate ? estimateValue : 0) + (hasHolding ? holdingProfitPercentValue : 0);
+ const cls = total > 0 ? 'up' : total < 0 ? 'down' : '';
+ const displayValue = `${total > 0 ? '+' : ''}${total.toFixed(2)}%`;
+
+ return (
+
+ {displayValue}
+
+ );
+ },
+ meta: {
+ align: 'right',
+ cellClassName: 'total-change-cell',
+ },
+ },
{
accessorKey: 'holdingAmount',
header: '持仓金额',
@@ -898,6 +943,7 @@ export default function PcFundTable({
'estimateNav',
'yesterdayChangePercent',
'estimateChangePercent',
+ 'totalChangePercent',
'holdingAmount',
'todayProfit',
'holdingProfit',
diff --git a/app/page.jsx b/app/page.jsx
index 8b3fbf9..e9e9f80 100644
--- a/app/page.jsx
+++ b/app/page.jsx
@@ -780,6 +780,7 @@ export default function HomePage() {
? (isNumber(f.estGszzl) ? Number(f.estGszzl) : null)
: (isNumber(f.gszzl) ? Number(f.gszzl) : null));
const estimateTime = f.noValuation ? (f.jzrq || '-') : (f.gztime || f.time || '-');
+ const hasTodayEstimate = !f.noValuation && isString(f.gztime) && f.gztime.startsWith(todayStr);
const holding = holdings[f.code];
const profit = getHoldingProfit(f, holding);
@@ -829,6 +830,7 @@ export default function HomePage() {
estimateChangeValue,
estimateChangeMuted: f.noValuation,
estimateTime,
+ hasTodayEstimate,
holdingAmount,
holdingAmountValue,
todayProfit,