From b690250002ee04f4309e6a90fd16fbfd9bd959e2 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 01 五月 2026 23:11:23 +0800
Subject: [PATCH] feat(router): 添加托盘操作页面路由

---
 Code/WMS/WIDESEA_WMSClient/src/views/Home.vue |  324 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 316 insertions(+), 8 deletions(-)

diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
index 820437a..9023c51 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
@@ -1,24 +1,332 @@
 <template>
-  <div class="title"></div>
+  <div class="dashboard-container">
+    <!-- 鍚勪粨搴撴湀搴﹀嚭鍏ュ簱瀵规瘮鍥� -->
+    <div class="chart-row full-width">
+      <div class="chart-card">
+        <div class="card-title">鍚勪粨搴撴湀搴﹀嚭鍏ュ簱瀵规瘮</div>
+        <div id="chart-warehouse-monthly" class="chart-content"></div>
+      </div>
+    </div>
+  </div>
 </template>
 
 <script>
-import { ref, reactive } from 'vue'
+import * as echarts from "echarts";
 
 export default {
-  setup() {
+  name: "Home",
+  data() {
     return {
+      charts: {},
+      monthlyData: [],
+      warehouseNames: ['FJSC1', 'ZJSC1', 'GWSC1', 'CWSC1', 'HCSC1']
+    };
+  },
+  mounted() {
+    this.initCharts();
+    this.loadData();
+    window.addEventListener("resize", this.handleResize);
+  },
+  beforeUnmount() {
+    window.removeEventListener("resize", this.handleResize);
+    Object.values(this.charts).forEach(chart => chart.dispose());
+  },
+  methods: {
+    handleResize() {
+      Object.values(this.charts).forEach(chart => chart.resize());
+    },
 
+    initCharts() {
+      this.charts.warehouseMonthly = echarts.init(document.getElementById("chart-warehouse-monthly"));
+    },
+
+    async loadData() {
+      await this.loadMonthlyStats();
+    },
+
+    async loadMonthlyStats() {
+      try {
+        const promises = this.warehouseNames.map(warehouse => 
+          this.http.get("/api/Dashboard/MonthlyStats", { 
+            months: 6, 
+            Roadway: warehouse 
+          })
+        );
+        
+        const results = await Promise.all(promises);
+        
+        this.monthlyData = results.map((res, index) => ({
+          warehouse: this.warehouseNames[index],
+          warehouseName: this.getWarehouseName(this.warehouseNames[index]),
+          data: res.data || []
+        }));
+        
+        this.updateWarehouseMonthlyChart();
+      } catch (e) {
+        console.error("鍔犺浇姣忔湀缁熻澶辫触", e);
+      }
+    },
+
+    getWarehouseName(code) {
+      const nameMap = {
+        'FJSC1': '璐熸瀬鍗�1鍙蜂粨搴�',
+        'ZJSC1': '姝f瀬鍗�1鍙蜂粨搴�',
+        'GWSC1': '楂樻俯1鍙蜂粨搴�',
+        'CWSC1': '甯告俯1鍙蜂粨搴�',
+        'HCSC1': '鍒嗗1鍙蜂粨搴�'
+      };
+      return nameMap[code] || code;
+    },
+
+    updateWarehouseMonthlyChart() {
+      // 鑾峰彇鎵�鏈夋湀浠�
+      const months = this.monthlyData[0]?.data.map(d => `${d.month}鏈坄) || [];
+      
+      // 涓烘瘡涓粨搴撶敓鎴愮郴鍒楁暟鎹�
+      const series = [];
+      
+      this.monthlyData.forEach((warehouseData, index) => {
+        const data = warehouseData.data;
+        
+        series.push({
+          name: warehouseData.warehouseName,
+          type: 'bar',
+          data: data.map(d => ({
+            value: (d.inbound || 0) + (d.outbound || 0),
+            inbound: d.inbound || 0,
+            outbound: d.outbound || 0,
+            label: {
+              show: true,
+              position: 'top',
+              formatter: function(params) {
+                return `鍏�:${params.data.inbound}\n鍑�:${params.data.outbound}`;
+              },
+              fontSize: 10,
+              color: '#fff',
+              lineHeight: 15
+            }
+          })),
+          barWidth: '15%',
+          barGap: '10%',
+          itemStyle: {
+            color: this.getBarColor(index),
+            borderRadius: [3, 3, 0, 0]
+          }
+        });
+      });
+
+      const option = {
+        title: {
+          text: '鍚勪粨搴撴湀搴﹀嚭鍏ュ簱瀵规瘮',
+          textStyle: {
+            color: '#00ffff',
+            fontSize: 16
+          },
+          left: 'center',
+          top: 10
+        },
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          },
+          formatter: function(params) {
+            let tip = `<strong>${params[0].axisValue}</strong><br/>`;
+            params.forEach(param => {
+              tip += `<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:${param.color};margin-right:5px;"></span>`;
+              tip += `${param.seriesName}: `;
+              tip += `鍏ュ簱:${param.data.inbound} | 鍑哄簱:${param.data.outbound} | 鎬昏:${param.value}<br/>`;
+            });
+            return tip;
+          }
+        },
+        legend: {
+          data: this.monthlyData.map(d => d.warehouseName),
+          textStyle: { color: '#fff', fontSize: 11 },
+          top: 45,
+          left: 'center',
+          type: 'scroll'
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '10%',
+          top: '20%',
+          containLabel: true
+        },
+        xAxis: {
+          type: 'category',
+          data: months,
+          axisLabel: {
+            color: '#fff',
+            fontSize: 11
+          },
+          axisLine: {
+            lineStyle: { color: 'rgba(255,255,255,0.3)' }
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: 'rgba(255,255,255,0.1)',
+              type: 'dashed'
+            }
+          }
+        },
+        yAxis: {
+          type: 'value',
+          name: '鏁伴噺',
+          nameTextStyle: { color: '#fff' },
+          axisLabel: { color: '#fff' },
+          splitLine: {
+            lineStyle: {
+              color: 'rgba(255,255,255,0.1)',
+              type: 'dashed'
+            }
+          }
+        },
+        dataZoom: [
+          {
+            type: 'inside',
+            start: 0,
+            end: 100
+          },
+          {
+            start: 0,
+            end: 100,
+            height: 20,
+            bottom: 0,
+            borderColor: 'rgba(255,255,255,0.3)',
+            fillerColor: 'rgba(0,255,255,0.1)',
+            handleStyle: {
+              color: '#00ffff',
+              borderColor: '#00ffff'
+            },
+            textStyle: {
+              color: '#fff'
+            }
+          }
+        ],
+        series: series
+      };
+
+      this.charts.warehouseMonthly.setOption(option, true);
+    },
+
+    getBarColor(index) {
+      const colors = [
+        '#5470c6', // 钃�
+        '#fac858', // 榛�
+        '#73c0de', // 澶╄摑
+        '#fc8452', // 姗�
+        '#ea7ccc'  // 绮�
+      ];
+      return colors[index] || '#5470c6';
     }
   }
-}
+};
 </script>
 
 <style scoped>
-.title {
-  line-height: 70vh;
+.dashboard-container {
+  padding: 20px;
+  color: #e0e0e0;
+  min-height: calc(100vh - 60px);
+  background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
+  background-attachment: fixed;
+}
+
+.chart-row {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+}
+
+.chart-row.full-width {
+  width: 100%;
+}
+
+.chart-card {
+  flex: 1;
+  background: rgba(10, 16, 35, 0.6);
+  backdrop-filter: blur(10px);
+  border: 1px solid rgba(64, 224, 208, 0.3);
+  border-radius: 12px;
+  padding: 15px;
+  position: relative;
+  box-shadow: 
+    0 0 15px rgba(0, 255, 255, 0.1),
+    inset 0 0 10px rgba(64, 224, 208, 0.1);
+  transition: all 0.3s ease;
+  overflow: hidden;
+}
+
+.chart-card:hover {
+  transform: translateY(-5px);
+  box-shadow: 
+    0 0 25px rgba(0, 255, 255, 0.3),
+    inset 0 0 15px rgba(64, 224, 208, 0.2);
+  border: 1px solid rgba(64, 224, 208, 0.6);
+}
+
+.chart-card::before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 10px;
+  height: 10px;
+  border-top: 2px solid #00ffff;
+  border-left: 2px solid #00ffff;
+  box-shadow: -2px -2px 10px #00ffff, 0 0 10px rgba(0, 255, 255, 0.7);
+}
+
+.chart-card::after {
+  content: "";
+  position: absolute;
+  top: 0;
+  right: 0;
+  width: 10px;
+  height: 10px;
+  border-top: 2px solid #00ffff;
+  border-right: 2px solid #00ffff;
+  box-shadow: 2px -2px 10px #00ffff, 0 0 10px rgba(0, 255, 255, 0.7);
+}
+
+.card-title {
+  color: #00ffff;
+  font-size: 16px;
   text-align: center;
-  font-size: 28px;
-  color: orange;
+  margin-bottom: 10px;
+  text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
+  font-weight: 500;
+}
+
+.chart-content {
+  height: 500px;
+  width: 100%;
+}
+
+.full-width .chart-card {
+  flex: none;
+  width: 100%;
+}
+
+.full-width .chart-content {
+  height: 500px;
+}
+
+.dashboard-container::before {
+  content: "";
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-image: 
+    linear-gradient(rgba(64, 224, 208, 0.05) 1px, transparent 1px),
+    linear-gradient(90deg, rgba(64, 224, 208, 0.05) 1px, transparent 1px);
+  background-size: 30px 30px;
+  pointer-events: none;
+  z-index: -1;
 }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3