manualIndex.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. <template>
  2. <div class="air">
  3. <div class="air-top">
  4. <div class="air-desc">
  5. <p class="air-title">空调<i>手动模式</i></p>
  6. <p class="air-temperature">
  7. {{ airTemp ? airTemp : "--" }}
  8. <sup>℃</sup>
  9. </p>
  10. <div class="show-all" @click.stop="showAll">
  11. <van-icon :name="lightIcon" class="light-icon" />
  12. <span>显示全部</span>
  13. </div>
  14. </div>
  15. <div class="air-right">
  16. <img v-if="airData.airImg" :src="airData.airImg" alt="" />
  17. <van-loading style="padding-top: 20px" v-else />
  18. <Switch
  19. class="switch-btn"
  20. :loading="loadingAir || firstLoadingAir"
  21. :disabled="loadingAir || firstLoadingAir"
  22. inactive-color="rgba(196, 196, 196, 0.4)"
  23. @click="airChange"
  24. :model-value="airData.isOpen"
  25. />
  26. </div>
  27. </div>
  28. <!--温度调节-->
  29. <template v-if="!showChild">
  30. <div class="air-control air-control-padding">
  31. <div class="control-box">
  32. <div class="temp-text">{{ airData.minTempSet }}℃</div>
  33. <div class="temp-slider" id="sliderId">
  34. <div
  35. class="item"
  36. v-for="(item, index) in 5"
  37. :key="'bar' + index"
  38. ></div>
  39. <div class="slider-bar" id="barId">
  40. <div class="bar-temp">{{ realTemp }}℃</div>
  41. <div class="bar-circle" id="handId"></div>
  42. </div>
  43. </div>
  44. <div class="temp-text">{{ airData.maxTempSet }}℃</div>
  45. </div>
  46. <div class="control-text">温度设定</div>
  47. </div>
  48. <div class="air-control">
  49. <div class="control-box">
  50. <div class="volume-box">
  51. <div class="number">
  52. <span
  53. v-for="(item, index) in windGearArr"
  54. :class="airData.gear === item ? 'number-active' : ''"
  55. :key="'volume' + index"
  56. >{{ item }}</span
  57. >
  58. </div>
  59. <div class="text">风量调节</div>
  60. </div>
  61. <div class="volume-icon">
  62. <div class="icon-item" @click="changeZongAir('gear', 'windLow')">
  63. <img :src="parseImgUrl('ipdImages', 'wind_small.png')" />
  64. </div>
  65. <div class="icon-item" @click="changeZongAir('gear', 'windUp')">
  66. <img :src="parseImgUrl('ipdImages', 'wind_big.png')" />
  67. </div>
  68. <div
  69. class="icon-item"
  70. @click="changeZongAir('gear', 'auto')"
  71. :class="airData.isAutoGear ? 'active-color' : ''"
  72. >
  73. <span> AUTO</span>
  74. </div>
  75. </div>
  76. </div>
  77. </div>
  78. <div class="air-control">
  79. <div class="control-box">
  80. <div class="volume-box">
  81. <div class="model">
  82. {{
  83. airData.workMode == 1
  84. ? "制冷"
  85. : airData.workMode == 2
  86. ? "制热"
  87. : "通风"
  88. }}
  89. </div>
  90. <div class="text">模式设定</div>
  91. </div>
  92. <div class="volume-icon">
  93. <div
  94. class="icon-item"
  95. :class="airData.workMode === 2 ? 'active-color' : ''"
  96. @click="changeZongAir('mode', 2)"
  97. >
  98. <img
  99. :src="
  100. airData.workMode === 2
  101. ? parseImgUrl('ipdImages', 'airsunred.svg')
  102. : parseImgUrl('ipdImages', 'airsunblack.svg')
  103. "
  104. />
  105. </div>
  106. <div
  107. class="icon-item"
  108. :class="airData.workMode === 1 ? 'active-color' : ''"
  109. @click="changeZongAir('mode', 1)"
  110. >
  111. <img
  112. :src="
  113. airData.workMode === 1
  114. ? parseImgUrl('ipdImages', 'aircoldblue.svg')
  115. : parseImgUrl('ipdImages', 'aircoldblack.svg')
  116. "
  117. />
  118. </div>
  119. <div
  120. class="icon-item"
  121. :class="airData.workMode === 3 ? 'active-color' : ''"
  122. @click="changeZongAir('mode', 3)"
  123. >
  124. <img
  125. :src="
  126. airData.workMode === 3
  127. ? parseImgUrl('ipdImages', 'aircloudgreen.svg')
  128. : parseImgUrl('ipdImages', 'aircloudblack.svg')
  129. "
  130. />
  131. </div>
  132. </div>
  133. </div>
  134. </div>
  135. </template>
  136. <!--子设备-->
  137. <div class="air-child" v-if="showChild">
  138. <div
  139. class="child-control-box"
  140. :key="'child' + index"
  141. v-for="(childItem, index) in equipList"
  142. >
  143. <div class="open-title">
  144. <span>{{ childItem.localName }}</span>
  145. <Switch
  146. class="child-switch"
  147. inactive-color="rgba(196, 196, 196, 0.4)"
  148. size="25px"
  149. />
  150. </div>
  151. <div class="adjust-box">
  152. <div class="adjust-item">
  153. <van-icon
  154. name="arrow-up"
  155. @click="changeItemAir('temp', childItem)"
  156. class="adjust-icon"
  157. />
  158. <span class="adjust-text">{{ childItem.tempSet }}</span>
  159. <van-icon name="arrow-down" class="adjust-icon" />
  160. <span class="adjust-title">温度</span>
  161. </div>
  162. <div class="adjust-item">
  163. <van-icon name="arrow-up" class="adjust-icon" />
  164. <span class="adjust-text">{{ childItem.gear }}</span>
  165. <van-icon name="arrow-down" class="adjust-icon" />
  166. <span class="adjust-title">档位</span>
  167. </div>
  168. <div class="adjust-item">
  169. <van-icon name="arrow-up" class="adjust-icon" />
  170. <span class="adjust-text">
  171. {{
  172. childItem.workMode == 1
  173. ? "制冷"
  174. : childItem.workMode == 2
  175. ? "制热"
  176. : "通风"
  177. }}
  178. </span>
  179. <van-icon name="arrow-down" class="adjust-icon" />
  180. <span class="adjust-title">模式</span>
  181. </div>
  182. </div>
  183. </div>
  184. </div>
  185. <!-- v-if="cotrolLoading" -->
  186. <!-- <div class="loading-box" v-if="cotrolLoading">
  187. <van-loading style="padding-top: 20px" />
  188. </div> -->
  189. </div>
  190. </template>
  191. <script lang="ts">
  192. import {
  193. defineComponent,
  194. onMounted,
  195. reactive,
  196. toRefs,
  197. computed,
  198. watch,
  199. onUnmounted,
  200. onBeforeMount,
  201. onBeforeUnmount,
  202. nextTick,
  203. } from "vue";
  204. import { Switch, Dialog, Toast } from "vant";
  205. import { swiper } from "@/utils/swiper";
  206. import { querySpaceConditioners, setSpaceCondtioners } from "@/apis/envmonitor";
  207. import { parseImgUrl, setQueryConfig } from "@/utils";
  208. import any = jasmine.any;
  209. export default defineComponent({
  210. props: {
  211. temperature: {
  212. // 空调基本信息
  213. type: Number,
  214. default: () => 0,
  215. },
  216. hasAir: {
  217. // 有无空调
  218. type: Boolean,
  219. default: () => false,
  220. },
  221. airVolumes: {
  222. // 风量信息
  223. type: Array,
  224. default: () => [],
  225. },
  226. projectId: {
  227. type: String,
  228. default: () => "",
  229. },
  230. spaceId: {
  231. type: String,
  232. default: () => "",
  233. },
  234. userIsControl: {
  235. type: Boolean,
  236. default: () => false,
  237. },
  238. forceOverTimeFlag: {
  239. type: Boolean,
  240. default: () => false,
  241. },
  242. },
  243. components: {
  244. Switch,
  245. [Dialog.Component.name]: Dialog.Component,
  246. },
  247. setup(props, contx) {
  248. const propsVal = props;
  249. let airData: any = {
  250. avg: "", // 算法调节温度(目标值)
  251. icon: 1, // 固定框文案ID 7 为关机,其它都是开机
  252. spaceStatus: "", // 固定框文案展示
  253. notice: "", // 弹框文案展示
  254. mode: 0, // 模式
  255. tempSet: 0, // 温度
  256. maxTempSet: 32,
  257. minTempSet: 16,
  258. isAutoGear: 0,
  259. workMode: 0, //1=cold(制冷);2=hot(制热);3=wind(通风)
  260. gear: 0, // 风量
  261. isOpen: false, // 空调开关 true 是开
  262. };
  263. const feedbackTimer: any = null;
  264. const airTimer: any = null;
  265. const domAirOpeen: any = false;
  266. let realTemp: any = 16;
  267. let windGearArr: any = [0, 1, 2, 3];
  268. let equipList: any = [];
  269. const proxyData = reactive({
  270. equipList: equipList,
  271. cotrolLoading: false,
  272. loadingTimer: 0,
  273. airTemp: 0, // 设备真实温度
  274. loadingAir: false,
  275. windGearArr: windGearArr, // 风量3/5个档位
  276. lightIcon: "arrow-down",
  277. showChild: false,
  278. realTemp: realTemp,
  279. temperature: props.temperature,
  280. userIsControl: props.userIsControl,
  281. forceOverTimeFlag: props.forceOverTimeFlag,
  282. firstLoadingAir: true,
  283. domAirOpeen: domAirOpeen,
  284. feedbackTimer: feedbackTimer,
  285. parseImgUrl: parseImgUrl,
  286. part: 1,
  287. airData: airData,
  288. modeName: "",
  289. showAirVolumeBtn: false, // 是否展示风量调节按钮
  290. showDialog: false,
  291. airTimer: airTimer,
  292. airSetText: {
  293. // 空调反馈文案
  294. notice: "",
  295. remark: [],
  296. nowImg: "",
  297. toWhere: "",
  298. designTemperature: 0,
  299. },
  300. // 点击展示所有的登录
  301. showAll() {
  302. proxyData.showChild = !proxyData.showChild;
  303. if (proxyData.lightIcon === "arrow-up") {
  304. proxyData.lightIcon = "arrow-down";
  305. } else {
  306. proxyData.lightIcon = "arrow-up";
  307. }
  308. },
  309. // 设置温度条的位置
  310. setBarNowPerstion() {
  311. let left: any =
  312. ((proxyData.airTemp - proxyData.airData.minTempSet) / 0.5) *
  313. proxyData.part;
  314. left = Math.floor(left);
  315. proxyData.realTemp = proxyData.airTemp;
  316. let barBox: any = document.querySelector("#barId");
  317. barBox.style.left = left + "px";
  318. },
  319. // 滑动
  320. endBoxSwiper() {
  321. let handBox: any = document.querySelector("#handId");
  322. let barBox: any = document.querySelector("#barId");
  323. let sliderBox: any = document.querySelector("#sliderId");
  324. let isMove: any = false;
  325. let barLeft: any = 0;
  326. let sliderWidth: any = sliderBox.offsetWidth;
  327. let barWidth: any = barBox.offsetWidth;
  328. let tempPart =
  329. (proxyData.airData.maxTempSet - proxyData.airData.minTempSet) / 20;
  330. let part: any = 0.5 / (tempPart / (Math.floor(sliderWidth) / 22));
  331. proxyData.part = part;
  332. handBox.addEventListener("touchstart", function (e: any) {
  333. barLeft = isNaN(parseInt(barBox.style.left))
  334. ? 0
  335. : parseInt(barBox.style.left);
  336. isMove = false;
  337. });
  338. handBox.addEventListener("touchend", function (e: any) {
  339. proxyData.changeZongAir("temp", proxyData.realTemp);
  340. });
  341. swiper(handBox, {
  342. swipeLeft: function (e: any) {
  343. barLeft = Math.abs(barLeft);
  344. let moveRealX: any = Math.abs(e.mation.moveX - e.mation.startX);
  345. let left: any = barLeft - moveRealX;
  346. left = left < 0 ? 0 : left;
  347. barBox.style.left = left + "px";
  348. proxyData.realTemp =
  349. proxyData.airData.minTempSet + Math.ceil(left / part) * 0.5;
  350. },
  351. swipeRight: function (e: any) {
  352. barLeft = Math.abs(barLeft);
  353. let moveRealX: any = Math.abs(e.mation.moveX - e.mation.startX);
  354. let left: any = barLeft + moveRealX;
  355. left = left > sliderWidth ? sliderWidth - barWidth : left;
  356. barBox.style.left = left + "px";
  357. proxyData.realTemp =
  358. proxyData.airData.minTempSet + Math.ceil(left / part) * 0.5;
  359. if (proxyData.realTemp > proxyData.airData.maxTempSet) {
  360. proxyData.realTemp = proxyData.airData.maxTempSet;
  361. }
  362. },
  363. });
  364. },
  365. // 格式化模式
  366. formateModel(model: any) {
  367. if (model) {
  368. if (model === 1) {
  369. proxyData.modeName = "制冷";
  370. } else if (model === 2) {
  371. proxyData.modeName = "制热";
  372. } else if (model === 3) {
  373. proxyData.modeName = "通风";
  374. } else if (model === 4) {
  375. proxyData.modeName = "除湿";
  376. } else {
  377. proxyData.modeName = "";
  378. }
  379. } else {
  380. proxyData.modeName = "";
  381. }
  382. },
  383. // 定时获取空调状态
  384. getAirInfoToTimer(timerLong: any = 3000) {
  385. if (proxyData.airTimer) {
  386. clearTimeout(proxyData.airTimer);
  387. }
  388. proxyData.airTimer = setTimeout(function () {
  389. proxyData.getAirInfo();
  390. }, timerLong);
  391. },
  392. // 计算loading时间
  393. setLoadingNumber() {
  394. let timer: any = setInterval(() => {
  395. proxyData.loadingTimer++;
  396. if (proxyData.loadingTimer > 15) {
  397. clearInterval(timer);
  398. proxyData.loadingAir = false;
  399. proxyData.getAirInfoToTimer(3000);
  400. }
  401. }, 1000);
  402. },
  403. // 格式化空调数据
  404. formatAirData(btnType: any, text: any) {
  405. let obj: any = {};
  406. if (btnType == "temp") {
  407. obj.codeKey = "tempSetCode";
  408. obj.value = text;
  409. }
  410. if (btnType == "gear" && text == "windLow") {
  411. //降挡
  412. if (proxyData.airData.gear > 1) {
  413. proxyData.airData.gear--;
  414. proxyData.airData.isAutoGear = 0;
  415. obj.value = proxyData.airData.gear;
  416. obj.codeKey = "gearCode";
  417. } else {
  418. return;
  419. }
  420. }
  421. if (btnType == "gear" && text == "windUp") {
  422. //升档
  423. if (proxyData.airData.gear < 3) {
  424. proxyData.airData.gear++;
  425. proxyData.airData.isAutoGear = 0;
  426. obj.value = proxyData.airData.gear;
  427. obj.codeKey = "gearCode";
  428. } else {
  429. return;
  430. }
  431. }
  432. if (btnType == "gear" && text == "auto") {
  433. proxyData.airData.isAutoGear == 1 ? 0 : 1;
  434. obj.value = proxyData.airData.isAutoGear ? 4 : proxyData.airData.gear;
  435. obj.codeKey = "gearCode";
  436. }
  437. if (btnType == "mode") {
  438. proxyData.airData.workMode = text;
  439. obj.codeKey = "modeSetCode";
  440. obj.value = text;
  441. }
  442. return obj;
  443. },
  444. /**
  445. * 加载loading
  446. */
  447. loadingStart() {
  448. proxyData.cotrolLoading = true;
  449. },
  450. /**
  451. * 结束
  452. */
  453. loadinngEnd() {
  454. proxyData.cotrolLoading = false;
  455. },
  456. // 子设备降低温度
  457. changeItemAir(btnType: any, childItem: any) {
  458. proxyData.loadingStart();
  459. if (btnType === "temp") {
  460. if (childItem.tempSet <= proxyData.airData.minTempSet) {
  461. return;
  462. }
  463. childItem.tempSet = childItem.tempSet - 0.5;
  464. let obj: any = {
  465. id: childItem.id, //类型:String 必有字段 备注:设备id
  466. code: childItem.tempSetCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  467. value: childItem.tempSet, //类型:String 必有字段 备注:值 0
  468. };
  469. }
  470. if (!proxyData.cotrolLoading) {
  471. }
  472. },
  473. // 改变设备状态
  474. setSpaceCondtioners(data: any) {
  475. setSpaceCondtioners(data)
  476. .then((res) => {
  477. // proxyData.setLoadingNumber();
  478. proxyData.loadinngEnd();
  479. })
  480. .catch(() => {
  481. // proxyData.setLoadingNumber();
  482. proxyData.loadinngEnd();
  483. });
  484. },
  485. // 改变空调状态
  486. changeZongAir(btnType: any, text: any) {
  487. if (!this.airData.isOpen) return;
  488. let equpObj: any = proxyData.formatAirData(btnType, text);
  489. if (equpObj.value) {
  490. let data: any = [];
  491. proxyData.equipList.map((item: any) => {
  492. let obj: any = {
  493. id: item.id, //类型:String 必有字段 备注:设备id
  494. code: item[equpObj.codeKey], //类型:String 必有字段 备注:编码 EquipSwtichSet
  495. value: equpObj.value, //类型:String 必有字段 备注:值 0
  496. };
  497. data.push(obj);
  498. });
  499. console.log("设备数据处理---");
  500. console.log(data);
  501. if (!proxyData.cotrolLoading) {
  502. proxyData.loadingStart();
  503. // 调整设备状态
  504. proxyData.setSpaceCondtioners(data);
  505. }
  506. }
  507. },
  508. // 总控制改变空调状态
  509. airChange() {
  510. // 先不更新状态等确认框弹出后再更新状
  511. proxyData.airData.isOpen = !proxyData.airData.isOpen;
  512. proxyData.loadingAir = true;
  513. proxyData.loadingTimer = 0;
  514. let data: any = [];
  515. proxyData.equipList.map((item: any) => {
  516. let obj: any = {
  517. id: item.id, //类型:String 必有字段 备注:设备id
  518. code: item.switchCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  519. value: proxyData.airData.isOpen ? "1" : "0", //类型:String 必有字段 备注:值 0
  520. };
  521. data.push(obj);
  522. });
  523. clearTimeout(proxyData.airTimer);
  524. proxyData.setLoadingNumber();
  525. // 设备状态处理
  526. proxyData.setSpaceCondtioners(data);
  527. },
  528. // 空调信息airTemp
  529. getAirInfo() {
  530. const paramObj = {
  531. // // projectId: props.projectId, //'Pj1101080255'
  532. // projectId: "Pj1101080255",
  533. spaceId: "Sp110108025564f438d7fef64eea8202a6462f1bbcce",
  534. // spaceId: props.spaceId,//'Sp110108025564f438d7fef64eea8202a6462f1bbcce' 空间id
  535. };
  536. //wx.showLoading();
  537. let str: any = setQueryConfig(paramObj);
  538. querySpaceConditioners(str)
  539. .then((res) => {
  540. let data: any = res.data || {};
  541. proxyData.firstLoadingAir = false;
  542. proxyData.loadingAir = false;
  543. proxyData.airTemp = data.tempSet;
  544. proxyData.airData.maxTempSet = data.maxTempSet;
  545. proxyData.airData.minTempSet = data.minTempSet;
  546. proxyData.airData.isOpen = data.runStatus ? true : false;
  547. proxyData.airData.isAutoGear = data.isAutoGear;
  548. proxyData.airData.gear = data.gear;
  549. proxyData.airData.workMode = data.workMode;
  550. proxyData.equipList = data.equipList;
  551. // 设置当前温度的位置
  552. proxyData.setBarNowPerstion();
  553. if (proxyData.airData.isOpen) {
  554. proxyData.airData.airImg = parseImgUrl(
  555. "page-officehome",
  556. "openair.png"
  557. );
  558. } else {
  559. proxyData.airData.airImg = parseImgUrl(
  560. "page-officehome",
  561. "air_close.png"
  562. );
  563. }
  564. if (data.equipList && data.equipList.length > 1) {
  565. }
  566. proxyData.getAirInfoToTimer(3000);
  567. })
  568. .catch(() => {});
  569. },
  570. });
  571. nextTick(() => {
  572. proxyData.endBoxSwiper();
  573. }),
  574. watch(props, (newProps: any) => {
  575. if (newProps.spaceId) {
  576. }
  577. proxyData.temperature = props.temperature;
  578. proxyData.userIsControl = newProps.userIsControl;
  579. proxyData.forceOverTimeFlag = newProps.forceOverTimeFlag;
  580. });
  581. onBeforeUnmount(() => {
  582. if (proxyData.airTimer) {
  583. clearTimeout(proxyData.airTimer);
  584. proxyData.airTimer = null;
  585. }
  586. if (proxyData.feedbackTimer) {
  587. clearTimeout(proxyData.feedbackTimer);
  588. proxyData.feedbackTimer = null;
  589. }
  590. });
  591. onMounted(() => {
  592. proxyData.getAirInfo();
  593. // 获取空调信息
  594. });
  595. return {
  596. ...toRefs(proxyData),
  597. };
  598. },
  599. });
  600. </script>
  601. <style lang="scss" scoped>
  602. .air {
  603. position: relative;
  604. width: 100%;
  605. background: #ffffff;
  606. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.07), 0px 4px 10px rgba(0, 0, 0, 0.05);
  607. border-radius: 25px;
  608. margin: 15px 0px;
  609. .loading-box {
  610. position: absolute;
  611. left: 50%;
  612. top: 50%;
  613. transform: translate(-50%, -50%);
  614. width: 100%;
  615. height: 100%;
  616. background: rgba(#000000, 0.3);
  617. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.07),
  618. 0px 4px 10px rgba(0, 0, 0, 0.05);
  619. text-align: center;
  620. z-index: 999;
  621. // line-height: 50px;
  622. }
  623. .active-color {
  624. background: $elActiveColor !important;
  625. span {
  626. color: #fff !important;
  627. }
  628. }
  629. }
  630. .air-child {
  631. width: 100%;
  632. .child-control-box {
  633. display: inline-block;
  634. width: 50%;
  635. justify-content: space-between;
  636. padding: 20px 10px 10px 20px;
  637. border-bottom: 1px solid rgba(196, 196, 196, 0.4);
  638. &:nth-child(2n + 1) {
  639. border-right: 1px solid rgba(196, 196, 196, 0.4);
  640. }
  641. .open-title {
  642. width: 100%;
  643. font-size: 14px;
  644. height: 25px;
  645. line-height: 25px;
  646. display: flex;
  647. justify-content: space-between;
  648. margin-bottom: 10px;
  649. span {
  650. display: inline-block;
  651. width: calc(100% - 50px);
  652. overflow: hidden;
  653. text-overflow: ellipsis;
  654. white-space: nowrap;
  655. }
  656. .child-switch {
  657. height: 20px;
  658. width: 50px;
  659. }
  660. }
  661. .adjust-box {
  662. box-sizing: border-box;
  663. padding-right: 10px;
  664. display: flex;
  665. justify-content: space-between;
  666. font-size: 19px;
  667. .adjust-item {
  668. // flex: 1;
  669. width: 40px;
  670. display: flex;
  671. flex-direction: column;
  672. justify-content: space-between;
  673. text-align: center;
  674. .adjust-icon {
  675. display: inline-block;
  676. flex: 1;
  677. }
  678. .adjust-text {
  679. flex: 1;
  680. padding: 20px 0;
  681. }
  682. .adjust-title {
  683. padding-top: 10px;
  684. font-size: 18px;
  685. }
  686. }
  687. }
  688. }
  689. }
  690. .air-top {
  691. padding-left: 20px;
  692. padding-bottom: 20px;
  693. display: flex;
  694. justify-content: space-between;
  695. .air-desc {
  696. position: relative;
  697. flex: 1 157px;
  698. padding-top: 10px;
  699. font-family: PingFang SC;
  700. font-size: 16px;
  701. line-height: 19px;
  702. color: #4d5262;
  703. flex: none;
  704. flex-grow: 0;
  705. margin: 5px 0px;
  706. min-height: 100px;
  707. .air-title {
  708. font-family: PingFang SC;
  709. padding-left: 5px;
  710. font-size: 16px;
  711. line-height: 20px;
  712. color: #4d5262;
  713. padding-bottom: 10px;
  714. i {
  715. display: inline-block;
  716. font-size: 12px;
  717. transform: scale(0.9);
  718. font-style: normal;
  719. padding-left: 5px;
  720. color: #c4c4c4;
  721. }
  722. }
  723. .air-temperature {
  724. display: inline-block;
  725. font-family: "Montserrat";
  726. font-style: normal;
  727. font-weight: normal;
  728. font-size: 32px;
  729. line-height: 32px;
  730. flex: none;
  731. order: 0;
  732. flex-grow: 0;
  733. margin: 0px 4px;
  734. sup {
  735. font-family: Mulish;
  736. font-style: normal;
  737. font-weight: 800;
  738. font-size: 12px;
  739. line-height: 15px;
  740. }
  741. }
  742. .show-all {
  743. position: absolute;
  744. bottom: -8px;
  745. font-family: PingFang SC;
  746. font-size: 14px;
  747. line-height: 16px;
  748. color: #c4c4c4;
  749. margin: 0px 5px;
  750. span {
  751. font-size: 12px;
  752. }
  753. .light-icon {
  754. font-size: 12px;
  755. padding-right: 10px;
  756. }
  757. }
  758. }
  759. .air-right {
  760. position: relative;
  761. width: 157px;
  762. text-align: center;
  763. img {
  764. width: 147px;
  765. height: 110px;
  766. }
  767. .switch-btn {
  768. position: absolute;
  769. z-index: 111;
  770. bottom: -5px;
  771. right: 25px;
  772. }
  773. }
  774. }
  775. .air-control {
  776. padding: 10px;
  777. border-top: 1px solid rgba(196, 196, 196, 0.4);
  778. .control-box {
  779. display: flex;
  780. justify-content: space-between;
  781. }
  782. .volume-box {
  783. padding: 10px;
  784. color: #c4c4c4;
  785. font-size: 12px;
  786. .text {
  787. padding-top: 5px;
  788. }
  789. .number {
  790. span {
  791. display: inline-block;
  792. vertical-align: middle;
  793. color: #c4c4c4;
  794. padding-right: 5px;
  795. }
  796. .number-active {
  797. font-family: "Montserrat";
  798. font-style: normal;
  799. font-weight: 500;
  800. font-size: 22px;
  801. line-height: 24px;
  802. color: #4d5262 !important;
  803. }
  804. }
  805. .model {
  806. font-size: 14px;
  807. color: #1f2429;
  808. }
  809. }
  810. .volume-icon {
  811. .icon-item {
  812. position: relative;
  813. display: inline-block;
  814. width: 42px;
  815. height: 42px;
  816. background: rgba(196, 196, 196, 0.2);
  817. border-radius: 50%;
  818. img {
  819. width: 20px;
  820. height: 20px;
  821. position: absolute;
  822. left: 50%;
  823. top: 50%;
  824. transform: translate(-50%, -50%);
  825. }
  826. &:nth-child(2) {
  827. margin-left: 10px;
  828. margin-right: 10px;
  829. }
  830. span {
  831. font-size: 12px;
  832. color: #000000;
  833. position: absolute;
  834. left: 50%;
  835. top: 50%;
  836. transform: translate(-50%, -50%) scale(0.8);
  837. }
  838. }
  839. }
  840. .temp-text {
  841. height: 20px;
  842. line-height: 20px;
  843. font-family: "Montserrat";
  844. font-style: normal;
  845. font-weight: 500;
  846. font-size: 11px;
  847. color: #c4c4c4;
  848. padding: 0 5px;
  849. }
  850. .temp-slider {
  851. position: relative;
  852. display: flex;
  853. height: 20px;
  854. flex: 1;
  855. border-radius: 5px;
  856. .item {
  857. height: 20px;
  858. flex: 1;
  859. font-size: 0;
  860. &:nth-child(1) {
  861. background: #5e8bcf;
  862. border-radius: 5px 0 0 5px;
  863. }
  864. &:nth-child(2) {
  865. background: #9fb7cd;
  866. }
  867. &:nth-child(3) {
  868. background: #f3f3f3;
  869. }
  870. &:nth-child(4) {
  871. background: #ff9882;
  872. }
  873. &:nth-child(5) {
  874. background: #e5574f;
  875. border-radius: 0 5px 5px 0;
  876. }
  877. }
  878. .slider-bar {
  879. position: absolute;
  880. width: 25px;
  881. left: 0;
  882. bottom: -2px;
  883. z-index: 333;
  884. .bar-temp {
  885. padding-bottom: 10px;
  886. font-size: 12px;
  887. color: #1f2429;
  888. }
  889. .bar-circle {
  890. width: 25px;
  891. height: 25px;
  892. background: #fff;
  893. border-radius: 50%;
  894. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1),
  895. 0px 4px 10px rgba(0, 0, 0, 0.07);
  896. border-radius: 21px;
  897. z-index: 444;
  898. }
  899. }
  900. }
  901. .control-text {
  902. font-style: normal;
  903. font-weight: 600;
  904. font-size: 11px;
  905. line-height: 15px;
  906. color: #c4c4c4;
  907. padding: 10px 0 0 10px;
  908. }
  909. }
  910. .air-control-padding {
  911. padding-top: 35px;
  912. padding-bottom: 15px;
  913. }
  914. </style>
  915. <style lang="scss">
  916. .air {
  917. .loading-box {
  918. .van-loading {
  919. position: absolute;
  920. left: 50%;
  921. top: 50%;
  922. transform: translate(-50%, -50%);
  923. }
  924. }
  925. .van-loading__spinner {
  926. color: $elActiveColor !important;
  927. }
  928. .van-switch__loading {
  929. top: 0;
  930. left: 0;
  931. width: 100%;
  932. height: 100%;
  933. line-height: 1;
  934. }
  935. .van-switch--disabled {
  936. opacity: 0.5;
  937. }
  938. .child-control-box {
  939. .child-switch {
  940. .van-switch__node {
  941. width: 20px !important;
  942. height: 20px !important;
  943. }
  944. }
  945. }
  946. }
  947. </style>