mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-02 20:27:49 +08:00
fix: accuracy loss in bigint field read pretty (#4360)
* fix: accuracy loss in bigint field read pretty * fix: accuracy loss in bigint field read pretty * fix: accuracy loss in bigint field read pretty * fix: accuracy loss in bigint field read pretty * fix: accuracy loss in bigint field read pretty * test: intege test * test: color test
This commit is contained in:
parent
46452ef275
commit
779029e348
@ -12,6 +12,7 @@ import { toFixedByStep } from '@nocobase/utils/client';
|
||||
import { format } from 'd3-format';
|
||||
import * as math from 'mathjs';
|
||||
import React, { useMemo } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
function countDecimalPlaces(value) {
|
||||
const number = Number(value);
|
||||
@ -28,7 +29,11 @@ const separators = {
|
||||
};
|
||||
//分隔符换算
|
||||
export function formatNumberWithSeparator(value, format = '0.00', step = 1, formatStyle?) {
|
||||
if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
|
||||
return formatBigNumberWithSeparator(value, format, step, formatStyle);
|
||||
}
|
||||
let number = value;
|
||||
|
||||
if (formatStyle) {
|
||||
number = Number(value);
|
||||
}
|
||||
@ -51,6 +56,33 @@ export function formatNumberWithSeparator(value, format = '0.00', step = 1, form
|
||||
}
|
||||
return formattedNumber;
|
||||
}
|
||||
//大字段分隔符换算
|
||||
function formatBigNumberWithSeparator(value, format = '0.00', step = 1, formatStyle?) {
|
||||
let number = value;
|
||||
|
||||
if (formatStyle) {
|
||||
number = new BigNumber(value).toString();
|
||||
}
|
||||
|
||||
let formattedNumber = '';
|
||||
if (separators[format]) {
|
||||
const { thousands, decimal } = separators[format];
|
||||
const [integerPart, initFractionalPart] = number.toString().split('.');
|
||||
let fractionalPart = initFractionalPart;
|
||||
// 格式化整数部分
|
||||
const formattedIntegerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousands);
|
||||
// 处理小数部分
|
||||
if (fractionalPart && step) {
|
||||
fractionalPart = fractionalPart.substring(0, step);
|
||||
formattedNumber = `${formattedIntegerPart}${decimal}${fractionalPart}`;
|
||||
} else {
|
||||
formattedNumber = formattedIntegerPart;
|
||||
}
|
||||
} else {
|
||||
formattedNumber = number.toString();
|
||||
}
|
||||
return formattedNumber;
|
||||
}
|
||||
|
||||
//单位换算
|
||||
export function formatUnitConversion(value, operator = '*', multiplier?: number) {
|
||||
@ -96,7 +128,7 @@ export function scientificNotation(number, decimalPlaces, separator = '.') {
|
||||
}
|
||||
|
||||
export function formatNumber(props) {
|
||||
const { step, formatStyle = 'normal', value, unitConversion, unitConversionType, separator = '0.00' } = props;
|
||||
const { step, formatStyle = 'normal', value, unitConversion, unitConversionType, separator = '0,0.00' } = props;
|
||||
|
||||
if (!isValid(value)) {
|
||||
return null;
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
import { fireEvent, render, screen } from '@nocobase/test/client';
|
||||
import React from 'react';
|
||||
import { formatNumberWithSeparator, formatUnitConversion, scientificNotation } from '../ReadPretty';
|
||||
import { formatNumberWithSeparator, formatUnitConversion, scientificNotation, formatNumber } from '../ReadPretty';
|
||||
import App2 from '../demos/addonBefore&addonAfter';
|
||||
import App3 from '../demos/highPrecisionDecimals';
|
||||
import App1 from '../demos/inputNumber';
|
||||
@ -126,6 +126,21 @@ describe('ReadPretty:formatUnitConversion', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ReadPretty:MAX_SAFE_INTEGER', () => {
|
||||
test('value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER', () => {
|
||||
const result = formatNumber({
|
||||
value: '1691195350092210177',
|
||||
formatStyle: 'normal',
|
||||
step: 1,
|
||||
});
|
||||
expect(result).toBe('1,691,195,350,092,210,177');
|
||||
});
|
||||
test('normal value', () => {
|
||||
const result = formatNumber({ value: 3, formatStyle: 'normal', step: 1 });
|
||||
expect(result).toBe('3');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ReadPretty:scientificNotation', () => {
|
||||
// Test case 1: Format a number into scientific notation with 2 decimal places
|
||||
test('Format number into scientific notation', () => {
|
||||
|
@ -135,7 +135,7 @@ test.describe('form item & view form', () => {
|
||||
await expect(
|
||||
page
|
||||
.getByLabel('block-item-CollectionField-general-form-general.integer-integer')
|
||||
.getByText(record.integer.toFixed(0)),
|
||||
.getByText(record.integer.toLocaleString()),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page
|
||||
@ -145,7 +145,7 @@ test.describe('form item & view form', () => {
|
||||
await expect(
|
||||
page
|
||||
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
|
||||
.getByText(`${(record.percent * 100).toFixed(0)}%`),
|
||||
.getByText(`${Math.round(record.percent * 100).toLocaleString()}%`),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page
|
||||
@ -195,9 +195,11 @@ test.describe('table column & table', () => {
|
||||
expectValue: async () => {
|
||||
await expect(page.getByRole('button', { name: record.email })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: record.singleLineText })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: String(record.integer) })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: record.integer.toLocaleString() })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: record.number.toFixed(0) })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: `${(record.percent * 100).toFixed(0)}%` })).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole('button', { name: `${Math.round(record.percent * 100).toLocaleString()}%` }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: record.longText.slice(0, 10) })).toBeVisible();
|
||||
},
|
||||
});
|
||||
|
@ -125,7 +125,7 @@ test.describe('form item & create form', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
|
||||
).not.toBeVisible();
|
||||
await expect(page.getByLabel('block-item-CollectionField-general-form-general.integer-integer')).toHaveText(
|
||||
'integer:112233',
|
||||
'integer:112,233',
|
||||
);
|
||||
},
|
||||
});
|
||||
@ -223,7 +223,7 @@ test.describe('form item & edit form', () => {
|
||||
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
|
||||
).not.toBeVisible();
|
||||
await expect(page.getByLabel('block-item-CollectionField-general-form-general.integer-integer')).toHaveText(
|
||||
`integer:${record.integer}`,
|
||||
`integer:${record.integer.toLocaleString()}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user