zhangwencui
5 小时以前 278151dbbe700c6fcbe918fd9014752cf6a480c0
src/views/reportAnalysis/unitEnergyConsumption/index.vue
@@ -4,22 +4,19 @@
    <div class="search_form">
      <el-form :model="searchForm"
               :inline="true">
        <el-form-item label="年份:">
          <el-select v-model="searchForm.year"
                     placeholder="请选择年份"
                     style="width: 120px;"
                     @change="handleQuery">
            <el-option v-for="year in years"
                       :key="year"
                       :label="year + '年'"
                       :value="year" />
          </el-select>
        <el-form-item label="统计维度:">
          <el-radio-group v-model="statisticsType"
                          @change="handleTypeChange">
            <el-radio-button label="day">按日统计</el-radio-button>
            <el-radio-button label="month">按月统计</el-radio-button>
            <el-radio-button label="year">按年统计</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="能耗类型:">
        <!-- <el-form-item label="能耗类型:">
          <el-select v-model="searchForm.energyType"
                     placeholder="全部"
                     clearable
                     style="width: 140px;"
                     style="width: 120px;"
                     @change="handleQuery">
            <el-option label="全部"
                       value="全部" />
@@ -29,6 +26,36 @@
                       value="电" />
            <el-option label="蒸汽"
                       value="蒸汽" />
          </el-select>
        </el-form-item> -->
        <el-form-item label="时间范围:">
          <el-date-picker v-if="statisticsType === 'day'"
                          v-model="searchForm.dateRange"
                          type="daterange"
                          range-separator="至"
                          start-placeholder="开始日期"
                          end-placeholder="结束日期"
                          value-format="YYYY-MM-DD"
                          style="width: 240px;"
                          @change="handleQuery" />
          <el-date-picker v-else-if="statisticsType === 'month'"
                          v-model="searchForm.monthRange"
                          type="monthrange"
                          range-separator="至"
                          start-placeholder="开始月份"
                          end-placeholder="结束月份"
                          value-format="YYYY-MM"
                          style="width: 240px;"
                          @change="handleQuery" />
          <el-select v-else
                     v-model="searchForm.year"
                     placeholder="选择年份"
                     style="width: 140px;"
                     @change="handleQuery">
            <el-option v-for="year in yearOptions"
                       :key="year"
                       :label="year + '年'"
                       :value="year" />
          </el-select>
        </el-form-item>
        <el-form-item>
@@ -63,54 +90,47 @@
        </el-icon>
        能耗单耗数据
      </h2>
      <el-table :data="tableData"
      <el-table :data="tableValue"
                v-loading="tableLoading"
                border>
        <el-table-column prop="energyType"
                         label="能耗"
                         width="100"
        <el-table-column prop="meterReadingDate"
                         label="日期"
                         align="center" />
        <!-- <el-table-column prop="type"
                         label="类型"
                         align="center"
                         width="100">
          <template #default="scope">
            <el-tag :type="scope.row.type === '生产' ? 'primary' : 'success'">
              {{ scope.row.type }}
            </el-tag>
          </template>
        </el-table-column> -->
        <el-table-column prop="energyTyep"
                         label="能耗类型"
                         align="center">
          <template #default="scope">
            <el-tag :type="getEnergyTypeType(scope.row.energyType)">
              {{ scope.row.energyType }}
            <el-tag :type="getEnergyTypeType(scope.row.type)">
              {{ scope.row.type }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="unit"
                         label="单位"
                         width="120"
                         align="center" />
        <el-table-column label="月度数据">
          <el-table-column prop="monthlyUnitConsumption"
                           label="月度累计单耗"
                           align="right">
            <template #default="scope">
              <span class="data-value">{{ scope.row.monthlyUnitConsumption }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="monthlyConsumption"
                           label="月度累计用量/月度累计产量"
                           align="right">
            <template #default="scope">
              <span class="data-value">{{ scope.row.monthlyConsumption }}/{{ scope.row.monthlyProduction }}</span>
            </template>
          </el-table-column>
        <el-table-column prop="consumption"
                         label="用量"
                         align="right" />
        <el-table-column prop="cost"
                         label="成本"
                         align="right">
          <template #default="scope">
            <span class="data-value">¥{{ scope.row.cost }}</span>
          </template>
        </el-table-column>
        <el-table-column label="年度数据">
          <el-table-column prop="annualUnitConsumption"
                           label="年度累计单耗"
                           align="right">
            <template #default="scope">
              <span class="data-value">{{ scope.row.annualUnitConsumption }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="annualConsumption"
                           label="年度累计用量/年度累计产量"
                           align="right">
            <template #default="scope">
              <span class="data-value">{{ scope.row.annualConsumption }}/{{ scope.row.annualProduction }}</span>
            </template>
          </el-table-column>
        <el-table-column prop="unitConsumption"
                         label="单耗"
                         align="right">
          <template #default="scope">
            <span class="data-value">{{ scope.row.unitConsumption }}</span>
          </template>
        </el-table-column>
      </el-table>
    </div>
@@ -122,19 +142,58 @@
  import { ElMessage } from "element-plus";
  import { TrendCharts, List } from "@element-plus/icons-vue";
  import * as echarts from "echarts";
  import { energyConsumptionDetailStatistics } from "@/api/energyManagement/energyType";
  // 统计维度
  const statisticsType = ref("day");
  // 搜索表单
  const searchForm = reactive({
    year: new Date().getFullYear(),
    energyType: "",
    dateRange: null,
    monthRange: null,
    year: new Date().getFullYear(),
  });
  // 生成年份选项
  const years = [];
  // 生成年份选项(最近7年)
  const yearOptions = [];
  const currentYear = new Date().getFullYear();
  for (let i = currentYear - 5; i <= currentYear; i++) {
    years.push(i);
  for (let i = currentYear - 6; i <= currentYear; i++) {
    yearOptions.push(i);
  }
  // 处理统计维度变化
  const handleTypeChange = () => {
    // 重置时间选择
    if (statisticsType.value === "day") {
      // 设置默认日期范围为最近30天
      const end = new Date();
      const start = new Date();
      start.setDate(start.getDate() - 29);
      searchForm.dateRange = [
        `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(start.getDate()).padStart(2, "0")}`,
        `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(end.getDate()).padStart(2, "0")}`,
      ];
    } else if (statisticsType.value === "month") {
      // 设置默认月份范围为最近6个月
      const end = new Date();
      const start = new Date();
      start.setMonth(start.getMonth() - 5);
      searchForm.monthRange = [
        `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, "0")}`,
        `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, "0")}`,
      ];
    } else {
      searchForm.year = currentYear;
    }
    handleQuery();
  };
  // 表格数据
  const tableData = ref([]);
@@ -167,49 +226,110 @@
  // 更新图表
  const updateChart = () => {
    const data = tableData.value;
    const months = [
      "1月",
      "2月",
      "3月",
      "4月",
      "5月",
      "6月",
      "7月",
      "8月",
      "9月",
      "10月",
      "11月",
      "12月",
    ];
    let xAxisData = [];
    // 准备图表数据
    const series = [];
    const energyTypes = ["水", "电", "蒸汽"];
    // 根据统计维度准备数据
    if (statisticsType.value === "year") {
      // 年度模式:12个月
      xAxisData = [
        "1月",
        "2月",
        "3月",
        "4月",
        "5月",
        "6月",
        "7月",
        "8月",
        "9月",
        "10月",
        "11月",
        "12月",
      ];
    } else if (statisticsType.value === "month") {
      // 月度模式:根据选择的月份范围
      if (searchForm.monthRange && searchForm.monthRange.length === 2) {
        const startMonth = searchForm.monthRange[0];
        const endMonth = searchForm.monthRange[1];
        const [startYear, startMonthNum] = startMonth.split("-");
        const [endYear, endMonthNum] = endMonth.split("-");
    energyTypes.forEach(type => {
      const typeData = data.find(item => item.energyType === type);
      if (typeData && typeData.monthlyData) {
        series.push({
          name: type,
          type: "line",
          data: typeData.monthlyData.map(item => item.unitConsumption),
          smooth: true,
          symbol: "circle",
          symbolSize: 8,
          lineStyle: {
            width: 3,
          },
          itemStyle: {
            color:
              getEnergyTypeType(type) === "primary"
                ? "#409EFF"
                : getEnergyTypeType(type) === "warning"
                ? "#E6A23C"
                : "#67C23A",
          },
        });
        xAxisData = [];
        let currentYear = parseInt(startYear);
        let currentMonth = parseInt(startMonthNum);
        const endYearInt = parseInt(endYear);
        const endMonthInt = parseInt(endMonthNum);
        while (
          currentYear < endYearInt ||
          (currentYear === endYearInt && currentMonth <= endMonthInt)
        ) {
          xAxisData.push(
            `${currentYear}-${String(currentMonth).padStart(2, "0")}`
          );
          currentMonth++;
          if (currentMonth > 12) {
            currentMonth = 1;
            currentYear++;
          }
        }
      } else {
        // 默认显示最近6个月
        xAxisData = [];
        const end = new Date();
        for (let i = 5; i >= 0; i--) {
          const date = new Date();
          date.setMonth(date.getMonth() - i);
          xAxisData.push(
            `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(
              2,
              "0"
            )}`
          );
        }
      }
    });
    } else {
      // 按日统计:根据选择的日期范围
      if (searchForm.dateRange && searchForm.dateRange.length === 2) {
        const startDate = searchForm.dateRange[0];
        const endDate = searchForm.dateRange[1];
        xAxisData = [];
        let currentDate = new Date(startDate);
        const end = new Date(endDate);
        while (currentDate <= end) {
          xAxisData.push(
            `${currentDate.getFullYear()}-${String(
              currentDate.getMonth() + 1
            ).padStart(2, "0")}-${String(currentDate.getDate()).padStart(2, "0")}`
          );
          currentDate.setDate(currentDate.getDate() + 1);
        }
      } else {
        // 默认显示最近30天
        xAxisData = [];
        const end = new Date();
        for (let i = 29; i >= 0; i--) {
          const date = new Date();
          date.setDate(date.getDate() - i);
          xAxisData.push(
            `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(
              2,
              "0"
            )}-${String(date.getDate()).padStart(2, "0")}`
          );
        }
      }
    }
    // 提取所有唯一的meterReadingDate并排序
    const allDates = [...new Set(data.map(item => item.meterReadingDate))].sort(
      (a, b) => {
        return new Date(a) - new Date(b);
      }
    );
    // 使用实际的meterReadingDate作为横轴数据
    xAxisData = allDates;
    const option = {
      tooltip: {
@@ -220,7 +340,7 @@
        textStyle: { color: "#303133" },
      },
      legend: {
        data: energyTypes,
        data: ["单耗"],
        top: 0,
        right: 10,
        textStyle: { color: "#606266" },
@@ -234,8 +354,11 @@
      },
      xAxis: {
        type: "category",
        data: months,
        axisLabel: { color: "#606266" },
        data: xAxisData,
        axisLabel: {
          color: "#606266",
          rotate: statisticsType.value === "month" ? 45 : 0,
        },
        axisLine: { lineStyle: { color: "#ebeef5" } },
        splitLine: { show: false },
      },
@@ -247,28 +370,152 @@
        axisLine: { show: false },
        splitLine: { lineStyle: { color: "#f0f2f5" } },
      },
      series: series,
      series: {
        name: "单耗",
        type: "line",
        data: data.map(item => item.totalCost),
        smooth: true,
        symbol: "circle",
        symbolSize: 8,
        lineStyle: {
          width: 3,
        },
        itemStyle: {
          color: "#409EFF",
        },
      },
    };
    consumptionChartInstance.setOption(option);
  };
  const tableValue = ref([]);
  // 查询
  const handleQuery = () => {
    tableLoading.value = true;
    // 模拟接口调用
    setTimeout(() => {
      generateMockData();
      tableLoading.value = false;
      updateChart();
    }, 500);
    const params = {
      type: "",
      state:
        statisticsType.value === "year"
          ? "年"
          : statisticsType.value === "month"
          ? "月"
          : "日",
    };
    if (searchForm.energyType && searchForm.energyType !== "全部") {
      params.type = searchForm.energyType;
    }
    if (statisticsType.value === "year") {
      params.startDate = searchForm.year + "-01-01";
      params.endDate = searchForm.year + "-12-31";
      // 计算天数
      const start = new Date(params.startDate);
      const end = new Date(params.endDate);
      params.days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
    } else if (statisticsType.value === "month" && searchForm.monthRange) {
      const [startMonth, endMonth] = searchForm.monthRange;
      const [startYearStr, startMonthStr] = startMonth.split("-");
      const [endYearStr, endMonthStr] = endMonth.split("-");
      params.startDate = `${startYearStr}-${startMonthStr}-01`;
      const endYear = Number(endYearStr);
      const endMonthNum = Number(endMonthStr);
      const lastDay = new Date(endYear, endMonthNum, 0).getDate();
      params.endDate = `${endYearStr}-${endMonthStr}-${String(lastDay).padStart(
        2,
        "0"
      )}`;
      // 计算天数
      const start = new Date(params.startDate);
      const end = new Date(params.endDate);
      params.days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
    } else if (statisticsType.value === "day" && searchForm.dateRange) {
      params.startDate = searchForm.dateRange[0];
      params.endDate = searchForm.dateRange[1];
      // 计算天数
      const start = new Date(params.startDate);
      const end = new Date(params.endDate);
      params.days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
    }
    energyConsumptionDetailStatistics(params)
      .then(res => {
        if (res.code === 200) {
          const data = res.data;
          tableData.value = data.energyCostDtos || [];
          tableValue.value = [];
          tableData.value.forEach(item => {
            tableValue.value.push({
              meterReadingDate: item.meterReadingDate,
              consumption: item.waterConsumption,
              cost: item.waterCost,
              type: "水",
            });
            tableValue.value.push({
              consumption: item.electricityConsumption,
              cost: item.electricityCost,
              meterReadingDate: item.meterReadingDate,
              type: "电",
            });
            tableValue.value.push({
              consumption: item.gasConsumption,
              cost: item.gasCost,
              meterReadingDate: item.meterReadingDate,
              type: "蒸汽",
            });
          });
          updateChart();
        } else {
          ElMessage.error(res.message || "获取数据失败");
          tableData.value = [];
        }
      })
      .catch(err => {
        console.error("获取数据异常:", err);
        ElMessage.error("系统异常,获取数据失败");
        tableData.value = [];
      })
      .finally(() => {
        tableLoading.value = false;
      });
  };
  // 重置
  const handleReset = () => {
    searchForm.year = new Date().getFullYear();
    // 重置搜索表单
    searchForm.energyType = "";
    if (statisticsType.value === "day") {
      // 设置默认日期范围为最近30天
      const end = new Date();
      const start = new Date();
      start.setDate(start.getDate() - 29);
      searchForm.dateRange = [
        `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(start.getDate()).padStart(2, "0")}`,
        `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(end.getDate()).padStart(2, "0")}`,
      ];
    } else if (statisticsType.value === "month") {
      // 设置默认月份范围为最近6个月
      const end = new Date();
      const start = new Date();
      start.setMonth(start.getMonth() - 5);
      searchForm.monthRange = [
        `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, "0")}`,
        `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, "0")}`,
      ];
    } else {
      searchForm.year = new Date().getFullYear();
    }
    handleQuery();
  };
@@ -277,71 +524,38 @@
    ElMessage.success("报表导出成功");
  };
  // 生成假数据
  const generateMockData = () => {
    const energyTypes = [
      {
        energyType: "水",
        unit: "吨/立方米",
        monthlyUnitConsumption: (Math.random() * 0.5 + 0.8).toFixed(4),
        monthlyConsumption: Math.floor(Math.random() * 5000 + 10000),
        monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
        annualUnitConsumption: (Math.random() * 0.3 + 0.9).toFixed(4),
        annualConsumption: Math.floor(Math.random() * 60000 + 120000),
        annualProduction: Math.floor(Math.random() * 120000 + 240000),
        monthlyData: generateMonthlyData(0.8, 1.3),
      },
      {
        energyType: "电",
        unit: "度/立方米",
        monthlyUnitConsumption: (Math.random() * 2 + 5).toFixed(4),
        monthlyConsumption: Math.floor(Math.random() * 50000 + 100000),
        monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
        annualUnitConsumption: (Math.random() * 1.5 + 5.5).toFixed(4),
        annualConsumption: Math.floor(Math.random() * 600000 + 1200000),
        annualProduction: Math.floor(Math.random() * 120000 + 240000),
        monthlyData: generateMonthlyData(5, 7),
      },
      {
        energyType: "蒸汽",
        unit: "吨/立方米",
        monthlyUnitConsumption: (Math.random() * 0.3 + 0.5).toFixed(4),
        monthlyConsumption: Math.floor(Math.random() * 3000 + 6000),
        monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
        annualUnitConsumption: (Math.random() * 0.2 + 0.55).toFixed(4),
        annualConsumption: Math.floor(Math.random() * 36000 + 72000),
        annualProduction: Math.floor(Math.random() * 120000 + 240000),
        monthlyData: generateMonthlyData(0.5, 0.8),
      },
    ];
    if (searchForm.energyType && searchForm.energyType !== "全部") {
      tableData.value = energyTypes.filter(
        item => item.energyType === searchForm.energyType
      );
    } else {
      tableData.value = energyTypes;
    }
  };
  // 生成月度数据
  const generateMonthlyData = (min, max) => {
    const data = [];
    for (let i = 1; i <= 12; i++) {
      data.push({
        month: i,
        unitConsumption: (Math.random() * (max - min) + min).toFixed(4),
      });
    }
    return data;
  };
  // 窗口大小变化时重新渲染图表
  const handleResize = () => {
    consumptionChartInstance && consumptionChartInstance.resize();
  };
  onMounted(() => {
    // 初始化时间范围
    if (statisticsType.value === "day") {
      // 设置默认日期范围为最近30天
      const end = new Date();
      const start = new Date();
      start.setDate(start.getDate() - 29);
      searchForm.dateRange = [
        `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(start.getDate()).padStart(2, "0")}`,
        `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(
          2,
          "0"
        )}-${String(end.getDate()).padStart(2, "0")}`,
      ];
    } else if (statisticsType.value === "month") {
      // 设置默认月份范围为最近6个月
      const end = new Date();
      const start = new Date();
      start.setMonth(start.getMonth() - 5);
      searchForm.monthRange = [
        `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, "0")}`,
        `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, "0")}`,
      ];
    }
    handleQuery();
    initChart();
    window.addEventListener("resize", handleResize);