You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

708 lines
23 KiB
C#

10 months ago
using DS.Module.Core.Extensions;
using DS.WMS.Core.Flow.Dtos;
using DS.WMS.Core.Flow.Entity;
using DS.WMS.Core.System.Entity;
10 months ago
using LanguageExt;
using Mapster;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SqlSugar;
10 months ago
namespace DS.WMS.Core.Flow.Method;
/// <summary>
///
/// </summary>
10 months ago
public class FlowRuntimeService
{
/// <summary>
/// 构造函数
/// </summary>
public FlowRuntimeService(FlowInstance instance, ISqlSugarClient _db)
{
db = _db;
BusinessId = instance.BusinessId;
ColumnView = instance.ColumnView;
InitNodes(instance.Content); //获取工作流模板内容的json对象;
10 months ago
CurrentNodeId = (instance.ActivityId == "" ? StartNodeId : instance.ActivityId);
CurrentNodeType = GetNodeType(CurrentNodeId);
10 months ago
// ti = schemeContentJson.title;
// initNum = schemeContentJson.initNum?? 0;
PreviousId = instance.PreviousId;
FlowInstanceId = instance.Id;
//会签开始节点和流程结束节点没有下一步
if (CurrentNodeType == 0 || CurrentNodeType == 4)
10 months ago
{
NextNodeId = "-1";
NextNodeType = -1;
}
else if (CurrentNodeType == 5)
{
NextNodeId = GetNextConditionNodeId(CurrentNode); //下一个节点
NextNodeType = GetNodeType(NextNodeId);
}
10 months ago
else
{
NextNodeId = GetNextNodeId(CurrentNodeId); //下一个节点
10 months ago
NextNodeType = GetNodeType(NextNodeId);
}
}
public long BusinessId { get; set; }
public string ColumnView { get; set; }
public ISqlSugarClient db { get; set; }
10 months ago
/// <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);
10 months ago
/// <summary>
/// 下一个节点
/// </summary>
public string NextNodeId { get; set; }
/// <summary>
/// 下一个节点类型 -1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束
/// </summary>
/// <value>The type of the next node.</value>
public int NextNodeType { get; set; }
/// <summary>
/// 下一个节点对象
/// </summary>
public FlowChild NextNode => NextNodeId != "-1" ? ChildNodes.First(x => x.Id == NextNodeId) : null;
10 months ago
/// <summary>
/// 上一个节点
/// </summary>
public string PreviousId { get; set; }
10 months ago
/// <summary>
/// 实例节点集合
/// </summary>
public List<FlowChild> ChildNodes { get; set; }
10 months ago
/// <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())
{
10 months ago
var parent = root.Adapt<FlowChild>();
ChildNodes.Add(parent);
GetFlowChildsByParent(parent.Id, parent);
10 months ago
}
}
/// <summary>
/// 撤销流程,清空所有节点
/// </summary>
public void Cancel()
{
foreach (var item in ChildNodes)
{
item.SetInfo = null;
}
}
private void GetFlowChildsByParent(string nodeId, FlowChild parent)
10 months ago
{
if (parent.Type == FlowChild.Exclusive && parent.Children.IsNotNull() && parent.Children.Count > 0)
{
foreach (var item in parent.Children)
10 months ago
{
ChildNodes.Add(item);
10 months ago
GetFlowChildsByParent(nodeId, item);
}
}
if (parent.Child.IsNotNull())
{
10 months ago
ChildNodes.Add(parent.Child);
GetFlowChildsByParent(parent.Child.Id, parent.Child);
10 months ago
}
// var childs = new List<FlowChild>();
10 months ago
}
10 months ago
private List<FlowChild> GetFlowConditions(FlowChild parent)
{
var conditionNodes = new List<FlowChild>();
foreach (var item in parent.Children)
10 months ago
{
conditionNodes.Add(item);
}
10 months ago
return conditionNodes;
}
10 months ago
10 months ago
/// <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);
var conditionId = string.Empty;
for (int i = 0; i < conditionNodes.Count; i++)
{
if (i == conditionNodes.Count - 1)
{
// return ChildNodes.Where(x => x.Pid == conditionNodes[i].Id).First().Id;
conditionId = conditionNodes[i].Id;
}
else
10 months ago
{
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 = ConditionalType.Equal,
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 = ConditionalType.Equal,
FieldValue = item1.Value
})
);
}
}
else
{
foreach (var item1 in group.Conditions)
{
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
(WhereType.Or,
new ConditionalModel
{
FieldName = item1.Field, ConditionalType = ConditionalType.Equal,
FieldValue = item1.Value
})
);
}
}
}
if (groupList.Count > 0)
{
conditionalCollections.Add(new ConditionalCollections
{
ConditionalList = groupList
}
)
;
}
}
else
10 months ago
{
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 = ConditionalType.Equal,
FieldValue = item.Value
})
);
}
10 months ago
if (conditionList.Count > 0)
10 months ago
{
conditionalCollections.Add(new ConditionalCollections
{
ConditionalList = conditionList
}
)
;
10 months ago
}
var groupList = new List<KeyValuePair<WhereType, ConditionalModel>>();
foreach (var group in conditions.Groups)
10 months ago
{
if (group.LogicalOperator == "and")
{
foreach (var item1 in group.Conditions)
{
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
(WhereType.And,
new ConditionalModel
{
FieldName = item1.Field, ConditionalType = ConditionalType.Equal,
FieldValue = item1.Value
})
);
}
}
else
{
foreach (var item1 in group.Conditions)
{
groupList.Add(new KeyValuePair<WhereType, ConditionalModel>
(WhereType.Or,
new ConditionalModel
{
FieldName = item1.Field, ConditionalType = ConditionalType.Equal,
FieldValue = item1.Value
})
);
}
}
10 months ago
}
if (groupList.Count > 0)
{
conditionalCollections.Add(new ConditionalCollections
{
ConditionalList = groupList
}
)
;
}
}
// var table = ColumnView
var conditionalModels =
db.ConfigQuery.Context.Utilities.JsonToConditionalModels(
JsonConvert.SerializeObject(conditionalCollections));
var info = db.Queryable<SysUser>().Where(x => x.Id == BusinessId).Where(conditionalModels)
.First();
if (info.IsNotNull())
{
conditionId = conditionNodes[i].Id;
10 months ago
}
}
10 months ago
}
return ChildNodes.Where(x => x.Pid == conditionId).First().Id;
10 months ago
}
10 months ago
/// <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();
}
10 months ago
}
}
/// <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;
}
}
}
10 months ago
/// <summary>
/// 获取实例接下来运行的状态
/// </summary>
/// <returns>-1无法运行,0开始,1结束,2一般节点,4流程运行结束</returns>
public int GetNextNodeType()
{
if (NextNodeId != "-1")
{
return GetNodeType(NextNodeId);
}
10 months ago
return -1;
}
/// <summary>
/// 获取节点类型 0会签开始,1会签结束,2一般节点,3开始节点,4流程运行结束
10 months ago
/// </summary>
/// <param name="nodeId"></param>
/// <returns></returns>
public int GetNodeType(string nodeId)
{
switch (ChildNodes.Where(x => x.Id == nodeId).First().Type)
{
//会签开始节点
case FlowChild.Approval:
10 months ago
return 0;
10 months ago
//会签结束节点
case FlowChild.JOIN:
return 1;
10 months ago
//结束节点
case FlowChild.END:
return 4;
//开始节点
case FlowChild.START:
return 3;
//互斥条件
case FlowChild.Exclusive:
return 5;
10 months ago
default:
return 2;
}
}
10 months ago
//获取上一个节点
private FlowChild GetPreNode(string nodeId = null)
{
10 months ago
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();
10 months ago
if (node.SetInfo != null && string.IsNullOrEmpty(rejectType))
{
rejectType = node.SetInfo.NodeRejectType;
}
10 months ago
if (rejectType == "0")
{
return PreviousId;
}
10 months ago
if (rejectType == "1")
{
return GetNextNodeId(StartNodeId);
}
return PreviousId;
}
10 months ago
///<summary>
/// 标记节点 1通过-1不通过0驳回
/// </summary>
/// <param name="nodeId"></param>
public void MakeTagNode(string nodeId, FlowTag tag)
10 months ago
{
// var node = ChildNodes.First(x => x.Id == nodeId);
foreach (var item in ChildNodes)
10 months ago
{
if (item.Id == nodeId)
10 months ago
{
if (item.SetInfo == null)
10 months ago
{
item.SetInfo = new Setinfo();
10 months ago
}
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");
10 months ago
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;
}
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
{
forkNode.SetInfo.ConfluenceOk++;
}
}
}
if (res == TagState.No.ToString("D"))
{
tag.Taged = (int) TagState.No;
MakeTagNode(nextNode.Id, tag);
}
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;
}
10 months ago
}