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,