fix: 初始化当日收益计算逻辑问题
This commit is contained in:
55
app/page.jsx
55
app/page.jsx
@@ -146,6 +146,7 @@ function GroupSummary({ funds, holdings, groupName, getProfit, stickyTop }) {
|
||||
let totalHoldingReturn = 0;
|
||||
let totalCost = 0;
|
||||
let hasHolding = false;
|
||||
let hasAnyTodayData = false;
|
||||
|
||||
funds.forEach(fund => {
|
||||
const holding = holdings[fund.code];
|
||||
@@ -154,7 +155,10 @@ function GroupSummary({ funds, holdings, groupName, getProfit, stickyTop }) {
|
||||
if (profit) {
|
||||
hasHolding = true;
|
||||
totalAsset += profit.amount;
|
||||
if (profit.profitToday != null) {
|
||||
totalProfitToday += profit.profitToday;
|
||||
hasAnyTodayData = true;
|
||||
}
|
||||
if (profit.profitTotal !== null) {
|
||||
totalHoldingReturn += profit.profitTotal;
|
||||
if (holding && typeof holding.cost === 'number' && typeof holding.share === 'number') {
|
||||
@@ -166,7 +170,7 @@ function GroupSummary({ funds, holdings, groupName, getProfit, stickyTop }) {
|
||||
|
||||
const returnRate = totalCost > 0 ? (totalHoldingReturn / totalCost) * 100 : 0;
|
||||
|
||||
return { totalAsset, totalProfitToday, totalHoldingReturn, hasHolding, returnRate };
|
||||
return { totalAsset, totalProfitToday, totalHoldingReturn, hasHolding, returnRate, hasAnyTodayData };
|
||||
}, [funds, holdings, getProfit]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
@@ -233,16 +237,18 @@ function GroupSummary({ funds, holdings, groupName, getProfit, stickyTop }) {
|
||||
<div style={{ textAlign: 'right' }}>
|
||||
<div className="muted" style={{ fontSize: '12px', marginBottom: 4 }}>当日收益</div>
|
||||
<div
|
||||
className={summary.totalProfitToday > 0 ? 'up' : summary.totalProfitToday < 0 ? 'down' : ''}
|
||||
className={summary.hasAnyTodayData ? (summary.totalProfitToday > 0 ? 'up' : summary.totalProfitToday < 0 ? 'down' : '') : 'muted'}
|
||||
style={{ fontSize: '18px', fontWeight: 700, fontFamily: 'var(--font-mono)' }}
|
||||
>
|
||||
{isMasked ? (
|
||||
<span style={{ fontSize: metricSize }}>******</span>
|
||||
) : (
|
||||
) : summary.hasAnyTodayData ? (
|
||||
<>
|
||||
<span style={{ marginRight: 1 }}>{summary.totalProfitToday > 0 ? '+' : summary.totalProfitToday < 0 ? '-' : ''}</span>
|
||||
<CountUp value={Math.abs(summary.totalProfitToday)} style={{ fontSize: metricSize }} />
|
||||
</>
|
||||
) : (
|
||||
<span style={{ fontSize: metricSize }}>--</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -539,14 +545,12 @@ export default function HomePage() {
|
||||
const getHoldingProfit = (fund, holding) => {
|
||||
if (!holding || typeof holding.share !== 'number') return null;
|
||||
|
||||
const now = nowInTz();
|
||||
const isAfter9 = now.hour() >= 9;
|
||||
const hasTodayData = fund.jzrq === todayStr;
|
||||
const hasTodayValuation = typeof fund.gztime === 'string' && fund.gztime.startsWith(todayStr);
|
||||
const canCalcTodayProfit = hasTodayData || hasTodayValuation;
|
||||
|
||||
// 如果是交易日且9点以后,且今日净值未出,则强制使用估值(隐藏涨跌幅列模式)
|
||||
const useValuation = isTradingDay && isAfter9 && !hasTodayData;
|
||||
const useValuation = isTradingDay && !hasTodayData;
|
||||
|
||||
let currentNav;
|
||||
let profitToday;
|
||||
@@ -559,7 +563,24 @@ export default function HomePage() {
|
||||
if (canCalcTodayProfit) {
|
||||
const amount = holding.share * currentNav;
|
||||
// 优先用 zzl (真实涨跌幅), 降级用 gszzl
|
||||
const rate = fund.zzl !== undefined ? Number(fund.zzl) : (Number(fund.gszzl) || 0);
|
||||
// 若 gztime 日期 > jzrq,说明估值更新晚于净值日期,优先使用 gszzl 计算当日盈亏
|
||||
const gz = typeof fund.gztime === 'string' ? toTz(fund.gztime) : null;
|
||||
const jz = typeof fund.jzrq === 'string' ? toTz(fund.jzrq) : null;
|
||||
const preferGszzl =
|
||||
!!gz &&
|
||||
!!jz &&
|
||||
gz.isValid() &&
|
||||
jz.isValid() &&
|
||||
gz.startOf('day').isAfter(jz.startOf('day'));
|
||||
|
||||
let rate;
|
||||
if (preferGszzl) {
|
||||
rate = Number(fund.gszzl);
|
||||
} else {
|
||||
const zzl = fund.zzl !== undefined ? Number(fund.zzl) : Number.NaN;
|
||||
rate = Number.isFinite(zzl) ? zzl : Number(fund.gszzl);
|
||||
}
|
||||
if (!Number.isFinite(rate)) rate = 0;
|
||||
profitToday = amount - (amount / (1 + rate / 100));
|
||||
} else {
|
||||
profitToday = null;
|
||||
@@ -1275,7 +1296,7 @@ export default function HomePage() {
|
||||
lastSyncedRef.current = next;
|
||||
syncUserConfig(userIdRef.current, false, payload, false);
|
||||
}
|
||||
}, 2000);
|
||||
}, 1000 * 5); // 往云端同步的防抖时间
|
||||
}, []);
|
||||
|
||||
const storageHelper = useMemo(() => {
|
||||
@@ -3404,7 +3425,7 @@ export default function HomePage() {
|
||||
<div className="table-header-cell text-right">涨跌幅</div>
|
||||
<div className="table-header-cell text-right">估值时间</div>
|
||||
<div className="table-header-cell text-right">持仓金额</div>
|
||||
<div className="table-header-cell text-right">当日盈亏</div>
|
||||
<div className="table-header-cell text-right">当日收益</div>
|
||||
<div className="table-header-cell text-right">持有收益</div>
|
||||
<div className="table-header-cell text-center">操作</div>
|
||||
</div>
|
||||
@@ -3519,10 +3540,8 @@ export default function HomePage() {
|
||||
</div>
|
||||
</div>
|
||||
{(() => {
|
||||
const now = nowInTz();
|
||||
const isAfter9 = now.hour() >= 9;
|
||||
const hasTodayData = f.jzrq === todayStr;
|
||||
const shouldHideChange = isTradingDay && isAfter9 && !hasTodayData;
|
||||
const shouldHideChange = isTradingDay && !hasTodayData;
|
||||
|
||||
if (!shouldHideChange) {
|
||||
// 如果涨跌幅列显示(即非交易时段或今日净值已更新),则显示单位净值和真实涨跌幅
|
||||
@@ -3736,10 +3755,8 @@ export default function HomePage() {
|
||||
) : (
|
||||
<>
|
||||
{(() => {
|
||||
const now = nowInTz();
|
||||
const isAfter9 = now.hour() >= 9;
|
||||
const hasTodayData = f.jzrq === todayStr;
|
||||
const shouldHideChange = isTradingDay && isAfter9 && !hasTodayData;
|
||||
const shouldHideChange = isTradingDay && !hasTodayData;
|
||||
|
||||
if (shouldHideChange) return null;
|
||||
|
||||
@@ -3794,9 +3811,11 @@ export default function HomePage() {
|
||||
<span className="value">¥{profit.amount.toFixed(2)}</span>
|
||||
</div>
|
||||
<div className="stat" style={{ flexDirection: 'column', gap: 4 }}>
|
||||
<span className="label">当日盈亏</span>
|
||||
<span className={`value ${profit.profitToday > 0 ? 'up' : profit.profitToday < 0 ? 'down' : ''}`}>
|
||||
{profit.profitToday > 0 ? '+' : profit.profitToday < 0 ? '-' : ''}¥{Math.abs(profit.profitToday).toFixed(2)}
|
||||
<span className="label">当日收益</span>
|
||||
<span className={`value ${profit.profitToday != null ? (profit.profitToday > 0 ? 'up' : profit.profitToday < 0 ? 'down' : '') : 'muted'}`}>
|
||||
{profit.profitToday != null
|
||||
? `${profit.profitToday > 0 ? '+' : profit.profitToday < 0 ? '-' : ''}¥${Math.abs(profit.profitToday).toFixed(2)}`
|
||||
: '--'}
|
||||
</span>
|
||||
</div>
|
||||
{profit.profitTotal !== null && (
|
||||
|
||||
Reference in New Issue
Block a user