增加撤销与启动,详见:#I3ILBG

调整工程结构,采用模块化机制
This commit is contained in:
yubaolee
2021-04-15 00:40:30 +08:00
parent 484daa48f0
commit cf23d0025f
86 changed files with 3032 additions and 2819 deletions

View File

@@ -0,0 +1,30 @@
namespace Infrastructure.Const
{
/// <summary>
/// 流程状态
/// </summary>
public struct FlowInstanceStatus
{
/// <summary>
/// 撤销、召回
/// </summary>
public const int Draft = -1;
/// <summary>
/// 正在运行
/// </summary>
public const int Running = 0;
/// <summary>
/// 完成
/// </summary>
public const int Finished = 1;
/// <summary>
/// 不同意
/// </summary>
public const int Disagree = 3;
/// <summary>
/// 驳回
/// </summary>
public const int Rejected = 4;
}
}

View File

@@ -381,6 +381,7 @@ namespace Infrastructure.Helpers
/// <param name="addStr">追加内容</param>
public static void RegxAddContentByParenthesis(string path, string addStr)
{
path = StringExtension.ReplacePath(path);
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
string originStr = sr.ReadToEnd();

View File

@@ -325,6 +325,17 @@ namespace OpenAuth.App.Flow
return previousId;
}
/// <summary>
/// 撤销流程,清空所有节点
/// </summary>
public void ReCall()
{
foreach (var item in Nodes)
{
item.Value.setInfo = null;
}
}
///<summary>
/// 标记节点1通过-1不通过0驳回
/// </summary>

View File

@@ -25,6 +25,7 @@ using System.Linq;
using System.Linq.Expressions;
using System.Net.Http;
using System.Threading.Tasks;
using Infrastructure.Const;
using Infrastructure.Helpers;
using OpenAuth.Repository;
@@ -41,6 +42,19 @@ namespace OpenAuth.App
private IHttpClientFactory _httpClientFactory;
private IServiceProvider _serviceProvider;
public FlowInstanceApp(IUnitWork<OpenAuthDBContext> unitWork,
IRepository<FlowInstance, OpenAuthDBContext> repository
, RevelanceManagerApp app, FlowSchemeApp flowSchemeApp, FormApp formApp,
IHttpClientFactory httpClientFactory, IAuth auth, IServiceProvider serviceProvider)
: base(unitWork, repository, auth)
{
_revelanceApp = app;
_flowSchemeApp = flowSchemeApp;
_formApp = formApp;
_httpClientFactory = httpClientFactory;
_serviceProvider = serviceProvider;
}
#region API
/// <summary>
@@ -93,7 +107,9 @@ namespace OpenAuth.App
flowInstance.CreateUserId = user.User.Id;
flowInstance.CreateUserName = user.User.Account;
flowInstance.MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime) : "");
flowInstance.IsFinish = (wfruntime.GetNextNodeType() == 4 ? 1 : 0);
flowInstance.IsFinish = (wfruntime.GetNextNodeType() == 4
? FlowInstanceStatus.Finished
: FlowInstanceStatus.Running);
UnitWork.Add(flowInstance);
wfruntime.flowInstanceId = flowInstance.Id;
@@ -156,7 +172,8 @@ namespace OpenAuth.App
wfruntime.MakeTagNode(wfruntime.currentNodeId, tag);
string canCheckId = ""; //寻找当前登录用户可审核的节点Id
foreach (string fromForkStartNodeId in wfruntime.FromNodeLines[wfruntime.currentNodeId].Select(u => u.to))
foreach (string fromForkStartNodeId in wfruntime.FromNodeLines[wfruntime.currentNodeId]
.Select(u => u.to))
{
var fromForkStartNode = wfruntime.Nodes[fromForkStartNodeId]; //与会前开始节点直接连接的节点
canCheckId = GetOneForkLineCanCheckNodeId(fromForkStartNode, wfruntime, tag);
@@ -177,7 +194,7 @@ namespace OpenAuth.App
string res = wfruntime.NodeConfluence(canCheckId, tag);
if (res == TagState.No.ToString("D"))
{
flowInstance.IsFinish = 3;
flowInstance.IsFinish = FlowInstanceStatus.Disagree;
}
else if (!string.IsNullOrEmpty(res))
{
@@ -185,7 +202,9 @@ namespace OpenAuth.App
flowInstance.ActivityId = wfruntime.nextNodeId;
flowInstance.ActivityType = wfruntime.nextNodeType;
flowInstance.ActivityName = wfruntime.nextNode.name;
flowInstance.IsFinish = (wfruntime.nextNodeType == 4 ? 1 : 0);
flowInstance.IsFinish = (wfruntime.nextNodeType == 4
? FlowInstanceStatus.Finished
: FlowInstanceStatus.Running);
flowInstance.MakerList =
(wfruntime.nextNodeType == 4 ? "" : GetNextMakers(wfruntime));
@@ -197,8 +216,8 @@ namespace OpenAuth.App
flowInstance.MakerList = GetForkNodeMakers(wfruntime, wfruntime.currentNodeId);
AddTransHistory(wfruntime);
}
}
#endregion
#region
@@ -213,13 +232,16 @@ namespace OpenAuth.App
flowInstance.ActivityType = wfruntime.nextNodeType;
flowInstance.ActivityName = wfruntime.nextNode.name;
flowInstance.MakerList = wfruntime.nextNodeType == 4 ? "" : GetNextMakers(wfruntime);
flowInstance.IsFinish = (wfruntime.nextNodeType == 4 ? 1 : 0);
flowInstance.IsFinish = (wfruntime.nextNodeType == 4
? FlowInstanceStatus.Finished
: FlowInstanceStatus.Running);
AddTransHistory(wfruntime);
}
else
{
flowInstance.IsFinish = 3; //表示该节点不同意
flowInstance.IsFinish = FlowInstanceStatus.Disagree; //表示该节点不同意
}
flowInstanceOperationHistory.Content = "【" + wfruntime.currentNode.name
+ "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm")
+ "】" + (tag.Taged == 1 ? "同意" : "不同意") + ",备注:"
@@ -247,7 +269,8 @@ namespace OpenAuth.App
{
var makerList = GetNodeMarkers(node);
if (node.setInfo.Taged == null && !string.IsNullOrEmpty(makerList) && makerList.Split(',').Any(one => tag.UserId == one))
if (node.setInfo.Taged == null && !string.IsNullOrEmpty(makerList) &&
makerList.Split(',').Any(one => tag.UserId == one))
{
canCheckId = node.id;
break;
@@ -273,7 +296,9 @@ namespace OpenAuth.App
FlowRuntime wfruntime = new FlowRuntime(flowInstance);
string rejectNode = ""; //驳回的节点
rejectNode = string.IsNullOrEmpty(reqest.NodeRejectStep) ? wfruntime.RejectNode(reqest.NodeRejectType) : reqest.NodeRejectStep;
rejectNode = string.IsNullOrEmpty(reqest.NodeRejectStep)
? wfruntime.RejectNode(reqest.NodeRejectType)
: reqest.NodeRejectStep;
var tag = new Tag
{
@@ -284,7 +309,7 @@ namespace OpenAuth.App
};
wfruntime.MakeTagNode(wfruntime.currentNodeId, tag);
flowInstance.IsFinish = 4;//4表示驳回需要申请者重新提交表单
flowInstance.IsFinish = FlowInstanceStatus.Rejected; //4表示驳回需要申请者重新提交表单
if (rejectNode != "")
{
flowInstance.PreviousId = flowInstance.ActivityId;
@@ -300,14 +325,10 @@ namespace OpenAuth.App
UnitWork.Add(new FlowInstanceOperationHistory
{
InstanceId = reqest.FlowInstanceId
,
CreateUserId = user.Id
,
CreateUserName = user.Name
,
CreateDate = DateTime.Now
,
InstanceId = reqest.FlowInstanceId,
CreateUserId = user.Id,
CreateUserName = user.Name,
CreateDate = DateTime.Now,
Content = "【"
+ wfruntime.currentNode.name
+ "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】驳回,备注:"
@@ -324,6 +345,7 @@ namespace OpenAuth.App
#endregion API
#region
/// <summary>
/// 寻找下一步的执行人
/// 一般用于本节点审核完成后,修改流程实例的当前执行人,可以做到通知等功能
@@ -336,6 +358,7 @@ namespace OpenAuth.App
{
throw (new Exception("无法寻找到下一个节点"));
}
if (wfruntime.nextNodeType == 0) //如果是会签节点
{
makerList = GetForkNodeMakers(wfruntime, wfruntime.nextNodeId);
@@ -387,14 +410,17 @@ namespace OpenAuth.App
{
break;
}
node = wfruntime.GetNextNode(node.id); //下一个节点
continue;
}
var marker = GetNodeMarkers(node);
if (marker == "")
{
throw (new Exception($"节点{node.name}没有审核者,请检查!"));
}
if (marker == "1")
{
throw (new Exception($"节点{node.name}是会签节点,不能用所有人,请检查!"));
@@ -404,6 +430,7 @@ namespace OpenAuth.App
{
markers += ",";
}
markers += marker;
break;
} while (node.type != FlowNode.JOIN);
@@ -443,8 +470,10 @@ namespace OpenAuth.App
{
makerList = "1";
}
return makerList;
}
#endregion
/// <summary>
@@ -484,7 +513,10 @@ namespace OpenAuth.App
if (request.type == "wait") //待办事项
{
Expression<Func<FlowInstance, bool>> waitExp = u => (u.MakerList == "1" || u.MakerList.Contains(user.User.Id)) && (u.IsFinish == 0|| u.IsFinish==4);
Expression<Func<FlowInstance, bool>> waitExp = u => (u.MakerList == "1"
|| u.MakerList.Contains(user.User.Id)) &&
(u.IsFinish == FlowInstanceStatus.Running ||
u.IsFinish == FlowInstanceStatus.Rejected);
// 加入搜索自定义标题
if (!string.IsNullOrEmpty(request.key))
@@ -550,26 +582,93 @@ namespace OpenAuth.App
ToNodeId = wfruntime.nextNodeId,
ToNodeName = wfruntime.nextNode.name,
ToNodeType = wfruntime.nextNodeType,
IsFinish = wfruntime.nextNodeType == 4 ? 1 : 0,
IsFinish = wfruntime.nextNodeType == 4 ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running,
TransitionSate = 0
});
}
public FlowInstanceApp(IUnitWork<OpenAuthDBContext> unitWork, IRepository<FlowInstance,OpenAuthDBContext> repository
, RevelanceManagerApp app, FlowSchemeApp flowSchemeApp, FormApp formApp, IHttpClientFactory httpClientFactory,IAuth auth, IServiceProvider serviceProvider)
: base(unitWork, repository, auth)
{
_revelanceApp = app;
_flowSchemeApp = flowSchemeApp;
_formApp = formApp;
_httpClientFactory = httpClientFactory;
_serviceProvider = serviceProvider;
}
public List<FlowInstanceOperationHistory> QueryHistories(QueryFlowInstanceHistoryReq request)
{
return UnitWork.Find<FlowInstanceOperationHistory>(u => u.InstanceId == request.FlowInstanceId)
.OrderByDescending(u => u.CreateDate).ToList();
}
/// <summary>
/// 召回流程
/// </summary>
public void ReCall(RecallFlowInstanceReq request)
{
var user = _auth.GetCurrentUser().User;
FlowInstance flowInstance = Get(request.FlowInstanceId);
FlowRuntime wfruntime = new FlowRuntime(flowInstance);
string startNodeId = wfruntime.startNodeId; //起始节点
wfruntime.ReCall();
flowInstance.IsFinish = FlowInstanceStatus.Draft;
flowInstance.PreviousId = flowInstance.ActivityId;
flowInstance.ActivityId = startNodeId;
flowInstance.ActivityType = wfruntime.GetNodeType(startNodeId);
flowInstance.ActivityName = wfruntime.Nodes[startNodeId].name;
flowInstance.MakerList = GetNodeMarkers(wfruntime.Nodes[startNodeId], flowInstance.CreateUserId);
AddTransHistory(wfruntime);
UnitWork.Update(flowInstance);
UnitWork.Add(new FlowInstanceOperationHistory
{
InstanceId = request.FlowInstanceId,
CreateUserId = user.Id,
CreateUserName = user.Name,
CreateDate = DateTime.Now,
Content = $"【撤销】由{user.Name}撤销,备注:{request.Description}"
});
UnitWork.Save();
}
/// <summary>启动流程</summary>
/// <remarks> 通常是对状态为【草稿】的流程进行操作,进入运行状态 </remarks>
public void Start(StartFlowInstanceReq request)
{
FlowInstance flowInstance = Get(request.FlowInstanceId);
var wfruntime = new FlowRuntime(flowInstance);
var user = _auth.GetCurrentUser();
#region
flowInstance.ActivityId = wfruntime.nextNodeId;
flowInstance.ActivityType = wfruntime.GetNextNodeType();
flowInstance.ActivityName = wfruntime.nextNode.name;
flowInstance.PreviousId = wfruntime.currentNodeId;
flowInstance.CreateUserId = user.User.Id;
flowInstance.CreateUserName = user.User.Account;
flowInstance.MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime) : "");
flowInstance.IsFinish = (wfruntime.GetNextNodeType() == 4
? FlowInstanceStatus.Finished
: FlowInstanceStatus.Running);
UnitWork.Update(flowInstance);
#endregion
#region
FlowInstanceOperationHistory processOperationHistoryEntity = new FlowInstanceOperationHistory
{
InstanceId = flowInstance.Id,
CreateUserId = user.User.Id,
CreateUserName = user.User.Name,
CreateDate = DateTime.Now,
Content = $"【启动】由用户{user.User.Name}启动"
};
UnitWork.Add(processOperationHistoryEntity);
#endregion
AddTransHistory(wfruntime);
UnitWork.Save();
}
}
}

View File

@@ -0,0 +1,18 @@
namespace OpenAuth.App.Request
{
/// <summary>
/// 召回、撤销流程
/// </summary>
public class RecallFlowInstanceReq
{
/// <summary>
/// 召回、撤销的流程实例ID
/// </summary>
public string FlowInstanceId { get; set; }
/// <summary>
/// 撤回备注
/// </summary>
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
namespace OpenAuth.App.Request
{
/// <summary>
/// 启动流程
/// </summary>
public class StartFlowInstanceReq
{
/// <summary>
/// 启动流程的实例Id
/// </summary>
public string FlowInstanceId { get; set; }
}
}

View File

@@ -11,6 +11,7 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using Infrastructure.Const;
using OpenAuth.Repository.Core;
namespace OpenAuth.Repository.Domain
@@ -44,7 +45,7 @@ namespace OpenAuth.Repository.Domain
this.CreateUserName= string.Empty;
this.FlowLevel= 0;
this.Description= string.Empty;
this.IsFinish= 0;
this.IsFinish= FlowInstanceStatus.Running;
this.MakerList= string.Empty;
}

View File

@@ -10,6 +10,7 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using Infrastructure.Const;
using OpenAuth.Repository.Core;
namespace OpenAuth.Repository.Domain
@@ -28,7 +29,7 @@ namespace OpenAuth.Repository.Domain
this.ToNodeId= string.Empty;
this.ToNodeName= string.Empty;
this.TransitionSate= 0;
this.IsFinish= 0;
this.IsFinish= FlowInstanceStatus.Running;
this.CreateDate= DateTime.Now;
this.CreateUserId= string.Empty;
this.CreateUserName= string.Empty;

View File

@@ -84,6 +84,44 @@ namespace OpenAuth.WebApi.Controllers
return result;
}
/// <summary>召回流程</summary>
/// <remarks> 召回后流程状态为【草稿】状态,可以再次发起流程。所有的流程节点状态还原,但保留审批记录 </remarks>
[HttpPost]
public Response ReCall(RecallFlowInstanceReq obj)
{
var result = new Response();
try
{
_app.ReCall(obj);
}
catch (Exception ex)
{
result.Code = 500;
result.Message = ex.InnerException?.Message ?? ex.Message;
}
return result;
}
/// <summary>启动流程</summary>
/// <remarks> 通常是对状态为【草稿】的流程进行操作,进入运行状态 </remarks>
[HttpPost]
public Response Start(StartFlowInstanceReq obj)
{
var result = new Response();
try
{
_app.Start(obj);
}
catch (Exception ex)
{
result.Code = 500;
result.Message = ex.InnerException?.Message ?? ex.Message;
}
return result;
}
//添加或修改
[HttpPost]
public Response Update(FlowInstance obj)

View File

@@ -10,7 +10,7 @@ namespace OpenAuth.WebApi
{
public static void Main(string[] args)
{
Console.WriteLine(@"
Console.WriteLine($@"
____ _ _ _ _ _
/ __ \ /\ | | | | | \ | | | |
| | | |_ __ ___ _ __ / \ _ _| |_| |__ | \| | ___| |_
@@ -24,7 +24,7 @@ namespace OpenAuth.WebApi
.Net 5 Repository: https://gitee.com/dotnetchina/OpenAuth.Net
.Net core 3.1 : https://gitee.com/yubaolee/OpenAuth.Core
-------------------------------------------------------------------
");
Start Time:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
CreateHostBuilder(args).Build().Run();
}