From b53e5f7552c99becaba5daa09318d9d37bd0dfa9 Mon Sep 17 00:00:00 2001 From: liuyunfeng Date: Thu, 11 Jul 2024 15:55:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=A7=E8=A1=8C=E8=B6=85?= =?UTF-8?q?=E6=97=B6bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Commons/CommonHelper.cs | 38 ++++++ .../SplitPackings/SplitPackingRecManager.cs | 123 ++++++++++++------ 2 files changed, 120 insertions(+), 41 deletions(-) diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Commons/CommonHelper.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Commons/CommonHelper.cs index ade4d7ddb..5b709e4d7 100644 --- a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Commons/CommonHelper.cs +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Commons/CommonHelper.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; @@ -36,5 +37,42 @@ public sealed class CommonHelper return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } } +} +/// +/// Expression动态拼接+泛型缓存 +/// +/// +/// +public class ExpressionGenericMapper//Mapper`2 +{ + private static Func _FUNC = null; + static ExpressionGenericMapper() + { + ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p"); + List memberBindingList = new List(); + foreach (var item in typeof(TOut).GetProperties()) + { + MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name)); + MemberBinding memberBinding = Expression.Bind(item, property); + memberBindingList.Add(memberBinding); + } + foreach (var item in typeof(TOut).GetFields()) + { + MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name)); + MemberBinding memberBinding = Expression.Bind(item, property); + memberBindingList.Add(memberBinding); + } + MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); + Expression> lambda = Expression.Lambda>(memberInitExpression, new ParameterExpression[] + { + parameterExpression + }); + _FUNC = lambda.Compile();//拼装是一次性的 + } + public static TOut Trans(TIn t) + { + return _FUNC(t); + } } + diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/SplitPackings/SplitPackingRecManager.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/SplitPackings/SplitPackingRecManager.cs index bd72af6e8..e47c930ec 100644 --- a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/SplitPackings/SplitPackingRecManager.cs +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/SplitPackings/SplitPackingRecManager.cs @@ -25,9 +25,9 @@ public class SplitPackingRecManager : DomainService, ISplitPackingRecManager public async Task BatchInsertAsync(List input) { + #region 校验 foreach (SplitPackingRec item in input) { - #region 校验 if (item.OprType == OprTypeEnum.SplitBox || item.OprType == OprTypeEnum.MergeBox) //拆箱或合箱 { if (item.FromPackingCode == item.ToPackingCode) @@ -42,18 +42,26 @@ public class SplitPackingRecManager : DomainService, ISplitPackingRecManager throw new UserFriendlyException("操作类型不是拆箱或合箱状态,源箱码和目标箱码必须相同!"); } } - #endregion } - + #endregion + //缓存数据 var query = await _repository.GetQueryableAsync().ConfigureAwait(false); + var fromPackCodeLst = input.Select(itm => itm.FromPackingCode).ToList(); + var toPackCodeLst = input.Select(itm => itm.ToPackingCode).ToList(); + var historyLst = await query.Where(itm => fromPackCodeLst.Contains(itm.ToPackingCode) && (itm.OprType == OprTypeEnum.SplitBox || itm.OprType == OprTypeEnum.MergeBox)).ToListAsync().ConfigureAwait(false); //取顶级箱码时用到 + var hisLst2 = await query.Where(itm => fromPackCodeLst.Contains(itm.FromPackingCode)).ToListAsync().ConfigureAwait(false); + Dictionary hisLst3 = await query.Where(itm => toPackCodeLst.Contains(itm.FromPackingCode) && itm.OprType == OprTypeEnum.Other).ToDictionaryAsync(itm => itm.FromPackingCode, it2 => it2).ConfigureAwait(false); + + //遍历、批量插入 + List operLst = new List(); foreach (SplitPackingRec item in input) { if (item.OprType == OprTypeEnum.SplitBox || item.OprType == OprTypeEnum.MergeBox) { //设置顶级箱码 - item.FromTopPackingCode = CalcuTopPackingCode(query, item.FromPackingCode); - item.ToTopPackingCode = CalcuTopPackingCode(query, item.FromPackingCode); //ToPackingCode + item.FromTopPackingCode = CalcuTopPackingCode(input, historyLst, item); + item.ToTopPackingCode = CalcuTopPackingCode(input, historyLst, item); if (item.FromTopPackingCode.IsNullOrEmpty()) { item.FromTopPackingCode = item.FromPackingCode; @@ -63,14 +71,12 @@ public class SplitPackingRecManager : DomainService, ISplitPackingRecManager item.ToTopPackingCode = item.FromTopPackingCode; } //设置六个单据号 - SetBillNumber(query, item); + SetBillNumber(hisLst2, item); //拆箱时,如果目标箱不存在,插入目标箱(两个箱码相同) - string toPackCode = item.ToPackingCode; - var toHis = await query.Where(itm => itm.FromPackingCode == toPackCode && itm.ToPackingCode == toPackCode).OrderBy(itm => itm.CreationTime).FirstOrDefaultAsync().ConfigureAwait(false); - if (toHis == null) + if (hisLst3.ContainsKey(item.ToPackingCode) == false) { - - SplitPackingRec newObj = CommonHelper.CloneObj(item); + //SplitPackingRec newObj = CommonHelper.CloneObj(item); + SplitPackingRec newObj = ExpressionGenericMapper.Trans(item); newObj.SetId(GuidGenerator.Create()); newObj.OprType = OprTypeEnum.Other; newObj.FromPackingCode = newObj.ToPackingCode; //克隆赋值 @@ -79,11 +85,20 @@ public class SplitPackingRecManager : DomainService, ISplitPackingRecManager newObj.FromUom = newObj.ToUom; newObj.FromQty = newObj.ToQty; newObj.FromLot = newObj.ToLot; - var res = await _repository.InsertAsync(newObj, false).ConfigureAwait(false); + //var res = await _repository.InsertAsync(newObj, false).ConfigureAwait(false); + operLst.Add(newObj); } - SplitPackingRec newEntity = CommonHelper.CloneObj(item); + //var toHis = await query.Where(itm => itm.FromPackingCode == toPackCode && itm.ToPackingCode == toPackCode).OrderBy(itm => itm.CreationTime).FirstOrDefaultAsync().ConfigureAwait(false); + //if (toHis == null) + //{ + //} + //SplitPackingRec newEntity = CommonHelper.CloneObj(item); + SplitPackingRec newEntity = ExpressionGenericMapper.Trans(item); + newEntity.SetId(GuidGenerator.Create()); - var ret = await _repository.InsertAsync(newEntity, false).ConfigureAwait(false); + // var ret = await _repository.InsertAsync(newEntity, false).ConfigureAwait(false); + operLst.Add(newEntity); + } else { @@ -95,11 +110,14 @@ public class SplitPackingRecManager : DomainService, ISplitPackingRecManager { item.ToTopPackingCode = item.FromPackingCode;// ToPackingCode; } - SplitPackingRec newEntity = CommonHelper.CloneObj(item); + //SplitPackingRec newEntity = CommonHelper.CloneObj(item); + SplitPackingRec newEntity = ExpressionGenericMapper.Trans(item); newEntity.SetId(GuidGenerator.Create()); - var ret = await _repository.InsertAsync(newEntity, false).ConfigureAwait(false); + //var ret = await _repository.InsertAsync(newEntity, false).ConfigureAwait(false); + operLst.Add(newEntity); } } //foreach + await _repository.InsertManyAsync(operLst).ConfigureAwait(false); return true; } @@ -203,48 +221,71 @@ public class SplitPackingRecManager : DomainService, ISplitPackingRecManager } /// - /// 取顶级箱码 + /// 取顶级箱码: /// - /// 箱码历史 - /// 箱码,from to时都传入from + /// 本次操作要插入的拆箱记录列表,位于内存中 + /// 数据库中的历史数据:拆箱或合箱、to箱码=内存中的from箱码 + /// 内存中当前记录 /// - private static string CalcuTopPackingCode(IQueryable historyQuery, string packingCode) + private static string CalcuTopPackingCode(List memoryInput, List historyLst, SplitPackingRec curRecord) { - var qry = historyQuery.Where(itm => itm.OprType == OprTypeEnum.SplitBox || itm.OprType == OprTypeEnum.MergeBox); - string ret = null; - SplitPackingRec? firstObj = null; - string toCode = packingCode; + //根据当前记录在内存列表中递归取得最上级拆箱记录:1-2 2-3 3-4 根据3-4能取到1-2 + SplitPackingRec priorMemoryRecord = curRecord; while (1 == 1) { - firstObj = qry.FirstOrDefault(itm => itm.ToPackingCode == toCode); - if (firstObj == null) + var obj = memoryInput.FirstOrDefault(itm => itm.ToPackingCode == priorMemoryRecord.FromPackingCode); + if (obj != null) { - ret = toCode; - break; + priorMemoryRecord = obj; } else { - toCode = firstObj.FromPackingCode; + break; } } - return ret; - //var historyRec = historyQuery.Where(itm => itm.FromPackingCode == packingCode).OrderBy(itm => itm.CreationTime).FirstOrDefault(); - //if (historyRec != null) - //{ - // return historyRec.FromTopPackingCode; - //} - //else + /* + 算法:根据当前记录的from箱码在数据库中取上级拆箱记录,并返回顶级箱码 + 前提:只查找拆箱、合箱记录 + 1-1 + 2-2 + 1-2 查询to箱码=1的(没有,顶级箱码=from箱码) + 3-3 + 2-3 查询 to箱码=2的(找到1-2记录,取顶级箱码字段) + 4-4 + 3-4 查询to箱码=3的(找到2-3记录,取顶级箱码字段) + 5-5 + 3-5 查询to箱码=3的(找到2-3记录,取顶级箱码字段) + */ + var hisObj = historyLst.FirstOrDefault(itm => itm.ToPackingCode == priorMemoryRecord.FromPackingCode); + if (hisObj != null) + { + return hisObj.FromTopPackingCode; + } + else + { + return priorMemoryRecord.FromPackingCode; + } + //var qry = historyLst.Where(itm => itm.OprType == OprTypeEnum.SplitBox || itm.OprType == OprTypeEnum.MergeBox); + //string ret = null; + //SplitPackingRec? firstObj = null; + //string toCode = priorRecord.FromPackingCode; + //while (1 == 1) //{ - // historyRec = historyQuery.Where(itm => itm.ToPackingCode == packingCode).OrderBy(itm => itm.CreationTime).FirstOrDefault(); - // if (historyRec != null) + // firstObj = qry.FirstOrDefault(itm => itm.ToPackingCode == toCode); + // if (firstObj == null) + // { + // ret = toCode; + // break; + // } + // else // { - // return historyRec.ToTopPackingCode; + // toCode = firstObj.FromPackingCode; // } //} - //return null; + //return ret; } - private static void SetBillNumber(IQueryable historyQuery, SplitPackingRec obj) + private static void SetBillNumber(List historyQuery, SplitPackingRec obj) { var historyRec = historyQuery.Where(itm => itm.FromPackingCode == obj.FromPackingCode).OrderBy(itm => itm.CreationTime).FirstOrDefault(); if (historyRec != null)