Files
admin-govern/src/views/govern/device/control/index.vue
2024-10-17 14:08:58 +08:00

987 lines
39 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div
class="default-main device-control"
:style="{ height: pageHeight.height }"
v-loading="loading"
style="position: relative"
>
<PointTree @node-click="nodeClick" @init="nodeClick" @pointTypeChange="pointTypeChange"></PointTree>
<div class="device-control-right" v-if="deviceData">
<el-descriptions title="设备基本信息" class="mb10" :column="3" border>
<template #extra>
<!-- <el-button v-if="deviceType == '1'" type="primary" @click="handleDownLoadTemplate">
模版下载
</el-button> -->
<el-button v-if="deviceType == '1'" type="primary" icon="el-icon-Connection" @click="handleImport">
离线补召
</el-button>
<el-button v-if="deviceType == '1'" type="primary" icon="el-icon-Monitor" @click="handleaddDevice">
在线补召
</el-button>
<el-button
v-if="deviceType == '1'"
type="primary"
icon="el-icon-Tickets"
@click="handleAnalysisList"
>
补召日志
</el-button>
</template>
<el-descriptions-item label="名称">
{{ deviceData.name ? deviceData.name : '/' }}
</el-descriptions-item>
<el-descriptions-item label="类型">
{{ echoName(deviceData.devType, devTypeOptions) }}
</el-descriptions-item>
<el-descriptions-item label="接入方式">
{{ deviceData.devAccessMethod ? deviceData.devAccessMethod : '/' }}
</el-descriptions-item>
<el-descriptions-item label="网络设备ID">
{{ deviceData.ndid ? deviceData.ndid : '/' }}
</el-descriptions-item>
<el-descriptions-item label="型号">
{{ echoName(deviceData.devModel, devModelOptions) }}
</el-descriptions-item>
<el-descriptions-item label="接入日期">
{{ deviceData.time ? deviceData.time : '/' }}
</el-descriptions-item>
</el-descriptions>
<el-tabs v-model="dataSet" type="border-card" class="device-control-box-card" @tab-click="handleClick">
<el-tab-pane
lazy
:label="item.name"
:name="item.id"
v-for="(item, index) in deviceData.dataSetList"
:key="index"
>
<template #label>
<span class="custom-tabs-label">
<el-icon>
<TrendCharts v-if="item.name == 'APF模块数据'" />
<DataLine v-if="item.name == '历史APF模块数据'" />
<DataAnalysis v-if="item.name.includes('趋势数据')" />
<Timer v-if="item.name.includes('实时数据')" />
<Monitor v-if="item.name.includes('暂态事件')" />
<Odometer
v-if="
item.name != 'APF模块数据' &&
item.name != '历史APF模块数据' &&
!item.name.includes('历史监测') &&
!item.name.includes('趋势数据') &&
!item.name.includes('实时数据') &&
!item.name.includes('暂态事件')
"
/>
<Histogram
v-if="
item.name != 'APF模块数据' &&
item.name != '历史APF模块数据' &&
item.name.includes('历史监测') &&
!item.name.includes('趋势数据') &&
!item.name.includes('实时数据') &&
!item.name.includes('暂态事件')
"
/>
</el-icon>
<span>{{ item.name }}</span>
</span>
</template>
</el-tab-pane>
<TableHeader
:showSearch="false"
:key="mqttMessage"
v-if="
(dataSet.indexOf('_trenddata') == -1 &&
dataSet.indexOf('_realtimedata') == -1 &&
dataSet.indexOf('_event') == -1) ||
realTimeFlag
"
>
<template #select>
<el-form-item label="日期" v-show="dataSet.indexOf('_history') != -1">
<DatePicker ref="datePickerRef"></DatePicker>
</el-form-item>
<el-form-item label="指标" v-show="!realTimeFlag">
<el-input
style="width: 160px"
v-model="formInline.searchValue"
autocomplete="off"
clearable
placeholder="请输入关键词"
></el-input>
</el-form-item>
<el-form-item v-if="mqttMessage.dataTime" label="数据时间">
{{ mqttMessage.dataTime }}
</el-form-item>
<el-form-item label="值类型">
<el-select
style="width: 160px !important"
v-model="formInline.dataLevel"
:disabled="dataLevel == 'Primary' && deviceType == '0'"
>
<el-option value="Primary" label="一次值"></el-option>
<el-option value="Secondary" label="二次值"></el-option>
</el-select>
</el-form-item>
</template>
<template #operation>
<el-button type="primary" icon="el-icon-Search" @click="handleClick">查询</el-button>
<el-button type="primary" v-if="realTimeFlag" :icon="DataLine" @click="handleTrend">
谐波频谱
</el-button>
<el-button
type="primary"
v-if="realTimeFlag"
:icon="TrendCharts"
@click="handleHarmonicSpectrum"
>
实时趋势
</el-button>
</template>
</TableHeader>
<div
style="height: calc(100vh - 300px)"
v-if="
dataSet.indexOf('_trenddata') == -1 &&
dataSet.indexOf('_realtimedata') == -1 &&
dataSet.indexOf('_event') == -1 &&
tableData.length == 0
"
v-loading="tableLoading"
></div>
<div
style="overflow: auto"
:style="{ height: tableHeight }"
v-if="
dataSet.indexOf('_trenddata') == -1 &&
dataSet.indexOf('_realtimedata') == -1 &&
dataSet.indexOf('_event') == -1 &&
tableData.length != 0
"
>
<!-- 循环渲染的card 最新数据/历史数据显示 -->
<div class="content" v-loading="tableLoading">
<el-card class="box-card" v-for="(item, index) in tableData" :key="index">
<template #header>
<div class="clearfix">
<span style="flex: 1">{{ item.name }}</span>
<Icon
name="el-icon-TrendCharts"
class="ml10"
@click="getDeviceDataTrend(item)"
style="font-size: 26px; cursor: pointer; color: #fff"
></Icon>
</div>
</template>
<!-- 模块数据 -->
<div class="box-card-content" v-if="dataSet.indexOf('_history') == -1">
<div v-for="(child, childIndex) in item.children" :key="childIndex">
{{ child.anotherName }}:
{{ child.dataValue === 3.1415926 ? '暂无数据' : child.dataValue }}
</div>
<div class="mt10">
统计时间:{{ item.children.length ? item.children[0].time : '' }}
</div>
</div>
<div v-else-if="item.children.length">
<div style="display: flex; align-items: center">
<el-tag
effect="dark"
type="danger"
style="width: 40px; text-align: center"
class="mr10"
>
MAX
</el-tag>
{{
item.children[0].maxValue === 3.1415956 ||
typeof item.children[0].maxValue != 'number'
? '暂无数据'
: item.children[0].maxValue
}}
</div>
<div style="display: flex; align-items: center" class="mt10">
<el-tag
effect="dark"
type="success"
style="width: 40px; text-align: center"
class="mr10"
>
AVG
</el-tag>
{{
item.children[0].avgValue === 3.1415956 ||
typeof item.children[0].avgValue != 'number'
? '暂无数据'
: item.children[0].avgValue
}}
</div>
<div style="display: flex; align-items: center" class="mt10">
<el-tag
effect="dark"
type="warning"
style="width: 40px; text-align: center"
class="mr10"
>
MIN
</el-tag>
{{
item.children[0].minValue === 3.1415956 ||
typeof item.children[0].minValue != 'number'
? '暂无数据'
: item.children[0].minValue
}}
</div>
</div>
</el-card>
<el-empty description="暂无数据" v-if="tableData.length === 0"></el-empty>
</div>
</div>
<el-pagination
v-if="
tableData.length &&
dataSet.indexOf('_trenddata') == -1 &&
dataSet.indexOf('_realtimedata') == -1 &&
dataSet.indexOf('_event') == -1
"
background
class="mr2 mt10"
style="float: right"
@size-change="handleSizeChange"
@current-change="pageChange"
:current-page="formInline.pageNum"
:page-sizes="[20, 30, 40, 50, 100]"
:page-size="formInline.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="formInline.total"
></el-pagination>
<!-- 趋势数据 -->
<div
style="height: calc(100vh - 340px)"
v-if="dataSet.indexOf('_trenddata') != -1"
v-loading="tableLoading"
>
<Trend ref="trendRef"></Trend>
</div>
<!-- 实时数据 -->
<div
style="height: calc(100vh - 340px)"
v-if="dataSet.indexOf('_realtimedata') != -1"
v-loading="tableLoading"
>
<!-- <div class="view_top_btn" v-if="realTimeFlag">
<el-button type="primary" :icon="Platform" @click="handleRecordWaves">
实时录波
</el-button>
</div> -->
<div class="view_top_btn" v-if="!realTimeFlag">
<el-button :icon="Back" @click="handleReturn">返回</el-button>
</div>
<!-- 实时数据主界面组件 -->
<realTime v-if="realTimeFlag" ref="realTimeRef"></realTime>
<!-- 实时数据-实时录波组件 -->
<recordWoves v-if="!realTimeFlag && sonTab == 0"></recordWoves>
<!-- 实时数据-实时趋势组件 -->
<realTrend
v-show="!realTimeFlag && sonTab == 1"
ref="realTrendRef"
@changeTrendType="changeTrendType"
></realTrend>
<!-- 实时数据-谐波频谱组件 -->
<harmonicSpectrum
v-show="!realTimeFlag && sonTab == 2"
ref="harmonicSpectrumRef"
></harmonicSpectrum>
</div>
<!-- 暂态事件 -->
<div
style="height: calc(100vh - 340px)"
v-if="dataSet.indexOf('_event') != -1"
v-loading="tableLoading"
>
<Event ref="eventRef"></Event>
</div>
<div v-if="!tableData" style="height: 42px"></div>
</el-tabs>
</div>
<el-empty v-else description="请选择设备" class="device-control-right" />
<Detail ref="detailRef" :detail="detail" @close="detail = null" :dataLevel="dataLevel" v-if="detail"></Detail>
<!-- 离线数据导入组件 -->
<offLineDataImport ref="offLineDataImportRef"></offLineDataImport>
<!-- 补召日志 -->
<analysisList ref="analysisListRef"></analysisList>
</div>
</template>
<script setup lang="ts">
import Detail from './detail.vue'
import PointTree from '@/components/tree/govern/pointTree.vue'
import { mainHeight } from '@/utils/layout'
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
import {
getDeviceData,
getTabsDataByType,
getBasicRealData,
getHarmRealData,
getOverLimitData
} from '@/api/cs-device-boot/EquipmentDelivery'
import { deviceHisData, deviceRtData, getGroup } from '@/api/cs-device-boot/csGroup'
import { ref, reactive, nextTick, onMounted, watch, onUnmounted, inject } from 'vue'
import { ElMessage } from 'element-plus'
import DatePicker from '@/components/form/datePicker/index.vue'
import Trend from './tabs/trend.vue' //趋势数据
import realTime from './tabs/realtime.vue' //实时数据-主界面
import realTrend from './tabs/components/realtrend.vue' //实时数据-实时趋势
import harmonicSpectrum from './tabs/components/harmonicSpectrum.vue' //实时数据-谐波频谱子页面
import recordWoves from './tabs/components/recordwoves.vue' //实时数据-实时录波子页面
import offLineDataImport from './offLineDataImport/index.vue'
import Event from './tabs/event.vue'
import { useRouter } from 'vue-router'
import TableHeader from '@/components/table/header/index.vue'
import { defineConfig, loadEnv } from 'vite'
import type { UserConfig, ConfigEnv } from 'vite'
import {
Platform,
Histogram,
TrendCharts,
DataLine,
ArrowLeft,
DataAnalysis,
Odometer,
Monitor,
Timer,
Back
} from '@element-plus/icons-vue'
import analysisList from './analysisList/index.vue'
import mqtt from 'mqtt'
defineOptions({
name: 'govern/device/control'
})
const pageHeight = mainHeight(20)
const loading = ref(true)
const tableLoading = ref(false)
const getGroupLoading = ref(false)
const deviceData = ref<any>(null)
const dataSet = ref('')
const devTypeOptions = ref([])
const devModelOptions = ref([])
const tableData = ref<any[]>([])
const tableHeight = mainHeight(330).height
const mangePopup = ref()
const datePickerRef = ref()
const formInline = reactive({
searchValue: '',
pageNum: 1,
pageSize: 20,
total: 0,
startTime: '',
endTime: '',
id: '',
lineId: '',
dataLevel: 'Secondary'
})
const detail = ref<any>(null)
//是否显示实时数据默认内容
const realTimeFlag = ref(true)
//实时数据子菜单
const sonTab = ref()
//实时录波
const handleRecordWaves = () => {
realTimeFlag.value = false
sonTab.value = 0
window.clearInterval(timer.value)
}
//谐波频谱
const realTrendRef = ref()
const changeTrendType = (val: any) => {
activeTrendName.value = val * 1
handleTrend()
}
//谐波频谱
const activeTrendName: any = ref(0)
const handleTrend = async () => {
realTimeFlag.value = false
sonTab.value = 1
clearInterval(timer.value)
clearInterval(realDataTimer.value)
await getHarmRealData(lineId.value, activeTrendName.value).then((res: any) => {
if (res.code == 'A0000') {
ElMessage.success('装置应答成功')
mqttRef.value.on('message', (topic: any, message: any) => {
// console.log('mqtt接收到消息', message,topic)
console.log('mqtt接收到消息', JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message)))))
let obj = JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message)))) || {}
realTrendRef.value && realTrendRef.value.setRealTrendData(obj)
})
} else {
ElMessage.success('装置应答失败')
}
})
await getOverLimitData(lineId.value).then((res: any) => {
console.log(res, '获取国标限制')
if (res.code == 'A0000') {
realTrendRef.value && realTrendRef.value.setOverLimitData(res.data)
}
})
realTrendRef.value &&
realTrendRef.value.open({ devId: deviceId.value, lineId: lineId.value, activeTrendName: activeTrendName.value })
}
//实时趋势
const harmonicSpectrumRef = ref()
//实时趋势
const handleHarmonicSpectrum = () => {
realTimeFlag.value = false
// harmonicSpectrumRef.value &&
// harmonicSpectrumRef.value.getHarmonicSpectrumParams({ devId: deviceId.value, lineId: lineId.value })
window.clearInterval(timer.value)
clearInterval(realDataTimer.value)
realTimeFlag.value = false
sonTab.value = 2
harmonicSpectrumRef.value && harmonicSpectrumRef.value.resetData()
getRealDataMqttMsg()
}
//返回
const handleReturn = () => {
realTimeFlag.value = true
sonTab.value = null
handleClick()
}
const getDeviceDataTrend = (e: any) => {
detail.value = {
devId: deviceId.value,
lineId: lineId.value,
dataLevel: dataLevel.value,
...e
}
}
const pageChange = (e: number) => {
formInline.pageNum = e
handleClick()
}
const handleSizeChange = (val: number) => {
formInline.pageNum = 1
formInline.pageSize = val
handleClick()
}
const { push, options, currentRoute } = useRouter()
//设备补召
const handleaddDevice = () => {
push({
path: '/supplementaryRecruitment',
query: {
id: lineId.value,
ndid: deviceData.value.ndid
}
})
}
//树节点点击事件
const deviceId: any = ref('')
const lineId: any = ref('')
const dataLevel: any = ref('')
const nodeClick = async (e: anyObj) => {
deviceId.value = e?.pid
lineId.value = e?.id
if (!e) {
loading.value = false
return
}
if (e.level == 3) {
loading.value = true
formInline.lineId = e.id
await getDeviceData(e.pid, 'history', e.id)
.then((res: any) => {
deviceData.value = res.data
formInline.dataLevel = res.data.dataLevel
dataLevel.value = res.data.dataLevel
if (dataLevel.value == 'Secondary') {
formInline.dataLevel = 'Primary'
}
if (!res.data.dataSetList) {
dataSet.value = ''
tableData.value = []
loading.value = false
} else {
res.data.dataSetList.forEach((item: any) => {
//历史
if (item.type === 'history') {
item.id = item.id + '_history'
}
//趋势数据
if (item.type === 'trenddata') {
item.id = item.id + '_trenddata'
}
//实时数据
if (item.type === 'realtimedata') {
item.id = item.id + '_realtimedata'
}
//暂态事件
if (item.type === 'event') {
item.id = item.id + '_event'
}
})
//便携式设备默认二次值
// if (deviceType.value == '1') {
// formInline.dataLevel = 'Primary'
// }
dataSet.value = res.data.dataSetList[0].id
handleClick()
}
loading.value = false
})
.catch(e => {
loading.value = false
})
} else {
loading.value = false
}
}
//治理设备和便携式设备切换判断
const deviceType = ref('0')
const pointTypeChange = (val: any, obj: any) => {
deviceType.value = val
nodeClick(obj)
}
const realTimeRef: any = ref()
//趋势数据组件
const trendRef: any = ref()
//暂态事件组件
const eventRef: any = ref()
const timer: any = ref()
const mqttRef = ref()
const url: any = inject('MQTTURL')
const connectMqtt = () => {
if (mqttRef.value) {
if (mqttRef.value.connected) {
return
}
}
const options: any = {
protocolId: 'MQTT',
qos: 2,
clean: true,
connectTimeout: 30 * 1000,
clientId: 'mqttjs' + Math.random(),
username: 't_user',
password: 'njcnpqs'
}
mqttRef.value = mqtt.connect(url, options)
}
const getRealDataMqttMsg = async () => {
clearInterval(timer.value)
clearInterval(realDataTimer.value)
//新的实时数据
//1.调用接口 mqtt推送数据
await getBasicRealData(lineId.value).then((res: any) => {
if (res.code == 'A0000') {
ElMessage.success('装置应答成功')
//2.建立mqtt通讯
//每隔30s调用一下接口通知后台推送mqtt消息
realDataTimer.value = setInterval(() => {
getBasicRealData(lineId.value).then((res: any) => {
console.log(res, '获取基础实时数据')
})
}, 30000)
connectMqtt()
mqttRef.value.on('connect', (e: any) => {
// ElMessage.success('连接mqtt服务器成功!')
console.log('mqtt客户端已连接....')
// mqttRef.value.subscribe('/Web/Progress')
mqttRef.value.subscribe('/Web/RealData/+')
//假数据
})
mqttRef.value.on('message', (topic: any, message: any) => {
mqttMessage.value = {}
// console.log('mqtt接收到消息', message,topic)
console.log('mqtt接收到消息', JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message)))))
let obj = JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message))))
//处理mqtt数据 1转2除 2转1乘
//如果消息返回值是二次值,下拉框是二次值只需要单位换算 除以1000
//如果消息返回值是一次值,下拉框是一次值只需要单位换算 除以1000
if (obj.dataLevel == formInline.dataLevel) {
obj = {
...obj,
// 电压有效值
vRmsA: obj.vRmsA / 1000,
vRmsB: obj.vRmsB / 1000,
vRmsC: obj.vRmsC / 1000,
//基波电压幅值
v1A: obj.v1A / 1000,
v1B: obj.v1B / 1000,
v1C: obj.v1C / 1000,
//有功功率
pA: obj.pA / 1000,
pB: obj.pB / 1000,
pC: obj.pC / 1000,
pTot: obj.pTot / 1000,
//无功功率
qA: obj.qA / 1000,
qB: obj.qB / 1000,
qC: obj.qC / 1000,
qTot: obj.qTot / 1000,
//视在功率
sA: obj.sA / 1000,
sB: obj.sB / 1000,
sC: obj.sC / 1000,
sTot: obj.sTot / 1000
}
}
//如果消息返回值是二次值,下拉框是一次值需要单位换算 除以1000 并且乘以pt ct
if (obj.dataLevel == 'Secondary' && formInline.dataLevel == 'Primary') {
obj = {
...obj,
// 电压有效值
vRmsA: (obj.vRmsA * obj.pt) / 1000,
vRmsB: (obj.vRmsA * obj.pt) / 1000,
vRmsC: (obj.vRmsA * obj.pt) / 1000,
// 电流有效值
iRmsA: obj.iRmsA * obj.ct,
iRmsB: obj.iRmsA * obj.ct,
iRmsC: obj.iRmsA * obj.ct,
//基波电压幅值
v1A: (obj.v1A * obj.pt) / 1000,
v1B: (obj.v1B * obj.pt) / 1000,
v1C: (obj.v1C * obj.pt) / 1000,
//基波电流幅值
i1A: obj.i1A * obj.ct,
i1B: obj.i1B * obj.ct,
i1C: obj.i1C * obj.ct,
//有功功率
pA: (obj.pA * obj.pt * obj.ct) / 1000,
pB: (obj.pB * obj.pt * obj.ct) / 1000,
pC: (obj.pC * obj.pt * obj.ct) / 1000,
pTot: (obj.pTot * obj.pt * obj.ct) / 1000,
//无功功率
qA: (obj.qA * obj.pt * obj.ct) / 1000,
qB: (obj.qB * obj.pt * obj.ct) / 1000,
qC: (obj.qC * obj.pt * obj.ct) / 1000,
qTot: (obj.qTot * obj.pt * obj.ct) / 1000,
//视在功率
sA: (obj.sA * obj.pt * obj.ct) / 1000,
sB: (obj.sB * obj.pt * obj.ct) / 1000,
sC: (obj.sC * obj.pt * obj.ct) / 1000,
sTot: (obj.sTot * obj.pt * obj.ct) / 1000
}
}
//如果消息返回值是一次值,下拉框是二次值需要单位换算 乘以1000 并且除以pt ct
if (obj.dataLevel == 'Primary' && formInline.dataLevel == 'Secondary') {
obj = {
...obj,
// 电压有效值
vRmsA: (obj.vRmsA / obj.pt) * 1000,
vRmsB: (obj.vRmsA / obj.pt) * 1000,
vRmsC: (obj.vRmsA / obj.pt) * 1000,
// 电流有效值
iRmsA: obj.iRmsA / obj.ct,
iRmsB: obj.iRmsA / obj.ct,
iRmsC: obj.iRmsA / obj.ct,
//基波电压幅值
v1A: (obj.v1A / obj.pt) * 1000,
v1B: (obj.v1B / obj.pt) * 1000,
v1C: (obj.v1C / obj.pt) * 1000,
//基波电流幅值
i1A: obj.i1A / obj.ct,
i1B: obj.i1B / obj.ct,
i1C: obj.i1C / obj.ct,
//有功功率
pA: (obj.pA / obj.pt / obj.ct) * 1000,
pB: (obj.pB / obj.pt / obj.ct) * 1000,
pC: (obj.pC / obj.pt / obj.ct) * 1000,
pTot: (obj.pTot / obj.pt / obj.ct) * 1000,
//无功功率
qA: (obj.qA / obj.pt / obj.ct) * 1000,
qB: (obj.qB / obj.pt / obj.ct) * 1000,
qC: (obj.qC / obj.pt / obj.ct) * 1000,
qTot: (obj.qTot / obj.pt / obj.ct) * 1000,
//视在功率
sA: (obj.sA / obj.pt / obj.ct) * 1000,
sB: (obj.sB / obj.pt / obj.ct) * 1000,
sC: (obj.sC / obj.pt / obj.ct) * 1000,
sTot: (obj.sTot / obj.pt / obj.ct) * 1000
}
}
//保留两位小数
for (var i in obj) {
if (typeof obj[i] == 'number' && obj[i] != 0 && Math.abs(obj[i]) % 1 != 0) {
obj[i] = obj[i].toFixed(2)
}
}
mqttMessage.value = obj
//更新实时数据值
realTimeFlag.value && realTimeRef.value && realTimeRef.value.setRealData(mqttMessage.value)
//更新谐波频谱数据
!realTimeFlag.value &&
sonTab.value == 2 &&
harmonicSpectrumRef.value &&
harmonicSpectrumRef.value.setHarmonicSpectrumData(mqttMessage.value)
})
mqttRef.value.on('error', (error: any) => {
console.log('mqtt连接失败...', error)
mqttRef.value.end()
})
mqttRef.value.on('close', function () {
console.log('mqtt客户端已断开连接.....')
})
} else {
ElMessage.success('装置应答失败')
}
})
}
//tab点击事件
const realDataTimer: any = ref()
const mqttMessage = ref<any>({})
const handleClick = async (tab?: any) => {
if (realDataTimer.value) {
window.clearInterval(realDataTimer.value)
}
tableLoading.value = true
//点击tab时更新dataSet最新值
if (tab && tab.props && tab.props.name && dataSet.value != tab.props.name) {
dataSet.value = tab.props.name
}
//初始化点击tab隐藏实时录波、实时趋势、谐波频谱按钮
realTimeFlag.value = false
//初始化点击tab隐藏子页面
sonTab.value = null
if (tab) {
tableData.value = []
formInline.pageNum = 1
}
if (timer.value) {
window.clearInterval(timer.value)
}
//查询历史指标
if (dataSet.value.includes('_history')) {
formInline.startTime = datePickerRef.value && datePickerRef.value.timeValue[0]
formInline.endTime = datePickerRef.value && datePickerRef.value.timeValue[1]
formInline.id = dataSet.value.replace('_history', '')
await deviceHisData(formInline)
.then((res: any) => {
tableData.value = res.data.records
formInline.total = res.data.total
setTimeout(() => {
tableLoading.value = false
}, 1500)
})
.catch(e => {
setTimeout(() => {
tableLoading.value = false
}, 1500)
})
}
//查询趋势数据
if (dataSet.value.includes('_trenddata')) {
let obj = {
devId: deviceId.value, //e.id
lineId: lineId.value, //e.pid
type: 1,
list: [
{
lineId: lineId.value,
devId: dataSet.value.replace('_trenddata', '')
}
]
// startTime: datePickerRef.value && datePickerRef.value.timeValue[0],
// endTime: datePickerRef.value && datePickerRef.value.timeValue[1]
}
setTimeout(() => {
trendRef.value && trendRef.value.getTrendRequest(obj)
tableLoading.value = false
}, 1500)
}
//查询实时数据
if (dataSet.value.includes('_realtimedata')) {
//查询实时数据显示实时录波、实时趋势、谐波频谱
realTimeFlag.value = true
setTimeout(() => {
tableLoading.value = false
}, 1500)
getRealDataMqttMsg()
}
//查询暂态事件
if (dataSet.value.includes('_event')) {
let obj = {
devId: deviceId.value, //e.id
lineId: lineId.value, //e.pid
type: 3,
list: [
{
lineId: lineId.value,
devId: dataSet.value.replace('_event', '')
}
]
}
setTimeout(() => {
//暂态事件表格请求参数
eventRef.value && eventRef.value.getTableParams(obj)
tableLoading.value = false
}, 1500)
}
//查询当前指标
if (!dataSet.value.includes('_')) {
formInline.id = dataSet.value
await deviceRtData(formInline)
.then((res: any) => {
tableData.value = res.data.records
formInline.total = res.data.total
tableLoading.value = false
setTimeout(() => {
loading.value = false
}, 1500)
})
.catch(e => {
setTimeout(() => {
tableLoading.value = false
}, 1500)
})
}
if (!dataSet.value.includes('_realtimedata')) {
clearInterval(timer.value)
clearInterval(realDataTimer.value)
if (mqttRef.value) {
mqttRef.value.end()
}
}
}
//模版下载
const handleDownLoadTemplate = () => {}
//补召日志
const analysisListRef = ref()
//打开补召日志
const handleAnalysisList = () => {
analysisListRef.value && analysisListRef.value.open()
}
//离线数据导入
const offLineDataImportRef = ref()
const handleImport = () => {
//设备devId&监测点lineId带入组件
offLineDataImportRef.value && offLineDataImportRef.value.open(deviceId.value, lineId.value)
}
queryByCode('Device_Type').then(res => {
queryCsDictTree(res.data.id).then(res => {
devTypeOptions.value = res.data.map((item: any) => {
return {
value: item.id,
label: item.name,
...item
}
})
})
queryByid(res.data.id).then(res => {
devModelOptions.value = res.data.map((item: any) => {
return {
value: item.id,
label: item.name,
...item
}
})
})
})
const echoName = (value: any, arr: any[]) => {
return value ? arr.find(item => item.value == value)?.label : '/'
}
onMounted(() => {})
onUnmounted(() => {
clearInterval(timer.value)
clearInterval(realDataTimer.value)
})
</script>
<style lang="scss">
.device-control {
display: flex;
&-right {
overflow: hidden;
flex: 1;
padding: 10px 10px 10px 0;
.el-descriptions__header {
height: 36px;
margin-bottom: 7px;
display: flex;
align-items: center;
}
.content {
box-sizing: border-box;
overflow: auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-template-rows: max-content;
grid-gap: 10px;
justify-content: center;
.box-card {
display: flex;
flex-direction: column;
justify-content: space-between;
color: var(--el-color-white);
min-height: 150px;
font-size: 13px;
.el-card__header {
padding: 0;
.clearfix {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
height: 35px;
padding: 0 10px;
background: var(--el-color-primary);
}
}
.el-card__body {
flex: 1;
padding: 10px;
margin-bottom: 0;
background-image: linear-gradient(var(--el-color-primary), var(--el-color-primary-light-3));
.box-card-content {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
}
}
}
}
.view_top_btn {
width: 100%;
height: 40px;
display: flex;
align-items: center;
justify-content: flex-end;
}
.custom-tabs-label {
display: flex;
align-items: center;
justify-content: space-between;
.el-icon {
margin-right: 5px;
}
}
.el-form {
width: 100%;
height: auto;
display: flex;
flex-wrap: wrap;
}
</style>