<!-- 📚📚📚 Vxe-Table 文档: https://vxetable.cn/#/table/start/install -->

<template>
  <!-- 查询表单 card -->
  <!-- <div class="table-box"> -->
  <SearchForm
    v-if="ifSearch && isShowSearch"
    :search="search"
    :reset="reset"
    :columns="searchColumns"
    :search-param="searchParam"
    :search-col="searchCol"
    :search-btn-size-extent="searchBtnSizeExtent"
    :project="tableprop_save?.searchProject"
    :form-props="tableprop_save?.search ?? {}"
    :layout-attr-define="searchFormDefault"
    @confirm="saveSearchSettingFunc"
    @save-project="editSearchProjectFunc"
    @updata-params="autoUpdataSearchParams"
  />

  <!-- 表格内容 card -->
  <div class="table-main flx-col" :class="`${propsDefine.height == 'auto' ? 'flx-1 overflow-hidden' : ''} ${tableCls}`">
    <!-- 表格头部 操作按钮 -->
    <div class="table-header flx-shrink">
      <div class="header-button-lf">
        <slot name="tableHeader" />
      </div>
      <div class="header-button-ri" v-if="toolButton.length" id="toolButton">
        <slot name="toolButton" :openColSetting="openColSetting" :refresh="refresh" :settingBtnLoading="settingBtnLoading">
          <template v-if="!collapseButtons">
            <el-tooltip
              v-if="defaultSort.length"
              effect="dark"
              :content="$t('common.table.clearSortBtn')"
              placement="top"
              :show-after="200"
            >
              <el-button :icon="Brush" round @click="clearSortEvent()">
                <span class="flx-center mr-6" v-for="(item, idx) in defaultSort" :key="idx">
                  <!-- {{ item.field }} -->
                  <span :class="globalStore.assemblySize == 'small' ? 'text-f-c' : 'text-body-c'">
                    {{ item.title ? item.title : $t(`table.${item.table}.${item.field}`) }}
                  </span>
                  <i
                    :class="{
                      iconfont: true,
                      'iconarrow-narrow-up': item.order == 'asc',
                      'iconarrow-narrow-down': item.order == 'desc'
                    }"
                  ></i>
                </span>
              </el-button>
            </el-tooltip>

            <!-- <el-button-group class="table-main__tool-button ml-12 mr-12"  -->
            <el-dropdown trigger="contextmenu" ref="printerListTpDropdownRef" v-if="getToolButton('print')">
              <el-button :icon="Printer" circle @click="checkPrintTemplateList('')"> </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <template v-if="printerTpList.length">
                    <el-dropdown-item
                      class="flx-justify-between"
                      v-for="(item, index) in printerTpList"
                      :key="index"
                      @click="openPrintPriveiew('', item, Boolean(item.printer))"
                    >
                      {{ item.aliase || item.printid }}
                      <el-tooltip
                        v-if="item.printer"
                        effect="dark"
                        :content="$t('sys.print.directPrint')"
                        placement="top"
                        :show-after="200"
                        :enterable="false"
                        :hide-after="0"
                      >
                        <i class="iconfont iconflash ml-8" :style="{ color: _variables.colorPolarGreen4 }"></i>
                      </el-tooltip>
                    </el-dropdown-item>
                  </template>
                  <el-dropdown-item :divided="Boolean(printerTpList.length)" @click="openPrint('')">
                    <div class="flx-center">
                      <el-icon>
                        <Setting />
                      </el-icon>
                      {{ $t("common.setText") }}
                    </div>
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
            <!-- <el-button class="pl-10 pr-10" :icon="Setting" @click="openPrint('')"> </el-button> -->
            <!-- </el-button-group> -->

            <el-button-group class="table-main__tool-button mr-12" v-if="getToolButton('printMx')">
              <el-tooltip
                v-if="Boolean(hiprinterStateMx)"
                effect="dark"
                :content="$t('sys.print.directPrint')"
                placement="top"
                :show-after="200"
              >
                <el-button class="pl-10 pr-10" @click="openPrintPriveiew('_mx', true)">
                  <template #icon>
                    <i class="iconfont iconflash"></i>
                  </template>
                </el-button>
              </el-tooltip>
              <el-tooltip effect="dark" :content="$t('common.table.print')" placement="top" :show-after="200">
                <el-button :icon="Printer" @click="openPrintPriveiew('_mx', null)">
                  <span class="text-body-c">{{ $t("common.table.detail") }}</span>
                </el-button>
              </el-tooltip>
              <el-button :icon="Setting" class="pl-10 pr-10" @click="openPrint('_mx')"> </el-button>
            </el-button-group>

            <el-button class="refresh-btn" :icon="Refresh" circle @click="refresh" v-if="toolButton.indexOf('refresh') > -1" />

            <el-tooltip
              effect="dark"
              v-if="getToolButton('export')"
              :content="$t('common.table.downloadBtn')"
              placement="top"
              :show-after="200"
            >
              <el-button class="default-btn" :icon="Download" circle @click="exportDataEvent" />
            </el-tooltip>

            <el-tooltip
              effect="dark"
              :content="$t('common.table.searchBtn')"
              placement="top"
              :show-after="200"
              v-if="toolButton.indexOf('search') > -1 && searchColumns.length"
            >
              <el-button
                :icon="Search"
                circle
                :type="isShowSearch ? 'primary' : ''"
                class="search-btn default-btn"
                :class="{ active: isShowSearch }"
                @click="isShowSearch = !isShowSearch"
              />
            </el-tooltip>

            <el-tooltip
              effect="dark"
              :content="$t('common.table.location')"
              placement="top"
              :show-after="200"
              v-if="toolButton.indexOf('location') > -1"
            >
              <el-button ref="locationBtnRef" :icon="Location" circle class="search-btn default-btn" />
            </el-tooltip>

            <el-tooltip
              effect="dark"
              v-if="toolButton.indexOf('guide') > -1"
              :content="$t('common.table.guide')"
              placement="top"
              :show-after="200"
            >
              <el-button class="default-btn" :icon="Guide" circle @click="checkIfNeedGuide(true)" />
            </el-tooltip>

            <template v-if="toolButton.indexOf('setting') > -1 && columns.length">
              <el-divider direction="vertical" />
              <el-tooltip effect="dark" :content="$t('common.table.tableSetBtn')" placement="top" :show-after="200">
                <el-button
                  class="default-btn"
                  id="toolButtonSetting"
                  :icon="Operation"
                  circle
                  :loading="settingBtnLoading"
                  @click="openColSetting"
                />
              </el-tooltip>
            </template>
          </template>
        </slot>
      </div>
    </div>
    <!-- 表格主体 -->
    <div
      id="vxeTableBody"
      class="relative table-warpper"
      :class="{ 'flx-1': propsDefine.height == 'auto' }"
      :style="{ minHeight: propsDefine?.minHeight }"
    >
      <el-dropdown
        v-if="collapseButtons && (defaultSort.length || toolButton.length)"
        class="collapse-buttons__group"
        placement="bottom-end"
        trigger="click"
        :teleported="false"
      >
        <el-button class="more-btn" :icon="More" circle></el-button>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item v-if="defaultSort.length" :icon="Brush" @click="clearSortEvent()">
              {{ $t("common.table.clearSortBtn") }}
            </el-dropdown-item>
            <el-dropdown-item v-if="toolButton.indexOf('refresh') > -1" :icon="Refresh" @click="refresh">
              {{ $t("tabs.refresh") }}
            </el-dropdown-item>
            <el-dropdown-item
              v-if="toolButton.indexOf('search') > -1 && searchColumns.length"
              :icon="Search"
              @click="isShowSearch = !isShowSearch"
            >
              {{ $t("common.table.searchBtn") }}
            </el-dropdown-item>
            <div ref="locationBtnRef" v-if="toolButton.indexOf('location') > -1">
              <el-dropdown-item :icon="Location">
                {{ $t("common.table.location") }}
              </el-dropdown-item>
            </div>
            <el-dropdown-item v-if="getToolButton('export')" :icon="Download" @click="exportDataEvent">
              {{ $t("common.table.downloadBtn") }}
            </el-dropdown-item>
            <el-dropdown-item v-if="getToolButton('import')" :icon="Upload" @click="importDataEvent">
              {{ $t("common.table.ImportBtn") }}
            </el-dropdown-item>
            <el-dropdown-item v-if="toolButton.indexOf('guide') > -1" :icon="Guide" @click="checkIfNeedGuide(true)">
              {{ $t("common.table.guide") }}
            </el-dropdown-item>
            <el-dropdown-item divided v-if="toolButton.indexOf('setting') > -1" :icon="Operation" @click="openColSetting">
              {{ $t("common.table.tableSetBtn") }}
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <vxe-table
        ref="tableRef"
        class="lj-vxetable"
        v-bind="tableOptions"
        :data="data ?? tableData"
        :key="isUpdate"
        :loading="tableLoading || extraLoading"
        v-on="propsEvents"
        :size="tableSize"
      >
        <!-- @resizable-change="handleResizChange" -->
        <!-- 默认插槽 -->
        <slot></slot>
        <template v-for="item in tableColumns" :key="item">
          <!-- checkbox || seq || expand -->
          <vxe-column v-bind="item" :align="item.align ?? 'center'" v-if="item.type && TABLE_TYPE_FILTER.includes(item.type)">
            <template #content="scope" v-if="item.type == 'expand'">
              <slot :name="item.type" v-bind="scope"></slot>
            </template>
          </vxe-column>
          <TableColumn
            v-if="(!item.type || item.type == 'html') && item.field && item.visible"
            :column="item"
            :editable="tableOptions?.editConfig?.enabled"
          >
            <template v-for="slotKey in Object.keys($slots)" #[slotKey]="scope">
              <slot :name="slotKey" v-bind="scope"></slot>
            </template>
            <template v-for="slotKey in Object.keys($slots)" #[`edit_${slotKey}`]="scope">
              <slot :name="`edit_${slotKey}`" v-bind="scope"></slot>
            </template>
          </TableColumn>
        </template>
        <!-- 插入表格最后一行之后的插槽 -->
        <!-- <template #append>
          <slot name="append"> </slot>
        </template> -->
        <!-- 无数据 -->
        <template #empty>
          <div class="table-empty">
            <slot name="empty">
              <img src="@/assets/images/notData.png" alt="notData" />
              <div>暂无数据</div>
            </slot>
          </div>
        </template>
        <template #loading>
          <LoadingCom />
        </template>
      </vxe-table>
    </div>
    <!-- 分页组件 -->
    <div class="flx-shrink">
      <div class="flx-justify-between">
        <div class="left_part">
          <slot name="pagination_left" />
        </div>
        <slot
          name="pagination"
          :pagination="pagination"
          :pageable="pageable"
          :pageSizes="pageSizes"
          :pageChange="handlePageChange"
        >
          <Pagination v-if="pagination" :pageable="pageable" :page-sizes="pageSizes" :handle-page-change="handlePageChange" />
        </slot>
      </div>
    </div>
  </div>
  <!-- 列设置 -->
  <ColSetting
    v-if="toolButton.length && toolButton.indexOf('setting') > -1"
    ref="baseMsgSettingRef"
    :data="colSetting"
    :title="props.title"
    :enum-map="baseEnumMap"
    :scroll-y-default="propsDefine.scrollY"
    @to-scroll-col="funcScrollToCol"
    @confirm="settingConfirm"
    @reset="resetSetting"
    @save-default="saveDefaultLayout"
  />
  <PrintEditor ref="printEditorRef" v-if="toolButton.length && toolButton.indexOf('print') > -1" @closed="toClosedPrintEditor" />
  <PrintTemplateSelector
    ref="printTemplateRef"
    v-if="toolButton.length && toolButton.indexOf('print') > -1"
    @newtemplate="toEditPrintTemplate"
    @edittemplate="toEditPrintTemplate"
    @preview="toPreviewPrintTemplate"
    @confirm="toPrintPrintTemplate"
    @closed="toGetPrinterState"
  />

  <!-- <LjDialog
    ref="locationDialogRef"
    :modal="false"
    width="20%"
    class="small find-dialog"
    :closed="autoCloseLocation"
    :close-on-click-modal="false"
  >
    <template #header>
      <el-tabs v-model="locationTabActive" class="tableheader-tabs">
        <el-tab-pane :label="$t('common.table.find') + $t('common.table.data')" name="data"></el-tab-pane>
        <el-tab-pane :label="$t('common.table.find') + $t('common.table.col')" name="col"></el-tab-pane>
      </el-tabs>
    </template>
    <el-form :model="locationFrom" label-width="auto">
      <el-form-item :label="$t('common.table.col')" class="mb-8">
        <el-autocomplete
          ref="locationAutocompleteRef"
          v-model="locationFrom.field"
          :fetch-suggestions="locationQuerySearch"
          popper-class="my-autocomplete"
          :placeholder="$t('common.table.locationTips')"
          value-key="field"
          clearable
          class="w-full"
          @select="funcScrollToCol"
        >
          <template #default="{ item }">
            <div class="flx-justify-between">
              <div class="text-body-b">{{ item.title }}</div>
              <span class="pl-8 text-secondary-text">{{ item.field }}</span>
            </div>
          </template>
        </el-autocomplete>
      </el-form-item>
      <el-form-item :label="$t('common.table.data')" style="margin-bottom: 0" v-if="locationTabActive == 'data'">
        <el-input v-model="locationFrom.value" @input="disshow(locationFrom.value)">
          <template #suffix>
            <template v-if="matchData.length">
              <span>
                {{ `${matchIndex + 1}/${matchData.length}` }}
              </span>
            </template>
            <el-button class="ml-4 pl-5 pr-5" text size="small" @click="funcChangeLocation(-1)">
              <template #icon>
                <i class="iconfont iconarrow-narrow-up"></i>
              </template>
            </el-button>
            <el-button class="ml-2 pl-5 pr-5" text size="small" @click="funcChangeLocation(1)">
              <template #icon>
                <i class="iconfont iconarrow-narrow-down"></i>  
              </template>
            </el-button>
          </template>
        </el-input>
      </el-form-item>
    </el-form>
  </LjDialog> -->

  <el-popover
    ref="locationRef"
    :virtual-ref="locationBtnRef"
    trigger="click"
    virtual-triggering
    placement="bottom-end"
    :width="240"
    :show-arrow="!collapseButtons"
    @show="autoShowLocationPopover"
  >
    <div class="text-h5-m mb-8">
      {{ $t("common.table.location") }}
    </div>
    <el-autocomplete
      ref="locationAutocompleteRef"
      v-model="scrollCol"
      :fetch-suggestions="locationQuerySearch"
      popper-class="my-autocomplete"
      :placeholder="$t('common.table.locationTips')"
      value-key="field"
      clearable
      class="w-full"
      placement="bottom-end"
      @select="funcScrollToCol"
    >
      <template #default="{ item }">
        <div class="flx-justify-between">
          <div class="text-body-b">{{ item.title }}</div>
          <span class="pl-8 text-secondary-text">{{ item.field }}</span>
        </div>
      </template>
    </el-autocomplete>
  </el-popover>
  <!-- </div> -->
</template>

<script setup lang="ts" name="LjVxeTable">
import { ref, reactive, watch, computed, provide, onMounted, nextTick, toRef, unref, inject } from "vue";
// import { ElTable } from "element-plus";
import { useTable } from "@/hooks/useTable";
import { useSelection } from "@/hooks/useSelection";
import { useDwLayout } from "@/hooks/useDwLayout";
import { BreakPoint } from "@/components/Grid/interface";
import { ColumnProps, getDefaultFilter, dwnameSaveLayoutAttr, LjVxetableProps } from "./interface";
import {
  Refresh,
  Printer,
  Operation,
  Search,
  DCaret,
  Download,
  SortDown,
  SortUp,
  Brush,
  More,
  Setting,
  Location,
  Guide,
  Upload
} from "@element-plus/icons-vue";
import { filterEnum, formatValue, handleProp, handleRowAccordingToProp, streamlineFunc, floatAdd } from "@/utils";
import SearchForm from "./components/SearchForm.vue";
import Pagination from "./components/Pagination.vue";
import ColSetting from "./components/ColSetting.vue";
import TableColumn from "./components/TableColumn.vue";
import PrintEditor from "@/components/PrintEditor/index.vue";
// import LjDialog from "@/components/LjDialog/index.vue";
import PrintTemplateSelector from "@/components/Selector/PrintTemplate/index.vue";
import { VxeTablePropTypes, VxeTableProps, VxeTableInstance, Colgroup } from "vxe-table";
import { cloneDeep, pick, defaultsDeep, throttle, omit } from "lodash-es";
import { useLayoutStore } from "@/stores/modules/layout";
import { useI18n } from "vue-i18n";
import { useUserStore } from "@/stores/modules/user";
import { useGlobalStore } from "@/stores/modules/global";
import { ElMessage, ElNotification } from "element-plus";
import LoadingCom from "../Loading/index.vue";
import { TABLE_LAYOUT_ATTR, TABLE_LAYOUT_ATTR_DEFINE, PRINT_KEY_ATTR, TABLE_TYPE_FILTER, ALLOW_EDIT_STATE } from "@/config/index";
import { useHiprinterStore } from "@/stores/modules/hiprinter";
import { usePrint } from "@/hooks/usePrint";
import variables from "@/styles/js.module.scss";
import { useAuthButtons } from "@/hooks/useAuthButtons";
import { pinyinFilter } from "@/utils/pinyin";
import { TourEnum } from "@/enums/tourEnum";
import { useTour } from "@/hooks/useTour";
// import { onKeyStroke } from "@vueuse/core";
import dayjs from "dayjs";
import { onClickOutside } from "@vueuse/core";
import { CommonDynamicSelect } from "@/api/modules/common";
import { isBoolean, isFunction, isNumber } from "@/utils/is";

const { t } = useI18n();
const globalStore = useGlobalStore();
const userStore = useUserStore();
const _variables: any = variables;

const tableSize = computed(() => {
  let _size: VxeTablePropTypes.Size = "";
  switch (globalStore.assemblySize) {
    case "large":
      _size = "";
      break;
    case "small":
      _size = "mini";
      break;
    default:
      _size = "medium";
      break;
  }
  return _size;
});

// /**
//  * @description 虚拟滚动参数
//  */
// const scrollYDefault = ref({
//   enabled: true,
//   oSize: 0,
//   mode: "default"
// });
const searchFormDefault = {
  labelPosition: "left",
  labelWidth: ""
};

// 接受父组件参数，配置默认值
const props = withDefaults(defineProps<LjVxetableProps>(), {
  columns: () => [],
  requestAuto: true,
  pagination: false,
  pageSizes: () => [20, 50, 100, 500, 1000, 10000],
  initParam: {},
  border: true,
  // toolButton: true,
  rowKey: "id",
  searchCol: () => ({ xs: 3, sm: 4, md: 5, lg: 6, xl: 8 }),
  // settingCol: () => ({ xs: 24, sm: 12, md: 8, lg: 6, xl: 4 }),
  layoutAttr: () => TABLE_LAYOUT_ATTR,
  layoutAttrDefine: () => TABLE_LAYOUT_ATTR_DEFINE,
  // height: "auto",
  tableCls: "card h-full",
  tableProps: {},
  extraLoading: false,
  tableEvents: {},
  toolButton: () => ["refresh", "setting", "search", "location"],
  toolButtonPower: () => [],
  autoLoadLayout: true,
  collapseButtons: true,
  miniSearchbar: true,
  footerSumAttrs: () => [],
  searchBtnSizeExtent: () => ["xs", "sm", "md"],
  multiSelect: undefined,
  editable: false,
  autoSelectFirstAfterRefresh: false,
  ifLoadQueryHabit: true,
  ifSearch: true
});
/**
 * @description 是否可编辑
 */
const orderStatus = inject("orderStatus", ref(""));

// 默认表格props
const _defineProps = ref({
  border: true,
  showOverflow: "tooltip",
  showHeaderOverflow: false,
  height: "auto",
  minHeight: "100px",
  rowConfig: {
    isCurrent: true,
    isHover: true,
    useKey: true,
    currentMethod: ({ row }: any) => {
      if (Object.keys(props).includes("lockRow")) {
        if (isBoolean(props?.lockRow)) {
          return !props.lockRow;
        } else if (isFunction(props?.lockRow)) {
          return !props?.lockRow(row);
        }
      }
      return true;
    }
  },
  columnConfig: { isCurrent: true, isHover: true, resizable: true },
  exportConfig: {},
  sortConfig: { trigger: "cell", multiple: true, chronological: true, defaultSort: {}, showIcon: false },
  checkboxConfig: { checkField: "checked", range: true },
  scrollY: {
    gt: 200,
    enabled: true,
    oSize: 0,
    mode: "default",
    scrollToTopOnChange: true
  },
  mouseConfig: { selected: true },
  keyboardConfig: { isArrow: true, isDel: true, isEnter: true, isTab: true, isEdit: true, isChecked: true },
  menuConfig: {
    header: {
      options: [
        [
          {
            code: "clear",
            name: t("common.table.filterClear"),
            visible: true,
            disabled: false
          }
        ],
        [
          {
            code: "clearAll",
            name: t("common.table.filterClearAll"),
            visible: true,
            disabled: false
          },
          {
            code: "export",
            name: t("common.export"),
            prefixIcon: "vxe-icon-download",
            visible: true,
            disabled: false
          }
        ],
        [
          {
            code: "hideColumn",
            name: t("common.table.hideColumn")
          }
        ]
      ]
    },
    body: {
      options: [
        [
          {
            code: "filter",
            name: t("common.table.filter"),
            visible: true,
            disabled: false,
            prefixIcon: "iconfont iconfilter-funnel-01",
            suffixIcon: "iconfont iconedit-02",
            children: [
              {
                code: "clear",
                name: t("common.table.filterClear"),
                visible: true,
                disabled: false,
                prefixIcon: "iconfont iconbrush-03-1"
              }
            ]
          },
          {
            code: "copy",
            name: t("common.table.copy"),
            visible: true,
            disabled: false,
            prefixIcon: "iconfont iconcopy-07"
          },
          // {
          //   code: "find",
          //   name: t("common.table.find"),
          //   visible: true,
          //   disabled: false,
          //   prefixIcon: "iconfont iconcopy-07"
          // },
          {
            code: "sort",
            name: "排序",
            prefixIcon: "iconfont iconswitch-vertical-02",
            children: [
              {
                code: "sortAsc",
                name: t("sys.setting.asc"),
                visible: true,
                disabled: false,
                prefixIcon: "iconfont iconarrow-narrow-up"
              },
              {
                code: "sortDesc",
                name: t("sys.setting.desc"),
                visible: true,
                disabled: false,
                prefixIcon: "iconfont iconarrow-narrow-down"
              },
              {
                code: "sortClear",
                name: t("common.clear"),
                visible: true,
                disabled: false,
                prefixIcon: "iconfont iconbrush-03-1"
              }
            ]
          }
        ],
        [
          {
            code: "clearAll",
            name: t("common.table.filterClearAll"),
            visible: true,
            disabled: false,
            prefixIcon: "iconfont icontrash-01"
          },
          {
            code: "export",
            name: t("common.export"),
            prefixIcon: "iconfont icondownload-01",
            visible: true,
            disabled: false
          }
        ]
      ]
    },
    visibleMethod({ options, column, row }: any) {
      options.forEach((list: any) => {
        list.forEach((item: any) => {
          if (item.children && item.children.length > 0) {
            item.children.forEach((itm: any) => {
              if (!row) {
                item.visible = false;
              } else {
                item.visible = true;
              }
            });
          }
          if (item.code === "filter") {
            // 复制
            if (row) {
              let _val = row[column.field] ? " - " + row[column.field] : row[column.field];
              item.name = t("common.table.filter") + _val;
              item.visible = true;
            } else {
              item.name = t("common.table.filter");
              item.visible = false;
            }
            // } else if (item.code === "copy") {
            //   // 复制
            //   if (row && row[column.field]) {
            //     item.name = t("common.table.copy") + " - " + row[column.field];
            //     item.visible = true;
            //   } else {
            //     item.name = t("common.table.copy");
            //     item.visible = false;
            //   }
          } else if (["copy", "clear"].includes(item.code)) {
            if (!row) {
              item.visible = false;
            } else {
              item.visible = true;
            }
          }
        });
      });
      return true;
    }
  },
  headerCellClassName: ({ column }: any) => {
    if (ALLOW_EDIT_STATE.includes(orderStatus.value) || props.editable) {
      if (column?.editRender && column.editRender.enabled !== false) {
        return "vxecol-edit";
      }
    }
    return null;
  },
  cellClassName: data => {
    let { column } = data;
    if (ALLOW_EDIT_STATE.includes(orderStatus.value) || props.editable) {
      if (column?.editRender && column.editRender.enabled !== false) {
        return "vxecol-edit";
      }
    }
    return props.cellClassName ? props.cellClassName(data, ALLOW_EDIT_STATE.includes(orderStatus.value) || props.editable) : null;
  }
});

// const propsDefine = Object.assign(_defineProps.value, props.tableProps);

interface RowVO {
  [key: string]: any;
}

// 获取缓存中当前页面的每页数量
let curPageSizes = undefined;
if (props.dwname && globalStore.pageSizes && globalStore.pageSizes.hasOwnProperty(props.dwname)) {
  curPageSizes = globalStore.pageSizes[props.dwname];
}

const { CheckPower } = useAuthButtons(t);
/**
 * @description 过滤表格按钮权限
 * @param type 按钮类型
 */
const getToolButton = (type: string) => {
  let _idx = props.toolButton.indexOf(type);

  if (_idx > -1) {
    if (props.toolButtonPower.length && _idx < props.toolButtonPower.length && props.toolButtonPower[_idx] != 0) {
      return CheckPower(props.toolButtonPower[_idx]);
    } else {
      return true;
    }
  }
  return false;
};

const emit = defineEmits([
  "afterMounted",
  "firstMounted",
  "layoutChange",
  "keydownStart",
  "keydown",
  "keydownEnd",
  "currentChange",
  "radioChange",
  "checkboxChange",
  "checkboxAll",
  "checkboxRangeStart",
  "checkboxRangeChange",
  "checkboxRangeEnd",
  "cellClick",
  "cellDblclick",
  "cellMenu",
  "cellMouseenter",
  "cellMouseleave",
  "cellDeleteValue",
  "headerCellClick",
  "headerCellDblclick",
  "headerCellMenu",
  "footerCellClick",
  "footerCellDblclick",
  "footerCellMenu",
  "clearMerge",
  "sortChange",
  "clearSort",
  "filterChange",
  "filterVisible",
  "clearFilter",
  "resizableChange",
  "toggleRowExpand",
  "toggleTreeExpand",
  "menuClick",
  "cellSelected",
  "editClosed",
  "editActivated",
  "editDisabled",
  "validError",
  "scroll",
  "scrollBoundary",
  "custom",
  "rowDragstart",
  "rowDragend"
]);
// 表格绑定的事件
const propsEvents = computed(() => {
  let defineEv = {
    keydownStart: (data: any) => emit("keydownStart", data),
    keydown: (data: any) => emit("keydown", data),
    keydownEnd: (data: any) => emit("keydownEnd", data),
    currentChange: (data: any) => {
      console.log("currentChange !!!!!!!!!!!!:>> ", data);
      emit("currentChange", data);
    },
    radioChange: (data: any) => emit("radioChange", data),
    checkboxChange: (data: any) => emit("checkboxChange", data),
    checkboxAll: (data: any) => emit("checkboxAll", data),
    checkboxRangeStart: (data: any) => emit("checkboxRangeStart", data),
    checkboxRangeChange: (data: any) => emit("checkboxRangeChange", data),
    checkboxRangeEnd: (data: any) => emit("checkboxRangeEnd", data),
    cellClick: (data: any) => {
      const { row, rowIndex, column, columnIndex } = data;
      // currentEditCell.value.row = row;
      currentEditCell.value.rowIndex = rowIndex;
      // currentEditCell.value.column = column;
      currentEditCell.value.field = column.field;
      console.log("editConfig cellClick :>> ", row, currentEditCell.value);
      emit("cellClick", data);
    },
    cellDblclick: (data: any) => emit("cellDblclick", data),
    cellMenu: (data: any) => emit("cellMenu", data),
    cellMouseenter: (data: any) => emit("cellMouseenter", data),
    cellMouseleave: (data: any) => emit("cellMouseleave", data),
    cellDeleteValue: (data: any) => emit("cellDeleteValue", data),
    headerCellClick: (data: any) => emit("headerCellClick", data),
    headerCellDblclick: (data: any) => emit("headerCellDblclick", data),
    headerCellMenu: (data: any) => emit("headerCellMenu", data),
    footerCellClick: (data: any) => emit("footerCellClick", data),
    footerCellDblclick: (data: any) => emit("footerCellDblclick", data),
    footerCellMenu: (data: any) => emit("footerCellMenu", data),
    clearMerge: (data: any) => emit("clearMerge", data),
    sortChange: (data: any) => {
      handleSortChange(data);
      emit("sortChange", data);
    },
    clearSort: (data: any) => emit("clearSort", data),
    filterChange: (data: any) => emit("filterChange", data),
    filterVisible: (data: any) => emit("filterVisible", data),
    clearFilter: (data: any) => emit("clearFilter", data),
    resizableChange: (data: any) => {
      handleResizChange(data);
      emit("resizableChange", data);
    },
    toggleRowExpand: (data: any) => emit("toggleRowExpand", data),
    toggleTreeExpand: (data: any) => emit("toggleTreeExpand", data),
    cellSelected: (data: any) => {
      handleCellSelected(data);
      emit("cellSelected", data);
    },
    editClosed: (data: any) => emit("editClosed", data),
    editActivated: (data: any) => emit("editActivated", data),
    editDisabled: (data: any) => emit("editDisabled", data),
    validError: (data: any) => emit("validError", data),
    scroll: (data: any) => emit("scroll", data),
    scrollBoundary: (data: any) => emit("scrollBoundary", data),
    custom: (data: any) => emit("custom", data),
    rowDragstart: (data: any) => emit("rowDragstart", data),
    rowDragend: (data: any) => emit("rowDragend", data),
    menuClick({ menu, type, row, rowIndex, column, columnIndex, $event }: any) {
      console.log("menu :>> ", menu);
      console.log("menu row :>> ", row);
      console.log("menu column :>> ", column);
      const $table = tableRef.value;
      if ($table) {
        switch (menu.code) {
          case "filter":
            if (column.filterRender) {
              // 自定义筛选
              // 修改第一个选项为勾选状态
              const option = column.filters[0];
              option.data.vals = [row[column.field].toString()];
              option.checked = true;
              // 如果是直接修复筛选条件，则需要手动调用 updateData 处理表格数据
              console.log("option", option);
            } else {
              // 定制筛选
              column.filters.forEach((item: any) => {
                if (item.value == row[column.field]) {
                  item.checked = true;
                } else {
                  item.checked = false;
                }
              });
            }
            if ($event.target.className.indexOf("iconedit-02") > -1) {
              if (column.filterRender) {
                column.filters[0].data.sVal = row[column.field].toString();
              }
              // 点击修改图标,弹出筛选下拉
              $table.openFilter(column.field);
            } else {
              $table.updateData();
            }
            break;
          case "copy":
            if (row && column) {
              const input = document.createElement("textarea");
              input.value = row[column.field];
              document.body.appendChild(input);
              input.select();
              document.execCommand("Copy");
              document.body.removeChild(input);
              ElMessage({
                type: "success",
                message: t("common.copySuccess")
              });
            }
            break;
          // case "find":
          //   locationTabActive.value = "data";
          //   if (locationFrom.field != column.field) {
          //     matchData.value = [];
          //     matchIndex.value = 0;
          //     locationFrom.value = "";
          //   }
          //   locationFrom.field = column.field;
          //   locationDialogRef.value.show();
          //   break;
          case "clear":
            $table.clearFilter(column);
            break;
          case "clearAll":
            $table.clearFilter();
            break;
          case "export":
            $table.openExport();
            break;
          case "hideColumn":
            // 隐藏列
            colSetting.forEach(item => {
              if (column.field === item.field) {
                item.visible = false;
                return;
              }
            });
            console.log("colSetting :>> ", colSetting);
            settingConfirm(colSetting);
            break;
          case "sortAsc":
            column && $table.sort({ field: column.field, order: "asc" });
            console.log("sortAsc $table.getSortColumns() :>> ", $table.getSortColumns());
            handleSortChange({ sortList: $table.getSortColumns() });
            break;
          case "sortDesc":
            column && $table.sort({ field: column.field, order: "desc" });
            console.log("sortDesc $table.getSortColumns() :>> ", $table.getSortColumns());
            handleSortChange({ sortList: $table.getSortColumns() });
            break;
          case "sortClear":
            column && clearSortEvent(column.field);
            break;
        }

        emit("menuClick", { menu, type, row, rowIndex, column, columnIndex, $event });
      }
    }
  };
  return Object.assign(defineEv, props.tableEvents);
});

// 通用查询接口返回的布局数据，保存
const loadDwLayout = (data: any) => {
  console.log("layout data:>> ", data);
  // 表格结构： {tableprop: string, columns: string}
  // typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
  // 兼容部分结构直接记录行数据
  if (data.hasOwnProperty("columns") && data.columns) {
    dwLayout.value = data.columns;
  } else {
    dwLayout.value = data;
  }

  loadLayoutCallBack(data);

  props.dwname && layoutStore.setDwLayout(props.dwname, data, t, false);

  console.log("onMounted dwLayout.value :>> ", dwLayout.value);
  loadDwLayoutFunc(dwLayout.value);
  // tableColumns.value = cloneDeep(props.columns);
  console.log("数行化BF，还原个性设置 tableColumns.value :>> ", tableColumns.value);
  // 扁平化，并读取个性设置
  flatColumns.value = flatColumnsFunc(cloneDeep(props.columns), dwFieldMap);
  console.log("读取个性设置 flatColumns.value  loadDwLayout:>> ", flatColumns.value);

  initLayoutColumns();
};

/**
 * @description 指引步骤
 */
const TourSteps = [
  {
    element: "#searchForm",
    popover: {
      title: t("business.guide.table.step1.title"),
      description: t("business.guide.table.step1.description"),
      side: "bottom"
    }
  },
  {
    element: "#searchForm_searchProject",
    popover: {
      title: t("business.guide.table.step2.title"),
      description: t("business.guide.table.step2.description"),
      side: "bottom"
    }
  },
  {
    element: "#toolButton",
    popover: {
      title: t("business.guide.table.step3.title"),
      description: t("business.guide.table.step3.description"),
      side: "bottom"
    }
  },
  {
    element: "#toolButtonSetting",
    popover: {
      title: t("business.guide.table.step4.title"),
      description: t("business.guide.table.step4.description"),
      side: "bottom"
    }
  },
  {
    element: "#vxeTableBody",
    popover: {
      title: t("business.guide.table.step5.title"),
      description: t("business.guide.table.step5.description")
    }
  },
  {
    element: "#ljVxePagination",
    popover: {
      title: t("business.guide.table.step6.title"),
      description: t("business.guide.table.step6.description"),
      side: "top"
    }
  }
];

// 新手指导
const { checkIfNeedGuide } = useTour(t, TourEnum.table, TourSteps);
const defaultRequest = (params: any) => {
  if (!props.requestAuto) return undefined;
  let newParams: any = {};
  params.pageNum && (newParams.pageindex = params.pageNum);
  params.pageSize && (newParams.pagesize = params.pageSize);
  delete params.pageNum;
  delete params.pageSize;
  newParams.queryParams = JSON.parse(JSON.stringify(params));
  console.log("newParams", newParams);
  let pkeys = Object.keys(newParams.queryParams);
  console.log("pkeys :>> ", pkeys);
  let flatSearchColumns = new Map<string, any>();
  for (let searchCol of searchColumns.value) {
    flatSearchColumns.set(searchCol.field || "", searchCol);
  }
  for (let pk of pkeys) {
    console.log("pk :>> ", pk);
    console.log("haspk", flatSearchColumns.has(pk));
    if (flatSearchColumns.has(pk)) {
      let searchInfo = flatSearchColumns.get(pk);
      console.log("searchInfo :>> ", searchInfo);
      if (searchInfo.search && searchInfo.search.props && searchInfo.search.props.type == "date") {
        const today = dayjs(dayjs().format("YYYY-MM-DD"));
        if (isNumber(newParams.queryParams[pk])) {
          newParams.queryParams[pk] = today.add(newParams.queryParams[pk], "day").format("YYYY-MM-DD HH:mm:ss");
        }
      }
    }
  }
  newParams.dsname = props.dwname;
  return CommonDynamicSelect(newParams, newParams.dsname);
};
const defaultDataCallback = (data: any) => {
  return {
    list: data.datatable,
    tableinfo: data.tableinfo,
    total: data.totalcnt,
    pageNum: data.pageindex,
    pageSize: data.pagesize
  };
};

// 表格操作 Hooks
const {
  tableData,
  pageable,
  searchParam,
  totalParam,
  searchInitParam,
  tableLoading,
  getTableList,
  search,
  reset,
  // handleSizeChange,
  // handleCurrentChange,
  handlePageChange
} = useTable(
  props.requestApi || defaultRequest,
  props.initParam,
  props.pagination,
  props.dataCallback || defaultDataCallback,
  props.requestError,
  props.dwname,
  curPageSizes,
  !props.autoLoadLayout,
  loadDwLayout,
  props?.pageChangeCallBack
);

/**
 * @description 默认表尾合计
 */
const defineFooterMethod = ({ columns, data }: any) => {
  // 返回一个二维数组的表尾合计
  return [
    columns.map((column: any, columnIndex: number) => {
      if (columnIndex === 0) {
        return "合计";
      }
      if (columnIndex === 1) {
        return data.length;
      }
      if ((column.field && column.field.indexOf("qty") > -1) || props.footerSumAttrs?.includes(column.field)) {
        let count = 0;
        data.forEach((item: any) => {
          item && (count = floatAdd(count, isNaN(Number(item[column.field])) ? 0 : Number(item[column.field])));
        });
        return count;
      }
    })
  ];
};

const propsDefine = defaultsDeep(props.tableProps, _defineProps.value);

// 表格参数:init
const tableOptions = reactive<any>({
  showFooter: typeof props.footerMethod != "boolean",
  footerMethod: typeof props.footerMethod != "boolean" ? props.footerMethod ?? defineFooterMethod : undefined,
  ...propsDefine
});

watch(
  () => props.editable,
  (newVal, oldVal) => {
    tableOptions.editConfig.enabled = newVal;
  }
);
console.log("init propsDefine :>> ", propsDefine);

if (props?.multiSelect != undefined) {
  tableOptions.checkboxConfig = {
    range: true,
    trigger: "cell",
    highlight: true
  };
  tableOptions.checkboxConfig.checkField = props.multiSelect ?? "";

  if (!props.columns.some(c => c.type == "checkbox")) {
    props.columns.unshift({
      type: "checkbox",
      width: 50
    });
  }
}
if (props?.editable) {
  if (tableOptions.editConfig == undefined) {
    tableOptions.editConfig = { trigger: "click", mode: "cell" };
  }
  tableOptions.editConfig.enabled = props?.editable ?? false;
}

/**表格存储参数 */
const tableprop_save = ref<dwnameSaveLayoutAttr>({
  scrollY: {},
  search: {},
  basicinfo: {},
  searchProject: []
});

// 是否显示搜索模块
const isShowSearch = ref(true);

// 是否更新数据
const isUpdate = ref(0);

// 表格 DOM 元素
const tableRef = ref<VxeTableInstance>();

// 表格多选 Hooks
// const { selectionChange, selectedList, selectedListIds, isSelected } = useSelection(props.rowKey);

/**
 * @description 当前已选列表
 */
const selectRecords = ref<any>();

const loadLayoutCallBack = (data: any) => {
  if (data?.hasOwnProperty("tableprop") && data.tableprop) {
    tableprop_save.value = data.tableprop;

    console.log("warch project newVal bbbbbf tableprop_save.value:>> ", tableprop_save.value);
    let _scrollY = tableprop_save.value.hasOwnProperty("scrollY") ? cloneDeep(tableprop_save.value.scrollY) : {};
    console.log("_scrollY :>> ", _scrollY);
    tableOptions.scrollY = defaultsDeep(_scrollY, propsDefine.scrollY);
  }
  console.log("warch project newVal loadLayoutCallBack tableprop_save.value:>> ", tableprop_save.value);
};

const flatColumnsCallBack = (col: any) => {
  // 设置 enumMap
  setEnumMap(col);
  // 设置 表格基础信息-format枚举
  setBaseEnumMap(col);

  col.filterRender = col.filterRender
    ? col.filterRender
    : col.filters
    ? undefined
    : {
        name: "FilterExtend",
        props: {
          sortfunc: (data: any) => {
            console.log("flatColumnsCallBack sortfunc :>> ", data);
            handleSortChange(data);
          },
          enum: enumMap.value.get(col.field!) ?? [],
          col: pick(col, ["field", "datatype"])
        }
      };
  col.filters = col.filters ?? getDefaultFilter(col);

  return col;
};

// 表格布局读取与存储
const {
  tableColumns,
  dwLayout,
  dwFieldMap,
  flatColumns,
  loadLayoutFunc,
  loadDwLayoutFunc,
  flatColumnsFunc,
  getDefineAttr,
  loadRenderAttr,
  columnStreamlineFunc,
  getOriColumns
} = useDwLayout(
  "table",
  t,
  cloneDeep(props.columns),
  props.layoutAttr,
  props.layoutAttrDefine,
  props.autoLoadLayout,
  props.dwname,
  loadLayoutCallBack,
  flatColumnsCallBack,
  props?.editable
);

/**
 * @description 打印前检测状态
 */
const funcBeforePrintCheck = () => {
  let _status = true;
  const $table = tableRef.value;
  if ($table) {
    const _records = $table.getCheckboxRecords() ?? [];
    const curRecords = $table.getCurrentRecord() ?? null;

    selectRecords.value = [];
    if (_records.length) {
      // 获取勾选列表
      selectRecords.value = _records;
    } else if (curRecords) {
      // 获取当前选中数据
      selectRecords.value = [curRecords];
    } else {
      // 默认获取第一条记录
      let fullData = $table.getTableData().fullData;
      if (fullData.length) {
        selectRecords.value = [fullData[0]];
        $table.setCurrentRow(fullData[0]);
      }
    }

    console.log("funcBeforePrintCheck selectRecords.value :>> ", selectRecords.value);
    props.beforePrintCallback && (_status = props.beforePrintCallback(selectRecords.value));
    console.log("beforePrintCallback _status :>> ", _status);
  } else {
    ElMessage("$table: 表格对象获取失败");
    _status = false;
  }
  return _status;
};

const getSelectRecords = () => {
  return selectRecords.value;
};

const {
  printEditorRef,
  printTemplateRef,
  printerListTpDropdownRef,
  activePrint,
  hiprinterStateList,
  hiprinterStateMx,
  printerTpList,
  toGetPrinterState,
  openPrint,
  openPrintPriveiew,
  toPreviewPrintTemplate,
  toPrintPrintTemplate,
  toEditPrintTemplate,
  checkPrintTemplateList
} = usePrint(t, props.dwname, getSelectRecords, funcBeforePrintCheck, props.printDataCallback);
// 清空选中数据列表
// const clearSelection = () => tableRef.value!.clearSelection();

// 定义 enumMap 存储 enum 值（避免异步请求无法格式化单元格内容 || 无法填充搜索下拉选择）
const enumMap = ref(new Map<string, { [key: string]: any }[]>());
const baseEnumMap = ref(new Map<string, { [key: string]: any }[]>());
provide("enumMap", enumMap);
const setEnumMap = async (col: ColumnProps) => {
  if (!col.enum) return;
  // 如果当前 enum 为后台数据需要请求数据，则调用该请求接口，并存储到 enumMap
  console.log("col.enum :>> ", col.field, col.enum);
  if (typeof col.enum !== "function") {
    let _enum = col.enum!;
    if (col.enumFilter) {
      _enum = col.enumFilter(searchParam.value, _enum, "");
    }
    return enumMap.value.set(col.field!, _enum);
  }
  const { data } = await col.enum();
  enumMap.value.set(col.field!, data);
};
const setBaseEnumMap = async (col: ColumnProps) => {
  if (!col.formatEnum) return;
  // 如果当前 enum 为后台数据需要请求数据，则调用该请求接口，并存储到 enumMap
  if (typeof col.formatEnum !== "function") return baseEnumMap.value.set(col.field!, col.formatEnum!);
  const { data } = await col.formatEnum();
  baseEnumMap.value.set(col.field!, data);
};

// // 扁平化 初始化 columns
// const flatColumnsFunc = (columns: ColumnProps[], dwMap: Map<KeyType, any> = new Map(), flatArr: ColumnProps[] = []) => {
//   columns.forEach(async (col: any) => {
//     if (col._children?.length) flatArr.push(...flatColumnsFunc(col._children, dwMap));
//     flatArr.push(col);

//     // 给每一项 column 添加默认属性
//     col.visible = col?.visible == false ? false : props.layoutAttrDefine.visible; // true
//     col.width = col.width ?? props.layoutAttrDefine.width; // 200
//     col.align = col.align ?? props.layoutAttrDefine.align; // "center"
//     col.sortable = col.sortable ?? props.layoutAttrDefine.sortable; // false
//     col.order = col.order ?? props.layoutAttrDefine.order; // ""
//     col.fixed = col.fixed ?? props.layoutAttrDefine.fixed; // ""
//     // col.isFilterEnum = col.isFilterEnum ?? true;

//     col.filterRender = col.filterRender ? col.filterRender : col.filters ? undefined : { name: "FilterExtend" };
//     col.filters = col.filters ?? defaultFilter.value;

//     // 读取个性设置属性
//     if (dwMap.size) {
//       let userStyle = dwMap.get(col.field);
//       if (userStyle) {
//         for (let prop of props.layoutAttr) {
//           if (userStyle.hasOwnProperty(prop) && prop != "title") {
//             col[prop] = userStyle[prop];
//           }
//         }
//         col.colorder = userStyle.colorder;
//         if (userStyle.search && col.search) {
//           col.search.order = userStyle.search.order ?? undefined;
//           col.search.span = userStyle.search.span ?? undefined;
//           col.search.labelPosition = userStyle.search.labelPosition ?? undefined;
//           col.search.labelWidth = userStyle.search.labelWidth ?? undefined;
//         }
//       }
//     }

//     if (TABLE_TYPE_FILTER.includes(col.type!)) {
//     } else if (col.field == "operation") {
//       col.title = t(`table.${col.field}`);
//     } else {
//       col.title = t(`table.${col.table}.${col.field}`);
//     }

//     // 搜索栏，读取个性设置属性
//     if (col.search) {
//       col.search.labelPosition = col.search.labelPosition ?? props.searchLayoutAttrDefine.labelPosition; // "top"
//       col.search.labelWidth = col.search.labelWidth ?? props.searchLayoutAttrDefine.labelWidth; // 120
//       col.search.span = col.search.span ?? props.searchLayoutAttrDefine.span; // 1
//     }

//     // 设置 enumMap
//     !enumMap.value.size && setEnumMap(col);
//     // 设置 表格基础信息-format枚举
//     !baseEnumMap.value.size && setBaseEnumMap(col);
//   });

//   // 读取个性设置后，排序，
//   if (dwFieldMap.size) {
//     flatArr.sort((a, b) => {
//       return a.colorder! - b.colorder!;
//     });
//   }
//   return flatArr.filter(item => !item._children?.length);
// };

// 读取个性布局,用Map()储存
// const dwFieldMap = new Map();
// const loadDwLayoutFunc = (loadLayout: ColumnProps[] = []) => {
//   console.log("loadLayout.value :>> ", loadLayout);
//   if (!loadLayout || !loadLayout.length) return false;

//   // 个性布局加顺序号
//   for (const i in loadLayout) {
//     loadLayout[i].colorder = Number(i);
//   }

//   // 个性布局构建键值Map()
//   dwFieldMap.clear();
//   for (const item of loadLayout) {
//     dwFieldMap.set(item.field, item);
//   }
//   console.log("dwFieldMap :>> ", dwFieldMap);
// };

// 布局暂存数据
const layoutStore = useLayoutStore();
// const dwLayout = ref([]);

//
// /**
//  * @description 树形化：接收 columns 并设置为响应式
//  */
// let tableColumns = ref<ColumnProps[]>(cloneDeep(props.columns));
// console.log("init tableColumns.value :>> ", tableColumns.value);

// /**
//  * @description 扁平化：columns，用于打印、记录
//  */
// const flatColumns = ref<ColumnProps[]>();
// console.log("flatColumns.value :>> ", flatColumns.value);

/**
 * @description 个性化设置columns
 */
let colSetting = reactive<ColumnProps[]>([]);
// let prototypeCol = reactive<ColumnProps[]>([]);
let defaultSort = ref<any[]>([]);
provide("defaultSort", defaultSort);

// 过滤需要搜索的配置项
let searchColumns = ref<ColumnProps[]>([]);
// const searchColumns = flatColumns.value.filter(item => item.search?.el || item.search?.render);

// // 设置搜索表单排序默认值 && 设置搜索表单项的默认值
// searchColumns.forEach((column, index) => {
//   column.search!.order = column.search!.order ?? index + 2;
//   if (column.search?.defaultValue !== undefined && column.search?.defaultValue !== null) {
//     searchInitParam.value[column.search.key ?? handleProp(column.field!)] = column.search?.defaultValue;
//     searchParam.value[column.search.key ?? handleProp(column.field!)] = column.search?.defaultValue;
//   }
// });

// // 排序搜索表单项
// searchColumns.sort((a, b) => a.search!.order! - b.search!.order!);

// 列设置 ==> 过滤掉不需要设置的列
// const colRef = ref();
// const colSetting = tableColumns.value!.filter(
//   item => !["checkbox", "index", "expand"].includes(item.type!) && item.field !== "operation" && !item.visible
// );
// const openColSetting = () => colRef.value.openColSetting();

let settingBtnLoading = ref(false);
const baseMsgSettingRef = ref();
const currentColumn = ref();
/**
 * @description 打开设置窗口
 */
const openColSetting = () => {
  settingBtnLoading.value = true;
  setTimeout(() => {
    baseMsgSettingRef.value?.openColSetting(tableOptions.scrollY, currentColumn.value);
    settingBtnLoading.value = false;
  }, 1);
};

/**
 * @description 监听当前高亮单元格
 */
const handleCellSelected = ({ row, rowIndex, $rowIndex, column, columnIndex, $columnIndex, $event }: any) => {
  currentColumn.value = column;
};

// let settingColumn: any = reactive(quoteColumns.cloumns);
// const fnUpdateSettingColumn = (prop: string, val: any) => {
//   console.log("prop :>> ", prop);
//   console.log("colSetting :>> ", colSetting);
//   for (let i = 0; i < colSetting.length; i++) {
//     if (colSetting[i].field == prop) {
//       console.log("settingColumn[i] :>> ", colSetting[i]);
//       // quoteColumns.cloumns[i][prop] = val
//     }
//   }
// };
// provide("updateSettingColumn", fnUpdateSettingColumn);
// const emit = defineEmits(["update:columns"]);

// const columnStreamlineFunc = (column: any, scrollParam?: any) => {
//   let oriColumns = cloneDeep(props.columns);
//   console.log("column :>> ", column);
//   console.log("oriColumns :>> ", oriColumns);

//   // 默认值字段集合
//   let defineAttr = getKeys(props.layoutAttrDefine);
//   defineAttr.unshift("field");

//   // 取默认值 + 自定义业务columns = 动态默认值属性
//   let oriDedine = oriColumns
//     .filter((item: any) => item.field)
//     .map((item: any) => {
//       let _define = getDefineAttr(item, props.layoutAttrDefine);
//       return pick(defaultsDeep(item, _define), defineAttr);
//     });
//   console.log("streamlineFunc column :>> ", column);
//   console.log("streamlineFunc props.layoutAttr :>> ", props.layoutAttr);
//   console.log("streamlineFunc oriDedine :>> ", oriDedine);
//   let _columns = column.filter((item: any) => item.field);
//   /**
//    * @argument tableprop table属性，api参考vxe-table
//    * @argument columns 个性化数据列集合
//    */
//   let saveCol: any = {
//     columns: streamlineFunc(_columns, props.layoutAttr, oriDedine)
//   };

//   let _scroll = undefined;
//   console.log("settingConfirm saveCol :>> ", saveCol);
//   if (scrollParam) {
//     _scroll = {
//       enabled: scrollParam?.enabled,
//       oSize: scrollParam.oSize,
//       mode: scrollParam.mode
//     };
//     tableOptions.scrollY!.enabled = scrollParam.enabled;
//     tableOptions.scrollY!.oSize = scrollParam.oSize;
//     tableOptions.scrollY!.mode = scrollParam.mode;
//   } else {
//     console.log("tableOptions.scrollY no :>> ", tableOptions.scrollY);
//     tableOptions.scrollY!.enabled = tableOptions.scrollY!.enabled ?? scrollYDefault.value?.enabled;
//     tableOptions.scrollY!.oSize = tableOptions.scrollY!.oSize ?? scrollYDefault.value?.oSize;
//     tableOptions.scrollY!.mode = tableOptions.scrollY!.mode ?? "default";
//     _scroll = {
//       enabled: tableOptions.scrollY!.enabled,
//       oSize: tableOptions.scrollY!.oSize,
//       mode: tableOptions.scrollY!.mode
//     };
//   }
//   console.log("_scroll :>> ", _scroll);
//   saveCol.tableprop = _scroll;

//   console.log("settingConfirm saveCol :>> ", saveCol);
//   return saveCol;
// };

// const saveLayoutfunc = async(column: any, scrollParam?: any) => {

//   // 简化储存字段，以props.layoutAttr为标准
//   let saveCol = [];
//   saveCol = columnStreamlineFunc(column, searchColumns.value);
//   let _scroll = undefined;
//   console.log("settingConfirm saveCol :>> ", saveCol);
//   if (scrollParam) {
//     _scroll = {
//       enabled: scrollParam?.enabled,
//       oSize: scrollParam.oSize,
//       mode: scrollParam.mode
//     };
//     tableOptions.scrollY!.enabled = scrollParam.enabled;
//     tableOptions.scrollY!.oSize = scrollParam.oSize;
//     tableOptions.scrollY!.mode = scrollParam.mode;
//   } else {
//     console.log("tableOptions.scrollY no :>> ", tableOptions.scrollY);
//     tableOptions.scrollY!.enabled = tableOptions.scrollY!.enabled ?? scrollYDefault.value?.enabled;
//     tableOptions.scrollY!.oSize = tableOptions.scrollY!.oSize ?? scrollYDefault.value?.oSize;
//     tableOptions.scrollY!.mode = tableOptions.scrollY!.mode ?? "default";
//     _scroll = {
//       enabled: tableOptions.scrollY!.enabled,
//       oSize: tableOptions.scrollY!.oSize,
//       mode: tableOptions.scrollY!.mode
//     };
//   }
//   console.log("_scroll :>> ", _scroll);

//   // 保存布局
//   props.dwname && (await layoutStore.setDwLayout(props.dwname, { tableprop: _scroll, columns: saveCol }, t));
// }

/**
 * @description 整理保存属性
 * @param {Array} column 列数组
 * @param {Object} scrollParam 虚拟滚动属性
 * @param {boolean} online 是否获取线上版本
 * @param {number} empid 员工id
 * @returns {Object} saveCol 整理后的保存属性
 */
const saveColumnsFunc = async (argColumns: any, param: any = {}, online: boolean = false, empid?: number) => {
  console.log("argColumns :>> ", argColumns);
  console.log("scrollParam :>> ", param);
  console.log("tableColumns.value :>> ", tableColumns.value);
  const prefixList = tableColumns.value.filter((item: any) => TABLE_TYPE_FILTER.includes(item?.type));
  const affixList = tableColumns.value.filter((item: any) => item.field == "operation");

  const _tableCol = tableColumns.value.filter(
    (item: any) => !TABLE_TYPE_FILTER.includes(item?.type) && item.field != "operation"
  );

  const oriColumns = await getOriColumns(true, online, empid, enumMap.value);
  // 详情页基础信息构建键值Map()
  let columnBasicinfoMap = new Map();
  for (const i in oriColumns.columns) {
    columnBasicinfoMap.set(oriColumns.columns[i].field, oriColumns.columns[i].basicinfo);
  }

  // 个性布局构建键值Map()
  let columnMap = new Map();
  // 个性布局加顺序号
  for (const i in argColumns) {
    argColumns[i].colorder = Number(i) + 2;
    columnMap.set(argColumns[i].field, argColumns[i]);
  }
  console.log("bf settingConfirm argColumns :>> ", argColumns);

  const _attr = [...props.layoutAttr, "colorder"];
  console.log("bf settingConfirm _attr :>> ", _attr);
  console.log("bf settingConfirm _tableCol :>> ", _tableCol);
  _tableCol.forEach((col: any) => {
    let colMap = columnMap.get(col.field);
    let colBasicMap = columnBasicinfoMap.get(col.field);
    if (colMap) {
      // 只更新关键字段，但不更新field和title字段
      for (const key of _attr) {
        if (col.hasOwnProperty(key) && !["field", "title"].includes(key)) {
          col[key] = colMap[key];
        } else if (key.indexOf("basicinfo") > -1) {
          let _attr = key.split(".")[1];
          colBasicMap && colBasicMap.hasOwnProperty(_attr) && (col.basicinfo[_attr] = colBasicMap[_attr]);
        } else if (key.indexOf("search") > -1) {
          let _attr = key.split(".")[1];
          colMap?.search.hasOwnProperty(_attr) && (col.search[_attr] = colMap.search[_attr]);
        }
      }
    }
  });

  // 排序搜索表单项
  _tableCol.sort((a: any, b: any) => a.colorder! - b.colorder!);
  console.log("aaaaf settingConfirm _tableCol :>> ", _tableCol);

  let arr = prefixList;
  arr = arr.concat(restoreColumnsFunc(_tableCol));
  arr = arr.concat(affixList);
  console.log("arr :>> ", arr);
  // tableColumns.value = arr;
  // $table?.reloadColumn(arr);
  // isUpdate.value++;
  // console.log("settingConfirm tableColumns.value :>> ", tableColumns.value);
  // // 更新个性属性设置数据源
  // colSetting = cloneDeep(column);

  // let _save = cloneDeep(tableprop_save.value);
  // if (param.hasOwnProperty("search")) {
  //   _save.search = param.search;
  // }
  // if (param.hasOwnProperty("scrollY")) {
  //   _save.scrollY = param.scrollY;
  // }
  // if (param.hasOwnProperty("searchProject")) {
  //   _save.searchProject = param.searchProject;
  // }
  let oriOtherParams = omit(oriColumns, ["columns"])?.tableprop ?? {};
  // 空值时，重复赋值
  param.hasOwnProperty("searchProject") && (oriOtherParams.searchProject = param.searchProject);
  let _save = defaultsDeep(param, oriOtherParams);

  console.log("saveColumnsFunc _save :>> ", _save);

  let saveCol = columnStreamlineFunc(arr, _save);

  console.log("saveColumnsFunc saveCol :>> ", JSON.stringify(saveCol));
  return {
    arr,
    _save,
    saveCol
  };
};

/**
 * @description 表格设置窗口，布局保存
 * @param {Array} column 列数组
 * @param {Object} scrollParam 虚拟滚动属性
 * @param {Boolean} updateLocal 本地数据刷新 默认true
 * @param {Function} cb
 */
const settingConfirm = async (column: any, param: any = {}, updateLocal = true, cb?: any) => {
  if (!props.dwname) {
    ElMessage.error("LjVextable组件未设置储存的模版名称，无法保存");
    return false;
  }
  console.log("settingConfirm column :>> ", JSON.stringify(column));
  console.log("settingConfirm param :>> ", param);
  let { arr, _save, saveCol }: any = await saveColumnsFunc(column, param);
  const $table = tableRef.value;
  // 保存布局
  console.log("settingConfirm settingConfirm saveCol _save :>> ", JSON.stringify(saveCol), _save);
  await layoutStore.setDwLayout(props.dwname, saveCol, t);

  if (updateLocal) {
    /** 本地刷新数据 */
    tableprop_save.value = _save;

    tableOptions.scrollY!.enabled = saveCol?.tableprop.scrollY.enabled;
    tableOptions.scrollY!.oSize = saveCol?.tableprop.scrollY.oSize;
    tableOptions.scrollY!.mode = saveCol?.tableprop.scrollY.mode;

    tableColumns.value = arr;
    $table?.reloadColumn(arr);
    isUpdate.value++;
    console.log("settingConfirm tableColumns.value :>> ", tableColumns.value);
    console.log("warch project newVal settingConfirm tableprop_save.value:>> ", tableprop_save.value);
    // 更新个性属性设置数据源
    colSetting = cloneDeep(column);
  }
  cb && cb();
};

/**
 * @description 搜索栏，布局保存
 */
const saveSearchSettingFunc = async (columns: any, searchParam: any = {}, callback: any) => {
  console.log("saveSearchSettingFunc t param :>> ", typeof searchParam);
  console.log("saveSearchSettingFunc param :>> ", searchParam);
  // let _param = { search: cloneDeep(searchParam) };
  // // // 精简当前布局
  // let flatColumn = cloneDeep(tableColumns.value).filter(
  //   (item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation"
  // );
  // console.log("saveSearchSettingFunc flatColumns :>> ", flatColumn);

  // loadDwLayoutFunc(columns, false);
  // console.log("saveSearchSettingFunc dwFieldMap :>> ", dwFieldMap);
  // flatColumn = flatColumnsFunc(flatColumn, dwFieldMap);

  // console.log("saveSearchSettingFunc flatColumns :>> ", flatColumn);
  // console.log("saveSearchSettingFunc param :>> ", param);

  // // // 保存布局
  // // props.dwname && layoutStore.setDwLayout(props.dwname, saveCol, t);
  await settingConfirm(columns, { search: searchParam }, false);
  // .then(() => {
  console.log("saveSearchSettingFunc success columns :>> ", columns);
  searchColumns.value = columns;

  callback && callback();
  // });
};

/**
 * @description 搜索栏，保存搜索方案
 */
const editSearchProjectFunc = async (columns: any, params: any, callback: any) => {
  console.log("editSearchProjectFunc columns :>> ", columns);
  console.log("editSearchProjectFunc params :>> ", params);
  await settingConfirm(columns, { searchProject: params }, false);

  callback && callback();
};

const autoUpdataSearchParams = (data: any) => {
  // searchParam.value = defaultsDeep(data, searchParam.value);
  searchParam.value = { ...data, pageNum: 1, pageSize: searchParam.value.pageSize };
  console.log("autoUpdataSearchParams searchParam.value :>> ", searchParam.value, tableprop_save.value);
};

//表格拖拽调整列宽
const handleResizChange = (ev: any) => {
  tableColumns.value.forEach(item => {
    if (item.field == ev.column.field) {
      item.width = ev.resizeWidth;
    }
  });
  colSetting.forEach(item => {
    if (item.field == ev.column.field) {
      item.width = ev.resizeWidth;
    }
  });
  console.log("tableColumns :>> ", tableColumns.value);

  // 精简当前布局
  let saveCol = columnStreamlineFunc(tableColumns.value, tableprop_save.value);

  // 保存布局
  props.dwname && layoutStore.setDwLayout(props.dwname, saveCol, t);
};

/**
 *
 * @param columns 列
 * @param flatArr 还原数组
 *
 * @returns {Array} flatArr
 */
const restoreColumnsFunc = (columns: ColumnProps[]) => {
  //先检测是不是数组类型
  if (!Array.isArray(columns)) {
    return [];
  }
  // JS的对象就是hash表
  const targetArr: ColumnProps[] = [];
  columns.forEach((item: ColumnProps) => {
    if (!item?.parents) {
      targetArr.push(item);
    } else {
      if (item?.parents.length > 1) {
        targetArr.push(releaseParentsFunc(item?.parents, item));
      } else {
        let rtArr = {
          field: item?.parents[item?.parents.length - 1],
          visible: true,
          _children: [item]
        };
        targetArr.push(rtArr);
      }
    }
  });
  return gatherColFunc(targetArr);
};

/**
 * 还原父级各层级
 * @param arr 数组
 * @param item ColumnProps
 */
const releaseParentsFunc = (arr: string[], item: any) => {
  let oArr = JSON.parse(JSON.stringify(arr));
  oArr.shift();
  let obj: any = {
    field: arr[0],
    visible: true,
    _children: []
  };
  if (oArr.length == 0) {
    obj._children.push(item);
  } else {
    obj._children.push(releaseParentsFunc(oArr, item));
  }
  return obj;
};

/**
 * 相邻层级归类
 * @param columns 列数组
 */
const gatherColFunc = (columns: ColumnProps[]) => {
  if (!Array.isArray(columns)) {
    return [];
  }

  const prefixList = columns.filter((item: any) => TABLE_TYPE_FILTER.includes(item?.type));
  const affixList = columns.filter((item: any) => item.field == "operation");
  // JS的对象就是hash表
  let arr: any = [];
  const objKey: any = [];
  columns.forEach((item: ColumnProps) => {
    if ((!item.type || item.type == "html") && item.field != "operation") {
      if (objKey.length && item?.field == objKey[objKey.length - 1]) {
        arr[objKey.length - 1]._children = arr[objKey.length - 1]._children?.concat(item._children);
      } else {
        arr.push(item);
        objKey.push(item.field);
      }
    }
  });
  arr.forEach((item: ColumnProps) => {
    if (item._children) {
      item._children = gatherColFunc(item?._children);
      let chidlNum = item._children?.filter(val => !val._children).length;
      if (chidlNum) {
        // item.visible = item._children?.filter(val => !val.visible).length != item._children?.filter(val => !val._children).length;
        item.visible = Boolean(item._children?.filter(val => val.visible).length);
        item.parentHidden =
          item._children?.filter(val => val.parentHidden && !val._children).length ==
          item._children?.filter(val => !val._children).length;
      } else {
        // 子级的均含有_children，即没有显示列，
        item.visible = Boolean(item._children?.filter(val => val.visible).length);
        item.parentHidden = Boolean(item._children?.filter(val => val.parentHidden).length);
      }
      if (item._children) {
        item.fixed = item._children[0].fixed ?? undefined;
      }
    }
  });

  let result = prefixList;
  result = result.concat(arr);
  result = result.concat(affixList);
  return result;
};

// 🙅‍♀️ 不需要打印可以把以下方法删除，打印功能目前存在很多 bug
// 处理打印数据（把后台返回的值根据 enum 做转换）
// const printData = computed(() => {
//   const handleData = props.data ?? tableData.value;
//   const printDataList = JSON.parse(JSON.stringify(selectedList.value.length ? selectedList.value : handleData));
//   // 找出需要转换数据的列（有 enum || 多级 prop && 需要根据 enum 格式化）
//   const needTransformCol = flatColumns.value!.filter(
//     item => (item.enum || (item.field && item.field.split(".").length > 1)) && item.isFilterEnum
//   );
//   needTransformCol.forEach(colItem => {
//     printDataList.forEach((tableItem: { [key: string]: any }) => {
//       tableItem[handleProp(colItem.field!)] =
//         colItem.field!.split(".").length > 1 && !colItem.enum
//           ? formatValue(handleRowAccordingToProp(tableItem, colItem.field!))
//           : filterEnum(handleRowAccordingToProp(tableItem, colItem.field!), enumMap.value.get(colItem.field!), colItem.fieldNames);
//       for (const key in tableItem) {
//         if (tableItem[key] === null) tableItem[key] = formatValue(tableItem[key]);
//       }
//     });
//   });
//   return printDataList;
// });

// 打印表格数据（💥 多级表头数据打印时，只能扁平化成一维数组，printJs 不支持多级表头打印）
// const print = () => {
//   const header = `<div style="text-align: center"><h2>${props.title}</h2></div>`;
//   const gridHeaderStyle = "border: 1px solid #ebeef5;height: 45px;color: #232425;text-align: center;background-color: #fafafa;";
//   const gridStyle = "border: 1px solid #ebeef5;height: 40px;color: #494b4e;text-align: center";
//   printJS({
//     printable: printData.value,
//     header: props.title && header,
//     properties: flatColumns
//       .value!.filter(item => !["checkbox", "index", "expand"].includes(item.type!) && !item.visible && item.field !== "operation")
//       .map((item: ColumnProps) => ({ field: handleProp(item.field!), displayName: item.label })),
//     type: "json",
//     gridHeaderStyle,
//     gridStyle
//   });
// };

const initLayoutColumns = () => {
  // 数行化，还原个性设置
  tableColumns.value = loadRenderAttr(restoreColumnsFunc(flatColumns.value));
  // tableRef.value?.reloadColumn(tableColumns.value);
  console.log("数行化，还原个性设置 tableColumns.value :>> ", tableColumns.value);

  colSetting = cloneDeep(flatColumns.value).filter(
    (item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation"
  );

  let dSort = tableColumns.value.filter(col => col.field && col.sortable && col.order);
  console.log("defaultSort :>> ", dSort);
  defaultSort.value = dSort.map(col => {
    return {
      field: col.field!,
      table: col.table!,
      order: col.order!,
      sortTime: col.sortTime ?? 0
    };
  });
  defaultSort.value.sort((a, b) => a.sortTime - b.sortTime);
  tableOptions.sortConfig!.defaultSort = defaultSort.value;
  console.log("tableOptions :>> ", tableOptions);

  // // 记录原始列
  // let prototype = flatColumnsFunc(cloneDeep(props.columns));
  // prototypeCol = prototype.filter(
  //   (item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation"
  // );

  // tableRef.value?.reloadColumn(tableColumns.value);
  nextTick(() => {
    isUpdate.value++;
  });

  // 过滤需要搜索的配置项
  searchColumns.value = flatColumns.value.filter((item: any) => item.search?.el || item.search?.render);

  console.log("init searchColumns.value :>> ", searchColumns.value);

  // 读取缓存搜索记录
  let queryHabit = {};
  if (props.dwname && props.ifLoadQueryHabit) {
    queryHabit = userStore.getQueryHabit(props.dwname);
  }
  console.log("init LayoutColumns queryHabit :>> ", queryHabit);

  // 设置搜索表单排序默认值 && 设置搜索表单项的默认值
  searchColumns.value.forEach((column, index) => {
    column.search!.order = column.search!.order ?? index + 2;
    if (column.search?.defaultValue !== undefined && column.search?.defaultValue !== null) {
      searchInitParam.value[column.search.key ?? handleProp(column.field!)] = column.search?.defaultValue;
      searchParam.value[column.search.key ?? handleProp(column.field!)] = column.search?.defaultValue;
    }
  });
  console.log("init LayoutColumns searchParam.value :>> ", searchParam.value);
  // 表格搜索栏,设置缓存搜索信息
  /** 赋值初始化搜索表单 */
  if (props.initParam) {
    for (const key in props.initParam) {
      !Object.keys(searchParam.value).includes(key) && (searchParam.value[key] = props.initParam[key]);
    }
  }
  Object.assign(searchParam.value, queryHabit);
  // 第一次搜索带入参数
  totalParam.value = searchParam.value;

  // 排序搜索表单项
  searchColumns.value.sort((a, b) => a.search!.order! - b.search!.order!);
  emit("layoutChange", tableColumns.value);
};

const loadColumns = (columns: any) => {
  flatColumns.value = flatColumnsFunc(cloneDeep(columns));
  tableColumns.value = loadRenderAttr(restoreColumnsFunc(flatColumns.value));
  console.log("数行化，还原个性设置 tableColumns.value onllyyyyy:>> ", columns, tableColumns.value);
  nextTick(() => {
    isUpdate.value++;
  });
};

/**
 * @description 获取表格数据后，自动执行选中第一行
 */
const afterGetData = () => {
  emit("afterMounted", tableData.value);
  if (props.autoSelectFirstAfterRefresh && tableData.value.length) {
    nextTick(() => {
      tableRef.value?.setCurrentRow(tableData.value[0]);
      if (props.tableEvents && "current-change" in props.tableEvents) {
        props.tableEvents["current-change"]({ newValue: tableData.value[0], row: tableData.value[0] });
      }
    });
  }
};

// 初始化请求
onMounted(async () => {
  await loadLayoutFunc();

  initLayoutColumns();
  console.log("onMounted .ifLoadQueryHabit :>> ", searchParam.value);

  if (props.requestAuto) {
    getTableList().then(() => {
      emit("firstMounted", tableData.value);
      console.log("onMounted tableColumns.value :>> ", tableColumns.value);

      nextTick(() => {
        // 指导
        props.toolButton.indexOf("guide") > -1 && checkIfNeedGuide();
        afterGetData();
      });
    });
  } else {
    emit("firstMounted", tableData.value);
    afterGetData();
  }

  /**
   * @description 获取打印机选项状态
   */
  toGetPrinterState();
});

/**
 * @description 重置布局
 */
const resetSetting = async (cb: any) => {
  let oriColumns = await getOriColumns(true, true, -1, enumMap.value);
  console.log("oriColumns :>> ", oriColumns);
  if (oriColumns.columns.length) {
  } else {
    ElMessage.warning(t("sys.layout.empty") + props.dwname);
  }
  cb && cb(oriColumns);

  // layoutStore.getDwLayout_online(-1, props.dwname!, 0).then((layout: any) => {
  //   console.log("layoutStore dwlayoutGet:>> ", layoutStore.dwlayoutGet);

  //   if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
  //     let dwLayout: ColumnProps[] = [];
  //     let scrollYDefault = {};
  //     console.log("resetSetting loadLayoutFunc layout :>> ", layout);
  //     if (layout?.hasOwnProperty("itemvalue") && layout.itemvalue) {
  //       // 表格结构： {tableprop: string, columns: string}
  //       typeof layout.itemvalue == "string" && (layout.itemvalue = JSON.parse(layout.itemvalue.replace(/'/g, '"')));
  //       // 兼容部分结构直接记录行数据
  //       if (layout.itemvalue.hasOwnProperty("columns") && layout.itemvalue.columns) {
  //         dwLayout = layout.itemvalue.columns;
  //       } else {
  //         dwLayout = layout.itemvalue;
  //       }

  //       if (layout.itemvalue?.hasOwnProperty("tableprop") && layout.itemvalue.tableprop) {
  //         scrollYDefault = layout.itemvalue.tableprop;
  //       }
  //     }

  //     // 读取默认属性
  //     loadDwLayoutFunc(props.columns, false);
  //     console.log(" resetSetting dwFieldMap :>>>>>>>>>>>>>>>>>>>>>", dwFieldMap);
  //     let prototype = flatColumnsFunc(dwLayout, dwFieldMap);
  //     let prototypeCol = prototype.filter((item: any) => !TABLE_TYPE_FILTER.includes(item.type!) && item.field !== "operation");
  //     cb && cb(prototypeCol, scrollYDefault);
  //   } else {
  //     ElMessage.warning(t("sys.layout.empty") + props.dwname);
  //     cb && cb([]);
  //   }
  // });
};

/**
 * @description 保存系统默认模版
 */
const saveDefaultLayout = async (column: any, param: any, cb: any) => {
  if (!props.dwname) {
    ElMessage.error("LjVextable组件未设置储存的模版名称，无法保存");
    return false;
  }
  let { saveCol }: any = await saveColumnsFunc(column, param, true, -1);
  // const $table = tableRef.value;
  // 保存布局
  console.log("settingConfirm saveCol :>> ", saveCol);
  await layoutStore.saveDwLayout_online(-1, props.dwname, saveCol);

  cb && cb();
  // settingConfirm(tableColumns.value, {}, false).then(() => {
  //   let orderstr = defaultSort.value.map((item: any) => `${item.field} ${item.order}`).join(", ");
  //   console.log("after settingConfirm orderstr :>> ", orderstr);
  //   searchInitParam.value.orderstr = orderstr;

  //   // 当页码大于1时，才重新加载数据
  //   if (fullData.length >= pageable.value.pageSize) {
  //     getTableList();
  //   }
  // });
};

/**
 * @description 主动刷新数据
 */
const refresh = async (outline?: boolean) => {
  !outline && (await getTableList());
  nextTick(() => {
    isUpdate.value++;

    afterGetData();
  });
};

/**
 * @description 清除排序
 */
const clearSortEvent = (field?: string) => {
  const $table = tableRef.value;

  if (field) {
    if ($table) {
      $table.clearSort(field);
      defaultSort.value = defaultSort.value.filter((itm: any) => itm.field !== field);
    }
    tableColumns.value.forEach((item: any) => {
      if (item.field === field) {
        item.order = "";
        item.sortTime = 0;
        return;
      }
    });
  } else {
    if ($table) {
      $table.clearSort();
      defaultSort.value = [];
    }
    tableColumns.value.forEach((item: any) => {
      item.order = "";
      item.sortTime = 0;
    });
  }

  let fullData = [];
  if ($table) {
    fullData = $table.getTableData().fullData;
  }

  settingConfirm(tableColumns.value, {}, false).then(() => {
    let orderstr = defaultSort.value.map((item: any) => `${item.field} ${item.order}`).join(", ");
    console.log("after settingConfirm orderstr :>> ", orderstr);
    searchInitParam.value.orderstr = orderstr;

    // 当页码大于1时，才重新加载数据
    if (fullData.length >= pageable.value.pageSize) {
      getTableList();
    }
  });
};

/**
 * @description 监听排序变化
 */
const handleSortChange = (data: any) => {
  console.log("handleSortChange data :>> ", data);
  const { sortList } = data;
  defaultSort.value = sortList.map((itm: any) => {
    return {
      field: itm.field,
      title: itm.column.title,
      order: itm.order,
      sortTime: itm.sortTime
    };
  });
  console.log("defaultSort.value :>> ", defaultSort.value);
  console.log("searchInitParam.value :>> ", searchInitParam.value);

  defaultSort.value.map((sortitem: any) => {
    tableColumns.value.forEach((item: any) => {
      if (item.field == sortitem.field) {
        item.order = sortitem.order;
        item.sortTime = sortitem.sortTime;
        return;
      }
    });
  });

  const $table = tableRef.value;
  let fullData = [];
  if ($table) {
    fullData = $table.getTableData().fullData;
  }

  settingConfirm(tableColumns.value, {}, false).then(() => {
    let orderstr = defaultSort.value.map((item: any) => `${item.field} ${item.order}`).join(", ");
    console.log("after settingConfirm orderstr :>> ", orderstr);
    searchInitParam.value.orderstr = orderstr;

    // 当页码大于1时，才重新加载数据
    if (fullData.length >= pageable.value.pageSize) {
      getTableList();
    }
  });
};

/**
 * @description 导出数据
 */
const exportDataEvent = () => {
  const $table = tableRef.value;
  $table?.openExport();
};

/**
 * @description 导出数据
 */
const importDataEvent = () => {
  const $table = tableRef.value;
  $table?.importData({
    remote: true,
    importMethod: ({ file }) => {
      console.log("importMethod file :>> ", file);
      // 处理表单
      // const formBody = new FormData();
      // formBody.append("file", file);
      // console.log("importMethod formBody :>> ", formBody);
      // 上传文件
      return props
        .importApi([file])
        .then(rest => {
          // if (rest.status === 200) {
          //   this.$refs.grid.commitProxy('query');
          //   this.$message({
          //     type: 'success',
          //     message: '导入成功'
          //   });
          // } else {
          //   this.$message({
          //     type: 'error',
          //     message: '导入失败'
          //   });
          // }
        })
        .catch(() => {
          // this.$message({ content: '导入失败，请检查数据是否正确！', status: 'error' })
        });
    }
  });
};

/**
 * @description 打印模块
 */
// const printEditorRef = ref();
// const PrintTemplateRef = ref();
// const hiprinterStore = useHiprinterStore();
// /**
//  * @description 获取打印模块个性名称
//  * @param name 额外名称
//  */
// const getPrintDwname = (name = "") => {
//   return props.dwname + name + "_print_template";
// };

// /**
//  * @description 直接打印：明细设置记录
//  */
// const hiprinterStateList = ref(false);
// /**
//  * @description 直接打印：条码设置记录
//  */
// const hiprinterStateMx = ref(false);
// const toGetPrinterState = () => {
//   let _mx = JSON.stringify(hiprinterStore.getPrinter(getPrintDwname(""))) != "{}";
//   hiprinterStateList.value = _mx;

//   let _barcode = JSON.stringify(hiprinterStore.getPrinter(getPrintDwname("_mx"))) != "{}";
//   hiprinterStateMx.value = _barcode;
// };

// /**
//  * 获取打印数据, 并返回厂商comid
//  */
// const getPrintDataFunc = (callback: any) => {
//   const $table = tableRef.value;
//   if ($table) {
//     const _records = $table.getCheckboxRecords() ?? [];
//     const curRecords = $table.getCurrentRecord() ?? null;
//     let cuscomid = 0;
//     if (_records.length == 0 && !curRecords) {
//       ElMessage.warning(t("common.table.printSelectDataTips"));
//       return;
//     } else {
//       if (_records.length > 0) {
//         cuscomid = _records[0].cuscomid;
//         for (let i = 1; i < _records.length; i++) {
//           if (_records[i].cuscomid != cuscomid) {
//             ElMessage.warning(t("common.table.printSelectSameTips"));
//             return false;
//           }
//         }
//       } else if (curRecords) {
//         cuscomid = curRecords.cuscomid;
//       }
//     }
//     selectRecords.value = !_records.length ? [curRecords] : _records;

//     let checkData = true;
//     props.beforePrintCallback && (checkData = props.beforePrintCallback(selectRecords.value));
//     console.log("checkData :>> ", checkData);
//     if (!checkData) return false;
//     callback && callback(cuscomid);
//   }
// };

// const activePrint = ref("");
// /**
//  * @description 打开打印
//  */
// const openPrint = (name = "") => {
//   activePrint.value = name ?? "";
//   // 获取打印数据
//   getPrintDataFunc((cuscomid: number) => {
//     PrintTemplateRef.value?.open({
//       dwname: getPrintDwname(name),
//       opposidecomid: cuscomid
//     });
//   });
// };
// /**
//  * @description 直接打开预览
//  */
// const openPrintPriveiew = (name = "", direct = false) => {
//   activePrint.value = name ?? "";
//   // 获取打印数据
//   getPrintDataFunc(async (cuscomid: number) => {
//     // PrintTemplateRef.value.getData()
//     // let _key = getPrintDwname(name);
//     // // 获取打印模板
//     // const data = await getPrintTemplate({
//     //   dwname: _key,
//     //   opposidecomid: cuscomid
//     // });
//     // console.log("getData data :>> ", data);
//     // if (data?.templateList.length) {
//     //   toPreviewPrintTemplate(data.templateList[0], _key, direct);
//     // } else {
//     //   ElMessage.warning(t("business.selector.printTemplate.printTemplageEmpty"));
//     //   PrintTemplateRef.value?.open({
//     //     dwname: _key,
//     //     opposidecomid: cuscomid
//     //   });
//     // }
//   });
// };

// /**
//  * 修改:打印模板列表页-修改
//  * @param data 打印模板
//  */
// const toEditPrintTemplate = (data?: any) => {
//   console.log("toEditPrintTemplate data :>> ", data);
//   if (data && data.comid == 0) {
//     // 系统模板,另存为
//     data.aliase = "新建模版";
//     // 新增模版
//     delete data.printid;
//   }
//   let tem = data ?? {
//     tid: 0,
//     aliase: "新建模版",
//     dwname: props.dwname + "_print_template",
//     content: {},
//   };
//   if (typeof tem.content == "string") {
//     tem.content = JSON.parse(tem.content);
//   }
//   console.log("selectRecords.value :>> ", selectRecords.value);
//   let printData = {
//     userInfo: userStore.userInfo,
//     // cusname: selectRecords.value[0].comname,
//     table: selectRecords.value
//   };
//   if (props.printDataCallback) {
//     props.printDataCallback(printData).then((res: any) => {
//       console.log("res :>> ", res);
//       printEditorRef.value?.open(tem, res);
//     });
//   } else {
//     printEditorRef.value?.open(tem, printData);
//   }
// };
// /**
//  * @description 预览:打印模板列表-预览
//  */
// const toPreviewPrintTemplate = (data: any) => {
//   // console.log("toEditPrintTemplate data :>> ", data);
//   // let tem = data;
//   // if (typeof tem.content == "string") {
//   //   tem.content = JSON.parse(tem.content);
//   // }
//   // let printData = {
//   //   comInfo: userStore.comInfo,
//   //   cusname: selectRecords.value[0].comname,
//   //   table: selectRecords.value
//   // };
//   // if (props.printDataCallback) {
//   //   props.printDataCallback(printData).then((res: any) => {
//   //     printEditorRef.value?.onlyPreview(tem, res, tem.aliase);
//   //   });
//   // } else {
//   //   printEditorRef.value?.onlyPreview(tem, printData, tem.aliase);
//   // }
// };

/**
 * @description 打印:打印模板列表-打印
 */
// const toPrintPrintTemplate = (data: any, callback: any) => {
// console.log("toEditPrintTemplate data :>> ", data);
// let tem = data;
// if (typeof tem.content == "string") {
//   tem.content = JSON.parse(tem.content);
// }
// let printData = {
//   comInfo: userStore.comInfo,
//   cusname: selectRecords.value[0].comname,
//   table: selectRecords.value
// };
// if (props.printDataCallback) {
//   props.printDataCallback(printData).then((res: any) => {
//     printEditorRef.value?.onlyPrint(tem, res, tem.aliase);
//     callback && callback();
//   });
// } else {
//   printEditorRef.value?.onlyPrint(tem, printData, tem.aliase);
//   callback && callback();
// }
// };

// /**
//  * 保存:打印模板编辑器
//  * @param data 打印模板参数
//  */
// const toSavePrintTemplate = async (data: any, callback?: any) => {
//   let _data = pick(data, PRINT_KEY_ATTR);
//   await savePrintTemplate({ template: _data });

//   ElMessage.success(t("sys.api.sueccessToSave"));

//   callback && callback();
// };
/**
 * 关闭后,是否刷新打印模板列表页
 * @param saved 是否有保存过
 */
const toClosedPrintEditor = (saved: boolean) => {
  saved && printTemplateRef.value?.getData();
};

const locationRef = ref();
const locationBtnRef = ref();
const scrollCol = ref("");
const locationAutocompleteRef = ref();
const oriTableData = ref<any>([]);
const locationFrom = reactive({
  field: "",
  value: ""
});

// onKeyStroke(["f", "Ctrl"], e => {
//   e.preventDefault();
//   oriTableData.value = cloneDeep(tableData.value);
//   locationDialogRef.value.show();
//   console.log("onKeyStroke e :>> ", e);
// });

/**
 * @description 定位列
 */
const funcScrollToCol = (item: any) => {
  console.log("locationAutocompleteRef.value :>> ", locationAutocompleteRef.value);
  // if (locationTabActive.value == "data") return false;
  let idx = tableColumns.value.findIndex((v: any) => v.field == item.field);
  let lastField = item.field;
  if (idx > 0) {
    lastField = tableColumns.value[idx - 1].field;
  }
  let _space = 400; //ms
  if (tableRef.value) {
    tableRef.value.scrollToColumn(lastField);
    tableRef.value.setCurrentColumn(item.field).then(() => {
      setTimeout(() => {
        tableRef.value &&
          tableRef.value.clearCurrentColumn().then(() => {
            setTimeout(() => {
              tableRef.value &&
                tableRef.value.setCurrentColumn(item.field).then(() => {
                  setTimeout(() => {
                    tableRef.value && tableRef.value.clearCurrentColumn();
                  }, _space);
                });
            }, _space);
          });
      }, _space);
    });
  }
};

const matchData = ref<any>([]);
const matchIndex = ref(0);

const funcChangeLocation = (index: number) => {
  console.log("index :>> ", index);
  let _index = matchIndex.value + index;
  if (_index >= matchData.value.length) {
    _index = 0;
  } else if (_index < 0) {
    _index = matchData.value.length - 1;
  }
  funcSrollToRow(locationFrom.value, _index);
};
/**
 * @description 定位行
 */
const funcSrollToRow = (value: any, index = 0) => {
  matchIndex.value = index;

  const filterVal = String(value).trim().toLowerCase();
  if (filterVal) {
    const filterRE = new RegExp(filterVal, "gi");

    tableData.value = cloneDeep(oriTableData.value);
    matchData.value = tableData.value.filter((v: any) => {
      let _match = false;
      for (const key in v) {
        if (String(v[key]).toLowerCase().indexOf(value) > -1) {
          _match = true;
          v[key] = String(v[key]).replace(filterRE, match => `<span class="keyword-lighten">${match}</span>`);
        }
        let idx = tableColumns.value.findIndex((itm: any) => key == itm.field);
        if (idx > 0 && ["hmlt", null, undefined].includes(tableColumns.value[idx].type)) {
          tableColumns.value[idx].type = _match ? "html" : null;
        }
      }
      // v.type = _match ? "html" : null;

      return _match;
      // return String(v[locationFrom.field]).toLowerCase().indexOf(value) > -1;
    });
    console.log(" tableData.value :>> ", tableData.value, tableColumns.value, matchData.value);

    let idx = tableColumns.value.findIndex((v: any) => v.field == locationFrom.field);
    let lastField = locationFrom.field;
    if (idx > 0) {
      lastField = tableColumns.value[idx - 1].field || lastField;
    }

    let _space = 400; //ms
    if (tableRef.value) {
      // let getRow = tableRef.value.getRowById(matchData.value[matchIndex.value]._X_ROW_KEY);
      let _row = matchData.value[matchIndex.value];
      // console.log("getRow :>> ", getRow);
      tableRef.value.scrollToRow(_row, lastField);
      tableRef.value.setCurrentColumn(locationFrom.field);
      tableRef.value.setCurrentRow(_row).then(() => {
        setTimeout(() => {
          if (tableRef.value) {
            tableRef.value.clearCurrentColumn();
            tableRef.value.clearCurrentRow();
          }
        }, _space);
      });
    }
  }
};
// 节流
const disshow = throttle((val: any) => {
  funcSrollToRow(val);
}, 500);
/**
 * @description 定位行/列
 */
const locationQuerySearch = (queryString: string, cb: any) => {
  let _query = queryString.toLowerCase();
  const results = queryString ? pinyinFilter(_query, tableColumns.value, ["title", "field"]) : tableColumns.value;
  console.log("results :>> ", results);

  cb(results);
};

const autoShowLocationPopover = () => {
  locationAutocompleteRef.value.focus();
};

const autoCloseLocation = () => {
  tableData.value = cloneDeep(oriTableData.value);
  tableColumns.value = tableColumns.value.map(item => {
    if (["hmlt", null, undefined].includes(item.type)) {
      item.type = null;
    }
    return item;
  });
};

// const locationDialogRef = ref();
// const locationTabActive = ref("col");
// const handleShowLocation = () => {
//   locationTabActive.value = "col";
//   locationDialogRef.value.show();
// };

// /**动态合并 */
// const mergeCells = ref<VxeTablePropTypes.MergeCells>([
//   { row: 4, col: 2, rowspan: 2, colspan: 5 },
//   { row: 30, col: 3, rowspan: 10, colspan: 1 },
//   { row: 80, col: 4, rowspan: 30, colspan: 3 }
// ]);

// 监听页面 initParam 改化，重新获取表格数据
watch(
  () => props.initParam,
  async val => {
    await search();
    afterGetData();
  },
  { deep: true }
);

/**
 * @description vxeTable方法封装
 */
const vxeTableEvents = {
  getTableData: () => tableRef.value?.getTableData(),
  insertAt: (records: any | any[], row?: any | -1 | 0) => tableRef.value?.insertAt(records, row),
  setCurrentRow: (params: any) =>
    nextTick(() => {
      tableRef.value?.setCurrentRow(params);
    }),
  setRow: (rows: any, record: any) => tableRef.value?.setRow(rows, record),
  remove: (params: any) => tableRef.value?.remove(params),
  getCurrentRecord: () => tableRef.value?.getCurrentRecord(),
  getCheckboxRecords: (isFull: any) => tableRef.value?.getCheckboxRecords(isFull),
  /**
   * @description 获取当前勾选/选中的数据，否则自动选择第一条数据
   */
  getCurrentRecords: () => {
    const _records = tableRef.value?.getCheckboxRecords() ?? [];
    const _cRecords = tableRef.value?.getCurrentRecord() ?? null;

    let curRecords: any[] = [];
    if (_records.length) {
      // 获取勾选列表
      curRecords = _records;
    } else if (_cRecords) {
      // 获取当前选中数据
      curRecords = [_cRecords];
    } else {
      // 默认获取第一条记录
      let visibleData = tableRef.value?.getTableData().visibleData;
      if (visibleData?.length) {
        curRecords = [visibleData[0]];
        tableRef.value?.setCurrentRow(visibleData[0]);
      }
    }

    return curRecords;
  }
};

/**
 * @description 点击表格外部，关闭编辑状态
 */
onClickOutside(tableRef, event => {
  let ifEdit = tableRef.value.getEditRecord();

  // 检查点击事件的目标元素是否在排除列表中，（下拉）
  const excludeElements = [
    event.target?.closest(".el-popper") ?? undefined,
    event.target?.closest(".vxe-select--panel") ?? undefined,
    event.target?.closest(".vxe-input--panel") ?? undefined
  ];
  const isExcluded = excludeElements.filter(Boolean).some(el => el.contains(event.target));

  // console.log("onClickOutside excludeElements :>> ", excludeElements);
  // console.log("onClickOutside isExcluded :>> ", isExcluded, !isExcluded && ifEdit);

  if (!isExcluded && ifEdit) {
    tableRef.value.clearEdit();
  }
});

/**
 * @description 当前编辑的单元格
 */
const currentEditCell = ref<any>({
  field: 0,
  rowIndex: 0
});

const scrollTo = (row: any, field?: any) => {
  tableRef.value.setCurrentRow(row);
  tableRef.value.scrollToRow(row, field);
};

// 暴露给父组件的参数和方法(外部需要什么，都可以从这里暴露出去)
defineExpose({
  element: tableRef,
  ...vxeTableEvents,
  tableData,
  // pageable,
  searchParam,
  // searchInitParam,
  tableColumns,
  getTableList,
  search,
  reset,
  refresh,
  // handleSizeChange,
  // handleCurrentChange,
  handlePageChange,
  openColSetting,
  // clearSelection,
  enumMap,
  baseEnumMap,
  // isSelected,
  // selectedList,
  // selectedListIds
  initLayoutColumns,
  currentEditCell,
  scrollTo,
  loadColumns
});
</script>

<style lang="scss" scoped>
.table-main {
  &.card {
    padding-top: 12px;
    padding-bottom: 0;
  }
  .search-btn.active {
    box-shadow: $shadow-1-down-inset;
  }
  .table-main__tool-button {
    margin-right: 12px;
    margin-left: 12px;
    :deep(.el-button-group) {
      .el-button:first-child {
        border-top-left-radius: 16px;
        border-bottom-left-radius: 16px;
      }
      .el-button:last-child {
        border-top-right-radius: 16px;
        border-bottom-right-radius: 16px;
      }
    }
  }
  .table-warpper {
    overflow: hidden;
    .collapse-buttons__group {
      position: absolute;
      top: 6px;
      right: $space-b1;
      z-index: 5;
    }
    // .more-btn {
    //   // opacity: 0.68;
    //   transition: all ease-in-out 0.2s;
    //   transform: translateX(70%);
    // }
    // &:hover {
    //   .more-btn {
    //     // opacity: 1;
    //     transform: translateX(0);
    //   }
    // }
  }
}
.lj-main-body.small .table-main {
  &.card {
    padding-top: 8px;
    padding-bottom: 0;
  }
}
.card + .card {
  margin-top: $space-b2;
}

/* 滚动条整体部分 */
.lj-vxetable ::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}
.lj-vxetable ::-moz-scrollbar {
  width: 12px;
  height: 12px;
}
.lj-vxetable {
  :deep(.vxe-loading) {
    background-color: rgb($color-gray-1 / 60%);
    backdrop-filter: blur(2px);
  }
}
</style>

<style lang="scss">
.lj-main-body {
  .tableheader-tabs {
    .el-tabs__header {
      margin-bottom: 0;
    }
  }
  &.small {
    .tableheader-tabs {
      --el-tabs-header-height: 33px;
    }
    .table-box .table-search,
    .table-main .table-search {
      margin-bottom: 0;
    }
  }
}
</style>
