Merge branch 'master' of https://gitea.mjm-staging.developers-homelab.net/BIMS/BIMS
This commit is contained in:
		
						commit
						096afe8a01
					
				@ -216,7 +216,7 @@
 | 
			
		||||
    var tarElePath = '';
 | 
			
		||||
    var sysSubList = [];
 | 
			
		||||
    var viewer3DNodeIds = [];
 | 
			
		||||
    var timeOuters = [];
 | 
			
		||||
    
 | 
			
		||||
    var eveDayElecChart = null;
 | 
			
		||||
    var eveWeekElecChart = null;
 | 
			
		||||
    var worOrdErrChart = null;
 | 
			
		||||
@ -269,7 +269,7 @@
 | 
			
		||||
        show3DModel();
 | 
			
		||||
        getSubList();
 | 
			
		||||
        getFirstEletric();
 | 
			
		||||
        timeOutGetData();
 | 
			
		||||
        
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function demoSubList() {
 | 
			
		||||
 | 
			
		||||
@ -968,7 +968,9 @@
 | 
			
		||||
            $(`#${matchDevice.device_number}_card [name=devStatus]`).text(data.value);
 | 
			
		||||
            //若為異常(match資料庫點位值)且後台有設定為閃爍
 | 
			
		||||
            if (getValueByName("ST") == matchDevice.device_error_point_value) {
 | 
			
		||||
                $(`#${matchDevice.device_number}_card`).addClass("light-flash")
 | 
			
		||||
                $(`#${matchDevice.device_number}_card`).addClass("light-flash");
 | 
			
		||||
            } else {
 | 
			
		||||
                $(`#${matchDevice.device_number}_card`).removeClass("light-flash");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //現在樓層
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,6 @@
 | 
			
		||||
                setLightColor();
 | 
			
		||||
            }
 | 
			
		||||
            if (arr.indexOf(3) != -1) {
 | 
			
		||||
                getLightPoint();
 | 
			
		||||
                getHotspotPoint(() => {
 | 
			
		||||
                    show3DModel(data.urn_3D);
 | 
			
		||||
                });
 | 
			
		||||
@ -96,12 +95,12 @@
 | 
			
		||||
        }
 | 
			
		||||
        myBaja.setSubscribeDevicesByBql(ordPath);
 | 
			
		||||
        myBaja.setSubscribeDevicesCallBack(function (data) {
 | 
			
		||||
            console.log(data)
 | 
			
		||||
           
 | 
			
		||||
            let matchDevice = allDevList.filter(x => x.device_number == data.device_number_full)[0];
 | 
			
		||||
            if (!matchDevice) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            console.log(data)
 | 
			
		||||
           
 | 
			
		||||
            //將訂閱值塞入 subDeviceData
 | 
			
		||||
            if (subDeviceData.findIndex(x => x.device_number == matchDevice.device_number) == -1) {
 | 
			
		||||
                let obj = {};
 | 
			
		||||
@ -144,6 +143,10 @@
 | 
			
		||||
 | 
			
		||||
        myBaja.setSubscribeDeviceEndCallBack(function (data) {
 | 
			
		||||
            endPageLoading();
 | 
			
		||||
            if (data.findIndex(x => x.point_name == "Temp") != -1) {
 | 
			
		||||
                // 顯示溫度條
 | 
			
		||||
                showHeat("[name=forgeHeatBar]");
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@ -186,6 +189,8 @@
 | 
			
		||||
            //是否閃爍
 | 
			
		||||
            if (isFlashing) {
 | 
			
		||||
                $(ele).parents(".card.device-wrap").addClass("light-flash");
 | 
			
		||||
            } else {
 | 
			
		||||
                $(ele).parents(".card.device-wrap").removeClass("light-flash");
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
@ -216,12 +221,6 @@
 | 
			
		||||
        return strHtml;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 設置 Forge 3D 溫度條
 | 
			
		||||
    function setTopHeatBar() {
 | 
			
		||||
        let strHtml = `<canvas name="forgeHeatBar" width="200" height="30" style="z-index:9999"></canvas>`;
 | 
			
		||||
        return strHtml;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // forge 3D 異常點位變紅色
 | 
			
		||||
    function setForgeHotSpotColor(device) {
 | 
			
		||||
        let subData = subDeviceData.filter(x => x.device_number == device.device_number)[0]
 | 
			
		||||
@ -267,7 +266,7 @@
 | 
			
		||||
                                                    <span class="d-inline-block mr-3">
 | 
			
		||||
                                                        <img src="${baseImgUrl + varPathDevIcon + devObj.device_image}" class="profile-image rounded-circle" onerror="defDev(this)" alt="...">
 | 
			
		||||
                                                    </span>
 | 
			
		||||
                                                    <a href="javascript:;">${devObj.full_name}</a>
 | 
			
		||||
                                                    <a name="devItemName" data-number="${devObj.device_number}" href="javascript:;">${devObj.full_name}</a>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        <div class="d-flex mb-0 mt-2 align-items-center">
 | 
			
		||||
@ -282,13 +281,28 @@
 | 
			
		||||
                })
 | 
			
		||||
                // Niagara 產生 file 開頭字串問題
 | 
			
		||||
                strHtml = strHtml.replaceAll(`src="/file/`, `src="`);
 | 
			
		||||
 | 
			
		||||
                if (!res.data || res.data.length == 0) {
 | 
			
		||||
                    endPageLoading();
 | 
			
		||||
                } else {
 | 
			
		||||
                    // 訂閱 baja 設備
 | 
			
		||||
                    subDevice();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // 繪製 html
 | 
			
		||||
                $("#floDevList").append(strHtml);
 | 
			
		||||
 | 
			
		||||
                // 存入 device 基本資料至元素 data 屬性
 | 
			
		||||
                $("#floDevList a[name=devItem]").each((idx, ele) => {
 | 
			
		||||
                    if (allDevList.findIndex(x => x.device_number == $(ele).data("number")) != -1) {
 | 
			
		||||
                        $(ele).data("devobj", allDevList.filter(x => x.device_number == $(ele).data("number"))[0]);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                // 初始化 pop 視窗
 | 
			
		||||
                initPopover();
 | 
			
		||||
                // 卡片設備名稱點擊事件
 | 
			
		||||
                devItemNameEvent();
 | 
			
		||||
            }
 | 
			
		||||
        }, null, "POST").send();
 | 
			
		||||
    }
 | 
			
		||||
@ -349,9 +363,7 @@
 | 
			
		||||
 | 
			
		||||
    function show3DModel(urn) {
 | 
			
		||||
        $(loadEle).Loading("start");
 | 
			
		||||
        getLightData(allDevList);
 | 
			
		||||
        launchViewerForHotspot(urn, (viewer, nodeIds) => {
 | 
			
		||||
            showHeat("[name=forgeHeatBar]");
 | 
			
		||||
            let devDbIds = allDevList.map(x => x.forge_dbid);
 | 
			
		||||
            /*hideAllObjects(devDbIds);*/
 | 
			
		||||
            
 | 
			
		||||
@ -454,42 +466,11 @@
 | 
			
		||||
                    $.extend(item, data);
 | 
			
		||||
                    myDataList.push(item);
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                console.log("1", myDataList)
 | 
			
		||||
               
 | 
			
		||||
                setHotspotPoint(myDataList);
 | 
			
		||||
                callback ? callback() : "";
 | 
			
		||||
            }
 | 
			
		||||
        }, null, "POST").send();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async function getLightPoint(callback = null) {
 | 
			
		||||
        let url = baseApiUrl + "/api/GetDevNodeForCor";
 | 
			
		||||
        let sendData = {
 | 
			
		||||
            "device_area_tag": pageAct.AreaTag,
 | 
			
		||||
            "device_building_tag": pageAct.buiTag,
 | 
			
		||||
            "device_system_tag": pageAct.sysMainTag,
 | 
			
		||||
            "device_name_tag": pageAct.sysSubTag,
 | 
			
		||||
        };
 | 
			
		||||
        objSendData.Data = sendData;
 | 
			
		||||
        ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
 | 
			
		||||
            if (!res || res.code != "0000" || !res.data) {
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                let myDataList = [];
 | 
			
		||||
                $.each(res.data, (idx, data) => {
 | 
			
		||||
                    let item = {};
 | 
			
		||||
                    item.position = {};
 | 
			
		||||
                    if (data.device_node_coordinate_3d != null && isJSON(data.device_node_coordinate_3d)) {
 | 
			
		||||
                        item.position = JSON.parse(data.device_node_coordinate_3d);
 | 
			
		||||
                    }
 | 
			
		||||
                    $.extend(item, data);
 | 
			
		||||
                    myDataList.push(item);
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                console.log("2", myDataList)
 | 
			
		||||
                setLightPoint(myDataList);
 | 
			
		||||
                if (pageAct.sysMainTag == "LT") {
 | 
			
		||||
                    setLightPoint(myDataList);
 | 
			
		||||
                }
 | 
			
		||||
                callback ? callback() : "";
 | 
			
		||||
            }
 | 
			
		||||
        }, null, "POST").send();
 | 
			
		||||
@ -501,7 +482,7 @@
 | 
			
		||||
        getHopspotPoint(myDataList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async function setLightPoint(myDataList = []) {
 | 
			
		||||
    function setLightPoint(myDataList = []) {
 | 
			
		||||
        console.log(myDataList)
 | 
			
		||||
        getLightData(myDataList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,9 @@
 | 
			
		||||
        <div id="floChart" style="height : 80vh!important;width:100%"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="col-6 my-3">
 | 
			
		||||
        <div id="forgeHeatBarDiv" class="d-flex mb-4" style="gap:15px">
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <div id="forgeViewer"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
@ -32,6 +35,7 @@
 | 
			
		||||
    var global_emergency_alarm_device_number = [];
 | 
			
		||||
    var zoomToggle = 3;
 | 
			
		||||
    $(function () {
 | 
			
		||||
        drawHeatBar();
 | 
			
		||||
        getHotspotPoint(() => {
 | 
			
		||||
            show3DModel(pageAct.urn);
 | 
			
		||||
        });
 | 
			
		||||
@ -465,10 +469,17 @@
 | 
			
		||||
 | 
			
		||||
            floMyBaja.setSubscribeDeviceEndCallBack(function (data) {
 | 
			
		||||
                endPageLoading();
 | 
			
		||||
                if (data.findIndex(x => x.point_name == "Temp") != -1) {
 | 
			
		||||
                    // 顯示溫度條
 | 
			
		||||
                    showHeat("[name=forgeHeatBar]");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function drawHeatBar() {
 | 
			
		||||
        $("#forgeHeatBarDiv").html(setTopHeatBar());
 | 
			
		||||
    }
 | 
			
		||||
   
 | 
			
		||||
    // 電梯 3D 位置呈現
 | 
			
		||||
    function set3DElevPos(viewer) {
 | 
			
		||||
@ -1070,7 +1081,6 @@
 | 
			
		||||
            }
 | 
			
		||||
            forge3DElev.init();
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -93,6 +93,9 @@ input:-webkit-autofill { background-color: rgba(0, 0, 0, 0.15) !important; }
 | 
			
		||||
.device-wrap .card-body #info, .device-wrap .card-body #errRec, .device-wrap .card-body #opeRec { min-width: 500px; }
 | 
			
		||||
.scrolledTable { overflow-y: auto; clear: both; max-height:100%;}
 | 
			
		||||
 | 
			
		||||
#toast-container > div {
 | 
			
		||||
    width:330px !important;
 | 
			
		||||
}
 | 
			
		||||
/*a[data-tabname="topFunBtn"] { color: #fff }
 | 
			
		||||
 | 
			
		||||
a[data-tabname="topFunBtn"].active { color: #886ab5 }
 | 
			
		||||
@ -103,7 +106,7 @@ a[data-tabname="topFunBtn"]:hover { color: var(--theme-primary-50); }
 | 
			
		||||
}
 | 
			
		||||
.userblock:hover { color: var(--theme-primary-50); }
 | 
			
		||||
.dropdown.show .userblock { color: var(--theme-primary-50) !important; }*/
 | 
			
		||||
.page-header a {color:#fff !important;}
 | 
			
		||||
.page-header a { color: #fff !important; }
 | 
			
		||||
.page-header a:hover { color: var(--theme-primary-50) !important; }
 | 
			
		||||
.page-header a.active { color: var(--theme-primary-500) !important; }
 | 
			
		||||
.dropdown.show a { color: var(--theme-primary-50) !important; }
 | 
			
		||||
 | 
			
		||||
@ -203,7 +203,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                                    <i class="fas fa-user-circle fs-1-5 w-100 text-center"></i>
 | 
			
		||||
                                    <span id="usrName" class="text-truncate text-truncate-header hidden-xs-down"></span>
 | 
			
		||||
                                </div>
 | 
			
		||||
                                
 | 
			
		||||
 | 
			
		||||
                            </a>
 | 
			
		||||
                            <div id="logoutList" class="dropdown-menu dropdown-menu-right dropdown-lg">
 | 
			
		||||
 | 
			
		||||
@ -667,6 +667,10 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div id="noticeBlock" style="position: fixed; top: 70px; right: 0px; padding: 20px; transition: 0.2s; z-index: 50000; ">
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!--<button id="testsysbtn" class="btn btn-info col-1">系統監控(測試用)</button>-->
 | 
			
		||||
    <!-- END Messenger -->
 | 
			
		||||
    <!-- BEGIN Page Settings -->
 | 
			
		||||
@ -725,6 +729,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
        var jwt = null;
 | 
			
		||||
        var loadingTip = '';
 | 
			
		||||
        var pageAct = {};  //記錄全頁面已選擇項目
 | 
			
		||||
        var timeOuters = [];
 | 
			
		||||
        pageAct.AreaTag = "";
 | 
			
		||||
        if (location.href.indexOf("ord") != -1) {
 | 
			
		||||
            location.href = "/file/index.html"
 | 
			
		||||
@ -781,6 +786,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                        "lib/chart.js/Chart.min",
 | 
			
		||||
                        "lib/dropzone/dropzone-min",
 | 
			
		||||
                        "lib/jstree-master/jstree.min",
 | 
			
		||||
                        "lib/notifications/sweetalert2/sweetalert2.bundle",
 | 
			
		||||
                    ], loadedMasterPack);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
@ -830,14 +836,14 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
             * 登入驗證完成 Callback
 | 
			
		||||
             * */
 | 
			
		||||
            function isValidLogin() {
 | 
			
		||||
              
 | 
			
		||||
 | 
			
		||||
                getUserInfo();
 | 
			
		||||
                iniFroList();
 | 
			
		||||
                showMainSys();
 | 
			
		||||
                getBuiList();
 | 
			
		||||
                getSysMonBtnList();
 | 
			
		||||
                checkDevState();
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
                if (lastPage) {
 | 
			
		||||
                    let lastPageAct = {};
 | 
			
		||||
                    if (isJSON(sessionStorage.getItem("pageAct"))) {
 | 
			
		||||
@ -849,12 +855,13 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $(`[data-tabname=topFunBtn][data-page=${lastPage}]`).YTTab("setAndClick");
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                    /*$(`[name=topFunBtn][data-page=${lastPage}]`).click();*/
 | 
			
		||||
                } else {
 | 
			
		||||
                    $("#app").load("_dashboard.html", loadCallback);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                timeOutGetData();
 | 
			
		||||
 | 
			
		||||
                function getBuiList() {
 | 
			
		||||
                    let url = baseApiUrl + "/api/Device/GetBuild";
 | 
			
		||||
@ -918,7 +925,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    if (!page) {
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (page != "systemMonitor") {
 | 
			
		||||
                    if (page != "systemMonitor" && page != "sysElevator") {
 | 
			
		||||
                        $("#sysMonBtnList .dropdown-item").removeClass("active");
 | 
			
		||||
                        pageAct.sysMainTag = null;
 | 
			
		||||
                        pageAct.sysSubTag = null;
 | 
			
		||||
@ -935,15 +942,10 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    endPageLoading();
 | 
			
		||||
                    $(".yt-alert").YTAlert().hide();
 | 
			
		||||
 | 
			
		||||
                    if (typeof timeOuters != "undefined") {
 | 
			
		||||
                        $.each(timeOuters, (idx, timeOut) => {
 | 
			
		||||
                            clearInterval(timeOut);
 | 
			
		||||
                        })
 | 
			
		||||
                        timeOuters = [];
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                    getUserInfo();
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                    sessionStorage.setItem("lastPage", page);
 | 
			
		||||
                    sessionStorage.setItem("pageAct", JSON.stringify(pageAct));
 | 
			
		||||
                    $("#app").load(`_${page}.html`, loadCallback);
 | 
			
		||||
@ -955,14 +957,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    location.href = "/logout";
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                onEvent("click", "#sysMonBtnList a", function (e) {
 | 
			
		||||
                    //pageAct.sysMainTag = $(this).data("subSysObj").main_system_tag;
 | 
			
		||||
                    //pageAct.sysSubTag = $(this).data("subSysObj").sub_system_tag;
 | 
			
		||||
                    //pageAct.sysSubName = $(this).data("subSysObj").full_name;
 | 
			
		||||
                    //pageAct.sysSubObj = $(this).data("subSysObj");
 | 
			
		||||
                    //getDevItem();
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
               
 | 
			
		||||
                onEvent("active:change", "#buiList", function (e, actEle) {
 | 
			
		||||
                    if (actEle) {
 | 
			
		||||
                        pageAct.buiTag = $(actEle).prop("id").split("buiBtn")[1];
 | 
			
		||||
@ -984,11 +979,20 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                onEvent("scroll", window, function () {
 | 
			
		||||
                    if ($(window).scrollTop() != 0) {
 | 
			
		||||
                        $("#noticeBlock").css("top", 0);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $("#noticeBlock").css("top", 70);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
              
 | 
			
		||||
                onEvent("click", "#testsysbtn", function () {
 | 
			
		||||
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                let fronIdx = 1;
 | 
			
		||||
                $(window).on("timeout:3s", function () {
 | 
			
		||||
 | 
			
		||||
                    getSystemAlarmByBaja((data) => {
 | 
			
		||||
                        if (typeof getAlarmSub != "undefined" && getAlarmSub) {
 | 
			
		||||
                            getAlarmSub(data);
 | 
			
		||||
@ -996,6 +1000,28 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                        alarmIconBlink();
 | 
			
		||||
 | 
			
		||||
                    })
 | 
			
		||||
                    let content = `<div class="col-12">
 | 
			
		||||
                                        <div class="row m-0">
 | 
			
		||||
                                            <span class="m-0">異常編號:<span>001</span></span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="row m-0">
 | 
			
		||||
                                            <span class="m-0">異常等級:<span>2</span></span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="row m-0">
 | 
			
		||||
                                            <span class="m-0">異常類別:<span>S01</span></span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="row m-0">
 | 
			
		||||
                                            <span class="m-0">設備名稱:<span>電表01</span></span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                        <div class="row m-0">
 | 
			
		||||
                                            <span class="m-0">異常訊息:<span>壞掉</span></span>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                </div>`
 | 
			
		||||
                    let titleHtml = `異常通知`
 | 
			
		||||
 | 
			
		||||
                    $("#noticeBlock").YTNotice("add", titleHtml + fronIdx, content,"warning");
 | 
			
		||||
                    fronIdx++;
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
@ -1022,7 +1048,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    dataType: 'json',
 | 
			
		||||
                    success: function (rel) {
 | 
			
		||||
                        if (rel.code != "0000") {
 | 
			
		||||
                            toast_error(rel.msg || "系統內部發生錯誤,請聯絡系統管理員");
 | 
			
		||||
                            toast_error(rel.msg || common.SysErr);
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
@ -1032,7 +1058,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    error: function (xhr, textStatus, thrownError) {
 | 
			
		||||
                        alert(textStatus);
 | 
			
		||||
                        alert(common.SysErr);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
@ -1078,7 +1104,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
            function drawErrRecTabBlo() {
 | 
			
		||||
                let strHtml = `<table id="errRecTable" class="table table-bordered table-striped text-center m-0 w-100">
 | 
			
		||||
 | 
			
		||||
                                                            </table>`
 | 
			
		||||
                                                                    </table>`
 | 
			
		||||
                return strHtml;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -1086,7 +1112,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
            function drawOpeRecTabBlo() {
 | 
			
		||||
                let strHtml = `<table id="opeRecTable" class="table table-bordered table-striped text-center m-0 w-100">
 | 
			
		||||
 | 
			
		||||
                                                            </table>`
 | 
			
		||||
                                                                    </table>`
 | 
			
		||||
                return strHtml;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -1103,54 +1129,62 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                    let lightHtml = type == "light" ? `<button type="button" id="lightSch-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#lightSch"><i class="fas fa-calendar-alt"></i></button>` : "";
 | 
			
		||||
                    let option = {
 | 
			
		||||
                        html: `<div class="card m-1 border device-wrap">
 | 
			
		||||
                                            <div class="card-header p-3">
 | 
			
		||||
 | 
			
		||||
                                                                <div class="card-header p-3">
 | 
			
		||||
                                                <div class="position-absolute w-50" style="word-break: break-all;">
 | 
			
		||||
                                                    <label class="m-0 mt-2">${devName}</label>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                                <div id="card-tab" class="row justify-content-end nav nav-tabs" role="tablist">
 | 
			
		||||
                                                    <button type="button" id="state-tab" class="btn btn-icon nav-link active" role="tab" data-tabname="cardTab" data-target="#state"><i class="fa fa-desktop icon"></i></button>
 | 
			
		||||
                                                    ${lightHtml}
 | 
			
		||||
                                                    <button type="button" id="info-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#info"><i class="fa fa-cog icon"></i></button>
 | 
			
		||||
                                                    <button type="button" id="errRec-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#errRec"><i class="fas fa-exclamation-triangle"></i></button>
 | 
			
		||||
                                                    <button type="button" id="opeRec-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#opeRec"><i class="fa fa-bars icon"></i></button>
 | 
			
		||||
                                                    <button class="btn p-2"><i class="fas fa-times fs-1 text-white-50" data-close="yttooltip"></i></button>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                            <div class="card-body p-2 tab-content">
 | 
			
		||||
                                                <div id="state" class="show active" data-tabname="cardTab" data-tabrole="child" style="height:100%;width:100%">
 | 
			
		||||
                                                    ${drawStateTabBlo(devNum)}
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                                <div id="info" data-tabname="cardTab" data-tabrole="child">
 | 
			
		||||
 | 
			
		||||
                                                                    <div class="position-absolute w-50" style="word-break: break-all;">
 | 
			
		||||
                                                                        <label class="m-0 mt-2">${devName}</label>
 | 
			
		||||
                                                                    </div>
 | 
			
		||||
                                                                    <div id="card-tab" class="row justify-content-end nav nav-tabs" role="tablist">
 | 
			
		||||
                                                                        <button type="button" id="state-tab" class="btn btn-icon nav-link active" role="tab" data-tabname="cardTab" data-target="#state"><i class="fa fa-desktop icon"></i></button>
 | 
			
		||||
                                                                        ${lightHtml}
 | 
			
		||||
                                                                        <button type="button" id="info-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#info"><i class="fa fa-cog icon"></i></button>
 | 
			
		||||
                                                                        <button type="button" id="errRec-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#errRec"><i class="fas fa-exclamation-triangle"></i></button>
 | 
			
		||||
                                                                        <button type="button" id="opeRec-tab" class="btn btn-icon nav-link" role="tab" data-tabname="cardTab" data-target="#opeRec"><i class="fa fa-bars icon"></i></button>
 | 
			
		||||
                                                                        <button class="btn p-2"><i class="fas fa-times fs-1 text-white-50" data-close="yttooltip"></i></button>
 | 
			
		||||
                                                                    </div>
 | 
			
		||||
                                                                </div>
 | 
			
		||||
                                                                <div class="card-body p-2 tab-content">
 | 
			
		||||
                                                                    <div id="state" class="show active" data-tabname="cardTab" data-tabrole="child" style="height:100%;width:100%">
 | 
			
		||||
                                                                        ${drawStateTabBlo(devNum)}
 | 
			
		||||
                                                                    </div>
 | 
			
		||||
                                                                    <div id="info" data-tabname="cardTab" data-tabrole="child">
 | 
			
		||||
 | 
			
		||||
                                                                    </div>
 | 
			
		||||
                                                                    <div id="errRec" data-tabname="cardTab" data-tabrole="child">
 | 
			
		||||
                                                                        ${drawErrRecTabBlo()}
 | 
			
		||||
                                                                    </div>
 | 
			
		||||
                                                                    <div id="opeRec" data-tabname="cardTab" data-tabrole="child">
 | 
			
		||||
                                                                        ${drawOpeRecTabBlo()}
 | 
			
		||||
                                                                    </div>
 | 
			
		||||
                                                                </div>
 | 
			
		||||
                                                            </div>`,
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                                <div id="errRec" data-tabname="cardTab" data-tabrole="child">
 | 
			
		||||
                                                    ${drawErrRecTabBlo()}
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                                <div id="opeRec" data-tabname="cardTab" data-tabrole="child">
 | 
			
		||||
                                                    ${drawOpeRecTabBlo()}
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>`,
 | 
			
		||||
                        group: "device",
 | 
			
		||||
                        onShow: function (tooltipEle, oriEle) {
 | 
			
		||||
                            var tab = new YT.Tab({ tabName: "cardTab" })
 | 
			
		||||
                            // 執行 pop 視窗上方 Tab 類別
 | 
			
		||||
                            new YT.Tab({ tabName: "cardTab" })
 | 
			
		||||
                            let devObj = $(oriEle).data("devobj");
 | 
			
		||||
                            // 讀取運維列表
 | 
			
		||||
                            loadOpeRecTable(devGuid);
 | 
			
		||||
                            
 | 
			
		||||
                            // 讀取異常列表
 | 
			
		||||
                            loadErr($(oriEle).data("number"));
 | 
			
		||||
                            // 讀取設備基本資料列表
 | 
			
		||||
                            $(tooltipEle).find("#info").html(typeof drawInfoTabBlo != "undefined" ? drawInfoTabBlo(devGuid) : "");
 | 
			
		||||
                            // 聚焦熱點
 | 
			
		||||
                            if ($(oriEle).data("dbId")) {
 | 
			
		||||
                                controlFocusHotspot($(oriEle).data("dbId"));
 | 
			
		||||
                            }
 | 
			
		||||
                            // 3D 視角 ZOOM IN 聚焦
 | 
			
		||||
                            moveViewToDevice(devObj?.forge_dbid);
 | 
			
		||||
                            // pop 視窗卡片可拖移功能初始化
 | 
			
		||||
                            $(tooltipEle).draggable({
 | 
			
		||||
                                cursor: "move",
 | 
			
		||||
                                handle: ".card-header",  // 只能通过卡片的标题栏拖拽
 | 
			
		||||
                                containment: "document",
 | 
			
		||||
                                scroll: true
 | 
			
		||||
                            });
 | 
			
		||||
                            // pop 視窗卡片可縮放功能初始化
 | 
			
		||||
                            $(tooltipEle).resizable({
 | 
			
		||||
                                resize: function (event,ui) {
 | 
			
		||||
                                resize: function (event, ui) {
 | 
			
		||||
                                    let iframe = $(ui.element).find("iframe");
 | 
			
		||||
                                    if (iframe.length != 0) {
 | 
			
		||||
                                        if (ui.size.width != ui.originalSize.width) {
 | 
			
		||||
@ -1161,15 +1195,17 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                                    }
 | 
			
		||||
                                    let cardBodyHeight = $(ui.element).find(".card-body").css("height");
 | 
			
		||||
                                    $(ui.element).find(".scrolledTable").css("height", cardBodyHeight)
 | 
			
		||||
                                   
 | 
			
		||||
 | 
			
		||||
                                    errRecTable.draw(false)
 | 
			
		||||
                                },
 | 
			
		||||
                                minWidth: 200,
 | 
			
		||||
                                minHeight:150,
 | 
			
		||||
                                minHeight: 150,
 | 
			
		||||
                            });
 | 
			
		||||
                            // 電梯管理 - Card table 更新
 | 
			
		||||
                            typeof subDeviceSetTable != "undefined" ? subDeviceSetTable($(oriEle).data("number")) : ""
 | 
			
		||||
                        },
 | 
			
		||||
                        onHide: function (tooltipEle, oriEle) {
 | 
			
		||||
                            // 3D 熱點解除
 | 
			
		||||
                            controlFocusHotspot($(oriEle).data("dbId"), false);
 | 
			
		||||
                            // sysMonFloor Echart 解除 focus
 | 
			
		||||
                            typeof chartUnFocus != "undefined" ? chartUnFocus(oriEle) : "";
 | 
			
		||||
@ -1182,6 +1218,15 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 卡片設備名稱點擊事件
 | 
			
		||||
            function devItemNameEvent() {
 | 
			
		||||
                onEvent("click", "[name=devItemName]", function () {
 | 
			
		||||
                    let devNum = $(this).data("number");
 | 
			
		||||
                    let devObj = $(`[name=devItem][data-number=${devNum}]`).data("devobj");
 | 
			
		||||
                    moveViewToDevice(devObj.forge_dbid);
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Card - 運維紀錄 Table
 | 
			
		||||
            function loadOpeRecTable(devGuid) {
 | 
			
		||||
                if (opeRecTable) {
 | 
			
		||||
@ -1390,6 +1435,12 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                return parentEle;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // 設置 Forge 3D 溫度條
 | 
			
		||||
            function setTopHeatBar() {
 | 
			
		||||
                let strHtml = `<canvas name="forgeHeatBar" width="200" height="30" style="z-index:9999"></canvas>`;
 | 
			
		||||
                return strHtml;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //==============================================================================
 | 
			
		||||
            //                       ↑  系統監控 - 共用 Function ↑
 | 
			
		||||
            //==============================================================================
 | 
			
		||||
@ -1408,7 +1459,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
 | 
			
		||||
        function getDevItem() {
 | 
			
		||||
            let url = baseApiUrl + "/api/Device/GetDeviceItem";
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            objSendData.Data = {
 | 
			
		||||
                main_system_tag: pageAct.sysMainTag,
 | 
			
		||||
                sub_system_tag: pageAct.sysSubTag,
 | 
			
		||||
@ -1433,6 +1484,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
        function timeOutGetData() {
 | 
			
		||||
            let timeOut3s = null, timeOut5m = null;
 | 
			
		||||
            let events = $._data($(window)[0], "events");
 | 
			
		||||
 | 
			
		||||
            if (Object.keys(events).findIndex(x => x == "timeout:3s") != -1) {
 | 
			
		||||
                timeOut3s = setInterval(() => {
 | 
			
		||||
                    $(window).trigger("timeout:3s");
 | 
			
		||||
@ -1483,35 +1535,35 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    let strHtml = `<div class="btn-group mx-4">
 | 
			
		||||
                                                        <a href="javascript:;" name="topFunBtn" data-page="dashboard" data-tabname="topFunBtn" class="text-center">
 | 
			
		||||
                                                            <i class="fal fa-home fa-2x"></i><br>首頁
 | 
			
		||||
                                                        </a>
 | 
			
		||||
                                                        <!--<div class="dropdown-menu">
 | 
			
		||||
                                                            <button class="dropdown-item" type="button">Action</button>
 | 
			
		||||
                                                            <button class="dropdown-item" type="button">Another action</button>
 | 
			
		||||
                                                            <button class="dropdown-item" type="button">Something else here</button>
 | 
			
		||||
                                                        </div>-->
 | 
			
		||||
                                                    </div>`;
 | 
			
		||||
                                                                <a href="javascript:;" name="topFunBtn" data-page="dashboard" data-tabname="topFunBtn" class="text-center">
 | 
			
		||||
                                                                    <i class="fal fa-home fa-2x"></i><br>首頁
 | 
			
		||||
                                                                </a>
 | 
			
		||||
                                                                <!--<div class="dropdown-menu">
 | 
			
		||||
                                                                    <button class="dropdown-item" type="button">Action</button>
 | 
			
		||||
                                                                    <button class="dropdown-item" type="button">Another action</button>
 | 
			
		||||
                                                                    <button class="dropdown-item" type="button">Something else here</button>
 | 
			
		||||
                                                                </div>-->
 | 
			
		||||
                                                            </div>`;
 | 
			
		||||
 | 
			
		||||
                    $.each(res.data, function (i, v) {
 | 
			
		||||
                        if (v.authCode == 'PF1') {
 | 
			
		||||
                            strHtml += `<div class="btn-group mx-4" >
 | 
			
		||||
                                                            <a href="javascript:;" id="sysMonTopBtn" class="text-center" data-toggle="navbar" data-target="#sysMonNavbar" data-tabname="topFunBtn" aria-haspopup="true" aria-expanded="false">
 | 
			
		||||
                                                                <i class="fal fa-tv fa-2x"></i><br>${v.subName}
 | 
			
		||||
                                                            </a>
 | 
			
		||||
                                                                    <a href="javascript:;" id="sysMonTopBtn" class="text-center" data-toggle="navbar" data-target="#sysMonNavbar" data-tabname="topFunBtn" aria-haspopup="true" aria-expanded="false">
 | 
			
		||||
                                                                        <i class="fal fa-tv fa-2x"></i><br>${v.subName}
 | 
			
		||||
                                                                    </a>
 | 
			
		||||
 | 
			
		||||
                                                        </div>`;
 | 
			
		||||
                                                                </div>`;
 | 
			
		||||
 | 
			
		||||
                            hasMonitor = true;
 | 
			
		||||
                        }
 | 
			
		||||
                        else {
 | 
			
		||||
                            let icon = v.authCode == 'PF2' ? 'fa-chart-pie' : v.authCode == 'PF3' ? 'fa-chart-area' : v.authCode == 'PF4' ? 'fa-chart-line' : v.authCode == 'PF5' ? 'fa-bell' : v.authCode == 'PF6' ? 'fa-server' : v.authCode == 'PF7' ? 'fa-image' : v.authCode == 'PF8' ? 'fa-user' : '';
 | 
			
		||||
                            strHtml += `<div class="btn-group mx-4">
 | 
			
		||||
                                                            <a href="javascript:;" name="topFunBtn" data-tabname="topFunBtn" class="dropdown-toggle no-arrow text-center"
 | 
			
		||||
                                                               data-page="${v.showView}">
 | 
			
		||||
                                                                <i class="fal ${icon} fa-2x"></i><br>${v.subName}
 | 
			
		||||
                                                            </a>
 | 
			
		||||
                                                        </div>`;
 | 
			
		||||
                                                                    <a href="javascript:;" name="topFunBtn" data-tabname="topFunBtn" class="dropdown-toggle no-arrow text-center"
 | 
			
		||||
                                                                       data-page="${v.showView}">
 | 
			
		||||
                                                                        <i class="fal ${icon} fa-2x"></i><br>${v.subName}
 | 
			
		||||
                                                                    </a>
 | 
			
		||||
                                                                </div>`;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    });
 | 
			
		||||
@ -1531,12 +1583,11 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
            };
 | 
			
		||||
            objSendData.Data = sendData;
 | 
			
		||||
            ytAjax = new YourTeam.Ajax(url, objSendData, function (res) {
 | 
			
		||||
                console.log(res);
 | 
			
		||||
                if (!res || res.code != "0000" || !res.data) {
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    $("#sysMonBtnList").html("")
 | 
			
		||||
                    
 | 
			
		||||
 | 
			
		||||
                    $.each(res.data.history_Main_Systems, (index, mainSysObj) => {
 | 
			
		||||
                        $.each(mainSysObj.history_Sub_systems, (index2, subSysObj) => {
 | 
			
		||||
                            let page = "systemMonitor";
 | 
			
		||||
@ -1556,12 +1607,12 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
            }, null, "POST").send();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		function getLogo() {
 | 
			
		||||
        function getLogo() {
 | 
			
		||||
            url = baseApiUrl + '/api/GetLogo';
 | 
			
		||||
            ytAjax = new YourTeam.Ajax(url, null, function (res) {
 | 
			
		||||
                $('[name=webLogo]').attr('src', baseImgUrl + '/img/' + res.data);
 | 
			
		||||
            }, null, "POST").send();
 | 
			
		||||
		}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function getUserInfo() {
 | 
			
		||||
            let url = baseApiUrl + varApiUrl + "getUserFull";
 | 
			
		||||
@ -1576,6 +1627,8 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
 | 
			
		||||
                }
 | 
			
		||||
            }, null, "POST").send();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
       
 | 
			
		||||
    </script>
 | 
			
		||||
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
@ -596,7 +596,7 @@ class ADHeatMaps {
 | 
			
		||||
        await dataVizExtn.setupSurfaceShading(this.model, heatmapData);
 | 
			
		||||
 | 
			
		||||
        // 對 "temperature" 的溫度設定兩種顏色:紅色和藍色
 | 
			
		||||
        dataVizExtn.registerSurfaceShadingColors("temperature", [0x0000ff, 0xff0000]);
 | 
			
		||||
        dataVizExtn.registerSurfaceShadingColors("temperature", [0x0000ff, 0x00ff00, 0xffff00, 0xff0000]);
 | 
			
		||||
 | 
			
		||||
        this.dataVizExtn = dataVizExtn;
 | 
			
		||||
 | 
			
		||||
@ -622,9 +622,9 @@ class ADHeatMaps {
 | 
			
		||||
                dev.temp = temp;
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
       
 | 
			
		||||
        this.dataVizExtn.updateSurfaceShading(this.getSensorValue.bind(this));
 | 
			
		||||
 | 
			
		||||
        $.each(this.roomDbIds, (idx, rDbid) => {
 | 
			
		||||
            this.dataVizExtn.renderSurfaceShading("RoomPanel" + rDbid, "temperature", this.getSensorValue.bind(this));
 | 
			
		||||
        })
 | 
			
		||||
        //if (rDbid != null) {
 | 
			
		||||
        //    // 取得新的溫度值
 | 
			
		||||
        //    let getSensorValue = (device, sensorType) => {
 | 
			
		||||
@ -720,23 +720,30 @@ function hideColor(nodeId) {//顏色改成透明
 | 
			
		||||
 | 
			
		||||
//紀錄燈具座標
 | 
			
		||||
async function getLightData(data) {
 | 
			
		||||
    lightList = [];
 | 
			
		||||
    lightDataList = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function testNewLight(dataList) {
 | 
			
		||||
    dataList.forEach((myData, index) => {
 | 
			
		||||
        const position = JSON.parse(myData.device_node_coordinate_3d);
 | 
			
		||||
        lightList.push({ dbid: myData.forge_dbid, device_guid: myData.device_guid, lightObject: new THREE.SpotLight(0xffffff, 200, 20, 0.6, 0.5, 10) });
 | 
			
		||||
        const position = JSON.parse(myData.device_coordinate_3d);
 | 
			
		||||
        if (lightList.findIndex(x => x.device_guid == myData.device_guid) == -1) { 
 | 
			
		||||
            lightList.push({ dbid: myData.forge_dbid, device_guid: myData.device_guid, lightObject: new THREE.SpotLight(0xff0000, 200, 20, 0.6, 0.5, 10) });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        lightList[index].lightObject.position.set(position.x, position.y, position.z);
 | 
			
		||||
        lightList[index].lightObject.castShadow = true;
 | 
			
		||||
        lightList[index].lightObject.visible = true;
 | 
			
		||||
        lightList[index].lightObject.target.position.set(position.x, position.y, position.z - 20);
 | 
			
		||||
        lightList[index].lightObject.target.position.set(position.x, position.y, position.z - 100);
 | 
			
		||||
        viewer.scene.add(lightList[index].lightObject.target);
 | 
			
		||||
        viewer.scene.add(lightList[index].lightObject);
 | 
			
		||||
        viewer.impl.sceneUpdated(true);
 | 
			
		||||
 | 
			
		||||
        //let spotLightHelper = new THREE.SpotLightHelper(lightList[index].lightObject);
 | 
			
		||||
        //viewer.scene.add(spotLightHelper);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
    viewer.impl.sceneUpdated(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------- 加入熱點 -----------------
 | 
			
		||||
@ -1170,10 +1177,10 @@ function createHeatmapRect(labels, colorStops, selector) {
 | 
			
		||||
    }
 | 
			
		||||
    const context = $(selector)[0].getContext('2d');
 | 
			
		||||
    let i, len;
 | 
			
		||||
    context.clearRect(0, 0, 300, 50);
 | 
			
		||||
    context.clearRect(0, 0, 200, 50);
 | 
			
		||||
    context.fillStyle = 'back';//white
 | 
			
		||||
    for (i = 0, len = labels.length; i < len; i++) {
 | 
			
		||||
        let x = 10 + 280 * i / (len - 1);
 | 
			
		||||
        let x = 10 + 180 * i / (len - 1);
 | 
			
		||||
        if (i === len - 1) {
 | 
			
		||||
            x -= context.measureText(labels[i]).width;
 | 
			
		||||
        }
 | 
			
		||||
@ -1182,12 +1189,12 @@ function createHeatmapRect(labels, colorStops, selector) {
 | 
			
		||||
        }
 | 
			
		||||
        context.fillText(labels[i], x, 10);
 | 
			
		||||
    }
 | 
			
		||||
    const gradient = context.createLinearGradient(0, 0, 300, 0);
 | 
			
		||||
    const gradient = context.createLinearGradient(0, 0, 200, 0);
 | 
			
		||||
    for (i = 0, len = colorStops.length; i < len; i++) {
 | 
			
		||||
        gradient.addColorStop(i / (len - 1), colorStops[i]);
 | 
			
		||||
    }
 | 
			
		||||
    context.fillStyle = gradient;
 | 
			
		||||
    context.fillRect(10, 20, 280, 20);
 | 
			
		||||
    context.fillRect(10, 20, 200, 25);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//======================== 外部呼叫function ===========================
 | 
			
		||||
 | 
			
		||||
@ -96,8 +96,8 @@ class subscriptionDevices {
 | 
			
		||||
            // var building_tag = "H";
 | 
			
		||||
            // var system_tag = "M10";
 | 
			
		||||
            // baja.Ord.make(`ip:greencloud.fic.com.tw|foxs:|station:|slot:/Arena/${building_tag}/${system_tag}|bql:select name, displayname, slotPath, out.value, out from control:ControlPoint`)
 | 
			
		||||
            console.log(`local:|foxs:|station:|slot:/TPE/${_this.ordPath.building_tag}/${_this.ordPath.system_tag}/${_this.ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`);
 | 
			
		||||
            baja.Ord.make(`local:|foxs:|station:|slot:/TPE/${_this.ordPath.building_tag}/${_this.ordPath.system_tag}/${_this.ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`)
 | 
			
		||||
            console.log(`local:|foxs:|station:|slot:/${_this.ordPath.area_tag}/${_this.ordPath.building_tag}/${_this.ordPath.system_tag}/${_this.ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`);
 | 
			
		||||
            baja.Ord.make(`local:|foxs:|station:|slot:/${_this.ordPath.area_tag}/${_this.ordPath.building_tag}/${_this.ordPath.system_tag}/${_this.ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`)
 | 
			
		||||
                .get(
 | 
			
		||||
                    function (table) {
 | 
			
		||||
                        var tableStart, tableFinish;
 | 
			
		||||
@ -358,8 +358,8 @@ function MyBaja() {
 | 
			
		||||
//        // var building_tag = "H";
 | 
			
		||||
//        // var system_tag = "M10";
 | 
			
		||||
//        // baja.Ord.make(`ip:greencloud.fic.com.tw|foxs:|station:|slot:/Arena/${building_tag}/${system_tag}|bql:select name, displayname, slotPath, out.value, out from control:ControlPoint`)
 | 
			
		||||
//        console.log(`local:|foxs:|station:|slot:/TPE/${ordPath.building_tag}/${ordPath.system_tag}/${ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`);
 | 
			
		||||
//        baja.Ord.make(`local:|foxs:|station:|slot:/TPE/${ordPath.building_tag}/${ordPath.system_tag}/${ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`)
 | 
			
		||||
//        console.log(`local:|foxs:|station:|slot:/${_this.ordPath.area_tag}/${ordPath.building_tag}/${ordPath.system_tag}/${ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`);
 | 
			
		||||
//        baja.Ord.make(`local:|foxs:|station:|slot:/${_this.ordPath.area_tag}/${ordPath.building_tag}/${ordPath.system_tag}/${ordPath.name_tag}|bql:select name, displayname, slotPath, out.value, out, facets  from control:ControlPoint`)
 | 
			
		||||
//            .get(
 | 
			
		||||
//                function (table) {
 | 
			
		||||
//                    var tableStart, tableFinish;
 | 
			
		||||
@ -507,7 +507,7 @@ function BajaSubscribeAlarmsByBql(ordPathForAlarm) {
 | 
			
		||||
                var sourceState = (this.$map.$map.in10.$val.$map.$map.value.$display) == 'true' ? "Offnormal" : "Normal";
 | 
			
		||||
 | 
			
		||||
                var modify_target_device = {
 | 
			
		||||
                    "system": "TPE_" + ordPathForAlarm.building_tag + "_" + ordPathForAlarm.system_tag + "_" + ordPathForAlarm.name_tag,
 | 
			
		||||
                    "system": ordPathForAlarm.area_tag + "_" + ordPathForAlarm.building_tag + "_" + ordPathForAlarm.system_tag + "_" + ordPathForAlarm.name_tag,
 | 
			
		||||
                    "sourceState": sourceState ? sourceState : null
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -518,8 +518,8 @@ function BajaSubscribeAlarmsByBql(ordPathForAlarm) {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        //使用bql語法
 | 
			
		||||
        console.log(`local:|foxs:|alarm:|bql:select top 1 timestamp, sourceState, normalTime where alarmData.sourceName like '%TPE_${ordPathForAlarm.building_tag}_${ordPathForAlarm.system_tag}_${ordPathForAlarm.name_tag}_%' order by timestamp desc`);
 | 
			
		||||
        baja.Ord.make(`local:|foxs:|alarm:|bql:select top 1 timestamp, sourceState, alarmData, alarmData.sourceName, normalTime where alarmData.sourceName like '%TPE_${ordPathForAlarm.building_tag}_${ordPathForAlarm.system_tag}_${ordPathForAlarm.name_tag}_%' order by timestamp desc`)
 | 
			
		||||
        console.log(`local:|foxs:|alarm:|bql:select top 1 timestamp, sourceState, normalTime where alarmData.sourceName like '%${ordPathForAlarm.area_tag}_${ordPathForAlarm.building_tag}_${ordPathForAlarm.system_tag}_${ordPathForAlarm.name_tag}_%' order by timestamp desc`);
 | 
			
		||||
        baja.Ord.make(`local:|foxs:|alarm:|bql:select top 1 timestamp, sourceState, alarmData, alarmData.sourceName, normalTime where alarmData.sourceName like '%${ordPathForAlarm.area_tag}_${ordPathForAlarm.building_tag}_${ordPathForAlarm.system_tag}_${ordPathForAlarm.name_tag}_%' order by timestamp desc`)
 | 
			
		||||
            .get(
 | 
			
		||||
                function (table) {
 | 
			
		||||
                    var tableStart, tableFinish;
 | 
			
		||||
@ -549,7 +549,7 @@ function BajaSubscribeAlarmsByBql(ordPathForAlarm) {
 | 
			
		||||
                            var normalTime = this.getDisplay("normalTime");
 | 
			
		||||
 | 
			
		||||
                            var modify_target_device = {
 | 
			
		||||
                                "system": "TPE_" + ordPathForAlarm.building_tag + "_" + ordPathForAlarm.system_tag + "_" + ordPathForAlarm.name_tag,
 | 
			
		||||
                                "system": ordPathForAlarm.area_tag + "_" + ordPathForAlarm.building_tag + "_" + ordPathForAlarm.system_tag + "_" + ordPathForAlarm.name_tag,
 | 
			
		||||
                                "sourceState": sourceState ? sourceState : null
 | 
			
		||||
                            }
 | 
			
		||||
                            totalTargetDevice.push(modify_target_device);
 | 
			
		||||
 | 
			
		||||
@ -407,6 +407,12 @@ function strToDate(text, type = null, cal = 0, unit = "d") {
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 將只有時間(Hms) 格式轉換為當日的時間
 | 
			
		||||
function fullTime(time) {
 | 
			
		||||
    let nowDate = displayDate(new Date(), "date");
 | 
			
		||||
    return new Date(nowDate + " " + time);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function dateRanCutPart(start, end, cutNum) {
 | 
			
		||||
    let sTime = (new Date(start)).getTime();
 | 
			
		||||
    let eTime = (new Date(end)).getTime();
 | 
			
		||||
@ -433,6 +439,161 @@ function isJSON(str) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addBsToast(container, type = "warning",title="",content ="", id, datas = {}, option = {}) {
 | 
			
		||||
    datas = Object.keys(datas).length != 0 ? `${Object.keys(datas).map(x => `data-${x}="${datas[x]}"`).join(" ")}` : "";
 | 
			
		||||
    let iconClass = option.iconHtml ?? `fas fa-exclamation-triangle`;
 | 
			
		||||
    let strHtml = `<div class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false" ${datas}> 
 | 
			
		||||
                        <div class="toast-header ${warning ? `bg-` + warning : ""}">
 | 
			
		||||
                            <i class="${iconClass}"></i>
 | 
			
		||||
                            <strong class="mr-auto">${title}</strong>
 | 
			
		||||
                            <small class="text-muted">just now</small>
 | 
			
		||||
                            <button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
 | 
			
		||||
                                <span aria-hidden="true">×</span>
 | 
			
		||||
                            </button>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="toast-body">
 | 
			
		||||
                            ${content}
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class YTNotice {
 | 
			
		||||
    constructor(option = {}) {
 | 
			
		||||
        this.title = option.title ?? "";
 | 
			
		||||
        this.content = option.content ?? "";
 | 
			
		||||
        this.type = option.type ?? null;
 | 
			
		||||
        this.keepTime = 0;
 | 
			
		||||
        this.iconClass = option.iconClass ?? "";
 | 
			
		||||
        this.container = "";
 | 
			
		||||
        this.eIcon = "";
 | 
			
		||||
        this.eTitle = "";
 | 
			
		||||
        this.eTimeAgo = "";
 | 
			
		||||
        this.eCloseBtn = "";
 | 
			
		||||
        this.eContent = "";
 | 
			
		||||
        this.init();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init = function () {
 | 
			
		||||
        this.setIconClass();
 | 
			
		||||
        this.setContainer();
 | 
			
		||||
        
 | 
			
		||||
        if (this.title) {
 | 
			
		||||
            this.setTitle(this.title);
 | 
			
		||||
        }
 | 
			
		||||
        if (this.content) {
 | 
			
		||||
            this.setContent(this.content);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setContainer = function () {
 | 
			
		||||
        this.container = $(`<div class="toast fade" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="false"> 
 | 
			
		||||
                                <div class="toast-header">
 | 
			
		||||
                                    
 | 
			
		||||
                                </div>
 | 
			
		||||
                                <div class="toast-body">
 | 
			
		||||
                                    
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>`);
 | 
			
		||||
        
 | 
			
		||||
        this.setIcon(this.iconClass);
 | 
			
		||||
        this.eTitle = $(`<strong class="mr-auto notice-title"></strong>`);
 | 
			
		||||
        this.eTimeAgo = $(`<small class="text-muted notice-ago ml-4">just now</small>`);
 | 
			
		||||
        this.eCloseBtn = $(`<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close"><span aria-hidden="true">×</span></button>`);
 | 
			
		||||
        this.eContent = $(`<div class="notice-content"></div>`);
 | 
			
		||||
        if (this.type != null) { 
 | 
			
		||||
            this.container.find(".toast-header").append(this.eIcon);
 | 
			
		||||
            this.eIcon.addClass("text-" + this.type);
 | 
			
		||||
        }
 | 
			
		||||
        this.container.find(".toast-header").append(this.eTitle);
 | 
			
		||||
        this.container.find(".toast-header").append(this.eTimeAgo);
 | 
			
		||||
        this.container.find(".toast-header").append(this.eCloseBtn);
 | 
			
		||||
        this.container.find(".toast-body").append(this.eContent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setIconClass = function () {
 | 
			
		||||
        if (this.type == "success") {
 | 
			
		||||
            this.iconClass = `fas fa-check`;
 | 
			
		||||
        } else if (this.type == "warning") {
 | 
			
		||||
            this.iconClass = `fas fa-exclamation-triangle`;
 | 
			
		||||
        } else if (this.type == "danger") {
 | 
			
		||||
            this.iconClass = `fas fa-times`;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setIcon = function (iconClass) {
 | 
			
		||||
        this.eIcon = $(`<i class="mr-2"></i>`);
 | 
			
		||||
        this.eIcon.addClass(iconClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setTitle = function (title = "") {
 | 
			
		||||
        this.eTitle.html(title);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setTimeAgo = function (timeAgo = "") {
 | 
			
		||||
        this.eTimeAgo.text(timeAgo);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setContent = function (content = "") {
 | 
			
		||||
        this.eContent.html(content);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class YTNoticeBlock {
 | 
			
		||||
    constructor(option = {}) {
 | 
			
		||||
        this.element = option.element;
 | 
			
		||||
        this.offsetBottom = 200;
 | 
			
		||||
        this.noticeArr = [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addNotice = function (option = {}) {
 | 
			
		||||
        let notice = new YTNotice(option);
 | 
			
		||||
        $(this.element).prepend(notice.container);
 | 
			
		||||
        let lastNoticeOffset = $(this.element).find(".toast").last().offset();
 | 
			
		||||
        if (lastNoticeOffset.top + this.offsetBottom > $(window).height()) {
 | 
			
		||||
            $(this.noticeArr[0].obj.container).toast('dispose');
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                $(this.noticeArr[0].obj.container).remove();
 | 
			
		||||
                this.noticeArr.shift();
 | 
			
		||||
            }, 500)
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
        $(notice.container).toast('show');
 | 
			
		||||
        this.noticeArr.push({ obj: notice, time: (new Date()).getTime() });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
$.fn.YTNotice = function (method = "init", ...args) {
 | 
			
		||||
    let _this = this;
 | 
			
		||||
 | 
			
		||||
    if (method == "init") {
 | 
			
		||||
        initNoticeBlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (method == "add") {
 | 
			
		||||
        let argArr = ["title", "content", "type", "iconClass"];
 | 
			
		||||
        let opt = {};
 | 
			
		||||
        let noticeBlock = _this[0]._noticeBlock;
 | 
			
		||||
        if (!noticeBlock) {
 | 
			
		||||
            initNoticeBlock();
 | 
			
		||||
            noticeBlock = _this[0]._noticeBlock;
 | 
			
		||||
        }
 | 
			
		||||
        argArr.forEach((arg, idx) => {
 | 
			
		||||
            opt[argArr[idx]] = args[idx];
 | 
			
		||||
        })
 | 
			
		||||
        
 | 
			
		||||
        noticeBlock.addNotice(opt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function initNoticeBlock() {
 | 
			
		||||
        let option = {};
 | 
			
		||||
        option.element = _this;
 | 
			
		||||
        let noticeBlock = new YTNoticeBlock(option);
 | 
			
		||||
        _this[0]._noticeBlock = noticeBlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 取得資料庫電梯設備,根據 baja 訂閱移動 3D 電梯
 | 
			
		||||
 | 
			
		||||
@ -364,7 +364,7 @@ function displayDate(dateTime, dateType = "YMdHms", locale = 'zh-TW') {
 | 
			
		||||
    
 | 
			
		||||
        date = [year, String(month).padStart(2, '0'), String(day).padStart(2, '0')].filter(n => n).join("/");
 | 
			
		||||
      
 | 
			
		||||
        time = [String(hour).padStart(2, '0'), String(minute).padStart(2, '0')];
 | 
			
		||||
        time = [String(hour).padStart(2, '0'), String(minute).padStart(2, '0')].join(":");
 | 
			
		||||
        
 | 
			
		||||
        if (dateType != "date" && dateType != "time" && dateType != "datetime") {
 | 
			
		||||
            let showArr = [];
 | 
			
		||||
@ -1427,8 +1427,12 @@ async function download(token,url, filename,callback = null) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onEvent(type, selector, callback) {
 | 
			
		||||
    $("body").off(type, selector);
 | 
			
		||||
    $("body").on(type, selector, callback);
 | 
			
		||||
    if (selector == "body" || selector == window) {
 | 
			
		||||
        $(selector).on(type, callback);
 | 
			
		||||
    } else {
 | 
			
		||||
        $("body").off(type, selector);
 | 
			
		||||
        $("body").on(type, selector, callback);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user