| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<ApiAction> Submit(SubmitInput input) |
| | | public async Task<ApiAction<SubmitOutput>> Submit(SubmitInput input) |
| | | { |
| | | var action = new ApiAction(); |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | try |
| | | { |
| | | //工步列表为空时,认为需要先扫描过站条码 |
| | | if (Steps.IsNullOrEmpty()) |
| | | //工步列表为空或者工序节点工步有未完成时,优先完成工序节点工步 |
| | | if (Steps.IsNullOrEmpty() || !IsFinishNodeSteps) |
| | | { |
| | | //先判断当前工单不为空且当前岗位在当前工单是不是首站,如果是则不允许变更当前工单,尝试把条码绑定到当前工单 |
| | | if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode)) |
| | | { |
| | | action = ScanSn(action, input); |
| | | action = NodeSubmit(action, input); |
| | | return action; |
| | | } |
| | | //当前岗位在当前工单不是首站,则查找条码已绑定的工单当作当前工单 |
| | |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosn.Batch.ORDER_NO }); |
| | | if (!result.IsSuccessed) |
| | | { |
| | | action = result; |
| | | action.IsSuccessed = result.IsSuccessed; |
| | | action.LocaleMsg = result.LocaleMsg; |
| | | return action; |
| | | } |
| | | } |
| | | //条码过站 |
| | | action = ScanSn(action, input); |
| | | action = NodeSubmit(action, input); |
| | | return action; |
| | | } |
| | | //查找不到条码已绑定的工单 |
| | |
| | | } |
| | | } |
| | | } |
| | | //完成第一步,后开始执行当前工序的行为列表 |
| | | else if (Steps.First().IsFinished && !IsFinishAllSteps) |
| | | //完成工序节点工步后,后开始执行当前工序的行为工步 |
| | | else if (IsFinishNodeSteps && !IsFinishAllSteps) |
| | | { |
| | | //var curStep = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | var curStep = Steps.Where(q => q.ID == input.StepID).FirstOrDefault(); |
| | | if (!curStep.IsNullOrEmpty()) |
| | | var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault(); |
| | | if (submitStep.IsNullOrEmpty()) |
| | | { |
| | | var result = curStep.Submit(input); |
| | | result.Data.StepID = curStep.ID; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurStep = CurStep; |
| | | action = BeginNextActionStep(input); |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | var result = submitStep.Submit(input); |
| | | //如果当前工步已完成,开始执行下一工步 |
| | | if (result.IsSuccessed && submitStep.IsFinished) |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | } |
| | | //如果当前工步未完成 |
| | | else |
| | | { |
| | | //行为执行出错,工步被重置 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale)); |
| | | } |
| | | else |
| | | { |
| | | 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; |
| | | } |
| | | } |
| | | //如果所有工步都完成 |
| | | if (IsFinishAllSteps) |
| | | { |
| | | return DoIfFinishAllSteps(result.ToApiAction()); |
| | | return DoIfFinishAllSteps(result); |
| | | } |
| | | return result.ToApiAction(); |
| | | return result; |
| | | } |
| | | } |
| | | //没有可执行的工步 |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 扫描过站条码 |
| | | /// 工序节点工步提交数据 |
| | | /// </summary> |
| | | /// <param name="action"></param> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public ApiAction ScanSn(ApiAction action, SubmitInput input) |
| | | public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input) |
| | | { |
| | | try |
| | | { |
| | | //绑定条码到工单 |
| | | if (!CurBatch.WoSNs.Any(q => q.SN == input.SN)) |
| | | //当工步列表为空,则执行当前工序的必要逻辑当作第一个工序节点,完成后按需求创建后续的工步列表 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | CurBatch.WoSNs.Add(new() |
| | | //绑定条码到工单 |
| | | if (!CurBatch.WoSNs.Any(q => q.SN == input.SN)) |
| | | { |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | SN = input.SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | }); |
| | | } |
| | | var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN); |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | |
| | | //条码过站 |
| | | var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSN.AUTH_PROD = CurLine.LINE_CODE; |
| | | wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS; |
| | | wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.FTY_CODE = CurFactory.FTY_CODE; |
| | | wipSN.WS_CODE = CurWorkshop.WS_CODE; |
| | | wipSN.LINE_CODE = CurLine.LINE_CODE; |
| | | wipSN.POST_CODE = CurPosition.POST_CODE; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | wipSN.OPERATION_TIME = DateTime.Now; |
| | | wipSN.SFTS_CODE = CurLine.SFTS_CODE; |
| | | //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE; |
| | | CurBatch.StartWorking(UserCode); |
| | | |
| | | //如果是投入站 |
| | | if (curNode.IS_INPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue(); |
| | | wipSN.INLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果是产出站 |
| | | if (curNode.IS_OUTPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.OUTLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果有提交不良 |
| | | if (!input.DFT_CODE.IsNullOrEmpty()) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue(); |
| | | wipSN.DFT_FLAG = "Y"; |
| | | wipSN.DFT_COUNT++; |
| | | wipSN.DFT_CODE = input.DFT_CODE; |
| | | } |
| | | |
| | | CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(curNode.ID, IWorkStep.Types.Node) |
| | | { |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | DBSubmitAction = () => |
| | | { |
| | | var db = GetCommitDB(); |
| | | db.Storageable(woSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(wipSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(CurWipSNHis, UserCode).ExecuteCommand(); |
| | | CurBatch.WoSNs.Add(new() |
| | | { |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | SN = input.SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | }); |
| | | } |
| | | }; |
| | | Steps.Add(curStep); |
| | | var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN); |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | |
| | | //如果当前工序节点有行为则添加到工步列表 |
| | | var acts = CurBatch.NodeActs.Where(q => q.NODE_ID == curNode.ID).ToList(); |
| | | foreach (var act in acts) |
| | | { |
| | | Steps.Add(new Biz.WorkStep(act.ID, IWorkStep.Types.Action) |
| | | //条码过站 |
| | | var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSN.AUTH_PROD = CurLine.LINE_CODE; |
| | | wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS; |
| | | wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.FTY_CODE = CurFactory.FTY_CODE; |
| | | wipSN.WS_CODE = CurWorkshop.WS_CODE; |
| | | wipSN.LINE_CODE = CurLine.LINE_CODE; |
| | | wipSN.POST_CODE = CurPosition.POST_CODE; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | wipSN.OPERATION_TIME = DateTime.Now; |
| | | wipSN.SFTS_CODE = CurLine.SFTS_CODE; |
| | | //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE; |
| | | CurBatch.StartWorking(UserCode); |
| | | |
| | | //如果是投入站 |
| | | if (curNode.IS_INPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue(); |
| | | wipSN.INLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果是产出站 |
| | | if (curNode.IS_OUTPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.OUTLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果有提交不良 |
| | | if (!input.DFT_CODE.IsNullOrEmpty()) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue(); |
| | | wipSN.DFT_FLAG = "Y"; |
| | | wipSN.DFT_COUNT++; |
| | | wipSN.DFT_CODE = input.DFT_CODE; |
| | | } |
| | | |
| | | CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(IWorkStep.Types.Node, this) |
| | | { |
| | | NodeID = curNode.ID, |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | NodeAct = act, |
| | | Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID), |
| | | }); |
| | | DBSubmitAction = () => |
| | | { |
| | | var db = GetCommitDB(); |
| | | db.Storageable(woSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(wipSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(CurWipSNHis, UserCode).ExecuteCommand(); |
| | | } |
| | | }; |
| | | Steps.Add(curStep); |
| | | |
| | | //有需要则添加工序节点的其他工步 |
| | | |
| | | //最后添加当前工序的行为工步 |
| | | GenerateSteps(curStep); |
| | | |
| | | //完成第一个工序节点工步 |
| | | curStep.IsFinished = true; |
| | | CurStep = curStep; |
| | | } |
| | | else if (!IsFinishNodeSteps) |
| | | { |
| | | var curStep = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | |
| | | //完成当前工序节点工步 |
| | | curStep.IsFinished = true; |
| | | CurStep = curStep; |
| | | } |
| | | |
| | | //完成当前工序节点 |
| | | curStep.IsFinished = true; |
| | | //未完成所有工步 |
| | | if (!IsFinishAllSteps) |
| | | { |
| | | var next = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | var result = next.Begin(this); |
| | | result.Data.StepID = next.ID; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurStep = CurStep; |
| | | return result.ToApiAction(); |
| | | var result = new ApiAction<SubmitOutput>(); |
| | | //未完成所有工序节点工步 |
| | | if (!IsFinishNodeSteps) |
| | | { |
| | | var next = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | //设置后续可执行的工步列表 |
| | | NextSteps.Clear(); |
| | | NextSteps.Add(next); |
| | | //根据后续工步返回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.NextStepID = next.ID; |
| | | |
| | | //根据工序节点工步的序号返回相应的操作提示 |
| | | switch (next.Sequence) |
| | | { |
| | | case 2: |
| | | //action.LocaleMsg = new($"请执行第二步"); |
| | | result.LocaleMsg = new("MES.Transaction.CollectNode.第二步操作提示"); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | //已完成所有工序节点工步,开始执行行为工步 |
| | | else |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | } |
| | | return result; |
| | | } |
| | | //已完成所有工步 |
| | | else |
| | | { |
| | | action.Data.IsFinished = IsFinishAllSteps; |
| | | action.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | action.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | action.Data.CurNode = CurStep.Node.NODE_NAME; |
| | | action.Data.NextStepID = ""; |
| | | action = DoIfFinishAllSteps(action); |
| | | } |
| | | } |
| | |
| | | /// </summary> |
| | | /// <param name="action"></param> |
| | | /// <returns></returns> |
| | | public ApiAction DoIfFinishAllSteps(ApiAction action) |
| | | public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action) |
| | | { |
| | | //保存数据库 |
| | | var dbTran = GetCommitDB().UseTran(() => |
| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<ApiAction> Submit(SubmitInput input) |
| | | public async Task<ApiAction<SubmitOutput>> Submit(SubmitInput input) |
| | | { |
| | | var action = new ApiAction(); |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | try |
| | | { |
| | | //工步列表为空时,认为需要先扫描过站条码 |
| | | if (Steps.IsNullOrEmpty()) |
| | | //工步列表为空或者工序节点工步有未完成时,优先完成工序节点工步 |
| | | if (Steps.IsNullOrEmpty() || !IsFinishNodeSteps) |
| | | { |
| | | //先判断当前工单不为空且当前岗位在当前工单是不是首站,如果是则不允许变更当前工单,尝试把条码绑定到当前工单 |
| | | if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode)) |
| | | { |
| | | action = ScanSn(action, input); |
| | | action = NodeSubmit(action, input); |
| | | return action; |
| | | } |
| | | //当前岗位在当前工单不是首站,则查找条码已绑定的工单当作当前工单 |
| | |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosn.Batch.ORDER_NO }); |
| | | if (!result.IsSuccessed) |
| | | { |
| | | action = result; |
| | | return action; |
| | | action.IsSuccessed = result.IsSuccessed; |
| | | action.LocaleMsg = result.LocaleMsg; |
| | | return action; |
| | | } |
| | | } |
| | | //条码过站 |
| | | action = ScanSn(action, input); |
| | | action = NodeSubmit(action, input); |
| | | return action; |
| | | } |
| | | //查找不到条码已绑定的工单 |
| | |
| | | } |
| | | } |
| | | } |
| | | //完成第一步,后开始执行当前工序的行为列表 |
| | | else if(Steps.First().IsFinished && !IsFinishAllSteps) |
| | | //完成工序节点工步后,后开始执行当前工序的行为工步 |
| | | else if(IsFinishNodeSteps && !IsFinishAllSteps) |
| | | { |
| | | //var curStep = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | var curStep = Steps.Where(q => q.ID == input.StepID).FirstOrDefault(); |
| | | if (!curStep.IsNullOrEmpty()) |
| | | var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault(); |
| | | if (submitStep.IsNullOrEmpty()) |
| | | { |
| | | var result = curStep.Submit(input); |
| | | result.Data.StepID = curStep.ID; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurStep = CurStep; |
| | | action = BeginNextActionStep(input); |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | var result = submitStep.Submit(input); |
| | | //如果当前工步已完成,开始执行下一工步 |
| | | if (result.IsSuccessed && submitStep.IsFinished) |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | } |
| | | //如果当前工步未完成 |
| | | else |
| | | { |
| | | //行为执行出错,工步被重置 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale)); |
| | | } |
| | | else |
| | | { |
| | | 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; |
| | | } |
| | | } |
| | | //如果所有工步都完成 |
| | | if (IsFinishAllSteps) |
| | | { |
| | | return DoIfFinishAllSteps(result.ToApiAction()); |
| | | return DoIfFinishAllSteps(result); |
| | | } |
| | | return result.ToApiAction(); |
| | | return result; |
| | | } |
| | | } |
| | | //没有可执行的工步 |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 扫描过站条码 |
| | | /// 工序节点工步提交数据 |
| | | /// </summary> |
| | | /// <param name="action"></param> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public ApiAction ScanSn(ApiAction action, SubmitInput input) |
| | | public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input) |
| | | { |
| | | try |
| | | { |
| | | //绑定条码到工单 |
| | | if (!CurBatch.WoSNs.Any(q => q.SN == input.SN)) |
| | | //当工步列表为空,则执行当前工序的必要逻辑当作第一个工序节点,完成后按需求创建后续的工步列表 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | CurBatch.WoSNs.Add(new() |
| | | //绑定条码到工单 |
| | | if (!CurBatch.WoSNs.Any(q => q.SN == input.SN)) |
| | | { |
| | | CurBatch.WoSNs.Add(new() |
| | | { |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | SN = input.SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | }); |
| | | } |
| | | var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN); |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | |
| | | //条码过站 |
| | | var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSN.AUTH_PROD = CurLine.LINE_CODE; |
| | | wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS; |
| | | wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.FTY_CODE = CurFactory.FTY_CODE; |
| | | wipSN.WS_CODE = CurWorkshop.WS_CODE; |
| | | wipSN.LINE_CODE = CurLine.LINE_CODE; |
| | | wipSN.POST_CODE = CurPosition.POST_CODE; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | wipSN.OPERATION_TIME = DateTime.Now; |
| | | wipSN.SFTS_CODE = CurLine.SFTS_CODE; |
| | | //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE; |
| | | CurBatch.StartWorking(UserCode); |
| | | |
| | | //如果是投入站 |
| | | if (curNode.IS_INPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue(); |
| | | wipSN.INLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果是产出站 |
| | | if (curNode.IS_OUTPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.OUTLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果有提交不良 |
| | | if (!input.DFT_CODE.IsNullOrEmpty()) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue(); |
| | | wipSN.DFT_FLAG = "Y"; |
| | | wipSN.DFT_COUNT++; |
| | | wipSN.DFT_CODE = input.DFT_CODE; |
| | | } |
| | | |
| | | CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"工单[{wipSN.WORK_ORDER}]的条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]工序[{wipSN.NODE_NAME}]过站成功,状态[{wipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]"); |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(IWorkStep.Types.Node, this) |
| | | { |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | SN = input.SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | }); |
| | | } |
| | | var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN); |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | NodeID = curNode.ID, |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | DBSubmitAction = () => |
| | | { |
| | | var db = GetCommitDB(); |
| | | db.Storageable(woSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(wipSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(CurWipSNHis, UserCode).ExecuteCommand(); |
| | | } |
| | | }; |
| | | Steps.Add(curStep); |
| | | |
| | | //有需要则添加工序节点的其他工步 |
| | | |
| | | //最后添加当前工序的行为工步 |
| | | GenerateSteps(curStep); |
| | | |
| | | //完成第一个工序节点工步 |
| | | curStep.IsFinished = true; |
| | | CurStep = curStep; |
| | | } |
| | | else if (!IsFinishNodeSteps) |
| | | { |
| | | var curStep = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | |
| | | //条码过站 |
| | | var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSN.AUTH_PROD = CurLine.LINE_CODE; |
| | | wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS; |
| | | wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.FTY_CODE = CurFactory.FTY_CODE; |
| | | wipSN.WS_CODE = CurWorkshop.WS_CODE; |
| | | wipSN.LINE_CODE = CurLine.LINE_CODE; |
| | | wipSN.POST_CODE = CurPosition.POST_CODE; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | wipSN.OPERATION_TIME = DateTime.Now; |
| | | wipSN.SFTS_CODE = CurLine.SFTS_CODE; |
| | | //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE; |
| | | CurBatch.StartWorking(UserCode); |
| | | |
| | | //如果是投入站 |
| | | if (curNode.IS_INPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue(); |
| | | wipSN.INLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果是产出站 |
| | | if (curNode.IS_OUTPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.OUTLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果有提交不良 |
| | | if (!input.DFT_CODE.IsNullOrEmpty()) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue(); |
| | | wipSN.DFT_FLAG = "Y"; |
| | | wipSN.DFT_COUNT++; |
| | | wipSN.DFT_CODE = input.DFT_CODE; |
| | | //完成当前工序节点工步 |
| | | curStep.IsFinished = true; |
| | | CurStep = curStep; |
| | | } |
| | | |
| | | CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"工单[{wipSN.WORK_ORDER}]的条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]工序[{wipSN.NODE_NAME}]过站成功,状态[{wipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]"); |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(curNode.ID, IWorkStep.Types.Node) { |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | DBSubmitAction = () => |
| | | { |
| | | var db = GetCommitDB(); |
| | | db.Storageable(woSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(wipSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(CurWipSNHis, UserCode).ExecuteCommand(); |
| | | } |
| | | }; |
| | | Steps.Add(curStep); |
| | | |
| | | //如果当前工序节点有行为则添加到工步列表 |
| | | var acts = CurBatch.NodeActs.Where(q => q.NODE_ID == curNode.ID).ToList(); |
| | | foreach (var act in acts) |
| | | { |
| | | Steps.Add(new Biz.WorkStep(act.ID, IWorkStep.Types.Action) |
| | | { |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | NodeAct = act, |
| | | Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID), |
| | | }); |
| | | } |
| | | |
| | | //完成当前工序节点 |
| | | curStep.IsFinished = true; |
| | | //未完成所有工步 |
| | | if (!IsFinishAllSteps) |
| | | { |
| | | var next = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | var result = next.Begin(this); |
| | | result.Data.StepID = next.ID; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurStep = CurStep; |
| | | return result.ToApiAction(); |
| | | var result = new ApiAction<SubmitOutput>(); |
| | | //未完成所有工序节点工步 |
| | | if (!IsFinishNodeSteps) |
| | | { |
| | | var next = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | //设置后续可执行的工步列表 |
| | | NextSteps.Clear(); |
| | | NextSteps.Add(next); |
| | | //根据后续工步返回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.NextStepID = next.ID; |
| | | |
| | | //根据工序节点工步的序号返回相应的操作提示 |
| | | switch (next.Sequence) |
| | | { |
| | | case 2: |
| | | //action.LocaleMsg = new($"请执行第二步"); |
| | | result.LocaleMsg = new("MES.Transaction.PackingNode.第二步操作提示"); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | //已完成所有工序节点工步,开始执行行为工步 |
| | | else |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | } |
| | | return result; |
| | | } |
| | | //已完成所有工步 |
| | | else |
| | | { |
| | | action.Data.IsFinished = IsFinishAllSteps; |
| | | action.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | action.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | action.Data.CurNode = CurStep.Node.NODE_NAME; |
| | | action.Data.NextStepID = ""; |
| | | action = DoIfFinishAllSteps(action); |
| | | } |
| | | } |
| | |
| | | /// </summary> |
| | | /// <param name="action"></param> |
| | | /// <returns></returns> |
| | | public ApiAction DoIfFinishAllSteps(ApiAction action) |
| | | public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action) |
| | | { |
| | | //保存数据库 |
| | | var dbTran = GetCommitDB().UseTran(() => |
| | |
| | | //保存成功,返回过站消息 |
| | | //action.LocaleMsg = new($"工单[{CurWipSN.WORK_ORDER}]的条码[{CurWipSN.SN}]在岗位[{CurWipSN.POST_CODE}]工序[{CurWipSN.NODE_NAME}]过站成功,状态[{CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]", CurWipSN.WORK_ORDER, CurWipSN.SN, CurWipSN.POST_CODE, CurWipSN.NODE_NAME, CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()); |
| | | action.LocaleMsg = new("MES.Transaction.PackingNode.ScanSn.PassSuccess", CurWipSN.WORK_ORDER, CurWipSN.SN, CurWipSN.POST_CODE, CurWipSN.NODE_NAME, CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()); |
| | | |
| | | return action; |
| | | } |
| | | #endregion Functions |
| | |
| | | using System.Threading.Tasks; |
| | | using Tiger.Model; |
| | | using static Tiger.Business.Biz; |
| | | using Org.BouncyCastle.Ocsp; |
| | | using Tiger.Model.Entitys.MES.Position; |
| | | using MailKit.Search; |
| | | |
| | | namespace Tiger.Business.MES.Transaction |
| | | { |
| | |
| | | public MES_WIP_DATA CurWipSN { get; set; } |
| | | public MES_WIP_HIS CurWipSNHis { get; set; } |
| | | public List<WorkStep> Steps { 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; |
| | | public WorkStep CurStep { get; set; } |
| | | public List<WorkStep> NextSteps { get; set; } = new(); |
| | | public bool IsFinishNodeSteps => !Steps.Any(q => q.Type == IWorkStep.Types.Node && !q.IsFinished); |
| | | 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; |
| | | #endregion Propertys & Variables |
| | | |
| | |
| | | CurWipSN = null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 生成传入工步后续的行为到工步列表 |
| | | /// </summary> |
| | | /// <param name="parent"></param> |
| | | public void GenerateSteps(WorkStep parent) |
| | | { |
| | | //递归添加所有工步 |
| | | AddNextActToSteps(parent); |
| | | //调整工步的序号 |
| | | //while (CurBatch.Edges.Any(q => Steps.First(s => s.NodeID == q.SRC_NODE).Sequence <= Steps.First(s => s.NodeID == q.TGT_NODE).Sequence)) |
| | | //{ |
| | | // var edges = CurBatch.Edges.Where(q => Steps.First(s => s.NodeID == q.SRC_NODE).Sequence >= Steps.First(s => s.NodeID == q.TGT_NODE).Sequence).ToList(); |
| | | // foreach (var edge in edges) |
| | | // { |
| | | // var source = Steps.First(s => s.NodeID == edge.SRC_NODE); |
| | | // var target = Steps.First(s => s.NodeID == edge.TGT_NODE); |
| | | // target.Sequence = source.Sequence + 1; |
| | | // } |
| | | //} |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加节点的下一个行为到工步列表 |
| | | /// </summary> |
| | | /// <param name="curNode"></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(); |
| | | foreach (var edge in edges) |
| | | { |
| | | var act = CurBatch.NodeActs.First(q => q.ID == edge.TGT_NODE); |
| | | if (Steps.Any(q => q.NodeID == act.ID)) |
| | | { |
| | | var next = Steps.First(q => q.NodeID == act.ID); |
| | | next.Sequence = next.Sequence > parent.Sequence ? next.Sequence : (parent.Sequence + 1); |
| | | next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | AddNextActToSteps(next); |
| | | } |
| | | else |
| | | { |
| | | 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.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | Steps.Add(next); |
| | | AddNextActToSteps(next); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据传入的工步,返回下一步可执行的工步列表 |
| | | /// </summary> |
| | | /// <param name="curStep"></param> |
| | | public List<WorkStep> GetNextSteps(WorkStep curStep) |
| | | { |
| | | var result = new List<WorkStep>(); |
| | | var nextSteps = Steps.Where(q => !q.IsFinished |
| | | && CurBatch.Edges.Any(e => e.SRC_NODE == curStep.NodeID && e.TGT_NODE == q.NodeID) |
| | | ).ToList(); |
| | | //尝试将当前工步的后续工步添加到可以执行的工步列表 |
| | | foreach (var step in nextSteps) |
| | | { |
| | | //查找有没有前置工步未完成,若有则不允许继续执行 |
| | | if (!Steps.Any(q => step.PrepNodeIDs.Any(id => id == q.NodeID && !q.IsFinished))) |
| | | { |
| | | result.Add(step); |
| | | } |
| | | } |
| | | //如果当前工步没有可执行的后续工步,则在前置工步查找还有没有后续工步没完成的工步,有则执行 |
| | | if (!result.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(); |
| | | var prepSteps = Steps.Where(q => prepIDs.Contains(q.NodeID)).OrderByDescending(q => q.Sequence).ToList(); |
| | | while (prepSteps.Any() && !result.Any()) |
| | | { |
| | | var prep = prepSteps.First(); |
| | | var prepNext = GetNextSteps(prep); |
| | | if (prepNext.Any()) |
| | | { |
| | | result = prepNext; |
| | | } |
| | | else |
| | | { |
| | | prepSteps.Remove(prep); |
| | | } |
| | | } |
| | | |
| | | } |
| | | return result.OrderBy(q => q.NodeAct.ACT_NAME).ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 开始执行下一行为工步 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | public ApiAction<SubmitOutput> BeginNextActionStep(SubmitInput input) |
| | | { |
| | | var result = new ApiAction<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; |
| | | |
| | | 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 = ""; |
| | | |
| | | //根据后续可执行工步列表返回相应的操作提示 |
| | | if (NextSteps.Count == 1) |
| | | { |
| | | result.LocaleMsg = NextSteps.First().GetBeginMsg(); |
| | | } |
| | | else |
| | | { |
| | | result.LocaleMsg = new(T(L("MES.Transaction.Position.PleaseSelectNextStep"), input.Locale) + "\r\n" + |
| | | string.Join("\r\n", NextSteps.Select(q => " >> " + T(q.GetBeginMsg(), input.Locale)))); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | #endregion Functions |
| | | |
| | | public override bool Close(bool needSaveHistoryLog = false) |
| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<ApiAction> Submit(SubmitInput input) |
| | | public async Task<ApiAction<SubmitOutput>> Submit(SubmitInput input) |
| | | { |
| | | var action = new ApiAction(); |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | try |
| | | { |
| | | //工步列表为空时,认为需要先扫描过站条码 |
| | | if (Steps.IsNullOrEmpty()) |
| | | //工步列表为空或者工序节点工步有未完成时,优先完成工序节点工步 |
| | | if (Steps.IsNullOrEmpty() || !IsFinishNodeSteps) |
| | | { |
| | | //先判断当前工单不为空且当前岗位在当前工单是不是首站,如果是则不允许变更当前工单,尝试把条码绑定到当前工单 |
| | | if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode)) |
| | | { |
| | | action = ScanSn(action, input); |
| | | action = NodeSubmit(action, input); |
| | | return action; |
| | | } |
| | | //当前岗位在当前工单不是首站,则查找条码已绑定的工单当作当前工单 |
| | |
| | | var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosn.Batch.ORDER_NO }); |
| | | if (!result.IsSuccessed) |
| | | { |
| | | action = result; |
| | | action.IsSuccessed = result.IsSuccessed; |
| | | action.LocaleMsg = result.LocaleMsg; |
| | | return action; |
| | | } |
| | | } |
| | | //条码过站 |
| | | action = ScanSn(action, input); |
| | | action = NodeSubmit(action, input); |
| | | return action; |
| | | } |
| | | //查找不到条码已绑定的工单 |
| | |
| | | } |
| | | } |
| | | //完成第一步,后开始执行当前工序的行为列表 |
| | | else if (Steps.First().IsFinished && !IsFinishAllSteps) |
| | | //完成工序节点工步后,后开始执行当前工序的行为工步 |
| | | else if (IsFinishNodeSteps && !IsFinishAllSteps) |
| | | { |
| | | var curStep = Steps.Where(q => q.ID == input.StepID).FirstOrDefault(); |
| | | if (!curStep.IsNullOrEmpty()) |
| | | var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault(); |
| | | if (submitStep.IsNullOrEmpty()) |
| | | { |
| | | var result = curStep.Submit(input); |
| | | result.Data.StepID = curStep.ID; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurStep = CurStep; |
| | | action = BeginNextActionStep(input); |
| | | return action; |
| | | } |
| | | else |
| | | { |
| | | var result = submitStep.Submit(input); |
| | | //如果当前工步已完成,开始执行下一工步 |
| | | if (result.IsSuccessed && submitStep.IsFinished) |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | } |
| | | //如果当前工步未完成 |
| | | else |
| | | { |
| | | //行为执行出错,工步被重置 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale)); |
| | | } |
| | | else |
| | | { |
| | | 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; |
| | | } |
| | | } |
| | | //如果所有工步都完成 |
| | | if (IsFinishAllSteps) |
| | | { |
| | | return DoIfFinishAllSteps(result.ToApiAction()); |
| | | return DoIfFinishAllSteps(result); |
| | | } |
| | | return result.ToApiAction(); |
| | | return result; |
| | | } |
| | | } |
| | | //没有可执行的工步 |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 扫描过站条码 |
| | | /// 工序节点工步提交数据 |
| | | /// </summary> |
| | | /// <param name="action"></param> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public ApiAction ScanSn(ApiAction action, SubmitInput input) |
| | | public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input) |
| | | { |
| | | try |
| | | { |
| | | //绑定条码到工单 |
| | | if (!CurBatch.WoSNs.Any(q => q.SN == input.SN)) |
| | | //当工步列表为空,则执行当前工序的必要逻辑当作第一个工序节点,完成后按需求创建后续的工步列表 |
| | | if (Steps.IsNullOrEmpty()) |
| | | { |
| | | CurBatch.WoSNs.Add(new() |
| | | //绑定条码到工单 |
| | | if (!CurBatch.WoSNs.Any(q => q.SN == input.SN)) |
| | | { |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | SN = input.SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | }); |
| | | } |
| | | var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN); |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | |
| | | //条码过站 |
| | | var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSN.AUTH_PROD = CurLine.LINE_CODE; |
| | | wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS; |
| | | wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.FTY_CODE = CurFactory.FTY_CODE; |
| | | wipSN.WS_CODE = CurWorkshop.WS_CODE; |
| | | wipSN.LINE_CODE = CurLine.LINE_CODE; |
| | | wipSN.POST_CODE = CurPosition.POST_CODE; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | wipSN.OPERATION_TIME = DateTime.Now; |
| | | wipSN.SFTS_CODE = CurLine.SFTS_CODE; |
| | | //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE; |
| | | CurBatch.StartWorking(UserCode); |
| | | |
| | | //如果是投入站 |
| | | if (curNode.IS_INPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue(); |
| | | wipSN.INLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果是产出站 |
| | | if (curNode.IS_OUTPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.OUTLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果有提交不良 |
| | | if (!input.DFT_CODE.IsNullOrEmpty()) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue(); |
| | | wipSN.DFT_FLAG = "Y"; |
| | | wipSN.DFT_COUNT++; |
| | | wipSN.DFT_CODE = input.DFT_CODE; |
| | | } |
| | | |
| | | CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(curNode.ID, IWorkStep.Types.Node) |
| | | { |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | DBSubmitAction = () => |
| | | { |
| | | var db = GetCommitDB(); |
| | | db.Storageable(woSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(wipSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(CurWipSNHis, UserCode).ExecuteCommand(); |
| | | CurBatch.WoSNs.Add(new() |
| | | { |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | SN = input.SN, |
| | | STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(), |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | }); |
| | | } |
| | | }; |
| | | Steps.Add(curStep); |
| | | var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN); |
| | | var curNode = CurBatch.GetNode(PostCode); |
| | | |
| | | //如果当前工序节点有行为则添加到工步列表 |
| | | var acts = CurBatch.NodeActs.Where(q => q.NODE_ID == curNode.ID).ToList(); |
| | | foreach (var act in acts) |
| | | { |
| | | Steps.Add(new Biz.WorkStep(act.ID, IWorkStep.Types.Action) |
| | | //条码过站 |
| | | var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA() |
| | | { |
| | | SN = input.SN, |
| | | STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(), |
| | | ITEM_CODE = CurBatch.WO.ITEM_CODE, |
| | | WORK_ORDER = CurBatch.Batch.ORDER_NO, |
| | | BATCH_NO = CurBatch.Batch.BATCH_NO, |
| | | HOLD_FLAG = "N", |
| | | REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N", |
| | | FINISHED_FLAG = "N", |
| | | INV_FLAG = "N", |
| | | DFT_FLAG = "N", |
| | | DFT_COUNT = 0, |
| | | }; |
| | | wipSN.AUTH_PROD = CurLine.LINE_CODE; |
| | | wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS; |
| | | wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | wipSN.NODE_ID = curNode.ID; |
| | | wipSN.NODE_NAME = curNode.NODE_NAME; |
| | | wipSN.FTY_CODE = CurFactory.FTY_CODE; |
| | | wipSN.WS_CODE = CurWorkshop.WS_CODE; |
| | | wipSN.LINE_CODE = CurLine.LINE_CODE; |
| | | wipSN.POST_CODE = CurPosition.POST_CODE; |
| | | wipSN.OPER_CODE = curNode.OPER_CODE; |
| | | wipSN.SEGMENT = curNode.SEGMENT; |
| | | wipSN.OPERATION_TIME = DateTime.Now; |
| | | wipSN.SFTS_CODE = CurLine.SFTS_CODE; |
| | | //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE; |
| | | //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE; |
| | | CurBatch.StartWorking(UserCode); |
| | | |
| | | //如果是投入站 |
| | | if (curNode.IS_INPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue(); |
| | | wipSN.INLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果是产出站 |
| | | if (curNode.IS_OUTPUT == "Y") |
| | | { |
| | | woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue(); |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue(); |
| | | wipSN.OUTLINE_DATE = DateTime.Now; |
| | | } |
| | | //如果有提交不良 |
| | | if (!input.DFT_CODE.IsNullOrEmpty()) |
| | | { |
| | | wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue(); |
| | | wipSN.DFT_FLAG = "Y"; |
| | | wipSN.DFT_COUNT++; |
| | | wipSN.DFT_CODE = input.DFT_CODE; |
| | | } |
| | | |
| | | CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"工单[{wipSN.WORK_ORDER}]条码[{wipSN.SN}]在岗位[{wipSN.POST_CODE}]过站工序[{wipSN.NODE_NAME}]成功"); |
| | | |
| | | //初始化工步列表 |
| | | Steps.Clear(); |
| | | var curStep = new Biz.WorkStep(IWorkStep.Types.Node, this) |
| | | { |
| | | NodeID = curNode.ID, |
| | | Sequence = Steps.Count + 1, |
| | | Node = curNode, |
| | | NodeAct = act, |
| | | Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID), |
| | | }); |
| | | DBSubmitAction = () => |
| | | { |
| | | var db = GetCommitDB(); |
| | | db.Storageable(woSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(wipSN, UserCode).ExecuteCommand(); |
| | | db.Storageable(CurWipSNHis, UserCode).ExecuteCommand(); |
| | | } |
| | | }; |
| | | Steps.Add(curStep); |
| | | |
| | | //有需要则添加工序节点的其他工步 |
| | | |
| | | //最后添加当前工序的行为工步 |
| | | GenerateSteps(curStep); |
| | | |
| | | //完成第一个工序节点工步 |
| | | curStep.IsFinished = true; |
| | | CurStep = curStep; |
| | | } |
| | | else if (!IsFinishNodeSteps) |
| | | { |
| | | var curStep = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | |
| | | //完成当前工序节点工步 |
| | | curStep.IsFinished = true; |
| | | CurStep = curStep; |
| | | } |
| | | |
| | | //完成当前工序节点 |
| | | curStep.IsFinished = true; |
| | | //未完成所有工步 |
| | | if (!IsFinishAllSteps) |
| | | { |
| | | var next = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | var result = next.Begin(this); |
| | | result.Data.StepID = next.ID; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurStep = CurStep; |
| | | return result.ToApiAction(); |
| | | var result = new ApiAction<SubmitOutput>(); |
| | | //未完成所有工序节点工步 |
| | | if (!IsFinishNodeSteps) |
| | | { |
| | | var next = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First(); |
| | | //设置后续可执行的工步列表 |
| | | NextSteps.Clear(); |
| | | NextSteps.Add(next); |
| | | //根据后续工步返回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.NextStepID = next.ID; |
| | | |
| | | //根据工序节点工步的序号返回相应的操作提示 |
| | | switch (next.Sequence) |
| | | { |
| | | case 2: |
| | | //action.LocaleMsg = new($"请执行第二步"); |
| | | result.LocaleMsg = new("MES.Transaction.TestNode.第二步操作提示"); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | //已完成所有工序节点工步,开始执行行为工步 |
| | | else |
| | | { |
| | | result = BeginNextActionStep(input); |
| | | } |
| | | return result; |
| | | } |
| | | //已完成所有工步 |
| | | else |
| | | { |
| | | action.Data.IsFinished = IsFinishAllSteps; |
| | | action.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | action.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | action.Data.CurNode = CurStep.Node.NODE_NAME; |
| | | action.Data.NextStepID = ""; |
| | | action = DoIfFinishAllSteps(action); |
| | | } |
| | | } |
| | |
| | | /// </summary> |
| | | /// <param name="action"></param> |
| | | /// <returns></returns> |
| | | public ApiAction DoIfFinishAllSteps(ApiAction action) |
| | | public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action) |
| | | { |
| | | //保存数据库 |
| | | var dbTran = GetCommitDB().UseTran(() => |
| | |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// 开始执行工序行为 |
| | | /// 初始化工序行为 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> Begin(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting) |
| | | public void Init(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting) |
| | | { |
| | | CurStep = curStep; |
| | | CurPosition = position; |
| | | NodeAct = nodeAct; |
| | | Setting = setting; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取行为开始的提示信息 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public Locale GetBeginMsg() |
| | | { |
| | | //var msg = new Locale("MES.WorkAction.IPQC.BeginMsg"); |
| | | var msg = new Locale($"请提交测试结果"); |
| | | return msg; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 尝试开始执行工序行为 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> TryBegin(SubmitInput input) |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | |
| | | |
| | | //action.LocaleMsg = new($"请按测试项提交测试数据"); |
| | | action.LocaleMsg = new("MES.WorkAction.IPQC.PleaseTest"); |
| | | |
| | | //如果根据输入可以开始执行当前行为则标记为成功,否则失败 |
| | | action.IsSuccessed = false; |
| | | return action; |
| | | } |
| | | /// <summary> |
| | |
| | | public ApiAction<SubmitOutput> Submit(SubmitInput input) |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | |
| | | //提交数据执行成功 |
| | | if (true) |
| | | { |
| | | action.IsSuccessed = true; |
| | | action.LocaleMsg = new($"执行成功"); |
| | | //action.LocaleMsg = new("MES.WorkAction.IPQC.Success"); |
| | | //行为执行完成 |
| | | if (false) |
| | | { |
| | | action = End(); |
| | | } |
| | | } |
| | | //提交数据执行失败 |
| | | else |
| | | { |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"执行失败"); |
| | | action.LocaleMsg = new("MES.WorkAction.IPQC.Fail"); |
| | | //如果行为设置为出错需要重置工序操作 |
| | | if (NodeAct.NEED_RESET == "Y") |
| | | { |
| | | CurPosition.ResetSteps(); |
| | | } |
| | | } |
| | | |
| | | return action; |
| | | } |
| | |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | |
| | | //记录行为操作记录 |
| | | var wipAct = new MES_WIP_ACT() |
| | | { |
| | | HIS_ID = CurPosition.CurWipSNHis.ID, |
| | | SN = CurPosition.CurWipSN.SN, |
| | | STATUS = CurPosition.CurWipSN.STATUS, |
| | | ITEM_CODE = CurPosition.CurWipSN.ITEM_CODE, |
| | | WORK_ORDER = CurPosition.CurWipSN.WORK_ORDER, |
| | | BATCH_NO = CurPosition.CurWipSN.BATCH_NO, |
| | | ROT_CODE = CurPosition.CurWipSN.ROT_CODE, |
| | | NODE_ID = CurPosition.CurWipSN.NODE_ID, |
| | | NODE_NAME = CurPosition.CurWipSN.NODE_NAME, |
| | | ACT_ID = NodeAct.ID, |
| | | ACT_NAME = NodeAct.ACT_NAME, |
| | | FTY_CODE = CurPosition.CurWipSN.FTY_CODE, |
| | | WS_CODE = CurPosition.CurWipSN.WS_CODE, |
| | | LINE_CODE = CurPosition.CurWipSN.LINE_CODE, |
| | | POST_CODE = CurPosition.CurWipSN.POST_CODE, |
| | | OPER_CODE = CurPosition.CurWipSN.OPER_CODE, |
| | | SEGMENT = CurPosition.CurWipSN.SEGMENT, |
| | | TRAY_SN = CurPosition.CurWipSN.TRAY_SN, |
| | | OPERATION_TIME = DateTime.Now, |
| | | SFTS_CODE = CurPosition.CurWipSN.SFTS_CODE, |
| | | SFT_CODE = CurPosition.CurWipSN.SFT_CODE, |
| | | PRD_CODE = CurPosition.CurWipSN.PRD_CODE, |
| | | ACT_TYPE = NodeAct.ACT_TYPE, |
| | | ACT_SN = CurPosition.CurWipSN.SN, |
| | | ACT_VALUE_1 = "", |
| | | ACT_VALUE_2 = "", |
| | | ACT_VALUE_3 = "", |
| | | ACT_VALUE_4 = "", |
| | | ACT_VALUE_5 = "", |
| | | ACT_RESULT = "Y", |
| | | TRACE_INFO = $"执行成功", |
| | | }; |
| | | |
| | | //保存数据 |
| | | CurStep.DBSubmitAction = () => |
| | | { |
| | | var db = CurPosition.GetCommitDB(); |
| | | db.Storageable(wipAct, CurPosition.UserCode).ExecuteCommand(); |
| | | }; |
| | | |
| | | IsFinished = true; |
| | | action.LocaleMsg = new($"行为结束"); |
| | | //action.LocaleMsg = new("MES.WorkAction.IPQC.Finish"); |
| | | return action; |
| | | } |
| | | /// <summary> |
| | | /// 获取行为提示信息 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction GetPrompt() |
| | | { |
| | | var action = new ApiAction(); |
| | | action.LocaleMsg = new($"开始打印条码"); |
| | | return action; |
| | | } |
| | | |
| | | |
| | | #endregion Functions |
| | | } |
| | |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// 开始执行工序行为 |
| | | /// 初始化工序行为 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> Begin(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting) |
| | | public void Init(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting) |
| | | { |
| | | CurStep = curStep; |
| | | CurPosition = position; |
| | | NodeAct = nodeAct; |
| | | Setting = setting; |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | |
| | | Label = Biz.Db.Queryable<BAS_LABEL_TEMP>().Where(q => q.LABEL_CODE == setting.LABEL_CODE).IncludesAllFirstLayer().First(); |
| | | LabelPV = Biz.Db.Queryable<BAS_LABEL_PV>().ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取行为开始的提示信息 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public Locale GetBeginMsg() |
| | | { |
| | | var msg = new Locale("MES.WorkAction.PrintLabel.BeginMsg", CurPosition.CurWipSN.SN, Label.LABEL_CODE, Label.LABEL_NAME); |
| | | //var msg = new Locale($"开始打印条码[{CurPosition.CurWipSN.SN}]的标签[{Label.LABEL_CODE}: {Label.LABEL_NAME}]"); |
| | | return msg; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 尝试开始执行工序行为 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> TryBegin(SubmitInput input) |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | |
| | | foreach (var item in Label.Variables) |
| | | { |
| | | switch (item.VAR_TYPE.GetEnum<BAS_LABEL_VAR.VAR_TYPEs>()) |
| | |
| | | break; |
| | | } |
| | | } |
| | | action.Data.StepActCode = nodeAct.Definition.ACT_CODE; |
| | | action.Data.Data = Label; |
| | | |
| | | //如果根据输入可以开始执行当前行为则标记为成功,否则失败 |
| | | action.IsSuccessed = true; |
| | | return action; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 工序行为提交数据 |
| | | /// </summary> |
| | |
| | | public ApiAction<SubmitOutput> Submit(SubmitInput input) |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | //提交数据执行成功 |
| | | if (input.Data.ToBoolean()) |
| | | { |
| | | action = End(); |
| | | } |
| | | //提交数据执行失败 |
| | | else |
| | | { |
| | | //重置当前工序 |
| | | CurPosition.ResetSteps(); |
| | | action.IsSuccessed = false; |
| | | //action.LocaleMsg = new($"标签{Label.LABEL_NAME}[{Label.LABEL_CODE}]打印失败,请重新扫描产品条码", Label.LABEL_NAME); |
| | | //action.LocaleMsg = new($"标签{Label.LABEL_NAME}[{Label.LABEL_CODE}]打印失败", Label.LABEL_NAME); |
| | | action.LocaleMsg = new("MES.WorkAction.PrintLabel.PrintFail", Label.LABEL_NAME, Label.LABEL_CODE); |
| | | //如果行为设置为出错需要重置工序操作 |
| | | if (NodeAct.NEED_RESET == "Y") |
| | | { |
| | | CurPosition.ResetSteps(); |
| | | } |
| | | } |
| | | return action; |
| | | } |
| | |
| | | { |
| | | var action = new ApiAction<SubmitOutput>(); |
| | | |
| | | //记录行为操作记录 |
| | | var wipAct = new MES_WIP_ACT() |
| | | { |
| | | HIS_ID = CurPosition.CurWipSNHis.ID, |
| | |
| | | using System.Xml.Linq; |
| | | using Tiger.IBusiness; |
| | | using System.Data; |
| | | using Tiger.Model.Entitys.MES.Position; |
| | | |
| | | namespace Tiger.Business |
| | | { |
| | |
| | | /// <returns></returns> |
| | | public static string T(string key, params object?[] args) => new Locale(key, args).Default(); |
| | | /// <summary> |
| | | /// 多语言翻译,按传入的语言翻译,传入语言为空则按BizSettings设置的默认语言(DefaultLanguage)翻译 |
| | | /// </summary> |
| | | /// <param name="locale"></param> |
| | | /// <param name="language"></param> |
| | | /// <returns></returns> |
| | | public static string T(Locale locale, string language) => language.IsNullOrEmpty() ? locale.Default() : locale[language]; |
| | | /// <summary> |
| | | /// 多语言对象(未翻译) |
| | | /// </summary> |
| | | /// <param name="key"></param> |
| | |
| | | /// </summary> |
| | | public partial class WorkStep : IWorkStep |
| | | { |
| | | public WorkStep(string id, IWorkStep.Types type) |
| | | public WorkStep(IWorkStep.Types type, IPosition position) |
| | | { |
| | | ID = id; |
| | | Type = type; |
| | | CurPosition = position; |
| | | } |
| | | |
| | | #region Propertys & Variables |
| | | public string ID { get; set; } = Guid.NewGuid().ToString("N"); |
| | | public string NodeID { get; set; } |
| | | public IWorkStep.Types Type { get; set; } |
| | | public int Sequence { get; set; } |
| | | public MES_WO_NODE Node { get; set; } |
| | |
| | | public MES_WO_ACTION Setting { get; set; } |
| | | public IPosition CurPosition { get; set; } |
| | | public IWorkAction CurAction { get; set; } |
| | | public List<string> PrepNodeIDs { get; set; } = new(); |
| | | private bool _IsFinished = false; |
| | | public bool IsFinished |
| | | { |
| | |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// 开始执行工步 |
| | | /// 初始化工步 |
| | | /// </summary> |
| | | /// <param name="position"></param> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> Begin(IPosition position) |
| | | public void Init() |
| | | { |
| | | CurPosition = position; |
| | | CurAction = DI.Resolve(NodeAct.Definition.SERVICE_TYPE) as IWorkAction; |
| | | //CurAction = DI.Resolve("Tiger.IBusiness.IPrintLabel,Tiger.IBusiness") as IWorkAction; |
| | | return CurAction.Begin(this, position, NodeAct, Setting); |
| | | CurAction.Init(this, CurPosition, NodeAct, Setting); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 尝试开始执行工步 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> TryBegin(SubmitInput input) |
| | | { |
| | | return CurAction.TryBegin(input); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取行为开始的提示信息 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public Locale GetBeginMsg() |
| | | { |
| | | return CurAction.GetBeginMsg(); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// 开始执行工序行为 |
| | | /// 初始化工序行为 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> Begin(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting); |
| | | public void Init(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting); |
| | | /// <summary> |
| | | /// 获取行为开始的提示信息 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public Locale GetBeginMsg(); |
| | | /// <summary> |
| | | /// 尝试开始执行工序行为 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> TryBegin(SubmitInput input); |
| | | /// <summary> |
| | | /// 工序行为提交数据 |
| | | /// </summary> |
| | |
| | | public MES_WO_ACTION Setting { get; set; } |
| | | public IPosition CurPosition { get; set; } |
| | | public IWorkAction CurAction { get; set; } |
| | | public List<string> PrepNodeIDs { get; set; } |
| | | public bool IsFinished { get; set; } |
| | | public Action DBSubmitAction { get; set; } |
| | | #endregion Propertys & Variables |
| | |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// 开始执行工步 |
| | | /// 尝试开始执行工步 |
| | | /// </summary> |
| | | /// <param name="position"></param> |
| | | /// <returns></returns> |
| | | public ApiAction<SubmitOutput> Begin(IPosition position); |
| | | public ApiAction<SubmitOutput> TryBegin(SubmitInput input); |
| | | /// <summary> |
| | | /// 获取行为开始的提示信息 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public Locale GetBeginMsg(); |
| | | /// <summary> |
| | | /// 工步提交数据 |
| | | /// </summary> |
| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public Task<ApiAction> Submit(SubmitInput input); |
| | | public Task<ApiAction<SubmitOutput>> Submit(SubmitInput input); |
| | | } |
| | | } |
| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public Task<ApiAction> Submit(SubmitInput input); |
| | | public Task<ApiAction<SubmitOutput>> Submit(SubmitInput input); |
| | | } |
| | | } |
| | |
| | | public IWorkBatch WorkBatch { get; } |
| | | public MES_WIP_DATA CurWipSN { get; set; } |
| | | public MES_WIP_HIS CurWipSNHis { get; set; } |
| | | public IPosition Init(string id, string apiHost, string userCode, string postCode); |
| | | public void ResetSteps(); |
| | | #endregion Propertys & Variables |
| | | |
| | | #region Functions |
| | | /// <summary> |
| | | /// 初始化岗位 |
| | | /// </summary> |
| | | /// <param name="id"></param> |
| | | /// <param name="apiHost"></param> |
| | | /// <param name="userCode"></param> |
| | | /// <param name="postCode"></param> |
| | | /// <returns></returns> |
| | | public IPosition Init(string id, string apiHost, string userCode, string postCode); |
| | | /// <summary> |
| | | /// 重置工步列表 |
| | | /// </summary> |
| | | public void ResetSteps(); |
| | | /// <summary> |
| | | /// 获取提交数据的DbClient对象 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public Task<ApiAction> Submit(SubmitInput input); |
| | | public Task<ApiAction<SubmitOutput>> Submit(SubmitInput input); |
| | | /// <summary> |
| | | /// 测试工序:获取工序不良代码 |
| | | /// </summary> |
| | |
| | | |
| | | namespace Tiger.Model |
| | | { |
| | | /// <summary> |
| | | /// 实体:工序行为 |
| | | /// </summary> |
| | | [Description("Primary:ID")] |
| | | [Serializable] |
| | | [SugarTable("MES_ROUTE_NODE_ACT")] |
| | | public class MES_ROUTE_NODE_ACT : DbEntityWithAuth |
| | | { |
| | | #region 构造函数 |
| | | /// <summary> |
| | | /// 实体:工序行为 |
| | | /// </summary> |
| | | public MES_ROUTE_NODE_ACT() {} |
| | | #endregion |
| | | /// <summary> |
| | | /// 实体:工艺行为节点 |
| | | /// </summary> |
| | | [Description("Primary:ID")] |
| | | [DisplayName("工艺行为节点")] |
| | | [Serializable] |
| | | [SugarTable("MES_ROUTE_NODE_ACT")] |
| | | public class MES_ROUTE_NODE_ACT : DbEntityWithAuth |
| | | { |
| | | #region 构造函数 |
| | | /// <summary> |
| | | /// 实体:工艺行为节点 |
| | | /// </summary> |
| | | public MES_ROUTE_NODE_ACT() { } |
| | | #endregion |
| | | |
| | | #region 公共属性 |
| | | /// <summary> |
| | | /// 行为名称 |
| | | /// </summary> |
| | | public string ACT_NAME { get; set; } |
| | | /// <summary> |
| | | /// 工艺路线ID |
| | | /// </summary> |
| | | public string ROT_ID { get; set; } |
| | | /// <summary> |
| | | /// 工艺路线节点ID |
| | | /// </summary> |
| | | public string NODE_ID { get; set; } |
| | | /// <summary> |
| | | /// 工序编码 |
| | | /// </summary> |
| | | //public string OPER_CODE { get; set; } |
| | | /// <summary> |
| | | /// 行为类型(0Normal默认行为|1Scan扫码验证|2Assy组装上料|3Test产品测试|4Audit产品抽检|5Print标签打印|6Package包装规则) |
| | | /// </summary> |
| | | public int ACT_TYPE { get; set; } |
| | | #region 公共属性 |
| | | /// <summary> |
| | | /// 行为名称 |
| | | /// </summary> |
| | | [DisplayName("行为名称")] |
| | | public string ACT_NAME { get; set; } |
| | | /// <summary> |
| | | /// 工艺路线ID |
| | | /// </summary> |
| | | [DisplayName("工艺路线ID")] |
| | | public string ROT_ID { get; set; } |
| | | /// <summary> |
| | | /// 工序节点ID |
| | | /// </summary> |
| | | [DisplayName("工序节点ID")] |
| | | public string NODE_ID { get; set; } |
| | | /// <summary> |
| | | /// 行为类型(0Normal默认行为|1Scan扫码验证|2Assy组装上料|3Test产品测试|4Audit产品抽检|5Print标签打印|6Package包装规则) |
| | | /// </summary> |
| | | [DisplayName("行为类型(0Normal默认行为|1Scan扫码验证|2Assy组装上料|3Test产品测试|4Audit产品抽检|5Print标签打印|6Package包装规则)")] |
| | | public int ACT_TYPE { get; set; } |
| | | /// <summary> |
| | | /// 行为编码 |
| | | /// </summary> |
| | |
| | | /// <summary> |
| | | /// 绘图属性:type |
| | | /// </summary> |
| | | [DisplayName("绘图属性:type")] |
| | | public string GPH_TYPE { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:x |
| | | /// </summary> |
| | | public double GPH_X { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:y |
| | | /// </summary> |
| | | public double GPH_Y { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:properties |
| | | /// </summary> |
| | | public string GPH_PROP { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:text |
| | | /// </summary> |
| | | public string GPH_TEXT { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:x |
| | | /// </summary> |
| | | [DisplayName("绘图属性:x")] |
| | | public double GPH_X { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:y |
| | | /// </summary> |
| | | [DisplayName("绘图属性:y")] |
| | | public double GPH_Y { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:properties |
| | | /// </summary> |
| | | [DisplayName("绘图属性:properties")] |
| | | public string GPH_PROP { get; set; } |
| | | /// <summary> |
| | | /// 绘图属性:text |
| | | /// </summary> |
| | | [DisplayName("绘图属性:text")] |
| | | public string GPH_TEXT { get; set; } |
| | | /// <summary> |
| | | /// 是否启用(Y/N) |
| | | /// </summary> |
| | | [DisplayName("是否启用(Y/N)")] |
| | | public string IS_ACTIVE { get; set; } |
| | | /// <summary> |
| | | /// 是否设置才能下发生产(Y/N) |
| | |
| | | [DisplayName("是否设置才能下发生产(Y/N)")] |
| | | public string NEED_SETUP { get; set; } |
| | | /// <summary> |
| | | /// 自定义方法类型(0ServerMethod服务端方法|1WebApiWebApi方法|2StoredProcedure存储过程) |
| | | /// 执行出错时,是否重置整个工序的操作(Y/N) |
| | | /// </summary> |
| | | // public int DO_TYPE { get; set; } |
| | | ///// <summary> |
| | | ///// 自定义方法(调用方法的全名) |
| | | ///// </summary> |
| | | //public string DO_METHOD { get; set; } |
| | | ///// <summary> |
| | | ///// 通过时执行(调用方法的全名) |
| | | ///// </summary> |
| | | //public string DO_IF_PASS { get; set; } |
| | | ///// <summary> |
| | | ///// 失败时执行(调用方法的全名) |
| | | ///// </summary> |
| | | //public string DO_IF_FAIL { get; set; } |
| | | /// <summary> |
| | | /// 设置值1 |
| | | /// </summary> |
| | | public string OPTION_1 { get; set; } |
| | | /// <summary> |
| | | /// 设置值2 |
| | | /// </summary> |
| | | public string OPTION_2 { get; set; } |
| | | /// <summary> |
| | | /// 设置值3 |
| | | /// </summary> |
| | | public string OPTION_3 { get; set; } |
| | | /// <summary> |
| | | /// 设置值4 |
| | | /// </summary> |
| | | public string OPTION_4 { get; set; } |
| | | /// <summary> |
| | | /// 设置值5 |
| | | /// </summary> |
| | | public string OPTION_5 { get; set; } |
| | | /// <summary> |
| | | /// 备注 |
| | | /// </summary> |
| | | public string REMARK { get; set; } |
| | | [DisplayName("执行出错时,是否重置整个工序的操作(Y/N)")] |
| | | public string NEED_RESET { get; set; } |
| | | /// <summary> |
| | | /// 设置值1 |
| | | /// </summary> |
| | | [DisplayName("设置值1")] |
| | | public string OPTION_1 { get; set; } |
| | | /// <summary> |
| | | /// 设置值2 |
| | | /// </summary> |
| | | [DisplayName("设置值2")] |
| | | public string OPTION_2 { get; set; } |
| | | /// <summary> |
| | | /// 设置值3 |
| | | /// </summary> |
| | | [DisplayName("设置值3")] |
| | | public string OPTION_3 { get; set; } |
| | | /// <summary> |
| | | /// 设置值4 |
| | | /// </summary> |
| | | [DisplayName("设置值4")] |
| | | public string OPTION_4 { get; set; } |
| | | /// <summary> |
| | | /// 设置值5 |
| | | /// </summary> |
| | | [DisplayName("设置值5")] |
| | | public string OPTION_5 { get; set; } |
| | | /// <summary> |
| | | /// 备注 |
| | | /// </summary> |
| | | [DisplayName("备注")] |
| | | public string REMARK { get; set; } |
| | | #endregion |
| | | |
| | | #region 虚拟属性 |
| | |
| | | Enum1, |
| | | } |
| | | */ |
| | | |
| | | /// <summary> |
| | | /// 枚举:行为类型(0Normal默认行为|1Scan扫码验证|2Assy组装上料|3Test产品测试|4Audit产品抽检|5Print标签打印|6Package包装规则) |
| | | /// </summary> |
| | | public enum ACT_TYPEs |
| | | { |
| | | [Description("自定义行为")] |
| | |
| | | Print = 5, |
| | | [Description("包装规则")] |
| | | Package = 6, |
| | | } |
| | | |
| | | public enum DO_TYPEs |
| | | { |
| | | [Description("服务端方法")] |
| | | ServerMethod, |
| | | [Description("WebApi方法")] |
| | | WebApi, |
| | | [Description("存储过程")] |
| | | StoredProcedure, |
| | | } |
| | | #endregion |
| | | |
| | |
| | | /// </summary> |
| | | [DisplayName("是否设置才能下发生产(Y/N)")] |
| | | public string NEED_SETUP { get; set; } |
| | | /// <summary> |
| | | /// 设置值1 |
| | | /// </summary> |
| | | [DisplayName("设置值1")] |
| | | /// <summary> |
| | | /// 执行出错时,是否重置整个工序的操作(Y/N) |
| | | /// </summary> |
| | | [DisplayName("执行出错时,是否重置整个工序的操作(Y/N)")] |
| | | public string NEED_RESET { get; set; } |
| | | /// <summary> |
| | | /// 设置值1 |
| | | /// </summary> |
| | | [DisplayName("设置值1")] |
| | | public string OPTION_1 { get; set; } |
| | | /// <summary> |
| | | /// 设置值2 |
| | |
| | | |
| | | public class SubmitInput : ApiInput |
| | | { |
| | | public int CurStep { get; set; } |
| | | public string StepID { get; set; } |
| | | /// <summary> |
| | | /// 客户端显示的语言 |
| | | /// </summary> |
| | | public string Locale { get; set; } |
| | | /// <summary> |
| | | /// 当前操作的工步ID,如果未指定则留空 |
| | | /// </summary> |
| | | public string CurStepID { get; set; } |
| | | /// <summary> |
| | | /// 当前扫描的内容,不限于条码 |
| | | /// </summary> |
| | | public string SN { get; set; } |
| | | /// <summary> |
| | | /// 当前操作提交的不良代码,没有则留空 |
| | | /// </summary> |
| | | public string DFT_CODE { get; set; } |
| | | /// <summary> |
| | | /// 当前操作需要提交的数据 |
| | | /// </summary> |
| | | public string Data { get; set; } |
| | | } |
| | | |
| | | public class SubmitOutput |
| | | { |
| | | /// <summary> |
| | | /// 整个工序操作是否完成 |
| | | /// </summary> |
| | | public bool IsFinished { get; set; } |
| | | public int CurStep { get; set; } |
| | | public string StepID { get; set; } |
| | | /// <summary> |
| | | /// 当前操作的工单 |
| | | /// </summary> |
| | | public string CurWO { get; set; } |
| | | /// <summary> |
| | | /// 当前操作的工单批次 |
| | | /// </summary> |
| | | public string CurBatch { get; set; } |
| | | /// <summary> |
| | | /// 当前操作的节点名称 |
| | | /// </summary> |
| | | public string CurNode { get; set; } |
| | | /// <summary> |
| | | /// 如果当前节点为工序行为节点,则行为定义编码,否则留空 |
| | | /// </summary> |
| | | public string StepActCode { get; set; } |
| | | /// <summary> |
| | | /// 下一个操作的工步ID |
| | | /// </summary> |
| | | public string NextStepID { get; set; } |
| | | /// <summary> |
| | | /// 当前操作返回的数据 |
| | | /// </summary> |
| | | public object Data { get; set; } |
| | | } |
| | | |