feat:持有相关数据隐藏完善

This commit is contained in:
hzm
2026-03-10 21:31:41 +08:00
parent f11fc46bce
commit 1e081167b3
5 changed files with 62 additions and 26 deletions

View File

@@ -59,6 +59,7 @@ export default function FundCard({
onToggleCollapse,
onToggleTrendCollapse,
layoutMode = 'card', // 'card' | 'drawer'drawer 时前10重仓与业绩走势以 Tabs 展示
masked = false,
}) {
const holding = holdings[f?.code];
const profit = getHoldingProfit?.(f, holding) ?? null;
@@ -246,7 +247,9 @@ export default function FundCard({
>
持仓金额 {layoutMode !== 'drawer' && <SettingsIcon width="12" height="12" style={{ opacity: 0.7 }} />}
</span>
<span className="value">¥{profit.amount.toFixed(2)}</span>
<span className="value">
{masked ? '******' : `¥${profit.amount.toFixed(2)}`}
</span>
</div>
<div className="stat" style={{ flexDirection: 'column', gap: 4 }}>
<span className="label">当日收益</span>
@@ -262,7 +265,9 @@ export default function FundCard({
}`}
>
{profit.profitToday != null
? `${profit.profitToday > 0 ? '+' : profit.profitToday < 0 ? '-' : ''}¥${Math.abs(profit.profitToday).toFixed(2)}`
? masked
? '******'
: `${profit.profitToday > 0 ? '+' : profit.profitToday < 0 ? '-' : ''}¥${Math.abs(profit.profitToday).toFixed(2)}`
: '--'}
</span>
</div>
@@ -288,14 +293,18 @@ export default function FundCard({
profit.profitTotal > 0 ? 'up' : profit.profitTotal < 0 ? 'down' : ''
}`}
>
{profit.profitTotal > 0 ? '+' : profit.profitTotal < 0 ? '-' : ''}
{percentModes?.[f.code]
? `${Math.abs(
holding?.cost * holding?.share
? (profit.profitTotal / (holding.cost * holding.share)) * 100
: 0,
).toFixed(2)}%`
: `¥${Math.abs(profit.profitTotal).toFixed(2)}`}
{masked
? '******'
: <>
{profit.profitTotal > 0 ? '+' : profit.profitTotal < 0 ? '-' : ''}
{percentModes?.[f.code]
? `${Math.abs(
holding?.cost * holding?.share
? (profit.profitTotal / (holding.cost * holding.share)) * 100
: 0,
).toFixed(2)}%`
: `¥${Math.abs(profit.profitTotal).toFixed(2)}`}
</>}
</span>
</div>
)}

View File

@@ -56,9 +56,11 @@ export default function GroupSummary({
groupName,
getProfit,
stickyTop,
masked,
onToggleMasked,
}) {
const [showPercent, setShowPercent] = useState(true);
const [isMasked, setIsMasked] = useState(false);
const [isMasked, setIsMasked] = useState(masked ?? false);
const [isSticky, setIsSticky] = useState(false);
const rowRef = useRef(null);
const [assetSize, setAssetSize] = useState(24);
@@ -74,6 +76,12 @@ export default function GroupSummary({
}
}, []);
useEffect(() => {
if (typeof masked === 'boolean') {
setIsMasked(masked);
}
}, [masked]);
const summary = useMemo(() => {
let totalAsset = 0;
let totalProfitToday = 0;
@@ -185,7 +193,13 @@ export default function GroupSummary({
</div>
<button
className="fav-button"
onClick={() => setIsMasked((value) => !value)}
onClick={() => {
if (onToggleMasked) {
onToggleMasked();
} else {
setIsMasked((value) => !value);
}
}}
aria-label={isMasked ? '显示资产' : '隐藏资产'}
style={{
margin: 0,

View File

@@ -108,6 +108,7 @@ function SortableRow({ row, children, isTableDragging, disabled }) {
* @param {string} [props.sortBy] - 排序方式,'default' 时长按行触发拖拽排序
* @param {(oldIndex: number, newIndex: number) => void} [props.onReorder] - 拖拽排序回调
* @param {(row: any) => Object} [props.getFundCardProps] - 给定行返回 FundCard 的 props传入后点击基金名称将用底部弹框展示卡片视图
* @param {boolean} [props.masked] - 是否隐藏持仓相关金额
*/
export default function MobileFundTable({
data = [],
@@ -126,6 +127,7 @@ export default function MobileFundTable({
getFundCardProps,
blockDrawerClose = false,
closeDrawerRef,
masked = false,
}) {
const [isNameSortMode, setIsNameSortMode] = useState(false);
@@ -559,7 +561,7 @@ export default function MobileFundTable({
}
}}
>
{holdingAmountDisplay}
{masked ? '******' : holdingAmountDisplay}
{hasDca && <span className="dca-indicator"></span>}
{isUpdated && <span className="updated-indicator"></span>}
</span>
@@ -754,10 +756,10 @@ export default function MobileFundTable({
<div style={{ width: '100%' }}>
<span className={cls} style={{ display: 'block', width: '100%', fontWeight: 700 }}>
<FitText maxFontSize={14} minFontSize={10}>
{amountStr}
{masked && hasProfit ? '******' : amountStr}
</FitText>
</span>
{percentStr ? (
{percentStr && !masked ? (
<span className={`${cls} estimate-profit-percent`} style={{ display: 'block', width: '100%', fontSize: '0.75em', opacity: 0.9, fontWeight: 500 }}>
<FitText maxFontSize={11} minFontSize={9}>
{percentStr}
@@ -784,10 +786,10 @@ export default function MobileFundTable({
<div style={{ width: '100%' }}>
<span className={cls} style={{ display: 'block', width: '100%', fontWeight: 700 }}>
<FitText maxFontSize={14} minFontSize={10}>
{amountStr}
{masked && hasProfit ? '******' : amountStr}
</FitText>
</span>
{percentStr && !isUpdated ? (
{percentStr && !isUpdated && !masked ? (
<span className={`${cls} today-profit-percent`} style={{ display: 'block', width: '100%', fontSize: '0.75em', opacity: 0.9, fontWeight: 500 }}>
<FitText maxFontSize={11} minFontSize={9}>
{percentStr}
@@ -813,10 +815,10 @@ export default function MobileFundTable({
<div style={{ width: '100%' }}>
<span className={cls} style={{ display: 'block', width: '100%', fontWeight: 700 }}>
<FitText maxFontSize={14} minFontSize={10}>
{amountStr}
{masked && hasTotal ? '******' : amountStr}
</FitText>
</span>
{percentStr ? (
{percentStr && !masked ? (
<span className={`${cls} holding-profit-percent`} style={{ display: 'block', width: '100%', fontSize: '0.75em', opacity: 0.9, fontWeight: 500 }}>
<FitText maxFontSize={11} minFontSize={9}>
{percentStr}

View File

@@ -131,6 +131,7 @@ function SortableRow({ row, children, isTableDragging, disabled }) {
* @param {React.MutableRefObject<(() => void) | null>} [props.closeDialogRef] - 注入关闭弹框的方法,用于确认删除时关闭
* @param {boolean} [props.blockDialogClose] - 为 true 时阻止点击遮罩关闭弹框(如删除确认弹框打开时)
* @param {number} [props.stickyTop] - 表头固定时的 top 偏移(与 MobileFundTable 一致,用于适配导航栏、筛选栏等)
* @param {boolean} [props.masked] - 是否隐藏持仓相关金额
*/
export default function PcFundTable({
data = [],
@@ -149,6 +150,7 @@ export default function PcFundTable({
closeDialogRef,
blockDialogClose = false,
stickyTop = 0,
masked = false,
}) {
const sensors = useSensors(
useSensor(PointerSensor, {
@@ -678,9 +680,9 @@ export default function PcFundTable({
return (
<div style={{ width: '100%' }}>
<FitText className={cls} style={{ fontWeight: 700, display: 'block' }} maxFontSize={14} minFontSize={10}>
{amountStr}
{masked && hasProfit ? '******' : amountStr}
</FitText>
{percentStr ? (
{percentStr && !masked ? (
<span className={`${cls} estimate-profit-percent`} style={{ display: 'block', fontSize: '0.75em', opacity: 0.9, fontWeight: 500 }}>
<FitText maxFontSize={11} minFontSize={9}>
{percentStr}
@@ -736,7 +738,7 @@ export default function PcFundTable({
>
<div style={{ flex: '1 1 0', minWidth: 0 }}>
<FitText style={{ fontWeight: 700 }} maxFontSize={14} minFontSize={10}>
{info.getValue() ?? '—'}
{masked ? '******' : (info.getValue() ?? '—')}
</FitText>
</div>
<button
@@ -774,9 +776,9 @@ export default function PcFundTable({
return (
<div style={{ width: '100%' }}>
<FitText className={cls} style={{ fontWeight: 700, display: 'block' }} maxFontSize={14} minFontSize={10}>
{amountStr}
{masked && hasProfit ? '******' : amountStr}
</FitText>
{percentStr && !isUpdated ? (
{percentStr && !isUpdated && !masked ? (
<span className={`${cls} today-profit-percent`} style={{ display: 'block', fontSize: '0.75em', opacity: 0.9, fontWeight: 500 }}>
<FitText maxFontSize={11} minFontSize={9}>
{percentStr}
@@ -806,9 +808,9 @@ export default function PcFundTable({
return (
<div style={{ width: '100%' }}>
<FitText className={cls} style={{ fontWeight: 700, display: 'block' }} maxFontSize={14} minFontSize={10}>
{amountStr}
{masked && hasTotal ? '******' : amountStr}
</FitText>
{percentStr ? (
{percentStr && !masked ? (
<span className={`${cls} holding-profit-percent`} style={{ display: 'block', fontSize: '0.75em', opacity: 0.9, fontWeight: 500 }}>
<FitText maxFontSize={11} minFontSize={9}>
{percentStr}

View File

@@ -185,6 +185,8 @@ export default function HomePage() {
// 视图模式
const [viewMode, setViewMode] = useState('card'); // card, list
// 全局隐藏金额状态(影响分组汇总、列表和卡片)
const [maskAmounts, setMaskAmounts] = useState(false);
// 用户认证状态
const [user, setUser] = useState(null);
@@ -3925,6 +3927,8 @@ export default function HomePage() {
groupName={getGroupName()}
getProfit={getHoldingProfit}
stickyTop={navbarHeight + filterBarHeight + (isMobile ? -14 : 0)}
masked={maskAmounts}
onToggleMasked={() => setMaskAmounts((v) => !v)}
/>
{currentTab !== 'all' && currentTab !== 'fav' && (
@@ -4019,6 +4023,7 @@ export default function HomePage() {
onCustomSettingsChange={triggerCustomSettingsSync}
closeDialogRef={fundDetailDialogCloseRef}
blockDialogClose={!!fundDeleteConfirm}
masked={maskAmounts}
getFundCardProps={(row) => {
const fund = row?.rawFund || (row ? { code: row.code, name: row.fundName } : null);
if (!fund) return {};
@@ -4047,6 +4052,7 @@ export default function HomePage() {
setPercentModes((prev) => ({ ...prev, [code]: !prev[code] })),
onToggleCollapse: toggleCollapse,
onToggleTrendCollapse: toggleTrendCollapse,
masked: maskAmounts,
layoutMode: 'drawer',
};
}}
@@ -4122,9 +4128,11 @@ export default function HomePage() {
setPercentModes((prev) => ({ ...prev, [code]: !prev[code] })),
onToggleCollapse: toggleCollapse,
onToggleTrendCollapse: toggleTrendCollapse,
masked: maskAmounts,
layoutMode: 'drawer',
};
}}
masked={maskAmounts}
/>
)}
<AnimatePresence mode="popLayout">
@@ -4165,6 +4173,7 @@ export default function HomePage() {
}
onToggleCollapse={toggleCollapse}
onToggleTrendCollapse={toggleTrendCollapse}
masked={maskAmounts}
/>
</motion.div>
))}