Files
admin-govern/src/views/govern/device/control/index.vue
2024-01-29 14:57:49 +08:00

355 lines
14 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">
<PointTree @node-click="nodeClick" @init="nodeClick"></PointTree>
<div class="device-control-right" v-if="deviceData">
<el-descriptions title="设备基本信息" class="mb10" :column="3" border>
<el-descriptions-item label="名称">
{{ deviceData.name }}
</el-descriptions-item>
<el-descriptions-item label="类型">
{{ echoName(deviceData.devType, devTypeOptions) }}
</el-descriptions-item>
<el-descriptions-item label="接入方式">
{{ deviceData.devAccessMethod }}
</el-descriptions-item>
<el-descriptions-item label="识别码">
{{ deviceData.ndid }}
</el-descriptions-item>
<el-descriptions-item label="型号">
{{ echoName(deviceData.devModel, devModelOptions) }}
</el-descriptions-item>
<el-descriptions-item label="接入时间">
{{ deviceData.time }}
</el-descriptions-item>
</el-descriptions>
<el-tabs v-model="dataSet" type="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"
></el-tab-pane>
<el-form :inline="true" style="white-space: nowrap; margin-top: 10px">
<el-form-item label="指标">
<el-input
v-model="formInline.searchValue"
autocomplete="off"
clearable
placeholder="请输入关键词"
></el-input>
</el-form-item>
<el-form-item label="日期" v-if="dataSet.indexOf('_history') > -1">
<DatePicker ref="datePickerRef"></DatePicker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-Search" @click="handleClick">查询</el-button>
</el-form-item>
</el-form>
<div style="overflow: auto" :style="{ height: tableHeight }" v-loading="tableLoading">
<div class="content">
<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 ? '暂无数据' : 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 ? '暂无数据' : 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 ? '暂无数据' : 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"
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>
</el-tabs>
</div>
<el-empty v-else description="请选择设备" class="device-control-right" />
<Popup ref="popupRef" />
</div>
</template>
<script setup lang="ts">
import Popup from './popup.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 } from '@/api/cs-device-boot/EquipmentDelivery'
import { deviceHisData, deviceRtData } from '@/api/cs-device-boot/csGroup'
import { getGroup } from '@/api/cs-device-boot/csGroup'
import { ref, reactive, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import DatePicker from '@/components/form/datePicker/index.vue'
defineOptions({
name: 'govern/device/control'
})
const popupRef = ref()
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(310).height
const mangePopup = ref()
const datePickerRef = ref()
const formInline = reactive({
searchValue: '',
pageNum: 1,
pageSize: 30,
total: 0,
startTime: '',
endTime: '',
id: '',
lineId: ''
})
const getDeviceDataTrend = (e: any) => {
popupRef.value.open(e.name, {
...e,
lineId: formInline.lineId
})
}
const pageChange = (e: number) => {
formInline.pageNum = e
handleClick()
}
const handleSizeChange = (val: number) => {
formInline.pageNum = 1
formInline.pageSize = val
handleClick()
}
const nodeClick = (e: anyObj) => {
if (!e) {
loading.value = false
return
}
if (e.level == 3) {
loading.value = true
getDeviceData(e.pid, 'history', e.id).then((res: any) => {
res.data.dataSetList.forEach((item: any) => {
if (item.type === 'history') {
item.id = item.id + '_history'
}
})
deviceData.value = res.data
if (res.data.dataSetList.length === 0) {
dataSet.value = ''
tableData.value = []
} else {
dataSet.value = res.data.dataSetList[0].id
handleClick()
}
loading.value = false
})
formInline.lineId = e.id
}
}
const handleClick = (tab?: any) => {
tableLoading.value = true
if (tab) {
tableData.value = []
formInline.pageNum = 1
}
setTimeout(() => {
if (dataSet.value.indexOf('_history') > -1) {
formInline.startTime = datePickerRef.value.timeValue[0]
formInline.endTime = datePickerRef.value.timeValue[1]
formInline.id = dataSet.value.replace('_history', '')
deviceHisData(formInline).then((res: any) => {
console.log(res)
tableData.value = res.data.records
formInline.total = res.data.total
tableLoading.value = false
})
} else {
formInline.id = dataSet.value
deviceRtData(formInline).then((res: any) => {
tableData.value = res.data.records
formInline.total = res.data.total
tableLoading.value = false
})
}
}, 100)
}
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 arr.find(item => item.value == value).label
}
const openGroup = () => {
if (!dataSet.value) {
return ElMessage.warning('暂无数据')
}
getGroupLoading.value = true
getGroup(dataSet.value).then((res: any) => {
const call = (data: any[]) => {
data.forEach(item => {
item.label = item.name
item.isShow = item.isShow == 1
if (item.children && item.children.length > 0) {
call(item.children)
}
})
}
call(res.data)
getGroupLoading.value = false
mangePopup.value.open({
deviceData: deviceData.value,
dataSetName: deviceData.value.dataSetList.filter((item: any) => item.id == dataSet.value)[0]?.name,
dataSet: dataSet.value,
tree: res.data
})
})
}
</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;
}
}
}
}
}
}
</style>