<template>
  <div class="JNPF-common-layout">
    <template v-if="columnData.type === 2 && !isComponent">
      <div class="JNPF-common-layout-left">
        <template v-for="(item, index) in columnData.treeList">
          <div :key="index" :style="`height:${(100 / columnData.treeList.length).toFixed(0)}%`">
            <div class="JNPF-common-title" v-if="item.treeTitle">
              <h2>
                {{ item.treeTitle }}
                <!--                <el-input size="mini" placeholder="输入关键字进行过滤"> </el-input>-->
              </h2>
            </div>
            <div style="height: calc(100% - 50px); overflow: auto">
              <el-tree
                :data="item.treeData"
                :props="item"
                highlight-current
                ref="treeBox"
                :expand-on-click-node="false"
                class="JNPF-common-el-tree"
                :node-key="item.treePropsValue"
                :show-checkbox="item.showCheckbox"
              >
                <span class="custom-tree-node" slot-scope="{ node, data }">
                  <i :class="data.icon"></i>
                  <span class="text" @click="handleNodeClick(node, item, index)">
                    {{ item.treeDataSource === 'dictionary' ? data.fullName : data[item.treePropsLabel] }}
                  </span>
                </span>
              </el-tree>
            </div>
          </div>
        </template>
      </div>
    </template>
    <div class="JNPF-common-layout-center">
      <topForm ref="topForm" v-if="columnData.type === 4" />
      <Search ref="Search" :list="columnData.searchList" :columnData="columnData" :treeBoxSearch="treeBoxSearch" @reset="reset" @search="search" />
      <div class="JNPF-common-layout-main JNPF-flex-main" style="height: calc(100% - 55px)">
        <!--        @row-dblclick="dbclick"-->
        <vxe-grid
          :size="tableSpacing === 1 ? 'mini' : 'small'"
          ref="xGrid"
          height="auto"
          :keep-source="true"
          resizable
          :align="formData.labelPosition"
          show-header-overflow
          :data="list"
          :row-config="{ isCurrent: true, isHover: true }"
          :columns="columnList"
          :column-config="{ minWidth: formData.labelWidth }"
          :loading="listLoading"
          :showFooter="columnData.showSummary"
          :printConfig="{}"
          :footer-method="footerMethod"
          :filter-config="{
            resetButtonText: ' ',
            confirmButtonText: ' '
          }"
          :toolbarConfig="toolbarConfig"
          :edit-config="{ trigger: 'click', mode: 'row', showStatus: true, icon: 'vxe-icon-edit' }"
          @edit-closed="editClosedEvent"
          :merge-cells="mergeCells"
          @checkbox-change="handleSelectionChange"
          @checkbox-all="handleSelectionChange"
          @cell-dblclick="dbClickColumnBtnsHandel"
        >
          <template #seq="{ rowIndex }">
            {{ rowIndex + 1 }}
          </template>
          <template #default_images="{ row, column }">
            <template v-if="imgList[column.property] && row[column.property]">
              <amis-sdk
                :datasource="{
                  images: row[column.property].split(';').map((o) => comUrlImage + '/api/file/getFileInputStreamById/' + o)
                }"
                :amis-json="{
                  type: 'images',
                  enlargeAble: true,
                  showToolbar: true,
                  source: '${images}',
                  thumbMode: 'cover',
                  thumbRatio: '16:9'
                }"
              />
            </template>
            <template v-if="row[column.property] && row[column.property].toString().includes('uploads')">
              <amis-sdk
                :datasource="{
                  images: row[column.property] ? JSON.parse(row[column.property]).map((o) => comUrlImage + '/' + o.url) : []
                }"
                :amis-json="{
                  type: 'images',
                  enlargeAble: true,
                  showToolbar: true,
                  source: '${images}',
                  thumbMode: 'cover',
                  thumbRatio: '16:9'
                }"
              />
            </template>
          </template>
          <template #default_file="{ row, column }">
            <template v-if="fileList[column.property] && row[column.property]">
              <el-button v-for="(item, uindex) in row[column.property].split(';').map((o) => fileList[column.property][o] || null)" type="text" size="mini" @click="imgOpenClick(item.filePath)">
                {{ item?.fileName }}
              </el-button>
            </template>
            <template v-else-if="column.params.jnpfKey === 'uploadFz' && row[column.property] && row[column.property] !== 'null' && row[column.property].includes('uploads/')">
              <el-button v-for="(item, uindex) in JSON.parse(row[column.property])" type="text" size="mini" @click="imgOpenClick(item?.url)">{{ item.name }}</el-button>
            </template>
            <template v-else>
              <template v-if="row[column.property]">
                <a
                  v-for="(fzItem, fzIndex) in row[column.property].split(';')"
                  :key="fzIndex"
                  style="color: #1890ff; display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis"
                  :href="'http://60.190.98.244:9175/system/systemfile/' + fzItem"
                  target="_blank"
                  ><i class="el-icon-document"></i> {{ fzItem }}</a
                >
              </template>
            </template>
            <!--            <el-button type="text" v-for="item in JSON.parse(row[column.property])">-->
            <!--              <a :href="'/' + item.url" target="_blank">{{ item.name }}</a>-->

            <!--            </el-button>-->
          </template>
          <template #relationDefault="{ row, column }">
            <div v-for="(item, index) in row[column.property] ? row[column.property].toString().split(';') : row[column.property]" :key="item">
              <template v-if="column.params.compoentConfig.relationData.isText">
                <!--                @click="associationModel(item, column)"-->
                <div class="el-button--text pointer" @click="associationModel(item, column)">
                  <template v-if="index > 0">,</template>
                  {{ formatAssociationData(row, column, item) }}
                </div>
              </template>
              <template v-else-if="column.params.compoentConfig.isUrl">
                <!--                @click="associationModel(item, column)"-->
                <div class="el-button--text pointer" @click="associationModel(item, column)">
                  <template v-if="index > 0">,</template>
                  {{ formatAssociationData(row, column, item) }}
                </div>
              </template>
              <template v-else>
                {{ formatAssociationData(row, column, item) }}
              </template>
            </div>
          </template>
          <template #columnAnotherName="{ row, column }">
            {{ formatColumnAnotherName(row, column) ? formatColumnAnotherName(row, column) : row[column.property] }}
          </template>
          <template #form_edit="{ row, column }">
            <template v-if="column.params.tag === 'el-select'">
              <el-select v-model="row[column.property]" v-bind="column.params.compoentConfig">
                <el-option v-for="item in column.params.compoentConfig.options" :key="item.id" :label="item.fullName" :value="item.id"></el-option>
              </el-select>
            </template>
            <template v-else>
              <component :is="column.params.tag" size="mini" v-bind="column.params.compoentConfig" v-model="row[column.property]" style="width: 100%" />
            </template>
          </template>
          <template #filter_edit="{ column }">
            <div style="padding: 4px">
              <template v-if="column.params.tag === 'el-select'">
                <el-select v-model="filterList[column.field]" v-bind="column.params.compoentConfig">
                  <el-option v-for="item in column.params.compoentConfig.options" :key="item.id" :label="item.fullName" :value="item.id"></el-option>
                </el-select>
              </template>
              <template v-else-if="column.params.tag === 'el-input-number'">
                <div class="flex flex-center gap-10">
                  <!--                  <el-select style="flex: 1" size="mini" value="eq" placeholder="请选择" @change="(val) => filterChange(val)">-->
                  <!--                    <el-option key="eq" label="等于" value="eq"> </el-option>-->
                  <!--                    <el-option key="ne" label="不等于" value="ne"> </el-option>-->
                  <!--                    <el-option key="gt" label="大于" value="gt"> </el-option>-->
                  <!--                  </el-select>-->
                  <component v-model="filterList[column.field]" :is="column.params.tag" size="mini" v-bind="column.params.compoentConfig" style="width: 80%" />
                </div>
              </template>
              <template v-else-if="column.params.tag === 'el-input'">
                <component v-model="filterList[column.field]" :is="column.params.tag" size="mini" v-bind="column.params.compoentConfig" style="width: 100%" />
              </template>
              <el-button size="mini" type="text" @click="handleFilterChange(column)">查询</el-button>
              <el-button size="mini" type="text" @click="clearHandleFilterChange(column)">重置</el-button>
            </div>
          </template>
          <template #operate="scope">
            <template v-for="(item, i) in columnData.columnBtnsList">
              <template v-if="item.value == 'edit'">
                <el-button size="mini" type="text" :key="i" :disabled="config.webType == 3 && [1, 2, 5].indexOf(scope.row.flowState) > -1" @click="columnBtnsHandel(item.value, scope.row)"
                  >{{ item.label }}
                </el-button>
              </template>
              <template v-if="item.value == 'remove'">
                <el-button
                  size="mini"
                  type="text"
                  :key="i"
                  class="JNPF-table-delBtn"
                  :disabled="config.webType == 3 && [1, 2, 3, 5].indexOf(scope.row.flowState) > -1"
                  @click="columnBtnsHandel(item.value, scope.row, item)"
                  >{{ item.label }}
                </el-button>
              </template>
              <template v-if="item.value == 'detail'">
                <el-button size="mini" type="text" :key="i" :disabled="config.webType == 3 && !scope.row.flowState" @click="columnBtnsHandel(item.value, scope.row)">
                  {{ item.label }}
                </el-button>
              </template>
              <template v-if="item.value == 'rowJournal'">
                <el-button size="mini" type="text" :key="i" :disabled="config.webType == 3 && !scope.row.flowState" @click="columnBtnsHandel(item.value, scope.row)">{{ item.label }}</el-button>
              </template>
            </template>
            <template v-if="getPreconditionObj[scope.row[columnDict[idKey]]] && getPreconditionObj[scope.row[columnDict[idKey]]].length > 0">
              <el-dropdown>
                <span class="el-dropdown-link">更多<i class="el-icon-arrow-down el-icon--right"></i> </span>
                <el-dropdown-menu slot="dropdown">
                  <template v-for="item in getPreconditionObj[scope.row[columnDict[idKey]]]">
                    <el-dropdown-item>
                      <el-button size="mini" type="text" :icon="item.icon" @click="isCustomBtnsHandel(item, scope)">{{ item.buttonName }}</el-button>
                    </el-dropdown-item>
                  </template>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
            <template v-else>
              <template v-for="item in getPreconditionObj[scope.row[columnDict[idKey]]]">
                <el-button :key="item.buttonId" size="mini" type="text" :icon="item.icon" @click="customBtnsHandel(item, scope)">
                  {{ item.buttonName }}
                </el-button>
              </template>
            </template>
          </template>
          <!--          <template v-slot:toolbar_buttons>-->
          <!--            <div class="JNPF-common-head">-->
          <!--              <div>-->
          <!--                <template v-for="(item, i) in customBtns.filter((o) => o.buttonLocation === 1)">-->
          <!--                  <el-button size="mini" type="text" :icon="item.icon" @click="customBtnsBatchHandel(item)">{{ item.label }}</el-button>-->
          <!--                </template>-->
          <!--              </div>-->
          <!--            </div>-->
          <!--          </template>-->
          <template #toolbar_tools>
            <div style="width: 100%; text-align: right; border-bottom: 1px solid #d9dddf; padding: 10px 0">
              <vxe-button
                size="mini"
                style="margin-right: 10px"
                v-if="columnData.btnsList.map((o) => o.value).includes('download')"
                type="text"
                icon="el-icon-download"
                @click="headBtnsHandel('download')"
              >
                导出
              </vxe-button>
              <vxe-button
                size="mini"
                style="margin-right: 10px"
                v-if="columnData.btnsList.map((o) => o.value).includes('recycle')"
                type="text"
                icon="el-icon-shopping-bag-1"
                @click="headBtnsHandel('recycle')"
              >
                回收站
              </vxe-button>
              <vxe-button title="刷新" type="text" style="margin-right: 12px" circle icon="fa fa-file-text-o" @click="openCustom">字段冻结</vxe-button>
              <el-popover placement="bottom" trigger="hover">
                <ul class="el-select-dropdown__list">
                  <li :class="[tableSpacing === 1 ? 'freezeClass' : '', 'el-select-dropdown__item']" @click="tableSpacingChange(1)">
                    <span style="float: left">紧凑</span><span v-if="tableSpacing === 1" style="float: right"><i class="el-icon-check"></i></span>
                  </li>
                  <li :class="[tableSpacing === 2 ? 'freezeClass' : '', 'el-select-dropdown__item']" @click="tableSpacingChange(2)">
                    <span style="float: left">宽松</span><span v-if="tableSpacing === 2" style="float: right"><i class="el-icon-check"></i></span>
                  </li>
                </ul>
                <vxe-button type="text" title="布局" size="mini" slot="reference" icon="el-icon-set-up" style="margin-right: 12px">{{ tableSpacing === 2 ? '宽松' : '紧凑' }}</vxe-button>
              </el-popover>
              <vxe-button title="刷新" type="text" style="margin-right: 10px" circle icon="el-icon-refresh" @click="refreshTableLayout()">刷新</vxe-button>
              <el-button size="mini" v-if="columnData.btnsList.map((o) => o.value).includes('add')" type="primary" icon="el-icon-plus" @click="headBtnsHandel('add')"> 新增 </el-button>
            </div>

            <!--            <template v-for="(item, i) in columnData.btnsList">-->
            <!--              <el-button size="mini" v-if="item.value !== 'journal'" :type="i === 0 ? 'primary' : 'text'" :icon="item.icon" @click="headBtnsHandel(item.value)" :key="i">-->
            <!--                {{ item.label }}-->
            <!--              </el-button>-->
            <!--              <el-dropdown v-else @command="handleCommand">-->
            <!--                <span class="el-dropdown-link">操作日志<i class="el-icon-arrow-down el-icon&#45;&#45;right"></i></span>-->
            <!--                <el-dropdown-menu slot="dropdown">-->
            <!--                  <el-dropdown-item command="uploadList">批量导入日志</el-dropdown-item>-->
            <!--                  <el-dropdown-item command="exportList">批量导出日志</el-dropdown-item>-->
            <!--                </el-dropdown-menu>-->
            <!--              </el-dropdown>-->
            <!--            </template>-->
            <!--            <div style="height: 5px; background: #ebeef5; width: 100%"></div>-->
          </template>
          <template v-slot:pager>
            <vxe-pager
              v-if="columnData.hasPage"
              background
              border
              :layouts="['Total', 'Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump']"
              :current-page.sync="listQuery.currentPage"
              :page-size.sync="listQuery.pageSize"
              :total="total"
              @page-change="refreshTableLayout()"
            >
            </vxe-pager>
          </template>
        </vxe-grid>
        <!--        <div style="display: flex; justify-content: space-between; margin: 10px">-->
        <!--          <div></div>-->
        <!--          <el-pagination-->
        <!--            v-if="columnData.hasPage"-->
        <!--            :page-sizes="[10, 20, 50, 100]"-->
        <!--            @size-change="listQuery.pageSize"-->
        <!--            @current-change="refreshTableLayout()"-->
        <!--            :current-page="listQuery.currentPage"-->
        <!--            layout="total, sizes, prev, pager, next, jumper"-->
        <!--            :total="total"-->
        <!--            :page-size="listQuery.currentPage"-->
        <!--          ></el-pagination>-->
        <!--        </div>-->
      </div>
    </div>
    <!--    轮播图-->
    <swiperWrapper v-if="imgShowVisible" @swiperclose="thumbsclose" ref="imgShowView" />

    <!--    流程-->
    <FlowBox v-if="flowVisible" ref="FlowBox" @close="colseFlow" />

    <!--    新增/删除-->
    <Form v-show="formVisible" :relation-data="relationData" :buttons="getPreconditionObjButs" ref="Form" @refreshDataList="refreshTableLayout()" :systemBtns="systemBtns" />

    <!--    详情-->
    <Detail v-show="detailVisible" ref="Detail" @close="detailVisible = false" />

    <!--    导入-->
    <UploadBox v-if="uploadBoxVisible" ref="UploadBox" @UploadChange="UploadChange" />

    <!--    修改记录-->
    <journal :config="columnData.columnList" :modelId="this.modelId" v-show="journalBoxVisible" ref="journalBox" @close="journalBoxVisible = false" />

    <!--   导出日志 -->
    <exportListBox :modelId="this.modelId" v-show="exportListBoxVisible" ref="exportListBox" @close="exportListBoxVisible = false" />

    <!--   导入日志 -->
    <uploadListBox :modelId="this.modelId" :assemblyOptions="this.assemblyOptions" v-show="uploadListBoxVisible" ref="uploadListBox" @close="uploadListBoxVisible = false" />

    <!--    回收站-->
    <recycleList
      :formData="formData"
      :config="columnList"
      :modelId="this.modelId"
      :assemblyOptions="this.assemblyOptions"
      v-if="recycleListBoxVisible"
      ref="recycleListBox"
      @recycleDataList="refreshTableLayout()"
      @editCurrent="recycleDetail"
      @close="recycleListBoxVisible = false"
    />

    <!--    批量编辑-->
    <batchEdit :modelId="this.modelId" v-show="batchEditBoxVisible" ref="batchEditListBox" @close="batchEditBoxVisible = false" @batchEditDataList="refreshTableLayout()" @refreshDataList="refresh" />

    <!--    关联组件-->
    <RelationForm v-show="RelationBoxVisible" :relationConf="relationData" @changeRow="changeElRowClick" ref="relationBox" @close="RelationBoxVisible = false" />

    <vxe-modal v-model="exportBoxVisible" width="600" title="导出excel" show-footer>
      <el-form label-width="80px">
        <el-form-item label="文件名称">
          <el-input v-model="exportBoxData.fileName"></el-input>
        </el-form-item>
        <el-form-item label="选择数据">
          <el-radio-group v-model="exportBoxData.exportType">
            <el-radio label="all">全部数据</el-radio>
            <el-radio label="current">当前页</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="选择字段">
          <vxe-table
            ref="tableRef"
            height="300"
            size="small"
            :row-config="{ useKey: true }"
            :tree-config="{ children: 'children' }"
            :scroll-y="{ enabled: false }"
            :checkbox-config="{ checkAll: true }"
            :data="exportBoxData.columnListFieldList"
          >
            <vxe-column type="checkbox" width="60"></vxe-column>
            <vxe-column field="title" title="字段名" tree-node></vxe-column>
          </vxe-table>
        </el-form-item>
      </el-form>

      <template #footer>
        <vxe-button @click="exportBoxVisible = false">关闭</vxe-button>
        <vxe-button status="primary" @click="exportMethod">导出</vxe-button>
      </template>
    </vxe-modal>
  </div>
</template>

<script>
import {
  batchDelete,
  deteleModel,
  executeBatchCustomButton,
  executeCustomButton,
  exportBaseModel,
  getBrowserData,
  getChildrenConfigData,
  getConfigData,
  getModePermV2,
  getPrecondition,
  NewupdateModel,
  updateModel,
  uploadModel
} from '@/api/onlineDev/visualDev'
import { deepClone, detail, getSeachPrimaryAndForeignTable, loopRelationList } from '@/utils'
import Form from './Form'
import FlowBox from '@/views/workFlow/components/FlowBox'
import Detail from './detail'
import ExportBox from './ExportBox'
import UploadBox from './UploadBox'
import Search from './Search'
import journal from './journal'
import exportListBox from './exportList'
import uploadListBox from './uploadList'
import recycleList from './recycleList'
import batchEdit from './batchEdit'
import topForm from './topForm'
import moment from 'moment'
import { dictDetail } from '@/api/newbi/dict'
import RelationForm from '@/components/Generator/components/RelationForm'
import swiperWrapper from './../components/swiperWrapper'
import { getAPIData, getTreeAPIData } from '@/components/Dataset-filter/util'
import AmisSdk from '@/components/AmisSdk.vue'
import { userInfo } from '@/api/user'
import { getToken } from '@/utils/auth'
import { Base64 } from 'js-base64'
import { getFileById } from '@/api/common'
import { comUrl } from '@/utils/define'
export default {
  name: 'dynamicModel',
  components: {
    AmisSdk,
    Form,
    ExportBox,
    Search,
    Detail,
    FlowBox,
    UploadBox,
    journal,
    exportListBox,
    uploadListBox,
    recycleList,
    batchEdit,
    RelationForm,
    swiperWrapper,
    topForm
  },
  // props: ['config', 'modelId', 'tabSearch', 'isComponent'],
  props: {
    config: {
      type: Object,
      default: () => {}
    },
    modelId: {
      type: String,
      default: ''
    },
    tabSearch: {
      type: Object,
      default: () => {}
    },
    isComponent: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      btnsOption: [
        { value: 'add', icon: 'el-icon-plus', label: '新增' },
        { value: 'download', icon: 'el-icon-download', label: '导出' },
        { value: 'batchUpload', icon: 'el-icon-upload2', label: '批量导入' },
        { value: 'batchUpdate', icon: 'el-icon-edit-outline', label: '批量编辑' },
        { value: 'batchRemove', icon: 'el-icon-delete', label: '批量删除' },
        { value: 'recycle', icon: 'el-icon-delete', label: '回收站' },
        { value: 'journal', icon: 'el-icon-date', label: '操作日志' }
      ],
      columnBtnsOption: [
        { value: 'edit', icon: 'el-icon-edit', label: '编辑' },
        { value: 'remove', icon: 'el-icon-delete', label: '删除' },
        { value: 'detail', icon: 'el-icon-tickets', label: '详情' },
        { value: 'rowJournal', icon: 'el-icon-date', label: '操作记录' }
      ],
      functionBtnsOption: [
        { value: 'uploadRevoke', icon: 'el-icon-refresh-left', label: '导入撤销' },
        { value: 'comDelete', icon: 'el-icon-delete', label: '彻底删除' }
      ],
      assemblyOptions: [],
      isPreview: false,
      keyword: '',
      treeProps: {
        children: 'children',
        label: 'fullName',
        value: 'enCode'
      },
      list: [],
      columnDict: {},
      idKey: this.config.idKey,
      total: 0,
      listLoading: false,
      listQuery: {
        currentPage: 1,
        pageSize: 5,
        sort: 'descs',
        sidx: this.config.idKey,
        json: ''
      },
      imgShowVisible: false,
      flowVisible: false,
      formVisible: false,
      detailVisible: false,
      importBoxVisible: false,
      exportBoxVisible: false,
      exportBoxData: {
        fileName: '', // 文件名
        exportType: 'all', // 导出类型
        fieldList: [], // 导出字段
        columnListFieldList: [] // 导出字段
      },
      uploadBoxVisible: false,
      journalBoxVisible: false,
      exportListBoxVisible: false,
      uploadListBoxVisible: false,
      recycleListBoxVisible: false,
      batchEditBoxVisible: false,
      RelationBoxVisible: false,
      treeData: [],
      treeActiveId: '',
      columnData: {
        columnBtnsList: []
      },
      formData: {},
      columnList: [],
      relationData: [],
      relationConfCopy: [],
      relationFlag: false,
      hasBatchBtn: false,
      refreshTable: true,
      multipleSelection: [],
      multipleSelectionDelectData: [],
      value: '',
      valueIndex: -1,
      itemLabel: '',
      oldList: [],
      oldData: null,
      btnArr: [],
      optionList: [],
      checkboxVal: null,
      cascaderVal: null,
      isFreeze: 1,
      isShowFalg: 1,
      isShowDisFalg: false,
      tableSpacing: 1,

      // 新版表格
      toolbarConfig: {
        print: false,
        zoom: false,
        custom: false,
        slots: {
          buttons: 'toolbar_buttons',
          tools: 'toolbar_tools'
        }
      },
      mergeCells: [],
      treeBoxSearch: '',
      // 表头筛选数组
      filterList: {},
      // 自定义按钮
      customBtns: [],
      systemBtns: [],
      getPreconditionObj: {},
      getPreconditionObjButs: [],
      imgList: {},
      fileList: {},
      comUrlImage: comUrl
    }
  },
  created() {
    this.init()
  },
  methods: {
    //触发关联按钮
    relationBoxclick(id, keyId) {
      this.relationConfCopy = deepClone(this.relationData)
      this.relationConfCopy.forEach((i) => {
        i.relationList.forEach((v) => {
          if (v.drawId === id) {
            this.RelationBoxVisible = true
            this.$refs.relationBox.getData(i.relationName, i.fieldName, i.fieldList, keyId)
          }
        })
      })
    },
    //关联回调
    changeElRowClick(row) {
      let { id, keyId, jsonData } = row
      this.relationConfCopy = deepClone(this.relationData)
      //过滤出当前修改row
      let editRow = this.list.filter((cur) => cur[this.columnDict[this.idKey]] === keyId)
      if (!editRow && !editRow.length) return
      this.relationConfCopy.forEach((i) => {
        if (i.relationName === id) {
          i.relationList.forEach((v) => {
            //时间类型特殊转换
            this.formData.fields.forEach((c) => {
              if (v.fieldId && v.drawId === c.__vModel__) {
                if (c.__config__.viewDataType === 'DATETIME') {
                  jsonData[v.fieldId] = moment(jsonData[v.fieldId]).valueOf()
                }
              }
            })
            editRow[0][this.columnDict[v.drawId]] = jsonData[v.fieldId]
          })
        }
      })
      this.$refs.relationBox.visible = false
      this.RelationBoxVisible = false
    },
    //自适应列宽度
    flexColumnWidth(str, tableData, flag = 'max') {
      // str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
      // flag为可选值，可不传该参数,传参时可选'max'或'equal',默认为'max'
      // flag为'max'则设置列宽适配该列中最长的内容,flag为'equal'则设置列宽适配该列中第一行内容的长度。
      let DelectData = deepClone(tableData)
      let jsonData = DelectData.map((i) => {
        return this.getBatchEditJsonData(i)
      })
      str = str + ''
      let columnContent = ''
      if (!jsonData || !jsonData.length || jsonData.length === 0) {
        return
      }
      if (!str || !str.length || str.length === 0) {
        return
      }
      if (flag === 'equal') {
        // 获取该列中第一个不为空的数据(内容)
        for (let i = 0; i < jsonData.length; i++) {
          if (jsonData[i][str].length > 0) {
            columnContent = jsonData[i][str]
            break
          }
        }
      } else {
        // 获取该列中最长的数据(内容)
        let index = 0
        for (let i = 0; i < jsonData.length; i++) {
          if (jsonData[i][str] !== null) {
            const now_temp = jsonData[i][str] + ''
            const max_temp = jsonData[index][str] + ''
            if (now_temp.length > max_temp.length) {
              index = i
            }
          }
        }
        columnContent = jsonData[index][str]
      }
      // 以下分配的单位长度可根据实际需求进行调整
      let flexWidth = 0
      if (columnContent) {
        for (let char of JSON.stringify(columnContent)) {
          if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
            // 如果是英文字符，为字符分配10个单位宽度
            flexWidth += 10
          } else if (char >= '\u4e00' && char <= '\u9fa5') {
            // 如果是中文字符，为字符分配15个单位宽度
            flexWidth += 15
          } else {
            // 其他种类字符，为字符分配9个单位宽度
            flexWidth += 10
          }
        }
      }
      if (flexWidth < 80) {
        // 设置最小宽度
        flexWidth = 100
        return 'auto'
      }
      if (flexWidth > 160 && flexWidth < 250) {
        // 设置最大宽度
        flexWidth = 150
        return flexWidth + 'px'
      }
      if (flexWidth > 250) {
        // 设置最大宽度
        flexWidth = 250
        return flexWidth + 'px'
      }

      // }else {
      //   return 'auto'
      // }
    },
    successClick(scope) {
      let rows = Object.assign({}, scope.row)
      delete scope.row.inputShow
      let editList = deepClone(this.columnDict)
      delete editList[this.idKey]
      // item.forEach((val) => {
      //   if (val.jnpfKey == 'date' || val.jnpfKey == 'datetime') {
      //     scope.row[this.columnDict[val.propId]] = String(
      //       new Date(scope.row[this.columnDict[val.propId]]).getTime()
      //     )
      //   }
      // })
      let id = scope.row ? scope.row[this.columnDict[this.idKey]] : ''
      for (let key in editList) {
        for (let index in rows) {
          if (editList[key] === index) {
            editList[key] = rows[index]
          }
        }
      }
      Object.keys(editList).forEach((item) => {
        if (typeof editList[item] === 'undefined' || editList[item] === null) {
          delete editList[item]
        }
      })
      Object.keys(this.oldData).forEach((item) => {
        if (typeof this.oldData[item] === 'undefined' || this.oldData[item] === null) {
          delete this.oldData[item]
        }
      })
      let dataForm = {
        data: JSON.stringify(editList),
        oldData: this.oldData ? JSON.stringify(this.oldData) : '',
        id: id
      }
      updateModel(this.modelId, [dataForm], dataForm.id)
        .then((res) => {
          this.$message({
            message: res.data.msg,
            type: 'success',
            duration: 1500
          })
          this.refreshTableLayout()
        })
        .catch(() => {
          this.refreshTableLayout()
        })
    },
    closeInput(scope) {
      let olds = Object.assign(this.oldList[scope.$index], {
        inputShow: false
      })
      this.oldData = null
      this.$set(this.list, scope.$index, olds)
      this.columnData.columnBtnsList = this.btnArr
      this.refreshTableLayout()
    },
    getdateMoment(list) {
      if (list && Object.prototype.toString.call(list)) {
        let arr = Object.keys(list)
        let arrs = []
        this.formData.fields.forEach((item) => {
          //查找表单设计时 哪些组件控件为时间类型 与编辑行匹配
          if (arr.includes(String(item.__vModel__)) && item.__config__.viewDataType === 'DATETIME') {
            //将时间类型的数据改为时间戳
            list[item.__vModel__] = moment(list[item.__vModel__]).valueOf()
            arrs = list
            //修改表格绑定list中时间选择控件需要的format类型
            this.columnList.forEach((val) => {
              if (val.propId === item.__vModel__) {
                val.format = item.format
                val['value-format'] = item['value-format']
              }
            })
          }
        })
        return arrs
      }
    },
    //下拉属性的组件  如果key和value值不相同 查询title
    getOptionData(v, id) {
      let list = []
      let str = v
      this.formData.fields.forEach((item) => {
        if (item.__vModel__ === id) {
          list = item.__slot__.options
        }
      })
      if (list.length) {
        let obj = list.find((i) => i.id == v)
        if (obj) str = obj.fullName
      }
      return str
    },
    //获取下拉框值
    getOption(key, id) {
      let list = []
      if (key === 'radio' || key === 'select' || key === 'checkbox') {
        this.formData.fields.forEach((item) => {
          if (item.__vModel__ === id) {
            list = item.__slot__.options
          }
        })
      }
      if (key === 'cascader') {
        this.formData.fields.forEach((item) => {
          if (item.__vModel__ === id) {
            list = item.options
          }
        })
      }
      return list
    },
    //如有主键或计算字段之类 要禁用
    getDisabled(id) {
      let ItemDisabled = false
      this.formData.fields.forEach((item) => {
        if (item.__vModel__ === id) {
          ItemDisabled = item.disabled
        }
      })
      return ItemDisabled
    },
    //获取时间值类型
    getFormat(id, type) {
      let str
      this.formData.fields.forEach((item) => {
        if (item.__vModel__ === id) {
          if (type === 'format') {
            str = item.format
          }
        }
      })
      return str
    },
    // 表头筛选数字类型处理
    filterChange(value) {
      console.log(value)
    },
    init() {
      this.refreshTable = false
      if (!this.config.columnData || !this.config.formData) return
      this.columnData = JSON.parse(this.config.columnData)
      this.relationData = JSON.parse(this.config.relationData)
      if (this.columnData.type === 3) {
        this.columnData.columnList = this.columnData.columnList.filter((o) => o.prop != this.columnData.groupField)
      }
      this.formData = JSON.parse(this.config.formData)
      this.getColumnList()
      if (this.isPreview) return
      this.listQuery.pageSize = this.columnData.pageSize
      this.listQuery.sort = this.columnData.sort
      this.listQuery.sidx = this.columnData.defaultSidx
      if (this.columnData.type === 3 || !this.columnData.hasPage) this.listQuery.pageSize = 10000
      if (this.columnData.type === 2) {
        this.getTreeView()
        this.initData()
      } else {
        //请求权限 列表 直接看这一条 从搜索组件调用
        this.initData()
      }
    },
    tableSpacingChange(value) {
      this.tableSpacing = value
      // this.listLoading = true
      // this.$nextTick(() => {
      //   this.$refs.PcListTable.doLayout();
      //   setTimeout( ()=>{
      //     this.listLoading = false
      //   }, 2000 )
      // })
    },
    //图片类型处理
    getImgFun(value) {
      try {
        const toObj = JSON.parse(value)
        if (Array.isArray(toObj) && toObj[0].url) {
          return toObj
        }
        // eslint-disable-next-line no-empty
      } catch {}
      return value
    },
    getImgUrl() {
      let ImgUrl
      if (process.env.NODE_ENV === 'development') {
        ImgUrl = this.define.comUrl
      } else {
        ImgUrl = document.location.origin
      }
      return ImgUrl + '/'
    },
    getImgFunList(val) {
      const list = this.getImgFun(val)
      if (Array.isArray(list) && list.length)
        return list.map((i) => {
          let ImgUrl
          if (process.env.NODE_ENV === 'development') {
            ImgUrl = this.define.comUrl
          } else {
            ImgUrl = document.location.origin
          }
          return ImgUrl + '/' + i.url
        })
    },
    imgShowClick(list) {
      this.imgShowVisible = true
      this.$nextTick(() => {
        this.$refs.imgShowView.init(list)
      })
    },
    thumbsclose() {
      this.imgShowVisible = false
    },
    //查询对应的key值
    getListPropId(id) {
      if (this.list && this.list.length) {
        let arr = Object.keys(this.list[0])
        let PropId = arr.filter((o) => {
          if (Number(o) === id) {
            return o
          }
        })
        return PropId.toString()
      }
    },
    async getTreeView() {
      const treeList = this.columnData.treeList
      for (const key in treeList) {
        const item = treeList[key]
        if (item.treeDataSource === 'dictionary') {
          if (!item.treeDictionary) return
          await dictDetail({ id: item.treeDictionary }).then((res) => {
            let content = JSON.parse(res.data.data.content || '[]')
            this.treeData = content.map((i) => ({ fullName: i.value, id: i.key }))
            this.columnData.treeList[key].treeData = this.treeData
            this.$set(this.columnData.treeList, key, this.columnData.treeList[key])
          })
        }
        if (item.treeDataSource === 'organize') {
          this.$store.dispatch('generator/getCompanyTree').then((res) => {
            this.treeData = res
          })
        }
        if (item.treeDataSource === 'department') {
          this.$store.dispatch('generator/getDepTree').then((res) => {
            this.treeData = res
          })
        }
        if (item.treeDataSource === 'api') {
          if (!item.treePropsUrl) return
          await getTreeAPIData(item.treePropsUrl, item).then((res) => {
            this.columnData.treeList[key].treeData = res
            this.$set(this.columnData.treeList, key, this.columnData.treeList[key])
          })
        }
      }
    },
    getColumnList() {
      if (this.isPreview || !this.columnData.useColumnPermission) {
        this.columnList = this.columnData.columnList
      } else {
        const permissionList = this.$store.getters.permissionList
        const modelId = this.$route.meta.modelId
        const list = permissionList.filter((o) => o.modelId === modelId)
        const columnList = list[0] && list[0].column ? list[0].column : []
        let realList = []
        for (let i = 0; i < columnList.length; i++) {
          inner: for (let j = 0; j < this.columnData.columnList.length; j++) {
            if (columnList[i].enCode === this.columnData.columnList[j].prop) {
              realList.push(this.columnData.columnList[j])
              break inner
            }
          }
        }
        this.columnList = realList
      }
    },
    handleNodeClick(node, data, index) {
      let obj = {}
      let arr = []
      this.columnData.columnList.forEach((i, k) => {
        if (i.field === data.treeRelation) {
          obj.cubeColumnId = data.treeRelation
          obj.function = data.treeSearchType || 'like'
          if (data.treeDataSource === 'dictionary') {
            obj.values = [node.data.id]
          } else if (obj.function == 'in') {
            const list = g.T.toTable(node.data, 'children')
            obj.values = list.map((i) => i[data.treeSearch || data.treePropsLabel])
          } else {
            obj.values = [node.data[data.treeSearch || data.treePropsLabel]]
          }
          arr.push(obj)
          console.log(obj)
        } else if (i.params?.propId === data.treeRelation) {
          obj.cubeColumnId = data.treeRelation
          obj.function = data.treeSearchType || 'like'
          if (data.treeDataSource === 'dictionary') {
            obj.values = [node.data.id]
          } else if (obj.function == 'in') {
            const list = g.T.toTable(node.data, 'children')
            obj.values = list.map((i) => i[data.treeSearch || data.treePropsLabel])
          } else {
            obj.values = [node.data[data.treeSearch || data.treePropsLabel]]
          }
          console.log(obj)
          arr.push(obj)
        }
      })
      this.treeFilter = arr
      console.log(this.treeFilter)
      // let json = JSON.stringify(arr) === '[]' ? [] : JSON.stringify(arr)
      // this.treeBoxSearch = {}
      this.refreshTableLayout()
    },
    //整合数据 配合流程进行存储回显数据
    getFlowJsonData(row) {
      let rows = Object.assign({}, row)
      let jsonData = deepClone(this.columnDict)
      let returnData = {}
      for (let key in jsonData) {
        for (let index in rows) {
          if (jsonData[key] === index && !index.includes('foreign_')) {
            returnData[key] = rows[index]
          }
        }
      }
      return returnData
    },
    startsWithReduceRow(row) {
      let filteredData = Object.keys(row).reduce((obj, key) => {
        if (!key.startsWith('foreign_')) {
          obj[key] = row[key]
        }
        return obj
      }, {})
      delete filteredData.mergeRow
      delete filteredData.row
      delete filteredData.seq
      delete filteredData._X_ROW_KEY
      return filteredData
    },
    //子表整合数据
    flattenedArrayWithKey(foreignObj) {
      const result = []
      for (const key in foreignObj) {
        foreignObj[key].forEach((item) => {
          result.push({ dbLink: key, id: '', oldData: null, data: JSON.stringify(item) })
        })
      }
      return result
    },
    /*
     * 删除
     */
    async handleDel(row, button) {
      let filteredData = this.startsWithReduceRow(row)
      this.$confirm(this.$t('common.delTip'), this.$t('common.tipTitle'), {
        type: 'warning'
      })
        .then(async () => {
          this.loading = this.$loading({
            lock: true,
            text: '正在删除',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
          })
          const find = this.systemBtns.find((o) => o.value === 'remove')
          if (find && find.preEventNum && find.preEventNum > 0) {
            const data = {
              row: row
            }
            const re = await this.customBtnsHandel(find, data, true)
            if (re?.data?.code !== 200) {
              this.loading.close()
              return
            }
          }
          let jsonData = this.getFlowJsonData(filteredData)
          let dataJson = JSON.stringify(filteredData)
          //主表整合信息
          let primaryTable = {
            dbLink: this.config.dbLinkId,
            id: row[this.columnDict[this.idKey]] ? row[this.columnDict[this.idKey]] : '',
            oldData: null,
            data: JSON.stringify(jsonData)
          }
          // 子表整合信息
          let foreignTable = {}
          for (let z in filteredData) {
            if (z.includes('FOREIGN_KEY_')) {
              foreignTable[z] = filteredData[z]
            }
          }
          let result = {}
          for (let key in foreignTable) {
            if (key.startsWith('FOREIGN_KEY_')) {
              let newKey = key.replace('FOREIGN_KEY_', '')
              // 初始化结果对象中新键名的值为一个空数组
              result[newKey] = []
              // 如果 obj 中存在 pageData，则进行处理
              if (foreignTable[key].pageData && Array.isArray(foreignTable[key].pageData)) {
                // 遍历 pageData 数组中的每个对象
                foreignTable[key].pageData.forEach((item) => {
                  // 创建一个新对象来存储映射后的属性
                  let newItem = {}
                  for (let prop in item) {
                    // 在 dict 中查找与当前属性名相匹配的键
                    for (let dictKey in this.columnDict) {
                      if (this.columnDict[dictKey] === prop) {
                        newItem[dictKey] = item[prop]
                        break // 找到匹配的映射后跳出循环
                      }
                    }
                  }
                  // 将映射后的对象添加到结果数组中
                  result[newKey].push(newItem)
                })
              }
            }
          }
          //子表整合数据
          let integrationForeignTable = this.flattenedArrayWithKey(result)
          let zzz = {
            ...jsonData,
            formData: {
              foreignTable: integrationForeignTable,
              primaryTable: primaryTable
            }
          }
          let flowDataJson = JSON.stringify(zzz)
          const param = new URLSearchParams()
          param.append('dataJson', dataJson)
          param.append('flowDataJson', flowDataJson)
          const res = await deteleModel(this.modelId, row[this.columnDict[this.idKey]], param)
          if (res.data.code === 200) {
            this.$message({
              type: 'success',
              message: res.data.msg,
              duration: 1000,
              onClose: () => {
                if (find && find.postEventNum && find.postEventNum > 0) {
                  const data = {
                    row: row
                  }
                  this.customBtnsHandel(find, data)
                } else {
                  this.loading.close()
                  this.refreshTableLayout()
                }
                this.multipleSelectionDelectData = {}
                this.multipleSelection = []
              }
            })
          }
          // deteleModel(this.modelId, row[this.columnDict[this.idKey]],dataJson).then(
          //   (res) => {
          //
          //   }
          // )
        })
        .catch(() => {
          this.loading.close()
          this.listLoading = false
        })
    },
    async addOrUpdateHandle(row, detailType, fullName) {
      // let userInfoObj = JSON.parse(localStorage.getItem('lowcodeUserInfo'))
      // if (!userInfoObj) {
      //   const { data } = await userInfo()
      //   userInfoObj = data.data
      //   localStorage.setItem('lowcodeUserInfo', JSON.stringify(data.data))
      // }
      let id = row ? row[this.columnDict[this.idKey]] : ''
      if (this.oldList && this.oldList.length) {
        row = this.oldList.find((i) => i[this.columnDict[this.idKey]] === id) || {}
      }
      if (row) {
        Object.keys(row).forEach((key) => {
          const cellValue = row[key]
          const field = key
          const column = this.columnList.filter((i) => i.params).find((i) => i.params.field === field)
          if (column && column.params && column.params.compoentConfig.relationData && column.params.compoentConfig.relationData.showTitle.length) {
            const fieldArray = []
            if (cellValue) {
              String(cellValue)
                .split(';')
                .forEach((i, index) => {
                  if (column.params.compoentConfig.relationData.isCheck) {
                    try {
                      const data = this.associationData[field][row[field]]
                      const primaryId = column.params.compoentConfig.relationData.itemRelationList.find((i) => i.drawId === column.params.propId)
                      const relationField = this.associationColumnDict[field][primaryId.columnId]
                      fieldArray.push(data ? data[relationField] : i)
                    } catch (e) {
                      fieldArray.push(row[field])
                    }
                  } else {
                    // 逗号隔开
                    try {
                      const data = this.associationData[field][i]
                      const primaryId = column.params.compoentConfig.relationData.itemRelationList.find((i) => i.drawId === column.params.propId)
                      const relationField = this.associationColumnDict[field][primaryId.columnId]
                      fieldArray.push(data[relationField] ? data[relationField] : i)
                    } catch (e) {
                      fieldArray.push(row[field])
                    }
                  }
                })
              row[field + '_TEXT'] = fieldArray.join(',')
            }
          }
        })
      }
      if (this.config.webType == 3) {
        let data = {
          id: id || '',
          enCode: this.config.flowEnCode,
          flowId: this.config.flowId,
          formType: 2,
          type: 1,
          opType: '-1',
          modelId: this.modelId,
          isPreview: this.isPreview
        }
        this.flowVisible = true
        this.$nextTick(() => {
          this.$refs.FlowBox.init(data)
        })
      } else {
        this.formVisible = true
        this.$nextTick(() => {
          const param = {
            formData: this.formData,
            modelId: this.modelId,
            id,
            idKey: this.idKey,
            columnDict: this.columnDict,
            dbLinkId: this.config.dbLinkId,
            row: row
          }
          this.columnList.forEach((i) => {
            if (i?.config?.isJoin) {
              const find = this.formData.fields.find((j) => j.__vModel__ === i.propId)
              if (find) {
                find.__config__ = { ...i.config, ...find.__config__ }
              }
            }
          })
          this.formData.fields.forEach((item) => {
            if (item?.__config__?.jnpfKey === 'modifyUserId' || item?.__config__?.jnpfKey === 'createUserId') {
              item.placeholder = userInfoObj.id
            }
            if (item?.__config__?.jnpfKey === 'createUser' || item?.__config__?.jnpfKey === 'modifyUser') {
              item.__config__.defaultValue = userInfoObj.realName
            }
            if (item?.__config__?.jnpfKey === 'createTime' || item?.__config__?.jnpfKey === 'modifyTime') {
              // if (!id) {
              //   item.__config__.defaultValue = moment().format('YYYY-MM-DD HH:mm:ss')
              // } else {
              //   item.__config__.defaultValue = moment(item.__config__.defaultValue).valueOf()
              // }
            }
            if (item?.__config__?.jnpfKey === 'currDept') {
              item.placeholder = userInfoObj.deptName
            }
            if (item?.__config__?.jnpfKey === 'currPosition') {
              item.placeholder = userInfoObj.postName
            }
          })
          this.$refs.Form.init(
            this.formData,
            this.modelId,
            id,
            this.isPreview,
            row,
            this.idKey,
            this.columnDict,
            this.config.dbLinkId,
            detailType,
            this.config.associationRelation,
            this.config.fullName
          )
        })
      }
    },
    /*
     * 关联模型
     * @param row 当前行数据
     * @param relationData 关联数据
     * @param associationData 关联模型数据
     * @param field 关联字段
     */
    async associationModel(row, column) {
      const field = column.field
      // 正在加载
      this.listLoading = true
      if (column.params.compoentConfig.isUrl) {
        const newUrl = g.replaceAll(row, '@', '&')
        // const unserialize = XEUtils.unserialize(newUrl)
        const unserialize = XEUtils.unserialize(newUrl)
        const res = await getConfigData(unserialize.modelId)
        const data = res.data.data
        const detailData = await detail(unserialize.modelId, data.dbLinkId, data.idKey, unserialize.id)
        const relationData = detailData.relationData
        const associationData = detailData.associationData
        const associationColumnDict = detailData.associationColumnDict
        param = {
          fullName: data.fullName,
          formData: JSON.parse(data.formData),
          associationRelation: data.associationRelation,
          modelId: unserialize.modelId,
          idKey: data.idKey,
          columnDict: detailData.columnDict,
          columnList: JSON.parse(data.columnData).columnList,
          dbLinkId: data.dbLinkId,
          row: detailData.data,
          id: 0
        }
        this.listLoading = false
        param.id = unserialize.id
        this.$refs.Form.init(param.formData, param.modelId, param.id, false, param.row, param.idKey, param.columnDict, param.dbLinkId, 'detail', param.associationRelation, param.fullName)
        return
      }
      const relationData = column.params.compoentConfig.relationData
      const associationData = this.associationData
      const associationColumnDict = this.associationColumnDict
      const res = await getConfigData(relationData.itemRelationTable)
      const data = res.data.data
      let param = {
        fullName: data.fullName,
        formData: JSON.parse(data.formData),
        associationRelation: data.associationRelation,
        modelId: relationData.itemRelationTable,
        idKey: data.idKey,
        columnDict: associationColumnDict[field],
        columnList: JSON.parse(data.columnData).columnList,
        dbLinkId: data.dbLinkId,
        row: associationData[field][row],
        id: 0
      }
      try {
        const detailData = await detail(param.modelId, param.dbLinkId, param.idKey, param.row[associationColumnDict[field][param.idKey]])
        if (detailData.data) {
          let relationMapList = loopRelationList(param.formData.fields)
          // param.formData.fields.forEach((i) => {
          //   if(i.__config__.jnpfKey === 'tab'){
          //     i.__config__.children.forEach((j) => {
          //       param.formData.fields.push(...j.__config__.children)
          //     })
          //   }
          // })
          const columnList = param.columnList.map((v) => {
            if (relationMapList.find((i) => i.__vModel__ === v.propId)) {
              return {
                ...v,
                ...{
                  params: {
                    compoentConfig: relationMapList.find((i) => i.__vModel__ === v.propId),
                    ...v,
                    field: detailData.columnDict[v.propId]
                  }
                }
              }
            }
          })
          Object.keys(detailData.data).forEach((key) => {
            const cellValue = detailData.data[key]
            const field = key
            const column = columnList
              .filter((i) => i)
              .filter((i) => i.params)
              .find((i) => i.params.field === field)
            if (column && column.params && column.params.compoentConfig.relationData && column.params.compoentConfig.relationData.showTitle.length) {
              const fieldArray = []
              if (cellValue) {
                cellValue.split(';').forEach((i, index) => {
                  if (column.params.compoentConfig.relationData.isCheck) {
                    try {
                      const data = detailData.associationData[field][row[field]]
                      const primaryId = column.params.compoentConfig.relationData.itemRelationList.find((i) => i.drawId === column.params.propId)
                      const relationField = detailData.associationColumnDict[field][primaryId.columnId]
                      fieldArray.push(data ? data[relationField] : i)
                    } catch (e) {
                      fieldArray.push(row[field])
                    }
                  } else {
                    // 逗号隔开
                    try {
                      const data = detailData.associationData[field][i]
                      const primaryId = column.params.compoentConfig.relationData.itemRelationList.find((i) => i.drawId === column.params.propId)
                      const relationField = detailData.associationColumnDict[field][primaryId.columnId]
                      fieldArray.push(data[relationField] ? data[relationField] : i)
                    } catch (e) {
                      fieldArray.push(detailData.data[field])
                    }
                  }
                })
                param.row[field + '_TEXT'] = fieldArray.join(',')
              }
            }
          })
        }
        this.listLoading = false
        param.id = param.row[param.columnDict[param.idKey]]
        this.$refs.Form.init(param.formData, param.modelId, param.id, false, param.row, param.idKey, param.columnDict, param.dbLinkId, 'detail', param.associationRelation, param.fullName)
      } catch (e) {
        console.log(e)
        this.listLoading = false
        this.$message.error('未获取到关联数据，请检查数据准确性')
      }
    },
    headBtnsHandel(key) {
      if (key === 'add') {
        this.addOrUpdateHandle()
      }
      if (key === 'download') {
        this.exportBoxData.columnListFieldList = this.columnList.filter((o) => {
          if (o && o.title !== '操作' && o.title !== '序号' && o.type !== 'checkbox') {
            return o
          }
        })
        this.exportBoxVisible = true
      }
      if (this.isPreview) return
      if (key === 'batchUpload') {
        this.uploadBoxVisible = true
        this.$nextTick(() => {
          let serialRow = this.formData.fields.find((o) => o.__config__.jnpfKey === 'serialNumber')
          this.$refs.UploadBox.init(this.columnList, this.config.dbLinkId, serialRow)
        })
      }
      if (key === 'batchRemove') {
        if (!this.idKey)
          return this.$message({
            message: '当前数据集暂无主键ID，不支持数据操作',
            type: 'warning'
          })
        this.batchRemove()
      }
      if (key === 'recycle') {
        this.recycleListBoxVisible = true
        this.$nextTick(() => {
          this.$refs.recycleListBox.init(this.columnList, this.config.dbLinkId)
        })
      }
      if (key === 'batchUpdate') {
        if (!this.idKey)
          return this.$message({
            message: '当前数据集暂无主键ID，不支持数据操作',
            type: 'warning'
          })
        this.batchEdit()
      }
    },
    handleCommand(command) {
      if (command === 'exportList') {
        this.exportListBoxVisible = true
        this.$nextTick(() => {
          this.$refs.exportListBox.init()
        })
      }
      if (command === 'uploadList') {
        this.uploadListBoxVisible = true
        this.$nextTick(() => {
          this.$refs.uploadListBox.init()
        })
      }
    },
    handleSelectionChange({ records }) {
      let data = g.removeRepeatAttr(records, this.columnDict[this.idKey])
      this.multipleSelectionDelectData = data
      this.multipleSelection = data.map((item) => item[this.columnDict[this.idKey]])
    },
    batchEdit() {
      if (!this.multipleSelection.length) {
        this.$message({
          type: 'error',
          message: '请至少选择一条数据',
          duration: 1500
        })
        return
      }
      let DelectData = deepClone(this.multipleSelectionDelectData)
      let jsonData = DelectData.map((i) => {
        return this.getBatchEditJsonData(i)
      })
      let columnPropId = this.columnList.map((i) => {
        return i.propId
      })
      //将列表中不显示的数据过滤掉
      const filteredArr = jsonData.map((obj) => {
        const filteredObj = {}
        Object.keys(obj).forEach((key) => {
          if (Number(key) === this.idKey || columnPropId.includes(Number(key))) {
            filteredObj[key] = obj[key]
          }
        })

        return filteredObj
      })
      this.batchEditBoxVisible = true
      this.$nextTick(() => {
        this.$refs.batchEditListBox.init(this.formData, this.columnList, filteredArr, this.idKey)
      })
    },
    //整合数据 配合流程进行存储回显数据
    getBatchEditJsonData(row) {
      let rows = Object.assign({}, row)
      let jsonData = deepClone(this.columnDict)
      const obj_ = {}
      // delete jsonData[this.idKey]
      for (let key in jsonData) {
        for (let index in rows) {
          if (jsonData[key] === index) {
            // jsonData[key] = rows[index]
            obj_[key] = rows[index]
          }
        }
      }
      return obj_
    },
    batchRemove() {
      if (!this.multipleSelection.length) {
        this.$message({
          type: 'error',
          message: '请至少选择一条数据',
          duration: 1500
        })
        return
      }
      let DelectData = deepClone(this.multipleSelectionDelectData)
      let jsonData = DelectData.map((i) => {
        return this.startsWithReduceRow(i)
      })
      let dataObj = {}
      for (let i = 0; i < jsonData.length; i++) {
        dataObj[jsonData[i][this.columnDict[this.idKey]]] = jsonData[i]
      }
      let dataJson = JSON.stringify(dataObj)
      this.$confirm('您确定要删除这些数据吗, 是否继续？', '提示', {
        type: 'warning'
      })
        .then(() => {
          batchDelete(this.modelId, this.multipleSelection, dataJson, JSON.stringify(this.columnDict)).then((res) => {
            this.$message({
              type: 'success',
              message: res.data.msg,
              duration: 1500,
              onClose: () => {
                this.refreshTableLayout()
              }
            })
          })
        })
        .catch(() => {})
    },
    UploadChange(data) {
      if (this.isPreview)
        return this.$message({
          message: '功能预览不支持数据导出',
          type: 'warning'
        })
      let query = { modelId: this.modelId, ...data }
      uploadModel(query)
        .then((res) => {
          if (res.data.code === 200) {
            this.$message({ message: res.data.msg, type: 'success' })
            this.$refs.UploadBox.visible = false
            this.$refs.UploadBox.btnLoading = false
            this.uploadBoxVisible = false
            this.$refs.Search.reset()
          } else {
            this.$refs.UploadBox.btnLoading = false
          }
        })
        .catch(() => {
          this.$refs.UploadBox.btnLoading = false
        })
    },
    dbClickColumnBtnsHandel({ row, column }) {
      if (column.editRender && column.editRender.enabled) {
        return false
      }
      this.columnBtnsHandel('detail', row)
    },
    handleFilterChange() {
      this.filterListSearch = []
      Object.keys(this.filterList).forEach((key) => {
        const obj = {}
        if (this.filterList[key]) {
          obj.cubeColumnId = +XEUtils.findKey(this.columnDict, (item) => item === key)
          obj.function = 'like'
          obj.values = [this.filterList[key]]
          if (obj.cubeColumnId) {
            this.filterListSearch.push(obj)
          }
        }
      })
      this.refreshTableLayout()
    },
    clearHandleFilterChange(column) {
      this.filterList[column.field] = ''
      this.handleFilterChange()
    },
    //操作按钮
    columnBtnsHandel(key, row, button) {
      if (!this.idKey)
        return this.$message({
          message: '当前数据集暂无主键ID，不支持数据操作',
          type: 'warning'
        })
      if (key === 'edit') {
        this.getPreconditionObjButs = this.getPreconditionObj[row[this.columnDict[this.idKey]]]
        this.addOrUpdateHandle(row)
      }
      if (key === 'detail') {
        this.addOrUpdateHandle(row, 'detail', this.config.fullName)
      }
      if (key == 'remove') {
        this.handleDel(row, button)
      }
      if (key == 'rowJournal') {
        this.journalBoxVisible = true
        this.$nextTick(() => {
          this.$refs.journalBox.init(row[this.columnDict[this.idKey]])
        })
      }
    },
    //回收站点击行显示详情数据
    recycleDetail(columnData) {
      let key = Object.keys(columnData)
      this.goDetail(columnData[key[0]][0])
    },
    //详情
    goDetail(row, flowState) {
      if (this.config.webType == 3) {
        let data = {
          id: row[this.idKey],
          enCode: this.config.flowEnCode,
          flowId: this.config.flowId,
          formType: 2,
          type: 1,
          opType: 0,
          modelId: this.modelId,
          isPreview: this.isPreview,
          status: flowState
        }
        this.flowVisible = true
        this.$nextTick(() => {
          this.$refs.FlowBox.init(data)
        })
      } else {
        this.detailVisible = true
        this.$nextTick(() => {
          this.$refs.Detail.init(this.formData, this.modelId, row, row[this.columnDict[this.idKey]], this.columnDict)
        })
      }
    },
    refresh(isRefresh, data) {
      // if(data){
      //   let adddata = data
      //   let keys = Object.keys(adddata)
      //   let obj = {}
      //   keys.forEach((i,k)=>{
      //     obj[this.columnDict[i]] = adddata[i]
      //   })
      //   this.list.unshift(obj)
      // }
      this.formVisible = false
      this.refreshTableLayout()
    },
    colseFlow(isRefresh) {
      this.flowVisible = false
      if (isRefresh) this.refreshTableLayout()
    },
    reset() {
      this.listQuery.sort = 'descs'
      this.listQuery.sidx = ''
      this.treeFilter = ''
      this.filterListSearch = ''
      this.treeBoxList = this.$refs.treeBox
      this.treeBoxList?.forEach((i) => {
        i.setCurrentKey(null)
      })
    },
    search(json) {
      if (this.isPreview) return
      if (!json) this.$refs.treeBox && this.$refs.treeBox.setCurrentKey(null)
      this.listQuery.json = json && json.length ? JSON.parse(json) : []
      this.listQuery.currentPage = 1
      this.refreshTableLayout()
    },
    // 新版表格开始
    async initData(foreignTableId = [], isRefresh = false) {
      if (this.isPreview) return
      this.listLoading = true
      //获取按钮权限
      await getModePermV2(this.modelId).then((res) => {
        this.customBtns = res.data.data
          .filter((v) => v.buttonType === 1)
          .map((item) => {
            item.value = item.permKey
            item.label = item.permName
            return item
          })
        let newArr = res.data.data
          .filter((v) => v.buttonType === 2)
          .map(function (item) {
            item.value = item.permKey
            item.label = item.permName
            return item
          })
        this.systemBtns = JSON.parse(JSON.stringify(newArr))
        this.columnData.btnsList = this.btnsOption
          .map((i) => {
            if (newArr.map((o) => o.value).includes(i.value)) {
              return i
            }
          })
          .filter((i) => i)
        this.hasBatchBtn = this.columnData.btnsList.some((o) => o.value == 'batchRemove') || this.customBtns.filter((o) => o.buttonLocation === 1).length > 0
        this.$nextTick(() => {
          this.refreshTable = true
        })
        this.columnData.columnBtnsList = this.columnBtnsOption
          .map((i) => {
            if (newArr.map((o) => o.value).includes(i.value)) {
              return i
            }
          })
          .filter((l) => l !== undefined)
        this.btnArr = this.columnData.columnBtnsList.concat()
        this.assemblyOptions = this.functionBtnsOption
          .map((i) => {
            if (newArr.map((o) => o.value).includes(i.value)) {
              return i.value
            }
          })
          .filter((l) => l !== undefined)
      })
      //获取列表数据
      function NewObj(key, vlaue) {
        this[key] = vlaue
      }
      let obj = new NewObj(this.listQuery.sort, this.listQuery.sidx)
      if (foreignTableId.length === 0 && !isRefresh) {
        foreignTableId = this.formData.fields
          .map((o) => {
            if (o.__config__.jnpfKey === 'table') {
              return o.__vModel__
            }
          })
          .filter((l) => l !== undefined)
      }
      if (this.listQuery.json && this.listQuery.json.length) {
        if (this.tabSearch) this.listQuery.json.push(this.tabSearch)
      } else {
        this.listQuery.json = this.tabSearch ? new Array(this.tabSearch) : ''
      }
      let listQuery = []
      if (this.treeFilter?.length) {
        listQuery = [...this.listQuery.json, ...this.treeFilter, ...(this.filterListSearch || [])]
      } else {
        listQuery = [...this.listQuery.json, ...(this.filterListSearch || [])]
      }
      let subTableQueryParams = []
      if (listQuery.length > 0) {
        listQuery.forEach((item) => {
          const oldItem = g.Copy(item)
          const findIndex = this.columnData.columnList.findIndex((i) => i.field === item.cubeColumnId)
          const find = this.columnData.columnList.find((i) => i.field === item.cubeColumnId)
          // 子表筛选
          if (findIndex && find?.config?.isJoin) {
            const subParamsObj = {
              tableName: find.config.tableName,
              columnName: find.config.columnName,
              function: find.config.jnpfKey === 'numInput' ? 'between' : 'like',
              values: oldItem.values
            }
            if (this.treeFilter.find((i) => i.cubeColumnId === item.cubeColumnId)) {
              subParamsObj.function = item.function
            }
            subTableQueryParams.push(subParamsObj)
            // 干掉主筛选里的子表条件
            listQuery = listQuery.splice(findIndex, 1)
          }
        })
      }
      // if (this.treeFilter?.length) {
      //   console.log(this.treeFilter)
      //   listQuery.push(this.treeFilter)
      // }
      const visualdevEntityDto = getSeachPrimaryAndForeignTable(this.config)
      this.parmes = {
        pageQuery: {
          currentPage: this.listQuery.currentPage,
          pageSize: this.listQuery.pageSize
        },
        primaryTableId: this.config.dbLinkId,
        foreignTableId: foreignTableId,
        modelId: this.modelId,
        browserRequest: listQuery ? JSON.stringify(listQuery) : JSON.stringify([]),
        subTableQueryParams: subTableQueryParams ? JSON.stringify(subTableQueryParams) : JSON.stringify([]),
        visualdevEntityDto
      }
      if (this.listQuery.sidx) {
        this.parmes.pageQuery[[this.listQuery.sort]] = this.listQuery.sidx
      }
      Object.assign(this.parmes.pageQuery, obj)
      const $grid = this.$refs.xGrid
      this.$grid = this.$refs.xGrid
      $grid.reloadData([])
      this.listLoading = true
      //获取数据权限过滤列表
      getBrowserData(this.config.dbLinkId, this.parmes).then(async (res) => {
        this.oldList = g.Copy(res.data.data.pageData.records)
        this.total = res.data.data.pageData.total
        if (!res.data.data.pageData.records) {
          this.listLoading = false
          return
        }
        this.associationData = res.data.data.associationData
        localStorage.setItem('BROWSER_associationData', JSON.stringify(this.associationData))
        this.associationColumnDict = res.data.data.associationColumnDict
        localStorage.setItem('BROWSER_associationColumnDict', JSON.stringify(this.associationColumnDict))

        //可显示的列
        let formDataFields = g.Copy(this.formData.fields)
        const itemRelationList = {}
        formDataFields.forEach((i) => {
          if (i.relationData && i.relationData.showTitle && i.relationData.showTitle.length) {
            i.relationData.itemRelationList.forEach((v) => {
              itemRelationList[v.drawId] = i.relationData
            })
          }
        })
        this.columnDict = res.data.data.columnDict
        formDataFields.forEach((i) => {
          if (i.__config__.jnpfKey === 'tab') {
            formDataFields = [
              ...formDataFields,
              ...g.T.toTable(
                i['__config__'].children.map((v) => v['__config__']),
                'children'
              ).filter((v) => v['__config__'])
            ]
          }
          if (i.__config__.jnpfKey === 'table') {
            formDataFields = [...formDataFields, ...g.T.toTable(i['__config__'].children, 'children').filter((v) => v['__config__'])]
          }
        })
        let columnList = []
        //过滤掉不可显示的列
        const apiList = {}
        const columnHeader = async (data, dbLinkId) => {
          let comName = {}
          let compoentConfig = {}
          comName = formDataFields.find((item) => item['__vModel__'] === data.propId)
          if (comName) {
            data.field = this.columnDict[data.propId]
            data.title = data.label
            data.showOverflow = true
            data.slots = {
              // 使用 JSX 渲染，
              edit: 'form_edit'
              // filter: 'filter_edit'
            }
            compoentConfig = comName ? JSON.parse(JSON.stringify(comName)) : {}
            if (comName && comName['__config__']) {
              compoentConfig = { ...compoentConfig, ...comName['__config__'] }
            }
            if (comName && comName['__slot__']) {
              compoentConfig = { ...compoentConfig, ...comName['__slot__'] }
            }
            if (comName.relationData && comName.relationData.PrimaryId) {
              compoentConfig.relationData.isText = true
            } else if (itemRelationList[data.propId]) {
              compoentConfig.relationData = itemRelationList[data.propId]
              compoentConfig.relationData.isText = !!comName.relationData?.PrimaryId
            }
            if (compoentConfig.tag === 'el-cascader') {
              compoentConfig.props = compoentConfig.props.props
              if (compoentConfig.propsUrl && compoentConfig.dataType !== 'static') {
                apiList[data.field] = await getAPIData(compoentConfig, compoentConfig.propsUrl, compoentConfig.ApiParams, this.formData.fields, '', compoentConfig.apiProps)
                const treeList = apiList[data.field].filter((i) => i[compoentConfig.apiProps.idKey] || i[compoentConfig.apiProps.pidKey])
                compoentConfig.options = g.T.toTree(treeList, compoentConfig.props.children, compoentConfig.apiProps.idKey, compoentConfig.apiProps.pidKey)
              }
            }
            if (compoentConfig.tag === 'el-select') {
              if (compoentConfig.dataType === 'dictionary') {
                await dictDetail({ id: compoentConfig.dictionaryType }).then((res) => {
                  // this.activeData.__slot__.options = res.data.data.list
                  let content = JSON.parse(res.data.data.content || '[]')
                  compoentConfig.options = content.map((i) => ({ fullName: i.value, id: i.key }))
                })
              } else if (compoentConfig.propsUrl && compoentConfig.dataType !== 'static') {
                apiList[data.field] = await getAPIData(compoentConfig, compoentConfig.propsUrl, compoentConfig.ApiParams, this.formData.fields, '', compoentConfig.apiProps)
                compoentConfig.options = apiList[data.field]
              }
            }
            if (compoentConfig.tag === 'JNPF-UploadImg' || compoentConfig.jnpfKey === 'radio') {
              compoentConfig.readonly = true
            }
            if (compoentConfig.relationData && compoentConfig.relationData.showTitle.length) {
              compoentConfig.readonly = true
              data.slots.default = 'relationDefault'
            }
            if (compoentConfig.isUrl) {
              compoentConfig.readonly = true
              data.slots.default = 'relationDefault'
            }
            data.editRender = {
              enabled: !compoentConfig.readonly,
              autoselect: true
            }
            if (!this.columnData.editable) {
              data.editRender.enabled = false
            }
            // console.log(compoentConfig.jnpfKey)
            if (compoentConfig.jnpfKey === 'uploadImg') {
              data.slots.default = 'default_images'
              data.showOverflow = false
            }
            if (compoentConfig.jnpfKey === 'uploadFz') {
              data.slots.default = 'default_file'
              data.showOverflow = false
            }
            if (['select', 'comInput', 'numInput'].includes(compoentConfig.jnpfKey)) {
              if (!this.columnData.showHeaderFilter) {
                // data.filters = []
                this.filterList[compoentConfig.__vModelName__] = {
                  function: 'eq'
                }
              }
            }
            data.params = comName ? { ...comName['__config__'], ...{ propId: data.propId, cPropId: dbLinkId, field: data.field }, ...{ compoentConfig: compoentConfig } } : {}
            data.formatter = ({ cellValue, row, column }) => {
              if (column.params.jnpfKey === 'comInput') {
                cellValue = `${column.params.compoentConfig.prepend || ''}${cellValue}${column.params.compoentConfig.append || ''}`
              }
              if (column.params.tag === 'el-date-picker') {
                cellValue = cellValue
                  ? XEUtils.toDateString(cellValue, column.params.compoentConfig.format) !== 'Invalid Date'
                    ? XEUtils.toDateString(cellValue, column.params.compoentConfig.format)
                    : cellValue
                  : ''
              }
              if (column.params.tag === 'el-time-picker') {
                try {
                  cellValue = cellValue
                    ? XEUtils.toDateString(cellValue, column.params.compoentConfig.format) !== 'Invalid Date'
                      ? XEUtils.toDateString(cellValue, column.params.compoentConfig.format)
                      : cellValue
                    : ''
                } catch (e) {}
              }
              if (column.params.tag === 'el-input-number') {
                // 数字
                if (column?.params?.compoentConfig?.precision > -1) {
                  cellValue = cellValue ? XEUtils.toNumber(cellValue).toFixed(column.params.compoentConfig.precision) : ''
                }
                // cellValue = cellValue ? XEUtils.toNumber(cellValue) : ''
              }
              if (column.params.tag === 'el-select') {
                if (data.params.dataType === 'dictionary') {
                  const find = column.params.compoentConfig.options.find((v) => v.id === cellValue)
                  cellValue = find && find.fullName ? find.fullName : cellValue
                } else if (data.params.dataType !== 'static') {
                  const find = apiList[data.field].find((v) => v[data.params.apiProps.value] === cellValue)
                  cellValue = find && find.fullName ? find.fullName : cellValue
                } else {
                  const find = column.params.compoentConfig.options.find((v) => v.id === cellValue)
                  cellValue = find && find.fullName ? find.fullName : cellValue
                }
              }
              if (column.params.tag === 'el-cascader') {
                if (data.params.dataType === 'dictionary') {
                  const find = column.params.compoentConfig.options.find((v) => v.id === cellValue)
                  cellValue = find && find.fullName ? find.fullName : cellValue
                } else if (data.params.dataType !== 'static') {
                  // 开启多选后，cellValue为多个数据 进行转换处理
                  if (data.params && data.params.compoentConfig && data.params.compoentConfig.props && data.params.compoentConfig.props.multiple) {
                    if (cellValue) {
                      cellValue = cellValue
                        .split(data.params.compoentConfig.props.separator || ';')
                        .map((v) => {
                          const find = apiList[data.field].find((i) => i[data.params.apiProps.idKey] === v)
                          return find && find.fullName ? find.fullName : v
                        })
                        .join(data.params.compoentConfig.props.separator || ';')
                    }
                  } else {
                    const find = apiList[data.field].find((v) => v[data.params.apiProps.idKey] === cellValue)
                    cellValue = find && find.fullName ? find.fullName : cellValue
                  }
                } else {
                  const find = g.T.toTable(column.params.compoentConfig.options, 'children').find((v) => v.id === cellValue)
                  cellValue = find && find.fullName ? find.fullName : cellValue
                }
              }
              if (column.params.tag === 'el-switch') {
                if (cellValue == column.params.compoentConfig['active-value']) {
                  cellValue = column.params.compoentConfig['active-text'] || '是'
                } else {
                  cellValue = column.params.compoentConfig['inactive-text'] || '否'
                }
              }
              if (column.params.jnpfKey === 'radio') {
                const find = column.params.compoentConfig.options.find((v) => v.id === cellValue)
                cellValue = find ? find.fullName : cellValue
              }
              if (cellValue == 'null' || cellValue == 'undefined') {
                return ''
              } else {
                return cellValue || null
              }
            }
          }
          return data
        }
        for (const item of this.columnList.filter((l) => l !== undefined)) {
          if (item.children && item.children.length > 0) {
            const list = []
            for (const v of item.children) {
              const data = await columnHeader(v, item.propId)
              list.push(data)
            }
            columnList.push({
              ...item,
              ...{
                sortable: false
              },
              children: list
            })
          } else {
            if (item.config && item.config.isJoin) {
              item.slots = {}
              // item.field = g.replaceAll(item.field, 'join_', '')
              if (item.jnpfKey === 'uploadImg') {
                item.slots.default = 'default_images'
                item.showOverflow = false
              }
              columnList.push(item)
            } else {
              const data = await columnHeader(item)
              columnList.push(data)
            }
          }
        }
        if (this.columnData.type !== 3 && this.columnData.hasPage) this.total = res.data.data.pageData.total
        if (this.columnData.type !== 3 && this.columnData.hasPage) this.listQuery.pageSize = res.data.data.pageData.size
        if (this.columnData.type !== 3 && this.columnData.hasPage) this.listQuery.currentPage = res.data.data.pageData.current
        if (this.columnData.type === 4) {
          this.$nextTick(() => {
            this.$refs.topForm.init(this.formData, this.modelId, this.isPreview, this.idKey)
          })
        }

        this.childrenForm = {}
        formDataFields.forEach((item) => {
          if (item['__config__'].jnpfKey === 'table' && item['__config__'].children.length > 0) {
            getChildrenConfigData(this.modelId, item.dbLinkId).then((res) => {
              const data = res.data.data
              this.childrenForm[data.dbLinkId] = data
            })
          }
        })
        let width = this.columnData.columnBtnsList.length * 55
        if (this.customBtns.length > 0) {
          width = width + 50
        }
        // console.log(width)
        if (!columnList.find((i) => i.title === '操作')) {
          columnList.push({ title: '操作', fixed: 'right', align: 'left', 'min-width': width, width: width, slots: { default: 'operate' } })
          columnList.unshift({ title: '序号', width: 50, field: 'seq', align: 'center' })
          if (this.hasBatchBtn) {
            columnList.unshift({ width: 50, type: 'checkbox', title: ' ' })
          }
        }
        this.columnList = columnList.filter((i) => i.title)
        this.listLoading = false
        // let dataList = res.data.data.pageData.records.map((v) => {
        //   Object.keys(v).forEach((key) => {
        //     if (key.includes('COL') && this.columnDict[this.idKey] !== key && !column.includes(key)) {
        //       delete v[key]
        //     }
        //   })
        //   return v
        // })
        this.getDataList(res.data.data.pageData.records)
      })
    },
    // 组装数据
    async getDataList(data) {
      if (!data) {
        this.listLoading = false
        return
      }
      data.forEach((item, index) => {
        item.seq = index + 1
      })
      const $grid = this.$refs.xGrid
      this.mergeCells = []
      let list = []
      let columnListTable = []
      if (this.isColumn) {
        columnListTable = $grid.getColumns()
      } else {
        columnListTable = g.T.toTable(this.columnList, 'children').filter((i) => i.jnpfKey !== 'table')
      }
      const dataMap = (data) => {
        return data.map((v, index) => {
          const foreignKeys = Object.keys(v).filter((key) => key.startsWith('FOREIGN_KEY_'))
          const mergedPageData = []
          if (foreignKeys.length > 0) {
            const foreignKeysLength = []
            for (let foreignKey of foreignKeys) {
              if (v[foreignKey] && v[foreignKey].pageData) {
                foreignKeysLength.push(v[foreignKey].pageData.length)
              }
            }
            if (foreignKeysLength.length === 0) {
              mergedPageData.push(v)
            } else {
              const numItems = Math.max(...foreignKeysLength)
              for (let i = 0; i < numItems; i++) {
                let mergedItem = {}
                // 循环合并在此索引位置的所有FOREIGN_KEY的pageData对象
                for (let foreignKey of foreignKeys) {
                  if (v[foreignKey] && v[foreignKey].pageData && v[foreignKey].pageData[i]) {
                    mergedItem = { ...mergedItem, ...v[foreignKey].pageData[i] }
                  }
                }
                // 添加合并后的对象到结果数组
                mergedPageData.push({ ...v, ...mergedItem, ...{ mergeRow: numItems, row: index } })
              }
            }
          } else {
            mergedPageData.push(v)
          }
          return mergedPageData
        })
      }
      list = dataMap(data)
      this.oldList = dataMap(this.oldList).flat()
      /*
        [
          { row: 0, col: 1, rowspan: 4, colspan: 1 },
          { row: 0, col: 2, rowspan: 4, colspan: 1 },
          { row: 0, col: 3, rowspan: 4, colspan: 1 },
          { row: 0, col: 4, rowspan: 4, colspan: 1 },
          { row: 4, col: 1, rowspan: 1, colspan: 1 },
          { row: 5, col: 1, rowspan: 2, colspan: 1 },
          { row: 5, col: 2, rowspan: 2, colspan: 1 },
          { row: 5, col: 3, rowspan: 2, colspan: 1 },
          { row: 5, col: 4, rowspan: 2, colspan: 1 },
        ]
       */
      let num = 0
      const newList = list.flat()
      let fields = {}

      for (const i of this.columnList) {
        if (i?.jnpfKey === 'uploadImg') {
          let newListArray = newList.map((o) => o[i.field])
          this.imgList[i.field] = newListArray
          console.log(this.imgList)
          // const res = await getFileById(newListArray.map((v) => v.split(';')).flat())
          // let obj = {}
          // Object.keys(res.data.data).forEach((o) => {
          //   obj[o] = comUrl + '/' + res.data.data[o].filePath
          // })
          // this.imgList[i.field] = obj
        }
        if (i?.jnpfKey === 'uploadFz') {
          let newListArray = newList
            .map((o) => o[i.field])
            .map((o) => (o?.url ? '' : o))
            .filter((o) => o && o !== 'null')
          const res = await getFileById(newListArray.map((v) => v.split(';')).flat())
          let obj = {}
          Object.keys(res.data.data).forEach((o) => {
            obj[o] = res.data.data[o]
          })
          this.fileList[i.field] = obj
        }
        if (i.children && i.children.length < 1) {
          fields[i.field] = columnListTable.findIndex((o) => o.field === i.field)
        }
      }

      // this.columnList.forEach((i, index) => {
      //   if (i?.jnpfKey === 'uploadImg') {
      //     getFileById(newList.map((o) => o[i.field]).map((o) => o.url || o)).then((res) => {
      //       let obj = {}
      //       Object.keys(res.data.data).forEach((o) => {
      //         obj[o] = [
      //           {
      //             name: res.data.data[o].fileName,
      //             fileId: res.data.data[o].id,
      //             url: comUrl + '/' + res.data.data[o].filePath
      //           }
      //         ]
      //       })
      //       this.imgList[i.field] = obj
      //     })
      //   }
      //   if (i.children && i.children.length < 1) {
      //     fields[i.field] = columnListTable.findIndex((o) => o.field === i.field)
      //   }
      // })
      list
        .filter((v) => v)
        .forEach((item) => {
          item.forEach((i, index) => {
            for (const iKey in i) {
              if (fields[iKey]) {
                this.mergeCells.push({
                  row: num,
                  col: fields[iKey],
                  rowspan: i.mergeRow,
                  colspan: 1
                })
              }
            }
            if (this.hasBatchBtn) {
              this.mergeCells.push({
                row: num,
                col: columnListTable.findIndex((o) => o.type === 'checkbox'),
                rowspan: i.mergeRow,
                colspan: 1
              })
            }
            this.mergeCells.push({
              row: num,
              col: columnListTable.findIndex((o) => o.title === '序号'),
              rowspan: i.mergeRow,
              colspan: 1
            })
            // 操作列合并
            this.mergeCells.push({
              row: num,
              col: columnListTable.findIndex((o) => o.title === '操作'),
              rowspan: i.mergeRow,
              colspan: 1
            })
          })
          num += item.length
        })
      // 数组拍平
      const getPreconditionParam = {
        buttonIdList: this.customBtns.map((i) => i.buttonId),
        idList: newList.map((i) => {
          return i[this.columnDict[this.idKey]]
        })
      }
      const getPreconditionObj = {}
      if (getPreconditionParam.buttonIdList.length > 0) {
        getPrecondition(this.modelId, getPreconditionParam).then((res) => {
          res.data.data.forEach((i) => {
            getPreconditionObj[i.authId] = i?.buttonList || []
            if (getPreconditionObj[i.authId].length > 0) {
              getPreconditionObj[i.authId].forEach((j) => {
                j.label = j.buttonName
                j.buttonId = j.id
              })
            }
          })
          this.getPreconditionObj = getPreconditionObj
        })
      }
      this.list = newList
    },
    // 重新渲染表格
    async refreshTableLayout(foreignTableId = [], isRefresh = false) {
      // eslint-disable-next-line no-unused-vars
      await this.initData((foreignTableId = []), (isRefresh = false))

      // getBrowserData(this.config.dbLinkId, this.parmes).then((res) => {
      //
      //   // this.getDataList(list)
      //   // this.listLoading = false
      //   // this.multipleSelectionDelectData = {}
      //   // this.multipleSelection = []
      //   // this.$refs.xGrid.clearSelected()
      // })
    },
    // 求和
    sumNum(list, field) {
      let count = 0
      list.forEach((item) => {
        count += Number(item[field] || 0)
      })
      return count
    },
    /*
      合计
     */
    footerMethod({ columns, data }) {
      const footerData = [
        columns.map((column, _columnIndex) => {
          if (_columnIndex === 0) {
            return '合计'
          }
          if (
            g.T.toTable(this.columnList)
              .filter((v) => v.showSummary)
              .map((v) => v.field)
              .includes(column.property)
          ) {
            return this.sumNum(data, column.property)
          }
          return '-'
        })
      ]
      return footerData
    },
    /*
      实时更新
     */
    editClosedEvent({ row, rowIndex, column }) {
      const $table = this.$refs.xGrid
      // 判断单元格值是否被修改
      let fields = []
      const fullColumn = $table.getTableColumn().fullColumn.filter((v) => v.params)
      Object.keys(row).forEach((field) => {
        if ($table.isUpdateByRow(row, field)) {
          column = fullColumn.find((v) => v.property === field)
          const dd = this.childrenForm[column.params.cPropId]
          setTimeout(() => {
            let idKey = this.idKey
            let type = 1
            let dbLinkId = this.config.dbLinkId

            if (dd && column.params.cPropId) {
              idKey = dd.idKey
              type = 2
              dbLinkId = dd.dbLinkId
              fields = this.columnList.filter((i) => i.propId === +dd.dbLinkId)
              fields = fields[0].children
            } else {
              fields = this.columnList.filter((i) => (i.children && i.children.length < 1) || !i.children)
            }
            let id = row ? row[this.columnDict[idKey]] : ''
            const primaryObj = {}
            let params = []
            //获取提交数据时 查询存在于子表数据集合的key 将主子表数据区分开
            fields.forEach((item) => {
              primaryObj[item.propId] = this.fillFormData(row, item, type)
            })
            params = [
              {
                data: JSON.stringify(primaryObj),
                id,
                oldData: this.$refs.Form.dataForm.oldData
              }
            ]
            NewupdateModel(this.modelId, params, id, dbLinkId, type).then((res) => {
              this.$message({
                message: res.data.msg,
                type: 'success',
                duration: 1500
              })
              $table.reloadRow(row, null, field)
              this.oldList.forEach((item) => {
                if (item[this.columnDict[idKey]] === row[this.columnDict[idKey]]) {
                  item[field] = row[field]
                }
              })
            })
          }, 300)
        }
      })
    },
    // 数据过滤
    fillFormData(data, item, type) {
      let val = data && data[item.field]
      let config = type === 1 ? item.config : item.params
      if (val) {
        if (config && config.viewDataType === 'DATETIME') {
          val = val ? moment(val).valueOf() : null
        }
        if (config && config.jnpfKey === 'select') {
          try {
            val = val.toString()
          } catch {}
        }
      }
      return val
    },
    // 自定义服务端导出
    exportMethod() {
      const $table = this.$refs.tableRef
      const colgroups = $table.getCheckboxRecords()
      const colgroupss = colgroups.filter((i) => i.children)
      const list = []
      console.log(colgroupss)
      colgroupss.map((item) => {
        if (item.children.length > 0) {
          const obj = {
            [item.title]: ''
          }
          item.children.forEach((i) => {
            list.push([...[obj], ...[{ [i.title]: i?.params?.propId }]])
          })
        } else {
          list.push([{ [item.title]: item?.params?.propId }])
        }
      })
      const data = {
        type: this.exportBoxData.exportType === 'all' ? true : false,
        isAll: this.exportBoxData.exportType === 'all' ? 1 : 0,
        title: list,
        columnIdList: colgroups.filter((i) => i.params).map((v) => v.params && v.params.propId),
        cubeIdList: g.removeRepeatAttr(colgroups.filter((i) => i.params).map((i) => i.params.cPropId)).filter((i) => i)
      }
      // if (!data.type){
      //   this.$refs.xGrid.exportData({
      //     filename: this.exportBoxData.fileName || '导出数据',
      //     columns: colgroups,
      //     type: 'xlsx',
      //   })
      //   return
      // }
      this.download(data)
    },
    download(data) {
      let taskName = this.exportBoxData.fileName || '导出数据'
      let modelId = this.modelId
      let query = {
        taskName,
        modelId,
        dataIdList: null,
        dataJson: null,
        currentPage: data.all === 'all' ? 1 : this.listQuery.currentPage,
        size: this.listQuery.pageSize,
        paramList: this.listQuery.json ? this.listQuery.json : [],
        ...data
      }
      exportBaseModel(query).then((res) => {
        if (res.data.code === 200) {
          this.$message({ message: res.data.msg, type: 'success' })
          this.exportBoxVisible = false
        }
      })
    },
    toolbarToolClickEvent(e) {
      const $grid = this.$refs.xGrid
      if (e.type === 'confirm') {
        // 是否字段选择
        this.isColumn = true
        setTimeout(() => {
          const columns = $grid.getColumns()
          // return
          this.refreshTableLayout(g.removeRepeatAttr(columns.map((i) => i.params && i.params.cPropId).filter((i) => i)), true)
        }, 300)
      }
      if (e.type === 'reset') {
        this.isColumn = false
        setTimeout(() => {
          this.refreshTableLayout([], false)
        }, 300)
      }
    },
    // 关联数据格式化
    formatAssociationData(row, column, item) {
      let cellValue = row[column.property]
      const field = column.field
      if (column.params.compoentConfig.isUrl) {
        const newUrl = g.replaceAll(cellValue, '@', '&')
        const unserialize = XEUtils.unserialize(newUrl)
        return unserialize.sname
      }
      if (column.params.compoentConfig.relationData && column.params.compoentConfig.relationData.showTitle.length) {
        if (column.params.compoentConfig.relationData.isCheck) {
          try {
            const data = this.associationData[field][row[field]]
            const primaryId = column.params.compoentConfig.relationData.itemRelationList.find((i) => i.drawId === column.params.propId)
            const relationField = this.associationColumnDict[field][primaryId.columnId]
            cellValue = data ? data[relationField] : cellValue
          } catch (e) {
            cellValue = row[field]
          }
        } else {
          // 逗号隔开
          try {
            const data = this.associationData[field][item]
            const primaryId = column.params.compoentConfig.relationData.itemRelationList.find((i) => i.drawId === column.params.propId)
            const relationField = this.associationColumnDict[field][primaryId.columnId]
            cellValue = data[relationField] ? data[relationField] : item
          } catch (e) {
            cellValue = row[field]
          }
        }
      }
      return cellValue === 'null' ? '' : cellValue
    },
    isCustomBtnsHandel(button, row) {
      if (button.execType === 2 && button.isWindow === 0 && button.windowTips) {
        this.$confirm(button.windowTips, '提示', {
          type: 'warning'
        })
          .then(() => {
            this.customBtnsHandel(button, row)
          })
          .catch(() => {})
      } else if (button.execType === 2 && button.isWindow === 1) {
        if (button.windowViewColumns) {
          let viewColumns = JSON.parse(button.windowViewColumns)
          let id = row.row ? row.row[this.columnDict[this.idKey]] : ''
          this.$refs.Form.init(
            this.formData,
            this.modelId,
            id,
            this.isPreview,
            row.row,
            this.idKey,
            this.columnDict,
            this.config.dbLinkId,
            '',
            this.config.associationRelation,
            this.config.fullName,
            viewColumns,
            true
          )
        }
      } else {
        this.customBtnsHandel(button, row)
      }
    },
    async customBtnsHandel(button, row, isQizhi = false) {
      const data = {}
      Object.entries(this.columnDict).forEach((item) => {
        const [key, value] = item
        const field = this.columnData.cubeList.find((i) => i.id === +key)
        if (field) {
          data[field.columnName] = row.row[value]
        }
      })
      if (button.execType === 1) {
        const url = XEUtils.template(button.redirectUrl, data)
        // 跳转新连接
        window.open(url)
        return
      }
      let loading = null
      if (!isQizhi) {
        loading = this.$loading({
          lock: true,
          text: '执行中',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        })
      }
      Object.entries(this.columnDict).forEach((item) => {
        const [key, value] = item
        const field = this.columnData.cubeList.find((i) => i.id === +key)
        if (field) {
          data[field.columnName] = row.row[value]
        }
      })
      const param = {
        buttonId: +button.buttonId,
        modelId: this.modelId,
        data
      }
      if (isQizhi) {
        param.executeTiming = 1
      }
      const res = await executeCustomButton(param)
        .catch((err) => {
          this.$message({
            message: err.data.msg,
            type: 'error',
            duration: 1500
          })
          this.loading?.close()
        })
        .finally(() => {
          if (!isQizhi) {
            this.loading?.close()
          }
          loading?.close()
        })
      if (!isQizhi) {
        this.loading?.close()
        this.$message({
          message: res.data.msg,
          type: 'success',
          duration: 1500
        })
      }
      if (!isQizhi) {
        this.refreshTableLayout()
      }
      return res
    },
    // 批量操作
    customBtnsBatchHandel(button) {
      if (!this.multipleSelection.length) {
        this.$message({
          type: 'error',
          message: '请至少选择一条数据',
          duration: 1500
        })
        return
      }
      const dataList = []
      this.multipleSelectionDelectData.forEach((row) => {
        const data = {}
        Object.entries(this.columnDict).forEach((item) => {
          const [key, value] = item
          const field = this.columnData.cubeList.find((i) => i.id === +key)
          if (field) {
            data[field.columnName] = row[value]
          }
        })
        dataList.push(data)
      })
      if (button.execType === 1) {
        const url = XEUtils.template(button.redirectUrl)
        // 跳转新连接
        window.open(url)
        return
      }
      const loading = this.$loading({
        lock: true,
        text: '执行中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      const param = {
        buttonId: +button.buttonId,
        modelId: this.modelId,
        dataList
      }
      executeBatchCustomButton(param)
        .then((res) => {
          this.$message({
            message: res.data.msg,
            type: 'success',
            duration: 1500
          })
          this.refreshTableLayout()
        })
        .catch((err) => {
          this.$message({
            message: err.data.msg,
            type: 'error',
            duration: 1500
          })
        })
        .finally(() => {
          loading.close()
        })
    },
    imgOpenClick(url) {
      let Base64 = require('js-base64').Base64
      // 获取当前时间的时间戳
      let currentTimestamp = Date.now()
      // 创建一个新的Date对象，并设置为当前时间加上一小时
      let oneHourLater = new Date(currentTimestamp)
      oneHourLater.setHours(oneHourLater.getHours() + 1)
      // 获取一小时后的时间戳
      let oneHourTimestamp = oneHourLater.getTime()
      let obj = {
        token: 'bearer ' + getToken(),
        time: oneHourTimestamp,
        env: document.location.origin
      }
      let objJson = Base64.encode(JSON.stringify(obj))
      let upUrl = Base64.encode(document.location.origin + '/' + url)
      let str = `/fileview/onlinePreview?url=${upUrl}&json=${objJson}`
      window.open(str, '_blank')
    },
    openCustom() {
      this.$grid.openCustom()
    }
  }
}
</script>
<style lang="scss" scoped>
.iconEdit {
  position: absolute;
  right: 10px;
  top: 10px;
  cursor: pointer;
}
.el-dropdown-link {
  cursor: pointer;
  color: var(--color-primary);
  font-size: 12px;
}
.el-icon-arrow-down {
  font-size: 12px;
}
.table_cell_clamp {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.el-tooltip__popper {
  max-width: 300px;
}
.el-tooltip__popper,
.el-tooltip__popper.is-dark {
  line-height: 24px;
}
.cell.el-tooltip {
  width: auto !important;
}
.freezeClass {
  background: #f1f1f1;
  border-radius: 7px;
}
.setAllTitle {
  padding: 0;
  cursor: pointer;
}
.setAllTitle:hover {
  color: #1890ff;
}
:deep(.amis-scope .cxd-Image-thumb) {
  width: 100%;
}
:deep(.amis-scope .cxd-Images) {
  margin: 0;
}
:deep(.amis-scope .cxd-ImagesField) {
  display: flex;
  align-items: center;
  justify-content: center;
}

:deep(.vxe-pager.is--background .vxe-pager--num-btn:not(.is--disabled).is--active) {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
:deep(.vxe-table--render-default .vxe-body--row.row--current) {
  background: var(--color-primary-bg);
}
:deep(.vxe-table--render-default .vxe-body--row.row--hover) {
  background: var(--color-primary-bg);
}
:deep(.vxe-button.type--text) {
  color: #000;
}
:deep(.vxe-button.type--text:not(.is--disabled):hover) {
  color: var(--color-primary);
}

:deep(.vxe-toolbar .vxe-buttons--wrapper, .vxe-toolbar .vxe-tools--wrapper) {
  flex: 0;
}
:deep(.vxe-tools--wrapper) {
  width: 100%;
}
:deep(.vxe-table-custom-wrapper) {
  right: 148px;
  top: -19px;
}
</style>
