using Tiger.Model; using SqlSugar; using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Rhea.Common; using System.Net; using System.Linq; using Newtonsoft.Json; using Tiger.Business.DbCache; using System.Text.RegularExpressions; using System.Diagnostics; using System.Threading; using System.Data; using Tiger.IBusiness; namespace Tiger.Business { /// /// BAS_CODE_RULE 扩展类 /// public static class BAS_CODE_RULEExtension { /// /// 规则验证 /// /// /// /// public static Result Verify(this BAS_CODE_RULE rule, string sn) { return Cache.CodeRule.Verify(sn, rule); } /// /// 生成条码 /// /// /// /// public static Result Generate(this BAS_CODE_RULE rule, params object?[] args) { return Cache.CodeRule.Generate(rule.RULE_CODE, args); } /// /// 尝试生成条码,不保存到数据库 /// /// /// /// public static Result TryGenerate(this BAS_CODE_RULE rule, params object?[] args) { return Cache.CodeRule.TryGenerate(rule.RULE_CODE, args); } }//endClass /// /// 条码规则验证类 /// public class RuleVerifier { public RuleVerifier(BAS_CODE_RULE rule) { Rule = rule; } public BAS_CODE_RULE Rule { get; set; } /// /// 是否完成验证 /// public bool isFinish { get; set; } = false; /// /// 是否匹配成功 /// public bool IsMatch { get; set; } = false; /// /// 是否验证异常 /// public bool IsException { get; set; } = false; /// /// 验证异常 /// public Exception MatchException { get; set; } /// /// 数据库关联验证 /// public static bool CheckDB(string key, BAS_CODE_DTL ruleDtl) { return ruleDtl.DATA_TYPE == BAS_CODE_DTL.DATA_TYPEs.DbCheck.GetValue() ? Biz.Db.Queryable(ruleDtl.CHECK_TABLE, "t").Where($"{ruleDtl.CHECK_FIELD} = '{key}'").Any() : true; } /// /// 规则验证 /// /// /// public RuleVerifier Verify(string code) { //Debug.WriteLine($"{Rule.RULE_CODE} verify begin"); IsMatch = true; IsException = false; isFinish = false; try { var match = Rule.GroupRegex.Match(code); IsMatch = match.Success; if (IsMatch) { foreach (var item in Rule.Details) { item.CodeValue = match.Groups[item.RULE_SEQ.ToString()].Value; //判断流水号是否符合规则 if (IsMatch && item.DATA_TYPE == BAS_CODE_DTL.DATA_TYPEs.SerialCode.GetValue()) { //按取值范围判断当前流水号是否在范围内 IsMatch &= item.SERIAL_MIN <= item.CodeValue.ToInt32() && item.CodeValue.ToInt32() <= item.SERIAL_MAX; //当前流水号是否按设置间隔固定数值 IsMatch &= (item.CodeValue.ToInt32() - item.SERIAL_MIN) % item.SERIAL_INTERVAL == 0; //判断当前流水号是否跳过以设置号码结尾的流水号 if (!item.SERIAL_IGNORE.IsNullOrEmpty()) { var ignoreList = item.SERIAL_IGNORE.Split(','); foreach (var num in ignoreList) { IsMatch &= !item.CodeValue.EndsWith(num); } } } } //判断关联字段是否符合规则 if (IsMatch) { foreach (var item in Rule.Details.Where(q => q.DATA_TYPE == BAS_CODE_DTL.DATA_TYPEs.DbCheck.GetValue())) { IsMatch &= CheckDB(item.CodeValue, item); } } } } catch (Exception ex) { IsMatch = false; IsException = true; MatchException = ex; } finally { isFinish = true; } //var sleep = new Random().Next(1, 5); //Thread.Sleep(sleep * 1000); //Debug.WriteLine($"{Rule.RULE_CODE} verify end, verify {(isFinish ? "Finish" : "not finish")}, match {(IsMatch ? "success" : "failed")}, sleep {sleep} seconds"); return this; } } /// /// 条码验证类 /// public class CodeVerifier { /// /// 条码验证类 /// /// /// public CodeVerifier(string code, Func predicate = null) { Code = code; Predicate = predicate; } public string Code { get; set; } public Func Predicate { get; set; } public Expression> Expression { get; set; } public Exception VerifyException { get; set; } private List _Verifiers = new(); public List Verifiers => _Verifiers.IsNullOrEmpty() ? Cache.CodeRule.Rules.WhereIF(!Predicate.IsNullOrEmpty(), Predicate).Select(q => new RuleVerifier(q)).ToList() : _Verifiers; /// /// 是否完成验证 /// public bool isFinish => !Verifiers.Any(q => !q.isFinish); /// /// 是否匹配成功 /// public bool IsMatch => Verifiers.Any(q => q.IsMatch); /// /// 耗费时间 /// public double ElapsedTime { get; set; } /// /// 匹配成功的规则 /// public List Matches => Verifiers.Where(q => q.IsMatch).OrderBy(q => q.Rule.PRIORITY).ToList(); /// /// 验证所有规则 /// public void DoVerify() { var begin = DateTime.Now; ElapsedTime = 0; //Debug.WriteLine($"{Code} verify begin at {begin:T}"); _Verifiers = Cache.CodeRule.Rules.WhereIF(!Predicate.IsNullOrEmpty(), Predicate).Select(q => new RuleVerifier(q)).ToList(); foreach (var item in Verifiers) { Work.DoAsync(() => { item.Verify(Code); }); //item.Verify(Code); } while (!isFinish) ; ElapsedTime = (DateTime.Now - begin).TotalSeconds; //Debug.WriteLine($"{Code} verify end, elapsed total {ElapsedTime} seconds"); } } }