From 461524a7a1def4532b9af4ab40733f899f360db7 Mon Sep 17 00:00:00 2001
From: heshaofeng <heshaofeng@hnkhzn.com>
Date: 星期四, 09 四月 2026 14:39:45 +0800
Subject: [PATCH] Merge branch 'htq20251215' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu into htq20251215

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs |  824 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 799 insertions(+), 25 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
index f87b6bf..d195df9 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
@@ -27,6 +27,7 @@
 using SqlSugar;
 using System.Reflection;
 using System.Reflection.Emit;
+using System.Text;
 using System.Threading.Tasks;
 using System.Xml.Linq;
 using WIDESEA_BasicService;
@@ -58,6 +59,7 @@
 using WIDESEA_IStockService;
 using WIDESEA_ITaskInfoService;
 using WIDESEA_Model.Models;
+using WIDESEA_Model.Models.Basic;
 using WIDESEA_Model.Models.Check;
 using WIDESEA_Model.Models.Outbound;
 using static HslCommunication.Profinet.Knx.KnxCode;
@@ -95,6 +97,9 @@
         private readonly HttpClientHelper _httpClientHelper;
         private readonly IBasicService _basicService;
         private readonly IRepository<Dt_TakeStockOrder> _takeStockOrder;
+        public readonly IRepository<Dt_LocationType> _locationTypeRepository;
+        public readonly IRepository<Dt_WarehouseArea> _warehouseAreaRepository;
+        private readonly IRepository<Dt_OutStockLockInfo> _outboundLockInfoRepository;
         public IRepository<Dt_Task> Repository => BaseDal;
 
         private Dictionary<string, SqlSugar.OrderByType> _taskOrderBy = new()
@@ -114,7 +119,7 @@
 
         public List<int> TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList();
 
-        public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService, IAllocateService allocateService, IRepository<Dt_OutboundBatch> outboundBatchRepository, IRepository<Dt_ReCheckOrder> reCheckOrderRepository, IRepository<Dt_AllocateOrderDetail> allocateOrderDetailRepository, IRepository<Dt_AllocateOrder> allocateOrderRepository, IMaterialUnitService materialUnitService, ITask_HtyService task_HtyService, IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfo, IRepository<Dt_AllocateMaterialInfo_Hty> allocateMaterialInfo_Hty, HttpClientHelper httpClientHelper, IBasicService basicService,IRepository<Dt_TakeStockOrder> takeStockOrder) : base(BaseDal)
+        public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService, IAllocateService allocateService, IRepository<Dt_OutboundBatch> outboundBatchRepository, IRepository<Dt_ReCheckOrder> reCheckOrderRepository, IRepository<Dt_AllocateOrderDetail> allocateOrderDetailRepository, IRepository<Dt_AllocateOrder> allocateOrderRepository, IMaterialUnitService materialUnitService, ITask_HtyService task_HtyService, IRepository<Dt_AllocateMaterialInfo> allocateMaterialInfo, IRepository<Dt_AllocateMaterialInfo_Hty> allocateMaterialInfo_Hty, HttpClientHelper httpClientHelper, IBasicService basicService,IRepository<Dt_TakeStockOrder> takeStockOrder, IRepository<Dt_LocationType> locationTypeRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_OutStockLockInfo> outboundLockInfoRepository) : base(BaseDal)
         {
             _mapper = mapper;
             _unitOfWorkManage = unitOfWorkManage;
@@ -143,6 +148,9 @@
             _httpClientHelper = httpClientHelper;
             _basicService = basicService;
             _takeStockOrder = takeStockOrder;
+            _locationTypeRepository = locationTypeRepository;
+            _warehouseAreaRepository = warehouseAreaRepository;
+            _outboundLockInfoRepository = outboundLockInfoRepository;
         }
 
         public async Task TaskStatusChange(string taskNum, TaskStatusEnum taskStatusEnum)
@@ -303,7 +311,7 @@
             stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
             stockInfo.Details.ForEach(x =>
             {
-                x.Status = StockStatusEmun.鍏ュ簱纭.ObjToInt();
+                x.Status = inboundOrders.FirstOrDefault().CreateType == (int)OrderCreateTypeEnum.CreateInSystem ? StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt():StockStatusEmun.鍏ュ簱纭.ObjToInt();
             });
             _stockService.StockInfoService.Repository.UpdateData(stockInfo);
             _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details);
@@ -383,12 +391,31 @@
                             allocatefeedmodel.Details = groupedData;
 
                             var response = responseModel(inboundOrder, 3, null, allocatefeedmodel);
-                            if (response != null && response.IsSuccess)
+                            if (response != null && response.IsSuccess && response.Data.Code =="200")
                             {
-                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 })
+                                var detailStatusList = _inboundOrderDetailService.Db.Queryable<Dt_InboundOrderDetail>()
+                                .Where(it => it.OrderId == inboundOrder.Id)
+                                .Select(it => it.OrderDetailStatus)
+                                .ToList();
+
+                                bool isAll = detailStatusList.Any()
+                                    ? detailStatusList.All(x => x == OrderDetailStatusEnum.Over.ObjToInt())
+                                    : false;
+
+                                if (isAll)
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
                                 .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
-                                _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
-                                .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
+                                else
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 3, Remark = "" })
+                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 3 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
                                 //鍥炰紶鎴愬姛搴撳瓨鎵嶅彲鐢�
                                 _stockRepository.Db.Updateable<Dt_StockInfoDetail>().SetColumns(it => new Dt_StockInfoDetail
                                 {
@@ -397,10 +424,29 @@
                             }
                             else
                             {
-                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = response.ErrorMessage })
+                                var detailStatusList = _inboundOrderDetailService.Db.Queryable<Dt_InboundOrderDetail>()
+                                .Where(it => it.OrderId == inboundOrder.Id)
+                                .Select(it => it.OrderDetailStatus)
+                                .ToList();
+
+                                bool isAll = detailStatusList.Any()
+                                    ? detailStatusList.All(x => x == OrderDetailStatusEnum.Over.ObjToInt())
+                                    : false;
+
+                                if (isAll)
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = "" })
                                 .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
-                                _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
-                               .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
+                                else
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 4, Remark = "" })
+                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 4 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
                             }
                         }
                     }
@@ -410,7 +456,7 @@
                     }
                     else
                     {
-                        if (inboundOrder != null && inboundOrder.OrderStatus == InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt())
+                        if (inboundOrder != null && inboundOrder.OrderStatus == InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt() && inboundOrder.CreateType == (int)OrderCreateTypeEnum.UpperSystemPush)
                         {
                             var feedmodel = new FeedbackInboundRequestModel
                             {
@@ -450,12 +496,32 @@
 
                             var response= responseModel(inboundOrder,2, feedmodel);
 
-                            if (response != null && response.IsSuccess)
+                            if (response != null && response.IsSuccess && response.Data.Code == "200")
                             {
-                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
+                                var detailStatusList = _inboundOrderDetailService.Db.Queryable<Dt_InboundOrderDetail>()
+                                .Where(it => it.OrderId == inboundOrder.Id)
+                                .Select(it => it.OrderDetailStatus)
+                                .ToList();
+
+                                bool isAll = detailStatusList.Any()
+                                    ? detailStatusList.All(x => x == OrderDetailStatusEnum.Over.ObjToInt())
+                                    : false;
+
+                                if (isAll)
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1, Remark = "" })
                                 .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
-                                _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
-                                .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 1 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
+                                else
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 3, Remark = "" })
+                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 3 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
+                                
                                 //鍥炰紶鎴愬姛搴撳瓨鎵嶅彲鐢�
                                 _stockRepository.Db.Updateable<Dt_StockInfoDetail>().SetColumns(it => new Dt_StockInfoDetail
                                 {
@@ -464,10 +530,29 @@
                             }
                             else
                             {
-                                _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = response.ErrorMessage })
+                                var detailStatusList = _inboundOrderDetailService.Db.Queryable<Dt_InboundOrderDetail>()
+                                .Where(it => it.OrderId == inboundOrder.Id)
+                                .Select(it => it.OrderDetailStatus)
+                                .ToList();
+
+                                bool isAll = detailStatusList.Any()
+                                    ? detailStatusList.All(x => x == OrderDetailStatusEnum.Over.ObjToInt())
+                                    : false;
+
+                                if (isAll)
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 2, Remark = "" })
                                 .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
-                                _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
-                               .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 2 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
+                                else
+                                {
+                                    _inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 4, Remark = "" })
+                                .Where(it => it.Id == inboundOrder.Id).ExecuteCommand();
+                                    _inboundOrderDetailService.Db.Updateable<Dt_InboundOrderDetail>().SetColumns(it => new Dt_InboundOrderDetail { ReturnToMESStatus = 4 })
+                                    .Where(it => it.OrderId == inboundOrder.Id).ExecuteCommand();
+                                }
                             }
                         }
                     }
@@ -480,6 +565,299 @@
             }
 
             return WebResponseContent.Instance.OK();
+        }
+
+        public async Task<WebResponseContent> RelocationTaskCompleted(Dt_Task task)
+        {
+            WebResponseContent content = new WebResponseContent();
+            try
+            {
+                if (task == null || string.IsNullOrEmpty(task.PalletCode) || string.IsNullOrEmpty(task.TargetAddress))
+                {
+                    return WebResponseContent.Instance.Error("绉诲簱浠诲姟淇℃伅涓嶅畬鏁达紙鎵樼洏鍙�/鐩爣璐т綅涓虹┖锛�");
+                }
+
+                // 2. 鏌ヨ鎵樼洏搴撳瓨淇℃伅
+                Dt_StockInfo stockInfo = await _stockRepository.Db.Queryable<Dt_StockInfo>()
+                    .Includes(x => x.Details)
+                    .Where(x => x.PalletCode == task.PalletCode)
+                    .FirstAsync();
+
+                if (stockInfo == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩榌{task.PalletCode}]瀵瑰簲鐨勭粍鐩樹俊鎭�");
+                }
+
+                // 闈炵┖鎵樼洏蹇呴』鏈夋槑缁�
+                if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt())
+                {
+                    _logger.LogInformation($"TaskService RelocationTaskCompleted: 鏈壘鍒拌鎵樼洏搴撳瓨鏄庣粏淇℃伅.{task.TaskNum}");
+                    return WebResponseContent.Instance.Error($"鏈壘鍒拌鎵樼洏[{task.PalletCode}]搴撳瓨鏄庣粏淇℃伅");
+                }
+
+                // 3. 鏌ヨ鐩爣璐т綅+鍘熻揣浣嶄俊鎭�
+                Dt_LocationInfo targetLocationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress);
+                if (targetLocationInfo == null)
+                {
+                    return content.Error($"鏈壘鍒板搴旂殑缁堢偣璐т綅[{task.TargetAddress}]淇℃伅");
+                }
+
+                // 鍘熻揣浣嶄俊鎭�
+                Dt_LocationInfo oldLocationInfo = null;
+                if (!string.IsNullOrEmpty(stockInfo.LocationCode))
+                {
+                    oldLocationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode);
+                    if (oldLocationInfo == null)
+                    {
+                        return content.Error($"鏈壘鍒板師璐т綅[{stockInfo.LocationCode}]淇℃伅");
+                    }
+                }
+
+                // 4. 璐т綅鐘舵�佹牎楠�
+                if (targetLocationInfo.LocationStatus == LocationStatusEnum.InStock.ObjToInt())
+                {
+                    return WebResponseContent.Instance.Error($"鐩爣璐т綅[{task.TargetAddress}]鐘舵�佷笉姝g‘锛堝綋鍓嶄负宸插崰鐢級");
+                }
+
+                // 5. 寮�鍚簨鍔″鐞嗘牳蹇冮�昏緫
+                _unitOfWorkManage.BeginTran();
+
+                // 5.1 璁板綍鐩爣璐т綅鍘熺姸鎬侊紝鏇存柊涓哄崰鐢�
+                var beforeTargetLocationStatus = targetLocationInfo.LocationStatus;
+                targetLocationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
+                _locationInfoService.Repository.UpdateData(targetLocationInfo);
+
+                // 5.2 閲婃斁鍘熻揣浣�
+                int beforeOldLocationStatus = 0;
+                if (oldLocationInfo != null)
+                {
+                    beforeOldLocationStatus = oldLocationInfo.LocationStatus;
+                    // 鍘熻揣浣嶆仮澶嶄负绌洪棽
+                    oldLocationInfo.LocationStatus = stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt()
+                        ? LocationStatusEnum.Pallet.ObjToInt()
+                        : LocationStatusEnum.Free.ObjToInt();
+                    _locationInfoService.Repository.UpdateData(oldLocationInfo);
+                }
+                var stockLockInfo = _outStockLockInfoService.Db.Queryable<Dt_OutboundLockInfo_Hty>().Where(x => x.PalletCode == stockInfo.PalletCode && x.TaskNum == task.TaskNum).First();
+                var allocateOrderToWarehouse = _allocateOrderRepository.Db.Queryable<Dt_AllocateOrder>().Where(x => x.OrderNo == stockLockInfo.OrderNo).First();
+                // 5.3 鏇存柊搴撳瓨鏄庣粏鐘舵�侊紙绉诲簱瀹屾垚锛�
+                stockInfo.Details.ForEach(x =>
+                {
+                    x.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+                    x.WarehouseCode = allocateOrderToWarehouse.ToWarehouse;
+                });
+                _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details);
+
+                // 5.4 鏇存柊搴撳瓨涓讳俊鎭紙缁戝畾鏂拌揣浣嶏級
+                string oldLocationCode = stockInfo.LocationCode; // 璁板綍鍘熻揣浣�
+                stockInfo.LocationCode = targetLocationInfo.LocationCode; // 缁戝畾鐩爣璐т綅
+                stockInfo.PalletCode = task.PalletCode;
+                stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt(); 
+
+                var name =_warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Code == allocateOrderToWarehouse.ToWarehouse).First();
+                var locationType =_locationTypeRepository.QueryFirst(x => x.LocationTypeDesc.Equals(name.Name));
+                if(locationType != null)
+                {
+                    stockInfo.LocationType = locationType.LocationType;
+                }
+                _stockRepository.UpdateData(stockInfo);
+
+                // 5.5 鏇存柊浠诲姟鐘舵�佷负瀹屾垚
+                task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
+                var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.鑷姩瀹屾垚);
+
+                // 鎻愪氦浜嬪姟
+                _unitOfWorkManage.CommitTran();
+
+                // 浠诲姟褰掓。澶辫触鍒欑洿鎺ュ垹闄�
+                if (!result)
+                {
+                    await Db.Deleteable(task).ExecuteCommandAsync();
+                }
+
+                // 6. 澶勭悊鍑哄簱鍗�+璋冩嫧鐗╂枡淇℃伅
+                Dt_OutboundOrder outboundOrder = null;
+                //var firstDetail = stockInfo.Details.FirstOrDefault();
+                if (stockLockInfo != null && !string.IsNullOrEmpty(stockLockInfo.OrderNo))
+                {
+                    outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+                        .Where(x => x.OrderNo == stockLockInfo.OrderNo)
+                        .Includes(x => x.Details)
+                        .First();
+                    string Operator = outboundOrder.Modifier;
+                    if (outboundOrder != null)
+                    {
+                        var allocatInfo =_allocateMaterialInfo.Db.Queryable<Dt_AllocateMaterialInfo>().Where(x => x.OrderNo == outboundOrder.OrderNo).ToList();
+                        // 鍒犻櫎璋冩嫧鐗╂枡淇℃伅
+                        foreach (var item in allocatInfo)
+                        {
+                            var inbounddetail = _allocateMaterialInfo.QueryFirst(x => x.OrderNo == item.OrderNo && x.Barcode == item.Barcode);
+                            if (inbounddetail != null)
+                            {
+                                var alldelete = _allocateMaterialInfo.DeleteAndMoveIntoHty(inbounddetail, OperateTypeEnum.鑷姩鍒犻櫎);
+                                if (!alldelete)
+                                {
+                                    await Db.Deleteable(task).ExecuteCommandAsync();
+                                }
+                            }
+                        }
+
+                        if (outboundOrder.Details.All(x => x.OrderDetailStatus == (int)OrderDetailStatusEnum.Over) && !allocatInfo.Any())
+                        {
+                            outboundOrder.OrderStatus = (int)InOrderStatusEnum.鍏ュ簱瀹屾垚;
+                            _outboundOrderService.UpdateData(outboundOrder);
+                        }
+
+                        // 7. 鍥炶皟MES
+                        
+                        HttpResponseResult<MesResponseDTO> httpResponseResult = new HttpResponseResult<MesResponseDTO>();
+                        string reqCode = Guid.NewGuid().ToString();
+                        string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+                        string requestData = string.Empty;
+                        List<string> lineNos = new List<string>();
+
+                        Dt_AllocateMaterialInfo allocateMaterialInfo = _allocateMaterialInfo.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo);
+                        // 绉诲簱鍦烘櫙锛氬嚭搴撳畬鎴愪笖鏈洖浼燤ES銆佹棤璋冩嫧鐗╂枡淇℃伅鏃跺洖璋�
+                        if (outboundOrder.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt() && outboundOrder.ReturnToMESStatus == 0 && allocateMaterialInfo == null)
+                        {
+                            Dt_AllocateOrder allocateOrder = _allocateOrderRepository.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo);
+                            if (allocateOrder == null)
+                            {
+                                return WebResponseContent.Instance.Error($"鏈壘鍒板搴旂殑璋冩嫧鍗昜{outboundOrder.OrderNo}]");
+                            }
+
+                            // 鏋勫缓绉诲簱鍥炶皟鏁版嵁
+                            AllocationReturnDTO? returnDTO = BuildAllocationFeedbackData(
+                                outboundOrder,
+                                allocateOrder.FromWarehouse, 
+                                allocateOrder.ToWarehouse,
+                                Operator);
+
+                            if (returnDTO == null)
+                            {
+                                return WebResponseContent.Instance.Error($"鏋勫缓绉诲簱鍥炶皟瀵硅薄澶辫触");
+                            }
+
+                            string apiUrl = AppSettings.GetValue("AllocationFeedbackUrl");
+                            returnDTO.ReqCode = reqCode;
+                            returnDTO.ReqTime = reqTime;
+                            JsonSerializerSettings settings = new JsonSerializerSettings
+                            {
+                                ContractResolver = new CamelCasePropertyNamesContractResolver()
+                            };
+                            requestData = JsonConvert.SerializeObject(returnDTO, settings);
+                            lineNos = returnDTO.Details.Select(x => x.LineNo).ToList();
+                            httpResponseResult = _httpClientHelper.Post<MesResponseDTO>(apiUrl, requestData);
+                            httpResponseResult.ApiUrl = apiUrl;
+                        }
+
+                        // 8. 澶勭悊MES鍥炶皟缁撴灉
+                        bool isSuccess = httpResponseResult.IsSuccess && httpResponseResult.Data?.Code == "200";
+                        string message = "鎴愬姛";
+                        if (!isSuccess)
+                        {
+                            if (!httpResponseResult.IsSuccess)
+                            {
+                                message = $"MES鎺ュ彛杩斿洖閿欒锛孒TTP浠g爜锛歿httpResponseResult.StatusCode}锛屼俊鎭細{httpResponseResult.ErrorMessage}";
+                            }
+                            else if (httpResponseResult?.Data?.Code != "200")
+                            {
+                                message = $"璋冪敤MES鎺ュ彛澶辫触锛屼唬鐮侊細{httpResponseResult?.Data?.Code}锛屼俊鎭細{httpResponseResult?.Data?.Message}";
+                            }
+                        }
+
+                        // 9. 璁板綍MES鍥炰紶璁板綍
+                        Dt_MesReturnRecord mesReturnRecord = new Dt_MesReturnRecord()
+                        {
+                            ApiUrl = httpResponseResult.ApiUrl,
+                            InterfaceType = outboundOrder.OrderType == 0 ? 1 : 3, // 绉诲簱鎺ュ彛绫诲瀷锛氬鐢ㄨ皟鎷ㄧ被鍨�3
+                            OrderId = outboundOrder.Id,
+                            OrderNo = outboundOrder.OrderNo,
+                            RequestCode = reqCode,
+                            RequestData = requestData,
+                            FailureReason = message,
+                            LastReturnTime = DateTime.Now,
+                            HttpStatusCode = httpResponseResult.StatusCode.ObjToInt(),
+                            ResponseData = httpResponseResult.Content,
+                            ReturnType = 0,
+                            ReturnCount = 1,
+                            ReturnStatus = isSuccess ? 1 : 2,
+                            SuccessTime = isSuccess ? DateTime.Now : null
+                        };
+
+                        // 寮�鍚簨鍔′繚瀛楳ES璁板綍+鏇存柊鍑哄簱鍗曠姸鎬�
+                        _unitOfWorkManage.BeginTran();
+                        _unitOfWorkManage.Db.Insertable(mesReturnRecord).ExecuteCommand();
+
+                        List<Dt_OutboundOrderDetail> outboundOrderDetails = outboundOrder.Details.Where(x => lineNos.Contains(x.lineNo)).ToList();
+                        outboundOrderDetails.ForEach(x =>
+                        {
+                            if (x.OverOutQuantity == x.OrderQuantity - x.MoveQty)
+                            {
+                                x.ReturnToMESStatus = isSuccess ? 1 : 2;
+                            }
+                            else
+                            {
+                                x.ReturnToMESStatus = isSuccess ? 3 : 4;
+                            }
+                            x.CurrentDeliveryQty = 0;
+                            x.ReturnJsonData = "";
+                        });
+
+                        mesReturnRecord.ReturnType = outboundOrder.Details.Count == outboundOrderDetails.Count ? 1 : 2;
+
+                        if (outboundOrder.Details.Count == outboundOrderDetails.Count && outboundOrderDetails.All(x => x.ReturnToMESStatus == 1 || x.ReturnToMESStatus == 2))
+                        {
+                            outboundOrder.ReturnToMESStatus = isSuccess ? 1 : 2;
+                        }
+                        else
+                        {
+                            outboundOrder.ReturnToMESStatus = isSuccess ? 3 : 4;
+                        }
+
+                        _outboundOrderService.Db.Updateable(outboundOrderDetails).ExecuteCommand();
+                        _outboundOrderService.UpdateData(outboundOrder);
+
+                        _unitOfWorkManage.CommitTran();
+                    }
+                }
+
+                // 10. 璁板綍璐т綅鐘舵�佸彉鏇达紙鐩爣璐т綅+鍘熻揣浣嶏級
+                try
+                {
+                    // 璁板綍鐩爣璐т綅鐘舵�佸彉鏇�
+                    _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
+                        targetLocationInfo,
+                        beforeTargetLocationStatus,
+                        StockChangeType.Inbound.ObjToInt(), 
+                        $"绉诲簱鍏ュ簱锛堝師璐т綅锛歿oldLocationCode}锛�",
+                        task.TaskNum);
+
+                    // 璁板綍鍘熻揣浣嶇姸鎬佸彉鏇达紙鑻ユ湁锛�
+                    if (oldLocationInfo != null)
+                    {
+                        _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
+                            oldLocationInfo,
+                            beforeOldLocationStatus,
+                            StockChangeType.Outbound.ObjToInt(),
+                            $"绉诲簱鍑哄簱锛堢洰鏍囪揣浣嶏細{targetLocationInfo.LocationCode}锛�",
+                            task.TaskNum);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    _logger.LogInformation($"RelocationTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
+                }
+
+                return content;
+            }
+            catch (Exception ex)
+            {
+                // 浜嬪姟鍥炴粴
+                _unitOfWorkManage.RollbackTran();
+                _logger.LogError($"RelocationTaskCompleted 澶勭悊澶辫触锛歿ex.Message}", ex);
+                return await Task.FromResult(WebResponseContent.Instance.Error($"绉诲簱浠诲姟澶勭悊澶辫触锛歿ex.Message}"));
+            }
         }
 
         public HttpResponseResult<MesResponseDTO> responseModel(Dt_InboundOrder order, int InterfaceType, FeedbackInboundRequestModel model = null, AllocateDto allocateDto = null)
@@ -529,7 +907,7 @@
                 ResponseData = httpResponseResult.Content,
                 ReturnType = 0,
                 ReturnCount = 1,
-                ReturnStatus = httpResponseResult.IsSuccess ? 1 : 2,
+                ReturnStatus = isSuccess ? 1 : 2,
                 SuccessTime = httpResponseResult.IsSuccess ? DateTime.Now : null
             };
             _unitOfWorkManage.Db.Insertable(mesReturnRecord).ExecuteCommand();
@@ -725,7 +1103,8 @@
                 }
                 Dt_OutboundOrder outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().Where(x => x.OrderNo == stockInfo.Details.FirstOrDefault().OrderNo).Includes(x=>x.Details).First();
 
-                if(outboundOrder != null)
+                string Operator = outboundOrder.Modifier;
+                if (outboundOrder != null)
                 {
                     foreach (var item in stockInfo.Details.Where(x => x.OrderNo == outboundOrder.OrderNo).ToList())
                     {
@@ -739,17 +1118,23 @@
                             }
                         }
                     }
+                    var allocateMaterialInfos = _allocateMaterialInfo.QueryData(x => x.OrderNo == outboundOrder.OrderNo);
+                    if (outboundOrder.Details.All(x => x.OrderDetailStatus == (int)OrderDetailStatusEnum.Over) && !allocateMaterialInfos.Any())
+                    {
+                        outboundOrder.OrderStatus = (int)InOrderStatusEnum.鍏ュ簱瀹屾垚;
+                        _outboundOrderService.UpdateData(outboundOrder);
+                    }
                 }
-                string Operator = outboundOrder.Modifier;
+               
                 ///鍥炶皟MES
                 HttpResponseResult<MesResponseDTO> httpResponseResult = new HttpResponseResult<MesResponseDTO>();
                 string reqCode = Guid.NewGuid().ToString();
                 string reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                 string requestData = string.Empty;
                 List<string> lineNos = new List<string>();
-                if (outboundOrder.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt())
+                Dt_AllocateMaterialInfo allocateMaterialInfo = _allocateMaterialInfo.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo);
+                if (outboundOrder.OrderStatus == OutOrderStatusEnum.鍑哄簱瀹屾垚.ObjToInt() && outboundOrder.ReturnToMESStatus == 0 && allocateMaterialInfo == null)
                 {
-                    
                     Dt_AllocateOrder allocateOrder = _allocateOrderRepository.QueryFirst(x => x.OrderNo == outboundOrder.OrderNo);
                     if (allocateOrder == null)
                     {
@@ -760,7 +1145,7 @@
                     {
                         return WebResponseContent.Instance.Error($"鏋勫缓鍥炶皟瀵硅薄澶辫触");
                     }
-                    string apiUrl = AppSettings.GetValue("AllocationFeedbackUrl"); ;
+                    string apiUrl = AppSettings.GetValue("AllocationFeedbackUrl");
                     returnDTO.ReqCode = reqCode;
                     returnDTO.ReqTime = reqTime;
                     JsonSerializerSettings settings = new JsonSerializerSettings
@@ -1849,7 +2234,7 @@
         /// <summary>
         /// 鐩樼偣鍑哄簱瀹屾垚
         /// </summary>
-        public WebResponseContent OutInventoryTaskCompleted(Dt_Task task)
+        public async Task<WebResponseContent> OutInventoryTaskCompleted(Dt_Task task)
         {
             WebResponseContent content = new WebResponseContent();
             try
@@ -1900,7 +2285,7 @@
             catch (Exception ex)
             {
                 _unitOfWorkManage.RollbackTran();
-                content.Error(ex.Message);
+                return await Task.FromResult(WebResponseContent.Instance.Error(ex.Message));
             }
             return content;
         }
@@ -2069,6 +2454,395 @@
                 return await Task.FromResult(WebResponseContent.Instance.Error(ex.Message));
             }
         }
+
+        /// <summary>
+        /// 浠诲姟鍙栨秷
+        /// </summary>
+        /// <param name="taskCodes"></param>
+        /// <returns></returns>
+        /// <summary>
+        public async Task<WebResponseContent> TaskCancel(List<int> taskCodes)
+        {
+            try
+            {
+                if (taskCodes == null || !taskCodes.Any())
+                {
+                    return WebResponseContent.Instance.Error("鍙栨秷鐨勪换鍔″彿涓嶈兘涓虹┖");
+                }
+
+                //var taskCancelUrl = AppSettings.GetValue("TaskCancelUrl");
+                //TaskCancelRequest taskc = new TaskCancelRequest();
+                //taskc.TaskCodes = taskCodes.Select(x => x.ToString()).ToList();
+
+                //string json = JsonConvert.SerializeObject(taskc);
+
+                //using var clientHttp = new HttpClient();
+                //var content = new StringContent(json, Encoding.UTF8, "application/json");
+
+                //HttpResponseMessage response = await clientHttp.PostAsync(taskCancelUrl,content);
+
+                //string responseJson = await response.Content.ReadAsStringAsync();
+                //TaskCancelApiResponse apiResponse = JsonConvert.DeserializeObject<TaskCancelApiResponse>(responseJson);
+
+                //if (apiResponse.Code != 0)
+                //{
+                //    return WebResponseContent.Instance.Error($"璇锋眰澶辫触锛歿apiResponse.Msg}");
+                //}
+                _unitOfWorkManage.BeginTran();
+
+                var tasks = await Db.Queryable<Dt_Task>()
+                                    .Where(x => taskCodes.Contains(x.TaskNum))
+                                    .ToListAsync();
+
+                if (!tasks.Any())
+                {
+                    _unitOfWorkManage.RollbackTran();
+                    return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
+                }
+
+                int inPickType = TaskTypeEnum.InPick.ObjToInt();
+                var inboundTypes = new List<int>
+        {
+            TaskTypeEnum.InAllocate.ObjToInt(),
+            TaskTypeEnum.InEmpty.ObjToInt(),
+            TaskTypeEnum.Inbound.ObjToInt(),
+            TaskTypeEnum.InInventory.ObjToInt(),
+            TaskTypeEnum.InQuality.ObjToInt()
+        };
+                var outboundTypes = new List<int>
+        {
+            TaskTypeEnum.Outbound.ObjToInt(),
+            TaskTypeEnum.OutAllocate.ObjToInt()
+        };
+
+                foreach (var task in tasks)
+                {
+                    if (task.TaskStatus == TaskStatusEnum.Cancel.ObjToInt())
+                        continue;
+
+                    var stock = await _stockRepository.QueryFirstAsync(x => x.PalletCode == task.PalletCode);
+                    if (stock == null)
+                        throw new Exception($"鎵樼洏 {task.PalletCode} 鏈壘鍒板簱瀛樹俊鎭�");
+
+                    if (task.TaskType == inPickType)
+                    {
+                        stock.StockStatus = StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt();
+                    }
+                    else if (inboundTypes.Contains(task.TaskType))
+                    {
+                        stock.StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.ObjToInt();
+                    }
+                    else if (outboundTypes.Contains(task.TaskType))
+                    {
+                        stock.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+
+                        var outStockLock = await _outStockLockInfoService.Db
+                            .Queryable<Dt_OutStockLockInfo>()
+                            .Where(x => x.PalletCode == task.PalletCode)
+                            .FirstAsync();
+
+                        if (outStockLock == null)
+                            throw new Exception($"鎵樼洏 {task.PalletCode} 鏈壘鍒板嚭搴撻攣瀹氫俊鎭�");
+
+                        int detailId = outStockLock.OrderDetailIds.ObjToInt();
+                        var outboundDetail = await _outboundOrderDetailService.Db
+                            .Queryable<Dt_OutboundOrderDetail>()
+                            .Where(x => x.Id == detailId)
+                            .FirstAsync();
+
+                        if (outboundDetail == null)
+                            throw new Exception($"鍑哄簱鏄庣粏ID {detailId} 涓嶅瓨鍦�");
+
+                        if (outboundDetail.LockQuantity < outStockLock.AssignQuantity)
+                            throw new Exception($"鍑哄簱鏄庣粏 {detailId} 閿佸畾鏁伴噺涓嶈冻");
+
+                        outboundDetail.LockQuantity -= outStockLock.AssignQuantity;
+                         _outboundOrderDetailService.UpdateData(outboundDetail);
+
+                         _outboundLockInfoRepository.DeleteAndMoveIntoHty(outStockLock, OperateTypeEnum.浜哄伐鍒犻櫎);
+                    }
+
+                    await _stockRepository.UpdateDataAsync(stock);
+
+                    task.TaskStatus = TaskStatusEnum.Cancel.ObjToInt();
+                    bool archiveSuccess = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.浜哄伐鍒犻櫎);
+
+                    if (!archiveSuccess)
+                    {
+                        await Db.Deleteable(task).ExecuteCommandAsync();
+                    }
+                }
+
+                _unitOfWorkManage.CommitTran();
+                return WebResponseContent.Instance.OK("浠诲姟鍙栨秷鎴愬姛");
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                _logger.LogError(ex, "浠诲姟鍙栨秷寮傚父");
+                return WebResponseContent.Instance.Error($"浠诲姟鍙栨秷澶辫触锛歿ex.Message}");
+            }
+        }
+
+        public async Task<WebResponseContent> AreaRelocationTaskCompleted(Dt_Task task)
+        {
+            WebResponseContent content = new WebResponseContent();
+            try
+            {
+                if (task == null || string.IsNullOrEmpty(task.PalletCode) || string.IsNullOrEmpty(task.TargetAddress))
+                {
+                    return WebResponseContent.Instance.Error("绉诲簱浠诲姟淇℃伅涓嶅畬鏁达紙鎵樼洏鍙�/鐩爣璐т綅涓虹┖锛�");
+                }
+
+                // 2. 鏌ヨ鎵樼洏搴撳瓨淇℃伅
+                Dt_StockInfo stockInfo = await _stockRepository.Db.Queryable<Dt_StockInfo>()
+                    .Includes(x => x.Details)
+                    .Where(x => x.PalletCode == task.PalletCode)
+                    .FirstAsync();
+
+                if (stockInfo == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩榌{task.PalletCode}]瀵瑰簲鐨勭粍鐩樹俊鎭�");
+                }
+
+                // 闈炵┖鎵樼洏蹇呴』鏈夋槑缁�
+                if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt())
+                {
+                    _logger.LogInformation($"TaskService RelocationTaskCompleted: 鏈壘鍒拌鎵樼洏搴撳瓨鏄庣粏淇℃伅.{task.TaskNum}");
+                    return WebResponseContent.Instance.Error($"鏈壘鍒拌鎵樼洏[{task.PalletCode}]搴撳瓨鏄庣粏淇℃伅");
+                }
+
+                // 3. 鏌ヨ鐩爣璐т綅+鍘熻揣浣嶄俊鎭�
+                Dt_LocationInfo targetLocationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress);
+                if (targetLocationInfo == null)
+                {
+                    return content.Error($"鏈壘鍒板搴旂殑缁堢偣璐т綅[{task.TargetAddress}]淇℃伅");
+                }
+
+                // 鍘熻揣浣嶄俊鎭�
+                Dt_LocationInfo oldLocationInfo = null;
+                if (!string.IsNullOrEmpty(stockInfo.LocationCode))
+                {
+                    oldLocationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode);
+                    if (oldLocationInfo == null)
+                    {
+                        return content.Error($"鏈壘鍒板師璐т綅[{stockInfo.LocationCode}]淇℃伅");
+                    }
+                }
+
+                // 4. 璐т綅鐘舵�佹牎楠�
+                if (targetLocationInfo.LocationStatus == LocationStatusEnum.InStock.ObjToInt())
+                {
+                    return WebResponseContent.Instance.Error($"鐩爣璐т綅[{task.TargetAddress}]鐘舵�佷笉姝g‘锛堝綋鍓嶄负宸插崰鐢級");
+                }
+
+                // 5. 寮�鍚簨鍔″鐞嗘牳蹇冮�昏緫
+                _unitOfWorkManage.BeginTran();
+
+                // 5.1 璁板綍鐩爣璐т綅鍘熺姸鎬侊紝鏇存柊涓哄崰鐢�
+                var beforeTargetLocationStatus = targetLocationInfo.LocationStatus;
+                targetLocationInfo.LocationStatus = stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt()
+                        ? LocationStatusEnum.Pallet.ObjToInt()
+                        : LocationStatusEnum.InStock.ObjToInt();
+                _locationInfoService.Repository.UpdateData(targetLocationInfo);
+
+                // 5.2 閲婃斁鍘熻揣浣�
+                int beforeOldLocationStatus = 0;
+                if (oldLocationInfo != null)
+                {
+                    beforeOldLocationStatus = oldLocationInfo.LocationStatus;
+                    // 鍘熻揣浣嶆仮澶嶄负绌洪棽
+                    oldLocationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt();
+                    _locationInfoService.Repository.UpdateData(oldLocationInfo);
+                }
+                // 5.4 鏇存柊搴撳瓨涓讳俊鎭紙缁戝畾鏂拌揣浣嶏級
+                string oldLocationCode = stockInfo.LocationCode; // 璁板綍鍘熻揣浣�
+                stockInfo.LocationCode = targetLocationInfo.LocationCode; // 缁戝畾鐩爣璐т綅
+                stockInfo.PalletCode = task.PalletCode;
+                stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+
+                _stockRepository.UpdateData(stockInfo);
+
+                // 5.5 鏇存柊浠诲姟鐘舵�佷负瀹屾垚
+                task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
+                var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.鑷姩瀹屾垚);
+
+                // 鎻愪氦浜嬪姟
+                _unitOfWorkManage.CommitTran();
+
+                // 浠诲姟褰掓。澶辫触鍒欑洿鎺ュ垹闄�
+                if (!result)
+                {
+                    await Db.Deleteable(task).ExecuteCommandAsync();
+                }
+                try
+                {
+                    // 璁板綍鐩爣璐т綅鐘舵�佸彉鏇�
+                    _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
+                        targetLocationInfo,
+                        beforeTargetLocationStatus,
+                        StockChangeType.Inbound.ObjToInt(),
+                        $"绉诲簱鍏ュ簱锛堝師璐т綅锛歿oldLocationCode}锛�",
+                        task.TaskNum);
+
+                    // 璁板綍鍘熻揣浣嶇姸鎬佸彉鏇达紙鑻ユ湁锛�
+                    if (oldLocationInfo != null)
+                    {
+                        _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
+                            oldLocationInfo,
+                            beforeOldLocationStatus,
+                            StockChangeType.Outbound.ObjToInt(),
+                            $"绉诲簱鍑哄簱锛堢洰鏍囪揣浣嶏細{targetLocationInfo.LocationCode}锛�",
+                            task.TaskNum);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    _logger.LogInformation($"RelocationTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
+                }
+
+                return content.OK();
+            }
+            catch (Exception ex)
+            {
+                // 浜嬪姟鍥炴粴
+                _unitOfWorkManage.RollbackTran();
+                _logger.LogError($"RelocationTaskCompleted 澶勭悊澶辫触锛歿ex.Message}", ex);
+                return await Task.FromResult(WebResponseContent.Instance.Error($"绉诲簱浠诲姟澶勭悊澶辫触锛歿ex.Message}"));
+            }
+        }
+
+
+        /// <summary>
+        /// 璺ㄥ尯鍩熺Щ搴撲换鍔″畬鎴�
+        /// </summary>
+        /// <param name="task"></param>
+        /// <returns></returns>
+        public async Task<WebResponseContent> CrossAreaRelocationTaskCompleted(Dt_Task task)
+        {
+            WebResponseContent content = new WebResponseContent();
+            try
+            {
+                if (task == null || string.IsNullOrEmpty(task.PalletCode) || string.IsNullOrEmpty(task.TargetAddress))
+                {
+                    return WebResponseContent.Instance.Error("璺ㄥ尯鍩熺Щ搴撲换鍔′俊鎭笉瀹屾暣锛堟墭鐩樺彿/鐩爣璐т綅涓虹┖锛�");
+                }
+
+                // 2. 鏌ヨ鎵樼洏搴撳瓨淇℃伅
+                Dt_StockInfo stockInfo = await _stockRepository.Db.Queryable<Dt_StockInfo>()
+                    .Includes(x => x.Details)
+                    .Where(x => x.PalletCode == task.PalletCode)
+                    .FirstAsync();
+
+                if (stockInfo == null)
+                {
+                    return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩榌{task.PalletCode}]瀵瑰簲鐨勫簱瀛樹俊鎭�");
+                }
+
+                // 闈炵┖鎵樼洏蹇呴』鏈夋槑缁�
+                if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt())
+                {
+                    _logger.LogInformation($"CrossAreaRelocationTaskCompleted: 鏈壘鍒拌鎵樼洏搴撳瓨鏄庣粏淇℃伅.{task.TaskNum}");
+                    return WebResponseContent.Instance.Error($"鏈壘鍒拌鎵樼洏[{task.PalletCode}]搴撳瓨鏄庣粏淇℃伅");
+                }
+
+                // 3. 鏌ヨ鐩爣璐т綅 + 鍘熻揣浣嶄俊鎭�
+                Dt_LocationInfo targetLocationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress);
+                if (targetLocationInfo == null)
+                {
+                    return content.Error($"鏈壘鍒板搴旂殑缁堢偣璐т綅[{task.TargetAddress}]淇℃伅");
+                }
+
+                // 鍘熻揣浣嶄俊鎭�
+                Dt_LocationInfo oldLocationInfo = null;
+                if (!string.IsNullOrEmpty(stockInfo.LocationCode))
+                {
+                    oldLocationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == stockInfo.LocationCode);
+                    if (oldLocationInfo == null)
+                    {
+                        return content.Error($"鏈壘鍒板師璐т綅[{stockInfo.LocationCode}]淇℃伅");
+                    }
+                }
+
+                // 4. 璐т綅鐘舵�佹牎楠�
+                if (targetLocationInfo.LocationStatus == LocationStatusEnum.InStock.ObjToInt())
+                {
+                    return WebResponseContent.Instance.Error($"鐩爣璐т綅[{task.TargetAddress}]鐘舵�佷笉姝g‘锛堝綋鍓嶄负宸插崰鐢級");
+                }
+
+                // 5. 寮�鍚簨鍔″鐞嗘牳蹇冮�昏緫
+                _unitOfWorkManage.BeginTran();
+
+                // 5.1 鐩爣璐т綅鏇存柊涓哄崰鐢�
+                var beforeTargetLocationStatus = targetLocationInfo.LocationStatus;
+                targetLocationInfo.LocationStatus = stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt()
+                        ? LocationStatusEnum.Pallet.ObjToInt()
+                        : LocationStatusEnum.InStock.ObjToInt();
+                _locationInfoService.Repository.UpdateData(targetLocationInfo);
+
+                // 5.2 鍘熻揣浣嶉噴鏀剧┖闂�
+                int beforeOldLocationStatus = 0;
+                if (oldLocationInfo != null)
+                {
+                    beforeOldLocationStatus = oldLocationInfo.LocationStatus;
+                    oldLocationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt();
+                    _locationInfoService.Repository.UpdateData(oldLocationInfo);
+                }
+
+                // 5.3 鏇存柊搴撳瓨锛氱粦瀹氭柊璐т綅 + 鎭㈠姝e父鐘舵��
+                string oldLocationCode = stockInfo.LocationCode;
+                stockInfo.LocationCode = targetLocationInfo.LocationCode;
+                stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+                stockInfo.LocationType = targetLocationInfo.LocationType;
+                _stockRepository.UpdateData(stockInfo);
+
+                // 5.4 浠诲姟鏍囪涓哄畬鎴�
+                task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
+                var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.鑷姩瀹屾垚);
+
+                // 鎻愪氦浜嬪姟
+                _unitOfWorkManage.CommitTran();
+
+                // 浠诲姟褰掓。澶辫触鍒欏垹闄�
+                if (!result)
+                {
+                    await Db.Deleteable(task).ExecuteCommandAsync();
+                }
+
+                // 璁板綍璐т綅鐘舵�佸彉鏇存棩蹇�
+                try
+                {
+                    _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
+                        targetLocationInfo,
+                        beforeTargetLocationStatus,
+                        StockChangeType.Inbound.ObjToInt(),
+                        $"璺ㄥ尯鍩熺Щ搴撳叆搴擄紙鍘熻揣浣嶏細{oldLocationCode}锛�",
+                        task.TaskNum);
+
+                    if (oldLocationInfo != null)
+                    {
+                        _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
+                            oldLocationInfo,
+                            beforeOldLocationStatus,
+                            StockChangeType.Outbound.ObjToInt(),
+                            $"璺ㄥ尯鍩熺Щ搴撳嚭搴擄紙鐩爣璐т綅锛歿targetLocationInfo.LocationCode}锛�",
+                            task.TaskNum);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    _logger.LogInformation($"CrossAreaRelocationTaskCompleted 璁板綍鏃ュ織寮傚父锛歿ex.Message}");
+                }
+
+                return content.OK("璺ㄥ尯鍩熺Щ搴撲换鍔″畬鎴�");
+            }
+            catch (Exception ex)
+            {
+                _unitOfWorkManage.RollbackTran();
+                _logger.LogError($"CrossAreaRelocationTaskCompleted 澶勭悊澶辫触锛歿ex.Message}", ex);
+                return await Task.FromResult(WebResponseContent.Instance.Error($"璺ㄥ尯鍩熺Щ搴撲换鍔″鐞嗗け璐ワ細{ex.Message}"));
+            }
+        }
     }
 }
 

--
Gitblit v1.9.3