"use strict";
import { util } from '../../../../util/util.js'
import { khcAlert } from '../../../alert/khcAlert.js'
import { tableButtons } from './tableButtons.js'
import { khcModal } from '../../../alert/khcModal.js'
import { form } from '../../form/form.js';
import { fullMap } from '../../../../fullMap.js';
import {pageInfoMap} from "../../../../pageInfoMap.js";
import {config} from "../../../../config.js";
import {khcToastr} from "../../../alert/khcToastr.js";
import {httpUtil} from "../../../../util/httpUtil.js";
import PhotoSwipeLightbox from "../../../../../../css/vendor/libs/photoswipe/photoswipe-lightbox.esm.js";
import {khcPhoto} from "../../../alert/khcPhoto.js";
import {tableUtil} from "./tableUtil.js";
import {khcModalSlide} from "../../../alert/khcModalSlide.js";
import {rowButtons} from "./rowButtons.js";
class table {
    constructor(data) {
        this.eleID = util.getUUID();//table的domid
        this._objID = this.eleID + 'div';//本组件的根Div的domid
        this.tableStructureData;//表结构信息
        this.pkFieldName;//数据的主键字段
        this.dictMap = new Map();//字典的map，key是字段名，object是字典的map，objectMap的key和value才是字典key和value
        this.showTypeMap = new Map();//表单展示类型
        this.dataMap = new Map();//当前表的数据，key是主键字段的值，object是content
        this.tableMinWidth = 0;//表格最小宽度，单位是px，在init时计算出来
        this.parentDomID = data.parentObjID//上级组件的domid，另外可以通过fullmap获取上级组件对象
        this.queryMap = data.queryMap;//获取查询条件的所有对象，在这个map里，遍历可获取查询条件的值
        this.queryObjID = data.queryObjID;
        //表格的三种状态
        this.page = 0;//默认当前页面
        this.pageSizeArray=[10,20,50,100];//可更换的页数
        this.allPages = 0;//总页面数
        this.contents = [];//查询的业务数据集
        this.code = data.code;//元数据的元数据，用于获取组件信息
        this.haveTree = data.haveTree;
        this.treeView = data.treeView;
        this.listLoadRenderFieldArray=[];//列表是否加载渲染
        this.columnDictCode=null;//是否列表展示字典
        this.queryInfo=data.queryInfo;
        this.autoRefreshFunc=null; // 用于存储定时器函数
        this.toggleTree = false; //左侧树
    }
    getObjID(){
        return this._objID;
    }
    getRowButtonArray(){
        return this.queryInfo.rowButtonArray;
    }
    getTableButtonArray(){
        return this.queryInfo.tableButtonArray;
    }
    
    //获取查询条件的值，其实应该是私有方法
    getQueryParam(queryCode) {
        let that=this;
        let queryParam= {};
        for (let item of that.queryMap) {

            if (item[0] != 'buttons') {
                queryParam[item[0]] = item[1].getValue();
            }
        }
        if(that.queryInfo.is_show_query=='N'&&that.queryInfo.is_show_table_search=='Y'){//table搜索框
            let tableSearchInput=document.getElementById(that.eleID+'tableSearchInput')
            if(tableSearchInput!=null){
                queryParam['tableSearchValue']=tableSearchInput.value;
                queryParam['tableSearchField']=document.getElementById(that.eleID+'tableSearchField').value;
            }
        }
        let cloneUrlQueryParam=pageInfoMap.getObj(queryCode);
        if(!util.isNull(cloneUrlQueryParam)){
            cloneUrlQueryParam=util.clone(cloneUrlQueryParam);
            queryParam=util.mergeObject(queryParam,cloneUrlQueryParam)
        }
        return queryParam;
    }
    //获取选中的数据UUID
    getCheckedDataUUID() {
        let that=this;
        let uuids = ''
        let checkBoxArray = document.getElementById(this.eleID).querySelectorAll('input[name="idcheck"]')
        for (let checkbox of checkBoxArray) {
            if (checkbox.checked == true) {
                if(!util.isNull(uuids))uuids+=','
                uuids+=that.dataMap.get(checkbox.getAttribute('value'))['uuid']
            }
        }
        return uuids;
    }
    //获取选中的数据
    getCheckedDataPkCode() {
        let ids = []
        let checkBoxArray = document.getElementById(this.eleID).querySelectorAll('input[name="idcheck"]')
        for (let checkbox of checkBoxArray) {
            if (checkbox.checked == true) {
                let idObj = { pkId: checkbox.getAttribute('value') }
                ids.push(idObj);
            }
        }
        return ids;
    }
    //获取选中的数据
    getCheckedDataAll() {
        let that=this;
        let dataArr = []
        let checkBoxArray = document.getElementById(this.eleID).querySelectorAll('input[name="idcheck"]')
        for (let checkbox of checkBoxArray) {
            if (checkbox.checked == true) {
                dataArr.push(that.dataMap.get(checkbox.getAttribute('value')))
            }
        }
        return dataArr;
    }
    //获取选中的自定义字段名拼接
    getCheckedDataByFieldName(fieldName) {
        let that=this;
        let strValues = ''
        let checkBoxArray = document.getElementById(this.eleID).querySelectorAll('input[name="idcheck"]')
        for (let checkbox of checkBoxArray) {
            if (checkbox.checked == true) {
                if(!util.isNull(strValues))strValues+=','
                strValues+=that.dataMap.get(checkbox.getAttribute('value'))[fieldName]
            }
        }
        return strValues;
    }
    //输出当前页面的表格数据，为外部调用修改使用
    getContentMap() {
        return this.dataMap;
    }
    getEleID() {
        return this.eleID;
    }
    //初始化
    init() {
        let code = this.code;
        let that = this;
        let pageComponent=fullMap.getObj(fullMap.getObj(that.queryObjID).pageID);
        that.pageComponent=pageComponent;
        let obj={url:config.getConfigJson().metaUrl,params:code,isClientCache:true}
        return httpUtil.post(obj, (response)=>{
            //主键
            that.pkFieldName = response.data.data.ds.ds_pk_id;
            that.queryInfo = response.data.data.query.queryInfo;
            //表结构数据
            that.tableStructureData = response.data.data.query.queryData;
            if (that.queryInfo.is_checkbox == 'Y') {
                that.tableMinWidth += 30+42;
            }
            if (that.queryInfo.is_managing=='Y') {
                that.tableMinWidth += 150+42;
            }
            for (let i = 0; i < that.tableStructureData.length; i++) {
                let tdData = that.tableStructureData[i].data;
                if (tdData.is_list == 'Y') {
                    that.tableMinWidth += tdData.width+42;
                }
            }
        });
    }
    initFunc(){
        let that = this;
        //鼠标悬浮行更改颜色背景
        that.trMouseoverFunc= function (){
            let tr=this;
            if(that.contents.length==0){
                return ;
            }
            this.classList.remove(config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutEvenBackgroundColor)
            this.classList.remove(config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutOddBackgroundColor)
            this.classList.add(config.getConfigJson().defaultTableColorClassJson.tableTdMouseoverBackgroundColor);
            if(that.queryInfo.is_managing == 'Y'&&that.pageComponent.isReadOnly!='Y'){
                tr.querySelector('td[to="buttons"]').classList.remove(config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutEvenBackgroundColor);
                tr.querySelector('td[to="buttons"]').classList.remove(config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutOddBackgroundColor);
                tr.querySelector('td[to="buttons"]').classList.add(config.getConfigJson().defaultTableColorClassJson.tableTdMouseoverBackgroundColor);
            }
            if(that.queryInfo.is_checkbox == 'Y'&&that.pageComponent.isReadOnly!='Y'){
                tr.querySelector('td[to="checkbox"]').classList.remove(config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutEvenBackgroundColor);
                tr.querySelector('td[to="checkbox"]').classList.remove(config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutOddBackgroundColor);
                tr.querySelector('td[to="checkbox"]').classList.add(config.getConfigJson().defaultTableColorClassJson.tableTdMouseoverBackgroundColor);
            }
        }
        //鼠标移出删除颜色背景
        that.trMouseoutFunc= function (){
            let tr=this;
            // 获取 tr 元素的索引（从 0 开始）
            let index = Array.from(tr.parentElement.children).indexOf(tr);
            // 判断奇偶行
            let addColorClass, removeColorClass;
            if (index % 2 === 0) {//偶数行
                addColorClass=config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutEvenBackgroundColor;
                removeColorClass=config.getConfigJson().defaultTableColorClassJson.tableTdMouseoverBackgroundColor;
            } else {//奇数行
                addColorClass=config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutOddBackgroundColor;
                removeColorClass=config.getConfigJson().defaultTableColorClassJson.tableTdMouseoverBackgroundColor;
            }
            if(that.contents.length==0)return ;
            let pkCode = tr.getAttribute("pkcode");
            tr.classList.remove(removeColorClass)
            let thisTrData=that.dataMap.get(pkCode);
            let rowColorJson=that.tUtil._getRowColorJson(thisTrData,addColorClass)
            let tdColor=rowColorJson['tdColor'];
            addColorClass=rowColorJson['tdColorClass'];
            if(that.queryInfo.is_managing == 'Y'&&that.pageComponent.isReadOnly!='Y')tr.querySelector('td[to="buttons"]').classList.remove(removeColorClass);
            if(that.queryInfo.is_checkbox == 'Y'&&that.pageComponent.isReadOnly!='Y')tr.querySelector('td[to="checkbox"]').classList.remove(removeColorClass);
            if(!util.isNull(tdColor)){
                tr.setAttribute("style", 'background-color:'+tdColor);
                if(that.queryInfo.is_managing == 'Y'&&that.pageComponent.isReadOnly!='Y')tr.querySelector('td[to="buttons"]').style.backgroundColor=tdColor;
                if(that.queryInfo.is_checkbox == 'Y'&&that.pageComponent.isReadOnly!='Y')tr.querySelector('td[to="checkbox"]').style.backgroundColor=tdColor;
            }else{
                tr.classList.add(addColorClass)
                if(that.queryInfo.is_managing == 'Y'&&that.pageComponent.isReadOnly!='Y')tr.querySelector('td[to="buttons"]').classList.add(addColorClass);
                if(that.queryInfo.is_checkbox == 'Y'&&that.pageComponent.isReadOnly!='Y')tr.querySelector('td[to="checkbox"]').classList.add(addColorClass);
            }
        }
        //增加鼠标移开行更改会默认颜色背景
        that.tableBodyWithChangeBackgroundColorFunc= ()=>{
            if(that.queryInfo.render_list_type=='render_card'){
                return '';
            }
            let tbodyObj = document.getElementById(that.eleID).querySelector('tbody');
            let trArray = tbodyObj.children;
            for (let trObjNum of trArray) {
                util.addEventListener(trObjNum,'mouseover',that.trMouseoverFunc)
                util.addEventListener(trObjNum,'mouseout',that.trMouseoutFunc)
            }
        }
        //给标题元素增加点击事件
        that.thClickFunc= function (){
            let th=this;
            let fieldName = th.getAttribute('fieldName')
            let sort = '';
            //判断当前为升序还是降序
            if (th.classList.contains('sorting_desc')) {
                sort = ' asc '
                th.classList.remove('sorting_desc')
                th.classList.add('sorting_asc')
            } else {
                sort = ' desc '
                th.classList.remove('sorting_asc')
                th.classList.add('sorting_desc')
            }
            that.queryInfo.sort_field = fieldName;
            that.queryInfo.sort_type = sort;
            that.refresh();
        }
        //点击表头排序时间
        that.thBySortFunc= ()=>{
            if(that.queryInfo.render_list_type=='render_card'){
                return '';
            }
            //获取表格组件中的th元素数组
            let thObjs = document.getElementById(that.eleID).querySelector('thead').querySelector('tr').querySelectorAll('th');
            for (let thObjNum of thObjs) {
                //如果th元素有class属性，则该字段为配置了可排序的字段
                if (thObjNum.classList.contains('sorting')||thObjNum.classList.contains('sorting_desc')||thObjNum.classList.contains('sorting_asc')) {
                    //给该元素增加点击事件
                    util.addEventListener(thObjNum,'click',that.thClickFunc)
                }
            }
        }
        that.toPageNumFunc= function (){
            let toPageNumThat=this;
            let tartPageNum = toPageNumThat.innerText
            let khcName = toPageNumThat.getAttribute('khcname');
            //前端显示的第一页是1，但是后台page的参数是0，所以以下代码
            if (khcName == 'Next') {
                that.page = that.page+1;
            } else if (khcName == 'Previous') {
                that.page = that.page-1;
            }else{//点击某一页
                that.page = Number(tartPageNum) - 1
            }
            if(that.page>=that.allPages){
                that.page=that.allPages-1
            }
            if(that.page<0){
                that.page=0
            }
            that.refresh();

        }
        //翻页事件
        that.pageDownFunc= function (){
            let eleID = that.eleID;
            //获取表格组件中的th元素数组
            let thObj=document.getElementById(eleID + 'pageInfoWithPage').querySelector('ul');
            if(thObj==null){
                return ;
            }
            let pageNumObjs = document.getElementById(eleID + 'pageInfoWithPage').querySelector('ul').querySelectorAll('li');
            let nowPageNum = that.page+1;
            let allPageNum = document.getElementById(eleID + 'pageInfoOfSize').querySelector('ccccc').innerText;
            for (let pageObjNum of pageNumObjs) {
                let tartPageNum = pageObjNum.innerText
                let khcName = pageObjNum.getAttribute('khcname');
                //是否增加点击事件
                let isAdd = true;
                if (nowPageNum == 1 && tartPageNum == 'Previous') {
                    isAdd = false;//第一页上翻不加事件
                }
                if (nowPageNum == allPageNum && tartPageNum == 'Next') {
                    isAdd = false;//最后一页下翻不加事件
                }
                if (isAdd) {
                    util.addEventListener(pageObjNum,'click',that.toPageNumFunc);
                }
            }
        }
        //跳转到指定页面
        that.toPageButtonFunc= ()=>{
            let tableObjID = that.getObjID();
            let toPageInputObj = document.getElementById(tableObjID + 'toPageInput');
            that.page = toPageInputObj.value-1;
            if(that.page>=that.allPages){
                that.page=that.allPages-1
            }
            that.refresh();
        }
        //更改单页面默认显示数据
        that.changePageSizeFunc= ()=>{
            //删除绑定的事件太难了，暂时方案为，给对象增加事件之后，打个属性标记，如果有该标记了，就不再重新绑定
            //切记切记，绑定事件是可以重复绑定，且会重复生效，重复执行
            //todo 额，将事件写到变量即可解决重复绑定事件
            let tableObjID = that.getObjID();
            let changePageSizeObj = document.getElementById(tableObjID + 'changePageSize');
            if(that.pageSizeArray.includes(Number(changePageSizeObj.value))){
                that.queryInfo.page_size = changePageSizeObj.value;
                that.page = 0;
                that.pageSize = Number(changePageSizeObj.value);
                that.refresh();
            }else{//该分页和配置的不一致，可能是后端重写buildSql造成的，这里提示page修改无效即可
                khcToastr.showErrorMessage('当前数据源修改页数无效');
            }
        }
        //双击行显示详情
        that.showDetailByTrWithDblClickFunc= ()=> {
            if(that.queryInfo.is_dblclick!='Y'){
                return ;
            }
            let trObjArray = document.getElementById(that.eleID).querySelector('tbody').querySelectorAll('tr');
            for (let trObj of trObjArray) {
                let tdArray = trObj.querySelectorAll('td');
                let tr = trObj;
                for (let tdObj of tdArray) {
                    if (tdObj.getAttribute('to') != 'buttons' && tdObj.getAttribute('to') != 'checkbox') {
                        tdObj.addEventListener('dblclick',  ()=> {
                            that.showDetail(tr.getAttribute('pkCode'));//tr是函数外的变量，暂时先不写成函数放变量了
                        });
                    }
                }

            }
        }
        //表头的check事件，点击全选，再点全部取消
        that.checkBoxSelectRowFunc= function (){
            let checkBoxArray = document.getElementById(that.eleID).querySelectorAll('input[name="idcheck"]')
            if (this.checked == true) {
                for (let checkbox of checkBoxArray) {
                    checkbox.checked = true;
                }
            } else {
                for (let checkbox of checkBoxArray) {
                    checkbox.checked = false;
                }
            }
        }
        //单行在非按钮和checkbox点击可以选中同一行的checkbox
        that.checkBoxSelectRowByTrFunc= ()=>{
            if(that.contents.length==0){
                return ;
            }
            let trObjArray = document.getElementById(that.eleID).querySelector('tbody').querySelectorAll('tr');
            for (let trObj of trObjArray) {
                let tdArray = trObj.querySelectorAll('td');
                let tr = trObj;
                for (let tdObj of tdArray) {
                    //每行除checkbox和button列其余都添加点击事件就选中和刷新checkbox
                    if (tdObj.getAttribute('to') != 'buttons') {
                        if(that.queryInfo.is_edit_table == 'Y'&&tdObj.getAttribute('to') != 'checkbox'){
                            continue ;//列表编辑只能通过点击checkbox选中
                        }
                        tdObj.addEventListener('click',  function (){
                            let checkbox = tr.querySelector('input[name="idcheck"]')
                            if (checkbox.checked == true) {
                                checkbox.checked = false;
                            } else {
                                checkbox.checked = true;
                            }
                            that.refreshCheckBoxSelectFunc();
                        });
                        if(tdObj.getAttribute('to') == 'checkbox'){
                            tdObj.querySelector('input').addEventListener('change',function (){
                                let checkbox = tr.querySelector('input[name="idcheck"]')
                                if (checkbox.checked == true) {
                                    checkbox.checked = false;
                                } else {
                                    checkbox.checked = true;
                                }
                                that.refreshCheckBoxSelectFunc();
                            })
                        }
                    }
                }
            }
        }
        //刷新表头的checkbox 如果点击完是全选了，则这个也选中，如果已经全选，取消了一个，则是不选中
        that.refreshCheckBoxSelectFunc= ()=>{
            let checkBoxArray = document.getElementById(that.eleID).querySelectorAll('input[name="idcheck"]')
            let isAllChecked=true;
            for (let checkbox of checkBoxArray) {
                if(checkbox.checked!=true){
                    isAllChecked=false;
                    break;
                }
            }
            let checkInputObj=document.getElementById(that.eleID).querySelector('input[khcattr]');
            if (isAllChecked) {
                checkInputObj.checked=checkInputObj;
            } else {
                checkInputObj.checked=false;
            }
        }
        //对表单字段类型为image添加查看原图事件
        that.imagePhotoSwipeLightboxFunc= ()=>{
            if(that.isImageFiled){
                let tableStructureData = that.tableStructureData;
                let contents = that.contents;
                for (let i = 0; i < contents.length; i++) {
                    //获取单条数据
                    let content = contents[i];
                    for (let j = 0; j < tableStructureData.length; j++) {
                        let tdData = tableStructureData[j].data;
                        if (tdData.is_list == 'Y') {
                            if (tdData.show_type == 'image'){
                                let imageId='#'+tdData.name+'-'+content[that.pkFieldName]+'photoswipe-example-query';
                                khcPhoto.init({gallery:imageId});
                            }
                        }
                    }
                }
            }
        }
        //列表编辑时对表单字段类型为file添加上传file事件
        that.editTableFileUploadFunc= ()=>{
            if(that.isListAndIsFileFiled){
                let tableStructureData = that.tableStructureData;
                let contents = that.contents;
                for (let i = 0; i < contents.length; i++) {
                    //获取单条数据
                    let content = contents[i];
                    for (let j = 0; j < tableStructureData.length; j++) {
                        let tdData = tableStructureData[j].data;
                        if (tdData.is_list == 'Y'&&tdData.show_type == 'file') {
                            let tr = document.getElementById(that.getEleID()).querySelector('tbody').querySelector('tr[pkCode="' + content[that.pkFieldName] + '"]');
                            let fileId=tdData.name+'-'+content[that.pkFieldName]
                            let showMaxUploadMessage=function (fileArray){
                                if(fileArray.length>=tdData.file_image_max_num){
                                    tr.querySelector('label[name="' + tdData.name + 'label"]').style.display='none'
                                }else{
                                    tr.querySelector('label[name="' + tdData.name + 'label"]').style.display=''
                                }
                            }
                            let showFileList=function (fileArray){
                                tr.querySelector('div[name="' + tdData.name + 'list"]').innerHTML='';
                                for (let i = 0; i < fileArray.length; i++) {
                                    let fileInfo = fileArray[i];
                                    let showFileName=fileInfo.realFileName;
                                    let showLength=25;
                                    if(showFileName.length>showLength){//文件长度大于25时省略中间内容
                                        showFileName=showFileName.substring(0,10)+'...'+showFileName.substring(showFileName.length-15,showFileName.length)
                                    }
                                    let fileUrl=util.getFileUrl(fileInfo);
                                    let openUrl='';
                                    //这里由于minio和service存储的suffix有区别需要判断两个一个带点一个不带
                                    let suffix=fileInfo['suffix'];
                                    let paramsFileUrl=encodeURIComponent(fileUrl);
                                    // 使用btoa进行Base64编码
                                    paramsFileUrl = btoa(paramsFileUrl);
                                    //let paramsFileUrl=encodeURIComponent(fileUrl);
                                    if(suffix=='docx'||suffix=='.docx'){
                                        openUrl='../preview/docxjs/index.html?file='+paramsFileUrl;
                                    }
                                    if((suffix=='xls'||suffix=='xlsx')||(suffix=='.xls'||suffix=='.xlsx')){
                                        openUrl='../preview/sheetjs/index.html?file='+paramsFileUrl;
                                    }
                                    if(suffix=='pdf'||suffix=='.pdf'){
                                        openUrl='../preview/pdfjs/web/viewer.html?file='+paramsFileUrl;
                                    }
                                    if((suffix=='jpg'||suffix=='jpeg'||suffix=='png')||(suffix=='.jpg'||suffix=='.jpeg'||suffix=='.png')){
                                        openUrl='../preview/photoswipe/index.html?file='+paramsFileUrl;
                                    }
                                    let previewHtml='';
                                    if(openUrl!=''){
                                        if((suffix=='xls'||suffix=='xlsx')||(suffix=='.xls'||suffix=='.xlsx')){
                                            previewHtml=`<a class="dropdown-item" href='javascript:window.open("${openUrl}");'>预览</a>`;
                                        }else{
                                            previewHtml=`<a class="dropdown-item" href='javascript:window.open("${openUrl}","title","menubar=0,scrollbars=1,resizable=1,status=1,titlebar=0,toolbar=0,location=1");'>预览</a>`;
                                        }
                                    }
                                    let html = `
            <div class="col-sm-12 row divRow" style="padding-right: .0rem !important;padding-left: .0rem !important;"><div class="col-sm-9" style="bottom: 3px;">
            <a href="javascript:void(0)" title="${fileInfo.realFileName}" data-toggle="dropdown" aria-expanded="false">
                ${showFileName}
             </a>
             <div class="dropdown-menu" x-placement="top-start" style="position: absolute; top: -177px; left: 0px; will-change: top, left;">
                ${previewHtml}
                <a download="${fileInfo.source=='minio'?`${fileInfo.realFileName}`:''}" class="dropdown-item"
                                 href="${fileUrl}" title="${fileInfo.realFileName}">下载</a>
            </div>
            </div>
            <div class="col-sm-3" id="${fileInfo.diskFileName}" style="text-align: right;">`
                                    if (that.queryInfo.is_edit_table == 'Y'
                                        &&that.pageComponent.isReadOnly!='Y'
                                        &&(util.isNull(tdData.is_edit_table)||tdData.is_edit_table=='Y')) {
                                        html += '<span style="cursor:pointer;">删除</span>'
                                    }
                                    html += '</div></div>'
                                    tr.querySelector('div[name="' + tdData.name + 'list"]').insertAdjacentHTML("beforeEnd", html);
                                    let removeFileFunc= ()=> {
                                        let fileDiskName = document.getElementById(fileInfo.diskFileName).getAttribute('id');
                                        fileArray = fileArray.filter( (item) =>{
                                            return item.diskFileName != fileDiskName;
                                        });
                                        tr.querySelector('input[name="' + tdData.name + '"]').value=JSON.stringify(fileArray)
                                        showMaxUploadMessage(fileArray)
                                        //因为调用的事件是change，导致如果同一个文件上传两次时第二次不触发change事件，所以上传完成后清空file tag的值
                                        document.getElementById(fileId).value = '';
                                        showFileList(fileArray);
                                    }
                                    util.addEventListener(fileInfo.diskFileName,'click',removeFileFunc)
                                }
                            }
                            if(tdData.uploadFileFunc==null){
                                tdData.uploadFileFunc=function (){
                                    let fileList = document.getElementById(fileId).files;
                                    let file = fileList[0];
                                    let params = new FormData();
                                    params.append("uploadFile", file, file.name);
                                    if(tdData.upload_file_to_type==undefined){
                                        tdData.upload_file_to_type='minio';
                                    }
                                    params.append("upload_file_to_type",tdData.upload_file_to_type);
                                    const selfConfig = {
                                        headers: {
                                            "Content-Type": "multipart/form-data;boundary=" + new Date().getTime(),
                                            Authorization:'Bearer '+config.getToken()}
                                    };
                                    let obj={url:config.getConfigJson().upFileUrl,params:params,config:selfConfig}
                                    fullMap.getObj('mask').show('正在上传...')
                                    httpUtil.post(obj, (response)=>{
                                        let newValue=tr.querySelector('input[name="' + tdData.name + '"]').value
                                        let fileArray=[]
                                        if(!util.isNull(newValue)){
                                            fileArray=JSON.parse(newValue)
                                        }
                                        let fileInfo = response.data.data.fileInfo;
                                        fileArray.push(fileInfo);
                                        tr.querySelector('input[name="' + tdData.name + '"]').value=JSON.stringify(fileArray)
                                        fullMap.getObj('mask').hide();
                                        showFileList(fileArray);
                                        showMaxUploadMessage(fileArray);
                                    })
                                    //因为调用的事件是change，导致如果同一个文件上传两次时第二次不触发change事件，所以上传完成后清空file tag的值
                                    document.getElementById(fileId).value = '';
                                }
                            }
                            let fileArray=[]
                            if(!util.isNull(content[tdData.name])){
                                fileArray=JSON.parse(content[tdData.name])
                            }
                            showFileList(fileArray)
                            showMaxUploadMessage(fileArray)
                            tr.querySelector('input[name="' + tdData.name + '"]').value=JSON.stringify(fileArray)
                            util.addEventListener(fileId,'change',tdData.uploadFileFunc)
                        }
                    }
                }
            }
        }
        that.editTableSaveRowDataFunc= ()=>{
            let tableStructureData = that.tableStructureData;
            let contents = that.contents;
            for (let i = 0; i < contents.length; i++) {
                //获取单条数据
                let content = contents[i];
                for (let j = 0; j < tableStructureData.length; j++) {
                    let tdData = tableStructureData[j].data;
                    if(tdData.is_list == 'Y'&&tdData.list_load_is_render=='Y'){
                        if (that.queryInfo.is_edit_table == 'Y'
                            &&that.pageComponent.isReadOnly!='Y'
                            &&(util.isNull(tdData.is_edit_table)||tdData.is_edit_table=='Y')) {
                            let tr = document.getElementById(that.getEleID()).querySelector('tbody').querySelector('tr[pkCode="' + content[that.pkFieldName] + '"]');
                            if(tdData.show_type=='text'){//文本需要手动点击按钮保存
                                let saveButton=tr.querySelector('button[name="' + tdData.name + 'SaveButton"]')
                                if(saveButton!=null){
                                    let eleObj = tr.querySelector('input[name="' + tdData.name + '"]');
                                    util.addEventListener(saveButton,'click',function (){
                                        let newValue=eleObj.value;
                                        if(content[tdData.name]==newValue){
                                            khcToastr.showWarningMessage('您没有更改数据，不做处理')
                                            return ;
                                        }
                                        content[tdData.name]=newValue;
                                        that.saveRowData(that.queryObjID,content)
                                    })
                                }
                            }
                            if(tdData.show_type=='select'){//下拉框自动保存
                                let eleObj = tr.querySelector('select[name="' + tdData.name + '"]');
                                util.addEventListener(eleObj,'change',function (){
                                    let newValue=eleObj.value;
                                    content[tdData.name]=newValue;
                                    that.saveRowData(that.queryObjID,content)
                                })
                            }
                            if(tdData.show_type=='switch'){//开关控件自动保存
                                let eleObj = tr.querySelector('input[name="' + tdData.name + content[that.pkFieldName] + '"]');
                                util.addEventListener(eleObj,'click',function (){
                                    let newValue='';
                                    if (eleObj.checked == true) {
                                        newValue = tdData['switch_yes_key'];
                                    }else{
                                        newValue = tdData['switch_no_key'];
                                    }
                                    content[tdData.name]=newValue;
                                    that.saveRowData(that.queryObjID,content)
                                })
                            }
                        }
                    }
                }
            }
        }
        that.saveRowData=(objID,content)=> {
            fullMap.getObj('mask').show(`更新中...`)
            let queryViewComponent = fullMap.getObj(objID);
            let tableViewComponent = queryViewComponent.getTableObj();
            let componentArray = fullMap.getObj(queryViewComponent.pageID).componentArray;
            let params = tableViewComponent.code;
            for (let i = 0; i < componentArray.length; i++) {
                if (componentArray[i].type == 'form') {
                    params = componentArray[i].code;
                }
            }
            params=util.clone(params);
            params['saveData'] = [content]
            let obj={url:config.getConfigJson().saveUrl,params:params}
            return httpUtil.post(obj, (response)=>{
                fullMap.getObj('mask').hide(100);
                setTimeout(function (){
                    khcToastr.showSuccessMessage('更新成功')
                },200)
            })


        }
        that.initTableSearchFunc=()=>{
            //使用util.addEventListener绑定事件，会在绑定之前先remove之前的事件，防止重复绑定
            util.addEventListener(that.eleID+'tableSearchButton','click',that.tableSearchButtonClickFunc);
            util.addEventListener(that.eleID+'tableSearchInput','focus',()=>{
                util.addEventListener(document.body,'keyup',that.tableSearchKeyupFunc);
            });
            util.addEventListener(that.eleID+'tableSearchInput','blur',()=>{
                util.removeEventListener(document.body,'keyup',that.tableSearchKeyupFunc);
            });
            let tableSearchButtonEle=document.getElementById(that.eleID+'tableSearchButton')
            Ladda.bind( tableSearchButtonEle, { timeout: 1000 } );//按钮loading动画效果
        }
        that.tableSearchButtonClickFunc=()=>{
            fullMap.getObj(that.queryObjID).search();
        }
        that.tableSearchKeyupFunc=(e)=>{
            if(e.keyCode==13){
                fullMap.getObj(that.queryObjID).search();
                document.getElementById(that.eleID+'tableSearchInput').blur();
            }
        }
    }
    //从服务器获取业务数据
    //todo 此处应该设置条件，根据条件判断是从服务器获取数据，还是被推过来了直接的json数据
    getContentsFromServer() {
        let that=this;
        let params = that.code;
        params['queryParam'] = that.getQueryParam(params.queryCode);
        params.queryParam.page = that.page;
        params.queryParam.pageSize = that.queryInfo.page_size;
        params.queryParam.sortField = that.queryInfo.sort_field;
        params.queryParam.sortType = that.queryInfo.sort_type;
        if(that.selectTableDataArray!=undefined&&that.selectTableDataArray.length>0){
            params.queryParam.selectTableDataArray=that.getSelectTableDataStr();
        }
        if(that.queryIds!=undefined&&that.queryIds.length>0){
            params.queryParam.queryIds=that.queryIds;
        }
        let obj={url:config.getConfigJson().queryUrl,params:params}
        return httpUtil.post(obj, (response)=>{
            //查询结果
            that.contents = response.data.data.content;
            that.selectContents = response.data.data.selectContent;
            //分页信息
            that.page = response.data.data.number;
            that.queryInfo.page_size = response.data.data.size;
            that.allItemNum = response.data.data.totalElements;
            that.allPages = response.data.data.totalPages;
        })
    }
    getTableHeaderHtml() {
        let that=this;
        let thColor=config.getConfigJson().defaultTableColorJson.tableThBackgroundColor;
        let tableManagingName=config.getConfigJson().tableManagingName;
        tableManagingName=`${that.queryInfo['table_managing_name']?that.queryInfo['table_managing_name']:tableManagingName}`
        let tableStructureData = that.tableStructureData;
        //生成表头信息
        let tableHeadHtml = ' <tr role="row">';
        if ((!util.isNull(that.queryInfo.is_checkbox) && that.queryInfo.is_checkbox == 'Y')&&that.pageComponent.isReadOnly!='Y') {
            tableHeadHtml += `<th width="30" style="position: sticky;left: 0;top:-1px;z-index: 1001;text-align:center;background-color: ${thColor}"><input  type="checkbox" khcattr="${that.eleID}checkcol" name="${that.eleID}checkcol"></th>`;
        }
        if (!util.isNull(that.queryInfo.is_managing)
            && that.queryInfo.is_managing == 'Y'
            &&(util.isNull(that.queryInfo.managing_show_type)||that.queryInfo.managing_show_type=='first_show')
            &&that.pageComponent.isReadOnly!='Y') {
            // 公式是：按钮数量*按钮长度+默认列长度
            let managerThWidth=that.queryInfo.rowButtonArray.length*Number(that.queryInfo.managing_button_length)+Number(that.queryInfo.managing_length)
            tableHeadHtml += `<th width="${managerThWidth}" class="${config.getConfigJson().defaultTableColorClassJson.tableThBackgroundColor}"
            style="text-align:center;position: sticky;left: ${that.queryInfo.is_checkbox=='Y'?'55px':'0'};top:-1px;z-index: 1000;">${tableManagingName}</th>`;
        }
        if (!util.isNull(that.queryInfo['is_show_table_number']) && that.queryInfo['is_show_table_number'] == 'Y') {
            tableHeadHtml += `<th width="30" class="${config.getConfigJson().defaultTableColorClassJson.tableThBackgroundColor}" style="text-align:center;position: sticky;top:-1px;z-index: 999;">序号</th>`;
        }
        let dict_code=[]
        that.listLoadRenderFieldArray=[];//每次渲染都重置
        for (let i = 0; i < tableStructureData.length; i++) {
            let tdData = tableStructureData[i].data;
            //将每个字段的字典数据装入map（字段名为key）
            let dictCode = tdData.dict_code.toString();
            if (!util.isNull(dictCode)) {
                let dictBodyMap = new Map();
                for (let j = 0; j < tdData.dict_code.data.length; j++) {
                    if (['multiPicker','tree','treeCheckBox'].includes(tdData.show_type)) {
                        dictBodyMap.set(tdData.dict_code.data[j].id.toString(), tdData.dict_code.data[j].name)
                    } else {
                        dictBodyMap.set(tdData.dict_code.data[j].key, tdData.dict_code.data[j].value)
                    }
                }
                that.dictMap.set(tdData.name, dictBodyMap);
            }
            if (tdData.is_list == 'Y') {
                dict_code.push({value:tdData.label_name,key:tdData.name})
                if(tdData.list_load_is_render=='Y'){
                    that.listLoadRenderFieldArray.push(tdData.name)
                    tableHeadHtml += `<th width="${tdData.width}" 
                    style="text-align:center;position: sticky;top:-1px;z-index: 999;" 
                    fieldName="${tdData.name}"`;
                    tableHeadHtml+=` class="${config.getConfigJson().defaultTableColorClassJson.tableThBackgroundColor}`
                    if (tdData.is_sort == 'Y') {//是否排序字段
                        if(util.isNull(that.queryInfo.sort_field)){
                            that.queryInfo.sort_field=that.queryInfo.default_sort_field
                        }
                        if (tdData.name == that.queryInfo.sort_field) {
                            if(util.isNull(that.queryInfo.sort_type)){
                                that.queryInfo.sort_type=that.queryInfo.default_sort_type
                            }
                            tableHeadHtml += ' sorting_' + that.queryInfo.sort_type.trim() + '';
                        } else if (tdData.is_sort == 'Y') {
                            tableHeadHtml += ' sorting '
                        }
                    }
                    tableHeadHtml += ' " '
                    let tooltipHtml=``;
                    if(tdData['is_list_header_question_circle']=='Y'){
                        tooltipHtml=`<i class="far fa-question-circle" style="font-size: 15px;cursor:pointer;" 
                                    data-toggle="tooltip" data-placement="top" title="" data-original-title="${tdData['list_header_question_circle_text']}"></i>`;
                    }
                    tableHeadHtml += '>' + tdData.label_name + tooltipHtml +'</th>'
                }
            }
        }
        that.columnDictCode={data:dict_code}
        if (!util.isNull(that.queryInfo.is_managing)
            && that.queryInfo.is_managing == 'Y'
            &&that.queryInfo.managing_show_type=='last_show'
            &&that.pageComponent.isReadOnly!='Y') {
            // 公式是：按钮数量*按钮长度+默认列长度
            let managerThWidth=that.queryInfo.rowButtonArray.length*Number(that.queryInfo.managing_button_length)+Number(that.queryInfo.managing_length)
            tableHeadHtml += `<th width="${managerThWidth}" class="${config.getConfigJson().defaultTableColorClassJson.tableThBackgroundColor}"
            style="text-align:center;position: sticky;left: 0;top:-1px;right:0px;z-index: 1000;">${tableManagingName}</th>`;
        }
        tableHeadHtml += '</tr>'
        return tableHeadHtml;
    }
    getSelectTableHeaderHtml() {
        let that=this;
        let thColor=config.getConfigJson().defaultTableColorJson.tableThBackgroundColor;
        let tableManagingName=config.getConfigJson().tableManagingName;
        tableManagingName=`${that.queryInfo['table_managing_name']?that.queryInfo['table_managing_name']:tableManagingName}`
        let tableStructureData = that.tableStructureData;
        //生成表头信息
        let tableHeadHtml = ' <tr role="row">';
        if (!util.isNull(that.queryInfo.is_managing)
            && that.queryInfo.is_managing == 'Y'
            &&(util.isNull(that.queryInfo.managing_show_type)||that.queryInfo.managing_show_type=='first_show')
            &&that.pageComponent.isReadOnly!='Y') {
            // 公式是：按钮数量*按钮长度+默认列长度
            let managerThWidth=that.queryInfo.rowButtonArray.length*Number(that.queryInfo.managing_button_length)+Number(that.queryInfo.managing_length)
            tableHeadHtml += `<th width="${managerThWidth}" 
            style="text-align:center;position: sticky;left: ${that.queryInfo.is_checkbox == 'Y'?'55px':'0'};top:-1px;z-index: 1000;background-color: ${thColor}">${tableManagingName}</th>`;
        }
        let dict_code=[]
        that.listLoadRenderFieldArray=[];//每次渲染都重置
        for (let i = 0; i < tableStructureData.length; i++) {
            let tdData = tableStructureData[i].data;
            //将每个字段的字典数据装入map（字段名为key）
            let dictCode = tdData.dict_code.toString();
            if (!util.isNull(dictCode)) {
                let dictBodyMap = new Map();
                for (let j = 0; j < tdData.dict_code.data.length; j++) {
                    if (['multiPicker','tree','treeCheckBox'].includes(tdData.show_type)) {
                        dictBodyMap.set(tdData.dict_code.data[j].id.toString(), tdData.dict_code.data[j].name)
                    } else {
                        dictBodyMap.set(tdData.dict_code.data[j].key, tdData.dict_code.data[j].value)
                    }
                }
                that.dictMap.set(tdData.name, dictBodyMap);
            }
            if (tdData.is_show_select_table == 'Y') {
                dict_code.push({value:tdData.label_name,key:tdData.name})
                if(tdData.list_load_is_render=='Y'){
                    that.listLoadRenderFieldArray.push(tdData.name)
                    tableHeadHtml += `<th width="${tdData.width}" 
                    style="position: sticky;top:-1px;z-index: 999;background-color: ${thColor};" 
                    fieldName="${tdData.name}"`;
                    let tooltipHtml=``;
                    if(tdData['is_list_header_question_circle']=='Y'){
                        tooltipHtml=`<i class="far fa-question-circle" style="font-size: 15px;cursor:pointer;" 
                                    data-toggle="tooltip" data-placement="top" title="" data-original-title="${tdData['list_header_question_circle_text']}"></i>`;
                    }
                    tableHeadHtml += '>' + tdData.label_name + tooltipHtml +'</th>'
                }
            }
        }
        that.columnDictCode={data:dict_code}
        if (!util.isNull(that.queryInfo.is_managing)
            && that.queryInfo.is_managing == 'Y'
            &&that.queryInfo.managing_show_type=='last_show'
            &&that.pageComponent.isReadOnly!='Y') {
            // 公式是：按钮数量*按钮长度+默认列长度
            let managerThWidth=that.queryInfo.rowButtonArray.length*Number(that.queryInfo.managing_button_length)+Number(that.queryInfo.managing_length)
            tableHeadHtml += `<th width="${managerThWidth}" 
            style="${true?`position: sticky;right: 0;top:-1px;z-index: 999;background-color: ${thColor};`:''}">${tableManagingName}</th>`;
        }
        tableHeadHtml += '</tr>'
        return tableHeadHtml;
    }
    getPageInfoHtml() {
        let that=this;
        let optionHtml=``;
        if(that.pageSize==undefined){
            that.pageSize=that.queryInfo.page_size;//默认配置的页数
        }
        let isEditComponent=util.getSessionStorageItem('isEditComponent');
        if(isEditComponent=='S'||isEditComponent=='P'){
            that.pageSizeArray=[10,20,50,100,200,500,1000,2000];
        }
        for (let i = 0; i < that.pageSizeArray.length; i++) {
            optionHtml += `<option value="${that.pageSizeArray[i]}" ${that.pageSize==that.pageSizeArray[i]?'selected':''}>每页${that.pageSizeArray[i]}条</option>`
        }
        let changePageSizeTemplate=`
            ${that.pageSizeArray.includes(that.queryInfo.page_size)?`&nbsp;总&nbsp;<ccccc>${that.allPages}</ccccc>&nbsp;页`:`<ccccc style="display: none">${that.allPages}</ccccc>`}
            ${that.pageSizeArray.includes(that.queryInfo.page_size)?`&nbsp;到第&nbsp;<hhh>
                <div class="input-group">
                    <input type="text" class="form-control form-control-sm" placeholder="" style="width: 50px;" value="${that.page + 1}" id="${that.getObjID()}toPageInput">
                    <span class="input-group-append">
                        <button class="btn btn-sm btn-secondary" type="button" id="${that.getObjID()}toPageButton">Go</button>
                    </span>
                </div></hhh>&nbsp;页&nbsp;&nbsp;`:`<hhh style="display: none">${that.page + 1}</hhh>`}
            <div id="${that.getObjID()}changePageSizeDiv" class=" pull-right"
            style="${!that.pageSizeArray.includes(that.queryInfo.page_size)?'display:none':''}">
            <select name="DataTables_Table_1_length" id="${that.getObjID()}changePageSize" class="form-control form-control-sm">
            ${optionHtml}
            </select>
            </div>`;
        let pageInfoHtml = '';
        pageInfoHtml += '共&nbsp;' + that.allItemNum + '&nbsp;条&nbsp;' + changePageSizeTemplate;
        return pageInfoHtml;
    }
    getPageDownHtml() {
        let nowPage = this.page;//当前页面
        let totalPage = this.allPages;//总页面
        let startPage = 0;
        let endPage = 5;
        if (totalPage <= 5) {
            endPage = totalPage;
        }
        if (totalPage > 5) {
            if (nowPage > 3) {
                startPage = nowPage - 2;
                endPage = nowPage + 3;
            }
            if (endPage > totalPage) {
                startPage = totalPage - 4;
                endPage = totalPage;
            }
        }
        let buttonBackgroundColor=config.getConfigJson().themeColor;
        let pageInfoHtmlTemplate=``;
        for (let i = startPage; i < endPage; i++) {
            pageInfoHtmlTemplate+=`
            <li class="paginate_button page-item ${nowPage==i?'active':''}">
            <span 
            style="cursor:pointer;${nowPage==i?`background-color: ${buttonBackgroundColor} !important;border-color: ${buttonBackgroundColor} !important;`:''}" class="page-link">
            ${i + 1}</span>
            </li>`;
        }
        let pageDownHtmlTemplate=`
        <ul class="pagination">
        <li khcname="Previous" class="paginate_button page-item previous ${nowPage==0?'disabled':''}">
        <span style="cursor:pointer;" class="page-link fas fa-angle-left d-block"></span>
        </li>
        ${pageInfoHtmlTemplate}
        <li khcname="Next"  class="paginate_button page-item next ${(nowPage + 1) == totalPage?'disabled':''}">
        <span style="cursor:pointer;" class="page-link fas fa-angle-right d-block"></span>
        </li></ul>`;
        return pageDownHtmlTemplate;
    }
    getSelectTableDataStr(){
        let that=this;
        let str='';
        for (let i = 0; i < that.selectTableDataArray.length; i++) {
            str+=that.selectTableDataArray[i]+','
        }
        str=str.substring(0,str.length-1);
        return str;
    }
    render() {
        this.initFunc();
        this.init()
            .then(() => {
                this.renderArea().then(() => {
                    if (this.haveTree) {
                        this.renderTree();
                    }
                    this.refresh().then(() => {
                        if (this.queryInfo.is_edit_table == 'Y') {
                            this.setDateElementEvent();
                        }
                    })
                });
            })
    }
    //实例化时先渲染表格的基本数据
    renderArea() {
        let that=this;
        let parentDomID = that.parentDomID;
        return new Promise((resolve, reject) => {
            let buttonBackgroundColor=config.getConfigJson().themeColor;
            let buttonFontColor=util.dynamicColor(buttonBackgroundColor);
            let titleFontSize=util.getFontSizeByLevel(6);
            let notSearchFiledTypeArray=['hidden','tree']
            let selectFiledNameTtml=`<option value="">查询范围</option>`
            if(that.queryInfo.is_show_query=='N'&&that.queryInfo.is_show_table_search=='Y'){
                let queryData=fullMap.getObj(that.queryObjID).queryData
                for (let i = 0; i < queryData.length; i++) {
                    if (!notSearchFiledTypeArray.includes(queryData[i]['show_type'])&&queryData[i]['data']['is_query'] == 'Y') {
                        selectFiledNameTtml+=`<option value="${queryData[i]['data']['name']}">${queryData[i]['data']['label_name']}</option>`
                    }
                }
            }
            let tableTitleHtmlTemplate=`
            <div id="${that.getObjID()}" style="padding-left: 1rem;padding-right: 1rem;" class="card">
            ${!util.isNull(that.queryInfo.table_title)?`<h6 class="card-header" style="font-size: ${titleFontSize}">${that.queryInfo.table_title}</h6>`:''}
            <div class="card-datatable table-responsive pl-2 pr-2"  style="padding: 1rem;">
            <div class="dataTables_wrapper container-fluid dt-bootstrap4 no-footer">
            <div class="row">
            <div class="col-sm-12 col-md-8" style="${that.queryInfo.is_show_select_table=='Y'?'display: none;':''}" >
            <div class="dataTables_length row" style="margin-left:-1.5rem" id="${that.eleID}tableAreaButton">
            </div></div>
            <div class="col-sm-12 col-md-4" style="min-width: 350px;">
            <div class="input-group-append" id="${that.eleID}tableSearchDiv" 
                style="${that.queryInfo.is_show_query=='N'&&that.queryInfo.is_show_table_search=='Y'?'':'display: none;'}margin-bottom: 10px;margin-right: -23px;">
                <select class="custom-select" style=" width: 180px;" id="${that.eleID}tableSearchField" value="" name="${that.eleID}tableSearchField">
                  ${selectFiledNameTtml}
                </select>
                <input type="text" id="${that.eleID}tableSearchInput" value="" name="${that.eleID}tableSearchInput" class="form-control" placeholder="请输入关键字">
                <span class="input-group-append">
                    <button class="btn btn- ladda-button" data-style="slide-down" type="button" id="${that.eleID}tableSearchButton"
                    style="background-color: ${buttonBackgroundColor};color: ${buttonFontColor}">搜索</button>
                </span>
            </div>
            </div></div>
            <div class="row" style="margin-bottom:5px;">
                ${that.haveTree?`<div>
                    <i id="${that.treeView.parentDomID}toggleBtn" class="d-flex justify-content-center rounded-circle align-items-center ion ion-md-menu" style="cursor: pointer;width:30px;height:30px;background-color:#f5f5f5;" data-toggle="tooltip" data-placement="top" title="" data-original-title="收起"></i></div>` : ''}
            </div>
            <div class="row">
            
            ${that.haveTree?`<div class="col-sm-4 col-xl-3 mt-2 ztree ${config.getConfigJson().defaultTableColorClassJson.tableTDMouseoutOddBackgroundColor}" id="${that.treeView.parentDomID}" 
            style="width:calc(35vh); overflow:auto;margin-top: .0rem !important;padding-top: 0px;background: ${config.getConfigJson().tableTdMouseoutBackgroundColor};transition:all 0.3s">
            545454545
            </div>
            <div class="col-sm-8 col-xl-9 pl-2" style="overflow:hidden;">`:`<div class="col-sm-${that.queryInfo.is_show_select_table=='Y'?'7':'12'}" style="overflow:hidden;">`}
            <div class="${that.haveTree?'pl-2':''}">
            <div id="${that.eleID}_show_table_div" style="overflow:auto;">
            ${that.queryInfo.is_show_select_table=='Y'?`
            <h6 class="card-header" style="font-size: ${util.getFontSizeByLevel(7)}">可选择：</h6>`:''}
            ${that.queryInfo.render_list_type!='render_card'?
                `<table id="${that.eleID}" width="100%" style="min-width:${that.tableMinWidth}px;margin-top: 0px !important;" 
                class=" table table-striped table-bordered dataTable no-footer">`:
                `<div class="row mr-2" id="${that.eleID}"></div>`}
            
            <thead></thead>
            <tbody></tbody>
            </table></div></div></div>
                        
            ${that.queryInfo.is_show_select_table=='Y'?`
            <div class="col-sm-5">
            <div class="pl-4">
            <div id="${that.eleID}_show_table_div_select" style="overflow:auto;">
            <h6 class="card-header" style="font-size: ${util.getFontSizeByLevel(7)}">已选择：</h6>
            <table id="${that.eleID}_select" width="100%" style="min-width:${that.tableMinWidth/2}px;margin-top: 0px !important;" class=" table table-striped table-bordered dataTable no-footer">
            <thead></thead>
            <tbody></tbody>
            </table></div></div>
            `:''}
            
            </div><div class="row">
            ${that.haveTree?`<div class="col-sm-4 col-xl-3 mt-2"></div><div id="${that.eleID}pageInfo" class="row col-sm-8 col-xl-9 pl-2">`:`<div id="${that.eleID}pageInfo" class="row col-sm-12">`}
            <div class="col-lg-8 col-12">
            <div class="dataTables_info" id="${that.eleID}pageInfoOfSize" role="status" aria-live="polite"></div>
            </div>
            <div class="col-lg-4 col-12">
            <div class="dataTables_paginate paging_simple_numbers" id="${that.eleID}pageInfoWithPage">
            </div></div></div></div></div>
            `;
            document.getElementById(parentDomID).insertAdjacentHTML("beforeEnd", tableTitleHtmlTemplate);



            let parentFormObjID=fullMap.getObj(fullMap.getObj(this.queryObjID).pageID).parentFormObjID
            if(!util.isNull(parentFormObjID)){
                fullMap.getObj('mask').showByElement(that.eleID,2000);
            }
            if(that.haveTree) {
                document.getElementById(`${that.treeView.parentDomID}toggleBtn`).addEventListener('click',function(){
                    $(`#${that.treeView.parentDomID}toggleBtn`).tooltip('hide');
                    that.toggleTree=!that.toggleTree;
                    let nextSibling = document.getElementById(`${that.treeView.parentDomID}`).nextElementSibling;
                    let parentDom = document.getElementById(`${that.treeView.parentDomID}`)

                    if(that.toggleTree){
                        parentDom.style.display='none';
                        if (nextSibling) {
                            nextSibling.className = 'col-12';

                        }
                        document.getElementById(`${that.treeView.parentDomID}toggleBtn`).setAttribute('data-original-title','展开');
                    }else{
                        parentDom.style.display='block';
                        if (nextSibling) {
                            nextSibling.className = 'col-sm-8 col-xl-9 pl-2';
                        }
                        document.getElementById(`${that.treeView.parentDomID}toggleBtn`).setAttribute('data-original-title','收起');

                    }
                })
            }
            resolve();
        });
    }
    updateTableMinWidth(){
        let that=this;
        document.getElementById(that.eleID).style.minWidth=that.tableMinWidth+'px';
    }
    //通过业务数据刷新表格（isForceRefresh：是否强制刷新）
    refresh(isForceRefresh=false) {
        let that = this;
        if((that.tUtil!=null&&that.isEditTableData())&&!isForceRefresh){
            khcAlert.showWarningMessage('检测到当前表格数据有改动，请先保存当前页数据')
            return Promise.resolve();
        }
        if(that.pageComponent['parentContent']!=undefined){
            let myselfFuncStr=util.toOldChar(that.queryInfo['query_show_func']);
            that.queryInfo.parentContent=that.pageComponent['parentContent'];
            util.executeDynamicCode(myselfFuncStr,that.queryInfo)
        }
        return that.getContentsFromServer().then(() => {
            if(!util.isNull(that.queryInfo.js_file)&&!util.isNull(that.queryInfo.table_render_before)){
                fullMap.push(that.getObjID(),that);
                let jsonConfig={objID:that.getObjID(),button_method:that.queryInfo.table_render_before}
                util.import2023(that.queryInfo.js_file,jsonConfig);
            }
            if(that.queryInfo['auto_refresh']!='0'&&that.autoRefreshFunc==null){
                if (that.queryInfo['auto_refresh'] > 0) {
                    that.autoRefreshFunc = setInterval(() => {
                        if (document.getElementById(that.eleID)) {
                            that.refresh();
                        }else{
                            // 如果元素不存在，清除定时器
                            clearInterval(that.autoRefreshFunc);
                            console.log('元素不存在，自动刷新定时器已清除');
                        }
                    }, that.queryInfo['auto_refresh'] * 1000);
                    console.log(`自动刷新已启动，每 ${that.queryInfo['auto_refresh']} 秒更新一次数据`);
                }
            }
            if(that.allPages!=0){
                document.getElementById(that.eleID + 'pageInfoOfSize').innerHTML = that.getPageInfoHtml();
                document.getElementById(that.eleID + 'pageInfoWithPage').innerHTML = that.getPageDownHtml();
            }else{
                document.getElementById(that.eleID + 'pageInfoOfSize').innerHTML = '';
                document.getElementById(that.eleID + 'pageInfoWithPage').innerHTML = '';
            }
            if(that.queryInfo.render_list_type=='render_card'){
                let tableStructureData = that.tableStructureData;
                for (let i = 0; i < tableStructureData.length; i++) {
                    let tdData = tableStructureData[i].data;
                    //将每个字段的字典数据装入map（字段名为key）
                    let dictCode = tdData.dict_code.toString();
                    if (!util.isNull(dictCode)) {
                        let dictBodyMap = new Map();
                        for (let j = 0; j < tdData.dict_code.data.length; j++) {
                            if (['multiPicker','tree','treeCheckBox'].includes(tdData.show_type)) {
                                dictBodyMap.set(tdData.dict_code.data[j].id.toString(), tdData.dict_code.data[j].name)
                            } else {
                                dictBodyMap.set(tdData.dict_code.data[j].key, tdData.dict_code.data[j].value)
                            }
                        }
                        that.dictMap.set(tdData.name, dictBodyMap);
                        that.showTypeMap.set(tdData.name, tdData.show_type);
                    }
                }
                that.renderTableButton();
                let renderListCardTemplate=util.toOldChar(that.queryInfo['render_list_card_template'])
                let renderValueHtmlTemplate='';
                that.dataMap.clear();
                if(that.contents.length==0){
                    renderValueHtmlTemplate=`<div class="col-lg-12 col-xl-12">
                        <div class="mb-3" style="">
                            <div style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
                                <i style="font-size: 30px" class="far fa-file d-block"></i>
                                <span>暂无数据</span>
                            </div>
                        </div>
                    </div>`;
                }else{
                    for (let i = 0; i < that.contents.length; i++) {
                        let content=that.contents[i];
                        let replaceContent=util.clone(content);
                        if(util.isNull(content[that.pkFieldName])){
                            khcToastr.showErrorMessage('error：未找到设置的主键，请核实该配置，如果使用的是mongo则可以改为uuid做为主键')
                            return ;
                        }
                        that.dataMap.set(content[that.pkFieldName].toString(), content);
                        for (let key in replaceContent) {
                            let dict=that.dictMap.get(key);
                            if(!util.isNull(dict)){
                                let showType=that.showTypeMap.get(key);
                                if(!util.isNull(replaceContent[key])&&['select','tree'].includes(showType)){
                                    replaceContent[key]=dict.get(replaceContent[key])
                                }if(['checkbox'].includes(showType)){
                                    let showValueArray=[];
                                    if(!util.isNull(replaceContent[key])){
                                        let value=replaceContent[key]
                                        let valueArray = value.split(',')
                                        for (let i = 0; i < valueArray.length; i++) {
                                            if(!util.isNull(valueArray[i])){
                                                showValueArray.push({index:dict.get(valueArray[i])})
                                            }
                                        }
                                    }
                                    replaceContent[key]=showValueArray;
                                }
                            }else{
                                let value=replaceContent[key];
                                // 判断 value 是否是一个有效的数组字符串
                                if (typeof value === 'string') {
                                    // 去掉多余空格并检查是否是数组格式
                                    const trimmedValue = value.trim();

                                    if (trimmedValue.startsWith('[') && trimmedValue.endsWith(']')) {
                                        let decodedValue;
                                        try {
                                            decodedValue=util.toOldChar(trimmedValue);
                                            // 手动替换换行符和制表符
                                            decodedValue = decodedValue.replace(/\n/g, '\\n').replace(/\t/g, '\\t');

                                            // 尝试将字符串解析为数组对象
                                            const parsedValue = JSON.parse(decodedValue);

                                            // 如果解析成功，将其赋值给 content[key]
                                            replaceContent[key] = parsedValue;
                                        } catch (e) {
                                            // 错误信息更具体
                                            console.error(`无法解析为有效数组`);
                                        }
                                    }
                                }
                            }
                        }
                        replaceContent['tableID']=that.eleID;
                        // 替换占位符为实际值
                        renderValueHtmlTemplate += util.replaceTemplate(renderListCardTemplate, replaceContent);
                    }
                }
                document.getElementById(that.eleID).innerHTML=renderValueHtmlTemplate
                //that.renderTableButton();
                that.renderRowButton();
                return '';
            }
            //测试发现当document.getElementById(that.eleID) 等于空对象时造成原因是A页面还没渲染完，就点击了B页面导致A页面渲染找不到。
            document.getElementById(that.eleID).querySelector('thead').innerHTML = that.getTableHeaderHtml();
            if(that.queryInfo.is_show_select_table=='Y'){
                document.getElementById(that.eleID+'_select').querySelector('thead').innerHTML = that.getSelectTableHeaderHtml();
            }
            that.tUtil=new tableUtil(that);
            that.tUtil.getTableBodyHtml().then((htmlTemplate)=>{
                document.getElementById(that.eleID).querySelector('tbody').innerHTML = htmlTemplate;
                /*new PerfectScrollbar(document.getElementById(that.eleID+'_show_table_div'));//bootstrap4滚动条*/
                if(that.queryInfo.is_show_select_table=='Y'){
                    that.tUtil.getSelectTableBodyHtml().then((selectHtmlTemplate)=>{
                        document.getElementById(that.eleID+'_select').querySelector('tbody').innerHTML = selectHtmlTemplate;
                        that.renderTableButton();
                    })
                }else{
                    that.renderTableButton();
                    that.renderRowButton()
                }
            })
        }).then(() => {
            that.addEventListener();
            //tableRenderAfter 渲染后执行的函数
            if(!util.isNull(that.queryInfo.js_file)&&!util.isNull(that.queryInfo.table_render_after)){
                fullMap.push(that.getObjID(),that);
                let jsonConfig={objID:that.getObjID(),button_method:that.queryInfo.table_render_after}
                util.import2023(that.queryInfo.js_file,jsonConfig);
            }
            let querySimpleCardArray=that.queryInfo['querySimpleCardArray'];
            if(!util.isNull(querySimpleCardArray)&&querySimpleCardArray.length>0){
                let querySimpleCardMap=fullMap.getObj(that.queryObjID).querySimpleCardMap;
                for (let key of querySimpleCardMap.keys()) {
                    let simpleCardObj = querySimpleCardMap.get(key)
                    simpleCardObj.refreshSimpleCardValue();
                }
            }
        });

    }
    downExcel() {
        let that=this;
        if(that.allItemNum==0){
            khcToastr.showErrorMessage('当前无导出记录');
            return Promise.resolve();
        }
        let obj={url:config.getConfigJson().exportExcelDataUrl,params:this.code}
        return httpUtil.post(obj, (response)=>{
            khcToastr.showSuccessMessage('导出成功');
            let downExcelUrl=config.getConfigJson().downFileUrl+'?realFileName='+response.data.data.realFileName+'&fileDiskName='+response.data.data.diskFileName+'&suffix='+response.data.data.suffix
            window.open(downExcelUrl);
        })
    }
    downExcelTemplate() {
        let that = this;
        let templateStr=that.queryInfo.excel_template;
        if(templateStr!=''&&templateStr!='[]'&&templateStr.length>0){//自定义下载模板
            let fileInfo=that.queryInfo.excel_template[0];
            khcToastr.showSuccessMessage('下载成功');
            let downExcelUrl=config.getConfigJson().downFileUrl+'?fileDiskName='+fileInfo.diskFileName+'&realFileName='+fileInfo.realFileName+'&suffix='+fileInfo.suffix
            window.open(downExcelUrl);
        }else{//系统生成下载模板
            let obj={url:config.getConfigJson().exportExcelTemplate,params:this.code}
            return httpUtil.post(obj, (response)=>{
                khcToastr.showSuccessMessage('下载成功');
                let downExcelUrl=config.getConfigJson().downFileUrl+'?fileDiskName='+response.data.data.diskFileName+'&realFileName='+response.data.data.realFileName+'&suffix='+response.data.data.suffix
                window.open(downExcelUrl);
            })
        }
    }
    //渲染按钮并绑定事件，映射到对应方法执行
    renderTableButton() {
        let that=this;
        let tableButtonArray = that.queryInfo.tableButtonArray;
        let buttonsInfo = {tableButtonArray: tableButtonArray }
        buttonsInfo.parentObjID = that.parentDomID;
        buttonsInfo.queryComponentObjID = that.queryObjID
        that.tableButtonsView = new tableButtons(buttonsInfo);
        that.tableButtonsView.render(that.eleID)
        if(that.pageComponent.isReadOnly=='Y'){
            document.getElementById(that.eleID+'tableAreaButton').style.display='none'
        }
    }
    //渲染按钮并绑定事件，映射到对应方法执行
    renderRowButton() {
        let that=this;
        if(that.queryInfo.is_managing=='N'||that.pageComponent.isReadOnly=='Y'){
            return ;
        }
        let buttonsInfo = { rowButtonArray: that.queryInfo.rowButtonArray,renderListType:that.queryInfo['render_list_type']}
        buttonsInfo.parentObjID = that.parentDomID;
        buttonsInfo.queryComponentObjID = that.queryObjID
        that.rowButtonsView = new rowButtons(buttonsInfo);
        that.rowButtonsView.render(that.eleID)
    }
    renderTree() {
        this.treeView.render();
        
    }
    //增加监听的统一入口
    addEventListener() {
        let that=this;
        //增加事件监听，因为表格每次刷新，会重置表格body的html，所以这个事件绑定不用判断是否已经有绑定，因为每次都是新的
        that.tableBodyWithChangeBackgroundColorFunc();
        that.thBySortFunc();
        $('[data-toggle="tooltip"]').tooltip();//tooltip 插件
        $('[data-toggle="popover"]').popover({html:true});//popover 弹出框组件
        let toPageButtonObj=document.getElementById(that.getObjID() + 'toPageButton')
        let toPageInputObj=document.getElementById(that.getObjID() + 'toPageInput')
        that.pageDownFunc();
        if(that.allPages!=0&&toPageButtonObj!=null){
            vanillaTextMask.maskInput({
                inputElement: toPageInputObj,
                mask: textMaskAddons.createNumberMask({//不允许输入数字以外的内容
                    includeThousandsSeparator:false,//不需要分割（默认true分割，如下：111,111）
                    allowDecimal: false,//不允许小数点
                    prefix: '',//前面展示
                    suffix: ''//后面展示
                })
            });
            let keydownFunc=function (e){
                if(e.keyCode==13){
                    that.toPageButtonFunc()
                }
            }
            toPageInputObj.addEventListener('focus',function (){
                util.addEventListener(toPageInputObj,'keyup',keydownFunc)
            })
            toPageInputObj.addEventListener('blur',function (){
                util.removeEventListener(toPageInputObj,'keyup',keydownFunc)
            })
            
            util.addEventListener(toPageButtonObj,'click',that.toPageButtonFunc);
            let changePageSizeObj=document.getElementById(that.getObjID() + 'changePageSize')
            util.addEventListener(changePageSizeObj,'change',that.changePageSizeFunc);
        }
        that.showDetailByTrWithDblClickFunc();
        that.imagePhotoSwipeLightboxFunc();//getTableBodyHtml 渲染图片时需要添加事件点击查看原图
        that.editTableFileUploadFunc();//列表编辑时对附件添加上传事件
        that.editTableSaveRowDataFunc();//列表编辑时添加实时保存功能(文本需要点击保存按钮)
        if (that.queryInfo.is_checkbox == 'Y'&&that.pageComponent.isReadOnly!='Y') {
            let checkInputObj=document.getElementById(that.eleID).querySelector('input[khcattr]');//全选 checkObj
            util.addEventListener(checkInputObj,'change',that.checkBoxSelectRowFunc);
            that.checkBoxSelectRowByTrFunc();
        }
        if(that.queryInfo.is_show_query=='N'&&that.queryInfo.is_show_table_search=='Y'){
            that.initTableSearchFunc();
        }

    }
    //在编辑状态下，需要给date型字段的元素增加设置
    setDateElementEvent() {
        //因为选定的日历弹出控件是jquery的插件，所以只能饮用jquery了
        //todo 早晚自己写一个日历控件
        $('#' + this.eleID).find('input[to="date"]').each( ()=> {
            $(this).datepicker({
                format: 'yyyy-mm-dd',
                weekStart: 1,
                autoclose: true,
                todayBtn: 'linked',
                language: 'cn',
            });
        });
    }
    showDetail(pkCode) {
        let that=this;
        let params = {};
        let pageComponentArray = that.pageComponent.componentArray;
        for (let i = 0; i < pageComponentArray.length; i++) {
            if (pageComponentArray[i].type == 'form') {
                params = pageComponentArray[i].code;
            }
        }
        params=util.clone(params);
        params.order=1;//加一个参数，会重新请求后端获取参数
        let content = that.dataMap.get(pkCode.toString());
        let khcModalForForm=that.showDetailSlideForm;
        if(khcModalForForm==null||khcModalForForm==undefined){
            khcModalForForm = new khcModalSlide({ modalAreaID: config.getConfigJson().modalAreaID });
            this.showDetailSlideForm=khcModalForForm;
            khcModalForForm.render().then(() => {
                let formComponent = new form({ parentObjID: khcModalForForm.getEleID(), code: params });
                khcModalForForm.formComponent=formComponent;
                formComponent.khcModalForForm=khcModalForForm;
                khcModalForForm.formObjID=formComponent.getObjID()
                let khcModalForFormKey='khcModalForForm#'+formComponent.getObjID();
                pageInfoMap.push(khcModalForFormKey,khcModalForForm);
                formComponent.setFormShowType('modals')
                formComponent.closeButton();
                formComponent.render().then(() => {
                    formComponent.renderThenFunc=(content)=> {
                        let eleMap = formComponent.getFormMap();
                        if(pageInfoMap.getObj(formComponent.code.queryCode)==undefined||
                            pageInfoMap.getObj(formComponent.code.queryCode).page_parent_uuid==undefined){
                        }else{
                            eleMap.get('page_parent_uuid').setValue(pageInfoMap.getObj(formComponent.code.queryCode).page_parent_uuid)
                        }
                        eleMap.forEach( (obj,key)=>{//在赋值之前，先全部置空，因为Mongo建表和MySQL不一样
                            obj.data.is_read_only='Y';//强制修改为只读
                            obj.setDisabled();
                            obj.setValue('');
                        })
                        for (let key in content) {
                            if(util.isNull(eleMap.get(key))){
                                if(config.getConfigJson().logLevel=='debug') console.log('（警告）字段名：'+key+' 未在表单组件同步配置，如buildSql查询出来的可忽略')
                                continue
                            }
                            eleMap.get(key).data.is_read_only='Y';//强制修改为只读
                            eleMap.get(key).setValue(content[key])
                            eleMap.get(key).setDisabled();
                        }
                        formComponent.formDetail()
                        khcModalForForm.show();
                    }
                    formComponent.renderThenFunc(content);
                });
            });
        }else{
            let formComponent=khcModalForForm.formComponent
            formComponent.renderThenFunc(content);
        }
    }
    getTableEditData(){
        let that=this;
        let updateData=that.tUtil.getTableEditData();
        return updateData;
    }
    //是否修改了表格数据，当用户点击下一页时判断如果修改了内容请先保存
    isEditTableData(){
        let that=this;
        if(that.queryInfo.is_edit_table=='N'){//不启用列表编辑直接返回false
            return false;
        }else{
            let updateData=that.tUtil.getTableEditData();
            if(updateData.length == 0){//未修改任何数据返回false
                return false;
            }else{
                return true;//修改了表格数据返回true
            }
        }
    }
    hidePageInfoWithPage(){
        document.getElementById(this.eleID + 'pageInfoWithPage').setAttribute('style','display:none;')
    }
    hidePageInfoOfSize(){
        document.getElementById(this.eleID + 'pageInfoOfSize').setAttribute('style','display:none;')
    }
    hideChangePageSizeDiv(){//啊嘞嘞，changePageSizeDiv 居然用的是objID
        document.getElementById(this.getObjID() + 'changePageSizeDiv').setAttribute('style','display:none;')
    }
    setDisabled(){
        this.refresh();
    }
}
export { table }