林豪 左 1 year ago
parent
commit
c2a52599d3

+ 46 - 0
ServiceCenter/Extensions/RedisExtension.cs

@@ -0,0 +1,46 @@
+using FreeRedis;
+
+namespace ServiceCenter.Extensions
+{
+    public static class RedisExtension
+    {
+        /// <summary>
+        /// 检查Redis中是否有对应key且value不为空
+        /// </summary>
+        /// <param name="redisClient">redis连接</param>
+        /// <param name="key">要检查的Key</param>
+        /// <returns>
+        /// 1.key不存在,创建这个key value默认为三个空格符。返回null
+        /// 2.key存在单value为空 返回null
+        /// 3.key存在value不为空 返回获取到的值
+        /// </returns>
+        public static string? Check(this RedisClient redisClient, string key)
+        {
+            var result = redisClient.Get(key);
+            if (!string.IsNullOrEmpty(result)) return result;
+            redisClient.Set(key, "   ");
+            Console.WriteLine($"无{key},创建并写入默认值:   ");
+            return null;
+        }
+
+        /// <summary>
+        /// 检查Redis中是否有对应key且value不为空
+        /// </summary>
+        /// <param name="redisClient">redis连接</param>
+        /// <param name="key">要检查的Key</param>
+        /// <param name="defaults">创建key是写入的默认值</param>
+        /// <returns>
+        /// 1.key不存在,创建这个key 并写入传入的默认值。返回默认值
+        /// 2.key存在单value为空 返回null
+        /// 3.key存在value不为空 返回获取到的值
+        /// </returns>
+        public static string? Check(this RedisClient redisClient, string key, string defaults)
+        {
+            var result = redisClient.Get(key);
+            if (!string.IsNullOrEmpty(result)) return result;
+            redisClient.Set(key, defaults);
+            Console.WriteLine($"无{key},创建并写入默认值:{defaults}");
+            return defaults;
+        }
+    }
+}

+ 9 - 0
ServiceCenter/Extensions/TypeExtension.cs

@@ -382,6 +382,9 @@ namespace ServiceCenter.Extensions
                 case GetFormatterEnum.yyyyMMddhhmmssfffffff:
                     return time.ToString("yyyy-MM-dd HH:mm:ss:fffffff");
 
+                case GetFormatterEnum.only:
+                    return time.ToString("yyyyMMddHHmmssfffffff");
+
                 default:
                     return time.ToString();
             }
@@ -670,5 +673,11 @@ namespace ServiceCenter.Extensions
         ///  yyyy-MM-dd hh:mm:ss:fffffff
         /// </summary>
         yyyyMMddhhmmssfffffff = 10,
+
+        /// <summary>
+        /// 用时间组成唯一值
+        ///  yyyyMMddhhmmssfffffff
+        /// </summary>
+        only = 11,
     }
 }

+ 22 - 40
ServiceCenter/Redis/RedisHub.cs

@@ -5,7 +5,7 @@ namespace ServiceCenter.Redis
     /// <summary>
     /// Redis
     /// </summary>
-    public static class RedisHub
+    public class RedisHub
     {
         /// <summary>
         /// 连接集合
@@ -17,7 +17,7 @@ namespace ServiceCenter.Redis
         /// </summary>
         public static string DefaultContextType { get; private set; } = null!;
 
-        /// <summary> 
+        /// <summary>
         /// 默认监控上下文类类型
         /// </summary>
         public static string MonitorContextType { get; private set; } = null!;
@@ -160,43 +160,25 @@ namespace ServiceCenter.Redis
             return ctx.Client;
         }
 
-        /// <summary>
-        /// 检查Redis中是否有对应key且value不为空
-        /// </summary>
-        /// <param name="redisClient">redis连接</param>
-        /// <param name="key">要检查的Key</param>
-        /// <returns>
-        /// 1.key不存在,创建这个key value默认为三个空格符。返回null
-        /// 2.key存在单value为空 返回null
-        /// 3.key存在value不为空 返回获取到的值
-        /// </returns>
-        public static string? Check(this RedisClient redisClient, string key)
-        {
-            var result = redisClient.Get(key);
-            if (!string.IsNullOrEmpty(result)) return result;
-            redisClient.Set(key, "   ");
-            Console.WriteLine($"无{key},创建并写入默认值:   ");
-            return null;
-        }
-
-        /// <summary>
-        /// 检查Redis中是否有对应key且value不为空
-        /// </summary>
-        /// <param name="redisClient">redis连接</param>
-        /// <param name="key">要检查的Key</param>
-        /// <param name="defaults">创建key是写入的默认值</param>
-        /// <returns>
-        /// 1.key不存在,创建这个key 并写入传入的默认值。返回默认值
-        /// 2.key存在单value为空 返回null
-        /// 3.key存在value不为空 返回获取到的值
-        /// </returns>
-        public static string? Check(this RedisClient redisClient, string key, string defaults)
-        {
-            var result = redisClient.Get(key);
-            if (!string.IsNullOrEmpty(result)) return result;
-            redisClient.Set(key, defaults);
-            Console.WriteLine($"无{key},创建并写入默认值:{defaults}");
-            return defaults;
-        }
+        ///// <summary>
+        /////  执行事务
+        ///// </summary>
+        ///// <param name="act"></param>
+        ///// <exception cref="Exception"></exception>
+        //public void Do(Action<RedisHub> act)
+        //{
+        //    if (!RedisClients.Any()) throw new Exception($"请调用{nameof(CreateContext)}方法设置设置数据库连接");
+        //    var db = new RedisHub();
+        //    try
+        //    {
+        //        act(db);//执行委托
+        //    }
+        //    catch (Exception ex)
+        //    {
+        //        db.Connect.RollbackTran();//回滚事务
+        //        //Console.WriteLine($"事务回滚记录:{ex.Message}:{ex.StackTrace}");
+        //        throw new Exception(ex.Message);
+        //    }
+        //}
     }
 }

+ 9 - 0
WCS.Entity/WCS_AgvTaskInfo.cs

@@ -25,6 +25,15 @@ namespace WCS.Entity
         [SugarColumn(ColumnDescription = "AGVID", Length = 50, IsNullable = true), DataMember(Order = 1)]
         public string AgvID { get; set; }
 
+        /// <summary>
+        ///  wcsTaskId
+        /// </summary>
+        [SugarColumn(ColumnDescription = "wcsTaskId", IsNullable = true), DataMember(Order = 2)]
+        public int TaskId { get; set; }
+
+        [Navigate(NavigateType.OneToOne, nameof(TaskId))]
+        public WCS_TaskInfo Task { get; set; }
+
         /// <summary>
         /// 任务类型
         /// </summary>

+ 6 - 0
WCS.Entity/WCS_TaskInfo.cs

@@ -262,6 +262,12 @@ namespace WCS.Entity
         [SugarColumn(ColumnDescription = "AGV任务号", IsNullable = true)]
         public int AgvTaskID { get; set; }
 
+        /// <summary>
+        ///  Agv任务信息
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(AgvTaskID))]
+        public WCS_AgvTaskInfo AgvTask { get; set; }
+
         /// <summary>
         /// 优先级
         /// </summary>

+ 6 - 0
WCS.Entity/WCS_TaskOld.cs

@@ -262,6 +262,12 @@ namespace WCS.Entity
         [SugarColumn(ColumnDescription = "AGV任务号", IsNullable = true)]
         public int AgvTaskID { get; set; }
 
+        /// <summary>
+        ///  Agv任务信息
+        /// </summary>
+        [Navigate(NavigateType.OneToOne, nameof(AgvTaskID))]
+        public WCS_AgvTaskInfo AgvTask { get; set; }
+
         /// <summary>
         /// 优先级
         /// </summary>

+ 1 - 0
WCS.Service/Program.cs

@@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting;
 using ServiceCenter.Redis;
 using ServiceCenter.WebApi;
 using System.Runtime.InteropServices;
+using ServiceCenter.Extensions;
 
 namespace WCS.Service
 {

+ 1 - 0
WCS.Service/Worker.cs

@@ -6,6 +6,7 @@ using ServiceCenter.Redis;
 using ServiceCenter.SqlSugars;
 using SqlSugar;
 using System.Text;
+using ServiceCenter.Extensions;
 using WCS.Core;
 using WCS.Entity;
 using WCS.WorkEngineering;

+ 2 - 1
WCS.WorkEngineering/Extensions/StationExtension.cs

@@ -1,4 +1,5 @@
-using ServiceCenter.Logs;
+using ServiceCenter.Extensions;
+using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using WCS.Core;
 using WCS.WorkEngineering.Protocol.Station;

+ 12 - 0
WCS.WorkEngineering/Extensions/TaskExtension.cs

@@ -92,6 +92,18 @@ namespace WCS.WorkEngineering.Extensions
             }
         }
 
+        /// <summary>
+        ///  更新表数据
+        /// </summary>
+        /// <param name="taskInfo"></param>
+        /// <param name="db"></param>
+        public static void Updateable(this WCS_TaskInfo taskInfo, SqlSugarScopeProvider db)
+        {
+            taskInfo.EditTime = DateTime.Now;
+            taskInfo.EditWho = "WCS";
+            db.Updateable(taskInfo).ExecuteCommand();
+        }
+
         ///// <summary>
         /////  获取出库任务
         ///// </summary>

+ 1 - 0
WCS.WorkEngineering/ProtocolProxy.cs

@@ -1,6 +1,7 @@
 using MessagePack;
 using Newtonsoft.Json;
 using ServiceCenter;
+using ServiceCenter.Extensions;
 using ServiceCenter.Redis;
 using WCS.Core;
 using WCS.WorkEngineering.Protocol.DataStructure;

+ 1 - 0
WCS.WorkEngineering/Systems/SrmSystems.cs

@@ -93,6 +93,7 @@ namespace WCS.WorkEngineering.Systems
                             switch (task.OutType)
                             {
                                 case OutTypeEnum.自动出库任务:
+                                    //TODO:区分站台,判断任务是否结束
                                     task.Status = Entity.TaskStatus.ConveyorExecution;
                                     var dev = new Station(Device.All.FirstOrDefault(v => v.Code == task.SrmStation) ?? throw new KnownException($"未找到{task.SrmStation}信息", LogLevelEnum.High), this.World);
                                     dev.Data.TaskNumber = task.ID;

+ 41 - 12
WCS.WorkEngineering/Systems/机台叫料生成AGV任务.cs

@@ -1,9 +1,14 @@
-using System.ComponentModel;
+using ServiceCenter.Extensions;
+using ServiceCenter.SqlSugars;
+using System.ComponentModel;
 using WCS.Core;
+using WCS.Entity;
+using WCS.WorkEngineering.Extensions;
 using WCS.WorkEngineering.Protocol.Station;
 using WCS.WorkEngineering.WebApi.Controllers;
 using WCS.WorkEngineering.Worlds;
 using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
+using TaskStatus = WCS.Entity.TaskStatus;
 
 namespace WCS.WorkEngineering.Systems
 {
@@ -17,21 +22,45 @@ namespace WCS.WorkEngineering.Systems
 
         public override void Do(Device<IStation520, IStation521, IStation523> obj)
         {
-            var res = AgvApi.测试路径("2533", "12346");
+            //var res = AgvApi.测试路径("2533", "12346");
             //var res = AgvApi.机台叫料("2534", "LX32", Guid.NewGuid().ToString().Replace("-", ""));
             //var res = AgvApi.托盘回库("LX32", Guid.NewGuid().ToString().Replace("-",""));
 
-            //if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status)) return;
-            //if (!obj.Data3.Status.HasFlag(StationStatus.Auto)) return;
+            if (!obj.Data3.Status.HasFlag(StationStatus.PH_Status)) return;
+            if (!obj.Data3.Status.HasFlag(StationStatus.Low_Station_2)) return;
+            if (!obj.Data3.Status.HasFlag(StationStatus.Auto)) return;
 
-            //SqlSugarHelper.Do(_db =>
-            //{
-            //    var db = _db.Default;
-            //    var task = db.Queryable<WCS_TaskInfo>().Single(x => x.ID == obj.Data.TaskNumber);
-            //    if (task == null) return;
-            //    if (task.Status != TaskStatus.ConveyorExecution) return;
-            //    //开始下发任务.0
-            //});
+            SqlSugarHelper.Do(_db =>
+            {
+                var db = _db.Default;
+                var task = db.Queryable<WCS_TaskInfo>().Single(x => x.ID == obj.Data.TaskNumber);
+                if (task == null) return;
+                if (task.Status != Entity.TaskStatus.ConveyorExecution) return;
+                //开始创建AGV任务
+                var agvTask = db.Queryable<WCS_AgvTaskInfo>().SplitTable(x => x.Take(2)).Single(x => x.TaskId == task.ID);
+                if (agvTask == null)
+                {
+                    db.Insertable(new WCS_AgvTaskInfo()
+                    {
+                        ID = task.ID,
+                        TaskType = AGVTaskType.CallMaterial,
+                        Status = AGVTaskStatus.NewBuild,
+                        TaskId = task.ID,
+                        Position = task.WorkBench,
+                        Station = obj.Entity.Code,
+                    }).SplitTable().ExecuteReturnSnowflakeId();
+                }
+                if (agvTask.Status != AGVTaskStatus.NewBuild) return;
+                var AgvId = DateTime.Now.GetFormat(GetFormatterEnum.only) /*SnowFlakeSingle.instance.getID()*/;
+
+                AgvApi.测试路径(obj.Entity.Code, AgvId);
+                agvTask.Status = AGVTaskStatus.Confirm;
+                agvTask.AgvStatus = AGVTaskStatus.Confirm;
+                db.Updateable(agvTask).SplitTable().ExecuteCommand();
+                task.Status = TaskStatus.AGVExecution;
+                task.Updateable(db);
+                task.AddWCS_TASK_DTL(db, obj.Entity.Code, "AGV", $"任务下发至AGV{AgvId}");
+            });
         }
 
         public override bool Select(Device dev)

+ 18 - 8
WCS.WorkEngineering/Systems/环形库/机械臂cs.cs

@@ -260,22 +260,28 @@ namespace WCS.WorkEngineering.Systems
                 arrOut = arrOut.Where(v => v.Data3.Status.HasFlag(StationStatus.PH_Status)).ToList();//无光电
                 if (!arrOut.Any()) throw new KnownException($"[{obj.Entity.Code}]等待出库任务输送到位", LogLevelEnum.Mid);
 
-                List<WCS_TaskInfo> taskInfoList = new List<WCS_TaskInfo>();
+                var taskInfoList = new List<WCS_TaskInfo>();
                 string nextAdd = "";
 
                 SqlSugarHelper.Do(db =>
                         {
                             //所有出库点设备号,即
                             var allOutCode = arrOut.Select(v => v.Entity.Code).ToList();
-
+                            //TODO:两个工位同时码垛,并不会一个执行一次,只有一个托盘任务全部执行完毕,才会继续执行下一个,设备号较小的码垛工位会优先执行
                             var taskInfos = db.Default.Queryable<WCS_TaskInfo>().Where(v => v.Type == TaskType.OutDepot && v.Status == Entity.TaskStatus.WaitingToExecute)
                                                                                                     .Where(v => allOutCode.Contains(v.SrmStation)).ToList()
-                                                                                                    .OrderBy(x => x.ProdLine)
-                                                                                                    .ThenBy(x => x.AddTime)
-                                                                                                    .Take(2);
-                            if (taskInfos!.MinBy(x => x.Depth).Depth + 1 != taskInfos.MaxBy(x => x.Depth).Depth)
+                                                                                                    .OrderBy(x => x.SrmStation.ToInt()) //按照码垛站台号进行一次排序
+                                                                                                    .ThenBy(x => x.ProdLine) //码垛从小到大
+                                                                                                    .ThenBy(x => x.AddTime)//任务生成时间从早到晚
+                                                                                                    .Take(2).ToList();
+                            if (taskInfos.Count == 2) //有两个任务
                             {
-                                taskInfos = taskInfos!.OrderBy(x => x.ProdLine).Take(1);
+                                var minDepth = taskInfos!.MinBy(x => x.Depth);
+                                var maxDepth = taskInfos.MaxBy(x => x.Depth);
+                                //物料号不同时只执行一个任务 不同的轮子物料号也不同
+                                if (minDepth.MatCode != maxDepth.MatCode) taskInfos = taskInfos.OrderBy(x => x.ProdLine).Take(1).ToList();
+                                //深度之和等于6(机械臂当前无法同时执行两个三深度的取货任务)
+                                else if (taskInfos.Sum(x => x.Depth) == 6) taskInfos = taskInfos.OrderBy(x => x.ProdLine).Take(1).ToList();
                             }
 
                             foreach (var task in taskInfos)
@@ -286,7 +292,7 @@ namespace WCS.WorkEngineering.Systems
                                 nextAdd = task.SrmStation;
                                 db.Default.Updateable(task).ExecuteCommand();
                                 task.AddWCS_TASK_DTL(db.Default, task.Device, task.SrmStation, "任务下发机械臂执行");
-                                taskInfoList!.Add(task);
+                                taskInfoList.Add(task);
                             }
                         });
 
@@ -296,6 +302,7 @@ namespace WCS.WorkEngineering.Systems
                 {
                     case 1:
                         var task = taskInfoList.FirstOrDefault();
+
                         //下发任务
                         obj.Data.TaskNumber1 = task.ID;
                         obj.Data.SLine1 = task.Line.ToShort();
@@ -322,7 +329,9 @@ namespace WCS.WorkEngineering.Systems
                         break;
 
                     case 2:
+
                         taskInfoList = taskInfoList.OrderBy(x => x.Depth).ToList();
+
                         //一工位取深度较大的任务
                         var taskInfo = taskInfoList[1];
                         obj.Data.TaskNumber1 = taskInfo.ID;
@@ -352,6 +361,7 @@ namespace WCS.WorkEngineering.Systems
                         break;
 
                     default:
+
                         throw new KnownException($"无法执行多个任务", LogLevelEnum.Mid);
                 }
             }

+ 3 - 2
WCS.WorkEngineering/WebApi/Controllers/AgvApi.cs

@@ -1,4 +1,5 @@
-using ServiceCenter.Logs;
+using ServiceCenter.Extensions;
+using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using ServiceCenter.WebApi;
 using WCS.WorkEngineering.WebApi.Models.AGV;
@@ -23,7 +24,7 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         {
             get
             {
-                _AgvUrl ??= RedisHub.Default.Check("AgvUrl");
+                _AgvUrl ??= RedisHub.Default.Check("AgvUrl")!;
                 if (string.IsNullOrEmpty(_AgvUrl))
                 {
                     throw new KnownException($"请在Redis配置AgvUrl", LogLevelEnum.High);

+ 54 - 66
WCS.WorkEngineering/WebApi/Controllers/AgvController.cs

@@ -171,94 +171,82 @@ namespace WCS.WorkEngineering.WebApi.Controllers
         {
             var key = $"WCS:Lock:AGV:{nameof(AgvCallback)}";
             var res = new AgvCallbackResponse() { code = AgvResponseCode.Success, message = "失败" };
-            return res;
+
             try
             {
-                if (RedisHub.Default.Get(key) != null)
+                if (RedisHub.Default.Exists(key))
                 {
                     res.code = AgvResponseCode.Error;
                     res.message = $"[{nameof(AgvCallback)}]--触发并发管控";
+                    return res;
                 }
-                else
+                RedisHub.Default.Expire(key, 60);
+
+                SqlSugarHelper.Do(db =>
                 {
-                    RedisHub.Default.Set(key, nameof(AgvCallback));
-                    WCS_TaskInfo taskInfo = null;
-                    try
+                    //跟据AGVid找到对应的AGV任务
+                    var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2))
+                        .First(v => v.AgvID == reqDto.taskCode && v.Status < AGVTaskStatus.MissionCompleted);
+                    if (agvTask == null)
                     {
-                        SqlSugarHelper.Do(db =>
-                        {
-                            //跟据AGVid找到对应的AGV任务
-                            var agvTask = db.Default.Queryable<WCS_AgvTaskInfo>().SplitTable(tabs => tabs.Take(2)).First(v => v.AgvID == reqDto.taskCode && v.Status < AGVTaskStatus.MissionCompleted);
-                            if (agvTask == null)
-                            {
-                                res.code = AgvResponseCode.Fail;
-                                res.message = "未找到对应的AGV任务";
-                            }
-                            else
-                            {
-                                switch (reqDto.method)
-                                {
-                                    //case "start": //表示请求巷道
-                                    //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
-                                    //    break;
-
-                                    //case "end": //表示请求巷道
-                                    //    agvTask.Status = AGVTaskStatus.RequestOrPermission1;
-                                    //    break;
-
-                                    case "applyContinue": //表示请求巷道
-                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
-                                        break;
+                        res.code = AgvResponseCode.Fail;
+                        res.message = "未找到对应的AGV任务";
+                        return;
+                    }
+                    switch (reqDto.method)
+                    {
+                        case "applyContinue": //表示请求巷道
+                            agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission1;
+                            break;
 
-                                    case "applySecurity": //表示请求放货或取货
-                                        agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission2;
-                                        break;
+                        case "applySecurity": //表示请求放货或取货
+                            agvTask.AgvStatus = AGVTaskStatus.RequestOrPermission2;
+                            break;
 
-                                    case "hjend_2": //补空任务完成
-                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                        break;
+                        case "hjend_2": //补空任务完成
+                            agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                            break;
 
-                                    case "endhjBM": //取满任务完成
-                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                        break;
+                        case "endhjBM": //取满任务完成
+                            agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                            break;
 
-                                    case "end": //二楼出满任务完成
-                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                        break;
+                        case "end": //二楼出满任务完成
+                            agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                            break;
 
-                                    case "tcEnd": //机台补空任务完成
-                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                        break;
+                        case "tcEnd": //机台补空任务完成
+                            agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                            break;
 
-                                    case "exc_end": //异常信息上抛-值不匹配
-                                        agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
-                                        break;
+                        case "exc_end": //异常信息上抛-值不匹配
+                            agvTask.AgvStatus = AGVTaskStatus.MissionCompleted;
+                            break;
 
-                                    case "outbin": //小车退出取货位
-                                        agvTask.AgvStatus = AGVTaskStatus.Complete3;
-                                        break;
+                        case "outbin": //小车退出取货位
+                            agvTask.AgvStatus = AGVTaskStatus.Complete3;
+                            break;
 
-                                    case "cancel": //取消任务
-                                                   //agvTask.AgvStatus = AGVTaskStatus.Cancel;
-                                        break;
-                                }
-                                db.Default.Updateable(agvTask).SplitTable().ExecuteCommand();
-                                res.code = AgvResponseCode.Success;
-                                res.message = "成功";
-                            }
-                        });
-                    }
-                    catch (Exception ex)
-                    {
-                        res.code = AgvResponseCode.Error;
-                        res.message = ex.Message;
+                        case "cancel": //取消任务
+                            //agvTask.AgvStatus = AGVTaskStatus.Cancel;
+                            break;
                     }
-                }
+
+                    db.Default.Updateable(agvTask).SplitTable().ExecuteCommand();
+                    res.code = AgvResponseCode.Success;
+                    res.message = "成功";
+                });
+            }
+            catch (Exception ex)
+            {
+                res.code = AgvResponseCode.Error;
+                res.message = ex.Message;
             }
             finally
             {
                 RedisHub.Default.Del(key);
             }
+
             return res;
         }
     }

+ 2 - 1
WCS.WorkEngineering/WebApi/Controllers/IwmsApi.cs

@@ -1,4 +1,5 @@
-using ServiceCenter.Logs;
+using ServiceCenter.Extensions;
+using ServiceCenter.Logs;
 using ServiceCenter.Redis;
 using ServiceCenter.WebApi;
 using WCS.WorkEngineering.WebApi.Models.AGV;