anxiaoxia 2 месяцев назад
Родитель
Сommit
7391552ac8
36 измененных файлов с 12359 добавлено и 6085 удалено
  1. 2 4
      package.json
  2. 2530 0
      public/project.config.js
  3. 49 0
      src/apis/taiguv1.js
  4. 5 0
      src/assets/svg/addCircle.svg
  5. 3 0
      src/assets/svg/line.svg
  6. 14 0
      src/assets/taiguv1/svg/room_aura_icon.svg
  7. 9 0
      src/assets/taiguv1/svg/room_eos_icon.svg
  8. 6 0
      src/assets/taiguv1/svg/room_gaia_icon.svg
  9. 13 0
      src/assets/taiguv1/svg/room_helios_icon.svg
  10. 6 0
      src/assets/taiguv1/svg/room_naiad_icon.svg
  11. BIN
      src/assets/taiguv1/svg/room_training_background.png
  12. 5 0
      src/assets/taiguv1/svg/room_training_icon.svg
  13. 141 0
      src/components/lamp-slider/LampSlider.vue
  14. 184 0
      src/components/slider/Slider.vue
  15. 69 0
      src/components/switch-button/SwitchButton.vue
  16. 2 2
      src/config/index.js
  17. 1 0
      src/config/index.ts
  18. 27 0
      src/hooks/useActiveIcon.js
  19. 11 21
      src/main.ts
  20. 21 21
      src/styles/index.scss
  21. 32 35
      src/utils/https.ts
  22. 328 0
      src/views/envmonitor/taiguv1/components/Air/AirMore.vue
  23. 0 695
      src/views/envmonitor/taiguv1/components/Air/index copy.vue
  24. 134 301
      src/views/envmonitor/taiguv1/components/Air/index.vue
  25. 61 67
      src/views/envmonitor/taiguv1/components/Curtain/CurtainMore.vue
  26. 51 55
      src/views/envmonitor/taiguv1/components/Curtain/index.vue
  27. 318 237
      src/views/envmonitor/taiguv1/components/Lamp/LightMore.vue
  28. 138 157
      src/views/envmonitor/taiguv1/components/Lamp/index.vue
  29. 11 15
      src/views/envmonitor/taiguv1/components/Screen/index.vue
  30. 28 297
      src/views/envmonitor/taiguv1/components/Volumn/index.vue
  31. 3548 483
      src/views/envmonitor/taiguv1/const.js
  32. 0 443
      src/views/envmonitor/taiguv1/index copy.vue
  33. 799 481
      src/views/envmonitor/taiguv1/index.vue
  34. 6 2
      tsconfig.json
  35. 81 75
      vue.config.js
  36. 3726 2694
      yarn.lock

+ 2 - 4
package.json

@@ -39,7 +39,7 @@
     "reflect-metadata": "^0.1.13",
     "tinymce": "5.6.2",
     "vant": "^3.4.5",
-    "vue": "^3.2.1",
+    "vue": "^3.5.13",
     "vue-class-component": "^8.0.0-0",
     "vue-draggable-next": "^2.0.1",
     "vue-image-crop-upload": "^2.5.0",
@@ -105,9 +105,7 @@
     "vue-jest": "^5.0.0-alpha.8",
     "webpackbar": "^5.0.0-3"
   },
-  "gitHooks": {
-    "pre-commit": "lint-staged"
-  },
+
   "lint-staged": {
     "*.{js,jsx,vue,ts,tsx}": [
       "vue-cli-service lint",

Разница между файлами не показана из-за своего большого размера
+ 2530 - 0
public/project.config.js


+ 49 - 0
src/apis/taiguv1.js

@@ -0,0 +1,49 @@
+import { duoduoenvService, envService } from '@/config'
+import { https } from '@/utils/https'
+import { ContentType, Method } from 'axios-mapper'
+
+const projectId = 'Pj3301050005'
+
+// 设备下发指令
+export const httpSetEnv = data => {
+  return https().httpClient.post(
+    `/server/ctrl/set?projectId=${projectId}`, // API 端点
+    data
+  )
+}
+
+// 获取空间预约模式
+export const httpGetByMeetingId = params => {
+  return https().request(
+    `/api/meetingBooking/getByMeetingId`, // API 端点
+    Method.GET,
+    params,
+    ContentType.json
+  )
+}
+
+// 获取环境参数
+export const HttpGetSpaceInfo = data => {
+  return https().request(
+    `/server/space/property`, // API 端点
+    Method.POST, // HTTP 方法
+    data, // 请求数据
+    ContentType.json // 内容类型
+  )
+}
+
+// 查询空调设备状态
+export const queryAirStatus = params => {
+  return https().request(
+    `${envService}/duoduoenv-service/ctrl/querySpaceConditioners`,
+    Method.GET,
+    params,
+    ContentType.json
+  )
+  // return https().request<any>(`${testApi}ctrl/querySpaceConditioners?${params}`, Method.GET, undefined, ContentType.json)
+}
+
+// 查询灯设备状态
+export const queryLampStatus = params => {
+  return https().request(`/server/light/status/query`, Method.GET, params, ContentType.json)
+}

+ 5 - 0
src/assets/svg/addCircle.svg

@@ -0,0 +1,5 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 17 17" fill="none">
+<path d="M8.5 0C3.80652 0 0 3.80652 0 8.5C0 13.1935 3.80652 17 8.5 17C13.1935 17 17 13.1935 17 8.5C17 3.80652 13.1935 0 8.5 0ZM8.5 16.2609C4.21304 16.2609 0.73913 12.787 0.73913 8.5C0.73913 4.21304 4.21304 0.73913 8.5 0.73913C12.787 0.73913 16.2609 4.21304 16.2609 8.5C16.2609 12.787 12.787 16.2609 8.5 16.2609Z" fill="#001428"/>
+<path d="M4.32324 8.67578H12.6754" stroke="#8E0003" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M8.5 4.5V12.8522" stroke="#8E0003" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 3 - 0
src/assets/svg/line.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="302" height="2" viewBox="0 0 302 2" fill="none">
+<path opacity="0.1" d="M1 1H301" stroke="black" stroke-opacity="0.8" stroke-linecap="round"/>
+</svg>

+ 14 - 0
src/assets/taiguv1/svg/room_aura_icon.svg

@@ -0,0 +1,14 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12.5963 12.0629L11.7666 12.8926L16.8192 17.9452L17.6489 17.1155L12.5963 12.0629Z" fill="white"/>
+<path d="M10.5845 9.70898H9.41113V10.8824H10.5845V9.70898Z" fill="white"/>
+<path d="M16.8182 22.6544L11.7656 27.707L12.5953 28.5367L17.6479 23.4841L16.8182 22.6544Z" fill="white"/>
+<path d="M10.5845 29.7051H9.41113V30.8785H10.5845V29.7051Z" fill="white"/>
+<path d="M27.411 12.0509L22.3584 17.1035L23.1881 17.9332L28.2407 12.8806L27.411 12.0509Z" fill="white"/>
+<path d="M20.5865 5H19.4131V19.121H20.5865V5Z" fill="white"/>
+<path d="M30.5884 9.70898H29.415V10.8824H30.5884V9.70898Z" fill="white"/>
+<path d="M18.8226 19.7109H0V20.8843H18.8226V19.7109Z" fill="white"/>
+<path d="M20.5865 21.4766H19.4131V35.5976H20.5865V21.4766Z" fill="white"/>
+<path d="M39.9994 19.7109H21.1768V20.8843H39.9994V19.7109Z" fill="white"/>
+<path d="M23.1793 22.6547L22.3496 23.4844L27.4022 28.537L28.2319 27.7073L23.1793 22.6547Z" fill="white"/>
+<path d="M30.5884 29.7051H29.415V30.8785H30.5884V29.7051Z" fill="white"/>
+</svg>

+ 9 - 0
src/assets/taiguv1/svg/room_eos_icon.svg

@@ -0,0 +1,9 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M36.6849 22.9694L25.2471 29.9336L25.921 31.0737L37.3588 24.1095L36.6849 22.9694Z" fill="white"/>
+<path d="M38.3335 33.2383H26.5498V34.5678H38.3335V33.2383Z" fill="white"/>
+<path d="M3.31549 22.9634L2.6416 24.1035L14.0794 31.0677L14.7533 29.9276L3.31549 22.9634Z" fill="white"/>
+<path d="M13.4507 33.2383H1.66699V34.5678H13.4507V33.2383Z" fill="white"/>
+<path d="M20.7163 3.33398H19.2783V27.2593H20.7163V3.33398Z" fill="white"/>
+<path d="M9.33932 12.0361L8.18164 12.6582L16.3626 28.3402L17.5203 27.7181L9.33932 12.0361Z" fill="white"/>
+<path d="M30.6693 12.0406L22.4883 27.7227L23.646 28.3448L31.827 12.6628L30.6693 12.0406Z" fill="white"/>
+</svg>

+ 6 - 0
src/assets/taiguv1/svg/room_gaia_icon.svg

@@ -0,0 +1,6 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M29.3309 32.6477L28.6999 33.6911L20.0044 28.4415L11.3009 33.6911L10.6699 32.6477L20.0044 27.0098L29.3309 32.6477Z" fill="white"/>
+<path d="M32.3318 27.6803L31.7009 28.7237L20.0044 21.6541L8.29987 28.7237L7.66895 27.6803L20.0044 20.2305L32.3318 27.6803Z" fill="white"/>
+<path d="M5.2989 23.7586L4.66797 22.7151L20.0044 13.4453L35.3327 22.7151L34.7018 23.7586L20.0044 14.877L5.2989 23.7586Z" fill="white"/>
+<path d="M38.3337 17.7396L37.7027 18.7912L20.0044 8.08965L2.29792 18.7912L1.66699 17.7396L20.0044 6.66602L38.3337 17.7396Z" fill="white"/>
+</svg>

+ 13 - 0
src/assets/taiguv1/svg/room_helios_icon.svg

@@ -0,0 +1,13 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M30.6492 4.90229L25.0469 12.6133L26.1506 13.4152L31.753 5.7042L30.6492 4.90229Z" fill="white"/>
+<path d="M30.6492 4.90229L25.0469 12.6133L26.1506 13.4152L31.753 5.7042L30.6492 4.90229Z" fill="white"/>
+<path d="M37.9125 14.1914L28.8477 17.1367L29.2692 18.4342L38.3341 15.4889L37.9125 14.1914Z" fill="white"/>
+<path d="M29.2683 23.013L28.8467 24.3105L37.9115 27.2559L38.3331 25.9584L29.2683 23.013Z" fill="white"/>
+<path d="M26.1438 28.036L25.04 28.8379L30.6424 36.5489L31.7461 35.747L26.1438 28.036Z" fill="white"/>
+<path d="M20.6768 30.25H19.3125V39.7813H20.6768V30.25Z" fill="white"/>
+<path d="M13.8426 28.0332L8.24023 35.7441L9.34396 36.546L14.9463 28.8351L13.8426 28.0332Z" fill="white"/>
+<path d="M10.7328 23.0176L1.66797 25.9629L2.08956 27.2604L11.1544 24.3151L10.7328 23.0176Z" fill="white"/>
+<path d="M2.08858 14.179L1.66699 15.4766L10.7318 18.4219L11.1534 17.1244L2.08858 14.179Z" fill="white"/>
+<path d="M9.34787 4.90317L8.24414 5.70508L13.8465 13.4161L14.9502 12.6142L9.34787 4.90317Z" fill="white"/>
+<path d="M20.6768 1.66602H19.3125V11.1973H20.6768V1.66602Z" fill="white"/>
+</svg>

Разница между файлами не показана из-за своего большого размера
+ 6 - 0
src/assets/taiguv1/svg/room_naiad_icon.svg


BIN
src/assets/taiguv1/svg/room_training_background.png


Разница между файлами не показана из-за своего большого размера
+ 5 - 0
src/assets/taiguv1/svg/room_training_icon.svg


+ 141 - 0
src/components/lamp-slider/LampSlider.vue

@@ -0,0 +1,141 @@
+<template>
+  <div class="slider-container" ref="slider-container">
+    <div class="slider-track">
+      <div
+        class="slider-thumb"
+        @touchstart="startDrag"
+        @touchmove="onDrag"
+        @touchend="endDrag"
+        ref="slider-thumb"
+        :style="{ left: `${thumbLeft}px` }"></div>
+    </div>
+    <!-- <div class="slider-value">{{ internalValue }}%</div> -->
+  </div>
+</template>
+
+<script setup>
+import { computed, defineModel, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
+
+const model = defineModel({ default: 50 })
+const internalValue = ref(model.value)
+const isDragging = ref(false)
+const sliderContainer = useTemplateRef('slider-container')
+const sliderThumb = useTemplateRef('slider-thumb')
+const max = ref(0)
+const min = ref(0)
+
+const touchstartPos = ref(0)
+const sliderThumbLeft = ref(0)
+const sliderContainerLeft = ref(0)
+let animationFrameId = null
+
+const thumbLeft = computed(() => {
+  return (internalValue.value / 100) * (max.value - min.value)
+})
+
+// 初始化滑块位置
+const initSlider = () => {
+  max.value = sliderContainer.value?.getBoundingClientRect().width
+  min.value = sliderThumb.value?.getBoundingClientRect().width
+  sliderContainerLeft.value = sliderContainer.value?.getBoundingClientRect().left
+}
+
+const startDrag = event => {
+  const touch = event.touches[0]
+  touchstartPos.value = touch.clientX
+  sliderThumbLeft.value = sliderThumb.value?.getBoundingClientRect().left
+  isDragging.value = true
+  initSlider()
+  onDrag(event)
+}
+
+const onDrag = event => {
+  if (!isDragging.value) return
+  const touch = event.touches[0]
+  const sliderRect = sliderContainer.value.getBoundingClientRect()
+  const maxRange = max.value - min.value
+
+  let offsetX = touch.clientX - touchstartPos.value + sliderThumbLeft.value - sliderContainerLeft.value
+  offsetX = Math.max(0, Math.min(offsetX, maxRange))
+
+  if (animationFrameId) {
+    cancelAnimationFrame(animationFrameId)
+  }
+  animationFrameId = requestAnimationFrame(() => {
+    model.value = internalValue.value = Math.round((offsetX / (max.value - min.value)) * 100)
+  })
+}
+const endDrag = () => {
+  isDragging.value = false
+  if (animationFrameId) {
+    cancelAnimationFrame(animationFrameId)
+  }
+}
+
+// 监听DOM插入
+let visibilityObserver = null
+// 监听DOM可见性
+const observeVisibility = () => {
+  const observer = new IntersectionObserver(entries => {
+    entries.forEach(entry => {
+      if (entry.isIntersecting) {
+        initSlider()
+      }
+    })
+  })
+
+  if (sliderContainer.value) {
+    observer.observe(sliderContainer.value)
+  }
+
+  return observer
+}
+
+onMounted(() => {
+  // 启动观察器
+  visibilityObserver = observeVisibility()
+})
+
+onUnmounted(() => {
+  // 清理观察器
+  visibilityObserver?.disconnect()
+})
+</script>
+
+<style scoped>
+.slider-container {
+  height: 100%;
+  width: 100%;
+  height: 100%;
+  width: 100%;
+  position: relative;
+  border-radius: 10px;
+  background: linear-gradient(93deg, #59c5ff 22.29%, #fff 48.81%, #ffb33a 75.32%);
+  cursor: pointer;
+}
+
+.slider-track {
+  height: 100%;
+  width: 100%;
+  position: relative;
+  cursor: pointer;
+}
+
+.slider-thumb {
+  position: absolute;
+  /* top: 2px; */
+  width: 54px;
+  height: 54px;
+  border-radius: 9px;
+  background: #fff;
+  flex-shrink: 0;
+  box-shadow: 0px 2px 7.7px 0px rgba(48, 16, 16, 0.25);
+  /* transform: translateX(-100%); 修改这里,使滑块右边缘对齐百分比位置 */
+}
+
+.slider-value {
+  margin-top: 10px;
+  text-align: center;
+  font-size: 14px;
+}
+</style>

+ 184 - 0
src/components/slider/Slider.vue

@@ -0,0 +1,184 @@
+<template>
+  <div class="slider-container" ref="slider-container">
+    <div class="slider-track">
+      <span class="slider-internalValue-text">{{ min }}</span>
+      <div
+        class="slider-progress"
+        :style="{ width: `${progressWidth}%` }"
+        @touchstart="startDrag"
+        @touchmove="onDrag"
+        @touchend="endDrag">
+        <span class="slider-progress-line"></span>
+      </div>
+      <span
+        class="slider-max-text"
+        :style="{ left: isFollow && progressWidth < 86 ? `calc(${progressWidth}% + 10px)` : 'auto', color: maxColor }"
+        >{{ showValue ? internalValue : max }}{{ suffix }}</span
+      >
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { computed, defineModel, defineProps, onMounted, ref, useTemplateRef } from 'vue'
+
+const emit = defineEmits(['onEnd', 'onStart'])
+const props = defineProps({
+  min: {
+    type: Number,
+    default: 0
+  },
+  max: {
+    type: Number,
+    default: 100
+  },
+  isFollow: {
+    type: Boolean,
+    default: false
+  },
+  suffix: {
+    type: String,
+    default: ''
+  },
+  showValue: {
+    type: Boolean,
+    default: false
+  }
+})
+
+const model = defineModel()
+
+const internalValue = ref(props.min)
+const isDragging = ref(false)
+let animationFrameId = null
+const sliderContainer = useTemplateRef('slider-container')
+
+const progressWidth = computed(() => {
+  const percentage = ((internalValue.value - props.min) / (props.max - props.min)) * 100
+  return `${Math.max(percentage, 10)}`
+})
+
+// const computedTrackBackground = computed(() => {
+//   const percentage = ((internalValue.value - props.min) / (props.max - props.min)) * 100
+//   return `linear-gradient(to right, #ff4d4f ${percentage}%, #e0e0e0 ${percentage}%)`
+// })
+
+const maxColor = computed(() => {
+  const percentage = ((internalValue.value - props.min) / (props.max - props.min)) * 100
+  return percentage >= 95 ? 'rgba(255, 255, 255, 0.6)' : 'rgb(116, 128, 141)'
+})
+
+const startDrag = event => {
+  isDragging.value = true
+  emit('onStart', internalValue.value)
+}
+
+const onDrag = event => {
+  if (!isDragging.value) return
+
+  const touch = event.touches[0]
+
+  const sliderRect = sliderContainer.value.getBoundingClientRect()
+
+  const offsetX = touch.clientX - sliderRect.left
+  //   console.log(touch, sliderRect, offsetX)
+  // 计算百分比并确保在 0 到 1 之间
+  const percentage = Math.min(Math.max(offsetX / sliderRect.width, 0), 1)
+  const newValue = Math.round(percentage * (props.max - props.min) + props.min)
+
+  // 更新 internalValue
+  if (animationFrameId) {
+    cancelAnimationFrame(animationFrameId)
+  }
+  animationFrameId = requestAnimationFrame(() => {
+    model.value = internalValue.value = newValue
+    // emit('update:modelValue', internalValue.value) // 确保使用正确的事件名称
+  })
+}
+const endDrag = () => {
+  isDragging.value = false
+  if (animationFrameId) {
+    cancelAnimationFrame(animationFrameId)
+  }
+  emit('onEnd')
+}
+
+onMounted(() => {
+  // 这里可以添加初始化逻辑
+})
+</script>
+
+<style scoped lang="scss">
+@mixin text-middle($left: auto, $right: auto) {
+  position: absolute;
+  top: 50%;
+  left: $left;
+  right: $right;
+  transform: translate(0, -50%);
+  font-size: 11px;
+  z-index: 6;
+  color: rgba(255, 255, 255, 0.6);
+  pointer-events: none;
+}
+
+.slider {
+  &-container {
+    position: relative;
+    box-sizing: border-box;
+    width: 100%;
+
+    height: 100%;
+    border-radius: 12px;
+    background: rgba(255, 255, 255, 0.6);
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  }
+  &-track {
+    position: absolute;
+    box-sizing: border-box;
+    width: calc(100% - 4px);
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+    /* padding: 2px; */
+    height: 100%; /* 设置轨道高度为 20px */
+    border-radius: 10px; /* 圆角 */
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: 1;
+  }
+  &-progress {
+    display: flex;
+    align-items: center;
+    color: rgba(255, 255, 255, 0.6);
+    padding: 0 6px;
+    font-size: 11px;
+    position: absolute;
+    background: linear-gradient(95.5deg, #99282b 21.44%, #a95459 84.95%);
+    left: 2px;
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: 1;
+    min-width: 4px;
+    height: calc(100% - 4px);
+    border-radius: 10px;
+    position: relative;
+    min-width: 30px;
+    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+    &-line {
+      position: absolute;
+      height: 12px;
+      width: 2px;
+      background: rgba(255, 255, 255, 0.8);
+      position: absolute;
+      right: 6px;
+      transform: translate(-50%, 0);
+      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+    }
+  }
+  &-internalValue-text {
+    @include text-middle(6px, auto);
+  }
+  &-max-text {
+    @include text-middle(auto, 10px);
+    color: rgb(116, 128, 141);
+  }
+}
+</style>

+ 69 - 0
src/components/switch-button/SwitchButton.vue

@@ -0,0 +1,69 @@
+<template>
+  <Switch
+    :size="size"
+    :inactive-color="inactiveColor"
+    :active-color="activeColor"
+    v-model="modelValue"
+    @click.stop
+    class="an-switch"
+    :loading="loading"
+    @change="handleSwitch" />
+</template>
+
+<script setup>
+import { Switch } from 'vant'
+
+const props = defineProps({
+  size: {
+    type: String,
+    default: '24px'
+  },
+  inactiveColor: {
+    type: String,
+    default: 'rgba(0, 0, 0, 0.3)'
+  },
+  activeColor: {
+    type: String,
+    default: ''
+  },
+  loading: {
+    type: Boolean,
+    default: false
+  }
+})
+const modelValue = defineModel('modelValue', {
+  type: Boolean,
+  default: false
+})
+
+const emit = defineEmits(['change'])
+const handleSwitch = () => {
+  emit('change', !modelValue.value)
+}
+</script>
+<style lang="scss" scoped>
+.an-switch {
+  padding: 1px 0;
+  // width: 46px;
+  // height: 24px;
+  &.van-switch--on {
+    background: linear-gradient(96deg, #99282b 21.44%, #a95459 84.95%);
+    :deep(.van-switch__node) {
+      top: 1px;
+      background: #fff;
+      // transform: translate(calc(var(--van-switch-width) - var(--van-switch-node-size) - 6px));
+    }
+  }
+  :deep(.van-switch__node) {
+    top: 1px;
+    // margin-left: 2px;
+    // width: 24px;
+    // height: 24px;
+    flex-shrink: 0;
+    background: #fff;
+    .van-loading__circular {
+      color: #99282b;
+    }
+  }
+}
+</style>

+ 2 - 2
src/config/index.js

@@ -1,4 +1,4 @@
-"use strict";
+'use strict'
 // // 默认配置
 // import {  netConfig, settingConfig, themeConfig } from './default'
 // // 自定义配置
@@ -6,4 +6,4 @@
 //
 // // 导出配置(自定义配置优先级高)
 // export default Object.assign({}, netConfig, settingConfig, themeConfig, customConfig)
-//# sourceMappingURL=index.js.map
+//# sourceMappingURL=index.js.map

+ 1 - 0
src/config/index.ts

@@ -9,6 +9,7 @@
 export const setupService = '/duoduo-service/setup-service/'
 export const objectService = '/duoduo-service/object-service/'
 export const duoduoenvService = '/duoduo-service/duoduoenv-service/'
+export const envService = '/duoduo-service'
 export const weachatService = '/duoduo-service/'
 export const customService = '/duoduo-service/custom-service/'
 export const ssoService = '/sso/'

+ 27 - 0
src/hooks/useActiveIcon.js

@@ -0,0 +1,27 @@
+
+import { useRoute } from 'vue-router'
+const GenerolModeIcon = require('@/assets/taiguv1/svg/GenerolMode_icon.svg')
+const VcModeIcon = require('@/assets/taiguv1/svg/VcMode_icon.svg')
+const YogaModeIcon = require('@/assets/taiguv1/svg/YogaMode_icon.svg')
+const RoadshowsIcon = require('@/assets/taiguv1/svg/Roadshows_icon.svg')
+const PrivateDiningIcon = require('@/assets/taiguv1/svg/PrivateDining_icon.svg')
+const OpenHouseIcon = require('@/assets/taiguv1/svg/OpenHouse_icon.svg')
+const CinemaIcon = require('@/assets/taiguv1/svg/Cinema_icon.svg')
+const PrivateAuctionIcon = require('@/assets/taiguv1/svg/PrivateAuction_icon.svg')
+const FoodTastingIcon = require('@/assets/taiguv1/svg/FoodTasting_icon.svg')
+const ProjectionIcon = require('@/assets/taiguv1/svg/Projection_icon.svg')
+const roomEosIcon = require('@/assets/taiguv1/svg/room_eos_icon.svg')
+const roomMetisIcon = require('@/assets/taiguv1/svg/meting_icon.svg')
+const roomNaiadIcon = require('@/assets/taiguv1/svg/room_naiad_icon.svg')
+const roomHeliosIcon = require('@/assets/taiguv1/svg/room_helios_icon.svg')
+const roomGaiaIcon = require('@/assets/taiguv1/svg/room_gaia_icon.svg')
+const roomAuraIcon = require('@/assets/taiguv1/svg/room_aura_icon.svg')
+
+const route = useRoute()
+const roomId = route.query.id
+
+const activeIcon = computed(() => {
+    return roomId === '1' ? GenerolModeIcon : VcModeIcon
+})
+
+export default activeIcon

+ 11 - 21
src/main.ts

@@ -1,16 +1,15 @@
-import { createApp } from 'vue'
-import App from './App.vue'
-import router from './router'
-import { store } from './store'
+import { createApp } from 'vue';
+import App from './App.vue';
+import router from './router';
+import { store } from './store';
 // import 'amfe-flexible' // rem 布局适配
 // import 'amfe-flexible/index.js'
-import '@/permission'
-import '@/styles/index.scss'
-import '@/utils/flexible.js'
-import 'default-passive-events'
-import { Icon, Loading, Popup, Tab, Tabs, Toast } from 'vant'
-import 'vant/lib/index.css'
-
+import '@/permission';
+import '@/styles/index.scss';
+import '@/utils/flexible.js';
+import 'default-passive-events';
+import { Icon, Loading, Popup, Tab, Tabs, Toast } from 'vant';
+import 'vant/lib/index.css';
 const app = createApp(App)
 
 // Toast.setDefaultOptions()
@@ -28,13 +27,4 @@ app.config.globalProperties.$fileUrl = 'http://api.sagacloud.cn/dp-auxiliary/ima
 app.config.globalProperties.$toast = Toast
 app.config.globalProperties.$loadingStart = loadingStart
 app.config.globalProperties.$loadinngEnd = loadinngEnd
-app
-  .use(Toast)
-  .use(Icon)
-  .use(Tabs)
-  .use(Tab)
-  .use(Loading)
-  .use(Popup)
-  .use(store)
-  .use(router)
-  .mount('#app')
+app.use(Toast).use(Icon).use(Tabs).use(Tab).use(Loading).use(Popup).use(store).use(router).mount('#app')

+ 21 - 21
src/styles/index.scss

@@ -184,42 +184,42 @@ div:focus {
   padding: 2.33vh 15px;
 }
 
-.van-switch--on {
-  background: $elActiveColor !important;
-}
+// .van-switch--on {
+// //   background: $elActiveColor !important;
+// }
 
 .switch-btn {
   margin-top: 2px;
   width: 48px !important;
   height: 24px !important;
 
-  .van-switch__node {
-    width: 24px !important;
-    height: 24px !important;
-  }
+//   .van-switch__node {
+//     width: 24px !important;
+//     height: 24px !important;
+//   }
 }
 
-.van-switch--on.switch-btn {
-  .van-switch__node {
-    transform: translate(calc(48px - 24px)) !important;
-  }
-}
+// .van-switch--on.switch-btn {
+//   .van-switch__node {
+//     transform: translate(calc(48px - 24px)) !important;
+//   }
+// }
 
 .child-switch {
   width: 33px !important;
   height: 16px !important;
 
-  .van-switch__node {
-    width: 16px !important;
-    height: 16px !important;
-  }
+//   .van-switch__node {
+//     width: 16px !important;
+//     height: 16px !important;
+//   }
 }
 
-.van-switch--on.child-switch {
-  .van-switch__node {
-    transform: translate(calc(33px - 16px)) !important;
-  }
-}
+// .van-switch--on.child-switch {
+// //   .van-switch__node {
+// //     transform: translate(calc(33px - 16px)) !important;
+// //   }
+// }
 
 .com-search {
   position: relative;

+ 32 - 35
src/utils/https.ts

@@ -1,18 +1,14 @@
-import { useStore } from '@/store'
-import HttpClient, { HttpClientConfig } from 'axios-mapper'
 import networkConfig from '@/config/default/net.config'
 import { getToken } from '@/utils/cookies'
-import { Toast } from 'vant'
-import Cookies from 'js-cookie'
-import { request } from 'http'
-import { getComparams, getUserInfo, setQueryConfig } from '.'
+import HttpClient, { HttpClientConfig } from 'axios-mapper'
+import { getUserInfo, setQueryConfig } from './index'
 
 export const https = (configobj: any = { timeout: '' }) => {
   // debugger
   let config: HttpClientConfig = {
     baseURL: networkConfig.host,
     headers: {
-      'token': getToken(),
+      token: getToken(),
       'sso-token': getToken(),
       'X-Forwarded-Token': getToken()
     }
@@ -21,21 +17,22 @@ export const https = (configobj: any = { timeout: '' }) => {
     config.timeout = configobj.timeout
   }
   const https = new HttpClient(config)
-  https.httpClient.interceptors.request.use(function (request) {
-    // debugger
-    let comInfo = getUserInfo()
-    // comInfo.projectId="Pj1101080255"
-    const comParams: string = setQueryConfig(comInfo)
-    let url: any = request.url
-    if (url.indexOf("?") != -1) {
-      request.url = request.url + "&" + comParams
-    } else {
-      request.url = request.url + "?" + comParams
-    }
-    return request
-  }, function (error) {
-
-  })
+  https.httpClient.interceptors.request.use(
+    function (request) {
+      // debugger
+      // let comInfo = getUserInfo()
+      // comInfo.projectId="Pj1101080255"
+      // const comParams: string = setQueryConfig(comInfo)
+      // let url: any = request.url
+      // if (url.indexOf('?') != -1) {
+      //   request.url = request.url + '&' + comParams
+      // } else {
+      //   request.url = request.url + '?' + comParams
+      // }
+      return request
+    },
+    function (error) {}
+  )
   // https.httpClient.interceptors.response.use(function (response) {
   //   return response
   // }, function (error) {
@@ -54,16 +51,19 @@ export const https = (configobj: any = { timeout: '' }) => {
 }
 
 export const post = (url: any, data: any) => {
-  return https().httpClient.post<Array<any>>(url, data).then(res => {
-    const resData: string = JSON.parse(JSON.stringify(res.data))
-    if (res.status >= 200 && res.status < 300) {
-      return Promise.resolve(resData)
-    } else {
-      return Promise.reject(resData)
-    }
-  }).catch(async error => {
-    return Promise.reject(error)
-  })
+  return https()
+    .httpClient.post<Array<any>>(url, data)
+    .then(res => {
+      const resData: string = JSON.parse(JSON.stringify(res.data))
+      if (res.status >= 200 && res.status < 300) {
+        return Promise.resolve(resData)
+      } else {
+        return Promise.reject(resData)
+      }
+    })
+    .catch(async error => {
+      return Promise.reject(error)
+    })
 }
 
 export const getUrlParams = (key: any = 'accessToken') => {
@@ -79,6 +79,3 @@ export const getUrlParams = (key: any = 'accessToken') => {
   let token: string = theRequest[key] || ''
   return token
 }
-
-
-

+ 328 - 0
src/views/envmonitor/taiguv1/components/Air/AirMore.vue

@@ -0,0 +1,328 @@
+<template>
+  <div class="more-box">
+    <div class="light-more-top">
+      <div class="left">
+        <div class="light-box">
+          <img
+            :src="LampsStatus === '全部关闭' ? lampCloseIcon : lampOpenIcon"
+            alt=""
+            :style="LampsStatus !== '全部关闭' ? { width: '58px', height: '62px' } : ''" />
+        </div>
+        <div class="light-name">{{ LampsStatus }}</div>
+      </div>
+      <div class="right">
+        <div class="control" :class="btnAllOpenActive ? 'active' : ''" @click="handleSwitch('allOpen')">全开</div>
+        <div class="control" :class="btnAllCloseActive ? 'active' : ''" @click="handleSwitch('allClose')">全关</div>
+      </div>
+    </div>
+    <div class="light-middle" v-if="LampsStatus !== '全部关闭'">
+      <div class="bright-slider">
+        <Slider v-model="allBrightValue" :isFollow="true" suffix="%" />
+      </div>
+      <div class="temp-slider">
+        <LampSlider v-model="allColorTempValue" />
+      </div>
+    </div>
+
+    <div class="divider">
+      <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 childLights">
+        <div class="name">{{ item.name }}</div>
+        <!-- <Switch
+                    class="switch-btn"
+                    inactive-color="rgba(0, 0, 0, 0.08)"
+                    v-model="item.valueSwitch"
+                    @click="handleChildLight(item)"
+                /> -->
+        <SwitchButton v-model="item.valueSwitch" @change="handleChildLight(item)" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import lampCloseIcon from '@/assets/taiguv1/svg/lamp_close_icon.svg'
+import lampOpenIcon from '@/assets/taiguv1/svg/lamp_open_p_icon.svg'
+import LampSlider from '@/components/lamp-slider/LampSlider.vue'
+import Slider from '@/components/slider/Slider.vue'
+import SwitchButton from '@/components/switch-button/SwitchButton.vue'
+import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
+
+const allBrightValue = ref(0)
+const allColorTempValue = ref(50)
+const btnAllCloseActive = ref(false)
+const btnAllOpenActive = ref(false)
+
+const emit = defineEmits(['statusChange'])
+const LampsStatus = ref('全部关闭')
+
+const childLights = ref([])
+
+const isHandlingSwitchOperation = ref(false)
+
+// 接收父组件传递的初始状态
+const props = defineProps({
+  initialStatus: {
+    type: Boolean,
+    default: false
+  },
+  currentLamps: {
+    type: Array,
+    default: () => []
+  }
+})
+
+const checkLampsStatus = () => {
+  const allOpen = childLights.value.every(item => item.valueSwitch)
+  const allClose = childLights.value.every(item => !item.valueSwitch)
+  if (allOpen) {
+    LampsStatus.value = '全部开启'
+    emit('statusChange', true, LampsStatus.value)
+    return
+  }
+  if (allClose) {
+    LampsStatus.value = '全部关闭'
+    emit('statusChange', false, LampsStatus.value)
+    return
+  }
+  LampsStatus.value = '部分开启'
+  emit('statusChange', true, LampsStatus.value)
+}
+
+let timer = null
+const handleSwitch = type => {
+  if (timer) {
+    clearTimeout(timer)
+  }
+  isHandlingSwitchOperation.value = true
+
+  if (type === 'allOpen') {
+    childLights.value.forEach(item => {
+      item.valueSwitch = true
+    })
+    btnAllOpenActive.value = true
+    btnAllCloseActive.value = false
+  } else {
+    childLights.value.forEach(item => {
+      item.valueSwitch = false
+    })
+    btnAllOpenActive.value = false
+    btnAllCloseActive.value = true
+  }
+  timer = setTimeout(() => {
+    btnAllOpenActive.value = false
+    btnAllCloseActive.value = false
+  }, 100)
+  checkLampsStatus()
+
+  const commands = []
+  childLights.value.forEach(item => {
+    const objName = {
+      id: item.id,
+      code: item.codeSwitch,
+      value: item.valueSwitch ? 1 : 0
+    }
+    commands.push(objName)
+  })
+  // httpSetEnv(commands);
+
+  setTimeout(() => {
+    isHandlingSwitchOperation.value = false
+  }, 0)
+}
+
+const handleChildLight = itemCurrent => {
+  childLights.value.forEach(item => {
+    if (item.id === itemCurrent.id) {
+      item.valueSwitch = itemCurrent.valueSwitch
+    }
+  })
+  checkLampsStatus()
+  const objName = {
+    id: itemCurrent.id,
+    code: itemCurrent.codeSwitch,
+    value: itemCurrent.valueSwitch ? 1 : 0
+  }
+  const commands = [objName]
+  // httpSetEnv(commands);
+}
+
+// 添加 watch 来监听 currentLamps 的变化
+watch(
+  () => props.currentLamps,
+  newVal => {
+    if (newVal && newVal.length > 0) {
+      childLights.value = JSON.parse(JSON.stringify(newVal))
+      // 场景切换了,需要设置环境
+      // setEnvMmode()
+    }
+  },
+  { immediate: true } // 确保组件初始化时执行
+)
+
+// 修改 watch,添加 immediate 属性以确保初始状态同步
+watch(
+  () => props.initialStatus,
+  newVal => {
+    if (LampsStatus.value === '部分开启' || isHandlingSwitchOperation.value) {
+      return
+    }
+    if (newVal) {
+      handleSwitch('allOpen')
+    } else {
+      handleSwitch('allClose')
+    }
+  },
+  { immediate: true }
+)
+
+onBeforeUnmount(() => {})
+onMounted(() => {})
+</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-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;
+
+      .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;
+
+      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;
+    }
+  }
+  .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-box-active {
+      background: rgba(255, 255, 255, 0.6);
+    }
+  }
+  .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-switch__loading {
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    line-height: 1;
+  }
+
+  .van-switch--disabled {
+    opacity: 0.5;
+  }
+}
+</style>

+ 0 - 695
src/views/envmonitor/taiguv1/components/Air/index copy.vue

@@ -1,695 +0,0 @@
-<template>
-  <div class="air">
-    <div class="air-top">
-      <Switch
-        class="switch-btn"
-        :size="23"
-        :loading="loadingAir || firstLoadingAir"
-        :disabled="!userIsControl || loadingAir || firstLoadingAir || disable"
-        inactive-color="rgba(196, 196, 196, 0.4)"
-        @click="airChange"
-        :model-value="airData.isOpen"
-        v-if="hasAir"
-      />
-    </div>
-    <!--温度调节-->
-    <div class="air-control">
-      <div class="control-title">温度调节</div>
-      <div class="btn-box">
-        <div class="control-btn mr20">
-          <img :src="parseImgUrl('envmonitor', 'arrow-top.png')" alt="" />
-        </div>
-        <div class="control-btn">
-          <img :src="parseImgUrl('envmonitor', 'arrow-down.png')" alt="" />
-        </div>
-      </div>
-    </div>
-    <div class="air-control">
-      <div class="control-title">风量调节</div>
-      <div class="btn-box">
-        <div class="control-btn mr20">
-          <img class="temp-img" :src="parseImgUrl('envmonitor', 'fengshan.png')" alt="" />
-        </div>
-        <div class="control-btn">
-          <img class="temp-img" :src="parseImgUrl('envmonitor', 'wendu.png')" alt="" />
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script lang="ts">
-import {
-  defineComponent,
-  onMounted,
-  reactive,
-  toRefs,
-  computed,
-  watch,
-  onUnmounted,
-  onBeforeMount,
-  onBeforeUnmount,
-} from "vue";
-import { Switch, Dialog, Loading, Toast } from "vant";
-import {
-  changeTempHttp,
-  getEquipmentListHttp,
-  getFeedbackDocumentsHttp,
-} from "@/apis/envmonitor";
-import { parseImgUrl } from "@/utils";
-import any = jasmine.any;
-
-export default defineComponent({
-  props: {
-    temperature: {
-      // 空调基本信息
-      type: Number,
-      default: () => 0,
-    },
-    hasAir: {
-      // 有无空调
-      type: Boolean,
-      default: () => false,
-    },
-    airVolumes: {
-      // 风量信息
-      type: Array,
-      default: () => [],
-    },
-    projectId: {
-      type: String,
-      default: () => "",
-    },
-    spaceId: {
-      type: String,
-      default: () => "",
-    },
-    userIsControl: {
-      type: Boolean,
-      default: () => false,
-    },
-    forceOverTimeFlag: {
-      type: Boolean,
-      default: () => false,
-    },
-    disable: {
-      type: Boolean,
-      default: () => false,
-    },
-  },
-  components: {
-    Switch,
-    [Dialog.Component.name]: Dialog.Component,
-    Loading,
-  },
-  setup(props, contx) {
-    const propsVal = props;
-    let airData: any = {
-      avg: "", // 算法调节温度(目标值)
-      icon: 1, // 固定框文案ID 7 为关机,其它都是开机
-      spaceStatus: "", // 固定框文案展示
-      notice: "", // 弹框文案展示
-      mode: 0, //  模式
-      tempSet: 0, // 温度
-      isOpen: false, // 空调开关 true 是开
-    };
-    const feedbackTimer: any = null;
-    const airTimer: any = null;
-    const domAirOpeen: any = false;
-    const proxyData = reactive({
-      loadingAir: false,
-      distroyFlag: false,
-      temperature: props.temperature,
-      userIsControl: props.userIsControl,
-      forceOverTimeFlag: props.forceOverTimeFlag,
-      firstLoadingAir: true,
-      spaceId: props.spaceId,
-      domAirOpeen: domAirOpeen,
-      feedbackTimer: feedbackTimer,
-      parseImgUrl: parseImgUrl,
-      airData: airData,
-      modeName: "",
-      showAirVolumeBtn: false, // 是否展示风量调节按钮
-      showDialog: false,
-      airTimer: airTimer,
-      airSetText: {
-        // 空调反馈文案
-        notice: "",
-        remark: [],
-        nowImg: "",
-        toWhere: "",
-        designTemperature: 0,
-      },
-      // 格式化模式
-      formateModel(model: any) {
-        if (model) {
-          if (model === 1) {
-            proxyData.modeName = "制冷";
-          } else if (model === 2) {
-            proxyData.modeName = "制热";
-          } else if (model === 3) {
-            proxyData.modeName = "通风";
-          } else if (model === 4) {
-            proxyData.modeName = "除湿";
-          } else {
-            proxyData.modeName = "";
-          }
-        } else {
-          proxyData.modeName = "";
-        }
-      },
-      // 获取设备类型(ACATVI)
-      getEquipmentListHttp() {
-        let params = {
-          spaceId: proxyData.spaceId,
-        };
-        proxyData.showAirVolumeBtn = false;
-        let flag: any = true;
-        getEquipmentListHttp(params).then((res) => {
-          let resData: any = res;
-          let data: any = resData ? resData.data : [];
-          if (data && data.length) {
-            for (let i = 0; i < data.length; i++) {
-              let item: any = data[i];
-              if (item.equipmentCategory === "ACATVI") {
-                // 多联机不展示风量调整
-                proxyData.showAirVolumeBtn = false;
-                flag = false;
-                break;
-              }
-            }
-            if (flag) {
-              proxyData.showAirVolumeBtn = true;
-            }
-          }
-        });
-      },
-      // 定时获取空调状态
-      getAirInfoToTimer(timerLong: any = 3000) {
-        if (proxyData.airTimer) {
-          clearTimeout(proxyData.airTimer);
-        }
-        proxyData.airTimer = setTimeout(function () {
-          if (!proxyData.distroyFlag) {
-            proxyData.getAirInfo();
-          }
-        }, timerLong);
-      },
-      // 定时调文案的接口
-      getFeedbackTimer(btnType: any, id: any) {
-        clearTimeout(proxyData.airTimer);
-        proxyData.airTimer = null;
-        proxyData.feedbackTimer = setTimeout(() => {
-          proxyData.getAirInfo("feedback", btnType, id, false); // 调节反馈文案
-        }, 3000);
-      },
-      // 关闭空调的按钮点击的loading状态
-      closeLoading() {
-        let num: any = 0;
-        let interval: any = setInterval(() => {
-          if (num > 15 || proxyData.domAirOpeen === proxyData.airData.isOpen) {
-            proxyData.loadingAir = false;
-            clearInterval(interval);
-          }
-          num++;
-        }, 1000);
-      },
-      getAirInfo(
-        type: string = "",
-        btnType: string = "",
-        feedbackId: any = "",
-        isTimer: boolean = true
-      ) {
-        let paramObj: any = {
-          projectId: propsVal.projectId, // 项目id
-          objectId: proxyData.spaceId, // 空间id
-        };
-
-        if (type === "feedback") {
-          paramObj.id = feedbackId;
-        }
-        console.log("paramObj===");
-        getFeedbackDocumentsHttp(paramObj)
-          .then((res) => {
-            const resData: any = res;
-            if (type !== "feedback") {
-              if (resData) {
-                proxyData.airData = resData;
-                proxyData.formateModel(proxyData.airData.mode);
-                contx.emit("updateAirTemp", proxyData.airData.tempSet);
-                if (proxyData.airData.icon && proxyData.airData.icon === 7) {
-                  proxyData.airData.isOpen = false;
-                  proxyData.airData.airImg = parseImgUrl(
-                    "page-officehome",
-                    "air_close.png"
-                  );
-                } else {
-                  if (proxyData.airData.icon && proxyData.airData.icon !== 6) {
-                    proxyData.airData.isOpen = true;
-                    proxyData.airData.airImg = parseImgUrl(
-                      "page-officehome",
-                      "openair.png"
-                    );
-                  }
-                }
-              }
-            }
-            //   弹窗
-            if (type === "feedback") {
-              if (resData.notice) {
-                proxyData.airSetText.notice = resData.notice;
-                if (resData.remark && resData.remark.length) {
-                  proxyData.airSetText.remark = resData.remark.split("*");
-                }
-                if (proxyData.feedbackTimer) {
-                  clearTimeout(proxyData.feedbackTimer); // 拿到反馈文案清除定时器
-                  proxyData.getAirInfoToTimer();
-                }
-              } else {
-                proxyData.getFeedbackTimer(btnType, feedbackId);
-              }
-            } else {
-              proxyData.getAirInfoToTimer();
-            }
-            proxyData.firstLoadingAir = false;
-          })
-          .catch(() => {
-            proxyData.getAirInfoToTimer();
-            proxyData.firstLoadingAir = false;
-            proxyData.airData.airImg = parseImgUrl("page-officehome", "air_close.png");
-          });
-      },
-      airChange() {
-        if (props.disable) {
-          return;
-        }
-        // 先不更新状态等确认框弹出后再更新状
-        if (proxyData.userIsControl) {
-          if (!proxyData.loadingAir) {
-            proxyData.airComfir();
-          } else {
-            Toast("指令正在下发中,勿重复操作!");
-          }
-        } else {
-          Toast("您没有当前空间的控制权限!");
-        }
-      },
-      // 确认
-      airComfir() {
-        const message = proxyData.airData.isOpen ? "要关闭空调吗?" : "要开启空调吗?";
-        const confirmBtnText = proxyData.airData.isOpen ? "关闭" : "开启";
-        Dialog.confirm({
-          cancelButtonText: "取消",
-          confirmButtonText: confirmBtnText,
-          confirmButtonColor: "$elActiveColor",
-          message: message,
-        })
-          .then(() => {
-            // 操作空调
-            const domAirOpen = !proxyData.airData.isOpen;
-            if (proxyData.forceOverTimeFlag && domAirOpen) {
-              //需要强制加班
-              contx.emit("triggerWork");
-              return;
-            }
-            const itemId = domAirOpen ? 12 : 10; // 12 开启 10关闭
-            proxyData.domAirOpeen = domAirOpen;
-            let btnTypeDetail = "";
-            if (itemId == 12) {
-              btnTypeDetail = "openAir";
-            } else {
-              btnTypeDetail = "closeAir";
-            }
-            proxyData.loadingAir = true;
-            proxyData.closeLoading();
-            proxyData.changeAir(itemId, "sw", btnTypeDetail);
-          })
-          .catch(() => {
-            // on cancel
-          });
-      },
-      // 切换散会的时候手动关闭空调()
-      closeScenarioAir() {
-        proxyData.changeAir(10, "sw", "closeAir");
-      },
-      // 更新空调开关状态
-      updatAirStatus(btnType: string) {
-        // 开启空调后手动调一下状态更新接口
-        if (btnType === "sw") {
-          proxyData.getAirInfo("", "", "", false);
-        }
-      },
-      // 更新
-      updateAirText(btnType: string, val: any) {
-        if (btnType !== "sw") {
-          proxyData.airSetText.designTemperature = val.designTemperature; // 目标温度
-          proxyData.airSetText.toWhere = val.toWhere;
-          if (proxyData.airSetText.toWhere == "toCold") {
-            proxyData.airSetText.nowImg = "dialog_cooling.svg";
-          } else if (proxyData.airSetText.toWhere == "toWarm") {
-            proxyData.airSetText.nowImg = "dialog_warmUp.svg";
-          } else {
-            proxyData.airSetText.nowImg = "icon_wind.svg";
-          }
-        }
-      },
-      // 展示空调反馈弹窗¬
-      showAirConditioning(btnType: string, btnTypeDetail: string) {
-        // 空调温度和风量调整的时候展示弹窗
-        if (btnType !== "sw") {
-          proxyData.showDialog = true;
-          // 调整空调温度接口
-          const defaultAirText: any = {
-            toWhere: btnTypeDetail,
-            designTemperature: 0,
-          };
-          proxyData.updateAirText(btnType, defaultAirText);
-        }
-      },
-      // 关闭弹窗
-      closeDialog() {
-        if (proxyData.feedbackTimer) {
-          clearInterval(proxyData.feedbackTimer); // 拿到反馈文案清除定时器
-          proxyData.feedbackTimer = null;
-        }
-        proxyData.getAirInfoToTimer();
-        proxyData.showDialog = false;
-      },
-      changeAir(itemId: number, btnType: string, btnTypeDetail: string) {
-        /**
-         * 缺少的逻辑:
-         * 1.设备位置判断
-         * 2.空调温度调整的反馈文案
-         */
-        // 温度切换的时候调整文案
-        proxyData.airSetText.notice = "";
-        proxyData.airSetText.remark = [];
-        const paramObj = {
-          projectId: propsVal.projectId, // 项目id
-          objectId: proxyData.spaceId, // 空间id
-          valueType: 1, // 固定为1
-          itemId: itemId, //    12 开启 10关闭  4 调低温  2 调高温 5 调小风量 6 调大风量
-        };
-        // 空调温度和风量调整的时候展示弹窗
-        proxyData.showAirConditioning(btnType, btnTypeDetail);
-        changeTempHttp(paramObj)
-          .then((res) => {
-            let resData: any = res;
-            // 开启和关闭空调之后手动
-            // proxyData.updatAirStatus(btnType)
-            // 调整温度和风量的时候修改文案
-            let airText = {
-              toWhere: btnTypeDetail,
-              designTemperature: resData.designTemperature,
-            };
-            proxyData.updateAirText(btnType, airText);
-            // 改变温度和风量的时候给弹窗设置文案
-            if (btnType !== "sw") {
-              // debugger
-              if (resData.notice) {
-                proxyData.airSetText.notice = resData.notice;
-                if (resData.remark && resData.remark.length) {
-                  proxyData.airSetText.remark = resData.remark.split("*");
-                }
-              } else {
-                proxyData.getFeedbackTimer(btnType, resData.id);
-              }
-            }
-          })
-          .catch(() => {
-            proxyData.loadingAir = false;
-          });
-      },
-    });
-    watch(
-      [() => props, () => props.spaceId],
-      (newProps: any, oldProps: any) => {
-        if (newProps[1] && newProps[1] != oldProps[1]) {
-          // 空间id改变的重新获取值调用接口
-          // 定时调空间信息
-          proxyData.spaceId = newProps[1];
-          proxyData.distroyFlag = false;
-          // proxyData.getAirInfoToTimer(0);
-          proxyData.getAirInfo();
-          // proxyData.getEquipmentListHttp();
-        }
-        if (newProps[0]) {
-          proxyData.temperature = newProps[0].temperature;
-          proxyData.userIsControl = newProps[0].userIsControl;
-          proxyData.forceOverTimeFlag = newProps[0].forceOverTimeFlag;
-        }
-      },
-      {
-        deep: false,
-        immediate: true,
-      }
-    );
-    onBeforeUnmount(() => {
-      proxyData.distroyFlag = true;
-      if (proxyData.airTimer) {
-        clearTimeout(proxyData.airTimer);
-        proxyData.airTimer = null;
-      }
-      if (proxyData.feedbackTimer) {
-        clearTimeout(proxyData.feedbackTimer);
-        proxyData.feedbackTimer = null;
-      }
-    });
-    onMounted(() => {
-      // 获取空调信息
-      proxyData.firstLoadingAir = true;
-      proxyData.distroyFlag = false;
-      proxyData.getAirInfo();
-      proxyData.getEquipmentListHttp();
-    });
-    const airRunImg = computed(() => {
-      let imgStr: string = "";
-      switch (proxyData.airData.icon) {
-        case 1:
-          imgStr = parseImgUrl("page-officehome", "temp-keep.png");
-          break;
-        case 2:
-          imgStr = parseImgUrl("page-officehome", "temp_cold.svg");
-          break;
-        case 3:
-          imgStr = parseImgUrl("page-officehome", "temp_sun.png");
-          break;
-        default:
-          imgStr = "";
-          break;
-      }
-      return imgStr;
-    });
-    return {
-      airRunImg,
-      ...toRefs(proxyData),
-    };
-  },
-});
-</script>
-<style lang="scss" scoped>
-.air {
-  box-sizing: border-box;
-  width: 364px;
-  height: 232px;
-  border-radius: 24px 24px 24px 50px;
-  box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
-  backdrop-filter: blur(40px);
-  background: rgba(255, 255, 255, 0.2);
-}
-
-.air-top {
-  padding-left: 20px;
-  padding-bottom: 10px;
-  display: flex;
-  justify-content: space-between;
-}
-
-.air-control {
-  display: flex;
-  justify-content: space-between;
-  padding: 10px 0;
-  padding-left: 28px;
-  padding-right: 15px;
-  border-top: 1px solid rgba(196, 196, 196, 0.4);
-
-  .control-title {
-    flex: 1;
-    line-height: 42px;
-    font-weight: 500;
-    font-size: 12px;
-    color: #c4c4c4;
-  }
-
-  .btn-box {
-    flex: 1;
-    text-align: right;
-  }
-
-  .control-btn {
-    display: inline-block;
-    vertical-align: middle;
-    width: 42px;
-    height: 42px;
-    text-align: center;
-    border-radius: 50%;
-    background: rgba(196, 196, 196, 0.2);
-
-    img {
-      width: 13px;
-      height: 17px;
-      margin: 0 auto;
-      margin-top: 12.5px;
-    }
-
-    .temp-img {
-      width: 20px;
-      height: 20px;
-    }
-  }
-}
-
-.dialog-width {
-  width: 280px !important;
-}
-
-.air-dialog-content {
-  position: relative;
-  width: 100%;
-  height: 340px;
-
-  .dialog-top {
-    position: relative;
-    height: 70px;
-    background: #f3f3f3;
-
-    .img-greey {
-      background: #c4c4c4;
-    }
-
-    .img-blue {
-      background: $elActiveColor;
-    }
-
-    .img-red {
-      background: #e5574f;
-    }
-
-    img {
-      box-sizing: border-box;
-      border-radius: 50%;
-      position: absolute;
-      left: 50%;
-      width: 70px;
-      height: 70px;
-      padding: 17px;
-      transform: translateX(-50%);
-      top: 15px;
-    }
-  }
-}
-
-.dialog-text {
-  padding-top: 52px;
-  text-align: center;
-
-  .air-temp-num {
-    font-family: Persagy;
-    display: inline-block;
-    font-size: 24px;
-    font-weight: 400;
-    line-height: 29px;
-    color: rgba(20, 0, 80, 1);
-
-    &.arrow-cooling {
-      color: $elActiveColor;
-      margin: 0 30px;
-      margin-bottom: 70px;
-    }
-
-    &.arrow-warn {
-      color: rgba(229, 87, 79, 1);
-      margin: 0 30px;
-      margin-bottom: 70px;
-    }
-  }
-
-  .air-temp-num-load {
-    display: inline-block;
-  }
-
-  .air-notice {
-    padding-top: 10px;
-    padding-left: 48px;
-    padding-right: 48px;
-    text-align: center;
-    // display: flex;
-    justify-content: center;
-    font-family: PingFang SC;
-    font-size: 15px;
-    font-weight: 400;
-    line-height: 21px;
-    color: rgba(77, 82, 98, 1);
-    span {
-      display: block;
-      padding-bottom: 5px;
-    }
-  }
-
-  .air-temp-load {
-    padding-top: 25px;
-  }
-
-  .air-body-item-num {
-    height: 50px;
-  }
-}
-
-.dialog-btns {
-  position: absolute;
-  left: 50%;
-  bottom: 30px;
-  transform: translateX(-50%);
-  text-align: center;
-  margin: 0 auto;
-  width: 88px;
-  height: 46px;
-  line-height: 1;
-  color: #4d5262;
-  background: #ffffff;
-  border: 1px solid #c4c4c4;
-  border-radius: 30px;
-  cursor: pointer;
-
-  span {
-    height: 46px;
-    line-height: 46px;
-    display: inline-block;
-  }
-}
-</style>
-<style lang="scss">
-.air-dialog-content {
-  .van-button_text {
-    color: $elActiveColor;
-  }
-}
-
-.air {
-  .van-loading__spinner {
-    color: $elActiveColor !important;
-  }
-
-  .van-switch__loading {
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    line-height: 1;
-  }
-
-  .van-switch--disabled {
-    opacity: 0.5;
-  }
-}
-</style>

+ 134 - 301
src/views/envmonitor/taiguv1/components/Air/index.vue

@@ -1,267 +1,162 @@
 <template>
-  <div class="volumn-box" :class="isOpen ? 'active' : ''">
+  <div class="volumn-box" :class="airData.isOpen ? 'active' : ''">
     <div class="top">
-      <img
-        :src="
-          parseImgUrl('taiguv1/envmonitor', isOpen ? 'active/air-con.svg' : 'air-con.svg')
-        "
-        alt=""
-      />
-      <div class="top-right">
-        <Switch
-          @change="getAirStatus"
-          class="switch-btn"
-          inactive-color="rgba(0, 0, 0, 0.3)"
-          v-model="isOpen"
-        />
-      </div>
+      <img :src="parseImgUrl('taiguv1/envmonitor', airData.isOpen ? 'active/air-con.svg' : 'air-con.svg')" alt="" />
+
+      <SwitchButton
+        :loading="airData.switchLoading"
+        @click.stop
+        @change="getAirStatus('isOpen')"
+        v-model="airData.isOpen" />
     </div>
     <div class="bottom">
       <div class="air-info">
         <div class="left">
           <div class="text">空调</div>
-          <div class="status">{{ isOpen ? "已开启" : "已关闭" }}</div>
+          <div class="status">{{ airData.isOpen ? '已开启' : '已关闭' }}</div>
         </div>
-        <div class="temp" v-if="isOpen">
-          {{ airData.airTemp }}
+        <div class="temp" v-if="airData.isOpen">
+          {{ airData.tempSet }}
           <sup>℃</sup>
         </div>
       </div>
       <!--温度⏭️-->
-      <div class="temp-box" id="sliderAirId" v-if="isOpen">
-        <div class="bar">
-          <div class="text text-left active-text">{{ airData.minTempSet }}</div>
-          <div class="active-bar" :style="{ width: barWidth + 'px' }" id="barAirId">
-            <div class="hand-box" id="handAirId">
-              <div class="line"></div>
-            </div>
-          </div>
-          <div class="text text-right" :class="isWhite ? 'active-text' : ''">
-            {{ airData.maxTempSet }}
-          </div>
-        </div>
+      <div class="temp-box" id="sliderAirId" v-if="airData.isOpen">
+        <Slider
+          v-model="airData.tempSet"
+          :min="airData.minTempSet"
+          :max="airData.maxTempSet"
+          @onEnd="getAirStatus('tempSet')"></Slider>
       </div>
 
       <!--风量调整-->
-      <div class="air-volume" v-if="isOpen">
+      <div class="air-volume" v-show="airData.isOpen">
         <div class="volume-left">
           <div class="volume-top">
-            <span :class="windNum === 1 ? 'span-active' : ''">1</span>
-            <span :class="windNum === 2 ? 'span-active' : ''">2</span>
-            <span :class="windNum === 3 ? 'span-active' : ''">3</span>
-            <span :class="windNum === 4 ? 'span-active' : ''">4</span>
+            <span :class="airData.gear == 0 ? 'span-active' : ''">0</span>
+            <span :class="airData.gear == 1 ? 'span-active' : ''">1</span>
+            <span :class="airData.gear == 2 ? 'span-active' : ''">2</span>
+            <span :class="airData.gear == 3 ? 'span-active' : ''">3</span>
           </div>
           <div class="text">风量调节</div>
         </div>
         <div class="volume-right">
-          <div class="control-item" @click="handle('minus')">
+          <div class="control-item" :ref="setRef" @click.prevent.stop="handle('minus')">
             <img class="icon" :src="parseImgUrl('taiguv1/envmonitor', 'minus.svg')" />
           </div>
-          <div class="control-item" @click="handle('plus')">
+          <div class="control-item" :ref="setRef" @click.prevent.stop="handle('plus')">
             <img class="icon" :src="parseImgUrl('taiguv1/envmonitor', 'plus.svg')" />
           </div>
-          <div class="control-item" @click="handle('auto')">A</div>
+          <div class="control-item" :class="airData.isAutoGear ? 'active' : ''" @click.prevent.stop="handle('auto')">
+            A
+          </div>
         </div>
       </div>
     </div>
   </div>
 </template>
 
-<script>
-import { fix, parseImgUrl } from "@/utils";
-import { swiper } from "@/utils/swiper";
-import { Dialog, Loading, Switch } from "vant";
-import {
-    defineComponent,
-    nextTick,
-    onBeforeUnmount,
-    onMounted,
-    reactive,
-    toRefs
-} from "vue";
+<script setup>
+import Slider from '@/components/slider/Slider.vue'
+import SwitchButton from '@/components/switch-button/SwitchButton.vue'
+import { parseImgUrl } from '@/utils'
+import { nextTick } from 'process'
+import { onMounted, ref, watch } from 'vue'
+const controlBtn = ref([])
+const setRef = el => {
+  console.log(el, 'el')
+  if (el) {
+    if (!controlBtn.value.includes(el)) {
+      controlBtn.value.push(el)
+    }
+  }
+}
 
-export default defineComponent({
-  components: {
-    Switch,
-    [Dialog.Component.name]: Dialog.Component,
-    Loading,
-  },
-  setup(props, contx) {
-    const proxyData = reactive({
-      parseImgUrl: parseImgUrl,
-      isOpen: false,
-      airData: {
+const props = defineProps({
+  status: {
+    type: Object,
+    default: function () {
+      return {
+        isOpen: false,
+        gear: 1,
         minTempSet: 16,
         maxTempSet: 32,
-        airTemp: 24,
-      },
-      part: 1,
-      realTemp: 24,
-      isWhite: false,
-      barWidth: 30,
-      windNum: 1,
-
-      handle(type){
-        if(type === 'minus'){
-            proxyData.windNum -= 1;
-            if(proxyData.windNum < 1){
-                proxyData.windNum = 1;
-            }
-        }else if(type === 'plus'){
-            proxyData.windNum += 1;
-            if(proxyData.windNum > 4){
-                proxyData.windNum = 4;
-            }
-        }else if(type === 'auto'){
-            proxyData.windNum = 4;
-        }
-        console.log('type==',type)
-      },
-      getAirStatus() {
-        if (proxyData.isOpen) {
-          nextTick(() => {
-            proxyData.endBoxSwiper();
-            proxyData.setBarNowPerstion();
-          });
-        }
-        contx.emit("getStatus", proxyData.isOpen);
-      },
-      getEleWidth(ele) {
-        // debugger;
-        if (ele) {
-          return ele.getBoundingClientRect().width;
-        } else {
-          return 1;
-        }
-      },
-      setBarNowPerstion() {
-        proxyData.realTemp = proxyData.airData.airTemp;
-        let barBox = document.querySelector("#barAirId");
-        if (!barBox) {
-          return;
-        }
-        let sliderBox = document.querySelector("#sliderAirId");
-        let sliderWidth = proxyData.getEleWidth(sliderBox);
-        if (
-          proxyData.airData.airTemp >= proxyData.airData.minTempSet &&
-          proxyData.airData.airTemp <= proxyData.airData.maxTempSet
-        ) {
-          let barWidth =
-            (proxyData.airData.airTemp - proxyData.airData.minTempSet) / proxyData.part;
-          // left = Math.floor(left);
-          if (barBox) {
-            barBox.style.width = barWidth + "px";
-          }
-        } else {
-          if (!proxyData.airData.airTemp) {
-            // barBox.style.width = 30 + "px";
-            proxyData.barWidth = 30;
-          } else if (proxyData.airData.airTemp < proxyData.airData.minTempSet) {
-            // barBox.style.width = 30 + "px";
-            proxyData.barWidth = 30;
-          } else if (proxyData.airData.airTemp > proxyData.airData.maxTempSet) {
-            let barWidth = barBox.offsetWidth;
-            // barBox.style.width = sliderWidth + "px";
-            proxyData.barWidth = barWidth;
-          }
-        }
-      },
-      endBoxSwiper() {
-        let sliderBox = document.querySelector("#sliderAirId");
-        let handBox = document.querySelector("#handAirId");
-        let barBox = document.querySelector("#barAirId");
-        let isMove = false;
-        let sliderWidth = proxyData.getEleWidth(sliderBox);
-        let startBarWidth = proxyData.getEleWidth(barBox);
-        if (sliderWidth > 1) {
-          sliderWidth = sliderWidth;
-        }
-        let tempPart =
-          (proxyData.airData.maxTempSet - proxyData.airData.minTempSet) /
-          (sliderWidth - 30);
-        let part = tempPart;
-        proxyData.part = part;
-        if (!handBox) {
-          return;
-        }
+        tempSet: 24,
+        isAutoGear: false,
+        switchLoading: false
+      }
+    }
+  },
+  equipList: {
+    type: Array,
+    default: function () {
+      return []
+    }
+  }
+})
 
-        handBox.addEventListener("touchstart", function (e) {
-          let oldBarWidth = (barBox && barBox.style && barBox.style.width) || 0;
-          startBarWidth = isNaN(parseInt(oldBarWidth)) ? 0 : parseInt(oldBarWidth);
-          isMove = true;
-        });
-        handBox.addEventListener("touchend", function (e) {
-          isMove = false;
-          proxyData.airData.airTemp = proxyData.realTemp;
-          //
-        });
-        swiper(handBox, {
-          swipeLeft: function (e) {
-            if (isMove) {
-              let moveRealX = Math.abs(e.mation.moveX - e.mation.startX);
-              moveRealX = parseInt(moveRealX);
-              let barWidth = startBarWidth - moveRealX;
-              barWidth = parseInt(barWidth);
-              barWidth = barWidth < 30 ? 30 : barWidth;
-              if (barWidth >= sliderWidth) {
-                proxyData.isWhite = true;
-              } else {
-                proxyData.isWhite = false;
-              }
+watch(
+  () => props.status,
+  (newVal, oldVal) => {
+    if (!newVal) {
+      return
+    }
+    console.log(newVal, 'newVal')
+    let { minTempSet, maxTempSet } = airData.value
+    airData.value = { ...newVal, minTempSet, maxTempSet }
+  }
+  // { deep: true } // 添加深度监听
+)
 
-              // barBox.style.width = barWidth + "px";
-              proxyData.barWidth = barWidth;
-              let realTemp = proxyData.airData.minTempSet + barWidth * part;
-              if (realTemp > proxyData.airData.maxTempSet) {
-                realTemp = proxyData.airData.maxTempSet;
-              }
-              if (realTemp) {
-                proxyData.realTemp = fix(realTemp.toFixed(1));
-              }
-              console.log("barWidth===", barWidth);
-              if (barWidth <= 30) {
-                proxyData.realTemp = 16;
-              }
-            }
-          },
-          swipeRight: function (e) {
-            if (isMove) {
-              let moveRealX = Math.abs(e.mation.moveX - e.mation.startX);
-              moveRealX = parseInt(moveRealX);
-              let barWidth = startBarWidth + moveRealX;
-              console.log("moveRealX==", moveRealX);
+const airData = ref({
+  isOpen: false,
+  gear: 1,
+  minTempSet: 16,
+  maxTempSet: 32,
+  tempSet: 16,
+  isAutoGear: false,
+  switchLoading: false
+})
 
-              barWidth = parseInt(barWidth);
-              barWidth = barWidth = barWidth > sliderWidth ? sliderWidth : barWidth;
-              if (barWidth >= sliderWidth) {
-                proxyData.isWhite = true;
-              } else {
-                proxyData.isWhite = false;
-              }
-              // barBox.style.width = barWidth + "px";
-              proxyData.barWidth = barWidth;
+const emit = defineEmits(['getStatus', 'restStatus'])
 
-              console.log("barWidth===", barWidth);
-              let realTemp = barWidth * part + proxyData.airData.minTempSet;
-              if (realTemp > proxyData.airData.maxTempSet) {
-                realTemp = proxyData.airData.maxTempSet;
-              }
-              if (realTemp) {
-                proxyData.realTemp = fix(realTemp.toFixed(1));
-              }
-            }
-          },
-        });
-      },
-    });
-    onBeforeUnmount(() => {});
-    onMounted(() => {});
+onMounted(() => {
+  nextTick(() => {
+    controlBtn.value.forEach(button => {
+      button.addEventListener('touchstart', () => {
+        button.classList.add('active')
+        setTimeout(() => {
+          button.classList.remove('active')
+        }, 200)
+      })
+    })
+  })
+})
+const handle = type => {
+  if (type === 'minus') {
+    airData.value.gear -= 1
+    if (airData.value.gear < 0) {
+      airData.value.gear = 0
+    }
+    airData.value.isAutoGear = false
+  } else if (type === 'plus') {
+    airData.value.gear += 1
+    if (airData.value.gear > 3) {
+      airData.value.gear = 3
+    }
+    airData.value.isAutoGear = false
+  } else if (type === 'auto') {
+    airData.value.isAutoGear = true
+  }
+  getAirStatus('gear')
+}
 
-    return {
-      ...toRefs(proxyData),
-    };
-  },
-});
+const getAirStatus = type => {
+  if (type == 'isOpen') {
+    airData.value.lastSwitchStatus = airData.value.isOpen
+  }
+  emit('getStatus', airData.value, type)
+}
 </script>
 <style lang="scss" scoped>
 .volumn-box {
@@ -279,8 +174,10 @@ export default defineComponent({
   .top {
     display: flex;
     justify-content: space-between;
+    align-items: center;
     img {
       width: 30px;
+      height: 30px;
     }
   }
   .bottom {
@@ -333,61 +230,11 @@ export default defineComponent({
       color: rgba(255, 255, 255, 0.4);
     }
     .temp-box {
-      position: relative;
-      box-sizing: border-box;
-      width: 100%;
-      padding: 2px;
       margin-top: 8px;
+      background: rgba(255, 255, 255, 0.6);
+      width: 100%;
       height: 34px;
       border-radius: 12px;
-      background: rgba(255, 255, 255, 0.6);
-      .text {
-        position: absolute;
-        top: 50%;
-        transform: translateY(-50%);
-        font-family: Jost;
-        font-size: 11px;
-        font-weight: 400;
-        line-height: 15px;
-        color: rgba(116, 128, 141, 1);
-        z-index: 2;
-      }
-      .text-left {
-        left: 8px;
-      }
-      .text-right {
-        right: 8px;
-      }
-      .active-text {
-        color: rgba(255, 255, 255, 0.6);
-      }
-      .active-bar {
-        position: absolute;
-        background: linear-gradient(95.5deg, #99282b 21.44%, #a95459 84.95%);
-        left: 2px;
-        top: 50%;
-        transform: translateY(-50%);
-        z-index: 1;
-        // width: 73px;
-        // min-width: 18px;
-        height: 30px;
-        border-radius: 10px;
-        .hand-box {
-          padding-left: 6px;
-          padding-right: 6px;
-          position: absolute;
-          top: 50%;
-          transform: translateY(-50%);
-          right: 0px;
-          height: 100%;
-        }
-        .line {
-          margin-top: 9px;
-          height: 12px;
-          width: 2px;
-          background: rgba(255, 255, 255, 0.8);
-        }
-      }
     }
   }
   .switch-btn {
@@ -453,9 +300,8 @@ export default defineComponent({
     .control-item {
       width: 36px;
       height: 36px;
-      opacity: 0.6;
       background: rgba(255, 255, 255, 0.4);
-      backdrop-filter: blur(60px);
+      // backdrop-filter: blur(15px);
       border-radius: 50%;
       text-align: center;
       .icon {
@@ -471,34 +317,21 @@ export default defineComponent({
         text-align: center;
         color: rgba(0, 20, 40, 1);
       }
-    }
-    .control-item.active {
-      opacity: 1;
+      &.active {
+        background: #fff;
+        box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+      }
+      // &:active,
+      // &:focus {
+      //   background: #fff;
+      //   box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+      // }
     }
   }
 }
 </style>
 <style lang="scss">
 .volumn-box {
-  .van-switch__node {
-    background: rgba(255, 255, 255, 0.6);
-    width: 24px;
-    height: 24px;
-    top: 0.33vh;
-    // top: 50%;
-    // transform: translateY(-50%);
-  }
-  .van-switch--on.switch-btn {
-    .van-switch__node {
-      transform: translate(calc(50px - 28px)) !important;
-    }
-  }
-  .van-switch--on {
-    background: linear-gradient(95.5deg, #99282b 21.44%, #a95459 84.95%) !important;
-    .van-switch__node {
-      background: #fff !important;
-    }
-  }
   .van-loading__spinner {
     color: $elActiveColor !important;
   }

+ 61 - 67
src/views/envmonitor/taiguv1/components/Curtain/CurtainMore.vue

@@ -13,12 +13,12 @@
                 <div
                     class="control_all"
                     :class="topActive ? 'active' : ''"
-                    @click="handle('all',1,'开启中')"
+                    @click="handle('all',1,'开启中','EquipOnSet')"
                 >全开</div>
                 <div
                     class="control_all"
                     :class="downActive ? 'active' : ''"
-                    @click="handle('all',0,'关闭中')"
+                    @click="handle('all',0,'关闭中','EquipOffSet')"
                 >全关</div>
             </div>
         </div>
@@ -33,17 +33,17 @@
                     <div
                         class="control"
                         :class="item.isActive && item.activeButton === 1 ? 'active' : ''"
-                        @click="handle('child',1,'开启中',item)"
+                        @click="handle('child',1,'开启中',item.id,'EquipOnSet')"
                     >上</div>
                     <div
                         class="control"
                         :class="item.isActive && item.activeButton === 2 ? 'active' : ''"
-                        @click="handle('child',2,'暂停中',item)"
+                        @click="handle('child',2,'暂停中',item.id,'EquipStopSet')"
                     >停</div>
                     <div
                         class="control"
                         :class="item.isActive && item.activeButton === 0 ? 'active' : ''"
-                        @click="handle('child',0,'关闭中',item)"
+                        @click="handle('child',0,'关闭中',item.id,'EquipOffSet')"
                     >下</div>
                 </div>
             </div>
@@ -53,28 +53,53 @@
 
 <script setup>
 import curtainIcon from '@/assets/taiguv1/svg/curtain_icon.svg';
-import { ref } from "vue";
-// const isOpen = ref(false)
+import { ref, watch } from "vue";
+const props = defineProps({
+    currentCurtains: {
+        type: Array,
+        default: () => []
+    }
+})
 const childCurtains = ref([
-    {
-        name: "内侧窗帘",
-        isActive: false,
-        activeButton: null,
-        id: 1
-    },
-    {
-        name: "外侧窗帘",
-        isActive: false,
-        activeButton: null,
-        id: 2
-    },
+    // {
+    //     name: "内侧窗帘",
+    //     isActive: false,
+    //     activeButton: null,
+    //     id: 1
+    // },
+    // {
+    //     name: "外侧窗帘",
+    //     isActive: false,
+    //     activeButton: null,
+    //     id: 2
+    // },
 ])
 const controlStatus = ref('')
 const topActive = ref(false)
 const downActive = ref(false)
 let timer = null // 添加timer变量
 let btnTimer = null;
-const handle = (type, status, name, itemCurrent) => {
+const setEnnv = (type,value,code,curentID )=>{
+    const paramsData = []
+    if (type === 'all') {
+        childCurtains.value.forEach((item) => {
+            paramsData.push({
+                id:item.id,
+                value,
+                code
+            })
+        })
+    }else{
+        let paramsObj = {
+            id:curentID,
+            value,
+            code
+        }
+        paramsData.push(paramsObj)
+    }
+    // httpSetEnv(paramsData)
+}
+const handle = (type, status, name,code, curentID) => {
     controlStatus.value = name;
     // 清除之前的定时器
     if (timer) {
@@ -97,12 +122,11 @@ const handle = (type, status, name, itemCurrent) => {
             topActive.value = false;
             downActive.value = false;
         }, 100);
-        childCurtains.value.forEach((item) => {
-            item.isActive = false; // 重置所有子窗帘的状态
-        })
+        setEnnv(type,status,code )
     } else {
+        setEnnv(type,status,code,curentID)
         childCurtains.value.forEach((item) => {
-            if (item.id === itemCurrent.id) {
+            if (item.id === curentID) {
                 item.activeButton = status;
                 item.isActive = true;
             } else {
@@ -118,6 +142,17 @@ const handle = (type, status, name, itemCurrent) => {
         }, 100);
     }
 };
+watch(
+   ()=>props.currentCurtains,
+   (newVal) => {
+    childCurtains.value = JSON.parse(JSON.stringify(newVal));
+    childCurtains.value.forEach(item=>{
+        item.isActive = false
+        item.activeButton = null
+    })  
+    },
+   { immediate: true } 
+)
 
 </script>
 <style lang="scss" scoped>
@@ -156,9 +191,8 @@ const handle = (type, status, name, itemCurrent) => {
                 align-items: center;
                 gap: 12px;
                 border-radius: 50px;
-                background: #dddddf;
+                background: #e1e1df;
                 box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.05);
-                backdrop-filter: blur(10px);
                 color: #001428;
                 text-align: center;
                 font-family: "PingFang SC";
@@ -243,46 +277,6 @@ const handle = (type, status, name, itemCurrent) => {
             background: rgba(255, 255, 255, 0.6);
         }
     }
-    .switch-btn {
-        margin-top: 0;
-        width: 50px !important;
-        height: 28px !important;
-        border: none;
-    }
-}
-</style>
-<style lang="scss">
-.more-box {
-    .van-switch__node {
-        background: rgba(255, 255, 255, 0.6);
-        width: 24px;
-        height: 24px;
-        top: 0.33vh;
-    }
-    .van-switch--on {
-        background: linear-gradient(
-            95.5deg,
-            #99282b 21.44%,
-            #a95459 84.95%
-        ) !important;
-        .van-switch__node {
-            background: #fff !important;
-        }
-    }
-    .van-loading__spinner {
-        color: $elActiveColor !important;
-    }
-
-    .van-switch__loading {
-        top: 0;
-        left: 0;
-        width: 100%;
-        height: 100%;
-        line-height: 1;
-    }
-
-    .van-switch--disabled {
-        opacity: 0.5;
-    }
 }
 </style>
+<

+ 51 - 55
src/views/envmonitor/taiguv1/components/Curtain/index.vue

@@ -23,7 +23,7 @@
                     <div
                         class="control-item"
                         :class="item.isActive ? 'active' : ''"
-                        @click.stop="handle(item.value, item.status)"
+                        @click.stop="handle(item.value, item.status,item.code)"
                     >{{ item.name }}</div>
                 </div>
             </div>
@@ -33,12 +33,12 @@
 
 <script setup>
 import { parseImgUrl } from "@/utils";
-import { onBeforeUnmount, onMounted, ref } from "vue";
+import { onBeforeUnmount, onMounted, ref, watch } from "vue";
 const controlStatus = ref('')
 const controlName = ref([
-    { isActive: false, name: '上', value: 1, status: '开启中' },
-    { isActive: false, name: '停', value: 2, status: '暂停中' },
-    { isActive: false, name: '下', value: 0, status: '关闭中' },
+    { isActive: false, name: '上', value: 1, status: '开启中', code: 'EquipOnSet' },
+    { isActive: false, name: '停', value: 2, status: '暂停中', code: 'EquipStop' },
+    { isActive: false, name: '下', value: 0, status: '关闭中', code: 'EquipOffSet' },
 ])
 const isOpen = ref(true)
 const isActive = ref(false)
@@ -48,8 +48,11 @@ const searchMore = () => {
 }
 let timer = null // 添加timer变量
 let btnTimer = null;
-const handle = (value, status) => {
+const curtainsList = ref([])
+const handle = (value, status, code) => {
     controlStatus.value = status;
+    // 下发指令
+    setEnv(value, code)
     if (btnTimer) {
         clearTimeout(btnTimer);
     }
@@ -62,8 +65,6 @@ const handle = (value, status) => {
         } else {
             item.isActive = false;
         }
-
-
     });
 
     if (timer) {
@@ -75,6 +76,46 @@ const handle = (value, status) => {
     }, 3000);
 
 }
+const props = defineProps({
+    currentCurtains: {
+        type: Array,
+        default: () => []
+    }
+})
+
+const setEnv = (value, code) => {
+    let paramsData = []
+    console.log(curtainsList,'窗帘1');
+    
+    curtainsList.value.forEach(item => {
+        paramsData.push({
+            id: item.id,
+            value,
+            code
+        })
+    })
+    // httpSetEnv(paramsData)
+}
+watch(
+    () => props.currentCurtains,
+    (newVal) => {
+        curtainsList.value = JSON.parse(JSON.stringify(newVal));
+        
+    },
+    { immediate: true }
+);
+watch(
+    () => props.modeType,
+    (newVal) => {
+        console.log(curtainsList.value,'窗帘数据');        
+        if (newVal) {
+            // httpSetEnv(curtainsList.value);
+        }
+        // 场景切换了,需要设置环境
+    },
+    { immediate: true }
+);
+
 onBeforeUnmount(() => { });
 onMounted(() => { });
 
@@ -95,13 +136,13 @@ onMounted(() => { });
     .top {
         display: flex;
         justify-content: space-between;
+        align-items: center;
         img {
             width: 30px;
+            height: 30px;
         }
     }
     .bottom {
-        // margin-top: 18vh;
-        // margin-top: 109px;
         .text {
             //styleName: Chi/Body Large;
             font-family: PingFang SC;
@@ -156,11 +197,6 @@ onMounted(() => { });
             }
         }
     }
-    .switch-btn {
-        width: 50px !important;
-        height: 28px !important;
-        border: none;
-    }
 }
 .active {
     background: rgba(255, 255, 255, 0.8);
@@ -177,43 +213,3 @@ onMounted(() => { });
     }
 }
 </style>
-<style lang="scss">
-.volumn-box {
-    .van-switch__node {
-        background: rgba(255, 255, 255, 0.6);
-        width: 24px;
-        height: 24px;
-        top: 0.33vh;
-    }
-    .van-switch--on.switch-btn {
-        .van-switch__node {
-            transform: translate(calc(50px - 28px)) !important;
-        }
-    }
-    .van-switch--on {
-        background: linear-gradient(
-            95.5deg,
-            #99282b 21.44%,
-            #a95459 84.95%
-        ) !important;
-        .van-switch__node {
-            background: #fff !important;
-        }
-    }
-    .van-loading__spinner {
-        color: $elActiveColor !important;
-    }
-
-    .van-switch__loading {
-        top: 0;
-        left: 0;
-        width: 100%;
-        height: 100%;
-        line-height: 1;
-    }
-
-    .van-switch--disabled {
-        opacity: 0.5;
-    }
-}
-</style>

+ 318 - 237
src/views/envmonitor/taiguv1/components/Lamp/LightMore.vue

@@ -1,277 +1,358 @@
 <template>
-    <div class="more-box">
-        <div class="light-more-top">
-            <div class="left">
-                <div class="light-box">
-                    <img
-                        :src="LampsStatus === '全部关闭' ?  lampCloseIcon:lampOpenIcon"
-                        alt=""
-                        :style="LampsStatus !== '全部关闭' ? {width: '58px',
-                            height: '62px'} : ''"
-                    />
-                </div>
-                <div class="light-name">{{ LampsStatus }}</div>
-            </div>
-            <div class="right">
-                <div
-                    class="control"
-                    @click="handleSwitch('allOpen')"
-                >全开</div>
-                <div
-                    class="control"
-                    @click="handleSwitch('allClose')"
-                >全关</div>
-            </div>
+  <div class="more-box">
+    <div class="light-more-top">
+      <div class="left">
+        <div class="light-box">
+          <img
+            :src="LampsStatus === '全部关闭' ? lampCloseIcon : lampOpenIcon"
+            alt=""
+            :style="LampsStatus !== '全部关闭' ? { width: '58px', height: '62px' } : ''" />
         </div>
-        <div
-            class="light-middle"
-            v-if="LampsStatus !== '全部关闭'"
-        >
-            <div>色温、亮度</div>
-        </div>
-        <div class="light-bottom">
-            <div
-                class="item-box"
-                :class="item.isOpen ? 'light-box-active ' : ''"
-                v-for="(item, index) in childLights"
-            >
-                <div class="name">{{ item.name }}</div>
-                <Switch
+        <div class="light-name">{{ LampsStatus }}</div>
+      </div>
+      <div class="right">
+        <div class="control" :class="btnAllOpenActive ? 'active' : ''" @click="handleSwitch('allOpen')">全开</div>
+        <div class="control" :class="btnAllCloseActive ? 'active' : ''" @click="handleSwitch('allClose')">全关</div>
+      </div>
+    </div>
+    <div class="light-middle" v-if="LampsStatus !== '全部关闭'">
+      <div class="bright-slider">
+        <Slider v-model="allBrightValue" :showValue="true" :isFollow="true" suffix="%" />
+      </div>
+      <div class="temp-slider">
+        <LampSlider v-model="allColorTempValue" />
+      </div>
+    </div>
+
+    <div class="divider">
+      <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 childLights">
+        <div class="name">{{ item.name }}</div>
+        <!-- <Switch
                     class="switch-btn"
                     inactive-color="rgba(0, 0, 0, 0.08)"
-                    v-model="item.isOpen"
+                    v-model="item.valueSwitch"
                     @click="handleChildLight(item)"
-                />
-            </div>
-        </div>
+                /> -->
+        <SwitchButton v-model="item.valueSwitch" @change="handleChildLight(item)" />
+      </div>
     </div>
+  </div>
 </template>
 
-<script setup lang="ts">
-import lampCloseIcon from "@/assets/taiguv1/svg/lamp_close_icon.svg";
-import lampOpenIcon from "@/assets/taiguv1/svg/lamp_open_p_icon.svg";
-import { Switch } from "vant";
-import { onBeforeUnmount, onMounted, ref, watch } from "vue";
+<script setup>
+import lampCloseIcon from '@/assets/taiguv1/svg/lamp_close_icon.svg'
+import lampOpenIcon from '@/assets/taiguv1/svg/lamp_open_p_icon.svg'
+import LampSlider from '@/components/lamp-slider/LampSlider.vue'
+import Slider from '@/components/slider/Slider.vue'
+import SwitchButton from '@/components/switch-button/SwitchButton.vue'
+import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
+
+const allBrightValue = ref(0)
+const allColorTempValue = ref(50)
+const btnAllCloseActive = ref(false)
+const btnAllOpenActive = ref(false)
+
+const emit = defineEmits(['statusChange'])
+const LampsStatus = ref('全部关闭')
 
-import any = jasmine.any;
+const childLights = ref([])
 
-const emit = defineEmits(['statusChange']);
-const LampsStatus = ref("全部关闭");
-const childLights = ref([
-    {
-        name: "主灯",
-        id: "1",
-        isOpen: false,
-    },
-    {
-        name: "氛围灯",
-        id: "2",
-        isOpen: false,
-    },
-    {
-        name: "吸顶灯",
-        id: "3",
-        isOpen: false,
-    },
-]);
+const isHandlingSwitchOperation = ref(false)
 
 // 接收父组件传递的初始状态
 const props = defineProps({
-    initialStatus: {
-        type: Boolean,
-        default: false
-    }
-});
+  initialStatus: {
+    type: Boolean,
+    default: false
+  },
+  currentLamps: {
+    type: Array,
+    default: () => []
+  }
+})
 
 const checkLampsStatus = () => {
-    const allOpen = childLights.value.every((item) => item.isOpen);
-    const allClose = childLights.value.every((item) => !item.isOpen);
-    if (allOpen) {
-        LampsStatus.value = "全部开启";
-        emit('statusChange', true);
-        return;
-    }
-    if (allClose) {
-        LampsStatus.value = "全部关闭";
-        emit('statusChange', false);
-        return;
+  const allOpen = childLights.value.every(item => item.valueSwitch)
+  const allClose = childLights.value.every(item => !item.valueSwitch)
+  if (allOpen) {
+    LampsStatus.value = '全部开启'
+    emit('statusChange', true, LampsStatus.value)
+    return
+  }
+  if (allClose) {
+    LampsStatus.value = '全部关闭'
+    emit('statusChange', false, LampsStatus.value)
+    return
+  }
+  LampsStatus.value = '部分开启'
+  emit('statusChange', true, LampsStatus.value)
+}
+
+let timer = null
+const handleSwitch = type => {
+  if (timer) {
+    clearTimeout(timer)
+  }
+  isHandlingSwitchOperation.value = true
+
+  if (type === 'allOpen') {
+    childLights.value.forEach(item => {
+      item.valueSwitch = true
+    })
+    btnAllOpenActive.value = true
+    btnAllCloseActive.value = false
+  } else {
+    childLights.value.forEach(item => {
+      item.valueSwitch = false
+    })
+    btnAllOpenActive.value = false
+    btnAllCloseActive.value = true
+  }
+  timer = setTimeout(() => {
+    btnAllOpenActive.value = false
+    btnAllCloseActive.value = false
+  }, 100)
+  checkLampsStatus()
+
+  const commands = []
+  childLights.value.forEach(item => {
+    const objName = {
+      id: item.id,
+      code: item.codeSwitch,
+      value: item.valueSwitch ? 1 : 0
     }
-    LampsStatus.value = "部分开启";
-    emit('statusChange', true);
-};
+    commands.push(objName)
+  })
+  // httpSetEnv(commands);
 
-const handleSwitch = (type) => {
-    if (type === "allOpen") {
-        childLights.value.forEach((item) => {
-            item.isOpen = true;
-        });
-    } else {
-        childLights.value.forEach((item) => {
-            item.isOpen = false;
-        });
+  setTimeout(() => {
+    isHandlingSwitchOperation.value = false
+  }, 0)
+}
+
+const handleChildLight = itemCurrent => {
+  childLights.value.forEach(item => {
+    if (item.id === itemCurrent.id) {
+      item.valueSwitch = itemCurrent.valueSwitch
     }
-    checkLampsStatus();
-};
+  })
+  checkLampsStatus()
+  const objName = {
+    id: itemCurrent.id,
+    code: itemCurrent.codeSwitch,
+    value: itemCurrent.valueSwitch ? 1 : 0
+  }
+  const commands = [objName]
+  // httpSetEnv(commands);
+}
 
-const handleChildLight = (itemCurrent: any) => {
-    childLights.value.forEach((item) => {
-        if (item.id === itemCurrent.id) {
-            item.isOpen = itemCurrent.isOpen;
-        }
-    });
-    checkLampsStatus();
-};
+const setEnvMmode = () => {
+  // 创建一个数组来存储所有需要设置的指令
+  const commands = []
+
+  childLights.value.forEach(item => {
+    // 开关指令
+    commands.push({
+      id: item.id,
+      code: item.codeSwitch,
+      value: item.valueSwitch
+    })
+
+    // 亮度指令
+    commands.push({
+      id: item.id,
+      code: item.codeBright,
+      value: item.valueBright
+    })
+
+    // 色温指令
+    commands.push({
+      id: item.id,
+      code: item.codeColorTemp,
+      value: item.valueColorTemp
+    })
+  })
+
+  // httpSetEnv(commands);
+}
+
+// 添加 watch 来监听 currentLamps 的变化
+watch(
+  () => props.currentLamps,
+  newVal => {
+    if (newVal && newVal.length > 0) {
+      childLights.value = JSON.parse(JSON.stringify(newVal))
+      // 场景切换了,需要设置环境
+      setEnvMmode()
+    }
+  },
+  { immediate: true } // 确保组件初始化时执行
+)
 
 // 修改 watch,添加 immediate 属性以确保初始状态同步
 watch(
-    () => props.initialStatus,
-    (newVal) => {
-        if ( LampsStatus.value === '部分开启' ) {
-            return;
-        }
-        if (newVal) {
-            handleSwitch('allOpen');
-        } else {
-            handleSwitch('allClose');
-        }
-    },
-    { immediate: true }
-);
+  () => props.initialStatus,
+  newVal => {
+    if (LampsStatus.value === '部分开启' || isHandlingSwitchOperation.value) {
+      return
+    }
+    if (newVal) {
+      handleSwitch('allOpen')
+    } else {
+      handleSwitch('allClose')
+    }
+  },
+  { immediate: true }
+)
 
-onBeforeUnmount(() => {});
-onMounted(() => {});
+onBeforeUnmount(() => {})
+onMounted(() => {})
 </script>
 <style lang="scss" scoped>
 .more-box {
-    .light-more-top {
-        display: flex;
-        align-items: center;
-        .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-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;
         }
-        .right {
-            height: 92px;
-            display: flex;
-            flex-direction: column;
-            justify-content: space-between;
+      }
+      .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;
 
-            .control {
-                width: 100px;
-                height: 40px;
-                line-height: 40px;
-                border-radius: 50px;
-                // background: #E1E1DF;
-                background: rgba(255, 255, 255, 0.2);
-                box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.05);
-                backdrop-filter: blur(10px);
-                color: #001428;
-                //styleName: Chi/Body Small;
-                font-family: PingFang SC;
-                font-size: 12px;
-                font-weight: 400;
-                letter-spacing: 0.04em;
-                text-align: center;
-            }
-        }
+      .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;
+  }
+  .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;
     }
-    .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);
-        }
+    .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;
+  }
+  .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);
+      }
     }
-    .switch-btn {
-        margin-top: 0;
-        width: 50px !important;
-        height: 28px !important;
-        border: none;
+    .light-box-active {
+      background: rgba(255, 255, 255, 0.6);
     }
+  }
+  .switch-btn {
+    margin-top: 0;
+    width: 50px !important;
+    height: 28px !important;
+    border: none;
+  }
 }
 </style>
 <style lang="scss">
 .more-box {
-    .van-switch__node {
-        background: rgba(255, 255, 255, 0.6);
-        width: 24px;
-        height: 24px;
-        top: 0.33vh;
-    }
-    .van-switch--on {
-        background: linear-gradient(
-            95.5deg,
-            #99282b 21.44%,
-            #a95459 84.95%
-        ) !important;
-        .van-switch__node {
-            background: #fff !important;
-        }
-    }
-    .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>

+ 138 - 157
src/views/envmonitor/taiguv1/components/Lamp/index.vue

@@ -1,195 +1,176 @@
 <template>
-    <div
-        class="volumn-box"
-        :class="isOpen ? 'active' : ''"
-        @click="searchMore"
-    >
-        <div class="top">
-            <img
-                :src="parseImgUrl('taiguv1/envmonitor', isOpen ? 'active/lamp.svg' : 'lamp.svg')"
-                alt=""
-            />
-            <div class="top-right">
-                <Switch
-                    class="switch-btn"
-                    inactive-color="rgba(0, 0, 0, 0.3)"
-                    v-model="isOpen"
-                    @click.stop="handleSwitch"
-                />
-            </div>
+  <div class="volumn-box" :class="isOpen ? 'active' : ''" @click="searchMore">
+    <div class="top">
+      <img :src="parseImgUrl('taiguv1/envmonitor', isOpen ? 'active/lamp.svg' : 'lamp.svg')" alt="" />
+      <div class="top-right">
+        <SwitchButton v-model="isOpen" @change="handleSwitch" />
+      </div>
+    </div>
+    <div class="bottom">
+      <div class="bottom-box">
+        <div class="bottom-left">
+          <div class="text">光照</div>
+          <div class="status">{{ lampStatusText }}</div>
         </div>
-        <div class="bottom">
-            <div class="text">光照</div>
-            <div class="status">{{ isOpen ? "已开启" : "已关闭" }}</div>
-            <div
-                v-if="isOpen"
-                class="right"
-            ></div>
+
+        <div class="bottom-right" v-if="isOpen">
+          {{ lampValue }}
         </div>
+      </div>
+
+      <div class="lamp-slider" v-if="isOpen">
+        <Slider v-model="lampValue"></Slider>
+      </div>
+
+      <!-- <Slider v-model="lampValue"></Slider> -->
     </div>
+  </div>
 </template>
 
 <script setup>
-import { parseImgUrl } from "@/utils";
-import { Switch } from "vant";
-import {
-    onBeforeUnmount,
-    onMounted,
-    ref,
-    watch
-} from "vue";
+import Slider from '@/components/slider/Slider.vue'
+import SwitchButton from '@/components/switch-button/SwitchButton.vue'
+import { parseImgUrl } from '@/utils'
+import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
 
 const isOpen = ref(false)
 const emit = defineEmits(['showMore', 'switchChange'])
+const lampValue = ref(0)
 
 const searchMore = () => {
-    emit("showMore", "lamp", true);
+  emit('showMore', 'lamp', true)
 }
-
+const childStatus = ref('')
 const handleSwitch = () => {
-    // 发送开关状态变化事件到父组件
-    emit("switchChange", isOpen.value);
+  // 发送开关状态变化事件到父组件
+  emit('switchChange', isOpen.value)
 }
 
 // 接收父组件传递的开关状态
 const props = defineProps({
-    switchStatus: {
-        type: Boolean,
-        default: false
+  lampStatusText: {
+    type: String,
+    default: () => '全部关闭'
+  },
+  lampStaus: {
+    type: Object,
+    default: () => {
+      return {
+        isOpen: false,
+        gear: 1,
+        minTempSet: 16,
+        maxTempSet: 32,
+        tempSet: 24,
+        isAutoGear: false,
+        switchLoading: false
+      }
     }
+  }
 })
 
-// 监听父组件传递的状态变化
 watch(
-    () => props.switchStatus,
-    (newVal) => {
-        isOpen.value = newVal;
-    },
-    { immediate: true }
-);
-
-onBeforeUnmount(() => { });
-onMounted(() => { });
-
+  () => props.lampStatusText,
+  newVal => {
+    childStatus.value = newVal
+  },
+  { immediate: true }
+)
 </script>
 <style lang="scss" scoped>
 .volumn-box {
-    box-sizing: border-box;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  padding: 16px;
+  width: 100%;
+  height: 100%;
+  border-radius: 24px 24px 44px 24px;
+  background-color: rgba(255, 255, 255, 0.2);
+  backdrop-filter: blur(40px);
+  box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+  .top {
     display: flex;
-    flex-direction: column;
     justify-content: space-between;
-    padding: 16px;
-    width: 100%;
-    height: 100%;
-    border-radius: 24px 24px 44px 24px;
-    background-color: rgba(255, 255, 255, 0.2);
-    backdrop-filter: blur(40px);
-    box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
-    .top {
-        display: flex;
-        justify-content: space-between;
-        img {
-            width: 30px;
-        }
-    }
-    .bottom {
-        // margin-top: 18vh;
-        position: relative;
-        // margin-top: 109px;
-        .text {
-            //styleName: Chi/Body Large;
-            font-family: PingFang SC;
-            font-size: 16px;
-            font-weight: 300;
-            line-height: 22px;
-            letter-spacing: 0.02em;
-            text-align: left;
-            text-underline-position: from-font;
-            text-decoration-skip-ink: none;
-            color: rgba(255, 255, 255, 1);
-            padding-bottom: 2px;
-        }
-        .status {
-            //styleName: Chi/Body XS;
-            font-family: PingFang SC;
-            font-size: 11px;
-            font-weight: 400;
-            line-height: 15px;
-            letter-spacing: 0.02em;
-            color: rgba(255, 255, 255, 0.4);
-        }
-        .right {
-            display: flex;
-            width: 133px;
-            height: 30px;
-            padding: 2px;
-            align-items: center;
-            gap: 10px;
-            background: rgba(111, 26, 26, 0.4);
-        }
-    }
-    .switch-btn {
-        margin-top: 0;
-        width: 50px !important;
-        height: 28px !important;
-        border: none;
-    }
-}
-.active {
-    background: rgba(255, 255, 255, 0.8);
-    backdrop-filter: blur(40px);
-    box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
-
-    .bottom {
-        .text {
-            color: rgba(0, 20, 40, 1);
-        }
-        .status {
-            color: rgba(116, 128, 141, 1);
-        }
+    align-items: center;
+    img {
+      width: 30px;
+      height: 30px;
     }
-    .right {
-        background: rgba(255, 255, 255, 0.4);
+  }
+  .bottom {
+    .bottom-box {
+      flex: 1;
+      display: flex;
+      justify-content: space-between;
     }
-}
-</style>
-<style lang="scss">
-.volumn-box {
-    .van-switch__node {
-        background: rgba(255, 255, 255, 0.6);
-        width: 24px;
-        height: 24px;
-        top: 0.33vh;
+    .text {
+      width: 100%;
+      //styleName: Chi/Body Large;
+      font-family: PingFang SC;
+      font-size: 16px;
+      font-weight: 300;
+      line-height: 22px;
+      letter-spacing: 0.02em;
+      text-align: left;
+      text-underline-position: from-font;
+      text-decoration-skip-ink: none;
+      color: rgba(255, 255, 255, 1);
+      padding-bottom: 2px;
     }
-    .van-switch--on.switch-btn {
-        .van-switch__node {
-            transform: translate(calc(50px - 28px)) !important;
-        }
+    .status {
+      width: 100%;
+      //styleName: Chi/Body XS;
+      font-family: PingFang SC;
+      font-size: 11px;
+      font-weight: 400;
+      line-height: 14px;
+      letter-spacing: 0.02em;
+      color: rgba(255, 255, 255, 0.4);
     }
-    .van-switch--on {
-        background: linear-gradient(
-            95.5deg,
-            #99282b 21.44%,
-            #a95459 84.95%
-        ) !important;
-        .van-switch__node {
-            background: #fff !important;
-        }
+    .bottom-right {
+      text-align: center;
+      font-size: 20px;
+      width: 50px;
+      height: 30px;
+      // color: var(--Blue, #001428);
+      align-self: end;
+      line-height: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: end;
     }
-    .van-loading__spinner {
-        color: $elActiveColor !important;
+    .lamp-slider {
+      margin-top: 8px;
+      background: rgba(255, 255, 255, 0.6);
+      width: 100%;
+      height: 34px;
+      border-radius: 12px;
     }
+  }
+  // .switch-btn {
+  //     // margin-top: 0;
+  //     // width: 50px !important;
+  //     // height: 28px !important;
+  //     // border: none;
+  // }
+}
+.active {
+  background: rgba(255, 255, 255, 0.8);
+  backdrop-filter: blur(40px);
+  box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
 
-    .van-switch__loading {
-        top: 0;
-        left: 0;
-        width: 100%;
-        height: 100%;
-        line-height: 1;
+  .bottom {
+    .text {
+      color: rgba(0, 20, 40, 1);
     }
-
-    .van-switch--disabled {
-        opacity: 0.5;
+    .status {
+      color: rgba(116, 128, 141, 1);
+    }
+    .bottom-right {
+      font-family: Jost;
+      color: rgba(0, 20, 40, 1);
     }
+  }
 }
 </style>

+ 11 - 15
src/views/envmonitor/taiguv1/components/Screen/index.vue

@@ -11,10 +11,10 @@
       <div class="btn" :class="type == 1 ? 'btn-active' : ''" @click="checkMode(1)">
         有线投屏
       </div>
-      <div class="btn" :class="type == 2 ? 'btn-active' : ''" @click="checkMode(2)">
+      <div class="btn" :class="type == '2' ? 'btn-active' : ''" @click="checkMode('2')">
         无线投屏
       </div>
-      <div class="btn" :class="type == 3 ? 'btn-active' : ''" @click="checkMode(3)">
+      <div class="btn" :class="type == '3' ? 'btn-active' : ''" @click="checkMode('3')">
         Team Room
       </div>
     </div>
@@ -22,19 +22,15 @@
 </template>
 
 <script>
+import { parseImgUrl } from "@/utils";
+import { Dialog, Loading, Switch } from "vant";
 import {
-  defineComponent,
-  onMounted,
-  reactive,
-  toRefs,
-  computed,
-  watch,
-  onUnmounted,
-  onBeforeMount,
-  onBeforeUnmount,
+    defineComponent,
+    onBeforeUnmount,
+    onMounted,
+    reactive,
+    toRefs
 } from "vue";
-import { Switch, Dialog, Loading, Toast } from "vant";
-import { parseImgUrl } from "@/utils";
 
 export default defineComponent({
   components: {
@@ -44,8 +40,8 @@ export default defineComponent({
   },
   props: {
     modeType: {
-      type: Number,
-      default: 1,
+      type: String,
+      default: '1',
     },
   },
   setup(props, contx) {

+ 28 - 297
src/views/envmonitor/taiguv1/components/Volumn/index.vue

@@ -1,226 +1,42 @@
 <template>
   <div class="volumn-box" :class="isOpen ? 'active' : ''">
     <div class="top">
-      <img
-        :src="isOpen ? speakerIcon : speakerCloseIcon"
-        alt=""
-      />
-      <div class="top-right">
-        <Switch
-          @change="getvolumnStatus"
-          class="switch-btn"
-          inactive-color="rgba(0, 0, 0, 0.3)"
-          v-model="isOpen"
-        />
-      </div>
+      <img :src="isOpen ? speakerIcon : speakerCloseIcon" alt="" />
+      <!-- <div class="top-right"> -->
+        <!-- <Switch @change="getvolumnStatus" class="switch-btn" inactive-color="rgba(0, 0, 0, 0.3)" v-model="isOpen" /> -->
+        <SwitchButton @change="getvolumnStatus" v-model="isOpen" />
+      <!-- </div> -->
     </div>
     <div class="bottom">
       <div class="volumn-info">
         <div class="left">
           <div class="text">音量</div>
-          <div class="status">{{ isOpen ? "播放中" : "已关闭" }}</div>
+          <div class="status">{{ isOpen ? '播放中' : '已关闭' }}</div>
         </div>
-        <div class="temp" v-if="isOpen">{{ volumnData.volumnTemp }}</div>
+        <div class="temp" v-if="isOpen">{{ volumnValue }}</div>
       </div>
-      <div class="temp-box" id="slidervolumnId" v-if="isOpen">
-        <div class="bar">
-          <div class="text text-left active-text">{{ volumnData.minTempSet }}</div>
-          <div class="active-bar" :style="{ width: barWidth + 'px' }" id="barvolumnId">
-            <div class="hand-box" id="handvolumnId">
-              <div class="line"></div>
-            </div>
-          </div>
-          <div class="text text-right" :class="isWhite ? 'active-text' : ''">
-            {{ volumnData.maxTempSet }}
-          </div>
-        </div>
+
+      <div class="volumn-slider" v-if="isOpen">
+        <Slider v-model="volumnValue" ></Slider>
       </div>
     </div>
   </div>
 </template>
 
-<script>
-import speakerCloseIcon from "@/assets/taiguv1/svg/speaker_close_icon.svg";
-import speakerIcon from "@/assets/taiguv1/svg/speaker_icon.svg";
-import { fix, parseImgUrl } from "@/utils";
-import { swiper } from "@/utils/swiper";
-import { Dialog, Loading, Switch } from "vant";
-import {
-    defineComponent,
-    nextTick,
-    onBeforeUnmount,
-    onMounted,
-    reactive,
-    toRefs
-} from "vue";
-
-export default defineComponent({
-  components: {
-    Switch,
-    [Dialog.Component.name]: Dialog.Component,
-    Loading,
-  },
-  setup(props, contx) {
-    const proxyData = reactive({
-      parseImgUrl: parseImgUrl,
-      speakerIcon: speakerIcon,
-      speakerCloseIcon: speakerCloseIcon,
-      isOpen: false,
-      volumnData: {
-        minTempSet: 0,
-        maxTempSet: 100,
-        volumnTemp: 30,
-      },
-      part: 1,
-      realTemp: 30,
-      isWhite: false,
-      barWidth: 30,
-      getvolumnStatus() {
-        if (proxyData.isOpen) {
-          nextTick(() => {
-            proxyData.endBoxSwiper();
-            proxyData.setBarNowPerstion();
-          });
-        }
-        contx.emit("getStatus", proxyData.isOpen);
-      },
-      getEleWidth(ele) {
-        // debugger;
-        if (ele) {
-          return ele.getBoundingClientRect().width;
-        } else {
-          return 1;
-        }
-      },
-      setBarNowPerstion() {
-        proxyData.realTemp = proxyData.volumnData.volumnTemp;
-        let barBox = document.querySelector("#barvolumnId");
-        if (!barBox) {
-          return;
-        }
-        let sliderBox = document.querySelector("#slidervolumnId");
-        let sliderWidth = proxyData.getEleWidth(sliderBox);
-        if (
-          proxyData.volumnData.volumnTemp >= proxyData.volumnData.minTempSet &&
-          proxyData.volumnData.volumnTemp <= proxyData.volumnData.maxTempSet
-        ) {
-          let barWidth =
-            (proxyData.volumnData.volumnTemp - proxyData.volumnData.minTempSet) /
-            proxyData.part;
-          // left = Math.floor(left);
-          if (barBox) {
-            barBox.style.width = barWidth + "px";
-          }
-        } else {
-          if (!proxyData.volumnData.volumnTemp) {
-            // barBox.style.width = 30 + "px";
-            proxyData.barWidth = 30;
-          } else if (proxyData.volumnData.volumnTemp < proxyData.volumnData.minTempSet) {
-            // barBox.style.width = 30 + "px";
-            proxyData.barWidth = 30;
-          } else if (proxyData.volumnData.volumnTemp > proxyData.volumnData.maxTempSet) {
-            let barWidth = barBox.offsetWidth;
-            // barBox.style.width = sliderWidth + "px";
-            proxyData.barWidth = barWidth;
-          }
-        }
-      },
-      endBoxSwiper() {
-        let sliderBox = document.querySelector("#slidervolumnId");
-        let handBox = document.querySelector("#handvolumnId");
-        let barBox = document.querySelector("#barvolumnId");
-        let isMove = false;
-        let sliderWidth = proxyData.getEleWidth(sliderBox);
-        let startBarWidth = proxyData.getEleWidth(barBox);
-        if (sliderWidth > 1) {
-          sliderWidth = sliderWidth;
-        }
-        let tempPart =
-          (proxyData.volumnData.maxTempSet - proxyData.volumnData.minTempSet) /
-          (sliderWidth - 30);
-        let part = tempPart;
-        proxyData.part = part;
-        if (!handBox) {
-          return;
-        }
-
-        handBox.addEventListener("touchstart", function (e) {
-          let oldBarWidth = (barBox && barBox.style && barBox.style.width) || 0;
-          startBarWidth = isNaN(parseInt(oldBarWidth)) ? 0 : parseInt(oldBarWidth);
-          isMove = true;
-        });
-        handBox.addEventListener("touchend", function (e) {
-          isMove = false;
-          proxyData.volumnData.volumnTemp = proxyData.realTemp;
-          //
-        });
-        swiper(handBox, {
-          swipeLeft: function (e) {
-            if (isMove) {
-              let moveRealX = Math.abs(e.mation.moveX - e.mation.startX);
-              moveRealX = parseInt(moveRealX);
-              let barWidth = startBarWidth - moveRealX;
-              barWidth = parseInt(barWidth);
-              barWidth = barWidth < 30 ? 30 : barWidth;
-              if (barWidth >= sliderWidth) {
-                proxyData.isWhite = true;
-              } else {
-                proxyData.isWhite = false;
-              }
+<script setup>
+import speakerCloseIcon from '@/assets/taiguv1/svg/speaker_close_icon.svg'
+import speakerIcon from '@/assets/taiguv1/svg/speaker_icon.svg'
+import Slider from '@/components/slider/Slider.vue'
+import SwitchButton from '@/components/switch-button/SwitchButton.vue'
+import { ref } from 'vue'
+const emit = defineEmits(['getStatus'])
+const isOpen = ref(false)
 
-              // barBox.style.width = barWidth + "px";
-              proxyData.barWidth = barWidth;
-              let realTemp = proxyData.volumnData.minTempSet + barWidth * part;
-              if (realTemp > proxyData.volumnData.maxTempSet) {
-                realTemp = proxyData.volumnData.maxTempSet;
-              }
-              if (realTemp) {
-                proxyData.realTemp = fix(realTemp.toFixed(1));
-              }
-              console.log("barWidth===", barWidth);
-              if (barWidth <= 30) {
-                proxyData.realTemp = 0;
-              }
-            }
-          },
-          swipeRight: function (e) {
-            if (isMove) {
-              let moveRealX = Math.abs(e.mation.moveX - e.mation.startX);
-              moveRealX = parseInt(moveRealX);
-              let barWidth = startBarWidth + moveRealX;
-              console.log("moveRealX==", moveRealX);
+const volumnValue = ref(0)
 
-              barWidth = parseInt(barWidth);
-              barWidth = barWidth = barWidth > sliderWidth ? sliderWidth : barWidth;
-              if (barWidth >= sliderWidth) {
-                proxyData.isWhite = true;
-              } else {
-                proxyData.isWhite = false;
-              }
-              // barBox.style.width = barWidth + "px";
-              proxyData.barWidth = barWidth;
-
-              console.log("barWidth===", barWidth);
-              let realTemp = barWidth * part + proxyData.volumnData.minTempSet;
-              if (realTemp > proxyData.volumnData.maxTempSet) {
-                realTemp = proxyData.volumnData.maxTempSet;
-              }
-              if (realTemp) {
-                proxyData.realTemp = fix(realTemp.toFixed(1));
-              }
-            }
-          },
-        });
-      },
-    });
-    onBeforeUnmount(() => {});
-    onMounted(() => {});
-
-    return {
-      ...toRefs(proxyData),
-    };
-  },
-});
+const getvolumnStatus = () => {
+  emit('getStatus', isOpen.value)
+}
 </script>
 <style lang="scss" scoped>
 .volumn-box {
@@ -238,8 +54,10 @@ export default defineComponent({
   .top {
     display: flex;
     justify-content: space-between;
+    align-items: center;
     img {
-      width: 30px;
+        width: 30px;
+        height: 30px;
     }
   }
   .bottom {
@@ -288,61 +106,12 @@ export default defineComponent({
       letter-spacing: 0.02em;
       color: rgba(255, 255, 255, 0.4);
     }
-    .temp-box {
-      position: relative;
-      box-sizing: border-box;
-      width: 100%;
-      padding: 2px;
+    .volumn-slider {
       margin-top: 8px;
+      background: rgba(255, 255, 255, 0.6);
+      width: 100%;
       height: 34px;
       border-radius: 12px;
-      background: rgba(255, 255, 255, 0.6);
-      .text {
-        position: absolute;
-        top: 50%;
-        transform: translateY(-50%);
-        font-family: Jost;
-        font-size: 11px;
-        font-weight: 400;
-        line-height: 15px;
-        color: rgba(116, 128, 141, 1);
-        z-index: 2;
-      }
-      .text-left {
-        left: 8px;
-      }
-      .text-right {
-        right: 8px;
-      }
-      .active-text {
-        color: rgba(255, 255, 255, 0.6);
-      }
-      .active-bar {
-        position: absolute;
-        background: linear-gradient(95.5deg, #99282b 21.44%, #a95459 84.95%);
-        left: 2px;
-        top: 50%;
-        transform: translateY(-50%);
-        z-index: 1;
-        width: 73px;
-        height: 30px;
-        border-radius: 10px;
-        .hand-box {
-          padding-left: 6px;
-          padding-right: 6px;
-          position: absolute;
-          top: 50%;
-          transform: translateY(-50%);
-          right: 0px;
-          height: 100%;
-        }
-        .line {
-          margin-top: 9px;
-          height: 12px;
-          width: 2px;
-          background: rgba(255, 255, 255, 0.8);
-        }
-      }
     }
   }
   .switch-btn {
@@ -367,42 +136,4 @@ export default defineComponent({
   }
 }
 </style>
-<style lang="scss">
-.volumn-box {
-  .van-switch__node {
-    background: rgba(255, 255, 255, 0.6);
-    width: 24px;
-    height: 24px;
-    left: 2px;
-    top: 0.33vh;
-  }
 
-  .van-switch--on {
-    background: linear-gradient(95.5deg, #99282b 21.44%, #a95459 84.95%) !important;
-    .van-switch__node {
-      background: #fff !important;
-    }
-  }
-
-  .van-switch--on.switch-btn {
-    .van-switch__node {
-      transform: translate(calc(50px - 28px)) !important;
-    }
-  }
-  .van-loading__spinner {
-    color: $elActiveColor !important;
-  }
-
-  .van-switch__loading {
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    line-height: 1;
-  }
-
-  .van-switch--disabled {
-    opacity: 0.5;
-  }
-}
-</style>

Разница между файлами не показана из-за своего большого размера
+ 3548 - 483
src/views/envmonitor/taiguv1/const.js


+ 0 - 443
src/views/envmonitor/taiguv1/index copy.vue

@@ -1,443 +0,0 @@
-<template>
-  <div class="main" :style="{ 'background-image': 'url(' + roomInfo.bg + ')' }">
-    <!-- <img :src="roomData[0].bg" class="video-image" /> -->
-    <!-- <img class="video-image" src="roomInfo.bg"></div> -->
-    <div class="video-image"></div>
-    <div class="content">
-      <div class="metting-info">
-        <img class="logo" :src="roomInfo.logo" />
-        <div class="name">{{ roomInfo.name }}</div>
-        <div class="location">{{ roomInfo.location }}</div>
-      </div>
-      <div class="env-box">
-        <img class="box-line" :src="boxLine" />
-        <div class="env-info">
-          <div class="item">
-            <div class="title">温度</div>
-            <div class="num-box">
-              <span>26</span>
-              <span>℃</span>
-            </div>
-          </div>
-          <div class="item">
-            <div class="title">CO2</div>
-            <div class="num-box">
-              <span>410</span>
-              <span>优</span>
-            </div>
-          </div>
-        </div>
-        <div class="line"></div>
-        <div class="env-info">
-          <div class="item">
-            <div class="title">湿度</div>
-            <div class="num-box">
-              <span>42</span>
-              <span>%</span>
-            </div>
-          </div>
-          <div class="item">
-            <div class="title">TVOC</div>
-            <div class="num-box">
-              <span>0.5</span>
-              <span>健康</span>
-            </div>
-          </div>
-        </div>
-        <div class="line"></div>
-        <div class="env-info">
-          <div class="item">
-            <div class="title">PM 2.5</div>
-            <div class="num-box">
-              <span>17</span>
-              <span>优</span>
-            </div>
-          </div>
-          <div class="item">
-            <div class="title">甲醛</div>
-            <div class="num-box">
-              <span>0.04</span>
-              <span>健康</span>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="fotter">
-      <div class="box">
-        <div class="info-box">
-          <div class="info">
-            <div class="item">
-              <div class="title">CO2</div>
-              <div class="num">410</div>
-              <div class="text">空气清新</div>
-            </div>
-            <div class="item">
-              <div class="title">CO2</div>
-              <div class="num">410</div>
-              <div class="text">空气清新</div>
-            </div>
-          </div>
-          <div class="info">
-            <div class="item">
-              <div class="title">甲醛</div>
-              <div class="num">0.5</div>
-              <div class="text">健康</div>
-            </div>
-            <div class="item">
-              <div class="title">TVOC</div>
-              <div class="num">6</div>
-              <div class="text">健康</div>
-            </div>
-          </div>
-        </div>
-
-        <!--室外天气-->
-        <div class="wether-box">
-          <div class="top">
-            <span>室外</span>
-            <span>-3 ℃</span>
-            <span>/</span>
-          </div>
-          <div class="bottom">
-            <span>PM 2.5</span>
-            <span>216</span>
-            <span>重毒污染</span>
-          </div>
-        </div>
-      </div>
-
-      <!--空调-->
-      <div class="box">
-        <Air></Air>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { defineComponent, reactive, toRefs, onMounted, onBeforeUnmount } from "vue";
-import Air from "./components/Air/index.vue";
-
-export default defineComponent({
-  components: {
-    Air,
-  },
-
-  setup() {
-    const proxyData = reactive({
-      boxLine: require("@/assets/taiguv1/svg/box_line.png"),
-      roomData: [
-        {
-          id: 1,
-          name: "ROOM EOS",
-          bg:
-            "https://reserv-h5.tenants.link/static/WeChat/page-taiguv1/page-pad/pad_room1.png",
-        },
-        {
-          id: 2,
-          name: "ROOM METIS",
-          bg:
-            "https://reserv-h5.tenants.link/static/WeChat/page-taiguv1/page-pad/pad_room2.png",
-        },
-        {
-          id: 3,
-          name: "ROOM NAIAD",
-          bg:
-            "https://reserv-h5.tenants.link/static/WeChat/page-taiguv1/page-pad/pad_room3.png",
-        },
-        {
-          id: 4,
-          name: "ROOM HELIOS",
-          bg:
-            "https://reserv-h5.tenants.link/static/WeChat/page-taiguv1/page-pad/pad_room4.png",
-        },
-        {
-          id: 5,
-          name: "ROOM GAIA",
-          bg:
-            "https://reserv-h5.tenants.link/static/WeChat/page-taiguv1/page-pad/pad_room5.png",
-        },
-        {
-          id: 6,
-          name: "ROOM AURA",
-          bg:
-            "https://reserv-h5.tenants.link/static/WeChat/page-taiguv1/page-pad/pad_room6.png",
-        },
-      ],
-      roomInfo: {},
-    });
-    onBeforeUnmount(() => {});
-    onMounted(() => {
-      proxyData.roomInfo = proxyData.roomData[0];
-      proxyData.roomInfo.logo = require("@/assets/taiguv1/svg/meting_icon.svg");
-      proxyData.roomInfo.location = "3F";
-    });
-    return {
-      ...toRefs(proxyData),
-    };
-  },
-});
-</script>
-<style lang="scss">
-.main {
-  position: relative;
-  width: 100%;
-  height: 100%;
-  background-size: 100% 100%;
-  // mask-image: linear-gradient(
-  //   113.73deg,
-  //   rgba(47, 36, 28, 0.4) 17.26%,
-  //   rgba(47, 36, 28, 0.8) 55.71%
-  // );
-  .video-image {
-    position: absolute;
-    left: 0;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    width: 100%;
-    height: 100%;
-    background: linear-gradient(
-      113.73deg,
-      rgba(47, 36, 28, 0.4) 17.26%,
-      rgba(47, 36, 28, 0.8) 55.71%
-    );
-  }
-  .content {
-    position: relative;
-  }
-  .metting-info {
-    padding-left: 40px;
-    padding-top: 36px;
-    display: flex;
-    align-items: center;
-    .logo {
-      width: 40px;
-      height: 40px;
-      margin-right: 9px;
-    }
-    .name {
-      font-family: Jost;
-      font-size: 40px;
-      font-weight: 300;
-      line-height: 57.8px;
-      letter-spacing: 0.02em;
-      color: #fff;
-      text-align: left;
-      margin-right: 8px;
-    }
-    .location {
-      //styleName: En/H3;
-      font-family: Jost;
-      font-size: 20px;
-      font-weight: 300;
-      line-height: 29px;
-      color: #fff;
-      margin-top: 15px;
-    }
-  }
-  .env-box {
-    position: absolute;
-    box-sizing: border-box;
-    width: 360px;
-    // height: 268px;
-    top: 36px;
-    left: 550px;
-    padding: 8px 56px;
-    border-radius: 24px 160px 24px 24px;
-    background: rgba(255, 255, 255, 0.2);
-    backdrop-filter: blur(20px);
-    box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.2);
-    .box-line {
-      position: absolute;
-      top: -10px;
-      left: -8px;
-      width: 360px;
-      height: 100%;
-      // height: 268px;
-    }
-    .line {
-      width: 244px;
-      height: 1px;
-      background: rgba(255, 255, 255, 0.2);
-    }
-    .env-info {
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      padding: 14px 0;
-      // border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-      .item {
-        width: 120px;
-        .title {
-          //styleName: Chi/Body XS;
-          font-family: PingFang SC;
-          font-size: 11px;
-          font-weight: 400;
-          line-height: 15px;
-          letter-spacing: 0.02em;
-          padding-bottom: 5px;
-          color: rgba(228, 228, 228, 1);
-        }
-        .num-box {
-          span {
-            //styleName: En/H1;
-            display: inline-block;
-            padding-right: 4px;
-            color: #fff;
-            &:nth-child(1) {
-              font-family: Jost;
-              font-size: 36px;
-              font-weight: 300;
-              line-height: 36px;
-            }
-            &:nth-child(2) {
-              font-family: Jost;
-              font-size: 12px;
-              font-weight: 400;
-              // line-height: 17px;
-            }
-          }
-        }
-      }
-    }
-  }
-  .fotter {
-    position: fixed;
-    box-sizing: border-box;
-    padding: 16px;
-    height: 264px;
-    left: 0;
-    bottom: 0;
-    width: 100%;
-    overflow-x: scroll;
-    border-radius: 24px;
-    backdrop-filter: blur(20px);
-    background: rgba(255, 255, 255, 0.1);
-    box-shadow: 0px -10px 20px 0px rgba(0, 0, 0, 0.2);
-    .info-box {
-      box-sizing: border-box;
-      padding: 7px 24px;
-      width: 180px;
-      height: 174px;
-      backdrop-filter: blur(60px);
-      box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.1);
-      background: rgba(255, 255, 255, 0.2);
-      border-radius: 24px 24px 24px 50px;
-      .info {
-        display: flex;
-        justify-content: space-between;
-        padding: 10px 0;
-        border-bottom: 1px solid rgba(255, 255, 255, 0.2);
-        text-align: center;
-        &:nth-child(2) {
-          border-bottom: none;
-        }
-      }
-      .item {
-        color: #fff;
-        width: 60px;
-        .title {
-          font-family: Jost;
-          font-size: 10px;
-          font-weight: 400;
-          line-height: 14px;
-          text-align: center;
-        }
-        .num {
-          //styleName: En/H3;
-          font-family: Jost;
-          font-size: 20px;
-          font-weight: 300;
-          line-height: 24px;
-          text-align: center;
-          margin-bottom: 4px;
-        }
-        .text {
-          display: inline-block;
-          box-sizing: border-box;
-          height: 18px;
-          padding: 2px 8px 2px 8px;
-          border-radius: 50px;
-          border: 1px solid rgba(255, 255, 255, 0.2);
-          font-family: PingFang SC;
-          font-size: 10px;
-          font-weight: 400;
-          line-height: 14px;
-          text-align: center;
-          margin: 0 auto;
-        }
-      }
-    }
-
-    .wether-box {
-      margin-top: 8px;
-      width: 180px;
-      border-radius: 24px;
-      box-sizing: border-box;
-      text-align: center;
-      padding: 7px 10px;
-      background: rgba(255, 255, 255, 0.1);
-      color: rgba(227, 227, 227, 1);
-
-      .top {
-        padding-bottom: 4px;
-        span {
-          display: inline-block;
-          font-family: PingFang SC;
-          font-size: 11px;
-          font-weight: 400;
-          line-height: 15px;
-          letter-spacing: 0.02em;
-          &:nth-child(1) {
-            //styleName: Chi/Body XS;
-            padding-right: 4px;
-          }
-          &:nth-child(2) {
-            //styleName: En/Body XS;
-            font-family: Jost;
-            font-size: 11px;
-            font-weight: 400;
-            line-height: 15px;
-          }
-        }
-      }
-      .bottom {
-        span {
-          display: inline-block;
-          &:nth-child(1) {
-            //styleName: En/Body XS;
-            font-family: Jost;
-            font-size: 11px;
-            font-weight: 400;
-            line-height: 15px;
-            padding-right: 2px;
-          }
-          &:nth-child(2) {
-            //styleName: En/Body XS;
-            font-family: Jost;
-            font-size: 11px;
-            font-weight: 400;
-            line-height: 15px;
-            padding-right: 4px;
-          }
-          &:nth-child(3) {
-            //styleName: Chi/Body XS;
-            font-family: PingFang SC;
-            font-size: 11px;
-            font-weight: 400;
-            line-height: 15px;
-            letter-spacing: 0.02em;
-          }
-        }
-      }
-    }
-    .box {
-      display: inline-block;
-      vertical-align: middle;
-      margin-right: 8px;
-    }
-  }
-}
-</style>

Разница между файлами не показана из-за своего большого размера
+ 799 - 481
src/views/envmonitor/taiguv1/index.vue


+ 6 - 2
tsconfig.json

@@ -11,7 +11,8 @@
     "esModuleInterop": true,
     "allowSyntheticDefaultImports": true,
     // "suppressImplicitAnyIndexErrors":true,
-    "noImplicitAny":true,
+    "noImplicitAny": false,
+    // "suppressImplicitAnyIndexErrors": true,
     "sourceMap": true,
     "baseUrl": ".",
     "types": [
@@ -29,7 +30,10 @@
       "dom",
       "dom.iterable",
       "scripthost"
-    ]
+    ],
+    "strictNullChecks": false,
+    "noImplicitThis": false,
+    "allowJs": true
   },
   "include": [
     "src/**/*.ts",

+ 81 - 75
vue.config.js

@@ -1,25 +1,25 @@
-const { resolve } = require("path");
-const path = require("path");
-const WebpackBar = require("webpackbar");
+const { resolve } = require('path')
+const path = require('path')
+const WebpackBar = require('webpackbar')
 // const dayjs = require('dayjs')
 // const time = dayjs().format('YYYY-M-D HH:mm:ss')
-const merge = require("webpack-merge");
-const tsImportPluginFactory = require("ts-import-plugin");
-const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
-const productionGzipExtensions = ["js", "css", "svg"];
+const merge = require('webpack-merge')
+const tsImportPluginFactory = require('ts-import-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+const productionGzipExtensions = ['js', 'css', 'svg']
 // process.env.VUE_APP_UPDATE_TIME = time
 
-const isProduction = process.env.NODE_ENV === "production";
+const isProduction = process.env.NODE_ENV === 'production'
 const cdn = {
-  css: ["https://cdn.jsdelivr.net/npm/vant@3/lib/index.css"],
+  css: ['https://cdn.jsdelivr.net/npm/vant@3/lib/index.css'],
   js: [
-    "https://unpkg.com/vue@3.2.31/dist/vue.global.js",
-    "https://unpkg.com/vue-router@4.0.14/dist/vue-router.global.js",
-    "https://unpkg.com/vuex@4.0.2/dist/vuex.global.js",
-    "https://cdn.jsdelivr.net/npm/vant@3/lib/vant.min.js",
-    "https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js"
+    'https://unpkg.com/vue@3.2.31/dist/vue.global.js',
+    'https://unpkg.com/vue-router@4.0.14/dist/vue-router.global.js',
+    'https://unpkg.com/vuex@4.0.2/dist/vuex.global.js',
+    'https://cdn.jsdelivr.net/npm/vant@3/lib/vant.min.js',
+    'https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js'
   ]
-};
+}
 const {
   publicPath,
   assetsDir,
@@ -29,8 +29,8 @@ const {
   transpileDependencies,
   title,
   devPort
-} = require("./src/config/default/vue.custom.config");
-const CompressionPlugin = require("compression-webpack-plugin");
+} = require('./src/config/default/vue.custom.config')
+const CompressionPlugin = require('compression-webpack-plugin')
 module.exports = {
   publicPath,
   assetsDir,
@@ -55,13 +55,13 @@ module.exports = {
     loaderOptions: {
       postcss: {
         plugins: [
-          require("postcss-pxtorem")({
+          require('postcss-pxtorem')({
             // 把px单位换算成rem单位
             rootValue: 96, // vant官方使用的是37.5
             minPixelValue: 4,
             unitPrecision: 3,
-            selectorBlackList: ["mu"], // 忽略转换正则匹配项
-            propList: ["*"]
+            selectorBlackList: ['mu'], // 忽略转换正则匹配项
+            propList: ['*']
           })
         ]
       }
@@ -77,61 +77,69 @@ module.exports = {
       errors: true
     },
     proxy: {
-      "/sgipad/duoduo-service/": {
-        target: "https://duoduoenv.sagacloud.cn",
+      '/sgipad/duoduo-service/': {
+        target: 'https://duoduoenv.sagacloud.cn',
         // target: 'http://192.168.0.47:52015',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/duoduo-service": "/duoduo-service"
+          '^/sgipad/duoduo-service': '/duoduo-service'
         }
       },
-      "/sgipad/pad_mtime": {
-        target: "http://39.106.8.246:9091/",
+      '/sgipad/pad_mtime': {
+        target: 'http://39.106.8.246:9091/',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/pad_mtime": "/pad_mtime"
+          '^/sgipad/pad_mtime': '/pad_mtime'
         }
       },
-      "/sgipad/server/": {
-        // target: 'https://duoduoenv.sagacloud.cn',
-        target: "http://sso.sagacloud.cn",
+      '/sgipad/server/': {
+        target: 'https://duoduoenv.sagacloud.cn',
+        // target: 'http://sso.sagacloud.cn',
+        changeOrigin: true,
+        pathRewrite: {
+          '^/sgipad/server': '/server'
+        }
+      },
+      '/sgipad/api/': {
+        target: 'https://bdbeta.tenants.link',
+        // target: 'http://sso.sagacloud.cn',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/server": "/server"
+          '^/sgipad': ''
         }
       },
-      "/sgipad/mngserver/": {
+      '/sgipad/mngserver/': {
         // target: 'https://duoduoenv.sagacloud.cn',
-        target: "http://mng.sagacloud.cn",
+        target: 'http://mng.sagacloud.cn',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/mngserver": "/server"
+          '^/sgipad/mngserver': '/server'
         }
       },
-      "/sgipad/anon/": {
+      '/sgipad/anon/': {
         // target: 'https://duoduoenv.sagacloud.cn',
-        target: "http://mng.sagacloud.cn",
+        target: 'http://mng.sagacloud.cn',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/anon": "/anon"
+          '^/sgipad/anon': '/anon'
         }
       },
-      "/sgipad/test/": {
+      '/sgipad/test/': {
         // target: 'https://duoduoenv.sagacloud.cn',
-        target: "http://192.168.88.6:52009", // 永琪
+        target: 'http://192.168.88.6:52009', // 永琪
         // target: 'http://192.168.4.54:52009', // 小静
         // target: 'http://192.168.16.168:52015',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/test": ""
+          '^/sgipad/test': ''
         }
       },
-      "/sgipad/test1/": {
+      '/sgipad/test1/': {
         // target: 'https://duoduoenv.sagacloud.cn',
-        target: "http://192.168.0.65:52009",
+        target: 'http://192.168.0.65:52009',
         changeOrigin: true,
         pathRewrite: {
-          "^/sgipad/test1": ""
+          '^/sgipad/test1': ''
         }
       }
       // '/api': {
@@ -172,11 +180,11 @@ module.exports = {
     }
   },
   pluginOptions: {
-    "style-resources-loader": {
-      preProcessor: "scss",
+    'style-resources-loader': {
+      preProcessor: 'scss',
       patterns: [
-        path.resolve(__dirname, "src/styles/_variables.scss"),
-        path.resolve(__dirname, "src/styles/_mixins.scss")
+        path.resolve(__dirname, 'src/styles/_variables.scss'),
+        path.resolve(__dirname, 'src/styles/_mixins.scss')
       ]
     }
   },
@@ -184,19 +192,19 @@ module.exports = {
     return {
       resolve: {
         alias: {
-          "@": resolve("src"),
-          "*": resolve(""),
-          Assets: resolve("src/assets")
+          '@': resolve('src'),
+          '*': resolve(''),
+          Assets: resolve('src/assets')
         }
       },
       module: {
         rules: [
           {
             test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
-            loader: "@intlify/vue-i18n-loader",
+            loader: '@intlify/vue-i18n-loader',
             include: [
               // Use `Rule.include` to specify the files of locale messages to be pre-compiled
-              path.resolve(__dirname, "src/lang")
+              path.resolve(__dirname, 'src/lang')
             ]
           }
         ]
@@ -216,14 +224,12 @@ module.exports = {
             }),
             // 配置压缩
             new CompressionPlugin({
-              test: new RegExp(
-                "\\.(" + productionGzipExtensions.join("|") + ")$"
-              ),
+              test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
               threshold: 1024 * 10, // 30K
               minRatio: 0.8,
-              algorithm: "gzip", // 使用gzip压缩
+              algorithm: 'gzip', // 使用gzip压缩
               // test: /\.js$|\.css$/, // 匹配文件名
-              filename: "[path].gz[query]", // 压缩后的文件名(保持原文件名,后缀加.gz)
+              filename: '[path].gz[query]', // 压缩后的文件名(保持原文件名,后缀加.gz)
               deleteOriginalAssets: false
             }),
             new WebpackBar({
@@ -242,38 +248,38 @@ module.exports = {
       //   'vue-router': 'VueRouter',
       //   'echarts': 'echarts'
       // } : {}
-    };
+    }
   },
   chainWebpack: config => {
-    config.plugins.delete("preload");
-    config.plugins.delete("prefetch");
-    config.optimization.minimizer("terser").tap(args => {
-      args[0].parallel = 4;
-      args[0].terserOptions.compress.warnings = true;
-      args[0].terserOptions.compress.drop_debugger = true;
-      args[0].terserOptions.compress.drop_console = true;
-      return args;
-    });
+    config.plugins.delete('preload')
+    config.plugins.delete('prefetch')
+    config.optimization.minimizer('terser').tap(args => {
+      args[0].parallel = 4
+      args[0].terserOptions.compress.warnings = true
+      args[0].terserOptions.compress.drop_debugger = true
+      args[0].terserOptions.compress.drop_console = true
+      return args
+    })
     config.module
-      .rule("ts")
-      .use("ts-loader")
+      .rule('ts')
+      .use('ts-loader')
       .tap(options => {
         options = merge(options, {
           transpileOnly: true,
           getCustomTransformers: () => ({
             before: [
               tsImportPluginFactory({
-                libraryName: "vant",
-                libraryDirectory: "es",
+                libraryName: 'vant',
+                libraryDirectory: 'es',
                 style: true
               })
             ]
           }),
           compilerOptions: {
-            module: "es2015"
+            module: 'es2015'
           }
-        });
-        return options;
-      });
+        })
+        return options
+      })
   }
-};
+}

Разница между файлами не показана из-за своего большого размера
+ 3726 - 2694
yarn.lock