From 2d3ee03961d6cfbde70342e8a97bc7b05d0b0dc3 Mon Sep 17 00:00:00 2001
From: kazelee <1847801760@qq.com>
Date: 星期一, 21 七月 2025 17:27:34 +0800
Subject: [PATCH] 优化代码, 封装货位锁和创建任务流程, 数据库事务等

---
 device/S7Helper.cs             |    2 
 models/TN_Location.cs          |   51 ---
 Program.cs                     |    7 
 core/Monitor.cs                |  281 +++++++++------------
 device/ProductionLineDevice.cs |    2 
 models/TN_Container.cs         |    8 
 wms/WMSHelper.cs               |    8 
 api/ApiModel.cs                |    2 
 HH.WCS.Mobox3.DSZSH.csproj     |    1 
 wms/WCSHelper.cs               |  106 ++++++--
 device/TcpClient.cs            |    2 
 device/TcpServer.cs            |    2 
 device/OpcUaHelper.cs          |    1 
 dispatch/NDC.cs                |    4 
 api/AgvController.cs           |    1 
 models/BaseModel.cs            |   29 --
 wms/DbTranHelper.cs            |   97 +++++++
 wms/SYSHelper.cs               |    3 
 device/TcpClientHelper.cs      |    2 
 models/TN_Loc_Container.cs     |   13 
 device/ModbusHelper.cs         |    2 
 wms/LocationHelper.cs          |    2 
 api/ErpController.cs           |    1 
 util/LogHelper.cs              |    2 
 models/TN_Task.cs              |    4 
 core/WCSCore.cs                |   75 +----
 device/ModbusFactory.cs        |    1 
 api/DebugController.cs         |    1 
 util/Settings.cs               |    2 
 api/ApiHelper.cs               |   39 --
 api/WMSController.cs           |    4 
 api/MoboxController.cs         |    1 
 32 files changed, 395 insertions(+), 361 deletions(-)

diff --git a/HH.WCS.Mobox3.DSZSH.csproj b/HH.WCS.Mobox3.DSZSH.csproj
index 393f918..e2be509 100644
--- a/HH.WCS.Mobox3.DSZSH.csproj
+++ b/HH.WCS.Mobox3.DSZSH.csproj
@@ -271,6 +271,7 @@
     <Compile Include="dispatch\HostToAGV.cs" />
     <Compile Include="util\LogHelper.cs" />
     <Compile Include="util\WebHelper.cs" />
+    <Compile Include="wms\DbTranHelper.cs" />
     <Compile Include="wms\LocationHelper.cs" />
     <Compile Include="wms\SYSHelper.cs" />
     <Compile Include="Program.cs" />
diff --git a/Program.cs b/Program.cs
index 29085fa..eb8520e 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,16 +1,17 @@
 锘縰sing System;
 using System.Collections.Generic;
 using System.Threading;
-using HH.WCS.Mobox3.DSZSH.device;
+
 using HH.WCS.Mobox3.DSZSH.core;
+using HH.WCS.Mobox3.DSZSH.device;
+using HH.WCS.Mobox3.DSZSH.util;
 
 using Microsoft.Owin.Hosting;
 
 using Topshelf;
 
-using Task = System.Threading.Tasks.Task;
 using Monitor = HH.WCS.Mobox3.DSZSH.core.Monitor;
-using System.Net.Sockets;
+using Task = System.Threading.Tasks.Task;
 
 namespace HH.WCS.Mobox3.DSZSH {
     internal class Program
diff --git a/api/AgvController.cs b/api/AgvController.cs
index 744500e..e6b2891 100644
--- a/api/AgvController.cs
+++ b/api/AgvController.cs
@@ -8,6 +8,7 @@
 using System.Web.Http;
 
 using HH.WCS.Mobox3.DSZSH.core;
+using HH.WCS.Mobox3.DSZSH.util;
 
 using Newtonsoft.Json;
 
diff --git a/api/ApiHelper.cs b/api/ApiHelper.cs
index f1adf15..8708fea 100644
--- a/api/ApiHelper.cs
+++ b/api/ApiHelper.cs
@@ -1,6 +1,7 @@
 锘縰sing System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Security.Cryptography;
 
 using HH.WCS.Mobox3.DSZSH.core;
 using HH.WCS.Mobox3.DSZSH.models;
@@ -8,6 +9,7 @@
 using HH.WCS.Mobox3.DSZSH.wms;
 
 using Newtonsoft.Json;
+
 using SqlSugar;
 
 using Swashbuckle.Swagger;
@@ -61,10 +63,8 @@
                 }
 
                 // 鏇存柊[璧风偣/缁堢偣]閿佺姸鎬�鍒涘缓浠诲姟
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
-
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
+                
                 using (var tran = db.Ado.UseTran()) {
                     // 鍒犻櫎/鏇存柊鏃璐т綅/瀹瑰櫒/鐗╂枡]淇℃伅
                     if (old.LocCntrRel != null && db.Deleteable(old.LocCntrRel).ExecuteCommand() <= 0) {
@@ -148,9 +148,7 @@
                 }
 
                 // 璧风偣缁堢偣涓婇攣,鍒涘缓浠诲姟
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
 
                 using (var tran = db.Ado.UseTran()) {
                     if (old.CgDetail != null && db.Deleteable(old.CgDetail).ExecuteCommand() <= 0) {
@@ -237,9 +235,7 @@
                     return NewSimpleResult(3, preLog + $"娌℃湁鎵惧埌鍚堥�鐨勭粓鐐硅揣浣�瑕佹眰:閿佺姸鎬�'鏃�;褰撳墠瀹瑰櫒鏁伴噺=0;鎵�湪搴撳尯={LogObject(taskInfo.EndAreas)}");
                 }
 
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
 
                 using (var tran = db.Ado.UseTran()) {
                     if (old.CgDetail != null && db.Deleteable(old.CgDetail).ExecuteCommand() <= 0) {
@@ -329,9 +325,7 @@
                     return NewSimpleResult(5, preLog + $"娌℃湁鎵惧埌鍚堥�鐨勭粓鐐硅揣浣�瑕佹眰:閿佺姸鎬�'鏃�;褰撳墠瀹瑰櫒鏁伴噺=0;鎵�湪搴撳尯={LogObject(taskInfo.EndAreas)}");
                 }
 
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, model.CntId, taskInfo.TaskName);
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
 
                 cntr.S_SOURCE = task.S_CODE; // 鐢ㄤ换鍔″彿浣滀负瀹瑰櫒鏇存柊鐨勪緷鎹�                 cntr.T_MODIFY = DateTime.Now;
@@ -396,10 +390,8 @@
                     return NewSimpleResult(3, preLog + $"娌℃湁鎵惧埌鍚堥�鐨勭粓鐐硅揣浣�瑕佹眰:閿佺姸鎬�'鏃�,褰撳墠瀹瑰櫒鏁伴噺=0,鎵�湪搴撳尯={LogObject(taskInfo.EndAreas)}");
                 }
 
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, model.CntId, taskInfo.TaskName);
-                
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, model.CntId, taskInfo.TaskName);
+
                 using (var tran = db.Ado.UseTran()) {
                     // 鏇存柊[璧风偣/缁堢偣]閿佺姸鎬�鍒涘缓浠诲姟
                     if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
@@ -463,10 +455,7 @@
                 cgDetail.T_MODIFY = DateTime.Now;
 
                 var cntId = locCntrRel.S_CNTR_CODE;
-                var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskInfo.TaskName);
-
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, cntId, taskInfo.TaskName);
 
                 using (var tran = db.Ado.UseTran()) {
                     if (db.Updateable(cgDetail).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
@@ -538,9 +527,7 @@
                 cgDetail.N_ITEM_STATE = 2;
                 cgDetail.S_ITEM_STATE = "涓嶅悎鏍�;
 
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, locCntrRel.S_CNTR_CODE, taskInfo.TaskName);
 
                 using (var tran = db.Ado.UseTran()) {
                     if (db.Updateable(cgDetail).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE }).ExecuteCommand() <= 0) {
@@ -601,9 +588,7 @@
 
                 var cntId = locCntrRel.S_CNTR_CODE;
 
-                WCSHelper.LockStartLoc(ref startLoc);
-                WCSHelper.LockEndLoc(ref endLoc);
-                var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskInfo.TaskName);
+                var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, cntId, taskInfo.TaskName);
 
                 using (var tran = db.Ado.UseTran()) {
                     //if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) {
diff --git a/api/ApiModel.cs b/api/ApiModel.cs
index 0a6667f..cd2647e 100644
--- a/api/ApiModel.cs
+++ b/api/ApiModel.cs
@@ -4,6 +4,8 @@
 using System.Text;
 using System.Threading.Tasks;
 
+using HH.WCS.Mobox3.DSZSH.util;
+
 using Newtonsoft.Json;
 
 namespace HH.WCS.Mobox3.DSZSH.api {
diff --git a/api/DebugController.cs b/api/DebugController.cs
index 57215cd..37d9793 100644
--- a/api/DebugController.cs
+++ b/api/DebugController.cs
@@ -16,7 +16,6 @@
 
 using static HH.WCS.Mobox3.DSZSH.api.ApiModel;
 using static HH.WCS.Mobox3.DSZSH.api.OtherModel;
-using static HH.WCS.Mobox3.DSZSH.Config;
 using static HH.WCS.Mobox3.DSZSH.core.Monitor;
 
 namespace HH.WCS.Mobox3.DSZSH.api {
diff --git a/api/ErpController.cs b/api/ErpController.cs
index 78b7ae5..d58e3fc 100644
--- a/api/ErpController.cs
+++ b/api/ErpController.cs
@@ -3,6 +3,7 @@
 using System.Collections.Generic;
 using System.Web.Http;
 using static HH.WCS.Mobox3.DSZSH.api.OtherModel;
+using HH.WCS.Mobox3.DSZSH.util;
 
 namespace HH.WCS.Mobox3.DSZSH.api {
     /// <summary>
diff --git a/api/MoboxController.cs b/api/MoboxController.cs
index 059da11..71c46e0 100644
--- a/api/MoboxController.cs
+++ b/api/MoboxController.cs
@@ -1,6 +1,7 @@
 锘縰sing System.Web.Http;
 
 using HH.WCS.Mobox3.DSZSH.models;
+using HH.WCS.Mobox3.DSZSH.util;
 
 using Newtonsoft.Json;
 
diff --git a/api/WMSController.cs b/api/WMSController.cs
index dc50059..0d4ed91 100644
--- a/api/WMSController.cs
+++ b/api/WMSController.cs
@@ -1,4 +1,6 @@
-锘縰sing Newtonsoft.Json;
+锘縰sing HH.WCS.Mobox3.DSZSH.util;
+
+using Newtonsoft.Json;
 using System.Collections.Generic;
 using System.Web.Http;
 
diff --git a/core/Monitor.cs b/core/Monitor.cs
index 65bcc53..da491d5 100644
--- a/core/Monitor.cs
+++ b/core/Monitor.cs
@@ -22,8 +22,6 @@
 
         public static void CheckInbound() {                
             var db = new SqlHelper<object>().GetInstance();
-            var info = "";
-            
             try {
                 // 鏌ヤ骇绾挎槸鍚︽湁鐗╂枡淇℃伅
                 foreach (var prod in Settings.ProductionLines) {
@@ -36,8 +34,7 @@
                     // TCPClient浼犻�淇℃伅鐨勬椂鍊�涓嶈鐢ㄦ柇鐐归樆濉炵▼搴�                     // {"item_code":"CG1001","batch_no":"BN1001","cntr_code":"CN2505111"}
                     if (!TcpClientHelper.TryReadProductionLine(out byte[] read)) {
-                        info = $"娴嬭瘯{prod.Id}鍙蜂骇绾縶prod.PlcIp}:{prod.PlcPort}:璇诲彇浜х嚎淇℃伅澶辫触";
-                        LogHelper.Info(info);
+                        LogHelper.Info($"娴嬭瘯{prod.Id}鍙蜂骇绾縶prod.PlcIp}:{prod.PlcPort}:璇诲彇浜х嚎淇℃伅澶辫触");
                         continue;
                     }
 
@@ -145,15 +142,12 @@
 
                     var cntId = detail.S_CNTR_CODE;
 
-                    var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName);
+                    var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, cntId, taskName);
                     task.S_OP_CODE = detail.S_OO_NO;
                     if (string.IsNullOrEmpty(detail.S_BS_NO)) {
                         task.S_BS_NO = detail.S_BS_NO;
                         task.S_BS_TYPE = "ERP";
                     }
-
-                    WCSHelper.LockStartLoc(ref startLoc); // 璧风偣鍑哄簱閿�-                    WCSHelper.LockEndLoc(ref endLoc); // 缁堢偣鍏ュ簱閿� 
                     using (var tran = db.Ado.UseTran()) {
                         if (db.Updateable(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
@@ -199,8 +193,6 @@
 
         public static void CheckCheckOrder() {
             var db = new SqlHelper<object>().GetInstance();
-            var info = "";
-
             var taskInfo = Settings.GetTaskInfo(ETask.C鎶芥鍑哄簱);
             var taskName = taskInfo.TaskName;
             const string preLog = "杞:鎶芥:";
@@ -208,7 +200,7 @@
             try {
                 var orderList = db.Queryable<TN_Spot_Check>().Where(c => c.N_B_STATE == 1).OrderBy(c => c.T_CREATE).ToList();
                 if (orderList.Count == 0) {
-                    LogHelper.Debug($"杞:{taskName}:鏆傛棤寰呮墽琛岀殑{taskName}鍗�);
+                    LogHelper.Debug(preLog + $"鏆傛棤寰呮墽琛岀殑{taskName}鍗�);
                     return;
                 }
 
@@ -229,7 +221,7 @@
                         .ToList();
 
                     if (checkDetailList.Count == 0) {
-                        LogHelper.Info($"杞:{taskName}:浠嶆湁浠诲姟鏈墽琛屽畬鎴�浣嗗綋鍓嶆病鏈夊凡涓嬪彂鐨勪换鍔�);
+                        LogHelper.Info(preLog + $"浠嶆湁浠诲姟鏈墽琛屽畬鎴�浣嗗綋鍓嶆病鏈夊凡涓嬪彂鐨勪换鍔�);
                         continue;
                     }
 
@@ -243,7 +235,7 @@
                         .Where((l, c) => c.S_CNTR_CODE == detail.S_CNTR_CODE).First();
 
                     if (startLoc == null) {
-                        LogHelper.Info($"杞:{taskName}:娌℃湁鎵惧埌鍚堥�鐨勮捣鐐硅揣浣�");
+                        LogHelper.Info(preLog + $"娌℃湁鎵惧埌鍚堥�鐨勮捣鐐硅揣浣�");
                         continue;
                     }
 
@@ -253,18 +245,125 @@
                         .Where(a => a.N_CURRENT_NUM == 0).First();
 
                     if (endLoc == null) {
-                        LogHelper.Info($"杞:{taskName}:娌℃湁鎵惧埌鍚堥�鐨勭粓鐐硅揣浣�");
+                        LogHelper.Info(preLog + $"娌℃湁鎵惧埌鍚堥�鐨勭粓鐐硅揣浣�");
                         continue;
                     }
 
                     detail.N_B_STATE = 2;
 
                     var cntId = detail.S_CNTR_CODE;
-                    var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName);
+                    var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, cntId, taskName);
                     task.S_OP_CODE = detail.S_OO_NO;
 
-                    WCSHelper.LockStartLoc(ref startLoc);
-                    WCSHelper.LockEndLoc(ref endLoc);
+                    using (var tran = db.Ado.UseTran()) {
+                        if (db.Updateable(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            LogHelper.Info(preLog + $"淇敼{taskName}鍗曟槑缁嗚〃鐘舵�涓哄畬鎴�-澶辫触!");
+                            continue;
+                        }
+
+                        if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            LogHelper.Info(preLog + $"鏇存柊[璧风偣璐т綅閿佺姸鎬乚澶辫触!璧风偣='{startLoc.S_CODE}',閿佺姸鎬�>'鍑哄簱閿�");
+                            continue;
+                        }
+
+                        if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            LogHelper.Info(preLog + $"鏇存柊[缁堢偣璐т綅閿佺姸鎬乚澶辫触!缁堢偣='{endLoc.S_CODE}',閿佺姸鎬�>'鍏ュ簱閿�");
+                            continue;
+                        }
+
+                        if (db.Insertable(task).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            LogHelper.Info(preLog + $"鐢熸垚浠诲姟'{taskName}'澶辫触,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}");
+                            continue;
+                        }
+
+                        tran.CommitTran();
+                        LogHelper.Info(preLog + $"鐢熸垚浠诲姟'{taskName}'鎴愬姛,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}");
+                        continue;
+                    }
+                }
+            }
+            catch (Exception ex) {
+                LogHelper.InfoEx(ex, preLog);
+            }
+        }
+
+        public static void CheckShiftOrder() {                
+            var db = new SqlHelper<object>().GetInstance();
+            var taskInfo = Settings.GetTaskInfo(ETask.Y绉诲簱);
+            var taskName = taskInfo.TaskName;
+            const string preLog = "杞:绉诲簱:";
+            
+            try {
+                var orderList = db.Queryable<TN_Relocation_List>()
+                    .Where(c => c.N_B_STATE == 1)
+                    .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc)
+                    .ToList();
+
+                if (orderList.Count == 0) {
+                    LogHelper.Debug(preLog + $"鏆傛棤寰呮墽琛岀殑{taskName}鍗�);
+                    return;
+                }
+
+                var detailList = new List<TN_RelocationList_Detail>();
+                foreach (var order in orderList) {
+                    var doingCount = db.Queryable<TN_RelocationList_Detail>()
+                        .Count(d => d.S_OO_NO == order.S_NO && d.N_B_STATE >= 2); // 鎵ц涓�+                    var allCount = db.Queryable<TN_RelocationList_Detail>()
+                        .Count(d => d.S_OO_NO == order.S_NO);
+                    LogHelper.Info(preLog + $"缁熻{taskName}鍗�{order.S_NO}浠诲姟宸蹭笅鍙�{doingCount}/{allCount}");
+
+                    if (doingCount == allCount) {
+                        order.N_B_STATE = 2; // 鎵�湁浠诲姟閮藉凡鎵ц
+                        db.Updateable(order).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand();
+                        continue;
+                    }
+
+                    var checkDetailList = db.Queryable<TN_RelocationList_Detail>()
+                        .Where(a => a.S_OO_NO == order.S_NO && a.N_B_STATE == 1) // 宸蹭笅鍙�+                        .ToList();
+
+                    if (checkDetailList.Count == 0) {
+                        LogHelper.Info(preLog + $"浠嶆湁浠诲姟鏈墽琛屽畬鎴�浣嗗綋鍓嶆病鏈夊凡涓嬪彂鐨勪换鍔�);
+                        continue;
+                    }
+
+                    foreach (var checkDetail in checkDetailList) {
+                        detailList.Add(checkDetail);
+                    }
+                }
+
+                foreach (var detail in detailList) {
+                    var startLoc = db.Queryable<TN_Location>()
+                        .LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE)
+                        .Where((l, c) => c.S_CNTR_CODE == detail.S_CNTR_CODE)
+                        .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "鏃� && l.C_ENABLE == "Y") // 绛涢�:鏈笂閿�+                        .Where(l => l.N_CURRENT_NUM == 1)
+                        .First();
+
+                    if (startLoc == null) {
+                        LogHelper.Info(preLog + $"娌℃湁鎵惧埌缁堢偣璐т綅={detail.S_END_AREA}鐨勭粓鐐硅揣浣�闇�婊¤冻:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0");
+                        continue;
+                    }
+
+                    var endLoc = db.Queryable<TN_Location>()
+                        .Where(l => l.S_AREA_CODE == detail.S_END_AREA)
+                        .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "鏃� && a.C_ENABLE == "Y") // 绛涢�:鏈笂閿�+                        .Where(a => a.N_CURRENT_NUM == 0).First();
+
+                    if (endLoc == null) {
+                        LogHelper.Info(preLog + $"娌℃湁鎵惧埌缁堢偣璐т綅={detail.S_END_AREA}鐨勭粓鐐硅揣浣�闇�婊¤冻:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0");
+                        continue;
+                    }
+
+                    detail.N_B_STATE = 2;
+
+                    var cntId = detail.S_CNTR_CODE;
+                    var task = WCSHelper.BuildTaskWithLocLock(startLoc, endLoc, cntId, taskName);
+                    task.S_OP_CODE = detail.S_OO_NO;
 
                     using (var tran = db.Ado.UseTran()) {
                         if (db.Updateable(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
@@ -287,146 +386,12 @@
 
                         if (db.Insertable(task).ExecuteCommand() <= 0) {
                             tran.RollbackTran();
-                            info = $"鐢熸垚浠诲姟'{taskName}'澶辫触,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}";
-                            LogHelper.Info(info);
+                            LogHelper.Info(preLog + $"鐢熸垚浠诲姟'{taskName}'澶辫触,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}");
                             continue;
                         }
 
                         tran.CommitTran();
-                        info = $"鐢熸垚浠诲姟'{taskName}'鎴愬姛,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}";
-                        LogHelper.Info(info);
-                        continue;
-                    }
-                }
-            }
-            catch (Exception ex) {
-                LogHelper.InfoEx(ex, preLog);
-            }
-        }
-
-        public static void CheckShiftOrder() {                
-            var db = new SqlHelper<object>().GetInstance();
-            var info = "";
-
-            var taskInfo = Settings.GetTaskInfo(ETask.Y绉诲簱);
-            var taskName = taskInfo.TaskName;
-            const string preLog = "杞:绉诲簱:";
-
-            try {
-                var orderList = db.Queryable<TN_Relocation_List>()
-                    .Where(c => c.N_B_STATE == 1)
-                    .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc)
-                    .ToList();
-
-                if (orderList.Count == 0) {
-                    LogHelper.Debug($"杞:{taskName}:鏆傛棤寰呮墽琛岀殑{taskName}鍗�);
-                    return;
-                }
-
-                var detailList = new List<TN_RelocationList_Detail>();
-                foreach (var order in orderList) {
-                    var doingCount = db.Queryable<TN_RelocationList_Detail>()
-                        .Count(d => d.S_OO_NO == order.S_NO && d.N_B_STATE >= 2); // 鎵ц涓�-                    var allCount = db.Queryable<TN_RelocationList_Detail>()
-                        .Count(d => d.S_OO_NO == order.S_NO);
-                    LogHelper.Info($"杞:{taskName}:缁熻{taskName}鍗�{order.S_NO}浠诲姟宸蹭笅鍙�{doingCount}/{allCount}");
-
-                    if (doingCount == allCount) {
-                        order.N_B_STATE = 2; // 鎵�湁浠诲姟閮藉凡鎵ц
-                        db.Updateable(order).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand();
-                        continue;
-                    }
-
-                    var checkDetailList = db.Queryable<TN_RelocationList_Detail>()
-                        .Where(a => a.S_OO_NO == order.S_NO && a.N_B_STATE == 1) // 宸蹭笅鍙�-                        .ToList();
-
-                    if (checkDetailList.Count == 0) {
-                        LogHelper.Info($"杞:{taskName}:浠嶆湁浠诲姟鏈墽琛屽畬鎴�浣嗗綋鍓嶆病鏈夊凡涓嬪彂鐨勪换鍔�);
-                        continue;
-                    }
-
-                    foreach (var checkDetail in checkDetailList) {
-                        detailList.Add(checkDetail);
-                    }
-                }
-
-                foreach (var detail in detailList) {
-                    var startLoc = db.Queryable<TN_Location>()
-                        .LeftJoin<TN_Loc_Container>((l, c) => l.S_CODE == c.S_LOC_CODE)
-                        .Where((l, c) => c.S_CNTR_CODE == detail.S_CNTR_CODE)
-                        .Where(l => l.N_LOCK_STATE == 0 && l.S_LOCK_STATE == "鏃� && l.C_ENABLE == "Y") // 绛涢�:鏈笂閿�-                        .Where(l => l.N_CURRENT_NUM == 1)
-                        .First();
-
-                    if (startLoc == null) {
-                        info = $"杞:{taskName}:娌℃湁鎵惧埌瀹瑰櫒鍙�{detail.S_CNTR_CODE}鐨勮捣鐐硅揣浣�闇�婊¤冻:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=1";
-                        LogHelper.Info(info);
-                        continue;
-                    }
-
-                    var endLoc = db.Queryable<TN_Location>()
-                        .Where(l => l.S_AREA_CODE == detail.S_END_AREA)
-                        .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "鏃� && a.C_ENABLE == "Y") // 绛涢�:鏈笂閿�-                        .Where(a => a.N_CURRENT_NUM == 0).First();
-
-                    if (endLoc == null) {
-                        info = $"杞:{taskName}:娌℃湁鎵惧埌缁堢偣璐т綅={detail.S_END_AREA}鐨勭粓鐐硅揣浣�闇�婊¤冻:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0";
-                        LogHelper.Info(info);
-                        continue;
-                    }
-
-                    detail.N_B_STATE = 2;
-
-                    var cntId = detail.S_CNTR_CODE;
-                    var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName);
-                    task.S_OP_CODE = detail.S_OO_NO;
-
-                    WCSHelper.LockStartLoc(ref startLoc); // 璧风偣鍑哄簱閿�-                    WCSHelper.LockEndLoc(ref endLoc); // 缁堢偣鍏ュ簱閿�-
-                    using (var tran = db.Ado.UseTran()) {
-                        if (db.Updateable(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) {
-                            tran.RollbackTran();
-                            LogHelper.Info($"杞:{taskName}:淇敼{taskName}鍗曟槑缁嗚〃鐘舵�涓哄畬鎴�-澶辫触!");
-                            continue;
-                        }
-
-                        if (db.Updateable(startLoc).UpdateColumns(it => new {
-                            it.N_LOCK_STATE,
-                            it.S_LOCK_STATE,
-                            it.S_LOCK_OP,
-                            it.T_MODIFY,
-                            it.N_CURRENT_NUM, // 璧风偣璐т綅缁戝畾鍚�灏嗚揣浣嶇姸鎬佹洿鏂�-                        }).ExecuteCommand() <= 0) {
-                            tran.RollbackTran();
-                            info = $"鐢熸垚浠诲姟'{taskName}'澶辫触:鏇存柊璧风偣璐т綅{startLoc.S_CODE}閿佺姸鎬佸け璐�;
-                            LogHelper.Info(info);
-                            continue;
-                        }
-
-                        if (db.Updateable(endLoc).UpdateColumns(it => new {
-                            it.N_LOCK_STATE,
-                            it.S_LOCK_STATE,
-                            it.S_LOCK_OP,
-                            it.T_MODIFY,
-                        }).ExecuteCommand() <= 0) {
-                            tran.RollbackTran();
-                            info = $"鐢熸垚浠诲姟'{taskName}'澶辫触:鏇存柊缁堢偣璐т綅{endLoc.S_CODE}閿佺姸鎬佸け璐�;
-                            LogHelper.Info(info);
-                            continue;
-                        }
-
-                        if (db.Insertable(task).ExecuteCommand() <= 0) {
-                            tran.RollbackTran();
-                            info = $"鐢熸垚浠诲姟'{taskName}'澶辫触,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}";
-                            LogHelper.Info(info);
-                            continue;
-                        }   
-
-                        tran.CommitTran();
-                        info = $"鐢熸垚浠诲姟'{taskName}'鎴愬姛,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}";
-                        LogHelper.Info(info);
+                        LogHelper.Info(preLog + $"鐢熸垚浠诲姟'{taskName}'鎴愬姛,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}");
                         continue;
                     }
                 }
@@ -438,7 +403,6 @@
 
         public static void CreateTaskReturnErp(TN_Task task) {
             var db = new SqlHelper<object>().GetInstance();
-            var info = "";
             var httpH = new HttpHelper();
 
             try {
@@ -447,8 +411,7 @@
                     .First();
 
                 if (plan == null) {
-                    info = $"璁″垝鍗曞彿{task.S_BS_NO}涓嶅瓨鍦�";
-                    LogHelper.Info(info);
+                    LogHelper.Info($"璁″垝鍗曞彿{task.S_BS_NO}涓嶅瓨鍦�");
                 }
 
                 var cgDetail = db.Queryable<TN_CG_Detail>()
@@ -456,8 +419,7 @@
                     .First();
 
                 if (cgDetail == null) {
-                    info = $"鐗╂枡缂栫爜涓嶅瓨鍦�";
-                    LogHelper.Info(info);
+                    LogHelper.Info($"璁″垝鍗曞彿{task.S_BS_NO}涓嶅瓨鍦�");
                 }
 
                 var model = new OtherModel.CreateTaskReturnErpInfo {
@@ -527,8 +489,7 @@
                 plan.HWZT = model.hwzt;
                 plan.PH = model.ph;
                 var success = db.Updateable(plan).UpdateColumns(p => new { p.HW, p.HWZT, p.PH }).ExecuteCommand() > 0;
-                info = "鏇存柊鍑哄簱璁″垝鍗曡褰曡〃" + (success ? "鎴愬姛" : "澶辫触");
-                LogHelper.Info(info);
+                LogHelper.Info("鏇存柊鍑哄簱璁″垝鍗曡褰曡〃" + (success ? "鎴愬姛" : "澶辫触"));
             }
             catch (Exception ex) {
                 LogHelper.InfoEx(ex);
diff --git a/core/WCSCore.cs b/core/WCSCore.cs
index 5f1e56a..801e745 100644
--- a/core/WCSCore.cs
+++ b/core/WCSCore.cs
@@ -113,7 +113,6 @@
 
         private static void RecordTaskTable(TN_Task task) {
             var db = new SqlHelper<object>().GetInstance();
-            var info = "";
 
             try {
                 var cgDetail = new TN_CG_Detail(); // 濡傛灉娌℃湁淇℃伅,榛樿灏辨槸绌哄�,鍙互鐩存帴濉叆,涓嶉渶瑕佸垽鏂�@@ -128,8 +127,7 @@
                         .First();
 
                     if (cgDetail == null) {
-                        info = $"浠诲姟{task.S_CODE}瀹屾垚,璁板綍鍑哄叆搴撳瓨鍦ㄩ棶棰�鏃犳硶鍦ㄥ鍣ㄨ揣鍝佹槑缁嗚〃涓壘鍒版墭鐩榹task.S_CNTR_CODE}瀵瑰簲鐨勭墿鏂�;
-                        LogHelper.Info(info);
+                        LogHelper.Info($"浠诲姟{task.S_CODE}瀹屾垚,璁板綍鍑哄叆搴撳瓨鍦ㄩ棶棰�鏃犳硶鍦ㄥ鍣ㄨ揣鍝佹槑缁嗚〃涓壘鍒版墭鐩榹task.S_CNTR_CODE}瀵瑰簲鐨勭墿鏂�);
                         //return;
                         cgDetail = new TN_CG_Detail() ;
                         cgDetail.S_ITEM_CODE = "寮傚父";
@@ -150,8 +148,7 @@
                     .Where(r => r.S_TASK_NO == task.S_CODE).First();
                 if (record != null) {
                     //needUpdateRecordTable = true;
-                    info = $"鍑哄叆搴撹褰曡〃涓凡缁忓瓨鍦ㄤ换鍔″彿{task.S_CODE}"; // 闃叉娴嬭瘯鏃跺弽澶嶈皟鐢�34562瀵艰嚧閲嶅璁板綍
-                    LogHelper.Info(info);
+                    LogHelper.Info($"鍑哄叆搴撹褰曡〃涓凡缁忓瓨鍦ㄤ换鍔″彿{task.S_CODE}"); // 闃叉娴嬭瘯鏃跺弽澶嶈皟鐢�34562瀵艰嚧閲嶅璁板綍
                     return;
                 }
 
@@ -175,13 +172,11 @@
 
                 // 鏁版嵁搴撴搷浣�                 if (db.Insertable(record).ExecuteCommand() <= 0) {
-                    info = "鎻掑叆鍑哄叆搴撹褰曡〃澶辫触:" + JsonConvert.SerializeObject(record);
-                    LogHelper.Info(info);
+                    LogHelper.Info("鎻掑叆鍑哄叆搴撹褰曡〃澶辫触:" + JsonConvert.SerializeObject(record));
                     return;
                 }
 
-                info = "鎻掑叆鍑哄叆搴撹褰曡〃鎴愬姛";
-                LogHelper.Info(info);
+                LogHelper.Info("鎻掑叆鍑哄叆搴撹褰曡〃鎴愬姛");
             }
             catch (Exception ex) {
                 LogHelper.InfoEx(ex);
@@ -313,7 +308,6 @@
 
         public static void PickUpReturnErp(TN_Task task) {
             var db = new SqlHelper<object>().GetInstance();
-            var info = "";
             var httpH = new HttpHelper();
             
             try {
@@ -322,8 +316,7 @@
                     .First();
 
                 if (plan == null) {
-                    info = $"璁″垝鍗曞彿{task.S_BS_NO}涓嶅瓨鍦�";
-                    LogHelper.Info(info);
+                    LogHelper.Info($"璁″垝鍗曞彿{task.S_BS_NO}涓嶅瓨鍦�");
                 }
 
                 var cgDetail = db.Queryable<TN_CG_Detail>()
@@ -331,8 +324,7 @@
                     .First();
 
                 if (cgDetail == null) {
-                    info = $"鐗╂枡缂栫爜涓嶅瓨鍦�";
-                    LogHelper.Info(info);
+                    LogHelper.Info($"鐗╂枡缂栫爜涓嶅瓨鍦�");
                 }
 
                 var model = new OtherModel.PickUpReturnErpInfo {
@@ -402,8 +394,7 @@
                 plan.SFSL = model.sfsl;
                 plan.HWZT = model.hwzt;
                 var success = db.Updateable(plan).UpdateColumns(p => new { p.SFJS, p.SFSL, p.HWZT }).ExecuteCommand() > 0;
-                info = "鏇存柊鍑哄簱璁″垝鍗曡褰曡〃" + (success ? "鎴愬姛" : "澶辫触");
-                LogHelper.Info(info);
+                LogHelper.Info("鏇存柊鍑哄簱璁″垝鍗曡褰曡〃" + (success ? "鎴愬姛" : "澶辫触"));
             }
             catch (Exception ex) {
                 LogHelper.InfoEx(ex);
@@ -496,7 +487,6 @@
         /// <returns></returns>
         public static Result<bool> CreateInboundTask(string startLocCode, string cntrCode) {
             var db = new SqlHelper<object>().GetInstance();
-            var info = "";
 
             var taskInfo = Settings.GetTaskInfo(ETask.M婊℃墭涓嬬嚎鍏ュ簱);
             var taskName = taskInfo.TaskName;
@@ -513,9 +503,7 @@
                 .First();
 
                 if (startLoc == null) {
-                    info = $"娌℃湁鎵惧埌璧风偣璐т綅'{startLocCode}',鎴栦笉婊¤冻瑕佹眰:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0";
-                    LogHelper.Info(info);
-                    return new Result<bool>(false, info);
+                    return NewResult(false, $"娌℃湁鎵惧埌璧风偣璐т綅'{startLocCode}',鎴栦笉婊¤冻瑕佹眰:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0");
                 }
 
                 var locCntrRelOld = db.Queryable<TN_Loc_Container>()
@@ -538,71 +526,46 @@
                     .First();
 
                 if (endLoc == null) {
-                    info = $"娌℃湁鎵惧埌鍚堥�鐨勩�缁堢偣璐т綅銆�闇�婊¤冻瑕佹眰:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0";
-                    LogHelper.Info(info);
-                    return new Result<bool>(false, info);
+                    return NewResult(false, $"娌℃湁鎵惧埌鍚堥�鐨勩�缁堢偣璐т綅銆�闇�婊¤冻瑕佹眰:鏈笂閿�褰撳墠瀹瑰櫒鏁伴噺=0");
                 }
 
                 var cntId = locCntrRel.S_CNTR_CODE;
                 var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName);
 
-                WCSHelper.LockStartLoc(ref startLoc); // 璧风偣鍑哄簱閿�-                WCSHelper.LockEndLoc(ref endLoc); // 缁堢偣鍏ュ簱閿�+                WCSHelper.LockStartLoc(startLoc); // 璧风偣鍑哄簱閿�+                WCSHelper.LockEndLoc(endLoc); // 缁堢偣鍏ュ簱閿� 
                 using (var tran = db.Ado.UseTran()) {
                     if (locCntrRelOld != null) {
                         if (db.Deleteable(locCntrRelOld).ExecuteCommand() <= 0 &&
                             db.Updateable<TN_Location>().SetColumns(l => l.N_CURRENT_NUM == 0).Where(l => l.S_CODE == locCntrRelOld.S_LOC_CODE).ExecuteCommand() <= 0) {
                             tran.RollbackTran();
-                            info = $"鍒犻櫎鏃ц揣浣嶅鍣ㄥ叧绯昏〃澶辫触:璐т綅缂栫爜{locCntrRelOld.S_LOC_CODE},瀹瑰櫒缂栫爜{locCntrRelOld.S_CNTR_CODE}";
-                            LogHelper.Info(info);
-                            return new Result<bool>(false, info);
+                            return NewResult(false, $"鍒犻櫎鏃ц揣浣嶅鍣ㄥ叧绯昏〃澶辫触:璐т綅缂栫爜{locCntrRelOld.S_LOC_CODE},瀹瑰櫒缂栫爜{locCntrRelOld.S_CNTR_CODE}");
                         }
                     }
 
                     if (db.Insertable(locCntrRel).ExecuteCommand() <= 0) {
                         tran.RollbackTran();
-                        info = $"鎻掑叆璐т綅瀹瑰櫒鍏崇郴琛ㄥけ璐�璐т綅缂栫爜{locCntrRel.S_LOC_CODE},瀹瑰櫒缂栫爜{locCntrRel.S_CNTR_CODE}";
-                        LogHelper.Info(info);
-                        return new Result<bool>(false, info);
+                        return NewResult(false, $"鎻掑叆璐т綅瀹瑰櫒鍏崇郴琛ㄥけ璐�璐т綅缂栫爜{locCntrRel.S_LOC_CODE},瀹瑰櫒缂栫爜{locCntrRel.S_CNTR_CODE}");
                     }
 
-                    if (db.Updateable(startLoc).UpdateColumns(it => new {
-                        it.N_LOCK_STATE,
-                        it.S_LOCK_STATE,
-                        it.S_LOCK_OP,
-                        it.T_MODIFY,
-                        it.N_CURRENT_NUM, // 璧风偣璐т綅缁戝畾鍚�灏嗚揣浣嶇姸鎬佹洿鏂�-                    }).ExecuteCommand() <= 0) {
+                    if (db.Updateable(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
                         tran.RollbackTran();
-                        info = $"鐢熸垚浠诲姟'{taskName}'澶辫触:鏇存柊璧风偣璐т綅{startLoc.S_CODE}閿佺姸鎬佸け璐�;
-                        LogHelper.Info(info);
-                        return new Result<bool>(false, info);
+                        return NewResult(false, $"鐢熸垚浠诲姟'{taskName}'澶辫触:鏇存柊璧风偣璐т綅{startLoc.S_CODE}閿佺姸鎬佸け璐�);
                     }
 
-                    if (db.Updateable(endLoc).UpdateColumns(it => new {
-                        it.N_LOCK_STATE,
-                        it.S_LOCK_STATE,
-                        it.S_LOCK_OP,
-                        it.T_MODIFY,
-                    }).ExecuteCommand() <= 0) {
+                    if (db.Updateable(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
                         tran.RollbackTran();
-                        info = $"鐢熸垚浠诲姟'{taskName}'澶辫触:鏇存柊缁堢偣璐т綅{endLoc.S_CODE}閿佺姸鎬佸け璐�;
-                        LogHelper.Info(info);
-                        return new Result<bool>(false, info);
+                        return NewResult(false, $"鐢熸垚浠诲姟'{taskName}'澶辫触:鏇存柊缁堢偣璐т綅{endLoc.S_CODE}閿佺姸鎬佸け璐�);
                     }
 
                     if (db.Insertable(task).ExecuteCommand() <= 0) {
                         tran.RollbackTran();
-                        info = $"鐢熸垚浠诲姟'{taskName}'澶辫触,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}";
-                        LogHelper.Info(info);
-                        return new Result<bool>(false, info);
+                        return NewResult(false, $"鐢熸垚浠诲姟'{taskName}'澶辫触,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}");
                     }
 
                     tran.CommitTran();
-                    info = $"鐢熸垚浠诲姟'{taskName}'鎴愬姛,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}";
-                    LogHelper.Info(info);
-                    return new Result<bool>(true, info);
+                    return NewResult(true, $"鐢熸垚浠诲姟'{taskName}'鎴愬姛,浠诲姟鍙�{task.S_CODE},瀹瑰櫒鍙�{cntId},璧风偣={startLoc.S_CODE},缁堢偣={endLoc.S_CODE}");
                 }
             }
             catch (Exception ex) {
diff --git a/device/ModbusFactory.cs b/device/ModbusFactory.cs
index 4c84a8a..d44947b 100644
--- a/device/ModbusFactory.cs
+++ b/device/ModbusFactory.cs
@@ -9,6 +9,7 @@
 
 using TcpClient = System.Net.Sockets.TcpClient;
 using System.IO;
+using HH.WCS.Mobox3.DSZSH.util;
 
 namespace HH.WCS.Mobox3.DSZSH.device {
     // 瀹氫箟Modbus閫氳鎺ュ彛
diff --git a/device/ModbusHelper.cs b/device/ModbusHelper.cs
index 5c8dc79..7633921 100644
--- a/device/ModbusHelper.cs
+++ b/device/ModbusHelper.cs
@@ -5,6 +5,8 @@
 
 using EasyModbus;
 
+using HH.WCS.Mobox3.DSZSH.util;
+
 namespace HH.WCS.Mobox3.DSZSH.device {
     /// <summary>
     /// modbus tcp 鐢ㄧ涓夋柟鐨勫寘
diff --git a/device/OpcUaHelper.cs b/device/OpcUaHelper.cs
index 106acb9..4f8922c 100644
--- a/device/OpcUaHelper.cs
+++ b/device/OpcUaHelper.cs
@@ -2,6 +2,7 @@
 using Opc.Ua;
 using System;
 using Opc.Ua.Configuration;
+using HH.WCS.Mobox3.DSZSH.util;
 
 
 namespace HH.WCS.Mobox3.DSZSH.device
diff --git a/device/ProductionLineDevice.cs b/device/ProductionLineDevice.cs
index 986d0f5..2c8dfd1 100644
--- a/device/ProductionLineDevice.cs
+++ b/device/ProductionLineDevice.cs
@@ -1,5 +1,7 @@
 锘縰sing System;
 
+using HH.WCS.Mobox3.DSZSH.util;
+
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 
diff --git a/device/S7Helper.cs b/device/S7Helper.cs
index dfe1385..7f54794 100644
--- a/device/S7Helper.cs
+++ b/device/S7Helper.cs
@@ -1,4 +1,6 @@
 锘縰sing HH.WCS.Mobox3.DSZSH.api;
+using HH.WCS.Mobox3.DSZSH.util;
+
 using Newtonsoft.Json.Linq;
 using S7.Net;
 using S7.Net.Types;
diff --git a/device/TcpClient.cs b/device/TcpClient.cs
index 44cb8b6..4b2bda1 100644
--- a/device/TcpClient.cs
+++ b/device/TcpClient.cs
@@ -1,5 +1,7 @@
 锘縰sing HH.WCS.Mobox3.DSZSH;
 using HH.WCS.Mobox3.DSZSH.device;
+using HH.WCS.Mobox3.DSZSH.util;
+
 using System;
 using System.Collections.Generic;
 using System.Linq;
diff --git a/device/TcpClientHelper.cs b/device/TcpClientHelper.cs
index 2981a95..e95f57e 100644
--- a/device/TcpClientHelper.cs
+++ b/device/TcpClientHelper.cs
@@ -4,6 +4,8 @@
 using System.Net.Sockets;
 using System.Text;
 
+using HH.WCS.Mobox3.DSZSH.util;
+
 using Newtonsoft.Json;
 
 namespace HH.WCS.Mobox3.DSZSH.device {
diff --git a/device/TcpServer.cs b/device/TcpServer.cs
index b85a167..3340cb5 100644
--- a/device/TcpServer.cs
+++ b/device/TcpServer.cs
@@ -1,4 +1,6 @@
 锘縰sing HH.WCS.Mobox3.DSZSH.dispatch;
+using HH.WCS.Mobox3.DSZSH.util;
+
 using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
diff --git a/dispatch/NDC.cs b/dispatch/NDC.cs
index 9fee4d1..1974369 100644
--- a/dispatch/NDC.cs
+++ b/dispatch/NDC.cs
@@ -1,4 +1,6 @@
-锘縰sing Newtonsoft.Json;
+锘縰sing HH.WCS.Mobox3.DSZSH.util;
+
+using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
 using System.Text;
diff --git a/models/BaseModel.cs b/models/BaseModel.cs
index fe43192..620a56f 100644
--- a/models/BaseModel.cs
+++ b/models/BaseModel.cs
@@ -3,40 +3,13 @@
 using SqlSugar;
 
 namespace HH.WCS.Mobox3.DSZSH.models {
-    /// <summary>
-    /// 銆愭鏋躲�妯℃澘鎶借薄绫�鍩烘湰琛ㄦ暟鎹ā鍨�-    /// </summary>
     public abstract class BaseModel {
-
-        /// <summary>
-        /// 鍞竴璇嗗埆鐮�(搴曞眰涓婚敭) 
-        /// </summary>
         [SugarColumn(IsPrimaryKey = true)]
         public string S_ID { get; set; } = Guid.NewGuid().ToString("D");
-
-        /// <summary>
-        /// 鍒涘缓浜�ID
-        /// </summary>
         public string S_CREATOR_ID { get; set; } = "sa";
-
-        /// <summary>
-        /// 鍒涘缓浜哄悕绉�-        /// </summary>
         public string S_CREATOR_NAME { get; set; } = "瓒呯骇鐢ㄦ埛";
-
-        /// <summary>
-        /// 鍒涘缓鏃堕棿
-        /// </summary>
         public DateTime T_CREATE { get; set; } = DateTime.Now;
-
-        /// <summary>
-        /// 淇敼鏃堕棿
-        /// </summary>
         public DateTime T_MODIFY { get; set; } = DateTime.Now;
-
-        /// <summary>
-        /// 鏁版嵁鐘舵�:缂栬緫,瀹氱増
-        /// </summary>
-        public string S_STATE { get; set; } = "缂栬緫";
+        public string S_STATE { get; set; } = "缂栬緫"; // 缂栬緫;瀹氱増
     }
 }
diff --git a/models/TN_Container.cs b/models/TN_Container.cs
index 2168a56..70e8b63 100644
--- a/models/TN_Container.cs
+++ b/models/TN_Container.cs
@@ -24,9 +24,13 @@
 
         public int N_DETAIL_COUNT { get; set; }
 
+        #region 闈炲瓧娈甸儴鍒�+        /// <summary>
+        /// <!--榛樿涓嶄娇鐢�->SqlSugar鍏崇郴鏄犲皠鍒楄〃
+        /// </summary>
         [SugarColumn(IsIgnore = true)]
         [Navigate(NavigateType.OneToMany, nameof(TN_CG_Detail.S_CNTR_CODE), nameof(S_CODE))]
-        public List<TN_CG_Detail> CntrItemRels { get; set; }
-
+        public List<TN_CG_Detail> CntrItemRels { get; set; } 
+        #endregion
     }
 }
diff --git a/models/TN_Loc_Container.cs b/models/TN_Loc_Container.cs
index 74ec013..03d239b 100644
--- a/models/TN_Loc_Container.cs
+++ b/models/TN_Loc_Container.cs
@@ -23,13 +23,18 @@
         /// </summary>
         public string S_CNTR_TYPE { get; set; }
 
-
-        // 瀹瑰櫒-鐗╂枡 1:n
+        #region 闈炲瓧娈甸儴鍒�+        /// <summary>
+        /// <!--榛樿涓嶄娇鐢�->SqlSugar鍏崇郴鏄犲皠鍒楄〃
+        /// </summary>
         [Navigate(NavigateType.OneToMany, nameof(TN_CG_Detail.S_CNTR_CODE))]
         public List<TN_CG_Detail> CntrItemRels { get; set; }
 
-        // 瀹瑰櫒鍏崇郴琛�瀹瑰櫒 1:1
+        /// <summary>
+        /// <!--榛樿涓嶄娇鐢�->SqlSugar鍏崇郴鏄犲皠鍒楄〃
+        /// </summary>
         [Navigate(NavigateType.OneToOne, nameof(S_CNTR_CODE))]
-        public TN_Container Container { get; set; }
+        public TN_Container Container { get; set; } 
+        #endregion
     }
 }
diff --git a/models/TN_Location.cs b/models/TN_Location.cs
index e9c844d..e1267d0 100644
--- a/models/TN_Location.cs
+++ b/models/TN_Location.cs
@@ -3,55 +3,16 @@
 using SqlSugar;
 
 namespace HH.WCS.Mobox3.DSZSH.models {
-    /// <summary>
-    /// 銆愭鏋躲�璐т綅琛�-    /// </summary>
-
     [SugarTable("TN_Location")]
     public class TN_Location : BaseModel {
-        /// <summary>
-        /// 璐т綅 ID
-        /// </summary>
         public string S_CODE { get; set; }
-
-        /// <summary>
-        /// 璐т綅鍚嶇О
-        /// </summary>
         public string S_NAME { get; set; } = "";
-
-        /// <summary>
-        /// 璐т綅鎵�湪鍖哄煙 ID
-        /// </summary>
         public string S_AREA_CODE { get; set; }
-
-        /// <summary>
-        /// 鍥借嚜 AGV 瀵瑰簲鐨勫簱浣嶅悕绉�-        /// </summary>
         public string S_AGV_SITE { get; set; } = "0";
-
-        /// <summary>
-        /// 璐т綅瀹瑰櫒瀹归噺
-        /// </summary>
         public int N_CAPACITY { get; set; } = 1;
-
-        /// <summary>
-        /// 璐т綅褰撳墠瀹瑰櫒鏁伴噺
-        /// </summary>
         public int N_CURRENT_NUM { get; set; } = 0;
-
-        /// <summary>
-        /// 琛屽彿
-        /// </summary>
         public int N_ROW { get; set; } = 0;
-
-        /// <summary>
-        /// 鍒楀彿
-        /// </summary>
         public int N_COL { get; set; } = 0;
-
-        /// <summary>
-        /// 璐т綅鐨勫眰鏁�-        /// </summary>
         public int N_LAYER { get; set; } = 1;
 
         // BEG 鍒濆鍖栬〃鏍间娇鐢�@@ -79,17 +40,12 @@
         /// </summary>
         public string S_LOCK_OP { get; set; } = "";
 
-        /// <summary>
-        /// 璐т綅鏄惁鍚敤:Y鍚敤
-        /// </summary>
         public string C_ENABLE { get; set; } = "Y";
 
+        #region 闈炲瓧娈甸儴鍒�         /// <summary>
-        /// 璐т綅-瀹瑰櫒 鍏崇郴鏄犲皠
+        /// <!--榛樿涓嶄娇鐢�->SqlSugar鍏崇郴鏄犲皠鍒楄〃
         /// </summary>
-        /// <remarks>
-        /// 榛樿鏄竴瀵瑰,閫氬父鎯呭喌鏄竴瀵逛竴
-        /// </remarks>
         [Navigate(NavigateType.OneToMany, nameof(TN_Loc_Container.S_LOC_CODE))]
         public List<TN_Loc_Container> LocCntrRels { get; set; }
 
@@ -102,6 +58,7 @@
                 case 3: str = "鍏跺畠閿�; break;
             }
             return str;
-        }
+        } 
+        #endregion
     }
 }
diff --git a/models/TN_Task.cs b/models/TN_Task.cs
index 540fce1..bf05cfe 100644
--- a/models/TN_Task.cs
+++ b/models/TN_Task.cs
@@ -96,7 +96,8 @@
         ///// </summary>
         //public int N_FORCE { get; set; } = 0;
 
-        internal static string GetStateStr(int state) {
+        #region 闈炲瓧娈甸儴鍒�+        public static string GetStateStr(int state) {
             // 0绛夊緟 1宸叉帹閫�2鎵ц 3瀹屾垚 4閿欒
             var status = "";
             switch (state) {
@@ -108,5 +109,6 @@
             }
             return status;
         }
+        #endregion
     }
 }
diff --git a/util/LogHelper.cs b/util/LogHelper.cs
index b13aff4..ba76934 100644
--- a/util/LogHelper.cs
+++ b/util/LogHelper.cs
@@ -9,7 +9,7 @@
 using NLog.Config;
 using NLog.Targets;
 
-namespace HH.WCS.Mobox3.DSZSH {
+namespace HH.WCS.Mobox3.DSZSH.util {
     public class LogHelper
     {
         public static Dictionary<string, ILogger> loggers = new Dictionary<string, ILogger>();
diff --git a/util/Settings.cs b/util/Settings.cs
index 1a2f598..74721a1 100644
--- a/util/Settings.cs
+++ b/util/Settings.cs
@@ -7,7 +7,7 @@
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 
-namespace HH.WCS.Mobox3.DSZSH {
+namespace HH.WCS.Mobox3.DSZSH.util {
     public class Settings
     {
         public static string WebApiUrl { get; set; }
diff --git a/wms/DbTranHelper.cs b/wms/DbTranHelper.cs
new file mode 100644
index 0000000..bbfb2da
--- /dev/null
+++ b/wms/DbTranHelper.cs
@@ -0,0 +1,97 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using HH.WCS.Mobox3.DSZSH.models;
+using HH.WCS.Mobox3.DSZSH.util;
+
+using Newtonsoft.Json;
+
+using SqlSugar;
+
+namespace HH.WCS.Mobox3.DSZSH.wms {
+    /// <summary>
+    /// [ 鏁版嵁搴撲簨鍔″鐞�] 甯姪绫�+    /// </summary>
+    public class DbTranHelper {
+        /// <summary>
+        /// 鏁版嵁搴撲簨鍔″鐞�( 鍒涘缓浠诲姟 )
+        /// </summary>
+        /// <remarks>瑕佹眰: obj != null</remarks>
+        /// <param name="obj"></param>
+        /// <returns></returns>
+        public static (bool Success, string Message) DoDbTranTask(DbTranTaskObj obj) {
+            var db = new SqlHelper<object>().GetInstance();
+            try {
+                using (var tran = db.Ado.UseTran()) {
+                    // 瀛樺湪[鏃瀹瑰櫒鍏宠仈淇℃伅:鍒犻櫎[鏃[瀹瑰櫒璐у搧鏄庣粏][璐т綅瀹瑰櫒鍏崇郴],鏇存柊[璐т綅][瀹瑰櫒鏁伴噺]
+                    if (obj.Old != null) {
+                        if (obj.Old.CgDetail != null && db.Deleteable(obj.Old.CgDetail).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            return (false, $"鍒犻櫎[鏃х墿鏂欎俊鎭痌澶辫触!!鏁版嵁:\n\n{JsonConvert.SerializeObject(obj.Old.CgDetail)}\n");
+                        }
+                        if (obj.Old.LocCntrRel != null && db.Deleteable(obj.Old.LocCntrRel).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            return (false, $"鍒犻櫎[鏃ц揣浣嶅鍣ㄥ叧绯籡澶辫触!!鏁版嵁:\n\n{JsonConvert.SerializeObject(obj.Old.LocCntrRel)}\n");
+                        }
+                        if (obj.Old.Location != null && db.Updateable(obj.Old.Location).UpdateColumns(l => new { l.N_CURRENT_NUM, l.T_MODIFY }).ExecuteCommand() <= 0) {
+                            tran.RollbackTran();
+                            return (false, $"鏇存柊[鏃ц揣浣峕[褰撳墠瀹瑰櫒鏁伴噺]澶辫触!!璐т綅='{obj.Old.Location.S_CODE}',鏁伴噺=>{obj.Old.Location.N_CURRENT_NUM}");
+                        }
+                    }
+
+                    // 鏇存柊[瀹瑰櫒琛╙(涓氬姟闇�)
+                    if (obj.ContainerToUpdate != null && db.Updateable(obj.ContainerToUpdate).UpdateColumns(c => new { c.S_SPEC, c.S_SOURCE, c.T_MODIFY }).ExecuteCommand() <= 0) {
+                        return (false, $"鏇存柊[瀹瑰櫒琛╙澶辫触!!鏁版嵁:\n\n{JsonConvert.SerializeObject(obj.ContainerToUpdate)}\n");
+                    }
+
+                    // 鏇存柊[瀹瑰櫒璐у搧鏄庣粏](涓氬姟闇�)
+                    if (obj.CgDetailToUpdate != null && db.Updateable(obj.CgDetailToUpdate).UpdateColumns(it => new { it.N_ITEM_STATE, it.S_ITEM_STATE, it.T_MODIFY }).ExecuteCommand() <= 0) {
+                        tran.RollbackTran();
+                        return (false, $"鏇存柊[鐗╂枡鏄庣粏琛╙澶辫触!!鐗╂枡鍙�'{obj.CgDetailToUpdate}',鐗╂枡鐘舵�=>'{obj.CgDetailToUpdate.S_ITEM_STATE}'");
+                    }
+
+                    // 瀛樺湪[鏂癩[璐т綅瀹瑰櫒缁戝畾鍏崇郴]:鎻掑叆[璐т綅瀹瑰櫒鍏崇郴琛╙
+                    if (obj.LocCntrRelToInsert != null && db.Insertable(obj.LocCntrRelToInsert).ExecuteCommand() <= 0) {
+                        tran.RollbackTran();
+                        return (false, $"鎻掑叆[瀹瑰櫒璐т綅缁戝畾琛╙澶辫触!!鏁版嵁:\n\n{JsonConvert.SerializeObject(obj.LocCntrRelToInsert)}\n");
+                    }
+
+                    // 鏇存柊[璧风偣][缁堢偣][閿佺姸鎬乚,鍒涘缓[浠诲姟]
+                    if (obj.StartLocToUpdate != null && db.Updateable(obj.StartLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, it.N_CURRENT_NUM, }).ExecuteCommand() <= 0) {
+                        tran.RollbackTran();
+                        return (false, $"鏇存柊[璧风偣璐т綅閿佺姸鎬乚澶辫触!!璧风偣='{obj.StartLocToUpdate.S_CODE}',閿佺姸鎬�>'{obj.StartLocToUpdate.S_LOCK_STATE}'");
+                    }
+                    if (obj.EndLocToUpdate != null && db.Updateable(obj.EndLocToUpdate).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY, }).ExecuteCommand() <= 0) {
+                        tran.RollbackTran();
+                        return (false, $"鏇存柊[缁堢偣璐т綅閿佺姸鎬乚澶辫触!!缁堢偣='{obj.EndLocToUpdate.S_CODE}',閿佺姸鎬�>'{obj.EndLocToUpdate.S_LOCK_STATE}'");
+                    }
+                    if (obj.TaskToInsert != null && db.Insertable(obj.TaskToInsert).ExecuteCommand() <= 0) {
+                        tran.RollbackTran();
+                        return (false, $"鐢熸垚浠诲姟'{obj.TaskToInsert.S_TYPE}'澶辫触!!浠诲姟鍙�'{obj.TaskToInsert.S_CODE}',瀹瑰櫒鍙�'{obj.TaskToInsert.S_CNTR_CODE}',璧风偣='{obj.TaskToInsert.S_START_LOC}',缁堢偣='{obj.TaskToInsert.S_END_LOC}'");
+                    }
+
+                    // 鎻愪氦鏁版嵁搴撴洿鏀�+                    tran.CommitTran();
+                    return (true, $"鐢熸垚浠诲姟'{obj.TaskToInsert.S_TYPE}'鎴愬姛!!浠诲姟鍙�'{obj.TaskToInsert.S_CODE}',瀹瑰櫒鍙�'{obj.TaskToInsert.S_CNTR_CODE}',璧风偣='{obj.TaskToInsert.S_START_LOC}',缁堢偣='{obj.TaskToInsert.S_END_LOC}'");
+                }
+            }
+            catch (Exception) {
+                throw; // 鐢卞閮ㄦ柟娉曟崟鑾峰鐞�+            }
+        }
+    }
+
+    public class DbTranTaskObj {
+        public LocCntrCg Old { get; set; } = null;
+        public TN_Container ContainerToUpdate { get; set; } = null;
+        public TN_CG_Detail CgDetailToUpdate { get; set; } = null;
+        public TN_Loc_Container LocCntrRelToInsert { get; set; } = null;
+        public TN_Location StartLocToUpdate { get; set; } = null;
+        public TN_Location EndLocToUpdate { get; set; } = null;
+        public TN_Task TaskToInsert { get; set; } = null;
+    }
+
+}
diff --git a/wms/LocationHelper.cs b/wms/LocationHelper.cs
index fc9bf9f..d713dc7 100644
--- a/wms/LocationHelper.cs
+++ b/wms/LocationHelper.cs
@@ -11,7 +11,7 @@
 
 namespace HH.WCS.Mobox3.DSZSH.wms {
     /// <summary>
-    /// 璐т綅甯姪绫�(鍖呭惈璐т綅-瀹瑰櫒鍏崇郴鐨勫鐞� 
+    /// 璐т綅甯姪绫�鍖呭惈璐т綅-瀹瑰櫒鍏崇郴鐨勫鐞� 
     /// </summary>
     public class LocationHelper
     {
diff --git a/wms/SYSHelper.cs b/wms/SYSHelper.cs
index 9eed2f2..fd6c4a8 100644
--- a/wms/SYSHelper.cs
+++ b/wms/SYSHelper.cs
@@ -9,6 +9,9 @@
 using System.Threading.Tasks;
 
 namespace HH.WCS.Mobox3.DSZSH.wms {
+    /// <summary>
+    /// 搴忓垪鍙风敓鎴愬府鍔╃被 (鍚嶇О/鍛藉悕绌洪棿涓哄巻鍙查仐鐣欓棶棰�
+    /// </summary>
     internal class SYSHelper {
         private static object locker = new object();
         internal static int GetSerialNumber(string snType, string prefix) {
diff --git a/wms/WCSHelper.cs b/wms/WCSHelper.cs
index d145c3a..1e7b40c 100644
--- a/wms/WCSHelper.cs
+++ b/wms/WCSHelper.cs
@@ -53,7 +53,7 @@
         }
 
         /// <summary>
-        /// ![[寮冪敤|鐞嗙敱:涓嶇伒娲�娑夊強涓氬姟杩囦簬鍏蜂綋]]妫�煡瀹瑰櫒绫诲瀷鏄惁姝g‘
+        /// <!--寮冪敤|鐞嗙敱:涓嶇伒娲�娑夊強涓氬姟杩囦簬鍏蜂綋-->妫�煡瀹瑰櫒绫诲瀷鏄惁姝g‘
         /// </summary>
         /// <param name="cntrCode"></param>
         /// <param name="cntrType"></param>
@@ -96,7 +96,7 @@
             if (locCntrRel != null) {
                 location = db.Queryable<TN_Location>().Where(l => l.S_CODE == locCntrRel.S_LOC_CODE).First();
                 if (location == null) {
-                    LogHelper.Warn($"");
+                    LogHelper.Warn($"鑾峰彇瀹瑰櫒鍏宠仈淇℃伅:[璐т綅瀹瑰櫒鍏崇郴]瀛樺湪,浣哰璐т綅]涓嶅瓨鍦�瀹瑰櫒='{cntrCode}',璐т綅='{locCntrRel.S_LOC_CODE}'");
                 }
             }
             if (location != null) {
@@ -112,19 +112,39 @@
         }
 
         /// <summary>
-        /// 缁戝畾[璐т綅-瀹瑰櫒]淇℃伅
+        /// [缁戝畾[璐т綅-瀹瑰櫒]淇℃伅](璁剧疆璐т綅鏁伴噺涓�;涓嶄細妫�煡loc鏄惁涓簄ull)
         /// </summary>
-        /// <param name="startLoc"></param>
+        /// <param name="loc"></param>
         /// <param name="cntrCode"></param>
         /// <returns></returns>
-        public static TN_Loc_Container BindLocCntr(ref TN_Location startLoc, string cntrCode) {
+        public static TN_Loc_Container BindLocCntr(ref TN_Location loc, string cntrCode) {
             var locCntrRel = new TN_Loc_Container {
-                S_LOC_CODE = startLoc.S_CODE,
+                S_LOC_CODE = loc.S_CODE,
                 S_CNTR_CODE = cntrCode,
             };
 
-            startLoc.N_CURRENT_NUM = 1;
-            startLoc.T_MODIFY = DateTime.Now;
+            if (loc.N_CURRENT_NUM != 0) {
+                LogHelper.Warn($"缁戝畾璐т綅瀹瑰櫒:绋嬪簭姝e湪灏濊瘯缁橻瀹瑰櫒鏁伴噺]涓嶆槸0鐨勮揣浣�璁剧疆[瀹瑰櫒鏁伴噺]涓�!璐т綅='{loc.S_CODE}',瀹瑰櫒鏁伴噺={loc.N_CURRENT_NUM}");
+            }
+
+            loc.N_CURRENT_NUM = 1;
+            loc.T_MODIFY = DateTime.Now;
+
+            return locCntrRel;
+        }
+
+        public static TN_Loc_Container BindLocCntrs(ref TN_Location loc, List<string> cntrCodes) {
+            var locCntrRel = new TN_Loc_Container {
+                S_LOC_CODE = loc.S_CODE,
+                S_CNTR_CODE = string.Join(",", cntrCodes)
+            };
+
+            if (loc.N_CURRENT_NUM != 0) {
+                LogHelper.Warn($"缁戝畾璐т綅瀹瑰櫒:绋嬪簭姝e湪灏濊瘯缁橻瀹瑰櫒鏁伴噺]涓嶆槸0鐨勮揣浣�璁剧疆[瀹瑰櫒鏁伴噺]涓�!璐т綅='{loc.S_CODE}',瀹瑰櫒鏁伴噺={loc.N_CURRENT_NUM}");
+            }
+
+            loc.N_CURRENT_NUM = 1;
+            loc.T_MODIFY = DateTime.Now;
 
             return locCntrRel;
         }
@@ -132,70 +152,102 @@
         /// <summary>
         /// 璧风偣鍑哄簱閿�         /// </summary>
+        /// <remarks>瑕佹眰: loc != null; 閿佺姸鎬�'鏃�;</remarks>
         /// <param name="loc"></param>
         /// <param name="lockSource"></param>
-        public static void LockStartLoc(ref TN_Location loc, string lockSource = "") {
-            if (loc == null) {
-                throw new ArgumentNullException(); // 鎺ュ彈璐т綅loc涓虹┖鏃剁洿鎺ユ姏寮傚父(閫氬父涓嶄細鍙戠敓)
-            }
-
+        public static void LockStartLoc(TN_Location loc, string lockSource = "") {
             if (loc.N_LOCK_STATE != 0 || loc.S_LOCK_STATE != "鏃�) {
-                LogHelper.Warn($"璧风偣鍑哄簱閿�绋嬪簭姝e湪灏濊瘯缁欏綋鍓峓閿佺姸鎬乚涓嶆槸'鏃�鐨勮揣浣嶄笂閿�璐т綅='{loc.S_CODE}',閿佺姸鎬�({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
+                LogHelper.Warn($"璧风偣鍑哄簱閿�绋嬪簭姝e湪灏濊瘯缁欏綋鍓峓閿佺姸鎬乚鈮�鏃�鐨勮揣浣嶄笂閿�璐т綅='{loc.S_CODE}',閿佺姸鎬�({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
             }
 
             loc.N_LOCK_STATE = 2; // 璧风偣鍑哄簱閿�             loc.S_LOCK_STATE = TN_Location.GetLockStateStr(2); // 璧风偣鍑哄簱閿�             loc.S_LOCK_OP = lockSource;
             loc.T_MODIFY = System.DateTime.Now;
+
+            LogHelper.Info($"璧风偣鍑哄簱閿�璧风偣璐т綅'{loc.S_CODE}'璁剧疆[鍑哄簱閿乚");
         }
 
         /// <summary>
         /// 缁堢偣鍏ュ簱閿�         /// </summary>
+        /// <remarks>瑕佹眰: loc != null; 閿佺姸鎬�'鏃�;</remarks>
         /// <param name="loc"></param>
         /// <param name="lockSource"></param>
-        public static void LockEndLoc(ref TN_Location loc, string lockSource = "") {
-            if (loc == null) {
-                throw new ArgumentNullException(); // 鎺ュ彈璐т綅loc涓虹┖鏃剁洿鎺ユ姏寮傚父(閫氬父涓嶄細鍙戠敓)
-            }
-
+        public static void LockEndLoc(TN_Location loc, string lockSource = "") {
             if (loc.N_LOCK_STATE != 0 || loc.S_LOCK_STATE != "鏃�) {
-                LogHelper.Warn($"璧风偣鍑哄簱閿�绋嬪簭姝e湪灏濊瘯缁欏綋鍓峓閿佺姸鎬乚涓嶆槸'鏃�鐨勮揣浣嶄笂閿�璐т綅='{loc.S_CODE}',閿佺姸鎬�({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
+                LogHelper.Warn($"缁堢偣鍏ュ簱閿�绋嬪簭姝e湪灏濊瘯缁欏綋鍓峓閿佺姸鎬乚鈮�鏃�鐨勮揣浣嶄笂閿�璐т綅='{loc.S_CODE}',閿佺姸鎬�({loc.N_LOCK_STATE},{loc.S_LOCK_STATE})");
             }
 
-            loc.N_LOCK_STATE = 1; // 缁堢偣鍑哄簱閿�-            loc.S_LOCK_STATE = TN_Location.GetLockStateStr(1); // 缁堢偣鍑哄簱閿�+            loc.N_LOCK_STATE = 1; // 缁堢偣鍏ュ簱閿�+            loc.S_LOCK_STATE = TN_Location.GetLockStateStr(1); // 缁堢偣鍏ュ簱閿�             loc.S_LOCK_OP = lockSource;
             loc.T_MODIFY = System.DateTime.Now;
+
+            LogHelper.Info($"缁堢偣鍏ュ簱閿�缁堢偣璐т綅='{loc.S_CODE}',鏉ユ簮='{lockSource}'");
         }
 
         /// <summary>
-        /// 鍒涘缓浠诲姟
+        /// [鍒涘缓浠诲姟](闇�‘淇漵tartLoc/endLoc涓嶄负null;涓嶄細妫�煡璐т綅S_CODE,S_AREA_CODE灞炴�鏄惁鍚堟硶)
         /// </summary>
         /// <param name="startLoc">璧风偣璐т綅:鑷冲皯鎻愪緵:S_CODE,S_AREA_CODE</param>
         /// <param name="endLoc">缁堢偣璐т綅:鑷冲皯鎻愪緵:S_CODE,S_AREA_CODE</param>
         /// <param name="cntId">瀹瑰櫒鍙�/param>
         /// <param name="type">浠诲姟绫诲瀷(鍚嶇О)</param>
         /// <param name="pri">浼樺厛绾�/param>
-        /// <param name="agvType">AGV绫诲瀷</param>
+        /// <param name="agv">AGV绫诲瀷</param>
         /// <returns></returns>
-        public static TN_Task BuildTask(TN_Location startLoc, TN_Location endLoc, string cntId, string type, int pri = 3, int agvType = 1) {
+        public static TN_Task BuildTask(TN_Location startLoc, TN_Location endLoc, string cntId, string type, int pri = 3, int agv = 1) {
             TN_Task TN_Task = new TN_Task() {
                 S_CODE = GenerateTaskNo(),
                 S_START_AREA = startLoc.S_AREA_CODE,
                 S_END_AREA = endLoc.S_AREA_CODE,
                 S_START_LOC = startLoc.S_CODE,
                 S_END_LOC = endLoc.S_CODE,
+                S_CNTR_CODE = cntId,
                 S_TYPE = type,
                 N_PRIORITY = pri,
-                N_SCHEDULE_TYPE = agvType,
+                N_SCHEDULE_TYPE = agv,
                 N_B_STATE = 0, // 浠诲姟鍒涘缓鏃�榛樿绛夊緟
-                S_CNTR_CODE = cntId,
             };
+
+            LogHelper.Info($"鍒涘缓浠诲姟:浠诲姟鍙�'{TN_Task.S_CODE}'");
 
             return TN_Task;
         }
 
+        /// <summary>
+        /// [ 鍒涘缓浠诲姟,骞朵笂閿�] ( 闇�‘淇漵tartLoc/endLoc涓嶄负null ; 涓嶄細妫�煡璐т綅S_CODE,S_AREA_CODE灞炴�鏄惁鍚堟硶 )
+        /// </summary>
+        /// <remarks>瑕佹眰 : (1) startLoc / endLoc 鈮�null<br/>(2) startLoc / endLoc 瀛樺湪 S_CODE , S_AREA_CODE</remarks>
+        /// <param name="startLoc">璧风偣璐т綅 : 鑷冲皯鎻愪緵 : S_CODE , S_AREA_CODE</param>
+        /// <param name="endLoc">缁堢偣璐т綅 : 鑷冲皯鎻愪緵 : S_CODE , S_AREA_CODE</param>
+        /// <param name="cntId">瀹瑰櫒鍙�/param>
+        /// <param name="type">浠诲姟绫诲瀷(鍚嶇О)</param>
+        /// <param name="pri">浼樺厛绾�/param>
+        /// <param name="agv">AGV绫诲瀷</param>
+        /// <returns></returns>
+        public static TN_Task BuildTaskWithLocLock(TN_Location startLoc, TN_Location endLoc, string cntId, string type, int pri = 3, int agv = 1) {
+            TN_Task TN_Task = new TN_Task() {
+                S_CODE = GenerateTaskNo(),
+                S_START_AREA = startLoc.S_AREA_CODE,
+                S_END_AREA = endLoc.S_AREA_CODE,
+                S_START_LOC = startLoc.S_CODE,
+                S_END_LOC = endLoc.S_CODE,
+                S_CNTR_CODE = cntId,
+                S_TYPE = type,
+                N_PRIORITY = pri,
+                N_SCHEDULE_TYPE = agv,
+                N_B_STATE = 0, // 浠诲姟鍒涘缓鏃�榛樿绛夊緟
+            };
+
+            LogHelper.Info($"鍒涘缓浠诲姟:浠诲姟鍙�'{TN_Task.S_CODE}'");
+
+            LockStartLoc(startLoc, TN_Task.S_CODE);
+            LockEndLoc(endLoc, TN_Task.S_CODE);
+
+            return TN_Task;
+        }
 
         internal static bool CheckActionRecordExist(string no, int code) {
             var db = new SqlHelper<TN_Task_Action>().GetInstance();
diff --git a/wms/WMSHelper.cs b/wms/WMSHelper.cs
index 6591b02..8bdebba 100644
--- a/wms/WMSHelper.cs
+++ b/wms/WMSHelper.cs
@@ -1,9 +1,17 @@
 锘縰sing System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Security.Cryptography;
 using System.Text;
 using System.Threading.Tasks;
 
+using HH.WCS.Mobox3.DSZSH.models;
+using HH.WCS.Mobox3.DSZSH.util;
+
+using Newtonsoft.Json;
+
+using static HH.WCS.Mobox3.DSZSH.api.ApiModel;
+
 namespace HH.WCS.Mobox3.DSZSH.wms {
     public class WMSHelper {
 

--
Gitblit v1.9.1