yunsan-pc/src/views/home/components/DashboardHeader.vue

206 lines
4.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="dashboard-header">
<div class="header-title">
<img src="/imgs/title.png" alt="title" class="title-img" />
</div>
<div class="weather-info">
<div class="weather-item">
<span class="label">天气</span>
<span class="value">{{ weatherInfo.weather || '--' }}</span>
</div>
<div class="weather-item">
<span class="label">温度</span>
<span class="value">{{ weatherInfo.tem || '--' }}</span>
</div>
<div class="weather-item">
<span class="label">风速</span>
<span class="value">{{ weatherInfo.wind_speed || '--' }}m/s</span>
</div>
<div class="weather-item">
<span class="label">湿度</span>
<span class="value">{{ weatherInfo.rh || '--' }}%</span>
</div>
<div class="weather-item">
<span class="label">能见度</span>
<span class="value">{{ weatherInfo.vis || '--' }}km</span>
</div>
</div>
<div class="header-time">{{ currentTime }}</div>
<div class="notice-marquee" v-if="noticeList.length > 0">
<div class="marquee-content" :class="{ 'marquee-scroll': noticeList.length > 1 }">
<div class="notice-item" v-for="(item, index) in displayNoticeList" :key="index">
{{ item }}
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'
import server from '@/utils/service'
const currentTime = ref('')
const weatherInfo = ref({})
const noticeList = ref([])
const currentNoticeIndex = ref(0)
let noticeTimer = null
let timeTimer = null
const displayNoticeList = computed(() => {
if (noticeList.value.length === 0) return []
return [noticeList.value[currentNoticeIndex.value]]
})
const updateTime = () => {
const now = new Date()
currentTime.value = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
}).replace(/\//g, '-')
}
const fetchWeather = async () => {
try {
const response = await server.getQxjGdybHour()
if (response.data.success) {
weatherInfo.value = response.data.data.tq
}
} catch (error) {
console.error('获取天气信息失败:', error)
}
}
const fetchTaskNotice = async () => {
try {
const response = await server.getTaskNotice()
console.log('原始数据-走马灯:', response.data.data)
if (response.data.success) {
const data = response.data.data
if (data && data.content) {
const textContent = data.content.replace(/<[^>]+>/g, '')
noticeList.value = [textContent]
startNoticeScroll()
}
}
} catch (error) {
console.error('获取走马灯数据失败:', error)
}
}
const startNoticeScroll = () => {
if (noticeList.value.length <= 1) return
noticeTimer = setInterval(() => {
currentNoticeIndex.value = (currentNoticeIndex.value + 1) % noticeList.value.length
}, 3000)
}
onMounted(() => {
updateTime()
fetchWeather()
fetchTaskNotice()
timeTimer = setInterval(updateTime, 1000)
})
onUnmounted(() => {
clearInterval(timeTimer)
clearInterval(noticeTimer)
})
</script>
<style lang="scss" scoped>
.dashboard-header {
width: 4800px;
height: 106px;
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: url('/imgs/top.png') no-repeat center center;
background-size: cover;
// border-bottom: 2px solid rgba(0, 212, 255, 0.5);
.header-title {
.title-img {
max-height: 100%;
max-width: 100%;
}
}
.header-time {
position: absolute;
// right: 40px;
top: 110px;
left: 50%;
font-family: BlackOpsOne, sans-serif;
font-size: 44px;
color: #19EBFF;
text-align: center;
// 居中显示
transform: translateX(-50%);
}
.notice-marquee {
position: absolute;
right: 40px;
top: 55px;
width: 1300px;
height: 45px;
overflow: hidden;
.marquee-content {
display: flex;
flex-direction: column;
.notice-item {
font-size: 40px;
color: rgba(255, 255, 255, 0.9);
white-space: nowrap;
animation: marquee 20s linear infinite;
}
}
}
@keyframes marquee {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
.weather-info {
position: absolute;
left: 200px;
top: 70%;
transform: translateY(-50%);
display: flex;
gap: 20px;
.weather-item {
display: flex;
align-items: center;
gap: 8px;
line-height: 45px;
.label {
font-size: 36px;
color: #FFF;
}
.value {
font-size: 36px;
color: #fff;
}
}
}
}
</style>