using DocumentFormat.OpenXml.Presentation; using Elastic.Clients.Elasticsearch; using Furion.DatabaseAccessor; using Furion.Logging; using NewLife.Serialization; using Newtonsoft.Json; using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using WCS.Application.Entity; using Microsoft.AspNetCore.Mvc; using Admin.NET.Core.Service; using DocumentFormat.OpenXml.Bibliography; using AngleSharp.Common; using AngleSharp.Text; using Newtonsoft.Json.Linq; using SqlSugar; using NewLife.Reflection; namespace WCS.Application; /// /// 示例开放接口 /// [ApiDescriptionSettings("开放接口", Name = "OpenApi", Order = 100)] //[Authorize(AuthenticationSchemes = SignatureAuthenticationDefaults.AuthenticationScheme)] [AllowAnonymous] public class OpenApi : IDynamicApiController { private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private readonly UserManager _userManager; private readonly SysCacheService _sysCacheService; private readonly SysConfigService _sysConfigService; private readonly WcsTaskService _taskService; public OpenApi(UserManager userManager, SysCacheService sysCacheService, SysConfigService sysConfigService, WcsTaskService taskService) { _userManager = userManager; _sysCacheService = sysCacheService; _sysConfigService = sysConfigService; _taskService = taskService; } // /// WCS接受WMS下发的任务(多 /// 条任务) /// 任务信息 /// 反馈信息 /// [AllowAnonymous] [UnitOfWork] public async Task AddWcsTasks(List modelList) { var listTaskNo = modelList.Select(s => s.TaskNo).ToList(); // 验证任务是否已存在 var taskInfo = await _db.Queryable().CountAsync(w => listTaskNo.Contains(w.TaskNo)); if (taskInfo > 0) { throw Oops.Bah("任务已存在!"); } var listTask = new List(); foreach (var models in modelList) { if (models.TaskType == "0") { models.Order = 1; } else { models.Order = 2; } //新增任务 var taskAdd = new WcsTask() { TaskNo = models.TaskNo, TaskType = (TaskTypeEnum)Convert.ToInt32(models.TaskType), Type = models.Type, Status = TaskStatusEnum.Wait, Levels = 999, Origin = "WMS", StartRoadway = models.StartRoadway, StartLocate = models.StartLocate, EndLocate = models.EndLocate, EndRoadway = models.EndRoadway, PalletNo = models.PalletNo, }; listTask.Add(taskAdd); } await _db.Insertable(listTask).ExecuteCommandAsync(); } /// /// WCS接受WMS下发的任务(单条任务) /// /// 任务信息 /// 反馈信息 [AllowAnonymous] public async Task AddWcsTask(ResponseTasksModel models) { // 验证任务是否已存在 var taskInfo = await _db.Queryable().FirstAsync(w => w.TaskNo == models.TaskNo); if (taskInfo != null) { throw Oops.Bah("任务:" + models.TaskNo + ";已存在!"); } if (models.TaskType == "0") { models.Order = 1; } else { models.Order = 2; } //新增任务 var taskAdd = new WcsTask() { TaskNo = models.TaskNo, TaskType = TaskTypeEnum.Out, Status = TaskStatusEnum.Wait, Levels = 999, Origin = "WMS", StartRoadway = models.StartRoadway, StartLocate = models.StartLocate, EndLocate = models.EndLocate, EndRoadway = models.EndRoadway, PalletNo = models.PalletNo, }; await _db.Insertable(taskAdd).ExecuteCommandAsync(); } /// /// WCS接收WMS下发的入库单任务 /// /// /// [HttpPost] [AllowAnonymous] public async Task AddOrderTask(List models) { foreach (var item in models) { // 验证任务是否已存在 //var taskInfo = _db.Queryable().First(w => w.OrderNo == item.OrderNo && w.SkuNo == item.SkuNo && w.LotNo == item.LotNo); //if (taskInfo == null) //{ var orderAdd = new WcsOderTask() { OrderNo = item.OrderNo, TaskNo = "", LotNo = item.LotNo, SkuNo = item.SkuNo, SkuName = item.SkuName, BoxType = item.BoxType, Qty = item.Qty, TaskType = (TaskTypeEnum)item.TaskType, }; await _db.Insertable(orderAdd).ExecuteCommandAsync(); //} } } /// /// WCS接收赋码系统推送的箱码信息 /// /// 箱码信息 /// 反馈信息 [HttpPost] [AllowAnonymous] public async Task AddBoxInfo(FumaBoxInfoInput models) { if (models.Origin != "赋码") { throw Oops.Bah("来源未识别"); } var num = await _db.Queryable().Where(m => m.BoxNo == models.BoxNo).ToListAsync(); var type = "add"; if (num.Count > 0) { //WCS存在箱码信息,更新箱码信息(需判断箱码是否已组盘入库) var num2 = num.Count(m => m.Status != "0" || !string.IsNullOrWhiteSpace(m.PalletNo)); if (num2 > 0) { throw Oops.Bah("该箱已入盘入库,不可更新信息"); } type = "edit"; } if (models.DelistList.Count == 0) { throw Oops.Bah("盒码集合不能为空"); } var listBox = new List(); foreach (var item in models.DelistList) { var level = "3"; if (string.IsNullOrWhiteSpace(item.BoxNo2)) { level = "2"; } if (item.DelistList2.Count == 0) { throw Oops.Bah("值码集合不能为空"); } //二级码 foreach (var item2 in item.DelistList2) { if (string.IsNullOrWhiteSpace(models.ProductionTime) || string.IsNullOrWhiteSpace(models.ExpirationTime)) { throw Oops.Bah("生产日期或失效日期不能为空"); } DateTime proTime; DateTime expTime; var isValid = DateTime.TryParse(models.ProductionTime, out proTime); var isValid2 = DateTime.TryParse(models.ExpirationTime, out expTime); if (!isValid || !isValid2) { throw Oops.Bah("生产日期或失效日期格式错误"); }; var boxAdd = new WcsBoxInfo() { BoxNo = models.BoxNo, //OrderNo = models.OrderNo, SkuNo = models.SkuNo, SkuName = models.SkuName, Standard = models.Standard, LotNo = models.LotNo, Qty = item2.Qty, FullQty = models.FullQty, //SupplierLot = models.SupplierLot, InsPectMark = models.InsPectMark, BitBoxMark = models.BitBoxMark, //InspectStatus = models.InspectStatus, ProductionTime = proTime, ExpirationTime = expTime, StoreTime = DateTime.Parse(models.StoreTime), EndLotFlag = string.IsNullOrWhiteSpace(models.EndBatchMark) ? "0" : models.EndBatchMark, BoxNo2 = item.BoxNo2, BoxNo3 = item2.BoxNo3, QtyCount = item2.QtyCount, QtyOrd = item2.QtyOrd, Status = "0", Level = level, }; listBox.Add(boxAdd); } } await _db.Insertable(listBox).ExecuteCommandAsync(); if (type == "edit") { await _db.Deleteable(num).ExecuteCommandAsync(); } } /// /// AGV小车申请开门 /// /// /// [HttpPost] [NonUnify] public async Task AgvApplyLock(AGVApplyLockInput input) { AGVCallBackResponse result = new AGVCallBackResponse() { //ReqCode = input.ReqCode, Message = "成功", Code = "0" }; var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.ConveyorLine); if (modPlc == null) { result.Code = "1"; result.Message = "找不到PLC信息"; } else { var modUtil = new PLCUtil(modPlc); string text = ""; if (input.DeviceIndex == "111") { text = "3号卷帘门"; } else if (input.DeviceIndex == "222") { text = "2号卷帘门"; } else { result.Code = "1"; result.Message = "卷帘门编号错误"; return result; } var modDevice = await _db.Queryable().FirstAsync(s => s.Text == text); if (modDevice == null) { result.Code = "1"; result.Message = "找不到卷帘门设备信息"; } else { if (input.ActionTask == "applyLock") { var (plcResult, value) = modUtil.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos); if (plcResult.IsSucceed) { //写入10申请开门,等待写入20返回结果让小车通过 plcResult = modUtil.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "10"); if (!plcResult.IsSucceed) { result.Code = "1"; result.Message = "打开卷帘门写入值失败"; } else { _sysCacheService.Set("OpenDoor" + input.DeviceIndex, input); } } else { result.Code = "1"; result.Message = "获取卷帘门状态失败"; } } else { var (plcResult, value) = modUtil.GetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos); if (plcResult.IsSucceed && value != 0) { plcResult = modUtil.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "30"); if (!plcResult.IsSucceed) { result.Code = "1"; result.Message = "关闭卷帘门写入值失败"; } } else { result.Code = "1"; result.Message = "获取卷帘门状态失败"; } } } } return result; } /// /// AGV小车回调 /// /// /// [HttpPost] [NonUnify] [UnitOfWork] public async Task agvCallback(AGVCallBackInput input) { AGVCallBackResponse result = new AGVCallBackResponse() { ReqCode = input.ReqCode, Message = "成功", Code = "0" }; if (input.TaskCode.Substring(0, 3) != "WCS" && input.TaskCode.Substring(0, 2) != "TK") return result; PLCUtil modUtil = null; try { var modTask = await _db.Queryable().FirstAsync(s => s.TaskNo == input.TaskCode); if (modTask != null) { switch (input.Method) { case "end"://任务完成 { PLCService.AGVStatus = false; //把成品货物拉到缓存工位后,下一个任务把托盘拉去提升机或者缓存区(优先级低一点) if (modTask.EndLocate == AGVStaionEnum.C1.ToString() || modTask.EndLocate == AGVStaionEnum.C2.ToString()) { var strEndLocate = ""; Enum.TryParse(await _sysConfigService.GetConfigValue("workshop_Trend"), out WorkshopEnum workshop); if (workshop == WorkshopEnum.Storage) strEndLocate = AGVStaionEnum.A1.ToString(); else strEndLocate = AGVStorageUtil.GetProductInStorage(); WcsTask modInsertTask = new WcsTask() { TaskNo = _taskService.GetTaskCode(), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = modTask.EndLocate,//缓存区 EndLocate = strEndLocate, PalletNo = modTask.PalletNo, Status = TaskStatusEnum.Wait, Levels = 6, Origin = "WCS" }; await _db.Insertable(modInsertTask).ExecuteCommandAsync(); HubUtil.PublicTask(modInsertTask.Adapt()); } //货品拉到电梯口需要向输送线写入100 if (modTask.EndLocate == AGVStaionEnum.A1.ToString()) { var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Text == "输送线"); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.First(s => s.Text == "C口"); var modStation = PLCTaskAction.plcPositions.First(s => s.Text == "C口申请入库"); var plcResult = modConn.SetPlcDBValue(modStation.PosType, modDevice.DbNumber, modStation.PlcPos, "100"); if (plcResult.IsSucceed) { WcsTaskMonitor modTaskMonitorPLC = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modStation.PlcPos, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modStation.Text}写入指令100,结果{plcResult.IsSucceed}", }; _db.Insertable(modTaskMonitorPLC).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitorPLC.Adapt()); } else { Log.Error("C口申请入库写入值100失败"); } } //放入拆托机后,向拆托机写入完成信号 if (modTask.EndLocate == AGVStaionEnum.D1.ToString()) { var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.PalletMachine); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.Text == "拆托机"); var res = modConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "0"); var modTaskMonitorPLC = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modDevice.WcsPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入完成信号0,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitorPLC).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitorPLC.Adapt()); modConn.Close(); } //if (modTask.EndLocate == AGVStaionEnum.B1.ToString() || modTask.EndLocate == AGVStaionEnum.B2.ToString()) //{ // var num = modTask.EndLocate.Substring(1, 1); // var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.RobotPalletizer && s.WareHouseNo == num); // var modConn = new PLCUtil(modPlc); // var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Level == DeviceLevelEnum.DB); // var res = modConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos, "0"); // var modTaskMonitorPLC = new WcsTaskMonitor() // { // TaskNo = modTask.TaskNo, // PlcId = modDevice.PlcId, // PlcName = modDevice.PlcPos, // Status = TaskStatusEnum.Doing, // InteractiveMsg = $"向{modDevice.Text}写入放托完成信号,结果{res.IsSucceed}", // }; // _db.Insertable(modTaskMonitorPLC).ExecuteCommand(); // HubUtil.PublicTaskMonitor(modTaskMonitorPLC.Adapt()); // modConn.Close(); //} if (modTask.EndLocate == AGVStaionEnum.F1.ToString()) { await _sysConfigService.UpdateConfigValue("cache_Materal", true); } if (modTask.StartLocate == AGVStaionEnum.F1.ToString()) { await _sysConfigService.UpdateConfigValue("cache_Materal", false); } modTask.Status = TaskStatusEnum.Complete; modTask.FinishDate = DateTime.Now; await _db.Updateable(modTask).ExecuteCommandAsync(); WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, //PlcId = modDevice.PlcId, PlcName = "AGV", StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, Status = TaskStatusEnum.Complete, InteractiveMsg = $"AGV小车反馈任务完成", }; await _db.Insertable(modTaskMonitor).ExecuteCommandAsync(); HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); if (modTask.Origin == "WMS") { HttpService httpService = new HttpService(); var inputs = new TaskRequestWMS(); inputs.TaskNo = modTask.TaskNo; inputs.PalletNo = modTask.PalletNo; inputs.TaskType = "2"; inputs.TaskStatus = "2"; var modResponseTask = httpService.RequestTask(inputs).Result; } //托盘进出缓存区 需要记录 if (new[] { "Z", "C" }.Contains(modTask.EndLocate.Substring(0, 1))) { await _sysConfigService.UpdateConfigValue($"cache_{modTask.EndLocate}", true); } if (new[] { "Z", "C" }.Contains(modTask.StartLocate.Substring(0, 1))) { await _sysConfigService.UpdateConfigValue($"cache_{modTask.StartLocate}", false); } } break; case "outbin"://走出储位 { //取空托完成后,向拆托机写入完成信号 if (modTask.StartLocate == AGVStaionEnum.D1.ToString() && (modTask.EndLocate == AGVStaionEnum.B1.ToString() || modTask.EndLocate == AGVStaionEnum.B2.ToString())) { var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.PalletMachine); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.Text == "拆托机"); var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice.Id && s.Text == "取托信号"); var res = modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "0"); WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入取托信号0,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice.Id && s.Text == "取托完成"); res = modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "1"); modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入取托完成1,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); modConn.Close(); } //todo:去码垛工位取货完成后,需要写PLC信号开启光幕 if ((modTask.StartLocate == AGVStaionEnum.B1.ToString() || modTask.StartLocate == AGVStaionEnum.B2.ToString()) && (modTask.EndLocate == AGVStaionEnum.C1.ToString() || modTask.EndLocate == AGVStaionEnum.C2.ToString())) { var num = modTask.StartLocate.Substring(1, 1); var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.RobotPalletizer && s.WareHouseNo == num); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Level == DeviceLevelEnum.DB); var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice.Id && s.Text == "开启光幕"); var res = modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "1"); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入开启光幕1,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); //写入光幕0 Task.Run(() => { var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Level == DeviceLevelEnum.DB); var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice.Id && s.Text == "开启光幕"); Thread.Sleep(1000); var res = modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "0"); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入开启光幕0,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); }); //向码垛机器人写取托完成信号 modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Level == DeviceLevelEnum.Station); res = modConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.PlcPos, "0"); modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入取托完成信号,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); modConn.Close(); } //起始工位是提升机取货工位 if (modTask.StartLocate == AGVStaionEnum.A2.ToString()) { var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.ConveyorLine); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Text == "C口"); var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice.Id && s.Text == "取走确认"); var res = modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "1"); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入取走确认,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); } } break; case "apply"://放货申请 { //todo:去码垛工位取货,需要写PLC信号关闭光幕 if ((modTask.StartLocate == AGVStaionEnum.B1.ToString() || modTask.StartLocate == AGVStaionEnum.B2.ToString()) && (modTask.EndLocate == AGVStaionEnum.C1.ToString() || modTask.EndLocate == AGVStaionEnum.C2.ToString())) { var no = modTask.StartLocate.Substring(1, 1); var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.RobotPalletizer && s.WareHouseNo == no); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.PlcId == modPlc.Id && s.Level == DeviceLevelEnum.DB); var modPos = PLCTaskAction.plcPositions.FirstOrDefault(s => s.DeviceId == modDevice.Id && s.Text == "关闭光幕"); var res = modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "1"); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入关闭光幕1,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); Task.Run(() => { Thread.Sleep(1000); modConn.SetPlcDBValue(modPos.PosType, modDevice.DbNumber, modPos.PlcPos, "0"); var modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = modDevice.PlcId, PlcName = modPos.PlcPos, Status = TaskStatusEnum.Doing, InteractiveMsg = $"向{modDevice.Text}写入开启光幕0,结果{res.IsSucceed}", }; _db.Insertable(modTaskMonitor).ExecuteCommand(); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); }); modConn.Close(); } } break; case "start"://任务开始 { //开始向拆托机放入托盘任务 if (modTask.EndLocate == AGVStaionEnum.D1.ToString()) { var modPlc = PLCTaskAction.plcs.FirstOrDefault(s => s.Type == PLCTypeEnum.PalletMachine); var modConn = new PLCUtil(modPlc); var modDevice = PLCTaskAction.plcDevices.FirstOrDefault(s => s.Text == "拆托机"); var res = modConn.SetPlcDBValue(modDevice.PosType, modDevice.DbNumber, modDevice.WcsPos, "1"); modConn.Close(); } var taskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcName = input.Method, InteractiveMsg = $"AGV小车反馈任务开始" }; await _db.Insertable(taskMonitor).ExecuteCommandAsync(); HubUtil.PublicTaskMonitor(taskMonitor.Adapt()); } break; case "cancel"://任务结束 { PLCService.AGVStatus = false; modTask.IsSuccess = TaskSuccessEnum.Fail; modTask.CancelDate = DateTime.Now; modTask.Status = TaskStatusEnum.Cancell; modTask.Levels = 999; await _db.Updateable(modTask).UpdateColumns(s => new { s.Status, s.IsSuccess, s.FinishDate, s.CancelDate, s.UpdateTime, s.UpdateUserId, s.UpdateUserName }).ExecuteCommandAsync(); //写入任务明细表 WcsTaskMonitor modTaskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, PlcId = 0, PlcName = "", Status = TaskStatusEnum.Complete, StartLocat = modTask.StartLocate, EndLocat = modTask.EndLocate, InteractiveMsg = "小车通知任务取消", PalletNo = modTask.PalletNo }; await _db.Insertable(modTaskMonitor).ExecuteCommandAsync(); HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(modTaskMonitor.Adapt()); } break; default: break; } } else { result.Code = "1"; result.Message = "找不到该任务"; } } catch (Exception ex) { result.Code = "1"; result.Message = ex.Message; } finally { modUtil?.Close(); } return result; } /// /// 修改原材料仓状态 /// /// [HttpPost] public async Task UpdateMateralStatus() { await _sysConfigService.UpdateConfigValue("cache_Materal", false); } /// /// 获取车间动向 /// /// [HttpPost] public async Task Workshop() { var result = Enum.TryParse(await _sysConfigService.GetConfigValue("workshop_Trend"), out WorkshopEnum workshop); return workshop; } /// /// 修改车间动向 /// /// [HttpPost] public async Task ChangeWorkshop(RequestTrends input) { await _sysConfigService.UpdateConfigValue("workshop_Trend", input.Type.ToString()); } /// /// 手动入托盘 /// /// //[HttpPost] //public async Task InPallet(RequestStorage input) //{ // var intPallet = _sysConfigService.GetConfigValue("cache_Pallet").Result; // if (intPallet + input.Qty > 3) // throw Oops.Bah($"输入数量大于可放置数"); // await _sysConfigService.UpdateConfigValue("cache_Pallet", (intPallet + input.Qty).ToString()); //} /// /// 成品缓存区入库 /// /// /// [HttpPost] [UnitOfWork] public async Task ProductStorage(RequestStorage input) { var intProduct = AGVStorageUtil.ProductCount(); var intTask = await _db.Queryable().Where(s => s.TaskType == TaskTypeEnum.Move && s.Type == PLCTypeEnum.AGV && s.Status <= TaskStatusEnum.Doing && s.StartLocate.StartsWith("Z") && s.EndLocate == AGVStaionEnum.A1.ToString()).CountAsync(); if (input.Qty > intProduct) throw Oops.Bah($"输入数量大于可出数量{intProduct}"); var listTask = new List(); var TaskNo = GetTaskCode("WCS"); for (int i = 0; i < input.Qty; i++) { listTask.Add(new WcsTask() { TaskNo = "WCS" + DateTime.Now.ToString("yyyyMMdd") + (TaskNo++).ToString().PadLeft(4, '0'), TaskType = TaskTypeEnum.Move, Type = PLCTypeEnum.AGV, StartLocate = AGVStaionEnum.Z11.ToString(), EndLocate = AGVStaionEnum.A1.ToString(), PalletNo = "", Status = TaskStatusEnum.Wait, Levels = 10, Origin = "PDA" }); } await _db.Insertable(listTask).ExecuteCommandAsync(); } /// /// 自动生成任务号 /// /// /// [NonAction] public static int GetTaskCode(string codeFlag = "WCS") { var list = _db.Queryable().Where(m => m.TaskNo.StartsWith("WCS")).ToList(); string maxNo = list.Max(m => m.TaskNo); if (!string.IsNullOrEmpty(maxNo)) { maxNo = maxNo.Substring(codeFlag.Length); } //获取数据库时间八位 string date = DateTime.Now.ToString("yyyyMMdd").Trim(); int no = 0; if (string.IsNullOrEmpty(maxNo)) { no = 1; } else { if (maxNo.Length == 12 && maxNo.Substring(0, 8) == date) { int lastNo = Convert.ToInt32(maxNo.Substring(8, 4)) + 1; no = lastNo; } else { no = 1; } } return no; } /// /// 完成任务 /// /// /// [HttpPost] public async Task FinishTask(WcsTask input) { if (input.TaskNo.IsNullOrEmpty()) throw Oops.Bah("任务号不能为空"); var modTask = await _db.Queryable().FirstAsync(s => s.TaskNo == input.TaskNo); if (modTask == null) throw Oops.Bah("找不到任务"); if (modTask.Status > TaskStatusEnum.Doing) throw Oops.Bah("任务状态不对"); modTask.FinishDate = DateTime.Now; modTask.Status = TaskStatusEnum.Complete; await _db.Updateable(modTask).ExecuteCommandAsync(); var taskMonitor = new WcsTaskMonitor() { TaskNo = modTask.TaskNo, InteractiveMsg = $"WMS调用完成任务" }; _db.Insertable(taskMonitor).ExecuteCommand(); //下发任务日志 HubUtil.PublicTask(modTask.Adapt()); HubUtil.PublicTaskMonitor(taskMonitor.Adapt()); } /// /// 查询缓存位状态 /// /// [HttpPost] public async Task> QueryCacheStorage() { string[] listPallet = new[] { "cache_Z11","cache_Z12","cache_Z13", "cache_Z21","cache_Z22","cache_Z23", "cache_Z31","cache_Z32","cache_Z33", "cache_Z41","cache_Z42","cache_Z43", "cache_Z51","cache_Z52","cache_Z53", }; Dictionary dic = new Dictionary(); foreach (var mod in listPallet) { dic.Add(mod.Split('_')[1], await _sysConfigService.GetConfigValue(mod)); } return dic; } /// /// 修改缓存位状态 /// /// [HttpPost] public async Task ChangeCacheStatus(StorageCacheStatus input) { Type type = input.GetType(); foreach (var item in type.GetProperties()) { string value = ""; var result = item.GetValue(input); if (!result.IsNullOrEmpty()) { if ((bool)item.GetValue(input)) value = "True"; else value = "False"; await _sysConfigService.UpdateConfigValue("cache_" + item.Name, value); } } } /// /// 查询小车正在执行的任务 /// /// [HttpPost] public async Task AGVTask() { return await _db.Queryable().Where(s => s.Type == PLCTypeEnum.AGV && s.Status == TaskStatusEnum.Doing).FirstAsync(); } /// /// 取消小车正在执行的任务 /// /// [HttpPost] public async Task CancelTask(WcsTask input) { await App.GetService().Finsh(new UpdateWcsTaskInput() { Id = input.Id, Status = TaskStatusEnum.Cancell }); } }