index-mine.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. <template>
  2. <customHeader>预警历史监控系统</customHeader>
  3. <div class="data-statistics">
  4. <div class="statistics-box" v-for="(item, index) in statisticsList" :key="index">
  5. <div class="left-box">
  6. <div class="box-title">{{ item.title }}</div>
  7. </div>
  8. <div class="right-box">
  9. <div class="box-text">
  10. <div class="text-label">监测数量</div>
  11. <div class="text-value">{{ item.valueT }}</div>
  12. </div>
  13. <div class="warning-state box-text">
  14. <div class="text-label">预警状态</div>
  15. <div class="text-value">{{ item.valueB }}</div>
  16. </div>
  17. </div>
  18. </div>
  19. </div>
  20. <a-tabs class="tab-box" v-model:activeKey="activeKey" @change="onChangeTab">
  21. <a-tab-pane tab="设备预警历史" key="device" />
  22. <a-tab-pane tab="联动预警历史" key="manageAuto" />
  23. <a-tab-pane tab="安全监控预警历史" key="safety" />
  24. </a-tabs>
  25. <div class="alarm-history-table">
  26. <template v-if="activeKey == 'device'">
  27. <BasicTable ref="alarmHistory" @register="registerTable" :scroll="{ x: 0, y: 350 }">
  28. <template #form-onExportXls>
  29. <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls()"> 导出</a-button>
  30. </template>
  31. <template #bodyCell="{ column, record }">
  32. <template v-if="column.dict">
  33. <!-- 除了 101(蓝色预警)其他都是红色字体 -->
  34. <span v-if="column.dataIndex === 'nwartype'"
  35. :class="{ 'color-#ff3823': ['102', '103', '104', '201', '1001'].includes(record.nwartype) }">
  36. {{ render.renderDictText(record.nwartype, 'leveltype') || '-' }}
  37. </span>
  38. <span v-else>
  39. {{ render.renderDictText(record[column.dataIndex], column.dict) || '-' }}
  40. </span>
  41. </template>
  42. </template>
  43. </BasicTable>
  44. </template>
  45. <template v-if="activeKey == 'manageAuto'">
  46. <BasicTable ref="alarmHistory" @register="registerTable" :scroll="{ x: 0, y: 350 }">
  47. <template #form-onExportXls>
  48. <a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls()"> 导出</a-button>
  49. </template>
  50. <template #bodyCell="{ column, record }">
  51. <template v-if="column.dict">
  52. <!-- 除了 101(蓝色预警)其他都是红色字体 -->
  53. <span v-if="column.dataIndex === 'nwartype'"
  54. :class="{ 'color-#ff3823': ['102', '103', '104', '201', '1001'].includes(record.nwartype) }">
  55. {{ render.renderDictText(record.nwartype, 'leveltype') || '-' }}
  56. </span>
  57. <span v-else>
  58. {{ render.renderDictText(record[column.dataIndex], column.dict) || '-' }}
  59. </span>
  60. </template>
  61. </template>
  62. </BasicTable>
  63. </template>
  64. <template v-if="activeKey == 'safety'">
  65. <AlarmHistoryTable ref="alarmHistoryTable" columns-type="alarm" :list="safetyList" device-type="safetymonitor"
  66. :device-list-api="getDeviceList.bind(null, { devicekind: 'safetymonitor', pageSize: 10000 })"
  67. designScope="alarm-history" />
  68. </template>
  69. </div>
  70. </template>
  71. <script lang="ts" name="system-user" setup>
  72. //ts语法
  73. import { watch, ref, defineExpose, onMounted, reactive } from 'vue';
  74. import { BasicTable } from '/@/components/Table';
  75. import { useListPage } from '/@/hooks/system/useListPage';
  76. import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
  77. import { manageAutoColumns } from './alarm.data';
  78. import { getAutoScrollContainer } from '/@/utils/common/compUtils';
  79. import { getAlarmLogList, getManageAutoLogList, getWarnCountInfo } from './warning.api';
  80. import { getDeviceList, safetyList, } from '../safetyMonitor/safety.api';
  81. import { useRoute } from 'vue-router';
  82. import customHeader from '/@/components/vent/customHeader.vue';
  83. import AlarmHistoryTable from '../safetyMonitor/AlarmHistoryTable.vue';
  84. import { render } from '/@/utils/common/renderUtils';
  85. const props = defineProps({
  86. formConfig: {
  87. type: Object as PropType<FormProps> | undefined,
  88. default: undefined,
  89. },
  90. });
  91. const route = useRoute();
  92. let statisticsList = reactive<any[]>([
  93. { title: '通风', valueT: 0, valueB: '' },
  94. { title: '粉尘', valueT: 0, valueB: '' },
  95. { title: '瓦斯', valueT: 0, valueB: '' },
  96. { title: '火灾', valueT: 0, valueB: '' },
  97. { title: '安全监测', valueT: 0, valueB: '' },
  98. ]);
  99. const activeKey = ref('device');
  100. const alarmHistory = ref();
  101. const deviceColumns = getTableHeaderColumns('alarm_history') as [];
  102. const dataColumns = ref(deviceColumns);
  103. const list = ref<any>(getAlarmLogList);
  104. // 列表页面公共参数、方法
  105. const { tableContext, onExportXls } = useListPage({
  106. tableProps: {
  107. api: list,
  108. columns: dataColumns,
  109. canResize: true,
  110. showTableSetting: false,
  111. showActionColumn: false,
  112. showIndexColumn: true,
  113. bordered: false,
  114. size: 'small',
  115. formConfig: {
  116. labelAlign: 'left',
  117. showAdvancedButton: false,
  118. // autoAdvancedCol: 2,
  119. schemas: [
  120. {
  121. label: '是否解决',
  122. // field: 'isok',
  123. field: 'isOk',
  124. defaultValue: false,
  125. component: 'Select',
  126. componentProps: {
  127. options: [
  128. {
  129. label: '未解决',
  130. value: false,
  131. },
  132. {
  133. label: '已解决',
  134. value: true,
  135. },
  136. ],
  137. },
  138. colProps: { span: 4 },
  139. },
  140. {
  141. label: '所属系统',
  142. // field: 'kindtype',systemType
  143. field: 'systemType',
  144. component: 'Select',
  145. componentProps: {
  146. options: [
  147. {
  148. label: '通风',
  149. value: 'ventS',
  150. },
  151. {
  152. label: '防灭火',
  153. value: 'fireS',
  154. },
  155. {
  156. label: '防尘',
  157. value: 'dustS',
  158. },
  159. {
  160. label: '瓦斯',
  161. value: 'gasS',
  162. },
  163. ],
  164. },
  165. colProps: { span: 4 },
  166. },
  167. // {
  168. // label: '设备类型',
  169. // field: 'deviceKind',
  170. // component: 'MTreeSelect',
  171. // componentProps: {
  172. // virtual: false,
  173. // },
  174. // colProps: { span: 4 },
  175. // },
  176. {
  177. label: '设备类型',
  178. field: 'deviceKind',
  179. component: 'Select',
  180. defaultValue: '',
  181. componentProps: {
  182. options: [
  183. {
  184. label: '全部',
  185. value: '',
  186. },
  187. ],
  188. },
  189. colProps: { span: 4 },
  190. },
  191. {
  192. field: 'starttime',
  193. label: '开始报警时间',
  194. component: 'DatePicker',
  195. componentProps: {
  196. showTime: true,
  197. valueFormat: 'YYYY-MM-DD HH:mm:ss',
  198. getPopupContainer: getAutoScrollContainer,
  199. },
  200. colProps: {
  201. span: 4,
  202. },
  203. },
  204. // {
  205. // field: 'endtime',
  206. // label: '结束时间',
  207. // component: 'DatePicker',
  208. // componentProps: {
  209. // showTime: true,
  210. // valueFormat: 'YYYY-MM-DD HH:mm:ss',
  211. // getPopupContainer: getAutoScrollContainer,
  212. // },
  213. // colProps: {
  214. // span: 4,
  215. // },
  216. // },
  217. ],
  218. },
  219. fetchSetting: {
  220. listField: 'records',
  221. },
  222. pagination: {
  223. current: 1,
  224. pageSize: 10,
  225. pageSizeOptions: ['10', '30', '50', '100'],
  226. },
  227. beforeFetch(params) {
  228. if (!params['deviceKind']) {
  229. params['deviceKind'] = null;
  230. }
  231. return params;
  232. },
  233. },
  234. exportConfig: {
  235. name: '预警历史列表',
  236. url: '/safety/ventanalyAlarmLog/exportXls',
  237. },
  238. });
  239. //注册table数据
  240. const [registerTable, { reload, setLoading, getForm }] = tableContext;
  241. function onChangeTab(tab) {
  242. if (tab === 'device') {
  243. list.value = getAlarmLogList;
  244. dataColumns.value = deviceColumns;
  245. } else {
  246. list.value = getManageAutoLogList;
  247. dataColumns.value = manageAutoColumns;
  248. }
  249. }
  250. //获取预警统计信息
  251. async function getEachMineWarnCountInfoList() {
  252. let res = await getWarnCountInfo({});
  253. statisticsList[0].valueT = res.ventSWarnInfo.totalNum || 0;
  254. statisticsList[0].valueB = res.ventSWarnInfo.maxWarnLevel || '';
  255. statisticsList[1].valueT = res.dustSWarnInfo.totalNum || 0;
  256. statisticsList[1].valueB = res.dustSWarnInfo.maxWarnLevel || '';
  257. statisticsList[2].valueT = res.gasSWarnInfo.totalNum || 0;
  258. statisticsList[2].valueB = res.gasSWarnInfo.maxWarnLevel || '';
  259. statisticsList[3].valueT = res.fireSWarnInfo.totalNum || 0;
  260. statisticsList[3].valueB = res.fireSWarnInfo.maxWarnLevel || '';
  261. statisticsList[4].valueT = res.synthesizeSWarnInfo.totalNum || 0;
  262. statisticsList[4].valueB = res.synthesizeSWarnInfo.maxWarnLevel || '';
  263. }
  264. onMounted(async () => {
  265. getEachMineWarnCountInfoList();
  266. });
  267. defineExpose({ setLoading });
  268. </script>
  269. <style scoped lang="less">
  270. @ventSpace: zxm;
  271. :deep(.zxm-table-container) {
  272. max-height: 720px !important;
  273. }
  274. :deep(.ventSpace-table-body) {
  275. height: auto !important;
  276. }
  277. :deep(.zxm-picker) {
  278. height: 30px !important;
  279. }
  280. :deep(.@{ventSpace}-picker-dropdown) {
  281. position: absolute !important;
  282. top: 35px !important;
  283. left: 0 !important;
  284. }
  285. .data-statistics {
  286. height: 200px;
  287. padding: 20px;
  288. margin-top: 90px;
  289. background-color: #0ebbff15;
  290. display: flex;
  291. justify-content: space-between;
  292. align-items: center;
  293. .statistics-box {
  294. display: flex;
  295. flex: 1;
  296. height: 100%;
  297. justify-content: center;
  298. align-items: center;
  299. .left-box {
  300. position: relative;
  301. width: 138px;
  302. height: 100%;
  303. .box-title {
  304. position: absolute;
  305. left: 50%;
  306. bottom: 18px;
  307. transform: translate(-50%, 0);
  308. color: #fff;
  309. }
  310. }
  311. &:nth-child(1) .left-box {
  312. background: url('../../../../assets/images/vent-tf.png') no-repeat center;
  313. background-size: 100% auto;
  314. }
  315. &:nth-child(2) .left-box {
  316. background: url('../../../../assets/images/dust-fc.png') no-repeat center;
  317. background-size: 100% auto;
  318. }
  319. &:nth-child(3) .left-box {
  320. background: url('../../../../assets/images/gas-ws.png') no-repeat center;
  321. background-size: 100% auto;
  322. }
  323. &:nth-child(4) .left-box {
  324. background: url('../../../../assets/images/fire-fz.png') no-repeat center;
  325. background-size: 100% auto;
  326. }
  327. &:nth-child(5) .left-box {
  328. background: url('../../../../assets/images/aqjc.png') no-repeat center;
  329. background-size: 100% auto;
  330. }
  331. .right-box {
  332. position: relative;
  333. width: 215px;
  334. height: 100%;
  335. display: flex;
  336. flex-direction: column;
  337. justify-content: space-around;
  338. align-items: center;
  339. .box-text {
  340. position: relative;
  341. width: 100%;
  342. height: 40px;
  343. color: #fff;
  344. background: url('../../../../assets/images/his-one.png') no-repeat center;
  345. background-size: 100% 100%;
  346. .text-label {
  347. position: absolute;
  348. left: 20px;
  349. top: 50%;
  350. transform: translate(0, -50%);
  351. }
  352. .text-value {
  353. position: absolute;
  354. left: 130px;
  355. top: 50%;
  356. transform: translate(0, -50%);
  357. font-family: 'douyuFont';
  358. }
  359. }
  360. .warning-state {
  361. .text-value {
  362. color: aqua !important;
  363. font-family: 'douyuFont';
  364. }
  365. }
  366. }
  367. }
  368. }
  369. .tab-box {
  370. display: flex;
  371. color: #fff;
  372. position: relative;
  373. top: 11px;
  374. background: linear-gradient(#001325, #012e4f);
  375. :deep(.zxm-tabs-nav) {
  376. margin: 0 !important;
  377. .zxm-tabs-tab {
  378. width: 180px;
  379. height: 45px;
  380. background: url('@/assets/images/top-btn.png') center no-repeat;
  381. background-size: cover;
  382. display: flex;
  383. justify-content: center;
  384. font-size: 16px;
  385. }
  386. .zxm-tabs-tab-active {
  387. width: 180px;
  388. position: relative;
  389. background: url('@/assets/images/top-btn-select.png') center no-repeat;
  390. background-size: cover;
  391. .zxm-tabs-tab-btn {
  392. color: #fff !important;
  393. }
  394. }
  395. .zxm-tabs-ink-bar {
  396. width: 0 !important;
  397. }
  398. .zxm-tabs-tab+.zxm-tabs-tab {
  399. margin: 0 !important;
  400. }
  401. }
  402. }
  403. .alarm-history-table {
  404. width: 100%;
  405. background-color: #0ebbff15;
  406. position: relative;
  407. margin-top: 10px;
  408. &::after {
  409. position: absolute;
  410. content: '';
  411. width: calc(100% + 10px);
  412. height: 2px;
  413. top: 0px;
  414. left: -10px;
  415. border-bottom: 1px solid #0efcff44;
  416. }
  417. }
  418. </style>