修改测试问题
This commit is contained in:
@@ -455,7 +455,8 @@ const handleTolerableEventClick = async (row: any) => {
|
||||
persistTime: row.value[0], //持续时间
|
||||
featureAmplitude: (row.value[1] / 100), //残余电压
|
||||
startTime: row.value[2], //时间
|
||||
lineName: row.value[4] //监测点名称
|
||||
lineName: row.value[4], //监测点名称
|
||||
engineeringName: row.value[5],
|
||||
}
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
|
||||
@@ -387,7 +387,8 @@ const handleTolerableEventClick = async (row: any) => {
|
||||
persistTime: row.value[0], //持续时间
|
||||
featureAmplitude: (row.value[1] / 100), //残余电压
|
||||
startTime: row.value[2], //时间
|
||||
lineName: row.value[4] //监测点名称
|
||||
lineName: row.value[4], //监测点名称
|
||||
engineeringName: row.value[5],
|
||||
}
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
|
||||
@@ -82,15 +82,50 @@ const tableStore: any = new TableStore({
|
||||
title: '指标名称',
|
||||
field: 'name',
|
||||
minWidth: 120
|
||||
}, {
|
||||
title: '越限时间',
|
||||
field: 'time',
|
||||
minWidth: 100,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限最高监测点',
|
||||
title: '越限最高监测点名称',
|
||||
field: 'lineName',
|
||||
minWidth: 120,
|
||||
minWidth: 140,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限程度(%)',
|
||||
field: 'extent',
|
||||
minWidth: 100,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue ? Math.floor(row.cellValue * 100) / 100 : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限最大值',
|
||||
field: 'maxValue',
|
||||
minWidth: 100,
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
const extentValue =
|
||||
row.maxValue !== null && row.maxValue !== undefined && row.maxValue !== ''
|
||||
? Math.floor(row.maxValue * 100) / 100
|
||||
: '/'
|
||||
return extentValue == '/' ? '/' : `<span style='cursor: pointer;text-decoration: underline;'>${extentValue}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '国标限值',
|
||||
field: 'internationalValue',
|
||||
minWidth: 100, formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '设备名称', field: 'devName', minWidth: 130, align: 'center', formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
@@ -106,42 +141,9 @@ const tableStore: any = new TableStore({
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限最大值',
|
||||
field: 'maxValue',
|
||||
minWidth: 100,
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
const extentValue =
|
||||
row.maxValue !== null && row.maxValue !== undefined && row.maxValue !== ''
|
||||
? Math.floor(row.maxValue * 100) / 100
|
||||
: '/'
|
||||
return extentValue=='/' ? '/' : `<span style='cursor: pointer;text-decoration: underline;'>${extentValue}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '国标限值',
|
||||
field: 'internationalValue',
|
||||
minWidth: 100, formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限程度(%)',
|
||||
field: 'extent',
|
||||
minWidth: 100,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue? Math.floor(row.cellValue * 100) / 100 : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限时间',
|
||||
field: 'time',
|
||||
minWidth: 100,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
|
||||
@@ -46,6 +46,7 @@ import { ref, onMounted, onUnmounted, provide, reactive, watch, h, computed, nex
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
||||
import { destroyLuckysheet, renderLuckysheetReport } from '@/utils/luckysheetHelper'
|
||||
import { buildExportBaseName } from '@/utils/echartMethod'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
@@ -72,6 +73,8 @@ const templateList = ref([])
|
||||
const idList = ref()
|
||||
|
||||
|
||||
const exportSubjectName = ref('')
|
||||
|
||||
const handleNodeClick = async (data: any) => {
|
||||
if (templateList.value.length == 0) {
|
||||
await querySysExcel({}).then(res => {
|
||||
@@ -83,6 +86,8 @@ const handleNodeClick = async (data: any) => {
|
||||
}
|
||||
|
||||
if (data?.level == 3 || data?.level == 2) {
|
||||
exportSubjectName.value = data.name || ''
|
||||
tableStore.exportName = { subject: exportSubjectName.value, feature: '治理效果报表' }
|
||||
tableStore.table.params.sensitiveUserId = data.id
|
||||
await tableStore.index()
|
||||
} else {
|
||||
@@ -104,7 +109,14 @@ const templateListData = () => {
|
||||
}
|
||||
// 下载表格
|
||||
const downloadExcel = () => {
|
||||
exportExcel(luckysheet.getAllSheets(), '治理效果报表')
|
||||
exportExcel(
|
||||
luckysheet.getAllSheets(),
|
||||
buildExportBaseName({
|
||||
subject: exportSubjectName.value,
|
||||
feature: '治理效果报表',
|
||||
date: tableStore.table.params.searchEndTime || tableStore.table.params.searchBeginTime
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -343,6 +343,11 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: trendRequestData.value?.lineName,
|
||||
feature: '趋势图',
|
||||
date: datePickerRef.value?.timeValue?.[1] || datePickerRef.value?.timeValue?.[0]
|
||||
},
|
||||
legend: {
|
||||
itemWidth: 20,
|
||||
itemHeight: 20,
|
||||
@@ -411,10 +416,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
exportSeriesCSV(
|
||||
echartsData.value.options.series,
|
||||
`${dialogTitle.value || '监测点指标趋势'}.csv`
|
||||
)
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -342,6 +342,11 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: trendRequestData.value?.lineName,
|
||||
feature: '趋势图',
|
||||
date: datePickerRef.value?.timeValue?.[1] || datePickerRef.value?.timeValue?.[0]
|
||||
},
|
||||
legend: {
|
||||
itemWidth: 20,
|
||||
itemHeight: 20,
|
||||
@@ -410,10 +415,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
exportSeriesCSV(
|
||||
echartsData.value.options.series,
|
||||
`${dialogTitle.value || '历史趋势'}.csv`
|
||||
)
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--主要监测点列表 -->
|
||||
<TableHeader :showReset="false" :timeKeyList="prop.timeKey" @selectChange="selectChange" v-if="fullscreen"
|
||||
ref="TableHeaderRef">
|
||||
<TableHeader :showReset="false" showExport :timeKeyList="prop.timeKey" @selectChange="selectChange"
|
||||
v-if="fullscreen" ref="TableHeaderRef">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input maxlength="32" show-word-limit v-model="tableStore.table.params.keywords" clearable
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch, nextTick } from 'vue'
|
||||
import { ref, onMounted, provide, watch, computed } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
|
||||
@@ -75,8 +75,6 @@ import { getTime } from '@/utils/formatTime'
|
||||
import { exportSeriesCSV } from '@/utils/echartMethod'
|
||||
import PointTree from '@/components/tree/govern/pointTree.vue'
|
||||
|
||||
const CSV_DOWNLOAD_ICON =
|
||||
'path://M896 346.8c-0.1 0 0 0 0 0 0-0.9-0.1-1.7-0.2-2.5 0-0.1 0-0.3-0.1-0.4-0.2-1.7-0.5-3.3-1-4.9-0.5-1.7-1-3.3-1.7-4.9v-0.1c-0.3-0.8-0.7-1.5-1.1-2.3v-0.1c-0.4-0.7-0.8-1.5-1.2-2.2-0.1-0.1-0.1-0.2-0.2-0.3-0.4-0.6-0.8-1.2-1.3-1.9-0.1-0.1-0.1-0.2-0.2-0.2-0.5-0.6-1-1.3-1.5-1.9-0.1-0.1-0.2-0.3-0.4-0.4-0.5-0.6-1-1.2-1.6-1.7l-0.1-0.1L637.3 74.5c-0.6-0.6-1.2-1.1-1.8-1.6-0.1-0.1-0.3-0.2-0.4-0.4-0.6-0.5-1.2-1-1.9-1.5-0.1 0-0.1-0.1-0.2-0.1-0.6-0.5-1.3-0.9-1.9-1.3-0.1-0.1-0.2-0.1-0.3-0.2-0.7-0.4-1.4-0.9-2.2-1.3-0.8-0.4-1.5-0.8-2.3-1.1h-0.1c-1.6-0.7-3.2-1.3-4.9-1.7-1.6-0.4-3.2-0.8-4.9-1-0.1 0-0.3 0-0.4-0.1-1.4-0.2-2.8-0.3-4.3-0.3H164c-19.9 0-36 16.1-36 36v823.3c0 19.9 16.1 36 36 36h696c19.9 0 36-16.1 36-36V348.6v-1.8zM647.8 186.9l125.4 125.6H647.8V186.9zM200 887.2V135.9h375.8v212.7c0 19.9 16.1 36 36 36H824v502.7H200zM363.5 661.5c-7.2 6.3-15.8 9.5-25.8 9.5-13.5 0-24.5-5-33-15S292 629.3 292 605.7c0-22.2 4.3-38.2 12.9-48.1 8.6-9.9 19.8-14.9 33.6-14.9 10 0 18.5 2.8 25.5 8.4s11.6 13.2 13.8 22.9l37.2-8.9c-4.2-14.9-10.6-26.3-19-34.3-14.2-13.5-32.7-20.2-55.5-20.2-26.1 0-47.1 8.6-63.1 25.7s-24 41.2-24 72.2c0 29.3 8 52.4 23.9 69.3 15.9 16.9 36.2 25.3 60.9 25.3 20 0 36.5-4.9 49.4-14.8 13-9.9 22.3-24.9 27.9-45.3L379 631.6c-3.1 13.6-8.3 23.6-15.5 29.9zM561.5 597.2c-8.8-4.6-22.3-9.1-40.6-13.4s-29.8-8.5-34.5-12.4c-3.7-3.1-5.6-6.9-5.6-11.3 0-4.8 2-8.7 6-11.6 6.2-4.5 14.7-6.7 25.6-6.7 10.6 0 18.5 2.1 23.8 6.3 5.3 4.2 8.7 11.1 10.3 20.6l37.6-1.7c-0.6-17.1-6.8-30.8-18.6-41s-29.4-15.4-52.7-15.4c-14.3 0-26.5 2.2-36.6 6.5-10.1 4.3-17.9 10.6-23.2 18.9-5.4 8.3-8.1 17.1-8.1 26.6 0 14.7 5.7 27.2 17.1 37.5 8.1 7.3 22.3 13.4 42.4 18.4 15.7 3.9 25.7 6.6 30.1 8.1 6.4 2.3 10.9 5 13.5 8.1 2.6 3.1 3.9 6.8 3.9 11.2 0 6.9-3.1 12.8-9.2 18-6.1 5.1-15.3 7.7-27.4 7.7-11.4 0-20.5-2.9-27.2-8.6-6.7-5.8-11.2-14.8-13.4-27l-36.6 3.6c2.5 20.8 10 36.7 22.6 47.5 12.6 10.9 30.7 16.3 54.2 16.3 16.2 0 29.7-2.3 40.5-6.8s19.2-11.4 25.1-20.8c5.9-9.3 8.9-19.3 8.9-30 0-11.8-2.5-21.6-7.4-29.6s-11.7-14.3-20.5-19zM689.9 651.6l-47.1-137.7h-40.7L668.6 700h40.1l66.7-186.1h-39.9z'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
@@ -138,11 +136,14 @@ const indicatorList = ref()
|
||||
// initCode()
|
||||
// })
|
||||
// }
|
||||
const exportSubjectName = ref('')
|
||||
const nodeClick = (e: any) => {
|
||||
if (e == undefined) {
|
||||
}
|
||||
if (e.level == 3) {
|
||||
exportSubjectName.value = e.name || ''
|
||||
tableStore.table.params.lineId = e.id
|
||||
tableStore.exportName = { subject: exportSubjectName.value, feature: '主要监测点列表' }
|
||||
initCode()
|
||||
}
|
||||
}
|
||||
@@ -182,6 +183,12 @@ const getSeriesForCsvExport = () => {
|
||||
}))
|
||||
}
|
||||
|
||||
const getChartExportFileName = () => ({
|
||||
subject: exportSubjectName.value,
|
||||
feature: '负荷曲线拟合图',
|
||||
date: tableStore.table.params.searchEndTime || tableStore.table.params.searchBeginTime
|
||||
})
|
||||
|
||||
const setEchart = () => {
|
||||
// 获取当前选择的功率和指标名称
|
||||
const powerName = powerList.value?.find((item: any) => item.id === tableStore.table.params.power)?.name || '功率'
|
||||
@@ -191,6 +198,7 @@ const setEchart = () => {
|
||||
const chartTitle = `${indicatorName}与${powerName}负荷曲线拟合图`
|
||||
|
||||
echartList.value = {
|
||||
exportFileName: getChartExportFileName(),
|
||||
title: {
|
||||
text: chartTitle
|
||||
},
|
||||
@@ -199,12 +207,9 @@ const setEchart = () => {
|
||||
myTool1: {
|
||||
show: true,
|
||||
title: '下载csv',
|
||||
icon: CSV_DOWNLOAD_ICON,
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
exportSeriesCSV(
|
||||
getSeriesForCsvExport(),
|
||||
`${echartList.value.title?.text || '负荷曲线拟合图'}.csv`
|
||||
)
|
||||
exportSeriesCSV(getSeriesForCsvExport(), echartList.value.exportFileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
|
||||
<!-- 监测点列表 -->
|
||||
<TableHeader ref="TableHeaderRef" :showReset="false" @selectChange="selectChange" v-if="fullscreen"
|
||||
<TableHeader ref="TableHeaderRef" :showReset="false" showExport @selectChange="selectChange" v-if="fullscreen"
|
||||
:timeKeyList="prop.timeKey">
|
||||
<template #select>
|
||||
<el-form-item label="关键字筛选">
|
||||
@@ -37,7 +37,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import { ref, onMounted, provide, watch, computed } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
@@ -159,7 +159,7 @@ const tableStore: any = new TableStore({
|
||||
{
|
||||
title: '电压等级(kV)',
|
||||
field: 'volGrade',
|
||||
minWidth: '80',
|
||||
minWidth: '100',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue == 0 ? '/' : row.cellValue || '/'
|
||||
}
|
||||
|
||||
@@ -377,6 +377,11 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: trendRequestData.value?.lineName,
|
||||
feature: '趋势图',
|
||||
date: datePickerRef.value?.timeValue?.[1] || datePickerRef.value?.timeValue?.[0]
|
||||
},
|
||||
legend: {
|
||||
itemWidth: 20,
|
||||
itemHeight: 20,
|
||||
@@ -446,10 +451,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
exportSeriesCSV(
|
||||
echartsData.value.options.series,
|
||||
`${titles.value || '监测点指标趋势'}.csv`
|
||||
)
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<template #select>
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input maxlength="32" show-word-limit style="width: 240px"
|
||||
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入敏感用户名称" />
|
||||
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入用户名称" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
@@ -77,7 +77,7 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '敏感用户名称',
|
||||
title: '用户名称',
|
||||
field: 'name',
|
||||
minWidth: '90'
|
||||
},
|
||||
|
||||
@@ -32,6 +32,7 @@ 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 { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echartMethod'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
@@ -85,14 +86,14 @@ const tableStore: any = new TableStore({
|
||||
field: 'advanceReason',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
formatter: (row: any) => ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
formatter: (row: any) => ReasonList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
},
|
||||
{
|
||||
title: '暂降类型',
|
||||
field: 'advanceType',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
formatter: (row: any) => EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
formatter: (row: any) => EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
},
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: 130, align: 'center' },
|
||||
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true },
|
||||
@@ -183,7 +184,7 @@ const tableStore: any = new TableStore({
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = row.wavePath.split('/')[2] || '波形文件'
|
||||
link.download = buildWaveExportFileName(getExportSubjectFromRow(row))
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
<template #content>
|
||||
<!-- <span v-html="list?.filter(item => item.time == data.day)[0]?.type || ''"></span> -->
|
||||
<div v-for="item in list?.filter((item:any) => item.name == data.day)">
|
||||
<div>电压暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>电压暂升:{{ item.eventUp || 0 }}</div>
|
||||
<div>暂降: {{ item.eventDown || 0 }}</div>
|
||||
<div>中断: {{ item.eventOff || 0 }}</div>
|
||||
<div>暂升: {{ item.eventUp || 0 }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<div
|
||||
@@ -43,13 +43,13 @@
|
||||
v-for="item in list?.filter((item:any) => item.name == data.day)"
|
||||
@click="descentClick(item)"
|
||||
>
|
||||
<!-- <div>电压暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>电压暂升:{{ item.eventUp || 0 }}</div> -->
|
||||
<!-- <div>暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>暂升:{{ item.eventUp || 0 }}</div> -->
|
||||
<template v-if="fullscreen">
|
||||
<div>电压暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>电压暂升:{{ item.eventUp || 0 }}</div>
|
||||
<div>暂降: {{ item.eventDown || 0 }}</div>
|
||||
<div>中断: {{ item.eventOff || 0 }}</div>
|
||||
<div>暂升: {{ item.eventUp || 0 }}</div>
|
||||
</template>
|
||||
<template v-else>暂态事件</template>
|
||||
</div>
|
||||
|
||||
@@ -37,6 +37,7 @@ 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 { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echartMethod'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
@@ -115,14 +116,14 @@ const tableStore: any = new TableStore({
|
||||
field: 'advanceReason',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
formatter: (row: any) => ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
formatter: (row: any) => ReasonList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
},
|
||||
{
|
||||
title: '暂降类型',
|
||||
field: 'advanceType',
|
||||
minWidth: 100,
|
||||
align: 'center',
|
||||
formatter: (row: any) => EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
formatter: (row: any) => EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
},
|
||||
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true },
|
||||
{
|
||||
@@ -206,7 +207,7 @@ const tableStore: any = new TableStore({
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = row.wavePath.split('/')[2] || '波形文件'
|
||||
link.download = buildWaveExportFileName(getExportSubjectFromRow(row))
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
|
||||
@@ -130,10 +130,14 @@ const initListByIds = () => {
|
||||
}
|
||||
|
||||
|
||||
const exportSubjectName = ref('')
|
||||
|
||||
const handleNodeClick = async (data: any) => {
|
||||
|
||||
|
||||
if (data?.level == 3 || data?.level == 2) {
|
||||
exportSubjectName.value = data.name || ''
|
||||
tableStore.exportName = { subject: exportSubjectName.value, feature: '趋势对比' }
|
||||
tableStore.table.params.sensitiveUserId = data.id
|
||||
await tableStore.index()
|
||||
} else {
|
||||
@@ -300,6 +304,11 @@ const setEchart = () => {
|
||||
...chartsListAfter.value.map((item: any) => item.statisticalData)]
|
||||
)
|
||||
echartList.value = {
|
||||
exportFileName: {
|
||||
subject: exportSubjectName.value,
|
||||
feature: '趋势对比',
|
||||
date: tableStore.table.params.searchEndTime || tableStore.table.params.searchBeginTime
|
||||
},
|
||||
title: {
|
||||
text: titleText
|
||||
},
|
||||
@@ -378,12 +387,8 @@ const setEchart = () => {
|
||||
show: true,
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
iconStyle: timeControl.value ? { borderColor: '#409EFF' } : {},
|
||||
onclick: () => {
|
||||
exportSeriesCSV(
|
||||
echartList.value.series,
|
||||
`${echartList.value.title?.text || '趋势对比'}.csv`
|
||||
)
|
||||
exportSeriesCSV(echartList.value.series, echartList.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'echarts-liquidfill'
|
||||
import 'echarts/lib/component/dataZoom'
|
||||
import { color, gradeColor3 } from './color'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod'
|
||||
// import { nextTick } from 'process'
|
||||
|
||||
const emit = defineEmits(['chartClick'])
|
||||
@@ -71,7 +72,9 @@ const initChart = () => {
|
||||
feature: {
|
||||
saveAsImage: {
|
||||
title: '下载图片',
|
||||
name: props.options?.title?.text || '图表'
|
||||
name: props.options?.exportFileName
|
||||
? buildExportBaseName(props.options.exportFileName)
|
||||
: ((props.options?.title?.text || '图表') + '_' + formatExportDateTime())
|
||||
},
|
||||
...(props.options?.toolbox?.featureProps || null)
|
||||
},
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
export let color = [ '#07CCCA','#00BFF5', '#FFBF00', '#77DA63', '#Ff6600', '#FF9100', '#5B6E96', '#66FFCC', '#B3B3B3']
|
||||
export let color = ['#07CCCA', '#00BFF5', '#FFBF00', '#77DA63', '#Ff6600', '#FF9100', '#5B6E96', '#66FFEC', '#B3B3B3', '#9B59B6', '#3498DB', '#2ECC71']
|
||||
export let color1 = [
|
||||
'#00A8B5', // 青
|
||||
'#3B7DD8', // 蓝
|
||||
'#5B5FC7', // 靛
|
||||
'#8B5CF6', // 紫
|
||||
'#B07CC6', // 淡紫
|
||||
'#C060A8', // 玫红
|
||||
'#D4A017', // 金
|
||||
'#6AAF50', // 草绿
|
||||
'#00A878', // 翠绿
|
||||
'#7C9EB2', // 烟蓝
|
||||
'#6B7B8C', // 板岩灰
|
||||
'#A8A8A8' // 灰
|
||||
]
|
||||
export const gradeColor3 = ['#339966', '#FFCC33', '#A52a2a']
|
||||
export const gradeColor5 = ['#00CC00', '#99CC99', '#FF9900','#996600','#A52a2a']
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import url from '@/assets/img/point.png'
|
||||
import url2 from '@/assets/img/dw.png'
|
||||
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
|
||||
import { getRmsWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
|
||||
|
||||
import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod'
|
||||
let waveRequestId = 0
|
||||
const pendingCacheKeys = new Map<number, string>()
|
||||
let rmsWorker: Worker | null = null
|
||||
@@ -202,7 +202,7 @@ const download = () => {
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
const creatIMg = document.createElement('a')
|
||||
creatIMg.download = 'rms波形.png'
|
||||
creatIMg.download = (props.boxoList.lineName || props.boxoList.measurementPointName || props.boxoList.equipmentName) + '_RMS波形_' + formatExportDateTime() + '.png'
|
||||
creatIMg.href = canvas.toDataURL()
|
||||
creatIMg.click()
|
||||
creatIMg.remove()
|
||||
|
||||
@@ -18,6 +18,7 @@ import { calcShuYAxisRange, formatAxisLabel } from '@/utils/chartAxisHelper'
|
||||
import url from '@/assets/img/point.png'
|
||||
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
|
||||
import { getShuWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
|
||||
import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod'
|
||||
|
||||
let waveRequestId = 0
|
||||
const pendingCacheKeys = new Map<number, string>()
|
||||
@@ -207,7 +208,7 @@ const download = () => {
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
const creatIMg = document.createElement('a')
|
||||
creatIMg.download = '瞬间波形.png'
|
||||
creatIMg.download = (props.boxoList.lineName || props.boxoList.measurementPointName || props.boxoList.equipmentName) + '_瞬间波形_' + formatExportDateTime() + '.png'
|
||||
creatIMg.href = canvas.toDataURL()
|
||||
creatIMg.click()
|
||||
creatIMg.remove()
|
||||
|
||||
@@ -74,6 +74,7 @@ import { useConfig } from '@/stores/config'
|
||||
import type TableStoreClass from '@/utils/tableStore'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { buildExportBaseName } from '@/utils/echartMethod'
|
||||
|
||||
const config = useConfig()
|
||||
const tableRef = ref<VxeTableInstance>()
|
||||
@@ -150,6 +151,16 @@ const selectChangeEvent: VxeTableEvents.CheckboxChange<any> = ({ checked }) => {
|
||||
const getRef = () => {
|
||||
return tableRef.value
|
||||
}
|
||||
const getTableExportFilename = () => {
|
||||
const exportName = tableStore.exportName
|
||||
if (exportName && typeof exportName === 'object') {
|
||||
return buildExportBaseName(exportName)
|
||||
}
|
||||
const feature =
|
||||
exportName || (document.querySelectorAll('.ba-nav-tab.active')[0] as HTMLElement | undefined)?.textContent || '导出'
|
||||
return buildExportBaseName({ feature })
|
||||
}
|
||||
|
||||
watch(
|
||||
() => tableStore.table.allFlag,
|
||||
newVal => {
|
||||
@@ -157,7 +168,7 @@ watch(
|
||||
console.log('🚀 ~ tableStore.table.allData:', tableStore.table.allData)
|
||||
|
||||
tableRef.value?.exportData({
|
||||
filename: tableStore.exportName || document.querySelectorAll('.ba-nav-tab.active')[0].textContent || '', // 文件名字
|
||||
filename: getTableExportFilename(), // 文件名字
|
||||
sheetName: 'Sheet1',
|
||||
type: 'xlsx', //导出文件类型 xlsx 和 csv
|
||||
useStyle: true,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<Tree
|
||||
ref="treRef"
|
||||
|
||||
:width="width"
|
||||
:showPush="props.showPush"
|
||||
:expand-on-click-node="false"
|
||||
|
||||
@@ -79,7 +79,7 @@ async function selectInitialNode(type: string | undefined, leaves: LineTreeLeave
|
||||
}
|
||||
|
||||
const loadTree = (type?: string) => {
|
||||
console.log("🚀 ~ loadTree ~ type:", type)
|
||||
// console.log("🚀 ~ loadTree ~ type:", type)
|
||||
tree.value = []
|
||||
getLineTree({ type: type === '2' ? 'engineering' : '' }).then(res => {
|
||||
const leaves = decorateLineTree(res.data, type, decorators, { disableParents: false })
|
||||
|
||||
@@ -93,7 +93,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
width: '280px',
|
||||
width: '270px',
|
||||
canExpand: true,
|
||||
showPush: false,
|
||||
baseOffset: 190,
|
||||
@@ -138,10 +138,12 @@ defineExpose({ treeRef })
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cn-tree-root {
|
||||
// width: 280px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 270px;
|
||||
transition: width 0.3s;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
@@ -135,6 +135,56 @@ export const yMethod = (arr: any) => {
|
||||
return [min, max]
|
||||
}
|
||||
|
||||
export interface ExportFileNameOptions {
|
||||
subject?: string
|
||||
feature: string
|
||||
date?: string | Date | string[] | null
|
||||
ext?: string
|
||||
}
|
||||
|
||||
/** 导出文件名中的日期,固定为当前年月日 yyyy-mm-dd */
|
||||
export const formatExportDate = (): string => {
|
||||
const pad = (n: number) => String(n).padStart(2, '0')
|
||||
const now = new Date()
|
||||
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
|
||||
}
|
||||
|
||||
/** 波形下载文件名中的时间,固定为当前时间 yyyy-mm-dd-HH-mm-ss */
|
||||
export const formatExportDateTime = (): string => {
|
||||
const pad = (n: number) => String(n).padStart(2, '0')
|
||||
const now = new Date()
|
||||
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}`
|
||||
}
|
||||
|
||||
/** 监测点 / 设备 / 项目(可选)_ 功能 _ yyyy-mm-dd(当前日期) */
|
||||
export const buildExportBaseName = (options: Pick<ExportFileNameOptions, 'subject' | 'feature' | 'date'>): string => {
|
||||
const { subject, feature } = options
|
||||
const dateStr = formatExportDate()
|
||||
return [subject?.trim(), feature?.trim(), dateStr].filter(part => part).join('_')
|
||||
}
|
||||
|
||||
/** 波形 zip 下载:监测点_波形_yyyy-mm-dd-HH-mm-ss.zip(当前时间) */
|
||||
export const buildWaveExportFileName = (subject?: string): string => {
|
||||
const base = [subject?.trim(), '波形', formatExportDateTime()].filter(part => part).join('_')
|
||||
return `${base}.zip`
|
||||
}
|
||||
|
||||
export const buildExportFileName = (options: ExportFileNameOptions): string => {
|
||||
const ext = (options.ext || 'csv').replace(/^\./, '')
|
||||
return `${buildExportBaseName(options)}.${ext}`
|
||||
}
|
||||
|
||||
export const resolveExportFileName = (filenameOrOptions: string | ExportFileNameOptions): string => {
|
||||
if (typeof filenameOrOptions === 'string') {
|
||||
return filenameOrOptions
|
||||
}
|
||||
return buildExportFileName(filenameOrOptions)
|
||||
}
|
||||
|
||||
/** 从行数据中取监测点 / 设备 / 项目名称 */
|
||||
export const getExportSubjectFromRow = (row: any): string =>
|
||||
row?.lineName || row?.equipmentName || row?.projectName || row?.engineeringName || row?.name || ''
|
||||
|
||||
/**
|
||||
* title['A相','B相',]
|
||||
* data[[1,2],[3,4]]
|
||||
@@ -150,7 +200,8 @@ const convertToCSV = (title: object, data: any) => {
|
||||
})
|
||||
return csv
|
||||
}
|
||||
export const exportCSV = (title: object, data: any, filename: string) => {
|
||||
export const exportCSV = (title: object, data: any, filenameOrOptions: string | ExportFileNameOptions) => {
|
||||
const filename = resolveExportFileName(filenameOrOptions)
|
||||
const csv = convertToCSV(title, data)
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
|
||||
const link = document.createElement('a')
|
||||
@@ -190,10 +241,13 @@ export const buildSeriesCsvData = (seriesList: Array<{ name: string; data?: any[
|
||||
return { titles, rows }
|
||||
}
|
||||
|
||||
export const exportSeriesCSV = (seriesList: Array<{ name: string; data?: any[] }>, filename: string) => {
|
||||
export const exportSeriesCSV = (
|
||||
seriesList: Array<{ name: string; data?: any[] }>,
|
||||
filenameOrOptions: string | ExportFileNameOptions
|
||||
) => {
|
||||
const { titles, rows } = buildSeriesCsvData(seriesList)
|
||||
if (!rows.length) return
|
||||
exportCSV(titles, rows, filename)
|
||||
exportCSV(titles, rows, filenameOrOptions)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { buildExportBaseName, type ExportFileNameOptions } from '@/utils/echartMethod'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { nextTick } from 'vue'
|
||||
import { exportExcel } from '@/views/system/reportForms/export.js'
|
||||
@@ -12,6 +13,10 @@ export function parseLuckysheetSheets(sheets: any[]) {
|
||||
/* ignore invalid json */
|
||||
}
|
||||
}
|
||||
if (!item.config) item.config = {}
|
||||
if (item.row == null) item.row = 36
|
||||
if (item.column == null) item.column = 18
|
||||
if (!item.data) item.data = []
|
||||
item.celldata?.forEach((cell: any) => {
|
||||
if (item.data?.[cell.r]?.[cell.c]?.v != null) {
|
||||
item.data[cell.r][cell.c] = cell.v
|
||||
@@ -47,10 +52,15 @@ export function renderLuckysheetReport(
|
||||
sheets: any[],
|
||||
options: Record<string, any> = {}
|
||||
) {
|
||||
if (!Array.isArray(sheets) || sheets.length === 0) {
|
||||
destroyLuckysheet()
|
||||
return
|
||||
}
|
||||
parseLuckysheetSheets(sheets)
|
||||
destroyLuckysheet()
|
||||
nextTick(() => {
|
||||
requestAnimationFrame(() => {
|
||||
if (!document.getElementById(container)) return
|
||||
luckysheet.create({
|
||||
container,
|
||||
...DEFAULT_REPORT_OPTIONS,
|
||||
@@ -62,7 +72,7 @@ export function renderLuckysheetReport(
|
||||
}
|
||||
|
||||
/** 安全导出 Luckysheet,无数据时提示并返回 false */
|
||||
export function exportLuckysheetFile(filename: string, hasData = true): boolean {
|
||||
export function exportLuckysheetFile(filenameOrOptions: string | ExportFileNameOptions, hasData = true): boolean {
|
||||
if (!hasData) {
|
||||
ElMessage.warning('暂无数据')
|
||||
return false
|
||||
@@ -77,6 +87,8 @@ export function exportLuckysheetFile(filename: string, hasData = true): boolean
|
||||
ElMessage.warning('暂无数据')
|
||||
return false
|
||||
}
|
||||
const filename =
|
||||
typeof filenameOrOptions === 'string' ? filenameOrOptions : buildExportBaseName(filenameOrOptions)
|
||||
exportExcel(sheets, filename)
|
||||
ElMessage.success('生成成功')
|
||||
return true
|
||||
|
||||
@@ -15,16 +15,12 @@
|
||||
</el-form-item> -->
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input maxlength="32" show-word-limit style="width: 240px"
|
||||
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入监测点名称" />
|
||||
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入设备名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="级别">
|
||||
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
|
||||
<el-option
|
||||
v-for="item in rankOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
<el-option v-for="item in rankOptions" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -103,9 +99,14 @@ const tableStore = new TableStore({
|
||||
}
|
||||
},
|
||||
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true },
|
||||
{ title: '设备名称', field: 'equipmentName', align: 'center', minWidth: 120 },
|
||||
{ title: '项目名称', field: 'projectName', align: 'center', minWidth: 120 },
|
||||
{ title: '工程名称', field: 'engineeringName', align: 'center', minWidth: 120 },
|
||||
{
|
||||
title: '监测点名称', field: 'lineName', minWidth: 130, align: 'center', formatter: (row: any) => {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{ title: '设备名称', field: 'equipmentName', align: 'center', minWidth: 130 },
|
||||
{ title: '项目名称', field: 'projectName', align: 'center', minWidth: 130 },
|
||||
{ title: '工程名称', field: 'engineeringName', align: 'center', minWidth: 130 },
|
||||
// { title: '监测点名称', field: 'lineName', align: 'center', minWidth: 120 },
|
||||
|
||||
|
||||
@@ -168,7 +169,7 @@ const tableStore = new TableStore({
|
||||
// }
|
||||
// }
|
||||
],
|
||||
beforeSearchFun: () => {},
|
||||
beforeSearchFun: () => { },
|
||||
exportProcessingData: () => {
|
||||
tableStore.table.allData = tableStore.table.allData.filter(item => {
|
||||
item.level =
|
||||
@@ -241,6 +242,6 @@ onMounted(() => {
|
||||
setTimeout(() => {
|
||||
// tableStore.table.height = mainHeight(200).height as any
|
||||
}, 0)
|
||||
const addMenu = () => {}
|
||||
const addMenu = () => { }
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>
|
||||
<el-button type="primary" icon="el-icon-Histogram" @click="statistics">暂降原因分析</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
|
||||
@@ -43,10 +44,12 @@ import { analyseWave, getFileByEventId } from '@/api/common'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echartMethod'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import analysisList from '@/views/govern/device/control/analysisList/index.vue'
|
||||
const props = defineProps(['deviceTree'])
|
||||
const emit = defineEmits(['statistics'])
|
||||
|
||||
const refheader = ref()
|
||||
const waveFormAnalysisRef = ref()
|
||||
@@ -91,12 +94,12 @@ const tableStore = new TableStore({
|
||||
{ title: '触发类型', field: 'showName', minWidth: 100, align: 'center' },
|
||||
{
|
||||
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
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.id == row.cellValue)?.name || '未知'
|
||||
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
}
|
||||
},
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: 130, align: 'center' },
|
||||
@@ -179,7 +182,7 @@ const tableStore = new TableStore({
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
|
||||
link.download = buildWaveExportFileName(getExportSubjectFromRow(row))
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
@@ -361,6 +364,10 @@ onMounted(() => {
|
||||
})
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const statistics = () => {
|
||||
emit('statistics')
|
||||
}
|
||||
const bxecharts = mainHeight(175).height as any
|
||||
setTimeout(() => {
|
||||
tableStore.table.height = mainHeight(200).height as any
|
||||
|
||||
39
src/views/govern/alarm/eventStatistics.vue
Normal file
39
src/views/govern/alarm/eventStatistics.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-tabs type="border-card" v-model.trim="activeName" tab-position="left">
|
||||
<el-tab-pane label="暂降分布统计" name="1">
|
||||
<Distribution v-if="activeName == '1'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="ITIC曲线" name="2">
|
||||
<ITIC v-if="activeName == '2'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="F47曲线" name="3">
|
||||
<F47 v-if="activeName == '3'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, provide } from 'vue'
|
||||
import Distribution from './eventStatistics/distribution.vue'
|
||||
import ITIC from './eventStatistics/ITIC.vue'
|
||||
import F47 from './eventStatistics/F47.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
|
||||
const emit = defineEmits(['back'])
|
||||
const activeName = ref('1')
|
||||
const layout = mainHeight(80)
|
||||
|
||||
provide('eventStatisticsBack', () => emit('back'))
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs--border-card>.el-tabs__content) {
|
||||
padding: 10px 10px 10px 0;
|
||||
}
|
||||
|
||||
:deep(.el-tabs--left.el-tabs--border-card .el-tabs__header.is-left) {
|
||||
height: calc(100vh - 193px);
|
||||
}
|
||||
</style>
|
||||
346
src/views/govern/alarm/eventStatistics/F47.vue
Normal file
346
src/views/govern/alarm/eventStatistics/F47.vue
Normal file
@@ -0,0 +1,346 @@
|
||||
<template>
|
||||
<div v-show="!isWaveCharts" class="event-statistics-curve" :style="pageHeight">
|
||||
<TableHeader ref="TableHeaderRef" :showReset="false" :timeKeyList="timeKeyList" datePicker
|
||||
@selectChange="selectChange"> <template v-slot:operation>
|
||||
<el-button icon="el-icon-Back" @click="handleBack">返回</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<my-echart v-loading="tableStore.table.loading" ref="chartRef" class="tall" :options="echartList"
|
||||
:style="chartStyle" @chart-click="handleChartClick" />
|
||||
</div>
|
||||
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef"
|
||||
@handleHideCharts="isWaveCharts = false" :wp="wp" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, computed, nextTick, inject } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { analyseWave } from '@/api/common'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const pageHeight = mainHeight(105)
|
||||
const eventStatisticsBack = inject<() => void>('eventStatisticsBack', () => {})
|
||||
const handleBack = () => eventStatisticsBack()
|
||||
const timeKeyList = ['1', '2', '3', '4', '5']
|
||||
const defaultInterval = 3
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
const headerHeight = ref(57)
|
||||
const echartList = ref()
|
||||
const chartRef = ref()
|
||||
const isWaveCharts = ref(false)
|
||||
const loading = ref(false)
|
||||
const wp = ref({})
|
||||
const boxoList: any = ref({})
|
||||
const waveFormAnalysisRef: any = ref(null)
|
||||
|
||||
const chartStyle = computed(() => ({
|
||||
width: '100%',
|
||||
height: `calc(${pageHeight.height} - 80px - ${headerHeight.value}px)`
|
||||
}))
|
||||
|
||||
const data = reactive({
|
||||
name: '事件个数',
|
||||
gs: 0,
|
||||
krr: 0,
|
||||
bkrr: 0
|
||||
})
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/csevent/f47Curve',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
const gongData = gongfunction(tableStore.table.data)
|
||||
data.gs = tableStore.table.data.length
|
||||
data.krr = gongData.pointF.length
|
||||
data.bkrr = gongData.pointFun.length
|
||||
echartList.value = {
|
||||
title: {
|
||||
text: 'F47曲线'
|
||||
},
|
||||
legend: {
|
||||
data: ['分割线', '可容忍事件', '不可容忍事件'],
|
||||
itemGap: 15
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
show: true,
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (a: any) {
|
||||
let relVal = `<strong>${a.seriesName}</strong><br/>`
|
||||
relVal += "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>特征幅值:" + Math.floor(a.value[1] * 100) / 100 + '%</font><br/>'
|
||||
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
|
||||
relVal += "<font style='color:" + "'>监测点名称:" + (a.value[4] || '/') + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>设备名称:" + (a.value[5] || '/') + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>项目名称:" + (a.value[6] || '/') + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>工程名称:" + (a.value[7] || '/') + '</font>'
|
||||
return relVal
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'log',
|
||||
min: 0.001,
|
||||
max: 1000,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 's'
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
color: ['#DAA520', 'green', 'red'],
|
||||
options: {
|
||||
dataZoom: null,
|
||||
series: [
|
||||
{
|
||||
name: '分割线',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.05, 0],
|
||||
[0.05, 50],
|
||||
[0.2, 50],
|
||||
[0.2, 70],
|
||||
[0.5, 70],
|
||||
[0.5, 80],
|
||||
[10, 80],
|
||||
[1000, 80]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
data: gongData.pointF,
|
||||
legendSymbol: 'circle'
|
||||
},
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
data: gongData.pointFun,
|
||||
legendSymbol: 'rect'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const selectChange = (_showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || defaultInterval) ?? 0,
|
||||
timeKeyList,
|
||||
[tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
let standF = 0
|
||||
let unstandF = 0
|
||||
let pointIun: any[] = []
|
||||
let pointI: any[] = []
|
||||
let pointF: any[] = []
|
||||
let pointFun: any[] = []
|
||||
const total = arr.length
|
||||
|
||||
if (total > 0) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const xx = arr[i].persistTime
|
||||
const yy = arr[i].eventValue
|
||||
const time = arr[i].time
|
||||
const eventId = arr[i].eventId
|
||||
const lineName = arr[i].lineName
|
||||
const equipmentName = arr[i].equipmentName
|
||||
const projectName = arr[i].projectName
|
||||
const engineeringName = arr[i].engineeringName
|
||||
const point = [xx, yy, time, eventId, lineName, equipmentName, projectName, engineeringName]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
const line = 250 - 30000 * xx
|
||||
if (yy > line) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else if (xx <= 0.02) {
|
||||
if (yy > 120) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else if (xx <= 0.5) {
|
||||
if (yy > 120 || yy < 70) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else if (xx <= 10) {
|
||||
if (yy > 110 || yy < 80) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else {
|
||||
if (yy > 110 || yy < 90) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
}
|
||||
|
||||
if (xx < 0.05) {
|
||||
standF++
|
||||
pointF.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
} else if (xx < 0.2) {
|
||||
if (yy > 50) {
|
||||
standF++
|
||||
pointF.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
}
|
||||
} else if (xx < 0.5) {
|
||||
if (yy > 70) {
|
||||
standF++
|
||||
pointF.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
}
|
||||
} else {
|
||||
if (yy > 80) {
|
||||
standF++
|
||||
pointF.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { standI, unstandI, pointI, pointIun, standF, unstandF, pointF, pointFun }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
tableStore.index()
|
||||
}, 100)
|
||||
})
|
||||
|
||||
const handleChartClick = (params: any) => {
|
||||
if (params.seriesName === '可容忍事件' || params.seriesName === '不可容忍事件') {
|
||||
handleTolerableEventClick(params)
|
||||
}
|
||||
}
|
||||
|
||||
const handleTolerableEventClick = async (row: any) => {
|
||||
loading.value = true
|
||||
ElMessage.info(`正在加载,请稍等...`)
|
||||
await analyseWave(row.value[3])
|
||||
.then(res => {
|
||||
if (res != undefined) {
|
||||
loading.value = true
|
||||
isWaveCharts.value = true
|
||||
boxoList.value = {
|
||||
persistTime: row.value[0],
|
||||
featureAmplitude: row.value[1] / 100,
|
||||
startTime: row.value[2],
|
||||
lineName: row.value[4],
|
||||
engineeringName: row.value[5],
|
||||
systemType: 'YPT'
|
||||
}
|
||||
wp.value = res.data
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
nextTick(() => {
|
||||
waveFormAnalysisRef.value?.getWpData(wp.value, boxoList.value, true)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.event-statistics-curve {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
332
src/views/govern/alarm/eventStatistics/ITIC.vue
Normal file
332
src/views/govern/alarm/eventStatistics/ITIC.vue
Normal file
@@ -0,0 +1,332 @@
|
||||
<template>
|
||||
<div v-show="!isWaveCharts" class="event-statistics-curve" :style="pageHeight">
|
||||
<TableHeader ref="TableHeaderRef" :showReset="false" :timeKeyList="timeKeyList" datePicker
|
||||
@selectChange="selectChange"> <template v-slot:operation>
|
||||
<el-button icon="el-icon-Back" @click="handleBack">返回</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<my-echart v-loading="tableStore.table.loading" ref="chartRef" class="tall" :options="echartList"
|
||||
:style="chartStyle" @chart-click="handleChartClick" />
|
||||
</div>
|
||||
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef"
|
||||
@handleHideCharts="isWaveCharts = false" :wp="wp" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, computed, nextTick, inject } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { analyseWave } from '@/api/common'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const pageHeight = mainHeight(105)
|
||||
const eventStatisticsBack = inject<() => void>('eventStatisticsBack', () => {})
|
||||
const handleBack = () => eventStatisticsBack()
|
||||
const timeKeyList = ['1', '2', '3', '4', '5']
|
||||
const defaultInterval = 3
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
const headerHeight = ref(57)
|
||||
const echartList = ref()
|
||||
const chartRef = ref()
|
||||
const isWaveCharts = ref(false)
|
||||
const loading = ref(false)
|
||||
const wp = ref({})
|
||||
const boxoList: any = ref({})
|
||||
const waveFormAnalysisRef: any = ref(null)
|
||||
|
||||
const chartStyle = computed(() => ({
|
||||
width: '100%',
|
||||
height: `calc(${pageHeight.height} - 80px - ${headerHeight.value}px)`
|
||||
}))
|
||||
|
||||
const data = reactive({
|
||||
name: '事件个数',
|
||||
gs: 0,
|
||||
krr: 0,
|
||||
bkrr: 0
|
||||
})
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/csevent/f47Curve',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
const gongData = gongfunction(tableStore.table.data)
|
||||
data.gs = tableStore.table.data.length
|
||||
data.krr = gongData.pointI.length
|
||||
data.bkrr = gongData.pointIun.length
|
||||
echartList.value = {
|
||||
title: {
|
||||
text: 'ITIC曲线'
|
||||
},
|
||||
legend: {
|
||||
data: ['上限', '下限', '可容忍事件', '不可容忍事件'],
|
||||
itemGap: 15
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
show: true,
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (a: any) {
|
||||
let relVal = `<strong>${a.seriesName}</strong><br/>`
|
||||
relVal += "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>特征幅值:" + Math.floor(a.value[1] * 100) / 100 + '%</font><br/>'
|
||||
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
|
||||
relVal += "<font style='color:" + "'>监测点名称:" + (a.value[4] || '/') + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>设备名称:" + (a.value[5] || '/') + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>项目名称:" + (a.value[6] || '/') + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>工程名称:" + (a.value[7] || '/') + '</font>'
|
||||
return relVal
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'log',
|
||||
min: 0.001,
|
||||
max: 1000,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 's'
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 3,
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
color: ['#FF8C00', '#00BFFF', 'green', 'red'],
|
||||
options: {
|
||||
dataZoom: null,
|
||||
series: [
|
||||
{
|
||||
name: '上限',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.001, 200],
|
||||
[0.003, 140],
|
||||
[0.003, 120],
|
||||
[0.5, 120],
|
||||
[0.5, 110],
|
||||
[10, 110],
|
||||
[1000, 110]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '下限',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.02, 0],
|
||||
[0.02, 70],
|
||||
[0.5, 70],
|
||||
[0.5, 80],
|
||||
[10, 80],
|
||||
[10, 90],
|
||||
[1000, 90]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
data: gongData.pointI,
|
||||
legendSymbol: 'circle'
|
||||
},
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
data: gongData.pointIun,
|
||||
legendSymbol: 'rect'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const selectChange = (_showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || defaultInterval) ?? 0,
|
||||
timeKeyList,
|
||||
[tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
let pointIun: any[] = []
|
||||
let pointI: any[] = []
|
||||
const total = arr.length
|
||||
|
||||
if (total > 0) {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const xx = arr[i].persistTime
|
||||
const yy = arr[i].eventValue
|
||||
const time = arr[i].time
|
||||
const eventId = arr[i].eventId
|
||||
const lineName = arr[i].lineName
|
||||
const equipmentName = arr[i].equipmentName
|
||||
const projectName = arr[i].projectName
|
||||
const engineeringName = arr[i].engineeringName
|
||||
const point = [xx, yy, time, eventId, lineName, equipmentName, projectName, engineeringName]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
const line = 230 - 30000 * xx
|
||||
if (yy > line) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else if (xx <= 0.02) {
|
||||
if (yy > 120) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else if (xx <= 0.5) {
|
||||
if (yy > 120 || yy < 70) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else if (xx <= 10) {
|
||||
if (yy > 110 || yy < 80) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
} else {
|
||||
if (yy > 110 || yy < 90) {
|
||||
unstandI++
|
||||
pointIun.push({ value: point, itemStyle: { normal: { color: 'red' } } })
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({ value: point, itemStyle: { normal: { color: 'green' } } })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { standI, unstandI, pointI, pointIun }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
tableStore.index()
|
||||
}, 100)
|
||||
})
|
||||
|
||||
const handleChartClick = (params: any) => {
|
||||
if (params.seriesName === '可容忍事件' || params.seriesName === '不可容忍事件') {
|
||||
handleTolerableEventClick(params)
|
||||
}
|
||||
}
|
||||
|
||||
const handleTolerableEventClick = async (row: any) => {
|
||||
loading.value = true
|
||||
ElMessage.info(`正在加载,请稍等...`)
|
||||
await analyseWave(row.value[3])
|
||||
.then(res => {
|
||||
if (res != undefined) {
|
||||
loading.value = true
|
||||
isWaveCharts.value = true
|
||||
boxoList.value = {
|
||||
persistTime: row.value[0],
|
||||
featureAmplitude: row.value[1] / 100,
|
||||
startTime: row.value[2],
|
||||
lineName: row.value[4],
|
||||
engineeringName: row.value[5],
|
||||
systemType: 'YPT'
|
||||
}
|
||||
|
||||
wp.value = res.data
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
nextTick(() => {
|
||||
waveFormAnalysisRef.value?.getWpData(wp.value, boxoList.value, true)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.event-statistics-curve {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
248
src/views/govern/alarm/eventStatistics/distribution.vue
Normal file
248
src/views/govern/alarm/eventStatistics/distribution.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<div class="distribution-page" :style="pageHeight" v-loading="tableStore.table.loading">
|
||||
<TableHeader ref="TableHeaderRef" :showReset="false" :timeKeyList="timeKeyList" datePicker
|
||||
@selectChange="selectChange">
|
||||
<template v-slot:operation>
|
||||
<el-button icon="el-icon-Back" @click="handleBack">返回</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<p class="note">注:暂降类型仅统计暂降原因为短路故障事件</p>
|
||||
<div class="statistics-main" v-if="renderFlag">
|
||||
<div class="chart-cell">
|
||||
<my-echart :options="reasonChart" class="chart-box" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<vxe-table height="auto" auto-resize :data="reasonData" v-bind="defaultAttribute">
|
||||
<vxe-column field="name" title="暂降原因" />
|
||||
<vxe-column field="value" title="暂降次数" sortable />
|
||||
</vxe-table>
|
||||
</div>
|
||||
<div class="chart-cell">
|
||||
<my-echart :options="typeChart" class="chart-box" />
|
||||
</div>
|
||||
<div class="table-cell">
|
||||
<vxe-table height="auto" auto-resize :data="typeData" v-bind="defaultAttribute">
|
||||
<vxe-column field="name" title="暂降类型" />
|
||||
<vxe-column field="value" title="暂降次数" sortable />
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, inject } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { color1 } from '@/components/echarts/color'
|
||||
const dictData = useDictData()
|
||||
const ReasonList: any = dictData.getBasicData('Event_Reason')
|
||||
const EventTypeList: any = dictData.getBasicData('Event_Type')
|
||||
const pageHeight = mainHeight(106)
|
||||
const eventStatisticsBack = inject<() => void>('eventStatisticsBack', () => {})
|
||||
const handleBack = () => eventStatisticsBack()
|
||||
const timeKeyList = ['1', '2', '3', '4', '5']
|
||||
const defaultInterval = 3
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
const renderFlag = ref(true)
|
||||
const reasonChart = ref({})
|
||||
const typeChart = ref({})
|
||||
const reasonData = ref<any[]>([])
|
||||
const typeData = ref<any[]>([])
|
||||
|
||||
const sortDistributionList = (list: any[]) => {
|
||||
const totalRow = list.find((item: any) => item.name === '总计')
|
||||
const total = totalRow?.value ?? list.reduce((sum, item) => sum + (item.value ?? 0), 0)
|
||||
const sorted = list
|
||||
.filter((item: any) => item.name !== '总计')
|
||||
.sort((a, b) => (b.value ?? 0) - (a.value ?? 0))
|
||||
return [{ name: '总计', value: total }, ...sorted]
|
||||
}
|
||||
|
||||
const transformReasonData = (eventReason: any[] = []) => {
|
||||
const list = ReasonList.map((item: any) => {
|
||||
const matched = eventReason.find((row: any) => row.eventReasonId === item.id)
|
||||
return {
|
||||
name: item.name,
|
||||
value: matched?.eventReasonCount ?? 0
|
||||
}
|
||||
})
|
||||
return sortDistributionList(list)
|
||||
}
|
||||
|
||||
const transformTypeData = (eventType: any[] = []) => {
|
||||
const list = EventTypeList.map((item: any) => {
|
||||
const matched = eventType.find((row: any) => row.eventTypeId === item.id)
|
||||
return {
|
||||
name: item.name,
|
||||
value: matched?.eventTypeCount ?? 0
|
||||
}
|
||||
})
|
||||
return sortDistributionList(list)
|
||||
}
|
||||
|
||||
const parseDistributionData = (raw: any) => {
|
||||
if (raw?.eventReason || raw?.eventType) {
|
||||
return {
|
||||
reason: transformReasonData(raw.eventReason || []),
|
||||
type: transformTypeData(raw.eventType || [])
|
||||
}
|
||||
}
|
||||
if (raw?.reason?.length || raw?.type?.length) {
|
||||
return {
|
||||
reason: sortDistributionList(raw.reason || []),
|
||||
type: sortDistributionList(raw.type || [])
|
||||
}
|
||||
}
|
||||
return {
|
||||
reason: transformReasonData([]),
|
||||
type: transformTypeData([])
|
||||
}
|
||||
}
|
||||
|
||||
const buildPieOptions = (title: string, seriesName: string, data: any[], exportFileName: string) => ({
|
||||
title: { text: title },
|
||||
exportFileName,
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
orient: 'vertical',
|
||||
left: 10,
|
||||
top: '5%',
|
||||
tooltip: { show: true }
|
||||
},
|
||||
color: color1,
|
||||
xAxis: { show: false },
|
||||
yAxis: { show: false },
|
||||
dataZoom: { show: false },
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} (次)',
|
||||
confine: true
|
||||
},
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: seriesName,
|
||||
type: 'pie',
|
||||
center: ['50%', '50%'],
|
||||
selectedOffset: 30,
|
||||
clockwise: true,
|
||||
label: { show: false, position: 'outside' },
|
||||
data: data.filter((item: any) => item.name !== '总计')
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const updateCharts = (res: any) => {
|
||||
renderFlag.value = false
|
||||
reasonData.value = res?.reason || []
|
||||
typeData.value = res?.type || []
|
||||
reasonChart.value = buildPieOptions('暂降原因', '暂降原因', reasonData.value, '暂降原因')
|
||||
typeChart.value = buildPieOptions('暂降类型', '暂降类型', typeData.value, '暂降类型')
|
||||
renderFlag.value = true
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/event/eventReasonAndTypeStatistics',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
updateCharts(parseDistributionData(tableStore.table.data))
|
||||
}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const selectChange = (_showSelect: any, _height: any, datePickerValue?: any) => {
|
||||
if (datePickerValue?.timeValue) {
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || defaultInterval) ?? 0,
|
||||
timeKeyList,
|
||||
[tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateCharts(parseDistributionData(null))
|
||||
setTimeout(() => {
|
||||
tableStore.index()
|
||||
}, 100)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.distribution-page {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.note {
|
||||
margin: 8px 0 0;
|
||||
flex-shrink: 0;
|
||||
color: #f56c6c;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.statistics-main {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 420px;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.chart-cell,
|
||||
.table-cell {
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chart-cell {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.chart-box {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chart-box :deep(.chart),
|
||||
.chart-box :deep(.my-chart) {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -2,8 +2,17 @@
|
||||
<div class="default-main">
|
||||
<el-tabs v-model.trim="activeName" type="border-card" class="demo-tabs">
|
||||
<el-tab-pane label="暂态事件" name="4">
|
||||
<Transient v-if="activeName == '4'" :deviceTree="deviceTree" :key="key" />
|
||||
<Transient
|
||||
v-if="!showEventStatistics"
|
||||
:deviceTree="deviceTree"
|
||||
:key="key"
|
||||
@statistics="showEventStatistics = true"
|
||||
/>
|
||||
<eventStatistics v-else @back="showEventStatistics = false" />
|
||||
</el-tab-pane>
|
||||
<!-- <el-tab-pane label="事件统计" name="5">
|
||||
|
||||
</el-tab-pane> -->
|
||||
<el-tab-pane label="稳态越限告警" name="3">
|
||||
<Steady v-if="activeName == '3'" :deviceTree="deviceTree" :key="key" />
|
||||
</el-tab-pane>
|
||||
@@ -20,11 +29,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide } from 'vue'
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import Steady from './Steady.vue'
|
||||
import Transient from './Transient.vue'
|
||||
import Device from './Device.vue'
|
||||
import Front from './Front.vue'
|
||||
import eventStatistics from './eventStatistics.vue'
|
||||
import { getDeviceTree } from '@/api/cs-device-boot/csLedger'
|
||||
defineOptions({
|
||||
name: 'govern/alarm/index'
|
||||
@@ -32,25 +42,32 @@ defineOptions({
|
||||
|
||||
const deviceTree = ref([])
|
||||
const activeName = ref('4')
|
||||
const showEventStatistics = ref(false)
|
||||
const key = ref(0)
|
||||
getDeviceTree().then(res => {
|
||||
// res.data.forEach((item: any) => {
|
||||
// item.value = item.id
|
||||
// item.label = item.name
|
||||
// item.children.forEach((child: any) => {
|
||||
// child.value = child.id
|
||||
// child.label = child.name
|
||||
// child.children.forEach((grand: any) => {
|
||||
// grand.value = grand.id
|
||||
// grand.label = grand.name
|
||||
// delete grand.children
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
deviceTree.value = res.data
|
||||
key.value += 1
|
||||
activeName.value = '4'
|
||||
|
||||
watch(activeName, val => {
|
||||
if (val !== '4') {
|
||||
showEventStatistics.value = false
|
||||
}
|
||||
})
|
||||
// getDeviceTree().then(res => {
|
||||
// res.data.forEach((item: any) => {
|
||||
// item.value = item.id
|
||||
// item.label = item.name
|
||||
// item.children.forEach((child: any) => {
|
||||
// child.value = child.id
|
||||
// child.label = child.name
|
||||
// child.children.forEach((grand: any) => {
|
||||
// grand.value = grand.id
|
||||
// grand.label = grand.name
|
||||
// delete grand.children
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// deviceTree.value = res.data
|
||||
// key.value += 1
|
||||
// activeName.value = '4'
|
||||
// })
|
||||
onMounted(() => { })
|
||||
|
||||
const addMenu = () => { }
|
||||
|
||||
@@ -120,12 +120,14 @@ const init = () => {
|
||||
})
|
||||
})
|
||||
}
|
||||
const exportSubjectName = ref('')
|
||||
const deviceTypeChange = (val: any, obj: any) => {
|
||||
flag.value = true
|
||||
nodeClick(obj)
|
||||
}
|
||||
const nodeClick = async (e: anyObj) => {
|
||||
if ((e.level == 2 || e.level == 3)) {
|
||||
exportSubjectName.value = e.name || ''
|
||||
formInline.devId = e.id
|
||||
loading.value = true
|
||||
if (zblist.value.length === 0) {
|
||||
@@ -259,6 +261,11 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: exportSubjectName.value,
|
||||
feature: zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name || 'APF数据',
|
||||
date: formInline.endTime || formInline.startTime
|
||||
},
|
||||
title: {
|
||||
text: zblist.value.filter(item => item.id == formInline.statisticalId)[0].name
|
||||
},
|
||||
@@ -319,9 +326,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
const chartTitle =
|
||||
zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name || 'APF数据'
|
||||
exportSeriesCSV(echartsData.value.options.series, `${chartTitle}.csv`)
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="default-main apf">
|
||||
<el-tabs type="border-card" v-model="activeName">
|
||||
<el-tab-pane label="APF" name="1">
|
||||
<el-tab-pane label="稳态" name="1">
|
||||
<APF v-if="activeName == '1'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="DVR" name="2">
|
||||
<el-tab-pane label="暂态" name="2">
|
||||
<DVR v-if="activeName == '2'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
@@ -58,6 +58,7 @@ import { analyseWave } from '@/api/common'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echartMethod'
|
||||
import MultiCondition from '@/views/govern/alarm/multiCondition.vue'
|
||||
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import { ElMessage } from 'element-plus'
|
||||
@@ -104,12 +105,12 @@ const tableStore = new TableStore({
|
||||
{ title: '触发类型', field: 'showName', minWidth: 100, align: 'center' },
|
||||
{
|
||||
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
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.id == row.cellValue)?.name || '未知'
|
||||
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -196,7 +197,7 @@ const tableStore = new TableStore({
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
|
||||
link.download = buildWaveExportFileName(getExportSubjectFromRow(row))
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
|
||||
@@ -271,6 +271,11 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: defaultCheckedKeys.value.map(item => item.name).filter(Boolean).join(''),
|
||||
feature: zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name || '稳态数据',
|
||||
date: formInline.endTime || formInline.startTime
|
||||
},
|
||||
title: {
|
||||
text: zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name
|
||||
},
|
||||
@@ -321,9 +326,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
const chartTitle =
|
||||
zblist.value.filter(item => item.id == formInline.statisticalId)[0]?.name || '稳态数据'
|
||||
exportSeriesCSV(echartsData.value.options.series, `${chartTitle}.csv`)
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -148,13 +148,14 @@ const handleNodeClick = (data: any, node: any) => {
|
||||
|
||||
const exportEvent = () => {
|
||||
const now = new Date()
|
||||
const year = now.getFullYear() // 4位年份
|
||||
const month = now.getMonth() + 1 // 月份0-11,需+1
|
||||
const day = now.getDate() // 日期1-31
|
||||
|
||||
// 格式化YYYY - MM - DD(补零)
|
||||
const formattedDate = `${year}${String(month).padStart(2, '0')}${String(day).padStart(2, '0')}`
|
||||
exportLuckysheetFile(name.value + formattedDate, tableStore.table.data.length > 0)
|
||||
exportLuckysheetFile(
|
||||
{
|
||||
subject: name.value,
|
||||
feature: '统计报表',
|
||||
date: datePickerRef.value?.timeValue?.[1] || now
|
||||
},
|
||||
tableStore.table.data.length > 0
|
||||
)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
2932
src/views/govern/cloudDeviceEntry/components/monitoring.vue
Normal file
2932
src/views/govern/cloudDeviceEntry/components/monitoring.vue
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -118,6 +118,11 @@ const init = () => {
|
||||
})
|
||||
let [min, max] = yMethod(arr.map((item: any) => item.statisticalData.toFixed(2)))
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: props.detail.name?.split('(')[0],
|
||||
feature: '历史趋势',
|
||||
date: datePickerRef.value?.timeValue?.[1] || datePickerRef.value?.timeValue?.[0]
|
||||
},
|
||||
|
||||
options: {
|
||||
legend: {
|
||||
@@ -261,7 +266,11 @@ const init = () => {
|
||||
|
||||
return [item[0], item[1], value1, value2, value3];
|
||||
});
|
||||
exportCSV(echartsData.value.options.series.map(item => item.name), dataList, echartsData.value.title.text + '.csv')
|
||||
exportCSV(
|
||||
echartsData.value.options.series.map(item => item.name),
|
||||
dataList,
|
||||
echartsData.value.exportFileName
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +377,7 @@ import {
|
||||
getRawData
|
||||
} from '@/api/cs-device-boot/EquipmentDelivery'
|
||||
import { deviceHisData, deviceRtData, realTimeData, getTestData } from '@/api/cs-device-boot/csGroup'
|
||||
import { buildExportFileName } from '@/utils/echartMethod'
|
||||
import { ref, reactive, onMounted, onUnmounted, inject, nextTick, onBeforeUnmount } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
@@ -1372,7 +1373,11 @@ const downloadTxt = () => {
|
||||
// 创建 <a> 标签并触发下载
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = '实时数据.txt' // 文件名
|
||||
link.download = buildExportFileName({
|
||||
subject: (TrendList.value as any)?.name,
|
||||
feature: '实时数据',
|
||||
ext: 'txt'
|
||||
})
|
||||
link.click()
|
||||
|
||||
// 释放 URL 对象
|
||||
|
||||
@@ -210,15 +210,12 @@ const buildTMetric = (name: string, items: RawMetricItem[]): DisplayMetric => {
|
||||
return {
|
||||
name,
|
||||
otherName: name,
|
||||
unit: sharedUnit,
|
||||
unit: getSharedUnit(items),
|
||||
type: 't-multi',
|
||||
subItems: items.map(item => {
|
||||
const keyword = extractSubTitle(item.otherName || item.name || '')
|
||||
return {
|
||||
subTitle: unitsDiffer ? buildTitle(keyword, item.unit) : keyword,
|
||||
subItems: items.map(item => ({
|
||||
subTitle: extractSubTitle(item.otherName || item.name || ''),
|
||||
value: item.data,
|
||||
}
|
||||
}),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +222,11 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: {
|
||||
subject: (props.TrendList as any)?.name || trendRequestData.value?.name,
|
||||
feature: '电度数据',
|
||||
date: datePickerRef.value?.timeValue?.[1] || datePickerRef.value?.timeValue?.[0]
|
||||
},
|
||||
legend: {
|
||||
itemWidth: 20,
|
||||
itemHeight: 20,
|
||||
@@ -290,7 +295,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
exportSeriesCSV(echartsData.value.options.series, '电度数据.csv')
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
|
||||
@@ -26,6 +26,7 @@ import { ArrowLeft, Message } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { analyseWave, getFileByEventId } from '@/api/common'
|
||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echartMethod'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
const emit=defineEmits(['fileRecall'])
|
||||
const tableParams: any = ref({})
|
||||
@@ -108,12 +109,12 @@ const tableStore: any = new TableStore({
|
||||
{ field: 'showName', title: '触发类型', minWidth: 100 },
|
||||
{
|
||||
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
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.id == row.cellValue)?.name || '未知'
|
||||
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
}
|
||||
},
|
||||
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true, },
|
||||
@@ -206,7 +207,7 @@ const tableStore: any = new TableStore({
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
|
||||
link.download = buildWaveExportFileName(getExportSubjectFromRow(row))
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
|
||||
@@ -62,7 +62,7 @@ import { ref, onMounted, watch } from 'vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { queryStatistical } from '@/api/system-boot/csstatisticalset'
|
||||
import { yMethod, exportSeriesCSV, completeTimeSeries } from '@/utils/echartMethod'
|
||||
import { yMethod, exportSeriesCSV, completeTimeSeries, buildExportFileName } from '@/utils/echartMethod'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { getTabsDataByType } from '@/api/cs-device-boot/EquipmentDelivery'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
@@ -283,6 +283,15 @@ const init = async () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
const getChartExportFileName = () => {
|
||||
const obj = deviceData.value.records?.find((item: any) => item.id == activeName.value)
|
||||
return {
|
||||
subject: (props.TrendList as any)?.name,
|
||||
feature: obj?.itemName || '历史趋势',
|
||||
date: datePickerRef.value?.timeValue?.[1] || datePickerRef.value?.timeValue?.[0]
|
||||
}
|
||||
}
|
||||
|
||||
const setEchart = () => {
|
||||
loading.value = true
|
||||
echartsData.value = {}
|
||||
@@ -315,6 +324,7 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: getChartExportFileName(),
|
||||
legend: {
|
||||
itemWidth: 20,
|
||||
itemHeight: 20,
|
||||
@@ -383,7 +393,7 @@ const setEchart = () => {
|
||||
title: '下载csv',
|
||||
icon: 'path://M642 673.1H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9s-8 17.9-17.9 17.9zM642 511.8H301.6c-9.9 0-17.9-8-17.9-17.9 0-9.9 8-17.9 17.9-17.9H642c9.9 0 17.9 8 17.9 17.9 0 9.9-8 17.9-17.9 17.9zM480.7 350.6H301.6c-9.9 0-17.9-8-17.9-17.9s8-17.9 17.9-17.9h179.2c9.9 0 17.9 8 17.9 17.9s-8.1 17.9-18 17.9zM874.9 350.6H695.7c-49.4 0-89.6-40.2-89.6-89.6V81.9c0-9.9 8-17.9 17.9-17.9 9.9 0 17.9 8 17.9 17.9V261c0 29.6 24.1 53.7 53.7 53.7h179.2c9.9 0 17.9 8 17.9 17.9s-7.9 18-17.8 18zM794.3 959.7H221c-49.4 0-89.6-40.2-89.6-89.6V153.5c0-49.4 40.2-89.6 89.6-89.6h403.1c4.8 0 9.3 1.9 12.7 5.2L887.6 320c3.4 3.4 5.2 7.9 5.2 12.7v537.5c0 52.7-51.9 89.5-98.5 89.5zM221 99.8c-29.6 0-53.7 24.1-53.7 53.7v716.6c0 29.6 24.1 53.7 53.7 53.7h573.3c29 0 62.7-23.5 62.7-53.7v-530L616.7 99.8H221z',
|
||||
onclick: () => {
|
||||
exportSeriesCSV(echartsData.value.options.series, '历史趋势.csv')
|
||||
exportSeriesCSV(echartsData.value.options.series, echartsData.value.exportFileName)
|
||||
}
|
||||
},
|
||||
myTool2: {
|
||||
@@ -651,11 +661,7 @@ const handleExport = async () => {
|
||||
const blob = new Blob([csvs], { type: 'text/csv;charset=utf-8;' })
|
||||
const link = document.createElement('a')
|
||||
link.href = URL.createObjectURL(blob)
|
||||
let obj = deviceData.value.records.find((item: any) => {
|
||||
return item.id == activeName.value
|
||||
})
|
||||
const date = window.XEUtils.toDateString(new Date(), 'yyyyMMdd HHmmss').replace(' ', '_')
|
||||
link.download = `${deviceData.value.itemName}_${obj?.itemName}_${date}.csv`
|
||||
link.download = buildExportFileName(echartsData.value?.exportFileName || getChartExportFileName())
|
||||
link.click()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ import DeviceTree from '@/components/tree/govern/deviceTree.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import { getDeviceData } from '@/api/cs-device-boot/EquipmentDelivery'
|
||||
import { buildExportBaseName } from '@/utils/echartMethod'
|
||||
import { getTargetById } from '@/api/cs-device-boot/csDataArray'
|
||||
import { getGroup } from '@/api/cs-device-boot/csGroup'
|
||||
import { ref } from 'vue'
|
||||
@@ -135,6 +136,7 @@ const deviceTypeChange = (val: any, obj: any) => {
|
||||
deviceType.value = val
|
||||
nodeClick(obj)
|
||||
}
|
||||
const exportSubjectName = ref('')
|
||||
// 树节点点击
|
||||
const nodeClick = (e: anyObj) => {
|
||||
if (!e) {
|
||||
@@ -142,6 +144,7 @@ const nodeClick = (e: anyObj) => {
|
||||
return
|
||||
}
|
||||
if (e.level == 2 || e.level == 3) {
|
||||
exportSubjectName.value = e.name || ''
|
||||
pName.value = e.pName
|
||||
nDid.value = e.ndid
|
||||
loading.value = true
|
||||
@@ -288,8 +291,12 @@ const handleRestartDevice = () => {
|
||||
})
|
||||
}
|
||||
const exportData = () => {
|
||||
const dataSetName = deviceData.value.dataSetList.filter((item: any) => item.id == dataSet.value)[0]?.name
|
||||
xTableRef.value.exportData({
|
||||
filename: deviceData.value.dataSetList.filter((item: any) => item.id == dataSet.value)[0]?.name, // 文件名字
|
||||
filename: buildExportBaseName({
|
||||
subject: exportSubjectName.value || deviceData.value?.name,
|
||||
feature: dataSetName || '数据集'
|
||||
}), // 文件名字
|
||||
sheetName: 'Sheet1',
|
||||
type: 'xlsx', //导出文件类型 xlsx 和 csv
|
||||
useStyle: true,
|
||||
|
||||
@@ -34,6 +34,7 @@ import waveFormAnalysis from '@/views/govern/device/control/tabs/components/wave
|
||||
import { analyseWave, getFileByEventId } from '@/api/common'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echartMethod'
|
||||
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import analysisList from '@/views/govern/device/control/analysisList/index.vue'
|
||||
|
||||
@@ -109,12 +110,12 @@ const tableStore = new TableStore({
|
||||
{ field: 'showName', title: '触发类型', minWidth: 100 },
|
||||
{
|
||||
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => {
|
||||
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '未知'
|
||||
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.id == row.cellValue)?.name || '未知'
|
||||
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
|
||||
}
|
||||
},
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: 120, align: 'center' },
|
||||
@@ -204,7 +205,7 @@ const tableStore = new TableStore({
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
|
||||
link.download = buildWaveExportFileName(getExportSubjectFromRow(row))
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
:name="item.id" :key="index">
|
||||
<template #label>
|
||||
<span class="custom-tabs-label">
|
||||
<el-icon>
|
||||
<!-- <el-icon>
|
||||
<TrendCharts />
|
||||
</el-icon>
|
||||
</el-icon> -->
|
||||
<span>{{ item.itemName }}</span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -203,7 +203,7 @@ import { getTestRecordInfo, getHistoryTrend } from '@/api/cs-device-boot/planDat
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { queryStatistical } from '@/api/system-boot/csstatisticalset'
|
||||
import { TrendCharts, Plus, Platform } from '@element-plus/icons-vue'
|
||||
import { yMethod, completeTimeSeries } from '@/utils/echartMethod'
|
||||
import { yMethod, completeTimeSeries, buildExportFileName } from '@/utils/echartMethod'
|
||||
import { color, gradeColor3 } from '@/components/echarts/color'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useConfig } from '@/stores/config'
|
||||
@@ -341,10 +341,12 @@ const handleClickTabs = async () => {
|
||||
transientRef.value && transientRef.value.init()
|
||||
}, 100)
|
||||
}
|
||||
const exportSubjectName = ref('')
|
||||
const nodeClick = async (e: anyObj) => {
|
||||
if (e == undefined) {
|
||||
return
|
||||
}
|
||||
exportSubjectName.value = e.name || ''
|
||||
// onIndexChange([])
|
||||
deviceData.value = []
|
||||
historyDevId.value = e?.children && e?.children.length != 0 ? e?.children[0].id : e?.id
|
||||
@@ -567,6 +569,15 @@ const init = (flag: boolean) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getChartExportFileName = () => {
|
||||
const obj = deviceData.value.records?.find((item: any) => item.id == activeName.value)
|
||||
return {
|
||||
subject: exportSubjectName.value,
|
||||
feature: obj?.itemName || '预案数据',
|
||||
date: obj?.endTime || obj?.startTime
|
||||
}
|
||||
}
|
||||
|
||||
const setEchart = () => {
|
||||
loading.value = true
|
||||
echartsData.value = {}
|
||||
@@ -597,6 +608,7 @@ const setEchart = () => {
|
||||
}
|
||||
|
||||
echartsData.value = {
|
||||
exportFileName: getChartExportFileName(),
|
||||
// title: {
|
||||
// text: chartTitle.value,
|
||||
// left: '0',
|
||||
@@ -919,11 +931,7 @@ const handleExport = async () => {
|
||||
const blob = new Blob([csvs], { type: 'text/csv;charset=utf-8;' })
|
||||
const link = document.createElement('a')
|
||||
link.href = URL.createObjectURL(blob)
|
||||
let obj = deviceData.value.records.find((item: any) => {
|
||||
return item.id == activeName.value
|
||||
})
|
||||
const date = window.XEUtils.toDateString(new Date(), 'yyyyMMdd HHmmss').replace(' ', '_')
|
||||
link.download = `${deviceData.value.itemName}_${obj?.itemName}_${date}.csv`
|
||||
link.download = buildExportFileName(echartsData.value?.exportFileName || getChartExportFileName())
|
||||
link.click()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
<div>
|
||||
<TableHeader datePicker showExport>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="设备名称">
|
||||
<el-input maxlength="32" show-word-limit
|
||||
|
||||
|
||||
v-model.trim="tableStore.table.params.searchValue"
|
||||
placeholder="请输入设备名称"
|
||||
/>
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
|
||||
placeholder="请输入设备、监测点名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="级别">
|
||||
<el-select v-model="levelFilter" multiple clearable collapse-tags placeholder="请选择级别">
|
||||
<el-option v-for="item in rankOptions" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
@@ -25,8 +27,44 @@ import TableHeader from '@/components/table/header/index.vue'
|
||||
defineOptions({
|
||||
name: 'govern/log/debug'
|
||||
})
|
||||
const rankOptions = ref([
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '1级'
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '2级'
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '3级'
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '3级'
|
||||
// },
|
||||
{
|
||||
value: '4',
|
||||
label: 'DEBUG'
|
||||
},
|
||||
{
|
||||
value: '5',
|
||||
label: 'NORMAL'
|
||||
},
|
||||
{
|
||||
value: '6',
|
||||
label: 'WARN'
|
||||
},
|
||||
{
|
||||
value: '7',
|
||||
label: 'ERROR'
|
||||
}
|
||||
|
||||
])
|
||||
const levelFilter = ref<string[]>([])
|
||||
const tableStore = new TableStore({
|
||||
url: '/cs-device-boot/process/queryPage',
|
||||
url: '/cs-harmonic-boot/event/getFrontDebugLogs',
|
||||
method: 'POST',
|
||||
publicHeight: 65,
|
||||
column: [
|
||||
@@ -38,36 +76,65 @@ const tableStore = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '设备名称', field: 'devName', align: 'center' },
|
||||
{ title: '操作用户', field: 'operatorName', align: 'center' },
|
||||
{ title: '调试时间', field: 'startTime', align: 'center', sortable: true, width: 180 },
|
||||
{ title: '设备名称', field: 'deviceName', align: 'center', width: 180 },
|
||||
{
|
||||
title: '操作内容',
|
||||
field: 'process',
|
||||
align: 'center',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue == 1
|
||||
? '设备登记'
|
||||
: row.cellValue == 2
|
||||
? '功能调试'
|
||||
: row.cellValue == 3
|
||||
? '出厂调试'
|
||||
: row.cellValue == 4
|
||||
? '设备投运'
|
||||
: ''
|
||||
title: '监测点名称', field: 'lineName', align: 'center', width: 180, formatter: (row: any) => {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{ title: '开始时间', field: 'startTime', align: 'center', sortable: true },
|
||||
|
||||
// { title: '操作用户', field: 'operatorName', align: 'center' },
|
||||
{
|
||||
title: '结束时间',
|
||||
field: 'endTime',
|
||||
title: '调试内容',
|
||||
field: 'event',
|
||||
align: 'center',
|
||||
sortable: true,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
minWidth: 250,
|
||||
|
||||
},
|
||||
{
|
||||
title: '级别',
|
||||
field: 'level',
|
||||
width: 110,
|
||||
render: 'tag',
|
||||
custom: {
|
||||
// 1:Ⅰ级 2:Ⅱ级 3:Ⅲ级 4:DEBUG 5:NORMAL 6:WARN 7:ERROR
|
||||
|
||||
// 1: 'danger',
|
||||
// 2: 'warning',
|
||||
// 3: 'success',
|
||||
4: 'success',
|
||||
5: 'success',
|
||||
6: 'warning',
|
||||
7: 'danger'
|
||||
},
|
||||
replaceValue: {
|
||||
// 1: '1级',
|
||||
// 2: '2级',
|
||||
// 3: '3级',
|
||||
4: 'DEBUG',
|
||||
5: 'NORMAL',
|
||||
6: 'WARN',
|
||||
7: 'ERROR'
|
||||
}
|
||||
}
|
||||
// {
|
||||
// title: '结束时间',
|
||||
// field: 'endTime',
|
||||
// align: 'center',
|
||||
// sortable: true,
|
||||
// formatter: (row: any) => {
|
||||
// return row.cellValue || '/'
|
||||
// }
|
||||
// }
|
||||
],
|
||||
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.level = levelFilter.value.length ? levelFilter.value.join(',') : ''
|
||||
},
|
||||
resetCallback: () => {
|
||||
levelFilter.value = []
|
||||
},
|
||||
loadCallback: () => {
|
||||
tableStore.table.data.forEach((item: any) => {
|
||||
item.result = item.result === 1 ? '成功' : '失败'
|
||||
@@ -88,6 +155,6 @@ tableStore.table.params.searchValue = ''
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const addMenu = () => {}
|
||||
tableStore.table.params.level = ''
|
||||
const addMenu = () => { }
|
||||
</script>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="default-main apf">
|
||||
<el-tabs type="border-card" v-model="activeName">
|
||||
<el-tab-pane label="治理交互日志" name="1">
|
||||
<el-tab-pane label="治理设备" name="1">
|
||||
<governance v-if="activeName == '1'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="前置交互日志" name="2">
|
||||
<el-tab-pane label="前置" name="2">
|
||||
<front v-if="activeName == '2'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
@@ -15,7 +15,7 @@ defineOptions({
|
||||
name: 'govern/log/operation'
|
||||
})
|
||||
const tableStore = new TableStore({
|
||||
url: '/cs-device-boot/cslog/queryLog',
|
||||
url: '/cs-system-boot/cslog/queryLog',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{
|
||||
@@ -26,10 +26,27 @@ const tableStore = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '操作日期', field: 'createTime', align: 'center', sortable: true, minWidth: '150' },
|
||||
{ title: '操作日期', field: 'createTime', align: 'center', sortable: true, width: '180' },
|
||||
{ title: '用户名称', field: 'userName', align: 'center', width: '180' },
|
||||
{ title: '操作描述', field: 'operate', align: 'center', minWidth: '300' },
|
||||
{ title: '用户名称', field: 'userName', align: 'center', minWidth: '130' },
|
||||
{ title: '更新时间', field: 'updateTime', align: 'center', sortable: true, minWidth: '150' },
|
||||
|
||||
{
|
||||
title: '状态',
|
||||
field: 'result',
|
||||
align: 'center',
|
||||
width: '100',
|
||||
render: 'tag',
|
||||
custom: {
|
||||
0: 'danger',
|
||||
1: 'success',
|
||||
null:'info'
|
||||
},
|
||||
replaceValue: {
|
||||
0: '失败',
|
||||
1: '成功',
|
||||
null: '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '失败原因',
|
||||
field: 'failReason',
|
||||
@@ -39,24 +56,15 @@ const tableStore = new TableStore({
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
field: 'result',
|
||||
align: 'center',
|
||||
minWidth: '100',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue == 1 ? '成功' : '失败'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '登录名',
|
||||
field: 'loginName',
|
||||
align: 'center',
|
||||
minWidth: '120',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
}
|
||||
// {
|
||||
// title: '登录名称',
|
||||
// field: 'loginName',
|
||||
// align: 'center',
|
||||
// minWidth: '120',
|
||||
// formatter: (row: any) => {
|
||||
// return row.cellValue || '/'
|
||||
// }
|
||||
// }
|
||||
],
|
||||
|
||||
loadCallback: () => {
|
||||
@@ -76,5 +84,5 @@ onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const addMenu = () => {}
|
||||
const addMenu = () => { }
|
||||
</script>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<el-option label="稳态" value="harmonic"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="敏感用户"class="top">
|
||||
<el-form-item label="敏感用户" class="top">
|
||||
<div style="display: flex;">
|
||||
<el-select v-model.trim="form.monitorUser" style="width: 230px;" filterable placeholder="请选择敏感用户"
|
||||
clearable>
|
||||
@@ -48,9 +48,12 @@
|
||||
<el-option label="CLD" value="CLD"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联项目" class="top">
|
||||
<el-form-item label="关联项目" class="top" prop="association" :required="isMonitorDeviceType">
|
||||
<div style="display: flex;">
|
||||
<el-cascader v-model.trim="form.association" filterable :options="engineeringList"
|
||||
:props="cascaderProps" clearable placeholder="请选择关联项目" />
|
||||
<el-button type="primary" icon="el-icon-Plus" class="ml10" @click="addProject" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" class="top" prop="sort">
|
||||
<el-input-number v-model.trim="form.sort" style="width: 100%;" :min="0" />
|
||||
@@ -105,9 +108,40 @@ const rules = reactive({
|
||||
devModel: [{ required: true, message: '请选择设备型号', trigger: 'change' }],
|
||||
devAccessMethod: [{ required: true, message: '请输入接入方式', trigger: 'blur' }],
|
||||
cntractNo: [{ required: true, message: '请输入合同号', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||
association: [{
|
||||
validator: (_rule: any, value: any, callback: (error?: Error) => void) => {
|
||||
if (isMonitorDevType(form.devType)) {
|
||||
if (!Array.isArray(value) || value.length < 2 || !value[0] || !value[1]) {
|
||||
callback(new Error('请选择关联项目'))
|
||||
return
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
trigger: 'change'
|
||||
}]
|
||||
})
|
||||
|
||||
const getDevTypeOptions = () => {
|
||||
if (form.devAccessMethod === 'CLD') {
|
||||
return Array.isArray(props.devTypeOptions2)
|
||||
? props.devTypeOptions2
|
||||
: props.devTypeOptions2
|
||||
? [props.devTypeOptions2]
|
||||
: []
|
||||
}
|
||||
return props.devTypeOptions
|
||||
}
|
||||
|
||||
const isMonitorDevType = (devType: unknown) => {
|
||||
if (!devType) return false
|
||||
const selected = getDevTypeOptions().find((item: any) => (item.value || item.id) == devType)
|
||||
return selected?.name === '监测设备' || selected?.label === '监测设备' || selected?.code === 'DEV_CLD'
|
||||
}
|
||||
|
||||
const isMonitorDeviceType = computed(() => isMonitorDevType(form.devType))
|
||||
|
||||
function getDefaultForm() {
|
||||
return {
|
||||
cntractNo: '',
|
||||
@@ -170,6 +204,12 @@ const formDevTypeOptions = computed(() => {
|
||||
const formDevTypeChange = (e: any) => {
|
||||
if (!e) return
|
||||
form.devModel = ''
|
||||
nextTick(() => {
|
||||
ruleFormRef.value?.clearValidate('association')
|
||||
if (isMonitorDevType(e)) {
|
||||
ruleFormRef.value?.validateField('association')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const openAdd = () => {
|
||||
@@ -219,6 +259,12 @@ const addMonitorUser = () => {
|
||||
name: 'govern/sensitiveLoadMange/index',
|
||||
})
|
||||
}
|
||||
const addProject = () => {
|
||||
sessionStorage.setItem('factoryNeedRefreshEngineeringList', '1')
|
||||
router.push({
|
||||
name: 'govern/manage/engineering',
|
||||
})
|
||||
}
|
||||
const onSubmit = () => {
|
||||
ruleFormRef.value.validate((valid: boolean) => {
|
||||
if (!valid) return
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="default-main" v-loading="loading">
|
||||
<div v-loading="loading">
|
||||
<TableHeader>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="关键字筛选">
|
||||
@@ -214,6 +214,7 @@ const tableStore = new TableStore({
|
||||
url: '/cs-device-boot/EquipmentDelivery/list',
|
||||
method: 'POST',
|
||||
isWebPaging: true,
|
||||
publicHeight: 60,
|
||||
column: [
|
||||
{
|
||||
width: '60',
|
||||
@@ -837,20 +838,8 @@ const getUserList = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 页面被 keep-alive 缓存后,从敏感用户页返回时刷新下拉列表
|
||||
onActivated(() => {
|
||||
if (sessionStorage.getItem('factoryNeedRefreshUserList')) {
|
||||
sessionStorage.removeItem('factoryNeedRefreshUserList')
|
||||
getUserList()
|
||||
}
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
getUserList()
|
||||
queryTheDictionary()
|
||||
engineeringProject().then(res => {
|
||||
const getEngineeringList = () => {
|
||||
return engineeringProject().then(res => {
|
||||
engineeringList.value = res.data.filter(item => {
|
||||
item.projectName = item.engineeringName
|
||||
item.projectId = item.engineeringId
|
||||
@@ -858,6 +847,27 @@ onMounted(() => {
|
||||
return item
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 页面被 keep-alive 缓存后,从敏感用户/工程页返回时刷新下拉列表
|
||||
onActivated(() => {
|
||||
// if (sessionStorage.getItem('factoryNeedRefreshUserList')) {
|
||||
// sessionStorage.removeItem('factoryNeedRefreshUserList')
|
||||
getUserList()
|
||||
// }
|
||||
|
||||
// if (sessionStorage.getItem('factoryNeedRefreshEngineeringList')) {
|
||||
// sessionStorage.removeItem('factoryNeedRefreshEngineeringList')
|
||||
getEngineeringList()
|
||||
// }
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
queryTheDictionary()
|
||||
// getUserList()
|
||||
// getEngineeringList()
|
||||
|
||||
setTimeout(() => { }, 100)
|
||||
})
|
||||
|
||||
@@ -30,6 +30,7 @@ import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import { buildExportBaseName } from '@/utils/echartMethod'
|
||||
defineOptions({
|
||||
name: 'manage/monthly'
|
||||
})
|
||||
@@ -180,7 +181,7 @@ tableStore.table.params.name = ''
|
||||
const tableRef = ref()
|
||||
const exportTab = () => {
|
||||
tableRef.value.getRef()?.exportData({
|
||||
filename: '半月报功能', // 文件名字
|
||||
filename: buildExportBaseName({ feature: '半月报功能' }), // 文件名字
|
||||
sheetName: 'Sheet1',
|
||||
type: 'xlsx', //导出文件类型 xlsx 和 csv
|
||||
useStyle: true,
|
||||
|
||||
@@ -140,6 +140,7 @@ import { genFileId, ElMessage, ElNotification } from 'element-plus'
|
||||
import type { UploadProps, UploadUserFile } from 'element-plus'
|
||||
import pointTree from '@/components/tree/govern/pointTree.vue'
|
||||
import { getLineExport } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { buildExportFileName } from '@/utils/echartMethod'
|
||||
import { isReportMonitorPoint } from '@/components/tree/govern/lineTreeUtils'
|
||||
defineOptions({
|
||||
name: 'TransientReport/monitoringpointReport'
|
||||
@@ -216,12 +217,6 @@ const exportEvent = () => {
|
||||
ElMessage('生成报告中,请稍等!')
|
||||
|
||||
const now = new Date()
|
||||
const year = now.getFullYear() // 4位年份
|
||||
const month = now.getMonth() + 1 // 月份0-11,需+1
|
||||
const day = now.getDate() // 日期1-31
|
||||
|
||||
// 格式化YYYY - MM - DD(补零)
|
||||
const formattedDate = `${year}${String(month).padStart(2, '0')}${String(day).padStart(2, '0')}`
|
||||
getLineExport(formd.value)
|
||||
.then(async (res: any) => {
|
||||
if (res == undefined) {
|
||||
@@ -236,7 +231,12 @@ const exportEvent = () => {
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = dotList.value.name + formattedDate // 设置下载的文件名
|
||||
link.download = buildExportFileName({
|
||||
subject: dotList.value.name,
|
||||
feature: '报告',
|
||||
date: formd.value.searchEndTime || now,
|
||||
ext: 'docx'
|
||||
})
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link)
|
||||
|
||||
@@ -113,7 +113,14 @@ const handleNodeClick = (data: any, node: any) => {
|
||||
}
|
||||
|
||||
const exportEvent = () => {
|
||||
exportLuckysheetFile('统计报表下载', tableStore.table.data.length > 0)
|
||||
exportLuckysheetFile(
|
||||
{
|
||||
subject: dotList.value?.name,
|
||||
feature: '统计报表',
|
||||
date: TableHeaderRef.value?.datePickerRef?.timeValue?.[1]
|
||||
},
|
||||
tableStore.table.data.length > 0
|
||||
)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
@@ -61,6 +61,7 @@ import TableStore from '@/utils/tableStore'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { ElMessage, ElNotification } from 'element-plus'
|
||||
import { exportModel } from '@/api/cs-harmonic-boot/datatrend'
|
||||
import { buildExportFileName } from '@/utils/echartMethod'
|
||||
import { isReportMonitorPoint } from '@/components/tree/govern/lineTreeUtils'
|
||||
|
||||
defineOptions({
|
||||
@@ -153,7 +154,6 @@ const exportEvent = () => {
|
||||
ElMessage('生成报告中...')
|
||||
|
||||
const now = new Date()
|
||||
const formattedDate = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}`
|
||||
|
||||
exportModel(form)
|
||||
.then((res: any) => {
|
||||
@@ -164,7 +164,12 @@ const exportEvent = () => {
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = props.dotList.name + formattedDate
|
||||
link.download = buildExportFileName({
|
||||
subject: props.dotList.name,
|
||||
feature: '报告',
|
||||
date: tableHeaderRef.value?.datePickerRef?.timeValue?.[1] || now,
|
||||
ext: 'docx'
|
||||
})
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
|
||||
@@ -110,11 +110,14 @@ const exportEvent = () => {
|
||||
return ElMessage.warning('治理监测点暂不支持出报表!')
|
||||
}
|
||||
const now = new Date()
|
||||
const year = now.getFullYear()
|
||||
const month = now.getMonth() + 1
|
||||
const day = now.getDate()
|
||||
const formattedDate = `${year}${String(month).padStart(2, '0')}${String(day).padStart(2, '0')}`
|
||||
exportLuckysheetFile(exportName.value + formattedDate, tableStore.table.data.length > 0)
|
||||
exportLuckysheetFile(
|
||||
{
|
||||
subject: exportName.value,
|
||||
feature: '统计报表',
|
||||
date: tableHeaderRef.value?.datePickerRef?.timeValue?.[1] || now
|
||||
},
|
||||
tableStore.table.data.length > 0
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
|
||||
@@ -123,13 +123,14 @@ const handleNodeClick = (data: any, node: any) => {
|
||||
|
||||
const exportEvent = () => {
|
||||
const now = new Date()
|
||||
const year = now.getFullYear() // 4位年份
|
||||
const month = now.getMonth() + 1 // 月份0-11,需+1
|
||||
const day = now.getDate() // 日期1-31
|
||||
|
||||
// 格式化YYYY - MM - DD(补零)
|
||||
const formattedDate = `${year}${String(month).padStart(2, '0')}${String(day).padStart(2, '0')}`
|
||||
exportLuckysheetFile(name.value + formattedDate, tableStore.table.data.length > 0)
|
||||
exportLuckysheetFile(
|
||||
{
|
||||
subject: name.value,
|
||||
feature: '统计报表',
|
||||
date: datePickerRef.value?.timeValue?.[1] || now
|
||||
},
|
||||
tableStore.table.data.length > 0
|
||||
)
|
||||
}
|
||||
onUnmounted(() => {
|
||||
destroyLuckysheet()
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<template>
|
||||
<div class="statistics-wx-zl default-main" :style="height">
|
||||
<aside>
|
||||
<!-- <CloudDeviceEntryTree
|
||||
ref="TerminalRef"
|
||||
template
|
||||
@Policy="stencil"
|
||||
@init="handleNodeClick"
|
||||
/> -->
|
||||
<APFTree @node-click="handleNodeClick" template @init="handleNodeClick" @Policy="stencil"></APFTree>
|
||||
</aside>
|
||||
<main class="statistics-wx-zl__main ">
|
||||
@@ -33,25 +27,26 @@
|
||||
</template>
|
||||
</TableHeader>
|
||||
<div class="statistics-wx-zl__sheet-box pl0" v-loading="tableStore.table.loading">
|
||||
<div
|
||||
v-if="tableStore.table.data.length > 0"
|
||||
id="luckysheet"
|
||||
class="statistics-wx-zl__sheet"
|
||||
<div class="statistics-wx-zl__sheet-wrap">
|
||||
<div id="luckysheet" class="statistics-wx-zl__sheet"></div>
|
||||
<el-empty
|
||||
v-show="!tableStore.table.loading && tableStore.table.data.length === 0"
|
||||
class="statistics-wx-zl__empty"
|
||||
description="暂无数据"
|
||||
/>
|
||||
<el-empty v-else class="statistics-wx-zl__empty" description="暂无数据" />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, provide, nextTick } from 'vue'
|
||||
import { onMounted, onUnmounted, ref, provide, nextTick } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import APFTree from '@/components/tree/govern/APFTree.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { exportExcel } from '@/views/system/reportForms/export.js'
|
||||
import CloudDeviceEntryTree from '@/components/tree/govern/cloudDeviceEntryTreeZL.vue'
|
||||
import { destroyLuckysheet, exportLuckysheetFile, renderLuckysheetReport } from '@/utils/luckysheetHelper'
|
||||
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
@@ -72,31 +67,30 @@ const tableStore = new TableStore({
|
||||
url: '/cs-harmonic-boot/customReport/getSensitiveUserReport',
|
||||
method: 'POST',
|
||||
column: [],
|
||||
showPage: false,
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.tempId = Template.value.id
|
||||
tableStore.table.params.lineId = dotList.value.id
|
||||
tableStore.table.params.sensitiveUserId = dotList.value.id
|
||||
if (!tableStore.table.params.tempId) {
|
||||
return ElMessage.warning('请选择模板')
|
||||
ElMessage.warning('请选择模板')
|
||||
return false
|
||||
}
|
||||
delete tableStore.table.params.searchBeginTime
|
||||
delete tableStore.table.params.searchEndTime
|
||||
const datePicker = TableHeaderRef.value?.datePickerRef
|
||||
if (datePicker?.timeValue?.[0] && datePicker?.timeValue?.[1]) {
|
||||
tableStore.table.params.searchBeginTime = datePicker.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePicker.timeValue[1]
|
||||
}
|
||||
destroyLuckysheet()
|
||||
delete tableStore.table.params.timeFlag
|
||||
},
|
||||
loadCallback: () => {
|
||||
name.value = dotList.value.name
|
||||
setTimeout(() => {
|
||||
luckysheet.create({
|
||||
container: 'luckysheet',
|
||||
title: '',
|
||||
lang: 'zh',
|
||||
showtoolbar: false,
|
||||
showinfobar: false,
|
||||
showsheetbar: true,
|
||||
allowEdit: false,
|
||||
data: tableStore.table.data
|
||||
})
|
||||
}, 10)
|
||||
if (tableStore.table.data.length > 0) {
|
||||
renderLuckysheetReport('luckysheet', tableStore.table.data, { allowEdit: false })
|
||||
} else {
|
||||
destroyLuckysheet()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -108,6 +102,10 @@ onMounted(() => {
|
||||
initListByIds()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
destroyLuckysheet()
|
||||
})
|
||||
|
||||
function initListByIds() {
|
||||
getListByIds({}).then((res: any) => {
|
||||
if (res.data?.length > 0) {
|
||||
@@ -130,7 +128,7 @@ const changetype = (val: any) => {
|
||||
}
|
||||
|
||||
const handleNodeClick = (data: any) => {
|
||||
if (data?.level == 3||data?.level == 2) {
|
||||
if (data?.level == 3 || data?.level == 2) {
|
||||
dotList.value = data
|
||||
nextTick(() => tableStore.index())
|
||||
} else {
|
||||
@@ -139,13 +137,13 @@ const handleNodeClick = (data: any) => {
|
||||
}
|
||||
|
||||
const exportEvent = () => {
|
||||
const now = new Date()
|
||||
const formattedDate = [
|
||||
now.getFullYear(),
|
||||
String(now.getMonth() + 1).padStart(2, '0'),
|
||||
String(now.getDate()).padStart(2, '0')
|
||||
].join('')
|
||||
exportExcel(luckysheet.getAllSheets(), name.value + formattedDate)
|
||||
exportLuckysheetFile(
|
||||
{
|
||||
subject: dotList.value?.name || name.value,
|
||||
feature: '统计报表'
|
||||
},
|
||||
tableStore.table.data.length > 0
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -196,6 +194,13 @@ const exportEvent = () => {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
&__sheet-wrap {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&__sheet,
|
||||
&__empty {
|
||||
height: 100%;
|
||||
@@ -207,6 +212,8 @@ const exportEvent = () => {
|
||||
}
|
||||
|
||||
&__empty {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<el-form-item label="所属厂站名称" prop="substationName">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.substationName" placeholder="请输入所属厂站名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="敏感用户名称" prop="name">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入敏感用户名称"></el-input>
|
||||
<el-form-item label="用户名称" prop="name">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入用户名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="敏感负荷类型" prop="loadType">
|
||||
<el-select v-model.trim="form.loadType" filterable clearable placeholder="请选择敏感负荷类型">
|
||||
@@ -64,7 +64,7 @@ const form = reactive<any>({
|
||||
})
|
||||
const rules = {
|
||||
substationName: [{ required: true, message: '请输入所属厂站名称', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入敏感用户名称', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入用户名称', trigger: 'blur' }],
|
||||
loadType: [{ required: true, message: '请输入请选择敏感负荷类型', trigger: 'blur' }],
|
||||
installedCapacity: [{ required: true, message: '请输入用户协议容量', trigger: 'blur' }],
|
||||
userAgreementCapacity: [{ required: true, message: '请输入装机容量', trigger: 'blur' }],
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
style="width: 240px"
|
||||
v-model.trim="tableStore.table.params.searchValue"
|
||||
clearable
|
||||
placeholder="请输入敏感用户名称"
|
||||
placeholder="请输入用户名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -51,7 +51,7 @@ const tableStore: any = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '敏感用户名称', field: 'name', minWidth: 180 },
|
||||
{ title: '用户名称', field: 'name', minWidth: 180 },
|
||||
{
|
||||
title: '敏感用户类型',
|
||||
field: 'loadType',
|
||||
|
||||
119
vite.config.ts.timestamp-1781526221528-0257d9cd8498d.mjs
Normal file
119
vite.config.ts.timestamp-1781526221528-0257d9cd8498d.mjs
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user