fix issue #I96DAJ

This commit is contained in:
wintel 2024-03-06 21:55:21 +08:00
parent 627e5b0d2c
commit 8a1491eec7

View File

@ -1,486 +1,486 @@
// *********************************************************************** // ***********************************************************************
// Assembly : OpenAuth.App // Assembly : OpenAuth.App
// Author : 李玉宝 // Author : 李玉宝
// Created : 07-19-2018 // Created : 07-19-2018
// //
// Last Modified By : 李玉宝 // Last Modified By : 李玉宝
// Last Modified On : 07-19-2018 // Last Modified On : 07-19-2018
// *********************************************************************** // ***********************************************************************
// <copyright file="FlowRuntime.cs" company="OpenAuth.App"> // <copyright file="FlowRuntime.cs" company="OpenAuth.App">
// Copyright (c) http://www.openauth.net.cn. All rights reserved. // Copyright (c) http://www.openauth.net.cn. All rights reserved.
// </copyright> // </copyright>
// <summary> // <summary>
// 一个正在运行中的流程实例 // 一个正在运行中的流程实例
//</summary> //</summary>
// *********************************************************************** // ***********************************************************************
using Infrastructure; using Infrastructure;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using OpenAuth.Repository.Domain; using OpenAuth.Repository.Domain;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using Castle.Core.Internal; using Castle.Core.Internal;
namespace OpenAuth.App.Flow namespace OpenAuth.App.Flow
{ {
public class FlowRuntime public class FlowRuntime
{ {
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
/// </summary> /// </summary>
public FlowRuntime(FlowInstance instance) public FlowRuntime(FlowInstance instance)
{ {
dynamic schemeContentJson = instance.SchemeContent.ToJson();//获取工作流模板内容的json对象; dynamic schemeContentJson = instance.SchemeContent.ToJson();//获取工作流模板内容的json对象;
InitLines(schemeContentJson); InitLines(schemeContentJson);
InitNodes(schemeContentJson); InitNodes(schemeContentJson);
currentNodeId = (instance.ActivityId == "" ? startNodeId : instance.ActivityId); currentNodeId = (instance.ActivityId == "" ? startNodeId : instance.ActivityId);
currentNodeType = GetNodeType(currentNodeId); currentNodeType = GetNodeType(currentNodeId);
FrmData = instance.FrmData; FrmData = instance.FrmData;
title = schemeContentJson.title; title = schemeContentJson.title;
initNum = schemeContentJson.initNum?? 0; initNum = schemeContentJson.initNum?? 0;
previousId = instance.PreviousId; previousId = instance.PreviousId;
flowInstanceId = instance.Id; flowInstanceId = instance.Id;
//会签开始节点和流程结束节点没有下一步 //会签开始节点和流程结束节点没有下一步
if (currentNodeType == 0 || currentNodeType == 4) if (currentNodeType == 0 || currentNodeType == 4)
{ {
nextNodeId = "-1"; nextNodeId = "-1";
nextNodeType = -1; nextNodeType = -1;
} }
else else
{ {
nextNodeId = GetNextNodeId();//下一个节点 nextNodeId = GetNextNodeId();//下一个节点
nextNodeType = GetNodeType(nextNodeId); nextNodeType = GetNodeType(nextNodeId);
} }
} }
#region #region
/// <summary> /// <summary>
/// 获取工作流节点的字典列表:key节点id /// 获取工作流节点的字典列表:key节点id
/// </summary> /// </summary>
/// <param name="schemeContentJson"></param> /// <param name="schemeContentJson"></param>
/// <returns></returns> /// <returns></returns>
private void InitNodes(dynamic schemeContentJson) private void InitNodes(dynamic schemeContentJson)
{ {
Nodes = new Dictionary<string, FlowNode>(); Nodes = new Dictionary<string, FlowNode>();
foreach (JObject item in schemeContentJson.nodes) foreach (JObject item in schemeContentJson.nodes)
{ {
var node = item.ToObject<FlowNode>(); var node = item.ToObject<FlowNode>();
if (!Nodes.ContainsKey(node.id)) if (!Nodes.ContainsKey(node.id))
{ {
Nodes.Add(node.id, node); Nodes.Add(node.id, node);
} }
if (node.type == FlowNode.START) if (node.type == FlowNode.START)
{ {
this.startNodeId = node.id; this.startNodeId = node.id;
} }
} }
} }
private void InitLines(dynamic schemeContentJson) private void InitLines(dynamic schemeContentJson)
{ {
Lines = new List<FlowLine>(); Lines = new List<FlowLine>();
FromNodeLines = new Dictionary<string, List<FlowLine>>(); FromNodeLines = new Dictionary<string, List<FlowLine>>();
ToNodeLines = new Dictionary<string, List<FlowLine>>(); ToNodeLines = new Dictionary<string, List<FlowLine>>();
foreach (JObject item in schemeContentJson.lines) foreach (JObject item in schemeContentJson.lines)
{ {
var line = item.ToObject<FlowLine>(); var line = item.ToObject<FlowLine>();
Lines.Add(line); Lines.Add(line);
if (!FromNodeLines.ContainsKey(line.from)) if (!FromNodeLines.ContainsKey(line.from))
{ {
List<FlowLine> d = new List<FlowLine> { line }; List<FlowLine> d = new List<FlowLine> { line };
FromNodeLines.Add(line.from, d); FromNodeLines.Add(line.from, d);
} }
else else
{ {
FromNodeLines[line.from].Add(line); FromNodeLines[line.from].Add(line);
} }
if (!ToNodeLines.ContainsKey(line.to)) if (!ToNodeLines.ContainsKey(line.to))
{ {
List<FlowLine> d = new List<FlowLine> { line }; List<FlowLine> d = new List<FlowLine> { line };
ToNodeLines.Add(line.to, d); ToNodeLines.Add(line.to, d);
} }
else else
{ {
ToNodeLines[line.to].Add(line); ToNodeLines[line.to].Add(line);
} }
} }
} }
/// <summary> /// <summary>
/// 获取下一个节点 /// 获取下一个节点
/// </summary> /// </summary>
private string GetNextNodeId(string nodeId = null) private string GetNextNodeId(string nodeId = null)
{ {
var lines = nodeId == null ? FromNodeLines[currentNodeId] : FromNodeLines[nodeId]; var lines = nodeId == null ? FromNodeLines[currentNodeId] : FromNodeLines[nodeId];
if (lines.Count == 0) if (lines.Count == 0)
{ {
throw new Exception("无法寻找到下一个节点"); throw new Exception("无法寻找到下一个节点");
} }
if (FrmData == "") return lines[0].to; if (FrmData == "" || FrmData == "{}") return lines[0].to;
FrmData = FrmData.ToLower();//统一转小写 FrmData = FrmData.ToLower();//统一转小写
var frmDataJson = FrmData.ToJObject();//获取数据内容 var frmDataJson = FrmData.ToJObject();//获取数据内容
foreach (var l in lines) foreach (var l in lines)
{ {
if (!(l.Compares.IsNullOrEmpty()) &&l.Compare(frmDataJson)) if (!(l.Compares.IsNullOrEmpty()) &&l.Compare(frmDataJson))
{ {
return l.to; return l.to;
} }
} }
return lines[0].to; return lines[0].to;
} }
#endregion #endregion
#region #region
//获取下一个节点 //获取下一个节点
public FlowNode GetNextNode(string nodeId = null) public FlowNode GetNextNode(string nodeId = null)
{ {
return Nodes[GetNextNodeId(nodeId)]; return Nodes[GetNextNodeId(nodeId)];
} }
/// <summary> /// <summary>
/// 获取实例接下来运行的状态 /// 获取实例接下来运行的状态
/// </summary> /// </summary>
/// <returns>-1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束</returns> /// <returns>-1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束</returns>
public int GetNextNodeType() public int GetNextNodeType()
{ {
if (nextNodeId != "-1") if (nextNodeId != "-1")
{ {
return GetNodeType(nextNodeId); return GetNodeType(nextNodeId);
} }
return -1; return -1;
} }
/// <summary> /// <summary>
/// 获取节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束 /// 获取节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束
/// </summary> /// </summary>
/// <param name="nodeId"></param> /// <param name="nodeId"></param>
/// <returns></returns> /// <returns></returns>
public int GetNodeType(string nodeId) public int GetNodeType(string nodeId)
{ {
switch (Nodes[nodeId].type) switch (Nodes[nodeId].type)
{ {
//会签开始节点 //会签开始节点
case FlowNode.FORK: case FlowNode.FORK:
return 0; return 0;
//会签结束节点 //会签结束节点
case FlowNode.JOIN: case FlowNode.JOIN:
return 1; return 1;
//结束节点 //结束节点
case FlowNode.END: case FlowNode.END:
return 4; return 4;
//开始节点 //开始节点
case FlowNode.START: case FlowNode.START:
return 3; return 3;
default: default:
return 2; return 2;
} }
} }
/// <summary> /// <summary>
/// 节点会签审核 /// 节点会签审核
/// </summary> /// </summary>
/// <param name="nodeId">会签时currentNodeId是会签开始节点。这个表示当前正在处理的节点</param> /// <param name="nodeId">会签时currentNodeId是会签开始节点。这个表示当前正在处理的节点</param>
/// <param name="tag"></param> /// <param name="tag"></param>
/// <returns>-1不通过,1等待,其它通过</returns> /// <returns>-1不通过,1等待,其它通过</returns>
public string NodeConfluence(string nodeId, Tag tag) public string NodeConfluence(string nodeId, Tag tag)
{ {
var forkNode = Nodes[currentNodeId]; //会签开始节点 var forkNode = Nodes[currentNodeId]; //会签开始节点
FlowNode nextNode = GetNextNode(nodeId); //获取当前处理的下一个节点 FlowNode nextNode = GetNextNode(nodeId); //获取当前处理的下一个节点
int forkNumber = FromNodeLines[currentNodeId].Count; //直接与会签节点连接的点,即会签分支数目 int forkNumber = FromNodeLines[currentNodeId].Count; //直接与会签节点连接的点,即会签分支数目
string res =string.Empty; //记录会签的结果,默认正在会签 string res =string.Empty; //记录会签的结果,默认正在会签
if (forkNode.setInfo.NodeConfluenceType == "one") //有一个步骤通过即可 if (forkNode.setInfo.NodeConfluenceType == "one") //有一个步骤通过即可
{ {
if (tag.Taged == (int) TagState.Ok) if (tag.Taged == (int) TagState.Ok)
{ {
if (nextNode.type == FlowNode.JOIN) //下一个节点是会签结束,则该线路结束 if (nextNode.type == FlowNode.JOIN) //下一个节点是会签结束,则该线路结束
{ {
res = GetNextNodeId(nextNode.id); res = GetNextNodeId(nextNode.id);
} }
} }
else if(tag.Taged ==(int) TagState.No) else if(tag.Taged ==(int) TagState.No)
{ {
if (forkNode.setInfo.ConfluenceNo == null) if (forkNode.setInfo.ConfluenceNo == null)
{ {
forkNode.setInfo.ConfluenceNo = 1; forkNode.setInfo.ConfluenceNo = 1;
} }
else if (forkNode.setInfo.ConfluenceNo == (forkNumber - 1)) else if (forkNode.setInfo.ConfluenceNo == (forkNumber - 1))
{ {
res = TagState.No.ToString("D"); res = TagState.No.ToString("D");
} }
else else
{ {
bool isFirst = true; //是不是从会签开始到现在第一个 bool isFirst = true; //是不是从会签开始到现在第一个
var preNode = GetPreNode(nodeId); var preNode = GetPreNode(nodeId);
while (preNode.id != forkNode.id) //反向一直到会签开始节点 while (preNode.id != forkNode.id) //反向一直到会签开始节点
{ {
if (preNode.setInfo != null && preNode.setInfo.Taged == (int) TagState.No) if (preNode.setInfo != null && preNode.setInfo.Taged == (int) TagState.No)
{ {
isFirst = false; isFirst = false;
break; break;
} }
} }
if (isFirst) if (isFirst)
{ {
forkNode.setInfo.ConfluenceNo++; forkNode.setInfo.ConfluenceNo++;
} }
} }
} }
} }
else //默认所有步骤通过 else //默认所有步骤通过
{ {
if (tag.Taged == (int) TagState.No) //只要有一个不同意,那么流程就结束 if (tag.Taged == (int) TagState.No) //只要有一个不同意,那么流程就结束
{ {
res = TagState.No.ToString("D"); res = TagState.No.ToString("D");
} }
else if(tag.Taged == (int)TagState.Ok) else if(tag.Taged == (int)TagState.Ok)
{ {
if (nextNode.type == FlowNode.JOIN) //这种模式下只有坚持到【会签结束】节点之前才有意义,是否需要判定这条线所有的节点都通过,不然直接执行这个节点?? if (nextNode.type == FlowNode.JOIN) //这种模式下只有坚持到【会签结束】节点之前才有意义,是否需要判定这条线所有的节点都通过,不然直接执行这个节点??
{ {
if (forkNode.setInfo.ConfluenceOk == null) if (forkNode.setInfo.ConfluenceOk == null)
{ {
forkNode.setInfo.ConfluenceOk = 1; forkNode.setInfo.ConfluenceOk = 1;
} }
else if (forkNode.setInfo.ConfluenceOk == (forkNumber - 1)) //会签成功 else if (forkNode.setInfo.ConfluenceOk == (forkNumber - 1)) //会签成功
{ {
res = GetNextNodeId(nextNode.id); res = GetNextNodeId(nextNode.id);
} }
else else
{ {
forkNode.setInfo.ConfluenceOk++; forkNode.setInfo.ConfluenceOk++;
} }
} }
} }
} }
if (res == TagState.No.ToString("D")) if (res == TagState.No.ToString("D"))
{ {
tag.Taged = (int) TagState.No; tag.Taged = (int) TagState.No;
MakeTagNode(nextNode.id, tag); MakeTagNode(nextNode.id, tag);
} }
else if (!string.IsNullOrEmpty(res)) //会签结束,标记合流节点 else if (!string.IsNullOrEmpty(res)) //会签结束,标记合流节点
{ {
tag.Taged = (int) TagState.Ok; tag.Taged = (int) TagState.Ok;
MakeTagNode(nextNode.id, tag); MakeTagNode(nextNode.id, tag);
nextNodeId = res; nextNodeId = res;
nextNodeType = GetNodeType(res); nextNodeType = GetNodeType(res);
} }
else else
{ {
nextNodeId = nextNode.id; nextNodeId = nextNode.id;
nextNodeType = GetNodeType(nextNode.id); nextNodeType = GetNodeType(nextNode.id);
} }
return res; return res;
} }
//获取上一个节点 //获取上一个节点
private FlowNode GetPreNode(string nodeId = null) private FlowNode GetPreNode(string nodeId = null)
{ {
var lines = nodeId == null ? ToNodeLines[currentNodeId] : ToNodeLines[nodeId]; var lines = nodeId == null ? ToNodeLines[currentNodeId] : ToNodeLines[nodeId];
if (lines.Count == 0) if (lines.Count == 0)
{ {
throw new Exception("无法找到上一个点"); throw new Exception("无法找到上一个点");
} }
return Nodes[lines[0].from]; return Nodes[lines[0].from];
} }
/// <summary> /// <summary>
/// 驳回 /// 驳回
/// </summary> /// </summary>
/// <param name="rejectType">驳回类型。null:使用节点配置的驳回类型/0:前一步/1:第一步/2指定节点使用NodeRejectStep</param> /// <param name="rejectType">驳回类型。null:使用节点配置的驳回类型/0:前一步/1:第一步/2指定节点使用NodeRejectStep</param>
/// <returns></returns> /// <returns></returns>
public string RejectNode(string rejectType) public string RejectNode(string rejectType)
{ {
dynamic node = Nodes[currentNodeId]; dynamic node = Nodes[currentNodeId];
if (node.setInfo != null && string.IsNullOrEmpty(rejectType)) if (node.setInfo != null && string.IsNullOrEmpty(rejectType))
{ {
rejectType = node.setInfo.NodeRejectType; rejectType = node.setInfo.NodeRejectType;
} }
if (rejectType == "0") if (rejectType == "0")
{ {
return previousId; return previousId;
} }
if (rejectType == "1") if (rejectType == "1")
{ {
return GetNextNodeId(startNodeId); return GetNextNodeId(startNodeId);
} }
return previousId; return previousId;
} }
/// <summary> /// <summary>
/// 撤销流程,清空所有节点 /// 撤销流程,清空所有节点
/// </summary> /// </summary>
public void ReCall() public void ReCall()
{ {
foreach (var item in Nodes) foreach (var item in Nodes)
{ {
item.Value.setInfo = null; item.Value.setInfo = null;
} }
} }
///<summary> ///<summary>
/// 标记节点1通过-1不通过0驳回 /// 标记节点1通过-1不通过0驳回
/// </summary> /// </summary>
/// <param name="nodeId"></param> /// <param name="nodeId"></param>
public void MakeTagNode(string nodeId, Tag tag) public void MakeTagNode(string nodeId, Tag tag)
{ {
foreach (var item in Nodes) foreach (var item in Nodes)
{ {
if (item.Key == nodeId) if (item.Key == nodeId)
{ {
if (item.Value.setInfo == null) if (item.Value.setInfo == null)
{ {
item.Value.setInfo = new Setinfo(); item.Value.setInfo = new Setinfo();
} }
item.Value.setInfo.Taged = tag.Taged; item.Value.setInfo.Taged = tag.Taged;
item.Value.setInfo.UserId = tag.UserId; item.Value.setInfo.UserId = tag.UserId;
item.Value.setInfo.UserName = tag.UserName; item.Value.setInfo.UserName = tag.UserName;
item.Value.setInfo.Description = tag.Description; item.Value.setInfo.Description = tag.Description;
item.Value.setInfo.TagedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm"); item.Value.setInfo.TagedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
break; break;
} }
} }
} }
public object ToSchemeObj() public object ToSchemeObj()
{ {
return new return new
{ {
title = this.title, title = this.title,
initNum = this.initNum, initNum = this.initNum,
lines = Lines, lines = Lines,
nodes = Nodes.Select(u => u.Value), nodes = Nodes.Select(u => u.Value),
areas = new string[0] areas = new string[0]
}; };
} }
/// <summary> /// <summary>
/// 通知三方系统,节点执行情况 /// 通知三方系统,节点执行情况
/// </summary> /// </summary>
public void NotifyThirdParty(HttpClient client, Tag tag) public void NotifyThirdParty(HttpClient client, Tag tag)
{ {
if (currentNode.setInfo == null || string.IsNullOrEmpty(currentNode.setInfo.ThirdPartyUrl)) if (currentNode.setInfo == null || string.IsNullOrEmpty(currentNode.setInfo.ThirdPartyUrl))
{ {
return; return;
} }
var postData = new var postData = new
{ {
flowInstanceId, flowInstanceId,
nodeName=currentNode.name, nodeName=currentNode.name,
nodeId = currentNodeId, nodeId = currentNodeId,
userId = tag.UserId, userId = tag.UserId,
userName = tag.UserName, userName = tag.UserName,
result=tag.Taged, //1通过;2不通过3驳回 result=tag.Taged, //1通过;2不通过3驳回
description = tag.Description, description = tag.Description,
execTime = tag.TagedTime, execTime = tag.TagedTime,
isFinish = currentNodeType == 4 isFinish = currentNodeType == 4
}; };
using (HttpContent httpContent = new StringContent(JsonHelper.Instance.Serialize(postData), Encoding.UTF8)) using (HttpContent httpContent = new StringContent(JsonHelper.Instance.Serialize(postData), Encoding.UTF8))
{ {
httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
client.PostAsync(currentNode.setInfo.ThirdPartyUrl, httpContent); client.PostAsync(currentNode.setInfo.ThirdPartyUrl, httpContent);
} }
} }
#endregion #endregion
#region #region
public string title { get; set; } public string title { get; set; }
public int initNum { get; set; } public int initNum { get; set; }
/// <summary> /// <summary>
/// 运行实例的Id /// 运行实例的Id
/// </summary> /// </summary>
public string flowInstanceId { get; set; } public string flowInstanceId { get; set; }
/// <summary> /// <summary>
/// 开始节点的ID /// 开始节点的ID
/// </summary> /// </summary>
public string startNodeId { get; set; } public string startNodeId { get; set; }
/// <summary> /// <summary>
/// 当前节点的ID /// 当前节点的ID
/// </summary> /// </summary>
public string currentNodeId { get; set; } public string currentNodeId { get; set; }
/// <summary> /// <summary>
/// 当前节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束 /// 当前节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束
/// </summary> /// </summary>
public int currentNodeType { get; set; } public int currentNodeType { get; set; }
/// <summary> /// <summary>
/// 当前节点的对象 /// 当前节点的对象
/// </summary> /// </summary>
public FlowNode currentNode => Nodes[currentNodeId]; public FlowNode currentNode => Nodes[currentNodeId];
/// <summary> /// <summary>
/// 下一个节点 /// 下一个节点
/// </summary> /// </summary>
public string nextNodeId { get; set; } public string nextNodeId { get; set; }
/// <summary> /// <summary>
/// 下一个节点类型 -1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束 /// 下一个节点类型 -1无法运行,0会签开始,1会签结束,2一般节点,4流程运行结束
/// </summary> /// </summary>
/// <value>The type of the next node.</value> /// <value>The type of the next node.</value>
public int nextNodeType { get; set; } public int nextNodeType { get; set; }
/// <summary> /// <summary>
/// 下一个节点对象 /// 下一个节点对象
/// </summary> /// </summary>
public FlowNode nextNode => nextNodeId != "-1"? Nodes[nextNodeId] : null; public FlowNode nextNode => nextNodeId != "-1"? Nodes[nextNodeId] : null;
/// <summary> /// <summary>
/// 上一个节点 /// 上一个节点
/// </summary> /// </summary>
public string previousId { get; set; } public string previousId { get; set; }
/// <summary> /// <summary>
/// 实例节点集合 /// 实例节点集合
/// </summary> /// </summary>
public Dictionary<string, FlowNode> Nodes { get; set; } public Dictionary<string, FlowNode> Nodes { get; set; }
/// <summary> /// <summary>
/// 流程实例中所有的线段 /// 流程实例中所有的线段
/// </summary> /// </summary>
public List<FlowLine> Lines { get; set; } public List<FlowLine> Lines { get; set; }
/// <summary> /// <summary>
/// 从节点发出的线段集合 /// 从节点发出的线段集合
/// </summary> /// </summary>
public Dictionary<string, List<FlowLine>> FromNodeLines { get; set; } public Dictionary<string, List<FlowLine>> FromNodeLines { get; set; }
/// <summary> /// <summary>
/// 到达节点的线段集合 /// 到达节点的线段集合
/// </summary> /// </summary>
public Dictionary<string, List<FlowLine>> ToNodeLines { get; set; } public Dictionary<string, List<FlowLine>> ToNodeLines { get; set; }
/// <summary> /// <summary>
/// 表单数据 /// 表单数据
/// </summary> /// </summary>
public string FrmData { get; set; } public string FrmData { get; set; }
#endregion #endregion
} }
} }