|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
using DS.Module.Core.Data;
|
|
|
|
|
using DS.Module.Core.Extensions;
|
|
|
|
|
using DS.Module.UserModule;
|
|
|
|
|
using DS.WMS.Core.Flow.Dtos;
|
|
|
|
|
using DS.WMS.Core.Flow.Entity;
|
|
|
|
|
using Mapster;
|
|
|
|
@ -13,22 +13,31 @@ namespace DS.WMS.Core.Flow.Method;
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class FlowRuntime
|
|
|
|
|
{
|
|
|
|
|
public FlowRuntime(FlowInstance instance, ISqlSugarClient _db) : this(instance, _db, null, null)
|
|
|
|
|
ISqlSugarClient db { get; set; }
|
|
|
|
|
ISqlSugarClient tenantDb { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 构造函数
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="instance"></param>
|
|
|
|
|
/// <param name="_db"></param>
|
|
|
|
|
public FlowRuntime(FlowInstance instance, ISqlSugarClient _db) : this(instance, _db, null)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 构造函数
|
|
|
|
|
/// </summary>
|
|
|
|
|
public FlowRuntime(FlowInstance instance, ISqlSugarClient _db, ISqlSugarClient tenantDb, IUser user)
|
|
|
|
|
public FlowRuntime(FlowInstance instance, ISqlSugarClient _db, ISqlSugarClient? tenantDb)
|
|
|
|
|
{
|
|
|
|
|
ArgumentNullException.ThrowIfNull(instance, nameof(instance));
|
|
|
|
|
|
|
|
|
|
db = _db;
|
|
|
|
|
BusinessId = instance.BusinessId;
|
|
|
|
|
ColumnView = instance.ColumnView;
|
|
|
|
|
this.tenantDb = tenantDb;
|
|
|
|
|
this.user = user;
|
|
|
|
|
|
|
|
|
|
InitNodes(instance.Content); //获取工作流模板内容的json对象;
|
|
|
|
|
ReadJson(instance.Content); //获取工作流模板内容的json对象;
|
|
|
|
|
|
|
|
|
|
CurrentNodeId = instance.ActivityId == "" ? StartNodeId : instance.ActivityId;
|
|
|
|
|
CurrentNodeType = GetNodeType(CurrentNodeId);
|
|
|
|
@ -48,7 +57,7 @@ public class FlowRuntime
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NextNodeId = GetNextNodeId(CurrentNodeId); //下一个节点
|
|
|
|
|
if (string.IsNullOrEmpty(NextNodeId) && CurrentNodeType == 3)
|
|
|
|
|
if (string.IsNullOrEmpty(NextNodeId) && CurrentNodeType == 3)
|
|
|
|
|
{
|
|
|
|
|
//当前节点类型为开始节点,且没有下一级节点,则认为应跳出工作流
|
|
|
|
|
ShouldSkip = true;
|
|
|
|
@ -56,27 +65,25 @@ public class FlowRuntime
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NextNodeType = GetNodeType(NextNodeId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 业务ID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public long BusinessId { get; set; }
|
|
|
|
|
public string ColumnView { get; set; }
|
|
|
|
|
|
|
|
|
|
ISqlSugarClient db { get; set; }
|
|
|
|
|
ISqlSugarClient tenantDb { get; set; }
|
|
|
|
|
IUser user { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 查询对象名
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string ColumnView { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 是否应跳过工作流执行
|
|
|
|
|
/// </summary>
|
|
|
|
|
public bool ShouldSkip { get; private set; }
|
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
|
|
///// 运行实例的Id
|
|
|
|
|
///// </summary>
|
|
|
|
|
//public long FlowInstanceId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 开始节点的ID
|
|
|
|
|
/// </summary>
|
|
|
|
@ -122,6 +129,9 @@ public class FlowRuntime
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<FlowChild> ChildNodes { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 备注
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string? Note { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -129,9 +139,9 @@ public class FlowRuntime
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="schemeContentJson"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private void InitNodes(string schemeContentJson)
|
|
|
|
|
private void ReadJson(string schemeContentJson)
|
|
|
|
|
{
|
|
|
|
|
ChildNodes = new List<FlowChild>();
|
|
|
|
|
ChildNodes = [];
|
|
|
|
|
|
|
|
|
|
var root = JsonConvert.DeserializeObject<FlowRoot>(schemeContentJson);
|
|
|
|
|
if (root.Type == FlowChild.START)
|
|
|
|
@ -177,8 +187,7 @@ public class FlowRuntime
|
|
|
|
|
// var childs = new List<FlowChild>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<FlowChild> GetFlowConditions(FlowChild parent)
|
|
|
|
|
private static List<FlowChild> GetFlowConditions(FlowChild parent)
|
|
|
|
|
{
|
|
|
|
|
var conditionNodes = new List<FlowChild>();
|
|
|
|
|
if (parent.Children != null)
|
|
|
|
@ -192,16 +201,15 @@ public class FlowRuntime
|
|
|
|
|
return conditionNodes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取下一个节点
|
|
|
|
|
/// <param name="nodeId"></param>
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string? GetNextNodeId(string nodeId = null)
|
|
|
|
|
private string? GetNextNodeId(string? nodeId = null)
|
|
|
|
|
{
|
|
|
|
|
if (nodeId == null)
|
|
|
|
|
{
|
|
|
|
|
return ChildNodes.Where(x => x.Pid == "root").First().Id;
|
|
|
|
|
return ChildNodes.Where(x => x.Pid == "root").First()?.Id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -219,7 +227,7 @@ public class FlowRuntime
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return ChildNodes.Where(x => x.Id == "end").First().Id;
|
|
|
|
|
return ChildNodes.Where(x => x.Id == "end").First()?.Id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -233,15 +241,30 @@ public class FlowRuntime
|
|
|
|
|
{
|
|
|
|
|
var conditionNodes = GetFlowConditions(parent);
|
|
|
|
|
var conditionId = string.Empty;
|
|
|
|
|
ISqlSugarClient sugarClient = tenantDb ?? db;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < conditionNodes.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var conditionNode = conditionNodes[i];
|
|
|
|
|
|
|
|
|
|
if (i == conditionNodes.Count - 1)
|
|
|
|
|
{
|
|
|
|
|
conditionId = conditionNodes[i].Id;
|
|
|
|
|
conditionId = conditionNode.Id;
|
|
|
|
|
}
|
|
|
|
|
else if (conditionNode.UseSQL)
|
|
|
|
|
{
|
|
|
|
|
var scalar = sugarClient.Ado.GetScalar(conditionNode.SQLText,
|
|
|
|
|
new SugarParameter(nameof(BaseModel<long>.Id), BusinessId));
|
|
|
|
|
|
|
|
|
|
if (scalar != null && (scalar is int count && count > 0 || scalar is bool boolValue && boolValue))
|
|
|
|
|
{
|
|
|
|
|
conditionId = conditionNode.Id;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var nodeSection = conditionNodes[i].Conditions;
|
|
|
|
|
var nodeSection = conditionNode.Conditions;
|
|
|
|
|
var list = new List<ConditionalCollections>();
|
|
|
|
|
var conditionList = new List<KeyValuePair<WhereType, ConditionalModel>>(nodeSection.Conditions.Count);
|
|
|
|
|
|
|
|
|
@ -297,15 +320,11 @@ public class FlowRuntime
|
|
|
|
|
if (list.Count == 0) //跳过默认条件
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
//string json = JsonConvert.SerializeObject(list);
|
|
|
|
|
//db.Utilities.JsonToConditionalModels(json);
|
|
|
|
|
List<IConditionalModel> conditionalModels = [.. list];
|
|
|
|
|
|
|
|
|
|
ISqlSugarClient sugarClient = tenantDb ?? db;
|
|
|
|
|
List<IConditionalModel> conditionalModels = [.. list];
|
|
|
|
|
var exists = sugarClient.Queryable<object>().AS(ColumnView).Where("Id=@Id", new { Id = BusinessId }).Where(conditionalModels).Any();
|
|
|
|
|
if (exists)
|
|
|
|
|
{
|
|
|
|
|
conditionId = conditionNodes[i].Id;
|
|
|
|
|
conditionId = conditionNode.Id;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -350,7 +369,6 @@ public class FlowRuntime
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转换FlowRoot
|
|
|
|
|
/// </summary>
|
|
|
|
@ -431,6 +449,7 @@ public class FlowRuntime
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转换SqlSugar 条件操作符
|
|
|
|
|
/// </summary>
|
|
|
|
@ -438,37 +457,29 @@ public class FlowRuntime
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static ConditionalType GetConditionalType(string conditionalType)
|
|
|
|
|
{
|
|
|
|
|
switch (conditionalType)
|
|
|
|
|
return conditionalType switch
|
|
|
|
|
{
|
|
|
|
|
//等于
|
|
|
|
|
case "equal":
|
|
|
|
|
return ConditionalType.Equal;
|
|
|
|
|
"equal" => ConditionalType.Equal,
|
|
|
|
|
//不等于
|
|
|
|
|
case "not_equal":
|
|
|
|
|
return ConditionalType.NoEqual;
|
|
|
|
|
"not_equal" => ConditionalType.NoEqual,
|
|
|
|
|
//大于
|
|
|
|
|
case "GreaterThan":
|
|
|
|
|
return ConditionalType.GreaterThan;
|
|
|
|
|
"GreaterThan" => ConditionalType.GreaterThan,
|
|
|
|
|
//大于等于
|
|
|
|
|
case "GreaterThanOrEqual":
|
|
|
|
|
return ConditionalType.GreaterThanOrEqual;
|
|
|
|
|
"GreaterThanOrEqual" => ConditionalType.GreaterThanOrEqual,
|
|
|
|
|
//小于
|
|
|
|
|
case "LessThan":
|
|
|
|
|
return ConditionalType.LessThan;
|
|
|
|
|
"LessThan" => ConditionalType.LessThan,
|
|
|
|
|
//小于等于
|
|
|
|
|
case "LessThanOrEqual":
|
|
|
|
|
return ConditionalType.GreaterThanOrEqual;
|
|
|
|
|
"LessThanOrEqual" => ConditionalType.GreaterThanOrEqual,
|
|
|
|
|
//包含
|
|
|
|
|
case "contains":
|
|
|
|
|
return ConditionalType.In;
|
|
|
|
|
"contains" => ConditionalType.In,
|
|
|
|
|
//不包含
|
|
|
|
|
case "not_contain":
|
|
|
|
|
return ConditionalType.NotIn;
|
|
|
|
|
"not_contain" => ConditionalType.NotIn,
|
|
|
|
|
//默认
|
|
|
|
|
default:
|
|
|
|
|
return ConditionalType.Equal;
|
|
|
|
|
}
|
|
|
|
|
_ => ConditionalType.Equal,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取节点类型 0会签开始,1会签结束,2一般节点,3开始节点,4流程运行结束
|
|
|
|
|
/// </summary>
|
|
|
|
@ -476,39 +487,23 @@ public class FlowRuntime
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public int GetNodeType(string nodeId)
|
|
|
|
|
{
|
|
|
|
|
switch (ChildNodes.Where(x => x.Id == nodeId).First().Type)
|
|
|
|
|
return ChildNodes.Where(x => x.Id == nodeId).First().Type switch
|
|
|
|
|
{
|
|
|
|
|
//会签开始节点
|
|
|
|
|
case FlowChild.Approval:
|
|
|
|
|
return 0;
|
|
|
|
|
FlowChild.Approval => 0,
|
|
|
|
|
//会签结束节点
|
|
|
|
|
case FlowChild.JOIN:
|
|
|
|
|
return 1;
|
|
|
|
|
FlowChild.JOIN => 1,
|
|
|
|
|
//结束节点
|
|
|
|
|
case FlowChild.END:
|
|
|
|
|
return 4;
|
|
|
|
|
FlowChild.END => 4,
|
|
|
|
|
//开始节点
|
|
|
|
|
case FlowChild.START:
|
|
|
|
|
return 3;
|
|
|
|
|
FlowChild.START => 3,
|
|
|
|
|
//互斥条件
|
|
|
|
|
FlowChild.Exclusive => 5,
|
|
|
|
|
//互斥条件
|
|
|
|
|
case FlowChild.Exclusive:
|
|
|
|
|
return 5;
|
|
|
|
|
FlowChild.Dynamic => 6,
|
|
|
|
|
//一般节点
|
|
|
|
|
default:
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取上一个节点
|
|
|
|
|
private FlowChild GetPreNode(string nodeId = null)
|
|
|
|
|
{
|
|
|
|
|
var child = ChildNodes.Where(x => x.Pid == nodeId).First();
|
|
|
|
|
if (child.IsNull())
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("无法找到上一个点");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return child;
|
|
|
|
|
_ => 2,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|