using JNPF.Common.Core.Manager; using JNPF.Common.Enums; using JNPF.Common.Extension; using JNPF.Common.Security; using JNPF.DependencyInjection; using JNPF.DynamicApiController; using JNPF.FriendlyException; using JNPF.JsonSerialization; using JNPF.Logging; using JNPF.Systems.Entitys.System; using JNPF.Systems.Interfaces.System; using JNPF.TaskScheduler; using JNPF.TaskScheduler.Entitys.Dto.TaskScheduler; using JNPF.TaskScheduler.Entitys.Model; using JNPF.VisualDev; using Microsoft.AspNetCore.Mvc; using SqlSugar; using Tnb.QcMgr.Entities; using Tnb.QcMgr.Entities.Entity; using Tnb.QcMgr.Entities.Enums; using Tnb.QcMgr.Interfaces; using Tnb.WarehouseMgr.Entities.Consts; using Tnb.BasicData; namespace Tnb.QcMgr { /// /// 质检方案模块 /// [ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 800)] [Route("api/[area]/[controller]/[action]")] [OverideVisualDev(ModuleId)] public class QcCheckPlanService : IOverideVisualDevService, IQcCheckPlanService, IDynamicApiController, ITransient { private const string ModuleId = "26589675013909"; private readonly ISqlSugarRepository _repository; private readonly IUserManager _userManager; private readonly TimeTaskService _timeTaskService; private readonly IBillRullService _billRullService; public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc(); private static Dictionary _dicBillCodes = new Dictionary() { [WmsWareHouseConst.SHOUJIAN_ID] = CodeTemplateConst.SHOUJIAN_CODE, [WmsWareHouseConst.XUNJIAN_ID] = CodeTemplateConst.XUNJIAN_CODE, [WmsWareHouseConst.MOJIAN_ID] = CodeTemplateConst.MOJIAN_CODE, [WmsWareHouseConst.LINGBUJIANZUIZHONGJIANYAN_ID] = CodeTemplateConst.LINGBUJIANZUIZHONGJIANYAN_CODE, [WmsWareHouseConst.CHENGPINJIANYAN_ID] = CodeTemplateConst.CHENGPINJIANYAN_CODE, }; public QcCheckPlanService(ISqlSugarRepository repository, IBillRullService billRullService, IUserManager userManager, TimeTaskService timeTaskService) { _repository = repository; _userManager = userManager; _billRullService = billRullService; _timeTaskService = timeTaskService; OverideFuncs.DeleteAsync = Delete; } private async Task Delete(string id) { ISqlSugarClient db = _repository.AsSugarClient(); QcCheckPlanH QcCheckPlanH = await db.Queryable().Where(p => p.id == id).FirstAsync(); List QcCheckPlanDs = await db.Queryable().Where(p => p.mainid == id).ToListAsync(); List QcCheckPlanAdds = await db.Queryable().Where(p => p.mainid == id).ToListAsync(); List QcCheckPlanMaterials = await db.Queryable().Where(p => p.planid == id).ToListAsync(); List QcCheckPlanProcesss = await db.Queryable().Where(p => p.planid == id).ToListAsync(); List QcCheckPlanWorks = await db.Queryable().Where(p => p.planid == id).ToListAsync(); await _timeTaskService.DeleteByName("生成质检任务" + QcCheckPlanH.id); await db.Ado.BeginTranAsync(); _ = await db.Deleteable(QcCheckPlanH).ExecuteCommandAsync(); _ = await db.Deleteable(QcCheckPlanDs).ExecuteCommandAsync(); _ = await db.Deleteable(QcCheckPlanAdds).ExecuteCommandAsync(); _ = await db.Deleteable(QcCheckPlanMaterials).ExecuteCommandAsync(); _ = await db.Deleteable(QcCheckPlanProcesss).ExecuteCommandAsync(); _ = await db.Deleteable(QcCheckPlanWorks).ExecuteCommandAsync(); await db.Ado.CommitTranAsync(); } /// /// 获取方案质检项附加信息 /// /// /// [HttpPost] public async Task GetCheckItems(string id) { ISqlSugarClient db = _repository.AsSugarClient(); List QcCheckItems = await db.Queryable().ToListAsync(); List QcCheckTypes = await db.Queryable().ToListAsync(); QcCheckPlanAdd QcCheckPlanAdd = await db.Queryable().Where(p => p.mainid == id).FirstAsync(); List QcCheckPlanDs = await db.Queryable().Where(p => p.mainid == id).ToListAsync(); CheckPlansOut CheckPlansOut = new() { id = id, hasadd = false, hasitem = false }; if (QcCheckPlanAdd != null) { CheckPlansOut.hasadd = true; CheckPlansOut.addid = QcCheckPlanAdd.id; CheckPlansOut.triggertype = QcCheckPlanAdd.triggertype!; CheckPlansOut.content = QcCheckPlanAdd.content!; CheckPlansOut.number = QcCheckPlanAdd.number; } if (QcCheckPlanDs != null && QcCheckPlanDs.Count > 0) { CheckPlansOut.hasitem = true; CheckPlansOut.checktypes = new List(); foreach (QcCheckPlanD QcCheckPlanD in QcCheckPlanDs) { if (CheckPlansOut.checktypes.Where(p => p.checktypeid == QcCheckPlanD.typeid).ToList().Count == 0) { CheckPlanTypeOut checkType = new() { checktypeid = QcCheckPlanD.typeid!, checktypename = QcCheckTypes.Where(p => p.id == QcCheckPlanD.typeid).First().name!, items = new List() }; CheckPlansOut.checktypes.Add(checkType); } PlanItemOut Item = new() { itemid = QcCheckPlanD.itemid!, itemdid = QcCheckPlanD.id!, code = QcCheckItems.Where(p => p.id == QcCheckPlanD.itemid).First().code!, name = QcCheckItems.Where(p => p.id == QcCheckPlanD.itemid).First().name!, setData = new PlanItemData { extype = QcCheckPlanD.extype!, excontent = JSON.Deserialize(QcCheckPlanD.excontent!), check = QcCheckPlanD.check! } }; if (!string.IsNullOrEmpty(QcCheckPlanD.errorcause)) { Item.setData.errorcause = QcCheckPlanD.errorcause!.Replace("[", "").Replace("]", "").Split(',', StringSplitOptions.RemoveEmptyEntries); } if (!string.IsNullOrEmpty(QcCheckPlanD.errorlevel)) { Item.setData.errorlevel = QcCheckPlanD.errorlevel!.Replace("[", "").Replace("]", "").Split(',', StringSplitOptions.RemoveEmptyEntries); } Item.setData.remark = QcCheckPlanD.remark!; Item.setData.attachment = QcCheckPlanD.attachment!; Item.setData.customer = QcCheckPlanD.custom!; if (!string.IsNullOrEmpty(QcCheckPlanD.isexec)) { Item.setData.isexec = JSON.Deserialize(QcCheckPlanD.isexec!); } Item.setShow = new PlanItemShow { extype = !string.IsNullOrEmpty(Item.setData.extype), excontent = !string.IsNullOrEmpty(QcCheckPlanD.excontent), check = !string.IsNullOrEmpty(Item.setData.check), errorcause = Item.setData.errorcause != null, errorlevel = Item.setData.errorlevel != null, remark = !string.IsNullOrEmpty(Item.setData.remark), attachment = !string.IsNullOrEmpty(Item.setData.attachment), customer = !string.IsNullOrEmpty(Item.setData.customer) }; Item.setShow.isexec = Item.setData.isexec != null && (Item.setData.isexec.attachment || Item.setData.isexec.remark); CheckPlansOut.checktypes.Where(p => p.checktypeid == QcCheckPlanD.typeid).First()?.items?.Add(Item); } } return CheckPlansOut; } /// /// 获取触发计划清单 /// /// /// [HttpPost] public async Task GetTriggerPlans() { ISqlSugarClient db = _repository.AsSugarClient(); List QcTriggerPlans = await db.Queryable().ToListAsync(); List QcTriggerEvents = await db.Queryable().ToListAsync(); List TriggerPlans = new(); foreach (QcTriggerPlan triggerPlan in QcTriggerPlans) { TriggerPlan TriggerPlan = new() { id = triggerPlan.id, name = triggerPlan.name!, code = triggerPlan.code!, type = triggerPlan.type!, cycle = triggerPlan.cycle! }; if (!string.IsNullOrEmpty(triggerPlan.trievent)) { TriggerPlan.trieventid = triggerPlan.trievent!.Replace("[", "").Replace("]", "").Replace("\r\n", "").Replace("\"", "").Replace(" ", "").Split(',', StringSplitOptions.RemoveEmptyEntries); TriggerPlan.trievent = QcTriggerEvents.Where(p => TriggerPlan.trieventid.Contains(p.id)).Select(p => p.name!).ToArray(); } TriggerPlans.Add(TriggerPlan); } return TriggerPlans; } /// /// 保存质检方案质检项和附加信息 /// /// /// [HttpPost] public async Task SaveData(CheckPlanInput CheckPlanInput) { ISqlSugarClient db = _repository.AsSugarClient(); try { if (string.IsNullOrEmpty(CheckPlanInput.mainid)) { return; } await _timeTaskService.DeleteByName("生成质检任务" + CheckPlanInput.mainid); _ = await db.Deleteable(p => p.mainid == CheckPlanInput.mainid).ExecuteCommandAsync(); _ = await db.Deleteable(p => p.mainid == CheckPlanInput.mainid).ExecuteCommandAsync(); QcCheckPlanAdd QcCheckPlanAdd = new() { mainid = CheckPlanInput.mainid, triggertype = CheckPlanInput.triggertype, content = CheckPlanInput.content, number = CheckPlanInput.number }; List QcCheckPlanDs = new(); if (CheckPlanInput.checktypes != null) { foreach (CheckPlanTypeInput checktype in CheckPlanInput.checktypes) { if (checktype.items != null) { foreach (PlanItemInput item in checktype.items) { QcCheckPlanD QcCheckPlanD = new() { mainid = CheckPlanInput.mainid, typeid = checktype.id, itemid = item.itemid, extype = item.extype, excontent = item.excontent, check = item.check, errorcause = item.errorcause?.Replace("\"", "").Trim(), errorlevel = item.errorlevel?.Replace("\"", "").Trim(), remark = item.remark, attachment = item.attachment, isexec = item.isexec, custom = item.customer, create_id = _userManager.UserId, create_time = DateTime.Now }; QcCheckPlanDs.Add(QcCheckPlanD); } } } } await db.Ado.BeginTranAsync(); _ = await db.Insertable(QcCheckPlanDs).ExecuteCommandAsync(); _ = await db.Insertable(QcCheckPlanAdd).ExecuteCommandAsync(); await db.Ado.CommitTranAsync(); if (QcCheckPlanAdd.triggertype == ((int)EnumTriggerType.周期触发).ToString() || QcCheckPlanAdd.triggertype == ((int)EnumTriggerType.一次性).ToString()) { ContentModel comtentModel = new() { cron = QcCheckPlanAdd.content!.Replace("\"", ""), interfaceId = "", interfaceName = "", parameter = new List() }; comtentModel.parameter!.Add(new InterfaceParameter() { field = "id", value = QcCheckPlanAdd.mainid, defaultValue = "" }); if (QcCheckPlanAdd.triggertype == ((int)EnumTriggerType.一次性).ToString()) { comtentModel.parameter!.Add(new InterfaceParameter() { field = "doonce", value = true.ToString(), defaultValue = "" }); } comtentModel.localHostTaskId = "QcTaskTimeWorker/CreateTask"; comtentModel.startTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); comtentModel.TenantId = _userManager?.TenantId!; comtentModel.TenantDbName = _userManager?.TenantDbName!; comtentModel.ConnectionConfig = _userManager?.ConnectionConfig!; comtentModel.Token = _userManager?.ToKen!; TimeTaskCrInput timeTaskCrInput = new() { enCode = DateTime.Now.ToString("yyyyMMddHHmmss"), fullName = "生成质检任务" + QcCheckPlanAdd.mainid, executeType = "3", executeContent = comtentModel.ToJsonString(), description = "", sortCode = 99, enabledMark = 1, }; await _timeTaskService.DeleteByName(timeTaskCrInput.fullName); await _timeTaskService.Create(timeTaskCrInput, false); } } catch (Exception) { await db.Ado.RollbackTranAsync(); throw Oops.Oh(ErrorCode.COM1000); } } /// /// WMS出库入库检 /// /// /// [HttpPost] public async Task CreateWmsTask(CreateTaskEntity entity) { ISugarQueryable Query = _repository.AsSugarClient().Queryable ((a, b) => new object[] { JoinType.Inner,a.id== b.mainid, }); GetQuery(Query, entity); List list = await Query.ToListAsync(); List taskEntities = new List(); foreach (QcCheckPlanH data in list) { if (entity.materialids.Count>0) { if (_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id).Any()) { var Materials= _repository.AsSugarClient().Queryable().Where(p => p.planid == data.id).Select(p=>p.materialid).ToList(); var Intersect = entity.materialids.Intersect(Materials).ToList(); if (Intersect.Count > 0) { taskEntities.Add(new TaskEntity { maintableid=entity.maintableid, materialids = Intersect!, qcCheckPlanH = data }); } } } } if (taskEntities.Count > 0) { await SaveTask(taskEntities); } } private void GetQuery(ISugarQueryable Query, CreateTaskEntity entity) { List DictionaryData = _repository.AsSugarClient().Queryable ((a, b) => new object[] { JoinType.Left, a.DictionaryTypeId == b.Id, }) .Where((a, b) => b.FullName == "质检类型选择").ToList(); QcTriggerEvent TriggerEvent = new(); EnumTriggerEvent? enumTriggerEvent = entity.triggerevent; RemarkAttribute remark = RemarkAttribute.GetRemark(enumTriggerEvent); string type = DictionaryData.Where(p => p.FullName == remark.CheckType).First().Id; TriggerEvent = _repository.AsSugarClient().Queryable().Where(p => p.type == type && p.name == remark.CheckContent).First(); Query = Query.Where((a, b) => b.triggertype == "3" && b.content!.Contains(TriggerEvent.id)); } private async Task SaveTask(List taskEntities) { DictionaryDataEntity DictionaryData = _repository.AsSugarClient().Queryable ((a, b) => new object[] { JoinType.Left, a.DictionaryTypeId == b.Id, }) .Where((a, b) => b.FullName == "质检状态" && a.FullName == "待执行").First(); foreach (var entity in taskEntities) { List plands = await _repository.AsSugarClient().Queryable().Where(p =>p.mainid== entity.qcCheckPlanH.id).ToListAsync(); foreach (string s in entity.materialids) { DateTime time = DateTime.Now; QcCheckExecH qcCheckExecH = new() { id = SnowflakeIdHelper.NextId(), checktype = entity.qcCheckPlanH.checktype, status = DictionaryData.Id, tasktime = time.ToString("yyyy-MM-dd HH:mm:ss"), materialid = s, create_id = _userManager.UserId, create_time = time, extras= entity.maintableid }; List ExecDs = new(); foreach (var pland in plands) { QcCheckExecD QcCheckExecD = new() { mainid = qcCheckExecH.id, extype = pland.extype, excontent = pland.excontent, check = pland.check, errorcause = pland.errorcause, errorlevel = pland.errorlevel, remark = pland.remark, attachment = pland.attachment, isexec = pland.isexec, custom = pland.custom, typeid = pland.typeid, itemid = pland.itemid, create_id = _userManager.UserId, create_time = time }; ExecDs.Add(QcCheckExecD); } _ = await _repository.AsSugarClient().Insertable(qcCheckExecH).ExecuteCommandAsync(); _ = await _repository.AsSugarClient().Insertable(ExecDs).ExecuteCommandAsync(); } } } /// /// 根据计划生成任务 /// /// /// [HttpPost] public async Task CreateTask(TriggerPlanEntity entity) { ISugarQueryable Query = _repository.AsSugarClient().Queryable ((a, b, c, d, e) => new object[] { JoinType.Inner,a.id== b.mainid, JoinType.Left,a.id == c.planid && c.materialid==entity.materialid, JoinType.Left,a.id == d.planid && d.processid==entity.processid, JoinType.Left,a.id == e.planid && e.workid==entity.workid, }); GetQuery(Query, entity); // if (!string.IsNullOrEmpty(entity.materialid)) // { // Query = Query.Where((a, b, c, d, e) => c.materialid==entity.materialid); // } // if (!string.IsNullOrEmpty(entity.processid)) // { // Query = Query.Where((a, b, c, d, e) => d.processid==entity.processid); // } // if (!string.IsNullOrEmpty(entity.workid)) // { // Query = Query.Where((a, b, c, d, e) => e.workid==entity.workid); // } //Query = Query.Where((a, b, c, d, e)=>c.materialid==entity.materialid || d.processid==entity.processid || e.workid==entity.workid); List list = await Query.ToListAsync(); if (list.IsEmpty()) { throw Oops.Bah($"{entity.triggerevent.ToString()}未找到质检方案"); } if (list.Count > 1) { throw Oops.Bah($"{entity.triggerevent.ToString()}找到多个质检方案"); } if (list[0].status == "0") { Log.Error($"{list[0].id}已停用"); return; } // List removes = new(); // foreach (QcCheckPlanH data in list) // { // if (!string.IsNullOrEmpty(entity.materialid)) // { // // if (_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id).Any()) // // { // // if (!_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id && p.materialid == entity.materialid).Any()) // // { // // removes.Add(data.id); // // } // // } // } // if (!string.IsNullOrEmpty(entity.processid)) // { // if (_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id).Any()) // { // if (!_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id && p.processid == entity.processid).Any()) // { // removes.Add(data.id); // } // // } // } // if (!string.IsNullOrEmpty(entity.workid)) // { // if (_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id).Any()) // { // if (!_repository.AsSugarClient().Queryable().Where(p => p.planid == data.id && p.workid == entity.workid).Any()) // { // removes.Add(data.id); // } // } // } // } // // list = list.Where(p => !removes.Contains(p.id)).ToList(); // .WhereIF(!string.IsNullOrEmpty(entity.materialid), (a, b, c, d, e) => c.materialid == entity.materialid) // .WhereIF(!string.IsNullOrEmpty(entity.processid), (a, b, c, d, e) => d.processid == entity.processid) // .WhereIF(!string.IsNullOrEmpty(entity.workid), (a, b, c, d, e) => e.workid == entity.workid).ToListAsync(); Filter(list, entity); if (list.Count > 0) { await SaveTask(list, entity); } } private void GetQuery(ISugarQueryable Query, TriggerPlanEntity entity) { List DictionaryData = _repository.AsSugarClient().Queryable ((a, b) => new object[] { JoinType.Left, a.DictionaryTypeId == b.Id, }) .Where((a, b) => b.FullName == "质检类型选择").ToList(); QcTriggerEvent TriggerEvent = new(); EnumTriggerEvent? enumTriggerEvent = entity.triggerevent; RemarkAttribute remark = RemarkAttribute.GetRemark(enumTriggerEvent); string type = DictionaryData.Where(p => p.FullName == remark.CheckType).First().Id; TriggerEvent = _repository.AsSugarClient().Queryable().Where(p => p.type == type && p.name == remark.CheckContent).First(); if (entity.triggertype == "3") { Query = Query.Where((a, b, c, d, e) => b.triggertype ==entity.triggertype && b.content!.Contains(TriggerEvent.id) && a.checktype==entity.plan_check_type); } else { Query = Query.Where((a, b, c, d, e) => b.triggertype ==entity.triggertype && a.checktype==entity.plan_check_type); } Query = Query.Where((a,b,c,d,e)=>!SqlFunc.IsNullOrEmpty(c.id) || !SqlFunc.IsNullOrEmpty(d.id) || !SqlFunc.IsNullOrEmpty(e.id)); } private void Filter(List QcCheckPlanHs, TriggerPlanEntity entity) { List removePlanHs = new(); EnumTriggerEvent? enumTriggerEvent = entity.triggerevent; foreach (QcCheckPlanH plan in QcCheckPlanHs) { if (enumTriggerEvent == EnumTriggerEvent.首件检换模具) { } if (enumTriggerEvent == EnumTriggerEvent.首件检换物料批号) { } if (enumTriggerEvent == EnumTriggerEvent.首件检换物料编号) { } if (enumTriggerEvent == EnumTriggerEvent.首件检新的生产任务) { } if (enumTriggerEvent == EnumTriggerEvent.首件检生产任务暂停) { } if (enumTriggerEvent == EnumTriggerEvent.出厂检按入厂频次) { } if (enumTriggerEvent == EnumTriggerEvent.入厂检按物料频次) { } if (enumTriggerEvent == EnumTriggerEvent.入厂检按物料编号) { } if (enumTriggerEvent == EnumTriggerEvent.生产检定量) { int? number = _repository.AsSugarClient().Queryable().Where(p => p.mainid == plan.id).First().number; if ((entity.newpronum + (entity.oldpronum / number)) <= (entity.oldpronum / number)) { removePlanHs.Add(plan); } } if (enumTriggerEvent == EnumTriggerEvent.零部件最终检验) { // int? number = _repository.AsSugarClient().Queryable().Where(p => p.mainid == plan.id).First().number; // if ((entity.newpronum + (entity.oldpronum / number)) <= (entity.oldpronum / number)) // { // removePlanHs.Add(plan); // } } if (enumTriggerEvent == EnumTriggerEvent.开工首件检) { } if (enumTriggerEvent == EnumTriggerEvent.生产检定码) { } if (enumTriggerEvent == EnumTriggerEvent.生产检产出频次) { int? number = _repository.AsSugarClient().Queryable().Where(p => p.mainid == plan.id).First().number; if ((entity.pronum % number) != 0) { removePlanHs.Add(plan); } } if (enumTriggerEvent == EnumTriggerEvent.生产检固定次数) { } if (enumTriggerEvent == EnumTriggerEvent.生产检按流转卡) { } } removePlanHs.ForEach(p => { _ = QcCheckPlanHs.Remove(p); }); } private async Task SaveTask(List planhs, TriggerPlanEntity entity) { DictionaryDataEntity DictionaryData = _repository.AsSugarClient().Queryable ((a, b) => new object[] { JoinType.Left, a.DictionaryTypeId == b.Id, }) .Where((a, b) => b.FullName == "质检状态" && a.FullName == "待执行").First(); List plands = await _repository.AsSugarClient().Queryable().Where(p => planhs.Select(p => p.id).ToList().Contains(p.mainid!)).ToListAsync(); foreach (QcCheckPlanH planh in planhs) { DateTime time = DateTime.Now; string billCode = await _billRullService.GetBillNumber(_dicBillCodes[planh.checktype]); QcCheckExecH qcCheckExecH = new() { id = SnowflakeIdHelper.NextId(), bill_code = billCode, checktype = planh.checktype, status = DictionaryData.Id, tasktime = time.ToString("yyyy-MM-dd HH:mm:ss"), materialid = entity.materialid, processid = entity.processid, workid = entity.workid, create_id = _userManager.UserId, create_time = time, mo_task_code = entity.mo_task_code, carry_code = entity.carry_code, report_id = entity.report_id, check_type = entity.check_type, batch = entity.batch }; if (entity.triggerevent == EnumTriggerEvent.零部件最终检验 || entity.triggerevent == EnumTriggerEvent.开工首件检 || entity.triggerevent==EnumTriggerEvent.末检质检方案 ) { qcCheckExecH.checknum = entity.newpronum.ToString(); } List ExecDs = new(); foreach (QcCheckPlanD? pland in plands.Where(p => p.mainid == planh.id).ToList()) { QcCheckExecD QcCheckExecD = new() { mainid = qcCheckExecH.id, extype = pland.extype, excontent = pland.excontent, check = pland.check, errorcause = pland.errorcause, errorlevel = pland.errorlevel, remark = pland.remark, attachment = pland.attachment, isexec = pland.isexec, custom = pland.custom, typeid = pland.typeid, itemid = pland.itemid, create_id = _userManager.UserId, create_time = time }; ExecDs.Add(QcCheckExecD); } _ = await _repository.AsSugarClient().Insertable(qcCheckExecH).ExecuteCommandAsync(); _ = await _repository.AsSugarClient().Insertable(ExecDs).ExecuteCommandAsync(); } } } }