<template>
<el-card class="card-duty">
<template #header>
<div class="card-header">
<span>重大警情</span>
</div>
</template>
<div class="card-body" v-loading="stateMajorAlert.loading" element-loading-background="rgb(0 0 0 / 34%)">
<div class="wrapper-timeline" @mouseenter="mouseenterEvent()" @mouseleave="mouseleaveEvent()" ref="refTimeline">
<ul class="timeline" v-if="stateMajorAlert.majorAlertList.length > 0">
<li class="timeline-item" v-for="(item, index) in stateMajorAlert.majorAlertList" :key="index">
<div class="timeline-item__wrapper">
<div class="timeline-itme__header">
<div class="timeline-item__level">{{ item.level }}</div>
<div class="timeline-item__type">{{ item.type }}</div>
<div class="timeline-item__address">{{ item.sfdz }}</div>
<div class="timeline-item__ajzt">{{ item.ajztmc }}</div>
</div>
<div class="timeline-item__content">
<div class="timeline-item__timestamp">发生时间:{{ item.time }}</div>
<div class="timeline-item__nr">警情内容:{{ item.nr }}</div>
<div class="timeline-item__nr" v-if="item.cjczqk">出警处置情况:{{ item.cjczqk }}</div>
<div class="timeline-item__nr" v-if="item.jqcljgsm">警情处理结果:{{ item.jqcljgsm }}</div>
</div>
</div>
</li>
</ul>
<div v-else class="empty">暂无数据</div>
</div>
</div>
</el-card>
</template>
<script setup>
import { onMounted, watch, ref, nextTick, reactive } from 'vue';
import { useMajorAlertStore } from '../../../stores/majorAlert.store';
const { stateMajorAlert, getMajorAlert } = useMajorAlertStore();
let refTimeline = ref(null);
watch(
() => stateMajorAlert.majorAlertList,
(val, oldVal) => {
initTimerInterval();
}
);
const state = reactive({
timer: null,
intervalTime: 30,
config: {
height: 0,
},
});
// 初始化定时器
function initTimerInterval() {
nextTick(() => {
clearTimerEvent();
let dom = document.querySelector('.timeline');
const outer = refTimeline.value;
// 如果内容高度小于外部高度,不滚动
if (outer.clientHeight > dom.offsetHeight) {
return;
}
state.config.height = dom.offsetHeight;
state.timer = setInterval(() => {
window.requestAnimationFrame(scroll);
}, state.intervalTime);
});
}
// 滚动
function scroll() {
const DOM = refTimeline.value;
if (DOM.scrollTop >= state.config.height - DOM.clientHeight) {
DOM.scrollTop = 0;
setTimeout(() => {
window.requestAnimationFrame(scroll);
}, state.intervalTime);
console.log(DOM.scrollTop >= state.config.height - DOM.clientHeight, 'DOM.scrollTop >= state.config.height - DOM.clientHeight');
return;
}
DOM.scrollTop++;
}
// 清除定时器
function clearTimerEvent() {
if (state.timer) {
clearInterval(state.timer);
state.timer = null;
}
}
// 鼠标移入关闭定时器
function mouseenterEvent() {
clearTimerEvent();
}
// 鼠标移出重新调用定时器
function mouseleaveEvent() {
initTimerInterval();
}
onMounted(() => {
getMajorAlert();
});
</script>
<style scoped lang="scss">
.card-duty {
width: 100%;
height: 276px;
margin-bottom: 10px;
}
.wrapper-timeline {
height: 200px;
overflow: auto;
.timeline {
list-style-type: none;
color: white;
margin: 0;
padding: 0;
padding-right: 10px;
.timeline-item {
position: relative;
display: flex;
// animation: marqueeAnim 5s linear 0s infinite;
.timeline-item__wrapper {
flex: 1;
position: relative;
margin-left: 6px;
margin-bottom: 8px;
background: rgb(10 100 195 / 20%);
padding: unset;
border: 1px solid #23568d;
border-radius: 5px;
min-height: 70px;
padding: 12px;
box-sizing: border-box;
color: #ffffff;
font-size: 14px;
.timeline-itme__header {
display: flex;
.timeline-item__level {
width: 20px;
height: 20px;
background-color: #1392ce;
border-radius: 50%;
border-right: 2px solid #082c64;
z-index: 9;
text-align: center;
line-height: 20px;
font-size: 12px;
}
.timeline-item__type {
height: 20px;
line-height: 20px;
background-color: #1392ce;
margin-left: -4px;
padding: 0 6px;
margin-right: 5px;
font-size: 12px;
}
.timeline-item__address {
flex: 1;
}
.timeline-item__ajzt {
height: 20px;
line-height: 20px;
border: 1px solid #2ad1f3;
background: linear-gradient(0deg, #037099 0%, #1aa4d5 100%);
border-radius: 2px;
padding: 0 3px;
font-size: 12px;
}
}
.timeline-item__content {
margin-top: 10px;
margin-left: 8px;
.timeline-item__timestamp {
margin-top: 5px;
color: #c3d2d2;
}
.timeline-item__nr {
margin-top: 5px;
color: #c3d2d2;
}
}
}
}
.timeline-item::after {
content: '';
position: absolute;
left: 6px;
top: 11px;
width: 2px;
height: 22px;
background: #05eaff;
}
}
}
::-webkit-scrollbar {
width: 6px;
border-radius: 3px;
}
::-webkit-scrollbar-track {
background-color: rgb(0 20 26 / 60%);
border-radius: 3px;
}
::-webkit-scrollbar-thumb {
background-color: #1b6cb5;
border-radius: 3px;
}
.empty {
font-size: 14px;
padding: 0;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
</style>