using Admin.Core.IRepository; using Admin.Core.Service; using Admin.Core.IService; using Admin.Core.Model; using Admin.Core.Common; using System.Threading.Tasks; using System.Linq; using SqlSugar; using System; using log4net; using Admin.Core.Model.ViewModels; using System.Collections.Generic; using System.Threading; using Admin.Core.PlcServer; namespace Admin.Core.Service { public class xl_materialServices : BaseServices, Ixl_materialServices { private static readonly log4net.ILog log = LogManager.GetLogger(typeof(xl_materialServices)); private readonly IBaseRepository _dal; private readonly Ixl_materialRepository _xl_materialRepository; private readonly IPmt_BinRepository _pmt_BinRepository; private readonly Ixl_planRepository _planRepository;//小料计划 private readonly IHw_BarrelRepository _hw_BarrelRepository; private readonly ILR_planRepository _lrPlanRepository; private readonly Ixl_weighRepository _xlWeighRepository; private readonly IBinFeedingReportRepository _binFeedingReportRepository; bool flag = true; int i = 0; #region 构造函数 public xl_materialServices(IBaseRepository dal, Ixl_materialRepository xl_materialRepository, IPmt_BinRepository pmt_BinRepository,Ixl_planRepository planRepository, IHw_BarrelRepository hw_BarrelRepository, ILR_planRepository lrPlanRepository, Ixl_weighRepository xlWeighRepository, IBinFeedingReportRepository binFeedingReportRepository) { this._dal = dal; base.BaseDal = dal; _xl_materialRepository = xl_materialRepository; _pmt_BinRepository = pmt_BinRepository; _planRepository = planRepository; _hw_BarrelRepository = hw_BarrelRepository; _lrPlanRepository = lrPlanRepository; _xlWeighRepository = xlWeighRepository; _binFeedingReportRepository = binFeedingReportRepository; } #endregion #region 小料投料执行类型防差错 /// /// 执行类型防差错 /// /// 料仓号 /// 状态 /// 物料编码 /// 物料重量 /// 物料二维码 /// public async Task> ExecPlcState(int binSerial, int state, string materialCode, decimal weight,string? barCode) { MessageModel mesage=new MessageModel(); log.Info(materialCode + "|" + weight); string station = string.Empty; try { if (string.IsNullOrEmpty(barCode.Trim())) { mesage.success = false; mesage.msg = "原材料二维码为空!请检查后重试"; return mesage; } station = GetStationPoint(binSerial, station); var plcList = PlcHelper.siemensList.SingleOrDefault(d => d.EquipName.Equals("小料PLC")); if (plcList.plc.IsConnected) { int ponintVal= plcList.plc.ReadInt16(station); if (ponintVal == 1) { mesage.success = false; mesage.msg = "锁已开,无需重复操作!"; return mesage; } var pmtBin = await _pmt_BinRepository.FirstAsync(d => d.Bin_Serial == binSerial); var material = await _xl_materialRepository.FirstAsync(d => d.ID == pmtBin.Material_ID); if (!string.IsNullOrEmpty(barCode.Trim())) { string[] str = barCode.Split("-"); //保存料仓投料重量 Hw_BinTypeErrorPreventionReport hw = new Hw_BinTypeErrorPreventionReport() { BinID = binSerial, Bin_Name = pmtBin.Bin_Name, Bin_Code = pmtBin.Bin_Code, MaterialID = pmtBin.Material_ID, MaterialName = material.Material_name, Material_Code = material.Material_code, Material_InventoryCode = str[0], Material_BatchNumber = str[1], Material_SerialCode = str[2], BarCodeStr = barCode, CreateTime = DateTime.Now }; Hw_BinAlarm binAlarm = new Hw_BinAlarm(); binAlarm.BinId = binSerial; binAlarm.BinName = pmtBin.Bin_Name; binAlarm.MaterialCode = pmtBin.Material_ID; binAlarm.MaterialName = material.Material_name; binAlarm.Weights = weight; binAlarm.TypeName = "入库"; binAlarm.CreateTime = DateTime.Now; //同时记录该扫码到数据库中 pmtBin.BinWeight = pmtBin.BinWeight + weight; bool saveResult = await _pmt_BinRepository.AddData(binAlarm, hw, pmtBin); } bool result = plcList.plc.WriteInt16(station, state.ToString());//写入开锁点位 if (result) { mesage.success = true; mesage.msg = "开锁成功!"; } else { mesage.success = true; mesage.msg = "开锁失败!"; } return mesage; } mesage.success = false; mesage.msg = "PLC连接失败!"; return mesage; } catch (Exception ex) { mesage.success = false; mesage.msg = $"开锁异常:{ex.Message}!"; return mesage; } } #region 获取料仓 /// /// 获取料仓 /// /// /// /// private static string GetStationPoint(int binSerial, string station) { #region 获取点位-小料料仓 switch (binSerial) { case 1: station = "DB127.DBW2"; break; case 2: station = "DB127.DBW4"; break; case 3: station = "DB127.DBW6"; break; case 4: station = "DB127.DBW8"; break; case 5: station = "DB127.DBW10"; break; case 6: station = "DB127.DBW12"; break; case 7: station = "DB127.DBW14"; break; case 8: station = "DB127.DBW16"; break; case 9: station = "DB127.DBW18"; break; case 10: station = "DB127.DBW20"; break; case 11: station = "DB127.DBW22"; break; case 12: station = "DB127.DBW24"; break; case 13: station = "DB127.DBW26"; break; case 14: station = "DB127.DBW28"; break; case 15: station = "DB127.DBW30"; break; case 16: station = "DB127.DBW32"; break; case 17: station = "DB127.DBW34"; break; case 18: station = "DB127.DBW36"; break; case 19: station = "DB127.DBW38"; break; case 20: station = "DB127.DBW40"; break; case 21: station = "DB127.DBW42"; break; case 22: station = "DB127.DBW44"; break; case 23: station = "DB127.DBW46"; break; case 24: station = "DB127.DBW48"; break; case 25: station = "DB127.DBW50"; break; case 26: station = "DB127.DBW52"; break; case 27: station = "DB127.DBW54"; break; case 28: station = "DB127.DBW56"; break; default: break; } #endregion return station; } #endregion #endregion #region 根据料仓条码获取物料 /// /// 根据料仓条码获取物料 /// /// /// //public async Task> GetByBinCode(string code) //{ // BinView view = new BinView(); // var binList = await _pmt_BinRepository.QueryAsync(); // if (binList == null) return null; // Pmt_Bin bin = binList.FirstOrDefault(d => d.Bin_Code == code); // var _materialList = await _xl_materialRepository.QueryAsync(d => d.IsEnable == "是"); // if (_materialList == null) return null; // xl_material mater = _materialList.Where(d => d.ID == bin.Material_ID).Take(1).FirstOrDefault(d => d.ID == bin.Material_ID); // log.Info($"测试1"); //view.Bin_Serial = bin.Bin_Serial; //view.Bin_Name = bin.Bin_Name; //view.Bin_Code = bin.Bin_Code; //view.Material_ID = bin.Material_ID; //view.Material_Name = "PRS-C-100";// mater.Material_name, //view.Material_code = "000524";// mater.Material_code // return view; //} #endregion #region 根据桶条码获取物料信息 /// /// 根据桶条码获取物料信息 /// /// /// public async Task GetByMaterialCode(string code) { try { var query = await _xl_materialRepository.QueryAsync(d=>d.IsEnable == "是"); if (query == null) return null; var m= query.FirstOrDefault(d => d.Material_code.Trim() == code.Trim()); return m; } catch (Exception ex) { log.Error(ex.Message); throw; } } #endregion #region 扫码料桶,绑定物料、重量批次信息 /// /// 扫码料桶,绑定物料、重量批次信息 /// /// /// /// public async Task BindBarrel(string code) { List down=new List(); if (flag) { flag = false; try { down = await _planRepository.GetDownLoadPlan(); if (down.Count() == 0) { return 0; } var exec = down.FirstOrDefault(); var plcList = PlcHelper.siemensList.SingleOrDefault(d => d.EquipName.Equals("小料PLC")); if (plcList.plc.IsConnected)// 000533 { if (plcList.plc.ReadInt16("DB110.DBW90").ObjToInt() == 1)//1:检量秤准备好 { decimal tcheckWeight = Convert.ToDecimal(plcList.plc.ReadInt16("DB104.DBW164")) / 1000;//检量秤重量 log.Info($"重量:{tcheckWeight}"); //绑定桶 var barrelList = await _hw_BarrelRepository.QueryAsync(); if (barrelList == null) return 1; Hw_Barrel barrel = barrelList.FirstOrDefault(d => d.BarCode == code.Trim()); bool bl = barrel == null?true:false; if (barrel == null) return 2; //if (!string.IsNullOrEmpty(barrel.MaterialID)) return 3;//判断桶是否绑定 barrel.MaterialID = exec.RecipeID;//配方主键 barrel.MaterialName = exec.Recipe_Name;//配方名称 barrel.PlanId = exec.Plan_Id; barrel.Weight = tcheckWeight; barrel.CreateDateTime = DateTime.Now; int tcheckBatch = GetTcheckBatch(plcList);//当前执行的车次 log.Info("批次:" + tcheckBatch.ToString()); if (tcheckBatch > 0) { int batch = exec.Plan_Num - tcheckBatch;//剩余批次 decimal error = exec.Total_Weight - Convert.ToDecimal(tcheckWeight);//实际误差 decimal total_Weight = exec.Plan_TotalWeight + tcheckWeight;//重量累加 decimal total_Error = exec.Plan_TotalError + error;//误差累加 decimal totalMaxError = exec.Total_Weight + exec.Total_Error;//最大值 decimal totalMinError = exec.Total_Weight - exec.Total_Error;//最小值 if (totalMinError <= tcheckWeight && tcheckWeight <= totalMaxError)//在误差之内 { await _hw_BarrelRepository.UpdateAsync(barrel); //total_Weight = total_Weight; //total_Error = total_Error; if (batch == 0) //完成 { log.Info($"no1>>剩余批次:{batch}>计划批次:{exec.Plan_Num}》当前批次》{tcheckBatch}"); await _hw_BarrelRepository.UpdateAsync(barrel); var r = await UpdatePlanCompletedQuantity(plcList, exec.Plan_Id, tcheckBatch, 8, DateTime.Now, total_Weight, total_Error); //log.Info("称量完成:" + r); if (r) { //判断上位机判断当前值与配方总重,满足要求时,置“2” plcList.plc.WriteInt32("DB110.DBW88", 2);//2:上位机完成,实点位为DB110.DBW90 return 6; } else { return 99; } } else { log.Info($"no2>>剩余批次:{batch}>计划批次:{exec.Plan_Num}》当前批次》{tcheckBatch}"); await _hw_BarrelRepository.UpdateAsync(barrel); var r = await UpdatePlanCompletedQuantity(exec.Plan_Id, tcheckBatch, total_Weight, total_Error); //log.Info("称量未完成:" + r); if (r) { //判断上位机判断当前值与配方总重,满足要求时,置“2” plcList.plc.WriteInt32("DB110.DBW88", 2); return 6; } else { return 99; } } } else { //total_Weight = total_Weight / 100; //total_Error = total_Error / 100; if (batch == 0)//完成 { log.Info($"no3>>剩余批次:{batch}>计划批次:{exec.Plan_Num}》当前批次》{tcheckBatch}"); await _hw_BarrelRepository.UpdateAsync(barrel); bool r = await UpdatePlanCompletedQuantity(plcList,exec.Plan_Id, tcheckBatch, 8, DateTime.Now, total_Weight, total_Error); log.Info("超重-称量完成:" + r); if (r) { //6检量超差记录 plcList.plc.WriteInt32("DB110.DBW88", 6);//6:检量超差 return 6; } else { return 99; } } else { log.Info($"no4>>剩余批次:{batch}>计划批次:{exec.Plan_Num}》当前批次》{tcheckBatch}"); await _hw_BarrelRepository.UpdateAsync(barrel); bool r = await UpdatePlanCompletedQuantity(exec.Plan_Id, tcheckBatch, total_Weight, total_Error); log.Info("超重-称量未完成:" + r); if (r) { //6检量超差记录 plcList.plc.WriteInt32("DB110.DBW88", 6);//6:检量超差 return 6; } else { return 99; } } } } else { log.Error("检量称状态显示未完成"); return 110;//检量称状态显示未完成 } } else { log.Error("PLC连接失败"); return 110;//PLC连接失败 } } else { log.Error("执行批次未获取"); return 8;//执行批次未获取 } } catch (Exception ex) { log.Error(ex.Message); return 10;//异常报错 } finally { Thread.Sleep(100); flag = true; } } else { return 100;//处理中 } } private async Task AddReport(XlPlanView exec, int tcheckBatch, decimal total_Weight, decimal total_Error) { LR_plan lr = new LR_plan { Dosing_Id = "0", Plan_Id = exec.Plan_Id, Plan_Serial = exec.Plan_Serial, Equip_Code = "0", Recipe_ID = exec.RecipeID, Recipe_Code = "", Recipe_Name = exec.Recipe_Name, Version = exec.Version, Shift_Id = "", Shift_Class = "", Plan_Num = exec.Plan_Num, Real_Num = exec.Real_Num, Duration_Time = 0, End_Date = DateTime.Now.ToString(), Plan_Batch = tcheckBatch.ToString(), Total_Weight = total_Weight, Total_Error = total_Error, CreateTime = DateTime.Now }; await _lrPlanRepository.AddAsync(lr); } #endregion #region 更新计划数-完成 /// /// 更新计划完成数量-完成 /// /// 计划号 /// 完成数量 /// public async Task UpdatePlanCompletedQuantity(PlcModel mode, string planId, int quantity, int state, DateTime date, decimal totalWeight, decimal totalError) { try { var planList= await _planRepository.QueryAsync(); if (planList == null) return false; var plan= planList.FirstOrDefault(d=>d.Plan_Id== planId); if (plan == null) return false; plan.Real_Num = mode.plc.ReadInt16("DB110.DBW212"); plan.End_Date = date.ToString(); plan.Plan_State = state; plan.Plan_TotalWeight = totalWeight; plan.Plan_TotalError = totalError; plan.Plan_StateText = StateToShow(state); var result= await _planRepository.UpdateAsync(plan); return result; } catch (Exception) { return false; } } #endregion #region 更新计划数 /// /// 更新计划完成数量 /// /// 计划号 /// 完成数量 /// public async Task UpdatePlanCompletedQuantity(string planId, int quantity, decimal totalWeight, decimal totalError) { try { var planList = await _planRepository.QueryAsync(); if (planList == null) return false; var plan = planList.FirstOrDefault(d => d.Plan_Id == planId); if (plan == null) return false; plan.Real_Num = quantity; plan.Plan_TotalWeight = totalWeight; plan.Plan_TotalError = totalError; var result = await _planRepository.UpdateAsync(plan); return result; } catch (Exception) { return false; } } #endregion #region 将计划运行状态转换为文字进行显示 /// /// 将计划运行状态转换为文字进行显示 /// /// 计划状态代码 /// 显示的文字信息 public static string StateToShow(int stateNum) { string reStr = null; if (stateNum == 3) { reStr = "正在运行"; } else if (stateNum == 4) { reStr = "已下传"; } else if (stateNum == 5) { reStr = "未启动"; } else if (stateNum == 7) { reStr = "已终止"; } else if (stateNum == 8) { reStr = "已完成"; } return reStr; } #endregion #region 获取批次信息 public int GetTcheckBatch(PlcModel model) { int tb = 0; int i = 0; do { tb = model.plc.ReadInt16("DB110.DBW212"); i++; } while (i >3); log.Info("获取批次:" + tb); return tb; } #endregion #region 获取当前正在称量的物料 public Task GetCurrentMaterial() { //down = await _planRepository.GetDownLoadPlan(); //if (down.Count() == 0) { return 0; } return Task.CompletedTask; } #endregion #region 料框防错验证——只验证单料 public async Task> MaterialVerification(string barCode) { MessageModel messageModel = new MessageModel(); Hw_Barrel hw_Barrel = await _hw_BarrelRepository.FirstAsync(d => d.BarCode == barCode); if (hw_Barrel == null) { messageModel.msg = "未查询到当前料桶信息!"; messageModel.success = false; return messageModel; } xl_plan xl = await _planRepository.FirstAsync(d => d.Plan_State == 3); if (xl == null) { messageModel.msg = "未查询到计划执行信息!"; messageModel.success = false; return messageModel; } List xlList = await _xlWeighRepository.QueryAsync(d => d.Recipe_ID == xl.Recipe_ID); if (xlList.Count > 1) { messageModel.msg = "系统无法验证混合物料,只能验证称量单个物料!"; messageModel.success = false; return messageModel; } if (xlList.Count == 0) { messageModel.msg = "系统未查询到物料!"; messageModel.success = false; return messageModel; } xl_weigh Weigh = xlList.FirstOrDefault(d => d.Material_ID == hw_Barrel.Material_KeyID); if (Weigh != null) { var material = await _xl_materialRepository.FirstAsync(d => d.ID == Weigh.Material_ID); messageModel.msg = $"物料验证成功!当前桶物料为[{hw_Barrel.Material_KeyName}],称量物料为[{material.Material_name}]"; messageModel.success = true; return messageModel; } else { xl_weigh xl_weigh = xlList.First(); var material = await _xl_materialRepository.FirstAsync(d => d.ID == xl_weigh.Material_ID); messageModel.msg = $"物料验证失败!当前桶物料为[{hw_Barrel.Material_KeyName}],称量物料为[{material.Material_name}]"; messageModel.success = false; return messageModel; } } #endregion /// /// 小料上位机同步插入物料信息 /// /// /// /// /// /// public async Task xlInsertMaterial(string materialCode, string materialName) { try { xl_material xl_m = new xl_material() { ID = Guid.NewGuid().ToString("N"), Material_code = materialCode, Material_name = materialName, CreateDateTime = DateTime.Now, Remark = null, Batch_number = null, Barcode1 = null, Barcode2 = null, Barcode3 = null, IsEnable = "是" }; var result = await _xl_materialRepository.Add(xl_m); if (result == 1) { return true; } else { return false; } } catch (Exception ex) { return false; } } } }