You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

815 lines
58 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<xl_material>, Ixl_materialServices
{
private static readonly log4net.ILog log = LogManager.GetLogger(typeof(xl_materialServices));
private readonly IBaseRepository<xl_material> _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<xl_material> 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 小料投料执行类型防差错
/// <summary>
/// 执行类型防差错
/// </summary>
/// <param name="binSerial">料仓号</param>
/// <param name="state">状态</param>
/// <param name="materialCode">物料编码</param>
/// <param name="weight">物料重量</param>
/// <param name="barCode">物料二维码</param>
/// <returns></returns>
public async Task<MessageModel<bool>> ExecPlcState(int binSerial, int state, string materialCode, decimal weight,string? barCode)
{
MessageModel<bool> mesage=new MessageModel<bool>();
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 获取料仓
/// <summary>
/// 获取料仓
/// </summary>
/// <param name="binSerial"></param>
/// <param name="station"></param>
/// <returns></returns>
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 根据料仓条码获取物料
/// <summary>
/// 根据料仓条码获取物料
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
//public async Task<MessageModel<BinView>> 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 根据桶条码获取物料信息
/// <summary>
/// 根据桶条码获取物料信息
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public async Task<xl_material> 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 扫码料桶,绑定物料、重量批次信息
/// <summary>
/// 扫码料桶,绑定物料、重量批次信息
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<int> BindBarrel(string code)
{
List<XlPlanView> down=new List<XlPlanView>();
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 更新计划数-完成
/// <summary>
/// 更新计划完成数量-完成
/// </summary>
/// <param name="planId">计划号</param>
/// <param name="quantity">完成数量</param>
/// <returns></returns>
public async Task<bool> 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 更新计划数
/// <summary>
/// 更新计划完成数量
/// </summary>
/// <param name="planId">计划号</param>
/// <param name="quantity">完成数量</param>
/// <returns></returns>
public async Task<bool> 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 将计划运行状态转换为文字进行显示
/// <summary>
/// 将计划运行状态转换为文字进行显示
/// </summary>
/// <param name="stateNum">计划状态代码</param>
/// <returns>显示的文字信息</returns>
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<MessageModel<bool>> MaterialVerification(string barCode)
{
MessageModel<bool> messageModel = new MessageModel<bool>();
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<xl_weigh> 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
/// <summary>
/// 小料上位机插入物料信息
/// </summary>
/// <param name="planDate"></param>
/// <param name="recipeGUID"></param>
/// <param name="batch"></param>
/// <param name="productName"></param>
/// <returns></returns>
public async Task<bool> xlInsertMaterial(
string id,
string materialCode,
string materialName,
int isEnable,
DateTime createDatetime)
{
try
{
xl_material xl_m = new xl_material()
{
ID = id,
Material_code = materialCode,
Material_name = materialName,
CreateDateTime = createDatetime,
Remark = null,
Batch_number = null,
Barcode1 = null,
Barcode2 = null,
Barcode3 = null,
IsEnable = isEnable == 1 ? "是" : "否"
};
var result = await _xl_materialRepository.Add(xl_m);
if (result == 1)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
throw;
}
}
/// <summary>
/// 小料上位机更新物料信息
/// </summary>
/// <param name="planDate"></param>
/// <param name="recipeGUID"></param>
/// <param name="batch"></param>
/// <param name="productName"></param>
/// <returns></returns>
public async Task<bool> xlUpdateMaterial(
string id,
string materialCode,
string materialName,
int isEnable,
DateTime createDatetime)
{
try
{
xl_material xl_m = new xl_material()
{
ID = id,
Material_code = materialCode,
Material_name = materialName,
CreateDateTime = createDatetime,
Remark = null,
Batch_number = null,
Barcode1 = null,
Barcode2 = null,
Barcode3 = null,
IsEnable = isEnable == 1 ? "是" : "否"
};
bool result = await _xl_materialRepository.UpdateAsync(xl_m, $"ID = '{id}'");
return result;
}
catch (Exception e)
{
throw;
}
}
/// <summary>
/// 获取小料上位机物料信息
/// </summary>
/// <param name="planDate"></param>
/// <param name="recipeGUID"></param>
/// <param name="batch"></param>
/// <param name="productName"></param>
/// <returns></returns>
public async Task<List<xl_material>> xlMaterialList()
{
try
{
return await _xl_materialRepository.QueryAsync();
}
catch (Exception ex)
{
throw;
}
}
/// <summary>
/// 根据ID查询物料信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<xl_material> SelectXlMaterialById(string id)
{
try
{
return await _xl_materialRepository.QueryByIdAsync(id);
}
catch (Exception ex)
{
throw;
}
}
}
}