You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1050 lines
45 KiB
1050 lines
45 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using QMAPP.FJC.TRACING.DAInterface;
|
|
using QMAPP.FJC.Entity.QT;
|
|
using QMAPP.FJC.DAL.QT;
|
|
using QMAPP.BLL;
|
|
using QMAPP.MD.DAL;
|
|
using QMAPP.FJC.Entity.Basic;
|
|
using QMFrameWork.Log;
|
|
|
|
namespace QMAPP.FJC.TRACING.DAHandler
|
|
{
|
|
/// <summary>
|
|
/// 数据获取类
|
|
/// </summary>
|
|
public class DataAcquirer : BaseBLL
|
|
{
|
|
#region 静态字段
|
|
/// <summary>
|
|
/// 数据解析类列表
|
|
/// </summary>
|
|
static Dictionary<string, Analyzer> _AnalyzerList;
|
|
/// <summary>
|
|
/// 数据解析类列表
|
|
/// </summary>
|
|
static List<Validator> _ValidatorList;
|
|
/// <summary>
|
|
/// 状态动作列表
|
|
/// </summary>
|
|
static Dictionary<string, StateAction> _StateActionList;
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 输入数据
|
|
/// </summary>
|
|
/// <param name="workcellcode">工序编码</param>
|
|
/// <param name="workloccode">工位编码</param>
|
|
/// <param name="dacode">采集点编码</param>
|
|
/// <param name="davalue">采集值</param>
|
|
/// <returns>返回采集结果</returns>
|
|
public DAResult Input(DAArgs Args)
|
|
{
|
|
DAResult result = new DAResult();
|
|
result.MouldCode = Args.MouldCode;
|
|
DAObject data = null;
|
|
StringBuilder log = new StringBuilder();
|
|
try
|
|
{
|
|
|
|
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
|
|
log.AppendFormat("{0},{1},{2}\t", Args.WorkLocCode, Args.DACode, Args.DAValue);
|
|
stopwatch.Start();
|
|
//初始化采集数据对象
|
|
data = InitDAObject(Args);
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("INITDA:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
AnalyzeData(data);//解析数据
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("ANADA:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
data.WorkLocState.LoadState(data.MouldCode);
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("LOADCH:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
if (data.OrderPlan == null)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.ORDERPLAN_PID))
|
|
{
|
|
//DAL.FIS.OrderPlanDAL orderplandal = new DAL.FIS.OrderPlanDAL();
|
|
//data.OrderPlan = orderplandal.Get(new Entity.FIS.OrderPlan { PID = data.WorkLocState.CurrentState.ORDERPLAN_PID });
|
|
DAL.ProductionPlan.WorkOrderDAL workorderdal = new DAL.ProductionPlan.WorkOrderDAL();
|
|
data.OrderPlan = workorderdal.GetOneByID(data.WorkLocState.CurrentState.ORDERPLAN_PID);
|
|
}
|
|
}
|
|
if (data.OrderPlan != null)
|
|
{
|
|
data.WorkLocState.CurrentState.ORDERPLAN_PID = data.OrderPlan.PID;
|
|
}
|
|
result.MouldCode = data.MouldCode;
|
|
|
|
//工序状态与采集点工序状态是否匹配
|
|
if (!string.IsNullOrWhiteSpace(data.DAI.STATE_CODE) && !string.Equals(data.DAI.STATE_CODE, data.WorkLocState.CurrentState.STATE_CODE))
|
|
{
|
|
if (string.Equals(data.DAI.CANPREINPUT, "1"))
|
|
{
|
|
return PreInput(data);
|
|
}
|
|
else
|
|
{
|
|
result.Message = string.Format("当前状态“{0}”,无法接收“{1}”输入!", data.WorkLocState.CurrentState.STATE_NAME, data.DAI.DA_NAME);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
if (!(string.Equals(data.DAI.DA_MODE, "3") || string.Equals(data.DAI.DA_MODE, "5")) && data.WorkLocState.DataCache.Count(p => p.DA_MODE == "3" || p.DA_MODE == "5") > 0)//如果当前采集项不是自适应项并且采集点列表中包含自适应项
|
|
{
|
|
LoadAdaptiveDA(data);
|
|
}
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("CHECKDA:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
var vresult = ValidateData(data);//校验数据
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("VALIDDA:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
if (!vresult.Passed)//验证未通过
|
|
{
|
|
result.Message = vresult.Message;
|
|
return result;
|
|
}
|
|
if (string.Equals(data.DAI.DA_MODE, "3") || string.Equals(data.DAI.DA_MODE, "5")) //如果为自适应项
|
|
{
|
|
SaveAdaptiveMaterial(data);
|
|
}
|
|
SetDACache(data);//设置数据采集缓存
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("SETCH:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
CheckState(data, result);//检查状态变化
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("STCHANGE:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
|
|
|
|
data.DataSession.OpenTs();//开启事务
|
|
data.PersistEntitys();
|
|
data.ExcuteSQL();
|
|
data.DataSession.CommitTs();//提交事务
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("EXECSQL:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
result.StateName = data.WorkLocState.CurrentState.STATE_NAME;
|
|
result.StateCode = data.WorkLocState.CurrentState.STATE_CODE;
|
|
//2017-10-1 闫永刚
|
|
result.MATERIAL_CODE = data.MaterialCode;
|
|
result.MATERIAL_NAME = data.MaterialName;
|
|
result.WorkOrderID = data.WorkOrderID;
|
|
result.AnalyzedValue = data.AnalyzedValue;
|
|
result.Success = true;
|
|
|
|
stopwatch.Stop();
|
|
log.AppendFormat("END:{0}ms\t", stopwatch.ElapsedMilliseconds);
|
|
stopwatch.Start();
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (data != null)
|
|
{
|
|
data.DataSession.RollbackTs();//回滚事务
|
|
}
|
|
result.Message = ex.Message;
|
|
return result;
|
|
}
|
|
finally
|
|
{
|
|
log.Append(result.Message);
|
|
LogManager.LogHelper.Debug(new LogInfo()
|
|
{
|
|
Info = log.ToString(),
|
|
});
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 保存采集模式为自适应的上料信息
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private static void SaveAdaptiveMaterial(DAObject data)
|
|
{
|
|
DAL.Produce.ProductDAL pdal = new DAL.Produce.ProductDAL();
|
|
var product = pdal.GetByPID(data.ObjectPID);
|
|
product.WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE;
|
|
//查找之前使用的上料信息
|
|
var usingmaterial = pdal.GetUsingMaterial(data.WorkLocState.WORKLOC_CODE).FirstOrDefault(p => p.MATERIAL_CODE == product.MATERIAL_CODE);
|
|
if (usingmaterial != null && !string.Equals(usingmaterial.PID, product.PID))
|
|
{
|
|
usingmaterial.WORKLOC_CODE = "";
|
|
data.AddToPersistentList(usingmaterial, usingmaterial.PID);
|
|
}
|
|
data.AddToPersistentList(product, product.PID);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 回滚/撤销
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public DAResult Rollback(DAArgs Args)
|
|
{
|
|
DAResult result = new DAResult();
|
|
DAObject data = null;
|
|
try
|
|
{
|
|
//初始化无采集点对象的
|
|
data = InitDAObjectForPass(Args);
|
|
data.WorkLocState.LoadState(Args.MouldCode);
|
|
result.MouldCode = data.MouldCode;
|
|
////判断是否已生成产品数据
|
|
//if (string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.PROCESS_CODE))
|
|
//{
|
|
// throw new Exception(string.Format("当前状态“{0}”,无法执行撤销操作!", data.WorkLocState.CurrentState.STATE_NAME));
|
|
//}
|
|
//StateActions.RollbackWithOrder rollback = new StateActions.RollbackWithOrder(); //执行数据回滚动作
|
|
//rollback.Execute(data);
|
|
//StateActions.ResetData resetdata = new StateActions.ResetData(); //执行数据复位
|
|
//resetdata.Execute(data);
|
|
if (string.Equals(data.WorkLocState.CurrentState.ROLLBACK_ACTION, "N/A"))
|
|
{
|
|
throw new Exception(string.Format("当前状态“{0}”,无法执行撤销操作!", data.WorkLocState.CurrentState.STATE_NAME));
|
|
}
|
|
foreach (var action in data.WorkLocState.CurrentState.ROLLBACK_ACTION.Split(';'))//执行放行动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
|
|
|
|
result.StateChanged = true;
|
|
SetToFirstState(data);
|
|
foreach (var action in data.WorkLocState.CurrentState.ENTRY_ACTION.Split(';'))//执行进入状态动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
CheckState(data, result);
|
|
data.DataSession.OpenTs();//开启事务
|
|
data.PersistEntitys();
|
|
data.ExcuteSQL();
|
|
data.DataSession.CommitTs();//提交事务
|
|
result.StateName = data.WorkLocState.CurrentState.STATE_NAME;
|
|
result.StateCode = data.WorkLocState.CurrentState.STATE_CODE;
|
|
result.Success = true;
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (data != null)
|
|
{
|
|
data.DataSession.RollbackTs();//回滚事务
|
|
}
|
|
result.Message = ex.Message;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 重置
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public DAResult Reset(DAArgs Args)
|
|
{
|
|
DAResult result = new DAResult();
|
|
DAObject data = null;
|
|
try
|
|
{
|
|
//初始化无采集点对象的
|
|
data = InitDAObjectForPass(Args);
|
|
data.WorkLocState.LoadState(Args.MouldCode);
|
|
result.MouldCode = data.MouldCode;
|
|
//判断是否已生成产品数据
|
|
//if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.PROCESS_CODE))
|
|
//{
|
|
// throw new Exception(string.Format("当前状态“{0}”,无法执行重置操作!", data.WorkLocState.CurrentState.STATE_NAME));
|
|
//}
|
|
//StateActions.ResetData resetdata = new StateActions.ResetData(); //执行数据复位
|
|
//resetdata.Execute(data);
|
|
if (string.Equals(data.WorkLocState.CurrentState.RESET_ACTION, "N/A"))
|
|
{
|
|
throw new Exception(string.Format("当前状态“{0}”,无法执行复位操作!", data.WorkLocState.CurrentState.STATE_NAME));
|
|
}
|
|
foreach (var action in data.WorkLocState.CurrentState.RESET_ACTION.Split(';'))//执行放行动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
|
|
result.StateChanged = true;
|
|
SetToFirstState(data);
|
|
foreach (var action in data.WorkLocState.CurrentState.ENTRY_ACTION.Split(';'))//执行进入状态动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
data.DataSession.OpenTs();//开启事务
|
|
data.PersistEntitys();
|
|
data.ExcuteSQL();
|
|
data.DataSession.CommitTs();//提交事务
|
|
result.StateName = data.WorkLocState.CurrentState.STATE_NAME;
|
|
result.StateCode = data.WorkLocState.CurrentState.STATE_CODE;
|
|
result.Success = true;
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (data != null)
|
|
{
|
|
data.DataSession.RollbackTs();//回滚事务
|
|
}
|
|
result.Message = ex.Message;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 放行
|
|
/// </summary>
|
|
/// <param name="Args"></param>
|
|
/// <returns></returns>
|
|
public DAResult LetPass(DAArgs Args)
|
|
{
|
|
DAResult result = new DAResult();
|
|
DAObject data = null;
|
|
try
|
|
{
|
|
//初始化无采集点对象的
|
|
data = InitDAObjectForPass(Args);
|
|
data.WorkLocState.LoadState(Args.MouldCode);
|
|
|
|
if (data.OrderPlan == null)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.ORDERPLAN_PID))
|
|
{
|
|
//DAL.FIS.OrderPlanDAL orderplandal = new DAL.FIS.OrderPlanDAL();
|
|
//data.OrderPlan = orderplandal.Get(new Entity.FIS.OrderPlan { PID = data.WorkLocState.CurrentState.ORDERPLAN_PID });
|
|
DAL.ProductionPlan.WorkOrderDAL workorderdal = new DAL.ProductionPlan.WorkOrderDAL();
|
|
data.OrderPlan = workorderdal.GetOneByID(data.WorkLocState.CurrentState.ORDERPLAN_PID);
|
|
}
|
|
}
|
|
if (data.OrderPlan != null)
|
|
{
|
|
data.WorkLocState.CurrentState.ORDERPLAN_PID = data.OrderPlan.PID;
|
|
}
|
|
|
|
result.MouldCode = data.MouldCode;
|
|
|
|
if (string.Equals(data.WorkLocState.CurrentState.MANUALPASS_ACTION, "N/A"))
|
|
{
|
|
throw new Exception(string.Format("当前状态“{0}”,无法执行放行操作!", data.WorkLocState.CurrentState.STATE_NAME));
|
|
}
|
|
foreach (var action in data.WorkLocState.CurrentState.MANUALPASS_ACTION.Split(';'))//执行放行动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
|
|
result.StateChanged = true;
|
|
foreach (var action in data.WorkLocState.CurrentState.EXIT_ACTION.Split(';'))//执行退出状态动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
SetToNextState(data);
|
|
foreach (var action in data.WorkLocState.CurrentState.ENTRY_ACTION.Split(';'))//执行进入状态动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
}
|
|
CheckState(data, result);
|
|
data.DataSession.OpenTs();//开启事务
|
|
data.PersistEntitys();
|
|
data.ExcuteSQL();
|
|
data.DataSession.CommitTs();//提交事务
|
|
result.StateName = data.WorkLocState.CurrentState.STATE_NAME;
|
|
result.StateCode = data.WorkLocState.CurrentState.STATE_CODE;
|
|
result.Success = true;
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (data != null)
|
|
{
|
|
data.DataSession.RollbackTs();//回滚事务
|
|
}
|
|
result.Message = ex.Message;
|
|
return result;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 提前输入
|
|
/// </summary>
|
|
/// <param name="Args"></param>
|
|
/// <returns></returns>
|
|
public DAResult PreInput(DAObject data)
|
|
{
|
|
data.PreInput = true;
|
|
DAResult result = new DAResult();
|
|
result.PreInput = true;
|
|
try
|
|
{
|
|
var percache= LoadPreInputCache(data);
|
|
|
|
foreach (var pre in percache)
|
|
{
|
|
var cache = data.WorkLocState.DataCache.FirstOrDefault(p => p.DA_CODE == pre.DA_CODE);
|
|
if (cache != null)
|
|
{
|
|
cache.DA_CODE = pre.DA_CODE;
|
|
cache.DA_SEQ = pre.DA_SEQ;
|
|
cache.DA_STATE = pre.DA_STATE;
|
|
cache.DA_VALUE = pre.DA_VALUE;
|
|
cache.OBJ_PID = pre.OBJ_PID;
|
|
cache.DATA_TYPE = pre.DATA_TYPE;
|
|
cache.MATERIAL_CODE = pre.MATERIAL_CODE;
|
|
cache.DA_MODE = pre.DA_MODE;
|
|
cache.DA_NAME = pre.DA_NAME;
|
|
cache.PIVOTAL = pre.PIVOTAL;
|
|
cache.ISPROCESSCODE = pre.ISPROCESSCODE;
|
|
cache.MATERIAL_TYPE = pre.MATERIAL_TYPE;
|
|
cache.PID = pre.PID;
|
|
cache.STATE_CODE = pre.STATE_CODE;
|
|
cache.WORKCELL_CODE = pre.WORKCELL_CODE;
|
|
cache.WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE;
|
|
cache.PREINPUT = pre.PREINPUT;
|
|
cache.IsNewInfo = pre.IsNewInfo;
|
|
}
|
|
else
|
|
{
|
|
data.WorkLocState.DataCache.Add(pre);
|
|
}
|
|
}
|
|
|
|
AnalyzeData(data);//解析数据
|
|
|
|
//if (!string.Equals(data.DAI.DA_MODE, "3") && data.WorkLocState.DataCache.Count(p => p.DA_MODE == "3") > 0)//如果当前采集项不是自适应项并且采集点列表中包含自适应项
|
|
//{
|
|
// LoadAdaptiveDA(data, false);
|
|
//}
|
|
if (!(string.Equals(data.DAI.DA_MODE, "3") || string.Equals(data.DAI.DA_MODE, "5")) && data.WorkLocState.DataCache.Count(p => p.DA_MODE == "3" || p.DA_MODE == "5") > 0)//如果当前采集项不是自适应项并且采集点列表中包含自适应项
|
|
{
|
|
LoadAdaptiveDA(data);
|
|
}
|
|
|
|
var vresult = ValidateData(data);//校验数据
|
|
if (!vresult.Passed)//验证未通过
|
|
{
|
|
result.Message = vresult.Message;
|
|
return result;
|
|
}
|
|
//if (string.Equals(data.DAI.DA_MODE, "3")) //如果为自适应项
|
|
//{
|
|
// SaveAdaptiveMaterial(data);
|
|
//}
|
|
if (string.Equals(data.DAI.DA_MODE, "3") || string.Equals(data.DAI.DA_MODE, "5")) //如果为自适应项
|
|
{
|
|
SaveAdaptiveMaterial(data);
|
|
}
|
|
SetDACache(data);//设置数据采集缓存
|
|
//CheckState(data, result);//检查状态变化
|
|
data.DataSession.OpenTs();//开启事务
|
|
data.PersistEntitys();
|
|
data.DataSession.CommitTs();//提交事务
|
|
result.StateName = data.WorkLocState.CurrentState.STATE_NAME;
|
|
result.StateCode = data.WorkLocState.CurrentState.STATE_CODE;
|
|
//2017-10-1 闫永刚
|
|
result.MATERIAL_CODE = data.MaterialCode;
|
|
result.MATERIAL_NAME = data.MaterialName;
|
|
result.MouldCode = data.MouldCode;
|
|
result.Success = true;
|
|
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (data != null)
|
|
{
|
|
data.DataSession.RollbackTs();//回滚事务
|
|
}
|
|
result.Message = ex.Message;
|
|
return result;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 加载提前扫描数据
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private List<DAICache> LoadPreInputCache(DAObject data)
|
|
{
|
|
DAICacheDAL dal = new DAICacheDAL();
|
|
var cachelist = dal.GetList(data.WorkLocState.WORKCELL_CODE, data.WorkLocState.WORKLOC_CODE).Where(p => string.Equals(p.PREINPUT, "1")).ToList();
|
|
DAIDAL daidal = new DAIDAL();
|
|
var predailist = daidal.GetList(data.WorkLocState.WORKCELL_CODE).Where(p => string.Equals(p.CANPREINPUT, "1")).ToList();
|
|
|
|
DAL.Basic.MachineInfoDAL machinedal = new DAL.Basic.MachineInfoDAL();
|
|
var machine= machinedal.GetMachineInfo(new MachineInfo { MACHINECODDE = data.MachineCode });
|
|
if (machine.ISSTATION == 2)
|
|
{
|
|
cachelist = cachelist.Where(p => p.MOULD_CODE == data.MouldCode).ToList();
|
|
}
|
|
|
|
if (cachelist == null || cachelist.Count == 0)
|
|
{
|
|
cachelist = new List<DAICache>();
|
|
foreach (var dai in predailist)
|
|
{
|
|
cachelist.Add(new DAICache
|
|
{
|
|
DA_CODE = dai.DA_CODE,
|
|
DA_SEQ = dai.DA_SEQ,
|
|
DA_STATE = dai.DA_STATUS,
|
|
DA_VALUE = "",
|
|
OBJ_PID = "",
|
|
DATA_TYPE = dai.DATA_TYPE,
|
|
MATERIAL_CODE = "",
|
|
DA_MODE = dai.DA_MODE,
|
|
DA_NAME = dai.DA_NAME,
|
|
PIVOTAL = dai.PIVOTAL,
|
|
ISPROCESSCODE = dai.ISPROCESSCODE,
|
|
MATERIAL_TYPE = dai.MATERIAL_TYPE,
|
|
PID = Guid.NewGuid().ToString(),
|
|
STATE_CODE = dai.STATE_CODE,
|
|
WORKCELL_CODE = dai.WORKCELL_CODE,
|
|
WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE,
|
|
UPDATEDATE = DateTime.Now,
|
|
PREINPUT = "1",
|
|
MOULD_CODE = data.MouldCode
|
|
});
|
|
}
|
|
dal.Insert(cachelist);
|
|
}
|
|
else if (cachelist.Count < predailist.Count)
|
|
{
|
|
foreach (var dai in predailist)
|
|
{
|
|
if (!cachelist.Exists(p => p.DA_CODE == dai.DA_CODE))
|
|
{
|
|
cachelist.Add(new DAICache
|
|
{
|
|
DA_CODE = dai.DA_CODE,
|
|
DA_SEQ = dai.DA_SEQ,
|
|
DA_STATE = dai.DA_STATUS,
|
|
DA_VALUE = "",
|
|
OBJ_PID = "",
|
|
DATA_TYPE = dai.DATA_TYPE,
|
|
MATERIAL_CODE = "",
|
|
DA_MODE = dai.DA_MODE,
|
|
DA_NAME = dai.DA_NAME,
|
|
PIVOTAL = dai.PIVOTAL,
|
|
ISPROCESSCODE = dai.ISPROCESSCODE,
|
|
MATERIAL_TYPE = dai.MATERIAL_TYPE,
|
|
PID = Guid.NewGuid().ToString(),
|
|
STATE_CODE = dai.STATE_CODE,
|
|
WORKCELL_CODE = dai.WORKCELL_CODE,
|
|
WORKLOC_CODE = data.WorkLocState.WORKLOC_CODE,
|
|
UPDATEDATE = DateTime.Now,
|
|
PREINPUT = "1",
|
|
IsNewInfo = true,
|
|
MOULD_CODE = data.MouldCode
|
|
});
|
|
}
|
|
}
|
|
dal.Insert(cachelist.Where(p => p.IsNewInfo).ToList());
|
|
}
|
|
return cachelist;
|
|
}
|
|
|
|
#region 采集点数据初始化
|
|
/// <summary>
|
|
/// 初始化采集数据对象
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private DAObject InitDAObject(DAArgs Args)
|
|
{
|
|
var workcell = new WorkCellDAL().GetWorkCellByCode(Args.WorkCellCode);
|
|
if (workcell == null)
|
|
{
|
|
throw new Exception("无法根据输入信息找到工序!请检查工序设置。");
|
|
}
|
|
var dai = new DAIDAL().GetDAIByCode(Args.WorkCellCode, Args.DACode);
|
|
if (dai == null)
|
|
{
|
|
throw new Exception("无法根据输入信息找到数据采集接口!请检查采集接口设置。");
|
|
}
|
|
dai.WORKLOC_CODE = Args.WorkLocCode;
|
|
|
|
var shift = new FJC.BLL.Basic.ProduceShiftBLL().GetWorkingShift(workcell.WORKCENTER_CODE);
|
|
|
|
|
|
int iscontrol = 0;
|
|
int.TryParse(Args.IsControl, out iscontrol);
|
|
//初始化采集数据对象
|
|
DAObject data = new DAObject()
|
|
{
|
|
DAI = dai,
|
|
WorkLocState = new WorkLocState(workcell, Args.WorkLocCode),
|
|
DAValue = Args.DAValue,
|
|
UserID = base.LoginUser.UserID,
|
|
MaterialCode = Args.MaterialCode,
|
|
MachineCode = Args.MachineCode,
|
|
MachineName = Args.MachineName,
|
|
IsControl = iscontrol,
|
|
MouldCode = Args.MouldCode,
|
|
Date = DateTime.Now,
|
|
Shift = shift != null ? shift : new ProduceShift { PRODUCESHIFTTCODE="-" },
|
|
AttachData=Args.AttachData,
|
|
MouldReLocate=false
|
|
};
|
|
return data;
|
|
}
|
|
/// <summary>
|
|
/// 初始化采集数据对象(无采集点对象)
|
|
/// </summary>
|
|
/// <param name="Args"></param>
|
|
/// <returns></returns>
|
|
private DAObject InitDAObjectForPass(DAArgs Args)
|
|
{
|
|
var workcell = new WorkCellDAL().GetWorkCellByCode(Args.WorkCellCode);
|
|
if (workcell == null)
|
|
{
|
|
throw new Exception("无法根据输入信息找到工序!请检查工序设置。");
|
|
}
|
|
int iscontrol = 0;
|
|
int.TryParse(Args.IsControl, out iscontrol);
|
|
var shift = new FJC.BLL.Basic.ProduceShiftBLL().GetWorkingShift(workcell.WORKCENTER_CODE);
|
|
//初始化采集数据对象
|
|
DAObject data = new DAObject()
|
|
{
|
|
DAI = null,
|
|
WorkLocState = new WorkLocState(workcell, Args.WorkLocCode),
|
|
DAValue = Args.DAValue,
|
|
UserID = base.LoginUser.UserID,
|
|
MaterialCode = Args.MaterialCode,
|
|
MachineCode = Args.MachineCode,
|
|
MachineName = Args.MachineName,
|
|
IsControl = iscontrol,
|
|
MouldCode = Args.MouldCode,
|
|
Date=DateTime.Now,
|
|
Shift = shift != null ? shift : new ProduceShift { PRODUCESHIFTTCODE = "-" },
|
|
AttachData = Args.AttachData,
|
|
MouldReLocate = false
|
|
};
|
|
return data;
|
|
}
|
|
/// <summary>
|
|
/// 加载自适应采集项
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void LoadAdaptiveDA(DAObject data, bool Persistent = true)
|
|
{
|
|
//提取采集数据中的物料号信息
|
|
var materials = (from da in data.WorkLocState.DataCache
|
|
where !string.IsNullOrWhiteSpace(da.MATERIAL_CODE)
|
|
&& !string.Equals(da.DA_MODE, "2") //过滤掉可省略的采集点
|
|
&& !string.Equals(da.DA_MODE, "3") //过滤掉自适应采集点
|
|
&& !string.Equals(da.DA_MODE, "5") //过滤掉自适应采集点
|
|
&& !string.Equals(da.DA_CODE, data.DAI.DA_CODE) //过滤掉当前输入的采集点
|
|
select da.MATERIAL_CODE).ToList();
|
|
PbomDAL dal = new PbomDAL();
|
|
materials.Add(data.MaterialCode + "");
|
|
var bomlocates = dal.LocateBom(materials.Distinct().ToArray()); //匹配物料BOM
|
|
MD.Entity.View.BomLocation bomloc = null;
|
|
if (bomlocates.Count>0)
|
|
{
|
|
if (data.OrderPlan != null)
|
|
{
|
|
bomloc = bomlocates.FirstOrDefault(p => p.BOMCode == data.OrderPlan.PBOM_CODE);
|
|
}
|
|
else if(bomlocates.GroupBy(p=>p.UP_MATERIAL_CODE).ToList().Count==1)
|
|
{
|
|
bomloc = bomlocates[0];
|
|
}
|
|
}
|
|
if (bomloc != null) //如果存在匹配的BOM
|
|
{
|
|
var bomitems = dal.GetBomItemsByLocate(bomloc); //查找组成物料列表
|
|
var adaptmaterials = (from bomtiem in bomitems
|
|
select bomtiem.MATERIAL_CODE).ToArray();
|
|
DAL.Produce.ProductDAL productdal = new DAL.Produce.ProductDAL();
|
|
var adapts = productdal.GetUsingMaterial(data.WorkLocState.WORKLOC_CODE);
|
|
foreach (var da in data.WorkLocState.DataCache.Where(p => p.DA_MODE == "3" || p.DA_MODE == "5"))
|
|
{
|
|
var adaptmaterial = adapts.FirstOrDefault(p => adaptmaterials.Contains(p.MATERIAL_CODE) && (p.MATERIAL_TYPE == da.MATERIAL_TYPE || p.PARENT_MATERIAL_TYPE == da.MATERIAL_TYPE));
|
|
if (adaptmaterial != null)//找到匹配的物料
|
|
{
|
|
da.DA_VALUE = adaptmaterial.PRODUCTCODE;
|
|
da.MATERIAL_CODE = adaptmaterial.MATERIAL_CODE;
|
|
da.OBJ_PID = adaptmaterial.PID;
|
|
}
|
|
else
|
|
{
|
|
da.DA_VALUE = "";
|
|
da.MATERIAL_CODE = "";
|
|
da.OBJ_PID = "";
|
|
}
|
|
if (Persistent)
|
|
{
|
|
data.AddToPersistentList(da, da.PID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 采集处理方法
|
|
/// <summary>
|
|
/// 解析数据
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void AnalyzeData(DAObject data)
|
|
{
|
|
if (_AnalyzerList == null)//如果解析类列表未加载,则执行加载
|
|
{
|
|
LoadAnalyzer();
|
|
}
|
|
IDataAnalyzer analyzer = null;
|
|
if (!string.IsNullOrWhiteSpace(data.DAI.ANALYZE_CODE) && _AnalyzerList.ContainsKey(data.DAI.ANALYZE_CODE)) //检查采集数据的解析编码是否存在于解析类列表中
|
|
{
|
|
analyzer = CreateInstance<IDataAnalyzer>(_AnalyzerList[data.DAI.ANALYZE_CODE].ASSEMBLYNAME, _AnalyzerList[data.DAI.ANALYZE_CODE].CLASSNAME);
|
|
}
|
|
else // 不存在则执行默认解析方法
|
|
{
|
|
analyzer = new DataAnalyzers.DefaultAnalyzer();
|
|
}
|
|
analyzer.Analyze(data);
|
|
}
|
|
/// <summary>
|
|
/// 校验采集数据
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private ValidateResult ValidateData(DAObject data)
|
|
{
|
|
if (_ValidatorList == null)//如果解析类列表未加载,则执行加载
|
|
{
|
|
LoadValidator();
|
|
}
|
|
//获取采集点校验配置
|
|
DAIValidationDAL dal = new DAIValidationDAL();
|
|
var daivalidations = dal.GetList(data.DAI.PID);
|
|
foreach (var validator in _ValidatorList) //遍历校验类
|
|
{
|
|
var daioption = daivalidations.FirstOrDefault(p => p.VALIDATION_CODE == validator.VALIDATOR_CODE);
|
|
if (string.Equals("1", validator.REQUIRED) || daioption != null) //如果校验类为必选项 或 采集点配置此校验
|
|
{
|
|
if (daioption == null || !string.Equals(daioption.DISABLE, "1"))
|
|
{
|
|
IDataValidator datavalidator;
|
|
datavalidator = CreateInstance<IDataValidator>(validator.ASSEMBLYNAME, validator.CLASSNAME);
|
|
var result = datavalidator.Validate(data, daioption);
|
|
if (!result.Passed)//校验未通过
|
|
{
|
|
return new ValidateResult(false,
|
|
string.Format("采集数据校验未通过,{0}:{1}", validator.VALIDATOR_NAME, result.Message));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return new ValidateResult(true, "");
|
|
}
|
|
/// <summary>
|
|
/// 检查工序状态
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void CheckState(DAObject data,DAResult result)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.PROCESS_CODE))
|
|
{
|
|
result.ProcessCode = data.WorkLocState.CurrentState.PROCESS_CODE;
|
|
}
|
|
//查找当前状态下未赋值的采集点数量
|
|
var novalue_count = data.WorkLocState.DataCache.Count(p => p.STATE_CODE == data.WorkLocState.CurrentState.STATE_CODE //采集点采集状态为当前工序状态
|
|
&& string.IsNullOrWhiteSpace(p.DA_VALUE) //采集点采集值不为空
|
|
&& !string.Equals(p.DA_MODE, "2") //过滤掉可省略的采集点
|
|
&& !string.Equals(p.DA_MODE, "5") //过滤掉可省略的采集点
|
|
&& (data.ReadSignal || !string.Equals(p.DA_CODE, "PLC_PARM"))); //如果当前设备设置为不读信号则过滤掉从当前设备采集的数据
|
|
if (novalue_count == 0) //当前工序状态下得采集点采集完成
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.MATERIAL_CODE))
|
|
{
|
|
var emptyDa = (from dai in data.WorkLocState.DataCache
|
|
where dai.STATE_CODE == data.WorkLocState.CurrentState.STATE_CODE //采集点采集状态为当前工序状态
|
|
&& string.IsNullOrWhiteSpace(dai.DA_VALUE) //采集值为空
|
|
&& (string.Equals(dai.DA_MODE, "2") //采集模式不是可忽略的
|
|
|| string.Equals(dai.DA_MODE, "5")) //采集模式不是可忽略的
|
|
orderby dai.DA_SEQ descending
|
|
select dai).ToList();
|
|
if (emptyDa.Count > 0)
|
|
{
|
|
PbomDAL dal = new PbomDAL();
|
|
MD.Entity.View.BomLocation bomloc=null;
|
|
var bomlocates = dal.LocateBomByUpMaterial(data.WorkLocState.CurrentState.MATERIAL_CODE);
|
|
if (bomlocates.Count > 0)
|
|
{
|
|
bomloc = bomlocates[0];
|
|
}
|
|
if (bomloc != null)
|
|
{
|
|
var bomitems = dal.GetBomItemsByLocateWithType(bomloc); //查找组成物料列表
|
|
foreach (var da in emptyDa)
|
|
{
|
|
if (bomitems.Exists(p => p.MATERIAL_TYPE_CODE == da.MATERIAL_TYPE || p.UP_MATERIAL_TYPE_CODE == da.MATERIAL_TYPE))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
result.StateChanged = true;
|
|
foreach (var action in data.WorkLocState.CurrentState.EXIT_ACTION.Split(';'))//执行退出状态动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.PROCESS_CODE))
|
|
{
|
|
result.ProcessCode = data.WorkLocState.CurrentState.PROCESS_CODE;
|
|
}
|
|
}
|
|
SetToNextState(data);
|
|
foreach (var action in data.WorkLocState.CurrentState.ENTRY_ACTION.Split(';'))//执行进入状态动作
|
|
{
|
|
ExecuteAction(action, data);
|
|
if (!string.IsNullOrWhiteSpace(action))
|
|
result.Actions.Add(action);
|
|
if (!string.IsNullOrWhiteSpace(data.WorkLocState.CurrentState.PROCESS_CODE))
|
|
{
|
|
result.ProcessCode = data.WorkLocState.CurrentState.PROCESS_CODE;
|
|
}
|
|
}
|
|
|
|
CheckState(data, result);//递归调用
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置工序到下一个状态
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void SetToNextState(DAObject data)
|
|
{
|
|
WorkCellRunStateDAL dal = new WorkCellRunStateDAL();
|
|
var state = dal.GetNextState(data.WorkLocState.WORKCELL_CODE, data.WorkLocState.CurrentState.STATE_SEQ);
|
|
if (state == null) //如果状态为空则获取第一个状态
|
|
{
|
|
state = dal.GetNextState(data.WorkLocState.WORKCELL_CODE, 0);
|
|
}
|
|
//更新工序状态
|
|
data.WorkLocState.CurrentState.UPDATEDATE = DateTime.Now;
|
|
data.WorkLocState.CurrentState.ENTRY_ACTION = state.ENTRY_ACTION;
|
|
data.WorkLocState.CurrentState.EXIT_ACTION = state.EXIT_ACTION;
|
|
data.WorkLocState.CurrentState.STATE_SEQ = state.STATE_SEQ;
|
|
data.WorkLocState.CurrentState.STATE_CODE = state.STATE_CODE;
|
|
data.WorkLocState.CurrentState.STATE_NAME = state.STATE_NAME;
|
|
|
|
data.AddToPersistentList(data.WorkLocState.CurrentState,data.WorkLocState.CurrentState.PID);
|
|
//dal.Update(data.WorkLocState.CurrentState, data.DataSession);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置工序到第一个状态
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void SetToFirstState(DAObject data)
|
|
{
|
|
WorkCellRunStateDAL dal = new WorkCellRunStateDAL();
|
|
var state = dal.GetNextState(data.WorkLocState.WORKCELL_CODE, 0);
|
|
//更新工序状态
|
|
data.WorkLocState.CurrentState.UPDATEDATE = DateTime.Now;
|
|
data.WorkLocState.CurrentState.ENTRY_ACTION = state.ENTRY_ACTION;
|
|
data.WorkLocState.CurrentState.EXIT_ACTION = state.EXIT_ACTION;
|
|
data.WorkLocState.CurrentState.STATE_SEQ = state.STATE_SEQ;
|
|
data.WorkLocState.CurrentState.STATE_CODE = state.STATE_CODE;
|
|
data.WorkLocState.CurrentState.STATE_NAME = state.STATE_NAME;
|
|
|
|
data.AddToPersistentList(data.WorkLocState.CurrentState, data.WorkLocState.CurrentState.PID);
|
|
//dal.Update(data.WorkLocState.CurrentState, data.DataSession);
|
|
}
|
|
/// <summary>
|
|
/// 执行状态动作
|
|
/// </summary>
|
|
/// <param name="Action"></param>
|
|
private void ExecuteAction(string action,DAObject data)
|
|
{
|
|
|
|
if (_StateActionList == null)
|
|
{
|
|
LoadStateAction();
|
|
}
|
|
if (string.IsNullOrWhiteSpace(action))
|
|
{
|
|
return;
|
|
}
|
|
if (_StateActionList.ContainsKey(action))
|
|
{
|
|
var act = CreateInstance<IStateAction>(_StateActionList[action].ASSEMBLYNAME, _StateActionList[action].CLASSNAME);
|
|
act.Execute(data);
|
|
}
|
|
|
|
}
|
|
/// <summary>
|
|
/// 设置数据采集缓存
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
private void SetDACache(DAObject data)
|
|
{
|
|
//DAICacheDAL dal = new DAICacheDAL();
|
|
var daicache = data.WorkLocState.DataCache.FirstOrDefault(p => p.DA_CODE == data.DAI.DA_CODE);
|
|
daicache.DA_VALUE = data.AnalyzedValue;
|
|
daicache.OBJ_PID = data.ObjectPID;
|
|
daicache.MATERIAL_CODE = data.MaterialCode;
|
|
daicache.DA_MODE = data.DAI.DA_MODE;
|
|
daicache.DA_SEQ = data.DAI.DA_SEQ;
|
|
daicache.DA_STATE = data.DAI.DA_STATUS;
|
|
daicache.DATA_TYPE = data.DAI.DATA_TYPE;
|
|
daicache.ISPROCESSCODE = data.DAI.ISPROCESSCODE;
|
|
daicache.MATERIAL_TYPE = data.DAI.MATERIAL_TYPE;
|
|
daicache.PIVOTAL = data.DAI.PIVOTAL;
|
|
daicache.STATE_CODE = data.DAI.STATE_CODE;
|
|
daicache.SAVED = daicache.SAVED.Replace(data.MouldCode, "");
|
|
daicache.MOULD_CODE = data.MouldCode;
|
|
data.AddToPersistentList(daicache, daicache.PID);
|
|
//dal.Update(daicache, data.DataSession);
|
|
}
|
|
#endregion
|
|
|
|
#region 静态方法
|
|
/// <summary>
|
|
/// 加载解析类
|
|
/// </summary>
|
|
private static void LoadAnalyzer()
|
|
{
|
|
//lock (_AnalyzerList)
|
|
//{
|
|
AnalyzerDAL dal = new AnalyzerDAL();
|
|
var list = dal.GetList();
|
|
if (_AnalyzerList == null)
|
|
{
|
|
_AnalyzerList = new Dictionary<string, Analyzer>();
|
|
}
|
|
else
|
|
{
|
|
if (_AnalyzerList.Count == list.Count)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
_AnalyzerList.Clear();
|
|
foreach (var analyzer in list)
|
|
{
|
|
_AnalyzerList.Add(analyzer.ANALYZER_CODE, analyzer);
|
|
}
|
|
//}
|
|
}
|
|
/// <summary>
|
|
/// 加载状态动作
|
|
/// </summary>
|
|
private static void LoadStateAction()
|
|
{
|
|
//lock (_StateActionList)
|
|
//{
|
|
StateActionDAL dal = new StateActionDAL();
|
|
var list = dal.GetServerActionList();
|
|
if (_StateActionList == null)
|
|
{
|
|
_StateActionList = new Dictionary<string, StateAction>();
|
|
}
|
|
else
|
|
{
|
|
if (_StateActionList.Count == list.Count)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
_StateActionList.Clear();
|
|
foreach (var action in list)
|
|
{
|
|
_StateActionList.Add(action.ACTION_CODE, action);
|
|
}
|
|
//}
|
|
}
|
|
/// <summary>
|
|
/// 加载校验类
|
|
/// </summary>
|
|
private static void LoadValidator()
|
|
{
|
|
//lock (_ValidatorList)
|
|
//{
|
|
ValidatorDAL dal = new ValidatorDAL();
|
|
var list = dal.GetList();
|
|
if (_ValidatorList == null)
|
|
{
|
|
_ValidatorList = new List<Validator>();
|
|
}
|
|
else
|
|
{
|
|
if (_ValidatorList.Count == list.Count)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
_ValidatorList.Clear();
|
|
foreach (var validator in list)
|
|
{
|
|
_ValidatorList.Add(validator);
|
|
}
|
|
//}
|
|
}
|
|
/// <summary>
|
|
/// 根据配置信息创建所对应的接口
|
|
/// </summary>
|
|
/// <typeparam name="T">要创建的接口</typeparam>
|
|
/// <param name="AssemblyName">程序集</param>
|
|
/// <param name="ClassPath">实现类全路径</param>
|
|
/// <returns>创建的接口</returns>
|
|
public static T CreateInstance<T>(String AssemblyName, String ClassPath)
|
|
{
|
|
Assembly _asse;
|
|
Type _type;
|
|
Object _obj;
|
|
T _mc;
|
|
_asse = Assembly.Load(AssemblyName);
|
|
_type = _asse.GetType(ClassPath);
|
|
_obj = System.Activator.CreateInstance(_type);
|
|
_mc = (T)_obj;
|
|
return _mc;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|