From 011aab07af85ba820b9f96a02c249b7ba26c8d26 Mon Sep 17 00:00:00 2001 From: he wei <858544502@qq.com> Date: 星期四, 26 六月 2025 09:02:06 +0800 Subject: [PATCH] U 整理提交 --- src/api/realtime.js | 38 src/components/echarts/BaseChart.vue | 21 src/components/echarts/line1.vue | 1 src/components/echarts/line-yj.vue | 173 +++ src/components/echarts/line2.vue | 12 package-lock.json | 11 src/views/alarm/earlyWarningAnalysis.vue | 1605 ++++++++++++++++++++++++++++++----- package.json | 1 src/api/alarm.js | 23 src/views/statistics/battCompare0_.vue | 546 ++++++++++++ src/components/echarts/line-scroll.vue | 57 src/views/realtime/tabs/system.vue | 190 ++- 12 files changed, 2,306 insertions(+), 372 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9be3195..6c04c4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "path-browserify": "^1.0.1", "pinia": "^2.1.7", "pinyin-match": "^1.2.8", + "tree-transfer-vue3": "^1.2.2", "vue": "^3.5.13", "vue-router": "^4.3.3", "xlsx": "^0.18.5" @@ -5847,6 +5848,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tree-transfer-vue3": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/tree-transfer-vue3/-/tree-transfer-vue3-1.2.2.tgz", + "integrity": "sha512-+jBDjXeHSay9PcKJqVwluHWaM6dlnLDtJGhsZ9bp7FKTYA7hNV13/amDjlsHY8OO675/ysrvBm1wJBtNvfKQVQ==", + "license": "ISC", + "dependencies": { + "element-plus": "^2.8.7", + "vue": "^3.5.12" + } + }, "node_modules/tslib": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", diff --git a/package.json b/package.json index 6874f79..8f8fa0f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "path-browserify": "^1.0.1", "pinia": "^2.1.7", "pinyin-match": "^1.2.8", + "tree-transfer-vue3": "^1.2.2", "vue": "^3.5.13", "vue-router": "^4.3.3", "xlsx": "^0.18.5" diff --git a/src/api/alarm.js b/src/api/alarm.js index 30cf4c5..c62c991 100644 --- a/src/api/alarm.js +++ b/src/api/alarm.js @@ -207,3 +207,26 @@ params }); } + +/** + * 棰勮鍒嗘瀽绠$悊-鏌ヨ鏃堕棿闂撮殧 + */ +export function getAlarmAnalysisCycle() { + return request({ + url: "analysis/getAlarmAnalysisCycle", + method: "GET" + }); +} + +/** + * 棰勮鍒嗘瀽绠$悊-璁剧疆鏃堕棿闂撮殧 + */ +export function updateAlarmAnalysisCycle(intervalTime) { + return request({ + url: "analysis/updateAlarmAnalysisCycle", + method: "GET", + params: { + intervalTime + } + }); +} \ No newline at end of file diff --git a/src/api/realtime.js b/src/api/realtime.js index a6db238..cbb8e60 100644 --- a/src/api/realtime.js +++ b/src/api/realtime.js @@ -1,40 +1,37 @@ import request from '@/utils/request'; /** - * 绯荤粺姒傝鑾峰彇鍗婂皬鏃舵牳瀹硅澶囦俊鎭� + * 绯荤粺姒傝鑾峰彇鏍稿璁惧淇℃伅 鍓�100绗� * battgroupId - * granularity */ -export function getHalfHourBattDevData(battgroupId, granularity) { +export function getBattDevData100(battgroupId, powerId) { return request({ - url: 'real/getHalfHourBattDevData', + url: 'real/getBattDevData100', method: 'GET', - params: { battgroupId, granularity } + params: { battgroupId, powerId } }); } /** - * 绯荤粺姒傝鑾峰彇鍗婂皬鏃朵氦娴佽緭鍏ョ粺璁� + * 绯荤粺姒傝鑾峰彇浜ゆ祦杈撳叆缁熻 鍓�100绗� * powerId - * granularity */ -export function getHalfHourPwrHisAcinData(powerId, granularity) { +export function getPwrHisAcinData100(powerId) { return request({ - url: 'real/getHalfHourPwrHisAcinData', + url: 'real/getPwrHisAcinData100', method: 'GET', - params: { powerId, granularity } + params: { powerId } }); } -/** 绯荤粺姒傝鑾峰彇鍗婂皬鏃剁洿娴佽緭鍑虹粺璁� +/** 绯荤粺姒傝鑾峰彇鐩存祦杈撳嚭缁熻 鍓�100绗� * powerId - * granularity */ -export function getHalfHourPwrHisDcoutData(powerId, granularity) { +export function getPwrHisDcoutData100(powerId) { return request({ - url: 'real/getHalfHourPwrHisDcoutData', + url: 'real/getPwrHisDcoutData100', method: 'GET', - params: { powerId, granularity } + params: { powerId } }); } @@ -69,4 +66,15 @@ method: 'GET', params: { battgroupId } }); +} + +/** + * 鐢垫簮蹇冭烦鍙傛暟 + */ +export function getPwrHeartParam(powerId) { + return request({ + url: 'pwrHeart/getPwrHeartParam', + method: 'GET', + params: { powerId } + }); } \ No newline at end of file diff --git a/src/components/echarts/BaseChart.vue b/src/components/echarts/BaseChart.vue index 07a9919..aa07836 100644 --- a/src/components/echarts/BaseChart.vue +++ b/src/components/echarts/BaseChart.vue @@ -21,6 +21,13 @@ const fullScreenFlag = ref(props.fullFlag); +function busHandler() { + setTimeout(() => { + resize(); + // 鍥犱负杩囨浮璁剧疆浜�0.5s,鎵�浠ラ渶瑕佺瓑寰�0.5s鍚庡啀resize + }, 580); +} + onMounted(() => { console.log('base mounted',chart.value, '============='); @@ -34,20 +41,13 @@ }); window.addEventListener("resize", resize); - eventBus.on("toggleSiteList", () => { - console.log('toggleSiteList', '============='); - setTimeout(() => { - resize(); - // 鍥犱负杩囨浮璁剧疆浜�0.5s,鎵�浠ラ渶瑕佺瓑寰�0.5s鍚庡啀resize - }, 500); - - }); + eventBus.on("toggleSiteList", busHandler); }); onBeforeUnmount(() => { window.removeEventListener("resize", resize); - eventBus.off("toggleSiteList"); + eventBus.off("toggleSiteList", busHandler); dispose(); }); @@ -97,6 +97,8 @@ } function resize() { + console.log('resize', chart_instance, '============='); + if (chart_instance) { chart_instance.resize(); } @@ -149,6 +151,7 @@ /* chart wrapper css */ .e-chart-root, .e-chart { + width: 100%; height: 100%; box-sizing: border-box; } diff --git a/src/components/echarts/line-scroll.vue b/src/components/echarts/line-scroll.vue index 054c8d3..7ddcfe5 100644 --- a/src/components/echarts/line-scroll.vue +++ b/src/components/echarts/line-scroll.vue @@ -80,8 +80,9 @@ function makeGrid(top, opt) { let res = echarts.util.merge({ top: top + '%', - height: gridHeight + '%', - left: 60, + height: gridHeight - 0.5 + '%', + bottom: top + gridHeight - 0.5 + '%', + left: 90, right: 14, }, opt || {}, true); return JSON.parse(JSON.stringify(res)); @@ -98,18 +99,26 @@ smooth: true, symbol: 'circle', symbolSize: 5, - showSymbol: false, + showSymbol: true, xAxisIndex: idx, yAxisIndex: idx, gridIndex: idx, + seriesIndex: idx, + // 绂佺敤鍔ㄧ敾锛岀‘淇濈珛鍗虫覆鏌� + animation: false, + // silent: true, lineStyle: { width: 1 }, - data: datas[idx], + tooltip: { + show: true, + }, + data: datas[idx].map(v => v + 3), }); }); - return JSON.parse(JSON.stringify(res)); + // return JSON.parse(JSON.stringify(res)); + return res; } let lastXLabels = []; @@ -121,8 +130,8 @@ nextTick(() => { chart.value.setOption(getOptions(lastXLabels, lastDatas)); }); - } - ) + }, + ); function getOptions(xLabels, datas) { @@ -152,23 +161,29 @@ color: '#fff' } }, - } : { show: false }; + } : { axisLine: { show: false }}; xAxis.push(makeXAxis(i, xAxisOption)); yAxis.push(makeYAxis(i, { - name: props.yLabels.length ? props.yLabels[i].replace(/(#)/g, '$1\n').replace(/\n$/, '') : '', - })); + name: props.yLabels.length ? props.yLabels[i] : '', + })); } const option = { + animation: false, color: ['#1186ce', '#e5c619', '#1d1dfd', '#2dbfae'], tooltip: { trigger: 'axis', + // 寮哄埗鏄剧ず鎵�鏈夌郴鍒� + alwaysShowContent: true, axisPointer: { + snap: true, lineStyle: { color: '#fff' } }, formatter: function (params) { + // console.log('params:', params); + // console.log('鎹曡幏鐨剆eriesIndex:', params.map(p => p.seriesIndex)); if (params.length) { // params.unshift({ seriesName: 'time', value: params[0].name, color: '#5193f2' }) let _label = ''; @@ -187,7 +202,7 @@ }); res.push('<span style="color: #000">' + _label + '</span>'); res = res.join('<br>'); - // console.log('res', res, '============='); + // console.log('res', res, params, '=====tooltip========', series, datas, xLabels[xLabels.length - 1]); return res; } @@ -206,12 +221,15 @@ series }; - console.log('option', option, '============='); + // console.log('option', option, '=======dcout======'); return option; } let myChart = null; + const startIndex = computed(() => { + return Math.floor(props.startIdx); + }); function initChart() { if (chart.value) { @@ -227,18 +245,25 @@ let option = getOptions(xLabels, datas); // chart.value.setOption(option, {notMerge: true}); chart.value.setOption(option); + + // tooltip Bug 閲嶆柊娓叉煋浜嗕竴涓� 灏辨病闂浜� + if (props.startIdx == 0) { + nextTick(() => { + emit('scroll', 0.1); + }); + } } } function scrollToTop() { - if (props.startIdx > 0) { + if (startIndex.value > 0) { emit('scroll', -1); } } function scrollToBottom() { - if (props.startIdx < props.modeCount - 4) { + if (startIndex.value < props.modeCount - 4) { nextTick(() => { emit('scroll', 1); }); @@ -261,10 +286,10 @@ <base-chart ref="chart" v-model:fullFlag="fullFlag" :key="startIdx"> <template #tools v-if="modeCount > 4"> <div class="t-contain"> - <div :class="['btn', 'btn-top', {disabled: startIdx == 0}]" @click="scrollToTop"> + <div :class="['btn', 'btn-top', {disabled: startIndex <= 0}]" @click="scrollToTop"> <svg-icon icon-class="arrow-right" ></svg-icon> </div> - <div :class="['btn', 'btn-bottom', {disabled: startIdx == modeCount - 4}]" @click="scrollToBottom"> + <div :class="['btn', 'btn-bottom', {disabled: startIndex == modeCount - 4}]" @click="scrollToBottom"> <svg-icon icon-class="arrow-right" ></svg-icon> </div> </div> diff --git a/src/components/echarts/line-yj.vue b/src/components/echarts/line-yj.vue new file mode 100644 index 0000000..7b0586e --- /dev/null +++ b/src/components/echarts/line-yj.vue @@ -0,0 +1,173 @@ +<script setup> + import { onMounted, ref, watchEffect, nextTick, onBeforeUnmount } from "vue"; + import * as echarts from 'echarts'; + import baseChart from "./BaseChart.vue"; + + import { toFixed } from '@/utils/toFixed.js'; + + const chart = ref(null); + const props = defineProps({ + title: { + type: String, + default: '' + }, + unit: { + type: String, + default: '' + } + }); + + function getMax(data) { + let max = Math.max.apply(null, data) * 1.2; + return toFixed(max, 1) || 1; + } + + + function getOptions(xLabels, datas, mark) { + xLabels = xLabels || []; + datas = datas || []; + mark = mark || ''; + const option = { + animation: false, + // title: { + // text: props.title, + // textStyle: { + // fontWeight: 'normal', + // fontSize: 14, + // color: '#fff' + // }, + // left: '6%' + // }, + tooltip: { + trigger: 'axis', + axisPointer: { + lineStyle: { + color: '#fff' + } + } + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + top: 30, + containLabel: true + }, + xAxis: [{ + type: 'category', + // boundaryGap: false, + axisLine: { + lineStyle: { + color: '#fff' + } + }, + data: xLabels + }], + yAxis: [{ + type: 'value', + name: props.unit, + axisTick: { + show: true, + }, + axisLine: { + show: true, + lineStyle: { + color: '#fff' + } + }, + axisLabel: { + margin: 10, + fontSize: 12, + color: '#fff' + }, + splitLine: { + lineStyle: { + color: 'rgba(255,255,255,0.2)' + } + }, + max: getMax(datas), + }], + series: [{ + // name: props.type, + type: 'line', + smooth: true, + symbol: 'circle', + symbolSize: 5, + showSymbol: false, + lineStyle: { + width: 1 + }, + // 娣诲姞鏍囪绾� + markLine: { + data: [ + { + name: '鍛婅鍒嗙晫绾�', + xAxis: mark, + lineStyle: { + color: 'red', + type: 'dashed' + }, + label: { + position: 'end', + formatter: '鍛婅鍒嗙晫绾�', + color: 'red' + }, + animation: false, + } + ] + }, + data: datas + }] + }; + + return option; + } + + let myChart = null; + let chart_instance = null; + + function initChart() { + if (chart.value) { + // myChart = chart.value.getChart(); + + let option = getOptions(); + chart.value.setOption(option); + chart_instance = chart.value.getChart(); + } + } + + function updateChart(xLabels, datas, mark) { + if (chart.value) { + let option = getOptions(xLabels, datas, mark); + chart.value.setOption(option); + } + } + + function getChart() { + return chart_instance; + } + + defineExpose({ + getChart, + updateChart + }); + + onMounted(() => { + // console.log('line mounted', '============='); + + initChart(); + }); +</script> + +<template> + <div class="line-chart"> + <base-chart ref="chart"></base-chart> + </div> +</template> + +<style scoped> +.line-chart { + width: 100%; + height: 100%; +} +</style> diff --git a/src/components/echarts/line1.vue b/src/components/echarts/line1.vue index 4707598..62b1c47 100644 --- a/src/components/echarts/line1.vue +++ b/src/components/echarts/line1.vue @@ -51,6 +51,7 @@ return [series, xlabels]; } + function getOptions(labels, datas) { labels = labels || []; datas = datas || []; diff --git a/src/components/echarts/line2.vue b/src/components/echarts/line2.vue index 16d4045..49e046b 100644 --- a/src/components/echarts/line2.vue +++ b/src/components/echarts/line2.vue @@ -62,7 +62,8 @@ return echarts.util.merge({ top: top + '%', height: gridHeight + '%', - left: '15%', + // left: '15%', + left: 80, right: 14, }, opt || {}, true); } @@ -203,16 +204,17 @@ // }], yAxis: [ makeYAxis(0, { - name: typeList[0].replace(/(.{2})/g, '$1\n').replace(/\n$/, ''), + // name: typeList[0].replace(/(.{2})/g, '$1\n').replace(/\n$/, ''), + name: typeList[0], }), makeYAxis(1, { - name: typeList[1].replace(/(.{2})/g, '$1\n').replace(/\n$/, ''), + name: typeList[1], }), makeYAxis(2, { - name: typeList[2].replace(/(.{2})/g, '$1\n').replace(/\n$/, ''), + name: typeList[2], }), makeYAxis(3, { - name: typeList[3].replace(/(.{2})/g, '$1\n').replace(/\n$/, ''), + name: typeList[3], }) ], series diff --git a/src/views/alarm/earlyWarningAnalysis.vue b/src/views/alarm/earlyWarningAnalysis.vue index 7618fd0..b1e2e6e 100644 --- a/src/views/alarm/earlyWarningAnalysis.vue +++ b/src/views/alarm/earlyWarningAnalysis.vue @@ -10,6 +10,9 @@ import getQueryString from "@/utils/getQueryString"; import alarmParams from '@/components/pwrAlarmParams.vue'; +import lineChart from '@/components/echarts/line-yj.vue'; +import treeTransfer from 'tree-transfer-vue3'; + import useStation from "@/hooks/useStationList.js"; const { provice, city, country, stationName, stationId, powerId, @@ -34,6 +37,9 @@ getBattAlmAnalyse, getHisRealInAlm, getAlmSummaryParam, + getHisRealWithChage, + getAlarmAnalysisCycle, + updateAlarmAnalysisCycle, } from "@/api/alarm.js"; import { @@ -43,6 +49,7 @@ const { $loading, $message, $confirm } = useElement(); const flag = ref(Math.random()); +const chart0 = ref(null); const headers0 = [ @@ -73,12 +80,84 @@ }, ]; +const headers1 = [ + { + prop: "fullName", + label: "鏈烘埧鍚嶇О", + width: "220", + }, + { + prop: "devName", + label: "璁惧鍚嶇О", + width: "80", + }, + { + prop: "almName", + label: "鍛婅鍚嶇О", + width: "160", + }, + { + prop: "almLevelStr", + label: "鍛婅绛夌骇", + width: "120", + }, + { + prop: "almStartTime", + label: "鍛婅寮�濮嬫椂闂�", + width: "120", + }, +]; + +const headers2 = [ + { + prop: "fullName", + label: "鏈烘埧鍚嶇О", + width: "220", + }, + { + prop: "battgroupName", + label: "鐢垫睜缁勫悕绉�", + width: "80", + }, + { + prop: "almName", + label: "鍛婅鍚嶇О", + width: "160", + }, + { + prop: "almLevelStr", + label: "鍛婅绛夌骇", + width: "120", + }, + { + prop: "almStartTime", + label: "鍛婅寮�濮嬫椂闂�", + width: "120", + }, +]; + const pageNum0 = ref(1); const pageSize0 = ref(10); const total0 = ref(0); -const addEditVisible = ref(false); +const timeVisible = ref(false); const dialogTitle = ref(""); const datas0 = reactive({ + tableData: [], + rowData: {}, +}); + +const pageNum1 = ref(1); +const pageSize1 = ref(10); +const total1 = ref(0); +const datas1 = reactive({ + tableData: [], + rowData: {}, +}); + +const pageNum2 = ref(1); +const pageSize2 = ref(10); +const total2 = ref(0); +const datas2 = reactive({ tableData: [], rowData: {}, }); @@ -88,6 +167,8 @@ const alarmTypeList = ref([]); const alarmId = ref(''); + + // 鐢垫簮鍛婅鍒楄〃 function getList0() { @@ -107,23 +188,118 @@ getPwrtAlmAnalyse(params).then((res) => { let { code, data, data2 } = res; let list = []; - // let _total0 = 0; + let _total0 = 0; loading.close(); if (code && data) { // console.log(data); list = data2.list.map(v => ({ ...v, almLevelStr: ['', '涓�绾у憡璀�', '浜岀骇鍛婅', '涓夌骇鍛婅', '鍥涚骇鍛婅'][v.almLevel], - + })); - // _total0 = data2.total0; + _total0 = data2.total; } datas0.tableData = list; - // total0.value = _total0; + total0.value = _total0; }) .catch((err) => { console.log(err); }); +} + +// 璁惧鍛婅鍒楄〃 +function getList1() { + let params = { + almIdList: alarmId.value ? [alarmId.value] : undefined, + provice: provice.value || undefined, + city: city.value || undefined, + country: country.value || undefined, + stationId: stationId.value || undefined, + powerId: powerId.value || undefined, + almLevel: alarmLevel.value, + pageNum: pageNum1.value, + pageSize: pageSize1.value, + }; + + let loading = $loading(); + getDevAlmAnalyse(params).then((res) => { + let { code, data, data2 } = res; + let list = []; + let _total0 = 0; + loading.close(); + if (code && data) { + // console.log(data); + list = data2.list.map(v => ({ + ...v, + almLevelStr: ['', '涓�绾у憡璀�', '浜岀骇鍛婅', '涓夌骇鍛婅', '鍥涚骇鍛婅'][v.almLevel], + + })); + _total0 = data2.total; + } + datas1.tableData = list; + console.log('list', list, '============='); + + total1.value = _total0; + }) + .catch((err) => { + console.log(err); + }); +} + +// 鐢垫睜鍛婅鍒楄〃 +function getList2() { + let params = { + almIdList: alarmId.value ? [alarmId.value] : undefined, + provice: provice.value || undefined, + city: city.value || undefined, + country: country.value || undefined, + stationId: stationId.value || undefined, + powerId: powerId.value || undefined, + almLevel: alarmLevel.value, + pageNum: pageNum2.value, + pageSize: pageSize2.value, + }; + + let loading = $loading(); + getBattAlmAnalyse(params).then((res) => { + let { code, data, data2 } = res; + let list = []; + let _total0 = 0; + loading.close(); + if (code && data) { + // console.log(data); + list = data2.list.map(v => ({ + ...v, + almLevelStr: ['', '涓�绾у憡璀�', '浜岀骇鍛婅', '涓夌骇鍛婅', '鍥涚骇鍛婅'][v.almLevel], + + })); + _total0 = data2.total; + } + datas2.tableData = list; + console.log('list', list, '============='); + + total2.value = _total0; + }) + .catch((err) => { + console.log(err); + }); +} + + +async function acTabChange() { + await nextTick(); + + switch (acTab.value) { + case 'power': + getList0(); + break; + case 'dev': + getList1(); + break; + case 'batt': + getList2(); + break; + } } const allProps = ref([]); @@ -136,6 +312,7 @@ list = data2; } allProps.value = list; + formatProp(list); } // 鏌ヨ鍛婅绫诲瀷 @@ -157,19 +334,155 @@ } +const chartRefs = ref({}); + +function setComponentRef (prop, el) { + if (el) { + chartRefs.value[prop] = el; + } else { + // 缁勪欢鍗歌浇鏃剁Щ闄ゅ紩鐢� + delete chartRefs.value[prop]; + } +}; const alarmType = ref(0); const acTab = ref('power'); const alarmLevel = ref(1); +const currAlm = ref({}); +// 褰撳墠鍛婅鐨勫憡璀﹀紑濮嬫椂闂� +const startTime = ref(''); +const battList = ref([]); +const battId = ref(''); async function view(record) { + currAlm.value = record; + battList.value = record.binfList; + battId.value = acTab.value == 'batt' + ? record.battgroupId + : record.binfList.length + ? record.binfList[0].battgroupId + : 0; + + getRtData(); +} + +const propInfo = ref({}); +async function getRtData() { let params = { - powerId: record.powerId, - almId: record.almId, - startTime: record.almStartTime, - battgroupId: record.battgroupIdList.length ? record.battgroupIdList[0] : 0, + powerId: currAlm.value.powerId, + almId: currAlm.value.almId, + startTime: currAlm.value.almStartTime, + battgroupId: battId.value, } let res = await getHisRealInAlm(params); + let { code, data, data2, data3, data4 } = res; + let list = []; + let mainProps = '涓诲睘鎬ф洸绾�'; + let subs = []; + if (code && data) { + let { batt, pwr } = data2; + // 鍙栧嚭涓诲睘鎬� 鍜� 鍓睘鎬� 鍙婂搴旂殑涓枃鍚嶇О + mainProps = data2[data3.main][0].dataName1; + if (data3.main == 'pwr') { + // batt 涓暟琛ㄧず鍏ㄩ儴鐨勫壇灞炴�� + // pwr 瑕佸幓鎺夌涓�涓富灞炴�� 鍓╀笅鐨勪负鍓睘鎬� + for(let i = 0, len = data3.batt; i < len; i++) { + let idx = i + 1; + let prop = batt[0][`dataName${idx}`]; + subs.push({prop, name: getPropName(prop), data: [], xLabels: [], valueProp: `dataValue${idx}`, from: 'batt'}); + } + for (let j = 0, len = data3.pwr - 1; j < len; j++) { + let idx = j + 2; + let prop = pwr[0][`dataName${idx}`]; + subs.push({prop, name: getPropName(prop), data: [], xLabels: [], valueProp: `dataValue${idx}`, from: 'pwr'}); + } + } else { + for(let i = 0, len = data3.batt - 1; i < len; i++) { + let idx = i + 2; + let prop = batt[0][`dataName${idx}`]; + subs.push({prop, name: getPropName(prop), data: [], xLabels: [], valueProp: `dataValue${idx}`, from: 'batt'}); + } + for (let j = 0, len = data3.pwr; j < len; j++) { + let idx = j + 1; + let prop = pwr[0][`dataName${idx}`]; + subs.push({prop, name: getPropName(prop), data: [], xLabels: [], valueProp: `dataValue${idx}`, from: 'pwr'}); + } + } + + // 鏍煎紡鍖栨暟鎹� + formatData(data2, data3, subs); + propInfo.value = data4; + + } + + subProp.value = subs; + + + startTime.value = currAlm.value.almStartTime; + name0.value = getPropName(mainProps); + + nextTick(() => { + // 鏇存柊鍥捐〃 + updateChart(); + }); + +} + + +function findClosestTime(timeArray, targetTime, format = 'YYYY-MM-DD HH:mm:ss') { + if (!timeArray || timeArray.length === 0) return ''; + + // 灏嗙洰鏍囨椂闂磋浆鎹负Moment瀵硅薄 + const targetMoment = moment(targetTime, format); + + + // 鎵惧嚭鎵�鏈夊ぇ浜庢垨绛変簬鐩爣鏃堕棿鐨勫厓绱� + const timesAfterTarget = timeArray.filter(time => + moment(time, format).isSameOrAfter(targetMoment) + ); + + // 濡傛灉瀛樺湪杩欐牱鐨勫厓绱狅紝杩斿洖绗竴涓� + if (timesAfterTarget.length > 0) { + return timesAfterTarget[0]; + } + + // 鑻ユ病鏈夋壘鍒板ぇ浜庢垨绛変簬鐩爣鏃堕棿鐨勫厓绱狅紝鍒欒繑鍥炴暣涓暟缁勪腑鐨勬渶鍚庝竴涓厓绱狅紙鍗虫渶鎺ヨ繎浣嗗皬浜庣洰鏍囨椂闂寸殑鍏冪礌锛� + return timeArray[timeArray.length - 1]; +} + +const mainData = ref([]); +// const xLabels0 = ref([]); +// const xLabels1 = ref([]); + +function formatData(data2, data3, subs) { + let _mainData = []; + let recordTimes = []; + for (let i = 0, len = data2[data3.main].length; i < len; i++) { + let item = data2[data3.main][i]; + let recordTime = item.recordTime; + _mainData.push(item.dataValue1); + recordTimes.push(recordTime); + + for (let j = 0, len = subs.length; j < len; j++) { + let sub = subs[j]; + // 鍙栧睘鎬у搴旂殑index + let { prop, from, valueProp } = sub; + + sub.data.push(data2[from][i][valueProp]); + sub.xLabels.push(data2[from][i].recordTime); + } + } + mainData.value = {labels: recordTimes, data: _mainData}; + // xlabels.value = recordTimes; +} + +function updateChart() { + console.log('xlabels.value, mainData.value', mainData.value, '============='); + + chart0.value.updateChart(mainData.value.labels, mainData.value.data, findClosestTime(mainData.value.labels, startTime.value)); + subProp.value.forEach((v, i) => { + chartRefs.value[v.prop].updateChart(v.xLabels, v.data, findClosestTime(v.xLabels, startTime.value)); + }); } @@ -197,6 +510,28 @@ function handleCurrentChange0(val) { pageNum0.value = val; getList0(); +} + +// 灞曠ず鏁版嵁鏁伴噺 +function handleSizeChange1(val) { + pageSize1.value = val; + getList1(); +} +// 缈婚〉 +function handleCurrentChange1(val) { + pageNum1.value = val; + getList1(); +} + +// 灞曠ず鏁版嵁鏁伴噺 +function handleSizeChange2(val) { + pageSize2.value = val; + getList2(); +} +// 缈婚〉 +function handleCurrentChange2(val) { + pageNum2.value = val; + getList2(); } async function exportExcelAll() { @@ -231,26 +566,240 @@ return name; } +// 鑾峰彇绫诲瀷鍚嶇О +function getTypeName(type) { + let name = ''; + let obj = allTypes.value.filter(v => v.id == type); + if (obj.length) { + name = obj[0].label; + } + return name; +} + const name0 = ref('涓诲睘鎬ф洸绾�'); + const subProp = ref([]); +const timeLong = ref(0); +async function getTimeSettings() { + let res = await getAlarmAnalysisCycle(); + let { code, data, data2 } = res; + let _time = 30; + if (code && data) { + _time = data2.paramValue; + } + timeLong.value = _time; +} -subProp.value = [1]; -// subProp.value = [1, 2]; -// subProp.value = [1, 2, 3]; -// subProp.value = [1, 2, 3, 4]; +const layout = { + gutter: 20, + span: 24, +}; -let obj = [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]; -let i = 0; +const form1 = reactive({ + time: 0, +}); + +const validatorTime = (rule, value, callback) => { + const reg = /^\d+$/; + + if (reg.test(value)) { + if (value < 1 || value > 1440) { + callback(new Error('鑼冨洿1~1440')); + } else { + callback(); + } + } else { + callback(new Error('璇疯緭鍏ユ暣鏁�')); + } + } + +const rules = reactive({ + time: [{ required: true, message: "涓嶈兘涓虹┖", trigger: ["blur", "change"] }, + { validator: validatorTime, trigger: ["blur", "change"] }, + ], +}); + + +function setTime() { + form1.time = timeLong.value; + dialogTitle.value = '璁剧疆鏃堕棿鍛ㄦ湡'; + timeVisible.value = true; +} + + +const formRef = ref(); +async function timeSetOk() { + let valid = await formRef.value.validate(() => { }); + // console.log('valid', valid, '============='); + if (!valid) { + $message.error("琛ㄥ崟楠岃瘉澶辫触"); + return false; + } + + let loading = $loading(); + let res = await updateAlarmAnalysisCycle(form1.time); + let { code, data } = res; + loading.close(); + if (code && data) { + $message.success("璁剧疆鎴愬姛"); + timeLong.value = form1.time; + timeVisible.value = false; + } else { + $message.error("璁剧疆澶辫触"); + } +} + +const transferRef = ref(); +const fromData = ref([]); +const propVisible = ref(false); +const toData = ref([]); + +function setProp () { + dialogTitle.value = '璁剧疆鍏虫敞灞炴��'; + propVisible.value = true; + nextTick(() => { + initSubProp(propInfo.value); + }); +} + +function initSubProp (data) { + let { + almId, + minorField1, + minorField1Type, + minorField2, + minorField2Type, + minorField3, + minorField3Type, + minorField4, + minorField4Type, + } = data; + let arr = []; + let obj = {}; + [1, 2, 3, 4].forEach((v) => { + let prop = `minorField${v}`; + let type = `${prop}Type`; + if (data[prop]) { + obj[data[type]] = obj[data[type]] || []; + obj[data[type]].push({ + pid: data[type] + '', + id: data[prop], + label: getPropName(data[prop]), + prop: data[prop], + type: data[type], + }); + // arr.push({ + // pid: data[type] + '', + // id: data[prop], + // label: getPropName(data[prop]), + // prop: data[prop], + // type: data[type], + // }); + } + }); + + Object.keys(obj).forEach((key) => { + arr.push({ + pid: 0, + id: key, + label: getTypeName(key), + children: obj[key], + }); + }); + + transferRef.value.removeToSource(false); + transferRef.value.addToAims(false); + toData.value = arr; +} + +function propSetOk() { + +} + +async function add (_fromData,_toData,{ checkedKeys, checkedNodes, harfKeys, harfNodes }) { + console.log('fromData,toData,obj', _fromData,_toData, checkedKeys, checkedNodes, harfKeys, harfNodes , '============='); + let params = { + battgroupId: battId.value, + powerId: currAlm.value.powerId, + startTime: currAlm.value.almStartTime, + } + let arr = []; + _toData.forEach((v) => { + arr.push(...v.children); + }); + let len = arr.length; + + if (len > 4) { + $message.error('鏈�澶氳缃�4涓睘鎬�'); + console.log('toData', _toData, toData, '============='); + toData.value = toData.value.map(v => ({ + ...v, + children: v.children.filter(vv => !checkedKeys.includes(vv.id)) + })); + return false; + } + let i = 0; + _toData.forEach((item) => { + item.children.forEach((v) => { + i++; + params[`dataName${i}`] = v.id; + params[`dataType${i}`] = v.pid; + + }); + }); + console.log('params', params, '============='); + + let res = await getHisRealWithChage(params); + + +} + +function remove(fromData,toData,obj) { + console.log('fromData,toData,obj', fromData,toData,obj, '============='); + +} + +const allTypes = ref([]); + +function formatProp(data) { + let obj = {}; + let res = []; + let types = []; + data.forEach((v) => { + obj[v.fieldType] = obj[v.fieldType] || []; + obj[v.fieldType].push(v); + + }); + Object.keys(obj).forEach((key) => { + types.push({ + id: key, + label: obj[key][0].fieldTypeName + }); + res.push({ + id: key, + pid: 0, + label: obj[key][0].fieldTypeName, + children: obj[key].map(vv => { + return { + ...vv, + id: vv.fieldName, + label: vv.fieldNameZh, + pid: key, + } + }) + }) + }); + fromData.value = res; + allTypes.value = types; + return res; +} + onMounted(async () => { await getAlarmType(); getAllProps(); + getTimeSettings(); getList0(); - setInterval(() => { - i++; - i%=4; - subProp.value.length = obj[i]; - }, 5000); }); // onActivated(async () => { @@ -258,10 +807,10 @@ // // console.log('pageFlag', pageFlag, flag.value, '============='); // await nextTick(); // await whenLoaded(); - + // if (pageFlag && pageFlag != flag.value) { // // let provice, city, country, stationName, battId; - + // if (getQueryString('stationId')) { // let statId = getQueryString('stationId'); // let stat = stationList.value.find(v => v.stationId == statId); @@ -286,267 +835,736 @@ <!-- <div class="page-header"> </div> --> <div class="page-content"> - <el-tabs tab-position="left" v-model="acTab" type="card" class="main-tabs"> + <el-tabs + tab-position="left" + v-model="acTab" + @tab-change="acTabChange" + type="card" + class="main-tabs" + > <el-tab-pane name="power" class="tab-pane" label="鐢垫簮鍛婅"> <div class="page-content-wrapper"> - <div class="page-content-tools page-filter"> - <div class="grid-container" :style="{'--counter': 9}"> - <div class="grid-item"> - <div class="label">鐪�</div> - <div class="value"> - <el-select - v-model="provice" - size="small" - clearable - placeholder="璇烽�夋嫨鐪�" - > - <el-option - v-for="item in proviceList" - :key="'l0_' + item" - :label="item" - :value="item" + <div class="page-content-tools page-filter"> + <div class="grid-container" :style="{'--counter': 9}"> + <div class="grid-item"> + <div class="label">鐪�</div> + <div class="value"> + <el-select + v-model="provice" + size="small" + clearable + placeholder="璇烽�夋嫨鐪�" > - </el-option> - </el-select> - </div> - </div> - <div class="grid-item"> - <div class="label">甯�</div> - <div class="value"> - <el-select - v-model="city" - size="small" - clearable - placeholder="璇烽�夋嫨甯�" - > - <el-option - v-for="item in cityList" - :key="'l1_' + item" - :label="item" - :value="item" - > - </el-option> - </el-select> - </div> - </div> - <div class="grid-item"> - <div class="label">鍖哄幙</div> - <div class="value"> - <el-select - v-model="country" - clearable - size="small" - placeholder="璇烽�夋嫨鍖哄幙" - > - <el-option - v-for="item in countryList" - :key="'l2_' + item" - :label="item" - :value="item" - > - </el-option> - </el-select> - </div> - </div> - <div class="grid-item"> - <div class="label">绔欑偣</div> - <div class="value"> - <el-select - v-model="stationName" - clearable - size="small" - placeholder="璇烽�夋嫨绔欑偣" - > - <el-option - v-for="item in stationList" - :key="'l3_' + item.stationId" - :label="item.stationName" - :value="item.stationName" - > - </el-option> - </el-select> - </div> - </div> - <div class="grid-item"> - <div class="label">鐢垫簮鍚嶇О</div> - <div class="value"> - <el-select - v-model="powerId" - clearable - size="small" - placeholder="璇烽�夋嫨鐢垫簮" - > - <el-option - v-for="item in powerList" - :key="'l4_' + item.powerId" - :label="`${item.stationName}-${item.powerName}`" - :value="item.powerId" - > - </el-option> - </el-select> - </div> - </div> - <div class="grid-item"> - <div class="label">鍛婅鍚嶇О</div> - <div class="value"> - <el-select - v-model="alarmId" - size="small" - clearable - filterable - placeholder="璇烽�夋嫨鍛婅鍚嶇О" - > - <el-option - v-for="item in alarmTypeList" - :key="item.value" - :label="item.label" - :value="item.value" - > - </el-option> - </el-select> - </div> - </div> - <div class="grid-item"> - <!-- <div class="label">涓�绾у憡璀�</div> - <div class="label">浜岀骇鍛婅</div> - <div class="label">涓夌骇鍛婅</div> - <div class="label">鍥涚骇鍛婅</div> --> - <el-radio-group v-model="alarmLevel" size="small" style="grid-column: span 6;"> - <el-radio-button :label="1">涓�绾у憡璀�</el-radio-button> - <el-radio-button :label="2">浜岀骇鍛婅</el-radio-button> - <el-radio-button :label="3">涓夌骇鍛婅</el-radio-button> - <el-radio-button :label="4">鍥涚骇鍛婅</el-radio-button> - </el-radio-group> - </div> - </div> - </div> - <div class="page-content-table"> - <div class="pos-rel"> - <div class="pos-abs"> - <el-table - class="yc-table" - stripe - height="100%" - size="small" - :data="datas0.tableData" - style="width: 100%" - > - <el-table-column - type="index" - fixed="left" - label="搴忓彿" - width="60" - ></el-table-column> - <el-table-column - v-for="header in headers0" - :key="header.prop" - :prop="header.prop" - :label="header.label" - :min-width="header.width" - align="center" - > - <template #default="scope"> - <template v-if="header.prop == 'almIsConfirmed'"> - <el-checkbox - disabled - :checked="scope.row[header.prop] == 1" - ></el-checkbox> - </template> - <template v-else> - {{ scope.row[header.prop] || '--' }} - </template> - </template> - </el-table-column> - <el-table-column - label="鎿嶄綔" - fixed="right" - width="120" - align="center" - > - <template #default="scope"> - <el-button - type="warning" - size="small" - @click="view(scope.row)" - >鏌ョ湅璇︽儏</el-button + <el-option + v-for="item in proviceList" + :key="'l0_' + item" + :label="item" + :value="item" > - </template> - </el-table-column> - </el-table> + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">甯�</div> + <div class="value"> + <el-select + v-model="city" + size="small" + clearable + placeholder="璇烽�夋嫨甯�" + > + <el-option + v-for="item in cityList" + :key="'l1_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍖哄幙</div> + <div class="value"> + <el-select + v-model="country" + clearable + size="small" + placeholder="璇烽�夋嫨鍖哄幙" + > + <el-option + v-for="item in countryList" + :key="'l2_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">绔欑偣</div> + <div class="value"> + <el-select + v-model="stationName" + clearable + size="small" + placeholder="璇烽�夋嫨绔欑偣" + > + <el-option + v-for="item in stationList" + :key="'l3_' + item.stationId" + :label="item.stationName" + :value="item.stationName" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鐢垫簮鍚嶇О</div> + <div class="value"> + <el-select + v-model="powerId" + clearable + size="small" + placeholder="璇烽�夋嫨鐢垫簮" + > + <el-option + v-for="item in powerList" + :key="'l4_' + item.powerId" + :label="`${item.stationName}-${item.powerName}`" + :value="item.powerId" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍛婅鍚嶇О</div> + <div class="value"> + <el-select + v-model="alarmId" + size="small" + clearable + filterable + placeholder="璇烽�夋嫨鍛婅鍚嶇О" + > + <el-option + v-for="item in alarmTypeList" + :key="item.value" + :label="item.label" + :value="item.value" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <el-radio-group + v-model="alarmLevel" + size="small" + style="grid-column: span 6;" + > + <el-radio-button :value="1">涓�绾у憡璀�</el-radio-button> + <el-radio-button :value="2">浜岀骇鍛婅</el-radio-button> + <el-radio-button :value="3">涓夌骇鍛婅</el-radio-button> + <el-radio-button :value="4">鍥涚骇鍛婅</el-radio-button> + </el-radio-group> + </div> </div> </div> - </div> - <div class="page-content-page"> - <div class="page-tool"> - <el-button - type="primary" - round - size="small" - @click="getList0" - :icon="Search" - >鏌ヨ</el-button - > + <div class="page-content-table"> + <div class="pos-rel"> + <div class="pos-abs"> + <el-table + class="yc-table" + stripe + height="100%" + size="small" + :data="datas0.tableData" + style="width: 100%" + > + <el-table-column + type="index" + fixed="left" + label="搴忓彿" + width="60" + ></el-table-column> + <el-table-column + v-for="header in headers0" + :key="header.prop" + :prop="header.prop" + :label="header.label" + :min-width="header.width" + align="center" + > + <template #default="scope"> + <template v-if="header.prop == 'almIsConfirmed'"> + <el-checkbox + disabled + :checked="scope.row[header.prop] == 1" + ></el-checkbox> + </template> + <template v-else> + {{ scope.row[header.prop] || '--' }} + </template> + </template> + </el-table-column> + <el-table-column + label="鎿嶄綔" + fixed="right" + width="120" + align="center" + > + <template #default="scope"> + <el-button + type="warning" + size="small" + @click="view(scope.row)" + >鏌ョ湅璇︽儏</el-button + > + </template> + </el-table-column> + </el-table> + </div> + </div> </div> - <div class="el-page-container"> - <el-pagination v-model:current-page="pageNum0" v-model:page-size="pageSize0" - :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" size="small" layout="total, sizes, prev, pager, next, jumper" :total="total0" - @size-change="handleSizeChange0" @current-change="handleCurrentChange0" /> - </div> - <div class="page-tool"> - <!-- <el-button type="primary" round size="small" @click="exportExcel" + <div class="page-content-page"> + <div class="page-tool"> + <el-button + type="primary" + round + size="small" + @click="getList0" + :icon="Search" + >鏌ヨ</el-button + > + </div> + <div class="el-page-container"> + <el-pagination + v-model:current-page="pageNum0" + v-model:page-size="pageSize0" + :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" + size="small" + layout="total, sizes, prev, pager, next, jumper" + :total="total0" + @size-change="handleSizeChange0" + @current-change="handleCurrentChange0" + /> + </div> + <div class="page-tool"> + <!-- <el-button type="primary" round size="small" @click="exportExcel" >瀵煎嚭</el-button > <el-button type="primary" round size="small" @click="exportExcelAll" >瀵煎嚭鍏ㄩ儴</el-button > --> + </div> </div> </div> - </div> </el-tab-pane> - <el-tab-pane name="dev" label="璁惧鍛婅">璁惧鍛婅</el-tab-pane> - <el-tab-pane name="batt" label="鐢垫睜鍛婅">鐢垫睜鍛婅</el-tab-pane> + <el-tab-pane name="dev" class="tab-pane" label="璁惧鍛婅"> + <div class="page-content-wrapper"> + <div class="page-content-tools page-filter"> + <div class="grid-container" :style="{'--counter': 9}"> + <div class="grid-item"> + <div class="label">鐪�</div> + <div class="value"> + <el-select + v-model="provice" + size="small" + clearable + placeholder="璇烽�夋嫨鐪�" + > + <el-option + v-for="item in proviceList" + :key="'l0_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">甯�</div> + <div class="value"> + <el-select + v-model="city" + size="small" + clearable + placeholder="璇烽�夋嫨甯�" + > + <el-option + v-for="item in cityList" + :key="'l1_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍖哄幙</div> + <div class="value"> + <el-select + v-model="country" + clearable + size="small" + placeholder="璇烽�夋嫨鍖哄幙" + > + <el-option + v-for="item in countryList" + :key="'l2_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">绔欑偣</div> + <div class="value"> + <el-select + v-model="stationName" + clearable + size="small" + placeholder="璇烽�夋嫨绔欑偣" + > + <el-option + v-for="item in stationList" + :key="'l3_' + item.stationId" + :label="item.stationName" + :value="item.stationName" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鐢垫簮鍚嶇О</div> + <div class="value"> + <el-select + v-model="powerId" + clearable + size="small" + placeholder="璇烽�夋嫨鐢垫簮" + > + <el-option + v-for="item in powerList" + :key="'l4_' + item.powerId" + :label="`${item.stationName}-${item.powerName}`" + :value="item.powerId" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍛婅鍚嶇О</div> + <div class="value"> + <el-select + v-model="alarmId" + size="small" + clearable + filterable + placeholder="璇烽�夋嫨鍛婅鍚嶇О" + > + <el-option + v-for="item in alarmTypeList" + :key="item.value" + :label="item.label" + :value="item.value" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <el-radio-group + v-model="alarmLevel" + size="small" + style="grid-column: span 6;" + > + <el-radio-button :value="1">涓�绾у憡璀�</el-radio-button> + <el-radio-button :value="2">浜岀骇鍛婅</el-radio-button> + <el-radio-button :value="3">涓夌骇鍛婅</el-radio-button> + <el-radio-button :value="4">鍥涚骇鍛婅</el-radio-button> + </el-radio-group> + </div> + </div> + </div> + <div class="page-content-table"> + <div class="pos-rel"> + <div class="pos-abs"> + <el-table + class="yc-table" + stripe + height="100%" + size="small" + :data="datas1.tableData" + style="width: 100%" + > + <el-table-column + type="index" + fixed="left" + label="搴忓彿" + width="60" + ></el-table-column> + <el-table-column + v-for="header in headers1" + :key="header.prop" + :prop="header.prop" + :label="header.label" + :min-width="header.width" + align="center" + > + <template #default="scope"> + <template v-if="header.prop == 'almIsConfirmed'"> + <el-checkbox + disabled + :checked="scope.row[header.prop] == 1" + ></el-checkbox> + </template> + <template v-else> + {{ scope.row[header.prop] || '--' }} + </template> + </template> + </el-table-column> + <el-table-column + label="鎿嶄綔" + fixed="right" + width="120" + align="center" + > + <template #default="scope"> + <el-button + type="warning" + size="small" + @click="view(scope.row)" + >鏌ョ湅璇︽儏</el-button + > + </template> + </el-table-column> + </el-table> + </div> + </div> + </div> + <div class="page-content-page"> + <div class="page-tool"> + <el-button + type="primary" + round + size="small" + @click="getList1" + :icon="Search" + >鏌ヨ</el-button + > + </div> + <div class="el-page-container"> + <el-pagination + v-model:current-page="pageNum1" + v-model:page-size="pageSize1" + :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" + size="small" + layout="total, sizes, prev, pager, next, jumper" + :total="total1" + @size-change="handleSizeChange1" + @current-change="handleCurrentChange1" + /> + </div> + <div class="page-tool"> + <!-- <el-button type="primary" round size="small" @click="exportExcel" + >瀵煎嚭</el-button + > + <el-button type="primary" round size="small" @click="exportExcelAll" + >瀵煎嚭鍏ㄩ儴</el-button + > --> + </div> + </div> + </div> + </el-tab-pane> + <el-tab-pane name="batt" class="tab-pane" label="鐢垫睜鍛婅"> + <div class="page-content-wrapper"> + <div class="page-content-tools page-filter"> + <div class="grid-container" :style="{'--counter': 9}"> + <div class="grid-item"> + <div class="label">鐪�</div> + <div class="value"> + <el-select + v-model="provice" + size="small" + clearable + placeholder="璇烽�夋嫨鐪�" + > + <el-option + v-for="item in proviceList" + :key="'l0_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">甯�</div> + <div class="value"> + <el-select + v-model="city" + size="small" + clearable + placeholder="璇烽�夋嫨甯�" + > + <el-option + v-for="item in cityList" + :key="'l1_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍖哄幙</div> + <div class="value"> + <el-select + v-model="country" + clearable + size="small" + placeholder="璇烽�夋嫨鍖哄幙" + > + <el-option + v-for="item in countryList" + :key="'l2_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">绔欑偣</div> + <div class="value"> + <el-select + v-model="stationName" + clearable + size="small" + placeholder="璇烽�夋嫨绔欑偣" + > + <el-option + v-for="item in stationList" + :key="'l3_' + item.stationId" + :label="item.stationName" + :value="item.stationName" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鐢垫簮鍚嶇О</div> + <div class="value"> + <el-select + v-model="powerId" + clearable + size="small" + placeholder="璇烽�夋嫨鐢垫簮" + > + <el-option + v-for="item in powerList" + :key="'l4_' + item.powerId" + :label="`${item.stationName}-${item.powerName}`" + :value="item.powerId" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍛婅鍚嶇О</div> + <div class="value"> + <el-select + v-model="alarmId" + size="small" + clearable + filterable + placeholder="璇烽�夋嫨鍛婅鍚嶇О" + > + <el-option + v-for="item in alarmTypeList" + :key="item.value" + :label="item.label" + :value="item.value" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <el-radio-group + v-model="alarmLevel" + size="small" + style="grid-column: span 6;" + > + <el-radio-button :value="1">涓�绾у憡璀�</el-radio-button> + <el-radio-button :value="2">浜岀骇鍛婅</el-radio-button> + <el-radio-button :value="3">涓夌骇鍛婅</el-radio-button> + <el-radio-button :value="4">鍥涚骇鍛婅</el-radio-button> + </el-radio-group> + </div> + </div> + </div> + <div class="page-content-table"> + <div class="pos-rel"> + <div class="pos-abs"> + <el-table + class="yc-table" + stripe + height="100%" + size="small" + :data="datas2.tableData" + style="width: 100%" + > + <el-table-column + type="index" + fixed="left" + label="搴忓彿" + width="60" + ></el-table-column> + <el-table-column + v-for="header in headers2" + :key="header.prop" + :prop="header.prop" + :label="header.label" + :min-width="header.width" + align="center" + > + <template #default="scope"> + <template v-if="header.prop == 'almIsConfirmed'"> + <el-checkbox + disabled + :checked="scope.row[header.prop] == 1" + ></el-checkbox> + </template> + <template v-else> + {{ scope.row[header.prop] || '--' }} + </template> + </template> + </el-table-column> + <el-table-column + label="鎿嶄綔" + fixed="right" + width="120" + align="center" + > + <template #default="scope"> + <el-button + type="warning" + size="small" + @click="view(scope.row)" + >鏌ョ湅璇︽儏</el-button + > + </template> + </el-table-column> + </el-table> + </div> + </div> + </div> + <div class="page-content-page"> + <div class="page-tool"> + <el-button + type="primary" + round + size="small" + @click="getList2" + :icon="Search" + >鏌ヨ</el-button + > + </div> + <div class="el-page-container"> + <el-pagination + v-model:current-page="pageNum2" + v-model:page-size="pageSize2" + :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" + size="small" + layout="total, sizes, prev, pager, next, jumper" + :total="total2" + @size-change="handleSizeChange2" + @current-change="handleCurrentChange2" + /> + </div> + <div class="page-tool"> + <!-- <el-button type="primary" round size="small" @click="exportExcel" + >瀵煎嚭</el-button + > + <el-button type="primary" round size="small" @click="exportExcelAll" + >瀵煎嚭鍏ㄩ儴</el-button + > --> + </div> + </div> + </div> + </el-tab-pane> </el-tabs> </div> <div class="page-footer"> <div class="left"> - <card :title="name0"></card> + <card :title="name0"> + <line-chart ref="chart0"></line-chart> + </card> </div> <div class="right"> <div class="btn-grp"> - <!-- <div class="item"> + <div class="item"> <div class="label">閫夋嫨鐢垫睜缁�</div> <div class="value"> <el-select v-model="battId" size="small" clearable + @change="getRtData" placeholder="璇烽�夋嫨鐢垫睜缁�" > <el-option v-for="item in battList" - :key="'l5_' + item.powerId" - :label="`${item.stationName}-${item.powerName}`" - :value="item.powerId" + :key="'l5_' + item.battgroupId" + :label="`${item.devName}-${item.battgroupName}`" + :value="item.battgroupId" > </el-option> </el-select> </div> </div> <div class="item"> - <div class="label">璁剧疆鏃堕棿鍛ㄦ湡</div> + <div class="label">璁剧疆鏃堕棿鍛ㄦ湡(鍒嗛挓)</div> <div class="value"> - {{ 132 }} + <div class="input">{{ timeLong }}</div> </div> + <el-button type="primary" size="small" @click="setTime" + >璁剧疆</el-button + > </div> <div class="item"> - <div class="label">鍏虫敞灞炴��</div> - </div> --> + <el-button type="primary" size="small" @click="setProp" + >鍏虫敞灞炴��</el-button + > + </div> </div> <!-- 涓�涓氨鍒嗕竴鍧� 涓や釜灏卞垎涓ゅ垪涓�琛� 涓や釜浠ヤ笂灏变袱鍒椾袱琛� --> - <div :class="['contain', { 'grid1': subProp.length == 1, 'grid2': subProp.length == 2, 'grid3': subProp.length > 2}]"> + <div + :class="['contain', { 'grid1': subProp.length == 1, 'grid2': subProp.length == 2, 'grid3': subProp.length > 2}]" + > <template v-for="(sub, idx) in subProp" :key="'sub_' + idx"> - <card :title="'娆″睘鎬�' + (idx + 1)"> - <line-chart :ref="() => chartRefs[idx]"></line-chart> + <card :title="sub.name"> + <line-chart + :ref="(el) => setComponentRef(sub.prop, el)" + ></line-chart> </card> </template> </div> @@ -555,21 +1573,60 @@ <!-- 寮圭獥 --> <el-dialog :title="dialogTitle" - v-model="addEditVisible" + v-model="timeVisible" top="0" draggable :close-on-click-modal="false" class="dialog-center" - width="860px" + width="460px" center > - <alarm-params - v-if="addEditVisible" - :type="alarmType" - :info="currentRow" - @change="getList" - v-model:visible="addEditVisible" - ></alarm-params> + <el-form ref="formRef" :model="form1" :rules="rules" label-width="10em"> + <el-row :gutter="layout.gutter"> + <el-col :span="layout.span"> + <el-form-item label="鏃堕棿鍛ㄦ湡(鍒嗛挓)" prop="time"> + <el-input v-model="form1.time"></el-input> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <span class="dialog-footer"> + <el-button @click="timeVisible = false">鍙� 娑�</el-button> + <el-button type="primary" @click="timeSetOk">纭� 瀹�</el-button> + </span> + </template> + </el-dialog> + <!-- 寮圭獥 --> + <el-dialog + :title="dialogTitle" + v-model="propVisible" + top="0" + draggable + :close-on-click-modal="false" + class="dialog-center transfer-dialog" + width="940px" + center + > + <tree-transfer + v-model:fromData="fromData" + :titleList="['鏈叧娉ㄥ睘鎬�', '宸插叧娉ㄥ睘鎬�']" + ref="transferRef" + :showBtnTxt="true" + :btnTitleList="['娣诲姞', '绉婚櫎']" + rootPid="0" + v-model:toData="toData" + :defaultProps="{label:'label', id: 'id', parentId: 'pid', children: 'children'}" + @add="add" + @remove="remove" + > + </tree-transfer> + <template #footer> + <span class="dialog-footer"> + <el-button @click="propVisible = false">鍙� 娑�</el-button> + <el-button type="primary" @click="propSetOk">纭� 瀹�</el-button> + </span> + </template> </el-dialog> </div> </template> @@ -710,6 +1767,54 @@ height: 100%; } } +.btn-grp { + .item { + font-size: 14px; + color: #439bc4; + margin-left: 12px; + display: flex; + align-items: center; + .label { + &::after { + content: ':'; + } + } + .value { + margin-left: 8px; + margin-right: 8px; + :deep(.el-select) { + width: 120px; + } + } + .input { + display: flex; + align-items: center; + padding-left: 6px; + color: #fff; + background: #439bc4; + border-radius: 4px; + min-width: 86px; + height: 28px; + } + } +} + +.item-setting { + display: flex; + align-items: center; + .label { + &::after { + content: ':'; + } + } + .value { + margin-left: 8px; + } +} +.dialog-footer { + display: flex; + justify-content: flex-end; +} .tools-filter { display: inline-block; @@ -728,4 +1833,10 @@ } } } +:deep(.transfer-dialog) { + .el-tree { + max-height: 500px; + overflow-y: auto; + } +} </style> diff --git a/src/views/realtime/tabs/system.vue b/src/views/realtime/tabs/system.vue index dcde4af..d75cb0e 100644 --- a/src/views/realtime/tabs/system.vue +++ b/src/views/realtime/tabs/system.vue @@ -18,15 +18,17 @@ import { - getHalfHourBattDevData, - getHalfHourPwrHisAcinData, - getHalfHourPwrHisDcoutData, + getBattDevData100, + getPwrHisAcinData100, + getPwrHisDcoutData100, + getPwrHeartParam, } from "@/api/realtime"; import { stopDis, restart, } from '@/api/control'; + const props = defineProps({ data: { @@ -137,6 +139,7 @@ if (!n) return; nextTick(() => { + getHeartParam(); // getAcinData(); // getDevData(); // getDcoutData(); @@ -182,6 +185,7 @@ const startIdx = ref(0); // 鍗婂皬鏃剁殑鏁版嵁鏉℃暟 1绉掍竴绗旇 +// 鏀逛负100绗� 鍙厤缃� 涓変釜灞炴�у彲浠ヨ缃笉鍚� const counter = 30 * 60; let xLabels1 = ref([]); @@ -296,7 +300,7 @@ } async function getAcinData() { - let { code, data, data2 } = await getHalfHourPwrHisAcinData(props.powerId, show_num.acin); + let { code, data, data2 } = await getPwrHisAcinData100(props.powerId); let list = []; if (code && data) { list = data2; @@ -305,7 +309,7 @@ } async function getDevData() { - let { code, data, data2 } = await getHalfHourBattDevData(props.battgroupId, show_num.dev); + let { code, data, data2 } = await getBattDevData100(props.battgroupId, props.powerId); let list = []; if (code && data) { list = data2; @@ -314,7 +318,7 @@ } async function getDcoutData() { - let { code, data, data2, data3 } = await getHalfHourPwrHisDcoutData(props.powerId, show_num.dcout); + let { code, data, data2, data3 } = await getPwrHisDcoutData100(props.powerId); let list = []; let cfg = []; if (code && data) { @@ -508,8 +512,8 @@ // let num = Math.ceil(counter / show_num['dev']); // TODO battRtstate 缂哄皯loadCurr let devObj = props.data.battRtstate; - xLabels1.value.shift(); - xLabels1.value.push(devObj.recordDatetime); + xLabels2.value.shift(); + xLabels2.value.push(devObj.recDatetime); chartData['dev'].shift(); chartData['dev'].push(devObj); updateChart2(); @@ -517,6 +521,46 @@ // 钃勭數姹犱俊鎭� battInfo.value = props.data.sticRtdata; } + +const configVisible = ref(false); +const formRef = ref(); +const form1 = reactive({ + time: 5, + count: 100, +}); + +function validatorTime(rule, value, callback) { + if(/^\d+$/.test(value)) { + if(value<1 || value>30) { + callback(new Error('鑼冨洿1~30')); + } else { + callback(); + } + }else { + callback(new Error('璇疯緭鍏ユ暣鏁�')); + } +} + +function validatorCount(rule, value, callback) { + if(/^\d+$/.test(value)) { + if (value<50 || value>200) { + callback(new Error('鑼冨洿50~200')); + } else { + callback(); + } + }else { + callback(new Error('璇疯緭鍏ユ暣鏁�')); + } +} + +const rules = { + time: [{ required: true, message: '璇疯緭鍏ユ椂闂�', trigger: ['blur', 'change'] }, + { validator: validatorTime, trigger: ['blur', 'change'] }, + ], + count: [{ required: true, message: '璇疯緭鍏ユ潯鏁�', trigger: ['blur', 'change'] }, + { validator: validatorCount, trigger: ['blur', 'change'] }, + ], +}; // 鍙栧墠鍗婂皬鏃舵暟鎹� 鏇存柊鍥捐〃 @@ -554,24 +598,46 @@ hrParamVisible.value = true; } +const config = ref({}); + +async function getHeartParam() { + let res = await getPwrHeartParam(props.powerId); + let { code, data, data2 } = res.data; + let cfg = {}; + if (code && data) { + cfg = data2; + } + config.value = cfg; +} + +const configTitle = ref(''); +function setConfig(type) { + switch(type) { + case 0: + configTitle.value = '璁剧疆浜ゆ祦杈撳叆閲囬泦鍙傛暟'; + form1.time = config.value.acinInterverCfg || 5; + form1.count = config.value.acinCountCfg || 100; + break; + case 1: + configTitle.value = '璁剧疆鐩存祦杈撳嚭閲囬泦鍙傛暟'; + form1.time = config.value.acoutInterverCfg || 5; + form1.count = config.value.acoutCountCfg || 100; + break; + case 2: + configTitle.value = '璁剧疆鏍稿璁惧閲囬泦鍙傛暟'; + form1.time = config.value.hrInterverCfg || 5; + form1.count = config.value.hrCountCfg || 100; + break; + } + configVisible.value = true; +} + +function updateConfig() { + configVisible.value = false; +} onMounted(async () => { - numChange('acin'); - numChange('dcout'); - numChange('dev'); - // await getAcinData(); - // await getDevData(); - // await getDcoutData(); - - // if (chart1.value) { - // chart1.value.updateChart(['04:12', '04:13', '04:14'], { - // '璁惧娓╁害': [100, 200, 220], - // '缁勭鐢垫祦': [100, 200, 220], - // '缁勭鐢靛帇': [100, 200, 220], - // '璐熻浇鐢垫祦': [100, 200, 220], - // }); - // } }); </script> @@ -648,28 +714,11 @@ <div class="card-item"> <card title="浜ゆ祦杈撳叆"> <template #tools> - <div class="page-filter"> - <div class="label">绮掑害</div> - <div class="value"> - <el-select - v-model="show_num['acin']" - size="small" - style="width: 50px" - @change="numChange('acin')" - > - <el-option - v-for="(n, i) in 10" - :key="'list0_' + i" - :label="'x' + n" - :value="n" - /> - </el-select> - </div> - </div> <el-radio-group class="tab-idx" v-model="tabIdx0" size="small"> <el-radio-button label="鐢垫祦" :value="0" /> <el-radio-button label="鐢靛帇" :value="1" /> </el-radio-group> + <svg-icon class-name="btn-setting" icon-class="setting" @click="setConfig(0)"></svg-icon> </template> <line-chart ref="chart0"></line-chart> </card> @@ -677,28 +726,11 @@ <div class="card-item"> <card title="鐩存祦杈撳嚭"> <template #tools> - <div class="page-filter"> - <div class="label">绮掑害</div> - <div class="value"> - <el-select - v-model="show_num['dcout']" - size="small" - style="width: 50px" - @change="numChange('dcout')" - > - <el-option - v-for="(n, i) in 10" - :key="'list0_' + i" - :label="'x' + n" - :value="n" - /> - </el-select> - </div> - </div> <el-radio-group class="tab-idx" v-model="tabIdx1" size="small"> <el-radio-button label="鐢垫祦" :value="0" /> <el-radio-button label="鐢靛帇" :value="1" /> </el-radio-group> + <svg-icon class-name="btn-setting" icon-class="setting" @click="setConfig(1)"></svg-icon> </template> <line-chart3 ref="chart1" @@ -713,25 +745,7 @@ <div class="card-item"> <card title="鏍稿璁惧淇℃伅"> <template #tools> - <div class="page-filter"> - <div class="label">绮掑害</div> - <div class="value"> - <el-select - v-model="show_num['dev']" - size="small" - style="width: 50px" - @change="numChange('dev')" - > - <el-option - v-for="(n, i) in 10" - :key="'list0_' + i" - :label="'x' + n" - :value="n" - /> - </el-select> - </div> - </div> - <!-- <svg-icon class-name="btn-setting" icon-class="setting"></svg-icon> --> + <svg-icon class-name="btn-setting" icon-class="setting" @click="setConfig(2)"></svg-icon> </template> <line-chart2 ref="chart2"></line-chart2> </card> @@ -815,12 +829,28 @@ </card> </div> </div> + <!-- 璁剧疆闂撮殧鍙傛暟 --> + <el-dialog v-model="configVisible" draggable :title="configTitle" width="560"> + <el-form ref="formRef" :model="form1" :rules="rules" label-width="10em"> + <el-form-item label="闂撮殧鏃堕棿(鍒�)" prop="time"> + <el-input v-model="form1.time"></el-input> + </el-form-item> + <el-form-item label="鏁版嵁绗旀暟" prop="count"> + <el-input v-model="form1.count"></el-input> + </el-form-item> + </el-form> + <template #footer> + <el-button @click="configVisible = false">鍏抽棴</el-button> + <!-- <el-button type="primary" @click="getConfig">璇诲彇</el-button> --> + <el-button type="primary" @click="updateConfig">璁惧畾</el-button> + </template> + </el-dialog> <!-- 璁剧疆鏍稿鍙傛暟 --> - <el-dialog v-model="hrParamVisible" :title="hrParamTitle" width="960"> + <el-dialog v-model="hrParamVisible" draggable :title="hrParamTitle" width="960"> <hr-params :devId="devId" v-model:visible="hrParamVisible" :battgroupId="battgroupId"></hr-params> </el-dialog> <!-- 璁剧疆璁惧鍛婅鍙傛暟 --> - <el-dialog v-model="devAlmVisible" title="璁惧鍛婅鍙傛暟" width="960"> + <el-dialog v-model="devAlmVisible" draggable title="璁惧鍛婅鍙傛暟" width="960"> <dev-alarm-params :devId="devId" v-model:visible="devAlmVisible"></dev-alarm-params> </el-dialog> </div> diff --git a/src/views/statistics/battCompare0_.vue b/src/views/statistics/battCompare0_.vue new file mode 100644 index 0000000..ae2208f --- /dev/null +++ b/src/views/statistics/battCompare0_.vue @@ -0,0 +1,546 @@ +<script setup name="battCompare0"> + import { ref, reactive, onMounted, computed, nextTick } from "vue"; + import { storeToRefs } from "pinia"; + import { Search, Plus } from "@element-plus/icons-vue"; + import ycCard from "@/components/ycCard/index.vue"; + import addEdit from "../datas/addEdit.vue"; + import { ElMessage } from "element-plus"; + import useElement from "@/hooks/useElement.js"; + import { useUserStore } from '@/store/user'; + + import useStation from "@/hooks/useStationList.js"; + const { provice, city, country, stationName, + proviceList, cityList, countryList, stationList, + } = useStation(); + + import { useRouter } from "vue-router"; + const router = useRouter(); + + import { ExportFile } from '@/utils/exportFile.js'; + + + import powerTypes from '@/utils/const/const_powerType.js'; + import hrTypes from '@/utils/const/const_hrTestType.js'; + import { + getBattPerformance, + getBatteryBrand, + } from "@/api/station"; + + const userStore = useUserStore(); + const { uid, uname } = storeToRefs(userStore); + import moment from 'moment'; + + import formatSeconds from '@/utils/formatSeconds'; + import { + toFixed, + digits, + } from '@/utils/toFixed'; + + import { + getBattCompare15, + } from "@/api/statistic.js"; + + const { $loading, $message, $confirm } = useElement(); + + + const headers = [ + { + prop: "stationName", + label: "绔欑偣鍚嶇О", + width: "160", + }, + { + prop: "devName", + label: "璁惧鍚嶇О", + width: "80", + }, + { + prop: "battgroupName", + label: "鐢垫睜缁勫悕绉�", + width: "80", + }, + { + prop: "product", + label: "鐢垫睜鍝佺墝", + width: "100", + }, + { + prop: "inuseTime", + label: "鎶曡繍鏃堕棿", + width: "100", + }, + { + prop: "monvolstd", + label: "鐢垫睜瑙勬牸", + width: "100", + }, + { + prop: "monNumsStr", + label: "钀藉悗鍗曚綋缂栧彿", + width: "160", + }, + { + prop: "realCap", + label: "棰勪及瀹归噺", + width: "80", + }, + { + prop: "precentCapStr", + label: "瀹归噺鐧惧垎姣�", + width: "80", + }, + { + prop: "capperformance", + label: "鐢垫睜鎬ц兘", + width: "80", + }, + ]; + + const testType = ref(''); + const hrTypeList = computed(() => { + return Object.keys(hrTypes).map(v => { + return { + value: v, + label: hrTypes[v], + }; + }); + }); + + + const background = ref(true); + const disabled = ref(false); + const pageCurr = ref(1); + const pageSize = ref(10); + const total = ref(0); + const addEditVisible = ref(false); + const dialogTitle = ref(""); + const currentAreaId = ref(); + const currentAreaIds = ref([]); + const testStartDate = ref(''); + const testEndDate = ref(''); + const datas = reactive({ + tableData: [], + rowData: {}, + }); + + + // 璁$畻灞炴�х敓鎴� picker-options锛堟洿绠�娲侊級 + const startDisabledDate = (time) => testEndDate.value ? moment(testEndDate.value).isBefore(time) || moment().isBefore(time) : moment().isBefore(time); + + const endDisabledDate = (time) => testStartDate.value ? moment(time).isBefore(testStartDate.value) || moment().isBefore(time) : moment().isBefore(time); + + const performance = ref(''); + const performanceList = ref([]); + + function getPerformancList() { + getBattPerformance() + .then((res) => { + let { code, data, data2 } = res; + let list = []; + if (code && data) { + // console.log(data); + list = Object.keys(data2).map((key) => ({ value: key, label: data2[key] })); + } + performanceList.value = list; + }) + .catch((err) => { + console.log(err); + }); + } + + const product = ref(''); + const productList = ref([]); + + function getProductList() { + getBatteryBrand().then((res) => { + let { code, data, data2 } = res; + let list = []; + if (code && data) { + list = data2; + } + productList.value = list; + }); + } + + + + function getList() { + let loading = $loading(); + let params = { + provice: provice.value || undefined, + city: city.value || undefined, + country: country.value || undefined, + stationName: stationName.value || undefined, + pageNum: pageCurr.value, + pageSize: pageSize.value, + + performance: performance.value || undefined, + product: product.value || undefined, + testStartTime: testStartDate.value ? testStartDate.value + ' 00:00:00' : undefined, + testEndTime: testEndDate.value ? testEndDate.value + ' 23:59:59' : undefined, + }; + + getBattCompare15(params) + .then((res) => { + let { code, data, data2 } = res; + let list = []; + let _total = 0; + if (code && data) { + // console.log(data); + list = data2.list.map(v => ({ + ...v, + monNumsStr: v.monNums.map(v => `#${v}`).join(',') || '--', + precentCapStr: toFixed(v.precentCap, digits.PREC) + '%', + })); + _total = data2.total; + } + loading.close(); + // tableData.length = 0; + // tableData.push(...list); + datas.tableData = list; + total.value = _total; + }) + .catch((err) => { + console.log(err); + loading.close(); + }); + } + + // 灞曠ず鏁版嵁鏁伴噺 + function handleSizeChange(val) { + pageSize.value = val; + getList(); + } + // 缈婚〉 + function handleCurrentChange(val) { + pageCurr.value = val; + getList(); + } + + function filterChange() { + nextTick(() => { + pageCurr.value = 1; + getList(); + }); + } + + function goRt (row) { + router.push({ + path: '/datas/realtime', + query: { + stationId: row.stationId || undefined, + powerId: row.powerId || undefined, + devId: row.devId || undefined, + battgroupId: row.battgroupId || undefined, + pageFlag: Math.random(), + } + }); + } + + function goHis (row) { + router.push({ + path: '/datas/history', + query: { + stationId: row.stationId || undefined, + powerId: row.powerId || undefined, + devId: row.devId || undefined, + battgroupId: row.battgroupId || undefined, + pageTab: 'his-real', + pageFlag: Math.random(), + } + }); + } + + function exportExcel() { + ExportFile(headers, datas.tableData, "钃勭數姹犵粍瀵规瘮鍒嗘瀽--鍚屼竴鍝佺墝鍚屼竴鏃堕棿"); + } + + onMounted(() => { + getPerformancList(); + getProductList(); + getList(); + }); +</script> + +<template> + <div class="page-wrapper"> + <!-- <div class="page-header"> + </div> --> + <div class="page-content"> + <yc-card is-full> + <div class="page-content-wrapper"> + <div class="page-content-tools page-filter"> + <div class="grid-container" :style="{'--counter': 10}"> + <div class="grid-item"> + <div class="label">鐪�</div> + <div class="value"> + <el-select + v-model="provice" + size="small" + clearable + @change="filterChange" + placeholder="璇烽�夋嫨鐪�" + > + <el-option + v-for="item in proviceList" + :key="'l0_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">甯�</div> + <div class="value"> + <el-select + v-model="city" + size="small" + clearable + @change="filterChange" + placeholder="璇烽�夋嫨甯�" + > + <el-option + v-for="item in cityList" + :key="'l1_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鍖哄幙</div> + <div class="value"> + <el-select + v-model="country" + clearable + @change="filterChange" + size="small" + placeholder="璇烽�夋嫨鍖哄幙" + > + <el-option + v-for="item in countryList" + :key="'l2_' + item" + :label="item" + :value="item" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">绔欑偣</div> + <div class="value"> + <el-select + v-model="stationName" + clearable + @change="filterChange" + size="small" + placeholder="璇烽�夋嫨绔欑偣" + > + <el-option + v-for="item in stationList" + :key="'l3_' + item.stationId" + :label="item.stationName" + :value="item.stationName" + > + </el-option> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鐢垫睜鎬ц兘</div> + <div class="value"> + <el-select + v-model="performance" + filterable + clearable + size="small" + @change="filterChange" + placeholder="璇烽�夋嫨" + > + <el-option + v-for="(item, idx) in performanceList" + :key="'list7_' + idx" + :label="item.label" + :value="item.value" + /> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">鐢垫睜鍝佺墝</div> + <div class="value"> + <el-select + v-model="product" + filterable + clearable + size="small" + @change="filterChange" + placeholder="璇烽�夋嫨" + > + <el-option + v-for="(item, idx) in productList" + :key="'list6_' + idx" + :label="item" + :value="item" + /> + </el-select> + </div> + </div> + <div class="grid-item"> + <div class="label">缁熻鏃堕棿娈�</div> + <div class="value" style="grid-column: span 7;"> + <el-date-picker + v-model="testStartDate" + type="date" + size="small" + placeholder="閫夋嫨鏃ユ湡" + format="YYYY-MM-DD" + value-format="YYYY-MM-DD" + :disabled-date="startDisabledDate" + /> + - + <el-date-picker + v-model="testEndDate" + size="small" + type="date" + placeholder="閫夋嫨鏃ユ湡" + format="YYYY-MM-DD" + value-format="YYYY-MM-DD" + :disabled-date="endDisabledDate" + /> + </div> + </div> + </div> + </div> + <div class="page-content-table"> + <div class="pos-rel"> + <div class="pos-abs"> + <el-table class="yc-table" stripe height="100%" size="small" :data="datas.tableData" style="width: 100%"> + <el-table-column type="index" fixed="left" label="搴忓彿" width="60"></el-table-column> + <el-table-column v-for="header in headers" :key="header.prop" :prop="header.prop" :label="header.label" + :min-width="header.width" align="center"> + <template #default="scope">{{ scope.row[header.prop] }}</template> + </el-table-column> + <el-table-column label="鎿嶄綔" fixed="right" width="240" align="center"> + <template #default="scope"> + <el-button type="warning" size="small" @click="goRt(scope.row)">瀹炴椂鐩戞祴</el-button> + <el-button type="primary" size="small" @click="goHis(scope.row)">鍘嗗彶鏁版嵁</el-button> + </template> + </el-table-column> + </el-table> + </div> + </div> + </div> + <div class="page-content-page"> + <div class="page-tool"> + <el-button type="primary" round size="small" @click="getList" :icon="Search">鏌ヨ</el-button> + </div> + <div class="el-page-container"> + <el-pagination v-model:current-page="pageCurr" v-model:page-size="pageSize" + :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" size="small" :disabled="disabled" + :background="background" layout="total, sizes, prev, pager, next, jumper" :total="total" + @size-change="handleSizeChange" @current-change="handleCurrentChange" /> + </div> + <div class="page-tool"> + <el-button type="primary" round size="small" @click="exportExcel">瀵煎嚭</el-button> + </div> + </div> + </div> + </yc-card> + </div> + <div class="page-footer"></div> + </div> +</template> + +<style scoped lang="less"> +.page-wrapper { + display: flex; + flex-direction: row; + // padding: 8px; + height: 100%; + + .page-content { + flex: 1; + } +} + +.page-content-wrapper { + display: flex; + flex-direction: column; + height: 100%; + + .page-content-tools { + padding-bottom: 8px; + } + + .page-content-table { + // border-top: 1px solid var(--border-light-color); + box-sizing: border-box; + flex: 1; + margin-left: 26px; + margin-right: 26px; + } + + .page-content-page { + padding: 8px 8px 0 8px; + text-align: center; + + .el-page-container { + display: inline-block; + padding: 0 16px; + } + + .page-tool { + display: inline-block; + } + } +} + +.hdw-card-container { + width: 240px; + padding-right: 8px; + height: 100%; +} + +.pos-rel { + position: relative; + width: 100%; + height: 100%; + + .pos-abs { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + } +} + +.tools-filter { + display: inline-block; + font-size: 14px; + + .tools-filter-item { + display: inline-block; + margin-right: 8px; + + .filter-label { + display: inline-block; + } + + .filter-content { + display: inline-block; + } + } +} +.max-width { + max-width: 200px; +} +</style> \ No newline at end of file -- Gitblit v1.9.1