Greasy Fork is available in English.

fw

对蜂网路由器后台进行优化,1.首页显示温度模块,2.内网主机可单机查看功能,3.防止自动退出登录,4.自动开启ping检测,5.ping检测日志列表处理...

// ==UserScript==
// @name         fw
// @namespace    http://tampermonkey.net/
// @version      0.2.5
// @description  对蜂网路由器后台进行优化,1.首页显示温度模块,2.内网主机可单机查看功能,3.防止自动退出登录,4.自动开启ping检测,5.ping检测日志列表处理...
// @author       005
// @match        *://*/*?PAGE=*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    // 1开启 0关闭
    //----------------------

    // 防止自动退出登录
    const isOnLogin = 1

    // 内网主机单机查看
    const isOnIpCheck = 1

    // 自动开启ping检测
    const isOnPing = 1
    // ping检测日志列表
    const isOnPingLog = 1

    // 点击logo跳转事件
    const isOnLogoTo = 0





























    //----------------------------------------------------------------------------------------------

    const logoToTime = 1500;//logo跳转时间(毫秒)
    const isDev = 0;

    // 权限测试
    {
        // 只读权限禁止放行
        const readonlyAPI = [
            '/dhcp_log_del.htm',
            '/start_upgred.htm',
            '/updateprogress.htm',
            '/update_online_again.htm',
            '/fw_profile_reset.htm',
            '/fw_config_restore.htm',
            '/restart2.htm',
            '/poweroff.htm',
            '/fwlog_ping_del.htm',
            '/action/fwlog_delete.htm',
        ]

        // 只读权限放行
        const whitelistAPI = [
            '/auth',
            '/fw_quit.htm',
            '/is_bind_lan.htm',
            '/hosts_info.htm',
            '/show_connect.htm',
            '/show_connect_exe.htm',
            '/waf_get_server.htm',
            '/waf_get_rule.htm',
            '/waf_get_log.htm',
        ]


        // 请求过滤器
        $.ajaxPrefilter(function (options, originalOptions, jqXHR) {

            if (!'只读权限') {
                for(let i=0;i<readonlyAPI.length;i++){
                    if (options.url.indexOf(readonlyAPI[i]) != -1) {
                        // 阻止请求
                        jqXHR.abort('Request blocked by ajaxPrefilter.')
                        alert('111只读权限')
                        location.reload();
                        return;
                    }
                }

                if (options.data) {
                    let isInterdict = false;
                    for(let i=0;i<whitelistAPI.length;i++){
                        if (options.url.indexOf(whitelistAPI[i]) == -1){
                            isInterdict = true;
                        }else{
                            return;
                        }
                    }
                    if(isInterdict){
                        // 阻止请求
                        jqXHR.abort('Request blocked by ajaxPrefilter.')
                        alert('222只读权限')
                        location.reload();
                    };
                }
            }


        });
    }

    // CSS
    {
        var btnCss = `margin-right:24x;
        display:inline-block;
        cursor:pointer;
        margin-left:10px;
        padding:5px 10px;
        background-color:#26A3E9;
        border-radius:4px;
        color:#fff;
        font-size:12px;
         -webkit-user-select: none;
         -moz-user-select: none;
         -ms-user-select: none;
         user-select: none;
         transition: all .2s linear;`
        var inpCss = `background-color: #ffffff;
        color: #666666;
        font-size: 14px;
        height: 28px;
        line-height: 28px;
        text-indent: 10px;
        width: 198px;
        border: 1px solid #dbdfe6;
        padding: 0;
        border-radius: 4px;`
        var selCss = `border: 1px solid #dbdfe6;
        border-radius: 4px;
        height: 28px;
        line-height: 28px;
        text-indent: 10px;
        width: 100px;
        `
    }


    {
        //防止自动退出登录
        if(isOnLogin){
            setInterval(() => {
                i = 1
            }, 600000)
            sessionStorage.setItem('login', '1')
        }

        //检查ping检测日志是否开启,如未打开检测将自动开启所有wan
        if(isOnPing){
            const toPingTime = 300;
            setTimeout(()=>{
                $.get('/action/ping_check_log_read.htm',(msg1)=>{
                    //console.log(msg1)
                    if(!msg1||msg1.line && msg1.line.length==0){
                        //开启
                        $.get('/action/wan_line_name_show.htm',(msg2)=>{
                            if(msg2.length>0){
                                const linesArr = []
                                for(let i=0;i<msg2.length;i++){
                                    console.log()
                                    if(msg2[i].id.indexOf('WAN')!=-1)linesArr.push(msg2[i].id)
                                }
                                if(1)
                                    setTimeout(()=>{
                                        $.post('/action/ping_check_log_write.htm', {data : JSON.stringify({
                                            url: 'jd.com',
                                            check_num: 100,
                                            line: linesArr
                                        })}, function (res) {
                                            if (res.state == 1) {
                                                message('success','已开启ping检测')
                                                if (location.search.indexOf("?PAGE=ping") !== -1)location.reload();
                                            }
                                        }, 'json');
                                    },toPingTime)
                            }
                        },'json')
                    }
                },'json');
            },toPingTime)

        }



        // 首页
        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        let IndexTime = null
        if (location.search.indexOf("?PAGE=index") !== -1) {
            IndexTime = null
            $.get('/action/env_check.htm', {}, function (msg) {
                // console.log(msg);
                let html = ''
                if (msg.cpu_term < 10 || msg.cpu_term > 85) {
                    html += '<span>CPU温度:&nbsp;&nbsp;&nbsp;&nbsp;[&nbsp;<font style="color:#ff0000;">' + msg.cpu_term + ' ℃</font>&nbsp;]<img src="images/warning.png"  title="温度异常,请及时清理设备,检查设备散热问题。" style="margin-left: 5px;width:14px; height:14px;"></span>';

                    $(".box-B10 p:nth(5)").after(`
    <div class="H10"></div>
    <p class="blk_tit"><span class="info_tit"><span style="cursor:pointer;" onclick="(()=>{window.location='/index.htm?PAGE=env_check'})()" title="点击跳转到环境检测">CPU温度</span></span><span class="blk_txt" id="cpu_term"><font style="color:#ff0000;">${msg.cpu_term} ℃</font><img src="images/warning.png"  title="温度异常,请及时清理设备,检查设备散热问题。" style="margin-left: 5px;width:14px; height:14px;">
    </span></p>
                                  `)
                } else {
                    html += '<span>CPU温度:&nbsp;&nbsp;&nbsp;&nbsp;[&nbsp;<font style="color:#59CBA0">' + msg.cpu_term + ' ℃</font>&nbsp;]</span>';
                    $(".box-B10 p:nth(5)").after(`
    <div class="H10"></div>
    <p class="blk_tit"><span class="info_tit"><span style="cursor:pointer;" onclick="(()=>{window.location='/index.htm?PAGE=env_check'})()" title="点击跳转到环境检测">CPU温度</span></span><span class="blk_txt" id="cpu_term">${msg.cpu_term} ℃
    </span></p>
                                  `)
                }

                $(".box-B10 p:last-of-type").css("display", "none")

            }, "JSON")
            IndexTime = setInterval(() => {
                $.get('/action/env_check.htm', {}, function (msg) {
                    //console.log(msg)
                    if (msg.cpu_term < 10 || msg.cpu_term > 85) {
                        $("#cpu_term").html(`<font style="color:#ff0000;">${msg.cpu_term} ℃</font><img src="images/warning.png"  title="温度异常,请及时清理设备,检查设备散热问题。" style="margin-left: 5px;width:14px; height:14px;">
                    `)
                    } else {
                        $("#cpu_term").html(msg.cpu_term + " ℃")
                    }
                }, "JSON")
            }, 4000)

            //关闭跳转事件
            $(".col-xs-7").off("click");

        }

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------







        //内网主机
        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        if (isOnIpCheck&&(location.search.indexOf("?PAGE=hosts_info") !== -1)) {

            $(".seitchH-ul>.PPPOE_div>.H20>p").html('')



            // 单机应用查看
            {
                $(".PPPOE_div>.div-tab").prepend(`
                 <span style="margin-right:5px;">单机查看:</span>
        <input type="text" id="ipInp" value=""
          style="${inpCss}width:130px;"
        />

        <div id="searchBtn"  style="${btnCss}"  >查看</div>
 <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;</span>

        `)

                $("#ipInp").val(localStorage.getItem("ipVal")||'')


            }

            //IP正则
            let ipaddress = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/;


            //遮罩层CSS
            {
                var maskCss = `background-color:rgba(0,0,0,.3);
                            display:none;
                            position:fixed;
                            width:100%;
                            min-width:1200px;
                            height:100%;
                            top:0;
                            left:0;
                            bottom:0;
                            z-index:99999;
                            transition: all .2s linear;
                            box-sizing: border-box;
                            overflow:auto;
                            `
                var maskGtDiv = `width:1200px;
                                height:calc(100% - 110px);
                                overflow:hidden;
                                margin:55px auto;
                                background-color:#fff;
                                border-radius: 10px;
                                padding:10px 0;
                                box-sizing: border-box;`
                var refreshTimeCss = `background-color: #ffffff;
        color: #666666;
        font-size: 13px;
        height: 28px;
        line-height: 28px;
        text-indent: 10px;
        width: 52px;
        border: 1px solid #dbdfe6;
        padding: 0;
        border-radius: 4px;
        margin:0 5px;`
                var listTableWrapperCss = `width:100%;
                                           height:calc(100% - 100px);
                                           margin-top:45px;
                                           border:1px solid #f0f0f0;
                                           border-radius:0 0 10px 10px;
                                           padding-bottom:10px;
                                           overflow: auto;
                                           `
            }
            //添加遮罩层
            {
                $("body").append(`
                <div id="mask" style="${maskCss}">
                     <div style="${maskGtDiv}">
                          <div style="
                                padding:15px 20px;
                                display:flex;
                                justify-content: space-between;
                                align-items:center;
                                border-bottom:1px solid #eee;
                                ">
                                <span style="font-size:16px;font-weight: bold;">连接列表</span>
                                <div id="colseBtn" style="${btnCss}color:#ff4d4f;background-color:#fff;" title="ESC 关闭">关闭</div>
                           </div>

                             <div style="padding:15px 40px;height:calc(100% - 95px);
                                           position: relative;">
                               <div style="display:flex;justify-content: space-between">
                                 <div style="display:flex;
                                 flex-direction: row;
                                align-items:center;">
                                     <select id="isHide" class="selCss"style="${selCss}width:65px;margin-right:4px;">
                                         <option value="1">隐藏</option>
                                         <option value="0">显示</option>
                                     </select>
                                     <span>:</span>
                                     <select class="selCss" id="hideType" style="${selCss}margin-right:10px;">
                                         <option value="appstat">连接类型</option>
                                         <option value="pri">优先级</option>
                                         <option value="proto">协议</option>
                                         <option value="sport">源端口</option>
                                         <option value="dport">目的端口</option>
                                         <option value="daddr">目标地址</option>
                                         <option value="wan">外网接口</option>
                                         <option value="status">连接状态</option>
                                     </select>
                                     <input id="hideInp" style="${inpCss}width:130px; "/>
                                     <div id="resetHideBtn" style="${btnCss}">重置</div>
                                     <div id="okHideBtn" style="${btnCss}">确认</div>
                                 </div>
                              <div>自动刷新:<input type="number" id="refreshTimeInp" style="${refreshTimeCss}"/>秒
                                       <div id="StartStopBtn" style="${btnCss}" title="空格 停止刷新">启动</div>
                                                                &nbsp;&nbsp;&nbsp;&nbsp;
                                       <div id="reloadBtn"  style="${btnCss}" title="R 刷新">立即刷新</div>
                              </div>
                               </div>

                                 <ul id="listTableWrapper" style="${listTableWrapperCss}">
                                   <li style="position:absolute;
                                              width: calc(100% - 77px);
                                              top: 61px;
                                              left: 40px;">
                                     <ul class="listTableHead" style="border-radius: 10px 10px 0 0;overflow:hidden;cursor: pointer;">
                                         <li data-type="appstat">连接类型</li>
                                         <li data-type="pri">优先级</li>
                                         <li data-type="up">上传流量</li>
                                         <li data-type="down">下载流量</li>
                                         <li data-type="proto">协议</li>
                                         <li data-type="sport">源端口</li>
                                         <li data-type="dport">目的端口</li>
                                         <li data-type="daddr">目标地址</li>
                                         <li data-type="wan">外网接口</li>
                                         <li data-type="status">连接状态</li>
                                     </ul>
                                   </li>

                                 </ul>
                                 </div>
                                </div>
                                `)

                //回到顶部
                /*
                $("#mask").append(`    <div id="back-to-top" style="
    position: fixed;
    bottom: 80px;
    right: calc(50% - 690px);;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    font-size: 24px;
    background-color: #fff;
    color:#1f1f1f;
    cursor: pointer;
    transition: all .2s linear;
    font-weight: bold;
                            " title="T 回到顶部">↑</div>
                            </div>`)
                 */



                //添加排序元素
                $(".listTableHead>li").append(`
                <div style="display:flex;flex-direction: column;margin-left:5px;">
                    <div style="width: 0;height: 0;
                         border-left: 4px solid transparent;
                         border-right: 4px solid transparent;
                         border-bottom: 5px solid #b1b1b1;"></div>
                     <div style="width: 0;height: 0;margin-top:3px;
                         border-top: 5px solid #b1b1b1;
                         border-left: 4px solid transparent;
                         border-right: 4px solid transparent;"></div>
                </div>
                `)



                //CSS-----------------------
                {
                    $(".selCss>option").css({
                        border:"1px solid #f0f0f0",
                    })

                    $(".listTableHead>li").css({
                        cursor: "pointer",
                        userSelect: "none",
                        transition: "all .2s linear"
                    })


                    $("#listTableWrapper>li>ul").css({
                        display:"flex"
                    })
                    $("#listTableWrapper>li>ul>li").css({
                        width:"10%",
                        height:"40px",
                        display:"flex",
                        justifyContent: "center",
                        alignItems: "center",
                        borderBottom:"1px solid #f0f0f0",
                    })
                    $("#listTableWrapper>li>ul").eq(0).children('li').css({
                        backgroundColor:"#fafafa",
                        fontWeight: "bold",
                        height:"40px"
                    })
                    //hover-------------------
                    //查看按钮
                    $("#searchBtn").hover(function(){
                        // 移入
                        $(this).css("background-color","#39ade6")
                    }, function(){
                        // 移出
                        $(this).css("background-color","#26a3e9")
                    });
                    // 遮罩层关闭按钮
                    $("#colseBtn").hover(function(){
                        $(this).css("color","#ff7875")
                        $(this).css("background-color","#fff2f0")
                    }, function(){
                        $(this).css("color","#ff4d4f")
                        $(this).css("background-color","#fff")
                    });
                    //按钮
                    $("#searchBtn,#reloadBtn,#okHideBtn,#StartStopBtn,#resetHideBtn").hover(function(){
                        // 移入
                        $(this).css("background-color","#39ade6")
                    }, function(){
                        // 移出
                        $(this).css("background-color","#26a3e9")
                    });

                    //列表头部排序
                    $(".listTableHead>li").hover(function(){
                        // 鼠标移入时的处理逻辑
                        $(this).css("background-color","#efefef")
                    }, function(){
                        // 鼠标移出时的处理逻辑
                        $(this).css("background-color","#fafafa")
                    });

                    //回到顶部按钮
                    $("#back-to-top").hover(function(){
                        // 鼠标移入时的处理逻辑
                        $(this).css("background-color","#f0f0f0")
                    }, function(){
                        // 鼠标移出时的处理逻辑
                        $(this).css("background-color","#fff")
                    });
                }
            }
            //ip详情列表样式
            function ipListTableCss(){
                $("#listTableWrapper>li>ul").css({
                    display:"flex"
                })
                $("#listTableWrapper>li>ul>li").css({
                    width:"10%",
                    height:"30px",
                    display:"flex",
                    justifyContent: "center",
                    alignItems: "center",
                    borderBottom:"1px solid #f0f0f0",
                })
                $("#listTableWrapper>li:gt(0)>ul").css({
                    transition: "all .2s linear"
                })
                //hover-------------------
                //除第一个li其他选中
                $("#listTableWrapper>li:gt(0)>ul").hover(function(){
                    // 鼠标移入时的处理逻辑
                    if($(this).children().last().text()=="稳定")
                        $(this).css("background-color","#fafafa")
                }, function(){
                    // 鼠标移出时的处理逻辑
                    if($(this).children().last().text()=="稳定")
                        $(this).css("background-color","#fff")
                });
            }



            let timerReload=null;//刷新定时器
            let isStart=false;//是否开始
            let sort={state:0,type:'down'};//排序
            let ipListData=[];//ip详情数据
            //查看按钮点击事件
            $(document).on("click", "#searchBtn",function(){
                getIpList();
                //初始显示隐藏组件
                let hideEntryInp = sessionStorage.getItem('hideEntry')?JSON.parse(sessionStorage.getItem('hideEntry')):'';
                if(Object.prototype.toString.call(hideEntryInp) === '[object Object]'){
                    const keys = Object.keys(hideEntryInp);
                    const values = Object.values(hideEntryInp);
                    $("#hideType").val(keys[0])

                    if(keys[0]=='pri'){
                        switch(values[0]){
                            case "1":$('#hideInp').val("最高");break;
                            case "2":$('#hideInp').val("高");break;
                            case "3":$('#hideInp').val("中");break;
                            case "4":$('#hideInp').val("低");break;
                            case "5":$('#hideInp').val("最低");break;
                        }
                    }else{
                        $('#hideInp').val(values[0]);
                        $('#isHide').val(hideEntryInp.isHide);
                    }
                }else{
                    $('#hideInp').val('');
                    $('#isHide').val(1);
                }
            });
            //隐藏重置点击事件
            $(document).on("click", "#resetHideBtn", function(){
                $("#hideInp").val('')
                sessionStorage.removeItem('hideEntry')

                getIpList()//发起请求
                message('', '已重置')
            });
            //隐藏输入框添加键盘事件
            $('#hideInp').keydown(function(event) {
                // 使用 event.key 来判断按键
                if (event.key === 'Enter') {
                    hideOk();
                }
            });
            //隐藏确认点击事件
            $(document).on("click", "#okHideBtn",hideOk);
            //自动刷新输入框添加键盘事件
            $('#refreshTimeInp').keydown(function(event) {
                // 使用 event.key 来判断按键
                if (event.key === 'Enter') {
                    if($("#refreshTimeInp").val()>0){
                        clearInterval(timerReload)
                        $("#StartStopBtn").text('停止')
                        isStart=true
                        timerReload=setInterval(getIpList,$("#refreshTimeInp").val()*1000)
                    }else{
                        message('warning','大于 0 生效!')
                    }
                }
            });
            //启/停定时按钮
            $(document).on("click", "#StartStopBtn", function(){
                if(isStart){
                    $("#StartStopBtn").text('启动')
                    clearInterval(timerReload)
                    isStart=false
                    message('', '已停止!')
                }else{
                    if($("#refreshTimeInp").val()>0){
                        message('success', '已启动!')
                        $("#StartStopBtn").text('停止')
                        isStart=true
                        timerReload=setInterval(getIpList,$("#refreshTimeInp").val()*1000)
                    }else{
                        message('warning', '大于 0 生效!')
                    }
                }
            });
            //立即刷新按钮
            $(document).on("click", "#reloadBtn", function(){
                getIpList()
                $("#StartStopBtn").text('启动')
                clearInterval(timerReload)
                isStart=false
                message('success', '刷新成功!')
            });
            //排序点击事件
            $(document).on("click", ".listTableHead>li", function(){
                $(".listTableHead>li>div").each(function() {
                    $(this).children().eq(0).css("border-bottom-color","#b1b1b1");
                    $(this).children().eq(1).css("border-top-color","#b1b1b1");
                })
                if(sort.type==this.dataset.type){
                    if(sort.state<2){
                        sort.state+=1
                    }else{
                        sort.state=0
                    }
                }else{
                    sort.state=1;
                    sort.type=this.dataset.type;
                }

                switch(sort.state){
                    case 1:$(this).children().children().eq(0).css("border-bottom-color","#1677ff");
                        $(this).children().children().eq(1).css("border-top-color","#b1b1b1");break;
                    case 2:$(this).children().children().eq(0).css("border-bottom-color","#b1b1b1");
                        $(this).children().children().eq(1).css("border-top-color","#1677ff");break;
                }
                addIpList()
            });

            //隐藏确认
            function hideOk(){
                let hideType = $("#hideType").val()
                let hideVal = $("#hideInp").val().trim()
                let isOk = true
                if(hideType=="pri"){
                    if(/^[\u4e00-\u9fa5]{1,2}$/.test(hideVal)){
                        switch(hideVal){
                            case "最高":hideVal="1";break;
                            case "高":hideVal="2";break;
                            case "中":hideVal="3";break;
                            case "低":hideVal="4";break;
                            case "最低":hideVal="5";break;
                            default:isOk = false;
                        }
                    }else{
                        isOk = false;
                    }
                }else if(hideType=="proto"){
                    if(!(/TCP/i.test(hideVal) || /UDP/i.test(hideVal) || /ICMP/i.test(hideVal)))isOk = false;
                }else if(hideType=="sport"||hideType=="dport"){
                    const num = parseInt(hideVal, 10);
                    if(!(!isNaN(num) && num >= 0 && num <= 65535))isOk = false;
                }else if(hideType=="daddr"){
                    const pattern = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
                    if(!pattern.test(hideVal))isOk = false;
                }else if(hideType=="wan"){
                    if(!((hideVal.indexOf('wan')!=-1)||(hideVal.indexOf('LAN')!=-1)||(hideVal.indexOf('l2tp')!=-1)||(hideVal.indexOf('pptp')!=-1)))isOk = false;
                }else if(hideType=="status"){
                    if(hideVal=="未响应"){
                        hideVal = 1
                    }else if(hideVal=="稳定"){
                        hideVal = 2
                    }else{
                        isOk = false
                    }
                }else if(hideType=="appstat"){
                    console.log(isOk,hideType,hideVal)
                }

                if(isOk&&hideVal){
                    message('success', 'OK!')
                    sessionStorage.setItem('hideEntry',JSON.stringify({[hideType]:hideVal,isHide:$("#isHide").val()}))
                }else{
                    console.log(isOk,hideType,hideVal)
                    message('warning', '类型与值不匹配!')
                }

                getIpList()//发起请求
                //console.log(isOk,hideType,hideVal)
            }

            // 请求获取ip详情列表
            function getIpList(){
                let ip = $("#ipInp")[0].value
                //判断输入IP是否正确
                if (ipaddress.test(ip)) {
                    let data = JSON.stringify({ ip, wan: $(".sel_line option:selected").attr("data") })
                    //请求数据
                    $.get('/action/show_connect_exe.htm', { data }, function (msg) {
                        localStorage.setItem("ipVal",ip)
                        if (msg.length > 0) {
                            if(Array.isArray(msg[0])){
                                message('','有子数组');
                            }else{
                                ipListData = msg;
                                addIpList()
                            }
                            $("#mask").css("display","block")

                        } else {
                            //没有查到数据
                            message('warning',"该IP无数据!")
                        }
                    }, "JSON")
                } else {
                    message('error',"IP有误!")
                }
            }

            // 添加ip详情列表数据
            function addIpList(){
                //console.log(sort.state,sort.type);
                $("#listTableWrapper>li:gt(0)").remove()
                let sortData=JSON.parse(JSON.stringify(ipListData));
                let hideEntry = sessionStorage.getItem('hideEntry')?JSON.parse(sessionStorage.getItem('hideEntry')):''
                let hideEntryKey = '';
                if(Object.prototype.toString.call(hideEntry) === '[object Object]'){
                    hideEntryKey = Object.keys(hideEntry)[0];
                }else{
                }
                switch(sort.state){
                    case 1:sortData.sort(function(a,b){return a[sort.type]-b[sort.type]});break;
                    case 2:sortData.sort(function(a,b){return b[sort.type]-a[sort.type]});break;
                }


                let html = ''
                sortData=sort.state==0?ipListData:sortData
                sortData.forEach(function(item,index){
                    if(hideEntryKey){
                        if(hideEntry.isHide==1){
                            if(item[hideEntryKey]==hideEntry[hideEntryKey])return;
                        }else{
                            if(item[hideEntryKey]!=hideEntry[hideEntryKey])return;
                        }
                    }
                    html +=`
                                 <li style="${item.status==1?'background-color:#fff2e8':''}">
                                     <ul>
                                         <li>${item.appstat}</li>
                                         <li>${(function(){
                        switch(item.pri){
                            case "1":return "最高";
                            case "2":return "高";
                            case "3":return "中";
                            case "4":return "低";
                            case "5":return "最低";
                        }
                    })()}</li>
                                         <li>${formatFileSize(item.up)}</li>
                                         <li>${formatFileSize(item.down)}</li>
                                         <li>${item.proto}</li>
                                         <li>${item.sport}</li>
                                         <li>${item.dport}</li>
                                         <li>${item.daddr}</li>
                                         <li>${item.wan}</li>
                                         <li>${item.status==1?"未响应":"稳定"}</li>
                                     </ul>
                                 </li>`

                                })

                if(html=='')html=`<li><div style="height:220px;display: flex;justify-content: center;align-items: center;color:#bfbfbf;flex-direction: column;">
                                              <div style="font-size:30px;">☁</div><div>暂无数据</div>
                                          </div>
                                      </li>`
                $("#listTableWrapper").append(html)
                ipListTableCss()
            }




            $(document).ready(function() {
                //返回顶部按钮
                // 绑定到某个元素(如按钮)的点击事件上
                $('#back-to-top').click(function() {
                    // 使用animate()方法来平滑地滚动到页面顶部
                    $('body, html').animate({
                        scrollTop: 0
                    }, 500); // 500是动画的持续时间,以毫秒为单位
                    return false; // 阻止链接的默认行为(如果有的话)
                });

                //手动刷新
                $(".auto-flush").val(0)

                //初始隐藏组件
                let hideEntryInp = sessionStorage.getItem('hideEntry')?JSON.parse(sessionStorage.getItem('hideEntry')):'';
                if(Object.prototype.toString.call(hideEntryInp) === '[object Object]'){
                    const keys = Object.keys(hideEntryInp);
                    const values = Object.values(hideEntryInp);
                    $("#hideType").val(keys[0])
                    $('#hideInp').val(values[0]);
                    $('#isHide').val(hideEntryInp.isHide);
                }else{
                    $('#hideInp').val('');
                    $('#isHide').val(1);
                }

                $("#mask").attr('tabindex', '0').focus()
                //添加键盘事件
                $("#mask").keydown(function(event) {
                    //console.log(event.keyCode)
                    // 检查是否按下了空格键
                    if (event.key === ' ' || event.keyCode === 32) {
                        message('', '已停止!')
                        //停止自动刷新
                        $("#StartStopBtn").text('启动')
                        clearInterval(timerReload)
                        isStart=false
                        // 阻止事件的默认行为
                        event.preventDefault();
                        return false; // 在jQuery中,返回false也会阻止事件冒泡
                    }else if(event.keyCode ===82){//R键
                        //立即刷新
                        $("#reloadBtn").click()
                    }else if(event.keyCode ===84){
                        //回到顶部
                        $('#back-to-top').click()
                    }else if(event.keyCode ===27){
                        $('#colseBtn').click()
                    }
                });
            });

            //遮罩层关闭按钮
            $("#colseBtn").click(function(){
                $("#mask").css("display","none")
                $('#hideInp').val('');
                clearInterval(timerReload)
                isStart=false
                $("#refreshTimeInp").val('')
                $("#StartStopBtn").text('启动')
            })









            // 单机流量详情
            {
                $("#tblMain>tr").click(function(){
                    //console.log(this)
                })
            }


        }

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------






        //Ping检测
        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        if (location.search.indexOf("?PAGE=ping") !== -1) {

            // 检测日志
            if(isOnPingLog)checkLog()


            function checkLog(){
                let changeLog = JSON.parse(localStorage.getItem('changeLog'))!=null?JSON.parse(localStorage.getItem('changeLog')):true;
                $("ul.detail-info>li").eq(3).append(`<div id="ping_check_log_wra" style="width:100%;margin:auto;display:block;">
                  <div style="display:flex;justify-content:space-between;align-items: center;">
                     <div style="display:flex;align-items: center;">
                          <select class="sel-nav sel_time" style="width:150px;margin-right:10px;">
                              <option value="0">所有时间</option>
                              <option value="3600">最近1小时</option>
                              <option value="43200">最近12小时</option>
                              <option value="86400">最近24小时</option>
                          </select>
                          <select class="sel-nav sel_line" style="width:150px;"></select>
                     </div>
                     <div>
                          <div id="ref_ping_log" style="${btnCss}">立即刷新</div>
                          <div id="del_ping_log" style="${btnCss}background-color:#ff4d4f;margin-right:10px;">删除</div>
                     </div>
                  </div>
                  <div class="H20 col"></div>
                  <div id="ping_check_log" style="width:100%;"></div>
                </div>`)

                //获取线路并添加到下拉列表
                $.get('/action/wan_line_name_show.htm',(res)=>{
                    let ele = '<option value="0">所有线路</option>'
                    if(res.length>0){
                        res.forEach(item=>{
                            if(item.id[0]!='3')ele+=`<option value="${item.id}">${item.name}</option>`
                        })
                    }
                    $(".sel_line").append(ele)
                },'json')
                //判断是否启用日志列表
                if(changeLog){
                    $("ul.detail-info>li:nth-child(4)>table").css("display","none")
                    $("#ping_check_log").css("display","block")
                }else{
                    $("ul.detail-info>li:nth-child(4)>table").css("display","table")
                    $("#ping_check_log_wra").css("display","none")
                }

                //添加滑块开关
                $("div.pdg20-LR>div.fc").append(`<div id="changeLogBtn" style="margin-left: auto;display:none;">
                   <input type="checkbox" name="able" class="input_hide able" value="1" id="changeLog">
				   <label class="slider-v3" for="changeLog"></label>
				</div>`)
                $("div.pdg20-LR>div.fc>div.menu>label").click(()=>{
                    $("#changeLogBtn").css("display","none")
                })
                $("div.pdg20-LR>div.fc>div.menu>label").eq(3).off('click')
                $("div.pdg20-LR>div.fc>div.menu>label").eq(3).click(()=>{
                    changeLog = JSON.parse(localStorage.getItem('changeLog'))!=null?JSON.parse(localStorage.getItem('changeLog')):true;
                    $("#changeLogBtn").css("display","block")
                    $("#changeLog")[0].checked = changeLog
                })
                //滑块开关点击事件
                $("#changeLog").click(function(){
                    if($("#changeLog")[0].checked){
                        JSON.stringify(localStorage.setItem('changeLog',true))
                        $("ul.detail-info>li:nth-child(4)>table").css("display","none")
                        $("#ping_check_log_wra").css("display","block")
                    }else{
                        JSON.stringify(localStorage.setItem('changeLog',false))
                        $("ul.detail-info>li:nth-child(4)>table").css("display","table")
                        $("#ping_check_log_wra").css("display","none")
                    }
                    //console.log(localStorage.getItem('changeLog'))
                })

                //下拉列表选择事件
                $(".sel_time,.sel_line").change(refPingLog)
                //刷新按钮
                $("#ref_ping_log").click(refPingLog)
                function refPingLog(){
                    if($(".sel_line").val()=='0'&&$(".sel_time").val()=='0'){
                        getPingLog(true)
                    }else{
                        $.get('/action/get_basic_info.htm',function(msg){
                            let selTimeVal = 0
                            if($(".sel_time").val()!=0){
                                selTimeVal=msg.time-$(".sel_time").val()*1
                            }
                            //console.log(true,selTimeVal,$(".sel_line").val().toLowerCase())
                            getPingLog(true,selTimeVal,$(".sel_line").val().toLowerCase())
                        },'json')
                    }
                }

                //删除按钮
                $("#del_ping_log").click(()=>{
                    if (confirm("确定要删除吗?")) {
                        $.get('/action/fwlog_ping_del.htm', {}, function(msg) {
                            if(msg.state == 1){
                                message("success","删除成功!");
                                getPingLog()
                            }else{
                                message("error","删除失败,请重试!");
                            }
                        }, 'json');
                    }
                })
                //按钮hover
                $("#ref_ping_log").hover(function () {$(this).css("background-color", "#39ade6")
                                                     }, function () {$(this).css("background-color", "#26a3e9")
                                                                    });
                $("#del_ping_log").hover(function () {$(this).css("background-color", "#ff7875")
                                                     }, function () {$(this).css("background-color", "#ff4d4f")
                                                                    });



                $("div.pdg20-LR>div.fc").css({
                    display:'flex',
                    alignItems: 'center',
                })


                getPingLog()
                function getPingLog(isMsg=false,timeFrame=false,wanLine=false){
                    const columns = [
                        {
                            title: '时间',
                            dataIndex: 'utime',
                            key: 'utime',
                            width:'200px'
                        },
                        {
                            title: '线路',
                            dataIndex: 'line',
                            key: 'line',
                        },
                        {
                            title: '域名/IP',
                            dataIndex: 'domain',
                            key: 'domain',
                        },
                        {
                            title: '发送(个包)',
                            dataIndex: 'sent',
                            key: 'sent',
                        },
                        {
                            title: '接收(个包)',
                            dataIndex: 'accept',
                            key: 'accept',
                        },
                        {
                            title: '最低延迟(ms)',
                            dataIndex: 'lowest',
                            key: 'lowest',
                        },
                        {
                            title: '最高延迟(ms)',
                            dataIndex: 'highest',
                            key: 'highest',
                        },
                        {
                            title: '平均延迟(ms)',
                            dataIndex: 'average',
                            key: 'average',
                        },
                        {
                            title: '丢包率(%)',
                            dataIndex: 'packetloss',
                            key: 'packetloss',
                        },
                    ]
                    const dataSource = []
                    $.get('/action/fwlog_ping.htm',function(msg){
                        if(msg.length>0){
                            if(isMsg)message("success","刷新成功!")
                            //console.log(msg);
                            msg.forEach((item,index) => {
                                if(item.type=='0x7002'){
                                    dataSource.push({
                                        key: index,
                                        utime: item.utime,
                                        line: item.text.match(/(wan\d+|pptp\d+|L2TP\d+)/ig)[0],
                                        domain: item.text.match(/PING ([^\s]+)/)[0].replace(/PING /g, ''),
                                        sent: item.text.match(/发送(\d+(\.\d+)?)个包/g)[0].replace(/发送|个包/g, ''),
                                        accept: item.text.match(/收到(\d+(\.\d+)?)个包/g)[0].replace(/收到|个包/g, ''),
                                        lowest: item.text.match(/最低延迟(\d+(\.\d+)?)ms/g)[0].replace(/最低延迟|ms/g, ''),
                                        highest: item.text.match(/最高延迟(\d+(\.\d+)?)ms/g)[0].replace(/最高延迟|ms/g, ''),
                                        average: item.text.match(/,平均延迟(\d+(\.\d+)?)ms/g)[0].replace(/,平均延迟|ms/g, ''),
                                        packetloss: item.text.match(/,丢包率为(\d+(\.\d+)?)%/g)[0].replace(/,丢包率为|%/g, ''),
                                    })
                                }else{
                                    dataSource.push({
                                        key: index,
                                        utime: item.utime,
                                        line: item.text.match(/(wan\d+|pptp\d+|L2TP\d+)/ig)[0],
                                        domain: item.text.replace(item.text.match(/(wan\d+|pptp\d+|L2TP\d+)/ig)[0], '').replace(/!/g, ''),
                                        sent: '9999',
                                        accept: '9999',
                                        lowest: '9999',
                                        highest: '9999',
                                        average: '9999',
                                        packetloss: '9999',
                                    })
                                }
                            });


                            let dataS=dataSource.sort((a,b)=>b.utime-a.utime)
                            if(timeFrame&&timeFrame!=0)dataS=JSON.parse(JSON.stringify(dataS.filter(item => timeFrame<=item.utime)));
                            if(wanLine&&wanLine!=0)dataS=JSON.parse(JSON.stringify(dataS.filter(item => (item.line.indexOf(wanLine)!=-1))));
                            table("#ping_check_log", dataS, columns,false,{
                                unit:{sent:'个包',accept:'个包',lowest:'ms',highest:'ms',average:'ms',packetloss:'%',},
                                changeVal:{utime:reverse_time},
                                status:{packetloss:{0:(a)=>(a==0),1:(a)=>(a>0&&a<10),2:(a)=>(a>10&&a<=100)}}
                            })
                        }else if(msg.length==0){
                            if(isMsg)message("warning","暂无数据!")
                            table("#ping_check_log", dataSource, columns,false)
                        }
                    },'json')
                }


            }







        }

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------






        //newfw
        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

        if(isOnLogoTo){
            if (window.location.host.indexOf(':') > 0 && !isPrivateIpAddress(window.location.hostname) || isDev == 1) $(".back_logo").css({ "cursor": "pointer" });
            // logo点击事件
            $(".back_logo").click(function () {

                if (window.location.host.indexOf(':') > 0 && !isPrivateIpAddress(window.location.hostname) || isDev == 1) {
                    let str = ''

                    if (window.location.host.split(':').length == 1) {
                        str = window.btoa(window.location.host + ':80' + '*@*' + ($.cookie("NAME") || ''));
                    } else {
                        str = window.btoa(window.location.host + '*@*' + ($.cookie("NAME") || ''));
                    }

                    let $temp = $('<input>');
                    $('body').append($temp);
                    $temp.val(str).select();
                    document.execCommand('copy');
                    $temp.remove();

                    $(".back_logo").html(`
        <div style="
        width:100%;
        height:100%;
        display: flex;
        justify-content: center;
        align-items: center;
        color:#666;
        font-size:20px;
        background-color:rgba(255, 255, 255,.8);
        user-select: none;
        ">OK</div>
        `);

                    setTimeout(() => {
                        if (isDev == 1) {
                            window.open("http://localhost:5173/login");
                        } else {
                            window.open("http://47.108.191.179:8887/login");
                        }

                        $(".back_logo").html("");
                    }, logoToTime)
                }

            });
        }



        // ip私有地址正则
        function isPrivateIpAddress(ip) {
            // CIDR格式的私有IP地址段
            var privateRegex = /^(?:(?:10|172\.(?:[1-9]|[1][0-9])|192\.168)\.)/;

            return privateRegex.test(ip);
        }

        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    }

    {

        $('#menu').css("border", "1px solid red !important")



    }









    //流量转换
    function formatFileSize(size) {
        const scale = 1024;
        if (size == "") {
            return "0B";
        } else if (size < scale) {
            return `${size}.00B`;
        } else if (size < scale * scale) {
            return `${(size / scale).toFixed(2)}KB`;
        } else if (size < scale * scale * scale) {
            return `${(size / (scale * scale)).toFixed(2)}MB`;
        } else if (size < scale * scale * scale * scale) {
            return `${(size / (scale * scale * scale)).toFixed(2)}GB`;
        } else {
            return `${size}`;
        }
    }

    //时间转换
    function reverse_time(time){
        let unixTimestamp = new Date(time*1000);

        let Y = unixTimestamp.getFullYear() + '-';
        let M = (unixTimestamp.getMonth()+1 < 10 ? '0'+(unixTimestamp.getMonth()+1) : unixTimestamp.getMonth()+1) + '-';
        let D = unixTimestamp.getDate() + ' ';
        let h = ((unixTimestamp.getHours()+'').length==1?'0'+unixTimestamp.getHours() :unixTimestamp.getHours())+ ':';
        let m = ((unixTimestamp.getMinutes()+'').length==1?'0'+unixTimestamp.getMinutes() :unixTimestamp.getMinutes())+ ':';
        let s = (unixTimestamp.getSeconds()+'').length==1?'0'+unixTimestamp.getSeconds() :unixTimestamp.getSeconds();
        return Y+M+D+h+m+s;
    }


    //消息提示
    //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    /**
        * 消息提示
         * @param {a} a 消息类型,例如:'default','success','warning','error'
         * @param {b} b 消息内容,例如:'这是一条消息提示'
         * @example
         * message('success', '恭喜你,这是一条成功消息')	//@example示例代码
         * @return {Function} 返回数据类型
         */

    _addMessageHTML();
    let timerMessage = null;
    let topPX = 0;
    let arrMes = [];
    /**
        * 消息提示
         * @param {a} a 消息类型,例如:'default','success','warning','error'
         * @param {b} b 消息内容,例如:'这是一条消息提示'
         * @example
         * message('success', '恭喜你,这是一条成功消息')	//@example示例代码
         * @return {Function} 返回数据类型
         */
    function message(a, b) {
        clearTimeout(timerMessage)
        switch (a) {
            case 'success': _success(); break;
            case 'warning': _warning(); break;
            case 'error': _error(); break;
            default: _default();
        }
        $('#pmt_text').text(b)
        $('#prompt').css('opacity', 1)
        $('#prompt').css('top', '20px')
        timerMessage = setTimeout(() => {
            _closeMessage();
        }, 3000)

        function _default() {
            $('#prompt').css('color', '#909399')
            $('#prompt').css('border-color', '#ebeef5')
            $('#prompt').css('background-color', '#edf2fc')
            $("#pmt_state").text('i');
            $("#pmt_state").css("background-color", "#909399")
        }

        function _success() {
            $('#prompt').css('color', '#67c23a')
            $('#prompt').css('border-color', '#e1f3d8')
            $('#prompt').css('background-color', '#f0f9eb')
            $("#pmt_state").text('√');
            $("#pmt_state").css("background-color", "#67c23a")
        }

        function _warning() {
            $('#prompt').css('color', '#e6a23c')
            $('#prompt').css('border-color', '#faecd8')
            $('#prompt').css('background-color', '#fdf6ec')
            $("#pmt_state").text('!');
            $("#pmt_state").css("background-color", "#e6a23c")
        }

        function _error() {
            $('#prompt').css('color', '#f56c6c')
            $('#prompt').css('border-color', '#fde2e2')
            $('#prompt').css('background-color', '#fef0f0')
            $("#pmt_state").text('×');
            $("#pmt_state").css("background-color", "#f56c6c")
        }
    }

    //关闭消息提示
    function _closeMessage() {
        topPX -= 48;
        clearTimeout(timerMessage)
        $('#prompt').css('opacity', 0)
        $('#prompt').css('top', '-48px')
    }
    //添加消息提示元素
    function _addMessageHTML() {
        const promptCSS = `
            position: fixed;
    background-color: #edf2fc;
    border-color: #ebeef5;
    color: #909399;
    /* font-size: 12px; */
    width: 380px;
    height: 48px;
    top: -48px;
    left: 50%;
    transform: translateX(-50%);
    border: 1px solid #ebeef5;
    border-radius: 3px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 18px;
    user-select: none;
    opacity: 0;
    transition: all .2s linear;
    z-index: 99999;
            `
            const pmt_stateCSS = `
            display: inline-block;
    font-size: 12px;
    font-weight: bold;
    width: 16px;
    height: 16px;
    line-height: 16px;
    border-radius: 50%;
    text-align: center;
    background-color: #909399;
    color: #edf2fc;
    margin-right: 10px;
            `
            const pmt_clearCSS = `
            font-size: 22px;
    color: #c4c5cc;
    cursor: pointer;
    transition: all .1s linear;
            `

            $('body').append(`
    <div id="prompt" style="${promptCSS}">
        <div id="pmt">
            <span id="pmt_state" style="${pmt_stateCSS}">i</span>
            <span id="pmt_text" style="font-size: 14px;">这是一条消息提示</span>
        </div>
        <div id="pmt_clear" style="${pmt_clearCSS}">×</div>
    </div>
    `)
    }
    //关闭消息提示按钮
    $("#pmt_clear").click(() => {
        _closeMessage()
    })



    //表格
    //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    /**
        * 表格
         * @param {a} a DOM,添加到DOM里,例如:'#div','.div'
         * @param {b} b 列表数据,例如:[{key: '1',name: '张三',age: 18,address: '翻斗大街',}]
         * @param {c} c 列表头,例如:[{title: '姓名',dataIndex: 'name',key: 'name',},{title: '年龄',dataIndex: 'age',key: 'age',},{title: '住址',dataIndex: 'address',key: 'address',}]
         * @param {d} d false
         * @param {e} e 其他选项,unit(单位)、changeVal(值转换)、status(状态背景色),例如:
         * @example
         * table("#ping_check_log", dataSource, columns,false,
                        {
                            unit:{sent:'个包',accept:'个包',lowest:'ms',highest:'ms',average:'ms',packetloss:'%',},
                            changeVal:{utime:reverse_time},
                            status:{packetloss:{0:(a)=>(a==0),1:(a)=>(a>0&&a<10),2:(a)=>(a>10)}}
                        })	//@example示例代码
         * @return {Function} 返回数据类型
         */
    function table(DOM, d, c, isCall = false, o={unit:{},changeVal:{},status:{}}) {
        !isCall && sessionStorage.setItem('originalD', JSON.stringify(d));
        let sort;//排序
        if(!isCall){
            sort={ state: 0, type: '' };
        }else{
            sort = JSON.parse(sessionStorage.getItem('sort'))
        }
        //sort = JSON.parse(sessionStorage.getItem('sort')) || { state: 0, type: '' };//排序
        switch (sort.state) {
            case 1: d.sort(function (a, b) { return a[sort.type] - b[sort.type] }); break;
            case 2: d.sort(function (a, b) { return b[sort.type] - a[sort.type] }); break;
            default: d = JSON.parse(sessionStorage.getItem('originalD')) || d;
                //console.log(JSON.parse(sessionStorage.getItem('originalD')));
        }
        //if(!isCall)console.log(d,sort.state,sort.type)
        const _tableCSS = `width:100%;height:calc(100% - 30px);border:1px solid #f0f0f0;
                                           border-radius: 0 0 10px 10px;
                                           padding-bottom:10px;
                                           overflow: auto;
                                           box-sizing: border-box;
                                           font-size: 14px;
                                           color:#505459;
                                           margin-top:30px;
                                           background-color:#fff;`

                let html = `<div style="width:100%;min-width:800px;height:100%;position:relative;overflow:hidden;border-radius:10px">
                    <ul id="listTableWrapper" style="${_tableCSS}">
                                   <li style="width:100%;position:absolute;top:0;left:0;overflow:hidden;">
                                     <ul class="listTableHead" style="width:100%;cursor: pointer;">
                    ${(() => {
                        let el = '';
                        for (let i = 0; i < c.length; i++) {
                            el += `<li data-key="${c[i].key}" data-type="${c[i].dataIndex}">${c[i].title}</li>`;
                        }
                        return el
                    })()}
                    </ul></li>
                        ${(() => {
                            let el = '';
                            if(d.length!=0){
                                for (let i = 0; i < d.length; i++) {
                                    el += `<li><ul>
                                  ${(() => {
                                        let ele = '';
                                        for (let j = 0; j < c.length; j++) {
                                            ele += `<li data-key="${c[j].key}">${(()=>{
                                                let temp = o.changeVal[c[j].key]?o.changeVal[c[j].key](d[i][c[j].key]):d[i][c[j].key]
                                                return (temp==9999)?'-':(temp+(o.unit[c[j].key]?o.unit[c[j].key]:''))
                                            })()}</li>`;
                                        }
                                        return ele
                                    }
                                    )()}
                              </ul></li>`;
                                }
                            }else{
                                el = `<li><div style="height:220px;display: flex;justify-content: center;align-items: center;color:#bfbfbf;flex-direction: column;">
                                              <div style="font-size:30px;">☁</div><div>暂无数据</div>
                                          </div>
                                      </li>`
                            }
                            return el
                        })()}
                    </ul></div>`

                $(DOM).html(html)
        //添加排序元素
        $(".listTableHead>li").append(`
                <div style="display:flex;flex-direction: column;margin-left:5px;">
                    <div style="width: 0;height: 0;
                         border-left: 4px solid transparent;
                         border-right: 4px solid transparent;
                         border-bottom: 5px solid #b1b1b1;"></div>
                     <div style="width: 0;height: 0;margin-top:3px;
                         border-top: 5px solid #b1b1b1;
                         border-left: 4px solid transparent;
                         border-right: 4px solid transparent;"></div>
                </div>
                `)

        init()


        //添加样式
        function addTableCss() {
            $(".listTableHead>li").css({
                cursor: "pointer",
                userSelect: "none",
                transition: "all .2s linear",
            })

            $("#listTableWrapper>li>ul").css({
                display: "flex"
            })

            $("#listTableWrapper>li>ul").eq(0).children('li').css({
                backgroundColor: "#fafafa",
                fontWeight: "bold",
                height: "40px"
            })

            $("#listTableWrapper>li>ul").css({
                display: "flex"
            })

            let allWidthPe=0,allWidthPx=0,allLength=0;
            c.forEach(item=>{
                if(item.width){
                    ++allLength;
                    if(item.width.indexOf('%')!=-1){
                        allWidthPe+=item.width.replace('%','')*1
                    }else{
                        allWidthPx+=item.width.replace('px','')*1
                    }
                }
            })
            //console.log((100-allWidthPe)/(c.length-allLength) + '%', allWidthPx+'px',allWidthPe,allWidthPx,allLength)
            $("#listTableWrapper>li>ul>li").css({
                width: `calc(${(100-allWidthPe)/(c.length-allLength) + '%'} - ${allWidthPx+'px'}`,
                width:100/c.length+ '%',
                //width:(100-allWidthPe)/(c.length-allLength) + '%' - allWidthPx+'px',
                width:'12.5%',
                //width:`calc(100% - ${allWidthPx+'px'})/(c.length-allLength) + '%'`,
                height: "30px",
                display: "flex",
                justifyContent: "center",
                alignItems: "center",
                borderBottom: "1px solid #f0f0f0",
                whiteSpace: "nowrap",

            })
            //$("#listTableWrapper>li>ul>li:nth-child(1)").css({
            //width:'200px',
            //backgroundColor: "#bfa",
            //})
            //自定义列宽
            c.forEach((item,index)=>{
                if(item.width){
                    $(`#listTableWrapper>li>ul>li:nth-child(${index+1})`).css({
                        width:'200px',
                    })
                }
            })
            $("#listTableWrapper>li:gt(0)>ul").css({
                transition: "all .2s linear"
            })


        }

        //自定义列宽
        function customColW(k,w){}

        // hover-------------------
        function hoverMove() {
            //列表头部移入移出
            $(".listTableHead>li").hover(function () {
                // 鼠标移入时的处理逻辑
                $(this).css("background-color", "#efefef")
            }, function () {
                // 鼠标移出时的处理逻辑
                $(this).css("background-color", "#fafafa")
            });

            //列表详情移入移出
            //除第一个li其他选中
            $("#listTableWrapper>li:gt(0)>ul").hover(function () {
                // 鼠标移入时的处理逻辑
                if ($(this).children().last().text() !== "稳定")
                    $(this).css("background-color", "#fafafa")
            }, function () {
                // 鼠标移出时的处理逻辑
                if ($(this).children().last().text() !== "稳定")
                    $(this).css("background-color", "#fff")
            });


            //关闭hover并添加列表背景色
            d.forEach((item,index)=>{
                for(let key in o.status){
                    if (item.hasOwnProperty(key)) {
                        $.each(o.status[key], function(k, vf) {
                            switch(k){
                                case '1':if(vf(item[key])){
                                    $(`#listTableWrapper>li:nth-child(${index+2})>ul`).off('mouseenter mouseleave');
                                    $(`#listTableWrapper>li:nth-child(${index+2})>ul`).css({
                                        backgroundColor: "#fff2e8",
                                    });};break;
                                case '2':if(vf(item[key])){
                                    $(`#listTableWrapper>li:nth-child(${index+2})>ul`).off('mouseenter mouseleave');
                                    $(`#listTableWrapper>li:nth-child(${index+2})>ul`).css({
                                        backgroundColor: "#ffc2c0",
                                    });};break;
                            }
                        });
                    }
                }
                //$(`#listTableWrapper>li:nth-child(${index+1})>ul`)
            })
        }

        //排序点击事件
        $('.listTableHead>li').off('click.sortEvent')
        $('.listTableHead>li').on('click', sortEvent);
        function sortEvent() {
            if (sort.type == this.dataset.type) {
                if (sort.state < 2) {
                    sort.state += 1
                } else {
                    sort.state = 0
                }
            } else {
                sort.state = 1;
                sort.type = this.dataset.type;
            }


            switch (sort.state) {
                case 1: d.sort(function (a, b) { return a[sort.type] - b[sort.type] }); break;
                case 2: d.sort(function (a, b) { return b[sort.type] - a[sort.type] }); break;
            }

            sessionStorage.setItem('sort', JSON.stringify({ state: sort.state, type: sort.type }))
            changeSortCSS();
            table(DOM, d, c, true, o)
        }



        // 切换排序样式
        function changeSortCSS() {
            $(".listTableHead>li>div").each(function () {
                $(this).children().eq(0).css("border-bottom-color", "#b1b1b1");
                $(this).children().eq(1).css("border-top-color", "#b1b1b1");
            })
            if (sort.state != 0) {
                $(".listTableHead>li").each(function () {
                    if ($(this).attr("data-type") == sort.type) {
                        switch (sort.state) {
                            case 1: $(this).children().children().eq(0).css("border-bottom-color", "#1677ff");
                                $(this).children().children().eq(1).css("border-top-color", "#b1b1b1"); break;
                            case 2: $(this).children().children().eq(0).css("border-bottom-color", "#b1b1b1");
                                $(this).children().children().eq(1).css("border-top-color", "#1677ff"); break;
                        }
                    }
                })
            }
        }

        // 初始化
        function init() {
            addTableCss();//添加样式
            hoverMove();//添加hover事件
            changeSortCSS();//排序样式
        }
    }


    //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

})();