using Org.BouncyCastle.Asn1.Ocsp; using Serenity.Data.Schema; using SqlSugar; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Threading.Tasks; using HT.Cloud.Code; using HT.Cloud.DataBase; using HT.Cloud.Domain.FlowManage; using HT.Cloud.Domain.InfoManage; using HT.Cloud.Domain.SystemManage; using HT.Cloud.Domain.SystemOrganize; using HT.Cloud.Service.InfoManage; using static iTextSharp.text.pdf.AcroFields; namespace HT.Cloud.Service.FlowManage { /// /// 创 建:超级管理员 /// 日 期:2020-07-14 09:18 /// 描 述:我的流程服务类 /// public class FlowinstanceService : BaseService, IDenpendency { public IHttpClientFactory _httpClientFactory { get; set; } public MessageService messageApp { get; set; } private string flowCreator; private string className { get; set; } public FlowinstanceService(ISqlSugarClient context) : base(context) { className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName.Split('.')[3].Substring(0, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName.Split('.')[3].Length - 7); } #region 获取数据 public async Task> GetList(string keyword = "") { var query = repository.IQueryable(); if (!string.IsNullOrEmpty(keyword)) { //此处需修改 query = query.Where(a => a.F_Code.Contains(keyword) || a.F_CustomName.Contains(keyword)); } return await query.Where(a => a.F_EnabledMark == true).OrderBy(a => a.F_Id, OrderByType.Desc).ToListAsync(); } public async Task> QueryHistories(string keyValue) { return await repository.Db.Queryable().Where(u => u.F_InstanceId == keyValue).OrderBy(u => u.F_CreatorTime).ToListAsync(); } public async Task> GetLookList(string keyword = "") { var query = repository.IQueryable(); if (!string.IsNullOrEmpty(keyword)) { //此处需修改 query = query.Where(a => a.F_Code.Contains(keyword) || a.F_CustomName.Contains(keyword)); } query = GetDataPrivilege("a", "", query); return await query.Where(a => a.F_EnabledMark == true).OrderBy(a => a.F_Id, OrderByType.Desc).ToListAsync(); } public async Task> GetLookList(SoulPage pagination, string type = "", string keyword = "") { //反格式化显示只能用"等于",其他不支持 Dictionary> dic = new Dictionary>(); Dictionary enabledTemp = new Dictionary(); enabledTemp.Add("0", "正在运行"); enabledTemp.Add("1", "审批通过"); enabledTemp.Add("2", "被撤回"); enabledTemp.Add("3", "不同意"); enabledTemp.Add("4", "被驳回"); dic.Add("F_IsFinish", enabledTemp); pagination = ChangeSoulData(dic, pagination); var query = repository.IQueryable(); if (!string.IsNullOrEmpty(keyword)) { //此处需修改 query = query.Where(a => a.F_Code.Contains(keyword) || a.F_CustomName.Contains(keyword)); } var user = currentuser; if (type == "todo") //待办事项 { query = query.Where(a => ((a.F_MakerList == "1" || a.F_MakerList.Contains(user.UserId))) && (a.F_IsFinish == 0 || a.F_IsFinish == 4) && a.F_ActivityType < 3); } else if (type == "done") //已办事项(即我参与过的流程) { var instances = repository.Db.Queryable().Where(a => a.F_CreatorUserId == user.UserId) .Select(a => a.F_InstanceId).Distinct().ToList(); query = query.Where(a => instances.Contains(a.F_Id)); } else //我的流程 { query = query.Where(a => a.F_CreatorUserId == user.UserId); } //权限过滤 query = GetDataPrivilege("a", "", query); return await query.Where(a => a.F_EnabledMark == true).ToPageListAsync(pagination); } public async Task GetForm(string keyValue) { var data = await repository.FindEntity(keyValue); return data; } #endregion 获取数据 public async Task GetLookForm(string keyValue) { var data = await repository.FindEntity(keyValue); return GetFieldsFilterData(data); } #region 获取各种节点的流程审核者 /// /// 驳回 /// 如果NodeRejectStep不为空,优先使用;否则按照NodeRejectType驳回 /// /// public async Task NodeReject(VerificationExtend reqest) { var user = currentuser; FlowinstanceEntity flowInstance = await GetForm(reqest.F_FlowInstanceId); flowCreator = flowInstance.F_CreatorUserId; FlowRuntime wfruntime = new FlowRuntime(flowInstance); string resnode = ""; resnode = string.IsNullOrEmpty(reqest.NodeRejectStep) ? wfruntime.RejectNode(reqest.NodeRejectType) : reqest.NodeRejectStep; var tag = new Tag { Description = reqest.F_VerificationOpinion, Taged = (int)TagState.Reject, UserId = user.UserId, UserName = user.UserName }; wfruntime.MakeTagNode(wfruntime.currentNodeId, tag); flowInstance.F_IsFinish = 4;//4表示驳回(需要申请者重新提交表单) repository.Db.Ado.BeginTran(); if (resnode != "") { wfruntime.RemoveNode(resnode); flowInstance.F_SchemeContent = wfruntime.ToSchemeObj().ToJson(); flowInstance.F_ActivityId = resnode; var prruntime = new FlowRuntime(flowInstance); prruntime.MakeTagNode(prruntime.currentNodeId, tag); flowInstance.F_PreviousId = prruntime.previousId; flowInstance.F_ActivityType = prruntime.GetNodeType(resnode); flowInstance.F_ActivityName = prruntime.Nodes[resnode].name; if (resnode == wfruntime.startNodeId) { flowInstance.F_MakerList = flowInstance.F_CreatorUserId; } else { flowInstance.F_MakerList = await repository.Db.Queryable().Where(a => a.F_FromNodeId == resnode && a.F_ToNodeId == prruntime.nextNodeId).OrderBy(a => a.F_CreatorTime, OrderByType.Desc).Select(a => a.F_CreatorUserId).FirstAsync();//当前节点可执行的人信息 } await AddRejectTransHistory(wfruntime, prruntime); var formDic = reqest.F_FrmData.ToObject>(); var oldformDic = flowInstance.F_FrmData.ToObject>(); foreach (var item in oldformDic) if (!formDic.ContainsKey(item.Key)) formDic.Add(item.Key, item.Value); if (flowInstance.F_FrmType == 1) { var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray(); var t = referencedAssemblies .SelectMany(a => a.GetTypes().Where(t => t.FullName.Contains("HT.Cloud.Service.") && t.FullName.Contains("." + flowInstance.F_DbName + "Service"))).First(); ICustomerForm icf = (ICustomerForm)GlobalContext.GetRequiredService(t); flowInstance.F_FrmData = formDic.ToJson(); await icf.Edit(flowInstance.F_Id, flowInstance.F_FrmData); } else { if (!string.IsNullOrEmpty(flowInstance.F_DbName)) { formDic.Add("F_LastModifyUserId", this.currentuser.UserId); formDic.Add("F_LastModifyTime", DateTime.Now); formDic.Add("F_LastModifyUserName", this.currentuser.UserName); flowInstance.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(flowInstance.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) List newID = data.Select(a => a.DbColumnName).ToList();//新增数据(新ID) foreach (var item in oldID.Except(newID)) formDic.Remove(item); await repository.Db.Updateable(formDic).AS(flowInstance.F_DbName).WhereColumns(data.FirstOrDefault(a => a.IsPrimarykey).DbColumnName).ExecuteCommandAsync(); } } await repository.Update(flowInstance); } await repository.Db.Insertable(new FlowInstanceOperationHistory { F_Id = Utils.GuId(), F_InstanceId = reqest.F_FlowInstanceId , F_CreatorUserId = user.UserId , F_CreatorUserName = user.UserName , F_CreatorTime = DateTime.Now , F_FrmData= flowInstance.F_FrmData , F_Content = "【" + wfruntime.currentNode.name + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】驳回,备注:" + reqest.F_VerificationOpinion }).ExecuteCommandAsync(); MessageEntity msg = new MessageEntity(); if (resnode == wfruntime.startNodeId) { msg.F_MessageInfo = flowInstance.F_CustomName + "--流程驳回"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; msg.F_ToUserId = flowInstance.F_CreatorUserId; msg.F_ToUserName = flowInstance.F_CreatorUserName; msg.F_ClickRead = true; msg.F_KeyValue = flowInstance.F_Id; } else { msg.F_MessageInfo = flowInstance.F_CustomName + "--流程待处理"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress.Remove(module.F_UrlAddress.Length - 5, 5) + "ToDoFlow"; msg.F_HrefTarget = module.F_Target; msg.F_ToUserId = flowInstance.F_MakerList == "1" ? "" : flowInstance.F_MakerList; msg.F_ClickRead = false; msg.F_KeyValue = flowInstance.F_Id; } msg.F_CreatorUserName = currentuser.UserName; msg.F_EnabledMark = true; msg.F_MessageType = 2; var lastmsg = repository.Db.Queryable().Where(a => a.F_ClickRead == false && a.F_KeyValue == flowInstance.F_Id).OrderBy(a => a.F_CreatorTime, OrderByType.Desc).First(); if (lastmsg != null && !await repository.Db.Queryable().Where(a => a.F_MessageId == lastmsg.F_Id).AnyAsync()) { await messageApp.ReadMsgForm(lastmsg.F_Id); } await messageApp.SubmitForm(msg); repository.Db.Ado.CommitTran(); wfruntime.NotifyThirdParty(_httpClientFactory.CreateClient(), tag); return true; } /// /// 节点审核 /// /// /// public async Task NodeVerification(VerificationExtend request) { var user = currentuser; var instanceId = request.F_FlowInstanceId; var tag = new Tag { UserName = user.UserName, UserId = user.UserId, Description = request.F_VerificationOpinion, Taged = Int32.Parse(request.F_VerificationFinally) }; FlowinstanceEntity flowInstance = await GetForm(instanceId); flowCreator = flowInstance.F_CreatorUserId; FlowInstanceOperationHistory flowInstanceOperationHistory = new FlowInstanceOperationHistory { F_Id = Utils.GuId(), F_InstanceId = instanceId, F_CreatorUserId = tag.UserId, F_CreatorUserName = tag.UserName, F_CreatorTime = DateTime.Now };//操作记录 FlowRuntime wfruntime = new FlowRuntime(flowInstance); repository.Db.Ado.BeginTran(); #region 会签 if (flowInstance.F_ActivityType == 0)//当前节点是会签节点 { //会签时的【当前节点】一直是会签开始节点 //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 = GetOneForkLineCanCheckNodeId(fromForkStartNode, wfruntime, tag); if (!string.IsNullOrEmpty(canCheckId)) break; } if (canCheckId == "") { throw (new Exception("审核异常,找不到审核节点")); } flowInstanceOperationHistory.F_Content = "【" + wfruntime.Nodes[canCheckId].name + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】" + (tag.Taged == 1 ? "同意" : "不同意") + ",备注:" + tag.Description; wfruntime.MakeTagNode(canCheckId, tag); //标记审核节点状态 string res = wfruntime.NodeConfluence(canCheckId, tag); if (res == TagState.No.ToString("D")) { flowInstance.F_IsFinish = 3; } else if (!string.IsNullOrEmpty(res)) { flowInstance.F_PreviousId = flowInstance.F_ActivityId; flowInstance.F_ActivityId = wfruntime.nextNodeId; flowInstance.F_ActivityType = wfruntime.nextNodeType; flowInstance.F_ActivityName = wfruntime.nextNode.name; flowInstance.F_IsFinish = (wfruntime.nextNodeType == 4 ? 1 : 0); flowInstance.F_MakerList = wfruntime.nextNodeType == 4 ? "" : GetNextMakers(wfruntime, request); await AddTransHistory(wfruntime); } else { //会签过程中,需要更新用户 flowInstance.F_MakerList = GetForkNodeMakers(wfruntime, wfruntime.currentNodeId); await AddTransHistory(wfruntime); } } #endregion 会签 #region 一般审核 else { wfruntime.MakeTagNode(wfruntime.currentNodeId, tag); if (tag.Taged == (int)TagState.Ok) { var roleIds = user.RoleId.Split(','); if (wfruntime.currentNode.setInfo.NodeDesignate == Setinfo.MORE_USER_MANAGER && roleIds.Intersect(wfruntime.currentNode.setInfo.NodeDesignateData.roles).Count() == 0) { flowInstance.F_MakerList = GetNodeMarkers(wfruntime.currentNode); } else { flowInstance.F_PreviousId = flowInstance.F_ActivityId; flowInstance.F_ActivityId = wfruntime.nextNodeId; flowInstance.F_ActivityType = wfruntime.nextNodeType; flowInstance.F_ActivityName = wfruntime.nextNode.name; flowInstance.F_IsFinish = (wfruntime.nextNodeType == 4 ? 1 : 0); flowInstance.F_MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime, request) : ""); } await AddTransHistory(wfruntime); } else { flowInstance.F_IsFinish = 3; //表示该节点不同意 } flowInstanceOperationHistory.F_Content = "【" + wfruntime.currentNode.name + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】" + (tag.Taged == 1 ? "同意" : "不同意") + ",备注:" + tag.Description; } #endregion 一般审核 wfruntime.RemoveNode(wfruntime.nextNodeId); flowInstance.F_SchemeContent = wfruntime.ToSchemeObj().ToJson(); var formDic = request.F_FrmData.ToObject>(); var oldformDic = flowInstance.F_FrmData.ToObject>(); foreach (var item in oldformDic) if (!formDic.ContainsKey(item.Key)) formDic.Add(item.Key, item.Value); if (flowInstance.F_FrmType == 1) { var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray(); var t = referencedAssemblies .SelectMany(a => a.GetTypes().Where(t => t.FullName.Contains("HT.Cloud.Service.") && t.FullName.Contains("." + flowInstance.F_DbName + "Service"))).First(); ICustomerForm icf = (ICustomerForm)GlobalContext.GetRequiredService(t); flowInstance.F_FrmData = formDic.ToJson(); await icf.Edit(flowInstance.F_Id, flowInstance.F_FrmData); } else { if (!string.IsNullOrEmpty(flowInstance.F_DbName)) { formDic.TryAdd("F_LastModifyUserId", this.currentuser.UserId); formDic.TryAdd("F_LastModifyTime", DateTime.Now); formDic.TryAdd("F_LastModifyUserName", this.currentuser.UserName); flowInstance.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(flowInstance.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) List newID = data.Select(a => a.DbColumnName).ToList();//新增数据(新ID) foreach (var item in oldID.Except(newID)) formDic.Remove(item); await repository.Db.Updateable(formDic).AS(flowInstance.F_DbName).WhereColumns(data.FirstOrDefault(a => a.IsPrimarykey).DbColumnName).ExecuteCommandAsync(); } } await repository.Update(flowInstance); flowInstanceOperationHistory.F_FrmData = flowInstance.F_FrmData; await repository.Db.Updateable(flowInstance).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); await repository.Db.Insertable(flowInstanceOperationHistory).ExecuteCommandAsync(); MessageEntity msg = new MessageEntity(); msg.F_CreatorUserName = currentuser.UserName; msg.F_EnabledMark = true; if (flowInstance.F_IsFinish == 1) { msg.F_MessageInfo = flowInstance.F_CustomName + "--流程已完成"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; msg.F_ToUserId = flowInstance.F_CreatorUserId; msg.F_ClickRead = true; msg.F_KeyValue = flowInstance.F_Id; } else if (flowInstance.F_IsFinish == 3) { msg.F_MessageInfo = flowInstance.F_CustomName + "--流程已终止"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; var makerList = repository.Db.Queryable().Where(a => a.F_InstanceId == flowInstance.F_Id && a.F_CreatorUserId != currentuser.UserId).Select(a => a.F_CreatorUserId).Distinct().ToList(); msg.F_ToUserId = flowInstance.F_CreatorUserId; msg.F_ClickRead = true; msg.F_KeyValue = flowInstance.F_Id; } else { msg.F_MessageInfo = flowInstance.F_CustomName + "--流程待处理"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress.Remove(module.F_UrlAddress.Length - 5, 5) + "ToDoFlow"; msg.F_HrefTarget = module.F_Target; msg.F_ToUserId = flowInstance.F_MakerList == "1" ? "" : flowInstance.F_MakerList; msg.F_ClickRead = false; msg.F_KeyValue = flowInstance.F_Id; } msg.F_MessageType = 2; var lastmsg = repository.Db.Queryable().Where(a => a.F_ClickRead == false && a.F_KeyValue == flowInstance.F_Id).OrderBy(a => a.F_CreatorTime, OrderByType.Desc).First(); if (lastmsg != null && !await repository.Db.Queryable().Where(a => a.F_MessageId == lastmsg.F_Id).AnyAsync()) { await messageApp.ReadMsgForm(lastmsg.F_Id); } await messageApp.SubmitForm(msg); repository.Db.Ado.CommitTran(); wfruntime.NotifyThirdParty(_httpClientFactory.CreateClient(), tag); return true; } //会签时,获取一条会签分支上面是否有用户可审核的节点 private string GetOneForkLineCanCheckNodeId(FlowNode fromForkStartNode, FlowRuntime wfruntime, Tag tag) { string canCheckId = ""; var node = fromForkStartNode; do //沿一条分支线路执行,直到遇到会签结束节点 { var makerList = GetNodeMarkers(node); if (node.setInfo.Taged == null && !string.IsNullOrEmpty(makerList) && makerList.Split(',').Any(one => tag.UserId == one)) { canCheckId = node.id; break; } node = wfruntime.GetNextNode(node.id); } while (node.type != FlowNode.JOIN); return canCheckId; } /// /// 寻找下一步的执行人 /// 一般用于本节点审核完成后,修改流程实例的当前执行人,可以做到通知等功能 /// /// private string GetNextMakers(FlowRuntime wfruntime, NodeDesignateEntity request = null) { string makerList = ""; if (wfruntime.nextNodeId == "-1") { throw (new Exception("无法寻找到下一个节点")); } if (wfruntime.nextNodeType == 0)//如果是会签节点 { makerList = GetForkNodeMakers(wfruntime, wfruntime.nextNodeId); } else if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE) { //如果是运行时指定角色 if (wfruntime.nextNode.setInfo.NodeDesignate != request.NodeDesignateType) { throw new Exception("前端提交的节点权限类型异常,请检查流程"); } var users = new List(); foreach (var item in request.NodeDesignates) { var temps = repository.Db.Queryable().Where(a => a.F_RoleId.Contains(item) && a.F_EnabledMark == true && a.F_DeleteMark == false).Select(a => a.F_Id).ToList(); if (temps != null && temps.Count > 0) { users.AddRange(temps); } } makerList = JsonHelper.ArrayToString(users.Distinct().ToList(), makerList); } else if (wfruntime.nextNode.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER) { //如果是运行时指定用户 if (wfruntime.nextNode.setInfo.NodeDesignate != request.NodeDesignateType) { throw new Exception("前端提交的节点权限类型异常,请检查流程"); } makerList = JsonHelper.ArrayToString(request.NodeDesignates, makerList); } else { makerList = GetNodeMarkers(wfruntime.nextNode); if (string.IsNullOrEmpty(makerList)) { throw (new Exception("无法寻找到节点的审核者,请查看流程设计是否有问题!")); } } return makerList; } /// /// 获取会签开始节点的所有可执行者 /// /// 会签开始节点 /// private string GetForkNodeMakers(FlowRuntime wfruntime, string forkNodeId) { string makerList = ""; foreach (string fromForkStartNodeId in wfruntime.FromNodeLines[forkNodeId].Select(u => u.to)) { var fromForkStartNode = wfruntime.Nodes[fromForkStartNodeId]; //与会前开始节点直接连接的节点 if (makerList != "") { makerList += ","; } makerList += GetOneForkLineMakers(fromForkStartNode, wfruntime); } return makerList; } //获取会签一条线上的审核者,该审核者应该是已审核过的节点的下一个人 private string GetOneForkLineMakers(FlowNode fromForkStartNode, FlowRuntime wfruntime) { string markers = ""; var node = fromForkStartNode; do //沿一条分支线路执行,直到遇到第一个没有审核的节点 { if (node.setInfo != null && node.setInfo.Taged != null) { if (node.type != FlowNode.FORK && node.setInfo.Taged != (int)TagState.Ok) //如果节点是不同意或驳回,则不用再找了 { 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}是会签节点,不能用所有人,请检查!")); } if (markers != "") { markers += ","; } markers += marker; break; } while (node.type != FlowNode.JOIN); return markers; } /// /// 寻找该节点执行人 /// /// /// private string GetNodeMarkers(FlowNode node) { string makerList = ""; if (node.setInfo != null) { if (node.setInfo.NodeDesignate == Setinfo.ALL_USER)//所有成员 { makerList = "1"; } else if (node.setInfo.NodeDesignate == Setinfo.SPECIAL_USER)//指定成员 { makerList = JsonHelper.ArrayToString(node.setInfo.NodeDesignateData.users, makerList); } else if (node.setInfo.NodeDesignate == Setinfo.SPECIAL_ROLE) //指定角色 { List list = new List(); List users = new List(); foreach (var item in node.setInfo.NodeDesignateData.roles) { var temp = repository.Db.Queryable().Where(a => a.F_RoleId.Contains(item)).ToList(); var tempList = new List(); if (node.setInfo.NodeDesignateData.currentDepart) { var currentDepartment = repository.Db.Queryable().InSingle(flowCreator).F_OrganizeId.Split(',').ToList(); foreach (var user in temp) { var nextCurrentDepartment = user.F_OrganizeId.Split(',').ToList(); if (TextHelper.IsArrayIntersection(currentDepartment, nextCurrentDepartment)) { tempList.Add(user); } } } else { tempList = temp; } var tempFinal = tempList.Select(a => a.F_Id).ToList(); users.AddRange(tempFinal); } users = users.Distinct().ToList(); makerList = JsonHelper.ArrayToString(users, makerList); } else if (node.setInfo.NodeDesignate == Setinfo.DEPARTMENT_MANAGER)//部门负责人 { var orgs = node.setInfo.NodeDesignateData.orgs; if (node.setInfo.NodeDesignateData.currentDepart) { var temp = repository.Db.Queryable().InSingle(flowCreator); orgs = temp.F_OrganizeId.Split(','); } var managers = repository.Db.Queryable().Where(a => orgs.Contains(a.F_Id) && !string.IsNullOrEmpty(a.F_ManagerId)).Select(a => a.F_ManagerId).ToList(); makerList = JsonHelper.ArrayToString(managers, makerList); } else if (node.setInfo.NodeDesignate == Setinfo.USER_MANAGER || node.setInfo.NodeDesignate == Setinfo.MORE_USER_MANAGER)//直属上级、直属上级多级负责人 { var temp = repository.Db.Queryable().InSingle(currentuser.UserId); if (temp != null) { makerList = temp.F_ManagerId; } } else if (node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_ROLE || node.setInfo.NodeDesignate == Setinfo.RUNTIME_SPECIAL_USER) { //如果是运行时选定的用户,则暂不处理。由上个节点审批时选定 } } else //如果没有设置节点信息,默认所有人都可以审核 { makerList = "1"; } return makerList; } /// /// 判定节点需要选择执行人或执行角色 /// /// /// private void CheckNodeDesignate(NodeDesignateEntity request) { if ((request.NodeDesignateType == Setinfo.RUNTIME_SPECIAL_ROLE || request.NodeDesignateType == Setinfo.RUNTIME_SPECIAL_USER) && request.NodeDesignates.Length == 0) { throw new Exception("下个节点需要选择执行人或执行角色"); } } /// /// 返回用于处理流程节点 /// /// /// public async Task GetForVerification(string id) { var flowinstance = await GetForm(id); var runtime = new FlowRuntime(flowinstance); if (runtime.nextNodeType != -1 && runtime.nextNode != null && runtime.nextNode.setInfo != null && runtime.nextNodeType != 4) { flowinstance.NextNodeDesignateType = runtime.nextNode.setInfo.NodeDesignate; if (flowinstance.NextNodeDesignateType == Setinfo.SPECIAL_USER) { flowinstance.NextNodeDesignates = runtime.nextNode.setInfo.NodeDesignateData.users; flowinstance.NextMakerName = string.Join(',', repository.Db.Queryable().Where(a => flowinstance.NextNodeDesignates.Contains(a.F_Id)).Select(a => a.F_RealName).ToList()); } else if (flowinstance.NextNodeDesignateType == Setinfo.SPECIAL_ROLE) { flowinstance.NextNodeDesignates = runtime.nextNode.setInfo.NodeDesignateData.roles; List list = new List(); List users = new List(); foreach (var item in flowinstance.NextNodeDesignates) { var temp = repository.Db.Queryable().Where(a => a.F_RoleId.Contains(item)).ToList(); var tempList = new List(); if (runtime.nextNode.setInfo.NodeDesignateData.currentDepart) { var currentDepartment = repository.Db.Queryable().InSingle(flowinstance.F_CreatorUserId).F_OrganizeId.Split(',').ToList(); foreach (var user in temp) { var nextCurrentDepartment = user.F_OrganizeId.Split(',').ToList(); if (TextHelper.IsArrayIntersection(currentDepartment, nextCurrentDepartment)) { tempList.Add(user); } } } else { tempList = temp; } var tempFinal = tempList.Select(a => a.F_Id).ToList(); users.AddRange(tempFinal); } users = users.Distinct().ToList(); flowinstance.NextMakerName = string.Join(',', repository.Db.Queryable().Where(a => users.Contains(a.F_Id)).Select(a => a.F_RealName).ToList()); } else if (flowinstance.NextNodeDesignateType == Setinfo.DEPARTMENT_MANAGER)//部门负责人 { var orgs = runtime.nextNode.setInfo.NodeDesignateData.orgs; if (runtime.nextNode.setInfo.NodeDesignateData.currentDepart) { var userEntity = repository.Db.Queryable().InSingle(flowinstance.F_CreatorUserId); orgs = userEntity.F_OrganizeId.Split(','); } var departments = repository.Db.Queryable().Where(a => orgs.Contains(a.F_Id) && !string.IsNullOrEmpty(a.F_ManagerId)).Select(a => a.F_ManagerId).ToList(); var departmentNames = repository.Db.Queryable().Where(a => departments.Contains(a.F_Id)).Select(a => a.F_RealName).ToList(); flowinstance.NextMakerName = string.Join(',', departmentNames); } else if (flowinstance.NextNodeDesignateType == Setinfo.USER_MANAGER || flowinstance.NextNodeDesignateType == Setinfo.MORE_USER_MANAGER)//直属上级、直属上级多级负责人 { var userEntity = repository.Db.Queryable().InSingle(currentuser.UserId); if (userEntity != null) { var manager = repository.Db.Queryable().InSingle(userEntity.F_ManagerId); flowinstance.NextMakerName = manager?.F_RealName; } } } if (runtime.currentNode != null && runtime.currentNode.setInfo != null && runtime.currentNodeType != 4) { flowinstance.CurrentNodeDesignateType = runtime.currentNode.setInfo.NodeDesignate; var roles = runtime.currentNode.setInfo.NodeDesignateData.roles; var currentRoles = currentuser.RoleId.Split(","); if (flowinstance.CurrentNodeDesignateType == Setinfo.MORE_USER_MANAGER && currentRoles.Intersect(roles).Count() == 0) { var userEntity = repository.Db.Queryable().InSingle(currentuser.UserId); if (userEntity != null) { var manager = repository.Db.Queryable().InSingle(userEntity.F_ManagerId); flowinstance.NextMakerName = manager?.F_RealName; } } if (flowinstance.F_MakerList != "1" && !string.IsNullOrEmpty(flowinstance.F_MakerList)) { var temps = flowinstance.F_MakerList.Split(','); flowinstance.CurrentMakerName = string.Join(',', repository.Db.Queryable().Where(a => temps.Contains(a.F_Id)).Select(a => a.F_RealName).ToList()); } else { flowinstance.CurrentMakerName = "所有人"; } var formDatas = flowinstance.F_FrmContentData.Split(','); var formlist = new List(); if (runtime.currentNode.setInfo.CanWriteFormItemIds!=null) foreach (var item in runtime.currentNode.setInfo.CanWriteFormItemIds) formlist.Add(formDatas[item.ToInt()]); flowinstance.CanWriteFormItems = formlist.ToArray(); } return flowinstance; } #endregion 获取各种节点的流程审核者 #region 提交数据 /// /// 添加扭转记录 /// private async Task AddTransHistory(FlowRuntime wfruntime) { var tag = currentuser; await repository.Db.Insertable(new FlowInstanceTransitionHistory { F_Id = Utils.GuId(), F_InstanceId = wfruntime.flowInstanceId, F_CreatorUserId = tag.UserId, F_CreatorTime = DateTime.Now, F_CreatorUserName = tag.UserName, F_FromNodeId = wfruntime.currentNodeId, F_FromNodeName = wfruntime.currentNode.name, F_FromNodeType = wfruntime.currentNodeType, F_ToNodeId = wfruntime.nextNodeId, F_ToNodeName = wfruntime.nextNode.name, F_ToNodeType = wfruntime.nextNodeType, F_IsFinish = wfruntime.nextNodeType == 4 ? true : false, F_TransitionSate = false }).ExecuteCommandAsync(); } /// /// 添加扭转记录 /// private async Task AddRejectTransHistory(FlowRuntime wfruntime, FlowRuntime prruntime) { var tag = currentuser; await repository.Db.Insertable(new FlowInstanceTransitionHistory { F_Id = Utils.GuId(), F_InstanceId = wfruntime.flowInstanceId, F_CreatorUserId = tag.UserId, F_CreatorTime = DateTime.Now, F_CreatorUserName = tag.UserName, F_FromNodeId = wfruntime.currentNodeId, F_FromNodeName = wfruntime.currentNode.name, F_FromNodeType = wfruntime.currentNodeType, F_ToNodeId = prruntime.currentNodeId, F_ToNodeName = prruntime.currentNode.name, F_ToNodeType = prruntime.currentNodeType, F_IsFinish = false, F_TransitionSate = false }).ExecuteCommandAsync(); } public async Task Verification(VerificationExtend entity) { bool isReject = TagState.Reject.Equals((TagState)Int32.Parse(entity.F_VerificationFinally)); if (isReject) //驳回 { await NodeReject(entity); } else { await NodeVerification(entity); } } public async Task CreateInstance(FlowinstanceEntity entity) { var nodeDesignate = new NodeDesignateEntity(); nodeDesignate.NodeDesignates = entity.NextNodeDesignates; nodeDesignate.NodeDesignateType = entity.NextNodeDesignateType; CheckNodeDesignate(nodeDesignate); entity.F_EnabledMark = true; FlowschemeEntity scheme = null; if (!string.IsNullOrEmpty(entity.F_SchemeId)) { scheme = await repository.Db.Queryable().InSingleAsync(entity.F_SchemeId); } if (scheme == null) { throw new Exception("该流程模板已不存在,请重新设计流程"); } entity.F_SchemeContent = scheme.F_SchemeContent; var form = await repository.Db.Queryable().InSingleAsync(scheme.F_FrmId); if (form == null) { throw new Exception("该流程模板对应的表单已不存在,请重新设计流程"); } entity.F_FrmContentData = form.F_ContentData; entity.F_FrmContent = form.F_Content; entity.F_FrmContentParse = form.F_ContentParse; entity.F_FrmType = form.F_FrmType; entity.F_FrmId = form.F_Id; Dictionary dic = JsonHelper.ToObject>(entity.F_FrmData); if (!dic.ContainsKey("申请人")) { dic.Add("申请人", currentuser.UserId); } if (!dic.ContainsKey("所属部门")) { dic.Add("所属部门", currentuser.OrganizeId); } entity.F_FrmData = dic.ToJson(); entity.F_InstanceSchemeId = ""; entity.F_DbName = form.F_WebId; if (entity.F_FrmType ==0) entity.F_DbName = form.F_DbName; entity.F_FlowLevel = 0; entity.Create(); flowCreator = currentuser.UserId; //创建运行实例 var wfruntime = new FlowRuntime(entity); var user = currentuser; #region 根据运行实例改变当前节点状态 entity.F_ActivityId = wfruntime.nextNodeId; entity.F_ActivityType = wfruntime.GetNextNodeType(); entity.F_ActivityName = wfruntime.nextNode.name; entity.F_PreviousId = wfruntime.currentNodeId; entity.F_CreatorUserName = user.UserName; entity.F_MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime, nodeDesignate) : ""); entity.F_IsFinish = (wfruntime.GetNextNodeType() == 4 ? 1 : 0); repository.Db.Ado.BeginTran(); wfruntime.flowInstanceId = entity.F_Id; //复杂表单提交 if (entity.F_FrmType == 1) { var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray(); var t = referencedAssemblies .SelectMany(a => a.GetTypes().Where(t => t.FullName.Contains("HT.Cloud.Service.") && t.FullName.Contains("." + entity.F_DbName + "Service"))).First(); ICustomerForm icf = (ICustomerForm)GlobalContext.GetRequiredService(t); await icf.Add(entity.F_Id, entity.F_FrmData); } else { if (!string.IsNullOrEmpty(entity.F_DbName)) { var formDic = entity.F_FrmData.ToObject>(); formDic.TryAdd("F_CreatorUserId", this.currentuser.UserId); formDic.TryAdd("F_CreatorTime", DateTime.Now); formDic.TryAdd("F_CreatorUserName", this.currentuser.UserName); formDic.TryAdd("F_Id", Utils.GuId()); entity.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(entity.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) List newID = data.Select(a => a.DbColumnName).ToList();//新增数据(新ID) foreach (var item in oldID.Except(newID)) formDic.Remove(item); await repository.Db.Insertable(formDic).AS(entity.F_DbName).ExecuteCommandAsync(); } } await repository.Db.Insertable(entity).ExecuteCommandAsync(); #endregion 根据运行实例改变当前节点状态 #region 流程操作记录 FlowInstanceOperationHistory processOperationHistoryEntity = new FlowInstanceOperationHistory { F_Id = Utils.GuId(), F_InstanceId = entity.F_Id, F_CreatorUserId = entity.F_CreatorUserId, F_CreatorUserName = entity.F_CreatorUserName, F_CreatorTime = entity.F_CreatorTime, F_FrmData = entity.F_FrmData, F_Content = "【创建】" + entity.F_CreatorUserName + "创建了一个流程【" + entity.F_Code + "/" + entity.F_CustomName + "】" }; await repository.Db.Insertable(processOperationHistoryEntity).ExecuteCommandAsync(); #endregion 流程操作记录 await AddTransHistory(wfruntime); MessageEntity msg = new MessageEntity(); msg.F_CreatorUserName = currentuser.UserName; msg.F_EnabledMark = true; if (entity.F_IsFinish == 1) { msg.F_MessageInfo = entity.F_CustomName + "--流程已完成"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; msg.F_ClickRead = true; msg.F_KeyValue = entity.F_Id; } else if (entity.F_IsFinish == 3) { msg.F_MessageInfo = entity.F_CustomName + "--流程已终止"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; var makerList = repository.Db.Queryable().Where(a => a.F_InstanceId == entity.F_Id && a.F_CreatorUserId != currentuser.UserId).Select(a => a.F_CreatorUserId).Distinct().ToList(); msg.F_ToUserId = entity.F_CreatorUserId; msg.F_ClickRead = true; msg.F_KeyValue = entity.F_Id; } else { msg.F_MessageInfo = entity.F_CustomName + "--流程待处理"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress.Remove(module.F_UrlAddress.Length - 5, 5) + "ToDoFlow"; msg.F_HrefTarget = module.F_Target; msg.F_ClickRead = false; msg.F_KeyValue = entity.F_Id; } msg.F_MessageType = 2; msg.F_ToUserId = entity.F_MakerList == "1" ? "" : entity.F_MakerList; var lastmsg = repository.Db.Queryable().Where(a => a.F_ClickRead == false && a.F_KeyValue == entity.F_Id).OrderBy(a => a.F_CreatorTime, OrderByType.Desc).First(); if (lastmsg != null && !await repository.Db.Queryable().Where(a => a.F_MessageId == lastmsg.F_Id).AnyAsync()) { await messageApp.ReadMsgForm(lastmsg.F_Id); } await messageApp.SubmitForm(msg); repository.Db.Ado.CommitTran(); } public async Task UpdateInstance(FlowinstanceEntity entity) { var nodeDesignate = new NodeDesignateEntity(); nodeDesignate.NodeDesignates = entity.NextNodeDesignates; nodeDesignate.NodeDesignateType = entity.NextNodeDesignateType; CheckNodeDesignate(nodeDesignate); FlowschemeEntity scheme = null; if (!string.IsNullOrEmpty(entity.F_SchemeId)) { scheme = await repository.Db.Queryable().InSingleAsync(entity.F_SchemeId); } if (scheme == null) { throw new Exception("该流程模板已不存在,请重新设计流程"); } entity.F_SchemeContent = scheme.F_SchemeContent; var form = await repository.Db.Queryable().InSingleAsync(scheme.F_FrmId); if (form == null) { throw new Exception("该流程模板对应的表单已不存在,请重新设计流程"); } Dictionary dic = JsonHelper.ToObject>(entity.F_FrmData); if (!dic.ContainsKey("申请人")) { dic.Add("申请人", currentuser.UserId); } if (!dic.ContainsKey("所属部门")) { dic.Add("所属部门", currentuser.OrganizeId); } entity.F_FrmData = dic.ToJson(); var oldEntity = await repository.FindEntity(entity.F_Id); var wfruntime = new FlowRuntime(oldEntity); entity.F_FrmContentData = form.F_ContentData; entity.F_FrmContentParse = form.F_ContentParse; entity.F_FrmType = form.F_FrmType; entity.F_FrmId = form.F_Id; entity.F_InstanceSchemeId = ""; entity.F_DbName = form.F_WebId; if (entity.F_FrmType == 0) entity.F_DbName = form.F_DbName; entity.F_FlowLevel = 0; flowCreator = currentuser.UserId; //创建运行实例 wfruntime = new FlowRuntime(entity); var user = currentuser; #region 根据运行实例改变当前节点状态 entity.F_ActivityId = wfruntime.nextNodeId; entity.F_ActivityType = wfruntime.GetNextNodeType(); entity.F_ActivityName = wfruntime.nextNode.name; entity.F_PreviousId = wfruntime.currentNodeId; entity.F_CreatorUserName = user.UserName; entity.F_MakerList = (wfruntime.GetNextNodeType() != 4 ? GetNextMakers(wfruntime, nodeDesignate) : ""); entity.F_IsFinish = (wfruntime.GetNextNodeType() == 4 ? 1 : 0); var formDic = entity.F_FrmData.ToObject>(); var oldformDic = oldEntity.F_FrmData.ToObject>(); foreach (var item in oldformDic) if (!formDic.ContainsKey(item.Key)) formDic.Add(item.Key, item.Value); repository.Db.Ado.BeginTran(); wfruntime.flowInstanceId = entity.F_Id; //复杂表单提交 if (entity.F_FrmType == 1) { var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray(); var t = referencedAssemblies .SelectMany(a => a.GetTypes().Where(t => t.FullName.Contains("HT.Cloud.Service.") && t.FullName.Contains("." + entity.F_DbName + "Service"))).First(); ICustomerForm icf = (ICustomerForm)GlobalContext.GetRequiredService(t); entity.F_FrmData = formDic.ToJson(); await icf.Edit(entity.F_Id, formDic.ToJson()); } else { if (!string.IsNullOrEmpty(entity.F_DbName)) { formDic.TryAdd("F_LastModifyUserId", this.currentuser.UserId); formDic.TryAdd("F_LastModifyTime", DateTime.Now); formDic.TryAdd("F_LastModifyUserName", this.currentuser.UserName); entity.F_FrmData = formDic.ToJson(); var data = repository.Db.DbMaintenance.GetColumnInfosByTableName(entity.F_DbName, false); List oldID = formDic.Keys.ToList();//原来数据(原来ID) List newID = data.Select(a => a.DbColumnName).ToList();//新增数据(新ID) foreach (var item in oldID.Except(newID)) formDic.Remove(item); await repository.Db.Updateable(formDic).AS(entity.F_DbName).WhereColumns(data.FirstOrDefault(a=>a.IsPrimarykey).DbColumnName).ExecuteCommandAsync(); } } await repository.Db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); #endregion 根据运行实例改变当前节点状态 #region 流程操作记录 FlowInstanceOperationHistory processOperationHistoryEntity = new FlowInstanceOperationHistory { F_Id = Utils.GuId(), F_InstanceId = entity.F_Id, F_CreatorUserId = user.UserId, F_CreatorUserName = entity.F_CreatorUserName, F_CreatorTime = DateTime.Now, F_FrmData= entity.F_FrmData, F_Content = "【修改】" + entity.F_CreatorUserName + "修改了一个流程【" + entity.F_Code + "/" + entity.F_CustomName + "】" }; await repository.Db.Insertable(processOperationHistoryEntity).ExecuteCommandAsync(); #endregion 流程操作记录 await AddTransHistory(wfruntime); MessageEntity msg = new MessageEntity(); msg.F_CreatorUserName = currentuser.UserName; msg.F_EnabledMark = true; if (entity.F_IsFinish == 1) { msg.F_MessageInfo = entity.F_CustomName + "--流程已完成"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; msg.F_ClickRead = true; msg.F_KeyValue = entity.F_Id; } else if (entity.F_IsFinish == 3) { msg.F_MessageInfo = entity.F_CustomName + "--流程已终止"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress; msg.F_HrefTarget = module.F_Target; var makerList = repository.Db.Queryable().Where(a => a.F_InstanceId == entity.F_Id && a.F_CreatorUserId != currentuser.UserId).Select(a => a.F_CreatorUserId).Distinct().ToList(); msg.F_ToUserId = entity.F_CreatorUserId; msg.F_ClickRead = true; msg.F_KeyValue = entity.F_Id; } else { msg.F_MessageInfo = entity.F_CustomName + "--流程待处理"; var module = repository.Db.Queryable().First(a => a.F_EnCode == className); msg.F_Href = module.F_UrlAddress.Remove(module.F_UrlAddress.Length - 5, 5) + "ToDoFlow"; msg.F_HrefTarget = module.F_Target; msg.F_ClickRead = false; msg.F_KeyValue = entity.F_Id; } msg.F_MessageType = 2; msg.F_ToUserId = entity.F_MakerList == "1" ? "" : entity.F_MakerList; var lastmsg = repository.Db.Queryable().Where(a => a.F_ClickRead == false && a.F_KeyValue == entity.F_Id).OrderBy(a => a.F_CreatorTime, OrderByType.Desc).First(); if (lastmsg != null && !await repository.Db.Queryable().Where(a => a.F_MessageId == lastmsg.F_Id).AnyAsync()) { await messageApp.ReadMsgForm(lastmsg.F_Id); } await messageApp.SubmitForm(msg); repository.Db.Ado.CommitTran(); msg.F_ClickRead = false; msg.F_KeyValue = entity.F_Id; } public async Task DeleteForm(string keyValue) { var ids = keyValue.Split(','); await repository.Update(a => ids.Contains(a.F_Id), a => new FlowinstanceEntity { F_EnabledMark = false }); } public async Task CancleForm(string keyValue) { var user = currentuser; FlowinstanceEntity flowInstance = await GetForm(keyValue); flowCreator = flowInstance.F_CreatorUserId; FlowRuntime wfruntime = new FlowRuntime(flowInstance); string resnode = ""; resnode = wfruntime.RejectNode("1"); var tag = new Tag { Description = "流程撤回", Taged = (int)TagState.Reject, UserId = user.UserId, UserName = user.UserName }; wfruntime.MakeTagNode(wfruntime.currentNodeId, tag); flowInstance.F_IsFinish = 2;//2表示撤回(需要申请者重新提交表单) repository.Db.Ado.BeginTran(); if (resnode != "") { wfruntime.RemoveNode(resnode); flowInstance.F_SchemeContent = wfruntime.ToSchemeObj().ToJson(); flowInstance.F_ActivityId = resnode; var prruntime = new FlowRuntime(flowInstance); prruntime.MakeTagNode(prruntime.currentNodeId, tag); flowInstance.F_PreviousId = prruntime.previousId; flowInstance.F_ActivityType = prruntime.GetNodeType(resnode); flowInstance.F_ActivityName = prruntime.Nodes[resnode].name; if (resnode == wfruntime.startNodeId) { flowInstance.F_MakerList = flowInstance.F_CreatorUserId; } else { flowInstance.F_MakerList = await repository.Db.Queryable().Where(a => a.F_FromNodeId == resnode && a.F_ToNodeId == prruntime.nextNodeId).OrderBy(a => a.F_CreatorTime, OrderByType.Desc).Select(a => a.F_CreatorUserId).FirstAsync();//当前节点可执行的人信息 } await AddRejectTransHistory(wfruntime, prruntime); await repository.Update(flowInstance); } await repository.Db.Insertable(new FlowInstanceOperationHistory { F_Id = Utils.GuId(), F_InstanceId = keyValue , F_CreatorUserId = user.UserId , F_CreatorUserName = user.UserName , F_CreatorTime = DateTime.Now , F_FrmData = flowInstance.F_FrmData , F_Content = "【" + wfruntime.currentNode.name + "】【" + DateTime.Now.ToString("yyyy-MM-dd HH:mm") + "】撤回,备注:流程撤回" }).ExecuteCommandAsync(); repository.Db.Ado.CommitTran(); wfruntime.NotifyThirdParty(_httpClientFactory.CreateClient(), tag); } #endregion 提交数据 } }