<!DOCTYPE html> <!-- Template Name: SmartAdmin Responsive WebApp - Template build with Twitter Bootstrap 4 Version: 4.5.1 Author: Sunnyat A. Website: http://gootbootstrap.com Purchase: https://wrapbootstrap.com/theme/smartadmin-responsive-webapp-WB0573SK0?ref=myorange License: You must have a valid license purchased only from wrapbootstrap.com (link above) in order to legally use this theme for your project. --> <html lang="zh-hant-TW" class="root-text-lg"> <head> <meta charset="utf-8" /> <title>Marketing Dashboard - Application Intel - SmartAdmin v4.5.1</title> <meta name="description" content="Marketing Dashboard" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no, minimal-ui" /> <!-- Call App Mode on ios devices --> <meta name="apple-mobile-web-app-capable" content="yes" /> <!-- Remove Tap Highlight on Windows Phone IE --> <meta name="msapplication-tap-highlight" content="no" /> <!-- base css --> <link id="vendorsbundle" rel="stylesheet" media="screen, print" href="lib/vendors.bundle.css" /> <link id="appbundle" rel="stylesheet" media="screen, print" href="lib/app.bundle.css" /> <link id="mytheme" rel="stylesheet" media="screen, print" href="#" /> <link id="myskin" rel="stylesheet" media="screen, print" href="lib/skins/skin-master.css" /> <link rel="stylesheet" href="lib/notifications/toastr/toastr.min.css" /> <link rel="stylesheet" href="lib/dropzone/dropzone.css" /> <!-- Place favicon.ico in the root directory --> <link rel="apple-touch-icon" sizes="180x180" href="img/favicon/apple-touch-icon.png" /> <link rel="icon" type="image/png" sizes="32x32" href="img/favicon/favicon-32x32.png" /> <link rel="mask-icon" href="img/favicon/safari-pinned-tab.svg" color="#5bbad5" /> <!-- Font Awesome --> <link href="lib/fontawesome-free/css/all.min.css" rel="stylesheet" /> <link href="lib/jquery-ui/jquery-ui.min.css" rel="stylesheet" /> <!--<link href="lib/chart.js/Chart.min.css" rel="stylesheet" />--> <link href="lib/jstree-master/themes/default/style.min.css" rel="stylesheet" /> <link href="lib/jstree-master/themes/default-dark/style.min.css" rel="stylesheet" /> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" /> <!--<link rel="stylesheet" media="screen, print" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap.min.css">--> <link rel="stylesheet" media="screen, print" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css" /> <link rel="stylesheet" href="css/site.css" /> <link rel="stylesheet" href="css/yourteam/plugins/yt-tooltip/yt-tooltip.css" /> <link rel="stylesheet" href="css/yourteam/plugins/yt-notice/yt-notice.css" /> <link rel="stylesheet" href="css/yourteam/plugins/yt-alert/ytpop-alert.css" /> <link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css" type="text/css" /> </head> <!-- BEGIN Body --> <!-- Possible Classes * 'header-function-fixed' - header is in a fixed at all times * 'nav-function-fixed' - left panel is fixed * 'nav-function-minify' - skew nav to maximize space * 'nav-function-hidden' - roll mouse on edge to reveal * 'nav-function-top' - relocate left pane to top * 'mod-main-boxed' - encapsulates to a container * 'nav-mobile-push' - content pushed on menu reveal * 'nav-mobile-no-overlay' - removes mesh on menu reveal * 'nav-mobile-slide-out' - content overlaps menu * 'mod-bigger-font' - content fonts are bigger for readability * 'mod-high-contrast' - 4.5:1 text contrast ratio * 'mod-color-blind' - color vision deficiency * 'mod-pace-custom' - preloader will be inside content * 'mod-clean-page-bg' - adds more whitespace * 'mod-hide-nav-icons' - invisible navigation icons * 'mod-disable-animation' - disables css based animations * 'mod-hide-info-card' - hides info card from left panel * 'mod-lean-subheader' - distinguished page header * 'mod-nav-link' - clear breakdown of nav links >>> more settings are described inside documentation page >>> --> <body class="mod-bg-1 mod-nav-link mod-skin-dark mod-hide-info-card nav-function-top nav-function-fixed mod-lean-subheader desktop chrome webkit pace-done blur"> <!-- DOC: script to save and load page settings --> <script> /** * This script should be placed right after the body tag for fast execution * Note: the script is written in pure javascript and does not depend on thirdparty library **/ "use strict"; var classHolder = document.getElementsByTagName("BODY")[0], /** * Load from localstorage **/ themeSettings = localStorage.getItem("themeSettings") ? JSON.parse(localStorage.getItem("themeSettings")) : {}, themeURL = themeSettings.themeURL || "", themeOptions = themeSettings.themeOptions || ""; /** * Load theme options **/ if (themeSettings.themeOptions) { classHolder.className = themeSettings.themeOptions; console.log("%c✔ Theme settings loaded", "color: #148f32"); } else { console.log( "%c✔ Heads up! Theme settings is empty or does not exist, loading default settings...", "color: #ed1c24" ); } if (themeSettings.themeURL && !document.getElementById("mytheme")) { var cssfile = document.createElement("link"); cssfile.id = "mytheme"; cssfile.rel = "stylesheet"; cssfile.href = themeURL; document.getElementsByTagName("head")[0].appendChild(cssfile); } else if (themeSettings.themeURL && document.getElementById("mytheme")) { document.getElementById("mytheme").href = themeSettings.themeURL; } /** * Save to localstorage **/ var saveSettings = function () { themeSettings.themeOptions = String(classHolder.className) .split(/[^\w-]+/) .filter(function (item) { return /^(nav|header|footer|mod|display)-/i.test(item); }) .join(" "); if (document.getElementById("mytheme")) { themeSettings.themeURL = document .getElementById("mytheme") .getAttribute("href"); } localStorage.setItem("themeSettings", JSON.stringify(themeSettings)); }; /** * Reset settings **/ var resetSettings = function () { localStorage.setItem("themeSettings", ""); }; </script> <!-- BEGIN Page Wrapper --> <div class="page-wrapper"> <div class="page-inner"> <!-- BEGIN Left Aside --> <!-- END Left Aside --> <div class="page-content-wrapper"> <!-- BEGIN Page Header --> <header class="page-header" role="banner"> <!--we need this logo when user switches to nav-function-top--> <div class="page-logo"> <a href="javascript:;" name="topFunBtn" data-page="dashboard" class="page-logo-link press-scale-down d-flex align-items-center position-relative"> <img src="img/logo.png" alt="SmartAdmin WebApp" aria-roledescription="logo" /> <!--<span class="page-logo-text mr-1">SmartAdmin WebApp</span>--> <!--<span class="position-absolute text-white opacity-50 small pos-top pos-right mr-2 mt-n2"></span> <i class="fal fa-angle-down d-inline-block ml-1 fs-lg color-primary-300"></i>--> </a> </div> <!--DOC: nav menu layout change shortcut--> <div class="hidden-md-down dropdown-icon-menu position-relative"> <a href="#" class="header-btn btn js-waves-off" data-action="toggle" data-class="nav-function-hidden" title="Hide Navigation"> <i class="ni ni-menu"></i> </a> <ul> <li> <a href="#" class="btn js-waves-off" data-action="toggle" data-class="nav-function-minify" title="Minify Navigation"> <i class="ni ni-minify-nav"></i> </a> </li> <li> <a href="#" class="btn js-waves-off" data-action="toggle" data-class="nav-function-fixed" title="Lock Navigation"> <i class="ni ni-lock-nav"></i> </a> </li> </ul> </div> <!--DOC: mobile button appears during mobile width--> <div class="hidden-lg-up"> <a href="#" class="header-btn btn press-scale-down" data-action="toggle" data-class="mobile-nav-on"> <i class="ni ni-menu"></i> </a> </div> <div class="dropdown"> <a class="dropdown-toggle fs-1" href="javascript:;" role="button" id="buiActDrop" data-target="buiList" data-toggle="dropdown" aria-haspopup="true"> </a> <div id="buiList" class="dropdown-menu dropdown-select-menu js-auto-close"></div> </div> <div class="ml-auto d-flex" id="froLisPage"></div> <div class="ml-auto d-flex mr-3"> <div class="dropdown"> <a href="javascript:;" id="toggleNoticeBtn" class="d-flex align-items-center justify-content-center ml-2"> <!--<img src="img/demo/avatars/avatar-admin.png" class="profile-image rounded-circle" alt="Dr. Codex Lantern">--> <!--you can also add username next to the avatar with the codes below:--> <div class="row m-0 justify-content-center userblock"> <i id="noticeConIcon" class="fs-1-5 w-100 text-center"></i> <span id="noticeConText" class="text-truncate text-truncate-header hidden-xs-down" data-hide="隱藏警告" data-show="顯示警告"></span> </div> </a> </div> <!--app user menu--> <div class="dropdown"> <a href="#" data-toggle="dropdown" data-target="logoutList" class="d-flex align-items-center justify-content-center ml-2"> <!--<img src="img/demo/avatars/avatar-admin.png" class="profile-image rounded-circle" alt="Dr. Codex Lantern">--> <!--you can also add username next to the avatar with the codes below:--> <div class="row m-0 justify-content-center userblock"> <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"> <a id="logout" href="javascript:;" class="dropdown-item fw-500 pt-3 pb-3"> <span>登出</span> </a> </div> </div> </div> <div class="ml-2 text-center"> <!-- <label class="mb-0 fs-1-2"> Diamond Controls<span class="fs-09 position-absolute" >®</span > </label ><br /> --> <!-- <label class="mb-0 fs-1-1">智慧大樓管理平台</label> --> </div> </header> <!-- END Page Header --> <!-- BEGIN Page Content --> <!-- the #js-page-content id is needed for some plugins to initialize --> <!--@RenderBody()--> <div id="app"></div> <!-- this overlay is activated only when mobile menu is triggered --> <div class="page-content-overlay" data-action="toggle" data-class="mobile-nav-on"></div> <div id="sysMonNavbar" class="yt-navbar yt-left-navbar"> <div class="yt-navbar-content"> <ul id="sysMonBtnList"></ul> </div> </div> <!-- END Page Content --> <!-- BEGIN Page Footer --> <!--<footer class="page-footer" role="contentinfo"> <div class="d-flex align-items-center flex-1 text-muted"> <span class="hidden-md-down fw-700">2022 © SmartAdmin by <a href='https://www.gotbootstrap.com' class='text-primary fw-500' title='gotbootstrap.com' target='_blank'>gotbootstrap.com</a></span> </div> <div> <ul class="list-table m-0"> <li><a href="intel_introduction.html" class="text-secondary fw-700">About</a></li> <li class="pl-3"><a href="info_app_licensing.html" class="text-secondary fw-700">License</a></li> <li class="pl-3"><a href="info_app_docs.html" class="text-secondary fw-700">Documentation</a></li> <li class="pl-3 fs-xl"><a href="https://wrapbootstrap.com/user/MyOrange" class="text-secondary" target="_blank"><i class="fal fa-question-circle" aria-hidden="true"></i></a></li> </ul> </div> </footer>--> <!-- END Page Footer --> <!-- BEGIN Shortcuts --> <!-- END Shortcuts --> <!-- BEGIN Color profile --> <!-- this area is hidden and will not be seen on screens or screen readers --> <!-- we use this only for CSS color refernce for JS stuff --> <p id="js-color-profile" class="d-none"> <span class="color-primary-50"></span> <span class="color-primary-100"></span> <span class="color-primary-200"></span> <span class="color-primary-300"></span> <span class="color-primary-400"></span> <span class="color-primary-500"></span> <span class="color-primary-600"></span> <span class="color-primary-700"></span> <span class="color-primary-800"></span> <span class="color-primary-900"></span> <span class="color-info-50"></span> <span class="color-info-100"></span> <span class="color-info-200"></span> <span class="color-info-300"></span> <span class="color-info-400"></span> <span class="color-info-500"></span> <span class="color-info-600"></span> <span class="color-info-700"></span> <span class="color-info-800"></span> <span class="color-info-900"></span> <span class="color-danger-50"></span> <span class="color-danger-100"></span> <span class="color-danger-200"></span> <span class="color-danger-300"></span> <span class="color-danger-400"></span> <span class="color-danger-500"></span> <span class="color-danger-600"></span> <span class="color-danger-700"></span> <span class="color-danger-800"></span> <span class="color-danger-900"></span> <span class="color-warning-50"></span> <span class="color-warning-100"></span> <span class="color-warning-200"></span> <span class="color-warning-300"></span> <span class="color-warning-400"></span> <span class="color-warning-500"></span> <span class="color-warning-600"></span> <span class="color-warning-700"></span> <span class="color-warning-800"></span> <span class="color-warning-900"></span> <span class="color-success-50"></span> <span class="color-success-100"></span> <span class="color-success-200"></span> <span class="color-success-300"></span> <span class="color-success-400"></span> <span class="color-success-500"></span> <span class="color-success-600"></span> <span class="color-success-700"></span> <span class="color-success-800"></span> <span class="color-success-900"></span> <span class="color-fusion-50"></span> <span class="color-fusion-100"></span> <span class="color-fusion-200"></span> <span class="color-fusion-300"></span> <span class="color-fusion-400"></span> <span class="color-fusion-500"></span> <span class="color-fusion-600"></span> <span class="color-fusion-700"></span> <span class="color-fusion-800"></span> <span class="color-fusion-900"></span> </p> <!-- END Color profile --> </div> </div> </div> <!-- END Page Wrapper --> <!-- BEGIN Messenger --> <div class="modal fade js-modal-messenger modal-backdrop-transparent" tabindex="-1" role="dialog" aria-hidden="true"> <div class="modal-dialog modal-dialog-right"> <div class="modal-content h-100"> <div class="dropdown-header bg-trans-gradient d-flex align-items-center w-100"> <div class="d-flex flex-row align-items-center mt-1 mb-1 color-white"> <span class="mr-2"> <span class="rounded-circle profile-image d-block" style=" background-image: url('img/demo/avatars/avatar-d.png'); background-size: cover; "></span> </span> <div class="info-card-text"> <a href="javascript:void(0);" class="fs-lg text-truncate text-truncate-lg text-white" data-toggle="dropdown" aria-expanded="false"> Tracey Chang <i class="fal fa-angle-down d-inline-block ml-1 text-white fs-md"></i> </a> <div class="dropdown-menu"> <a class="dropdown-item" href="#">Send Email</a> <a class="dropdown-item" href="#">Create Appointment</a> <a class="dropdown-item" href="#">Block User</a> </div> <span class="text-truncate text-truncate-md opacity-80">IT Director</span> </div> </div> <button type="button" class="close text-white position-absolute pos-top pos-right p-2 m-1 mr-2" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true"><i class="fal fa-times"></i></span> </button> </div> <div class="modal-body p-0 h-100 d-flex"> <!-- BEGIN msgr-list --> <div class="msgr-list d-flex flex-column bg-faded border-faded border-top-0 border-right-0 border-bottom-0 position-absolute pos-top pos-bottom"> <div> <div class="height-4 width-3 h3 m-0 d-flex justify-content-center flex-column color-primary-500 pl-3 mt-2"> <i class="fal fa-search"></i> </div> <input type="text" class="form-control bg-white" id="msgr_listfilter_input" placeholder="Filter contacts" aria-label="FriendSearch" data-listfilter="#js-msgr-listfilter" /> </div> <div class="flex-1 h-100 custom-scroll"> <div class="w-100"> <ul id="js-msgr-listfilter" class="list-unstyled m-0"> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="tracey chang online"> <div class="d-table-cell align-middle status status-success status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-d.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> Tracey Chang <small class="d-block font-italic text-success fs-xs"> Online </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="oliver kopyuv online"> <div class="d-table-cell align-middle status status-success status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-b.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> Oliver Kopyuv <small class="d-block font-italic text-success fs-xs"> Online </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="dr john cook phd away"> <div class="d-table-cell align-middle status status-warning status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-e.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> Dr. John Cook PhD <small class="d-block font-italic fs-xs"> Away </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="ali amdaney online"> <div class="d-table-cell align-middle status status-success status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-g.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> Ali Amdaney <small class="d-block font-italic fs-xs text-success"> Online </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="sarah mcbrook online"> <div class="d-table-cell align-middle status status-success status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-h.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> Sarah McBrook <small class="d-block font-italic fs-xs text-success"> Online </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="ali amdaney offline"> <div class="d-table-cell align-middle status status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-a.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> oliver.kopyuv@gotbootstrap.com <small class="d-block font-italic fs-xs"> Offline </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="ali amdaney busy"> <div class="d-table-cell align-middle status status-danger status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-j.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> oliver.kopyuv@gotbootstrap.com <small class="d-block font-italic fs-xs text-danger"> Busy </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="ali amdaney offline"> <div class="d-table-cell align-middle status status-sm"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-c.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> oliver.kopyuv@gotbootstrap.com <small class="d-block font-italic fs-xs"> Offline </small> </div> </div> </a> </li> <li> <a href="#" class="d-table w-100 px-2 py-2 text-dark hover-white" data-filter-tags="ali amdaney inactive"> <div class="d-table-cell align-middle"> <span class="profile-image-md rounded-circle d-block" style=" background-image: url('img/demo/avatars/avatar-m.png'); background-size: cover; "></span> </div> <div class="d-table-cell w-100 align-middle pl-2 pr-2"> <div class="text-truncate text-truncate-md"> +714651347790 <small class="d-block font-italic fs-xs opacity-50"> Missed Call </small> </div> </div> </a> </li> </ul> <div class="filter-message js-filter-message"></div> </div> </div> <div> <a class="fs-xl d-flex align-items-center p-3"> <i class="fal fa-cogs"></i> </a> </div> </div> <!-- END msgr-list --> <!-- BEGIN msgr --> <div class="msgr d-flex h-100 flex-column bg-white"> <!-- BEGIN custom-scroll --> <div class="custom-scroll flex-1 h-100"> <div id="chat_container" class="w-100 p-4"> <!-- start .chat-segment --> <div class="chat-segment"> <div class="time-stamp text-center mb-2 fw-400">Jun 19</div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-sent"> <div class="chat-message"> <p>Hey Tracey, did you get my files?</p> </div> <div class="text-right fw-300 text-muted mt-1 fs-xs"> 3:00 pm </div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-get"> <div class="chat-message"> <p>Hi</p> <p> Sorry going through a busy time in office. Yes I analyzed the solution. </p> <p> It will require some resource, which I could not manage. </p> </div> <div class="fw-300 text-muted mt-1 fs-xs">3:24 pm</div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-sent chat-start"> <div class="chat-message"> <p>Okay</p> </div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-sent chat-end"> <div class="chat-message"> <p> Sending you some dough today, you can allocate the resources to this project. </p> </div> <div class="text-right fw-300 text-muted mt-1 fs-xs"> 3:26 pm </div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-get chat-start"> <div class="chat-message"> <p>Perfect. Thanks a lot!</p> </div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-get"> <div class="chat-message"> <p>I will have them ready by tonight.</p> </div> </div> <!-- end .chat-segment --> <!-- start .chat-segment --> <div class="chat-segment chat-segment-get chat-end"> <div class="chat-message"> <p>Cheers</p> </div> </div> <!-- end .chat-segment --> <!-- start .chat-segment for timestamp --> <div class="chat-segment"> <div class="time-stamp text-center mb-2 fw-400">Jun 20</div> </div> <!-- end .chat-segment for timestamp --> </div> </div> <!-- END custom-scroll --> <!-- BEGIN msgr__chatinput --> <div class="d-flex flex-column"> <div class="border-faded border-right-0 border-bottom-0 border-left-0 flex-1 mr-3 ml-3 position-relative shadow-top"> <div class="pt-3 pb-1 pr-0 pl-0 rounded-0" tabindex="-1"> <div id="msgr_input" contenteditable="true" data-placeholder="Type your message here..." class="height-10 form-content-editable"></div> </div> </div> <div class="height-8 px-3 d-flex flex-row align-items-center flex-wrap flex-shrink-0"> <a href="javascript:void(0);" class="btn btn-icon fs-xl width-1 mr-1" data-toggle="tooltip" data-original-title="More options" data-placement="top"> <i class="fal fa-ellipsis-v-alt color-fusion-300"></i> </a> <a href="javascript:void(0);" class="btn btn-icon fs-xl mr-1" data-toggle="tooltip" data-original-title="Attach files" data-placement="top"> <i class="fal fa-paperclip color-fusion-300"></i> </a> <a href="javascript:void(0);" class="btn btn-icon fs-xl mr-1" data-toggle="tooltip" data-original-title="Insert photo" data-placement="top"> <i class="fal fa-camera color-fusion-300"></i> </a> <div class="ml-auto"> <a href="javascript:void(0);" class="btn btn-info">Send</a> </div> </div> </div> <!-- END msgr__chatinput --> </div> <!-- END msgr --> </div> </div> </div> </div> <div id="noticeBlock" style=" position: fixed; top: 70px; right: 0px; padding: 20px; transition: 0.2s; z-index: 50000; height: 100%; "></div> <!--<button id="testsysbtn" class="btn btn-info col-1">系統監控(測試用)</button>--> <!-- END Messenger --> <!-- BEGIN Page Settings --> <!-- END Page Settings --> <!-- base vendor bundle: DOC: if you remove pace.js from core please note on Internet Explorer some CSS animations may execute before a page is fully loaded, resulting 'jump' animations + pace.js (recommended) + jquery.js (core) + jquery-ui-cust.js (core) + popper.js (core) + bootstrap.js (core) + slimscroll.js (extension) + app.navigation.js (core) + ba-throttle-debounce.js (core) + waves.js (extension) + smartpanels.js (extension) + src/../jquery-snippets.js (core) --> <!-- verdors.bundle.js 已含有 jquery Library v3.5.1--> <script src="lib/vendors.bundle.js"></script> <!-- toast 第三方套件 若 require 此套件只能用 define 使用,先暫時 html 引用--> <script src="lib/notifications/toastr/toastr.min.js"></script> <script src="js/toast.js"></script> <script src="lib/echarts.min.js"></script> <!--The order of scripts is irrelevant. Please check out the plugin pages for more details about these plugins below:--> <script src="lib/statistics/easypiechart/easypiechart.bundle.js"></script> <!--Bajascript--> <script src="js/bajascript/bscriptReq.js"></script> <!--<script type='text/javascript' src='/module/js/com/tridium/js/ext/require/require.min.js?version=1496767636459'></script>--> <script src="js/bajascript/require.js"></script> <script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.js"></script> <script src="js/forge/forgemodel.js"></script> <script src="js/yourteam/plugins/yt-alert/ytpop-alert.js"></script> <script type="text/javascript"> define("niagaraSystemProperties", function () { return {}; }); </script> <script src="js/n4js/bajatest.js"></script> <script src="js/n4js/electricmeterbaja.js"></script> <script src="js/n4js/elevatorbaja.js"></script> <script src="js/bajascript/require.config.js"></script> <script src="js/FileSaver.js"></script> <script> /*$('#js-page-content').smartPanel();*/ var cookies = null; var jwt = null; var loadingTip = ""; var pageAct = {}; //記錄全頁面已選擇項目 var timeOuters = []; pageAct.AreaTag = ""; if (location.href.indexOf("ord") != -1) { location.href = "/file/index.html"; } var lastPage = sessionStorage.getItem("lastPage"); // 執行初步 Loading var loadEle = pageLoading(); var errRecTable = null, opeRecTable = null; var tolSubList = []; var allDevices = []; var tempSubTag = ["M10", "M12"]; // 溫度向小類 /** * 頁面 Loading 建立 * */ function pageLoading(text = null) { let background = $(`<div class="loading-bg"></div>`); let aleObj = YT.Alert.Tip(text || "讀取中,請稍後", "show"); $(background)[0]._aleObj = aleObj; $("body").css("overflow", "hidden"); $("body .page-content-wrapper").append(background); $(background).animate({ opacity: 1 }, 300); return background; } try { $(function () { // 二次引用 jquery.js // - 在 require 內部程序需要引用 jquery,由於 require 的套件需要依賴 jquery ,就算 HTML 已經引用 jquery, require 也無法參考 // - 上方 HTML 引用套件若有使用 jquery 內存數據程序 (ex: $(x).data() , $(x).trigger("custom event") , $.fn.custom ...) // - 會被清洗,有類似程序需放入 loadPack1 Function rquired 引用 // (原 datatable.bundle.js require 會出問題,先以 cdn datatable.min.js引用) require(["jquery"], loadedBasePack); }); /** * jquery.js 二次引用後 Callback,載入第三方套件 * */ function loadedBasePack() { require([ "lib/bootstrap/bootstrap.bundle.min", "lib/app.bundle", "lib/app.menu", "datatables.net.b4", "n4js/alarmbaja", "n4js/historybaja", "n4js/accmanbaja", "lib/statistics/flot/flot.bundle", "lib/statistics/peity/peity.bundle", "lib/jquery-validation/dist/jquery.validate", /*"lib/jquery-validation/dist/additional-methods.min",*/ /* 會影響 messages_zh_TW 文字呈現 */ "lib/jquery-validation/dist/localization/messages_zh_TW", "lib/jquery-ui/jquery-ui.min", "lib/chart.js_4.1.2/chart.umd", "lib/dropzone/dropzone-min", "lib/jstree-master/jstree.min", "lib/notifications/sweetalert2/sweetalert2.bundle", ], loadedMasterPack); } /** * 第三方套件引用後 Callback,載入額外套件 * */ function loadedMasterPack() { require([ "yourteam/yourteam.utility.class", "yourteam/yourteam.ajax.class", "yourteam/yourteam.jquery.datatables", "yourteam/plugins/yt-tooltip/yt-tooltip", "yourteam/plugins/yt-tab/yt-tab", "yourteam/plugins/yt-navbar/yt-navbar", "yourteam/plugins/yt-notice/yt-notice", "style", ], function () { require(["init", "site"], loadedJsPack); }); } /** * 全數套件讀取完成 Callback * */ function loadedJsPack() { cookies = new YourTeam.Utility.Cookie(); jwt = cookies.get("JWT-Authorization"); pageAct.AreaTag = initAreaTag; loadEvent(); if (!jwt) { if (location.href.indexOf("localhost:5966") != -1) { location.href = "login.html"; } myBaja = new MyBaja(); myBaja.setMyUserAccount(Login); } else { isValidLogin(); } $(loadEle).Loading("close"); } /** * 登入驗證完成 Callback * */ function isValidLogin() { getUserInfo(); iniFroList(); showMainSys(); getBuiList(); getSysMonBtnList(); checkDevState(); loadNoticeConSta(); allDevices = getAllDevice(); if (lastPage) { let lastPageAct = {}; if (isJSON(sessionStorage.getItem("pageAct"))) { lastPageAct = JSON.parse(sessionStorage.getItem("pageAct")); } if ( (lastPageAct.sysSubTag && lastPage == "systemMonitor") || lastPage == "sysElevator" // || lastPage == "sysSensor" ) { $(`#subSysBtn${lastPageAct.sysSubTag}`).click(); $("#sysMonTopBtn").YTTab("set"); } 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"; ytAjax = new YourTeam.Ajax( url, null, function (res) { if (!res || res.code != "0000" || !res.data) { } else { let strHtml = ``; $.each(res.data, (index, buiObj) => { strHtml += `<a id="buiBtn${buiObj.building_tag}" data-urn="${buiObj.urn_3D}" class="dropdown-item" href="javascript:;">${buiObj.full_name}</a>`; }); $("#buiList").append(strHtml).droSetItem(); //droSetItem 預設第一筆 active } }, null, "POST" ).send(); } //lily test function checkDevState() { //TPE_B1_LT_L1 //main_system_tag: pageAct.sysMainTag, //building_tag: pageAct.buiTag, //floor_tag: pageAct.floTag, let systemPath = "TPE_B1"; // if (pageAct != undefined && pageAct != null && pageAct.sysMainTag != null && pageAct.buiTag != null) { // systemPath = "TPE_" + pageAct.buiTag + "_" + pageAct.sysMainTag + "_" + "EL"; // } getOneSystemAlarmStateByBaja(systemPath, callbackForCheckDevState); // console.log("systemP: " + systemPath); // console.log("devList: " + deviceList[0].device_guid + ", " + deviceList[3].device_guid + ", " + deviceList[8].device_guid); //callbackForCheckDevState("test"); } function callbackForCheckDevState(result) { // console.log("------ " + result); // $.each(deviceList, (index, devObj) => { // if ((`${devObj.device_guid}`) == '4ed28a93-5025-11ed-b23e-0242ac110002' // || (`${devObj.device_guid}`) == '5d9fdff0-5343-43fe-86f4-bd73cdb15111') { // var str = ""; // $(`#${devObj.device_guid}`).empty(); // str = `<span class="status status-danger d-inline-block"><img src="${baseImgUrl + varPathImg + devObj.device_master_icon}" class="profile-image rounded-circle" onerror="defDev(this)" alt="..."></span> ${devObj.full_name}`; // $(`#${devObj.device_guid}`).append(str); // } // }) // console.log(result); } } // page loaded callback function loadCallback() { initTabsByEle(); resetYTTooltip(); $("#sysMonTopBtn").YTNavbar("hide"); } // 事件先行讀取 function loadEvent() { onEvent("click", "[name=topFunBtn]", function () { _ytTabInited = []; let page = $(this).data("page"); if (!page) { return; } if ( page != "systemMonitor" && page != "sysElevator" // && page != "sysSensor" ) { $("#sysMonBtnList [name=topFunBtn]").removeClass("active"); pageAct.sysMainTag = null; pageAct.sysSubTag = null; } else { setSysTagForPageAct(this); $("#sysMonTopBtn").YTTab("set"); $(`#subSysBtn${pageAct.sysSubTag}`).YTTab("set"); } // 取消當前所有 baja 訂閱 $.each(tolSubList, (idx, sub) => { sub.unsubscribeAll(); sub.detach(); }); // 清空 baja 訂閱紀錄 tolSubList = []; // 清空 loading 狀態 endPageLoading(); // $(loadEle).Loading("close"); $(".yt-alert").YTAlert().hide(); // 取得使用者資訊 getUserInfo(); // 存取現在頁面 (重整讀取紀錄用) sessionStorage.setItem("lastPage", page); sessionStorage.setItem("pageAct", JSON.stringify(pageAct)); // 讀取子頁面 $("#app").load(`_${page}.html`, loadCallback); }); onEvent("click", "#logout", function () { localStorage.removeItem("JWT-Authorization"); location.href = "/logout"; }); onEvent("active:change", "#buiList", function (e, actEle) { if (actEle) { pageAct.buiTag = $(actEle).prop("id").split("buiBtn")[1]; pageAct.urn = $(actEle).data("urn"); } }); onEvent("yt:tab:change", "#lightSch-tab", function () { if (pageAct.sysMainTag == "LT" && $("#lightSchModal").length != 0) { setLightSchBlcok ? setLightSchBlcok(this) : ""; $("#lightSchModal").modal("show"); } }); onEvent( "yt:tab:prechange", "[data-tabname=topFunBtn]", function (e, arg) { if ($(this)[0].id == "sysMonTopBtn" || !$(this).data("page")) { arg.cancel = true; } } ); onEvent("scroll", window, function () { if ($(window).scrollTop() != 0) { $("#noticeBlock").css("top", 0); } else { $("#noticeBlock").css("top", 70); } }); onEvent("click", "#testsysbtn", function () { }); //onEvent("click", "button[id^=noticeChkBtn]", function () { // $(this).parents(".toast").YTNotice("hide"); //}) onEvent("click", "button[id^=noticeChkBtn]", function () { /**button[id^=bajaAckBtn] */ let uuid = $(this).data("uuid"); let url = window.location.origin + "/obix/alarm/" + uuid + "/ack"; let myBaja = new MyBaja(); myBaja.setMyUserAccount((data) => { let sendData = '<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>'; $.post( url, sendData, (rel) => { console.log(rel); $(this).parents(".toast").YTNotice("hide"); }, "text" ); }); }); onEvent("click", "#toggleNoticeBtn", function () { chaNoticeConSta(); }); $(window).on("timeout:3s", function () { getSystemAlarmByBaja((data) => { if (typeof getAlarmSub != "undefined" && getAlarmSub) { getAlarmSub(data); } alarmIconBlink(); }); getAlarm(); }); } // 登入驗證 function Login(account) { console.log(account); /*if ($("#login-form").valid()) {*/ var url = baseApiUrl + "/api/Login/"; var send_data = { account: account, password: "rJ2T5Kkj", }; if (location.href.indexOf("localhost:5966") != -1) { location.href = "login.html"; } $.ajax({ method: "post", url: url, data: JSON.stringify(send_data), async: false, contentType: "application/json; charset=UTF-8", dataType: "json", success: function (rel) { if (rel.code != "0000") { toast_error(rel.msg || common.SysErr); return; } else { /*toast_ok(rel.msg);*/ cookies.create( "JWT-Authorization", rel.data.token, 12 * 60 * 60 * 1000 ); isValidLogin(); } }, error: function (xhr, textStatus, thrownError) { alert(common.SysErr); }, }); } //============================================================================== // ↓ 系統監控 - 共用 Function ↓ //============================================================================== // Card - 基本資料 Table function drawInfoTabBlo(devGuid) { let tabEle = $( `<table class="table table-bordered table-striped text-center m-0">` ); let tbody = tabEle.append("<tbody>"); let columnNames = ["設備編號", "設備名稱"]; $.each(columnNames, (index, colName) => { let tr = $("<tr></tr>"); let td = $("<td></td>"); td.text(colName); tr.append(td); tbody.append(tr); }); let url = baseApiUrl + "/api/Device/GetBaseDevice"; let sendData = { device_guid: devGuid, }; objSendData.Data = sendData; ytAjax = new YourTeam.Ajax( url, objSendData, function (res) { if (!res || res.code != "0000" || !res.data) { } else { tbody .find("tr") .eq(0) .append(creEle("td", res.data.device_number)); tbody.find("tr").eq(1).append(creEle("td", res.data.full_name)); } }, null, "POST" ).send(); return tabEle.prop("outerHTML"); } // Card - 異常紀錄 block function drawErrRecTabBlo() { let strHtml = `<table id="errRecTable" class="table table-bordered table-striped text-center m-0 w-100"> </table>`; return strHtml; } // Card - 運維紀錄 block function drawOpeRecTabBlo() { let strHtml = `<table id="opeRecTable" class="table table-bordered table-striped text-center m-0 w-100"> </table>`; return strHtml; } // Card 呈現初始化 function initPopover( type = null, extOption = {}, selector = "[name=devItem]" ) { if (type == null && pageAct.sysMainTag == "LT") { type = "light"; } $(selector).each((index, ele) => { let devNum = $(ele).data("number"); //設備編號 let devGuid = $(ele).data("id"); //guid let devName = $(ele).data("name"); //full_name let lightHtml = type == "light" ? `<button type="button" data-toggle="tooltip" data-placement="bottom" title="燈控排程" id="lightSch-tab" class="px-2 btn btn-icon border-0 nav-link mx-1" role="tab" data-tabname="cardTab" data-target="#lightSch"><i class="fas fa-calendar-alt icon fa-2x"></i></button>` : ""; let option = { html: `<div class="card m-1 border device-wrap" data-number="${devNum}" data-position="left"> <div class="card-header p-3"> <div class="position-absolute mr-5" 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" data-toggle="tooltip" data-placement="bottom" title="即時監控" class="px-2 btn btn-icon border-0 nav-link active mx-1" role="tab" data-tabname="cardTab" data-target="#state"><i class="fa fa-desktop icon fa-2x"></i></button> ${lightHtml} <button type="button" id="info-tab" data-toggle="tooltip" data-placement="bottom" title="基本資料" class="px-2 btn btn-icon border-0 nav-link mx-1" role="tab" data-tabname="cardTab" data-target="#info"><i class="fa fa-cog icon fa-2x"></i></button> <button type="button" d data-toggle="tooltip" data-placement="bottom" title="告警資料" id="errRec-tab" class=" px-2 btn btn-icon border-0 nav-link mx-1 position-relative " role="tab" data-tabname="cardTab" data-target="#errRec"><i class="fas fa-exclamation-triangle fa-2x"></i></button> <button type="button" data-toggle="tooltip" data-placement="bottom" title="運維紀錄" id="opeRec-tab" class=" px-2 btn btn-icon border-0 nav-link mx-1" role="tab" data-tabname="cardTab" data-target="#opeRec"><i class="fa fa-bars icon fa-2x"></i></button> <button type="button" class="px-2 btn btn-icon border-0 nav-link mx-1"><i class="fas fa-times text-white-50 fa-2x" data-close="yttooltip"></i></button> </div> </div> <div class="card-body p-2 tab-content w-100"> <div id="state" class="show active w-100" data-tabname="cardTab" data-tabrole="child" > ${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>`, group: "device", // 在 _sysElevator.html 及 _sysMonAll.html 會用到 onShow: function (tooltipEle, oriEle) { // 執行 pop 視窗上方 Tab 類別 new YT.Tab({ tabName: "cardTab" }); // 系統監控才會有 data-devobj 屬性 let devObj = $(oriEle).data("devobj"); // 讀取運維列表 loadOpeRecTable(devGuid); // 讀取異常列表 loadErr($(oriEle).data("number")); // 讀取設備基本資料列表 $(tooltipEle) .find("#info") .html( typeof drawInfoTabBlo != "undefined" ? drawInfoTabBlo(devGuid) : "" ); // 聚焦熱點 const eleDbId = parseInt($(oriEle).data("dbId")); if (eleDbId) { if (alarmDbIdList.some((dbId) => dbId == eleDbId)) { changeScaleForHotspot(eleDbId); } else { controlFocusHotspot(eleDbId); } } // 3D 視角 ZOOM IN 聚焦 if (devObj) { console.log("devObj", devObj); moveViewToDevice(devObj?.forge_dbid); } // pop 視窗卡片可拖移功能初始化 $(tooltipEle).draggable({ cursor: "move", handle: ".card-header", // 只能通过卡片的标题栏拖拽 containment: "document", scroll: true, }); // pop 視窗卡片可縮放功能初始化 // $(tooltipEle).resizable({ // // resize: function (event, ui) { // // let iframe = $(ui.element).find("iframe"); // // if (iframe.length != 0) { // // if (ui.size.width != ui.originalSize.width) { // // iframe.css("width", "100%"); // // } else if (ui.size.height != ui.originalSize.height) { // // iframe.css("height", "100%"); // // } // // } // // let cardBodyHeight = $(ui.element).find(".card-body").css("height"); // // $(ui.element).find(".scrolledTable").css("height", cardBodyHeight) // // errRecTable.draw(false) // // }, // // minWidth: 200, // // minHeight: 150, // }); // 電梯管理 - Card table 更新 typeof subDeviceSetTable != "undefined" ? subDeviceSetTable($(oriEle).data("number")) : ""; }, onHide: function (tooltipEle, oriEle) { const eleDbId = $(oriEle).data("dbId"); if (eleDbId) { if (alarmDbIdList.some((dbId) => dbId == eleDbId)) { changeScaleForHotspot(eleDbId, false); } else { // 3D 熱點解除 controlFocusHotspot(eleDbId, false); } } // sysMonFloor Echart 解除 focus typeof chartUnFocus != "undefined" ? chartUnFocus(oriEle) : ""; }, }; $.extend(option, extOption); $(ele).YTTooltip(option); }); } // 卡片設備名稱點擊事件 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) { opeRecTable.destroy(); } let url = baseApiUrl + "/api/Device/GetOpeDevice?device_guid=" + devGuid; let tag = "#opeRecTable"; let column_defs = [ { targets: [0], width: "8%", sortable: true }, { targets: [1], width: "8%", sortable: true }, { targets: [2], width: "7%", sortable: true }, { targets: [3], width: "7%", sortable: true }, ]; let columns = [ { title: "類型", data: "work_type_name", }, { title: "項目", data: "fix_do", }, { title: "處理人員", data: "work_person_name", }, { title: "發生/完成時間", data: "finishTime", render: function (data, type, row) { return row.createdAt + "<br>" + data; }, }, ]; opeRecTable = new YourTeam.JqDataTables.getTableByAjax( url, tag, null, columns, column_defs, null, null, null, null, null, null, "<'scrolledTable'tpi>" ); } function loadLightSchTable(devGuid) { /*let url = baseApiUrl + "/api/Device/GetOpeDevice?device_guid=" + devGuid;*/ let url = `https://63772efc5c47776512165937.mockapi.io/api/GetLightSche`; let tag = "#lightSchTable"; let column_defs = [ { targets: [0], width: "14%", sortable: true }, { targets: [1], width: "14%", sortable: true }, { targets: [2], width: "14%", sortable: true }, { targets: [3], width: "14%", sortable: true }, { targets: [4], width: "14%", sortable: true }, { targets: [5], width: "14%", sortable: true }, { targets: [6], width: "16%", sortable: true }, ]; let columns = [ { title: "序號", data: null, render: function (data, type, row, meta) { return meta.row + 1; }, }, { title: "排程名稱", data: "sch_name", }, { title: "設備數量", data: "dev_cnt", }, { title: "排程設定", data: "sch_set", }, { title: "動作", data: "action", }, { title: "狀態", data: "status", }, { title: "功能", data: "sch_id", render: function (data, type, row) { let btnDiv = creDiv(["row", "m-0", "justify-content-center"], { style: "gap:10px", }); let icon = creI(["fas", "fa-pencil-alt"]); btnDiv.append( creBtnHtml("觸發執行", "lightSchTabTogBtn" + data, null, [ "btn", "btn-success", ]) ); btnDiv.append( creBtn( "修改", "lightSchTabEdiBtn" + data, null, ["btn", "btn-danger"], { toggle: "modal", target: "#delModal" } ).append(icon) ); return btnDiv.outerHtml(); }, }, ]; let lightSchTable = new YourTeam.JqDataTables.getTableByAjax( url, tag, null, columns, column_defs, null, null, null, null, null, null, "tpi" ); } function controlFocusHotspot(dbId, open = true) { pageAct.sysSubTag !== "L1" && pageAct.sysSubTag !== "M12" && console.log("dbId", dbId); pageAct.sysSubTag !== "L1" && pageAct.sysSubTag !== "M12" && changeColorForHotspot(dbId, open ? "focus" : null); changeScaleForHotspot(dbId, open); } // Baja 取得異常紀錄 function loadErr(allPath) { if (allPath != undefined && allPath != null) { getOneDeviceAlarmTop10ByBaja(allPath, callbackForErr); } else { console.log("no device"); } } // Card - 異常紀錄 Table function callbackForErr(result) { // console.log("@@@",result) if (errRecTable) { errRecTable.destroy(); } let tag = "#errRecTable"; let datas; let column_defs = [ { targets: [0], width: "15%", sortable: true }, { targets: [1], width: "25%", sortable: true }, { targets: [2], width: "25%", sortable: true }, { targets: [3], width: "35%", sortable: true }, ]; let columns = [ { title: "異常ID", data: "uuid", }, { title: "異常原因", data: "msgText", }, { title: "ACK確認", data: "ackState", }, { title: "發生/完成時間", data: "normalTime", // "render": function (data, type, row) { // return row.timestamp + "<br>" + data; // }, }, ]; let json_object = JSON.parse(result); datas = json_object["data"]; errRecTable = new YourTeam.JqDataTables.getTableByStatic( tag, datas, columns, column_defs, null, null, null, null, "<'scrolledTable'tpi>" ); } //根據 data-type 設置顏色 (判斷後台是否有設定,若無則帶預設) function setLightColor() { $("[data-light-type]").each((index, ele) => { let type = $(ele).data("light-type"); let isFlashing = false; let color = "#000"; switch (type) { case "normal": color = pageAct.sysSubObj.device_normal_color ?? "var(--theme-success)"; isFlashing = pageAct.sysSubObj.device_normal_flashing == "1"; break; case "close": color = pageAct.sysSubObj.device_close_color ?? "var(--theme-secondary)"; isFlashing = pageAct.sysSubObj.device_close_flashing == "1"; break; case "error": color = pageAct.sysSubObj.device_error_color ?? "var(--theme-danger)"; isFlashing = pageAct.sysSubObj.device_error_flashing == "1"; break; } $(ele).css("background-color", color); //是否閃爍 if (isFlashing) { $(ele).parents(".device-wrap").addClass("light-flash"); } else { $(ele).parents(".device-wrap").removeClass("light-flash"); } }); } // 設置昇位圖上方 燈號 function setTopLight() { let sysSubObj = pageAct.sysSubObj; let strHtml = ``; if ( sysSubObj.device_normal_point_name != null && sysSubObj.device_normal_point_value != null ) { strHtml += ` <div class="row m-0 align-items-center"> <span id="sysNorLight" class="circle-light mr-2 " data-light-type="normal"></span> <label class="mb-0">${sysSubObj.device_normal_text}</label> </div>`; } if ( sysSubObj.device_close_point_name != null && sysSubObj.device_close_point_value != null ) { strHtml += ` <div class="row m-0 align-items-center"> <span id="sysCloLight" class="circle-light mr-2" data-light-type="close"></span> <label class="mb-0">${sysSubObj.device_close_text}</label> </div>`; } if ( sysSubObj.device_error_point_name != null && sysSubObj.device_error_point_value != null ) { strHtml += ` <div class="row m-0 align-items-center"> <span id="sysErrLight" class="circle-light mr-2" data-light-type="error"></span> <label class="mb-0">${sysSubObj.device_error_text}</label> </div>`; } return strHtml; } function crePosPopover(position, obj) { let _position = {}; _position.tpLeft = position[0]; _position.tpTop = position[1]; _position.tpOffHeight = 24; let parentEle = creDiv(); parentEle.append( `<a href="javascript:;" name="devItem" class=" ml-2 mb-0 ">詳細資料</a>` ); parentEle.data("id", obj.device_guid); parentEle.data("number", obj.device_number); parentEle.data("dbId", obj._dbId); parentEle.data("name", obj.full_name || obj.device_node_full_name); console.log("crePosPopover", parentEle.data()); initPopover(null, _position, parentEle); return parentEle; } // 設置 Forge 3D 溫度條 function setTopHeatBar() { let strHtml = `<canvas name="forgeHeatBar" width="200" height="30" style="position: absolute; z-index:9999"></canvas>`; return strHtml; } //============================================================================== // ↑ 系統監控 - 共用 Function ↑ //============================================================================== } catch (e) { $(loadEle).Loading("close"); } function setSysTagForPageAct(obj) { pageAct.sysMainTag = $(obj).data("subSysObj").main_system_tag; pageAct.sysSubTag = $(obj).data("subSysObj").sub_system_tag; pageAct.sysSubName = $(obj).data("subSysObj").full_name; pageAct.sysSubObj = $(obj).data("subSysObj"); getDevItem(); } function getDevItem() { let url = baseApiUrl + "/api/Device/GetDeviceItem"; objSendData.Data = { main_system_tag: pageAct.sysMainTag, sub_system_tag: pageAct.sysSubTag, }; ytAjax = new YourTeam.Ajax( url, objSendData, function (res) { if (!res || res.code != "0000" || !res.data) { } else { pageAct.devItems = res.data; } }, null, "POST" ).send(); } function alarmIconBlink(data) { if (data?.data.length != 0) { $(".page-header [name=topFunBtn][data-page=alert] i").addClass( "blink" ); } else { $(".page-header [name=topFunBtn][data-page=alert] i").removeClass( "blink" ); } } 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"); }, 3000); } if (Object.keys(events).findIndex((x) => x == "timeout:5m") != -1) { timeOut5m = setInterval(() => { $(window).trigger("timeout:5m"); }, 5 * 60 * 1000); } timeOuters = timeOuters.concat([timeOut3s, timeOut5m]); } function showMainSys() { let url = baseApiUrl + "/Utility/isShowMaiSys"; ytAjax = new YourTeam.Ajax( url, null, function (res) { if (!res || res.code != "0000") { } else { pageAct.mainStatus = res.data; } }, null, "POST" ).send(); } function startPageLoading() { if (!loadingTip) { loadingTip = YT.Alert.Tip("資料讀取中...", "show"); } } function endPageLoading() { if (loadingTip != null) { $(loadingTip.ele).YTAlert().hide(); loadingTip = null; } } function iniFroList() { url = baseApiUrl + "/api/GetUsrFroList"; let hasMonitor = false; ytAjax = new YourTeam.Ajax( url, null, function (res) { if (!res || res.code != "0000" || !res.data) { } 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>`; $.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> </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>`; } }); $("#froLisPage").html(strHtml); $("#sysMonTopBtn").YTNavbar("init"); } }, null, "POST" ).send(); } function getSysMonBtnList() { let url = baseApiUrl + "/api/Device/GetMainSub"; let sendData = { building_tag: pageAct.buiTag, }; objSendData.Data = sendData; ytAjax = new YourTeam.Ajax( url, objSendData, function (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"; if (subSysObj.sub_system_tag == "EL") { page = "sysElevator"; } // console.log(subSysObj.sub_system_tag) // if (subSysObj.sub_system_tag == "M12") { // page = "sysSensor"; // } let li = creEle("li"); let a = creA( subSysObj.full_name, { href: "javascript:;" }, [], `subSysBtn${subSysObj.sub_system_tag}`, { page: page, tabname: "systemMonitor" }, "topFunBtn" ); li.append(a); a.data("subSysObj", subSysObj); subSysObj.main_system_tag = mainSysObj.main_system_tag; $("#sysMonBtnList").append(li); }); }); } }, null, "POST" ).send(); } 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"; ytAjax = new YourTeam.Ajax( url, null, function (res) { if (!res || res.code != "0000") { } else { pageAct.userInfo = res.data; let user = res.data; $("#usrName").text(user.full_name); } }, null, "POST" ).send(); } var noticeOptArr = []; function getAlarmFromDB() { let url = baseApiUrl + "/api/AlarmCard"; ytAjax = new YourTeam.Ajax( url, null, function (res) { if (!res || res.code != "0000" || !res.data) { } else { let datas = res.data; } }, null, "POST", true ).send(); } function getAlarm() { let now = new Date().getTime(); let noticeObj = [ { title: "異常編號", data: "uuid" }, { title: "異常等級", data: "priority" }, { title: "異常類別", data: "alarmClass" }, { title: "設備名稱", data: "full_name" }, { title: "異常訊息", data: "msgText" }, ]; // 向 niagara 取得告警資料 getDeviceAlarmCardByBaja(null, now, false, false, function (bajaDatas) { let datas = bajaDatas.data; let titleHtml = `異常通知`; let notices = []; // 遍歷每個告警資料 $.each(datas ?? [], (idx, data) => { if (noticeOptArr.findIndex((x) => x.id == data.uuid) == -1) { // 針對該告警對象的設備,從 allDevices 找出設備名稱 datas[idx].full_name = allDevices.filter( (x) => x.device_number == data.devicePath )[0]?.full_name; let div1 = creDiv(["col-12"]); let button = creBtn( "確認", "noticeChkBtn", null, ["btn btn-sm btn-secondary ml-auto col-4"], { uuid: data.uuid } ); let btnDiv = creDiv(["d-flex m-0 gap-5 mt-2"]); btnDiv.append(button); // 繪製 每行告警資訊 noticeObj.forEach((notice) => { let div2 = creDiv(["row", "m-0"]); let span1 = creSpan(notice.title + ":", ["m-0"]); if (notice.data === "uuid") { data[notice.data] = data[notice.data].split("-")[0]; } span1.append(creSpan(data[notice.data])); div2.append(span1); div1.append(div2); }); div1.append(btnDiv); // 拚湊 YTNotice 通知套件所需參數 let main = { title: titleHtml, content: div1.outerHtml(), type: "warning", id: data.uuid, hasCloseBtn: true, timeText: displayDate(data.timestamp), }; noticeOptArr.push(main); notices.push(main); } }); if (notices.length != 0) { $("#noticeBlock").YTNotice( "add_many", notices.oSort("id").reverse() ); } }); } function getAllDevice() { let url = baseApiUrl + "/api/Device/GetAllDevice"; let result = []; ytAjax = new YourTeam.Ajax( url, null, function (res) { if (!res || res.code != "0000" || !res.data) { } else { result = res.data; } }, null, "POST" ).send(); return result; } function loadNoticeConSta() { let noticeStatus = localStorage.getItem("noticeStatus"); chaNoticeConSta(noticeStatus ?? "show"); } function chaNoticeConSta(type = null) { let showText = $("#toggleNoticeBtn #noticeConText").data("show"); let hideText = $("#toggleNoticeBtn #noticeConText").data("hide"); let iconArr = ["fal fa-comment-slash", "fal fa-comment-dots"]; $("#noticeConIcon").removeClass(iconArr[0]).removeClass(iconArr[1]); if (type != null) { if (type == "hide") { setHide(); } else if (type == "show") { setShow(); } } else { if ($("#noticeBlock").is(":visible")) { setHide(); } else if (!$("#noticeBlock").is(":visible")) { setShow(); } } function setShow() { $("#toggleNoticeBtn").find("#noticeConText").text(hideText); $("#noticeConIcon").addClass(iconArr[0]); $("#noticeBlock").show(); $("#noticeBlock").animate({ opacity: 1 }, 200); localStorage.setItem("noticeStatus", "show"); } function setHide() { $("#toggleNoticeBtn").find("#noticeConText").text(showText); $("#noticeConIcon").addClass(iconArr[1]); $("#noticeBlock").animate({ opacity: 0 }, 200, function () { $("#noticeBlock").hide(); }); localStorage.setItem("noticeStatus", "hide"); } } </script> </body> <!-- END Body --> </html>