|
@@ -4,31 +4,28 @@
|
|
|
<div class="point_box" style="margin-top: 10px;">
|
|
|
<el-input v-model="value" placeholder="按设备名称搜索" />
|
|
|
</div>
|
|
|
- <div class="_deviceList_mains" ref="mainsRef" @mouseenter="pauseCarousel" @mouseleave="resumeCarousel">
|
|
|
- <div :style="{ transform: `translateY(${scrollY}px)` }">
|
|
|
- <div class="_deviceList_mains_item" v-for="(item, index) in eventList" :key="index">
|
|
|
- <el-text class="w-150px mb-2 " truncated
|
|
|
- style="color: white;flex: .4;display: flex;align-items: center;">
|
|
|
- <el-icon color="#168cdb" size="16">
|
|
|
- <el-icon>
|
|
|
- <Headset />
|
|
|
- </el-icon>
|
|
|
- </el-icon>
|
|
|
- <span class="_table_row1">{{ item.DeviceName }}</span>
|
|
|
- </el-text>
|
|
|
- <el-text class="w-150px mb-2" :class="item.UseState == 1 ? '_success' : ''" truncated
|
|
|
- style="color: #fff;flex: .2;">
|
|
|
- {{ getUseState(item.UseState) }}
|
|
|
- </el-text>
|
|
|
- <el-text class="w-150px mb-2" :class="item.OnlineState == 1 ? '' : '_warning'" truncated
|
|
|
- style="flex: .2;color: #fff;">
|
|
|
- {{ getOnlineState(item.OnlineState) }}
|
|
|
- </el-text>
|
|
|
- <el-icon color="#168cdb" style="flex: .2;">
|
|
|
- <el-icon>
|
|
|
- <Aim />
|
|
|
- </el-icon>
|
|
|
- </el-icon>
|
|
|
+ <div class="page">
|
|
|
+ <div class="header-view">
|
|
|
+ <div class="view_item" v-for="item in headerList">{{ 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">
|
|
|
+ <el-icon color="#168cdb" size="16">
|
|
|
+ <Headset />
|
|
|
+ </el-icon>
|
|
|
+ {{ item.DeviceName }}
|
|
|
+ </div>
|
|
|
+ <!-- 运行/停止/故障 -->
|
|
|
+ <div class="time view_item" :class="item.OnlineState == 0 ? 'yellow_title' : 'blue_title'">
|
|
|
+ {{ item.UseState == 0 ? '空闲' : '播放' }}
|
|
|
+ </div>
|
|
|
+ <div class="time view_item" :class="item.OnlineState == 0 ? 'blue_title' : 'red_title'">{{
|
|
|
+ item.OnlineState == 0 ? '离线' : '在线' }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -36,7 +33,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, onUnmounted } from "vue";
|
|
|
+import { ref, onBeforeMount, onMounted, onBeforeUnmount, nextTick } from "vue";
|
|
|
import HeadlineTag from '@/components/HeadlineTag'
|
|
|
import { Headset, Aim } from '@element-plus/icons-vue'
|
|
|
const props = defineProps({
|
|
@@ -45,148 +42,183 @@ const props = defineProps({
|
|
|
default: []
|
|
|
}
|
|
|
})
|
|
|
-const value = ref('')
|
|
|
-// const eventList = ref([
|
|
|
-// { name: '终端1', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端2', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端3', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端4', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端5', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端6', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端7', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端8', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端9', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端10', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端11', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端12', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端13', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端14', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端15', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端16', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端17', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端18', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端19', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端20', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端21', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端22', state: '空闲', flag: '离线' },
|
|
|
-// { name: '终端23', state: '播放', flag: '在线' },
|
|
|
-// { name: '终端24', state: '空闲', flag: '离线' }
|
|
|
-// ])
|
|
|
-const eventList = ref([])
|
|
|
-function getUseState(value) {
|
|
|
- let title = ''
|
|
|
- if (value == 0) {
|
|
|
- title = '空闲'
|
|
|
- } else {
|
|
|
- title = '播放'
|
|
|
- }
|
|
|
- return title
|
|
|
-}
|
|
|
-function getOnlineState(value) {
|
|
|
- let title = ''
|
|
|
- if (value == 0) {
|
|
|
- title = '离线'
|
|
|
- } else {
|
|
|
- title = '在线'
|
|
|
- }
|
|
|
- return title
|
|
|
-}
|
|
|
-const mainsRef = ref(null)
|
|
|
-const scrollY = ref(0)
|
|
|
-let intervalId = null
|
|
|
-const scrollSpeed = 0.5 // 滚动速度
|
|
|
-
|
|
|
-const startCarousel = () => {
|
|
|
- intervalId = setInterval(() => {
|
|
|
- const itemHeight = mainsRef.value?.querySelector('._deviceList_mains_item')?.offsetHeight;
|
|
|
- if (!itemHeight) return;
|
|
|
- scrollY.value -= scrollSpeed;
|
|
|
- // 检查第一个元素是否完全离开视口
|
|
|
- if (Math.abs(scrollY.value) >= itemHeight) {
|
|
|
- // 将第一个元素移到列表末尾
|
|
|
- const firstItem = eventList.value.shift();
|
|
|
- if (firstItem) {
|
|
|
- eventList.value.push(firstItem);
|
|
|
- }
|
|
|
- // 调整滚动位置
|
|
|
- scrollY.value += itemHeight;
|
|
|
- }
|
|
|
- }, 20);
|
|
|
-};
|
|
|
-const pauseCarousel = () => {
|
|
|
- clearInterval(intervalId);
|
|
|
-};
|
|
|
-const resumeCarousel = () => {
|
|
|
- startCarousel();
|
|
|
+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) {
|
|
|
- eventList.value = 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(() => {
|
|
|
- startCarousel();
|
|
|
-});
|
|
|
+})
|
|
|
+//判断列表是否有滚动条
|
|
|
+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);
|
|
|
+};
|
|
|
|
|
|
-onUnmounted(() => {
|
|
|
- clearInterval(intervalId);
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ //离开页面清理定时器
|
|
|
+ intervalId && clearInterval(intervalId);
|
|
|
});
|
|
|
+
|
|
|
+//鼠标进入,停止滚动
|
|
|
+const onMouseenter = () => {
|
|
|
+ isAutoScrolling = false;
|
|
|
+};
|
|
|
+//鼠标移出,继续滚动
|
|
|
+const onMouseleave = () => {
|
|
|
+ isAutoScrolling = true;
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-._success {
|
|
|
- color: #168cdb !important;
|
|
|
+._deviceList {
|
|
|
+ overflow: hidden;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
}
|
|
|
|
|
|
-._warning {
|
|
|
- color: rgb(244, 67, 54) !important;
|
|
|
+.page {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
-._table_row1 {
|
|
|
- margin-left: 10px;
|
|
|
- text-emphasis: none;
|
|
|
- /* 新增样式让文本超出显示省略号 */
|
|
|
- white-space: nowrap;
|
|
|
- overflow: hidden;
|
|
|
- text-overflow: ellipsis;
|
|
|
+.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);
|
|
|
}
|
|
|
|
|
|
-._deviceList {
|
|
|
- overflow: hidden;
|
|
|
+.view_item {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ color: #ffffff;
|
|
|
+}
|
|
|
+
|
|
|
+.view_item:first-child {
|
|
|
+ flex: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.warning-view {
|
|
|
+ width: 100%;
|
|
|
+ height: calc(100% - 51px);
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
+}
|
|
|
|
|
|
- &_mains {
|
|
|
- margin: 10px 30px;
|
|
|
- overflow: hidden; // 隐藏溢出内容
|
|
|
- cursor: pointer;
|
|
|
- font-size: 12px;
|
|
|
+.label {
|
|
|
+ color: #fff;
|
|
|
+ padding: 20px;
|
|
|
+ font-size: 22px;
|
|
|
+}
|
|
|
|
|
|
- &_item {
|
|
|
- display: flex;
|
|
|
- justify-content: space-between;
|
|
|
- padding: 10px;
|
|
|
- }
|
|
|
+.scroll-view {
|
|
|
+ flex: 1;
|
|
|
+ height: 0;
|
|
|
+ width: 100%;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
|
|
|
- &_item:nth-child(even) {
|
|
|
- background: rgba($color: #168cdb, $alpha: .05);
|
|
|
- }
|
|
|
+.list {
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
|
|
|
- &_item:hover {
|
|
|
- cursor: pointer;
|
|
|
- background-image: linear-gradient(to right, #168cdb, transparent);
|
|
|
- }
|
|
|
- }
|
|
|
+.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;
|
|
|
+}
|
|
|
+
|
|
|
+.yellow_title {
|
|
|
+ color: #E6A23C;
|
|
|
}
|
|
|
</style>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.point_box {
|
|
|
- margin: 10px 30px;
|
|
|
-}
|
|
|
+// .point_box {
|
|
|
+// margin: 10px 30px;
|
|
|
+// }
|
|
|
|
|
|
.point_box :deep(.el-input__wrapper) {
|
|
|
background-color: transparent !important;
|