PageHeader.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <template>
  2. <header class="page-header">
  3. <div class="header-content">
  4. <div class="header-left">
  5. <div class="logo-container">
  6. <img src="/金水logo.png" alt="中国水文" class="water-logo">
  7. </div>
  8. <div class="title-container">
  9. <h1 class="site-title">东南大区成果展示平台</h1>
  10. <h2 class="site-subtitle">数字孪生技术在水文领域的应用与解决方案</h2>
  11. </div>
  12. </div>
  13. <nav class="nav-menu">
  14. <router-link to="/" class="nav-item" :class="{ active: currentRoute === '/' }">首页</router-link>
  15. <router-link to="/model-management" class="nav-item" :class="{ active: currentRoute === '/model-management' }">项目管理</router-link>
  16. <a href="#" class="nav-item">数据分析</a>
  17. <a href="#" class="nav-item">监测预警</a>
  18. <router-link to="/admin" class="nav-item">后台管理</router-link>
  19. </nav>
  20. <div class="header-right">
  21. <div class="current-time">{{ currentTime }}</div>
  22. </div>
  23. </div>
  24. </header>
  25. </template>
  26. <script setup>
  27. import { ref, onMounted, onUnmounted, watch } from 'vue'
  28. import { useRoute, useRouter } from 'vue-router'
  29. const currentRoute = ref('')
  30. const currentTime = ref('')
  31. const route = useRoute()
  32. const router = useRouter()
  33. const updateTime = () => {
  34. const now = new Date()
  35. const year = now.getFullYear()
  36. const month = String(now.getMonth() + 1).padStart(2, '0')
  37. const day = String(now.getDate()).padStart(2, '0')
  38. const hours = String(now.getHours()).padStart(2, '0')
  39. const minutes = String(now.getMinutes()).padStart(2, '0')
  40. const seconds = String(now.getSeconds()).padStart(2, '0')
  41. currentTime.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  42. }
  43. let timer = null
  44. onMounted(() => {
  45. currentRoute.value = route.path
  46. updateTime()
  47. timer = setInterval(updateTime, 1000)
  48. })
  49. // 监听路由变化
  50. watch(
  51. () => route.path,
  52. (newPath) => {
  53. currentRoute.value = newPath
  54. }
  55. )
  56. onUnmounted(() => {
  57. if (timer) {
  58. clearInterval(timer)
  59. }
  60. })
  61. </script>
  62. <style scoped>
  63. .page-header {
  64. background: linear-gradient(135deg, #326ee2 100%);
  65. color: white;
  66. padding: 0.8rem 0;
  67. box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  68. position: relative;
  69. z-index: 1000;
  70. height: 80px;
  71. }
  72. .header-content {
  73. width: 100%;
  74. height: 100%;
  75. padding: 0 1rem;
  76. display: flex;
  77. justify-content: space-between;
  78. align-items: center;
  79. max-width: 100%;
  80. margin: 0 auto;
  81. }
  82. .header-left {
  83. display: flex;
  84. align-items: center;
  85. gap: 1rem;
  86. flex: 1;
  87. }
  88. .logo-container {
  89. display: flex;
  90. align-items: center;
  91. justify-content: center;
  92. }
  93. .water-logo {
  94. width: 60px;
  95. height: 60px;
  96. object-fit: contain;
  97. filter: brightness(0) invert(1);
  98. transition: transform 0.3s ease;
  99. }
  100. .water-logo:hover {
  101. transform: scale(1.1);
  102. }
  103. .title-container {
  104. display: flex;
  105. flex-direction: column;
  106. gap: -0.8rem;
  107. }
  108. .site-title {
  109. font-size: 2rem;
  110. font-weight: 700;
  111. margin: 0;
  112. background: linear-gradient(45deg, #fff, #f0f0f0);
  113. -webkit-background-clip: text;
  114. -webkit-text-fill-color: transparent;
  115. background-clip: text;
  116. letter-spacing: 0.1rem;
  117. line-height: 1.3;
  118. }
  119. .site-subtitle {
  120. font-size: 0.875rem;
  121. font-weight: 400;
  122. opacity: 0.9;
  123. margin: 0;
  124. /* margin-top: -0.8rem; */
  125. letter-spacing: 0.05rem;
  126. line-height: 1.5;
  127. }
  128. .nav-menu {
  129. display: flex;
  130. gap: 2.5rem;
  131. justify-content: center;
  132. flex: 2;
  133. }
  134. .nav-item {
  135. color: white;
  136. text-decoration: none;
  137. font-size: 1rem;
  138. font-weight: 400;
  139. padding: 0.5rem 1rem;
  140. border-radius: 4px;
  141. transition: all 0.3s ease;
  142. opacity: 0.9;
  143. line-height: 1.6;
  144. }
  145. .nav-item:hover {
  146. opacity: 1;
  147. transform: translateY(-2px);
  148. text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  149. }
  150. .nav-item.active {
  151. opacity: 1;
  152. background: rgba(255, 255, 255, 0.2);
  153. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  154. }
  155. .header-right {
  156. display: flex;
  157. flex-direction: column;
  158. align-items: flex-end;
  159. gap: 1.5rem;
  160. flex: 1;
  161. }
  162. .current-time {
  163. font-size: 0.875rem;
  164. font-weight: 400;
  165. opacity: 0.9;
  166. font-family: 'Courier New', monospace;
  167. background: rgba(0, 0, 0, 0.1);
  168. padding: 0.3rem 0.8rem;
  169. border-radius: 4px;
  170. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  171. line-height: 1.5;
  172. }
  173. </style>