<template>
|
<div class="messagePrompt" v-if="allUnreadItems.length > 0 && showTip">
|
<div
|
class="messageList"
|
:style="{ transform: `translateY(-${currentIndex * 3.8}rem)`, transition: 'transform 0.5s ease' }"
|
>
|
<div class="messageItem" v-for="(item, index) in allUnreadItems" :key="index">
|
<div class="messageleft">
|
<img src="@/assets/images/warning.png" alt="" />
|
<span class="dots"></span>
|
<div class="infodetail">
|
<span>{{ item.name }}</span>
|
<span>{{ item.date }}</span>
|
</div>
|
</div>
|
<div class="messagebtn" @click="stopmessagetip">不再提醒</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { useStore } from 'vuex'
|
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
import notificationSound from '@/assets/audio/audio_8652e075da.mp3'
|
import { getOrderOrEventApi } from '@/api/home'
|
|
const store = useStore()
|
const consoleShow = computed(() => store?.state?.task?.consoleShow)
|
let audio = new Audio()
|
audio.src = notificationSound
|
audio.volume = 1
|
audio.loop = true
|
audio?.pause()
|
const userInfo = computed(() => store.getters.userInfo)
|
const todosData = computed(() => store.state.common?.todosData)
|
const dateRange = computed(() => store.state.home.eventTimeRang)
|
const showTip = ref(true)
|
const currentIndex = ref(0)
|
let carouselTimer = null
|
const hasUnread = computed(() => todosData.value?.some(i => !i?.is_read))
|
const allUnreadItems = computed(() => todosData.value?.filter(i => !i.is_read) || [])
|
const newunread = ref(null)
|
let refreshInterval = null // 自动刷新待办事项(每5秒)
|
let pauseTimeout = null // 1分钟后暂停播放
|
let cfTimeout = null //5分钟重复一次
|
let retryTimeout = null // 1分钟后重试弹框
|
const yzxs = ref(true) //一值提醒
|
const todosParams = {
|
type: 1,
|
area_code: userInfo.value.detail.areaCode,
|
start_time: dateRange.value[0],
|
end_time: dateRange.value[1],
|
}
|
|
// 轮播
|
const startCarousel = () => {
|
if (carouselTimer) clearInterval(carouselTimer)
|
if (allUnreadItems.value.length <= 1) return
|
|
carouselTimer = setInterval(() => {
|
currentIndex.value = (currentIndex.value + 1) % allUnreadItems.value.length
|
}, 3000)
|
}
|
// 停止消息提示
|
const stopmessagetip = () => {
|
showTip.value = false
|
yzxs.value = false // 设置手动关闭标志
|
clearInterval(carouselTimer)
|
audio?.pause()
|
}
|
watch(allUnreadItems, val => {
|
if (!showTip.value) return
|
|
if (val && !consoleShow.value && yzxs.value) {
|
startCarousel()
|
audio?.play()
|
} else {
|
audio?.pause()
|
clearInterval(carouselTimer)
|
}
|
})
|
|
// 获取待办事项
|
const getListMatter = async () => {
|
const res = await getOrderOrEventApi(todosParams)
|
if (!res.data.data || res.data.data?.length === 0) {
|
store.commit('setTodosData', [])
|
return
|
}
|
const oldList = (todosData.value || []).filter(i => !i.is_read).map(i => i.id)
|
const newList = (res.data.data || []).filter(i => !i.is_read).map(i => i.id)
|
const hasNewItem = newList.filter(item => !oldList.includes(item))
|
newunread.value = hasNewItem
|
if (hasNewItem.length > 0) {
|
showTip.value = true
|
audio?.play()
|
startCarousel()
|
}
|
store.commit('setTodosData', res.data.data)
|
}
|
const startAutoRefresh = () => {
|
refreshInterval = setInterval(getListMatter, 5000)
|
}
|
|
watch(
|
dateRange,
|
newVal => {
|
if (newVal) {
|
todosParams.start_time = newVal[0]
|
todosParams.end_time = newVal[1]
|
getListMatter()
|
}
|
},
|
{ deep: true }
|
)
|
|
onMounted(() => {
|
getListMatter()
|
startAutoRefresh()
|
startCarousel()
|
})
|
|
onBeforeUnmount(() => {
|
refreshInterval && clearInterval(refreshInterval)
|
pauseTimeout && clearTimeout(pauseTimeout)
|
cfTimeout && clearInterval(cfTimeout)
|
retryTimeout && clearTimeout(retryTimeout)
|
clearInterval(carouselTimer)
|
audio?.pause()
|
audio = null
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.messagePrompt {
|
position: absolute;
|
top: 105px;
|
left: 50%;
|
transform: translateX(-50%);
|
color: #ffffff;
|
border-radius: 4px;
|
font-size: 14px;
|
width: 633px;
|
height: 38px;
|
overflow: hidden;
|
background: url('@/assets/images/warninfobg.png') no-repeat center;
|
background-size: 100% 100%;
|
|
.messageList {
|
height: 38px;
|
width: 100%;
|
}
|
|
.messageItem {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
width: 633px;
|
height: 38px;
|
.messageleft {
|
display: flex;
|
align-items: center;
|
margin-left: 85px;
|
img {
|
width: 32px;
|
height: 32px;
|
}
|
.dots {
|
display: inline-block;
|
width: 6px;
|
height: 6px;
|
background: #ff5741;
|
border-radius: 50%;
|
}
|
.infodetail {
|
display: flex;
|
width: 332px;
|
justify-content: space-between;
|
margin-left: 7px;
|
}
|
}
|
.messagebtn {
|
cursor: pointer;
|
margin-right: 57px;
|
}
|
}
|
}
|
</style>
|