.vs/HH.WCS.Mobox3.AnGang/FileContentIndex/05336dc4-4629-4a97-bb9a-4516a380cd0d.vsidxBinary files differ
.vs/HH.WCS.Mobox3.AnGang/FileContentIndex/1a441e71-f454-4033-af8e-db39c2339a05.vsidxBinary files differ
.vs/HH.WCS.Mobox3.AnGang/FileContentIndex/bd85daa8-32a5-4c87-9f8f-b1ed513fa1f8.vsidxBinary files differ
.vs/HH.WCS.Mobox3.AnGang/FileContentIndex/c94de693-d780-402e-840f-826433af2f96.vsidxBinary files differ
AppStart/Config.cs
File was deleted AppStart/Settings.cs
File was deleted App_Start/Startup.cs
App_Start/SwaggerConfig.cs
App_Start/SwaggerControllerDescProvider.cs
Consts/AgvStateCode.cs
File was deleted Consts/AgvStateName.cs
File was deleted Consts/AreaCode.cs
File was deleted Consts/LockStateCode.cs
File was deleted Consts/LockStateName.cs
File was deleted Consts/TaskName.cs
File was deleted Controllers/ApiModel.cs
File was deleted Controllers/DebugController.cs
File was deleted Controllers/MoboxController.cs
File was deleted Dispatch/GZRobot.cs
@@ -2,26 +2,19 @@ using System.Collections.Generic; using System.IdentityModel.Protocols.WSTrust; using System.Threading.Tasks; using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Helper; using HH.WCS.Mobox3.AnGang.Helpers; using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.Services; using HH.WCS.Mobox3.AnGang.core; using HH.WCS.Mobox3.AnGang.models; using Newtonsoft.Json; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using static HH.WCS.Mobox3.AnGang.Controllers.ApiModel; using static HH.WCS.Mobox3.AnGang.Dtos.Request.AgvRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Response.AgvResponse; namespace HH.WCS.Mobox3.AnGang.Dispatch { namespace HH.WCS.Mobox3.AnGang.dispatch { /// <summary> /// 国自调度辅助类 /// </summary> public class GZRobot { private static readonly HttpHelper apiHelper = new HttpHelper(); private static readonly string baseUrl = AppStart.Settings.Config.RCSApiUrl;//配置文件获取国自调度地址 private static readonly string baseUrl = Settings.RCSApiUrl;//配置文件获取国自调度地址 //private static readonly string logName = "guozi"; public static List<IOState> GetIO() { var result = apiHelper.Get(baseUrl + "api/engine/view/iostates/"); @@ -33,7 +26,6 @@ var result = apiHelper.Post(baseUrl + "api/engine/tasks/iostates/", JsonConvert.SerializeObject(data)); var dataResult = JsonConvert.DeserializeObject<gzResult<IOStatesInfoResult>>(result); } public static int CreateOrder(string taskNo, int priority, string param, string ts = "churuku", string created_user = "hanhe") { LogHelper.Info($"CreateOrder参数信息:taskNo:{taskNo},priority:{priority},param:{param},ts:{ts},created_user:{created_user}", "API"); @@ -157,7 +149,14 @@ if (agv.state != 0) { agv.task_no = model.orderName; agv.forklift_no = model.agvIDList; AgvService.OperateAgvTaskStatus(agv); WCSCore.OperateAgvTaskStatus(agv); } else { result.resultCode = 2; result.orderID = model.orderID; result.msg = "反馈订单状态失败,orderStatus参数不正确"; LogHelper.Info(result.msg, "API"); return result; } result.resultCode = 0; Dispatch/HanAo.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Web.Services.Description; namespace HH.WCS.Mobox3.AnGang.Dispatch { namespace HH.WCS.Mobox3.AnGang.dispatch { /// <summary> /// 国自调度辅助类 /// </summary> Dispatch/NDC.cs
@@ -5,7 +5,7 @@ using Newtonsoft.Json; namespace HH.WCS.Mobox3.AnGang.Dispatch { namespace HH.WCS.Mobox3.AnGang.dispatch { public class NDC { private static HostToAGV callClient = null; Dispatch/NDCApi.cs
@@ -1,19 +1,18 @@ using System; using System.Collections.Generic; using HH.WCS.Mobox3.AnGang.AppStart; using HH.WCS.Mobox3.AnGang.config; using Newtonsoft.Json; namespace HH.WCS.Mobox3.AnGang.Dispatch { namespace HH.WCS.Mobox3.AnGang.dispatch { public class NDCApi { public static string NDCApiUrl { set; get; } static NDCApi() { NDCApiUrl = Settings.Config.NDCApiUrl; NDCApiUrl = Settings.NDCApiUrl; } Dispatch/NDCHelper.cs
@@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; namespace HH.WCS.Mobox3.AnGang.Dispatch namespace HH.WCS.Mobox3.AnGang.dispatch { public class NDCHelper { Dtos/Request/AgvRequest.cs
File was deleted Dtos/Request/DebugRequest.cs
File was deleted Dtos/Request/ErpRequest.cs
File was deleted Dtos/Request/MoboxRequest.cs
File was deleted Dtos/Response/AgvResponse.cs
File was deleted Dtos/Response/DebugResponse.cs
File was deleted Dtos/Response/ErpResponse.cs
File was deleted Dtos/Response/MoboxResponse.cs
File was deleted HH.WCS.Mobox3.AnGang.csproj
@@ -257,76 +257,60 @@ </Reference> </ItemGroup> <ItemGroup> <Compile Include="AppStart\Config.cs" /> <Compile Include="Consts\AgvStateCode.cs" /> <Compile Include="Consts\AgvStateName.cs" /> <Compile Include="Consts\AreaCode.cs" /> <Compile Include="Consts\LockStateCode.cs" /> <Compile Include="Consts\LockStateName.cs" /> <Compile Include="Consts\TaskName.cs" /> <Compile Include="Controllers\DebugController.cs" /> <Compile Include="Controllers\ErpController.cs" /> <Compile Include="Controllers\MoboxController.cs" /> <Compile Include="Controllers\AgvController.cs" /> <Compile Include="Controllers\ApiModel.cs" /> <Compile Include="AppStart\SwaggerControllerDescProvider.cs" /> <Compile Include="Devices\SnapDevice.cs" /> <Compile Include="Devices\SnapManager.cs" /> <Compile Include="Dtos\Request\DebugRequest.cs" /> <Compile Include="Dtos\Request\ErpRequest.cs" /> <Compile Include="Dtos\Response\DebugResponse.cs" /> <Compile Include="Dtos\Response\ErpResponse.cs" /> <Compile Include="Helpers\AgvHelper.cs" /> <Compile Include="Helpers\DbHelper.cs" /> <Compile Include="Models\DebugModel.cs" /> <Compile Include="Models\TN_Inbound_Order.cs" /> <Compile Include="Models\TN_Outbound_Order.cs" /> <Compile Include="ServiceCore\WMSCore.cs" /> <Compile Include="Models\BaseModel.cs" /> <Compile Include="Services\DebugService.cs" /> <Compile Include="Devices\ModbusHelper.cs" /> <Compile Include="Devices\OpcUaHelper.cs" /> <Compile Include="Devices\PlcHelper.cs" /> <Compile Include="Devices\S7Helper.cs" /> <Compile Include="Devices\TcpClient.cs" /> <Compile Include="Devices\TcpServer.cs" /> <Compile Include="Dispatch\GZRobot.cs" /> <Compile Include="Dispatch\HanAo.cs" /> <Compile Include="Dispatch\NDC.cs" /> <Compile Include="ServiceCore\Monitor.cs" /> <Compile Include="Dispatch\NDCApi.cs" /> <Compile Include="Dtos\Request\AgvRequest.cs" /> <Compile Include="Dtos\Request\MoboxRequest.cs" /> <Compile Include="Dtos\Response\AgvResponse.cs" /> <Compile Include="Dtos\Response\MoboxResponse.cs" /> <Compile Include="Models\TN_CG_Detail.cs" /> <Compile Include="Models\TN_CAR_IN.cs" /> <Compile Include="Models\TN_Container.cs" /> <Compile Include="Models\TN_Location.cs" /> <Compile Include="Models\TN_Loc_Container.cs" /> <Compile Include="Models\TN_WorkOrder.cs" /> <Compile Include="Models\TN_Task.cs" /> <Compile Include="Models\TN_Task_Action.cs" /> <Compile Include="Helpers\DeviceProcess.cs" /> <Compile Include="ServiceCore\WCSCore.cs" /> <Compile Include="Controllers\WmsController.cs" /> <Compile Include="Dispatch\HostToAGV.cs" /> <Compile Include="Helpers\TaskHelper.cs" /> <Compile Include="Services\AgvService.cs" /> <Compile Include="Services\ErpService.cs" /> <Compile Include="Services\MoboxService.cs" /> <Compile Include="Helpers\LogHelper.cs" /> <Compile Include="Helpers\ContainerHelper.cs" /> <Compile Include="Helpers\LocationHelper.cs" /> <Compile Include="Helpers\WMSHelper.cs" /> <Compile Include="Helpers\SysHelper.cs" /> <Compile Include="api\ApiHelper.cs" /> <Compile Include="api\DebugController.cs" /> <Compile Include="api\ErpController.cs" /> <Compile Include="api\MoboxController.cs" /> <Compile Include="api\AgvController.cs" /> <Compile Include="api\ApiModel.cs" /> <Compile Include="App_Start\SwaggerControllerDescProvider.cs" /> <Compile Include="device\SnapDevice.cs" /> <Compile Include="device\SnapManager.cs" /> <Compile Include="models\TN_Count_CG_Detail.cs" /> <Compile Include="models\TN_Count_Diff.cs" /> <Compile Include="models\TN_Count_Order.cs" /> <Compile Include="models\TN_Count_Plan.cs" /> <Compile Include="models\TN_Inbound_Order.cs" /> <Compile Include="models\TN_Outbound_Order.cs" /> <Compile Include="core\WMSCore.cs" /> <Compile Include="models\BaseModel.cs" /> <Compile Include="device\ModbusHelper.cs" /> <Compile Include="device\OpcUaHelper.cs" /> <Compile Include="device\PlcHelper.cs" /> <Compile Include="device\S7Helper.cs" /> <Compile Include="device\TcpClient.cs" /> <Compile Include="device\TcpServer.cs" /> <Compile Include="dispatch\GZRobot.cs" /> <Compile Include="dispatch\HanAo.cs" /> <Compile Include="dispatch\NDC.cs" /> <Compile Include="core\Monitor.cs" /> <Compile Include="dispatch\NDCApi.cs" /> <Compile Include="models\TN_CG_Detail.cs" /> <Compile Include="models\TN_CAR_IN.cs" /> <Compile Include="models\TN_Container.cs" /> <Compile Include="models\TN_Location.cs" /> <Compile Include="models\TN_Loc_Container.cs" /> <Compile Include="models\TN_WorkOrder.cs" /> <Compile Include="models\TN_Task.cs" /> <Compile Include="models\TN_Task_Action.cs" /> <Compile Include="process\DeviceProcess.cs" /> <Compile Include="core\WCSCore.cs" /> <Compile Include="api\WmsController.cs" /> <Compile Include="dispatch\HostToAGV.cs" /> <Compile Include="util\LogHelper.cs" /> <Compile Include="wms\ContainerHelper.cs" /> <Compile Include="wms\LocationHelper.cs" /> <Compile Include="wms\WMSHelper.cs" /> <Compile Include="wms\SYSHelper.cs" /> <Compile Include="process\TaskProcess.cs" /> <Compile Include="Program.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="AppStart\Settings.cs" /> <Compile Include="AppStart\Startup.cs" /> <Compile Include="Dispatch\NDCHelper.cs" /> <Compile Include="Helpers\HttpHelper.cs" /> <Compile Include="Helpers\WCSHelper.cs" /> <Compile Include="util\Settings.cs" /> <Compile Include="App_Start\Startup.cs" /> <Compile Include="dispatch\NDCHelper.cs" /> <Compile Include="util\HttpHelper.cs" /> <Compile Include="wms\WCSHelper.cs" /> <Compile Include="util\SqlHelper.cs" /> </ItemGroup> <ItemGroup> <None Include=".editorconfig" /> Helpers/AgvHelper.cs
File was deleted Helpers/DbHelper.cs
File was deleted Models/BaseModel.cs
@@ -2,7 +2,7 @@ using SqlSugar; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { /// <summary> /// 【框架】模板抽象类:基本表数据模型 /// </summary> Models/DebugModel.cs
File was deleted Models/TN_CAR_IN.cs
@@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Models namespace HH.WCS.Mobox3.AnGang.models { /// <summary> /// 容器生产车数关联子表 Models/TN_CG_Detail.cs
@@ -1,6 +1,6 @@ using SqlSugar; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { /// <summary> /// 物料-容器 关系表 /// </summary> @@ -37,7 +37,6 @@ /// 数量:这里当做重量 /// </summary> public float F_QTY { get; set; } = 0f; /// <summary> /// 图片链接 Models/TN_Container.cs
@@ -1,7 +1,7 @@ using SqlSugar; using System.Collections.Generic; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { [SugarTable("TN_Container")] public class TN_Container : BaseModel { public string S_CODE { get; set; } Models/TN_Inbound_Order.cs
@@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { public class TN_Inbound_Order : BaseModel { /// <summary> /// 储位码 Models/TN_Loc_Container.cs
@@ -1,7 +1,7 @@ using SqlSugar; using System.Collections.Generic; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { //TN_Loc_Container //LocCntrRel [SugarTable("TN_Loc_Container")] Models/TN_Location.cs
@@ -1,7 +1,7 @@ using SqlSugar; using System.Collections.Generic; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { [SugarTable("TN_Location")] public class TN_Location : BaseModel { Models/TN_Outbound_Order.cs
@@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { public class TN_Outbound_Order : BaseModel { /// <summary> /// 储位码 Models/TN_Task.cs
@@ -1,7 +1,7 @@ using SqlSugar; using System; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { [SugarTable("TN_Task")] public class TN_Task : BaseModel { Models/TN_Task_Action.cs
@@ -1,6 +1,6 @@ using SqlSugar; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { [SugarTable("TN_Task_Action")] public class TN_Task_Action : BaseModel { Models/TN_WorkOrder.cs
@@ -1,6 +1,6 @@ using SqlSugar; namespace HH.WCS.Mobox3.AnGang.Models { namespace HH.WCS.Mobox3.AnGang.models { /// <summary> /// 生产工单 /// </summary> Program.cs
@@ -3,8 +3,7 @@ using System.Threading; using System.Threading.Tasks; using HH.WCS.Mobox3.AnGang.AppStart; using HH.WCS.Mobox3.AnGang.Devices; using HH.WCS.Mobox3.AnGang.device; using Microsoft.Owin.Hosting; @@ -59,7 +58,7 @@ Console.WriteLine("Startup ApiController"); Task.Run(() => { var url = Settings.Config.WebApiUrl; var url = Settings.WebApiUrl; Console.WriteLine(url); using (WebApp.Start<Startup>(url)) { @@ -74,8 +73,8 @@ /// </summary> private static void StartTcp() { var tcpServerIP = Settings.Config.TCPServerIP; var tcpServerPort = Settings.Config.TCPServerPort; var tcpServerIP = Settings.TCPServerIP; var tcpServerPort = Settings.TCPServerPort; new TcpServer(tcpServerIP, tcpServerPort); } @@ -115,8 +114,7 @@ } private static void StartSnap() { //new SnapManager(Settings.Snap); new SnapManager(Settings.Config.Snap[0]); new SnapManager(Settings.Snaps[0]); } public class WorkThread @@ -127,11 +125,7 @@ // 添加任务推送线程 //tasks.Add(GetTask(WCSCore.Dispatch)); ////添加自定义线程 //tasks.Add(GetTask(Monitor.CheckEmptyCnt));//检测空托盘 ////根据S7/Modbus协议判断输送线的信号 原材料产线库区=>满托缓存库区,空托缓存库区=>原材料产线库区 //tasks.Add(GetTask(Monitor.CheckS7Devices)); Task.WaitAll(tasks.ToArray()); } ServiceCore/Monitor.cs
File was deleted ServiceCore/WCSCore.cs
File was deleted Services/DebugService.cs
File was deleted Services/ErpService.cs
File was deleted Services/MoboxService.cs
File was deleted api/AgvController.cs
File was renamed from Controllers/AgvController.cs @@ -1,21 +1,19 @@ using HH.WCS.Mobox3.AnGang.ServiceCore; using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.core; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.process; using HH.WCS.Mobox3.AnGang.Helper; using HH.WCS.Mobox3.AnGang.wms; using Newtonsoft.Json; using System.Collections.Generic; using System.Reflection; using System.Web.Http; using static HH.WCS.Mobox3.AnGang.Dispatch.NDC; using static HH.WCS.Mobox3.AnGang.dispatch.NDC; using System.Linq; using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Services; using static HH.WCS.Mobox3.AnGang.Dtos.Request.AgvRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Response.AgvResponse; using static HH.WCS.Mobox3.AnGang.Controllers.ApiModel; namespace HH.WCS.Mobox3.AnGang.Controllers using static HH.WCS.Mobox3.AnGang.api.ApiModel; namespace HH.WCS.Mobox3.AnGang.api { /// <summary> /// 设备信息上报(hosttoagv上报、杭奥堆垛机、国自agv) @@ -55,7 +53,7 @@ [HttpPost] [Route("safetyInteraction")] public ReturnResult SafetyInteraction(SafetyInteractionInfo model) { return AgvService.SafetyInteraction(model); return WCSCore.SafetyInteraction(model); } } } api/ApiHelper.cs
New file @@ -0,0 +1,612 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.util; using HH.WCS.Mobox3.AnGang.wms; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using static HH.WCS.Mobox3.AnGang.api.OtherModel; namespace HH.WCS.Mobox3.AnGang.api { public class ApiHelper { /// <summary> /// 产品入库(PDA) /// </summary> /// <param name="model"></param> /// <returns></returns> internal static SimpleResult Inbound(InboundInfo model) { var taskName = TaskName.产品入库; var db = new SqlHelper<object>().GetInstance(); try { // 起点位置必须:为空、无锁、启用、属于收发区域 var startLoc = db.Queryable<TN_Location>() .Where(a => a.S_CODE == model.StartLoc) .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") .Where(a => a.N_CURRENT_NUM == 0) .Where(a => a.S_AREA_CODE == "SFQ") .First(); if (startLoc == null) { return NewSimpleResult(1, $"起点位置{model.StartLoc}不存在!"); } // 容器 ID 和 物料 ID 未指定,由系统直接生成 var cntId = Guid.NewGuid().ToString("D"); var CgId = Guid.NewGuid().ToString("D"); // 初始是没有绑定信息的,先将起点位置与容器绑定,容器与物料绑定 var locCntrRel = new TN_Loc_Container() { S_LOC_CODE = startLoc.S_CODE, S_CNTR_CODE = cntId, }; var cgDetail = new TN_CG_Detail() { S_ITEM_CODE = CgId, S_CNTR_CODE = cntId, }; var endLocCode = "0"; // 假的默认终点地址 // 指定货位排号(不能为空、空字符串或空格) if (model.Row != null && model.Row.Trim() != "") { endLocCode = model.Row; // 用排号字符串当做假地址 if (!int.TryParse(model.Row.Trim(), out int row)) { return NewSimpleResult(2, $"{model.Row} 不合法:无法转成整数类型"); } // 货架排号只能是 0 - 8 if (row <= 0 || row > 8) { return NewSimpleResult(2, $"货架号 {model.Row} 必须是1-8之间的整数"); } } var task = WCSHelper.BuildInboundTask(startLoc, endLocCode, cntId); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 // 无论是否选择终点货架,都等到称重之后再计算终点货位 using (var tran = db.Ado.UseTran()) { if (db.Insertable<TN_Loc_Container>(locCntrRel).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"插入货位容器关系表失败:货位{locCntrRel.S_LOC_CODE},容器{locCntrRel.S_CNTR_CODE}"); } if (db.Insertable<TN_CG_Detail>(cgDetail).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"插入容器货品明细表失败:容器{cgDetail.S_CNTR_CODE},物料{cgDetail.S_ITEM_CODE}"); } if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"更新起点货位锁状态失败:起点货位{startLoc.S_CODE}"); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成任务 {taskName} 失败:容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLocCode} ,终点货位未指定"); } tran.CommitTran(); return NewSimpleResult(0, $"生成任务 {taskName} 成功:容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLocCode} ,终点货位未指定"); } } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// <summary> /// PDA选择终点货位 /// </summary> /// <param name="model"></param> /// <returns></returns> internal static SimpleResult SelectLocation(SelectLocationInfo model) { var db = new SqlHelper<object>().GetInstance(); try { // 任务号存在:终点货架和终点位置为空,且任务为产品入库(PDA) var task = db.Queryable<TN_Task>() .Where(a => a.S_B_STATE == "取货完成" && a.S_TYPE == TaskName.产品入库) .OrderBy(a => a.T_CREATE, SqlSugar.OrderByType.Desc).First(); if (task == null) { return NewSimpleResult(2, $"当前不存在状态为 取货完成 的 产品入库 任务"); } if (task.S_END_LOC != null && task.S_END_LOC != "0") { return NewSimpleResult(3, $"该任务已有终点"); } var cgDetail = db.Queryable<TN_CG_Detail>() .Where(a => a.S_CNTR_CODE == task.S_CNTR_CODE).First(); if (cgDetail == null) { return NewSimpleResult(4, $"托盘物料不存在"); } var endLoc = new TN_Location(); if (cgDetail.F_QTY > 1500) { // 重量超过1.5t,需要选择1-3层货架 endLoc = db.Queryable<TN_Location>() .Where(a => a.S_CODE == model.endLoc) .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") .Where(a => a.N_CURRENT_NUM == 0) .Where(a => a.S_AREA_CODE == "HJQ") .Where(a => a.N_LAYER <= 3) .First(); } else if (cgDetail.F_QTY > 0) { endLoc = db.Queryable<TN_Location>() .Where(a => a.S_CODE == model.endLoc) .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") .Where(a => a.N_CURRENT_NUM == 0) .Where(a => a.S_AREA_CODE == "HJQ") //.Where(a => a.N_LAYER <= 3) .First(); } else { return NewSimpleResult(5, $"物料重量信息不合法:{cgDetail.F_QTY}"); } // 没有符合条件的货位 if (endLoc == null) { return NewSimpleResult(6, $"货位{model.endLoc}不存在,或不满足称重放置要求"); } // 修改任务终点为PDA指定终点 task.S_END_LOC = endLoc.S_CODE; LocationHelper.LockLoc(ref endLoc, 1); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Task>(task).UpdateColumns(a => a.S_END_LOC).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(7, $"任务{task.S_CODE}修改失败,修改终点位置为{endLoc.S_CODE}"); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(7, $"任务{task.S_CODE}修改失败,修改终点位置为{endLoc.S_CODE}"); } tran.CommitTran(); return NewSimpleResult(0, $"任务{task.S_CODE}修改成功,修改终点位置为{endLoc.S_CODE}"); } } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// <summary> /// 产品部分出库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> internal static SimpleResult PartOutbound(PartOutboundInfo model) { var taskName = TaskName.产品部分出库; var db = new SqlHelper<object>().GetInstance(); try { // 起点位置:货架(有货、没有锁、已启用) var startLoc = db.Queryable<TN_Location>() .Where(a => a.S_CODE == model.startLoc) .Where(a => a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y") .Where(a => a.N_CURRENT_NUM == 1) .First(); if (startLoc == null) { return NewSimpleResult(2, $"起点位置 {model.startLoc} 不存在或不具备取货要求"); } var locCntrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc); if (locCntrRel == null) { return NewSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可出库的物料"); } var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == "SFQ"); if (endLoc == null) { return NewSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// <summary> /// 产品部分回库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> internal static SimpleResult PartInbound(PartInboundInfo model) { var taskName = TaskName.产品部分回库; var db = new SqlHelper<object>().GetInstance(); try { // 起点位置:取放货区(有货物、没有锁、已启用) var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == "SFQ"); if (startLoc == null) { return NewSimpleResult(2, $"起点位置 {model.startLoc} 不符合回库条件"); } var locCntrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc); if (locCntrRel == null) { return NewSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料"); } // 终点位置:货架(没有货物,没有锁) var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (endLoc == null) { return NewSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } var cntId = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } public static SimpleResult CreateCountPlan(CreateCountPlanInfo model) { var db = new SqlHelper<object>().GetInstance(); try { var countPlan = new TN_Count_Plan() { S_CP_NO = GenerateNo("盘点计划", "CP"), S_TYPE = model.countType, }; if (model.countType == "货位") { countPlan.S_LOC_CODE = model.targetId; } else if (model.countType == "物料") { countPlan.S_ITEM_CODE = model.targetId; } else { return NewSimpleResult(2, $"创建盘点计划失败:不合法的盘点类型 '{model.countType}'"); } if (db.Insertable<TN_Count_Plan>(countPlan).ExecuteCommand() <= 0) { return NewSimpleResult(2, "创建盘点计划失败"); } return NewSimpleResult(0, "创建盘点计划成功"); } catch (Exception ex) { return NewSimpleResult(1, ex.Message); } } public static SimpleResult CreateCountOrder(CreateCountOrderInfo model) { var db = new SqlHelper<object>().GetInstance(); var info = ""; try { var countPlan = db.Queryable<TN_Count_Plan>() .Where(a => a.S_CP_NO == model.planId).First(); if (countPlan == null) { return NewSimpleResult(2, $"盘点计划单号 '{model.planId}' 不存在"); } var countOrder = new TN_Count_Order() { S_CP_NO = model.planId, S_COUNT_NO = GenerateNo("盘点单", "CN"), }; var countDetailList = new List<TN_Count_CG_Detail>(); if (countPlan.S_TYPE == "货位") { var cgDetail = db.Queryable<TN_Location, TN_Loc_Container, TN_CG_Detail> ((l, c, d) => l.S_CODE == c.S_LOC_CODE && c.S_CNTR_CODE == d.S_CNTR_CODE) .Where(l => l.S_CODE == countPlan.S_LOC_CODE) .Select((l, c, d) => d).First(); var countDetail = new TN_Count_CG_Detail { S_COUNT_NO = countOrder.S_COUNT_NO, S_CNTR_CODE = cgDetail.S_CNTR_CODE, S_ITEM_CODE = cgDetail.S_ITEM_CODE, }; countDetailList.Add(countDetail); } else if (countPlan.S_TYPE == "物料") { var cgDetailList = db.Queryable<TN_CG_Detail>() .Where(d => d.S_ITEM_CODE == countPlan.S_ITEM_CODE).ToList(); foreach (var cgDetail in cgDetailList) { var countDetail = new TN_Count_CG_Detail { S_COUNT_NO = countOrder.S_COUNT_NO, S_CNTR_CODE = cgDetail.S_CNTR_CODE, S_ITEM_CODE = cgDetail.S_ITEM_CODE, }; countDetailList.Add(countDetail); } } else { return NewSimpleResult(3, $"计划单'{model.planId}'的类型{countPlan.S_TYPE}不合法"); } using (var tran = db.Ado.UseTran()) { if (db.Insertable<TN_Count_Order>(countOrder).ExecuteCommand() <= 0) { tran.RollbackTran(); info = "创建盘点单失败"; return NewSimpleResult(2, info); } if (db.Insertable<TN_Count_CG_Detail>(countDetailList).ExecuteCommand() <= 0) { tran.RollbackTran(); info = "创建盘点单明细失败"; return NewSimpleResult(3, info); } tran.CommitTran(); } return NewSimpleResult(0, "创建盘点单成功"); } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } public static SimpleResult CountProduct(CountProductInfo model) { var db = new SqlHelper<object>().GetInstance(); try { var cgDetail = db.Queryable<TN_CG_Detail>() .Where(d => d.S_CNTR_CODE == model.cntrCode).First(); if (cgDetail == null) { return NewSimpleResult(2, $"找不到容器号'{model.cntrCode}'对应的物料"); } var countDiff = new TN_Count_Diff { S_CNTR_CODE = cgDetail.S_CNTR_CODE, F_ACTUAL_QTY = model.qty }; if (db.Insertable<TN_Count_Diff>(countDiff).ExecuteCommand() <= 0) { return NewSimpleResult(3, $"插入盘点差异表失败"); } return NewSimpleResult(0, "盘点差异完成"); } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } internal static string GenerateNo(string snType, string prefix) { var id = SYSHelper.GetSerialNumber(snType, prefix); var date = DateTime.Now.ToString("yyMMdd"); return $"TN{date}{id.ToString().PadLeft(4, '0')}"; } /// <summary> /// 盘点理货出库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> internal static SimpleResult CheckOutbound(CheckOutboundInfo model) { var taskName = TaskName.盘点理货出库; var db = new SqlHelper<object>().GetInstance(); try { // 起点位置:取放货区(有货物、没有锁、已启用) var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == "SFQ"); if (startLoc == null) { return NewSimpleResult(2, $"起点位置 {model.startLoc} 不符合出库条件"); } var locCntrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc); if (locCntrRel == null) { return NewSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料"); } // 终点位置:货架(没有货物,没有锁) var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (endLoc == null) { return NewSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } var cntID = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntID, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } /// <summary> /// 盘点理货回库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> internal static SimpleResult CheckInbound(CheckInboundInfo model) { var taskName = TaskName.盘点理货回库; var db = new SqlHelper<object>().GetInstance(); try { // 起点位置:取放货区(有货物、没有锁、已启用) var startLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.startLoc && a.N_CURRENT_NUM == 1 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y" && a.S_AREA_CODE == "SFQ"); if (startLoc == null) { return NewSimpleResult(2, $"起点位置 {model.startLoc} 不符合回库条件"); } var locCntrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == model.startLoc); if (locCntrRel == null) { return NewSimpleResult(3, $"起点位置 {model.startLoc} 没有绑定容器,无可回库的物料"); } // 终点位置:货架(没有货物,没有锁) var endLoc = db.Queryable<TN_Location>().First(a => a.S_CODE == model.endLoc && a.N_CURRENT_NUM == 0 && a.N_LOCK_STATE == 0 && a.S_LOCK_STATE == "无" && a.C_ENABLE == "Y"); if (endLoc == null) { return NewSimpleResult(4, $"终点位置 {model.endLoc} 不具备放货条件"); } var cntID = locCntrRel.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntID, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"); } if (db.Updateable<TN_Location>(endLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); return NewSimpleResult(500, $"生成 {taskName} 失败,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } tran.CommitTran(); return NewSimpleResult(0, $"生成 {taskName} 成功,容器号 {cntID} ,起点 {startLoc.S_CODE} ,终点货架 {endLoc.S_CODE}"); } } catch (Exception ex) { return NewSimpleResult(1, $"发生了异常:{ex.Message}"); } } public static ErpResult InboundDataSync(InboundDataSyncInfo model) { var db = new SqlHelper<object>().GetInstance(); try { } catch (Exception ex) { return BuildErpResult(1, ex.Message); } return BuildErpResult(0, null); } public static ErpResult OutboundDataSync(OutboundDataSyncInfo model) { var db = new SqlHelper<object>().GetInstance(); try { } catch (Exception ex) { return BuildErpResult(1, ex.Message); } return BuildErpResult(1, null); } } } api/ApiModel.cs
New file @@ -0,0 +1,481 @@ using System.Collections.Generic; using Newtonsoft.Json; namespace HH.WCS.Mobox3.AnGang.api { /// <summary> /// 通用model /// </summary> public class ApiModel { #region mobox 相关 public class SimpleResult { public int resultCode { get; set; } public string resultMsg { get; set; } public List<object> result { get; set; } = new List<object>(); } public static SimpleResult NewSimpleResult(int code, string message) { return new SimpleResult { resultCode = code, resultMsg = message }; } #endregion /// <summary> /// hosttoagv上报任务状态 /// </summary> public class AgvTaskState { public int state { get; set; } public string task_no { get; set; } public string forklift_no { get; set; } /// <summary> /// 安全门编号 /// </summary> public string lock_no { get; set; } public string ext_data { get; set; } } public class SafetyInteractionInfo { public int station_id { get; set; } /// <summary> /// 请求上线/下线的的站台库位名称,例如work6、work8 /// </summary> public string station_name { get; set; } /// <summary> /// 请求码 /// </summary> public string apply_code { get; set; } public string task_no { set; get; } } public class orderStatusReportParme { /// <summary> /// 订单ID /// </summary> public int orderID { get; set; } /// <summary> /// 订单名 /// </summary> public string orderName { get; set; } /// <summary> /// 订单状态 /// </summary> public string orderStatus { get; set; } /// <summary> /// agv车号列表 /// </summary> public string agvIDList { get; set; } /// <summary> /// 优先级 /// </summary> public string priority { get; set; } /// <summary> /// 订单当前的目的地 /// </summary> public string currentDes { get; set; } /// <summary> /// 当前指令 /// </summary> public string currentCmd { get; set; } /// <summary> /// 错误码 /// </summary> public int errorCode { get; set; } /// <summary> /// 订单的截至时间 /// </summary> public string deadLine { get; set; } /// <summary> /// 订单的创建时间 /// </summary> public string createdTime { get; set; } /// <summary> /// 额外信息1 /// </summary> public string extraInfo1 { get; set; } /// <summary> /// 额外信息2 /// </summary> public string extraInfo2 { get; set; } } /// <summary> /// 返回给hosttoagv /// </summary> public class ReturnResult { public int ResultCode { get; set; } public string ResultMsg { get; set; } } /// <summary> /// 返回给GZ /// </summary> public class GzResult { public int resultCode { get; set; } public string msg { get; set; } public int orderID { get; set; } } } public class OtherModel { public class InboundInfo { /// <summary> /// 起点货位 /// </summary> [JsonProperty("StartLoc")] public string StartLoc { get; set; } /// <summary> /// 终点货架(可选) /// </summary> [JsonProperty("Nrow")] public string Row { get; set; } } public class SelectLocationInfo { /// <summary> /// AGV小车号:NOTE 后期可能省略,因为只有一辆车 /// </summary> public string forklift_no { get; set; } public string endLoc { get; set; } } /// <summary> /// 产品部分回库信息 /// </summary> public class PartInboundInfo { /// <summary> /// 起点位置 /// </summary> public string startLoc { get; set; } /// <summary> /// 终点位置 /// </summary> public string endLoc { get; set; } } /// <summary> /// 产品部分出库信息 /// </summary> public class PartOutboundInfo { /// <summary> /// 起点位置 /// </summary> public string startLoc { get; set; } /// <summary> /// 终点位置 /// </summary> public string endLoc { get; set; } } public class CreateCountPlanInfo { public string countType { get; set; } public string targetId { get; set; } } public class CreateCountOrderInfo { public string planId { get; set; } } public class CountProductInfo { public string cntrCode { get; set; } public float qty { get; set; } } /// <summary> /// 盘点理货出库信息 /// </summary> public class CheckOutboundInfo { /// <summary> /// 起点位置 /// </summary> public string startLoc { get; set; } /// <summary> /// 终点位置 /// </summary> public string endLoc { get; set; } } /// <summary> /// 盘点理货回库信息 /// </summary> public class CheckInboundInfo { /// <summary> /// 起点位置 /// </summary> public string startLoc { get; set; } /// <summary> /// 终点位置 /// </summary> public string endLoc { get; set; } } public class ErpResult { /// <summary> /// 接口反馈码 /// </summary> public int errCode { get; set; } /// <summary> /// 错误说明 /// </summary> public string errMsg { get; set; } } public static ErpResult BuildErpResult(int code, string message, bool printLog = true) { if (printLog) { LogHelper.Info(message); } return new ErpResult { errCode = code, errMsg = message }; } /// <summary> /// 入库数据同步信息 /// </summary> public class InboundDataSyncInfo { /// <summary> /// 库存明细(列表) /// </summary> public List<StockTransaction> stockTransactions { get; set; } /// <summary> /// 总记录数 /// </summary> public string totalRecords { get; set; } /// <summary> /// 数据生成时间戳 /// </summary> public string timestamp { get; set; } } /// <summary> /// 库存明细信息 /// </summary> public class StockTransaction { /// <summary> /// 储位码 /// </summary> public string locationCode { get; set; } /// <summary> /// 库存明细交易号 /// </summary> public string stockTransactionId { get; set; } /// <summary> /// 物料编码 /// </summary> public string itemCode { get; set; } /// <summary> /// 物料名称 /// </summary> public string itemName { get; set; } /// <summary> /// 物料短描述 /// </summary> public string itemShortDesc { get; set; } /// <summary> /// 库存数量 /// </summary> public string stockQuantity { get; set; } /// <summary> /// 入库数量 /// </summary> public string inQuantity { get; set; } /// <summary> /// 库存总价 /// </summary> public string totalPrice { get; set; } /// <summary> /// 入库时间 /// </summary> public string stockInTime { get; set; } /// <summary> /// 保管员 /// </summary> public string storeKeeper { get; set; } /// <summary> /// 产线部门代码 /// </summary> public string lineCode { get; set; } /// <summary> /// 送货单行号 /// </summary> public string deliveryItemNo { get; set; } /// <summary> /// 供应商名称 /// </summary> public string supplierName { get; set; } /// <summary> /// 库存责任人姓名 /// </summary> public string inventoryManager { get; set; } /// <summary> /// 备用字段1 /// </summary> public string ext1 { get; set; } /// <summary> /// 备用字段2 /// </summary> public string ext2 { get; set; } /// <summary> /// 备用字段3 /// </summary> public string ext3 { get; set; } /// <summary> /// 备用字段4 /// </summary> public string ext4 { get; set; } /// <summary> /// 备用字段5 /// </summary> public string ext5 { get; set; } } /// <summary> /// 出库发料同步信息 /// </summary> public class OutboundDataSyncInfo { /// <summary> /// 发料记录明细列表 /// </summary> public List<MaterialIssue> materialIssues { get; set; } /// <summary> /// 总记录数 /// </summary> public string totalRecords { get; set; } /// <summary> /// 数据生成时间戳 /// </summary> public string timestamp { get; set; } } /// <summary> /// 发料记录明细信息 /// </summary> public class MaterialIssue { /// <summary> /// 储位码 /// </summary> public string locationCode { get; set; } /// <summary> /// 领用单号 /// </summary> public string withdrawalOrderNo { get; set; } /// <summary> /// 物料编码 /// </summary> public string itemCode { get; set; } /// <summary> /// 物料名称 /// </summary> public string itemName { get; set; } /// <summary> /// 物料短描述 /// </summary> public string itemShortDesc { get; set; } /// <summary> /// 实发数量 /// </summary> public string actualIssuedQty { get; set; } /// <summary> /// 实发金额 /// </summary> public string issuedAmount { get; set; } /// <summary> /// 供应商名称 /// </summary> public string supplierName { get; set; } /// <summary> /// 实发人 /// </summary> public string issuer { get; set; } /// <summary> /// 发料日期 /// </summary> public string issueDate { get; set; } /// <summary> /// 保管员 /// </summary> public string storeKeeper { get; set; } /// <summary> /// 产线部门代码 /// </summary> public string lineCode { get; set; } /// <summary> /// 批次 /// </summary> public string batchNo { get; set; } /// <summary> /// 备用字段1 /// </summary> public string ext1 { get; set; } /// <summary> /// 备用字段2 /// </summary> public string ext2 { get; set; } /// <summary> /// 备用字段3 /// </summary> public string ext3 { get; set; } /// <summary> /// 备用字段4 /// </summary> public string ext4 { get; set; } /// <summary> /// 备用字段5 /// </summary> public string ext5 { get; set; } } } } api/DebugController.cs
New file @@ -0,0 +1,320 @@ using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.wms; using HH.WCS.Mobox3.AnGang.models; using Newtonsoft.Json; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using HH.WCS.Mobox3.AnGang.util; namespace HH.WCS.Mobox3.AnGang.api { /// <summary> /// 测试用,如果项目中要和设备对接,前期设备无法测试,用接口模拟 /// </summary> [RoutePrefix("api")] public class DebugController : System.Web.Http.ApiController { /// <summary> /// AGV状态一键回报1462-国自 /// </summary> /// <returns></returns> [HttpPost] [Route("AGVSeriesReports")] public GzResults AGVSeriesReports(UpdateTaskState model) { GzResults gzResults = new GzResults(); gzResults.GzResultList = new List<GzResult>(); var orderStatus = new orderStatusReportParme() { orderName = model.TaskID, agvIDList = model.ForkliftNo, orderStatus = "waiting", }; var temp1 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp1); orderStatus.orderStatus = "source_finish"; var temp2 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp2); orderStatus.orderStatus = "dest_finish"; var temp3 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp3); orderStatus.orderStatus = "finish"; var temp4 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp4); return gzResults; } /// <summary> /// AGV状态一键回报14-国自 /// </summary> /// <returns></returns> [HttpPost] [Route("AGVSeriesReports-14")] public GzResults AGVSeriesReports14(UpdateTaskState model) { GzResults gzResults = new GzResults(); gzResults.GzResultList = new List<GzResult>(); var orderStatus = new orderStatusReportParme() { orderName = model.TaskID, agvIDList = model.ForkliftNo, orderStatus = "waiting", }; var temp1 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp1); orderStatus.orderStatus = "source_finish"; var temp2 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp2); return gzResults; } /// <summary> /// AGV状态一键回报62-国自 /// </summary> /// <returns></returns> [HttpPost] [Route("AGVSeriesReports-62")] public GzResults AGVSeriesReports62(UpdateTaskState model) { GzResults gzResults = new GzResults(); gzResults.GzResultList = new List<GzResult>(); var orderStatus = new orderStatusReportParme() { orderName = model.TaskID, agvIDList = model.ForkliftNo, orderStatus = "dest_finish", }; var temp3 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp3); orderStatus.orderStatus = "finish"; var temp4 = GZRobot.orderStatusReport(orderStatus); gzResults.GzResultList.Add(temp4); return gzResults; } /// <summary> /// 初始化数据库 /// </summary> /// <returns></returns> [HttpPost] [Route("CreateDatabase")] public string CreateDatabase(CoverInfo model) { try { var db = new SqlHelper<object>().GetInstance(); var cover = model.IsCover; var entityTypes = new Type[] { typeof(TN_CAR_IN), typeof(TN_CG_Detail), typeof(TN_Container), typeof(TN_Loc_Container), typeof(TN_Location), typeof(TN_Task), typeof(TN_Task_Action), typeof(SYSHelper.OI_SYS_MAXID), }; using (var tran = db.Ado.UseTran()) { if (cover) { // 删除所有表(按依赖关系倒序) var tables = db.DbMaintenance.GetTableInfoList(); foreach (var table in tables.OrderByDescending(t => t.Name)) { db.DbMaintenance.DropTable(table.Name); } // 创建新表 db.CodeFirst.InitTables(entityTypes); //db.CodeFirst.BackupTable().InitTables(entityTypes); } else { db.CodeFirst.InitTables(entityTypes); } tran.CommitTran(); } } catch (Exception ex) { LogHelper.Info($"发生了异常"); return "初始化数据库错误" + ex.Message; } return "成功"; } /// <summary> /// DEBUG:插入货位、容器、货品信息 /// </summary> /// <returns></returns> [HttpPost] [Route("InsertLocCntrCg")] public string InsertLocCntrCg(LocCntrCg locCntrCg) { var db = new SqlHelper<object>().GetInstance(); try { using (var tran = db.UseTran()) { LogHelper.Info("LogCntrCg:" + JsonConvert.SerializeObject(locCntrCg)); if (string.IsNullOrEmpty(locCntrCg.LocCode)) { return "参数非法"; } var loc = db.Queryable<TN_Location>().First(a => a.S_CODE == locCntrCg.LocCode); if (loc == null) { var newLoc = new TN_Location { S_CODE = locCntrCg.LocCode, S_AREA_CODE = locCntrCg.LocArea ?? "" }; if (db.Insertable<TN_Location>(newLoc).ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"插入位置{locCntrCg.LocCode}失败"); return "插入失败"; } loc = newLoc; } //if (loc.N_CURRENT_NUM == 0) { // loc.N_CURRENT_NUM = 1; // if (db.Updateable<TN_Location>(loc).UpdateColumns( // it => new { it.N_CURRENT_NUM, it.T_MODIFY }).ExecuteCommand() <= 0) { // tran.RollbackTran(); // LogHelper.Info($"修改位置{locCntrCg.LocCode}失败"); // continue; // } //} if (string.IsNullOrEmpty(locCntrCg.CntrCode)) { tran.CommitTran(); LogHelper.Info("容器号为空,不再读取后面的数据"); return "容器号为空,不再读取后面的数据"; } var locCntrRel = db.Queryable<TN_Loc_Container>().First(a => a.S_LOC_CODE == locCntrCg.LocCode && a.S_CNTR_CODE == locCntrCg.CntrCode); if (locCntrRel == null) { var newLocCntrRel = new TN_Loc_Container { S_LOC_CODE = locCntrCg.LocCode, S_CNTR_CODE = locCntrCg.CntrCode }; loc.N_CURRENT_NUM = 1; if (db.Insertable<TN_Loc_Container>(newLocCntrRel).ExecuteCommand() <= 0 && db.Updateable<TN_Location>(loc).UpdateColumns(c => c.N_CURRENT_NUM).ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"插入位置托盘关系{locCntrCg.LocCode}-{locCntrCg.CntrCode}失败"); return "插入失败"; } } if (string.IsNullOrEmpty(locCntrCg.ItemCode)) { tran.CommitTran(); LogHelper.Info("物料号为空,不再读取后面的数据"); return "物料号为空,不再读取后面的数据"; } var cgDetail = db.Queryable<TN_CG_Detail>().First(a => a.S_CNTR_CODE == locCntrCg.CntrCode && a.S_ITEM_CODE == locCntrCg.ItemCode); if (cgDetail == null) { var locList = new List<TN_CG_Detail>(); locList.Add(new TN_CG_Detail { S_CNTR_CODE = locCntrCg.CntrCode, S_ITEM_CODE = locCntrCg.ItemCode, S_BATCH_NO = locCntrCg.BatchNo ?? "" }); if (db.Insertable<TN_CG_Detail>(locList).ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"插入托盘物料关系{locCntrCg.CntrCode}-{locCntrCg}失败"); return "插入失败"; } } tran.CommitTran(); } return "插入数据成功"; } catch (Exception ex) { return $"{ex.Message}"; } } [HttpPost] [Route("SetTaskWeight")] public string SetTaskWeight(SetTaskWeightInfo model) { var db = new SqlHelper<object>().GetInstance(); var cgDetail = db.Queryable<TN_CG_Detail, TN_Task>((d, t) => d.S_CNTR_CODE == t.S_CNTR_CODE) .Where((d, t) => t.S_CODE == model.TaskNo).First(); if (cgDetail == null) { return "找不到对应的物料信息"; } cgDetail.F_QTY = model.Weight; try { if (db.Updateable<TN_CG_Detail>(cgDetail).UpdateColumns(it => it.F_QTY) .ExecuteCommand() <= 0) { return "修改失败"; } return "修改成功"; } catch (Exception ex) { return ex.Message; } } } public class ReturnResults { public List<ReturnResult> ResultList { set; get; } } public class GzResults { public List<GzResult> GzResultList { set; get; } } public class LocCntrCg { public string LocCode { get; set; } public string LocArea { get; set; } public string CntrCode { get; set; } public string ItemCode { get; set; } public string BatchNo { get; set; } } /// <summary> /// 模拟 AGV 传递信号,用于更改任务状态 /// </summary> public class UpdateTaskState { /// <summary> /// 任务ID /// </summary> public string TaskID { set; get; } /// <summary> /// AGV 小车号 /// </summary> public string ForkliftNo { set; get; } /// <summary> /// AGV 下一个状态 /// </summary> public int NextState { set; get; } } public class CoverInfo { public bool IsCover { set; get; } = true; } public class SetTaskWeightInfo { public string TaskNo { set; get; } public float Weight { set; get; } } } api/ErpController.cs
File was renamed from Controllers/ErpController.cs @@ -1,11 +1,8 @@ using System.Web.Http; using HH.WCS.Mobox3.AnGang.Services; using static HH.WCS.Mobox3.AnGang.api.OtherModel; using static HH.WCS.Mobox3.AnGang.Dtos.Request.ErpRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Response.ErpResponse; namespace HH.WCS.Mobox3.AnGang.Controllers { namespace HH.WCS.Mobox3.AnGang.api { /// <summary> /// ERP 调用的接口 /// </summary> @@ -19,7 +16,7 @@ [HttpPost] [Route("InboundDataSync")] public static ErpResult InboundDataSync(InboundDataSyncInfo model) { return ErpService.InboundDataSync(model); return ApiHelper.InboundDataSync(model); } /// <summary> @@ -30,7 +27,7 @@ [HttpPost] [Route("OutboundDataSync")] public static ErpResult OutboundDataSync(OutboundDataSyncInfo model) { return ErpService.OutboundDataSync(model); return ApiHelper.OutboundDataSync(model); } } } api/MoboxController.cs
New file @@ -0,0 +1,115 @@ using System.Web.Http; using Newtonsoft.Json; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using static HH.WCS.Mobox3.AnGang.api.OtherModel; namespace HH.WCS.Mobox3.AnGang.api { /// <summary> /// Mobox3 调用,脚本中调用 /// </summary> [RoutePrefix("api")] public class MoboxController : ApiController { /// <summary> /// 货品入库(PDA) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("Inbound")] public SimpleResult Inbound(InboundInfo model) { LogHelper.Info("触发API:产品入库(PDA)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.Inbound(model); } /// <summary> /// PDA选择终点货位 /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("SelectLocation")] public SimpleResult SelectLocation(SelectLocationInfo model) { LogHelper.Info("触发API:PDA选择终点货位" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.SelectLocation(model); } /// <summary> /// 产品部分出库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("PartOutbound")] public SimpleResult PartOutbound(PartOutboundInfo model) { LogHelper.Info("触发API:产品部分出库(WMS)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.PartOutbound(model); } /// <summary> /// 产品部分回库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("PartInbound")] public SimpleResult PartInbound(PartInboundInfo model) { LogHelper.Info("触发API:产品部分回库(WMS)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.PartInbound(model); } /// <summary> /// 创建盘点计划单(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("CreateCountPlan")] public SimpleResult CreateCountPlan(CreateCountPlanInfo model) { LogHelper.Info("触发API:创建盘点计划单(WMS)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.CreateCountPlan(model); } /// <summary> /// 创建盘点单(PDA) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("CreateCountOrder")] public SimpleResult CreateCountOrder(CreateCountOrderInfo model) { LogHelper.Info("触发API:创建盘点单(PDA)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.CreateCountOrder(model); } public SimpleResult CountProduct(CountProductInfo model) { LogHelper.Info("触发API:盘点理货(PDA)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.CountProduct(model); } /// <summary> /// 盘点理货出库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("CheckOutbound")] public SimpleResult CheckOutbound(CheckOutboundInfo model) { LogHelper.Info("触发API:盘点理货出库(WMS)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.CheckOutbound(model); } /// <summary> /// 盘点理货回库(WMS) /// </summary> /// <param name="model"></param> /// <returns></returns> [HttpPost] [Route("CheckInbound")] public SimpleResult CheckInbound(CheckInboundInfo model) { LogHelper.Info("触发API:盘点理货回库(WMS)" + JsonConvert.SerializeObject(model), "API"); return ApiHelper.CheckInbound(model); } } } api/WmsController.cs
File was renamed from Controllers/WmsController.cs @@ -3,9 +3,9 @@ using Newtonsoft.Json; using System.Collections.Generic; using System.Web.Http; using static HH.WCS.Mobox3.AnGang.Controllers.ApiModel; using static HH.WCS.Mobox3.AnGang.api.ApiModel; namespace HH.WCS.Mobox3.AnGang.Controllers namespace HH.WCS.Mobox3.AnGang.api { /// <summary> /// 第三方调用的接口 config/config.json
@@ -2,7 +2,7 @@ "WebApiUrl": "http://127.0.0.1:8901", "RCSApiUrl": "http://127.0.0.1:6001", "NDCApiUrl": "http://127.0.0.1:5201/api/order/", "SqlServer": "Data Source=192.168.1.144;Initial Catalog=YinKouAnGan;User ID=hhuser;Password=Am123123", "SqlServer": "Data Source=(local);Initial Catalog=AnGangTest;User ID=sa;Password=123456", "TCPServerIP": "127.0.0.1", "TCPServerPort": 8085, "Areas": [ @@ -15,7 +15,7 @@ "Codes": [ "HJQ" ] } ], "Snap": [ "Snaps": [ { "Ip": "172.23.8.95", "Port": 37777, core/Monitor.cs
New file @@ -0,0 +1,159 @@ using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.process; using HH.WCS.Mobox3.AnGang.util; using HH.WCS.Mobox3.AnGang.wms; using Newtonsoft.Json; using System; using System.Collections.Generic; namespace HH.WCS.Mobox3.AnGang.core { /// <summary> /// 定时轮询任务 /// </summary> public class Monitor { public static void CheckCountOrder() { var taskName = TaskName.盘点理货出库; var db = new SqlHelper<object>().GetInstance(); var info = ""; try { var orderList = db.Queryable<TN_Count_Order>() .Where(c => c.N_B_STATE == 1) .OrderBy(c => c.T_CREATE, SqlSugar.OrderByType.Asc) .ToList(); if (orderList.Count == 0) { LogHelper.Info("轮询--出库--暂无待执行的Order"); return; } var detailList = new List<TN_Count_CG_Detail>(); foreach (var order in orderList) { var doingCount = db.Queryable<TN_Count_CG_Detail>() .Count(d => d.S_COUNT_NO == order.S_COUNT_NO && d.N_B_STATE >= 2); // 执行中 var allCount = db.Queryable<TN_Count_CG_Detail>() .Count(d => d.S_COUNT_NO == order.S_COUNT_NO); LogHelper.Info($"轮询--{taskName}--统计{taskName}单'{order.S_COUNT_NO}'任务已下发:{doingCount}/{allCount}"); if (doingCount == allCount) { order.N_B_STATE = 2; // 所有任务都已执行 db.Updateable<TN_Count_Order>(order).UpdateColumns(it => new { it.N_B_STATE }).ExecuteCommand(); continue; } var lastDetail = db.Queryable<TN_Count_CG_Detail>() .Where(d => d.S_COUNT_NO == order.S_COUNT_NO && d.N_B_STATE == 2) // TODO 或者改成查task .First(); if (lastDetail != null) { LogHelper.Info($"轮询--{taskName}--{taskName}单'{order.S_COUNT_NO}'上一个任务仍在进行中:" + JsonConvert.SerializeObject(lastDetail)); continue; } var outboundDetail = db.Queryable<TN_Count_CG_Detail>() .Where(a => a.S_COUNT_NO == order.S_COUNT_NO && a.N_B_STATE == 1) // 已下发 .First(); if (outboundDetail != null) { LogHelper.Info($"轮询--{taskName}--"); continue; } detailList.Add(outboundDetail); } if (detailList.Count == 0) { return; } var startLocList = new List<TN_Location>(); var endLocList = new List<TN_Location>(); var taskList = new List<TN_Task>(); 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) .First(); if (startLoc == null) { LogHelper.Info($"轮询--出库:没有找到合适的起点货位!"); continue; } var endLoc = db.Queryable<TN_Location>() .Where(a => a.S_AREA_CODE == "SFQ") .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($"轮询--出库:没有找到合适的终点货位!S_NO为 '{detail.S_COUNT_NO}'"); continue; } detail.N_B_STATE = 2; var cntId = detail.S_CNTR_CODE; var task = WCSHelper.BuildTask(startLoc, endLoc, cntId, taskName); LocationHelper.LockLoc(ref startLoc, 1); // 起点出库锁 LocationHelper.LockLoc(ref endLoc, 2); // 终点入库锁 using (var tran = db.Ado.UseTran()) { if (db.Updateable<TN_Count_CG_Detail>(detail).UpdateColumns(it => it.N_B_STATE).ExecuteCommand() <= 0) { tran.RollbackTran(); LogHelper.Info($"轮询--出库--修改明细表状态为完成失败!"); } if (db.Updateable<TN_Location>(startLoc).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; LogHelper.Info(info); continue; } if (db.Updateable<TN_Location>(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} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; LogHelper.Info(info); continue; } if (db.Insertable<TN_Task>(task).ExecuteCommand() <= 0) { tran.RollbackTran(); info = $"生成 {taskName} 失败,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; LogHelper.Info(info); continue; } tran.CommitTran(); info = $"生成 {taskName} 成功,容器号 {cntId} ,起点 {startLoc.S_CODE} ,终点货位 {endLoc.S_CODE}"; LogHelper.Info(info); continue; } } } catch (Exception ex) { info = $"发生了异常:{ex.Message}"; LogHelper.Info(info); } } } } core/WCSCore.cs
File was renamed from Services/AgvService.cs @@ -1,47 +1,34 @@ using HH.WCS.Mobox3.AnGang.Helpers; using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.device; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.process; using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Helper; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using HH.WCS.Mobox3.AnGang.wms; using HH.WCS.Mobox3.AnGang.util; using static HH.WCS.Mobox3.AnGang.Dtos.Request.AgvRequest; using static HH.WCS.Mobox3.AnGang.Dtos.Response.AgvResponse; using HH.WCS.Mobox3.AnGang.Consts; using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.Devices; namespace HH.WCS.Mobox3.AnGang.Services { public class AgvService { namespace HH.WCS.Mobox3.AnGang.core { internal class WCSCore { public static ReturnResult OperateAgvTaskStatus(AgvTaskState model) { var result = new ReturnResult(); try { switch (model.state) { case 1023: break; case 1025: break; case 1012: break; case 1004: break; case 1103: break; default: // AGV 执行任务的逻辑处理 if (!AgvTaskProcessOk(model)) { // 执行不OK,说明没有找到任务 result.ResultCode = 1; result.ResultMsg = $"根据Model.No未找到对应的任务,{model.task_no}"; LogHelper.Info(result.ResultMsg, "API"); return result; } break; if (model.state > 0 && model.state < 1000) { // AGV 执行任务的逻辑处理 if (!AgvTaskProcessOk(model)) { // 执行不OK,说明没有找到任务 result.ResultCode = 1; result.ResultMsg = $"根据Model.No未找到对应的任务,{model.task_no}"; LogHelper.Info(result.ResultMsg, "API"); return result; } } result.ResultCode = 0; @@ -69,48 +56,48 @@ if (model.state > 7) { //安全请求等 TaskHelper.OperateReq(model.task_no, model.state, model.forklift_no, model.ext_data); TaskProcess.OperateReq(model.task_no, model.state, model.forklift_no, model.ext_data); return true; } // AGV 任务 134562(7) 状态处理 switch (model.state) { case AgvStateCode.执行: case 1: // 执行 WCSHelper.Begin(TN_Task, model.forklift_no); // 已推送的任务的状态改成执行 break; case AgvStateCode.开始取货: case 3: // 开始取货 WCSHelper.UpdateStatus(TN_Task, "开始取货"); // 任务状态改成开始取货 break; case AgvStateCode.取货完成: case 4: // 取货完成 WCSHelper.UpdateStatus(TN_Task, "取货完成"); // 任务状态改成取货完成 var captureTask = Task.Run(() => { if (TN_Task.S_TYPE == TaskName.产品入库 || TN_Task.S_TYPE == TaskName.产品部分回库) { if (TN_Task.S_TYPE == TaskName.产品入库 || TN_Task.S_TYPE == TaskName.产品部分回库) { var captureTask = Task.Run(() => { CapturePic(TN_Task); } }); }); } var setEndLocTask = Task.Run(() => { // 只要任务为产品入库(PDA),就需要重新指定终点(默认endLoc为"") if (TN_Task.S_TYPE == TaskName.产品入库) { if (TN_Task.S_TYPE == TaskName.产品入库) { var setEndLocTask = Task.Run(() => { // 只要任务为产品入库(PDA),就需要重新指定终点(默认endLoc为"") SetEndLoc(TN_Task); } }); }); } TaskHelper.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点 TaskProcess.OperateStatus(TN_Task, 4); // 起点容器货位解绑,解锁起点 break; case AgvStateCode.开始卸货: case 5: // 开始卸货 WCSHelper.UpdateStatus(TN_Task, "开始卸货"); // 任务状态改成开始卸货 break; case AgvStateCode.卸货完成: case 6: // 卸货完成 WCSHelper.UpdateStatus(TN_Task, "卸货完成"); // 任务状态改成卸货完成 TaskHelper.OperateStatus(TN_Task, 6); // 终点容器货位绑定,解锁终点 TaskProcess.OperateStatus(TN_Task, 6); // 终点容器货位绑定,解锁终点 break; case AgvStateCode.完成: case 2: // 完成 WCSHelper.End(TN_Task); // 任务状态改成结束 break; case AgvStateCode.异常: TaskHelper.OperateStatus(TN_Task, 7); // 异常处理 case 7: // 异常 TaskProcess.OperateStatus(TN_Task, 7); // 异常处理 WCSHelper.Fail(TN_Task); // 任务状态改成错误 break; } @@ -122,7 +109,7 @@ } public static void CapturePic(TN_Task model) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var filepath = SnapManager.GetCapturePicturePath(); if (string.IsNullOrEmpty(filepath)) { @@ -140,7 +127,7 @@ } public static void SetEndLoc(TN_Task tn_task) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var endLoc = db.Queryable<TN_Location>() .First(a => a.S_CODE == tn_task.S_END_LOC); @@ -218,45 +205,58 @@ //}; //GZRobot.UpdateInteractInfo(request); using (var trans = db.Ado.UseTran()) { if (db.Updateable<TN_Task>(tn_task).UpdateColumns(it => new { it.S_END_LOC }) if (db.Updateable<TN_Task>(tn_task).UpdateColumns(it => new { it.S_END_LOC }) .ExecuteCommand() > 0) { //LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); LogHelper.Info($"重新计算后没有合适货位,任务 {tn_task.S_CODE} 修改成功,修改终点货位为 0空"); } else { trans.RollbackTran(); LogHelper.Info($"重新计算后没有合适货位,任务 {tn_task.S_CODE} 修改失败,修改终点货位为 0空"); } //LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 LogHelper.Info($"重新计算后没有合适货位,任务 {tn_task.S_CODE} 修改成功,修改终点货位为 0空"); } else { LogHelper.Info($"重新计算后没有合适货位,任务 {tn_task.S_CODE} 修改失败,修改终点货位为 0空"); } } else { // 找到合适的货位,推送 tn_task.S_END_LOC = endLoc.S_CODE; using (var trans = db.Ado.UseTran()) { if (db.Updateable<TN_Task>(tn_task).UpdateColumns(it => new { it.S_END_LOC }) if (db.Updateable<TN_Task>(tn_task).UpdateColumns(it => new { it.S_END_LOC }) .ExecuteCommand() > 0) { LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 trans.CommitTran(); LogHelper.Info($"计算货位成功,任务 {tn_task.S_CODE} 修改成功,终点货架为 {endLoc.N_ROW},修改终点位置为 {endLoc.S_CODE}"); } else { trans.RollbackTran(); LogHelper.Info($"计算货位成功,任务 {tn_task.S_CODE} 修改失败,终点货架为 {endLoc.N_ROW},修改终点位置为 {endLoc.S_CODE}"); } LocationHelper.LockLoc(endLoc.S_CODE, 1);//终点入库锁 LogHelper.Info($"计算货位成功,任务 {tn_task.S_CODE} 修改成功,终点货架为 {endLoc.N_ROW},修改终点位置为 {endLoc.S_CODE}"); } else { LogHelper.Info($"计算货位成功,任务 {tn_task.S_CODE} 修改失败,终点货架为 {endLoc.N_ROW},修改终点位置为 {endLoc.S_CODE}"); } } } /// <summary> /// 任务分发,根据调度类型发给不同的调度系统 /// </summary> internal static void Dispatch() { //查询任务 //获取所有等待的任务 var list = WCSHelper.GetWaitingTaskList(); LogHelper.Info("等待任务信息" + JsonConvert.SerializeObject(list), "API"); if (list.Count > 0) { list.ForEach(task => { //使用自定义任务推送 TaskProcess.SendTask(task);//调度NDC或杭奥或国自设备 //TaskProcess.SendGZTask(task);///调度国自设备 }); } else { LogHelper.Info("暂无任务"); } } public static ReturnResult SafetyInteraction(SafetyInteractionInfo model) { var gzResult = new ReturnResult(); //var db = DbHelper.GetDbClient(); //var db = new SqlHelper<object>().GetInstance(); //ModbusHelper.Relink(); //var productionLineInfo = Settings.ProductionLines[0]; core/WMSCore.cs
File was renamed from ServiceCore/WMSCore.cs @@ -1,4 +1,4 @@ using HH.WCS.Mobox3.AnGang.Helper; using System; using System.Collections.Generic; using System.Linq; @@ -6,7 +6,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.ServiceCore { namespace HH.WCS.Mobox3.AnGang.core { internal class WMSCore { device/ModbusHelper.cs
File was renamed from Devices/ModbusHelper.cs @@ -6,7 +6,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Helpers namespace HH.WCS.Mobox3.AnGang.device { /// <summary> /// modbus tcp 用第三方的包 device/OpcUaHelper.cs
File was renamed from Devices/OpcUaHelper.cs @@ -3,7 +3,7 @@ using System; using Opc.Ua.Configuration; namespace HH.WCS.Mobox3.AnGang.Devices namespace HH.WCS.Mobox3.AnGang.device { internal class OpcUaHelper { device/PlcHelper.cs
File was renamed from Devices/PlcHelper.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Devices namespace HH.WCS.Mobox3.AnGang.device { internal class PlcHelper { device/S7Helper.cs
File was renamed from Devices/S7Helper.cs @@ -1,4 +1,4 @@ using HH.WCS.Mobox3.AnGang.Controllers; using HH.WCS.Mobox3.AnGang.api; using Newtonsoft.Json.Linq; using S7.Net; using S7.Net.Types; @@ -10,7 +10,7 @@ using System.Threading.Tasks; using System.Web.Services.Description; namespace HH.WCS.Mobox3.AnGang.Devices namespace HH.WCS.Mobox3.AnGang.device { /// <summary> device/SnapDevice.cs
File was renamed from Devices/SnapDevice.cs @@ -9,7 +9,7 @@ using NetSDKCS; namespace HH.WCS.Mobox3.AnGang.Devices { namespace HH.WCS.Mobox3.AnGang.device { public class SnapDevice { private IntPtr _LoginID = IntPtr.Zero; private IntPtr _PlayID = IntPtr.Zero; @@ -27,7 +27,7 @@ //NETClient.SetSnapRevCallBack(_SnapRevCallBack, IntPtr.Zero); } catch (Exception ex) { LogHelper.InfoEx(ex); LogHelper.Info($"发生了异常:{ex.Message}"); } } @@ -35,10 +35,10 @@ NETClient.Cleanup(); } public void LoadInfo(AppStart.Snap snap) { public void LoadInfo(Config.Snap snap) { LoadInfo(snap.Ip, snap.Port, snap.Name, snap.Pwd); } public void LoadInfo(string ip, int port, string name, string pwd) { if (IntPtr.Zero == _LoginID) { ushort uPort = 0; @@ -151,7 +151,7 @@ } } catch (Exception ex) { LogHelper.InfoEx(ex); LogHelper.Info($"发生了异常:{ex.Message}"); return; } // 替代Demo程序的Frame图片展示 device/SnapManager.cs
File was renamed from Devices/SnapManager.cs @@ -4,12 +4,10 @@ using System.Text; using System.Threading.Tasks; using HH.WCS.Mobox3.AnGang.AppStart; namespace HH.WCS.Mobox3.AnGang.Devices { namespace HH.WCS.Mobox3.AnGang.device { public class SnapManager { private static SnapDevice _snapDevice { get; set; } public SnapManager(AppStart.Snap snap) { public SnapManager(Config.Snap snap) { if (_snapDevice == null) { _snapDevice = new SnapDevice(); } device/TcpClient.cs
File was renamed from Devices/TcpClient.cs @@ -1,5 +1,5 @@ using HH.WCS.Mobox3.AnGang; using HH.WCS.Mobox3.AnGang.Devices; using HH.WCS.Mobox3.AnGang.device; using System; using System.Collections.Generic; using System.Linq; @@ -7,7 +7,7 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Devices { namespace HH.WCS.Mobox3.AnGang.device { internal class TcpClient { /// <summary> device/TcpServer.cs
File was renamed from Devices/TcpServer.cs @@ -1,4 +1,4 @@ using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.config; using Newtonsoft.Json; using System; @@ -8,7 +8,7 @@ using System.Net.Sockets; using System.Text; namespace HH.WCS.Mobox3.AnGang.Devices namespace HH.WCS.Mobox3.AnGang.device { public class TcpServer { models/TN_Count_CG_Detail.cs
New file @@ -0,0 +1,22 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SqlSugar; namespace HH.WCS.Mobox3.AnGang.models { /// <summary> /// 盘点单明细表 /// </summary> [SugarTable("TN_Count_CG_Detail")] public class TN_Count_CG_Detail { public string S_COUNT_NO { get; set; } public string S_ITEM_CODE { get; set; } public string S_CNTR_CODE { get; set; } public int N_B_STATE { get; set; } } } models/TN_Count_Diff.cs
New file @@ -0,0 +1,21 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SqlSugar; namespace HH.WCS.Mobox3.AnGang.models { /// <summary> /// 盘点差异表 /// </summary> [SugarTable("TN_Count_Diff")] public class TN_Count_Diff : BaseModel { public string S_COUNT_NO { get; set; } public string S_CNTR_CODE { get; set; } public float F_QTY { get; set; } public float F_ACTUAL_QTY { get; set; } public string S_ITEM_CODE { get; set; } } } models/TN_Count_Order.cs
New file @@ -0,0 +1,24 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SqlSugar; namespace HH.WCS.Mobox3.AnGang.models { [SugarTable("TN_Count_Order")] public class TN_Count_Order : BaseModel { public string S_CP_NO { get; set; } /// <summary> /// 盘点单号 /// </summary> public string S_COUNT_NO { get; set; } /// <summary> /// 业务状态:0等待执行 1已执行待生成任务 2任务执行中 3任务完成 /// </summary> public int N_B_STATE { get; set; } } } models/TN_Count_Plan.cs
New file @@ -0,0 +1,38 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SqlSugar; namespace HH.WCS.Mobox3.AnGang.models { [SugarTable("TN_Count_Plan")] public class TN_Count_Plan : BaseModel { /// <summary> /// 盘点计划号 /// </summary> public string S_CP_NO { get; set; } /// <summary> /// 盘点类型:货物盘点/货位盘点 /// </summary> public string S_TYPE { get; set; } /// <summary> /// 盘点状态:0 – 未执行 1 – 启动中 2 – 执行中 3 – 完成 4 – 出错 /// </summary> public int N_B_STATE { get; set; } = 0; ///// <summary> ///// 计划盘点物料数量 ///// </summary> //public int N_PLAN_TOTAL { get; set; } // ------ public string S_LOC_CODE { get; set; } = ""; public string S_ITEM_CODE { get; set; } = ""; } } process/DeviceProcess.cs
File was renamed from Helpers/DeviceProcess.cs @@ -1,8 +1,7 @@ using HH.WCS.Mobox3.AnGang.Devices; using HH.WCS.Mobox3.AnGang.device; using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Helper; using System; using System.Collections.Generic; using System.Linq; process/TaskProcess.cs
File was renamed from Helpers/TaskHelper.cs @@ -1,21 +1,14 @@ using HH.WCS.Mobox3.AnGang.ServiceCore; using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Helper; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.wms; using Newtonsoft.Json; using Opc.Ua; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using static HH.WCS.Mobox3.AnGang.Controllers.ApiModel; using Org.BouncyCastle.Crypto; using HH.WCS.Mobox3.AnGang.Devices; using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.models; using System; namespace HH.WCS.Mobox3.AnGang.process { internal class TaskHelper { internal class TaskProcess { #region 任务相关 //--------------------------------------------------任务相关-------------------------------------------------- /// <summary> @@ -35,6 +28,7 @@ LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } } /// <summary> @@ -59,16 +53,13 @@ } /// <summary> /// 任务状态更新处理 /// </summary> /// <param name="mst"></param> /// <param name="state"></param> internal static void OperateStatus(TN_Task mst, int state) { if (state == 4) { if (state == 4) { CacheBitUpdate(mst, true); } if (state == 6)//卸货完成 @@ -87,15 +78,11 @@ /// <param name="state"></param> /// <param name="forkliftNo"></param> /// <param name="extData"></param> internal static void OperateReq(string no, int state, string forkliftNo, string extData = "") { if (state == 1101) { internal static void OperateReq(string no, int state, string forkliftNo, string extData = "") { if (state == 1101) { //请求取货, } if (state == 1102) { if (state == 1102) { //请求卸货, //根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数 var dic = new Dictionary<string, string>(); @@ -106,8 +93,7 @@ NDC.ChangeOrder(dic); //改完参数车子就会自己卸货 } if (state == 1103) { if (state == 1103) { //大铁框叉走以后通知,我们要通知输送线 } } @@ -115,12 +101,11 @@ private static object locLocker = new object(); /// <summary> /// <summary> /// 推送任务 /// </summary> /// <param name="mst"></param> internal static bool SendTask(TN_Task mst) { internal static bool SendTask(TN_Task mst) { var result = false; var start = "0"; var end = "0"; @@ -131,10 +116,9 @@ start = LocationHelper.GetAgvSite(mst.S_START_LOC); end = LocationHelper.GetAgvSite(mst.S_END_LOC); if (mst.S_TYPE == "空托下线堆叠") { end = LocationHelper.GetAgvSite(mst.S_END_LOC,true); } //if (mst.S_TYPE == "空托下线堆叠") { // end = LocationHelper.GetAgvSite(mst.S_END_LOC, true); //} LogHelper.Info($"NDC推送任务 {mst.S_CODE};" + "start=" + start + "end= " + end); var startLoc = LocationHelper.GetLoc(mst.S_START_LOC); @@ -147,19 +131,16 @@ dic.Add(new param() { name = "Ctype", value = "0" }); if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库") { dic.Add(new param() { name = "DATA", value = "1024" }); } else { dic.Add(new param() { name = "DATA", value = "0" }); } //if (mst.S_TYPE == "余料下线入库" || mst.S_TYPE == "人工拆盘入库") { // dic.Add(new param() { name = "DATA", value = "1024" }); //} //else { // dic.Add(new param() { name = "DATA", value = "0" }); //} var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令 if (res != null && (res.err_code == 0 || res.err_code == 50009)) { if (res != null && (res.err_code == 0 || res.err_code == 50009)) { //推送成功,修改任务优先级 mst.N_B_STATE = 1; mst.S_B_STATE = TN_Task.GetStateStr(1); @@ -167,16 +148,14 @@ result = true; LogHelper.Info($"NDC推送任务成功 {mst.S_CODE}start= {mst.S_START_LOC} + end = {mst.S_END_LOC}"); } else { else { LogHelper.Info($"NDC推送任务失败 {mst.S_CODE};Res:" + JsonConvert.SerializeObject(res)); } } else if (mst.N_SCHEDULE_TYPE == 5)//通过杭奥调度设备 { //调第三方接口 var model = new HanAo.TaskInfoModel { var model = new HanAo.TaskInfoModel { requestPk = mst.S_CODE, frmPos = mst.S_START_LOC, toPos = mst.S_END_LOC, @@ -188,8 +167,7 @@ WCSHelper.UpdateStatus(mst); LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos); } else { else { LogHelper.Info($"杭奥推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(model)); } } @@ -204,8 +182,7 @@ WCSHelper.UpdateEQNo(mst); LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC); } else { else { LogHelper.Info($"国自推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(mst)); } } util/HttpHelper.cs
util/LogHelper.cs
File was renamed from Helpers/LogHelper.cs @@ -35,8 +35,6 @@ } } public static void Info(string message, string name = "") { //logger.Info(message); ILogger logger = null; @@ -77,15 +75,6 @@ } } #region 自定义方法 public static void InfoEx(Exception ex) { Info($"异常:{ex.Message}"); } public static void InfoApi(string taskType, object model) { Info($"触发API:{taskType} " + JsonConvert.SerializeObject(model), "API"); } #endregion } internal class LogFactory util/Settings.cs
New file @@ -0,0 +1,113 @@ using System; using System.Collections.Generic; using System.IO; using HH.WCS.Mobox3.AnGang; using Newtonsoft.Json; using Newtonsoft.Json.Linq; // 根据 JSON 文件 生成对应的 C# 对象;网址:https://json2csharp.com/ namespace HH.WCS.Mobox3.AnGang { public class Settings { public static string WebApiUrl { get; set; } public static string RCSApiUrl { get; set; } public static string NDCApiUrl { get; set; } public static string SqlServer { get; set; } public static string TCPServerIP { get; set; } public static int TCPServerPort { get; set; } public static List<Config.Area> Areas { get; set; } public static List<Config.Snap> Snaps { get; set; } public static string CaptureUrl { get; set; } /// <summary> /// 库区字典(加载后就不变) /// </summary> public static Dictionary<string, List<string>> AreaMap { get; set; } = new Dictionary<string, List<string>>(); public static void Init() { // 加载配置文件 LoadJson(); // 针对 Areas 进行转换:将 Config 的 List 加载到 Dict 中 LoadAreas(); } private static void LoadJson() { LogHelper.Info("加载配置文件信息 开始"); // JSON 文件路径 string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "./config/config.json"); try { // 读取 JSON 文件内容 string jsonContent = File.ReadAllText(filePath); // 反序列化为 Root 对象 var root = JsonConvert.DeserializeObject<Config.Root>(jsonContent); WebApiUrl = root.WebApiUrl; RCSApiUrl = root.RCSApiUrl; NDCApiUrl = root.NDCApiUrl; SqlServer = root.SqlServer; TCPServerIP = root.TCPServerIP; TCPServerPort = root.TCPServerPort; Areas = root.Areas; Snaps = root.Snaps; CaptureUrl = root.CaptureUrl; } catch (FileNotFoundException) { LogHelper.Info("JSON 文件未找到"); } catch (JsonException ex) { LogHelper.Info($"JSON 解析错误: {ex.Message}"); } catch (Exception ex) { LogHelper.Info($"发生错误: {ex.Message}"); } LogHelper.Info("加载配置文件信息 完成"); } private static void LoadAreas() { foreach (var area in Areas) { AreaMap.Add(area.Name, area.Codes); } } } public class Config { // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); public class Area { public string Name { get; set; } public List<string> Codes { get; set; } } public class Root { public string WebApiUrl { get; set; } public string RCSApiUrl { get; set; } public string NDCApiUrl { get; set; } public string SqlServer { get; set; } public string TCPServerIP { get; set; } public int TCPServerPort { get; set; } public List<Area> Areas { get; set; } public List<Snap> Snaps { get; set; } public string CaptureUrl { get; set; } } public class Snap { public string Ip { get; set; } public int Port { get; set; } public string Name { get; set; } public string Pwd { get; set; } } } public class TaskName { public const string 产品入库 = "产品入库"; public const string 产品部分出库 = "产品部分出库"; public const string 产品部分回库 = "产品部分回库"; public const string 盘点理货出库 = "盘点理货出库"; public const string 盘点理货回库 = "盘点理货回库"; } } util/SqlHelper.cs
New file @@ -0,0 +1,70 @@ using HH.WCS.Mobox3.AnGang; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Linq.Expressions; namespace HH.WCS.Mobox3.AnGang.util { //https://www.donet5.com/Home/Doc public class SqlHelper<T> where T : class, new() { /// <summary> /// 如果用Oracle数据需要包Oracle.ManagedDataAccess/21.15.0,环境netframework 4.62,太新了4.8有的服务器安装不上去 /// </summary> /// <param name="url"></param> /// <returns></returns> public SqlSugarClient GetInstance(string url = "") { //创建数据库对象 SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = string.IsNullOrEmpty(url) ? Settings.SqlServer : url, //ConnectionString = @"Data Source=192.168.1.198\sql2008;Initial Catalog=OIMobox;User ID=sa;Password=sa@2015", DbType = DbType.SqlServer, //ConnectionString = @"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=OIMobox)));User Id=system;Password=Am123123;", //DbType = DbType.Oracle, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute//从特性读取主键自增信息 }); //监控所有超过1秒的Sql db.Aop.OnLogExecuted = (sql, p) => { //执行时间超过1秒 if (db.Ado.SqlExecutionTime.TotalSeconds > 1) { Console.WriteLine(sql + "\r\n" + db.Utilities.SerializeObject(p.ToDictionary(it => it.ParameterName, it => it.Value))); //代码CS文件名 var fileName = db.Ado.SqlStackTrace.FirstFileName; //代码行数 var fileLine = db.Ado.SqlStackTrace.FirstLine; //方法名 var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName; } //相当于EF的 PrintToMiniProfiler }; //每次设置数值时都去除前导后导空格 db.Aop.DataExecuted = (value, entity) => { entity.EntityColumnInfos.ToList().ForEach(a => { var pvalue = entity.GetValue(a.PropertyName); if (pvalue != null && pvalue.GetType() == typeof(String)) { entity.SetValue(a.PropertyName, pvalue.ToString().Trim()); } }); }; //据转换 (ExecuteCommand才会拦截,查询不行) //db.Aop.DataExecuting = (value, entity) => { // //var val=entity.EntityColumnInfo // Console.WriteLine(entity.EntityName); //}; return db; } } } wms/ContainerHelper.cs
File was renamed from Helpers/ContainerHelper.cs @@ -1,4 +1,4 @@ using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.config; using Newtonsoft.Json; using System; @@ -6,10 +6,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using static HH.WCS.Mobox3.AnGang.Dispatch.NDC; using HH.WCS.Mobox3.AnGang.Helpers; using static HH.WCS.Mobox3.AnGang.dispatch.NDC; using HH.WCS.Mobox3.AnGang.util; namespace HH.WCS.Mobox3.AnGang.Helper { namespace HH.WCS.Mobox3.AnGang.wms { /// <summary> /// 容器帮助类 /// </summary> @@ -23,7 +23,7 @@ /// <returns></returns> public static string BindingCG(string cnt, List<string> cGs) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var logs = $"容器:{cnt},货品:{JsonConvert.SerializeObject(cGs)}"; try { @@ -88,7 +88,7 @@ /// <returns></returns> public static string UnBindingCG(string cnt, List<string> cGs) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var logs = $"容器:{cnt},货品:{JsonConvert.SerializeObject(cGs)}"; try { wms/LocationHelper.cs
File was renamed from Helpers/LocationHelper.cs @@ -1,4 +1,4 @@ using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.config; using Newtonsoft.Json; using SqlSugar; @@ -7,11 +7,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using static HH.WCS.Mobox3.AnGang.Controllers.ApiModel; using HH.WCS.Mobox3.AnGang.Helpers; using static HH.WCS.Mobox3.AnGang.Dtos.Response.MoboxResponse; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using HH.WCS.Mobox3.AnGang.util; namespace HH.WCS.Mobox3.AnGang.Helper { namespace HH.WCS.Mobox3.AnGang.wms { public class LocationHelper { private static Dictionary<string, TN_Location> Locations = null; @@ -54,7 +53,7 @@ /// <returns></returns> internal static List<TN_Location> GetAllLocList() { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); return db.Queryable<TN_Location>().ToList(); } @@ -131,8 +130,29 @@ internal static TN_Location GetLoc(string code) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); return db.Queryable<TN_Location>().Where(a => a.S_CODE.Trim() == code).First(); } /// <summary> /// 入库锁定终点,出库锁定起点 /// 你创建任务锁定货位的时候,把锁的来源就是任务号也写上去(加锁的方法加个参数,可空的参数),解锁的时候把来源置空。 /// </summary> /// <param name="loc"></param> /// <param name="lockState">1:入库锁、2:出库锁、2:其它锁</param> /// <param name="lockSource">锁的来源=任务号</param> /// <returns></returns> public static bool LockLoc(ref TN_Location loc, int lockState, string lockSource = "") { //if (loc == null || loc.N_LOCK_STATE != 0) { // return false; //} loc.N_LOCK_STATE = lockState; loc.S_LOCK_STATE = TN_Location.GetLockStateStr(lockState); loc.S_LOCK_OP = lockSource; loc.T_MODIFY = System.DateTime.Now; return true; } /// <summary> @@ -146,7 +166,7 @@ public static bool LockLoc(string loc, int lockState, string lockSource = "") { var res = false; var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var model = db.Queryable<TN_Location>().Where(a => a.S_CODE == loc).First(); LogHelper.Info($"锁货位{loc},状态{lockState},信息" + JsonConvert.SerializeObject(model)); if (model != null && model.N_LOCK_STATE == 0) @@ -171,7 +191,7 @@ { LogHelper.Info("UnLockLoc:" + loc); var res = false; var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var model = db.Queryable<TN_Location>().Where(a => a.S_CODE == loc).First(); if (model != null) { @@ -197,7 +217,7 @@ /// <returns></returns> public static string UnBindingLoc(string loc, List<string> cntrs) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}"; try { @@ -270,7 +290,7 @@ /// <returns></returns> public static string BindingLoc(string loc, List<string> cntrs) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}"; try { @@ -379,7 +399,7 @@ LogHelper.Info("触发API:货位容器重置" + JsonConvert.SerializeObject(model), "API"); var result = new SimpleResult(); var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); try { wms/SYSHelper.cs
File was renamed from Helpers/SYSHelper.cs @@ -1,5 +1,5 @@ using HH.WCS.Mobox3.AnGang.config; using HH.WCS.Mobox3.AnGang.Helpers; using HH.WCS.Mobox3.AnGang.util; using SqlSugar; using System; @@ -8,15 +8,15 @@ using System.Text; using System.Threading.Tasks; namespace HH.WCS.Mobox3.AnGang.Helper namespace HH.WCS.Mobox3.AnGang.wms { internal class SysHelper internal class SYSHelper { private static object locker = new object(); internal static int GetSerialNumber(string snType, string prefix) { int result = 0; lock (locker) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var sId = db.Queryable<OI_SYS_MAXID>().Where(a => a.CN_S_TYPE.Trim() == snType && a.CN_S_PRE.Trim() == prefix).First(); if (sId != null) { sId.CN_N_MAX++; wms/WCSHelper.cs
File was renamed from Helpers/WCSHelper.cs @@ -1,4 +1,4 @@ using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.config; using Newtonsoft.Json; using System; @@ -6,27 +6,26 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using HH.WCS.Mobox3.AnGang.Helpers; using HH.WCS.Mobox3.AnGang.Consts; using HH.WCS.Mobox3.AnGang.util; namespace HH.WCS.Mobox3.AnGang.Helper { namespace HH.WCS.Mobox3.AnGang.wms { internal class WCSHelper { internal static string GenerateTaskNo() { var id = SysHelper.GetSerialNumber("任务号", "TN"); var id = SYSHelper.GetSerialNumber("任务号", "TN"); var date = DateTime.Now.ToString("yyMMdd"); return $"TN{date}{id.ToString().PadLeft(4, '0')}"; } internal static bool UpdateStatus(TN_Task task, string status) { var res = false; var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); task.S_B_STATE = status; res = db.Updateable(task).UpdateColumns(it => new { it.S_B_STATE }).ExecuteCommand()>0; return res; } internal static bool UpdateStatus(TN_Task task) { var res = false; var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); task.S_B_STATE = TN_Task.GetStateStr(task.N_B_STATE); task.T_MODIFY = DateTime.Now; db.Updateable(task).UpdateColumns(it => new { it.N_B_STATE, it.S_B_STATE, it.T_MODIFY }).ExecuteCommand(); @@ -35,16 +34,53 @@ internal static bool UpdateEQNo(TN_Task task) { var res = false; var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); task.T_MODIFY = DateTime.Now; db.Updateable(task).UpdateColumns(it => new { it.S_EQ_TASK_CODE, it.T_MODIFY }).ExecuteCommand(); return res; } internal static TN_Task GetTask(string no) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var task = db.Queryable<TN_Task>().Where(a => a.S_CODE == no).First(); return task; } public static TN_Task BuildTask(TN_Location startLoc, TN_Location endLoc, string cntId, string type) { 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_TYPE = type, N_PRIORITY = 3, N_SCHEDULE_TYPE = 3, // 国自 N_B_STATE = 0, S_CNTR_CODE = cntId, }; return TN_Task; } public static TN_Task BuildInboundTask(TN_Location startLoc, string endLocCode, string cntId) { var type = TaskName.产品入库; var endArea = "HJQ"; TN_Task TN_Task = new TN_Task() { S_CODE = GenerateTaskNo(), S_START_AREA = startLoc.S_AREA_CODE, S_END_AREA = endArea, S_START_LOC = startLoc.S_CODE, S_END_LOC = endLocCode, S_TYPE = type, N_PRIORITY = 3, N_SCHEDULE_TYPE = 3, // 国自 N_B_STATE = 0, S_CNTR_CODE = cntId, }; return TN_Task; } /// <summary> @@ -90,7 +126,7 @@ }; var log = JsonConvert.SerializeObject(TN_Task); var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var res = db.Insertable(TN_Task).ExecuteCommand() > 0; if (res) { @@ -130,7 +166,7 @@ }); } var log = JsonConvert.SerializeObject(tN_Tasks); var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var res = db.Insertable<TN_Task>(tN_Tasks).ExecuteCommand() > 0; if (res) { @@ -148,13 +184,13 @@ internal static bool CheckActionRecordExist(string no, int code) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); return db.Queryable<TN_Task_Action>().Count(a => a.S_TASK_CODE == no && a.N_ACTION_CODE == code) > 0; } internal static void Begin(TN_Task task, string forklift_no) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); if (task != null) { if (task.N_B_STATE == 1) @@ -169,7 +205,7 @@ } } internal static void End(TN_Task task) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); if (task != null) { task.N_B_STATE = 3; task.S_B_STATE = TN_Task.GetStateStr(task.N_B_STATE); @@ -178,7 +214,7 @@ } } internal static void Fail(TN_Task task) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); if (task != null) { //判断有没有取货完成,没有就变成失败。有取货完成默认完成了(跟据项目而定,有些项目人工拉走了也没有放到终点)。 task.N_B_STATE = 4; @@ -189,7 +225,7 @@ internal static bool AddActionRecord(string no, int state, string forkliftNo, string extData) { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); var action = new TN_Task_Action() { N_ACTION_CODE = state, @@ -202,7 +238,7 @@ } internal static List<TN_Task> GetWaitingTaskList() { var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); return db.Queryable<TN_Task>().Where(a => a.N_B_STATE == 0 && (a.S_B_STATE == "等待" || a.S_B_STATE == "待推送")).ToList(); } } wms/WMSHelper.cs
File was renamed from Helpers/WMSHelper.cs @@ -1,6 +1,6 @@ using HH.WCS.Mobox3.AnGang.Controllers; using HH.WCS.Mobox3.AnGang.Dispatch; using HH.WCS.Mobox3.AnGang.Models; using HH.WCS.Mobox3.AnGang.api; using HH.WCS.Mobox3.AnGang.dispatch; using HH.WCS.Mobox3.AnGang.models; using HH.WCS.Mobox3.AnGang.config; using System; using System.Collections.Generic; @@ -10,11 +10,10 @@ using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading.Tasks; using static HH.WCS.Mobox3.AnGang.Controllers.ApiModel; using HH.WCS.Mobox3.AnGang.Helpers; using static HH.WCS.Mobox3.AnGang.Dtos.Response.MoboxResponse; using static HH.WCS.Mobox3.AnGang.api.ApiModel; using HH.WCS.Mobox3.AnGang.util; namespace HH.WCS.Mobox3.AnGang.Helper namespace HH.WCS.Mobox3.AnGang.wms { /// <summary> /// wms管到作业 @@ -29,7 +28,7 @@ internal static SimpleResult PDACancleTask(CancleTaskInfo model) { SimpleResult simpleResult = new SimpleResult(); var db = DbHelper.GetDbClient(); var db = new SqlHelper<object>().GetInstance(); try { if (model.taskNO.Length > 0)