From 108a4fb5ce13ed06596f7e125e59632e76aafa58 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 10 三月 2026 18:00:37 +0800
Subject: [PATCH] 能耗管理模块

---
 src/api/productionPlan/productionPlan.js                          |   11 
 src/api/energyManagement/energyType.js                            |   53 
 src/views/energyManagement/energyType/index2.vue                  |  697 +++++++++++
 src/views/productionPlan/productionPlan/index.vue                 |  735 ++++++++---
 src/views/energyManagement/officeEnergyConsumption/index.vue      |  696 +++++++++++
 src/views/energyManagement/energyConsumptionStatistical/index.vue |  874 +++++++++++++
 src/views/energyManagement/productionEnergyConsumption/index.vue  |  696 +++++++++++
 7 files changed, 3,556 insertions(+), 206 deletions(-)

diff --git a/src/api/energyManagement/energyType.js b/src/api/energyManagement/energyType.js
new file mode 100644
index 0000000..43b8066
--- /dev/null
+++ b/src/api/energyManagement/energyType.js
@@ -0,0 +1,53 @@
+// 鑳借�楃被鍨�
+import request from "@/utils/request";
+
+// 鑳借�楃被鍨�-鍒嗛〉鏌ヨ
+export function energyTypeListPage(query) {
+  return request({
+    url: "/energy/page",
+    method: "get",
+    params: query,
+  });
+}
+// 鑳借�楃被鍨�-鏂板淇敼
+export function energyTypeAdd(query) {
+  return request({
+    url: "/energy",
+    method: "post",
+    data: query,
+  });
+}
+
+// 鑳借�楃被鍨�-鍒犻櫎
+export function energyTypeDelete(ids) {
+  return request({
+    url: "/energy/" + ids,
+    method: "delete",
+  });
+}
+
+// 鑳借�楁妱琛ㄦ槑缁�
+export function energyConsumptionDetailListPage(query) {
+  return request({
+    url: "/energyConsumptionDetail/page",
+    method: "get",
+    params: query,
+  });
+}
+// 鑳借�楁妱琛ㄦ槑缁�-鏂板淇敼
+export function energyConsumptionDetailAdd(query) {
+  return request({
+    url: "/energyConsumptionDetail",
+    method: "post",
+    data: query,
+  });
+}
+
+
+// 鑳借�楁妱琛ㄦ槑缁�-鍒犻櫎
+export function energyConsumptionDetailDelete(ids) {
+  return request({
+    url: "/energyConsumptionDetail/" + ids,
+    method: "delete",
+  });
+}
\ No newline at end of file
diff --git a/src/api/productionPlan/productionPlan.js b/src/api/productionPlan/productionPlan.js
new file mode 100644
index 0000000..2b08129
--- /dev/null
+++ b/src/api/productionPlan/productionPlan.js
@@ -0,0 +1,11 @@
+// 鐢熶骇璁㈠崟椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+
+export function productionPlanListPage(query) {
+  return request({
+    url: "/productionPlan/listPage",
+    method: "get",
+    params: query,
+  });
+}
diff --git a/src/views/energyManagement/energyConsumptionStatistical/index.vue b/src/views/energyManagement/energyConsumptionStatistical/index.vue
new file mode 100644
index 0000000..9363511
--- /dev/null
+++ b/src/views/energyManagement/energyConsumptionStatistical/index.vue
@@ -0,0 +1,874 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储鍖哄煙 -->
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <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-select v-model="searchForm.energyType"
+                     placeholder="鍏ㄩ儴"
+                     clearable
+                     style="width: 120px;"
+                     @change="handleQuery">
+            <el-option label="鍏ㄩ儴"
+                       value="鍏ㄩ儴" />
+            <el-option label="鍔炲叕"
+                       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>
+          <el-button type="primary"
+                     @click="handleQuery">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button type="success"
+                   @click="handleExport">瀵煎嚭鎶ヨ〃</el-button>
+      </div>
+    </div>
+    <!-- 缁熻姒傝鍗$墖 -->
+    <div class="statistics-overview">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <div class="overview-card total-consumption">
+            <div class="overview-icon">
+              <el-icon>
+                <DataLine />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">鎬昏兘鑰楃敤閲�</div>
+              <div class="overview-value">{{ overview.totalConsumption }} <span class="unit">鍚�/搴�/m鲁</span></div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="overview-card total-amount">
+            <div class="overview-icon">
+              <el-icon>
+                <Money />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">鎬昏兘鑰楄垂鐢�</div>
+              <div class="overview-value">楼{{ overview.totalAmount }}</div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="overview-card avg-consumption">
+            <div class="overview-icon">
+              <el-icon>
+                <TrendCharts />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">骞冲潎鐢ㄩ噺</div>
+              <div class="overview-value">{{ overview.avgConsumption }} <span class="unit">/{{ statisticsType === 'day' ? '鏃�' : statisticsType === 'month' ? '鏈�' : '骞�' }}</span></div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <div class="overview-card compare-last">
+            <div class="overview-icon">
+              <el-icon>
+                <Histogram />
+              </el-icon>
+            </div>
+            <div class="overview-info">
+              <div class="overview-label">鐜瘮鍙樺寲</div>
+              <div class="overview-value"
+                   :class="overview.compareRate >= 0 ? 'up' : 'down'">
+                <el-icon v-if="overview.compareRate >= 0">
+                  <ArrowUp />
+                </el-icon>
+                <el-icon v-else>
+                  <ArrowDown />
+                </el-icon>
+                {{ Math.abs(overview.compareRate) }}%
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+    <!-- 鍥捐〃鍖哄煙 -->
+    <div class="charts-container">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楃敤閲忚秼鍔�</div>
+            <div ref="consumptionChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楄垂鐢ㄨ秼鍔�</div>
+            <div ref="amountChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+      </el-row>
+      <el-row :gutter="20"
+              style="margin-top: 20px;">
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楃被鍨嬪崰姣�</div>
+            <div ref="typeChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card">
+            <div class="chart-title">鑳借�楃被鍨嬭垂鐢ㄥ崰姣�</div>
+            <div ref="amountTypeChart"
+                 class="chart-content"></div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <div class="table-section">
+      <div class="section-title">璇︾粏鏁版嵁</div>
+      <el-table :data="tableData"
+                v-loading="tableLoading"
+                border
+                stripe>
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column prop="timePeriod"
+                         :label="timeColumnLabel"
+                         align="center" />
+        <el-table-column prop="waterConsumption"
+                         label="鐢ㄦ按閲�(鍚�)"
+                         align="right">
+          <template #default="scope">
+            <span class="consumption-value">{{ scope.row.waterConsumption }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="waterAmount"
+                         label="姘磋垂(鍏�)"
+                         align="right">
+          <template #default="scope">
+            <span class="amount-value">{{ scope.row.waterAmount }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="electricityConsumption"
+                         label="鐢ㄧ數閲�(搴�)"
+                         align="right">
+          <template #default="scope">
+            <span class="consumption-value">{{ scope.row.electricityConsumption }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="electricityAmount"
+                         label="鐢佃垂(鍏�)"
+                         align="right">
+          <template #default="scope">
+            <span class="amount-value">{{ scope.row.electricityAmount }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="gasConsumption"
+                         label="鐢ㄦ皵閲�(m鲁)"
+                         align="right">
+          <template #default="scope">
+            <span class="consumption-value">{{ scope.row.gasConsumption }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="gasAmount"
+                         label="姘旇垂(鍏�)"
+                         align="right">
+          <template #default="scope">
+            <span class="amount-value">{{ scope.row.gasAmount }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="totalConsumption"
+                         label="鍚堣鐢ㄩ噺"
+                         align="right">
+          <template #default="scope">
+            <span class="total-value">{{ scope.row.totalConsumption }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="totalAmount"
+                         label="鍚堣璐圭敤(鍏�)"
+                         align="right"
+                         fixed="right">
+          <template #default="scope">
+            <span class="total-amount-value">楼{{ scope.row.totalAmount }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- 鍒嗛〉 -->
+    <div class="pagination-container">
+      <el-pagination v-model:current-page="page.current"
+                     v-model:page-size="page.size"
+                     :page-sizes="[10, 20, 50, 100]"
+                     :total="page.total"
+                     layout="total, sizes, prev, pager, next, jumper"
+                     @size-change="handleSizeChange"
+                     @current-change="handleCurrentChange" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted, computed, nextTick } from "vue";
+  import { ElMessage } from "element-plus";
+  import {
+    DataLine,
+    Money,
+    TrendCharts,
+    Histogram,
+    ArrowUp,
+    ArrowDown,
+  } from "@element-plus/icons-vue";
+  import * as echarts from "echarts";
+
+  // 缁熻缁村害锛歞ay-鎸夋棩锛宮onth-鎸夋湀锛寉ear-鎸夊勾
+  const statisticsType = ref("day");
+
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    energyType: "",
+    dateRange: [],
+    monthRange: [],
+    year: new Date().getFullYear(),
+  });
+
+  // 骞翠唤閫夐」
+  const yearOptions = computed(() => {
+    const currentYear = new Date().getFullYear();
+    const years = [];
+    for (let i = currentYear - 5; i <= currentYear; i++) {
+      years.push(i);
+    }
+    return years.reverse();
+  });
+
+  // 鏃堕棿鍒楁爣绛�
+  const timeColumnLabel = computed(() => {
+    const labels = {
+      day: "鏃ユ湡",
+      month: "鏈堜唤",
+      year: "骞翠唤",
+    };
+    return labels[statisticsType.value];
+  });
+
+  // 缁熻姒傝
+  const overview = reactive({
+    totalConsumption: "25,680.5",
+    totalAmount: "45,280.60",
+    avgConsumption: "856.0",
+    compareRate: -5.2,
+  });
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 鍥捐〃寮曠敤
+  const consumptionChart = ref(null);
+  const amountChart = ref(null);
+  const typeChart = ref(null);
+  const amountTypeChart = ref(null);
+
+  // 鍥捐〃瀹炰緥
+  let consumptionChartInstance = null;
+  let amountChartInstance = null;
+  let typeChartInstance = null;
+  let amountTypeChartInstance = null;
+
+  // 鐢熸垚妯℃嫙鏁版嵁
+  const generateMockData = () => {
+    const data = [];
+    const count =
+      statisticsType.value === "day"
+        ? 30
+        : statisticsType.value === "month"
+        ? 12
+        : 5;
+
+    for (let i = 0; i < count; i++) {
+      const waterConsumption = (Math.random() * 100 + 50).toFixed(2);
+      const waterAmount = (waterConsumption * 2.5).toFixed(2);
+      const electricityConsumption = (Math.random() * 500 + 200).toFixed(2);
+      const electricityAmount = (electricityConsumption * 0.8).toFixed(2);
+      const gasConsumption = (Math.random() * 200 + 100).toFixed(2);
+      const gasAmount = (gasConsumption * 3.0).toFixed(2);
+
+      let timePeriod;
+      if (statisticsType.value === "day") {
+        const date = new Date();
+        date.setDate(date.getDate() - i);
+        timePeriod = date.toISOString().split("T")[0];
+      } else if (statisticsType.value === "month") {
+        const date = new Date();
+        date.setMonth(date.getMonth() - i);
+        timePeriod = date.toISOString().slice(0, 7);
+      } else {
+        timePeriod = (new Date().getFullYear() - i).toString();
+      }
+
+      data.push({
+        timePeriod,
+        waterConsumption,
+        waterAmount,
+        electricityConsumption,
+        electricityAmount,
+        gasConsumption,
+        gasAmount,
+        totalConsumption: (
+          parseFloat(waterConsumption) +
+          parseFloat(electricityConsumption) +
+          parseFloat(gasConsumption)
+        ).toFixed(2),
+        totalAmount: (
+          parseFloat(waterAmount) +
+          parseFloat(electricityAmount) +
+          parseFloat(gasAmount)
+        ).toFixed(2),
+      });
+    }
+    return data.reverse();
+  };
+
+  // 鍒濆鍖栧浘琛�
+  const initCharts = () => {
+    nextTick(() => {
+      // 鑳借�楃敤閲忚秼鍔垮浘
+      if (consumptionChart.value) {
+        consumptionChartInstance = echarts.init(consumptionChart.value);
+        updateConsumptionChart();
+      }
+      // 鑳借�楄垂鐢ㄨ秼鍔垮浘
+      if (amountChart.value) {
+        amountChartInstance = echarts.init(amountChart.value);
+        updateAmountChart();
+      }
+      // 鑳借�楃被鍨嬪崰姣斿浘
+      if (typeChart.value) {
+        typeChartInstance = echarts.init(typeChart.value);
+        updateTypeChart();
+      }
+      // 鑳借�楃被鍨嬭垂鐢ㄥ崰姣斿浘
+      if (amountTypeChart.value) {
+        amountTypeChartInstance = echarts.init(amountTypeChart.value);
+        updateAmountTypeChart();
+      }
+    });
+  };
+
+  // 鏇存柊鑳借�楃敤閲忚秼鍔垮浘
+  const updateConsumptionChart = () => {
+    const data = tableData.value;
+    const option = {
+      tooltip: {
+        trigger: "axis",
+        axisPointer: { type: "cross" },
+      },
+      legend: {
+        data: ["鐢ㄦ按閲�", "鐢ㄧ數閲�", "鐢ㄦ皵閲�"],
+        bottom: 0,
+      },
+      grid: {
+        left: "3%",
+        right: "4%",
+        bottom: "15%",
+        containLabel: true,
+      },
+      xAxis: {
+        type: "category",
+        data: data.map(item => item.timePeriod),
+        axisLabel: { rotate: statisticsType.value === "day" ? 45 : 0 },
+      },
+      yAxis: {
+        type: "value",
+        name: "鐢ㄩ噺",
+      },
+      series: [
+        {
+          name: "鐢ㄦ按閲�",
+          type: "bar",
+          data: data.map(item => item.waterConsumption),
+          itemStyle: { color: "#409EFF" },
+        },
+        {
+          name: "鐢ㄧ數閲�",
+          type: "bar",
+          data: data.map(item => item.electricityConsumption),
+          itemStyle: { color: "#E6A23C" },
+        },
+        {
+          name: "鐢ㄦ皵閲�",
+          type: "bar",
+          data: data.map(item => item.gasConsumption),
+          itemStyle: { color: "#67C23A" },
+        },
+      ],
+    };
+    consumptionChartInstance.setOption(option);
+  };
+
+  // 鏇存柊鑳借�楄垂鐢ㄨ秼鍔垮浘
+  const updateAmountChart = () => {
+    const data = tableData.value;
+    const option = {
+      tooltip: {
+        trigger: "axis",
+        axisPointer: { type: "cross" },
+      },
+      legend: {
+        data: ["姘磋垂", "鐢佃垂", "姘旇垂"],
+        bottom: 0,
+      },
+      grid: {
+        left: "3%",
+        right: "4%",
+        bottom: "15%",
+        containLabel: true,
+      },
+      xAxis: {
+        type: "category",
+        data: data.map(item => item.timePeriod),
+        axisLabel: { rotate: statisticsType.value === "day" ? 45 : 0 },
+      },
+      yAxis: {
+        type: "value",
+        name: "璐圭敤(鍏�)",
+      },
+      series: [
+        {
+          name: "姘磋垂",
+          type: "line",
+          data: data.map(item => item.waterAmount),
+          smooth: true,
+          itemStyle: { color: "#409EFF" },
+        },
+        {
+          name: "鐢佃垂",
+          type: "line",
+          data: data.map(item => item.electricityAmount),
+          smooth: true,
+          itemStyle: { color: "#E6A23C" },
+        },
+        {
+          name: "姘旇垂",
+          type: "line",
+          data: data.map(item => item.gasAmount),
+          smooth: true,
+          itemStyle: { color: "#67C23A" },
+        },
+      ],
+    };
+    amountChartInstance.setOption(option);
+  };
+
+  // 鏇存柊鑳借�楃被鍨嬪崰姣斿浘
+  const updateTypeChart = () => {
+    const data = tableData.value;
+    const totalWater = data.reduce(
+      (sum, item) => sum + parseFloat(item.waterConsumption),
+      0
+    );
+    const totalElectricity = data.reduce(
+      (sum, item) => sum + parseFloat(item.electricityConsumption),
+      0
+    );
+    const totalGas = data.reduce(
+      (sum, item) => sum + parseFloat(item.gasConsumption),
+      0
+    );
+
+    const option = {
+      tooltip: {
+        trigger: "item",
+        formatter: "{a} <br/>{b}: {c} ({d}%)",
+      },
+      legend: {
+        orient: "vertical",
+        left: "left",
+      },
+      series: [
+        {
+          name: "鑳借�楃敤閲�",
+          type: "pie",
+          radius: ["40%", "70%"],
+          avoidLabelOverlap: false,
+          itemStyle: {
+            borderRadius: 10,
+            borderColor: "#fff",
+            borderWidth: 2,
+          },
+          label: {
+            show: true,
+            formatter: "{b}: {d}%",
+          },
+          data: [
+            {
+              value: totalWater.toFixed(2),
+              name: "姘�",
+              itemStyle: { color: "#409EFF" },
+            },
+            {
+              value: totalElectricity.toFixed(2),
+              name: "鐢�",
+              itemStyle: { color: "#E6A23C" },
+            },
+            {
+              value: totalGas.toFixed(2),
+              name: "姘�",
+              itemStyle: { color: "#67C23A" },
+            },
+          ],
+        },
+      ],
+    };
+    typeChartInstance.setOption(option);
+  };
+
+  // 鏇存柊鑳借�楃被鍨嬭垂鐢ㄥ崰姣斿浘
+  const updateAmountTypeChart = () => {
+    const data = tableData.value;
+    const totalWaterAmount = data.reduce(
+      (sum, item) => sum + parseFloat(item.waterAmount),
+      0
+    );
+    const totalElectricityAmount = data.reduce(
+      (sum, item) => sum + parseFloat(item.electricityAmount),
+      0
+    );
+    const totalGasAmount = data.reduce(
+      (sum, item) => sum + parseFloat(item.gasAmount),
+      0
+    );
+
+    const option = {
+      tooltip: {
+        trigger: "item",
+        formatter: "{a} <br/>{b}: 楼{c} ({d}%)",
+      },
+      legend: {
+        orient: "vertical",
+        left: "left",
+      },
+      series: [
+        {
+          name: "鑳借�楄垂鐢�",
+          type: "pie",
+          radius: "60%",
+          data: [
+            {
+              value: totalWaterAmount.toFixed(2),
+              name: "姘磋垂",
+              itemStyle: { color: "#409EFF" },
+            },
+            {
+              value: totalElectricityAmount.toFixed(2),
+              name: "鐢佃垂",
+              itemStyle: { color: "#E6A23C" },
+            },
+            {
+              value: totalGasAmount.toFixed(2),
+              name: "姘旇垂",
+              itemStyle: { color: "#67C23A" },
+            },
+          ],
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: "rgba(0, 0, 0, 0.5)",
+            },
+          },
+        },
+      ],
+    };
+    amountTypeChartInstance.setOption(option);
+  };
+
+  // 缁熻缁村害鍒囨崲
+  const handleTypeChange = () => {
+    // 閲嶇疆鏃堕棿鑼冨洿
+    searchForm.dateRange = [];
+    searchForm.monthRange = [];
+    searchForm.year = new Date().getFullYear();
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 鏌ヨ
+  const handleQuery = () => {
+    tableLoading.value = true;
+    setTimeout(() => {
+      const data = generateMockData();
+      tableData.value = data;
+      page.total = data.length;
+      tableLoading.value = false;
+      updateCharts();
+    }, 300);
+  };
+
+  // 鏇存柊鎵�鏈夊浘琛�
+  const updateCharts = () => {
+    nextTick(() => {
+      if (consumptionChartInstance) updateConsumptionChart();
+      if (amountChartInstance) updateAmountChart();
+      if (typeChartInstance) updateTypeChart();
+      if (amountTypeChartInstance) updateAmountTypeChart();
+    });
+  };
+
+  // 閲嶇疆
+  const handleReset = () => {
+    searchForm.energyType = "";
+    searchForm.dateRange = [];
+    searchForm.monthRange = [];
+    searchForm.year = new Date().getFullYear();
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 瀵煎嚭
+  const handleExport = () => {
+    ElMessage.success("鎶ヨ〃瀵煎嚭鎴愬姛");
+  };
+
+  // 鍒嗛〉澶у皬鍙樺寲
+  const handleSizeChange = val => {
+    page.size = val;
+  };
+
+  // 椤电爜鍙樺寲
+  const handleCurrentChange = val => {
+    page.current = val;
+  };
+
+  // 绐楀彛澶у皬鍙樺寲鏃堕噸鏂版覆鏌撳浘琛�
+  const handleResize = () => {
+    consumptionChartInstance && consumptionChartInstance.resize();
+    amountChartInstance && amountChartInstance.resize();
+    typeChartInstance && typeChartInstance.resize();
+    amountTypeChartInstance && amountTypeChartInstance.resize();
+  };
+
+  onMounted(() => {
+    handleQuery();
+    initCharts();
+    window.addEventListener("resize", handleResize);
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 20px;
+  }
+
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+    padding: 15px;
+    background-color: #f5f7fa;
+    border-radius: 8px;
+  }
+
+  .statistics-overview {
+    margin-bottom: 20px;
+  }
+
+  .overview-card {
+    display: flex;
+    align-items: center;
+    padding: 20px;
+    border-radius: 8px;
+    background: #fff;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+    &.total-consumption {
+      border-left: 4px solid #409eff;
+    }
+
+    &.total-amount {
+      border-left: 4px solid #67c23a;
+    }
+
+    &.avg-consumption {
+      border-left: 4px solid #e6a23c;
+    }
+
+    &.compare-last {
+      border-left: 4px solid #909399;
+    }
+
+    .overview-icon {
+      width: 50px;
+      height: 50px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      background: #f5f7fa;
+      border-radius: 50%;
+      margin-right: 15px;
+
+      .el-icon {
+        font-size: 24px;
+        color: #409eff;
+      }
+    }
+
+    .overview-info {
+      flex: 1;
+
+      .overview-label {
+        font-size: 14px;
+        color: #909399;
+        margin-bottom: 5px;
+      }
+
+      .overview-value {
+        font-size: 24px;
+        font-weight: bold;
+        color: #303133;
+
+        .unit {
+          font-size: 14px;
+          font-weight: normal;
+          color: #909399;
+        }
+
+        &.up {
+          color: #67c23a;
+        }
+
+        &.down {
+          color: #f56c6c;
+        }
+
+        .el-icon {
+          font-size: 16px;
+          vertical-align: middle;
+        }
+      }
+    }
+  }
+
+  .charts-container {
+    margin-bottom: 20px;
+  }
+
+  .chart-card {
+    background: #fff;
+    border-radius: 8px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    padding: 20px;
+
+    .chart-title {
+      font-size: 16px;
+      font-weight: bold;
+      color: #303133;
+      margin-bottom: 15px;
+      padding-bottom: 10px;
+      border-bottom: 1px solid #ebeef5;
+    }
+
+    .chart-content {
+      height: 300px;
+    }
+  }
+
+  .table-section {
+    background: #fff;
+    border-radius: 8px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+    padding: 20px;
+    margin-bottom: 20px;
+
+    .section-title {
+      font-size: 16px;
+      font-weight: bold;
+      color: #303133;
+      margin-bottom: 15px;
+      padding-bottom: 10px;
+      border-bottom: 1px solid #ebeef5;
+    }
+  }
+
+  .consumption-value {
+    font-weight: bold;
+    color: #409eff;
+  }
+
+  .amount-value {
+    font-weight: bold;
+    color: #67c23a;
+  }
+
+  .total-value {
+    font-weight: bold;
+    color: #e6a23c;
+  }
+
+  .total-amount-value {
+    font-weight: bold;
+    color: #f56c6c;
+    font-size: 14px;
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+  }
+</style>
diff --git a/src/views/energyManagement/energyType/index2.vue b/src/views/energyManagement/energyType/index2.vue
new file mode 100644
index 0000000..88296a1
--- /dev/null
+++ b/src/views/energyManagement/energyType/index2.vue
@@ -0,0 +1,697 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储鍖哄煙 -->
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <el-form-item label="鑳芥簮绫诲瀷:">
+          <el-select v-model="searchForm.energyTyep"
+                     placeholder="鍏ㄩ儴"
+                     clearable
+                     style="width: 120px;"
+                     @change="handleQuery">
+            <el-option label="姘�"
+                       value="gas" />
+            <el-option label="鐢�"
+                       value="electricity" />
+            <el-option label="姘�"
+                       value="water" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鑳芥簮鍚嶇О:">
+          <el-input v-model="searchForm.energyName"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    style="width: 160px;"
+                    @keyup.enter="handleQuery" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary"
+                     @click="handleQuery">鏌ヨ</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button type="primary"
+                   @click="handleAdd">鏂板</el-button>
+        <!-- <el-button type="success"
+                   @click="handleImport">瀵煎叆</el-button> -->
+        <el-button type="warning"
+                   @click="handleExport">瀵煎嚭</el-button>
+      </div>
+    </div>
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <div class="table_list">
+      <el-table :data="tableData"
+                v-loading="tableLoading"
+                border
+                height="calc(100vh - 350px)"
+                stripe>
+        <el-table-column type="selection"
+                         width="55"
+                         align="center" />
+        <el-table-column prop="energyTyep"
+                         label="鑳芥簮绫诲瀷"
+                         width="100"
+                         align="center">
+          <template #default="scope">
+            <el-tag :type="getEnergyTypeType(scope.row.energyTyep)">
+              {{ scope.row.energyTyep }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="energyName"
+                         label="鑳芥簮鍚嶇О"
+                         align="center" />
+        <el-table-column prop="unitPrice"
+                         label="鍗曚环"
+                         sortable
+                         align="right">
+          <template #default="scope">
+            <span>{{ scope.row.unitPrice }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="澶囨敞"
+                         prop="remark"
+                         align="center" />
+        <el-table-column prop="unit"
+                         label="鍗曚綅"
+                         align="center" />
+        <el-table-column prop="createUserName"
+                         label="鍒涘缓浜�"
+                         align="center" />
+        <el-table-column prop="createTime"
+                         label="鍒涘缓鏃堕棿"
+                         sortable
+                         align="center" />
+        <el-table-column label="鎿嶄綔"
+                         align="center"
+                         fixed="right">
+          <template #default="scope">
+            <el-button type="primary"
+                       link
+                       @click="handleDetail(scope.row)">璇︽儏</el-button>
+            <el-button type="danger"
+                       link
+                       @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+            <el-button type="primary"
+                       link
+                       @click="handleEdit(scope.row)">缂栬緫</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 鍒嗛〉 -->
+      <div class="pagination-container">
+        <el-pagination v-model:current-page="page.current"
+                       v-model:page-size="page.size"
+                       :page-sizes="[10, 20, 50, 100]"
+                       :total="page.total"
+                       layout="total, sizes, prev, pager, next, jumper"
+                       @size-change="handleSizeChange"
+                       @current-change="handleCurrentChange" />
+      </div>
+    </div>
+    <!-- 鏂板/缂栬緫寮圭獥 -->
+    <el-dialog v-model="dialogVisible"
+               :title="dialogTitle"
+               width="600px">
+      <el-form :model="form"
+               :rules="rules"
+               ref="formRef"
+               label-width="100px">
+        <el-form-item label="鑳芥簮鍚嶇О"
+                      prop="energyName">
+          <el-input v-model="form.energyName"
+                    placeholder="璇疯緭鍏�" />
+        </el-form-item>
+        <el-form-item label="鑳芥簮绫诲瀷"
+                      prop="energyTyep">
+          <el-select v-model="form.energyTyep"
+                     placeholder="璇烽�夋嫨"
+                     style="width: 100%;">
+            <el-option label="姘�"
+                       value="姘�" />
+            <el-option label="鐢�"
+                       value="鐢�" />
+            <el-option label="姘�"
+                       value="姘�" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="澶囨敞"
+                      prop="remark">
+          <el-input v-model="form.remark"
+                    type="textarea"
+                    rows="3" />
+        </el-form-item>
+        <el-form-item label="鍗曚綅"
+                      prop="unit">
+          <el-input v-model="form.unit"
+                    placeholder="璇疯緭鍏�" />
+        </el-form-item>
+        <el-form-item label="鍗曚环"
+                      prop="unitPrice">
+          <el-input-number v-model="form.unitPrice"
+                           :precision="2"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button type="primary"
+                     @click="handleSubmit">纭畾</el-button>
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- 璇︽儏寮圭獥 -->
+    <el-dialog v-model="detailDialogVisible"
+               title="鑳芥簮绫诲瀷璇︽儏"
+               width="600px">
+      <el-form :model="detailForm"
+               label-width="100px"
+               disabled>
+        <el-form-item label="鑳芥簮绫诲瀷">
+          <el-tag :type="getEnergyTypeType(detailForm.energyTyep)">
+            {{ detailForm.energyTyep }}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="鑳芥簮鍚嶇О">
+          <el-input v-model="detailForm.energyName" />
+        </el-form-item>
+        <el-form-item label="鍗曚环">
+          <el-input v-model="detailForm.unitPrice" />
+        </el-form-item>
+        <el-form-item label="鍗曚綅">
+          <el-input v-model="detailForm.unit" />
+        </el-form-item>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="detailForm.remark"
+                    type="textarea"
+                    rows="3" />
+        </el-form-item>
+        <el-form-item label="鍒涘缓浜�">
+          <el-input v-model="detailForm.createUserName" />
+        </el-form-item>
+        <el-form-item label="鍒涘缓鏃堕棿">
+          <el-input v-model="detailForm.createTime" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted, getCurrentInstance } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import {
+    energyTypeListPage,
+    energyTypeAdd,
+    energyTypeDelete,
+  } from "@/api/energyManagement/energyType";
+
+  import { More } from "@element-plus/icons-vue";
+
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    energyTyep: "",
+    energyName: "",
+  });
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 寮圭獥鎺у埗
+  const dialogVisible = ref(false);
+  const dialogTitle = ref("鏂板鑳芥簮绫诲瀷");
+  const formRef = ref(null);
+  const isEdit = ref(false);
+  const currentId = ref(null);
+
+  // 琛ㄥ崟鏁版嵁
+  const form = reactive({
+    energyName: "",
+    energyTyep: "",
+    id: "",
+    remark: "",
+    unit: "",
+    unitPrice: 0,
+  });
+  const { proxy } = getCurrentInstance();
+  // 琛ㄥ崟鏍¢獙瑙勫垯
+  const rules = {
+    energyTyep: [
+      { required: true, message: "璇烽�夋嫨鑳芥簮绫诲瀷", trigger: "change" },
+    ],
+    energyName: [{ required: true, message: "璇疯緭鍏ヨ兘婧愬悕绉�", trigger: "blur" }],
+    unitPrice: [{ required: true, message: "璇疯緭鍏ュ崟浠�", trigger: "blur" }],
+    unit: [{ required: true, message: "璇疯緭鍏ュ崟浣�", trigger: "blur" }],
+  };
+
+  // 璇︽儏寮圭獥
+  const detailDialogVisible = ref(false);
+  const detailForm = reactive({
+    energyTyep: "",
+    energyName: "",
+    unitPrice: "",
+    unit: "",
+    remark: "",
+    createUserName: "",
+    createUserNameOrganization: "",
+    createTime: "",
+    updateTime: "",
+  });
+
+  // 鑾峰彇鑳芥簮绫诲瀷鏍峰紡
+  const getEnergyTypeType = type => {
+    const typeMap = {
+      姘�: "success",
+      鐢�: "warning",
+      姘�: "primary",
+    };
+    return typeMap[type] || "info";
+  };
+
+  // 鐢熸垚妯℃嫙鏁版嵁
+  const generateMockData = () => {
+    const data = [
+      {
+        id: 1,
+        energyTyep: "姘�",
+        energyName: "钂告苯",
+        unitPrice: "0.00",
+        unit: "T",
+        createUserName: "鐧芥礇宸茬棿鐢�",
+        createUserNameOrganization: "瀹佸涓摱缁掍笟瀹炰笟闆嗗洟鏈夐檺鍏徃",
+        createTime: "2022-11-09 14:14:05",
+        updateTime: "2022-11-10 18:14:48",
+        remark: "",
+      },
+      {
+        id: 2,
+        energyTyep: "鐢�",
+        energyName: "鐢甸噺",
+        unitPrice: "0.00",
+        unit: "搴�",
+        createUserName: "鐜嬬惇宸茬棿鐢�",
+        createUserNameOrganization: "瀹佸涓摱缁掍笟瀹炰笟闆嗗洟鏈夐檺鍏徃",
+        createTime: "2022-10-08 17:27:27",
+        updateTime: "2022-11-10 18:14:40",
+        remark: "",
+      },
+      {
+        id: 3,
+        energyTyep: "姘�",
+        energyName: "涓按",
+        unitPrice: "0.00",
+        unit: "m鲁",
+        createUserName: "鐜嬬惇宸茬棿鐢�",
+        createUserNameOrganization: "瀹佸涓摱缁掍笟瀹炰笟闆嗗洟鏈夐檺鍏徃",
+        createTime: "2022-10-08 10:03:03",
+        updateTime: "2022-11-10 18:10:31",
+        remark: "",
+      },
+    ];
+    return data;
+  };
+
+  // 鏌ヨ
+  const handleQuery = () => {
+    tableLoading.value = true;
+    let params = {
+      current: page.current,
+      size: page.size,
+      energyTyep: searchForm.energyTyep,
+      energyName: searchForm.energyName,
+    };
+    energyTypeListPage(params)
+      .then(res => {
+        if (res.code === 200) {
+          tableData.value = res.data.records;
+          page.total = res.data.total;
+          tableLoading.value = false;
+        } else {
+          ElMessage.error(res.message || "鏌ヨ澶辫触");
+          tableLoading.value = false;
+        }
+      })
+      .catch(error => {
+        ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+        tableLoading.value = false;
+      });
+  };
+
+  // 閲嶇疆
+  const handleReset = () => {
+    searchForm.energyTyep = "";
+    searchForm.energyName = "";
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 鏂板
+  const handleAdd = () => {
+    isEdit.value = false;
+    currentId.value = null;
+    dialogTitle.value = "鏂板鑳芥簮绫诲瀷";
+    resetForm();
+    dialogVisible.value = true;
+  };
+
+  // 缂栬緫
+  const handleEdit = row => {
+    isEdit.value = true;
+    currentId.value = row.id;
+    dialogTitle.value = "缂栬緫鑳芥簮绫诲瀷";
+    Object.assign(form, row);
+    dialogVisible.value = true;
+  };
+
+  // 璇︽儏
+  const handleDetail = row => {
+    Object.assign(detailForm, row);
+    detailDialogVisible.value = true;
+  };
+
+  // 鍒犻櫎
+  const handleDelete = row => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ鑳芥簮绫诲瀷鍚楋紵", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      tableLoading.value = true;
+      energyTypeDelete([row.id])
+        .then(res => {
+          if (res.code === 200) {
+            ElMessage.success("鍒犻櫎鎴愬姛");
+            handleQuery();
+          } else {
+            ElMessage.error(res.message || "鍒犻櫎澶辫触");
+          }
+        })
+        .catch(error => {
+          ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+        })
+        .finally(() => {
+          tableLoading.value = false;
+        });
+    });
+  };
+
+  // 澶嶅埗
+  const handleCopy = row => {
+    isEdit.value = false;
+    currentId.value = null;
+    dialogTitle.value = "澶嶅埗鑳芥簮绫诲瀷";
+    Object.assign(form, row);
+    delete form.id;
+    dialogVisible.value = true;
+    ElMessage.success("宸插鍒跺埌琛ㄥ崟");
+  };
+
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    form.energyName = "";
+    form.energyTyep = "";
+    form.id = "";
+    form.remark = "";
+    form.unit = "";
+    form.unitPrice = 0;
+  };
+
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        tableLoading.value = true;
+        energyTypeAdd(form)
+          .then(res => {
+            if (res.code === 200) {
+              ElMessage.success(isEdit.value ? "缂栬緫鎴愬姛" : "鏂板鎴愬姛");
+              dialogVisible.value = false;
+              handleQuery();
+            } else {
+              ElMessage.error(res.message || "鎿嶄綔澶辫触");
+            }
+          })
+          .catch(error => {
+            ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+          })
+          .finally(() => {
+            tableLoading.value = false;
+          });
+      }
+    });
+  };
+
+  // 瀵煎叆
+  const handleImport = () => {
+    ElMessage.success("瀵煎叆鎴愬姛");
+  };
+
+  // 瀵煎嚭
+  const handleExport = () => {
+    // proxy.download("/energy/export", { ...searchForm.value }, "鑳借�楃被鍨�.xlsx");
+    proxy.download("/energy/export", {}, "鑳借�楃被鍨�.xlsx");
+  };
+
+  // 鍒嗛〉澶у皬鍙樺寲
+  const handleSizeChange = val => {
+    page.size = val;
+    handleQuery();
+  };
+
+  // 椤电爜鍙樺寲
+  const handleCurrentChange = val => {
+    page.current = val;
+    handleQuery();
+  };
+
+  onMounted(() => {
+    handleQuery();
+  });
+</script>
+<style scoped lang="scss">
+  .app-container {
+    padding: 24px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 48px);
+  }
+
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 24px;
+    padding: 20px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
+    }
+  }
+
+  .table_list {
+    // margin-bottom: 24px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    overflow: hidden;
+    height: calc(100vh - 250px);
+  }
+
+  :deep(.el-table) {
+    border: none;
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-table__header-wrapper {
+      background-color: #fafafa;
+
+      th {
+        background-color: #fafafa;
+        font-weight: 600;
+        color: #303133;
+        border-bottom: 1px solid #ebeef5;
+        padding: 14px 0;
+      }
+    }
+
+    .el-table__body-wrapper {
+      tr {
+        transition: all 0.3s ease;
+
+        &:hover {
+          background-color: #f5f7fa;
+        }
+
+        td {
+          border-bottom: 1px solid #ebeef5;
+          padding: 12px 0;
+        }
+      }
+
+      tr.current-row {
+        background-color: #ecf5ff;
+      }
+    }
+
+    .el-table__empty-block {
+      padding: 40px 0;
+    }
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+    padding: 16px 20px;
+    background-color: #ffffff;
+    border-top: 1px solid #ebeef5;
+    border-radius: 0 0 12px 12px;
+  }
+
+  :deep(.el-button) {
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-1px);
+    }
+  }
+
+  :deep(.el-dialog) {
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-dialog__header {
+      background-color: #fafafa;
+      border-bottom: 1px solid #ebeef5;
+      padding: 20px 24px;
+
+      .el-dialog__title {
+        font-size: 16px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+
+    .el-dialog__body {
+      padding: 24px;
+    }
+
+    .el-dialog__footer {
+      padding: 16px 24px;
+      border-top: 1px solid #ebeef5;
+      background-color: #fafafa;
+    }
+  }
+
+  :deep(.el-form) {
+    .el-form-item {
+      margin-bottom: 20px;
+
+      .el-form-item__label {
+        font-weight: 500;
+        color: #303133;
+      }
+
+      .el-input,
+      .el-select,
+      .el-date-picker,
+      .el-input-number {
+        width: 100%;
+
+        // .el-input__inner {
+        //   border-radius: 6px;
+        //   border: 1px solid #dcdfe6;
+        //   transition: all 0.3s ease;
+
+        //   &:focus {
+        //     border-color: #409eff;
+        //     box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+        //   }
+        // }
+      }
+    }
+  }
+
+  :deep(.el-tag) {
+    border-radius: 4px;
+    padding: 2px 8px;
+    font-size: 12px;
+  }
+
+  @media (max-width: 768px) {
+    .app-container {
+      padding: 16px;
+    }
+
+    .search_form {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 12px;
+
+      .el-form {
+        width: 100%;
+
+        .el-form-item {
+          width: 100%;
+        }
+      }
+
+      > div {
+        width: 100%;
+        display: flex;
+        gap: 12px;
+
+        .el-button {
+          flex: 1;
+        }
+      }
+    }
+
+    :deep(.el-table) {
+      th,
+      td {
+        padding: 10px 0;
+        font-size: 12px;
+      }
+    }
+
+    :deep(.el-dialog) {
+      width: 90% !important;
+      margin: 20px auto !important;
+    }
+  }
+  .consumption-value {
+    font-weight: bold;
+    color: #409eff;
+  }
+
+  .consumption-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-left: 4px;
+  }
+  .search_form {
+    :deep(.el-form-item) {
+      margin-bottom: 0px !important;
+    }
+  }
+</style>
diff --git a/src/views/energyManagement/officeEnergyConsumption/index.vue b/src/views/energyManagement/officeEnergyConsumption/index.vue
new file mode 100644
index 0000000..c3fbf82
--- /dev/null
+++ b/src/views/energyManagement/officeEnergyConsumption/index.vue
@@ -0,0 +1,696 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储鍖哄煙 -->
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <el-form-item label="鑳借�楃被鍨�:">
+          <el-select v-model="searchForm.energyType"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 140px;"
+                     @change="handleQuery">
+            <el-option label="姘�"
+                       value="water" />
+            <el-option label="鐢�"
+                       value="electricity" />
+            <el-option label="姘�"
+                       value="gas" />
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item label="鏃ユ湡鑼冨洿:">
+          <el-date-picker v-model="searchForm.dateRange"
+                          type="daterange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫棩鏈�"
+                          end-placeholder="缁撴潫鏃ユ湡"
+                          value-format="YYYY-MM-DD"
+                          style="width: 240px;"
+                          @change="handleQuery" />
+        </el-form-item> -->
+        <el-form-item>
+          <el-button type="primary"
+                     @click="handleQuery">鎼滅储</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <!-- <el-button type="primary"
+                   @click="handleAdd">鏂板</el-button> -->
+        <el-button type="success"
+                   @click="handleExport">瀵煎嚭</el-button>
+      </div>
+    </div>
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <div class="table_list">
+      <el-table :data="tableData"
+                v-loading="tableLoading"
+                border
+                height="calc(100vh - 350px)"
+                stripe>
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column prop="meterReadingDate"
+                         label="鎶勮〃鏃ユ湡"
+                         width="120"
+                         sortable
+                         align="center" />
+        <el-table-column prop="energyType"
+                         label="鑳芥簮绫诲瀷"
+                         width="100"
+                         align="center">
+          <template #default="scope">
+            <el-tag :type="getEnergyTypeType(scope.row.energyTyep)">
+              {{ scope.row.energyTyep }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="energyName"
+                         label="鑳芥簮鍚嶇О"
+                         align="center" />
+        <el-table-column prop="meterReadingLocation"
+                         label="鎶勮〃浣嶇疆"
+                         align="center" />
+        <el-table-column prop="startCode"
+                         label="璧风爜"
+                         sortable
+                         align="right" />
+        <el-table-column prop="stopCode"
+                         label="姝㈢爜"
+                         sortable
+                         align="right" />
+        <el-table-column prop="dosage"
+                         label="鐢ㄩ噺"
+                         sortable
+                         align="right">
+          <template #default="scope">
+            <span class="consumption-value">{{ scope.row.dosage }}</span>
+            <span class="consumption-unit">{{ scope.row.unit }}</span>
+          </template>
+        </el-table-column>
+        <!-- <el-table-column prop="unit"
+                         label="鍗曚綅"
+                         width="80"
+                         align="center" /> -->
+        <!-- <el-table-column prop="energyId"
+                         label="鑳芥簮绫诲瀷ID"
+                         width="120"
+                         align="center" /> -->
+        <el-table-column prop="remark"
+                         label="澶囨敞"
+                         min-width="150"
+                         show-overflow-tooltip />
+        <!-- <el-table-column label="鎿嶄綔"
+                         width="180"
+                         align="center"
+                         fixed="right">
+          <template #default="scope">
+            <el-button type="primary"
+                       link
+                       @click="handleEdit(scope.row)">缂栬緫</el-button>
+            <el-button type="danger"
+                       link
+                       @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column> -->
+      </el-table>
+      <div class="pagination-container">
+        <el-pagination v-model:current-page="page.current"
+                       v-model:page-size="page.size"
+                       :page-sizes="[10, 20, 50, 100]"
+                       :total="page.total"
+                       layout="total, sizes, prev, pager, next, jumper"
+                       @size-change="handleSizeChange"
+                       @current-change="handleCurrentChange" />
+      </div>
+    </div>
+    <!-- 鍒嗛〉 -->
+    <!-- 鏂板/缂栬緫寮圭獥 -->
+    <el-dialog v-model="dialogVisible"
+               :title="dialogTitle"
+               width="600px">
+      <el-form :model="form"
+               :rules="rules"
+               ref="formRef"
+               label-width="120px">
+        <el-form-item label="鎶勮〃鏃ユ湡"
+                      prop="meterReadingDate">
+          <el-date-picker v-model="form.meterReadingDate"
+                          type="date"
+                          placeholder="璇烽�夋嫨"
+                          value-format="YYYY-MM-DD"
+                          style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="鑳芥簮绫诲瀷"
+                      prop="energyType">
+          <el-select v-model="form.energyType"
+                     placeholder="璇烽�夋嫨"
+                     style="width: 100%;"
+                     @change="handleEnergyTypeChange">
+            <el-option v-for="item in energyTypeList"
+                       :key="item.id"
+                       :label="item.energyName"
+                       :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鎶勮〃浣嶇疆"
+                      prop="meterReadingLocation">
+          <el-input v-model="form.meterReadingLocation"
+                    placeholder="璇疯緭鍏�" />
+        </el-form-item>
+        <el-form-item label="璧风爜"
+                      prop="startCode">
+          <el-input-number v-model="form.startCode"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="姝㈢爜"
+                      prop="stopCode">
+          <el-input-number v-model="form.stopCode"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="鐢ㄩ噺"
+                      prop="dosage">
+          <el-input-number v-model="form.dosage"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="鍗曚綅"
+                      prop="unit">
+          <el-input v-model="form.unit"
+                    disabled
+                    placeholder="璇疯緭鍏�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞"
+                      prop="remark">
+          <el-input v-model="form.remark"
+                    type="textarea"
+                    rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="handleSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted, getCurrentInstance } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Watermelon, Lightning } from "@element-plus/icons-vue";
+  import {
+    energyConsumptionDetailListPage,
+    energyConsumptionDetailAdd,
+    energyConsumptionDetailDelete,
+    energyTypeListPage,
+  } from "@/api/energyManagement/energyType";
+
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    energyType: "",
+    dateRange: [],
+  });
+  const { proxy } = getCurrentInstance();
+
+  // 缁熻鏁版嵁
+  const statistics = reactive({
+    waterTotal: 1256.8,
+    waterAmount: "3,142.00",
+    electricityTotal: 8520.5,
+    electricityAmount: "6,816.40",
+    gasTotal: 3200.6,
+    gasAmount: "9,601.80",
+  });
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 寮圭獥鎺у埗
+  const dialogVisible = ref(false);
+  const dialogTitle = ref("鏂板鑳借�楄褰�");
+  const formRef = ref(null);
+  const isEdit = ref(false);
+  const currentId = ref(null);
+
+  // 琛ㄥ崟鏁版嵁
+  const form = reactive({
+    meterReadingDate: "",
+    energyType: "",
+    energyName: "",
+    energyId: "",
+    meterReadingLocation: "",
+    startCode: 0,
+    stopCode: 0,
+    dosage: 0,
+    unit: "",
+    remark: "",
+    type: "鍔炲叕",
+  });
+
+  // 琛ㄥ崟鏍¢獙瑙勫垯
+  const rules = {
+    meterReadingDate: [
+      { required: true, message: "璇烽�夋嫨鎶勮〃鏃ユ湡", trigger: "change" },
+    ],
+    energyType: [
+      { required: true, message: "璇烽�夋嫨鑳芥簮绫诲瀷", trigger: "change" },
+    ],
+    energyName: [
+      { required: true, message: "璇烽�夋嫨鑳芥簮鍚嶇О", trigger: "change" },
+    ],
+    energyId: [{ required: true, message: "璇烽�夋嫨鑳芥簮绫诲瀷", trigger: "change" }],
+    meterReadingLocation: [
+      { required: true, message: "璇疯緭鍏ユ妱琛ㄤ綅缃�", trigger: "blur" },
+    ],
+    startCode: [{ required: true, message: "璇疯緭鍏ヨ捣鐮�", trigger: "blur" }],
+    stopCode: [{ required: true, message: "璇疯緭鍏ユ鐮�", trigger: "blur" }],
+    dosage: [{ required: true, message: "璇疯緭鍏ョ敤閲�", trigger: "blur" }],
+    unit: [{ required: true, message: "璇疯緭鍏ュ崟浣�", trigger: "blur" }],
+  };
+
+  // 鑾峰彇鑳借�楃被鍨嬫牱寮�
+  const getEnergyTypeType = type => {
+    const typeMap = {
+      姘�: "primary",
+      鐢�: "warning",
+      姘�: "success",
+      water: "primary",
+      electricity: "warning",
+      gas: "success",
+    };
+    return typeMap[type] || "info";
+  };
+
+  // 鑾峰彇鑳借�楃被鍨嬫枃鏈�
+  const getEnergyTypeText = type => {
+    const textMap = {
+      water: "姘�",
+      electricity: "鐢�",
+      gas: "姘�",
+    };
+    return textMap[type] || type;
+  };
+
+  // 鏌ヨ
+  const handleQuery = () => {
+    tableLoading.value = true;
+    const params = {
+      current: page.current,
+      size: page.size,
+      type: "鍔炲叕",
+      // energyType: searchForm.energyType,
+      // startDate:
+      //   searchForm.dateRange && searchForm.dateRange.length === 2
+      //     ? searchForm.dateRange[0]
+      //     : null,
+      // endDate:
+      //   searchForm.dateRange && searchForm.dateRange.length === 2
+      //     ? searchForm.dateRange[1]
+      //     : null,
+    };
+    energyConsumptionDetailListPage(params)
+      .then(res => {
+        if (res.code === 200) {
+          tableData.value = res.data.records;
+          page.total = res.data.total;
+        } else {
+          ElMessage.error(res.message || "鏌ヨ澶辫触");
+        }
+      })
+      .catch(error => {
+        ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+      })
+      .finally(() => {
+        tableLoading.value = false;
+      });
+  };
+  const energyTypeList = ref([]);
+  const getEnergyTypeList = () => {
+    energyTypeListPage({ current: -1, size: -1 })
+      .then(res => {
+        if (res.code === 200) {
+          energyTypeList.value = res.data.records;
+        } else {
+          ElMessage.error(res.message || "鏌ヨ澶辫触");
+        }
+      })
+      .catch(error => {
+        ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+      });
+  };
+
+  // 閲嶇疆
+  const handleReset = () => {
+    searchForm.energyType = "";
+    searchForm.dateRange = [];
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 瀵煎嚭
+  const handleExport = () => {
+    proxy.download(
+      "/energyConsumptionDetail/export",
+      { type: "鍔炲叕" },
+      "鑳借�楁槑缁�.xlsx"
+    );
+  };
+
+  // 鍒嗛〉澶у皬鍙樺寲
+  const handleSizeChange = val => {
+    page.size = val;
+    handleQuery();
+  };
+
+  // 椤电爜鍙樺寲
+  const handleCurrentChange = val => {
+    page.current = val;
+    handleQuery();
+  };
+
+  // 澶勭悊鑳芥簮绫诲瀷鍙樺寲
+  const handleEnergyTypeChange = value => {
+    const selectedType = energyTypeList.value.find(item => item.id === value);
+    if (selectedType) {
+      form.energyName = selectedType.energyName;
+      form.energyId = selectedType.id;
+      form.unit = selectedType.unit;
+    }
+  };
+
+  // 鏂板
+  const handleAdd = () => {
+    isEdit.value = false;
+    currentId.value = null;
+    dialogTitle.value = "鏂板鑳借�楄褰�";
+    resetForm();
+    dialogVisible.value = true;
+  };
+
+  // 缂栬緫
+  const handleEdit = row => {
+    isEdit.value = true;
+    currentId.value = row.id;
+    dialogTitle.value = "缂栬緫鑳借�楄褰�";
+    Object.assign(form, row);
+    dialogVisible.value = true;
+  };
+
+  // 鍒犻櫎
+  const handleDelete = row => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ鑳借�楄褰曞悧锛�", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      tableLoading.value = true;
+      energyConsumptionDetailDelete([row.id])
+        .then(res => {
+          if (res.code === 200) {
+            ElMessage.success("鍒犻櫎鎴愬姛");
+            handleQuery();
+          } else {
+            ElMessage.error(res.message || "鍒犻櫎澶辫触");
+          }
+        })
+        .catch(error => {
+          ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+        })
+        .finally(() => {
+          tableLoading.value = false;
+        });
+    });
+  };
+
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    form.meterReadingDate = "";
+    form.energyType = "";
+    form.energyName = "";
+    form.energyId = "";
+    form.meterReadingLocation = "";
+    form.startCode = 0;
+    form.stopCode = 0;
+    form.dosage = 0;
+    form.unit = "";
+    form.remark = "";
+    form.type = "鍔炲叕";
+  };
+
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        tableLoading.value = true;
+        energyConsumptionDetailAdd(form)
+          .then(res => {
+            if (res.code === 200) {
+              ElMessage.success(isEdit.value ? "缂栬緫鎴愬姛" : "鏂板鎴愬姛");
+              dialogVisible.value = false;
+              handleQuery();
+            } else {
+              ElMessage.error(res.message || "鎿嶄綔澶辫触");
+            }
+          })
+          .catch(error => {
+            ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+          })
+          .finally(() => {
+            tableLoading.value = false;
+          });
+      }
+    });
+  };
+
+  onMounted(() => {
+    getEnergyTypeList();
+    handleQuery();
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 24px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 48px);
+  }
+
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 24px;
+    padding: 20px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
+    }
+  }
+
+  .table_list {
+    // margin-bottom: 24px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    overflow: hidden;
+    height: calc(100vh - 250px);
+  }
+
+  :deep(.el-table) {
+    border: none;
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-table__header-wrapper {
+      background-color: #fafafa;
+
+      th {
+        background-color: #fafafa;
+        font-weight: 600;
+        color: #303133;
+        border-bottom: 1px solid #ebeef5;
+        padding: 14px 0;
+      }
+    }
+
+    .el-table__body-wrapper {
+      tr {
+        transition: all 0.3s ease;
+
+        &:hover {
+          background-color: #f5f7fa;
+        }
+
+        td {
+          border-bottom: 1px solid #ebeef5;
+          padding: 12px 0;
+        }
+      }
+
+      tr.current-row {
+        background-color: #ecf5ff;
+      }
+    }
+
+    .el-table__empty-block {
+      padding: 40px 0;
+    }
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+    padding: 16px 20px;
+    background-color: #ffffff;
+    border-top: 1px solid #ebeef5;
+    border-radius: 0 0 12px 12px;
+  }
+
+  :deep(.el-button) {
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-1px);
+    }
+  }
+
+  :deep(.el-dialog) {
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-dialog__header {
+      background-color: #fafafa;
+      border-bottom: 1px solid #ebeef5;
+      padding: 20px 24px;
+
+      .el-dialog__title {
+        font-size: 16px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+
+    .el-dialog__body {
+      padding: 24px;
+    }
+
+    .el-dialog__footer {
+      padding: 16px 24px;
+      border-top: 1px solid #ebeef5;
+      background-color: #fafafa;
+    }
+  }
+
+  :deep(.el-form) {
+    .el-form-item {
+      margin-bottom: 20px;
+
+      .el-form-item__label {
+        font-weight: 500;
+        color: #303133;
+      }
+
+      .el-input,
+      .el-select,
+      .el-date-picker,
+      .el-input-number {
+        width: 100%;
+
+        // .el-input__inner {
+        //   border-radius: 6px;
+        //   border: 1px solid #dcdfe6;
+        //   transition: all 0.3s ease;
+
+        //   &:focus {
+        //     border-color: #409eff;
+        //     box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+        //   }
+        // }
+      }
+    }
+  }
+
+  :deep(.el-tag) {
+    border-radius: 4px;
+    padding: 2px 8px;
+    font-size: 12px;
+  }
+
+  @media (max-width: 768px) {
+    .app-container {
+      padding: 16px;
+    }
+
+    .search_form {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 12px;
+
+      .el-form {
+        width: 100%;
+
+        .el-form-item {
+          width: 100%;
+        }
+      }
+
+      > div {
+        width: 100%;
+        display: flex;
+        gap: 12px;
+
+        .el-button {
+          flex: 1;
+        }
+      }
+    }
+
+    :deep(.el-table) {
+      th,
+      td {
+        padding: 10px 0;
+        font-size: 12px;
+      }
+    }
+
+    :deep(.el-dialog) {
+      width: 90% !important;
+      margin: 20px auto !important;
+    }
+  }
+  .consumption-value {
+    font-weight: bold;
+    color: #409eff;
+  }
+
+  .consumption-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-left: 4px;
+  }
+  .search_form {
+    :deep(.el-form-item) {
+      margin-bottom: 0px !important;
+    }
+  }
+</style>
diff --git a/src/views/energyManagement/productionEnergyConsumption/index.vue b/src/views/energyManagement/productionEnergyConsumption/index.vue
new file mode 100644
index 0000000..7a69ec2
--- /dev/null
+++ b/src/views/energyManagement/productionEnergyConsumption/index.vue
@@ -0,0 +1,696 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储鍖哄煙 -->
+    <div class="search_form">
+      <el-form :model="searchForm"
+               :inline="true">
+        <el-form-item label="鑳借�楃被鍨�:">
+          <el-select v-model="searchForm.energyType"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 140px;"
+                     @change="handleQuery">
+            <el-option label="姘�"
+                       value="water" />
+            <el-option label="鐢�"
+                       value="electricity" />
+            <el-option label="姘�"
+                       value="gas" />
+          </el-select>
+        </el-form-item>
+        <!-- <el-form-item label="鏃ユ湡鑼冨洿:">
+          <el-date-picker v-model="searchForm.dateRange"
+                          type="daterange"
+                          range-separator="鑷�"
+                          start-placeholder="寮�濮嬫棩鏈�"
+                          end-placeholder="缁撴潫鏃ユ湡"
+                          value-format="YYYY-MM-DD"
+                          style="width: 240px;"
+                          @change="handleQuery" />
+        </el-form-item> -->
+        <el-form-item>
+          <el-button type="primary"
+                     @click="handleQuery">鎼滅储</el-button>
+          <el-button @click="handleReset">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+      <div>
+        <el-button type="primary"
+                   @click="handleAdd">鏂板</el-button>
+        <el-button type="success"
+                   @click="handleExport">瀵煎嚭</el-button>
+      </div>
+    </div>
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <div class="table_list">
+      <el-table :data="tableData"
+                v-loading="tableLoading"
+                border
+                height="calc(100vh - 350px)"
+                stripe>
+        <el-table-column type="index"
+                         label="搴忓彿"
+                         width="60"
+                         align="center" />
+        <el-table-column prop="meterReadingDate"
+                         label="鎶勮〃鏃ユ湡"
+                         width="120"
+                         sortable
+                         align="center" />
+        <el-table-column prop="energyType"
+                         label="鑳芥簮绫诲瀷"
+                         width="100"
+                         align="center">
+          <template #default="scope">
+            <el-tag :type="getEnergyTypeType(scope.row.energyTyep)">
+              {{ scope.row.energyTyep }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="energyName"
+                         label="鑳芥簮鍚嶇О"
+                         align="center" />
+        <el-table-column prop="meterReadingLocation"
+                         label="鎶勮〃浣嶇疆"
+                         align="center" />
+        <el-table-column prop="startCode"
+                         label="璧风爜"
+                         sortable
+                         align="right" />
+        <el-table-column prop="stopCode"
+                         label="姝㈢爜"
+                         sortable
+                         align="right" />
+        <el-table-column prop="dosage"
+                         label="鐢ㄩ噺"
+                         sortable
+                         align="right">
+          <template #default="scope">
+            <span class="consumption-value">{{ scope.row.dosage }}</span>
+            <span class="consumption-unit">{{ scope.row.unit }}</span>
+          </template>
+        </el-table-column>
+        <!-- <el-table-column prop="unit"
+                         label="鍗曚綅"
+                         width="80"
+                         align="center" /> -->
+        <!-- <el-table-column prop="energyId"
+                         label="鑳芥簮绫诲瀷ID"
+                         width="120"
+                         align="center" /> -->
+        <el-table-column prop="remark"
+                         label="澶囨敞"
+                         min-width="150"
+                         show-overflow-tooltip />
+        <el-table-column label="鎿嶄綔"
+                         width="180"
+                         align="center"
+                         fixed="right">
+          <template #default="scope">
+            <el-button type="primary"
+                       link
+                       @click="handleEdit(scope.row)">缂栬緫</el-button>
+            <el-button type="danger"
+                       link
+                       @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container">
+        <el-pagination v-model:current-page="page.current"
+                       v-model:page-size="page.size"
+                       :page-sizes="[10, 20, 50, 100]"
+                       :total="page.total"
+                       layout="total, sizes, prev, pager, next, jumper"
+                       @size-change="handleSizeChange"
+                       @current-change="handleCurrentChange" />
+      </div>
+    </div>
+    <!-- 鍒嗛〉 -->
+    <!-- 鏂板/缂栬緫寮圭獥 -->
+    <el-dialog v-model="dialogVisible"
+               :title="dialogTitle"
+               width="600px">
+      <el-form :model="form"
+               :rules="rules"
+               ref="formRef"
+               label-width="120px">
+        <el-form-item label="鎶勮〃鏃ユ湡"
+                      prop="meterReadingDate">
+          <el-date-picker v-model="form.meterReadingDate"
+                          type="date"
+                          placeholder="璇烽�夋嫨"
+                          value-format="YYYY-MM-DD"
+                          style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="鑳芥簮绫诲瀷"
+                      prop="energyType">
+          <el-select v-model="form.energyType"
+                     placeholder="璇烽�夋嫨"
+                     style="width: 100%;"
+                     @change="handleEnergyTypeChange">
+            <el-option v-for="item in energyTypeList"
+                       :key="item.id"
+                       :label="item.energyName"
+                       :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鎶勮〃浣嶇疆"
+                      prop="meterReadingLocation">
+          <el-input v-model="form.meterReadingLocation"
+                    placeholder="璇疯緭鍏�" />
+        </el-form-item>
+        <el-form-item label="璧风爜"
+                      prop="startCode">
+          <el-input-number v-model="form.startCode"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="姝㈢爜"
+                      prop="stopCode">
+          <el-input-number v-model="form.stopCode"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="鐢ㄩ噺"
+                      prop="dosage">
+          <el-input-number v-model="form.dosage"
+                           :min="0"
+                           style="width: 100%;" />
+        </el-form-item>
+        <el-form-item label="鍗曚綅"
+                      prop="unit">
+          <el-input v-model="form.unit"
+                    disabled
+                    placeholder="璇疯緭鍏�" />
+        </el-form-item>
+        <el-form-item label="澶囨敞"
+                      prop="remark">
+          <el-input v-model="form.remark"
+                    type="textarea"
+                    rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="handleSubmit">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted, getCurrentInstance } from "vue";
+  import { ElMessage, ElMessageBox } from "element-plus";
+  import { Watermelon, Lightning } from "@element-plus/icons-vue";
+  import {
+    energyConsumptionDetailListPage,
+    energyConsumptionDetailAdd,
+    energyConsumptionDetailDelete,
+    energyTypeListPage,
+  } from "@/api/energyManagement/energyType";
+
+  // 鎼滅储琛ㄥ崟
+  const searchForm = reactive({
+    energyType: "",
+    dateRange: [],
+  });
+  const { proxy } = getCurrentInstance();
+
+  // 缁熻鏁版嵁
+  const statistics = reactive({
+    waterTotal: 1256.8,
+    waterAmount: "3,142.00",
+    electricityTotal: 8520.5,
+    electricityAmount: "6,816.40",
+    gasTotal: 3200.6,
+    gasAmount: "9,601.80",
+  });
+
+  // 琛ㄦ牸鏁版嵁
+  const tableData = ref([]);
+  const tableLoading = ref(false);
+
+  // 鍒嗛〉
+  const page = reactive({
+    current: 1,
+    size: 10,
+    total: 0,
+  });
+
+  // 寮圭獥鎺у埗
+  const dialogVisible = ref(false);
+  const dialogTitle = ref("鏂板鑳借�楄褰�");
+  const formRef = ref(null);
+  const isEdit = ref(false);
+  const currentId = ref(null);
+
+  // 琛ㄥ崟鏁版嵁
+  const form = reactive({
+    meterReadingDate: "",
+    energyType: "",
+    energyName: "",
+    energyId: "",
+    meterReadingLocation: "",
+    startCode: 0,
+    stopCode: 0,
+    dosage: 0,
+    unit: "",
+    remark: "",
+    type: "鐢熶骇",
+  });
+
+  // 琛ㄥ崟鏍¢獙瑙勫垯
+  const rules = {
+    meterReadingDate: [
+      { required: true, message: "璇烽�夋嫨鎶勮〃鏃ユ湡", trigger: "change" },
+    ],
+    energyType: [
+      { required: true, message: "璇烽�夋嫨鑳芥簮绫诲瀷", trigger: "change" },
+    ],
+    energyName: [
+      { required: true, message: "璇烽�夋嫨鑳芥簮鍚嶇О", trigger: "change" },
+    ],
+    energyId: [{ required: true, message: "璇烽�夋嫨鑳芥簮绫诲瀷", trigger: "change" }],
+    meterReadingLocation: [
+      { required: true, message: "璇疯緭鍏ユ妱琛ㄤ綅缃�", trigger: "blur" },
+    ],
+    startCode: [{ required: true, message: "璇疯緭鍏ヨ捣鐮�", trigger: "blur" }],
+    stopCode: [{ required: true, message: "璇疯緭鍏ユ鐮�", trigger: "blur" }],
+    dosage: [{ required: true, message: "璇疯緭鍏ョ敤閲�", trigger: "blur" }],
+    unit: [{ required: true, message: "璇疯緭鍏ュ崟浣�", trigger: "blur" }],
+  };
+
+  // 鑾峰彇鑳借�楃被鍨嬫牱寮�
+  const getEnergyTypeType = type => {
+    const typeMap = {
+      姘�: "primary",
+      鐢�: "warning",
+      姘�: "success",
+      water: "primary",
+      electricity: "warning",
+      gas: "success",
+    };
+    return typeMap[type] || "info";
+  };
+
+  // 鑾峰彇鑳借�楃被鍨嬫枃鏈�
+  const getEnergyTypeText = type => {
+    const textMap = {
+      water: "姘�",
+      electricity: "鐢�",
+      gas: "姘�",
+    };
+    return textMap[type] || type;
+  };
+
+  // 鏌ヨ
+  const handleQuery = () => {
+    tableLoading.value = true;
+    const params = {
+      current: page.current,
+      size: page.size,
+      type: "鐢熶骇",
+      // energyType: searchForm.energyType,
+      // startDate:
+      //   searchForm.dateRange && searchForm.dateRange.length === 2
+      //     ? searchForm.dateRange[0]
+      //     : null,
+      // endDate:
+      //   searchForm.dateRange && searchForm.dateRange.length === 2
+      //     ? searchForm.dateRange[1]
+      //     : null,
+    };
+    energyConsumptionDetailListPage(params)
+      .then(res => {
+        if (res.code === 200) {
+          tableData.value = res.data.records;
+          page.total = res.data.total;
+        } else {
+          ElMessage.error(res.message || "鏌ヨ澶辫触");
+        }
+      })
+      .catch(error => {
+        ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+      })
+      .finally(() => {
+        tableLoading.value = false;
+      });
+  };
+  const energyTypeList = ref([]);
+  const getEnergyTypeList = () => {
+    energyTypeListPage({ current: -1, size: -1 })
+      .then(res => {
+        if (res.code === 200) {
+          energyTypeList.value = res.data.records;
+        } else {
+          ElMessage.error(res.message || "鏌ヨ澶辫触");
+        }
+      })
+      .catch(error => {
+        ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+      });
+  };
+
+  // 閲嶇疆
+  const handleReset = () => {
+    searchForm.energyType = "";
+    searchForm.dateRange = [];
+    page.current = 1;
+    handleQuery();
+  };
+
+  // 瀵煎嚭
+  const handleExport = () => {
+    proxy.download(
+      "/energyConsumptionDetail/export",
+      { type: "鐢熶骇" },
+      "鑳借�楁槑缁�.xlsx"
+    );
+  };
+
+  // 鍒嗛〉澶у皬鍙樺寲
+  const handleSizeChange = val => {
+    page.size = val;
+    handleQuery();
+  };
+
+  // 椤电爜鍙樺寲
+  const handleCurrentChange = val => {
+    page.current = val;
+    handleQuery();
+  };
+
+  // 澶勭悊鑳芥簮绫诲瀷鍙樺寲
+  const handleEnergyTypeChange = value => {
+    const selectedType = energyTypeList.value.find(item => item.id === value);
+    if (selectedType) {
+      form.energyName = selectedType.energyName;
+      form.energyId = selectedType.id;
+      form.unit = selectedType.unit;
+    }
+  };
+
+  // 鏂板
+  const handleAdd = () => {
+    isEdit.value = false;
+    currentId.value = null;
+    dialogTitle.value = "鏂板鑳借�楄褰�";
+    resetForm();
+    dialogVisible.value = true;
+  };
+
+  // 缂栬緫
+  const handleEdit = row => {
+    isEdit.value = true;
+    currentId.value = row.id;
+    dialogTitle.value = "缂栬緫鑳借�楄褰�";
+    Object.assign(form, row);
+    dialogVisible.value = true;
+  };
+
+  // 鍒犻櫎
+  const handleDelete = row => {
+    ElMessageBox.confirm("纭畾瑕佸垹闄よ鑳借�楄褰曞悧锛�", "鎻愮ず", {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    }).then(() => {
+      tableLoading.value = true;
+      energyConsumptionDetailDelete([row.id])
+        .then(res => {
+          if (res.code === 200) {
+            ElMessage.success("鍒犻櫎鎴愬姛");
+            handleQuery();
+          } else {
+            ElMessage.error(res.message || "鍒犻櫎澶辫触");
+          }
+        })
+        .catch(error => {
+          ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+        })
+        .finally(() => {
+          tableLoading.value = false;
+        });
+    });
+  };
+
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    form.meterReadingDate = "";
+    form.energyType = "";
+    form.energyName = "";
+    form.energyId = "";
+    form.meterReadingLocation = "";
+    form.startCode = 0;
+    form.stopCode = 0;
+    form.dosage = 0;
+    form.unit = "";
+    form.remark = "";
+    form.type = "鐢熶骇";
+  };
+
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = () => {
+    formRef.value.validate(valid => {
+      if (valid) {
+        tableLoading.value = true;
+        energyConsumptionDetailAdd(form)
+          .then(res => {
+            if (res.code === 200) {
+              ElMessage.success(isEdit.value ? "缂栬緫鎴愬姛" : "鏂板鎴愬姛");
+              dialogVisible.value = false;
+              handleQuery();
+            } else {
+              ElMessage.error(res.message || "鎿嶄綔澶辫触");
+            }
+          })
+          .catch(error => {
+            ElMessage.error("缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+          })
+          .finally(() => {
+            tableLoading.value = false;
+          });
+      }
+    });
+  };
+
+  onMounted(() => {
+    getEnergyTypeList();
+    handleQuery();
+  });
+</script>
+
+<style scoped lang="scss">
+  .app-container {
+    padding: 24px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 48px);
+  }
+
+  .search_form {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 24px;
+    padding: 20px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
+    }
+  }
+
+  .table_list {
+    // margin-bottom: 24px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    overflow: hidden;
+    height: calc(100vh - 250px);
+  }
+
+  :deep(.el-table) {
+    border: none;
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-table__header-wrapper {
+      background-color: #fafafa;
+
+      th {
+        background-color: #fafafa;
+        font-weight: 600;
+        color: #303133;
+        border-bottom: 1px solid #ebeef5;
+        padding: 14px 0;
+      }
+    }
+
+    .el-table__body-wrapper {
+      tr {
+        transition: all 0.3s ease;
+
+        &:hover {
+          background-color: #f5f7fa;
+        }
+
+        td {
+          border-bottom: 1px solid #ebeef5;
+          padding: 12px 0;
+        }
+      }
+
+      tr.current-row {
+        background-color: #ecf5ff;
+      }
+    }
+
+    .el-table__empty-block {
+      padding: 40px 0;
+    }
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+    padding: 16px 20px;
+    background-color: #ffffff;
+    border-top: 1px solid #ebeef5;
+    border-radius: 0 0 12px 12px;
+  }
+
+  :deep(.el-button) {
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-1px);
+    }
+  }
+
+  :deep(.el-dialog) {
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-dialog__header {
+      background-color: #fafafa;
+      border-bottom: 1px solid #ebeef5;
+      padding: 20px 24px;
+
+      .el-dialog__title {
+        font-size: 16px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+
+    .el-dialog__body {
+      padding: 24px;
+    }
+
+    .el-dialog__footer {
+      padding: 16px 24px;
+      border-top: 1px solid #ebeef5;
+      background-color: #fafafa;
+    }
+  }
+
+  :deep(.el-form) {
+    .el-form-item {
+      margin-bottom: 20px;
+
+      .el-form-item__label {
+        font-weight: 500;
+        color: #303133;
+      }
+
+      .el-input,
+      .el-select,
+      .el-date-picker,
+      .el-input-number {
+        width: 100%;
+
+        // .el-input__inner {
+        //   border-radius: 6px;
+        //   border: 1px solid #dcdfe6;
+        //   transition: all 0.3s ease;
+
+        //   &:focus {
+        //     border-color: #409eff;
+        //     box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+        //   }
+        // }
+      }
+    }
+  }
+
+  :deep(.el-tag) {
+    border-radius: 4px;
+    padding: 2px 8px;
+    font-size: 12px;
+  }
+
+  @media (max-width: 768px) {
+    .app-container {
+      padding: 16px;
+    }
+
+    .search_form {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 12px;
+
+      .el-form {
+        width: 100%;
+
+        .el-form-item {
+          width: 100%;
+        }
+      }
+
+      > div {
+        width: 100%;
+        display: flex;
+        gap: 12px;
+
+        .el-button {
+          flex: 1;
+        }
+      }
+    }
+
+    :deep(.el-table) {
+      th,
+      td {
+        padding: 10px 0;
+        font-size: 12px;
+      }
+    }
+
+    :deep(.el-dialog) {
+      width: 90% !important;
+      margin: 20px auto !important;
+    }
+  }
+  .consumption-value {
+    font-weight: bold;
+    color: #409eff;
+  }
+
+  .consumption-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-left: 4px;
+  }
+  .search_form {
+    :deep(.el-form-item) {
+      margin-bottom: 0px !important;
+    }
+  }
+</style>
diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index 15c1fa9..7c475ce 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -50,6 +50,7 @@
                 :column="tableColumn"
                 :tableData="tableData"
                 :page="page"
+                height="calc(100vh - 350px)"
                 :tableLoading="tableLoading"
                 :isSelection="true"
                 :selectable="isSelectable"
@@ -63,12 +64,12 @@
                width="500px">
       <el-form :model="mergeForm"
                label-width="120px">
-        <el-form-item label="鐢熶骇璁″垝鍙�">
-          <el-input v-model="mergeForm.productionPlanNo"
+        <el-form-item label="搴忓垪鍙�">
+          <el-input v-model="mergeForm.serialNo"
                     disabled />
         </el-form-item>
         <el-form-item label="鐢熶骇璁″垝鏁伴噺">
-          <el-input-number v-model="mergeForm.totalManufactureQuantity"
+          <el-input-number v-model="mergeForm.totalquantity"
                            :min="1"
                            :step="1"
                            style="width: 100%" />
@@ -93,17 +94,83 @@
       <el-table :data="categorySummary"
                 border
                 style="width: 100%">
-        <el-table-column prop="productCategory"
+        <el-table-column prop="materialCategory"
                          label="浜у搧绫诲埆"
                          align="center"
                          width="150" />
-        <el-table-column prop="totalManufactureQuantity"
+        <el-table-column prop="totalquantity"
                          label="鎬诲埗閫犳暟閲�"
                          align="center" />
       </el-table>
       <template #footer>
         <span class="dialog-footer">
           <el-button @click="showCategorySummaryDialog = false">鍏抽棴</el-button>
+        </span>
+      </template>
+    </el-dialog>
+    <!-- 杩借釜杩涘害寮圭獥 -->
+    <el-dialog v-model="showTrackProgressDialog"
+               :title="`杩借釜杩涘害 - ${trackProgressForm.serialNo || ''}`"
+               width="600px">
+      <el-form :model="trackProgressForm"
+               label-width="120px">
+        <el-form-item label="搴忓垪鍙�">
+          <el-input v-model="trackProgressForm.serialNo"
+                    disabled />
+        </el-form-item>
+        <el-form-item label="褰撳墠鐘舵��">
+          <el-select v-model="trackProgressForm.currentStatus"
+                     placeholder="璇烽�夋嫨鐘舵��">
+            <el-option label="寰呭鐞�"
+                       value="pending" />
+            <el-option label="杩涜涓�"
+                       value="processing" />
+            <el-option label="宸插畬鎴�"
+                       value="completed" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="瀹屾垚杩涘害">
+          <el-progress :percentage="trackProgressForm.completionRate"
+                       :status="trackProgressForm.completionRate === 100 ? 'success' : ''" />
+        </el-form-item>
+        <el-form-item label="杩涘害璇︽儏">
+          <el-table :data="trackProgressForm.progressDetails"
+                    border
+                    style="width: 100%">
+            <el-table-column prop="step"
+                             label="姝ラ"
+                             align="center"
+                             width="100" />
+            <el-table-column prop="status"
+                             label="鐘舵��"
+                             align="center"
+                             width="100">
+              <template #default="scope">
+                <el-tag :type="scope.row.status === 'completed' ? 'success' : scope.row.status === 'processing' ? 'warning' : 'info'">
+                  {{ scope.row.status === 'completed' ? '宸插畬鎴�' : scope.row.status === 'processing' ? '杩涜涓�' : '寰呭紑濮�' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="startTime"
+                             label="寮�濮嬫椂闂�"
+                             align="center"
+                             width="180" />
+            <el-table-column prop="endTime"
+                             label="缁撴潫鏃堕棿"
+                             align="center"
+                             width="180" />
+          </el-table>
+        </el-form-item>
+        <el-form-item label="澶囨敞">
+          <el-input v-model="trackProgressForm.remark"
+                    type="textarea" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="showTrackProgressDialog = false">鍏抽棴</el-button>
+          <el-button type="primary"
+                     @click="handleUpdateProgress">鏇存柊杩涘害</el-button>
         </span>
       </template>
     </el-dialog>
@@ -114,7 +181,7 @@
   import { onMounted, ref } from "vue";
   import { ElMessage } from "element-plus";
   import dayjs from "dayjs";
-  import { productOrderListPage } from "@/api/productionManagement/productionOrder.js";
+  import { productionPlanListPage } from "@/api/productionPlan/productionPlan.js";
   import PIMTable from "./components/PIMTable.vue";
 
   const tableColumn = ref([
@@ -139,8 +206,8 @@
       width: "120px",
     },
     {
-      label: "鐢熶骇璁″垝鍙�",
-      prop: "productionPlanNo",
+      label: "搴忓垪鍙�",
+      prop: "serialNo",
       width: "140px",
     },
     {
@@ -155,7 +222,7 @@
     },
     {
       label: "浜у搧绫诲埆",
-      prop: "productCategory",
+      prop: "materialCategory",
       width: "100px",
     },
     {
@@ -171,7 +238,7 @@
     },
     {
       label: "鍒堕�犳暟閲�",
-      prop: "manufactureQuantity",
+      prop: "quantity",
       width: "100px",
       align: "right",
     },
@@ -237,8 +304,8 @@
           clickFun: row => {
             // 鍗曠嫭涓嬪彂鎿嶄綔
             // 璁剧疆琛ㄥ崟鏁版嵁
-            mergeForm.productionPlanNo = row.productionPlanNo;
-            mergeForm.totalManufactureQuantity = row.manufactureQuantity;
+            mergeForm.serialNo = row.serialNo;
+            mergeForm.totalquantity = row.quantity;
             mergeForm.remark = "";
 
             // 鎵撳紑寮圭獥
@@ -249,8 +316,7 @@
           name: "杩借釜杩涘害",
           type: "text",
           clickFun: row => {
-            // 杩借釜杩涘害鎿嶄綔
-            ElMessage.warning("杩借釜杩涘害鍔熻兘寰呭紑鍙�");
+            handleTrackProgress(row);
           },
         },
       ],
@@ -274,17 +340,118 @@
   const isShowNewModal = ref(false);
   // 鍚堝苟涓嬪彂琛ㄥ崟鏁版嵁
   const mergeForm = reactive({
-    productionPlanNo: "",
-    totalManufactureQuantity: 0,
+    serialNo: "",
+    totalquantity: 0,
     remark: "",
   });
+
+  // 杩借釜杩涘害寮圭獥鎺у埗
+  const showTrackProgressDialog = ref(false);
+  // 杩借釜杩涘害琛ㄥ崟鏁版嵁
+  const trackProgressForm = reactive({
+    serialNo: "",
+    currentStatus: "",
+    completionRate: 0,
+    progressDetails: [],
+    remark: "",
+  });
+
+  // 澶勭悊杩借釜杩涘害鎸夐挳鐐瑰嚮
+  const handleTrackProgress = row => {
+    // 璁剧疆琛ㄥ崟鏁版嵁
+    trackProgressForm.serialNo = row.serialNo;
+    trackProgressForm.currentStatus = row.status;
+
+    // 鐢熸垚妯℃嫙杩涘害鏁版嵁
+    trackProgressForm.progressDetails = generateProgressDetails(row.status);
+
+    // 璁$畻瀹屾垚鐜�
+    trackProgressForm.completionRate = calculateCompletionRate(
+      trackProgressForm.progressDetails
+    );
+    trackProgressForm.remark = "";
+
+    // 鎵撳紑寮圭獥
+    showTrackProgressDialog.value = true;
+  };
+
+  // 鐢熸垚妯℃嫙杩涘害璇︽儏鏁版嵁
+  const generateProgressDetails = status => {
+    const details = [
+      {
+        step: "璁″垝纭",
+        status: "completed",
+        startTime: "2026-03-01 09:00:00",
+        endTime: "2026-03-01 10:00:00",
+      },
+      {
+        step: "鐗╂枡鍑嗗",
+        status:
+          status === "completed"
+            ? "completed"
+            : status === "processing"
+            ? "completed"
+            : "pending",
+        startTime:
+          status === "completed" || status === "processing"
+            ? "2026-03-01 10:30:00"
+            : "",
+        endTime:
+          status === "completed" || status === "processing"
+            ? "2026-03-02 16:00:00"
+            : "",
+      },
+      {
+        step: "鐢熶骇鍔犲伐",
+        status:
+          status === "completed"
+            ? "completed"
+            : status === "processing"
+            ? "processing"
+            : "pending",
+        startTime:
+          status === "completed" || status === "processing"
+            ? "2026-03-03 08:00:00"
+            : "",
+        endTime: status === "completed" ? "2026-03-08 17:00:00" : "",
+      },
+      {
+        step: "璐ㄩ噺妫�楠�",
+        status: status === "completed" ? "completed" : "pending",
+        startTime: status === "completed" ? "2026-03-09 09:00:00" : "",
+        endTime: status === "completed" ? "2026-03-09 15:00:00" : "",
+      },
+      {
+        step: "鍏ュ簱",
+        status: status === "completed" ? "completed" : "pending",
+        startTime: status === "completed" ? "2026-03-10 10:00:00" : "",
+        endTime: status === "completed" ? "2026-03-10 11:00:00" : "",
+      },
+    ];
+    return details;
+  };
+
+  // 璁$畻瀹屾垚鐜�
+  const calculateCompletionRate = details => {
+    const completedSteps = details.filter(
+      step => step.status === "completed"
+    ).length;
+    return Math.round((completedSteps / details.length) * 100);
+  };
+
+  // 澶勭悊杩涘害鏇存柊
+  const handleUpdateProgress = () => {
+    // 杩欓噷鍙互娣诲姞鏇存柊杩涘害鐨勯�昏緫
+    ElMessage.success("杩涘害鏇存柊鎴愬姛");
+    showTrackProgressDialog.value = false;
+  };
 
   const data = reactive({
     searchForm: {
       customerName: "",
       salesContractNo: "",
       projectName: "",
-      productCategory: "",
+      materialCategory: "",
       specificationModel: "",
     },
   });
@@ -307,14 +474,14 @@
 
     // 閬嶅巻琛ㄦ牸鏁版嵁锛屾寜浜у搧绫诲埆姹囨��
     tableData.value.forEach(row => {
-      const category = row.productCategory;
+      const category = row.materialCategory;
       if (!summary[category]) {
         summary[category] = {
-          productCategory: category,
-          totalManufactureQuantity: 0,
+          materialCategory: category,
+          totalquantity: 0,
         };
       }
-      summary[category].totalManufactureQuantity += row.manufactureQuantity;
+      summary[category].totalquantity += row.quantity;
     });
 
     // 杞崲涓烘暟缁勬牸寮�
@@ -326,164 +493,164 @@
     // 鏋勯�犱竴涓柊鐨勫璞★紝涓嶅寘鍚玡ntryDate瀛楁
     const params = { ...searchForm.value, ...page };
     params.entryDate = undefined;
-    tableData.value = [
-      {
-        id: 1,
-        source: "閿�鍞鍗�",
-        status: "寰呭鐞�",
-        auditStatus: "宸插鏍�",
-        orderNo: "SO20260301001",
-        productionPlanNo: "PP20260301001",
-        partNo: "P001",
-        partName: "闆朵欢A",
-        productCategory: "绫诲埆1",
-        processFileNo: "PF20260301001",
-        salesQuantity: 100,
-        manufactureQuantity: 105,
-        partUnit: "涓�",
-        mainPlanDemandDate: "2026-03-15",
-        commitmentDate: "2026-03-10",
-        manufactureProperty: "甯歌",
-        remark: "",
-        updateTime: "2026-03-01",
-        updateBy: "admin",
-        createTime: "2026-03-01",
-        createBy: "admin",
-      },
-      {
-        id: 2,
-        source: "閿�鍞鍗�",
-        status: "寰呭鐞�",
-        auditStatus: "宸插鏍�",
-        orderNo: "SO20260301002",
-        productionPlanNo: "PP20260301001",
-        partNo: "P002",
-        partName: "闆朵欢B",
-        productCategory: "绫诲埆1",
-        processFileNo: "PF20260301002",
-        salesQuantity: 200,
-        manufactureQuantity: 210,
-        partUnit: "涓�",
-        mainPlanDemandDate: "2026-03-15",
-        commitmentDate: "2026-03-10",
-        manufactureProperty: "甯歌",
-        remark: "",
-        updateTime: "2026-03-01",
-        updateBy: "admin",
-        createTime: "2026-03-01",
-        createBy: "admin",
-      },
-      {
-        id: 3,
-        source: "閿�鍞鍗�",
-        status: "杩涜涓�",
-        auditStatus: "宸插鏍�",
-        orderNo: "SO20260301003",
-        productionPlanNo: "PP20260301002",
-        partNo: "P003",
-        partName: "闆朵欢C",
-        productCategory: "绫诲埆2",
-        processFileNo: "PF20260301003",
-        salesQuantity: 150,
-        manufactureQuantity: 155,
-        partUnit: "涓�",
-        mainPlanDemandDate: "2026-03-20",
-        commitmentDate: "2026-03-15",
-        manufactureProperty: "甯歌",
-        remark: "",
-        updateTime: "2026-03-01",
-        updateBy: "admin",
-        createTime: "2026-03-01",
-        createBy: "admin",
-      },
-      {
-        id: 4,
-        source: "閿�鍞鍗�",
-        status: "杩涜涓�",
-        auditStatus: "宸插鏍�",
-        orderNo: "SO20260301004",
-        productionPlanNo: "PP20260301002",
-        partNo: "P004",
-        partName: "闆朵欢D",
-        productCategory: "绫诲埆2",
-        processFileNo: "PF20260301004",
-        salesQuantity: 300,
-        manufactureQuantity: 315,
-        partUnit: "涓�",
-        mainPlanDemandDate: "2026-03-20",
-        commitmentDate: "2026-03-15",
-        manufactureProperty: "甯歌",
-        remark: "",
-        updateTime: "2026-03-01",
-        updateBy: "admin",
-        createTime: "2026-03-01",
-        createBy: "admin",
-      },
-      {
-        id: 5,
-        source: "閿�鍞鍗�",
-        status: "宸插畬鎴�",
-        auditStatus: "宸插鏍�",
-        orderNo: "SO20260301005",
-        productionPlanNo: "PP20260301003",
-        partNo: "P005",
-        partName: "闆朵欢E",
-        productCategory: "绫诲埆3",
-        processFileNo: "PF20260301005",
-        salesQuantity: 250,
-        manufactureQuantity: 260,
-        partUnit: "涓�",
-        mainPlanDemandDate: "2026-03-10",
-        commitmentDate: "2026-03-05",
-        manufactureProperty: "甯歌",
-        remark: "",
-        updateTime: "2026-03-01",
-        updateBy: "admin",
-        createTime: "2026-03-01",
-        createBy: "admin",
-      },
-    ];
-    tableLoading.value = false;
-    page.total = tableData.value.length;
-    // 璁$畻浜у搧绫诲埆姹囨�荤粺璁�
-    calculateCategorySummary();
-    // productOrderListPage(params)
-    //   .then(res => {
-    //     tableLoading.value = false;
+    // tableData.value = [
+    //   {
+    //     id: 1,
+    //     source: "閿�鍞鍗�",
+    //     status: "寰呭鐞�",
+    //     auditStatus: "宸插鏍�",
+    //     orderNo: "SO20260301001",
+    //     serialNo: "PP20260301001",
+    //     partNo: "P001",
+    //     partName: "闆朵欢A",
+    //     materialCategory: "绫诲埆1",
+    //     processFileNo: "PF20260301001",
+    //     salesQuantity: 100,
+    //     quantity: 105,
+    //     partUnit: "涓�",
+    //     mainPlanDemandDate: "2026-03-15",
+    //     commitmentDate: "2026-03-10",
+    //     manufactureProperty: "甯歌",
+    //     remark: "",
+    //     updateTime: "2026-03-01",
+    //     updateBy: "admin",
+    //     createTime: "2026-03-01",
+    //     createBy: "admin",
+    //   },
+    //   {
+    //     id: 2,
+    //     source: "閿�鍞鍗�",
+    //     status: "寰呭鐞�",
+    //     auditStatus: "宸插鏍�",
+    //     orderNo: "SO20260301002",
+    //     serialNo: "PP20260301001",
+    //     partNo: "P002",
+    //     partName: "闆朵欢B",
+    //     materialCategory: "绫诲埆1",
+    //     processFileNo: "PF20260301002",
+    //     salesQuantity: 200,
+    //     quantity: 210,
+    //     partUnit: "涓�",
+    //     mainPlanDemandDate: "2026-03-15",
+    //     commitmentDate: "2026-03-10",
+    //     manufactureProperty: "甯歌",
+    //     remark: "",
+    //     updateTime: "2026-03-01",
+    //     updateBy: "admin",
+    //     createTime: "2026-03-01",
+    //     createBy: "admin",
+    //   },
+    //   {
+    //     id: 3,
+    //     source: "閿�鍞鍗�",
+    //     status: "杩涜涓�",
+    //     auditStatus: "宸插鏍�",
+    //     orderNo: "SO20260301003",
+    //     serialNo: "PP20260301002",
+    //     partNo: "P003",
+    //     partName: "闆朵欢C",
+    //     materialCategory: "绫诲埆2",
+    //     processFileNo: "PF20260301003",
+    //     salesQuantity: 150,
+    //     quantity: 155,
+    //     partUnit: "涓�",
+    //     mainPlanDemandDate: "2026-03-20",
+    //     commitmentDate: "2026-03-15",
+    //     manufactureProperty: "甯歌",
+    //     remark: "",
+    //     updateTime: "2026-03-01",
+    //     updateBy: "admin",
+    //     createTime: "2026-03-01",
+    //     createBy: "admin",
+    //   },
+    //   {
+    //     id: 4,
+    //     source: "閿�鍞鍗�",
+    //     status: "杩涜涓�",
+    //     auditStatus: "宸插鏍�",
+    //     orderNo: "SO20260301004",
+    //     serialNo: "PP20260301002",
+    //     partNo: "P004",
+    //     partName: "闆朵欢D",
+    //     materialCategory: "绫诲埆2",
+    //     processFileNo: "PF20260301004",
+    //     salesQuantity: 300,
+    //     quantity: 315,
+    //     partUnit: "涓�",
+    //     mainPlanDemandDate: "2026-03-20",
+    //     commitmentDate: "2026-03-15",
+    //     manufactureProperty: "甯歌",
+    //     remark: "",
+    //     updateTime: "2026-03-01",
+    //     updateBy: "admin",
+    //     createTime: "2026-03-01",
+    //     createBy: "admin",
+    //   },
+    //   {
+    //     id: 5,
+    //     source: "閿�鍞鍗�",
+    //     status: "宸插畬鎴�",
+    //     auditStatus: "宸插鏍�",
+    //     orderNo: "SO20260301005",
+    //     serialNo: "PP20260301003",
+    //     partNo: "P005",
+    //     partName: "闆朵欢E",
+    //     materialCategory: "绫诲埆3",
+    //     processFileNo: "PF20260301005",
+    //     salesQuantity: 250,
+    //     quantity: 260,
+    //     partUnit: "涓�",
+    //     mainPlanDemandDate: "2026-03-10",
+    //     commitmentDate: "2026-03-05",
+    //     manufactureProperty: "甯歌",
+    //     remark: "",
+    //     updateTime: "2026-03-01",
+    //     updateBy: "admin",
+    //     createTime: "2026-03-01",
+    //     createBy: "admin",
+    //   },
+    // ];
+    // tableLoading.value = false;
+    // page.total = tableData.value.length;
+    // // 璁$畻浜у搧绫诲埆姹囨�荤粺璁�
+    // calculateCategorySummary();
+    productionPlanListPage(params)
+      .then(res => {
+        tableLoading.value = false;
 
-    //     tableData.value = res.data.records;
-    //     page.total = res.data.total;
-    //     // 璁$畻浜у搧绫诲埆姹囨�荤粺璁�
-    //     calculateCategorySummary();
-    //   })
-    //   .catch(() => {
-    //     tableLoading.value = false;
-    //   });
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+        // 璁$畻浜у搧绫诲埆姹囨�荤粺璁�
+        calculateCategorySummary();
+      })
+      .catch(() => {
+        tableLoading.value = false;
+      });
   };
 
-  // 閫変腑鐨勭敓浜ц鍒掑彿
-  const selectedProductionPlanNo = ref("");
+  // 閫変腑鐨勫簭鍒楀彿
+  const selectedserialNo = ref("");
 
   // 琛ㄦ牸閫夋嫨鏁版嵁
   const handleSelectionChange = selection => {
     selectedRows.value = selection;
-    // 濡傛灉鏈夐�変腑鐨勮锛岃褰曠涓�涓�変腑琛岀殑鐢熶骇璁″垝鍙�
+    // 濡傛灉鏈夐�変腑鐨勮锛岃褰曠涓�涓�変腑琛岀殑搴忓垪鍙�
     if (selection.length > 0) {
-      selectedProductionPlanNo.value = selection[0].productionPlanNo;
+      selectedserialNo.value = selection[0].serialNo;
     } else {
-      // 濡傛灉娌℃湁閫変腑鐨勮锛屾竻绌虹敓浜ц鍒掑彿
-      selectedProductionPlanNo.value = "";
+      // 濡傛灉娌℃湁閫変腑鐨勮锛屾竻绌哄簭鍒楀彿
+      selectedserialNo.value = "";
     }
   };
 
   // 鍒ゆ柇琛屾槸鍚﹀彲閫夋嫨
   const isSelectable = row => {
     // 濡傛灉娌℃湁閫変腑鐨勮锛屾墍鏈夎閮藉彲閫夋嫨
-    if (!selectedProductionPlanNo.value) {
+    if (!selectedserialNo.value) {
       return true;
     }
-    // 濡傛灉鏈夐�変腑鐨勮锛屽彧鏈夌敓浜ц鍒掑彿鐩稿悓鐨勮鎵嶅彲閫夋嫨
-    return row.productionPlanNo === selectedProductionPlanNo.value;
+    // 濡傛灉鏈夐�変腑鐨勮锛屽彧鏈夊簭鍒楀彿鐩稿悓鐨勮鎵嶅彲閫夋嫨
+    return row.serialNo === selectedserialNo.value;
   };
 
   // 澶勭悊鍚堝苟涓嬪彂鎸夐挳鐐瑰嚮
@@ -495,12 +662,12 @@
 
     // 璁$畻鎬诲埗閫犳暟閲�
     const totalQuantity = selectedRows.value.reduce((sum, row) => {
-      return sum + row.manufactureQuantity;
+      return sum + row.quantity;
     }, 0);
 
     // 璁剧疆琛ㄥ崟鏁版嵁
-    mergeForm.productionPlanNo = selectedProductionPlanNo.value;
-    mergeForm.totalManufactureQuantity = totalQuantity;
+    mergeForm.serialNo = selectedserialNo.value;
+    mergeForm.totalquantity = totalQuantity;
     mergeForm.remark = "";
 
     // 鎵撳紑寮圭獥
@@ -521,56 +688,212 @@
 </script>
 
 <style scoped lang="scss">
+  .app-container {
+    padding: 24px;
+    background-color: #f0f2f5;
+    min-height: calc(100vh - 48px);
+  }
+
   .search_form {
-    align-items: start;
-  }
-
-  .summary-section {
-    margin-bottom: 16px;
-  }
-
-  .horizontal-summary {
     display: flex;
-    flex-wrap: wrap;
-    gap: 20px;
-    padding: 10px 0;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 24px;
+    padding: 20px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.08);
+    }
   }
 
-  .summary-item {
-    flex: 1;
-    min-width: 120px;
-    text-align: center;
-    padding: 10px;
-    background-color: #f5f7fa;
+  .table_list {
+    // margin-bottom: 24px;
+    background-color: #ffffff;
+    border-radius: 6px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+    overflow: hidden;
+    height: calc(100vh - 250px);
+  }
+
+  :deep(.el-table) {
+    border: none;
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-table__header-wrapper {
+      background-color: #fafafa;
+
+      th {
+        background-color: #fafafa;
+        font-weight: 600;
+        color: #303133;
+        border-bottom: 1px solid #ebeef5;
+        padding: 14px 0;
+      }
+    }
+
+    .el-table__body-wrapper {
+      tr {
+        transition: all 0.3s ease;
+
+        &:hover {
+          background-color: #f5f7fa;
+        }
+
+        td {
+          border-bottom: 1px solid #ebeef5;
+          padding: 12px 0;
+        }
+      }
+
+      tr.current-row {
+        background-color: #ecf5ff;
+      }
+    }
+
+    .el-table__empty-block {
+      padding: 40px 0;
+    }
+  }
+
+  .pagination-container {
+    display: flex;
+    justify-content: flex-end;
+    padding: 16px 20px;
+    background-color: #ffffff;
+    border-top: 1px solid #ebeef5;
+    border-radius: 0 0 12px 12px;
+  }
+
+  :deep(.el-button) {
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-1px);
+    }
+  }
+
+  :deep(.el-dialog) {
+    border-radius: 6px;
+    overflow: hidden;
+
+    .el-dialog__header {
+      background-color: #fafafa;
+      border-bottom: 1px solid #ebeef5;
+      padding: 20px 24px;
+
+      .el-dialog__title {
+        font-size: 16px;
+        font-weight: 600;
+        color: #303133;
+      }
+    }
+
+    .el-dialog__body {
+      padding: 24px;
+    }
+
+    .el-dialog__footer {
+      padding: 16px 24px;
+      border-top: 1px solid #ebeef5;
+      background-color: #fafafa;
+    }
+  }
+
+  :deep(.el-form) {
+    .el-form-item {
+      margin-bottom: 20px;
+
+      .el-form-item__label {
+        font-weight: 500;
+        color: #303133;
+      }
+
+      .el-input,
+      .el-select,
+      .el-date-picker,
+      .el-input-number {
+        width: 100%;
+
+        // .el-input__inner {
+        //   border-radius: 6px;
+        //   border: 1px solid #dcdfe6;
+        //   transition: all 0.3s ease;
+
+        //   &:focus {
+        //     border-color: #409eff;
+        //     box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+        //   }
+        // }
+      }
+    }
+  }
+
+  :deep(.el-tag) {
     border-radius: 4px;
-    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+    padding: 2px 8px;
+    font-size: 12px;
   }
 
-  .summary-label {
-    font-size: 14px;
-    color: #606266;
-    margin-bottom: 5px;
+  @media (max-width: 768px) {
+    .app-container {
+      padding: 16px;
+    }
+
+    .search_form {
+      flex-direction: column;
+      align-items: flex-start;
+      gap: 12px;
+
+      .el-form {
+        width: 100%;
+
+        .el-form-item {
+          width: 100%;
+        }
+      }
+
+      > div {
+        width: 100%;
+        display: flex;
+        gap: 12px;
+
+        .el-button {
+          flex: 1;
+        }
+      }
+    }
+
+    :deep(.el-table) {
+      th,
+      td {
+        padding: 10px 0;
+        font-size: 12px;
+      }
+    }
+
+    :deep(.el-dialog) {
+      width: 90% !important;
+      margin: 20px auto !important;
+    }
+  }
+  .consumption-value {
+    font-weight: bold;
+    color: #409eff;
   }
 
-  .summary-value {
-    font-size: 18px;
-    font-weight: 600;
-    color: #303133;
+  .consumption-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-left: 4px;
   }
-
-  ::v-deep .yellow {
-    background-color: #faf0de;
-  }
-
-  ::v-deep .pink {
-    background-color: #fae1de;
-  }
-
-  ::v-deep .red {
-    background-color: #f80202;
-  }
-
-  ::v-deep .purple {
-    background-color: #f4defa;
+  .search_form {
+    :deep(.el-form-item) {
+      margin-bottom: 0px !important;
+    }
   }
 </style>

--
Gitblit v1.9.3