|
|
@@ -38,7 +38,7 @@
|
|
|
<div class="stat-value">{{ formatCount(statistics.deviceTotal) }}</div>
|
|
|
<div class="stat-sub">
|
|
|
<span>离线 <b class="text-primary">{{ formatCount(statistics.offlineDeviceCount) }}</b></span>
|
|
|
- <span>预警 <b class="text-orange">{{ formatCount(statistics.alarmingDeviceCount) }}</b></span>
|
|
|
+ <span>报警 <b class="text-orange">{{ formatCount(statistics.alarmingDeviceCount) }}</b></span>
|
|
|
</div>
|
|
|
</article>
|
|
|
<article class="stat-card">
|
|
|
@@ -112,6 +112,7 @@ const currentDate = ref('')
|
|
|
const noticeScrollRef = ref()
|
|
|
const noticeTrackRef = ref()
|
|
|
const noticePaused = ref(false)
|
|
|
+const shouldScrollNotices = ref(false)
|
|
|
const noticeDialogVisible = ref(false)
|
|
|
const noticeDetailLoading = ref(false)
|
|
|
const noticeDetail = ref({})
|
|
|
@@ -122,7 +123,7 @@ let lastNoticeFrame = 0
|
|
|
let noticeRequestId = 0
|
|
|
|
|
|
const displayName = computed(() => userStore.nickName || userStore.name || '用户')
|
|
|
-const scrollingNotices = computed(() => notices.value.length ? notices.value.concat(notices.value) : [])
|
|
|
+const scrollingNotices = computed(() => shouldScrollNotices.value ? notices.value.concat(notices.value) : notices.value)
|
|
|
const warningTrend = computed(() => buildTrend(statistics.value.todayWarningCount, statistics.value.yesterdayWarningCount))
|
|
|
const alarmTrend = computed(() => buildTrend(statistics.value.todayAlarmCount, statistics.value.yesterdayAlarmCount))
|
|
|
const modules = computed(() => {
|
|
|
@@ -221,7 +222,7 @@ function noticeDotClass(index) {
|
|
|
}
|
|
|
|
|
|
function animateNotices(timestamp) {
|
|
|
- if (!noticePaused.value && notices.value.length && timestamp - lastNoticeFrame >= 30) {
|
|
|
+ if (!noticePaused.value && shouldScrollNotices.value && timestamp - lastNoticeFrame >= 30) {
|
|
|
const scroll = noticeScrollRef.value
|
|
|
const track = noticeTrackRef.value
|
|
|
if (scroll && track) {
|
|
|
@@ -241,17 +242,47 @@ function animateNotices(timestamp) {
|
|
|
noticeAnimationFrame = requestAnimationFrame(animateNotices)
|
|
|
}
|
|
|
|
|
|
+async function updateNoticeScrollState() {
|
|
|
+ await nextTick()
|
|
|
+ const scroll = noticeScrollRef.value
|
|
|
+ const track = noticeTrackRef.value
|
|
|
+ if (!scroll || !track || !notices.value.length) {
|
|
|
+ shouldScrollNotices.value = false
|
|
|
+ noticeOffset = 0
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const duplicateStart = track.querySelector('[data-copy-start="true"]')
|
|
|
+ const firstNotice = track.firstElementChild
|
|
|
+ const lastOriginalNotice = track.children[notices.value.length - 1]
|
|
|
+ const contentWidth = duplicateStart && firstNotice
|
|
|
+ ? lastOriginalNotice.getBoundingClientRect().right - firstNotice.getBoundingClientRect().left
|
|
|
+ : track.scrollWidth
|
|
|
+ const needsScroll = contentWidth > scroll.clientWidth + 1
|
|
|
+ shouldScrollNotices.value = needsScroll
|
|
|
+ if (!needsScroll) {
|
|
|
+ noticeOffset = 0
|
|
|
+ scroll.scrollLeft = 0
|
|
|
+ } else {
|
|
|
+ await nextTick()
|
|
|
+ if (noticeScrollRef.value) noticeScrollRef.value.scrollLeft = Math.floor(noticeOffset)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
async function loadPortalData() {
|
|
|
const [statisticsResult, noticesResult] = await Promise.allSettled([getPortalStatistics(), getPortalNotices()])
|
|
|
if (statisticsResult.status === 'fulfilled' && statisticsResult.value.data) statistics.value = statisticsResult.value.data
|
|
|
if (noticesResult.status === 'fulfilled') {
|
|
|
notices.value = Array.isArray(noticesResult.value.data) ? noticesResult.value.data : []
|
|
|
- await nextTick()
|
|
|
noticeOffset = 0
|
|
|
- if (noticeScrollRef.value) noticeScrollRef.value.scrollLeft = 0
|
|
|
+ await updateNoticeScrollState()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function handleNoticeResize() {
|
|
|
+ updateNoticeScrollState()
|
|
|
+}
|
|
|
+
|
|
|
async function openNotice(noticeId) {
|
|
|
const requestId = ++noticeRequestId
|
|
|
noticeDialogVisible.value = true
|
|
|
@@ -289,12 +320,14 @@ function logout() {
|
|
|
onMounted(() => {
|
|
|
updateCurrentDate()
|
|
|
dateTimer = window.setInterval(updateCurrentDate, 60000)
|
|
|
+ window.addEventListener('resize', handleNoticeResize)
|
|
|
noticeAnimationFrame = requestAnimationFrame(animateNotices)
|
|
|
loadPortalData()
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
window.clearInterval(dateTimer)
|
|
|
+ window.removeEventListener('resize', handleNoticeResize)
|
|
|
cancelAnimationFrame(noticeAnimationFrame)
|
|
|
})
|
|
|
</script>
|