//全局枚举变量,引入的js文件通过【sysU.sysEnumData】 统一入口访问枚举
let sysEnumData = window.top.homeEnumData;

var SelectorSource = {},
importFileName = ["form", "table", "tableEdit", "element", "jquery"];
if (typeof customImportFileName != "undefined") importFileName = customImportFileName;

/*时间格式化 new Date(n).format("yyyy-MM-dd hh-mm-ss")  */
Date.prototype.format = function (format) {
    var date = this;
    var year = date.getFullYear().toString();
    var month = (date.getMonth() + 1).toString().padStart(2, '0');
    var day = date.getDate().toString().padStart(2, '0');
    var hours = date.getHours().toString().padStart(2, '0');
    var minutes = date.getMinutes().toString().padStart(2, '0');
    var seconds = date.getSeconds().toString().padStart(2, '0');
    var milliseconds = date.getMilliseconds().toString().padStart(3, '0');

    var replacements = {
        'yyyy': year,
        'MM': month,
        'dd': day,
        'hh': hours,
        'mm': minutes,
        'ss': seconds,
        'SSS': milliseconds
    };

    var placeholderKeys = Object.keys(replacements);
    for (var i = 0; i < placeholderKeys.length; i++) {
        var key = placeholderKeys[i];
        format = format.split(key).join(replacements[key]);
    }

    return format;
};

/**
 * 返回开始时间和结束时间之间的时间段,并以"yyyy-mm-dd"的格式显示 
 * startDate设置为当前时间,并将endDate设置为往前减去numDays 天
 */
String.prototype.GetTimeRange = function (startDate, endDate, numDays = 0) {
    if (numDays >0) {
        startDate = new Date();   
        endDate = new Date();
        endDate.setDate(endDate.getDate() - numDays);   
    }
    var result = [];
    var currentDate = new Date(startDate);

    while (currentDate >= endDate) {
        result.unshift(currentDate.toISOString().split('T')[0]);
        currentDate.setDate(currentDate.getDate() - 1);
    }
    return result;
}


/* 数组去掉重复*/
Array.prototype.unique5 = function () {
    var x = new Set(this);
    return [...x];
}


/* 数组对象去掉重复*/
Array.prototype.uniqueFunc = function (uniId) {
    const res = new Map();
    return this.filter((item) => !res.has(item[uniId]) && res.set(item[uniId], 1));
}

/**
 *数组对象去掉重复 支持多个参数 
 使用方法:arr.uniqueFuncs('keys1', 'keys2',keysx);
 * @returns
 */
Array.prototype.uniqueFuncs = function () {
    const uniIds = Array.prototype.slice.call(arguments);
    const res = new Map();

    return this.filter((item) => {
        const key = uniIds.map((uniId) => item[uniId]).join('|');
        return !res.has(key) && res.set(key, 1);
    });
};

//判断元素是否在数组中 nowValue比较的值、field字段
Array.prototype.contains = function (nowValue, field,) {
    for (var i = 0; i < this.length; i++) {
        if (nowValue == this[i][field]) {
            return true;
        }
    }
    return false;
}

//根据索引删除数组
Array.prototype.removeIndex = function (dx) {
    if (isNaN(dx) || dx > this.length) { return false; }
    this.splice(dx, 1);
}

//根据某个特定的值删除数组中的指定元素
Array.prototype.removeByVal = function (field, nowValue) {
    if (isNaN(nowValue) || this.length==0) { return false; }
    for (var i = 0; i < this.length; i++) {
        if (this[i][field] == nowValue ) {
            this.splice(i, 1);
            return true;
        }
    }
    return false;
}


 /**
 * 取数组对象某个值  keys:条件的列名,comparisonValue:条件值,comparisonKeys:返回的列名
 * 返回字符串,逗号隔开
 * @returns
 */
Array.prototype.GetArrValue = function (keys, comparisonValue = "", comparisonKeys = "", isRetrunString = true) {
    var temp = this.map(function (e) {
        if (comparisonValue != "") {
            if (e[keys] == comparisonValue) return e[comparisonKeys];
        } else {
            return e[keys];
        }
    });
    if (temp.length === 0) {
        console.log("GetArrValue is null");
        return null;
    }
    return isRetrunString ? temp.filter(d => d).join() : temp;
}

/**
 * 取数组对象符合符合条件的行,支持多参数
 * 调用方式: arr.GetArrValueRows(
  { key: 'address', val: '123 Main St' },
  { key: 'name', val: 'Alice' }
)
 * @returns
 */
Array.prototype.GetArrValueRows = function () {
    const filters = Array.prototype.slice.call(arguments);
    return this.filter(item => {
        for (const filter of filters) {
            const { key, val } = filter;
            if (item[key] !== val) {
                return false;
            }
        }
        return true;
    });
};


//取数组对象符合符合条件的行,返回是数组对象
Array.prototype.GetArrValueRow = function (key, val) {
    return this.filter(item => item[key] == val);
}

/*数组插入指定位置 */
Array.prototype.insertExtend = function (index, value) {
    this.splice(index, 0, value);
};

//最大值
Array.prototype.max = function () {
    return Math.max.apply({}, this);
}

//最小值
Array.prototype.min = function () {
    return Math.min.apply({}, this);
}
//数组复制
Array.prototype.copy = function () {
    let [...tempArr] = this;
    return tempArr;
}

//类型判断
String.prototype.typeX = function (obj) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

//对象复制
String.prototype.copyObj = function (obj) {
    let { ...json2 } = obj;
    return json2;
}

//对象浅复制 
String.prototype.copyObj2 = function (obj) {
    let objA = Object.assign({}, obj);
    return objA;
}

//参数拼接  id=1&id2=2 格式 
String.prototype.parseParamExtend = function (obj) {
    var str = [];
    for (var p in obj) {
        if (!Object.prototype.hasOwnProperty.call(obj, p)) continue;
        str.push(p + "=" + obj[p]);
    }
    return str.join("&");
}

//获取url中指定参数值,没有值返回 null 如果出现乱码 请使用 encodeURIComponent 编码
String.prototype.GetUrlParam = function (name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return decodeURIComponent(r[2]); return null;
}

//GetUrlParam 的升级版本 自动读取URL所有参数并填充到对象 ,并解决乱码问题  encodeURIComponent
String.prototype.getAllUrlParameters = function () {
    const params = {};
    const queryString = window.location.search; // 获取 URL 中的查询字符串 
    const urlParams = new URLSearchParams(queryString); // 遍历所有的 URL 参数
    urlParams.forEach((value, key) => {
        params[key] = value ? decodeURIComponent(value) : null;
    }); return params;
}

/*数字每隔三位加逗号分开*/
String.prototype.Locale = function (value) {
    if (typeof value === 'undefined' || value == null) return 0;
    const temp = Number(value);
    return temp < 999 ? value : Number(value).toLocaleString();
};

/*获取状态*/
String.prototype.GetState = function (data, value) {
	if (!data) console.error("GetState方法 数据源data is null")
    let isOk = false;
    let val = "";
    for (var item in data) {
        if (!Object.prototype.hasOwnProperty.call(data, item)) continue;
        if (data[item] == value) {
            isOk = true;
            val = item;
            break;
        }
    }
    return isOk ? val : value;
}


/*获取设备类型名称*/
String.prototype.GetEquipmentTypeName = function (value, key="code", returnKey = "name") {
    let data = sysEnumData.sysEquipmentType;
    if (!data) return "";
    let isOk = false;
    let val = "";
    for (var i = 0; i < data.length; i++) {
        if (data[i][key] == "") continue;
        if (data[i][key] == value) {
            val = data[i][returnKey];
            isOk = true;
            break;
        }
    }
    return isOk ? val : value;
}

/*判断是否为空*/
String.prototype.isEmpty = function (value) {
    return typeof value === 'undefined' || value === null || value.length <= 0;
}
/*判断是数字 true:数字*/
String.prototype.isNumber = function (value) {
    if ("".isEmpty(value)) return false;
    return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
}

/*判断是正数字 true:正整数*/
String.prototype.isDigits = function (value) {
    if ("".isEmpty(value)) return false;
    return /^\d+$/.test(value);
}

/*XSS 编码*/
String.prototype.XssEscape = function (e) {
    return e === undefined || null === e ? "" : /[<"'>]|&(?=#[a-zA-Z0-9]+)/g.test(e += "") ? e.replace(/&(?!#?[a-zA-Z0-9]+;)/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/'/g, "&#39;").replace(/"/g, "&quot;") : e
}
/*XSS 解码*/
String.prototype.XssUnescape = function (e) {
    return e !== undefined && null !== e || (e = ""),
        (e += "").replace(/\&amp;/g, "&").replace(/\&lt;/g, "<").replace(/\&gt;/g, ">").replace(/\&#39;/g, "'").replace(/\&quot;/g, '"')
}

/*秒转换小时、分钟*/
String.prototype.convertSecondsToTime = function (seconds) {
    seconds = parseInt(seconds);
    if (typeof seconds !== 'number') return seconds;
    var hours = Math.floor(seconds / 3600);
    var minutes = Math.floor((seconds % 3600) / 60);
    var remainingSeconds = Math.floor(seconds % 60);

    var result = '';
    if (hours > 0) {
        result += hours + '小时';
    }
    if (minutes > 0) {
        result += minutes + '分';
    }
    result += remainingSeconds + '秒';
    return result;
}

/*ztree 获取当前选中节点的子节点集合 */
String.prototype.GetChildNodes = function (ztreeObj, treeNode, arrReturnKey = "id") {
    var childNodes = ztreeObj.transformToArray(treeNode);
    var nodes = new Array();
    for (let i = 0; i < childNodes.length; i++) {
        nodes[i] = childNodes[i][arrReturnKey];
    }
    return nodes;
}

/**
 * name layui合并tbody中单元格的方法
 * @param fieldName  要合并列的field属性值
 * @param index 表格的索引值 从1开始
 * @desc 此方式适用于没有列冻结=的单元格合并
 */
String.prototype.tableRowSpan = function (fieldName, index) {
    var fixedNode = document.getElementsByClassName("layui-table-body")[index - 1];
    if (!fixedNode) {
        return false;
    }
    var child = fixedNode.getElementsByTagName("td");
    var childFilterArr = [];
    // 获取data-field属性为fieldName的td
    for (let i = 0; i < child.length; i++) {
        if (child[i].getAttribute("data-field") == fieldName) {
            childFilterArr.push(child[i]);
        }
    }
    // 获取td的个数和种类
    var childFilterTextObj = {};
    for (let i = 0; i < childFilterArr.length; i++) {
        var childText = childFilterArr[i].textContent;
        if (childFilterTextObj[childText] == undefined) {
            childFilterTextObj[childText] = 1;
        } else {
            var num = childFilterTextObj[childText];
            childFilterTextObj[childText] = num * 1 + 1;
        }
    }
    // 给获取到的td设置合并单元格属性
    for (var key in childFilterTextObj) {
        var tdNum = childFilterTextObj[key];
        var canRowSpan = true;
        for (let i = 0; i < childFilterArr.length; i++) {
            if (childFilterArr[i].textContent == key) {
                if (canRowSpan) {
                    childFilterArr[i].setAttribute("rowspan", tdNum);
                    canRowSpan = false;
                } else {
                    childFilterArr[i].style.display = "none";
                }
            }
        }
    }
    return true;
}


/**
* 初始化 xmSelect 初始化选中 opt新增属性initValue: [4],
* opt必要传入参数: el: '#demo1', data: [{ name: 'x', value: 1 }]
* html  <div id="demo1" class="xm-select-demo"></div>
*/
String.prototype.XmSelectInit = function (opt, sU, callback) {
    if (typeof xmSelect == "undefined") {
        alert("initXmSelect方法 xmSelect为空,请确认是否引入xm-select.js文件!");
        return false;
    }
    // 验证选项
    if (!opt.el || $(opt.el).length === 0) {
        alert("initXmSelect方法 参数,opt.el为空或节点不存在!");
        return false;
    }
    let config = {
        paging: true,
        pageSize: 10,
        theme: {
            color: '#1cbbb4',
        },
        //工具条 全选、清空
        toolbar: {
            show: true,
            showIcon: false,
        },
        //direction: 'up',
        //filterable: true,//搜索模式
        size: 'small',
        autoRow: true,//自动换行
        searchTips: '请输入搜索内容',
        data: []
    }
    Object.assign(config, opt)
    // 如果提供了 URL,则验证 AJAX 配置
    if (typeof config.url != "undefined") {
        if (!config.keyValue || !config.keylabel) {
            alert("initXmSelect方法 参数,opt.keyValue或opt.keylabel为空!");
            return false;
        }
        var ajaxConfig = {
            url: config.url,
            data: config.paramData || {},
            success: function (result) {
                if (sU.successBefore(result)) return false;
                // 转换结果数据
                config.data = result.Result.map(x => ({
                    name: x[config.keylabel],
                    value: x[config.keyValue],
                }));
                let obj = xmSelect.render(config)
                if (typeof callback === "function") callback(obj, config);
            }
        }
        sU.ajax(ajaxConfig);
    } else {
        return xmSelect.render(config)
    }
}


/**
 * xmSelect 设置值,不传入参数是 清空值, 
 * 追加值 xmSelect.append([x]) x是value 类似ID
 * 删除值 xmSelect.delete([x]) x是value 类似ID
*/
String.prototype.XmSelectSetValue = function (xmSelectObj,data = []) {
    if (typeof xmSelectObj == "undefined") {
        alert("XmSelectSetValue方法 参数,xmSelectObj(XmSelectInit返回对象) 为空!");
        return;
    }
    xmSelectObj.setValue(data)
}

/**
 * xmSelect 获取值  type有 name, nameStr, value, valueStr 4个值提供
 * 默认返回value 字符串隔开 ,未选中返回""
*/
String.prototype.XmSelectGetValue = function (xmSelectObj,type = "valueStr") {
    if (typeof xmSelectObj == "undefined") {
        alert("XmSelectGetValue方法 参数,xmSelectObj(XmSelectInit返回对象) 为空!");
        return;
    }
    var selectArr = xmSelectObj.getValue(type);
    return selectArr
}

layui.define(importFileName, function (exports) {
    var form = layui.form,
        carousel = layui.carousel,
        element = layui.element,
        layer = layui.layer,
        laydate = layui.laydate,
        $ = layui.jquery,
        tableEdit = layui.tableEdit,
        $document = $(document),
        tableSelect = layui.tableSelect,
        excel = layui.excel,
        table = layui.table,
        flow = layui.flow,
        treeTable = layui.treeTable,
        timeStamprowClick = 0,
        timeInitFormEvent = 0,
        timeDocumentClick = 0,
        footerSuffix = "Footer",
        descSuffix = "Desc";
    if (treeTable != undefined) table = treeTable;

    let systemAction = null, sU;

    var u = function () {
        this.config = {
            tokenInvalid: "登入信息已失效,系统将自动跳转到登入页!",
            urlLogin: "/Login/Index",
            titleError: "请检查服务是否开启,反复出现请联系管理员",
            titleAdd: "新增",
            titleEdit: "编辑<span style=\"color:red;font-weight: bold;\">(系统编码请谨慎修改!)</span>",

            titleDeleteId: "删除操作keys值为空,请确认核实!",
            titleDeleteSuccess: "删除成功",
            titleUpdateSuccess: "修改成功",
            titleAddSuccess: "新增成功",
            titleSchedulingSuccess: "排产成功",
            titleSelectOneRowData: "请至少选择一条数据!",
            titleSelectOne: "请选择一条数据!",
            titleOpen: "提示",
            titleConfirmDelete: "确定要删除所选信息吗?",
            titleTime: "开始时间不能大于结束时间",
            titleActionSuccess: "操作成功",
            titleDataNull: "查询无数据!",
            title404: "您访问的页面资源不存在,请核实!",

            titleCopyAdd: "复制新增",
            titleQcCodePrint: "二维码打印",
            selectOptFirstText:"-请选择(支持模糊搜索)-",
            errorTime: 5000,
            msgOpenTime: 2000,
            iconoOk: 1,
            iconoError: 2,
            ignoreEvent: ["LAYTABLE_COLS"],

            btnRefreshLoadIndex: -1,
            descSuffix :"Desc",
            footerSuffix: "Footer",
            checkTableRowData: null,
            checkTableALLRowData: null,
            colsWidthFlag:"_colsWidth"
        }
    }
    //cookie Token 失效返回登入页
    u.prototype.cookieVerification = function () {
        var i = this;
        var cookie = i.cookie("Token");
        if (cookie == null) {
            layer.msg(i.config.tokenInvalid, { icon: i.config.iconoError, shade: 0.4, time: 2000 });
            setTimeout(function () {
                window.location.href = i.config.urlLogin;
            }, 2500);
        }
    }

    //cookie set ,read[value 是空 read]
    u.prototype.cookie = function (key, value, options) {
        if (typeof value !== "undefined") {//write
            options = options || {}
            var cookie = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            if (typeof options.expries === "number") {
                var date = new Date();
                date.setDate(date.getDate() + options.expries);
                cookie += ";expries=" + date.toUTCString();
            }
            if (options.path) cookie += ";path=" + options.path;
            if (options.domain) cookie += ";domain=" + options.domain;
            if (options.secure) cookie += ";secure";
            document.cookie = cookie;
        }
        var cookies = document.cookie.split(";");
        for (var i = 0; i < cookies.length; i++) {
            var readCookie = cookies[i].split("=");
            var name = decodeURIComponent(readCookie.shift());
            if ($.trim(name) === key) return decodeURIComponent(readCookie.join("="));
        }
        return null;
    }

    //ajax //服务器返回json存在特殊字符或者是对象里面包含字符串需要手动拼接json,案例参考homeController 
    u.prototype.ajax = function (parameter) {
        var i = this;
        i.cookieVerification();
        //在这里可以判断cooke 失效 重定性
        //let index = layer.load();
        let index = -1;
        if (parameter.loading == undefined) {
            index = layer.load();
        }
        let data = parameter.data;
        if (parameter.jsonStr) {
            data = JSON.stringify(parameter.data);
        }
        var objs = $.extend({
            dataType: "json",
            data: data,
            error: function (xmlHttpRequest, textStatus, errorThrown) {
                layer.alert(i.config.titleError + ":" + xmlHttpRequest.responseText, { icon: i.config.iconoError, shadeClose: true, title: i.config.titleError });
                console.error(XMLHttpRequest + "-----" + textStatus + "---" + errorThrown);
                console.error(JSON.stringify(parameter));
                console.trace();
            },
            dataFilter: function (data, type) {
                if (parameter.url.indexOf("PostMan") > -1 || typeof (parameter.isDataFilter) != "undefined") return data;
                //返回处理后的数据
                return data.replaceAll("\\", "").replaceAll("`", "").replaceAll("'", "").replaceAll("<", "").replace(/(^")|("$)/g, "").replaceAll(">", "");
            },
            success: parameter.success,
            type: "post",
            //timeout: 6000,  //超时时间设置,单位毫秒
            beforeSend: function (request) {
                //request.setRequestHeader("Authorization", "x");
            },
            complete: function (xmlHttpRequest, status) {
                if (parameter.loading == undefined) {
                    layer.close(index);
                }
                if (status === 'timeout') {
                    console.error("请求时间超时6秒 问题频繁出现请联系管理员");
                    console.trace();
                }
            }
        }, parameter);
        $.ajax(objs);
    }

    //ajax global error  listen 
    u.prototype.ajaxError = function () {
        var i = this;
        $document.ajaxError(function (event, xhr, options, exc) {
            if (xhr.status == 'undefined') return;
            switch (xhr.status) {
                case 404:
                    layer.alert(`${i.config.title404} 【${options.url},${options.type}】`, { icon: i.config.iconoError, shadeClose: true, title: i.config.titleError });
                    console.trace();
                    break;
                default:
                    layer.alert(`${xhr.statusText} 【${options.url},${options.type}】`, { icon: i.config.iconoError, shadeClose: true, title: i.config.titleError });
                    console.trace();
                    break;
            }
        });
    }

    /**
     * initTable
     * parseDataExtend:一定要return 只处理Result 数据源,其他格式不要破坏、
     * contentType 直接写在 parameter里面
     * 修改分页请求参数request: {  pageName: "当前第几页", limitName: "每页总条数",},
     * @returns
     */
    u.prototype.initTable = function (parameter) {
        let i = this;
        var tempTable = table;
        if (typeof (parameter.treeTable) != "undefined") {
            tempTable = treeTable;
        }
        if (typeof (parameter.elem) == "undefined") {
            layer.alert("initTable方法 参数,parameter.elem为空!", { icon: 2, shadeClose: true, title: i.config.titleError });
            return false;
        }
        if ($(parameter.elem).length == 0) {
            layer.alert("initTable方法 参数,parameter.elem 节点不存在!", { icon: 2, shadeClose: true, title: i.config.titleError });
            return false;
        }
        if (parameter.cols == null || parameter.cols.length == 0) {
            layer.alert("initTable方法 参数,parameter.cols表格列不存在!", { icon: 2, shadeClose: true, title: i.config.titleError });
            return false;
        }
        let index = layer.load(0); //添加laoding,0-2两种方式
        var objs = $.extend({
            method: !parameter.method ? "post" : parameter.method,
            limit: 50,
            limits: [50],
            loading: false,
            even: true,
            page: typeof parameter.page == "undefined" ? { layout: ['prev', 'page', 'next', 'skip', 'count', 'limit', 'refresh'] } : parameter.page,
            height: typeof parameter.height == "undefined" ? "full-1" : parameter.height,
            cellMinWidth: 80,
            parseData: function (res) {
                var result = {
                    Code: res.Code == 200 ? res.Code : -1,
                    Message: res.Message,
                    Count: res.Count,
                    Result: res.Result
                };
                if (!parameter.parseDataExtend) return result
                return parameter.parseDataExtend && parameter.parseDataExtend.call(this, res);
            },
            done: function (res) {
                if (sU.config.btnRefreshLoadIndex != -1) layer.close(sU.config.btnRefreshLoadIndex);

                layer.close(index);
                if (typeof res.code != "undefined" && (res.code === 0 || (res.data != null && res.data.length > 0))) {
                    var selectColKey = "".GetUrlParam("selectColKey");
                    if (selectColKey != null) {
                        var targetArrValue = "".GetUrlParam("targetArrValue");
                        if (targetArrValue != "" && targetArrValue != null) {
                            i.SetTableCheck(targetArrValue.split(","), res, selectColKey, parameter.elem);
                        }
                    }
                }
                var elem = parameter.elem.replace("#", "");
                //表格工具栏事件
                system.registerEvent(elem);
                //查询搜索框事件
                system.query();
                //表格自带事件
                i.bindTableEvents({ elem: elem, url: parameter.url });
                //表格完成事件
                parameter.doneExtend && parameter.doneExtend.call(this, res, arguments[1]);

                if (typeof parameter.setTableBgColor != "undefined") i.SetTableBgColor(parameter);

                tempTable.on('edit(' + elem + ')', function (obj) {
                    parameter.editExtend && parameter.editExtend.call(this, obj.value, obj.field, obj.data);
                });
            },
            size: 'sm',
            defaultToolbar: ['filter']
        }, parameter);
        let tableIns = tempTable.render(objs);        
        return tableIns;
    }

    //表格单选框选中单条件
    u.prototype.SetTableRadioCheck = function (targetValue, resData, resDataKey, tableElem) {
        localStorage.setItem("sysRadioClickFlag", 0);
        if (targetValue == null || targetValue === "") {
            console.log("SetTableRadioCheck 方法 url targetValue 参数值为空");
            return;
        }
        if ("".typeX(targetValue) != "string") {
            layer.alert("SetTableRadioCheck方法 参数targetValue 是string类型", { icon: 2, shadeClose: true, title: sU.config.titleError });
            return false;
        }
        // 遍历数据,查找目标值
        for (var j = 0; j < resData.Result.length; j++) {
            if (targetValue != resData.Result[j][resDataKey]) continue;
            localStorage.setItem("sysRadioClickFlag", 1);
            // 设置选中状态
            var trIndex = resData.Result[j]["LAY_TABLE_INDEX"],
                tableRadio = $(`div[lay-id='${tableElem}'] .layui-table-fixed-l tr[data-index='${trIndex}'] input[type='radio']`);
            // 先取消其他单选框的选中状态
            //$(`div[lay-id='${tableElem}'].layui-table-fixed-l tr input[type='radio']`).prop("checked", false).next().removeClass("layui-form-checked");
            // 设置当前单选框为选中
            //tableRadio.prop("checked", true);
           // tableRadio.next().addClass("layui-form-checked");

            // 触发相关事件(可选)
            tableRadio.next().trigger('click');  
            break;  
        }
    }

     //表格单选框选中单条件 处理模拟自动触发机制
    u.prototype.SetTableRadioCheckBefore = function () {
        var sysRadioClickFlag = localStorage.getItem("sysRadioClickFlag");
        if (sysRadioClickFlag == 1) {
            localStorage.setItem("sysRadioClickFlag", 0);
            return false;
        }
        return true;
    }

    localStorage.setItem("sysRadioClickFlag", 0);

    //表格选中单条件
    u.prototype.SetTableCheck = function (targetArrValue, resData, resDataKey, tableElem) {
        if (targetArrValue == null || targetArrValue =="" ) {
            console.log("SetTableCheck 方法 url targetArrValue 参数值为空,q");
            return;
        }
        if ("".typeX(targetArrValue) == "string") {
            targetArrValue = targetArrValue.split(',');
        }
        for (var i = 0; i < targetArrValue.length; i++) {
            for (var j = 0; j < resData.Result.length; j++) {
                if (targetArrValue[i] != resData.Result[j][resDataKey]) continue;
                resData.Result[j]["LAY_CHECKED"] = true;
                var trIndex = resData.Result[j]["LAY_TABLE_INDEX"],
                    tableCheckbox = $(".layui-table-fixed-l tr[data-index=" + trIndex + '] input[type="checkbox"]');
                tableCheckbox.prop("checked", true);
                tableCheckbox.next().addClass("layui-form-checked");
            }
        }
        //如果构成全选
        var checkStatus = table.checkStatus(tableElem.replace("#", "")),
            tableHeaderTh = $('.layui-table-header th[data-field="0"] input[type="checkbox"]');
        if (checkStatus.isAll) {
            tableHeaderTh.prop('checked', true);
            tableHeaderTh.next().addClass('layui-form-checked');
        }
    }

    //表格选中多条件
    u.prototype.SetTableMoreCheck = function (targetArrValue, resData, resDataKey, tableElem) {
        var resDataKeys = resDataKey.split(',');
        if (targetArrValue == null || typeof targetArrValue == "undefined" || targetArrValue.count == 0) {
            console.log("SetTableMoreCheck 方法 url targetArrValue 参数值为空");
            return;
        }
        if (resDataKeys.length == 0) {
            console.log("SetTableMoreCheck 方法 url resDataKey 参数值为空");
            return;
        }
        var finish = 0;
        for (var i = 0; i < resData.Result.length; i++) {
            for (var j = 0; j < targetArrValue.count; j++) {
                for (var u = 0; u < resDataKeys.length; u++) {
                    if (targetArrValue[resDataKeys[u]][j] != resData.Result[i][resDataKeys[u]]) { finish++ }
                }
                if (finish > 0) {
                    finish = 0;
                    continue;
                };
                resData.Result[i]["LAY_CHECKED"] = true;
                var trIndex = resData.Result[i]["LAY_TABLE_INDEX"],
                    tableCheckbox = $(".layui-table-fixed-l tr[data-index=" + trIndex + '] input[type="checkbox"]');
                tableCheckbox.prop("checked", true);
                tableCheckbox.next().addClass("layui-form-checked");
            }
        }
        //如果构成全选
        var checkStatus = table.checkStatus(tableElem.replace("#", "")),
            tableHeaderTh = $('.layui-table-header th[data-field="0"] input[type="checkbox"]');
        if (checkStatus.isAll) {
            tableHeaderTh.prop('checked', true);
            tableHeaderTh.next().addClass('layui-form-checked');
        }
    }

    //表格设置背景颜色 val可以是值 也可以定义函数
    u.prototype.SetTableBgColor = function (parameter) {
        var td = $(parameter.elem).next().find(`.layui-table-body tbody td[data-field='${parameter.setTableBgColor.colsName}']`),
            val = parameter.setTableBgColor.colsValue,
            css = parameter.setTableBgColor["css"];
        if (td.length == 0) {
            console.error(`表格设置背景颜色方法:SetTableBgColor 元素【${parameter.elem}】 td【data-field='${parameter.setTableBgColor.colsName}'】节点不存在!`)
            return;
        }
        if (!val) {
            console.error(`表格设置背景颜色方法:parameter.setTableBgColor.colsValue 值是空!`);
            return;
        }
        if (!css) css = { "background-color": "#f2dede" };
        for (var j = 0; j < td.length; j++) {
            var tdElem = $(td[j]),
                tdElemVal = tdElem.text().trim();
            let index;
            if (typeof val === "function") {
                index = val(tdElemVal, tdElem);
            } else {
                index = val.find(item => {
                    return item == tdElemVal;
                });
            }
            if (index != undefined) tdElem.parent().css(css);
        }
    }

    //bind table all events
    u.prototype.bindTableEvents = function (parameter) {
        let i = this;
        //https://www.cnblogs.com/XuYuFan/p/11733546.html
        var tableId = parameter.elem.replace("#", "");
        $document.on("click", ".layui-table-body table.layui-table tbody tr", function (e) {
            var now = +new Date();
            if (now - timeDocumentClick < 100) return;
            timeDocumentClick = now;
            var thisInfo = $(this),
                index = thisInfo.attr("data-index"),
                tableBox = thisInfo.parents(".layui-table-box"),
                tableDiv;
            if (tableBox.find(".layui-table-fixed.layui-table-fixed-l").length > 0) {
                tableDiv = tableBox.find(".layui-table-fixed.layui-table-fixed-l");
            } else {
                tableDiv = tableBox.find(".layui-table-body.layui-table-main");
            }
            var trElem = tableDiv.find("tr[data-index=" + index + "]"),
                checkboxCellElem = trElem.find("td div.laytable-cell-checkbox div.layui-form-checkbox I"),
                radioCellElem = trElem.find(".layui-form-radio");
            if (checkboxCellElem.length > 0) checkboxCellElem.click();
            if (radioCellElem.length > 0) radioCellElem.click();
        });
        $document.on("click", "td div.laytable-cell-checkbox div.layui-form-checkbox", function (e) {
            e.stopPropagation();
        });
        $document.on("click", ".layui-table-body table.layui-table tbody tr td .layui-form-radio", function (e) {
            e.stopPropagation(); // 阻止事件冒泡,防止连续触发
        });

        //点击行选中复选框, 时间时间戳解决重复执行
        table.on(`row(${tableId})`, function (obj) {
            var now = +new Date();
            if (now - timeStamprowClick < 80) return;
            timeStamprowClick = now;
            obj.tr.addClass("layui-table-click").siblings().removeClass("layui-table-click");
            obj.tr.find("i[class=\"layui-anim layui-icon\"]").trigger("click");
        });

        //监听表格排序 initSort 【field】排序字段、【排序方式】、【initSort】记录初始排序,如果不设的话,将无法标记表头的排序状态
        table.on(`sort(${tableId})`, function (obj) {
            table.reload(tableId, { url: parameter.url, initSort: obj, method: "post", where: { field: obj.field, order: obj.type } });
        });

        let objData;
        //监听表格行单击事件
        table.on(`row(${tableId})`, function (obj) {
            var ishover = $(this).hasClass("layui-table-hover");
            if (!ishover) return false;
            objData = obj.data;
            var rowDataClcik = action["rowData"],
                bgColor = { "background-color": "#5FB878", "color": "#000000", "font-weight": 600 }
                customKeys = "customTableCelClick",
                tableRowOneClick = action["tableRowOneClick"];
            var trSiblingsEle = obj.tr.siblings();
            for (var j = 0; j < trSiblingsEle.length; j++) {
                $(trSiblingsEle[j]).removeAttr("style");
            }
            $(obj.tr[0]).css(bgColor);
            if (typeof rowDataClcik != "undefined") action.rowData = obj.data;
            tableRowOneClick != null ? tableRowOneClick.call(this, obj) : console.log("table checkbox没有找到action对应的tableRowOneClick方法,业务不需要请忽略! 参数 obj");
            if (action[customKeys] != null) action[customKeys].call(this, obj, tableId);
        });

        //监听表格行双击事件(默认执行表格切换),监听表格行自定义双击事件
        table.on(`rowDouble(${tableId})`, function (obj) {
            var keys = "tableRowClick",
                customKeys = "customTableRowClick",
                bgColor = { "background-color": "#5FB878", "color": "#000000", "font-weight":600};
			//var trSiblingsEle = obj.tr.siblings();
   //         for (var j = 0; j < trSiblingsEle.length; j++) {
   //             $(trSiblingsEle[j]).removeAttr("style");
   //         }
   //         $(obj.tr[0]).css(bgColor);
            systemAction[keys].call(this, obj, tableId);
            if (action[customKeys] != null) action[customKeys].call(this, obj, tableId);
        });

        /**
         * 单元格点击事件   使用方法在表格列 添加属性 event:"x"
         * 目前扩展的类型 fileEvent:图片预览、openBlank:打开子窗口、openBlank:打开新标签页、openBlankPdf:pdf 预览
         */
        table.on(`tool(${tableId})`, function (obj) {
            let data = obj.data,
                thisInfo = $(this);
            if (obj.event === 'fileEvent') {
                var url = $(this).find("a[data-href]").attr("data-href").split(",");
                i.initCarousel(url);
                return false;
            }
            //第一个位是menuFlag
            if (obj.event === 'pageOpen') {
                let urlContent = thisInfo.find("a[data-href]").attr("data-href"),
                    title = urlContent.split("?")[1];
                var tempTitle = thisInfo.find("a[data-href]").attr("data-title");
                if (tempTitle) title = tempTitle;
                layer.open({
                    type: 2,
                    title: `【${thisInfo.text()}】信息【${title}】`,
                    content: urlContent,
                    area: ['1000px', '580px']
                });
                return false;
            }
            else if (obj.event === 'openBlank') {
                let url = thisInfo.find("a[data-href]").attr("data-href");
                if (url == null || url == "") {
                    console.error("table 单元格事件tool,参数url 不存在!");
                    return false;
                }
                window.open(url, url);
                return false;
            }
            else if (obj.event === 'openBlankPdf') {
                let url = thisInfo.find("a[data-href]").attr("data-href");
                if (url == null || url == ""||url.indexOf("pdf") == -1) {
                    alert("pdf预览url后缀需要包含pdf名称!")
                    return;
                }
                window.open("/htmlTemp/pdf.html?" + url, url);  
                return false;
            }
            var eventFn = action[obj.event];
            eventFn != null ? eventFn(obj) : console.log(`table tool 单元格没有找到action对应的方法${obj.event},实现方式【cols某一列属性 event:${obj.event},action注册事件:${obj.event}】,业务不需要请忽略,参数 obj!`);
        });

        //监听表格复选框时间事件
        table.on(`checkbox(${tableId})`, function (obj) {
            if (obj.type == "one") {
                obj.data = objData;
                action["checkTableALLRowData"] = [obj.data];
                localStorage.setItem("checkTableRowData", JSON.stringify(objData));
            }
            //全部取消
            else if (obj.type == "all" && !obj.checked) {
                action["checkTableALLRowData"] = table.cache[tableId]
                //action["checkTableALLRowDataChecked"] = obj.checked;
            }
            else {
                var checkTableALLRowData = table.cache[tableId].filter(x => { if (x["LAY_CHECKED"]) return x; });
                action["checkTableALLRowData"] = checkTableALLRowData;
                if (checkTableALLRowData.length == 0) {
                    action["checkTableALLRowData"] = [obj.data];
                }
               // action["checkTableALLRowDataChecked"] = obj.checked;
            }
            
            //sU.config.checkTableALLRowData = checkTableALLRowData;
            //localStorage.setItem("checkTableALLRowData", JSON.stringify(checkTableALLRowData))
            //if (checkTableALLRowData == null || checkTableALLRowData.length == 0) {
            //    layer.alert(`system内部错误,表格行选中的数据为空,请联系管理员!`, { icon: sU.config.iconoError, shadeClose: true, title: "错误信息" });
            //    return;
            //}
            var eventFn = action["checkboxMethod"];
            eventFn != null ? eventFn(obj) : console.log("table checkbox没有找到action对应的checkboxMethod方法,业务不需要请忽略,参数 obj !");
        });


        //监听表格 单选框事件
        table.on(`radio(${tableId})`, function (obj) {
            var eventFn = action["radioMethod"];
            let objInfo = {
                data: obj.data,
                checked: obj.checked,
                obj: obj
            }
            eventFn != null ? eventFn(objInfo) : console.log("table radio没有找到action对应的radioMethod方法,业务不需要请忽略,参数 obj !");
        });


        //监听表格列 选中状态
        form.on("checkbox()", function (data) {
            i.columnSelectedStatus(data);
        });

        //table.on('edit(' + tableId + ')', function (obj) {
        //    //console.log(obj.value); // 得到编辑修改后的值
        //    //console.log(obj.field); // 得到编辑的字段名
        //    //console.log(obj.data); // 得到修改后该行的数据
        //    parameter.editExtend && parameter.editExtend.call(this, obj.value, obj.field, obj.data);
        //});


        //单元格编辑 表格数据是否编辑判断属性【】isEdit 不为undefined
        //table.on(`edit(${tableId})`, function (obj) {
        //    var value = obj.value, //得到修改后的值
        //        data = obj.data, //得到所在行所有键值
        //        field = obj.field; //得到字段
        //    var update = {};
        //    update[field] = value;
        //    obj.update(update);
        //});
    }

    //获取表格当前页所有数据
    u.prototype.getTableAllData = (elem) => { return table.cache[elem]; }

    //注册表单 "select", "checkbox", "radio" 事件  dom 元素name+FromEvent
    u.prototype.initFormEvent = function (parameter) {
        if (typeof action == "undefined") {
            console.log("initFormEvent:action is null");
            return false;
        }
        if (typeof form == "undefined") {
            console.log("initFormEvent:form is null");
            return false;
        }
        //下拉选择框
        form.on("select", function (data) {
            if (typeof (data.value) != "undefined" && data.value === "on") return;
            var now = +new Date();
            if (now - timeInitFormEvent < 200) return;
            timeInitFormEvent = now;
            let temp = data.elem.name + "FromEvent";
            var eventFn = action[temp];
            if (typeof data.elem.selectedIndex !== "undefined") {
                data["text"] = data.elem[data.elem.selectedIndex].text;
            } else {
                data["text"] = "";
            }
            if (eventFn != null) eventFn(data);
            if (eventFn == null) console.log(`initFormEvent select 没有找到action对应的方法:${temp},参数data包含 elem、value、text 参数等 业务不需要请忽略!`);
        });

        //checkbox
        var sysCheckBox = $(".layui-checkbox-sys-register");
        if (sysCheckBox.length > 0) {
            for (let i = 0; i < sysCheckBox.length; i++) {
                var filter = $(sysCheckBox[i]).attr("lay-filter");
                if (filter == "") return;
                let keys = `checkbox(${filter})`
                form.on(keys, function (data) {
                    let temp = data.elem.name + "FromEventCheckbox";
                    var eventFn = action[temp];                     
                    if (eventFn != null) eventFn(data.elem.checked, data.value, data);
                    if (eventFn == null) console.log(`initFormEvent  checkbox 没有找到action对应的方法:${temp},参数data包含 checked、value、data 参数等 业务不需要请忽略!`);
                });
            }
        }

        //注册tab页签 事件 需要绑定系统class layui-tab-sys-register
        var tabList = $(".layui-tab-sys-register");
        if (tabList.length > 0) {
            for (let i = 0; i < tabList.length; i++) {
                let tabfilterEle = $(tabList[i]).attr("lay-filter");
                element.on(`tab(${tabfilterEle})`, function (data) {
                    let keyMethod = tabfilterEle + "TabMethod";
                    var eventFn = action[keyMethod];
                    if (eventFn != null) eventFn(data);
                    if (eventFn == null) console.log(`initFormEvent 没有找到action对应的方法:${keyMethod},参数data包含 elem、index参数 业务不需要请忽略!`);
                });
            }             
        }    
    }

    //openAddOrEdit
    u.prototype.openAddOrEdit = function (parameter) {
        var area = parameter["area"] == undefined ? ["750px", "500px"] : parameter.area,
            content = parameter["content"] == undefined ? $('#modifyForm') : parameter.content,
            title = parameter["title"],
            btn = parameter["btn"] == undefined ? ["保存", "关闭"] : parameter.btn,
            maxmin = parameter["maxmin"] == undefined ? true : parameter.maxmin;
        if (content.length == 0) {
            console.error("方法openAddOrEdit,参数content元素dom不存在!");
            return;
        }

        layer.open({
            title: title,
            area: area,
            maxmin: maxmin,
            type: 1,
            content: content,
            btn: btn,
            end: function (index, layero) {
                $(parameter.fromId)[0].reset();
                //最后触发关闭事件,一定会执行
                if (action["closeAfter"] != null) {
                    action["closeAfter"].call(this, function () {
                        layer.close(index);
                    });
                } else {
                    layer.close(index);
                }
            },
            success: function () {
                if (action["editAfter"] != null) {
                    action["editAfter"].call(this, function () { parameter.success(layer.index); }, parameter);
                } else {
                    parameter.success(layer.index);
                }
            },
            yes: function (index, layero) {
                if (btn.length > 1) {
                    if (parameter["btnOpenYes"] == null || parameter["btnOpenYes"] == undefined) {
                        console.error("表单隐藏提交按钮 flag: button[name=fromxxx] 为空");
                    }
                    var ele = layero.find(parameter["btnOpenYes"]);
                    if (ele.length == 0) {
                        console.error(`表单元素隐藏提交按钮${parameter["btnOpenYes"]} 为空`);
                        layer.msg(`表单元素隐藏提交按钮${parameter["btnOpenYes"]} 为空`, { icon: 2, shade: 0.4, time: 2500 });
                        return;
                    }
                    ele.click();
                } else {
                    layer.close(index);
                }
            }
        });
    }

    // 表格删除
    u.prototype.deleteConfirm = function (parameter, sysU, selectData) {
        var conTitleDelete = sysU.config.titleConfirmDelete;
        if (typeof (parameter["titleConfirmDelete"]) != "undefined") {
            conTitleDelete = parameter["titleConfirmDelete"];
        }
        layer.confirm(conTitleDelete +` 当前选择的行数【${selectData.length}】条`, { icon: 3 }, function (index) {
            var ids = selectData.map(function (e) { return e[parameter.keyId]; });
            if (ids[0] == undefined) {
                layer.alert(`${sysU.config.titleDeleteId}【action deleteOptions 配置keyId:${parameter.keyId}】不存在!` , { icon: sysU.config.iconoError, shade: 0.4, time: sysU.config.errorTime });
                console.error(`${sysU.config.titleDeleteId}【action deleteOptions 配置keyId:${parameter.keyId}】不存在!`);
                return false;
            }
            if (parameter["deleteCount"] != "undefined" && parameter["deleteCount"] == 1) {
                if (selectData.length > 1) {
                    layer.msg("不支持批量删除,请选择一条数据!", { icon: sysU.config.iconoError, shade: 0.4, time: sysU.config.errorTime });
                    return false;
                }
            }
            var ajaxConfig = {
                data: { ids: ids },
                url: parameter.url,
                success: function (result) {
                    if (parameter["refresh"] != undefined) {
                        $("#" + parameter["toolbarId"]).next().children(".layui-table-page").find(".layui-icon-refresh").click();
                    }
                    if (sysU.successBefore(result)) return;
                    layer.close(index);
                    layer.msg(result.Message, { icon: sysU.config.iconoOk, shade: 0.4, time: sysU.config.msgOpenTime });
                    //$("#" + parameter["toolbarId"]).next().children(".layui-table-page").find(".layui-icon-refresh").click();
                    if (action["actionSuccess"] !== undefined) action["actionSuccess"].call(null, parameter["actionSuccessFlag"]);
                }
            };
            sysU.ajax(ajaxConfig);
        });
    }

    // 打印二维码
    u.prototype.printBarCode = function (parameter, sysU, selectData) {
        var area = parameter["area"] == undefined ? ["800px", "600px"] : parameter.area,
            qcCodeHead = parameter["qcCodeHead"] == undefined ? $('#qcCodeHead') : parameter.qcCodeHead,
            qcCodeBody = parameter["qcCodeBody"] == undefined ? $('#qcCodeBody') : parameter.qcCodeBody,
            title = parameter["title"] == undefined ? sysU.config.titleQcCodePrint : parameter.title;
        parameter["qcCodeBody"] = qcCodeBody;
        if (qcCodeHead.length == 0) {
            layer.alert("printBarCode:打印二维码外层跟节点元素dom不存在:" + qcCodeHead.selector, { icon: 2, shadeClose: true, title: i.config.titleError });
            return;
        }
        if (qcCodeBody.length == 0) {
            layer.alert("printBarCode:打印二维码内容节点元素dom不存在:" + qcCodeBody.selector, { icon: 2, shadeClose: true, title: i.config.titleError });
            return;
        }
        qcCodeBody.empty();  //清空上一次数据
        var result = parameter.customFn(sysU, parameter, selectData);
        if (typeof result == "undefined") {
            layer.alert("printBarCode:打印二维码 自定义方法执行错误customFn 返回值不能为undefined!", { icon: 2, shadeClose: true, title: i.config.titleError });
            return;
        }
        layer.open({
            type: 1,
            title: title,
            area: area,
            content: qcCodeHead,
            scrollbar: true,
            skin: 'qcCode-class',
            btn: ["打印"],
            yes: function (index, layero) {
                qcCodeHead.jqprint({});
                layer.close(index);
            }
        });
    }

    // 二维码写入Dom
    u.prototype.qRCodeWirtDom = function (parameter, qrcodeElem, qrcodeId, qcCodeValue) {
        parameter.qcCodeBody.append(qrcodeElem);
        var qrcodeObj = new QRCode(document.getElementById(qrcodeId), {
            width: 100,
            height: 100
        });
        qrcodeObj.makeCode(qcCodeValue);
    }

    //表单扩展验证 layui 自带的 存在bug 在某些时候额外处理一遍
    u.prototype.requiredExtend = function (form) {
        var result = true;
        for (var i = 0; i < form.length; i++) {
            if (form[i].nodeName === "SELECT") {
                var seElem = $(form[i]),
                    seValue = seElem.find("option:selected").val(),
                    seVerify = seElem.attr("lay-verify");
                if (seVerify === "required" && (seValue == null || seValue === "")) {
                    result = false;
                    layer.msg("必填项不能为空", { icon: 2, shift: 6 });
                    $(form[i + 1]).focus();
                    form[i + 1].style.cssText += 'border-color: red !important;';
                    break;
                }
            }
        }
        return result;
    }

    //ajax 成功状态判断
    u.prototype.successBefore = function (result) {
        var i = this;
        var isOk = false;
        if (result.Code != 200 || !result.Status) {
            if (result["code"] == 200 || result["Code"] == 200) return isOk;
            layer.alert(result.Message || result.msg, { icon: i.config.iconoError, shadeClose: true, title: i.config.errorTitle });
            isOk = true;
        }
        return isOk;
    }

    //对象是否是数组
    u.prototype.isArray = function (obj) {
        return (typeof obj == 'object') && obj.constructor == Array;
    }

    //excel  导出数据【tableObj】当前表格信息,【result】后台返回的数据 http://excel.wj2015.com/
    u.prototype.ExcelExportData = function (parameter, results) {
        let index = layer.load();
        setTimeout(function () {
            var resultDatas = [],         //第一行是列头,第2行是列对应的数据
                dataKey = ["head", "body", "footer"],
                curMenu = JSON.parse(sessionStorage.getItem("curmenu")),
                newTime = new Date().format("yyyy-MM-dd hh-mm-ss"),
                fileName = curMenu == null ? newTime : curMenu.title + newTime;
            if (typeof parameter.excelCols == "undefined" || parameter.excelCols == null) {
                layer.alert("导出配置参数exportOptions【excelCols】必须是head,body,footer,请核实配置参数!", { icon: i.config.iconoError, shadeClose: true, title: i.config.errorTitle });
                return;
            }
            for (var i = 0; i < dataKey.length; i++) {
                var columnNameTemp = parameter.excelCols[dataKey[i]];
                if (typeof columnNameTemp == "undefined") {
                    console.log(`导出配置参数exportOptions【excelCols】head,body,footer,配置参数${dataKey[i]}不存在公共方法dataKey中,如果没有请忽略提示!`)
                    continue;
                }
                var columnName = columnNameTemp[0]
                var dataSource = results.Result == null || sU.isArray(results.Result) ? results.Result : results.Result[dataKey[i]];
                if (sU.isArray(results.Result) && i == 1) break;
                if (dataSource != undefined) {
                    resultDatas.push(sU.GetExcelData(columnName, dataSource));
                }
                //不存在,false不导明细(单表导出 false)
                if (typeof parameter.isDefault == "undefined" || !parameter.isDefault) break;
            }
            var excelData = {};//{sheet1: x, sheet2: x}
            if (resultDatas.length > 0) {
                for (var xp = 0; xp < resultDatas.length; xp++) {
                    excelData["sheet" + (xp + 1)] = resultDatas[xp];
                }
                excel.exportExcel(excelData, fileName + ".xlsx", 'xlsx');
            }
            layer.close(index);
            layer.msg(Object.keys(excelData).join(',') + "导出完成!", { icon: 6, shade: 0.4, time: 1500 });

        }, 0);
    }

    //excel方法 ExcelExportData  数据处理 noExel 为true 不导出excel列
    u.prototype.GetExcelData = function (tableCols, resultdata) {
        var resultData = [],
            exelData = [],
            tempChTitle = [];
        for (var i = 0; i < tableCols.length; i++) {
            if (tableCols[i].noExel) continue;
            if (!tableCols[i].fixed) {
                exelData[tableCols[i].field] = tableCols[i].title;
                tempChTitle.push(tableCols[i].title);
            }
        }
        resultData.push(tempChTitle);
        var title = Object.keys(exelData);
        for (var xp = 0; xp < resultdata.length; xp++) {
            var nowData = [];
            for (var j = 0; j < title.length; j++) {
                var cols = title[j];
                let value = resultdata[xp][cols];
                if (typeof (value) == "undefined") {
                    console.log("数据源 resultdata:" + JSON.stringify(resultdata[xp]));
                    console.group();
                    console.log("后台返回数据源的字段和列表table页面cols的字段不一致: " + cols);
                }
                nowData.push(resultdata[xp][cols]);
            }
            resultData.push(nowData);
        }
        return resultData;
    }

    //excel  下载模板 读取的表格table 列 过滤 noExel属性(和导出没有关系), 且读取 type=normal的
    u.prototype.exelDownTemplate = function (tableObj) {
        var tableCols = tableObj.config.cols[0],
            //第一行是列头,第2行是列对应的数据
            resultData = [],
            englishTitle = [],
            chTitle = [];
        for (var i = 0; i < tableCols.length; i++) {
            if (typeof (tableCols[i].noExel) != "undefined" || tableCols[i].noExel) continue;
            if (tableCols[i].type === "normal") {
                englishTitle[tableCols[i].field] = tableCols[i].title;
                chTitle.push(tableCols[i].title);
            }
        }
        resultData.push(Object.keys(englishTitle));
        resultData.push(chTitle);
        var curmenu = JSON.parse(sessionStorage.getItem("curmenu")),
            newTime = new Date().format("yyyyMMddhhMMss"),
            fileName = curmenu == null ? newTime : curmenu.title + newTime;
        excel.exportExcel({ sheet1: resultData }, "模板" + fileName + ".xlsx", 'xlsx');
    }

    //表格列 恢复记忆
    u.prototype.columnRecord = function (tablelid, colsArr) {
        let i = this;
        var account = localStorage.getItem("Account");
        var paths = window.location.pathname.split("/");
        var controller = paths[paths.length - 2];
        var cookieName = account + "_" + controller + "_" + tablelid;
        var cookieval = localStorage.getItem(cookieName);
        if (cookieval == null) return colsArr;
        var colsetting = JSON.parse(cookieval);
        if (colsetting == null) return
        colsArr[0].forEach(function (item, len) {
            if (colsetting[item.field] !== undefined) {
                item.hide = !(colsetting[item.field]);
            }
            //设置列宽
            var colsWidth = colsetting[item.field + i.config.colsWidthFlag]
            if (colsWidth !== undefined) {
                item.width = colsWidth;
            }
        });
        return colsArr;
    }

    //表格列 设置选中或者取消
    u.prototype.columnSelectedStatus = function (data) {
        var attributes = data.elem.attributes;
        if (attributes['lay-filter'] === undefined) return;
        if (attributes['lay-filter'].nodeValue != 'LAY_TABLE_TOOL_COLS') return;

        var tb = data.elem.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
        var account = localStorage.getItem("Account");
        var paths = window.location.pathname.split("/");
        var controller = paths[paths.length - 2];
        var tablelid = tb.previousElementSibling.id;
        var checkflag = data.elem.checked;
        var colname = attributes['name'].nodeValue;
        var cookieName = account + "_" + controller + "_" + tablelid;
        var cookieval = localStorage.getItem(cookieName);
        var colsetting = {};
        if (cookieval == undefined) {
            colsetting[colname] = checkflag;
        }
        else {
            colsetting = JSON.parse(cookieval);
            colsetting[colname] = checkflag;
        }
        localStorage.setItem(cookieName, JSON.stringify(colsetting));
    }

    //表格列 设置宽度
    u.prototype.setColumnWidth = function () {
        let i = this;
        $document.on('mouseup', '.layui-table-header th', function (e) {
            var thisInfo = $(this);
            //复选框排除
            if (thisInfo.find("input[type=checkbox]").length > 0) return false
            var account = localStorage.getItem("Account");
            var paths = window.location.pathname.split("/");
            var controller = paths[paths.length - 2];
            var tablelid = thisInfo[0].parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.previousElementSibling.id
            var colname = thisInfo.attr("data-field") + i.config.colsWidthFlag;
            var width = thisInfo.width();

            var cookieName = account + "_" + controller + "_" + tablelid;
            var cookieval = localStorage.getItem(cookieName);
            var colsetting = {};
            if (cookieval == undefined) {
                colsetting[colname] = width;
            }
            else {
                colsetting = JSON.parse(cookieval);
                colsetting[colname] = width;
            }
            localStorage.setItem(cookieName, JSON.stringify(colsetting));
        });
    }

    //initSelect   字典、url、本地静态数据源(需要指定dataSource: sysLocalDataSource.libraryOptions,)
    u.prototype.initSelect = function (selectOption, fnCallBack) {
        var sysU = new u();
		if (selectOption == null) {
            layer.alert("initSelectBatches 方法 参数【selectOption】不能为空! ", { icon: sysU.config.iconoOk, shadeClose: true, title: sysU.config.errorTitle });
            return;
        }
        let fn = fnCallBack;
        var allSelector = Object.keys(selectOption);
        allSelector.pop();
        var seLength = allSelector.length,
            index = 0,
            indexAjax = 0;
        if (seLength == 0) console.log("initSelect方法 配置参数selectOption:节点属性配置为空,如果没有请忽略提示!");
        allSelector.forEach(function (key) {
            let selectObj = {
                Dom: selectOption[key]["Dom"],
                SelType: selectOption[key].SelType,
                SelFrom: selectOption[key].SelFrom,
                SelLabel: selectOption[key].SelLabel,
                OptGroup: selectOption[key]["OptGroup"],
                SelValue: selectOption[key].SelValue,
                Where: selectOption[key]["Where"],
                isFirstSelected: selectOption[key]["isFirstSelected"] ?? true//是否默认选择第一个下拉选项
            };
            if (selectObj.SelType === "FromUrl") {
                let data = { limit: 1000 };
                if (selectObj.Where != undefined && selectObj.Where != null) {
                    let allKeyArr = Object.keys(selectObj.Where);
                    for (var xp = 0; xp < allKeyArr.length; xp++) {
                        data[allKeyArr[xp]] = selectObj.Where[allKeyArr[xp]];
                    }
                }
                var ajaxConfig = {
                    data: data,
                    url: selectObj.SelFrom,
                    success: function (result) {
                        indexAjax++;
                        if (result.Code != 200 && result.Count === 0) {
                            layer.alert(result.Message, { icon: sysU.config.iconoError, shadeClose: true, title: sysU.config.errorTitle });
                            return;
                        }
                        SelectorSource[key] = result.Result;
                        if (typeof selectOption.selectData != "undefined") selectOption.selectData[key] = result.Result;
                        sysU.createSelectElement(selectObj, result.Result);
                        form.render("select");
                        if (index + indexAjax >= seLength) {
                            if (fn != null) fn();
                            form.render("select");
                        }
                    }
                };
                sysU.ajax(ajaxConfig);
            }
            else if (selectObj.SelType === "FromDict") {
                index++;
                var tempData = sysU.arrFilterByProperty("DictType", selectObj.SelFrom);
                SelectorSource[key] = tempData;
                if (typeof selectOption.selectData != "undefined" && selectOption.selectData != null) selectOption.selectData[key] = tempData;
                sysU.createSelectElement(selectObj, tempData);
                if (index + indexAjax >= seLength) {
                    if (fn != null) fn();
                    form.render("select");
                }
            }
            else if (selectObj.SelType === "sysLocalDataSource") {
                index++;
                var tempData = selectOption[key].dataSource;
                SelectorSource[key] = tempData;
                if (typeof selectOption.selectData != "undefined" && selectOption.selectData != null) selectOption.selectData[key] = tempData;
                sysU.createSelectElement(selectObj, tempData);
                if (index + indexAjax >= seLength) {
                    if (fn != null) fn();
                    form.render("select");
                }
            }
        });
    }

   /**
    * initSelectBatches  级联关系 省、市案例
    * nowNode 当前Josn节点名称 字符串格式
    * rootNode 当前节点的根节点
    * fnCallBack
    */
    u.prototype.initSelectBatches = function (nowNode, rootNode, fnCallBack) {
        var sysU = new u();
        let selectOpt = rootNode[nowNode];
        let key = nowNode;
        if (selectOpt == null) {
            layer.alert("initSelectBatches 方法 参数【nowNode,rootNode】的值不能为空,rootNode:是nowNode的上层节点! ", { icon: sysU.config.iconoOk, shadeClose: true, title: sysU.config.errorTitle });
            return;
        }
        let fn = fnCallBack;
        let selectObj = {
            Dom: selectOpt["Dom"],
            SelType: selectOpt.SelType,
            SelFrom: selectOpt.SelFrom,
            SelLabel: selectOpt.SelLabel,
            OptGroup: selectOpt["OptGroup"],
            SelValue: selectOpt.SelValue,
            Where: selectOpt["Where"],
        };
        if (selectObj.SelType === "FromUrl") {
            let data = { limit: 1000 };
            if (selectObj.Where != undefined && selectObj.Where != null) {
                let allKeyArr = Object.keys(selectObj.Where);
                for (var xp = 0; xp < allKeyArr.length; xp++) {
                    data[allKeyArr[xp]] = selectObj.Where[allKeyArr[xp]];
                }
            }
            var ajaxConfig = {
                data: data,
                url: selectObj.SelFrom,
                success: function (result) {
                    if (result.Result.length === 0 && result.Code != 200) {
                        layer.alert(result.Message, { icon: sysU.config.iconoOk, shadeClose: true, title: sysU.config.errorTitle });
                        return;
                    }
                    SelectorSource[key] = result.Result;
                    if (typeof rootNode.selectData != "undefined") rootNode.selectData[key] = result.Result;
                    sysU.createSelectElement(selectObj, result.Result);
                    if (fn != null) fn();
                    form.render("select");
                }
            };
            sysU.ajax(ajaxConfig);
        }
        else if (selectObj.SelType === "FromDict") {
            var tempData = sysU.arrFilterByProperty("dictType", selectObj.SelFrom);
            SelectorSource[key] = tempData;
            if (typeof rootNode.selectData != "undefined" && rootNode.selectData != null) rootNode.selectData[key] = tempData;
            sysU.createSelectElement(selectObj, tempData);
            if (fn != null) fn();
            form.render("select");
        }
        else if (selectObj.SelType === "sysLocalDataSource") {
            var tempData = selectOpt.dataSource;
            SelectorSource[key] = tempData;
            if (typeof rootNode.selectData != "undefined" && rootNode.selectData != null) rootNode.selectData[key] = tempData;
            sysU.createSelectElement(selectObj, tempData);
            if (fn != null) fn();
            form.render("select");
        }
    }

    //initSelecteByEnum  Local data source  注意dataSource 数据源是对象格式
    u.prototype.initSelecteByEnum = function (selectOption, fnCallBack) {
        var sysU = new u();
		if (selectOption == null) {
            layer.alert("initSelecteByEnum方法:数据是枚举 、参数【selectOption】不能为空! ", { icon: sysU.config.iconoOk, shadeClose: true, title: sysU.config.errorTitle });
            return;
        }
        let fn = fnCallBack;
        var allSelector = Object.keys(selectOption);
        allSelector.pop();
        var seLength = allSelector.length,
            index = 0;
        if (seLength == 0) console.log("initSelect方法 配置参数selectOption:节点属性配置为空,如果没有请忽略提示!");
        allSelector.forEach(function (key) {
            index++;
            let selectObj = {
                Dom: selectOption[key]["Dom"],
                SelType: selectOption[key].SelType,
                SelFrom: selectOption[key].SelFrom,
                SelLabel: selectOption[key].SelLabel,
                OptGroup: selectOption[key]["OptGroup"],
                SelValue: selectOption[key].SelValue,
                dataSource: selectOption[key].dataSource,
                isFirstSelected: selectOption[key]["isFirstSelected"] ?? true//是否默认选择第一个下拉选项
            };
            SelectorSource[key] = selectObj.dataSource;
            if (typeof selectOption.selectData != "undefined" && selectOption.selectData != null) selectOption.selectData[key] = selectObj.dataSource;
            sysU.createSelectElement(selectObj, selectObj.dataSource);
            if (index >= seLength) {
                if (fn != null) fn();
                form.render("select");
            }
        });
    }

    //创建select【dom】 $dom,【dataSource】数据源,【selLabel】 text, 【selValue】 value,【isRender】layui 重新渲染 次方法有可能多次调用
    u.prototype.createSelectElement = function (selectOption, dataSource, isRender = false) {
        if (dataSource == null || dataSource.length === 0) {
            console.log("createSelectElement 数据源:[" + selectOption["SelFrom"] + "]配置有误或该url查询无数据!");
            //清空
            for (let i = 0; i < selectOption.Dom.length; i++) {
                if (selectOption.Dom[i].length === 0) continue;
                selectOption.Dom[i].empty();
            }
            return false;
        }
        if (selectOption.Dom == null || selectOption.Dom.length == 0) {
            console.log("createSelectElement Dom:[" + selectOption["Dom"] + "]不存在元素节点!");
            return false;
        }
        //组装html 元素 一次性写入文档节点
        var tempArr = [];
        tempArr.push(`<option  value='' >${this.config.selectOptFirstText}</option>`);

        //OptGroup:开启分组,group 组数,data 数据源
        if (selectOption["OptGroup"] != null) {
            var groupData = dataSource.groupData;
            var allData = dataSource.data;
            var groupDataKeys = Object.keys(groupData);
            for (var j = 0; j < groupDataKeys.length; j++) {
                tempArr.push(`<optgroup  label='${groupData[groupDataKeys[j]]}'>`);
                var nowGroupNextData = allData[groupDataKeys[j]];
                for (var l = 0; l < nowGroupNextData.length; l++) {
                    tempArr.push("<option value = '" + nowGroupNextData[l][selectOption.SelValue] + "'>" + nowGroupNextData[l][selectOption.SelLabel] + "</option>");
                }
                tempArr.push("<optgroup>");
            }
        } else {
            //本地数据源提前读取出来
            if (selectOption.SelFrom == "dataSource") {
                var dt = Object.keys(dataSource);
                if (dt == "undefined") console.log(`reateSelectElement 中dataSource selectOption.SelValue 为空${selectOption.SelValue} `);
                let index=0
                dt.forEach(x => {
                    let keys = dataSource[x];
                    //key的值也是文本
                    if (selectOption.SelValue == "key") keys = x;
                    if (index == 0 && selectOption.isFirstSelected) {
                        tempArr.push("<option selected value = '" + keys + "'>" + x + "</option>");
                    } else {
                        tempArr.push("<option  value = '" + keys + "'>" + x + "</option>");
                    }
                    index++;
                });
            } else {
                for (var k = 0; k < dataSource.length; k++) {
                    var temp = dataSource[k][selectOption.SelValue];
                    if (temp == "undefined") console.log(`reateSelectElement 中dataSource  为空,目前值支持读取的枚举数据!${selectOption.SelType} `);
                    if (k == 0 && selectOption.isFirstSelected) {
                        tempArr.push("<option selected value = '" + temp + "'>" + dataSource[k][selectOption.SelLabel] + "</option>");
                    } else {
                        tempArr.push("<option value = '" + temp + "'>" + dataSource[k][selectOption.SelLabel] + "</option>");
                    }
                }
            }
        }
        //写入元素
        for (var i = 0; i < selectOption.Dom.length; i++) {
            if (selectOption.Dom[i].length === 0) continue;
            selectOption.Dom[i].empty();
            selectOption.Dom[i].append(tempArr.join(""));
            for (var j = 0; j < selectOption.Dom[i].length; j++) {
                selectOption.Dom[i][j].setAttribute("lay-search", "");
            }
        }
        if (isRender) form.render('select');
    }

    // 字典数组对象查询 通过属性 Property
    u.prototype.arrFilterByProperty = function (property, propertyValue) {
        if (window.top.sysDic.data == null) {
            window.top.sysDic.method();
        }
        return window.top.sysDic.data.filter(item => item[property] === propertyValue);
    }

    //文本框下拉表格 checkedKey和key必须一致:表格的主键,lableName:文本显示的元素dom
    u.prototype.initSelectTable = function (parameter) {
        var i = this;
        var searchPlaceholder = parameter["searchPlaceholder"] == undefined ? "名称搜索" : parameter.searchPlaceholder;
        let doneKey = parameter["doneKey"],
            searchKey = parameter["searchKey"],
            page = true,
            par = parameter;
        if (parameter.checkedKey != doneKey.key) {
            var msg1 = `initSelectTable:文本框下拉表格传入参数 checkedKey【${parameter.checkedKey}】和doneKey=>key【${doneKey.key}】表格的主键必须一致!`;
            console.error(msg1);
            layer.alert(msg1, { icon: i.config.iconoError, shadeClose: true, title: i.config.titleError });
            console.error();
            return;
        }
        if ($(parameter.elem).length <= 0) {
            var msg = `initSelectTable:文本框下拉表格传入参数【elem】${parameter.elem} DOM元素不存在请确认!`;
            console.error(msg);
            layer.alert(msg, { icon: i.config.iconoError, shadeClose: true, title: i.config.titleError });
            return;
        }
        if (par["isCache"] == "true") page = false;
        //before 不支持异步 函数
        if (typeof parameter.before != "undefined") {
            var result = parameter.before.call(this, parameter);
            if (!result) return;
        }
        tableSelect.render({
            elem: parameter.elem,
            checkedKey: parameter.checkedKey,
            searchPlaceholder: searchPlaceholder,
            searchKey: searchKey == undefined ? "keyword" : searchKey,
            table: {
                limit: 50,
                limits: [50],
                url: parameter.url,
                page: page,
                where: parameter.where,
                //纠正数据源格式
                parseData: function (res) {
                    var resultData = res;
                    //对缓存数据搜索
                    if (tableSelect.data != null && par["isCache"] === "true") {
                        var keys = Object.keys(tableSelect.data.field);
                        var fieldNmae = keys[0];
                        if (keys.length > 0 && $.trim(tableSelect.data.field[fieldNmae]).length > 0) {
                            resultData.Result = resultData.Result.filter(x => {
                                var value = tableSelect.data.field[fieldNmae];
                                return x[keys].indexOf(value) > -1;
                            });
                        }
                    }
                    if (resultData.length === 0) {
                        return { code: 0, msg: "查询无数据", count: 0, data: null };
                    } else if (resultData.Code === 0) {
                        return resultData;
                    }
                    else {
                        return {
                            Code: resultData.Code,
                            Message: resultData.Message,
                            Count: resultData.Count,
                            Result: resultData.Result
                        };
                    }
                },
                method: "post",
                cols: parameter.cols,
            },
            done: function (elem, data, $nowElem,otherObj) {
                var keys = data.data.map((obj) => { return obj[doneKey.key] }).join(",");
                $nowElem.val(keys);
                $nowElem.attr("ts-selected", keys);

                var lableValues = data.data.map((obj) => { return obj[doneKey.lableValue] }).join(",");
                //显示名称
                $nowElem.next(doneKey.lableName).val(lableValues);
                //回调函数
                var allData = i.getTableAllData(otherObj.tableId)
                parameter.doneExtend && parameter.doneExtend.call(this, elem, data, $nowElem, otherObj);
            }
        });
    }

    //员工下拉表格 isCache true取的是缓存 启用js搜索
    u.prototype.initSelectUser = function (parameter) {
        var i = this;
        var objs = $.extend({
            url: "/HomeRedis/GetBaseInfoByKey?key=user",
            isCache: "true",
            searchPlaceholder: "员工名称",
            cols: [[
                { type: "checkbox", fixed: true },
                { field: "id", width: 80, title: "Id" },
                { field: "account", width: 160, title: "员工编码" },
                { field: "name", width: 150, title: "员工名称" }]]

        }, parameter);
        i.initSelectTable(objs);
    }
    
    //设备VPN下拉表格
    u.prototype.initVpnList = function (parameter) {
        var i = this;
        var objs = $.extend({
            url: "/Base/BaseVpn/Load",
            searchPlaceholder: parameter.searchName == null ? "VPN账号" : parameter.searchName,
            cols: [[
                { type: "checkbox", fixed: true },
                { field: "id", width: 80, hide: true, title: "Id", hide: true },
                { field: "vpnKey", width: 150, title: "vpnKey", hide: true },
                { field: "vpnNumber", width: 150, title: "VPN账号" },
                { field: "ip", width: 150, title: "VPN-IP" },
                { field: "virtualIP", width: 150, title: "虚拟IP" },
                { field: "remark", width: 150, title: "备注" },
                { field: "createTime", width: 150, title: "创建时间" },
                { field: "createBy", width: 150, title: "创建人" }
            ]]
        }, parameter);
        i.initSelectTable(objs);
    }

    //设备网关下拉表格
    u.prototype.initGatewayList = function (parameter) {
        var i = this;
        var objs = $.extend({
            url: "/Base/BaseGateway/Load",
            searchPlaceholder: parameter.searchName == null ? "网关账号" : parameter.searchName,
            cols: [[
                { type: "checkbox", fixed: true },
                { field: "id", width: 80, title: "Id", hide: true },
                { field: "gatewayKey", width: 150, title: "gatewayKey", hide: true },
                { field: "gatewaySerialNumber", width: 200, title: "网关序列号" },
                { field: "gatewayClient", width: 150, title: "网关客户" },

                { field: "virtualIP", width: 150, title: "VPN虚拟IP" },
                { field: "vpnNumber", width: 150, title: "VPN账号" },
                { field: "simId", width: 150, title: "SIM卡ID" },
                { field: "simNumber", width: 150, title: "SIM卡账号" },
                { field: "remark", width: 150, title: "备注" },

                { field: "createTime", width: 150, title: "创建时间" },
                { field: "createBy", width: 150, title: "创建人" },
            ]]
        }, parameter);
        i.initSelectTable(objs);
    }

    //初始化日期控件 dateFormat 时间格式 默认 datetime,type=time
    var fn1 = [];
    u.prototype.initDate = function (fn) {
        if (fn != null && typeof fn != "undefined") {
            fn1.push(fn);
        }
        $(".layui-date").each(function () {
            let thisInfo = $(this),
                type = thisInfo.attr("time") || thisInfo.attr("typeTime"),
                format = thisInfo.attr("dateFormat"),
                showBottom = thisInfo.attr("showBottom");
            var laydateObj = {
                elem: this,
                btns: ["confirm"],
                calendar: true,
                trigger: "click",
                done: function (value, date, endDate) {
                    if (fn1.length <= 0) return;
                    for (var i = 0; i < fn1.length; i++) {
                        fn1[i](value, date, endDate, thisInfo);
                    }
                }
            };
            if (format != undefined) laydateObj["format"] = format;
            if (showBottom != undefined) laydateObj["showBottom"] = showBottom;
            if (type != undefined) laydateObj["type"] = type;
            laydate.render(laydateObj);
        });
    }

    //防抖
    u.prototype.debounce = function (fn, delay) {
        let timeout = null;
        return function () {
            clearTimeout(timeout);
            timeout = setTimeout(() => {
                fn.apply(this, arguments);
            }, delay);
        };
    }

    //轮播图 sysU.initCarousel(["","",""]);
    u.prototype.initCarousel = function (img) {
        var arr = [],
            height = 560,
            width = 750,
            area = ["750px", "600px"],
            parameter = action["carouselOptions"],
            carouselId = Number(Math.random().toString().substr(3, 3) + Date.now()).toString(36);
        arr.push(`<div class="layui-carousel" id='${carouselId}'> <div carousel-item='' style="margin-left:-1.6vw">`);
        for (var i = 0; i < img.length; i++) {
            if (img[i] == "" || img[i] == null) continue;
            arr.push(` <div><img src="${img[i]}" style='width:100%;height:100%' /></div>`);
        }
        arr.push("</div></div>");
        if (parameter != undefined) {
            parameter = parameter();
            height = parameter.height;
            width = parameter.width;
            area = parameter.area;
        }
        layer.open({
            title: null,
            content: arr.join(" "),
            area: area,
            btn: null,
            success: function (layero, index) {
                var objs = $.extend({
                    elem: "#" + carouselId,
                    height: height,
                    width: width,
                    autoplay: true,
                    arrow: "always"
                }, parameter);
                carousel.render(objs);
            }
        });
    }

    //流加载;
    u.prototype.initFlow = function (parameter) {
        if (typeof flow == "undefined") return false;
        flow.load({
            elem: parameter.elem,
            done: function (page, next) {
                var lis = [];
                if (typeof parameter.ajax != "undefined") {
                    parameter.data["page"] = page;
                    sU.ajax(parameter.ajax);
                }
                next("xxx", page < 10);
            }
        });
    }

    //调用父页面方法, 用于子页面调用父页面方法;
    u.prototype.initParentEvent = function (obj) {
        var parDoc = parent.$(window.parent.document);
        if (parDoc == null || parDoc.length == 0) {
            console.log("initParentEvent:parDoc is null");
            return false;
        }
        parent.$(window.parent.document).trigger('props', obj);
    }

    //父页面监听子页面注册 props 事件(action["WatchChild"]);
    u.prototype.initWatchChild = function () {
        $document.on('props', function (event, obj) {
            if (typeof action == "undefined") {
                console.log("initWatchChild:action is null");
                return false;
            }
            action["WatchChild"].call(this, event, obj);
            var openIndex = localStorage.getItem("openIndex");
            layer.close(openIndex);
        });
    }

    //获取页面高度 用于:需要动态设置高度
    u.prototype.getFrameHeight = function () {
        return $document.height();
    }

    //将分钟转换成x天x小时x分钟
    u.prototype.getMinutesIntoTime = function (value) {
        var values = '';
        var day = parseInt(value / 1440);
        var hour = parseInt(value % 1440 / 60);
        var minute = parseInt(value % 1440 % 60);
        if (day > 0) {
            values += day + '天';
        }
        if (hour > 0) {
            values += hour + '小时';
        }
        if (minute > 0) {
            values += minute + '分钟';
        }
        return values == '' ? '0分钟' : values;
    }


    //公共事件用于全局、system方法调用、外部js不要使用
    u.prototype.initRegisterEvent = function () {
        var i = this;
        $('body').on('click', '.layui-table-grid-down .layui-icon-down', function () {
            setTimeout(function () {
                var div = document.getElementsByClassName('layui-table-tips-main')[0];
                if (document.body.createTextRange) {
                    let range = document.body.createTextRange();
                    range.moveToElementText(div);
                    range.select();
                } else if (window.getSelection) {
                    var selection = window.getSelection();
                    let range = document.createRange();
                    range.selectNodeContents(div);
                    selection.removeAllRanges();
                    selection.addRange(range);
                } else {
                    console.warn("none");
                }
                document.execCommand("Copy");
                //layer.alert("文本内容已复制好,可贴粘使用。", { icon: 6, shade: 0.4, time: i.config.msgOpenTime });
            });
        });
    }

    /**
     * 表单验证 手动调用
     * @param {*} formId 表单所在容器id
     * @returns 是否通过验证
     */
    u.prototype.VerifyForm = function (formId) {
        var stop = null,  //验证不通过状态
            verify = layui.form.config.verify,  //验证规则
            DANGER = 'layui-form-danger',  //警示样式
            formElem = $('#' + formId),  //当前所在表单域
            verifyElem = formElem.find('*[lay-verify]'),  //获取需要校验的元素
            device = layui.device();

        //开始校验
        layui.each(verifyElem, function (_, item) {
            var othis = $(this),
                vers = othis.attr('lay-verify').split('|'),
                verType = othis.attr('lay-verType'),//提示方式
                value = othis.val();

            othis.removeClass(DANGER); //移除警示样式

            //遍历元素绑定的验证规则
            layui.each(vers, function (_, thisVer) {
                var isTrue, //是否命中校验
                    errorText = '', //错误提示文本
                    isFn = typeof verify[thisVer] === 'function';
                //匹配验证规则
                if (verify[thisVer]) {
                    isTrue = isFn ? errorText = verify[thisVer](value, item) : !verify[thisVer][0].test(value);
                    errorText = errorText || verify[thisVer][1];
                    if (thisVer === 'required') {
                        errorText = othis.attr('lay-reqText') || errorText;
                    }
                    //如果是必填项或者非空命中校验,则阻止提交,弹出提示
                    if (isTrue) {
                        //提示层风格
                        if (verType === 'tips') {
                            layer.tips(errorText, function () {
                                if (typeof othis.attr('lay-ignore') !== 'string') {
                                    if (item.tagName.toLowerCase() === 'select' || /^checkbox|radio$/.test(item.type)) {
                                        return othis.next();
                                    }
                                }
                                return othis;
                            }(), { tips: 1 });
                        } else if (verType === 'alert') {
                            layer.alert(errorText, { title: '提示', shadeClose: true });
                        } else {
                            layer.msg(errorText, { icon: 5, shift: 6 });
                        }
                        //非移动设备自动定位焦点
                        if (!device.android && !device.ios) {
                            setTimeout(function () {
                                item.focus();
                            }, 7);
                        }
                        othis.addClass(DANGER);
                        return stop = true;
                    }
                }
            });
            if (stop) return stop;
        });
        if (stop) return false;
        return true;
    }

    /**
    * 刷新head,删除操作刷新主子表
    */
    u.prototype.refreshTable = function (app, sysU, sendDataDesc, falg, callBack) {
        //主表    
        if (falg.indexOf(descSuffix) == -1&& falg.indexOf(footerSuffix)==-1) {
            sysU.refreshHead(app, sysU, sendDataDesc, falg);
        }
        //子表
        else if (falg.indexOf(descSuffix) > -1) {
            sysU.refreshTableDesc(app, sysU, sendDataDesc, falg);
        }
        if (callBack != null) callBack();
    },

    /**
    * 刷新head,删除操作刷新主子表
    */
    u.prototype.refreshHead = function (app, sysU, sendDataDesc, falg) {
        if (falg == "delete") {
            if (sysU.getTableAllData(app.data.tableElem).length == 0) {
                app.data.tableIns.config.where = {};
                app.data.tableIns.config.page.curr = app.data.tableIns.config.page.curr;
                app.data.tableIns.reload(app.data.tableElem, {});
            }

            if (sendDataDesc != null) sysU.refreshTableDesc(app, sysU, sendDataDesc, falg);
        }
        if (sysU.getTableAllData(app.data.tableElem).length == 0) {
            app.data.tableIns.config.where = sendDataDesc;
            app.data.tableIns.config.page.curr = app.data.tableIns.config.page.curr;
            app.data.tableIns.reload(app.data.tableElem, sendDataDesc);
        }
        //修复页面搜索后,在新增数据成功后刷新列表(ps:layui 表格自身bug导致)
        var ele = $("#" + app.data.tableElem).next().children(".layui-table-page").find(".layui-icon-refresh");
        if (ele.length == 0) {
            app.data.tableIns.config.where = sendDataDesc;
            app.data.tableIns.config.page.curr = app.data.tableIns.config.page.curr;
            app.data.tableIns.reload(app.data.tableElem, sendDataDesc);
        } else {
            ele.click()
        }
    },

    /**
        * 刷新子表
    */
    u.prototype.refreshTableDesc = function (app, sysU, sendDataDesc) {
        if (typeof app.data.tableInsDesc != "undefined" && app.data.tableInsDesc != null) {
            if (sysU.getTableAllData(app.data.tableElemDesc).length == 0) {
                app.data.tableInsDesc.config.where = sendDataDesc;
                app.data.tableInsDesc.config.page.curr = app.data.tableInsDesc.config.page.curr;
                app.data.tableInsDesc.reload(app.data.tableElemDesc, {});
            }
            //修复页面搜索后,在新增数据成功后刷新列表(ps:layui 表格自身bug导致)
            var ele = $("#" + app.data.tableElemDesc).next().children(".layui-table-page").find(".layui-icon-refresh");
            if (ele.length == 0) {
                app.data.tableInsDesc.config.where = sendDataDesc;
                app.data.tableInsDesc.config.page.curr = app.data.tableInsDesc.config.page.curr;
                app.data.tableInsDesc.reload(app.data.tableElemDesc, {});
            } else{
                ele.click()
            }
        }
    }

    /**
     * 打开新页面
    */
    u.prototype.openPage = function (config) {
        //默认参数
        var opt = {
            title: "新增",
           /* fromFlag:n,*/
            //checkTableRowDataCount:1,//选择表格行数据 ,确定按钮返回选择行的数据
            type: 1,//0(信息框)1( $('#modifyRateForm' ) 默认)2(iframe层  页面url地址 常用)3(加载层)4(tips层)
            btn: null,//['保存', '关闭']
            area: ["750px", "500px"]
        };
        Object.assign(opt, config)
        layer.open({
            title: opt.title,
            area: opt.area,
            maxmin: true,
            type: opt.type,
            content: opt.content,
            btn: opt.btn,
            end: function (index, layero) {
                if (opt.endCallBackFn) opt.endCallBackFn()
            },
            success: function (layero, index) {
                if (config["iframeAddHeight"]) {
                    var he = document.querySelector("iframe").style.height;
                    var resultHe = parseInt(he.replace("px", "")) + 10 + "px";
                    document.querySelector("iframe").style.height = resultHe
                }
                if (opt.successCallBackFn) opt.successCallBackFn(layero, index)
            },
            yes: function (index, layero) {
                if (!opt.yesCallBackFn) {
                    layer.close(index);
                    return false;
                }
                //返回当前选中表格行数
                var rowDataAll = null;
                if (typeof (opt["checkTableRowDataCount"]) != "undefined") {
                    rowDataAll = JSON.parse(localStorage.getItem("checkTableALLRowData"))
                    if (rowDataAll.length != 1 && opt["checkTableRowDataCount"] == 1) {
                        layer.alert(sU.config.titleSelectOne, { icon: sU.config.iconoError, shade: 0.4, time: sU.config.errorTime });
                        return false;
                    }
                    else if ((rowDataAll.length == 0 || rowDataAll == "null") && opt["checkTableRowDataCount"] > 1) {
                        layer.alert(sU.config.titleSelectOneRowData, { icon: sU.config.iconoError, shade: 0.4, time: sU.config.errorTime });
                        return false;
                    }
                } else if (opt["fromFlag"] != null) {
                }
                //执行yes 父页面的方法 ,并将值回传过去
                if (opt.yesBeforeCallBackFn != null) {
                    var result = opt.yesBeforeCallBackFn(index, layero);
                    if (result=="-1") return;
                    opt.yesCallBackFn(result, function () {
                        layer.close(index);
                    })
                    return false
                }
                opt.yesCallBackFn(rowDataAll, function () {
                    layer.close(index);
                })                
            }
        });

    }

    /**
     * 打开新页面
    */
    u.prototype.tabClick = function (tabfilterEle) {
        element.on(`tab(${tabfilterEle})`, function (data) {
            if (data.index == 0) {
                systemAction.config.panelSearchDesc.hide();
                systemAction.config.panelSearchFooter.hide();  
            } else if (data.index == 1) {
                systemAction.config.panelSearch.hide();
                systemAction.config.panelSearchFooter.hide();  
            } else if (data.index == 2) {
                systemAction.config.panelSearch.hide();
                systemAction.config.panelSearchDesc.hide();  
            }
        });
    }

    /**
     * PdF预览 第一位不需要?号
    */
    u.prototype.pdfPreview = function (url = "sampleDemo.pdf") {
        if (url.indexOf("pdf") == -1) {
            alert("pdf预览url后缀需要包含pdf名称!")
            return;
        }
        window.open("/htmlTemp/pdf.html?" + url, "pdf预览");  
    }

    /**
     * 获取父页面元素
    */
    u.prototype.getParentElemId = function (id) {
        return window.parent.document.getElementById(id);
    }

    /**
     * 全局枚举访问对象
    */
    u.prototype.sysEnumData = sysEnumData

    /*btn 
        * action 是对应引入js 全局变量配置
    */
    sU = new u();
    systemAction = {
        config: {
            panelSearch: $("#panelSearch"),
            panelSearchDesc: $("#panelSearchDesc"),
            panelSearchFooter: $("#panelSearchFooter")
        },

        btnAdd: (sysU, toolbarId, obj, $event) => {
            var parm = null, before = null, addSaveBefore = null, actionSuccessFlag = null;
            if (toolbarId.indexOf(descSuffix) > -1) {
                parm = action.addOptionsDesc(sysU, toolbarId, obj, $event);
                before = action["addBeforeDesc"];
                addSaveBefore = action["addSaveBeforeDesc"];
                actionSuccessFlag = "addDesc";
                parm["btnOpenYes"] = "button[name=fromAddDesc]";
            } else {
                parm = action.addOptions(sysU, toolbarId, obj, $event);
                before = action["addBefore"];
                addSaveBefore = action["addSaveBefore"];
                actionSuccessFlag = "add";
                parm["btnOpenYes"] = "button[name=fromAdd]";
            }
            parm["title"] = sysU.config.titleAdd + (parm["title"] == undefined ? "" : parm["title"]);
            //成功回调函数
            parm.success = function (index) {
                let addOpenIndex = index;
                form.on(parm.submit, function (data) {
                    var result = sysU.requiredExtend(data.form);
                    if (!result) return false;
                    function ajax() {
                        var ajaxConfig = {
                            data: { entity: data.field },
                            url: parm.url,
                            success: function (result) {
                                if (sysU.successBefore(result)) return false;
                                layer.close(addOpenIndex);
                                $(parm.fromId)[0].reset();
                                layer.msg(sysU.config.titleAddSuccess, { icon: sysU.config.iconoOk, shade: 0.4, time: sysU.config.msgOpenTime });
                                $("#" + toolbarId).next().children(".layui-table-page").find(".layui-icon-refresh").click();
                                if (action["actionSuccess"] !== undefined) action["actionSuccess"].call(null, actionSuccessFlag);
                            }
                        };
                        sysU.ajax(ajaxConfig);
                    }
                    if (addSaveBefore === undefined) {
                        ajax();
                        return false;
                    }
                    addSaveBefore.call(null, data, function () { ajax() });
                    return false;
                });
            }

            if (before == undefined) {
                sysU.openAddOrEdit(parm, sysU);
                return false;
            }
            before.call(null, function () { sysU.openAddOrEdit(parm, sysU); });
            return false;
        },

        btnCopyAdd: (sysU, toolbarId, obj, $event) => {
            var checkStatus = table.checkStatus(toolbarId),
                flagKey ="btnCopyAdd",
                //选中的行数
                selectRow = checkStatus.data.length;
            if (selectRow === 0 || selectRow > 1) {
                layer.alert(`请选择一条数据后,在复制新增。当前选择的行数【${selectRow}】条!`, { icon: sysU.config.iconoError, shadeClose: true, title: "错误信息" });
                return false;
            }
            if (toolbarId.indexOf(descSuffix) > -1) {
                parm = action.addOptionsDesc(flagKey, toolbarId, obj, $event);
                editBefore = action["editBeforeDesc"];
                before = action["addBeforeDesc"];
                addSaveBefore = action["addSaveBeforeDesc"];
                actionSuccessFlag = "addDesc";
                parm["btnOpenYes"] = "button[name=fromAddDesc]";
            } else {
                parm = action.addOptions(flagKey,  toolbarId, obj, $event);
                editBefore = action["editBefore"];
                before = action["addBefore"];
                addSaveBefore = action["addSaveBefore"];
                actionSuccessFlag = "add";
                parm["btnOpenYes"] = "button[name=fromAdd]";
            }
            parm["title"] = sysU.config.titleCopyAdd + (parm["title"] == undefined ? "" : parm["title"]);
            //成功回调函数
            parm.success = function (index) {
                let addOpenIndex = index;
                form.on(parm.submit, function (data) {
                    var result = sysU.requiredExtend(data.form);
                    if (!result) return false;
                    function ajax() {
                        var ajaxConfig = {
                            data: { entity: data.field },
                            url: parm.url,
                            success: function (result) {
                                if (sysU.successBefore(result)) return false;
                                layer.close(addOpenIndex);
                                $(parm.fromId)[0].reset();
                                layer.msg(sysU.config.titleAddSuccess, { icon: sysU.config.iconoOk, shade: 0.4, time: sysU.config.msgOpenTime });
                                $("#" + toolbarId).next().children(".layui-table-page").find(".layui-icon-refresh").click();
                                if (action["actionSuccess"] !== undefined) action["actionSuccess"].call(null, actionSuccessFlag);
                            }
                        };
                        sysU.ajax(ajaxConfig);
                    }
                    if (addSaveBefore === undefined) {
                        ajax();
                        return false;
                    }
                    addSaveBefore.call(null, data, function () { ajax() }, flagKey);
                    return false;
                });
            }

            if (before == undefined) {
                layer.alert("【复制新增】请先配置addBeforeXXX配置!", { icon: sysU.config.iconoError, shade: 0.4, time: sysU.config.errorTime });
                return false;
            }
            before.call(null, function () {
                editBefore.call(null, checkStatus.data[0], function () {
                    sysU.openAddOrEdit(parm, sysU);
                }, flagKey);
            }, flagKey);
            return false;
        },

        btnEdit: function (sysU, toolbarId, obj, $event) {
            var checkStatus = {};
            if (!table.checkStatus) {
                checkStatus["data"] = [action.rowData];
            } else {
                checkStatus = table.checkStatus(toolbarId);
            }
            var selectRow = checkStatus.data.length;//选中的行数
            if (selectRow === 0 || selectRow > 1) {
                layer.alert(`请选择一条数据后,再编辑。当前选择的行数【${selectRow}】条!`, { icon: sysU.config.iconoError, shadeClose: true, title: "错误信息" });
                return false;
            }
            var parm = null, before = null, editSaveBefore = null, actionSuccessFlag = null;
            if (toolbarId.indexOf(descSuffix) > -1) {
                parm = action.editOptionsDesc(checkStatus.data[0],sysU, toolbarId, obj, $event);
                before = action["editBeforeDesc"];
                editSaveBefore = action["editSaveBeforeDesc"];
                actionSuccessFlag = "editDesc";
                parm["btnOpenYes"] = "button[name=fromUpdateDesc]";
            } else {
                parm = action.editOptions(checkStatus.data[0], sysU, toolbarId, obj, $event);
                before = action["editBefore"];
                editSaveBefore = action["editSaveBefore"];
                actionSuccessFlag = "edit";
                parm["btnOpenYes"] = "button[name=fromUpdate]";
            }
            parm["title"] = sysU.config.titleEdit + (parm["title"] == undefined ? "" : parm["title"]);
            var fromId = $(parm.fromId);
            if (fromId.length === 0) {
                layer.alert(`btnEdit方法,表单节点${parm.fromId}不存在!请核实xxx.cshtml页面!`, { icon: sysU.config.iconoError, shadeClose: true, title: "错误信息" });
                return false;
            }
            $(parm.fromId)[0].reset();

            parm.success = function (index) {
                let addOpenIndex = index;
                form.on(parm.submit, function (data) {
                    var result = sysU.requiredExtend(data.form);
                    if (!result) return false;
                    function ajax() {
                        var ajaxConfig = {
                            data: { entity: data.field },
                            url: parm.url,
                            success: function (result) {
                                if (sysU.successBefore(result)) return;
                                layer.close(addOpenIndex);
                                layer.msg(sysU.config.titleUpdateSuccess, { icon: sysU.config.iconoOk, shade: 0.4, time: sysU.config.msgOpenTime });
                                $("#" + toolbarId).next().children(".layui-table-page").find(".layui-icon-refresh").click();
                                if (action["actionSuccess"] !== undefined) action["actionSuccess"].call(null, actionSuccessFlag);
                            }
                        };
                        sysU.ajax(ajaxConfig);
                    }
                    if (editSaveBefore === undefined) {
                        ajax();
                        return false;
                    }
                    editSaveBefore.call(null, data, function () { ajax() });
                    return false;
                });
            }
            if (before == undefined) {
                sysU.openAddOrEdit(parm, sysU);
                return false;
            }
            before.call(null, checkStatus.data[0], function () { sysU.openAddOrEdit(parm, sysU) });
            return false;
        },

        btnDelete: (sysU, toolbarId, obj, $event) => {
            var checkStatus = {};
            if (!table.checkStatus) {
                checkStatus["data"] = [action.rowData] ;
            } else {
                checkStatus = table.checkStatus(toolbarId);
            }
            var parm = null, before = null;
            if (toolbarId.indexOf(descSuffix) > -1) {
                parm = action.deleteOptionsDesc(sysU, toolbarId, obj, $event);
                before = action["deleteBeforeDesc"];
                parm["actionSuccessFlag"] = "deleteDesc";
            } else {
                parm = action.deleteOptions(sysU, toolbarId, obj, $event);
                before = action["deleteBefore"];
                parm["actionSuccessFlag"] = "delete";
            }
            parm["toolbarId"] = toolbarId;

            if (checkStatus.data.length === 0) {
                layer.alert(sysU.config.titleSelectOneRowData, { icon: sysU.config.iconoError, shadeClose: true, title: sysU.config.titleSelectOneRowData });
                return false;
            }
            if (before == undefined) {
                sysU.deleteConfirm(parm, sysU, checkStatus.data);
                return false;
            }
            before.call(null, checkStatus.data, function () { sysU.deleteConfirm(parm, sysU, checkStatus.data) });
        },

        btnRefresh: (sysU, toolbarId) => {
            //actionSuccess 删除需要刷新,其他的不需要 
            var flag = toolbarId == null ? "" : toolbarId.indexOf(descSuffix) > -1 ? "refreshDesc" : "refresh";
            sU.config.btnRefreshLoadIndex = layer.load(0); //添加laoding,0-2两种方式
            var refreshElem = $("#" + toolbarId).next(),
                pageArr = refreshElem.attr("lay-filter").split('-'),
                lastPage = pageArr[pageArr.length - 1];
            //var pageElem = "#layui-table-page" + lastPage,
            //    $pageElem = $(pageElem).find(".layui-icon-refresh");
            //if ($pageElem.length > 0) {
            //    $pageElem.click();
            //} 
			layer.close(sU.config.btnRefreshLoadIndex);
            if (action["actionSuccess"] !== undefined) action["actionSuccess"].call(null, flag, toolbarId);
        },

        btnSelect: (sysU, toolbarId) => {
            if (toolbarId.indexOf(descSuffix) > -1) {
                if (systemAction.config.panelSearchDesc.length == 0) {
                    console.log("检索按钮未找到,元素节点为panelSearchDesc,如不需要,模块配置删除此按钮!");
                }
                systemAction.config.panelSearchDesc.toggle("fast");
            } else if (toolbarId.indexOf(footerSuffix) > -1) {
                if (systemAction.config.panelSearchFooter.length == 0) {
                    console.log("检索按钮未找到,元素节点为panelSearchFooter,如不需要,模块配置删除此按钮!");
                }
                systemAction.config.panelSearchFooter.toggle("fast");
            } else {
                if (systemAction.config.panelSearch.length == 0) {
                    console.log("检索按钮未找到,元素节点为panelSearch,如不需要,模块配置删除此按钮!");
                }
                systemAction.config.panelSearch.toggle("fast");
            }
        },

        btnUpload: (sysU, toolbarId, tableObj) => {
            var parm = null, before = null,
                uploadSaveBefore = null, actionSuccessFlag = null;
            if (toolbarId.indexOf(descSuffix) > -1) {
                parm = action.uploadOptionsDesc();
                before = action["uploadBeforeDesc"];
                uploadSaveBefore = action["uploadSaveBeforeDesc"];
                actionSuccessFlag = "uploadDesc";
            } else {
                parm = action.uploadOptions();
                before = action["uploadBefore"];
                uploadSaveBefore = action["uploadSaveBefore"];
                actionSuccessFlag = "upload";
            }
            if (typeof parm.content == "undefined") {
                console.log("btnUpload 方法 uploadOptions 参数不存在 content ");
                return false;
            }
            if (parm.content.length==0) {
                layer.alert(`btnUpload方法 参数,parameter.content 节点${parm.content.selector}不存在!`, { icon: 2, shadeClose: true, title: sysU.config.titleError });
                return false;
            }
            let title = parm.title;
            if (typeof parm.title == "undefined") {
                title = "请选择导入的文件<span style=\"color:red;font-weight: bold;\">(时间可能比较久,请耐心等待...)</span>";
            }
            var area = parm["area"] == undefined ? ['420px', '300px'] : parm.area;
            //是否要选择数据 上传
            var selectRow = table.checkStatus(toolbarId);
            if (selectRow.data.length != 1) {
                layer.alert(sysU.config.titleSelectOne, { icon: sysU.config.iconoError, shadeClose: true, title: "错误信息" });
                return false;
            }
            if (selectRow.data.length === 0) {
                //'#modifyForm form'
                var keyEle = "#" + parm.content[0].id + " form"
                if ($(keyEle).length > 0) $(keyEle)[0].reset();
            }
            $(parm.fromFile).val("");
            if (before != undefined) {
                var result = before.call(null, selectRow, parm, () => { form.val(parm.content[0].id, selectRow.data[0]);});
                if (typeof result != "undefined" && !result) return false;
            } else {
                form.val(parm.content[0].id, selectRow.data[0]);
            }
            layer.open({
                type: 1,
                skin: "layui-layer-molv",
                anim: 1,
                id: "LAY_layuipro", //设定一个id,防止重复弹出
                moveType: 1, //拖拽模式,0或者1
                title: title, //不显示标题
                area: area, //宽高
                content: parm.content, //捕获的元素
                scrollbar: false,
                btn: ['导入', '关闭'],
                yes: function (index) {
                    var index1 = layer.load();
                    let tempId = parm.fromFile.replace("#", "");
                    var fileEle = document.getElementById(tempId); // js 获取文件对象
                    if (fileEle == null) {
                        layer.alert(`上传配置文件元素节点【${tempId}】不存在`, { skin: 'layui-layer-molv', anim: 1, icon: sysU.config.iconoError });
                        layer.close(index1);
                        return false;
                    }
                    var fileObj = fileEle.files;
                    //上传和编辑使用同一方法,此处在后端进行验证
                    //if (typeof (fileObj) == "undefined" || fileObj.length <= 0) {
                    //    layer.alert("请先选择需要上传的文件!", { skin: 'layui-layer-molv', anim: 1, icon: sysU.config.iconoError });
                    //    layer.close(index1);
                    //    return false;
                    //}
                    var formFile = new FormData(),
                        keys = "excelfile";
                    for (var i = 0; i < fileObj.length; i++) {
                        formFile.append(keys, fileObj[i]); //加入文件对象
                    }
                    //填充表单值
                    var fromValue = form.val(parm.content[0].id);
                    delete fromValue.excelfile;
                    var allFormNamekeys = Object.keys(fromValue);
                    for (var item in allFormNamekeys) {
                        if (!Object.prototype.hasOwnProperty.call(keys, item)) continue;
                        var closName = allFormNamekeys[item],
                            val = fromValue[closName];
                        formFile.append(closName, val);
                    }

                    function ajax() {
                        var ajaxConfig = {
                            data: formFile,
                            url: parm.url,
                            timeout: 300000,//超时5分钟
                            cache: false,//上传文件无需缓存
                            processData: false,//用于对data参数进行序列化处理 这里必须false
                            contentType: false, //必须
                            success: function (result) {
                                if (sysU.successBefore(result)) return;
                                layer.msg(result.Message, { icon: sysU.config.iconoOk, shade: 0.4, time: sysU.config.msgOpenTime });
                                if (action["actionSuccess"] !== undefined) action["actionSuccess"].call(null, actionSuccessFlag);
                                setTimeout(() => { layer.closeAll(); }, 2000);
                            }
                        };
                        sysU.ajax(ajaxConfig);
                    }
                    if (uploadSaveBefore === undefined) {
                        ajax();
                        return false;
                    }
                    uploadSaveBefore.call(null, { formFile, parm, closeIndex: index1, keys: keys }, selectRow, function () { ajax() });
                },
                cancel: function (index) {
                    layer.close(index);
                }
            });
        },

        btnExport: (sysU, toolbarId, tableObj) => {
            var parm = action.exportOptions(),
                data = form.val(parm.fromId);
            data["Exel"] = true;
            //附加查询条件 exportOptions: sendDataWhere
            if (typeof (parm.sendDataWhere) != "undefined") {
                var allKeys = Object.keys(parm.sendDataWhere);
                for (var tempKey in allKeys) {
                    if (Object.prototype.hasOwnProperty.call(allKeys, tempKey)) {
                        let resultKey = allKeys[tempKey];
                        data[resultKey] = parm.sendDataWhere[resultKey];
                    }
                }
            }
            function fnCallBack() {
                var ajaxConfig = $.extend({
                    data: data,
                    url: parm.url,
                    success: function (result) {
                        if (sysU.successBefore(result)) return false;
                        var excelParm = typeof parm.isDefault == "undefined" ? tableObj : parm;
                        //ajax成功之后对数据二次处理
                        if (typeof (parm.ExcelExportFn) != "undefined") {
                            parm.ExcelExportFn(excelParm, result, toolbarId, (function (excelParm, result, toolbarId) {
                                sysU.ExcelExportData(excelParm, result, toolbarId)
                            }));
                        } else {
                            sysU.ExcelExportData(excelParm, result, toolbarId);
                        }
                    }
                }, parm.ajaxOpt);
                sysU.ajax(ajaxConfig);
            }
            var keysMethodName = "btnExportBefore";
            if (action[keysMethodName] !== undefined) {
                action[keysMethodName].call(null, sysU, parm, data, tableObj, fnCallBack);
                return false;
            }
            fnCallBack();
        },

        btnQuery: function (sysU, parameter) {
            var tempTable = table;
            //用于判断是否为树形表格
            if (parameter.isTable == true) {
                tempTable = treeTable;
            }
            let index = layer.load(0);
            if (typeof parameter.isDefault != "undefined" && !parameter.isDefault) {
                var result = parameter.customFn(sysU, parameter);
                if (result != "0" || typeof result == "undefined") systemAction.config.panelSearch.toggle("fast");
                return false;
            }
            var wherepPram = form.val(parameter.fromId);
            if (typeof parameter.sendDataWhere != "undefined" ) {
                $.extend(wherepPram, parameter.sendDataWhere);
            }
            let toolbarId = parameter.mainTable.config.id;
            function fnCallBack() {
                var ajaxConfig = $.extend({
                    page: { curr: 1 },
                    url: parameter.urlQuery,
                    method: "post",
                    where: wherepPram,
                    done: function (x, y, z) {
                        layer.close(index);
                        //回调函数
                        parameter.doneExtend && parameter.doneExtend.call(this, x, y, z);
                    }
                }, parameter.ajaxOpt);
                tempTable.reload(parameter.mainTable.config.id, ajaxConfig);
                systemAction.btnSelect(sysU, toolbarId);
            }
            var keysMethodName = "queryBefore";
            if (action[keysMethodName] !== undefined) {
                action[keysMethodName].call(null, sysU, toolbarId, wherepPram, fnCallBack);
                return false;
            }
            fnCallBack();
        },

        /*
         * 0:layui方式引入 jqprint
         * 1:传统方式引入qrcode.js文件,
         * 2:qrCodeValueKey是二维码值 对应的key
         * 3:customFn 自定义填充的内容显示数据
        */
        btnPrint: (sysU, toolbarId) => {
            var checkStatus = table.checkStatus(toolbarId);
            var parm = null, before = null;
            if (toolbarId.indexOf(descSuffix) > -1) {
                parm = action.qcCodePrintOptionsDesc();
                before = action["qcCodePrintBeforeDesc"];
            } else {
                parm = action.qcCodePrintOptions();
                before = action["qcCodePrintBefore"];
            }
            if (checkStatus.data.length === 0) {
                layer.alert(sysU.config.titleSelectOneRowData, { icon: sysU.config.iconoError, shadeClose: true, title: sysU.config.titleSelectOneRowData });
                return false;
            }
            for (var i = 0; i < checkStatus.data.length; i++) {
                var qcValue = checkStatus.data[i][parm.qrCodeValueKey];
                if (qcValue == null || qcValue == "") {
                    layer.alert(`选择的行数据二维码行号【${i + 1}】key:【${parm.qrCodeValueKey}】值为空!`, { icon: 2, shadeClose: true, title: sysU.config.titleSelectOneRowData });
                    console.error("打印二维码 btnPrint 二维码值对月的值是空:" + parm.qrCodeValueKey);
                    return false;
                }
            }
            if (before == undefined) {
                sysU.printBarCode(parm, sysU, checkStatus.data);
                return false;
            }
            before.call(null, checkStatus.data, function () { sysU.printBarCode(parm, sysU, checkStatus.data) });
        },

        //reset
        btnReset: (sysU, parameter) => { $(parameter.resetFrom)[0].reset(); },

        //close
        btnClose: (sysU, parameter) => {
           // systemAction.btnSelect(sysU, parameter.mainTable.config.id);

            systemAction.config.panelSearchDesc.hide("fast");
            systemAction.config.panelSearchFooter.hide("fast");
            systemAction.config.panelSearch.hide("fast");
        },

        //down
        btnTemplate: (sysU, parameter) => { sysU.exelDownTemplate(parameter.mainTable); },

        tableRowClick: function (obj) {
            if (typeof action == "undefined" || typeof action.rowClickOptions == "undefined") {
                console.log("action is null or action rowClickOptions is null");
                return false;
            }
            var parm = action.rowClickOptions(obj),
                tableId = $(obj.tr[0]).closest(".layui-tab-item").children("table");
            if (tableId.length == 0) {
                element.tabChange(parm.tabfilter, parm.tabId);
                parm.customFn(obj);
            } else {
                tableId = tableId[0].id;
                if (tableId.indexOf(descSuffix) > -1 && typeof action.rowClickOptionsFooter != "undefined") {
                    parm = action.rowClickOptionsFooter();
                    systemAction.config.panelSearchFooter.hide();
                } else {
                    systemAction.config.panelSearch.hide();
                }
                if (!parm.isDefault) {
                    parm.customFn(obj);
                    return false;
                }
                if (tableId === parm.targetTableId) {
                    element.tabChange(parm.tabfilter, parm.tabId);
                    parm.customFn(obj);
                } else {
                    console.log("tableRowClick 没有找到对应的表格targetTableId:" + JSON.stringify(parm));
                }
            }
        }
    }

    sU.initFormEvent();
    sU.initDate();
    sU.initRegisterEvent();
    sU.initWatchChild();
    sU.ajaxError();
    sU.setColumnWidth();
    //外部入口
    var system = {
        u: u,
        /*
        * table 工具栏事件
        */
        registerEvent: function (toolbarId, detailId = "") {
            table.on(`toolbar(${toolbarId})`, function (obj) {
                if (sU.config.ignoreEvent.includes(obj.event)) return false;
                sU.cookieVerification();
                //公共方法 【systemAction】
                var event = systemAction[obj.event];
                if (event != null) event(sU, toolbarId, obj, $(this));
                //自定义方法【action】
                if (event == null && action[obj.event] != null) action[obj.event](sU, toolbarId, obj,$(this));
                if (event == null && action[obj.event] == null) console.error("主表toolbar没有找到对应的方法:" + obj.event +"参数 sU, toolbarId, obj");
            });

            //明细表格
            if (detailId !== "") {
                table.on(`toolbar(${detailId})`, function (obj) {
                    if (sU.config.ignoreEvent.includes(obj.event)) return false;
                    sU.cookieVerification();
                    var event = systemAction[obj.event];
                    if (event != null) event(sU, detailId, obj, $(this));
                    if (event == null && action[obj.event] != null) action[obj.event](sU, detailId, obj, $(this));
                    if (event == null && action[obj.event] == null) console.error("明细表格toolbar没有找到对应的方法:" + obj.event);
                });
            }
        },

        query: () => {
            //查询、重置、关闭
            $("#ImportData .layui-btn,.toolList .layui-btn").unbind('click').click(function () {
                var type = $(this).data('type'),
                    falg = $(this).data('flag');
                if (!type) {
                    console.log("query方法type没有找到对应方法:" + type);
                    return;
                }
                var parm = "";
                if (typeof falg != "undefined") {
                    parm = eval(`action.queryOptions${falg}()`);
                } else {
                    parm = action.queryOptions();
                }
                systemAction[type] ? systemAction[type].call(this, sU, parm) : console.error("query方法type没有找到对应方法:" + type);
            });
        },

		//自定义table tool点击事件(不是table 也想使用公共方法) 需要手动注册事件,默认 【system】.queryExtend();
        //layui-btn-container class下面的layui-btn 元素
        queryExtend: () => {
            $(".layui-btn-container .layui-btn").unbind('click').click(function () {
                var type = $(this).attr("lay-event");
                sU.cookieVerification();
                //公共方法 【systemAction】
                var event = systemAction[type];
                if (event != null) event(sU, "queryExtend", null);
                //自定义方法【action】
                if (event == null && action[type] != null) action[type](sU, null, null);

                if (event == null && action[type] == null)  
                    console.log(`自定义table tool点击事件【lay-event:${type}】为空请留意,业务不需要请忽略!`);
            });
        }
    };
    exports('system', system);
});

///dataSourceKey:数据源 ,comparisonField:数据源属性的值(一般是code) retrunKey:返回字段的值(一般是name) , comparisonValue:具体的值
function GetDicLabel(dataSourceKey, comparisonField, retrunKey, comparisonValue) {
    var temp = SelectorSource[dataSourceKey];
    if (temp == null) {
        console.error(`GetDicLabel 读取数据不存在,dataSourceKey:${dataSourceKey}、comparisonField:${comparisonField}、返回字段:${retrunKey}、当前比较的值:${comparisonValue}、`);
        return comparisonValue;
    }
    var result = "";
    for (var i = 0; i < temp.length; i++) { 
        if (temp[i][comparisonField] != comparisonValue) continue;
        result = temp[i][retrunKey];
    }
    return result;
}

var sbList = {};
function loadMenus(modulecode, areaMenus) {
    var menuFlag = "".GetUrlParam("menuFlag");
    //-2无菜单,用于子页面弹窗公用layui-table-tool
    if (menuFlag == -2) {
        $(".layui-table-tool").remove();
        return "";
    }
    if (sbList[areaMenus] != undefined) { return sbList[areaMenus]; }
    var urlMenu = `/base/SysModule/LoadAuthorizedMenus?modulecode=${modulecode}&AreaMenus=${areaMenus}`;
    var strArr = [];
    $.ajax({
        url: urlMenu,
        success: function (data) {
            if (data === "") { return }
            var elementJosn = JSON.parse(data);
            for (var i = 0; i < elementJosn.length; i++) {
                strArr.push(`<a href='javascript:;' lay-event=${elementJosn[i].DomId} class='layui-btn layui-btn-sm ${elementJosn[i].Class}'>`);
                if (elementJosn[i].Icon != null && elementJosn[i].Icon != '') {
                    strArr.push(`<i class='layui-icon'>${elementJosn[i].Icon}</i>`);
                }
                strArr.push(`${elementJosn[i].Name} </a>`);
            }
            var tempStr = strArr.join("");
            sbList[areaMenus] = tempStr;
            var quanxian = $(".layui-btn-container");
            if (quanxian.length > 1) {
                quanxian.eq(1).append(tempStr);
            } else {
                quanxian.append(tempStr);
            }
        }
    });
}