nitrogenHome.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. <template>
  2. <div id="nitrogenCss3D" class="threejs-Object-CSS"
  3. style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 2; top: 0px; left: 0px">
  4. <a-spin :spinning="loading" />
  5. <div v-for="groupNum in monitorDataGroupNum" :key="groupNum" class="modal-monitor">
  6. <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
  7. <div class="title">{{ groupNum }}号制氮机 </div>
  8. <div class="monitor-item">
  9. <span class="monitor-title">注氮压力:</span>
  10. <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['nitrogenPressure'] ?
  11. monitorData[groupNum - 1]['nitrogenPressure'] : '-' }}</span><span class="unit">Mpa</span></span>
  12. </div>
  13. <div class="monitor-item">
  14. <span class="monitor-title">氮气实时流量:</span>
  15. <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['instantaneousFlow'] ?
  16. monitorData[groupNum - 1]['instantaneousFlow'] : '-' }}</span><span class="unit">m³/h</span></span>
  17. </div>
  18. <div class="monitor-item">
  19. <span class="monitor-title">氮气浓度:</span>
  20. <span class="monitor-val"><span class="val">{{ monitorData[groupNum - 1]['nitrogenContent'] ?
  21. monitorData[groupNum - 1]['nitrogenContent'] : '-' }}</span><span class="unit">%</span></span>
  22. </div>
  23. <div class="signal-item">
  24. <div class="signal"><span class="monitor-title">运行信号</span><span
  25. :class="{ 'signal-round': true, 'signal-round-run': monitorData[groupNum - 1]['compressRunSigF1'], 'signal-round-gry': !monitorData[groupNum - 1]['compressRunSigF1'] }"></span>
  26. </div>
  27. <div class="signal"><span class="monitor-title">加载信号</span><span
  28. :class="{ 'signal-round': true, 'signal-round-run': monitorData[groupNum - 1]['compressLoadSigF1'], 'signal-round-gry': !monitorData[groupNum - 1]['compressLoadSigF1'] }"></span>
  29. </div>
  30. </div>
  31. </fourBorderBg>
  32. </div>
  33. </div>
  34. <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
  35. <div class="nitrogen-home">
  36. <div class="nitrogen-container">
  37. <div class="top-box">
  38. <!-- 左边监测数据 -->
  39. <div class="lr-box left-box">
  40. <div class="item item-l" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
  41. <ventBox1>
  42. <template #title>
  43. <div>{{ groupNum }}号制氮机组</div>
  44. </template>
  45. <template #container>
  46. <div class="monitor-box">
  47. <div class="parameter-title group-parameter-title"><SvgIcon class="icon" size="38" name="device-group-paramer"/><span>机组参数</span></div>
  48. <div class="state-item" v-for="(data, index) in groupParameterData" :key="index">
  49. <div class="item-col">
  50. <span class="state-title">{{ Object.values(data)[0] }} :</span>
  51. <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
  52. >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
  53. </div>
  54. <div class="item-col" v-if="Object.keys(data)[1]">
  55. <span class="state-title">{{ Object.values(data)[1] }} :</span>
  56. <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
  57. >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
  58. </div>
  59. </div>
  60. </div>
  61. <div class="monitor-box">
  62. <div class="parameter-title device-parameter-title"><SvgIcon class="icon" size="32" name="device-paramer"/><span>电机数据</span></div>
  63. <div class="state-item" v-for="(data, index) in deviceParameterData" :key="index">
  64. <div class="item-col">
  65. <span class="state-title">{{ Object.values(data)[0] }} :</span>
  66. <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[0]])
  67. >= 0 ? monitorData[groupNum - 1][Object.keys(data)[0]] : '-' }}</span>
  68. </div>
  69. <div class="item-col" v-if="Object.keys(data)[1]">
  70. <span class="state-title">{{ Object.values(data)[1] }} :</span>
  71. <span class="state-val">{{ (monitorData.length > 0 && monitorData[groupNum - 1][Object.keys(data)[1]])
  72. >= 0 ? monitorData[groupNum - 1][Object.keys(data)[1]] : '-' }}</span>
  73. </div>
  74. </div>
  75. </div>
  76. </template>
  77. </ventBox1>
  78. </div>
  79. </div>
  80. <!-- 右边控制状态 -->
  81. <div class="lr-box right-box">
  82. <ventBox1>
  83. <template #title>
  84. <div>远程控制</div>
  85. </template>
  86. <template #container>
  87. <div class="control-group">
  88. <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
  89. <div class="control-item-title">{{ zdjs[groupNum - 1] }}</div>
  90. <div class="control-item-state">
  91. <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small" checked-children="开启"
  92. un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
  93. @change="handlerDevice(airCompressorState[groupNum - 1])">
  94. </a-switch>
  95. </div>
  96. </div>
  97. <div class="control-item" v-for="groupNum in monitorDataGroupNum" :key="groupNum">
  98. <div class="control-item-title">{{ kyjs[groupNum - 1] }}</div>
  99. <div class="control-item-state">
  100. <a-switch v-model="airCompressorState[groupNum - 1][`compressRunSigF1`]" size="small" checked-children="开启"
  101. un-checked-children="关闭" :disabled="airCompressorState[groupNum - 1][`controlModel`]"
  102. @change="handlerDevice(airCompressorState[groupNum - 1])">
  103. </a-switch>
  104. </div>
  105. </div>
  106. <div class="control-item">
  107. <div class="control-item-title">是否开启联动</div>
  108. <div class="control-item-state">
  109. <a-radio v-model:checked="isLink">开启</a-radio>
  110. </div>
  111. </div>
  112. </div>
  113. </template>
  114. </ventBox1>
  115. <ventBox1 class="vent-margin-t-10">
  116. <template #title>
  117. <div>设备实时监测曲线</div>
  118. </template>
  119. <template #container >
  120. <BarAndLineCustom xAxisPropType="readTime" :chartData="monitorData" height="240px" :propTypeArr="['flowRate']" :option="zhudanOption" />
  121. </template>
  122. </ventBox1>
  123. <div class="vent-margin-t-10">
  124. <LivePlayer id="fm-player1" style="height: 250px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
  125. </div>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. </template>
  131. <script lang="ts" setup name="nitrogenHome">
  132. import { onMounted, onUnmounted, ref, watch, reactive } from 'vue'
  133. import ventBox1 from '/@/components/vent/ventBox1.vue'
  134. import fourBorderBg from '../../../comment/components/fourBorderBg.vue'
  135. import { mountedThree, destroy } from '../nitrogen.threejs'
  136. import { list } from '../nitrogen.api'
  137. import { SvgIcon } from '/@/components/Icon'
  138. import LivePlayer from '@liveqing/liveplayer-v3';
  139. import BarAndLineCustom from '/@/components/chart/BarAndLineCustom.vue';
  140. import { zhudanOption } from '../nitrogen.data.ts'
  141. const loading = ref(true)
  142. const isLink = ref(true)
  143. const zdjs = ['1号制氮机', '2号制氮机', '3号制氮机', '4号制氮机'];
  144. const kyjs = ['1号空压机', '1号空压机', '1号空压机', '1号空压机'];
  145. const flvURL1 = () => {
  146. return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
  147. // return ''
  148. };
  149. const monitorDataGroupNum = ref(0);
  150. const airCompressorState = reactive([
  151. {
  152. id: '',
  153. compressRunSigF1: false,
  154. controlModel: false
  155. },
  156. {
  157. id: '',
  158. compressRunSigF1: false,
  159. controlModel: false
  160. },
  161. {
  162. id: '',
  163. compressRunSigF1: false,
  164. controlModel: false
  165. },
  166. {
  167. id: '',
  168. compressRunSigF1: false,
  169. controlModel: false
  170. }
  171. ]);
  172. const groupParameterData = [
  173. {
  174. cumulativeFlow: '累计流量(m³)',
  175. centerTemperature: '加热器中心温度',
  176. },
  177. {
  178. outletTemperature: '加热器出口温度',
  179. },
  180. ];
  181. const deviceParameterData = [
  182. {
  183. Ia: 'A项电流(A)',
  184. Ib: 'B项电流(A)',
  185. },
  186. {
  187. Ic: 'c项电流(A)',
  188. Vab: 'AB项间电压(V)',
  189. },
  190. {
  191. Vac: 'AC项间电压(V)',
  192. Vbc: 'BC项间电压(V)',
  193. },
  194. ];
  195. const monitorData = ref(new Array(3).fill({
  196. strName: '空压机',
  197. cumulativeFlow: '-',
  198. centerTemperature: '-',
  199. outletTemperature: '-',
  200. Ia: '-',
  201. Ib: '-',
  202. Ic: '-',
  203. Vab: '-',
  204. Vac: '-',
  205. Vbc: '-',
  206. compressGroupName: '',
  207. compressExhaustPressF1: '-',
  208. compressSeparatePressF1: '-',
  209. compressHostTempF1: '-',
  210. compressCrewTempF1: '-',
  211. compressRunTimeF1: '-',
  212. controlModel: 'LOC'
  213. }));
  214. // https获取监测数据
  215. let timer: null | NodeJS.Timeout = null;
  216. async function getMonitor(flag?) {
  217. if (Object.prototype.toString.call(timer) === '[object Null]') {
  218. timer = await setTimeout(async () => {
  219. await getDataSource();
  220. if (timer) {
  221. timer = null;
  222. }
  223. await getMonitor();
  224. }, flag ? 0 : 1000);
  225. }
  226. };
  227. async function getDataSource() {
  228. const res = await list({ devicetype: 'nitrogen', pagetype: 'normal' });
  229. const dataSource = res.msgTxt[0].datalist || [];
  230. monitorData.value = dataSource.filter((data) => {
  231. const item = data.readData;
  232. Object.assign(data, item);
  233. return item
  234. });
  235. monitorDataGroupNum.value = monitorData.value.length
  236. loading.value = false
  237. };
  238. function handlerDevice(data) {
  239. // if (data.length < 1) return
  240. // handleAirCompressor({ id: data.id, compressRunF1: data.compressRunSigF1 }).then(res => {
  241. // if (res.success) {
  242. // message.success('操作成功')
  243. // } else {
  244. // message.warning(data.msg)
  245. // }
  246. // })
  247. };
  248. function resetDevice(data) {
  249. }
  250. function handlerControlModel(data) {
  251. }
  252. watch(monitorDataGroupNum, (newVal) => {
  253. if (newVal) {
  254. destroy()
  255. mountedThree(newVal)
  256. }
  257. })
  258. onMounted(async () => {
  259. await getMonitor(true)
  260. })
  261. onUnmounted(() => {
  262. destroy();
  263. if (timer) {
  264. clearTimeout(timer);
  265. timer = undefined;
  266. }
  267. });
  268. </script>
  269. <style lang="less" scoped>
  270. @ventSpace: zxm;
  271. .nitrogen-box {
  272. width: 100%;
  273. height: 100%;
  274. display: flex;
  275. justify-content: center;
  276. }
  277. #nitrogenCss3D {
  278. .modal-monitor {
  279. width: 200px;
  280. position: absolute;
  281. left: 0px;
  282. top: 0px;
  283. }
  284. &:deep(.win) {
  285. margin: 0 !important;
  286. background: #00000044;
  287. }
  288. }
  289. .nitrogen-home {
  290. width: 100%;
  291. height: 100%;
  292. position: fixed;
  293. z-index: 99;
  294. display: flex;
  295. flex-direction: column;
  296. justify-content: center;
  297. align-items: center;
  298. pointer-events: none;
  299. top: 60px;
  300. .nitrogen-container {
  301. width: 100%;
  302. height: calc(100%);
  303. display: flex;
  304. justify-content: space-between;
  305. margin-bottom: 100px;
  306. .top-box {
  307. width: 100%;
  308. padding: 10px;
  309. overflow: hidden;
  310. display: flex;
  311. justify-content: space-between;
  312. .lr-box {
  313. height: fit-content;
  314. display: flex;
  315. flex-direction: column;
  316. position: relative;
  317. overflow: hidden;
  318. z-index: 9999;
  319. pointer-events: auto;
  320. }
  321. .item {
  322. width: 335px;
  323. height: auto;
  324. position: relative;
  325. border-radius: 5px;
  326. margin-top: 10px;
  327. margin-bottom: 0px;
  328. pointer-events: auto;
  329. color: #fff;
  330. overflow: hidden;
  331. &:first-child{
  332. margin-top: 0px;
  333. }
  334. .base-title {
  335. color: #fff;
  336. margin-bottom: 8px;
  337. padding-left: 10px;
  338. position: relative;
  339. font-size: 16px;
  340. &::after{
  341. content: '';
  342. position: absolute;
  343. display: block;
  344. width: 4px;
  345. height: 12px;
  346. top: 7px;
  347. left: 0px;
  348. background: #45d3fd;
  349. border-radius: 4px;
  350. }
  351. }
  352. .state-item {
  353. display: flex;
  354. flex-direction: row;
  355. padding: 5px;
  356. .item-col {
  357. width: calc(50% - 5px);
  358. display: flex;
  359. justify-content: center;
  360. align-items: center;
  361. padding-right: 4px;
  362. background-image: linear-gradient(to right, #39A3FF00, #39A3FF10);
  363. &:first-child{
  364. margin-right: 10px;
  365. }
  366. .state-title {
  367. color: #ffffffcc;
  368. flex: 9;
  369. font-size: 14px;
  370. }
  371. .state-val {
  372. flex: 1;
  373. color: #00eefffe;
  374. margin-right: 5px;
  375. text-align: right;
  376. font-size: 14px;
  377. }
  378. }
  379. }
  380. .signal-box {
  381. margin: 5px 0;
  382. display: flex;
  383. align-items: center;
  384. .signal-title {
  385. color: #7AF5FF;
  386. margin: 0 5px;
  387. }
  388. &:last-child {
  389. margin-right: 0px;
  390. }
  391. }
  392. .list-item {
  393. padding: 0 10px;
  394. display: flex;
  395. justify-content: space-between;
  396. align-items: center;
  397. .item-data-key {
  398. color: #ffffff99;
  399. }
  400. }
  401. .item-data-box {
  402. color: #fff;
  403. .state-icon {
  404. display: inline-block;
  405. width: 12px;
  406. height: 12px;
  407. border-radius: 12px;
  408. }
  409. .open {
  410. border: 5px solid #133a56;
  411. background: #4ecb73;
  412. }
  413. .close {
  414. border: 5px solid #192961;
  415. background: #6d7898;
  416. }
  417. }
  418. }
  419. .item-l {
  420. width: 100%;
  421. .monitor-box {
  422. width: 100%;
  423. .parameter-title{
  424. position: relative;
  425. width: 100%;
  426. height: 14px;
  427. margin-top: 10px;
  428. .icon, span{
  429. position: absolute;
  430. top: -10px;
  431. }
  432. }
  433. .group-parameter-title{
  434. background-image: linear-gradient(to right, #39a3ff50, #39a3ff00);
  435. .icon{
  436. left: -12px;
  437. top: -17px;
  438. }
  439. span{
  440. left: 18px;
  441. }
  442. .item-col{
  443. background-image: linear-gradient(to right, #39A3FF00, #39A3FF10);
  444. }
  445. }
  446. .device-parameter-title{
  447. background-image: linear-gradient(to right, #3df6ff40, #3df6ff00);
  448. .icon{
  449. left: -10px;
  450. top: -14px;
  451. }
  452. span{
  453. left: 18px;
  454. }
  455. .item-col{
  456. background-image: linear-gradient(to right, #3df6ff10, #3df6ff00);
  457. }
  458. }
  459. }
  460. }
  461. .right-box {
  462. width: 330px;
  463. .control-group{
  464. display: flex;
  465. // justify-content: space-around;
  466. flex-wrap: wrap;
  467. .control-item {
  468. display: flex;
  469. flex-direction: column;
  470. justify-content: center;
  471. align-items: center;
  472. padding: 0 4px;
  473. .control-item-title{
  474. color: #A6DCE9;
  475. position: relative;
  476. top: 5px;
  477. }
  478. .control-item-state{
  479. width: 94px;
  480. height: 47px;
  481. background: url('/@/assets/images/vent/control-switch-bg.png');
  482. display: flex;
  483. justify-content: center;
  484. align-items: center;
  485. color: #fff;
  486. }
  487. .button-box {
  488. position: relative;
  489. padding: 5px;
  490. border: 1px transparent solid;
  491. background-clip: border-box;
  492. border-radius: 5px;
  493. margin-left: 8px;
  494. }
  495. .a-button {
  496. pointer-events: auto;
  497. }
  498. &::v-deep .a-button--mini {
  499. padding: 6px 10px;
  500. }
  501. &::v-deep .a-button--mini.is-round {
  502. padding: 6px 10px;
  503. }
  504. }
  505. }
  506. }
  507. .left-box {
  508. width: 365px;
  509. }
  510. }
  511. &:deep(.win) {
  512. width: 100%;
  513. margin: 0 !important;
  514. }
  515. }
  516. }
  517. &:deep(.main) {
  518. .title {
  519. height: 34px;
  520. text-align: center;
  521. font-weight: 600;
  522. color: #7AF5FF;
  523. // background-image: url('../../../assets/img/yfj/light.png');
  524. background-repeat: no-repeat;
  525. background-position-x: center;
  526. background-position-y: 100%;
  527. background-size: 80%;
  528. font-size: 16px;
  529. }
  530. .monitor-item {
  531. width: 200px;
  532. display: flex;
  533. flex-direction: row;
  534. width: auto;
  535. margin-bottom: 3px;
  536. .monitor-val {
  537. color: #ffb700;
  538. display: flex;
  539. width: auto;
  540. .val {
  541. width: 80px;
  542. font-size: 14px;
  543. }
  544. .unit {
  545. color: #ffffffbb;
  546. font-size: 14px;
  547. }
  548. }
  549. }
  550. .monitor-title {
  551. width: 100px;
  552. color: #7AF5FF;
  553. font-weight: 400;
  554. font-size: 14px;
  555. }
  556. .signal-item {
  557. display: flex;
  558. justify-content: space-between;
  559. // margin-bottom: 5px;
  560. .signal-round {
  561. display: inline-block;
  562. width: 8px;
  563. height: 8px;
  564. border-radius: 50%;
  565. margin: 0 10px;
  566. position: relative;
  567. &::after {
  568. display: block;
  569. content: '';
  570. position: absolute;
  571. width: 12px;
  572. height: 12px;
  573. top: -2px;
  574. left: -2px;
  575. border-radius: 50%;
  576. }
  577. }
  578. .signal-round-gry {
  579. background-color: #858585;
  580. &::after {
  581. background-color: #85858544;
  582. box-shadow: 0 0 1px 1px #85858599;
  583. }
  584. }
  585. .signal-round-run {
  586. background-color: #67FC00;
  587. &::after {
  588. background-color: #67FC0044;
  589. box-shadow: 0 0 1px 1px #c6ff77;
  590. }
  591. }
  592. .signal-round-warning {
  593. background-color: #E9170B;
  594. &::after {
  595. background-color: #E9170B44;
  596. box-shadow: 0 0 1px 1px #E9170B;
  597. }
  598. }
  599. }
  600. }
  601. :deep(.zxm-radio-wrapper){
  602. color: #fff !important;
  603. }
  604. </style>