Jelajahi Sumber

fix:空调

anxiaoxia 1 bulan lalu
induk
melakukan
3dbd52dab4

+ 32 - 25
src/views/envmonitor/taiguv1/components/Air/AirMore.vue

@@ -64,7 +64,7 @@
     <div class="divider" v-if="airSwitchStatus.switchStatus">
       <img src="@/assets/svg/line.svg" alt="" />
     </div>
-
+<!-- 子设备列表 -->
     <div class="air-bottom">
       <div class="item-box" :class="item.isOpen ? 'item-active' : ''" v-for="item in airEquipList" :key="item.id">
         <div class="handle-top">
@@ -214,7 +214,7 @@ watch(
       airData.value = { ...newVal, minTempSet, maxTempSet }
     }
   },
-  { deep: true } // 添加深度监听
+  { deep: true} // 添加深度监听
 )
 watch(
   () => props.airList,
@@ -231,30 +231,34 @@ watch(
 // 对比和store中开关状态
 const compareStatus = data => {
   airEquipList.value = data.map(item => {
-    if (allAirStatus.value[item.id]) {
-      if (allAirStatus.value[item.id].lastSwitchStatus == item.runStatus) {
-        store.dispatch('taiguv1/setAirStatus', {
-          id: item.id,
-          status: {
-            loading: false,
-            lastSwitchStatus: item.runStatus == 1
-          }
-        })
-        return {
-          ...item,
-          isOpen: item.runStatus == 1
-        }
-      } else {
-        return {
-          ...item,
-          isOpen: allAirStatus.value[item.id].lastSwitchStatus
+    const currentStatus = allAirStatus.value[item.id]
+    
+    // 基础状态对象
+    const baseStatus = {
+      ...item,
+      isOpen: item.runStatus == 1
+    }
+
+    if (!currentStatus) {
+      return baseStatus
+    }
+
+    // 如果最后切换状态与当前运行状态相同,重置状态
+    if (currentStatus.lastSwitchStatus == item.runStatus) {
+      store.dispatch('taiguv1/setAirStatus', {
+        id: item.id,
+        status: {
+          loading: false,
+          lastSwitchStatus: null
         }
-      }
-    } else {
-      return {
-        ...item,
-        isOpen: item.runStatus == 1
-      }
+      })
+      return baseStatus
+    }
+
+    // 如果有待处理的切换状态,使用该状态
+    return {
+      ...item,
+      isOpen: currentStatus.lastSwitchStatus ?? (item.runStatus == 1)
     }
   })
 }
@@ -341,12 +345,14 @@ onMounted(() => {
   nextTick(() => {
     controlBtn.value.forEach(button => {
       button.addEventListener('touchstart', handleTouchStart)
+      button.addEventListener('click', handleTouchStart)
     })
   })
 })
 
 // 添加 touchstart 处理函数
 const handleTouchStart = event => {
+  console.log('debugger111')
   const button = event.currentTarget
   const type = button.getAttribute('data-type') // 获取按钮类型
   button.classList.add('active')
@@ -366,6 +372,7 @@ const handleTouchStart = event => {
 onUnmounted(() => {
   controlBtn.value.forEach(button => {
     button.removeEventListener('touchstart', handleTouchStart)
+    button.removeEventListener('click', handleTouchStart)
   })
 })
 </script>

+ 298 - 267
src/views/envmonitor/taiguv1/components/Lamp/LightMore.vue

@@ -1,51 +1,77 @@
 <template>
-  <div class="more-box">
-    <div class="light-more-top">
-      <div class="left">
-        <div class="light-box">
-          <img
-            :src="lampData.isOpen ? lampOpenIcon : lampCloseIcon"
-            alt=""
-            :style="lampData.isOpen ? { width: '58px', height: '62px' } : ''" />
+    <div class="more-box">
+        <div class="light-more-top">
+            <div class="left">
+                <div class="light-box">
+                    <img
+                        :src="lampData.isOpen ? lampOpenIcon : lampCloseIcon"
+                        alt=""
+                        :style="lampData.isOpen ? { width: '58px', height: '62px' } : ''"
+                    />
+                </div>
+                <div class="light-name">{{ $t(`lamp.${lampData.lampStatusText}`) }}</div>
+            </div>
+            <div class="right">
+                <div
+                    class="control"
+                    :ref="setRef"
+                    @click="handleSwitch('isOpen', true)"
+                >{{ $t(`common.全开`) }}</div>
+                <div
+                    class="control"
+                    :ref="setRef"
+                    @click="handleSwitch('isOpen', false)"
+                >{{ $t(`common.全关`) }}</div>
+            </div>
         </div>
-        <div class="light-name">{{ $t(`lamp.${lampData.lampStatusText}`) }}</div>
-      </div>
-      <div class="right">
-        <div class="control" :ref="setRef" @click="handleSwitch('isOpen', true)">{{ $t(`common.全开`) }}</div>
-        <div class="control" :ref="setRef" @click="handleSwitch('isOpen', false)">{{ $t(`common.全关`) }}</div>
-      </div>
-    </div>
-    <div class="light-middle" v-if="lampData.isOpen">
-      <div class="bright-slider">
-        <Slider
-          :min="min"
-          :max="max"
-          v-model="lampData.brightValue"
-          isFollow
-          showValue
-          suffixNormal
-          suffix="%"
-          @onEnd="setLampStatus('brightValue')" />
-      </div>
-      <!-- <div class="temp-slider">
+        <div
+            class="light-middle"
+            v-if="lampData.isOpen"
+        >
+            <div class="bright-slider">
+                <Slider
+                    :min="min"
+                    :max="max"
+                    v-model="lampData.brightValue"
+                    isFollow
+                    showValue
+                    suffixNormal
+                    suffix="%"
+                    @onEnd="setLampStatus('brightValue')"
+                />
+            </div>
+            <!-- <div class="temp-slider">
         <LampSlider v-model="lampData.colorTempValue" @onEnd="setLampStatus('colorTempValue')" />
       </div> -->
-    </div>
+        </div>
 
-    <div class="divider" v-if="lampData.isOpen">
-      <img src="@/assets/svg/line.svg" alt="" />
-    </div>
+        <div
+            class="divider"
+            v-if="lampData.isOpen"
+        >
+            <img
+                src="@/assets/svg/line.svg"
+                alt=""
+            />
+        </div>
 
-    <div class="light-bottom">
-      <div class="item-box" :class="item.valueSwitch ? 'light-box-active ' : ''" v-for="(item, index) in lampList">
-        <div class="name">{{ item.localName }}</div>
-        <SwitchButton
-          :loading="allLampStatus[item.id]?.loading"
-          v-model="item.isOpen"
-          @change="sigleLampChange('isOpen', item, 'single')" />
-      </div>
+        <div class="light-bottom">
+            <div
+                class="item-box"
+                :class="item.valueSwitch ? 'light-box-active ' : ''"
+                v-for="(item, index) in lampList"
+            >
+                <div class="name">{{ item.localName }}</div>
+                <div style="width: 100rpx;">
+                    <SwitchButton
+                        :loading="allLampStatus[item.id]?.loading"
+                        v-model="item.isOpen"
+                        @change="sigleLampChange('isOpen', item, 'single')"
+                    />
+                </div>
+            </div>
+        </div>
     </div>
-  </div>
 </template>
 
 <script setup>
@@ -63,33 +89,33 @@ const min = 0
 const max = 100
 // 接收父组件传递的初始状态
 const props = defineProps({
-  lampStatus: {
-    type: Object,
-    default: () => {
-      return {
-        isOpen: false,
-        brightValue: 0
-      }
-    }
-  },
-  equipList: {
-    type: Array,
-    default: () => {
-      return []
+    lampStatus: {
+        type: Object,
+        default: () => {
+            return {
+                isOpen: false,
+                brightValue: 0
+            }
+        }
+    },
+    equipList: {
+        type: Array,
+        default: () => {
+            return []
+        }
     }
-  }
 })
 
 const controlBtn = ref([])
 const setRef = el => {
-  if (el) {
-    if (!controlBtn.value.includes(el)) {
-      controlBtn.value.push(el)
+    if (el) {
+        if (!controlBtn.value.includes(el)) {
+            controlBtn.value.push(el)
+        }
     }
-  }
 }
 
-const lampList = ref(props.equipList||[])
+const lampList = ref(props.equipList || [])
 const lampData = ref(props.lampStatus)
 
 const allLampStatus = computed(() => store.state.taiguv1.lampSwitchStatus)
@@ -111,257 +137,262 @@ const allLampStatus = computed(() => store.state.taiguv1.lampSwitchStatus)
 //   }
 // })
 watch(
-  () => props.lampStatus,
-  (newVal, oldVal) => {
-    if (!newVal) {
-      return
-    }
-    let { brightValue } = lampData.value
-    lampData.value = { ...newVal, brightValue }
-  },
-  { deep: true } // 添加深度监听
+    () => props.lampStatus,
+    (newVal, oldVal) => {
+        if (!newVal) {
+            return
+        }
+        let { brightValue } = lampData.value
+        lampData.value = { ...newVal, brightValue }
+    },
+    { deep: true } // 添加深度监听
 )
 watch(
-  () => props.equipList,
-  (newVal, oldVal) => {
-    compareStatus(newVal)
-  },
-  { deep: true }
+    () => props.equipList,
+    (newVal, oldVal) => {
+        compareStatus(newVal)
+    },
+    { deep: true }
 )
 
 // 对比和store中开关状态
 const compareStatus = data => {
-  lampList.value = data.map(item => {
-    if (allLampStatus.value[item.id]) {
-      if (allLampStatus.value[item.id].lastSwitchStatus == item.runStatus) {
-        store.dispatch('taiguv1/setLampStatus', {
-          id: item.id,
-          status: {
-            loading: false,
-            lastSwitchStatus: item.runStatus == 1
-          }
-        })
-        return {
-          ...item,
-          isOpen: item.runStatus == 1
-        }
-      } else {
-        return {
-          ...item,
-          isOpen: allLampStatus.value[item.id].lastSwitchStatus
+    lampList.value = data.map(item => {
+        const currentStatus = allLampStatus.value[item.id]
+  
+    // 基础状态对象
+    const baseStatus = {
+      ...item,
+      isOpen: item.runStatus == 1
+    }
+
+    if (!currentStatus) {
+      return baseStatus
+    }
+
+    // 如果最后切换状态与当前运行状态相同,重置状态
+    if (currentStatus.lastSwitchStatus == item.runStatus) {
+      store.dispatch('taiguv1/setLampStatus', {
+        id: item.id,
+        status: {
+          loading: false,
+          lastSwitchStatus: null
         }
-      }
-    } else {
-      return {
-        ...item,
-        isOpen: item.runStatus == 1
-      }
+      })
+      return baseStatus
     }
-  })
+
+    // 如果有待处理的切换状态,使用该状态
+    return {
+      ...item,
+      isOpen: currentStatus.lastSwitchStatus ?? (item.runStatus == 1)
+    }
+
+    })
 }
 // 整体开关
 const handleSwitch = (type, value) => {
-  lampData.value.isOpen = value
-  setLampStatus(type)
+    lampData.value.isOpen = value
+    setLampStatus(type)
 }
 
 // 单个空调开关
 const sigleLampChange = (type, source, all) => {
-  if (type == 'isOpen') {
-    store.dispatch('taiguv1/setLampStatus', {
-      id: source.id,
-      status: {
-        loading: true,
-        lastSwitchStatus: source.isOpen
-      }
-    })
-  }
-  if (all == 'single') {
-    const params = deviceControl.assemblyLampCommand(source[type], type, source)
-    deviceControl.sendCommands(params)
-  }
+    if (type == 'isOpen') {
+        store.dispatch('taiguv1/setLampStatus', {
+            id: source.id,
+            status: {
+                loading: true,
+                lastSwitchStatus: source.isOpen
+            }
+        })
+    }
+    if (all == 'single') {
+        const params = deviceControl.assemblyLampCommand(source[type], type, source)
+        deviceControl.sendCommands(params)
+    }
 }
 const setLampStatus = type => {
-  if (type == 'isOpen') {
-    store.dispatch('taiguv1/setLampStatus', {
-      id: 'all',
-      status: {
-        loading: true,
-        lastSwitchStatus: lampData.value.isOpen
-      }
-    })
-    lampList.value.forEach(item => {
-      item.isOpen = lampData.value.isOpen
-      sigleLampChange(type, item, 'all')
-    })
-  }
-  const params = deviceControl.assemblyLampCommand(lampData.value[type], type, lampList.value)
-  deviceControl.sendCommands(params)
+    if (type == 'isOpen') {
+        store.dispatch('taiguv1/setLampStatus', {
+            id: 'all',
+            status: {
+                loading: true,
+                lastSwitchStatus: lampData.value.isOpen
+            }
+        })
+        lampList.value.forEach(item => {
+            item.isOpen = lampData.value.isOpen
+            sigleLampChange(type, item, 'all')
+        })
+    }
+    const params = deviceControl.assemblyLampCommand(lampData.value[type], type, lampList.value)
+    deviceControl.sendCommands(params)
 }
 onMounted(() => {
-  nextTick(() => {
-    controlBtn.value.forEach(button => {
-      button.addEventListener('touchstart', handleTouchStart)
+    nextTick(() => {
+        controlBtn.value.forEach(button => {
+            button.addEventListener('touchstart', handleTouchStart)
+        })
     })
-  })
 })
 
 // 添加 touchstart 处理函数
 const handleTouchStart = event => {
-  const button = event.currentTarget
-  button.classList.add('active')
-  setTimeout(() => {
-    button.classList.remove('active')
-  }, 200)
+    const button = event.currentTarget
+    button.classList.add('active')
+    setTimeout(() => {
+        button.classList.remove('active')
+    }, 200)
 }
 // 添加 onUnmounted 钩子
 onUnmounted(() => {
-  controlBtn.value.forEach(button => {
-    button.removeEventListener('touchstart', handleTouchStart)
-  })
+    controlBtn.value.forEach(button => {
+        button.removeEventListener('touchstart', handleTouchStart)
+    })
 })
 </script>
 <style lang="scss" scoped>
 .more-box {
-  .light-more-top {
-    display: flex;
-    align-items: center;
-    margin-bottom: 36px;
-    .left {
-      margin-right: 36px;
-      .light-box {
-        width: 110px;
-        height: 110px;
-        background: rgba(255, 255, 255, 0.4);
-        border-radius: 50%;
-        text-align: center;
-        margin-right: 27px;
-        img {
-          width: 36px;
-          height: 36px;
-          margin: 0 auto;
-          margin-top: 37px;
+    .light-more-top {
+        display: flex;
+        align-items: center;
+        margin-bottom: 36px;
+        .left {
+            margin-right: 36px;
+            .light-box {
+                width: 110px;
+                height: 110px;
+                background: rgba(255, 255, 255, 0.4);
+                border-radius: 50%;
+                text-align: center;
+                margin-right: 27px;
+                img {
+                    width: 36px;
+                    height: 36px;
+                    margin: 0 auto;
+                    margin-top: 37px;
+                }
+            }
+            .light-name {
+                //styleName: Chi/Body Large;
+                margin-top: 12px;
+                font-family: PingFang SC;
+                width: 110px;
+                font-size: 16px;
+                font-weight: 300;
+                line-height: 22px;
+                letter-spacing: 0.02em;
+                text-align: center;
+                color: rgba(0, 20, 40, 1);
+            }
         }
-      }
-      .light-name {
-        //styleName: Chi/Body Large;
-        margin-top: 12px;
-        font-family: PingFang SC;
-        width: 110px;
-        font-size: 16px;
-        font-weight: 300;
-        line-height: 22px;
-        letter-spacing: 0.02em;
-        text-align: center;
-        color: rgba(0, 20, 40, 1);
-      }
-    }
-    .right {
-      height: 92px;
-      display: flex;
-      flex-direction: column;
-      justify-content: space-between;
+        .right {
+            height: 92px;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-between;
 
-      .control {
-        width: 100px;
-        height: 40px;
-        line-height: 40px;
-        border-radius: 50px;
-        border-radius: 50px;
-        background: #e1e1df;
-        box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.05);
-        color: #001428;
-        //styleName: Chi/Body Small;
-        font-family: PingFang SC;
-        font-size: 12px;
-        font-weight: 400;
-        letter-spacing: 0.04em;
-        text-align: center;
-      }
-      .control.active {
-        background: rgba(255, 255, 255, 1);
-        box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
-      }
+            .control {
+                width: 100px;
+                height: 40px;
+                line-height: 40px;
+                border-radius: 50px;
+                border-radius: 50px;
+                background: #e1e1df;
+                box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.05);
+                color: #001428;
+                //styleName: Chi/Body Small;
+                font-family: PingFang SC;
+                font-size: 12px;
+                font-weight: 400;
+                letter-spacing: 0.04em;
+                text-align: center;
+            }
+            .control.active {
+                background: rgba(255, 255, 255, 1);
+                box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+            }
+        }
     }
-  }
-  .light-middle {
-    // height: 100px;
-    // background: #fff;
-    .bright-slider {
-      width: 100%;
-      height: 62px;
+    .light-middle {
+        // height: 100px;
+        // background: #fff;
+        .bright-slider {
+            width: 100%;
+            height: 62px;
 
-      background: rgba(255, 255, 255, 0.6);
-      margin-bottom: 12px;
-      border-radius: 12px;
+            background: rgba(255, 255, 255, 0.6);
+            margin-bottom: 12px;
+            border-radius: 12px;
+        }
+        .temp-slider {
+            width: 100%;
+            height: 58px;
+            padding: 2px;
+            border-radius: 12px;
+            background: var(--White-White-60, rgba(255, 255, 255, 0.6));
+            margin-bottom: 12px;
+        }
     }
-    .temp-slider {
-      width: 100%;
-      height: 58px;
-      padding: 2px;
-      border-radius: 12px;
-      background: var(--White-White-60, rgba(255, 255, 255, 0.6));
-      margin-bottom: 12px;
+    .divider {
+        height: 24px;
+        display: flex;
+        align-items: center;
+        margin-bottom: 12px;
     }
-  }
-  .divider {
-    height: 24px;
-    display: flex;
-    align-items: center;
-    margin-bottom: 12px;
-  }
-  .light-bottom {
-    // margin-top: 36px;
-    .item-box {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      width: 300px;
-      height: 68px;
-      box-sizing: border-box;
-      padding: 20px 24px;
-      border-radius: 24px 24px 44px 24px;
-      background: rgba(255, 255, 255, 0.2);
-      box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.05);
-      margin-bottom: 12px;
-      .name {
-        //styleName: Chi/Body Regular;
-        font-family: PingFang SC;
-        font-size: 14px;
-        font-weight: 400;
-        line-height: 19px;
-        letter-spacing: 0.02em;
-        color: rgba(0, 20, 40, 1);
-      }
+    .light-bottom {
+        // margin-top: 36px;
+        .item-box {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            width: 300px;
+            height: 68px;
+            box-sizing: border-box;
+            padding: 20px 24px;
+            border-radius: 24px 24px 44px 24px;
+            background: rgba(255, 255, 255, 0.2);
+            box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.05);
+            margin-bottom: 12px;
+            .name {
+                //styleName: Chi/Body Regular;
+                font-family: PingFang SC;
+                font-size: 14px;
+                font-weight: 400;
+                line-height: 19px;
+                letter-spacing: 0.02em;
+                color: rgba(0, 20, 40, 1);
+            }
+        }
+        .light-box-active {
+            background: rgba(255, 255, 255, 0.6);
+        }
     }
-    .light-box-active {
-      background: rgba(255, 255, 255, 0.6);
+    .switch-btn {
+        margin-top: 0;
+        width: 50px !important;
+        height: 28px !important;
+        border: none;
     }
-  }
-  .switch-btn {
-    margin-top: 0;
-    width: 50px !important;
-    height: 28px !important;
-    border: none;
-  }
 }
 </style>
 <style lang="scss">
 .more-box {
-  .van-loading__spinner {
-    color: $elActiveColor !important;
-  }
+    .van-loading__spinner {
+        color: $elActiveColor !important;
+    }
 
-  .van-switch__loading {
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    line-height: 1;
-  }
+    .van-switch__loading {
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        line-height: 1;
+    }
 
-  .van-switch--disabled {
-    opacity: 0.5;
-  }
+    .van-switch--disabled {
+        opacity: 0.5;
+    }
 }
 </style>

+ 1 - 1
src/views/envmonitor/taiguv1/const.js

@@ -3597,7 +3597,7 @@ export const ENV_CONFIG = {
     threshold: 800,
     unit: "ppm",
   },
-  TVOC: {
+  tvoc: {
     min: 0,
     max: 600,
     threshold: 500,

+ 5 - 5
src/views/envmonitor/taiguv1/index.vue

@@ -79,9 +79,9 @@
           <div class="item">
             <div class="title">TVOC</div>
             <div class="num-box">
-              <template v-if="envParams.TVOC">
-                <span>{{ envParams?.TVOC?.value }}</span>
-                <span>{{ $t(`env.${envParams?.TVOC?.level}`) }}</span>
+              <template v-if="envParams.tvoc">
+                <span>{{ envParams?.tvoc?.value }}</span>
+                <span>{{ $t(`env.${envParams?.tvoc?.level}`) }}</span>
               </template>
               <span v-else>--</span>
             </div>
@@ -270,12 +270,12 @@ const getSpaceInfo = () => {
     }).then(res => {
       if (res.result === 'success') {
         let [spaceInfo] = res.content
-        let { temperature, co2, pm25, TVOC, humidity } = spaceInfo || {}
+        let { temperature, co2, pm25, tvoc, humidity } = spaceInfo || {}
         envParams.value = {
           temperature,
           co2,
           pm25,
-          TVOC,
+          tvoc,
           humidity
         }
         // 获取环境参数