From 5f1294d6dea53d286f5e7029839d37bf490e32bb Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 28 四月 2026 00:05:36 +0800
Subject: [PATCH] feat(任务管理): 新增组盘拆盘操作及任务创建功能
---
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 252 insertions(+), 0 deletions(-)
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs
index b799f1e..a550faf 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs
@@ -1,9 +1,13 @@
using System.ComponentModel;
using System.Reflection;
using Newtonsoft.Json;
+using SqlSugar;
+using WIDESEA_Common.Constants;
+using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEA_Core.Helper;
+using WIDESEA_DTO.MES;
using WIDESEA_DTO.Task;
using WIDESEA_Model.Models;
@@ -328,6 +332,254 @@
return descAttr?.Description ?? taskStatus.ToString();
}
+ /// <summary>
+ /// 缁勭洏/鎷嗙洏鎿嶄綔骞跺垱寤哄叆搴撲换鍔★紝瀹屾垚鍚庝笅鍙慦CS
+ /// </summary>
+ /// <param name="dto">缁勭洏/鎷嗙洏鎿嶄綔鍙傛暟</param>
+ /// <returns>鎿嶄綔缁撴灉</returns>
+ public async Task<WebResponseContent> PalletOperationAndCreateTaskAsync(PalletOperationTaskDto dto)
+ {
+ try
+ {
+ // 1. 鍙傛暟鏍¢獙
+ if (string.IsNullOrWhiteSpace(dto.PalletCode))
+ return WebResponseContent.Instance.Error("鎵樼洏鍙蜂笉鑳戒负绌�");
+
+ if (string.IsNullOrWhiteSpace(dto.Action)
+ || (dto.Action != "缁勭洏" && dto.Action != "鎷嗙洏"))
+ return WebResponseContent.Instance.Error("鎵ц鍔ㄤ綔蹇呴』鏄�'缁勭洏'鎴�'鎷嗙洏'");
+
+ if (string.IsNullOrWhiteSpace(dto.LineId))
+ return WebResponseContent.Instance.Error("绾夸綋缂栧彿涓嶈兘涓虹┖");
+
+ if (string.IsNullOrWhiteSpace(dto.WarehouseCode))
+ return WebResponseContent.Instance.Error("浠撳簱缂栧彿涓嶈兘涓虹┖");
+
+ if (string.IsNullOrWhiteSpace(dto.RobotName))
+ return WebResponseContent.Instance.Error("鏈烘鎵嬪悕绉颁笉鑳戒负绌�");
+
+ // 缁勭洏鏃剁數鑺垪琛ㄥ繀浼�
+ if (dto.Action == "缁勭洏" && (dto.Cells == null || !dto.Cells.Any()))
+ return WebResponseContent.Instance.Error("缁勭洏鏃剁數鑺垪琛ㄤ笉鑳戒负绌�");
+
+ // 2. 鏍规嵁浠撳簱缂栧彿鏌ヨ浠撳簱淇℃伅锛岃幏鍙� WarehouseId銆乼argetAddress 鍜� roadway
+ var warehouse = _sqlSugarClient.Queryable<Dt_Warehouse>()
+ .First(w => w.WarehouseCode == dto.WarehouseCode);
+ if (warehouse == null)
+ return WebResponseContent.Instance.Error($"鏈壘鍒颁粨搴撶紪鍙蜂负[{dto.WarehouseCode}]鐨勪粨搴�");
+
+ int warehouseId = warehouse.WarehouseId;
+ string targetAddress = warehouse.WarehouseCode;
+ string roadway = warehouse.WarehouseCode;
+
+ // 3. 鏍规嵁鍔ㄤ綔绫诲瀷鎵ц涓嶅悓娴佺▼
+ if (dto.Action == "缁勭洏")
+ return await ExecuteGroupPalletAsync(dto, warehouseId, targetAddress, roadway);
+
+ return await ExecuteSplitPalletAsync(dto, warehouseId, targetAddress, roadway);
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"缁勭洏/鎷嗙洏鎿嶄綔寮傚父: {ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 鎵ц缁勭洏鎿嶄綔锛氭坊鍔犲簱瀛� 鈫� 鐩存帴璋冪敤MES缁戝畾 鈫� 鍒涘缓鍏ュ簱浠诲姟 鈫� 涓嬪彂WCS
+ /// </summary>
+ private async Task<WebResponseContent> ExecuteGroupPalletAsync(
+ PalletOperationTaskDto dto, int warehouseId, string targetAddress, string roadway)
+ {
+ return await _unitOfWorkManage.BeginTranAsync(async () =>
+ {
+ // 1. 鍒涘缓搴撳瓨涓昏褰曪紙涓嶇粦瀹氳揣浣嶏級
+ var stockInfo = new Dt_StockInfo
+ {
+ PalletCode = dto.PalletCode,
+ PalletType = 0,
+ WarehouseId = warehouseId,
+ LocationId = 0,
+ StockStatus = 0,
+ MesUploadStatus = 0
+ };
+ var stockId = await _stockInfoService.Repository.AddDataAsync(stockInfo);
+ if (stockId <= 0)
+ return WebResponseContent.Instance.Error("鍒涘缓搴撳瓨璁板綍澶辫触");
+
+ // 2. 鎵归噺鍒涘缓搴撳瓨鏄庣粏
+ var details = dto.Cells.Select((cell, i) => new Dt_StockInfoDetail
+ {
+ StockId = (int)stockId,
+ MaterielCode = cell.SfcCode,
+ MaterielName = "",
+ OrderNo = "",
+ ProductionDate = DateTime.Now.ToString("yyyy-MM-dd"),
+ EffectiveDate = "",
+ SerialNumber = cell.SfcCode,
+ StockQuantity = 1,
+ OutboundQuantity = 0,
+ Status = 0,
+ InboundOrderRowNo = Convert.ToInt32(cell.Channel),
+ Remark = cell.Channel
+ }).ToList();
+ if (await _sqlSugarClient.Insertable(details).ExecuteCommandAsync() <= 0)
+ return WebResponseContent.Instance.Error("鍒涘缓搴撳瓨鏄庣粏澶辫触");
+
+ // 3. 璋冪敤MES缁戝畾
+ var (equipmentCode, resourceCode, token) = ResolveMesConfig(dto.RobotName);
+ var bindRequest = new BindContainerRequest
+ {
+ ContainerCode = dto.PalletCode,
+ EquipmentCode = equipmentCode,
+ ResourceCode = resourceCode,
+ LocalTime = DateTime.Now,
+ OperationType = StockConstants.MES_BIND_OPERATION_TYPE,
+ ContainerSfcList = dto.Cells.Select((cell, i) => new ContainerSfcItem
+ {
+ Sfc = cell.SfcCode,
+ Location = cell.Channel
+ }).ToList()
+ };
+ var mesResult = string.IsNullOrWhiteSpace(token)
+ ? _mesService.BindContainer(bindRequest)
+ : _mesService.BindContainer(bindRequest, token);
+ if (!CheckMesResult(mesResult, out var mesError))
+ return WebResponseContent.Instance.Error($"MES缁勭洏缁戝畾澶辫触: {mesError}");
+
+ // 4. 鍒涘缓鍏ュ簱浠诲姟骞朵笅鍙慦CS
+ return await CreateTaskAndDispatchAsync(dto, warehouseId, targetAddress, roadway,
+ TaskInboundTypeEnum.Inbound, "缁勭洏鎴愬姛骞跺垱寤哄叆搴撲换鍔�");
+ });
+ }
+
+ /// <summary>
+ /// 鎵ц鎷嗙洏鎿嶄綔锛氭煡璇㈠簱瀛� 鈫� 鐩存帴璋冪敤MES瑙g粦 鈫� 娓呴櫎搴撳瓨璐т綅 鈫� 鍒涘缓绌烘墭鐩樺叆搴撲换鍔� 鈫� 涓嬪彂WCS
+ /// </summary>
+ private async Task<WebResponseContent> ExecuteSplitPalletAsync(
+ PalletOperationTaskDto dto, int warehouseId, string targetAddress, string roadway)
+ {
+ return await _unitOfWorkManage.BeginTranAsync(async () =>
+ {
+ // 1. 瀵艰埅鏌ヨ搴撳瓨鍙婃槑缁�
+ var stockInfo = await _stockInfoService.Repository
+ .QueryDataNavFirstAsync(s => s.PalletCode == dto.PalletCode);
+ if (stockInfo == null)
+ return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩榌{dto.PalletCode}]鐨勫簱瀛樿褰�");
+
+ var sfcList = stockInfo.Details?.Select(d => d.SerialNumber).ToList()
+ ?? new List<string>();
+ if (!sfcList.Any())
+ return WebResponseContent.Instance.Error($"鎵樼洏[{dto.PalletCode}]涓嬫棤鐢佃姱鏁版嵁");
+
+ // 2. 璋冪敤MES瑙g粦
+ var (equipmentCode, resourceCode, token) = ResolveMesConfig(dto.RobotName);
+ var unbindRequest = new UnBindContainerRequest
+ {
+ EquipmentCode = equipmentCode,
+ ResourceCode = resourceCode,
+ LocalTime = DateTime.Now,
+ ContainCode = dto.PalletCode,
+ SfcList = sfcList
+ };
+ var mesResult = string.IsNullOrWhiteSpace(token)
+ ? _mesService.UnBindContainer(unbindRequest)
+ : _mesService.UnBindContainer(unbindRequest, token);
+ if (!CheckMesResult(mesResult, out var mesError))
+ return WebResponseContent.Instance.Error($"MES鎷嗙洏瑙g粦澶辫触: {mesError}");
+
+ // 3. 娓呴櫎搴撳瓨缁戝畾鐨勮揣浣�
+ stockInfo.LocationId = 0;
+ stockInfo.LocationCode = null;
+ await _sqlSugarClient.Updateable(stockInfo)
+ .UpdateColumns(s => new { s.LocationId, s.LocationCode })
+ .ExecuteCommandAsync();
+
+ // 4. 鍒涘缓绌烘墭鐩樺叆搴撲换鍔″苟涓嬪彂WCS
+ return await CreateTaskAndDispatchAsync(dto, warehouseId, targetAddress, roadway,
+ TaskInboundTypeEnum.InEmpty, "鎷嗙洏鎴愬姛骞跺垱寤虹┖鎵樼洏鍏ュ簱浠诲姟");
+ });
+ }
+
+ /// <summary>
+ /// 瑙f瀽MES璁惧閰嶇疆锛岃繑鍥� (equipmentCode, resourceCode, token)
+ /// </summary>
+ private (string equipmentCode, string resourceCode, string token) ResolveMesConfig(string deviceName)
+ {
+ var config = _mesDeviceConfigService.GetByDeviceName(deviceName);
+ return (
+ config?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE,
+ config?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE,
+ config?.Token
+ );
+ }
+
+ /// <summary>
+ /// 妫�鏌ES杩斿洖缁撴灉锛屽け璐ユ椂閫氳繃 error 杈撳嚭閿欒淇℃伅
+ /// </summary>
+ private bool CheckMesResult(HttpResponseResult<MesResponse> result, out string error)
+ {
+ if (result?.Data != null && result.Data.IsSuccess)
+ {
+ error = null;
+ return true;
+ }
+
+ error = result?.Data?.Msg ?? result?.ErrorMessage ?? "鏈煡閿欒";
+ return false;
+ }
+
+ /// <summary>
+ /// 鍒涘缓鍏ュ簱浠诲姟骞朵笅鍙慦CS
+ /// </summary>
+ private async Task<WebResponseContent> CreateTaskAndDispatchAsync(
+ PalletOperationTaskDto dto, int warehouseId, string targetAddress, string roadway,
+ TaskInboundTypeEnum taskType, string successMessage)
+ {
+ int taskNum = await BaseDal.GetTaskNo();
+ var task = new Dt_Task
+ {
+ TaskNum = taskNum,
+ PalletCode = dto.PalletCode,
+ SourceAddress = dto.LineId,
+ TargetAddress = targetAddress,
+ TaskType = taskType.GetHashCode(),
+ TaskStatus = TaskInStatusEnum.InNew.GetHashCode(),
+ Grade = dto.Grade,
+ Roadway = roadway,
+ WarehouseId = warehouseId,
+ CurrentAddress = dto.LineId,
+ NextAddress = targetAddress,
+ Creater = "manual",
+ CreateDate = DateTime.Now,
+ ModifyDate = DateTime.Now
+ };
+
+ if (await BaseDal.AddDataAsync(task) <= 0)
+ return WebResponseContent.Instance.Error("鍒涘缓浠诲姟澶辫触");
+
+ var wmsTaskDto = new WMSTaskDTO
+ {
+ TaskNum = task.TaskNum,
+ PalletCode = task.PalletCode,
+ SourceAddress = task.SourceAddress,
+ TargetAddress = task.TargetAddress,
+ TaskType = task.TaskType,
+ Roadway = task.Roadway,
+ TaskStatus = task.TaskStatus,
+ WarehouseId = task.WarehouseId
+ };
+
+ var wcsResult = _httpClientHelper.Post<WebResponseContent>(
+ "http://localhost:9292/api/Task/ReceiveManualTask",
+ new List<WMSTaskDTO> { wmsTaskDto }.ToJson());
+
+ if (!wcsResult.IsSuccess || !wcsResult.Data.Status)
+ return WebResponseContent.Instance.Error(
+ $"浠诲姟宸插垱寤轰絾鍙戦�佺粰WCS澶辫触: {wcsResult.ErrorMessage}\r\n {wcsResult.Data?.Message}");
+
+ return WebResponseContent.Instance.OK($"{successMessage}锛屼换鍔″彿: {taskNum}");
+ }
+
#endregion 鎵嬪姩浠诲姟
}
}
--
Gitblit v1.9.3