[Frontend][系統監控] 電梯 class 建置 | 切換2D/3D紐建置

This commit is contained in:
dev01 2022-11-28 12:38:19 +08:00
parent 8236dad38b
commit b871f5063e
5 changed files with 175 additions and 76 deletions

View File

@ -18,6 +18,13 @@
elevator .elevator-body, elevator .elevator-header { elevator .elevator-body, elevator .elevator-header {
padding: 0.7rem; padding: 0.7rem;
} }
.elevator-item {
position: absolute;
width: 43px;
height: 47px;
border: 4px solid orange;
}
</style> </style>
<div class="d-flex"> <div class="d-flex">
@ -27,14 +34,21 @@
<div style="position:relative "> <div style="position:relative ">
<div id="elevatorBlock" class="elevator"> <div id="elevatorBlock" class="elevator">
<div class="elevator-header"> <div class="elevator-header">
<div class="row m-0 align-items-center p-2 gap-3 btn-group btn-group-toggle">
<button class="btn btn-secondary btn-sm active" data-tabname="floShowType" data-target="#2dDiv">2D
</button>
<button class="btn btn-secondary btn-sm" data-tabname="floShowType" data-target="#3dDiv">3D
</button>
</div>
</div> </div>
<div class="elevator-body d-flex align-items-center justify-content-center h-100 yt-table-container"> <div class="elevator-body d-flex align-items-center justify-content-center yt-table-container">
<div id="floorTable_wrapper" class="elevator-build-container"> <div id="2dDiv" data-tabname="floShowType" data-tabrole="child">
<table id="floorTable" class="elevator-build m-auto"> <table id="floorTable" class="elevator-build m-auto">
</table> </table>
</div> </div>
<div id="3dDiv" data-tabname="floShowType" data-tabrole="child">
</div>
</div> </div>
</div> </div>
<!--<div> <!--<div>
@ -139,7 +153,7 @@
</label> </label>
</div> </div>
<div> <div>
<label id="groConFailText" class="form-check-label h4" for="flexRadioDefault1"> <label id="groConFailText" class="form-check-label h4" for="flexRadioDefault1">
未動作 未動作
</label> </label>
</div> </div>
@ -154,7 +168,7 @@
</label> </label>
</div> </div>
<div> <div>
<label id="emerPowerText" class="form-check-label h4" for="flexRadioDefault1"> <label id="emerPowerText" class="form-check-label h4" for="flexRadioDefault1">
未動作 未動作
</label> </label>
</div> </div>
@ -861,8 +875,6 @@
</div> </div>
<script> <script>
var floors = ["B2F", "B1F", "1F", "2F", "3F", "4F", "5F", "6F"];
var eleManTable = null; var eleManTable = null;
var allDevList = []; var allDevList = [];
var subSeviceData = []; var subSeviceData = [];
@ -879,7 +891,7 @@
var zoomToggle = 3; var zoomToggle = 3;
$(function () { $(function () {
initChart(); initChart();
setBuildFloor(floors.length, 3); setBuildFloor();
setCards(); setCards();
subDeviceSetStatus(); subDeviceSetStatus();
setEleManTable(); setEleManTable();
@ -944,13 +956,13 @@
//地震管制 //地震管制
actLightByPoi("EER", "#earQuaCon"); actLightByPoi("EER", "#earQuaCon");
//將訂閱值塞入 subSeviceData //將訂閱值塞入 subSeviceData
if (subSeviceData.findIndex(x => x.device_number == matchDevice.device_number) == -1) { if (subSeviceData.findIndex(x => x.device_number == matchDevice.device_number) == -1) {
let obj = {}; let obj = {};
obj.device_number = matchDevice.device_number; obj.device_number = matchDevice.device_number;
subSeviceData.push(obj) subSeviceData.push(obj)
} }
let subData = subSeviceData.filter(x => x.device_number == matchDevice.device_number)[0]; let subData = subSeviceData.filter(x => x.device_number == matchDevice.device_number)[0];
@ -996,13 +1008,13 @@
result.push(main); result.push(main);
}) })
}) })
console.log("redraw",result) console.log("redraw", result)
return result; return result;
} }
// Card - 設置列表中訂閱內容 // Card - 設置列表中訂閱內容
function subDeviceSetTable(devNum) { function subDeviceSetTable(devNum) {
let subData = subSeviceData.filter(x => x.device_number == devNum)[0] let subData = subSeviceData.filter(x => x.device_number == devNum)[0]
let matchDevice = allDevList.filter(x => x.device_number == devNum)[0]; let matchDevice = allDevList.filter(x => x.device_number == devNum)[0];
if (!subData) { if (!subData) {
@ -1017,7 +1029,7 @@
let masterTag = devNum?.split("_")[5]; let masterTag = devNum?.split("_")[5];
let notSerFloors = Object.keys(subData).filter(x => x.startsWith("SP_FLS_") && subData[x] == "trueText").map(x => x?.split("SP_FLS_")[1]); let notSerFloors = Object.keys(subData).filter(x => x.startsWith("SP_FLS_") && subData[x] == "trueText").map(x => x?.split("SP_FLS_")[1]);
//現在樓層 //現在樓層
if (subData["CP"]) { if (subData["CP"]) {
$(`#imdStaTable_${devNum} [name=curFloor]`).text(subData["CP"] + "F"); $(`#imdStaTable_${devNum} [name=curFloor]`).text(subData["CP"] + "F");
@ -1091,52 +1103,24 @@
} }
//左側 2D 樓層 Table //左側 2D 樓層 Table
function setBuildFloor(floorCnt = 10, eleCnt = 3) { function setBuildFloor() {
let tbody = creEle("tbody"); let options = {
//樓層從小到大 floors: [
let rfloors = floors.reverse(); { name: "B2F", sort: 0 },
let eleCircle = creDiv(["elevator-circle"]); { name: "B1F", sort: 1 },
//樓層表格建置 { name: "1F", sort: 2 },
for (let f = 1; f <= floorCnt; f++) { { name: "2F", sort: 3 },
let tr = creEle("tr"); { name: "3F", sort: 4 },
for (let e = 1; e <= eleCnt + 2; e++) { { name: "4F", sort: 5 },
let td = creEle("td"); { name: "5F", sort: 6 },
if (e == 1) { { name: "6F", sort: 7 },
td.addClass("t-black") ],
td.text(rfloors[f - 1]);
} else if (e == eleCnt + 2) {
}
else {
let div = creDiv(["d-flex", "justify-content-center", "align-items-end", "h-100"]);
div.append(`<i class="fas fa-door-open fs-1-05"></i>`)
td.append(div)
}
tr.append(td);
}
tbody.append(tr);
$("#floorTable_wrapper").append(eleCircle)
} }
$("#floorTable").html(tbody); let eleObj = new ElevatorHandler("#floorTable", options);
$("#floorTable tbody tr").each((index, tr) => {
$(tr).find("td:eq(0)").css("border-left", "0");
$(tr).find("td:eq(-1)").css("border-right", "0");
if (index == 0) {
$(tr).find("td").each((index, td) => {
$(td).css("border-top", "0");
})
} else if (index == $("#floorTable tbody tr").length - 1) {
$(tr).find("td").each((index, td) => {
$(td).css("border-bottom", "0");
})
}
})
} }
function drawStateTabBlo(devNum) { function drawStateTabBlo(devNum) {
@ -1164,7 +1148,7 @@
] ]
let data = [{ let data = [{
row: 0, col: 2, style:"vertical-align:middle", row: 0, col: 2, style: "vertical-align:middle",
data: `<div class="flex-column"> data: `<div class="flex-column">
<i name="upFloArrow" class="fas fa-caret-up fa-3x ml-auto" style="--flash-color-1:#6fe560;--flash-color-2:#fff;"></i> <i name="upFloArrow" class="fas fa-caret-up fa-3x ml-auto" style="--flash-color-1:#6fe560;--flash-color-2:#fff;"></i>
<h4 name="curFloor" class="d-flex justify-content-center mb-0"></h4> <h4 name="curFloor" class="d-flex justify-content-center mb-0"></h4>
@ -1238,7 +1222,7 @@
} }
function reloadEleManTable(datas) { function reloadEleManTable(datas) {
let tabCols = eleManTable.context[0].aoColumns.map(x => x.data); let tabCols = eleManTable.context[0].aoColumns.map(x => x.data);
$.each(datas, (idx, data) => { $.each(datas, (idx, data) => {
$.each(tabCols, (idx2, value) => { $.each(tabCols, (idx2, value) => {
@ -1247,14 +1231,14 @@
} }
}) })
}) })
eleManTable.clear().rows.add(datas).draw(); eleManTable.clear().rows.add(datas).draw();
} }
function setEleManTable() { function setEleManTable() {
let tag = "#eleManTable"; let tag = "#eleManTable";
let datas = []; let datas = [];
let column_defs = [ let column_defs = [
{ "targets": [0], "width": "11%", "sortable": true }, { "targets": [0], "width": "11%", "sortable": true },
{ "targets": [1], "width": "11%", "sortable": true }, { "targets": [1], "width": "11%", "sortable": true },
@ -1311,12 +1295,12 @@
{ {
"title": "動作", "title": "動作",
"data": null, "data": null,
"className":"text-center", "className": "text-center",
"render": function (data, type, row) { "render": function (data, type, row) {
let btn = ''; let btn = '';
if (row._rowType == "master") { if (row._rowType == "master") {
btn = creBtn("編輯", "eleManMasEdit" + row.devName, null, ["btn", "btn-info"]); btn = creBtn("編輯", "eleManMasEdit" + row.devName, null, ["btn", "btn-info"]);
} else if (row._rowType == "device"){ } else if (row._rowType == "device") {
btn = creBtn("編輯", "eleManDevEdit" + row.devNum, null, ["btn", "btn-info"]); btn = creBtn("編輯", "eleManDevEdit" + row.devNum, null, ["btn", "btn-info"]);
} }
btn.append(`<i class="fal fa-pen pl-1"></i>`); btn.append(`<i class="fal fa-pen pl-1"></i>`);
@ -1342,7 +1326,7 @@
function bajaValToBool(boolText) { function bajaValToBool(boolText) {
return boolText == "trueText"; return boolText == "trueText";
} }
$("#eleManModal #detDevDiv [name=devName]").text(matchDevice.full_name); $("#eleManModal #detDevDiv [name=devName]").text(matchDevice.full_name);
$("#eleManModal #detDevDiv [name=status]").text(subData["ST"]); $("#eleManModal #detDevDiv [name=status]").text(subData["ST"]);
$("#eleManModal #detDevDiv [name=curFloor]").text(subData["CP"] + "F"); $("#eleManModal #detDevDiv [name=curFloor]").text(subData["CP"] + "F");
@ -1371,9 +1355,9 @@
// 電梯管理 Modal - 不服務樓層 設定列表 // 電梯管理 Modal - 不服務樓層 設定列表
function setNotSerFloTable(floors) { function setNotSerFloTable(floors) {
let tbody =$("<tbody></tbody>"); let tbody = $("<tbody></tbody>");
let rows = []; let rows = [];
$.each(floors, (idx, floor) => { $.each(floors, (idx, floor) => {
rows.push({ id: floor, text: floor }); rows.push({ id: floor, text: floor });
}) })
@ -1420,17 +1404,17 @@
let scheBtn = ["preMeaSche", "stopSche", "onlyOpeSche", "vipSche", "retOpeSche"]; let scheBtn = ["preMeaSche", "stopSche", "onlyOpeSche", "vipSche", "retOpeSche"];
$("#bajaSche").html(""); $("#bajaSche").html("");
// 電梯管理 Modal 切換到 detail 頁面 // 電梯管理 Modal 切換到 detail 頁面
modalTogDiv("#eleManModal", "#tabDiv", "#detDevDiv","next", function () { modalTogDiv("#eleManModal", "#tabDiv", "#detDevDiv", "next", function () {
subDeviceSetEleManDet(devNum); subDeviceSetEleManDet(devNum);
$.each(scheBtn, (idx, scheSelector) => { $.each(scheBtn, (idx, scheSelector) => {
onEvent("click", `#${scheSelector}`, function() { onEvent("click", `#${scheSelector}`, function () {
let devNumPath = devNum.split("_").join("/"); let devNumPath = devNum.split("_").join("/");
let point = $(this).data("point"); let point = $(this).data("point");
let ifHtml = `<iframe src="http://localhost:8080/ord?station:%7Cslot:${devNumPath}/Sch_${point}|view:?fullScreen=true" width="100%" height="100%" style="height:30rem"></iframe>` let ifHtml = `<iframe src="/ord?station:%7Cslot:${devNumPath}/Sch_${point}|view:?fullScreen=true" width="100%" height="100%" style="height:30rem"></iframe>`
$("#bajaSche").html(ifHtml); $("#bajaSche").html(ifHtml);
}) })
}) })
}) })
}) })
@ -1443,7 +1427,7 @@
modalTogDiv("#eleManModal", "#tabDiv", "#detMasDiv", "next", function () { modalTogDiv("#eleManModal", "#tabDiv", "#detMasDiv", "next", function () {
subDeviceSetEleManNotSerFloor(master); subDeviceSetEleManNotSerFloor(master);
let devNumPath = subData.device_number?.split("_").join("/"); let devNumPath = subData.device_number?.split("_").join("/");
let ifHtml = `<iframe src="http://localhost:8080/ord?station:%7Cslot:${devNumPath}/Sch_FLS|view:?fullScreen=true" width="100%" height="100%" style="height:30rem"></iframe>` let ifHtml = `<iframe src="/ord?station:%7Cslot:${devNumPath}/Sch_FLS|view:?fullScreen=true" width="100%" height="100%" style="height:30rem"></iframe>`
$("#bajaMasSche").html(ifHtml); $("#bajaMasSche").html(ifHtml);
}) })
@ -1452,8 +1436,8 @@
// 切換 modal 內 div 頁面 // 切換 modal 內 div 頁面
function modalTogDiv(modal, div1, div2, type = "next", callback = null) { function modalTogDiv(modal, div1, div2, type = "next", callback = null) {
$(modal).find(div1).parent("div").css("overflow", "hidden"); $(modal).find(div1).parent("div").css("overflow", "hidden");
$(modal).find(div1).css({ "position":"relative"}); $(modal).find(div1).css({ "position": "relative" });
$(modal).find(div2).css({ "position": "relative"}); $(modal).find(div2).css({ "position": "relative" });
let aniDiv1Obj = {}, aniDiv2Obj = {}; let aniDiv1Obj = {}, aniDiv2Obj = {};
if (type == "next") { if (type == "next") {
aniDiv1Obj.left = "-200%"; aniDiv1Obj.left = "-200%";

View File

@ -2701,8 +2701,8 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
} }
$.each(tolSubList, (idx, sub) => { $.each(tolSubList, (idx, sub) => {
console.log("sub",sub,idx) console.log("sub",sub,idx)
//sub.unsubscribeAll(); sub.unsubscribeAll();
//sub.detach(); sub.detach();
}) })
$("#app").load(`_${page}.html`, loadCallback); $("#app").load(`_${page}.html`, loadCallback);
}) })

View File

@ -106,4 +106,104 @@ function creSelect(id = null, cls = [], name = null, data = {}, attr = {}, text
function creOption(text = null, value = null, data = {}, attr = {}, cls = [], name = null, id = null) { function creOption(text = null, value = null, data = {}, attr = {}, cls = [], name = null, id = null) {
attr = value != null ? attr.value = value : attr; attr = value != null ? attr.value = value : attr;
return creEle("option", text, id, name, cls, data, attr); return creEle("option", text, id, name, cls, data, attr);
}
class ElevatorHandler {
constructor(ele, option = {}) {
this.ele = ele;
this.eleId = "";
this.eleWra = $("<div></div>");
this.speed = 0;
this.monStatus = 0; // 0=no 1=up 2=down
this.floorHeight = typeof option.fHeight == "undefined" ? 50 : option.fHeight;
this.floorWidth = typeof option.fWidth == "undefined" ? 45 : option.fWidth;
this.floors = typeof option.floors == "undefined" ? [{}] : option.floors;
this.eleCnt = typeof option.eleCnt == "undefined" ? 3 : option.eleCnt;
this.init();
}
init = function () {
this.setTabWra();
this.setTabFloor();
}
// 設置 wrapper
setTabWra = function () {
let id = $(this.ele).prop("id");
this.eleId = id;
if ($(this.ele).parent(".elevator-table-wrapper").length != 0) {
$(this.ele).unwrap(".elevator-table-wrapper");
}
let wrapper = creDiv(["elevator-table-wrapper"], null, `${id}_wrapper`);
$(this.ele).wrap(wrapper);
this.eleWra = wrapper;
}
// 設置 table 樓層
setTabFloor = function () {
let _w = this.floorWidth, _h = this.floorHeight;
let thead = creEle("thead"), tbody = creEle("tbody");
let _floors = this.floors, _ele = this.ele, _eleCnt = this.eleCnt;
//樓層從小到大
_floors = _floors.oSort("sort").reverse().map(x => x.name);
let theadTr = creEle("tr");
for (let e = 1; e <= _eleCnt + 2; e++) {
let th = creEle("th");
th.css({ "width": `${_w}px`, "height": `${_h}px` });
if (e != 1 && e != _eleCnt + 2) {
// 電梯方框
let span = creEle("span", null, "elevator-item-" + (e - 1), null, ["elevator-item"]);
span.css({ "width": `${_w - 3}px`, "height": `${_h - 3}px`, "top": `1.5px`})
th.append(span);
}
theadTr.append(th);
}
thead.css("position", "absolute");
thead.append(theadTr);
//樓層表格建置 tbody
for (let f = 1; f <= _floors.length; f++) {
let tr = creEle("tr");
for (let e = 1; e <= _eleCnt + 2; e++) {
let td = creEle("td");
td.css({ "width": `${_w}px`, "height": `${_h}px` });
if (e == 1) {
td.addClass("t-black")
td.text(_floors[f - 1]);
} else if (e == _eleCnt + 2) {
}
else {
let div = creDiv(["d-flex", "justify-content-center", "align-items-end", "h-100"]);
div.append(`<i class="fas fa-door-open fs-1-05"></i>`)
td.append(div)
}
tr.append(td);
}
tbody.append(tr);
}
$(_ele).append(thead);
$(_ele).append(tbody);
//表格外圍無框線
$(_ele).find("tbody tr").each((index, tr) => {
$(tr).find("td:eq(0)").css("border-left", "0");
$(tr).find("td:eq(-1)").css("border-right", "0");
if (index == 0) {
$(tr).find("td").each((index, td) => {
$(td).css("border-top", "0");
})
} else if (index == $("#floorTable tbody tr").length - 1) {
$(tr).find("td").each((index, td) => {
$(td).css("border-bottom", "0");
})
}
})
}
} }

View File

@ -51,6 +51,19 @@ Array.prototype.DistinctBy = function (...otherCol) {
return result; return result;
} }
Array.prototype.nSort = function () {
function compareNumbers(a, b) {
return a - b;
}
return this.sort(compareNumbers);
}
Array.prototype.oSort = function (key) {
function compareNumbers(a, b) {
return a[key] - b[key];
}
return this.sort(compareNumbers);
}
BigInt.prototype.toJSON = function () { return this.toString() } BigInt.prototype.toJSON = function () { return this.toString() }
$.fn.classList = function () { return this[0].className.split(/\s+/); }; $.fn.classList = function () { return this[0].className.split(/\s+/); };

View File

@ -71,7 +71,7 @@ $.fn.YTTooltip = function (option) {
obj.tooltipDiv = clone; obj.tooltipDiv = clone;
//顯示 tooltip //顯示 tooltip
$(clone).css({ "display": display, "position": "absolute" }); $(clone).css({ "display": display, "position": "absolute" });
obj.onShow ? obj.onShow(clone,obj.ele,obj) : "";
//tooltip 高寬 //tooltip 高寬
let toolWidth = $(clone)[0].offsetWidth; let toolWidth = $(clone)[0].offsetWidth;
let toolHeight = $(clone)[0].offsetHeight; let toolHeight = $(clone)[0].offsetHeight;
@ -95,7 +95,9 @@ $.fn.YTTooltip = function (option) {
} else if (obj.direction == "top" || obj.direction == "bottom"){ } else if (obj.direction == "top" || obj.direction == "bottom"){
$(clone).css({ left: offset.left, top: top}); $(clone).css({ left: offset.left, top: top});
} }
setTimeout(function () {
obj.onShow ? obj.onShow(clone, obj.ele, obj) : "";
}, 10)
event(); event();
} else { } else {
obj.hideTooltipEvent(tooId); obj.hideTooltipEvent(tooId);