新型管道消毒机前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

590 lines
15 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="seal_test_container">
  3. <div class="left_container">
  4. <div class="title_wrap">
  5. <img class="icon" :src="SealPng" alt="" />
  6. <div class="title">实时压力表</div>
  7. </div>
  8. <div class="echarts_box" id="seal_echarts"></div>
  9. <div class="oper_box">
  10. <div class="air_box">
  11. <p class="box"></p>
  12. <p class="tit">测试前气压</p>
  13. <p class="num">
  14. {{
  15. sealStore.oldAirPressure != null
  16. ? sealStore.oldAirPressure
  17. : '--'
  18. }}KPa
  19. </p>
  20. </div>
  21. <img
  22. class="air_img"
  23. v-if="!sealStore.isStartTest"
  24. @click="newStartTest(1)"
  25. :src="StartTest"
  26. alt=""
  27. />
  28. <img
  29. class="air_img"
  30. @click="newStartTest(2)"
  31. v-if="sealStore.isStartTest"
  32. :src="StopTest"
  33. alt=""
  34. />
  35. <!-- <input
  36. type="number"
  37. placeholder="第一次"
  38. v-model="sleepVal1"
  39. style="width: 100px; height: 100px"
  40. />
  41. <input
  42. type="number"
  43. placeholder="第二次"
  44. v-model="sleepVal2"
  45. style="width: 100px; height: 100px"
  46. /> -->
  47. </div>
  48. </div>
  49. <div class="right_container">
  50. <div class="header">
  51. <div class="left">
  52. <img :src="TestIcon" class="icon" alt="" />
  53. <p class="title">密封测试</p>
  54. </div>
  55. <p class="en">SEAL</p>
  56. </div>
  57. <div class="oper_box">
  58. <div class="emp_box">
  59. <div class="title">测试时间</div>
  60. <div class="num">
  61. {{ resultTime ? resultTime : '未开始' }}
  62. </div>
  63. </div>
  64. <div class="emp_box">
  65. <div class="title">气压差值</div>
  66. <div class="num">
  67. {{
  68. sealStore.differenceValue != null
  69. ? `${sealStore.differenceValue}KPa`
  70. : '未开始'
  71. }}
  72. </div>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. </template>
  78. <script setup>
  79. import * as echarts from 'echarts'
  80. import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
  81. import SealPng from '@/assets/img/seal/seal.png'
  82. import TestIcon from '@/assets/img/seal/test.png'
  83. import StartTest from '@/assets/img/seal/starttest.png'
  84. import StopTest from '@/assets/img/seal/stoptest.png'
  85. import {
  86. someAirSwitchJSON,
  87. airCompressor_setStateJSON,
  88. airCompressorGetPressureDirectIntervalJSON,
  89. airCompressor_channelCtrlJSON,
  90. AirInletProportionalValve_setStateJSON,
  91. AirOutletProportionalValve_setStateJSON,
  92. airCompressorGetPressureDirectJSON,
  93. airCompressorSetValve1JSON,
  94. airCompressorSetValve2JSON,
  95. airCompressorChannelSelectJSON,
  96. AirOutletProportionalValve_getStateJSON,
  97. airInletProportionalValve_getStateJSON,
  98. } from '@/mock/command'
  99. import { useSealStore, useTestStore, useWebSocketStore } from '@/store'
  100. import { storeToRefs } from 'pinia'
  101. const sealStore = useSealStore()
  102. const testStore = useTestStore()
  103. const websocketStore = useWebSocketStore()
  104. const { airInletProportionalInitVal, airOutletProportionalInitVal } =
  105. storeToRefs(sealStore)
  106. const sealCharts = ref(null)
  107. const sealOptions = ref({
  108. series: [
  109. {
  110. type: 'gauge',
  111. min: 0,
  112. max: 800,
  113. progress: {
  114. show: true,
  115. width: 18,
  116. itemStyle: {
  117. color: '#3442aa',
  118. },
  119. },
  120. pointer: {
  121. itemStyle: {
  122. color: '#3442aa',
  123. },
  124. },
  125. axisLine: {
  126. lineStyle: {
  127. width: 18,
  128. },
  129. },
  130. axisTick: {
  131. show: false,
  132. },
  133. splitLine: {
  134. length: 15,
  135. lineStyle: {
  136. width: 2,
  137. color: '#999',
  138. },
  139. },
  140. axisLabel: {
  141. distance: 25,
  142. color: '#999',
  143. fontSize: 20,
  144. },
  145. anchor: {
  146. show: true,
  147. showAbove: true,
  148. size: 25,
  149. itemStyle: {
  150. borderWidth: 10,
  151. borderColor: '#3442aa',
  152. },
  153. },
  154. title: {
  155. show: false,
  156. },
  157. detail: {
  158. valueAnimation: true,
  159. fontSize: 40,
  160. color: '#3442aa',
  161. formatter: '{value} KPa',
  162. offsetCenter: [0, '70%'],
  163. },
  164. data: [
  165. {
  166. value: sealStore.currentAirPressure,
  167. },
  168. ],
  169. },
  170. ],
  171. })
  172. const n_sec = ref(0) // 秒
  173. const n_min = ref(0) // 分
  174. const n_hour = ref(0) // 时
  175. const resultTime = ref('')
  176. const timerStart = ref(null)
  177. const timerReal = () => {
  178. var str_sec = n_sec.value
  179. var str_min = n_min.value
  180. var str_hour = n_hour.value
  181. if (n_sec.value < 10) {
  182. str_sec = '0' + n_sec.value
  183. }
  184. if (n_min.value < 10) {
  185. str_min = '0' + n_min.value
  186. }
  187. if (n_hour.value < 10) {
  188. str_hour = '0' + n_hour.value
  189. }
  190. resultTime.value = str_hour + ':' + str_min + ':' + str_sec
  191. n_sec.value = n_sec.value + 1
  192. if (n_sec.value > 59) {
  193. n_sec.value = 0
  194. n_min.value = n_min.value + 1
  195. }
  196. if (n_min.value > 59) {
  197. n_min.value = 0
  198. n_hour.value = n_hour.value + 1
  199. }
  200. }
  201. watch(
  202. () => sealStore.isStartTest,
  203. (newValue, oldValue) => {
  204. if (!newValue) {
  205. stopTimer()
  206. }
  207. },
  208. )
  209. const stopTimer = () => {
  210. // 改变测试前oldAirPressure为null
  211. sealStore.updateOldAirPressure(null)
  212. // 结束测试时将时间重置null
  213. clearInterval(timerStart.value)
  214. timerStart.value = null
  215. resultTime.value = null
  216. n_sec.value = 0
  217. n_min.value = 0
  218. n_hour.value = 0
  219. sealStore.updateIsStartTest(false)
  220. }
  221. const timerFunc = () => {
  222. timerReal()
  223. timerStart.value = setInterval(() => {
  224. timerReal()
  225. }, 1000)
  226. }
  227. const wait = async ms => {
  228. await new Promise(resolve => setTimeout(resolve, ms))
  229. }
  230. const sleepVal1 = ref(1)
  231. const sleepVal2 = ref(5)
  232. const newStartTest = async flag => {
  233. if (flag == 1) {
  234. // 开始测试
  235. // 启动计时器
  236. timerFunc()
  237. sealStore.updateIsStartTest(true)
  238. // 空压机选通阀切换到通道2(空气)
  239. websocketStore.sendCommandMsg(airCompressorChannelSelectJSON([2]))
  240. // 空压机电子阀1打开 空压机电子阀2打开
  241. websocketStore.sendCommandMsg(airCompressorSetValve1JSON([1]))
  242. websocketStore.sendCommandMsg(airCompressorSetValve2JSON([1]))
  243. // 风机入口比例阀闭合 风机出口比例阀闭合
  244. websocketStore.sendCommandMsg(AirInletProportionalValve_setStateJSON([0]))
  245. websocketStore.sendCommandMsg(AirOutletProportionalValve_setStateJSON([0]))
  246. // 空压机打开
  247. websocketStore.sendCommandMsg(airCompressor_setStateJSON([1]))
  248. // 等待1s
  249. await wait(sleepVal1.value * 1000)
  250. // 空压机关闭
  251. websocketStore.sendCommandMsg(airCompressor_setStateJSON([0]))
  252. // 空压机电子阀1关闭 空压机电子阀2关闭
  253. websocketStore.sendCommandMsg(airCompressorSetValve1JSON([0]))
  254. websocketStore.sendCommandMsg(airCompressorSetValve2JSON([0]))
  255. // 空压机选通阀切换到通道1 (入气口)
  256. websocketStore.sendCommandMsg(airCompressorChannelSelectJSON([1]))
  257. // 等待5s
  258. await wait(sleepVal2.value * 1000)
  259. // 记录当前压力数值作为初始压力值
  260. websocketStore.sendCommandMsg(airCompressorGetPressureDirectJSON)
  261. }
  262. if (flag == 2) {
  263. // 停止测试
  264. /**
  265. * 空压机电子阀1打开
  266. * 空压机电子阀2打开
  267. * 空压机选通阀切换到通道1
  268. * 风机入口比例阀恢复
  269. * 风机出口比例阀恢复
  270. */
  271. websocketStore.sendCommandMsg(airCompressorSetValve1JSON([1]))
  272. websocketStore.sendCommandMsg(airCompressorSetValve2JSON([1]))
  273. websocketStore.sendCommandMsg(airCompressorChannelSelectJSON([1]))
  274. // 数值为刚开始记录的数值
  275. websocketStore.sendCommandMsg(
  276. AirInletProportionalValve_setStateJSON([
  277. airInletProportionalInitVal.value[0],
  278. ]),
  279. )
  280. websocketStore.sendCommandMsg(
  281. AirOutletProportionalValve_setStateJSON([
  282. airOutletProportionalInitVal.value[0],
  283. ]),
  284. )
  285. // 停止计时器
  286. stopTimer()
  287. }
  288. }
  289. const timer = ref(null)
  290. const timerData = ref(null)
  291. onBeforeUnmount(() => {
  292. clearInterval(timerData.value)
  293. clearInterval(timer.value)
  294. clearInterval(timerStart.value)
  295. })
  296. onMounted(() => {
  297. // 需要记录当前的风机入口出口比例阀数值
  298. sealCharts.value = echarts.init(document.getElementById('seal_echarts'))
  299. sealCharts.value.setOption(sealOptions.value)
  300. timer.value = setInterval(() => {
  301. sealCharts.value.setOption({
  302. series: [
  303. {
  304. type: 'gauge',
  305. min: 0,
  306. max: 800,
  307. progress: {
  308. show: true,
  309. width: 18,
  310. itemStyle: {
  311. color: '#3442aa',
  312. },
  313. },
  314. pointer: {
  315. itemStyle: {
  316. color: '#3442aa',
  317. },
  318. },
  319. axisLine: {
  320. lineStyle: {
  321. width: 18,
  322. },
  323. },
  324. axisTick: {
  325. show: false,
  326. },
  327. splitLine: {
  328. length: 15,
  329. lineStyle: {
  330. width: 2,
  331. color: '#999',
  332. },
  333. },
  334. axisLabel: {
  335. distance: 25,
  336. color: '#999',
  337. fontSize: 20,
  338. },
  339. anchor: {
  340. show: true,
  341. showAbove: true,
  342. size: 25,
  343. itemStyle: {
  344. borderWidth: 10,
  345. borderColor: '#3442aa',
  346. },
  347. },
  348. title: {
  349. show: false,
  350. },
  351. detail: {
  352. valueAnimation: true,
  353. fontSize: 40,
  354. color: '#3442aa',
  355. formatter: '{value} KPa',
  356. offsetCenter: [0, '70%'],
  357. },
  358. data: [
  359. {
  360. value: sealStore.currentAirPressure,
  361. },
  362. ],
  363. },
  364. ],
  365. })
  366. }, 1000)
  367. websocketStore.sendCommandMsg(airInletProportionalValve_getStateJSON)
  368. websocketStore.sendCommandMsg(AirOutletProportionalValve_getStateJSON)
  369. timerData.value = setInterval(() => {
  370. websocketStore.sendCommandMsg(airCompressorGetPressureDirectIntervalJSON)
  371. }, 100)
  372. })
  373. </script>
  374. <style lang="scss" scoped>
  375. .seal_test_container {
  376. margin-bottom: 19px;
  377. height: 580px;
  378. box-sizing: border-box;
  379. border-radius: 16px;
  380. display: flex;
  381. align-items: center;
  382. .left_container {
  383. margin-right: 30px;
  384. width: 766px;
  385. height: 580px;
  386. box-sizing: border-box;
  387. border-radius: 16px;
  388. background: #ffffff;
  389. position: relative;
  390. .title_wrap {
  391. position: absolute;
  392. left: 28px;
  393. top: 28px;
  394. width: 141px;
  395. height: 31px;
  396. box-sizing: border-box;
  397. display: flex;
  398. align-items: center;
  399. .title {
  400. font-family: 思源黑体;
  401. font-size: 20px;
  402. font-weight: bold;
  403. line-height: normal;
  404. letter-spacing: 0.02em;
  405. font-feature-settings: 'kern' on;
  406. color: #000000;
  407. margin-left: 9px;
  408. }
  409. .icon {
  410. width: 30px;
  411. height: 30px;
  412. }
  413. }
  414. .oper_box {
  415. position: absolute;
  416. left: 28px;
  417. bottom: 28px;
  418. width: 710px;
  419. height: 110px;
  420. display: flex;
  421. align-items: center;
  422. justify-content: space-between;
  423. .air_img {
  424. width: 341px;
  425. height: 110px;
  426. }
  427. .air_box {
  428. width: 341px;
  429. height: 110px;
  430. border-radius: 16px;
  431. background: #f6f6f6;
  432. display: flex;
  433. align-items: center;
  434. justify-content: center;
  435. .box {
  436. width: 16px;
  437. height: 16px;
  438. background: #4359b9;
  439. margin-right: 6px;
  440. }
  441. .tit {
  442. font-family: 思源黑体;
  443. font-size: 20px;
  444. font-weight: normal;
  445. line-height: normal;
  446. letter-spacing: 0.06em;
  447. font-feature-settings: 'kern' on;
  448. color: #3d3d3d;
  449. margin-right: 8px;
  450. }
  451. .num {
  452. font-family: Source Han Sans;
  453. font-size: 30px;
  454. font-weight: bold;
  455. line-height: normal;
  456. letter-spacing: 0.06em;
  457. font-feature-settings: 'kern' on;
  458. color: #4359b9;
  459. }
  460. }
  461. }
  462. .echarts_box {
  463. height: 580px;
  464. position: absolute;
  465. left: 0;
  466. top: -36px;
  467. width: 100%;
  468. }
  469. }
  470. .right_container {
  471. height: 580px;
  472. box-sizing: border-box;
  473. border-radius: 16px;
  474. background: #ffffff;
  475. flex: 1;
  476. padding: 32px 42px;
  477. .header {
  478. display: flex;
  479. align-items: center;
  480. justify-content: space-between;
  481. box-sizing: border-box;
  482. width: 340px;
  483. height: 45px;
  484. border-radius: 245px;
  485. background: #06518b;
  486. padding-left: 17px;
  487. padding-right: 24px;
  488. margin-bottom: 20px;
  489. .left {
  490. display: flex;
  491. align-items: center;
  492. .icon {
  493. width: 16px;
  494. height: 16px;
  495. }
  496. .title {
  497. font-family: 思源黑体;
  498. font-size: 14px;
  499. font-weight: normal;
  500. line-height: normal;
  501. letter-spacing: 0.1em;
  502. margin-left: 9px;
  503. color: #ffffff;
  504. }
  505. }
  506. .en {
  507. font-family: 思源黑体;
  508. font-size: 12px;
  509. font-weight: normal;
  510. line-height: normal;
  511. letter-spacing: 0.1em;
  512. color: #ffffff;
  513. }
  514. }
  515. .oper_box {
  516. width: 340px;
  517. height: 455px;
  518. border-radius: 16px;
  519. background: #f6f6f6;
  520. box-sizing: border-box;
  521. padding: 20px;
  522. .emp_box {
  523. width: 300px;
  524. height: 198px;
  525. border-radius: 12px;
  526. background: #fff;
  527. margin-bottom: 20px;
  528. box-sizing: border-box;
  529. padding-top: 16px;
  530. padding-left: 27px;
  531. padding-right: 27px;
  532. padding-bottom: 20px;
  533. display: flex;
  534. flex-direction: column;
  535. .title {
  536. font-family: Source Han Sans;
  537. font-size: 16px;
  538. font-weight: 500;
  539. line-height: normal;
  540. letter-spacing: 0.06em;
  541. font-feature-settings: 'kern' on;
  542. color: #06518b;
  543. }
  544. .num {
  545. flex: 1;
  546. display: flex;
  547. align-items: center;
  548. justify-content: center;
  549. font-family: 思源黑体;
  550. font-size: 30px;
  551. font-weight: bold;
  552. line-height: normal;
  553. letter-spacing: 0.1em;
  554. color: #000000;
  555. border-radius: 12px;
  556. background: #fafafa;
  557. box-sizing: border-box;
  558. }
  559. }
  560. .test_png {
  561. width: 300px;
  562. height: 50px;
  563. }
  564. }
  565. }
  566. }
  567. // input[type='number']::-webkit-inner-spin-button,
  568. // input[type='number']::-webkit-outer-spin-button,
  569. // input[type='datetime']::-webkit-inner-spin-button,
  570. // input[type='datetime']::-webkit-outer-spin-button {
  571. // /* 设置箭头按钮的宽度和高度 */
  572. // width: 50px;
  573. // height: 100px;
  574. // }
  575. </style>