添加工程树

This commit is contained in:
guanj
2026-03-06 09:36:42 +08:00
parent 3fdb41c468
commit 1171d37a86
22 changed files with 1757 additions and 1249 deletions

View File

@@ -142,3 +142,11 @@ export function getModuleState(data?: any) {
params: data
})
}
//获取运行取数
export function getRawData(data?: any) {
return createAxios({
url: '/cs-device-boot/pqsCommunicate/getRawData',
method: 'POST',
data
})
}

View File

@@ -1,18 +1,20 @@
import createAxios from '@/utils/request'
// 设备列表
export function getDeviceTree() {
export function getDeviceTree(params?: any) {
return createAxios({
url: '/cs-device-boot/csLedger/deviceTree',
method: 'POST'
method: 'POST',
params
})
}
// 监测点列表
export function getLineTree() {
export function getLineTree(params?: any) {
return createAxios({
url: '/cs-device-boot/csLedger/lineTree',
method: 'POST'
method: 'POST',
params
})
}
// 监测点列表治理

View File

@@ -147,8 +147,9 @@ const tableStore: any = new TableStore({
backgroundColor: 'rgba(0,0,0,0.55)',
borderWidth: 0,
formatter: function (a: any) {
var relVal = ''
relVal = "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
var relVal = `<strong>${a.seriesName}</strong><br/>`
relVal += "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
relVal += "<font style='color:" + "'>特征幅值:" + a.value[1].toFixed(2) + '%</font>'
return relVal
@@ -214,18 +215,18 @@ const tableStore: any = new TableStore({
// [0.2, 10, '2023-01-01 10:00:00'],
// [0.4, 50, '2023-01-01 11:00:00']
// ],
legendSymbol: 'circle',
legendSymbol: 'circle'
tooltip: {
show: true,
trigger: 'item',
formatter: function (params: any) {
return `<strong>可容忍事件</strong><br/>
持续时间: ${params.value[0]}s<br/>
特征幅值: ${params.value[1].toFixed(2)}%<br/>
发生时间: ${params.value[2] || 'N/A'}`
}
}
// tooltip: {
// show: true,
// trigger: 'item',
// formatter: function (params: any) {
// return `<strong>可容忍事件</strong><br/>
// 持续时间: ${params.value[0]}s<br/>
// 特征幅值: ${params.value[1].toFixed(2)}%<br/>
// 发生时间: ${params.value[2] || 'N/A'}`
// }
// }
},
{
name: '不可容忍事件',

View File

@@ -186,7 +186,7 @@ const initProbabilityData = () => {
var tips = ''
tips += '指标类型: ' + yAxisData[yIndex] + '</br>'
tips += '越限程度: ' + params.seriesName + '</br>'
tips += '越限数: ' + params.value[2] + '</br>'
tips += '越限数: ' + params.value[2] + '</br>'
return tips
}
},
@@ -228,7 +228,7 @@ const initProbabilityData = () => {
},
zAxis3D: {
type: 'value',
name: '越限数',
name: '越限数',
nameLocation: 'middle',
nameGap: 30,
minInterval: 10

View File

@@ -185,7 +185,7 @@ const initProbabilityData = () => {
var tips = ''
tips += '指标类型: ' + yAxisData[yIndex] + '</br>'
tips += '越限程度: ' + params.seriesName + '</br>'
tips += '越限数: ' + params.value[2] + '</br>'
tips += '越限数: ' + params.value[2] + '</br>'
return tips
}
},
@@ -227,7 +227,7 @@ const initProbabilityData = () => {
},
zAxis3D: {
type: 'value',
name: '越限数',
name: '越限数',
nameLocation: 'middle',
nameGap: 30,
minInterval: 10

View File

@@ -106,13 +106,15 @@ const initChart = () => {
start: 0,
bottom: '20px',
end: 100
end: 100,
filterMode: 'none'
},
{
start: 0,
height: 13,
bottom: '20px',
end: 100
end: 100,
filterMode: 'none'
}
// {
// show: true,

View File

@@ -14,7 +14,7 @@
/>
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1 }">
<div style="display: flex; align-items: center" class="mb10">
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
<el-input maxlength="32" v-model.trim="filterText" placeholder="请输入内容" clearable>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>

View File

@@ -5,7 +5,7 @@
style='cursor: pointer' />
<div class='cn-tree' :style='{ opacity: menuCollapse ? 0 : 1 }'>
<div style='display: flex; align-items: center' class='mb10'>
<el-input maxlength="32" show-word-limit v-model.trim='filterText' placeholder='请输入内容' clearable>
<el-input maxlength="32" v-model.trim='filterText' placeholder='请输入内容' clearable>
<template #prefix>
<Icon name='el-icon-Search' style='font-size: 16px' />
</template>

View File

@@ -13,18 +13,29 @@
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1 }">
<div style="display: flex; align-items: center" class="mb10">
<!-- <el-form-item> -->
<el-input
maxlength="32"
show-word-limit
v-model.trim="filterText"
autocomplete="off"
placeholder="请输入内容"
clearable
>
<template #prepend>
<el-select v-model="treeType" @change="changeTreeType" style="min-width: 75px">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<!-- </el-form-item> -->
<Icon
@click="onMenuCollapse"
@@ -42,6 +53,8 @@
v-model.trim="activeName"
style="flex: 1; height: 100%"
@change="changeDevice"
v-if="treeType == '1'"
v-loading="loading"
>
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
@@ -142,6 +155,32 @@
</el-tree>
</el-collapse-item>
</el-collapse>
<div v-if="treeType == '2'" v-loading="loading">
<el-tree
:style="{ height: 'calc(100vh - 188px)' }"
ref="treeRef4"
:props="defaultProps"
highlight-current
:filter-node-method="filterNode"
node-key="id"
v-bind="$attrs"
:data="data"
style="overflow: auto"
:default-expand-all="false"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
</el-tree>
</div>
</div>
</div>
</template>
@@ -154,7 +193,7 @@ import { ref, watch, defineEmits, onMounted, nextTick } from 'vue'
defineOptions({
name: 'govern/tree'
})
const emit = defineEmits(['changeDeviceType'])
const emit = defineEmits(['changeDeviceType', 'changeTreeType'])
interface Props {
width?: string
canExpand?: boolean
@@ -170,6 +209,17 @@ const props = withDefaults(defineProps<Props>(), {
data: [],
height: 0
})
const treeType = ref('1')
const options = [
{
label: '设备',
value: '1'
},
{
label: '工程',
value: '2'
}
]
const { proxy } = useCurrentInstance()
const menuCollapse = ref(false)
const activeName = ref('0')
@@ -219,7 +269,9 @@ watch(
)
watch(filterText, val => {
if (activeName.value == '0') {
if (treeType.value == '2') {
treeRef4.value!.filter(val)
} else if (activeName.value == '0') {
treeRef1.value!.filter(val)
} else if (activeName.value == '1') {
treeRef2.value!.filter(val)
@@ -362,27 +414,43 @@ const treeRef1 = ref<InstanceType<typeof ElTree>>()
const treeRef2 = ref<InstanceType<typeof ElTree>>()
//前置
const treeRef3 = ref<InstanceType<typeof ElTree>>()
defineExpose({ treeRef1, treeRef2, treeRef3 })
const treeRef4 = ref<InstanceType<typeof ElTree>>()
defineExpose({ treeRef1, treeRef2, treeRef3, treeRef4 })
onMounted(() => {
setTimeout(() => {
if (zlDeviceData.value.length != 0) {
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
activeName.value = '0'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
activeName.value = '1'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
activeName.value = '2'
}
if (!zlDeviceData.value && !bxsDeviceData.value) {
activeName.value = ''
}
nextTick(() => {
changeDevice(activeName.value)
})
setActiveName()
}, 500)
})
const setActiveName = () => {
if (zlDeviceData.value.length != 0) {
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
activeName.value = '0'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
activeName.value = '1'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
activeName.value = '2'
}
if (!zlDeviceData.value && !bxsDeviceData.value) {
activeName.value = ''
}
nextTick(() => {
changeDevice(activeName.value)
})
}
const loading = ref(false)
const changeTreeType = (val: string) => {
loading.value = true
emit('changeTreeType', val)
if (val == '1') {
setActiveName()
}
setTimeout(() => {
loading.value = false
}, 1000)
}
</script>
<style lang="scss" scoped>
@@ -412,4 +480,7 @@ onMounted(() => {
display: flex;
align-items: center;
}
:deep(.el-input-group__prepend) {
background-color: var(--el-fill-color-blank);
}
</style>

View File

@@ -7,6 +7,7 @@
:data="tree"
:height="props.height"
@changeDeviceType="changeDeviceType"
@changeTreeType="info"
/>
</template>
@@ -16,6 +17,7 @@ import Tree from '../device.vue'
import { getDeviceTree } from '@/api/cs-device-boot/csLedger'
import { useConfig } from '@/stores/config'
import { throttle } from 'lodash'
import { on } from 'events'
defineOptions({
name: 'govern/deviceTree'
})
@@ -38,112 +40,149 @@ const treRef = ref()
const changeDeviceType = (val: any, obj: any) => {
emit('deviceTypeChange', val, obj)
}
getDeviceTree().then(res => {
let arr: any[] = []
let arr2: any[] = []
let arr3: any[] = []
//治理设备
res.data.map((item: any) => {
if (item.name == '治理设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
const info = (type?: string) => {
getDeviceTree({ type: type == '2' ? 'engineering' : '' }).then(res => {
let arr: any[] = []
let arr2: any[] = []
let arr3: any[] = []
let arr4: any[] = []
//治理设备
res.data.map((item: any) => {
if (type == '2') {
item.icon = 'el-icon-Menu'
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.pName = '治理设备'
item3.icon = 'el-icon-Platform'
item3.level = 2
item3.color = config.getColorVal('elementUiPrimary')
if (item3.comFlag === 1) {
item3.color = '#e26257 !important'
}
arr.push(item3)
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.color = config.getColorVal('elementUiPrimary')
item2.color =
item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
arr4.push(item2)
})
})
})
} else if (item.name == '便携式设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-Platform'
item.color = config.getColorVal('elementUiPrimary')
item.color = '#e26257 !important'
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
// item.disabled =true
item.pName = '便携式设备'
if (item.type == 'device') {
arr2.push(item)
}
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-Platform'
item2.color = item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item2.pName = '便携式设备'
// item2.children.forEach((item3: any) => {
// item3.icon = 'el-icon-Platform'
// item3.color = config.getColorVal('elementUiPrimary')
// if (item3.comFlag === 1) {
// item3.color = '#e26257 !important'
// }
// arr.push(item3)
// })
})
})
} else if (item.name == '监测设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.pName = '监测设备'
item3.icon = 'el-icon-Platform'
item3.color = config.getColorVal('elementUiPrimary')
if (item3.comFlag === 1) {
item3.color = '#e26257 !important'
}
arr3.push(item3)
})
})
})
}
})
tree.value = res.data
nextTick(() => {
setTimeout(() => {
if (arr.length > 0) {
treRef.value.treeRef1.setCurrentKey(arr[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr[0]
})
return
} else if (arr2.length > 0) {
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr2[0]
})
return
} else if (arr3.length > 0) {
console.log('🚀 ~ arr3:', arr3)
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr3[0]
})
return
} else {
emit('init')
return
if (item.name == '治理设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.pName = '治理设备'
item3.icon = 'el-icon-Platform'
item3.level = 2
item3.color = config.getColorVal('elementUiPrimary')
if (item3.comFlag === 1) {
item3.color = '#e26257 !important'
}
arr.push(item3)
})
})
})
} else if (item.name == '便携式设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-Platform'
item.color = config.getColorVal('elementUiPrimary')
item.color = '#e26257 !important'
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
// item.disabled =true
item.pName = '便携式设备'
if (item.type == 'device') {
arr2.push(item)
}
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-Platform'
item2.color =
item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item2.pName = '便携式设备'
// item2.children.forEach((item3: any) => {
// item3.icon = 'el-icon-Platform'
// item3.color = config.getColorVal('elementUiPrimary')
// if (item3.comFlag === 1) {
// item3.color = '#e26257 !important'
// }
// arr.push(item3)
// })
})
})
} else if (item.name == '监测设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.pName = '监测设备'
item3.icon = 'el-icon-Platform'
item3.color = config.getColorVal('elementUiPrimary')
if (item3.comFlag === 1) {
item3.color = '#e26257 !important'
}
arr3.push(item3)
})
})
})
}
}
}, 500)
})
tree.value = res.data
nextTick(() => {
setTimeout(() => {
if (type == '2') {
//初始化选中
treRef.value?.treeRef4.setCurrentKey(arr4[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr4[0]
})
// changePointType('4', arr4[0])
return
}
if (arr.length > 0) {
treRef.value.treeRef1.setCurrentKey(arr[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr[0]
})
return
} else if (arr2.length > 0) {
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr2[0]
})
return
} else if (arr3.length > 0) {
console.log('🚀 ~ arr3:', arr3)
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
// 注册父组件事件
emit('init', {
level: 2,
...arr3[0]
})
return
} else {
emit('init')
return
}
}, 500)
})
})
}
onMounted(() => {
info('1')
})
throttle(

View File

@@ -1,5 +1,12 @@
<template>
<Tree ref="treRef" :width="width" :data="tree" default-expand-all @changePointType="changePointType" />
<Tree
ref="treRef"
:width="width"
:data="tree"
default-expand-all
@changePointType="changePointType"
@changeTreeType="info"
/>
</template>
<script lang="ts" setup>
@@ -27,80 +34,124 @@ const dictData = useDictData()
const treRef = ref()
const width = ref('')
const info = () => {
const info = (type?: string) => {
tree.value = []
let arr1: any[] = []
let arr2: any[] = []
let arr3: any[] = []
getLineTree().then(res => {
let arr4: any[] = []
getLineTree({ type: type == '2' ? 'engineering' : '' }).then(res => {
//治理设备
res.data.map((item: any) => {
if (item.name == '治理设备') {
if (type == '2') {
item.icon = 'el-icon-Menu'
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.level = 1
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.level = 1
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.icon = 'el-icon-Platform'
item3.level = 2
item3.color =
item3.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item3.children.forEach((item4: any) => {
item4.icon = 'el-icon-Platform'
item4.color =
item4.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
// item4.color = '#e26257 !important'
arr1.push(item4)
})
arr4.push(item3)
// item3.children.forEach((item4: any) => {
// item4.icon = 'el-icon-Platform'
// item4.color =
// item4.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
// })
})
})
})
} else if (item.name == '便携式设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-Platform'
item.color = config.getColorVal('elementUiPrimary')
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-Platform'
item2.color =
item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
arr2.push(item2)
})
})
} else if (item.name == '监测设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.level = 1
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.level = 1
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.icon = 'el-icon-Platform'
item3.level = 1
item3.color =
item3.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item3.children.forEach((item4: any) => {
item4.icon = 'el-icon-Platform'
item4.color =
item4.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
// item4.color = '#e26257 !important'
arr3.push(item4)
} else {
if (item.name == '治理设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.level = 1
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.level = 1
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.icon = 'el-icon-Platform'
item3.level = 2
item3.color =
item3.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item3.children.forEach((item4: any) => {
item4.icon = 'el-icon-Platform'
item4.color =
item4.comFlag === 2
? config.getColorVal('elementUiPrimary')
: '#e26257 !important'
// item4.color = '#e26257 !important'
arr1.push(item4)
})
})
})
})
})
} else if (item.name == '便携式设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-Platform'
item.color = config.getColorVal('elementUiPrimary')
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-Platform'
item2.color =
item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
arr2.push(item2)
})
})
} else if (item.name == '监测设备') {
item.children.forEach((item: any) => {
item.icon = 'el-icon-HomeFilled'
item.level = 1
item.color = config.getColorVal('elementUiPrimary')
item.children.forEach((item2: any) => {
item2.icon = 'el-icon-List'
item2.level = 1
item2.color = config.getColorVal('elementUiPrimary')
item2.children.forEach((item3: any) => {
item3.icon = 'el-icon-Platform'
item3.level = 1
item3.color =
item3.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
item3.children.forEach((item4: any) => {
item4.icon = 'el-icon-Platform'
item4.color =
item4.comFlag === 2
? config.getColorVal('elementUiPrimary')
: '#e26257 !important'
// item4.color = '#e26257 !important'
arr3.push(item4)
})
})
})
})
}
}
})
tree.value = res.data
nextTick(() => {
setTimeout(() => {
if (arr1.length > 0) {
if (type == '2') {
//初始化选中
treRef.value?.treeRef4.setCurrentKey(arr4[0].id)
// 注册父组件事件
emit('init', {
level: 3,
...arr4[0]
})
changePointType('4', arr4[0])
return
} else if (arr1.length > 0) {
//初始化选中
treRef.value?.treeRef1.setCurrentKey(arr1[0].id)
// 注册父组件事件
@@ -119,7 +170,6 @@ const info = () => {
})
return
} else if (arr3.length > 0) {
treRef.value?.treeRef3?.setCurrentKey(arr3[0].id)
emit('init', {
level: 2,

View File

@@ -5,7 +5,7 @@
<div style="display: flex; align-items: center" class="mb10">
<el-input
maxlength="32"
show-word-limit
v-model.trim="filterText"
placeholder="请输入内容"
clearable

View File

@@ -5,7 +5,7 @@
style='cursor: pointer' />
<div class='cn-tree' :style='{ opacity: menuCollapse ? 0 : 1 }'>
<div style='display: flex; align-items: center' class='mb10'>
<el-input maxlength="32" show-word-limit v-model.trim='filterText' placeholder='请输入内容' clearable>
<el-input maxlength="32" v-model.trim='filterText' placeholder='请输入内容' clearable>
<template #prefix>
<Icon name='el-icon-Search' style='font-size: 16px' />
</template>

View File

@@ -13,11 +13,27 @@
/>
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
<div style="display: flex; align-items: center" class="mb10">
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
<!-- <el-input maxlength="32" v-model.trim="filterText" placeholder="请输入内容" clearable>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input> -->
<el-input maxlength="32" v-model.trim="filterText" placeholder="请输入内容" clearable>
<template #prepend>
<el-select v-model="treeType" @change="changeTreeType" style="min-width: 75px">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>
</el-input>
<!-- -->
<Icon
@click="onMenuCollapse"
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
@@ -34,6 +50,8 @@
v-model.trim="activeName"
style="flex: 1; height: 100%"
@change="changeDevice"
v-if="treeType == '1'"
v-loading="loading"
>
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
@@ -120,6 +138,33 @@
</el-tree>
</el-collapse-item>
</el-collapse>
<div v-if="treeType == '2'" v-loading="loading">
<el-tree
:style="{ height: 'calc(100vh - 188px)' }"
class="pt10"
ref="treeRef4"
:props="defaultProps"
highlight-current
:filter-node-method="filterNode"
node-key="id"
v-bind="$attrs"
:data="data"
style="overflow: auto"
:default-expand-all="false"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<Icon
:name="data.icon"
style="font-size: 16px"
:style="{ color: data.color }"
v-if="data.icon"
/>
<span style="margin-left: 4px">{{ node.label }}</span>
</span>
</template>
</el-tree>
</div>
</div>
</div>
</template>
@@ -133,7 +178,7 @@ import { useRoute } from 'vue-router'
defineOptions({
name: 'govern/tree'
})
const emit = defineEmits(['changePointType'])
const emit = defineEmits(['changePointType', 'changeTreeType'])
interface Props {
width?: string
canExpand?: boolean
@@ -157,6 +202,17 @@ const defaultProps = {
label: 'name',
value: 'id'
}
const treeType = ref('1')
const options = [
{
label: '设备',
value: '1'
},
{
label: '工程',
value: '2'
}
]
//治理设备数据
const zlDeviceData = ref<any>([])
const zlDevList = ref<any>([])
@@ -196,7 +252,9 @@ watch(
)
watch(filterText, val => {
if (activeName.value == '0') {
if (treeType.value == '2') {
treeRef4.value!.filter(val)
} else if (activeName.value == '0') {
treeRef1.value!.filter(val)
} else if (activeName.value == '1') {
treeRef2.value!.filter(val)
@@ -217,8 +275,6 @@ watch(process, val => {
})
const changeDevice = (val: any) => {
console.log('🚀 ~ changeDevice ~ val:', val)
let arr1: any = []
//zlDeviceData
zlDevList.value.forEach((item: any) => {
@@ -381,27 +437,43 @@ const treeRef1 = ref<InstanceType<typeof ElTree>>()
const treeRef2 = ref<InstanceType<typeof ElTree>>()
//在线
const treeRef3 = ref<InstanceType<typeof ElTree>>()
defineExpose({ treeRef1, treeRef2, treeRef3 })
// 工程
const treeRef4 = ref<InstanceType<typeof ElTree>>()
defineExpose({ treeRef1, treeRef2, treeRef3, treeRef4 })
onMounted(() => {
setTimeout(() => {
if (zlDeviceData.value.length != 0) {
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
activeName.value = '0'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
activeName.value = '1'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
activeName.value = '2'
}
if (!zlDeviceData.value && !bxsDeviceData.value) {
activeName.value = '2'
}
nextTick(() => {
changeDevice(activeName.value)
})
setActiveName()
}, 500)
})
const setActiveName = () => {
if (zlDeviceData.value.length != 0) {
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
activeName.value = '0'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
activeName.value = '1'
}
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
activeName.value = '2'
}
if (!zlDeviceData.value && !bxsDeviceData.value) {
activeName.value = '2'
}
nextTick(() => {
changeDevice(activeName.value)
})
}
const loading = ref(false)
const changeTreeType = (val: string) => {
loading.value = true
emit('changeTreeType', val)
if (val == '1') {
setActiveName()
}
setTimeout(() => {
loading.value = false
}, 1000)
}
</script>
<style lang="scss" scoped>
@@ -432,4 +504,7 @@ onMounted(() => {
display: flex;
align-items: center;
}
:deep(.el-input-group__prepend) {
background-color: var(--el-fill-color-blank);
}
</style>

View File

@@ -5,7 +5,7 @@
style='cursor: pointer' />
<div class='cn-tree' :style='{ opacity: menuCollapse ? 0 : 1 }'>
<div style='display: flex; align-items: center' class='mb10'>
<el-input maxlength="32" show-word-limit v-model.trim='filterText' placeholder='请输入内容' clearable>
<el-input maxlength="32" v-model.trim='filterText' placeholder='请输入内容' clearable>
<template #prefix>
<Icon name='el-icon-Search' style='font-size: 16px' />
</template>

View File

@@ -4,7 +4,7 @@ import { ElLoading, ElMessage, ElNotification, type LoadingOptions } from 'eleme
import { refreshToken } from '@/api/user-boot/user'
import router from '@/router/index'
import { useAdminInfo } from '@/stores/adminInfo'
import { useNavTabs } from '@/stores/navTabs'
window.requests = []
window.tokenRefreshing = false
let loginExpireTimer: any = null
@@ -13,7 +13,7 @@ const loadingInstance: LoadingInstance = {
target: null,
count: 0
}
const navTabs = useNavTabs()
/**
* 根据运行环境获取基础请求URL
*/
@@ -164,6 +164,9 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
message: response.data.message
})
adminInfo.removeToken()
navTabs.closeTabs()
window.localStorage.clear()
adminInfo.reset()
router.push({ name: 'login' })
loginExpireTimer = null // 执行后清空定时器
}, 100) // 可根据实际情况调整延迟时间

View File

@@ -100,6 +100,7 @@ const tableStore = new TableStore({
}
},
{ title: '设备名称', field: 'equipmentName', align: 'center', width: 120 },
{ title: '监测点名称', field: 'lineName', align: 'center', width: 140 },
{ title: '工程名称', field: 'engineeringName', align: 'center', width: 120 },
{ title: '项目名称', field: 'projectName', align: 'center', width: 120 },
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true },

View File

@@ -12,7 +12,7 @@
</pane>
<pane style="background: #fff">
<div class="device-manage-right">
<el-form :inline="true" class="demo-form-inline" style="height: 42px">
<el-form :inline="true" class="demo-form-inline" style="height: 42px">
<el-form-item style="position: relative; z-index: 2">
<el-button icon="el-icon-Plus" type="primary" @click="add" v-if="nodeLevel != 4">
{{
@@ -77,7 +77,7 @@
<el-form
class="main-form overview_scroll"
:label-position="'right'"
label-width="120px"
label-width="130px"
:inline="true"
ref="mainForm"
:model="formData"
@@ -965,7 +965,11 @@
class="form-item"
label="是否治理:"
:prop="'lineInfoList[' + lIndex + '].govern'"
:rules="{ required: true, message: '请选择是否治理', trigger: 'change' }"
:rules="{
required: true,
message: '请选择是否治理',
trigger: 'change'
}"
>
<el-select
clearable
@@ -1015,7 +1019,11 @@
class="form-item"
label="日志等级:"
:prop="'lineInfoList[' + lIndex + '].lineLogLevel'"
:rules="{ required: true, message: '请选择日志等级', trigger: 'change' }"
:rules="{
required: true,
message: '请选择日志等级',
trigger: 'change'
}"
>
<!-- 0运行1检修2停运3调试4退运 -->
<el-select
@@ -1031,7 +1039,7 @@
)
"
>
<el-option
<el-option
v-for="value in logList"
:key="value.value"
:label="value.label"
@@ -1039,7 +1047,34 @@
></el-option>
</el-select>
</el-form-item>
<el-form-item
class="form-item"
label="是否主要监测点:"
:prop="'lineInfoList[' + lIndex + '].isImportant'"
:rules="{
required: true,
message: '请选择是否主要监测点',
trigger: 'change'
}"
>
<!-- 0运行1检修2停运3调试4退运 -->
<el-select
clearable
filterable
v-model="lineItem.isImportant"
placeholder="请选择是否主要监测点"
:disabled="
!(
(nodeLevel == 4 && pageStatus == 3) ||
((nodeLevel == 3 || (nodeLevel == 2 && pageStatus == 2)) &&
pageStatus == 2)
)
"
>
<el-option label="是" :value="1"></el-option>
<el-option label="否" :value="0"></el-option>
</el-select>
</el-form-item>
</div>
</el-tab-pane>
</el-tabs>
@@ -1278,6 +1313,7 @@ interface LineInfo {
position: string
govern: string | number
lineLogLevel: string
isImportant: string | number
runStatus: string | number
basicCapacity: number
shortCircuitCapacity: number
@@ -1660,6 +1696,7 @@ const add = () => {
position: '',
govern: 0,
lineLogLevel: 'WARN',
isImportant: 0,
runStatus: 0,
basicCapacity: 0,
shortCircuitCapacity: 0,
@@ -1839,6 +1876,7 @@ const updateLineFunc = (id: any) => {
position: currentLine.position || '',
govern: currentLine.govern,
lineLogLevel: currentLine.lineLogLevel,
isImportant: currentLine.isImportant,
runStatus: currentLine.runStatus,
basicCapacity: currentLine.basicCapacity || 0,
shortCircuitCapacity: currentLine.shortCircuitCapacity || 0,
@@ -2004,7 +2042,7 @@ const next = async () => {
devModel: '',
devType: '',
devAccessMethod: 'CLD',
devLogLevel: 'WARN',
devLogLevel: 'WARN',
mac: '',
ndid: '',
nodeId: '',
@@ -2037,7 +2075,8 @@ const next = async () => {
monitorObj: '',
position: '',
govern: 0,
lineLogLevel:'WARN',
lineLogLevel: 'WARN',
isImportant: 0,
runStatus: 0,
basicCapacity: 0,
shortCircuitCapacity: 0,
@@ -2466,6 +2505,7 @@ const resetAllForms = () => {
line.position = ''
line.govern = 0
line.lineLogLevel = 'WARN'
line.isImportant = 0
line.runStatus = 0
line.basicCapacity = 0
line.shortCircuitCapacity = 0
@@ -2636,6 +2676,7 @@ const submitData = () => {
position: currentLine.position,
govern: currentLine.govern,
lineLogLevel: currentLine.lineLogLevel,
isImportant: currentLine.isImportant,
runStatus: currentLine.runStatus,
basicCapacity: currentLine.basicCapacity,
shortCircuitCapacity: currentLine.shortCircuitCapacity,
@@ -2750,7 +2791,7 @@ const handleBusBarTabsEdit = (targetName: any, action: any) => {
devModel: '',
devType: '',
devAccessMethod: 'CLD',
devLogLevel: 'WARN',
devLogLevel: 'WARN',
mac: '',
ndid: '',
nodeId: '',
@@ -2828,6 +2869,7 @@ const handleLineTabsEdit = (targetName: any, action: any) => {
position: '',
govern: 0,
lineLogLevel: 'WARN',
isImportant: 0,
runStatus: 0,
basicCapacity: 0,
shortCircuitCapacity: 0,

View File

@@ -141,7 +141,8 @@
v-show="
dataSet.includes('_items') ||
dataSet.indexOf('_history') != -1 ||
dataSet.indexOf('_moduleData') != -1
dataSet.indexOf('_moduleData') != -1||
dataSet.indexOf('_devRunTrend') != -1
"
>
<DatePicker ref="datePickerRef"></DatePicker>
@@ -165,7 +166,7 @@
</el-select> -->
<el-radio-group
v-model.trim="formInline.dataLevel"
v-if="!dataSet.includes('_moduleData') && TrendList?.lineType == 1"
v-if="!dataSet.includes('_devRunTrend') &&!dataSet.includes('_moduleData') && TrendList?.lineType == 1"
:disabled="TrendList?.lineType != 1"
@change="handleClick"
>
@@ -525,6 +526,14 @@
>
<moduleData ref="moduleDataRef" @onSubmit="handleClick" />
</div>
<!-- 运行趋势 -->
<div
style="height: calc(100vh - 395px)"
v-if="dataSet.indexOf('_devRunTrend') != -1"
v-loading="tableLoading"
>
<operatingTrend ref="operatingTrendRef" @onSubmit="handleClick" />
</div>
<div v-if="!tableData" style="height: 42px"></div>
</el-tabs>
</div>
@@ -548,7 +557,8 @@ import {
getOverLimitData,
queryDictType,
getById,
allModelData
allModelData,
getRawData
} from '@/api/cs-device-boot/EquipmentDelivery'
import { deviceHisData, deviceRtData, realTimeData, getTestData } from '@/api/cs-device-boot/csGroup'
import { ref, reactive, onMounted, onUnmounted, inject, nextTick, onBeforeUnmount } from 'vue'
@@ -557,6 +567,7 @@ 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 operatingTrend from './tabs/operatingTrend.vue' //运行趋势
import harmonicSpectrum from './tabs/components/harmonicSpectrum.vue' //实时数据-谐波频谱子页面
import recordWoves from './tabs/components/recordwoves.vue' //实时数据-实时录波子页面
import offLineDataImport from './offLineDataImport/index.vue'
@@ -660,6 +671,7 @@ const volConTypeList = dictData.getBasicData('Dev_Connect')
// }
//谐波频谱
const realTrendRef = ref()
const operatingTrendRef = ref()
const changeTrendType = (val: any) => {
trendDataTime.value = ''
activeTrendName.value = val * 1
@@ -920,6 +932,10 @@ const nodeClick = async (e: anyObj, node: any) => {
if (item.type === 'moduleData') {
item.id = item.id + '_moduleData'
}
// 模块数据
if (item.type === 'devRunTrend') {
item.id = item.id + '_devRunTrend'
}
})
res.data.dataSetList = res.data.dataSetList.filter((item: any) => item.name != '历史统计数据')
//便携式设备默认二次值
@@ -1316,6 +1332,39 @@ const handleClick = async (tab?: any) => {
}, 0)
}, 0)
}
//运行趋势
if (dataSet.value.includes('_devRunTrend')) {
setTimeout(async () => {
if (tab.props != undefined) await (datePickerRef.value && datePickerRef.value?.setInterval(5))
let obj = {
// devId: deviceId.value, //e.id
lineId: [deviceId.value], //e.pid
startTime: datePickerRef.value && datePickerRef.value.timeValue[0],
endTime: datePickerRef.value && datePickerRef.value.timeValue[1]
}
await setTimeout(() => {
getRawData(obj)
.then((res: any) => {
tableLoading.value = false
setTimeout(() => {
operatingTrendRef.value?.setData(res.data)
}, 500)
setTimeout(() => {
loading.value = false
}, 1500)
})
.catch(e => {
setTimeout(() => {
tableLoading.value = false
}, 1500)
})
}, 0)
}, 0)
}
//查询当前指标
if (!dataSet.value.includes('_')) {

View File

@@ -0,0 +1,165 @@
<template>
<div :style="height">
<MyEchart v-if="list.length != 0" :options="options1" style="height: 100%; width: 100%" class="pt10" />
<el-empty description="暂无数据" style="width: 100%; height: 100%" v-else></el-empty>
</div>
</template>
<script setup lang="ts">
import MyEchart from '@/components/echarts/MyEchart.vue'
import { ref, reactive } from 'vue'
import { mainHeight } from '@/utils/layout'
import { max } from 'lodash'
const height = ref(mainHeight(290))
const list = ref([])
const options1 = ref({})
const setData = (data: any) => {
// list.value = [...fillDataFromFirstTime(data),...data]
list.value = data
init()
}
/**
* 补全离散数据严格从数组第一个time开始最后一个time结束
* @param {Array} data 原始离散数据数组
* @param {number} interval 补全时间间隔默认10秒
* @returns {Array} 补全后的连续数据
*/
function fillDataFromFirstTime(data, interval = 10) {
// 1. 基础校验
if (!Array.isArray(data) || data.length === 0) {
console.error('原始数据必须是非空数组')
return []
}
// 2. 锁定起始时间直接取数组第一个元素的time不做任何偏移
const firstItem = data[0]
const startTime = new Date(firstItem.time)
const startTimestamp = startTime.getTime()
// 3. 锁定结束时间取数组最后一个元素的time
const lastItem = data[data.length - 1]
const endTime = new Date(lastItem.time)
const endTimestamp = endTime.getTime()
// 4. 预处理:按时间排序(防止原始数据乱序)
const sortedData = [...data].sort((a, b) => new Date(a.time) - new Date(b.time))
// 5. 初始化状态继承第一个数据的type
let currentType = firstItem.type
let currentDesc = firstItem.description
let nextStatusIndex = 1 // 指向待切换的下一个状态点
const filledData = []
// 6. 核心循环从第一个time开始按间隔补全到最后一个time
for (let ts = startTimestamp; ts <= endTimestamp; ts += interval * 1000) {
const currentDate = new Date(ts)
// 格式化时间为和原始数据一致的 "YYYY-MM-DD HH:mm:ss" 格式
const formattedTime = `${currentDate.getFullYear()}-${String(currentDate.getMonth() + 1).padStart(
2,
'0'
)}-${String(currentDate.getDate()).padStart(2, '0')} ${String(currentDate.getHours()).padStart(
2,
'0'
)}:${String(currentDate.getMinutes()).padStart(2, '0')}:${String(currentDate.getSeconds()).padStart(2, '0')}`
// 7. 检查是否到达下一个状态切换点
if (nextStatusIndex < sortedData.length) {
const nextStatusTime = new Date(sortedData[nextStatusIndex].time).getTime()
if (ts >= nextStatusTime) {
currentType = sortedData[nextStatusIndex].type
currentDesc = sortedData[nextStatusIndex].description
nextStatusIndex++
}
}
// 8. 生成补全数据项(结构与原始数据完全一致)
filledData.push({
time: formattedTime,
devId: firstItem.devId,
description: currentDesc,
type: currentType
})
}
return filledData
}
const init = () => {
options1.value = {
title: {
text: '运行状态'
},
legend: {
show: false
},
tooltip: {
formatter: function (params: any) {
var res = params[0].data[0] + '<br/>运行状态:'
var texts = ''
if (params[0].data[1] === 1 || params[0].data[1] === '1') {
texts = '中断'
} else if (params[0].data[1] === 10 || params[0].data[1] === '10') {
texts = '正常'
}
res = res + texts
return res
}
},
xAxis: {
// type: 'category',
// data: data.updateTime
type: 'time',
name: '时间',
//
axisLabel: {
formatter: {
day: '{MM}-{dd}',
month: '{MM}',
year: '{yyyy}'
}
}
},
yAxis: {
name: '',
type: 'value',
max: 11,
interval: 1,
splitLine: {
lineStyle: {
// 使用深浅的间隔色
color: ['#ccc'],
type: 'dashed',
opacity: 0
}
},
axisLabel: {
// 这里重新定义就可以
formatter: function (value: number) {
var texts = []
if (value === 1) {
texts.push('中断')
} else if (value === 10) {
texts.push('正常')
}
return texts
}
}
},
series: [
{
name: '运行状态',
data: list.value.map((item: any, index: number) => [item.time, item.type == 0 ? 1 : 10]),
type: 'line',
showSymbol: false,
step: 'end'
}
]
}
}
defineExpose({
setData
})
</script>
<style lang="scss" scoped></style>

View File

@@ -6,7 +6,7 @@
style="cursor: pointer" />
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
<div style="display: flex; align-items: center" class="mb10">
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
<el-input maxlength="32" v-model.trim="filterText" placeholder="请输入内容" clearable>
<template #prefix>
<Icon name="el-icon-Search" style="font-size: 16px" />
</template>

View File

@@ -108,8 +108,8 @@ const info = async (list: any) => {
return
}
let relVal = ''
relVal = "<font style='color:" + "'>供电公司:" + '&nbsp' + '&nbsp' + a[0].value[3] + '</font><br/>'
var relVal = `<strong>${a.seriesName}</strong><br/>`
relVal += "<font style='color:" + "'>供电公司:" + '&nbsp' + '&nbsp' + a[0].value[3] + '</font><br/>'
relVal += "<font style='color:" + "'>变电站:" + '&nbsp' + '&nbsp' + a[0].value[4] + '</font><br/>'
relVal += "<font style='color:" + "'>发生时刻:" + '&nbsp' + '&nbsp' + a[0].value[2] + '</font><br/>'
relVal +=