| | |
| | | public MES_SHIFT_SYS CurShiftSys { get; set; } |
| | | public WorkBatch CurBatch { get; set; } |
| | | public IWorkBatch WorkBatch => CurBatch; |
| | | public MES_WIP_DATA CurWipSN { get; set; } |
| | | public MES_WIP_HIS CurWipSNHis { get; set; } |
| | | public List<MES_WIP_DATA> CurWipSNs { get; set; } |
| | | public string CurSN => CurWipSNs.First().TRAY_SN.IsNullOrEmpty() ? CurWipSNs.First().SN : CurWipSNs.First().TRAY_SN; |
| | | public List<MES_WIP_HIS> CurWipSNHiss { get; set; } |
| | | public Dictionary<string, object> Context { get; set; } = new(); |
| | | public List<WorkStep> Steps { get; set; } = new(); |
| | | public WorkStep CurStep { get; set; } |
| | | public List<WorkStep> NextSteps { get; set; } = new(); |
| | |
| | | public bool IsFinishAllSteps => !Steps.Any() || !Steps.Any(q => !q.IsFinished); |
| | | //public int CurStep => Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).FirstOrDefault()?.Sequence ?? 0; |
| | | private DbClient CommitDB; |
| | | /// <summary> |
| | | /// 是否需要临时存储数据库提交操作,待需要的时候再提交 |
| | | /// </summary> |
| | | public bool NeedTemporaryStoreDBCommitAction { get; set; } = false; |
| | | protected List<Action> DBCommitList { get; set; } = new(); |
| | | |
| | | #endregion Propertys & Variables |
| | | |
| | | #region Functions |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重置当前工步 |
| | | /// 重置工序操作 |
| | | /// </summary> |
| | | public void ResetSteps() |
| | | /// <returns></returns> |
| | | public ApiAction Reset() |
| | | { |
| | | var action = new ApiAction(); |
| | | |
| | | ResetNode(); |
| | | action.IsSuccessed = true; |
| | | action.LocaleMsg = new($"工序操作已重置,请重新扫描进站产品条码"); |
| | | action.LocaleMsg = new("MES.Transaction.Position.ResetNode"); |
| | | |
| | | return action; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重置当前工序,有需要则重写此方法 |
| | | /// </summary> |
| | | public virtual void ResetNode() |
| | | { |
| | | Steps.Clear(); |
| | | CurWipSN = null; |
| | | CurWipSNs = null; |
| | | CurWipSNHiss = null; |
| | | CurStep = null; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <summary> |
| | | /// 添加节点的下一个行为到工步列表 |
| | | /// </summary> |
| | | /// <param name="curNode"></param> |
| | | /// <param name="parent"></param> |
| | | private void AddNextActToSteps(WorkStep parent) |
| | | { |
| | | var edges = CurBatch.Edges.Where(q => q.SRC_NODE == parent.NodeID && CurBatch.NodeActs.Any(a => a.NODE_ID == parent.Node.ID && a.ID == q.TGT_NODE)).ToList(); |
| | |
| | | { |
| | | var next = Steps.First(q => q.NodeID == act.ID); |
| | | next.Sequence = next.Sequence > parent.Sequence ? next.Sequence : (parent.Sequence + 1); |
| | | next.PrepNodeIDs.Add(parent.NodeID); |
| | | next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | AddNextActToSteps(next); |
| | |
| | | { |
| | | var next = new WorkStep(IWorkStep.Types.Action, this) |
| | | { |
| | | NodeID = act.ID, |
| | | Sequence = parent.Sequence + 1, |
| | | Node = parent.Node, |
| | | NodeAct = act, |
| | | Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID), |
| | | }; |
| | | next.Init(); |
| | | next.PrepNodeIDs.Add(parent.NodeID); |
| | | next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | Steps.Add(next); |
| | |
| | | } |
| | | } |
| | | //如果当前工步没有可执行的后续工步,则在前置工步查找还有没有后续工步没完成的工步,有则执行 |
| | | if (!result.Any()) |
| | | if (!result.Any() && Steps.Any()) |
| | | { |
| | | //查找有没有前置工步未完成,若有则先完成未完成的前置工步 |
| | | var prepIDs = curStep.PrepNodeIDs.Where(id => CurBatch.Edges.Any(e => e.SRC_NODE == id && Steps.Any(q => !q.IsFinished && e.TGT_NODE == q.NodeID))).ToList(); |
| | |
| | | /// <param name="input"></param> |
| | | public ApiAction<SubmitOutput> BeginNextActionStep(SubmitInput input) |
| | | { |
| | | var result = new ApiAction<SubmitOutput>(); |
| | | var result = new ApiAction<SubmitOutput>(new SubmitOutput()); |
| | | //设置后续可执行的工步列表 |
| | | NextSteps = GetNextSteps(CurStep); |
| | | //尝试有没有可以直接开始的后续工步 |
| | | foreach (var step in NextSteps) |
| | | { |
| | | //尝试执行后续工步 |
| | | var canBegin = step.TryBegin(input); |
| | | //如果后续工步可以直接开始则直接执行 |
| | | if (canBegin.IsSuccessed) |
| | | { |
| | | //更新当前执行工步为已开始工步 |
| | | CurStep = step; |
| | | //更新后续可执行的工步列表 |
| | | NextSteps = GetNextSteps(CurStep); |
| | | //返回结果到客户端 |
| | | result = canBegin; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | result.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | result.Data.CurNode = CurStep.NodeAct.ACT_NAME; |
| | | result.Data.StepActCode = CurStep.NodeAct.ACT_CODE; |
| | | result.Data.NextStepID = CurStep.ID; |
| | | |
| | | result.Data.SetValue(CurBatch, CurStep, CurStep?.ID, IsFinishAllSteps); |
| | | |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | //根据后续工步返回ApiAction |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | result.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | result.Data.CurNode = CurStep.Node.NODE_NAME; |
| | | result.Data.StepActCode = CurStep.NodeAct.ACT_CODE; |
| | | result.Data.NextStepID = ""; |
| | | //没有可以直接开始的后续工步,根据后续工步返回ApiAction |
| | | result.Data.SetValue(CurBatch, CurStep, "", IsFinishAllSteps); |
| | | |
| | | //根据后续可执行工步列表返回相应的操作提示 |
| | | //没有可以直接开始的后续工步,根据后续可执行工步列表返回相应的操作提示 |
| | | if (NextSteps.Count == 1) |
| | | { |
| | | result.LocaleMsg = NextSteps.First().GetBeginMsg(); |
| | |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 保存工步的数据库提交操作到数据库 |
| | | /// </summary> |
| | | protected void SaveStepsCommitActionToDB() |
| | | { |
| | | //保存工步的数据库提交操作到提交操作列表 |
| | | foreach (var step in Steps.OrderBy(q => q.Sequence)) |
| | | { |
| | | DBCommitList.Add(step.DBSubmitAction); |
| | | } |
| | | //如果不需要临时存储数据库提交操作,则把提交操作列表提交到数据库 |
| | | if (!NeedTemporaryStoreDBCommitAction) |
| | | { |
| | | //恢复临时存储标记为false |
| | | NeedTemporaryStoreDBCommitAction = false; |
| | | |
| | | var dbTran = GetCommitDB().UseTran(() => |
| | | { |
| | | //在同一个事务中保存所有工步的数据 |
| | | foreach (var action in DBCommitList) |
| | | { |
| | | action.Invoke(); |
| | | } |
| | | }); |
| | | if (dbTran.IsSuccess) |
| | | { |
| | | //保存成功则清空提交操作列表 |
| | | DBCommitList.Clear(); |
| | | } |
| | | else |
| | | { |
| | | //抛出异常 |
| | | throw dbTran.ErrorException; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取打印标签模板过程变量值 |
| | | /// </summary> |
| | | /// <param name="labelPVs">过程变量列表</param> |
| | | /// <param name="label">标签模板</param> |
| | | /// <returns></returns> |
| | | public BAS_LABEL_TEMP SetLabelVariables(List<BAS_LABEL_PV> labelPVs, BAS_LABEL_TEMP label) |
| | | { |
| | | foreach (var item in label.Variables) |
| | | { |
| | | switch (item.VAR_TYPE.GetEnum<BAS_LABEL_VAR.VAR_TYPEs>()) |
| | | { |
| | | case BAS_LABEL_VAR.VAR_TYPEs.Constant: |
| | | item.Value = item.VAR_VALUE; |
| | | break; |
| | | case BAS_LABEL_VAR.VAR_TYPEs.ProcessVariable: |
| | | item.Value = GetPrintProcessValue(labelPVs, item); |
| | | break; |
| | | case BAS_LABEL_VAR.VAR_TYPEs.DateVariable: |
| | | item.Value = DateTime.Now.ToString(item.VAR_VALUE); |
| | | break; |
| | | case BAS_LABEL_VAR.VAR_TYPEs.CustomVariable: |
| | | default: |
| | | item.Value = ""; |
| | | break; |
| | | } |
| | | } |
| | | return label; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取打印标签模板过程变量值 |
| | | /// </summary> |
| | | /// <param name="labelPVs">过程变量列表</param> |
| | | /// <param name="lv">标签模板变量</param> |
| | | /// <returns></returns> |
| | | public string GetPrintProcessValue(List<BAS_LABEL_PV> labelPVs, BAS_LABEL_VAR lv) |
| | | { |
| | | var pv = labelPVs.FirstOrDefault(q => q.VAR_CODE == lv.VAR_VALUE); |
| | | if (!pv.IsNullOrEmpty()) |
| | | { |
| | | switch (pv.VAR_TYPE.GetEnum<BAS_LABEL_PV.VAR_TYPEs>()) |
| | | { |
| | | case BAS_LABEL_PV.VAR_TYPEs.ServerMethod: |
| | | { |
| | | switch (pv.VAR_METHOD) |
| | | { |
| | | case "GetSN": |
| | | return string.Join(",", CurWipSNs.Select(q => q.SN)); |
| | | case "GetTraySN": |
| | | return CurSN; |
| | | case "GetBAS_ITEM": |
| | | return WorkBatch.Product.ToJson(); |
| | | case "GetCustomer": |
| | | return WorkBatch.Batch.ToJson(); |
| | | case "GetVarByWo": |
| | | return GetLabelVarWo(lv); |
| | | default: |
| | | return ""; |
| | | } |
| | | } |
| | | case BAS_LABEL_PV.VAR_TYPEs.WebApiWebApi: |
| | | break; |
| | | case BAS_LABEL_PV.VAR_TYPEs.StoredProcedure: |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | return ""; |
| | | } |
| | | /// <summary> |
| | | /// 获取工单维护的模板变量 |
| | | /// </summary> |
| | | /// <param name="labelId"></param> |
| | | /// <returns></returns> |
| | | private string GetLabelVarWo(BAS_LABEL_VAR lv) |
| | | { |
| | | string result = ""; |
| | | var labelVarwos = Biz.Db.Queryable<BAS_LABEL_VAR_WO>().Where(x => x.LABEL_ID == lv.LABEL_ID && x.VAR_NAME == lv.VAR_NAME).ToList(); |
| | | if (labelVarwos.Any(q => q.WORK_ORDER == WorkBatch.Batch.ORDER_NO)) |
| | | { |
| | | result = labelVarwos.First(q => q.WORK_ORDER == WorkBatch.Batch.ORDER_NO).VAR_VALUE; |
| | | } |
| | | else |
| | | { |
| | | result = labelVarwos.Count > 0 ? labelVarwos[0].DEFAULT_VALUE : ""; |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | #endregion Functions |
| | | |
| | | public override bool Close(bool needSaveHistoryLog = false) |