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_WMSServer/Controllers/TaskInfo/TaskController.cs           |   11 +
 Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs                             |    5 
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs       |    5 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs                           |    7 +
 Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs |    2 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs                  |  252 ++++++++++++++++++++++++++++++++++++++++++
 Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/PalletOperationTaskDto.cs                         |   70 +++++++++++
 7 files changed, 349 insertions(+), 3 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
index 38f60f8..d3555a1 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ConveyorLineDispatchHandler.cs
@@ -172,7 +172,7 @@
 
             QuartzLogHelper.LogInfo(_logger, $"RequestInNextAddress锛氬叆搴撲笅涓�鍦板潃锛屼换鍔″彿: {task.TaskNum}锛屽瓙璁惧: {childDeviceCode}", conveyorLine.DeviceCode);
 
-            bool isEmptyTask = task.TaskType == (int)TaskOutboundTypeEnum.OutEmpty;
+            bool isEmptyTask = task.TaskType == (int)TaskInboundTypeEnum.InEmpty;
 
             // 纭畾鐩爣鍦板潃
             string targetAddress;
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
index cdd7a09..944164b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
@@ -170,7 +170,10 @@
             // ===== 鍚� NextAddress 鏃犲彲鐢ㄤ换鍔★紝灏濊瘯涓嶅悓 NextAddress 鐨勪换鍔� =====
             // 鏌ユ壘鍏朵粬鍙敤鐨勫嚭搴撶珯鍙�
             // 鏌ヨ鍏朵粬绔欏彴鐨勫嚭搴撲换鍔�
-            var tasks = _taskService.QueryStackerCraneOutTasks(deviceCode, new List<string> { candidateTask.NextAddress }, false);
+            var tasks = _taskService.QueryStackerCraneOutTasks(deviceCode, new List<string> { candidateTask.NextAddress }, false)
+                .GroupBy(x => x.TargetAddress)
+                .Select(g => g.FirstOrDefault())
+                .ToList();
             foreach (var alternativeTask in tasks)
             {
                 selectedTask = TrySelectOutboundTask(alternativeTask);
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/PalletOperationTaskDto.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/PalletOperationTaskDto.cs
new file mode 100644
index 0000000..d0ca62d
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/PalletOperationTaskDto.cs
@@ -0,0 +1,70 @@
+using System.Text.Json.Serialization;
+
+namespace WIDESEA_DTO.Task
+{
+    /// <summary>
+    /// 缁勭洏/鎷嗙洏鎿嶄綔浠诲姟Dto
+    /// </summary>
+    public class PalletOperationTaskDto
+    {
+        /// <summary>
+        /// 鐢佃姱鍒楄〃锛堢粍鐩樻椂蹇呬紶锛屾媶鐩樻椂涓嶄紶锛�
+        /// </summary>
+        [JsonPropertyName("cells")]
+        public List<PalletCellItem> Cells { get; set; }
+
+        /// <summary>
+        /// 鎵樼洏鍙�
+        /// </summary>
+        [JsonPropertyName("palletCode")]
+        public string PalletCode { get; set; }
+
+        /// <summary>
+        /// 鎵ц鍔ㄤ綔锛氱粍鐩� 鎴� 鎷嗙洏
+        /// </summary>
+        [JsonPropertyName("action")]
+        public string Action { get; set; }
+
+        /// <summary>
+        /// 绾夸綋缂栧彿锛堜綔涓轰换鍔¤捣鐐瑰湴鍧� sourceAddress锛�
+        /// </summary>
+        [JsonPropertyName("lineId")]
+        public string LineId { get; set; }
+
+        /// <summary>
+        /// 鏈烘鎵嬪悕绉帮紙鐢ㄤ簬MES璁惧閰嶇疆鏌ヨ锛�
+        /// </summary>
+        [JsonPropertyName("robotName")]
+        public string RobotName { get; set; }
+
+        /// <summary>
+        /// 浠撳簱缂栧彿锛堢敤浜庢煡璇� targetAddress 鍜屽贩閬擄級
+        /// </summary>
+        [JsonPropertyName("warehouseCode")]
+        public string WarehouseCode { get; set; }
+
+        /// <summary>
+        /// 浼樺厛绾э紝榛樿1
+        /// </summary>
+        [JsonPropertyName("grade")]
+        public int Grade { get; set; } = 1;
+    }
+
+    /// <summary>
+    /// 鐢佃姱椤癸紙鐢佃姱鐮�+閫氶亾鍙蜂竴涓�瀵瑰簲锛�
+    /// </summary>
+    public class PalletCellItem
+    {
+        /// <summary>
+        /// 鐢佃姱鐮�
+        /// </summary>
+        [JsonPropertyName("sfcCode")]
+        public string SfcCode { get; set; }
+
+        /// <summary>
+        /// 閫氶亾鍙�
+        /// </summary>
+        [JsonPropertyName("channel")]
+        public string Channel { get; set; }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs
index bdf4510..614fd9c 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs
@@ -174,6 +174,13 @@
         /// <returns>鎵归噺涓嬪彂缁撴灉</returns>
         Task<WebResponseContent> DispatchTasksToWCSAsync(List<DispatchTaskDto> dtos);
 
+        /// <summary>
+        /// 缁勭洏/鎷嗙洏鎿嶄綔骞跺垱寤哄叆搴撲换鍔�
+        /// </summary>
+        /// <param name="dto">缁勭洏/鎷嗙洏鎿嶄綔鍙傛暟</param>
+        /// <returns>鎿嶄綔缁撴灉</returns>
+        Task<WebResponseContent> PalletOperationAndCreateTaskAsync(PalletOperationTaskDto dto);
+
 
         #region 鏋佸嵎搴撲换鍔℃ā鍧�
         /// <summary>
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
index 241396b..77f62a8 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -42,6 +42,7 @@
         private readonly IMESDeviceConfigService _mesDeviceConfigService;
         private readonly IMesLogService _mesLogService;
         private readonly IMesUploadHelper _mesUploadHelper;
+        private readonly ISqlSugarClient _sqlSugarClient;
 
         public IRepository<Dt_Task> Repository => BaseDal;
 
@@ -69,7 +70,8 @@
             IRecordService recordService,
             IMESDeviceConfigService mesDeviceConfigService,
             IMesLogService mesLogService,
-            IMesUploadHelper mesUploadHelper) : base(BaseDal)
+            IMesUploadHelper mesUploadHelper,
+            ISqlSugarClient sqlSugarClient) : base(BaseDal)
         {
             _mapper = mapper;
             _stockInfoService = stockInfoService;
@@ -85,6 +87,7 @@
             _mesDeviceConfigService = mesDeviceConfigService;
             _mesLogService = mesLogService;
             _mesUploadHelper = mesUploadHelper;
+            _sqlSugarClient = sqlSugarClient;
         }
 
         /// <summary>
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 鎵嬪姩浠诲姟
     }
 }
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
index ac0da61..742489e 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
@@ -69,6 +69,17 @@
         }
 
         /// <summary>
+        /// 缁勭洏/鎷嗙洏鎿嶄綔骞跺垱寤哄叆搴撲换鍔�
+        /// </summary>
+        /// <param name="dto">缁勭洏/鎷嗙洏鎿嶄綔鍙傛暟</param>
+        /// <returns>鎿嶄綔缁撴灉</returns>
+        [HttpGet, HttpPost, Route("PalletOperation"), AllowAnonymous]
+        public async Task<WebResponseContent?> PalletOperationAsync([FromBody] PalletOperationTaskDto dto)
+        {
+            return await Service.PalletOperationAndCreateTaskAsync(dto);
+        }
+
+        /// <summary>
         /// 鑾峰彇鍙叆搴撹揣浣�
         /// </summary>
         /// <param name="taskDto"></param>

--
Gitblit v1.9.3