index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <template>
  2. <div class="company-home">
  3. <div class="top-bg">
  4. <div class="main-title">{{ mainTitle }}</div>
  5. </div>
  6. <div class="company-content">
  7. <div class="area-content">
  8. <div class="left-area">
  9. <!-- 矿井通风状态监测 -->
  10. <div class="area-card">
  11. <mineWind :airKjStatus="airKjStatus" />
  12. </div>
  13. <!-- 一通三防风险分析与预警 -->
  14. <div class="area-card1">
  15. <riskWarn :earlyWarn="earlyWarn" />
  16. </div>
  17. </div>
  18. <div class="center-area">
  19. <!-- 地图底图 -->
  20. <div class="center-bg">
  21. <div class="bg-map">
  22. <div class="build"></div>
  23. <iconLight @show-detail="showDetail" :warningList="warningList" />
  24. </div>
  25. </div>
  26. <div
  27. v-if="sysDataType === 'all'"
  28. :class="{ 'realtime-mode': isDataRealTime }"
  29. alt="切换数据模式"
  30. class="switch-button report-mode"
  31. @click="switchDataMode"
  32. ></div>
  33. <!-- 榆家梁矿 -->
  34. <!-- <div class="area-card2">
  35. </div> -->
  36. <!-- 通风巷道长度统计,原文件共享中心 -->
  37. <div class="area-card3">
  38. <windRoad :roadData="roadData" />
  39. <!-- <fileShare :shareData="shareData" /> -->
  40. </div>
  41. </div>
  42. <div class="right-area">
  43. <!-- 关键场景通防综合监测 -->
  44. <div class="area-card">
  45. <sceneKey :compositeData="compositeData" />
  46. </div>
  47. <!-- 原通风巷道长度统计(wind-road.vue) -->
  48. <div class="area-card1">
  49. <BillboardEntry />
  50. <!-- <windRoad :roadData="roadData" /> -->
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. <div class="area-card2" v-show="isShowDialog">
  56. <dialogModal ref="dialogModalRef" @close-dialog="closeDialog" :title="dialogTitle" :centerDetail="centerDetail" />
  57. </div>
  58. </div>
  59. </template>
  60. <script lang="ts" setup>
  61. import { ref, reactive, nextTick, onMounted, onUnmounted } from 'vue';
  62. import mineWind from './components/mine-wind.vue';
  63. import riskWarn from './components/risk-warn.vue';
  64. // import fileShare from './components/file-share.vue';
  65. import BillboardEntry from './components/billboard-entry.vue';
  66. import windRoad from './components/wind-road-middle.vue';
  67. import sceneKey from './components/scene-key.vue';
  68. import iconLight from './components/icon-light.vue';
  69. import dialogModal from './components/dialog-modal.vue';
  70. import { getHomeData, getList } from './clique.api';
  71. import { useGlobSetting } from '/@/hooks/setting';
  72. const { sysDataType = 'monitor' } = useGlobSetting();
  73. const dialogModalRef = ref();
  74. let mainTitle = ref('国能神东一通三防管控平台');
  75. // let mainTitle = ref('国家能源神东煤炭集团');
  76. // let mainTitle = ref('XXXX集团');
  77. const isShowDialog = ref(false);
  78. const dialogTitle = ref('');
  79. //矿井通风状态数据
  80. let airKjStatus = reactive<any[]>([]);
  81. //风险分析与预警数据
  82. let earlyWarn = ref<any[]>([]);
  83. //通防综合监测数据
  84. let compositeData = ref<any[]>([]);
  85. //地图区域详情数据
  86. let centerDetail = ref({});
  87. //文件共享中心数据
  88. let shareData = reactive<any[]>([]);
  89. let warningList = ref([]);
  90. //通风巷道长度统计数据
  91. let roadData = reactive({
  92. totallength: 0,
  93. data: [],
  94. data1: [],
  95. });
  96. let orgcode = ref('');
  97. /** 数据是否使用实时数据,使用实时数据/报表数据对应某些数据的不同字段 */
  98. const isDataRealTime = ref(sysDataType === 'monitor');
  99. // https获取监测数据
  100. let timer: null | NodeJS.Timeout = null;
  101. function getMonitor() {
  102. timer = setTimeout(async () => {
  103. await getHomeDataList();
  104. await getLists();
  105. if (timer) {
  106. timer = null;
  107. }
  108. getMonitor();
  109. }, 10000);
  110. }
  111. //获取公司端首页数据
  112. async function getHomeDataList() {
  113. let res = await getHomeData();
  114. if (res && res.length > 0) {
  115. earlyWarn.value = res;
  116. roadData.totallength = res.reduce((len, r) => {
  117. return r.sys_data ? len + r.sys_data.totallength : len;
  118. }, 0);
  119. roadData.data.length = 0;
  120. roadData.data1.length = 0;
  121. airKjStatus.length = 0;
  122. const warningListTemp: { orgcode: string; isWarning: boolean }[] = [];
  123. res.forEach(({ sys_data, orgcode }) => {
  124. const air = {
  125. deviceName: sys_data.deviceName,
  126. jf: isDataRealTime.value ? sys_data.zongjinfeng : sys_data.totalIntM3,
  127. xf: isDataRealTime.value ? sys_data.xufengliang : sys_data.totalPlanM3,
  128. hf: isDataRealTime.value ? sys_data.zonghuifeng : sys_data.totalRetM3,
  129. isWarning: false,
  130. };
  131. air.isWarning = Number(air.jf) < Number(air.xf);
  132. airKjStatus.push(air);
  133. //临时添加,前端判断,后期后端加上预警再处理
  134. if (air.isWarning) {
  135. warningListTemp.push({ orgcode: orgcode, isWarning: true });
  136. } else {
  137. warningListTemp.push({ orgcode: orgcode, isWarning: false });
  138. }
  139. roadData.data.push(sys_data.flength);
  140. // roadData.data.push(sys_data.totallength);
  141. roadData.data1.push(sys_data.deviceName);
  142. });
  143. warningList.value = warningListTemp;
  144. compositeData.value = res.reduce((arr, e) => {
  145. if (isDataRealTime.value) {
  146. arr.push(...e.majorpath_data);
  147. } else {
  148. arr.push(
  149. ...e.majorpath_data.map((ele) => {
  150. const { majorpath, readData } = ele;
  151. const { drag_1, drag_2, drag_3, drag_total } = majorpath;
  152. const { retM3_merge, fy_merge } = readData;
  153. // 报表数据只有总数据,按实时数据计算比例然后乘以报表数据
  154. if (fy_merge && retM3_merge) {
  155. return {
  156. ...ele,
  157. majorpath: {
  158. drag_1: Math.round((drag_1 / drag_total) * parseInt(fy_merge.value)),
  159. drag_2: Math.round((drag_2 / drag_total) * parseInt(fy_merge.value)),
  160. drag_3: Math.round((drag_3 / drag_total) * parseInt(fy_merge.value)),
  161. drag_total: parseInt(fy_merge.value),
  162. m3_total: parseInt(retM3_merge.value),
  163. },
  164. };
  165. } else {
  166. return {
  167. ...ele,
  168. majorpath: {
  169. drag_1: NaN,
  170. drag_2: NaN,
  171. drag_3: NaN,
  172. drag_total: NaN,
  173. m3_total: NaN,
  174. },
  175. };
  176. }
  177. })
  178. );
  179. }
  180. return arr;
  181. }, []);
  182. centerDetail.value = res.filter((v) => v.orgcode == orgcode.value)[0];
  183. }
  184. }
  185. //获取文件共享中心数据
  186. async function getLists() {
  187. let res = await getList();
  188. if (res.length != 0) {
  189. shareData.length = 0;
  190. res.forEach((el) => {
  191. shareData.push({ title: el.sysOrgName, value: el.tolalNum, value1: el.approveNum });
  192. });
  193. }
  194. }
  195. function showDetail(code, label, leftV, topV) {
  196. if (code) {
  197. orgcode.value = code;
  198. dialogTitle.value = label;
  199. isShowDialog.value = true;
  200. getHomeDataList();
  201. }
  202. nextTick(() => {
  203. const tooltipDom = document.getElementById('detailModal') as HTMLElement;
  204. tooltipDom.style.left = leftV;
  205. tooltipDom.style.top = topV;
  206. });
  207. }
  208. function closeDialog() {
  209. isShowDialog.value = false;
  210. }
  211. function switchDataMode() {
  212. isDataRealTime.value = !isDataRealTime.value;
  213. getHomeDataList();
  214. }
  215. onMounted(() => {
  216. getHomeDataList();
  217. getLists();
  218. getMonitor();
  219. });
  220. onUnmounted(() => {
  221. if (timer) {
  222. clearTimeout(timer);
  223. timer = null;
  224. }
  225. });
  226. </script>
  227. <style lang="less" scoped>
  228. @font-face {
  229. font-family: 'douyuFont';
  230. src: url('../../../../assets/font/douyuFont.otf');
  231. }
  232. // @font-face {
  233. // font-family: 'yjsz';
  234. // src: url('../../../../assets/font/yjsz.TTF');
  235. // }
  236. .company-home {
  237. --image-monitor-realtime: url('/@/assets/images/company/monitor-realtime.png');
  238. --image-monitor-doc: url('/@/assets/images/company/monitor-doc.png');
  239. width: 100%;
  240. height: 100%;
  241. position: relative;
  242. background: url('../../../../assets/images/company/home-pageBg.png') no-repeat center;
  243. background-size: 100% 100%;
  244. .top-bg {
  245. width: 100%;
  246. height: 97px;
  247. background: url('../../../../assets/images/company/top-bg.png') no-repeat center;
  248. position: absolute;
  249. z-index: 1;
  250. .main-title {
  251. height: 96px;
  252. color: #fff;
  253. font-family: 'douyuFont';
  254. font-size: 20px;
  255. letter-spacing: 2px;
  256. display: flex;
  257. justify-content: center;
  258. align-items: center;
  259. }
  260. }
  261. .company-content {
  262. position: absolute;
  263. left: 0;
  264. top: 0;
  265. width: 100%;
  266. height: 100%;
  267. background: url('../../../../assets/images/company/content-bg.png') no-repeat;
  268. background-size: 100% 100%;
  269. .area-content {
  270. position: absolute;
  271. top: 45px;
  272. width: 100%;
  273. height: calc(100% - 45px);
  274. padding: 0px 20px 20px 20px;
  275. box-sizing: border-box;
  276. display: flex;
  277. justify-content: space-between;
  278. .left-area {
  279. width: 23%;
  280. height: 100%;
  281. margin-right: 15px;
  282. display: flex;
  283. flex-direction: column;
  284. justify-content: space-between;
  285. align-items: center;
  286. position: relative;
  287. z-index: 1;
  288. .area-card {
  289. width: 100%;
  290. height: calc(60% - 15px);
  291. margin-bottom: 15px;
  292. background: url('../../../../assets/images/company/area-card.png') no-repeat;
  293. background-size: 100% 100%;
  294. }
  295. .area-card1 {
  296. width: 100%;
  297. height: 40%;
  298. background: url('../../../../assets/images/company/area-card1.png') no-repeat;
  299. background-size: 100% 100%;
  300. }
  301. }
  302. .center-area {
  303. width: 1000px;
  304. height: 100%;
  305. position: relative;
  306. z-index: 0;
  307. .center-bg {
  308. position: absolute;
  309. bottom: 240px;
  310. left: 50%;
  311. transform: translate(-50%, 0);
  312. width: 1128px;
  313. height: 630px;
  314. background: url('../../../../assets/images/company/home-dz.png') no-repeat center;
  315. background-size: contain;
  316. background-position: 50% 50px;
  317. z-index: 0;
  318. .bg-map {
  319. width: 1086px;
  320. height: 610px;
  321. left: 30px;
  322. top: 60px;
  323. background: url('../../../../assets/images/company/home-map2.png') no-repeat center;
  324. background-size: contain;
  325. // background-position: 0px 70px;
  326. position: relative;
  327. z-index: 0;
  328. .build {
  329. position: absolute;
  330. background: url('../../../../assets/images/company/build1.png') no-repeat center;
  331. background-size: contain;
  332. width: 80px;
  333. height: 80px;
  334. left: 500px;
  335. top: 295px;
  336. z-index: 999;
  337. }
  338. }
  339. }
  340. .area-card2 {
  341. position: absolute;
  342. right: 0;
  343. top: 62px;
  344. width: 568px;
  345. height: 437px;
  346. background: url('../../../../assets/images/company/area-card2.png') no-repeat;
  347. background-size: 100% 100%;
  348. // pointer-events: auto;
  349. }
  350. .area-card3 {
  351. position: absolute;
  352. right: 0;
  353. bottom: 0px;
  354. width: 100%;
  355. height: 269px;
  356. background: url('../../../../assets/images/company/area-card3.png') no-repeat;
  357. background-size: 100% 100%;
  358. }
  359. }
  360. .right-area {
  361. width: 23%;
  362. height: 100%;
  363. margin-left: 15px;
  364. display: flex;
  365. flex-direction: column;
  366. justify-content: space-between;
  367. align-items: center;
  368. position: relative;
  369. z-index: 1;
  370. // pointer-events: auto;
  371. .area-card {
  372. width: 100%;
  373. height: calc(60% - 15px);
  374. margin-bottom: 15px;
  375. background: url('../../../../assets/images/company/area-card.png') no-repeat;
  376. background-size: 100% 100%;
  377. }
  378. .area-card1 {
  379. width: 100%;
  380. height: 40%;
  381. background: url('../../../../assets/images/company/area-card1.png') no-repeat;
  382. background-size: 100% 100%;
  383. }
  384. }
  385. }
  386. }
  387. .switch-button {
  388. width: 34px;
  389. height: 34px;
  390. position: absolute;
  391. right: 5px;
  392. bottom: 30%;
  393. z-index: 5;
  394. background-repeat: no-repeat;
  395. background-size: 100% 100%;
  396. }
  397. .report-mode {
  398. background-image: var(--image-monitor-doc);
  399. }
  400. .realtime-mode {
  401. background-image: var(--image-monitor-realtime);
  402. }
  403. }
  404. </style>