nodeList.blade.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. @extends('user.layouts')
  2. @section('css')
  3. <script src="//at.alicdn.com/t/font_682457_e6aq10jsbq0yhkt9.js" type="text/javascript"></script>
  4. <link href="/assets/global/fonts/font-awesome/font-awesome.min.css" type="text/css" rel="stylesheet">
  5. <link href="/assets/global/vendor/webui-popover/webui-popover.min.css" type="text/css" rel="stylesheet">
  6. <link href="/assets/global/vendor/jvectormap/jquery-jvectormap.min.css" type="text/css" rel="stylesheet">
  7. @endsection
  8. @section('content')
  9. <!-- BEGIN CONTENT BODY -->
  10. <div class="page-content container-fluid">
  11. <div class="row">
  12. <div class="col-md-9">
  13. <div class="card card-inverse card-shadow bg-white map">
  14. <div class="card-block h-450">
  15. <div class="h-p100" id="world-map"></div>
  16. </div>
  17. </div>
  18. </div>
  19. <div class="col-md-3">
  20. <div class="row map">
  21. <div class="col-md-12">
  22. <div class="card card-block p-20 bg-indigo-500">
  23. <div class="counter counter-lg counter-inverse">
  24. <div class="counter-label text-uppercase font-size-16">账号等级</div>
  25. <div class="counter-number-group">
  26. <span class="counter-icon"><i class="icon wb-user-circle" aria-hidden="true"></i></span>
  27. <span class="counter-number ml-10">{{Auth::getUser()->level}}</span>
  28. </div>
  29. <div class="counter-label text-uppercase font-size-16">{{Auth::getUser()->level_name}}</div>
  30. </div>
  31. </div>
  32. </div>
  33. @if(Auth::getUser()->group_id)
  34. <div class="col-md-12">
  35. <div class="card card-block p-20 bg-indigo-500">
  36. <div class="counter counter-lg counter-inverse">
  37. <div class="counter-label text-uppercase font-size-16">所属分组</div>
  38. <div class="counter-number-group">
  39. <span class="counter-icon"><i class="icon wb-globe" aria-hidden="true"></i></span>
  40. <span class="counter-number ml-10">{{Auth::getUser()->group->name}}</span>
  41. </div>
  42. </div>
  43. </div>
  44. </div>
  45. @endif
  46. <div class="col-md-12">
  47. <div class="card card-block p-20 bg-indigo-500">
  48. <div class="counter counter-lg counter-inverse">
  49. <div class="counter-label text-uppercase font-size-16">限速</div>
  50. <div class="counter-number-group">
  51. <span class="counter-icon"><i class="icon wb-signal" aria-hidden="true"></i></span>
  52. <span class="counter-number ml-10">{{Auth::getUser()->speed_limit ?? '无限制'}}</span>
  53. </div>
  54. <div class="counter-label font-size-16">Mbps</div>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. @foreach($nodeList as $node)
  61. <div class="col-xxl-3 col-xl-4 col-sm-6">
  62. <div class="card card-inverse card-shadow bg-white node">
  63. <div class="card-block p-30 row">
  64. <div class="col-4">
  65. <svg class="w-p100 text-center" aria-hidden="true">
  66. <use xlink:href="@if($node->country_code)#icon-{{$node->country_code}}@else #icon-un @endif"></use>
  67. </svg>
  68. </div>
  69. <div class="col-8 text-break text-right">
  70. <p class="font-size-20 blue-600">
  71. <span class="badge badge-pill up m-0 badge-default">{{$node->level_table->name}}</span>
  72. @if($node->offline)
  73. <i class="red-600 icon wb-warning" data-content="线路波动/维护中" data-trigger="hover" data-toggle="popover" data-placement="top"></i>
  74. @endif
  75. @if($node->traffic_rate != 1)
  76. <i class="green-600 icon wb-info-circle" data-content="{{$node->traffic_rate}} 倍流量消耗" data-trigger="hover" data-toggle="popover"
  77. data-placement="top"></i>
  78. @endif
  79. {{$node->name}}
  80. </p>
  81. <blockquote>
  82. @foreach($node->labels as $label)
  83. <span class="badge badge-pill font-size-10 up m-0 badge-info">{{$label->label->name}}</span>
  84. @endforeach
  85. <br>
  86. {{$node->description}}
  87. </blockquote>
  88. <p class="font-size-14">
  89. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{$node->id}}','code')">
  90. <i id="code{{$node->id}}" class="icon fa-code"></i>
  91. </button>
  92. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{$node->id}}','qrcode')">
  93. <i id="qrcode{{$node->id}}" class="icon fa-qrcode"></i>
  94. </button>
  95. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{$node->id}}','text')">
  96. <i id="text{{$node->id}}" class="icon fa-list"></i>
  97. </button>
  98. </p>
  99. <p class="text-muted">
  100. <span>电信: {{$node->ct>0 ?$node->ct.' ms' :'无数据'}} </span>
  101. <span>联通: {{$node->cu>0 ?$node->cu.' ms' :'无数据'}} </span>
  102. <br>
  103. <span>移动: {{$node->cm>0 ?$node->cm.' ms' :'无数据'}} </span>
  104. <span>香港: {{$node->hk>0 ?$node->hk.' ms' :'无数据'}} </span>
  105. </p>
  106. </div>
  107. </div>
  108. </div>
  109. </div>
  110. @endforeach
  111. </div>
  112. </div>
  113. @endsection
  114. @section('javascript')
  115. <script src="/assets/global/vendor/matchheight/jquery.matchHeight-min.js" type="text/javascript"></script>
  116. <script src="/assets/global/js/Plugin/matchheight.js" type="text/javascript"></script>
  117. <script src="/assets/custom/jquery-qrcode/jquery.qrcode.min.js" type="text/javascript"></script>
  118. <script src="/assets/global/js/Plugin/webui-popover.js" type="text/javascript"></script>
  119. <script src="/assets/global/vendor/jvectormap/jquery-jvectormap.min.js"></script>
  120. <script src="/assets/custom/maps/jquery-jvectormap-world-mill-cn.js"></script>
  121. <script type="text/javascript">
  122. $(function() {
  123. $('#world-map').vectorMap({
  124. map: 'world_mill',
  125. scaleColors: ['#C8EEFF', '#0071A4'],
  126. normalizeFunction: 'polynomial',
  127. zoomAnimate: true,
  128. hoverOpacity: 0.7,
  129. hoverColor: false,
  130. regionStyle: {
  131. initial: {
  132. fill: '#3E8EF7',
  133. },
  134. hover: {
  135. fill: '#589FFC',
  136. },
  137. selected: {
  138. fill: '#0B69E3',
  139. },
  140. selectedHover: {
  141. fill: '#589FFC',
  142. },
  143. },
  144. markerStyle: {
  145. initial: {
  146. r: 3,
  147. fill: '#FF4C52',
  148. 'stroke-width': 0,
  149. },
  150. hover: {
  151. r: 6,
  152. stroke: '#FF4C52',
  153. 'stroke-width': 0,
  154. },
  155. },
  156. backgroundColor: '#fff',
  157. markers: [
  158. @foreach($nodesGeo as $name => $geo)
  159. {
  160. latLng: [{{$name}}], name: '{{$geo}}',
  161. },
  162. @endforeach
  163. ],
  164. });
  165. $('.node').matchHeight();
  166. $('.map').matchHeight();
  167. });
  168. function getInfo(id, type) {
  169. const oldClass = $('#' + type + id).attr('class');
  170. $.ajax({
  171. method: 'POST',
  172. url: '{{route('node')}}',
  173. data: {_token: '{{csrf_token()}}', id: id, type: type},
  174. beforeSend: function() {
  175. $('#' + type + id).removeAttr('class').addClass('icon wb-loop icon-spin');
  176. },
  177. success: function(ret) {
  178. if (ret.status === 'success') {
  179. switch (type) {
  180. case 'code':
  181. swal.fire({
  182. html: '<textarea class="form-control" rows="8" readonly="readonly">' + ret.data + '</textarea>' +
  183. '<a href="' + ret.data + '" class="btn btn-danger btn-block mt-10">打开' + ret.title + '</a>',
  184. showConfirmButton: false,
  185. });
  186. break;
  187. case 'qrcode':
  188. swal.fire({
  189. title: '{{trans('home.scan_qrcode')}}',
  190. html: '<div id="qrcode"></div>',
  191. onBeforeOpen: () => {
  192. $('#qrcode').qrcode({text: ret.data});
  193. },
  194. showConfirmButton: false,
  195. });
  196. break;
  197. case 'text':
  198. swal.fire({
  199. title: '{{trans('home.setting_info')}}',
  200. html: '<textarea class="form-control" rows="12" readonly="readonly">' + ret.data + '</textarea>',
  201. showConfirmButton: false,
  202. });
  203. break;
  204. default:
  205. swal.fire({title: ret.title, text: ret.data, icon: 'error'});
  206. }
  207. }
  208. },
  209. complete: function() {
  210. $('#' + type + id).removeAttr('class').addClass(oldClass);
  211. },
  212. });
  213. }
  214. </script>
  215. @endsection