import {
  getJSExpressionPrototype,
  getParamSetterPrototype,
  getStyleListByPosition,
} from './common-style';
import React, { useEffect } from 'react';
import qs from 'query-string';
import { ButtonPosition } from './position/button-position';
import {
  createRequestSuccessPrototype,
  createServiceSelectPrototype,
  getRealResponse,
  handleRequestParams,
  handleResultProcessFunc,
  makeRequest,
  transRequestConfigToRemote,
} from '../util/request';
import {
  calculateTextExprValue,
  executeFunction,
  executeObjectExpr,
  getArrayTableCurrentRowByField2,
  getArrayTableFieldList,
  getBizComponent,
  getBizComponentNameList,
  getDataSourceList,
  getDataSourceListWithAllPath,
  getDownloadProps,
  getNodeById,
  getRealizeValue,
  getRealRequestUrl,
  getRunTimeBizComponent, getVariableDsList,
  handleI18nLabel,
  handlePrototypeCondition,
  isArrayNotEmpty,
  isRecursionComponent,
  renderIcon,
  uuid,
} from '../util/util';
import {
  CnButton,
  CnDialog,
  CnDownload,
  CnMenuButton,
  CnMenuButtonItem,
  CnMessage,
} from '@cainiaofe/cn-ui';
import uniq from 'lodash/uniq';
import isPlainObject from 'lodash/isPlainObject';
import cloneDeep from 'lodash/cloneDeep';
import flatten from 'lodash/flatten';
import './button.scss';
import { createMessageSetters } from '@/common/util/message';
import $i18n from 'panda-i18n';
import CheckboxSetter from '@/common/setter/checkbox-setter';
import {
  getFieldSelectSetterSnippet,
  getFormHandleTypeSetterSnippet,
  getJSXTemplate,
  getSelectDialogSnippet,
  getSetterSnippet,
} from '@/common/manager/setter-snippet';
import groupBy from 'lodash/groupBy';
import {
  __arrayTableCurrentRow__,
  __dataSource__,
  __flowData__,
  componentRefSplit,
  getCommonBoolDataSource,
  getOpenDialogModeEnum,
  openDialogModeLabel,
} from '@/common/util/expr-const';
import { getSelectParamSelectSetter } from '@/common/manager/filter-item/select';
import {
  formComponentRefStorage,
  pageDataSource,
} from '@/common/util/const';
import {
  CnDataSourceChange,
  emitEvent,
} from '@/common/util/event-name';
import { ActionRunEnv } from '@/common/util/action-run-env';
import ExprSetter from '@/common/setter/expr-setter';
import isNaN from 'lodash/isNaN';
import isNumber from 'lodash/isNumber';
import isFunction from 'lodash/isFunction';
import { ParamSelectSetter } from '@/common/setter/param-select-setter';
import set from 'lodash/set';
import isUndefined from 'lodash/isUndefined';
import findLastIndex from 'lodash/findLastIndex';
import { DisplayPosition } from '@/common/manager/position/display-position';

const { ActionSetter } = window.VisualEngineUtils || {};
const jsActionMap = {
  [ButtonPosition.formItemEvent]: `/**
* onFieldValueChange
* 用法请参考formily官方示例
* https://formilyjs.org/zh-CN/guide/advanced/linkages#effects-%E7%94%A8%E4%BE%8B-2
*
* @param field 当前字段
* @param form 当前表单实例
*/
function onFieldValueChange(field, form) {
  // 当前字段的值
  // const value = field.value;
  // 查询其他字段的值
  // const otherFieldValue = field.query('xxx').value()
  // 设置字段的值
  // form.setFieldState('xxx', (state) => {
  //   state.value = yyy;
  // })
}`,
  [ButtonPosition.filterItemEvent]: `/**
* onFieldValueChange
*
* @param field 当前字段
* @param form 当前筛选栏实例
*/
function onFieldValueChange(field, form) {
  // 当前字段的值
  // const value = field.value;
  // 查询其他字段的值
  // const otherFieldValue = field.query('xxx').value()
  // 设置字段的值
  // form.setFieldState('xxx', (state) => {
  //   state.value = yyy;
  // })
}`,
  // [ButtonPosition.formDialogItemEvent]: this[ButtonPosition.formItemEvent],
  [ButtonPosition.cnArrayTableItemEvent]: `/**
* onFieldValueChange
* 用法请参考formily官方示例
* https://formilyjs.org/zh-CN/guide/advanced/linkages#effects-%E7%94%A8%E4%BE%8B-2
*
* @param field 当前字段
* @param form 当前表单实例
*/
function onFieldValueChange(field, form) {
  // 当前字段的值
  // const value = field.value;
  // 当前行的index
  // const index = field?.path?.segments?.[1];
  // 查询当前行其他字段的值，xxx代表可编辑表格的字段编码，yyy代表表格某列的字段编码
  // const otherFieldValue = field.query(\`xxx.$\{index}.yyy\`).value()
  // 查询表单其他字段的值
  // const otherFieldValue2 = field.query('xxx').value()
  // 设置当前行其他字段的值
  // form.setFieldState(\`xxx.$\{index}.yyy\`, (state) => {
  //   state.value = zzz;
  // });
}`,
  [ButtonPosition.form]: `/**
* js脚本
*
*/
function jsAction({ form, state }) {
  // state：全部组件的数据
  // form：表单实例
}`,
  [ButtonPosition.tabEvent]: `/**
* js脚本
*
*/
function jsAction(activeKey, state) {
}`,
};
jsActionMap[ButtonPosition.formDialogItemEvent] =
  jsActionMap[ButtonPosition.formItemEvent];
jsActionMap[ButtonPosition.formDialog] = jsActionMap[ButtonPosition.form];
jsActionMap[ButtonPosition.cnArraySubAreaCardItemEvent] =
  jsActionMap[ButtonPosition.cnArrayTableItemEvent];
jsActionMap[ButtonPosition.formEvent] = jsActionMap[ButtonPosition.form];

const ALL_BUTTON_POSITION_LIST = Object.values(ButtonPosition);

const componentLoopMap = {};

const jsAction = {
  title: 'js脚本',
  value: 'jsAction',
  position: ALL_BUTTON_POSITION_LIST,
  // getPrototypeList: (position) => {
  //   if([ButtonPosition.filterItemEvent,ButtonPosition.formItemEvent,ButtonPosition.formDialogItemEvent].includes(position)) {
  //     return [
  //       {
  //         title: '自定义脚本',
  //         name: 'jsFunction',
  //         setter: <ActionSetter
  //           defaultCode={`/**
  // * cn-table responseTransform
  // * @param res any 返回数据
  // */
  // function onChange(res) {
  //   return {
  //     tableColumns: {},
  //     tableData: [],
  //     paging: {},
  //   }
  // }`}
  //           defaultActionName="onChange"
  //         />
  //       }
  //     ]
  //   }
  // },
  getPrototypeList: (position, config) => {
    const { __field } = config || {};
    if (
      [
        ButtonPosition.filterItemEvent,
        ButtonPosition.formItemEvent,
        ButtonPosition.formDialogItemEvent,
        ButtonPosition.cnArrayTableItemEvent,
      ].includes(position)
    ) {
      return [
        {
          title: '自定义脚本',
          name: 'jsFunction',
          // isRequired: true,
          // editable:true,
          display: 'inline',
          // condition(){
          //   return true;
          // },
          className: 'cn-action-setter',
          // setter: <ActionSetter
          //   supportTypes={['page']}
          //   defaultCode={defaultCode}
          //   defaultActionName={defaultActionName}
          // />,
          setter: {
            componentName: (
              <ActionSetter
              // supportTypes={['page']}
              // defaultCode={defaultCode}
              // defaultActionName={defaultActionName}
              />
            ),
            props: () => {
              let defaultCode = jsActionMap[position];
              let defaultActionName = 'onFieldValueChange';
              if (__field?.getValue?.()?.name === 'onFieldReact') {
                if (ButtonPosition.cnArrayTableItemEvent === position) {
                  defaultCode = `/**
* onFieldReact
* 用法请参考formily官方示例
* https://formilyjs.org/zh-CN/guide/advanced/linkages#%E8%A2%AB%E5%8A%A8%E6%A8%A1%E5%BC%8F
*
* @param field 当前字段
* @param form 当前表单实例
*/
function onFieldReact(field, form) {
  // 当前字段的值
  // const value = field.value;
  // 当前行的index
  // const index = field?.path?.segments?.[1];
  // 查询当前行其他字段的值，xxx代表可编辑表格的字段编码，yyy代表表格某列的字段编码
  // const otherFieldValue = field.query(\`xxx.$\{index}.yyy\`).value()
  // 查询表单其他字段的值
  // const otherFieldValue2 = field.query('xxx').value()

  // 示例：当前字段的值等于 自身的值 + 当前行其他字段的值。
  // field.value = value + otherFieldValue
}`;
                } else {
                  defaultCode = `/**
* onFieldReact
* 用法请参考formily官方示例
* https://formilyjs.org/zh-CN/guide/advanced/linkages#%E8%A2%AB%E5%8A%A8%E6%A8%A1%E5%BC%8F
*
* @param field 当前字段
* @param form 当前表单实例
*/
function onFieldReact(field, form) {
  // 查询其他字段的值
  // const otherFieldValue = field.query('xxx').value()
  // 查询其他字段的值
  // const otherFieldValue2 = field.query('xxx2').value()
  // 示例：当前字段的值等于otherFieldValue乘otherFieldValue2。
  // field.value = otherFieldValue * otherFieldValue2
}`;
                }
                defaultActionName = 'onFieldReact';
              }
              return {
                supportTypes: ['page'],
                defaultCode,
                defaultActionName,
              };
            },
          },
        },
      ];
    } else {
      return [
        {
          title: '自定义脚本',
          name: 'jsFunction',
          // isRequired: true,
          // editable:true,
          display: 'inline',
          // condition(){
          //   return true;
          // },
          className: 'cn-action-setter',
          // setter: <ActionSetter
          //   supportTypes={['page']}
          //   defaultCode={defaultCode}
          //   defaultActionName={defaultActionName}
          // />,
          setter: {
            componentName: (
              <ActionSetter
              // supportTypes={['page']}
              // defaultCode={defaultCode}
              // defaultActionName={defaultActionName}
              />
            ),
            props: () => {
              const defaultCode = jsActionMap[position];
              const defaultActionName = 'jsAction';
              return {
                supportTypes: ['page'],
                defaultCode,
                defaultActionName,
              };
            },
          },
        },
      ];
    }
  },
  action: (config) => {
    const {
      buttonConfig,
      _context,
      position,
      extraParams = {},
      formInstance,
      field,
      recordDataSource,
    } = config;
    const { name, options } = buttonConfig;
    const { jsFunction } = options || {};
    if (typeof jsFunction === 'function') {
      if (
        [
          ButtonPosition.filterItemEvent,
          ButtonPosition.formItemEvent,
          ButtonPosition.formDialogItemEvent,
        ].includes(position)
      ) {
        if (name === 'onChange') {
          const { formValue, fieldName } = extraParams;
          const value = '';
          return jsFunction(value, fieldName, formValue, _context);
        } else {
          return jsFunction(field, getRealizeValue(formInstance));
        }
      } else if (
        [
          ButtonPosition.form,
          ButtonPosition.formDialog,
          ButtonPosition.formEvent,
        ].includes(position)
      ) {
        const form = getRealizeValue(formInstance);
        const state = _context?.state;
        async function executeJsFunction() {
          await jsFunction({ state, form });
        }
        return executeJsFunction();
      } else if ([ButtonPosition.tabEvent].includes(position)) {
        const state = _context?.state;
        async function executeJsFunction() {
          await jsFunction(recordDataSource, state);
        }
        return executeJsFunction();
      } 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;
      //   },
      //   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: '返回上一页',
                value: 'back',
              },
            ],
          },
        },
      },
      {
        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 = [],
      getExtraParam,
      arrayTableCurrentRow,
      arrayBaseFieldIndex,
      parentPosition,
    } = config;
    const needDelay =
      position === ButtonPosition.formDialogSubmitAfterRequestSuccess ||
      position === ButtonPosition.formSubmitAfterRequestSuccess;
    const { options } = buttonConfig || {};
    let extraParamList = [];
    let recordDataSource = getRealizeValue(originalRecordDataSource);
    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?.(formItemConfig?.name)?.value?.();
          if (Array.isArray(list) && list[field?.index]) {
            recordDataSource = list[field.index];
            extraParamList = [field.index];
          }
        }
      }
    } else if (position === ButtonPosition.arrayTableCell) {
      const { field } = extra || {};
      if (field) {
        const index = +field?.path?.segments?.[1];
        if (typeof index === 'number' && !isNaN(index)) {
          recordDataSource = field.query('..').value()?.[index];
          extraParamList = [index];
        }
      }
    } else {
      extraParamList.push(selectedRowKeys);
      extraParamList.push(selectedRowRecords);
    }
    if (
      position === ButtonPosition.subCardAction &&
      parentPosition === DisplayPosition.cnArraySubAreaCard
    ) {
      extraParamList = [
        {
          [__arrayTableCurrentRow__]: arrayTableCurrentRow,
        },
      ];
    }
    if (options) {
      const { url, redirectType, urlParams = [] } = options;
      let search = '';
      if (redirectType === 'back') {
        window?.history?.back?.();
      } else {
        if (urlParams && urlParams.length > 0) {
          const temp = handleRequestParams(urlParams, {
            urlParamsDataSource,
            recordDataSource,
            state,
            extraParamList,
            getExtraParam,
          });
          search = qs.stringify(temp);
        }
        if (url) {
          let realUrl = calculateTextExprValue(url, {
            urlParamsDataSource,
            recordDataSource,
            state,
            extraParamList,
            getExtraParam,
          });
          if (typeof realUrl === 'string' && realUrl.length > 0) {
            if (realUrl.indexOf('?') !== -1) {
              if (search) {
                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],
                    reload: true,
                  });
                } 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 <span {...events}>{children}</span>;
  //   }
  //   return null;
  // },
};


const pollingAction = {
  title: '轮询操作',
  value: 'pollingAction',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: (position, config) => {
    return [
      {
        name: 'pollingItem',
        display: 'inline',
        title: '轮询项配置',
        tip: '以配置的项为基础单位都会不停轮询',
        setter: createPollingListSetters({
          position,
          activeSetter: {
            componentName: 'MixedSetter',
            props: {
              setters: [
                {
                  componentName: <CheckboxSetter />,
                  title: '启用/禁用',
                },
                {
                  componentName: (
                    <ExprSetter/>
                  ),
                  props(field) {
                    const [flowList, index] = getPollingFlowList(field);
                    // 是否开启的地方
                    return {
                      configList: [
                        {
                          groupName: '动作编排的数据',
                          groupExprName: __flowData__,
                          needSecondParam: true,
                          flowList,
                          currentFlowIndex: index,
                        },
                        {
                          groupName: '其他数据',
                          groupExprName: __dataSource__,
                          needSecondParam: true,
                        },
                      ],
                    };
                  },
                  title: '简单表达式',
                },
                {
                  title: '写js表达式',
                  componentName: 'CnRowDataSetter',
                  props(field) {
                    const [flowList, index] = getPollingFlowList(field);
                    // 是否开启的js 地方
                    const stateList = getDataSourceListWithAllPath({
                      needChildren: true,
                      prototypeConfig: {
                        flowList,
                        currentFlowIndex: index,
                      },
                    });
                    return {
                      list: stateList,
                      initialCode: `(arg, state) => {
                        // return state.urlParams.xxx;
                      }`,
                      tip: `
                        state：全部的数据，在左侧列表中选择使用。
                      `,
                    };
                  },
                },
              ],
            },
          },
          excludeButtonList: ['pollingAction', 'submit']
        })
      },
      {
        name: 'checkIsEnd',
        display: 'block',
        title: '判断是否结束(根据接口返回数据)',
        setter: getJSExpressionPrototype({ type: 'pollService' }),
      },
      {
        name: 'interval',
        display: 'block',
        title: '间隔时间（秒）',
        setter: 'NumberSetter',
      }
    ]
  },
  action: async (config, ...otherArgs) => {
    const { buttonConfig, position, _context, getFlowActionInfo } = config || {};
    const { options, optType: fromOptType } = buttonConfig || {};
    const { pollingItem, checkIsEnd, interval } = options;
    async function executeFlowListInPolling(list) {
      let isStop = false;
      const result = [];
      while(!isStop) {
        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) {
            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: 'pollingAction',
                  getFlowActionInfo: () => {
                    return {
                      pollingItem,
                      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.polling = {
              //   ...(_context.state.valueOf.polling ?? {}),
              //   [optType + realIndex]: flowResult,
              // }

              const parentIndex = fromOptType === "pollingAction" ? getFlowActionInfo()?.currentFlowIndex : '';

              _context.state.valueOf[ `polling${parentIndex}_${optType}${realIndex}`] = flowResult;
            }
            !isUndefined(flowResult) && result.push(flowResult);
            if(!isStop) {
              isStop = executeFunction(checkIsEnd, flowResult, _context?.state );
            }
          }
        }
        if(!isStop) {
          await waitAsync(interval ? interval * 1000 :2000);
        }
      }
      return result[result.length - 1];
    }
    if (Array.isArray(pollingItem) && pollingItem.length > 0) {
      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;
              }
            }
          });
        }
      }
      return await executeFlowListInPolling(pollingItem);
    }
  }
}

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,
      parentComponentName,
    } = config;
    const { options = {} } = buttonConfig;
    const { keepPagination } = options;

    if (isRecursionComponent(parentComponentName)) {
      recordDataSource = getArrayTableCurrentRowByField2(field) || {};
      const segments = field?.path?.segments || [];
      extraParamList = segments[segments?.length - 2];
    }
    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 <span {...events}>{children}</span>;
  //   }
  //   return null;
  // },
};

const batch = {
  title: '批量操作',
  value: 'batch',
  position: [ButtonPosition.tableBatchArea],
  getPrototypeList: (position) => {
    let paramSetter = 'StringSetter';
    let paramSelectSetter;
    let jsExpressionSetter;
    const setterSnippet = getSetterSnippet({
      position,
      optType: 'batch',
    });
    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',
        );
      }
    }

    return [
      ...createServiceSelectPrototype({
        optType: 'batch',
        paramSetter,
        position,
        paramSelectSetter,
        jsExpressionSetter,
      }),
      createRequestSuccessPrototype(
        ButtonPosition.tableBatchAreaAfterRequestSuccess,
      ),
    ];
  },
  action: ({
    buttonConfig,
    selectedRowKeys,
    selectedRowRecords,
    tableRef,
    urlParamsDataSource,
    recordDataSource,
    state,
    position,
  }) => {
    if (selectedRowKeys?.length > 0) {
      return makeRequest({
        position,
        buttonConfig,
        urlParamsDataSource,
        recordDataSource,
        state,
        extraParamList: [selectedRowKeys, selectedRowRecords],
        handleParams: (params) => {
          return {
            selectedRowKeys,
            selectedRowRecords,
          };
        },
      }).then((res) => {
        tableRef?.load?.();
      });
    } else {
      CnMessage.error(
        $i18n.get({ id: 'PleaseSelectTableData', dm: '请选择表格数据' }),
      );
      return Promise.reject();
    }
  },
};
const submit = {
  title: '提交（先校验表单，再发请求）',
  value: 'submit',
  position: [
    ButtonPosition.formDialog,
    ButtonPosition.form,
    ButtonPosition.cardAction,
  ],
  getPrototypeList: (position, config) => {
    let afterRequestPosition;
    let dynamicUrlTemplate;
    if (ButtonPosition.formDialog === position) {
      afterRequestPosition = ButtonPosition.formDialogSubmitAfterRequestSuccess;
      dynamicUrlTemplate = `function(state, { openDialogMode }) {
  // openDialogMode: ${openDialogModeLabel}: 新增(new)、编辑(edit)、详情(detail)
  return '/xxx';
}`;
    } else if (ButtonPosition.form === position) {
      afterRequestPosition = ButtonPosition.formSubmitAfterRequestSuccess;
    }

    let paramSetter = 'StringSetter';
    let paramSelectSetter;
    let jsExpressionSetter;
    const setterSnippet = getSetterSnippet({
      position,
      optType: 'submit',
      ...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',
        );
      }
    }
    let afterRequestPrototype;
    if (afterRequestPosition) {
      afterRequestPrototype =
        createRequestSuccessPrototype(afterRequestPosition);
    }
    const result = [
      ...createServiceSelectPrototype({
        optType: 'submit',
        paramSetter,
        position,
        paramSelectSetter,
        jsExpressionSetter,
        paramTitleDom: (
          <div>
            请求参数配置{' '}
            <span
              style={{ fontWeight: 'bold', color: 'red', marginLeft: '30px' }}
            >
              提示：提交时会默认带上当前表单的全部数据作为参数，无需手动配置
            </span>
          </div>
        ),
        dynamicUrlTemplate,
      }),
    ];
    if (afterRequestPrototype) {
      result.push(afterRequestPrototype);
    }
    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,
      getFormInstance,
    } = config;
    let realFormInstance = getRealizeValue(formInstance);
    if (typeof getFormInstance === 'function') {
      realFormInstance = getRealizeValue(executeFunction(getFormInstance));
    }
    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;
              }
              if ([ButtonPosition.cardAction].includes(position)) {
                needSuccessToast = true;
              }
              return makeRequest({
                buttonConfig,
                urlParamsDataSource,
                recordDataSource: value,
                state,
                needSuccessToast,
                getExtraParam,
                handleParams: () => {
                  return value;
                },
                onCancel: () => {
                  if (realFormInstance?.setSubmitting) {
                    realFormInstance.setSubmitting(false);
                  }
                },
                extraParamList: [
                  dialogRef?.selectedRowKeys,
                  dialogRef?.selectedRowRecords,
                ],
              })
                .then((res) => {
                  const { optType } = afterRequest || {};
                  if (optType && afterRequestPosition) {
                    const action = getButtonAction({
                      ...afterRequest,
                      position: afterRequestPosition,
                    });
                    action?.({
                      position: afterRequestPosition,
                      urlParamsDataSource,
                      recordDataSource: getRealizeValue(recordDataSource),
                      state,
                      buttonConfig: afterRequest,
                      _context,
                      response: res,
                      formInstance: realFormInstance,
                    });
                  }
                  if (afterRequestNotCloseDialog !== true) {
                    close && close();
                  }
                  return res;
                })
                .finally((res) => {
                  if (realFormInstance?.setSubmitting) {
                    realFormInstance.setSubmitting(false);
                  }
                });
            }
          });
        } else {
          return realFormInstance?.validate?.();
        }
      }
    }
  },
  // getButtonNode: (arg) => {
  //   const { buttonConfig } = 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 <Button type={'primary'} {...events}>{children}</Button>;
  //   }
  //   return null;
  // },
};

const cancel = {
  title: '取消（关闭当前弹窗）',
  value: 'cancel',
  position: [
    ButtonPosition.dialog,
    ButtonPosition.formDialog,
    ButtonPosition.form,
    ButtonPosition.blockButton,
  ],
  action: ({ buttonConfig, formData, open, close }) => {
    if (buttonConfig) {
      close && close();
    }
  },
  // getButtonNode: (arg) => {
  //   const { buttonConfig } = 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 <Button {...events}>{children}</Button>;
  //   }
  //   return null;
  // },
};

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('*');
    }
  },
  // getButtonNode: (arg) => {
  //   const { buttonConfig } = 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 <Button {...events}>{children}</Button>;
  //   }
  //   return null;
  // },
};

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,
      formProps,
    } = config || {};
    const { _dataSourceName } = formProps || {};
    let recordDataSource = record;
    if (position === ButtonPosition.arraySubAreaCardOperate) {
      recordDataSource = arrayTableCurrentRow;
    } else if (!record && extra?.field) {
      const { field } = extra;
      const { formItemConfig } = arrayTableConfig || {};
      if (position === ButtonPosition.arrayTableCell) {
        const tempCurrentRow = getArrayTableCurrentRowByField2(field);
        const fieldName = field?.path?.segments?.[0];
        if (fieldName && isPlainObject(tempCurrentRow)) {
          recordDataSource = cloneDeep(tempCurrentRow);
          set(
            _context?.state,
            `valueOf.${_dataSourceName}.${fieldName}.${__arrayTableCurrentRow__}`,
            { ...recordDataSource },
          );
        }
      } else 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 data;
        // if (ButtonPosition.tableOperate === position && dialogNode && _context && record) {
        //   data = record;
        //   const { props = {} } = dialogNode;
        //   const { _dataSourceName } = props;
        //   if (_dataSourceName) {
        //     _context?.setState({
        //       [_dataSourceName]: record,
        //     });
        //   }
        // }
        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;
  },
  // getButtonNode: (arg) => {
  //   const { buttonConfig } = arg;
  //   const { optType, options = {}, children } = buttonConfig;
  //   if (children) {
  //     const events = {};
  //     if (optType) {
  //       // const button = componentMap[optType];
  //       // if(typeof button?.action === 'function'){
  //       //   events = {
  //       //     onClick: button.action.bind(this, arg),
  //       //   }
  //       // }
  //     }
  //     return <span {...events}>{children}</span>;
  //   }
  //   return null;
  // },
};

const ossImport = {
  title: '导入',
  value: 'ossImport',
  position: [ButtonPosition.tableToolArea],
  action: ({ buttonConfig, _context }) => {},
  getPrototypeList: () => {
    return [
      {
        name: 'uploadService',
        title: '文件上传API',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramTitleDom: (
              <div className=''>
                请求参数配置：
                <a
                  target={'_blank'}
                  href='https://yuque.antfin.com/docs/share/ae7a75a0-f1b1-48f4-82ac-8ea75e78f7f5?'
                  rel='noreferrer'
                >
                  接口文档
                </a>
              </div>
            ),
            paramSetter: [
              getParamSetterPrototype({
                type: 'filter',
              }),
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              getJSExpressionPrototype({ type: 'formRequest' }),
            ],
          },
        },
      },
      {
        name: 'createService',
        title: '创建任务API',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramTitleDom: (
              <div>
                请求参数配置：
                <a
                  target={'_blank'}
                  href='https://yuque.antfin.com/docs/share/fdc3c9de-a262-42a9-ba8a-423cd2d7b6ca?'
                  rel='noreferrer'
                >
                  接口文档
                </a>
              </div>
            ),
            resultProcessFuncTemplate: `function(res) {
  // 需要返回的如下的数据结构
  // return {
  //   success: true,
  //   data: {
  //     jobId: number
  //   }
  // }
 return res;
}`,
            paramSetter: [
              getParamSetterPrototype({
                type: 'filter',
              }),
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              getJSExpressionPrototype({ type: 'formRequest' }),
            ],
          },
        },
      },
      {
        name: 'pollingService',
        title: '任务轮询API',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramTitleDom: (
              <div>
                请求参数配置：
                <a
                  target={'_blank'}
                  href='https://yuque.antfin.com/docs/share/fdc3c9de-a262-42a9-ba8a-423cd2d7b6ca?'
                  rel='noreferrer'
                >
                  接口文档
                </a>
              </div>
            ),
            paramSetter: [
              getParamSetterPrototype({
                type: 'filter',
              }),
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              getJSExpressionPrototype({ type: 'formRequest' }),
            ],
          },
        },
      },
      {
        name: 'templateUrl',
        title: '导入模板文件的链接',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                title: '配置文件链接',
                componentName: 'StringSetter',
                props: {
                  placeholder: '请填写导入模板文件的url',
                },
              },
              {
                title: '配置请求获取文件链接',
                componentName: 'ServiceChoiceSetter',
                props: {
                  buttonText: '选择请求API',
                  params: {
                    env: 'pre',
                    pageSize: 999,
                    // serviceType: 'HSF',
                  },
                  paramSetter: [
                    {
                      componentName: 'ParamSelectSetter',
                      props: {
                        dataKey: 'config',
                        labelKey: 'label',
                        valueKey: 'name',
                        groupName: '筛选栏',
                        relativeDataSourceName: '_bindFilterDataSourceName',
                        relativeDataSourceNameKey: '_dataSourceName',
                      },
                      title: '选择参数',
                    },
                    {
                      componentName: 'StringSetter',
                      title: '字符串',
                    },
                    getJSExpressionPrototype({ type: 'formRequest' }),
                  ],
                },
              },
            ],
          },
        },
      },
      {
        name: 'hideLoop',
        title: '关闭任务轮询',
        display: 'inline',
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              { title: '是', value: true },
              { title: '否', value: false },
              { title: '不设置' },
            ],
          },
        },
      },
      {
        name: 'dialogDescription',
        title: '提示信息',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                title: '文本',
                componentName: 'CnI18nSetter',
              },
              getJSXTemplate({
                position: ButtonPosition.tableToolArea,
              }),
            ],
          },
        },
      },
    ];
  },
};

const download = {
  title: '下载',
  value: 'download',
  position: [
    ButtonPosition.tableBatchArea,
    ButtonPosition.subCardAction,
    ButtonPosition.cardAction,
  ],
  getRenderDom: (config) => {
    const {
      buttonConfig,
      recordDataSource,
      state,
      urlParamsDataSource,
      btnProps,
    } = config || {};
    const { children, options, iconType } = buttonConfig || {};
    const { url } = options || {};
    const formValue = getRealizeValue(recordDataSource) || {};
    let downloadProps;
    if (typeof url === 'function') {
      downloadProps = {
        url: executeFunction(url, formValue, state),
      };
    } else {
      downloadProps = getDownloadProps({
        url,
        extraParams: {
          state,
          recordDataSource: getRealizeValue(recordDataSource) || {},
          urlParamsDataSource,
        },
      });
    }
    let realChildren = children;
    if (iconType) {
      realChildren = (
        <>
          {renderIcon(iconType)}
          {children}
        </>
      );
    }
    return (
      <CnDownload
        buttonText={realChildren}
        buttonProps={{
          size: 'small',
          ...btnProps,
        }}
        {...downloadProps}
      />
    );
  },
  getPrototypeList: (position, config) => {
    const setterSnippet = getSetterSnippet({
      position,
      optType: 'download',
    });
    const { requestParamSetter } = setterSnippet || {};
    return [
      {
        name: 'url',
        title: '文件下载链接',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'StringSetter',
                title: '纯文本',
              },
              {
                title: '配置请求获取文件链接',
                componentName: 'ServiceChoiceSetter',
                props: {
                  buttonText: '选择请求API',
                  params: {
                    env: 'pre',
                    pageSize: 999,
                    // serviceType: 'HSF',
                  },
                  paramSetter: requestParamSetter?.props?.setters || [],
                },
              },
              getJSExpressionPrototype({
                type: 'formRequest',
              }),
            ],
          },
        },
      },
    ];
  },
};

const exportButton = {
  title: '导出',
  value: 'export',
  position: [
    ButtonPosition.tableToolArea,
    ButtonPosition.tableBatchArea,
    window?.__page__?.siteName || window?.siteInfo?.appName === 'Apollo2.0'
      ? ButtonPosition.tableOperate
      : null,
  ],
  action: ({ buttonConfig, _context }) => {},
  getPrototypeList: (position) => {
    let paramSetter = 'StringSetter';
    const setterSnippet = getSetterSnippet({
      position,
      optType: 'export',
    });
    const { requestParamSetter } = setterSnippet || {};
    if (requestParamSetter) {
      paramSetter = requestParamSetter;
    }

    return [
      {
        name: 'createService',
        title: '创建任务API',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramTitleDom: (
              <div>
                请求参数配置：
                <a
                  target={'_blank'}
                  href='https://yuque.antfin.com/docs/share/cff5b56e-8e92-4d8e-a036-f923fafcbd20?'
                  rel='noreferrer'
                >
                  接口文档
                </a>
                <span
                  style={{
                    fontWeight: 'bold',
                    color: 'red',
                    marginLeft: '10px',
                  }}
                >
                  提示：导出时会默认带上筛选栏的数据作为参数，无需手动配置
                </span>
              </div>
            ),
            resultProcessFuncTemplate: `function(res) {
  // 需要返回的如下的数据结构
  // return {
  //   success: true,
  //   data: {
  //     jobId: number
  //   }
  // }
 return res;
}`,
            paramSetter: [
              getParamSetterPrototype({
                type: 'filter',
              }),
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              getJSExpressionPrototype({ type: 'formRequest' }),
            ],
            paramSetter,
          },
        },
      },
      {
        name: 'pollingService',
        title: '任务轮询API',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramTitleDom: (
              <div>
                请求参数配置：
                <a
                  target={'_blank'}
                  href='https://yuque.antfin.com/docs/share/fdc3c9de-a262-42a9-ba8a-423cd2d7b6ca?'
                  rel='noreferrer'
                >
                  接口文档
                </a>
              </div>
            ),
            paramSetter,
          },
        },
      },
      {
        name: 'hideLoop',
        title: '关闭任务轮询',
        display: 'inline',
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              { title: '是', value: true },
              { title: '否', value: false },
              { title: '不设置' },
            ],
          },
        },
      },
      {
        name: 'needRename',
        title: '自定义导出任务的名称',
        display: 'inline',
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              { title: '是', value: true },
              { title: '否', value: false },
              { title: '不设置' },
            ],
          },
        },
      },
      {
        name: 'defaultJobName',
        title: '设置导出任务的默认名称',
        display: 'inline',
        setter: 'StringSetter',
        condition(prop) {
          return prop?.parent?.getPropValue?.('needRename') === true;
        },
      },
      {
        name: 'autoDownload',
        title: '导出完成后自动下载',
        display: 'inline',
        defaultValue: true,
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              { title: '是', value: true },
              { title: '否', value: false },
            ],
          },
        },
      },
    ];
  },
};

const tableReload = {
  title: '表格重新请求',
  value: 'tableReload',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return [
      ...createTableSelectSetters(),
      {
        name: 'keepPagination',
        title: '表格重新请求时保留分页信息',
        setter: 'BoolSetter',
      },
      {
        name: 'refreshExceptPaging',
        title: '表格重新请求时清除勾选数据',
        setter: 'BoolSetter',
        condition(prop) {
          return prop?.parent?.getValue?.()?.keepPagination === true;
        },
      },
    ];
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindTable, keepPagination, refreshExceptPaging } = options;
    function reloadOneTable(id) {
      if (typeof id === 'string') {
        const table = _context.$(id);
        if (keepPagination === true && refreshExceptPaging === true) {
          table?.refreshExceptPaging()?.();
        } else if (keepPagination === true) {
          table?.tableLoad()?.();
        } else {
          table?.load?.();
        }
      }
    }

    if (_bindTable && _context) {
      if (Array.isArray(_bindTable)) {
        _bindTable.forEach((item) => {
          reloadOneTable(item);
        });
      } else {
        reloadOneTable(_bindTable);
      }
    }
  },
};

const arrayTableRemove = {
  title: '删除',
  value: 'arrayTableRemove',
  position: [ButtonPosition.arrayTableOperate],
  action: (config) => {
    const { field } = config || {};
    if (typeof field?.parent?.remove === 'function') {
      const segments = field?.path?.segments;
      let currentIndex = +segments?.[1];
      if (typeof currentIndex !== 'number') {
        currentIndex = segments?.[segments?.length - 2];
      }
      if (typeof currentIndex === 'number') {
        field?.parent?.remove(currentIndex);
      }
    }
  },
};

const arrayTableMoveUp = {
  title: '上移',
  value: 'arrayTableMoveUp',
  position: [ButtonPosition.arrayTableOperate],
};

const arrayTableMoveDown = {
  title: '下移',
  value: 'arrayTableMoveDown',
  position: [ButtonPosition.arrayTableOperate],
};

const arrayTableAdd = {
  title: '添加一行',
  value: 'arrayTableAdd',
  position: [ButtonPosition.arrayTableOperate],
  getPrototypeList: (position) => {
    return [
      {
        name: 'defaultValue',
        title: '添加一行时的默认值',
        display: 'block',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'ArraySetter',
                props: {
                  mode: 'list',
                  itemSetter: {
                    componentName: 'ObjectSetter',
                    props: {
                      config: {
                        items: [
                          {
                            name: 'label',
                            display: 'inline',
                            title: '字段名',
                            isRequired: true,
                            setter: {
                              componentName: 'SelectSetter',
                              props: (field) => {
                                const options = [];
                                const arrayTableConfig =
                                  field?.parent?.parent?.parent?.parent?.parent?.parent?.getPropValue?.(
                                    'config',
                                  );
                                if (
                                  Array.isArray(arrayTableConfig) &&
                                  arrayTableConfig.length > 0
                                ) {
                                  arrayTableConfig.forEach((item) => {
                                    const { label, name } = item || {};
                                    if (name !== '_index' && name) {
                                      options.push({
                                        label: handleI18nLabel(label) || name,
                                        value: name,
                                      });
                                    }
                                  });
                                }
                                return {
                                  showSearch: true,
                                  options,
                                };
                              },
                            },
                          },
                          {
                            name: 'value',
                            display: 'inline',
                            title: '默认值',
                            isRequired: true,
                            initialValue: 'value',
                            setter: {
                              componentName: 'MixedSetter',
                              props: {
                                setters: [
                                  {
                                    componentName: 'StringSetter',
                                    title: '字符串',
                                  },
                                  {
                                    componentName: 'NumberSetter',
                                    title: '数字',
                                  },
                                  {
                                    componentName: 'BoolSetter',
                                    title: '布尔（true/false）',
                                  },
                                  getJSExpressionPrototype({
                                    type: 'formRequest',
                                  }),
                                ],
                              },
                            },
                          },
                        ],
                      },
                    },
                  },
                },
              },
              getJSExpressionPrototype({
                type: 'base',
              }),
            ],
          },
        },
      },
    ];
  },
  action: ({ buttonConfig, formData, open, close }) => {
    if (buttonConfig) {
    }
  },
};

const arraySubAreaCardAdd = {
  title: '添加',
  value: 'arraySubAreaCardAdd',
  position: [ButtonPosition.arraySubAreaCardOperate],
  getPrototypeList: (position) => {
    return [
      // {
      //   name: 'defaultValue',
      //   title:'添加一行时的默认值',
      //   display:'block',
      //   setter:{
      //     componentName: 'ArraySetter',
      //     props: {
      //       mode: 'list',
      //       itemSetter: {
      //         componentName: 'ObjectSetter',
      //         props: {
      //           config: {
      //             items: [
      //               {
      //                 name: 'label',
      //                 display: 'inline',
      //                 title: '字段名',
      //                 isRequired: true,
      //                 setter:{
      //                   componentName: 'SelectSetter',
      //                   props: (field)=>{
      //                     const options = [];
      //                     const arrayTableConfig = field?.parent?.parent?.parent?.parent?.parent?.parent?.getPropValue?.('config');
      //                     if(Array.isArray(arrayTableConfig) && arrayTableConfig.length > 0) {
      //                       arrayTableConfig.forEach(item=>{
      //                         const { label, name } = item || {};
      //                         if(name !== '_index' && name) {
      //                           options.push({
      //                             label: handleI18nLabel(label) || name,
      //                             value: name,
      //                           })
      //                         }
      //                       })
      //                     }
      //                     return {
      //                       showSearch: true,
      //                       options,
      //                     }
      //                   }
      //                 }
      //               },
      //               {
      //                 name: 'value',
      //                 display: 'inline',
      //                 title: '默认值',
      //                 isRequired: true,
      //                 initialValue: 'value',
      //                 setter: {
      //                   componentName: 'MixedSetter',
      //                   props: {
      //                     setters: [
      //                       {
      //                         componentName:'StringSetter',
      //                         title:'字符串',
      //                       },
      //                       {
      //                         componentName:'NumberSetter',
      //                         title:'数字',
      //                       },
      //                       {
      //                         componentName:'BoolSetter',
      //                         title:'布尔（true/false）',
      //                       },
      //                     ],
      //                   },
      //                 }
      //               },
      //             ],
      //           },
      //         },
      //       },
      //     },
      //   },
      // },
    ];
  },
  action: ({ buttonConfig, formData, open, close }) => {
    if (buttonConfig) {
    }
  },
};

const arraySubAreaCardRemove = {
  title: '删除',
  value: 'arraySubAreaCardRemove',
  position: [ButtonPosition.arraySubAreaCardOperate],
  action: (config) => {
    const { arrayBaseField, arrayBaseFieldIndex } = config || {};
    if (
      typeof arrayBaseField?.remove === 'function' &&
      typeof arrayBaseFieldIndex === 'number'
    ) {
      arrayBaseField.remove(arrayBaseFieldIndex);
    }
  },
};

const arraySubAreaCardMoveUp = {
  title: '上移',
  value: 'arraySubAreaCardMoveUp',
  position: [ButtonPosition.arraySubAreaCardOperate],
  action:(config)=>{
    const { arrayBaseField, arrayBaseFieldIndex } = config || {}
    if(arrayBaseField) {
      if(arrayBaseField?.disabled === true || arrayBaseField?.pattern !== 'editable') {
        return
      }
      arrayBaseField?.moveUp(arrayBaseFieldIndex);
    }
  }
};

const arraySubAreaCardMoveDown = {
  title: '下移',
  value: 'arraySubAreaCardMoveDown',
  position: [ButtonPosition.arraySubAreaCardOperate],
  action:(config)=>{
    const { arrayBaseField, arrayBaseFieldIndex } = config || {}
    if(arrayBaseField) {
      if(arrayBaseField?.disabled === true || arrayBaseField?.pattern !== 'editable') {
        return
      }
      arrayBaseField?.moveDown(arrayBaseFieldIndex);
    }
  }
};

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);
          let path = 'request';
          const lastRequestIndex = findLastIndex(
            beforeList,
            (item) => {
              if(item?.optType === 'request') {
                return true;
              }else if(item?.optType === 'submit') {
                path = 'submit'
                return true;
              }
              return false;
            },
          );
          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 confirm = {
  title: '带确认的提示信息（confirm）',
  value: 'confirm',
  position: [ButtonPosition.tableBatchAreaAfterRequestSuccess],
  getPrototypeList: (position) => {
    return createMessageSetters({ isConfirm: true });
  },
  action: (config) => {
    const {
      response = {},
      buttonConfig,
      urlParamsDataSource,
      state,
      _context,
    } = config || {};
    const msg = response?.msg;
    const { options = {} } = buttonConfig || {};
    const { type = 'success', title, content } = options;
    let realContent = content;
    if (typeof content === 'function') {
      realContent = content(response, state);
    }
    if (!realContent && !title) {
      realContent = msg;
    }
    CnDialog?.[type]?.({
      title,
      content: realContent,
    });
  },
};

const formReload = {
  title: '表单重新请求',
  value: 'formReload',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return createFormSelectSetters({
      mode: 'multiple',
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindForm } = options;
    function reloadOneForm(id) {
      if (typeof id === 'string') {
        const form = _context.$(id);
        form?.load?.();
      }
    }

    if (_bindForm && _context) {
      if (Array.isArray(_bindForm)) {
        _bindForm.forEach((item) => {
          reloadOneForm(item);
        });
      } else {
        reloadOneForm(_bindForm);
      }
    }
  },
};

const componentReload = {
  title: '组件重新请求',
  value: 'componentReload',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return createComponentSelectSetters({
      mode: 'multiple',
      containsKey: ['isCnList', 'isCnStep'],
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindComponent } = options;
    function reloadOneComponent(id) {
      if (typeof id === 'string') {
        const com = _context.$(id);
        com?.load?.();
      }
    }

    if (_bindComponent && _context) {
      if (Array.isArray(_bindComponent)) {
        _bindComponent.forEach((item) => {
          reloadOneComponent(item);
        });
      } else {
        reloadOneComponent(_bindComponent);
      }
    }
  },
};

const filterReset = {
  title: '筛选栏重置',
  value: 'filterReset',
  position: [
    ButtonPosition.tabEvent,
    ButtonPosition.dialog,
    ButtonPosition.blockButton,
  ],
  getPrototypeList: () => {
    return createFilterSelectSetters({
      mode: 'multiple',
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindFilter } = options;
    function reloadOneFilter(id) {
      if (typeof id === 'string') {
        const filter = _context.$(id);
        filter?.reset?.();
      }
    }

    if (_bindFilter && _context) {
      if (Array.isArray(_bindFilter)) {
        _bindFilter.forEach((item) => {
          reloadOneFilter(item);
        });
      } else {
        reloadOneFilter(_bindFilter);
      }
    }
  },
};

const filterSearch = {
  title: '筛选栏查询',
  value: 'filterSearch',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return createFilterSelectSetters({
      mode: 'multiple',
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindFilter } = options;
    function searchOneFilter(id) {
      if (typeof id === 'string') {
        const filter = _context.$(id);
        filter?.search?.();
      }
    }

    if (_bindFilter && _context) {
      if (Array.isArray(_bindFilter)) {
        _bindFilter.forEach((item) => {
          searchOneFilter(item);
        });
      } else {
        searchOneFilter(_bindFilter);
      }
    }
  },
};

const setFormData = {
  title: '将请求数据(res.data)填入表单',
  value: 'setFormData',
  position: [
    ButtonPosition.formDialogSubmitAfterRequestSuccess,
    ButtonPosition.formSubmitAfterRequestSuccess,
  ],
  action: (arg) => {
    const { formInstance, response } = arg || {};
    if (formInstance && response) {
      const { success, data } = response;
      if (success && isPlainObject(data)) {
        formInstance.setValues?.(data, 'overwrite');
      }
    }
  },
};

const locationReload = {
  title: '刷新页面(location.reload)',
  value: 'locationReload',
  position: ALL_BUTTON_POSITION_LIST,
  action: (arg) => {
    location?.reload?.();
  },
};

const textRender = {
  title: '展示文本',
  value: 'textRender',
  position: [
    ButtonPosition.tableToolArea,
    ButtonPosition.tableBatchArea,
    ButtonPosition.formDialog,
    ButtonPosition.dialog,
    ButtonPosition.form,
    ButtonPosition.step,
    ButtonPosition.pageRightButton,
    ButtonPosition.blockButton,
  ],
  getRenderDom: (config) => {
    if (config) {
      const {
        buttonConfig,
        state,
        position,
        selectedRowKeys,
        selectedRowRecords,
        recordDataSource,
      } = config;
      const { options, children } = buttonConfig || {};
      const { content, color } = options || {};
      let realContent = children;
      if (typeof content === 'string' && content.length > 0) {
        realContent = content;
      } else if (typeof content === 'function') {
        if (
          [
            ButtonPosition.tableBatchArea,
            ButtonPosition.tableToolArea,
          ].includes(position)
        ) {
          realContent = executeFunction(
            content,
            recordDataSource,
            state,
            selectedRowKeys,
            selectedRowRecords,
          );
        } else {
          const formValue = getRealizeValue(recordDataSource);
          realContent = executeFunction(content, formValue || {}, state);
        }
      }
      const style = {
        display: 'inline-block',
      };
      if (color) {
        style.color = color;
      }
      return (
        <CnButton style={style} text>
          {realContent}
        </CnButton>
      );
    }
  },
  getPrototypeList: (position) => {
    return [
      {
        name: 'content',
        title: '内容',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'CnI18nSetter',
                title: '字符串',
              },
              getJSXTemplate({
                position,
              }),
            ],
          },
        },
      },
      {
        name: 'color',
        title: '文本颜色',
        setter: {
          componentName: 'CnSelectSetter',
          props: {
            options: [
              {
                label: '绿色',
                value: '#1ad78c',
              },
              {
                label: '黄色',
                value: '#ff9f00',
              },
              {
                label: '红色',
                value: '#ff4b4b',
              },
              {
                label: '蓝色',
                value: '#4576f5',
              },
            ],
            selectProps: {
              hasClear: true,
            },
          },
        },
      },
    ];
  },
};

const tableLoop = {
  title: '表格轮询',
  value: 'tableLoop',
  position: [ButtonPosition.tableToolArea, ButtonPosition.tableBatchArea],
  getDefaultProps: () => {
    return {
      active: true,
      interval: 5,
    };
  },
  getRenderDom: (config) => {
    useEffect(() => {
      const { options, tableRef, isDesign, state } = config || {};
      const { active, interval, keepPagination, stopLoop } = options;
      const isActive = isFunction(active)
        ? executeFunction(active, {}, state)
        : active;

      let loopId;

      function doStopLoop() {
        const stop = calculateTextExprValue(stopLoop, {
          recordDataSource: {},
          state,
        });
        if (stop === true && loopId) {
          clearInterval(loopId);
        }
      }

      function loopOneTable() {
        loopId = setInterval(() => {
          if (keepPagination === true) {
            tableRef?.tableLoad()?.();
          } else {
            tableRef?.load?.();
          }
          tableRef
            ?.getRemoteOperation?.()
            ?.current?.innerInfo?.setLoading?.(false);
          doStopLoop();
        }, interval * 1000);
      }

      if (
        !isDesign &&
        isActive &&
        tableRef?.load &&
        typeof interval === 'number' &&
        interval >= 2
      ){
        loopOneTable();
      }
      return () => {
        if (loopId !== undefined) {
          clearInterval(loopId);
        }
      };
    }, []);

    return null;
  },
  getPrototypeList: (position) => {
    return [
      {
        name: 'active',
        title: '启用',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'BoolSetter',
                title: '开关启用',
              },
              getJSExpressionPrototype({ type: 'base' }),
            ],
          },
        },
      },
      {
        name: 'interval',
        title: '轮询间隔时间（单位秒）',
        display: 'inline',
        setter: 'NumberSetter',
      },
      {
        name: 'keepPagination',
        title: '表格重新请求时保留分页信息',
        setter: 'BoolSetter',
      },
      {
        name: 'stopLoop',
        title: '何时终止轮询',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              getJSExpressionPrototype({
                type: 'base',
              }),
            ],
          },
        },
      },
    ];
  },
};

const tableLoop2 = {
  title: '表格轮询',
  value: 'tableLoop2',
  position: [
    ButtonPosition.form,
    ButtonPosition.formDialog,
    ButtonPosition.tableOperate,
    ButtonPosition.pageDidMount,
  ],
  getDefaultProps: () => {
    return {
      active: true,
      interval: 5,
    };
  },
  getPrototypeList: (position) => {
    return [
      ...createTableSelectSetters(),
      {
        name: 'active',
        title: '启用',
        display: 'inline',
        setter: 'BoolSetter',
      },
      {
        name: 'interval',
        title: '轮询间隔时间（单位秒）',
        display: 'inline',
        setter: 'NumberSetter',
      },
      {
        name: 'stopLoop',
        title: '何时终止轮询',
        display: 'inline',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              getJSExpressionPrototype({
                type: 'base',
              }),
            ],
          },
        },
      },
    ];
  },
  action: (config) => {
    const { buttonConfig, _context, state, urlParamsDataSource } = config || {};
    const { options } = buttonConfig || {};
    const { _bindTable, active, interval, stopLoop } = options || {};

    function doStopLoop(id) {
      const stop = calculateTextExprValue(stopLoop, {
        urlParamsDataSource,
        recordDataSource: {},
        state,
      });
      const isLooping = componentLoopMap[id];
      if (stop === true && typeof isLooping === 'number') {
        clearInterval(isLooping);
        componentLoopMap[id] = undefined;
      }
    }

    function loopOneTable(id) {
      if (typeof id === 'string') {
        const table = _context.$(id);
        if (table) {
          const isLooping = componentLoopMap[id];
          if (
            isLooping === undefined &&
            active &&
            typeof interval === 'number'
          ) {
            componentLoopMap[id] = setInterval(() => {
              table.load?.();
              table
                ?.getRemoteOperation?.()
                ?.current?.innerInfo?.setLoading?.(false);
              doStopLoop(id);
            }, interval * 1000);
          }
        }
      }
    }

    if (isArrayNotEmpty(_bindTable) && _context) {
      _bindTable.forEach((item) => {
        loopOneTable(item);
      });
    }
  },
};

const setTableSelectRowKeys = {
  title: '设置表格选中项',
  value: 'setTableSelectRowKeys',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: (position, config) => {
    const { flowList, currentFlowIndex } = config || {};
    return [
      ...createTableSelectSetters(),
      {
        name: 'selectedRowKeys',
        display: 'inline',
        title: '设置选中项',
        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: '从数据源选择',
              },
              getJSExpressionPrototype({
                type: 'base',
                prototypeConfig: config,
              }),
            ],
          },
        },
      },
    ];
  },
  action: (config) => {
    const { buttonConfig, _context, state, urlParamsDataSource } = config || {};
    const { options } = buttonConfig || {};
    const { _bindTable, selectedRowKeys } = options || {};
    function selectOneTable(id, keys) {
      if (typeof id === 'string') {
        const table = _context.$(id);
        if (table) {
          const innerInfo = table.getRemoteOperation?.()?.current?.innerInfo;
          if (innerInfo) {
            innerInfo?.setSelectKeys(keys);
          }
        }
      }
    }

    if (isArrayNotEmpty(_bindTable) && _context && selectedRowKeys) {
      const realSelectedRowKeys = calculateTextExprValue(selectedRowKeys, {
        urlParamsDataSource,
        recordDataSource: {},
        state,
      });
      if (isArrayNotEmpty(realSelectedRowKeys)) {
        _bindTable.forEach((item) => {
          selectOneTable(item, realSelectedRowKeys);
        });
      }
    }
  },
};
const setTableOpenKeys = {
  title: '设置表格展开项',
  value: 'setTableOpenKeys',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: (position, config) => {
    const { flowList, currentFlowIndex } = config || {};
    return [
      ...createTableSelectSetters(),
      {
        name: 'openKeys',
        display: 'inline',
        title: '设置展开项',
        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: '从数据源选择',
              },
              getJSExpressionPrototype({
                type: 'base',
                prototypeConfig: config,
              }),
            ],
          },
        },
      },
    ];
  },
  action: (config) => {
    const { buttonConfig, _context, state, urlParamsDataSource } = config || {};
    const { options } = buttonConfig || {};
    const { _bindTable, openKeys } = options || {};
    function selectOneTable(id, keys) {
      if (typeof id === 'string') {
        const table = _context.$(id);
        if (table) {
          const innerInfo = table.getRemoteOperation?.()?.current?.innerInfo;
          if (innerInfo) {
            innerInfo?.setTreeKeys(keys);
          }
        }
      }
    }

    if (isArrayNotEmpty(_bindTable) && _context && openKeys) {
      const realOpenKeys = calculateTextExprValue(openKeys, {
        urlParamsDataSource,
        recordDataSource: {},
        state,
      });
      if (isArrayNotEmpty(realOpenKeys)) {
        _bindTable.forEach((item) => {
          selectOneTable(item, realOpenKeys);
        });
      }
    }
  },
};

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: <CheckboxSetter />,
                  title: '启用/禁用',
                },
                {
                  componentName: (
                    <ExprSetter
                    // configList={[
                    //   {
                    //     groupName:'其他数据',
                    //     groupExprName: __dataSource__,
                    //     needSecondParam:true,
                    //   }
                    // ]}
                    />
                  ),
                  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 setFormValue = {
  title: '给表单设置数据',
  value: 'setFormValue',
  position: ALL_BUTTON_POSITION_LIST,
  getDefaultProps: () => {
    return {
      mode: 'merge',
    };
  },
  getPrototypeList: (position, config) => {
    const { flowList, currentFlowIndex } = config || {};
    let jsExpressionPrototype = getJSExpressionPrototype({
      type: 'formRequest',
      prototypeConfig: config,
    });
    if ([ButtonPosition.cnArrayTableItemEvent].includes(position)) {
      jsExpressionPrototype = getJSExpressionPrototype({
        type: 'arrayTableCurrentRowRequest',
        prototypeConfig: 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: [
                    getFieldSelectSetterSnippet(),
                    {
                      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: '从数据源选择',
                            },
                            jsExpressionPrototype,
                          ],
                        },
                      },
                    },
                  ],
                },
              },
            },
          },
        },
      },
      {
        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,
      parentComponentName,
    } = 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;
          let extraParamList = [{}];
          if (
            [ButtonPosition.formItemEvent].includes(position) &&
            ['CnArrayTable'].includes(parentComponentName)
          ) {
            extraParamList = [
              {
                [__arrayTableCurrentRow__]:
                  getArrayTableCurrentRowByField2(field) || {},
              },
            ];
          }
          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,
                extraParamList,
              });
              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,
                        extraParamList,
                      });
                      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 loadDynamicFormConfig = {
  title: '动态加载表单',
  value: 'loadDynamicFormConfig',
  position: [
    ButtonPosition.formItemEvent,
    ButtonPosition.formDialogItemEvent,
    ButtonPosition.treeEvent,
    ButtonPosition.filterEvent,
  ],
  getPrototypeList: (position, config) => {
    const paramSelectSetter = getSelectParamSelectSetter({ position });
    const result = [
      {
        name: 'requestConfig',
        title: '查询服务',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            paramTitleDom: <div className=''>请求参数配置：</div>,
            // responseDom: <div style={{paddingTop:'10px'}}>
            //   请求返回结果的数据结构：<a target={'_blank'} href="https://yuque.antfin.com/cn-framework-committee/cn-ui-data-structure/cn-async-select#iEuF0">接口文档</a> <CnTooltip
            //   v2
            //   align={'t'}
            //   trigger={<a>接口预览</a>}
            // >
            //   <div style={{width:'200px',height:'260px'}}>
            //     <img style={{width:'100%'}} src="https://img.alicdn.com/imgextra/i1/O1CN01W5SNFR25Fg4QyRC53_!!6000000007497-0-tps-456-570.jpg"/>
            //   </div>
            // </CnTooltip>
            // </div>,
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            paramSetter: {
              componentName: 'MixedSetter',
              props: {
                setters: [
                  paramSelectSetter,
                  {
                    componentName: 'StringSetter',
                    title: '字符串',
                  },
                  getJSExpressionPrototype({ type: 'formRequest' }),
                ],
              },
            },
          },
        },
      },
    ];
    if (ButtonPosition.treeEvent === position) {
      result.unshift(...createFormSelectSetters({ mode: 'multiple' }));
    }
    return result;
  },
  action: (config) => {
    const {
      buttonConfig,
      urlParamsDataSource,
      state,
      _context,
      formRef,
      recordDataSource,
      isDesign,
    } = config || {};
    const { options } = buttonConfig || {};
    const { requestConfig, _bindForm } = options || {};
    const realFormRef = getRealizeValue(formRef);
    if (requestConfig?.url) {
      function reloadOne(ref) {
        const tempConfig = transRequestConfigToRemote({
          requestConfig,
          state,
          urlParamsDataSource,
          recordDataSource: getRealizeValue(recordDataSource),
          isDesign,
        });
        const formatResult = handleResultProcessFunc(requestConfig);
        if (typeof formatResult === 'function') {
          tempConfig.formatResult = formatResult;
        }
        ref?.reLoad?.(tempConfig);
      }
      if (realFormRef) {
        reloadOne(realFormRef);
      } else if (isArrayNotEmpty(_bindForm)) {
        _bindForm.forEach((id) => {
          if (typeof id === 'string' && id) {
            const tempFormRef = _context?.$(id)?.getFormRef?.();
            reloadOne(tempFormRef);
          }
        });
      }
    }
  },
};

const buttonGroup = {
  title: '按钮组',
  value: 'buttonGroup',
  position: [ButtonPosition.tableBatchArea, ButtonPosition.tableToolArea],
  getRenderDom: (config) => {
    const {
      state,
      children,
      optType,
      options = {},
      position,
      selectedRowKeys,
      selectedRowRecords,
      makeButton,
    } = config;
    const { buttonList } = options;
    const menu = [];
    if (Array.isArray(buttonList) && buttonList.length > 0 && makeButton) {
      buttonList.forEach((item, index) => {
        const tempButton = makeButton(item, position, {
          buttonProps: {
            text: true,
          },
        });
        if (tempButton) {
          const { disabled, onClick } = tempButton;
          if (isPlainObject(tempButton) && onClick) {
            const isDisabled = executeObjectExpr(disabled, {}, selectedRowKeys);
            menu.push(
              <CnMenuButtonItem
                key={index}
                disabled={isDisabled}
                onClick={onClick.bind(
                  this,
                  selectedRowKeys,
                  selectedRowRecords,
                )}
              >
                {tempButton.children}
              </CnMenuButtonItem>,
            );
          } else if (typeof tempButton === 'function') {
            const tempButton2 = executeFunction(
              tempButton,
              selectedRowKeys,
              selectedRowRecords,
            );
            if (tempButton2) {
              menu.push(
                <CnMenuButtonItem key={index}>{tempButton2}</CnMenuButtonItem>,
              );
            }
          }
        }
      });
    }
    return (
      <CnMenuButton
        autoWidth={false}
        popupProps={{ cache: true }}
        label={children}
      >
        {menu}
      </CnMenuButton>
    );
  },
  getPrototypeList: (position) => {
    return [
      {
        name: 'buttonList',
        title: '按钮组',
        display: 'plain',
        setter: createButtonListSetters({
          position,
          excludeButtonList: ['buttonGroup'],
        }),
      },
    ];
  },
  action: (arg) => {},
};

const setSelectDataSource = {
  title: '给选择框/树选择/级联选择设置下拉列表',
  value: 'setSelectDataSource',
  position: [
    ButtonPosition.formItemEvent,
    ButtonPosition.formDialogItemEvent,
    ButtonPosition.cnArrayTableItemEvent,
    ButtonPosition.filterItemEvent,
  ],
  getPrototypeList: (position, config) => {
    const { flowList, currentFlowIndex } = config || {};
    let jsExpressionPrototype = getJSExpressionPrototype({
      type: 'formRequest',
      prototypeConfig: config,
    });
    if (ButtonPosition.cnArrayTableItemEvent === position) {
      jsExpressionPrototype = getJSExpressionPrototype({
        type: 'arrayTableCurrentRow',
        prototypeConfig: config,
      });
    }
    return [
      {
        name: 'toSetDataSourceList',
        title: '给选择框设置下拉列表',
        className: 'cn-button-url-param-setter',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                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 config = field
                                  ?.getNode?.()
                                  .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 (
                                        item?.componentName === 'CnArrayTable'
                                      ) {
                                        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: {
                                      configList: [
                                        {
                                          groupName: '其他数据',
                                          groupExprName: __dataSource__,
                                          needSecondParam: true,
                                        },
                                        {
                                          groupName: '动作编排的数据',
                                          groupExprName: __flowData__,
                                          needSecondParam: true,
                                          flowList,
                                          currentFlowIndex,
                                        },
                                      ],
                                    },
                                    title: '从数据源选择',
                                  },
                                  {
                                    componentName: 'StringSetter',
                                    title: '字符串',
                                  },
                                  {
                                    componentName: 'NumberSetter',
                                    title: '数字',
                                  },
                                  jsExpressionPrototype,
                                ],
                              },
                            },
                          },
                        ],
                      },
                    },
                  },
                },
              },
              // getJSExpressionPrototype({type:'base'})
            ],
          },
        },
      },
    ];
  },
  action: (arg) => {
    const {
      buttonConfig,
      _context,
      formInstance,
      urlParamsDataSource,
      recordDataSource,
      state,
      componentProps,
      field,
    } = arg || {};
    const { options } = buttonConfig || {};
    const { toSetDataSourceList } = options || {};
    const realFormInstance = getRealizeValue(formInstance);
    if (realFormInstance) {
      if (
        Array.isArray(toSetDataSourceList) &&
        toSetDataSourceList.length > 0
      ) {
        const temp = handleRequestParams(toSetDataSourceList, {
          urlParamsDataSource,
          recordDataSource: getRealizeValue(recordDataSource),
          state,
          extraParamList: [
            {
              __arrayTableCurrentRow__:
                getArrayTableCurrentRowByField2(field) || {},
            },
          ],
        });
        if (isPlainObject(temp)) {
          const newValue = cloneDeep(temp);
          for (const key in newValue) {
            if (key) {
              let newDataSource = newValue[key];
              if (!Array.isArray(newDataSource)) {
                newDataSource = [];
              }
              let newKey = key;
              let newIndex;
              if (key.includes(__arrayTableCurrentRow__)) {
                const segments = field?.path?.segments;
                if (isArrayNotEmpty(segments)) {
                  newIndex = +segments[segments.length - 2];
                }
                newKey = key.replace(__arrayTableCurrentRow__, newIndex);
              }
              const { _dataSourceName } = componentProps || {};
              if (_dataSourceName) {
                const selectRef =
                  formComponentRefStorage[
                    `${_dataSourceName}${componentRefSplit}${newKey}`
                  ];
                if (
                  typeof selectRef?.current?.mutateDataSource === 'function'
                ) {
                  selectRef?.current?.mutateDataSource(newDataSource);
                }
              }
            }
          }
        }
      }
    }
  },
};

const closeDialog = {
  title: '关闭弹窗',
  value: 'closeDialog',
  position: ALL_BUTTON_POSITION_LIST,
  action: (config) => {
    const { buttonConfig, _context } = config;
    if (buttonConfig && _context) {
      const { options = {} } = buttonConfig;
      const { _bindDialog } = options;
      if (_bindDialog) {
        const dialogNode = _context.$(_bindDialog);
        dialogNode?.close?.();
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve();
          }, 400);
        });
      }
    }
  },
  getPrototypeList: () => {
    return [getSelectDialogSnippet()];
  },
};

const previousStep = {
  title: '上一步',
  value: 'previousStep',
  position: [ButtonPosition.formDialog, ButtonPosition.form],
  // getPrototypeList: (position) => {
  //   return [];
  // },
  action: (config) => {
    const {
      buttonConfig,
      formInstance,
      position,
      close,
      urlParamsDataSource,
      recordDataSource,
      state,
      _context,
      dialogRef,
      needSuccessToast: paramNeedSuccessToast,
      formStepInstance,
      isFormStep,
    } = config;
    const realFormInstance = getRealizeValue(formInstance);
    if (buttonConfig && realFormInstance && formStepInstance) {
      formStepInstance.back?.();
    }
  },
};

const nextStep = {
  title: '下一步',
  value: 'nextStep',
  position: [ButtonPosition.formDialog, ButtonPosition.form],
  // getPrototypeList: (position) => {
  //   return [];
  // },
  action: (config) => {
    const {
      buttonConfig,
      formInstance,
      position,
      close,
      urlParamsDataSource,
      recordDataSource,
      state,
      _context,
      dialogRef,
      needSuccessToast: paramNeedSuccessToast,
      formStepInstance,
      isFormStep,
    } = config;
    const realFormInstance = getRealizeValue(formInstance);
    if (buttonConfig && realFormInstance && formStepInstance) {
      formStepInstance.next?.();
    }
  },
};

const clearTableCurrentRow = {
  title: '清空表格当前点击行数据',
  value: 'clearTableCurrentRow',
  position: [ButtonPosition.tableToolArea, ButtonPosition.tableBatchArea],
  // getDefaultProps: () => {
  //   return {
  //   };
  // },
  getPrototypeList: (position, config) => {
    return createTableSelectSetters();
  },
  action: (config) => {
    const { buttonConfig, _context } = config || {};
    const { options = {} } = buttonConfig;
    const { _bindTable } = options || {};

    function handleOneTable(id) {
      if (typeof id === 'string') {
        const table = _context.$(id);
        table?.setDataSource?.({
          __tableCurrentRow__: undefined,
        });
      }
    }

    if (_bindTable && _context) {
      if (Array.isArray(_bindTable)) {
        _bindTable.forEach((item) => {
          handleOneTable(item);
        });
      } else {
        handleOneTable(_bindTable);
      }
    }
    return Promise.resolve();
  },
};

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: 'CnSelectSetter',
                              props: (field) => {
                                return {
                                  options: getVariableDsList(),
                                  selectProps: {
                                    showSearch: true,
                                  },
                                };
                              },
                            },
                          },
                          {
                            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: '数字',
                                  },
                                  {
                                    componentName: 'BoolSetter',
                                    title: '布尔（true/false）',
                                  },
                                  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 setTabActiveKey = {
  title: '设置Tab组件选中项',
  value: 'setTabActiveKey',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return [
      ...createTabSelectSetters(),
      {
        name: 'activeKey',
        title: '当前选中项',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              // {
              //   componentName: 'CnSelectSetter',
              //   title: '选择tab项',
              //   props(prop){
              //     const dataSource = []
              //     const _bindTab = prop?.parent?.getValue?.()?._bindTab;
              //     if(_bindTab) {
              //       const items = prop?.getNode?.()?.document?.getNode?.(_bindTab)?.getPropValue?.('items');
              //       if(isArrayNotEmpty(items)) {
              //         items.forEach(item=>{
              //           const label = handleI18nLabel(item.title)
              //           const value = item.primaryKey;
              //           if(label && value) {
              //             dataSource.push({
              //               label,
              //               value,
              //             })
              //           }
              //         })
              //       }
              //     }
              //     return {
              //       options:dataSource,
              //     }
              //   }
              // },
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              {
                componentName: 'ParamSelectSetter',
                props: {
                  configList: [
                    {
                      groupName: '其他数据',
                      groupExprName: __dataSource__,
                      needSecondParam: true,
                    },
                  ],
                },
                title: '从数据源选择',
              },
              getJSExpressionPrototype({ type: 'base' }),
            ],
          },
        },
      },
    ];
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options } = buttonConfig || {};
    const { activeKey, _bindTab } = options || {};
    const realActiveKey = calculateTextExprValue(activeKey, {
      state: _context?.state,
      recordDataSource: {},
    });
    if (realActiveKey && _bindTab) {
      const dom = _context?.$?.(_bindTab);
      if (typeof dom?.setTabActiveKey === 'function') {
        dom.setTabActiveKey(realActiveKey);
      }
    }
  },
};

const treeReload = {
  title: '左树右表中的树重新请求',
  value: 'treeReload',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return createTreeSelectSetters({
      mode: 'multiple',
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options } = buttonConfig || {};
    const { _bindTree } = options || {};
    function reloadOneTree(id) {
      if (typeof id === 'string') {
        const tree = _context?.$(id);
        tree?.load?.();
      }
    }

    if (isArrayNotEmpty(_bindTree) && _context) {
      _bindTree.forEach((item) => {
        reloadOneTree(item);
      });
    }
  },
};

const wait = {
  title: '等待一会',
  value: 'wait',
  position: [
    ButtonPosition.form,
    ButtonPosition.dialog,
    ButtonPosition.formDialog,
    ButtonPosition.tableBatchArea,
    ButtonPosition.tableToolArea,
    ButtonPosition.tableOperate,
    ButtonPosition.tabEvent,
    ButtonPosition.subCardAction,
    ButtonPosition.arrayTableOperate,
    ButtonPosition.blockButton,
  ],
  getPrototypeList: () => {
    return [
      {
        name: 'seconds',
        title: '等待毫秒数 单位：毫秒',
        setter: 'NumberSetter',
      },
    ];
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options } = buttonConfig || {};
    const { seconds } = options || {};
    if (typeof seconds === 'number') {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(true);
        }, seconds);
      });
    }
  },
};

const setStepActiveKey = {
  title: '设置步骤组件（CnStep）的激活步骤',
  value: 'setStepActiveKey',
  position: [ButtonPosition.step],
  getPrototypeList: () => {
    return [
      ...createStepSelectSetters(),
      {
        name: 'activeKey',
        title: '设置激活步骤',
        setter: {
          componentName: 'MixedSetter',
          props: {
            setters: [
              {
                componentName: 'NumberSetter',
                title: '指定第几步',
              },
              {
                componentName: 'StringSetter',
                title: '设置激活步骤的编码',
              },
              {
                componentName: 'ParamSelectSetter',
                props: {
                  configList: [
                    {
                      groupName: '其他数据',
                      groupExprName: __dataSource__,
                      needSecondParam: true,
                    },
                  ],
                },
                title: '从数据源选择',
              },
              getJSExpressionPrototype({ type: 'base' }),
            ],
          },
        },
      },
    ];
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options } = buttonConfig || {};
    const { activeKey, _bindStep } = options || {};
    if (activeKey && _bindStep) {
      const dom = _context?.$?.(_bindStep);
      if (typeof dom?.changeStep === 'function') {
        dom.changeStep(activeKey, { needSetState: true });
      }
    }
  },
};

/**
 * 分步表单步骤
 */
const setFormStepCurrent = {
  title: '跳转对应步骤',
  value: 'setFormStepCurrent',
  position: [ButtonPosition.formEvent],
  // getPrototypeList: () => {
  //   return [
  //     {
  //       name:'current',
  //       title:'设置激活步骤',
  //       setter:{
  //         componentName: 'MixedSetter',
  //         props: {
  //           setters: [
  //             {
  //               componentName: 'NumberSetter',
  //               title: '指定第几步',
  //             },
  //             {
  //               componentName: 'StringSetter',
  //               title: '设置激活步骤的编码',
  //             },
  //             {
  //               componentName: 'ParamSelectSetter',
  //               props: {
  //                 configList:[
  //                   {
  //                     groupName:'其他数据',
  //                     groupExprName: __dataSource__,
  //                     needSecondParam:true,
  //                   },
  //                 ],
  //               },
  //               title: '从数据源选择',
  //             },
  //             getJSExpressionPrototype({ type: 'base' }),
  //           ],
  //         },
  //       },
  //     }
  //   ]
  // },
  // action: (arg) => {
  //   const { buttonConfig, _context } = arg || {};
  //   const { options } = buttonConfig || {}
  //   const { current, _bindStep } = options || {};
  //   if(current && _bindStep) {
  //     const dom = _context?.$?.(_bindStep);
  //     if(typeof dom?.changeStep === 'function') {
  //       dom.changeStep(current, { needSetState: true});
  //     }
  //   }
  // },
};

const setFilterValue = {
  title: '给筛选栏设置数据',
  value: 'setFilterValue',
  position: ALL_BUTTON_POSITION_LIST,
  getDefaultProps: () => {
    return {
      handleFilterType: 'setFilterFieldValue',
    };
  },
  getPrototypeList: (position, config) => {
    const { flowList, currentFlowIndex } = config || {};
    return [
      ...createFilterSelectSetters({
        mode: 'single',
      }),
      getFormHandleTypeSetterSnippet({
        componentTitle: '筛选栏',
        componentName: 'Filter',
        handleTypeName: 'handleFilterType',
      }),
      {
        name: 'formValues',
        title: '要填入筛选栏的数据',
        className: 'cn-button-url-param-setter',
        condition(prop) {
          return (
            prop?.parent?.getPropValue?.('handleFilterType') ===
            'setFilterFieldValue'
          );
        },
        originalCondition(prop) {
          return (
            prop?.parent?.getPropValue?.('handleFilterType') ===
            'setFilterFieldValue'
          );
        },
        setter: {
          title: '给筛选栏每个字段设置数据',
          componentName: 'ArraySetter',
          props: {
            mode: 'list',
            itemSetter: {
              componentName: 'ObjectSetter',
              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 { _bindFilter } = currentData || {};
                          if (_bindFilter && field) {
                            const node = getNodeById({
                              field,
                              id: _bindFilter,
                            });
                            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);
                                  }
                                });
                              }
                            }
                          }
                          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: 'allFilterValues',
        display: 'inline',
        condition(prop) {
          return (
            prop?.parent?.getPropValue?.('handleFilterType') ===
            'setAllFilterValue'
          );
        },
        originalCondition(prop) {
          return (
            prop?.parent?.getPropValue?.('handleFilterType') ===
            'setAllFilterValue'
          );
        },
        title: '新的表单数据',
        className: 'cn-param-select-setter',
        // className: 'cn-button-url-param-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: '从数据源选择',
              },
              {
                componentName: 'StringSetter',
                title: '字符串',
              },
              {
                componentName: 'NumberSetter',
                title: '数字',
              },
              getJSExpressionPrototype({
                type: 'formRequest',
                prototypeConfig: config,
              }),
            ],
          },
        },
      },
    ];
  },
  action: (config) => {
    const { buttonConfig, urlParamsDataSource, state, _context } = config || {};
    const { options } = buttonConfig || {};
    const { formValues, _bindFilter, handleFilterType, allFilterValues } =
      options || {};
    if (_bindFilter) {
      const formNode = _context?.$(_bindFilter);
      const formInstance = formNode?.getFormInstance?.();
      const oldFormValue = cloneDeep(formInstance?.values);
      if (formInstance) {
        if (handleFilterType === 'clearFilterValue') {
          formInstance.setValues?.({}, 'overwrite');
        } else if (handleFilterType === 'setAllFilterValue') {
          const newFormValue = calculateTextExprValue(allFilterValues, {
            urlParamsDataSource,
            recordDataSource: oldFormValue,
            state,
          });
          if (isPlainObject(newFormValue)) {
            formInstance.setValues?.(newFormValue, 'overwrite');
          }
        } else {
          let newFormValue;
          if (Array.isArray(formValues)) {
            if (formValues.length > 0) {
              const temp = handleRequestParams(formValues, {
                urlParamsDataSource,
                recordDataSource: oldFormValue || {},
                state,
              });
              if (isPlainObject(temp)) {
                newFormValue = temp;
              }
            }
          }
          formInstance.setValues?.(newFormValue);
        }
      }
    }
    return Promise.resolve();
  },
};

const filterValidate = {
  title: '筛选栏校验',
  value: 'filterValidate',
  position: [ButtonPosition.tableToolArea, ButtonPosition.tableBatchArea],
  getPrototypeList: () => {
    return createFilterSelectSetters();
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindFilter } = options;

    if (typeof _bindFilter === 'string' && _context) {
      const filter = _context.$(_bindFilter);
      const formInstance = filter?.getFormInstance?.();
      if (formInstance?.validate) {
        return formInstance.validate();
      }
    }
  },
};

const tabReload = {
  title: 'Tab重新请求',
  value: 'tabReload',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return createTabSelectSetters({
      mode: 'multiple',
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindTab } = options;
    function reloadOneTab(id) {
      if (typeof id === 'string') {
        const tab = _context.$(id);
        tab?.getData?.();
      }
    }

    if (_bindTab && _context) {
      if (Array.isArray(_bindTab)) {
        _bindTab.forEach((item) => {
          reloadOneTab(item);
        });
      } else {
        reloadOneTab(_bindTab);
      }
    }
  },
};

const formReRender = {
  title: '表单重新渲染',
  value: 'formReRender',
  position: [ButtonPosition.filterEvent],
  getPrototypeList: () => {
    return createFormSelectSetters({
      mode: 'multiple',
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindForm } = options;
    function reloadOneForm(id) {
      if (typeof id === 'string') {
        const form = _context.$(id);
        form?.reRender()?.();
      }
    }

    if (_bindForm && _context) {
      if (Array.isArray(_bindForm)) {
        _bindForm.forEach((item) => {
          reloadOneForm(item);
        });
      } else {
        reloadOneForm(_bindForm);
      }
    }
  },
};

const setFormFieldState = {
  title: '设置表单/筛选栏字段状态',
  value: 'setFormFieldState',
  position: ALL_BUTTON_POSITION_LIST,
  getDefaultProps: () => {
    return {
      handleType: 'setByField',
    };
  },
  getPrototypeList: (position, config) => {
    return [
      ...createFormOrFilterSelectSetters({
        mode: 'single',
      }),
      {
        title: `对字段做何处理`,
        name: 'handleType',
        defaultValue: 'setByField',
        setter: {
          componentName: 'CnSelectSetter',
          props: {
            selectProps: {
              hasClear: true,
            },
            options: [
              {
                label: `给每个字段单独设置状态`,
                value: `setByField`,
              },
              {
                label: `批量设置字段状态`,
                value: `batchSetField`,
              },
            ],
          },
        },
      },
      {
        condition(prop) {
          return prop?.parent?.getPropValue?.('handleType') === 'setByField';
        },
        originalCondition(prop) {
          return prop?.parent?.getPropValue?.('handleType') === 'setByField';
        },
        name: 'fieldStateList',
        title: '字段列表',
        className: 'cn-button-url-param-setter',
        setter: {
          title: '给每个字段设置状态',
          componentName: 'ArraySetter',
          props: {
            mode: 'list',
            itemSetter: {
              componentName: 'ObjectSetter',
              props: {
                config: {
                  items: [
                    getFieldSelectSetterSnippet(),
                    {
                      name: 'value',
                      display: 'inline',
                      title: '状态',
                      isRequired: true,
                      setter: {
                        componentName: 'CnSelectSetter',
                        props: {
                          options: [
                            {
                              label: '禁用',
                              value: 'disabled',
                            },
                            {
                              label: '隐藏',
                              value: 'hidden',
                            },
                            {
                              label: '只读',
                              value: 'readOnly',
                            },
                          ],
                          selectProps: {
                            hasClear: true,
                          },
                        },
                      },
                    },
                    {
                      name: 'state',
                      display: 'inline',
                      title: '是 / 否',
                      defaultValue: true,
                      isRequired: true,
                      setter: {
                        componentName: 'MixedSetter',
                        props: {
                          setters: [
                            {
                              componentName: 'BoolSetter',
                              title: '布尔（true/false）',
                            },
                            getJSExpressionPrototype({
                              type: 'base',
                            }),
                          ],
                        },
                      },
                    },
                  ],
                },
              },
            },
          },
        },
      },
      {
        condition(prop) {
          return prop?.parent?.getPropValue?.('handleType') === 'batchSetField';
        },
        originalCondition(prop) {
          return prop?.parent?.getPropValue?.('handleType') === 'batchSetField';
        },
        name: 'batchSetFieldFieldCallback',
        title: '批量设置字段状态',
        className: 'cn-action-setter',
        setter: {
          componentName: (
            <ActionSetter
              supportTypes={['page']}
              defaultCode={`/**
 * 批量设置字段状态
 * 详细用法请参考formily官方示例
 * https://core.formilyjs.org/zh-CN/api/models/form#setfieldstate
 */
function batchSetFieldField({ form, state }) {
  // state：全部组件的数据
  // form：表单实例
  // form.setFieldState('*(field1,field2,field3)',(fieldState)=>{fieldState.hidden = true})
}`}
              defaultActionName={'batchSetFieldField'}
            />
          ),
        },
      },
    ];
  },
  action: (config) => {
    const {
      buttonConfig,
      urlParamsDataSource,
      state,
      _context,
      field,
      position,
    } = config || {};
    const { options } = buttonConfig || {};
    const {
      _bindForm,
      fieldStateList,
      handleType,
      batchSetFieldFieldCallback,
    } = options || {};
    if (_bindForm) {
      const formNode = _context?.$(_bindForm);
      const formInstance = formNode?.getFormInstance?.();
      if (formInstance) {
        if (handleType === 'batchSetField') {
          if (typeof batchSetFieldFieldCallback === 'function') {
            executeFunction(batchSetFieldFieldCallback, {
              form: formInstance,
              state,
            });
          }
        } else {
          if (isArrayNotEmpty(fieldStateList)) {
            const groupFieldState = groupBy(fieldStateList, 'label');
            for (const key in groupFieldState) {
              const stateList = groupFieldState[key];
              let realKey = key;
              if (key && isArrayNotEmpty(stateList)) {
                if (key?.includes(__arrayTableCurrentRow__) && field) {
                  const arr = key?.split?.(`.${__arrayTableCurrentRow__}.`);
                  if (arr.length === 2) {
                    const fieldName = arr[0];
                    const arrayTableFieldName = arr[1];
                    const segments = field?.path?.segments || [];
                    const fieldIndex = +segments[segments?.length - 2];
                    if (!isNaN(fieldIndex)) {
                      realKey = `${fieldName}.${fieldIndex}.${arrayTableFieldName}`;
                    }
                  }
                }
                formInstance.setFieldState(realKey, (fieldState) => {
                  stateList.forEach((item) => {
                    const { value, state } = item;
                    if (value && state !== undefined) {
                      fieldState[value] = executeObjectExpr(
                        state,
                        {},
                        {},
                        _context?.state,
                      );
                    }
                  });
                });
              }
            }
          }
        }
      }
    }
    return Promise.resolve();
  },
};

const componentReRender = {
  title: '组件重新渲染',
  value: 'componentReRender',
  position: ALL_BUTTON_POSITION_LIST,
  getPrototypeList: () => {
    return createComponentSelectSetters({
      mode: 'multiple',
      containsKey: [
        'isCnTable',
        'isCnTab',
        'isCnStatisticCard',
        'isCnForm',
        'isCnFormDialog',
        'isCnPieChart',
        'isCnPage',
        ...(window?.cnLowCodeUtils?.canForceUpdate || []).map((i) => i.propKey),
      ],
    });
  },
  action: (arg) => {
    const { buttonConfig, _context } = arg || {};
    const { options = {} } = buttonConfig;
    const { _bindComponent } = options;
    function reloadOneComponent(id) {
      if (typeof id === 'string') {
        const compIns = _context.$(id);
        if (isFunction(compIns?.reRender)) {
          compIns?.reRender?.()?.();
        } else {
          compIns?.forceUpdate?.();
        }
      }
    }

    if (_bindComponent && _context) {
      if (Array.isArray(_bindComponent)) {
        _bindComponent.forEach((item) => {
          reloadOneComponent(item);
        });
      } else {
        reloadOneComponent(_bindComponent);
      }
    }
  },
};

const componentMap = {
  link,
  request,
  pollingAction,
  batch,
  submit,
  reset,
  cancel,
  dialog,
  ossImport,
  export: exportButton,
  download,
  tableReload,
  jsAction,
  arrayTableRemove,
  arrayTableAdd,
  arrayTableMoveUp,
  arrayTableMoveDown,
  arraySubAreaCardRemove,
  arraySubAreaCardAdd,
  arraySubAreaCardMoveUp,
  arraySubAreaCardMoveDown,
  componentReload,
  message,
  confirm,
  formReload,
  setFormData,
  textRender,
  tableLoop,
  setFormValue,
  loadDynamicFormConfig,
  filterReset,
  filterSearch,
  filterValidate,
  buttonGroup,
  setSelectDataSource,
  closeDialog,
  previousStep,
  nextStep,
  tabReload,
  clearTableCurrentRow,
  setDataSourceValue,
  locationReload,
  setTableSelectRowKeys,
  setTableOpenKeys,
  setTabActiveKey,
  setStepActiveKey,
  setFormStepCurrent,
  treeReload,
  wait,
  setFilterValue,
  tableLoop2,
  formReRender,
  setFormFieldState,
  componentReRender,
  flowAction,
};

// 注册回调动作
export function registerButton(plugin) {
  const { name } = plugin || {};
  if (name) {
    componentMap[name] = plugin;
  }
}

// 获取按钮列表
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;
}

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;
}

// 获取按钮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 function getItemDefaultProps(position, componentName) {
  const func = getItem(position, componentName, 'getDefaultProps');
  if (typeof func === 'function') {
    return func();
  }
}

export function getButtonAction(buttonConfig) {
  const { optType, position } = buttonConfig || {};
  if (optType) {
    const action = getItem(position, optType, 'action');

    if (typeof action === 'function') {
      return action;
    }
  }
}

export function getRunTimeItem(componentName) {
  let result;
  if (componentName) {
    result = componentMap[componentName];
    if (!result) {
      result = getRunTimeBizComponent(componentName);
    }
  }
  return result;
}

// // 获取button的node
// export function getButtonNode(arg){
//   const { buttonConfig = {}} = arg;
//   const { optType } = buttonConfig;
//   if(optType) {
//     const button = componentMap[optType];
//     if(typeof button?.getButtonNode === 'function'){
//       // 传递record,index ， 这样onClick就能拿到
//       return button.getButtonNode(arg)
//     }
//   }
//   return null;
// }

export const createButtonListSetters = (config) => {
  const { position, childrenTitle, additionalPosition, extraInitialValues } =
    config || {};
  const tempButtonList = getButtonListByPosition(position, config);
  let titleSetter = 'CnI18nSetter';
  if (
    [
      ButtonPosition.cardAction,
      ButtonPosition.subCardAction,
      ButtonPosition.blockButton,
    ].includes(position)
  ) {
    titleSetter = {
      componentName: 'MixedSetter',
      props: {
        setters: [
          {
            componentName: 'CnI18nSetter',
            title: '纯文本',
          },
          getJSExpressionPrototype({
            type: 'formRequest',
          }),
        ],
      },
    };
  }
  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 || '标题',
      // initialValue: "按钮",
      // extraProps: {
      // setValue(target,value){
      // },
      // },
      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,
          });
        },
      },
      // "extraProps": {
      //   "setValue": {
      //     "type": "JSFunction",
      //     "value": "(target, value) => {}"
      //   }
      // },
      // initialValue: tempButtonList[0]?.value,
      editable: true,
      setter: {
        componentName: 'CnSelectSetter',
        // props: {
        //   options: getButtonListByPosition(position),
        // },
        props: () => {
          return {
            options: getButtonListByPosition(position, config),
            selectProps: {
              showSearch: true,
            },
          };
        },
      },
    },
  ];
  configure.push({
    name: 'options',
    // display: 'accordion',
    display: 'block',
    title: '按钮配置项',
    extraProps: {
      defaultCollapsed: false,
    },
    setter: {
      componentName: 'ObjectSetter',
      props: () => {
        return {
          config: {
            items: [
              ...getButtonPrototypeListByPosition(position, {
                additionalPosition,
              }),
            ],
          },
        };
      },
    },
  });

  const styleList = getStyleListByPosition(position);
  if (styleList?.length > 0) {
    configure.push({
      title: '样式',
      type: 'group',
      display: 'accordion',
      collapsed: true,
      items: styleList,
    });
    // configure.push({
    //   name: 'style',
    //   display: 'block',
    //   title: '样式',
    //   setter: {
    //     componentName: "ObjectSetter",
    //     props: {
    //       config: {
    //         items: [
    //           {
    //             name: 'type',
    //             title: '按钮样式',
    //             // supportVariable: true,
    //             display:'inline',
    //             initialValue: 'normal',
    //             setter: <SelectSetter
    //               options={
    //                 [
    //                   {
    //                     title: 'normal',
    //                     value: 'normal'
    //                   },
    //                   {
    //                     title: 'primary',
    //                     value: 'primary'
    //                   },
    //                   {
    //                     title: 'secondary',
    //                     value: 'secondary'
    //                   }
    //                 ]
    //               }
    //             />
    //           }
    //         ]
    //       }
    //     }
    //   }
    // })
  }
  // configure.push({
  //   title: '高级配置（请谨慎使用）',
  //   name: __advancedCodeConfig__,
  //   display: 'accordion',
  //   extraProps: {
  //     defaultCollapsed: true,
  //   },
  //   setter: {
  //     componentName: 'ObjectSetter',
  //     props: {
  //       config: {
  //         items: [
  //           {
  //             name: 'handleProps',
  //             title: '手动设置组件props',
  //             display: 'inline',
  //             setter: getJSExpressionPrototype({
  //               type:'props',
  //             }),
  //           },
  //         ]
  //       }
  //     }
  //   }
  // })
  const buttonInitialValue = getItemDefaultProps(
    position,
    tempButtonList[0]?.value,
  );
  return {
    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() {
          return {
            primaryKey: uuid(6),
            children: '按钮',
            optType: tempButtonList[0]?.value,
            options: buttonInitialValue,
            ...extraInitialValues,
          };
        },
        props: {
          config: {
            items: configure,
          },
        },
      },
    },
  };

  // return <ListSetter
  //   descriptor="children"
  //   display="drawer"
  //   checkField={null}
  //   configure={configure}
  // />
};

function getPollingFlowList(field) {
  let flowList = field?.parent?.parent?.getValue?.()?.slice?.() ?? [];
  let flowIndex = field?.parent?.name;
  const lastParentName = field?.parent?.parent?.parent?.parent?.parent?.name;
  if(lastParentName === 'flowList') {
    let parentIndex = field?.parent?.parent?.parent?.parent?.name;
    flowList?.forEach(item=> {
      if(isPlainObject(item)) {
        item.prefix = {
          text: `轮询${parentIndex || ''}`,
          path: `polling${parentIndex || ''}`,
          changeIndex: -parentIndex
        }
      }
    })
    let parentFlowList = field?.parent?.parent?.parent?.parent?.parent?.getValue?.()?.slice?.();
    parentFlowList[parentIndex] = flowList;
    flowList = flatten(parentFlowList);
    flowIndex = flowIndex + parentIndex;
  }
  return [flowList, flowIndex];
}
export const createPollingListSetters = (config) => {
  const { position, activeSetter, excludeButtonList = [] } = 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: 'CnSelectSetter',
                  props: () => {
                    return {
                      options: getButtonListByPosition(position, {
                        excludeButtonList: ['flowAction', ...(excludeButtonList ?? [])],
                      }),
                      selectProps: {
                        showSearch: true,
                      },
                    };
                  },
                },
              },
              {
                name: 'active',
                display: 'inline',
                title: '启用',
                isRequired: true,
                setter: activeSetter || {
                  componentName: <CheckboxSetter />,
                  title: '启用/禁用',
                },
              },
              {
                name: 'options',
                // display: 'accordion',
                display: 'plain',
                title: '动作配置项',
                extraProps: {
                  defaultCollapsed: false,
                },
                setter: {
                  componentName: 'ObjectSetter',
                  props: (field) => {
                    const [flowList, flowIndex] = getPollingFlowList(field);
                    // 内部的   数据直接下啦选择的地方
                    return {
                      config: {
                        items: [
                          ...getButtonPrototypeListByPosition(position, {
                            flowList,
                            currentFlowIndex: flowIndex,
                          }),
                        ],
                      },
                    };
                  },
                },
              },
            ],
          },
        },
      },
    },
  };
};

export const createFlowListSetters = (config) => {
  const { position, activeSetter, excludeButtonList = [] } = 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: 'CnSelectSetter',
                  props: () => {
                    return {
                      options: getButtonListByPosition(position, {
                        excludeButtonList: ['flowAction', ...(excludeButtonList ?? [])],
                      }),
                      selectProps: {
                        showSearch: true,
                      },
                    };
                  },
                },
              },
              {
                name: 'active',
                display: 'inline',
                title: '启用',
                isRequired: true,
                setter: activeSetter || {
                  componentName: <CheckboxSetter />,
                  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 createFormSelectSetters(config) {
  const { mode } = config || {};
  const getSelectSetterItemInfoByNodeItem = getSelectSetterItemFuntion([
    'isCnForm',
    'isCnFormDialog',
  ]);
  return [
    {
      name: '_bindForm',
      title: '选择表单',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          const { title } = getSelectSetterItemInfoByNodeItem(item);

          title &&
            options.push({
              title,
              value: item.id,
            });
        });
        return {
          componentName: 'SelectSetter',
          props: {
            mode,
            // hasClear: true,
            options,
          },
        };
      },
    },
  ];
}

// propKey 用于判断组件类型  prefix为前缀  titleKey是获取
const allBindComponentMatchConfig = [
  {
    propKey: 'isCnTable',
    prefix: '表格',
    titleKey: 'tableName',
  },
  {
    propKey: 'isCnTab',
    prefix: '选项卡',
  },
  {
    propKey: 'isCnStatisticCard',
    prefix: '指标卡',
  },
  {
    propKey: 'isCnForm',
    prefix: '表单',
  },
  {
    propKey: 'isCnFormDialog',
    prefix: '弹窗表单',
  },
  {
    propKey: 'isCnPieChart',
    prefix: '饼图',
  },
  {
    propKey: 'isCnList',
    prefix: '列表',
    titleKey: 'header',
  },
  {
    propKey: 'isCnStep',
    prefix: '步骤条',
  },
  {
    propKey: 'isCnPage',
    prefix: 'CnPage',
  },
];
//
function getSelectSetterItemFuntion(containsKey: string[] = []) {
  const realAllBindComponentMatchConfig = allBindComponentMatchConfig.concat(
    window?.cnLowCodeUtils?.canForceUpdate || [],
  );
  const filterConfig =
    containsKey?.length > 0
      ? realAllBindComponentMatchConfig.filter((configItem) =>
          containsKey.includes(configItem?.propKey),
        )
      : realAllBindComponentMatchConfig;
  // 根据config
  return function getSelectSetterItemInfoByNodeItem(item) {
    if (isFunction(item?.getPropValue)) {
      let matchConfig = null;
      filterConfig.forEach((configItem) => {
        const { propKey, prefix, titleKey = 'title' } = configItem;
        const isMatch = item.getPropValue(propKey);
        if (isMatch) {
          const componentTitle = item?.propsData?.[titleKey] ?? '';
          matchConfig = {
            prefix,
            title: `${prefix}_${handleI18nLabel(componentTitle) || ''}`,
          };
        }
      });
      if (matchConfig) {
        return matchConfig;
      }
    }
    return {
      prefix: '',
      title: '',
    };
  };
}

export function createComponentSelectSetters(config) {
  const { mode, containsKey } = config || {};
  const getSelectSetterItemInfoByNodeItem = getSelectSetterItemFuntion(
    containsKey || [
      'isCnTable',
      'isCnTab',
      'isCnStatisticCard',
      'isCnForm',
      'isCnFormDialog',
      'isCnPieChart',
      ...(window?.cnLowCodeUtils?.canForceUpdate || []).map((i) => i.propKey),
    ],
  );
  return [
    {
      name: '_bindComponent',
      title: '选择组件',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          const { title } = getSelectSetterItemInfoByNodeItem(item);
          if (title) {
            options.push({
              title,
              value: item.id || '',
            });
          }
        });
        return {
          componentName: 'SelectSetter',
          props: {
            mode,
            // hasClear: true,
            options,
          },
        };
      },
    },
  ];
}

export function createFilterSelectSetters(config, extraConfig) {
  const { mode } = config || {};
  return [
    {
      name: '_bindFilter',
      title: '选择筛选栏',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          if (item.getPropValue('isCnFilter')) {
            const 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,
          },
        };
      },
      ...extraConfig,
    },
  ];
}

export function createFormOrFilterSelectSetters(config) {
  const { mode } = config || {};
  return [
    {
      name: '_bindForm',
      title: '选择筛选栏/表单',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          const isCnFilter = item.getPropValue('isCnFilter');
          const isCnForm = item.getPropValue('isCnForm');
          const isCnFormDialog = item.getPropValue('isCnFormDialog');
          if (isCnFilter || isCnForm || isCnFormDialog) {
            let prefix = '筛选栏';
            if (isCnForm) {
              prefix = '表单';
            }
            if (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 createTableSelectSetters(config, extraConfig) {
  const { mode } = config || {};
  return [
    {
      name: '_bindTable',
      title: '选择表格',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          if (item.getPropValue('isCnTable')) {
            const id = item.id || '';
            const tableName = item?.propsData?.tableName || '';
            const title = `表格_${tableName}`;
            options.push({
              title,
              value: id,
            });
          }
        });
        return {
          componentName: 'SelectSetter',
          props: {
            mode: mode || 'multiple',
            // hasClear: true,
            options,
          },
        };
      },
      ...extraConfig,
    },
  ];
}

// 选择Tab setter
export function createTabSelectSetters(config) {
  const { mode } = config || {};
  return [
    {
      name: '_bindTab',
      title: '选择Tab组件',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          if (item.getPropValue('isCnTab')) {
            const prefix = 'Tab';
            const id = item?.id || '';
            const title = `${prefix}_${
              handleI18nLabel(item?.propsData?.title) || ''
            }`;
            options.push({
              title,
              value: id,
            });
          }
        });
        return {
          componentName: 'SelectSetter',
          props: {
            mode,
            // hasClear: true,
            options,
          },
        };
      },
    },
  ];
}

// 选择Step setter
export function createStepSelectSetters(config) {
  const { mode } = config || {};
  return [
    {
      name: '_bindStep',
      title: '选择组件',
      setter: {
        componentName: 'CnSelectSetter',
        props(prop) {
          const options = [];
          prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
            if (item.getPropValue('isCnStep')) {
              const prefix = 'Step';
              const id = item?.id || '';
              const title = `${prefix}_${
                handleI18nLabel(item?.propsData?.title) || ''
              }`;
              options.push({
                title,
                value: id,
              });
            }
          });
          return {
            mode,
            hasClear: true,
            options,
          };
        },
      },
    },
  ];
}

// 选择树 setter
export function createTreeSelectSetters(config) {
  const { mode } = config || {};
  return [
    {
      name: '_bindTree',
      title: '选择树组件',
      setter(prop) {
        const options = [];
        prop?.getNode?.()?.document?.nodesMap?.forEach((item) => {
          if (item?.getPropValue('isCnLeftTree')) {
            const 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,
          },
        };
      },
    },
  ];
}

function waitAsync(time: number) {

  return new Promise((resolve)=> {
    setTimeout(() => {
      resolve(true);
    }, time)
  })
}
