From af4404160a9e8d14c09f1e6acab2ba00cb7fc91b Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期日, 19 四月 2026 16:32:04 +0800
Subject: [PATCH] fix(WMS): 修复首页、3D、websocket
---
Code/WMS/WIDESEA_WMSClient/src/views/Home.vue | 409 +++++++++++++++++++++++++++------------------------------
1 files changed, 193 insertions(+), 216 deletions(-)
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
index a14728a..ea951db 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
@@ -3,44 +3,21 @@
<!-- 椤堕儴锛氭湰鏈堝嚭鍏ュ簱瓒嬪娍 (鍏ㄥ) -->
<div class="chart-row full-width">
<div class="chart-card">
- <div class="card-title">鏈湀鍑哄叆搴撹秼鍔�</div>
+ <div class="card-title">姣忔湀鍑哄叆搴撹秼鍔�</div>
<div id="chart-monthly-trend" class="chart-content"></div>
</div>
</div>
- <!-- 绗簩琛岋細浠婃棩/鏈懆鍑哄叆搴撳姣� -->
- <div class="chart-row">
+ <!-- 绗簩琛岋細姣忔棩鍑哄叆搴撹秼鍔� (鍏ㄥ) -->
+ <div class="chart-row full-width">
<div class="chart-card">
- <div class="card-title">浠婃棩鍑哄叆搴撳姣�</div>
- <div id="chart-today" class="chart-content"></div>
- </div>
- <div class="chart-card">
- <div class="card-title">鏈懆鍑哄叆搴撳姣�</div>
- <div id="chart-week" class="chart-content"></div>
+ <div class="card-title">姣忔棩鍑哄叆搴撹秼鍔�</div>
+ <div id="chart-daily" class="chart-content"></div>
</div>
</div>
- <!-- 绗笁琛岋細鏈湀瀵规瘮/搴撳瓨鎬婚噺 -->
+ <!-- 绗洓琛岋細浠撳簱鍒嗗竷 -->
<div class="chart-row">
- <div class="chart-card">
- <div class="card-title">鏈湀鍑哄叆搴撳姣�</div>
- <div id="chart-month" class="chart-content"></div>
- </div>
- <div class="chart-card">
- <div class="card-title">褰撳墠搴撳瓨鎬婚噺</div>
- <div class="stock-total">
- <div class="total-number">{{ overviewData.TotalStock || 0 }}</div>
- <div class="total-label">鎵樼洏</div>
- </div>
- </div>
- </div>
-
- <!-- 绗洓琛岋細搴撻緞鍒嗗竷/浠撳簱鍒嗗竷 -->
- <div class="chart-row">
- <div class="chart-card">
- <div class="card-title">搴撳瓨搴撻緞鍒嗗竷</div>
- <div id="chart-stock-age" class="chart-content"></div>
- </div>
<div class="chart-card">
<div class="card-title">鍚勪粨搴撳簱瀛樺垎甯�</div>
<div id="chart-warehouse" class="chart-content"></div>
@@ -57,16 +34,8 @@
data() {
return {
charts: {},
- overviewData: {
- TodayInbound: 0,
- TodayOutbound: 0,
- MonthInbound: 0,
- MonthOutbound: 0,
- TotalStock: 0
- },
- weeklyData: [],
+ dailyData: [],
monthlyData: [],
- stockAgeData: [],
warehouseData: []
};
},
@@ -86,53 +55,22 @@
initCharts() {
this.charts.monthlyTrend = echarts.init(document.getElementById("chart-monthly-trend"));
- this.charts.today = echarts.init(document.getElementById("chart-today"));
- this.charts.week = echarts.init(document.getElementById("chart-week"));
- this.charts.month = echarts.init(document.getElementById("chart-month"));
- this.charts.stockAge = echarts.init(document.getElementById("chart-stock-age"));
+ this.charts.daily = echarts.init(document.getElementById("chart-daily"));
this.charts.warehouse = echarts.init(document.getElementById("chart-warehouse"));
},
async loadData() {
- await this.loadOverview();
- await this.loadWeeklyStats();
await this.loadMonthlyStats();
- await this.loadStockAgeDistribution();
+ await this.loadDailyStats();
await this.loadStockByWarehouse();
- },
-
- async loadOverview() {
- try {
- const res = await this.http.get("/api/Dashboard/Overview");
- console.log("鎬昏鏁版嵁", res.Data);
- if (res.Status && res.Data) {
- this.overviewData = res.Data;
- this.updateTodayChart();
- this.updateWeekChart();
- this.updateMonthChart();
- }
- } catch (e) {
- console.error("鍔犺浇鎬昏鏁版嵁澶辫触", e);
- }
- },
-
- async loadWeeklyStats() {
- try {
- const res = await this.http.get("/api/Dashboard/WeeklyStats", { weeks: 12 });
- if (res.Status && res.Data) {
- this.weeklyData = res.Data;
- this.updateWeekChart();
- }
- } catch (e) {
- console.error("鍔犺浇姣忓懆缁熻澶辫触", e);
- }
},
async loadMonthlyStats() {
try {
const res = await this.http.get("/api/Dashboard/MonthlyStats", { months: 12 });
- if (res.Status && res.Data) {
- this.monthlyData = res.Data;
+ if (res.status && res.data) {
+ console.log("姣忔湀缁熻鏁版嵁:", res.data);
+ this.monthlyData = res.data;
this.updateMonthlyTrendChart();
}
} catch (e) {
@@ -140,110 +78,30 @@
}
},
- async loadStockAgeDistribution() {
+ async loadDailyStats() {
try {
- const res = await this.http.get("/api/Dashboard/StockAgeDistribution");
- if (res.Status && res.Data) {
- this.stockAgeData = res.Data;
- this.updateStockAgeChart();
+ const res = await this.http.get("/api/Dashboard/DailyStats", { days: 30 });
+ if (res.status && res.data) {
+ console.log("姣忔棩缁熻鏁版嵁:", res.data);
+ this.dailyData = res.data;
+ this.updateDailyChart();
}
} catch (e) {
- console.error("鍔犺浇搴撻緞鍒嗗竷澶辫触", e);
+ console.error("鍔犺浇姣忔棩缁熻澶辫触", e);
}
},
async loadStockByWarehouse() {
try {
const res = await this.http.get("/api/Dashboard/StockByWarehouse");
- if (res.Status && res.Data) {
- this.warehouseData = res.Data;
+ if (res.status && res.data) {
+ console.log("浠撳簱鍒嗗竷鏁版嵁:", res.data);
+ this.warehouseData = res.data.data || res.data;
this.updateWarehouseChart();
}
} catch (e) {
console.error("鍔犺浇浠撳簱鍒嗗竷澶辫触", e);
}
- },
-
- updateTodayChart() {
- const option = {
- tooltip: { trigger: "axis" },
- legend: { data: ["鍏ュ簱", "鍑哄簱"], textStyle: { color: "#fff" } },
- xAxis: {
- type: "category",
- data: ["浠婃棩"],
- axisLabel: { color: "#fff" }
- },
- yAxis: {
- type: "value",
- axisLabel: { color: "#fff" }
- },
- series: [
- { name: "鍏ュ簱", type: "bar", data: [this.overviewData.TodayInbound], itemStyle: { color: "#5470c6" } },
- { name: "鍑哄簱", type: "bar", data: [this.overviewData.TodayOutbound], itemStyle: { color: "#91cc75" } }
- ]
- };
- this.charts.today.setOption(option, true);
- },
-
- updateWeekChart() {
- const thisWeek = this.getThisWeekData(this.weeklyData);
- const option = {
- tooltip: { trigger: "axis" },
- legend: { data: ["鍏ュ簱", "鍑哄簱"], textStyle: { color: "#fff" } },
- xAxis: {
- type: "category",
- data: ["鏈懆"],
- axisLabel: { color: "#fff" }
- },
- yAxis: {
- type: "value",
- axisLabel: { color: "#fff" }
- },
- series: [
- { name: "鍏ュ簱", type: "bar", data: [thisWeek.Inbound], itemStyle: { color: "#5470c6" } },
- { name: "鍑哄簱", type: "bar", data: [thisWeek.Outbound], itemStyle: { color: "#91cc75" } }
- ]
- };
- this.charts.week.setOption(option, true);
- },
-
- getThisWeekData(weeklyData) {
- if (!weeklyData || weeklyData.length === 0) return { Inbound: 0, Outbound: 0 };
- const thisWeekKey = this.getCurrentWeekKey();
- const thisWeek = weeklyData.find(w => w.Week === thisWeekKey);
- return thisWeek || { Inbound: 0, Outbound: 0 };
- },
-
- getCurrentWeekKey() {
- const now = new Date();
- const diff = (7 + (now.getDay() - 1)) % 7;
- const monday = new Date(now);
- monday.setDate(now.getDate() - diff);
- const year = monday.getFullYear();
- const jan1 = new Date(year, 0, 1);
- const weekNum = Math.ceil(((monday - jan1) / 86400000 + jan1.getDay() + 1) / 7);
- return `${year}-W${String(weekNum).padStart(2, "0")}`;
- },
-
- updateMonthChart() {
- const option = {
- tooltip: { trigger: "axis" },
- legend: { data: ["鍏ュ簱", "鍑哄簱"], textStyle: { color: "#fff" } },
- xAxis: {
- type: "category",
- data: ["鏈湀"],
- axisLabel: { color: "#fff" }
- },
- yAxis: {
- type: "value",
- axisLabel: { color: "#fff" }
- },
- series: [
- { name: "鍏ュ簱", type: "bar", data: [this.overviewData.MonthInbound], itemStyle: { color: "#5470c6" } },
- { name: "鍑哄簱", type: "bar", data: [this.overviewData.MonthOutbound], itemStyle: { color: "#91cc75" } }
- ]
- };
- this.charts.month.setOption(option, true);
},
updateMonthlyTrendChart() {
@@ -252,7 +110,7 @@
legend: { data: ["鍏ュ簱", "鍑哄簱"], textStyle: { color: "#fff" } },
xAxis: {
type: "category",
- data: this.monthlyData.map(m => m.Month),
+ data: this.monthlyData.map(m => m.month),
axisLabel: { color: "#fff", rotate: 45 }
},
yAxis: [
@@ -263,56 +121,144 @@
}
],
series: [
- { name: "鍏ュ簱", type: "bar", data: this.monthlyData.map(m => m.Inbound), itemStyle: { color: "#5470c6" } },
- { name: "鍑哄簱", type: "line", data: this.monthlyData.map(m => m.Outbound), itemStyle: { color: "#91cc75" } }
+ { name: "鍏ュ簱", type: "bar", data: this.monthlyData.map(m => m.inbound), itemStyle: { color: "#5470c6" } },
+ { name: "鍑哄簱", type: "line", data: this.monthlyData.map(m => m.outbound), itemStyle: { color: "#91cc75" } }
]
};
this.charts.monthlyTrend.setOption(option, true);
},
- updateStockAgeChart() {
+ updateDailyChart() {
const option = {
tooltip: { trigger: "axis" },
+ legend: { data: ["鍏ュ簱", "鍑哄簱"], textStyle: { color: "#fff" } },
xAxis: {
type: "category",
- data: this.stockAgeData.map(s => s.Range),
- axisLabel: { color: "#fff" }
+ data: this.dailyData.map(d => d.date),
+ axisLabel: {
+ color: "#fff",
+ interval: 0,
+ rotate: 45,
+ fontSize: 12,
+ margin: 10
+ },
+ axisTick: {
+ alignWithLabel: true
+ }
},
yAxis: {
type: "value",
axisLabel: { color: "#fff" }
},
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '15%',
+ top: '10%',
+ containLabel: true
+ },
series: [
- {
- type: "bar",
- data: this.stockAgeData.map(s => s.Count),
- itemStyle: { color: "#5470c6" }
- }
+ { name: "鍏ュ簱", type: "bar", data: this.dailyData.map(d => d.inbound), itemStyle: { color: "#5470c6" } },
+ { name: "鍑哄簱", type: "bar", data: this.dailyData.map(d => d.outbound), itemStyle: { color: "#91cc75" } }
]
};
- this.charts.stockAge.setOption(option, true);
+ this.charts.daily.setOption(option, true);
},
updateWarehouseChart() {
+ const warehouseNames = this.warehouseData.map(w => w.warehouse);
+ const totalStocks = this.warehouseData.map(w => w.total);
+ const hasStocks = this.warehouseData.map(w => w.hasStock);
+ const noStocks = this.warehouseData.map(w => w.noStock);
+ const hasStockPercentages = this.warehouseData.map(w => w.hasStockPercentage);
+ const noStockPercentages = this.warehouseData.map(w => w.noStockPercentage);
+
const option = {
- tooltip: { trigger: "axis" },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'shadow'
+ },
+ formatter: function(params) {
+ let tip = params[0].name + '<br/>';
+ params.forEach(param => {
+ const dataIndex = param.dataIndex;
+ const warehouse = window.homeComponent.warehouseData[dataIndex];
+
+ if (param.seriesName === '宸茬敤瀹归噺') {
+ tip += `${param.marker}${param.seriesName}: ${param.value} (${warehouse.hasStockPercentage})<br/>`;
+ tip += `鏈夊簱瀛�: ${warehouse.hasStock}<br/>`;
+ tip += `鏃犲簱瀛�: ${warehouse.noStock}<br/>`;
+ tip += `鎬诲閲�: ${warehouse.total}`;
+ } else if (param.seriesName === '鍓╀綑瀹归噺') {
+ tip += `${param.marker}${param.seriesName}: ${param.value} (${warehouse.noStockPercentage})<br/>`;
+ tip += `鏈夊簱瀛�: ${warehouse.hasStock}<br/>`;
+ tip += `鏃犲簱瀛�: ${warehouse.noStock}<br/>`;
+ tip += `鎬诲閲�: ${warehouse.total}`;
+ }
+ });
+ return tip;
+ }
+ },
+ legend: {
+ data: ['宸茬敤瀹归噺', '鍓╀綑瀹归噺'],
+ textStyle: { color: '#fff' }
+ },
xAxis: {
- type: "category",
- data: this.warehouseData.map(w => w.Warehouse),
- axisLabel: { color: "#fff", rotate: 30 }
+ type: 'category',
+ data: warehouseNames,
+ axisLabel: { color: '#fff', rotate: 30 }
},
yAxis: {
- type: "value",
- axisLabel: { color: "#fff" }
+ type: 'value',
+ axisLabel: { color: '#fff' }
},
series: [
{
- type: "bar",
- data: this.warehouseData.map(w => w.Count),
- itemStyle: { color: "#5470c6" }
+ name: '宸茬敤瀹归噺',
+ type: 'bar',
+ data: hasStocks.map((value, index) => ({
+ value: value,
+ label: {
+ show: true,
+ position: 'top',
+ formatter: '{c} {a|' + hasStockPercentages[index] + '}',
+ rich: {
+ a: {
+ lineHeight: 20,
+ borderColor: '#91cc75',
+ color: '#91cc75'
+ }
+ }
+ }
+ })),
+ itemStyle: { color: '#91cc75' }
+ },
+ {
+ name: '鍓╀綑瀹归噺',
+ type: 'bar',
+ data: noStocks.map((value, index) => ({
+ value: value,
+ label: {
+ show: true,
+ position: 'top',
+ formatter: '{c} {a|' + noStockPercentages[index] + '}',
+ rich: {
+ a: {
+ lineHeight: 20,
+ borderColor: '#fac858',
+ color: '#fac858'
+ }
+ }
+ }
+ })),
+ itemStyle: { color: '#fac858' }
}
]
};
+
+ window.homeComponent = this;
+
this.charts.warehouse.setOption(option, true);
}
}
@@ -322,8 +268,10 @@
<style scoped>
.dashboard-container {
padding: 20px;
- background-color: #0e1a2b;
+ color: #e0e0e0;
min-height: calc(100vh - 60px);
+ background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
+ background-attachment: fixed;
}
.chart-row {
@@ -338,11 +286,25 @@
.chart-card {
flex: 1;
- background: rgba(255, 255, 255, 0.05);
- border: 1px solid rgba(25, 186, 139, 0.17);
- border-radius: 4px;
+ 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 {
@@ -352,8 +314,9 @@
left: 0;
width: 10px;
height: 10px;
- border-top: 2px solid #02a6b5;
- border-left: 2px solid #02a6b5;
+ 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 {
@@ -363,41 +326,39 @@
right: 0;
width: 10px;
height: 10px;
- border-top: 2px solid #02a6b5;
- border-right: 2px solid #02a6b5;
+ 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);
+}
+
+.chart-card::before,
+.chart-card::after {
+ animation: neon-flicker 2s infinite alternate;
+}
+
+@keyframes neon-flicker {
+ 0%, 100% {
+ opacity: 1;
+ box-shadow: -2px -2px 10px #00ffff, 0 0 10px rgba(0, 255, 255, 0.7);
+ }
+ 50% {
+ opacity: 0.8;
+ box-shadow: -2px -2px 5px #00ffff, 0 0 5px rgba(0, 255, 255, 0.5);
+ }
}
.card-title {
- color: #fff;
+ color: #00ffff;
font-size: 16px;
text-align: center;
margin-bottom: 10px;
+ text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
+ font-weight: 500;
}
.chart-content {
height: 280px;
width: 100%;
-}
-
-.stock-total {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 280px;
-}
-
-.total-number {
- font-size: 64px;
- font-weight: bold;
- color: #67caca;
- font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
-}
-
-.total-label {
- font-size: 18px;
- color: #fcf0d8;
- margin-top: 10px;
}
/* 鍏ㄥ鍥捐〃 */
@@ -409,4 +370,20 @@
.full-width .chart-content {
height: 350px;
}
-</style>
+
+/* 娣诲姞缃戞牸绾挎晥鏋� */
+.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