style(portfolio): 优化 CSV 导出字段格式,精准剥离价格末尾的无意义零
This commit is contained in:
parent
3e81c1dc5b
commit
e692d47b6a
@ -1,5 +1,10 @@
|
||||
# Omniledger 架构与开发记忆 (Memory)
|
||||
|
||||
## 优化 exportToCSV 数据净洗逻辑,利用防科学计数法的纯正则处理去除现价/成本价末尾的无意义零 (Task 69)
|
||||
- 在 `app/dashboard/page.tsx` 的 `exportToCSV()` 函数顶部注入 `stripTrailingZeros` 纯字符串去零工具函数。
|
||||
- 该函数内置防御性设计:对 null/undefined/空值返回 `"0"`;仅对包含小数点的字符串执行正则处理(`/0+$/` 剥离尾随零 → `/\.$/` 剥离末尾小数点),彻底杜绝极小数值(如 `0.00000001`)被 `String()` 转换后触发科学计数法(`1e-8`)。
|
||||
- 将 CSV 映射层中的"成本价"字段(`avgCostNative`)和"现价"字段(`latestPrice`)包裹 `stripTrailingZeros()`,使小米 `29.020` 输出为 `29.02`、整数价格 `29.00` 输出为 `29`,而"总市值""浮动盈亏""累计盈亏"等法币资产字段保留 `.toFixed(2)` 的两位小数格式以维持表格对齐。
|
||||
|
||||
## 新增持仓明细的已清仓资产显示开关(基于 1e-8 精度容差过滤),并实装注入 UTF-8 BOM 的客户端 CSV 导出功能 (Task 68)
|
||||
- 在 `src/actions/portfolio.ts` 的 `getPortfolioPositions()` 函数中新增 `includeCleared: boolean = false` 参数,将清仓判定从 `quantity === 0` 升级为 `Big.js` 的 `1e-8` 精度容差过滤(`holding.quantity.gt('1e-8')`),杜绝浮点数灰尘资产被错误保留或隐藏。
|
||||
- 当 `!includeCleared` 时,自动过滤掉持仓量 ≤ 1e-8 的已清仓资产;当 `includeCleared` 为 true 时,已清仓资产会被返回,其 `marketValue` 和 `floatingPnl` 为 0,但**保留真实计算出的 `accumulatedPnl`(累计盈亏)字段**,确保历史盈亏数据不丢失。
|
||||
|
||||
@ -56,14 +56,24 @@ function formatNative(value: string, baseCurrency: string): string {
|
||||
}
|
||||
|
||||
function exportToCSV(positions: any[]) {
|
||||
const stripTrailingZeros = (val: any): string => {
|
||||
if (val === null || val === undefined || val === '') return "0";
|
||||
let str = String(val);
|
||||
if (str.includes('.')) {
|
||||
str = str.replace(/0+$/, '');
|
||||
str = str.replace(/\.$/, '');
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
const headers = ["资产名称", "代码", "持仓量", "成本价", "现价", "总市值", "浮动盈亏", "累计盈亏"];
|
||||
|
||||
const rows = positions.map(item => [
|
||||
item.name || item.symbol,
|
||||
item.symbol,
|
||||
item.quantity || '0',
|
||||
new Big(item.avgCostNative || '0').toFixed(2),
|
||||
item.latestPrice || '0',
|
||||
stripTrailingZeros(new Big(item.avgCostNative || '0').toFixed(2)),
|
||||
stripTrailingZeros(item.latestPrice || '0'),
|
||||
new Big(item.marketValueNative || '0').toFixed(2),
|
||||
new Big(item.floatingPnlNative || '0').toFixed(2),
|
||||
new Big(item.cumulativePnlNative || '0').toFixed(2),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user