[Frontend] 告警通知從 niagara 取資料並可以發送ack確認程序建置 | [儀錶板] 圖表 x 軸文字調整 | [即時告警] 修復全選資料出不來問題 | [圖資管理] 修復上傳照片有誤問題 | [歷史資料] active 呈現程序建置

This commit is contained in:
dev01 2023-01-18 17:49:25 +08:00
parent fecc34b121
commit e43389724f
8 changed files with 169 additions and 130 deletions

View File

@ -470,7 +470,6 @@
$('#confirmed').addClass('btn-info');
$('#unconfirmed').addClass('btn-secondary');
}
if (!first)
getData();
}
@ -619,7 +618,7 @@
}
function callBackFromAllDeviceAlert(res) {
res = JSON.parse(res);
refTable(res.data);
if (historyTable != null) {
let t = $('#alertTable').dataTable();
@ -850,9 +849,7 @@
}
function chgAck(devUuid) {
$.post(window.location.origin + '/obix/alarm/' + devUuid + '/ack', '<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>', function () {
}, "text");
$.post(window.location.origin + '/obix/alarm/' + devUuid + '/ack', '<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>', null, "text");
getData();
}
</script>

View File

@ -483,11 +483,6 @@
x: {
offset: true,
grid: { color: color.fusion._500 },
ticks: {
callback: function (value, index, ticks) {
return value
}
},
},
y: {
beginAtZero: true,
@ -572,11 +567,6 @@
x: {
offset: true,
grid: { color: color.fusion._500 },
ticks: {
callback: function (value, index, ticks) {
return value
}
},
},
y: {
beginAtZero: true,
@ -598,7 +588,7 @@
}
},
}
console.log(eveWeekElecChartData)
if (eveWeekElecChart == null) {
eveWeekElecChart = new Chart(eveWeekElecChartCanvas, {
data: eveWeekElecChartData,

View File

@ -577,9 +577,7 @@
let graMyDesDiaFile = uploader["graMyDesignDiagram"][0].dropzone.files.filter(x => x.accepted == true)[0];
/*let graMyAsBuiFile = uploader["graMyAsBuilt"][0].dropzone.files.filter(x => x.accepted == true)[0];*/
let fd = new FormData();
fd.append("code", $("#graPicNum").val());
fd.append("layer_id", curLayerId);
fd.append("name", $("#graPicName").val());
fd.append("oriOrgName", graMyDesDiaFile?.name ?? null);
/*fd.append("donOrgName", graMyAsBuiFile?.name ?? null);*/
fd.append("oriSavName", graMyDesDiaFile?.savename ?? null);

View File

@ -197,7 +197,7 @@
<ul style="${(i1 != null ? index == i1 : first) && index2 == i2 ? `display:block;` : ``}">`;
$.each(val2.device, function (index3, val3) {
strHtml += `<li>
strHtml += `<li data-tabname="hisListItem">
<a href="#" onClick="setValue('${val3.device_number}', '${val3.full_name}', null)" data-filter-tags="${val3.full_name.toLowerCase() } ${val3.device_serial_tag.toLowerCase()}" data-devnum="${val3.device_number}">
<span class="nav-link-text">
${val3.full_name} ${val3.device_serial_tag}
@ -231,6 +231,7 @@
});
$('#js_nested_list').html(strHtml);
$(`[data-tabname="hisListItem"]`).YTTab();
}
ytAjax = new YourTeam.Ajax(url, objSendData, success, null, "POST").send();
}
@ -409,7 +410,10 @@
},
{
"title": "數值",
"data": "value",
"data": "value",
"render": function (data) {
return data.roundDecimal(2);
}
},
{
"title": "紀錄時間",

View File

@ -10,42 +10,43 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
<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">
<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
@ -732,6 +733,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
</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>
@ -754,6 +756,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
var loadEle = pageLoading();
var errRecTable = null, opeRecTable = null;
var tolSubList = [];
var allDevices = [];
/**
* 頁面 Loading 建立
@ -798,7 +801,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
/*"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/Chart.min",
"lib/chart.js_4.1.2/chart.umd",
"lib/dropzone/dropzone-min",
"lib/jstree-master/jstree.min",
"lib/notifications/sweetalert2/sweetalert2.bundle",
@ -861,6 +864,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
checkDevState();
loadNoticeConSta();
allDevices = getAllDevice();
if (lastPage) {
let lastPageAct = {};
if (isJSON(sessionStorage.getItem("pageAct"))) {
@ -1018,10 +1022,10 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
onEvent("click", "button[id^=noticeChkBtn]", function () { /**button[id^=bajaAckBtn] */
let uuid = $(this).data("uuid");
let url = window.location.origin + "/obix/alarm/" + uuid + "/ack";
let url = window.location.origin + "/obix/alarm/"+uuid+"/ack";
let myBaja = new MyBaja();
myBaja.setMyUserAccount((data) => {
let sendData = '<obj is="obix:AckAlarmIn"><str name="' + data + '" val="obix" /></obj>';
let sendData = '<obj is="obix:AckAlarmIn"><str name="ackUser" val="obix" /></obj>';
$.post(url, sendData, (rel) => {
console.log(rel)
$(this).parents(".toast").YTNotice("hide");
@ -1039,12 +1043,11 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
if (typeof getAlarmSub != "undefined" && getAlarmSub) {
getAlarmSub(data);
}
alarmIconBlink();
})
getAlarmFromDB();
getAlarm();
})
}
@ -1199,9 +1202,11 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
controlFocusHotspot($(oriEle).data("dbId"));
}
// 3D 視角 ZOOM IN 聚焦
//if (devObj) {
// moveViewToDevice(devObj?.forge_dbid);
//}
/*
if (devObj) {
moveViewToDevice(devObj?.forge_dbid);
}
*/
// pop 視窗卡片可拖移功能初始化
$(tooltipEle).draggable({
cursor: "move",
@ -1562,7 +1567,7 @@ 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 active">
<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">
@ -1663,52 +1668,81 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
} else {
let datas = res.data;
let titleHtml = `異常通知`;
let notices = [];
$.each(datas, (idx, data) => {
if (noticeOptArr.findIndex(x => x.id == data.id) == -1) {
/*<button id="bajaAckBtn${data.id}" data-uuid="${data.uuid}" class="btn btn-sm btn-primary col-8 text-nowrap">已至現場確認問題</button> */
let content = `<div class="col-12">
<div class="row m-0">
<span class="m-0">異常編號:<span>${data.id}</span></span>
</div>
<div class="row m-0">
<span class="m-0">異常等級:<span>${data.priority}</span></span>
</div>
<div class="row m-0">
<span class="m-0">異常類別:<span>${data.alarmClass_txt}</span></span>
</div>
<div class="row m-0">
<span class="m-0">設備名稱:<span>${data.device_name}</span></span>
</div>
<div class="row m-0">
<span class="m-0">異常訊息:<span>${data.errMsg}</span></span>
</div>
<div class="d-flex m-0 gap-5 mt-2">
<button id="noticeChkBtn${data.id}" class="btn btn-sm btn-secondary ml-auto col-4">確認</button>
</div>
</div>`
let main = {
title: titleHtml,
content: content,
type: "warning",
id: data.id,
hasCloseBtn: true,
timeText: displayDate(data.timestamp),
}
noticeOptArr.push(main);
notices.push(main);
}
})
if (notices.length != 0) {
$("#noticeBlock").YTNotice("add_many", notices.oSort("id").reverse());
}
}
}, 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 取得告警資料
getAllDeviceAlarmByBaja(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"]);
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");

View File

@ -1,4 +1,4 @@

function addzero(num) {
return num < 10 ? '0' + num : num;
}
@ -93,7 +93,7 @@ function getAlarmByBaja(startDate_millisecond, endDate_millisecond, isRecover, i
var _index = 0;
var _recoverState = isRecover ? "!= null" : "= null";
var _ackState = isAck ? "= 'acked'" : "= 'unacked'";
console.log("local:|foxs:|alarm:|bql:select timestamp, ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where alarmClass = '" + alarmClass + "' and timestamp.millis > " + startDate_millisecond + " and timestamp.millis < " + endDate_millisecond + " and normalTime " + _recoverState + " and ackState " + _ackState + " order by timestamp asc")
require(['baja!'], function (baja) {
baja.Ord.make("local:|foxs:|alarm:|bql:select timestamp, ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where alarmClass = '" + alarmClass + "' and timestamp.millis > " + startDate_millisecond + " and timestamp.millis < " + endDate_millisecond + " and normalTime " + _recoverState + " and ackState " + _ackState + " order by timestamp asc").get()
.then(function (table) {
@ -239,7 +239,7 @@ function getOneSystemAlarmStateByBaja(systemPath, callback) {
var _result = "";
var _ss = "";
var _index = 0;
console.log("local:|foxs:|alarm:|bql:select alarmData, alarmData.sourceName, sourceState, uuid where alarmData.sourceName like '%" + systemPath + "%' order by timestamp desc")
require(['baja!'], function (baja) {
baja.Ord.make("local:|foxs:|alarm:|bql:select alarmData, alarmData.sourceName, sourceState, uuid where alarmData.sourceName like '%" + systemPath + "%' order by timestamp desc").get()
.then(function (table) {
@ -564,34 +564,45 @@ function getSystemAlarmByBaja(callback) {
}
function getAllDeviceAlarmByBaja(startDate_millisecond, endDate_millisecond, isRecover, isAck, callback) {
let _sourceTmp;
var _result = "";
var _ss = "";
var _bfName = "";
var _sourceName = "";
var _result = { count: 0, data: [] };
var _index = 0;
var _recoverState = isRecover ? "!= null" : "= null";
var _ackState = isAck ? "= 'acked'" : "= 'unacked'";
require(['baja!'], function (baja) {
console.log("local:|foxs:|alarm:|bql:select timestamp, ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where timestamp.millis >= " + startDate_millisecond + " and timestamp.millis <= " + endDate_millisecond + " and normalTime " + _recoverState + " and ackState " + _ackState + " order by timestamp desc");
baja.Ord.make("local:|foxs:|alarm:|bql:select timestamp, ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where timestamp.millis >= " + startDate_millisecond + " and timestamp.millis <= " + endDate_millisecond + " and normalTime " + _recoverState + " and ackState " + _ackState + " order by timestamp desc").get()
let startUrl = "";
if (startDate_millisecond) {
startUrl = "timestamp.millis >= " + startDate_millisecond + " and ";
}
console.log("local:|foxs:|alarm:|bql:select timestamp, priority ,ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where " + startUrl + "timestamp.millis <= " + endDate_millisecond + " and normalTime " + _recoverState + " and ackState " + _ackState + " order by timestamp desc");
baja.Ord.make("local:|foxs:|alarm:|bql:select timestamp, priority ,ackState, alarmClass, alarmClassDisplayName, alarmValue, alarmData, alarmData.sourceName, uuid, alarmData.msgText, alarmData.numericValue, alarmData.presentValue, alarmData.status, alarmData.toState, normalTime from openAlarms where " + startUrl + "timestamp.millis <= " + endDate_millisecond + " and normalTime " + _recoverState + " and ackState " + _ackState + " order by timestamp desc").get()
.then(function (table) {
return table.cursor({
each: function (record) {
_sourceTmp = (record.get('alarmData').get('sourceName')).toString().split('_');
_bfName = _sourceTmp[1] + "-" + _sourceTmp[4];
_sourceName = _sourceTmp[7] + "-" + _sourceTmp[8];
if (_index == 0)
_ss += '{"buildingFloorName_zh":"' + _bfName + '", "uuid":"' + record.get('uuid') + '", "timestamp":"' + record.get('timestamp') + '", "alarmClass":"' + record.get('alarmClass') + '", "sourceName_zh":"' + _sourceName + '", "msgText":"' + record.get('alarmData').get('msgText') + '", "ackState":"' + record.get('ackState') + '", "normalTime":"' + record.get('normalTime') + '"}';
else
_ss += ',{"buildingFloorName_zh":"' + _bfName + '", "uuid":"' + record.get('uuid') + '", "timestamp":"' + record.get('timestamp') + '", "alarmClass":"' + record.get('alarmClass') + '", "sourceName_zh":"' + _sourceName + '", "msgText":"' + record.get('alarmData').get('msgText') + '", "ackState":"' + record.get('ackState') + '", "normalTime":"' + record.get('normalTime') + '"}';
let main = {};
console.log(record.get('alarmData').get('sourceName'))
_sourcePoint = (record.get('alarmData').get('sourceName')).toString().split(':')[1];
console.log(_sourcePoint)
_sourceTmp = _sourcePoint.split("_");
let _bfName = _sourceTmp[1] + "-" + _sourceTmp[4];
let _sourceName = _sourceTmp[7] + "-" + _sourceTmp[8];
main.buildingFloorName_zh = _bfName;
main.sourceName_zh = _sourceName;
main.uuid = record.get('uuid').$val;
main.timestamp = record.get('timestamp');
main.alarmClass = record.get('alarmClass');
main.point = _sourcePoint;
main.devicePath = _sourceTmp.slice(0, 8).join("_");;
main.msgText = record.get('alarmData').get('msgText');
main.normalTime = record.get('normalTime');
main.priority = record.get('priority');
_result.data.push(main);
_index++;
},
after: function () {
_result += '{' + '"count": ' + _index + ', "data":[';
_result += _ss + ']';
_result += '}';
_result.count = _index;
if (typeof callback === 'function') {
callback(_result);
}

View File

@ -243,6 +243,7 @@ function getElectricMeterHourDataByBaja(devicePath, company, startDateTime, endD
return table.cursor({
each: function (record) {
let main = {};
main.timestamp = record.get('timestamp');
main.endTimestamp = record.get('endTimestamp');
main.min = record.get('min');

View File

@ -188,6 +188,10 @@ function creI(cls = [], data = {}, attr = {}, id = null, name = null, text = nul
function creA(text = null, attr = {}, cls = [], id = null, data = {}, name = null) {
return creEle("a", text, id, name, cls, data, attr);
}
function creSpan(text = null, cls = [], id = null, attr = {}, data = {}, name = null) {
return creEle("span", text, id, name, cls, data, attr);
}
/**
* 根據該棟建築底下的'所有'電梯執行緒物件
* */