浏览代码

fix: 第二版界面,相关设备接口

anxiaoxia 2 周之前
父节点
当前提交
d50096abae
共有 93 个文件被更改,包括 1614 次插入833 次删除
  1. 二进制
      dist.zip
  2. 1 1
      dist/tenantslink/index.html
  3. 0 1
      dist/tenantslink/static/css/app.e3054e82.css
  4. 0 1
      dist/tenantslink/static/css/chunk-016ba2f5.eb12a606.css
  5. 0 1
      dist/tenantslink/static/css/chunk-03ee2bea.4a0e7e5f.css
  6. 二进制
      dist/tenantslink/static/css/chunk-03ee2bea.4a0e7e5f.css.gz
  7. 0 1
      dist/tenantslink/static/css/chunk-0f7bdb64.024a04c0.css
  8. 二进制
      dist/tenantslink/static/css/chunk-0f7bdb64.024a04c0.css.gz
  9. 0 1
      dist/tenantslink/static/css/chunk-1be83e5a.c42b1165.css
  10. 二进制
      dist/tenantslink/static/css/chunk-1be83e5a.c42b1165.css.gz
  11. 0 1
      dist/tenantslink/static/css/chunk-25e1b0c2.ff926608.css
  12. 二进制
      dist/tenantslink/static/css/chunk-25e1b0c2.ff926608.css.gz
  13. 0 1
      dist/tenantslink/static/css/chunk-287190ab.7e76e03a.css
  14. 0 1
      dist/tenantslink/static/css/chunk-2e62b616.21c73629.css
  15. 0 1
      dist/tenantslink/static/css/chunk-3b59defb.20a38813.css
  16. 0 1
      dist/tenantslink/static/css/chunk-4f85f2e2.d269295d.css
  17. 0 1
      dist/tenantslink/static/css/chunk-6919b5fa.c371ac26.css
  18. 二进制
      dist/tenantslink/static/css/chunk-6919b5fa.c371ac26.css.gz
  19. 0 1
      dist/tenantslink/static/css/chunk-72e1d1ce.5a2aad26.css
  20. 0 1
      dist/tenantslink/static/css/chunk-75ae125c.6974d508.css
  21. 0 1
      dist/tenantslink/static/css/chunk-92b66cce.fb475f7f.css
  22. 0 1
      dist/tenantslink/static/css/chunk-a1ee0466.2fac2e52.css
  23. 二进制
      dist/tenantslink/static/css/chunk-a1ee0466.2fac2e52.css.gz
  24. 0 1
      dist/tenantslink/static/css/chunk-vendors.77ab3d73.css
  25. 二进制
      dist/tenantslink/static/css/chunk-vendors.77ab3d73.css.gz
  26. 0 1
      dist/tenantslink/static/js/app.ee93f67b.js
  27. 二进制
      dist/tenantslink/static/js/app.ee93f67b.js.gz
  28. 0 1
      dist/tenantslink/static/js/chunk-016ba2f5.5f350c0a.js
  29. 0 1
      dist/tenantslink/static/js/chunk-03ee2bea.6b49a9b4.js
  30. 二进制
      dist/tenantslink/static/js/chunk-03ee2bea.6b49a9b4.js.gz
  31. 0 1
      dist/tenantslink/static/js/chunk-0f7bdb64.6af9e353.js
  32. 二进制
      dist/tenantslink/static/js/chunk-0f7bdb64.6af9e353.js.gz
  33. 0 1
      dist/tenantslink/static/js/chunk-10ee235a.d8019cb1.js
  34. 0 1
      dist/tenantslink/static/js/chunk-1be83e5a.928054cb.js
  35. 二进制
      dist/tenantslink/static/js/chunk-1be83e5a.928054cb.js.gz
  36. 0 7
      dist/tenantslink/static/js/chunk-25e1b0c2.df10d931.js
  37. 二进制
      dist/tenantslink/static/js/chunk-25e1b0c2.df10d931.js.gz
  38. 0 10
      dist/tenantslink/static/js/chunk-27676557.ca357779.js
  39. 二进制
      dist/tenantslink/static/js/chunk-27676557.ca357779.js.gz
  40. 0 1
      dist/tenantslink/static/js/chunk-287190ab.dd8f5d93.js
  41. 二进制
      dist/tenantslink/static/js/chunk-287190ab.dd8f5d93.js.gz
  42. 0 1
      dist/tenantslink/static/js/chunk-2b270b5e.2118792e.js
  43. 0 1
      dist/tenantslink/static/js/chunk-2e62b616.188fe673.js
  44. 0 1
      dist/tenantslink/static/js/chunk-3b59defb.7ae7d4f7.js
  45. 0 1
      dist/tenantslink/static/js/chunk-4f85f2e2.072397b0.js
  46. 二进制
      dist/tenantslink/static/js/chunk-4f85f2e2.072397b0.js.gz
  47. 0 1
      dist/tenantslink/static/js/chunk-6919b5fa.8050aeba.js
  48. 二进制
      dist/tenantslink/static/js/chunk-6919b5fa.8050aeba.js.gz
  49. 0 1
      dist/tenantslink/static/js/chunk-72e1d1ce.7a3a3654.js
  50. 二进制
      dist/tenantslink/static/js/chunk-72e1d1ce.7a3a3654.js.gz
  51. 0 1
      dist/tenantslink/static/js/chunk-75ae125c.d5e6ba5e.js
  52. 0 22
      dist/tenantslink/static/js/chunk-92b66cce.817b4451.js
  53. 二进制
      dist/tenantslink/static/js/chunk-92b66cce.817b4451.js.gz
  54. 0 1
      dist/tenantslink/static/js/chunk-a1ee0466.98a342e8.js
  55. 二进制
      dist/tenantslink/static/js/chunk-a1ee0466.98a342e8.js.gz
  56. 0 10
      dist/tenantslink/static/js/chunk-bb545e94.4bfcb9b8.js
  57. 二进制
      dist/tenantslink/static/js/chunk-bb545e94.4bfcb9b8.js.gz
  58. 0 18
      dist/tenantslink/static/js/chunk-vendors.61537750.js
  59. 二进制
      dist/tenantslink/static/js/chunk-vendors.61537750.js.gz
  60. 22 4
      src/apis/taiguv1.js
  61. 11 0
      src/assets/taiguv1/svg/Curtain_card_active_icon.svg
  62. 11 0
      src/assets/taiguv1/svg/Curtain_card_unactive_icon.svg
  63. 6 0
      src/assets/taiguv1/svg/down_active_icon.svg
  64. 6 0
      src/assets/taiguv1/svg/down_icon.svg
  65. 5 0
      src/assets/taiguv1/svg/filter_icon.svg
  66. 7 0
      src/assets/taiguv1/svg/stop_active_icon.svg
  67. 7 0
      src/assets/taiguv1/svg/stop_icon.svg
  68. 10 0
      src/assets/taiguv1/svg/un_Cinema_icon.svg
  69. 19 0
      src/assets/taiguv1/svg/un_FoodTasting_icon.svg
  70. 5 0
      src/assets/taiguv1/svg/un_GenerolMode_icon.svg
  71. 23 0
      src/assets/taiguv1/svg/un_OpenHouse_icon.svg
  72. 21 0
      src/assets/taiguv1/svg/un_PrivateAuction_icon.svg
  73. 4 0
      src/assets/taiguv1/svg/un_PrivateDining_icon.svg
  74. 10 0
      src/assets/taiguv1/svg/un_Projection_icon.svg
  75. 32 0
      src/assets/taiguv1/svg/un_Roadshows_icon.svg
  76. 8 0
      src/assets/taiguv1/svg/un_VcMode_icon.svg
  77. 5 0
      src/assets/taiguv1/svg/un_YogaMode_icon.svg
  78. 6 0
      src/assets/taiguv1/svg/up_active_icon.svg
  79. 6 0
      src/assets/taiguv1/svg/up_icon.svg
  80. 2 1
      src/components/lamp-slider/LampSlider.vue
  81. 10 4
      src/components/slider/Slider.vue
  82. 97 0
      src/hooks/useDeviceControl.js
  83. 107 0
      src/hooks/useLampControl.js
  84. 12 10
      src/store/index.ts
  85. 49 0
      src/store/modules/taiguv1/index.js
  86. 458 183
      src/views/envmonitor/taiguv1/components/Air/AirMore.vue
  87. 142 51
      src/views/envmonitor/taiguv1/components/Air/index.vue
  88. 31 40
      src/views/envmonitor/taiguv1/components/Curtain/CurtainMore.vue
  89. 67 39
      src/views/envmonitor/taiguv1/components/Curtain/index.vue
  90. 163 154
      src/views/envmonitor/taiguv1/components/Lamp/LightMore.vue
  91. 120 41
      src/views/envmonitor/taiguv1/components/Lamp/index.vue
  92. 48 0
      src/views/envmonitor/taiguv1/const.js
  93. 83 207
      src/views/envmonitor/taiguv1/index.vue

二进制
dist.zip


文件差异内容过多而无法显示
+ 1 - 1
dist/tenantslink/index.html


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/app.e3054e82.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-016ba2f5.eb12a606.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-03ee2bea.4a0e7e5f.css


二进制
dist/tenantslink/static/css/chunk-03ee2bea.4a0e7e5f.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-0f7bdb64.024a04c0.css


二进制
dist/tenantslink/static/css/chunk-0f7bdb64.024a04c0.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-1be83e5a.c42b1165.css


二进制
dist/tenantslink/static/css/chunk-1be83e5a.c42b1165.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-25e1b0c2.ff926608.css


二进制
dist/tenantslink/static/css/chunk-25e1b0c2.ff926608.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-287190ab.7e76e03a.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-2e62b616.21c73629.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-3b59defb.20a38813.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-4f85f2e2.d269295d.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-6919b5fa.c371ac26.css


二进制
dist/tenantslink/static/css/chunk-6919b5fa.c371ac26.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-72e1d1ce.5a2aad26.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-75ae125c.6974d508.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-92b66cce.fb475f7f.css


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-a1ee0466.2fac2e52.css


二进制
dist/tenantslink/static/css/chunk-a1ee0466.2fac2e52.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/css/chunk-vendors.77ab3d73.css


二进制
dist/tenantslink/static/css/chunk-vendors.77ab3d73.css.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/app.ee93f67b.js


二进制
dist/tenantslink/static/js/app.ee93f67b.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-016ba2f5.5f350c0a.js


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-03ee2bea.6b49a9b4.js


二进制
dist/tenantslink/static/js/chunk-03ee2bea.6b49a9b4.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-0f7bdb64.6af9e353.js


二进制
dist/tenantslink/static/js/chunk-0f7bdb64.6af9e353.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-10ee235a.d8019cb1.js


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-1be83e5a.928054cb.js


二进制
dist/tenantslink/static/js/chunk-1be83e5a.928054cb.js.gz


文件差异内容过多而无法显示
+ 0 - 7
dist/tenantslink/static/js/chunk-25e1b0c2.df10d931.js


二进制
dist/tenantslink/static/js/chunk-25e1b0c2.df10d931.js.gz


文件差异内容过多而无法显示
+ 0 - 10
dist/tenantslink/static/js/chunk-27676557.ca357779.js


二进制
dist/tenantslink/static/js/chunk-27676557.ca357779.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-287190ab.dd8f5d93.js


二进制
dist/tenantslink/static/js/chunk-287190ab.dd8f5d93.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-2b270b5e.2118792e.js


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-2e62b616.188fe673.js


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-3b59defb.7ae7d4f7.js


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-4f85f2e2.072397b0.js


二进制
dist/tenantslink/static/js/chunk-4f85f2e2.072397b0.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-6919b5fa.8050aeba.js


二进制
dist/tenantslink/static/js/chunk-6919b5fa.8050aeba.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-72e1d1ce.7a3a3654.js


二进制
dist/tenantslink/static/js/chunk-72e1d1ce.7a3a3654.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-75ae125c.d5e6ba5e.js


文件差异内容过多而无法显示
+ 0 - 22
dist/tenantslink/static/js/chunk-92b66cce.817b4451.js


二进制
dist/tenantslink/static/js/chunk-92b66cce.817b4451.js.gz


文件差异内容过多而无法显示
+ 0 - 1
dist/tenantslink/static/js/chunk-a1ee0466.98a342e8.js


二进制
dist/tenantslink/static/js/chunk-a1ee0466.98a342e8.js.gz


文件差异内容过多而无法显示
+ 0 - 10
dist/tenantslink/static/js/chunk-bb545e94.4bfcb9b8.js


二进制
dist/tenantslink/static/js/chunk-bb545e94.4bfcb9b8.js.gz


文件差异内容过多而无法显示
+ 0 - 18
dist/tenantslink/static/js/chunk-vendors.61537750.js


二进制
dist/tenantslink/static/js/chunk-vendors.61537750.js.gz


+ 22 - 4
src/apis/taiguv1.js

@@ -1,4 +1,4 @@
-import { duoduoenvService, envService } from '@/config'
+import { envService } from '@/config'
 import { https } from '@/utils/https'
 import { ContentType, Method } from 'axios-mapper'
 
@@ -7,7 +7,7 @@ const projectId = 'Pj3301050005'
 // 设备下发指令
 export const httpSetEnv = data => {
   return https().httpClient.post(
-    `/server/ctrl/set?projectId=${projectId}`, // API 端点
+    `${envService}/duoduoenv-service/ctrl/set?projectId=${projectId}`, // API 端点
     data
   )
 }
@@ -21,11 +21,29 @@ export const httpGetByMeetingId = params => {
     ContentType.json
   )
 }
+// 查询音频状态
+export const queryAudioStatus = params => {
+  return https().request(
+    `${envService}/duoduoenv-service/ctrl/querySpaceAudio`, // API 端点
+    Method.GET,
+    params,
+    ContentType.json
+  )
+}
+// 查询视频状态
+export const queryScreenCastingStatus = params => {
+  return https().request(
+    `${envService}/duoduoenv-service/ctrl/querySpaceScreenCasting`, // API 端点
+    Method.GET,
+    params,
+    ContentType.json
+  )
+}
 
 // 获取环境参数
 export const HttpGetSpaceInfo = data => {
   return https().request(
-    `/server/space/property`, // API 端点
+    `${envService}/duoduoenv-service/space/property`, // API 端点
     Method.POST, // HTTP 方法
     data, // 请求数据
     ContentType.json // 内容类型
@@ -45,5 +63,5 @@ export const queryAirStatus = params => {
 
 // 查询灯设备状态
 export const queryLampStatus = params => {
-  return https().request(`/server/light/status/query`, Method.GET, params, ContentType.json)
+  return https().request(`${envService}/duoduoenv-service/light/status/query`, Method.GET, params, ContentType.json)
 }

+ 11 - 0
src/assets/taiguv1/svg/Curtain_card_active_icon.svg

@@ -0,0 +1,11 @@
+<svg width="24" height="22" viewBox="0 0 24 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Group">
+<path id="Vector" d="M3.58094 18.0639V20.9999H2.25781V2.96875" stroke="#001428" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M20.4438 18.0639V20.9999H21.767V2.96875" stroke="#001428" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M3.58105 5.94336H20.4436" stroke="#8E0003" stroke-width="0.8" stroke-miterlimit="10"/>
+<path id="Vector_4" d="M3.58105 9.60352H20.4436" stroke="#8E0003" stroke-width="0.8" stroke-miterlimit="10"/>
+<path id="Vector_5" d="M3.58105 13.0801H20.4436" stroke="#8E0003" stroke-width="0.8" stroke-miterlimit="10"/>
+<path id="Vector_6" d="M3.58105 3.29688V16.673H20.4436V3.29688" stroke="#8E0003" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_7" d="M23.0514 0.84375H0.973633V2.96847H23.0514V0.84375Z" stroke="#001428" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 11 - 0
src/assets/taiguv1/svg/Curtain_card_unactive_icon.svg

@@ -0,0 +1,11 @@
+<svg width="24" height="22" viewBox="0 0 24 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Group">
+<path id="Vector" d="M3.58094 18.0639V20.9999H2.25781V2.96875" stroke="white" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M20.4438 18.0639V20.9999H21.767V2.96875" stroke="white" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M3.58105 5.94336H20.4436" stroke="white" stroke-width="0.8" stroke-miterlimit="10"/>
+<path id="Vector_4" d="M3.58105 9.60352H20.4436" stroke="white" stroke-width="0.8" stroke-miterlimit="10"/>
+<path id="Vector_5" d="M3.58105 13.0801H20.4436" stroke="white" stroke-width="0.8" stroke-miterlimit="10"/>
+<path id="Vector_6" d="M3.58105 3.29688V16.673H20.4436V3.29688" stroke="white" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_7" d="M23.0514 0.84375H0.973633V2.96847H23.0514V0.84375Z" stroke="white" stroke-width="0.8" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

文件差异内容过多而无法显示
+ 6 - 0
src/assets/taiguv1/svg/down_active_icon.svg


文件差异内容过多而无法显示
+ 6 - 0
src/assets/taiguv1/svg/down_icon.svg


+ 5 - 0
src/assets/taiguv1/svg/filter_icon.svg

@@ -0,0 +1,5 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="icon/filter">
+<path id="Vector" d="M8.33333 15.0007H17.5M2.5 15.0007H5M5 15.0007V16.6673M5 15.0007V13.334M16.25 10.0007H17.5M2.5 10.0007H13.3333M13.3333 10.0007V11.6673M13.3333 10.0007V8.33398M11.6667 5.00065H17.5M2.5 5.00065H8.33333M8.33333 5.00065V6.66732M8.33333 5.00065V3.33398" stroke="#001428" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 7 - 0
src/assets/taiguv1/svg/stop_active_icon.svg

@@ -0,0 +1,7 @@
+<svg width="17" height="18" viewBox="0 0 17 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Group 48097606">
+<path id="Vector" d="M8.5 0.333984C3.80652 0.333984 0 4.14051 0 8.83398C0 13.5275 3.80652 17.334 8.5 17.334C13.1935 17.334 17 13.5275 17 8.83398C17 4.14051 13.1935 0.333984 8.5 0.333984ZM8.5 16.5949C4.21304 16.5949 0.73913 13.1209 0.73913 8.83398C0.73913 4.54703 4.21304 1.07311 8.5 1.07311C12.787 1.07311 16.2609 4.54703 16.2609 8.83398C16.2609 13.1209 12.787 16.5949 8.5 16.5949Z" fill="#001428"/>
+<path id="Vector_2" d="M7 5.33398L7 12.334" stroke="#8E0003" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M10 5.33398L10 12.334" stroke="#8E0003" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 7 - 0
src/assets/taiguv1/svg/stop_icon.svg

@@ -0,0 +1,7 @@
+<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Group 48097606">
+<path id="Vector" 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 id="Vector_2" d="M7 5L7 12" stroke="#001428" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M10 5L10 12" stroke="#001428" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 10 - 0
src/assets/taiguv1/svg/un_Cinema_icon.svg

@@ -0,0 +1,10 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.19107 15.1522H2.21973V4H21.7808V15.1522H21.033" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M2 19.7081V18.8384C2 18.2206 2.4999 17.7207 3.11766 17.7207H4.52794C5.1457 17.7207 5.6456 18.2206 5.6456 18.8384V19.7081" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M7.4502 19.7081V18.8384C7.4502 18.2206 7.95009 17.7207 8.56785 17.7207H9.97814C10.5959 17.7207 11.0958 18.2206 11.0958 18.8384V19.7081" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M12.9043 19.7081V18.8384C12.9043 18.2206 13.4042 17.7207 14.022 17.7207H15.4322C16.05 17.7207 16.5499 18.2206 16.5499 18.8384V19.7081" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M18.3545 19.7081V18.8384C18.3545 18.2206 18.8544 17.7207 19.4722 17.7207H20.8824C21.5002 17.7207 22.0001 18.2206 22.0001 18.8384V19.7081" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M4.72705 16.1769V15.3071C4.72705 14.6894 5.22695 14.1895 5.84471 14.1895H7.25499C7.87275 14.1895 8.37265 14.6894 8.37265 15.3071V16.1769" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10.1772 16.1769V15.3071C10.1772 14.6894 10.6771 14.1895 11.2949 14.1895H12.7052C13.3229 14.1895 13.8228 14.6894 13.8228 15.3071V16.1769" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M15.6274 16.1769V15.3071C15.6274 14.6894 16.1273 14.1895 16.7451 14.1895H18.1554C18.7731 14.1895 19.273 14.6894 19.273 15.3071V16.1769" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 19 - 0
src/assets/taiguv1/svg/un_FoodTasting_icon.svg

@@ -0,0 +1,19 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_2337_124424)">
+<path d="M20.5549 21.9993H3.4451C3.19585 21.9993 3 21.7985 3 21.543V5.0891C3 4.83358 3.19585 4.63281 3.4451 4.63281H20.5549C20.8042 4.63281 21 4.83358 21 5.0891V21.543C21 21.7985 20.8042 21.9993 20.5549 21.9993ZM3.89021 21.0867H20.1098V5.5454H3.89021V21.0867Z" fill="white" fill-opacity="0.6"/>
+<path d="M15.1952 17.6009C14.9459 17.6009 14.7501 17.4001 14.7501 17.1446C14.7501 15.5932 13.5127 14.3247 11.9993 14.3247C10.486 14.3247 9.24861 15.5932 9.24861 17.1446C9.24861 17.4001 9.05276 17.6009 8.8035 17.6009C8.55424 17.6009 8.3584 17.4001 8.3584 17.1446C8.3584 15.0913 9.98748 13.4121 11.9993 13.4121C14.0112 13.4121 15.6403 15.0821 15.6403 17.1446C15.6403 17.4001 15.4445 17.6009 15.1952 17.6009Z" fill="white" fill-opacity="0.6"/>
+<path d="M12.0008 14.3254C11.7515 14.3254 11.5557 14.1246 11.5557 13.8691V12.2356C11.5557 11.9801 11.7515 11.7793 12.0008 11.7793C12.25 11.7793 12.4459 11.9801 12.4459 12.2356V13.8691C12.4459 14.1246 12.25 14.3254 12.0008 14.3254Z" fill="white" fill-opacity="0.6"/>
+<path d="M16.7983 17.602H7.21073C6.96147 17.602 6.76562 17.4013 6.76562 17.1457C6.76562 16.8902 6.96147 16.6895 7.21073 16.6895H16.7983C17.0475 16.6895 17.2434 16.8902 17.2434 17.1457C17.2434 17.4013 17.0475 17.602 16.7983 17.602Z" fill="white" fill-opacity="0.6"/>
+<path d="M20.5549 8.82079H3.4451C3.19585 8.82079 3 8.62002 3 8.3645C3 8.10897 3.19585 7.9082 3.4451 7.9082H20.5549C20.8042 7.9082 21 8.10897 21 8.3645C21 8.62002 20.8042 8.82079 20.5549 8.82079Z" fill="white" fill-opacity="0.6"/>
+<path d="M5.57206 7.18876C5.3228 7.18876 5.12695 6.98799 5.12695 6.73247V3.45629C5.12695 3.20077 5.3228 3 5.57206 3C5.82132 3 6.01716 3.20077 6.01716 3.45629V6.73247C6.01716 6.98799 5.82132 7.18876 5.57206 7.18876Z" fill="white" fill-opacity="0.6"/>
+<path d="M8.8035 7.18876C8.55424 7.18876 8.3584 6.98799 8.3584 6.73247V3.45629C8.3584 3.20077 8.55424 3 8.8035 3C9.05276 3 9.24861 3.20077 9.24861 3.45629V6.73247C9.24861 6.98799 9.05276 7.18876 8.8035 7.18876Z" fill="white" fill-opacity="0.6"/>
+<path d="M12.0008 7.18876C11.7515 7.18876 11.5557 6.98799 11.5557 6.73247V3.45629C11.5557 3.20077 11.7515 3 12.0008 3C12.25 3 12.4459 3.20077 12.4459 3.45629V6.73247C12.4459 6.98799 12.25 7.18876 12.0008 7.18876Z" fill="white" fill-opacity="0.6"/>
+<path d="M15.1961 7.18876C14.9468 7.18876 14.751 6.98799 14.751 6.73247V3.45629C14.751 3.20077 14.9468 3 15.1961 3C15.4453 3 15.6412 3.20077 15.6412 3.45629V6.73247C15.6412 6.98799 15.4453 7.18876 15.1961 7.18876Z" fill="white" fill-opacity="0.6"/>
+<path d="M18.3914 7.18876C18.1421 7.18876 17.9463 6.98799 17.9463 6.73247V3.45629C17.9463 3.20077 18.1421 3 18.3914 3C18.6407 3 18.8365 3.20077 18.8365 3.45629V6.73247C18.8365 6.98799 18.6407 7.18876 18.3914 7.18876Z" fill="white" fill-opacity="0.6"/>
+</g>
+<defs>
+<clipPath id="clip0_2337_124424">
+<rect width="18" height="19" fill="white" transform="translate(3 3)"/>
+</clipPath>
+</defs>
+</svg>

文件差异内容过多而无法显示
+ 5 - 0
src/assets/taiguv1/svg/un_GenerolMode_icon.svg


+ 23 - 0
src/assets/taiguv1/svg/un_OpenHouse_icon.svg

@@ -0,0 +1,23 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_2337_124404)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9932 4.51957C12.2693 4.51604 12.496 4.73701 12.4995 5.01313C12.5272 7.17281 11.6889 9.46848 10.4537 11.2242C9.23353 12.9584 7.526 14.2985 5.74414 14.2985C5.468 14.2985 5.24414 14.0747 5.24414 13.7985C5.24414 13.5224 5.468 13.2985 5.74414 13.2985C7.03787 13.2985 8.48412 12.2857 9.63582 10.6488C10.7724 9.03327 11.5241 6.93944 11.4996 5.02593C11.4961 4.74981 11.7171 4.52311 11.9932 4.51957Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3.05354 12.4882C3.17448 12.2399 3.47376 12.1367 3.72202 12.2576L5.96355 13.3496C6.2118 13.4705 6.31501 13.7698 6.19407 14.0181C6.07314 14.2663 5.77385 14.3695 5.5256 14.2486L3.28407 13.1566C3.03582 13.0357 2.93261 12.7364 3.05354 12.4882Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.41574 13.4199C5.62397 13.2385 5.9398 13.2603 6.12118 13.4685C6.82531 14.2769 7.37487 14.9907 7.77762 16.0514C8.17465 17.0971 8.41789 18.4495 8.57973 20.5265C8.60119 20.8018 8.3954 21.0423 8.12009 21.0638C7.84478 21.0852 7.60421 20.8795 7.58276 20.6041C7.42315 18.5559 7.18854 17.3171 6.84274 16.4064C6.50265 15.5107 6.04439 14.9028 5.36712 14.1253C5.18575 13.9171 5.20752 13.6012 5.41574 13.4199Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.77462 9.08695C8.04164 9.15733 8.20105 9.43086 8.13066 9.69788C7.85372 10.7485 7.43177 11.6885 6.87546 12.4037C6.31849 13.1197 5.6039 13.6369 4.75029 13.7654C4.47723 13.8065 4.22254 13.6185 4.18142 13.3454C4.14031 13.0723 4.32834 12.8177 4.60141 12.7765C5.1292 12.6971 5.63529 12.3693 6.08614 11.7897C6.53765 11.2092 6.91066 10.4029 7.16369 9.44299C7.23408 9.17597 7.5076 9.01657 7.77462 9.08695Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.06068 9.27906C5.33589 9.25638 5.57738 9.4611 5.60005 9.73631C5.65873 10.4484 5.53932 11.1827 5.30424 11.814C5.07247 12.4365 4.70742 13.013 4.22858 13.3558C4.00404 13.5166 3.69171 13.4648 3.53097 13.2403C3.37024 13.0158 3.42196 12.7034 3.6465 12.5427C3.90614 12.3568 4.17533 11.9801 4.3671 11.4651C4.55556 10.959 4.64901 10.3716 4.60343 9.81843C4.58076 9.54322 4.78547 9.30174 5.06068 9.27906Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3.51172 4.51953C3.78786 4.51953 4.01172 4.74339 4.01172 5.01953V20.515C4.01172 20.7911 3.78786 21.015 3.51172 21.015C3.23558 21.015 3.01172 20.7911 3.01172 20.515V5.01953C3.01172 4.74339 3.23558 4.51953 3.51172 4.51953Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12.006 4.51957C12.2822 4.52311 12.5031 4.74981 12.4996 5.02593C12.4751 6.93944 13.2268 9.03327 14.3634 10.6488C15.5151 12.2857 16.9613 13.2985 18.2551 13.2985C18.5312 13.2985 18.7551 13.5224 18.7551 13.7985C18.7551 14.0747 18.5312 14.2985 18.2551 14.2985C16.4732 14.2985 14.7657 12.9584 13.5455 11.2242C12.3103 9.46848 11.472 7.17281 11.4997 5.01313C11.5032 4.73701 11.7299 4.51604 12.006 4.51957Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M20.937 12.4875C21.0583 12.7355 20.9556 13.035 20.7075 13.1563L18.4747 14.2483C18.2266 14.3696 17.9271 14.2668 17.8058 14.0188C17.6845 13.7707 17.7873 13.4713 18.0353 13.3499L20.2682 12.258C20.5162 12.1367 20.8157 12.2394 20.937 12.4875Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M18.5835 13.4199C18.7917 13.6012 18.8135 13.9171 18.6321 14.1253C17.9548 14.9028 17.4966 15.5107 17.1565 16.4064C16.8107 17.3171 16.5761 18.5559 16.4165 20.6041C16.395 20.8795 16.1545 21.0852 15.8791 21.0638C15.6038 21.0423 15.3981 20.8018 15.4195 20.5265C15.5814 18.4495 15.8246 17.0971 16.2216 16.0514C16.6244 14.9907 17.1739 14.2769 17.8781 13.4685C18.0594 13.2603 18.3753 13.2385 18.5835 13.4199Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M16.2164 9.08695C16.4835 9.01657 16.757 9.17597 16.8274 9.44299C17.0804 10.4029 17.4534 11.2092 17.9049 11.7897C18.3558 12.3693 18.8618 12.6971 19.3896 12.7765C19.6627 12.8177 19.8507 13.0723 19.8096 13.3454C19.7685 13.6185 19.5138 13.8065 19.2408 13.7654C18.3871 13.6369 17.6726 13.1197 17.1156 12.4037C16.5593 11.6885 16.1373 10.7485 15.8604 9.69788C15.79 9.43086 15.9494 9.15733 16.2164 9.08695Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M18.9311 9.27906C19.2063 9.30174 19.411 9.54322 19.3884 9.81843C19.3428 10.3716 19.4362 10.959 19.6247 11.4651C19.8165 11.9801 20.0857 12.3568 20.3453 12.5427C20.5698 12.7034 20.6216 13.0158 20.4608 13.2403C20.3001 13.4648 19.9878 13.5166 19.7632 13.3558C19.2844 13.013 18.9193 12.4365 18.6876 11.814C18.4525 11.1827 18.3331 10.4484 18.3917 9.73631C18.4144 9.4611 18.6559 9.25638 18.9311 9.27906Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M20.4795 4.51953C20.7556 4.51953 20.9795 4.74339 20.9795 5.01953V20.515C20.9795 20.7911 20.7556 21.015 20.4795 21.015C20.2033 21.015 19.9795 20.7911 19.9795 20.515V5.01953C19.9795 4.74339 20.2033 4.51953 20.4795 4.51953Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1.93457 3.43359C1.93457 3.15745 2.15843 2.93359 2.43457 2.93359H21.5658C21.8419 2.93359 22.0658 3.15745 22.0658 3.43359V5.01954C22.0658 5.29568 21.8419 5.51953 21.5658 5.51953H2.43457C2.15843 5.51953 1.93457 5.29568 1.93457 5.01954V3.43359ZM2.93457 3.93359V4.51953H21.0658V3.93359H2.93457Z" fill="white" fill-opacity="0.6"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M1.93457 20.5664C1.93457 20.2903 2.15843 20.0664 2.43457 20.0664H21.5658C21.8419 20.0664 22.0658 20.2903 22.0658 20.5664C22.0658 20.8425 21.8419 21.0664 21.5658 21.0664H2.43457C2.15843 21.0664 1.93457 20.8425 1.93457 20.5664Z" fill="white" fill-opacity="0.6"/>
+</g>
+<defs>
+<clipPath id="clip0_2337_124404">
+<rect width="20" height="18" fill="white" transform="translate(2 3)"/>
+</clipPath>
+</defs>
+</svg>

文件差异内容过多而无法显示
+ 21 - 0
src/assets/taiguv1/svg/un_PrivateAuction_icon.svg


文件差异内容过多而无法显示
+ 4 - 0
src/assets/taiguv1/svg/un_PrivateDining_icon.svg


+ 10 - 0
src/assets/taiguv1/svg/un_Projection_icon.svg

@@ -0,0 +1,10 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.5 9.96875H2.87575C2.39247 9.96875 2 10.3602 2 10.8445V16.8729C2 17.3561 2.39146 17.7486 2.87575 17.7486H21.1243C21.6075 17.7486 22 17.3571 22 16.8729V10.8445C22 10.3612 21.6085 9.96875 21.1243 9.96875H14.5" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.7165 11.9785H15.6758" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M4.02002 6.68164L5.16919 7.83081" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M15.0212 6.74219L13.873 7.89035" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M9.53369 4.43359V6.05797" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M9.5208 16.0123C11.5769 16.0123 13.2437 14.3455 13.2437 12.2894C13.2437 10.2332 11.5769 8.56641 9.5208 8.56641C7.46467 8.56641 5.79785 10.2332 5.79785 12.2894C5.79785 14.3455 7.46467 16.0123 9.5208 16.0123Z" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M5.56335 18.5039V18.7672C5.56335 19.2091 5.20518 19.5673 4.76326 19.5673H3.70389C3.26198 19.5673 2.90381 19.2091 2.90381 18.7672V18.5039" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M21.0951 18.5039V18.7672C21.0951 19.2091 20.7369 19.5673 20.295 19.5673H19.2356C18.7937 19.5673 18.4355 19.2091 18.4355 18.7672V18.5039" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 32 - 0
src/assets/taiguv1/svg/un_Roadshows_icon.svg

@@ -0,0 +1,32 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_2337_124408)">
+<path d="M14.0605 12.2647V12.166" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M14.0404 11.7734L14.0604 12.168V12.2666L14.1304 13.3714L14.6804 22.5052H12.5504L11.4104 14.92L10.2604 22.5052H8.13037L8.78037 11.8425" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10.6601 11.548L14.5001 11.8045C15.4301 11.8637 16.1001 10.9463 15.7501 10.098L14.7701 7.76032C14.4601 7.02053 13.7201 6.52734 12.9101 6.52734H8.85013C7.72013 6.52734 6.92013 7.63209 7.29013 8.68751L8.14013 11.0943C8.43013 11.913 9.40013 12.2681 10.1501 11.8341L13.4201 9.97967C13.4901 9.94021 13.5301 9.8613 13.5201 9.78239L13.3801 8.62833" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M13.5201 9.67143L10.2001 9.59252L9.83008 8.73438" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M10.9899 6.53634C12.1221 6.53634 13.0399 5.63103 13.0399 4.51426C13.0399 3.3975 12.1221 2.49219 10.9899 2.49219C9.85776 2.49219 8.93994 3.3975 8.93994 4.51426C8.93994 5.63103 9.85776 6.53634 10.9899 6.53634Z" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M21.4998 12.5273H20.3398" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M1.5 12.5273H2.66" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 18.1565L19.02 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 18.1565L19.02 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 18.1565L19.02 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 18.1565L19.02 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 6.89258L3.9699 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 6.89258L3.9699 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 6.89258L3.9699 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 6.89258L3.9699 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 6.89258L19.02 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 6.89258L19.02 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 6.89258L19.02 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M19.84 6.89258L19.02 7.70141" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 18.1565L3.9699 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 18.1565L3.9699 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 18.1565L3.9699 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M3.1499 18.1565L3.9699 17.3477" stroke="white" stroke-opacity="0.6" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_2337_124408">
+<rect width="21" height="21" fill="white" transform="translate(1 2)"/>
+</clipPath>
+</defs>
+</svg>

文件差异内容过多而无法显示
+ 8 - 0
src/assets/taiguv1/svg/un_VcMode_icon.svg


文件差异内容过多而无法显示
+ 5 - 0
src/assets/taiguv1/svg/un_YogaMode_icon.svg


文件差异内容过多而无法显示
+ 6 - 0
src/assets/taiguv1/svg/up_active_icon.svg


文件差异内容过多而无法显示
+ 6 - 0
src/assets/taiguv1/svg/up_icon.svg


+ 2 - 1
src/components/lamp-slider/LampSlider.vue

@@ -23,7 +23,7 @@ const sliderContainer = useTemplateRef('slider-container')
 const sliderThumb = useTemplateRef('slider-thumb')
 const max = ref(0)
 const min = ref(0)
-
+const emit = defineEmits(['onEnd'])
 const touchstartPos = ref(0)
 const sliderThumbLeft = ref(0)
 const sliderContainerLeft = ref(0)
@@ -70,6 +70,7 @@ const endDrag = () => {
   if (animationFrameId) {
     cancelAnimationFrame(animationFrameId)
   }
+  emit('onEnd', internalValue.value)
 }
 
 // 监听DOM插入

+ 10 - 4
src/components/slider/Slider.vue

@@ -20,7 +20,7 @@
 </template>
 
 <script setup>
-import { computed, defineModel, defineProps, onMounted, ref, useTemplateRef } from 'vue'
+import { computed, defineModel, defineProps, onMounted, ref, useTemplateRef, watch } from 'vue'
 
 const emit = defineEmits(['onEnd', 'onStart'])
 const props = defineProps({
@@ -47,12 +47,18 @@ const props = defineProps({
 })
 
 const model = defineModel()
-
-const internalValue = ref(props.min)
+watch(
+  () => model.value,
+  newValue => {
+    if (newValue) {
+      internalValue.value = newValue
+    }
+  }
+)
+const internalValue = ref(model.value || 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)}`

+ 97 - 0
src/hooks/useDeviceControl.js

@@ -0,0 +1,97 @@
+import { httpSetEnv } from '@/apis/taiguv1'
+const COMMAND_MAPPINGS = {
+  air: {
+    isOpen: item => ({ code: item.switchCode, value: val => (val ? 1 : 0) }),
+    tempSet: item => ({ code: item.tempSetCode, value: val => val }),
+    gear: item => ({ code: item.gearCode, value: val => val })
+  },
+  lamp: {
+    isOpen: () => ({ code: 'EquipSwitchSet', value: val => (val ? 1 : 0) }),
+    brightValue: () => ({ code: 'brightSet', value: val => val }),
+    colorTempValue: () => ({ code: 'colorTempSet', value: val => val })
+  },
+  curtain: {
+    isOpen: () => ({ code: 'EquipOffSet', value: val => (val ? 1 : 0) })
+  }
+}
+
+const assemblyCommand = type => (commandVal, command, data) => {
+  if (!COMMAND_MAPPINGS[type]?.[command]) {
+    console.warn(`未知的命令类型: ${type} ${command}`)
+    return []
+  }
+
+  const dataArray = Array.isArray(data) ? data : [data]
+
+  return dataArray.map(item => {
+    const commandConfig = COMMAND_MAPPINGS[type][command](item)
+    return {
+      id: item.id,
+      code: commandConfig.code,
+      value: commandConfig.value(commandVal)
+    }
+  })
+}
+
+// 组装设备的下发参数
+const assemblyAirCommand = assemblyCommand('air')
+const assemblyLampCommand = assemblyCommand('lamp')
+const assemblyCurtainCommand = assemblyCommand('curtain')
+
+// 初始化下发指令
+const initDeviceCommand = data => {
+  let { lamps = [], curtains = [] } = data || {}
+  let commands = []
+  // 灯具指令
+  lamps.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
+    })
+  })
+  // 窗帘指令
+  curtains.forEach(item => {
+    commands.push({
+      id: item.id,
+      code: item.code,
+      value: item.value
+    })
+  })
+  return commands
+}
+
+export default function useDeviceControl() {
+  const sendCommands = params => {
+    httpSetEnv(params).then(res => {
+      let { status, data } = res
+      if (status === 200) {
+        console.log('下发成功')
+      } else {
+        console.log('下发失败')
+      }
+    })
+  }
+  return {
+    assemblyAirCommand,
+    assemblyLampCommand,
+    assemblyCurtainCommand,
+    sendCommands,
+    initDeviceCommand
+  }
+}

+ 107 - 0
src/hooks/useLampControl.js

@@ -0,0 +1,107 @@
+export default function useLampControl() {
+  // 组装空调的下发参数
+  const assemblyAirCommand = (commandVal, command, data) => {
+    let commands = []
+    // 将单个对象转换为数组处理
+    const dataArray = Array.isArray(data) ? data : [data]
+    dataArray.forEach(item => {
+      // 开关指令
+      if (command == 'isOpen') {
+        commands.push({
+          id: item.id,
+          code: item.switchCode,
+          value: commandVal ? 1 : 0
+        })
+      }
+      // 温度指令
+      if (command == 'tempSet') {
+        commands.push({
+          id: item.id,
+          code: item.tempSetCode,
+          value: commandVal
+        })
+      }
+      // 档位指令
+      if (command == 'gear') {
+        commands.push({
+          id: item.id,
+          code: item.gearCode,
+          value: commandVal
+        })
+      }
+    })
+    return commands
+  }
+
+  // 组装灯下发参数
+  const assemblyLampCommand = (commandVal, command, data) => {
+    let commands = []
+    // 将单个对象转换为数组处理
+    const dataArray = Array.isArray(data) ? data : [data]
+
+    dataArray.forEach(item => {
+      // 开关指令
+      if (command == 'isOpen') {
+        commands.push({
+          id: item.id,
+          code: item.codeSwitch,
+          value: commandVal ? 1 : 0
+        })
+      }
+      if (command == 'bright') {
+        // 灯亮度指令
+        commands.push({
+          id: item.id,
+          code: item.codeBright,
+          value: commandVal
+        })
+      }
+
+      if ((command = 'colorTemp')) {
+        // 色温指令
+        commands.push({
+          id: item.id,
+          code: item.codeColorTemp,
+          value: commandVal
+        })
+      }
+    })
+
+    return commands
+  }
+
+  // 组装窗帘下发参数
+  const assemblyCurtainCommand = (commandVal, command, data) => {
+    let commands = []
+    // 将单个对象转换为数组处理
+    const dataArray = Array.isArray(data) ? data : [data]
+    dataArray.forEach(item => {
+      // 开关指令
+      if (command == 'isOpen') {
+        commands.push({
+          id: item.id,
+          code: item.code,
+          value: commandVal ? 1 : 0
+        })
+      }
+    })
+    return commands
+  }
+
+  const sendCommands = (commandVal, command, data) => {
+    httpSetEnv(assemblyAirCommand(commandVal, command, data)).then(res => {
+      let { status, data } = res
+      if (status === 200) {
+        console.log('下发成功')
+      } else {
+        console.log('下发失败')
+      }
+    })
+  }
+  return {
+    assemblyAirCommand,
+    sendCommands,
+    assemblyLampCommand,
+    assemblyCurtainCommand
+  }
+}

+ 12 - 10
src/store/index.ts

@@ -1,16 +1,17 @@
-import {createStore, createLogger} from 'vuex'
-import {store as permission, PermissionStore, PermissionState} from '@/store/modules/permission'
-import {store as user, UserStore, UserState} from '@/store/modules/user'
-import {store as portait, PortaitStore, PortaitState} from '@/store/modules/portait'
-
+import { createStore, createLogger } from 'vuex'
+import { store as permission, PermissionStore, PermissionState } from '@/store/modules/permission'
+import { store as user, UserStore, UserState } from '@/store/modules/user'
+import { store as portait, PortaitStore, PortaitState } from '@/store/modules/portait'
+import taiguv1 from '@/store/modules/taiguv1'
 export interface RootState {
   permission: PermissionState
-  user: UserState,
-  portait:PortaitState
+  user: UserState
+  portait: PortaitState
 }
 
-export type Store = PermissionStore<Pick<RootState, 'permission'>>
-  & UserStore<Pick<RootState, 'user'>>  & PortaitStore<Pick<RootState, 'portait'>>
+export type Store = PermissionStore<Pick<RootState, 'permission'>> &
+  UserStore<Pick<RootState, 'user'>> &
+  PortaitStore<Pick<RootState, 'portait'>>
 
 // Plug in logger when in development environment
 const debug = process.env.NODE_ENV !== 'production'
@@ -23,7 +24,8 @@ export const store = createStore({
   modules: {
     permission,
     user,
-    portait
+    portait,
+    taiguv1
   }
 })
 

+ 49 - 0
src/store/modules/taiguv1/index.js

@@ -0,0 +1,49 @@
+const state = {
+  airSwtichStatus: {},
+  lampSwitchStatus: {}
+}
+
+const mutations = {
+  SET_AIES_TATUS: (state, air) => {
+    let { id, status } = air
+    state.airSwtichStatus[id] = status
+  },
+  SET_LAMP_STATUS: (state, lamp) => {
+    let { id, status } = lamp
+    state.lampSwitchStatus[id] = status
+  }
+}
+
+const actions = {
+  setAirStatus({ commit, state }, air) {
+    commit('SET_AIES_TATUS', air)
+    ;(function (airData) {
+      setTimeout(() => {
+        if (state.airSwtichStatus[airData.id] && state.airSwtichStatus[airData.id].loading == true) {
+          airData.status.loading = false
+          airData.status.lastSwitchStatus = null
+          commit('SET_AIES_TATUS', airData)
+        }
+      }, 1000 * 15)
+    })(air)
+  },
+  setLampStatus({ commit, state }, lamp) {
+    commit('SET_LAMP_STATUS', lamp)
+    ;(function (lampData) {
+      setTimeout(() => {
+        if (state.lampSwitchStatus[lampData.id] && state.lampSwitchStatus[lampData.id].loading == true) {
+          lampData.status.loading = false
+          lampData.status.lastSwitchStatus = null
+          commit('SET_LAMP_STATUS', lampData)
+        }
+      }, 1000 * 5)
+    })(lamp)
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 458 - 183
src/views/envmonitor/taiguv1/components/Air/AirMore.vue

@@ -1,26 +1,57 @@
 <template>
   <div class="more-box">
-    <div class="light-more-top">
+    <div class="air-more-top">
       <div class="left">
-        <div class="light-box">
+        <div class="air-box">
           <img
-            :src="LampsStatus === '全部关闭' ? lampCloseIcon : lampOpenIcon"
             alt=""
-            :style="LampsStatus !== '全部关闭' ? { width: '58px', height: '62px' } : ''" />
+            :src="
+              parseImgUrl('taiguv1/envmonitor', airSwitchStatus.switchStatus ? 'active/air-con.svg' : 'air-con.svg')
+            " />
         </div>
-        <div class="light-name">{{ LampsStatus }}</div>
+        <div class="air-name">{{ airSwitchStatus.statusText }}</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 class="control" :ref="setRef" @click="handleSwitch('isOpen', true)">全开</div>
+        <div class="control" :ref="setRef" @click="handleSwitch('isOpen', false)">全关</div>
       </div>
     </div>
-    <div class="light-middle" v-if="LampsStatus !== '全部关闭'">
+    <div class="air-middle" v-if="airSwitchStatus.switchStatus">
       <div class="bright-slider">
-        <Slider v-model="allBrightValue" :isFollow="true" suffix="%" />
+        <Slider
+          v-model="airData.tempSet"
+          :min="airData.minTempSet"
+          :max="airData.maxTempSet"
+          isFollow
+          showValue
+          suffix="℃"
+          @onEnd="setAirStatus('tempSet')"></Slider>
       </div>
       <div class="temp-slider">
-        <LampSlider v-model="allColorTempValue" />
+        <div class="handle-box">
+          <div class="handle-item air-down" :ref="setRef" @click.prevent.stop="handle('minus', airData, 'all')">
+            <img class="icon" :src="parseImgUrl('taiguv1/envmonitor', 'minus.svg')" />
+          </div>
+          <div class="handle-item air-up" :ref="setRef" @click.prevent.stop="handle('plus', airData, 'all')">
+            <img class="icon" :src="parseImgUrl('taiguv1/envmonitor', 'plus.svg')" />
+          </div>
+          <div
+            class="handle-item air-auto"
+            :class="airData.isAutoGear ? 'active' : ''"
+            @click.prevent.stop="handle('auto', airData, 'all')">
+            A
+          </div>
+        </div>
+
+        <div class="fan-speed">
+          <div class="volume-top">
+            <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>
     </div>
 
@@ -28,183 +59,282 @@
       <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 class="air-bottom">
+      <div class="item-box" v-for="item in airEquipList" :key="item.id">
+        <div class="handle-top">
+          <div class="switch-box">
+            <div class="name">{{ item.localName }}</div>
+            <div class="switch">
+              <SwitchButton
+                :loading="allAirStatus[item.id]?.loading"
+                v-model="item.isOpen"
+                @change="sigleAirChange('isOpen', item, 'single')" />
+            </div>
+          </div>
+          <div class="fan-speed air-card">
+            <div class="handle-box">
+              <div class="handle-item air-down" :ref="setRef" @click.prevent.stop="handle('minus', item, 'single')">
+                <img class="icon" :src="parseImgUrl('taiguv1/envmonitor', 'minus.svg')" />
+              </div>
+              <div class="handle-item air-up" :ref="setRef" @click.prevent.stop="handle('plus', item, 'single')">
+                <img class="icon" :src="parseImgUrl('taiguv1/envmonitor', 'plus.svg')" />
+              </div>
+              <div
+                class="handle-item air-auto"
+                :class="item.isAutoGear ? 'active' : ''"
+                @click.prevent.stop="handle('auto', item, 'single')">
+                A
+              </div>
+            </div>
+            <div class="fans-view">
+              <div class="volume-top">
+                <span :class="item.gear == 0 ? 'span-active' : ''">0</span>
+                <span :class="item.gear == 1 ? 'span-active' : ''">1</span>
+                <span :class="item.gear == 2 ? 'span-active' : ''">2</span>
+                <span :class="item.gear == 3 ? 'span-active' : ''">3</span>
+              </div>
+              <div class="text">风量调节</div>
+            </div>
+          </div>
+        </div>
+        <div class="handle-bottom">
+          <Slider
+            isFollow
+            showValue
+            suffix="℃"
+            v-model="item.tempSet"
+            :min="airData.minTempSet"
+            :max="airData.maxTempSet"
+            @onEnd="sigleAirChange('tempSet', item, 'single')"></Slider>
+        </div>
       </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)
-
+import { computed, onBeforeUnmount, onMounted, ref, watch, nextTick, onUnmounted } from 'vue'
+import { parseImgUrl } from '@/utils'
+import { useStore } from '@/store'
+import useDeviceControl from '@/hooks/useDeviceControl'
+const emit = defineEmits(['getStatus'])
+const controlBtn = ref([])
+const store = useStore()
+const setRef = el => {
+  if (el) {
+    if (!controlBtn.value.includes(el)) {
+      controlBtn.value.push(el)
+    }
+  }
+}
+const deviceControl = useDeviceControl()
 // 接收父组件传递的初始状态
 const props = defineProps({
-  initialStatus: {
-    type: Boolean,
-    default: false
-  },
-  currentLamps: {
+  airList: {
     type: Array,
     default: () => []
+  },
+  status: {
+    type: Object,
+    default: function () {
+      return {
+        isOpen: false,
+        gear: 1,
+        minTempSet: 16,
+        maxTempSet: 32,
+        tempSet: 24,
+        isAutoGear: false,
+        switchLoading: false
+      }
+    }
   }
 })
-
-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
+const airEquipList = ref([])
+const airData = ref(props.status)
+const airSwitchStatus = computed(() => {
+  let statusText = ''
+  let switchStatus = false
+  let arr = props.airList.filter(item => item.runStatus == 1)
+  if (arr.length == 0) {
+    statusText = '全部关闭'
+    switchStatus = false
+  } else {
+    statusText = arr.length > 0 && arr.length < props.airList.length ? '部分开启' : '全部开启'
+    switchStatus = true
   }
-  LampsStatus.value = '部分开启'
-  emit('statusChange', true, LampsStatus.value)
-}
-
-let timer = null
-const handleSwitch = type => {
-  if (timer) {
-    clearTimeout(timer)
+  return {
+    statusText,
+    switchStatus
   }
-  isHandlingSwitchOperation.value = true
+})
+const allAirStatus = computed(() => store.state.taiguv1.airSwtichStatus)
 
-  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()
+watch(
+  () => props.status,
+  (newVal, oldVal) => {
+    if (!newVal) {
+      return
+    }
+    let { minTempSet, maxTempSet } = airData.value
+    airData.value = { ...newVal, minTempSet, maxTempSet }
+  },
+  { deep: true } // 添加深度监听
+)
+watch(
+  () => props.airList,
+  (newVal, oldVal) => {
+    compareStatus(newVal)
+  },
+  { deep: true }
+)
 
-  const commands = []
-  childLights.value.forEach(item => {
-    const objName = {
-      id: item.id,
-      code: item.codeSwitch,
-      value: item.valueSwitch ? 1 : 0
+// 对比和store中开关状态
+const compareStatus = data => {
+  console.log(airEquipList.value, 'airEquipList.value')
+  airEquipList.value = data.map(item => {
+    if (allAirStatus.value[item.id]) {
+      if (allAirStatus.value[item.id].lastSwitchStatus == item.runStatus) {
+        store.dispatch('taiguv1/setAirStatus', {
+          id: item.id,
+          status: {
+            loading: false,
+            lastSwitchStatus: item.runStatus == 1
+          }
+        })
+        return {
+          ...item,
+          isOpen: item.runStatus == 1
+        }
+      } else {
+        return {
+          ...item,
+          isOpen: allAirStatus.value[item.id].lastSwitchStatus
+        }
+      }
+    } else {
+      return {
+        ...item,
+        isOpen: item.runStatus == 1
+      }
     }
-    commands.push(objName)
   })
-  // httpSetEnv(commands);
+}
 
-  setTimeout(() => {
-    isHandlingSwitchOperation.value = false
-  }, 0)
+// 整体开关
+const handleSwitch = (type, value) => {
+  airData.value.isOpen = value
+  setAirStatus(type)
 }
 
-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 sigleAirChange = (type, source, all) => {
+  console.log(source, 11111)
+  if (type == 'isOpen') {
+    store.dispatch('taiguv1/setAirStatus', {
+      id: source.id,
+      status: {
+        loading: true,
+        lastSwitchStatus: source.isOpen
+      }
+    })
+  }
+  if (all == 'single') {
+    const params = deviceControl.assemblyAirCommand(source[type], type, source)
+    deviceControl.sendCommands(params)
   }
-  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
+const setAirStatus = type => {
+  if (type == 'isOpen') {
+    store.dispatch('taiguv1/setAirStatus', {
+      id: 'all',
+      status: {
+        loading: true,
+        lastSwitchStatus: airData.value.isOpen
+      }
+    })
+    airEquipList.value.forEach(item => {
+      item.isOpen = airData.value.isOpen
+      sigleAirChange(type, item, 'all')
+    })
+  }
+  const params = deviceControl.assemblyAirCommand(airData.value[type], type, airEquipList.value)
+  deviceControl.sendCommands(params)
+}
+const handle = (type, data, all) => {
+  console.log('debugger')
+  if (!data.gear) data.gear = 0
+  if (type === 'minus') {
+    data.gear -= 1
+    if (data.gear < 0) {
+      data.gear = 0
     }
-    if (newVal) {
-      handleSwitch('allOpen')
-    } else {
-      handleSwitch('allClose')
+    data.isAutoGear = false
+  } else if (type === 'plus') {
+    data.gear += 1
+    if (data.gear > 3) {
+      data.gear = 3
     }
-  },
-  { immediate: true }
-)
+    data.isAutoGear = false
+  } else if (type === 'auto') {
+    data.isAutoGear = true
+  }
+  if (all == 'all') {
+    setAirStatus('gear', all)
+  } else {
+    sigleAirChange('gear', data, all)
+  }
+}
 
-onBeforeUnmount(() => {})
-onMounted(() => {})
+onMounted(() => {
+  nextTick(() => {
+    controlBtn.value.forEach(button => {
+      button.addEventListener('touchstart', handleTouchStart)
+    })
+  })
+})
+
+// 添加 touchstart 处理函数
+const handleTouchStart = event => {
+  const button = event.currentTarget
+  button.classList.add('active')
+  setTimeout(() => {
+    button.classList.remove('active')
+  }, 200)
+}
+// 添加 onUnmounted 钩子
+onUnmounted(() => {
+  controlBtn.value.forEach(button => {
+    button.removeEventListener('touchstart', handleTouchStart)
+  })
+})
 </script>
 <style lang="scss" scoped>
 .more-box {
-  .light-more-top {
+  .air-more-top {
     display: flex;
     align-items: center;
     margin-bottom: 36px;
     .left {
       margin-right: 36px;
-      .light-box {
+      .air-box {
         width: 110px;
         height: 110px;
         background: rgba(255, 255, 255, 0.4);
         border-radius: 50%;
         text-align: center;
         margin-right: 27px;
+        display: flex;
+        justify-self: center;
+        align-items: center;
         img {
-          width: 36px;
-          height: 36px;
+          width: 30px;
+          height: 30px;
           margin: 0 auto;
-          margin-top: 37px;
         }
       }
-      .light-name {
+      .air-name {
         //styleName: Chi/Body Large;
         margin-top: 12px;
         font-family: PingFang SC;
@@ -245,7 +375,7 @@ onMounted(() => {})
       }
     }
   }
-  .light-middle {
+  .air-middle {
     // height: 100px;
     // background: #fff;
     .bright-slider {
@@ -257,46 +387,191 @@ onMounted(() => {})
       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;
+      display: flex;
+      width: 296px;
+      height: 65px;
+      padding: 0px 24px;
+      justify-content: space-between;
+      align-items: center;
+      flex-shrink: 0;
+      border-radius: 24px 24px 60px 24px;
+      background: rgba(255, 255, 255, 0.6);
+      .handle-box {
+        display: flex;
+        .handle-item {
+          width: 36px;
+          height: 36px;
+          background: rgba(255, 255, 255, 0.4);
+          // backdrop-filter: blur(15px);
+          border-radius: 50%;
+          text-align: center;
+          .icon {
+            width: 20px;
+            height: 20px;
+            margin-top: 8px;
+          }
+          &:nth-child(3) {
+            font-family: Jost;
+            font-size: 16px;
+            font-weight: 300;
+            line-height: 36px;
+            text-align: center;
+            color: rgba(0, 20, 40, 1);
+          }
+          &.active {
+            background: #fff;
+            box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+          }
+        }
+      }
+      .fan-speed {
+        .volume-top {
+          padding-bottom: 2px;
+          height: 3.33vh;
+          line-height: 1;
+          span {
+            //styleName: En/Body Small;
+            display: inline-block;
+            margin-right: 5px;
+            font-family: Jost;
+            font-size: 12px;
+            font-weight: 400;
+            line-height: 17px;
+            color: rgba(116, 128, 141, 1);
+          }
+          .span-active {
+            color: rgba(0, 20, 40, 1);
+            font-size: 16px;
+            line-height: 22px;
+          }
+        }
+        .text {
+          //styleName: Chi/Body XS;
+          font-family: PingFang SC;
+          font-size: 11px;
+          font-weight: 400;
+          line-height: 15px;
+          letter-spacing: 0.02em;
+          color: rgba(0, 20, 40, 1);
+        }
+      }
+    }
+  }
+  .fan-speed {
+    &.air-card {
+      display: flex;
+      justify-content: space-between;
+    }
+    .volume-top {
+      padding-bottom: 2px;
+      height: 3.33vh;
+      line-height: 1;
+      span {
+        //styleName: En/Body Small;
+        display: inline-block;
+        margin-right: 5px;
+        font-family: Jost;
+        font-size: 12px;
+        font-weight: 400;
+        line-height: 17px;
+        color: rgba(116, 128, 141, 1);
+      }
+      .span-active {
+        color: rgba(0, 20, 40, 1);
+        font-size: 16px;
+        line-height: 22px;
+      }
+    }
+    .text {
+      //styleName: Chi/Body XS;
+      font-family: PingFang SC;
+      font-size: 11px;
+      font-weight: 400;
+      line-height: 15px;
+      letter-spacing: 0.02em;
+      color: rgba(0, 20, 40, 1);
+    }
+  }
+  .handle-box {
+    display: flex;
+    gap: 6px;
+    .handle-item {
+      width: 36px;
+      height: 36px;
+      background: rgba(255, 255, 255, 0.4);
+      // backdrop-filter: blur(15px);
+      border-radius: 50%;
+      text-align: center;
+      .icon {
+        width: 20px;
+        height: 20px;
+        margin-top: 8px;
+      }
+      &:nth-child(3) {
+        font-family: Jost;
+        font-size: 16px;
+        font-weight: 300;
+        line-height: 36px;
+        text-align: center;
+        color: rgba(0, 20, 40, 1);
+      }
+      &.active {
+        background: #fff;
+        box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+      }
     }
   }
   .divider {
     height: 24px;
     display: flex;
     align-items: center;
-    margin-bottom: 12px;
   }
-  .light-bottom {
+  .air-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);
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      gap: 12px;
       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 {
+      border-radius: 24px 24px 60px 24px;
       background: rgba(255, 255, 255, 0.6);
+      .handle-top {
+        width: 100%;
+        margin-bottom: 12px;
+        .switch-box {
+          width: 100%;
+          display: flex;
+          height: 28px;
+          justify-content: space-between;
+          margin-bottom: 12px;
+          .name {
+            color: var(--Blue, #001428);
+            font-family: 'PingFang SC';
+            font-size: 18px;
+            font-style: normal;
+            font-weight: 400;
+            line-height: normal;
+            letter-spacing: 0.36px;
+          }
+          .switch {
+            width: 50px;
+          }
+        }
+      }
+      .handle-bottom {
+        display: flex;
+        width: 243px;
+        height: 48px;
+        padding: 2px;
+        align-items: center;
+        gap: 10px;
+        border-radius: 14px;
+        background: var(--White-White-60, rgba(255, 255, 255, 0.6));
+      }
     }
   }
   .switch-btn {
@@ -308,21 +583,21 @@ onMounted(() => {})
 }
 </style>
 <style lang="scss">
-.more-box {
-  .van-loading__spinner {
-    color: $elActiveColor !important;
-  }
+// .more-box {
+//   .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>

+ 142 - 51
src/views/envmonitor/taiguv1/components/Air/index.vue

@@ -1,14 +1,21 @@
 <template>
   <div class="volumn-box" :class="airData.isOpen ? 'active' : ''">
-    <div class="top">
-      <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="top">
+        <img :src="parseImgUrl('taiguv1/envmonitor', airData.isOpen ? 'active/air-con.svg' : 'air-con.svg')" alt="" />
+        <SwitchButton
+          :loading="allAirStatus.all?.loading"
+          @click.stop
+          @change="setAirStatus('isOpen')"
+          v-model="airData.isOpen" />
+      </div>
+      <div class="filter-box" v-if="equipList.length > 1">
+        <div class="filter-item" @click="searchMore">
+          <img :src="FilterIcon" alt="" />
+        </div>
+      </div>
     </div>
+
     <div class="bottom">
       <div class="air-info">
         <div class="left">
@@ -26,7 +33,7 @@
           v-model="airData.tempSet"
           :min="airData.minTempSet"
           :max="airData.maxTempSet"
-          @onEnd="getAirStatus('tempSet')"></Slider>
+          @onEnd="setAirStatus('tempSet')"></Slider>
       </div>
 
       <!--风量调整-->
@@ -57,14 +64,18 @@
 </template>
 
 <script setup>
+import FilterIcon from '@/assets/taiguv1/svg/filter_icon.svg'
 import Slider from '@/components/slider/Slider.vue'
 import SwitchButton from '@/components/switch-button/SwitchButton.vue'
+import useDeviceControl from '@/hooks/useDeviceControl'
+import { useStore } from '@/store'
 import { parseImgUrl } from '@/utils'
 import { nextTick } from 'process'
-import { onMounted, ref, watch } from 'vue'
+import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
+const store = useStore()
+const deviceControl = useDeviceControl()
 const controlBtn = ref([])
 const setRef = el => {
-  console.log(el, 'el')
   if (el) {
     if (!controlBtn.value.includes(el)) {
       controlBtn.value.push(el)
@@ -94,20 +105,6 @@ const props = defineProps({
     }
   }
 })
-
-watch(
-  () => props.status,
-  (newVal, oldVal) => {
-    if (!newVal) {
-      return
-    }
-    console.log(newVal, 'newVal')
-    let { minTempSet, maxTempSet } = airData.value
-    airData.value = { ...newVal, minTempSet, maxTempSet }
-  }
-  // { deep: true } // 添加深度监听
-)
-
 const airData = ref({
   isOpen: false,
   gear: 1,
@@ -117,22 +114,82 @@ const airData = ref({
   isAutoGear: false,
   switchLoading: false
 })
+watch(
+  () => props.status,
+  (newVal, oldVal) => {
+    if (!newVal) {
+      return
+    }
+    compareStatus(newVal)
+  },
+  { deep: true } // 添加深度监听
+)
+const compareStatus = data => {
+  let { minTempSet, maxTempSet } = airData.value
+  if (allAirStatus.value.all) {
+    if (allAirStatus.value.all.lastSwitchStatus == data.runStatus) {
+      store.dispatch('taiguv1/setAirStatus', {
+        id: 'all',
+        status: {
+          loading: false,
+          lastSwitchStatus: data.runStatus == 1
+        }
+      })
+      airData.value = {
+        ...data,
+        isOpen: data.runStatus == 1,
+        minTempSet,
+        maxTempSet
+      }
+    } else {
+      airData.value = {
+        ...data,
+        isOpen: allAirStatus.value.all.lastSwitchStatus,
+        minTempSet,
+        maxTempSet
+      }
+    }
+  } else {
+    airData.value = {
+      ...data,
+      isOpen: data.runStatus == 1,
+      minTempSet,
+      maxTempSet
+    }
+  }
+  emit('getStatus', airData.value.isOpen)
+}
 
-const emit = defineEmits(['getStatus', 'restStatus'])
+const allAirStatus = computed(() => store.state.taiguv1.airSwtichStatus)
+
+const emit = defineEmits(['getStatus'])
 
 onMounted(() => {
   nextTick(() => {
-    controlBtn.value.forEach(button => {
-      button.addEventListener('touchstart', () => {
-        button.classList.add('active')
-        setTimeout(() => {
-          button.classList.remove('active')
-        }, 200)
+    nextTick(() => {
+      controlBtn.value.forEach(button => {
+        button.addEventListener('touchstart', handleTouchStart)
       })
     })
   })
 })
+
+// 添加 touchstart 处理函数
+const handleTouchStart = event => {
+  const button = event.currentTarget
+  button.classList.add('active')
+  setTimeout(() => {
+    button.classList.remove('active')
+  }, 200)
+}
+// 添加 onUnmounted 钩子
+onUnmounted(() => {
+  controlBtn.value.forEach(button => {
+    button.removeEventListener('touchstart', handleTouchStart)
+  })
+})
 const handle = type => {
+  if (!airData.value.gear) airData.value.gear = 0
   if (type === 'minus') {
     airData.value.gear -= 1
     if (airData.value.gear < 0) {
@@ -148,14 +205,30 @@ const handle = type => {
   } else if (type === 'auto') {
     airData.value.isAutoGear = true
   }
-  getAirStatus('gear')
+  setAirStatus('gear')
 }
 
-const getAirStatus = type => {
+const setAirStatus = type => {
+  // if (type == 'isOpen') {
+  //   airData.value.lastSwitchStatus = airData.value.isOpen
+  // }
+  // console.log(airData.isOpen, 'airData.isOpen')
   if (type == 'isOpen') {
-    airData.value.lastSwitchStatus = airData.value.isOpen
+    store.dispatch('taiguv1/setAirStatus', {
+      id: 'all',
+      status: {
+        loading: true,
+        lastSwitchStatus: airData.value.isOpen
+      }
+    })
   }
-  emit('getStatus', airData.value, type)
+  const params = deviceControl.assemblyAirCommand(airData.value[type], type, props.equipList)
+  deviceControl.sendCommands(params)
+
+  emit('getStatus', airData.value.isOpen)
+}
+const searchMore = () => {
+  emit('showMore', 'air', true)
 }
 </script>
 <style lang="scss" scoped>
@@ -171,6 +244,24 @@ const getAirStatus = type => {
   background-color: rgba(255, 255, 255, 0.2);
   backdrop-filter: blur(40px);
   box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+  .filter-box {
+    margin-top: 10px;
+    display: flex;
+    justify-content: flex-end;
+    gap: 10px;
+
+    .filter-item {
+      display: flex;
+      width: 36px;
+      height: 36px;
+      justify-content: center;
+      align-items: center;
+      gap: 10px;
+      flex-shrink: 0;
+      border-radius: 60px;
+      background: var(--White-White-40, rgba(255, 255, 255, 0.4));
+    }
+  }
   .top {
     display: flex;
     justify-content: space-between;
@@ -331,21 +422,21 @@ const getAirStatus = type => {
 }
 </style>
 <style lang="scss">
-.volumn-box {
-  .van-loading__spinner {
-    color: $elActiveColor !important;
-  }
+// .volumn-box {
+//   .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>

+ 31 - 40
src/views/envmonitor/taiguv1/components/Curtain/CurtainMore.vue

@@ -27,24 +27,28 @@
             <div
                 class="item-box"
                 v-for="(item, index) in childCurtains"
+                :key="item.id"
             >
                 <div class="name">{{ item.name }}</div>
                 <div class="control-box">
                     <div
                         class="control"
-                        :class="item.isActive && item.activeButton === 1 ? 'active' : ''"
-                        @click="handle('child',1,'开启中',item.id,'EquipOnSet')"
-                    >上</div>
+                        @click="handle('child',1,'开启中','EquipOnSet',item.id)"
+                    >
+                        <img :src="item.isActive && item.activeButton === 1 ? UpActiveIcon : UpUnActiveIcon" alt="">
+                    </div>
                     <div
                         class="control"
-                        :class="item.isActive && item.activeButton === 2 ? 'active' : ''"
-                        @click="handle('child',2,'暂停中',item.id,'EquipStopSet')"
-                    >停</div>
+                        @click="handle('child',2,'暂停中','EquipStopSet',item.id)"
+                    >
+                        <img :src="item.isActive && item.activeButton === 2 ? StopActiveIcon : StopUnActiveIcon" alt="">
+                    </div>
                     <div
                         class="control"
-                        :class="item.isActive && item.activeButton === 0 ? 'active' : ''"
-                        @click="handle('child',0,'关闭中',item.id,'EquipOffSet')"
-                    >下</div>
+                        @click="handle('child',0,'关闭中','EquipOffSet',item.id)"
+                    >
+                        <img :src="item.isActive && item.activeButton === 0 ? DownActiveIcon : DownUnActiveIcon" alt="">
+                    </div>
                 </div>
             </div>
         </div>
@@ -52,7 +56,14 @@
 </template>
 
 <script setup>
+import { httpSetEnv } from '@/apis/taiguv1';
 import curtainIcon from '@/assets/taiguv1/svg/curtain_icon.svg';
+import DownActiveIcon from '@/assets/taiguv1/svg/down_active_icon.svg';
+import DownUnActiveIcon from '@/assets/taiguv1/svg/down_icon.svg';
+import StopActiveIcon from '@/assets/taiguv1/svg/stop_active_icon.svg';
+import StopUnActiveIcon from '@/assets/taiguv1/svg/stop_icon.svg';
+import UpActiveIcon from '@/assets/taiguv1/svg/up_active_icon.svg';
+import UpUnActiveIcon from '@/assets/taiguv1/svg/up_icon.svg';
 import { ref, watch } from "vue";
 const props = defineProps({
     currentCurtains: {
@@ -60,20 +71,7 @@ const props = defineProps({
         default: () => []
     }
 })
-const childCurtains = ref([
-    // {
-    //     name: "内侧窗帘",
-    //     isActive: false,
-    //     activeButton: null,
-    //     id: 1
-    // },
-    // {
-    //     name: "外侧窗帘",
-    //     isActive: false,
-    //     activeButton: null,
-    //     id: 2
-    // },
-])
+const childCurtains = ref([])
 const controlStatus = ref('')
 const topActive = ref(false)
 const downActive = ref(false)
@@ -97,7 +95,7 @@ const setEnnv = (type,value,code,curentID )=>{
         }
         paramsData.push(paramsObj)
     }
-    // httpSetEnv(paramsData)
+    httpSetEnv(paramsData)
 }
 const handle = (type, status, name,code, curentID) => {
     controlStatus.value = name;
@@ -126,6 +124,7 @@ const handle = (type, status, name,code, curentID) => {
     } else {
         setEnnv(type,status,code,curentID)
         childCurtains.value.forEach((item) => {
+
             if (item.id === curentID) {
                 item.activeButton = status;
                 item.isActive = true;
@@ -139,7 +138,7 @@ const handle = (type, status, name,code, curentID) => {
                 item.isActive = false;
                 item.activeButton = null;
             });
-        }, 100);
+        }, 1000);
     }
 };
 watch(
@@ -252,24 +251,16 @@ watch(
                 align-items: center;
                 .control {
                     display: flex;
-                    width: 40px;
-                    height: 40px;
+                    width: 24px;
+                    height: 24px;
                     justify-content: center;
                     align-items: center;
                     margin-left: 10px;
-                    border-radius: 60px;
-                    opacity: 0.6;
-                    background: rgba(255, 255, 255, 0.4);
-                    backdrop-filter: blur(30px);
-                    color: #000;
-                    font-family: Jost;
-                    font-size: 16px;
-                    font-style: normal;
-                    font-weight: 300;
-                    line-height: normal;
-                }
-                .control.active {
-                    opacity: 1;
+                    img{
+                        width: 17px;
+                        height: 17px; 
+                    }
+                   
                 }
             }
         }

+ 67 - 39
src/views/envmonitor/taiguv1/components/Curtain/index.vue

@@ -2,15 +2,26 @@
     <div
         class="volumn-box"
         :class="isOpen ? 'active' : ''"
-        @click="searchMore"
     >
-        <div class="top">
-            <img
-                :src="
-          parseImgUrl('taiguv1/envmonitor/', isOpen ? 'active/curtain.svg' : 'curtain.svg')
-        "
-                alt=""
-            />
+        <div>
+
+            <div class="top">
+                <img
+                    :src="isOpen ? CurtainCardIcon : CurtainCardUnActiveIcon"
+                    alt=""
+                />
+            </div>
+            <div class="filter-box" v-if="curtainsList.length > 1">
+                <div
+                    class="filter-item"
+                    @click="searchMore"
+                >
+                    <img
+                        :src="FilterIcon"
+                        alt=""
+                    />
+                </div>
+            </div>
         </div>
         <div class="bottom">
             <div class="text">窗帘</div>
@@ -22,9 +33,14 @@
                 >
                     <div
                         class="control-item"
-                        :class="item.isActive ? 'active' : ''"
                         @click.stop="handle(item.value, item.status,item.code)"
-                    >{{ item.name }}</div>
+                    >
+                        <img
+                            :src="item.isActive ? item.iconActive : item.iconUnActive"
+                            alt=""
+                        >
+                    </div>
+
                 </div>
             </div>
         </div>
@@ -32,13 +48,22 @@
 </template>
 
 <script setup>
-import { parseImgUrl } from "@/utils";
+import { httpSetEnv } from '@/apis/taiguv1';
+import CurtainCardIcon from '@/assets/taiguv1/svg/Curtain_card_active_icon.svg';
+import CurtainCardUnActiveIcon from '@/assets/taiguv1/svg/Curtain_card_unactive_icon.svg';
+import DownActiveIcon from '@/assets/taiguv1/svg/down_active_icon.svg';
+import DownUnActiveIcon from '@/assets/taiguv1/svg/down_icon.svg';
+import FilterIcon from '@/assets/taiguv1/svg/filter_icon.svg';
+import StopActiveIcon from '@/assets/taiguv1/svg/stop_active_icon.svg';
+import StopUnActiveIcon from '@/assets/taiguv1/svg/stop_icon.svg';
+import UpActiveIcon from '@/assets/taiguv1/svg/up_active_icon.svg';
+import UpUnActiveIcon from '@/assets/taiguv1/svg/up_icon.svg';
 import { onBeforeUnmount, onMounted, ref, watch } from "vue";
 const controlStatus = ref('')
 const controlName = ref([
-    { isActive: false, name: '上', value: 1, status: '开启中', code: 'EquipOnSet' },
-    { isActive: false, name: '停', value: 2, status: '暂停中', code: 'EquipStop' },
-    { isActive: false, name: '下', value: 0, status: '关闭中', code: 'EquipOffSet' },
+    { isActive: false, name: '上', value: 1, status: '开启中', code: 'EquipOnSet', iconActive: UpActiveIcon, iconUnActive: UpUnActiveIcon },
+    { isActive: false, name: '停', value: 2, status: '暂停中', code: 'EquipStop', iconActive: StopActiveIcon, iconUnActive: StopUnActiveIcon },
+    { isActive: false, name: '下', value: 0, status: '关闭中', code: 'EquipOffSet', iconActive: DownActiveIcon, iconUnActive: DownUnActiveIcon },
 ])
 const isOpen = ref(true)
 const isActive = ref(false)
@@ -61,7 +86,7 @@ const handle = (value, status, code) => {
             item.isActive = true;
             btnTimer = setTimeout(() => {
                 item.isActive = false;
-            }, 100);
+            }, 700);
         } else {
             item.isActive = false;
         }
@@ -85,8 +110,6 @@ const props = defineProps({
 
 const setEnv = (value, code) => {
     let paramsData = []
-    console.log(curtainsList,'窗帘1');
-    
     curtainsList.value.forEach(item => {
         paramsData.push({
             id: item.id,
@@ -94,22 +117,21 @@ const setEnv = (value, code) => {
             code
         })
     })
-    // httpSetEnv(paramsData)
+    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);
+            httpSetEnv(curtainsList.value);
         }
         // 场景切换了,需要设置环境
     },
@@ -133,6 +155,24 @@ onMounted(() => { });
     background: rgba(255, 255, 255, 0.2);
     backdrop-filter: blur(40px);
     box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
+
+    .filter-box {
+        margin-top: 10px;
+        display: flex;
+        justify-content: flex-end;
+        gap: 10px;
+        .filter-item {
+            display: flex;
+            width: 36px;
+            height: 36px;
+            justify-content: center;
+            align-items: center;
+            gap: 10px;
+            flex-shrink: 0;
+            border-radius: 60px;
+            background: var(--White-White-40, rgba(255, 255, 255, 0.4));
+        }
+    }
     .top {
         display: flex;
         justify-content: space-between;
@@ -176,24 +216,12 @@ onMounted(() => { });
                 display: flex;
                 align-items: center;
                 justify-content: center;
-                width: 36px;
-                height: 36px;
-                border-radius: 60px;
-                opacity: 0.6;
-                background: var(--White-White-40, rgba(255, 255, 255, 0.4));
-                backdrop-filter: blur(30px);
-                font-family: Jost;
-                font-size: 16px;
-                color: var(--Blue, #001428);
-                font-style: normal;
-                font-weight: 300;
-                line-height: normal;
-            }
-            .control-item.active {
-                border-radius: 60px;
-                opacity: 1;
-                box-shadow: 0px 10px 20px 0px rgba(0, 20, 40, 0.1);
-                color: #000;
+                width: 24px;
+                height: 24px;
+                img {
+                    width: 17px;
+                    height: 17px;
+                }
             }
         }
     }

+ 163 - 154
src/views/envmonitor/taiguv1/components/Lamp/LightMore.vue

@@ -4,23 +4,30 @@
       <div class="left">
         <div class="light-box">
           <img
-            :src="LampsStatus === '全部关闭' ? lampCloseIcon : lampOpenIcon"
+            :src="lampData.isOpen ? lampOpenIcon : lampCloseIcon"
             alt=""
-            :style="LampsStatus !== '全部关闭' ? { width: '58px', height: '62px' } : ''" />
+            :style="lampData.isOpen ? { width: '58px', height: '62px' } : ''" />
         </div>
-        <div class="light-name">{{ LampsStatus }}</div>
+        <div class="light-name">{{ lampData.lampStatusText }}</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 class="control" :ref="setRef" @click="handleSwitch('isOpen', true)">全开</div>
+        <div class="control" :ref="setRef" @click="handleSwitch('isOpen', false)">全关</div>
       </div>
     </div>
-    <div class="light-middle" v-if="LampsStatus !== '全部关闭'">
+    <div class="light-middle" v-if="lampData.isOpen">
       <div class="bright-slider">
-        <Slider v-model="allBrightValue" :showValue="true" :isFollow="true" suffix="%" />
+        <Slider
+          :min="min"
+          :max="max"
+          v-model="lampData.brightValue"
+          isFollow
+          showValue
+          suffix="%"
+          @onEnd="setLampStatus('brightValue')" />
       </div>
       <div class="temp-slider">
-        <LampSlider v-model="allColorTempValue" />
+        <LampSlider v-model="lampData.colorTempValue" @onEnd="setLampStatus('colorTempValue')" />
       </div>
     </div>
 
@@ -29,15 +36,12 @@
     </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 class="item-box" :class="item.valueSwitch ? 'light-box-active ' : ''" v-for="(item, index) in lampList">
+        <div class="name">{{ item.localName }}</div>
+        <SwitchButton
+          :loading="allLampStatus[item.id]?.loading"
+          v-model="item.isOpen"
+          @change="sigleLampChange('isOpen', item, 'single')" />
       </div>
     </div>
   </div>
@@ -49,168 +53,173 @@ 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)
+import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
 
+import useDeviceControl from '@/hooks/useDeviceControl'
+import { useStore } from '@/store'
+const store = useStore()
+const deviceControl = useDeviceControl()
+const min = 0
+const max = 100
 // 接收父组件传递的初始状态
 const props = defineProps({
-  initialStatus: {
-    type: Boolean,
-    default: false
+  lampStatus: {
+    type: Object,
+    default: () => {
+      return {
+        isOpen: false,
+        brightValue: 0
+      }
+    }
   },
-  currentLamps: {
+  equipList: {
     type: Array,
-    default: () => []
+    default: () => {
+      return []
+    }
   }
 })
 
-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
+const controlBtn = ref([])
+const setRef = el => {
+  if (el) {
+    if (!controlBtn.value.includes(el)) {
+      controlBtn.value.push(el)
+    }
   }
-  LampsStatus.value = '部分开启'
-  emit('statusChange', true, LampsStatus.value)
 }
 
-let timer = null
-const handleSwitch = type => {
-  if (timer) {
-    clearTimeout(timer)
-  }
-  isHandlingSwitchOperation.value = true
+const lampList = ref([])
+const lampData = ref(props.lampStatus)
 
-  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 allLampStatus = computed(() => store.state.taiguv1.lampSwitchStatus)
 
-  const commands = []
-  childLights.value.forEach(item => {
-    const objName = {
-      id: item.id,
-      code: item.codeSwitch,
-      value: item.valueSwitch ? 1 : 0
+// const lampSwitchStatus = computed(() => {
+//   let statusText = ''
+//   let switchStatus = false
+//   let arr = props.equipList.filter(item => item.runStatus == 1)
+//   if (arr.length == 0) {
+//     statusText = '全部关闭'
+//     switchStatus = false
+//   } else {
+//     statusText = arr.length > 0 && arr.length < props.equipList.length ? '部分开启' : '全部开启'
+//     switchStatus = true
+//   }
+//   return {
+//     statusText,
+//     switchStatus
+//   }
+// })
+watch(
+  () => props.lampStatus,
+  (newVal, oldVal) => {
+    if (!newVal) {
+      return
     }
-    commands.push(objName)
-  })
-  // httpSetEnv(commands);
-
-  setTimeout(() => {
-    isHandlingSwitchOperation.value = false
-  }, 0)
-}
+    let { brightValue } = lampData.value
+    lampData.value = { ...newVal, brightValue }
+  },
+  { deep: true } // 添加深度监听
+)
+watch(
+  () => props.equipList,
+  (newVal, oldVal) => {
+    compareStatus(newVal)
+  },
+  { deep: true }
+)
 
-const handleChildLight = itemCurrent => {
-  childLights.value.forEach(item => {
-    if (item.id === itemCurrent.id) {
-      item.valueSwitch = itemCurrent.valueSwitch
+// 对比和store中开关状态
+const compareStatus = data => {
+  lampList.value = data.map(item => {
+    if (allLampStatus.value[item.id]) {
+      if (allLampStatus.value[item.id].lastSwitchStatus == item.runStatus) {
+        store.dispatch('taiguv1/setLampStatus', {
+          id: item.id,
+          status: {
+            loading: false,
+            lastSwitchStatus: item.runStatus == 1
+          }
+        })
+        return {
+          ...item,
+          isOpen: item.runStatus == 1
+        }
+      } else {
+        return {
+          ...item,
+          isOpen: allLampStatus.value[item.id].lastSwitchStatus
+        }
+      }
+    } else {
+      return {
+        ...item,
+        isOpen: item.runStatus == 1
+      }
     }
   })
-  checkLampsStatus()
-  const objName = {
-    id: itemCurrent.id,
-    code: itemCurrent.codeSwitch,
-    value: itemCurrent.valueSwitch ? 1 : 0
-  }
-  const commands = [objName]
-  // httpSetEnv(commands);
+}
+// 整体开关
+const handleSwitch = (type, value) => {
+  lampData.value.isOpen = value
+  setLampStatus(type)
 }
 
-const setEnvMmode = () => {
-  // 创建一个数组来存储所有需要设置的指令
-  const commands = []
-
-  childLights.value.forEach(item => {
-    // 开关指令
-    commands.push({
-      id: item.id,
-      code: item.codeSwitch,
-      value: item.valueSwitch
+// 单个空调开关
+const sigleLampChange = (type, source, all) => {
+  if (type == 'isOpen') {
+    store.dispatch('taiguv1/setLampStatus', {
+      id: source.id,
+      status: {
+        loading: true,
+        lastSwitchStatus: source.isOpen
+      }
     })
-
-    // 亮度指令
-    commands.push({
-      id: item.id,
-      code: item.codeBright,
-      value: item.valueBright
+  }
+  if (all == 'single') {
+    const params = deviceControl.assemblyLampCommand(source[type], type, source)
+    deviceControl.sendCommands(params)
+  }
+}
+const setLampStatus = type => {
+  if (type == 'isOpen') {
+    store.dispatch('taiguv1/setLampStatus', {
+      id: 'all',
+      status: {
+        loading: true,
+        lastSwitchStatus: lampData.value.isOpen
+      }
     })
-
-    // 色温指令
-    commands.push({
-      id: item.id,
-      code: item.codeColorTemp,
-      value: item.valueColorTemp
+    lampList.value.forEach(item => {
+      item.isOpen = lampData.value.isOpen
+      sigleLampChange(type, item, 'all')
+    })
+  }
+  const params = deviceControl.assemblyLampCommand(lampData.value[type], type, lampList.value)
+  deviceControl.sendCommands(params)
+}
+onMounted(() => {
+  nextTick(() => {
+    controlBtn.value.forEach(button => {
+      button.addEventListener('touchstart', handleTouchStart)
     })
   })
+})
 
-  // httpSetEnv(commands);
+// 添加 touchstart 处理函数
+const handleTouchStart = event => {
+  const button = event.currentTarget
+  button.classList.add('active')
+  setTimeout(() => {
+    button.classList.remove('active')
+  }, 200)
 }
-
-// 添加 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(() => {})
+// 添加 onUnmounted 钩子
+onUnmounted(() => {
+  controlBtn.value.forEach(button => {
+    button.removeEventListener('touchstart', handleTouchStart)
+  })
+})
 </script>
 <style lang="scss" scoped>
 .more-box {

+ 120 - 41
src/views/envmonitor/taiguv1/components/Lamp/index.vue

@@ -1,80 +1,142 @@
 <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">
-        <SwitchButton v-model="isOpen" @change="handleSwitch" />
+  <div class="volumn-box" :class="lampData.isOpen ? 'active' : ''">
+    <div>
+      <div class="top">
+        <img :src="parseImgUrl('taiguv1/envmonitor', lampData.isOpen ? 'active/lamp.svg' : 'lamp.svg')" alt="" />
+        <div class="top-right">
+          <SwitchButton
+            :loading="allLampStatus.all?.loading"
+            @click.stop
+            v-model="lampData.isOpen"
+            @change="setLampStatus('isOpen')" />
+        </div>
+      </div>
+      <div class="filter-box">
+        <div class="filter-item" @click="searchMore">
+          <img :src="FilterIcon" alt="" />
+        </div>
       </div>
     </div>
+
     <div class="bottom">
       <div class="bottom-box">
         <div class="bottom-left">
           <div class="text">光照</div>
-          <div class="status">{{ lampStatusText }}</div>
+          <div class="status">{{ lampData.lampStatusText }}</div>
         </div>
 
-        <div class="bottom-right" v-if="isOpen">
-          {{ lampValue }}
+        <div class="bottom-right" v-if="lampData.isOpen">
+          {{ lampData.brightValue }}
         </div>
       </div>
 
-      <div class="lamp-slider" v-if="isOpen">
-        <Slider v-model="lampValue"></Slider>
+      <div class="lamp-slider" v-if="lampData.isOpen">
+        <Slider v-model="lampData.brightValue" :min="min" :max="max" @onEnd="setLampStatus('bright')"></Slider>
       </div>
-
-      <!-- <Slider v-model="lampValue"></Slider> -->
     </div>
   </div>
 </template>
 
 <script setup>
+import FilterIcon from '@/assets/taiguv1/svg/filter_icon.svg'
 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)
-}
-const childStatus = ref('')
-const handleSwitch = () => {
-  // 发送开关状态变化事件到父组件
-  emit('switchChange', isOpen.value)
-}
+import { ref, watch, computed } from 'vue'
+import { useStore } from '@/store'
+import useDeviceControl from '@/hooks/useDeviceControl'
+const min = 0
+const max = 100
+const emit = defineEmits(['getStatus', 'showMore'])
 
 // 接收父组件传递的开关状态
 const props = defineProps({
-  lampStatusText: {
-    type: String,
-    default: () => '全部关闭'
-  },
-  lampStaus: {
+  lampStatus: {
     type: Object,
     default: () => {
       return {
         isOpen: false,
-        gear: 1,
-        minTempSet: 16,
-        maxTempSet: 32,
-        tempSet: 24,
-        isAutoGear: false,
-        switchLoading: false
+        brightValue: 0
       }
     }
+  },
+  equipList: {
+    type: Array,
+    default: () => {
+      return []
+    }
   }
 })
 
+const store = useStore()
+const deviceControl = useDeviceControl()
+const allLampStatus = computed(() => store.state.taiguv1.lampSwitchStatus)
+
+const searchMore = () => {
+  emit('showMore', 'lamp', true)
+}
+
+const lampData = ref({
+  isOpen: false,
+  brightValue: 0
+})
+
 watch(
-  () => props.lampStatusText,
-  newVal => {
-    childStatus.value = newVal
+  () => props.lampStatus,
+  (newVal, oldVal) => {
+    if (!newVal) {
+      return
+    }
+    console.log('props.lampStaus')
+    compareStatus(newVal)
   },
-  { immediate: true }
+  { deep: true } // 添加深度监听
 )
+
+const compareStatus = data => {
+  if (allLampStatus.value.all) {
+    if (allLampStatus.value.all.lastSwitchStatus == data.isOpen) {
+      store.dispatch('taiguv1/setLampStatus', {
+        id: 'all',
+        status: {
+          loading: false,
+          lastSwitchStatus: data.isOpen
+        }
+      })
+      lampData.value = {
+        ...data,
+        isOpen: data.isOpen
+      }
+    } else {
+      lampData.value = {
+        ...data,
+        isOpen: allLampStatus.value.all.lastSwitchStatus
+      }
+    }
+  } else {
+    lampData.value = {
+      ...data,
+      isOpen: data.isOpen
+    }
+  }
+  emit('getStatus', lampData.value.isOpen)
+}
+
+const setLampStatus = type => {
+  if (type == 'isOpen') {
+    store.dispatch('taiguv1/setLampStatus', {
+      id: 'all',
+      status: {
+        loading: true,
+        lastSwitchStatus: lampData.value.isOpen
+      }
+    })
+  }
+  const params = deviceControl.assemblyLampCommand(lampData.value[type], type, props.equipList)
+  deviceControl.sendCommands(params)
+
+  emit('getStatus', lampData.value.isOpen)
+}
 </script>
 <style lang="scss" scoped>
 .volumn-box {
@@ -98,6 +160,23 @@ watch(
       height: 30px;
     }
   }
+  .filter-box {
+    margin-top: 10px;
+    display: flex;
+    justify-content: flex-end;
+    gap: 10px;
+    .filter-item {
+      display: flex;
+      width: 36px;
+      height: 36px;
+      justify-content: center;
+      align-items: center;
+      gap: 10px;
+      flex-shrink: 0;
+      border-radius: 60px;
+      background: var(--White-White-40, rgba(255, 255, 255, 0.4));
+    }
+  }
   .bottom {
     .bottom-box {
       flex: 1;

+ 48 - 0
src/views/envmonitor/taiguv1/const.js

@@ -1,13 +1,23 @@
 const GenerolModeIcon = require("@/assets/taiguv1/svg/GenerolMode_icon.svg");
+const UnGenerolModeIcon = require("@/assets/taiguv1/svg/un_GenerolMode_icon.svg");
 const VcModeIcon = require("@/assets/taiguv1/svg/VcMode_icon.svg");
+const UnVcModeIcon = require("@/assets/taiguv1/svg/un_VcMode_icon.svg");
 const YogaModeIcon = require("@/assets/taiguv1/svg/YogaMode_icon.svg");
+const UnYogaModeIcon = require("@/assets/taiguv1/svg/un_YogaMode_icon.svg");
 const RoadshowsIcon = require("@/assets/taiguv1/svg/Roadshows_icon.svg");
+const UnRoadshowsIcon = require("@/assets/taiguv1/svg/un_Roadshows_icon.svg");
 const PrivateDiningIcon = require("@/assets/taiguv1/svg/PrivateDining_icon.svg");
+const UnPrivateDiningIcon = require("@/assets/taiguv1/svg/un_PrivateDining_icon.svg");
 const OpenHouseIcon = require("@/assets/taiguv1/svg/OpenHouse_icon.svg");
+const UnOpenHouseIcon = require("@/assets/taiguv1/svg/un_OpenHouse_icon.svg");
 const CinemaIcon = require("@/assets/taiguv1/svg/Cinema_icon.svg");
+const UnCinemaIcon = require("@/assets/taiguv1/svg/un_Cinema_icon.svg");
 const PrivateAuctionIcon = require("@/assets/taiguv1/svg/PrivateAuction_icon.svg");
+const UnPrivateAuctionIcon = require("@/assets/taiguv1/svg/un_PrivateAuction_icon.svg");
 const FoodTastingIcon = require("@/assets/taiguv1/svg/FoodTasting_icon.svg");
+const UnFoodTastingIcon = require("@/assets/taiguv1/svg/un_FoodTasting_icon.svg");
 const ProjectionIcon = require("@/assets/taiguv1/svg/Projection_icon.svg");
+const UnProjectionIcon = require("@/assets/taiguv1/svg/un_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");
@@ -30,6 +40,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005489a578b67eb44fabbf5643fc7cade61",
@@ -124,6 +135,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005489a578b67eb44fabbf5643fc7cade61",
@@ -214,6 +226,7 @@ export const roomSourceData = [
             englishName: "Projection",
             id: "2",
             activeSvg: ProjectionIcon,
+            unActiveSvg: UnProjectionIcon,
             lamps: [
               {
                 id: "Eq3301050005489a578b67eb44fabbf5643fc7cade61",
@@ -304,6 +317,7 @@ export const roomSourceData = [
             englishName: "VC Mode",
             id: "3",
             activeSvg: VcModeIcon,
+            unActiveSvg: UnVcModeIcon,
             lamps: [
               {
                 id: "Eq3301050005489a578b67eb44fabbf5643fc7cade61",
@@ -418,6 +432,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -513,6 +528,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -603,6 +619,7 @@ export const roomSourceData = [
             englishName: "Projection",
             id: "2",
             activeSvg: ProjectionIcon,
+            unActiveSvg: UnProjectionIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -693,6 +710,7 @@ export const roomSourceData = [
             englishName: "VC Mode",
             id: "3",
             activeSvg: VcModeIcon,
+            unActiveSvg: UnVcModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -788,6 +806,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -878,6 +897,7 @@ export const roomSourceData = [
             englishName: "Yoga",
             id: "2",
             activeSvg: YogaModeIcon,
+            unActiveSvg: UnYogaModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -973,6 +993,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -1063,6 +1084,7 @@ export const roomSourceData = [
             englishName: "Private Dining",
             id: "2",
             activeSvg: PrivateDiningIcon,
+            unActiveSvg: UnPrivateDiningIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -1158,6 +1180,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -1248,6 +1271,7 @@ export const roomSourceData = [
             englishName: "Open House",
             id: "2",
             activeSvg: OpenHouseIcon,
+            unActiveSvg: UnOpenHouseIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -1343,6 +1367,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -1433,6 +1458,7 @@ export const roomSourceData = [
             englishName: "Roadshows",
             id: "2",
             activeSvg: RoadshowsIcon,
+            unActiveSvg: UnRoadshowsIcon,
             lamps: [
               {
                 id: "Eq33010500056256413e463a454194bf45e9a93708c9",
@@ -1547,6 +1573,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500058e8af2fbb4874e0782cb95218f0719c7",
@@ -1712,6 +1739,7 @@ export const roomSourceData = [
             englishName: "Projection",
             id: "2",
             activeSvg: ProjectionIcon,
+            unActiveSvg: UnProjectionIcon,
             lamps: [
               {
                 id: "Eq33010500058e8af2fbb4874e0782cb95218f0719c7",
@@ -1792,6 +1820,7 @@ export const roomSourceData = [
             englishName: "VC Mode",
             id: "3",
             activeSvg: VcModeIcon,
+            unActiveSvg: UnVcModeIcon,
             lamps: [
               {
                 id: "Eq33010500058e8af2fbb4874e0782cb95218f0719c7",
@@ -1877,6 +1906,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500058e8af2fbb4874e0782cb95218f0719c7",
@@ -1957,6 +1987,7 @@ export const roomSourceData = [
             englishName: "Private Auction",
             id: "2",
             activeSvg: PrivateAuctionIcon,
+            unActiveSvg: UnPrivateAuctionIcon,
             lamps: [
               {
                 id: "Eq33010500058e8af2fbb4874e0782cb95218f0719c7",
@@ -2122,6 +2153,7 @@ export const roomSourceData = [
             englishName: "Cinema",
             id: "2",
             activeSvg: CinemaIcon,
+            unActiveSvg: UnCinemaIcon,
             lamps: [
               {
                 id: "Eq33010500058e8af2fbb4874e0782cb95218f0719c7",
@@ -2221,6 +2253,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005a11cfda11638425cadbd9da35d3c6701",
@@ -2312,6 +2345,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005a11cfda11638425cadbd9da35d3c6701",
@@ -2398,6 +2432,7 @@ export const roomSourceData = [
             englishName: "Projection",
             id: "2",
             activeSvg: ProjectionIcon,
+            unActiveSvg: UnProjectionIcon,
             lamps: [
               {
                 id: "Eq3301050005a11cfda11638425cadbd9da35d3c6701",
@@ -2489,6 +2524,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005a11cfda11638425cadbd9da35d3c6701",
@@ -2575,6 +2611,7 @@ export const roomSourceData = [
             englishName: "Food Tasting",
             id: "2",
             activeSvg: FoodTastingIcon,
+            unActiveSvg: UnFoodTastingIcon,
             lamps: [
               {
                 id: "Eq3301050005a11cfda11638425cadbd9da35d3c6701",
@@ -2680,6 +2717,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005789a729d25664dd99ebda00b82acb330",
@@ -2758,6 +2796,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq3301050005789a729d25664dd99ebda00b82acb330",
@@ -2831,6 +2870,7 @@ export const roomSourceData = [
             englishName: "Projection",
             id: "2",
             activeSvg: ProjectionIcon,
+            unActiveSvg: UnProjectionIcon,
             lamps: [
               {
                 id: "Eq3301050005789a729d25664dd99ebda00b82acb330",
@@ -2904,6 +2944,7 @@ export const roomSourceData = [
             englishName: "VC Mode",
             id: "3",
             activeSvg: VcModeIcon,
+            unActiveSvg: UnVcModeIcon,
             lamps: [
               {
                 id: "Eq3301050005789a729d25664dd99ebda00b82acb330",
@@ -2996,6 +3037,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq330105000504db37237ccf4bb68a563eafd0c7c450",
@@ -3071,6 +3113,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq330105000504db37237ccf4bb68a563eafd0c7c450",
@@ -3141,6 +3184,7 @@ export const roomSourceData = [
             englishName: "Projection",
             id: "2",
             activeSvg: ProjectionIcon,
+            unActiveSvg: UnProjectionIcon,
             lamps: [
               {
                 id: "Eq330105000504db37237ccf4bb68a563eafd0c7c450",
@@ -3211,6 +3255,7 @@ export const roomSourceData = [
             englishName: "VC Mode",
             id: "3",
             activeSvg: VcModeIcon,
+            unActiveSvg: UnVcModeIcon,
             lamps: [
               {
                 id: "Eq330105000504db37237ccf4bb68a563eafd0c7c450",
@@ -3300,6 +3345,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq330105000519f35f96f89c4fca95cf9f70da5278de",
@@ -3388,6 +3434,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq330105000510d1683a6e954988be1c6af16fc06559",
@@ -3466,6 +3513,7 @@ export const roomSourceData = [
             englishName: "Generol Mode",
             id: "1",
             activeSvg: GenerolModeIcon,
+            unActiveSvg: UnGenerolModeIcon,
             lamps: [
               {
                 id: "Eq33010500050d26b9830d9340ba977eaebc34dec653",

+ 83 - 207
src/views/envmonitor/taiguv1/index.vue

@@ -9,7 +9,7 @@
       :controls="false"
       :poster="roomInfo.bg"
       :src="roomInfo.video"></video>
-    <div class="video-model"></div>
+    <div class="video-model" v-if="roomInfo.id != 'room9' && roomInfo.id != 'room8' && roomInfo.id != 'room7'"></div>
     <div class="content">
       <div class="metting-info">
         <img class="logo" :src="roomInfo.icon" />
@@ -37,7 +37,7 @@
                         :src="modeType == item.id ?  item.activeSvg : item.activeSvg"
                         alt=""
                     /> -->
-          <img :src="item.activeSvg" alt="" />
+          <img :src="modeType == item.id ? item.activeSvg : item.unActiveSvg" alt="" />
           <span>{{ item.chineseName }}</span>
         </div>
       </div>
@@ -113,12 +113,12 @@
         <Volumn></Volumn>
       </div>
       <div class="box" v-if="spaceDevice.lamps">
-        <Lamp :currentLamps="spaceDevice.lamps" @switch-change="handleLampSwitch" @showMore="showMore"></Lamp>
+        <Lamp :equipList="lampEquipList" @showMore="showMore" :lampStatus="lampStatus"></Lamp>
       </div>
       <div class="box air-box">
-        <Air @getStatus="getStatus" :status="airStatus" @click="showMore('air')"></Air>
+        <Air @getStatus="getAirStatus" :equipList="airEquipList" :status="airStatus" @showMore="showMore"></Air>
       </div>
-      <div class="box" v-if="spaceDevice.curtains">
+      <div class="box" v-if="spaceDevice.curtains?.length">
         <Curtain @showMore="showMore" :modeType="modeType" :currentCurtains="spaceDevice.curtains"></Curtain>
       </div>
     </div>
@@ -131,23 +131,24 @@
       class="taigu-popup"
       teleport="#app">
       <div>
-        <LightMore
-          v-if="popupType == 'lamp'"
-          :initial-status="lampSwitchStatus"
-          @status-change="handleChildLampSwitch"
-          :currentLamps="spaceDevice.lamps"></LightMore>
+        <LightMore v-if="popupType == 'lamp'" :equipList="lampEquipList" :lampStatus="lampStatus"></LightMore>
         <CurtainMore v-if="popupType == 'curtain'" :currentCurtains="spaceDevice.curtains"></CurtainMore>
-        <AirMore v-if="popupType == 'air'" :currentLamps="spaceDevice.lamps"></AirMore>
+        <AirMore
+          @getStatus="getAirStatus"
+          v-if="popupType == 'air'"
+          :airList="airEquipList"
+          :status="airStatus"></AirMore>
       </div>
     </van-popup>
   </div>
 </template>
 
 <script setup>
-import { computed, onMounted, ref, onUnmounted } from 'vue'
+import { useStore } from '@/store'
+import { onMounted, onUnmounted, ref } from 'vue'
 import { useRoute } from 'vue-router'
-import Air from './components/Air/index.vue'
 import AirMore from './components/Air/AirMore.vue'
+import Air from './components/Air/index.vue'
 import CurtainMore from './components/Curtain/CurtainMore.vue'
 import Curtain from './components/Curtain/index.vue'
 import Lamp from './components/Lamp/index.vue'
@@ -157,11 +158,11 @@ import Volumn from './components/Volumn/index.vue'
 import { ENV_CONFIG, lanageArr, roomSourceData } from './const'
 const boxLine = require('@/assets/taiguv1/svg/box_line.png')
 // import "vue3-video-play/dist/style.css";
-import { httpSetEnv, queryAirStatus, queryLampStatus, httpGetByMeetingId, HttpGetSpaceInfo } from '@/apis/taiguv1'
-import { nextTick } from 'process'
+import { httpGetByMeetingId, HttpGetSpaceInfo, httpSetEnv, queryAirStatus, queryLampStatus } from '@/apis/taiguv1'
+import useDeviceControl from '@/hooks/useDeviceControl'
 const type = ref('zh')
-const deviceList = ['lamps', 'curtains', 'air', 'AV', 'screen']
 const route = useRoute()
+const deviceControl = useDeviceControl()
 const checkLanage = item => {
   type.value = item.type
 }
@@ -178,12 +179,10 @@ const modeType = ref('1')
 // 空间设备
 const spaceDevice = ref({})
 
-const _spaceDevice = ref({})
-
-const lampStatusText = ref('')
+const lampStatus = ref({})
+const lampEquipList = ref([])
 
 const airStatus = ref({
-  isOpen: false,
   minTempSet: 16,
   maxTempSet: 32,
   tempSet: 24,
@@ -197,32 +196,31 @@ const isPopup = ref(false)
 
 const popupType = ref(null)
 
-// const isCurtainMoreFlag = ref(false)
-
 const envParams = ref({})
 
-const lampSwitchStatus = ref(false)
-let airSwitchTimer = null
-const handleLampSwitch = status => {
-  lampSwitchStatus.value = status
-}
 const handleChildLampSwitch = (status, text) => {
-  lampSwitchStatus.value = status
-  lampStatusText.value = text
+  // lampSwitchStatus.value = status
+  // lampStatusText.value = text
 }
-let deviceStatusTimer = null
+let deviceStatusPolling = null
 const projectId = 'Pj3301050005'
 const airIsOpen = ref(false)
 // 添加场景执行标志
 const hasExecutedDefault = ref(false)
 const hasExecutedModeScene = ref(false)
+// const store = useStore()
 
 onMounted(() => {
   let roomId = route.query.id || 'room4'
 
   roomInfo.value = roomSourceData.find(item => item.id == roomId) || {}
-  // 获取场景===>轮询 30s
-  getSpaceScene({ meetingId: roomInfo.value.meetingId })
+
+  if (roomId == 'room7' || roomId == 'room8' || roomId == 'room9') {
+    showDefaultScene()
+  } else {
+    // 获取场景===>轮询 30s
+    getSpaceScene({ meetingId: roomInfo.value.meetingId })
+  }
 
   // 获取设备的状态===>需要轮询
   getDeviceStatus()
@@ -286,6 +284,17 @@ const handleEnvData = (type, num) => {
     unit: config.unit
   }
 }
+// 展示默认场景
+const showDefaultScene = () => {
+  // 默认场景
+  if (!hasExecutedDefault.value) {
+    spaceScene.value = 'SceneDefaul' // Meeting SceneDefaul
+    initSpace()
+    sendCommand()
+    hasExecutedDefault.value = true
+    hasExecutedModeScene.value = false // 重置会议场景标志
+  }
+}
 // 获取空间场景
 const getSpaceScene = params => {
   const polling = createPollingTask(() => {
@@ -309,23 +318,11 @@ const getSpaceScene = params => {
             }
           } else {
             // 默认场景
-            if (!hasExecutedDefault.value) {
-              spaceScene.value = 'SceneDefaul'
-              initSpace()
-              sendCommand()
-              hasExecutedDefault.value = true
-              hasExecutedModeScene.value = false // 重置会议场景标志
-            }
+            showDefaultScene()
           }
         } else {
           // 默认场景
-          if (!hasExecutedDefault.value) {
-            spaceScene.value = 'SceneDefaul'
-            initSpace()
-            sendCommand()
-            hasExecutedDefault.value = true
-            hasExecutedModeScene.value = false // 重置会议场景标志
-          }
+          showDefaultScene()
         }
       }
     })
@@ -342,7 +339,6 @@ const initSpace = () => {
   modeData.value = sceneData.value.mode || {}
   modeType.value = modeData.value[0].id
   spaceDevice.value = modeData.value[0]
-  _spaceDevice.value = { ...modeData.value[0] }
 }
 
 // 切换场景模式
@@ -359,92 +355,52 @@ const changeMode = type => {
 // 场景下给设备下发指令
 const sendCommand = () => {
   // 组装指令
-  let commands = assemblyLampCommand()
-  // TODO: A下发指令接口
-  console.log('commands')
-  httpSetEnv(commands).then(res => {
-    let { status, data } = res
-    if (status == 200) {
-      console.log('下发成功')
-    } else {
-      console.log('下发失败')
-    }
-  })
+  let devices = modeData.value.find(item => item.id == modeType.value)
+  let commands = deviceControl.initDeviceCommand(devices)
+  deviceControl.sendCommands(commands)
 }
 
 // 获取设备状态
 const getDeviceStatus = () => {
-  // let params = {
-  //   projectId: 'Pj1101010007',
-  //   spaceId: 'Sp1101010007e9cf6e1a3cd3425c8ba610087eb4052d'
-  // }
   let params = {
     projectId,
     spaceId: roomInfo.value.spaceId
   }
-  let polling = null
-  if (polling) {
-    polling.stop()
+
+  // 如果已存在polling实例,先停止它
+  if (deviceStatusPolling) {
+    deviceStatusPolling.stop()
   }
-  polling = createPollingTask(() => {
+
+  deviceStatusPolling = createPollingTask(() => {
     // 空调状态
     queryAirStatus(params).then(res => {
       if (res.result == 'success') {
-        // 更新空调状态
         updateAirStatus(res.data)
       }
     })
     // 灯具状态
     queryLampStatus(params).then(res => {
       if (res.result == 'success') {
-        // 更新空调状态
-        updateLampStatus(res.data)
+        updateLampStatus(res.content)
       }
     })
-  }, 5000)
+  }, 1000 * 2)
 
-  polling.start()
-
-  // clearTimeout(deviceStatusTimer)
-  // deviceStatusTimer = null
-
-  // const fetchStatus = () => {
-  //   // 空调状态
-  //   queryAirStatus(params).then(res => {
-  //     if (res.result == 'success') {
-  //       // 更新空调状态
-  //       updateAirStatus(res.data)
-  //     }
-  //   })
-  //   // 灯具状态
-  //   queryLampStatus(params).then(res => {
-  //     if (res.result == 'success') {
-  //       // 更新空调状态
-  //       updateLampStatus(res.data)
-  //     }
-  //   })
-
-  //   // 递归调用
-  //   deviceStatusTimer = setTimeout(fetchStatus, 2000)
-  // }
-
-  // // 首次调用
-  // fetchStatus()
+  deviceStatusPolling.start()
 }
 
+// 在组件卸载时确保清理定时器
+onUnmounted(() => {
+  if (deviceStatusPolling) {
+    deviceStatusPolling.stop()
+  }
+})
+
 const updateAirStatus = data => {
-  console.log(data.equipList, 'datam.equipList')
   let { runStatus, gear, tempSet, maxTempSet, minTempSet, isAutoGear, equipList = [] } = data || {}
-  let isOpen = runStatus == 1
-  if (airStatus.value.lastSwitchStatus != undefined && airStatus.value.lastSwitchStatus != isOpen) {
-    isOpen = airStatus.value.lastSwitchStatus
-  } else {
-    airStatus.value.switchLoading = false
-    clearTimeout(airSwitchTimer)
-    airSwitchTimer = null
-  }
   airStatus.value = {
-    isOpen,
+    runStatus,
     gear,
     tempSet,
     maxTempSet,
@@ -453,11 +409,26 @@ const updateAirStatus = data => {
     lastSwitchStatus: airStatus.value.lastSwitchStatus,
     switchLoading: airStatus.value.switchLoading
   }
-  airIsOpen.value = isOpen
+  // console.log(airStatus.value, '  airStatus.value ')
+  // airIsOpen.value = isOpen
   airEquipList.value = equipList
 }
 
-const updateLampStatus = data => {}
+const updateLampStatus = data => {
+  let brightLamp = data.find(item => item.runStatus == 1)
+  let arr = data.filter(item => item.runStatus == 1)
+  lampStatus.value = {
+    brightValue: brightLamp?.brightValue,
+    colorTempValue: brightLamp?.colorTempValue,
+    lampStatusText: arr.length == 0 ? '全部关闭' : arr.length < data.length ? '部分开启' : '全部开启'
+  }
+  if (brightLamp) {
+    lampStatus.value.isOpen = true
+  } else {
+    lampStatus.value.isOpen = false
+  }
+  lampEquipList.value = data
+}
 
 // 打开左弹框
 const showMore = (type, showStatus) => {
@@ -472,75 +443,13 @@ const showMore = (type, showStatus) => {
 //   关闭左弹框
 const closePopup = () => {}
 
-// 组装灯和窗帘下发参数
-const assemblyLampCommand = types => {
-  let devices = modeData.value.find(item => item.id == modeType.value)
-  let { lamps = [], curtains = [] } = devices || {}
-  let commands = []
-  // 灯具指令
-  lamps.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
-    })
-  })
-  // 窗帘指令
-  curtains.forEach(item => {
-    commands.push({
-      id: item.id,
-      code: item.code,
-      value: item.value
-    })
-  })
-  return commands
-}
-const getStatus = (status, type) => {
-  airStatus.value = status
-  airIsOpen.value = airStatus.value.isOpen
-  sendAirCommand(type)
-}
-const sendAirCommand = type => {
-  airStatus.value.switchLoading = true
-
-  httpSetEnv(assemblyAirCommand(type)).then(res => {
-    let { status, data } = res
-    if (status === 200) {
-      console.log('下发成功')
-    } else {
-      console.log('下发失败')
-    }
-  })
-  setTimeout(() => {
-    getDeviceStatus()
-  }, 1500)
-  airSwitchTimer = setTimeout(() => {
-    airStatus.value.switchLoading = false
-    airStatus.value.isOpen = airStatus.value.lastSwitchStatus = !airStatus.value.lastSwitchStatus
-    setTimeout(() => {
-      airIsOpen.value = airStatus.value.isOpen
-    }, 700)
-  }, 1000 * 15)
+// 空调总开关
+const getAirStatus = status => {
+  airIsOpen.value = status
 }
 
 const createPollingTask = (callback, interval = 3000) => {
   let timer = null
-
   const start = firstCallbackDone => {
     clearTimeout(timer)
     timer = null
@@ -568,39 +477,6 @@ const createPollingTask = (callback, interval = 3000) => {
 
   return { start, stop }
 }
-
-// 组装空调的下发参数
-const assemblyAirCommand = type => {
-  let commands = []
-  console.log(type, 2222)
-  airEquipList.value.forEach(item => {
-    // 开关指令
-    if (type == 'isOpen') {
-      commands.push({
-        id: item.id,
-        code: item.switchCode,
-        value: airStatus.value.isOpen ? 1 : 0
-      })
-    }
-    // 温度指令
-    if (type == 'tempSet') {
-      commands.push({
-        id: item.id,
-        code: item.tempSetCode,
-        value: airStatus.value.tempSet
-      })
-    }
-    // 档位指令
-    if (type == 'gear') {
-      commands.push({
-        id: item.id,
-        code: item.gearCode,
-        value: airStatus.value.gear
-      })
-    }
-  })
-  return commands
-}
 </script>
 <style lang="scss">
 .main {