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
|
{
|
/// <summary>
|
/// BAS_CODE_RULE 扩展类
|
/// </summary>
|
public static class BAS_CODE_RULEExtension
|
{
|
/// <summary>
|
/// 规则验证
|
/// </summary>
|
/// <param name="rule"></param>
|
/// <param name="sn"></param>
|
/// <returns></returns>
|
public static Result Verify(this BAS_CODE_RULE rule, string sn)
|
{
|
return Cache.CodeRule.Verify(sn, rule);
|
}
|
|
/// <summary>
|
/// 生成条码
|
/// </summary>
|
/// <param name="rule"></param>
|
/// <param name="args"></param>
|
/// <returns></returns>
|
public static Result Generate(this BAS_CODE_RULE rule, params object?[] args)
|
{
|
return Cache.CodeRule.Generate(rule.RULE_CODE, args);
|
}
|
|
/// <summary>
|
/// 尝试生成条码,不保存到数据库
|
/// </summary>
|
/// <param name="rule"></param>
|
/// <param name="args"></param>
|
/// <returns></returns>
|
public static Result TryGenerate(this BAS_CODE_RULE rule, params object?[] args)
|
{
|
return Cache.CodeRule.TryGenerate(rule.RULE_CODE, args);
|
}
|
}//endClass
|
|
/// <summary>
|
/// 条码规则验证类
|
/// </summary>
|
public class RuleVerifier
|
{
|
public RuleVerifier(BAS_CODE_RULE rule)
|
{
|
Rule = rule;
|
}
|
|
public BAS_CODE_RULE Rule { get; set; }
|
/// <summary>
|
/// 是否完成验证
|
/// </summary>
|
public bool isFinish { get; set; } = false;
|
/// <summary>
|
/// 是否匹配成功
|
/// </summary>
|
public bool IsMatch { get; set; } = false;
|
/// <summary>
|
/// 是否验证异常
|
/// </summary>
|
public bool IsException { get; set; } = false;
|
/// <summary>
|
/// 验证异常
|
/// </summary>
|
public Exception MatchException { get; set; }
|
|
/// <summary>
|
/// 数据库关联验证
|
/// </summary>
|
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;
|
}
|
|
/// <summary>
|
/// 规则验证
|
/// </summary>
|
/// <param name="code"></param>
|
/// <returns></returns>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 条码验证类
|
/// </summary>
|
public class CodeVerifier
|
{
|
/// <summary>
|
/// 条码验证类
|
/// </summary>
|
/// <param name="code"></param>
|
/// <param name="predicate"></param>
|
public CodeVerifier(string code, Func<BAS_CODE_RULE, bool> predicate = null)
|
{
|
Code = code;
|
Predicate = predicate;
|
}
|
|
public string Code { get; set; }
|
public Func<BAS_CODE_RULE, bool> Predicate { get; set; }
|
public Expression<Func<BAS_CODE_RULE, bool>> Expression { get; set; }
|
public Exception VerifyException { get; set; }
|
private List<RuleVerifier> _Verifiers = new();
|
public List<RuleVerifier> Verifiers => _Verifiers.IsNullOrEmpty() ? Cache.CodeRule.Rules.WhereIF(!Predicate.IsNullOrEmpty(), Predicate).Select(q => new RuleVerifier(q)).ToList() : _Verifiers;
|
/// <summary>
|
/// 是否完成验证
|
/// </summary>
|
public bool isFinish => !Verifiers.Any(q => !q.isFinish);
|
/// <summary>
|
/// 是否匹配成功
|
/// </summary>
|
public bool IsMatch => Verifiers.Any(q => q.IsMatch);
|
/// <summary>
|
/// 耗费时间
|
/// </summary>
|
public double ElapsedTime { get; set; }
|
/// <summary>
|
/// 匹配成功的规则
|
/// </summary>
|
public List<RuleVerifier> Matches => Verifiers.Where(q => q.IsMatch).OrderBy(q => q.Rule.PRIORITY).ToList();
|
|
/// <summary>
|
/// 验证所有规则
|
/// </summary>
|
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");
|
}
|
}
|
}
|