manualIndex.vue 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386
  1. <template>
  2. <div class="air">
  3. <div class="air-top">
  4. <div class="air-desc">
  5. <p class="air-title">空调</p>
  6. <p class="air-temperature">
  7. {{ airTemp ? airTemp : "--" }}
  8. <sup></sup>
  9. </p>
  10. <div
  11. class="show-all"
  12. @click.stop="showAll"
  13. v-if="equipList && equipList.length > 1"
  14. >
  15. <van-icon :name="lightIcon" class="light-icon" />
  16. <span v-if="!showChild">查看全部</span>
  17. <span v-else>收起全部</span>
  18. </div>
  19. </div>
  20. <div class="air-right">
  21. <img v-if="airData.airImg" :src="airData.airImg" alt="" />
  22. <van-loading style="padding-top: 20px" v-else />
  23. <Switch
  24. class="switch-btn"
  25. v-if="!showChild"
  26. :loading="loadingAir || firstLoadingAir"
  27. :disabled="loadingAir || firstLoadingAir"
  28. inactive-color="rgba(196, 196, 196, 0.4)"
  29. @click="airChange"
  30. :model-value="airData.isOpen"
  31. />
  32. </div>
  33. </div>
  34. <!--温度调节-->
  35. <div
  36. v-if="!showChild && airData.runStatus"
  37. :style="{ opacity: loadingAir || !airData.runStatus ? '0.4' : '1' }"
  38. >
  39. <div class="air-control air-control-padding">
  40. <div class="control-box">
  41. <div class="temp-text">{{ airData.minTempSet }}</div>
  42. <div class="temp-slider" id="sliderId">
  43. <div
  44. class="item"
  45. v-for="(item, index) in 5"
  46. :key="'bar' + index"
  47. ></div>
  48. <div class="slider-bar" id="barId">
  49. <div class="bar-temp">{{ realTemp }}</div>
  50. <div class="bar-circle" id="handId"></div>
  51. </div>
  52. </div>
  53. <div class="temp-text">{{ airData.maxTempSet }}</div>
  54. </div>
  55. <div class="control-text">温度设定</div>
  56. </div>
  57. <div class="air-control">
  58. <div class="control-box">
  59. <div class="volume-box">
  60. <div class="number">
  61. <span
  62. v-for="(item, index) in windGearArr"
  63. :class="airData.gear === item ? 'number-active' : ''"
  64. :key="'volume' + index"
  65. >{{ item }}</span
  66. >
  67. </div>
  68. <div class="text">风量调节</div>
  69. </div>
  70. <div class="volume-icon">
  71. <div
  72. class="icon-item"
  73. :style="{
  74. opacity: airData.gear <= 1 ? '0.6' : 1,
  75. }"
  76. @click="changeZongAir('gear', 'windLow')"
  77. >
  78. <img :src="parseImgUrl('ipdImages', 'wind_small.png')" />
  79. </div>
  80. <div
  81. class="icon-item"
  82. :style="{ opacity: airData.gear >= 3 ? '0.6' : 1 }"
  83. @click="changeZongAir('gear', 'windUp')"
  84. >
  85. <img :src="parseImgUrl('ipdImages', 'wind_big.png')" />
  86. </div>
  87. <div
  88. class="icon-item"
  89. @click="changeZongAir('gear', 'auto')"
  90. :class="airData.isAutoGear ? 'active-color' : ''"
  91. >
  92. <span> AUTO</span>
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. <div class="air-control">
  98. <div class="control-box">
  99. <div class="volume-box">
  100. <div class="model">
  101. {{
  102. airData.workMode == 1
  103. ? "制冷"
  104. : airData.workMode == 2
  105. ? "制热"
  106. : "通风"
  107. }}
  108. </div>
  109. <div class="text">模式设定</div>
  110. </div>
  111. <div class="volume-icon">
  112. <div
  113. class="icon-item"
  114. :class="airData.workMode === 2 ? 'active-color' : ''"
  115. @click="changeZongAir('mode', 2)"
  116. >
  117. <img
  118. :src="
  119. airData.workMode === 2
  120. ? parseImgUrl('ipdImages', 'airsunred.svg')
  121. : parseImgUrl('ipdImages', 'airsunblack.svg')
  122. "
  123. />
  124. </div>
  125. <div
  126. class="icon-item"
  127. :class="airData.workMode === 1 ? 'active-color' : ''"
  128. @click="changeZongAir('mode', 1)"
  129. >
  130. <img
  131. :src="
  132. airData.workMode === 1
  133. ? parseImgUrl('ipdImages', 'aircoldblue.svg')
  134. : parseImgUrl('ipdImages', 'aircoldblack.svg')
  135. "
  136. />
  137. </div>
  138. <div
  139. class="icon-item"
  140. :class="airData.workMode === 3 ? 'active-color' : ''"
  141. @click="changeZongAir('mode', 3)"
  142. >
  143. <img
  144. :src="
  145. airData.workMode === 3
  146. ? parseImgUrl('ipdImages', 'aircloudgreen.svg')
  147. : parseImgUrl('ipdImages', 'aircloudblack.svg')
  148. "
  149. />
  150. </div>
  151. </div>
  152. </div>
  153. </div>
  154. </div>
  155. <!--子设备-->
  156. <div class="air-child" v-if="showChild">
  157. <div
  158. class="child-control-box"
  159. :key="'child' + index"
  160. v-for="(childItem, index) in equipList"
  161. >
  162. <div class="open-title">
  163. <span>{{ childItem.localName }}</span>
  164. <Switch
  165. @click="changeChildItemAir('switch', childItem, 'switch')"
  166. :loading="
  167. childItem.loadingTimer > 0 && childItem.loadingTimer <= 15
  168. ? true
  169. : false
  170. "
  171. :disabled="
  172. childItem.loadingTimer > 0 && childItem.loadingTimer <= 15
  173. ? true
  174. : false
  175. "
  176. :model-value="childItem.isOpen"
  177. class="child-switch"
  178. inactive-color="rgba(196, 196, 196, 0.4)"
  179. size="14px"
  180. />
  181. </div>
  182. <div
  183. class="adjust-box"
  184. :style="{
  185. opacity: childItem.runStatus && childItem.isOpen ? '' : '0.3',
  186. }"
  187. >
  188. <div class="adjust-item">
  189. <van-icon
  190. name="arrow-up"
  191. :class="
  192. childItem.tempSet >= airData.maxTempSet ? 'disable-color' : ''
  193. "
  194. @click="changeChildItemAir('temp', childItem, 'up')"
  195. class="adjust-icon"
  196. />
  197. <div class="adjust-text">
  198. <div
  199. class="value-wrap"
  200. :style="{
  201. transform: valueHeight
  202. ? 'translateY(' + -childItem.sel * valueHeight + 'px)'
  203. : 'translateY(0px)',
  204. }"
  205. >
  206. <div
  207. class="value"
  208. :key="index + 'ct'"
  209. v-for="(titem, index) in childItem.tempArr"
  210. >
  211. {{ titem }}
  212. </div>
  213. </div>
  214. </div>
  215. <van-icon
  216. name="arrow-down"
  217. :class="
  218. childItem.tempSet <= airData.minTempSet ? 'disable-color' : ''
  219. "
  220. @click="changeChildItemAir('temp', childItem, 'down')"
  221. class="adjust-icon"
  222. />
  223. <span class="adjust-title">温度</span>
  224. </div>
  225. <div class="adjust-item">
  226. <van-icon
  227. name="arrow-up"
  228. :class="childItem.isAutoGear ? 'disable-color' : ''"
  229. @click="changeChildItemAir('gear', childItem, 'up')"
  230. class="adjust-icon"
  231. />
  232. <div class="adjust-text">
  233. <div
  234. class="value-wrap"
  235. :style="{
  236. transform: valueHeight
  237. ? 'translateY(' + -childItem.gIndex * valueHeight + 'px)'
  238. : 'translateY(0px)',
  239. }"
  240. >
  241. <div
  242. class="value"
  243. v-for="(gItem, index) in childItem.gearArr"
  244. :key="index + 'g'"
  245. >
  246. {{ gItem }}
  247. </div>
  248. </div>
  249. </div>
  250. <van-icon
  251. name="arrow-down"
  252. :class="
  253. !childItem.isAutoGear && childItem.gear <= 1
  254. ? 'disable-color'
  255. : ''
  256. "
  257. @click="changeChildItemAir('gear', childItem, 'down')"
  258. class="adjust-icon"
  259. />
  260. <span class="adjust-title">档位</span>
  261. </div>
  262. <div class="adjust-item">
  263. <van-icon
  264. name="arrow-up"
  265. :class="childItem.workMode >= 3 ? 'disable-color' : ''"
  266. @click="changeChildItemAir('model', childItem, 'up')"
  267. class="adjust-icon"
  268. />
  269. <div class="adjust-text">
  270. <div
  271. class="value-wrap"
  272. :style="{
  273. transform: valueHeight
  274. ? 'translateY(' + -childItem.mIndex * valueHeight + 'px)'
  275. : 'translateY(0px)',
  276. }"
  277. >
  278. <div
  279. class="value"
  280. v-for="(mItem, index) in childItem.modelArr"
  281. :key="index + 'm'"
  282. >
  283. {{ mItem }}
  284. </div>
  285. </div>
  286. </div>
  287. <van-icon
  288. name="arrow-down"
  289. :class="childItem.workMode <= 1 ? 'disable-color' : ''"
  290. @click="changeChildItemAir('model', childItem, 'down')"
  291. class="adjust-icon"
  292. />
  293. <span class="adjust-title">模式</span>
  294. </div>
  295. </div>
  296. </div>
  297. </div>
  298. <!-- v-if="cotrolLoading" -->
  299. <!-- <div class="loading-box" v-if="cotrolLoading">
  300. <van-loading style="padding-top: 20px" />
  301. </div> -->
  302. </div>
  303. </template>
  304. <script lang="ts">
  305. import {
  306. defineComponent,
  307. onMounted,
  308. reactive,
  309. toRefs,
  310. computed,
  311. watch,
  312. onUnmounted,
  313. onBeforeMount,
  314. onBeforeUnmount,
  315. nextTick,
  316. } from "vue";
  317. import { Switch, Dialog, Toast } from "vant";
  318. import { swiper } from "@/utils/swiper";
  319. import { querySpaceConditioners, setSpaceCondtioners } from "@/apis/envmonitor";
  320. import { parseImgUrl, setQueryConfig } from "@/utils";
  321. import any = jasmine.any;
  322. export default defineComponent({
  323. props: {
  324. temperature: {
  325. // 空调基本信息
  326. type: Number,
  327. default: () => 0,
  328. },
  329. hasAir: {
  330. // 有无空调
  331. type: Boolean,
  332. default: () => false,
  333. },
  334. airVolumes: {
  335. // 风量信息
  336. type: Array,
  337. default: () => [],
  338. },
  339. projectId: {
  340. type: String,
  341. default: () => "",
  342. },
  343. spaceId: {
  344. type: String,
  345. default: () => "",
  346. },
  347. userIsControl: {
  348. type: Boolean,
  349. default: () => false,
  350. },
  351. forceOverTimeFlag: {
  352. type: Boolean,
  353. default: () => false,
  354. },
  355. seviceEquipmentList: {
  356. // 是否走服务定制的设备
  357. type: Array,
  358. default: () => [],
  359. },
  360. },
  361. components: {
  362. Switch,
  363. [Dialog.Component.name]: Dialog.Component,
  364. },
  365. setup(props, contx) {
  366. const propsVal = props;
  367. let airData: any = {
  368. avg: "", // 算法调节温度(目标值)
  369. icon: 1, // 固定框文案ID 7 为关机,其它都是开机
  370. spaceStatus: "", // 固定框文案展示
  371. notice: "", // 弹框文案展示
  372. mode: 0, // 模式
  373. tempSet: 0, // 温度
  374. maxTempSet: 32,
  375. minTempSet: 16,
  376. isAutoGear: 0,
  377. workMode: 0, //1=cold(制冷);2=hot(制热);3=wind(通风)
  378. gear: 0, // 风量
  379. isOpen: false, // 空调开关 true 是开
  380. runStatus: 0, // 查询设备的真实状态
  381. };
  382. const feedbackTimer: any = null;
  383. const airTimer: any = null;
  384. const domAirOpeen: any = false;
  385. let realTemp: any = 16;
  386. let windGearArr: any = [0, 1, 2, 3];
  387. let equipList: any = [];
  388. let valueDom: any = null;
  389. let valueHeight: any = null;
  390. let spaceId: any = "";
  391. const proxyData = reactive({
  392. seviceEquipmentList: props.seviceEquipmentList,
  393. valueDom: valueDom,
  394. spaceId: spaceId,
  395. valueHeight: valueHeight,
  396. equipList: equipList,
  397. cotrolLoading: false,
  398. loadingTimer: 0,
  399. airTemp: 0, // 设备真实温度
  400. loadingAir: false,
  401. windGearArr: windGearArr, // 风量3/5个档位
  402. lightIcon: "arrow-down",
  403. showChild: false,
  404. realTemp: realTemp,
  405. temperature: props.temperature,
  406. userIsControl: props.userIsControl,
  407. forceOverTimeFlag: props.forceOverTimeFlag,
  408. firstLoadingAir: true,
  409. domAirOpeen: domAirOpeen,
  410. swiperIinit: false,
  411. parseImgUrl: parseImgUrl,
  412. part: 1,
  413. airData: airData,
  414. modeName: "",
  415. showAirVolumeBtn: false, // 是否展示风量调节按钮
  416. showDialog: false,
  417. airTimer: airTimer,
  418. airSetText: {
  419. // 空调反馈文案
  420. notice: "",
  421. remark: [],
  422. nowImg: "",
  423. toWhere: "",
  424. designTemperature: 0,
  425. },
  426. // 点击展示所有的登录
  427. async showAll() {
  428. proxyData.showChild = !proxyData.showChild;
  429. if (proxyData.lightIcon === "arrow-up") {
  430. proxyData.lightIcon = "arrow-down";
  431. } else {
  432. proxyData.lightIcon = "arrow-up";
  433. }
  434. if (proxyData.showChild) {
  435. await nextTick(() => {
  436. proxyData.setChildSelectList();
  437. });
  438. } else {
  439. await nextTick(() => {
  440. proxyData.barSwiperInit();
  441. });
  442. }
  443. // proxyData.getAirInfoToTimer(0);
  444. },
  445. // 设置温度条的位置
  446. setBarNowPerstion() {
  447. proxyData.realTemp = proxyData.airTemp;
  448. let barBox: any = document.querySelector("#barId");
  449. // console.log("设置温度位置---");
  450. // console.log(barBox)
  451. if (!barBox) {
  452. return;
  453. }
  454. let sliderBox: any = document.querySelector("#sliderId");
  455. if (
  456. proxyData.airTemp >= proxyData.airData.minTempSet &&
  457. proxyData.airTemp <= proxyData.airData.maxTempSet
  458. ) {
  459. // 正常温度范围
  460. let left: any =
  461. ((proxyData.airTemp - proxyData.airData.minTempSet) / 0.5) *
  462. proxyData.part;
  463. left = Math.floor(left);
  464. if (barBox) {
  465. barBox.style.left = left + "px";
  466. }
  467. } else {
  468. if (!proxyData.airTemp) {
  469. barBox.style.left = 0 + "px";
  470. } else if (proxyData.airTemp < proxyData.airData.minTempSet) {
  471. barBox.style.left = 0 + "px";
  472. } else if (proxyData.airTemp > proxyData.airData.maxTempSet) {
  473. let sliderWidth: any = sliderBox.offsetWidth;
  474. let barWidth: any = barBox.offsetWidth;
  475. barBox.style.left = sliderWidth - barWidth + "px";
  476. }
  477. }
  478. },
  479. // 滑动
  480. endBoxSwiper() {
  481. proxyData.swiperIinit = true;
  482. let handBox: any = document.querySelector("#handId");
  483. let barBox: any = document.querySelector("#barId");
  484. let sliderBox: any = document.querySelector("#sliderId");
  485. let isMove: any = false;
  486. let barLeft: any = 0;
  487. let sliderWidth: any = sliderBox ? sliderBox.offsetWidth : 1;
  488. let barWidth: any = barBox ? barBox.offsetWidth : 20;
  489. let tempPart =
  490. (proxyData.airData.maxTempSet - proxyData.airData.minTempSet) / 20;
  491. let part: any = 0.5 / (tempPart / (Math.floor(sliderWidth) / 22));
  492. proxyData.part = part;
  493. if (!handBox) {
  494. return;
  495. }
  496. handBox.addEventListener("touchstart", function (e: any) {
  497. barLeft = isNaN(parseInt(barBox.style.left))
  498. ? 0
  499. : parseInt(barBox.style.left);
  500. isMove = true;
  501. });
  502. handBox.addEventListener("touchend", function (e: any) {
  503. isMove = false;
  504. proxyData.changeZongAir("temp", proxyData.realTemp);
  505. proxyData.airTemp = proxyData.realTemp;
  506. });
  507. swiper(handBox, {
  508. swipeLeft: function (e: any) {
  509. if (isMove) {
  510. barLeft = Math.abs(barLeft);
  511. let moveRealX: any = Math.abs(e.mation.moveX - e.mation.startX);
  512. let left: any = barLeft - moveRealX;
  513. left = left < 0 ? 0 : left;
  514. barBox.style.left = left + "px";
  515. proxyData.realTemp =
  516. proxyData.airData.minTempSet + Math.ceil(left / part) * 0.5;
  517. }
  518. },
  519. swipeRight: function (e: any) {
  520. if (isMove) {
  521. barLeft = Math.abs(barLeft);
  522. let moveRealX: any = Math.abs(e.mation.moveX - e.mation.startX);
  523. let left: any = barLeft + moveRealX;
  524. left = left > sliderWidth ? sliderWidth - barWidth : left;
  525. barBox.style.left = left + "px";
  526. proxyData.realTemp =
  527. proxyData.airData.minTempSet + Math.ceil(left / part) * 0.5;
  528. if (proxyData.realTemp > proxyData.airData.maxTempSet) {
  529. proxyData.realTemp = proxyData.airData.maxTempSet;
  530. }
  531. }
  532. },
  533. });
  534. },
  535. // 定时获取空调状态
  536. getAirInfoToTimer(timerLong: any = 10000) {
  537. if (proxyData.airTimer) {
  538. clearTimeout(proxyData.airTimer);
  539. proxyData.airTimer = null;
  540. }
  541. proxyData.airTimer = setTimeout(function () {
  542. proxyData.getAirInfo();
  543. }, timerLong);
  544. },
  545. // 计算loading时间
  546. setLoadingNumber() {
  547. let timer: any = setInterval(() => {
  548. proxyData.loadingTimer++;
  549. console.log(proxyData.loadingTimer);
  550. if (proxyData.loadingTimer >= 15) {
  551. clearInterval(timer);
  552. proxyData.loadingAir = false;
  553. proxyData.getAirInfoToTimer(0);
  554. }
  555. }, 1000);
  556. },
  557. // 格式化空调数据
  558. formatAirData(btnType: any, text: any) {
  559. let obj: any = {};
  560. if (btnType == "temp") {
  561. obj.codeKey = "tempSetCode";
  562. obj.value = text;
  563. }
  564. if (btnType == "gear" && text == "windLow") {
  565. //降挡
  566. if (proxyData.airData.gear > 1) {
  567. proxyData.airData.gear--;
  568. proxyData.airData.isAutoGear = 0;
  569. obj.value = proxyData.airData.gear;
  570. obj.codeKey = "gearCode";
  571. } else {
  572. return;
  573. }
  574. }
  575. if (btnType == "gear" && text == "windUp") {
  576. //升档
  577. if (proxyData.airData.gear < 3) {
  578. proxyData.airData.gear++;
  579. proxyData.airData.isAutoGear = 0;
  580. obj.value = proxyData.airData.gear;
  581. obj.codeKey = "gearCode";
  582. } else {
  583. return;
  584. }
  585. }
  586. if (btnType == "gear" && text == "auto") {
  587. proxyData.airData.isAutoGear = proxyData.airData.isAutoGear ? 0 : 1;
  588. obj.value = proxyData.airData.isAutoGear ? 4 : proxyData.airData.gear;
  589. obj.codeKey = "gearCode";
  590. }
  591. if (btnType == "mode") {
  592. proxyData.airData.workMode = text;
  593. obj.codeKey = "modeSetCode";
  594. obj.value = text;
  595. }
  596. return obj;
  597. },
  598. /**
  599. * 加载loading
  600. */
  601. loadingStart() {
  602. proxyData.cotrolLoading = true;
  603. },
  604. /**
  605. * 结束
  606. */
  607. loadinngEnd() {
  608. proxyData.cotrolLoading = false;
  609. },
  610. // 计算loading时间
  611. setChildLoadingNumber(childItem: any) {
  612. childItem.loadingTimer = 1;
  613. let timer: any = setInterval(() => {
  614. childItem.loadingTimer++;
  615. if (childItem.loadingTimer >= 15) {
  616. clearInterval(timer);
  617. childItem.loadingTimer = 0;
  618. proxyData.getAirInfoToTimer(0);
  619. }
  620. console.log("===");
  621. console.log(childItem.loadingTimer);
  622. }, 1000);
  623. },
  624. // 连续点击2秒内未点击才发指令
  625. childDisabled(childItem: any, data: any) {
  626. clearTimeout(childItem.timeOuter);
  627. childItem.timeOuter = setInterval(() => {
  628. childItem.num--;
  629. if (childItem.num == 0) {
  630. proxyData.setSpaceCondtioners(data);
  631. clearTimeout(childItem.timeOuter);
  632. }
  633. }, 1000);
  634. },
  635. // 子设备降低温度
  636. changeChildItemAir(btnType: any, childItem: any, symbol: any) {
  637. const domAirOpen = !childItem.isOpen;
  638. let isExeSpaceTime: Boolean = proxyData.checkDeviceIsExeSpaceTime([
  639. childItem,
  640. ]);
  641. if (
  642. proxyData.forceOverTimeFlag &&
  643. domAirOpen &&
  644. isExeSpaceTime &&
  645. btnType == "switch"
  646. ) {
  647. //需要强制加班
  648. contx.emit("triggerWork", 2, childItem);
  649. return;
  650. }
  651. // 空调没有开的时候不让调温度和风量
  652. if (!childItem.isOpen && btnType !== "switch") {
  653. return;
  654. }
  655. let arr: any = [];
  656. if (btnType === "switch") {
  657. if (childItem.loadingTimer >= 1 && childItem.loadingTimer <= 15) {
  658. return;
  659. }
  660. childItem.isOpen = !childItem.isOpen;
  661. proxyData.setChildLoadingNumber(childItem);
  662. let obj: any = {
  663. id: childItem.id, //类型:String 必有字段 备注:设备id
  664. code: childItem.switchCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  665. value: childItem.isOpen ? "1" : "0", //类型:String 必有字段 备注:值 0
  666. };
  667. arr.push(obj);
  668. // loadig的状态
  669. } else if (btnType === "temp") {
  670. childItem.num = 2;
  671. if (symbol === "up") {
  672. if (childItem.tempSet >= proxyData.airData.maxTempSet) {
  673. return;
  674. }
  675. childItem.tempSet = childItem.tempSet + 0.5;
  676. } else if (symbol === "down") {
  677. if (childItem.tempSet <= proxyData.airData.minTempSet) {
  678. return;
  679. }
  680. childItem.tempSet = childItem.tempSet - 0.5;
  681. }
  682. let obj: any = {
  683. id: childItem.id, //类型:String 必有字段 备注:设备id
  684. code: childItem.tempSetCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  685. value: childItem.tempSet, //类型:String 必有字段 备注:值 0
  686. };
  687. arr.push(obj);
  688. proxyData.childDisabled(childItem, arr);
  689. } else if (btnType === "gear") {
  690. if (symbol === "up") {
  691. if (childItem.isAutoGear) {
  692. return;
  693. }
  694. if (childItem.gear >= 3) {
  695. childItem.isAutoGear = 1;
  696. } else {
  697. childItem.gear++;
  698. childItem.isAutoGear = 0;
  699. }
  700. } else if (symbol === "down") {
  701. if (!childItem.isAutoGear && childItem.gear <= 1) {
  702. return;
  703. }
  704. if (childItem.isAutoGear) {
  705. childItem.isAutoGear = 0;
  706. childItem.gear = 3;
  707. } else {
  708. childItem.gear--;
  709. }
  710. }
  711. let obj: any = {
  712. id: childItem.id, //类型:String 必有字段 备注:设备id
  713. code: childItem.gearCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  714. value: childItem.isAutoGear ? 4 : childItem.gear, //类型:String 必有字段 备注:值 0
  715. };
  716. arr.push(obj);
  717. } else if (btnType === "model") {
  718. if (symbol === "up") {
  719. if (childItem.workMode >= 3) {
  720. return;
  721. }
  722. childItem.workMode++;
  723. } else if (symbol === "down") {
  724. if (childItem.workMode <= 1) {
  725. return;
  726. }
  727. childItem.workMode--;
  728. }
  729. let obj: any = {
  730. id: childItem.id, //类型:String 必有字段 备注:设备id
  731. code: childItem.modeSetCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  732. value: childItem.workMode, //类型:String 必有字段 备注:值 0
  733. };
  734. arr.push(obj);
  735. }
  736. // 修改单个设备的状态
  737. if (btnType !== "temp") {
  738. proxyData.setSpaceCondtioners(arr);
  739. }
  740. proxyData.updateChildPerstion();
  741. },
  742. // 改变设备状态
  743. setSpaceCondtioners(data: any) {
  744. setSpaceCondtioners(data)
  745. .then((res) => {
  746. // proxyData.setLoadingNumber();
  747. proxyData.loadinngEnd();
  748. })
  749. .catch(() => {
  750. // proxyData.setLoadingNumber();
  751. proxyData.loadinngEnd();
  752. });
  753. },
  754. // 改变空调状态
  755. changeZongAir(btnType: any, text: any) {
  756. if (!airData.runStatus) return;
  757. let equpObj: any = proxyData.formatAirData(btnType, text);
  758. let data: any = [];
  759. proxyData.equipList.map((item: any) => {
  760. let obj: any = {
  761. id: item.id, //类型:String 必有字段 备注:设备id
  762. code: item[equpObj.codeKey], //类型:String 必有字段 备注:编码 EquipSwtichSet
  763. value: equpObj.value, //类型:String 必有字段 备注:值 0
  764. };
  765. data.push(obj);
  766. });
  767. console.log("设备数据处理---");
  768. console.log(data);
  769. if (!proxyData.cotrolLoading) {
  770. proxyData.loadingStart();
  771. // 调整设备状态
  772. proxyData.setSpaceCondtioners(data);
  773. }
  774. },
  775. // 检查设备是否执行空间服务时间
  776. checkDeviceIsExeSpaceTime(deviceAll: any = []) {
  777. let seviceEquipmentList: any = proxyData.seviceEquipmentList;
  778. let flag: any = false;
  779. for (let i = 0; i < seviceEquipmentList.length; i++) {
  780. for (let j = 0; j < deviceAll.length; j++) {
  781. if (
  782. seviceEquipmentList[i].id == deviceAll[j].id &&
  783. seviceEquipmentList[i].isExeSpaceTime
  784. ) {
  785. flag = true;
  786. break;
  787. }
  788. }
  789. if (flag) {
  790. break;
  791. }
  792. }
  793. return flag;
  794. },
  795. // 总控制改变空调状态
  796. airChange() {
  797. // 先不更新状态等确认框弹出后再更新状
  798. // 操作空调
  799. const domAirOpen = !proxyData.airData.isOpen;
  800. let isExeSpaceTime: Boolean = proxyData.checkDeviceIsExeSpaceTime(
  801. proxyData.equipList
  802. );
  803. if (proxyData.forceOverTimeFlag && domAirOpen && isExeSpaceTime) {
  804. //需要强制加班
  805. contx.emit("triggerWork", 2);
  806. return;
  807. }
  808. proxyData.airData.isOpen = !proxyData.airData.isOpen;
  809. proxyData.loadingAir = true;
  810. proxyData.loadingTimer = 0;
  811. clearTimeout(proxyData.airTimer);
  812. proxyData.setLoadingNumber();
  813. let data: any = [];
  814. proxyData.equipList.map((item: any) => {
  815. let obj: any = {
  816. id: item.id, //类型:String 必有字段 备注:设备id
  817. code: item.switchCode, //类型:String 必有字段 备注:编码 EquipSwtichSet
  818. value: proxyData.airData.isOpen ? "1" : "0", //类型:String 必有字段 备注:值 0
  819. };
  820. data.push(obj);
  821. });
  822. // 设备状态处理
  823. proxyData.setSpaceCondtioners(data);
  824. },
  825. // 设置子设备的状态
  826. formateSetChildStatus() {
  827. proxyData.equipList.map((item: any) => {
  828. item.isOpen = item.runStatus === 1 ? true : false;
  829. });
  830. },
  831. // 初始化滚动
  832. async barSwiperInit() {
  833. if (proxyData.airData.isOpen && !proxyData.showChild) {
  834. proxyData.endBoxSwiper();
  835. proxyData.setBarNowPerstion();
  836. }
  837. },
  838. // 设置子设备的可调范围
  839. setChildSelectList() {
  840. proxyData.equipList.map((item: any) => {
  841. let tempArr: any = [];
  842. for (
  843. let i = proxyData.airData.minTempSet;
  844. i <= proxyData.airData.maxTempSet;
  845. i = i + 0.5
  846. ) {
  847. tempArr.push(i);
  848. }
  849. item.tempArr = tempArr;
  850. let index: any = item.tempArr.findIndex((ele: any) => {
  851. return ele == item.tempSet;
  852. });
  853. item.sel = index == -1 ? 0 : index;
  854. let modelArr: any = ["制冷", "制热", "通风"];
  855. item.modelArr = modelArr;
  856. if (item.workMode > 3) {
  857. item.workMode = 1;
  858. }
  859. let mIndex: any = item.workMode ? item.workMode - 1 : 2;
  860. item.mIndex = mIndex;
  861. let gearArr: any = [0, 1, 2, 3, "AUTO"];
  862. item.gearArr = gearArr;
  863. let gIndex: any = item.gearArr.findIndex((ele: any) => {
  864. if (item.isAutoGear == 1) {
  865. return ele == "AUTO";
  866. } else {
  867. return ele == item.gear;
  868. }
  869. });
  870. item.gIndex = gIndex == -1 ? 0 : gIndex;
  871. });
  872. proxyData.setValueHeight();
  873. },
  874. setValueHeight() {
  875. if (!proxyData.valueHeight) {
  876. proxyData.valueDom = proxyData.valueDom
  877. ? proxyData.valueDom
  878. : document.querySelectorAll(".value")[0];
  879. proxyData.valueHeight = proxyData.valueDom
  880. ? proxyData.valueDom.offsetHeight
  881. : 0;
  882. }
  883. console.log("proxyData.valueHeight==", proxyData.valueHeight);
  884. },
  885. // 改变子设备选中的位置
  886. updateChildPerstion() {
  887. proxyData.equipList.map((item: any) => {
  888. let index: any = item.tempArr.findIndex((ele: any) => {
  889. return ele == item.tempSet;
  890. });
  891. item.sel = index == -1 ? 0 : index;
  892. let mIndex: any = item.workMode ? item.workMode - 1 : 2;
  893. item.mIndex = mIndex;
  894. let gIndex: any = item.gearArr.findIndex((ele: any) => {
  895. if (item.isAutoGear == 1) {
  896. return ele == "AUTO";
  897. } else {
  898. return ele == item.gear;
  899. }
  900. });
  901. item.gIndex = gIndex == -1 ? 0 : gIndex;
  902. });
  903. },
  904. // 空调信息airTemp
  905. getAirInfo() {
  906. const paramObj = {
  907. // // projectId: props.projectId, //'Pj1101080255'
  908. // projectId: "Pj1101080255",
  909. // spaceId: "Sp110108025564f438d7fef64eea8202a6462f1bbcce",
  910. spaceId: proxyData.spaceId,
  911. // spaceId: props.spaceId,//'Sp110108025564f438d7fef64eea8202a6462f1bbcce' 空间id
  912. };
  913. //wx.showLoading();
  914. let str: any = setQueryConfig(paramObj);
  915. querySpaceConditioners(str)
  916. .then((res) => {
  917. let data: any = res.data || {};
  918. proxyData.firstLoadingAir = false;
  919. proxyData.loadingAir = false;
  920. proxyData.airTemp = data.tempSet;
  921. proxyData.airData.maxTempSet = data.maxTempSet;
  922. proxyData.airData.minTempSet = data.minTempSet;
  923. proxyData.airData.isOpen = data.runStatus ? true : false;
  924. proxyData.airData.runStatus = data.runStatus;
  925. proxyData.airData.isAutoGear = data.isAutoGear;
  926. proxyData.airData.gear = data.gear;
  927. proxyData.airData.workMode = data.workMode;
  928. proxyData.equipList = data.equipList;
  929. // 设置子设备的状态
  930. proxyData.setChildSelectList();
  931. proxyData.formateSetChildStatus();
  932. // 设置当前温度的位置
  933. if (proxyData.airData.isOpen) {
  934. proxyData.airData.airImg = parseImgUrl(
  935. "page-officehome",
  936. "openair.png"
  937. );
  938. } else {
  939. proxyData.airData.airImg = parseImgUrl(
  940. "page-officehome",
  941. "air_close.png"
  942. );
  943. }
  944. nextTick(() => {
  945. proxyData.barSwiperInit();
  946. });
  947. proxyData.getAirInfoToTimer();
  948. })
  949. .catch(() => {});
  950. },
  951. });
  952. watch(props, (newProps: any) => {
  953. if (newProps.spaceId) {
  954. // proxyData.swiperIinit = false;
  955. proxyData.spaceId = newProps.spaceId;
  956. // proxyData.getAirInfoToTimer(0);
  957. proxyData.temperature = props.temperature;
  958. proxyData.userIsControl = newProps.userIsControl;
  959. proxyData.forceOverTimeFlag = newProps.forceOverTimeFlag;
  960. proxyData.seviceEquipmentList = props.seviceEquipmentList;
  961. }
  962. });
  963. onBeforeUnmount(() => {
  964. if (proxyData.airTimer) {
  965. clearTimeout(proxyData.airTimer);
  966. proxyData.airTimer = null;
  967. }
  968. });
  969. onMounted(() => {
  970. proxyData.spaceId = props.spaceId;
  971. proxyData.getAirInfoToTimer(0);
  972. // 获取空调信息
  973. });
  974. return {
  975. ...toRefs(proxyData),
  976. };
  977. },
  978. });
  979. </script>
  980. <style lang="scss" scoped>
  981. .air {
  982. position: relative;
  983. width: 100%;
  984. background: #ffffff;
  985. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.07), 0px 4px 10px rgba(0, 0, 0, 0.05);
  986. border-radius: 25px;
  987. margin: 15px 0px;
  988. .loading-box {
  989. position: absolute;
  990. left: 50%;
  991. top: 50%;
  992. transform: translate(-50%, -50%);
  993. width: 100%;
  994. height: 100%;
  995. background: rgba(#000000, 0.3);
  996. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.07),
  997. 0px 4px 10px rgba(0, 0, 0, 0.05);
  998. text-align: center;
  999. z-index: 999;
  1000. // line-height: 50px;
  1001. }
  1002. .active-color {
  1003. background: $elActiveColor !important;
  1004. span {
  1005. color: #fff !important;
  1006. }
  1007. }
  1008. }
  1009. .air-child {
  1010. width: 100%;
  1011. // padding: 20px;
  1012. padding-left: 10px;
  1013. padding-right: 10px;
  1014. // padding-top: 10px;
  1015. .child-control-box {
  1016. display: inline-block;
  1017. width: 50%;
  1018. justify-content: space-between;
  1019. padding: 10px 10px 10px 10px;
  1020. // margin-top: 10px;
  1021. // padding-right: 10px;
  1022. border-top: 1px solid rgba(196, 196, 196, 0.4);
  1023. &:nth-child(2n + 1) {
  1024. border-right: 1px solid rgba(196, 196, 196, 0.4);
  1025. }
  1026. .open-title {
  1027. width: 100%;
  1028. font-size: 14px;
  1029. height: 25px;
  1030. line-height: 25px;
  1031. display: flex;
  1032. justify-content: space-between;
  1033. margin-bottom: 10px;
  1034. span {
  1035. font-size: 16px;
  1036. display: inline-block;
  1037. width: calc(100% - 50px);
  1038. overflow: hidden;
  1039. text-overflow: ellipsis;
  1040. white-space: nowrap;
  1041. }
  1042. .child-switch {
  1043. // height: 20px;
  1044. // width: 50px;
  1045. }
  1046. }
  1047. .adjust-box {
  1048. box-sizing: border-box;
  1049. // padding-right: 10px;
  1050. padding-top: 10px;
  1051. display: flex;
  1052. justify-content: space-between;
  1053. font-size: 19px;
  1054. .adjust-item {
  1055. // flex: 1;
  1056. // width: 40px;
  1057. display: flex;
  1058. flex-direction: column;
  1059. justify-content: space-between;
  1060. text-align: center;
  1061. &:nth-child(2) {
  1062. // width: 60px;
  1063. flex: 1;
  1064. }
  1065. .adjust-icon {
  1066. display: inline-block;
  1067. flex: 1;
  1068. }
  1069. .adjust-text {
  1070. // flex: 1;
  1071. // padding: 20px 0;
  1072. height: 50px;
  1073. overflow: hidden;
  1074. color: #1f2429;
  1075. .value-wrap {
  1076. transition: transform 1s;
  1077. .value {
  1078. width: 100%;
  1079. height: 50px;
  1080. display: flex;
  1081. align-items: center;
  1082. font-weight: 400;
  1083. justify-content: center;
  1084. text-align: center;
  1085. font-size: 14px;
  1086. }
  1087. }
  1088. }
  1089. .adjust-title {
  1090. padding-top: 10px;
  1091. font-size: 14px;
  1092. font-weight: 400;
  1093. }
  1094. .disable-color {
  1095. color: $elDisabledColor;
  1096. }
  1097. }
  1098. }
  1099. }
  1100. }
  1101. .air-top {
  1102. padding-left: 20px;
  1103. padding-bottom: 20px;
  1104. display: flex;
  1105. justify-content: space-between;
  1106. .air-desc {
  1107. position: relative;
  1108. // flex: 1 157px;
  1109. padding-top: 10px;
  1110. font-family: PingFang SC;
  1111. font-size: 16px;
  1112. line-height: 19px;
  1113. color: #4d5262;
  1114. flex: none;
  1115. flex-grow: 0;
  1116. margin: 5px 0px;
  1117. min-height: 100px;
  1118. .air-title {
  1119. font-family: PingFang SC;
  1120. padding-left: 5px;
  1121. font-size: 16px;
  1122. line-height: 20px;
  1123. color: #4d5262;
  1124. padding-bottom: 10px;
  1125. i {
  1126. display: inline-block;
  1127. font-size: 12px;
  1128. transform: scale(0.9);
  1129. font-style: normal;
  1130. padding-left: 5px;
  1131. color: #c4c4c4;
  1132. }
  1133. }
  1134. .air-temperature {
  1135. display: inline-block;
  1136. font-family: "Montserrat";
  1137. font-style: normal;
  1138. font-weight: normal;
  1139. font-size: 32px;
  1140. line-height: 32px;
  1141. flex: none;
  1142. order: 0;
  1143. flex-grow: 0;
  1144. margin: 0px 4px;
  1145. sup {
  1146. font-family: Mulish;
  1147. font-style: normal;
  1148. font-weight: 800;
  1149. font-size: 12px;
  1150. line-height: 15px;
  1151. }
  1152. }
  1153. .show-all {
  1154. position: absolute;
  1155. width: 110px;
  1156. bottom: -8px;
  1157. font-family: PingFang SC;
  1158. font-size: 14px;
  1159. line-height: 16px;
  1160. color: #c4c4c4;
  1161. margin: 0px 5px;
  1162. span {
  1163. font-size: 12px;
  1164. }
  1165. .light-icon {
  1166. font-size: 12px;
  1167. padding-right: 10px;
  1168. }
  1169. }
  1170. }
  1171. .air-right {
  1172. position: relative;
  1173. width: 157px;
  1174. text-align: center;
  1175. img {
  1176. width: 147px;
  1177. height: 110px;
  1178. }
  1179. .switch-btn {
  1180. position: absolute;
  1181. z-index: 111;
  1182. bottom: -5px;
  1183. right: 25px;
  1184. }
  1185. }
  1186. }
  1187. .air-control {
  1188. padding: 10px;
  1189. border-top: 1px solid rgba(196, 196, 196, 0.4);
  1190. .control-box {
  1191. display: flex;
  1192. justify-content: space-between;
  1193. }
  1194. .volume-box {
  1195. padding: 10px;
  1196. color: #c4c4c4;
  1197. font-size: 12px;
  1198. .text {
  1199. padding-top: 5px;
  1200. font-style: normal;
  1201. font-weight: 600;
  1202. font-size: 11px;
  1203. }
  1204. .number {
  1205. span {
  1206. display: inline-block;
  1207. vertical-align: middle;
  1208. color: #c4c4c4;
  1209. padding-right: 5px;
  1210. }
  1211. .number-active {
  1212. font-family: "Montserrat";
  1213. font-style: normal;
  1214. font-weight: 500;
  1215. font-size: 22px;
  1216. line-height: 24px;
  1217. color: #4d5262 !important;
  1218. }
  1219. }
  1220. .model {
  1221. font-size: 14px;
  1222. color: #1f2429;
  1223. }
  1224. }
  1225. .volume-icon {
  1226. .icon-item {
  1227. position: relative;
  1228. display: inline-block;
  1229. width: 42px;
  1230. height: 42px;
  1231. background: rgba(196, 196, 196, 0.2);
  1232. border-radius: 50%;
  1233. img {
  1234. width: 20px;
  1235. height: 20px;
  1236. position: absolute;
  1237. left: 50%;
  1238. top: 50%;
  1239. transform: translate(-50%, -50%);
  1240. }
  1241. &:nth-child(2) {
  1242. margin-left: 10px;
  1243. margin-right: 10px;
  1244. }
  1245. span {
  1246. font-size: 12px;
  1247. color: #000000;
  1248. position: absolute;
  1249. left: 50%;
  1250. top: 50%;
  1251. transform: translate(-50%, -50%) scale(0.8);
  1252. }
  1253. }
  1254. }
  1255. .temp-text {
  1256. height: 20px;
  1257. line-height: 20px;
  1258. font-family: "Montserrat";
  1259. font-style: normal;
  1260. font-weight: 500;
  1261. font-size: 11px;
  1262. color: #c4c4c4;
  1263. padding: 0 5px;
  1264. }
  1265. .temp-slider {
  1266. position: relative;
  1267. display: flex;
  1268. height: 20px;
  1269. flex: 1;
  1270. border-radius: 5px;
  1271. .item {
  1272. height: 20px;
  1273. flex: 1;
  1274. font-size: 0;
  1275. &:nth-child(1) {
  1276. background: #5e8bcf;
  1277. border-radius: 11px 0 0 11px;
  1278. }
  1279. &:nth-child(2) {
  1280. background: #9fb7cd;
  1281. }
  1282. &:nth-child(3) {
  1283. background: #f3f3f3;
  1284. }
  1285. &:nth-child(4) {
  1286. background: #ff9882;
  1287. }
  1288. &:nth-child(5) {
  1289. background: #e5574f;
  1290. border-radius: 0 11px 11px 0;
  1291. }
  1292. }
  1293. .slider-bar {
  1294. position: absolute;
  1295. width: 25px;
  1296. left: 0;
  1297. bottom: -2px;
  1298. z-index: 333;
  1299. .bar-temp {
  1300. padding-bottom: 10px;
  1301. font-size: 12px;
  1302. color: #1f2429;
  1303. }
  1304. .bar-circle {
  1305. width: 25px;
  1306. height: 25px;
  1307. background: #fff;
  1308. border-radius: 50%;
  1309. box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1),
  1310. 0px 4px 10px rgba(0, 0, 0, 0.07);
  1311. border-radius: 21px;
  1312. z-index: 444;
  1313. }
  1314. }
  1315. }
  1316. .control-text {
  1317. font-style: normal;
  1318. font-weight: 600;
  1319. font-size: 11px;
  1320. line-height: 15px;
  1321. color: #c4c4c4;
  1322. padding: 10px 0 0 10px;
  1323. }
  1324. }
  1325. .air-control-padding {
  1326. padding-top: 35px;
  1327. padding-bottom: 15px;
  1328. }
  1329. </style>
  1330. <style lang="scss">
  1331. .air {
  1332. .loading-box {
  1333. .van-loading {
  1334. position: absolute;
  1335. left: 50%;
  1336. top: 50%;
  1337. transform: translate(-50%, -50%);
  1338. }
  1339. }
  1340. .van-loading__spinner {
  1341. color: $elActiveColor !important;
  1342. }
  1343. .van-switch__loading {
  1344. top: 0;
  1345. left: 0;
  1346. width: 100%;
  1347. height: 100%;
  1348. line-height: 1;
  1349. }
  1350. .van-switch--disabled {
  1351. opacity: 0.5;
  1352. }
  1353. .child-control-box {
  1354. .child-switch {
  1355. // position: relative;
  1356. .van-switch__node {
  1357. // margin-top: -6px;
  1358. // width: 20px !important;
  1359. // height: 20px !important;
  1360. }
  1361. }
  1362. }
  1363. }
  1364. </style>