123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Reflection;
- using System.Linq.Expressions;
- using System.Collections;
- namespace MRMS.Utility
- {
- public static class OperateSerialNo
- {
- public static System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("[^0-9]");
- /// <summary>
- /// 卡序列号加减运算(减操作时,参数addNum为负数)
- /// </summary>
- /// <param name="cardSerialNo"></param>
- /// <param name="AddNum"></param>
- /// <param name="needAlign">返回值是否需要原来的运算值的位长对齐(主要用于减的情况和包装连操作)</param>
- /// <returns></returns>
- ///
- public static string CardSerialNoAddNum(string cardSerialNo, int addNum, bool needAlign=true)
- {
- if ((string.IsNullOrWhiteSpace(cardSerialNo)))
- {
- cardSerialNo = "0";
- }
- cardSerialNo = cardSerialNo.Trim();
- string getCardSerialNo = cardSerialNo;
- if (addNum == 0)
- {
- return getCardSerialNo;
- }
- if (IsNumber(cardSerialNo))
- {
- getCardSerialNo = IsNumberStrValueAddNum(cardSerialNo, addNum, needAlign);
- }
- else
- { //包含有非数字字符,出现频率较小,对此要分开处理。
- //记录 cardSerialNo 中的各个非数字字母和位置。
- notNumLetterAndPlace[] supplyInfor = getstrValueNotNumPart(cardSerialNo);
- cardSerialNo = regex.Replace(cardSerialNo, "");
- getCardSerialNo = IsNumberStrValueAddNum(cardSerialNo, addNum, needAlign);
- //对getCardSerialNo补加cardSerialNo 中的各个非数字字母。
- getCardSerialNo = supplyStrValueNotNumPar(getCardSerialNo, supplyInfor);
- }
- return getCardSerialNo;
- }
- /// <summary>
- /// 得到起止序列号之间的卡数量,包括起止序列号卡本身。
- /// </summary>
- /// <param name="serialNoBegin"></param>
- /// <param name="serialNoEnd"></param>
- /// <returns>没意义的或异常的数值运算将返回 -1</returns>
- public static int CardSerialNoContainNum(string serialNoBegin, string serialNoEnd)
- {
- int containNum = 1;
- if (string.IsNullOrWhiteSpace(serialNoBegin))
- {
- serialNoBegin = "0";
- }
- if (string.IsNullOrWhiteSpace(serialNoEnd))
- {
- serialNoEnd = "0";
- }
- serialNoBegin = serialNoBegin.Trim().ToLower();
- serialNoEnd = serialNoEnd.Trim().ToLower();
- //added by belyn 当票据的可用起止序列号都为0代表用完了
- if (serialNoBegin == "0" && serialNoEnd == "0")
- {
- return 0;
- }
- if (serialNoBegin == serialNoEnd)
- {
- containNum = 1;
- return containNum;
- }
- if (IsNumber(serialNoBegin) && IsNumber(serialNoEnd))
- {
- containNum = IsNumberStrValueCardSerialNoContainNum(serialNoBegin, serialNoEnd);
- }
- else
- { //包含有非数字字符,出现频率较小,对此要分开处理。
- serialNoBegin = regex.Replace(serialNoBegin, "");
- serialNoEnd = regex.Replace(serialNoEnd, "");
-
- containNum = IsNumberStrValueCardSerialNoContainNum(serialNoBegin, serialNoEnd);
- }
- return containNum;
- }
- /// <summary>
- /// 将两个序列号拆分成序列号数组
- /// </summary>
- /// <param name="serialNoBegin"></param>
- /// <param name="serialNoEnd"></param>
- /// <returns></returns>
- public static IList<string> SplitSerialNo(string serialNoBegin, string serialNoEnd)
- {
- int i;
- int count = CardSerialNoContainNum(serialNoBegin, serialNoEnd);
- IList<string> result = new List<string>();
- if (count == -1)
- {
- throw(new OperateSerialNoException("序列号起止并非合法的序列号对,无法计算起止序列号之间的数量。"));
- }
- for (i = 0; i < count; i++)
- {
- result.Add(CardSerialNoAddNum(serialNoBegin, i));
- }
- return result;
- }
- /// <summary>
- /// 得到起止序列号之间的卡数量,包括起止序列号卡本身。
- /// </summary>
- /// <param name="serialNoBegin">字符串中都是数字</param>
- /// <param name="serialNoEnd">字符串中都是数字</param>
- /// <returns>没意义的或异常的将抛出异常</returns>
- private static int IsNumberStrValueCardSerialNoContainNum(string serialNoBegin, string serialNoEnd)
- { //从左边开头比较抵消处理。
- //先判断是否有非数值字母,有的话要转变处理。
- if (string.IsNullOrWhiteSpace(serialNoBegin))
- {
- serialNoBegin = "0";
- }
- if (string.IsNullOrWhiteSpace(serialNoEnd))
- {
- serialNoEnd = "0";
- }
- serialNoBegin = serialNoBegin.Trim().ToLower();
- serialNoEnd = serialNoEnd.Trim().ToLower();
-
- int serialNoBeginLen = serialNoBegin.Length;
- int serialNoEndLen = serialNoEnd.Length;
-
- Int64 containNum = 1;
- if (serialNoBegin.CompareTo(serialNoEnd) == 0)
- { //相同。
- containNum = 1;
- }
- else
- {
- int leftPartSamLen; //左边边相同部分的长度;防止长字符,可以消减。
- //相互比对左边补0;以使两个操作项位数相同。
- if (serialNoBeginLen != serialNoEndLen)
- {
- if (serialNoBeginLen < serialNoEndLen)
- {
- serialNoBegin = serialNoBegin.PadLeft(serialNoEndLen, '0');
- }
- else
- {
- serialNoEnd = serialNoEnd.PadLeft(serialNoBeginLen, '0');
- }
- }
- if (serialNoBegin.CompareTo(serialNoEnd) == 0)
- { //相同。
- containNum = 1;
- }
- else
- {
- string inBeginSingleStr;
- string inEndSingleStr;
- leftPartSamLen = 0;
- while ((leftPartSamLen + 1) <= serialNoBegin.Length)
- {
- inBeginSingleStr = serialNoBegin.Substring(leftPartSamLen, 1);
- inEndSingleStr = serialNoEnd.Substring(leftPartSamLen, 1);
- if (inBeginSingleStr == inEndSingleStr)
- {
- leftPartSamLen++;
- }
- else
- {
- break;
- }
- }
- string joinOperateSerialNoBegin; //参与运算的起序列号部分。
- string joinOperateSerialNoEnd; //参与运算的止序列号部分。
- joinOperateSerialNoBegin = serialNoBegin.Substring(leftPartSamLen);
- joinOperateSerialNoEnd = serialNoEnd.Substring(leftPartSamLen);
- try
- {
- containNum = System.Convert.ToInt64(joinOperateSerialNoEnd) - System.Convert.ToInt64(joinOperateSerialNoBegin) + 1;
- }
- catch (System.Exception err)
- {
- string errStr = err.Message;
- throw new OperateSerialNoException("操作数运算溢出异常!");
- }
- }
- }
- return System.Convert.ToInt32(containNum);
- }
- /// <summary>
- /// 比较两个字符串的大小;后者不小于前者。
- /// </summary>
- /// <param name="lower"></param>
- /// <param name="upper"></param>
- /// <returns></returns>
- public static bool CompareNotLess(string lower, string upper)
- {
- bool checkResult = false;
- if ((string.IsNullOrWhiteSpace(lower)))
- {
- lower = "0";
- }
- if ((string.IsNullOrWhiteSpace(upper)))
- {
- upper = "0";
- }
- if (lower.Trim().ToLower() == upper.Trim().ToLower())
- {
- checkResult = true;
- }
- else
- {
- if (CardSerialNoContainNum(lower, upper) >= 1)
- {
- checkResult = true;
- }
- }
- return checkResult;
- }
- /// <summary>
- /// 比较两个字符串的大小;后者大于前者。
- /// </summary>
- /// <param name="lower"></param>
- /// <param name="upper"></param>
- /// <returns></returns>
- public static bool CompareGreater(string lower, string upper)
- {
- bool checkResult = false;
- if ((string.IsNullOrWhiteSpace(lower)))
- {
- lower = "0";
- }
- if ((string.IsNullOrWhiteSpace(upper)))
- {
- upper = "0";
- }
- if (lower.Trim().ToLower() == upper.Trim().ToLower())
- {
- checkResult = false;
- }
- else
- {
- if (CardSerialNoContainNum(lower, upper) > 1)
- {
- checkResult = true;
- }
- }
- return checkResult;
- }
- /// <summary>
- /// 判断字符串是否在下限、上限内。
- /// </summary>
- /// <param name="lower"></param>
- /// <param name="upper"></param>
- /// <param name="checkValue"></param>
- /// <returns></returns>
- public static bool CheckRangeContentedValue(string lower, string upper, string checkValue)
- {
- bool checkResult = false;
- if ((string.IsNullOrWhiteSpace(lower)))
- {
- lower = "0";
- }
- if ((string.IsNullOrWhiteSpace(upper)))
- {
- upper = "0";
- }
- if ((string.IsNullOrWhiteSpace(checkValue)))
- {
- checkValue = "0";
- }
- if (lower.Trim() == "0" && upper.Trim() == "0" && checkValue.Trim() != "0") return false;
- if (lower.Trim() == "0" && upper.Trim() == "0" && checkValue.Trim() == "0") return true;
- if (CardSerialNoContainNum(lower, checkValue) >= 1
- && CardSerialNoContainNum(checkValue, upper) >= 1
- )
- {
- checkResult = true;
- }
- return checkResult;
- }
- /// <summary>
- /// 记录非数字的字母和字母位置
- /// </summary>
- public struct notNumLetterAndPlace
- {
- public string notNumLetter; //非数字字母
- public int LetterPlace; //该字母在字符串中的位置,和string定义的位置一致,0开始从左到右。
- }
- /// <summary>
- /// 根据字母和位置信息给字符串补充字母。-1标记不补充,补充操作从左到右不可反向。(要考虑位不足)
- /// </summary>
- /// <returns></returns>
- private static string supplyStrValueNotNumPar(string strValue, notNumLetterAndPlace[] supplyInfor)
- {
- string getStrValue = strValue;
- int supplyInforLen = supplyInfor.Length;
- //获取最大位置的非字母的位置,如果需要插入的原始值位数小于该值,则需要前边不0。
- int needMinShort = 0;
- for (int leftFirtCharPlace = 0; leftFirtCharPlace < supplyInforLen; leftFirtCharPlace++)
- {
- if (supplyInfor[leftFirtCharPlace].LetterPlace != -1)
- {
- needMinShort = supplyInforLen-leftFirtCharPlace+1;
- }
- }
- if (strValue.Length < needMinShort)
- {
- strValue = strValue.PadLeft(needMinShort, '0');
- }
- for (int letterPlaceIndex = 0; letterPlaceIndex < supplyInforLen; letterPlaceIndex++)
- {
- if (supplyInfor[letterPlaceIndex].LetterPlace != -1)
- { //补充操作
- getStrValue = getStrValue.Insert(supplyInfor[letterPlaceIndex].LetterPlace, supplyInfor[letterPlaceIndex].notNumLetter);
- }
- }
- return getStrValue;
- }
- /// <summary>
- /// 长数字字符的加运算(包括减运算)
- /// </summary>
- /// <param name="strValue">字符串中都是数字</param>
- /// <param name="addNum"></param>
- /// <param name="needAlign">是否需要位长对齐(主要用于减的情况)</param>
- /// <returns></returns>
- private static string IsNumberStrValueAddNum(string strValue, int addNum, bool needAlign = true)
- {
- strValue = strValue.Trim();
- if (strValue == "" || strValue == null || string.Equals(strValue, System.String.Empty))
- {
- strValue = "0";
- }
- string resultStrValue;
- int strValueLen; //字符串长度,即 strValue 的长度。
- strValueLen = strValue.Length;
- //int nowDoDegreeHigh; //当前处理的高位位置(从右到左,和整数位数定义一致)。
- //int nowDoNumLen; //当次运算涉及到的位数。
- //int nowDoDegreeLow; //当前处理的底位位置(从右到左,和整数位数定义一致)。
- //Int64 joinNumInStrValue; //要参与当次运算的字符串部分数值。
- //Int64 joinNumInRemnant; //剩余要加的数量,开始时是 要加数量。
-
- //nowDoNumLen = addNum.ToString().Length; //第一次运算涉及到的位数是传入的要加数量的位数。
- //nowDoDegreeHigh = addNum.ToString().Length;
- //nowDoDegreeLow = 1;
- int canDoIntMaxLen = 18;
- if (strValueLen <= canDoIntMaxLen)
- { //位整型最大值19位,可直接运算后返回。
- resultStrValue = System.Convert.ToString(System.Convert.ToInt64(strValue) + addNum);
- }
- else
- {
- #region 不再使用递归处理,而是直接取后18位来处理;然后补加左边。
- /* 不再使用递归处理,而是直接取后18位来处理;然后补加左边。
- //加的超常位的,从右到左递推计算。
- resultStrValue = "";
- joinNumInRemnant = addNum;
- while (nowDoDegreeHigh < strValueLen)
- {
- nowDoNumLen = joinNumInRemnant.ToString().Length;
- joinNumInStrValue = System.Convert.ToInt64(strValue.Substring((strValueLen - nowDoDegreeHigh), nowDoNumLen));
- joinNumInRemnant = joinNumInStrValue + joinNumInRemnant;
- //resultStrValue = System.Convert.ToString(joinNumInRemnant) + resultStrValue;
- //判断是否进位
- if (joinNumInRemnant.ToString().Length <= nowDoNumLen)
- { //没进位,结束循环。
- resultStrValue = System.Convert.ToString(joinNumInRemnant) + resultStrValue;
- break;
- }
- else
- { //进位
- resultStrValue = (System.Convert.ToString(joinNumInRemnant)).Substring(1) + resultStrValue;
- joinNumInRemnant = 1; //只有1这个值。(System.Convert.ToString(joinNumInRemnant)).Substring(1)
- nowDoDegreeHigh = nowDoDegreeHigh + 1;
- nowDoDegreeLow = nowDoDegreeHigh;
- }
- }
- */
- #endregion
- string canDoMaxRightPar = strValue.Substring((strValueLen - canDoIntMaxLen), canDoIntMaxLen);
- string strLowPlaceValue = System.Convert.ToString(System.Convert.ToInt64(canDoMaxRightPar) + addNum);
- resultStrValue = strValue.Substring(0, (strValue.Length - strLowPlaceValue.Length)) + strLowPlaceValue;
- }
- if (needAlign)
- {
- resultStrValue = supplyleftPart(resultStrValue, strValue, addNum);
- }
- return resultStrValue;
- }
- /// <summary>
- /// 根据参照字符串,补充左边缺的部分,如0开头的。
- /// </summary>
- /// <param name="strValue"></param>
- /// <param name="strValueRefer"></param>
- /// <returns></returns>
- private static string supplyleftPart(string strValueNeedSupply, string strValueRefer, int addNum)
- {
- string resultStrValue;
- if (strValueNeedSupply.Length >= strValueRefer.Length)
- { //不需要补充
- resultStrValue = strValueNeedSupply;
- }
- else
- {
- //不可简单的在左边补0;
- //resultStrValue = strValueRefer.Substring(0, (strValueRefer.Length - strValueNeedSupply.Length)) + strValueNeedSupply;
- //resultStrValue = strValueNeedSupply.PadLeft(strValueRefer.Length, '0');
- if (addNum >= 0)
- {
- resultStrValue = strValueRefer.Substring(0, (strValueRefer.Length - strValueNeedSupply.Length)) + strValueNeedSupply;
- }
- else
- {
- resultStrValue = strValueNeedSupply.PadLeft(strValueRefer.Length, '0');
- }
- }
- return resultStrValue;
- }
- public static notNumLetterAndPlace[] getstrValueNotNumPart(string strValue)
- {
- notNumLetterAndPlace[] getValue = new notNumLetterAndPlace[strValue.Length];
- string Letter;
- for (int i = 0; i < strValue.Length; i++)
- {
- Letter = strValue.Substring(i, 1);
- if (regex.IsMatch(Letter))
- { //是非数字字母
- getValue[i].notNumLetter = Letter;
- getValue[i].LetterPlace = i;
- }
- else
- {
- getValue[i].LetterPlace = -1; //是数字字母,标位置为-1。
- }
- }
- return getValue;
- }
- /// <summary>
- /// 判断该字符串是否全数字
- /// 注意: "" 返回是false.
- /// </summary>
- /// <param name="strNumber"></param>
- /// <returns></returns>
- public static bool IsNumber(string strNumber)
- {
- //bool b = System.Text.RegularExpressions.Regex.IsMatch(strNumber, @"^(-?\\d+)(\\.\\d+)?$");
- return System.Text.RegularExpressions.Regex.IsMatch(strNumber, @"^(-?\d+$)");
- }
- /// <summary>
- /// 判断字符串是否为正整数
- /// </summary>
- /// <param name="str">要判断的字符串对象</param>
- /// <returns></returns>
- public static bool IsInt(string str)
- {
- return System.Text.RegularExpressions.Regex.IsMatch(str, @"^(0|([1-9]\d*))$");
- }
- public static string[][] MergeSerialNo(string[] singleSerialNos)
- {
- int i;
- ArrayList result = new ArrayList();
- string lastSerialNo = "";
- string serialNoFirst = "";
- for (i = 0; i < singleSerialNos.Length; i++)
- {
- if (lastSerialNo == "")
- {
- lastSerialNo = singleSerialNos[i];
- serialNoFirst = lastSerialNo;
- continue;
- }
- if (singleSerialNos[i] != CardSerialNoAddNum(lastSerialNo, 1))
- {
- result.Add(new string[] { serialNoFirst, lastSerialNo });
- serialNoFirst = singleSerialNos[i];
- }
- lastSerialNo = singleSerialNos[i];
- }
- if (serialNoFirst != "" && lastSerialNo != "")
- { result.Add(new string[] { serialNoFirst, lastSerialNo }); }
- return (string[][])result.ToArray(typeof(string[]));
- }
- /// <summary>
- /// 将分段的序列号合成整体
- /// </summary>
- /// <param name="source">输入的数据源</param>
- /// <param name="serialNoStart">序列号起字段</param>
- /// <param name="serialNoEnd">序列号止字段</param>
- /// <param name="qty">用于存放合并后区间序列号数量的字段</param>
- /// <param name="mergeCondition">需要合并的数据的筛选条件,不符合该条件的数据原封不动返回</param>
- /// <param name="groupBy">合并时的分组条件字段</param>
- /// <returns></returns>
- public static IList<T> MergeSerialNo<T>(IEnumerable<T> source, Expression<Func<T, string>> serialNoStart, Expression<Func<T, string>> serialNoEnd,
- Expression<Func<T, int?>> qty, Expression<Func<T, bool>> mergeCondition) where T : class
- {
- return MergeSerialNo(source, serialNoStart, serialNoEnd, qty, mergeCondition, (x => x));
- }
- public static IList<T> MergeSerialNo<T, GroupByCondition>(IEnumerable<T> source, Expression<Func<T, string>> serialNoStart, Expression<Func<T, string>> serialNoEnd,
- Expression<Func<T, int?>> qty, Expression<Func<T, bool>> mergeCondition, Expression<Func<T, GroupByCondition>> groupBy)
- {
- IList<T> result = new List<T>();
- IList<T> needMergeRowsList = new List<T>();
- PropertyInfo[] allProperties = typeof(T).GetProperties();
- PropertyInfo[] groupProperties = typeof(GroupByCondition).GetProperties();
- if (serialNoStart.Body.NodeType != ExpressionType.MemberAccess)
- {
- throw new OperateSerialNoException("serialNoStart必须为属性选择的Expression。");
- }
- if (serialNoEnd.Body.NodeType != ExpressionType.MemberAccess)
- {
- throw new OperateSerialNoException("serialNoEnd必须为属性选择的Expression。");
- }
- var qtyNodeType = qty.Body.NodeType;
- if (qtyNodeType == ExpressionType.Convert)
- {
- qtyNodeType = (qty.Body as UnaryExpression).Operand.NodeType;
- }
- if (qtyNodeType != ExpressionType.MemberAccess && qty.Body.ToString() != "null")
- {
- throw new OperateSerialNoException("qty必须为属性选择的Expression,如传入的对象没有任何表示数量的列,则直接输入如:x => null。");
- }
- string serialNoStartColumnName = (serialNoStart.Body as MemberExpression).Member.Name;
- string serialNoEndColumnName = (serialNoEnd.Body as MemberExpression).Member.Name;
- string qtyColumnName;
- if (qty.Body.ToString() != "null")
- {
- if (qty.Body.NodeType == ExpressionType.Convert)
- {
- qtyColumnName = ((qty.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
- }
- else
- {
- qtyColumnName = (qty.Body as MemberExpression).Member.Name;
- }
- }
- else
- {
- qtyColumnName = "";
- }
- var serialNoStartFunc = serialNoStart.Compile();
- var serialNoEndFunc = serialNoEnd.Compile();
- var qtyFunc = qty.Compile();
- var mergeConditionFunc = mergeCondition.Compile();
- var groupByFunc = groupBy.Compile();
- needMergeRowsList = source.Where(mergeCondition.Compile()).ToList();
- result = (
- from s in source
- join nmr in needMergeRowsList
- on new { Group = groupByFunc.Invoke(s), SerialNoStart = serialNoStartFunc.Invoke(s), SerialNoEnd = serialNoEndFunc.Invoke(s) }
- equals new { Group = groupByFunc.Invoke(nmr), SerialNoStart = serialNoStartFunc.Invoke(nmr), SerialNoEnd = serialNoEndFunc.Invoke(nmr) } into dnmr
- from enmr in dnmr.DefaultIfEmpty()
- where enmr == null
- select s
- ).ToList();
- var startSerialNoList = (
- from nmr in needMergeRowsList
- join nmr1 in needMergeRowsList
- on new { Group = groupByFunc.Invoke(nmr), SerialNo = CardSerialNoAddNum(serialNoStartFunc.Invoke(nmr), -1) }
- equals new { Group = groupByFunc.Invoke(nmr1), SerialNo = serialNoEndFunc.Invoke(nmr1) } into dnmr
- from enmr in dnmr.DefaultIfEmpty()
- where enmr == null
- select new
- {
- Group = groupByFunc.Invoke(nmr),
- SerialNo = serialNoStartFunc.Invoke(nmr),
- IsEnd = false
- }
- );
- var endSerialNoList = (
- from nmr in needMergeRowsList
- join nmr1 in needMergeRowsList
- on new { Group = groupByFunc.Invoke(nmr), SerialNo = CardSerialNoAddNum(serialNoEndFunc.Invoke(nmr), 1) }
- equals new { Group = groupByFunc.Invoke(nmr1), SerialNo = serialNoStartFunc.Invoke(nmr1) } into dnmr
- from enmr in dnmr.DefaultIfEmpty()
- where enmr == null
- select new
- {
- Group = groupByFunc.Invoke(nmr),
- SerialNo = serialNoEndFunc.Invoke(nmr),
- IsEnd = true
- }
- );
- var serialNoList = startSerialNoList.Union(endSerialNoList).ToList();
- if (groupProperties.Length > 0)
- {
- var orderingSerialNoList = serialNoList.OrderBy(x => groupProperties[0].GetValue(x.Group, null));
- for (int i = 1; i < groupProperties.Length; i++)
- {
- orderingSerialNoList.ThenBy(x => groupProperties[i].GetValue(x.Group, null));
- }
- orderingSerialNoList = orderingSerialNoList.ThenBy(x => x.SerialNo);
- serialNoList = orderingSerialNoList.ToList();
- }
- string lastStartSerialNo = "";
- foreach (var serialNo in serialNoList)
- {
- if (!serialNo.IsEnd)
- {
- lastStartSerialNo = serialNo.SerialNo;
- }
- else
- {
- T item = (T)typeof(T).Assembly.CreateInstance(typeof(T).FullName);
- //AutoMapper.Mapper.Map(item, serialNo.Group);
- foreach (var property in groupProperties)
- {
- allProperties.Where(x => x.Name == property.Name).First().SetValue(item, property.GetValue(serialNo.Group, null), null);
- }
- allProperties.Where(x => x.Name == serialNoStartColumnName).First().SetValue(item, lastStartSerialNo, null);
- allProperties.Where(x => x.Name == serialNoEndColumnName).First().SetValue(item, serialNo.SerialNo, null);
- if (qtyColumnName != "")
- {
- allProperties.Where(x => x.Name == qtyColumnName).First().SetValue(item, CardSerialNoContainNum(lastStartSerialNo, serialNo.SerialNo), null);
- }
- result.Add(item);
- }
- }
- return result;
- }
- public static string GetMaxSerialNo(string serialNo1, string serialNo2)
- {
- return CompareGreater(serialNo1, serialNo2) ? serialNo2 : serialNo1;
- }
- public static string GetMinSerialNo(string serialNo1, string serialNo2)
- {
- return CompareGreater(serialNo1, serialNo2) ? serialNo1 : serialNo2;
- }
- /// <summary>
- /// 获取两个字符串的相同开头
- /// </summary>
- /// <param name="string1"></param>
- /// <param name="string2"></param>
- /// <returns></returns>
- public static string GetSameStart(string string1, string string2)
- {
- int i;
- int minLength;
- int differentIndex = -1;
- char[] char1, char2;
- if (string1 == "" || string2 == "")
- { return ""; }
- if (string1.Length > string2.Length)
- { minLength = string2.Length; }
- else
- { minLength = string1.Length; }
- char1 = string1.ToCharArray();
- char2 = string2.ToCharArray();
- for (i = 0; i < minLength; i++)
- {
- if (char1[i] != char2[i])
- {
- differentIndex = i;
- break;
- }
- }
- if (differentIndex != -1)
- { return string1.Substring(0, differentIndex); }
- else
- { return string1.Substring(0, minLength); }
- }
- public static string TrimStart(string source, string trimString)
- {
- int i;
- if (source == "" || trimString == "")
- { return ""; }
- if (trimString.Length > source.Length)
- {
- throw (new Exception("搜索的字符串长度超出源字符串范围。"));
- }
- if (!source.StartsWith(trimString))
- { return source; }
- return source.Substring(trimString.Length, source.Length - trimString.Length);
- }
- public static IList<SerialNoSegment> SerialNoDecrease(this IList<SerialNoSegment> sourceList, IList<SerialNoSegment> decreasorList)
- {
- int i, j, k;
- IList<SerialNoSegment> resultList = null;
- foreach (var source in sourceList.OrderBy(x => x.SerialNoStart))
- {
- string startSerialNo = source.SerialNoStart;
- string endSerialNo = source.SerialNoEnd;
- foreach (var decreasor in decreasorList.OrderBy(x => x.SerialNoStart))
- {
- string decreaseStartSerialNo = decreasor.SerialNoStart;
- string decreaseEndSerialNo = decreasor.SerialNoEnd;
- try
- {
- if (decreaseStartSerialNo == "0" || decreaseEndSerialNo == "0")
- {
- continue;
- }
- if (startSerialNo.Length != decreaseStartSerialNo.Length)
- {
- continue;
- }
- string sameStart = GetSameStart(startSerialNo, decreaseStartSerialNo);
- string sameEnd = GetSameStart(endSerialNo, decreaseEndSerialNo);
- string sameAll = GetSameStart(sameStart, sameEnd);
- if (sameStart.Length == startSerialNo.Length && sameEnd.Length == endSerialNo.Length)
- {
- break;
- }
- if (!IsInt(TrimStart(startSerialNo, sameAll)) || !IsInt(TrimStart(decreaseStartSerialNo, sameAll))
- || !IsInt(TrimStart(endSerialNo, sameAll)) || !IsInt(TrimStart(decreaseEndSerialNo, sameAll)))
- {
- continue;
- }
- int intStartSerialNo, intEndSerialNo, intDecreaseStartSerialNo, intDecreaseEndSerialNo;
- intStartSerialNo = Convert.ToInt32(TrimStart(startSerialNo, sameAll));
- intEndSerialNo = Convert.ToInt32(TrimStart(endSerialNo, sameAll));
- intDecreaseStartSerialNo = Convert.ToInt32(TrimStart(decreaseStartSerialNo, sameAll));
- intDecreaseEndSerialNo = Convert.ToInt32(TrimStart(decreaseEndSerialNo, sameAll));
- if (!(intStartSerialNo <= intDecreaseEndSerialNo && intEndSerialNo >= intDecreaseStartSerialNo))
- {
- continue;
- }
- if (intStartSerialNo >= intDecreaseStartSerialNo && intEndSerialNo <= intDecreaseEndSerialNo)
- {
- break;
- }
- if (intStartSerialNo < intDecreaseStartSerialNo)
- {
- resultList.Add(new SerialNoSegment { SerialNoStart = startSerialNo, SerialNoEnd = CardSerialNoAddNum(decreaseStartSerialNo, -1) });
- }
- if (intEndSerialNo > intDecreaseEndSerialNo)
- {
- startSerialNo = CardSerialNoAddNum(decreaseEndSerialNo, 1);
- resultList.Add(new SerialNoSegment { SerialNoStart = startSerialNo, SerialNoEnd = endSerialNo });
- }
- else
- {
- startSerialNo = "0";
- endSerialNo = "0";
- }
- }
- catch (Exception ex)
- {
- throw (ex);
- }
- }
- }
- return resultList;
- }
- }
- public class SerialNoSegment
- {
- public string SerialNoStart { get; set; }
- public string SerialNoEnd { get; set; }
- }
- public class OperateSerialNoException : Exception
- {
- public OperateSerialNoException(string message)
- : base(message)
- { }
- public OperateSerialNoException(string message, Exception ex)
- : base(message, ex)
- { }
- }
- }
|