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