| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- <template>
- <div class="fire-monitor">
- <div class="basic-fire-box">
- <div class="box-top">
- <CommonBd title="设备状态总览">
- <CustomGalleryNew :option="option" :galleryData="galleryData"></CustomGalleryNew>
- </CommonBd>
- </div>
- <div class="box-cen">
- <CommonBd title="光谱摄像机">
- <CommonTable
- :columns="deviceColumns"
- :table-data="tableDataGp"
- selectable
- :selected-key="selectedGpId"
- @row-click="onSelectGp"
- ></CommonTable>
- </CommonBd>
- </div>
- <div class="box-bot">
- <CommonBd title="火灾探测器">
- <CommonTable
- :columns="deviceColumns"
- :table-data="tableDataHz"
- selectable
- :selected-key="selectedHzId"
- @row-click="onSelectHz"
- ></CommonTable>
- </CommonBd>
- </div>
- </div>
- <div class="basic-fire-box1">
- <!-- 模型区域 -->
- <div class="model-box">
- <dwgViewer ref="dwgViewerRef" :devices="tableData" />
- </div>
- <!-- <div class="box1-bot">
- <CommonBd title="快捷操作">
- <QuickAction :quick-option="quickOption" :btn-option="btnOption" :quick-data="quickData"></QuickAction>
- </CommonBd>
- </div> -->
- </div>
- <div class="basic-fire-box">
- <div class="box-top1">
- <CommonBd title="报警监控">
- <!-- <AlarmMonitor :option="alarmOption" :cardData="alarmData"></AlarmMonitor> -->
- <AlarmMonitor @locate="locateDeviceOnMap"></AlarmMonitor>
- </CommonBd>
- </div>
- <div class="box-cen1">
- <!-- <CommonBd title="区域温度统计">
- <CustomChart :chart-config="chartTempConfig" :chart-data="chartTempData"></CustomChart>
- </CommonBd> -->
- <CommonBd title="历史温度曲线">
- <HistoryLine :deviceOptions="deviceOptions"></HistoryLine>
- </CommonBd>
- </div>
- <div class="box-bot1">
- <CommonBd title="环境监测数据">
- <EnvironmentMonitor :option="envOption" :environData="envData"></EnvironmentMonitor>
- </CommonBd>
- </div>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { onMounted, onUnmounted, ref, computed, nextTick, onBeforeMount, watch, reactive, inject, Ref } from 'vue';
- import CommonBd from './components/CommonBd.vue';
- import CustomGalleryNew from './components/CustomGalleryNew.vue';
- import CommonTable from './components/CommonTable.vue';
- import AlarmMonitor from './components/AlarmMonitor.vue';
- import HistoryLine from './components/HistoryLine.vue';
- import EnvironmentMonitor from './components/EnvironmentMonitor.vue';
- // import QuickAction from './components/QuickAction.vue';
- import dwgViewer from '../../cad/dwgViewerTest.vue';
- import { option, chartConfig, deviceColumns, quickOption, btnOption, alarmOption, chartTempConfig, } from './hsqHome.data';
- import { managesysList, monitorSystem, deviceList, monitorDevice, getManagesysDeviceNum } from './hsqHome.api';
- /** 当前系统ID */
- let systemId = ref('')
- /** 设备状态总览卡片数据 */
- let galleryData = ref({})
- /** 设备列表表格数据(包含双光谱相机和火灾探测器) */
- let tableData = ref<any[]>([])
- /** 光谱摄像机表格数据 */
- let tableDataGp = ref<any[]>([])
- /** 火灾探测器表格数据 */
- let tableDataHz = ref<any[]>([])
- /** 光谱摄像机当前选中行 */
- const selectedGpId = ref<string | number | null>(null)
- /** 火灾探测器当前选中行 */
- const selectedHzId = ref<string | number | null>(null)
- /** CAD 图纸组件引用 */
- const dwgViewerRef = ref<InstanceType<typeof dwgViewer> | null>(null)
- /** 历史温度曲线设备选项配置 */
- let deviceOptions = ref<any[]>([])
- /** 环境监测设备选项配置 */
- let envOption = ref<any[]>([])
- /** 环境监测数据 */
- let envData = reactive({})
- /** 定时获取监测数据定时器 */
- let timer: null | NodeJS.Timeout = null;
- /** 点击列表行后定位 CAD 图标 */
- function locateDeviceOnMap(deviceID: string | number | null | undefined) {
- if (deviceID == null || deviceID === '') return
- dwgViewerRef.value?.locateIcon?.(deviceID)
- }
- /** 光谱摄像机行点击选中并定位 */
- function onSelectGp(row: any) {
- selectedGpId.value = row?.deviceID ?? null
- locateDeviceOnMap(selectedGpId.value)
- }
- /** 火灾探测器行点击选中并定位 */
- function onSelectHz(row: any) {
- selectedHzId.value = row?.deviceID ?? null
- locateDeviceOnMap(selectedHzId.value)
- }
- /**
- * 定时获取监测数据
- * 通过定时器循环调用数据获取方法,更新表格数据
- *
- * @param flag - 是否立即执行(首次调用时传true跳过延时)
- */
- function getMonitor(flag?: boolean) {
- timer = setTimeout(async () => {
- await getManagesysDeviceNumTj();
- await getTableData();
- await getDeviceMonitor();
- if (timer) {
- timer = null;
- }
- getMonitor();
- }, flag ? 0 : 10000);
- }
- /**
- * 获取管理系统设备数量统计
- * 调用 getManagesysDeviceNum 接口,根据当前系统ID获取设备数量统计信息
- */
- async function getManagesysDeviceNumTj() {
- const res = await getManagesysDeviceNum({ sysId: systemId.value, deviceKinds: "duaSpeCamera" });
- galleryData.value = res || {};
- }
- /**
- * 获取设备列表数据
- *
- * 调用 deviceList 接口获取双光谱相机设备列表,
- * 并将返回数据赋值给 tableData
- */
- async function getTableData() {
- const res = await monitorSystem({ type: 'all', systemID: systemId.value, devicetype: '' });
- tableDataGp.value = (res?.deviceInfo?.duaSpeCamera?.datalist || []).map(el => Object.assign({}, el, el.readData || {}));
- tableDataHz.value = (res?.deviceInfo?.imgFireDet?.datalist || []).map(el => Object.assign({}, el, el.readData || {}));
- tableData.value = tableDataGp.value
- deviceOptions.value = tableDataGp.value.map(v => ({
- label: v.strname,
- value: v.deviceID,
- devicetype: v.deviceType
- }))
- }
- /**
- * 获取环境监测设备数据
- * 调用 monitorDevice 接口,查询指定系统的户外火灾相关监测设备状态
- */
- async function getDeviceMonitor() {
- const res = await monitorDevice({ devicetype: 'sys', systemID: systemId.value, types: 'sys_openair_fire' });
- const sensors = (res?.msgTxt || []).filter((v: any) => String(v?.type || '').indexOf('modelsensor') != -1)
- envOption.value = sensors.map((el: any) => {
- const first = el?.datalist?.[0] || {}
- const readData = first.readData || {}
- return {
- label: first.typeName || '-',
- value: Object.keys(readData).filter((v) => v.endsWith('val') || v.endsWith('ture'))[0] || '',
- unit: first.typeName == '温度传感器' ? '℃' : first.typeName == '氧气传感器' ? '%' : first.typeName == 'CO传感器' ? 'ppm' : first.typeName == '瓦斯传感器' ? '%' : first.typeName == '烟雾传感器' ? '' : ''
- }
- })
- // 保持 reactive 引用,避免整体替换导致子组件不更新
- Object.keys(envData).forEach((key) => delete (envData as any)[key])
- const merged = Object.assign({}, ...sensors.map((el: any) => el?.datalist?.[0]?.readData || {}))
- Object.assign(envData, merged)
- }
- /**
- * 获取管理系统列表
- * 调用 managesysList 接口获取户外火灾相关系统列表,并取第一个系统ID作为当前系统
- */
- async function getManagesysList() {
- const res = await managesysList({ strtype: 'sys_openair_fire', pagetype: 'normal' });
- if (res && res.records) {
- systemId.value = res.records[0].id
- }
- }
- /**
- * 组件挂载完成
- * 先获取管理系统列表初始化系统ID,然后立即启动定时获取监测数据
- */
- onMounted(async () => {
- await getManagesysList();
- getMonitor(true);
- });
- /**
- * 组件卸载前
- * 清理定时器,停止轮询获取监测数据
- */
- onUnmounted(() => {
- if (timer) clearTimeout(timer);
- timer = null;
- });
- </script>
- <style lang="less" scoped>
- @import '/@/design/theme.less';
- .fire-monitor {
- position: relative;
- width: 100%;
- height: calc(100% - 10px);
- color: @white;
- margin-bottom: 10px;
- display: flex;
- justify-content: space-between;
- .basic-fire-box {
- width: 430px;
- height: 100%;
- &:nth-child(1) {
- margin-right: 10px;
- }
- &:nth-child(3) {
- margin-left: 10px;
- }
- }
- .basic-fire-box1 {
- position: relative;
- width: calc(100% - 880px);
- height: 100%;
- }
- .model-box {
- position: absolute;
- top: 63px;
- left: 0;
- width: 100%;
- // height: 615px;
- height: calc(100% - 63px);
- border: 1px solid rgba(40, 165, 232, 0.8);
- // margin-bottom: 10px;
- }
- .box1-bot {
- position: absolute;
- bottom: 0px;
- left: 0;
- width: 100%;
- height: 155px;
- }
- .box-top {
- height: 185px;
- margin-bottom: 10px;
- }
- .box-top1 {
- height: 360px;
- margin-bottom: 10px;
- }
- .box-cen {
- height: 310px;
- margin-bottom: 10px;
- }
- .box-cen1 {
- height: 220px;
- margin-bottom: 10px;
- }
- .box-bot {
- height: 335px;
- }
- .box-bot1 {
- height: 250px;
- }
- }
- :deep(.loading-box) {
- position: unset;
- }
- </style>
|