fix: show count traffic (#1062)
Reviewed-on: daoyoucloud/tachybase#1062 Co-authored-by: bai.zixv <bai.zixv@foxmail.com> Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
parent
b15d9e6790
commit
90c4a66889
@ -26,7 +26,7 @@ export const checkboxComponentFieldSettings = new SchemaSettings({
|
||||
return {
|
||||
title: t('Field component'),
|
||||
options: fieldModeOptions,
|
||||
value: fieldSchema['x-component-props'].mode || 'Checkbox',
|
||||
value: fieldSchema['x-component-props']?.mode || 'Checkbox',
|
||||
onChange(mode) {
|
||||
const schema = {
|
||||
['x-uid']: fieldSchema['x-uid'],
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { onFormValuesChange } from '@tachybase/schema';
|
||||
import { useField, useFieldSchema, useForm, useFormEffects } from '@tachybase/schema';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Input } from '@tachybase/client';
|
||||
import { evaluators } from '@tachybase/evaluators/client';
|
||||
import { onFormValuesChange, useField, useFieldSchema, useForm, useFormEffects } from '@tachybase/schema';
|
||||
|
||||
import { Descriptions, DescriptionsProps } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { evaluators } from '@tachybase/evaluators/client';
|
||||
|
||||
const transformFormula = (formula: string) => {
|
||||
if (!formula) return [];
|
||||
const formulaArray = formula.split(/([+\-*/?:()%])/).filter((item) => item);
|
||||
@ -12,11 +13,11 @@ const transformFormula = (formula: string) => {
|
||||
};
|
||||
|
||||
export const CalcResult = (props) => {
|
||||
// 公式,单位,前缀,后缀,小数点位数,面板逻辑代码
|
||||
const { formula, prefix, suffix, decimal, panel } = props;
|
||||
const form = useForm();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const field = useField();
|
||||
// 公式,单位,前缀,后缀,小数点位数,面板逻辑代码
|
||||
const { formula, prefix, suffix, decimal, panel } = props;
|
||||
const path: any = field.path.entire;
|
||||
const fieldPath = path?.replace(`.${fieldSchema.name}`, '');
|
||||
const engine = evaluators.get('math.js');
|
||||
|
@ -0,0 +1,12 @@
|
||||
import { Plugin } from '@tachybase/client';
|
||||
|
||||
import { SCFormula, ShowFieldFormulaInterface } from './show-formula/Formula.interface';
|
||||
|
||||
export class PluginFieldAppends extends Plugin {
|
||||
async afterAdd() {
|
||||
this.app.pm.add(SCFormula);
|
||||
}
|
||||
async load() {
|
||||
this.app.dataSourceManager.addFieldInterfaces([ShowFieldFormulaInterface]);
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
import { CollectionFieldInterface, interfacesProperties, Plugin } from '@tachybase/client';
|
||||
|
||||
import { ViewFormula } from './Formula.view';
|
||||
|
||||
const { defaultProps } = interfacesProperties;
|
||||
|
||||
export interface FormulaProps {
|
||||
// 公式字符串
|
||||
formulaString: string;
|
||||
// 前缀
|
||||
prefix: string;
|
||||
// 后缀
|
||||
suffix: string;
|
||||
// 精度
|
||||
decimal: string;
|
||||
}
|
||||
|
||||
export class SCFormula extends Plugin {
|
||||
async load() {
|
||||
this.app.addComponents({
|
||||
Viewformula: ViewFormula,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ShowFieldFormulaInterface extends CollectionFieldInterface {
|
||||
name = 'formulaShow';
|
||||
type = 'object';
|
||||
group = 'advanced';
|
||||
title = '公式(显示)';
|
||||
description = '通过公式, 用于定制化显示用户界面内容';
|
||||
sortable = true;
|
||||
default = {
|
||||
type: 'virtual',
|
||||
uiSchema: {
|
||||
type: 'string',
|
||||
'x-component': 'Viewformula',
|
||||
'x-component-props': {
|
||||
formulaString: '',
|
||||
prefix: '',
|
||||
suffix: '',
|
||||
decimal: '',
|
||||
} as FormulaProps,
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
};
|
||||
properties = {
|
||||
...defaultProps,
|
||||
'uiSchema.x-component-props.prefix': {
|
||||
type: 'string',
|
||||
title: '前缀',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
'uiSchema.x-component-props.suffix': {
|
||||
type: 'string',
|
||||
title: '后缀',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
'uiSchema.x-component-props.decimal': {
|
||||
type: 'string',
|
||||
title: '{{t("Precision")}}',
|
||||
'x-component': 'Select',
|
||||
'x-decorator': 'FormItem',
|
||||
required: true,
|
||||
default: '0',
|
||||
enum: [
|
||||
{ value: '0', label: '1' },
|
||||
{ value: '1', label: '1.0' },
|
||||
{ value: '2', label: '1.00' },
|
||||
{ value: '3', label: '1.000' },
|
||||
{ value: '4', label: '1.0000' },
|
||||
{ value: '5', label: '1.00000' },
|
||||
],
|
||||
},
|
||||
'uiSchema.x-component-props.formulaString': {
|
||||
type: 'string',
|
||||
title: '公式',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
default: '',
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
import React from 'react';
|
||||
import { Input } from '@tachybase/client';
|
||||
import evaluators from '@tachybase/evaluators/client';
|
||||
import { useField, useFieldSchema, useForm } from '@tachybase/schema';
|
||||
|
||||
import { FormulaProps } from './Formula.interface';
|
||||
|
||||
export const ViewFormula = (props: FormulaProps) => {
|
||||
const { resultShowValue } = useAction(props);
|
||||
return <Input.ReadPretty value={resultShowValue} />;
|
||||
};
|
||||
|
||||
function useAction(props: FormulaProps) {
|
||||
const form = useForm();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const field = useField();
|
||||
const { formulaString, prefix, suffix, decimal } = props;
|
||||
|
||||
const path: any = field.path.entire;
|
||||
const fieldPath = path?.replace(`.${fieldSchema.name}`, '');
|
||||
const engine = evaluators.get('math.js');
|
||||
const evaluate = engine.evaluate.bind(engine);
|
||||
const transformFormulaArray = transformFormula(formulaString);
|
||||
|
||||
let calculateData = [];
|
||||
|
||||
const newFormulaArray = (data): [string, object] => {
|
||||
calculateData = [];
|
||||
let count = 0;
|
||||
const scopes = {};
|
||||
if (transformFormulaArray.length === 0) return;
|
||||
for (let i = 0; i < transformFormulaArray.length; i++) {
|
||||
const item = transformFormulaArray[i];
|
||||
if (!item) continue;
|
||||
const isNumber = !isNaN(Number(item));
|
||||
const symbol = ['+', '-', '*', '/', '?', ':', '(', ')', '%'].includes(item);
|
||||
if (!isNumber && !symbol) {
|
||||
let value;
|
||||
// 举例: ${fieldObj}.fieldName
|
||||
const pattern = /\${(.*?)}/g;
|
||||
if (item.match(pattern)?.length) {
|
||||
const target = item.match(pattern)[0].replace(/\${|}/g, '');
|
||||
// 以.分割字符串
|
||||
const targetField = item.split('.')[1];
|
||||
|
||||
if (path === fieldPath) {
|
||||
// @ts-ignore
|
||||
value = _.chain(data).get(target).get(targetField, 0).value();
|
||||
} else {
|
||||
// @ts-ignore
|
||||
value = _.chain(data).get(fieldPath).get(target).get(targetField, 0).value();
|
||||
}
|
||||
} else {
|
||||
if (path === fieldPath) {
|
||||
// @ts-ignore
|
||||
value = _.chain(data).get(item, 0).value();
|
||||
} else {
|
||||
// @ts-ignore
|
||||
value = _.chain(data).get(fieldPath).get(item, 0).value();
|
||||
}
|
||||
}
|
||||
if (!value) {
|
||||
value = 0;
|
||||
}
|
||||
count += 1;
|
||||
const varName = 'var' + count;
|
||||
const varValue = value;
|
||||
scopes[varName] = varValue;
|
||||
calculateData.push('{{' + varName + '}}');
|
||||
} else {
|
||||
calculateData.push(item);
|
||||
}
|
||||
}
|
||||
return [calculateData.join(''), scopes];
|
||||
};
|
||||
|
||||
const formulaArray = newFormulaArray(form.values);
|
||||
|
||||
if (!formulaArray) {
|
||||
return {};
|
||||
}
|
||||
const [code, scopes] = formulaArray;
|
||||
let resultShowValue;
|
||||
try {
|
||||
const pre = prefix || '';
|
||||
const suf = suffix || '';
|
||||
const res = evaluate(code, scopes);
|
||||
const main = isNaN(res) ? res : Number(res).toFixed(+decimal || 0);
|
||||
resultShowValue = pre + main + suf;
|
||||
} catch (error) {
|
||||
resultShowValue = `${code}`;
|
||||
console.warn('code: ', code, ' scopes: ', scopes, 'error: ', resultShowValue, ' error message ', error.message);
|
||||
}
|
||||
|
||||
return { resultShowValue };
|
||||
}
|
||||
|
||||
function transformFormula(formula: string) {
|
||||
if (!formula) return [];
|
||||
const formulaArray = formula.split(/([+\-*/?:()%])/).filter((item) => item);
|
||||
return formulaArray;
|
||||
}
|
@ -18,6 +18,7 @@ import { PluginContextMenu } from './features/context-menu';
|
||||
import { DepartmentsPlugin } from './features/departments';
|
||||
import { EmbedPlugin } from './features/embed';
|
||||
import { PluginExtendedFilterForm } from './features/extended-filter-form';
|
||||
import { PluginFieldAppends } from './features/field-appends';
|
||||
import { PluginHeraVersion } from './features/hera-version';
|
||||
import { PluginOutbound } from './features/outbound';
|
||||
import { PluginPageStyle } from './features/page-style';
|
||||
@ -85,6 +86,7 @@ export class PluginCoreClient extends Plugin {
|
||||
await this.app.pm.add(PluginExtendedFilterForm);
|
||||
await this.app.pm.add(PluginOutbound);
|
||||
// await this.app.pm.add(PluginModeHighlight);
|
||||
await this.app.pm.add(PluginFieldAppends);
|
||||
}
|
||||
|
||||
async registerSettings() {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { interfacesProperties, CollectionFieldInterface } from '@tachybase/client';
|
||||
import { CollectionFieldInterface, interfacesProperties } from '@tachybase/client';
|
||||
|
||||
const { defaultProps } = interfacesProperties;
|
||||
|
||||
const formulaType = [
|
||||
@ -27,7 +28,7 @@ export class CalcFieldInterface extends CollectionFieldInterface {
|
||||
name = 'calc2';
|
||||
type = 'object';
|
||||
group = 'advanced';
|
||||
title = '数据计算';
|
||||
title = '数据计算(过期)';
|
||||
description = '数据字段计算';
|
||||
sortable = true;
|
||||
default = {
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { interfacesProperties, CollectionFieldInterface } from '@tachybase/client';
|
||||
import { CollectionFieldInterface, interfacesProperties } from '@tachybase/client';
|
||||
|
||||
const { defaultProps } = interfacesProperties;
|
||||
|
||||
export class CustomFieldInterface extends CollectionFieldInterface {
|
||||
name = 'custom';
|
||||
type = 'object';
|
||||
group = 'advanced';
|
||||
title = '自定义字段';
|
||||
description = '自定义字段';
|
||||
title = '组件字段';
|
||||
description = '组件字段';
|
||||
sortable = true;
|
||||
default = {
|
||||
type: 'virtual',
|
||||
|
Loading…
Reference in New Issue
Block a user