layouts.blade.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. @extends('_layout')
  2. @section('title', sysConfig('website_name'))
  3. @section('layout_css')
  4. <link href="/assets/global/fonts/font-awesome/css/all.min.css" rel="stylesheet">
  5. @yield('css')
  6. @endsection
  7. @section('body_class', 'dashboard')
  8. @section('layout_content')
  9. <nav class="site-navbar navbar navbar-default navbar-fixed-top navbar-mega {{ config('theme.navbar.inverse') }} {{ config('theme.navbar.skin') }}"
  10. role="navigation">
  11. <div class="navbar-header">
  12. <button class="navbar-toggler hamburger hamburger-close navbar-toggler-left hided" data-toggle="menubar" type="button">
  13. <span class="sr-only">{{ trans('common.toggle_action', ['action' => trans('common.function.navigation')]) }}</span>
  14. <span class="hamburger-bar"></span>
  15. </button>
  16. <button class="navbar-toggler collapsed" data-target="#site-navbar-collapse" data-toggle="collapse" type="button">
  17. <i class="icon wb-more-horizontal" aria-hidden="true"></i>
  18. </button>
  19. <div class="navbar-brand navbar-brand-center">
  20. <img class="navbar-brand-logo" src="{{ sysConfig('website_logo') ? asset(sysConfig('website_logo')) : '/assets/images/logo.png' }}"
  21. alt="logo" />
  22. <span class="navbar-brand-text hidden-xs-down"> {{ sysConfig('website_name') }}</span>
  23. </div>
  24. </div>
  25. <div class="navbar-container container-fluid">
  26. <div class="collapse navbar-collapse navbar-collapse-toolbar" id="site-navbar-collapse">
  27. <ul class="nav navbar-toolbar">
  28. <li class="nav-item hidden-float" id="toggleMenubar">
  29. <a class="nav-link" data-toggle="menubar" href="#" role="button">
  30. <i class="icon hamburger hamburger-arrow-left">
  31. <span class="sr-only">{{ trans('common.toggle_action', ['action' => trans('common.function.menubar')]) }}</span>
  32. <span class="hamburger-bar"></span>
  33. </i>
  34. </a>
  35. </li>
  36. <li class="nav-item hidden-sm-down">
  37. <a class="nav-link icon icon-fullscreen" data-toggle="fullscreen" href="#" role="button">
  38. <span class="sr-only">{{ trans('common.toggle_action', ['action' => trans('common.function.fullscreen')]) }}</span>
  39. </a>
  40. </li>
  41. <li class="nav-item dropdown">
  42. <a class="nav-link" data-toggle="dropdown" href="javascript:void(0)" role="button">
  43. <span class="icon wb-globe"></span>
  44. <span class="icon wb-chevron-down-mini"></span>
  45. </a>
  46. <div class="dropdown-menu" role="menu">
  47. @foreach (config('common.language') as $key => $value)
  48. <a class="dropdown-item" href="{{ route('lang', ['locale' => $key]) }}" role="menuitem">
  49. <i class="fi fi-{{ $value[1] }}" aria-hidden="true"></i>
  50. <span style="padding: inherit;">{{ $value[0] }}</span>
  51. </a>
  52. @endforeach
  53. </div>
  54. </li>
  55. </ul>
  56. <ul class="nav navbar-toolbar navbar-right navbar-toolbar-right">
  57. <li class="nav-item dropdown">
  58. <a class="nav-link navbar-avatar" data-toggle="dropdown" data-animation="scale-up" href="#" role="button" aria-expanded="false">
  59. <span class="avatar avatar-online">
  60. <img data-uid="{{ auth()->user()->id }}" data-qq="{{ auth()->user()->qq }}" data-username="{{ auth()->user()->username }}"
  61. src="" alt="{{ trans('common.avatar') }}" loading="lazy" />
  62. <i></i>
  63. </span>
  64. </a>
  65. <div class="dropdown-menu" role="menu">
  66. <a class="dropdown-item" href="/" role="menuitem">
  67. <i class="icon wb-settings" aria-hidden="true"></i>
  68. {{ trans('admin.user_dashboard') }}
  69. </a>
  70. <div class="dropdown-divider" role="presentation"></div>
  71. <a class="dropdown-item" href="{{ route('logout') }}" role="menuitem">
  72. <i class="icon wb-power" aria-hidden="true"></i>
  73. {{ trans('auth.logout') }}
  74. </a>
  75. </div>
  76. </li>
  77. </ul>
  78. </div>
  79. </div>
  80. </nav>
  81. @php
  82. $apply_count = auth()->user()->can('admin.aff.index')
  83. ? Cache::rememberForever('open_referral_apply_count', static function () {
  84. return App\Models\ReferralApply::whereStatus(0)->count();
  85. })
  86. : null;
  87. $ticket_count = auth()->user()->can('admin.ticket.index')
  88. ? Cache::rememberForever('open_ticket_count', static function () {
  89. return App\Models\Ticket::whereStatus(0)->count();
  90. })
  91. : null;
  92. $env = config('app.env') === 'local' && config('app.debug');
  93. @endphp
  94. <x-ui.site.menubar :items="[
  95. ['icon' => 'wb-dashboard', 'route' => 'admin.index', 'text' => trans('admin.menu.dashboard'), 'can' => 'admin.index'],
  96. [
  97. 'icon' => 'wb-user',
  98. 'text' => trans('admin.menu.user.attribute'),
  99. 'active' => ['admin.user.*', 'admin.log.credit', 'admin.subscribe.*'],
  100. 'can' => ['admin.user.index', 'admin.user.group.index', 'admin.log.credit', 'admin.subscribe.index'],
  101. 'children' => [
  102. [
  103. 'route' => 'admin.user.index',
  104. 'active' => ['admin.user.index', 'admin.user.edit', 'admin.user.monitor', 'admin.user.online', 'admin.user.online', 'admin.user.export'],
  105. 'text' => trans('admin.menu.user.list'),
  106. 'can' => 'admin.user.index',
  107. ],
  108. ['route' => 'admin.user.oauth', 'active' => 'admin.user.oauth', 'text' => trans('admin.menu.user.oauth'), 'can' => 'admin.user.oauth'],
  109. [
  110. 'route' => 'admin.user.group.index',
  111. 'active' => 'admin.user.group.*',
  112. 'text' => trans('admin.menu.user.group'),
  113. 'can' => 'admin.user.group.index',
  114. ],
  115. ['route' => 'admin.log.credit', 'active' => 'admin.log.credit', 'text' => trans('admin.menu.user.credit_log'), 'can' => 'admin.log.credit'],
  116. [
  117. 'route' => 'admin.subscribe.index',
  118. 'active' => 'admin.subscribe.*',
  119. 'text' => trans('admin.menu.user.subscribe'),
  120. 'can' => 'admin.subscribe.index',
  121. ],
  122. ],
  123. ],
  124. [
  125. 'icon' => 'wb-users',
  126. 'text' => trans('admin.menu.rbac.attribute'),
  127. 'active' => ['admin.permission.*', 'admin.role.*'],
  128. 'can' => ['admin.permission.index', 'admin.role.index'],
  129. 'children' => [
  130. [
  131. 'route' => 'admin.permission.index',
  132. 'active' => 'admin.permission.*',
  133. 'text' => trans('admin.menu.rbac.permission'),
  134. 'can' => 'admin.permission.index',
  135. ],
  136. ['route' => 'admin.role.index', 'active' => 'admin.role.*', 'text' => trans('admin.menu.rbac.role'), 'can' => 'admin.role.index'],
  137. ],
  138. ],
  139. [
  140. 'icon' => 'wb-chat-working',
  141. 'text' => trans('admin.menu.customer_service.attribute'),
  142. 'active' => ['admin.ticket.*', 'admin.article.*', 'admin.marketing.*'],
  143. 'can' => ['admin.ticket.index', 'admin.article.index', 'admin.marketing.index'],
  144. 'badge' => $ticket_count,
  145. 'children' => [
  146. [
  147. 'route' => 'admin.ticket.index',
  148. 'active' => 'admin.ticket.*',
  149. 'text' => trans('admin.menu.customer_service.ticket'),
  150. 'can' => 'admin.ticket.index',
  151. 'badge' => $ticket_count,
  152. ],
  153. [
  154. 'route' => 'admin.article.index',
  155. 'active' => 'admin.article.*',
  156. 'text' => trans('admin.menu.customer_service.article'),
  157. 'can' => 'admin.article.index',
  158. ],
  159. [
  160. 'route' => 'admin.marketing.index',
  161. 'active' => 'admin.marketing.*',
  162. 'text' => trans('admin.menu.customer_service.marketing'),
  163. 'can' => 'admin.marketing.index',
  164. ],
  165. ],
  166. ],
  167. [
  168. 'icon' => 'wb-cloud',
  169. 'text' => trans('admin.menu.node.attribute'),
  170. 'active' => ['admin.node.*', 'admin.node.auth.*', 'admin.node.cert.*'],
  171. 'can' => ['admin.node.index', 'admin.node.auth.index', 'admin.node.cert.index'],
  172. 'children' => [
  173. [
  174. 'route' => 'admin.node.index',
  175. 'active' => ['admin.node.index', 'admin.node.create', 'admin.node.edit'],
  176. 'text' => trans('admin.menu.node.list'),
  177. 'can' => 'admin.node.index',
  178. ],
  179. [
  180. 'route' => 'admin.node.auth.index',
  181. 'active' => 'admin.node.auth.*',
  182. 'text' => trans('admin.menu.node.auth'),
  183. 'can' => 'admin.node.auth.index',
  184. ],
  185. [
  186. 'route' => 'admin.node.cert.index',
  187. 'active' => 'admin.node.cert.*',
  188. 'text' => trans('admin.menu.node.cert'),
  189. 'can' => 'admin.node.cert.index',
  190. ],
  191. ],
  192. ],
  193. [
  194. 'icon' => 'wb-eye',
  195. 'text' => trans('admin.menu.rule.attribute'),
  196. 'active' => 'admin.rule.*',
  197. 'can' => ['admin.rule.index', 'admin.rule.group.index', 'admin.rule.log'],
  198. 'children' => [
  199. ['route' => 'admin.rule.index', 'active' => 'admin.rule.index', 'text' => trans('admin.menu.rule.list'), 'can' => 'admin.rule.index'],
  200. [
  201. 'route' => 'admin.rule.group.index',
  202. 'active' => 'admin.rule.group.*',
  203. 'text' => trans('admin.menu.rule.group'),
  204. 'can' => 'admin.rule.group.index',
  205. ],
  206. ['route' => 'admin.rule.log', 'active' => 'admin.rule.log', 'text' => trans('admin.menu.rule.trigger'), 'can' => 'admin.rule.log'],
  207. ],
  208. ],
  209. [
  210. 'icon' => 'wb-shopping-cart',
  211. 'text' => trans('admin.menu.shop.attribute'),
  212. 'active' => ['admin.goods.*', 'admin.coupon.*', 'admin.order'],
  213. 'can' => ['admin.goods.index', 'admin.coupon.index', 'admin.order'],
  214. 'children' => [
  215. ['route' => 'admin.goods.index', 'active' => 'admin.goods.*', 'text' => trans('admin.menu.shop.goods'), 'can' => 'admin.goods.index'],
  216. ['route' => 'admin.coupon.index', 'active' => 'admin.coupon.*', 'text' => trans('admin.menu.shop.coupon'), 'can' => 'admin.coupon.index'],
  217. ['route' => 'admin.order', 'active' => 'admin.order', 'text' => trans('admin.menu.shop.order'), 'can' => 'admin.order'],
  218. ],
  219. ],
  220. [
  221. 'icon' => 'wb-thumb-up',
  222. 'text' => trans('admin.menu.promotion.attribute'),
  223. 'active' => ['admin.invite.*', 'admin.aff.*'],
  224. 'can' => ['admin.invite.index', 'admin.aff.index', 'admin.aff.rebate'],
  225. 'badge' => $apply_count,
  226. 'children' => [
  227. ['route' => 'admin.invite.index', 'active' => 'admin.invite.*', 'text' => trans('admin.menu.promotion.invite'), 'can' => 'admin.invite.index'],
  228. [
  229. 'route' => 'admin.aff.index',
  230. 'active' => ['admin.aff.index', 'admin.aff.detail'],
  231. 'text' => trans('admin.menu.promotion.withdraw'),
  232. 'can' => 'admin.aff.index',
  233. 'badge' => $apply_count,
  234. ],
  235. [
  236. 'route' => 'admin.aff.rebate',
  237. 'active' => 'admin.aff.rebate',
  238. 'text' => trans('admin.menu.promotion.rebate_flow'),
  239. 'can' => 'admin.aff.rebate',
  240. ],
  241. ],
  242. ],
  243. [
  244. 'icon' => 'wb-stats-bars',
  245. 'text' => trans('admin.menu.analysis.attribute'),
  246. 'active' => 'admin.report.*',
  247. 'can' => ['admin.report.accounting', 'admin.report.userAnalysis', 'admin.report.nodeAnalysis', 'admin.report.siteAnalysis'],
  248. 'children' => [
  249. [
  250. 'route' => 'admin.report.accounting',
  251. 'active' => 'admin.report.accounting',
  252. 'text' => trans('admin.menu.analysis.accounting'),
  253. 'can' => 'admin.report.accounting',
  254. ],
  255. [
  256. 'route' => 'admin.report.userAnalysis',
  257. 'active' => 'admin.report.userAnalysis',
  258. 'text' => trans('admin.menu.analysis.user_flow'),
  259. 'can' => 'admin.report.userAnalysis',
  260. ],
  261. [
  262. 'route' => 'admin.report.nodeAnalysis',
  263. 'active' => 'admin.report.nodeAnalysis',
  264. 'text' => trans('admin.menu.analysis.node_flow'),
  265. 'can' => 'admin.report.nodeAnalysis',
  266. ],
  267. [
  268. 'route' => 'admin.report.siteAnalysis',
  269. 'active' => 'admin.report.siteAnalysis',
  270. 'text' => trans('admin.menu.analysis.site_flow'),
  271. 'can' => 'admin.report.siteAnalysis',
  272. ],
  273. ],
  274. ],
  275. [
  276. 'icon' => 'wb-calendar',
  277. 'text' => trans('admin.menu.log.attribute'),
  278. 'active' => [
  279. 'admin.log.traffic',
  280. 'admin.log.flow',
  281. 'admin.log.ban',
  282. 'admin.log.ip',
  283. 'admin.log.online',
  284. 'admin.log.notify',
  285. 'admin.payment.callback',
  286. ],
  287. 'can' => ['admin.log.traffic', 'admin.log.flow', 'admin.log.ban', 'admin.log.ip', 'admin.log.online', 'admin.log.notify', 'admin.payment.callback'],
  288. 'children' => [
  289. ['route' => 'admin.log.traffic', 'active' => 'admin.log.traffic', 'text' => trans('admin.menu.log.traffic'), 'can' => 'admin.log.traffic'],
  290. ['route' => 'admin.log.flow', 'active' => 'admin.log.flow', 'text' => trans('admin.menu.log.traffic_flow'), 'can' => 'admin.log.flow'],
  291. ['route' => 'admin.log.ban', 'active' => 'admin.log.ban', 'text' => trans('admin.menu.log.service_ban'), 'can' => 'admin.log.ban'],
  292. ['route' => 'admin.log.ip', 'active' => 'admin.log.ip', 'text' => trans('admin.menu.log.online_logs'), 'can' => 'admin.log.ip'],
  293. ['route' => 'admin.log.online', 'active' => 'admin.log.online', 'text' => trans('admin.menu.log.online_monitor'), 'can' => 'admin.log.online'],
  294. ['route' => 'admin.log.notify', 'active' => 'admin.log.notify', 'text' => trans('admin.menu.log.notify'), 'can' => 'admin.log.notify'],
  295. [
  296. 'route' => 'admin.payment.callback',
  297. 'active' => 'admin.payment.callback',
  298. 'text' => trans('admin.menu.log.payment_callback'),
  299. 'can' => 'admin.payment.callback',
  300. ],
  301. ['route' => 'log-viewer::dashboard', 'text' => trans('admin.menu.log.system'), 'can' => 'log-viewer'],
  302. ['route' => 'horizon.index', 'text' => 'Horizon', 'can' => 'viewHorizon'],
  303. ['route' => 'telescope', 'text' => 'Telescope', 'can' => 'viewTelescope', 'show' => $env],
  304. ],
  305. ],
  306. [
  307. 'icon' => 'wb-briefcase',
  308. 'text' => trans('admin.menu.tools.attribute'),
  309. 'active' => 'admin.tools.*',
  310. 'can' => ['admin.tools.decompile', 'admin.tools.convert', 'admin.tools.import', 'admin.tools.analysis'],
  311. 'children' => [
  312. [
  313. 'route' => 'admin.tools.decompile',
  314. 'active' => 'admin.tools.decompile',
  315. 'text' => trans('admin.menu.tools.decompile'),
  316. 'can' => 'admin.tools.decompile',
  317. ],
  318. [
  319. 'route' => 'admin.tools.convert',
  320. 'active' => 'admin.tools.convert',
  321. 'text' => trans('admin.menu.tools.convert'),
  322. 'can' => 'admin.tools.convert',
  323. ],
  324. ['route' => 'admin.tools.import', 'active' => 'admin.tools.import', 'text' => trans('admin.menu.tools.import'), 'can' => 'admin.tools.import'],
  325. [
  326. 'route' => 'admin.tools.analysis',
  327. 'active' => 'admin.tools.analysis',
  328. 'text' => trans('admin.menu.tools.analysis'),
  329. 'can' => 'admin.tools.analysis',
  330. ],
  331. ],
  332. ],
  333. [
  334. 'icon' => 'wb-settings',
  335. 'text' => trans('admin.menu.setting.attribute'),
  336. 'active' => ['admin.config.*', 'admin.system.index'],
  337. 'can' => ['admin.config.filter.index', 'admin.config.index', 'admin.system.index'],
  338. 'children' => [
  339. [
  340. 'route' => 'admin.config.filter.index',
  341. 'active' => 'admin.config.filter.index',
  342. 'text' => trans('admin.menu.setting.email_suffix'),
  343. 'can' => 'admin.config.filter.index',
  344. ],
  345. [
  346. 'route' => 'admin.config.index',
  347. 'active' => 'admin.config.index',
  348. 'text' => trans('admin.menu.setting.universal'),
  349. 'can' => 'admin.config.index',
  350. ],
  351. [
  352. 'route' => 'admin.system.index',
  353. 'active' => 'admin.system.index',
  354. 'text' => trans('admin.menu.setting.system'),
  355. 'can' => 'admin.system.index',
  356. ],
  357. ],
  358. ],
  359. ]" />
  360. <div class="page">
  361. @yield('content')
  362. </div>
  363. @endsection
  364. @section('layout_javascript')
  365. <script src="/assets/custom/sweetalert2/sweetalert2.all.min.js"></script>
  366. <script>
  367. // 全局变量,用于common.js
  368. const CSRF_TOKEN = '{{ csrf_token() }}';
  369. const TRANS = {
  370. warning: '{{ trans('common.warning') }}',
  371. confirm: {
  372. delete: '{{ trans('admin.confirm.delete', ['attribute' => '{attribute}', 'name' => '{name}']) }}'
  373. },
  374. btn: {
  375. close: '{{ trans('common.close') }}',
  376. confirm: '{{ trans('common.confirm') }}'
  377. },
  378. copy: {
  379. success: '{{ trans('common.copy.success') }}',
  380. failed: '{{ trans('common.copy.failed') }}'
  381. }
  382. };
  383. const $buoop = {
  384. required: {
  385. e: 11,
  386. f: -6,
  387. o: -6,
  388. s: -6,
  389. c: -6
  390. },
  391. insecure: true,
  392. unsupported: true,
  393. api: 2024.07
  394. };
  395. function $buo_f() {
  396. const e = document.createElement("script");
  397. e.src = "//browser-update.org/update.min.js";
  398. document.body.appendChild(e);
  399. }
  400. try {
  401. document.addEventListener("DOMContentLoaded", $buo_f, false);
  402. } catch (e) {
  403. window.attachEvent("onload", $buo_f);
  404. }
  405. </script>
  406. <script src="/assets/js/config/common.js"></script>
  407. <script src="/assets/js/config/admin.js"></script>
  408. @yield('javascript')
  409. @endsection