From 4fcb076d99ec447fa2aaa124eee2461e06412efd Mon Sep 17 00:00:00 2001
From: hzm <934585316@qq.com>
Date: Sun, 1 Mar 2026 19:07:14 +0800
Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E7=A7=BB=E5=8A=A8=E7=AB=AF?=
=?UTF-8?q?=E8=A1=A8=E6=A0=BC=E5=AE=BD=E5=BA=A6=E5=8A=A8=E6=80=81=E8=AE=A1?=
=?UTF-8?q?=E7=AE=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/components/MobileFundTable.jsx | 87 ++++++++++++++++++++++++++----
app/components/PcFundTable.jsx | 63 +++++++++++++++-------
app/page.jsx | 17 +++---
3 files changed, 131 insertions(+), 36 deletions(-)
diff --git a/app/components/MobileFundTable.jsx b/app/components/MobileFundTable.jsx
index 4f08002..4bf5ec3 100644
--- a/app/components/MobileFundTable.jsx
+++ b/app/components/MobileFundTable.jsx
@@ -27,12 +27,16 @@ import MobileSettingModal from './MobileSettingModal';
import { ExitIcon, SettingsIcon, StarIcon } from './Icons';
const MOBILE_NON_FROZEN_COLUMN_IDS = [
+ 'latestNav',
+ 'estimateNav',
'yesterdayChangePercent',
'estimateChangePercent',
'todayProfit',
'holdingProfit',
];
const MOBILE_COLUMN_HEADERS = {
+ latestNav: '最新净值',
+ estimateNav: '估算净值',
yesterdayChangePercent: '昨日涨跌幅',
estimateChangePercent: '估值涨跌幅',
todayProfit: '当日收益',
@@ -214,6 +218,48 @@ export default function MobileFundTable({
return allVisible;
});
const [settingModalOpen, setSettingModalOpen] = useState(false);
+ const tableContainerRef = useRef(null);
+ const [tableContainerWidth, setTableContainerWidth] = useState(0);
+
+ useEffect(() => {
+ const el = tableContainerRef.current;
+ if (!el) return;
+ const updateWidth = () => setTableContainerWidth(el.clientWidth || 0);
+ updateWidth();
+ const ro = new ResizeObserver(updateWidth);
+ ro.observe(el);
+ return () => ro.disconnect();
+ }, []);
+
+ const NAME_CELL_WIDTH = 140;
+ const GAP = 12;
+ const LAST_COLUMN_EXTRA = 12;
+ const FALLBACK_WIDTHS = {
+ fundName: 140,
+ latestNav: 64,
+ estimateNav: 64,
+ yesterdayChangePercent: 72,
+ estimateChangePercent: 80,
+ todayProfit: 80,
+ holdingProfit: 80,
+ };
+
+ const columnWidthMap = useMemo(() => {
+ const visibleNonNameIds = mobileColumnOrder.filter((id) => mobileColumnVisibility[id] !== false);
+ const nonNameCount = visibleNonNameIds.length;
+ if (tableContainerWidth > 0 && nonNameCount > 0) {
+ const gapTotal = nonNameCount >= 3 ? 3 * GAP : (nonNameCount) * GAP;
+ const remaining = tableContainerWidth - NAME_CELL_WIDTH - gapTotal - LAST_COLUMN_EXTRA;
+ const divisor = nonNameCount >= 3 ? 3 : nonNameCount;
+ const otherColumnWidth = Math.max(48, Math.floor(remaining / divisor));
+ const map = { fundName: NAME_CELL_WIDTH };
+ MOBILE_NON_FROZEN_COLUMN_IDS.forEach((id) => {
+ map[id] = otherColumnWidth;
+ });
+ return map;
+ }
+ return { ...FALLBACK_WIDTHS };
+ }, [tableContainerWidth, mobileColumnOrder, mobileColumnVisibility]);
const handleResetMobileColumnOrder = () => {
const defaultOrder = [...MOBILE_NON_FROZEN_COLUMN_IDS];
@@ -356,7 +402,31 @@ export default function MobileFundTable({
),
cell: (info) => ,
- meta: { align: 'left', cellClassName: 'name-cell', width: 140 },
+ meta: { align: 'left', cellClassName: 'name-cell', width: columnWidthMap.fundName },
+ },
+ {
+ accessorKey: 'latestNav',
+ header: '最新净值',
+ cell: (info) => (
+
+
+ {info.getValue() ?? '—'}
+
+
+ ),
+ meta: { align: 'right', cellClassName: 'value-cell', width: columnWidthMap.latestNav },
+ },
+ {
+ accessorKey: 'estimateNav',
+ header: '估算净值',
+ cell: (info) => (
+
+
+ {info.getValue() ?? '—'}
+
+
+ ),
+ meta: { align: 'right', cellClassName: 'value-cell', width: columnWidthMap.estimateNav },
},
{
accessorKey: 'yesterdayChangePercent',
@@ -375,7 +445,7 @@ export default function MobileFundTable({
);
},
- meta: { align: 'right', cellClassName: 'change-cell', width: 72 },
+ meta: { align: 'right', cellClassName: 'change-cell', width: columnWidthMap.yesterdayChangePercent },
},
{
accessorKey: 'estimateChangePercent',
@@ -395,7 +465,7 @@ export default function MobileFundTable({
);
},
- meta: { align: 'right', cellClassName: 'est-change-cell', width: 80 },
+ meta: { align: 'right', cellClassName: 'est-change-cell', width: columnWidthMap.estimateChangePercent },
},
{
accessorKey: 'todayProfit',
@@ -413,7 +483,7 @@ export default function MobileFundTable({
);
},
- meta: { align: 'right', cellClassName: 'profit-cell', width: 80 },
+ meta: { align: 'right', cellClassName: 'profit-cell', width: columnWidthMap.todayProfit },
},
{
accessorKey: 'holdingProfit',
@@ -441,10 +511,10 @@ export default function MobileFundTable({
);
},
- meta: { align: 'right', cellClassName: 'holding-cell', width: 80 },
+ meta: { align: 'right', cellClassName: 'holding-cell', width: columnWidthMap.holdingProfit },
},
],
- [currentTab, favorites, refreshing]
+ [currentTab, favorites, refreshing, columnWidthMap]
);
const table = useReactTable({
@@ -482,7 +552,6 @@ export default function MobileFundTable({
const headerGroup = table.getHeaderGroups()[0];
- const LAST_COLUMN_EXTRA = 12;
const mobileGridLayout = (() => {
if (!headerGroup?.headers?.length) return { gridTemplateColumns: '', minWidth: undefined };
const gap = 12;
@@ -501,12 +570,12 @@ export default function MobileFundTable({
const getAlignClass = (columnId) => {
if (columnId === 'fundName') return '';
- if (['yesterdayChangePercent', 'estimateChangePercent', 'todayProfit', 'holdingProfit'].includes(columnId)) return 'text-right';
+ if (['latestNav', 'estimateNav', 'yesterdayChangePercent', 'estimateChangePercent', 'todayProfit', 'holdingProfit'].includes(columnId)) return 'text-right';
return 'text-right';
};
return (
-
+
(
-
{info.getValue() ?? '—'}
+
+ {info.getValue() ?? '—'}
+
+ ),
+ meta: {
+ align: 'right',
+ cellClassName: 'value-cell',
+ },
+ },
+ {
+ accessorKey: 'estimateNav',
+ header: '估算净值',
+ size: 100,
+ minSize: 80,
+ cell: (info) => (
+
+ {info.getValue() ?? '—'}
+
),
meta: {
align: 'right',
@@ -420,9 +441,9 @@ export default function PcFundTable({
const cls = value > 0 ? 'up' : value < 0 ? 'down' : '';
return (
-
+
{info.getValue() ?? '—'}
-
+
{date}
@@ -447,9 +468,9 @@ export default function PcFundTable({
const cls = isMuted ? 'muted' : value > 0 ? 'up' : value < 0 ? 'down' : '';
return (
-
+
{info.getValue() ?? '—'}
-
+
{time}
@@ -494,13 +515,17 @@ export default function PcFundTable({
return (
{
e.stopPropagation?.();
onHoldingAmountClickRef.current?.(original, { hasHolding: true });
}}
>
-
{info.getValue() ?? '—'}
+
+
+ {info.getValue() ?? '—'}
+
+
@@ -531,9 +556,9 @@ export default function PcFundTable({
const hasProfit = value != null;
const cls = hasProfit ? (value > 0 ? 'up' : value < 0 ? 'down' : '') : 'muted';
return (
-
+
{hasProfit ? (info.getValue() ?? '') : ''}
-
+
);
},
meta: {
@@ -554,16 +579,16 @@ export default function PcFundTable({
return (
{
if (!hasTotal) return;
e.stopPropagation?.();
onHoldingProfitClickRef.current?.(original);
}}
>
-
+
{hasTotal ? (info.getValue() ?? '') : ''}
-
+
);
},
@@ -836,6 +861,8 @@ export default function PcFundTable({
const columnId = cell.column.id || cell.column.columnDef?.accessorKey;
const isNameColumn = columnId === 'fundName';
const rightAlignedColumns = new Set([
+ 'latestNav',
+ 'estimateNav',
'yesterdayChangePercent',
'estimateChangePercent',
'holdingAmount',
diff --git a/app/page.jsx b/app/page.jsx
index a4e4e0b..7670bfa 100644
--- a/app/page.jsx
+++ b/app/page.jsx
@@ -728,14 +728,12 @@ export default function HomePage() {
() =>
displayFunds.map((f) => {
const hasTodayData = f.jzrq === todayStr;
- const shouldHideChange = isTradingDay && !hasTodayData;
- const navOrEstimate = !shouldHideChange
- ? (f.dwjz ?? '—')
- : (f.noValuation
- ? (f.dwjz ?? '—')
- : (f.estPricedCoverage > 0.05
- ? (f.estGsz != null ? Number(f.estGsz).toFixed(4) : '—')
- : (f.gsz ?? '—')));
+ const latestNav = f.dwjz != null && f.dwjz !== '' ? (typeof f.dwjz === 'number' ? Number(f.dwjz).toFixed(4) : String(f.dwjz)) : '—';
+ const estimateNav = f.noValuation
+ ? '—'
+ : (f.estPricedCoverage > 0.05
+ ? (f.estGsz != null ? Number(f.estGsz).toFixed(4) : '—')
+ : (f.gsz != null ? (typeof f.gsz === 'number' ? Number(f.gsz).toFixed(4) : String(f.gsz)) : '—'));
const yesterdayChangePercent =
f.zzl != null && f.zzl !== ''
@@ -794,7 +792,8 @@ export default function HomePage() {
code: f.code,
fundName: f.name,
isUpdated: f.jzrq === todayStr,
- navOrEstimate,
+ latestNav,
+ estimateNav,
yesterdayChangePercent,
yesterdayChangeValue,
yesterdayDate,