diff --git a/BasicData/Tnb.BasicData.Entities/Consts/DictConst.cs b/BasicData/Tnb.BasicData.Entities/Consts/DictConst.cs index 3d130676..da84b4d4 100644 --- a/BasicData/Tnb.BasicData.Entities/Consts/DictConst.cs +++ b/BasicData/Tnb.BasicData.Entities/Consts/DictConst.cs @@ -163,6 +163,11 @@ public static class DictConst /// andon状态已完成 /// public const string AndonStatusYWC = "5"; + + /// + /// 产成品入库单 + /// + public const string CHANCHENGPINRUKUDAN = "40"; #endregion diff --git a/BasicData/Tnb.BasicData/BasQrcodeService.cs b/BasicData/Tnb.BasicData/BasQrcodeService.cs index 796891dc..c3875673 100644 --- a/BasicData/Tnb.BasicData/BasQrcodeService.cs +++ b/BasicData/Tnb.BasicData/BasQrcodeService.cs @@ -10,6 +10,7 @@ using Tnb.BasicData.Entities.Dto; using Tnb.BasicData.Entitys.Dto.BasProcess; using Tnb.BasicData.Interfaces; using Tnb.EquipMgr.Entities; +using Tnb.WarehouseMgr.Entities; namespace Tnb.BasicData { @@ -41,8 +42,10 @@ namespace Tnb.BasicData .LeftJoin((a, b) => a.source_id == b.Id) .LeftJoin((a, b, c) => a.source_id == c.id) .LeftJoin((a, b, c, d) => a.source_id == d.id) + .LeftJoin((a,b,c,d,e)=>a.source_id==e.id) + .LeftJoin((a,b,c,d,e,f)=>a.source_id==f.id) .Where((a, b, c, d) => a.code == code) - .Select((a, b, c, d) => new + .Select((a, b, c, d,e,f) => new { id = a.id, source_id = a.source_id, @@ -52,6 +55,10 @@ namespace Tnb.BasicData equip_code = a.code, equip_name = c.name, tool_location_code = d.location_code, + bas_location_name = e.location_name, + bas_location_code = e.location_code, + carry_name = f.carry_name, + carry_code = f.carry_code, }).FirstAsync(); return result; } diff --git a/EquipMgr/Tnb.EquipMgr.Entities/Entity/EqpEquipment.cs b/EquipMgr/Tnb.EquipMgr.Entities/Entity/EqpEquipment.cs index c94ec696..70b020ae 100644 --- a/EquipMgr/Tnb.EquipMgr.Entities/Entity/EqpEquipment.cs +++ b/EquipMgr/Tnb.EquipMgr.Entities/Entity/EqpEquipment.cs @@ -212,5 +212,15 @@ public partial class EqpEquipment : BaseEntity /// 挤出件类型 /// public string? tube { get; set; } + + /// + /// 入库库位id + /// + public string? as_location_id { get; set; } + + /// + /// 第三方平台设备编号 + /// + public string? third_equip_code { get; set; } } diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/InstockInput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/InstockInput.cs new file mode 100644 index 00000000..c7413345 --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/InstockInput.cs @@ -0,0 +1,8 @@ +namespace Tnb.ProductionMgr.Entities.Dto +{ + public class InstockInput + { + public string equip_code { get; set; } + public string as_location_code { get; set; } + } +} \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/KittingOutNewInput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/KittingOutNewInput.cs new file mode 100644 index 00000000..bf98ca2b --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/KittingOutNewInput.cs @@ -0,0 +1,27 @@ +namespace Tnb.ProductionMgr.Entities.Dto +{ + public class KittingOutNewInput + { + + /// + /// 目标库位编号 + /// + public string location_code { get; set; } = string.Empty; + + + /// + /// 齐套搭配方案ID + /// + public string collocation_scheme_id { get; set; } = string.Empty; + + /// 所属工位 + /// + public string? workstation_id { get; set; } + + /// + /// 任务单 + /// + public string? mo_task_id { get; set; } + + } +} \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/MaterialPreparationPlanOutput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/MaterialPreparationPlanOutput.cs new file mode 100644 index 00000000..f8c367bd --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/MaterialPreparationPlanOutput.cs @@ -0,0 +1,30 @@ +namespace Tnb.ProductionMgr.Entities.Dto.PrdManage +{ + public class MaterialPreparationPlanOutput + { + public string mo_task_id { get; set; } + public string mo_task_code { get; set; } + public string material_id { get; set; } + public string material_code { get; set; } + public int? num { get; set; } + public List children { get; set; } = new List(); + } + + public class MaterialPreparationPlanDOutput + { + public int? rate_num { get; set; } + public string mo_task_id { get; set; } + public string mo_task_code { get; set; } + public string parent_id { get; set; } + public string material_id { get; set; } + public string material_code { get; set; } + public List children { get; set; } = new List(); + } + + public class MaterialPreparationPlanDDOutput + { + public string material_id { get; set; } + public string material_code { get; set; } + public decimal? num { get; set; } + } +} \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/PADPackageTaskPageOutput.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/PADPackageTaskPageOutput.cs index a0365f28..f332da09 100644 --- a/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/PADPackageTaskPageOutput.cs +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Dto/PrdManage/PADPackageTaskPageOutput.cs @@ -144,5 +144,15 @@ namespace Tnb.ProductionMgr.Entities.Dto.PrdManage /// 副单位数量(kg) /// public string? deputy_num { get; set; } + + /// + /// 第三方平台设备编号 + /// + public string? third_equip_code { get; set; } + + /// + /// 称重点位名称 + /// + public string? weight_name { get; set; } } } \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdReport.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdReport.cs index d1980bec..e24a66f2 100644 --- a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdReport.cs +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdReport.cs @@ -126,8 +126,8 @@ public partial class PrdReport : BaseEntity public string? process_id { get; set; } /// - /// 料箱二维码 + /// 料箱编号 /// - public string material_box_qrcode { get; set; } + public string material_box_code { get; set; } } diff --git a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdInstockService.cs b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdInstockService.cs index 5e6b5e87..5cca73d3 100644 --- a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdInstockService.cs +++ b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdInstockService.cs @@ -21,5 +21,12 @@ namespace Tnb.ProductionMgr.Interfaces /// source_id /// public Task SyncInstock(Dictionary dic); + + /// + /// 注塑满箱到位后入库申请 + /// + /// + /// + public Task InstockTypeOne(InstockInput inut); } } \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdMoTaskService.cs b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdMoTaskService.cs index 16eca732..29f0b0aa 100644 --- a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdMoTaskService.cs +++ b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IPrdMoTaskService.cs @@ -19,5 +19,12 @@ namespace Tnb.ProductionMgr.Interfaces /// /// Task> GetListByEqpId(string eqpId); + + /// + /// 获取备料计划 + /// + /// + Task GetMaterialPreparationPlan(); + } } diff --git a/ProductionMgr/Tnb.ProductionMgr.Interfaces/IRedisDataService.cs b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IRedisDataService.cs new file mode 100644 index 00000000..35ff9417 --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr.Interfaces/IRedisDataService.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Tnb.ProductionMgr.Interfaces +{ + public interface IRedisDataService + { + /// + /// 根据机号获取重量 + /// + Task GetWeight(string key, string field); + } +} diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdInstockService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdInstockService.cs index 2e5d2d2f..a854e8d2 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdInstockService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdInstockService.cs @@ -29,6 +29,7 @@ using JNPF.Common.Filter; using JNPF.Common.Security; using JNPF.Systems.Entitys.Permission; using JNPF.Systems.Interfaces.Permission; +using Microsoft.AspNetCore.Authorization; using SQLitePCL; using SqlSugar.Extensions; @@ -261,5 +262,132 @@ namespace Tnb.ProductionMgr return result.IsSuccess; } + + /// + /// 注塑满箱到位后入库申请 + /// + /// + /// + /// + [AllowAnonymous] + public async Task InstockTypeOne(InstockInput inut) + { + string equip_code = inut.equip_code; + string as_location_code = inut.as_location_code; + if (!string.IsNullOrEmpty(equip_code)) throw Oops.Bah("请传机台号"); + var db = _repository.AsSugarClient(); + EqpEquipment equipment = await db.Queryable().Where(x => x.code == equip_code).FirstAsync(); + if(equipment==null ) throw Oops.Bah("未找到机台"); + if(string.IsNullOrEmpty(equipment.as_location_id)) throw Oops.Bah("未找到入库库位"); + BasLocation basLocation = await db.Queryable().SingleAsync(x=>x.id==equipment.as_location_id); + if(basLocation==null) throw Oops.Bah("未找到入库库位"); + PrdReport prdReport = await db.Queryable() + .Where(x => x.equip_id == equipment.id && x.status == 0).OrderByDescending(x => x.create_time) + .FirstAsync(); + if(prdReport==null) throw Oops.Bah("未找到提报记录"); + + PrdInstockH prdInstockH = null; + List prdInstockDs = new List() { }; + DbResult result2 = new DbResult(); + BasMaterial basMaterial = await db.Queryable().SingleAsync(x=>x.id==prdReport.material_id); + DbResult result = await db.Ado.UseTranAsync(async () => + { + OrganizeEntity workline = await _organizeService.GetAnyParentByWorkstationId(prdReport.station, DictConst.RegionCategoryWorklineCode); + OrganizeEntity workshop = await _organizeService.GetAnyParentByWorkstationId(prdReport.station, DictConst.RegionCategoryWorkshopCode); + + prdInstockH = new PrdInstockH() + { + bill_type = DictConst.CHANCHENGPINRUKUDAN, + bill_date = DateTime.Now, + create_id = _userManager.UserId, + location_code = basLocation.location_code, + carry_code = prdReport.material_box_code, + is_check = 1, + station_id = prdReport.station, + workline_id = workline?.Id ?? "", + workshop_id = workshop?.Id ?? "", + org_id = _userManager.GetUserInfo().Result.organizeId, + warehouse_id = basLocation?.wh_id, + status = 0, + }; + + prdInstockDs.Add(new PrdInstockD() + { + instock_id = prdInstockH.id, + report_id = prdReport.create_id, + material_id = prdReport.material_id, + material_code = basMaterial.code, + unit_id = prdReport.unit_id, + barcode = prdReport.barcode, + code_batch = prdReport.barcode+"0001", + quantity = (int)prdReport.reported_qty, + }); + }); + + if (result.IsSuccess) + { + MESCreateInstockInput mesCreateInstockInput = new MESCreateInstockInput(); + mesCreateInstockInput.instock = new MESWmsInstockHInput() + { + org_id = _userManager.GetUserInfo().Result.organizeId, + bill_date = DateTime.Now, + bill_type = DictConst.CHANCHENGPINRUKUDAN, + warehouse_id = basLocation?.wh_id, + source_id = prdInstockH.id, + create_id = _userManager.UserId, + carry_code = prdReport.material_box_code, + location_code = basLocation.location_code, + is_check = 1, + }; + mesCreateInstockInput.instockds = new List(); + mesCreateInstockInput.instockcodes = new List(); + mesCreateInstockInput.instockds.Add(new MESWmsInstockDInput() + { + material_id = prdReport.material_id, + material_code = basMaterial.code, + unit_id = prdReport.unit_id, + code_batch = prdReport.barcode, + pr_qty = (int)prdReport.reported_qty, + }); + + mesCreateInstockInput.instockcodes.Add(new MESWmsInstockCodeInput() + { + material_id = prdReport.material_id, + material_code = basMaterial.code, + unit_id = prdReport.unit_id, + barcode = prdReport.barcode, + code_batch = prdReport.barcode+"0001", + codeqty = (int)prdReport.reported_qty, + }); + string domain = (App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host; + Dictionary header = new Dictionary() + { + ["Authorization"] = App.HttpContext.Request.Headers["Authorization"] + }; + var sendResult = HttpUtils.RequestPost(domain + WebApiConst.MES_CREATE_INSTOCK,JsonConvert.SerializeObject(mesCreateInstockInput),header); + Log.Information(sendResult); + AuthResponse authResponse = JsonConvert.DeserializeObject(sendResult); + if (authResponse.code != 200 || !authResponse.data.ObjToBool()) + { + throw Oops.Bah(authResponse.msg); + } + else + { + result2 = await db.Ado.UseTranAsync(async () => + { + await _repository.InsertAsync(prdInstockH); + + if (prdInstockDs.Count > 0) + { + await db.Insertable(prdInstockDs).ExecuteCommandAsync(); + } + }); + + } + } + + if(!result2.IsSuccess) throw Oops.Oh(ErrorCode.COM1008); + return result2.IsSuccess ? "申请成功" : result2.ErrorMessage; + } } } \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdKittingOutService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdKittingOutService.cs index e94f3915..fd81e5b3 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdKittingOutService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdKittingOutService.cs @@ -8,6 +8,7 @@ using JNPF.Extras.CollectiveOAuth.Utils; using JNPF.FriendlyException; using JNPF.Logging; using JNPF.Systems.Entitys.Permission; +using JNPF.Systems.Entitys.System; using JNPF.Systems.Interfaces.Permission; using JNPF.Systems.Interfaces.System; using JNPF.VisualDev; @@ -23,11 +24,12 @@ using Tnb.ProductionMgr.Entities; using Tnb.ProductionMgr.Interfaces; using Tnb.WarehouseMgr.Entities.Dto.Inputs; using Tnb.ProductionMgr.Entities.Dto; +using Tnb.WarehouseMgr.Entities; namespace Tnb.ProductionMgr { /// - /// 生产领料 + /// 齐套出库 /// [ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)] [Route("api/[area]/[controller]/[action]")] @@ -184,7 +186,6 @@ namespace Tnb.ProductionMgr collocation_scheme_id = kittingOutInput.collocation_scheme_id, collocation_scheme_code = kittingOutInput.collocation_scheme_code, source_id = prdKittingOutH.id, - seq = !string.IsNullOrEmpty(kittingOutInput.seq) ? Convert.ToInt32(kittingOutInput.seq) : 0, create_id = _userManager.UserId, wmsKittingoutDs = new List(), }); @@ -262,5 +263,142 @@ namespace Tnb.ProductionMgr } } + + + /// + /// 齐套出库申请 + /// + /// + /// + /// + [HttpPost] + public async Task KittingOutNew(KittingOutNewInput kittingOutInput) + { + PrdKittingOutH prdKittingOutH = new PrdKittingOutH(); + string warehouse_id = "26103348825381";//二楼缓存仓 + try + { + var db = _repository.AsSugarClient(); + PrdMoTask prdMoTask = await db.Queryable().SingleAsync(x=>x.id==kittingOutInput.mo_task_id); + BasMaterial basMaterial = await db.Queryable().SingleAsync(x=>x.id==prdMoTask.material_id); + WmsCollocationSchemeH wmsCollocationSchemeH = await db.Queryable().SingleAsync(x=>x.id==kittingOutInput.collocation_scheme_id); + List wmsCollocationSchemeDs = await db.Queryable().Where(x=>x.bill_id==kittingOutInput.collocation_scheme_id).ToListAsync(); + List materialIds = wmsCollocationSchemeDs.Select(x => x.material_id).ToList(); + List basMaterials = await db.Queryable().Where(x=>materialIds.Contains(x.id)).ToListAsync(); + Dictionary unitIdDic = await db.Queryable() + .LeftJoin((a, b) => b.EnCode == DictConst.MeasurementUnit) + .LeftJoin((a, b, c) => b.Id == c.DictionaryTypeId && a.unit_id == c.EnCode) + .Where((a,b,c)=>materialIds.Contains(a.id)) + .Select((a, b, c) => new + { + key = a.id, + value = c.Id + }) + .ToDictionaryAsync(x => x.key, x => x.value); + Dictionary unitCodeDic = basMaterials.ToDictionary(x => x.id, x => x.unit_id); + OrganizeEntity workline = await _organizeService.GetAnyParentByWorkstationId(kittingOutInput.workstation_id, DictConst.RegionCategoryWorklineCode); + + List input = new List(); + input.Add(new MESKittingOutStkInput() + { + org_id = _userManager.GetUserInfo().Result.organizeId, + bill_date = DateTime.Now, + warehouse_id = warehouse_id, + location_code = kittingOutInput.location_code, + material_id = prdMoTask.material_id, + material_code = basMaterial.code, + collocation_scheme_id = kittingOutInput.collocation_scheme_id, + collocation_scheme_code = wmsCollocationSchemeH.bill_code, + source_id = prdKittingOutH.id, + create_id = _userManager.UserId, + wmsKittingoutDs = new List(), + }); + + foreach (var item in wmsCollocationSchemeDs) + { + input[0].wmsKittingoutDs.Add(new MESKittingOutStkDInput() + { + material_id = item.material_id, + material_code = item.material_code, + unit_id = unitIdDic.ContainsKey(item.material_id) ? unitIdDic[item.material_id].ToString() : "", + unit_code = unitCodeDic.ContainsKey(item.material_id) ? unitCodeDic[item.material_id].ToString() : "", + pr_qty = item.qty, + code_batch = "", + box = item.box, + }); + } + + string domain = (App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host; + Dictionary header = new Dictionary() + { + ["Authorization"] = App.HttpContext.Request.Headers["Authorization"] + }; + var sendResult = HttpUtils.RequestPost(domain + WebApiConst.MES_KITTING_OUT_STK,JsonConvert.SerializeObject(input),header); + Log.Information(sendResult); + + AuthResponse authResponse = JsonConvert.DeserializeObject(sendResult); + if (authResponse.code != 200) + { + throw Oops.Bah(authResponse.msg); + } + else + { + prdKittingOutH.code = await _billRullService.GetBillNumber(CodeTemplateConst.PRDKITTINGOUTSTOCK_CODE); + prdKittingOutH.warehouse_id = warehouse_id; + prdKittingOutH.location_code = kittingOutInput.location_code; + prdKittingOutH.material_id = basMaterial.id; + prdKittingOutH.material_code = basMaterial.code; + prdKittingOutH.collocation_scheme_id = kittingOutInput.collocation_scheme_id; + prdKittingOutH.collocation_scheme_code = wmsCollocationSchemeH.bill_code; + prdKittingOutH.workline_id = workline?.Id ?? ""; + prdKittingOutH.workstation_id = kittingOutInput.workstation_id; + prdKittingOutH.mo_task_id = kittingOutInput.mo_task_id; + prdKittingOutH.seq = "0"; + prdKittingOutH.create_id = _userManager.UserId; + prdKittingOutH.create_time = DateTime.Now; + prdKittingOutH.org_id = _userManager.GetUserInfo().Result.organizeId; + List prdKittingOutDs = new List(); + foreach (var item in wmsCollocationSchemeDs) + { + prdKittingOutDs.Add(new PrdKittingOutD() + { + material_id = item.material_id, + material_code = item.material_code, + unit_id = unitIdDic.ContainsKey(item.material_id) ? unitIdDic[item.material_id].ToString() : "", + unit_code = unitCodeDic.ContainsKey(item.material_id) ? unitCodeDic[item.material_id].ToString() : "", + pr_qty = item.qty, + code_batch = "", + box = item.box, + kitting_out_id = prdKittingOutH.id, + }); + } + + // VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleId, true); + // await _runService.Create(templateEntity, visualDevModelDataCrInput); + + DbResult result = await _repository.AsSugarClient().Ado.UseTranAsync(async () => + { + await _repository.InsertAsync(prdKittingOutH); + if (prdKittingOutDs.Count > 0) + { + await db.Insertable(prdKittingOutDs).ExecuteCommandAsync(); + } + }); + + if (!result.IsSuccess) + { + throw Oops.Bah(result.ErrorMessage); + } + } + return await Task.FromResult(true); + } + catch (Exception e) + { + Console.WriteLine(e); + Log.Error(e.Message); + throw Oops.Bah(e.Message); + } + + } } } \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs index e04856d5..7f2dea96 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs @@ -2121,7 +2121,7 @@ namespace Tnb.ProductionMgr return await _db.Queryable().Where(it => it.eqp_id == eqpId && it.mo_task_status == DictConst.InProgressEnCode).ToListAsync(); } - + /// /// 计算预计结束日期 /// @@ -2607,6 +2607,70 @@ namespace Tnb.ProductionMgr count = SqlFunc.AggregateCount(c.mo_status) }).ToListAsync(); } + + + /// + /// 获取备料计划 + /// + /// + public async Task GetMaterialPreparationPlan() + { + string now = DateTime.Now.ToString("yyyy-MM-dd"); + var childrenList = await _db.Queryable() + .LeftJoin((a, b) => a.id == b.parent_id) + .LeftJoin((a, b, c) => b.material_id == c.id) + .Where((a, b) => a.schedule_type == 2 && string.IsNullOrEmpty(a.parent_id) && a.estimated_start_date.Value.ToString("yyyy-MM-dd") == now) + .Select((a, b, c) => new MaterialPreparationPlanDOutput + { + mo_task_id = b.id, + mo_task_code = b.mo_task_code, + rate_num = SqlFunc.Subqueryable().Where(o => o.id == a.bom_id) + .OrderByDesc(o => o.create_time).Select(o => o.num), + parent_id = b.parent_id, + material_id = b.material_id, + material_code = c.code, + children = SqlFunc.Subqueryable() + .LeftJoin((x, y) => x.material_id == y.id) + .Where((x, y) => x.mbom_process_id == b.mbom_process_id) + .ToList((x, y) => new MaterialPreparationPlanDDOutput() + { + material_id = x.material_id, + material_code = y.code, + num = x.num + }) + + }).ToListAsync(); + + var prdMoTaskList = await _db.Queryable() + .LeftJoin((a, b) => a.material_id == b.id) + .Where(a => a.schedule_type == 2 && string.IsNullOrEmpty(a.parent_id) && a.estimated_start_date.Value.ToString("yyyy-MM-dd") == now) + .Select((a,b)=>new MaterialPreparationPlanOutput() + { + mo_task_id = a.id, + mo_task_code = a.mo_task_code, + material_id = b.id, + material_code = b.code, + num = a.scheduled_qty, + }) + .ToListAsync(); + + foreach (var item in prdMoTaskList) + { + item.children = childrenList.Where(x => x.parent_id == item.mo_task_id).ToList(); + foreach (var itemChild in item.children) + { + foreach (var itemChildChild in itemChild.children) + { + if (itemChildChild.num > 0 && itemChild.rate_num != null && itemChild.rate_num>0) + { + itemChildChild.num = item.num * itemChildChild.num / itemChild.rate_num; + } + } + } + } + + return prdMoTaskList; + } } diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs index d975fe21..f7751cfd 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdPackReportService.cs @@ -401,13 +401,14 @@ namespace Tnb.ProductionMgr .LeftJoin((a,b,c,d,e,f,g,h,i)=>a.process_id==i.process_id && i.enabled==1) .LeftJoin((a,b,c,d,e,f,g,h,i,j)=>a.mo_id==j.id) .LeftJoin((a,b,c,d,e,f,g,h,i,j,k)=>a.material_id==k.material_id && k.auxiliary_unit_id=="kg") + .LeftJoin((a,b,c,d,e,f,g,h,i,j,k,l)=>a.eqp_id==l.equip_id && l.enabled==1 && l.label_point=="提报装箱称重点位") .Where((a, b) => a.workstation_id == input.stationId && (a.mo_task_status == DictConst.ToBeStartedEnCode || a.mo_task_status == DictConst.MoStatusPauseCode || a.mo_task_status == DictConst.ComplatedEnCode || a.mo_task_status == DictConst.InProgressEnCode) ) .WhereIF(!string.IsNullOrEmpty(mo_task_code),a=>a.mo_task_code.Contains(mo_task_code)) //.WhereIF(!string.IsNullOrEmpty(mo_task_status),a=>a.mo_task_status==mo_task_status) .WhereIF(statusList.Count>0,a=>statusList.Contains(a.mo_task_status)) .WhereIF(status=="3" && start_time!=null,a=>a.act_end_date>=start_time) .WhereIF(status=="3" && end_time!=null,a=>a.act_end_date<=end_time) - .Select((a, b, c, d, e,f,g,h,i,j,k) => new PADPackageTaskPageOutput + .Select((a, b, c, d, e,f,g,h,i,j,k,l) => new PADPackageTaskPageOutput { id = a.id, mo_task_code = a.mo_task_code, @@ -448,6 +449,8 @@ namespace Tnb.ProductionMgr minpacking = b.minpacking, main_num = k.number_of_primary_unit, deputy_num = k.number_of_auxiliary_unit, + third_equip_code = f.third_equip_code, + weight_name = l.label_name }) .MergeTable() .OrderBy($"{input.sidx} {input.sort}") diff --git a/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs b/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs new file mode 100644 index 00000000..2a2150c6 --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr/RedisBackGround.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JNPF.Common.Cache; +using Microsoft.Extensions.Hosting; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; +using UAParser; +using Tnb.ProductionMgr.Interfaces; +using Tnb.ProductionMgr.Entities.Dto; + +namespace Tnb.ProductionMgr +{ + //redis定时获取数采数据 + public class RedisBackGround : IHostedService, IDisposable + { + private Timer? packtimer; + private Timer? limittimer; + private readonly RedisCache _redisCache; + private readonly IPrdInstockService _prdInstockService; + public RedisBackGround(RedisCache redisCache, IPrdInstockService prdInstockService) + { + _redisCache = redisCache; + _prdInstockService = prdInstockService; + } + //获取装箱状态 + private void GetPackStatus(object state) + { + Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); + Console.WriteLine($"获取装箱状态"); + /* + var data = _redisCache.GetHash("TY4C-JICHU", "weight_4").Result; + var res = JsonConvert.DeserializeObject(data); + if (res != null && res["Value"] != null) + { + InstockInput instockInput = new InstockInput(); + instockInput.equip_code = res["Value"]!.ToString(); + _prdInstockService.InstockTypeOne(instockInput); + Console.WriteLine(decimal.Parse(res["Value"]!.ToString())); + }*/ + } + //获取限位状态 + private void GetLimitStatus(object state) + { + Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); + Console.WriteLine($"获取限位状态"); + /* + var data = _redisCache.GetHash("TY4C-JICHU", "weight_4").Result; + var res = JsonConvert.DeserializeObject(data); + if (res != null && res["Value"] != null) + { + InstockInput instockInput = new InstockInput(); + instockInput.equip_code = res["Value"]!.ToString(); + _prdInstockService.InstockTypeOne(instockInput); + Console.WriteLine(decimal.Parse(res["Value"]!.ToString())); + }*/ + } + public void Dispose() + { + packtimer?.Dispose(); + limittimer?.Dispose(); + } + public Task StartAsync(CancellationToken cancellationToken) + { + // packtimer = new Timer(GetPackStatus, null, TimeSpan.Zero, TimeSpan.FromSeconds(2)); + // limittimer = new Timer(GetLimitStatus, null, TimeSpan.Zero, TimeSpan.FromSeconds(2)); + return Task.CompletedTask; + } + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + } +} \ No newline at end of file diff --git a/ProductionMgr/Tnb.ProductionMgr/RedisDataService.cs b/ProductionMgr/Tnb.ProductionMgr/RedisDataService.cs new file mode 100644 index 00000000..d9ea93f4 --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr/RedisDataService.cs @@ -0,0 +1,67 @@ +using System.Collections; +using JNPF.Common.Cache; +using JNPF.Common.Extension; +using JNPF.Common.Manager; +using JNPF.DependencyInjection; +using JNPF.DynamicApiController; +using JNPF.FriendlyException; +using JNPF.TaskScheduler; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Tnb.ProductionMgr.Interfaces; + +namespace Tnb.ProductionMgr +{ + /// + /// 数据采集 + /// + [ApiDescriptionSettings(Tag = ModuleConst.Tag, Area = ModuleConst.Area, Order = 700)] + [Route("api/[area]/[controller]/[action]")] + public class RedisDataService: IRedisDataService, IDynamicApiController, ITransient + { + private readonly RedisCache _redisCache; + public RedisDataService(RedisCache redisCache) + { + _redisCache = redisCache; + + } + /// + /// 根据机号获取重量 + /// + [HttpPost] + public async Task GetWeight(string device, string jihao) + { + /* + var dic = _redisCache.HGetAll("TY4C-ZHUSU1"); + string a= "weighCall_7&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_7\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_4&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_4\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_6&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_6\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_2&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_2\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_5&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_5\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_11&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_11\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_1&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_1\",\"StatusCode\":0,\"Value\":1.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:31:03\"}$weight_12&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_12\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_11&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_11\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_9&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_9\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_4&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_4\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_7&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_7\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_14&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_14\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_7&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_7\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_10&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_10\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_1&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_1\",\"StatusCode\":0,\"Value\":true,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:10:51\"}$weighDone_12&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_12\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_14&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_14\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_14&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_14\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_11&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_11\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_5&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_5\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_9&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_9\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_13&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_13\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_8&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_8\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_2&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_2\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_2&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_2\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_8&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_8\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_3&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_3\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_14&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_14\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_9&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_9\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_7&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_7\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_3&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_3\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_8&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_8\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_1&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_1\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_12&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_12\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_4&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_4\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_1&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_1\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_6&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_6\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_2&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_2\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_3&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_3\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_10&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_10\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_10&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_10\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_13&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_13\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$State&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"State\",\"StatusCode\":0,\"Value\":\"OK\",\"TagValueType\":\"Unkown\",\"TimeStamp\":\"2023-11-02 11:14:28\"}$weighCall_12&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_12\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_6&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_6\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_13&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_13\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_10&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_10\",\"StatusCode\":0,\"Value\":33.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 10:19:44\"}$weighDone_11&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_11\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_9&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_9\",\"StatusCode\":0,\"Value\":11.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 10:15:26\"}$weight_8&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_8\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_4&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_4\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighCall_6&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighCall_6\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_5&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_5\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weighDone_5&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weighDone_5\",\"StatusCode\":0,\"Value\":false,\"TagValueType\":\"Bit\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weightSum_13&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weightSum_13\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$weight_3&{\"DevName\":\"TY4C-ZHUSU1\",\"TagName\":\"weight_3\",\"StatusCode\":0,\"Value\":0.0,\"TagValueType\":\"Float\",\"TimeStamp\":\"2023-11-03 09:09:02\"}$"; + foreach (var kvp in dic) + { + a += kvp.Key + "&" + kvp.Value + "$"; + } + var ss= a.Split('$', StringSplitOptions.RemoveEmptyEntries); + foreach (var s in ss) + { + var b = s.Split('&'); + _redisCache.HSet("TY4C-ZHUSU1", b[0], b[1]); + } + */ + decimal result = 0; + bool flag = await _redisCache.HashExist(device, jihao); + if (!flag) + throw Oops.Bah("没有找到" + device + "----" + jihao + "的数据"); + var data = await _redisCache.GetHash(device, jihao); + var res = JsonConvert.DeserializeObject(data); + if (res != null && res["Value"] != null) + { + result = decimal.Parse(res["Value"]!.ToString()); + } + else + { + throw Oops.Bah("数据格式错误"); + } + return result; + } + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESKittingOutStkInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESKittingOutStkInput.cs index ec0f52d8..c93af439 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESKittingOutStkInput.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/MESKittingOutStkInput.cs @@ -81,11 +81,6 @@ namespace Tnb.WarehouseMgr.Entities.Dto.Inputs /// public string source_code { get; set; } - /// - /// 顺序号 - /// - public int seq { get; set; } - /// /// 创建用户ID /// diff --git a/apihost/Tnb.API.Entry/Configurations/App.json b/apihost/Tnb.API.Entry/Configurations/App.json index 2610456e..136f83e5 100644 --- a/apihost/Tnb.API.Entry/Configurations/App.json +++ b/apihost/Tnb.API.Entry/Configurations/App.json @@ -71,7 +71,8 @@ "txt", "rar", "zip", - "csv" + "csv", + "json" ], //过滤上传文件名称特殊字符 "SpecialString": [ @@ -188,5 +189,5 @@ "DoMainApp": "http://localhost:8081", // 前端App外网能访问的地址(域名), 回调的时候拼接接口地址用 "AppPushUrl": "https://8e84eea8-6922-4033-8e86-67ad7442e692.bspapp.com/unipush" }, - "IsStartTimeJob": true //是否开启定时任务 + "IsStartTimeJob": false //是否开启定时任务 } \ No newline at end of file diff --git a/apihost/Tnb.API.Entry/Startup.cs b/apihost/Tnb.API.Entry/Startup.cs index 07ba27d3..f517e4d4 100644 --- a/apihost/Tnb.API.Entry/Startup.cs +++ b/apihost/Tnb.API.Entry/Startup.cs @@ -23,6 +23,7 @@ using Senparc.Weixin; using Senparc.Weixin.Entities; using Senparc.Weixin.RegisterServices; using SqlSugar; +using Tnb.ProductionMgr; using Tnb.WarehouseMgr; namespace JNPF.API.Entry; @@ -66,7 +67,7 @@ public class Startup : AppStartup //定时任务 services.AddHostedService(); - + services.AddHostedService(); } diff --git a/common/Tnb.Common/Cache/RedisCache.cs b/common/Tnb.Common/Cache/RedisCache.cs index 5cebbd3d..a57fe0c5 100644 --- a/common/Tnb.Common/Cache/RedisCache.cs +++ b/common/Tnb.Common/Cache/RedisCache.cs @@ -224,4 +224,20 @@ public class RedisCache : ICache, ISingleton long second = RedisHelper.PTtl(key); return DateTime.Now.AddMilliseconds(second); } + public Task GetHash(string key, string field) + { + return RedisHelper.HGetAsync(key, field); + } + public Task HashExist(string key, string field) + { + return RedisHelper.HExistsAsync(key, field); + } + public Task> HGetAll(string key) + { + return RedisHelper.HGetAllAsync(key); + } + public Task HSet(string key, string field, string value) + { + return RedisHelper.HSetAsync(key, field,value); + } } \ No newline at end of file diff --git a/common/Tnb.Common/Extension/TnbStringExtensions.cs b/common/Tnb.Common/Extension/TnbStringExtensions.cs index e8436ddb..8be6669e 100644 --- a/common/Tnb.Common/Extension/TnbStringExtensions.cs +++ b/common/Tnb.Common/Extension/TnbStringExtensions.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using JNPF.Common.Extension; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace System; @@ -183,4 +184,17 @@ public static class StringExtensions public static string ToCamel(this string str) => str.SplitWord().Select((a, i) => i == 0 ? a : a.UpperFirst()).JoinAsString(""); #endregion + + public static (string, string) LastSplit(this string str, char seperate) + { + int n = str.LastIndexOf(seperate); + if(n > 0) + { + return (str.Substring(0, n), str.Substring(n + 1)); + } + else + { + return (str, null); + } + } } \ No newline at end of file diff --git a/visualdev/Tnb.Vengine/DataAccess/DataAccess.cs b/visualdev/Tnb.Vengine/DataAccess/DataAccess.cs index 79b070ca..22299cdb 100644 --- a/visualdev/Tnb.Vengine/DataAccess/DataAccess.cs +++ b/visualdev/Tnb.Vengine/DataAccess/DataAccess.cs @@ -1,6 +1,8 @@ using System.Collections.Concurrent; +using System.Security.Cryptography.Xml; using JNPF; using JNPF.Common.Core.Manager; +using JNPF.Common.Extension; using JNPF.DependencyInjection; using Microsoft.Extensions.Configuration; using SqlSugar; @@ -15,7 +17,7 @@ namespace Tnb.Vengine.DataAccess; public class DataAccess : IDataAccess, ITransient, IDisposable { private const int MAX_PAGE_SIZE = 1000; - private ISqlSugarClient? _db; + private static ISqlSugarClient? _db; protected ISqlSugarClient Db { @@ -170,14 +172,18 @@ public class DataAccess : IDataAccess, ITransient, IDisposable private async Task LoadVmodelNavigateAsync(Vmodel vm) { Dictionary dictVm = new(); + var vmids = vm.navProps.Select(a => a.vmid).Distinct().ToList(); + var ls = await Db.Queryable().Where(a => vmids.Contains(a.id)).ToListAsync(); + var navs = ls.ToDictionary(a => a.id); foreach (var navProp in vm.navProps) { - if (!dictVm.ContainsKey(navProp.vmid)) - { - var navModel = await GetVmodelAsync(navProp.vmid); - dictVm.Add(navProp.vmid, navModel); - } - navProp.naviModel = dictVm[navProp.vmid]; + navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid); + //if (!dictVm.ContainsKey(navProp.vmid)) + //{ + // var navModel = await GetVmodelAsync(navProp.vmid); + // dictVm.Add(navProp.vmid, navModel); + //} + //navProp.naviModel = dictVm[navProp.vmid]; } } @@ -191,10 +197,8 @@ public class DataAccess : IDataAccess, ITransient, IDisposable var selProps = vm.GetVmSelectProps(input.o); //处理导航属性联表 List joins = vm.GetJoinInfos(selProps); - query.AddJoinInfo(joins); //if (joins.Count > 0) - //{ - //} + query.AddJoinInfo(joins); List wheres = vm.GetConditionalModels(input.q); if (!string.IsNullOrEmpty(input.k)) { @@ -208,10 +212,8 @@ public class DataAccess : IDataAccess, ITransient, IDisposable wheres.Add(new ConditionalCollections() { ConditionalList = lsCondition }); } //处理查询参数 - query.Where(wheres); //if (wheres.Count > 0) - //{ - //} + query.Where(wheres); if (!string.IsNullOrEmpty(input.sort)) { query.OrderBy(input.sort); @@ -229,7 +231,7 @@ public class DataAccess : IDataAccess, ITransient, IDisposable //组装输出对象 foreach (var data in ls) { - DObject ret = await NestedOutputAsync(vm, new DObject(data), selProps); + DObject ret = await CombineOutputAsync(vm, new DObject(data), selProps); result.items.Add(ret); } @@ -243,11 +245,12 @@ public class DataAccess : IDataAccess, ITransient, IDisposable /// /// /// - private async Task NestedOutputAsync(Vmodel vm, DObject src, List selProps) + private async Task CombineOutputAsync(Vmodel vm, DObject src, List selProps) { DObject ret = new(); foreach (var prop in selProps) { + // 加载主表字段 if (prop.navType == eNavigateType.None || prop.navCode == VmSelectProp.MAIN_ALIES) { if (src.ContainsKey(prop.code)) @@ -257,40 +260,14 @@ public class DataAccess : IDataAccess, ITransient, IDisposable } else { + // 加载关联表字段 if (prop.navType == eNavigateType.OneToOne) { - //以 nav_prop的形式返回 - var key = prop.navCode + "_" + prop.code; - ret.Add(key, src[key]); - //以 nav.prop的形式返回 - //if (!ret.ContainsKey(prop.navCode)) - //{ - // ret.Add(prop.navCode, new DObject()); - //} - //var key = prop.navCode + "_" + prop.code; - //if (src.ContainsKey(key)) - //{ - // ((DObject)ret[prop.navCode]).Add(prop.code, src[key]); - //} + NestedOutput(vm, src, ret, prop); } else if (prop.navType == eNavigateType.OneToMany) { - if (!ret.ContainsKey(prop.navCode)) - { - ret.Add(prop.navCode, new List()); - } - var navProp = vm.navProps.First(a => a.code == prop.navCode); - if (navProp != null && navProp.naviModel != null && src.ContainsKey(navProp.refField)) - { - VmListInput input = new VmListInput(); - var fkProp = navProp.naviModel.FieldCodeToPropCode(navProp.fkField); - if (!string.IsNullOrEmpty(fkProp)) - { - input.q = new DObject(fkProp, src[navProp.refField]); - input.o = string.Join(',', selProps.Where(a => a.navCode == prop.navCode).Select(a => a.code)); - ret[prop.navCode] = (await QueryDataAsync(navProp.naviModel, input)).items; - } - } + await NestedOneToManyAsync(vm, src, ret, prop, selProps); } else if (prop.navType == eNavigateType.ManyToMany) { @@ -304,6 +281,50 @@ public class DataAccess : IDataAccess, ITransient, IDisposable return ret; } + /// + /// 将一对一的关联表字段嵌入到返回值中 + /// + private void NestedOutput(Vmodel vm, DObject src, DObject ret, VmSelectProp prop) + { + // 以 nav_prop的形式返回 + var key = prop.navCode + "_" + prop.code; + ret.Add(key, src[key]); + // 以 nav.prop的形式返回 + //if (!ret.ContainsKey(prop.navCode)) + //{ + // ret.Add(prop.navCode, new DObject()); + //} + //var key = prop.navCode + "_" + prop.code; + //if (src.ContainsKey(key)) + //{ + // ((DObject)ret[prop.navCode]).Add(prop.code, src[key]); + //} + } + + private async Task NestedOneToManyAsync(Vmodel vm, DObject src, DObject ret, VmSelectProp prop, List selProps) + { + // 在返回值中增加导航属性 + if (ret.ContainsKey(prop.navCode)) + { + return; + } + ret.Add(prop.navCode, new List()); + + // 找到导航属性的配置 + var navCfg = vm.navProps.First(a => a.code == prop.navCode); + if (navCfg != null && navCfg.naviModel != null && src.ContainsKey(navCfg.refField) && navCfg.refCode == VmSelectProp.MAIN_ALIES) + { + VmListInput input = new VmListInput(); + var fkProp = navCfg.naviModel.FieldCodeToPropCode(navCfg.fkField); + if (!string.IsNullOrEmpty(fkProp)) + { + input.q = new DObject(fkProp, src[navCfg.refField]); + input.o = string.Join(',', selProps.Where(a => a.navCode == prop.navCode).Select(a => a.code)); + ret[prop.navCode] = (await QueryDataAsync(navCfg.naviModel, input)).items; + } + } + } + /// /// 新增数据 默认方法 /// diff --git a/visualdev/Tnb.Vengine/Domain/OutputParser.cs b/visualdev/Tnb.Vengine/Domain/OutputParser.cs new file mode 100644 index 00000000..2a90c0b9 --- /dev/null +++ b/visualdev/Tnb.Vengine/Domain/OutputParser.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JNPF.Common.Extension; +using Tnb.Vengine.DataAccess; + +namespace Tnb.Vengine.Domain +{ + public class OutputParser + { + private readonly IDataAccess _dataAccess; + private readonly Vmodel _root; + private List _outputs; + private Dictionary _selectProps = new Dictionary(); + private Dictionary _navModels = new Dictionary(); + public OutputParser(IDataAccess dataAccess, Vmodel rootModel, string output) + { + _dataAccess = dataAccess; + _root = rootModel; + _outputs = output.Split(',').Distinct().ToList(); + ParseOutputStr(); + } + /// + /// 按模型组织要输出的属性 + /// + private void ParseOutputStr() + { + foreach (var outStr in _outputs) + { + if (string.IsNullOrWhiteSpace(outStr)) + { + continue; + } + string vmPath; + int n = outStr.LastIndexOf('.'); + if (n < 1) + { + vmPath = Vmodel.MAIN_ALIES; + } + else + { + vmPath = outStr.Substring(0, n); + } + if (!_selectProps.ContainsKey(vmPath)) + { + _selectProps.Add(vmPath, new OutputSelect { navPaths = vmPath.Split(',').ToList(), vmPath = vmPath }); + } + var outSelect = _selectProps[vmPath]; + outSelect.propCodes.Add(outStr.Substring(n + 1)); + } + } + + private async Task LoadNavModel() + { + var navProps = _root.navProps.Where(a => _selectProps.Values.Any(b => b.vmPath.StartsWith(a.code + "."))).ToList(); + await LoadVmodelNavigateAsync(navProps); + } + private async Task LoadVmodelNavigateAsync(List navProps) + { + var db = _dataAccess.GetSqlSugar(); + + var vmids = navProps.Select(a => a.vmid).Distinct().ToList(); + var navs = await db.Queryable().Where(a => vmids.Contains(a.id)).ToDictionaryAsync(a => a.id, a => a); + foreach (var navProp in navProps) + { + navProp.naviModel = (Vmodel)navs.GetOrDefault(navProp.vmid); + navProp.naviModel.navProps.Where(a => _selectProps.Values.Any(b => b.vmPath.StartsWith(a.code + "."))).ToList(); + } + } + + } + + internal class OutputSelect + { + public string vmId { get; set; } = string.Empty; + public string vmCode { get; set; } = string.Empty; + public string vmPath { get; set; } = string.Empty; + public eNavigateType navType { get; set; } = eNavigateType.None; + public List navPaths { get; set; } = new List(); + + public List propCodes { get; set; } = new List(); + public List fieldCodes { get; set; } = new List(); + + public OutputSelect() + { + + } + public OutputSelect(Vmodel model) + { + vmId = model.id; + vmCode = model.vmCode; + vmPath = Vmodel.MAIN_ALIES; + } + } +} diff --git a/visualdev/Tnb.Vengine/Domain/VengineDto.cs b/visualdev/Tnb.Vengine/Domain/VengineDto.cs index d1d441bf..f83b61a9 100644 --- a/visualdev/Tnb.Vengine/Domain/VengineDto.cs +++ b/visualdev/Tnb.Vengine/Domain/VengineDto.cs @@ -164,6 +164,7 @@ public class VmSelectProp public const string MAIN_ALIES = "m"; public string code { get; set; } = string.Empty; public string field { get; set; } = string.Empty; + public List navPath { get; set; } = new List(); public string navCode { get; set; } = MAIN_ALIES; public ePropType propType { get; set; } public eNavigateType navType { get; set; } diff --git a/visualdev/Tnb.Vengine/Domain/VmDbProp.cs b/visualdev/Tnb.Vengine/Domain/VmDbProp.cs index c654a1f3..b985f776 100644 --- a/visualdev/Tnb.Vengine/Domain/VmDbProp.cs +++ b/visualdev/Tnb.Vengine/Domain/VmDbProp.cs @@ -111,7 +111,7 @@ public class VmDbProp : VmBaseProp /// 获取默认值文本 /// /// - public object? GetDefaultValueString() + public string? GetDefaultValueString() { string val = ""; if (!required) return val; diff --git a/visualdev/Tnb.Vengine/Domain/Vmodel.cs b/visualdev/Tnb.Vengine/Domain/Vmodel.cs index 9c5fb6cb..89b0d03f 100644 --- a/visualdev/Tnb.Vengine/Domain/Vmodel.cs +++ b/visualdev/Tnb.Vengine/Domain/Vmodel.cs @@ -23,6 +23,8 @@ namespace Tnb.Vengine.Domain; [SugarTable("sys_vmodel")] public partial class Vmodel : Entity { + public const string MAIN_ALIES = "m"; + #region Properties /// @@ -146,7 +148,8 @@ public partial class Vmodel : Entity } #endregion Properties - + //private Dictionary? _mapField2Prop = null; + //private Dictionary? _mapProp2Field = null; /// /// 通过实体创建模型 /// @@ -351,11 +354,30 @@ public partial class Vmodel : Entity if (filter == null) return wheres; foreach (var item in filter) { + VmDbProp? prop = null; // TODO 按子表条件查询 if (item.Key.Contains(".")) { + var codes = item.Key.Split('.'); + if (codes.Length >= 2) + { + var navProp = navProps.FirstOrDefault(a => a.code == codes[0]); + if (navProp != null && navProp.naviModel != null) + { + var dbProp = navProp.naviModel.dbProps.FirstOrDefault(a => a.code == codes[1]); + if (dbProp != null) + { + prop = new VmDbProp(); + prop.field = codes[0] + "." + dbProp.field; + prop.csType = dbProp.csType; + } + } + } + } + else + { + prop = dbProps.FirstOrDefault(a => a.code == item.Key); } - var prop = dbProps.FirstOrDefault(a => a.code == item.Key); if (prop == null) continue; if (item.Value is JArray val) {