nitrogenHome_bd.vue 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476
  1. <template>
  2. <div>{{ Math.random() }}</div>
  3. <div id="nitrogen3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden"></div>
  4. <div
  5. id="nitrogenCss3D"
  6. class="threejs-Object-CSS"
  7. style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 2; top: 0px; left: 0px"
  8. >
  9. <a-spin :spinning="loading" />
  10. <template>
  11. <div v-for="groupNum in 1" :key="groupNum" class="modal-monitor">
  12. <fourBorderBg :class="`kyj${groupNum}`" :id="`nitrogenMonitor${groupNum}`">
  13. <div class="title">{{ monitorData[0]['strname'] }} </div>
  14. <div class="monitor-item">
  15. <span class="monitor-title">实时流量:</span>
  16. <span class="monitor-val" v-if="!refresh"
  17. ><span class="val">{{ monitorData[0]['flow'] ? monitorData[0]['flow'] : '-' }}</span> <span class="unit">m³/min</span></span
  18. >
  19. </div>
  20. <div class="monitor-item">
  21. <span class="monitor-title">单次流量:</span>
  22. <span class="monitor-val" v-if="!refresh"
  23. ><span class="val">{{ monitorData[0]['single_flow'] ? monitorData[0]['single_flow'] : '-' }}</span> <span class="unit">m³</span></span
  24. >
  25. </div>
  26. <div class="monitor-item">
  27. <span class="monitor-title">总流量:</span>
  28. <span class="monitor-val" v-if="!refresh"
  29. ><span class="val">{{ monitorData[0]['total_flow'] ? monitorData[0]['total_flow'] : '-' }}</span> <span class="unit">m³</span></span
  30. >
  31. </div>
  32. <div class="monitor-item">
  33. <span class="monitor-title">氧浓度:</span>
  34. <span class="monitor-val" v-if="!refresh"
  35. ><span class="val">{{ monitorData[0]['oxygen_concentration'] ? monitorData[0]['oxygen_concentration'] : '-' }}</span>
  36. <span class="unit">%</span></span
  37. >
  38. </div>
  39. </fourBorderBg>
  40. </div>
  41. </template>
  42. </div>
  43. <div class="nitrogen-home">
  44. <div class="nitrogen-container">
  45. <div class="top-box">
  46. <!-- 中间区域控制按钮 -->
  47. <div class="center-item-box">
  48. <div class="top-left">
  49. <div class="button-box" @click="handlerDevice(airCompressorState[0], '主机启动')">主机启动</div>
  50. <div class="button-box" @click="handlerDevice(airCompressorState[0], '主机停止')">主机停止</div>
  51. <div class="button-box" @click="handlerDevice(airCompressorState[0], '备机启动')">备机启动</div>
  52. <div class="button-box" @click="handlerDevice(airCompressorState[0], '备机停止')">备机停止</div>
  53. </div>
  54. <div class="top-center">
  55. <div class="top-c-label">通信状态:</div>
  56. <div class="top-c-val">{{ monitorData[0]['netStatus'] == 1 ? '连接' : monitorData[0]['netStatus'] == 0 ? '断开' : '未知' }}</div>
  57. </div>
  58. <div class="top-right">
  59. <div class="control-type">
  60. <div class="control-title">运行状态:</div>
  61. <a-radio-group v-model:value="monitorData[0]['overhaul_run']">
  62. <a-radio :value="`1`" disabled>检修</a-radio>
  63. <a-radio :value="`0`" disabled>运行</a-radio>
  64. </a-radio-group>
  65. </div>
  66. <div class="control-type">
  67. <div class="control-title">控制模式:</div>
  68. <a-radio-group v-model:value="monitorData[0]['remote_local']">
  69. <a-radio :value="`1`" disabled>就地</a-radio>
  70. <a-radio :value="`0`" disabled>远程</a-radio>
  71. </a-radio-group>
  72. </div>
  73. </div>
  74. </div>
  75. <!-- 底部区域故障数据 -->
  76. <div class="footer-item-box">
  77. <div class="device-detail">
  78. <div class="device-title">&nbsp</div>
  79. <div class="device-val">主机进气蝶阀</div>
  80. <div class="device-val">主机出气蝶阀</div>
  81. <div class="device-val">备机进气蝶阀</div>
  82. <div class="device-val">备机出气蝶阀</div>
  83. <!-- <div class="device-val">故障</div> -->
  84. </div>
  85. <div v-for="(device, key) in deviceMonitorList" class="device-detail" :key="key">
  86. <div class="device-title">{{ device.title }}</div>
  87. <div v-for="(detailItem, index) in device.dataList" :key="detailItem.code" class="device-val">
  88. <span :style="{ color: monitorData[0][detailItem.code] != '1' ? '#BFBFBF' : '#10BC79' }">{{
  89. monitorData[0][detailItem.code] == '0' ? '正常' : monitorData[0][detailItem.code] == '1' ? '故障' : '-'
  90. }}</span>
  91. <!-- <span v-if="index == 1"
  92. :style="{ color: monitorData[0][detailItem.code] != '1' ? '#BFBFBF' : '#10BC79' }">{{
  93. monitorData[0][detailItem.code] == '0' ? '正常' : monitorData[0][detailItem.code] == '1' ? '故障' :
  94. '-'
  95. }}</span> -->
  96. </div>
  97. </div>
  98. </div>
  99. <!-- 左边监测数据 -->
  100. <div class="lr-box left-box">
  101. <div class="item item-l" v-for="(groupNum, ind) in monitorDataGroupNum" :key="groupNum">
  102. <ventBox1>
  103. <template #title>
  104. <!-- <div>{{ monitorData[groupNum - 1]['strname'] }}</div> -->
  105. <div v-if="ind == 0">{{ `${monitorData[0]['strname']}-主` }}</div>
  106. <div v-else>{{ `${monitorData[0]['strname']}-备` }}</div>
  107. </template>
  108. <template #container>
  109. <div class="monitor-box">
  110. <div class="parameter-title group-parameter-title">
  111. <SvgIcon class="icon" size="38" name="device-group-paramer" /><span>进气蝶阀参数</span>
  112. </div>
  113. <div v-if="ind == 0">
  114. <div class="state-item" v-for="(data, index) in groupParameterData" :key="index">
  115. <div class="item-col">
  116. <span class="state-title1">{{ Object.values(data)[0] }} :</span>
  117. <span class="state-val1" v-if="index == 0">{{
  118. (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]]) >= 0
  119. ? monitorData[0][Object.keys(data)[0]]
  120. ? parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2)
  121. : '-'
  122. : '-'
  123. }}</span>
  124. <span class="state-val" v-else>
  125. <span
  126. v-if="monitorData[0][Object.keys(data)[0]] == '0'"
  127. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  128. ></span>
  129. <span
  130. v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
  131. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  132. ></span>
  133. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  134. </span>
  135. </div>
  136. <div class="item-col" v-if="Object.keys(data)[1]">
  137. <span class="state-title1">{{ Object.values(data)[1] }} :</span>
  138. <span class="state-val1">
  139. <span
  140. v-if="monitorData[0][Object.keys(data)[1]] == '0'"
  141. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  142. ></span>
  143. <span
  144. v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
  145. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  146. ></span>
  147. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  148. </span>
  149. </div>
  150. </div>
  151. </div>
  152. <div v-else>
  153. <div class="state-item" v-for="(data, index) in groupParameterData1" :key="index">
  154. <div class="item-col">
  155. <span class="state-title1">{{ Object.values(data)[0] }} :</span>
  156. <span class="state-val1" v-if="index == 0">{{
  157. (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]]) >= 0
  158. ? monitorData[0][Object.keys(data)[0]]
  159. ? parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2)
  160. : '-'
  161. : '-'
  162. }}</span>
  163. <span class="state-val" v-else>
  164. <span
  165. v-if="monitorData[0][Object.keys(data)[0]] == '0'"
  166. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  167. ></span>
  168. <span
  169. v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
  170. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  171. ></span>
  172. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  173. </span>
  174. </div>
  175. <div class="item-col" v-if="Object.keys(data)[1]">
  176. <span class="state-title1">{{ Object.values(data)[1] }} :</span>
  177. <span class="state-val1">
  178. <span
  179. v-if="monitorData[0][Object.keys(data)[1]] == '0'"
  180. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  181. ></span>
  182. <span
  183. v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
  184. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  185. ></span>
  186. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  187. </span>
  188. </div>
  189. </div>
  190. </div>
  191. </div>
  192. <div class="monitor-box monitor-box1">
  193. <div class="parameter-title device-parameter-title">
  194. <SvgIcon class="icon" size="32" name="device-paramer" /><span>出气蝶阀参数</span>
  195. </div>
  196. <div class="state-box">
  197. <div v-if="ind == 0">
  198. <div class="state-item" v-for="(data, index) in deviceParameterData" :key="index">
  199. <div class="item-col">
  200. <span class="state-title1">{{ Object.values(data)[0] }} :</span>
  201. <span class="state-val1" v-if="index == 0">{{
  202. (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]]) >= 0
  203. ? monitorData[0][Object.keys(data)[0]]
  204. ? parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2)
  205. : '-'
  206. : '-'
  207. }}</span>
  208. <span class="state-val" v-else>
  209. <span
  210. v-if="monitorData[0][Object.keys(data)[0]] == '0'"
  211. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  212. ></span>
  213. <span
  214. v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
  215. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  216. ></span>
  217. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  218. </span>
  219. </div>
  220. <div class="item-col" v-if="Object.keys(data)[1]">
  221. <span class="state-title1">{{ Object.values(data)[1] }} :</span>
  222. <span class="state-val1">
  223. <span
  224. v-if="monitorData[0][Object.keys(data)[1]] == '0'"
  225. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  226. ></span>
  227. <span
  228. v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
  229. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  230. ></span>
  231. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  232. </span>
  233. </div>
  234. </div>
  235. </div>
  236. <div v-else>
  237. <div class="state-item" v-for="(data, index) in deviceParameterData1" :key="index">
  238. <div class="item-col">
  239. <span class="state-title1">{{ Object.values(data)[0] }} :</span>
  240. <span class="state-val1" v-if="index == 0">{{
  241. (monitorData.length > 0 && monitorData[0][Object.keys(data)[0]]) >= 0
  242. ? monitorData[0][Object.keys(data)[0]]
  243. ? parseFloat(monitorData[0][Object.keys(data)[0]]).toFixed(2)
  244. : '-'
  245. : '-'
  246. }}</span>
  247. <span class="state-val" v-else>
  248. <span
  249. v-if="monitorData[0][Object.keys(data)[0]] == '0'"
  250. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  251. ></span>
  252. <span
  253. v-else-if="monitorData[0][Object.keys(data)[0]] == '1'"
  254. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  255. ></span>
  256. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  257. </span>
  258. </div>
  259. <div class="item-col" v-if="Object.keys(data)[1]">
  260. <span class="state-title1">{{ Object.values(data)[1] }} :</span>
  261. <span class="state-val1">
  262. <span
  263. v-if="monitorData[0][Object.keys(data)[1]] == '0'"
  264. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: blue"
  265. ></span>
  266. <span
  267. v-else-if="monitorData[0][Object.keys(data)[1]] == '1'"
  268. style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: greenyellow"
  269. ></span>
  270. <span v-else style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: #ccc"></span>
  271. </span>
  272. </div>
  273. </div>
  274. </div>
  275. </div>
  276. </div>
  277. </template>
  278. </ventBox1>
  279. </div>
  280. </div>
  281. <!-- 右边控制状态 -->
  282. <div class="lr-box right-box">
  283. <ventBox1 class="vent-margin-t-10">
  284. <template #title>
  285. <div>设备实时监测曲线</div>
  286. </template>
  287. <template #container>
  288. <BarAndLine
  289. v-if="chartsColumns.length > 0"
  290. xAxisPropType="readTime"
  291. :dataSource="echartData"
  292. height="240px"
  293. :chartsColumns="chartsColumns"
  294. :option="echatsOption"
  295. />
  296. </template>
  297. </ventBox1>
  298. <div ref="playerRef" class="player-box vent-margin-t-10"></div>
  299. </div>
  300. </div>
  301. </div>
  302. </div>
  303. <HandleModal :modal-is-show="modalIsShow" :modal-title="modalTitle" :modal-type="modalType" @handle-ok="handleOK" @handle-cancel="handleCancel" />
  304. </template>
  305. <script lang="ts" setup name="nitrogenHome">
  306. import { onMounted, onUnmounted, ref, watch, reactive, defineProps, nextTick, inject, onBeforeUnmount } from 'vue';
  307. import ventBox1 from '/@/components/vent/ventBox1.vue';
  308. import fourBorderBg from '../../../comment/components/fourBorderBg.vue';
  309. import { mountedThree, destroy, setModelType } from '../nitrogen.threejs';
  310. import { getDevice } from '../nitrogen.api';
  311. import { SvgIcon } from '/@/components/Icon';
  312. import BarAndLine from '/@/components/chart/BarAndLine.vue';
  313. import HandleModal from './modal.vue';
  314. import { deviceControlApi } from '/@/api/vent/index';
  315. import { message } from 'ant-design-vue';
  316. import { useCamera } from '/@/hooks/system/useCamera';
  317. import lodash from 'lodash';
  318. import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
  319. const globalConfig = inject('globalConfig');
  320. const props = defineProps({
  321. deviceId: {
  322. type: String,
  323. require: true,
  324. },
  325. modalType: {
  326. type: String,
  327. require: true,
  328. },
  329. });
  330. const { getCamera, removeCamera } = useCamera();
  331. const refresh = ref(false);
  332. const modalTitle = ref(''); // 模态框标题显示内容,根据设备操作类型决定
  333. const modalType = ref(''); // 模态框内容显示类型,设备操作类型
  334. const modalIsShow = ref<boolean>(false); // 是否显示模态框
  335. const loading = ref(true);
  336. let kzParam = reactive<any>({
  337. data: {},
  338. isFw: '',
  339. });
  340. const playerRef = ref();
  341. const colors = ['#FDB146', '#EE6666', '#9BCB75', '#03C2EC', '#DA3914', '#9C83D9'];
  342. const echatsOption = {
  343. grid: {
  344. top: '20%',
  345. left: '0px',
  346. right: '10px',
  347. bottom: '3%',
  348. containLabel: true,
  349. },
  350. toolbox: {
  351. feature: {},
  352. },
  353. };
  354. const monitorDataGroupNum = ref(0);
  355. let airCompressorState = reactive<any[]>([]);
  356. //主机进气
  357. const groupParameterData = [
  358. {
  359. m_in_open: '开度',
  360. m_bv_in_remote: '远控',
  361. },
  362. {
  363. m_bv_in_open: '开到位',
  364. m_bv_in_close: '关到位',
  365. },
  366. ];
  367. //备机进气
  368. const groupParameterData1 = [
  369. {
  370. b_in_open: '开度',
  371. b_bv_in_remote: '远控',
  372. },
  373. {
  374. b_bv_in_open: '开到位',
  375. b_bv_in_close: '关到位',
  376. },
  377. ];
  378. //主机出气
  379. const deviceParameterData = [
  380. {
  381. m_out_open: '开度',
  382. m_bv_out_remote: '远控',
  383. },
  384. {
  385. m_bv_out_open: '开到位',
  386. m_bv_out_close: '关到位',
  387. },
  388. ];
  389. //备机出气
  390. const deviceParameterData1 = [
  391. {
  392. b_out_open: '开度',
  393. b_bv_out_remote: '远控',
  394. },
  395. {
  396. b_bv_out_open: '开到位',
  397. b_bv_out_close: '关到位',
  398. },
  399. ];
  400. const deviceMonitorList = reactive([
  401. {
  402. title: '负载短路故障',
  403. dataList: [
  404. {
  405. title: '主机-进',
  406. code: 'm_in_load_short',
  407. },
  408. {
  409. title: '主机-出',
  410. code: 'm_out_load_short',
  411. },
  412. {
  413. title: '备机-进',
  414. code: 'b_in_load_short',
  415. },
  416. {
  417. title: '备机-出',
  418. code: 'b_out_load_short',
  419. },
  420. ],
  421. },
  422. {
  423. title: '电压过低故障',
  424. dataList: [
  425. {
  426. title: '主机-进',
  427. code: 'm_in_low_voltage',
  428. },
  429. {
  430. title: '主机-出',
  431. code: 'm_out_low_voltage',
  432. },
  433. {
  434. title: '备机-进',
  435. code: 'b_in_low_voltage',
  436. },
  437. {
  438. title: '备机-出',
  439. code: 'b_out_low_voltage',
  440. },
  441. ],
  442. },
  443. {
  444. title: '电压过高故障',
  445. dataList: [
  446. {
  447. title: '主机-进',
  448. code: 'm_in_high_voltage',
  449. },
  450. {
  451. title: '主机-出',
  452. code: 'm_out_high_voltage',
  453. },
  454. {
  455. title: '备机-进',
  456. code: 'b_in_high_voltage',
  457. },
  458. {
  459. title: '备机-出',
  460. code: 'b_out_high_voltage',
  461. },
  462. ],
  463. },
  464. {
  465. title: '电机漏电故障',
  466. dataList: [
  467. {
  468. title: '主机-进',
  469. code: 'm_in_motor_leakage',
  470. },
  471. {
  472. title: '主机-出',
  473. code: 'm_out_motor_leakage',
  474. },
  475. {
  476. title: '备机-进',
  477. code: 'b_in_motor_leakage',
  478. },
  479. {
  480. title: '备机-出',
  481. code: 'b_out_motor_leakage',
  482. },
  483. ],
  484. },
  485. {
  486. title: '电源缺相故障',
  487. dataList: [
  488. {
  489. title: '主机-进',
  490. code: 'm_in_supply_phase',
  491. },
  492. {
  493. title: '主机-出',
  494. code: 'm_out_supply_phase',
  495. },
  496. {
  497. title: '备机-进',
  498. code: 'b_in_supply_phase',
  499. },
  500. {
  501. title: '备机-出',
  502. code: 'b_out_supply_phase',
  503. },
  504. ],
  505. },
  506. {
  507. title: '关向过力矩故障',
  508. dataList: [
  509. {
  510. title: '主机-进',
  511. code: 'm_in_closing_overtorque',
  512. },
  513. {
  514. title: '主机-出',
  515. code: 'm_out_closing_overtorque',
  516. },
  517. {
  518. title: '备机-进',
  519. code: 'b_in_closing_overtorque',
  520. },
  521. {
  522. title: '备机-出',
  523. code: 'b_out_closing_overtorque',
  524. },
  525. ],
  526. },
  527. {
  528. title: '开向过力矩故障',
  529. dataList: [
  530. {
  531. title: '主机-进',
  532. code: 'm_in_opening_overtorque',
  533. },
  534. {
  535. title: '主机-出',
  536. code: 'm_out_opening_overtorque',
  537. },
  538. {
  539. title: '备机-进',
  540. code: 'b_in_opening_overtorque',
  541. },
  542. {
  543. title: '备机-出',
  544. code: 'b_out_opening_overtorque',
  545. },
  546. ],
  547. },
  548. {
  549. title: '关向过电流故障',
  550. dataList: [
  551. {
  552. title: '主机-进',
  553. code: 'm_in_closing_overcurrent',
  554. },
  555. {
  556. title: '主机-出',
  557. code: 'm_out_closing_overcurrent',
  558. },
  559. {
  560. title: '备机-进',
  561. code: 'b_in_closing_overcurrent',
  562. },
  563. {
  564. title: '备机出',
  565. code: 'b_out_closing_overcurrent',
  566. },
  567. ],
  568. },
  569. {
  570. title: '开向过电流故障',
  571. dataList: [
  572. {
  573. title: '主机-进',
  574. code: 'm_in_opening_overcurrent',
  575. },
  576. {
  577. title: '主机-出',
  578. code: 'm_out_opening_overcurrent',
  579. },
  580. {
  581. title: '备机-进',
  582. code: 'b_in_opening_overcurrent',
  583. },
  584. {
  585. title: '备机-出',
  586. code: 'b_out_opening_overcurrent',
  587. },
  588. ],
  589. },
  590. {
  591. title: '关向超时故障',
  592. dataList: [
  593. {
  594. title: '主机-进',
  595. code: 'm_in_closing_timeout',
  596. },
  597. {
  598. title: '主机-出',
  599. code: 'm_out_closing_timeout',
  600. },
  601. {
  602. title: '备机-进',
  603. code: 'b_in_closing_timeout',
  604. },
  605. {
  606. title: '备机-出',
  607. code: 'b_out_closing_timeout',
  608. },
  609. ],
  610. },
  611. {
  612. title: '开向超时故障',
  613. dataList: [
  614. {
  615. title: '主机-进',
  616. code: 'm_in_opening_timeout',
  617. },
  618. {
  619. title: '主机-出',
  620. code: 'm_out_opening_timeout',
  621. },
  622. {
  623. title: '备机-进',
  624. code: 'b_in_opening_timeout',
  625. },
  626. {
  627. title: '备机-出',
  628. code: 'b_out_opening_timeout',
  629. },
  630. ],
  631. },
  632. {
  633. title: '阀位故障',
  634. dataList: [
  635. {
  636. title: '主机-进',
  637. code: 'm_in_valve_position',
  638. },
  639. {
  640. title: '主机-出',
  641. code: 'm_out_valve_position',
  642. },
  643. {
  644. title: '备机-进',
  645. code: 'b_in_valve_position',
  646. },
  647. {
  648. title: '备机-出',
  649. code: 'b_out_valve_position',
  650. },
  651. ],
  652. },
  653. {
  654. title: '热过载故障',
  655. dataList: [
  656. {
  657. title: '主机-进',
  658. code: 'm_in_thermal_overload',
  659. },
  660. {
  661. title: '主机-出',
  662. code: 'm_out_thermal_overload',
  663. },
  664. {
  665. title: '备机-进',
  666. code: 'b_in_thermal_overload',
  667. },
  668. {
  669. title: '备机-出',
  670. code: 'b_out_thermal_overload',
  671. },
  672. ],
  673. },
  674. ]);
  675. // const chartsColumns = ref([])
  676. const chartsColumns = ref(getTableHeaderColumns('sys_nitrogen_chart'));
  677. // const propTypeArr = ref([])
  678. // watch(monitorDataGroupNum, () => {
  679. // const arr = <any[]>[]
  680. // const item = getTableHeaderColumns('sys_nitrogen_chart')
  681. // const propTypeList = []
  682. // for (let i = 1; i <= monitorDataGroupNum.value; i++) {
  683. // const lineType = lodash.cloneDeep(item[0])
  684. // lineType.legend = `制氮机${i}瞬时流量`;
  685. // lineType.dataIndex = `${item[0].dataIndex}${i}`
  686. // lineType.color = colors[i - 1]
  687. // arr.push(lineType)
  688. // }
  689. // chartsColumns.value = arr
  690. // })
  691. const monitorData = ref(
  692. new Array(3).fill({
  693. // strName: '空压机',
  694. // cumulativeFlow: '-',
  695. // centerTemperature: '-',
  696. // outletTemperature: '-',
  697. // Ia: '-',
  698. // Ib: '-',
  699. // Ic: '-',
  700. // Vab: '-',
  701. // Vac: '-',
  702. // Vbc: '-',
  703. // compressGroupName: '',
  704. // compressExhaustPressF1: '-',
  705. // compressSeparatePressF1: '-',
  706. // compressHostTempF1: '-',
  707. // compressCrewTempF1: '-',
  708. // compressRunTimeF1: '-',
  709. // controlModel: 'LOC'
  710. })
  711. );
  712. //图表数据
  713. let echartData = ref<any>([]);
  714. // https获取监测数据
  715. let timer: null | NodeJS.Timeout = null;
  716. async function getMonitor(flag?) {
  717. if (Object.prototype.toString.call(timer) === '[object Null]') {
  718. timer = await setTimeout(
  719. async () => {
  720. if (props.deviceId) {
  721. await getDataSource(props.deviceId);
  722. }
  723. if (timer) {
  724. timer = null;
  725. }
  726. await getMonitor();
  727. },
  728. flag ? 0 : 3000
  729. );
  730. }
  731. }
  732. async function getDataSource(systemID) {
  733. const res = await getDevice({ devicetype: 'sys', systemID, type: 'all' });
  734. if (res) {
  735. const result = res;
  736. if (!result || result.msgTxt.length < 1) return;
  737. result.msgTxt.forEach((item) => {
  738. if (item.type && item.type.startsWith('nitrogen')) {
  739. airCompressorState.length = 0;
  740. monitorData.value = item['datalist'].filter((data) => {
  741. const readData = data.readData;
  742. airCompressorState.push({
  743. id: data.deviceID,
  744. deviceType: data.deviceType,
  745. m_start: readData.m_start,
  746. m_stop: readData.m_stop,
  747. b_start: readData.b_start,
  748. b_stop: readData.b_stop,
  749. });
  750. return Object.assign(data, readData);
  751. });
  752. console.log(monitorData, 'monitorData.value---===');
  753. console.log(airCompressorState, 'airCompressorState--------');
  754. const airCompressor = { readTime: monitorData.value[0]['readTime'].substring(11) };
  755. const dataArr = lodash.cloneDeep(echartData.value);
  756. //图表数据
  757. if (dataArr.length < 4) {
  758. monitorData.value.forEach((el, index) => {
  759. airCompressor['flow'] = el['flow'] || 0;
  760. });
  761. dataArr.push(airCompressor);
  762. } else {
  763. dataArr.shift();
  764. // dataArr.push(airCompressor)
  765. monitorData.value.forEach((el, index) => {
  766. airCompressor['flow'] = el['flow'] || 0;
  767. });
  768. dataArr.push(airCompressor);
  769. // console.log(dataArr,'dataArr---------')
  770. }
  771. echartData.value = dataArr;
  772. }
  773. });
  774. // monitorDataGroupNum.value = monitorData.value.length;
  775. monitorDataGroupNum.value = 2;
  776. refresh.value = true;
  777. nextTick(() => {
  778. refresh.value = false;
  779. });
  780. }
  781. }
  782. function handlerDevice(data, titles) {
  783. kzParam.data = data;
  784. kzParam.isFw = titles;
  785. switch (titles) {
  786. case '主机启动':
  787. modalTitle.value = titles;
  788. modalType.value = '1';
  789. modalIsShow.value = true;
  790. kzParam.data.m_start = data.m_start;
  791. break;
  792. case '备机启动':
  793. modalTitle.value = titles;
  794. modalType.value = '2';
  795. modalIsShow.value = true;
  796. kzParam.data.b_start = data.b_start;
  797. break;
  798. case '主机停止':
  799. modalTitle.value = titles;
  800. modalType.value = '1';
  801. modalIsShow.value = true;
  802. kzParam.data.m_stop = data.m_stop;
  803. break;
  804. case '备机停止':
  805. modalTitle.value = titles;
  806. modalType.value = '2';
  807. modalIsShow.value = true;
  808. kzParam.data.b_stop = data.b_stop;
  809. break;
  810. }
  811. }
  812. function handleOK(passWord, handlerState) {
  813. console.log(kzParam, 'kz----------');
  814. let data = {};
  815. switch (kzParam.isFw) {
  816. case '主机启动':
  817. data = {
  818. deviceid: kzParam.data.id,
  819. devicetype: kzParam.data.deviceType,
  820. password: passWord,
  821. // m_start: '1',
  822. paramcode: 'm_start',
  823. value: '1',
  824. };
  825. break;
  826. case '备机启动':
  827. data = {
  828. deviceid: kzParam.data.id,
  829. devicetype: kzParam.data.deviceType,
  830. password: passWord,
  831. paramcode: 'b_start',
  832. value: '1',
  833. };
  834. break;
  835. case '主机停止':
  836. data = {
  837. deviceid: kzParam.data.id,
  838. devicetype: kzParam.data.deviceType,
  839. password: passWord,
  840. paramcode: 'm_stop',
  841. value: '1',
  842. };
  843. break;
  844. case '备机停止':
  845. data = {
  846. deviceid: kzParam.data.id,
  847. devicetype: kzParam.data.deviceType,
  848. password: passWord,
  849. paramcode: 'b_stop',
  850. value: '1',
  851. };
  852. break;
  853. }
  854. deviceControlApi(data).then((res) => {
  855. // 模拟时开启
  856. if (res.success) {
  857. modalIsShow.value = false;
  858. getDataSource(props.deviceId);
  859. if (globalConfig.History_Type == 'remote') {
  860. message.success('指令已下发至生产管控平台成功!');
  861. } else {
  862. message.success('指令已下发成功!');
  863. }
  864. }
  865. });
  866. }
  867. function handleCancel() {
  868. modalIsShow.value = false;
  869. modalTitle.value = '';
  870. modalType.value = '';
  871. }
  872. watch([monitorDataGroupNum, loading], ([newMonitorDataGroupNum, newLoading]) => {
  873. nextTick(() => {
  874. if (newMonitorDataGroupNum && !newLoading) {
  875. setModelType(props.modalType, newMonitorDataGroupNum);
  876. }
  877. });
  878. });
  879. watch(
  880. () => props.deviceId,
  881. async (deviceId) => {
  882. if (deviceId) {
  883. await getCamera(deviceId, playerRef.value);
  884. }
  885. }
  886. );
  887. onBeforeUnmount(() => {
  888. removeCamera();
  889. });
  890. onMounted(async () => {
  891. await getMonitor(true);
  892. await mountedThree().then(() => {
  893. loading.value = false;
  894. });
  895. await getCamera(props.deviceId, playerRef.value);
  896. });
  897. onUnmounted(() => {
  898. destroy();
  899. removeCamera();
  900. if (timer) {
  901. clearTimeout(timer);
  902. timer = undefined;
  903. }
  904. });
  905. </script>
  906. <style lang="less" scoped>
  907. @import '/@/design/theme.less';
  908. @ventSpace: zxm;
  909. @{theme-deepblue} {
  910. .nitrogen-home {
  911. --button-box-bg: linear-gradient(#0963c1, #1774d7);
  912. --control-title-color: #0a80fa;
  913. --border-color: #0a80fad4;
  914. --footer-item-bg: rgba(0, 32, 66, 0.6);
  915. }
  916. }
  917. .nitrogen-box {
  918. width: 100%;
  919. height: 100%;
  920. display: flex;
  921. justify-content: center;
  922. }
  923. #nitrogenCss3D {
  924. .modal-monitor {
  925. width: 200px;
  926. position: absolute;
  927. left: 0px;
  928. top: 0px;
  929. }
  930. &:deep(.win) {
  931. margin: 0 !important;
  932. background: #00000044;
  933. }
  934. }
  935. .nitrogen-home {
  936. --button-box-bg: linear-gradient(#1fa6cb, #127cb5);
  937. --control-title-color: #73e8fe;
  938. --border-color: #00baffd4;
  939. --footer-item-bg: #0e223b90;
  940. width: 100%;
  941. height: 100%;
  942. position: fixed;
  943. z-index: 9999;
  944. display: flex;
  945. flex-direction: column;
  946. justify-content: center;
  947. align-items: center;
  948. pointer-events: none;
  949. top: 20px;
  950. .nitrogen-container {
  951. width: 100%;
  952. height: calc(100% - 100px);
  953. display: flex;
  954. justify-content: space-between;
  955. margin-bottom: 100px;
  956. .top-box {
  957. // margin-top: 40px; //lxh
  958. position: relative;
  959. width: 100%;
  960. padding: 10px;
  961. overflow: hidden;
  962. display: flex;
  963. justify-content: space-between;
  964. .center-item-box {
  965. position: absolute;
  966. left: 50%;
  967. top: 50px;
  968. transform: translate(-48%, 0);
  969. width: calc(100% - 760px);
  970. height: 50px;
  971. display: flex;
  972. align-items: center;
  973. pointer-events: auto;
  974. .top-left {
  975. display: flex;
  976. flex: 2;
  977. color: var(--vent-font-color);
  978. .button-box {
  979. position: relative;
  980. width: auto;
  981. height: 32px;
  982. display: flex;
  983. align-items: center;
  984. justify-content: center;
  985. border-radius: 5px;
  986. color: var(--vent-font-color);
  987. padding: 10px 15px;
  988. margin: 0px 10px;
  989. box-sizing: border-box;
  990. cursor: pointer;
  991. background: var(--button-box-bg);
  992. }
  993. }
  994. .top-center {
  995. display: flex;
  996. flex: 1;
  997. justify-content: center;
  998. align-items: center;
  999. font-size: 20px;
  1000. color: var(--vent-font-color);
  1001. .top-c-label {
  1002. color: yellow;
  1003. }
  1004. }
  1005. .top-right {
  1006. display: flex;
  1007. flex: 2;
  1008. justify-content: right;
  1009. align-items: center;
  1010. color: var(--vent-font-color);
  1011. .control-type {
  1012. display: flex;
  1013. color: var(--vent-font-color);
  1014. .control-title {
  1015. color: var(--control-title-color);
  1016. }
  1017. }
  1018. }
  1019. }
  1020. .footer-item-box {
  1021. width: calc(100% - 20px);
  1022. height: auto;
  1023. position: absolute;
  1024. left: 50%;
  1025. bottom: 30px;
  1026. transform: translate(-50%);
  1027. display: flex;
  1028. justify-content: center;
  1029. color: var(--vent-font-color);
  1030. // box-shadow: 0 0 30px rgb(0, 153, 184) inset;
  1031. pointer-events: auto;
  1032. .device-detail {
  1033. text-align: center;
  1034. &:first-child {
  1035. background-color: var(--footer-item-bg);
  1036. }
  1037. &:last-child {
  1038. .device-val,
  1039. .device-title {
  1040. border-right: 1px solid var(--border-color);
  1041. }
  1042. }
  1043. .device-val {
  1044. line-height: 36px;
  1045. border-top: 1px solid var(--border-color);
  1046. border-left: 1px solid var(--border-color);
  1047. &:last-child {
  1048. border-bottom: 1px solid var(--border-color);
  1049. }
  1050. }
  1051. }
  1052. .device-title {
  1053. width: 110px;
  1054. text-align: center;
  1055. border-top: 1px solid var(--border-color);
  1056. border-left: 1px solid var(--border-color);
  1057. line-height: 46px;
  1058. color: #e7fdff;
  1059. background-color: var(--footer-item-bg);
  1060. }
  1061. }
  1062. .lr-box {
  1063. height: fit-content;
  1064. display: flex;
  1065. flex-direction: column;
  1066. position: relative;
  1067. overflow: hidden;
  1068. z-index: 9999;
  1069. pointer-events: auto;
  1070. }
  1071. .item {
  1072. width: 335px;
  1073. height: auto;
  1074. position: relative;
  1075. border-radius: 5px;
  1076. margin-top: 10px;
  1077. margin-bottom: 0px;
  1078. pointer-events: auto;
  1079. color: var(--vent-font-color);
  1080. overflow: hidden;
  1081. &:first-child {
  1082. margin-top: 0px;
  1083. }
  1084. .base-title {
  1085. color: var(--vent-font-color);
  1086. margin-bottom: 8px;
  1087. padding-left: 10px;
  1088. position: relative;
  1089. font-size: 16px;
  1090. &::after {
  1091. content: '';
  1092. position: absolute;
  1093. display: block;
  1094. width: 4px;
  1095. height: 12px;
  1096. top: 7px;
  1097. left: 0px;
  1098. background: #45d3fd;
  1099. border-radius: 4px;
  1100. }
  1101. }
  1102. .state-item {
  1103. display: flex;
  1104. flex-direction: row;
  1105. padding: 5px;
  1106. .item-col {
  1107. width: calc(50% - 5px);
  1108. display: flex;
  1109. justify-content: center;
  1110. align-items: center;
  1111. padding-right: 4px;
  1112. background-image: linear-gradient(to right, #39a3ff00, #39a3ff10);
  1113. &:first-child {
  1114. margin-right: 10px;
  1115. }
  1116. .state-title {
  1117. color: #ffffffcc;
  1118. flex: 9;
  1119. font-size: 14px;
  1120. }
  1121. .state-val {
  1122. flex: 1;
  1123. color: #00eefffe;
  1124. margin-right: 5px;
  1125. text-align: right;
  1126. font-size: 14px;
  1127. }
  1128. .state-title1 {
  1129. color: #ffffffcc;
  1130. flex: 5;
  1131. font-size: 14px;
  1132. }
  1133. .state-val1 {
  1134. display: flex;
  1135. flex: 1;
  1136. justify-content: center;
  1137. align-items: center;
  1138. }
  1139. }
  1140. }
  1141. .signal-box {
  1142. margin: 5px 0;
  1143. display: flex;
  1144. align-items: center;
  1145. .signal-title {
  1146. color: var(--vent-font-action-link);
  1147. margin: 0 5px;
  1148. }
  1149. &:last-child {
  1150. margin-right: 0px;
  1151. }
  1152. }
  1153. .list-item {
  1154. padding: 0 10px;
  1155. display: flex;
  1156. justify-content: space-between;
  1157. align-items: center;
  1158. .item-data-key {
  1159. color: #ffffff99;
  1160. }
  1161. }
  1162. .item-data-box {
  1163. color: var(--vent-font-color);
  1164. .state-icon {
  1165. display: inline-block;
  1166. width: 12px;
  1167. height: 12px;
  1168. border-radius: 12px;
  1169. }
  1170. .open {
  1171. border: 5px solid #133a56;
  1172. background: #4ecb73;
  1173. }
  1174. .close {
  1175. border: 5px solid #192961;
  1176. background: #6d7898;
  1177. }
  1178. }
  1179. }
  1180. .item-l {
  1181. width: 100%;
  1182. .monitor-box {
  1183. width: 100%;
  1184. .parameter-title {
  1185. position: relative;
  1186. width: 100%;
  1187. height: 14px;
  1188. margin-top: 10px;
  1189. .icon,
  1190. span {
  1191. position: absolute;
  1192. top: -10px;
  1193. }
  1194. }
  1195. .group-parameter-title {
  1196. background-image: linear-gradient(to right, #39a3ff50, #39a3ff00);
  1197. .icon {
  1198. left: -12px;
  1199. top: -17px;
  1200. }
  1201. span {
  1202. left: 18px;
  1203. }
  1204. .item-col {
  1205. background-image: linear-gradient(to right, #39a3ff00, #39a3ff10);
  1206. }
  1207. }
  1208. .device-parameter-title {
  1209. background-image: linear-gradient(to right, #3df6ff40, #3df6ff00);
  1210. .icon {
  1211. left: -10px;
  1212. top: -14px;
  1213. }
  1214. span {
  1215. left: 18px;
  1216. }
  1217. .item-col {
  1218. background-image: linear-gradient(to right, #3df6ff10, #3df6ff00);
  1219. }
  1220. }
  1221. }
  1222. // .monitor-box1 {
  1223. // height: 126px;
  1224. // }
  1225. .state-box {
  1226. height: calc(100% - 24px);
  1227. overflow-y: auto;
  1228. }
  1229. }
  1230. .right-box {
  1231. width: 330px;
  1232. margin-top: 50px;
  1233. }
  1234. .left-box {
  1235. width: 365px;
  1236. margin-top: 80px;
  1237. }
  1238. }
  1239. &:deep(.win) {
  1240. width: 100%;
  1241. margin: 0 !important;
  1242. }
  1243. }
  1244. }
  1245. &:deep(.main) {
  1246. .title {
  1247. height: 34px;
  1248. text-align: center;
  1249. font-weight: 600;
  1250. color: var(--vent-font-action-link);
  1251. // background-image: url('../../../assets/img/yfj/light.png');
  1252. background-repeat: no-repeat;
  1253. background-position-x: center;
  1254. background-position-y: 100%;
  1255. background-size: 80%;
  1256. font-size: 16px;
  1257. }
  1258. .monitor-item {
  1259. width: 200px;
  1260. display: flex;
  1261. flex-direction: row;
  1262. width: auto;
  1263. margin-bottom: 3px;
  1264. .monitor-val {
  1265. color: #ffb700;
  1266. display: flex;
  1267. width: auto;
  1268. .val {
  1269. width: 80px;
  1270. // font-size: 14px;
  1271. font-size: 16px;
  1272. }
  1273. .unit {
  1274. color: #ffffffbb;
  1275. // font-size: 14px;
  1276. font-size: 16px;
  1277. }
  1278. }
  1279. }
  1280. .monitor-title {
  1281. width: 100px;
  1282. color: var(--vent-font-action-link);
  1283. font-weight: 400;
  1284. // font-size: 14px;
  1285. font-size: 16px;
  1286. }
  1287. .signal-item {
  1288. display: flex;
  1289. justify-content: space-between;
  1290. // margin-bottom: 5px;
  1291. .signal-round {
  1292. display: inline-block;
  1293. width: 8px;
  1294. height: 8px;
  1295. border-radius: 50%;
  1296. margin: 0 10px;
  1297. position: relative;
  1298. &::after {
  1299. display: block;
  1300. content: '';
  1301. position: absolute;
  1302. width: 12px;
  1303. height: 12px;
  1304. top: -2px;
  1305. left: -2px;
  1306. border-radius: 50%;
  1307. }
  1308. }
  1309. .signal-round-gry {
  1310. background-color: #858585;
  1311. &::after {
  1312. background-color: #85858544;
  1313. box-shadow: 0 0 1px 1px #85858599;
  1314. }
  1315. }
  1316. .signal-round-run {
  1317. background-color: #67fc00;
  1318. &::after {
  1319. background-color: #67fc0044;
  1320. box-shadow: 0 0 1px 1px #c6ff77;
  1321. }
  1322. }
  1323. .signal-round-warning {
  1324. background-color: #e9170b;
  1325. &::after {
  1326. background-color: #e9170b44;
  1327. box-shadow: 0 0 1px 1px #e9170b;
  1328. }
  1329. }
  1330. }
  1331. }
  1332. :deep(.zxm-radio-wrapper) {
  1333. color: var(--vent-font-color) !important;
  1334. }
  1335. :deep(.zxm-radio-group) {
  1336. color: var(--vent-font-color) !important;
  1337. }
  1338. :deep(.zxm-radio-group .zxm-radio-wrapper) {
  1339. color: var(--vent-font-color) !important;
  1340. }
  1341. :deep(.zxm-radio-disabled + span) {
  1342. color: var(--vent-font-color);
  1343. }
  1344. :deep(.zxm-radio-disabled .zxm-radio-inner::after) {
  1345. background-color: #0490a8;
  1346. }
  1347. </style>