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");
}
}
}