index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <template>
  2. <div
  3. v-show="activeKey == 'monitor' && !loading"
  4. class="bg"
  5. style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; overflow: hidden"
  6. >
  7. <a-spin :spinning="loading" />
  8. <div id="workFace3D" style="width: 100%; height: 100%; position: absolute; overflow: hidden; z-index: 1; top: 0"> </div>
  9. <div
  10. id="workFace3DCSS"
  11. class="threejs-Object-CSS"
  12. v-show="monitorActive == 4"
  13. style="width: 100%; height: 100%; position: absolute; pointer-events: none; overflow: hidden; z-index: 1; top: 0"
  14. >
  15. </div>
  16. </div>
  17. <div class="scene-box">
  18. <customHeader
  19. :fieldNames="{ label: 'systemname', value: 'id', options: 'children' }"
  20. :options="options"
  21. @change="getSelectRow"
  22. :optionValue="optionValue"
  23. >回采工作面智能管控</customHeader
  24. >
  25. <div class="center-container">
  26. <template v-if="activeKey == 'monitor'">
  27. <div class="monitor-nav">
  28. <template v-for="(nav, index) in monitorNavData" :key="index">
  29. <div class="nav-item" :class="{ 'nav-item-active': nav.isShow }" @click="changeMonitor(nav)">{{ nav.title }} </div>
  30. <a-divider v-if="index !== monitorNav.length - 1" type="vertical" style="height: 10px; background-color: #00e1ff" />
  31. </template>
  32. </div>
  33. <workFaceHome v-if="monitorActive == 0" :deviceId="optionValue" />
  34. <workFaceVentHome v-if="monitorActive == 1" :deviceId="optionValue" />
  35. <workFaceFireHome v-if="monitorActive == 2" :deviceId="optionValue" />
  36. <workFaceDustHome v-if="monitorActive == 3" :deviceId="optionValue" />
  37. <workFaceGasHome v-if="monitorActive == 4" :deviceId="optionValue" :gas-unit-num="gasUnitNum" />
  38. </template>
  39. <div v-else class="history-group">
  40. <div class="device-button-group" v-if="deviceList.length > 0 && activeKey !== 'faultRecord'">
  41. <div
  42. class="device-button"
  43. :class="{ 'device-active': deviceActive == device.deviceType }"
  44. v-for="(device, index) in deviceList"
  45. :key="index"
  46. @click="deviceChange(index)"
  47. >{{ device.deviceName }}</div
  48. >
  49. </div>
  50. <div class="history-container">
  51. <workFaceHistory
  52. v-if="activeKey == 'monitor_history' && isRefresh"
  53. ref="historyTable"
  54. class="vent-margin-t-20"
  55. :deviceId="optionValue"
  56. :device-type="deviceType"
  57. />
  58. <workFaceHandleHistory
  59. v-if="activeKey == 'handler_history' && isRefresh"
  60. ref="alarmHistoryTable"
  61. class="vent-margin-t-20"
  62. :deviceId="optionValue"
  63. :device-type="deviceType"
  64. />
  65. <workFaceAlarmHistory
  66. v-if="activeKey == 'faultRecord' && isRefresh"
  67. ref="handlerHistoryTable"
  68. class="vent-margin-t-20"
  69. :deviceId="optionValue"
  70. :device-type="deviceType"
  71. />
  72. </div>
  73. </div>
  74. </div>
  75. <BottomMenu @change="changeActive" />
  76. </div>
  77. </template>
  78. <script setup lang="ts">
  79. import { onBeforeMount, ref, onMounted, onUnmounted, nextTick } from 'vue';
  80. import { mountedThree, destroy, setModelType, showOrHideGasPlane } from './wokeFace.threejs';
  81. import { getTableList, systemList } from './workFace.api';
  82. import { monitorNav } from './workFace.data';
  83. import customHeader from '/@/components/vent/customHeader.vue';
  84. import BottomMenu from '/@/views/vent/comment/components/bottomMenu.vue';
  85. import workFaceVentHome from './components/workFaceVentHome.vue';
  86. import workFaceHome from './components/workFaceHome.vue';
  87. import workFaceFireHome from './components/workFaceFireHome.vue';
  88. import workFaceDustHome from './components/workFaceDustHome.vue';
  89. import workFaceGasHome from './components/workFaceGasHome.vue';
  90. import workFaceHistory from './components/workFaceHistory.vue';
  91. import workFaceHandleHistory from './components/workFaceHandleHistory.vue';
  92. import workFaceAlarmHistory from './components/workFaceAlarmHistory.vue';
  93. import { useRouter } from 'vue-router';
  94. type DeviceType = { deviceType: string; deviceName: string; datalist: any[] };
  95. const { currentRoute } = useRouter();
  96. const activeKey = ref('monitor');
  97. const loading = ref(false);
  98. const monitorNavData = ref(monitorNav);
  99. const monitorActive = ref(0);
  100. let modalType = ''; //模型类型
  101. const historyTable = ref();
  102. const alarmHistoryTable = ref();
  103. const handlerHistoryTable = ref();
  104. //关联设备
  105. const deviceList = ref<DeviceType[]>([]);
  106. const deviceActive = ref('');
  107. const deviceType = ref('');
  108. const options = ref();
  109. const optionValue = ref('');
  110. const gasUnitNum = ref(0);
  111. const isRefresh = ref(true);
  112. function changeActive(activeValue) {
  113. activeKey.value = activeValue;
  114. loading.value = true;
  115. if (activeKey.value === 'monitor') {
  116. // gasUnitNum.value = Math.ceil(Math.random() * 10)
  117. gasUnitNum.value = 4;
  118. setTimeout(() => {
  119. loading.value = false;
  120. }, 600);
  121. } else {
  122. loading.value = false;
  123. }
  124. nextTick(() => {
  125. setModelType(modalType, gasUnitNum.value, monitorActive.value == 4 ? true : false);
  126. });
  127. }
  128. function deviceChange(index) {
  129. deviceActive.value = deviceType.value = deviceList.value[index].deviceType;
  130. isRefresh.value = false;
  131. nextTick(() => {
  132. isRefresh.value = true;
  133. });
  134. }
  135. async function getDeviceList() {
  136. const res = await systemList({ devicetype: 'sys', systemID: optionValue.value });
  137. const result = res.msgTxt;
  138. const deviceArr = <DeviceType[]>[];
  139. result.forEach((item) => {
  140. const data = item['datalist'].filter((data: any) => {
  141. const readData = data.readData;
  142. return Object.assign(data, readData);
  143. });
  144. if (item.type != 'sys') {
  145. deviceArr.unshift({
  146. deviceType: item.type,
  147. deviceName: item['typeName'] ? item['typeName'] : item['datalist'][0]['typeName'],
  148. datalist: data,
  149. });
  150. }
  151. });
  152. deviceList.value = deviceArr;
  153. deviceActive.value = deviceArr[0].deviceType;
  154. deviceChange(0);
  155. }
  156. async function getSysDataSource() {
  157. const res = await getTableList({ strtype: 'sys_surface_caimei', pagetype: 'normal' });
  158. if (!options.value) {
  159. // 初始时选择第一条数据
  160. options.value = res.records || [];
  161. if (!optionValue.value) {
  162. optionValue.value = options.value[0]['id'];
  163. getDeviceList();
  164. changeModalType(options.value[0]);
  165. }
  166. }
  167. }
  168. // 切换检测数据
  169. async function getSelectRow(deviceID) {
  170. const currentData = options.value.find((item: any) => {
  171. return item.id == deviceID;
  172. });
  173. optionValue.value = deviceID;
  174. changeModalType(currentData);
  175. getDeviceList();
  176. }
  177. // 获取模型类型
  178. function changeModalType(currentData) {
  179. if (currentData['strsystype'] === 'sys_surface_caimei_modal_1') {
  180. // 单进单回
  181. modalType = 'workFace1';
  182. } else if (currentData['strsystype'] === 'sys_surface_caimei_modal_3') {
  183. // 双进单回
  184. modalType = 'workFace3';
  185. } else if (currentData['strsystype'] === 'sys_surface_caimei_modal_4') {
  186. // 双进双回
  187. modalType = 'workFace4';
  188. }
  189. // gasUnitNum.value = Math.ceil(Math.random() * 4)
  190. gasUnitNum.value = 4;
  191. setModelType(modalType, gasUnitNum.value, monitorActive.value == 4 ? true : false);
  192. }
  193. function changeMonitor(nav) {
  194. nav.isShow = true;
  195. monitorNav.forEach((item, index) => {
  196. if (item.title !== nav.title) {
  197. item.isShow = false;
  198. } else {
  199. monitorActive.value = index;
  200. if (monitorActive.value != 4) {
  201. }
  202. }
  203. });
  204. showOrHideGasPlane(monitorActive.value == 4 ? true : false);
  205. }
  206. onBeforeMount(() => {});
  207. onMounted(async () => {
  208. if (currentRoute.value && currentRoute.value['query'] && currentRoute.value['query']['id']) optionValue.value = currentRoute.value['query']['id'];
  209. await getSysDataSource();
  210. loading.value = true;
  211. mountedThree().then(async () => {
  212. // gasUnitNum.value = Math.ceil(Math.random() * 10)
  213. gasUnitNum.value = 4;
  214. loading.value = false;
  215. nextTick(() => {
  216. setModelType(modalType, gasUnitNum.value, monitorActive.value == 4 ? true : false);
  217. });
  218. });
  219. });
  220. onUnmounted(() => {
  221. destroy();
  222. });
  223. </script>
  224. <style lang="less" scoped>
  225. @import '/@/design/vent/modal.less';
  226. @import '/@/design/theme.less';
  227. @ventSpace: zxm;
  228. :deep(.@{ventSpace}-tabs-tabpane-active) {
  229. overflow: auto;
  230. }
  231. .scene-box {
  232. --image-wokeFaca-nav: url('/@/assets/images/vent/wokeFaca-nav.png');
  233. --gradient-0: linear-gradient(45deg, #96c5ca38, #156c7d4a);
  234. --color-0: #73e8fe;
  235. --color-2: #96c5ca38;
  236. --color-3: #156c7d4a;
  237. --color-5: #6195af1a;
  238. --color-6: #00fffd22;
  239. --color-7: #44b4ff33;
  240. --color-10: #6176af;
  241. --color-15: #ffffff88;
  242. --color-16: #f73b2440;
  243. --color-18: #ff9b1740;
  244. --color-22: #ffa500;
  245. width: 100%;
  246. height: 100%;
  247. }
  248. .monitor-nav {
  249. width: 860px;
  250. height: 42px;
  251. display: flex;
  252. justify-content: center;
  253. align-items: center;
  254. // border: 1px solid var(--color-0);
  255. color: var(--vent-font-color);
  256. position: absolute;
  257. top: 88px;
  258. left: 50% !important;
  259. transform: translateX(-50%) !important;
  260. pointer-events: auto;
  261. background: var(--gradient-0);
  262. clip-path: polygon(
  263. 14px 0,
  264. calc(100% - 14px) 0,
  265. 100% 14px,
  266. 100% calc(100% - 14px),
  267. calc(100% - 14px) 100%,
  268. 14px 100%,
  269. 0 calc(100% - 14px),
  270. 0 14px
  271. );
  272. // background: var(--image-wokeFaca-nav) no-repeat !important;
  273. .nav-item {
  274. padding: 1px 10px;
  275. cursor: pointer;
  276. }
  277. .nav-item-active {
  278. color: var(--vent-font-action-link);
  279. }
  280. }
  281. .history-group {
  282. padding: 0 20px;
  283. margin-top: 90px;
  284. .history-container {
  285. position: relative;
  286. background: var(--color-5);
  287. width: calc(100% + 10px);
  288. left: -10px;
  289. border: 1px solid var(--color-6);
  290. padding: 10px 0;
  291. box-shadow: 0 0 20px var(--color-7) inset;
  292. }
  293. }
  294. .device-button-group {
  295. // margin: 0 20px;
  296. display: flex;
  297. pointer-events: auto;
  298. position: relative;
  299. &::after {
  300. position: absolute;
  301. content: '';
  302. width: calc(100% + 10px);
  303. height: 2px;
  304. top: 30px;
  305. left: -10px;
  306. border-bottom: 1px solid var(--vent-font-action-link);
  307. }
  308. .device-button {
  309. padding: 4px 15px;
  310. position: relative;
  311. display: flex;
  312. justify-content: center;
  313. align-items: center;
  314. font-size: 14px;
  315. color: var(--vent-font-color);
  316. cursor: pointer;
  317. margin: 0 3px;
  318. &::before {
  319. content: '';
  320. position: absolute;
  321. top: 0;
  322. right: 0;
  323. bottom: 0;
  324. left: 0;
  325. border: 1px solid var(--color-10);
  326. transform: skewX(-38deg);
  327. background-color: rgba(0, 77, 103, 85%);
  328. z-index: -1;
  329. }
  330. }
  331. .device-active {
  332. // color: var(--color-11);
  333. &::before {
  334. border-color: var(--color-12);
  335. box-shadow: 1px 1px 3px 1px var(--color-13) inset;
  336. }
  337. }
  338. }
  339. .input-box {
  340. display: flex;
  341. align-items: center;
  342. padding-left: 10px;
  343. .input-title {
  344. color: var(--color-14);
  345. width: auto;
  346. }
  347. .@{ventSpace}-input-number {
  348. border-color: var(--color-15) !important;
  349. }
  350. margin-right: 10px;
  351. }
  352. .monitor-msg-box {
  353. width: 170px;
  354. margin-top: 100px;
  355. .monitor-msg-container {
  356. width: 170px;
  357. height: 150px;
  358. box-shadow: rgba(128, 128, 128, 0.3) 0px 0px 40px inset;
  359. border: 1px solid rgba(128, 128, 128, 0.3);
  360. background-color: transparent;
  361. }
  362. .errorColor {
  363. box-shadow: var(--color-16) 0px 0px 40px inset;
  364. border: 1px solid var(--color-17);
  365. }
  366. .warningColor {
  367. box-shadow: var(--color-18) 0px 0px 40px inset;
  368. border: 1px solid var(--color-19);
  369. }
  370. .monitor-item {
  371. padding: 10px 10px 0px 10px;
  372. color: var(--color-20);
  373. letter-spacing: 2px;
  374. .item-title {
  375. color: var(--color-21);
  376. }
  377. .num {
  378. color: var(--color-22);
  379. }
  380. }
  381. }
  382. </style>