refactor(ui): 规范资产卡片术语,智能隐藏同币种双轨制冗余数据
This commit is contained in:
parent
84d889fbe5
commit
7d7a7804a6
@ -118,26 +118,30 @@ export default async function DashboardPage() {
|
|||||||
{pos.holdingDays} 天
|
{pos.holdingDays} 天
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between">
|
{pos.baseCurrency !== 'CNY' && (
|
||||||
<span className="text-muted-foreground">持仓成本 ({pos.baseCurrency})</span>
|
<>
|
||||||
<span className="font-medium">
|
<div className="flex justify-between">
|
||||||
{formatAmount(pos.totalCostNative)}
|
<span className="text-muted-foreground">持仓成本 ({pos.baseCurrency})</span>
|
||||||
</span>
|
<span className="font-medium">
|
||||||
</div>
|
{formatAmount(pos.totalCostNative)}
|
||||||
<div className="flex justify-between">
|
</span>
|
||||||
<span className="text-muted-foreground">当前盈亏 ({pos.baseCurrency})</span>
|
</div>
|
||||||
<span className={`font-semibold ${posPnlNativePositive ? 'text-green-500' : 'text-red-500'}`}>
|
<div className="flex justify-between">
|
||||||
{posPnlNativePositive ? '+' : ''}{formatAmount(pos.pnlNative)}
|
<span className="text-muted-foreground">当前盈亏 ({pos.baseCurrency})</span>
|
||||||
</span>
|
<span className={`font-semibold ${posPnlNativePositive ? 'text-green-500' : 'text-red-500'}`}>
|
||||||
</div>
|
{posPnlNativePositive ? '+' : ''}{formatAmount(pos.pnlNative)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div className="flex justify-between opacity-50">
|
<div className="flex justify-between opacity-50">
|
||||||
<span className="text-muted-foreground">成本 (CNY)</span>
|
<span className="text-muted-foreground">投入本金 (CNY)</span>
|
||||||
<span className="font-medium">
|
<span className="font-medium">
|
||||||
¥{formatAmount(pos.totalCostCny)}
|
¥{formatAmount(pos.totalCostCny)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between opacity-50">
|
<div className="flex justify-between opacity-50">
|
||||||
<span className="text-muted-foreground">盈亏 (CNY)</span>
|
<span className="text-muted-foreground">综合总盈亏 (CNY)</span>
|
||||||
<span className={`font-semibold ${posPnlPositive ? 'text-green-500' : 'text-red-500'}`}>
|
<span className={`font-semibold ${posPnlPositive ? 'text-green-500' : 'text-red-500'}`}>
|
||||||
{posPnlPositive ? '+' : ''}{formattedPosPnl}
|
{posPnlPositive ? '+' : ''}{formattedPosPnl}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -26,6 +26,7 @@ interface Position {
|
|||||||
holdingDays: number;
|
holdingDays: number;
|
||||||
exchange: string;
|
exchange: string;
|
||||||
accumulatedDividendsCny: string;
|
accumulatedDividendsCny: string;
|
||||||
|
accumulatedDividendsNative: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RawRate {
|
interface RawRate {
|
||||||
@ -159,6 +160,7 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
|||||||
// 已实现盈亏
|
// 已实现盈亏
|
||||||
realizedPnlCny: Big;
|
realizedPnlCny: Big;
|
||||||
accumulatedDividendsCny: Big;
|
accumulatedDividendsCny: Big;
|
||||||
|
accumulatedDividendsNative: Big;
|
||||||
// 首次买入日期
|
// 首次买入日期
|
||||||
firstBuyDate: Date | null;
|
firstBuyDate: Date | null;
|
||||||
}>();
|
}>();
|
||||||
@ -182,6 +184,7 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
|||||||
totalBuyQuantity: new Big('0'),
|
totalBuyQuantity: new Big('0'),
|
||||||
realizedPnlCny: new Big('0'),
|
realizedPnlCny: new Big('0'),
|
||||||
accumulatedDividendsCny: new Big('0'),
|
accumulatedDividendsCny: new Big('0'),
|
||||||
|
accumulatedDividendsNative: new Big('0'),
|
||||||
firstBuyDate: null,
|
firstBuyDate: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -235,6 +238,7 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
|||||||
const dividendAmountNative = new Big(tx.quantity).times(new Big(tx.price));
|
const dividendAmountNative = new Big(tx.quantity).times(new Big(tx.price));
|
||||||
const dividendCny = dividendAmountNative.times(new Big(tx.exchangeRate || '1'));
|
const dividendCny = dividendAmountNative.times(new Big(tx.exchangeRate || '1'));
|
||||||
holding.accumulatedDividendsCny = holding.accumulatedDividendsCny.plus(dividendCny);
|
holding.accumulatedDividendsCny = holding.accumulatedDividendsCny.plus(dividendCny);
|
||||||
|
holding.accumulatedDividendsNative = holding.accumulatedDividendsNative.plus(dividendAmountNative);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.assetLatestPrice) {
|
if (tx.assetLatestPrice) {
|
||||||
@ -261,7 +265,7 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
|||||||
const totalPnlCny = unrealizedPnlCny.plus(holding.realizedPnlCny).plus(holding.accumulatedDividendsCny);
|
const totalPnlCny = unrealizedPnlCny.plus(holding.realizedPnlCny).plus(holding.accumulatedDividendsCny);
|
||||||
|
|
||||||
const currentNativeValue = new Big(holding.latestPrice).times(holding.quantity);
|
const currentNativeValue = new Big(holding.latestPrice).times(holding.quantity);
|
||||||
const pnlNative = currentNativeValue.minus(holding.totalBuyCostNative);
|
const pnlNative = currentNativeValue.minus(holding.totalBuyCostNative).plus(holding.accumulatedDividendsNative);
|
||||||
|
|
||||||
// 平均成本 = 总买入成本 / 总买入数量
|
// 平均成本 = 总买入成本 / 总买入数量
|
||||||
let avgCost = new Big('0');
|
let avgCost = new Big('0');
|
||||||
@ -300,8 +304,9 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
|||||||
avgCost: avgCost.toString(),
|
avgCost: avgCost.toString(),
|
||||||
dilutedCost: dilutedCost.toString(),
|
dilutedCost: dilutedCost.toString(),
|
||||||
holdingDays,
|
holdingDays,
|
||||||
exchange: holding.exchange,
|
exchange: holding.exchange,
|
||||||
accumulatedDividendsCny: holding.accumulatedDividendsCny.toString(),
|
accumulatedDividendsCny: holding.accumulatedDividendsCny.toString(),
|
||||||
|
accumulatedDividendsNative: holding.accumulatedDividendsNative.toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user