Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 

130 řádky
4.6 KiB

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>{% block title %}管理后台{% endblock %} - 肠愈同行管理系统</title>
  7. <link rel="icon" href="/static/favicon.ico" type="image/x-icon">
  8. <!-- Element Plus CSS -->
  9. <link rel="stylesheet" href="/static/css/admin.css?v={{version}}">
  10. <!-- Tailwind CSS 4 -->
  11. <script src="/static/lib/tailwindcss/browser.js"></script>
  12. <link rel="stylesheet" href="/static/lib/element-plus/index.css?v={{version}}">
  13. <!-- Element Plus 主色调覆盖 -->
  14. <style>
  15. :root {
  16. --el-color-primary: #ff7800;
  17. --el-color-primary-light-1: #ff861a;
  18. --el-color-primary-light-2: #ff9333;
  19. --el-color-primary-light-3: #ffa14d;
  20. --el-color-primary-light-4: #ffae66;
  21. --el-color-primary-light-5: #ffbc80;
  22. --el-color-primary-light-6: #ffc999;
  23. --el-color-primary-light-7: #ffd7b3;
  24. --el-color-primary-light-8: #ffe4cc;
  25. --el-color-primary-light-9: #fff2e6;
  26. --el-color-primary-dark-2: #cc6000;
  27. }
  28. /* 修复 Tailwind CSS 4 与 Element Plus 表格冲突 */
  29. .el-table table { display: table; }
  30. .el-table thead { display: table-header-group; }
  31. .el-table tbody { display: table-row-group; }
  32. .el-table tr { display: table-row; }
  33. .el-table th, .el-table td { display: table-cell; }
  34. /* 防止 Vue 挂载前闪烁未编译模板 */
  35. [v-cloak] { display: none !important; }
  36. /* 侧边栏栏目菜单:防止加载闪烁 */
  37. #columnMenuGroup:empty { min-height: 200px; }
  38. /* 防止残留遮罩层阻止页面交互 */
  39. body > .el-overlay:not(:has(.el-dialog)):not(:has(.el-message-box)):not(:has(.el-drawer)) {
  40. display: none !important;
  41. }
  42. </style>
  43. {% block css %}{% endblock %}
  44. </head>
  45. <body data-page="{{ currentPage }}">
  46. <div class="admin-layout" id="app">
  47. {% include "./common/_sidebar.html" %}
  48. <div class="main-area">
  49. {% include "./common/_header.html" %}
  50. <div class="page-content">
  51. {% block content %}{% endblock %}
  52. <div id="watermarkWrap" style="position:fixed;top:0;left:210px;right:0;bottom:0;pointer-events:none;z-index:999;overflow:hidden;"></div>
  53. </div>
  54. </div>
  55. </div>
  56. <!-- Vue 3.5 -->
  57. <script src="/static/lib/vue/vue.global.prod.js"></script>
  58. <!-- Element Plus -->
  59. <script src="/static/lib/element-plus/index.full.min.js"></script>
  60. <!-- Element Plus Icons -->
  61. <script src="/static/lib/element-plus-icons/index.js"></script>
  62. <!-- Element Plus 中文语言包 -->
  63. <script src="/static/lib/element-plus/locale/zh-cn.min.js"></script>
  64. <!-- 水印 -->
  65. <script>
  66. (function() {
  67. var wmEl = document.getElementById('watermarkWrap');
  68. if (!wmEl) return;
  69. wmEl.innerHTML = '<el-watermark :content="text" :font="font" style="width:100%;height:100%;"></el-watermark>';
  70. var wApp = Vue.createApp({
  71. delimiters: ['[[', ']]'],
  72. setup: function() {
  73. return {
  74. text: '{{ adminUser.nickname or adminUser.username or "" }}',
  75. font: { fontSize: 14, color: 'rgba(0,0,0,0.08)' }
  76. };
  77. }
  78. });
  79. wApp.use(ElementPlus);
  80. wApp.mount(wmEl);
  81. })();
  82. </script>
  83. {% block js %}{% endblock %}
  84. <script>
  85. // 菜单展开/收起
  86. document.querySelectorAll('.menu-parent > .menu-item').forEach(item => {
  87. item.addEventListener('click', () => {
  88. item.parentElement.classList.toggle('open');
  89. });
  90. });
  91. // 清理残留的 Element Plus 遮罩层
  92. (function cleanOverlays() {
  93. function removeStaleOverlays() {
  94. document.querySelectorAll('body > .el-overlay').forEach(function(el) {
  95. // 只移除空的 overlay(没有弹窗内容的)
  96. if (!el.querySelector('.el-dialog, .el-message-box, .el-drawer')) {
  97. el.remove();
  98. }
  99. });
  100. }
  101. removeStaleOverlays();
  102. // 延迟再清理一次(等待异步脚本执行完)
  103. setTimeout(removeStaleOverlays, 100);
  104. setTimeout(removeStaleOverlays, 500);
  105. // 监听 body 子节点变化,及时清理新插入的空 overlay
  106. if (window.MutationObserver) {
  107. new MutationObserver(function(mutations) {
  108. mutations.forEach(function(m) {
  109. m.addedNodes.forEach(function(node) {
  110. if (node.nodeType === 1 && node.classList && node.classList.contains('el-overlay') &&
  111. !node.querySelector('.el-dialog, .el-message-box, .el-drawer')) {
  112. // 延迟检查,给 Vue 渲染内容的时间
  113. setTimeout(function() {
  114. if (!node.querySelector('.el-dialog, .el-message-box, .el-drawer')) {
  115. node.remove();
  116. }
  117. }, 50);
  118. }
  119. });
  120. });
  121. }).observe(document.body, { childList: true });
  122. }
  123. })();
  124. </script>
  125. </body>
  126. </html>