<template>
  <div :class="listPageMode === LIST_MODE.HORIZONTAL ? 'relative' : ''">
    <a-tabs
      type="editable-card"
      hide-add
      class="mode-tabs"
      v-if="listPageMode === LIST_MODE.VERTICAL && !onlyShowAddForm"
      v-model:activeKey="modeActiveKey"
      :tabBarGutter="0"
      :tabBarStyle="{
        background: 'white',
        borderRadius: '16px',
        margin: '10px 0 0',
        border: '1px solid #EEE',
        height: '52px',
        padding: '0 16px',
      }"
      @edit="handleTabsEdit"
      @change="handleTabsClick"
    >
      <a-tab-pane
        v-for="item in modePanes"
        :key="item.key"
        :tab="item.title"
        :closable="item.closable"
      />
    </a-tabs>
    <ResizePageWrapper
      v-show="
        (((listPageMode === LIST_MODE.VERTICAL && modeActiveKey === 1) ||
          listPageMode === LIST_MODE.DEFAULT) &&
          !onlyShowAddForm) ||
        listPageMode === LIST_MODE.HORIZONTAL ||
        listPageMode === LIST_MODE.CARD
      "
      :hasLeft="listConfig.isLeftMenu ? true : false"
      :formLeftWidth="300"
      :listPageMode="listPageMode"
      :searchHeight="searchHeight"
      :class="
        listPageMode === LIST_MODE.HORIZONTAL
          ? `w-1/2 mr-10px ${
              listConfig.isLeftMenu ? `${leftTreeShow ? 'block' : ''} listmode-horizontal-tree` : ''
            }`
          : ''
      "
    >
      <template #resizeLeft v-if="listConfig.isLeftMenu">
        <a-tabs
          v-model:activeKey="leftMenuIndex"
          @change="leftTabChange"
          v-if="listConfig.leftMenuConfig!.length > 1"
          class="left-menu-box"
        >
          <a-tab-pane
            :key="index"
            :tab="config.title || index + 1"
            v-for="(config, index) in listConfig.leftMenuConfig"
          >
            <LeftTree
              :config="config"
              :treeData="treeData"
              @handle-select="handleSelect"
              @handle-select-tree="handleSelectTree"
            />
          </a-tab-pane>
        </a-tabs>
        <LeftTree
          v-else
          :config="listConfig.leftMenuConfig![0]"
          :treeData="treeData"
          @handle-select="handleSelect"
          @handle-select-tree="handleSelectTree"
        />
      </template>

      <template #resizeRight>
        <div :class="isCardList ? 'card-box' : ''" style="height: 100%">
          <BasicTable
            @register="registerTable"
            ref="tableRef"
            @expand="expandedRowsChange"
            @columns-change="handleColumnChange"
            @tree-show-change="handleTreeChange"
            @redo="handleRedo"
            @change="handleTableChange"
            isMenuTable
          >
            <template #customFilterIcon="{ filtered, column }">
              <Icon
                icon="ant-design:filter-filled"
                @click="handleFilterClick(column)"
                :class="filterClass(column, filtered)"
                :style="{ color: filtered ? '#108ee9' : undefined }"
              />
            </template>
            <template #toolbar>
              <template v-for="button in tableButtonConfig" :key="button.code">
                <a-button v-if="button.isDefault" type="primary" @click="buttonClick(button.code)">
                  <template #icon><Icon :icon="button.icon" /></template>
                  {{ button.name }}
                </a-button>
                <template v-else>
                  <CustomButtonModal v-if="button.buttonType == 'modal'" :info="button" />
                  <a-button v-else type="primary" @click="customButtonClick(button)">
                    <template #icon><Icon :icon="button.icon" /></template>
                    {{ button.name }}
                  </a-button>
                </template>
              </template>
            </template>
            <template #bodyCell="{ column, record }" v-if="!isCardList">
              <template v-if="column.componentType === 'switch'">
                <a-switch
                  v-model:checked="record[column.dataIndex]"
                  :unCheckedValue="0"
                  :checkedValue="1"
                  :disabled="true"
                />
              </template>
              <template v-if="column.componentType === 'picker-color'">
                <ColorPicker v-model:value="record[column.dataIndex]" :disabled="true" />
              </template>
              <template v-else-if="column.componentType === 'labelComponent'">
                <XjrLabelComponentInfo
                  :value="record[column.dataIndex]"
                  :styleConfig="column.styleConfig"
                />
              </template>
              <template v-if="column.dataIndex === 'action'">
                <div class="btn-box" ref="pushBtnRef" v-if="isShowBtn && pushFormId === record.id">
                  <a-button
                    type="primary"
                    v-for="item in pushorderInfo!.setting.formInfo"
                    :key="item.formId"
                    @click="openPushorder(item)"
                  >
                    {{ item.formType === 0 ? item.functionName : item.formName }}
                  </a-button>
                </div>

                <TableAction
                  :actions="getLessActions(record, false)"
                  :dropDownActions="getMoreActions(record, false)"
                />
              </template>

              <template v-else-if="column.componentType === 'money-chinese'">
                <span :style="executeListStyle(record, column?.listStyle)">
                  {{ moneyChineseData(record[column.dataIndex]) }}
                </span>
              </template>

              <template v-else-if="column.dataIndex && column?.listStyle">
                <span
                  :style="executeListStyle(getValue(record, column, 'style'), column?.listStyle)"
                >
                  {{ getValue(record, column, 'value') }}
                </span>
              </template>
            </template>
            <template #expandedRowRender="{ record }" v-if="subFormList?.length">
              <a-table
                v-for="item in subFormList"
                :key="item.key"
                :columns="innerColumns[item.field]"
                :data-source="getInnerDataSource(record.id, item.field)"
                :pagination="false"
                :scroll="{ x: 'max-content' }"
              >
                <template #bodyCell="{ column, record: innerRecord }">
                  <template v-if="column.componentType === 'picker-color'">
                    <ColorPicker v-model:value="innerRecord[column.dataIndex]" :disabled="true" />
                  </template>
                  <template v-if="column.componentType === 'labelComponent'">
                    <XjrLabelComponentInfo
                      :value="innerRecord[column.dataIndex]"
                      :styleConfig="column.styleConfig"
                    />
                  </template>
                  <template v-else-if="column.componentType === 'money-chinese'">
                    {{ moneyChineseData(innerRecord[column.dataIndex]) }}
                  </template>
                </template>
              </a-table>
            </template>
            <template #emptyText v-if="isCardList">
              <a-checkbox-group
                v-model:value="selectedKeys"
                class="data-list"
                v-if="datasource.length"
              >
                <div
                  v-for="(data, idx) in datasource"
                  :key="data.id"
                  :class="[
                    'box-container',
                    selectedKeys.includes(data.id) ? 'selected-box' : 'unselected-box',
                  ]"
                >
                  <div class="box-title">
                    <div>
                      <a-checkbox :value="data.id" class="!mr-1" v-if="hasListCheckbox" />
                      <span class="text-black" v-if="isShowIndex">#{{ idx + 1 }}</span>
                    </div>
                    <div class="flex">
                      <a-tooltip v-for="(item, index) in getActions(data, true)" :key="index">
                        <template #title>{{ item.tooltip }} </template>
                        <Icon
                          :icon="item.icon"
                          :class="['icon-box', item.color === 'error' ? 'icon-delete' : '']"
                          :style="{ height: '24px', width: '24px' }"
                          @click="
                            () => {
                              if (item.onClick) item.onClick();
                            }
                          "
                        />
                      </a-tooltip>

                      <div
                        class="btn-box"
                        ref="pushBtnRef"
                        v-if="isShowBtn && pushFormId === data.id"
                      >
                        <a-button
                          type="primary"
                          v-for="info in pushorderInfo!.setting.formInfo"
                          :key="info.formId"
                          @click="openPushorder(info)"
                        >
                          {{ info.formType === 0 ? info.functionName : info.formName }}
                        </a-button>
                      </div>
                    </div>
                  </div>
                  <div class="flex-box">
                    <div
                      v-for="(key, value) in getData(data)"
                      :key="value"
                      :class="`flex-item text-${key.align || 'left'} ${
                        key.aRow ? '!basis-full' : ''
                      }`"
                    >
                      <div :class="['title', key.textBold ? 'font-bold' : '']">
                        {{ value }}
                      </div>
                      <div class="value">{{ key.value }}</div>
                    </div>
                  </div>
                </div>
              </a-checkbox-group>
              <div v-else>
                <a-empty />
              </div>
            </template>
          </BasicTable>
        </div>
      </template>

      <FormModal
        v-if="formType === 'modal'"
        @register="registerModal"
        @success="handleFormSuccess"
        @cancel="handleFormCancel"
        :formType="formType"
        :formWidth="formWidth"
        :formHeight="formHeight"
        :formButtons="formButtons"
        :form-id="formIdComputedRef"
        :menuId="menuId"
      />
      <FormModal
        v-else-if="formType === 'drawer'"
        @register="registerDrawer"
        @success="handleFormSuccess"
        @cancel="handleFormCancel"
        :formType="formType"
        :formWidth="formWidth"
        :form-id="formIdComputedRef"
        :formButtons="formButtons"
        :menuId="menuId"
      />

      <ImportModal
        @register="registerImportModal"
        importUrl="/form/execute/import"
        :data="{ releaseId: menuId }"
        @success="handleImportSuccess"
      />
      <LookProcess
        v-if="visibleLookProcessRef"
        :taskId="taskIdRef"
        :processId="processIdRef"
        @close="visibleLookProcessRef = false"
        :visible="visibleLookProcessRef"
      />

      <ApprovalProcess
        v-if="visibleApproveProcessRef"
        :taskId="taskIdRef"
        :processId="processIdRef"
        :schemaId="schemaIdRef"
        @close="handleCloseApproval"
        :visible="visibleApproveProcessRef"
      />
      <SetRuleUserModal @register="registerRuleUserModal" @success="handleSuccess" />
      <PrintPreview
        v-if="visiblePrintPreview"
        :id="printData.id"
        :request-params-configs="printData.requestParamsConfigs"
        :request-body-configs="printData.requestBodyConfigs"
        :request-header-configs="printData.requestHeaderConfigs"
        @close="handleClosePrintPreview"
      />
      <ExportModal
        v-if="visibleExport"
        :columns="columns"
        @close="visibleExport = false"
        @success="handleExportSuccess"
      />
      <BasicModal
        v-if="visibleFlowRecordModal"
        :visible="visibleFlowRecordModal"
        :title="t('查看流转记录')"
        :paddingRight="15"
        :showOkBtn="false"
        :width="1200"
        @visible-change="
          (v) => {
            visibleFlowRecordModal = v;
          }
        "
        :bodyStyle="{ minHeight: '400px !important' }"
      >
        <FlowRecord :processId="processIdRef" />
      </BasicModal>
      <PushOrderModal @register="registerPushModal" />
    </ResizePageWrapper>
    <LaunchProcess
      v-if="visibleLaunchProcessRef"
      :schemaId="schemaIdRef"
      :form-data="formDataRef"
      :form-id="formIdComputedRef"
      :rowKeyData="rowKeyData"
      :draftsId="draftsId"
      @close="handleCloseLaunch"
    />
    <div
      :class="
        listPageMode === LIST_MODE.HORIZONTAL
          ? 'form-horizontal-modal'
          : !isQueryFullScreen
          ? 'pt-10px'
          : ''
      "
      v-show="
        (modeActiveKey !== 1 &&
          listPageMode === LIST_MODE.VERTICAL &&
          !(schemaInitConfig && schemaInitConfig.enabled && schemaInitConfig.enabledAddApprove)) ||
        (onlyShowAddForm && listPageMode === LIST_MODE.VERTICAL) ||
        listPageMode === LIST_MODE.HORIZONTAL
      "
      :style="{
        height:
          listPageMode === LIST_MODE.HORIZONTAL
            ? 'calc(100vh - 149px)'
            : listPageMode === LIST_MODE.VERTICAL && !listConfig.listStyleConfig?.onlyShowForm
            ? 'calc(100vh - 201px)'
            : !isQueryFullScreen
            ? 'calc(100vh - 139px)'
            : 'calc(100vh - 20px)',
      }"
    >
      <EmptyBox
        v-if="listPageMode === LIST_MODE.HORIZONTAL && horizontalEmpty"
        :title="t('当前无相关数据')"
        :desc="t(`请点击左侧${hasAddBtn ? '新增或' : ''}编辑按钮来操作数据`)"
      />
      <div class="h-full" v-show="!horizontalEmpty || listPageMode === LIST_MODE.VERTICAL">
        <div v-if="listPageMode === LIST_MODE.HORIZONTAL" class="form-horizontal-title">
          {{ horizontalTitle }}
        </div>
        <FormModal
          :class="listPageMode === LIST_MODE.HORIZONTAL ? 'pt-76px' : ''"
          ref="FormNormalRef"
          @success="handleSuccess(listPageMode === LIST_MODE.HORIZONTAL ? true : false)"
          formType="normal"
          :onlyShowAddForm="onlyShowAddForm"
          :listPageMode="listPageMode"
          :form-id="formIdComputedRef"
          :formButtons="formButtons"
          :isShowBtn="listConfig.listStyleConfig?.isShowBtn"
        />
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
  import { useDrawer } from '/@/components/Drawer';
  import { ResizePageWrapper } from '/@/components/Page';
  import {
    BasicColumn,
    BasicTable,
    FormProps,
    FormSchema,
    TableAction,
    useTable,
    ActionItem,
  } from '/@/components/Table';
  import FormModal from './components/FormModal.vue';
  import { ColorPicker } from '/@/components/ColorPicker';
  import { XjrLabelComponentInfo } from '/@/components/LabelComponent';
  import { ImportModal } from '/@/components/Import';
  import SetRuleUserModal from '/@/components/Designer/src/components/generateComponent/SetRuleUserModal.vue';
  import Icon from '/@/components/Icon/index';
  import LookProcess from '/@/views/workflow/task/components/LookProcess.vue';
  import LaunchProcess from '/@/views/workflow/task/components/LaunchProcess.vue';
  import ApprovalProcess from '/@/views/workflow/task/components/ApprovalProcess.vue';
  import { downloadByData } from '/@/utils/file/download';
  import { onMounted, ref, unref, computed, createVNode, provide, reactive, nextTick } from 'vue';
  import { useRouter } from 'vue-router';
  import { getFormSchemaId, getFormTemplate } from '/@/api/form/design';
  import { getFormRelease } from '/@/api/form/release';
  import { useModal, BasicModal } from '/@/components/Modal';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { FormReleaseConfig, GeneratorConfig } from '/@/model/generator/generatorConfig';
  import { ColumnConfig, ListConfig, QueryConfig, ApiConfig } from '/@/model/generator/listConfig';
  import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
  import { buildOption } from '/@/utils/helper/designHelper';
  import { whetherNeedToTransform, findSchema } from '/@/utils/helper/generatorHelper';
  import { ComponentOptionModel } from '/@/model/generator/codeGenerator';
  import {
    deleteFormExecute,
    getFormExecutePage,
    getFormExecuteWorkflow,
    exportForm,
    setDataAuth,
    getFormExecute,
    getSubData,
  } from '/@/api/form/execute';
  import { handleSearchForm } from '/@/utils/helper/exportHelper';
  import { useTabs } from '/@/hooks/web/useTabs';
  import { executeListStyle, getValue } from '/@/hooks/web/useListStyle';
  import { useTitle } from '@vueuse/core';
  import { useGlobSetting } from '/@/hooks/setting';
  import { usePermission } from '/@/hooks/web/usePermission';
  import { TreeItem } from '/@/components/Tree';
  import { getDicDetailList } from '/@/api/system/dic';
  import {
    apiConfigFunc,
    generateTableJson,
    isValidJSON,
    moneyChineseData,
  } from '/@/utils/event/design';
  import { Modal } from 'ant-design-vue';
  import { CloseCircleOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
  import printJS from 'print-js';
  import { getPrintConfigInfo } from '/@/api/system/generator/print';
  import PrintPreview from '/@/views/generator/print/Preview.vue';
  import { PrintButton } from '/@/enums/printEnum';
  import { InputParamItem } from '/@/components/ApiConfig/src/interface';
  import { getDraftInfo } from '/@/api/workflow/process';
  import FlowRecord from '/@/views/workflow/task/components/flow/FlowRecord.vue';
  import LeftTree from './components/LeftTree.vue';
  import PushOrderModal from './components/PushOrderModal.vue';
  import ExportModal from './components/ExportModal.vue';
  import { LIST_MODE } from '/@/enums/formViewEnum';
  import { useConcurrentLock } from '/@/hooks/web/useConcurrentLock';
  import { baseHandler } from '../../../../src/layouts/default/setting/handler';
  import { HandlerEnum } from '../../../../src/layouts/default/setting/enum';
  import EmptyBox from '/@/views/workflow/task/components/flow/EmptyBox.vue';
  import XLSX from 'xlsx-js-style';
  import { executeCustomEvent } from '/@/utils/event/data';
  import { AssignmentTypeToRuleType } from '/@/api/ruleProcess/model';
  import { buttonListInfo } from '/@/components/Designer';
  import { cloneDeep } from 'lodash-es';
  import CustomButtonModal from '/@/components/Form/src/components/CustomButtonModal.vue';
  interface SearchDate {
    fieldName: string;
    format: string;
  }
  const listSpliceNum = ref(3); //操作列最先展示几个
  const { setTitle } = useTabs();
  const { title } = useGlobSetting();
  const {
    enableLockeData,
    handleOpenFormEnableLockeData,
    handleCloseFormEnableLocke,
    handleHasEnableLocke,
  } = useConcurrentLock();
  const { currentRoute } = useRouter();
  const listPageMode = ref<string>(LIST_MODE.DEFAULT);
  const leftTreeShow = ref(false);
  const { path, query } = unref(currentRoute);
  const printMenuId = computed(() => currentRoute.value.meta.menuId as string);
  const { filterColumnAuth, filterHeaderColumnAuth, filterButtonAuth, hasPermission } =
    usePermission();
  const onlyShowAddForm = computed(() => {
    if (query.onlyShowAddForm) {
      baseHandler(HandlerEnum.FULL_CONTENT, true);
      return true;
    } else if (
      listPageMode.value == LIST_MODE.VERTICAL &&
      listConfig.value.listStyleConfig?.onlyShowForm
    ) {
      return true;
    } else {
      return false;
    }
  });
  const isQueryFullScreen = computed(() => {
    return query.fullScreen;
  });

  const horizontalTitle = ref('新增');
  const horizontalEmpty = ref(true);
  let columns: BasicColumn[] = [], //列表配置
    searchFormSchema: FormSchema[] = [], //搜索框配置
    searchDate: SearchDate[] = [], //搜索栏时间组件配置
    formProps: FormProps = {}, //表单配置
    listConfig = ref<ListConfig>({
      isLeftMenu: false,
      isPage: false,
      pageSize: 10,
      queryConfigs: [],
      columnConfigs: [],
      buttonConfigs: [],
      listTitle: '',
      isAdvancedQuery: false,
      querySelectOption: '',
      objectId: '',
    }), //列表配置
    formEventConfig = ref<FormEventColumnConfig>(), //表单事件配置
    treeData = ref<any[]>([]), //树结构数据
    selectId = ref<string>(), // 左侧菜单所选;
    formType = ref<string>(''), //弹窗类型：modal、drawer、normal
    formWidth = ref<number>(800), // 弹窗、抽屉宽度
    formHeight = ref(), // 弹窗高度
    formButtons = ref<buttonListInfo[]>([]), //表单自定义按钮
    menuId = ref<string>(''),
    pkField = ref<string>(''), //主表主键
    tableRef = ref(),
    innerColumns = ref({}),
    innerDataSource = ref({}),
    subFormList = ref<any[]>([]),
    formDesignType = ref(0);

  // 模板打印 入参参数
  let printData: {
    id: string;
    requestParamsConfigs: Array<InputParamItem>;
    requestHeaderConfigs: Array<InputParamItem>;
    requestBodyConfigs: Array<InputParamItem>;
  } = reactive({
    id: '',
    requestParamsConfigs: [],
    requestHeaderConfigs: [],
    requestBodyConfigs: [],
  });

  //展示在列表内的按钮
  const actionButtons = ref<string[]>([
    'view',
    'edit',
    'copyData',
    'delete',
    'startwork',
    'flowRecord',
    'pushorder',
  ]);
  const { notification } = useMessage();
  const { t } = useI18n();
  defineEmits(['register']);
  const selectedKeys = ref<string[]>([]);
  const selectedRowsData = ref<any[]>([]);

  const isDataAuth = ref<boolean>(false);

  const listTitle = ref<string>('');
  const pageParamsInfo = ref<any>({});
  const isShowFilter = ref(false);
  const showColumnIndex = ref<string>('');
  const clickColumnIndex = ref<string>('');
  const visibleFlowRecordModal = ref(false);
  const menuName = ref('');
  const menuCode = ref('');
  const pushorderInfo = ref();
  const schemaInitConfig = ref();
  const datasource = ref<any>([]);
  const listDataSource = ref<any>([]);
  const treeMenuSeleceted = ref({});

  const isNotable = computed(() => {
    return formDesignType.value === 3;
  });

  provide<boolean>('isCustomForm', true);
  const paths = path.split('/');
  menuId.value = paths.length > 0 ? paths[paths.length - 1] : '';
  const filterColumns = ref<BasicColumn[]>([]);
  const buttonConfigs = computed(() => {
    if (!listConfig.value.buttonConfigs) return;
    listConfig.value.buttonConfigs.map((item, index) => {
      if (item.code === 'delete') {
        //删除按钮放在最后
        listConfig.value.buttonConfigs.splice(index, 1);
        listConfig.value.buttonConfigs.push(item);
        return;
      }
      if (item.code === 'pushorder') {
        //推单按钮放在最前面
        listConfig.value.buttonConfigs.splice(index, 1);
        listConfig.value.buttonConfigs.unshift(item);
        return;
      }
    });
    return filterButtonAuth(listConfig.value.buttonConfigs.filter((x) => x.isUse));
  });

  const tableButtonConfig = computed(() => {
    return buttonConfigs.value?.filter(
      (x) => !actionButtons.value.includes(x.code) && x.showType !== 'inline',
    );
  });

  const actionButtonConfig = computed(() => {
    return buttonConfigs.value?.filter(
      (x) => actionButtons.value.includes(x.code) || x.showType === 'inline',
    );
  });

  const filterClass = (column, filtered) => {
    return (isShowFilter.value && column.dataIndex === showColumnIndex.value) ||
      column.dataIndex === clickColumnIndex.value ||
      filtered
      ? 'show'
      : 'hide';
  };

  const visibleLookProcessRef = ref(false);
  const processIdRef = ref('');

  const visibleLaunchProcessRef = ref(false);
  const schemaIdRef = ref('');
  const formDataRef = ref();
  const rowKeyData = ref();
  const draftsId = ref();
  const pushFormId = ref();
  const pushBtnRef = ref();
  const pushbtnleft = ref();
  const isShowBtn = ref(false);
  const hasListCheckbox = ref(false);
  const isShowIndex = ref(true);

  const visibleApproveProcessRef = ref(false);
  const taskIdRef = ref('');

  const formIdComputedRef = ref('');

  const visiblePrintPreview = ref(false);
  const visibleExport = ref(false);

  const apiConfig = ref([]);
  const listApiConfig = ref({});
  const dataSource = ref([]);
  const leftMenuIndex = ref(0);

  let hasExecuteFieldParams = computed(() => {
    const executeButton = buttonConfigs.value?.filter((x) => !x.isDefault && x.setting?.length);
    if (executeButton && executeButton.length <= 0) return false;
    const hasFieldParams = executeButton?.find((btn) => {
      return btn.setting.find((set) => {
        return set.operateConfig.apiConfig?.apiParams?.find((par) => {
          return par.tableInfo?.find(
            (info) => info.bindType === 'data' && info.value.includes('bindField'),
          );
        });
      });
    });
    let FieldParams = !!hasFieldParams;
    if (!FieldParams) {
      const hasExcelFieldParams = executeButton?.find((btn) => {
        return btn.setting.find((set) => {
          return set?.ruleConfig?.processParamConfigs.find((info) => {
            return info.assignmentType === AssignmentTypeToRuleType.FORM;
          });
        });
      });
      FieldParams = !!hasExcelFieldParams;
    }
    return FieldParams;
  });
  const btnEvent = {
    view: handleView,
    add: handleAdd,
    edit: handleEdit,
    delete: handleDelete,
    batchdelete: handleBatchdelete,
    batchSetUserId: handleBatchSetUserId,
    import: handleImport,
    export: handleExport,
    print: handlePrint,
    copyData: handleCopyData,
    pushorder: handlePushorder,
  };

  const isCardList = computed(() => {
    return listConfig.value?.listStyle === 'card';
  });

  const [registerModal, { openModal }] = useModal();
  const [registerDrawer, { openDrawer }] = useDrawer();
  const [registerImportModal, { openModal: openImportModal }] = useModal();
  const [registerRuleUserModal, { openModal: openRuleUserModal }] = useModal();
  const [registerPushModal, { openModal: openPushModal }] = useModal();

  const [
    registerTable,
    { reload, setProps, getForm, setSelectedRowKeys, getRawDataSource, setColumns, setLoading },
  ] = useTable({
    title: '',
    columns,
    formConfig: {
      rowProps: {
        gutter: 16,
      },
      schemas: searchFormSchema,
      showResetButton: false,
    },
    beforeFetch: (pageParams) => {
      //发送请求默认新增  左边树结构所选机构id
      const newParams = {
        releaseId: menuId.value,
        params: { ...pageParams },
        order: pageParams.order,
        field: pageParams.field,
      };
      pageParamsInfo.value = {
        releaseId: menuId.value,
        params: pageParams,
      };
      //如果有左侧菜单 需要加上左侧树 所选项  作为参数
      if (listConfig.value.isLeftMenu && selectId.value !== undefined) {
        pageParams[listConfig.value.leftMenuConfig![leftMenuIndex.value]!.listFieldName as string] =
          selectId.value;
      }
      newParams['headers'] = {
        FormId: formIdComputedRef.value,
        PK: pkField.value,
      };
      return newParams;
    },
    afterFetch: (res) => {
      handleFilterAndRowSpan(res);
      selectedKeys.value = [];
      selectedRowsData.value = [];
      setSelectedRowKeys([]);
      setColumns(filterColumns.value);

      if (isCardList.value) {
        listDataSource.value = res;
        getDataList(res);
        return [];
      } else {
        setColumns(filterColumns.value);
      }
      return res;
    },
    useSearchForm: true,
    showTableSetting: true,
    listPageMode,
    leftTreeShow,
    striped: false,
    isFilterByDataSoure: true,
    notUseFilterValueSearch: true,
    actionColumn: {
      width: 160,
      title: t('操作'),
      dataIndex: 'action',
      slots: { customRender: 'action' },
    },
    customRow,
    tableSetting: {
      size: false,
    },
    isAdvancedQuery: false,
    querySelectOption: '',
    objectId: '',
  });

  function handleFilterClick(column) {
    clickColumnIndex.value = column.dataIndex;
  }

  function customRow(record: Recordable) {
    return {
      onClick: () => {
        let selectedRowKeys = [...selectedKeys.value];
        if (selectedRowKeys.indexOf(record[pkField.value]) >= 0) {
          let index = selectedRowKeys.indexOf(record[pkField.value]);
          selectedRowKeys.splice(index, 1);
        } else {
          selectedRowKeys.push(record[pkField.value]);
        }
        selectedKeys.value = selectedRowKeys;
        setSelectedRowKeys(selectedKeys.value);
      },
      ondblclick: () => {
        if (record.isCanEdit && hasPermission(`${menuCode.value}:edit`)) {
          handleEdit(record);
        }
      },
    };
  }
  function buttonClick(code) {
    if (code.includes(PrintButton.CODE)) {
      printTemplate(code);
    } else {
      btnEvent[code]();
    }
  }
  async function customButtonClick(btn) {
    const executeButton = buttonConfigs.value?.find((x) => x.code === btn.code);
    if (!executeButton) return;
    let selectedKey = hasExecuteFieldParams.value ? selectedKeys.value : '';
    let selectedRows = selectedRowsData.value;
    let res = executeCustomEvent(
      executeButton.setting,
      getFormExecute,
      menuId.value,
      selectedKey,
      selectedRows,
    );
    if (res) {
      setTimeout(() => {
        reload();
      }, 500);
    }
  }

  async function handleCustomClick(data) {
    const executeButton = buttonConfigs.value?.find((x) => x.code === data.code);
    if (!executeButton) return;
    let selectedKey = hasExecuteFieldParams.value ? [data.record[pkField.value]] : '';
    executeCustomEvent(executeButton.setting, getFormExecute, menuId.value, selectedKey, [
      data.record,
    ]);
    setTimeout(() => {
      reload();
    }, 500);
  }
  // 模板打印
  async function printTemplate(code) {
    if (!selectedKeys.value.length) {
      notification.warning({
        message: t('提示'),
        description: t('请选择数据'),
      });
      return;
    }
    if (selectedKeys.value.length > 1) {
      notification.warning({
        message: t('提示'),
        description: t('只能选择一条数据进行操作'),
      });
      return;
    }
    try {
      let record;
      if (isNotable.value) {
        const viewConfig = (apiConfig.value as ApiConfig[]).find((item) => item.value === 'view');
        const record = await apiConfigFunc(viewConfig, false, selectedRowsData.value[0]);
        const listConfig = (apiConfig.value as ApiConfig[]).find(
          (item) => item.value === 'view',
        )?.outputConfig;
        for (let key in record) {
          listConfig?.forEach((config) => {
            if (config.apiField === key) {
              record[config.bindField!] = record[key];
            }
          });
        }
      } else {
        let id = selectedKeys.value[0];
        record = await getFormExecute({ releaseId: menuId.value, id: id });
      }
      const res = await getPrintConfigInfo(code, printMenuId.value);

      if (res.enabledMark == null) {
        notification.warning({
          message: t('提示'),
          description: t('当前功能未绑定打印模板，请绑定后再进行模板打印。'),
        });
        return;
      }
      if (res.enabledMark == 0) {
        notification.warning({
          message: t('提示'),
          description: t('找不到打印模板，请联系管理员。'),
        });
        return;
      }
      printData.id = res.schemaId;
      if (res.id && res.apiConfig) {
        let json = JSON.parse(res.apiConfig);
        if (json.requestParamsConfigs && json.requestParamsConfigs.length > 0) {
          printData.requestParamsConfigs = json.requestParamsConfigs.map((ele) => {
            if (ele.config && record[ele.config] != undefined) {
              ele.value = record[ele.config];
            }
            return ele;
          });
        }
        if (json.requestHeaderConfigs && json.requestHeaderConfigs.length > 0) {
          printData.requestHeaderConfigs = json.requestHeaderConfigs.map((ele) => {
            if (ele.config && record[ele.config] != undefined) {
              ele.value = record[ele.config];
            }
            return ele;
          });
        }
        if (json.requestBodyConfigs && json.requestBodyConfigs.length > 0) {
          printData.requestBodyConfigs = json.requestBodyConfigs.map((ele) => {
            if (ele.config && record[ele.config] != undefined) {
              ele.value = record[ele.config];
            }
            return ele;
          });
        }
        visiblePrintPreview.value = true;
      } else {
        notification.warning({
          message: t('提示'),
          description: t('当前功能未绑定打印模板，请绑定后再进行模板打印。'),
        });
      }
    } catch (error) {}
  }
  function onSelectChange(rowKeys: [], selectedRows) {
    selectedKeys.value = rowKeys;
    selectedRowsData.value = selectedRows;

    setSelectedRowKeys(selectedKeys.value);
  }

  function handleColumnChange(data, checkIndex, checkSelect) {
    isShowIndex.value = checkIndex;
    hasListCheckbox.value = checkSelect;
    const showColumns = data.filter((x) => x.visible).map((x) => x.dataIndex);
    const columns = filterColumns.value.filter((x) => showColumns.includes(x.dataIndex));
    getDataList(listDataSource.value, columns);
  }

  const searchHeight = ref(0);
  function handleTreeChange(val, headerHeight) {
    searchHeight.value = headerHeight;
    leftTreeShow.value = val;
  }

  function getDataList(data, columns?) {
    datasource.value = [];
    if (data?.length) {
      data.forEach((item) => {
        let listData = {
          id: item.id,
          workflowData: item.workflowData,
        };
        const col = columns || filterColumns.value;
        col.forEach((col) => {
          for (let key in item) {
            if (col.dataIndex === key) {
              let value = item[key];
              if (col.componentType === 'money-chinese') {
                value = moneyChineseData(value);
              }
              listData[col.title as string] = {
                value,
                align: col.align,
                aRow: col.aRow,
                textBold: col.textBold,
              };
            }
          }
        });

        datasource.value.push(listData);
      });
    }
  }
  function getData(data) {
    let dataObj: any = {};
    for (let key in data) {
      if (key !== 'id' && key !== 'workflowData' && key !== 'isCanEdit') {
        dataObj[key] = data[key];
      }
    }
    return dataObj;
  }

  function handleAdd() {
    // 发起审批按钮的配置中 启用并新增即审批 打开发起流程
    if (
      schemaInitConfig.value &&
      schemaInitConfig.value.enabled &&
      schemaInitConfig.value.enabledAddApprove
    ) {
      visibleLaunchProcessRef.value = true;
    } else {
      formProps = buildOption(formJson.value.formJson, false);

      const info = {
        isUpdate: false,
        releaseId: menuId.value,
        pkField: pkField.value,
        formEventConfig,
        formProps,
        menuName,
        isNotable: isNotable.value,
        apiConfig: apiConfig.value,
      };
      if (listPageMode.value === LIST_MODE.VERTICAL) {
        modeActiveKey.value = 0;
        FormNormalRef.value.handleInner(info);
      } else if (listPageMode.value === LIST_MODE.HORIZONTAL) {
        horizontalTitle.value = '新增';
        horizontalEmpty.value = false;
        FormNormalRef.value.handleInner(info);
      } else {
        formType.value === 'modal' ? openModal(true, info) : openDrawer(true, info);
      }
    }
  }

  async function handleEdit(record: Recordable) {
    try {
      let hasIn = handleHasEnableLocke(buttonConfigs.value, 'edit');
      if (hasIn) {
        let res = await handleOpenFormEnableLockeData(
          record[pkField.value],
          formIdComputedRef.value,
        );
        if (res !== null) {
          return;
        }
      }
      let info: any = {
        id: record[pkField.value],
        releaseId: menuId.value,
        pkField: pkField.value,
        isUpdate: true,
        formEventConfig,
        formProps,
        menuName,
      };
      if (isNotable.value) {
        info = {
          record,
          isUpdate: true,
          formEventConfig,
          formProps,
          menuName,
          isNotable: isNotable.value,
          apiConfig: apiConfig.value,
        };
      }
      if (listPageMode.value === LIST_MODE.VERTICAL) {
        let field = pkField.value;
        if (filterColumns.value.length > 0) field = filterColumns.value[0].dataIndex as string;
        modeActiveKey.value = modePanes.value.length + (hasAddBtn.value ? 0 : 1);
        let idx = modePanes.value.findIndex((o) => {
          return o.content?.id == record[pkField.value];
        });
        if (idx >= 0) {
          modeActiveKey.value = idx + (hasAddBtn.value ? 0 : 1);
          modePanes.value.splice(idx, 1, {
            key: modeActiveKey.value,
            title: record[field],
            closable: true,
            content: info,
          });
        } else {
          modePanes.value.push({
            key: modeActiveKey.value,
            title: record[field],
            closable: true,
            content: info,
          });
        }

        FormNormalRef.value.handleInner(info);
      } else if (listPageMode.value === LIST_MODE.HORIZONTAL) {
        horizontalTitle.value = '编辑';
        horizontalEmpty.value = false;
        FormNormalRef.value.handleInner(info);
      } else {
        formType.value === 'modal' ? openModal(true, info) : openDrawer(true, info);
      }
    } catch (error) {}
  }

  function handleView(record: Recordable) {
    let info: any = {
      id: record[pkField.value],
      releaseId: menuId.value,
      pkField: pkField.value,
      isView: true,
      formEventConfig,
      formProps,
      menuName,
    };
    if (isNotable.value) {
      info = {
        record,
        isView: true,
        formEventConfig,
        formProps,
        menuName,
        isNotable: isNotable.value,
        apiConfig: apiConfig.value,
      };
    }
    if (listPageMode.value === LIST_MODE.HORIZONTAL) {
      horizontalTitle.value = '查看';
      horizontalEmpty.value = false;
      FormNormalRef.value.handleInner(info);
    } else {
      formType.value === 'modal' ? openModal(true, info) : openDrawer(true, info);
    }
  }

  function handleCopyData(record: Recordable) {
    let info: any = {
      id: record[pkField.value],
      releaseId: menuId.value,
      pkField: pkField.value,
      isCopy: true,
      formEventConfig,
      formProps,
      menuName,
    };
    if (isNotable.value) {
      info = {
        record,
        isCopy: true,
        formEventConfig,
        formProps,
        menuName,
        isNotable: isNotable.value,
        apiConfig: apiConfig.value,
      };
    }
    formType.value === 'modal' ? openModal(true, info) : openDrawer(true, info);
  }

  async function handleDelete(record: Recordable) {
    if (isNotable.value) {
      Modal.confirm({
        title: '提示信息',
        icon: createVNode(ExclamationCircleOutlined),
        content: '是否确认删除？',
        okText: '确认',
        cancelText: '取消',
        async onOk() {
          const deleteConfig = (apiConfig.value as ApiConfig[]).find(
            (item) => item.value === 'delete',
          );
          try {
            await apiConfigFunc(deleteConfig, false, record);
            notification.success({
              message: 'Tip',
              description: t('删除成功！'),
            });
            getDataSource(getForm().getFieldsValue());
          } catch (error) {
            notification.error({
              message: 'Tip',
              description: t('删除失败！'),
            });
          }
        },
        onCancel() {},
      });
    } else {
      deleteList([record[pkField.value]]);
    }
  }

  async function handlePrint() {
    const dataSourceInfo = Array.isArray(getRawDataSource())
      ? getRawDataSource()
      : getRawDataSource().list;
    const json = generateTableJson(
      filterColumns.value,
      isNotable.value ? dataSource.value : dataSourceInfo,
    );
    const properties = filterColumns.value.map((item) => item.title);
    printJS({
      printable: json,
      properties: properties,
      type: 'json',
    });
  }

  async function handlePushorder(record) {
    if (pushorderInfo.value?.setting.type === 'form') {
      pushFormId.value = record.id;
      isShowBtn.value = !isShowBtn.value;
      if (isShowBtn.value) {
        nextTick(() => {
          pushbtnleft.value = `-${pushBtnRef.value?.offsetWidth}px`;
        });
      }
    } else {
      Modal.confirm({
        title: '提示信息',
        icon: createVNode(ExclamationCircleOutlined),
        content: '确定需要推单吗？',
        okText: '确认',
        cancelText: '取消',
        onOk() {
          try {
            apiConfigFunc(pushorderInfo.value?.setting.apiConfig, false, record).then(() => {
              notification.success({
                message: 'Tip',
                description: '执行成功',
              });
            });
          } catch (error) {}
        },
      });
    }
  }

  async function openPushorder(record) {
    isShowBtn.value = false;
    let rowInfo;
    if (isNotable.value) {
      const viewConfig = (apiConfig.value as ApiConfig[]).find((item) => item.value === 'view');
      rowInfo = await apiConfigFunc(viewConfig, false, selectedRowsData.value[0]);
      const listConfig = (apiConfig.value as ApiConfig[]).find(
        (item) => item.value === 'view',
      )?.outputConfig;
      for (let key in rowInfo) {
        listConfig?.forEach((config) => {
          if (config.apiField === key) {
            rowInfo[config.bindField!] = rowInfo[key];
          }
        });
      }
    } else {
      rowInfo = await getFormExecute({ releaseId: menuId.value, id: pushFormId.value });
    }
    openPushModal(true, {
      info: record,
      rowInfo,
      isCustom: true,
    });
  }

  function handleBatchdelete() {
    if (!selectedKeys.value.length) {
      notification.warning({
        message: t('提示'),
        description: t('请选择需要删除的数据'),
      });
      return;
    }
    if (isCardList.value) {
      selectedRowsData.value = datasource.value.filter((x) => selectedKeys.value.includes(x.id));
    }
    //与工作流相关的数据不能进行批量删除
    const cantDelete = selectedRowsData.value.filter((x) => {
      return (x.workflowData?.enabled && x.workflowData?.status) || !!x.workflowData?.processId;
    });
    if (cantDelete.length) {
      notification.warning({
        message: 'Tip',
        description: t('含有不能删除的数据'),
      });
      return;
    }
    if (isNotable.value) {
      Modal.confirm({
        title: '提示信息',
        icon: createVNode(ExclamationCircleOutlined),
        content: '是否确认删除？',
        okText: '确认',
        cancelText: '取消',
        async onOk() {
          const batchdeleteConfig = buttonConfigs.value?.find(
            (item) => item.code === 'batchdelete',
          )?.apiConfig;
          try {
            await apiConfigFunc(batchdeleteConfig, false, selectedRowsData.value);
            notification.success({
              message: 'Tip',
              description: t('删除成功！'),
            });
            getDataSource(getForm().getFieldsValue());
          } catch (error) {
            notification.error({
              message: 'Tip',
              description: t('删除失败！'),
            });
          }
        },
        onCancel() {},
      });
    } else {
      deleteList(selectedKeys.value);
    }
  }

  function deleteList(ids) {
    Modal.confirm({
      title: t('提示信息'),
      icon: createVNode(ExclamationCircleOutlined),
      content: t('是否确认删除？'),
      okText: t('确认'),
      cancelText: t('取消'),
      onOk() {
        deleteFormExecute({ releaseId: menuId.value, ids }).then((_) => {
          handleSuccess();
          notification.success({
            message: t('提示'),
            description: t('删除成功！'),
          });
        });
      },
      onCancel() {},
    });
  }

  function handleBatchSetUserId() {
    if (!isDataAuth.value) {
      Modal.confirm({
        title: t('操作失败'),
        icon: createVNode(CloseCircleOutlined, { style: 'color: #ed6f6f' }),
        content: createVNode(
          'div',
          { style: 'color: #999' },
          t('当前功能未配置数据权限，请配置后再进行操作。'),
        ),
        centered: true,
        okText: t('确定'),
        cancelText: t('取消'),
        onOk() {
          reload();
        },
        onCancel() {
          reload();
        },
      });
      return;
    }
    if (!selectedKeys.value.length) {
      notification.warning({
        message: t('提示'),
        description: t('请选择需要设置权限的数据'),
      });
      return;
    }
    openRuleUserModal(true, {
      rowKey: pkField.value,
      columns: filterColumns.value,
      dataSource: selectedRowsData.value,
      setDataAuthApi: setDataAuth, //设置权限的接口地址
      params: { releaseId: menuId.value },
      isCustomForm: true,
    });
  }

  function handleExport() {
    if (isNotable.value) {
      noTableExport();
    } else {
      visibleExport.value = true;
    }
  }

  function noTableExport() {
    const exportValue: Array<string>[] = [];
    const title = columns.map((col) => col.title) as string[];
    exportValue.push(title);

    dataSource.value.forEach((item, index) => {
      columns.forEach((col) => {
        if (!exportValue[index + 1]) {
          exportValue[index + 1] = [];
        }
        exportValue[index + 1].push(item[col.dataIndex as string] || '');
      });
    });

    const dataInfo = XLSX.utils.aoa_to_sheet(exportValue);
    /**设置标题头背景色 */
    for (const key in dataInfo) {
      // 第一行，表头
      if (key.replace(/[^0-9]/gi, '') === '1') {
        dataInfo[key].s = {
          fill: {
            //背景色
            fgColor: {
              rgb: 'C0C0C0',
            },
          },
          font: {
            //字体
            name: '宋体',
            sz: 12,
            bold: true,
          },
          border: {
            //边框
            bottom: {
              style: 'thin',
              color: '#9a9a9a',
            },
            right: {
              style: 'thin',
              color: '#9a9a9a',
            },
          },
          alignment: {
            horizontal: 'center', //水平居中
            vertical: 'center',
          },
        };
      }
    }
    dataInfo['!rows'] = [{ hpx: 25 }];

    // 创建工作簿
    const wb = XLSX.utils.book_new();
    // 将工作表放入工作簿中
    XLSX.utils.book_append_sheet(wb, dataInfo);
    // 生成文件并下载
    XLSX.writeFile(wb, `${menuName.value}.xlsx`);
  }

  async function handleExportSuccess(cols) {
    const fileName = listTitle.value;
    const res = await exportForm({ ...pageParamsInfo.value, columns: cols });
    visibleExport.value = false;

    downloadByData(
      res.data,
      `${fileName}.xlsx`,
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    );
    reload();
  }

  function handleImport() {
    openImportModal(true, {
      title: t('快速导入'),
      downLoadUrl: '/form/execute/export',
      type: 'POST',
    });
  }

  function handleImportSuccess() {
    reload();
  }
  function handleRedo() {
    if (isNotable.value) {
      getDataSource(getForm().getFieldsValue());
    }
  }
  function handleSuccess(isReload?) {
    selectedKeys.value = [];
    selectedRowsData.value = [];
    setSelectedRowKeys([]);
    if (isNotable.value) {
      getDataSource(getForm().getFieldsValue());
    }
    if (isReload === false) {
      tabChangeIsReload.value = true;
    } else {
      reload();
    }
  }
  function handleFormSuccess() {
    handleSuccess();
    handleCloseFormEnableLocke(buttonConfigs.value, 'edit');
  }
  function handleFormCancel() {
    handleCloseFormEnableLocke(buttonConfigs.value, 'edit');
  }
  function handleViewWorkflow(record: Recordable) {
    if (record.workflowData) {
      visibleLookProcessRef.value = true;
      processIdRef.value = record.workflowData.processId;
    }
  }
  function handleFlowRecord(record: Recordable) {
    if (record.workflowData) {
      visibleFlowRecordModal.value = true;
      processIdRef.value = record.workflowData?.processId;
    }
  }
  async function handleLaunchProcess(record: Recordable) {
    try {
      let hasIn = handleHasEnableLocke(buttonConfigs.value, 'startwork');
      if (hasIn) {
        await handleOpenFormEnableLockeData(record[pkField.value], formIdComputedRef.value);
      }
      if (record.workflowData) {
        if (record.workflowData.draftId) {
          let res = await getDraftInfo(record.workflowData.draftId);
          let data = isValidJSON(res.formData);
          if (data) {
            for (let key in data) {
              if (key.includes(formIdComputedRef.value)) {
                formDataRef.value = data[key];
              }
            }
          }
          draftsId.value = record.workflowData.draftId;
        } else {
          //
          const result = await getFormExecuteWorkflow({
            formId: formIdComputedRef.value,
            id: record[pkField.value],
          });
          formDataRef.value = result;
        }
        rowKeyData.value = record[pkField.value];
        visibleLaunchProcessRef.value = true;
        schemaIdRef.value = record.workflowData.schemaId;
      }
    } catch (error) {}
  }
  async function handleApproveProcess(record: Recordable) {
    try {
      let hasIn = handleHasEnableLocke(buttonConfigs.value, 'startwork');
      if (hasIn) {
        await handleOpenFormEnableLockeData(record[pkField.value], formIdComputedRef.value);
      }
      visibleApproveProcessRef.value = true;
      schemaIdRef.value = record.workflowData.schemaId;
      processIdRef.value = record.workflowData.processId;
      taskIdRef.value = record.workflowData.taskIds[0];
    } catch (error) {}
  }
  function handleCloseLaunch() {
    visibleLaunchProcessRef.value = false;
    draftsId.value = '';
    if (listPageMode.value === LIST_MODE.VERTICAL) {
      modeActiveKey.value = 1;
    }
    reload();
    handleCloseFormEnableLocke(buttonConfigs.value, 'startwork');
  }
  function handleCloseApproval() {
    visibleApproveProcessRef.value = false;
    reload();
    handleCloseFormEnableLocke(buttonConfigs.value, 'startwork');
  }
  function handleFilterAndRowSpan(dataSource) {
    filterColumns.value.map((column: any) => {
      if (column.onFilter) {
        const info = dataSource.map((item) => item[column.dataIndex!]);
        column.filters = [...new Set(info)].map((item) => {
          return {
            text: item,
            value: item,
          };
        });
        column.customHeaderCell = () => {
          return {
            onmouseenter: () => {
              isShowFilter.value = true;
              showColumnIndex.value = column.dataIndex;
              clickColumnIndex.value = '';
            },
            onmouseleave: () => {
              isShowFilter.value = false;
              showColumnIndex.value = '';
            },
          };
        };
      }
    });
    //处理列表页行合并
    let colobj = listConfig.value.columnConfigs.find((o) => o.rowSpan);
    if (colobj) {
      let colName = colobj.columnName;
      let curI = 0;
      let cur = dataSource[curI][colName];
      let arr: number[] = [];
      dataSource.forEach((o, i) => {
        arr.push(1);
        if (i >= 1) {
          if (o[colName] == cur) {
            arr[curI] += 1;
            arr[i] = 0;
          } else {
            curI = i;
            cur = dataSource[curI][colName];
          }
        }
      });
      filterColumns.value.forEach((item) => {
        if (item.dataIndex == colName) {
          item.customCell = (_, index) => {
            let obj = { rowSpan: 1 };
            arr.forEach((o, i) => {
              if (index == i) {
                obj = { rowSpan: o };
              }
            });
            return obj;
          };
        }
      });
    }
  }
  const getDataSource = async (value, pagination?) => {
    setLoading(true);
    let page = { total: 0, ...pagination };
    dataSource.value = await apiConfigFunc(listApiConfig.value, false, value, null, page);
    if (dataSource.value && !Array.isArray(dataSource.value)) {
      dataSource.value = [];
      return;
    }
    const listCol = (apiConfig.value as ApiConfig[]).find(
      (item) => item.value === 'view',
    )?.outputConfig;
    dataSource.value?.map((item) => {
      for (let key in item) {
        listCol?.forEach((config) => {
          if (config.apiField === key) {
            item[config.bindField!] = item[key];
          }
        });
      }
    });
    setProps({ dataSource: dataSource.value, pagination: { total: Number(page.total || 0) } });
    handleFilterAndRowSpan(dataSource.value);
    setColumns(filterColumns.value);
    setLoading(false);
  };
  function handleTableChange(page) {
    let value = getForm().getFieldsValue();
    getDataSource(value, page);
  }
  function handleClosePrintPreview() {
    visiblePrintPreview.value = false;
    reload();
  }
  const formJson = ref();
  const hasAddBtn = ref();
  const modeActiveKey = ref(1);
  const tabChangeIsReload = ref(false);
  const FormNormalRef = ref();
  const modePanes = ref<{ title: string; content?: any; key: number; closable?: boolean }[]>([
    {
      key: 0,
      title: '新增',
      closable: false,
    },
    {
      key: 1,
      title: '列表页',
      closable: false,
    },
  ]);
  // watch(
  //   () => modeActiveKey.value,
  //   (val) => {
  //     if (val === 0 && hasAddBtn.value) {
  //       handleAdd();
  //     } else if (val === 1) {
  //       if (tabChangeIsReload.value) reload();
  //       tabChangeIsReload.value = false;
  //     } else if (val > 1) {
  //       let idx = hasAddBtn.value ? val : val - 1;
  //       if (modePanes.value[idx]) FormNormalRef.value.handleInner(modePanes.value[idx].content);
  //     }
  //   },
  // );
  async function handleTabsClick(val) {
    if (val === 0 && hasAddBtn.value) {
      handleAdd();
    } else if (val === 1) {
      if (tabChangeIsReload.value) reload();
      tabChangeIsReload.value = false;
    } else if (val > 1) {
      let idx = hasAddBtn.value ? val : val - 1;
      if (modePanes.value[idx]) {
        try {
          let hasIn = handleHasEnableLocke(buttonConfigs.value, 'edit');
          if (hasIn) {
            await handleOpenFormEnableLockeData(
              modePanes.value[idx].content.id,
              formIdComputedRef.value,
            );
          }
          FormNormalRef.value.handleInner(modePanes.value[idx].content);
        } catch (error) {}
      }
    }
  }
  onMounted(async () => {
    //获取发布数据
    const releaseResult = await getFormRelease(menuId.value as string);
    const configJson = JSON.parse(releaseResult.configJson) as FormReleaseConfig;
    formIdComputedRef.value = releaseResult.formId;
    menuName.value = configJson.menuConfig.name;
    menuCode.value = configJson.menuConfig.code;
    listPageMode.value = configJson.listConfig?.listStyle || LIST_MODE.DEFAULT;
    //设置Tab标题
    setTitle(menuName.value);
    //设置浏览器标题
    useTitle(` ${menuName.value} - ${title} `);
    if (!Array.isArray(configJson.listConfig!.leftMenuConfig)) {
      configJson.listConfig!.leftMenuConfig = [configJson.listConfig!.leftMenuConfig!];
    }
    //设置是否需要左侧菜单
    listConfig.value = cloneDeep(configJson.listConfig!);
    listApiConfig.value = listConfig.value.apiConfig || {};
    // 获取发起审批按钮配置信息

    let startWorkArr = buttonConfigs.value?.find((x) => x.code === 'startwork');
    if (startWorkArr) {
      schemaInitConfig.value = startWorkArr.schemaInitConfig;
      if (
        schemaInitConfig.value &&
        schemaInitConfig.value.config &&
        schemaInitConfig.value.config.id
      ) {
        let schemeId = await getFormSchemaId(schemaInitConfig.value.config.id);
        if (schemeId) schemaIdRef.value = schemeId;
      }
    }
    pushorderInfo.value = buttonConfigs.value?.find((x) => x.code === 'pushorder');
    hasAddBtn.value = buttonConfigs.value?.find((x) => x.code === 'add');

    if (!hasAddBtn.value) {
      modePanes.value.splice(0, 1);
    }
    listTitle.value = listConfig.value.listTitle || menuName.value;
    let { queryConfigs, columnConfigs, isHeaderMerging, headerMergingData } =
      configJson.listConfig!;

    //如果设置了左侧菜单  需要请求菜单数据
    if (listConfig.value.isLeftMenu) {
      fetchLeftData();
    }
    //获取表单模板数据
    const templateResult = await getFormTemplate(releaseResult.formId);
    formDesignType.value = templateResult.formDesignType;

    formJson.value = JSON.parse(templateResult.formJson) as GeneratorConfig;
    isDataAuth.value = formJson.value.isDataAuth || false;
    apiConfig.value = formJson.value.apiConfig || [];

    const mainTable = formJson.value.tableConfigs?.find((item) => item.isMain);
    pkField.value = mainTable?.pkField || 'id';
    if (onlyShowAddForm.value && hasAddBtn.value) {
      nextTick(() => {
        handleAdd();
      });
    }
    //
    //构建表单Props
    formProps = buildOption(formJson.value.formJson, false);
    formType.value = formJson.value.formJson.config.formType!;
    formWidth.value = formJson.value.formJson.config.formWidth || 800;
    formHeight.value = formJson.value.formJson.config.formHeight;
    formButtons.value = formJson.value.formJson.buttonList || [];
    formEventConfig.value = formJson.value.formEventConfig;
    //查询配置转换为schema
    if (listConfig.value.isAdvancedQuery) {
      let tempArr = JSON.parse(listConfig.value.querySelectOption);
      queryConfigs = tempArr.map((tempEle) => {
        return {
          fieldName: tempEle.value,
          isDate: ['time', 'date'].includes(tempEle.type) || !!tempEle.isDate,
        };
      });
    }
    [searchFormSchema, searchDate] = ConvertQueryConfigToFormSchema(
      queryConfigs,
      formProps.schemas!,
      formJson.value.formJson.list,
    );

    //列表配置 转换为 BasicColumn
    if (isHeaderMerging) {
      columns = ConvertColumnConfigToBasicColumn(headerMergingData);
      filterColumns.value = filterHeaderColumnAuth(columns);
      setProps({
        bordered: true,
      });
    } else {
      columns = ConvertColumnConfigToBasicColumn(columnConfigs);
      filterColumns.value = filterColumnAuth(columns);
    }
    hasListCheckbox.value = tableButtonConfig.value!.some(
      (x) =>
        ['batchdelete', 'batchSetUserId'].includes(x.code) ||
        x.isDefault == false ||
        x.code.includes(PrintButton.CODE),
    );
    getSubFormList(formProps.schemas);
    //是否展示多选按钮
    if (hasListCheckbox.value) {
      setProps({
        rowSelection: {
          onChange: onSelectChange,
        },
      });
    }
    if (isNotable.value) {
      getDataSource(getForm().getFieldsValue());
      setProps({
        handleSearchInfoFn(info) {
          getDataSource(info);
        },
      });
    } else {
      setProps({
        api: getFormExecutePage,
        pagination: {
          pageSize: listConfig.value.pageSize ? listConfig.value.pageSize : 10,
        },
      });
    }
    //重新设定table组件props
    setProps({
      title: listTitle.value,
      rowKey: pkField.value,
      columns: filterColumns.value,
      formConfig: {
        labelWidth: 100,
        schemas: searchFormSchema,
        fieldMapToTime: searchDate.map((date) => {
          return [
            date.fieldName!,
            [date.fieldName + 'Start', date.fieldName + 'End'],
            date.format,
            true,
          ];
          // [['fieldTime', ['startTime', 'endTime'], 'YYYY-MM-DD']],
        }),
        showResetButton: false,
      },
      isAdvancedQuery: listConfig.value.isAdvancedQuery,
      querySelectOption: JSON.stringify(searchFormSchema),
      objectId: menuId.value, ////系统表单formId,自定义表单releaseId的id值
      actionColumn: {
        width:
          (actionButtonConfig.value!.length > 3
            ? listSpliceNum.value
            : actionButtonConfig.value!.length) *
          (buttonConfigs.value &&
          Array.isArray(buttonConfigs.value) &&
          buttonConfigs.value.length > 0 &&
          buttonConfigs.value?.some((x) => x.code === 'startwork')
            ? 130
            : 65),
        title: t('操作'),
        dataIndex: 'action',
        slots: { customRender: 'action' },
      },
      hasLeftTree: listConfig.value.isLeftMenu,
      useSearchForm: searchFormSchema.length > 0 ? true : false,
    });
    if (isCardList.value) {
      setProps({
        pagination: {
          pageSizeOptions: ['9', '12', '15', '18'],
          pageSize: 9,
        },
        actionColumn: undefined,
      });
    }
    // reload();
    setTimeout(() => {
      reload();
    }, 1);
  });

  const getSubFormList = (list) => {
    list?.map((item) => {
      if (['tab', 'grid', 'card'].includes(item.type)) {
        for (const child of item.children!) {
          getSubFormList(child.list);
        }
      } else if (item.type == 'table-layout') {
        for (const child of item.children!) {
          for (const sub of child.list) {
            getSubFormList(sub.children);
          }
        }
      } else if (item.type === 'form') {
        if (item.componentProps.isListView) {
          subFormList.value.push(item);
          innerColumns.value[item.field] = (item.componentProps! as FormSchema)
            .viewList!.filter((sub) => sub.checked)
            .map((sub) => {
              return {
                title: sub.label,
                dataIndex: sub.field,
                componentType: sub.componentType,
              };
            });
        }
      }
    });
  };

  function getActions(record: Recordable, isCardList: boolean): ActionItem[] {
    record.isCanEdit = false;
    const hasStartWorkButton = buttonConfigs.value?.some((x) => x.code === 'startwork');
    let actionsList: ActionItem[] = [];
    let editAndDelBtn: ActionItem[] = [];
    let pushorderBtn: ActionItem[] = [];
    let orderBtn: ActionItem[] = [];
    let flowRecordBtn: ActionItem = {};
    let hasFlowRecord = false;
    const showName = isCardList ? 'tooltip' : 'label';
    actionButtonConfig.value?.map((button) => {
      const icon = isCardList ? button.icon : '';
      let executeBtn = !button.isDefault && button.setting?.length;
      const btns: ActionItem = {
        ...button,
        icon,
        [showName]: button?.name,
        color: button.code === 'delete' ? 'error' : undefined,
        onClick: executeBtn
          ? handleCustomClick.bind(null, { record, code: button.code })
          : btnEvent[button.code]?.bind(null, record),
      };
      if (['edit', 'delete'].includes(button.code)) {
        editAndDelBtn.push(btns);
      } else if (!['pushorder', 'startwork', 'flowRecord'].includes(button.code)) {
        orderBtn.push(btns);
      }
      if (button.code === 'pushorder') {
        pushorderBtn.push({
          icon,
          [showName]: button?.name,
          onClick: btnEvent[button.code].bind(null, record),
        });
      }
      if (button.code === 'flowRecord') {
        hasFlowRecord = true;
        flowRecordBtn = {
          [showName]: '查看流转记录',
          icon: isCardList ? 'liuzhuanxinxi|svg' : '',
          onClick: handleFlowRecord.bind(null, record),
        };
      }
    });
    if (record.workflowData?.enabled) {
      if (!hasStartWorkButton) {
        record.isCanEdit = !record.workflowData.status;
        if (!record.workflowData.status) {
          actionsList = actionsList.concat(editAndDelBtn);
        }
        actionsList.unshift(...pushorderBtn, ...orderBtn, flowRecordBtn);

        return actionsList;
      }
      //与工作流有关联的表单
      if (record.workflowData.status) {
        //如果是本人需要审批的数据 就会有taskIds  所以需要修改绑定事件
        const act: ActionItem = {};
        if (record.workflowData.taskIds) {
          act[showName] = t('查看流程(待审批)');
          act.icon = isCardList ? 'daishenpi|svg' : '';
          act.onClick = handleApproveProcess.bind(null, record);
        } else {
          act[showName] =
            t('查看流程') +
            (record.workflowData.status === 'ACTIVE' ? t('(审批中)') : t('(已完成)'));
          act.icon = !isCardList
            ? ''
            : record.workflowData.status === 'ACTIVE'
            ? 'jinshenpi|svg'
            : 'shenpiwancheng|svg';
          act.onClick = handleViewWorkflow.bind(null, record);
        }
        actionsList.unshift(act);
        if (hasFlowRecord) {
          actionsList.splice(1, 0, flowRecordBtn);
        }
      } else {
        actionsList.unshift({
          icon: isCardList ? 'faqishenpi|svg' : '',
          [showName]: record.workflowData.draftId ? t('编辑草稿') : t('发起审批'),
          onClick: handleLaunchProcess.bind(null, record),
        });
        record.isCanEdit = true;
        actionsList = actionsList.concat(editAndDelBtn);
      }
    } else {
      if (!record.workflowData?.processId) {
        //与工作流没有关联的表单并且在当前页面新增的数据 如选择编辑、删除按钮则加上
        record.isCanEdit = true;
        actionsList = actionsList.concat(editAndDelBtn);
      }
    }
    actionsList.unshift(...pushorderBtn, ...orderBtn);

    return actionsList;
  }
  function getLessActions(record: Recordable, isCardList: boolean) {
    let list = getActions(record, isCardList);
    return list.slice(0, listSpliceNum.value);
  }
  function getMoreActions(record: Recordable, isCardList: boolean) {
    let list = getActions(record, isCardList);
    return list.slice(listSpliceNum.value);
  }
  function handleSelectTree(treeConditions) {
    if (isNotable.value) {
      getDataSource({ ...treeConditions[0] });
    } else {
      reload({ searchInfo: { treeConditions: treeConditions } });
    }
    treeMenuSeleceted.value[leftMenuIndex.value] = treeConditions;
  }
  function handleSelect(selectIds) {
    selectId.value = selectIds[0];
    const searchInfo = {
      [listConfig.value.leftMenuConfig![leftMenuIndex.value]!.listFieldName as string]:
        selectId.value,
    };
    if (isNotable.value) {
      getDataSource(searchInfo);
    } else {
      reload({
        searchInfo,
      });
    }
    leftTreeShow.value = false;
    treeMenuSeleceted.value[leftMenuIndex.value] = selectIds;
  }

  async function fetchLeftData() {
    //如果是数据字典
    if (listConfig.value.leftMenuConfig![leftMenuIndex.value]!.datasourceType === 'dic') {
      treeData.value = (await getDicDetailList({
        itemId: listConfig.value.leftMenuConfig![leftMenuIndex.value]!.dictionaryItemId,
      })) as unknown as TreeItem[];
    } else if (listConfig.value.leftMenuConfig![leftMenuIndex.value]!.datasourceType === 'static') {
      //如果是静态数据
      treeData.value = listConfig.value.leftMenuConfig![leftMenuIndex.value]!.staticData!;
    } else if (listConfig.value.leftMenuConfig![leftMenuIndex.value]!.datasourceType === 'api') {
      //如果是api
      treeData.value = (await apiConfigFunc(
        listConfig.value.leftMenuConfig![leftMenuIndex.value]!.apiConfig,
        false,
      )) as unknown as TreeItem[];
    }
    addRenderIcon(treeData.value);
  }

  async function leftTabChange() {
    await fetchLeftData();
    const value = treeMenuSeleceted.value[leftMenuIndex.value];
    if (!value) {
      reload();
    } else if (listConfig.value.leftMenuConfig![leftMenuIndex.value].datasourceType === 'tree') {
      handleSelectTree(value);
    } else {
      handleSelect(value);
    }
  }

  function addRenderIcon(data) {
    data.map((item) => {
      if (item.children?.length) addRenderIcon(item.children);
      return (item.renderIcon = item.children?.length ? 'parentIcon' : 'childIcon');
    });
  }

  function getInnerDataSource(id, field) {
    if (innerDataSource.value[id]) {
      return innerDataSource.value[id][field];
    }
    return [];
  }

  async function expandedRowsChange(isOpen, record) {
    if (!isOpen) return;
    const tableInfo = await getSubData({
      dataId: record.id,
      formId: formIdComputedRef.value,
    });
    innerDataSource.value[record.id] = tableInfo;
  }

  /**
   * QueryConfig 转换 为搜索栏 FormSchema
   * 根据查询字段 获取到 当前字段查询组件的类型
   * 普通类型：input
   * 远程组件：ApiSelect
   * 时间字段：RangePicker
   */
  function ConvertQueryConfigToFormSchema(
    queryConfigs: QueryConfig[],
    schemas: FormSchema[],
    list: ComponentOptionModel[],
  ): [FormSchema[], SearchDate[]] {
    const searchDate: SearchDate[] = [];
    const searchFormSchema = queryConfigs.map((config) => {
      if (!!config.isDate) {
        searchDate.push({
          fieldName: config.fieldName,
          format: config.format!,
        });
      }
      const schema = findSchema(schemas, config.fieldName);
      const [isNeedTrans, option] = whetherNeedToTransform(config, list);
      return handleSearchForm(option, schema, config, isNeedTrans, false) as FormSchema;
    });
    return [searchFormSchema, searchDate];
  }

  /**
   *
   * columnConfig转 BasicColumn
   * @param columnConfigs
   *
   */
  function ConvertColumnConfigToBasicColumn(columnConfigs: ColumnConfig[]): BasicColumn[] {
    return columnConfigs.map((config) => {
      const column: BasicColumn = {
        dataIndex: config.dataIndex ? config.dataIndex : config.columnName,
        title: config.label ?? config.title,
        columnName: config.columnName ? config.columnName : config.title,
        componentType: config.componentType,
        listStyle: config.componentProps?.listStyle,
        styleConfig: config.componentProps?.styleConfig,
        sorter: config.componentProps?.sorter ?? false,
        resizable: config.componentProps?.resizable ?? false,
        defaultHidden: false,
      };
      if (config.alignType) column.align = config.alignType as any;
      if (config.isTotal) column.total = true;
      if (!config.autoWidth && config.columnWidth) column.width = config.columnWidth;
      if (config.componentProps?.datasourceType === 'staticData') {
        column.customRender = ({ record }) => {
          const staticOptions = config.componentProps?.staticOptions;
          if (config.componentType === 'checkbox') {
            const valArr = record[config.columnName]?.split(',');
            return staticOptions
              .filter((x) => valArr.includes(x.value))
              ?.map((x) => x.label)
              .toString();
          }
          return staticOptions.filter((x) => x.value == record[config.columnName])[0]?.label;
        };
      }
      if (config.textBold) column.textBold = true;
      if (config.aRow) column.aRow = true;
      if (config.isFixed) {
        column.fixed = 'left';
      } else {
        column.fixed = false;
      }
      if (config.isFilter) {
        column.onFilter = (value, record) => {
          return record[config.columnName] === value;
        };
      }
      if (config.children && Array.isArray(config.children) && config.children.length > 0) {
        column.children = ConvertColumnConfigToBasicColumn(config.children);
      }
      return column;
    });
  }

  function handleTabsEdit(targetKey) {
    handleTabsRemove(targetKey);
    handleCloseFormEnableLocke(buttonConfigs.value, 'edit');
  }
  function handleTabsRemove(targetKey) {
    let lastIndex = 0;
    modePanes.value.forEach((pane, i) => {
      if (pane.key === targetKey) {
        lastIndex = i - 1;
        enableLockeData.dataId = pane.content.id;
        enableLockeData.formId = formIdComputedRef.value;
      }
    });
    modePanes.value = modePanes.value.filter((pane) => pane.key !== targetKey);
    if (modePanes.value.length && modeActiveKey.value === targetKey) {
      if (lastIndex >= (hasAddBtn.value ? 1 : 0)) {
        modeActiveKey.value = modePanes.value[lastIndex].key;
        if (lastIndex > (hasAddBtn.value ? 1 : 0))
          FormNormalRef.value.handleInner(modePanes.value[lastIndex].content);
      }
    }
  }
</script>
<style lang="less" scoped>
  :deep(.ant-table-selection-col) {
    width: 50px;
  }

  .show {
    display: flex;
  }

  .hide {
    display: none !important;
  }

  .btn-box {
    display: grid;
    position: absolute;
    top: 0;
    left: v-bind(pushbtnleft);
    z-index: 999;

    .ant-btn {
      margin-top: 5px;
      padding: 0 10px;
    }
  }

  :deep(.ant-table-expanded-row) {
    .ant-table {
      margin: 0 !important;
      height: 100%;

      .ant-table-thead {
        height: 40px;
      }

      .ant-empty-normal {
        margin: 16px 0;
      }
    }

    .ant-table-wrapper {
      height: 200px;
    }
  }

  .card-box {
    :deep(.ant-table-content) {
      max-height: none !important;
    }

    :deep(.vben-basic-table) {
      .ant-table .ant-table-body {
        height: 100% !important;
        border-radius: 16px;

        table {
          width: 100% !important;
        }

        tr td {
          padding: 0 !important;
          border-bottom: none;
        }
      }
    }

    :deep(.ant-table-header) {
      display: none;
    }

    :deep(.ant-table-expanded-row-fixed) {
      margin: 0 !important;
      padding: 0;
    }
  }

  .selected-box {
    border: 1px solid @primary-color;
    background: linear-gradient(to bottom, #88b1ff, #fff 80%);

    .box-title {
      border-bottom: 1px solid #98b7f1;

      .icon-box {
        background: @primary-color;
        color: #fff;
      }

      .icon-delete {
        background: #ed6f6f;
      }
    }
  }

  .unselected-box {
    background: linear-gradient(to bottom, #e7efff, #fff 80%);

    .box-title {
      border-bottom: 1px solid #e3edff;

      .icon-box {
        background: #fff;
        color: @primary-color;
      }

      .icon-delete {
        background: #fff;
        color: #ed6f6f;
      }
    }
  }

  .data-list {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    margin-top: 10px;
    padding: 0 10px;

    .box-container {
      margin: 0 10px 10px 0;
      flex: 0 0 calc((100% - 20px) / 3);
      height: 270px;
      overflow: auto;
      padding-bottom: 10px;

      &:nth-child(3n) {
        margin-right: 0;
      }

      .box-title {
        width: 100%;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0 5px;

        .icon-box {
          padding: 4px;
          border-radius: 50%;
          margin-right: 5px;
          cursor: pointer;
          vertical-align: middle;
        }
      }

      .flex-box {
        display: flex;
        flex-wrap: wrap;
        height: calc(100% - 40px);
        overflow: auto;
        padding: 10px 10px 0;

        .flex-item {
          flex: 0 0 50%;
          height: 50px;
          overflow: hidden;

          > div {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }

          .title {
            color: #67676c;
          }

          .value {
            font-weight: bold;
            color: #4a4b4d;
          }
        }
      }
    }
  }

  .left-menu-box {
    :deep(.ant-tabs-tab) {
      padding: 12px;
      margin: 0;
    }

    :deep(.ant-tabs-nav) {
      margin-bottom: 0;
    }

    :deep(.ant-tabs-content),
    :deep(.ant-tabs-top) {
      height: 100%;
    }
  }
</style>
