base.html 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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="{{ url_for('static', filename='favicon.ico') }}">
  8. <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  9. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
  10. <style>
  11. :root {
  12. --primary-color: #4361ee;
  13. --secondary-color: #3f37c9;
  14. --accent-color: #4895ef;
  15. --light-color: #f8f9fa;
  16. --dark-color: #212529;
  17. --text-color: #333;
  18. --text-light: #6c757d;
  19. --shadow-sm: 0 2px 8px rgba(0,0,0,0.1);
  20. --shadow-md: 0 4px 12px rgba(0,0,0,0.15);
  21. --shadow-lg: 0 8px 24px rgba(0,0,0,0.2);
  22. --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  23. }
  24. body {
  25. background-color: var(--light-color);
  26. font-family: "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif;
  27. color: var(--text-color);
  28. min-height: 100vh;
  29. display: flex;
  30. flex-direction: column;
  31. }
  32. .navbar {
  33. background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
  34. box-shadow: var(--shadow-md);
  35. padding: 0.75rem 1rem;
  36. }
  37. .navbar-brand {
  38. font-weight: 600;
  39. font-size: 1.25rem;
  40. display: flex;
  41. align-items: center;
  42. }
  43. .navbar-brand::before {
  44. content: "";
  45. display: inline-block;
  46. width: 4px;
  47. height: 20px;
  48. background: white;
  49. border-radius: 2px;
  50. margin-right: 10px;
  51. }
  52. .nav-link {
  53. padding: 0.5rem 1rem;
  54. border-radius: 4px;
  55. transition: var(--transition);
  56. }
  57. .nav-link:hover {
  58. background: rgba(255,255,255,0.1);
  59. }
  60. .navbar-toggler {
  61. border: none;
  62. }
  63. .container {
  64. max-width: 1200px;
  65. flex: 1;
  66. }
  67. .alert {
  68. border-radius: 8px;
  69. box-shadow: var(--shadow-sm);
  70. }
  71. /* 用户管理特定样式 */
  72. .user-management {
  73. margin-top: 2rem;
  74. }
  75. .user-table th {
  76. background-color: var(--primary-color);
  77. color: white;
  78. }
  79. .btn-user-action {
  80. margin-right: 0.5rem;
  81. margin-bottom: 0.5rem;
  82. }
  83. .form-user {
  84. background: white;
  85. border-radius: 12px;
  86. padding: 2rem;
  87. box-shadow: var(--shadow-md);
  88. }
  89. .form-user label {
  90. font-weight: 500;
  91. }
  92. .form-user .form-check-input:checked {
  93. background-color: var(--primary-color);
  94. border-color: var(--primary-color);
  95. }
  96. /* 卡片样式 */
  97. .card {
  98. border: none;
  99. border-radius: 12px;
  100. box-shadow: var(--shadow-sm);
  101. transition: var(--transition);
  102. }
  103. .card:hover {
  104. box-shadow: var(--shadow-md);
  105. }
  106. .card-header {
  107. border-radius: 12px 12px 0 0 !important;
  108. }
  109. /* 表格样式 */
  110. .table-responsive {
  111. border-radius: 12px;
  112. overflow: hidden;
  113. }
  114. .table {
  115. margin-bottom: 0;
  116. }
  117. .table-hover tbody tr:hover {
  118. background-color: rgba(67, 97, 238, 0.05);
  119. }
  120. /* 按钮组样式 */
  121. .btn-group-sm .btn {
  122. padding: 0.25rem 0.5rem;
  123. font-size: 0.875rem;
  124. border-radius: 0.25rem;
  125. }
  126. .btn-group .btn {
  127. margin-right: 0.25rem;
  128. }
  129. .btn-group .btn:last-child {
  130. margin-right: 0;
  131. }
  132. /* 页脚样式 */
  133. .footer {
  134. background-color: white;
  135. box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
  136. }
  137. .footer-line {
  138. width: 60px;
  139. height: 2px;
  140. background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
  141. margin: 0 auto;
  142. opacity: 0.5;
  143. }
  144. @media (max-width: 768px) {
  145. .navbar-collapse {
  146. padding: 1rem 0;
  147. }
  148. .nav-link {
  149. margin: 0.25rem 0;
  150. }
  151. .btn-user-action {
  152. width: 100%;
  153. margin-right: 0;
  154. }
  155. .table-responsive {
  156. border-radius: 0;
  157. }
  158. }
  159. </style>
  160. {% block styles %}{% endblock %}
  161. </head>
  162. <body>
  163. <nav class="navbar navbar-expand-lg navbar-dark">
  164. <div class="container">
  165. <a class="navbar-brand" href="{{ url_for('index') }}">逐鹿导航</a>
  166. <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
  167. <span class="navbar-toggler-icon"></span>
  168. </button>
  169. <div class="collapse navbar-collapse" id="navbarNav">
  170. <ul class="navbar-nav me-auto">
  171. {% if current_user.is_authenticated %}
  172. <li class="nav-item">
  173. <a class="nav-link" href="{{ url_for('dashboard') }}">
  174. <i class="bi bi-collection me-1"></i>我的导航
  175. </a>
  176. </li>
  177. {% if current_user.is_admin %}
  178. <li class="nav-item">
  179. <a class="nav-link" href="{{ url_for('admin') }}">
  180. <i class="bi bi-gear me-1"></i>管理后台
  181. </a>
  182. </li>
  183. {% endif %}
  184. {% endif %}
  185. </ul>
  186. <ul class="navbar-nav">
  187. {% if current_user.is_authenticated %}
  188. <li class="nav-item dropdown">
  189. <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown">
  190. <i class="bi bi-person-circle me-1"></i>{{ current_user.username }}
  191. </a>
  192. <ul class="dropdown-menu dropdown-menu-end">
  193. <li><a class="dropdown-item" href="{{ url_for('dashboard') }}">
  194. <i class="bi bi-person me-2"></i>我的导航
  195. </a></li>
  196. {% if current_user.is_admin %}
  197. <li><a class="dropdown-item" href="{{ url_for('admin') }}">
  198. <i class="bi bi-gear me-2"></i>管理后台
  199. </a></li>
  200. {% endif %}
  201. <li><hr class="dropdown-divider"></li>
  202. <li><a class="dropdown-item text-danger" href="{{ url_for('logout') }}">
  203. <i class="bi bi-box-arrow-right me-2"></i>退出登录
  204. </a></li>
  205. </ul>
  206. </li>
  207. {% else %}
  208. <li class="nav-item">
  209. <a class="nav-link" href="{{ url_for('login') }}">
  210. <i class="bi bi-box-arrow-in-right me-1"></i>登录
  211. </a>
  212. </li>
  213. <li class="nav-item">
  214. <a class="nav-link" href="{{ url_for('register') }}">
  215. <i class="bi bi-person-plus me-1"></i>注册
  216. </a>
  217. </li>
  218. {% endif %}
  219. </ul>
  220. </div>
  221. </div>
  222. </nav>
  223. <div class="container mt-4">
  224. {% with messages = get_flashed_messages(with_categories=true) %}
  225. {% if messages %}
  226. {% for category, message in messages %}
  227. <div class="alert alert-{{ 'danger' if category == 'error' else category }} alert-dismissible fade show" role="alert">
  228. <i class="bi bi-{{ 'exclamation-triangle-fill' if category == 'error' else 'info-circle-fill' }} me-2"></i>
  229. {{ message }}
  230. <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
  231. </div>
  232. {% endfor %}
  233. {% endif %}
  234. {% endwith %}
  235. {% block content %}{% endblock %}
  236. </div>
  237. <footer class="footer py-4 mt-4">
  238. <div class="container text-center text-muted small">
  239. <div class="footer-line mb-3"></div>
  240. <p>© 2025 逐鹿导航 · Designed by 易安</p>
  241. </div>
  242. </footer>
  243. <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
  244. <script src="{{ url_for('static', filename='js/main.js') }}"></script>
  245. {% block scripts %}{% endblock %}
  246. </body>
  247. </html>