diff --git a/OpenAuth.App/Flow/FlowRuntime.cs b/OpenAuth.App/Flow/FlowRuntime.cs index d2ee0106..0939cda9 100644 --- a/OpenAuth.App/Flow/FlowRuntime.cs +++ b/OpenAuth.App/Flow/FlowRuntime.cs @@ -8,9 +8,11 @@ using System.Net.Http; using System.Text; using Castle.Core.Internal; using Infrastructure.Const; +using Infrastructure.Extensions; using Infrastructure.Extensions.AutofacManager; using Infrastructure.Helpers; using OpenAuth.App.Interface; +using OpenAuth.App.Request; using SqlSugar; namespace OpenAuth.App.Flow @@ -190,10 +192,36 @@ namespace OpenAuth.App.Flow /// 会签时,currentNodeId是会签开始节点。这个表示当前正在处理的节点 /// /// -1不通过,1等待,其它通过 - public string NodeConfluence(HttpClient httpClient, string nodeId, Tag tag) + public string NodeConfluence(HttpClient httpClient, Tag tag) { + var user = AutofacContainerModule.GetService().GetCurrentUser().User; + //会签时的【当前节点】一直是会签开始节点 + //TODO: 标记会签节点的状态,这个地方感觉怪怪的 + MakeTagNode(currentNodeId, tag); + + string canCheckId = ""; //寻找当前登录用户可审核的节点Id + foreach (string fromForkStartNodeId in FromNodeLines[currentNodeId] + .Select(u => u.to)) + { + var fromForkStartNode = Nodes[fromForkStartNodeId]; //与会前开始节点直接连接的节点 + canCheckId = GetOneForkLineCanCheckNodeId(fromForkStartNode, tag); + if (!string.IsNullOrEmpty(canCheckId)) break; + } + + if (canCheckId == "") + { + throw new Exception("审核异常,找不到审核节点"); + } + + var content = + $"{user.Account}-{DateTime.Now:yyyy-MM-dd HH:mm}审批了【{Nodes[canCheckId].name}】" + + $"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}"; + AddOperationHis(tag, content); + + MakeTagNode(canCheckId, tag); //标记审核节点状态 + var forkNode = Nodes[currentNodeId]; //会签开始节点 - FlowNode nextNode = GetNextNode(nodeId); //获取当前处理的下一个节点 + FlowNode nextNode = GetNextNode(canCheckId); //获取当前处理的下一个节点 int forkNumber = FromNodeLines[currentNodeId].Count; //直接与会签节点连接的点,即会签分支数目 string res = string.Empty; //记录会签的结果,默认正在会签 @@ -219,7 +247,7 @@ namespace OpenAuth.App.Flow else { bool isFirst = true; //是不是从会签开始到现在第一个 - var preNode = GetPreNode(nodeId); + var preNode = GetPreNode(canCheckId); while (preNode.id != forkNode.id) //反向一直到会签开始节点 { if (preNode.setInfo != null && preNode.setInfo.Taged == (int)TagState.No) @@ -299,7 +327,7 @@ namespace OpenAuth.App.Flow return Nodes[lines[0].from]; } - + /// /// 驳回 /// @@ -374,6 +402,21 @@ namespace OpenAuth.App.Flow }; } + public void AddOperationHis(Tag tag, string content) + { + FlowInstanceOperationHistory flowInstanceOperationHistory = new FlowInstanceOperationHistory + { + InstanceId = flowInstanceId, + CreateUserId = tag.UserId, + CreateUserName = tag.UserName, + CreateDate = DateTime.Now, + Content = content + }; //操作记录 + + var SugarClient = AutofacContainerModule.GetService(); + SugarClient.Insertable(flowInstanceOperationHistory).ExecuteCommand(); + } + /// /// 保存本次扭转记录 /// @@ -395,8 +438,8 @@ namespace OpenAuth.App.Flow ToNodeType = nextNodeType, IsFinish = nextNodeType == 4 ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running, TransitionSate = 0 - }; - + }; + SugarClient.Insertable(transitionHistory).ExecuteCommand(); } @@ -433,7 +476,92 @@ namespace OpenAuth.App.Flow #endregion 共有方法 #region 获取节点审批人 - /// + + /// + /// 寻找下一步的执行人 + /// 一般用于本节点审核完成后,修改流程实例的当前执行人,可以做到通知等功能 + /// + /// + public string GetNextMakers(NodeDesignateReq request = null) + { + string makerList = ""; + if (nextNodeId == "-1") + { + throw new Exception("无法寻找到下一个节点"); + } + + if (nextNodeType == 0) //如果是会签节点 + { + makerList = GetForkNodeMakers(nextNodeId); + } + else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE) + { + //如果是运行时指定角色 + if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType) + { + throw new Exception("前端提交的节点权限类型异常,请检查流程"); + } + + var revelanceApp = AutofacContainerModule.GetService(); + var users = revelanceApp.Get(Define.USERROLE, false, request.NodeDesignates); + makerList = GenericHelpers.ArrayToString(users, makerList); + } + else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER) + { + //如果是运行时指定用户 + if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType) + { + throw new Exception("前端提交的节点权限类型异常,请检查流程"); + } + + makerList = GenericHelpers.ArrayToString(request.NodeDesignates, makerList); + } + else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_PARENT + || nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_MANY_PARENTS) + { + //如果是上一节点执行人的直属上级或连续多级直属上级 + if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType) + { + throw new Exception("前端提交的节点权限类型异常,请检查流程"); + } + + //当创建流程时,肯定执行的开始节点,登录用户就是创建用户 + //当审批流程时,能进到这里,表明当前登录用户已经有审批当前节点的权限,完全可以直接用登录用户的直接上级 + var userManagerApp = AutofacContainerModule.GetService(); + var user = AutofacContainerModule.GetService().GetCurrentUser().User; + var parentId = userManagerApp.GetParent(user.Id); + if (StringExtension.IsNullOrEmpty(parentId)) + { + throw new Exception("无法找到当前用户的直属上级"); + } + + makerList = GenericHelpers.ArrayToString(new[] { parentId }, makerList); + } + else if (nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_CHAIRMAN) + { + //如果是发起人的部门负责人 + if (nextNode.setInfo.NodeDesignate != request.NodeDesignateType) + { + throw new Exception("前端提交的节点权限类型异常,请检查流程"); + } + + var orgManagerApp = AutofacContainerModule.GetService(); + var chairmanIds = orgManagerApp.GetChairmanId(nextNode.setInfo.NodeDesignateData.orgs); + makerList = GenericHelpers.ArrayToString(chairmanIds, makerList); + } + else + { + makerList = GetNodeMarkers(nextNode); + if (string.IsNullOrEmpty(makerList)) + { + throw new Exception("无法寻找到节点的审核者,请查看流程设计是否有问题!"); + } + } + + return makerList; + } + + /// /// 计算节点执行人 /// /// @@ -475,7 +603,7 @@ namespace OpenAuth.App.Flow return makerList; } - + /// /// 会签时,获取一条会签分支上面是否有用户可审核的节点 /// @@ -502,7 +630,7 @@ namespace OpenAuth.App.Flow return canCheckId; } - + /// /// 获取会签开始节点的所有可执行者 /// @@ -568,6 +696,7 @@ namespace OpenAuth.App.Flow return markers; } + #endregion #region 属性 @@ -580,6 +709,36 @@ namespace OpenAuth.App.Flow /// 运行实例的Id /// private string flowInstanceId { get; set; } + + /// + /// 上一个节点 + /// + private string previousId { get; set; } + + /// + /// 流程实例中所有的线段 + /// + private List Lines { get; set; } + + /// + /// 从节点发出的线段集合 + /// + private Dictionary> FromNodeLines { get; set; } + + /// + /// 到达节点的线段集合 + /// + private Dictionary> ToNodeLines { get; set; } + + /// + /// 当前节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束 + /// + private int currentNodeType { get; set; } + + /// + /// 表单数据 + /// + private string FrmData { get; set; } /// /// 开始节点的ID @@ -591,11 +750,6 @@ namespace OpenAuth.App.Flow /// public string currentNodeId { get; set; } - /// - /// 当前节点类型 0会签开始,1会签结束,2一般节点,开始节点,4流程运行结束 - /// - public int currentNodeType { get; set; } - /// /// 当前节点的对象 /// @@ -617,36 +771,11 @@ namespace OpenAuth.App.Flow /// public FlowNode nextNode => nextNodeId != "-1" ? Nodes[nextNodeId] : null; - /// - /// 上一个节点 - /// - private string previousId { get; set; } - /// /// 实例节点集合 /// public Dictionary Nodes { get; set; } - /// - /// 流程实例中所有的线段 - /// - private List Lines { get; set; } - - /// - /// 从节点发出的线段集合 - /// - public Dictionary> FromNodeLines { get; set; } - - /// - /// 到达节点的线段集合 - /// - private Dictionary> ToNodeLines { get; set; } - - /// - /// 表单数据 - /// - public string FrmData { get; set; } - #endregion 属性 } } \ No newline at end of file diff --git a/OpenAuth.App/FlowInstance/FlowInstanceApp.cs b/OpenAuth.App/FlowInstance/FlowInstanceApp.cs index feb6d615..d496686f 100644 --- a/OpenAuth.App/FlowInstance/FlowInstanceApp.cs +++ b/OpenAuth.App/FlowInstance/FlowInstanceApp.cs @@ -3,7 +3,7 @@ * @Date: 2024-12-13 16:55:17 * @Description: 工作流实例表操作 * @LastEditTime: 2024-12-24 10:58:01 - * Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved. + * Copyright (c) 2024 by yubaolee | ahfu~ , All Rights Reserved. */ using Infrastructure; @@ -100,7 +100,7 @@ namespace OpenAuth.App addFlowInstanceReq.CreateUserName = user.User.Account; flowInstance.MakerList = - wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime, addFlowInstanceReq) : ""; + wfruntime.GetNextNodeType() != 4 ? wfruntime.GetNextMakers(addFlowInstanceReq) : ""; flowInstance.IsFinish = wfruntime.GetNextNodeType() == 4 ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running; @@ -350,33 +350,8 @@ namespace OpenAuth.App /// private void CounterSign(FlowRuntime wfruntime, Tag tag, FlowInstance flowInstance) { - var user = _auth.GetCurrentUser().User; - string instanceId = flowInstance.Id; - //会签时的【当前节点】一直是会签开始节点 - //TODO: 标记会签节点的状态,这个地方感觉怪怪的 - wfruntime.MakeTagNode(wfruntime.currentNodeId, tag); - - string canCheckId = ""; //寻找当前登录用户可审核的节点Id - foreach (string fromForkStartNodeId in wfruntime.FromNodeLines[wfruntime.currentNodeId] - .Select(u => u.to)) - { - var fromForkStartNode = wfruntime.Nodes[fromForkStartNodeId]; //与会前开始节点直接连接的节点 - canCheckId = wfruntime.GetOneForkLineCanCheckNodeId(fromForkStartNode, tag); - if (!string.IsNullOrEmpty(canCheckId)) break; - } - - if (canCheckId == "") - { - throw new Exception("审核异常,找不到审核节点"); - } - - var content = - $"{user.Account}-{DateTime.Now:yyyy-MM-dd HH:mm}审批了【{wfruntime.Nodes[canCheckId].name}】" + - $"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}"; - AddOperationHis(instanceId, tag, content); - - wfruntime.MakeTagNode(canCheckId, tag); //标记审核节点状态 - string res = wfruntime.NodeConfluence(_httpClientFactory.CreateClient(), canCheckId, tag); + string res = wfruntime.NodeConfluence(_httpClientFactory.CreateClient(), tag); + if (res == TagState.No.ToString("D")) { flowInstance.IsFinish = FlowInstanceStatus.Disagree; @@ -391,7 +366,7 @@ namespace OpenAuth.App ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running; flowInstance.MakerList = - wfruntime.nextNodeType == 4 ? "" : GetNextMakers(wfruntime); + wfruntime.nextNodeType == 4 ? "" : wfruntime.GetNextMakers(); wfruntime.SaveTransitionHis(); } @@ -487,7 +462,7 @@ namespace OpenAuth.App flowInstance.ActivityId = wfruntime.nextNodeId; flowInstance.ActivityType = wfruntime.nextNodeType; flowInstance.ActivityName = wfruntime.nextNode.name; - flowInstance.MakerList = wfruntime.nextNodeType == 4 ? "" : GetNextMakers(wfruntime, request); + flowInstance.MakerList = wfruntime.nextNodeType == 4 ? "" : wfruntime.GetNextMakers(request); flowInstance.IsFinish = wfruntime.nextNodeType == 4 ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running; @@ -503,7 +478,7 @@ namespace OpenAuth.App var content = $"{user.Account}-{DateTime.Now.ToString("yyyy-MM-dd HH:mm")}审批了【{wfruntime.currentNode.name}】" + $"结果:{(tag.Taged == 1 ? "同意" : "不同意")},备注:{tag.Description}"; - AddOperationHis(flowInstance.Id, tag, content); + wfruntime.AddOperationHis(tag, content); if (flowInstance.IsFinish == 1) { @@ -573,8 +548,9 @@ namespace OpenAuth.App flowInstance.ActivityId = rejectNode; flowInstance.ActivityType = wfruntime.GetNodeType(rejectNode); flowInstance.ActivityName = wfruntime.Nodes[rejectNode].name; - flowInstance.MakerList = wfruntime.GetNodeMarkers(wfruntime.Nodes[rejectNode], flowInstance.CreateUserId); - + flowInstance.MakerList = + wfruntime.GetNodeMarkers(wfruntime.Nodes[rejectNode], flowInstance.CreateUserId); + wfruntime.SaveTransitionHis(); } @@ -587,7 +563,8 @@ namespace OpenAuth.App CreateUserId = user.Id, CreateUserName = user.Name, CreateDate = DateTime.Now, - Content = $"【{wfruntime.currentNode.name}】【{DateTime.Now:yyyy-MM-dd HH:mm}】驳回,备注:{reqest.VerificationOpinion}" + Content = + $"【{wfruntime.currentNode.name}】【{DateTime.Now:yyyy-MM-dd HH:mm}】驳回,备注:{reqest.VerificationOpinion}" }).ExecuteCommand(); //给流程创建人发送通知信息 @@ -603,92 +580,6 @@ namespace OpenAuth.App #endregion 流程处理API - #region 获取各种节点的流程审核者 - - /// - /// 寻找下一步的执行人 - /// 一般用于本节点审核完成后,修改流程实例的当前执行人,可以做到通知等功能 - /// - /// - private string GetNextMakers(FlowRuntime wfruntime, NodeDesignateReq request = null) - { - string makerList = ""; - if (wfruntime.nextNodeId == "-1") - { - throw new Exception("无法寻找到下一个节点"); - } - - if (wfruntime.nextNodeType == 0) //如果是会签节点 - { - makerList = wfruntime.GetForkNodeMakers(wfruntime.nextNodeId); - } - else if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE) - { - //如果是运行时指定角色 - if (wfruntime.nextNode.setInfo.NodeDesignate != request.NodeDesignateType) - { - throw new Exception("前端提交的节点权限类型异常,请检查流程"); - } - - var users = _revelanceApp.Get(Define.USERROLE, false, request.NodeDesignates); - makerList = GenericHelpers.ArrayToString(users, makerList); - } - else if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER) - { - //如果是运行时指定用户 - if (wfruntime.nextNode.setInfo.NodeDesignate != request.NodeDesignateType) - { - throw new Exception("前端提交的节点权限类型异常,请检查流程"); - } - - makerList = GenericHelpers.ArrayToString(request.NodeDesignates, makerList); - } - else if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_PARENT - || wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_MANY_PARENTS) - { - //如果是上一节点执行人的直属上级或连续多级直属上级 - if (wfruntime.nextNode.setInfo.NodeDesignate != request.NodeDesignateType) - { - throw new Exception("前端提交的节点权限类型异常,请检查流程"); - } - - //当创建流程时,肯定执行的开始节点,登录用户就是创建用户 - //当审批流程时,能进到这里,表明当前登录用户已经有审批当前节点的权限,完全可以直接用登录用户的直接上级 - var user = _auth.GetCurrentUser().User; - var parentId = _userManagerApp.GetParent(user.Id); - if (StringExtension.IsNullOrEmpty(parentId)) - { - throw new Exception("无法找到当前用户的直属上级"); - } - - makerList = GenericHelpers.ArrayToString(new[] { parentId }, makerList); - } - else if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_CHAIRMAN) - { - //如果是发起人的部门负责人 - if (wfruntime.nextNode.setInfo.NodeDesignate != request.NodeDesignateType) - { - throw new Exception("前端提交的节点权限类型异常,请检查流程"); - } - - var chairmanIds = _orgManagerApp.GetChairmanId(wfruntime.nextNode.setInfo.NodeDesignateData.orgs); - makerList = GenericHelpers.ArrayToString(chairmanIds, makerList); - } - else - { - makerList = wfruntime.GetNodeMarkers(wfruntime.nextNode); - if (string.IsNullOrEmpty(makerList)) - { - throw new Exception("无法寻找到节点的审核者,请查看流程设计是否有问题!"); - } - } - - return makerList; - } - - - #endregion - /// /// 审核流程 /// @@ -848,20 +739,6 @@ namespace OpenAuth.App return result; } - private void AddOperationHis(string instanceId, Tag tag, string content) - { - FlowInstanceOperationHistory flowInstanceOperationHistory = new FlowInstanceOperationHistory - { - InstanceId = instanceId, - CreateUserId = tag.UserId, - CreateUserName = tag.UserName, - CreateDate = DateTime.Now, - Content = content - }; //操作记录 - - SugarClient.Insertable(flowInstanceOperationHistory).ExecuteCommand(); - } - public List QueryHistories(QueryFlowInstanceHistoryReq request) { return SugarClient.Queryable() @@ -938,7 +815,7 @@ namespace OpenAuth.App flowInstance.PreviousId = wfruntime.currentNodeId; flowInstance.CreateUserId = user.User.Id; flowInstance.CreateUserName = user.User.Account; - flowInstance.MakerList = wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime) : ""; + flowInstance.MakerList = wfruntime.GetNextNodeType() != 4 ? wfruntime.GetNextMakers() : ""; flowInstance.IsFinish = wfruntime.GetNextNodeType() == 4 ? FlowInstanceStatus.Finished : FlowInstanceStatus.Running;