From 51922d7093b9c8f52417bfdd0fe9aa087d1fb5be Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期五, 01 五月 2026 18:31:01 +0800
Subject: [PATCH] feat: 优化仓库仪表盘界面并添加电池和空托盘统计功能
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs | 49 ---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs | 2
Code/WMS/WIDESEA_WMSClient/src/views/Home.vue | 721 +++++++++++++++++++++++------------------------
Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotTask.vue | 3
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/TaskInfo/Dt_RobotTask.cs | 14
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json | 2
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs | 83 +++++
Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue | 5
8 files changed, 457 insertions(+), 422 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotTask.vue b/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotTask.vue
index 8b6fec7..ca13d9c 100644
--- a/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotTask.vue
+++ b/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotTask.vue
@@ -42,6 +42,9 @@
robotSourceAddressPalletCode: "",
robotTargetAddressPalletCode: "",
robotGrade: 2,
+ robotExceptionMessage: "",
+ robotDispatchertime: "",
+ robotRemark: "",
});
// 缂栬緫琛ㄥ崟閰嶇疆
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/TaskInfo/Dt_RobotTask.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/TaskInfo/Dt_RobotTask.cs
index c5155db..7fcc68b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/TaskInfo/Dt_RobotTask.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/TaskInfo/Dt_RobotTask.cs
@@ -66,31 +66,31 @@
/// <summary>
/// 鏈哄櫒浜烘潵婧愬湴鍧�杈撻�佺嚎缂栧彿
/// </summary>
- [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜烘潵婧愬湴鍧�杈撻�佺嚎缂栧彿")]
+ [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜烘潵婧愬湴鍧�杈撻�佺嚎缂栧彿", IsNullable = true)]
public string RobotSourceAddressLineCode { get; set; }
/// <summary>
/// 鏈哄櫒浜虹洰鏍囧湴鍧�杈撻�佺嚎缂栧彿
/// </summary>
- [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜虹洰鏍囧湴鍧�杈撻�佺嚎缂栧彿")]
+ [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜虹洰鏍囧湴鍧�杈撻�佺嚎缂栧彿", IsNullable = true)]
public string RobotTargetAddressLineCode { get; set; }
/// <summary>
/// 鏈哄櫒浜烘潵婧愬湴鍧�杈撻�佺嚎鎵樼洏鍙�
/// </summary>
- [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜烘潵婧愬湴鍧�杈撻�佺嚎鎵樼洏鍙�")]
+ [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜烘潵婧愬湴鍧�杈撻�佺嚎鎵樼洏鍙�", IsNullable = true)]
public string RobotSourceAddressPalletCode { get; set; }
/// <summary>
/// 鏈哄櫒浜虹洰鏍囧湴鍧�绾挎墭鐩樺彿
/// </summary>
- [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜虹洰鏍囧湴鍧�绾挎墭鐩樺彿")]
+ [SugarColumn(Length = 20, ColumnDescription = "鏈哄櫒浜虹洰鏍囧湴鍧�绾挎墭鐩樺彿", IsNullable = true)]
public string RobotTargetAddressPalletCode { get; set; }
/// <summary>
/// 鏈哄櫒浜哄紓甯镐俊鎭�
/// </summary>
- [SugarColumn(ColumnDescription = "鏈哄櫒浜哄紓甯镐俊鎭�")]
+ [SugarColumn(ColumnDescription = "鏈哄櫒浜哄紓甯镐俊鎭�", IsNullable = true)]
public string RobotExceptionMessage { get; set; }
/// <summary>
@@ -102,13 +102,13 @@
/// <summary>
/// 鏈哄櫒浜鸿皟搴︽椂闂�
/// </summary>
- [SugarColumn(ColumnDescription = "鏈哄櫒浜鸿皟搴︽椂闂�")]
+ [SugarColumn(ColumnDescription = "鏈哄櫒浜鸿皟搴︽椂闂�", IsNullable = true)]
public DateTime? RobotDispatchertime { get; set; }
/// <summary>
/// 鏈哄櫒浜哄娉�
/// </summary>
- [SugarColumn(Length = 50, ColumnDescription = "鏈哄櫒浜哄娉�")]
+ [SugarColumn(Length = 50, ColumnDescription = "鏈哄櫒浜哄娉�", IsNullable = true)]
public string RobotRemark { get; set; }
}
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
index 7332c59..93fc738 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -714,56 +714,7 @@
.ToList()
};
}
- /// <summary>
- /// 鏋勫缓搴撳瓨鍥炰紶 DTO
- /// </summary>
- /// <remarks>
- /// 鐢ㄤ簬鎷嗙洏鍜岀粍鐩樻搷浣滄椂锛屽悜 WMS 鍥炰紶搴撳瓨淇℃伅銆�
- /// DTO 鍖呭惈婧愯揣浣嶃�佺洰鏍囪揣浣嶃�佹墭鐩樼爜浠ュ強姣忎釜浣嶇疆鐨勭數姹犳潯鐮併��
- /// </remarks>
- /// <param name="state">鏈哄櫒浜哄綋鍓嶇姸鎬�</param>
- /// <param name="positions">鐢垫睜浣嶇疆鏁扮粍</param>
- /// <returns>鏋勫缓濂界殑搴撳瓨 DTO</returns>
- public static StockDTO BuildStockDTO1(RobotSocketState state, int[] positions)
- {
- return new StockDTO
- {
- // 婧愯緭閫佺嚎缂栧彿
- SourceLineNo = state.CurrentTask.RobotSourceAddressLineCode,
- // 婧愭墭鐩樺彿
- SourcePalletNo = state.CurrentTask.RobotSourceAddressPalletCode,
-
- // 鐩爣鎵樼洏鍙�
- TargetPalletNo = state.CurrentTask.RobotTargetAddressPalletCode,
-
- // 鐩爣杈撻�佺嚎缂栧彿
- TargetLineNo = state.CurrentTask.RobotTargetAddressLineCode,
-
- // 宸烽亾缂栧彿(鏈哄櫒浜哄悕绉�)
- Roadway = state.CurrentTask.RobotRoadway,
-
- // 鐢垫睜浣嶇疆璇︽儏鍒楄〃
- // 杩囨护鎺変綅缃负 0 鎴栬礋鏁扮殑鏃犳晥鏁版嵁
- // 鎸変綅缃紪鍙锋帓搴�
- // 涓烘瘡涓綅缃敓鎴愬搴旂殑搴撳瓨璇︽儏
- Details = positions
- .Where(x => x > 0) // 杩囨护鏃犳晥浣嶇疆
- .OrderBy(x => x) // 鎸変綅缃帓搴�
- .Select((x, idx) => new StockDetailDTO
- {
- // 鏁伴噺锛氬鏋滃凡鏈変换鍔℃�绘暟锛屼娇鐢ㄤ换鍔℃�绘暟+褰撳墠浣嶇疆鏁帮紱鍚﹀垯鍙娇鐢ㄥ綋鍓嶄綅缃暟
- Quantity = 1,
-
- // 閫氶亾/浣嶇疆缂栧彿
- Channel = x,
-
- // 鐢垫睜鏉$爜锛氬彇褰撳墠鎵规鏉$爜鍒楄〃鐨勬渶鍚� N 涓紙N = 鏈夋晥浣嶇疆鏁帮級
- CellBarcode = !state.CurrentBatchBarcodes.IsNullOrEmpty() ? state.CurrentBatchBarcodes[^(positions.Count(p => p > 0) - idx)].ToString() ?? string.Empty : string.Empty
- })
- .ToList()
- };
- }
/// <summary>
/// 璋冪敤鎷嗙洏 API
/// </summary>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
index d057a4d..503b5ec 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
@@ -326,7 +326,7 @@
else
{
// 缁勭洏浠诲姟锛氬師鏈夐�昏緫
- var stockDTO = RobotTaskProcessor.BuildStockDTO1(state, positions);
+ var stockDTO = RobotTaskProcessor.BuildStockDTO(state, positions);
var result = _taskProcessor.PostGroupPalletAsync(nameof(ConfigKey.GroupPalletAsync), stockDTO);
putSuccess = result.Data.Status && result.IsSuccess;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
index 32359d5..96461c7 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
@@ -1,91 +1,78 @@
<template>
<div class="dashboard-container">
- <!-- 椤堕儴KPI鍗$墖锛氭樉绀轰粨搴撴�绘暟鍜屾�诲簱瀛橀噺 -->
+ <!-- 椤堕儴KPI鍗$墖锛氭樉绀烘�昏揣浣嶅強鍚勪粨搴撹揣浣� -->
<div class="kpi-cards">
<div class="kpi-card">
<div class="kpi-icon">馃彋锔�</div>
<div class="kpi-info">
- <div class="kpi-label">浠撳簱鎬绘暟</div>
- <div class="kpi-value">{{ totalWarehouses }}</div>
+ <div class="kpi-label">鎬昏揣浣�</div>
+ <div class="kpi-value">{{ totalLocation }}</div>
</div>
</div>
<div class="kpi-card">
- <div class="kpi-icon">馃摝</div>
+ <div class="kpi-icon">馃敟</div>
<div class="kpi-info">
- <div class="kpi-label">鎬诲簱瀛橀噺</div>
- <div class="kpi-value">{{ totalStock.toLocaleString() }}</div>
+ <div class="kpi-label">鍖栨垚搴�</div>
+ <div class="kpi-value">{{ warehouseLocations.hc }}</div>
</div>
</div>
<div class="kpi-card">
- <div class="kpi-icon">馃搳</div>
+ <div class="kpi-icon">馃尅锔�</div>
<div class="kpi-info">
- <div class="kpi-label">鏈湀鎬诲叆搴�</div>
- <div class="kpi-value">{{ monthlyInboundTotal.toLocaleString() }}</div>
+ <div class="kpi-label">楂樻俯搴�</div>
+ <div class="kpi-value">{{ warehouseLocations.gw }}</div>
</div>
</div>
<div class="kpi-card">
- <div class="kpi-icon">馃摛</div>
+ <div class="kpi-icon">鉂勶笍</div>
<div class="kpi-info">
- <div class="kpi-label">鏈湀鎬诲嚭搴�</div>
- <div class="kpi-value">{{ monthlyOutboundTotal.toLocaleString() }}</div>
+ <div class="kpi-label">甯告俯搴�</div>
+ <div class="kpi-value">{{ warehouseLocations.cw }}</div>
+ </div>
+ </div>
+ <div class="kpi-card">
+ <div class="kpi-icon">馃摐</div>
+ <div class="kpi-info">
+ <div class="kpi-label">鏋佸嵎搴�</div>
+ <div class="kpi-value">{{ warehouseLocations.jj }}</div>
</div>
</div>
</div>
- <!-- 椤堕儴锛氭湰鏈堝嚭鍏ュ簱瓒嬪娍 - 涓�3涓�2甯冨眬锛屾瘡涓崱鐗囩洿鎺ユ樉绀轰粨搴撴暟瀛� -->
- <div class="chart-row top-three">
- <div v-for="warehouse in topWarehouses" :key="warehouse.code" class="chart-card">
- <div class="card-title">{{ warehouse.name }}</div>
- <!-- 浠撳簱鏁板瓧鏄剧ず鍖哄煙 -->
+ <!-- 绗竴琛岋細4涓瘡鏃ュ嚭鍏ュ簱瓒嬪娍鍥撅紙姣忚2涓級 -->
+ <div class="chart-row daily-grid">
+ <div class="chart-card" v-for="warehouse in dailyWarehouses" :key="warehouse.code">
+ <div class="card-title">{{ warehouse.name }} - 姣忔棩瓒嬪娍</div>
+ <!-- 浠撳簱鏁板瓧鏄剧ず鍖哄煙锛氭樉绀烘瘡鏃ユ�婚噺鍜岀┖鎵樼洏鏁伴噺 -->
<div class="warehouse-numbers">
- <div class="number-item inbound">
- <span class="number-label">鍏ュ簱</span>
- <span class="number-value">{{ getMonthlyInbound(warehouse.code) }}</span>
- </div>
- <div class="number-item outbound">
- <span class="number-label">鍑哄簱</span>
- <span class="number-value">{{ getMonthlyOutbound(warehouse.code) }}</span>
- </div>
- <div class="number-item stock">
- <span class="number-label">搴撳瓨</span>
- <span class="number-value">{{ getWarehouseStock(warehouse.code) }}</span>
- </div>
+ <!-- 鏋佸嵎搴撴樉绀烘湁璐ф墭鐩橈紙鐢垫睜鏁伴噺锛夊拰绌烘墭鐩� -->
+ <template v-if="warehouse.code === 'ROLL'">
+ <div class="number-item battery">
+ <span class="number-label">鐢垫睜鏁伴噺</span>
+ <span class="number-value">{{ getBatteryCount(warehouse.code) }}</span>
+ </div>
+ <div class="number-item empty-tray">
+ <span class="number-label">绌烘墭鐩樻暟閲�</span>
+ <span class="number-value">{{ getEmptyTrayCount(warehouse.code) }}</span>
+ </div>
+ </template>
+ <!-- 鍏朵粬浠撳簱鏄剧ず鐢垫睜鏁伴噺鍜岀┖鎵樼洏鏁伴噺 -->
+ <template v-else>
+ <div class="number-item inbound">
+ <span class="number-label">鐢垫睜鏁伴噺</span>
+ <span class="number-value">{{ getBatteryCount(warehouse.code) }}</span>
+ </div>
+ <div class="number-item empty-tray">
+ <span class="number-label">绌烘墭鐩樻暟閲�</span>
+ <span class="number-value">{{ getEmptyTrayCount(warehouse.code) }}</span>
+ </div>
+ </template>
</div>
- <div :id="`chart-${warehouse.code}`" class="chart-content"></div>
+ <div :id="`daily-chart-${warehouse.code}`" class="chart-content"></div>
</div>
</div>
- <div class="chart-row bottom-two">
- <div v-for="warehouse in bottomWarehouses" :key="warehouse.code" class="chart-card">
- <div class="card-title">{{ warehouse.name }}</div>
- <!-- 浠撳簱鏁板瓧鏄剧ず鍖哄煙 -->
- <div class="warehouse-numbers">
- <div class="number-item inbound">
- <span class="number-label">鍏ュ簱</span>
- <span class="number-value">{{ getMonthlyInbound(warehouse.code) }}</span>
- </div>
- <div class="number-item outbound">
- <span class="number-label">鍑哄簱</span>
- <span class="number-value">{{ getMonthlyOutbound(warehouse.code) }}</span>
- </div>
- <div class="number-item stock">
- <span class="number-label">搴撳瓨</span>
- <span class="number-value">{{ getWarehouseStock(warehouse.code) }}</span>
- </div>
- </div>
- <div :id="`chart-${warehouse.code}`" class="chart-content"></div>
- </div>
- </div>
-
- <!-- 姣忔棩鍑哄叆搴撹秼鍔� (鍏ㄥ) -->
- <div class="chart-row full-width">
- <div class="chart-card">
- <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>
@@ -103,41 +90,54 @@
data() {
return {
charts: {},
- // 浜斾釜浠撳簱瀹氫箟 - 涓�3涓�
- topWarehouses: [
- { code: "GWSC1", name: "楂樻俯1鍙蜂粨搴�" },
- { code: "CWSC1", name: "甯告俯1鍙蜂粨搴�" },
- { code: "HCSC1", name: "鍒嗗1鍙蜂粨搴�" }
+ // 鍥涗釜鏍稿績浠撳簱锛堝悎骞朵簡姝h礋鏋佸嵎搴撲负鏋佸嵎搴擄級
+ dailyWarehouses: [
+ { code: "HCSC1", name: "鍖栨垚搴�", type: "hc" },
+ { code: "GWSC1", name: "楂樻俯搴�", type: "gw" },
+ { code: "CWSC1", name: "甯告俯搴�", type: "cw" },
+ { code: "ROLL", name: "鏋佸嵎搴�", type: "jj" }
],
- // 涓�2涓�
- bottomWarehouses: [
- { code: "FJSC1", name: "璐熸瀬鍗�1鍙蜂粨搴�" },
- { code: "ZJSC1", name: "姝f瀬鍗�1鍙蜂粨搴�" }
- ],
- dailyData: [],
- // 瀛樺偍姣忎釜浠撳簱鐨勬湀搴︽暟鎹�
- monthlyData: {
+ // 鍘熷姣忔棩鏁版嵁瀛樺偍 (鍏朵腑ROLL涓哄悎骞跺悗鐨勬瀬鍗峰簱鏁版嵁)
+ dailyDataMap: {
GWSC1: [],
CWSC1: [],
HCSC1: [],
- FJSC1: [],
- ZJSC1: []
+ ROLL: []
},
- // 瀛樺偍姣忎釜浠撳簱鐨勫綋鍓嶅簱瀛�
+ // 瀛樺偍姣忎釜浠撳簱鐨勭數姹犳暟閲�
warehouseStocks: {
GWSC1: 0,
CWSC1: 0,
HCSC1: 0,
- FJSC1: 0,
- ZJSC1: 0
+ ROLL: 0
},
- warehouseData: [],
- // KPI 姹囨�绘暟鎹�
- totalWarehouses: 5,
- totalStock: 0,
- monthlyInboundTotal: 0,
- monthlyOutboundTotal: 0
+ // 鏋佸嵎搴撶壒娈婃暟鎹�
+ rollData: {
+ batteryCount: 0, // 鐢垫睜鏁伴噺
+ emptyTrayCount: 0 // 绌烘墭鐩樻暟閲�
+ },
+ // 鍏朵粬浠撳簱鐨勭┖鎵樼洏鏁伴噺
+ emptyTrayCounts: {
+ GWSC1: 0,
+ CWSC1: 0,
+ HCSC1: 0
+ },
+ warehouseData: [], // 浠撳簱鍒嗗竷鍥炬暟鎹�
+ // 浠撳簱璐т綅鏁版嵁锛堝浐瀹氶厤缃級
+ warehouseLocations: {
+ hc: 35, // 鍖栨垚搴�
+ gw: 324, // 楂樻俯搴�
+ cw: 140, // 甯告俯搴�
+ jj: 104 // 鏋佸嵎搴�
+ }
};
+ },
+ computed: {
+ // 鎬昏揣浣嶈绠�
+ totalLocation() {
+ return this.warehouseLocations.hc + this.warehouseLocations.gw +
+ this.warehouseLocations.cw + this.warehouseLocations.jj;
+ }
},
mounted() {
this.initCharts();
@@ -154,181 +154,265 @@
},
initCharts() {
- // 鍒濆鍖栨墍鏈変粨搴撳浘琛�
- const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
- allWarehouses.forEach(warehouse => {
- const chartId = `chart-${warehouse.code}`;
+ // 鍒濆鍖栨瘡鏃ュ浘琛�
+ this.dailyWarehouses.forEach(warehouse => {
+ const chartId = `daily-chart-${warehouse.code}`;
const el = document.getElementById(chartId);
if (el) {
- this.charts[warehouse.code] = echarts.init(el);
+ this.charts[`daily-${warehouse.code}`] = echarts.init(el);
}
});
- // 鍒濆鍖栨瘡鏃ュ浘琛ㄥ拰浠撳簱鍒嗗竷鍥捐〃
- this.charts.daily = echarts.init(document.getElementById("chart-daily"));
+ // 鍒濆鍖栦粨搴撳垎甯冨浘琛�
this.charts.warehouse = echarts.init(document.getElementById("chart-warehouse"));
},
async loadData() {
- // 骞惰鍔犺浇鎵�鏈変粨搴撶殑鏈堝害鏁版嵁锛堝垎鍒紶鍏ヤ笉鍚岀殑Roadway鍙傛暟锛�
- const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
- const monthlyPromises = allWarehouses.map(warehouse =>
- this.loadMonthlyStatsForWarehouse(warehouse.code)
- );
- await Promise.all(monthlyPromises);
- // 鏇存柊鎵�鏈変粨搴撶殑鏈堝害鍥捐〃
- this.updateAllMonthlyTrendCharts();
-
- await this.loadDailyStats();
- await this.loadStockByWarehouse();
- await this.loadWarehouseStocks();
- this.calculateKPIs();
- },
-
- async loadMonthlyStatsForWarehouse(roadway) {
- console.log(`姝e湪鍔犺浇${roadway}鐨勬瘡鏈堢粺璁℃暟鎹�...`);
try {
- // 鍏抽敭淇锛氬垎鍒紶鍏ヤ笉鍚岀殑Roadway鍙傛暟
- const res = await this.http.get("/api/Dashboard/MonthlyStats?monthly=12&roadway=" + roadway);
- if (res.status && res.data) {
- console.log(`${roadway} 姣忔湀缁熻鏁版嵁:`, res.data);
- this.monthlyData[roadway] = res.data;
- } else {
- this.monthlyData[roadway] = [];
- }
- } catch (e) {
- console.error(`鍔犺浇${roadway}姣忔湀缁熻澶辫触`, e);
- this.monthlyData[roadway] = [];
+ // 骞惰鍔犺浇鎵�鏈夋暟鎹�
+ await Promise.all([
+ this.loadAllDailyStats(),
+ this.loadStockAndTrayCount(),
+ this.loadStockByWarehouse()
+ ]);
+
+ // 鏇存柊鎵�鏈夊浘琛�
+ this.updateAllDailyCharts();
+ } catch (error) {
+ console.error("鍔犺浇鏁版嵁澶辫触:", error);
+ this.$message?.error("鏁版嵁鍔犺浇澶辫触锛岃绋嶅悗閲嶈瘯");
}
},
- async loadDailyStats() {
- try {
- 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);
+ async loadAllDailyStats() {
+ console.log("姝e湪鍔犺浇鎵�鏈変粨搴撶殑姣忔棩缁熻鏁版嵁...");
+ const res = await this.http.get("/api/Dashboard/DailyStats?days=10");
+ if (res.status && res.data) {
+ console.log("鎵�鏈変粨搴撴瘡鏃ョ粺璁℃暟鎹�:", res.data);
+
+ const dataArray = res.data;
+
+ // 鎸変粨搴撳垎绫绘暟鎹�
+ dataArray.forEach(item => {
+ const roadway = item.roadway;
+ const dailyStats = item.dailyStats || [];
+
+ switch(roadway) {
+ case "GWSC1":
+ this.dailyDataMap.GWSC1 = dailyStats;
+ break;
+ case "CWSC1":
+ this.dailyDataMap.CWSC1 = dailyStats;
+ break;
+ case "HCSC1":
+ this.dailyDataMap.HCSC1 = dailyStats;
+ break;
+ case "ZJSC1":
+ case "FJSC1":
+ // 鏋佸嵎搴撴暟鎹悎骞跺鐞�
+ this.mergeRollDailyStats(dailyStats);
+ break;
+ }
+ });
+
+ console.log("GWSC1鏁版嵁:", this.dailyDataMap.GWSC1);
+ console.log("CWSC1鏁版嵁:", this.dailyDataMap.CWSC1);
+ console.log("HCSC1鏁版嵁:", this.dailyDataMap.HCSC1);
+ console.log("鏋佸嵎搴撳悎骞舵暟鎹�:", this.dailyDataMap.ROLL);
+ } else {
+ console.error("鑾峰彇姣忔棩鏁版嵁澶辫触");
+ }
+ },
+
+ mergeRollDailyStats(newData) {
+ // 鍚堝苟姝f瀬鍗峰簱鍜岃礋鏋佸嵎搴撶殑姣忔棩鏁版嵁
+ if (!this.dailyDataMap.ROLL.length) {
+ this.dailyDataMap.ROLL = [...newData];
+ } else {
+ const dateMap = new Map();
+ [...this.dailyDataMap.ROLL, ...newData].forEach(item => {
+ const date = item.date;
+ if (date) {
+ if (!dateMap.has(date)) {
+ dateMap.set(date, { date, inbound: 0, outbound: 0 });
+ }
+ const existing = dateMap.get(date);
+ existing.inbound += item.inbound || 0;
+ existing.outbound += item.outbound || 0;
+ }
+ });
+
+ const sortedDates = Array.from(dateMap.keys()).sort();
+ const mergedData = sortedDates.map(date => dateMap.get(date));
+ this.dailyDataMap["ROLL"] = mergedData;
+ }
+ },
+
+ async loadStockAndTrayCount() {
+ // 鍔犺浇鐢垫睜鏁伴噺鍜岀┖鎵樼洏鏁伴噺
+ console.log("姝e湪鍔犺浇鐢垫睜鏁伴噺鍜岀┖鎵樼洏鏁版嵁...");
+ const res = await this.http.get("/api/Dashboard/StockAndTrayCount");
+
+ if (res.status && res.data) {
+ console.log("鐢垫睜鍜岀┖鎵樼洏鏁版嵁:", res.data);
+
+ // 閲嶇疆鏁版嵁
+ this.rollData.batteryCount = 0;
+ this.rollData.emptyTrayCount = 0;
+
+ // 鏍规嵁杩斿洖鐨勬暟鎹粨鏋勮В鏋�
+ res.data.forEach(item => {
+ const warehouseName = item.warehouseName;
+ const batteryCount = item.batteryCount || 0;
+ const emptyTrayCount = item.emptyTrayCount || 0;
+
+ // 鏍规嵁浠撳簱鍚嶇О鏄犲皠鍒板搴旂殑浠g爜
+ if (warehouseName === "楂樻俯搴�") {
+ this.emptyTrayCounts.GWSC1 = emptyTrayCount;
+ this.warehouseStocks.GWSC1 = batteryCount;
+ } else if (warehouseName === "甯告俯搴�") {
+ this.emptyTrayCounts.CWSC1 = emptyTrayCount;
+ this.warehouseStocks.CWSC1 = batteryCount;
+ } else if (warehouseName === "鍖栨垚搴�") {
+ this.emptyTrayCounts.HCSC1 = emptyTrayCount;
+ this.warehouseStocks.HCSC1 = batteryCount;
+ } else if (warehouseName === "鏋佸嵎搴�") {
+ // 鏋佸嵎搴撻渶瑕佸悎骞朵袱涓瀬鍗峰簱鐨勬暟鎹�
+ this.rollData.batteryCount += batteryCount;
+ this.rollData.emptyTrayCount += emptyTrayCount;
+ }
+ });
+
+ // 璁剧疆鏋佸嵎搴撴�荤數姹犳暟閲�
+ this.warehouseStocks.ROLL = this.rollData.batteryCount;
+
+ console.log("鐗规畩鏁版嵁鍔犺浇瀹屾垚:", {
+ rollData: this.rollData,
+ emptyTrayCounts: this.emptyTrayCounts,
+ warehouseStocks: this.warehouseStocks
+ });
+ } else {
+ console.error("鑾峰彇鐢垫睜鍜岀┖鎵樼洏鏁版嵁澶辫触");
+ throw new Error("鑾峰彇鐢垫睜鍜岀┖鎵樼洏鏁版嵁澶辫触");
}
},
async loadStockByWarehouse() {
- try {
- const res = await this.http.get("/api/Dashboard/StockByWarehouse");
- if (res.status && res.data) {
- console.log("浠撳簱鍒嗗竷鏁版嵁:", res.data);
- this.warehouseData = res.data.data || res.data;
- this.updateWarehouseChart();
- }
- } catch (e) {
- console.error("鍔犺浇浠撳簱鍒嗗竷澶辫触", e);
- }
- },
-
- async loadWarehouseStocks() {
- // 妯℃嫙鍔犺浇姣忎釜浠撳簱鐨勫綋鍓嶅簱瀛橀噺
- // 濡傛灉鍚庣鏈夋帴鍙o紝鍙互鏇挎崲涓虹湡瀹濧PI璋冪敤
- try {
- // 灏濊瘯鍔犺浇搴撳瓨鏁版嵁锛屽鏋滄帴鍙d笉瀛樺湪鍒欎娇鐢ㄦā鎷熸暟鎹�
- const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
- for (const warehouse of allWarehouses) {
- try {
- const res = await this.http.get(`/api/Dashboard/WarehouseStock?warehouse=${warehouse.code}`);
- if (res.status && res.data) {
- this.warehouseStocks[warehouse.code] = res.data.stock || 0;
- } else {
- // 浠庢湀搴︽暟鎹腑璁$畻妯℃嫙搴撳瓨锛堟渶杩戞湀浠界疮璁″叆搴�-鍑哄簱锛�
- const monthlyData = this.monthlyData[warehouse.code] || [];
- let totalInbound = 0;
- let totalOutbound = 0;
- monthlyData.forEach(m => {
- totalInbound += (m.inbound ?? m.Inbound) || 0;
- totalOutbound += (m.outbound ?? m.Outbound) || 0;
- });
- this.warehouseStocks[warehouse.code] = Math.max(0, totalInbound - totalOutbound);
- }
- } catch (e) {
- // 浣跨敤妯℃嫙鏁版嵁
- const mockStocks = {
- GWSC1: 12580,
- CWSC1: 8920,
- HCSC1: 15600,
- FJSC1: 4300,
- ZJSC1: 7200
- };
- this.warehouseStocks[warehouse.code] = mockStocks[warehouse.code] || 0;
+ console.log("姝e湪鍔犺浇浠撳簱鍒嗗竷鏁版嵁...");
+ const res = await this.http.get("/api/Dashboard/StockByWarehouse");
+
+ if (res.status && res.data) {
+ console.log("浠撳簱鍒嗗竷鏁版嵁:", res.data);
+ const rawData = res.data.data || res.data;
+
+ // 澶勭悊鏋佸嵎搴撳悎骞�
+ let rollHasStock = 0;
+ let rollNoStock = 0;
+ let rollTotal = 0;
+ const otherWarehouses = [];
+
+ rawData.forEach(item => {
+ if (item.warehouse === "鏋佸嵎搴�" || item.warehouse.includes("鏋佸嵎搴�")) {
+ // 鍚堝苟鏋佸嵎搴撴暟鎹�
+ rollHasStock += item.hasStock || 0;
+ rollNoStock += item.noStock || 0;
+ rollTotal += item.total || 0;
+ } else {
+ otherWarehouses.push(item);
}
+ });
+
+ // 娣诲姞鍚堝苟鍚庣殑鏋佸嵎搴�
+ if (rollTotal > 0) {
+ const hasStockPercentage = ((rollHasStock / rollTotal) * 100).toFixed(1) + "%";
+ const noStockPercentage = ((rollNoStock / rollTotal) * 100).toFixed(1) + "%";
+
+ otherWarehouses.push({
+ warehouse: "鏋佸嵎搴�",
+ hasStock: rollHasStock,
+ noStock: rollNoStock,
+ total: rollTotal,
+ hasStockPercentage: hasStockPercentage,
+ noStockPercentage: noStockPercentage
+ });
}
- } catch (e) {
- console.error("鍔犺浇浠撳簱搴撳瓨澶辫触", e);
+
+ this.warehouseData = otherWarehouses;
+ this.updateWarehouseChart();
+ } else {
+ console.error("鑾峰彇浠撳簱鍒嗗竷鏁版嵁澶辫触");
+ throw new Error("鑾峰彇浠撳簱鍒嗗竷鏁版嵁澶辫触");
}
},
- getMonthlyInbound(warehouseCode) {
- const data = this.monthlyData[warehouseCode] || [];
- if (data.length === 0) return 0;
- // 鑾峰彇鏈�杩戜竴涓湀锛堟渶鍚庝竴鏉★級鐨勫叆搴撴暟
- const latest = data[data.length - 1];
- return (latest.inbound ?? latest.Inbound) || 0;
+ getDailyTotalInbound(warehouseCode) {
+ const data = this.dailyDataMap[warehouseCode] || [];
+ return data.reduce((sum, item) => sum + (item.inbound || 0), 0);
},
- getMonthlyOutbound(warehouseCode) {
- const data = this.monthlyData[warehouseCode] || [];
- if (data.length === 0) return 0;
- // 鑾峰彇鏈�杩戜竴涓湀锛堟渶鍚庝竴鏉★級鐨勫嚭搴撴暟
- const latest = data[data.length - 1];
- return (latest.outbound ?? latest.Outbound) || 0;
+ getDailyTotalOutbound(warehouseCode) {
+ const data = this.dailyDataMap[warehouseCode] || [];
+ return data.reduce((sum, item) => sum + (item.outbound || 0), 0);
},
getWarehouseStock(warehouseCode) {
return this.warehouseStocks[warehouseCode] || 0;
},
- calculateKPIs() {
- // 璁$畻鎬诲簱瀛�
- let totalStock = 0;
- for (const code in this.warehouseStocks) {
- totalStock += this.warehouseStocks[code];
+ getBatteryCount(warehouseCode) {
+ if (warehouseCode === 'ROLL') {
+ return this.rollData.batteryCount;
+ } else if (warehouseCode === 'GWSC1') {
+ return this.warehouseStocks.GWSC1;
+ } else if (warehouseCode === 'CWSC1') {
+ return this.warehouseStocks.CWSC1;
+ } else if (warehouseCode === 'HCSC1') {
+ return this.warehouseStocks.HCSC1;
}
- this.totalStock = totalStock;
-
- // 璁$畻鏈湀鎬诲叆搴撳拰鎬诲嚭搴擄紙鎵�鏈変粨搴撴渶杩戜竴涓湀鐨勫悎璁★級
- let totalInbound = 0;
- let totalOutbound = 0;
- const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
- allWarehouses.forEach(warehouse => {
- totalInbound += this.getMonthlyInbound(warehouse.code);
- totalOutbound += this.getMonthlyOutbound(warehouse.code);
- });
- this.monthlyInboundTotal = totalInbound;
- this.monthlyOutboundTotal = totalOutbound;
+ return 0;
},
- // 鏇存柊鎵�鏈変粨搴撶殑鏈堝害瓒嬪娍鍥捐〃
- updateAllMonthlyTrendCharts() {
- const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
- allWarehouses.forEach(warehouse => {
- this.updateMonthlyTrendChartForWarehouse(warehouse.code);
+ getEmptyTrayCount(warehouseCode) {
+ if (warehouseCode === 'ROLL') {
+ return this.rollData.emptyTrayCount;
+ } else if (warehouseCode === 'GWSC1') {
+ return this.emptyTrayCounts.GWSC1;
+ } else if (warehouseCode === 'CWSC1') {
+ return this.emptyTrayCounts.CWSC1;
+ } else if (warehouseCode === 'HCSC1') {
+ return this.emptyTrayCounts.HCSC1;
+ }
+ return 0;
+ },
+
+ updateAllDailyCharts() {
+ this.dailyWarehouses.forEach(warehouse => {
+ this.updateDailyChartForWarehouse(warehouse.code);
});
},
- updateMonthlyTrendChartForWarehouse(roadway) {
- const chart = this.charts[roadway];
+ updateDailyChartForWarehouse(roadway) {
+ const chart = this.charts[`daily-${roadway}`];
if (!chart) return;
- const data = this.monthlyData[roadway] || [];
- // 鍏煎澶у皬鍐欏瓧娈靛悕
- const monthLabels = data.map(m => m.month || m.Month || "");
- const inboundData = data.map(m => {
- const val = m.inbound ?? m.Inbound;
- return val !== undefined && val !== null ? Number(val) : 0;
- });
- const outboundData = data.map(m => {
- const val = m.outbound ?? m.Outbound;
- return val !== undefined && val !== null ? Number(val) : 0;
- });
+ const data = this.dailyDataMap[roadway] || [];
+
+ // 濡傛灉娌℃湁鏁版嵁锛屾樉绀虹┖鍥捐〃鎻愮ず
+ if (!data.length) {
+ chart.setOption({
+ title: {
+ show: true,
+ text: '鏆傛棤鏁版嵁',
+ left: 'center',
+ top: 'center',
+ textStyle: { color: '#ccc', fontSize: 14 }
+ }
+ }, true);
+ return;
+ }
+
+ const dates = data.map(d => d.date);
+ const inboundData = data.map(d => d.inbound || 0);
+ const outboundData = data.map(d => d.outbound || 0);
const option = {
tooltip: {
@@ -358,7 +442,7 @@
},
xAxis: {
type: "category",
- data: monthLabels,
+ data: dates,
axisLabel: {
color: "#ccc",
rotate: 45,
@@ -370,7 +454,7 @@
},
yAxis: {
type: "value",
- name: "浠诲姟鏁伴噺",
+ name: "鏁伴噺",
nameTextStyle: { color: "#ccc", fontSize: 11 },
axisLabel: { color: "#ccc" },
splitLine: { lineStyle: { color: "#2a3a4a", type: "dashed" } }
@@ -384,12 +468,13 @@
color: "#5470c6",
borderRadius: [4, 4, 0, 0]
},
- barWidth: "35%",
+ barWidth: "40%",
label: {
- show: inboundData.length <= 8,
+ show: true,
position: "top",
color: "#5470c6",
- fontSize: 10
+ fontSize: 10,
+ formatter: (params) => params.value
}
},
{
@@ -402,10 +487,11 @@
lineStyle: { width: 2, type: "solid" },
smooth: false,
label: {
- show: outboundData.length <= 8,
+ show: true,
position: "top",
color: "#91cc75",
- fontSize: 10
+ fontSize: 10,
+ formatter: (params) => params.value
}
}
]
@@ -413,56 +499,22 @@
chart.setOption(option, true);
},
- updateDailyChart() {
- if (!this.charts.daily) return;
- const option = {
- tooltip: { trigger: "axis" },
- legend: { data: ["鍏ュ簱", "鍑哄簱"], textStyle: { color: "#fff" } },
- xAxis: {
- type: "category",
- 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: [
- {
- 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.daily.setOption(option, true);
- },
-
updateWarehouseChart() {
if (!this.charts.warehouse) return;
+
+ if (!this.warehouseData.length) {
+ this.charts.warehouse.setOption({
+ title: {
+ show: true,
+ text: '鏆傛棤浠撳簱鏁版嵁',
+ left: 'center',
+ top: 'center',
+ textStyle: { color: '#ccc' }
+ }
+ });
+ return;
+ }
+
const warehouseNames = this.warehouseData.map(w => w.warehouse);
const hasStocks = this.warehouseData.map(w => w.hasStock);
const noStocks = this.warehouseData.map(w => w.noStock);
@@ -472,14 +524,12 @@
const option = {
tooltip: {
trigger: "axis",
- axisPointer: {
- type: "shadow"
- },
- formatter: function(params) {
+ axisPointer: { type: "shadow" },
+ formatter: (params) => {
let tip = params[0].name + "<br/>";
params.forEach(param => {
const dataIndex = param.dataIndex;
- const warehouse = window.homeComponent?.warehouseData[dataIndex];
+ const warehouse = this.warehouseData[dataIndex];
if (warehouse) {
if (param.seriesName === "宸茬敤瀹归噺") {
tip += `${param.marker}${param.seriesName}: ${param.value} (${warehouse.hasStockPercentage})<br/>`;
@@ -519,9 +569,9 @@
label: {
show: true,
position: "top",
- formatter: (params) => {
- const pct = hasStockPercentages[params.dataIndex];
- return `${params.value} (${pct})`;
+ formatter: () => {
+ const pct = hasStockPercentages[index];
+ return `${value} (${pct})`;
},
color: "#91cc75",
fontSize: 11
@@ -537,9 +587,9 @@
label: {
show: true,
position: "top",
- formatter: (params) => {
- const pct = noStockPercentages[params.dataIndex];
- return `${params.value} (${pct})`;
+ formatter: () => {
+ const pct = noStockPercentages[index];
+ return `${value} (${pct})`;
},
color: "#fac858",
fontSize: 11
@@ -550,7 +600,6 @@
]
};
- window.homeComponent = this;
this.charts.warehouse.setOption(option, true);
}
}
@@ -566,10 +615,10 @@
background-attachment: fixed;
}
-/* KPI 鍗$墖鏍峰紡 */
+/* KPI 鍗$墖鏍峰紡 - 5鍒楀竷灞� */
.kpi-cards {
display: grid;
- grid-template-columns: repeat(4, 1fr);
+ grid-template-columns: repeat(5, 1fr);
gap: 20px;
margin-bottom: 24px;
}
@@ -617,24 +666,11 @@
line-height: 1.2;
}
-/* 涓�3涓浘琛ㄥ竷灞� */
-.chart-row.top-three {
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- gap: 20px;
- margin-bottom: 20px;
-}
-
-/* 涓�2涓浘琛ㄥ竷灞� */
-.chart-row.bottom-two {
+/* 姣忔棩鍥捐〃甯冨眬 - 姣忚2涓� */
+.chart-row.daily-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
- margin-bottom: 20px;
-}
-
-.chart-row.full-width {
- width: 100%;
margin-bottom: 20px;
}
@@ -680,23 +716,6 @@
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: #00ffff;
font-size: 15px;
@@ -717,11 +736,13 @@
padding: 8px 0;
background: rgba(0, 0, 0, 0.3);
border-radius: 8px;
+ flex-wrap: wrap;
}
.number-item {
text-align: center;
flex: 1;
+ min-width: 80px;
}
.number-label {
@@ -733,7 +754,7 @@
.number-value {
display: block;
- font-size: 20px;
+ font-size: 18px;
font-weight: 700;
letter-spacing: 1px;
}
@@ -742,67 +763,41 @@
color: #5470c6;
}
-.number-item.outbound .number-value {
- color: #91cc75;
+.number-item.battery .number-value {
+ color: #ee6666;
}
-.number-item.stock .number-value {
- color: #fac858;
+.number-item.empty-tray .number-value {
+ color: #fc8452;
}
.chart-content {
- height: 240px;
+ height: 280px;
width: 100%;
-}
-
-/* 鍏ㄥ鍥捐〃 */
-.full-width .chart-card {
- width: 100%;
-}
-
-.full-width .chart-content {
- height: 350px;
-}
-
-/* 鍝嶅簲寮忚皟鏁� */
-@media (max-width: 1024px) {
- .kpi-cards {
- grid-template-columns: repeat(2, 1fr);
- }
- .chart-row.top-three {
- grid-template-columns: repeat(2, 1fr);
- }
- .chart-row.bottom-two {
- grid-template-columns: repeat(2, 1fr);
- }
}
@media (max-width: 768px) {
.kpi-cards {
- grid-template-columns: 1fr;
+ grid-template-columns: repeat(2, 1fr);
}
- .chart-row.top-three {
- grid-template-columns: 1fr;
- }
- .chart-row.bottom-two {
+ .chart-row.daily-grid {
grid-template-columns: 1fr;
}
.chart-content {
- height: 220px;
- }
- .full-width .chart-content {
- height: 280px;
+ height: 240px;
}
.card-title {
font-size: 13px;
white-space: normal;
}
.number-value {
- font-size: 16px;
+ font-size: 14px;
+ }
+ .number-item {
+ min-width: 60px;
}
}
-/* 娣诲姞缃戞牸绾挎晥鏋� */
.dashboard-container::before {
content: "";
position: fixed;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue b/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
index b35bd72..b4ab422 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
@@ -21,6 +21,7 @@
palletCode: "鎵樼洏缂栧彿",
stockStatus: "搴撳瓨鐘舵��",
locationCode: "璐т綅缂栧彿",
+ locationId: "璐т綅id",
outboundDate: "鍑哄簱鏃堕棿",
warehouse: "浠撳簱",
creator: "鍒涘缓浜�",
@@ -63,7 +64,8 @@
mesUploadStatus: "",
stockStatus: "",
locationCode: "",
- locationDetails: ""
+ locationDetails: "",
+ locationId: "",
});
@@ -72,6 +74,7 @@
{ field: "palletCode", title: TEXT.palletCode, type: "string" },
{ field: "stockStatus", title: TEXT.stockStatus, type: "select", dataKey: "stockStatusEmun", data: [] },
{ field: "locationCode", title: TEXT.locationCode, type: "string" },
+ { field: "locationId", title: TEXT.locationId, type: "string"},
],
]);
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
index 191dd33..cffe42d 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
@@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using WIDESEA_Common.LocationEnum;
+using WIDESEA_Common.StockEnum;
using WIDESEA_Core;
using WIDESEA_Model.Models;
@@ -415,5 +416,87 @@
return WebResponseContent.Instance.Error($"鍚勪粨搴撳簱瀛樺垎甯冭幏鍙栧け璐�: {ex.Message}");
}
}
+ /// <summary>
+ /// 鏌ヨ鍚勪粨搴撶數姹�/鏈夎揣鏁伴噺鍜岀┖鎵樼洏鏁伴噺
+ /// </summary>
+ /// <remarks>
+ /// 浠撳簱ID瑙勫垯锛�1=楂樻俯搴�, 2=甯告俯搴�, 3=鍖栨垚搴�, 6/7=鏋佸嵎搴�
+ /// <br/>
+ /// 缁熻瑙勫垯锛�
+ /// <br/>
+ /// - 楂樻俯/甯告俯/鍖栨垚搴擄細缁熻 鐢垫睜鏁伴噺(StockStatus=6) 鍜� 绌烘墭鐩樻暟閲�(StockStatus=22)
+ /// <br/>
+ /// - 鏋佸嵎搴�(6/7)锛氱粺璁� 鏈夎揣鏁伴噺(StockStatus鈮�22) 鍜� 绌烘墭鐩樻暟閲�(StockStatus=22)
+ /// <br/>
+ /// 閫氳繃杩斿洖鏁版嵁涓殑 StockStatus 鍜� Count 鍙互杩涗竴姝ユ煡璇㈡槑缁嗙數姹犮��
+ /// </remarks>
+ [HttpGet("StockAndTrayCount"), AllowAnonymous]
+ public async Task<WebResponseContent> StockAndTrayCount()
+ {
+ try
+ {
+ var warehouseIds = new[] { 1, 2, 3, 6, 7 };
+
+ var warehouseNames = new Dictionary<int, string>
+ {
+ { 1, "楂樻俯搴�" },
+ { 2, "甯告俯搴�" },
+ { 3, "鍖栨垚搴�" },
+ { 6, "鏋佸嵎搴�" },
+ { 7, "鏋佸嵎搴�" }
+ };
+
+ var result = new List<object>();
+
+ foreach (var warehouseId in warehouseIds)
+ {
+ var warehouseName = warehouseNames.GetValueOrDefault(warehouseId, $"浠撳簱{warehouseId}");
+
+ if (warehouseId == 6 || warehouseId == 7)
+ {
+ var totalCount = await _db.Queryable<Dt_StockInfo>()
+ .Where(s => s.WarehouseId == warehouseId)
+ .CountAsync();
+
+ var emptyTrayCount = await _db.Queryable<Dt_StockInfo>()
+ .Where(s => s.WarehouseId == warehouseId && s.StockStatus == (int)StockStatusEmun.绌烘墭鐩樺簱瀛�)
+ .CountAsync();
+
+ result.Add(new
+ {
+ WarehouseId = warehouseId,
+ WarehouseName = warehouseName,
+ HasGoodsCount = totalCount - emptyTrayCount,
+ EmptyTrayCount = emptyTrayCount,
+ });
+ }
+ else
+ {
+ var batteryCount = await _db.Queryable<Dt_StockInfo>()
+ .Where(s => s.WarehouseId == warehouseId && s.StockStatus == (int)StockStatusEmun.鍏ュ簱瀹屾垚)
+ .LeftJoin<Dt_StockInfoDetail>((s, d) => s.Id == d.StockId)
+ .CountAsync();
+
+ var emptyTrayCount = await _db.Queryable<Dt_StockInfo>()
+ .Where(s => s.WarehouseId == warehouseId && s.StockStatus == (int)StockStatusEmun.绌烘墭鐩樺簱瀛�)
+ .CountAsync();
+
+ result.Add(new
+ {
+ WarehouseId = warehouseId,
+ WarehouseName = warehouseName,
+ BatteryCount = batteryCount,
+ EmptyTrayCount = emptyTrayCount,
+ });
+ }
+ }
+
+ return WebResponseContent.Instance.OK(null, result);
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"鐢垫睜鍜岀┖鎵樼洏鏁伴噺鏌ヨ澶辫触: {ex.Message}");
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
index fc7e7ae..c3cbc40 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -64,7 +64,7 @@
"PDAVersion": "4",
"WebSocketPort": 9296,
"AutoOutboundTask": {
- "Enable": true, /// 鏄惁鍚敤鑷姩鍑哄簱浠诲姟
+ "Enable": false, /// 鏄惁鍚敤鑷姩鍑哄簱浠诲姟
"CheckIntervalSeconds": 300, /// 妫�鏌ラ棿闅旓紙绉掞級
"TargetAddresses": { /// 鎸夊贩閬撳墠缂�閰嶇疆鐩爣鍦板潃锛堟敮鎸佸鍑哄簱鍙o級
"GW": [ "11001", "11010", "11068" ],
--
Gitblit v1.9.3