优化暂态事件列表

This commit is contained in:
guanj
2026-06-09 19:51:31 +08:00
parent 03d302ded8
commit bda7373133
48 changed files with 1834 additions and 1474 deletions

View File

@@ -193,14 +193,14 @@
</TableHeader>
<div class="data_time" :style="{
alignItems: realTimeFlag ? 'flex-end' : 'center'
}" v-if="dataSet.includes('_realtimedata') && sonTab != 2 && trendDataTime && !realTimeFlag">
<p class="mb10 mt10">
}" v-if="dataSet.includes('_realtimedata') && sonTab != 2 && !realTimeFlag">
<p class="mb10 mt10" >
<span>数据时间:{{ trendDataTime || '-' }}</span>
</p>
<el-button v-if="!realTimeFlag && dataSet.includes('_realtimedata')" style="float: right !important"
:icon="Back" @click="handleReturn" :loading="tableLoading">
:icon="Back" @click="handleReturn" >
返回
</el-button>
</div>
@@ -225,7 +225,7 @@
">
<div class="mb10 mt10" v-if="dataSet.indexOf('_history') == -1"
style="font-weight: 700; font-size: 13px; text-align: center">
最新数据时标:{{ tableData[0]?.time || '-' }}
最新数据时标:{{ latestTime || '-' }}
</div>
<nearRealTimeData ref="nearRealTimeDataRef" v-if="dataSet.indexOf('_history') == -1"
@@ -309,8 +309,7 @@
</div>
<!-- 实时数据 -->
<div :style="`height: calc(100vh - (${sonTab == 1 ? '346px' : sonTab == 2 ? '308px' : '393px'}))`"
v-if="dataSet.indexOf('_realtimedata') != -1" v-loading="tableLoading"
>
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">
实时录波
@@ -334,7 +333,7 @@
</div>
<!-- 暂态事件 -->
<div style="height: calc(100vh - 340px)" v-if="dataSet.indexOf('_event') != -1">
<Event ref="eventRef" :deviceType="deviceType"></Event>
<Event ref="eventRef" :deviceType="deviceType" @fileRecall="handleAnalysisList"></Event>
</div>
<!-- 测试项记录 -->
<div style="height: calc(100vh - 395px)" v-if="dataSet.indexOf('_items') != -1"
@@ -503,7 +502,7 @@ const activeTrendName: any = ref(0)
const trendTimer: any = ref()
const trendDataTime: any = ref()
const showButton = ref(false)
const latestTime=ref('')
const decodeMqttPayload = (message: any) => {
try {
return JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message))))
@@ -536,7 +535,7 @@ const handleTrend = async () => {
await getHarmRealData(lineId.value, activeTrendName.value)
.then((res: any) => {
if (res.code == 'A0000') {
trendDataTime.value = ''
// trendDataTime.value = ''
// ElMessage.success('设备应答成功')
//每隔30s调用一下接口通知后台推送mqtt消息
trendTimer.value = window.setInterval(() => {
@@ -625,14 +624,14 @@ const handleReturn = async () => {
const handleSearch = () => {
let queryListName = queryList.value.filter((item: any) => item.id == formInline.targetType)
let list = tableData.value.filter((item: any) => {
if (item.otherName.includes(searchValue.value)) {
if (item.name.includes(searchValue.value)) {
return item
}
})
if (oddAndEvenFlag.value) {
list = list.filter((item: any) => {
let str = item.otherName.split('次')[0]
queryListName[0].name == '间谐波电压含有率' ? (str = str - 0.5) : ''
let str = item.name.split('次')[0]
if (oddAndEven.value == '1') {
// 奇次
@@ -689,9 +688,16 @@ const dataLevel: any = ref('')
const dataSource = ref([])
const engineeringName = ref('')
const nodeClick = async (e: anyObj, node?: any) => {
console.log("🚀 ~ nodeClick ~ node:", e)
if (e == undefined) {
return (loading.value = false)
}
if(e.pname?.includes('便携')){
deviceType.value = '1'
}else{
deviceType.value = '2'
}
searchValue.value = ''
deviceId.value = e?.pid
@@ -788,7 +794,7 @@ const nodeClick = async (e: anyObj, node?: any) => {
//治理设备和便携式设备切换判断
const deviceType = ref('0')
const pointTypeChange = (val: any, obj: any) => {
deviceType.value = val
nodeClick(obj)
}
const realTimeRef: any = ref()
@@ -1234,21 +1240,23 @@ const handleClick = async (tab?: any) => {
//查询当前指标
if (!dataSet.value.includes('_')) {
formInline.id = dataSet.value
latestTime.value=''
tableData.value=[]
// await deviceRtData(formInline)
await realTimeData(formInline)
.then((res: any) => {
tableData.value = res.data
tableData.value = res.data[0].children
latestTime.value=res.data[0].dataTime
formInline.total = res.data.total
let queryListName = queryList.value.filter((item: any) => item.id == formInline.targetType)
let list = tableData.value.filter((item: any) => {
if (item.otherName.includes(searchValue.value)) {
if (item.name.includes(searchValue.value)) {
return item
}
})
if (oddAndEvenFlag.value) {
list = list.filter((item: any) => {
let str = item.otherName.split('次')[0]
queryListName[0].name == '间谐波电压含有率' ? (str = str - 0.5) : ''
let str = item.name.split('次')[0]
if (oddAndEven.value == '1') {
// 奇次
@@ -1276,6 +1284,7 @@ const handleClick = async (tab?: any) => {
}, 1500)
})
.catch(e => {
loading.value = false
setTimeout(() => {
tableLoading.value = false
}, 1500)
@@ -1340,10 +1349,12 @@ queryByCode('Device_Type').then(res => {
})
})
const handleTargetTypeChange = () => {
if (queryList.value.filter((item: any) => item.id == formInline.targetType)[0].name != '基本数据') {
oddAndEvenFlag.value = true
const targetItem = queryList.value.filter((item: any) => item.id == formInline.targetType)[0];
if (targetItem?.name !== '基本数据' && !targetItem?.name?.includes('间谐波')) {
oddAndEvenFlag.value = true;
} else {
oddAndEvenFlag.value = false
oddAndEvenFlag.value = false;
}
}
const queryList: any = ref([])

View File

@@ -1,17 +1,18 @@
<template>
<div class="near-realtime-data">
<div class="view_bot">
<template v-for="(section, sectionIndex) in tableSections" :key="sectionIndex">
<vxe-table class="near-realtime-table" border height="" width="100%" :data="[section.row]"
:column-config="tableColumnConfig" :tooltip-config="tableTooltipConfig">
<vxe-colgroup v-for="(item, colIndex) in section.abcItems" :key="`abc-${colIndex}`" align="center"
:title="item.otherName" :width="getMetricWidth(section)">
<vxe-column align="center" :field="`v${colIndex}A`" title="A相" :width="getPhaseWidth(section)"
:formatter="cellFormatter"></vxe-column>
<vxe-column align="center" :field="`v${colIndex}B`" title="B相" :width="getPhaseWidth(section)"
:formatter="cellFormatter"></vxe-column>
<vxe-column align="center" :field="`v${colIndex}C`" title="C相" :width="getPhaseWidth(section)"
:formatter="cellFormatter"></vxe-column>
<vxe-column align="center" :field="`v${colIndex}A`" :title="item.phaseLabels[0]"
:width="getPhaseWidth(section)" :formatter="cellFormatter"></vxe-column>
<vxe-column align="center" :field="`v${colIndex}B`" :title="item.phaseLabels[1]"
:width="getPhaseWidth(section)" :formatter="cellFormatter"></vxe-column>
<vxe-column align="center" :field="`v${colIndex}C`" :title="item.phaseLabels[2]"
:width="getPhaseWidth(section)" :formatter="cellFormatter"></vxe-column>
</vxe-colgroup>
<vxe-column v-for="(item, colIndex) in section.scalarItems" :key="`scalar-${colIndex}`"
align="center" :field="`s${colIndex}`" :title="item.otherName" :width="getMetricWidth(section)"
@@ -34,19 +35,48 @@ import { ref } from 'vue'
const ROW_WITH_ABC = 4
const ROW_SCALAR_ONLY = 5
interface DisplayMetric {
otherName: string
valueA?: unknown
valueB?: unknown
valueC?: unknown
valueM?: unknown
phaseLabels: [string, string, string]
sort: number
}
interface MetricItem {
type: 'abc' | 'scalar'
data: any
data: DisplayMetric
}
interface TableSection {
abcItems: any[]
scalarItems: any[]
abcItems: DisplayMetric[]
scalarItems: DisplayMetric[]
row: Record<string, unknown>
slotsPerRow: number
emptySlotCount: number
}
interface RawMetricItem {
targetId?: string
name?: string
unit?: string | null
phase?: string
sort?: number
data?: unknown
otherName?: string
valueA?: unknown
valueB?: unknown
valueC?: unknown
valueM?: unknown
}
const PHASE_GROUPS = [
{ keys: ['A', 'B', 'C'], labels: ['A相', 'B相', 'C相'] as [string, string, string] },
{ keys: ['AB', 'BC', 'CA'], labels: ['AB', 'BC', 'CA'] as [string, string, string] },
]
const height = mainHeight(345)
const tableSections = ref<TableSection[]>([])
@@ -64,10 +94,103 @@ const formatCellValue = (value: unknown): string | number => {
const cellFormatter = ({ cellValue }: { cellValue: unknown }) => formatCellValue(cellValue)
const hasAbcValues = (item: any) =>
const buildOtherName = (name: string, unit?: string | null) => (unit ? `${name}(${unit})` : name)
const isNewFormat = (item: RawMetricItem) => item.targetId != null && item.phase != null && 'data' in item
const hasAbcValues = (item: DisplayMetric | RawMetricItem) =>
item.valueA != null || item.valueB != null || item.valueC != null
const buildRow = (abcItems: any[], scalarItems: any[]) => {
const normalizeOldItem = (item: RawMetricItem): DisplayMetric => ({
otherName: item.otherName || buildOtherName(item.name || ''),
valueA: item.valueA,
valueB: item.valueB,
valueC: item.valueC,
valueM: item.valueM,
phaseLabels: ['A相', 'B相', 'C相'],
sort: item.sort ?? 0,
})
const getHarmonicOrder = (name: string) => {
const match = name.match(/^(\d+(?:\.\d+)?)次/)
return match ? parseFloat(match[1]) : null
}
const getGroupKey = (item: RawMetricItem) => `${item.targetId}_${item.name}`
const groupNewFormatData = (list: RawMetricItem[]): DisplayMetric[] => {
const groupMap = new Map<string, { name: string; unit: string | null; sort: number; phases: Record<string, unknown> }>()
list.forEach(item => {
const key = getGroupKey(item)
if (!groupMap.has(key)) {
groupMap.set(key, {
name: item.name || '',
unit: item.unit ?? null,
sort: item.sort ?? 0,
phases: {},
})
}
if (item.phase != null) {
groupMap.get(key)!.phases[item.phase] = item.data
}
})
return Array.from(groupMap.values())
.sort((a, b) => {
if (a.sort !== b.sort) return a.sort - b.sort
const orderA = getHarmonicOrder(a.name)
const orderB = getHarmonicOrder(b.name)
if (orderA != null && orderB != null) return orderA - orderB
return a.name.localeCompare(b.name, 'zh-CN')
})
.map(group => {
const otherName = buildOtherName(group.name, group.unit)
const phaseKeys = Object.keys(group.phases)
if (phaseKeys.length === 1 && phaseKeys[0] === 'T') {
return {
otherName,
valueM: group.phases.T,
phaseLabels: ['A相', 'B相', 'C相'],
sort: group.sort,
}
}
for (const { keys, labels } of PHASE_GROUPS) {
if (keys.some(key => group.phases[key] != null)) {
return {
otherName,
valueA: group.phases[keys[0]],
valueB: group.phases[keys[1]],
valueC: group.phases[keys[2]],
phaseLabels: labels,
sort: group.sort,
}
}
}
return {
otherName,
valueM: phaseKeys.length === 1 ? group.phases[phaseKeys[0]] : undefined,
valueA: group.phases.A ?? group.phases.AB,
valueB: group.phases.B ?? group.phases.BC,
valueC: group.phases.C ?? group.phases.CA,
phaseLabels: group.phases.AB != null ? ['AB', 'BC', 'CA'] : ['A相', 'B相', 'C相'],
sort: group.sort,
}
})
}
const normalizeMetrics = (data: RawMetricItem[]): DisplayMetric[] => {
if (!data?.length) return []
if (isNewFormat(data[0])) {
return groupNewFormatData(data)
}
return data.map(normalizeOldItem).sort((a, b) => a.sort - b.sort)
}
const buildRow = (abcItems: DisplayMetric[], scalarItems: DisplayMetric[]) => {
const row: Record<string, unknown> = {}
abcItems.forEach((item, index) => {
row[`v${index}A`] = item.valueA
@@ -80,10 +203,10 @@ const buildRow = (abcItems: any[], scalarItems: any[]) => {
return row
}
const buildTableSections = (abcList: any[], scalarList: any[]) => {
const buildTableSections = (abcList: DisplayMetric[], scalarList: DisplayMetric[]) => {
const unified: MetricItem[] = [
...abcList.map((data) => ({ type: 'abc' as const, data })),
...scalarList.map((data) => ({ type: 'scalar' as const, data })),
...abcList.map(data => ({ type: 'abc' as const, data })),
...scalarList.map(data => ({ type: 'scalar' as const, data })),
]
const sections: TableSection[] = []
@@ -95,8 +218,8 @@ const buildTableSections = (abcList: any[], scalarList: any[]) => {
const chunk = unified.slice(index, index + maxCount)
index += chunk.length
const abcItems = chunk.filter((item) => item.type === 'abc').map((item) => item.data)
const scalarItems = chunk.filter((item) => item.type === 'scalar').map((item) => item.data)
const abcItems = chunk.filter(item => item.type === 'abc').map(item => item.data)
const scalarItems = chunk.filter(item => item.type === 'scalar').map(item => item.data)
const slotsPerRow = abcItems.length > 0 ? ROW_WITH_ABC : ROW_SCALAR_ONLY
const metricCount = abcItems.length + scalarItems.length
sections.push({
@@ -111,18 +234,11 @@ const buildTableSections = (abcList: any[], scalarList: any[]) => {
return sections
}
const setData = (data: any, _targetType: any) => {
const list = JSON.parse(JSON.stringify(data))
const abcList: any[] = []
const scalarList: any[] = []
list.forEach((item: any) => {
if (hasAbcValues(item)) {
abcList.push(item)
} else {
scalarList.push(item)
}
})
const setData = (data: RawMetricItem[], _targetType?: unknown) => {
const list = JSON.parse(JSON.stringify(data || [])) as RawMetricItem[]
const metrics = normalizeMetrics(list)
const abcList = metrics.filter(item => hasAbcValues(item))
const scalarList = metrics.filter(item => !hasAbcValues(item))
tableSections.value = buildTableSections(abcList, scalarList)
}

View File

@@ -99,6 +99,8 @@ const getMakeUpDataList = (row: any) => {
})
dirList.value = res.data
loading.value = false
}).catch(() => {
loading.value = false
})
}
// 进入文件夹

View File

@@ -4,8 +4,8 @@
<div class="harmonic_select" v-if="!loading">
<el-form :model="searchForm" id="history_select">
<el-form-item label="稳态指标">
<el-select multiple collapse-tags collapse-tags-tooltip filterable v-model.trim="searchForm.index"
placeholder="请选择统计指标" :multiple-limit="3" value-key="id">
<el-select multiple collapse-tags collapse-tags-tooltip filterable v-model.trim="searchForm.index"
placeholder="请选择统计指标" :multiple-limit="3" value-key="id">
<el-option v-for="(item, index) in indexOptions" :label="item.name" :key="index"
:value="item"></el-option>
</el-select>
@@ -145,6 +145,31 @@ const loading = ref(false)
const allDataList: any = ref([])
const xAixsTimeList: any = ref([])
const formatChartValueText = (val: unknown, digits = 2) => {
if (val == null || val === '') return '-'
const num = Number(val)
if (Number.isNaN(num)) return '-'
return num.toFixed(digits)
}
const axisPointerLabelFormatter = (params: any) => {
if (params.axisDimension === 'x') {
return params.value ?? '-'
}
return formatChartValueText(params.value)
}
const tooltipFormatter = (params: any) => {
const list = Array.isArray(params) ? params : [params]
if (!list.length) return ''
let html = `${list[0].axisValueLabel ?? list[0].name ?? ''}`
list.forEach((item: any) => {
const rawValue = Array.isArray(item.value) ? item.value[1] : item.value
html += `<br/>${item.marker}${item.seriesName}: ${formatChartValueText(rawValue)}`
})
return html
}
const resetData = (dataLevel: string) => {
loading.value = true
indexOptions.value = [
@@ -259,7 +284,7 @@ const resetData = (dataLevel: string) => {
resetData('Primary')
const mqttMessage: any = ref()
const setHarmonicSpectrumData = (val: any) => {
mqttMessage.value = val
init()
}
@@ -285,7 +310,7 @@ const init = () => {
// 清空当前时间点的数据(如果存在),防止重复
const currentTime = mqttMessage.value.dataTime.split(" ")[1];
vv.yMethodList = vv.yMethodList.filter((point: any) => point[0] !== currentTime);
item.data.push({
// time: mqttMessage.value.dataTime,
value: mqttMessage.value[vv.name],
@@ -295,7 +320,7 @@ const init = () => {
vv.data.push(mqttMessage.value[vv.name])
// 更新yMethodList数据确保与xAixsTimeList保持同步
vv.yMethodList.push([currentTime, mqttMessage.value[vv.name] + '', vv.phase])
// 限制数据点数量,避免过多数据点导致性能问题和显示重复
if (vv.yMethodList.length > 50) {
vv.yMethodList.shift()
@@ -320,11 +345,14 @@ const init = () => {
// right: '4%'
// },
tooltip: {
trigger: 'axis',
formatter: tooltipFormatter,
axisPointer: {
type: 'cross',
label: {
color: '#fff',
fontSize: 16
fontSize: 16,
formatter: axisPointerLabelFormatter
}
},
textStyle: {

View File

@@ -1,8 +1,8 @@
<!-- 实时数据 - 谐波频谱页面 -->
<template>
<div class="realtrend" v-loading="loading">
<div class="select" v-if="!loading">
<div class="mr10">次数</div>
<div class="select" v-if="!loading && !isInterharmonicTab">
<div class="mr10">谐波次数</div>
<el-select v-model.trim="selectValue" style="width: 100px" @change="selectChange">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
@@ -29,17 +29,19 @@
</div> -->
<div class="realtrend_table" v-if="Object.keys(tableData).length != 0">
<div class="thead_left">
<p style="font-weight: 700; background-color: #f3f6f9">次数()</p>
<p style="font-weight: 700; background-color: #f3f6f9">
{{ isInterharmonicTab ? '间谐波次数(次)' : '谐波次数(次)' }}
</p>
<p>{{ item.groupName }}{{ item.unit ? '(' + item.unit + ')' : '' }}</p>
<!-- <p>国标限值{{ item.unit ? '(' + item.unit + ')' : '' }}</p> -->
</div>
<div class="thead_right">
<div class="right_cell" v-for="(value, key, index) in tableData" :key="index">
<p v-if="item.groupName.includes('间谐波')" style="background-color: #f3f6f9">
{{ Number(String(key).replace('data', ' ')) - 0.5 }}
<p v-if="isInterharmonicTab" style="background-color: #f3f6f9">
{{ getHarmonicOrder(key, true) }}
</p>
<p v-else style="background-color: #f3f6f9">
<span>{{ String(key).replace('data', ' ') }}</span>
<span>{{ getHarmonicOrder(key) }}</span>
</p>
<p>
<span
@@ -78,14 +80,19 @@
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, defineEmits } from 'vue'
import { ref, onMounted, computed } from 'vue'
import { VxeGridProps } from 'vxe-table'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import MyEchart from '@/components/echarts/MyEchart.vue'
const activeName = ref(0)
const emit = defineEmits(['changeTrendType'])
const tableList: any = []
const selectValue = ref('1')
const selectValue = ref('3')
const getHarmonicOrder = (key: string | number, interharmonic = false) => {
const order = Number(String(key).replace('data', ''))
return interharmonic ? order - 0.5 : order
}
const options = [
{
@@ -142,6 +149,9 @@ const tabsList: any = ref([
unit: '%'
}
])
const isInterharmonicTab = computed(() => {
return tabsList.value[activeName.value]?.groupName?.includes('间谐波')
})
const loading: any = ref(true)
//接收参数
const params = ref({})
@@ -208,9 +218,9 @@ const init = () => {
value: limitData.value[key]
})
}
if (selectValue.value == '1') {
if (!isInterharmonicTab.value && selectValue.value == '1') {
gbData.value = gbData.value.filter((_, index: number) => index % 2 !== 0)
} else if (selectValue.value == '2') {
} else if (!isInterharmonicTab.value && selectValue.value == '2') {
gbData.value = gbData.value.filter((_, index: number) => index % 2 == 0)
}
let xAxisList: any = []
@@ -229,9 +239,10 @@ const init = () => {
echartsData.value = {
color: ['#2E8B57', '#DAA520'],
xAxis: {
name: '次数',
name: isInterharmonicTab.value ? '间谐波次数' : '谐波次数',
data: trendData.map((item: any) => {
return (activeName.value == 2 ? item.count - 0.5 : item.count) + '次'
const count = isInterharmonicTab.value ? item.count - 0.5 : item.count
return `${count}次`
})
},
yAxis: {
@@ -278,6 +289,19 @@ const handleClick = (tab: any, event: any) => {
//获取mqtt传送的实时数据
const mqttMessage: any = ref()
const tableData: any = ref({})
const shouldIncludeHarmonicData = (numberPart: number) => {
if (isInterharmonicTab.value) {
return numberPart < 17
}
if (selectValue.value === '3') {
return true
}
if (selectValue.value === '2') {
return numberPart % 2 === 0
}
return numberPart % 2 !== 0
}
const setRealTrendData = (val: any) => {
mqttMessage.value = {}
if (!val) {
@@ -289,44 +313,14 @@ const setRealTrendData = (val: any) => {
for (let key in val) {
if (String(key).includes('data') && String(key) != 'dataLevel' && String(key) != 'dataTime') {
const numberPart = parseInt(key.replace('data', ''))
if (selectValue.value != '3') {
if (selectValue.value == '2') {
if (activeName.value == 2) {
if (numberPart % 2 !== 0 && numberPart < 17) {
tableData.value[key] = val[key].toFixed(2)
}
} else {
if (numberPart % 2 === 0) {
tableData.value[key] = val[key].toFixed(2)
}
}
} else {
if (activeName.value == 2) {
if (numberPart % 2 === 0 && numberPart < 17) {
tableData.value[key] = val[key].toFixed(2)
}
} else {
if (numberPart % 2 !== 0) {
tableData.value[key] = val[key].toFixed(2)
}
}
}
} else {
if (activeName.value == 2) {
if (numberPart < 17) {
tableData.value[key] = val[key].toFixed(2)
}
} else {
tableData.value[key] = val[key].toFixed(2)
}
if (shouldIncludeHarmonicData(numberPart)) {
tableData.value[key] = val[key].toFixed(2)
}
}
}
if (!tabsList.value[activeName.value].groupName.includes('间谐波')) {
if (!isInterharmonicTab.value) {
delete tableData.value.data1
} else {
// console.log('不删除')
}
if (Object.keys(tableData.value).length != 0) {
init()
@@ -335,11 +329,11 @@ const setRealTrendData = (val: any) => {
emit('changeTrendType', activeName.value)
}
}
const selectChange = (val: any) => {
loading.value = true
// setTimeout(() => {
// loading.value=false
// },3000)
const selectChange = () => {
if (isInterharmonicTab.value) return
if (mqttMessage.value && Object.keys(mqttMessage.value).length) {
setRealTrendData(mqttMessage.value)
}
}
//获取国标限值
const limitData: any = ref()

View File

@@ -1,18 +1,25 @@
<template>
<div class="view">
<div v-show="!isWaveCharts">
<TableHeader datePicker ref="headerRef" :showReset="false"></TableHeader>
<TableHeader datePicker showExport ref="headerRef" @onResetForm="onResetForm">
<template v-slot:operation>
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
<MultiCondition v-model:visible="filterVisible" :params="tableStore.table.params" ref="multiConditionRef"
@confirm="onFilterConfirm" />
</div>
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef"
@handleHideCharts="isWaveCharts = false" :wp="wp" />
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, provide, nextTick, defineEmits } from 'vue'
import { ref, onMounted, provide, nextTick, } from 'vue'
import { getTabsDataByType } from '@/api/cs-device-boot/EquipmentDelivery'
import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import MultiCondition from '@/views/govern/alarm/multiCondition.vue'
import TableHeader from '@/components/table/header/index.vue'
import waveFormAnalysis from './components/waveFormAnalysis.vue'
import { ArrowLeft, Message } from '@element-plus/icons-vue'
@@ -20,6 +27,7 @@ import { ElMessage } from 'element-plus'
import { analyseWave, getFileByEventId } from '@/api/common'
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
import { useDictData } from '@/stores/dictData'
const emit=defineEmits(['fileRecall'])
const tableParams: any = ref({})
const refheader = ref()
const view = ref(true)
@@ -31,7 +39,7 @@ const boxoList: any = ref([])
const wp = ref({})
const value = ref(1)
const waveFormAnalysisRef = ref()
const headerRef = ref()
const multiConditionRef = ref()
const props = defineProps({
deviceType: {
@@ -46,6 +54,7 @@ const tableStore: any = new TableStore({
url: '/cs-device-boot/csGroup/deviceDataByType',
publicHeight: 215,
method: 'POST',
exportName: '暂态事件',
column: [
// { width: '60', type: 'checkbox', fixed: 'left' },
{
@@ -91,15 +100,20 @@ const tableStore: any = new TableStore({
return row.cellValue || '-'
}
},
{ field: 'showName', title: '触发类型', minWidth: 120 },
{
title: '严重度', field: 'severity', minWidth: 80, align: 'center', sortable: true, formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/'
}
},
{ field: 'showName', title: '触发类型', minWidth: 100 },
{
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
return ReasonList.find((item: any) => item.value == row.cellValue)?.label || '未知'
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
}
},
{
title: '暂降类型', field: 'advanceType', minWidth: 100, align: 'center', formatter: (row: any) => {
return EventTypeList.find((item: any) => item.value == row.cellValue)?.label || '未知'
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '未知'
}
},
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true, },
@@ -161,16 +175,16 @@ const tableStore: any = new TableStore({
})
}
},
{
name: 'edit',
text: '暂无波形',
type: 'info',
icon: 'el-icon-DataLine',
render: 'basicButton',
disabled: row => {
return row.wavePath
}
},
// {
// name: 'edit',
// text: '暂无波形',
// type: 'info',
// icon: 'el-icon-DataLine',
// render: 'basicButton',
// disabled: row => {
// return row.wavePath
// }
// },
{
name: 'edit',
title: '波形下载',
@@ -207,14 +221,24 @@ const tableStore: any = new TableStore({
type: 'primary',
icon: 'el-icon-Check',
render: 'basicButton',
loading: 'loading3',
disabled: row => {
return !(props.deviceType == '2' && row.wavePath == null)
return !(row.wavePath == null)
},
click: row => {
getFileByEventId(row.id).then(res => {
ElMessage.success(res.message)
tableStore.index()
})
if (props.deviceType == '2') {
row.loading3 = true
getFileByEventId(row.id).then(res => {
ElMessage.success(res.message)
tableStore.index()
row.loading3 = false
}).catch(() => {
row.loading3 = false
})
}else if(props.deviceType == '1'){
emit('fileRecall', row.id)
}
}
}
]
@@ -229,6 +253,27 @@ const tableStore: any = new TableStore({
},
loadCallback: () => { }
})
Object.assign(tableStore.table.params, {
featureAmplitudeMin: undefined,
featureAmplitudeMax: undefined,
evtParamTmMin: undefined,
evtParamTmMax: undefined,
severityMin: undefined,
severityMax: undefined,
fileFlag: ''
})
// 重置
const onResetForm = () => {
filterVisible.value = false
tableStore.table.params.cascader = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.deviceTypeName = ''
multiConditionRef.value?.reset()
}
const filterVisible = ref(false)
provide('tableStore', tableStore)
const isWaveCharts = ref(false)
//获取请求参数
@@ -237,17 +282,18 @@ const getTableParams = (val: any) => {
isWaveCharts.value = false
tableStore.index()
}
//返回
const handleBack = async () => {
isWaveCharts.value = false
emit('activeTabsType', '')
await tableStore.index()
const onFilterConfirm = () => {
tableStore.onTableAction('search', {})
}
const openFilterDialog = () => {
filterVisible.value = true
}
defineExpose({ getTableParams })
onMounted(() => {
console.log('🚀 ~ props.deviceType:', props.deviceType)
tableStore.index()
// tableStore.index()
})
</script>
<style lang="scss" scoped>

View File

@@ -1,7 +1,16 @@
<template>
<div>
<div v-show="!isWaveCharts">
<TableHeader showExport ref="headerRef" @onResetForm="onResetForm">
<template v-slot:operation>
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>
</template>
</TableHeader>
<Table ref="tableRef" />
<MultiCondition v-model:visible="filterVisible" :params="tableStore.table.params" ref="multiConditionRef"
@confirm="onFilterConfirm" />
<!-- 补召日志 -->
<analysisList ref="analysisListRef"></analysisList>
</div>
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef"
@handleHideCharts="isWaveCharts = false" :wp="wp" />
@@ -20,10 +29,14 @@ import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue'
import { ElMessage } from 'element-plus'
import MultiCondition from '@/views/govern/alarm/multiCondition.vue'
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue';
import { analyseWave } from '@/api/common'
import { analyseWave, getFileByEventId } from '@/api/common'
import { mainHeight } from '@/utils/layout'
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
import analysisList from '@/views/govern/device/control/analysisList/index.vue'
import { useDictData } from '@/stores/dictData'
const props = defineProps({
activeName: String,
@@ -33,10 +46,14 @@ const loading = ref(false)
const dictData = useDictData()
const ReasonList: any = dictData.getBasicData('Event_Reason')
const EventTypeList: any = dictData.getBasicData('Event_Type')
const DeviceType = ref([])
const waveFormAnalysisRef = ref()
const isWaveCharts = ref(false)
const boxoList: any = ref([])
const analysisListRef = ref()
const wp = ref({})
const filterVisible = ref(false)
const multiConditionRef = ref()
const tableStore = new TableStore({
url: '/cs-harmonic-boot/data/getEventByItem',
method: 'POST',
@@ -72,6 +89,11 @@ const tableStore = new TableStore({
return row.cellValue
}, sortable: true
},
{
title: '严重度', field: 'severity', minWidth: 80, align: 'center', sortable: true, formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/'
}
},
{
field: 'phaseType',
title: '相别',
@@ -83,15 +105,15 @@ const tableStore = new TableStore({
},
{ field: 'showName', title: '触发类型', minWidth: 170 },
{ field: 'showName', title: '触发类型', minWidth: 100 },
{
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
return ReasonList.find((item: any) => item.value == row.cellValue)?.label || '未知'
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
}
},
{
title: '暂降类型', field: 'advanceType', minWidth: 100, align: 'center', formatter: (row: any) => {
return EventTypeList.find((item: any) => item.value == row.cellValue)?.label || '未知'
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '未知'
}
},
{ title: '监测点名称', field: 'lineName', minWidth: 120, align: 'center' },
@@ -150,16 +172,16 @@ const tableStore = new TableStore({
})
}
},
{
name: 'edit',
text: '暂无波形',
type: 'info',
icon: 'el-icon-DataLine',
render: 'basicButton',
disabled: row => {
return row.wavePath
}
},
// {
// name: 'edit',
// text: '暂无波形',
// type: 'info',
// icon: 'el-icon-DataLine',
// render: 'basicButton',
// disabled: row => {
// return row.wavePath
// }
// },
{
name: 'edit',
title: '波形下载',
@@ -190,7 +212,56 @@ const tableStore = new TableStore({
})
}
}
},
{
name: 'edit',
text: '暂不支持补召',
type: 'info',
icon: 'el-icon-DataLine',
render: 'basicButton',
disabled: row => {
let code = DeviceType.value.filter((item: any) => item.id == row.devType)[0]?.code
return !(code == 'Direct_Connected_Device' || code == 'Gateway')
},
},
{
name: 'edit',
text: '波形补召',
type: 'primary',
icon: 'el-icon-DataLine',
render: 'basicButton',
loading: 'loading2',
disabled: row => {
return row.wavePath
},
click: row => {
let code = DeviceType.value.filter((item: any) => item.id == row.devType)[0]?.code
if (code == 'Portable') {
// 便携式设备
analysisListRef.value &&
analysisListRef.value.open({
lineId: row.lineId,
deviceData: row,
deviceId: row.deviceId
})
} else if (code == 'DEV_CLD') {
row.loading2 = true
// 监测设备
getFileByEventId(row.id).then(res => {
ElMessage.success(res.message)
tableStore.index()
row.loading2 = false
}).catch(() => {
row.loading2 = false
})
}
}
},
]
}
],
@@ -199,6 +270,15 @@ const tableStore = new TableStore({
}
})
Object.assign(tableStore.table.params, {
featureAmplitudeMin: undefined,
featureAmplitudeMax: undefined,
evtParamTmMin: undefined,
evtParamTmMax: undefined,
severityMin: undefined,
severityMax: undefined,
fileFlag: ''
})
const setHeight = () => {
if (props.activeColName == '0') {
waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(350, 485)
@@ -209,6 +289,23 @@ const setHeight = () => {
tableStore.table.height = mainHeight(240).height
}
}
queryByCode('Device_Type').then(res => {
queryCsDictTree(res.data.id).then((list: any) => {
DeviceType.value = list.data
})
})
const onResetForm = () => {
filterVisible.value = false
tableStore.table.params.cascader = ''
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = ''
tableStore.table.params.deviceTypeName = ''
multiConditionRef.value?.reset()
}
provide('tableStore', tableStore)
const init = () => {
tableStore.table.params.id = props.activeName
@@ -217,6 +314,12 @@ const init = () => {
// })
tableStore.index()
}
const onFilterConfirm = () => {
tableStore.onTableAction('search', {})
}
const openFilterDialog = () => {
filterVisible.value = true
}
onMounted(() => {
})