using Rhea.Common; using Tiger.IBusiness; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading; using System.Threading.Tasks; using Tiger.Model; using Tiger.Model.Sharetronic.Shelf; using System.ComponentModel; namespace Tiger.Business.MES.Transaction { /// /// SMT上料调度事务 /// public class LoadingMaterial : MESTransactionBase, ILoadingMaterial { public ILoadingMaterial Init(string id, string userCode, string apiHost, string orgCode) { TransID = id; UserCode = userCode; ApiHost = apiHost; OrgCode = orgCode; Logger.Console.Info($"Start {this.GetType().Name} Transaction[ID: {TransID}]"); return this; } #region Propertys & Variables public string UserCode { get; set; } public long UserId { get; set; } public string OrgCode { get; set; } public string CurrSmtCode { get; set; } public string CurrSlotNo { get; set; } /// /// 步骤类型 /// public enum Step_Types { /// /// 扫描机器编码 /// [Description("机器编码")] SmtCode, /// /// 扫描槽位 /// [Description("槽位")] SlotNo, /// /// 扫描飞达 /// [Description("Feeder")] Feeder, /// /// 扫描料盘SN /// [Description("料盘码")] SN, } /// /// 完成状态 /// public enum Statuss { /// /// 扫描机器编码完成 /// [Description("机器编码完成")] SmtCodeOK, /// /// 扫描槽位完成 /// [Description("槽位完成")] SlotNoOK, /// /// 扫描飞达完成 /// [Description("Feeder完成")] FeederOK, /// /// 扫描料盘SN完成 /// [Description("料盘码完成")] SnOK, /// /// 当前机器完成 /// [Description("当前机器完成")] CurrCompleted, /// /// 全部完成 /// [Description("全部完成")] Completed, } #endregion Propertys & Variables #region Functions /// /// 扫描条码上料 /// /// /// public async Task> ScanItem(SmtLoadingInput input) { var action = new ApiAction(); try { if (input.Code.IsNullOrEmpty()) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"{EnumHelper.GetEnum(input.Step).GetDesc()}不能为空"); return action; } //01根据上料步骤执行相应方法 switch (EnumHelper.GetEnum(input.Step)) { case Step_Types.SmtCode: action = ExecuteSmtCode(input); break; case Step_Types.SlotNo: action = ExecuteSlotNo(input); break; case Step_Types.Feeder: action = ExecuteFeeder(input); break; case Step_Types.SN: action = ExecuteSN(input); break; } if (!action.IsSuccessed) { return action; } //02保存上料数据 //03查看未上料列表 SmtTool smtTool = new(); var actionSmtTool = await smtTool.GetNotLoadingMaterial(input); if (actionSmtTool.IsSuccessed) { //带入机器编码查询,如果没有未上料的项,说明当前机器所有槽位均已完成上料! if (actionSmtTool.Data.Count == 0) { var _input = input.Clone(); _input.machineCode = ""; action.LocaleMsg = Biz.L($"当前机器所有槽位均已完成上料!"); var _actionSmtTool = await smtTool.GetNotLoadingMaterial(_input); if (_actionSmtTool.IsSuccessed) { //不带入机器编码查询,如果没有未上料的项,说明当前线别所有机器均已完成上料! if (_actionSmtTool.Data.Count == 0) { action.LocaleMsg = Biz.L($"当前线别所有机器均已完成上料"); } } else { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"获取未上料列表失败!"); } } } else { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"获取未上料列表失败!"); } //action.Data = new ProdReqOutput() //{ // SN = CurInv.SN, // ItemCode = CurInv.ItemInfo.ITEM_CODE, // Qty = CurInv.CurPkg.QTY, // CutQty = CurInv.CurPkg.QTY - cutQty, // isCutting = isCutting, // isExceed = isExceed, // ReqNo = req.BILLCODE, // regionCode = CurInv.Region.REGION_CODE, // locationCode = CurInv.Location?.LOCATION_CODE, //}; } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"扫描物料[{input.Code}]复核异常"); } return action; } /// /// 01扫描机器编码操作 /// /// /// private ApiAction ExecuteSmtCode(SmtLoadingInput input) { var action = new ApiAction(); SmtLoadingReturn loadingReturn = new(); try { if (Biz.Db.Queryable().Where(x => x.WORK_ORDER == input.moCode && x.LINE_CODE == input.lineCode && x.PROD_CODE == input.prodCode && x.SMT_CODE == input.Code).Any()) { CurrSmtCode = input.Code; action.IsSuccessed = true; action.LocaleMsg = Biz.L($"机器编码验证通过!"); loadingReturn.SmtCode = CurrSmtCode; loadingReturn.Step = (int)Step_Types.SmtCode; loadingReturn.Status = (int)Statuss.SmtCodeOK; } else { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"料站表中不存在此机器编码,请确认料站表是否正确上传!"); } action.Data = loadingReturn; } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"扫描机器编码异常"); } return action; } /// /// 02扫描槽位操作 /// /// /// private ApiAction ExecuteSlotNo(SmtLoadingInput input) { var action = new ApiAction(); SmtLoadingReturn loadingReturn = new(); try { if (Biz.Db.Queryable().Where(x => x.WORK_ORDER == input.moCode && x.LINE_CODE == input.lineCode && x.PROD_CODE == input.prodCode && x.SMT_CODE == CurrSmtCode && x.SLOT_NO == input.Code).Any()) { CurrSlotNo = input.Code; action.IsSuccessed = true; action.LocaleMsg = Biz.L($"槽位验证通过!"); loadingReturn.SmtCode = CurrSmtCode; loadingReturn.SlotNo = CurrSlotNo; loadingReturn.Step = (int)Step_Types.SlotNo; loadingReturn.Status = (int)Statuss.SlotNoOK; loadingReturn.LoadingCount = Biz.Db.Queryable().Where(x=> x.WORK_ORDER == input.moCode && x.LINE_CODE == input.lineCode && x.PROD_CODE == input.prodCode && x.SMT_CODE == CurrSmtCode && x.SLOT_NO == input.Code).Count(); } else { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"此槽位[{input.Code}]不存在或料站表未上传!"); } action.Data = loadingReturn; } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"扫描槽位异常"); } return action; } /// /// 03扫描飞达操作 /// /// /// private ApiAction ExecuteFeeder(SmtLoadingInput input) { var action = new ApiAction(); SmtLoadingReturn loadingReturn = new(); try { var _feeder = Biz.Db.Queryable().Where(x => x.FEEDER_CODE == input.Code).First(); //检查飞达保养维护情况 if (_feeder.FEEDER_TYPE.IsNullOrEmpty()) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"此飞达[{input.Code}]未维护类型信息!"); return action; } if (_feeder.FEEDER_TYPE != input.feederType) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"此Feeder[{input.Code}]类型不一致!要求的类型:[{_feeder.FEEDER_TYPE}];当前Feeder的类型:[{input.feederType}]"); return action; } if (_feeder.USED_COUNT >= _feeder.MAX_COUNT) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"此Feeder[{input.Code}]已达最大使用次数,请保养后再使用!"); return action; } var _loading = Biz.Db.Queryable().Where(x => x.FEEDER_CODE == input.Code).First(); if (_loading!=null) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"此Feeder[{input.Code}]已被占用!线别:[{_loading.LINE_CODE}],工单:[{_loading.WORK_ORDER}],机器:[{_loading.SMT_CODE}],槽位:[{_loading.SLOT_NO}]"); return action; } action.LocaleMsg = Biz.L($"此Feeder验证通过!"); loadingReturn.SmtCode = CurrSmtCode; loadingReturn.SlotNo = CurrSlotNo; loadingReturn.Step = (int)Step_Types.Feeder; loadingReturn.Status = (int)Statuss.FeederOK; loadingReturn.LoadingCount = Biz.Db.Queryable().Where(x => x.WORK_ORDER == input.moCode && x.LINE_CODE == input.lineCode && x.PROD_CODE == input.prodCode && x.SMT_CODE == CurrSmtCode && x.FEEDER_CODE == input.Code && x.SLOT_NO == CurrSlotNo).Count(); } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"扫描Feeder异常"); } return action; } /// /// 04扫描物料条码操作 /// /// /// private ApiAction ExecuteSN(SmtLoadingInput input) { var action = new ApiAction(); try { } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"扫描料盘码异常"); } return action; } /// /// 添加一个ApiAction的历史记录 /// /// public override void AddHistory(Microsoft.AspNetCore.Http.HttpRequest request, ApiAction action) { var his = action.History(); //his.TraceDic.Add("CurReqType", CurReqType); //his.TraceDic.Add("CurInv", CurInv); //his.TraceDic.Add("req", req); //his.TraceDic.Add("toMes", toMes); //his.TraceDic.Add("CurPoolList", CurPoolList); //his.TraceDic.Add("isComplete", his_isComplete); //ActionHistoryList.Add($"{request.HttpContext.TraceIdentifier} at {action.Timestamp:yyyy/MM/dd HH:mm:ss.fff}: {request.Path}", his); LastActionTime = DateTime.Now; } #endregion Functions public override bool Close(bool needSaveHistoryLog = false) { //needSaveHistoryLog = true; //保存操作日志 this.IsFinished = true; return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished; } }//endClass }