Browse Source

优化、补充

AaronBruin 2 months ago
parent
commit
4dbb6db35f

BIN
src/assets/images/chassis.png


BIN
src/assets/images/pedestal1.png


BIN
src/assets/images/pedestalActivate1.png


BIN
src/assets/logo/ball.png


+ 3 - 3
src/layout/components/Sidebar/Logo.vue

@@ -301,8 +301,8 @@ onMounted(() => {
   color: rgb(207, 248, 255);
   border: 3px solid transparent;
   border-radius: 60px;
-  background-color: rgb(6, 69, 73);
-  background-image: linear-gradient(to bottom right, rgb(10, 107, 115), rgb(2, 10, 14)), linear-gradient(125deg, rgba(255, 255, 255, 0) 45%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0) 53%);
+  background-color: rgb(10, 64, 112);
+  background-image: linear-gradient(to bottom right, rgb(40, 105, 160), rgb(2, 10, 14)), linear-gradient(125deg, rgba(255, 255, 255, 0) 45%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0) 53%);
   background-origin: border-box;
   background-clip: padding-box, border-box;
   background-size: 100%, 200%;
@@ -315,7 +315,7 @@ onMounted(() => {
 
 .shiny-button:hover {
   cursor: pointer;
-  background-image: linear-gradient(-60deg, rgb(40, 105, 160) 0%, rgb(186, 211, 229) 100%), linear-gradient(125deg, rgba(255, 255, 255, 0) 45%, rgba(255, 255, 255, 0.6) 50%, rgba(255, 255, 255, 0) 53%);
+  background-color: rgb(40, 105, 160);
   color: rgb(250, 250, 255);
   box-shadow: rgba(0, 0, 0, 0.7) 5px 5px 5px;
   text-shadow: 0px 0px 3px rgba(255, 255, 255, 0.7);

+ 9 - 9
src/layout/components/Sidebar/index.vue

@@ -19,7 +19,7 @@
       <div class="tag-style" ref="tagBox">
         <div class="menu_bottom_box" ref="scrollWrapper">
           <div class="item_box_sidebar" v-for="(item, index) in filteredArray" :key="item.path + index" :id="item.path">
-            <div @click="goBack(item.path)">
+            <div class="center_in" @click="goBack(item.path)">
               <div class="img_box_item" :class="getPathUrl(item.path) ? 'activate_img_sidebar' : ''">
                 <svg class="energy_box_icon" aria-hidden="true">
                   <defs>
@@ -376,17 +376,18 @@ onMounted(() => {
   display: flex;
   flex-direction: column;
   align-items: center;
-  padding: 4px 0px;
-  width: 100px;
+  padding: 0px 0px 4px 0px;
+  width: 85px;
+  z-index: 10;
 }
 
 .img_box_item {
   cursor: pointer;
   position: absolute;
   bottom: 25px;
-  width: 60px;
+  width: 50px;
   height: 50px;
-  background: url("@/assets/images/pedestal.png");
+  background: url("@/assets/images/pedestal1.png");
   background-size: cover;
   display: flex;
   justify-content: center;
@@ -394,7 +395,7 @@ onMounted(() => {
 }
 
 .activate_img_sidebar {
-  background: url("@/assets/images/pedestalActivate.png");
+  background: url("@/assets/images/pedestalActivate1.png");
   background-size: cover;
 }
 
@@ -405,9 +406,8 @@ onMounted(() => {
 }
 
 .energy_box_icon {
-  width: 30px;
-  height: 30px;
+  width: 28px;
+  height: 28px;
   position: relative;
-  vertical-align: -2px;
 }
 </style>

+ 124 - 40
src/views/ce.html

@@ -22,7 +22,7 @@
             right: 0px;
             width: 100px;
             height: 40px;
-            background-color: rgba(34, 91, 153, 0.3);
+            background-color: rgba(7, 27, 60, 0.8);
             display: flex;
             align-items: center;
             justify-content: center;
@@ -30,10 +30,18 @@
             border-radius: 4px;
         }
 
+        .triangle {
+            position: relative;
+            width: 15px;
+            height: 15px;
+            margin-left: 15px;
+        }
+
         .triangle:after {
             content: '';
             display: inline-block;
-            margin-left: 20px;
+            position: absolute;
+            top: 0;
             width: 10px;
             height: 10px;
             border-top: 1px solid #ffffff;
@@ -46,6 +54,7 @@
             position: absolute;
             top: 50px;
             right: 0px;
+            flex-direction: column;
         }
 
         .box_item_bf {
@@ -83,8 +92,8 @@
         .floor_box::after {
             content: "";
             position: absolute;
-            width: 55px;
-            height: 55px;
+            width: 50px;
+            height: 50px;
             border-radius: 50%;
             padding: var(--t);
             background: var(--c);
@@ -117,8 +126,8 @@
         .activate_box::after {
             content: "";
             position: absolute;
-            width: 55px;
-            height: 55px;
+            width: 50px;
+            height: 50px;
             border-radius: 50%;
             padding: var(--t);
             background: var(--c);
@@ -147,88 +156,163 @@
 
 <body>
     <div class="card_floor_control">
-        <div class="floor_control" @click="switchover">{{ currentItem }}<span class="triangle"></span></div>
-        <div class="all_building_floor">
-            <div class="box_item_bf" :class="currentId == item.id ? 'activate_box' : 'floor_box'"
+        <div class="floor_control" id="floorControl">全部<span class="triangle"></span></div>
+        <!-- <div class="floor_control" @click="switchover">{{ currentItem }}<span class="triangle"></span></div> -->
+        <div class="all_building_floor" id="allBuildingFloor">
+            <!-- <div class="box_item_bf" :class="currentId == item.id ? 'activate_box' : 'floor_box'"
                 v-for="(item, index) in currentData" :key="index" @click="switchoverItem(item)">
                 {{ item.title }}
-            </div>
+            </div> -->
         </div>
     </div>
     <script>
+        let currentId = 'all';
         let currentItem = '全部';
-        const currentId = ref('all');
-        const currentData = ref([])
+        let showList = false;
         const arrData = [{
             title: '全部',
             id: 'all',
         }, {
             title: 'A栋',
             id: 'A',
-            list: [{
+            childList: [{
                 title: '3F',
-                id: '3',
+                id: 'A3',
             }, {
                 title: '2F',
-                id: '2',
+                id: 'A2',
             }, {
                 title: '1F',
-                id: '1',
+                id: 'A1',
+            }, {
+                title: '全部',
+                id: 'omn',
             }]
         }, {
             title: 'B栋',
             id: 'B',
-            list: [{
+            childList: [{
                 title: '3F',
-                id: '3',
+                id: 'B3',
             }, {
                 title: '2F',
-                id: '2',
+                id: 'B2',
             }, {
                 title: '1F',
-                id: '1',
+                id: 'B1',
             }]
         }, {
             title: 'C栋',
             id: 'C',
-            list: [{
+            childList: [{
                 title: '4F',
-                id: '4',
+                id: 'C4',
             }, {
                 title: '3F',
-                id: '3',
+                id: 'C3',
             }, {
                 title: '2F',
-                id: '2',
+                id: 'C2',
             }, {
                 title: '1F',
-                id: '1',
+                id: 'C1',
             }]
         }, {
             title: 'D栋',
             id: 'D',
-            list: [{
+            childList: [{
                 title: '2F',
+                id: 'D2',
             }, {
                 title: '1F',
+                id: 'D1',
             }]
         }]
-        function switchover() {
-            currentData.value = arrData
-            currentId.value = 'all'
-            currentItem = '全部'
-        }
-        function switchoverItem(value) {
-            currentItem = value.title
-            currentId.value = value.id
-            arrData.forEach((item) => {
-                if (currentId.value == item.id) {
-                    currentData.value = item.list
-                    if (value.id == 'all') {
-                        currentData.value = arrData
+        const floorControl = document.getElementById('floorControl');
+        const allBuildingFloor = document.getElementById('allBuildingFloor');
+        floorControl.addEventListener('click', () => {
+            currentId = 'all';
+            allBuildingFloor.style.display = 'flex';
+            renderList(true);
+        });
+        let listData = [];
+        // 渲染列表区域  
+        function renderList(flag) {
+            allBuildingFloor.innerHTML = '';
+            if (currentId === 'all') {
+                currentTitle = '全部';
+                floorControl.childNodes[0].nodeValue = currentTitle;
+                listData = arrData;
+            } else {
+                if (flag) {
+                    listData = arrData;
+                } else {
+                    function find(list, id) {
+                        return list && id ? (function filter(arr) {
+                            for (var i = 0; i < arr.length; ++i) {
+                                var itemId = arr[i].id;
+                                var children = arr[i].childList || [];
+                                var _ret = arr[i];
+                                if (id === itemId) {
+                                    return _ret;
+                                } else if (children.length) {
+                                    _ret = filter(children);
+                                    if (_ret) return _ret;
+                                }
+                            }
+                            return null;
+                        })(list) : null;
+                    }
+                    const currentBuilding = find(arrData, currentId);
+                    if (currentBuilding && currentBuilding.childList) {
+                        listData = currentBuilding.childList;
+                    }
+                }
+            }
+            let allFlag = true
+            listData.forEach(item => {
+                const div = document.createElement('div');
+                div.classList.add('box_item_bf');
+                if (item.id === currentId) {
+                    allFlag = false
+                    div.classList.add('activate_box');
+
+                } else {
+                    if (allFlag && item.id == 'omn') {
+                        div.classList.add('activate_box');
                     }
+                    console.log(allFlag, item.id, 2);
+
+                    div.classList.add('floor_box');
                 }
-            })
+                div.textContent = item.title;
+                div.addEventListener('click', (e) => {
+                    e.stopPropagation();  // 阻止事件冒泡,避免触发外层点击  
+                    switchoverItem(item);
+                });
+                allBuildingFloor.appendChild(div);
+            });
+        }
+        // 切换选中项  
+        function switchoverItem(item) {
+            // 如果点了目前已经选中的项,列表隐藏  
+            if (item.id === currentId) {
+                showList = false;
+                return;
+            }
+            currentId = item.id;
+            currentTitle = item.title;
+            floorControl.childNodes[0].nodeValue = currentTitle;
+            if (currentId === 'all') {
+                renderList(false);
+            } else {
+                const isTopLevel = arrData.some(it => it.id === currentId);
+                if (isTopLevel) {
+                    renderList(false);
+                } else {
+                    renderList(false);
+                }
+            }
         }
     </script>
 </body>

+ 297 - 0
src/views/dddd.html

@@ -0,0 +1,297 @@
+<!DOCTYPE html>  
+<html lang="en">  
+
+<head>  
+  <meta charset="UTF-8" />  
+  <meta name="viewport" content="width=device-width, initial-scale=1" />  
+  <title>纯 JS 楼层切换控件</title>  
+  <style>  
+    .card_floor_control {  
+      user-select: none;  
+      position: absolute;  
+      top: 100px;  
+      right: calc(25% + 10px);  
+      width: 100px;  
+      height: auto;  
+      font-family: Arial, sans-serif;  
+    }  
+
+    .floor_control {  
+      position: relative;  
+      cursor: pointer;  
+      width: 100px;  
+      height: 40px;  
+      background-color: rgba(34, 91, 153, 0.3);  
+      display: flex;  
+      align-items: center;  
+      justify-content: center;  
+      color: #ffffff;  
+      border-radius: 4px;  
+      user-select: none;  
+    }  
+
+    .triangle:after {  
+      content: '';  
+      display: inline-block;  
+      margin-left: 20px;  
+      width: 10px;  
+      height: 10px;  
+      border-top: 1px solid #ffffff;  
+      border-right: 1px solid #ffffff;  
+      transform: rotate(135deg);  
+      -webkit-transform: rotate(135deg);  
+    }  
+
+    .all_building_floor {  
+      position: relative;  
+      margin-top: 10px;  
+      display: none;  
+      flex-direction: column;  
+      right: 0px;  
+    }  
+
+    .box_item_bf {  
+      display: flex;  
+      align-items: center;  
+      justify-content: center;  
+      font-size: 18px;  
+      position: relative;  
+      user-select: none;  
+    }  
+
+    .floor_box {  
+      cursor: pointer;  
+      color: rgb(108, 111, 113);  
+      --c: rgb(108, 111, 113);  
+      --n: 4;  
+      --t: 2px;  
+      --d: 45deg;  
+      aspect-ratio: 1;  
+      width: 60px;  
+      height: 60px;  
+      border-radius: 50%;  
+      background-color: rgb(1, 6, 19);  
+      margin-bottom: 10px;  
+      position: relative;  
+    }  
+
+    .floor_box::after {  
+      content: "";  
+      position: absolute;  
+      top: 2.5px;  
+      left: 2.5px;  
+      width: 55px;  
+      height: 55px;  
+      border-radius: 50%;  
+      padding: var(--t);  
+      background: var(--c);  
+      -webkit-mask:  
+        linear-gradient(#0000 0 0) content-box,  
+        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
+      -webkit-mask-composite: source-in;  
+      mask:  
+        linear-gradient(#0000 0 0) content-box,  
+        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
+      mask-composite: intersect;  
+    }  
+
+    .activate_box {  
+      cursor: pointer;  
+      color: #fff;  
+      --c: #fff;  
+      --n: 4;  
+      --t: 2px;  
+      --d: 45deg;  
+      aspect-ratio: 1;  
+      width: 60px;  
+      height: 60px;  
+      border-radius: 50%;  
+      background-color: rgb(1, 6, 19);  
+      margin-bottom: 10px;  
+      position: relative;  
+    }  
+
+    .activate_box::after {  
+      content: "";  
+      position: absolute;  
+      top: 2.5px;  
+      left: 2.5px;  
+      width: 55px;  
+      height: 55px;  
+      border-radius: 50%;  
+      padding: var(--t);  
+      background: var(--c);  
+      -webkit-mask:  
+        linear-gradient(#0000 0 0) content-box,  
+        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
+      -webkit-mask-composite: source-in;  
+      mask:  
+        linear-gradient(#0000 0 0) content-box,  
+        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
+      mask-composite: intersect;  
+      animation: rotate 5s linear infinite;  
+    }  
+
+    @keyframes rotate {  
+      from {  
+        transform: rotate(0deg);  
+      }  
+
+      to {  
+        transform: rotate(360deg);  
+      }  
+    }  
+  </style>  
+</head>  
+
+<body>  
+  <div class="card_floor_control">  
+    <div class="floor_control" id="floorControl">  
+      全部<span class="triangle"></span>  
+    </div>  
+    <div class="all_building_floor" id="allBuildingFloor"></div>  
+  </div>  
+
+  <script>  
+    (function () {  
+      const arrData = [  
+        { title: '全部', id: 'all' },  
+        {  
+          title: 'A栋', id: 'A', list: [  
+            { title: '3F', id: '3' },  
+            { title: '2F', id: '2' },  
+            { title: '1F', id: '1' }  
+          ]  
+        },  
+        {  
+          title: 'B栋', id: 'B', list: [  
+            { title: '3F', id: '3' },  
+            { title: '2F', id: '2' },  
+            { title: '1F', id: '1' }  
+          ]  
+        },  
+        {  
+          title: 'C栋', id: 'C', list: [  
+            { title: '4F', id: '4' },  
+            { title: '3F', id: '3' },  
+            { title: '2F', id: '2' },  
+            { title: '1F', id: '1' }  
+          ]  
+        },  
+        {  
+          title: 'D栋', id: 'D', list: [  
+            { title: '2F', id: '2' },  
+            { title: '1F', id: '1' }  
+          ]  
+        }  
+      ]  
+
+      // 当前选中项id 和 title  
+      let currentId = 'all';  
+      let currentTitle = '全部';  
+
+      const floorControl = document.getElementById('floorControl');  
+      const allBuildingFloor = document.getElementById('allBuildingFloor');  
+
+      // 控制楼层列表容器显示/隐藏  
+      let showList = false;  
+
+      floorControl.addEventListener('click', () => {  
+        showList = !showList;  
+        if (showList) {  
+          allBuildingFloor.style.display = 'flex';  
+          // 切换显示当前选中项对应的列表  
+          renderList();  
+        } else {  
+          allBuildingFloor.style.display = 'none';  
+        }  
+      });  
+
+      // 渲染列表区域  
+      function renderList() {  
+        allBuildingFloor.innerHTML = '';  
+
+        // 找到当前id对应的item,和列表数据  
+        let listData = [];  
+
+        if (currentId === 'all') {  
+          // 如果是全部,展示顶层选项  
+          listData = arrData;  
+        } else {  
+          const currentBuilding = arrData.find(item => item.id === currentId);  
+          if (currentBuilding && currentBuilding.list) {  
+            listData = currentBuilding.list;  
+          } else {  
+            // 防止找不到对应list  
+            listData = [];  
+          }  
+        }  
+
+        listData.forEach(item => {  
+          const div = document.createElement('div');  
+          div.classList.add('box_item_bf');  
+
+          if (item.id === currentId) {  
+            div.classList.add('activate_box');  
+          } else {  
+            div.classList.add('floor_box');  
+          }  
+
+          div.textContent = item.title;  
+
+          div.addEventListener('click', (e) => {  
+            e.stopPropagation();  // 阻止事件冒泡,避免触发外层点击  
+            switchoverItem(item);  
+          });  
+
+          allBuildingFloor.appendChild(div);  
+        });  
+      }  
+
+      // 切换选中项  
+      function switchoverItem(item) {  
+        // 如果点了目前已经选中的项,列表隐藏  
+        if (item.id === currentId) {  
+          showList = false;  
+          allBuildingFloor.style.display = 'none';  
+          return;  
+        }  
+
+        currentId = item.id;  
+        currentTitle = item.title;  
+
+        // 改变按钮显示文字  
+        floorControl.childNodes[0].nodeValue = currentTitle;  
+
+        // 如果选中的是“全部”,则展示arrData顶层数据  
+        if (currentId === 'all') {  
+          // 当前激活项就是全部  
+          renderList();  
+        } else {  
+          // 判断当前id是否是顶层id,如果在顶层arrData里则显示对应list,否则显示arrData顶层选项  
+          const isTopLevel = arrData.some(it => it.id === currentId);  
+
+          if (isTopLevel) {  
+            renderList();  
+          } else {  
+            // 当前选中的是具体楼层,这时列表显示 arrData 顶层,方便切换楼栋  
+            currentId = 'all'; // 也可以这样处理,或者直接关闭列表  
+            currentTitle = '全部';  
+            floorControl.childNodes[0].nodeValue = currentTitle;  
+            showList = false;  
+            allBuildingFloor.style.display = 'none';  
+          }  
+        }  
+      }  
+
+      // 初始化显示  
+      floorControl.childNodes[0].nodeValue = currentTitle;  
+
+      // 说明:初始时列表隐藏,点击按钮显示顶层选项,也就是arrData。  
+
+    })();  
+  </script>  
+
+</body>  
+
+</html>

+ 1 - 1
src/views/index/particle.vue

@@ -121,7 +121,7 @@ const render = () => {
     particles.geometry.attributes.position.needsUpdate = true;
     particles.geometry.attributes.scale.needsUpdate = true;
     renderer.render(scene, camera);
-    count += 0.1;
+    count += 0.08;
 };
 
 const animate = () => {

+ 58 - 6
src/views/login.vue

@@ -2,7 +2,9 @@
   <dv-full-screen-container>
     <div class="login">
       <div class="login_box">
-        <div class="ball_login"></div>
+        <div class="ball_login">
+          <div id="canvas"></div>
+        </div>
         <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
           <h3 class="title">{{ title }}</h3>
           <el-form-item prop="username">
@@ -52,6 +54,7 @@ import Cookies from "js-cookie";
 import { encrypt, decrypt } from "@/utils/jsencrypt";
 import useUserStore from '@/store/modules/user'
 import particle from './index/particle.vue'
+import * as THREE from "three";
 
 const title = import.meta.env.VITE_APP_TITLE;
 const userStore = useUserStore();
@@ -142,8 +145,57 @@ function getCookie() {
   };
 }
 
-getCode();
-getCookie();
+onMounted(() => {
+  getCode();
+  getCookie();
+  nextTick(() => {
+    init();
+  })
+});
+var renderer, scene, camera;
+const init = () => {
+  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
+  renderer.setSize(window.innerWidth, window.innerHeight);
+  document.getElementById('canvas').appendChild(renderer.domElement);
+  scene = new THREE.Scene();
+  camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 1, 1000);
+  camera.position.z = 500;
+  scene.add(camera);
+  var geom = new THREE.IcosahedronGeometry(7, 1);
+  var geom2 = new THREE.IcosahedronGeometry(15, 1);
+  var mat = new THREE.MeshPhongMaterial({
+    color: 0xffffff,
+    shading: THREE.FlatShading
+  });
+  var mat2 = new THREE.MeshPhongMaterial({
+    color: 0xffffff,
+    wireframe: true,
+    side: THREE.DoubleSide
+  });
+  var planet = new THREE.Mesh(geom, mat);
+  planet.scale.x = planet.scale.y = planet.scale.z = 16;
+  var center = new THREE.Object3D();
+  center.add(planet);
+  scene.add(center);
+  renderer.render(scene, camera)
+  var planet2 = new THREE.Mesh(geom2, mat2);
+  planet2.scale.x = planet2.scale.y = planet2.scale.z = 10;
+  outside = new THREE.Object3D();
+  outside.add(planet2);
+  scene.add(outside);
+  var ambientLight = new THREE.AmbientLight(0x999999);
+  scene.add(ambientLight);
+  var lights1 = new THREE.DirectionalLight(0xffffff, 1);
+  lights1.position.set(1, 0, 0);
+  var lights2 = new THREE.DirectionalLight(0x11E8BB, 1);
+  lights2.position.set(0.75, 1, 0.5);
+  var lights3 = new THREE.DirectionalLight(0x8200C9, 1);
+  lights3.position.set(-0.75, -1, 0.5);
+  scene.add(lights1);
+  scene.add(lights2);
+  scene.add(lights3);
+
+};
 </script>
 
 <style lang='scss' scoped>
@@ -157,7 +209,7 @@ getCookie();
 
 .login_box {
   position: absolute;
-  top: 5%;
+  top: 15%;
   display: flex;
   justify-content: center;
   align-items: center;
@@ -174,8 +226,8 @@ getCookie();
 
 .ball_login {
   flex: none;
-  width: 700px;
-  height: 700px;
+  width: 500px;
+  height: 500px;
   background: url("@/assets/logo/ball.png");
   background-size: cover;
 }

+ 16 - 9
src/views/system/elevator/modules/consume.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="_runnings">
         <HeadlineTag value="行为检测(周)"></HeadlineTag>
-        <div class="_runnings_mains">
-            <div class="_runnings_mains_left">
+        <div class="_runnings_mains" :style="{ '--heightSume': heightcon + 'px' }">
+            <div class="_runnings_mains_left" id="sumeWidth">
                 <div class="_runnings_mains_left_tuan tuan1"></div>
                 <div class="_runnings_mains_left_conter">
                     <div class="_runnings_mains_left_conter_num">{{ resultData.OverloadWarning || 0 }}</div>
@@ -41,21 +41,28 @@ const props = defineProps({
         default: {}
     }
 })
+const heightcon = ref(0)
+// 生命周期
+onMounted(() => {
+    var element = document.getElementById("sumeWidth");
+    var width = element.offsetWidth;
+    heightcon.value = width
+});
 </script>
 <style lang="scss" scoped>
 .tuan1 {
     background: url("@/assets/images/video_bg_1.png");
-    // animation: scanning 10s linear infinite;
+    animation: scanning 10s linear infinite;
 }
 
 .tuan2 {
     background: url("@/assets/images/video_bg_2.png");
-    // animation: scanning 10s linear infinite;
+    animation: scanning 10s linear infinite;
 }
 
 .tuan3 {
     background: url("@/assets/images/video_bg_3.png");
-    // animation: scanning 10s linear infinite;
+    animation: scanning 10s linear infinite;
 }
 
 ._runnings {
@@ -65,15 +72,15 @@ const props = defineProps({
 
     &_mains {
         flex: 1;
-        margin: 30px;
+        width: 100%;
         display: flex;
         align-items: center;
-        flex-wrap: wrap;
+        justify-content: space-around;
 
         &_left {
             flex-shrink: 0;
-            width: 140px;
-            height: 140px;
+            width: 32%;
+            height: var(--heightSume);
             position: relative;
 
             &_tuan {

+ 3 - 1
src/views/system/lighting/modules/deviceList.vue

@@ -111,7 +111,9 @@ const resumeCarousel = () => {
 };
 
 onMounted(() => {
-    startCarousel();
+    nextTick(() => {
+        startCarousel();
+    })
 });
 
 onUnmounted(() => {