treeListFrame.jsp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
  4. <%@ page session="false" %>
  5. <!doctype html>
  6. <html lang="ko" style="min-width:300px !important;overflow:hidden">
  7. <head>
  8. <%@ include file="/WEB-INF/jsp/common.jsp" %>
  9. <meta name="_csrf" content="${_csrf.token}"/>
  10. <meta name="_csrf_header" content="${_csrf.headerName}"/>
  11. <link rel="stylesheet" type="text/css" href="${contextRoot }/css/common.css"/>
  12. <link rel="stylesheet" type="text/css" href="${contextRoot }/css/main.css"/>
  13. <link rel="stylesheet" href="${contextRoot }/css/themes/default/style.css"/>
  14. </head>
  15. <body class="sang" style="min-width:305px !important;overflow:hidden">
  16. <div class="leftMenu">
  17. <ul class="tabs">
  18. <li><a href="javascript:goIntMenu()" class="tab" id="tab1"><img src="images/tab01_on.png" alt="교차로메뉴"/></a></li>
  19. <!-- <li><a href="javascript:goGroupMenu()" class="tab" id="tab2"><img src="images/tab02_off.png" alt="신호그룹메뉴" /></a></li> -->
  20. </ul>
  21. <div id="onOffTree"></div>
  22. <div class="searchBox">
  23. <input type="text" id="searchText" placeholder="검색어를 입력해주세요" autocomplete="false" onkeyup="searchTreeData(event)">
  24. <div class="search-button" onclick="searchTreeData()">검색</div>
  25. </div>
  26. <div id="intTree"></div>
  27. <div id="groupTree"></div>
  28. <div class="treeLoading"><img src="/css/themes/classic/throbber.gif"/></div>
  29. </div>
  30. <script type="text/javascript" src="${contextRoot }/js/common/moment.js"></script>
  31. <script src="${contextRoot }/js/common/common-all.js" type="text/javascript"></script>
  32. <script src="${contextRoot }/js/signalInfo.js" type="text/javascript"></script>
  33. <script src="${contextRoot }/js/common/jstree.min.js" type="text/javascript"></script>
  34. <script type="text/javascript">
  35. var treeJson = null;
  36. var groupTreeJson = null;
  37. var treeCtrl;
  38. var onlineCenterStatusCheckId;
  39. var offlineCenterStatusCheckId;
  40. var onlineIntStatusCheckId;
  41. var offlineIntStatusCheckId;
  42. var _RegionCdArr = [];
  43. var _GroupNoArr = [];
  44. var intGroupLineArr = [];
  45. var intGroupCircleArr = [];
  46. var _groupTreeListCallBackData;
  47. var onlineCenterStatusData;
  48. var offlineCenterStatusData;
  49. var onlineIntStatusData;
  50. var offlineIntStatusData;
  51. let _regionMap = new Map();
  52. var _searchText = "";
  53. function setAddrMap(data) {
  54. _regionMap.clear();
  55. for (let ii = 0; ii < data.length; ii++) {
  56. if (data[ii].addr1 == null || data[ii].addr1 == '-') {
  57. continue;
  58. }
  59. _regionMap.set(data[ii].addr1, data[ii].regionid);
  60. }
  61. }
  62. function getAddrSi() {
  63. return Array.from(_regionMap.keys());
  64. }
  65. function getEngAddr(addr){
  66. let region_id = _regionMap.get(addr);
  67. if (region_id === null || region_id === undefined) {
  68. return "U99"
  69. }
  70. return region_id;
  71. }
  72. setTreeList();
  73. getIntTreeList();
  74. var timeout = setInterval(controllerOnOffFuc, 1000);
  75. function searchTreeData(el) {
  76. if (el && el.code !== "Enter") {
  77. return;
  78. }
  79. const $searchText = $('#searchText');
  80. _searchText = $searchText.val();
  81. const oldTree = $('#intTree').jstree(true);
  82. if (oldTree) {
  83. oldTree.destroy();
  84. }
  85. setTreeList();
  86. getIntTreeList();
  87. $('#intTree').jstree("refresh");
  88. }
  89. /*
  90. * 신호 제어기 상태 정보
  91. * 1 : 정상, 2: 교차로 시각 오류 0: 마지막통신 시간 3초이상 지연시
  92. */
  93. function controllerOnOffFuc() {
  94. var addrArr = getAddrSi();
  95. for(var ll = 0; ll < addrArr.length; ll++) {
  96. var ctnlCount =0;
  97. var errorCount=0;
  98. var now = new Date();
  99. var preDate = moment(now.getTime()).add("-30", "s").format("YYYY-MM-DD HH:mm:ss");
  100. var nxtDate = moment(now.getTime()).add("30", "s").format("YYYY-MM-DD HH:mm:ss");
  101. window.parent._signalInfoArr.forEach(function (el, idx) {
  102. if (el.addr1 == addrArr[ll]) {
  103. ctnlCount++;
  104. if (!el.commStatus) {
  105. el.status = 0; // 데이터 없음(현재 통신하고 있지 않음)
  106. errorCount++;
  107. }
  108. else {
  109. el.status = 1;
  110. // if (now.getTime() - el.commDate.getTime() > 3000 ) {
  111. // console.log(el);
  112. // }
  113. // if ((now.getSeconds() - el.commDate.getSeconds()) <= 3) {
  114. // let cmmnDate = null;
  115. // if (el.date) {
  116. // cmmnDate = new Date(el.date);
  117. // }
  118. // if (cmmnDate && (el.commDate.getTime() - cmmnDate.getTime()) <= 3000) {
  119. // // 마지막 통신시각이 현재시각보다 3초 이내이면 통신 정상
  120. // el.status = 1;
  121. // // 로컬시각이 현재시각과 차이날 경우 아이콘의 색을 노랑색으로 변경하도록 한다.
  122. // var localDate = moment(el.date).format('YYYY-MM-DD HH:mm:ss');
  123. // if (localDate < preDate || localDate > nxtDate) { //시간이 null거나 3초전이거나
  124. // el.status = 2; // 교차로 시각 오류 (노랑색 아이콘으로 표출)
  125. // }
  126. // }
  127. // else {
  128. // // 마지막 통신시각이 현재시각보다 3초 이후이면 통신 Off Line 으로 판단
  129. // el.status = 0;
  130. // errorCount++;
  131. // } //
  132. }
  133. var commOnOffImg = 'background-image:url("images/intStatus_' + el.status + '.png");background-position:center center';
  134. /*if (el.status == 1) {
  135. commOnOffImg = 'background-image:url("images/intStatusOn.png");background-position:center center';
  136. } else if(el.status == 2) {
  137. //errorCount++;
  138. commOnOffImg = 'background-image:url("images/intStatusOff.png");background-position:center center';
  139. }else{
  140. //errorCount++;
  141. commOnOffImg = 'background-image:url("images/intStatusNull.png");background-position:center center';
  142. }*/
  143. $('#' + el.nodeId + ' .jstree-anchor .jstree-icon').attr('style', commOnOffImg);
  144. }
  145. });
  146. $('#intErrCnt_'+getEngAddr(addrArr[ll])).text(errorCount);
  147. $('#intTotal_'+getEngAddr(addrArr[ll])).text(ctnlCount);
  148. }
  149. }
  150. function setTreeList() {
  151. /**
  152. ** ****************************************************
  153. ** 레이어 리스트 Tree 생성
  154. ** ****************************************************
  155. */
  156. treeCtrl = treeCtrl || (function () {
  157. var Node = function (nodeName, data, id, icon) {
  158. return {
  159. id: id,
  160. icon: icon,
  161. text: nodeName,
  162. state: {'opened': false, 'selected': false},
  163. data: data, // @type: ol.Layer
  164. children: []
  165. };
  166. };
  167. var _root = new Node('ROOT', 'item');
  168. var findChild = function (parent, nodeName) {
  169. for (var i = 0; i < parent.children.length; i++) {
  170. var child = parent.children[i];
  171. if (child.text == nodeName) {
  172. return child;
  173. }
  174. }
  175. return null;
  176. };
  177. // find parent which save item
  178. var getParent = function (parent, group, data, id, icon, opt_make) {
  179. opt_make = (typeof opt_make === 'undefined') ? true : false;
  180. for (var i = 0; i < group.length; i++) {
  181. var child = findChild(parent, group[i]);
  182. // 없으면 Node 생성
  183. if (!child) {
  184. if (!opt_make) return null;
  185. child = new Node(group[i], data);
  186. parent.children.push(child);
  187. }
  188. parent = child;
  189. }
  190. return parent;
  191. }
  192. // group에 layer 아이템 저장
  193. var _set = function (key, item) {
  194. key.forEach(function (el) {
  195. var group = el.split('-');
  196. var parent = getParent(_root, group, item.data, item.id, item.icon);
  197. var child = new Node(item.name, item.data, item.id, item.icon);
  198. parent.children.push(child);
  199. return child;
  200. });
  201. };
  202. // item인 node들만 반환 (=layer)
  203. var _get = function (key) {
  204. var group = key.split('-');
  205. var parent = getParent(_root, group);
  206. return parent.children.filter(function (node) {
  207. return node.type == 'item'
  208. });
  209. };
  210. var _clear = function () {
  211. _root.children = [];
  212. };
  213. var _setState = function (key, state) {
  214. var group = key.split('-');
  215. var node = getParent(_root, group, false);
  216. if (!node) return false;
  217. node['state'] = state;
  218. return true;
  219. };
  220. var _toTreeJson = function () {
  221. return _root.children;
  222. };
  223. return {
  224. 'root': _root,
  225. 'set': _set,
  226. 'get': _get,
  227. 'setState': _setState,
  228. 'toTreeJson': _toTreeJson,
  229. 'clear': _clear,
  230. };
  231. })(treeCtrl);
  232. }
  233. function getIntTreeList() {
  234. $('.treeLoading').show();
  235. var url = 'getIntTreeList.do';
  236. requestService(url, '', getIntTreeListCallback);
  237. }
  238. function nameSort(a, b) {
  239. const aA = a.addr1;
  240. const bA = b.addr1;
  241. const x = a.name.toLowerCase();
  242. const y = b.name.toLowerCase();
  243. return aA > bA ? 1 : aA === bA ? (x > y ? 1 : x === y ? 0 : -1) : -1;
  244. //return x < y ? -1 : x > y ? 1 : 0;
  245. }
  246. function getIntTreeListCallback(data) {
  247. treeCtrl.clear();
  248. var nodeId;
  249. var name;
  250. var lat;
  251. var lng;
  252. var addr1;
  253. var addr2;
  254. var addr3;
  255. var ipAddr;
  256. var nameCntOn;
  257. data.sort(nameSort);
  258. //TODO: 20230221
  259. setAddrMap(data);
  260. window.parent._signalInfoArr = [];
  261. for (var i = 0; i < data.length; i++) {
  262. if (data[i].addr1 == null || data[i].addr1 == '-') {
  263. continue;
  264. }
  265. nodeId = data[i].nodeid;
  266. name = data[i].name;
  267. lat = data[i].lat;
  268. lng = data[i].lng;
  269. addr1 = data[i].addr1;
  270. addr2 = data[i].addr2;
  271. addr3 = data[i].addr3;
  272. ipAddr = data[i].ipaddr;
  273. //console.log('nodeid :'+nodeId+' , name : '+name+', lat : '+lat+', lng : '+lng+', addr1 : '+addr1);
  274. var signal = new SignalInfo(nodeId, name, lat, lng, addr1, addr2, addr3);
  275. //부모 변수에 저장
  276. //iframe이라서 직접 접근이 안됨
  277. window.parent._signalInfoArr.push(signal);
  278. var engAddr = getEngAddr(addr1);
  279. nameCntOn = '&nbsp;<strong class="centerNm_' + engAddr + '">' + addr1 + '</strong>&nbsp;( 전체 : <span class="intTotal" id="intTotal_'+engAddr+'" style="color:#0000FF"></span> / 이상 : '+
  280. '<span class="intErrCnt" id="intErrCnt_'+engAddr+'" style="color:#FF0000"></span> )';
  281. //guTitleOff = nameCntOn + '-' + addr2 + '&nbsp;';
  282. var intNm = nodeId + '_' + name;
  283. var intStatus = getStatus(signal.status);
  284. function getStatus(stts){
  285. if(stts == 1){
  286. return "On"; //정상
  287. }else if( stts == 2){
  288. return "Off"; //교차로시각이상
  289. }else{
  290. return "Null"; // 통신시간 3초이상
  291. }
  292. }
  293. let searchX = null;
  294. let searchY = null;
  295. let searchText = null;
  296. if (_searchText) {
  297. if (_searchText.indexOf(',') > -1) {
  298. const coordArr = _searchText.split(',');
  299. if (coordArr.length === 2) {
  300. searchX = coordArr[0].trim();
  301. searchY = coordArr[1].trim();
  302. if (lat.toString() !== searchX.toString() || lng.toString() !== searchY.toString()) {
  303. continue;
  304. }
  305. }
  306. }
  307. else {
  308. searchText = _searchText;
  309. if (nodeId.indexOf(searchText) === -1 &&
  310. name.indexOf(searchText) === -1
  311. ) {
  312. continue;
  313. }
  314. }
  315. }
  316. treeCtrl.set([nameCntOn], {
  317. name: name+" ("+nodeId+")",
  318. id: nodeId,
  319. icon: "images/comm" + intStatus + ".png",
  320. data: {
  321. 'line': 'offline',
  322. 'intNo': nodeId, 'intNm': name,
  323. 'lat': lat, 'lng': lng,
  324. }
  325. });
  326. }
  327. treeJson = treeCtrl.toTreeJson();
  328. $('#intTree').jstree({
  329. 'core': {
  330. 'data': treeJson,
  331. "themes": {"stripes": true},
  332. },
  333. "plugins": ["wholerow"]
  334. });
  335. // jsTree 클릭 이벤트 : 레이어 setVisible
  336. $('#intTree').bind('select_node.jstree', function (event, data) {
  337. var parentNd = data.node.parent;
  338. var children = data.node.children;
  339. //parent._RegionCd = data.node.data.regionCd;
  340. if (parentNd == '#') //시도 선택
  341. {
  342. //console.log("시도 선택했음");
  343. } else if (parentNd != '#' && children.length > 0) //구 선택
  344. {
  345. //console.log("구 선택했음");
  346. } else {
  347. var intNm = data.node.data.intNm;
  348. var lng = data.node.data.lng;
  349. var lat = data.node.data.lat;
  350. if(parent._Level > 3) parent.map.setLevel(1);
  351. parent.map.panTo(new parent.kakao.maps.LatLng(lat, lng));
  352. setTimeout(
  353. function() {
  354. parent.getSignalInfo();
  355. parent.customOverlayFnc(intNm,lng,lat);
  356. }, 100 * 2);
  357. }
  358. });
  359. $('.treeLoading').hide();
  360. }
  361. //유선 센터상테 체크..
  362. function onlineCenterStatusCheck() {
  363. if (onlineCenterStatusCheckId != null) clearTimeout(onlineCenterStatusCheckId);
  364. onlineCenterStatusCheckId = setTimeout('onlineCenterStatusCheck()', 5 * 1000);
  365. var url = 'getOnlineCenterStatus.do';
  366. requestService(url, '', onlineCenterStatusCheckCallback);
  367. }
  368. function onlineCenterStatusCheckCallback(data) {
  369. onlineCenterStatusData = data;
  370. drawCenterStatus(0, data);
  371. }
  372. //무선 센터상테 체크..
  373. function offlineCenterStatusCheck() {
  374. if (offlineCenterStatusCheckId != null) clearTimeout(offlineCenterStatusCheckId);
  375. offlineCenterStatusCheckId = setTimeout('offlineCenterStatusCheck()', 5 * 1000);
  376. var url = 'getOfflineCenterStatus.do';
  377. requestService(url, '', offlineCenterStatusCheckCallback);
  378. }
  379. function offlineCenterStatusCheckCallback(data) {
  380. offlineCenterStatusData = data;
  381. drawCenterStatus(1, data);
  382. }
  383. function drawCenterStatus(network, data) {
  384. var regionCd;
  385. var totCnt;
  386. var errCnt;
  387. var commState;
  388. var commImg = '';
  389. for (var ii = 0; ii < data.length; ii++) {
  390. regionCd = data[ii].REGION_CD;
  391. totCnt = data[ii].TOT;
  392. errCnt = data[ii].ERR_CNT;
  393. commState = data[ii].COMM_STATE;
  394. if (commState == 1) {
  395. commImg = 'images/commOff.png';
  396. $('.intErrCnt_' + network + '_' + regionCd).text(totCnt);
  397. } else {
  398. commImg = 'images/commOn.png';
  399. $('.intErrCnt_' + network + '_' + regionCd).text(errCnt);
  400. }
  401. if (network == 0) $('.regionComm_' + network + '_' + regionCd).attr('src', commImg);
  402. $('.intTotal_' + network + '_' + regionCd).text(totCnt);
  403. }
  404. }
  405. //유선 제어기 상태 체크..
  406. function onlineIntStatusCheck() {
  407. if (_RegionCdArr.length > 0) {
  408. if (onlineIntStatusCheckId != null) clearTimeout(onlineIntStatusCheckId);
  409. onlineIntStatusCheckId = setTimeout('onlineIntStatusCheck()', 5 * 1000);
  410. var url = 'getOnlineIntStatus.do';
  411. var param = 'regionCd=' + _RegionCdArr;
  412. requestService(url, param, onlineIntStatusCheckCallback);
  413. }
  414. }
  415. function onlineIntStatusCheckCallback(data) {
  416. onlineIntStatusData = data;
  417. drawIntStatus(0, data);
  418. }
  419. //무선 제어기 상태 체크..
  420. function offlineIntStatusCheck() {
  421. if (_RegionCdArr.length > 0) {
  422. if (offlineIntStatusCheckId != null) clearTimeout(offlineIntStatusCheckId);
  423. offlineIntStatusCheckId = setTimeout('offlineIntStatusCheck()', 5 * 1000);
  424. var url = 'getOfflineIntStatus.do';
  425. var param = 'regionCd=' + _RegionCdArr;
  426. requestService(url, param, offlineIntStatusCheckCallback);
  427. }
  428. }
  429. function offlineIntStatusCheckCallback(data) {
  430. offlineIntStatusData = data;
  431. drawIntStatus(1, data);
  432. }
  433. function drawIntStatus(network, data) {
  434. var commState;
  435. if (network == 0) {
  436. for (var i = 0; i < onlineCenterStatusData.length; i++) {
  437. if (onlineCenterStatusData[i].REGION_CD == data[0].REGION_CD) {
  438. commState = onlineCenterStatusData[i].COMM_STATE;
  439. break;
  440. }
  441. }
  442. } else {
  443. commState = 0;
  444. }
  445. var regionCd;
  446. var siguguCd;
  447. var intNoArr;
  448. var commOnOffFlagArr;
  449. var commOnOffImg;
  450. for (var ii = 0; ii < data.length; ii++) {
  451. regionCd = data[ii].REGION_CD;
  452. sigunguCd = data[ii].SIGUNGU_CD;
  453. intNoArr = data[ii].INT_NO.split('|');
  454. commOnOffFlagArr = data[ii].COMM_ON_OFF_FLAG.split('|');
  455. $('.guIntTotal_' + network + '_' + sigunguCd).text(intNoArr.length);
  456. //sigunguCd = 41190 부천시 , 41430 의왕시, 41410 군포시
  457. //commState = 1;
  458. //시군구 코드가 없으면 상태정보이미지가 없데이트가 안된다...
  459. if (commState == 0) {
  460. var guIntErrCnt = 0;
  461. for (var jj = 0; jj < intNoArr.length; jj++) {
  462. if (commOnOffFlagArr[jj] == 1) {
  463. guIntErrCnt++;
  464. commOnOffImg = 'background-image:url("images/intStatusOff.png");background-position:center center';
  465. } else {
  466. commOnOffImg = 'background-image:url("images/intStatusOn.png");background-position:center center';
  467. }
  468. $('#' + regionCd + '_' + network + '_' + intNoArr[jj] + ' .jstree-anchor .jstree-icon').attr('style', commOnOffImg);
  469. }
  470. $('.guIntErrCnt_' + network + '_' + sigunguCd).text(guIntErrCnt);
  471. } else {
  472. for (var j = 0; j < intNoArr.length; j++) {
  473. commOnOffImg = 'background-image:url("images/intStatusOff.png");background-position:center center';
  474. $('#' + regionCd + '_' + network + '_' + intNoArr[j] + ' .jstree-anchor .jstree-icon').attr('style', commOnOffImg);
  475. }
  476. $('.guIntErrCnt_' + network + '_' + sigunguCd).text(intNoArr.length);
  477. }
  478. }
  479. }
  480. </script>
  481. </body>
  482. </html>