    <template>
        <div class="dhc-proTable" ref="dhcProTableRef">
            <!-- 查询表单-->
            <search-form ref="searchForm" :search="search" :reset="reset" :searchParam="searchParam"
                :columns="searchColumns" :searchCol="searchCol" :tableCollapsed="collapsed"
                :labelWidth="searchLabelWidth" :formProps="searchFormProps" :searchDefaultShowRow="searchDefaultShowRow"
                v-show="isShowSearch" @collapsedChange="collapsed = !collapsed" />
            <!-- 表格顶部按钮 -->
            <div class="dhc-proTable-heard" ref="dhcProTableHeardRef" v-show="showTableHead">
                <div style="float: left;">
                    <slot name="header"></slot>
                </div>
                <div class="dhc-proTable-heard-icon" style="float: right;display: flex;">
                    <!-- 导出 -->
                    <a-button v-if="showExportButCom" type="primary" @click="executeExport" size="small"
                        icon="a-icon-upload2">导出</a-button>
                    <!-- 导入 -->
                    <div v-if="importConfig">
                        <a-upload v-show="showImportBut" ref="proTableImportBut" :action="action"
                            :headers="importHeaders"
                            :on-progress="importConfig['on-progress'] != undefined ? (event, file, fileList) => importConfig['on-progress'](event, file, fileList) : onImportProgress"
                            :on-success="importConfig['on-success'] != undefined ? (response, file, fileList) => { importFlag = false; messageCloseAll(); return importConfig['on-success'](response, file, fileList); } : onImportSuccess"
                            :on-error="importConfig['on-error'] != undefined ? (err, file, fileList) => { importFlag = false; messageCloseAll(); return importConfig['on-error'](err, file, fileList); } : onImportError"
                            :before-upload="onImportBeforeUpload" :show-file-list="false" v-bind="importConfig">
                            <a-button type="primary" size="small" icon="a-icon-download"
                                style="margin-left: 9px;margin-right: 9px;">导入</a-button>
                        </a-upload>
                    </div>
                    <!-- <a-tooltip v-if="searchColumns.length > 0" class="item" effect="dark" :content="collapsed ? '收起' : '展开'" placement="top-start">
            <a-button v-if="searchColumns.length > searchCol - 1" size="small" circle class="search-isOpen" @click="changeCollapsed(collapsed)">
                <i v-if="collapsed" class="a-icon-arrow-up"></i>
                <i v-else class="a-icon-arrow-down"></i>
            </a-button>
            </a-tooltip> -->
                    <a-tooltip v-if="searchColumns.length > 0" class="item" effect="dark" content="隐藏/展示"
                        placement="top-start">
                        <a-button v-if="searchColumns.length > 0" @click="isShowSearch = !isShowSearch" circle
                            size="small" icon="a-icon-view"></a-button>
                    </a-tooltip>
                </div>
            </div>


            <a-table ref="proTable" class="dhc-pro-table" :row-class-name="tableRowClassName"
                :dataSource="pageIsReadOnly && readOnlyTableData && readOnlyTableData.length > 0 ? readOnlyTableData : tableData"
                v-loading="loading" :row-style="{ height: rowHeight + 'px' }" :cell-style="{ padding: '0px' }"
                @row-click="proTableRowClick" @row-dblclick="proTableDblclick" @header-dragend="handleHeaderDragend"
                :height="customTableHeight > 0 ? customTableHeight : tableHeight" border :stripe="stripeFlag"
                :span-method="$attrs['span-method'] ? $attrs['span-method'] : handlerSpanMethod" :pagination="false"
                :rowSelection="rowSelection" :rowKey="rowKey" v-bind="$attrs" v-on="$listeners">

                <!-- 操作列 -->
                <a-table-column v-for="(item, index) in operationColums" :key="'operation' + index"
                    :fixed="isOperationFixed ? (operationAlignLeft ? 'left' : 'right') : undefined"
                    :dataIndex="item.prop" :title="item.label" v-bind="item">

                    <template v-slot="scope">
                        <div class="dhc-proTable-operation">
                            <div v-if="item.operationConfig != undefined" class="operation-buttons">
                                <h2>wyq</h2>
                                <render-dom :render="() => renderOperationButs(item, scope)"></render-dom>
                            </div>
                            <div v-else>

                                <render-dom :render="() => item.render(scope)"></render-dom>
                            </div>
                        </div>
                    </template>
                </a-table-column>
                <!-- 普通列 -->
                <a-table-column v-for="(item, index) in filterColumns" :key="index"
                    :class-name="item.tagConfig || item.editConfig || item.render ? 'renderCol' : (item.wrapDisplay ? 'wrapDisplay' : '')"
                    :show-overflow-tooltip="item.tagConfig || item.editConfig || item.render || item.wrapDisplay ? false : true"
                    :dataIndex="item.prop" :title="item.label" v-bind="item">
                    <!-- tag列 -->
                    <template v-if="item.tagConfig" v-slot="scope">
                        <a-tag :type="getTagType(scope, item)"
                            :size="item.tagConfig.size ? item.tagConfig.size : 'small'" v-bind="item.tagConfig">{{
                                scope.row[item.prop] }}</a-tag>
                    </template>

                    <!-- 编辑列 方式二 start-->
                    <template v-else-if="item.editing" #default="scope">
                        <a-form-item :name="['departLevelInfoData', 'records', scope.renderIndex, item.prop]"
                            :rules="item.rules" :style="{ margin: 0, width: '100%' }">
                            <a-input v-if="editableData[scope.index + item.prop]" v-focus
                                v-model:value="scope.record[item.prop]" @pressEnter="closeEdit(item, scope)"
                                @blur="closeEdit(item, scope)" placeholder="请输入" :allowClear="true" />
                            <div v-else @click="openEdit(item, scope)">
                                <div v-if="scope.record[item.prop]">{{ scope.record[item.prop] }}</div>
                                <div v-else style="color: white;background-color: transparent;">点击编辑</div>
                            </div>
                        </a-form-item>
                    </template>
                    <!-- 编辑列 方式二 end-->

                    <!-- 可编辑列 -->
                    <template v-else-if="item.editConfig" v-slot="scope">
                        <div @click="editColumnClick(scope)"
                            :class="{ 'dhc-proTable-editCell': true, 'isSelected': showEditCell(scope), 'isNotSelected': !showEditCell(scope) }">
                            <TableEditColumn :column="item" :rows="scope.record" />
                        </div>
                    </template>

                    <!-- 需要render的列 -->
                    <template v-else-if="item.render && item.isOperation != true" v-slot="scope">
                        <render-dom :render="() => item.render(scope)"></render-dom>
                    </template>
                </a-table-column>
                <slot></slot>
            </a-table>

            <!-- 分页栏 -->
            <div class="dhc-proTable-pagination" v-if="(showPagination == true)">
                <a-pagination align="center" :showSizeChanger="true" @change="paginationChange"
                    v-model:current="pageIndex" v-model:page-size="pageSize" @showSizeChange="handleSizeChange"
                    size="small" :show-total="total => `共 ${total} 条数据`" :total="totalCount">
                </a-pagination>
            </div>
            <export-config v-if="exportConfigVisible" :exportConfigVisible="exportConfigVisible"
                @close:modal='exportConfigVisible = false' :exportRquestConfig='exportRquestConfig'
                :exportExcelMeta="exportExcelMeta"></export-config>
        </div>
    </template>
<script lang="jsx">
    // import { exportExeclFile } from '@/utils/util.ts'
    import settings from '@/settings'
    import SearchForm from '../SearchForm/index.vue'
    import { getRefreashToken, getToken } from '@/utils/auth'
    import TableEditColumn from './components/TableEditColumn.vue'
    import { message as Message } from 'ant-design-vue'
    import { DashOutlined, CheckOutlined, EditOutlined, CloseOutlined } from '@ant-design/icons-vue'
    import { cloneDeep } from 'lodash-es';
    import {
        amtFormatter,
        indexOfArray
    } from '@/utils/util.ts'
    import ExportConfig from './components/ExportConfig.vue'
    import { TRUE } from 'sass'
    const { systemPrefix } = settings
    export default {
        name: 'ProTable',
        components: {
            renderDom: {
                functional: true,
                props: {
                    render: Function,
                },
                render (createElement, renDom) {
                    return this.$props.render()
                },
            },
            SearchForm,
            TableEditColumn,
            ExportConfig
        },
        inject: {
            pageIsReadOnly: {
                default: false
            }
        },
        props: {
            queryRule: Function,     //查询方法
            afterExecuteQuery: Function,  //查询方法执行之后执行
            rowClick: Function,      //单击事件
            dblclick: Function,      //双击事件
            columns: {
                type: Array,
                default: () => []
            },
            showPagination: {       //分页栏展示标志
                type: Boolean,
                default: () => true
            },
            dataSource: {           //数据源
                type: Object,
                default: () => ({})
            },
            showExportBut: Boolean,   //导出按钮展示标志
            exportConfig: Function,   //导出配置
            showImportBut: Boolean,   //导入按钮展示标志
            showTableHead: {
                type: Boolean,
                default: () => true     //为真时默认保留表格顶部按钮位置
            },
            importConfig: {           //导入配置
                type: Object,
                default: () => ({})
            },
            searchCol: {              //查询表单每行列数
                type: [Number, String],
                default: () => 3
            },
            searchLabelWidth: String, //查询表单项label宽度
            searchFormProps: Object,         //查询表单参数
            operationAlignLeft: {         //操作列居左居右（默认居左）
                type: Boolean,
                default: () => true
            },
            isOperationFixed: {           //操作列是否设置固定属性（默认fixed设置并根据operationAlignLeft默认居左）
                type: Boolean,
                default: () => true
            },
            // 高度差微调滚动高度
            altitudeDiff: {
                type: Number,
                default: 0,
            },
            // 表单展开时高度差微调滚动高度
            expandaltitudeDiff: {
                type: Number,
                default: 0,
            },
            isDefaultQuery: {
                type: Boolean,
                default: () => true
            },
            //行合并设置：{colList:String,uniqueList:String,hasPriority:Boolean}
            //colList：要合并的列,用逗号分隔；uniqueList：指定主键,用逗号分隔,
            //hasPriority:true|false 是否按照colList中列的顺序当做优先级来合并，排在前面的合并了后面的才能合并，与colList不能同时生效（优先生效）
            mergeConfig: Object,
            searchDefaultShowRow: [Number, String],   //查询表单默认展示的行数
            isSettingHeight: {     //是否设置表格高度
                type: Boolean,
                default: () => true
            },
            setPageSizes: {
                type: Array,
            },
            setPageSize: {
                type: Number,
            },
            isBaseQuery: {
                type: Boolean,
                default: () => false
            },
            //自定义表格高度
            customTableHeight: {
                type: Number,
                default: () => 0
            },
            // 查看数据源
            readTableData: {
                type: [Object, Array],
                default: null
            },
            exFormKey: {
                type: String,
                default: null
            },
            tableRowClassName: {
                type: Function,
            },
            stripeFlag: {
                type: Boolean,
                default: true
            },
            singleSelect: Boolean,//单选行: true为单选,false为多选,undefined不显示选择框
            rowKey: {
                type: String,
                default: () => 'no'
            },
        },
        data () {

            const formRules = {
                // 添加验证规则
                brf: [
                    { required: false, message: '层级功能描述不能为空', trigger: 'blur' },
                    // 其他校验规则
                ]
            };
            const { pageSize: pageSizeFormSet, pageSizes } = settings.proTable
            let { current = 1, total = 0, pageSize = pageSizeFormSet, data, records } = this.dataSource
            const { searchDefaultShowRow, setPageSizes, setPageSize } = this
            if (pageSize && pageSizes.indexOf(pageSize) == -1) {
                pageSizes.push(pageSize)
                pageSizes.sort((x, y) => {//比较函数
                    if (x < y) {
                        return -1
                    } else if (x > y) {
                        return 1
                    } else {
                        return 0
                    }
                })
            }
            let collapsed = true
            //设置了查询表单默认展示的行数，则查询表单默认收起
            if (searchDefaultShowRow != undefined && searchDefaultShowRow != 0) {
                collapsed = false
            }
            let tableData;
            if (data) {
                tableData = data
            } else if (records) {
                tableData = records
            } else {
                tableData = []
            }
            let editableData = {};
            return {
                editableData: editableData,
                tableData: tableData,
                pageIndex: current,
                pageSize: setPageSize ? setPageSize : pageSize,
                totalCount: total,
                pageSizes: setPageSizes ? setPageSizes : pageSizes,
                loading: false,
                tableHeight: 420,
                rowHeight: 37,
                searchFormHeight: 0,
                firstInit: true,
                //是否显示搜索表单
                isShowSearch: true,
                searchParam: {},
                //表单展开标志
                collapsed,
                //操作列展示的按钮数
                operationShowBut: 3,
                action: systemPrefix + this.importConfig?.action,
                //导入请求头
                importHeaders: {
                    Authorization: `Bearer ${getToken()}`,
                    'Refresh-Token': `${getRefreashToken()}`,
                    ...this.importConfig?.headers
                },
                importFlag: false,
                //操作列被选中的单元格
                selectedCell: {},
                //高度变化标志
                heightUpdateFlag: false,
                //导入中提示Message实例，用于关闭该提示框
                loadingMessage: undefined,
                mergedRanges: {},
                readOnlyTableData: this.readTableData,
                //记录表格横坐标的滚动距离，防止页面激活时滚动条重置
                scrollLeft: 0,
                exportConfigVisible: false,
                exportRquestConfig: {},
                exportExcelMeta: {},
                selectedRowKeys: [],//表格被选中的行
            }
        },
        watch: {
            isShowSearch (val) {
                const _this = this
                _this.$nextTick(() => {
                    let targetHeight = _this.tableHeight  //变化后表格高度
                    let tableHeight = _this.tableHeight   //表格高度
                    let searchFormHeight = _this.searchFormHeight //表单高度
                    if (val) {
                        targetHeight = tableHeight - searchFormHeight - 5
                    } else {
                        targetHeight = tableHeight + searchFormHeight + 5
                    }
                    _this.tableHeight = targetHeight
                })
                _this.heightUpdateFlag = true

            },
            collapsed (val) {
                const _this = this
                _this.$nextTick(() => {
                    let tableHeight = _this.tableHeight     //表格高度
                    let searchFormHeightDiff = _this.searchFormHeight - _this.$refs.searchForm.$el.offsetHeight   //变化前后表单的高度差
                    let targetHeight = tableHeight + searchFormHeightDiff   //变化后表格高度
                    _this.searchFormHeight = _this.$refs.searchForm.$el.offsetHeight    //计算完成后更新为当前表单高度
                    _this.tableHeight = targetHeight
                })
                _this.heightUpdateFlag = true
            },
            setPageSizes () {
                if (this.setPageSizes) {
                    this.pageSizes = this.setPageSizes
                }
            },
            columns: {
                immediate: true,//首次加载的时候执行函数
                handler () {
                    this.getSearchInitValue()
                }
            },
            searchParam () {
                consol.log('gzg  searchParam', this.searchParam)
                if (this.isBaseQuery) {
                    this.executeQuery(this.searchParam)
                }
            },
            dataSource: {
                deep: true,
                handler(val){
                    if (val.data){
                        this.tableData = val.data
                    } else if (val.records){
                        this.tableData = val.records
                    }else{
                        this.tableData = []
                    }
                }
            }
        },
        mounted () {
            console.log('gzg  mounted')
            if (this.isDefaultQuery) {
                this.executeQuery(this.searchParam)
            }
        },
        updated () {
            //设置表头工具栏样式
            this.setProTableHeardStyle()
            const _this = this
            // if (_this.isShowSearch && _this.heightUpdateFlag == false) {
            //     if (!this.$attrs.height) {
            //         setTimeout(() => {
            //             _this.$nextTick(() => {
            //                 let targetHeight = 420
            //                 //表格的offsetTop(某些页面表单展开时获取的高度有问题)
            //                 let proTableTop = _this.$refs.proTable.$el.offsetTop
            //                 _this.searchFormHeight = _this.$refs.searchForm.$el.offsetHeight
            //                 if (proTableTop > 0) {
            //                     let altitudeDiff = _this.altitudeDiff
            //                     if (_this.collapsed && _this.expandaltitudeDiff != 0) {
            //                         altitudeDiff = _this.expandaltitudeDiff
            //                     }
            //                     proTableTop = proTableTop > 150 ? proTableTop : proTableTop + 84
            //                     //表格内容高度 = 页面高度 - 表格的offsetTop - 顶部和页签边距等（90） - 页面补偿  - 分页
            //                     targetHeight = window.innerHeight - proTableTop - altitudeDiff - 32 - 10
            //                     if (targetHeight > 420 && this.showPagination) {
            //                         _this.$emit('update:altitudeSub', 420 - targetHeight)
            //                         _this.rowHeight = 37
            //                     }
            //                     _this.tableHeight = targetHeight
            //                 }
            //             })
            //         }, 500)
            //     } else {
            //         this.tableHeight = this.$attrs.height
            //     }
            // }
        },
        methods: {
            //---------暴露给父组件的方法-------------
            //重新加载表格数据
            reload () {
                this.executeQuery(this.searchParam)
            },
            //获取原生表格的ref
            getOrignRef () {
                return this.$refs.proTable
            },
            //获取表格数据源
            getTableData () {
                return this.tableData
            },
            //获取表格数据源
            getUploadRef () {
                return this.$refs.proTableImportBut
            },
            //设置当前被选中的行，通过rowIndex
            selectRowByIndex (rowIndex) {
                let row = this.tableData.filter((item, index) => index == rowIndex)
                if (row.length > 0) {
                    //单选
                    if (this.singleSelect == true) {
                        this.selectedRowKeys = [row[0][this.rowKey]]
                    } else if (this.singleSelect == false) {//多选
                        this.selectedRowKeys.push(row[0][this.rowKey])
                    }

                }
            },
            //设置当前被选中的行，通过rowKey
            selectRowByKey (rowKey) {
                let row = this.tableData.filter((item, index) => item[rowKey] == key)
                if (row.length > 0) {
                    //单选
                    if (this.singleSelect == true) {
                        this.selectedRowKeys = [row[0][this.rowKey]]
                    } else if (this.singleSelect == false) {//多选
                        this.selectedRowKeys.push(row[0][this.rowKey])
                    }
                }
            },
            //返回当前被选中的行数据(单选)
            getSelected () {
                const _this = this
                if (_this.selectedRowKeys.length == 0) {
                    return null;
                }
                return _this.tableData.filter(item => item[_this.rowKey] == _this.selectedRowKeys[0])[0]
            },
            //返回当前被选中的行数据(多选)
            getChecked () {
                const _this = this
                return _this.tableData.filter(item => _this.selectedRowKeys.includes(item[_this.rowKey]))
            },
            //手动向表格中塞入数据（适配easyUi写法）
            loadData (data) {
                const { rows, total } = data
                this.tableData = rows
                this.pageIndex = 1
                this.totalCount = total
            },
            //传入查询参数，重新调用加载方法（适配easyUi写法）
            reload (params) {
                console.log('gzg  reload', params)
                this.executeQuery(params);
            },
            //传入查询参数，重新调用加载方法，并将页码改为1（适配easyUi写法）
            load (params) {
                console.log('gzg  load', params)
                this.pageIndex = 1
                this.executeQuery(params);
            },
            //获取表格显示行数据、总数(rows、total)（适配easyUi写法）
            getData () {
                return { rows : this.tableData, total : this.totalCount }
            },

            //插入数据到指定索引位置（适配easyUi写法）
            insertRow (data) {
                const { index = 0, row } = data
                this.tableData.splice(index, 0, row)
            },
            //根据指定索引位置，更新行数据（适配easyUi写法）
            updateRow (data) {
                const { index, row } = data
                if (this.tableData[index]){
                    this.tableData[index] = { ...this.tableData[index],...row}
                }
            },
            //根据指定索引位置，删除数据（适配easyUi写法）
            deleteRow (index) {
                this.totalCount -= 1
                this.tableData.splice(index, 1)
            },
            getRowIndex (row){
                if (typeof row == 'object') {
                    return indexOfArray(this.tableData, row);
                } else {
                    for (var i = 0; i < this.tableData.length; i++) {
                        if (this.tableData[i][this.rowKey] == row) {
                            return i;
                        }
                    }
                    return -1;
                }
            },
            //----------------------------------------
            handleSizeChange (current, size) {
                if (this.pageSize != size) {   //防止重复请求
                    console.log('gzg  handleSizeChange', current, size)
                }
                this.pageSize = size
                this.pageIndex = 1
                //this.executeQuery(this.searchParam)
            },
            paginationChange (page, pageSize) {
                if (this.pageIndex != page || this.pageSize != pageSize) {   
                    //防止重复请求
                    console.log('gzg  paginationChange', page, pageSize)
                }
                this.pageIndex = page
                this.executeQuery(this.searchParam)
            },
            messageCloseAll () {
                this.loadingMessage && this.loadingMessage.close()
                Message.closeAll()
            },
            //获取导入按钮原生ref
            // getImportButRef(){
            //     return this.$refs.proTableImportBut
            // },
            //搜索方法重置方法
            search (params) {
                this.executeQuery(params)
            },
            //表单重置方法
            reset (initValues) {
                this.searchParam = JSON.parse(JSON.stringify(initValues))
                this.executeQuery({ ...initValues, isButton: true })
                // 添加重置后置处理
                this.$emit('searchForm:resetAfter')
            },
            async executeQuery (params = {}) {
                console.log('gzg  executeQuery', params)
                if (!this.queryRule)return;
                const that = this
                let validateFlag = true
                //执行查询方法前先对查询表单进行校验
                if (this.searchColumns.length > 0) {
                    this.$refs.searchForm.getOrignRef()?.validate((valid) => {
                        if (valid == false) {
                            validateFlag = false
                            return false
                        }
                    })
                }
                //查询表单校验成功执行查询方法
                if (validateFlag) {
                    this.loading = true
                    let resp = await this.queryRule({ pageIndex: this.pageIndex, pageSize: this.pageSize }, params)

                    if (resp.success == false) {
                        that.$message({
                            message: "表格查询失败！ " + resp.errMessage,
                            type: "error"
                        })
                        return
                    }

                    // if (this.rowKey == 'key') {
                    //     resp.data = resp.data.map((item, index) => {
                    //         item.key = index
                    //         return item;
                    //     })
                    // }

                    //判断当前页是否大于分页栏总页数，如果大于则跳转到第一页
                    //页数
                    let pageNum = parseInt(resp.total / that.pageSize)
                    //余数
                    let rowNum = resp.total % that.pageSize
                    //总页数
                    let pageTotal = pageNum + (rowNum > 0 ? 1 : 0)
                    if (that.pageIndex > pageTotal && resp.total > 0) {
                        this.pageIndex = 1
                        console.log('gzg  executeQuery1', params)

                        this.executeQuery(params)
                        return
                    }

                    //格式化表格列数据，不改变数据源，给列增加formatter方法
                    if (this.formatColums.length > 0) {
                        let props = this.formatColums.map(item => item.prop)
                        for (let i = 0; i < resp.data?.length; i++) {
                            props.forEach((item, index) => {
                                let { type, prefix = '', suffix = '' } = that.formatColums[index].formatterValue
                                if (type) {
                                    switch (type) {
                                        //金额，三位一逗
                                        case 'amt':
                                            that.formatColums[index].formatter = function (row, column, cellValue, index) {
                                                row[item] = isEmpty(row[item]) ? '' : row[item]
                                                return prefix + amtFormatter(row[item]) + suffix
                                            }
                                            break
                                    }
                                }
                            })
                        }
                    }


                    this.tableData = resp.data,
                        this.pageIndex = resp.current,
                        this.pageSize = resp.pageSize,
                        this.totalCount = resp.total,
                        this.loading = false

                    if (this.pageIsReadOnly && this.tableData) {
                        let readTableDataWrapper = []
                        let readTableDataTemp = [...this.readTableData]
                        readTableDataTemp.forEach((item, index) => {
                            if (this.tableData[index]) {
                                Object.entries(this.tableData[index]).forEach(([k, v]) => {
                                    if (!item[k] && v) {
                                        item[k] = v
                                    }
                                })
                            }
                            readTableDataWrapper.push(item)
                        })
                        this.readOnlyTableData = readTableDataWrapper
                    }
                }
                this.afterExecuteQuery && this.afterExecuteQuery()
                this.$emit("update:tableData", this.tableData)
                //如果有合并且为优先级合并，则刷新一下this.mergedRanges
                if (this.mergeConfig && this.mergeConfig.hasPriority) {
                    this.computMergeRange()
                }
            },
            //计算要合并的各个列的范围
            computMergeRange () {
                let { colList } = this.mergeConfig
                //计数器，默认为一行
                let count = 1
                //要合并的列,用逗号分隔(例如:"name,department,office"，"no");
                let fileds = colList.split(",")
                let mergedRanges = {}
                fileds.forEach(filed => {
                    mergedRanges[filed] = []
                })
                let tableData = this.tableData
                fileds.forEach((filed, index) => {
                    let endIndex = -1
                    for (let rowIndex = 0; rowIndex < tableData.length; rowIndex++) {
                        count = 1
                        if (rowIndex <= endIndex) {
                            continue
                        }
                        //首个需要合并的列，不需要根据前几列进行限制
                        if (index === 0) {
                            //计算此单元格要合并的行
                            for (let i = rowIndex + 1; i < tableData.length; i++) {
                                if (tableData[i][filed] === tableData[rowIndex][filed]) {
                                    count++
                                } else {
                                    break
                                }
                            }
                            //保存合并行的下标范围
                            if (count > 1) {
                                let flag1 = true
                                mergedRanges[filed].forEach(item => {
                                    if (item.start === rowIndex && item.end === count + rowIndex - 1) {
                                        flag1 = false
                                    }
                                })
                                if (flag1) {
                                    endIndex = count + rowIndex - 1
                                    mergedRanges[filed].push({ start: rowIndex, end: count + rowIndex - 1 })
                                }
                            }
                        } else {//不是第一个要合并的列，根据前一个要合并的列的范围来限制合并的行
                            //如果此行在合并的行的下标范围内，则为被合并的行，直接返回0行0列
                            let quitFlag = false
                            let ranges = mergedRanges[fileds[index]]
                            for (let i = 0; i < ranges.length; i++) {
                                if (rowIndex > ranges[i].start && rowIndex <= ranges[i].end) {
                                    quitFlag = true
                                    break
                                }
                            }
                            if (quitFlag) {
                                continue
                            }
                            //计算此单元格要合并的行
                            for (let i = rowIndex + 1; i < tableData.length; i++) {
                                if (tableData[i][filed] === tableData[rowIndex][filed]) {
                                    count++
                                } else {
                                    break
                                }
                            }
                            //获取前一个要合并的列的范围数组
                            let ranges1 = mergedRanges[fileds[index - 1]]
                            let flag = true
                            for (let i = 0; i < ranges1.length; i++) {
                                if (rowIndex >= ranges1[i].start && rowIndex <= ranges1[i].end) {
                                    //限制合并的范围不超过上一级的end
                                    if (rowIndex + count > ranges1[i].end) {
                                        count = ranges1[i].end - rowIndex + 1
                                    }
                                    flag = false
                                    break
                                }
                            }
                            //如果不在任何一个范围里，说明不应该合并
                            if (flag) {
                                continue
                            }
                            //保存合并行的下标范围
                            if (count > 1) {
                                let flag1 = true
                                mergedRanges[filed].forEach(item => {
                                    if (item.start === rowIndex && item.end === count + rowIndex - 1) {
                                        flag1 = false
                                    }
                                })
                                if (flag1) {
                                    mergedRanges[filed].push({ start: rowIndex, end: count + rowIndex - 1 })
                                }
                            }
                        }
                    }
                })
                this.mergedRanges = mergedRanges
            },
            //导出方法
            executeExport () {
                if (this.exportConfig != undefined) {
                    let searchParam = this.searchParam;
                    //过滤掉值为空的参数，解决导出数据异常问题
                    searchParam = Object.keys(searchParam).filter((key) => searchParam[key] !== null && searchParam[key] != '' && searchParam[key] !== undefined)
                        .reduce((acc, key) => ({ ...acc, [key]: searchParam[key] }), {});

                    let { exportRquestConfig, exportExcelMeta } = this.exportConfig(searchParam)
                    let columns = this.columns.filter(item => item.prop && item.prop != '' && item.isExport != false)
                    if (isEmpty(exportExcelMeta.columnList)) {
                        exportExcelMeta.columnList = columns.map(item => {
                            return {
                                title: item.label,
                                field: item.prop,
                                align: item.align,
                                width: item.width || item["min-width"] || 120
                            }
                        })
                    }
                    console.log('gzg  exportRquestConfig, exportExcelMeta', exportRquestConfig, exportExcelMeta)
                    this.exportRquestConfig = exportRquestConfig
                    this.exportExcelMeta = exportExcelMeta
                    this.exportConfigVisible = true
                    // exportExeclFile(exportRquestConfig, exportExcelMeta)
                } else {
                    this.$message({
                        message: "未设置导出配置！",
                        type: "error"
                    })
                }

            },
            proTableRowClick (row, column, event) {
                if (this.rowClick) {
                    this.rowClick(row, column, event)
                }
            },
            proTableDblclick (row) {
                if (this.dblclick) {
                    this.dblclick(row)
                }
            },
            //获取tag类型
            getTagType (scope, item) {
                if (item.tagConfig.types) {
                    for (let key in item.tagConfig.types) {
                        if (scope.row[item.prop] == key) {
                            return item.tagConfig.types[scope.row[item.prop]]
                        }
                    }
                } else {
                    return ''
                }
            },
            //操作列按钮渲染函数
            renderOperationButs (item, scope) {
                let result = ''
                let dropdown = []
                let { operationShowBut } = this
                let that = this
                if (item.operationConfig?.operationShowBut) {
                    operationShowBut = item.operationConfig.operationShowBut
                }
                if (item.operationConfig?.buttons?.length > 0) {
                    //过滤掉不展示的按钮
                    let buttons = item.operationConfig.buttons.filter(item => {
                        if (item.isShow) {
                            return item.isShow(scope)
                        } else {
                            return true
                        }
                    })
                    //直接展示的按钮
                    result = buttons.map((attr, index) => {
                        if (index < operationShowBut) {
                            return <a-button
                                type="link"
                                size="small"
                                disabled={attr.disabled ? attr.disabled(scope) : false}
                                onClick={() => attr.onClick(scope)}
                                icon={attr.icon}>{attr.text}</a-button>
                        }
                    })
                    let dropdownItem = []
                    buttons.forEach((attr, index) => {
                        if (index >= operationShowBut) {
                            dropdownItem.push(<a-menu-item>
                                <a-button
                                    type="link"
                                    size="small"
                                    disabled={attr.disabled ? attr.disabled(scope) : false}
                                    onClick={() => attr.onClick(scope)}
                                    icon={attr.icon}>{attr.text}</a-button>
                            </a-menu-item>)
                        }
                    })
                    //创建下拉菜单按钮组
                    if (dropdownItem.length > 0) {
                        dropdown = <a-dropdown trigger="click" size="small" placement="bottomStart" style="margin-left: 10px;">
                            <a-button type="link" size="small"><DashOutlined /></a-button>
                            <template v-solt:overlay>
                                <a-menu>
                                    {dropdownItem}
                                </a-menu>
                            </template>
                        </a-dropdown>
                        result.push(dropdown)
                    }
                }
                return result
            },
            //导入文件时的钩子
            onImportProgress (event, file, fileList) {
                if (!this.importFlag) {
                    this.importFlag = true
                    this.loadingMessage = this.$message({
                        message: '导入中...',
                        iconClass: 'a-icon-loading',
                        showClose: "true",
                        duration: 5000,
                    })
                }
            },
            //导入文件成功时的钩子
            onImportSuccess (response, file, fileList) {
                let { success, errMessage } = response
                this.importFlag = false
                this.messageCloseAll()
                if (!success) {
                    this.$message.error('导入失败!' + errMessage)
                }
            },
            //导入文件失败时的钩子
            onImportError (err, file, fileList) {
                this.importFlag = false
                this.messageCloseAll()
                this.$message.error('导入失败!' + err)
            },
            //上传文件之前的钩子
            async onImportBeforeUpload (file) {
                let flag = true
                if (this.importConfig['before-upload']) {
                    flag = await this.importConfig['before-upload'](file)
                } else {
                    let { fileTypes = ['xlsx', 'xls'] } = this.importConfig
                    let { name } = file
                    let suffixName = name.substring(name.lastIndexOf(".") + 1, name.length)

                    flag = fileTypes.includes(suffixName)

                    if (!flag) {
                        let message = "导入文件格式只能为" + fileTypes.join('、')
                        this.$message.error(message)
                    }
                }
                if (!flag) return Promise.reject(flag) //正确的终止
                return flag
            },
            //编辑列点击回调
            editColumnClick (scope) {
                this.selectedCell = { index: scope.$index, prop: scope.column.property }
            },
            openEdit (item, scope) {
                // 关闭其他编辑单元格
                this.editableData = {};
                this.editableData[scope.index + item.prop] = scope.index + item.prop;
            },
            closeEdit (item, scope) {
                delete this.editableData[scope.index + item.prop];
            },
            //校验编辑单元格是否可编辑
            showEditCell (scope) {
                return scope.index == this.selectedCell.index && scope.column.property == this.selectedCell.prop
            },
            //设置表头工具栏样式
            setProTableHeardStyle () {
                this.$nextTick(() => {
                    //表头工具栏DOM
                    let proTableHeard = document.getElementsByClassName('dhc-proTable-heard')
                    proTableHeard = Array.from(proTableHeard)
                    proTableHeard.forEach((item) => {
                        //工具栏只有右侧按钮
                        if (item.children.length == 1) {
                            //右侧按钮Dom
                            let heardIcon = Array.from(item.children)[0]
                            //按钮全部不展示，将工具栏高度和内边距设为0
                            if (Array.from(heardIcon.children).length == 0) {
                                item.style.minHeight = '0px'
                                item.style.padding = '0px'
                            }
                        }
                    })
                })
            },
            /**
             * 返回指定行与之后行的联合主键相等的行数
             * @param {*} uniqueCols 联合主键列
             * @param {*} data 表格数据
             * @param {*} rowIndex 指定行
             * @param {*} count 相同行数(方法内部使用)
             */
            isEqualsRows (uniqueCols, tableData, rowIndex, rowCount) {
                //行相等计数器
                let count = 1
                if (rowCount) {
                    count = rowCount
                }
                //当前行为最后一行时
                if (tableData.length == rowIndex + 1) {
                    return count
                }
                //下一行数据
                let nextData = tableData[rowIndex + 1]
                let equalsFlag = true
                //判断联合主键是否相等
                uniqueCols.forEach(item => {
                    if (equalsFlag == false) {
                        return
                    } else if (tableData[rowIndex][item] != nextData[item]) {
                        equalsFlag = false
                    }
                })
                //与下一行相等
                if (equalsFlag) {
                    return this.isEqualsRows(uniqueCols, tableData, rowIndex + 1, count + 1)
                } else {
                    return count
                }
            },
            //单元格合并回调
            handlerSpanMethod ({ row, column, rowIndex, columnIndex }) {
                let { tableData, mergeConfig } = this
                //未设置合并配置,直接展示
                if (mergeConfig == undefined || (mergeConfig.colList == undefined) || (mergeConfig.hasPriority == undefined && mergeConfig.uniqueList == undefined)) {
                    return {
                        rowspan: 1,
                        colspan: 1
                    }
                } else {
                    //如果hasPriority为true，则调用mergeRowsWithPriority方法
                    if (mergeConfig.hasPriority) {
                        return this.mergeRowsWithPriority(row, column, rowIndex, columnIndex)
                    } else {
                        //通过联合主键来合并
                        return this.mergeRowsWithCompositeKey(row, column, rowIndex, columnIndex)
                    }
                }
            },
            //通过联合主键来合并
            mergeRowsWithCompositeKey (row, column, rowIndex, columnIndex) {
                let { tableData, mergeConfig } = this
                let { colList, uniqueList } = mergeConfig
                //要合并的列,用逗号分隔(例如:"name,department,office"，"no");
                let fileds = colList.split(",")
                //指定主键,用逗号分隔(例如:"no,name");
                let uniqueCols = uniqueList.split(",")
                //行的porp
                let { property } = column
                //当前列是否在需要合并的列中
                let flag = false
                fileds.forEach(item => {
                    if (flag) {
                        return
                    } else if (item == property) {
                        flag = true
                    }
                })
                //当前列不需要进行合并
                if (!flag) {
                    return {
                        rowspan: 1,
                        colspan: 1
                    }
                }
                //非首行数据时
                if (rowIndex != 0) {
                    //上一行数据
                    let upData = tableData[rowIndex - 1]
                    let equalsFlag = true
                    //判断联合主键是否相等
                    uniqueCols.forEach(item => {
                        if (equalsFlag == false) {
                            return
                        } else if (tableData[rowIndex][item] != upData[item]) {
                            equalsFlag = false
                        }
                    })
                    //与上一行联合主键相等
                    if (equalsFlag) {
                        return {
                            rowspan: 0,
                            colspan: 0,
                        }
                    } else {//与上一行联合主键不相等
                        let rowspan = this.isEqualsRows(uniqueCols, tableData, rowIndex)
                        return {
                            rowspan: rowspan,
                            colspan: 1,
                        }
                    }
                } else {//首行数据时
                    let rowspan = this.isEqualsRows(uniqueCols, tableData, rowIndex)
                    return {
                        rowspan: rowspan,
                        colspan: 1,
                    }
                }
            },
            //通过列的优先级来合并
            mergeRowsWithPriority (row, column, rowIndex, columnIndex) {
                let { colList } = this.mergeConfig
                //要合并的列,用逗号分隔(例如:"name,department,office"，"no");
                let fileds = colList.split(",")
                //行的porp
                let { property } = column
                //计数器，默认为一行
                let index = fileds.indexOf(property)
                //当前列是否在需要合并的列中
                if (index !== -1) {
                    let ranges = this.mergedRanges[fileds[index]]
                    for (let i = 0; i < ranges.length; i++) {
                        if (rowIndex > ranges[i].start && rowIndex <= ranges[i].end) {
                            return {
                                rowspan: 0,
                                colspan: 0
                            }
                        } else if (rowIndex == ranges[i].start) {
                            return {
                                rowspan: ranges[i].end - ranges[i].start + 1,
                                colspan: 1
                            }
                        }
                    }

                    return { rowspan: 1, colspan: 1 }

                } else {
                    //当前列不需要进行合并
                    return {
                        rowspan: 1,
                        colspan: 1
                    }
                }

            },
            //获取查询表单初始化值
            getSearchInitValue () {
                let result = {}
                this.columns.map(item => {
                    if (item.search?.defaultValue) {
                        result[item.search.key ? item.search.key : item.prop] = item.search.defaultValue
                    }
                })
                this.searchParam = result
            },
            changeCollapsed (collapsed) {
                if (this.isShowSearch) {
                    this.collapsed = !collapsed
                } else {
                    this.$message.error('请展示后操作!')
                }
            },
            //设置某一行的选中状态，第一个参数为每条数据的唯一标识参数名，第二个参数为为每条数据的唯一标识参数值
            toggleRowSelection (paramName, paramValue, selected) {
                for (let row of this.tableData) {
                    if (row[paramName] === paramValue) {
                        this.$refs.proTable.toggleRowSelection(row, selected)
                    }
                }
            },
            //当拖动表头改变了列的宽度的时候重新渲染一下表格结构，解决操作列塌陷和上移的问题
            handleHeaderDragend (newWidth, oldWidth, column, event) {
                this.$nextTick(() => {
                    this.$refs['proTable'].doLayout()
                })
            },
            //暴露给父组件使用，解决tabs切换时高度塌陷问题
            doLayout () {
                this.$nextTick(() => {
                    this.$refs['proTable'].doLayout()
                })
            },
            //表格列被选择回调
            onSelectChange (selectedRowKeys) {
                this.selectedRowKeys = selectedRowKeys;
            },
        },
        computed: {
            searchColumns () {
                const _this = this
                let searchColumn = this.columns.filter(item => item.search?.el)
                searchColumn.sort((a, b) => {
                    if (a.search.order && !b.search.order) {
                        return false
                    } else if (!a.search.order && b.search.order) {
                        return true
                    } else if (a.search.order && b.search.order) {
                        return a.search.order - b.search.order
                    } else {
                        return true
                    }
                })
                return searchColumn
            },
            filterColumns () {
                //过滤掉不展示和操作列
                let result = this.columns.filter(item => item.isShow !== false)
                return result.filter(item => item.isOperation != true)
            },
            //操作列
            operationColums () {
                //获取操作列
                return this.columns.filter(item => item.isOperation == true)
            },
            //需要格式化的列
            formatColums () {
                let result = []
                result = this.columns.filter(item => item.formatterValue && item.formatterValue != {})
                return result
            },
            showExportButCom () {
                const { showExportBut } = settings.proTable
                return showExportBut && this.showExportBut
            },
            rowSelection () {

                if (this.singleSelect === undefined) {
                    return null;
                } else if (this.singleSelect === true) {
                    return { type: 'radio', selectedRowKeys: this.selectedRowKeys, onChange: this.onSelectChange }
                } else {
                    return { type: 'checkbox', selectedRowKeys: this.selectedRowKeys, onChange: this.onSelectChange }
                }
            }
        },
        beforeUpdate () {
            // table数据更新后，重新渲染table避免闪动
            // this.$nextTick(() => {
            //     this.$refs['proTable'].doLayout()
            // })
        },
        //被激活时触发重新渲染方法，解决切换页面回来后渲染列塌陷的问题
        activated () {
            let that = this
            this.$nextTick(() => {
                // this.$refs['proTable'].doLayout()
                let bodyWrapper = document.querySelector(".a-table__body-wrapper")
                //设置横向滚动条
                // bodyWrapper.scrollTo(that.scrollLeft, 0)
            })
        },
        // deactivated () {
        //     // 记录滚动条位置
        //     let bodyWrapper = document.querySelector(".a-table__body-wrapper")
        //     this.scrollLeft = bodyWrapper.scrollLeft
        // },

        // directives: {
        //     // 自定义指令用于聚焦输入框
        //     focus: {
        //         mounted: (el) => {
        //             // el.focus();
        //             // el.querySelector('input')?.focus();
        //             el.querySelector('.ant-input')?.focus();
        //         }
        //     }
        // }
    }
    </script>
<style lang="scss">
.dhc-proTable {
    background-color: rgb(240, 242, 245);

    //表头内容固定居中
    .a-table__header-wrapper thead tr th div {
        text-align: center;
    }

    .dhc-proTable-heard {
        min-height: 50px;
        background-color: white;
        padding: 10px;
        line-height: 30px;
        font-size: 13px;

        .dhc-proTable-heard-icon {
            >*:not(:first-child) {
                padding-left: 9px;
            }
        }
    }

    .dhc-pro-table {
        width: 100%;
    }

    .dhc-proTable-pagination {
        background-color: white;
    }

    .dhc-proTable-pagination .a-pagination {
        padding: 4px 5px;
    }

    //操作列
    .dhc-proTable-operation {
        .operation-buttons {
            //水平垂直居中
            display: flex;
            justify-content: center;
            align-items: center;
        }
    }

    .dhc-proTable-editCell {
        width: calc(99.9% + 20px);
        margin-left: -20px;
    }

    .renderCol>.cell {
        text-overflow: clip;
    }

    //显示不完就换行显示
    .wrapDisplay {
        white-space: pre-wrap;
        word-break: break-word;
    }
}
</style>
