mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 07:45:18 +00:00
fix: formula field calculation error (#3929)
* fix: formula field calculation error * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * fix: bug * test: foumula e2e test
This commit is contained in:
parent
4ac2875d51
commit
aa96a16d1d
@ -2,17 +2,29 @@ import { connect, mapReadPretty } from '@formily/react';
|
||||
import { InputNumber as AntdNumber, InputNumberProps } from 'antd';
|
||||
import React from 'react';
|
||||
import { ReadPretty } from './ReadPretty';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
type ComposedInputNumber = React.ForwardRefExoticComponent<
|
||||
Pick<Partial<any>, string | number | symbol> & React.RefAttributes<unknown>
|
||||
> & {
|
||||
ReadPretty?: React.FC<InputNumberProps>;
|
||||
};
|
||||
|
||||
function toSafeNumber(value) {
|
||||
if (value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER) {
|
||||
return new BigNumber(value).toString();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
export const InputNumber: ComposedInputNumber = connect((props) => {
|
||||
const { onChange, ...others } = props;
|
||||
const handleChange = (v) => {
|
||||
onChange(Number.isNaN(v) ? null : v);
|
||||
if (Number.isNaN(v)) {
|
||||
onChange(null);
|
||||
} else {
|
||||
console.log(toSafeNumber(v));
|
||||
onChange(toSafeNumber(v));
|
||||
}
|
||||
};
|
||||
return <AntdNumber onChange={handleChange} {...others} />;
|
||||
}, mapReadPretty(ReadPretty));
|
||||
|
@ -20,7 +20,7 @@ const separators = {
|
||||
'0.00': { thousands: '', decimal: '.' }, // 没有千位分隔符
|
||||
};
|
||||
//分隔符换算
|
||||
export function formatNumberWithSeparator(value, format = '0.00', step = 1, formatStyle) {
|
||||
export function formatNumberWithSeparator(value, format = '0.00', step = 1, formatStyle?) {
|
||||
let number = value;
|
||||
if (formatStyle) {
|
||||
number = Number(value);
|
||||
|
@ -0,0 +1,24 @@
|
||||
import { T3879 } from './utils';
|
||||
|
||||
import { test, expect } from '@nocobase/test/e2e';
|
||||
|
||||
// https://nocobase.height.app/T-3529
|
||||
test('formula field calculation', async ({ page, mockPage }) => {
|
||||
const nocoPage = await mockPage(T3879).waitForInit();
|
||||
await nocoPage.goto();
|
||||
await page.getByLabel('block-item-CardItem-general-').click();
|
||||
await page
|
||||
.getByLabel('block-item-CollectionField-general-form-general.number1-number1')
|
||||
.getByRole('spinbutton')
|
||||
.click();
|
||||
await page
|
||||
.getByLabel('block-item-CollectionField-general-form-general.number1-number1')
|
||||
.getByRole('spinbutton')
|
||||
.fill('3');
|
||||
await page.getByLabel('block-item-CollectionField-general-form-general.number2-number2').click();
|
||||
await page
|
||||
.getByLabel('block-item-CollectionField-general-form-general.number2-number2')
|
||||
.getByRole('spinbutton')
|
||||
.fill('3');
|
||||
await expect(await page.locator('.nb-read-pretty-input-number').innerText()).toBe('6');
|
||||
});
|
@ -0,0 +1,394 @@
|
||||
import { PageConfig } from '@nocobase/test/e2e';
|
||||
|
||||
export const T3879: PageConfig = {
|
||||
collections: [
|
||||
{
|
||||
name: 'general',
|
||||
fields: [
|
||||
{
|
||||
key: 'ojv1s67810y',
|
||||
name: 'id',
|
||||
type: 'bigInt',
|
||||
interface: 'integer',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
allowNull: false,
|
||||
uiSchema: {
|
||||
type: 'number',
|
||||
title: '{{t("ID")}}',
|
||||
'x-component': 'InputNumber',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '0ahsnha9s0i',
|
||||
name: 'createdAt',
|
||||
type: 'date',
|
||||
interface: 'createdAt',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
field: 'createdAt',
|
||||
uiSchema: {
|
||||
type: 'datetime',
|
||||
title: '{{t("Created at")}}',
|
||||
'x-component': 'DatePicker',
|
||||
'x-component-props': {},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'u8mym9tukph',
|
||||
name: 'createdBy',
|
||||
type: 'belongsTo',
|
||||
interface: 'createdBy',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
target: 'users',
|
||||
foreignKey: 'createdById',
|
||||
uiSchema: {
|
||||
type: 'object',
|
||||
title: '{{t("Created by")}}',
|
||||
'x-component': 'AssociationField',
|
||||
'x-component-props': {
|
||||
fieldNames: {
|
||||
value: 'id',
|
||||
label: 'nickname',
|
||||
},
|
||||
},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
targetKey: 'id',
|
||||
},
|
||||
{
|
||||
key: '1o03q1bmmpm',
|
||||
name: 'updatedAt',
|
||||
type: 'date',
|
||||
interface: 'updatedAt',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
field: 'updatedAt',
|
||||
uiSchema: {
|
||||
type: 'string',
|
||||
title: '{{t("Last updated at")}}',
|
||||
'x-component': 'DatePicker',
|
||||
'x-component-props': {},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'xhhbeil1yyd',
|
||||
name: 'updatedBy',
|
||||
type: 'belongsTo',
|
||||
interface: 'updatedBy',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
target: 'users',
|
||||
foreignKey: 'updatedById',
|
||||
uiSchema: {
|
||||
type: 'object',
|
||||
title: '{{t("Last updated by")}}',
|
||||
'x-component': 'AssociationField',
|
||||
'x-component-props': {
|
||||
fieldNames: {
|
||||
value: 'id',
|
||||
label: 'nickname',
|
||||
},
|
||||
},
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
targetKey: 'id',
|
||||
},
|
||||
{
|
||||
key: 'z37glqjfxsu',
|
||||
name: 'number1',
|
||||
type: 'double',
|
||||
interface: 'number',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
uiSchema: {
|
||||
'x-component-props': {
|
||||
step: '1',
|
||||
stringMode: true,
|
||||
},
|
||||
type: 'number',
|
||||
'x-component': 'InputNumber',
|
||||
title: 'number1',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: '9u6q4vycsiw',
|
||||
name: 'number2',
|
||||
type: 'double',
|
||||
interface: 'number',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
uiSchema: {
|
||||
'x-component-props': {
|
||||
step: '1',
|
||||
stringMode: true,
|
||||
},
|
||||
type: 'number',
|
||||
'x-component': 'InputNumber',
|
||||
title: 'number2',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'sxy03y6frg3',
|
||||
name: 'formula',
|
||||
type: 'formula',
|
||||
interface: 'formula',
|
||||
description: null,
|
||||
collectionName: 'general',
|
||||
parentKey: null,
|
||||
reverseKey: null,
|
||||
dataType: 'double',
|
||||
uiSchema: {
|
||||
'x-component-props': {
|
||||
step: '1',
|
||||
stringMode: true,
|
||||
},
|
||||
type: 'string',
|
||||
'x-component': 'Formula.Result',
|
||||
'x-read-pretty': true,
|
||||
title: 'formula',
|
||||
},
|
||||
engine: 'math.js',
|
||||
expression: '{{number1}}+{{number2}}',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
pageSchema: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Page',
|
||||
properties: {
|
||||
'8hkd58b3qnq': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'page:addBlock',
|
||||
properties: {
|
||||
'52dyxddrvtm': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
i1kv7cehwlv: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
'4j1qw9tuuae': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-acl-action-props': {
|
||||
skipScopeCheck: true,
|
||||
},
|
||||
'x-acl-action': 'general:create',
|
||||
'x-decorator': 'FormBlockProvider',
|
||||
'x-use-decorator-props': 'useCreateFormBlockDecoratorProps',
|
||||
'x-decorator-props': {
|
||||
dataSource: 'main',
|
||||
collection: 'general',
|
||||
},
|
||||
'x-toolbar': 'BlockSchemaToolbar',
|
||||
'x-settings': 'blockSettings:createForm',
|
||||
'x-component': 'CardItem',
|
||||
properties: {
|
||||
jj471ycbuz0: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'FormV2',
|
||||
'x-use-component-props': 'useCreateFormBlockProps',
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'form:configureFields',
|
||||
properties: {
|
||||
'860f2ujyhx2': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
thtymo9b987: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
number1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'fieldSettings:FormItem',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': 'general.number1',
|
||||
'x-component-props': {},
|
||||
'x-uid': 'afjer0fjqx6',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'ec4uvlevafy',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'bgjkklybgur',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
ogiz7jghxo2: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
tn4unrkfwt7: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
number2: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'fieldSettings:FormItem',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': 'general.number2',
|
||||
'x-component-props': {},
|
||||
'x-uid': 'terpf07giw3',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'h8igfdq7r9m',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '9p03cl31g6b',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
n5en8fni23d: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
i5ydxdhtbg1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
formula: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
'x-toolbar': 'FormItemSchemaToolbar',
|
||||
'x-settings': 'fieldSettings:FormItem',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': 'general.formula',
|
||||
'x-component-props': {},
|
||||
'x-read-pretty': true,
|
||||
'x-uid': 's6wgood8gvh',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'vegea94g2p3',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 't3e5slk8oz0',
|
||||
'x-async': false,
|
||||
'x-index': 3,
|
||||
},
|
||||
},
|
||||
'x-uid': 'ch6n1991w36',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
'58gw5mli2ch': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-initializer': 'createForm:configureActions',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
layout: 'one-column',
|
||||
style: {
|
||||
marginTop: 24,
|
||||
},
|
||||
},
|
||||
'x-uid': '2z5u3wiumtl',
|
||||
'x-async': false,
|
||||
'x-index': 2,
|
||||
},
|
||||
},
|
||||
'x-uid': '2wsiciz1bzn',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '0qha4fhtb5c',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'zy5e2j75f5v',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '0cw0sjxwlli',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': '13kkb5ow3ex',
|
||||
'x-async': false,
|
||||
'x-index': 1,
|
||||
},
|
||||
},
|
||||
'x-uid': 'otwpz1wc0af',
|
||||
'x-async': true,
|
||||
'x-index': 1,
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue
Block a user