From c906272c0905b1309503de92affbdb06ec9d4268 Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期五, 01 五月 2026 09:48:41 +0800
Subject: [PATCH] 1
---
Code/WMS/WIDESEA_WMSClient/src/views/Home.vue | 821 +++++++++++++++++++++-----
Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js | 11
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs | 304 ++++----
Code/WMS/WIDESEA_WMSClient/src/extension/stock/hcstockInfo.jsx | 163 +++++
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs | 25
Code/WMS/WIDESEA_WMSClient/src/views/stock/hcstockInfo.vue | 505 ++++++++++++++++
Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue | 2
7 files changed, 1,498 insertions(+), 333 deletions(-)
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs
index cb689b9..5a3c6f4 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs
@@ -1,153 +1,153 @@
-锘縰sing Serilog;
-using System.Diagnostics.CodeAnalysis;
-using WIDESEA_Core;
-using WIDESEAWCS_Common.HttpEnum;
-using WIDESEAWCS_Common.TaskEnum;
-using WIDESEAWCS_Core;
-using WIDESEAWCS_Core.Enums;
-using WIDESEAWCS_Core.Helper;
-using WIDESEAWCS_DTO;
-using WIDESEAWCS_DTO.TaskInfo;
-using WIDESEAWCS_ITaskInfoRepository;
-using WIDESEAWCS_ITaskInfoService;
-using WIDESEAWCS_Model.Models;
-using WIDESEAWCS_QuartzJob.Models;
-using WIDESEAWCS_QuartzJob.Service;
-using WIDESEAWCS_Tasks;
-
-namespace WIDESEAWCS_TaskInfoService.Flows
-{
- /// <summary>
- /// 鍏ュ簱浠诲姟娴佺▼鏈嶅姟銆�
- /// 璐熻矗鍏ュ簱浠诲姟鎺ユ敹鍒濆鍖栥�佺姸鎬佹帹杩涘強鍫嗗灈鏈哄畬鎴愬鐞嗐��
- /// </summary>
- public class InboundTaskFlowService : IInboundTaskFlowService
- {
+锘縰sing Serilog;
+using System.Diagnostics.CodeAnalysis;
+using WIDESEA_Core;
+using WIDESEAWCS_Common.HttpEnum;
+using WIDESEAWCS_Common.TaskEnum;
+using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.Enums;
+using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_DTO;
+using WIDESEAWCS_DTO.TaskInfo;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+using WIDESEAWCS_QuartzJob.Models;
+using WIDESEAWCS_QuartzJob.Service;
+using WIDESEAWCS_Tasks;
+
+namespace WIDESEAWCS_TaskInfoService.Flows
+{
+ /// <summary>
+ /// 鍏ュ簱浠诲姟娴佺▼鏈嶅姟銆�
+ /// 璐熻矗鍏ュ簱浠诲姟鎺ユ敹鍒濆鍖栥�佺姸鎬佹帹杩涘強鍫嗗灈鏈哄畬鎴愬鐞嗐��
+ /// </summary>
+ public class InboundTaskFlowService : IInboundTaskFlowService
+ {
private readonly IRouterService _routerService;
- private readonly ITaskRepository _taskRepository;
- private readonly HttpClientHelper _httpClientHelper;
- private readonly ILogger _logger;
-
- /// <summary>
- /// 鍒濆鍖栧叆搴撲换鍔℃祦绋嬫湇鍔°��
- /// </summary>
- /// <param name="routerService">璺敱鏈嶅姟銆�</param>
- /// <param name="httpClientHelper">WMS鎺ュ彛璋冪敤甯姪绫汇��</param>
- public InboundTaskFlowService(IRouterService routerService, ITaskRepository taskRepository, HttpClientHelper httpClientHelper, ILogger logger)
- {
- _routerService = routerService;
- _taskRepository = taskRepository;
- _httpClientHelper = httpClientHelper;
- _logger = logger;
- }
-
- /// <summary>
- /// 鎺ユ敹WMS浠诲姟鏃跺垵濮嬪寲鍏ュ簱浠诲姟銆�
- /// </summary>
- /// <param name="task">浠诲姟瀹炰綋銆�</param>
- /// <param name="source">WMS浠诲姟鍘熷鏁版嵁銆�</param>
- public WebResponseContent InitializeOnReceive([NotNull] Dt_Task task, [NotNull] WMSTaskDTO source)
- {
- WebResponseContent content = new WebResponseContent();
- Dt_Router routers = _routerService.QueryNextRoute(source.SourceAddress);
- if (routers.IsNullOrEmpty())
- {
- return content.Error("鏈壘鍒拌矾鐢变俊鎭�");
- }
-
- task.TaskStatus = (int)TaskInStatusEnum.InNew;
- task.CurrentAddress = source.SourceAddress;
- task.NextAddress = routers.ChildPosi;
-
- return content.OK();
- }
-
- /// <summary>
- /// 鎺ㄨ繘鍏ュ簱浠诲姟鐘舵�侊紝骞跺湪鍏抽敭鐘舵�佽皟鐢╓MS鎺ュ彛銆�
- /// </summary>
- /// <param name="task">浠诲姟瀹炰綋銆�</param>
- /// <returns>鎺ㄨ繘缁撴灉銆�</returns>
- public WebResponseContent MoveToNextStatus([NotNull] Dt_Task task)
- {
- if (task.TaskStatus >= (int)TaskInStatusEnum.InFinish)
- return WebResponseContent.Instance.Error($"璇ヤ换鍔$姸鎬佷笉鍙烦杞埌涓嬩竴姝�,浠诲姟鍙�:銆恵task.TaskNum}銆�,浠诲姟鐘舵��:銆恵task.TaskStatus}銆�");
-
- task.TaskStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskInStatusEnum>();
- if (task.TaskStatus <= 0)
- return WebResponseContent.Instance.Error($"璇ヤ换鍔$姸鎬佷笉鍙烦杞埌涓嬩竴姝�,浠诲姟鍙�:銆恵task.TaskNum}銆�,浠诲姟鐘舵��:銆恵task.TaskStatus}銆�");
-
- if (task.TaskStatus == (int)TaskInStatusEnum.Line_InFinish)
- {
- return GetWMSInboundLocation(task);
- }
-
- return UpdateWMSTaskStatus(task);
- }
-
- /// <summary>
- /// 澶勭悊鍫嗗灈鏈哄叆搴撳畬鎴愬姩浣溿��
- /// </summary>
- /// <param name="task">浠诲姟瀹炰綋銆�</param>
- /// <returns>澶勭悊缁撴灉銆�</returns>
- public WebResponseContent CompleteStackerTask([NotNull] Dt_Task task)
- {
- WebResponseContent content = new WebResponseContent();
- if (task.TaskStatus != (int)TaskInStatusEnum.SC_InExecuting)
- {
- return WebResponseContent.Instance.OK();
- }
-
- int nextStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskInStatusEnum>();
- task.TaskStatus = nextStatus;
- task.ModifyDate = DateTime.Now;
- task.Modifier = "System";
-
- var result = _httpClientHelper.Post<WebResponseContent>(
- nameof(ConfigKey.InboundFinishTaskAsync),
- (new CreateTaskDto { PalletCode = task.PalletCode }).ToJson());
-
- if (!result.IsSuccess || !result.Data.Status)
- {
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆怚nboundFinishTaskAsync銆�,璇锋眰鍙傛暟:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "InboundTaskFlowService");
- return content.Error($"閫氱煡WMS绯荤粺鍫嗗灈鏈哄叆搴撳畬鎴愬け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
- }
-
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆怚nboundFinishTaskAsync銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:0ms", "InboundTaskFlowService");
- return content.OK($"閫氱煡WMS绯荤粺鍫嗗灈鏈哄叆搴撳畬鎴愭垚鍔�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�");
- }
-
- /// <summary>
- /// 浠嶹MS鑾峰彇鍏ュ簱鐩爣鍦板潃骞跺洖鍐欎换鍔°��
- /// </summary>
- /// <param name="task">浠诲姟瀹炰綋銆�</param>
- /// <returns>璋冪敤缁撴灉銆�</returns>
- private WebResponseContent GetWMSInboundLocation(Dt_Task task)
- {
- string configKey = nameof(ConfigKey.GetTasksLocation);
- string requestParam = new CreateTaskDto { PalletCode = task.PalletCode }.ToJson();
- DateTime startTime = DateTime.Now;
-
- var result = _httpClientHelper.Post<WebResponseContent>(
- configKey,
- requestParam);
-
- if (!result.IsSuccess || !result.Data.Status)
- {
- QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "InboundTaskFlowService");
- return WebResponseContent.Instance.Error($"璋冪敤WMS鎺ュ彛鑾峰彇浠诲姟鐩爣鍦板潃澶辫触,浠诲姟鍙�:銆恵task.TaskNum}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
- }
-
- QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "InboundTaskFlowService");
-
- string? nextAddress = result.Data.Data?.ToString();
- if (string.IsNullOrEmpty(nextAddress))
- return WebResponseContent.Instance.Error($"璋冪敤WMS鎺ュ彛鑾峰彇浠诲姟鐩爣鍦板潃澶辫触,浠诲姟鍙�:銆恵task.TaskNum}銆�,閿欒淇℃伅:銆愭湭鑾峰彇鍒版湁鏁堢殑鐩爣鍦板潃銆�");
-
- task.CurrentAddress = task.NextAddress;
- task.NextAddress = nextAddress;
- task.TargetAddress = nextAddress;
-
- return WebResponseContent.Instance.OK();
+ private readonly ITaskRepository _taskRepository;
+ private readonly HttpClientHelper _httpClientHelper;
+ private readonly ILogger _logger;
+
+ /// <summary>
+ /// 鍒濆鍖栧叆搴撲换鍔℃祦绋嬫湇鍔°��
+ /// </summary>
+ /// <param name="routerService">璺敱鏈嶅姟銆�</param>
+ /// <param name="httpClientHelper">WMS鎺ュ彛璋冪敤甯姪绫汇��</param>
+ public InboundTaskFlowService(IRouterService routerService, ITaskRepository taskRepository, HttpClientHelper httpClientHelper, ILogger logger)
+ {
+ _routerService = routerService;
+ _taskRepository = taskRepository;
+ _httpClientHelper = httpClientHelper;
+ _logger = logger;
+ }
+
+ /// <summary>
+ /// 鎺ユ敹WMS浠诲姟鏃跺垵濮嬪寲鍏ュ簱浠诲姟銆�
+ /// </summary>
+ /// <param name="task">浠诲姟瀹炰綋銆�</param>
+ /// <param name="source">WMS浠诲姟鍘熷鏁版嵁銆�</param>
+ public WebResponseContent InitializeOnReceive([NotNull] Dt_Task task, [NotNull] WMSTaskDTO source)
+ {
+ WebResponseContent content = new WebResponseContent();
+ Dt_Router routers = _routerService.QueryNextRoute(source.SourceAddress);
+ if (routers.IsNullOrEmpty())
+ {
+ return content.Error("鏈壘鍒拌矾鐢变俊鎭�");
+ }
+
+ task.TaskStatus = (int)TaskInStatusEnum.InNew;
+ task.CurrentAddress = source.SourceAddress;
+ task.NextAddress = routers.ChildPosi;
+
+ return content.OK();
+ }
+
+ /// <summary>
+ /// 鎺ㄨ繘鍏ュ簱浠诲姟鐘舵�侊紝骞跺湪鍏抽敭鐘舵�佽皟鐢╓MS鎺ュ彛銆�
+ /// </summary>
+ /// <param name="task">浠诲姟瀹炰綋銆�</param>
+ /// <returns>鎺ㄨ繘缁撴灉銆�</returns>
+ public WebResponseContent MoveToNextStatus([NotNull] Dt_Task task)
+ {
+ if (task.TaskStatus >= (int)TaskInStatusEnum.InFinish)
+ return WebResponseContent.Instance.Error($"璇ヤ换鍔$姸鎬佷笉鍙烦杞埌涓嬩竴姝�,浠诲姟鍙�:銆恵task.TaskNum}銆�,浠诲姟鐘舵��:銆恵task.TaskStatus}銆�");
+
+ task.TaskStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskInStatusEnum>();
+ if (task.TaskStatus <= 0)
+ return WebResponseContent.Instance.Error($"璇ヤ换鍔$姸鎬佷笉鍙烦杞埌涓嬩竴姝�,浠诲姟鍙�:銆恵task.TaskNum}銆�,浠诲姟鐘舵��:銆恵task.TaskStatus}銆�");
+
+ if (task.TaskStatus == (int)TaskInStatusEnum.Line_InFinish)
+ {
+ return GetWMSInboundLocation(task);
+ }
+
+ return UpdateWMSTaskStatus(task);
+ }
+
+ /// <summary>
+ /// 澶勭悊鍫嗗灈鏈哄叆搴撳畬鎴愬姩浣溿��
+ /// </summary>
+ /// <param name="task">浠诲姟瀹炰綋銆�</param>
+ /// <returns>澶勭悊缁撴灉銆�</returns>
+ public WebResponseContent CompleteStackerTask([NotNull] Dt_Task task)
+ {
+ WebResponseContent content = new WebResponseContent();
+ if (task.TaskStatus != (int)TaskInStatusEnum.SC_InExecuting)
+ {
+ return WebResponseContent.Instance.OK();
+ }
+
+ int nextStatus = task.TaskStatus.GetNextNotCompletedStatus<TaskInStatusEnum>();
+ task.TaskStatus = nextStatus;
+ task.ModifyDate = DateTime.Now;
+ task.Modifier = "System";
+
+ var result = _httpClientHelper.Post<WebResponseContent>(
+ nameof(ConfigKey.InboundFinishTaskAsync),
+ (new CreateTaskDto { PalletCode = task.PalletCode }).ToJson());
+
+ if (!result.IsSuccess || !result.Data.Status)
+ {
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆怚nboundFinishTaskAsync銆�,璇锋眰鍙傛暟:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "InboundTaskFlowService");
+ return content.Error($"閫氱煡WMS绯荤粺鍫嗗灈鏈哄叆搴撳畬鎴愬け璐�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
+ }
+
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆怚nboundFinishTaskAsync銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:0ms", "InboundTaskFlowService");
+ return content.OK($"閫氱煡WMS绯荤粺鍫嗗灈鏈哄叆搴撳畬鎴愭垚鍔�,浠诲姟鍙�:銆恵task.TaskNum}銆�,鎵樼洏鍙�:銆恵task.PalletCode}銆�");
+ }
+
+ /// <summary>
+ /// 浠嶹MS鑾峰彇鍏ュ簱鐩爣鍦板潃骞跺洖鍐欎换鍔°��
+ /// </summary>
+ /// <param name="task">浠诲姟瀹炰綋銆�</param>
+ /// <returns>璋冪敤缁撴灉銆�</returns>
+ private WebResponseContent GetWMSInboundLocation(Dt_Task task)
+ {
+ string configKey = nameof(ConfigKey.GetTasksLocation);
+ string requestParam = new CreateTaskDto { PalletCode = task.PalletCode }.ToJson();
+ DateTime startTime = DateTime.Now;
+
+ var result = _httpClientHelper.Post<WebResponseContent>(
+ configKey,
+ requestParam);
+
+ if (!result.IsSuccess || !result.Data.Status)
+ {
+ QuartzLogHelper.LogError(_logger, $"璋冪敤WMS鎺ュ彛澶辫触,鎺ュ彛:銆恵configKey}銆�,璇锋眰鍙傛暟:銆恵requestParam}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�", "InboundTaskFlowService");
+ return WebResponseContent.Instance.Error($"璋冪敤WMS鎺ュ彛鑾峰彇浠诲姟鐩爣鍦板潃澶辫触,浠诲姟鍙�:銆恵task.TaskNum}銆�,閿欒淇℃伅:銆恵result.Data?.Message}銆�");
+ }
+
+ QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "InboundTaskFlowService");
+
+ string? nextAddress = result.Data.Data?.ToString();
+ if (string.IsNullOrEmpty(nextAddress))
+ return WebResponseContent.Instance.Error($"璋冪敤WMS鎺ュ彛鑾峰彇浠诲姟鐩爣鍦板潃澶辫触,浠诲姟鍙�:銆恵task.TaskNum}銆�,閿欒淇℃伅:銆愭湭鑾峰彇鍒版湁鏁堢殑鐩爣鍦板潃銆�");
+
+ task.CurrentAddress = task.NextAddress;
+ task.NextAddress = nextAddress;
+ task.TargetAddress = nextAddress;
+
+ return WebResponseContent.Instance.OK();
}
/// <summary>
@@ -200,6 +200,6 @@
QuartzLogHelper.LogInfo(_logger, $"璋冪敤WMS鎺ュ彛鎴愬姛,鎺ュ彛:銆恵configKey}銆�,鍝嶅簲鏁版嵁:銆恵result.Data?.Data}銆�,鑰楁椂:{(DateTime.Now - startTime).TotalMilliseconds}ms", "InboundTaskFlowService");
return WebResponseContent.Instance.OK();
- }
- }
-}
+ }
+ }
+}
diff --git a/Code/WMS/WIDESEA_WMSClient/src/extension/stock/hcstockInfo.jsx b/Code/WMS/WIDESEA_WMSClient/src/extension/stock/hcstockInfo.jsx
new file mode 100644
index 0000000..7bb7d44
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/extension/stock/hcstockInfo.jsx
@@ -0,0 +1,163 @@
+//姝s鏂囦欢鏄敤鏉ヨ嚜瀹氫箟鎵╁睍涓氬姟浠g爜锛屽彲浠ユ墿灞曚竴浜涜嚜瀹氫箟椤甸潰鎴栬�呴噸鏂伴厤缃敓鎴愮殑浠g爜
+
+let extension = {
+ components: {
+ //鏌ヨ鐣岄潰鎵╁睍缁勪欢
+ gridHeader: "",
+ gridBody: "",
+ gridFooter: "",
+ //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
+ modelHeader: "",
+ modelBody: "",
+ modelFooter: "",
+ },
+ tableAction: "",
+ buttons: { view: [], box: [], detail: [] },
+ methods: {
+ onInit() {
+ // 娣诲姞MES鎿嶄綔鍒�
+ this.columns.push({
+ title: "鎿嶄綔",
+ field: "鎿嶄綔",
+ align: "center",
+ width: 200,
+ fixed: "right",
+ render: (h, { row, column, index }) => {
+ return (
+ <div>
+ <el-button
+ type="primary"
+ size="small"
+ onClick={($e) => {
+ this.handleInbound(row);
+ }}
+ >
+ 杩涚珯
+ </el-button>
+ <el-button
+ type="success"
+ size="small"
+ style="margin-left: 8px"
+ onClick={($e) => {
+ this.handleOutbound(row);
+ }}
+ >
+ 鍑虹珯
+ </el-button>
+ </div>
+ );
+ },
+ });
+ },
+
+ // 鎵樼洏杩涚珯鎿嶄綔
+ async handleInbound(row) {
+ try {
+ await this.$confirm(
+ `纭鎵ц鎵樼洏杩涚珯鎿嶄綔锛焅n鎵樼洏缂栧彿锛�${row.palletCode}`,
+ "杩涚珯纭",
+ {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ },
+ );
+
+ const result = await this.http.post(
+ "/api/StockInfo/inboundInContainer",
+ {
+ palletCode: row.palletCode,
+ stockId: row.id,
+ },
+ "姝e湪璋冪敤MES鎺ュ彛...",
+ );
+
+ if (result.status) {
+ this.$Message.success(result.message || "鎵樼洏杩涚珯鎴愬姛");
+ this.$refs.table.load();
+ } else {
+ this.$error(result.message || "鎵樼洏杩涚珯澶辫触");
+ }
+ } catch (error) {
+ if (error !== "cancel") {
+ this.$error(error.message || "缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+ }
+ }
+ },
+
+ // 鎵樼洏鍑虹珯鎿嶄綔
+ async handleOutbound(row) {
+ try {
+ await this.$confirm(
+ `纭鎵ц鎵樼洏鍑虹珯鎿嶄綔锛焅n鎵樼洏缂栧彿锛�${row.palletCode}`,
+ "鍑虹珯纭",
+ {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ },
+ );
+
+ const result = await this.http.post(
+ "/api/StockInfo/outboundInContainer",
+ {
+ palletCode: row.palletCode,
+ stockId: row.id,
+ },
+ "姝e湪璋冪敤MES鎺ュ彛...",
+ );
+
+ if (result.status) {
+ this.$Message.success(result.message || "鎵樼洏鍑虹珯鎴愬姛");
+ this.$refs.table.load();
+ } else {
+ this.$error(result.message || "鎵樼洏鍑虹珯澶辫触");
+ }
+ } catch (error) {
+ if (error !== "cancel") {
+ this.$error(error.message || "缃戠粶閿欒锛岃绋嶅悗閲嶈瘯");
+ }
+ }
+ },
+
+ onInited() {
+ // 妗嗘灦鍒濆鍖栭厤缃悗
+ },
+ searchBefore(param) {
+ const stockStatusFilter1 = {
+ name: "stockStatus",
+ value: "6",
+ displayType: "int"
+ };
+ const warehouseIdFilter1 = {
+ name: "warehouseId",
+ value: "3",
+ displayType: "int"
+ };
+ if (!param.wheres) {
+ param.wheres = [];
+ }
+ // 灏嗚繃婊ゆ潯浠舵坊鍔犲埌鏌ヨ鍙傛暟涓�
+ param.wheres.push(stockStatusFilter1);
+ param.wheres.push(warehouseIdFilter1);
+ return true;
+ },
+ searchAfter(result) {
+ return result;
+ },
+ addBefore(formData) {
+ return true;
+ },
+ updateBefore(formData) {
+ return true;
+ },
+ rowClick({ row, column, event }) {
+ this.$refs.table.$refs.table.toggleRowSelection(row);
+ },
+ modelOpenAfter(row) {
+ // 鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚�
+ },
+ },
+};
+
+export default extension;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js b/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
index e2bc776..598b86e 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
+++ b/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
@@ -78,11 +78,18 @@
path: '/outboundOrderDetail',
name: 'outboundOrderDetail',
component: () => import('@/views/outbound/outboundOrderDetail.vue')
- }, {
+ },
+ {
path: '/stockInfo',
name: 'stockInfo',
component: () => import('@/views/stock/stockInfo.vue')
- }, {
+ },
+ {
+ path: '/hcstockInfo',
+ name: 'hcstockInfo',
+ component: () => import('@/views/stock/hcstockInfo.vue')
+ },
+ {
path: '/stockInfoDetail',
name: 'stockInfoDetail',
component: () => import('@/views/stock/stockInfoDetail.vue')
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
index 9023c51..32359d5 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/Home.vue
@@ -1,10 +1,95 @@
<template>
<div class="dashboard-container">
- <!-- 鍚勪粨搴撴湀搴﹀嚭鍏ュ簱瀵规瘮鍥� -->
+ <!-- 椤堕儴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>
+ </div>
+ <div class="kpi-card">
+ <div class="kpi-icon">馃摝</div>
+ <div class="kpi-info">
+ <div class="kpi-label">鎬诲簱瀛橀噺</div>
+ <div class="kpi-value">{{ totalStock.toLocaleString() }}</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">{{ monthlyInboundTotal.toLocaleString() }}</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">{{ monthlyOutboundTotal.toLocaleString() }}</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>
+ <!-- 浠撳簱鏁板瓧鏄剧ず鍖哄煙 -->
+ <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 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-warehouse-monthly" 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-warehouse" class="chart-content"></div>
</div>
</div>
</div>
@@ -18,8 +103,40 @@
data() {
return {
charts: {},
- monthlyData: [],
- warehouseNames: ['FJSC1', 'ZJSC1', 'GWSC1', 'CWSC1', 'HCSC1']
+ // 浜斾釜浠撳簱瀹氫箟 - 涓�3涓�
+ topWarehouses: [
+ { code: "GWSC1", name: "楂樻俯1鍙蜂粨搴�" },
+ { code: "CWSC1", name: "甯告俯1鍙蜂粨搴�" },
+ { code: "HCSC1", name: "鍒嗗1鍙蜂粨搴�" }
+ ],
+ // 涓�2涓�
+ bottomWarehouses: [
+ { code: "FJSC1", name: "璐熸瀬鍗�1鍙蜂粨搴�" },
+ { code: "ZJSC1", name: "姝f瀬鍗�1鍙蜂粨搴�" }
+ ],
+ dailyData: [],
+ // 瀛樺偍姣忎釜浠撳簱鐨勬湀搴︽暟鎹�
+ monthlyData: {
+ GWSC1: [],
+ CWSC1: [],
+ HCSC1: [],
+ FJSC1: [],
+ ZJSC1: []
+ },
+ // 瀛樺偍姣忎釜浠撳簱鐨勫綋鍓嶅簱瀛�
+ warehouseStocks: {
+ GWSC1: 0,
+ CWSC1: 0,
+ HCSC1: 0,
+ FJSC1: 0,
+ ZJSC1: 0
+ },
+ warehouseData: [],
+ // KPI 姹囨�绘暟鎹�
+ totalWarehouses: 5,
+ totalStock: 0,
+ monthlyInboundTotal: 0,
+ monthlyOutboundTotal: 0
};
},
mounted() {
@@ -29,198 +146,412 @@
},
beforeUnmount() {
window.removeEventListener("resize", this.handleResize);
- Object.values(this.charts).forEach(chart => chart.dispose());
+ Object.values(this.charts).forEach(chart => chart && chart.dispose());
},
methods: {
handleResize() {
- Object.values(this.charts).forEach(chart => chart.resize());
+ Object.values(this.charts).forEach(chart => chart && chart.resize());
},
initCharts() {
- this.charts.warehouseMonthly = echarts.init(document.getElementById("chart-warehouse-monthly"));
+ // 鍒濆鍖栨墍鏈変粨搴撳浘琛�
+ const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
+ allWarehouses.forEach(warehouse => {
+ const chartId = `chart-${warehouse.code}`;
+ const el = document.getElementById(chartId);
+ if (el) {
+ this.charts[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() {
- await this.loadMonthlyStats();
+ // 骞惰鍔犺浇鎵�鏈変粨搴撶殑鏈堝害鏁版嵁锛堝垎鍒紶鍏ヤ笉鍚岀殑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 loadMonthlyStats() {
+ async loadMonthlyStatsForWarehouse(roadway) {
+ console.log(`姝e湪鍔犺浇${roadway}鐨勬瘡鏈堢粺璁℃暟鎹�...`);
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();
+ // 鍏抽敭淇锛氬垎鍒紶鍏ヤ笉鍚岀殑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("鍔犺浇姣忔湀缁熻澶辫触", e);
+ console.error(`鍔犺浇${roadway}姣忔湀缁熻澶辫触`, e);
+ this.monthlyData[roadway] = [];
}
},
- getWarehouseName(code) {
- const nameMap = {
- 'FJSC1': '璐熸瀬鍗�1鍙蜂粨搴�',
- 'ZJSC1': '姝f瀬鍗�1鍙蜂粨搴�',
- 'GWSC1': '楂樻俯1鍙蜂粨搴�',
- 'CWSC1': '甯告俯1鍙蜂粨搴�',
- 'HCSC1': '鍒嗗1鍙蜂粨搴�'
- };
- return nameMap[code] || code;
+ 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);
+ }
},
- 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
+ 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);
}
- })),
- barWidth: '15%',
- barGap: '10%',
- itemStyle: {
- color: this.getBarColor(index),
- borderRadius: [3, 3, 0, 0]
+ } catch (e) {
+ // 浣跨敤妯℃嫙鏁版嵁
+ const mockStocks = {
+ GWSC1: 12580,
+ CWSC1: 8920,
+ HCSC1: 15600,
+ FJSC1: 4300,
+ ZJSC1: 7200
+ };
+ this.warehouseStocks[warehouse.code] = mockStocks[warehouse.code] || 0;
}
- });
+ }
+ } catch (e) {
+ console.error("鍔犺浇浠撳簱搴撳瓨澶辫触", e);
+ }
+ },
+
+ 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;
+ },
+
+ 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;
+ },
+
+ getWarehouseStock(warehouseCode) {
+ return this.warehouseStocks[warehouseCode] || 0;
+ },
+
+ calculateKPIs() {
+ // 璁$畻鎬诲簱瀛�
+ let totalStock = 0;
+ for (const code in this.warehouseStocks) {
+ totalStock += this.warehouseStocks[code];
+ }
+ 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;
+ },
+
+ // 鏇存柊鎵�鏈変粨搴撶殑鏈堝害瓒嬪娍鍥捐〃
+ updateAllMonthlyTrendCharts() {
+ const allWarehouses = [...this.topWarehouses, ...this.bottomWarehouses];
+ allWarehouses.forEach(warehouse => {
+ this.updateMonthlyTrendChartForWarehouse(warehouse.code);
+ });
+ },
+
+ updateMonthlyTrendChartForWarehouse(roadway) {
+ const chart = this.charts[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 option = {
- title: {
- text: '鍚勪粨搴撴湀搴﹀嚭鍏ュ簱瀵规瘮',
- textStyle: {
- color: '#00ffff',
- fontSize: 16
- },
- left: 'center',
- top: 10
+ tooltip: {
+ trigger: "axis",
+ formatter: function(params) {
+ let result = params[0].axisValue + "<br/>";
+ params.forEach(p => {
+ result += `${p.marker}${p.seriesName}: ${p.value}<br/>`;
+ });
+ return result;
+ }
},
+ legend: {
+ data: ["鍏ュ簱", "鍑哄簱"],
+ textStyle: { color: "#fff" },
+ top: 0,
+ right: 10,
+ itemWidth: 20,
+ itemHeight: 12
+ },
+ grid: {
+ left: "8%",
+ right: "8%",
+ top: "18%",
+ bottom: "12%",
+ containLabel: true
+ },
+ xAxis: {
+ type: "category",
+ data: monthLabels,
+ axisLabel: {
+ color: "#ccc",
+ rotate: 45,
+ fontSize: 10,
+ interval: 0,
+ margin: 8
+ },
+ axisLine: { lineStyle: { color: "#4a5b6e" } }
+ },
+ yAxis: {
+ type: "value",
+ name: "浠诲姟鏁伴噺",
+ nameTextStyle: { color: "#ccc", fontSize: 11 },
+ axisLabel: { color: "#ccc" },
+ splitLine: { lineStyle: { color: "#2a3a4a", type: "dashed" } }
+ },
+ series: [
+ {
+ name: "鍏ュ簱",
+ type: "bar",
+ data: inboundData,
+ itemStyle: {
+ color: "#5470c6",
+ borderRadius: [4, 4, 0, 0]
+ },
+ barWidth: "35%",
+ label: {
+ show: inboundData.length <= 8,
+ position: "top",
+ color: "#5470c6",
+ fontSize: 10
+ }
+ },
+ {
+ name: "鍑哄簱",
+ type: "line",
+ data: outboundData,
+ symbol: "circle",
+ symbolSize: 6,
+ itemStyle: { color: "#91cc75" },
+ lineStyle: { width: 2, type: "solid" },
+ smooth: false,
+ label: {
+ show: outboundData.length <= 8,
+ position: "top",
+ color: "#91cc75",
+ fontSize: 10
+ }
+ }
+ ]
+ };
+ 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;
+ const warehouseNames = this.warehouseData.map(w => w.warehouse);
+ 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',
+ trigger: "axis",
axisPointer: {
- type: 'shadow'
+ type: "shadow"
},
formatter: function(params) {
- let tip = `<strong>${params[0].axisValue}</strong><br/>`;
+ let tip = params[0].name + "<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/>`;
+ const dataIndex = param.dataIndex;
+ const warehouse = window.homeComponent?.warehouseData[dataIndex];
+ if (warehouse) {
+ 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/>`;
+ }
+ } else {
+ tip += `${param.marker}${param.seriesName}: ${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
+ data: ["宸茬敤瀹归噺", "鍓╀綑瀹归噺"],
+ textStyle: { color: "#fff" }
},
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'
- }
- }
+ type: "category",
+ data: warehouseNames,
+ axisLabel: { color: "#fff", rotate: 30, interval: 0 }
},
yAxis: {
- type: 'value',
- name: '鏁伴噺',
- nameTextStyle: { color: '#fff' },
- axisLabel: { color: '#fff' },
- splitLine: {
- lineStyle: {
- color: 'rgba(255,255,255,0.1)',
- type: 'dashed'
- }
- }
+ type: "value",
+ name: "瀹归噺",
+ axisLabel: { color: "#fff" }
},
- dataZoom: [
+ series: [
{
- type: 'inside',
- start: 0,
- end: 100
+ name: "宸茬敤瀹归噺",
+ type: "bar",
+ data: hasStocks.map((value, index) => ({
+ value: value,
+ label: {
+ show: true,
+ position: "top",
+ formatter: (params) => {
+ const pct = hasStockPercentages[params.dataIndex];
+ return `${params.value} (${pct})`;
+ },
+ color: "#91cc75",
+ fontSize: 11
+ }
+ })),
+ itemStyle: { color: "#91cc75" }
},
{
- 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'
- }
+ name: "鍓╀綑瀹归噺",
+ type: "bar",
+ data: noStocks.map((value, index) => ({
+ value: value,
+ label: {
+ show: true,
+ position: "top",
+ formatter: (params) => {
+ const pct = noStockPercentages[params.dataIndex];
+ return `${params.value} (${pct})`;
+ },
+ color: "#fac858",
+ fontSize: 11
+ }
+ })),
+ itemStyle: { color: "#fac858" }
}
- ],
- series: series
+ ]
};
- this.charts.warehouseMonthly.setOption(option, true);
- },
-
- getBarColor(index) {
- const colors = [
- '#5470c6', // 钃�
- '#fac858', // 榛�
- '#73c0de', // 澶╄摑
- '#fc8452', // 姗�
- '#ea7ccc' // 绮�
- ];
- return colors[index] || '#5470c6';
+ window.homeComponent = this;
+ this.charts.warehouse.setOption(option, true);
}
}
};
@@ -235,36 +566,93 @@
background-attachment: fixed;
}
-.chart-row {
+/* KPI 鍗$墖鏍峰紡 */
+.kpi-cards {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 20px;
+ margin-bottom: 24px;
+}
+
+.kpi-card {
+ background: rgba(10, 16, 35, 0.7);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(64, 224, 208, 0.3);
+ border-radius: 16px;
+ padding: 16px 20px;
display: flex;
+ align-items: center;
+ gap: 16px;
+ transition: all 0.3s ease;
+ box-shadow: 0 0 15px rgba(0, 255, 255, 0.1);
+}
+
+.kpi-card:hover {
+ transform: translateY(-3px);
+ border-color: rgba(64, 224, 208, 0.6);
+ box-shadow: 0 0 25px rgba(0, 255, 255, 0.2);
+}
+
+.kpi-icon {
+ font-size: 32px;
+ opacity: 0.9;
+}
+
+.kpi-info {
+ flex: 1;
+}
+
+.kpi-label {
+ font-size: 13px;
+ color: #8ba0b5;
+ margin-bottom: 6px;
+ letter-spacing: 1px;
+}
+
+.kpi-value {
+ font-size: 28px;
+ font-weight: 700;
+ color: #00ffff;
+ text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
+ 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 {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-bottom: 20px;
}
.chart-row.full-width {
width: 100%;
+ margin-bottom: 20px;
}
.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);
+ 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);
+ 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);
}
@@ -292,29 +680,129 @@
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: 16px;
+ font-size: 15px;
text-align: center;
- margin-bottom: 10px;
+ margin-bottom: 12px;
text-shadow: 0 0 10px rgba(0, 255, 255, 0.7);
font-weight: 500;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* 浠撳簱鏁板瓧鏄剧ず鍖哄煙 */
+.warehouse-numbers {
+ display: flex;
+ justify-content: space-around;
+ margin-bottom: 12px;
+ padding: 8px 0;
+ background: rgba(0, 0, 0, 0.3);
+ border-radius: 8px;
+}
+
+.number-item {
+ text-align: center;
+ flex: 1;
+}
+
+.number-label {
+ display: block;
+ font-size: 11px;
+ color: #8ba0b5;
+ margin-bottom: 4px;
+}
+
+.number-value {
+ display: block;
+ font-size: 20px;
+ font-weight: 700;
+ letter-spacing: 1px;
+}
+
+.number-item.inbound .number-value {
+ color: #5470c6;
+}
+
+.number-item.outbound .number-value {
+ color: #91cc75;
+}
+
+.number-item.stock .number-value {
+ color: #fac858;
}
.chart-content {
- height: 500px;
+ height: 240px;
width: 100%;
}
+/* 鍏ㄥ鍥捐〃 */
.full-width .chart-card {
- flex: none;
width: 100%;
}
.full-width .chart-content {
- height: 500px;
+ 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;
+ }
+ .chart-row.top-three {
+ grid-template-columns: 1fr;
+ }
+ .chart-row.bottom-two {
+ grid-template-columns: 1fr;
+ }
+ .chart-content {
+ height: 220px;
+ }
+ .full-width .chart-content {
+ height: 280px;
+ }
+ .card-title {
+ font-size: 13px;
+ white-space: normal;
+ }
+ .number-value {
+ font-size: 16px;
+ }
+}
+
+/* 娣诲姞缃戞牸绾挎晥鏋� */
.dashboard-container::before {
content: "";
position: fixed;
@@ -322,8 +810,7 @@
left: 0;
right: 0;
bottom: 0;
- background-image:
- linear-gradient(rgba(64, 224, 208, 0.05) 1px, transparent 1px),
+ 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;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/stock/hcstockInfo.vue b/Code/WMS/WIDESEA_WMSClient/src/views/stock/hcstockInfo.vue
new file mode 100644
index 0000000..271cedb
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/stock/hcstockInfo.vue
@@ -0,0 +1,505 @@
+<template>
+ <view-grid ref="grid" :columns="columns" :detail="detail" :editFormFields="editFormFields"
+ :editFormOptions="editFormOptions" :searchFormFields="searchFormFields" :searchFormOptions="searchFormOptions"
+ :table="table" :tableExpand="tableExpand" :extend="extend">
+ </view-grid>
+</template>
+
+<script>
+import extend from "@/extension/stock/hcstockInfo.jsx";
+import {
+ defineComponent,
+ getCurrentInstance,
+ h,
+ reactive,
+ ref,
+ resolveComponent,
+} from "vue";
+
+const TEXT = {
+ pageName: "搴撳瓨淇℃伅",
+ palletCode: "鎵樼洏缂栧彿",
+ stockStatus: "搴撳瓨鐘舵��",
+ locationCode: "璐т綅缂栧彿",
+ outboundDate: "鍑哄簱鏃堕棿",
+ warehouse: "浠撳簱",
+ creator: "鍒涘缓浜�",
+ createDate: "鍒涘缓鏃堕棿",
+ modifier: "淇敼浜�",
+ modifyDate: "淇敼鏃堕棿",
+ detailName: "搴撳瓨鏄庣粏",
+ materielName: "鐗╂枡鍚嶇О",
+ serialNumber: "鐢佃姱鐮�",
+ stockQuantity: "搴撳瓨鏁伴噺",
+ status: "鐘舵��",
+ inboundOrderRowNo: "閫氶亾鍙�",
+ detailLoading: "搴撳瓨鏄庣粏鍔犺浇涓�...",
+ detailLoadFailed: "搴撳瓨鏄庣粏鍔犺浇澶辫触",
+ detailEmpty: "褰撳墠搴撳瓨澶存殏鏃犳槑缁嗘暟鎹�",
+ expandPrefix: "鎵樼洏锛�",
+ expandMiddle: " / ",
+ expandLocation: "璐т綅锛�",
+};
+
+export default defineComponent({
+ setup() {
+ const { proxy } = getCurrentInstance();
+ const ElTable = resolveComponent("el-table");
+ const ElTableColumn = resolveComponent("el-table-column");
+
+ const table = ref({
+ key: "id",
+ footer: "Foots",
+ cnName: TEXT.pageName,
+ name: "stockInfo",
+ url: "/StockInfo/",
+ sortName: "id",
+ });
+
+ const editFormFields = ref({
+ palletCode: "",
+ palletType: 0,
+ warehouseId: 0,
+ mesUploadStatus: "",
+ stockStatus: "",
+ locationCode: "",
+ locationDetails: ""
+ });
+
+
+ const editFormOptions = ref([
+ [
+ { field: "palletCode", title: TEXT.palletCode, type: "string" },
+ { field: "stockStatus", title: TEXT.stockStatus, type: "select", dataKey: "stockStatusEmun", data: [] },
+ { field: "locationCode", title: TEXT.locationCode, type: "string" },
+ ],
+ ]);
+
+ const searchFormFields = ref({
+ palletCode: "",
+ warehouseId: "",
+ stockStatus: "",
+ locationCode: "",
+ });
+
+ const searchFormOptions = ref([
+ [
+ { title: TEXT.palletCode, field: "palletCode", type: "like" },
+ { title: TEXT.warehouse, field: "warehouseId", type: "selectList", dataKey: "warehouseEnum", data: [] },
+ { title: TEXT.stockStatus, field: "stockStatus", type: "selectList", dataKey: "stockStatusEmun", data: [] },
+ { title: TEXT.locationCode, field: "locationCode", type: "like" },
+ ],
+ ]);
+
+ const columns = ref([
+ {
+ field: "id",
+ title: "Id",
+ type: "int",
+ width: 90,
+ hidden: true,
+ readonly: true,
+ require: true,
+ align: "left",
+ },
+ {
+ field: "palletCode",
+ title: TEXT.palletCode,
+ type: "string",
+ width: 150,
+ align: "left",
+ },
+ {
+ field: "stockStatus",
+ title: TEXT.stockStatus,
+ type: "int",
+ width: 120,
+ align: "left",
+ bind: { key: "stockStatusEmun", data: [] },
+ },
+ {
+ field: "mesUploadStatus",
+ title: "MES鐘舵��",
+ type: "int",
+ width: 120,
+ align: "left",
+ bind: { key: "mesUploadStatusEnum", data: [] },
+ },
+ {
+ field: "outboundDate",
+ title: TEXT.outboundDate,
+ type: "string",
+ width: 150,
+ align: "left",
+ },
+ {
+ field: "locationCode",
+ title: TEXT.locationCode,
+ type: "string",
+ width: 120,
+ align: "left",
+ },
+ {
+ field: "warehouseId",
+ title: TEXT.warehouse,
+ type: "select",
+ width: 100,
+ align: "left",
+ bind: { key: "warehouseEnum", data: [] },
+ },
+ {
+ field: "creater",
+ title: TEXT.creator,
+ type: "string",
+ width: 90,
+ align: "left",
+ },
+ {
+ field: "createDate",
+ title: TEXT.createDate,
+ type: "datetime",
+ width: 160,
+ align: "left",
+ },
+ {
+ field: "modifier",
+ title: TEXT.modifier,
+ type: "string",
+ width: 100,
+ align: "left",
+ hidden: true,
+ },
+ {
+ field: "modifyDate",
+ title: TEXT.modifyDate,
+ type: "datetime",
+ width: 160,
+ align: "left",
+ hidden: true,
+ },
+ ]);
+
+ const detail = ref({
+ cnName: "#detailCnName",
+ table: "",
+ columns: [],
+ sortName: "",
+ });
+
+ const detailState = reactive({
+ rowsMap: {},
+ loadingMap: {},
+ errorMap: {},
+ });
+
+ const stockStatusOptions = ref([]);
+
+ const detailColumns = [
+ { field: "materielName", title: TEXT.materielName, minWidth: 160 },
+ { field: "serialNumber", title: TEXT.serialNumber, minWidth: 160 },
+ { field: "stockQuantity", title: TEXT.stockQuantity, minWidth: 120 },
+ { field: "status", title: TEXT.status, minWidth: 120 },
+ { field: "inboundOrderRowNo", title: TEXT.inboundOrderRowNo, minWidth: 120 },
+ ];
+
+ const normalizeValue = (value) => {
+ return value === null || value === undefined || value === "" ? "--" : value;
+ };
+
+ const formatStatusText = (value) => {
+ const matched = stockStatusOptions.value.find((item) => `${item.key}` === `${value}`);
+ return matched ? matched.value || matched.label : normalizeValue(value);
+ };
+
+ const getDetailRows = (stockId) => {
+ return detailState.rowsMap[stockId] || [];
+ };
+
+ const loadDetailRows = async (row) => {
+ if (!row || !row.id || detailState.loadingMap[row.id]) {
+ return;
+ }
+ if (detailState.rowsMap[row.id]) {
+ return;
+ }
+
+ detailState.loadingMap[row.id] = true;
+ detailState.errorMap[row.id] = "";
+ try {
+ const result = await proxy.http.post("/api/StockInfoDetail/getPageData", {
+ page: 1,
+ rows: 200,
+ sort: "id",
+ order: "asc",
+ wheres: JSON.stringify([
+ {
+ name: "stockId",
+ value: String(row.id),
+ displayType: "int",
+ },
+ ]),
+ });
+ detailState.rowsMap[row.id] = (result && result.rows) || [];
+ } catch (error) {
+ detailState.rowsMap[row.id] = null;
+ detailState.errorMap[row.id] = error?.message || TEXT.detailLoadFailed;
+ } finally {
+ detailState.loadingMap[row.id] = false;
+ }
+ };
+
+ const loadStockStatusOptions = async () => {
+ try {
+ const result = await proxy.http.post("/api/Sys_Dictionary/GetVueDictionary", ["stockStatusEmun", "mesUploadStatusEnum"]);
+ const matched = (result || []).find((item) => item.dicNo === "stockStatusEmun");
+ stockStatusOptions.value = matched ? matched.data || [] : [];
+ } catch (error) {
+ stockStatusOptions.value = [];
+ }
+ };
+
+ loadStockStatusOptions();
+
+ const renderStatus = (row) => {
+ if (detailState.loadingMap[row.id]) {
+ return h("div", { class: "stock-detail-status" }, TEXT.detailLoading);
+ }
+ if (detailState.errorMap[row.id]) {
+ return h(
+ "div",
+ { class: "stock-detail-status stock-detail-status--error" },
+ detailState.errorMap[row.id]
+ );
+ }
+ return null;
+ };
+
+ const renderDetailTable = (row) => {
+ const statusNode = renderStatus(row);
+ if (statusNode) {
+ return statusNode;
+ }
+
+ const rows = getDetailRows(row.id);
+ if (!rows.length) {
+ return h("div", { class: "stock-detail-status" }, TEXT.detailEmpty);
+ }
+
+ return h("div", { class: "stock-detail-table-wrapper" }, [
+ h("div", { class: "stock-detail-toolbar" }, [
+ h("div", { class: "stock-detail-toolbar__left" }, TEXT.detailName),
+ h("div", { class: "stock-detail-toolbar__right" }, [
+ h("span", { class: "stock-detail-count" }, `${rows.length} 鏉),
+ ]),
+ ]),
+ h(
+ ElTable,
+ {
+ data: rows,
+ border: true,
+ stripe: true,
+ size: "small",
+ class: "stock-detail-el-table",
+ maxHeight: 420,
+ emptyText: TEXT.detailEmpty,
+ },
+ () =>
+ detailColumns.map((column) =>
+ h(ElTableColumn, {
+ key: column.field,
+ prop: column.field,
+ label: column.title,
+ minWidth: column.minWidth,
+ showOverflowTooltip: true,
+ formatter: (detailRow) =>
+ column.field === "status"
+ ? formatStatusText(detailRow[column.field])
+ : normalizeValue(detailRow[column.field]),
+ })
+ )
+ ),
+ ]);
+ };
+
+ const tableExpand = ref({
+ width: 55,
+ onChange(row, expandedRows) {
+ const isExpanded = expandedRows.some((item) => item.id === row.id);
+ if (isExpanded) {
+ loadDetailRows(row);
+ }
+ },
+ render(render, { row }) {
+ return render("div", { class: "stock-detail-panel" }, [
+ render("div", { class: "stock-detail-header" }, [
+ render("div", { class: "stock-detail-header__main" }, [
+ render("div", { class: "stock-detail-title" }, TEXT.detailName),
+ render(
+ "div",
+ { class: "stock-detail-subtitle" },
+ `${TEXT.expandPrefix}${normalizeValue(row.palletCode)}${TEXT.expandMiddle}${TEXT.expandLocation}${normalizeValue(row.locationCode)}`
+ ),
+ ]),
+ // render("div", { class: "stock-detail-tags" }, [
+ // render("span", { class: "stock-detail-tag" }, normalizeValue(row.palletCode)),
+ // render(
+ // "span",
+ // { class: "stock-detail-tag stock-detail-tag--muted" },
+ // normalizeValue(row.locationCode)
+ // ),
+ // ]),
+ ]),
+ renderDetailTable(row),
+ ]);
+ },
+ });
+
+ return {
+ table,
+ extend,
+ editFormFields,
+ editFormOptions,
+ searchFormFields,
+ searchFormOptions,
+ columns,
+ detail,
+ tableExpand,
+ };
+ },
+});
+</script>
+
+<style scoped>
+.stock-detail-panel {
+ margin: 4px 8px 12px;
+ padding: 14px 16px 16px;
+ background: linear-gradient(180deg, #ffffff 0%, #fafbfc 100%);
+ border: 1px solid #e8edf3;
+ border-radius: 10px;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
+}
+
+.stock-detail-header {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 12px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid #edf1f5;
+}
+
+.stock-detail-header__main {
+ min-width: 0;
+}
+
+.stock-detail-title {
+ margin-bottom: 4px;
+ font-size: 15px;
+ font-weight: 700;
+ color: #303133;
+}
+
+.stock-detail-subtitle {
+ font-size: 13px;
+ color: #606266;
+ line-height: 1.6;
+}
+
+.stock-detail-tags {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-end;
+ gap: 8px;
+}
+
+.stock-detail-tag {
+ display: inline-flex;
+ align-items: center;
+ height: 28px;
+ padding: 0 10px;
+ color: #1f5eff;
+ background: #edf4ff;
+ border: 1px solid #d8e6ff;
+ border-radius: 999px;
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.stock-detail-tag--muted {
+ color: #4e5969;
+ background: #f4f6f8;
+ border-color: #e5e9ef;
+}
+
+.stock-detail-status {
+ padding: 14px 12px;
+ color: #606266;
+ background: #f8fafc;
+ border: 1px dashed #d9e2ec;
+ border-radius: 8px;
+}
+
+.stock-detail-status--error {
+ color: #f56c6c;
+ background: #fef0f0;
+ border-color: #fde2e2;
+}
+
+.stock-detail-table-wrapper {
+ overflow-x: auto;
+ border: 1px solid #ebeef5;
+ border-radius: 8px;
+ background: #fff;
+}
+
+.stock-detail-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ padding: 12px 14px;
+ background: #f8fafc;
+ border-bottom: 1px solid #edf1f5;
+}
+
+.stock-detail-toolbar__left {
+ font-size: 13px;
+ font-weight: 600;
+ color: #303133;
+}
+
+.stock-detail-count {
+ display: inline-flex;
+ align-items: center;
+ height: 24px;
+ padding: 0 10px;
+ color: #606266;
+ background: #fff;
+ border: 1px solid #e5e9ef;
+ border-radius: 999px;
+ font-size: 12px;
+}
+
+:deep(.stock-detail-el-table) {
+ border-top: none;
+}
+
+:deep(.stock-detail-el-table .el-table__inner-wrapper::before) {
+ display: none;
+}
+
+:deep(.stock-detail-el-table th.el-table__cell) {
+ background: #f5f7fa;
+ color: #303133;
+ font-weight: 600;
+}
+
+:deep(.stock-detail-el-table td.el-table__cell) {
+ color: #606266;
+}
+
+:deep(.stock-detail-el-table .el-table__body tr:hover > td.el-table__cell) {
+ background: #f0f7ff;
+}
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue b/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
index 789e395..b35bd72 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/stock/stockInfo.vue
@@ -77,6 +77,7 @@
const searchFormFields = ref({
palletCode: "",
+ warehouseId: "",
stockStatus: "",
locationCode: "",
});
@@ -84,6 +85,7 @@
const searchFormOptions = ref([
[
{ title: TEXT.palletCode, field: "palletCode", type: "like" },
+ { title: TEXT.warehouse, field: "warehouseId", type: "selectList", dataKey: "warehouseEnum", data: [] },
{ title: TEXT.stockStatus, field: "stockStatus", type: "selectList", dataKey: "stockStatusEmun", data: [] },
{ title: TEXT.locationCode, field: "locationCode", type: "like" },
],
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 da08436..191dd33 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Dashboard/DashboardController.cs
@@ -218,7 +218,7 @@
/// 鎸夊勾鏈堢粺璁″叆绔欏拰鍑虹珯浠诲姟鏁伴噺
/// </remarks>
[HttpGet("MonthlyStats"), AllowAnonymous]
- public async Task<WebResponseContent> MonthlyStats([FromQuery] int months = 12, string Roadway = null)
+ public async Task<WebResponseContent> MonthlyStats(int months, string roadway)
{
try
{
@@ -230,11 +230,12 @@
// 浠撳簱鍚嶇О鏄犲皠
var roadwayNames = new Dictionary<string, string>
{
- { "FJSC1", "璐熸瀬鍗�1鍙蜂粨搴�" },
- { "ZJSC1", "姝f瀬鍗�1鍙蜂粨搴�" },
+
{ "GWSC1", "楂樻俯1鍙蜂粨搴�" },
{ "CWSC1", "甯告俯1鍙蜂粨搴�" },
- { "HCSC1", "鍒嗗1鍙蜂粨搴�" }
+ { "HCSC1", "鍒嗗1鍙蜂粨搴�" },
+ { "FJSC1", "璐熸瀬鍗�1鍙蜂粨搴�" },
+ { "ZJSC1", "姝f瀬鍗�1鍙蜂粨搴�" },
};
// 鏋勫缓鏌ヨ
@@ -242,9 +243,9 @@
.Where(t => t.InsertTime >= startDate);
// 濡傛灉鎸囧畾浜嗛亾璺紝娣诲姞閬撹矾杩囨护鏉′欢
- if (!string.IsNullOrEmpty(Roadway))
+ if (!string.IsNullOrEmpty(roadway))
{
- query = query.Where(t => t.Roadway == Roadway);
+ query = query.Where(t => t.Roadway == roadway);
}
var monthlyStats = await query
@@ -294,9 +295,9 @@
Month = monthKey,
Inbound = stat.Inbound,
Outbound = stat.Outbound,
- Roadway = Roadway,
- RoadwayName = !string.IsNullOrEmpty(Roadway) && roadwayNames.ContainsKey(Roadway)
- ? roadwayNames[Roadway]
+ Roadway = roadway,
+ RoadwayName = !string.IsNullOrEmpty(roadway) && roadwayNames.ContainsKey(roadway)
+ ? roadwayNames[roadway]
: null
});
}
@@ -307,9 +308,9 @@
Month = monthKey,
Inbound = 0,
Outbound = 0,
- Roadway = Roadway,
- RoadwayName = !string.IsNullOrEmpty(Roadway) && roadwayNames.ContainsKey(Roadway)
- ? roadwayNames[Roadway]
+ Roadway = roadway,
+ RoadwayName = !string.IsNullOrEmpty(roadway) && roadwayNames.ContainsKey(roadway)
+ ? roadwayNames[roadway]
: null
});
}
--
Gitblit v1.9.3