在线补召
This commit is contained in:
@@ -54,3 +54,12 @@ export function downloadWave(params: string) {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//根据事件补召波形
|
||||||
|
export function getFileByEventId(eventId: string) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/icd/bzFileByEventId?eventId=' + eventId,
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
19
src/api/cs-device-boot/recall.ts
Normal file
19
src/api/cs-device-boot/recall.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import createAxios from '@/utils/request'
|
||||||
|
|
||||||
|
//补召事件
|
||||||
|
export function eventRecall(data: any) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/icd/bzEvent',
|
||||||
|
method: 'post',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//补召波形
|
||||||
|
export function fileRecall(data: any) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/icd/bzFile',
|
||||||
|
method: 'post',
|
||||||
|
params: data
|
||||||
|
})
|
||||||
|
}
|
||||||
107
src/components/tree/govern/selectTree.vue
Normal file
107
src/components/tree/govern/selectTree.vue
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
<template>
|
||||||
|
<Tree ref="treRef" :width="width" :data="tree" default-expand-all @changePointType="changePointType" @checkedNodesChange="handleCheckedNodesChange"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, nextTick, onMounted, defineProps } from 'vue'
|
||||||
|
import Tree from '../select.vue'
|
||||||
|
import { getLineTree } from '@/api/cs-device-boot/csLedger'
|
||||||
|
import { useConfig } from '@/stores/config'
|
||||||
|
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
||||||
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
// const props = defineProps(['template'])
|
||||||
|
interface Props {
|
||||||
|
template?: boolean
|
||||||
|
}
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
template: false
|
||||||
|
})
|
||||||
|
defineOptions({
|
||||||
|
name: 'govern/deviceTree'
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['init', 'checkChange', 'pointTypeChange', 'Policy'])
|
||||||
|
const config = useConfig()
|
||||||
|
const tree = ref()
|
||||||
|
const dictData = useDictData()
|
||||||
|
const treRef = ref()
|
||||||
|
const width = ref('')
|
||||||
|
|
||||||
|
const info = () => {
|
||||||
|
tree.value = []
|
||||||
|
let arr3: any[] = []
|
||||||
|
getLineTree().then(res => {
|
||||||
|
//治理设备
|
||||||
|
res.data.map((item: any) => {
|
||||||
|
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.filter(item => item.name == '在线设备')
|
||||||
|
nextTick(() => {
|
||||||
|
if (arr3.length) {
|
||||||
|
//初始化选中
|
||||||
|
treRef.value.treeRef1.setCurrentKey(arr3[0].id)
|
||||||
|
// 注册父组件事件
|
||||||
|
emit('init', {
|
||||||
|
level: 2,
|
||||||
|
...arr3[0]
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emit('init')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const changePointType = (val: any, obj: any) => {
|
||||||
|
emit('pointTypeChange', val, obj)
|
||||||
|
}
|
||||||
|
// 处理子组件传递的勾选节点变化,并转发给父组件
|
||||||
|
const handleCheckedNodesChange = (nodes: any[]) => {
|
||||||
|
// 先给父组件
|
||||||
|
emit('checkChange', nodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (props.template) {
|
||||||
|
getTemplateByDept({ id: dictData.state.area[0].id })
|
||||||
|
.then((res: any) => {
|
||||||
|
emit('Policy', res.data)
|
||||||
|
info()
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
info()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
info()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {})
|
||||||
|
</script>
|
||||||
185
src/components/tree/select.vue
Normal file
185
src/components/tree/select.vue
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<template>
|
||||||
|
<div :style="{ width: menuCollapse ? '40px' : props.width }" style='transition: all 0.3s; overflow: hidden;'>
|
||||||
|
<Icon v-show='menuCollapse' @click='onMenuCollapse' :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||||
|
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 mt20 menu-collapse'
|
||||||
|
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>
|
||||||
|
<template #prefix>
|
||||||
|
<Icon name='el-icon-Search' style='font-size: 16px' />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<el-tree :style="{ height: 'calc(100vh)' }"
|
||||||
|
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current
|
||||||
|
:filter-node-method='filterNode' node-key='id' v-bind='$attrs'
|
||||||
|
show-checkbox @check="handleCheckChange" :default-checked-keys="defaultCheckedKeys">
|
||||||
|
<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>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang='ts' setup>
|
||||||
|
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||||
|
import { ElMessage, ElTree } from 'element-plus'
|
||||||
|
import { emit } from 'process';
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'govern/tree'
|
||||||
|
})
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
width?: string
|
||||||
|
canExpand?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
width: '280px',
|
||||||
|
canExpand: true
|
||||||
|
})
|
||||||
|
const { proxy } = useCurrentInstance()
|
||||||
|
const menuCollapse = ref(false)
|
||||||
|
const filterText = ref('')
|
||||||
|
const defaultProps = {
|
||||||
|
label: 'name',
|
||||||
|
value: 'id'
|
||||||
|
}
|
||||||
|
const emit = defineEmits(['changePointType', 'checkedNodesChange'])
|
||||||
|
|
||||||
|
watch(filterText, val => {
|
||||||
|
treeRef.value!.filter(val)
|
||||||
|
|
||||||
|
})
|
||||||
|
const onMenuCollapse = () => {
|
||||||
|
menuCollapse.value = !menuCollapse.value
|
||||||
|
proxy.eventBus.emit('cnTreeCollapse', menuCollapse)
|
||||||
|
}
|
||||||
|
const filterNode = (value: string, data: any, node: any) => {
|
||||||
|
if (!value) return true
|
||||||
|
// return data.name.includes(value)
|
||||||
|
if (data.name) {
|
||||||
|
|
||||||
|
return chooseNode(value, data, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
||||||
|
const chooseNode = (value: string, data: any, node: any) => {
|
||||||
|
|
||||||
|
if (data.name.indexOf(value) !== -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const level = node.level
|
||||||
|
// 如果传入的节点本身就是一级节点就不用校验了
|
||||||
|
if (level === 1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 先取当前节点的父节点
|
||||||
|
let parentData = node.parent
|
||||||
|
// 遍历当前节点的父节点
|
||||||
|
let index = 0
|
||||||
|
while (index < level - 1) {
|
||||||
|
// 如果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
|
||||||
|
if (parentData.data.name.indexOf(value) !== -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 否则的话再往上一层做匹配
|
||||||
|
parentData = parentData.parent
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
// 没匹配到返回false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储所有勾选的节点
|
||||||
|
const checkedNodes = ref<any[]>([])
|
||||||
|
const defaultCheckedKeys = ref<string[]>([])
|
||||||
|
// 处理节点勾选变化
|
||||||
|
const handleCheckChange = (data: any, checkInfo: any) => {
|
||||||
|
const { checkedNodes: nodes } = checkInfo
|
||||||
|
// 过滤出监测点层级(level=3)的节点
|
||||||
|
const monitoringPointNodes = nodes.filter((node: any) => {
|
||||||
|
// 监测点节点通常具有 comFlag 属性或其他标识
|
||||||
|
return node.level === 3
|
||||||
|
})
|
||||||
|
// 限制最多只能勾选5个监测点
|
||||||
|
if (monitoringPointNodes.length > 5) {
|
||||||
|
ElMessage.warning('最多只能选择5个监测点')
|
||||||
|
// 保持之前勾选的状态
|
||||||
|
treeRef.value?.setCheckedNodes(checkedNodes.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
checkedNodes.value = monitoringPointNodes
|
||||||
|
|
||||||
|
// 将勾选的监测点节点暴露出去
|
||||||
|
emit('checkedNodesChange', monitoringPointNodes)
|
||||||
|
|
||||||
|
// 更新节点的可勾选状态
|
||||||
|
updateNodeCheckStatus(monitoringPointNodes.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 更新节点的可勾选状态
|
||||||
|
const updateNodeCheckStatus = (currentCount: number) => {
|
||||||
|
if (!treeRef.value) return
|
||||||
|
|
||||||
|
// 如果已经选了5个,则禁用其他未选中的监测点节点
|
||||||
|
const isMaxSelected = currentCount >= 5
|
||||||
|
|
||||||
|
// 获取所有节点并更新状态
|
||||||
|
const allNodes = treeRef.value.store._getAllNodes()
|
||||||
|
allNodes.forEach((node: any) => {
|
||||||
|
if (node.level === 3) { // 监测点层级
|
||||||
|
// 如果已达到最大数量且该节点未被选中,则禁用勾选
|
||||||
|
if (isMaxSelected && !node.checked) {
|
||||||
|
node.disabled = true
|
||||||
|
} else {
|
||||||
|
node.disabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||||||
|
defineExpose({ treeRef })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
.cn-tree {
|
||||||
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 10px;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
:deep(.el-tree) {
|
||||||
|
border: 1px solid var(--el-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
|
||||||
|
background-color: var(--el-color-primary-light-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-collapse {
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-tree-node {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -10,15 +10,6 @@
|
|||||||
<div class="device-control-right" v-if="deviceData">
|
<div class="device-control-right" v-if="deviceData">
|
||||||
<el-descriptions title="监测点信息" class="mb10" width="180" :column="3" border>
|
<el-descriptions title="监测点信息" class="mb10" width="180" :column="3" border>
|
||||||
<template #extra>
|
<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
|
<el-button
|
||||||
v-if="deviceType == '1'"
|
v-if="deviceType == '1'"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -45,9 +36,6 @@
|
|||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
<!-- <el-descriptions-item label="安装位置" width="160">
|
|
||||||
{{ devData.position || '/' }}
|
|
||||||
</el-descriptions-item> -->
|
|
||||||
|
|
||||||
<el-descriptions-item label="PT变比" width="160">
|
<el-descriptions-item label="PT变比" width="160">
|
||||||
{{ devData.ptRatio || '/' }}
|
{{ devData.ptRatio || '/' }}
|
||||||
@@ -56,27 +44,9 @@
|
|||||||
{{ devData.ctRatio || '/' }}
|
{{ devData.ctRatio || '/' }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
<!-- <el-descriptions-item label="名称">
|
|
||||||
{{ devData.name ? devData.name : '/' }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="类型">
|
|
||||||
{{ echoName(devData.devType, devTypeOptions) }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
|
|
||||||
<el-descriptions-item label="接入方式">
|
|
||||||
{{ devData.devAccessMethod ? devData.devAccessMethod : '/' }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="网络设备ID">
|
|
||||||
{{ devData.ndid ? devData.ndid : '/' }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="型号">
|
|
||||||
{{ echoName(devData.devModel, devModelOptions) }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="接入日期">
|
|
||||||
{{ devData.time ? devData.time : '/' }}
|
|
||||||
</el-descriptions-item> -->
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<el-tabs v-model.trim="dataSet" type="border-card" class="device-control-box-card" @tab-click="handleClick">
|
<el-tabs v-model.trim="dataSet" type="border-card" class="mb10" @tab-click="handleClick">
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
lazy
|
lazy
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
@@ -498,7 +468,7 @@
|
|||||||
v-if="dataSet.indexOf('_event') != -1"
|
v-if="dataSet.indexOf('_event') != -1"
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
>
|
>
|
||||||
<Event ref="eventRef"></Event>
|
<Event ref="eventRef" :device-type="deviceType"></Event>
|
||||||
</div>
|
</div>
|
||||||
<!-- 测试项记录 -->
|
<!-- 测试项记录 -->
|
||||||
<div
|
<div
|
||||||
@@ -928,6 +898,7 @@ const nodeClick = async (e: anyObj) => {
|
|||||||
const deviceType = ref('0')
|
const deviceType = ref('0')
|
||||||
const pointTypeChange = (val: any, obj: any) => {
|
const pointTypeChange = (val: any, obj: any) => {
|
||||||
deviceType.value = val
|
deviceType.value = val
|
||||||
|
console.log('pointTypeChange', val)
|
||||||
nodeClick(obj)
|
nodeClick(obj)
|
||||||
}
|
}
|
||||||
const realTimeRef: any = ref()
|
const realTimeRef: any = ref()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import TableHeader from '@/components/table/header/index.vue'
|
|||||||
import waveFormAnalysis from './components/waveFormAnalysis.vue'
|
import waveFormAnalysis from './components/waveFormAnalysis.vue'
|
||||||
import { ArrowLeft } from '@element-plus/icons-vue'
|
import { ArrowLeft } from '@element-plus/icons-vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { analyseWave } from '@/api/common'
|
import { analyseWave,getFileByEventId } from '@/api/common'
|
||||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||||
const tableParams: any = ref({})
|
const tableParams: any = ref({})
|
||||||
const refheader = ref()
|
const refheader = ref()
|
||||||
@@ -29,6 +29,15 @@ const wp = ref({})
|
|||||||
const value = ref(1)
|
const value = ref(1)
|
||||||
const waveFormAnalysisRef = ref()
|
const waveFormAnalysisRef = ref()
|
||||||
const headerRef = ref()
|
const headerRef = ref()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
deviceType: {
|
||||||
|
type: String,
|
||||||
|
default: '0'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/cs-device-boot/csGroup/deviceDataByType',
|
url: '/cs-device-boot/csGroup/deviceDataByType',
|
||||||
publicHeight: 215,
|
publicHeight: 215,
|
||||||
@@ -125,7 +134,7 @@ const tableStore: any = new TableStore({
|
|||||||
icon: 'el-icon-DataLine',
|
icon: 'el-icon-DataLine',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
disabled: row => {
|
disabled: row => {
|
||||||
return row.wavePath
|
return props.deviceType === '2' || row.wavePath;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -151,10 +160,22 @@ const tableStore: any = new TableStore({
|
|||||||
document.body.removeChild(link) //释放标签
|
document.body.removeChild(link) //释放标签
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'edit',
|
||||||
|
title: '波形补召',
|
||||||
|
type: 'primary',
|
||||||
|
icon: 'el-icon-Check',
|
||||||
|
render: 'basicButton',
|
||||||
|
disabled: row => {
|
||||||
|
return props.deviceType != '2' || row.wavePath;
|
||||||
|
},
|
||||||
|
click: row => {
|
||||||
|
getFileByEventId(row.id).then(res => {
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
151
src/views/govern/monitorRecall/eventRecall.vue
Normal file
151
src/views/govern/monitorRecall/eventRecall.vue
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
<template>
|
||||||
|
<div class="view" style="height: 100%">
|
||||||
|
<TableHeader datePicker ref="TableHeaderRef" :showReset="false">
|
||||||
|
<template #operation>
|
||||||
|
<el-button type="primary" :icon="Setting" @click="recall1">事件补召</el-button>
|
||||||
|
<el-button type="primary" :icon="Setting" @click="recall2">波形补召</el-button>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" style="height: calc(100% - 120px)" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, provide, nextTick, defineEmits, watch } from 'vue'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { Setting } from '@element-plus/icons-vue'
|
||||||
|
import {eventRecall,fileRecall} from '@/api/cs-device-boot/recall'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import DatePicker from '@/components/form/datePicker/time.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
checkedNodes: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const headerRef = ref()
|
||||||
|
const datePickerRef = ref()
|
||||||
|
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/cs-device-boot/portableOfflLog/queryMainLogPage',
|
||||||
|
publicHeight: 0,
|
||||||
|
method: 'POST',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
title: '序号', width: 80, formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'projectName',
|
||||||
|
title: '工程名称',
|
||||||
|
minWidth: 170,
|
||||||
|
formatter: row => {
|
||||||
|
return row.cellValue ? row.cellValue : '/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ field: 'successCount', title: '成功解析数', minWidth: 150 },
|
||||||
|
{ field: 'startTime', title: '导入开始时间', minWidth: 170, sortable: true },
|
||||||
|
{ field: 'endTime', title: '导入结束时间', minWidth: 170 , sortable: true},
|
||||||
|
{
|
||||||
|
title: '解析状态',
|
||||||
|
field: 'status',
|
||||||
|
width: 100,
|
||||||
|
render: 'tag',
|
||||||
|
custom: {
|
||||||
|
0: 'warning',
|
||||||
|
1: 'success',
|
||||||
|
2: 'danger',
|
||||||
|
3: 'primary'
|
||||||
|
},
|
||||||
|
replaceValue: {
|
||||||
|
0: '未解析',
|
||||||
|
1: '解析成功',
|
||||||
|
2: '解析失败',
|
||||||
|
3: '文件不存在'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: '100',
|
||||||
|
render: 'buttons',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
name: 'edit',
|
||||||
|
title: '详情',
|
||||||
|
type: 'primary',
|
||||||
|
icon: 'el-icon-EditPen',
|
||||||
|
render: 'basicButton',
|
||||||
|
click: row => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
|
const recall1 = async () => {
|
||||||
|
if (!props.checkedNodes || props.checkedNodes.length === 0) {
|
||||||
|
ElMessage.warning('请先勾选监测点')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await eventRecall({
|
||||||
|
startTime: tableStore.table.params.startTime,
|
||||||
|
endTime: tableStore.table.params.endTime,
|
||||||
|
lineList: props.checkedNodes.map((node: any) => node.id)
|
||||||
|
}).then((res: any) => {
|
||||||
|
ElMessage.success('补召事件成功')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const recall2 = async () => {
|
||||||
|
if (!props.checkedNodes || props.checkedNodes.length === 0) {
|
||||||
|
ElMessage.warning('请先勾选监测点')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await fileRecall({
|
||||||
|
startTime: tableStore.table.params.startTime,
|
||||||
|
endTime: tableStore.table.params.endTime,
|
||||||
|
lineList: props.checkedNodes.map((node: any) => node.id)
|
||||||
|
}).then((res: any) => {
|
||||||
|
ElMessage.success('补召波形成功')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.header_btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view :deep(.el-table) {
|
||||||
|
height: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
186
src/views/govern/monitorRecall/index.vue
Normal file
186
src/views/govern/monitorRecall/index.vue
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="default-main device-control"
|
||||||
|
:style="{ height: pageHeight.height }"
|
||||||
|
v-loading="loading"
|
||||||
|
style="position: relative"
|
||||||
|
>
|
||||||
|
<!-- @init="nodeClick" -->
|
||||||
|
<PointTree @node-click="nodeClick" @pointTypeChange="pointTypeChange" @checkChange="handleCheckedNodesChange"></PointTree>
|
||||||
|
<div class="device-control-right" >
|
||||||
|
<el-tabs type="border-card" class="mb10" @tab-click="handleClick" v-model="activeTab">
|
||||||
|
<el-tab-pane label="稳态补召" name="deviceInfo1">
|
||||||
|
<div style="height: calc(100vh - 205px)">
|
||||||
|
<SteadyRecall ref="steadyRef" :checked-nodes="checkedNodes"></SteadyRecall>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="暂态补召" name="deviceInfo2">
|
||||||
|
<div style="height: calc(100vh - 205px)">
|
||||||
|
<Event ref="eventRef" :checked-nodes="checkedNodes"></Event>
|
||||||
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import PointTree from '@/components/tree/govern/selectTree.vue'
|
||||||
|
import { ref, reactive, onMounted, onUnmounted, inject, nextTick, onBeforeUnmount } from 'vue'
|
||||||
|
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { mainHeight } from '@/utils/layout'
|
||||||
|
import Event from './eventRecall.vue'
|
||||||
|
import SteadyRecall from './steadyRecall.vue'
|
||||||
|
|
||||||
|
const pageHeight = mainHeight(20)
|
||||||
|
const steadyRef = ref()
|
||||||
|
const eventRef = ref()
|
||||||
|
const loading = ref(false)
|
||||||
|
const activeTab = ref('deviceInfo1')
|
||||||
|
const checkedNodes = ref<any[]>([]) // 存储左侧树勾选的节点
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'govern/monitorRecall/index'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理子组件传递的勾选节点变化
|
||||||
|
const handleCheckedNodesChange = (nodes: any[]) => {
|
||||||
|
|
||||||
|
checkedNodes.value = nodes
|
||||||
|
|
||||||
|
// 将勾选的节点传递给当前激活的tab组件
|
||||||
|
if (activeTab.value === 'deviceInfo1' && steadyRef.value) {
|
||||||
|
// 如果steadyRecall组件有接收勾选节点的方法,可以调用
|
||||||
|
if (steadyRef.value.setCheckedNodes) {
|
||||||
|
steadyRef.value.setCheckedNodes(nodes)
|
||||||
|
}
|
||||||
|
} else if (activeTab.value === 'deviceInfo2' && eventRef.value) {
|
||||||
|
// 如果eventRecall组件有接收勾选节点的方法,可以调用
|
||||||
|
if (eventRef.value.setCheckedNodes) {
|
||||||
|
eventRef.value.setCheckedNodes(nodes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tab切换时的处理
|
||||||
|
const handleClick = (tab: any) => {
|
||||||
|
activeTab.value = tab.props.name
|
||||||
|
|
||||||
|
// tab切换时刷新对应组件的数据
|
||||||
|
nextTick(() => {
|
||||||
|
if (tab.props.name === 'deviceInfo1' && steadyRef.value) {
|
||||||
|
// 刷新稳态补召数据
|
||||||
|
if (steadyRef.value.refreshData) {
|
||||||
|
steadyRef.value.refreshData(checkedNodes.value)
|
||||||
|
} else if (steadyRef.value.getTableParams) {
|
||||||
|
// 如果有getTableParams方法,调用它
|
||||||
|
steadyRef.value.getTableParams({ nodes: checkedNodes.value })
|
||||||
|
}
|
||||||
|
} else if (tab.props.name === 'deviceInfo2' && eventRef.value) {
|
||||||
|
// 刷新暂态补召数据
|
||||||
|
if (eventRef.value.refreshData) {
|
||||||
|
eventRef.value.refreshData(checkedNodes.value)
|
||||||
|
} else if (eventRef.value.getTableParams) {
|
||||||
|
// 如果有getTableParams方法,调用它
|
||||||
|
eventRef.value.getTableParams({ nodes: checkedNodes.value })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeClick = (node: any) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const pointTypeChange = (type: any, node: any) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.device-control {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&-left {
|
||||||
|
// width: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-right {
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px 10px 10px 0;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.el-tabs {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tabs__content {
|
||||||
|
height: calc(100% - 55px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tab-pane {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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(310px, 1fr));
|
||||||
|
grid-gap: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.box-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: var(--el-color-white);
|
||||||
|
min-height: 80px;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-control-right > div {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
133
src/views/govern/monitorRecall/steadyRecall.vue
Normal file
133
src/views/govern/monitorRecall/steadyRecall.vue
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<template>
|
||||||
|
<div class="view" style="height: 100%">
|
||||||
|
<TableHeader
|
||||||
|
datePicker
|
||||||
|
ref="headerRef"
|
||||||
|
>
|
||||||
|
<template v-slot:operation>
|
||||||
|
<el-button type="primary" :icon="Setting" @click="exportTab">补召</el-button>
|
||||||
|
</template>
|
||||||
|
</TableHeader>
|
||||||
|
<Table ref="tableRef" style="height: calc(100% - 120px)" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, onMounted, provide, nextTick, defineEmits, watch } from 'vue'
|
||||||
|
import { getTabsDataByType } from '@/api/cs-device-boot/EquipmentDelivery'
|
||||||
|
import TableStore from '@/utils/tableStore'
|
||||||
|
import Table from '@/components/table/index.vue'
|
||||||
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { Setting } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
checkedNodes: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const tableParams: any = ref({})
|
||||||
|
const headerRef = ref()
|
||||||
|
|
||||||
|
const tableStore: any = new TableStore({
|
||||||
|
url: '/cs-device-boot/portableOfflLog/queryMainLogPage',
|
||||||
|
publicHeight: 0,
|
||||||
|
method: 'POST',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
title: '序号', width: 80, formatter: (row: any) => {
|
||||||
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'projectName',
|
||||||
|
title: '工程名称',
|
||||||
|
minWidth: 170,
|
||||||
|
formatter: row => {
|
||||||
|
return row.cellValue ? row.cellValue : '/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ field: 'successCount', title: '成功解析数', minWidth: 150 },
|
||||||
|
{ field: 'startTime', title: '导入开始时间', minWidth: 170, sortable: true },
|
||||||
|
{ field: 'endTime', title: '导入结束时间', minWidth: 170 , sortable: true},
|
||||||
|
{
|
||||||
|
title: '解析状态',
|
||||||
|
field: 'status',
|
||||||
|
width: 100,
|
||||||
|
render: 'tag',
|
||||||
|
custom: {
|
||||||
|
0: 'warning',
|
||||||
|
1: 'success',
|
||||||
|
2: 'danger',
|
||||||
|
3: 'primary'
|
||||||
|
},
|
||||||
|
replaceValue: {
|
||||||
|
0: '未解析',
|
||||||
|
1: '解析成功',
|
||||||
|
2: '解析失败',
|
||||||
|
3: '文件不存在'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
width: '100',
|
||||||
|
render: 'buttons',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
name: 'edit',
|
||||||
|
title: '详情',
|
||||||
|
type: 'primary',
|
||||||
|
icon: 'el-icon-EditPen',
|
||||||
|
render: 'basicButton',
|
||||||
|
click: row => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
beforeSearchFun: () => {
|
||||||
|
|
||||||
|
},
|
||||||
|
loadCallback: () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
|
|
||||||
|
//获取请求参数
|
||||||
|
const getTableParams = (val: any) => {
|
||||||
|
tableParams.value = val
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
getTableParams
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
tableStore.index()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.header_btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view :deep(.el-table) {
|
||||||
|
height: calc(100% - 56px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user