gasPumpHome.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <!-- <div id="FlowSensor" class="FlowSensor-box" style="position: absolute;" v-if="selectData.FlowSensor_InputFlux">
  3. <div class="elementContent" >
  4. <p style="color: #50c8fc;"><span class="data-title">抽采泵流量(m³):</span>{{ formatNum(selectData.FlowSensor_InputFlux) }}</p>
  5. </div>
  6. </div> -->
  7. <div class="monitor-container">
  8. <div class="lr left-box">
  9. <div class="left-container">
  10. <div class="monitor-box">
  11. <ventBox1>
  12. <template #title>
  13. <div>抽采泵</div>
  14. </template>
  15. <template #container>
  16. <div v-for="key in 2" :key="key">
  17. <div class="parameter-title group-parameter-title"><SvgIcon class="icon" size="14" name="pulp-title"/><span>{{ key }}#抽采泵</span></div>
  18. <div class="input-box">
  19. <div v-for="(item, index) in pumpMonitorData" class="input-item" :key="index">
  20. <template v-if="selectData[item.code.replace('CentrifugalPump', `CentrifugalPump${key}`)] != undefined">
  21. <div class="title">{{ item.title }}:</div>
  22. <template v-if="item.type !== 'sign'">
  23. <div class="value">{{ selectData && selectData[item.code.replace('CentrifugalPump', `CentrifugalPump${key}`)] ? formatNum(selectData[item.code.replace('CentrifugalPump', `CentrifugalPump${key}`)]) : '-' }}</div>
  24. </template>
  25. <template v-else>
  26. <div class="value">
  27. <span :class="{ 'signal-round': true, 'signal-round-run': selectData[item.code.replace('CentrifugalPump', `CentrifugalPump${key}`)] == '1', 'signal-round-gry': selectData[item.code.replace('CentrifugalPump', `CentrifugalPump${key}`)] == '0' }"></span>
  28. </div>
  29. </template>
  30. </template>
  31. </div>
  32. </div>
  33. </div>
  34. </template>
  35. </ventBox1>
  36. <ventBox1 class="vent-margin-t-10">
  37. <template #title>
  38. <div>注水泵</div>
  39. </template>
  40. <template #container>
  41. <div v-for="key in 2" :key="key">
  42. <div class="parameter-title group-parameter-title"><SvgIcon class="icon" size="14" name="pulp-title"/><span>{{ key }}#注水泵</span></div>
  43. <div class="input-box">
  44. <div v-for="(item, index) in waterPumpData" class="input-item" :key="index">
  45. <template v-if="selectData[item.code.replace('WaterfloodPump', `WaterfloodPump${key}`)] != undefined">
  46. <div class="title">{{ item.title }}:</div>
  47. <template v-if="item.type !== 'sign'">
  48. <div class="value">{{ selectData && selectData[item.code.replace('WaterfloodPump', `WaterfloodPump${key}`)] ? formatNum(selectData[item.code.replace('WaterfloodPump', `WaterfloodPump${key}`)]) : '-' }}</div>
  49. </template>
  50. <template v-else>
  51. <div class="value">
  52. <span :class="{ 'signal-round': true, 'signal-round-run': selectData[item.code.replace('WaterfloodPump', `WaterfloodPump${key}`)], 'signal-round-gry': selectData[item.code.replace('WaterfloodPump', `WaterfloodPump${key}`)]=='0' }"></span>
  53. </div>
  54. </template>
  55. </template>
  56. </div>
  57. </div>
  58. </div>
  59. </template>
  60. </ventBox1>
  61. <ventBox1 class="vent-margin-t-10">
  62. <template #title>
  63. <div>排水泵</div>
  64. </template>
  65. <template #container>
  66. <div v-for="key in 2" :key="key">
  67. <div class="parameter-title group-parameter-title"><SvgIcon class="icon" size="14" name="pulp-title"/><span>{{ key }}#排水泵</span></div>
  68. <div class="input-box">
  69. <div v-for="(item, index) in dewateringPumpData" class="input-item" :key="index">
  70. <template v-if="selectData[item.code.replace('DewateringPump', `DewateringPump${key}`)] != undefined">
  71. <div class="title">{{ item.title }}:</div>
  72. <template v-if="item.type !== 'sign'">
  73. <div class="value">{{ selectData && selectData[item.code.replace('DewateringPump', `DewateringPump${key}`)] ? formatNum(selectData[item.code.replace('DewateringPump', `DewateringPump${key}`)]) : '-' }}</div>
  74. </template>
  75. <template v-else>
  76. <div class="value">
  77. <span :class="{ 'signal-round': true, 'signal-round-run': selectData[item.code.replace('DewateringPump', `DewateringPump${key}`)], 'signal-round-gry': selectData[item.code.replace('DewateringPump', `DewateringPump${key}`)] == '0' }"></span>
  78. </div>
  79. </template>
  80. </template>
  81. </div>
  82. </div>
  83. </div>
  84. </template>
  85. </ventBox1>
  86. </div>
  87. </div>
  88. </div>
  89. <div class="lr right-box">
  90. <div class="item-box sensor-container">
  91. <ventBox1 class="vent-margin-t-10">
  92. <template #title>
  93. <div>泵站远程集中控制</div>
  94. </template>
  95. <template #container>
  96. <div class="top-btn">
  97. <div class="btn-group">
  98. <a-button class="btn-item" type="primary" @click="handlerFn('zfw')">总复位</a-button>
  99. <a-button class="btn-item" type="default" disabled @click="handlerFn('change')">一键切换</a-button>
  100. </div>
  101. <div class="btn-group">
  102. <a-button style="width: calc(100% - 16px); padding: 0 8px;" type="primary" @click="openModal">瓦斯泵控制</a-button>
  103. </div>
  104. <div>
  105. <div class="control-item">
  106. <div class="control-title">控制模式:</div>
  107. <a-radio-group v-model:value="selectData['ykjdqh']" @change="changeCtr">
  108. <a-radio :value="'0'">就地</a-radio>
  109. <a-radio :value="'1'">远程</a-radio>
  110. </a-radio-group>
  111. </div>
  112. <div class="control-item">
  113. <div class="control-title">检修模式:</div>
  114. <a-radio-group v-model:value="selectData['jxmsqh']" @change="changeMode">
  115. <a-radio :value="'0'">关闭</a-radio>
  116. <a-radio :value="'1'">开启</a-radio>
  117. </a-radio-group>
  118. </div>
  119. </div>
  120. </div>
  121. </template>
  122. </ventBox1>
  123. <ventBox1 class="vent-margin-t-10">
  124. <template #title>
  125. <div>阀门运行状态</div>
  126. </template>
  127. <template #container>
  128. <div class="state-header">
  129. <div class="header-item" v-for="(header, index) in stateHeader" :key="index">{{ header }}</div>
  130. </div>
  131. <div class="">
  132. <div v-for="key in 2" :key="key">
  133. <div class="device-row" v-for="(valveType, index) in valveCtrlType" :key="index">
  134. <div class="state" >#{{ key }}{{ valveType.title }} </div>
  135. <div class="state" v-for="(state, i) in valveState" :key="i" >
  136. <span v-if="state.code == '_CtrlMode'">{{ selectData[`CentrifugalPump${key}_${valveType.code}${state.code}`] == '1' ? '控制' : '-' }}</span>
  137. <span v-else :class="{ 'signal-round': true, 'signal-round-run': selectData[`CentrifugalPump${key}_${valveType.code}${state.code}`] == '1', 'signal-round-gry': selectData[`CentrifugalPump${key}_${valveType.code}${state.code}`] == '0' }"></span>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </template>
  143. </ventBox1>
  144. </div>
  145. <!-- <div class="item-box" >
  146. <LivePlayer id="fm-player1" style="height: 250px;" ref="player1" :videoUrl="flvURL1()" muted live loading controls />
  147. </div> -->
  148. </div>
  149. </div>
  150. <DetailModal @register="register" :device-type="deviceType" :device-id="deviceId"/>
  151. <PasswordModal :modal-is-show="passwordModalIsShow" modal-title="密码检验" :modal-type="handlerType" @handle-ok="handleOK"
  152. @handle-cancel="handleCancel"/>
  153. </template>
  154. <script setup lang="ts">
  155. import { onBeforeMount, ref, onMounted, onUnmounted, reactive, defineProps, watch, inject } from 'vue';
  156. import ventBox1 from '/@/components/vent/ventBox1.vue'
  157. import { setModelType } from '../gasPump.threejs';
  158. import { stateHeader, valveState, pumpMonitorData, waterPumpData, dewateringPumpData, pumpCtrlType, valveCtrlType, valveCtrl, PumpCtrlItems, pumpCtrl } from '../gasPump.data'
  159. import { list } from '../gasPump.api';
  160. import { SvgIcon } from '/@/components/Icon'
  161. import { formatNum } from '/@/utils/ventutil'
  162. import DetailModal from './DetailModal.vue'
  163. import { useModal } from '/@/components/Modal';
  164. import { deviceControlApi } from '/@/api/vent/index';
  165. import PasswordModal from '../../comment/components/PasswordModal.vue'
  166. import { message } from 'ant-design-vue';
  167. const globalConfig = inject('globalConfig');
  168. const props = defineProps({
  169. deviceId: {
  170. type: String,
  171. require: true
  172. },
  173. deviceType: {
  174. type: String,
  175. require: true
  176. }
  177. })
  178. const [register, { openModal }] = useModal()
  179. const loading = ref(false);
  180. const tabActiveKey = ref(1)
  181. const passwordModalIsShow = ref(false)
  182. const handlerType = ref('')
  183. // 默认初始是第一行
  184. // 监测数据
  185. const selectData = reactive({
  186. pump1: false,
  187. pump2: false,
  188. pump3: false,
  189. pump4: false,
  190. waterPump1: false,
  191. waterPump2: false,
  192. waterPump3: false,
  193. waterPump4: false,
  194. inValve1: false,
  195. outValve1: false,
  196. inValve2: false,
  197. outValve2: false,
  198. inValve3: false,
  199. outValve3: false,
  200. inValve4: false,
  201. outValve4: false,
  202. jxmsqh: '1',
  203. ykjdqh: '1',
  204. FlowSensor_InputFlux: '-',
  205. });
  206. const flvURL1 = () => {
  207. return `https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv`;
  208. // return ''
  209. };
  210. // https获取监测数据
  211. let timer: null | NodeJS.Timeout = null;
  212. function getMonitor(flag?) {
  213. if (Object.prototype.toString.call(timer) === '[object Null]') {
  214. timer = setTimeout(async () => {
  215. if (props.deviceId) {
  216. const data = await getDataSource(props.deviceId)
  217. Object.assign(selectData, data);
  218. }
  219. if (timer) {
  220. timer = null;
  221. }
  222. await getMonitor();
  223. loading.value = false
  224. }, flag ? 0 : 1000);
  225. }
  226. };
  227. async function getDataSource(systemID) {
  228. const res = await list({ devicetype: props.deviceType, ids: systemID });
  229. const result = res.msgTxt[0]['datalist'][0];
  230. Object.assign(result, result['readData'])
  231. return result
  232. }
  233. function handler(passWord, paramcode) {
  234. let value = null
  235. if(paramcode == 'ykjdqh'){
  236. value = selectData['ykjdqh'] == '1' ? '2' : '1'
  237. }
  238. if (paramcode == 'jxmsqh') {
  239. value = selectData['jxmsqh'] == '1' ? '2' : '1'
  240. }
  241. const data = {
  242. deviceid: selectData.deviceID,
  243. devicetype: selectData.deviceType,
  244. paramcode: paramcode,
  245. password: passWord,
  246. value: value,
  247. };
  248. deviceControlApi(data).then((res) => {
  249. if (globalConfig.History_Type == 'remote') {
  250. message.success('指令已下发至生产管控平台成功!')
  251. } else {
  252. message.success('指令已下发成功!')
  253. }
  254. }).catch((err) => {
  255. message.success('控制异常');
  256. });
  257. }
  258. function changeCtr(e) {
  259. if(e.target.value == 1){
  260. // 就地
  261. handlerType.value = 'jxmsqh'
  262. }else if(e.target.value == 2) {
  263. // 远程
  264. handlerType.value = 'jxmsqh'
  265. }
  266. passwordModalIsShow.value = true;
  267. }
  268. function changeMode(e) {
  269. if (e.target.value == 1) {
  270. // 检修开
  271. handlerType.value = 'ykjdqh'
  272. } else if (e.target.value == 2) {
  273. // 检修关
  274. handlerType.value = 'ykjdqh'
  275. }
  276. passwordModalIsShow.value = true;
  277. }
  278. function handlerFn(paramcode){
  279. handlerType.value = paramcode
  280. passwordModalIsShow.value = true;
  281. }
  282. function handleOK(passWord, handlerState) {
  283. handler(passWord, handlerState)
  284. passwordModalIsShow.value = false;
  285. handlerType.value = ''
  286. }
  287. function handleCancel() {
  288. passwordModalIsShow.value = false;
  289. handlerType.value = ''
  290. };
  291. // 喷粉操作
  292. function handlerDevice(code, data) {
  293. }
  294. watch(() => props.deviceType, () => {
  295. if(props.deviceType == 'pump_over'){
  296. setModelType('gasPump')
  297. }else if(props.deviceType == 'pump_under') {
  298. setModelType('gasPumpUnder')
  299. }
  300. })
  301. onBeforeMount(() => {
  302. });
  303. onMounted(async() => {
  304. timer = null
  305. await getMonitor(true)
  306. });
  307. onUnmounted(() => {
  308. if (timer) {
  309. clearTimeout(timer);
  310. timer = undefined;
  311. }
  312. });
  313. </script>
  314. <style lang="less" scoped>
  315. @import '/@/design/vent/modal.less';
  316. @import '../../comment/less/workFace.less';
  317. @ventSpace: zxm;
  318. .lr{
  319. margin-top: 0 !important;
  320. }
  321. .left-box{
  322. width: 360px !important;
  323. direction: rtl;
  324. overflow-y: auto;
  325. overflow-x: hidden;
  326. height: calc(100% - 30px);
  327. .left-container{
  328. margin-top: 30px;
  329. direction: ltr;
  330. }
  331. }
  332. .right-box{
  333. width: 350px !important;
  334. .environment-monitor{
  335. .item{
  336. flex: 1;
  337. margin: 0 5px;
  338. .title{
  339. color: #7ae5ff;
  340. text-align: center;
  341. margin-bottom: 2px;
  342. }
  343. .num{
  344. width: 100%;
  345. height: 30px;
  346. text-align: center;
  347. border-top: 2px solid #50c8fc;
  348. border-radius: 4px;
  349. background-image: linear-gradient( #2e4d5955, #3780b499, #2E465955);
  350. }
  351. }
  352. }
  353. .pool-box{
  354. width: 327px;
  355. height: 65px;
  356. padding: 0 5px;
  357. background: url('/@/assets/images/vent/pump1.png') no-repeat;
  358. background-size: cover;
  359. background-origin: content-box;
  360. margin-top: 2px;
  361. .num{
  362. color: aqua;
  363. }
  364. .center{
  365. padding-right: 5px;
  366. }
  367. }
  368. }
  369. .control-group{
  370. display: flex;
  371. // justify-content: space-around;
  372. flex-wrap: wrap;
  373. margin: 4px 0;
  374. .control-item {
  375. display: flex;
  376. flex-direction: column;
  377. justify-content: center;
  378. align-items: center;
  379. padding: 1px 10px;
  380. .control-item-title{
  381. color: #A6DCE9;
  382. position: relative;
  383. }
  384. .control-item-state{
  385. width: 86px;
  386. height: 31px;
  387. background: url('/@/assets/images/vent/control-switch-bg1.png');
  388. display: flex;
  389. justify-content: center;
  390. align-items: center;
  391. color: #fff;
  392. }
  393. .button-box {
  394. position: relative;
  395. padding: 5px;
  396. border: 1px transparent solid;
  397. background-clip: border-box;
  398. border-radius: 5px;
  399. margin-left: 8px;
  400. }
  401. .a-button {
  402. pointer-events: auto;
  403. }
  404. &::v-deep .a-button--mini {
  405. padding: 6px 10px;
  406. }
  407. &::v-deep .a-button--mini.is-round {
  408. padding: 6px 10px;
  409. }
  410. }
  411. }
  412. .input-box{
  413. width: calc(100%);
  414. display: flex;
  415. flex-direction: row !important;
  416. flex-wrap: wrap !important;
  417. .input-item{
  418. width: calc(50% - 8px);
  419. padding: 0 2px;
  420. &:nth-child(2n){
  421. margin-left: 4px;
  422. }
  423. }
  424. }
  425. .btn-group{
  426. display: flex;
  427. justify-content: space-around;
  428. .btn-item{
  429. width: 82px;
  430. text-align: center;
  431. }
  432. }
  433. .top-btn{
  434. .btn-group{
  435. margin-bottom: 8px;
  436. .btn-item{
  437. width: calc(50% - 16px);
  438. margin: 0 4px;
  439. }
  440. }
  441. .control-item{
  442. margin-left: 10px;
  443. margin-bottom: 8px;
  444. display: flex;
  445. .control-title{
  446. width: 150px;
  447. color: #73e8fe;
  448. }
  449. }
  450. }
  451. .state-header{
  452. display: flex;
  453. color: #73e8fe;
  454. .header-item{
  455. width: 25%;
  456. text-align: center;
  457. }
  458. }
  459. .device-row{
  460. display: flex;
  461. margin-top: 10px;
  462. .state{
  463. width: 25%;
  464. text-align: center;
  465. font-size: 13px;
  466. }
  467. }
  468. :deep(.@{ventSpace}-tabs-tabpane-active) {
  469. overflow: auto;
  470. }
  471. </style>