优化暂态事件列表
This commit is contained in:
@@ -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([])
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -99,6 +99,8 @@ const getMakeUpDataList = (row: any) => {
|
||||
})
|
||||
dirList.value = res.data
|
||||
loading.value = false
|
||||
}).catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
// 进入文件夹
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user