|
@@ -1,211 +1,243 @@
|
|
|
<template>
|
|
|
- <div class="_consume">
|
|
|
- <HeadlineTag type="right" value="温度变化趋势"></HeadlineTag>
|
|
|
- <div class="_consume_mains">
|
|
|
- <div ref="chartRef" style="width: 100%; height: 100%;"></div>
|
|
|
+ <div class="_eventList">
|
|
|
+ <HeadlineTag type="right" value="报警列表" style="flex-shrink: 0;"></HeadlineTag>
|
|
|
+ <div class="scroll-view" ref="scrollViewRef" @mouseenter="onMouseenter" @mouseleave="onMouseleave">
|
|
|
+ <div ref="listRef" class="list" v-for="(p, n) in count" :key="n">
|
|
|
+ <div class="item" v-for="(item, index) in dataRunning" :key="index">
|
|
|
+ <div class="_eventList_mains_item_text view_item" style="width: 45%;">
|
|
|
+ <div :class="item.Id === 'on' ? '_success' : '_warning'"
|
|
|
+ class="_eventList_mains_item_text_flag"></div>
|
|
|
+ <el-text class="w-150px mb-2" truncated style="color: white;margin-left: 10px;">
|
|
|
+ {{ item.full_region_name }}
|
|
|
+ </el-text>
|
|
|
+ </div>
|
|
|
+ <div class="view_item_trend" style="width: 20%;">{{ item.alarm_title }}</div>
|
|
|
+ <div class="view_item">{{ item.alarm_create_time }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, onUnmounted } from 'vue';
|
|
|
-import * as echarts from 'echarts';
|
|
|
-import HeadlineTag from '@/components/HeadlineTag';
|
|
|
+import { ref, onMounted, onUnmounted } from "vue";
|
|
|
+import HeadlineTag from '@/components/HeadlineTag'
|
|
|
const props = defineProps({
|
|
|
resultData: {
|
|
|
- type: Object,
|
|
|
- default: {}
|
|
|
+ type: Array,
|
|
|
+ default: []
|
|
|
}
|
|
|
})
|
|
|
+const dataRunning = ref([]); //列表数据
|
|
|
+const listRef = ref(); //列表dom
|
|
|
+const scrollViewRef = ref(); //滚动区域dom
|
|
|
+const count = ref(1); //列表个数
|
|
|
|
|
|
-const chartRef = ref(null);
|
|
|
-let chart = null;
|
|
|
-const generateRandomData = (length, max) => {
|
|
|
- const randomData = [];
|
|
|
- for (let i = 0; i < length; i++) {
|
|
|
- randomData.push(Math.floor(Math.random() * max));
|
|
|
- }
|
|
|
- return randomData;
|
|
|
-};
|
|
|
-const handleResize = () => {
|
|
|
- if (chart) {
|
|
|
- chart.resize();
|
|
|
- }
|
|
|
-};
|
|
|
-onMounted(() => {
|
|
|
- if (chartRef.value) {
|
|
|
- chart = echarts.init(chartRef.value);
|
|
|
- // 修改为 24 小时
|
|
|
- // const hours = Array.from({ length: 24 }, (_, i) => `${i}时`);
|
|
|
- const hours = []
|
|
|
- const option = {
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- // 使用 24 小时数据
|
|
|
- data: hours,
|
|
|
- axisLabel: {
|
|
|
- color: '#fff'
|
|
|
- },
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- type: 'cross',
|
|
|
- crossStyle: {
|
|
|
- color: '#999'
|
|
|
- }
|
|
|
- },
|
|
|
- textStyle: {
|
|
|
- color: '#fafafa',
|
|
|
- },
|
|
|
- borderColor: 'transparent',
|
|
|
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
|
- extraCssText: 'backdrop-filter: blur(6px);',
|
|
|
- },
|
|
|
- grid: {
|
|
|
- top: '10%',
|
|
|
- bottom: '10%',
|
|
|
- right: '0%',
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value',
|
|
|
- axisLabel: {
|
|
|
- show: true,
|
|
|
- color: '#fff'
|
|
|
- },
|
|
|
- splitLine: {
|
|
|
- show: false,
|
|
|
- lineStyle: {
|
|
|
- color: '#44585e'
|
|
|
- }
|
|
|
- },
|
|
|
- axisTick: {
|
|
|
- show: false
|
|
|
- },
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: '温度',
|
|
|
- // data: generateRandomData(7, 50),
|
|
|
- data: [],
|
|
|
- type: 'line',
|
|
|
- showSymbol: false,
|
|
|
- smooth: true,
|
|
|
- color: '#f5c400',
|
|
|
- lineStyle: {
|
|
|
- width: 2,
|
|
|
- },
|
|
|
- areaStyle: {
|
|
|
- color: new echarts.graphic.LinearGradient(
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- [{
|
|
|
- offset: 0,
|
|
|
- color: 'rgba(245, 196, 0, .6)',
|
|
|
- },
|
|
|
- {
|
|
|
- offset: 0.8,
|
|
|
- color: 'rgba(245, 196, 0, .2)',
|
|
|
- },
|
|
|
- ],
|
|
|
- false
|
|
|
- ),
|
|
|
- shadowColor: 'rgba(0, 0, 0, 0.1)',
|
|
|
- shadowBlur: 10,
|
|
|
- },
|
|
|
- symbol: 'circle',
|
|
|
- symbolSize: 6,
|
|
|
- }
|
|
|
- ]
|
|
|
- };
|
|
|
+let intervalId = null;
|
|
|
+let isAutoScrolling = true; //是否自动滚动标识
|
|
|
|
|
|
- chart.setOption(option);
|
|
|
- }
|
|
|
-});
|
|
|
+//获取列表数据
|
|
|
+const getData = () => {
|
|
|
+ //模拟接口请求列表数据
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ setTimeout(() => {
|
|
|
+ //生成10条数据
|
|
|
+ let list = new Array(30).fill().map((item, index) => index);
|
|
|
+ resolve(list);
|
|
|
+ }, 100);
|
|
|
+ });
|
|
|
+};
|
|
|
|
|
|
watch(() => props.resultData, (newVal) => {
|
|
|
- if (chart) {
|
|
|
- chart.setOption({
|
|
|
- xAxis: {
|
|
|
- data: Object.keys(newVal),
|
|
|
- },
|
|
|
- series: [{
|
|
|
- type: 'line',
|
|
|
- data: Object.entries(newVal),
|
|
|
- }],
|
|
|
- })
|
|
|
+ if (newVal) {
|
|
|
+ // data.value = await getData();
|
|
|
+ dataRunning.value = newVal;
|
|
|
+ intervalId && clearInterval(intervalId);
|
|
|
+ nextTick(() => {
|
|
|
+ //判断列表是否生成滚动条
|
|
|
+ count.value = hasScrollBar() ? 2 : 1;
|
|
|
+ //有滚动条开始自动滚动
|
|
|
+ if (count.value == 2) {
|
|
|
+ autoScrolling();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
}, { deep: true, immediate: true } // 开启深度监听
|
|
|
)
|
|
|
-onUnmounted(() => {
|
|
|
- window.removeEventListener('resize', handleResize);
|
|
|
- if (chart) {
|
|
|
- chart.dispose();
|
|
|
- }
|
|
|
+onMounted(() => {
|
|
|
+})
|
|
|
+//判断列表是否有滚动条
|
|
|
+const hasScrollBar = () => {
|
|
|
+ return scrollViewRef.value.scrollHeight > scrollViewRef.value.clientHeight;
|
|
|
+};
|
|
|
+//设置自动滚动
|
|
|
+const autoScrolling = () => {
|
|
|
+ intervalId = setInterval(() => {
|
|
|
+ if (scrollViewRef.value.scrollTop < listRef.value[0].clientHeight) {
|
|
|
+ scrollViewRef.value.scrollTop += isAutoScrolling ? 1 : 0;
|
|
|
+ } else {
|
|
|
+ scrollViewRef.value.scrollTop = 0;
|
|
|
+ }
|
|
|
+ }, 20);
|
|
|
+};
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ //离开页面清理定时器
|
|
|
+ intervalId && clearInterval(intervalId);
|
|
|
});
|
|
|
+
|
|
|
+//鼠标进入,停止滚动
|
|
|
+const onMouseenter = () => {
|
|
|
+ isAutoScrolling = false;
|
|
|
+};
|
|
|
+//鼠标移出,继续滚动
|
|
|
+const onMouseleave = () => {
|
|
|
+ isAutoScrolling = true;
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss">
|
|
|
-._divider {
|
|
|
- height: 1px;
|
|
|
- border: 1px dashed #168cdb;
|
|
|
- flex: 1;
|
|
|
- margin: 0 10px;
|
|
|
+<style lang="scss" scoped>
|
|
|
+._success {
|
|
|
+ background: #15acaa;
|
|
|
}
|
|
|
|
|
|
-._consume {
|
|
|
+._warning {
|
|
|
+ background: #FFC107;
|
|
|
+}
|
|
|
+
|
|
|
+._eventList {
|
|
|
+ overflow: hidden;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
|
|
|
&_mains {
|
|
|
margin: 10px 30px;
|
|
|
- flex: 1;
|
|
|
- display: flex;
|
|
|
+ overflow: hidden; // 隐藏溢出内容
|
|
|
+ // 鼠标移入时改变手势
|
|
|
+ cursor: pointer;
|
|
|
|
|
|
&_item {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- padding: 10px;
|
|
|
-
|
|
|
- &_name {
|
|
|
- width: 30px;
|
|
|
- height: 30px;
|
|
|
- background: url("@/assets/images/content_circle_num.png");
|
|
|
- background-size: 100% 100%;
|
|
|
- background-position: center;
|
|
|
- background-repeat: no-repeat;
|
|
|
- // animation: scanning 4s linear infinite;
|
|
|
- border: 1px solid red;
|
|
|
- }
|
|
|
+ padding: 10px 0;
|
|
|
|
|
|
- &_flag {
|
|
|
+ &_text {
|
|
|
display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- gap: 3px;
|
|
|
|
|
|
- &_item {
|
|
|
- width: 30px;
|
|
|
- height: 30px;
|
|
|
- border: 3px dashed #168cdb;
|
|
|
- box-sizing: border-box;
|
|
|
- background: #0e6ead;
|
|
|
- color: #fff;
|
|
|
+ &_flag {
|
|
|
+ width: 10px;
|
|
|
+ height: 10px;
|
|
|
border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- font-size: 14px;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &_p {
|
|
|
+ margin-left: 10px;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- &_item:hover {
|
|
|
- cursor: pointer;
|
|
|
- background-image: linear-gradient(to right, #168cdb, transparent);
|
|
|
+ &_btn {
|
|
|
+ color: red;
|
|
|
+ display: flex;
|
|
|
+ font-size: 14px;
|
|
|
+ gap: 20px;
|
|
|
+
|
|
|
+ &_item {
|
|
|
+ border-radius: 5px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+.header-view {
|
|
|
+ margin-top: 10px;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 10px 10px 10px 20px;
|
|
|
+ background-color: rgba(16, 40, 92, 1);
|
|
|
+}
|
|
|
+
|
|
|
+.view_item {
|
|
|
+ // flex: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+ width: 33%;
|
|
|
+}
|
|
|
+
|
|
|
+.view_item_trend {
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.warning-view {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100% - 51px);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.label {
|
|
|
+ color: #fff;
|
|
|
+ padding: 20px;
|
|
|
+ font-size: 22px;
|
|
|
+}
|
|
|
+
|
|
|
+.scroll-view {
|
|
|
+ flex: 1;
|
|
|
+ height: 0;
|
|
|
+ width: 100%;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.list {
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.item {
|
|
|
+ padding: 0px 10px 0px 20px;
|
|
|
+ width: 100%;
|
|
|
+ height: 50px;
|
|
|
+ min-height: 50px;
|
|
|
+ font-size: 15px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ color: #eee;
|
|
|
+}
|
|
|
+
|
|
|
+.item:nth-child(even) {
|
|
|
+ background: rgba(16, 40, 92, 0.4);
|
|
|
+}
|
|
|
+
|
|
|
+.item:hover {
|
|
|
+ cursor: pointer;
|
|
|
+ background-image: linear-gradient(to right, #168cdb, transparent);
|
|
|
+}
|
|
|
+
|
|
|
+/*隐藏滚动条
|
|
|
+ */
|
|
|
+::-webkit-scrollbar {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+.blue_title {
|
|
|
+ color: #67C23A;
|
|
|
+}
|
|
|
+
|
|
|
+.red_title {
|
|
|
+ color: #F56C6C;
|
|
|
+}
|
|
|
</style>
|