|
|
|
@ -75,54 +75,42 @@ namespace DS.WMS.Core.TaskPlat
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
// 判断每项流程达成的条件数量
|
|
|
|
|
Dictionary<long, int> configMatchCount = allConfigList.ToDictionary(x => x.Id, x => 0);
|
|
|
|
|
Dictionary<long, int> configMatchCount = new(allConditionList.Count);
|
|
|
|
|
foreach (var configItem in allConfigList)
|
|
|
|
|
{
|
|
|
|
|
var conditionItem = allConditionList.FirstOrDefault(x => x.ConfigId == configItem.Id);
|
|
|
|
|
if (conditionItem != null && !string.IsNullOrEmpty(conditionItem.Content))
|
|
|
|
|
if (conditionItem == null || string.IsNullOrEmpty(conditionItem.Content))
|
|
|
|
|
{
|
|
|
|
|
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(conditionItem.Content)!;
|
|
|
|
|
|
|
|
|
|
var oldValue = configMatchCount[configItem.Id];
|
|
|
|
|
if (ConditionHelper.IsPass(contitionContent, dataContext))
|
|
|
|
|
{
|
|
|
|
|
configMatchCount[configItem.Id] = oldValue + 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
configMatchCount[configItem.Id] = oldValue - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 取出最匹配的流程
|
|
|
|
|
KeyValuePair<long, int>? bestMatched = null!;
|
|
|
|
|
foreach (var item in configMatchCount)
|
|
|
|
|
{
|
|
|
|
|
if (bestMatched == null)
|
|
|
|
|
{
|
|
|
|
|
bestMatched = new KeyValuePair<long, int>(item.Key, item.Value);
|
|
|
|
|
configMatchCount.Add(configItem.Id, 0);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.Value > bestMatched.Value.Value)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bestMatched = new KeyValuePair<long, int>(item.Key, item.Value);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
var conditionContent = JsonConvert.DeserializeObject<ConditionContent>(conditionItem.Content)!;
|
|
|
|
|
|
|
|
|
|
if (item.Value == bestMatched.Value.Value)
|
|
|
|
|
{
|
|
|
|
|
// 如果达成的条件数量相等,则取最早的流程
|
|
|
|
|
if (item.Key < bestMatched.Value.Key)
|
|
|
|
|
if (ConditionHelper.IsPass(conditionContent, dataContext))
|
|
|
|
|
{
|
|
|
|
|
bestMatched = new KeyValuePair<long, int>(item.Key, item.Value);
|
|
|
|
|
continue;
|
|
|
|
|
var conditionCount = ConditionHelper.GetConditionCount(conditionContent);
|
|
|
|
|
configMatchCount.Add(configItem.Id, conditionCount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var targetConfig = allConfigList.First(x => x.Id == bestMatched.Value.Key);
|
|
|
|
|
// 取出最匹配的流程
|
|
|
|
|
TaskFlowConfig? targetConfig = null;
|
|
|
|
|
if (configMatchCount.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
targetConfig = allConfigList.First(x => x.Id == configMatchCount.First().Key);
|
|
|
|
|
}
|
|
|
|
|
else if (configMatchCount.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
var maxMatchNum = configMatchCount.OrderByDescending(x => x.Value).First().Value; // 取匹配条件数最多的一条
|
|
|
|
|
var temp = configMatchCount.Where(x => x.Value == maxMatchNum).OrderBy(x => x.Key).First().Key;
|
|
|
|
|
targetConfig = allConfigList.First(x => x.Id == temp);
|
|
|
|
|
}
|
|
|
|
|
if (targetConfig == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("targetConfig目标流程意外为null");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 待执行的流程(节点列表)
|
|
|
|
|
var configList = await tenantDb.Queryable<TaskFlowConfig>().Where(x => x.MainConfigId == targetConfig.Id).ToListAsync();
|
|
|
|
@ -169,31 +157,32 @@ namespace DS.WMS.Core.TaskPlat
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 对节点列表里面的节点进行依次判断,取出要执行的节点
|
|
|
|
|
var matchedConfigList = new List<(TaskFlowConfig config, bool isHasCondition)>();
|
|
|
|
|
Dictionary<TaskFlowConfig, int> matchedConfigList = new();
|
|
|
|
|
foreach (var waitMatchConfigItem in waitMatchConfigList)
|
|
|
|
|
{
|
|
|
|
|
var condition = conditionList.FirstOrDefault(x => x.ConfigId == waitMatchConfigItem.Id);
|
|
|
|
|
if (condition == null || string.IsNullOrEmpty(condition.Content))
|
|
|
|
|
{
|
|
|
|
|
matchedConfigList.Add((waitMatchConfigItem, false));
|
|
|
|
|
matchedConfigList.Add(waitMatchConfigItem, 0);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
|
|
|
|
|
if (ConditionHelper.IsPass(contitionContent, dataContext))
|
|
|
|
|
var conditionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
|
|
|
|
|
if (ConditionHelper.IsPass(conditionContent, dataContext))
|
|
|
|
|
{
|
|
|
|
|
matchedConfigList.Add((waitMatchConfigItem, true));
|
|
|
|
|
var conditionCount = ConditionHelper.GetConditionCount(conditionContent);
|
|
|
|
|
matchedConfigList.Add(waitMatchConfigItem, conditionCount);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (matchedConfigList.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
executeConfig = matchedConfigList[0].config;
|
|
|
|
|
executeConfig = matchedConfigList.First().Key;
|
|
|
|
|
}
|
|
|
|
|
else if (matchedConfigList.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
var temp = matchedConfigList.OrderBy(x => x.config.Id).Where(x => x.isHasCondition).ToList();
|
|
|
|
|
executeConfig = temp.FirstOrDefault().config;
|
|
|
|
|
var maxMatchNum = matchedConfigList.OrderByDescending(x => x.Value).First().Value; // 取匹配条件数最多的一条
|
|
|
|
|
executeConfig = matchedConfigList.Where(x => x.Value == maxMatchNum).OrderBy(x => x.Key.Id).First().Key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (executeConfig == null)
|
|
|
|
@ -393,7 +382,7 @@ namespace DS.WMS.Core.TaskPlat
|
|
|
|
|
/// <param name="workFlowType">工作流流程类型</param>
|
|
|
|
|
/// <param name="dataContext"></param>
|
|
|
|
|
/// <param name="currentTaskType">当前执行的任务类型(如果为空,则返回首个任务类型)</param>
|
|
|
|
|
/// <returns>(下一个任务类型,下一节点Id)</returns>
|
|
|
|
|
/// <returns>(下一个任务类型)</returns>
|
|
|
|
|
public async Task<TaskBaseTypeEnum?> GetWorkFlowNextConfigByTaskType(TaskBaseTypeEnum workFlowType, TaskFlowDataContext dataContext, TaskBaseTypeEnum? currentTaskType)
|
|
|
|
|
{
|
|
|
|
|
var allConfigList = await tenantDb.Queryable<TaskFlowConfig>()
|
|
|
|
@ -432,20 +421,21 @@ namespace DS.WMS.Core.TaskPlat
|
|
|
|
|
.Where(x => configIdList.Contains(x.ConfigId))
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var matchedConfigList = new List<TaskFlowConfig>();
|
|
|
|
|
Dictionary<TaskFlowConfig, int> matchedConfigList = new();
|
|
|
|
|
foreach (var item in waitMatchConfigList)
|
|
|
|
|
{
|
|
|
|
|
var condition = conditionList.FirstOrDefault(x => x.ConfigId == item.Id);
|
|
|
|
|
if (condition == null || string.IsNullOrEmpty(condition.Content))
|
|
|
|
|
{
|
|
|
|
|
matchedConfigList.Add(item);
|
|
|
|
|
matchedConfigList.Add(item, 0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
|
|
|
|
|
if (ConditionHelper.IsPass(contitionContent, dataContext))
|
|
|
|
|
var conditionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
|
|
|
|
|
if (ConditionHelper.IsPass(conditionContent, dataContext))
|
|
|
|
|
{
|
|
|
|
|
matchedConfigList.Add(item);
|
|
|
|
|
var conditionCount = ConditionHelper.GetConditionCount(conditionContent);
|
|
|
|
|
matchedConfigList.Add(item, conditionCount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -453,11 +443,12 @@ namespace DS.WMS.Core.TaskPlat
|
|
|
|
|
TaskFlowConfig? executeConfig = null;
|
|
|
|
|
if (matchedConfigList.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
executeConfig = matchedConfigList[0];
|
|
|
|
|
executeConfig = matchedConfigList.First().Key;
|
|
|
|
|
}
|
|
|
|
|
else if (matchedConfigList.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
executeConfig = matchedConfigList.FirstOrDefault(x => x.IsMoreMatchDefault);
|
|
|
|
|
var maxMatchNum = matchedConfigList.OrderByDescending(x => x.Value).First().Value; // 取匹配条件数最多的一条
|
|
|
|
|
executeConfig = matchedConfigList.Where(x => x.Value == maxMatchNum).OrderBy(x => x.Key.Id).First().Key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (executeConfig == null)
|
|
|
|
@ -492,108 +483,6 @@ namespace DS.WMS.Core.TaskPlat
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据当前节点Id,获取工作流下一个任务类型
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="workFlowType">工作流流程类型</param>
|
|
|
|
|
/// <param name="dataContext"></param>
|
|
|
|
|
/// <param name="currentConfigId">当前执行的配置Id(如果为空,则返回首个任务类型)</param>
|
|
|
|
|
/// <returns>(下一个任务类型,下一节点Id)</returns>
|
|
|
|
|
public async Task<(TaskBaseTypeEnum taskType, long configId)?> GetWorkFlowNextConfig(TaskBaseTypeEnum workFlowType, TaskFlowDataContext dataContext, long? currentConfigId = null)
|
|
|
|
|
{
|
|
|
|
|
var allConfigList = await tenantDb.Queryable<TaskFlowConfig>()
|
|
|
|
|
.Where(t => t.MainConfigId == SqlFunc.Subqueryable<TaskFlowConfig>().Where(x => x.IsMain && x.TaskType == workFlowType.ToString()).Select(x => x.Id))
|
|
|
|
|
.OrderBy(t => t.Id)
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
if (allConfigList.Count == 0) return null;
|
|
|
|
|
|
|
|
|
|
long configId;
|
|
|
|
|
if (currentConfigId == null)
|
|
|
|
|
{
|
|
|
|
|
configId = allConfigList.First(x => x.IsMain).Id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
configId = currentConfigId.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<TaskFlowConfig> waitMatchConfigList = new();
|
|
|
|
|
for (int i = 0; i < allConfigList.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var currentConfig = allConfigList.FirstOrDefault(x => x.Id == configId);
|
|
|
|
|
if (currentConfig == null || string.IsNullOrEmpty(currentConfig.NextConfigId))
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var nextIds = currentConfig.NextConfigId.Split(',').Where(x => !string.IsNullOrEmpty(x)).Select(x => Convert.ToInt64(x));
|
|
|
|
|
waitMatchConfigList = allConfigList.Where(x => nextIds.Contains(x.Id)).ToList();
|
|
|
|
|
|
|
|
|
|
if (waitMatchConfigList.Count == 0) return null; // 如果走了这一步的return,说明配置有问题:配置了下一节点的id,但是却查不到
|
|
|
|
|
|
|
|
|
|
var configIdList = waitMatchConfigList.Select(x => x.Id);
|
|
|
|
|
var conditionList = await tenantDb.Queryable<TaskFlowCondition>()
|
|
|
|
|
.Where(x => configIdList.Contains(x.ConfigId))
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
var matchedConfigList = new List<TaskFlowConfig>();
|
|
|
|
|
foreach (var item in waitMatchConfigList)
|
|
|
|
|
{
|
|
|
|
|
var condition = conditionList.FirstOrDefault(x => x.ConfigId == item.Id);
|
|
|
|
|
if (condition == null || string.IsNullOrEmpty(condition.Content))
|
|
|
|
|
{
|
|
|
|
|
matchedConfigList.Add(item);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var contitionContent = JsonConvert.DeserializeObject<ConditionContent>(condition.Content)!;
|
|
|
|
|
if (ConditionHelper.IsPass(contitionContent, dataContext))
|
|
|
|
|
{
|
|
|
|
|
matchedConfigList.Add(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TaskFlowConfig? executeConfig = null;
|
|
|
|
|
if (matchedConfigList.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
executeConfig = matchedConfigList[0];
|
|
|
|
|
}
|
|
|
|
|
else if (matchedConfigList.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
executeConfig = matchedConfigList.FirstOrDefault(x => x.IsMoreMatchDefault);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (executeConfig == null)
|
|
|
|
|
{
|
|
|
|
|
executeConfig = waitMatchConfigList.FirstOrDefault(x => x.IsUnMatchDefault);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (executeConfig == null)
|
|
|
|
|
{
|
|
|
|
|
// 如果最终还是没有匹配到,则需要判断情况
|
|
|
|
|
// 如果待匹配的分支只有1个,则继续循环判断下一节点;否则如果待匹配的分支有多个,则无法判断下一节点
|
|
|
|
|
if (waitMatchConfigList.Count == 1)
|
|
|
|
|
{
|
|
|
|
|
configId = waitMatchConfigList[0].Id;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var taskType = await tenantDb.Queryable<TaskFlowModule>().Where(x => x.Id == executeConfig.ExecuteModuleId && x.ModuleType == 2).Select(x => x.TaskType).FirstAsync();
|
|
|
|
|
|
|
|
|
|
if (taskType != null && Enum.TryParse(typeof(TaskBaseTypeEnum), taskType, out object? temp))
|
|
|
|
|
{
|
|
|
|
|
return ((TaskBaseTypeEnum)temp, executeConfig.Id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
static string WriteLog(string throwMsg, Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return string.Format("【自定义错误】:{0} \r\n【异常类型】:{1} \r\n【异常信息】:{2} \r\n【堆栈调用】:{3}", new object[]
|
|
|
|
|