using Dm.filter; using DocumentFormat.OpenXml.Drawing.Charts; using DocumentFormat.OpenXml.Office.CustomUI; using DocumentFormat.OpenXml.Presentation; using Elastic.Clients.Elasticsearch; using Furion.Logging; using Newtonsoft.Json; using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using WCS.Application.Entity; namespace WCS.Application; /// /// 示例开放接口 /// [ApiDescriptionSettings("开放接口", Name = "Demo", Order = 100)] //[Authorize(AuthenticationSchemes = SignatureAuthenticationDefaults.AuthenticationScheme)] [AllowAnonymous] public class DemoOpenApi : IDynamicApiController { private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId); private readonly UserManager _userManager; public DemoOpenApi(UserManager userManager) { _userManager = userManager; } //[HttpGet("helloWord")] //public Task HelloWord() //{ // return Task.FromResult($"Hello word. {_userManager.Account}"); //} // /// WCS接受WMS下发的任务(单条任务) /// /// 任务信息 /// 反馈信息 [AllowAnonymous] public ResponseModel AddWcsTasks(List modelList) { ResponseModel result = new ResponseModel(); result.StatusCode = 0; try { foreach (var models in modelList) { var res = AddWcsTask(models); if (res.StatusCode == -1) { result.StatusCode = -1; result.Msg = res.Msg; } else if (res.StatusCode == 0) { result.StatusCode = 0; result.Msg = models.TaskNo + "任务" + res.Msg; } } } catch (Exception ex) { return new ResponseModel() { StatusCode = -1, Msg = ex.Message }; } return result; } /// /// WCS接受WMS下发的任务(单条任务) /// /// 任务信息 /// 反馈信息 [AllowAnonymous] public ResponseModel AddWcsTask(ResponseTasksModel models) { ResponseModel result = new ResponseModel(); try { string str = JsonConvert.SerializeObject(models); Log.Information("接收WMS出入库任务,任务号:" + models.TaskNo + ",托盘号:"+ models.PalletNo); // 验证任务是否已存在 var taskInfo = _db.Queryable().First(w => w.TaskNo == models.TaskNo); if (taskInfo != null) { result.StatusCode = -1; result.Msg = "任务:" + models.TaskNo + ";已存在!"; return result; } if (models.TaskType == "0" && models.TaskType == "0") { models.Order = 1; } else { models.Order = 2; } Enum type; var bale = "0"; var nqty = "0"; var ncomqty = "0"; if (models.TaskType == "0" ) { type = TaskTypeEnum.In; } else if (models.TaskType == "1") { type = TaskTypeEnum.Out; } else if (models.TaskType == "3") { type = TaskTypeEnum.In; bale = "1";//裹包 } else { type = TaskTypeEnum.Move; } if (!string.IsNullOrEmpty( models.Qty)) { nqty = models.Qty; } if (!string.IsNullOrEmpty(models.CompleteQty)) { nqty = models.CompleteQty; } //新增任务 var taskAdd = new WcsTask() { TaskNo = models.TaskNo, TaskType = (TaskTypeEnum?)type, Status = TaskStatusEnum.Wait, //IsSuccess =TaskSuccessEnum.Success, Levels = 999, Origin = "WMS", StartRoadway = models.StartRoadway, StartLocate = models.StartLocate, EndLocate = models.EndLocate, EndRoadway = models.EndRoadway, PalletNo = models.PalletNo, IsBale = bale, LotNo = models.LotNo, SkuName = models.SkuName, Qty = int.Parse(nqty), CompleteQty = int.Parse(ncomqty), OrderNo = models.OrderNo }; _db.Insertable(taskAdd).ExecuteCommand(); return new ResponseModel() { StatusCode = 0, Msg = "插入成功" }; } catch (Exception ex) { return new ResponseModel() { StatusCode = -1, Msg = ex.Message }; } } /// /// WCS接收WMS下发的出入库单任务 /// /// /// [HttpPost] [AllowAnonymous] public ResponseModel AddOrderTask(List models) { ResponseModel result = new ResponseModel(); try { foreach (var item in models) { string str = JsonConvert.SerializeObject(models); Log.Information("接收WMS推送的箱码信息:" + str); // 验证任务是否已存在 //var taskInfo = _db.Queryable().First(w => w.OrderNo == item.OrderNo && w.SkuNo == item.SkuNo && w.LotNo == item.LotNo); //if (taskInfo == null) //{ //var taskid = _db.Queryable().OrderByDescending(w=>w.CreateTime).First(); //int newid = (int)taskid.Id + 1; 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, CreateTime = DateTime.Now, Status = TaskStatusEnum.Wait, }; _db.Insertable(orderAdd).ExecuteCommand(); //} } return new ResponseModel() { StatusCode = 0, Msg = "插入成功" }; } catch (Exception ex) { return new ResponseModel() { StatusCode = -1, Msg = ex.Message }; } } /// /// WCS接受赋码系统推送的箱码信息 /// /// 箱码信息 /// 反馈信息 [HttpPost] [AllowAnonymous] public ResponseFuMaModel AddHttpBoxInfo(FumaBoxInfoInput models) { try { string str = JsonConvert.SerializeObject(models); Log.Information("接收赋码推送的箱码信息:"+str); if (models.Origin != "赋码") { throw new Exception("来源未识别"); } var num = _db.Queryable().Where(m=>m.BoxNo == models.BoxNo && m.IsDelete == false).ToList(); var type = "add"; if (num.Count>0) { //WCS存在箱码信息,更新箱码信息(需判断箱码是否已组盘入库) var num2 = num.Count(m => m.Status != "0" || !string.IsNullOrWhiteSpace(m.PalletNo)); if (num2 > 0) { throw new Exception("该箱已入盘入库,不可更新信息"); } type = "edit"; } if (models.DelistList.Count == 0) { throw new Exception("盒码集合不能为空"); } 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 new Exception("支码集合不能为空"); } //二级码 foreach (var item2 in item.DelistList2) { if (string.IsNullOrWhiteSpace(models.ProductionTime) || string.IsNullOrWhiteSpace(models.ExpirationTime)) { throw new Exception("生产日期或失效日期不能为空"); } DateTime proTime; DateTime expTime; var isValid = DateTime.TryParse(models.ProductionTime, out proTime); var isValid2 = DateTime.TryParse(models.ExpirationTime, out expTime); if (!isValid || !isValid2) { throw new Exception("生产日期或失效日期格式错误"); }; DateTime? stortime = null; if (!string.IsNullOrWhiteSpace(models.StoreTime)) { stortime = DateTime.Parse(models.StoreTime); } var boxAdd = new WcsBoxInfo() { BoxNo = models.BoxNo, //OrderNo = models.OrderNo, SkuNo = models.SkuNo, SkuName = models.SkuName, Standard = models.Standard, LotNo = models.LotNo, LineNo = models.LineNo, // 产线号或产线名称 Qty = item2.Qty, FullQty = models.FullQty, //SupplierLot = models.SupplierLot, InsPectMark = models.InsPectMark, BitBoxMark = models.BitBoxMark, //InspectStatus = models.InspectStatus, ProductionTime = proTime, ExpirationTime = expTime, StoreTime = stortime, EndLotFlag = string.IsNullOrWhiteSpace(models.EndBatchMark) ? "0" : models.EndBatchMark, BoxNo2 = item.BoxNo2, BoxNo3 = item2.BoxNo3, QtyCount = item2.QtyCount, QtyOrd = item2.QtyOrd, Status = "0", Level = level, IsDelete = false }; listBox.Add(boxAdd); } } _db.Insertable(listBox).ExecuteCommand(); if (type == "edit") { //gen _db.Deleteable(num).ExecuteCommand(); return new ResponseFuMaModel() { Success = "0", Message = "更新成功" }; } return new ResponseFuMaModel() { Success = "0", Message = "插入成功" }; } catch (Exception ex) { return new ResponseFuMaModel() { Success = "-1", Message = ex.Message }; } } /// /// WCS接受赋码系统推送的箱码移除 /// /// 箱码信息 /// 反馈信息 [HttpPost] [AllowAnonymous] public ResponseFuMaModel DelgatesHttpBoxInfo(FumaBoxInfoInput models) { try { string str = JsonConvert.SerializeObject(models); Log.Information("接收赋码推送的箱码移除:" + str); var num = _db.Queryable().Where(m => m.BoxNo == models.BoxNo && m.IsDelete == false).ToList(); if (num.Count > 0) { //WCS存在箱码信息,更新箱码信息(需判断箱码是否已组盘入库) var num2 = num.Count(m => m.Status != "0" || !string.IsNullOrWhiteSpace(m.PalletNo)); if (num2 > 0) { throw new Exception("该箱已盘入库,不可更新信息"); } } if (num.Count == 0) { throw new Exception("未找到该箱码,箱码移除失败!"); } _db.Deleteable(num).ExecuteCommand(); return new ResponseFuMaModel() { Success = "0", Message = "移除箱码成功" }; } catch (Exception ex) { return new ResponseFuMaModel() { Success = "-1", Message = ex.Message }; } } /// /// WCS接受赋码系统推送的结批总数量 /// /// 结批数量信息 /// 反馈信息 [HttpPost] [AllowAnonymous] public ResponseFuMaModel HttpTotalNum(FumaJiepiModel models) { try { string str = JsonConvert.SerializeObject(models); Log.Information("接收赋码推送的完工结批总数量:" + str); //查看赋码下发的任务信息是否正在分拣 var num = _db.Queryable().Where(m => m.SkuNo == models.SkuNo &&m.LotNo == models.LotNo && m.Status == "1").ToList(); if (num.Count < 1) { return new ResponseFuMaModel() { Success = "-1", Message = "该批次未进行分拣或已结批" }; } int Fqty = int.Parse(models.FinishQty); int Jpqty = 0; //写入该任务完成数量 foreach (var item in num) { int jp = 0;//结批是否需要组盘0:不需要,1:需要。不需要组盘则直接释放分道,需要组盘则下发PLC预结批信号 item.FinishQty = Fqty; //判断当前单据码垛数量是否和完工数量相等,是则结批该单据 //获取已组盘数量 var checkNum = _db.Queryable().Where(m => m.SkuNo == models.SkuNo && m.LotNo == models.LotNo && m.OrderCode == item.OrderNo).ToList();//组盘表箱码信息 if (checkNum.Count>0) { if (!(string.IsNullOrEmpty(checkNum.First().BoxNo2))||!(string.IsNullOrEmpty(checkNum.First().BoxNo3)))//有支码 { foreach (var item2 in checkNum) { Jpqty = (int)(Jpqty + item2.Qty); } } else//无支码 { foreach (var item2 in checkNum) { Jpqty = (int)(Jpqty + item2.QtyCount); } } } //获取已插码数量 var checkNum2 = _db.Queryable().Where(m =>m.BitBoxMark != "1" && m.SkuNo == models.SkuNo && m.LotNo == models.LotNo &&(m.PalletNo != null || m.PalletNo != "") && m.OrderCode == item.OrderNo).ToList();//箱码表已码垛箱码信息 if (checkNum2.Count>0) { jp = 1;//箱码表还有未组盘箱,需要组盘 if (!string.IsNullOrEmpty(checkNum2.First().BoxNo2)||!string.IsNullOrEmpty(checkNum2.First().BoxNo3))//有支码 { foreach (var item2 in checkNum2) { Jpqty = (int)(Jpqty + item2.Qty); } } else//无支码 { foreach (var item2 in checkNum2) { Jpqty = (int)(Jpqty + item2.QtyCount); } } } //获取零箱数量 var checkNum3 = _db.Queryable().Where(m => m.BitBoxMark == "1" && m.SkuNo == models.SkuNo && m.LotNo == models.LotNo).ToList(); if (checkNum3.Count > 0) { if (!string.IsNullOrEmpty(checkNum3.First().BoxNo2) || !string.IsNullOrEmpty(checkNum3.First().BoxNo3))//有支码 { foreach (var item3 in checkNum3) { Jpqty = (int)(Jpqty + item3.Qty); } } else//无支码 { foreach (var item3 in checkNum3) { Jpqty = (int)(Jpqty + item3.QtyCount); } } } if (Jpqty == Fqty) { var modPlc = _db.Queryable().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Text == ("2层托盘输送线")).First(); if (modPlc == null) throw Oops.Bah("未找到输送线PLC"); PLCUtil plcConn = new PLCUtil(modPlc); //判断当前分道是否有未组盘箱 if (jp == 0) { // 分道解绑,抓箱品种写入0 var ret1 = plcConn.SetPlcDBValue(item.PosTypeLot, item.DbNumber, item.PlcPos, "0"); if (ret1.IsSucceed) { //更新入库订单 var orderTask = _db.Queryable().Where(w => w.SkuNo == item.SkuNo && w.LotNo == item.LotNo && w.IsDelete == false).ToList(); if (orderTask.Count > 0) { foreach (var item2 in orderTask) { item2.Status = TaskStatusEnum.Complete; _db.Updateable(item2).ExecuteCommand(); } } //写入流程字成功后更新分拣任务 liudl 最后一托盘申请完入库才可清空 item.OrderNo = ""; item.TaskNo = ""; item.LotNo = ""; item.SkuNo = ""; item.SkuName = ""; item.BoxType = ""; item.Qty = 0; item.PZNo = ""; item.Status = "0"; // 绑定分道 0:解绑 1:绑定 item.FinishQty = 0; //更新分拣任务 _db.Updateable(item).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } } else { //预结批信号下发 var ret2 = plcConn.SetPlcDBValue(item.PosType, item.DbNumber, item.PosLot, "1");//写入开始结批信号 if (ret2.IsSucceed) { item.Status = "2";//结批中 } else { throw new Exception("完工结批信号下发给PLC错误"); } } _db.Updateable(item).ExecuteCommand(); } } return new ResponseFuMaModel() { Success = "0", Message = "接受完工结批数量成功" }; } catch (Exception ex) { return new ResponseFuMaModel() { Success = "-1", Message = ex.Message }; } } /// /// WCS接受WMS入库放货确认接口 /// /// /// 反馈信息 [HttpPost] [AllowAnonymous] public IsBaleModel2 HttpInConfirm(PortModel models) { try { string str = JsonConvert.SerializeObject(models); Log.Information("接收WMS入库放货确认,放货口:" + models.Port+"入库口"); var portno = models.Port; var layer = "3"; switch (models.Port) { case "033": portno = "33"; layer = "1"; break; case "039": portno = "39"; layer = "1"; break; case "044": portno = "44"; layer = "1"; break; case "051": portno = "51"; layer = "1"; break; } //检测入库口状态,120为可放,占用则修改为130 var modPlc = _db.Queryable().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Text == (layer + "层托盘输送线")).First(); if (modPlc == null) throw Oops.Bah("未找到输送线PLC"); PLCUtil plcConn = new PLCUtil(modPlc); //获取工位点位信息 var listPlcDevice = _db.Queryable().Where(s => s.LedIP != null && s.StationNum == portno).First(); var modDevice = _db.Queryable().Where(s => s.StationNum == portno && s.Text == "PLC").First(); var (res1, val) = plcConn.GetPlcDBValue(modDevice.PosType, listPlcDevice.DbNumber, modDevice.PlcPos); if (val.ToString() == "120") { //读取成功后写入130 modDevice = _db.Queryable().Where(s => s.StationNum == portno && s.Text == "WCS").First(); var ret = plcConn.SetPlcDBValue(modDevice.PosType, listPlcDevice.DbNumber, modDevice.PlcPos, "130");//占用此工位 if (ret.IsSucceed) { //回传WMS可放信号 return new IsBaleModel2() { Success = 0, Message = "接受成功" }; } } return new IsBaleModel2() { Success = -1, Message = "读取PLC点位信息失败" }; } catch (Exception ex) { return new IsBaleModel2() { Success = -1, Message = ex.Message }; } } /// /// WCS接受WMS入库放货请求接口 /// /// /// 反馈信息 [HttpPost] [AllowAnonymous] public IsBaleModel2 HttpInRequest(PortRequestModel models) { try { string str = JsonConvert.SerializeObject(models); Log.Information("接收WMS入库放货请求,放货口:" + models.Port + "入库口"); var portno = models.Port; var layer = "3"; switch (models.Port) { case "033": portno = "33"; layer = "1"; break; case "039": portno = "39"; layer = "1"; break; case "044": portno = "44"; layer = "1"; break; case "051": portno = "51"; layer = "1"; break; } var modPlc = _db.Queryable().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Text == (layer + "层托盘输送线")).First(); if (modPlc == null) throw Oops.Bah("未找到输送线PLC"); PLCUtil plcConn = new PLCUtil(modPlc); //获取工位点位信息 var listPlcDevice = _db.Queryable().Where(s=>s.LedIP != null && s.StationNum == portno).First(); var modDevice = _db.Queryable().Where(s => s.StationNum == portno && s.Text == "任务号").First(); plcConn.SetPlcDBValue(modDevice.PosType, listPlcDevice.DbNumber, modDevice.PlcPos, models.TaskNo);//写入任务号 // modDevice = _db.Queryable().Where(s => s.StationNum == portno && s.Text == "WCS").First(); var ret = plcConn.SetPlcDBValue(modDevice.PosType, listPlcDevice.DbNumber, modDevice.PlcPos, "140");//写入开始放货信号 if (ret.IsSucceed) { //回传WMS放货信号 return new IsBaleModel2() { Success = 0, Message = "接受成功" }; } return new IsBaleModel2() { Success = -1, Message = "读取PLC点位信息失败" }; } catch (Exception ex) { return new IsBaleModel2() { Success = -1, Message = ex.Message }; } } /// /// WCS接受WMS小车放完成接口 /// /// /// 反馈信息 [HttpPost] [AllowAnonymous] public IsBaleModel2 HttpInFinish(PortModel models) { try { string str = JsonConvert.SerializeObject(models); Log.Information("接收WMS入库放货完成,放货口:" + models.Port + "入库口"); var portno = models.Port; var layer = "3"; switch (models.Port) { case "033": portno = "33"; layer = "1"; break; case "039": portno = "39"; layer = "1"; break; case "044": portno = "44"; layer = "1"; break; case "051": portno = "51"; layer = "1"; break; } var modPlc = _db.Queryable().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Text == (layer + "层托盘输送线")).First(); if (modPlc == null) throw Oops.Bah("未找到输送线PLC"); PLCUtil plcConn = new PLCUtil(modPlc); //获取工位点位信息 var listPlcDevice = _db.Queryable().Where(s => s.LedIP != null && s.StationNum == portno).First(); var modDevice = _db.Queryable().Where(s => s.StationNum == portno && s.Text == "WCS").First(); var ret = plcConn.SetPlcDBValue(modDevice.PosType, listPlcDevice.DbNumber, modDevice.PlcPos, "160");//放完成 if (ret.IsSucceed) { //回传WMS放货信号 return new IsBaleModel2() { Success = 0, Message = "接受成功" }; } return new IsBaleModel2() { Success = -1, Message = "读取PLC点位信息失败" }; } catch (Exception ex) { return new IsBaleModel2() { Success = -1, Message = ex.Message }; } } }