import { getExtComponent } from '@alife/cn-lowcode-utils';
import isPlainObject from 'lodash/isPlainObject';
import get from 'lodash/get';
import isNaN from 'lodash/isNaN';
import isNumber from 'lodash/isNumber';
import trim from 'lodash/trim';
import uniq from 'lodash/uniq';
import qs from 'query-string';
import { customAlphabet } from 'nanoid';
import cloneDeep from 'lodash/cloneDeep';
import {
componentMap as filterItemComponentMap,
transRulesToValidator,
} from '../manager/filter-item';
import dayjs from 'dayjs';
import isArray from 'lodash/isArray';
import { getButtonAction, getItem as getButtonItem } from '../manager/button';
import merge from 'lodash/merge';
import {
symbolMap,
tableCurrentRowLabel,
__arrayTableCurrentRow__,
__dataSource__,
__extraParam__,
__paging__,
__selectedRowKeys__,
__selectedRowRecords__,
__tableColumns__,
__tableCurrentRow__,
__tableData__,
__tableExtra__,
__tab_activeKey__,
formDialogStateLabel,
openDialogModeLabel,
__stateValueOfSplit__,
__formValue__,
__filterValue__,
__list_currentItem__,
} from './expr-const';
import { handleRequestParams, makeRequest } from '../manager/request';
import { CnMessage, CnIcon, CnButton } from '@cainiaofe/cn-ui-m';
import {
_dataSourceName,
allowSelectFirstComponentList,
dataOriginRequest,
dataOriginStatic,
formUrlencoded,
needSaveDataFlowActionList,
preMokelayDomain,
recursionComponentList,
} from '@/common/util/const';
import { ButtonPosition } from '@/type/button-position';
import { DisplayPosition } from '@/type/display-position';
import { ValidatorPosition } from '@/type/validator-position';
import {
_getContext,
_getFormValues,
} from '@/common/util/biz-component-prop-name';
// 缓存表单配置项
const cacheFormConfig = {};
const { VisualEngine } = window;
const Engine = VisualEngine;
export const __urlParams__ = '__urlParams__';
export const __record__ = '__record__';
export const __ds__ = '__ds__';
export const __blank__ = '__blank__';
const messageTypeMap = {
success: 'success',
warning: 'warning',
error: 'error',
notice: 'notice',
help: 'help',
loading: 'loading',
};
// 获取业务组件列表
export function getBizComponentNameList() {
let result = [];
if (VisualEngine) {
const componentsMap = VisualEngine?.designer?.getComponentsMap?.();
if (componentsMap) {
result = Object.keys(componentsMap);
}
}
return result;
}
function getRunTimeBizComponent(name) {
if (name) {
let result;
const componentsMap = VisualEngine?.designer?.getComponentsMap?.();
if (componentsMap && componentsMap[name]) {
result = {
componentName: name,
component: {
realize: () => {
return componentsMap[name];
},
},
};
} else if (window.ConeRenderEngine) {
const components = getRealComponents();
if (components?.length > 0) {
const com = components.find((item) => item.name === name);
if (com && com.module) {
result = {
componentName: name,
component: {
realize: () => {
return com.module;
},
},
};
}
}
} else {
const com = getExtComponent(name);
if (com) {
result = {
componentName: com.name,
component: {
realize: () => {
return com.module;
},
},
};
}
}
if (isPlainObject(result)) {
result.isBizComponent = true;
}
return result;
}
}
function getRealComponents() {
const components = window?.ConeRenderEngine?.core?.components;
if (isArrayNotEmpty(components)) {
return components;
} else {
return window?.renderContext?.rawComponents || [];
}
}
function getRealResponse(res = {}) {
const { status, data } = res;
let result = res;
if (status === 200 && data) {
result = data;
}
return result;
}
export function getBizComponent(name, position) {
if (name) {
const componentMeta = VisualEngine?.designer?.getComponentMeta(name);
if (componentMeta) {
const { prototype } = componentMeta;
if (prototype) {
const config = prototype.getConfig?.();
const packageName = prototype.getPackageName?.();
if (config) {
const runtimeComponent = getRunTimeBizComponent(name);
const {
title,
category,
cnLowCodeConfig,
componentName,
configure = [],
} = config;
if (cnLowCodeConfig && componentName && runtimeComponent) {
const { position: comPosition = [] } = cnLowCodeConfig;
if (comPosition.includes(position)) {
const tempList = [
DisplayPosition.filter,
DisplayPosition.form,
DisplayPosition.formDialog,
DisplayPosition.tableCell,
ButtonPosition.tableCell,
ButtonPosition.tableOperate,
ButtonPosition.tableBatchArea,
ButtonPosition.tableToolArea,
ButtonPosition.formDialog,
ButtonPosition.form,
ValidatorPosition.formDialog,
ValidatorPosition.form,
DisplayPosition.tableRowDetail,
DisplayPosition.cnArrayTable,
ButtonPosition.dialog,
DisplayPosition.dialogTitle,
ButtonPosition.formItemEvent,
ButtonPosition.formDialogItemEvent,
];
if (tempList.includes(position)) {
const result = {
// 业务方
bizInfo: [
{
label: '业务组件',
value: 'common',
},
],
category,
...cnLowCodeConfig,
title,
componentName,
packageName,
component: {
realize: () => {
return VisualEngine.designer?.getComponentsMap?.()[
componentName
];
},
},
};
if (configure?.length > 0) {
result.configure = configure;
}
return result;
}
}
}
}
}
}
}
}
export function condition(prop, type, primaryKey) {
return prop?.parent?.parent?.getPropValue?.(primaryKey) === type;
}
export function handlePrototypeCondition(
prototypeList = [],
componentName,
primaryKey,
) {
if (prototypeList?.length > 0) {
return prototypeList.map((item) => {
let newItem = item;
if (isPlainObject(item)) {
newItem = { ...item };
newItem.__optType = componentName;
}
if (!newItem?.condition) {
newItem.condition = function (prop) {
return condition(prop, componentName, primaryKey);
};
}
return newItem;
});
}
return prototypeList;
}
export const generateIndex = (dataSourceList, componentName, key = 'value') => {
let index = 2;
while (
dataSourceList.find((item) => item[key] === `${componentName}${index}`)
) {
index++;
}
return index;
};
export function getRunTimeItem(componentMap, componentName) {
let result;
if (componentName) {
result = componentMap[componentName];
if (!result) {
result = getRunTimeBizComponent(componentName);
}
}
return result;
}
export const findNodeConfigListByDataSourceName = (config) => {
const { dsNameKey, dsName } = config || {};
const nodesMap = VisualEngine?.designer?.currentDocument?.nodesMap;
const result: any = {
configList: [],
node: null,
};
if (nodesMap?.values()) {
for (const item of nodesMap?.values()) {
if (item?.getPropValue?.(dsNameKey) === dsName) {
const { componentName } = item;
if (componentName === 'CnTable') {
result.configList = [
{
label: tableCurrentRowLabel,
text: tableCurrentRowLabel,
value: `state.${dsName}.${__tableCurrentRow__}`,
},
{
label: '选中数据主键列表(selectedRowKeys)',
text: '选中数据主键列表(selectedRowKeys)',
value: `state.${dsName}.${__selectedRowKeys__}`,
},
{
label: '选中数据列表(selectedRowRecords)',
text: '选中数据列表(selectedRowRecords)',
value: `state.${dsName}.${__selectedRowRecords__}`,
},
{
label: '表格请求返回的数据(tableData)',
text: '表格请求返回的数据(tableData)',
value: `state.${dsName}.${__tableData__}`,
},
{
label: '表格的列头(columns)',
text: '表格的列头(columns)',
value: `state.${dsName}.${__tableColumns__}`,
},
{
label: '表格请求返回的分页信息(paging)',
text: '表格请求返回的分页信息(paging)',
value: `state.${dsName}.${__paging__}`,
children: [
{
label: '当前页(currentPage)',
text: '当前页(currentPage)',
value: `state.${dsName}.${__paging__}.currentPage`,
},
{
label: '每页显示几条(pageSize)',
text: '每页显示几条(pageSize)',
value: `state.${dsName}.${__paging__}.pageSize`,
},
{
label: '数据总个数(totalCount)',
text: '数据总个数(totalCount)',
value: `state.${dsName}.${__paging__}.totalCount`,
},
],
},
{
label: '请求返回的额外信息(extra)',
text: '请求返回的额外信息(extra)',
value: `state.${dsName}.${__tableExtra__}`,
},
];
} else if (componentName === 'CnTab') {
result.configList = [
{
label: 'Tab的选中项',
text: 'Tab的选中项',
value: `state.${dsName}.${__tab_activeKey__}`,
},
];
} else if (componentName === 'CnList') {
result.configList = [
{
label: 'List 当前点击项',
text: 'List 当前点击项',
value: `state.${dsName}.${__list_currentItem__}`,
},
]
} else {
const configList = item?.getPropValue?.('config');
if (Array.isArray(configList) && configList.length > 0) {
const tempList = handleOriginList(
configList,
'label',
'name',
`state.${dsName}`,
{ dsName },
);
if (isArrayNotEmpty(tempList)) {
result.configList = [...result.configList, ...tempList];
}
}
if (componentName === 'CnFormDialog') {
result.configList.push({
label: formDialogStateLabel,
children: [
{
label: openDialogModeLabel,
value: `state.valueOf.${dsName}${__stateValueOfSplit__}openDialogMode`,
},
],
});
}
}
result.node = item;
break;
}
}
}
return result;
};
export function handleComponentTitle(title) {
if (typeof title === 'string') {
return title;
} else if (isPlainObject(title)) {
const { mock, type, value } = title;
if (type === 'JSExpression') {
if (mock) {
return mock;
} else {
return '动态标题弹窗';
}
}
return '动态标题';
}
return title;
}
export function handleI18nLabel(label) {
if (isPlainObject(label) && label.type === 'cn-i18n') {
return label.dm || '';
}
return label;
}
export function getNodeTitle(node) {
const { propsData, componentName } = node || {};
const { tableName } = propsData || {};
let { title } = propsData || {};
title = handleComponentTitle(handleI18nLabel(title));
let realTitle = title;
if (componentName === 'CnTable') {
return tableName || '表格';
}
if (title) {
if (componentName === 'CnFormDialog') {
realTitle = `表单弹窗_${title}`;
} else if (componentName === 'CnDialog') {
realTitle = `弹窗_${title}`;
}
return realTitle;
}
}
export const getDataSourceList = (config) => {
const { typeList, needChildren } = config || {};
const dataSource = VisualEngine?.context?.getManager('dataPool');
const items = dataSource?.getItems();
const result = [];
if (items?.length > 0) {
items.forEach((item) => {
const { id, name, type, config: dsConfig } = item;
const label = dsConfig?.description || name;
const ds = {
text: label,
label,
value: name,
dataSourceId: dsConfig?.id,
id,
};
const temp = findNodeConfigListByDataSourceName({
dsNameKey: '_dataSourceName',
dsName: name,
});
const { configList, node } = temp || {};
const title = getNodeTitle(node);
ds.componentName = node?.componentName;
if (title) {
ds.label = title;
ds.text = title;
}
if (needChildren) {
if (configList?.length > 0) {
ds.children = configList;
}
}
if (Array.isArray(typeList) && typeList.length > 0) {
if (typeList.includes(type)) {
result.push(ds);
}
} else {
result.push(ds);
}
});
}
return result;
};
export const getDataSourceListWithAllPath = (config) => {
const { typeList, needChildren, prototypeConfig } = config || {};
const dataSource = VisualEngine?.context?.getManager('dataPool');
const items = dataSource?.getItems();
const result = [];
const { flowList, currentFlowIndex } = prototypeConfig || {};
if (items?.length > 0) {
items.forEach((item) => {
const { name, type, config: dsConfig } = item;
const label = dsConfig?.description || name;
const ds = {
text: label,
label,
value: `state.${name}`,
};
const temp = findNodeConfigListByDataSourceName({
dsNameKey: '_dataSourceName',
dsName: name,
});
const { configList, node } = temp || {};
const title = getNodeTitle(node);
if (title) {
ds.label = title;
ds.text = title;
}
if (needChildren) {
if (configList?.length > 0) {
ds.children = configList;
}
}
if (Array.isArray(typeList) && typeList.length > 0) {
if (typeList.includes(type)) {
result.push(ds);
}
} else {
result.push(ds);
}
});
}
if (
typeof currentFlowIndex === 'number' &&
Array.isArray(flowList) &&
flowList.length > 0
) {
const existFlowList = flowList.slice(0, currentFlowIndex);
if (existFlowList?.length > 0) {
const extra: any = {
label: '动作编排的数据',
children: [],
};
existFlowList.forEach((item, index) => {
const { optType, active, options } = item || {};
if (optType && active === true) {
if (needSaveDataFlowActionList.includes(optType)) {
let realIndex = index;
if (index === 0) {
realIndex = '';
}
const currentFlowValue = `state.valueOf.${optType}${realIndex}`;
let realLabel = '发请求';
let children = [
{
label: 'success',
value: `${currentFlowValue}.success`,
},
{
label: 'data',
value: `${currentFlowValue}.data`,
},
{
label: 'msg',
value: `${currentFlowValue}.msg`,
},
];
if (optType === 'submit') {
realLabel = '提交';
} else if (optType === 'jsbridge') {
realLabel = '跨端JsBridge';
children = [
{
label: 'success',
value: `${currentFlowValue}.success`,
},
{
label: 'data',
value: `${currentFlowValue}.data`,
},
{
label: 'error',
value: `${currentFlowValue}.error`,
},
];
}
extra.children.push({
label: `${realLabel}${realIndex}`,
value: currentFlowValue,
children,
});
}
}
});
if (extra.children.length > 0) {
result.unshift(extra);
}
}
}
return result;
};
function getFlowListDataSource(config) {
const result = [];
const { currentFlowIndex, flowList } = config || {};
if (
typeof currentFlowIndex === 'number' &&
Array.isArray(flowList) &&
flowList.length > 0
) {
const existFlowList = flowList.slice(0, currentFlowIndex);
if (existFlowList?.length > 0) {
existFlowList.forEach((item, index) => {
const { optType, active } = item || {};
if (optType && active !== false) {
let flowLabel;
if (optType === 'submit') {
flowLabel = '提交';
} else if (optType === 'request') {
flowLabel = '发请求';
}
if (['request', 'submit'].includes(optType)) {
let realIndex = index;
if (index === 0) {
realIndex = '';
}
const currentFlowValue = `${__dataSource__}.valueOf.${optType}${realIndex}`;
result.push({
label: `${flowLabel}${realIndex}`,
value: currentFlowValue,
children: [
{
label: 'success',
value: `${currentFlowValue}.success`,
},
{
label: 'data',
value: `${currentFlowValue}.data`,
},
{
label: 'msg',
value: `${currentFlowValue}.msg`,
},
],
});
}
}
});
}
}
return result;
}
export function getRealizeValue(v) {
if (v && typeof v.realize === 'function') {
return v.realize();
}
return v;
}
export function isTextExpr(str) {
if (typeof str === 'string' && str.length > 0) {
if (str === __blank__) {
return {
prefix: __blank__,
};
} else if (str.startsWith(`${__record__}`)) {
return {
prefix: __record__,
value: str.replace(`${__record__}.`, ''),
};
} else if (str.startsWith(__urlParams__)) {
return {
prefix: __urlParams__,
value: str.replace(`${__urlParams__}.`, ''),
};
} else if (str.startsWith(__ds__)) {
if (str.endsWith(__ds__)) {
const dataSourceName = str.slice(6, str.lastIndexOf(__ds__));
return {
prefix: __ds__,
dataSourceName,
};
} else {
const index = str.indexOf(`${__ds__}.`);
if (index > 0) {
const dataSourceName = str.slice(6, index);
const value = str.slice(index + 7);
if (value && dataSourceName) {
return {
prefix: __ds__,
value,
dataSourceName,
};
}
}
}
}
}
return false;
}
export function isValueObjectExpr(obj) {
return !!(isPlainObject(obj) && obj.group && obj.param);
}
export function executeFunction(func, ...rest) {
if (typeof func === 'function') {
let result;
try {
result = func(...rest);
} catch (e) {}
return result;
}
}
export function calculateTextExprValue(originValue, config = {}) {
const textExpr = isTextExpr(originValue);
const {
urlParamsDataSource,
recordDataSource,
state,
extraParamList = [],
tableCurrentRow,
extraParam,
getExtraParam,
} = config;
if (textExpr) {
const { prefix, value: textExprValue, dataSourceName } = textExpr;
let temp;
if (prefix === __blank__) {
temp = undefined;
} else if (prefix === __record__) {
temp = recordDataSource;
} else if (prefix === __urlParams__) {
temp = urlParamsDataSource;
} else if (prefix === __ds__ && dataSourceName) {
temp = state?.[dataSourceName];
}
if (textExprValue) {
return get(temp, textExprValue);
} else {
return temp;
}
} else if (typeof originValue === 'function') {
try {
let extra = extraParamList;
if (!Array.isArray(extra)) {
extra = [];
}
return originValue(recordDataSource, state, ...extra);
} catch (e) {
return;
}
} else if (isValueObjectExpr(originValue)) {
const { group, param, secondParam, thirdParam } = originValue;
if (group && param) {
let result;
let realExtraParam = extraParam;
if (typeof getExtraParam === 'function') {
realExtraParam = executeFunction(getExtraParam);
}
const objExprArgMap = {
[__record__]: recordDataSource,
[__dataSource__]: state,
[__tableCurrentRow__]: tableCurrentRow,
[__extraParam__]: realExtraParam,
};
if (secondParam) {
result = get(
objExprArgMap,
`${group}.${param}.${secondParam}${
thirdParam ? `.${thirdParam}` : ''
}`,
);
} else {
result = get(objExprArgMap, `${group}.${param}`);
}
return result;
}
}
return originValue;
}
function calculateUrl(config, extra) {
const { url, urlParams = [] } = config || {};
if (url) {
let search = '';
const { urlParamsDataSource, recordDataSource, state, extraParamList } =
extra || {};
if (urlParams && urlParams.length > 0) {
const temp = handleRequestParams(urlParams, {
urlParamsDataSource,
recordDataSource,
state,
extraParamList,
});
search = qs.stringify(temp);
}
let realUrl = calculateTextExprValue(url, {
urlParamsDataSource,
recordDataSource,
state,
extraParamList,
});
if (typeof realUrl === 'string' && realUrl.length > 0) {
if (realUrl.indexOf('?') !== -1) {
realUrl += `&${search}`;
} else {
realUrl += `?${search}`;
}
return realUrl;
}
}
}
export function makeFormItemSchema(config) {
const {
formItemConfig,
isDesign,
urlParams,
formValue,
state,
usedComponentList,
formProps,
_context,
formInstance,
getFormInstance,
isInCnFilterPro,
} = config || {};
const { formStyle } = formProps || {};
const { readOnly: formReadOnly, allowCopy } = formStyle || {};
const {
label,
name,
componentName,
rules = [],
options = {},
disabled,
hidden,
hasClear,
tip,
readOnly,
placeholder,
extra,
colSpan,
readOnlyClick,
size,
labelAlign,
__advancedCodeConfig__,
} = formItemConfig || {};
const { handleProps } = __advancedCodeConfig__ || {};
const title = label;
const { dataOrigin } = options;
let componentProps = { ...options };
if (formReadOnly === true && allowCopy === true) {
componentProps.readOnlyProps = {
allowCopy: true,
};
}
if (isPlainObject(readOnlyClick)) {
if (readOnlyClick?.optType) {
const action = getButtonAction({
...readOnlyClick,
position: ButtonPosition.arrayTableCell,
});
if (action && !isDesign) {
if (!componentProps.readOnlyProps) {
componentProps.readOnlyProps = {};
}
if (typeof action === 'function') {
componentProps.readOnlyProps.onClick = action.bind(null, {
buttonConfig: readOnlyClick,
state: _context?.state,
urlParamsDataSource: urlParams,
_context,
position: ButtonPosition.arrayTableCell,
});
}
}
}
}
if (hasClear !== undefined) {
componentProps.hasClear = hasClear;
}
if (size) {
componentProps.size = size;
}
if (placeholder) {
componentProps.placeholder = placeholder;
}
const componentDefine = getRunTimeItem(filterItemComponentMap, componentName);
if (componentDefine) {
const { isBizComponent } = componentDefine;
if (isBizComponent === true) {
componentProps[_getContext] = () => {
return _context;
};
}
let component = componentDefine?.component;
component = getRealizeValue(component);
const formBeforeHandler = component?.formBeforeHandler;
if (formBeforeHandler) {
componentProps = formBeforeHandler(componentProps, {
isDesign,
urlParamsDataSource: urlParams,
recordDataSource: formValue,
state,
isInForm: true,
formInstance,
_context,
getFormInstance,
});
}
}
const formItemProps = {};
if (typeof colSpan === 'number') {
formItemProps.colSpan = colSpan;
}
if (name && componentName && componentName !== 'CnAgreement') {
let realComponentProps;
if (typeof handleProps === 'function') {
const extraProps = executeFunction(
handleProps,
{ ...componentProps },
_context?.state,
);
if (isPlainObject(extraProps)) {
realComponentProps = merge(extraProps, { ...componentProps });
}
}
if (!realComponentProps) {
realComponentProps = { ...componentProps };
}
const formItem: any = {
title,
'x-component': componentName,
'x-component-props': realComponentProps,
'x-decorator': 'CnFormItem',
...formItemProps,
};
formItem['x-data'] = {
disabled,
hidden,
readOnly,
};
formItem['x-decorator-props'] = {};
if (tip) {
formItem['x-decorator-props'].tip = tip;
}
if (labelAlign) {
formItem['x-decorator-props'].labelAlign = labelAlign;
}
if (extra) {
if (typeof extra === 'string') {
formItem['x-decorator-props'].extra = extra;
} else if (isPlainObject(extra)) {
const { redirectType, text } = extra;
const url = calculateUrl(extra, {
urlParamsDataSource: urlParams,
recordDataSource: formValue,
state,
});
const extraProps = {
style: { color: '#005be5' },
};
if (redirectType === 'open') {
extraProps.target = '_blank';
}
if (url) {
extraProps.href = url;
}
formItem['x-decorator-props'].extra = {text};
} else if (typeof extra === 'function') {
formItem['x-decorator-props'].extra = executeFunction(
extra,
formValue,
state,
);
}
}
// if (typeof isReadOnly === 'boolean') {
// formItem.readOnly = isReadOnly;
// }
// if (typeof isHidden === 'boolean') {
// formItem['x-hidden'] = isHidden;
// // formItem['x-display'] = isHidden ? 'none' : 'visible'
// }
// if (typeof isDisabled === 'boolean') {
// formItem['x-disabled'] = isDisabled;
// }
usedComponentList.push(componentName);
if (rules.length > 0) {
formItem['x-validator'] = transRulesToValidator(rules, {
formValue,
state,
position: ValidatorPosition.form,
});
}
if (componentDefine) {
const formItemBeforeHandler = componentDefine?.formItemBeforeHandler;
if (formItemBeforeHandler) {
formItemBeforeHandler(formItem, {
formItemConfig,
formProps,
isDesign,
usedComponentList,
urlParams,
formValue,
state,
_context,
formInstance,
});
}
}
const ds = formItem['x-component-props']?.dataSource;
if (dataOrigin === 'static') {
if (Array.isArray(ds) && ds.length > 0) {
formItem.enum = ds;
}
if (formItem?.['x-component-props']?.dataSource) {
if (componentName === 'CnAsyncSelect' || isInCnFilterPro) {
} else {
delete formItem['x-component-props'].dataSource;
}
}
}
return formItem;
}
}
function compileLeft(str) {
let left = trim(str);
let attr;
let urlParamsKey;
let dataSourceName;
if (left) {
left = left.replaceAll('"', '');
left = left.replaceAll("'", '');
if (left) {
if (left.startsWith(`${__urlParams__}.`)) {
attr = __urlParams__;
urlParamsKey = left.replace(`${__urlParams__}.`, '');
} else if (left.startsWith(`${__ds__}`)) {
const index = left.lastIndexOf(`${__ds__}`);
if (index > 0) {
attr = str.slice(0, index + 6);
urlParamsKey = str.slice(index + 7);
dataSourceName = str.slice(6, index);
}
} else {
attr = left;
}
}
}
return {
attr,
urlParamsKey,
dataSourceName,
};
}
const symbolList = ['>=', '<=', '>', '<', '!==', '!=', '===', '==', '='];
export function compileTextExpr2(str, type = null) {
if (!str) {
str = '';
}
let attr;
let value;
let symbol;
let realType;
let urlParamsKey;
let dataSourceName;
try {
if (typeof str === 'string' && str.length > 0) {
symbol = symbolList.find((item) => str.includes(item));
try {
let left;
let right;
if (symbol) {
const list = str.split(symbol);
left = trim(list[0]);
left = left.replaceAll('"', '');
left = left.replaceAll("'", '');
right = trim(list[1]);
} else {
left = str;
}
if (left) {
const leftResult = compileLeft(left);
if (leftResult.attr) {
attr = leftResult.attr;
}
if (leftResult.urlParamsKey) {
urlParamsKey = leftResult.urlParamsKey;
}
if (leftResult.dataSourceName) {
dataSourceName = leftResult.dataSourceName;
}
}
if (right) {
const tempSymbol = ['"', '"', "'"];
const tempSymbolFirst = tempSymbol.find((item) =>
right.includes(item),
);
if (tempSymbolFirst) {
right = right.slice(
right.indexOf(tempSymbolFirst) + 1,
right.lastIndexOf(tempSymbolFirst),
);
realType = 'string';
} else if (right === 'true' || right === 'false') {
realType = 'boolean';
} else {
const temp = Number(right);
if (isNumber(temp) && !isNaN(temp)) {
realType = 'number';
}
}
if (right) {
if (!type) {
type = realType;
}
if (type === 'boolean') {
value = right === 'true';
} else if (type === 'number') {
const temp = Number(right);
if (isNumber(temp) && !isNaN(temp)) {
value = temp;
} else {
value = undefined;
}
} else if (type === 'string') {
value = right;
} else {
value = right;
}
}
}
} catch (e) {}
}
} catch (e) {}
return {
attr,
value,
symbol,
type: realType,
urlParamsKey,
dataSourceName,
};
}
function transTextExprToFunction(str) {
const expr = compileTextExpr2(str);
if (expr) {
const { attr, value, symbol, urlParamsKey, dataSourceName } = expr;
try {
if (attr && symbol) {
if (attr.startsWith(__ds__)) {
if (urlParamsKey && dataSourceName) {
switch (symbol) {
case '>':
return (record, params, state) => {
return get(state?.[dataSourceName], urlParamsKey) > value;
};
case '<':
return (record, params, state) => {
return get(state?.[dataSourceName], urlParamsKey) < value;
};
case '>=':
return (record, params, state) => {
return get(state?.[dataSourceName], urlParamsKey) >= value;
};
case '<=':
return (record, params, state) => {
return get(state?.[dataSourceName], urlParamsKey) <= value;
};
case '===':
case '==':
case '=':
if (value === undefined || value === null || value === '') {
return (record, params, state) => {
return !get(state?.[dataSourceName], urlParamsKey);
};
} else {
return (record, params, state) => {
return get(state?.[dataSourceName], urlParamsKey) === value;
};
}
case '!==':
case '!=':
if (value === undefined || value === null || value === '') {
return (record, params, state) => {
return !!get(state?.[dataSourceName], urlParamsKey);
};
} else {
return (record, params, state) => {
return get(state?.[dataSourceName], urlParamsKey) !== value;
};
}
}
}
} else if (attr === __urlParams__) {
if (urlParamsKey) {
switch (symbol) {
case '>':
return (record, params) => {
return params?.[urlParamsKey] > value;
};
case '<':
return (record, params) => {
return params?.[urlParamsKey] < value;
};
case '>=':
return (record, params) => {
return params?.[urlParamsKey] >= value;
};
case '<=':
return (record, params) => {
return params?.[urlParamsKey] <= value;
};
case '===':
case '==':
case '=':
if (value === undefined || value === null || value === '') {
return (record, params) => {
return !params?.[urlParamsKey];
};
} else {
return (record, params) => {
return params?.[urlParamsKey] === value;
};
}
case '!==':
case '!=':
if (value === undefined || value === null || value === '') {
return (record, params) => {
return !!params?.[urlParamsKey];
};
} else {
return (record, params) => {
return params?.[urlParamsKey] !== value;
};
}
}
}
} else if (attr.startsWith(`${__record__}.`)) {
const realAttr = attr.slice(`${__record__}.`.length);
if (realAttr) {
switch (symbol) {
case '>':
return (record) => {
return record?.[realAttr] > value;
};
case '<':
return (record) => {
return record?.[realAttr] < value;
};
case '>=':
return (record) => {
return record?.[realAttr] >= value;
};
case '<=':
return (record) => {
return record?.[realAttr] <= value;
};
case '===':
case '==':
case '=':
if (value === undefined || value === null || value === '') {
return (record) => {
return !record?.[realAttr];
};
} else {
return (record) => {
return record?.[realAttr] === value;
};
}
case '!==':
case '!=':
if (value === undefined || value === null || value === '') {
return (record) => {
return !!record?.[realAttr];
};
} else {
return (record) => {
return record?.[realAttr] !== value;
};
}
}
}
}
}
} catch (e) {}
}
}
// 执行对象表达式
export function executeObjectExpr(str, objExprArgMap, ...args) {
if (typeof str === 'boolean') {
return str;
} else if (typeof str === 'function') {
let result;
try {
const params = args.map((item) => {
if (item === null || item === undefined) {
return {};
}
return item;
});
result = str(...params);
} catch (e) {
console.error(e);
}
if (typeof result === 'boolean') {
return result;
}
} else if (typeof str === 'string' && str.length > 0) {
const func = transTextExprToFunction(str);
const params = [...args];
let first = {};
let last = {};
let state = {};
if (params.length > 0) {
first = args[0] || {};
state = args[args.length - 1];
if (state && state.urlParams) {
last = state.urlParams;
}
}
const result = executeFunction(func, first, last, state || {});
if (typeof result === 'boolean') {
return result;
}
} else if (isPlainObject(str)) {
const { group, param, secondParam, symbol, type, value, thirdParam } = str;
if (group && param && symbol) {
let leftValue;
if (group === __dataSource__) {
if (secondParam) {
leftValue = get(
objExprArgMap,
`${group}.${param}.${secondParam}${
thirdParam ? `.${thirdParam}` : ''
}`,
);
}
} else {
leftValue = get(objExprArgMap, `${group}.${param}`);
}
const func = symbolMap[symbol];
if (typeof func === 'function') {
const result = func(leftValue, value, str);
if (typeof result === 'boolean') {
return result;
}
}
}
}
}
export function isDesignMode(props) {
let mode;
if (isPlainObject(props)) {
mode = props?.__designMode;
} else if (typeof props === 'string') {
mode = props;
}
return mode === 'design';
}
export function getItem(
componentMap,
position,
componentName,
propKey,
extraQueryParams,
) {
let result;
if (componentName) {
let item = componentMap[componentName];
if (!item) {
item = getBizComponent(componentName, position);
}
if (typeof item === 'function') {
item = executeFunction(item, { position });
}
let flag = true;
if (item && item.position && item.position.includes(position)) {
} else {
flag = false;
}
if (isPlainObject(extraQueryParams)) {
for (const key in extraQueryParams) {
if (key && Array.isArray(item?.[key])) {
if (item[key].includes(extraQueryParams[key])) {
} else {
flag = false;
}
}
}
}
if (flag) {
if (!item.label) {
item.label = item.title;
}
if (!item.value) {
item.value = item.componentName;
}
if (propKey) {
result = item[propKey];
} else {
result = item;
}
}
}
return result;
}
export function getItemPrototypeListByPosition(config) {
const { position, primaryKey, componentMap } = config;
const defaultList = Object.keys(componentMap);
const bizComponentNameList = getBizComponentNameList();
let prototypeList: any = [];
const allComponentList = uniq([...defaultList, ...bizComponentNameList]);
allComponentList.forEach((name) => {
const item = getItem(componentMap, position, name) || {};
const { getPrototypeList, configure = [] } = item;
if (typeof getPrototypeList === 'function') {
const temp = getPrototypeList(position);
if (temp && temp.length > 0) {
prototypeList = [
...prototypeList,
...handlePrototypeCondition(temp, name, primaryKey),
];
}
} else if (configure?.length > 0) {
prototypeList = [
...prototypeList,
...handlePrototypeCondition(configure, name, primaryKey),
];
}
});
return prototypeList;
}
export function getItemDefaultProps(componentMap, position, componentName) {
const func = getItem(
componentMap,
position,
componentName,
'getDefaultProps',
);
if (typeof func === 'function') {
return func();
}
}
export function getItemListByPosition(config) {
const { position, componentMap, extraQueryParams } = config;
const result = [];
const defaultList = Object.keys(componentMap);
const bizComponentNameList = getBizComponentNameList();
const allComponentList = uniq([...defaultList, ...bizComponentNameList]);
allComponentList.forEach((name) => {
const component = getItem(
componentMap,
position,
name,
null,
extraQueryParams,
);
if (component) {
const { bizInfo = [] } = component;
if (bizInfo.length > 0) {
bizInfo.forEach((item) => {
const { label, value } = item;
const existGroup = result.find((item2) => item2.value === value);
if (existGroup) {
existGroup?.children.push(component);
} else {
result.push({
title: label,
value,
children: [component],
});
}
});
return;
}
result.push(component);
}
});
return result;
}
export function isArrayNotEmpty(list) {
return Array.isArray(list) && list.length > 0;
}
function uuid(len = 4) {
return customAlphabet('abcdefghijklmnopqrstuvwxyz', len)();
}
export function getDsNameFromVariable(dsExpr) {
let result = '';
if (dsExpr && dsExpr.variable) {
result = dsExpr.variable.slice(dsExpr.variable.lastIndexOf('.') + 1);
}
return result;
}
export function generateDataSource(config) {
const { componentName } = config || {};
if (componentName) {
}
let dataSourceList = [];
dataSourceList = getDataSourceList();
let index = '';
const first = dataSourceList?.find(
(item) => item.value === `${componentName}`,
);
if (first) {
index = generateIndex(dataSourceList, componentName);
}
if (Engine) {
const componentPrototype =
Engine?.designer?.getComponentMeta?.(componentName)?.prototype;
const dataSource = Engine?.context?.getManager('dataPool');
const ds = dataSource?.addItem({
description: `${
componentPrototype?.options?.title || componentName
}${index}的数据源`,
dpType: 'VALUE',
id: '',
initialData: '',
isGlobal: false,
name: `${componentName}${index}`,
protocal: 'VALUE',
});
if (ds?.name) {
return ds;
}
}
}
export function handleSuccessMessage(res) {
const { msg, extra } = res || {};
const { type } = extra || {};
let resultType = 'success';
if (messageTypeMap[type]) {
resultType = type;
}
CnMessage[resultType](msg || '请求成功');
}
// 处理设计态时的表单项缩进
export function handleDesignFormConfig(tconfig) {
const { nodeId, newFormConfig } = tconfig || {};
const oldNodeConfig = cacheFormConfig[nodeId];
if (oldNodeConfig) {
const { formConfigLength, formConfig } = oldNodeConfig;
if (formConfigLength === newFormConfig?.length) {
let isSame = true;
for (const index in formConfig) {
const newItem = newFormConfig?.[index];
const oldItem = formConfig[index];
if (newItem?.componentName !== oldItem?.componentName) {
isSame = false;
break;
}
}
if (isSame === true) {
const first = document.querySelector('.lc-sortable')?.children?.[0];
const handled = first?.getAttribute?.('handled');
if (handled === 'handled') {
return;
}
}
}
}
console.info('design: form handle indent');
handleFormConfigIndent({
config: newFormConfig,
formInfo: getFormInfo(newFormConfig) || {},
children: document.querySelector('.lc-sortable')?.children,
});
cacheFormConfig[nodeId] = {
formConfigLength: newFormConfig?.length,
formConfig: newFormConfig?.map((item) => {
return {
componentName: item.componentName,
name: item.name,
};
}),
};
}
// 计算表单字段的缩进
function handleFormConfigIndent(config) {
const { config: fieldConfig, formInfo, children } = config || {};
const { isFormStep, isFormTab, hasCard } = formInfo || {};
if (isArrayNotEmpty(fieldConfig)) {
fieldConfig.forEach((item, index) => {
const { componentName, name } = item || {};
if (name && componentName) {
let backgroundColor;
let borderTopLeftRadius;
let padding;
let marginLeft;
const currentDom = children?.[index];
if (isFormStep || isFormTab) {
if (
componentName === 'CnFormStepItem' ||
componentName === 'CnFormTabItem'
) {
backgroundColor = '#cbd9ff';
borderTopLeftRadius = '5px';
padding = '3px';
marginLeft = '0px';
} else {
borderTopLeftRadius = '0px';
padding = '0px';
marginLeft = '12px';
backgroundColor = '#f0f2ff';
}
} else if (hasCard) {
if (componentName === 'CnCard') {
backgroundColor = '#cbd9ff';
borderTopLeftRadius = '5px';
padding = '3px';
marginLeft = '0px';
} else {
borderTopLeftRadius = '0px';
padding = '0px';
marginLeft = '12px';
backgroundColor = '#f0f2ff';
}
}
if (currentDom?.style) {
if (index === 0) {
currentDom.setAttribute('handled', 'handled');
}
currentDom.style.borderTopLeftRadius = borderTopLeftRadius;
currentDom.style.padding = padding;
currentDom.style.marginLeft = marginLeft;
currentDom.style.backgroundColor = backgroundColor;
}
}
});
}
}
function getFormInfo(originalConfig) {
let firstFormStep;
let isFormStep = false;
let isFormTab = false;
let hasCard = false;
let firstFormTabIndex = 0;
if (isArrayNotEmpty(originalConfig)) {
for (const index in originalConfig) {
const item = originalConfig[index];
if (item?.componentName === 'CnFormStepItem') {
firstFormStep = item;
isFormStep = true;
break;
} else if (item?.componentName === 'CnFormTabItem') {
isFormTab = true;
firstFormTabIndex = +index;
break;
} else if (item?.componentName === 'CnCard') {
hasCard = true;
}
}
}
return {
firstFormStep,
isFormStep,
isFormTab,
firstFormTabIndex,
hasCard,
};
}
function visibleRun(extraProps, visible, type, run) {
// const { requestConfig, state, recordDataSource } = extraProps || {}
// const execute = calculateRequestExecute(requestConfig, {
// [__formValue__]: recordDataSource,
// [__filterValue__]: recordDataSource,
// [__dataSource__]: state,
// }, recordDataSource || {}, state)
if (visible) {
run?.();
}
}
function handleFormUrlencodedContentType(requestConfig) {
if (
requestConfig?.serviceType === 'http' &&
requestConfig?.contentType === formUrlencoded
) {
requestConfig.headers = {
'content-type': formUrlencoded,
};
}
}
// 处理设计态的mokelay请求url
const handleDesignMokelayUrl = (url) => {
const domain = window.getCnLowcodeStoreItem?.('__next_cone_domain__');
if (domain && domain?.value) {
return `${location.protocol}//${domain.value}${url}`;
}
return preMokelayDomain + url;
};
function handleSelectRequestConfig(config) {
const {
componentProps,
isDesign,
urlParamsDataSource,
recordDataSource,
state,
ignoreHandleParam,
} = config || {};
if (isPlainObject(componentProps)) {
const { dataOrigin, extraProps } = componentProps;
if (dataOrigin === 'request') {
// if (componentProps?.requestConfig?.url) {
delete componentProps.dataSource;
// }
if (componentProps?.requestConfig?.serviceType === 'mokelay') {
componentProps.requestConfig.method = 'post';
if (isDesign && componentProps?.requestConfig?.url) {
componentProps.requestConfig.url = handleDesignMokelayUrl(
componentProps.requestConfig?.url,
);
}
} else if (componentProps?.requestConfig) {
componentProps.requestConfig.withCredentials = true;
}
if (
ignoreHandleParam !== true &&
Array.isArray(componentProps?.requestConfig?.params) &&
componentProps?.requestConfig?.params.length > 0
) {
const realParams = handleRequestParams(
componentProps?.requestConfig?.params,
{
urlParamsDataSource,
recordDataSource,
state,
},
);
if (realParams) {
if (componentProps?.requestConfig?.method === 'post') {
componentProps.requestConfig.data = realParams;
delete componentProps.requestConfig.params;
} else {
componentProps.requestConfig.params = realParams;
}
}
}
if (
componentProps?.requestConfig?.serviceType !== 'mock' &&
typeof componentProps?.requestConfig?.resultProcessFunc === 'function'
) {
componentProps.requestConfig.formatResult = (res) => {
let newRes = getRealResponse(res);
try {
newRes = componentProps?.requestConfig?.resultProcessFunc(newRes);
} catch (e) {
console.error('请求结果回调执行失败', e);
}
if (Array.isArray(newRes?.data)) {
newRes = newRes.data;
} else if (Array.isArray(newRes?.data?.dataSource)) {
newRes = newRes?.data?.dataSource;
}
return newRes;
};
} else if (
componentProps?.requestConfig?.serviceType === 'mock' &&
isPlainObject(componentProps?.requestConfig?.mockData)
) {
componentProps.requestConfig.formatResult = () => {
return cloneDeep(componentProps?.requestConfig?.mockData?.data);
};
}
if (componentProps?.searchRemote) {
componentProps.filterLocal = false;
if (componentProps?.searchKey && componentProps?.requestConfig) {
componentProps.requestConfig.searchKey = componentProps.searchKey;
}
}
if (componentProps?.requestConfig) {
componentProps.requestConfig.throttleWait = 800;
if (extraProps?.enableRemoteLazyLoad === true) {
componentProps.enableRemoteLazyLoad = true;
if (extraProps?.remoteLazyLoadKey) {
componentProps.requestConfig.remoteLazyLoadKey =
extraProps.remoteLazyLoadKey;
}
}
// const execute = calculateRequestExecute(componentProps?.requestConfig, {
// [__formValue__]: recordDataSource,
// [__filterValue__]: recordDataSource,
// [__dataSource__]: state,
// }, recordDataSource || {}, state)
// if(execute === false) {
// componentProps.requestConfig.manual = true;
// }
handleFormUrlencodedContentType(componentProps.requestConfig);
}
if (componentProps?.requestWhenFocus === false) {
} else {
componentProps.onVisibleChange = visibleRun.bind(null, {
requestConfig: componentProps?.requestConfig,
state,
recordDataSource,
});
}
delete componentProps.searchRemote;
delete componentProps.searchKey;
delete componentProps.extraProps;
delete componentProps.requestWhenFocus;
componentProps.showSearch = true;
} else {
delete componentProps.requestConfig;
}
}
}
function handleSelectDataSource(config) {
const { componentProps, state } = config || {};
if (isPlainObject(componentProps)) {
const { dataOrigin, dataSource } = componentProps;
if (dataOrigin === 'static') {
if (typeof dataSource === 'function') {
try {
const temp = dataSource(state);
if (Array.isArray(temp)) {
componentProps.dataSource = temp;
}
} catch (e) {}
} else if (isValueObjectExpr(dataSource)) {
const tempDs = calculateTextExprValue(dataSource, { state });
if (Array.isArray(tempDs)) {
componentProps.dataSource = tempDs;
}
}
if (!Array.isArray(componentProps.dataSource)) {
componentProps.dataSource = [];
}
}
}
}
function calculateDataSource(config) {
const { dataFrom, state, _context, _bindFilter } = config || {};
let result;
if (isPlainObject(dataFrom)) {
const { dataOrigin, dataSource } = dataFrom;
if (dataOrigin === dataOriginStatic) {
if (Array.isArray(dataSource)) {
result = dataSource;
} else if (typeof dataSource === 'function') {
try {
const temp = dataSource(state);
if (Array.isArray(temp)) {
result = temp;
}
} catch (e) {}
} else if (isValueObjectExpr(dataSource)) {
const tempDs = calculateTextExprValue(dataSource, { state });
if (Array.isArray(tempDs)) {
result = tempDs;
}
}
} else if (
dataOrigin === dataOriginRequest &&
isPlainObject(dataFrom?.requestConfig)
) {
return makeRequest({
buttonConfig: {
options: {
requestConfig: dataFrom?.requestConfig,
},
},
recordDataSource: {},
state,
needSuccessToast: false,
handleParams: () => {
return {
...getFilterValue({
filterConfig: {
_bindFilter,
},
_context,
}),
};
},
extraParamList: [],
});
}
}
return result;
}
function isRecursionComponent(componentName) {
return recursionComponentList.includes(componentName);
}
function handleOriginList(
originList,
labelKey,
valueKey,
groupExprName,
extraConfig,
) {
const result = [];
const { dsName } = extraConfig || {};
if (isArrayNotEmpty(originList)) {
originList.forEach((item2) => {
const { componentName } = item2;
const label = handleI18nLabel(item2[labelKey]);
const value = item2[valueKey];
if (value) {
const newLabel = label ? `${label}(${value})` : value;
const temp = {
label: newLabel,
text: newLabel,
value: `${groupExprName}.${value}`,
};
if (
componentName === 'RangePicker' ||
componentName === 'RangeTimePicker'
) {
temp.children = [
{
label: '开始时间',
value: `${temp.value}[0]`,
},
{
label: '结束时间',
value: `${temp.value}[0]`,
},
];
}
if (componentName === 'CnFormArrayCard' && item2?.name && dsName) {
result.push({ ...temp });
temp.label = `${temp.label} 的额外数据`;
temp.children = [
{
label: tableCurrentRowLabel,
value: `state.valueOf.${dsName}.${item2.name}.${__arrayTableCurrentRow__}`,
},
];
}
result.push(temp);
// if(handleComposeComponent && componentName === 'Compose') {
// const tempChildren = handleOriginList(item2?.options?.config, 'label','name',`${groupExprName}.${value}` )
// if(isArrayNotEmpty(tempChildren)) {
// result = [...result, ...tempChildren]
// }
// }
}
});
}
return result;
}
function getNodeById(config) {
const { field, id } = config;
let result;
if (id) {
const nodesMap = field?.getNode?.()?.document?.nodesMap;
if (nodesMap?.values()) {
for (const item of nodesMap.values()) {
if (item?.id === id) {
result = item;
break;
}
}
}
}
return result;
}
function getArrayTableFieldList(param) {
const { config, arrayTableName } = param || {};
if (arrayTableName && isArrayNotEmpty(config)) {
const result = [];
config.forEach((item) => {
const { label, name } = item || {};
if (name) {
const realLabel = handleI18nLabel(label) || name;
result.push({
label: realLabel,
value: `${arrayTableName}.${__arrayTableCurrentRow__}.${name}`,
});
}
});
return result;
}
}
function getDataSourceByName(name) {
return VisualEngine?.context?.getManager?.('dataPool')?.getItemByName?.(name);
}
function removeDataSourceByNode(current) {
if (current?.id) {
const dataSourceName = current.getPropValue(_dataSourceName);
if (dataSourceName) {
const node = VisualEngine?.designer?.currentDocument?.nodesMap?.get?.(
current.id,
);
if (!node) {
const ds = getDataSourceByName(dataSourceName);
if (ds && ds.id) {
VisualEngine?.context?.getManager?.('dataPool')?.removeItem?.(ds.id);
}
}
}
}
}
function getFormDefaultValue(defaultParams, config) {
const {
urlParamsDataSource,
state,
position,
isDesign,
formConfig,
getExtraParam,
ignoreDefaultSelectFormRequest,
} = config || {};
const {
dataOrigin,
defaultValue = {},
requestConfig = {},
afterRequest = {},
} = defaultParams || {};
if (dataOrigin === 'static') {
const result = calculateTextExprValue(defaultValue, {
urlParamsDataSource,
state,
});
if (result) {
if (isPlainObject(result) && Object.keys(result).length > 0) {
return result;
} else if (
isArrayNotEmpty(result) &&
typeof defaultValue !== 'function'
) {
const temp = {};
const formItemFormatMap = {};
const formItemComponentNameMap = {};
const formItemMap = {};
if (Array.isArray(formConfig)) {
formConfig.forEach((item) => {
const { name, componentName, options } = item;
if (name && options?.outputFormat) {
formItemFormatMap[name] = options.outputFormat;
}
formItemComponentNameMap[name] = componentName;
formItemMap[name] = item;
});
}
result.forEach((item) => {
const { name, valueType, value } = item;
if (name && valueType && value !== undefined) {
if (valueType === 'buildIn') {
if (isPlainObject(value)) {
const time = calculateTime(value, formItemFormatMap[name], {
range: formItemComponentNameMap?.[name] === 'RangePicker',
});
if (time) {
temp[name] = time;
}
}
} else if (valueType === 'DefaultSelect') {
const current = formItemMap[name];
if (
allowSelectFirstComponentList.includes(current?.componentName)
) {
const { options } = current || {};
if (options?.dataOrigin === dataOriginStatic) {
const { dataSource } = options;
if (isArrayNotEmpty(dataSource)) {
if (typeof value === 'number') {
const tempDs = dataSource[value];
if (tempDs?.value !== undefined) {
temp[name] = tempDs.value;
}
}
}
} else if (options?.dataOrigin === dataOriginRequest) {
if (
isEmptyButNotZero(temp[name]) &&
ignoreDefaultSelectFormRequest !== true
) {
temp[name] = item;
}
}
}
} else if (valueType === 'SelectFromDataSource') {
temp[name] = calculateTextExprValue(value, {
state,
});
} else {
temp[name] = value;
}
}
});
if (Object.keys(temp).length > 0) {
return temp;
}
}
}
} else if (dataOrigin === 'request') {
const execute = calculateRequestExecute(
requestConfig,
{
[__dataSource__]: state,
},
{},
state,
);
if (execute === false) {
return;
}
const realUrl = getRealRequestUrl({
requestConfig,
state,
extraParam: getExtraParam?.(),
});
if (realUrl) {
return makeRequest({
buttonConfig: {
options: {
requestConfig: {
...requestConfig,
url: realUrl,
dynamicUrl: undefined,
},
},
},
urlParamsDataSource,
recordDataSource: {},
state,
needSuccessToast: false,
isDesign,
getExtraParam,
}).then((res) => {
const res2 = getRealResponse(res);
const { success, data } = res2;
if (success) {
if (isPlainObject(data) && Object.keys(data).length > 0) {
return data;
}
}
});
}
}
}
function getRealRequestUrl(config) {
const { requestConfig, state, extraParam } = config || {};
let result;
if (requestConfig) {
const { dynamicUrl, useDynamicUrl, url } = requestConfig;
result = url;
if (useDynamicUrl === true && typeof dynamicUrl === 'function') {
const temp = executeFunction(dynamicUrl, state, extraParam || {});
if (typeof temp === 'string') {
result = temp;
} else {
result = '';
}
}
}
return result;
}
function isEmptyButNotZero(value) {
return value === undefined || value === null || value === '';
}
function handleFormat(time, format) {
if (time) {
if (format) {
return time.format(format);
} else {
return time?.valueOf();
}
}
return time;
}
const transProxyToObject = (origin) => {
const result = {};
if (typeof origin === 'object') {
const keys = Object.keys(origin);
if (keys && keys.length > 0) {
keys.forEach((key) => {
result[key] = origin[key];
});
}
}
return result;
};
function calculateTime(value, format, config) {
const { range } = config;
if (isPlainObject(value)) {
try {
const { num, rela, time, unit } = value;
if (rela && num !== undefined && unit) {
let temp = dayjs()[rela](num, unit);
if (temp) {
if (range) {
let start;
let end;
if (rela === 'subtract') {
start = handleFormat(temp, format);
end = handleFormat(dayjs(), format);
} else if (rela === 'add') {
start = handleFormat(dayjs(), format);
end = handleFormat(temp, format);
}
return [start, end];
} else if (time) {
if (time !== 'now') {
temp = temp[time]('d');
}
return handleFormat(temp, format);
}
}
}
} catch (e) {}
}
}
function calculateWaitComponentList(config, defaultParams) {
const result = {
waitComponentList: [],
waitComponentMap: {},
configMap: {},
};
if (isArrayNotEmpty(config)) {
config.forEach((item, index) => {
const { name } = item || {};
result.configMap[name] = item;
const need = needRequestRemote(item, defaultParams);
if (need) {
result.waitComponentList.push(name);
result.waitComponentMap[name] = need;
}
});
}
return result;
}
function needRequestRemote(config, defaultParams) {
const { dataOrigin, defaultValue } = defaultParams || {};
if (dataOrigin === dataOriginStatic && isArray(defaultValue)) {
const { name, componentName, options } = config || {};
if (name && allowSelectFirstComponentList.includes(componentName)) {
const { dataOrigin, requestConfig } = options || {};
if (dataOrigin === dataOriginRequest && requestConfig?.url) {
const current = defaultValue.find(
(item) => item?.name === name && item?.valueType === 'DefaultSelect',
);
if (current?.name) {
return current;
}
}
}
}
return false;
}
function executeEventWithoutJS(config) {
const {
eventType,
events,
_context,
position,
urlParamsDataSource,
recordDataSource,
jsParamList,
} = config || {};
if (eventType && Array.isArray(events) && events.length > 0) {
for (const item of events) {
const { name: eventName } = item;
if (eventName === eventType) {
const action = getButtonAction({ ...item, position });
if (typeof action === 'function') {
action({
buttonConfig: {
...item,
position,
options: {
...item,
},
},
position,
state: _context?.state,
urlParamsDataSource,
recordDataSource,
_context,
jsParamList,
});
}
}
}
}
}
function transDataSourceToMap(list) {
const result = {};
if (Array.isArray(list) && list.length > 0) {
list.forEach((item) => {
if (
item.value !== undefined &&
item.value !== null &&
item.label !== undefined
) {
result[item.value] = item.label;
}
});
}
return result;
}
function handleListI18nLabel(list, key) {
if (isArrayNotEmpty(list)) {
list?.forEach((item) => {
if (item?.[key]) {
item[key] = handleI18nLabel(item[key]);
}
});
}
}
function isRequestConfig(requestConfig) {
if (requestConfig) {
const { url, serviceType } = requestConfig;
if (url && serviceType) {
return true;
}
}
return false;
}
function renderIcon(type) {
if (typeof type === 'string' && type.length > 0) {
return ;
}
return undefined;
}
function setDataToDs(config) {
const { data, _dataSourceName, _context, _dataSource } = config || {};
if (isPlainObject(data) && _dataSourceName && _context) {
_context?.setState({
[_dataSourceName]: {
..._dataSource,
...data,
},
});
}
}
function getArrayTableCurrentRowByField2(field) {
if (field) {
const segments = field?.path?.segments;
const realSegments = segments.slice(0, -1);
const currentRow = field?.form?.getValuesIn?.(realSegments);
if (isPlainObject(currentRow)) {
return currentRow;
}
}
}
function getDataSourceById(id) {
return VisualEngine?.context?.getManager?.('dataPool')?.getItemById?.(id);
}
function createDataSource(dsConfig) {
if (dsConfig) {
const { id, name, description } = dsConfig;
// const dataSourceList = getDataSourceList();
if (id && name && VisualEngine) {
const dataSource = VisualEngine?.context?.getManager('dataPool');
return dataSource?.addItem({
description,
dpType: 'VALUE',
id,
initialData: '',
isGlobal: false,
name,
protocal: 'VALUE',
});
}
}
}
async function executeFlowList(config) {
const result = [];
const { list, position, _context } = config || {};
if (isArrayNotEmpty(list) && _context) {
for (const index in list) {
const item = list[index];
const { active, optType } = item || {};
const isActive = executeObjectExpr(
active,
{
[__dataSource__]: _context?.state,
},
{},
_context?.state,
);
if (isActive === true) {
const action = getButtonAction({
...item,
position,
});
let flowResult;
if (typeof action === 'function') {
flowResult = await action({
position,
needSuccessToast: false,
buttonConfig: { ...item },
_context,
state: _context?.state,
urlParamsDataSource: _context?.state?.urlParams || {},
recordDataSource: {},
});
}
const handleFlowResult = getButtonItem(
position,
optType,
'handleFlowResult',
);
if (typeof handleFlowResult === 'function') {
flowResult = handleFlowResult(flowResult);
}
if (flowResult && _context) {
let realIndex = +index;
if (realIndex === 0) {
realIndex = '';
}
_context.state.valueOf[optType + realIndex] = flowResult;
}
result.push(flowResult);
}
}
}
return result;
}
function clearState(config) {
const { _context } = config || {};
if (_context?.state) {
const flowDataKeys = Object.keys(_context.state.valueOf);
if (Array.isArray(flowDataKeys) && flowDataKeys.length > 0) {
flowDataKeys.forEach((key) => {
if (key?.includes(__stateValueOfSplit__)) {
} else {
// FIXME 需要将动作编排的临时存储数据清掉
// _context.state.valueOf[key] = undefined;
}
});
}
}
}
function setAdvancedConfigToProps(props) {
if (isPlainObject(props?.__advancedConfig__)) {
Object.keys(props.__advancedConfig__).forEach((key) => {
const tempV = props.__advancedConfig__[key];
if (key && !isEmptyButNotZero(tempV)) {
props[key] = tempV;
}
});
delete props.__advancedConfig__;
}
}
function batchCalculateTextExprValue(obj, config) {
if (isPlainObject(obj)) {
const result = {};
for (const key in obj) {
if (key && key.indexOf('_unsafe_MixedSetter') === -1) {
const value = calculateTextExprValue(obj[key], config);
if (key && value !== undefined) {
result[key] = value;
}
}
}
return result;
}
}
function handlePageDataSource(config) {
const { componentProps, state } = config || {};
if (isPlainObject(componentProps)) {
const { dataOrigin, dataSource } = componentProps;
if (dataOrigin === 'static') {
if (typeof dataSource === 'function') {
try {
componentProps.dataSource = dataSource(state);
} catch (e) {}
} else if (isValueObjectExpr(dataSource)) {
componentProps.dataSource = calculateTextExprValue(dataSource, {
state,
});
}
}
}
}
// 计算请求是否执行
function calculateRequestExecute(requestConfig, ...arg) {
if (requestConfig) {
const originalExecute = requestConfig?.execute;
const tempExecute = requestConfig?.__extraConfig__?.execute;
if (
isObjectExpr(tempExecute) ||
typeof tempExecute === 'function' ||
typeof tempExecute === 'boolean'
) {
return executeObjectExpr(tempExecute, ...arg);
} else if (typeof originalExecute === 'function') {
return executeObjectExpr(originalExecute, ...arg);
}
}
}
function isObjectExpr(obj) {
if (isPlainObject(obj) && obj.group && obj.param && obj.symbol) {
return true;
}
return false;
}
function makeButtons(config) {
const {
buttons,
_context,
state,
urlParamsDataSource,
recordDataSource,
extraParamList = [],
formInstance,
handleBtnProps,
useProxyButton,
arrayTableCurrentRow,
arrayBaseField,
arrayBaseFieldIndex,
jsParamList,
} = config;
if (Array.isArray(buttons) && buttons.length > 0) {
const result = [];
for (const index in buttons) {
const item = buttons[index];
const {
iconType,
primaryKey,
optType,
options = {},
children,
position,
hidden,
disabled,
getExtraParam,
...rest
} = item;
const isHidden = executeObjectExpr(
hidden,
{
[__filterValue__]: recordDataSource || {},
[__formValue__]: recordDataSource || {},
[__dataSource__]: state,
[__arrayTableCurrentRow__]: arrayTableCurrentRow,
},
recordDataSource || {},
state,
arrayBaseFieldIndex,
formInstance?.values,
);
if (isHidden) {
continue;
}
const isDisabled = executeObjectExpr(
disabled,
{
[__filterValue__]: recordDataSource || {},
[__formValue__]: recordDataSource || {},
[__dataSource__]: state,
[__arrayTableCurrentRow__]: arrayTableCurrentRow,
},
recordDataSource || {},
state,
arrayBaseFieldIndex,
formInstance?.values,
);
const action = getButtonAction({ ...item, position });
const componentDefine = getRunTimeItem({}, optType);
const getRenderDom = getButtonItem(position, optType, 'getRenderDom');
const btnProps = {
...rest,
};
if (isDisabled === true) {
btnProps.disabled = isDisabled;
}
if (componentDefine?.component) {
const component = getRealizeValue(componentDefine.component);
if (component) {
result.push(
React.createElement(component, {
children,
...btnProps,
buttonConfig: item,
_context,
[_getFormValues]: () => {
return formInstance?.values;
},
formInstance: undefined,
arrayBaseField,
arrayBaseFieldIndex,
}),
);
continue;
}
} else if (typeof getRenderDom === 'function') {
const dom = executeFunction(getRenderDom, {
_context,
buttonConfig: item,
state,
urlParamsDataSource,
recordDataSource: {
realize: () => {
return formInstance?.values;
},
},
btnProps,
});
if (dom) {
result.push(dom);
continue;
}
}
if (action) {
btnProps.onClick = action.bind(null, {
buttonConfig: item,
position,
state,
urlParamsDataSource,
recordDataSource: {
realize: () => {
return formInstance?.values;
},
},
formInstance,
_context,
getExtraParam,
arrayTableCurrentRow,
arrayBaseField,
arrayBaseFieldIndex,
jsParamList,
...extraParamList,
});
}
if (typeof handleBtnProps === 'function') {
handleBtnProps(btnProps);
}
const ButtonCom = CnButton;
if (useProxyButton === true) {
}
result.push(
{renderIcon(iconType)}
{children}
,
);
}
return result;
}
return null;
}
function makeALink(config) {
const { linkExpr, _context, recordDataSource } = config || {};
const { redirectType, text } = linkExpr;
if (text) {
const url = calculateUrl(linkExpr, {
urlParamsDataSource: _context?.state?.urlParams || {},
recordDataSource: {},
state: _context?.state,
});
const extraProps = {};
if (redirectType === 'open') {
extraProps.target = '_blank';
}
if (url) {
extraProps.href = url;
}
return (
{calculateTextExprValue(text, {
recordDataSource: recordDataSource || {},
state: _context?.state,
})}
);
}
return null;
}
function getFilterValue(config) {
const { filterConfig, _context } = config || {};
const { _bindFilter } = filterConfig || {};
let result = {};
if (isArrayNotEmpty(_bindFilter)) {
for (const item of _bindFilter) {
if (item) {
const filterDom = _context?.$(item);
const { _dataSourceName } = filterDom?.props || {};
if (_dataSourceName) {
result = {
...result,
...transProxyToObject(_context?.state?.[_dataSourceName]),
};
}
}
}
}
return result;
}
function dialogOpen(config) {
const { dialogNodeId, data, _context } = config || {};
if (dialogNodeId && typeof _context?.$ === 'function') {
const dialogNode = _context.$(dialogNodeId);
if (dialogNode) {
return new Promise((resolve) => {
setTimeout(() => {
const p = dialogNode?.open?.(data);
if (typeof p?.then === 'function') {
p.then((res) => {
setTimeout(() => {
resolve(true);
});
});
} else {
setTimeout(() => {
resolve(true);
});
}
});
});
}
}
}
function dialogClose(config) {
const { dialogNodeId, data, _context } = config || {};
if (dialogNodeId && typeof _context?.$ === 'function') {
const dialogNode = _context.$(dialogNodeId);
if (dialogNode) {
return new Promise((resolve) => {
setTimeout(() => {
const p = dialogNode?.close?.(data);
if (typeof p?.then === 'function') {
p.then(() => {
setTimeout(() => {
resolve(true);
});
});
} else {
setTimeout(() => {
resolve(true);
});
}
});
});
}
}
}
function tableLoad(config) {
const { _bindTable, _context } = config || {};
function reloadOneTable(id) {
if (typeof id === 'string') {
const table = _context?.$(id);
table?.load?.();
}
}
if (_bindTable && _context) {
if (Array.isArray(_bindTable)) {
_bindTable.forEach((item) => {
reloadOneTable(item);
});
} else {
reloadOneTable(_bindTable);
}
}
}
export {
handleDesignMokelayUrl,
handleSelectRequestConfig,
handleSelectDataSource,
getRealResponse,
handleFormUrlencodedContentType,
isRecursionComponent,
getFlowListDataSource,
handleOriginList,
getNodeById,
getArrayTableFieldList,
removeDataSourceByNode,
getFormDefaultValue,
calculateTime,
isEmptyButNotZero,
getRealRequestUrl,
transProxyToObject,
calculateWaitComponentList,
needRequestRemote,
executeEventWithoutJS,
getRunTimeBizComponent,
transDataSourceToMap,
handleListI18nLabel,
isRequestConfig,
renderIcon,
setDataToDs,
getArrayTableCurrentRowByField2,
getDataSourceById,
createDataSource,
uuid,
executeFlowList,
clearState,
setAdvancedConfigToProps,
batchCalculateTextExprValue,
handlePageDataSource,
calculateRequestExecute,
isObjectExpr,
makeButtons,
calculateDataSource,
makeALink,
getFilterValue,
dialogOpen,
dialogClose,
tableLoad
};