<template>
  <div v-show="tableColumns.length > 0">
    <a-row :class="{'hiddenFunctionalArea':hiddenFunctionalArea}" :gutter="hiddenFunctionalArea ? 0 :48">
      <a-col v-show="showLeftOperaBtn">
        <span :style="{ float: 'left', marginBottom: '8px' }">
          <a-space>
            <!--            <a-button v-if="eventState.customDelete" type="primary" @click="custom('customDelete')">-->
            <!--              <a-icon type="delete"/>删除-->
            <!--            </a-button>-->
            <!--            <a-button v-if="eventState.customSave" type="primary" @click="custom('customSave')">-->
            <!--              <a-icon type="save"/>保存-->
            <!--            </a-button>-->
            <slot name="leftButton" v-if="buttonState.extra !== false" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
            <a-button v-if="buttonState.add && buttonRendering('add')" type="primary" @click="add">
              <a-icon type="plus"/>新增
            </a-button>
            <a-button v-if="buttonState.move && buttonRendering('move')" type="primary" @click="move">
              <a-icon type="plus"/>添加
            </a-button>
            <a-button
              v-if="buttonState.choose && buttonRendering('choose')"
              :disabled="!isChoose"
              type="primary"
              @click="choose">
              <a-icon type="check-square"/>选择
            </a-button>
            <a-button
              v-if="buttonState.edit && buttonRendering('edit')"
              :disabled="!isModify"
              :loading="editLoading"
              class="btn-success"
              type="dashed"
              @click="edit()">
              <a-icon :style="iconStyle" type="form"/>修改
            </a-button>
            <template
              v-if="buttonState.editRow && buttonRendering('editRow')">
              <a-button
                v-if="isEditMode"
                class="ant-btn-hover"
                @click="editRowSave">
                <a-icon :style="iconStyle" type="save"/>保存
              </a-button>
              <a-button
                v-else
                @click="openEditMode">
                <a-icon :style="iconStyle" type="edit"/>行编辑
              </a-button>
            </template>
            <a-button
              v-if="buttonState.delete && buttonRendering('delete')"
              :disabled="!isDelete"
              type="danger"
              @click="deleteItem">
              <a-icon :style="iconStyle" type="delete"/>删除
            </a-button>
            <a-button
              v-if="buttonState.import && buttonRendering('import')"
              type="dashed"
              @click="importData">
              <a-icon :style="iconStyle" type="import"/>导入
            </a-button>
            <a-dropdown v-if="!buttonState || buttonState.export && buttonRendering('export')">
              <a-menu slot="overlay">
                <a-menu-item :disabled="selectedRowKeys.length === 0" key="1" @click="handleExport('selected')"><a-icon
                  :style="iconStyle"
                  type="ordered-list"/>导出选中数据</a-menu-item>
                <a-menu-item key="2" @click="handleExport('curPage')"><a-icon :style="iconStyle" type="snippets"/>导出本页数据</a-menu-item>
                <a-menu-item key="3" @click="handleExport('exportByQuery')"><a-icon :style="iconStyle" type="download"/>导出所有符合条件的数据</a-menu-item>
              </a-menu>
              <a-button>导出 <a-icon type="down" :style="iconStyle"/> </a-button>
            </a-dropdown>
            <a-dropdown v-if="!buttonState || buttonState.print && buttonRendering('print')">
              <a-menu slot="overlay">
                <a-menu-item :disabled="selectedRowKeys.length === 0" key="1" @click="handlePrint('selected')"><a-icon
                  :style="iconStyle"
                  type="ordered-list"/>打印选中数据</a-menu-item>
                <a-menu-item key="2" @click="handlePrint('curPage')"><a-icon :style="iconStyle" type="snippets"/>打印本页数据</a-menu-item>
                <a-menu-item key="3" @click="handlePrint('exportByQuery')"><a-icon :style="iconStyle" type="download"/>打印所有符合条件的数据</a-menu-item>
              </a-menu>
              <a-button>打印 <a-icon type="printer" :style="iconStyle"/> </a-button>
            </a-dropdown>
            <template
              v-if="buttonState.extra !== false">
              <!-- 遍历按钮配置数组，动态生成按钮 -->
              <a-button
                v-for="(button, index) in editButtonStateData"
                :key="index"
                :type="button.type || 'dashed'"
                @click="editButtonStateDataClick(index)"
                class="btn-success"
              >
                <a-icon type="dashed" :style="iconStyle"/>
                {{ button.buttonName }}
              </a-button>
            </template>
            <a-button
              v-if="allowedCardMode && !simpleMode"
              @click="changeViewMode"
              :type="isTableMode ? '' : 'primary'">
              看板模式
            </a-button>
            <a-badge
              v-if="selectRowMode === 'listView'"
              :count="selectedRows.length"
              :number-style="{ backgroundColor:theme.color }"
            >
              <a-button
                type="dashed"
                @click="showTempData">
                <a-icon :style="iconStyle" type="monitor"/>已选择
              </a-button>
            </a-badge>
            <!-- 头部附加栅格 -->
            <x-report
              v-if="attachGrid"
              :env="env"
              :isWidget="true"
              :use-oss-for-img="false"
              :config-name="attachGrid"
              :show-img-in-cell="true"
              :display-only="true"
              :edit-mode="false"
              :show-save-button="false"
              :dont-format="true"/>

            <slot name="button" v-if="buttonState.extra !== false" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
          </a-space>
        </span>
      </a-col>
      <a-col v-show="showRightTools && !simpleMode">
        <span :style="{ float: 'right', overflow: 'hidden', marginBottom: '8px' }">
          <a-button-group>
            <a-tooltip v-if="showSummary" title="汇总" placement="bottom">
              <a-button @click="showDrawer">
                <a-icon :style="iconStyle" type="project"/>
              </a-button>
            </a-tooltip>
            <a-tooltip title="重新查询" placement="bottom">
              <a-button @click="refresh(true)">
                <a-icon :style="iconStyle" type="reload"/>
              </a-button>
            </a-tooltip>
            <a-tooltip title="列展示/排序" placement="bottom">
              <table-setting v-if="columnSelectLoaded" v-model="tableColumns"/>
            </a-tooltip>
            <slot name="rightBtnExpand" :selectedRowKeys="selectedRowKeys" :selectedRows="selectedRows"></slot>
            <a-popover title="开发者调试信息" placement="bottomRight" v-if="!isDebugUser()">
              <template slot="content">
                <p>租户：{{ realQueryParams.$globalProp?.tenantAlias }}</p>
                <p>命名空间：{{ realQueryParams.$globalProp?.namespaceName }} - {{ realQueryParams.$globalProp?.module }}</p>
                <p>配置名称：{{ queryParamsName }}</p>
                <p>版本号：{{ realQueryParams.$globalProp?.version }}</p>
              </template>
              <a-button>
                <a-icon :style="iconStyle" type="bug"/>
              </a-button>
            </a-popover>
          </a-button-group>
        </span>
      </a-col>
    </a-row>
    <!--  如果当前是表格模式  -->
    <template v-if="isTableMode">
      <x-table-wrapper
        ref="table"
        :defaultPageSize="defaultPageSize"
        :pageSizeArray="pageSizeArray"
        :queryParamsName="queryParamsName"
        :disableAction="disableAction"
        @progressUpdated="handleProgressUpdated"
        @rowClick="handleRowClick"
        @rowDblClick="handleRowDblClick"
        @beforeDataChange="beforeDataChange"
        @expand="onExpand">
        <template slot="expandedRowRender">
          <!-- 列扩展栅格 -->
          <x-report
            v-if="expandedGrid"
            :env="env"
            ref="report"
            :isWidget="true"
            :use-oss-for-img="false"
            :config-name="expandedGrid"
            :show-img-in-cell="true"
            :display-only="true"
            :edit-mode="false"
            :show-save-button="false"
            :dont-format="true"/>
        </template>
        <template slot="footer">
          <slot
            name="footer"
            :selectedRowKeys="selectedRowKeys"
            :selectedRows="selectedRows"></slot>
        </template>
        <template slot="fixedfooter">
          <slot name="fixedfooter"></slot>
        </template>
      </x-table-wrapper>
    </template>
    <!--  如果当前是看板模式  -->
    <template v-else>
      <XDataCard
        ref="table"
        @cardEmit="handleCardEmit"
        :tableColumns="tableColumns"
        :card-config="cardModeConfig"
        :show-pagination="!simpleMode"
        :prePageSize="simpleMode ? 1000 : undefined"
        :serviceName="serviceName"
        :card-data="loadData"
        :env="env"
        :createdQuery="createdQuery"
        :simple-mode="simpleMode"/>
    </template>
    <!-- 上传文件 -->
    <a-drawer
      title="汇总信息"
      placement="right"
      :closable="false"
      :visible="summaryDrawerVisible"
      :z-index="2000"
      :width="`${summaryDrawerWidth}vw`"
      :after-visible-change="afterVisibleChange"
      @close="onClose"
    >
      <template>
        <a-row>
          <a-col :span="8" v-for="(f,index) in summaryData" :key="index">
            <a-statistic
              :title="f.title + '：'"
              :value="f.value"
              :precision="f.precision">
              <template #prefix>
                <a-spin :spinning="f.loading">
                </a-spin>
              </template>
              <template #suffix>
                <a-icon
                  v-show="!f.loading"
                  :type="f.success !== false ? 'check-circle' : 'close-circle'"
                  :style="{color: f.success !== false ? 'green' : 'red'}"/>
              </template>
            </a-statistic>
          </a-col>
          <a-col
            :span="item.span"
            v-for="(item,index) in chartsConfigArray"
            :key="`${queryParamsName}-${index}`"
            style="height: 20rem; margin-bottom: 3rem">
            <div class="custom-chart-title" v-if="item.config.title">{{ item.config.title }}</div>
            <div class="custom-chart-desc" v-if="item.config.description">{{ item.config.description }}</div>
            <g2Charts
              :key="`${queryParamsName}-${index}`"
              :chatsKey="`${queryParamsName}-${index}`"
              :is-dev="env === 'dev'"
              :config="item.config"
              :requestParameters="requestParameters"/>
          </a-col>
        </a-row>
      </template>
    </a-drawer>
    <x-import-excel
      ref="importExcel"
      @ok="importExcelOk"
      :title="title"
      :extraData="extraData"
      :service-name="serviceName"
      :env="env"
      :query-params-name="queryParamsName"
    >
      <template #importExcelSlot>
        <slot name="importExcelSlot"></slot>
      </template>
    </x-import-excel>
    <ExportExcel
      ref="exportExcel"
    />
    <a-modal @cancel="$refs.table.refresh()" v-model="selectedRowModalVisible" width="80vw" title="已选中数据" :footer="null">
      <x-table-wrapper
        ref="selectedDataTable"
        :load-selected-data="true"
        @progressUpdated="handleProgressUpdated"
        @beforeDataChange="beforeDataChange"
        @rowClick="handleRowClick"
        @rowDblClick="handleRowDblClick">
      </x-table-wrapper>
    </a-modal>
  </div>
</template>
<script>
import { STable } from '@vue2-client/components'
import { getChangedData, setDataByRealKey } from '@vue2-client/utils/util'
import * as util from '@vue2-client/utils/util'
import TableSetting from '@vue2-client/components/TableSetting/TableSetting'
import {
  query,
  querySummary,
  queryWithResource,
  remove,
  getConfigByNameAsync,
  editRowSave,
  runLogic
} from '@vue2-client/services/api/common'
import XImportExcel from '@vue2-client/base-client/components/common/XImportExcel'
import { Modal } from 'ant-design-vue'
import { mapState } from 'vuex'
import { executeStrFunction, executeStrFunctionByContext } from '@vue2-client/utils/runEvalFunction'
import debounce from 'lodash.debounce'
import XDataCard from '@vue2-client/base-client/components/common/XDataCard/XDataCard.vue'
import { getRealKeyData } from '@vue2-client/utils/formatter'
import ReportTableHome from '../../../../pages/report/ReportTableHome.vue'
import CustomFuncCel from '@vue2-client/base-client/components/common/XTable/CustomFuncCel.vue'
import ExportExcel from '@vue2-client/base-client/components/common/XTable/ExportExcel.vue'
import g2Charts from '@vue2-client/components/g2Charts/index.vue'
import moment from 'moment/moment'
import XTableWrapper from './XTableWrapper.vue'
import { isDebugUser } from '@vue2-client/utils/common'

export default {
  name: 'XTable',
  components: {
    ExportExcel,
    CustomFuncCel,
    XDataCard,
    TableSetting,
    STable,
    XImportExcel,
    g2Charts,
    XReport: () => import('@vue2-client/base-client/components/common/XReportGrid/XReport.vue'),
    ReportTableHome,
    XTableWrapper
  },
  inject: ['getSelf'],
  provide () {
    return {
      tableContext: this,
      getFormLabelData: this.getFormLabelData.bind(this)
    }
  },
  data () {
    return {
      uniqueId: `x-table-${this._uid}`, // 使用 _uid 生成唯一 ID
      // 筛选列加载状态
      columnSelectLoaded: false,
      // 预览模式
      viewMode: false,
      // 本地编辑模式
      localEditMode: false,
      // 本地编辑表单提交方式
      formSubmitTypeInLocalEditMode: 'cover',
      // 本地编辑模式所用数据源
      localEditModeDataSource: [],
      // 本地编辑模式数据源是否已由外部加载
      isLocalDataSourceLoadedExternally: false,
      // 行选择模式
      rowSelectMode: false,
      // 行选择模式-允许选中行数量，0：任意数量行，大于0：指定值数量的行
      allowSelectRowNum: 0,
      // 头部附件的栅格配置名
      attachGrid: '',
      // 表格行扩展区域的栅格配置名
      expandedGrid: '',
      // 是否展示右侧工具栏
      showRightTools: true,
      // 是否展示左边按钮栏
      showLeftOperaBtn: true,
      // 加载数据方法 必须为 Promise 对象
      loadData: parameter => {
        // 取到表格携带的表单参数
        const requestParameters = Object.assign({}, parameter)
        // 取到父组件传入的表单参数
        const conditionParams = {}
        Object.assign(conditionParams, this.fixedQueryForm)
        Object.assign(conditionParams, this.form)
        // 如果传了燃气公司字段，则进行数据处理
        if (conditionParams.orgName) {
          requestParameters.orgName = conditionParams.orgName
          delete conditionParams.orgName
        }
        Object.keys(conditionParams).forEach(key => {
          if (Array.isArray(conditionParams[key])) {
            // 检查数组中是否包含 null
            const hasNull = conditionParams[key].every(item => item === '') || conditionParams[key].length === 0
            // 如果包含 null，则删除该属性
            if (hasNull) {
              delete conditionParams[key]
            }
          }
        })
        requestParameters.conditionParams = conditionParams
        requestParameters.queryParamsName = this.queryParamsName
        requestParameters.queryParams = this.queryParams && Object.keys(this.queryParams).length > 0 ? this.queryParams : undefined
        this.requestParameters = requestParameters
        // 加载数据
        return this.loadTableData(requestParameters)
      },
      requestParameters: {},
      rowKey: undefined,
      // x滚动条宽度
      scrollXWidth: 1600,
      // y滚动条高度
      scrollYHeight: 'calc(100vh - 31rem)',
      // modal 模式下本次生命周期内是否已计算过高度（避免每次查询重复计算导致高度逐次变短）
      modalScrollYHeightSet: false,
      // 表格选择列Key集合
      selectedRowKeys: [],
      // 表格选择Row集合
      selectedRows: [],
      // 表格选择列Key集合
      innerSelectedRowKeys: [],
      // 表格选择Row集合
      innerSelectedRows: [],
      // 禁止表格选择Row集合
      selectedDisableRows: [],
      // 业务标题
      title: '',
      // 数据列
      tableColumns: [],
      // 查询用表单
      form: {},
      oldForm: {},
      // 是否允许修改
      isModify: false,
      // 是否允许删除
      isDelete: false,
      // 是否允许选择
      isChoose: false,
      // 选中用于修改的id
      selectId: undefined,
      // 是否显示展示列抽屉
      visible: false,
      // 编辑按钮加载状态
      editLoading: false,
      // 按钮状态
      buttonState: {},
      // eventBtnState
      eventState: {},
      // 自定义按钮数组
      editButtonStateData: [],
      // 按钮权限
      buttonPermissions: [],
      // 行样式函数，用于控制每行的样式类型
      rowStyleFunction: null,
      // 是否展示汇总
      showSummary: false,
      // 自定义汇总
      showCustomSummary: false,
      summaryData: [],
      // 图标样式
      iconStyle: {
        position: 'relative',
        top: '1px'
      },
      // 当前环境
      env: 'prod',
      // 预览模式（表格 or 看板）
      isTableMode: true,
      // 汇总抽屉是否显示
      summaryDrawerVisible: false,
      // 汇总更新标志
      summaryUpdate: false,
      customSummaryArray: [],
      formItems: [],
      // 是否为行编辑模式
      isEditMode: false,
      // 定义主键
      primaryKey: '',
      // 是否进行初始化查询
      createdQuery: false,
      // 允许看板模式
      allowedCardMode: false,
      // 看板模式配置
      cardModeConfig: undefined,
      // 暂存行编辑前数据 用于比较哪些变化了才需要保存
      editRowBeforeData: [],
      // 是否简易模式
      simpleMode: false,
      // crud打印模板配置
      printTemplate: false,
      queryParams: {},
      realQueryParams: {},
      // 定义总行数
      totalCount: 0,
      user: {},
      chartsConfigArray: [],
      summaryDrawerWidth: 35,
      // 行选择模式
      selectRowMode: 'default',
      tableSize: 'default',
      clearSelectRowAfterQuery: false,
      selectedRowModalVisible: false,
      // 是否禁用右侧操作行为
      disableAction: false,
      // 中文字段名列表
      chineseQueryColumnArray: [],
      // 自定义参数
      extraData: {},
      // 导出图片列
      excelImageExportTemplate: [],
      // 导出时需要脱敏的字段列表
      exportDesensitizeFields: [],
    }
  },
  props: {
    // 查询配置文件名
    queryParamsName: {
      type: String,
      default: () => {
        return ''
      }
    },
    // 查询配置文件名
    serviceName: {
      type: String,
      default: () => {
        return ''
      }
    },
    // 查询配置文件Json
    queryParamsJson: {
      type: Object,
      default: null
    },
    // 固定查询表单
    fixedQueryForm: {
      type: Object,
      default: () => {
        return {}
      }
    },
    // 行编辑模式自动数据切换自动保存
    autoSave: {
      type: Boolean,
      default: false
    },
    // 数据只有一页时是否展示分页，true：展示，auto：隐藏
    showPagination: {
      type: Boolean,
      default: true
    },
    // 是否自定义删除功能
    customDelete: {
      type: Boolean,
      default: false
    },
    // 自适应底部边距
    extraHeight: {
      type: Number,
      default: 80
    },
    pageMaxSize: {
      type: Number,
      default: null
    },
    // 外部传入的选中行keys
    externalSelectedRowKeys: {
      type: Array,
      default: () => []
    },
    // 是否使用自定义分页样式
    customPagination: {
      type: Boolean,
      default: false
    },
    // 是否隐藏顶部功能区
    hiddenFunctionalArea: {
      type: Boolean,
      default: false
    },
    // 默认查询的当页行数
    defaultPageSize: {
      type: Number,
      default: 10
    },
    // 分页配置
    pageSizeArray: {
      type: Array,
      default: () => ['10', '20', '30', '40']
    }
  },
  computed: {
    ...mapState('setting', ['theme']),
    rowSelection () {
      return this.selectRowMode === 'disabled' ? undefined : {
        selectedRowKeys: this.innerSelectedRowKeys,
        onChange: this.onSelectChange,
        onSelect: this.selectRowMode === 'listView' ? this.onSelect : undefined,
        onSelectAll: this.selectRowMode === 'listView' ? this.onSelectAll : undefined,
        getCheckboxProps: record => ({
          props: {
            disabled: this.selectedDisableRows.includes(record[this.rowKey]), // Column configuration not to be checked
            name: record.name,
          },
        }),
      }
    },
    ...mapState('account', { currUser: 'user', curRoles: 'roles', curPermissions: 'permissions' }),
    ...mapState('setting', ['compatible']),

    /**
     * 是否启用跨页选中模式
     * 条件：selectRowMode 为 listView 且不在查询后清空选中 且有主键
     */
    isMultiPageSelectionEnabled () {
      return this.selectRowMode === 'listView'
        && !this.clearSelectRowAfterQuery
        && (this.primaryKey || this.rowKey)
    }
  },
  watch: {
    pageMaxSize: {
      handler (val) {
        if (this.tableContext) {
          this.tableContext.pageMaxSize = val
        }
      },
      immediate: true
    },
    externalSelectedRowKeys: {
      handler (newVal) {
        // 如果新值和当前值相同，则不处理
        if (JSON.stringify(newVal) === JSON.stringify(this.selectedRowKeys)) {
          return
        }
        if (newVal && newVal.length > 0) {
          this.$nextTick(() => {
            this.updateTableSelection(newVal)
          })
        }
      }
    }
  },
  mounted () {
    window.addEventListener('resize', this.handleResize)
    // 初始化时如果有外部选中值，等待 table 准备好后设置
    if (this.externalSelectedRowKeys && this.externalSelectedRowKeys.length > 0) {
      this.$nextTick(() => {
        this.updateTableSelection(this.externalSelectedRowKeys)
      })
    }
  },
  beforeDestroy () {
    // 销毁页面查询定时器
    if (this.queryTimer) {
      clearInterval(this.queryTimer)
    }
    window.removeEventListener('resize', this.handleResize)
  },
  methods: {
    isDebugUser,
    showTempData () {
      this.selectedRowModalVisible = true
      this.$nextTick(() => {
        if (this.$refs.selectedDataTable) {
          // 确保数据已经准备好
          const selectedData = this.selectedRows.map(row => ({ ...row }))
          this.$refs.selectedDataTable.refresh(true)
          // 等待数据加载完成后再更新选中状态
          setTimeout(() => {
            if (this.$refs.selectedDataTable) {
              this.$refs.selectedDataTable.updateSelect(
                selectedData.map(row => row[this.primaryKey || this.rowKey]),
                selectedData
              )
            }
          }, 100)
        }
      })
    },
    customFunctionShow (customFunction, record, cIndex) {
      return executeStrFunctionByContext(this, customFunction, [record, cIndex, this.curPermissions, this.curRoles])
    },
    getConfigByNameAsync,
    runLogic,
    executeStrFunctionByContext,
    columnClick (key, value, record) {
      this.$emit('columnClick', key, value, record)
    },
    gotoUserDetail (key, value, record) {
      this.$emit('gotoUserDetail', key, value, record)
    },
    // 打开行编辑
    openEditMode () {
      this.isEditMode = true
      this.editRowBeforeData = JSON.parse(JSON.stringify(this.getTableData()))
    },
    // 标记行保存
    editRowSave () {
      // 获取最新数据
      const editRowAfterData = this.getTableData()
      const changeData = getChangedData(this.editRowBeforeData, editRowAfterData)
      if (this.eventState?.customSave) {
        this.custom('customSave', {
          tableData: editRowAfterData,
          changeData
        })
        return
      }
      if (changeData.length === 0) {
        this.$message.info('没有数据发生变化')
      } else {
        Modal.confirm({
          title: '是否确认保存?',
          content: `此操作将保存当前行编辑的数据，共修改${changeData.length}条数据`,
          zIndex: 1001,
          onOk: () => {
            return new Promise((resolve, reject) => {
              const requestParameters = {
                queryParamsName: this.queryParamsName,
                changeData: changeData.map(h => getRealKeyData(h)),
                operaInfo: this.currUser.operaInfo
              }
              editRowSave(requestParameters, this.serviceName, this.env === 'dev').then(res => {
                const { successCount, failureCount, errors, totalItems } = res
                let baseMsg = `处理完成，共 ${totalItems} 行数据。`
                if (successCount > 0) baseMsg += ` 成功 ${successCount} 行`
                if (failureCount > 0) baseMsg += ` 失败 ${failureCount} 行`
                if (failureCount > 0) {
                  const contentVNode = this.$createElement(
                    'div',
                    { style: 'max-height:300px; overflow:auto;' },
                    [
                      this.$createElement('div', baseMsg),
                      ...errors.map((e, idx) =>
                        this.$createElement('div', `${idx + 1}.${e.msg}`)
                      )
                    ]
                  )
                  this.$confirm({
                    title: '行内数据保存完成',
                    content: contentVNode,
                    okText: '我知道了',
                    cancelButtonProps: { style: 'display:none' }, // 隐藏取消
                    centered: true
                  })
                } else {
                  this.$message.success(baseMsg)
                }
                this.isEditMode = false
                this.refresh()
                resolve(res)
              }).catch(e => {
                reject(e)
                this.$message.error('保存失败！')
              })
            })
          },
          onCancel () {
          }
        })
      }
    },
    importExcelOk (data) {
      this.refresh(true)
      this.$emit('importExcelOk', data)
    },
    /**
     * 行选择事件
     * @param row 选中行集合
     * @param attr 表单项属性
     */
    async rowChoose (row, attr, callback, record) {
      // 如果配置了自定义函数
      if (attr.dataChangeFunc) {
        await executeStrFunction(attr.dataChangeFunc, [record, this.setForm, {
          ...attr,
          selectRows: row
        }, util, this.getSelf(), this.mode, runLogic, getConfigByNameAsync])
      } else {
        // 默认填充选中行数据到当前表单
        setDataByRealKey(record, row[0])
      }
      if (callback) {
        callback()
      }
    },
    setForm (record, obj) {
      Object.assign(record, obj)
      this.$forceUpdate()
    },
    /**
     * 聚焦到指定行和字段的 input
     * @param {Number} rowIndex 行索引
     * @param {String} fieldName 字段名
     */
    focusInput (rowIndex, fieldName) {
      this.$nextTick(() => {
        // 构造 ID：{rowIndex}-{fieldName}input
        const inputId = `${rowIndex}-${fieldName}input`

        // 使用 ID 查找元素（因为 input 在子组件中，无法通过 this.$refs 访问）
        const inputContainer = document.getElementById(inputId)

        if (inputContainer) {
          // 如果找到的是容器元素（Ant Design Vue 组件会包装一层），查找内部的 input
          const inputElement = inputContainer.tagName === 'INPUT'
            ? inputContainer
            : inputContainer.querySelector('input')

          if (inputElement) {
            // 聚焦并选中文本
            inputElement.focus()
            // 延迟选中，确保焦点已经设置
            this.$nextTick(() => {
              if (inputElement.select) {
                inputElement.select()
              }
            })
          } else {
            console.warn(`未找到实际的 input 元素，容器 ID: ${inputId}`)
          }
        } else {
          console.warn(`未找到 input 元素，ID: ${inputId}`)
        }
      })
    },
    /**
     * 处理表单项事件，向外抛出事件供开发者处理
     * @param {Object} context 增强的上下文数据
     */
    handleFormItemEvent (context) {
      const { func, attr, value, currentRecord, currentIndex, nextRecord, nextIndex } = context

      // 向外抛出事件，参数顺序：func, attr, value, currentRecord, currentIndex, nextRecord, nextIndex
      this.$emit('x-form-item-emit-func', func, attr, value, currentRecord, currentIndex, nextRecord, nextIndex)
    },
    handleResize () {
      this.setScrollYHeight({})
    },
    isInAModal () {
      let parent = this.$parent
      while (parent) {
        // 检查组件名称，这里假设a-modal组件的名称为AModal，根据实际情况可能需要调整
        if (parent.$options.name === 'AModal') {
          return true
        }
        parent = parent.$parent
      }
      return false
    },
    executeStrFunction,
    // 切换看板模式和表格模式
    changeViewMode () {
      this.isTableMode = !this.isTableMode
      // 看板切换回表格模式 刷新列表
      this.refresh(true)
    },
    /**
     * 初始化表格参数
     */
    init (params) {
      const {
        // 查询参数对象, 用于没有对应查询配置文件名时
        queryParams,
        realQueryParams,
        tableColumns,
        attachGrid,
        expandedGrid,
        buttonState,
        eventState = {},
        buttonPermissions,
        editButtonStateData = [],
        title,
        form,
        tableSummaryMap = {},
        customTableSummaryArray = [],
        viewMode,
        localEditMode,
        formSubmitTypeInLocalEditMode = 'cover',
        rowSelectMode,
        allowSelectRowNum = 0,
        formItems,
        env = 'prod',
        createdQuery = true,
        createdEditMode = false,
        primaryKey,
        allowedCardMode = false,
        simpleMode = false,
        showRightTools = true,
        cardModeConfig,
        summaryUpdate,
        summaryDrawerWidth = 35,
        chartsConfigArray = [],
        printTemplate = 'DEFAULT_CRUD_PRINT_TEMPLATE',
        selectRowMode = 'default',
        tableSize = 'default',
        clearSelectRowAfterQuery = false,
        disableAction = false,
        extraData,
        chineseQueryColumnArray = [],
        rowStyleFunction = null,
        tableSummaryConfig = {},
        excelImageExportTemplate = [],
        exportDesensitizeFields = []
      } = params
      this.showSummary = Object.keys(tableSummaryMap).length > 0
      if (this.showSummary) {
        Object.keys(tableSummaryMap).forEach(item => {
          this.summaryData.push({
            key: item,
            title: tableSummaryMap[item],
            value: ' ',
            loading: true,
            success: false,
            precision: tableSummaryConfig[item]?.precision ?? 2
          })
        })
      }
      if (customTableSummaryArray.length > 0) {
        customTableSummaryArray.forEach(item => {
          this.summaryData.push({
            key: item.key,
            title: item.title,
            value: ' ',
            loading: true,
            success: false,
            precision: tableSummaryConfig[item]?.precision ?? 2
          })
        })
        this.showCustomSummary = true
        this.customSummaryArray = customTableSummaryArray
      }
      this.chineseQueryColumnArray = chineseQueryColumnArray
      if (this.summaryData.length > 0) {
        this.sortSummaryData()
      }
      this.queryParams = queryParams
      this.realQueryParams = realQueryParams
      this.tableColumns = JSON.parse(JSON.stringify(tableColumns))
      if (this.tableColumns.length === 0) {
        return
      }
      this.attachGrid = attachGrid
      this.expandedGrid = expandedGrid
      this.viewMode = viewMode
      this.localEditMode = localEditMode
      this.formSubmitTypeInLocalEditMode = formSubmitTypeInLocalEditMode
      this.rowSelectMode = rowSelectMode
      this.allowSelectRowNum = allowSelectRowNum
      this.simpleMode = simpleMode
      this.formItems = formItems
      this.user = this.currUser
      this.createdQuery = createdQuery
      this.primaryKey = primaryKey
      this.buttonState = buttonState
      this.eventState = eventState
      this.showRightTools = showRightTools
      this.printTemplate = printTemplate
      this.summaryDrawerWidth = summaryDrawerWidth
      this.chartsConfigArray = chartsConfigArray
      this.selectRowMode = selectRowMode
      this.tableSize = tableSize
      this.clearSelectRowAfterQuery = clearSelectRowAfterQuery
      this.disableAction = disableAction
      this.extraData = extraData
      this.rowStyleFunction = rowStyleFunction
      this.excelImageExportTemplate = excelImageExportTemplate
      this.exportDesensitizeFields = exportDesensitizeFields
      if (this.chartsConfigArray.length > 0) {
        // 循环chartsConfigArray，将每个配置的数据请求参数赋值给requestParameters
        this.chartsConfigArray.forEach(item => {
          item.config.queryParams = JSON.parse(JSON.stringify(this.queryParams))
          item.config.queryParamsName = this.queryParamsName
        })
      }
      if (this.localEditMode) {
        this.localEditModeDataSource = []
        if (this.formSubmitTypeInLocalEditMode === 'append') {
          this.isLocalDataSourceLoadedExternally = true
          const defaultItem = {}
          defaultItem['序号'] = 0
          this.localEditModeDataSource.push(defaultItem)
        } else {
          this.isLocalDataSourceLoadedExternally = false
        }
        this.buttonState.import = false
        this.buttonState.export = false
        this.showRightTools = false
      }
      if (this.rowSelectMode) {
        this.buttonState = {
          choose: true
        }
        this.showRightTools = false
      }
      this.buttonPermissions = buttonPermissions
      this.editButtonStateData = editButtonStateData
      this.title = title
      this.env = env
      this.rowKey = this.getPrimaryKeyName()
      this.allowedCardMode = allowedCardMode
      this.cardModeConfig = cardModeConfig
      this.summaryUpdate = summaryUpdate
      this.isEditMode = createdEditMode
      let totalWidth = 0
      for (let i = 0; i < this.tableColumns.length; i++) {
        const item = this.tableColumns[i]
        // 设置操作列
        if (item.slotType === 'action') {
          item.fixed = 'right'
          item.width = 70
        }
        if (item.fixedType) {
          item.fixed = item.fixedType
        }
        // 设置表格宽度
        if (item.width) {
          totalWidth = totalWidth + item.width
        } else {
          totalWidth = totalWidth + 180
        }
      }
      // 横向滚动长度大于所有宽度，才能实现固定表头
      this.scrollXWidth = totalWidth
      // 加载筛选列完成
      this.columnSelectLoaded = true
      this.setQueryForm(form || {})
      // 简易模式，并且是看板模式，默认直接进入看板模式
      if (this.allowedCardMode && this.simpleMode) {
        this.isTableMode = false
      }
      if (params.queryInterval) {
        this.queryTimer = setInterval(() => {
          this.refresh()
        }, params.queryInterval * 1000)
      }
    },
    // 操作面板按钮渲染
    buttonRendering (button) {
      if (!this.buttonPermissions) {
        return true
      }
      try {
        const existingItem = this.buttonPermissions.find(item => item.btnName === button)
        const rolestr = this.currUser.rolestr?.split(',')
        if (existingItem?.state) {
          const currUserRole = existingItem.roleStr
          return rolestr.some(item => currUserRole && currUserRole.includes(item))
        } else {
          return true
        }
      } catch (e) {
        console.error(e)
        return false
      }
    },
    // 防止查询多次点击处理
    loadTableData (requestParameters) {
      if (this.queryPromise) {
        return this.queryPromise
      }
      this.queryPromise = this.loadTableDataGen(requestParameters).finally(() => {
        this.queryPromise = undefined
      })
      return this.queryPromise
    },
    /**
     * 加载表格数据
     * @param requestParameters 请求参数
     */
    async loadTableDataGen (requestParameters) {
      let result
      if (this.localEditMode) {
        if (!this.isLocalDataSourceLoadedExternally && requestParameters?.conditionParams && Object.keys(requestParameters?.conditionParams).length > 0) {
          const result = await query(Object.assign(requestParameters, { userId: this.currUser?.id }),
            this.serviceName, this.env === 'dev')
          if (result.data) {
            let no = 0
            this.localEditModeDataSource = result.data.map(item => {
              item['序号'] = no
              no++
              return item
            })
          }
          this.isLocalDataSourceLoadedExternally = true
        }
        result = new Promise((resolve) => {
          resolve({
            data: this.localEditModeDataSource
          })
        })
      } else {
        result = query(Object.assign(requestParameters, { userId: this.currUser?.id }), this.serviceName, this.env === 'dev')
        result.then(res => {
          this.totalCount = res.totalCount || 0

          // 数据加载完成后，恢复选中状态
          if (this.selectRowMode !== 'disabled' && !this.clearSelectRowAfterQuery) {
            this.restoreSelectionAfterQuery(res.data)
          }
        }).catch(() => {
          this.$message.error('查询超时！')
        })
      }

      this.$emit('afterQuery', result, requestParameters.conditionParams)
      return result
    },
    /**
     * 操作列事件
     * @param record 本条数据
     * @param actionType 操作类型
     * @param func 事件默认 action
     * @param index 行下标
     */
    action (record, actionType, func = 'action', index) {
      this.$emit('action', record, record[this.getPrimaryKeyName()], actionType, func, index)
    },
    // 看板点击事件
    handleCardEmit (data, eventName) {
      this.action(data, undefined, eventName)
    },
    /**
     * 选择列勾选改变事件
     * @param record 被选择的列数据
     * @param selected 是否选中
     * @param selectedRows 被选择的列集合
     * @param nativeEvent 原生事件
     */
    onSelect (record, selected, selectedRows, nativeEvent) {
      if (this.selectRowMode === 'listView') {
        const primaryKeyName = this.primaryKey || this.rowKey
        // 获取主键数据
        const primaryData = record[primaryKeyName]
        // 取消勾选时
        if (!selected) {
          this.selectedRowKeys = this.selectedRowKeys.filter(item => item !== primaryData)
          this.selectedRows = this.selectedRows.filter(item => item[primaryKeyName] !== primaryData)
        }
      }
    },
    /**
     * 选择列全选事件
     * @param selected 是否选中
     * @param selectedRows 被选择的列集合
     * @param changeRows 改变的行集合
     */
    onSelectAll (selected, selectedRows, changeRows) {
      if (this.selectRowMode === 'listView') {
        if (!selected) {
          const primaryKeyName = this.primaryKey || this.rowKey
          // 获取所有改变的key
          const changeKeys = changeRows.map(item => item[primaryKeyName])
          this.selectedRowKeys = this.selectedRowKeys.filter(item => !changeKeys.includes(item))
          this.selectedRows = this.selectedRows.filter(item => !changeKeys.includes(item[primaryKeyName]))
        }
      }
    },

    /**
     * 【用户交互】选择列数据改变事件（用户手动勾选复选框时触发）
     *
     * 功能：处理用户勾选/取消勾选复选框的操作
     *
     * 逻辑：
     * - 跨页模式(listView)：合并多页选中数据，保留其他页的选中状态
     * - 单页模式：直接使用当前页选中数据，切换页面会清空选中
     *
     * @param {Array} currentPageSelectedKeys - 当前页被选中的行keys
     * @param {Array} currentPageSelectedRows - 当前页被选中的行数据
     */
    onSelectChange (currentPageSelectedKeys, currentPageSelectedRows) {
      // 跨页选中模式：需要合并多页数据
      if (this.isMultiPageSelectionEnabled) {
        const primaryKeyName = this.primaryKey || this.rowKey
        // 当前页所有的key
        const currentPageAllKeys = this.$refs.table.localDataSource.map(row => row[primaryKeyName])
        this.mergeMultiPageSelection(currentPageAllKeys, currentPageSelectedRows, primaryKeyName)
      } else {
        // 单页选中模式：直接使用当前页数据
        this.selectedRowKeys = currentPageSelectedKeys
        this.selectedRows = currentPageSelectedRows
      }

      // 同步内部状态并更新UI
      this.syncSelectionState(currentPageSelectedKeys, currentPageSelectedRows)
    },

    /**
     * 【跨页选中】合并多页选中数据（核心合并逻辑）
     *
     * 功能：在跨页选中模式下，合并当前页和其他页的选中数据
     *
     * 逻辑：
     * 1. 获取当前页所有行的keys
     * 2. 保留不在当前页的已选中行（其他页的选中数据）
     * 3. 添加当前页的选中行（覆盖重复项，确保数据最新）
     * 4. 使用 Map 去重，key为主键，value为行数据
     *
     * 结果：
     * - selectedRowKeys: 所有页面选中的keys
     * - selectedRows: 所有页面选中的行数据
     *
     * @param currentPageAllKeys - 当前页所有的key
     * @param {Array} currentPageSelectedRows - 当前页被选中的行数据
     * @param primaryKeyName - 主键字段名
     */
    mergeMultiPageSelection (currentPageAllKeys, currentPageSelectedRows, primaryKeyName) {
      // 使用 Map 统一处理 keys 和 rows 的合并
      const rowsMap = new Map()

      // 1. 保留其他页的选中行
      this.selectedRows.forEach(row => {
        if (!currentPageAllKeys.includes(row[primaryKeyName])) {
          rowsMap.set(row[primaryKeyName], row)
        }
      })

      // 2. 添加当前页的选中行（覆盖重复项）
      currentPageSelectedRows.forEach(row => {
        rowsMap.set(row[primaryKeyName], row)
      })

      // 3. 更新结果
      this.selectedRows = Array.from(rowsMap.values())
      this.selectedRowKeys = Array.from(rowsMap.keys())
    },

    /**
     * 【UI同步】同步选中状态到UI（内部公共方法）
     *
     * 功能：统一处理选中状态的UI更新逻辑
     *
     * 执行步骤：
     * 1. 更新当前页选中状态（innerSelectedRowKeys/innerSelectedRows）
     * 2. 更新表格复选框显示
     * 3. 更新按钮状态（修改/删除/选择按钮的启用/禁用）
     * 4. 触发选择事件，通知父组件
     *
     * 调用场景：
     * - onSelectChange: 用户勾选复选框后
     * - restoreSelectionAfterQuery: 数据加载后恢复选中状态
     * - doUpdateTableSelection: 外部传入keys更新选中状态
     *
     * @param {Array} currentPageSelectedKeys - 当前页被选中的行keys
     * @param {Array} currentPageSelectedRows - 当前页被选中的行数据
     */
    syncSelectionState (currentPageSelectedKeys, currentPageSelectedRows) {
      // 更新当前页选中状态
      this.innerSelectedRowKeys = currentPageSelectedKeys
      this.innerSelectedRows = currentPageSelectedRows

      // 更新表格显示
      this.$nextTick(() => {
        this.$refs.table?.updateSelect(this.innerSelectedRowKeys, this.innerSelectedRows)
      })

      // 更新按钮状态
      this.updateButtonState()

      // 触发选择事件
      this.$emit('selectRow', this.selectedRowKeys, this.selectedRows)
    },

    /**
     * 【数据加载】数据加载后恢复选中状态
     *
     * 功能：在表格数据重新加载后，恢复之前的选中状态
     *
     * 使用场景：
     * - 翻页后，恢复当前页应该被选中的行
     * - 刷新数据后，保持选中状态不丢失
     *
     * 逻辑：
     * 1. 从新加载的数据中，筛选出应该被选中的行（根据 selectedRowKeys）
     * 2. 合并跨页选中数据（复用 mergeMultiPageSelection）
     * 3. 同步UI状态
     *
     * @param {Array} currentPageData - 当前页加载的数据
     */
    restoreSelectionAfterQuery (currentPageData) {
      const primaryKeyName = this.primaryKey || this.rowKey

      // 找出当前页中应该被选中的行
      const currentPageSelectedRows = currentPageData.filter(row =>
        this.selectedRowKeys.includes(row[primaryKeyName])
      )
      const currentPageSelectedKeys = currentPageSelectedRows.map(row => row[primaryKeyName])

      this.$nextTick(() => {
        if (!this.$refs.table) return

        // 合并跨页选中数据（复用合并逻辑）
        const primaryKeyName = this.primaryKey || this.rowKey
        const currentPageAllKeys = currentPageSelectedRows.map(row => row[primaryKeyName])
        this.mergeMultiPageSelection(currentPageAllKeys, currentPageSelectedRows, primaryKeyName)

        // 同步UI状态
        this.syncSelectionState(currentPageSelectedKeys, currentPageSelectedRows)
      })
    },

    /**
     * 【按钮状态】更新按钮状态
     *
     * 功能：根据选中数量，更新操作按钮的启用/禁用状态
     *
     * 按钮规则：
     * - isModify: 修改按钮，仅选中1条时启用
     * - isDelete: 删除按钮，选中至少1条时启用
     * - isChoose: 选择按钮，根据 allowSelectRowNum 配置判断
     *   - allowSelectRowNum = 0: 选中任意数量即可
     *   - allowSelectRowNum > 0: 必须选中指定数量
     */
    updateButtonState () {
      this.isModify = this.selectedRowKeys.length === 1
      this.isDelete = this.selectedRowKeys.length > 0
      this.isChoose = this.allowSelectRowNum === 0
        ? this.selectedRowKeys.length > 0
        : this.selectedRowKeys.length === this.allowSelectRowNum
    },

    /**
     * 【清空选中】清空所有选中状态
     *
     * 功能：清空全局和当前页的选中状态
     *
     * 使用场景：
     * - 删除操作成功后
     * - 需要重置选中状态时
     */
    clearSelection () {
      this.selectedRowKeys = []
      this.selectedRows = []
      this.innerSelectedRowKeys = []
      this.innerSelectedRows = []
    },
    /**
     * 清除表格选中项
     */
    clearRowKeys () {
      this.$refs.table.clearSelected()
    },
    /**
     * 为表格附加查询条件
     */
    setQueryForm (form = {}) {
      this.form = form
      if (this.createdQuery) {
        this.refresh(true)
      } else {
        this.createdQuery = true
      }
    },
    /**
     * 主动传递条件查询表格
     */
    async queryTable (conditionParams) {
      // 备份一下 form 这个函数传递的 condition 仅临时用一下
      // 如果要实质修改 form 需要在 x-form 中赋值
      const _from = JSON.parse(JSON.stringify(this.form))
      this.form = Object.assign(_from, conditionParams)
      await this.refresh(true)
      this.form = _from
    },
    /**
     * 表格重新加载方法
     * 如果参数为 true, 则强制刷新到第一页
     */
    refresh (bool) {
      this.$nextTick(() => {
        this.$refs.table?.refresh(bool)
      })
    },
    setScrollYHeight ({ extraHeight = this.extraHeight, id = this.uniqueId, type = '' }) {
      this.$nextTick(() => {
        debounce(() => {
          const curDocument = window?.rawDocument || document
          const innerHeight = window?.rawWindow?.innerHeight || window.innerHeight || 0
          if (typeof extraHeight == 'undefined') {
            //  默认底部分页32 + 边距48
            extraHeight = 48 + 32
          }
          let tHeader = null
          if (id) {
            tHeader = curDocument.getElementById(id) ? curDocument.getElementById(id).getElementsByClassName('ant-table-thead')[0] : null
          } else {
            tHeader = curDocument.getElementsByClassName('ant-table-thead')[0]
          }
          // 表格内容距离顶部的距离
          let tHeaderBottom = 0
          if (tHeader) {
            // 8px是分页器marginTop
            tHeaderBottom = tHeader.getBoundingClientRect().bottom + 8
          }
          if (tHeaderBottom === 0) {
            this.scrollYHeight = 'calc(100vh - 31rem)'
            if (window.__MICRO_APP_ENVIRONMENT__) {
              this.scrollYHeight = 'calc(100vh - 28.5rem)'
            }
            return
          }

          // 判断是否在 modal 中
          if (this.isInAModal()) {
            // modal 模式下本次生命周期内只计算一次高度，避免每次查询重复计算导致高度逐次变短
            if (this.modalScrollYHeightSet) {
              return
            }
            let modalElement = null
            if (tHeader) {
              modalElement = tHeader.closest('.ant-modal-body')
            } else {
              modalElement = curDocument.querySelector('.ant-modal-body')
            }
            if (modalElement) {
              const modalRect = modalElement.getBoundingClientRect()
              // 使用 modal 内部可用高度计算，避免依赖 modalRect.bottom 导致的累积缩小
              // 表格滚动区域 = modal 内容区高度 - 表头到 modal 顶部的距离 - 分页(32) - 边距(48)
              const spaceAboveTable = tHeaderBottom - modalRect.top
              const scrollAreaHeight = modalRect.height - spaceAboveTable - 32 - 48
              if (scrollAreaHeight > 210) {
                this.scrollYHeight = `${scrollAreaHeight}px`
              } else {
                this.scrollYHeight = 'calc(100vh - 31rem)'
              }
              this.modalScrollYHeightSet = true
              return
            }
          }
          if (innerHeight - (tHeaderBottom + extraHeight) < 210) {
            this.scrollYHeight = 'calc(100vh - 31rem)'
            return
          }
          // 窗体高度-表格内容顶部的高度-表格内容底部的高度
          // this.scrollYHeight = document.body.clientHeight - tHeaderBottom - extraHeight
          this.scrollYHeight = `calc(100vh - ${tHeaderBottom + extraHeight}px)`
        }, 100)()
      })
    },
    /**
     * 获取主键列名称
     */
    getPrimaryKeyName () {
      if (this.primaryKey) {
        return this.primaryKey
      }
      const indexColumn = this.tableColumns.find(i => i?.slotType === 'index')
      return indexColumn ? indexColumn.dataIndex : this.tableColumns[0].dataIndex
    },
    async handleExport(type) {
      const formTable = this.getSelf && this.getSelf()
      let customHeaders = []
      if (formTable && typeof formTable.beforeExportSetHeaders === 'function') {
        customHeaders = await formTable.beforeExportSetHeaders()
      }
      this.$refs.exportExcel.handleExport(type, this.title, customHeaders)
    },
    handlePrint (type) {
      const printData = {
        title: this.title,
        form: this.form,
        operaInfo: this.currUser.operaInfo,
        operaTime: moment().format('YYYY-MM-DD HH:mm:ss'),
        summary: this.retrieveSummaryData
      }
      this.$refs.exportExcel.handlePrint(type, printData)
    },
    validateTableAndSyncData (currRow, defaultAppendRowData) {
      let isLastRow = false
      if (this.localEditModeDataSource.length === 0) {
        isLastRow = true
      } else if (currRow['序号'] === this.localEditModeDataSource[this.localEditModeDataSource.length - 1]['序号']) {
        isLastRow = true
      }
      if (isLastRow) {
        this.appendLocalData(defaultAppendRowData)
      }
    },
    // 新增业务
    add () {
      if (this.eventState?.customAdd) {
        this.custom('customAdd', {})
        return
      }
      if (this.localEditMode && this.isEditMode) {
        this.appendLocalData({})
      } else {
        this.$emit('add')
      }
    },
    // 添加业务
    move () {
      this.$emit('move')
    },
    // 通用事件业务
    custom (func) {
      this.$emit('customEvent', func)
    },
    // 编辑业务
    edit (id) {
      this.editLoading = true
      this.getEditData(id).then(modifyModelData => {
        if (this.eventState?.customEdit) {
          this.custom('customEdit', { id, modifyModelData })
          return
        }
        this.$emit('edit', modifyModelData)
        this.editLoading = false
      })
    },
    // 行选择业务
    choose () {
      if (this.isChoose) {
        // 如果配置了自定义函数
        this.$emit('rowChoose', this.selectedRows)
      } else {
        this.$message.warning(this.allowSelectRowNum === 0 ? '请选择数据' : `请选择${this.allowSelectRowNum}条数据`)
      }
    },
    // 自定义按钮点击
    editButtonStateDataClick (index) {
      this.$emit('editButtonStateDataClick', this.editButtonStateData[index].functionName, this.selectedRows)
    },
    // 获取被编辑的数据
    getEditData (id) {
      if (!id) {
        this.selectId = this.selectedRowKeys[0]
      } else {
        this.selectId = id
      }
      const primaryKeyName = this.getPrimaryKeyName()
      if (this.tableColumns[0].dataIndex !== primaryKeyName) {
        this.selectId = this.selectedRows[0][primaryKeyName]
      }
      // 将更新需要的主键值加入到primaryKeyData中
      const primaryKeyData = {}
      primaryKeyData[primaryKeyName] = this.selectId
      if (this.localEditMode) {
        return new Promise((resolve) => {
          const modifyData = this.getDataByRowKeyValue(this.selectId)
          resolve({
            data: modifyData,
            primaryKeyData: primaryKeyData
          })
        })
      }
      const requestParameters = {
        queryParamsName: this.queryParamsName,
        queryParams: this.queryParams && Object.keys(this.queryParams).length > 0 ? this.queryParams : undefined,
        conditionParams: {},
        pageNo: 1,
        pageSize: 1
      }
      requestParameters.conditionParams[primaryKeyName] = this.selectId
      requestParameters.f_businessid = this.selectId
      return queryWithResource(requestParameters, this.serviceName, this.env === 'dev').then(res => {
        return { data: res.data[0], primaryKeyData: primaryKeyData, images: res.images, files: res.files }
      })
    },
    // 删除业务
    deleteItem () {
      if (this.viewMode) {
        this.$message.info('预览模式禁止删除')
        return
      }
      Modal.confirm({
        title: '提示',
        content: '您本次要删除共' + this.selectedRowKeys.length + '条数据，确定操作吗？',
        zIndex: 1001,
        onOk: () => {
          const requestParameters = {
            queryParamsName: this.queryParamsName,
            idList: this.selectedRowKeys
          }
          if (this.eventState?.customDelete) {
            this.custom('customDelete', {
              selectedRowKeys: this.selectedRowKeys,
              selectedRows: this.selectedRows
            })
            return
          }
          return new Promise((resolve, reject) => {
            if (this.localEditMode) {
              this.localEditModeDataSource = this.getLocalData().filter(item => !this.selectedRowKeys.includes(item[this.rowKey]))
              resolve(200)
              this.$message.success('删除成功！')
              // 清空选中状态
              this.clearSelection()
              this.refresh(true)
              // afterDelete
              this.$emit('afterDelete', requestParameters)
            } else if (this.customDelete) {
              this.$emit('del', this.selectedRows, resolve)
            } else {
              remove(requestParameters, this.serviceName, this.env === 'dev').then(res => {
                resolve(res)
                this.$message.success('删除成功！')
                // 清空选中状态
                this.clearSelection()
                this.refresh(true)
                // afterDelete
                this.$emit('afterDelete', requestParameters)
              }).catch(e => {
                reject(e)
                this.$message.error('删除失败！')
              })
            }
          })
        },
        onCancel () {
        }
      })
    },
    // 导入业务
    importData () {
      this.$refs.importExcel.importExcelHandleOpen()
    },
    afterVisibleChange (val) {
      if (val) {
        this.retrieveSummaryData()
      }
    },
    async retrieveSummaryData () {
      const promises = []

      if (this.requestParameters.querySummary) {
        const querySummaryPromise = querySummary(Object.assign(this.requestParameters, { userId: this.currUser?.id }), this.serviceName, this.env === 'dev')
          .then(res => {
            if (this.compatible === 'V3') {
              res = res.data
            }
            if (res.length > 0) {
              this.summaryData.forEach(item => {
                res.forEach(summary => {
                  if (item.title === summary.title) {
                    item.value = summary.value
                    item.success = true
                    item.loading = false
                  }
                })
              })
            }
          })
        promises.push(querySummaryPromise)
      }

      if (this.showCustomSummary) {
        this.customSummaryArray.forEach(item => {
          const runLogicPromise = runLogic(item.source, Object.assign(this.requestParameters, { userId: this.currUser?.id }), this.serviceName, this.env === 'dev')
            .then(res => {
              this.summaryData.forEach(summary => {
                if (item.key === summary.key) {
                  summary.value = res.value
                  summary.success = true
                  summary.loading = false
                }
              })
            })
            .catch(e => {
              this.summaryData.forEach(summary => {
                if (item.key === summary.key) {
                  summary.value = 0
                  summary.success = false
                  summary.loading = false
                }
              })
            })
          promises.push(runLogicPromise)
        })
      }

      await Promise.all(promises)
      return this.summaryData
    },
    sortSummaryData () {
      const result = this.summaryData
      // 过滤出 result 中实际存在的 title，并按照 fieldsArray 的顺序排序
      this.summaryData = [...result].sort((a, b) => {
        const indexA = this.chineseQueryColumnArray.indexOf(a.title)
        const indexB = this.chineseQueryColumnArray.indexOf(b.title)
        return indexA - indexB
      })
    },
    showDrawer () {
      if (this.summaryUpdate) {
        this.summaryData.forEach(item => {
          item.loading = true
          item.success = false
          item.value = ' '
        })
        this.summaryDrawerVisible = true
      } else {
        this.$message.warning('请查询后再来查看')
      }
    },
    onClose () {
      this.summaryDrawerVisible = false
    },
    // 获取表格内所有数据
    getTableData () {
      return this.$refs.table.localDataSource
    },
    // 设置表格内数据
    setTableData (data) {
      if (this.localEditMode) {
        // 本地编辑模式下，需要修改 localEditModeDataSource
        this.localEditModeDataSource = data.map((item, index) => ({
          ...item,
          序号: index + 1
        }))
        this.$nextTick(() => {
          this.$refs.table?.refresh()
        })
      } else {
        // 普通模式
        this.$nextTick(() => {
          if (this.$refs.table) {
            this.$refs.table.setLocalDataSource(data)
          }
        })
      }
    },
    // 获取所有本地数据
    getLocalData () {
      return this.localEditModeDataSource
    },
    // 获取指定rowKey的value的本地数据
    getDataByRowKeyValue (rowKeyValue) {
      return this.getLocalData().find(item => {
        return item[this.rowKey] === rowKeyValue
      })
    },
    // 修改本地数据
    modifyLocalData (rowKeyValue, data) {
      const modifyItem = this.getDataByRowKeyValue(rowKeyValue)
      if (modifyItem) {
        Object.assign(modifyItem, data)
      }
    },
    // 追加本地数据
    appendLocalData (item) {
      if (this.localEditModeDataSource.length === 0) {
        item['序号'] = 1
      } else {
        item['序号'] = this.localEditModeDataSource[this.localEditModeDataSource.length - 1]['序号'] + 1
      }
      this.localEditModeDataSource.push(item)
    },
    handleRowClick (record, index, event) {
      // 如果点击的是编辑单元格或操作列内的元素，不触发行点击事件
      if (event && event.target) {
        const clickedElement = event.target.closest ? event.target.closest('.innerTable, .ant-dropdown, .x-table-action-dropdown') : null
        if (clickedElement) {
          return
        }
      }
      this.$emit('rowClick', record)
    },
    handleRowDblClick (record) {
      this.$emit('rowDblClick', record)
    },
    beforeDataChange (record) {
      if (this.isEditMode && this.autoSave) {
        this.editRowSave()
      }
      this.$emit('beforeDataChange', record)
    },
    onExpand (expanded, record) {
      this.$emit('expand', expanded, record)
    },
    // 添加新方法处理表格选中状态（外部调用）
    updateTableSelection (selectedKeys) {
      if (!this.$refs.table) {
        return
      }
      // 检查数据是否已加载
      if (!this.$refs.table.localDataSource || this.$refs.table.localDataSource.length === 0) {
        // 等待数据加载完成后再处理
        const checkDataLoaded = () => {
          if (this.$refs.table.localDataSource && this.$refs.table.localDataSource.length > 0) {
            this.doUpdateTableSelection(selectedKeys)
          } else {
            setTimeout(checkDataLoaded, 100)
          }
        }
        checkDataLoaded()
        return
      }

      this.doUpdateTableSelection(selectedKeys)
    },

    // 实际执行更新选中状态的方法
    doUpdateTableSelection (selectedKeys) {
      const primaryKeyName = this.primaryKey || this.rowKey

      // 从当前页数据中筛选出应该被选中的行
      const currentPageSelectedRows = this.$refs.table.localDataSource.filter(row =>
        selectedKeys.includes(row[primaryKeyName])
      )
      const currentPageSelectedKeys = currentPageSelectedRows.map(row => row[primaryKeyName])

      // 更新总选中状态（外部传入的keys）
      this.selectedRowKeys = [...selectedKeys]
      this.selectedRows = currentPageSelectedRows

      // 同步内部状态并更新UI（复用方法）
      this.syncSelectionState(currentPageSelectedKeys, currentPageSelectedRows)
    },
    /**
     * 处理进度更新事件
     * @param {Object} data 进度数据
     * @param {Object} record 行数据
     * @param {String} dataIndex 列字段名
     */
    handleProgressUpdated (data, record, dataIndex) {
      this.$emit('progressUpdated', data, record, dataIndex)
    },
    /**
     * 更新额外数据
     * @param {Object} newExtraData 新的额外数据
     */
    updateExtraData (newExtraData) {
      this.extraData = newExtraData
    },
    /**
     * 获取表单字段的 labelData（用于导出/打印等场景）
     * 通过父组件 XFormTable 访问 XForm 的方法
     * @returns {Object} labelData 对象
     */
    getFormLabelData () {
      // 通过 getSelf 获取 XFormTable 实例
      const formTable = this.getSelf && this.getSelf()
      if (formTable && typeof formTable.getFormLabelData === 'function') {
        return formTable.getFormLabelData()
      }
      return {}
    }
  }
}
</script>
<style lang="less" scoped>

.custom-chart-title {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 8px;
}

.custom-chart-desc {
  font-size: 12px;
  color: rgba(0, 0, 0, .45);
  margin-bottom: 16px;
}

:deep(.ant-table-thead > tr > th) {
  font-weight: 600;
}

:deep(.table-wrapper .ant-pagination) {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 0;
}

:deep(.table-wrapper .ant-pagination .ant-pagination-total-text) {
  white-space: nowrap;
}

:deep(.ant-table td) {
  white-space: nowrap;
}

.footer_sum_title {
  color: @primary-color;
  font-weight: bold;
}

.footer_sum_item {
  white-space: nowrap;
}

.ant-btn-hover {
  border-color: @primary-color;
  color: @primary-color;
}

.hiddenFunctionalArea {
  display: none;
}
</style>
