9 changed files with 1275 additions and 150 deletions
			
			
		@ -0,0 +1,295 @@ | 
				
			|||||||
 | 
					<template> | 
				
			||||||
 | 
					  <div> | 
				
			||||||
 | 
					    <div class="historyCharts" ref="chart_ref"></div> | 
				
			||||||
 | 
					  </div> | 
				
			||||||
 | 
					</template> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script> | 
				
			||||||
 | 
					import * as echarts from "echarts"; | 
				
			||||||
 | 
					export default { | 
				
			||||||
 | 
					  props: { | 
				
			||||||
 | 
					    chartsData: { | 
				
			||||||
 | 
					      type: Array, | 
				
			||||||
 | 
					      default: () => [], | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  data() { | 
				
			||||||
 | 
					    return { | 
				
			||||||
 | 
					      chartInstance: null, | 
				
			||||||
 | 
					      option: {}, | 
				
			||||||
 | 
					      chartData1: [], | 
				
			||||||
 | 
					      chartData2: [], | 
				
			||||||
 | 
					      bottomData: [], | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  watch: { | 
				
			||||||
 | 
					    chartsData: { | 
				
			||||||
 | 
					      immediate: true, // 页面加载时立即触发一次监听 | 
				
			||||||
 | 
					      handler(newVal, oldVal) { | 
				
			||||||
 | 
					        if (newVal) { | 
				
			||||||
 | 
					          console.log("charts传值", newVal); | 
				
			||||||
 | 
					          let data = newVal; | 
				
			||||||
 | 
					          if (data.length > 0) { | 
				
			||||||
 | 
					            data.forEach((item) => { | 
				
			||||||
 | 
					              // 处理 chartData1 | 
				
			||||||
 | 
					              const value1 = | 
				
			||||||
 | 
					                item.indoorTemp === null || item.indoorTemp === "" | 
				
			||||||
 | 
					                  ? 0 | 
				
			||||||
 | 
					                  : item.indoorTemp; | 
				
			||||||
 | 
					              this.chartData1.push(value1); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              // 假设 item 中对应 chartData2 的字段是 indoorHumidity | 
				
			||||||
 | 
					              const value2 = | 
				
			||||||
 | 
					                item.indoorHumidity === null || item.indoorHumidity === "" | 
				
			||||||
 | 
					                  ? 0 | 
				
			||||||
 | 
					                  : item.indoorHumidity; | 
				
			||||||
 | 
					              this.chartData2.push(value2); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              // 假设 item 中对应 bottomData 的字段是 curTime | 
				
			||||||
 | 
					              const value3 = | 
				
			||||||
 | 
					                item.curTime === null || item.curTime === "" ? 0 : item.curTime; | 
				
			||||||
 | 
					              this.bottomData.push(value3); | 
				
			||||||
 | 
					            }); | 
				
			||||||
 | 
					            this.$nextTick(() => { | 
				
			||||||
 | 
					              const adapterOption = { | 
				
			||||||
 | 
					                xAxis: { | 
				
			||||||
 | 
					                  data: this.bottomData, | 
				
			||||||
 | 
					                }, | 
				
			||||||
 | 
					                series: [ | 
				
			||||||
 | 
					                  { | 
				
			||||||
 | 
					                    yAxisIndex: 0, | 
				
			||||||
 | 
					                    data: this.chartData1, | 
				
			||||||
 | 
					                  }, | 
				
			||||||
 | 
					                  { | 
				
			||||||
 | 
					                    yAxisIndex: 0, | 
				
			||||||
 | 
					                    data: this.chartData2, | 
				
			||||||
 | 
					                  }, | 
				
			||||||
 | 
					                ], | 
				
			||||||
 | 
					              }; | 
				
			||||||
 | 
					              this.chartInstance.setOption(adapterOption); | 
				
			||||||
 | 
					              //手动的调用图标对象的resize才能产生效果 | 
				
			||||||
 | 
					              this.chartInstance.resize(); | 
				
			||||||
 | 
					            }); | 
				
			||||||
 | 
					          } else { | 
				
			||||||
 | 
					            this.$nextTick(() => { | 
				
			||||||
 | 
					              const adapterOption = { | 
				
			||||||
 | 
					                xAxis: { | 
				
			||||||
 | 
					                  data: [], | 
				
			||||||
 | 
					                }, | 
				
			||||||
 | 
					                series: [ | 
				
			||||||
 | 
					                  { | 
				
			||||||
 | 
					                    yAxisIndex: 0, | 
				
			||||||
 | 
					                    data: [], | 
				
			||||||
 | 
					                  }, | 
				
			||||||
 | 
					                  { | 
				
			||||||
 | 
					                    yAxisIndex: 0, | 
				
			||||||
 | 
					                    data: [], | 
				
			||||||
 | 
					                  }, | 
				
			||||||
 | 
					                ], | 
				
			||||||
 | 
					              }; | 
				
			||||||
 | 
					              this.chartInstance.setOption(adapterOption); | 
				
			||||||
 | 
					              //手动的调用图标对象的resize才能产生效果 | 
				
			||||||
 | 
					              this.chartInstance.resize(); | 
				
			||||||
 | 
					              this.screenAdapter(); | 
				
			||||||
 | 
					            }); | 
				
			||||||
 | 
					          } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					      }, | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  mounted() { | 
				
			||||||
 | 
					    this.initChart(); | 
				
			||||||
 | 
					    this.screenAdapter(); | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  destroyed() { | 
				
			||||||
 | 
					    //取消监听器 | 
				
			||||||
 | 
					    window.removeEventListener("resize", this.screenAdapter); | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  methods: { | 
				
			||||||
 | 
					    // 折线图自适应+ 根据按钮切换图例仅限一条且不可点击+ 折线图数据 | 
				
			||||||
 | 
					    screenAdapter() { | 
				
			||||||
 | 
					      //自己定义的比较合适的适配大小,2.6  mes_ref是图表盒子 | 
				
			||||||
 | 
					      const titleFontSize = this.$refs.chart_ref.offsetWidth / 130; | 
				
			||||||
 | 
					      //因为option可以多次配置的,所以这里的option只需要写 需要配置大小的相关数据 | 
				
			||||||
 | 
					      const adapterOption = {}; | 
				
			||||||
 | 
					      //记得重新给配置项给实例对象。只要实例对象.chartInstance不变,option就可以多次配置不同的条件。也可以配置一个dataoption只写需要从后台请求的数据相关 | 
				
			||||||
 | 
					      this.chartInstance.setOption(adapterOption); | 
				
			||||||
 | 
					      //手动的调用图标对象的resize才能产生效果 | 
				
			||||||
 | 
					      this.chartInstance.resize(); | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    //初始化chartInstance对象 | 
				
			||||||
 | 
					    initChart() { | 
				
			||||||
 | 
					      const chartRef = this.$refs.chart_ref; | 
				
			||||||
 | 
					      if (chartRef) { | 
				
			||||||
 | 
					        // 初始化图表的代码 | 
				
			||||||
 | 
					        this.chartInstance = echarts.init(this.$refs.chart_ref); | 
				
			||||||
 | 
					        this.option = { | 
				
			||||||
 | 
					          tooltip: { | 
				
			||||||
 | 
					            trigger: "axis", | 
				
			||||||
 | 
					          }, | 
				
			||||||
 | 
					          legend: { | 
				
			||||||
 | 
					            show: true, | 
				
			||||||
 | 
					            top: 0, | 
				
			||||||
 | 
					            textStyle: { | 
				
			||||||
 | 
					              color: "white", | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					          }, | 
				
			||||||
 | 
					          grid: { | 
				
			||||||
 | 
					            top: "10%", | 
				
			||||||
 | 
					            left: "4%", | 
				
			||||||
 | 
					            right: "6%", | 
				
			||||||
 | 
					            bottom: "3%", | 
				
			||||||
 | 
					            containLabel: true, | 
				
			||||||
 | 
					          }, | 
				
			||||||
 | 
					          xAxis: { | 
				
			||||||
 | 
					            type: "category", | 
				
			||||||
 | 
					            //设置为true代表离零刻度间隔一段距离 | 
				
			||||||
 | 
					            boundaryGap: true, | 
				
			||||||
 | 
					            // 修饰刻度标签的颜色即x坐标数据 | 
				
			||||||
 | 
					            axisLabel: { | 
				
			||||||
 | 
					              // interval: 0, //强制显示所有x轴数据 | 
				
			||||||
 | 
					              // rotate: 30, //x轴坐标字体倾斜30度 | 
				
			||||||
 | 
					              color: "rgba(255, 255, 255, 1)", | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            axisTick: { | 
				
			||||||
 | 
					              show: false, // 不显示坐标轴刻度线 | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            // x坐标轴的颜色 | 
				
			||||||
 | 
					            axisLine: { | 
				
			||||||
 | 
					              show: true, | 
				
			||||||
 | 
					              lineStyle: { | 
				
			||||||
 | 
					                color: "#365576", | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            splitLine: { | 
				
			||||||
 | 
					              lineStyle: { | 
				
			||||||
 | 
					                color: "#e2e6f0", | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					            }, //x轴分割线 | 
				
			||||||
 | 
					            data: this.bottomData, | 
				
			||||||
 | 
					          }, | 
				
			||||||
 | 
					          yAxis: { | 
				
			||||||
 | 
					            min: 0, | 
				
			||||||
 | 
					            // max:20, | 
				
			||||||
 | 
					            // // // min:'dataMin', | 
				
			||||||
 | 
					            // // // max:'dataMax', | 
				
			||||||
 | 
					            // name: "kwh", // 第一个 y 轴的单位描述 | 
				
			||||||
 | 
					            // 设置 name 的样式 | 
				
			||||||
 | 
					            nameTextStyle: { | 
				
			||||||
 | 
					              color: "rgba(255, 255, 255, 1)", | 
				
			||||||
 | 
					              fontSize: 12, | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            miniInterval: 5, | 
				
			||||||
 | 
					            type: "value", | 
				
			||||||
 | 
					            // 修饰刻度标签的颜色即y坐标数据 | 
				
			||||||
 | 
					            axisLabel: { | 
				
			||||||
 | 
					              color: "rgba(255, 255, 255, 1)", | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            // 显示y坐标轴 | 
				
			||||||
 | 
					            axisLine: { | 
				
			||||||
 | 
					              show: true, | 
				
			||||||
 | 
					              lineStyle: { | 
				
			||||||
 | 
					                color: "#365576", // 设置 y 轴线的颜色 | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            //y轴分割线段数 | 
				
			||||||
 | 
					            // splitNumber: 10, | 
				
			||||||
 | 
					            // 修改y轴分割线的颜色 | 
				
			||||||
 | 
					            splitLine: { | 
				
			||||||
 | 
					              lineStyle: { | 
				
			||||||
 | 
					                color: "#1a3d62", // 设置分割线的颜色 | 
				
			||||||
 | 
					                type: "dashed", // 设置分割线为虚线 | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					          }, | 
				
			||||||
 | 
					          series: [ | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					              type: "line", | 
				
			||||||
 | 
					              // 拐点大小 | 
				
			||||||
 | 
					              symbolSize: 8, | 
				
			||||||
 | 
					              data: this.chartData1, | 
				
			||||||
 | 
					              name: "温度", | 
				
			||||||
 | 
					              //折线颜色 | 
				
			||||||
 | 
					              itemStyle: { | 
				
			||||||
 | 
					                color: "#1a69f1", //折线点的颜色 | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					              lineStyle: { | 
				
			||||||
 | 
					                color: "#1a69f1", //折线点的颜色 | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					              smooth: false, | 
				
			||||||
 | 
					              // 不显示折线点 | 
				
			||||||
 | 
					              showSymbol: false, | 
				
			||||||
 | 
					              // 区域填充样式,添加渐变背景 | 
				
			||||||
 | 
					              areaStyle: { | 
				
			||||||
 | 
					                color: { | 
				
			||||||
 | 
					                  type: "linear", | 
				
			||||||
 | 
					                  x: 0, | 
				
			||||||
 | 
					                  y: 0, | 
				
			||||||
 | 
					                  x2: 0, | 
				
			||||||
 | 
					                  y2: 1, | 
				
			||||||
 | 
					                  colorStops: [ | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                      offset: 0, | 
				
			||||||
 | 
					                      color: "rgba(26, 105, 241, 0.5)", // 渐变起始颜色 | 
				
			||||||
 | 
					                    }, | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                      offset: 1, | 
				
			||||||
 | 
					                      color: "rgba(26, 105, 241, 0)", // 渐变结束颜色 | 
				
			||||||
 | 
					                    }, | 
				
			||||||
 | 
					                  ], | 
				
			||||||
 | 
					                  global: false, // 缺省为 false | 
				
			||||||
 | 
					                }, | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					            { | 
				
			||||||
 | 
					              type: "line", | 
				
			||||||
 | 
					              // 拐点大小 | 
				
			||||||
 | 
					              symbolSize: 8, | 
				
			||||||
 | 
					              data: this.chartData2, | 
				
			||||||
 | 
					              name: "湿度", | 
				
			||||||
 | 
					              //折线颜色 | 
				
			||||||
 | 
					              itemStyle: { | 
				
			||||||
 | 
					                color: "#00CED1", //折线的颜色 | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					              smooth: false, | 
				
			||||||
 | 
					              // 不显示折线点 | 
				
			||||||
 | 
					              showSymbol: false, | 
				
			||||||
 | 
					              areaStyle: { | 
				
			||||||
 | 
					                color: { | 
				
			||||||
 | 
					                  type: "linear", | 
				
			||||||
 | 
					                  x: 0, | 
				
			||||||
 | 
					                  y: 0, | 
				
			||||||
 | 
					                  x2: 0, | 
				
			||||||
 | 
					                  y2: 1, | 
				
			||||||
 | 
					                  colorStops: [ | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                      offset: 0, | 
				
			||||||
 | 
					                      color: "rgba(0, 206, 209, 0.5)", // 渐变起始颜色 | 
				
			||||||
 | 
					                    }, | 
				
			||||||
 | 
					                    { | 
				
			||||||
 | 
					                      offset: 1, | 
				
			||||||
 | 
					                      color: "rgba(0, 206, 209, 0)", // 渐变结束颜色 | 
				
			||||||
 | 
					                    }, | 
				
			||||||
 | 
					                  ], | 
				
			||||||
 | 
					                  global: false, // 缺省为 false | 
				
			||||||
 | 
					                }, | 
				
			||||||
 | 
					              }, | 
				
			||||||
 | 
					            }, | 
				
			||||||
 | 
					          ], | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					        //把配置项给实例对象 | 
				
			||||||
 | 
					        this.chartInstance.setOption(this.option, true); | 
				
			||||||
 | 
					      } else { | 
				
			||||||
 | 
					        console.error("未找到有效的 DOM 元素"); | 
				
			||||||
 | 
					      } | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					</script> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped> | 
				
			||||||
 | 
					.historyCharts { | 
				
			||||||
 | 
					  width: 100%; | 
				
			||||||
 | 
					  height: 200px; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					</style> | 
				
			||||||
@ -0,0 +1,53 @@ | 
				
			|||||||
 | 
					<template> | 
				
			||||||
 | 
					  <div> | 
				
			||||||
 | 
					    <el-table class="historyTables" :data="tableList" height="200px"> | 
				
			||||||
 | 
					      <el-table-column | 
				
			||||||
 | 
					        prop="curTime" | 
				
			||||||
 | 
					        label="时间" | 
				
			||||||
 | 
					      ></el-table-column> | 
				
			||||||
 | 
					      <el-table-column | 
				
			||||||
 | 
					        prop="indoorTemp" | 
				
			||||||
 | 
					        label="温度(℃)" | 
				
			||||||
 | 
					      ></el-table-column> | 
				
			||||||
 | 
					      <el-table-column | 
				
			||||||
 | 
					        prop="indoorHumidity" | 
				
			||||||
 | 
					        label="湿度(%)" | 
				
			||||||
 | 
					      ></el-table-column> | 
				
			||||||
 | 
					    </el-table> | 
				
			||||||
 | 
					  </div> | 
				
			||||||
 | 
					</template> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script> | 
				
			||||||
 | 
					export default { | 
				
			||||||
 | 
					  props: { | 
				
			||||||
 | 
					    tableData: { | 
				
			||||||
 | 
					      type: Array, | 
				
			||||||
 | 
					      default: () => [], | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  data() { | 
				
			||||||
 | 
					    return { | 
				
			||||||
 | 
					      tableList: [], | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  watch: { | 
				
			||||||
 | 
					    tableData: { | 
				
			||||||
 | 
					      immediate: true, // 页面加载时立即触发一次监听 | 
				
			||||||
 | 
					      handler(newVal, oldVal) { | 
				
			||||||
 | 
					        if (newVal) { | 
				
			||||||
 | 
					          console.log("charts传值", newVal); | 
				
			||||||
 | 
					          let data = newVal; | 
				
			||||||
 | 
					          if (data.length > 0) { | 
				
			||||||
 | 
					            this.tableList = newVal; | 
				
			||||||
 | 
					          } else { | 
				
			||||||
 | 
					            this.tableList = []; | 
				
			||||||
 | 
					          } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					      }, | 
				
			||||||
 | 
					      deep: true, // 深度监听 | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					</script> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style></style> | 
				
			||||||
@ -1,13 +1,306 @@ | 
				
			|||||||
<template> | 
					<template> | 
				
			||||||
  <div>历史数据</div> | 
					  <div class="app-container"> | 
				
			||||||
 | 
					    <div class="btn-condition"> | 
				
			||||||
 | 
					      <div class="condition-left"> | 
				
			||||||
 | 
					        <el-form | 
				
			||||||
 | 
					          :model="queryParams" | 
				
			||||||
 | 
					          ref="queryForm" | 
				
			||||||
 | 
					          size="small" | 
				
			||||||
 | 
					          :inline="true" | 
				
			||||||
 | 
					          label-width="68px" | 
				
			||||||
 | 
					        > | 
				
			||||||
 | 
					          <el-form-item label="房间" prop="gwName"> | 
				
			||||||
 | 
					            <el-cascader | 
				
			||||||
 | 
					              class="elCascader" | 
				
			||||||
 | 
					              :options="options" | 
				
			||||||
 | 
					              :props="props" | 
				
			||||||
 | 
					              collapse-tags | 
				
			||||||
 | 
					              clearable | 
				
			||||||
 | 
					              v-model="selectedValue" | 
				
			||||||
 | 
					              @change="handleCascaderChange" | 
				
			||||||
 | 
					            ></el-cascader> | 
				
			||||||
 | 
					          </el-form-item> | 
				
			||||||
 | 
					          <el-form-item label="时间范围" prop="gwName"> | 
				
			||||||
 | 
					            <el-date-picker | 
				
			||||||
 | 
					              v-model="timeDate" | 
				
			||||||
 | 
					              :default-time="['00:00:00', '23:59:59']" | 
				
			||||||
 | 
					              type="datetimerange" | 
				
			||||||
 | 
					              range-separator="至" | 
				
			||||||
 | 
					              placeholder="选择日期" | 
				
			||||||
 | 
					              start-placeholder="开始日期" | 
				
			||||||
 | 
					              end-placeholder="结束日期" | 
				
			||||||
 | 
					            > | 
				
			||||||
 | 
					            </el-date-picker> | 
				
			||||||
 | 
					          </el-form-item> | 
				
			||||||
 | 
					        </el-form> | 
				
			||||||
 | 
					        <div class="primary-btn"> | 
				
			||||||
 | 
					          <el-button | 
				
			||||||
 | 
					            type="primary" | 
				
			||||||
 | 
					            icon="el-icon-search" | 
				
			||||||
 | 
					            size="mini" | 
				
			||||||
 | 
					            @click="handleQuery" | 
				
			||||||
 | 
					            >搜索</el-button | 
				
			||||||
 | 
					          > | 
				
			||||||
 | 
					        </div> | 
				
			||||||
 | 
					      </div> | 
				
			||||||
 | 
					    </div> | 
				
			||||||
 | 
					    <div class="history" v-loading="loading"> | 
				
			||||||
 | 
					      <div | 
				
			||||||
 | 
					        class="history-li" | 
				
			||||||
 | 
					        :class="{ oneClass: tableData.length === 1 }" | 
				
			||||||
 | 
					        v-for="(item, index) in tableData" | 
				
			||||||
 | 
					        :key="index" | 
				
			||||||
 | 
					      > | 
				
			||||||
 | 
					        <div class="history-top"> | 
				
			||||||
 | 
					          <div class="room">{{ item.houseName }}</div> | 
				
			||||||
 | 
					          <div class="change" @click="toggleComponent(index)"> | 
				
			||||||
 | 
					            <svg-icon | 
				
			||||||
 | 
					              slot="prefix" | 
				
			||||||
 | 
					              icon-class="chartsSvg" | 
				
			||||||
 | 
					              class="chartsSvg" | 
				
			||||||
 | 
					              v-if="item.showCharts" | 
				
			||||||
 | 
					            /> | 
				
			||||||
 | 
					            <svg-icon | 
				
			||||||
 | 
					              slot="prefix" | 
				
			||||||
 | 
					              icon-class="tableSvg" | 
				
			||||||
 | 
					              class="tableSvg" | 
				
			||||||
 | 
					              v-else | 
				
			||||||
 | 
					            /> | 
				
			||||||
 | 
					          </div> | 
				
			||||||
 | 
					        </div> | 
				
			||||||
 | 
					        <div class="title">{{ timeDate[0] }}-{{ timeDate[1] }}温湿度数据</div> | 
				
			||||||
 | 
					        <!-- 图表和表格可以自由切换 --> | 
				
			||||||
 | 
					        <history-charts | 
				
			||||||
 | 
					          v-if="item.showCharts" | 
				
			||||||
 | 
					          :chartsData="item.dataList" | 
				
			||||||
 | 
					        ></history-charts> | 
				
			||||||
 | 
					        <history-tables v-else :tableData="item.dataList"></history-tables> | 
				
			||||||
 | 
					      </div> | 
				
			||||||
 | 
					    </div> | 
				
			||||||
 | 
					  </div> | 
				
			||||||
</template> | 
					</template> | 
				
			||||||
 | 
					
 | 
				
			||||||
<script> | 
					<script> | 
				
			||||||
 | 
					import { format2 } from "@/utils/datetime"; | 
				
			||||||
 | 
					import { spaceTree } from "@/api/region"; | 
				
			||||||
 | 
					import { temHistory } from "@/api/temSys/temMonitor"; | 
				
			||||||
 | 
					import historyCharts from "./components/historyCharts.vue"; | 
				
			||||||
 | 
					import HistoryTables from "./components/historyTables.vue"; | 
				
			||||||
export default { | 
					export default { | 
				
			||||||
 | 
					  components: { historyCharts, HistoryTables }, | 
				
			||||||
 | 
					  data() { | 
				
			||||||
 | 
					    return { | 
				
			||||||
 | 
					      loading: false, | 
				
			||||||
 | 
					      timeDate: [], | 
				
			||||||
 | 
					      // 查询参数 | 
				
			||||||
 | 
					      queryParams: { | 
				
			||||||
 | 
					        systemType: "4", | 
				
			||||||
 | 
					        houseIds: [], //多选房间的id数组 | 
				
			||||||
 | 
					        startTime: "", | 
				
			||||||
 | 
					        endTime: "", | 
				
			||||||
 | 
					      }, | 
				
			||||||
 | 
					      selectedValue: [], //选中的数组(里面也是数组) | 
				
			||||||
 | 
					      props: { | 
				
			||||||
 | 
					        value: "id", // 指定使用 id 作为值的标识 | 
				
			||||||
 | 
					        label: "label", | 
				
			||||||
 | 
					        children: "children", | 
				
			||||||
 | 
					        multiple: true, | 
				
			||||||
 | 
					      }, | 
				
			||||||
 | 
					      options: [], | 
				
			||||||
 | 
					      tableData: [ | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					          name: "A201", | 
				
			||||||
 | 
					          showCharts: true, // 初始显示图表组件 | 
				
			||||||
 | 
					        }, | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					          name: "A202", | 
				
			||||||
 | 
					          showCharts: true, // 初始显示图表组件 | 
				
			||||||
 | 
					        }, | 
				
			||||||
 | 
					        { | 
				
			||||||
 | 
					          name: "A203", | 
				
			||||||
 | 
					          showCharts: true, // 初始显示图表组件 | 
				
			||||||
 | 
					        }, | 
				
			||||||
 | 
					      ], | 
				
			||||||
 | 
					    }; | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  mounted() { | 
				
			||||||
 | 
					    this.initializeTimeDate(); | 
				
			||||||
 | 
					    this.getSysBuild(); | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					  methods: { | 
				
			||||||
 | 
					    // 初始化时间 | 
				
			||||||
 | 
					    initializeTimeDate() { | 
				
			||||||
 | 
					      const start = new Date(new Date().setHours(0, 0, 0, 0)); | 
				
			||||||
 | 
					      const end = new Date(new Date().setHours(23, 59, 59, 59)); | 
				
			||||||
 | 
					      this.timeDate = [format2(start), format2(end)]; // 更新 | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    getSysBuild() { | 
				
			||||||
 | 
					      spaceTree().then((res) => { | 
				
			||||||
 | 
					        if (res.code == 200) { | 
				
			||||||
 | 
					          // 只需要保留热水的系统 | 
				
			||||||
 | 
					          console.log("楼栋返回值", res); | 
				
			||||||
 | 
					          let newRes = { ...res }; | 
				
			||||||
 | 
					
 | 
				
			||||||
} | 
					          if (newRes.data && newRes.data[0] && newRes.data[0].children) { | 
				
			||||||
</script> | 
					            newRes.data[0].children = newRes.data[0].children.filter((item) => { | 
				
			||||||
 | 
					              // 假设子项有一个 label属性,用于检查是否包含 "热水" | 
				
			||||||
 | 
					              return item.label && item.label.includes("温度监测"); | 
				
			||||||
 | 
					            }); | 
				
			||||||
 | 
					          } | 
				
			||||||
 | 
					          this.options = newRes.data[0].children[0].children; | 
				
			||||||
 | 
					          console.log("温度监测的数组", this.options); | 
				
			||||||
 | 
					          // 提取路径 | 
				
			||||||
 | 
					          if (this.options.length > 0) { | 
				
			||||||
 | 
					            // 找到最后一层的第一个子节点 | 
				
			||||||
 | 
					            const lastLevelFirstChild = this.findLastLevelFirstChild( | 
				
			||||||
 | 
					              this.options[0] | 
				
			||||||
 | 
					            ); | 
				
			||||||
 | 
					            console.log("最后一个节点的id", lastLevelFirstChild); | 
				
			||||||
 | 
					            // 查找完整路径 | 
				
			||||||
 | 
					            const path = this.findPath(this.options, lastLevelFirstChild.id); | 
				
			||||||
 | 
					            if (path) { | 
				
			||||||
 | 
					              this.selectedValue = [path]; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					            console.log("反推三个id", path); | 
				
			||||||
 | 
					          } | 
				
			||||||
 | 
					
 | 
				
			||||||
<style> | 
					          this.getList(); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					      }); | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    // 递归函数,找到最后一层的第一个子节点 | 
				
			||||||
 | 
					    findLastLevelFirstChild(node, level = 1) { | 
				
			||||||
 | 
					      if (!node.children || node.children.length === 0) { | 
				
			||||||
 | 
					        return { | 
				
			||||||
 | 
					          id: node.id, | 
				
			||||||
 | 
					        }; | 
				
			||||||
 | 
					      } | 
				
			||||||
 | 
					      return this.findLastLevelFirstChild(node.children[0], level + 1); | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    // 最后id反推前三id数组 | 
				
			||||||
 | 
					    findPath(options, targetId, currentPath = []) { | 
				
			||||||
 | 
					      for (let i = 0; i < options.length; i++) { | 
				
			||||||
 | 
					        const item = options[i]; | 
				
			||||||
 | 
					        // 检查 item 是否有 id 属性 | 
				
			||||||
 | 
					        if (!item.id) continue; | 
				
			||||||
 | 
					        const newPath = [...currentPath, item.id]; | 
				
			||||||
 | 
					        if (item.id === targetId) { | 
				
			||||||
 | 
					          return newPath; | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					        if (item.children && item.children.length > 0) { | 
				
			||||||
 | 
					          const result = this.findPath(item.children, targetId, newPath); | 
				
			||||||
 | 
					          if (result) { | 
				
			||||||
 | 
					            return result; | 
				
			||||||
 | 
					          } | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					      } | 
				
			||||||
 | 
					      return null; | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    handleQuery() { | 
				
			||||||
 | 
					      this.getList(); | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    getList() { | 
				
			||||||
 | 
					      this.queryParams.startTime = this.timeDate[0]; | 
				
			||||||
 | 
					      this.queryParams.endTime = this.timeDate[1]; | 
				
			||||||
 | 
					      let data = this.queryParams; | 
				
			||||||
 | 
					      console.log("参数", data); | 
				
			||||||
 | 
					      temHistory(data).then((res) => { | 
				
			||||||
 | 
					        console.log("历史数据返回", res); | 
				
			||||||
 | 
					        if (res.code == 200) { | 
				
			||||||
 | 
					          // 开启 loading 效果 | 
				
			||||||
 | 
					          this.loading = true; | 
				
			||||||
 | 
					          // 过滤掉 dataList 为空的对象 | 
				
			||||||
 | 
					          const filteredRows = res.rows.filter( | 
				
			||||||
 | 
					            (item) => item.dataList && item.dataList.length > 0 | 
				
			||||||
 | 
					          ); | 
				
			||||||
 | 
					          // 为过滤后的每个对象添加 showCharts: true 属性 | 
				
			||||||
 | 
					          const newRows = filteredRows.map((item) => ({ | 
				
			||||||
 | 
					            ...item, | 
				
			||||||
 | 
					            showCharts: true, | 
				
			||||||
 | 
					          })); | 
				
			||||||
 | 
					          this.tableData = newRows; | 
				
			||||||
 | 
					          console.log("处理后的历史数据", newRows); | 
				
			||||||
 | 
					        } | 
				
			||||||
 | 
					      }).catch((error) => { | 
				
			||||||
 | 
					          console.error("查询表格数据时发生错误:", error); | 
				
			||||||
 | 
					        }) | 
				
			||||||
 | 
					        .finally(() => { | 
				
			||||||
 | 
					          setTimeout(() => { | 
				
			||||||
 | 
					            this.loading = false; | 
				
			||||||
 | 
					          }, 1000); | 
				
			||||||
 | 
					        }); | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    handleCascaderChange(selectedOptions) { | 
				
			||||||
 | 
					      console.log("选中的完全路径", selectedOptions); | 
				
			||||||
 | 
					      // 提取所有选中项的最后一级 id 值 | 
				
			||||||
 | 
					      const selectedIds = selectedOptions.map( | 
				
			||||||
 | 
					        (option) => option[option.length - 1] | 
				
			||||||
 | 
					      ); | 
				
			||||||
 | 
					      console.log("选中的 id 数组:", selectedIds); | 
				
			||||||
 | 
					      this.queryParams.houseIds = selectedIds; | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					    toggleComponent(index) { | 
				
			||||||
 | 
					      // 切换显示状态 | 
				
			||||||
 | 
					      this.tableData[index].showCharts = !this.tableData[index].showCharts; | 
				
			||||||
 | 
					    }, | 
				
			||||||
 | 
					  }, | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					</script> | 
				
			||||||
 | 
					
 | 
				
			||||||
</style> | 
					<style lang="scss" scoped> | 
				
			||||||
 | 
					.elCascader { | 
				
			||||||
 | 
					  width: 290px; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					.history { | 
				
			||||||
 | 
					  width: 100%; | 
				
			||||||
 | 
					  display: flex; | 
				
			||||||
 | 
					  flex-direction: row; | 
				
			||||||
 | 
					  align-items: center; | 
				
			||||||
 | 
					  flex-wrap: wrap; | 
				
			||||||
 | 
					  .history-li { | 
				
			||||||
 | 
					    background-color: rgb(38, 64, 99); | 
				
			||||||
 | 
					    width: calc(49% - 20px); | 
				
			||||||
 | 
					    height: 330px; | 
				
			||||||
 | 
					    margin: 0 10px; | 
				
			||||||
 | 
					    padding: 20px; | 
				
			||||||
 | 
					    border-radius: 20px; | 
				
			||||||
 | 
					    margin-bottom: 20px; | 
				
			||||||
 | 
					    .history-top { | 
				
			||||||
 | 
					      width: 100%; | 
				
			||||||
 | 
					      display: flex; | 
				
			||||||
 | 
					      flex-direction: row; | 
				
			||||||
 | 
					      align-items: center; | 
				
			||||||
 | 
					      justify-content: space-between; | 
				
			||||||
 | 
					      .room { | 
				
			||||||
 | 
					        font-family: Arial, sans-serif; | 
				
			||||||
 | 
					        font-size: 20px; | 
				
			||||||
 | 
					        font-weight: bold; | 
				
			||||||
 | 
					        color: #00aaff; | 
				
			||||||
 | 
					        text-shadow: 0 0 5px rgba(0, 170, 255, 0.5); | 
				
			||||||
 | 
					      } | 
				
			||||||
 | 
					      .change { | 
				
			||||||
 | 
					        cursor: pointer; | 
				
			||||||
 | 
					        width: 30px; | 
				
			||||||
 | 
					        height: 30px; | 
				
			||||||
 | 
					        border-radius: 50%; | 
				
			||||||
 | 
					        background-color: #00aaff; | 
				
			||||||
 | 
					        display: flex; | 
				
			||||||
 | 
					        flex-direction: column; | 
				
			||||||
 | 
					        align-items: center; | 
				
			||||||
 | 
					        justify-content: center; | 
				
			||||||
 | 
					      } | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    .title { | 
				
			||||||
 | 
					      width: 100%; | 
				
			||||||
 | 
					      font-size: 15px; | 
				
			||||||
 | 
					      color: #fff; | 
				
			||||||
 | 
					      font-weight: bold; | 
				
			||||||
 | 
					      margin: 10px 0; | 
				
			||||||
 | 
					      text-align: center; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					  .oneClass { | 
				
			||||||
 | 
					    width: 100% !important; | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					</style> | 
				
			||||||
 | 
				
			|||||||
					Loading…
					
					
				
		Reference in new issue