|
|
|
|
using DS.Module.Core.Extensions;
|
|
|
|
|
using DS.Module.UserModule;
|
|
|
|
|
using DS.WMS.Core.Flow.Dtos;
|
|
|
|
|
using DS.WMS.Core.Flow.Entity;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
|
|
|
|
|
namespace DS.WMS.Core.Flow.Method;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class FlowRuntime
|
|
|
|
|
{
|
|
|
|
|
public FlowRuntime(FlowInstance instance, ISqlSugarClient _db) : this(instance, _db, null, null)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 构造函数
|
|
|
|
|
/// </summary>
|
|
|
|
|
public FlowRuntime(FlowInstance instance, ISqlSugarClient _db, ISqlSugarClient tenantDb, IUser user)
|
|
|
|
|
{
|
|
|
|
|
db = _db;
|
|
|
|
|
BusinessId = instance.BusinessId;
|
|
|
|
|
ColumnView = instance.ColumnView;
|
|
|
|
|
this.tenantDb = tenantDb;
|
|
|
|
|
this.user = user;
|
|
|
|
|
|
|
|
|
|
InitNodes(instance.Content); //获取工作流模板内容的json对象;
|
|
|
|
|
|
|
|
|
|
CurrentNodeId = instance.ActivityId == "" ? StartNodeId : instance.ActivityId;
|
|
|
|
|
CurrentNodeType = GetNodeType(CurrentNodeId);
|
|
|
|
|
|
|
|
|
|
// ti = schemeContentJson.title;
|
|
|
|
|
// initNum = schemeContentJson.initNum?? 0;
|
|
|
|
|
PreviousId = instance.PreviousId;
|
|
|
|
|
FlowInstanceId = instance.Id;
|
|
|
|
|
|
|
|
|
|
//会签开始节点和流程结束节点没有下一步
|
|
|
|
|
if (CurrentNodeType == 0 || CurrentNodeType == 4)
|
|
|
|
|
{
|
|
|
|
|
NextNodeId = "-1";
|
|
|
|
|
NextNodeType = -1;
|
|
|
|
|
}
|
|
|
|
|
else if (CurrentNodeType == 5)
|
|
|
|
|
{
|
|
|
|
|
NextNodeId = GetNextConditionNodeId(CurrentNode); //下一个节点
|
|
|
|
|
NextNodeType = GetNodeType(NextNodeId);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NextNodeId = GetNextNodeId(CurrentNodeId); //下一个节点
|
|
|
|
|
NextNodeType = GetNodeType(NextNodeId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public long BusinessId { get; set; }
|
|
|
|
|
public string ColumnView { get; set; }
|
|
|
|
|
public ISqlSugarClient db { get; set; }
|
|
|
|
|
public ISqlSugarClient tenantDb { get; set; }
|
|
|
|
|
public IUser user { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
|
|
|
|
public int initNum { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 运行实例的Id
|
|
|
|
|
/// </summary>
|
|
|
|
|
public long FlowInstanceId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 开始节点的ID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string StartNodeId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前节点的ID
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string CurrentNodeId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int CurrentNodeType { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 当前节点的对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
public FlowChild CurrentNode => ChildNodes.First(x => x.Id == CurrentNodeId);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 下一个节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string NextNodeId { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 下一个节点类型 -1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束,5同级审批
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int NextNodeType { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 下一个节点对象
|
|
|
|
|
/// </summary>
|
|
|
|
|
public FlowChild? NextNode => NextNodeId != "-1" ? ChildNodes.First(x => x.Id == NextNodeId) : null;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 上一个节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PreviousId { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 实例节点集合
|
|
|
|
|
/// </summary>
|
|
|
|
|
public List<FlowChild> ChildNodes { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取工作流节点的字典列表:key节点id
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="schemeContentJson"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private void InitNodes(string schemeContentJson)
|
|
|
|
|
{
|
|
|
|
|
ChildNodes = new List<FlowChild>();
|
|
|
|
|
|
|
|
|
|
var root = JsonConvert.DeserializeObject<FlowRoot>(schemeContentJson);
|
|
|
|
|
if (root.Type == FlowChild.START)
|
|
|
|
|
{
|
|
|
|
|
this.StartNodeId = root.Id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (root.Child.IsNotNull())
|
|
|
|
|
{
|
|
|
|
|
var parent = root.Adapt<FlowChild>();
|
|
|
|
|
ChildNodes.Add(parent);
|
|
|
|
|
GetFlowChildsByParent(parent.Id, parent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 撤销流程,清空所有节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Cancel()
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
item.SetInfo = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GetFlowChildsByParent(string nodeId, FlowChild parent)
|
|
|
|
|
{
|
|
|
|
|
if (parent.Type == FlowChild.Exclusive && parent.Children.IsNotNull() && parent.Children.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in parent.Children)
|
|
|
|
|
{
|
|
|
|
|
ChildNodes.Add(item);
|
|
|
|
|
GetFlowChildsByParent(nodeId, item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parent.Child.IsNotNull())
|
|
|
|
|
{
|
|
|
|
|
ChildNodes.Add(parent.Child);
|
|
|
|
|
GetFlowChildsByParent(parent.Child.Id, parent.Child);
|
|
|
|
|
}
|
|
|
|
|
// var childs = new List<FlowChild>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<FlowChild> GetFlowConditions(FlowChild parent)
|
|
|
|
|
{
|
|
|
|
|
var conditionNodes = new List<FlowChild>();
|
|
|
|
|
if (parent.Children != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in parent.Children)
|
|
|
|
|
{
|
|
|
|
|
conditionNodes.Add(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return conditionNodes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取下一个节点
|
|
|
|
|
/// <param name="nodeId"></param>
|
|
|
|
|
/// </summary>
|
|
|
|
|
private string GetNextNodeId(string nodeId = null)
|
|
|
|
|
{
|
|
|
|
|
if (nodeId == null)
|
|
|
|
|
{
|
|
|
|
|
return ChildNodes.Where(x => x.Pid == "root").First().Id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (ChildNodes.Exists(x => x.Pid == nodeId))
|
|
|
|
|
{
|
|
|
|
|
var nextChild = ChildNodes.Where(x => x.Pid == nodeId).First();
|
|
|
|
|
if (nextChild.Type == FlowChild.Exclusive) //互斥条件
|
|
|
|
|
{
|
|
|
|
|
return GetNextConditionNodeId(nextChild); //下一个节点
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return nextChild.Id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return ChildNodes.Where(x => x.Id == "end").First().Id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// return ChildNodes.Where(x => x.Pid == nodeId).First().Id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取下一个条件节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="parent"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public string GetNextConditionNodeId(FlowChild parent)
|
|
|
|
|
{
|
|
|
|
|
var conditionNodes = GetFlowConditions(parent);
|
|
|
|
|
string? conditionId = null;
|
|
|
|
|
if (conditionNodes.Count == 1)
|
|
|
|
|
conditionId = conditionNodes[0].Id;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < conditionNodes.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var conditions = conditionNodes[i].Conditions;
|
|
|
|
|
var conditionalCollections = new List<ConditionalCollections>();
|
|
|
|
|
if (conditions.LogicalOperator == "and")
|
|
|
|
|
{
|
|
|
|
|
var conditionList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
|
|
foreach (var item in conditions.Conditions)
|
|
|
|
|
{
|
|
|
|
|
conditionList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
|
|
(WhereType.And,
|
|
|
|
|
new ConditionalModel
|
|
|
|
|
{
|
|
|
|
|
FieldName = item.Field,
|
|
|
|
|
ConditionalType = GetConditionalType(item.Operator),
|
|
|
|
|
FieldValue = item.Value
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (conditionList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
|
|
{
|
|
|
|
|
ConditionalList = conditionList
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var groupList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
|
|
foreach (var group in conditions.Groups)
|
|
|
|
|
{
|
|
|
|
|
if (group.LogicalOperator == "and")
|
|
|
|
|
{
|
|
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
|
|
{
|
|
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
|
|
(WhereType.And,
|
|
|
|
|
new ConditionalModel
|
|
|
|
|
{
|
|
|
|
|
FieldName = item1.Field,
|
|
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
|
|
FieldValue = item1.Value
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
|
|
{
|
|
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
|
|
(WhereType.Or,
|
|
|
|
|
new ConditionalModel
|
|
|
|
|
{
|
|
|
|
|
FieldName = item1.Field,
|
|
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
|
|
FieldValue = item1.Value
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (groupList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
|
|
{
|
|
|
|
|
ConditionalList = groupList
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var conditionList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
|
|
foreach (var item in conditions.Conditions)
|
|
|
|
|
{
|
|
|
|
|
conditionList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
|
|
(WhereType.Or,
|
|
|
|
|
new ConditionalModel
|
|
|
|
|
{
|
|
|
|
|
FieldName = item.Field,
|
|
|
|
|
ConditionalType = GetConditionalType(item.Operator),
|
|
|
|
|
FieldValue = item.Value
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (conditionList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
|
|
{
|
|
|
|
|
ConditionalList = conditionList
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var groupList = new List<KeyValuePair<WhereType, ConditionalModel>>();
|
|
|
|
|
foreach (var group in conditions.Groups)
|
|
|
|
|
{
|
|
|
|
|
if (group.LogicalOperator == "and")
|
|
|
|
|
{
|
|
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
|
|
{
|
|
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
|
|
(WhereType.And,
|
|
|
|
|
new ConditionalModel
|
|
|
|
|
{
|
|
|
|
|
FieldName = item1.Field,
|
|
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
|
|
FieldValue = item1.Value
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var item1 in group.Conditions)
|
|
|
|
|
{
|
|
|
|
|
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
|
|
|
|
|
(WhereType.Or,
|
|
|
|
|
new ConditionalModel
|
|
|
|
|
{
|
|
|
|
|
FieldName = item1.Field,
|
|
|
|
|
ConditionalType = GetConditionalType(item1.Operator),
|
|
|
|
|
FieldValue = item1.Value
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (groupList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
conditionalCollections.Add(new ConditionalCollections
|
|
|
|
|
{
|
|
|
|
|
ConditionalList = groupList
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var conditionalModels = db.ConfigQuery.Context.Utilities.JsonToConditionalModels(JsonConvert.SerializeObject(conditionalCollections));
|
|
|
|
|
if (conditionalModels.Count == 0) //跳过默认条件
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
ISqlSugarClient sugarClient = tenantDb ?? db;
|
|
|
|
|
var exists = sugarClient.Queryable<object>().AS(ColumnView).Where("Id=@Id", new { Id = BusinessId }).Where(conditionalModels).Any();
|
|
|
|
|
if (exists)
|
|
|
|
|
{
|
|
|
|
|
conditionId = conditionNodes[i].Id;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ChildNodes.Where(x => x.Pid == conditionId).First().Id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取下一个节点
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nodeId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public FlowChild GetNextNode(string nodeId = null)
|
|
|
|
|
{
|
|
|
|
|
if (nodeId == null)
|
|
|
|
|
{
|
|
|
|
|
return ChildNodes.Where(x => x.Pid == "root").First();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (ChildNodes.Exists(x => x.Pid == nodeId))
|
|
|
|
|
{
|
|
|
|
|
var nextChild = ChildNodes.Where(x => x.Pid == nodeId).First();
|
|
|
|
|
if (nextChild.Type == FlowChild.Exclusive)
|
|
|
|
|
{
|
|
|
|
|
var childId = GetNextConditionNodeId(nextChild);
|
|
|
|
|
return ChildNodes.Where(x => x.Id == childId).First(); //下一个节点
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nextChild;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return ChildNodes.Where(x => x.Id == "end").First();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转换FlowRoot
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public FlowRoot ToFlowRoot()
|
|
|
|
|
{
|
|
|
|
|
var root = ChildNodes.First(x => x.Id == "root");
|
|
|
|
|
|
|
|
|
|
var list = ChildNodes.Where(x => x.Id != "root").ToList();
|
|
|
|
|
var info = root.Adapt<FlowRoot>();
|
|
|
|
|
info.Child = list.First(x => x.Pid == "root");
|
|
|
|
|
UpdateChild(info.Child);
|
|
|
|
|
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateChild(FlowChild parent)
|
|
|
|
|
{
|
|
|
|
|
if (parent.Type == FlowChild.Exclusive)
|
|
|
|
|
{
|
|
|
|
|
if (ChildNodes.Exists(x => x.Pid == parent.Id && x.Type != "condition"))
|
|
|
|
|
{
|
|
|
|
|
var child = ChildNodes.Where(x => x.Pid == parent.Id && x.Type != "condition").First();
|
|
|
|
|
parent.Child = child;
|
|
|
|
|
UpdateChild(child);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var childs = ChildNodes.Where(x => x.Pid == parent.Id && x.Type == "condition").ToList();
|
|
|
|
|
parent.Children = childs;
|
|
|
|
|
foreach (var item in childs)
|
|
|
|
|
{
|
|
|
|
|
UpdateChild(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (parent.Type != FlowChild.Exclusive && ChildNodes.Exists(x => x.Pid == parent.Id))
|
|
|
|
|
{
|
|
|
|
|
var child = ChildNodes.Where(x => x.Pid == parent.Id).First();
|
|
|
|
|
parent.Child = child;
|
|
|
|
|
UpdateChild(parent.Child);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateFlowChild(string nodeId, FlowChild parent)
|
|
|
|
|
{
|
|
|
|
|
// var childs = new List<FlowChild>();
|
|
|
|
|
if (parent.Type == FlowChild.Exclusive && parent.Children.IsNotNull() && parent.Children.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < parent.Children.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (parent.Children[0].Id == nodeId)
|
|
|
|
|
{
|
|
|
|
|
var newNode = ChildNodes.First(x => x.Id == nodeId);
|
|
|
|
|
parent.Children[0] = newNode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parent.Child.IsNotNull())
|
|
|
|
|
{
|
|
|
|
|
if (parent.Child.Id == nodeId)
|
|
|
|
|
{
|
|
|
|
|
var newNode = ChildNodes.First(x => x.Id == nodeId);
|
|
|
|
|
parent.Child = newNode;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取实例接下来运行的状态
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>-1无法运行,0开始,1结束,2一般节点,4流程运行结束</returns>
|
|
|
|
|
public int GetNextNodeType()
|
|
|
|
|
{
|
|
|
|
|
if (NextNodeId != "-1")
|
|
|
|
|
{
|
|
|
|
|
return GetNodeType(NextNodeId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 转换SqlSugar 条件操作符
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="conditionalType"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static ConditionalType GetConditionalType(string conditionalType)
|
|
|
|
|
{
|
|
|
|
|
switch (conditionalType)
|
|
|
|
|
{
|
|
|
|
|
//等于
|
|
|
|
|
case "equal":
|
|
|
|
|
return ConditionalType.Equal;
|
|
|
|
|
//不等于
|
|
|
|
|
case "not_equal":
|
|
|
|
|
return ConditionalType.NoEqual;
|
|
|
|
|
//大于
|
|
|
|
|
case "GreaterThan":
|
|
|
|
|
return ConditionalType.GreaterThan;
|
|
|
|
|
//大于等于
|
|
|
|
|
case "GreaterThanOrEqual":
|
|
|
|
|
return ConditionalType.GreaterThanOrEqual;
|
|
|
|
|
//小于
|
|
|
|
|
case "LessThan":
|
|
|
|
|
return ConditionalType.LessThan;
|
|
|
|
|
//小于等于
|
|
|
|
|
case "LessThanOrEqual":
|
|
|
|
|
return ConditionalType.GreaterThanOrEqual;
|
|
|
|
|
//包含
|
|
|
|
|
case "contains":
|
|
|
|
|
return ConditionalType.In;
|
|
|
|
|
//不包含
|
|
|
|
|
case "not_contain":
|
|
|
|
|
return ConditionalType.NotIn;
|
|
|
|
|
//默认
|
|
|
|
|
default:
|
|
|
|
|
return ConditionalType.Equal;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取节点类型 0会签开始,1会签结束,2一般节点,3开始节点,4流程运行结束
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nodeId"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public int GetNodeType(string nodeId)
|
|
|
|
|
{
|
|
|
|
|
switch (ChildNodes.Where(x => x.Id == nodeId).First().Type)
|
|
|
|
|
{
|
|
|
|
|
//会签开始节点
|
|
|
|
|
case FlowChild.Approval:
|
|
|
|
|
return 0;
|
|
|
|
|
//会签结束节点
|
|
|
|
|
case FlowChild.JOIN:
|
|
|
|
|
return 1;
|
|
|
|
|
//结束节点
|
|
|
|
|
case FlowChild.END:
|
|
|
|
|
return 4;
|
|
|
|
|
//开始节点
|
|
|
|
|
case FlowChild.START:
|
|
|
|
|
return 3;
|
|
|
|
|
//互斥条件
|
|
|
|
|
case FlowChild.Exclusive:
|
|
|
|
|
return 5;
|
|
|
|
|
//一般节点
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 驳回
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="rejectType">驳回类型。null:使用节点配置的驳回类型/0:前一步/1:第一步/2:指定节点,使用NodeRejectStep</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public string RejectNode(string rejectType)
|
|
|
|
|
{
|
|
|
|
|
var node = ChildNodes.Where(x => x.Id == CurrentNodeId).First();
|
|
|
|
|
if (node.SetInfo != null && string.IsNullOrEmpty(rejectType))
|
|
|
|
|
{
|
|
|
|
|
rejectType = node.SetInfo.NodeRejectType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rejectType == "0")
|
|
|
|
|
{
|
|
|
|
|
return PreviousId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rejectType == "1")
|
|
|
|
|
{
|
|
|
|
|
return GetNextNodeId(StartNodeId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PreviousId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///<summary>
|
|
|
|
|
/// 标记节点 1通过,2不通过,3驳回
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nodeId"></param>
|
|
|
|
|
public void MakeTagNode(string nodeId, FlowTag tag)
|
|
|
|
|
{
|
|
|
|
|
// var node = ChildNodes.First(x => x.Id == nodeId);
|
|
|
|
|
foreach (var item in ChildNodes)
|
|
|
|
|
{
|
|
|
|
|
if (item.Id == nodeId)
|
|
|
|
|
{
|
|
|
|
|
if (item.SetInfo == null)
|
|
|
|
|
{
|
|
|
|
|
item.SetInfo = new Setinfo();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item.SetInfo.Taged = tag.Taged;
|
|
|
|
|
item.SetInfo.UserId = tag.UserId;
|
|
|
|
|
item.SetInfo.UserName = tag.UserName;
|
|
|
|
|
item.SetInfo.Description = tag.Description;
|
|
|
|
|
item.SetInfo.TagedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 节点审核
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nodeId">会签时,currentNodeId是会签开始节点。这个表示当前正在处理的节点</param>
|
|
|
|
|
/// <param name="tag">节点标签</param>
|
|
|
|
|
/// <returns>-1不通过,1等待,其它通过</returns>
|
|
|
|
|
public string NodeConfluence(string nodeId, FlowTag tag)
|
|
|
|
|
{
|
|
|
|
|
var forkNode = ChildNodes.First(x => x.Id == CurrentNodeId); //会签开始节点
|
|
|
|
|
FlowChild nextNode = GetNextNode(nodeId); //获取当前处理的下一个节点
|
|
|
|
|
int forkNumber = 0;
|
|
|
|
|
if (forkNode.AssigneeType == "user")
|
|
|
|
|
{
|
|
|
|
|
forkNumber = forkNode.Users.Count;
|
|
|
|
|
}
|
|
|
|
|
else if (forkNode.AssigneeType == "role")
|
|
|
|
|
{
|
|
|
|
|
forkNumber = forkNode.Roles.Count;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
forkNumber = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// int forkNumber = FromNodeLines[currentNodeId].Count; //直接与会签节点连接的点,即会签分支数目
|
|
|
|
|
string res = string.Empty; //记录会签的结果,默认正在会签
|
|
|
|
|
//或签
|
|
|
|
|
if (forkNode.Multi == "single") //有一个步骤通过即可
|
|
|
|
|
{
|
|
|
|
|
if (tag.Taged == (int)TagState.Ok)
|
|
|
|
|
{
|
|
|
|
|
res = nextNode.Id;
|
|
|
|
|
}
|
|
|
|
|
else if (tag.Taged == (int)TagState.No)
|
|
|
|
|
{
|
|
|
|
|
if (forkNode.SetInfo.ConfluenceNo == null)
|
|
|
|
|
{
|
|
|
|
|
forkNode.SetInfo.ConfluenceNo = 1;
|
|
|
|
|
if (forkNode.SetInfo.ConfluenceNo == forkNumber)
|
|
|
|
|
{
|
|
|
|
|
res = TagState.No.ToString("D");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (forkNode.SetInfo.ConfluenceNo == (forkNumber - 1))
|
|
|
|
|
{
|
|
|
|
|
res = TagState.No.ToString("D");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
forkNode.SetInfo.ConfluenceNo++;
|
|
|
|
|
// bool isFirst = true; //是不是从会签开始到现在第一个
|
|
|
|
|
// var preNode = GetPreNode(nodeId);
|
|
|
|
|
// while (preNode.id != forkNode.id) //反向一直到会签开始节点
|
|
|
|
|
// {
|
|
|
|
|
// if (preNode.setInfo != null && preNode.setInfo.Taged == (int) TagState.No)
|
|
|
|
|
// {
|
|
|
|
|
// isFirst = false;
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// if (isFirst)
|
|
|
|
|
// {
|
|
|
|
|
// forkNode.SetInfo.ConfluenceNo++;
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//会签
|
|
|
|
|
else //默认所有步骤通过
|
|
|
|
|
{
|
|
|
|
|
if (tag.Taged == (int)TagState.No) //只要有一个不同意,那么流程就结束
|
|
|
|
|
{
|
|
|
|
|
res = TagState.No.ToString("D");
|
|
|
|
|
}
|
|
|
|
|
else if (tag.Taged == (int)TagState.Ok)
|
|
|
|
|
{
|
|
|
|
|
//这种模式下只有坚持到【会签结束】节点之前才有意义,是否需要判定这条线所有的节点都通过,不然直接执行这个节点??
|
|
|
|
|
if (forkNode.SetInfo.ConfluenceOk == null)
|
|
|
|
|
{
|
|
|
|
|
forkNode.SetInfo.ConfluenceOk = 1;
|
|
|
|
|
|
|
|
|
|
if (forkNode.SetInfo.ConfluenceOk == forkNumber)
|
|
|
|
|
{
|
|
|
|
|
res = nextNode.Id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//同一节点的会签,未达到所有审核人同意时,节点类型设置为5
|
|
|
|
|
NextNodeType = 5;
|
|
|
|
|
res = nodeId;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
forkNode.SetInfo.ConfluenceOk++;
|
|
|
|
|
|
|
|
|
|
if (forkNode.SetInfo.ConfluenceOk == forkNumber) //会签成功
|
|
|
|
|
{
|
|
|
|
|
res = nextNode.Id;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//同一节点的会签,未达到所有审核人同意时,节点类型设置为5
|
|
|
|
|
NextNodeType = 5;
|
|
|
|
|
res = nodeId;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (res == TagState.No.ToString("D"))
|
|
|
|
|
{
|
|
|
|
|
tag.Taged = (int)TagState.No;
|
|
|
|
|
MakeTagNode(nextNode.Id, tag);
|
|
|
|
|
NextNodeId = nextNode.Id;
|
|
|
|
|
NextNodeType = GetNodeType(nextNode.Id);
|
|
|
|
|
}
|
|
|
|
|
else if (!string.IsNullOrEmpty(res)) //会签结束,标记合流节点
|
|
|
|
|
{
|
|
|
|
|
tag.Taged = (int)TagState.Ok;
|
|
|
|
|
// MakeTagNode(nextNode.Id, tag);
|
|
|
|
|
NextNodeId = res;
|
|
|
|
|
NextNodeType = GetNodeType(res);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NextNodeId = nextNode.Id;
|
|
|
|
|
NextNodeType = GetNodeType(nextNode.Id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal string GetOtherUsers(FlowTag tag)
|
|
|
|
|
{
|
|
|
|
|
var forkNode = ChildNodes.First(x => x.Id == CurrentNodeId);
|
|
|
|
|
//int index = forkNode.Users.IndexOf(tag.UserId);
|
|
|
|
|
//if (index > -1 && index <= forkNode.Users.Count - 2)
|
|
|
|
|
// return forkNode.Users[index + 1];
|
|
|
|
|
|
|
|
|
|
if (!forkNode.Users.IsNullOrEmpty())
|
|
|
|
|
{
|
|
|
|
|
return string.Join(',',
|
|
|
|
|
forkNode.Users.Except([tag.UserId]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
}
|
|
|
|
|
}
|