| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- <template>
- <div class="top-nav">
- <div class="nav-title">中国安全生产科学研究院实验室安全智慧化管控中心</div>
- <div class="nav-tabs">
- <div
- v-for="tab in tabs"
- :key="tab.path"
- class="nav-tab"
- :class="{ active: currentPath === tab.path }"
- @click="handleTabClick(tab)"
- >{{ tab.label }}</div>
- </div>
- <div class="nav-right">
- <span class="weather">{{ weather }}</span>
- <span class="weekday">{{ dateStr }}</span>
- <span class="clock">{{ timeStr }}</span>
- </div>
- </div>
- </template>
- <script>
- import { getWeather } from '@/api'
- export default {
- name: 'ScreenHeader',
- data() {
- return {
- tabs: [
- { label: '实验室情况', path: '/lab-status' },
- { label: '视频监控', path: '/video-monitor' }
- ],
- dateStr: '',
- timeStr: '',
- weather: '北京 · 晴 18°C'
- }
- },
- computed: {
- currentPath() {
- return this.$route.path
- }
- },
- mounted() {
- this.updateTime()
- this.timer = setInterval(this.updateTime, 1000)
- this.fetchWeather()
- },
- beforeDestroy() {
- clearInterval(this.timer)
- },
- methods: {
- updateTime() {
- const now = new Date()
- const pad = n => String(n).padStart(2, '0')
- const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
- this.dateStr = weekDays[now.getDay()]
- this.timeStr = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
- },
- handleTabClick(tab) {
- if (this.$route.path !== tab.path) {
- this.$router.push(tab.path)
- }
- },
- async fetchWeather() {
- try {
- const res = await getWeather()
- const d = res.data
- this.weather = `☁ ${d.city} · ${d.weather} ${d.temp}°C`
- } catch (e) {
- this.weather = '☁ 北京 · 晴 18°C'
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .top-nav {
- width: 100%;
- height: $header-height;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 30px;
- background: linear-gradient(180deg, rgba(10,30,70,0.95) 0%, rgba(6,20,50,0.75) 100%);
- border-bottom: 1px solid $border-color;
- position: relative;
- z-index: 100;
- // 底部静态渐变线
- &::after {
- content: '';
- position: absolute;
- bottom: 0;
- left: 10%;
- right: 10%;
- height: 1px;
- background: linear-gradient(90deg, transparent, $accent, transparent);
- }
- // 底部流光
- &::before {
- content: '';
- position: absolute;
- bottom: -1px;
- left: 0;
- width: 120px;
- height: 2px;
- background: linear-gradient(90deg, transparent, $accent, rgba(72,215,255,0.8), transparent);
- animation: navFlow 4s linear infinite;
- z-index: 101;
- }
- }
- @keyframes navFlow {
- 0% { left: -120px; }
- 100% { left: calc(100% + 120px); }
- }
- .nav-title {
- font-size: 26px;
- font-weight: 700;
- letter-spacing: 6px;
- background: linear-gradient(135deg, #fff 0%, $accent 100%);
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- text-shadow: 0 0 30px rgba(72,215,255,0.3);
- animation: titleGlow 3s ease-in-out infinite;
- }
- @keyframes titleGlow {
- 0%, 100% { filter: drop-shadow(0 0 6px rgba(72,215,255,0.2)); }
- 50% { filter: drop-shadow(0 0 16px rgba(72,215,255,0.5)); }
- }
- .nav-tabs {
- display: flex;
- gap: 4px;
- }
- .nav-tab {
- padding: 8px 28px;
- border-radius: 4px;
- cursor: pointer;
- font-size: 15px;
- letter-spacing: 2px;
- transition: all 0.3s;
- border: 1px solid transparent;
- color: $text-secondary;
- background: transparent;
- &:hover {
- color: $accent;
- border-color: $border-color;
- }
- &.active {
- background: linear-gradient(135deg, rgba(72,215,255,0.18), rgba(58,123,255,0.12));
- border-color: $accent;
- color: #fff;
- box-shadow: 0 0 16px rgba(72,215,255,0.2);
- animation: tabGlow 2.5s ease-in-out infinite;
- }
- }
- @keyframes tabGlow {
- 0%, 100% { box-shadow: 0 0 10px rgba(72,215,255,0.15); }
- 50% { box-shadow: 0 0 22px rgba(72,215,255,0.35), inset 0 0 10px rgba(72,215,255,0.08); }
- }
- .nav-right {
- display: flex;
- align-items: center;
- gap: 20px;
- font-size: 14px;
- color: $text-secondary;
- .clock {
- font-size: 22px;
- font-weight: 600;
- color: $accent;
- letter-spacing: 2px;
- animation: clockPulse 2s ease-in-out infinite;
- }
- }
- @keyframes clockPulse {
- 0%, 100% { text-shadow: 0 0 6px rgba(72,215,255,0.3); }
- 50% { text-shadow: 0 0 14px rgba(72,215,255,0.6), 0 0 28px rgba(72,215,255,0.2); }
- }
- </style>
|