206 lines
4.7 KiB
Vue
206 lines
4.7 KiB
Vue
<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>
|