Browse Source

+++优化列表

AaronBruin 2 months ago
parent
commit
6a12e8c612

+ 1 - 0
src/assets/icons/svg/abnormal.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1747706696264" class="icon" viewBox="0 0 1059 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3486" xmlns:xlink="http://www.w3.org/1999/xlink" width="206.8359375" height="200"><path d="M901.39586188 961.04827625H155.70758656c-49.98620719 0-90.17379281-19.82896594-110.23448343-54.35586281-20.06068969-34.52689687-17.61103406-79.64689687 6.72-123.74068969L428.44689687 101.84827625C452.94344844 57.45655156 489.35724125 32 528.32 32c38.92965563 0 75.31034437 25.42344844 99.87310313 69.78206906l376.71724125 681.268965c24.29793094 44.06068969 26.81379281 89.14758656 6.72 123.67448344-20.02758656 34.52689687-60.24827625 54.28965563-110.2344825 54.28965469z m-373.07586188-862.67586281c-12.48 0-26.84689688 12.57931031-38.46620719 33.6L109.66068969 822.01379281c-11.91724125 21.64965563-14.69793094 41.14758656-7.61379282 53.42896594 7.15034438 12.18206906 25.29103406 19.2 49.7544825 19.2H905.26896594c24.49655156 0 42.60413812-6.95172375 49.72137844-19.2 7.05103406-12.28137938 4.30344844-31.74620719-7.61379282-53.39586187L566.75310312 131.97241344c-11.55310312-21.05379281-25.92-33.6-38.4-33.6zM528.55172375 674.10758656c-18.27310312 0-33.10344844-16.02206906-33.1034475-35.75172468v-321.7655175c0-19.72965562 14.83034438-35.75172375 33.1034475-35.75172376 18.24 0 33.10344844 16.02206906 33.10344844 35.75172375v321.7655175c0 19.72965562-14.86344844 35.75172375-33.10344844 35.75172469z m0 138.40551656c22.84137937 0 41.37931031-18.73655156 41.37931031-41.87586187 0-23.10620719-18.53793094-41.87586187-41.37931031-41.87586187s-41.37931031 18.76965563-41.37931031 41.87586187c0 23.13931031 18.53793094 41.87586187 41.37931031 41.87586188z" p-id="3487"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/svg/amount.svg


+ 1 - 0
src/assets/icons/svg/offline.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1747706692258" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3343" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M459.78752 825.3056c-72.096 72.096-188.99328 72.096-261.0912 0-72.09792-72.09984-72.09792-188.9952 0-261.09312l130.54656-130.53504-52.21248-52.21248L146.48384 512c-100.5216 100.52352-100.5216 265.00416 0 365.51616 101.1072 100.512 264.40896 100.512 365.51616 0l130.54656-130.53504-52.21248-52.21248-130.54656 130.53504zM877.4816 146.48192c-101.1072-100.512-264.40896-100.512-365.51616 0l-130.512 130.53504 52.21248 52.21248 130.54656-130.53504c72.096-72.09792 188.99328-72.09792 261.0912 0 72.09792 72.09792 72.09792 188.99328 0 261.0912l-130.54656 130.53504 52.21248 52.21248L877.51616 512c100.5216-100.52352 100.5216-265.00416 0-365.51616h-0.03456zM364.30784 32v150.5664H289.0304V32h75.27744zM182.56448 364.30784H32V289.0304h150.5664v75.27744z m31.18464-97.33248l-106.464-106.464 53.22624-53.23008 106.46592 106.464-53.22816 53.23008zM992 734.9696h-150.5664v-75.27744H992v75.27744z m-257.01888 106.464V992h-75.27744v-150.5664h75.27744z m75.26976-84.4128l106.464 106.46592-53.22624 53.23008-106.46592-106.46592 53.22816-53.23008z" p-id="3344"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/assets/icons/svg/onlinelink.svg


+ 1 - 0
src/assets/icons/svg/total.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1747706701618" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3774" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M968.81019259 272.18678518c0.07281778 0.80099555 0.25486222 1.56558222 0.26699852 2.37871407v471.38588445c0 1.35926518-0.23058963 2.70639408-0.38836148 4.04138667 2.2816237 13.72615111-4.35693037 27.8528-17.45199408 34.24862815L530.38648889 988.82294518c-4.41761185 2.18453333-9.23572148 3.21611852-14.06596741 3.21611852a32.33109333 32.33109333 0 0 1-13.99314963-3.21611852L81.48916148 784.24139852c-2.51221333-1.21362963-4.73315555-2.83989333-6.80846223-4.62392889-12.09988741-4.61179259-20.74093037-16.22622815-20.74093036-29.95237926V274.56549925c0-8.09490963 3.10689185-15.40096 8.04636444-21.04433777 3.16757333-5.74046815 7.90072889-10.57071408 14.04169482-13.51983407l426.42090667-204.58154666c8.8594963-4.17488592 19.13893925-4.23556741 27.92561777 0.06068147l420.85034666 204.59368296a32.04224948 32.04224948 0 0 1 18.0224 28.90865779c0.0121363 1.10440297-0.32768 2.12385185-0.43690666 3.20398221zM118.16504889 730.58683259L478.62518518 905.8592237V491.13770667L118.16504889 318.17121185v412.41562074zM543.67573333 495.91940741l-0.02427258 414.97637926 361.17617777-175.61220742V320.42856297L543.67573333 495.91940741z m-27.41589333-395.80103111L164.19802075 268.98280297l352.06181925 168.85229036 347.42575408-168.85229036-347.42575408-168.86442667z" p-id="3775"></path></svg>

+ 1 - 0
src/components/layout_/index.vue

@@ -40,6 +40,7 @@ const appStore = useAppStore()
       position: absolute;
       top: 0;
       background: rgba(#3b90d7, 0.03);
+      backdrop-filter: blur(10px);
     }
 
     &_left {

+ 1 - 1
src/views/login.vue

@@ -186,7 +186,7 @@ onMounted(() => {
 }
 
 .login-form {
-  margin-left: 10%;
+  margin-left: 15%;
   flex: none;
   border-radius: 6px;
   // background: #ffffff;

+ 1 - 1
src/views/system/broadcast/modules/deviceList.vue

@@ -6,7 +6,7 @@
         </div>
         <div class="page">
             <div class="header-view">
-                <div class="view_item" v-for="item in headerList">{{ item }}</div>
+                <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
             </div>
             <div class="warning-view">
                 <div class="scroll-view" ref="scrollViewRef" @mouseenter="onMouseenter" @mouseleave="onMouseleave">

+ 1 - 1
src/views/system/building/groupControl.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="page">
         <div class="header-view">
-            <div class="view_item" v-for="item in headerList">{{ item }}</div>
+            <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
         </div>
         <div class="warning-view">
             <div class="scroll-view" ref="scrollViewRef" @mouseenter="onMouseenter" @mouseleave="onMouseleave">

+ 1 - 1
src/views/system/building/incident.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="page">
         <div class="header-view">
-            <div class="view_item" v-for="item in headerList">{{ item }}</div>
+            <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
         </div>
         <div class="warning-view">
             <div class="scroll-view" ref="scrollViewRef" @mouseenter="onMouseenter" @mouseleave="onMouseleave">

+ 2 - 2
src/views/system/energy/index.vue

@@ -3,9 +3,9 @@
         <layout>
             <template #left>
                 <div style="height: 100%;display: flex;flex-direction: column;overflow: hidden;">
-                    <sameDay :resultData="leftData" style="flex: 1;" />
-                    <consumptionPower :resultData="leftData.OnedayPowerConsumption" style="flex: 1;" />
                     <consumptionWater :resultData="leftData.OnedayWaterConsumption" style="flex: 1;" />
+                    <consumptionPower :resultData="leftData.OnedayPowerConsumption" style="flex: 1;" />
+                    <sameDay :resultData="leftData.OnedayWaterConsumption" style="flex: 1;" />
                 </div>
             </template>
             <template #content>

+ 2 - 2
src/views/system/energy/modules/consumptionPower.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="_consume">
-        <HeadlineTag value="24小时能耗-电/kwh"></HeadlineTag>
+        <HeadlineTag value="24小时能耗-电/kWh"></HeadlineTag>
         <div class="_consume_mains">
             <div ref="chartRef" style="width: 100%; height: 100%;"></div>
         </div>
@@ -85,7 +85,7 @@ onMounted(() => {
             },
             series: [
                 {
-                    name: '24小时能耗',
+                    name: '24小时能耗',
                     // data: generateRandomData(7, 50),
                     data: [],
                     type: 'line',

+ 167 - 112
src/views/system/energy/modules/sameDay.vue

@@ -1,36 +1,16 @@
 <template>
-    <div class="_sameDay">
-        <HeadlineTag value="水、电统计"></HeadlineTag>
-        <div class="_sameDay_mains">
-            <div class="_sameDay_mains_left" id="dayWidth" :style="{ '--heightSameDay': heightDay + 'px' }">
-                <div class="_sameDay_mains_left_tuan"></div>
-                <div class="_sameDay_mains_left_conter">
-                    <div class="_sameDay_mains_left_conter_num">
-                        {{resultData.PowerConsumption}}<span style="font-size: 12px;">kwh</span>/{{resultData.WaterConsumption}}<span style="font-size: 12px;">T</span></div>
-                    <div class="_sameDay_mains_left_conter_text">今日实时电/水</div>
-                </div>
-            </div>
-            <div class="_sameDay_mains_right">
-                <div class="_sameDay_mains_right_item" v-for="item, index in sameDayList" :key="index">
-                    <div class="_sameDay_mains_right_item_tuan">
-                        <span class="_sameDay_mains_right_item_tuan_flag"
-                            :style="{ backgroundColor: item.color }"></span>
-                        <el-text class="w-150px mb-2" truncated style="color: #ccc;">
-                            {{ item.name }}
-                        </el-text>
-                    </div>
-                    <div class="_sameDay_mains_right_item__txt">
-                        {{ item.state }}
-                    </div>
-                </div>
-            </div>
+    <div class="_consume">
+        <HeadlineTag value="24小时能耗-气/kPa"></HeadlineTag>
+        <div class="_consume_mains">
+            <div ref="chartRef" style="width: 100%; height: 100%;"></div>
         </div>
     </div>
 </template>
 
 <script setup>
-import { ref } from "vue";
-import HeadlineTag from '@/components/HeadlineTag'
+import { ref, onMounted, onUnmounted } from 'vue';
+import * as echarts from 'echarts';
+import HeadlineTag from '@/components/HeadlineTag';
 const props = defineProps({
     resultData: {
         type: Object,
@@ -38,119 +18,194 @@ const props = defineProps({
     }
 })
 
-const sameDayList = ref([
-    { name: '昨日用电', state: 0, color: '#15acaa' },
-    { name: '本月用电', state: 0, color: '#15acaa' },
-    { name: '昨日用水', state: 0, color: '#FFC107' },
-    { name: '本月用水', state: 0, color: '#FFC107' },
-])
+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: '24小时气能耗',
+                    // data: generateRandomData(7, 50),
+                    data: [],
+                    type: 'line',
+                    showSymbol: false,
+                    smooth: true,
+                    color: '#49e645',
+                    lineStyle: {
+                        width: 2,
+                    },
+                    areaStyle: {
+                        color: new echarts.graphic.LinearGradient(
+                            0,
+                            0,
+                            0,
+                            1,
+                            [{
+                                offset: 0,
+                                color: 'rgba(58, 226, 56, .6)',
+                            },
+                            {
+                                offset: 0.8,
+                                color: 'rgba(58, 226, 56, .2)',
+                            },
+                            ],
+                            false
+                        ),
+                        shadowColor: 'rgba(0, 0, 0, 0.1)',
+                        shadowBlur: 10,
+                    },
+                    symbol: 'circle',
+                    symbolSize: 6,
+                }
+            ]
+        };
+
+        chart.setOption(option);
+    }
+});
 
 watch(() => props.resultData, (newVal) => {
-    if (newVal) {
-        sameDayList.value[0].state = newVal.YesterdayConsumption
-        sameDayList.value[1].state = newVal.MonthElectricityConsumption
-        sameDayList.value[2].state = newVal.YesterdayWaterConsumption
-        sameDayList.value[3].state = newVal.MonthWaterConsumption
+    if (chart) {
+        chart.setOption({
+            xAxis: {
+                data: Object.keys(newVal),
+            },
+            series: [{
+                type: 'line',
+                data: Object.entries(newVal),
+            }],
+        })
     }
 }, { deep: true, immediate: true } // 开启深度监听
 )
-const heightDay = ref(0)
-// 生命周期
-onMounted(() => {
-    var element = document.getElementById("dayWidth");
-    var width = element.offsetWidth;
-    heightDay.value = width
+onUnmounted(() => {
+    window.removeEventListener('resize', handleResize);
+    if (chart) {
+        chart.dispose();
+    }
 });
 </script>
-<style lang="scss" scoped>
-._sameDay {
+
+<style lang="scss">
+._divider {
+    height: 1px;
+    border: 1px dashed #168cdb;
+    flex: 1;
+    margin: 0 10px;
+}
+
+._consume {
     display: flex;
-    align-items: center;
     flex-direction: column;
 
     &_mains {
+        margin: 10px 30px;
         flex: 1;
-        width: calc(100% - 30px);
-        padding-left: 30px;
         display: flex;
-        align-items: center;
 
-        &_left {
-            width: 50%;
-            height: var(--heightSameDay);
-            position: relative;
-            flex-shrink: 0;
+        &_item {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 10px;
 
-            &_tuan {
-                width: 100%;
-                height: 100%;
-                background: url("@/assets/images/content_circle.png");
+            &_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;
-            }
-
-            &_conter {
-                position: absolute;
-                left: 0;
-                top: 0;
-                flex-shrink: 0;
-                width: 100%;
-                height: 100%;
-                display: flex;
-                flex-direction: column;
-                align-items: center;
-                justify-content: center;
-                color: #fff;
-
-                &_num {
-                    font-size: 18px;
-                }
-
-                &_text {
-                    font-size: 12px;
-                }
+                // animation: scanning 4s linear infinite;
+                border: 1px solid red;
             }
-        }
-
-        &_right {
-            margin-left: 10px;
-            flex: 1;
-            color: #fff;
 
-            &_item {
+            &_flag {
                 display: flex;
                 align-items: center;
-                gap: 40px;
-                padding: 5px 0;
-
-                &_tuan {
+                gap: 3px;
+
+                &_item {
+                    width: 30px;
+                    height: 30px;
+                    border: 3px dashed #168cdb;
+                    box-sizing: border-box;
+                    background: #0e6ead;
+                    color: #fff;
+                    border-radius: 50%;
                     display: flex;
                     align-items: center;
-
-                    &_flag {
-                        display: block;
-                        width: 7px;
-                        height: 7px;
-                        border-radius: 50%;
-                        margin-right: 10px;
-                    }
-                }
-
-                &__txt {
-                    font-size: 24px;
+                    justify-content: center;
+                    font-size: 14px;
                 }
             }
         }
 
-
-    }
-}
-
-@keyframes scanning {
-    to {
-        transform: rotate(1turn);
+        &_item:hover {
+            cursor: pointer;
+            background-image: linear-gradient(to right, #168cdb, transparent);
+        }
     }
 }
 </style>

+ 178 - 45
src/views/system/entranceguard/equipment.vue

@@ -3,7 +3,7 @@
         <div class="ment_equip">
             <div class="card_ment_equip">
                 <div class="box_bj_equip center_in blue_bj_equip">
-                    <svg-icon icon-class="rke" color="#fff" className="arch_icon_rke" />
+                    <svg-icon icon-class="amount" color="#fff" className="arch_icon_rke" />
                 </div>
                 <div class="equip_ment">
                     <div class="equip_ment_title">设备总数</div>
@@ -11,26 +11,43 @@
                 </div>
             </div>
             <div class="card_ment_equip">
-                <div class="box_bj_equip center_in yellow_bj_equip">
-                    <svg-icon icon-class="rke" color="#fff" className="arch_icon_rke" />
+                <div class="box_bj_equip center_in green_bj_equip">
+                    <svg-icon icon-class="onlinelink" color="#fff" className="arch_icon_rke" />
                 </div>
                 <div class="equip_ment">
                     <div class="equip_ment_title">在线</div>
-                    <span class="num_ment yellow_title">{{ resultData.Online }}</span>
+                    <span class="num_ment green_title">{{ resultData.Online }}</span>
                 </div>
             </div>
             <div class="card_ment_equip">
-                <div class="box_bj_equip center_in green_bj_equip">
-                    <svg-icon icon-class="rke" color="#fff" className="arch_icon_rke" />
+                <div class="box_bj_equip center_in yellow_bj_equip">
+                    <svg-icon icon-class="abnormal" color="#fff" className="arch_icon_rke" />
                 </div>
                 <div class="equip_ment">
                     <div class="equip_ment_title">异常</div>
-                    <span class="num_ment green_title">{{ resultData.Abnormal }}</span>
+                    <span class="num_ment yellow_title">{{ resultData.Abnormal }}</span>
                 </div>
             </div>
         </div>
         <div class="box_arch_ment">
-            <dv-scroll-board :config="config" style="width:100%;height:calc(100% - 10px);margin-top: 10px;" />
+            <div class="page">
+                <div class="header-view">
+                    <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
+                </div>
+                <div class="warning-view">
+                    <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 data" :key="index">
+                                <div class="content view_item">{{ item.AlarmContent }}</div>
+                                <div class="content view_item">{{ item.Location }}</div>
+                                <div class="time view_item" :class="item.State == 0 ? 'green_titleil' : 'red_title'">{{
+                                    item.State == 0 ? '正常' : '异常' }}</div>
+                                <div class="time view_item">{{ item.Date }}</div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
         </div>
     </div>
 </template>
@@ -42,48 +59,75 @@ const props = defineProps({
         default: {}
     }
 })
-const config = ref({
-    headerBGC: '#10285c',
-    oddRowBGC: '#10285c7f',
-    evenRowBGC: '#10285c00',
-    header: ['设备名称', '位置', '状态'],
-    data: [
-        ['行1列1', '行1列2', '行1列3'],
-        ['行2列1', '行2列2', '行2列3'],
-        ['行3列1', '行3列2', '行3列3'],
-        ['行4列1', '行4列2', '行4列3'],
-        ['行5列1', '行5列2', '行5列3'],
-        ['行6列1', '行6列2', '行6列3'],
-        ['行7列1', '行7列2', '行7列3'],
-        ['行8列1', '行8列2', '行8列3'],
-        ['行9列1', '行9列2', '行9列3'],
-        ['行10列1', '行10列2', '行10列3']
-    ]
-})
+const headerList = ref(['设备名称', '位置', '状态', '时间'])
+const data = ref([]); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
-        let arrData = []
-        let arrData1 = newVal.AlarmList
-        if (arrData1 && arrData1.length > 0) {
-            arrData1.forEach(item => {
-                let arrData2 = []
-                arrData2.push(item.AlarmContent)
-                arrData2.push(item.Location)
-                let title = ''
-                if (item.State == 0) {
-                    title = '正常'
-                } else {
-                    title = '异常'
-                }
-                arrData2.push(title)
-                arrData2.push(item.Date)
-                arrData.push(arrData2)
-            })
-        }
-        // config.value.data = arrData
+        // data.value = await getData();
+        data.value = newVal.AlarmList;
+        console.log(data.value, 333);
+
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
     }
 }, { deep: true, immediate: true } // 开启深度监听
 )
+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 scoped lang="scss">
@@ -170,4 +214,93 @@ watch(() => props.resultData, (newVal) => {
 .green_bj_equip {
     background-image: linear-gradient(25deg, rgb(87, 172, 115) 0%, rgba(0, 0, 0, 0)66%, rgb(87, 172, 115) 100%);
 }
+
+.page {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
+}
+
+.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;
+    color: #fff;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    overflow: hidden;
+    max-width: 33%;
+}
+
+.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: auto;
+    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;
+}
+
+.green_titleil {
+    color: #67C23A;
+}
+
+.red_title {
+    color: #F56C6C;
+}
 </style>

+ 2 - 2
src/views/system/entranceguard/index.vue

@@ -31,10 +31,10 @@
                             <alleyway :resultData="leftData"></alleyway>
                         </div>
                     </div>
-                    <div class="flex_spection">
+                    <div class="flex_spection" style="height: 33%;">
                         <HeadlineTag type="right" value="实时告警与通知"></HeadlineTag>
                         <div class="box_arch">
-                            <inform :resultData="leftData"></inform>
+                            <inform :resultData="leftData.devices"></inform>
                         </div>
                     </div>
                 </div>

+ 166 - 43
src/views/system/entranceguard/inform.vue

@@ -1,66 +1,189 @@
 <template>
-    <div class="person_box">
-        <dv-scroll-board :config="config" style="width:100%;height:calc(100% - 10px);margin-top: 10px;" />
+    <div class="page">
+        <div class="header-view">
+            <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
+        </div>
+        <div class="warning-view">
+            <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 data" :key="index">
+                        <div class="content view_item">{{ item.Name }}</div>
+                        <div class="time view_item">
+                            {{ item.Location }}
+                        </div>
+                        <div class="time view_item">{{ item.Event }}</div>
+                    </div>
+                </div>
+            </div>
+        </div>
     </div>
 </template>
 
 <script setup>
+import { ref, onBeforeMount, onMounted, onBeforeUnmount, nextTick } from "vue";
 const props = defineProps({
     resultData: {
-        type: Object,
-        default: {}
+        type: Array,
+        default: []
     }
 })
-const config = ref({
-    headerBGC: '#10285c',
-    oddRowBGC: '#10285c7f',
-    evenRowBGC: '#10285c00',
-    header: ['告警内容', '地点', '状态', '时间'],
-    data: [
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-        ['行1列1', '行1列2', '行1列3', '行1列3'],
-    ]
-})
+const headerList = ref(['告警内容', '地点', '时间'])
+const data = ref([]); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
-        let arrData = []
-        let arrData1 = newVal.AlarmList
-        if (arrData1 && arrData1.length > 0) {
-            arrData1.forEach(item => {
-                let arrData2 = []
-                arrData2.push(item.AlarmContent)
-                arrData2.push(item.Location)
-                let title = ''
-                if (item.State == 0) {
-                    title = '正常'
-                } else {
-                    title = '异常'
-                }
-                arrData2.push(title)
-                arrData2.push(item.Date)
-                arrData.push(arrData2)
-            })
-        }
-        config.value.data = arrData
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
     }
 }, { deep: true, immediate: true } // 开启深度监听
 )
+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 scoped lang="scss">
-.person_box {
+.page {
     width: 100%;
     height: 100%;
     display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
+}
+
+.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;
+    max-width: 33%;
+}
+
+.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;
+    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>
+</style>

+ 7 - 35
src/views/system/inspection/index.vue

@@ -8,13 +8,14 @@
             <div class="point_box" style="margin-top: 10px;margin-left: 15px;">
               <el-input v-model="input" placeholder="按巡查点名称搜索" />
             </div>
-            <div style="height: calc(100% - 160px);">
+            <point :resultData="leftData.DeviceList"></point>
+            <!-- <div style="height: calc(100% - 160px);">
               <Empty></Empty>
             </div>
             <div class="center_in">
               <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
                 layout="total, prev, pager, next" @pagination="getList" />
-            </div>
+            </div> -->
           </div>
         </div>
       </template>
@@ -51,8 +52,8 @@
           </div>
           <div class="flex_spection">
             <HeadlineTag type="right" value="实时巡检"></HeadlineTag>
-            <div class="box_arch">
-              <dv-scroll-board :config="config" style="width:100%;height:calc(100% - 10px);margin-top: 10px;" />
+            <div class="box_arch" style="height: 33%;">
+              <polling :resultData="leftData.realTime"></polling>
             </div>
           </div>
         </div>
@@ -66,6 +67,8 @@ import { getEndpoint } from "@/api/system/endpoint"
 import layout from "@/components/layout_/index.vue";
 import HeadlineTag from '@/components/HeadlineTag'
 import Empty from '@/components/Empty'
+import polling from './polling.vue'
+import point from './point.vue'
 import * as echarts from 'echarts'
 const total = ref(0);
 const queryParams = ref({
@@ -73,25 +76,6 @@ const queryParams = ref({
   pageSize: 10,
 });
 const input = ref('')
-const config = ref({
-  headerBGC: '#10285c',
-  oddRowBGC: '#10285c7f',
-  evenRowBGC: '#10285c00',
-  header: ['名称', '位置', '时间'],
-  data: [
-    ['行1列1', '行1列2', '行1列3'],
-    ['行2列1', '行2列2', '行2列3'],
-    ['行3列1', '行3列2', '行3列3'],
-    ['行4列1', '行4列2', '行4列3'],
-    ['行5列1', '行5列2', '行5列3'],
-    ['行6列1', '行6列2', '行6列3'],
-    ['行7列1', '行7列2', '行7列3'],
-    ['行8列1', '行8列2', '行8列3'],
-    ['行9列1', '行9列2', '行9列3'],
-    ['行10列1', '行10列2', '行10列3']
-  ]
-})
-
 /** 查询列表 */
 function getList() {
 };
@@ -202,18 +186,6 @@ watch(() => leftData.value, (newVal) => {
       }],
     })
   }
-  let arrData = []
-  let arrData1 = newVal.realTime
-  if (arrData1 && arrData1.length > 0) {
-    arrData1.forEach(item => {
-      let arrData2 = []
-      arrData2.push(item.Name)
-      arrData2.push(item.Location)
-      arrData2.push(item.Event)
-      arrData.push(arrData2)
-    })
-  }
-  config.value.data = arrData
 }, { deep: true, immediate: true } // 开启深度监听
 )
 // 窗口自适应

+ 229 - 0
src/views/system/inspection/point.vue

@@ -0,0 +1,229 @@
+<template>
+    <div class="_eventList">
+        <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 data" :key="index">
+                    <div class="_eventList_mains_item_text">
+                        <div :class="item.State === 0 ? '_warning' : '_success'"
+                            class="_eventList_mains_item_text_flag">
+                        </div>
+                        <el-text class="w-150px mb-2" truncated style="color: white;margin-left: 10px;">
+                            {{ item.Name }}
+                        </el-text>
+                    </div>
+                    <el-text class="w-150px mb-2" :class="item.State == 0 ? 'blue_title' : 'red_title'">
+                        {{ item.State == 0 ? '在线' : '离线' }}</el-text>
+                    <el-text class="w-150px mb-2" truncated style="color: white;">
+                        {{ item.Date }}
+                    </el-text>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted } from "vue";
+const props = defineProps({
+    resultData: {
+        type: Object,
+        default: {}
+    }
+})
+
+const data = ref(); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
+    }
+}, { deep: true, immediate: true } // 开启深度监听
+)
+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" scoped>
+._success {
+    background: #15acaa;
+}
+
+._warning {
+    background: #FFC107;
+}
+
+._eventList {
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+    height: calc(100% - 40px);
+
+    &_mains {
+        margin: 10px 30px;
+        overflow: hidden; // 隐藏溢出内容
+        // 鼠标移入时改变手势
+        cursor: pointer;
+
+        &_item {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 10px 0;
+
+            &_text {
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+
+                &_flag {
+                    width: 10px;
+                    height: 10px;
+                    border-radius: 50%;
+                    margin-left: 10px;
+                }
+
+                &_p {
+                    margin-left: 10px;
+                }
+            }
+        }
+
+        &_item:hover {
+            background-image: linear-gradient(to right, #168cdb, transparent);
+        }
+    }
+}
+
+.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;
+}
+
+.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>

+ 190 - 0
src/views/system/inspection/polling.vue

@@ -0,0 +1,190 @@
+<template>
+    <div class="page">
+        <div class="header-view">
+            <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
+        </div>
+        <div class="warning-view">
+            <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 data" :key="index">
+                        <div class="content view_item">{{ item.Name }}</div>
+                        <div class="time view_item">
+                            {{ item.Name }}
+                        </div>
+                        <div class="time view_item">{{ item.Date }}</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onBeforeMount, onMounted, onBeforeUnmount, nextTick } from "vue";
+const props = defineProps({
+    resultData: {
+        type: Array,
+        default: []
+    }
+})
+const headerList = ref(['名称', '位置', '时间'])
+const data = ref([]); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
+    }
+}, { deep: true, immediate: true } // 开启深度监听
+)
+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 scoped lang="scss">
+.page {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
+}
+
+.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;
+    max-width: 33%;
+}
+
+.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>

+ 2 - 2
src/views/system/intruderalarm/inspection.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="page">
         <div class="header-view">
-            <div class="view_item" v-for="item in headerList">{{ item }}</div>
+            <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
         </div>
         <div class="warning-view">
             <div class="scroll-view" ref="scrollViewRef" @mouseenter="onMouseenter" @mouseleave="onMouseleave">
@@ -118,7 +118,7 @@ const onMouseleave = () => {
 }
 
 .view_item {
-    // flex: 1;
+    flex: 1;
     // display: flex;
     // align-items: center;
     // justify-content: flex-start;

+ 229 - 0
src/views/system/passageway/access.vue

@@ -0,0 +1,229 @@
+<template>
+    <div class="_eventList">
+        <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 data" :key="index">
+                    <div class="_eventList_mains_item_text">
+                        <div :class="item.State === 0 ? '_warning' : '_success'"
+                            class="_eventList_mains_item_text_flag">
+                        </div>
+                        <el-text class="w-150px mb-2" truncated style="color: white;margin-left: 10px;">
+                            {{ item.Name }}
+                        </el-text>
+                    </div>
+                    <el-text class="w-150px mb-2" :class="item.State == 0 ? 'blue_title' : 'green_title'">{{ item.State
+                        == 0 ? '出' : '入' }}</el-text>
+                    <el-text class="w-150px mb-2" truncated style="color: white;">
+                        {{ item.Date }}
+                    </el-text>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted } from "vue";
+const props = defineProps({
+    resultData: {
+        type: Object,
+        default: {}
+    }
+})
+
+const data = ref(); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
+    }
+}, { deep: true, immediate: true } // 开启深度监听
+)
+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" scoped>
+._success {
+    background: #15acaa;
+}
+
+._warning {
+    background: #FFC107;
+}
+
+._eventList {
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+    height: calc(100% - 40px);
+
+    &_mains {
+        margin: 10px 30px;
+        overflow: hidden; // 隐藏溢出内容
+        // 鼠标移入时改变手势
+        cursor: pointer;
+
+        &_item {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 10px 0;
+
+            &_text {
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+
+                &_flag {
+                    width: 10px;
+                    height: 10px;
+                    border-radius: 50%;
+                    margin-left: 10px;
+                }
+
+                &_p {
+                    margin-left: 10px;
+                }
+            }
+        }
+
+        &_item:hover {
+            background-image: linear-gradient(to right, #168cdb, transparent);
+        }
+    }
+}
+
+.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;
+}
+
+.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;
+}
+
+.green_title {
+    color: #409EFF;
+}
+</style>

+ 4 - 2
src/views/system/passageway/index.vue

@@ -8,13 +8,14 @@
             <div class="point_box" style="margin-top: 10px;margin-left: 15px;">
               <el-input v-model="input" placeholder="按出入口名称搜索" />
             </div>
-            <div style="height: calc(100% - 160px);">
+            <access :resultData="leftData.DeviceList"></access>
+            <!-- <div style="height: calc(100% - 160px);">
               <Empty></Empty>
             </div>
             <div class="center_in">
               <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
                 layout="total, prev, pager, next" @pagination="getList" />
-            </div>
+            </div> -->
           </div>
         </div>
       </template>
@@ -91,6 +92,7 @@ import { getAccess } from "@/api/system/passageway"
 import layout from "@/components/layout_/index.vue";
 import HeadlineTag from '@/components/HeadlineTag'
 import Personnel from './Personnel.vue'
+import access from './access.vue'
 import Empty from '@/components/Empty'
 import * as echarts from 'echarts'
 const total = ref(0);

+ 189 - 0
src/views/system/passengerFlow/incident.vue

@@ -0,0 +1,189 @@
+<template>
+    <div class="page">
+        <div class="header-view">
+            <div class="view_item" v-for="item in headerList" :key="item">{{ item }}</div>
+        </div>
+        <div class="warning-view">
+            <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 data" :key="index">
+                        <div class="content view_item">{{ item.Name }}</div>
+                        <div class="time view_item">
+                            {{ item.Location }}
+                        </div>
+                        <div class="time view_item">{{ item.Event }}</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onBeforeMount, onMounted, onBeforeUnmount, nextTick } from "vue";
+const props = defineProps({
+    resultData: {
+        type: Array,
+        default: []
+    }
+})
+const headerList = ref(['名称', '位置', '时间'])
+const data = ref([]); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
+    }
+}, { deep: true, immediate: true } // 开启深度监听
+)
+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 scoped lang="scss">
+.page {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
+}
+
+.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;
+    max-width: 33%;
+}
+
+.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;
+    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>

+ 3 - 32
src/views/system/passengerFlow/index.vue

@@ -39,8 +39,8 @@
           </div>
           <div class="flex_spection">
             <HeadlineTag type="right" value="安全事件列表"></HeadlineTag>
-            <div class="box_arch">
-              <dv-scroll-board :config="config" style="width:100%;height:calc(100% - 10px);margin-top: 10px;" />
+            <div class="box_arch" style="height: 33%;">
+              <incident  :resultData="leftData.Event"></incident>
             </div>
           </div>
         </div>
@@ -57,27 +57,10 @@ import monitoring from './monitoring'
 import earlyWarning from './earlyWarning'
 import security from './security'
 import district from './district'
+import incident from './incident'
 import * as echarts from 'echarts'
 const chartFlow = ref(null);
 let chartInstanceWater = null;
-const config = ref({
-  headerBGC: '#10285c',
-  oddRowBGC: '#10285c7f',
-  evenRowBGC: '#10285c00',
-  header: ['名称', '位置', '时间'],
-  data: [
-    ['行1列1', '行1列2', '行1列3'],
-    ['行2列1', '行2列2', '行2列3'],
-    ['行3列1', '行3列2', '行3列3'],
-    ['行4列1', '行4列2', '行4列3'],
-    ['行5列1', '行5列2', '行5列3'],
-    ['行6列1', '行6列2', '行6列3'],
-    ['行7列1', '行7列2', '行7列3'],
-    ['行8列1', '行8列2', '行8列3'],
-    ['行9列1', '行9列2', '行9列3'],
-    ['行10列1', '行10列2', '行10列3']
-  ]
-})
 const initChart = (arrData) => {
   let list = arrData
   if (!chartInstanceWater) {
@@ -242,18 +225,6 @@ watch(() => leftData.value, (newVal) => {
     let arr = newVal.Customers
     let result = Object.entries(arr).map(([name, value]) => ({ name, value }));
     initChart(result)
-    let arrData = []
-    let arrData1 = newVal.Event
-    if (arrData1 && arrData1.length > 0) {
-      arrData1.forEach(item => {
-        let arrData2 = []
-        arrData2.push(item.Name)
-        arrData2.push(item.Location)
-        arrData2.push(item.Event)
-        arrData.push(arrData2)
-      })
-    }
-    config.value.data = arrData
   }
 }, { deep: true, immediate: true } // 开启深度监听
 )

+ 5 - 4
src/views/system/tenement/modules/running.vue

@@ -5,7 +5,7 @@
             <div class="_running_mains_left" id="videoWidth" :style="{ '--heightRun': heightVideo + 'px' }">
                 <div class="_running_mains_left_tuan"></div>
                 <div class="_running_mains_left_conter">
-                    <div class="_running_mains_left_conter_num">{{getTotal()}}</div>
+                    <div class="_running_mains_left_conter_num">{{ getTotal() }}</div>
                     <div class="_running_mains_left_conter_text">人口总数</div>
                 </div>
             </div>
@@ -20,8 +20,9 @@
                     </div>
                     <div class="_running_mains_right_item__txt">
                         <span>{{ item.state }}</span>
-                        <span :style="{ color: item.color, 'font-size': '12px', 'margin-left': '5px' }">{{ item.unit
-                            }}</span>
+                        <span :style="{ color: item.color, 'font-size': '12px', 'margin-left': '5px' }">
+                            {{ item.unit }}
+                        </span>
                     </div>
                 </div>
             </div>
@@ -53,7 +54,7 @@ watch(() => props.resultData, (newVal) => {
     }
 }, { deep: true, immediate: true } // 开启深度监听
 )
-function getTotal (){
+function getTotal() {
     let num = runningList.value[0].state + runningList.value[1].state + runningList.value[2].state + runningList.value[3].state
     return num
 }

+ 2 - 2
src/views/system/visitor/index.vue

@@ -9,7 +9,7 @@
               <div class="point_box" style="margin-top: 10px;margin-left: 15px;">
                 <el-input v-model="input" placeholder="按访客名称搜索" />
               </div>
-              <register :resultData="leftData"></register>
+              <register :resultData="leftData.VisitorRegistration"></register>
               <!-- <div style="height: calc(100%);">
                 <Empty></Empty>
               </div> -->
@@ -25,7 +25,7 @@
               <div class="point_box" style="margin-top: 10px;margin-left: 15px;">
                 <el-input v-model="input" placeholder="按访客名称搜索" />
               </div>
-              <swiping :resultData="leftData"></swiping>
+              <swiping :resultData="leftData.VisitorsSwipeCards"></swiping>
               <!-- <div style="height: calc(100%);">
                 <Empty></Empty>
               </div> -->

+ 132 - 79
src/views/system/visitor/register.vue

@@ -1,10 +1,8 @@
 <template>
     <div class="_eventList">
-        <!-- 绑定鼠标移入移出事件 -->
-        <div class="_eventList_mains" ref="mainsRef" @mouseenter="pauseCarousel" @mouseleave="resumeCarousel">
-            <!-- 复制一份数据用于无缝滚动 -->
-            <div :style="{ transform: `translateY(${scrollY}px)` }">
-                <div class="_eventList_mains_item" v-for="(item, index) in eventList" :key="index">
+        <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 data" :key="index">
                     <div class="_eventList_mains_item_text">
                         <div :class="item.Name === 0 ? '_warning' : '_success'" class="_eventList_mains_item_text_flag">
                         </div>
@@ -35,87 +33,73 @@ const props = defineProps({
         default: {}
     }
 })
-// const eventList = ref([{
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     phone: '17231123222',
-//     address: '1号门',
-//     time: '2025-04-15 10:20:00'
-// }])
-
-const eventList = ref([])
+
+const data = ref(); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
-        eventList.value = []
-        eventList.value = newVal.VisitorRegistration
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
     }
 }, { deep: true, immediate: true } // 开启深度监听
 )
-const mainsRef = ref(null)
-const scrollY = ref(0)
-let intervalId = null
-const scrollSpeed = 1 // 滚动速度
-
-const startCarousel = () => {
+onMounted(() => {
+})
+//判断列表是否有滚动条
+const hasScrollBar = () => {
+    return scrollViewRef.value.scrollHeight > scrollViewRef.value.clientHeight;
+};
+//设置自动滚动
+const autoScrolling = () => {
     intervalId = setInterval(() => {
-        const itemHeight = mainsRef.value.querySelector('._eventList_mains_item').offsetHeight
-        scrollY.value -= scrollSpeed
-        if (Math.abs(scrollY.value) >= itemHeight * eventList.value.length) {
-            scrollY.value = 0
+        if (scrollViewRef.value.scrollTop < listRef.value[0].clientHeight) {
+            scrollViewRef.value.scrollTop += isAutoScrolling ? 1 : 0;
+        } else {
+            scrollViewRef.value.scrollTop = 0;
         }
-    }, 20)
-}
-
-const pauseCarousel = () => {
-    clearInterval(intervalId)
-}
-
-const resumeCarousel = () => {
-    startCarousel()
-}
-
-onMounted(async () => {
-    await nextTick();
-    startCarousel()
-})
-
-onUnmounted(() => {
-    clearInterval(intervalId)
-})
+    }, 20);
+};
+
+onBeforeUnmount(() => {
+    //离开页面清理定时器
+    intervalId && clearInterval(intervalId);
+});
+
+//鼠标进入,停止滚动
+const onMouseenter = () => {
+    isAutoScrolling = false;
+};
+//鼠标移出,继续滚动
+const onMouseleave = () => {
+    isAutoScrolling = true;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -168,4 +152,73 @@ onUnmounted(() => {
         }
     }
 }
+.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;
+}
+
+.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;
+}
+
 </style>

+ 131 - 79
src/views/system/visitor/swiping.vue

@@ -1,10 +1,8 @@
 <template>
     <div class="_eventList">
-        <!-- 绑定鼠标移入移出事件 -->
-        <div class="_eventList_mains" ref="mainsRef" @mouseenter="pauseCarousel" @mouseleave="resumeCarousel">
-            <!-- 复制一份数据用于无缝滚动 -->
-            <div :style="{ transform: `translateY(${scrollY}px)` }">
-                <div class="_eventList_mains_item" v-for="(item, index) in eventList" :key="index">
+        <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 data" :key="index">
                     <div class="_eventList_mains_item_text">
                         <div :class="item.Name === 0 ? '_success' : '_warning'" class="_eventList_mains_item_text_flag">
                         </div>
@@ -35,87 +33,72 @@ const props = defineProps({
         default: []
     }
 })
-// const eventList = ref([{
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 0,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 1,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 1,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 0,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 0,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 1,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 1,
-//     time: '2025-04-15 10:20:00'
-// }, {
-//     name: '张史蒂',
-//     address: 'A栋1层东门',
-//     direction: 0,
-//     time: '2025-04-15 10:20:00'
-// }])
-
-const eventList = ref([])
+const data = ref(); //列表数据
+const listRef = ref(); //列表dom
+const scrollViewRef = ref(); //滚动区域dom
+const count = ref(1); //列表个数
+
+let intervalId = null;
+let isAutoScrolling = true; //是否自动滚动标识
+
+//获取列表数据
+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 (newVal) {
-        eventList.value = []
-        eventList.value = newVal.VisitorsSwipeCards
+        // data.value = await getData();
+        data.value = newVal;
+        intervalId && clearInterval(intervalId);
+        nextTick(() => {
+            //判断列表是否生成滚动条
+            count.value = hasScrollBar() ? 2 : 1;
+            //有滚动条开始自动滚动
+            if (count.value == 2) {
+                autoScrolling();
+            }
+        });
     }
 }, { deep: true, immediate: true } // 开启深度监听
 )
-const mainsRef = ref(null)
-const scrollY = ref(0)
-let intervalId = null
-const scrollSpeed = 1 // 滚动速度
-
-const startCarousel = () => {
+onMounted(() => {
+})
+//判断列表是否有滚动条
+const hasScrollBar = () => {
+    return scrollViewRef.value.scrollHeight > scrollViewRef.value.clientHeight;
+};
+//设置自动滚动
+const autoScrolling = () => {
     intervalId = setInterval(() => {
-        const itemHeight = mainsRef.value.querySelector('._eventList_mains_item').offsetHeight
-        scrollY.value -= scrollSpeed
-        if (Math.abs(scrollY.value) >= itemHeight * eventList.value.length) {
-            scrollY.value = 0
+        if (scrollViewRef.value.scrollTop < listRef.value[0].clientHeight) {
+            scrollViewRef.value.scrollTop += isAutoScrolling ? 1 : 0;
+        } else {
+            scrollViewRef.value.scrollTop = 0;
         }
-    }, 50)
-}
-
-const pauseCarousel = () => {
-    clearInterval(intervalId)
-}
-
-const resumeCarousel = () => {
-    startCarousel()
-}
-
-onMounted(async () => {
-    await nextTick();
-    startCarousel()
-})
-
-onUnmounted(() => {
-    clearInterval(intervalId)
-})
+    }, 20);
+};
+
+onBeforeUnmount(() => {
+    //离开页面清理定时器
+    intervalId && clearInterval(intervalId);
+});
+
+//鼠标进入,停止滚动
+const onMouseenter = () => {
+    isAutoScrolling = false;
+};
+//鼠标移出,继续滚动
+const onMouseleave = () => {
+    isAutoScrolling = true;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -168,4 +151,73 @@ onUnmounted(() => {
         }
     }
 }
+
+.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;
+}
+
+.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;
+}
 </style>

Some files were not shown because too many files changed in this diff