supplyAir.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. <template>
  2. <BasicModal
  3. @register="register"
  4. title="按需供风联动"
  5. :maskStyle="{ backgroundColor: '#000000aa', backdropFilter: 'blur(3px)' }"
  6. width="1200px"
  7. v-bind="$attrs"
  8. @ok="onSubmit"
  9. @cancel="onCancel"
  10. :canFullscreen="false"
  11. :destroyOnClose="true"
  12. :footer="null"
  13. :maskClosable="false"
  14. >
  15. <div class="modal-box">
  16. <div class="left-box" style="width: 550px; height: 400px"> </div>
  17. <div class="right-box">
  18. <BarAndLine
  19. class="echarts-line"
  20. xAxisPropType="readTime"
  21. height="400px"
  22. :dataSource="echartsData"
  23. :chartsColumns="chartsColumnList1"
  24. :option="echatsOption1"
  25. />
  26. </div>
  27. </div>
  28. <div class="setting-box">
  29. <div class="right-inputs">
  30. <div class="vent-flex-row">
  31. <div class="input-title">出风口风量(m³/min):</div>
  32. <span class="input-box" size="normal">{{ data.ductOutletAirVolume_merge }}</span>
  33. <div class="input-title">局扇供风量(m³/min):</div>
  34. <span class="input-box" size="normal">{{ data.inletAirVolume_merge }}</span>
  35. <div class="input-title">目标风量(m³/min):</div>
  36. <span class="input-box" size="normal">{{ props.targetVolume }}</span>
  37. <div class="btn btn1" @click="onHide">隐藏</div>
  38. <div class="btn btn1" @click="stop">紧急停止</div>
  39. </div>
  40. </div>
  41. </div>
  42. </BasicModal>
  43. </template>
  44. <script lang="ts" setup>
  45. import { BasicModal, useModalInner } from '/@/components/Modal';
  46. import { ref, onMounted, nextTick, watch } from 'vue';
  47. import echarts from '/@/utils/lib/echarts';
  48. import BarAndLine from '/@/components/chart/BarAndLine.vue';
  49. import { option, chartsColumnList1, echatsOption1 } from '../fanLocal.data';
  50. import { autoAdjust } from '../fanLocal.api';
  51. import { message } from 'ant-design-vue';
  52. const emit = defineEmits(['close', 'register', 'openModal']);
  53. const props = defineProps({
  54. data: {
  55. type: Object,
  56. default: () => {},
  57. },
  58. targetVolume: {
  59. type: Number,
  60. },
  61. fanlocalId: {
  62. type: String,
  63. },
  64. });
  65. // 注册 modal
  66. const [register, { closeModal }] = useModalInner((data) => {
  67. nextTick(() => {
  68. if (option['xAxis']) option['xAxis']['data'] = xData;
  69. option['series'] = yDataList;
  70. initEcharts();
  71. });
  72. });
  73. const ChartRef = ref();
  74. const myChart = ref();
  75. const refresh = ref(true);
  76. const xData: any[] = [];
  77. const yDataList: [] = [];
  78. // const echartsData = ref([]);
  79. // const monitorData = ref({});
  80. const echartsData = ref<Record<string, any>[]>([]);
  81. const monitorData = ref<Record<string, any>>({});
  82. watch(
  83. () => props.data,
  84. (newVal) => {
  85. // 创建新对象,合并 newVal 和 targetVolume
  86. const combinedData = {
  87. inletAirVolume_merge: newVal.inletAirVolume_merge,
  88. targetVolume: props.targetVolume, // 添加目标风量
  89. readTime: newVal.readTime || new Date().toISOString(), // 确保有时间字段
  90. };
  91. monitorData.value = combinedData;
  92. if (echartsData.value.length > 20) {
  93. echartsData.value.shift();
  94. }
  95. echartsData.value = [...echartsData.value, combinedData];
  96. }
  97. );
  98. function onSubmit() {
  99. emit('close');
  100. closeModal();
  101. }
  102. function onCancel() {
  103. //
  104. }
  105. function initEcharts() {
  106. if (ChartRef.value) {
  107. myChart.value = echarts.init(ChartRef.value);
  108. option && myChart.value.setOption(option);
  109. refresh.value = false;
  110. nextTick(() => {
  111. if (option['xAxis']) option['xAxis']['data'] = xData;
  112. option['series'] = yDataList;
  113. initEcharts();
  114. });
  115. });
  116. const ChartRef = ref();
  117. const myChart = ref();
  118. const refresh = ref(true);
  119. const xData: any[] = [];
  120. const yDataList: [] = [];
  121. // const echartsData = ref([]);
  122. // const monitorData = ref({});
  123. const echartsData = ref<Record<string, any>[]>([]);
  124. const monitorData = ref<Record<string, any>>({});
  125. watch(
  126. () => props.data,
  127. (newVal) => {
  128. // 创建新对象,合并 newVal 和 targetVolume
  129. const combinedData = {
  130. inletAirVolume_merge: newVal.inletAirVolume_merge,
  131. targetVolume: props.targetVolume, // 添加目标风量
  132. readTime: newVal.readTime || new Date().toISOString(), // 确保有时间字段
  133. };
  134. monitorData.value = combinedData;
  135. if (echartsData.value.length > 20) {
  136. echartsData.value.shift();
  137. }
  138. echartsData.value = [...echartsData.value, combinedData];
  139. }
  140. );
  141. function onSubmit() {
  142. emit('close');
  143. closeModal();
  144. }
  145. }
  146. function onHide() {
  147. closeModal();
  148. }
  149. function stop() {
  150. const params = { auto: 0, fanlocalId: props.fanlocalId };
  151. autoAdjust(params)
  152. .then(() => {
  153. message.success('指令已下发成功!');
  154. })
  155. .catch(() => {
  156. message.error('指令下发失败');
  157. });
  158. }
  159. onMounted(() => {
  160. // initEcharts();
  161. });
  162. </script>
  163. <style scoped lang="less">
  164. .modal-box {
  165. display: flex;
  166. flex-direction: row;
  167. background-color: #ffffff05;
  168. padding: 10px 8px 0 8px;
  169. border: 1px solid #00d8ff22;
  170. position: relative;
  171. // min-height: 600px;
  172. .left-box {
  173. flex: 1; /* 占据 3/4 的空间 */
  174. background-image: url(../../../../../assets/images/supplyAir.svg);
  175. background-repeat: no-repeat;
  176. background-size: contain; /* 确保背景图片完整显示 */
  177. background-position: center; /* 确保背景图片居中 */
  178. }
  179. .right-box {
  180. flex: 1; /* 占据 3/4 的空间 */
  181. height: 400px;
  182. width: 100%;
  183. }
  184. }
  185. .setting-box {
  186. width: 100%;
  187. height: 70px;
  188. margin: 10px 0;
  189. background-color: #ffffff05;
  190. border: 1px solid #00d8ff22;
  191. display: flex;
  192. align-items: center;
  193. justify-content: space-between;
  194. .right-inputs {
  195. width: 100%;
  196. display: flex;
  197. height: 40px;
  198. margin: 0 10px;
  199. justify-content: space-between;
  200. }
  201. .left-buttons {
  202. display: flex;
  203. height: 40px;
  204. .btn {
  205. margin: 0 10px;
  206. }
  207. }
  208. .border-clip {
  209. width: 1px;
  210. height: 25px;
  211. border-right: 1px solid #8b8b8b77;
  212. }
  213. .input-title {
  214. max-width: 150px;
  215. }
  216. .input-box {
  217. width: 120px !important;
  218. background: transparent !important;
  219. border-color: #00d8ff44 !important;
  220. margin-right: 20px;
  221. color: #fff !important;
  222. }
  223. .btn {
  224. padding: 8px 20px;
  225. margin: 10px;
  226. position: relative;
  227. // min-height: 600px;
  228. .left-box {
  229. flex: 1; /* 占据 3/4 的空间 */
  230. background-image: url(../../../../../assets/images/supplyAir.svg);
  231. background-repeat: no-repeat;
  232. background-size: contain; /* 确保背景图片完整显示 */
  233. background-position: center; /* 确保背景图片居中 */
  234. }
  235. .right-box {
  236. flex: 1; /* 占据 3/4 的空间 */
  237. height: 400px;
  238. width: 100%;
  239. }
  240. }
  241. .setting-box {
  242. width: 1570px;
  243. height: 70px;
  244. margin: 10px 0;
  245. background-color: #ffffff05;
  246. border: 1px solid #00d8ff22;
  247. display: flex;
  248. align-items: center;
  249. justify-content: space-between;
  250. .right-inputs {
  251. width: 100%;
  252. display: flex;
  253. height: 40px;
  254. margin: 0 10px;
  255. justify-content: space-between;
  256. }
  257. .left-buttons {
  258. display: flex;
  259. height: 40px;
  260. .btn {
  261. margin: 0 10px;
  262. }
  263. }
  264. .border-clip {
  265. width: 1px;
  266. height: 25px;
  267. border-right: 1px solid #8b8b8b77;
  268. }
  269. .input-title {
  270. max-width: 150px;
  271. }
  272. .input-box {
  273. width: 220px !important;
  274. background: transparent !important;
  275. border-color: #00d8ff44 !important;
  276. margin-right: 20px;
  277. color: #fff !important;
  278. }
  279. .btn {
  280. padding: 8px 20px;
  281. position: relative;
  282. border-radius: 2px;
  283. color: #fff;
  284. width: fit-content;
  285. cursor: pointer;
  286. &::before {
  287. position: absolute;
  288. display: block;
  289. content: '';
  290. width: calc(100% - 4px);
  291. height: calc(100% - 4px);
  292. top: 2px;
  293. left: 2px;
  294. border-radius: 2px;
  295. z-index: -1;
  296. }
  297. }
  298. .btn1 {
  299. border: 1px solid #5cfaff;
  300. &::before {
  301. background-image: linear-gradient(#2effee92, #0cb1d592);
  302. }
  303. &:hover {
  304. border: 1px solid #5cfaffaa;
  305. &::before {
  306. background-image: linear-gradient(#2effee72, #0cb1d572);
  307. }
  308. }
  309. }
  310. }
  311. @keyframes open {
  312. 0% {
  313. height: 0px;
  314. }
  315. 100% {
  316. height: fit-content;
  317. }
  318. }
  319. @keyframes close {
  320. 0% {
  321. height: fit-content;
  322. }
  323. 100% {
  324. height: 0px;
  325. }
  326. }
  327. :deep(.zxm-divider-inner-text) {
  328. color: #cacaca88 !important;
  329. }
  330. :deep(.zxm-form-item) {
  331. margin-bottom: 10px;
  332. }
  333. </style>