From 7f3dfb31cf731d21df88e1195d092ed52a6640e0 Mon Sep 17 00:00:00 2001 From: hzm <934585316@qq.com> Date: Sun, 8 Mar 2026 18:59:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20PC=E7=AB=AF=E5=88=97=E8=A1=A8=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E7=82=B9=E5=87=BB=E5=9F=BA=E9=87=91=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/FundCard.jsx | 16 +++---- app/components/Icons.jsx | 6 +-- app/components/PcFundTable.jsx | 79 +++++++++++++++++++++++++++++++--- app/page.jsx | 37 ++++++++++++++++ 4 files changed, 122 insertions(+), 16 deletions(-) diff --git a/app/components/FundCard.jsx b/app/components/FundCard.jsx index 0d0058d..139f07e 100644 --- a/app/components/FundCard.jsx +++ b/app/components/FundCard.jsx @@ -220,25 +220,25 @@ export default function FundCard({ display: 'flex', alignItems: 'center', gap: 4, - cursor: 'pointer', + cursor: layoutMode === 'drawer' ? 'default' : 'pointer', }} - onClick={() => onHoldingClick?.(f)} + onClick={() => layoutMode !== 'drawer' && onHoldingClick?.(f)} > - 未设置 + 未设置 {layoutMode !== 'drawer' && } ) : ( <>
onActionClick?.(f)} + style={{ cursor: layoutMode === 'drawer' ? 'default' : 'pointer', flexDirection: 'column', gap: 4 }} + onClick={() => layoutMode !== 'drawer' && onActionClick?.(f)} > - 持仓金额 + 持仓金额 {layoutMode !== 'drawer' && } ¥{profit.amount.toFixed(2)}
@@ -267,12 +267,12 @@ export default function FundCard({ e.stopPropagation(); onPercentModeToggle?.(f.code); }} - style={{ cursor: 'pointer', flexDirection: 'column', gap: 4 }} + style={{ cursor: 'pointer', flexDirection: 'column', gap: 4, alignItems: 'flex-end' }} title="点击切换金额/百分比" > 持有收益{percentModes?.[f.code] ? '(%)' : ''} diff --git a/app/components/Icons.jsx b/app/components/Icons.jsx index 0649adb..175653c 100644 --- a/app/components/Icons.jsx +++ b/app/components/Icons.jsx @@ -267,13 +267,13 @@ export function SwitchIcon({ props }) { p-id="2524" width="13" height="13"> + fill="currentColor" p-id="2525"> + fill="currentColor" p-id="2526"> + fill="currentColor" p-id="2527"> ) } diff --git a/app/components/PcFundTable.jsx b/app/components/PcFundTable.jsx index 20401ec..4539446 100644 --- a/app/components/PcFundTable.jsx +++ b/app/components/PcFundTable.jsx @@ -25,7 +25,14 @@ import { CSS } from '@dnd-kit/utilities'; import ConfirmModal from './ConfirmModal'; import FitText from './FitText'; import PcTableSettingModal from './PcTableSettingModal'; -import { DragIcon, ExitIcon, SettingsIcon, StarIcon, TrashIcon } from './Icons'; +import FundCard from './FundCard'; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { CloseIcon, DragIcon, ExitIcon, SettingsIcon, StarIcon, TrashIcon } from './Icons'; const NON_FROZEN_COLUMN_IDS = [ 'yesterdayChangePercent', @@ -118,6 +125,9 @@ function SortableRow({ row, children, isTableDragging, disabled }) { * @param {(row: any) => void} [props.onRemoveFromGroup] - 从当前分组移除 * @param {(row: any, meta: { hasHolding: boolean }) => void} [props.onHoldingAmountClick] - 点击持仓金额 * @param {boolean} [props.refreshing] - 是否处于刷新状态(控制删除按钮禁用态) + * @param {(row: any) => Object} [props.getFundCardProps] - 给定行返回 FundCard 的 props;传入后点击基金名称将用弹框展示卡片详情 + * @param {React.MutableRefObject<(() => void) | null>} [props.closeDialogRef] - 注入关闭弹框的方法,用于确认删除时关闭 + * @param {boolean} [props.blockDialogClose] - 为 true 时阻止点击遮罩关闭弹框(如删除确认弹框打开时) */ export default function PcFundTable({ data = [], @@ -132,6 +142,9 @@ export default function PcFundTable({ sortBy = 'default', onReorder, onCustomSettingsChange, + getFundCardProps, + closeDialogRef, + blockDialogClose = false, }) { const sensors = useSensors( useSensor(PointerSensor, { @@ -143,6 +156,7 @@ export default function PcFundTable({ ); const [activeId, setActiveId] = useState(null); + const [cardDialogRow, setCardDialogRow] = useState(null); const handleDragStart = (event) => { setActiveId(event.active.id); @@ -341,6 +355,13 @@ export default function PcFundTable({ const onRemoveFromGroupRef = useRef(onRemoveFromGroup); const onHoldingAmountClickRef = useRef(onHoldingAmountClick); + useEffect(() => { + if (closeDialogRef) { + closeDialogRef.current = () => setCardDialogRow(null); + return () => { closeDialogRef.current = null; }; + } + }, [closeDialogRef]); + useEffect(() => { onRemoveFundRef.current = onRemoveFund; onToggleFavoriteRef.current = onToggleFavorite; @@ -353,7 +374,7 @@ export default function PcFundTable({ onHoldingAmountClick, ]); - const FundNameCell = ({ info, showFullFundName }) => { + const FundNameCell = ({ info, showFullFundName, onOpenCardDialog }) => { const original = info.row.original || {}; const code = original.code; const isUpdated = original.isUpdated; @@ -400,7 +421,15 @@ export default function PcFundTable({ )} -
+
{ e.stopPropagation?.(); onOpenCardDialog(original); } : undefined} + onKeyDown={onOpenCardDialog ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpenCardDialog(original); } } : undefined} + style={onOpenCardDialog ? { cursor: 'pointer' } : undefined} + title={onOpenCardDialog ? '查看基金详情' : (original.isUpdated ? '今日净值已更新' : undefined)} + > , + cell: (info) => ( + setCardDialogRow(row) : undefined} + /> + ), meta: { align: 'left', cellClassName: 'name-cell', @@ -732,7 +767,7 @@ export default function PcFundTable({ }, }, ], - [currentTab, favorites, refreshing, sortBy, showFullFundName], + [currentTab, favorites, refreshing, sortBy, showFullFundName, getFundCardProps], ); const table = useReactTable({ @@ -997,6 +1032,40 @@ export default function PcFundTable({ showFullFundName={showFullFundName} onToggleShowFullFundName={handleToggleShowFullFundName} /> + { + if (!open && !blockDialogClose) setCardDialogRow(null); + }} + > + e.preventDefault() : undefined} + > + + + 基金详情 + + + +
+ {cardDialogRow && getFundCardProps ? ( + + ) : null} +
+
+
); } diff --git a/app/page.jsx b/app/page.jsx index d1dbea6..f6fc753 100644 --- a/app/page.jsx +++ b/app/page.jsx @@ -319,6 +319,7 @@ export default function HomePage() { const tabsRef = useRef(null); const [fundDeleteConfirm, setFundDeleteConfirm] = useState(null); // { code, name } const fundDetailDrawerCloseRef = useRef(null); // 由 MobileFundTable 注入,用于确认删除时关闭基金详情 Drawer + const fundDetailDialogCloseRef = useRef(null); // 由 PcFundTable 注入,用于确认删除时关闭基金详情 Dialog const todayStr = formatDate(); @@ -2445,6 +2446,8 @@ export default function HomePage() { if (hasHolding) { setFundDeleteConfirm({ code: fund.code, name: fund.name }); } else { + fundDetailDrawerCloseRef.current?.(); + fundDetailDialogCloseRef.current?.(); removeFund(fund.code); } }; @@ -4021,6 +4024,39 @@ export default function HomePage() { setPercentModes(prev => ({ ...prev, [row.code]: !prev[row.code] })); }} onCustomSettingsChange={triggerCustomSettingsSync} + closeDialogRef={fundDetailDialogCloseRef} + blockDialogClose={!!fundDeleteConfirm} + getFundCardProps={(row) => { + const fund = row?.rawFund || (row ? { code: row.code, name: row.fundName } : null); + if (!fund) return {}; + return { + fund, + todayStr, + currentTab, + favorites, + dcaPlans, + holdings, + percentModes, + valuationSeries, + collapsedCodes, + collapsedTrends, + transactions, + theme, + isTradingDay, + refreshing, + getHoldingProfit, + onRemoveFromGroup: removeFundFromCurrentGroup, + onToggleFavorite: toggleFavorite, + onRemoveFund: requestRemoveFund, + onHoldingClick: (f) => setHoldingModal({ open: true, fund: f }), + onActionClick: (f) => setActionModal({ open: true, fund: f }), + onPercentModeToggle: (code) => + setPercentModes((prev) => ({ ...prev, [code]: !prev[code] })), + onToggleCollapse: toggleCollapse, + onToggleTrendCollapse: toggleTrendCollapse, + layoutMode: 'drawer', + }; + }} />
@@ -4156,6 +4192,7 @@ export default function HomePage() { confirmText="确定删除" onConfirm={() => { fundDetailDrawerCloseRef.current?.(); + fundDetailDialogCloseRef.current?.(); removeFund(fundDeleteConfirm.code); setFundDeleteConfirm(null); }}