index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <!-- eslint-disable vue/multi-word-component-names -->
  2. <template>
  3. <div class="company-home">
  4. <SystemSelect
  5. :class="{
  6. 'custom-system-select': true,
  7. 'custom-system-select-mine': appStore.getSimpleMapParams.isLeaf,
  8. }"
  9. />
  10. <template v-if="appStore.getSimpleMapParams.isLeaf">
  11. <div class="company-title">
  12. <div class="company-title-content">
  13. <span class="title-text">
  14. {{ departName }}
  15. </span>
  16. </div>
  17. </div>
  18. </template>
  19. <template v-else>
  20. <div class="button-border"></div>
  21. </template>
  22. <!-- 渲染所有模块 -->
  23. <ModulePrimary
  24. v-for="cfg in cfgs"
  25. :key="cfg.deviceType"
  26. :show-style="cfg.showStyle"
  27. :module-data="cfg.moduleData"
  28. :module-name="cfg.moduleName"
  29. :device-type="cfg.deviceType"
  30. :data="data"
  31. :visible="true"
  32. />
  33. </div>
  34. </template>
  35. <script lang="ts" setup>
  36. import { computed, onUnmounted, ref, watch, shallowRef } from 'vue';
  37. import { useInitConfigs, useInitPage } from '@/components/Configurable/hooks/useInit';
  38. import { testConfigSealedGoaf, testConfigSealedMine } from './configurable.data.sealedGoaf';
  39. import {
  40. getCoalSeamFireNum,
  41. getMineProductionStatusNum,
  42. getOverLimitNum,
  43. getGoafAlarmNum,
  44. getGoafAccessCount,
  45. getGoafData,
  46. getGoafStatusNum,
  47. getProvinceAlarm,
  48. } from './sealedGoaf.api';
  49. import ModulePrimary from '/@/components/Configurable/ModulePrimary.vue';
  50. import { useGlobSetting } from '/@/hooks/setting';
  51. import { useAppStore } from '/@/store/modules/app';
  52. import { useMineDepartmentStore } from '/@/store/modules/mine';
  53. import SystemSelect from '/@/layouts/default/feature/SystemSelect.vue';
  54. const { title = '老空区永久密闭监测与分析系统' } = useGlobSetting();
  55. const { data, updateData } = useInitPage(title);
  56. const appStore = useAppStore();
  57. const mineStore = useMineDepartmentStore();
  58. const departName = ref('');
  59. const cfgs = computed(() => configs.value);
  60. const { configs } = useInitConfigs();
  61. const mineData = shallowRef({
  62. coalSeamFireData: null,
  63. productionStatusData: null,
  64. overLimitData: null,
  65. goafAlarmData: null,
  66. // goafAlarmLevel: null,
  67. totalNum: {
  68. productionNum: 0, // 原有生产状态总计
  69. alarmNum: {
  70. alarm1Total: 0, // alarm1 总计
  71. alarm2Total: 0, // alarm2 总计
  72. alarm3Total: 0, // alarm3 总计
  73. alarm4Total: 0, // alarm4 总计
  74. alarmTotal: 0, // 所有alarm总计
  75. },
  76. },
  77. goafAccessCount: {
  78. accessDetails: null,
  79. totalNum: {
  80. yjTotal: 0, // 应接入总计
  81. zxTotal: 0, // 在线总计
  82. lxTotal: 0, // 离线总计
  83. wjTotal: 0, // 未接入总计
  84. },
  85. },
  86. }); // 所有数据汇总
  87. const goafData = ref({
  88. monitorData: null,
  89. transCoalSeamFireData: null as any[] | null,
  90. coalSeamFireData: null,
  91. goafStatusNum: null,
  92. goafAlarmNum: null,
  93. provinceAlarm: null,
  94. });
  95. async function fetchHomeData() {
  96. try {
  97. // 2. 异步获取所有接口数据(并行请求提升性能)
  98. const [coalSeamFireData, productionStatusData, overLimitData, goafAlarmData, accessDetails] = await Promise.all([
  99. getCoalSeamFireNum(appStore.simpleMapParams), // 煤层自燃倾向数据
  100. getMineProductionStatusNum(appStore.simpleMapParams), // 当日生产状态数据
  101. getOverLimitNum(appStore.simpleMapParams), // 超限数据(可按需处理)
  102. getGoafAlarmNum(appStore.simpleMapParams), // 执法处风险统计
  103. getGoafAccessCount(appStore.simpleMapParams),
  104. // getGoafAlarmLevel(appStore.simpleMapParams),
  105. // getGoafAlarmLevel({ mineCode: '100008' }),
  106. ]);
  107. const totalProductionNum = Array.isArray(productionStatusData) ? productionStatusData.reduce((sum, item) => sum + (item.num || 0), 0) : 0;
  108. productionStatusData.push({
  109. num: [1, 7, 2, 0, 6, 8, 9].reduce((total, index) => total + productionStatusData[index].num, 0),
  110. name: '停产停建',
  111. });
  112. productionStatusData.push({
  113. num: [10, 11, 12].reduce((total, index) => total + productionStatusData[index].num, 0),
  114. name: '长期停产停建',
  115. });
  116. let alarm1Total = 0;
  117. let alarm2Total = 0;
  118. let alarm3Total = 0;
  119. let alarm4Total = 0;
  120. // 遍历数组累加(边界处理:确保是数组,字段非数字则取0)
  121. if (Array.isArray(goafAlarmData)) {
  122. goafAlarmData.forEach((item) => {
  123. alarm1Total += Number(item.alarm1) || 0;
  124. alarm2Total += Number(item.alarm2) || 0;
  125. alarm3Total += Number(item.alarm3) || 0;
  126. alarm4Total += Number(item.alarm4) || 0;
  127. });
  128. }
  129. // 计算所有alarm的总合计
  130. const alarmTotal = alarm1Total + alarm2Total + alarm3Total + alarm4Total;
  131. // console.log('所有alarm的总合计:', alarmTotal);
  132. const totalNum = { productionNum: totalProductionNum, alarmNum: { alarm1Total, alarm2Total, alarm3Total, alarm4Total, alarmTotal } };
  133. // 联网状态模块数据处理:遍历 accessDetails 数组,累加所有项的 yjNum、zxNum、lxNum、wjNum
  134. let yjTotal = 0;
  135. let zxTotal = 0;
  136. let lxTotal = 0;
  137. let wjTotal = 0;
  138. let zdTotal = 0;
  139. if (Array.isArray(accessDetails)) {
  140. accessDetails.forEach((item) => {
  141. yjTotal += Number(item.yjNum) || 0;
  142. zxTotal += Number(item.zxNum) || 0;
  143. lxTotal += Number(item.lxNum) || 0;
  144. wjTotal += Number(item.wjNum) || 0;
  145. zdTotal += Number(item.zdNum) || 0;
  146. });
  147. }
  148. const goafAccessCount = {
  149. accessDetails,
  150. totalNum: { yjTotal, zxTotal, lxTotal, wjTotal, zdTotal },
  151. };
  152. // const coalSeamFireChartData = ['Ⅰ类容易自燃', 'Ⅱ类自燃', 'Ⅲ类不易自燃'].reduce(
  153. // (val: any, key) => {
  154. // const arr = coalSeamFireData[key];
  155. // val.coalSeamLevel.push(key);
  156. // val.num.push(arr.length);
  157. // val.desc.push(arr.map((e) => `${e.mineName}-${e.coalSeamName}`).join('、'));
  158. // // return { coalSeamLevel: key, num: arr?.length, desc: };
  159. // return val;
  160. // },
  161. // { coalSeamLevel: [], num: [], desc: [] }
  162. // );
  163. const coalSeamFireChartData = ['Ⅰ类容易自燃', 'Ⅱ类自燃', 'Ⅲ类不易自燃'].map((key) => {
  164. const arr = coalSeamFireData[key];
  165. const obj = { name1: key, name2: arr.map((e) => `${e.mineName}-${e.coalSeamName}`).join('<br>') };
  166. return {
  167. coalSeamLevel: `${obj.name1}:${obj.name2.length}`,
  168. num: arr?.length,
  169. };
  170. });
  171. // console.log('debug coal', coalSeamFireChartData);
  172. // 3. 把接口数据赋值给响应式变量(备用)
  173. mineData.value = {
  174. coalSeamFireData: coalSeamFireChartData as any,
  175. productionStatusData,
  176. overLimitData,
  177. goafAlarmData,
  178. totalNum,
  179. goafAccessCount,
  180. };
  181. // 5. 更新页面数据
  182. updateData(mineData.value);
  183. } catch (error) {
  184. console.error('数据获取/配置更新失败:', error);
  185. }
  186. }
  187. async function fetchLeafData() {
  188. try {
  189. // 异步获取所有接口数据(并行请求提升性能)
  190. const [monitorData, coalSeamFireData, goafStatusNum, goafAlarmNum, provinceAlarm] = await Promise.all([
  191. getGoafData(appStore.simpleMapParams), // 密闭监测详情
  192. getCoalSeamFireNum(appStore.simpleMapParams), // 煤层自燃倾向数据
  193. getGoafStatusNum(appStore.simpleMapParams), // 密闭统计
  194. getGoafAlarmNum(appStore.simpleMapParams), // 预警统计
  195. getProvinceAlarm(appStore.simpleMapParams), // 预警信息列表
  196. ]);
  197. if (provinceAlarm?.records) {
  198. const alarmTypeMap = {
  199. leakageAlarm: '老空区永久密闭漏风状态报警',
  200. sourcePressureAlarm: '内外压差风险报警',
  201. fireAlarm: '自燃发火隐患报警',
  202. fireAlarmOut: '老空区永久密闭墙外自燃发火报警',
  203. unsealAlarm: '火区老空区永久密闭启封报警',
  204. explosionAlarm: '老空区永久密闭爆炸危险性报警',
  205. overLimitAlarm: '超限报警',
  206. lateReport: '数据延迟上报预警',
  207. };
  208. // 遍历列表,把 alarmType 替换成中文
  209. provinceAlarm.records = provinceAlarm.records.map((item) => {
  210. item.alarmTypeCont = alarmTypeMap[item.alarmType] || item.alarmType;
  211. return item;
  212. });
  213. }
  214. // 遍历煤层自燃倾向性,数据重组
  215. let transCoalSeamFireData: any[] = [];
  216. if (coalSeamFireData) {
  217. transCoalSeamFireData = Object.values(coalSeamFireData).flat();
  218. }
  219. // 把接口数据赋值给响应式变量(备用)
  220. goafData.value = { monitorData, coalSeamFireData, transCoalSeamFireData, goafStatusNum, goafAlarmNum, provinceAlarm };
  221. // 更新页面数据
  222. updateData(goafData.value);
  223. } catch (error) {
  224. console.error('数据获取/配置更新失败:', error);
  225. }
  226. }
  227. watch(
  228. () => appStore.getSimpleMapParams,
  229. (params) => {
  230. if (params.isLeaf) {
  231. fetchLeafData();
  232. configs.value = testConfigSealedMine; // 解构触发响应式更新
  233. const depart = mineStore.findDepartById(params.deptId, mineStore.getDepartTree);
  234. if (depart) {
  235. departName.value = depart.departName;
  236. // console.log('自动填充矿区名称:', depart.departName);
  237. }
  238. } else {
  239. fetchHomeData();
  240. configs.value = testConfigSealedGoaf; // 解构触发响应式更新
  241. }
  242. },
  243. {
  244. immediate: true,
  245. }
  246. );
  247. // 数据处理函数
  248. onUnmounted(() => {});
  249. </script>
  250. <style lang="less" scoped>
  251. @import '/@/design/theme.less';
  252. @font-face {
  253. font-family: 'douyuFont';
  254. src: url('/@/assets/font/douyuFont.otf');
  255. }
  256. .company-home {
  257. position: fixed;
  258. width: 100%;
  259. height: 100%;
  260. color: @white;
  261. background-image: linear-gradient(90deg, @map-bg 0%, @map-bg 20%, transparent 30%, transparent 70%, @map-bg 80%, @map-bg 100%);
  262. background-repeat: no-repeat;
  263. background-size: 100% 100%;
  264. z-index: @layout-basic-z-index;
  265. // 允许点击穿透以支持下面的地图进行交互
  266. pointer-events: none;
  267. .custom-system-select {
  268. z-index: @layout-header-fixed-z-index;
  269. position: absolute;
  270. top: 25px;
  271. left: 25px;
  272. pointer-events: all;
  273. }
  274. }
  275. .custom-system-select-mine {
  276. top: 70px !important;
  277. }
  278. .button-border {
  279. position: absolute;
  280. width: 405px;
  281. height: 60px;
  282. left: 22px;
  283. top: 15px;
  284. border: 2px dashed #0070ff;
  285. border-radius: 5px;
  286. }
  287. .company-title {
  288. position: absolute;
  289. width: 405px;
  290. height: 110px;
  291. left: 22px;
  292. top: 15px;
  293. border: 2px dashed #0070ff;
  294. border-radius: 5px;
  295. // padding: 14px 20px;
  296. .company-title-content {
  297. width: 100%;
  298. height: 52px;
  299. background-image: url(/src/assets/images/sealedGoaf/title-bg.png);
  300. background-repeat: no-repeat;
  301. background-size: 100% 100%;
  302. }
  303. .title-text {
  304. display: block;
  305. width: 100%;
  306. overflow: hidden;
  307. white-space: nowrap;
  308. text-overflow: ellipsis;
  309. text-align: center;
  310. line-height: 52px;
  311. }
  312. }
  313. :deep(.ant-select-selection-item) {
  314. display: flex;
  315. align-items: center;
  316. }
  317. </style>