From b48d247fcff0755b7bd47c490e0620b9e2c3a54a Mon Sep 17 00:00:00 2001 From: guanj Date: Fri, 5 Sep 2025 16:03:31 +0800 Subject: [PATCH] =?UTF-8?q?=E8=81=94=E8=B0=83=E8=B0=90=E6=B3=A2=E8=B4=A3?= =?UTF-8?q?=E4=BB=BB=E5=88=92=E5=88=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/advance-boot/division.ts | 16 + src/components/echarts/MyEchart.vue | 643 +++++++++--------- src/views/pqs/business/log/frontLog/index.vue | 2 +- .../detailed/division/components/compute.vue | 455 ++++++++++++- .../detailed/division/components/detail.vue | 226 ++++-- .../detailed/division/index.vue | 2 - 6 files changed, 938 insertions(+), 406 deletions(-) diff --git a/src/api/advance-boot/division.ts b/src/api/advance-boot/division.ts index 21591960..3edb6391 100644 --- a/src/api/advance-boot/division.ts +++ b/src/api/advance-boot/division.ts @@ -48,3 +48,19 @@ export function displayHistoryData(data: any) { params: data }) } +//生成谐波责任指标 +export function getResponsibilityData(data: any) { + return createAxios({ + url: '/advance-boot/responsibility/getResponsibilityData', + method: 'post', + data + }) +} +//生成动态谐波责任数据 +export function getDynamicData(data: any) { + return createAxios({ + url: '/advance-boot/responsibility/getDynamicData', + method: 'post', + data + }) +} diff --git a/src/components/echarts/MyEchart.vue b/src/components/echarts/MyEchart.vue index f9d38d93..b826f0fe 100644 --- a/src/components/echarts/MyEchart.vue +++ b/src/components/echarts/MyEchart.vue @@ -1,321 +1,322 @@ - - - - - + + + + + diff --git a/src/views/pqs/business/log/frontLog/index.vue b/src/views/pqs/business/log/frontLog/index.vue index 36c22cf4..ae00d56f 100644 --- a/src/views/pqs/business/log/frontLog/index.vue +++ b/src/views/pqs/business/log/frontLog/index.vue @@ -69,7 +69,7 @@ const tableStore = new TableStore({ }, { - title: '日志错误码', + title: '日志类型', field: 'codeName', minWidth: '180', formatter: (row: any) => { diff --git a/src/views/pqs/harmonicMonitoring/detailed/division/components/compute.vue b/src/views/pqs/harmonicMonitoring/detailed/division/components/compute.vue index a4f9bbf2..2be5d102 100644 --- a/src/views/pqs/harmonicMonitoring/detailed/division/components/compute.vue +++ b/src/views/pqs/harmonicMonitoring/detailed/division/components/compute.vue @@ -4,7 +4,8 @@
贡献度计算
- {{ dotList.alias || '' }} + + 当前位置:{{ dotList.alias || '' }}
@@ -45,7 +46,7 @@ - + 确定 - +
@@ -75,31 +76,93 @@ format="YYYY-MM-DD" date-format="YYYY-MM-DD" time-format="YYYY-MM-DD" + value-format="YYYY-MM-DD" :disabled-date="handleDisabledDate" /> 执行
-
- - - +
+ + + + + - - + + + + - - + + + + - + 生成动态谐波责任数据 - 生成谐波责任指标 + + 生成谐波责任指标 +
+ +
+ + +
+ +
+ +
+ + + + + + +
+
@@ -112,14 +175,17 @@ import { ref, reactive, onMounted, onUnmounted } from 'vue' import { mainHeight } from '@/utils/layout' import 'splitpanes/dist/splitpanes.css' import { Splitpanes, Pane } from 'splitpanes' +import { defaultAttribute } from '@/components/table/defaultAttribute' import PointTree from '@/components/tree/pqs/pointTree.vue' import BackComponent from '@/components/icon/back/index.vue' import { harmonicOptions } from '@/utils/dictionary' -import { userDataList } from '@/api/advance-boot/division' +import { userDataList, getHistoryHarmData, getDynamicData, getResponsibilityData } from '@/api/advance-boot/division' import { useRouter } from 'vue-router' import { ElMessage } from 'element-plus' -import { formatDate } from '@/utils/formatTime' -import { getHistoryHarmData } from '@/api/advance-boot/division' +import { Edit } from '@element-plus/icons-vue' +import MyEChart from '@/components/echarts/MyEchart.vue' +import { timeFormat } from '@/utils/common' +import { yMethod } from '@/utils/echartMethod' defineOptions({ name: 'division/compute' }) @@ -132,23 +198,29 @@ const size = ref(0) const showTabs = ref(false) const loadDataOptions: any = ref([]) const form: any = reactive({ - type: '0', + type: '1', index: [], - loadData: '' + loadDataId: '' }) +const code = ref(3) +const xAxisData = ref([]) +const loading = ref(false) +const loading1 = ref(false) const tabList: any = ref([]) const activeName = ref(0) +const xValue = ref('') const handleNodeClick = (data: any, node: any) => { if (data.level == 6) { dotList.value = data } } // 设置时间 +const timeFrame = ref(['', '']) // 处理日期禁用逻辑 const handleDisabledDate = date => { // 定义时间边界 - const startLimit = new Date(tabList.value[0].time[0]).getTime() - const endLimit = new Date(tabList.value[0].time[1]).setHours(23, 59, 59, 999) + const startLimit = new Date(timeFrame.value[0]).getTime() - 86400000 //向前推1天 + const endLimit = new Date(timeFrame.value[1]).setHours(23, 59, 59, 999) // 如果日期不存在(选择今天时可能出现),不禁用 if (!date) return false @@ -156,16 +228,26 @@ const handleDisabledDate = date => { // 禁用 2025-08-01 之前和 2025-08-31 之后的日期 return date.getTime() < startLimit || date.getTime() > endLimit } +// 这是按钮变色 +const setCode = (num: number) => { + if (code.value == num) { + return (code.value = 3) + } + code.value = num +} // 确定 const submit = () => { - if (form.loadData == '') { + if (form.loadDataId == '') { return ElMessage.warning('请选择负荷数据') } + if (form.index.length == 0) { + return ElMessage.warning('请选择谐波次数') + } if (form.index.length == 0) { showTabs.value = false } else { - let timeList = loadDataOptions.value.filter((item: any) => item.id == form.loadData)[0] + let timeList = loadDataOptions.value.filter((item: any) => item.id == form.loadDataId)[0] showTabs.value = true let list = JSON.parse(JSON.stringify(form.index)).sort((a, b) => a - b) tabList.value = [] @@ -179,24 +261,311 @@ const submit = () => { limit: '', time1: '', time2: '' - } + }, + showEcahr: 3, //1显示echart 2显示无数据 3什么都没有 + options: {}, + dynamicOptions: {}, //动态echarts + dynamicList: {}, //动态echarts + showDynamic: false //动态执行展示 }) + timeFrame.value = [timeList.startTime, timeList.endTime] }) - // tabList.value = + code.value = 3 activeName.value = 0 } } // 执行 -const execute = (item: any, index: number) => { - getHistoryHarmData({ +const execute = async (item: any, index: number) => { + tabList.value[activeName.value].showDynamic = false + loading.value = true + await getHistoryHarmData({ searchBeginTime: item.time[0], searchEndTime: item.time[1], type: form.type, time: item.key, - // userDataId:form.loadData, lineId: dotList.value.id - }).then((res: any) => {}) - tabList.value[index].showExecute = true + }) + .then((res: any) => { + let [min, max] = yMethod(res.data.historyData.map((item: any) => item.value + 0.1)) + xAxisData.value = res.data.historyData.map((item: any) => item.time) + tabList.value[index].options = { + title: { + text: '' + }, + xAxis: { + type: 'time', + name: '时间', + axisLabel: { + formatter: { + day: '{MM}-{dd}', + month: '{MM}', + year: '{yyyy}' + } + } + }, + tooltip: { + formatter(params: any) { + xValue.value = params[0].value[0] + let str = params[0].value[0] + '
' + for (let i = 0; i < params.length; i++) { + str = str + params[i].marker + params[i].seriesName + ':' + params[i].value[1] + '
' + } + + return str + } + }, + grid: { + top: 30 + }, + legend: { + show: false + }, + yAxis: { + name: form.type == 1 ? '%' : 'A', + min: min, + max: max + }, + toolbox: { + show: false + }, + + series: [ + { + name: item.key + (form.type == 1 ? '次谐波电压' : '次谐波电流'), + data: res.data.historyData.map((item: any) => [ + item.time, + Math.floor(item.value * 10000) / 10000 + ]), + type: 'line', + symbol: 'none', + markLine: { + symbol: 'none', // 去除箭头 + label: { + show: false // 隐藏标签 + }, + data: [ + { + yAxis: '' + }, + { + xAxis: '' + }, + { + xAxis: '' + } + ], + // 样式配置 + lineStyle: { + color: 'red', + type: 'dashed' // 虚线 + } + } + } + ] + } + tabList.value[index].showEcahr = 1 + loading.value = false + }) + .catch(() => { + tabList.value[index].showEcahr = 2 + loading.value = false + }) +} +const resDataId = ref('') +// 生成动态谐波责任数据 +const generateFn = async () => { + loading1.value = true + await getDynamicData({ + lineId: dotList.value.id, + searchBeginTime: tabList.value[activeName.value].time[0], + searchEndTime: tabList.value[activeName.value].time[1], + time: tabList.value[activeName.value].key, + type: form.type, + userDataId: form.loadDataId + }) + .then((res: any) => { + resDataId.value = res.data.responsibilityDataIndex + tabList.value[activeName.value].dynamicData = res.data.responsibilities + let [min, max] = yMethod(res.data.datas.map((item: any) => item.valueDatas).flat()) + let series: any[] = [] + let time: any[] = res.data.timeDatas.map((item: any) => timeFormat(item)) + res.data.datas.forEach((item: any) => { + series.push({ + name: item.customerName, + data: item.valueDatas.map((k: any, i: number) => [time[i], Math.floor(k * 10000) / 10000]), + type: 'line', + symbol: 'none' + }) + }) + + tabList.value[activeName.value].dynamicOptions = { + title: { + text: '' + }, + xAxis: { + type: 'time', + name: '时间', + axisLabel: { + formatter: { + day: '{MM}-{dd}', + month: '{MM}', + year: '{yyyy}' + } + } + }, + tooltip: { + formatter(params: any) { + let str = params[0].value[0] + '
' + for (let i = 0; i < params.length; i++) { + str = str + params[i].marker + params[i].seriesName + ':' + params[i].value[1] + '
' + } + + return str + } + }, + grid: { + top: 30 + }, + legend: { + show: false + }, + yAxis: { + name: form.type == 1 ? '%' : 'A', + min: min, + max: max + }, + toolbox: { + show: false + }, + + options: { + series: series + } + } + + tabList.value[activeName.value].showDynamic = true + }) + .catch(() => { + loading1.value = false + }) + loading1.value = false +} +// 生成指标 +const generateMetrics = async () => { + if (tabList.value[activeName.value].form.limit == '') return ElMessage.warning('请选择限值!') + if (tabList.value[activeName.value].form.time1 == '') return ElMessage.warning('请选择时间一!') + if (tabList.value[activeName.value].form.time2 == '') return ElMessage.warning('请选择时间二!') + loading1.value = true + await getResponsibilityData({ + limitEndTime: tabList.value[activeName.value].form.time2, + limitStartTime: tabList.value[activeName.value].form.time1, + limitValue: tabList.value[activeName.value].form.limit, + resDataId: resDataId.value, + time: tabList.value[activeName.value].key, + type: form.type + }) + .then((res: any) => { + tabList.value[activeName.value].dynamicData = res.data.responsibilities + let [min, max] = yMethod(res.data.datas.map((item: any) => item.valueDatas).flat()) + let series: any[] = [] + let time: any[] = res.data.timeDatas.map((item: any) => timeFormat(item)) + res.data.datas.forEach((item: any) => { + series.push({ + name: item.customerName, + data: item.valueDatas.map((k: any, i: number) => [time[i], Math.floor(k * 10000) / 10000]), + type: 'line', + symbol: 'none' + }) + }) + + tabList.value[activeName.value].dynamicOptions = { + title: { + text: '' + }, + xAxis: { + type: 'time', + name: '时间', + axisLabel: { + formatter: { + day: '{MM}-{dd}', + month: '{MM}', + year: '{yyyy}' + } + } + }, + tooltip: { + formatter(params: any) { + let str = params[0].value[0] + '
' + for (let i = 0; i < params.length; i++) { + str = str + params[i].marker + params[i].seriesName + ':' + params[i].value[1] + '
' + } + + return str + } + }, + grid: { + top: 30 + }, + legend: { + show: false + }, + yAxis: { + name: form.type == 1 ? '%' : 'A', + min: min, + max: max + }, + toolbox: { + show: false + }, + + options: { + series: series + } + } + + tabList.value[activeName.value].showDynamic = true + }) + .catch(() => { + loading1.value = false + }) + loading1.value = false +} +// 监听echart点击 +const group = (chart: any, myChartDom: any) => { + myChartDom.addEventListener('click', function (event: any) { + // 获取点击位置相对于图表容器的坐标 + const rect = myChartDom.getBoundingClientRect() + const x = event.clientX - rect.left + const y = event.clientY - rect.top + const pointInPixel = [x, y] + // 转换为逻辑坐标(相对于图表坐标系) + const pointInGrid = chart.convertFromPixel({ gridIndex: 0 }, pointInPixel) + // 计算X轴和Y轴的对应数据 + + // 处理X轴数据(分类轴) + + // 处理Y轴数据(数值轴) + let yValue = pointInGrid[1].toFixed(4) + // xValue = timeFormat(pointInGrid[0].toFixed(0) - 0) + if (code.value == 0) { + tabList.value[activeName.value].form.limit = yValue + tabList.value[activeName.value].options.series[0].markLine.data[0].yAxis = yValue + chart.setOption(tabList.value[activeName.value].options) + } else if (code.value == 1) { + tabList.value[activeName.value].form.time1 = xValue.value + tabList.value[activeName.value].options.series[0].markLine.data[1].xAxis = xValue.value + chart.setOption(tabList.value[activeName.value].options) + } else if (code.value == 2) { + tabList.value[activeName.value].form.time2 = xValue.value + tabList.value[activeName.value].options.series[0].markLine.data[2].xAxis = xValue.value + chart.setOption(tabList.value[activeName.value].options) + } + // 控制台输出详细信息 + // console.log('点击事件详情:', { + // X轴数据: xValue, + // Y轴数据: yValue + // }) + }) } onMounted(() => { @@ -229,4 +598,32 @@ onMounted(() => { width: 300px; } } +.monitoring-point { + font-size: 14px; + font-weight: 700; + color: var(--el-color-primary); +} +.box { + // height: 280px; + height: calc((100vh - 370px) / 2); +} +.boxTab { + display: flex; +} +.harmonicButton { + height: 42px; + display: flex; + justify-content: end; + align-items: center; +} +:deep(.el-tabs__content) { + height: calc(100vh - 265px); +} +:deep(.el-input-group__append, .el-input-group__prepend) { + background-color: #ffffff00; +} +:deep(.frontBox) { + background-color: var(--el-color-primary) !important; + color: #fff !important; +} diff --git a/src/views/pqs/harmonicMonitoring/detailed/division/components/detail.vue b/src/views/pqs/harmonicMonitoring/detailed/division/components/detail.vue index dcb47993..2a35edea 100644 --- a/src/views/pqs/harmonicMonitoring/detailed/division/components/detail.vue +++ b/src/views/pqs/harmonicMonitoring/detailed/division/components/detail.vue @@ -1,53 +1,173 @@ - - - - + + + + diff --git a/src/views/pqs/harmonicMonitoring/detailed/division/index.vue b/src/views/pqs/harmonicMonitoring/detailed/division/index.vue index 0c01768a..7e46302d 100644 --- a/src/views/pqs/harmonicMonitoring/detailed/division/index.vue +++ b/src/views/pqs/harmonicMonitoring/detailed/division/index.vue @@ -63,8 +63,6 @@ const tableStore = new TableStore({ click: row => { console.log("🚀 ~ row:", row) - - // push('/admin/division/detail') push({ path: "/admin/division/detail", query: {