import { ButtonPosition } from '@/type/button-position';
import uniq from 'lodash/uniq';
import qs from 'query-string';
import * as cnUniApi from '@alife/cn-uni-api';
import {
calculateTextExprValue,
executeFunction,
executeObjectExpr,
getArrayTableFieldList,
getBizComponent,
getBizComponentNameList,
getDataSourceList,
getDataSourceListWithAllPath,
getNodeById,
getRealizeValue,
getRealRequestUrl,
getRealResponse,
getRunTimeBizComponent,
handleI18nLabel,
handlePrototypeCondition,
isArrayNotEmpty,
isRecursionComponent,
uuid,
} from '../util/util';
import {
createServiceSelectPrototype,
handleRequestParams,
makeRequest,
} from './request';
import {
createTableSelectSetters,
getFormHandleTypeSetterSnippet,
getSelectDialogSnippet,
getSetterSnippet,
} from './setter-snippet';
import {
getJSExpressionPrototype,
getStyleListByPosition,
} from '@/common/manager/common-style';
import CheckboxSetter from '@/common/setter/checkbox-setter';
import ExprSetter from '@/common/setter/expr-setter';
import {
__arrayTableCurrentRow__,
__dataSource__,
__flowData__,
getCommonBoolDataSource,
} from '@/common/util/expr-const';
import isPlainObject from 'lodash/isPlainObject';
import { ActionRunEnv } from '@/type/action-run-env';
import { ParamSelectSetter } from '@/common/setter/param-select-setter';
import cloneDeep from 'lodash/cloneDeep';
import { pageDataSource } from '@/common/util/const';
import { CnDataSourceChange, emitEvent } from '@/common/util/event-name';
import { createMessageSetters } from '@/common/manager/message';
import isNumber from 'lodash/isNumber';
import { CnMessage } from '@cainiaofe/cn-ui-m';
import findLastIndex from 'lodash/findLastIndex';
const CnUniApi = window.cnUniApi || cnUniApi; // 兼容:优先用户script注入的cnUniApi
const { ActionSetter } = window.VisualEngineUtils || {};
const ALL_BUTTON_POSITION_LIST = Object.values(ButtonPosition);
const jsActionMap = {
[ButtonPosition.navBarEvent]: `/**
* onBack
*
*/
function onBack(state) {
}`,
[ButtonPosition.navBarRightButton]: `/**
* onClick
*
*/
function onClick(state) {
}`,
[ButtonPosition.form]: `/**
* onClick
*
*/
function onClick({ form, state}) {
}`,
[ButtonPosition.formDialog]: `/**
* onClick
*
*/
function onClick({ form, state}) {
}`,
};
const jsAction = {
title: 'js脚本',
value: 'jsAction',
position: ALL_BUTTON_POSITION_LIST,
getPrototypeList: (position, config) => {
const { __field } = config || {};
if (
[
ButtonPosition.navBarEvent,
ButtonPosition.navBarRightButton,
ButtonPosition.form,
ButtonPosition.formDialog,
].includes(position)
) {
let defaultActionName = 'onBack';
if (
[
ButtonPosition.form,
ButtonPosition.formDialog,
ButtonPosition.navBarRightButton,
].includes(position)
) {
defaultActionName = 'onClick';
}
return [
{
title: '自定义脚本',
name: 'jsFunction',
display: 'inline',
className: 'cn-action-setter',
setter: {
componentName: ,
props: () => {
const defaultCode = jsActionMap[position];
return {
supportTypes: ['page'],
defaultCode,
defaultActionName,
};
},
},
},
];
}else {
return [
{
title: '自定义脚本',
name: 'jsFunction',
// isRequired: true,
// editable:true,
display: 'inline',
// condition(){
// return true;
// },
className: 'cn-action-setter',
// setter: ,
setter: {
componentName: (
),
props: () => {
const defaultCode = jsActionMap[position];
const defaultActionName = 'jsAction';
return {
supportTypes: ['page'],
defaultCode,
defaultActionName,
};
},
},
},
];
}
},
action: (config) => {
const { buttonConfig, _context, position, jsParamList = [] } = config;
const { name, options } = buttonConfig;
const { jsFunction } = options || {};
if (typeof jsFunction === 'function') {
if (
[
ButtonPosition.navBarEvent,
ButtonPosition.filterItemEvent,
ButtonPosition.formItemEvent,
ButtonPosition.formDialogItemEvent,
].includes(position)
) {
if (name === 'onBack') {
return jsFunction(...jsParamList);
}
} else if (
[
ButtonPosition.navBarRightButton,
ButtonPosition.form,
ButtonPosition.formDialog,
].includes(position)
) {
return jsFunction(...jsParamList);
}else {
async function executeJsFunction() {
await jsFunction();
}
return executeJsFunction();
}
}
},
};
const link = {
title: '跳转链接',
value: 'link',
position: ALL_BUTTON_POSITION_LIST,
getDefaultProps: () => {
return {
redirectType: 'open',
routerType: 'location',
};
},
getPrototypeList: (position, config) => {
let paramSetter = 'StringSetter';
let urlSetter = 'StringSetter';
const setterSnippet = getSetterSnippet({
position,
optType: 'link',
...config,
});
const { urlSetter: newUrlSetter, requestParamSetter } = setterSnippet || {};
if (requestParamSetter) {
paramSetter = requestParamSetter;
}
if (newUrlSetter) {
urlSetter = newUrlSetter;
}
return [
{
title: '路由类型',
name: 'routerType',
condition() {
return false;
},
originalCondition() {
return false;
},
description: '路由类型',
setter: 'StringSetter',
},
{
title: '链接地址',
name: 'url',
// condition: {
// "type": "JSFunction",
// "value": "() => false"
// },
description: '链接地址',
className: 'cn-link-url-setter',
setter: urlSetter,
},
{
title: '打开方式',
name: 'redirectType',
description: '打开方式',
setter: {
componentName: 'RadioGroupSetter',
initialValue: 'current',
props: {
options: [
{
title: '当前页面',
value: 'current',
},
{
title: '新开页面',
value: 'open',
},
],
},
},
},
{
title: 'url参数',
name: 'urlParams',
description: 'url参数',
// extraProps: {
// },
className: 'cn-button-url-param-setter',
setter: {
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
// initialValue: {
// "type": "JSFunction",
// "value": "() => {return {primaryKey: String(Math.floor(Math.random() * 10000)),children: \"Title\",optType:\"link\" };}"
// },
initialValue: {
label: 'param',
},
props: {
config: {
items: [
{
title: '参数名',
name: 'label',
isRequired: true,
description: '参数名',
setter: 'StringSetter',
},
// {
// title: '参数值',
// name: 'value',
// isRequired: true,
// description: '参数值',
// supportVariable: true,
// setter: 'StringSetter',
// },
{
title: '参数值',
name: 'value',
isRequired: true,
description: '参数值',
// supportVariable: true,
className: 'cn-param-select-setter',
setter: paramSetter,
},
],
},
},
},
},
},
},
];
},
action: (config, extra) => {
const {
buttonConfig,
urlParamsDataSource,
recordDataSource: originalRecordDataSource,
state,
position,
arrayTableConfig,
selectedRowKeys = [],
selectedRowRecords = [],
} = config;
const needDelay =
position === ButtonPosition.formDialogSubmitAfterRequestSuccess ||
position === ButtonPosition.formSubmitAfterRequestSuccess;
const { options } = buttonConfig || {};
let extraParamList = [];
let recordDataSource = getRealizeValue(originalRecordDataSource);
if (position === ButtonPosition.arrayTableOperate) {
if (extra?.field) {
const { field } = extra;
const { formItemConfig } = arrayTableConfig || {};
if (formItemConfig?.name && field) {
const list = field?.query?.(formItemConfig?.name)?.value?.();
if (Array.isArray(list) && list[field?.index]) {
recordDataSource = list[field.index];
extraParamList = [field.index];
}
}
}
} else {
extraParamList.push(selectedRowKeys);
extraParamList.push(selectedRowRecords);
}
if (options) {
const { url, redirectType, urlParams = [] } = options;
let search = '';
if (urlParams && urlParams.length > 0) {
const temp = handleRequestParams(urlParams, {
urlParamsDataSource,
recordDataSource,
state,
extraParamList,
});
search = qs.stringify(temp);
}
if (url) {
let realUrl = calculateTextExprValue(url, {
urlParamsDataSource,
recordDataSource,
state,
extraParamList,
});
if (typeof realUrl === 'string' && realUrl.length > 0) {
if (realUrl.indexOf('?') !== -1) {
realUrl += `&${search}`;
} else if (search) {
realUrl += `?${search}`;
}
const temp = () => {
if (redirectType === 'current') {
if (typeof window.jumpTo === 'function') {
const tempList = realUrl?.split('?');
window.jumpTo({
pathname: tempList?.[0],
search: tempList?.[1],
});
} else {
location.href = realUrl;
}
} else if (redirectType === 'open') {
if (typeof window.jumpTo === 'function') {
const tempList = realUrl?.split('?');
window.jumpTo({
pathname: tempList?.[0],
search: tempList?.[1],
type: '_blank',
});
} else {
window.open(realUrl);
}
}
};
if (needDelay) {
setTimeout(temp, 1500);
} else {
temp();
}
}
}
}
},
// getButtonNode: (arg) => {
// const { buttonConfig, record, index } = arg;
// const { optType, options = {}, children } = buttonConfig;
// if (children) {
// let events = {};
// if (optType) {
// const button = componentMap[optType];
// if (typeof button?.action === 'function') {
// events = {
// onClick: button.action.bind(this, arg),
// };
// }
// }
// return {children};
// }
// return null;
// },
};
const message = {
title: '提示信息(toast)',
value: 'message',
position: ALL_BUTTON_POSITION_LIST,
getPrototypeList: (position, config) => {
return createMessageSetters({ position, isToast: true, config });
},
action: (config) => {
const {
buttonConfig,
urlParamsDataSource,
state,
_context,
recordDataSource,
actionRunEnv,
getFlowActionInfo,
position,
} = config || {};
let { response = {} } = config || {};
if (ActionRunEnv.flowAction === actionRunEnv) {
const flowInfo = getFlowActionInfo?.();
const { flowList, currentFlowIndex } = flowInfo || {};
if (isArrayNotEmpty(flowList) && currentFlowIndex) {
const realIndex = +currentFlowIndex;
if (isNumber(realIndex) && !isNaN(realIndex)) {
const beforeList = flowList.slice(0, realIndex);
// const lastRequestIndex = beforeList.findLastIndex(item=>item?.optType === 'request');
const lastRequestIndex = findLastIndex(
beforeList,
(item) => item?.optType === 'request',
);
let path = 'request';
if (lastRequestIndex !== 0) {
path += lastRequestIndex;
}
const realResponse = state?.valueOf?.[path];
if (isPlainObject(realResponse)) {
response = realResponse;
}
}
}
}
const msg = response?.msg;
const { options = {} } = buttonConfig || {};
const { type, title, content, ...rest } = options;
let realContent = content;
const realType =
calculateTextExprValue(type, {
urlParamsDataSource,
recordDataSource: getRealizeValue(recordDataSource),
state,
}) || 'success';
if (typeof content === 'function') {
let realFirstParam = response;
if (
[
ButtonPosition.formItemEvent,
ButtonPosition.formDialogItemEvent,
].includes(position)
) {
realFirstParam = getRealizeValue(recordDataSource);
}
realContent = content(realFirstParam, state);
}
if (!realContent && !title) {
realContent = msg;
}
CnMessage?.[realType]?.({ title, content: realContent, ...rest });
},
};
const submit = {
title: '提交(先校验表单,再发请求)',
value: 'submit',
position: [ButtonPosition.formDialog, ButtonPosition.form],
getPrototypeList: (position) => {
let paramSetter = 'StringSetter';
let paramSelectSetter;
let jsExpressionSetter;
const setterSnippet = getSetterSnippet({
position,
optType: 'submit',
});
const { requestParamSetter } = setterSnippet || {};
if (requestParamSetter) {
paramSetter = requestParamSetter;
if (Array.isArray(requestParamSetter?.props?.setters)) {
paramSelectSetter = requestParamSetter?.props?.setters?.find(
(item) => item?.componentName === 'ParamSelectSetter',
);
jsExpressionSetter = requestParamSetter?.props?.setters?.find(
(item) => item?.componentName === 'CnRowDataSetter',
);
}
}
const result = [
...createServiceSelectPrototype({
optType: 'submit',
paramSetter,
position,
paramSelectSetter,
jsExpressionSetter,
paramTitleDom: (
请求参数配置{' '}
提示:提交时会默认带上当前表单的全部数据作为参数,无需手动配置
),
}),
];
if ([ButtonPosition.formDialog].includes(position)) {
result.push({
name: 'afterRequestNotCloseDialog',
title: '请求成功后不关闭弹窗',
setter: 'BoolSetter',
});
}
return result;
},
action: (config) => {
const {
buttonConfig,
formInstance,
position,
close,
urlParamsDataSource,
recordDataSource,
state,
_context,
dialogRef,
needSuccessToast: paramNeedSuccessToast,
getExtraParam,
} = config;
const realFormInstance = getRealizeValue(formInstance);
if (buttonConfig && realFormInstance) {
if (realFormInstance?.submitting) {
} else {
let afterRequestPosition;
if (ButtonPosition.formDialog === position) {
afterRequestPosition =
ButtonPosition.formDialogSubmitAfterRequestSuccess;
} else if (ButtonPosition.form === position) {
afterRequestPosition = ButtonPosition.formSubmitAfterRequestSuccess;
}
const { options } = buttonConfig || {};
const {
afterRequest = {},
requestConfig = {},
afterRequestNotCloseDialog,
} = options || {};
const realUrl = getRealRequestUrl({
requestConfig,
state,
extraParam: getExtraParam?.(),
});
if (realUrl) {
requestConfig.url = realUrl;
requestConfig.dynamicUrl = undefined;
requestConfig.useDynamicUrl = undefined;
return realFormInstance?.submit((value) => {
if (value) {
let needSuccessToast = true;
if (paramNeedSuccessToast !== undefined) {
needSuccessToast = paramNeedSuccessToast;
}
if (afterRequestPosition && afterRequest?.optType === 'message') {
needSuccessToast = false;
}
return makeRequest({
buttonConfig,
urlParamsDataSource,
recordDataSource: value,
state,
needSuccessToast,
getExtraParam,
handleParams: () => {
return value;
},
onCancel: () => {
if (realFormInstance?.setSubmitting) {
realFormInstance.setSubmitting(false);
}
},
extraParamList: [],
})
.then((res) => {
if (afterRequestNotCloseDialog !== true) {
close && close();
}
return res;
})
.finally((res) => {
if (realFormInstance?.setSubmitting) {
realFormInstance.setSubmitting(false);
}
});
}
});
} else {
return realFormInstance?.validate?.();
}
}
}
},
};
const reset = {
title: '重置',
value: 'reset',
position: [ButtonPosition.formDialog, ButtonPosition.form],
action: (config) => {
const { buttonConfig, formInstance, position } = config;
const realFormInstance = getRealizeValue(formInstance);
if (buttonConfig && realFormInstance) {
realFormInstance.reset('*');
}
},
};
const setFormValue = {
title: '给表单设置数据',
value: 'setFormValue',
position: ALL_BUTTON_POSITION_LIST,
getDefaultProps: () => {
return {
mode: 'merge',
};
},
getPrototypeList: (position, config) => {
const { flowList, currentFlowIndex } = config || {};
return [
...createFormSelectSetters({
mode: 'single',
}),
getFormHandleTypeSetterSnippet(),
// {
// name:'mode',
// title:'新数据填入表单的方式',
// setter: {
// componentName: 'RadioGroupSetter',
// props: {
// options: [
// {
// title: '和原表单值合并',
// value: 'merge',
// },
// {
// title: '清空表单重新设值',
// value: 'overwrite',
// },
// ],
// },
// },
// },
{
name: 'formValues',
title: '要填入表单的数据',
className: 'cn-button-url-param-setter',
condition(prop) {
return (
prop?.parent?.getPropValue?.('handleType') === 'setFormFieldValue'
);
},
originalCondition(prop) {
return (
prop?.parent?.getPropValue?.('handleType') === 'setFormFieldValue'
);
},
setter: {
title: '给表单每个字段设置数据',
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
// initialValue: {
// },
props: {
config: {
items: [
{
name: 'label',
display: 'inline',
title: '选择字段',
isRequired: true,
setter: {
componentName: 'CnTreeSelectSetter',
props: (field) => {
const dataSource = [];
const currentData =
field?.parent?.parent?.parent?.getValue?.();
const { _bindForm } = currentData || {};
if (_bindForm && field) {
const node = getNodeById({
field,
id: _bindForm,
});
if (node?.id) {
const config = node?.getPropValue?.('config');
if (Array.isArray(config) && config.length > 0) {
config.forEach((item) => {
if (item?.name) {
const temp = {
label:
handleI18nLabel(item?.label) ||
item.name,
value: item.name,
};
dataSource.push(temp);
if (
isRecursionComponent(item?.componentName)
) {
const children = getArrayTableFieldList({
config: item?.options?.config,
arrayTableName: item.name,
});
if (isArrayNotEmpty(children)) {
temp.children = children;
}
}
}
});
}
}
}
return {
dataSource,
popupClassName: 'cn-tree-select-setter-pupup',
};
},
},
},
{
name: 'value',
display: 'inline',
title: '数据',
isRequired: true,
className: 'cn-param-select-setter',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
componentName: 'ParamSelectSetter',
props: {
ParamSelectSetterComponent: ParamSelectSetter,
configList: [
{
groupName: '其他数据',
groupExprName: __dataSource__,
needSecondParam: true,
},
{
groupName: '动作编排的数据',
groupExprName: __flowData__,
needSecondParam: true,
flowList,
currentFlowIndex,
},
],
},
title: '从数据源选择',
},
getJSExpressionPrototype({
type: 'formRequest',
prototypeConfig: config,
}),
],
},
},
},
],
},
},
},
},
},
},
{
name: 'allFormValues',
display: 'inline',
condition(prop) {
return (
prop?.parent?.getPropValue?.('handleType') === 'setAllFormValue'
);
},
originalCondition(prop) {
return (
prop?.parent?.getPropValue?.('handleType') === 'setAllFormValue'
);
},
title: '新的表单数据',
className: 'cn-param-select-setter',
// className: 'cn-button-url-param-setter',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
componentName: 'ParamSelectSetter',
props: {
configList: [
{
groupName: '其他数据',
groupExprName: __dataSource__,
needSecondParam: true,
},
{
groupName: '动作编排的数据',
groupExprName: __flowData__,
needSecondParam: true,
flowList,
currentFlowIndex,
},
],
},
title: '从数据源选择',
},
{
componentName: 'StringSetter',
title: '字符串',
},
{
componentName: 'NumberSetter',
title: '数字',
},
getJSExpressionPrototype({
type: 'formRequest',
prototypeConfig: config,
}),
],
},
},
},
];
},
action: (config) => {
const {
buttonConfig,
urlParamsDataSource,
state,
_context,
field,
position,
arrayBaseFieldIndex,
} = config || {};
const { options } = buttonConfig || {};
const { formValues, _bindForm, handleType, allFormValues } = options || {};
if (_bindForm) {
const formNode = _context?.$(_bindForm);
const formInstance = formNode?.getFormInstance?.();
if (formInstance) {
const oldFormValue = cloneDeep(formInstance?.values);
if (handleType === 'clearFormValue') {
formInstance.setValues?.({}, 'overwrite');
} else if (handleType === 'setAllFormValue') {
const newFormValue = calculateTextExprValue(allFormValues, {
urlParamsDataSource,
recordDataSource: oldFormValue,
state,
});
if (isPlainObject(newFormValue)) {
formInstance.setValues?.(newFormValue, 'overwrite');
}
} else {
let newFormValue;
if (Array.isArray(formValues)) {
if (formValues.length > 0) {
const arrayTableValues = [];
const notArrayTableValues = [];
formValues.forEach((item) => {
if (item?.label?.includes(__arrayTableCurrentRow__)) {
arrayTableValues.push(item);
} else {
notArrayTableValues.push(item);
}
});
const temp = handleRequestParams(notArrayTableValues, {
urlParamsDataSource,
recordDataSource: oldFormValue || {},
state,
});
if (isArrayNotEmpty(arrayTableValues)) {
let fieldIndex;
if (position === ButtonPosition.arraySubAreaCardOperate) {
fieldIndex = arrayBaseFieldIndex;
} else if (field) {
fieldIndex = field?.path?.segments?.[1];
}
if (typeof fieldIndex === 'number') {
const tempFormValue = { ...oldFormValue, ...temp };
arrayTableValues.forEach((aitem) => {
const { label, value } = aitem || {};
const arr = label?.split?.(`.${__arrayTableCurrentRow__}.`);
if (arr.length === 2) {
const fieldName = arr[0];
const arrayTableFieldName = arr[1];
const temp2 = handleRequestParams([aitem], {
urlParamsDataSource,
recordDataSource: tempFormValue,
state,
});
if (
fieldName &&
arrayTableFieldName &&
tempFormValue[fieldName]?.[fieldIndex]
) {
tempFormValue[fieldName][fieldIndex][
arrayTableFieldName
] = temp2[label];
temp[fieldName] = tempFormValue[fieldName];
}
}
});
}
}
if (isPlainObject(temp)) {
newFormValue = temp;
}
}
}
formInstance.setValues?.(newFormValue);
}
}
}
return Promise.resolve();
},
};
const arrayTableAdd = {
title: '添加一行',
value: 'arrayTableAdd',
position: [ButtonPosition.arrayTableOperate],
getPrototypeList: (position) => {
return [];
},
action: ({ buttonConfig, formData, open, close }) => {},
};
const flowAction = {
title: '动作编排',
value: 'flowAction',
position: ALL_BUTTON_POSITION_LIST,
getPrototypeList: (position) => {
return [
{
name: 'flowList',
title: '动作编排',
display: 'plain',
setter: createFlowListSetters({
position,
activeSetter: {
componentName: 'MixedSetter',
props: {
setters: [
{
componentName: ,
title: '启用/禁用',
},
{
componentName: (
),
props(field) {
const flowList = field?.parent?.parent?.getValue?.();
const index = field?.parent?.name;
return {
configList: [
{
groupName: '动作编排的数据',
groupExprName: __flowData__,
needSecondParam: true,
flowList,
currentFlowIndex: index,
},
{
groupName: '其他数据',
groupExprName: __dataSource__,
needSecondParam: true,
},
],
};
},
title: '简单表达式',
},
{
title: '写js表达式',
componentName: 'CnRowDataSetter',
props(field) {
const stateList = getDataSourceListWithAllPath({
needChildren: true,
prototypeConfig: {
flowList: field?.parent?.parent?.getValue?.(),
currentFlowIndex: field?.parent?.name,
},
});
return {
list: stateList,
initialCode: `(arg, state) => {
// return state.urlParams.xxx;
}`,
tip: `
state:全部的数据,在左侧列表中选择使用。
`,
};
},
},
],
},
},
}),
},
];
},
action: (config, ...otherArgs) => {
const { buttonConfig, position, _context } = config || {};
const { options } = buttonConfig || {};
const { flowList } = options;
if (Array.isArray(flowList) && flowList.length > 0) {
async function executeFlowList(list) {
const result = [];
for (const index in list) {
const item = list[index];
const { active, optType, options: itemOptions } = item || {};
const isActive = executeObjectExpr(
active,
{
[__dataSource__]: _context?.state,
},
{},
_context?.state,
);
if (isActive === true) {
let action = getButtonAction({
...item,
position,
});
if (!action) {
const componentDefine = getRunTimeItem(optType);
const component = getRealizeValue(componentDefine?.component);
if (typeof component?.action === 'function') {
action = component.action;
}
}
let flowResult;
if (typeof action === 'function') {
flowResult = await action(
{
needSuccessToast: false,
...config,
buttonConfig: { ...item },
// 动作执行的环境
actionRunEnv: 'flowAction',
getFlowActionInfo: () => {
return {
flowList,
currentFlowIndex: index,
};
},
},
...otherArgs,
);
}
const handleFlowResult = getItem(
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;
}
if (_context?.state) {
const flowDataKeys = Object.keys(_context.state.valueOf);
if (Array.isArray(flowDataKeys) && flowDataKeys.length > 0) {
flowDataKeys.forEach((key) => {
if (key) {
if (key.includes('$$$') || key.startsWith('Cn')) {
} else {
_context.state.valueOf[key] = undefined;
}
}
});
}
}
executeFlowList(flowList);
// try {
// }catch (e){
// console.log('flow action run error', e);
// }
}
},
};
const request = {
title: '发请求',
value: 'request',
position: ALL_BUTTON_POSITION_LIST,
getPrototypeList: (position, config) => {
let paramSetter = 'StringSetter';
let paramSelectSetter;
let jsExpressionSetter;
let wholeParamSetter;
const setterSnippet = getSetterSnippet({
position,
optType: 'request',
...config,
});
const { requestParamSetter } = setterSnippet || {};
if (requestParamSetter) {
paramSetter = requestParamSetter;
if (Array.isArray(requestParamSetter?.props?.setters)) {
paramSelectSetter = requestParamSetter?.props?.setters?.find(
(item) => item?.componentName === 'ParamSelectSetter',
);
jsExpressionSetter = requestParamSetter?.props?.setters?.find(
(item) => item?.componentName === 'CnRowDataSetter',
);
}
}
if ([ButtonPosition.tableOperate].includes(position)) {
wholeParamSetter = {
name: 'params',
title: '请求参数配置',
className: 'params-list',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
title: '设置每个字段的值',
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
initialValue: {},
props: {
config: {
items: [
{
name: 'label',
isRequired: true,
title: '参数名',
setter: 'StringSetter',
},
{
name: 'value',
isRequired: true,
title: '参数值',
setter: paramSetter,
},
],
},
},
},
},
},
jsExpressionSetter,
],
},
},
};
}
return createServiceSelectPrototype({
optType: 'request',
paramSetter,
position,
paramSelectSetter,
jsExpressionSetter,
wholeParamSetter,
});
},
action: (config, extra) => {
let {
buttonConfig = {},
record,
componentProps = {},
position,
tableRef,
state,
urlParamsDataSource,
recordDataSource,
needSuccessToast,
extraParamList,
arrayTableConfig,
noNeedHandleResult,
isDesign,
_context,
field,
formInstance,
actionRunEnv,
getExtraParam,
arrayTableCurrentRow,
arrayBaseFieldIndex,
} = config;
const { options = {} } = buttonConfig;
const { keepPagination } = options;
if (position === ButtonPosition.arraySubAreaCardOperate) {
recordDataSource = arrayTableCurrentRow;
extraParamList = [arrayBaseFieldIndex];
} else if (position === ButtonPosition.arrayTableOperate) {
if (extra?.field) {
const { field } = extra;
const { formItemConfig } = arrayTableConfig || {};
if (formItemConfig?.name && field) {
const list = field?.query?.('..')?.value?.();
if (Array.isArray(list) && list[field?.index]) {
recordDataSource = list[field.index];
if (!extraParamList) {
extraParamList = [field.index];
}
}
}
}
}
const realField = field || extra?.field;
return makeRequest({
buttonConfig,
urlParamsDataSource,
recordDataSource: getRealizeValue(recordDataSource),
state,
needSuccessToast,
noNeedHandleResult,
extraParamList,
position,
isDesign,
_context,
getExtraParam: () => {
const tempExtraParam = executeFunction(getExtraParam);
let extraParam = {};
if (isPlainObject(tempExtraParam)) {
extraParam = {
...tempExtraParam,
};
}
// const realFormInstance = getRealizeValue(formInstance);
// if(realFormInstance && field && position === ButtonPosition.formItemEvent) {
// const tempFormValue = realFormInstance.values;
// if(tempFormValue) {
// const segments = field?.path?.segments;
// if(isArrayNotEmpty(segments) && segments.length >= 3) {
// const needSegments = segments.slice(0,2)
// const tempCurrentRow = get(tempFormValue, needSegments)
// if(isPlainObject(tempCurrentRow)) {
// extraParam[__arrayTableCurrentRow__] = tempCurrentRow;
// }
// }
//
// }
// }
const realFormInstance = getRealizeValue(formInstance);
if (
realFormInstance &&
realField &&
[
ButtonPosition.formItemEvent,
ButtonPosition.arraySubAreaCardOperate,
].includes(position)
) {
const realPath = field?.path?.parent?.()?.segments;
if (ButtonPosition.arraySubAreaCardOperate === position) {
}
const tempCurrentRow = realFormInstance?.getValuesIn?.(
field?.path?.parent?.()?.segments,
);
if (isPlainObject(tempCurrentRow)) {
extraParam[__arrayTableCurrentRow__] = tempCurrentRow;
}
}
return extraParam;
},
handleParams: () => {
const params = {};
if (position === ButtonPosition.tableOperate) {
const { primaryKey } = componentProps;
if (primaryKey && record[primaryKey] !== undefined) {
params[primaryKey] = record[primaryKey];
}
}
return params;
},
}).then((res) => {
if (position !== ButtonPosition.tableToolArea) {
if (actionRunEnv === ActionRunEnv.flowAction) {
} else if (position === ButtonPosition.tableOperate) {
if (keepPagination === true) {
tableRef?.tableLoad()?.();
} else {
tableRef?.load?.();
}
} else {
tableRef?.load?.();
}
}
return res;
});
},
handleFlowResult: (res) => {
return getRealResponse(res);
},
// getButtonNode: (arg) => {
// const { buttonConfig, record, index } = arg;
// const { optType, options = {}, children } = buttonConfig;
// if (children) {
// let events = {};
// if (optType) {
// const { needConfirm, confirmInfo = {} } = options;
// const button = componentMap[optType];
// if (typeof button?.action === 'function') {
// const action = button.action.bind(this, arg);
// events = {
// onClick: needConfirm ? () => {
// Dialog.confirm({
// v2: true,
// title: confirmInfo.title || '通知',
// content: confirmInfo.content || '是否确认',
// onOk: action,
// cancelProps: {
// children: '关闭弹框',
// },
// });
// } : action,
// };
// }
// }
// return {children};
// }
// return null;
// },
};
const arrayTableRemove = {
title: '删除',
value: 'arrayTableRemove',
position: [ButtonPosition.arrayTableOperate],
action: (config) => {},
};
const setDataSourceValue = {
title: '给页面的数据源设置数据',
value: 'setDataSourceValue',
position: ALL_BUTTON_POSITION_LIST,
getDefaultProps: () => {
return {};
},
getPrototypeList: (position, config) => {
const { flowList, currentFlowIndex } = config || {};
return [
{
name: 'dataSourceValues',
title: '给数据源设置数据',
className: 'cn-button-url-param-setter',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
title: '给数据源设置数据',
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
// initialValue: {
// },
props: {
config: {
items: [
{
name: 'label',
display: 'inline',
title: '选择页面数据源',
isRequired: true,
setter: {
componentName: 'SelectSetter',
props: (field) => {
const options = getDataSourceList({
typeList: ['VALUE'],
})?.filter(
(item) =>
item?.dataSourceId &&
item.dataSourceId?.startsWith?.(
pageDataSource,
),
);
return {
options: options || [],
};
},
},
},
{
name: 'value',
display: 'inline',
title: '数据',
isRequired: true,
className: 'cn-param-select-setter',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
componentName: 'ParamSelectSetter',
props: {
configList: [
{
groupName: '其他数据',
groupExprName: __dataSource__,
needSecondParam: true,
},
{
groupName: '动作编排的数据',
groupExprName: __flowData__,
needSecondParam: true,
flowList,
currentFlowIndex,
},
],
},
title: '从数据源选择',
},
{
componentName: 'StringSetter',
title: '字符串',
},
{
componentName: 'NumberSetter',
title: '数字',
},
getJSExpressionPrototype({
type: 'formRequest',
prototypeConfig: config,
}),
],
},
},
},
],
},
},
},
},
},
// getJSExpressionPrototype({type:'base'})
],
},
},
},
];
},
action: (config) => {
const {
buttonConfig,
urlParamsDataSource,
state,
_context,
recordDataSource,
} = config || {};
const { options } = buttonConfig || {};
const { dataSourceValues } = options || {};
if (Array.isArray(dataSourceValues) && dataSourceValues.length > 0) {
const temp = handleRequestParams(dataSourceValues, {
urlParamsDataSource,
recordDataSource: getRealizeValue(recordDataSource) || {},
state,
});
if (isPlainObject(temp) && Object.keys(temp).length > 0) {
_context?.setState?.(temp);
emitEvent(CnDataSourceChange);
}
}
return Promise.resolve();
},
};
const dialog = {
title: '弹窗',
value: 'dialog',
position: ALL_BUTTON_POSITION_LIST,
action: (config, extra) => {
const {
arrayTableConfig,
buttonConfig,
_context,
position,
componentProps,
record,
index,
selectedRowKeys,
selectedRowRecords,
response,
arrayTableCurrentRow,
} = config || {};
let recordDataSource = record;
if (position === ButtonPosition.arraySubAreaCardOperate) {
recordDataSource = arrayTableCurrentRow;
} else if (!record && extra?.field) {
const { field } = extra;
const { formItemConfig } = arrayTableConfig || {};
if (formItemConfig?.name && field) {
if (field.path.segments.length === 5) {
const path = field.path.segments.slice(0, 4);
const tempRow = field?.form?.getValuesIn?.(path);
if (isPlainObject(tempRow)) {
recordDataSource = cloneDeep(tempRow);
}
} else {
const list = field?.query?.(formItemConfig?.name)?.value?.();
if (Array.isArray(list) && list[field?.index]) {
recordDataSource = cloneDeep(list[field.index]);
}
}
}
}
if (position === ButtonPosition.tableCellAfterRequestSuccess) {
recordDataSource = response?.data || {};
}
if (buttonConfig && _context) {
const { options = {} } = buttonConfig;
const { _bindDialog, setCurrentRowToDialog } = options;
if (_bindDialog) {
const dialogNode = _context.$(_bindDialog);
let realRecordDataSource = recordDataSource;
if (setCurrentRowToDialog === false) {
realRecordDataSource = undefined;
}
return new Promise((resolve) => {
setTimeout(() => {
const p = dialogNode?.open?.(realRecordDataSource, {
buttonConfig,
position,
selectedRowKeys,
selectedRowRecords,
});
if (typeof p?.then === 'function') {
p.then((res) => {
setTimeout(() => {
resolve(true);
}, 8);
});
} else {
setTimeout(() => {
resolve(true);
}, 8);
}
});
});
// table?.load?.();
}
}
},
getPrototypeList: (position) => {
const result = [
getSelectDialogSnippet(),
// {
// name:'openDialogMode',
// title:'当一个弹窗复用于新增和编辑多个场景时,你希望本次打开的弹窗用途',
// setter:{
// componentName:'CnSelectSetter',
// props:{
// options: getOpenDialogModeEnum({
// prefix:'用于'
// }),
// selectProps:{
// hasClear: true,
// }
// }
// }
// }
];
if (
[
ButtonPosition.tableOperate,
ButtonPosition.arrayTableOperate,
ButtonPosition.tableCell,
].includes(position)
) {
result.splice(1, 0, {
title: '是否将表格当前行数据默认带入到弹窗表单中',
name: 'setCurrentRowToDialog',
setter: {
componentName: 'RadioGroupSetter',
props: {
options: getCommonBoolDataSource(),
},
},
defaultValue: true,
});
}
return result;
},
};
const cancel = {
title: '取消(关闭当前弹窗)',
value: 'cancel',
position: [
ButtonPosition.dialog,
ButtonPosition.formDialog,
ButtonPosition.form,
],
action: ({ buttonConfig, formData, open, close }) => {
if (buttonConfig) {
close && close();
}
},
};
const tableReload = {
title: '刷新表格',
value: 'tableReload',
position: ALL_BUTTON_POSITION_LIST,
getPrototypeList: () => {
return [...createTableSelectSetters()];
},
action: (arg) => {
const { buttonConfig, _context } = arg || {};
const { options = {} } = buttonConfig;
const { _bindTable, keepPagination } = options;
function reloadOneTable(id) {
if (typeof id === 'string') {
const table = _context.$(id);
if (keepPagination === true) {
table?.tableLoad()?.();
} else {
table?.load?.();
}
}
}
if (_bindTable && _context) {
if (Array.isArray(_bindTable)) {
_bindTable.forEach((item) => {
reloadOneTable(item);
});
} else {
reloadOneTable(_bindTable);
}
}
},
};
/// --------- jsbridge start ---------
const jsBridgeTextSetter = ({ position, config }) => {
const { urlSetter = 'StringSetter' } =
getSetterSnippet({
position,
optType: 'jsbridge',
...config,
}) || {};
return urlSetter;
};
const getJsBridgeToastMessageField = ({ initialValue = '' }) => ({
successToastMessage: {
title: '成功toast文案',
setter: {
componentName: 'StringSetter',
initialValue,
},
},
});
const toastResultCallback = ({ response, inputParams }) => {
const { successToastMessage } = inputParams || {};
if (successToastMessage) {
CnMessage.success?.({ content: successToastMessage });
}
};
/** api配置 */
const BRIDGE_API_CONFIGS = {
callPhone: {
title: '拨打电话',
props: {
phoneNumber: {
title: '电话号码',
setter: jsBridgeTextSetter,
},
},
},
scan: {
title: '扫一扫',
props: {
scanType: {
title: '扫码类型',
setter: {
componentName: 'RadioGroupSetter',
initialValue: 'qrCode',
props: {
options: [
{
title: '二维码',
value: 'qrCode',
},
{
title: '条形码',
value: 'barCode',
},
],
},
},
},
scanResult: {
title: '扫码结果',
setter: {
componentName: 'RadioGroupSetter',
initialValue: 'blank',
props: {
options: [
{
title: '新开窗口',
value: 'blank',
},
{
title: '复制到剪贴板',
value: 'copy',
},
],
},
},
},
},
/**
* 端执行回调
* response: 端执行的结果
* inputParams: 参数,保存用户做的选择
*/
resultCallback: ({ response, inputParams }) => {
const code = response?.code || response?.qrCode || response?.barCode;
const { scanResult } = inputParams || {};
if (scanResult === 'blank') {
CnUniApi?.navigateTo?.({ url: code });
} else if (scanResult === 'copy') {
CnUniApi?.setClipboard?.({ text: code })
?.then(() => CnMessage.success({ content: '已复制到剪贴板' }))
?.catch((err) =>
CnMessage.error({ content: err?.errMsg || '复制失败' }),
);
}
},
},
showSharePanel: {
title: '分享',
props: {
title: {
title: '分享标题',
setter: jsBridgeTextSetter,
},
content: {
title: '分享文案',
setter: jsBridgeTextSetter,
},
url: {
title: '分享网址',
setter: jsBridgeTextSetter,
},
image: {
title: 'logo主图',
setter: jsBridgeTextSetter,
},
},
},
saveImage: {
title: '保存到相册',
props: {
url: {
title: '图片地址',
setter: jsBridgeTextSetter,
},
...getJsBridgeToastMessageField({ initialValue: '保存成功' }),
},
resultCallback: toastResultCallback,
},
setClipboard: {
title: '复制到剪贴板',
props: {
text: {
title: '复制文案',
setter: jsBridgeTextSetter,
},
...getJsBridgeToastMessageField({ initialValue: '复制成功' }),
},
resultCallback: toastResultCallback,
},
choosePhoneContact: {
title: '通讯录',
props: {
needCallPhone: {
title: '选择后拨打',
setter: {
componentName: 'BoolSetter',
initialValue: true,
},
},
},
resultCallback: ({ response, inputParams }) => {
const { needCallPhone } = inputParams || {};
const mobile = response?.mobile || '';
const phoneNumber = mobile.split(',')?.[0] || mobile;
if (needCallPhone) {
CnUniApi?.callPhone?.({ phoneNumber });
}
},
},
navigateTo: {
title: '新开浏览器窗口',
props: {
url: {
title: '新窗口地址',
setter: jsBridgeTextSetter,
},
},
},
navigateBack: {
title: '关闭浏览器窗口',
},
setNavigationBarTitle: {
title: '设置标题',
props: {
title: {
title: '标题名称',
setter: jsBridgeTextSetter,
},
},
},
getLocation: {
title: '获取位置',
},
getNetworkType: {
title: '获取当前网络状态',
},
pay: {
title: '支付',
props: {
payStr: {
title: '订单信息',
setter: jsBridgeTextSetter,
},
},
},
vibrate: {
title: '手机震动',
},
snapshot: {
title: '截屏',
},
call: {
title: '自定义能力',
props: {
data: {
title: '自定义入参',
setter: {
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
initialValue: {
label: 'param',
},
props: {
config: {
items: [
{
title: '参数名',
name: 'label',
isRequired: true,
description: '参数名',
setter: 'StringSetter',
},
{
title: '参数值',
name: 'value',
isRequired: true,
description: '参数值',
className: 'cn-param-select-setter',
setter: {
componentName: 'MixedSetter',
props: {
setters: [
{
componentName: 'StringSetter',
title: '字符串',
},
{
componentName: 'NumberSetter',
title: '数字',
},
{
componentName: 'BoolSetter',
title: '布尔(true/false)',
},
],
},
},
},
],
},
},
},
},
},
},
},
},
};
const jsbridge = {
title: '跨端JSBridge',
value: 'jsbridge',
position: ALL_BUTTON_POSITION_LIST,
getDefaultProps: () => {
return {};
},
/**
* 二级面板配置
* @param position 位置,如:btn_tableOperate
* @param config TODO: 配置,默认undefined | {__field: Node}
* @returns
*/
getPrototypeList: (position, config) => {
const jsbridgeApis = {
name: 'apiName',
title: '跨端能力',
// setter: https://lowcode-engine.cn/site/docs/guide/appendix/setters
setter(node) {
const options = Object.keys(BRIDGE_API_CONFIGS).map((key) => ({
title: BRIDGE_API_CONFIGS[key]?.title,
value: key,
}));
return {
componentName: 'SelectSetter',
initialValue: 'callPhone', // 初始化值
props: {
options,
},
};
},
};
const apiPropsList = Object.keys(BRIDGE_API_CONFIGS)
.map((apiName) => {
const { props = {} } = BRIDGE_API_CONFIGS[apiName];
return Object.keys(props).map((fieldName) => {
const fieldConfig = props[fieldName];
const { title = '', setter = 'StringSetter' } = fieldConfig || {};
return {
name: fieldName,
title,
condition: (node) => {
return node?.parent?.getPropValue?.('apiName') === apiName;
},
setter:
typeof setter === 'function'
? setter({ position, config })
: setter,
};
});
})
.flat();
return [
jsbridgeApis, // api选择
...apiPropsList, // 配置选择
];
},
action: async (context) => {
const {
buttonConfig: { options } = {},
// urlParamsDataSource,
// recordDataSource,
// state,
// getExtraParam,
// position,
// arrayTableConfig,
// selectedRowKeys = [],
// selectedRowRecords = [],
} = context;
if (!options) {
return;
}
/**
* 根据参数表达式,获得真实的值
* originalParams: 输入参数。用户的原始选择(包含表达式)
* context: action上下文环境
*/
const getApiParams = (originalParams, context) => {
const { urlParamsDataSource, recordDataSource, state, getExtraParam } =
context;
const params = Object.keys(originalParams)
.map((key) => {
if (key.startsWith('_unsafe_')) {
return null;
}
const originalValue = originalParams[key];
const newValue = calculateTextExprValue(originalValue, {
urlParamsDataSource,
recordDataSource,
state,
extraParamList: [],
getExtraParam,
});
return { [key]: newValue };
})
.filter((item) => !!item)
.reduce((prev, current) => {
return { ...prev, ...current };
}, {});
return params;
};
/**
* 根据apiName配置,执行对应的回调函数(如有)
* apiName: api命名
* inputParams: 参数,保存用户做的选择
* response: 端执行的结果
*/
const excuteApiResultCallback = ({ apiName, inputParams, response }) => {
const apiNameConfig = Object.keys(BRIDGE_API_CONFIGS)
.filter((key) => key === apiName)
.map((key) => BRIDGE_API_CONFIGS[key])?.[0];
const { resultCallback } = apiNameConfig || {};
if (!apiNameConfig) {
return;
}
if (!resultCallback) {
return;
}
resultCallback?.({ response, inputParams });
};
// cn-uni-api处理
// 1. 获取真实的参数值
const { apiName, ...rest } = options;
const inputParams = getApiParams(rest, context);
const { log, warn } = console; // TODO: 真机调试不方便,先打点调试,后续删除。
log('--before jsbridge--:', apiName, inputParams);
// 2. 执行
return CnUniApi?.[apiName]?.({ ...inputParams })
?.then((response) => {
// 3. 回调处理
log('--success jsbridge--:', response);
excuteApiResultCallback({ apiName, inputParams, response });
// 处理回调函数,用“动作编排”能力。
return {
success: true,
data: response,
error: null,
};
})
?.catch((err) => {
warn('--fail jsbridge--:', err);
return {
success: true,
data: null,
error: err,
};
});
},
};
/// --------- jsbridge end ---------
const componentMap = {
request,
link,
submit,
reset,
setFormValue,
tableReload,
dialog,
cancel,
arrayTableAdd,
arrayTableRemove,
setDataSourceValue,
message,
flowAction,
jsAction,
jsbridge,
};
export const createFlowListSetters = (config) => {
const { position, activeSetter } = config || {};
return {
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
initialValue: {
active: true,
},
props: {
config: {
items: [
{
name: 'optType',
display: 'inline',
title: '动作类型',
isRequired: true,
setter: {
componentName: 'SelectSetter',
props: () => {
return {
options: getButtonListByPosition(position, {
excludeButtonList: ['flowAction'],
}),
};
},
},
},
{
name: 'active',
display: 'inline',
title: '启用',
isRequired: true,
setter: activeSetter || {
componentName: ,
title: '启用/禁用',
},
},
{
name: 'options',
// display: 'accordion',
display: 'plain',
title: '动作配置项',
extraProps: {
defaultCollapsed: false,
},
setter: {
componentName: 'ObjectSetter',
props: (field) => {
const flowList = field?.parent?.parent?.getValue?.();
const index = field?.parent?.name;
return {
config: {
items: [
...getButtonPrototypeListByPosition(position, {
flowList,
currentFlowIndex: index,
}),
],
},
};
},
},
},
],
},
},
},
},
};
};
export function getItem(position, componentName, propKey) {
let result;
if (componentName) {
let item = componentMap[componentName];
if (!item) {
item = getBizComponent(componentName, position);
}
if (item && item.position && item.position.includes(position)) {
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 getButtonAction(buttonConfig) {
const { optType, position } = buttonConfig || {};
if (optType) {
const action = getItem(position, optType, 'action');
if (typeof action === 'function') {
return action;
}
}
}
// 获取按钮列表
export function getButtonListByPosition(position, config) {
const { excludeButtonList = [] } = config || {};
const defaultList = Object.keys(componentMap);
const bizComponentNameList = getBizComponentNameList();
const allComponentList = uniq([...defaultList, ...bizComponentNameList]);
const result = [];
if (position !== undefined) {
allComponentList.forEach((name) => {
if (excludeButtonList?.includes(name)) {
} else {
const component = getItem(position, name);
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;
}
// 获取按钮prototype列表by position
export function getButtonPrototypeListByPosition(position, config) {
const defaultList = Object.keys(componentMap);
let prototypeList = [];
const bizComponentNameList = getBizComponentNameList();
const allComponentList = uniq([...defaultList, ...bizComponentNameList]);
if (position !== undefined) {
allComponentList.forEach((name) => {
const item = getItem(position, name) || {};
const { getPrototypeList, configure = [] } = item;
if (typeof getPrototypeList === 'function') {
const temp = getPrototypeList(position, config);
if (temp && temp.length > 0) {
prototypeList = [
...prototypeList,
...handlePrototypeCondition(temp, name, 'optType'),
];
}
} else if (configure?.length > 0) {
prototypeList = [
...prototypeList,
...handlePrototypeCondition(configure, name, 'optType'),
];
}
});
}
return prototypeList;
}
export const createButtonListSetters = (config) => {
const { position, childrenTitle } = config || {};
const tempButtonList = getButtonListByPosition(position, config);
const titleSetter = 'CnI18nSetter';
const configure = [
{
name: 'primaryKey',
title: '唯一标识',
condition: {
type: 'JSFunction',
value: '() => false',
},
initialValue: {
type: 'JSFunction',
value:
'val => {\n if (val) return val;\n return String(Math.floor(Math.random() * 10000));\n }',
},
setter: 'StringSetter',
},
{
name: 'children',
isRequired: true,
title: childrenTitle || '标题',
setter: titleSetter,
},
{
name: 'optType',
title: '按钮功能',
isRequired: true,
display: 'inline',
// extraProps: {
// setValue(target, value) {
// const currentRowValue = target?.parent?.getValue();
// const newButtonInitialValue = getItemDefaultProps(position, value);
// target?.parent.setValue({
// ...currentRowValue,
// optType: value,
// options: newButtonInitialValue,
// });
// },
// },
editable: true,
setter: {
componentName: 'SelectSetter',
props: () => {
return {
options: getButtonListByPosition(position, config),
};
},
},
},
];
configure.push({
name: 'options',
// display: 'accordion',
display: 'block',
title: '按钮配置项',
extraProps: {
defaultCollapsed: false,
},
setter: {
componentName: 'ObjectSetter',
props: () => {
return {
config: {
items: [...getButtonPrototypeListByPosition(position)],
},
};
},
},
});
const styleList = getStyleListByPosition(position);
if (styleList?.length > 0) {
configure.push({
title: '样式',
type: 'group',
display: 'accordion',
collapsed: true,
items: styleList,
});
}
return {
componentName: 'ArraySetter',
props: {
mode: 'list',
itemSetter: {
componentName: 'ObjectSetter',
initialValue() {
return {
primaryKey: uuid(6),
children: '按钮',
optType: tempButtonList[0]?.value,
};
},
props: {
config: {
items: configure,
},
},
},
},
};
};
export function createFormSelectSetters(config) {
const { mode } = config || {};
return [
{
name: '_bindForm',
title: '选择表单',
setter(prop) {
const options = [];
prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
if (
item.getPropValue('isCnForm') ||
item.getPropValue('isCnFormDialog')
) {
let prefix = '表单';
if (item.getPropValue('isCnFormDialog')) {
prefix = '弹窗表单';
}
const id = item.id || '';
const title = `${prefix}_${
handleI18nLabel(item?.propsData?.title) || ''
}`;
options.push({
title,
value: id,
});
}
});
return {
componentName: 'SelectSetter',
props: {
mode,
// hasClear: true,
options,
},
};
},
},
];
}
export function getRunTimeItem(componentName) {
let result;
if (componentName) {
result = componentMap[componentName];
if (!result) {
result = getRunTimeBizComponent(componentName);
}
}
return result;
}