fix(ledger): 修复币种符号映射逻辑,并扩充引擎下发流水明细支持 UI 下钻
This commit is contained in:
parent
e63f309a3a
commit
cdea2ce608
@ -66,6 +66,10 @@
|
||||
- 修復了 `avgCostFormatted` 的判空邏輯,將 `Big.eq(0)` 修正為 `Big.eq('0')`,確保當 `pos.avgCost` 存在且不為 0 時能正確格式化,不再顯示 `¥-`。
|
||||
- 在資產卡片中新增「累計分紅」行,展示 `accumulatedDividendsCny` 數據,保持與其它 CNY 數據一致的 `opacity-50` 樣式。
|
||||
|
||||
## 修復幣種符號映射 Bug 與引擎數據擴充 (Task 40)
|
||||
- 修復了币种符号映射错乱 Bug:`getCurrencySymbol()` 中 CNY 和 HKD 被错误地映射为 `HK$`,现修正为 USD→$、HKD→HK$、CNY→¥。
|
||||
- 在 portfolio 引擎中新增了单资产的流水明细数组:`Position` 接口新增 `transactions` 字段,`getPortfolioPositions()` 按资产名下发排序后的原始交易流水,支持前端展开查看。
|
||||
|
||||
## 持倉引擎 Native 幣種算法重構 (Task 38)
|
||||
- 重構底層盈虧引擎,全面轉向 Native 原生幣種計算,新增浮動/累計盈虧及百分比指標。
|
||||
- 徹底分離 Native 與 CNY 計算:單隻股票的成本與盈虧全部改用 Native (原幣種) 進行計算。
|
||||
|
||||
@ -6,13 +6,9 @@ import { SyncButton } from '@/components/assets/sync-button';
|
||||
import Big from 'big.js';
|
||||
|
||||
function getCurrencySymbol(currency: string): string {
|
||||
switch (currency) {
|
||||
case 'USD': return '$';
|
||||
case 'CNY':
|
||||
case 'HKD': return 'HK$';
|
||||
case 'JPY': return '¥';
|
||||
default: return currency + ' ';
|
||||
}
|
||||
if (currency === 'USD') return '$';
|
||||
if (currency === 'HKD') return 'HK$';
|
||||
return '¥';
|
||||
}
|
||||
|
||||
function formatNative(value: string, baseCurrency: string): string {
|
||||
|
||||
@ -37,6 +37,15 @@ interface Position {
|
||||
floatingPnlPercent: string;
|
||||
cumulativePnlNative: string;
|
||||
cumulativePnlPercent: string;
|
||||
transactions: TransactionRecord[];
|
||||
}
|
||||
|
||||
interface TransactionRecord {
|
||||
txType: string;
|
||||
quantity: string;
|
||||
price: string;
|
||||
txCurrency: string;
|
||||
executedAt: Date | null;
|
||||
}
|
||||
|
||||
interface RawRate {
|
||||
@ -174,6 +183,8 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
||||
accumulatedDividendsNative: Big;
|
||||
// 首次买入日期
|
||||
firstBuyDate: Date | null;
|
||||
// 原始流水明细
|
||||
transactions: TransactionRecord[];
|
||||
}>();
|
||||
|
||||
for (const tx of allTransactions) {
|
||||
@ -198,6 +209,7 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
||||
accumulatedDividendsCny: new Big('0'),
|
||||
accumulatedDividendsNative: new Big('0'),
|
||||
firstBuyDate: null,
|
||||
transactions: [],
|
||||
});
|
||||
}
|
||||
|
||||
@ -265,6 +277,14 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
||||
if (tx.assetLatestPrice) {
|
||||
holding.latestPrice = tx.assetLatestPrice;
|
||||
}
|
||||
|
||||
holding.transactions.push({
|
||||
txType: tx.txType,
|
||||
quantity: tx.quantity,
|
||||
price: tx.price,
|
||||
txCurrency: tx.txCurrency,
|
||||
executedAt: tx.executedAt,
|
||||
});
|
||||
}
|
||||
|
||||
const today = getTodayInShanghai();
|
||||
@ -373,6 +393,7 @@ export async function getPortfolioPositions(): Promise<Position[]> {
|
||||
floatingPnlPercent: floatingPnlPercent.toString(),
|
||||
cumulativePnlNative: cumulativePnlNative.toString(),
|
||||
cumulativePnlPercent: cumulativePnlPercent.toString(),
|
||||
transactions: holding.transactions,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user