topology.view.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php declare(strict_types = 0);
  2. /*
  3. ** L2 Topology page — display-only map (all settings live in the config center).
  4. ** @var CView $this
  5. ** @var array $data
  6. */
  7. use Modules\WecomCenter\Lib\I18n;
  8. $this->addCssFile('modules/WecomCenter/assets/l2topology/style.css');
  9. $base = '/modules/WecomCenter/assets/l2topology/';
  10. $snapJson = (string) ($data['snap_json'] ?? 'null');
  11. $cfgJson = (string) ($data['cfg_json'] ?? '{}');
  12. $snapSafe = str_replace('</', '<\/', $snapJson);
  13. $cfgSafe = str_replace('</', '<\/', $cfgJson);
  14. $i18nKeys = [
  15. 'l2.title','l2.search_ph','l2.show_term','l2.only_off','l2.auto_refresh','l2.min',
  16. 'l2.refresh_now','l2.fit','l2.alarms','l2.offline','l2.time_live','l2.time_btn',
  17. 'l2.time_label','l2.dark','l2.no_data','l2.offline_empty','l2.alarm_empty','l2.updated',
  18. 'l2.pause','l2.resume','l2.legend_speed','l2.legend_tier','l2.legend_lat','l2.core','l2.dist','l2.access',
  19. 'l2.lat_norm','l2.term_on','l2.term_off','l2.zoom_in','l2.zoom_out','l2.snapshot','l2.showing','l2.live_tag',
  20. 'l2.back_overview','l2.unit_sw','l2.tile_hint','l2.not_in_topo','l2.click_hint',
  21. 'l2.net_surve','l2.net_office','l2.net_other'
  22. ];
  23. $i18n = [];
  24. foreach ($i18nKeys as $k) { $i18n[$k] = I18n::t($k); }
  25. $i18nJson = str_replace('</', '<\/', json_encode($i18n, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
  26. $hist = $data['history'] ?? [];
  27. $isLive = !empty($data['is_live']);
  28. $usedTs = (int) ($data['used_ts'] ?? 0);
  29. $tsOpts = '<option value=""'.($isLive ? ' selected' : '').'>'.htmlspecialchars(I18n::t('l2.time_live')).'</option>';
  30. foreach ($hist as $h) {
  31. $sel = (!$isLive && $usedTs === (int) $h['ts']) ? ' selected' : '';
  32. $tsOpts .= '<option value="'.(int) $h['ts'].'"'.$sel.'>'.date('Y-m-d H:i:s', (int) $h['ts']).'</option>';
  33. }
  34. $refreshSec = (int) ($data['cfg_refresh'] ?? 300);
  35. if (!function_exists('l2e')) { function l2e($v) { return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8'); } }
  36. ?>
  37. <div class="l2-wrap<?php echo !empty($data['cfg_dark']) ? ' l2-dark' : ''; ?>" id="l2-wrap">
  38. <div class="l2-toolbar">
  39. <span class="tb-title"><?php echo l2e(I18n::t('l2.title')); ?></span>
  40. <button class="l2-btn" id="l2-back" style="display:none"><?php echo l2e(I18n::t('l2.back_overview')); ?></button>
  41. <div class="l2-search-wrap">
  42. <input id="l2-search" type="text" placeholder="<?php echo l2e(I18n::t('l2.search_ph')); ?>" autocomplete="off"/>
  43. <div id="l2-sug"></div>
  44. </div>
  45. <label class="l2-chk"><input type="checkbox" id="l2-showterm"/> <?php echo l2e(I18n::t('l2.show_term')); ?></label>
  46. <label class="l2-chk"><input type="checkbox" id="l2-onlyoff"/> <?php echo l2e(I18n::t('l2.only_off')); ?></label>
  47. <label class="l2-chk"><input type="checkbox" id="l2-dark"/> <?php echo l2e(I18n::t('l2.dark')); ?></label>
  48. <label class="l2-ts-label"><?php echo l2e(I18n::t('l2.time_label')); ?>
  49. <select id="l2-ts" class="l2-btn"><?php echo $tsOpts; ?></select>
  50. </label>
  51. <span class="l2-spacer"></span>
  52. <span id="l2-countdown" class="l2-muted"></span>
  53. <button class="l2-btn" id="l2-pause" title="pause">❚❚</button>
  54. <button class="l2-btn primary" id="l2-refresh-btn"><?php echo l2e(I18n::t('l2.refresh_now')); ?></button>
  55. <button class="l2-btn" id="l2-zin">+</button>
  56. <button class="l2-btn" id="l2-zout">-</button>
  57. <button class="l2-btn" id="l2-fit"><?php echo l2e(I18n::t('l2.fit')); ?></button>
  58. </div>
  59. <div class="l2-main">
  60. <div class="l2-canvas">
  61. <div id="l2-cy"></div>
  62. <div class="l2-stats" id="l2-stats"></div>
  63. <div class="l2-net-tabs" id="l2-net-tabs" style="display:none"></div>
  64. <div class="l2-legend" id="l2-legend"></div>
  65. </div>
  66. <div class="l2-side">
  67. <div class="side-tabs">
  68. <div class="side-tab active" data-sec="alarms"><?php echo l2e(I18n::t('l2.alarms')); ?> <span class="badge" id="l2-alarm-count">0</span></div>
  69. <div class="side-tab" data-sec="offline"><?php echo l2e(I18n::t('l2.offline')); ?> <span class="badge" id="l2-offline-count" style="background:#78909c">0</span></div>
  70. </div>
  71. <div class="side-body">
  72. <div class="panel-sec active" id="sec-alarms"><div id="l2-alarm-list"></div></div>
  73. <div class="panel-sec" id="sec-offline"><div id="l2-offline-list"></div></div>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. <div class="l2-tip" id="l2-tip"></div>
  79. <script>
  80. window.L2SNAP = <?php echo $snapSafe; ?>;
  81. window.L2_CFG = <?php echo $cfgSafe; ?>;
  82. window.L2_I18N = <?php echo $i18nJson; ?>;
  83. window.L2_META = {
  84. base: '<?php echo $base; ?>',
  85. snapshotUrl: '<?php echo $base; ?>snapshot.json',
  86. isLive: <?php echo $isLive ? 'true' : 'false'; ?>,
  87. usedTs: <?php echo $usedTs; ?>,
  88. refreshSeconds: <?php echo $refreshSec; ?>,
  89. zabbixHostUrl: '/zabbix.php?action=problem.view&hostids%5B%5D=__HOSTID__'
  90. };
  91. </script>
  92. <script src="<?php echo $base; ?>cytoscape.min.js"></script>
  93. <script src="<?php echo $base; ?>app.js"></script>
  94. <script>
  95. (function(){
  96. var tabs = document.querySelectorAll('.side-tab');
  97. tabs.forEach(function(t){
  98. t.addEventListener('click', function(){
  99. tabs.forEach(function(x){x.classList.remove('active');});
  100. t.classList.add('active');
  101. document.querySelectorAll('.panel-sec').forEach(function(s){s.classList.remove('active');});
  102. var sec = document.getElementById('sec-' + t.getAttribute('data-sec'));
  103. if (sec) sec.classList.add('active');
  104. });
  105. });
  106. })();
  107. </script>