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.

973 lines
34 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DS.Module.Core.Extensions;
using DS.Module.SqlSugar;
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, ISaasDbService saasService, IUser user)
{
db = _db;
BusinessId = instance.BusinessId;
ColumnView = instance.ColumnView;
this.saasService = saasService;
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 ISaasDbService saasService { 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>();
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 virtual 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
{
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));
// var info = db.Queryable<SysUser>().Where(x => x.Id == BusinessId).Where(conditionalModels)
// .First();
var info = db.Queryable<object>().AS(ColumnView).Where("Id=@Id", new { Id = BusinessId }).Where(conditionalModels).First();
if (info.IsNotNull())
{
conditionId = conditionNodes[i].Id;
}
}
}
return ChildNodes.Where(x => x.Pid == conditionId).First().Id;
}
public string GetClientNextConditionNodeId(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
{
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));
// var info = db.Queryable<SysUser>().Where(x => x.Id == BusinessId).Where(conditionalModels)
// .First();
var tentDb = saasService.GetBizDbScopeById(user.TenantId);
var info = tentDb.Queryable<object>().AS(ColumnView).Where("Id=@Id", new { Id = BusinessId }).Where(conditionalModels).First();
if (info.IsNotNull())
{
conditionId = conditionNodes[i].Id;
}
}
}
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;
}
}