Asset.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. <?php
  2. namespace Dcat\Admin\Layout;
  3. class Asset
  4. {
  5. /**
  6. * 路径别名.
  7. *
  8. * @var array
  9. */
  10. protected $pathAlias = [
  11. // Dcat Admin静态资源路径别名
  12. '@admin' => 'vendors/dcat-admin',
  13. // Dcat Acmin扩展静态资源路径别名
  14. '@extension' => 'vendors/dcat-admin-extensions',
  15. ];
  16. /**
  17. * 别名.
  18. *
  19. * @var array
  20. */
  21. protected $alias = [
  22. '@nunito' => [
  23. 'css' => ['https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,800,800i,900,900i'],
  24. ],
  25. '@montserrat' => [
  26. 'css' => ['https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600'],
  27. ],
  28. '@dcat' => [
  29. 'js' => '@admin/dcat/js/dcat-app.js',
  30. 'css' => '@admin/dcat/css/dcat-app.css',
  31. ],
  32. '@vendors' => [
  33. 'js' => '@admin/vendors/js/vendors.min.js',
  34. 'css' => '@admin/vendors/css/vendors.min.css',
  35. ],
  36. '@bootstrap' => [
  37. 'css' => '@admin/css/bootstrap.css',
  38. ],
  39. '@bootstrap-extended' => [
  40. 'css' => '@admin/css/bootstrap-extended.css',
  41. ],
  42. '@default-colors' => [
  43. 'css' => '@admin/css/colors.css',
  44. ],
  45. '@menu' => [
  46. 'js' => '@admin/js/core/app-menu.js',
  47. ],
  48. '@app' => [
  49. 'js' => '@admin/js/core/app.js',
  50. ],
  51. '@components' => [
  52. 'css' => '@admin/css/components.css',
  53. ],
  54. '@palette-gradient' => [
  55. 'css' => '@admin/css/core/colors/palette-gradient.css',
  56. ],
  57. '@datatables' => [
  58. 'css' => '@admin/vendors/css/tables/datatable/datatables.min.css',
  59. ],
  60. '@data-list-view' => [
  61. 'css' => '@admin/css/pages/data-list-view.css',
  62. ],
  63. '@custom' => [
  64. 'css' => '@admin/css/custom-laravel.css',
  65. ],
  66. '@grid-extension' => [
  67. 'js' => '@admin/dcat/extra/grid-extend.js',
  68. ],
  69. '@resource-selector' => [
  70. 'js' => '@admin/dcat/extra/resource-selector.js',
  71. ],
  72. '@layer' => [
  73. 'js' => '@admin/dcat/plugins/layer/layer.js',
  74. ],
  75. '@pjax' => [
  76. 'js' => '@admin/dcat/plugins/jquery-pjax/jquery.pjax.min.js',
  77. ],
  78. '@toastr' => [
  79. 'js' => '@admin/vendors/js/extensions/toastr.min.js',
  80. 'css' => '@admin/vendors/css/extensions/toastr.css',
  81. ],
  82. '@jquery.nestable' => [
  83. 'js' => '@admin/dcat/plugins/nestable/jquery.nestable.min.js',
  84. 'css' => '@admin/dcat/plugins/nestable/nestable.css',
  85. ],
  86. '@validator' => [
  87. 'js' => '@admin/dcat/plugins/bootstrap-validator/validator.min.js',
  88. ],
  89. '@select2' => [
  90. 'js' => '@admin/vendors/js/forms/select/select2.full.min.js',
  91. 'css' => '@admin/vendors/css/forms/select/select2.min.css',
  92. ],
  93. '@bootstrap-datetimepicker' => [
  94. 'js' => '@admin/dcat/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js',
  95. 'css' => '@admin/dcat/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css',
  96. ],
  97. '@moment' => [
  98. 'js' => [
  99. '@admin/dcat/plugins/moment/moment.min.js',
  100. ],
  101. ],
  102. '@moment-timezone' => [
  103. 'js' => [
  104. '@admin/dcat/plugins/moment/moment-timezone-with-data.min.js',
  105. ],
  106. ],
  107. '@rwd-table' => [
  108. 'js' => '@admin/dcat/plugins/RWD-Table-Patterns/dist/js/rwd-table.min.js',
  109. 'css' => '@admin/dcat/plugins/RWD-Table-Patterns/dist/css/rwd-table.min.css',
  110. ],
  111. '@jstree' => [
  112. 'js' => '@admin/dcat/plugins/jstree-theme/jstree.min.js',
  113. 'css' => '@admin/dcat/plugins/jstree-theme/themes/proton/style.min.css',
  114. ],
  115. '@switchery' => [
  116. 'js' => '@admin/dcat/plugins/switchery/switchery.min.js',
  117. 'css' => '@admin/dcat/plugins/switchery/switchery.min.css',
  118. ],
  119. '@webuploader' => [
  120. 'js' => [
  121. '@admin/dcat/plugins/webuploader/webuploader.min.js',
  122. '@admin/dcat/extra/upload.js',
  123. ],
  124. 'css' => '@admin/dcat/extra/upload.css',
  125. ],
  126. '@chartjs' => [
  127. 'js' => '@admin/dcat/plugins/chart.js/chart.bundle.min.js',
  128. ],
  129. '@jquery.sparkline' => [
  130. 'js' => '@admin/dcat/plugins/jquery.sparkline/jquery.sparkline.min.js',
  131. ],
  132. '@jquery.bootstrap-duallistbox' => [
  133. 'js' => '@admin/dcat/plugins/bootstrap-duallistbox/dist/jquery.bootstrap-duallistbox.min.js',
  134. 'css' => '@admin/dcat/plugins/bootstrap-duallistbox/dist/bootstrap-duallistbox.min.css',
  135. ],
  136. '@number-input' => [
  137. 'js' => '@admin/dcat/plugins/number-input/bootstrap-number-input.js',
  138. ],
  139. '@ionslider' => [
  140. 'js' => [
  141. '@admin/dcat/plugins/ionslider/ion.rangeSlider.min.js',
  142. ],
  143. 'css' => [
  144. '@admin/dcat/plugins/ionslider/ion.rangeSlider.css',
  145. '@admin/dcat/plugins/ionslider/ion.rangeSlider.skinNice.css',
  146. ],
  147. ],
  148. '@editor-md' => [
  149. 'js' => [
  150. '@admin/dcat/plugins/editor-md/lib/raphael.min.js',
  151. '@admin/dcat/plugins/editor-md/lib/marked.min.js',
  152. '@admin/dcat/plugins/editor-md/lib/prettify.min.js',
  153. '@admin/dcat/plugins/editor-md/lib/underscore.min.js',
  154. '@admin/dcat/plugins/editor-md/lib/sequence-diagram.min.js',
  155. '@admin/dcat/plugins/editor-md/lib/flowchart.min.js',
  156. '@admin/dcat/plugins/editor-md/lib/jquery.flowchart.min.js',
  157. '@admin/dcat/plugins/editor-md/editormd.min.js',
  158. ],
  159. 'css' => [
  160. '@admin/dcat/plugins/editor-md/css/editormd.preview.min.css',
  161. '@admin/dcat/extra/markdown.css',
  162. ],
  163. ],
  164. '@jquery.inputmask' => [
  165. 'js' => '@admin/dcat/plugins/input-mask/jquery.inputmask.bundle.min.js',
  166. ],
  167. '@apex-charts' => [
  168. 'js' => '@admin/vendors/js/charts/apexcharts.min.js',
  169. ],
  170. '@smart-wizard' => [
  171. 'js' => '@admin/dcat/plugins/SmartWizard/dist/js/jquery.smartWizard.min.js',
  172. 'css' => '@admin/dcat/extra/step.css',
  173. ],
  174. '@fontawesome-iconpicker' => [
  175. 'js' => '@admin/dcat/plugins/fontawesome-iconpicker/dist/js/fontawesome-iconpicker.js',
  176. 'css' => '@admin/dcat/plugins/fontawesome-iconpicker/dist/css/fontawesome-iconpicker.min.css',
  177. ],
  178. ];
  179. /**
  180. * js代码.
  181. *
  182. * @var array
  183. */
  184. public $script = [];
  185. /**
  186. * css代码.
  187. *
  188. * @var array
  189. */
  190. public $style = [];
  191. /**
  192. * css脚本路径.
  193. *
  194. * @var array
  195. */
  196. public $css = [];
  197. /**
  198. * js脚本路径.
  199. *
  200. * @var array
  201. */
  202. public $js = [];
  203. /**
  204. * 在head标签内加载的js脚本.
  205. *
  206. * @var array
  207. */
  208. public $headerJs = [
  209. 'vendors' => '@vendors',
  210. 'dcat' => '@dcat',
  211. ];
  212. /**
  213. * 基础css.
  214. *
  215. * @var array
  216. */
  217. public $baseCss = [
  218. 'vendors' => '@vendors',
  219. 'bootstrap' => '@bootstrap',
  220. 'bootstrap-extended' => '@bootstrap-extended',
  221. 'toastr' => '@toastr',
  222. 'components' => '@components',
  223. 'palette-gradient' => '@palette-gradient',
  224. 'colors' => '@default-colors',
  225. //'custom' => 'custom',
  226. 'datatables' => '@datatables',
  227. 'data-list-view' => '@data-list-view',
  228. 'dcat' => '@dcat',
  229. ];
  230. /**
  231. * 基础js.
  232. *
  233. * @var array
  234. */
  235. public $baseJs = [
  236. 'menu' => '@menu',
  237. 'app' => '@app',
  238. 'toastr' => '@toastr',
  239. 'pjax' => '@pjax',
  240. 'validator' => '@validator',
  241. 'layer' => '@layer',
  242. ];
  243. /**
  244. * @var array
  245. */
  246. public $fonts = [
  247. '@nunito',
  248. '@montserrat',
  249. ];
  250. /**
  251. * @var bool
  252. */
  253. protected $isPjax = false;
  254. /**
  255. * @var bool
  256. */
  257. protected $usingFullPage = false;
  258. /**
  259. * @var array
  260. */
  261. protected $themeCssMap = [
  262. 'dark' => 'dark-layout',
  263. 'semi-dark' => 'semi-dark-layout',
  264. ];
  265. /**
  266. * Assets constructor.
  267. */
  268. public function __construct()
  269. {
  270. $this->isPjax = request()->pjax();
  271. }
  272. /**
  273. * 设置或获取别名.
  274. *
  275. * @param string|array $name
  276. * @param string|array $js
  277. * @param string|array $css
  278. *
  279. * @return void|array
  280. */
  281. public function alias($name, $js = null, $css = null)
  282. {
  283. if (is_array($name)) {
  284. foreach ($name as $key => $value) {
  285. $this->alias($key, $value['js'] ?? [], $value['css'] ?? []);
  286. }
  287. return;
  288. }
  289. if ($js === null && $css === null) {
  290. return $this->alias[$name] ?? [];
  291. }
  292. if (mb_strpos($name, '@') !== 0) {
  293. $name = '@'.$name;
  294. }
  295. $this->alias[$name] = [
  296. 'js' => $js,
  297. 'css' => $css,
  298. ];
  299. }
  300. /**
  301. * 使用全页面(无菜单和导航栏).
  302. *
  303. * @param bool $value
  304. *
  305. * @return $this
  306. */
  307. public function full(bool $value = true)
  308. {
  309. $this->usingFullPage = $value;
  310. return $this;
  311. }
  312. /**
  313. * 根据别名设置需要载入的js和css脚本.
  314. *
  315. * @param string $alias
  316. */
  317. public function collect(string $alias)
  318. {
  319. if (mb_strpos($alias, '@') !== 0) {
  320. $alias = '@'.$alias;
  321. }
  322. $this->js($this->alias[$alias]['js'] ?? null);
  323. $this->css($this->alias[$alias]['css'] ?? null);
  324. }
  325. /**
  326. * 设置需要载入的css脚本.
  327. *
  328. * @param string|array $css
  329. */
  330. public function css($css)
  331. {
  332. if (! $css) {
  333. return;
  334. }
  335. $this->css = array_merge(
  336. $this->css,
  337. (array) $css
  338. );
  339. }
  340. /**
  341. * 设置需要载入的基础css脚本.
  342. *
  343. * @param array $css
  344. */
  345. public function baseCss(array $css)
  346. {
  347. $this->baseCss = $css;
  348. }
  349. /**
  350. * 设置需要载入的js脚本.
  351. *
  352. * @param string|array $js
  353. */
  354. public function js($js)
  355. {
  356. if (! $js) {
  357. return;
  358. }
  359. $this->js = array_merge(
  360. $this->js,
  361. (array) $js
  362. );
  363. }
  364. /**
  365. * 根据别名获取资源路径.
  366. *
  367. * @param string $path
  368. * @param string $type
  369. *
  370. * @return string|array|null
  371. */
  372. public function get($path, string $type = 'js')
  373. {
  374. if (empty($this->alias[$path])) {
  375. return $this->url($path);
  376. }
  377. $paths = isset($this->alias[$path][$type]) ? (array) $this->alias[$path][$type] : null;
  378. if (! $paths) {
  379. return $paths;
  380. }
  381. foreach ($paths as &$value) {
  382. $value = $this->url($value);
  383. }
  384. return $paths;
  385. }
  386. /**
  387. * 获取静态资源完整URL.
  388. *
  389. * @param string $path
  390. *
  391. * @return string
  392. */
  393. public function url($path)
  394. {
  395. if (! $path) {
  396. return $path;
  397. }
  398. $path = $this->getRealPath($path);
  399. if (mb_strpos($path, '//') === false) {
  400. $path = config('admin.assets_server').'/'.trim($path, '/');
  401. }
  402. return (config('admin.https') || config('admin.secure')) ? secure_asset($path) : asset($path);
  403. }
  404. /**
  405. * 获取真实路径.
  406. *
  407. * @param string|null $path
  408. *
  409. * @return string|null
  410. */
  411. public function getRealPath(?string $path)
  412. {
  413. if (! $this->hasAlias($path)) {
  414. return $path;
  415. }
  416. return implode(
  417. '/',
  418. array_map(
  419. function ($v) {
  420. $v = $this->pathAlias[$v] ?? $v;
  421. if (! $this->hasAlias($v)) {
  422. return $v;
  423. }
  424. return $this->getRealPath($v);
  425. },
  426. explode('/', $path)
  427. )
  428. );
  429. }
  430. /**
  431. * 判断是否含有别名.
  432. *
  433. * @param string $value
  434. *
  435. * @return bool
  436. */
  437. protected function hasAlias($value)
  438. {
  439. return $value && mb_strpos($value, '@') !== false;
  440. }
  441. /**
  442. * 设置在head标签内加载的js.
  443. *
  444. * @param string|array $js
  445. */
  446. public function headerJs($js)
  447. {
  448. if (! $js) {
  449. return;
  450. }
  451. $this->headerJs = array_merge($this->headerJs, (array) $js);
  452. }
  453. /**
  454. * 设置基础js脚本.
  455. *
  456. * @param array $js
  457. */
  458. public function baseJs(array $js)
  459. {
  460. $this->baseJs = $js;
  461. }
  462. /**
  463. * 设置js代码.
  464. *
  465. * @param string|array $script
  466. */
  467. public function script($script)
  468. {
  469. if (! $script) {
  470. return;
  471. }
  472. $this->script = array_merge($this->script, (array) $script);
  473. }
  474. /**
  475. * 设置css代码.
  476. *
  477. * @param string $style
  478. */
  479. public function style($style)
  480. {
  481. if (! $style) {
  482. return;
  483. }
  484. $this->style = array_merge($this->style, (array) $style);
  485. }
  486. /**
  487. * 增加布局css文件.
  488. */
  489. protected function addLayoutCss()
  490. {
  491. if ($this->usingFullPage) {
  492. return;
  493. }
  494. if (config('admin.layout.main_layout_type') === 'horizontal') {
  495. $this->baseCss[] = '@admin/css/core/menu/menu-types/horizontal-menu.css';
  496. }
  497. $this->baseCss[] = '@admin/css/core/menu/menu-types/vertical-menu.css';
  498. }
  499. /**
  500. * 主题css文件.
  501. */
  502. protected function addThemeCss()
  503. {
  504. if (! $theme = config('admin.layout.theme')) {
  505. return;
  506. }
  507. $css = $this->themeCssMap[$theme] ?? $theme;
  508. if ($css === 'light') {
  509. return;
  510. }
  511. $this->baseCss[] = "@admin/css/themes/{$css}.css";
  512. }
  513. /**
  514. * 字体css脚本路径.
  515. */
  516. protected function addFontCss()
  517. {
  518. $this->fonts && (
  519. $this->baseCss = array_merge(
  520. $this->baseCss,
  521. (array) $this->fonts
  522. )
  523. );
  524. }
  525. /**
  526. * 合并基础css脚本.
  527. */
  528. protected function mergeBaseCss()
  529. {
  530. if ($this->isPjax) {
  531. return;
  532. }
  533. $this->addLayoutCss();
  534. $this->addThemeCss();
  535. $this->addFontCss();
  536. $this->css = array_merge($this->baseCss, $this->css);
  537. }
  538. /**
  539. * @return string
  540. */
  541. public function cssToHtml()
  542. {
  543. $this->mergeBaseCss();
  544. $html = '';
  545. foreach (array_unique($this->css) as &$v) {
  546. if (! $paths = $this->get($v, 'css')) {
  547. continue;
  548. }
  549. foreach ((array) $paths as $path) {
  550. $html .= "<link rel=\"stylesheet\" href=\"{$path}\">";
  551. }
  552. }
  553. return $html;
  554. }
  555. /**
  556. * 合并基础js脚本.
  557. */
  558. protected function mergeBaseJs()
  559. {
  560. if ($this->isPjax) {
  561. return;
  562. }
  563. if ($this->usingFullPage) {
  564. unset($this->baseJs['menu']);
  565. }
  566. $this->js = array_merge($this->baseJs, $this->js);
  567. }
  568. /**
  569. * @return string
  570. */
  571. public function jsToHtml()
  572. {
  573. $this->mergeBaseJs();
  574. $html = '';
  575. foreach (array_unique($this->js) as &$v) {
  576. if (! $paths = $this->get($v, 'js')) {
  577. continue;
  578. }
  579. foreach ((array) $paths as $path) {
  580. $html .= "<script src=\"{$path}\"></script>";
  581. }
  582. }
  583. return $html;
  584. }
  585. /**
  586. * @return string
  587. */
  588. public function headerJsToHtml()
  589. {
  590. $html = '';
  591. foreach (array_unique($this->headerJs) as &$v) {
  592. if (! $paths = $this->get($v, 'js')) {
  593. continue;
  594. }
  595. foreach ((array) $paths as $path) {
  596. $html .= "<script src=\"{$path}\"></script>";
  597. }
  598. }
  599. return $html;
  600. }
  601. /**
  602. * @return string
  603. */
  604. public function scriptToHtml()
  605. {
  606. $script = implode(';', array_unique($this->script));
  607. return <<<HTML
  608. <script data-exec-on-popstate>
  609. Dcat.ready(function () {
  610. try {
  611. {$script}
  612. } catch (e) {
  613. console.error(e)
  614. }
  615. });
  616. </script>
  617. HTML;
  618. }
  619. /**
  620. * @return string
  621. */
  622. public function styleToHtml()
  623. {
  624. $style = implode('', array_unique($this->style));
  625. return "<style>$style</style>";
  626. }
  627. }