EnvMonitor.vue 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. <script setup lang="ts">
  2. import { onMounted, ref, watch } from 'vue';
  3. import { message } from 'ant-design-vue';
  4. import ButtonTabs from '@/components/ButtonTabs.vue';
  5. import LineChart from '@/components/LineChart.vue';
  6. import SvgIcon from '@/components/SvgIcon.vue';
  7. import { useRequest } from '@/hooks/request';
  8. import { t } from '@/i18n';
  9. import {
  10. addMonitorPoint,
  11. addRegion,
  12. deleteMonitorPoint,
  13. getDeviceGroupList,
  14. getDeviceListSimple,
  15. getGroupRegions,
  16. getMonitorPointInfo,
  17. getPageList,
  18. getRegionsPointsData,
  19. queryDevicesList,
  20. regionDelete,
  21. regionUpdate,
  22. updateMonitorPoint,
  23. updateRegionMonitorPoint,
  24. } from '@/api';
  25. import { HumitureType } from '@/constants';
  26. import envMonitorBgc from '@/assets/img/env-monitor-bgc.png';
  27. import type { CSSProperties } from 'vue';
  28. import type { FormInstance, Rule } from 'ant-design-vue/es/form';
  29. import type { DefaultOptionType, SelectValue } from 'ant-design-vue/es/select';
  30. import type {
  31. DeviceGroup,
  32. DeviceGroupItem,
  33. DeviceParams,
  34. DevicesListItem,
  35. GroupRegions,
  36. MonitoringForm,
  37. MonitoringPointData,
  38. OutdooForm,
  39. RegionNameList,
  40. RegionsPointsItem,
  41. } from '@/types';
  42. interface EnvMonitorStyle {
  43. background: string;
  44. backgroundSize: string;
  45. }
  46. const oneDeviceGroup = ref<DeviceGroup[]>([]);
  47. const twoDeviceGroup = ref<DeviceGroup[]>([]);
  48. const gradeOne = ref<number | undefined>(undefined);
  49. const gradeTwo = ref<number | undefined>(undefined);
  50. const monitoringPointOpen = ref<boolean>(false);
  51. const outdoorOpen = ref<boolean>(false);
  52. const regionNameOpen = ref<boolean>(false);
  53. const regionName = ref<string>('');
  54. const groupRegions = ref<GroupRegions[]>([]);
  55. const titleRegions = ref<boolean>(true);
  56. const titleMonitoring = ref<boolean>(true);
  57. const deviceGroup = ref<DeviceGroupItem[]>([]);
  58. const returnDevicesList = ref<DevicesListItem[]>([]);
  59. const supplyDevicesList = ref<DevicesListItem[]>([]);
  60. const outdoorDevicesList = ref<DevicesListItem[]>([]);
  61. const returnDeviceParamsList = ref<DeviceParams[]>([]);
  62. const supplyDeviceParamsList = ref<DeviceParams[]>([]);
  63. const outdoorDeviceParamsList = ref<DeviceParams[]>([]);
  64. const monitoringPointData = ref<MonitoringPointData[]>([]);
  65. const regionNameList = ref<RegionNameList[]>([]);
  66. const regionList = ref<RegionsPointsItem[]>([]);
  67. const selectId = ref<number>(0);
  68. const monitoringId = ref<number>();
  69. const formRef = ref<FormInstance>();
  70. const envMonitorStyle = ref<EnvMonitorStyle>({
  71. background: `url(${envMonitorBgc})`,
  72. backgroundSize: 'cover',
  73. });
  74. const monitoringForm = ref<MonitoringForm>({
  75. name: '',
  76. tempHumidityControlMode: '2',
  77. regionId: undefined,
  78. returnDevGroupId: undefined,
  79. returnDevId: undefined,
  80. returnTempParamCode: '',
  81. returnHumidityParamCode: '',
  82. supplyDevGroupId: undefined,
  83. supplyTempParamCode: '',
  84. supplyHumidityParamCode: '',
  85. tempUpper: 0,
  86. tempLower: 0,
  87. tempPreset: 0,
  88. humidityUpper: 0,
  89. humidityLower: 0,
  90. humidityPreset: 0,
  91. });
  92. const outdooForm = ref<OutdooForm>({
  93. regionId: undefined,
  94. outsideDevGroupId: undefined,
  95. outsideDevId: undefined,
  96. outsideTempParamCode: '',
  97. outsideHumidityParamCode: '',
  98. outsideEnthalpyParamCode: '',
  99. });
  100. const headerStyle: CSSProperties = {
  101. borderBottom: 0,
  102. padding: '16px 16px 0 24px',
  103. };
  104. const footerStyle: CSSProperties = {
  105. borderTop: 0,
  106. padding: '16px 24px',
  107. };
  108. const rules: Record<string, Rule[]> = {
  109. name: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  110. regionId: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  111. returnDevGroupId: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  112. returnDevId: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  113. returnTempParamCode: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  114. returnHumidityParamCode: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  115. supplyDevGroupId: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  116. supplyDevId: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  117. supplyTempParamCode: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  118. supplyHumidityParamCode: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  119. };
  120. const { handleRequest } = useRequest();
  121. const getGroupRegionsList = () => {
  122. console.log(gradeTwo.value);
  123. handleRequest(async () => {
  124. if (gradeTwo.value) {
  125. groupRegions.value = await getGroupRegions(gradeTwo.value);
  126. }
  127. });
  128. };
  129. const regionNameOk = () => {
  130. if (!regionName.value) {
  131. return message.warning('请输入区域名称');
  132. }
  133. handleRequest(async () => {
  134. if (gradeTwo.value && regionName.value) {
  135. if (titleRegions.value) {
  136. await addRegion({
  137. devGroupId: gradeTwo.value,
  138. regionName: regionName.value,
  139. });
  140. } else {
  141. await regionUpdate({
  142. id: monitoringForm.value.regionId,
  143. devGroupId: gradeTwo.value,
  144. regionName: regionName.value,
  145. });
  146. }
  147. getGroupRegionsList();
  148. regionNameOpen.value = false;
  149. }
  150. });
  151. };
  152. const regionNameDelete = () => {
  153. if (!regionName.value) {
  154. return message.warning('请输入区域名称');
  155. }
  156. handleRequest(async () => {
  157. if (monitoringForm.value.regionId) {
  158. await regionDelete(monitoringForm.value.regionId);
  159. monitoringForm.value.regionId = undefined;
  160. getGroupRegionsList();
  161. regionNameOpen.value = false;
  162. }
  163. });
  164. };
  165. const addRegionName = () => {
  166. titleRegions.value = true;
  167. regionNameOpen.value = true;
  168. regionName.value = '';
  169. };
  170. const addRegionList = (value: SelectValue, option: DefaultOptionType) => {
  171. regionName.value = option.regionName;
  172. };
  173. const editingRegionName = () => {
  174. if (monitoringForm.value.regionId) {
  175. titleRegions.value = false;
  176. regionNameOpen.value = true;
  177. } else {
  178. return message.warning('请选择区域名称');
  179. }
  180. };
  181. const addMonitoringPoint = () => {
  182. titleMonitoring.value = true;
  183. monitoringPointOpen.value = true;
  184. };
  185. const addAllGatewayList = (value: number) => {
  186. handleRequest(async () => {
  187. const data = await getDeviceGroupList({
  188. parentId: value,
  189. });
  190. if (data.length) {
  191. if (value === -1) {
  192. oneDeviceGroup.value = data;
  193. gradeOne.value = data[0].id;
  194. } else {
  195. twoDeviceGroup.value = data;
  196. gradeTwo.value = data[0].id;
  197. }
  198. }
  199. });
  200. };
  201. const getRegionsPointsList = (value: number) => {
  202. monitoringPointData.value = [];
  203. regionNameList.value = [];
  204. handleRequest(async () => {
  205. const data = await getRegionsPointsData(value);
  206. if (data.length) {
  207. data.forEach((item) => {
  208. const { id, regionName } = item;
  209. if (item.points.length) {
  210. monitoringPointData.value.push(...item.points);
  211. }
  212. regionNameList.value.push({
  213. name: regionName,
  214. id,
  215. });
  216. });
  217. if (data[0].id) {
  218. selectId.value = data[0].id;
  219. }
  220. }
  221. });
  222. };
  223. const obtainRegionsPointsData = (value: number) => {
  224. handleRequest(async () => {
  225. regionList.value = await getRegionsPointsData(value);
  226. });
  227. };
  228. const adddDeviceGroup = (value: SelectValue, option: DefaultOptionType, judgment: number) => {
  229. getDevicesGroupList(option.id, judgment);
  230. };
  231. const adddDevice = (value: SelectValue, option: DefaultOptionType, judgment: number) => {
  232. getDeviceParamsList(option.id, judgment);
  233. };
  234. const getDeviceParamsList = (id: number, judgment: number) => {
  235. handleRequest(async () => {
  236. const data = await getDeviceListSimple(id);
  237. if (judgment === HumitureType.ReturnAir) {
  238. returnDeviceParamsList.value = data;
  239. monitoringForm.value.returnHumidityParamCode = '';
  240. monitoringForm.value.returnTempParamCode = '';
  241. } else if (judgment === HumitureType.SupplyAir) {
  242. supplyDeviceParamsList.value = data;
  243. monitoringForm.value.supplyHumidityParamCode = '';
  244. monitoringForm.value.supplyTempParamCode = '';
  245. } else if (judgment === HumitureType.Outdoor) {
  246. outdoorDeviceParamsList.value = data;
  247. outdooForm.value.outsideEnthalpyParamCode = '';
  248. outdooForm.value.outsideHumidityParamCode = '';
  249. outdooForm.value.outsideTempParamCode = '';
  250. }
  251. });
  252. };
  253. const getDevicesGroupList = (id: number, judgment: number) => {
  254. handleRequest(async () => {
  255. const { records } = await queryDevicesList({
  256. pageIndex: 1,
  257. pageSize: 99999,
  258. groupId: id,
  259. });
  260. if (judgment === HumitureType.ReturnAir) {
  261. returnDevicesList.value = records;
  262. monitoringForm.value.returnDevId = undefined;
  263. monitoringForm.value.returnHumidityParamCode = '';
  264. monitoringForm.value.returnTempParamCode = '';
  265. } else if (judgment === HumitureType.SupplyAir) {
  266. supplyDevicesList.value = records;
  267. monitoringForm.value.supplyDevId = undefined;
  268. monitoringForm.value.supplyHumidityParamCode = '';
  269. monitoringForm.value.supplyTempParamCode = '';
  270. } else if (judgment === HumitureType.Outdoor) {
  271. outdoorDevicesList.value = records;
  272. outdooForm.value.outsideDevId = undefined;
  273. outdooForm.value.outsideEnthalpyParamCode = '';
  274. outdooForm.value.outsideHumidityParamCode = '';
  275. outdooForm.value.outsideTempParamCode = '';
  276. }
  277. });
  278. };
  279. const deleteMonitoringPoint = () => {
  280. if (!titleMonitoring.value) {
  281. handleRequest(async () => {
  282. if (monitoringId.value) {
  283. await deleteMonitorPoint(monitoringId.value);
  284. }
  285. });
  286. }
  287. monitoringPointOpen.value = false;
  288. };
  289. const saveMonitoringPoint = () => {
  290. formRef.value
  291. ?.validate()
  292. .then(() => {
  293. handleRequest(async () => {
  294. if (titleMonitoring.value) {
  295. await addMonitorPoint(monitoringForm.value);
  296. } else {
  297. await updateMonitorPoint(monitoringForm.value);
  298. }
  299. if (gradeTwo.value) {
  300. getRegionsPointsList(gradeTwo.value);
  301. }
  302. monitoringPointOpen.value = false;
  303. });
  304. })
  305. .catch(() => {});
  306. };
  307. const getDeviceGroup = () => {
  308. handleRequest(async () => {
  309. deviceGroup.value = await getPageList();
  310. });
  311. };
  312. const offDrawer = () => {
  313. monitoringPointOpen.value = false;
  314. };
  315. const selectClick = (id: number) => {
  316. selectId.value = id;
  317. };
  318. const editorClick = (monitoringPointId: number) => {
  319. handleRequest(async () => {
  320. const {
  321. humidityLower,
  322. humidityPreset,
  323. humidityUpper,
  324. name,
  325. regionId,
  326. returnDevGroupId,
  327. returnDevId,
  328. returnHumidityParamCode,
  329. returnTempParamCode,
  330. supplyDevGroupId,
  331. supplyDevId,
  332. supplyHumidityParamCode,
  333. supplyTempParamCode,
  334. tempHumidityControlMode,
  335. tempLower,
  336. tempPreset,
  337. tempUpper,
  338. id,
  339. } = await getMonitorPointInfo(monitoringPointId);
  340. Object.assign(monitoringForm.value, {
  341. humidityLower,
  342. humidityPreset,
  343. humidityUpper,
  344. name,
  345. regionId,
  346. returnDevGroupId,
  347. returnDevId,
  348. returnHumidityParamCode,
  349. returnTempParamCode,
  350. supplyDevGroupId,
  351. supplyDevId,
  352. supplyHumidityParamCode,
  353. supplyTempParamCode,
  354. tempHumidityControlMode: String(tempHumidityControlMode),
  355. tempLower,
  356. tempPreset,
  357. tempUpper,
  358. id,
  359. });
  360. monitoringId.value = id;
  361. getDevicesGroupList(returnDevGroupId, HumitureType.ReturnAir);
  362. getDevicesGroupList(supplyDevGroupId, HumitureType.SupplyAir);
  363. getDeviceParamsList(returnDevId, HumitureType.ReturnAir);
  364. getDeviceParamsList(supplyDevId, HumitureType.SupplyAir);
  365. titleMonitoring.value = false;
  366. monitoringPointOpen.value = true;
  367. });
  368. };
  369. const addOutdoorDrawer = () => {
  370. outdoorOpen.value = true;
  371. regionList.value.forEach((item) => {
  372. const {
  373. outsideEnthalpyParamCode,
  374. outsideHumidityParamCode,
  375. outsideTempParamCode,
  376. outsideDevGroupId,
  377. outsideDevId,
  378. id,
  379. } = item;
  380. if (item.id === selectId.value) {
  381. Object.assign(outdooForm.value, {
  382. outsideEnthalpyParamCode,
  383. outsideHumidityParamCode,
  384. outsideTempParamCode,
  385. outsideDevGroupId,
  386. outsideDevId,
  387. regionId: id,
  388. });
  389. if (outsideDevGroupId) {
  390. getDevicesGroupList(outsideDevGroupId, HumitureType.Outdoor);
  391. }
  392. if (outsideDevId) {
  393. getDeviceParamsList(outsideDevId, HumitureType.Outdoor);
  394. }
  395. }
  396. });
  397. };
  398. const saveOutdoo = () => {
  399. handleRequest(async () => {
  400. await updateRegionMonitorPoint(outdooForm.value);
  401. if (gradeTwo.value) {
  402. obtainRegionsPointsData(gradeTwo.value);
  403. }
  404. outdoorOpen.value = false;
  405. });
  406. };
  407. const offOutdoorDrawer = () => {
  408. outdoorOpen.value = false;
  409. };
  410. watch(
  411. () => gradeOne.value,
  412. (count) => {
  413. if (count) {
  414. addAllGatewayList(count);
  415. }
  416. },
  417. );
  418. watch(
  419. () => gradeTwo.value,
  420. (count) => {
  421. if (count) {
  422. getRegionsPointsList(count);
  423. obtainRegionsPointsData(count);
  424. getGroupRegionsList();
  425. }
  426. },
  427. );
  428. onMounted(() => {
  429. addAllGatewayList(-1);
  430. getDeviceGroup();
  431. });
  432. </script>
  433. <template>
  434. <div>
  435. <AFlex justify="space-between">
  436. <AFlex align="center">
  437. <div class="text-top">环境监控</div>
  438. <ASelect
  439. class="select-width select-monitoring"
  440. v-model:value="gradeOne"
  441. :options="oneDeviceGroup"
  442. :field-names="{ label: 'groupName', value: 'id' }"
  443. placeholder="请选择"
  444. />
  445. <ASelect
  446. class="select-width"
  447. v-model:value="gradeTwo"
  448. :options="twoDeviceGroup"
  449. :field-names="{ label: 'groupName', value: 'id' }"
  450. placeholder="请选择"
  451. />
  452. </AFlex>
  453. <div>
  454. <AButton class="icon-button default-button">
  455. <AFlex align="center">
  456. <SvgIcon name="plus" />
  457. <span>切换到列表显示 </span>
  458. </AFlex>
  459. </AButton>
  460. <AButton type="primary" class="icon-button button-monitoring" @click="addMonitoringPoint">
  461. <AFlex align="center">
  462. <SvgIcon name="plus" />
  463. <span> 添加检测点 </span>
  464. </AFlex>
  465. </AButton>
  466. </div>
  467. </AFlex>
  468. <div class="content-monitoring">
  469. <div class="content-monitoring-top">123</div>
  470. <AFlex class="content-monitoring-canvas">
  471. <div class="content-monitoring-canvas-left">
  472. <div v-for="item in monitoringPointData" :key="item.id">
  473. <LineChart :data="item" @editorClick="editorClick" />
  474. </div>
  475. </div>
  476. <AFlex :style="envMonitorStyle" class="monitoring-img">
  477. <AFlex v-if="regionList.length" align="center" class="list-regions">
  478. <ButtonTabs
  479. :data="regionNameList"
  480. :select-id="selectId"
  481. :width="'75px'"
  482. :radius="'16px'"
  483. :tooltip="true"
  484. @selectClick="selectClick"
  485. />
  486. </AFlex>
  487. <div v-if="regionList.length" class="canvas-div">
  488. <AFlex justify="space-between" class="canvas-div-top">
  489. <AButton class="icon-button" @click="addOutdoorDrawer">
  490. <SvgIcon name="outdoor" />
  491. 22.9℃|60.6%
  492. </AButton>
  493. <AFlex>
  494. <AFlex justify="center" align="center" class="button-icon">
  495. <SvgIcon name="edit-o" />
  496. </AFlex>
  497. <AFlex justify="center" align="center" class="button-icon">
  498. <SvgIcon name="copy" />
  499. </AFlex>
  500. </AFlex>
  501. </AFlex>
  502. <div class="canvas-content">
  503. <AButton class="icon-button icon-button-margin">
  504. <SvgIcon name="outdoor" />
  505. 22.9℃|60.6%
  506. </AButton>
  507. </div>
  508. </div>
  509. </AFlex>
  510. </AFlex>
  511. </div>
  512. <ADrawer
  513. width="600"
  514. :open="monitoringPointOpen"
  515. :closable="false"
  516. class="drawer-monitoring"
  517. :header-style="headerStyle"
  518. :footer-style="footerStyle"
  519. >
  520. <template #title>{{ titleMonitoring ? '添加检测点' : '编辑监测点' }} </template>
  521. <template #extra>
  522. <SvgIcon class="off-icon" @click="offDrawer" name="close" />
  523. </template>
  524. <AForm ref="formRef" class="form-ref" :model="monitoringForm" layout="vertical" :rules="rules">
  525. <AFormItem name="name">
  526. <AInput v-model:value="monitoringForm.name" class="input-wdith region-bottom" placeholder="请输入" />
  527. </AFormItem>
  528. <AFormItem label="区域" name="regionId">
  529. <AFlex align="center">
  530. <ASelect
  531. class="input-wdith"
  532. v-model:value="monitoringForm.regionId"
  533. :options="groupRegions"
  534. :field-names="{ label: 'regionName', value: 'id' }"
  535. placeholder="请选择"
  536. @change="addRegionList"
  537. />
  538. <div @click="editingRegionName">
  539. <AFlex justify="center" align="center" class="button-flex">
  540. <SvgIcon name="edit-o" />
  541. </AFlex>
  542. </div>
  543. <div @click="addRegionName">
  544. <AFlex justify="center" align="center" class="button-flex button-plus">
  545. <SvgIcon name="plus" />
  546. </AFlex>
  547. </div>
  548. </AFlex>
  549. </AFormItem>
  550. <ARadioGroup v-model:value="monitoringForm.tempHumidityControlMode" class="radio-group">
  551. <ARadio value="2">回风控制</ARadio>
  552. <ARadio value="1">送风控制</ARadio>
  553. </ARadioGroup>
  554. <AFlex justify="space-between">
  555. <div>
  556. <AFormItem class="form-item" label="回风温湿度仪表" name="returnDevGroupId">
  557. <ASelect
  558. class="input-wdith"
  559. v-model:value="monitoringForm.returnDevGroupId"
  560. :options="twoDeviceGroup"
  561. :field-names="{ label: 'groupName', value: 'id' }"
  562. placeholder="请选择"
  563. @change="(value, option) => adddDeviceGroup(value, option, HumitureType.ReturnAir)"
  564. />
  565. </AFormItem>
  566. <AFormItem name="returnDevId">
  567. <ASelect
  568. class="input-wdith"
  569. v-model:value="monitoringForm.returnDevId"
  570. :options="returnDevicesList"
  571. :field-names="{ label: 'deviceName', value: 'id' }"
  572. placeholder="请选择"
  573. @change="(value, option) => adddDevice(value, option, HumitureType.ReturnAir)"
  574. />
  575. </AFormItem>
  576. <AFormItem name="returnTempParamCode">
  577. <ASelect
  578. class="input-wdith"
  579. v-model:value="monitoringForm.returnTempParamCode"
  580. :options="returnDeviceParamsList"
  581. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  582. placeholder="请选择"
  583. />
  584. </AFormItem>
  585. <AFormItem name="returnHumidityParamCode">
  586. <ASelect
  587. class="input-wdith"
  588. v-model:value="monitoringForm.returnHumidityParamCode"
  589. :options="returnDeviceParamsList"
  590. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  591. placeholder="请选择"
  592. />
  593. </AFormItem>
  594. </div>
  595. <div>
  596. <AFormItem label="送风温湿度仪表" name="supplyDevGroupId">
  597. <ASelect
  598. class="input-wdith"
  599. v-model:value="monitoringForm.supplyDevGroupId"
  600. :options="twoDeviceGroup"
  601. :field-names="{ label: 'groupName', value: 'id' }"
  602. placeholder="请选择"
  603. @change="(value, option) => adddDeviceGroup(value, option, HumitureType.SupplyAir)"
  604. />
  605. </AFormItem>
  606. <AFormItem name="supplyDevId">
  607. <ASelect
  608. class="input-wdith"
  609. v-model:value="monitoringForm.supplyDevId"
  610. :options="supplyDevicesList"
  611. :field-names="{ label: 'deviceName', value: 'id' }"
  612. placeholder="请选择"
  613. @change="(value, option) => adddDevice(value, option, HumitureType.SupplyAir)"
  614. />
  615. </AFormItem>
  616. <AFormItem name="supplyTempParamCode">
  617. <ASelect
  618. class="input-wdith"
  619. v-model:value="monitoringForm.supplyTempParamCode"
  620. :options="supplyDeviceParamsList"
  621. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  622. placeholder="请选择"
  623. />
  624. </AFormItem>
  625. <AFormItem name="supplyHumidityParamCode">
  626. <ASelect
  627. class="input-wdith"
  628. v-model:value="monitoringForm.supplyHumidityParamCode"
  629. :options="supplyDeviceParamsList"
  630. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  631. placeholder="请选择"
  632. />
  633. </AFormItem>
  634. </div>
  635. </AFlex>
  636. <AFlex justify="space-between">
  637. <div>
  638. <AFormItem label="室内温度配置">
  639. <AFlex align="center">
  640. <AInputNumber class="input-number-width" v-model:value="monitoringForm.tempUpper" :min="0" :max="999" />
  641. <div class="configure-text">上限值</div>
  642. </AFlex>
  643. </AFormItem>
  644. <AFormItem>
  645. <AFlex align="center">
  646. <AInputNumber class="input-number-width" v-model:value="monitoringForm.tempLower" :min="0" :max="999" />
  647. <div class="configure-text">下限值</div>
  648. </AFlex>
  649. </AFormItem>
  650. <AFormItem>
  651. <AFlex align="center">
  652. <AInputNumber
  653. class="input-number-width"
  654. v-model:value="monitoringForm.tempPreset"
  655. :min="0"
  656. :max="999"
  657. />
  658. <div class="configure-text">限定值</div>
  659. </AFlex>
  660. </AFormItem>
  661. </div>
  662. <div>
  663. <AFormItem label="室内湿度配置">
  664. <AFlex align="center">
  665. <AInputNumber
  666. class="input-number-width"
  667. v-model:value="monitoringForm.humidityUpper"
  668. :min="0"
  669. :max="999"
  670. />
  671. <div class="configure-text">上限值</div>
  672. </AFlex>
  673. </AFormItem>
  674. <AFormItem>
  675. <AFlex align="center">
  676. <AInputNumber
  677. class="input-number-width"
  678. v-model:value="monitoringForm.humidityLower"
  679. :min="0"
  680. :max="999"
  681. />
  682. <div class="configure-text">下限值</div>
  683. </AFlex>
  684. </AFormItem>
  685. <AFormItem>
  686. <AFlex align="center">
  687. <AInputNumber
  688. class="input-number-width"
  689. v-model:value="monitoringForm.humidityPreset"
  690. :min="0"
  691. :max="999"
  692. />
  693. <div class="configure-text">限定值</div>
  694. </AFlex>
  695. </AFormItem>
  696. </div>
  697. </AFlex>
  698. </AForm>
  699. <template #footer>
  700. <AFlex justify="flex-end" :gap="16">
  701. <AButton class="default-button" @click="deleteMonitoringPoint">删除</AButton>
  702. <AButton type="primary" @click="saveMonitoringPoint">保存</AButton>
  703. </AFlex>
  704. </template>
  705. </ADrawer>
  706. <ADrawer
  707. class="drawer-monitoring"
  708. width="304"
  709. :open="outdoorOpen"
  710. :closable="false"
  711. :header-style="headerStyle"
  712. :footer-style="footerStyle"
  713. >
  714. <template #title>室外温湿度</template>
  715. <template #extra>
  716. <SvgIcon class="off-icon" @click="offOutdoorDrawer" name="close" />
  717. </template>
  718. <AForm ref="formOutdoorRef" :model="outdooForm" layout="vertical">
  719. <AFormItem label="室外温湿度仪表" name="outsideDevGroupId">
  720. <ASelect
  721. class="input-wdith"
  722. v-model:value="outdooForm.outsideDevGroupId"
  723. :options="twoDeviceGroup"
  724. :field-names="{ label: 'groupName', value: 'id' }"
  725. placeholder="请选择"
  726. @change="(value, option) => adddDeviceGroup(value, option, HumitureType.Outdoor)"
  727. />
  728. </AFormItem>
  729. <AFormItem name="outsideDevId">
  730. <ASelect
  731. class="input-wdith"
  732. v-model:value="outdooForm.outsideDevId"
  733. :options="outdoorDevicesList"
  734. :field-names="{ label: 'deviceName', value: 'id' }"
  735. placeholder="请选择"
  736. @change="(value, option) => adddDevice(value, option, HumitureType.Outdoor)"
  737. />
  738. </AFormItem>
  739. <AFormItem name="outsideTempParamCode">
  740. <ASelect
  741. class="input-wdith"
  742. v-model:value="outdooForm.outsideTempParamCode"
  743. :options="outdoorDeviceParamsList"
  744. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  745. placeholder="请选择"
  746. />
  747. </AFormItem>
  748. <AFormItem name="outsideHumidityParamCode">
  749. <ASelect
  750. class="input-wdith"
  751. v-model:value="outdooForm.outsideHumidityParamCode"
  752. :options="outdoorDeviceParamsList"
  753. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  754. placeholder="请选择"
  755. />
  756. </AFormItem>
  757. <AFormItem name="outsideEnthalpyParamCode">
  758. <ASelect
  759. class="input-wdith"
  760. v-model:value="outdooForm.outsideEnthalpyParamCode"
  761. :options="outdoorDeviceParamsList"
  762. :field-names="{ label: 'deviceParamName', value: 'deviceParamCode' }"
  763. placeholder="请选择"
  764. />
  765. </AFormItem>
  766. </AForm>
  767. <template #footer>
  768. <AFlex justify="flex-end" :gap="16">
  769. <AButton type="primary" @click="saveOutdoo">保存</AButton>
  770. </AFlex>
  771. </template>
  772. </ADrawer>
  773. <AModal
  774. v-model:open="regionNameOpen"
  775. :title="titleRegions ? '添加区域' : '编辑区域'"
  776. :footer="null"
  777. width="460px"
  778. :mask-closable="false"
  779. :keyboard="false"
  780. >
  781. <div class="region-name">区域名</div>
  782. <AInput v-model:value="regionName" placeholder="请输入" />
  783. <AFlex justify="flex-end" class="region-name-top">
  784. <AButton v-if="!titleRegions" class="default-button" @click="regionNameDelete">{{
  785. $t('common.delete')
  786. }}</AButton>
  787. <AButton class="default-button cancel-button" @click="regionNameOpen = false">{{
  788. $t('common.cancel')
  789. }}</AButton>
  790. <AButton type="primary" @click="regionNameOk">{{ $t('common.confirm') }}</AButton>
  791. </AFlex>
  792. </AModal>
  793. </div>
  794. </template>
  795. <style lang="scss" scoped>
  796. .icon-button-margin {
  797. margin: 16px 0 0 16px;
  798. }
  799. .canvas-div-top {
  800. margin-bottom: 16px;
  801. margin-left: 16px;
  802. }
  803. .canvas-div {
  804. width: 820px;
  805. }
  806. .button-icon {
  807. width: 32px;
  808. height: 32px;
  809. margin-left: 12px;
  810. font-size: 16px;
  811. color: var(--antd-color-primary);
  812. cursor: pointer;
  813. background: #fff;
  814. border: 1px solid #32bac0;
  815. border-radius: 4px;
  816. }
  817. .canvas-content {
  818. width: 820px;
  819. height: 660px;
  820. background: #f5f7fa;
  821. border: 1px solid var(--antd-color-primary);
  822. border-radius: 12px;
  823. }
  824. .list-regions {
  825. height: 100%;
  826. margin-right: 16px;
  827. }
  828. .content-monitoring-canvas-left {
  829. width: 260px;
  830. padding-right: 30px;
  831. padding-bottom: 24px;
  832. overflow: hidden;
  833. overflow: hidden auto; /* 隐藏水平滚动条 */ /* 只显示垂直滚动条 */
  834. }
  835. .monitoring-img {
  836. width: 100%;
  837. height: 100%;
  838. }
  839. .content-monitoring-canvas {
  840. height: calc(100% - 45px);
  841. padding-top: 24px;
  842. }
  843. .content-monitoring-top {
  844. height: 40px;
  845. }
  846. .drawer-monitoring .form-ref .ant-form-item .ant-form-item-label > label {
  847. color: #666;
  848. }
  849. .configure-text {
  850. margin-left: 12px;
  851. font-size: 14px;
  852. font-style: normal;
  853. font-weight: 400;
  854. line-height: 22px;
  855. color: #666;
  856. text-align: left;
  857. }
  858. .radio-group {
  859. margin: 8px 0 24px;
  860. }
  861. .region-bottom {
  862. margin-bottom: 8px;
  863. }
  864. .drawer-monitoring .ant-form-item {
  865. margin-bottom: 16px;
  866. }
  867. .input-number-width {
  868. width: 192px;
  869. margin-bottom: 16px;
  870. }
  871. .segmented-monitoring {
  872. width: 196px;
  873. margin-bottom: 24px;
  874. }
  875. .off-icon {
  876. cursor: pointer;
  877. }
  878. .cancel-button {
  879. margin: 0 16px;
  880. }
  881. .region-name-top {
  882. margin-top: 40px;
  883. }
  884. .region-name {
  885. margin-top: 16px;
  886. margin-bottom: 5px;
  887. color: #666;
  888. }
  889. .button-plus {
  890. margin-left: 12px !important;
  891. font-size: 16px;
  892. }
  893. .button-flex {
  894. width: 32px;
  895. height: 32px;
  896. margin-left: 16px;
  897. cursor: pointer;
  898. background: #fff;
  899. border: 1px solid #d9d9d9;
  900. border-radius: 4px;
  901. }
  902. .input-wdith {
  903. width: 256px;
  904. }
  905. .button-monitoring {
  906. margin-left: 16px;
  907. }
  908. .content-monitoring {
  909. height: calc(100vh - 85px);
  910. // min-height: 100%;
  911. padding: 24px 0 0 24px; // 上、右、下、左
  912. margin-top: 16px;
  913. // overflow: hidden;
  914. background-color: #fff;
  915. border-radius: 16px;
  916. }
  917. .select-monitoring {
  918. margin-right: 16px;
  919. margin-left: 32px;
  920. }
  921. .select-width {
  922. width: 192px;
  923. }
  924. .text-top {
  925. font-size: 20px;
  926. font-style: normal;
  927. font-weight: 500;
  928. line-height: 32px;
  929. color: rgb(0 0 0 / 85%);
  930. text-align: left;
  931. }
  932. </style>