管道式消毒机
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.

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