export.blade.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. @extends('admin.table_layouts')
  2. @section('content')
  3. <div class="page-content container-fluid">
  4. <x-admin.table-panel :title="trans('admin.user.proxies_config', ['username' => $user->username])" :theads="[
  5. '#',
  6. trans('model.node.attribute'),
  7. trans('admin.node.info.extend'),
  8. trans('model.node.domain'),
  9. trans('model.node.ipv4'),
  10. trans('admin.user.proxy_info'),
  11. ]" :count="trans('admin.node.counts', ['num' => $nodeList->total()])" :pagination="$nodeList->links()">
  12. <x-slot:tbody>
  13. @foreach ($nodeList as $node)
  14. <tr>
  15. <td>{{ $loop->iteration }}</td>
  16. <td>
  17. @can('admin.node.edit')
  18. <a href="{{ route('admin.node.edit', $node) }}" target="_blank"> {{ $node->name }} </a>
  19. @else
  20. {{ $node->name }}
  21. @endcan
  22. </td>
  23. <td>
  24. @isset($node->profile['passwd'])
  25. {{-- 单端口 --}}
  26. <span class="badge badge-lg badge-info"><i class="fa-solid fa-arrows-left-right-to-line" aria-hidden="true"></i></span>
  27. @endisset
  28. @if ($node->is_display === 0)
  29. {{-- 节点完全不可见 --}}
  30. <span class="badge badge-lg badge-danger"><i class="icon wb-eye-close" aria-hidden="true"></i></span>
  31. @elseif($node->is_display === 1)
  32. {{-- 节点只在页面中显示 --}}
  33. <span class="badge badge-lg badge-danger"><i class="fa-solid fa-link-slash" aria-hidden="true"></i></span>
  34. @elseif($node->is_display === 2)
  35. {{-- 节点只可被订阅到 --}}
  36. <span class="badge badge-lg badge-danger"><i class="fa-solid fa-store-slash" aria-hidden="true"></i></span>
  37. @endif
  38. </td>
  39. <td>{{ $node->server }}</td>
  40. <td>{{ $node->ip }}</td>
  41. <td>
  42. @can('admin.user.exportProxy')
  43. <div class="btn-group">
  44. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{ $node->id }}','code')">
  45. <i class="fa-solid fa-code" id="code{{ $node->id }}"></i>
  46. </button>
  47. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{ $node->id }}','qrcode')">
  48. <i class="fa-solid fa-qrcode" id="qrcode{{ $node->id }}"></i>
  49. </button>
  50. <button class="btn btn-sm btn-outline-info" onclick="getInfo('{{ $node->id }}','text')">
  51. <i class="fa-solid fa-list" id="text{{ $node->id }}"></i>
  52. </button>
  53. </div>
  54. @endcan
  55. </td>
  56. </tr>
  57. @endforeach
  58. </x-slot:tbody>
  59. </x-admin.table-panel>
  60. </div>
  61. @endsection
  62. @push('javascript')
  63. <script src="/assets/custom/easy.qrcode.min.js" type="text/javascript"></script>
  64. @can('admin.user.exportProxy')
  65. <script>
  66. function getInfo(id, type) {
  67. const oldClass = $(`#${type}${id}`).attr("class");
  68. const requestOptions = {
  69. beforeSend: function() {
  70. $(`#${type}${id}`).removeAttr("class").addClass("icon wb-loop icon-spin");
  71. },
  72. complete: function() {
  73. $(`#${type}${id}`).removeAttr("class").addClass(oldClass);
  74. }
  75. };
  76. switch (type) {
  77. case "code":
  78. requestOptions.success = function(ret) {
  79. if (ret.status === "success") {
  80. swal.fire({
  81. html: "<textarea class=\"form-control\" rows=\"8\" readonly=\"readonly\">" + ret.data +
  82. "</textarea>" +
  83. "<a href=\"" + ret.data +
  84. '" class="btn btn-block btn-danger mt-4">{{ trans('common.open') }} ' +
  85. ret.title + "</a>",
  86. showConfirmButton: false
  87. });
  88. }
  89. };
  90. break;
  91. case "qrcode":
  92. requestOptions.success = function(ret) {
  93. if (ret.status === "success") {
  94. swal.fire({
  95. title: '{{ trans('user.scan_qrcode') }}',
  96. html: '<div id="qrcode"></div><button class="btn btn-block btn-outline-primary mt-4" onclick="Download()"> <i class="icon wb-download"></i> {{ trans('common.download') }}</button>',
  97. onBeforeOpen: () => {
  98. new QRCode(document.getElementById("qrcode"), {
  99. text: ret.data
  100. });
  101. },
  102. showConfirmButton: false
  103. });
  104. }
  105. };
  106. break;
  107. case "text":
  108. requestOptions.success = function(ret) {
  109. if (ret.status === "success") {
  110. swal.fire({
  111. title: '{{ trans('user.node.info') }}',
  112. html: "<textarea class=\"form-control\" rows=\"12\" readonly=\"readonly\">" + ret.data +
  113. "</textarea>",
  114. showConfirmButton: false
  115. });
  116. }
  117. };
  118. break;
  119. default:
  120. requestOptions.success = function(ret) {
  121. if (ret.status === "success") {
  122. swal.fire({
  123. title: ret.title,
  124. text: ret.data
  125. });
  126. }
  127. };
  128. }
  129. ajaxPost('{{ route('admin.user.exportProxy', $user) }}', {
  130. id: id,
  131. type: type
  132. }, requestOptions);
  133. }
  134. function Download() {
  135. const canvas = document.getElementsByTagName("canvas")[0];
  136. canvas.toBlob((blob) => {
  137. let link = document.createElement("a");
  138. link.download = "qr.png";
  139. let reader = new FileReader();
  140. reader.readAsDataURL(blob);
  141. reader.onload = () => {
  142. link.href = reader.result;
  143. link.click();
  144. };
  145. }, "image/png");
  146. }
  147. </script>
  148. @endcan
  149. @endpush