using ce.autofac.extension; using Infrastructure; using Infrastructure.Extensions; using Infrastructure.Helpers; using Microsoft.Extensions.Configuration; using OpenAuth.App.Base; using OpenAuth.App.BasicQueryService; using OpenAuth.App.Config; using OpenAuth.App.Interface; using OpenAuth.App.Request; using OpenAuth.Repository; using OpenAuth.Repository.Core; using OpenAuth.Repository.Domain; using SqlSugar; using System.Data; using System.Linq; using Newtonsoft.Json; using OpenAuth.App.BaseApp.Jobs; using System.Text; using DocumentFormat.OpenXml.Spreadsheet; using Infrastructure.Utilities; using OpenAuth.App.BaseApp.Base; using System.Diagnostics; using NPOI.Util; namespace OpenAuth.App { public partial class WFProcessApp : SqlSugarBaseApp { ISqlSugarClient client; UserManager userManager; PositionManager positionManager; IConfiguration _configuration; OpenJobApp _job; public WFProcessApp(SqlSugar.ISugarUnitOfWork unitWork, SqlSugar.ISimpleClient repository, IAuth auth, UserManager userManager, OpenJobApp job, PositionManager positionManager, IConfiguration _configuration ) : base(unitWork, repository, auth) { client = base.Repository.AsSugarClient(); this.userManager = userManager; this.positionManager = positionManager; this._configuration = _configuration; _job = job; } #region 获取数据 /// /// 获取流程列表 /// /// 分页参数 /// 查询参数 /// public async Task>> GetPageList(PageReq pageReq, WFProcessSearchDto searchParams) { RefAsync totalCount = 0; var exp = Expressionable.Create() .AndIF(!string.IsNullOrEmpty(searchParams.Keyword), t => t.Title.Contains(searchParams.Keyword) || t.SchemeName.Contains(searchParams.Keyword)) .AndIF(!string.IsNullOrEmpty(searchParams.Code), t => t.SchemeCode == searchParams.Code) .AndIF(searchParams.StartDate != null && searchParams.EndDate != null, t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate); if (searchParams.Type == 3) { exp = exp.And(t => t.EnabledMark == 3); } else { exp = exp.And(t => t.EnabledMark == 1); if (searchParams.Type == 1) { exp = exp.And(t => t.IsFinished == 1); } else { exp = exp.And(t => t.IsFinished == 0); } } var list = await client.Queryable() .Where(exp.ToExpression()) .OrderByDescending(t => t.CreateDate) .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); return new PageInfo> { Items = list, Total = totalCount }; } /// /// 获取我的流程 /// /// 分页参数 /// 查询参数 /// 1正常2草稿3作废 /// public async Task>> GetMyPageList(PageReq pageReq, WFProcessSearchDto searchParams, int type) { RefAsync totalCount = 0; var userId = _auth.GetUserId(); var expression = Expressionable.Create(); expression = expression.And(t => t.CreateUserId == userId || t.UserId == userId); if (type == 2) { expression = expression.And(t => t.EnabledMark == 2); } else { expression = expression.And(t => t.EnabledMark != 2); } if (!string.IsNullOrEmpty(searchParams.Keyword)) { expression = expression.And(t => t.Title.Contains(searchParams.Keyword) || t.SchemeName.Contains(searchParams.Keyword)); } if (!string.IsNullOrEmpty(searchParams.Code)) { expression = expression.And(t => t.SchemeCode == searchParams.Code); } if (searchParams.StartDate != null && searchParams.EndDate != null) { expression = expression.And(t => t.CreateDate >= searchParams.StartDate && t.CreateDate <= searchParams.EndDate); } var list = await client.Queryable() .Where(expression.ToExpression()) .OrderByDescending(t => t.CreateDate) .ToPageListAsync(pageReq.page, pageReq.limit, totalCount); return new PageInfo> { Items = list, Total = totalCount }; } /// /// 获取流程进程实体 /// /// 主键 /// public async Task GetEntity(string keyValue) { return await base.Repository.GetByIdAsync(keyValue); } #endregion #region 保存更新删除 /// /// 删除流程进程实体 /// /// 流程进程主键 public async Task DeleteEntity(string processId) { return await base.Repository.DeleteByIdAsync(processId); } #endregion #region 流程API /// /// 保存草稿 /// /// 流程进程主键 /// 流程模板编码 /// 创建人 /// 父级流程进程主键 /// 父级流程节点Id /// 父级任务id /// 是否为子流程 /// 流程标题 /// public async Task> SaveDraft(string processId, string schemeCode, string userId, string instanceInfo, string parentProcessId, string parentNodeId, string parentTaskId, int isChild, string title = "") { var flag = false; var currentUser = _auth.GetCurrentUser().User; // 判断当前流程进程是否有保存过 var processEntity = await GetEntity(processId); if (processEntity == null) { // 创建草稿,已经存在不做处理 var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == schemeCode); WFProcess wfProcessEntity = new WFProcess() { Id = processId, SchemeCode = schemeCode, SchemeId = schemeInfo.SchemeId, SchemeName = schemeInfo.Name, Title = title, InstanceInfo = JsonConvert.DeserializeObject(instanceInfo), EnabledMark = 2, IsAgain = 0, IsFinished = 0, IsChild = isChild, IsStart = 0, ParentNodeId = parentNodeId, ParentProcessId = parentProcessId, ParentTaskId = parentTaskId, CreateUserId = currentUser.Id.ToString(), CreateUserName = currentUser.Name, CreateUserAccount = currentUser.Account, UserId = currentUser.Id.ToString() }; if (string.IsNullOrEmpty(title)) { wfProcessEntity.Title = currentUser.Name + "-" + schemeInfo.Name; } wfProcessEntity.CreateDate = DateTime.Now; wfProcessEntity.UserId = currentUser.Id.ToString(); flag = await base.Repository.InsertAsync(wfProcessEntity); } else if (!string.IsNullOrEmpty(title) && processEntity.Title != title) { processEntity.Title = title; flag = await base.Repository.UpdateAsync(processEntity); } else { flag = true; } return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } /// /// 保存草稿-新版用户查询 /// /// 流程进程主键 /// 流程模板编码 /// 创建人 /// 父级流程进程主键 /// 父级流程节点Id /// 父级任务id /// 是否为子流程 /// 流程标题 /// public async Task> SaveDraftWithUser(string processId, string schemeCode, string userName, string instanceInfo, string parentProcessId, string parentNodeId, string parentTaskId, int isChild, string title = "") { var flag = false; var currentUser = await client.Queryable().FirstAsync(r => r.Name == userName) ?? new SysUser { Id = -1, Account = Define.SYSTEM_USERNAME, Name = "超级管理员", }; // 判断当前流程进程是否有保存过 var processEntity = await GetEntity(processId); if (processEntity == null) { // 创建草稿,已经存在不做处理 var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == schemeCode); WFProcess wfProcessEntity = new WFProcess() { Id = processId, SchemeCode = schemeCode, SchemeId = schemeInfo.SchemeId, SchemeName = schemeInfo.Name, Title = title, InstanceInfo = JsonConvert.DeserializeObject(instanceInfo), EnabledMark = 2, IsAgain = 0, IsFinished = 0, IsChild = isChild, IsStart = 0, ParentNodeId = parentNodeId, ParentProcessId = parentProcessId, ParentTaskId = parentTaskId, CreateUserId = currentUser?.Id.ToString(), CreateUserName = currentUser?.Name, CreateUserAccount = currentUser?.Account, UserId = currentUser?.Id.ToString() }; if (string.IsNullOrEmpty(title)) { wfProcessEntity.Title = currentUser.Name + "-" + schemeInfo.Name; } wfProcessEntity.CreateDate = DateTime.Now; wfProcessEntity.UserId = currentUser.Id.ToString(); flag = await base.Repository.InsertAsync(wfProcessEntity); } else if (!string.IsNullOrEmpty(title) && processEntity.Title != title) { processEntity.Title = title; flag = await base.Repository.UpdateAsync(processEntity); } return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } /// /// 删除草稿 /// /// 流程进程主键 public async Task> DeleteDraft(string processId) { var flag = false; var response = new Response(); var iWFEngine = await Bootstraper(string.Empty, processId, null); var scriptResult = await ExecuteScript(processId, "deleteDraft", iWFEngine.CreateUser, iWFEngine.WFScheme.DeleteDraftType, iWFEngine.WFScheme.DeleteDraftDbCode, iWFEngine.WFScheme.DeleteDraftDbSQL, iWFEngine.WFScheme.DeleteDraftUrl, iWFEngine.WFScheme.DeleteDraftIOCName); if (scriptResult) { flag = await DeleteEntity(processId); if (flag) { response.Result = true; response.Message = "success"; } else { response.Result = false; response.Message = "脚本执行成功,但流程信息删除失败"; } } else { response.Result = false; response.Message = "error"; } return response; } /// /// 创建流程 /// /// 流程进程主键 /// 流程模板编码 /// 创建人 /// 下一个节点审核人 /// 流程标题 /// public async Task> Create(string processId, string schemeCode, string userId, Dictionary nextUsers, string InstanceInfo, string title = "") { var flag = false; var userInfo = await GetUserInfo(userId); var iWFEngine = await Bootstraper(schemeCode, processId, userInfo, nextUsers); // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id); //获取当前流程信息 var process = await GetEntity(processId); // 处理任务并更新数据 List myTaskList; using (var uwo = UnitWork.CreateContext()) { var processEntity = GetWFProcessEntity(iWFEngine.Config.Params, title); processEntity.InstanceInfo = JsonConvert.DeserializeObject(InstanceInfo); if (string.IsNullOrEmpty(processEntity.Title)) { processEntity.Title = userInfo.Name + "-" + processEntity.SchemeName; } processEntity.CreateDate = DateTime.Now; if (taskList.FindIndex(t => t.Type == 100) != -1) { processEntity.IsFinished = 1; if (process != null && process.IsChild == 1) { WFTask ts = new WFTask(); await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, "", ts, ""); } } if (process != null && process.IsChild == 1) { var taskEntity = await client.Queryable().Where(a => a.Id == process.ParentTaskId).FirstAsync(); if (taskEntity != null) { taskEntity.State = 3; if (taskEntity.Type == 7) { var currentUser = _auth.GetCurrentUser().User; taskEntity.UserId = currentUser.Id.ToString(); taskEntity.UserName = currentUser.Name; } await uwo.WFTask.UpdateAsync(taskEntity); } } if (!string.IsNullOrEmpty(schemeCode)) { await uwo.WFProcess.InsertAsync(processEntity); } else { await uwo.WFProcess.UpdateAsync(processEntity); } myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, "create", "create"); foreach (var item in myTaskList) { if (item.Type == 7) { await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); } item.ProcessTitle = processEntity.Title; await Add(item); } WFTaskLog wfTaskLogEntity = new WFTaskLog() { OperationCode = "create", OperationName = "提交流程", TaskType = 0, IsLast = 1, Des = "提交流程", ProcessId = processId, UnitId = iWFEngine.StartNode.Id, UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name }; await AddLog(wfTaskLogEntity); flag = uwo.Commit(); } var respone = new Response(); if (flag) { var scriptResults = new List(); // 脚本执行 var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); foreach (var item in scriptTaskList) { var result = await ExecuteScript(item, "create", processId, "", "",iWFEngine.CreateUser, iWFEngine, null,""); scriptResults.Add(result); } if (scriptResults.Contains(false)) { respone.Result = false; respone.Message = "流程信息存储成功,但脚本执行失败"; } else { respone.Result = true; respone.Message = "success"; } } else { respone.Result = false; respone.Message = "error"; } return respone; } /// /// 创建流程 /// /// 流程进程主键 /// 流程模板编码 /// 创建人 /// 下一个节点审核人 /// 流程标题 /// public async Task> CreateWithUser(string processId, string schemeCode, string userName, Dictionary nextUsers, string InstanceInfo, string title = "") { var flag = false; //var userInfo = await client.Queryable().FirstAsync(r => r.Name == userName); var userInfo = await client.Queryable().FirstAsync(r => r.Name == userName) ?? new SysUser { Id = -1, Account = Define.SYSTEM_USERNAME, Name = "超级管理员", }; var iWFEngine = await BootstraperWithUser(schemeCode, processId, userInfo, nextUsers); // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id); //获取当前流程信息 var process = await GetEntity(processId); // 处理任务并更新数据 List myTaskList; using (var uwo = UnitWork.CreateContext()) { var processEntity = GetWFProcessEntity(iWFEngine.Config.Params, title); processEntity.InstanceInfo = JsonConvert.DeserializeObject(InstanceInfo); if (string.IsNullOrEmpty(processEntity.Title)) { processEntity.Title = userInfo.Name + "-" + processEntity.SchemeName; } processEntity.CreateDate = DateTime.Now; if (taskList.FindIndex(t => t.Type == 100) != -1) { processEntity.IsFinished = 1; if (process != null && process.IsChild == 1) { WFTask ts = new WFTask(); await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, "", ts, ""); } } if (process != null && process.IsChild == 1) { var taskEntity = await client.Queryable().Where(a => a.Id == process.ParentTaskId).FirstAsync(); if (taskEntity != null) { taskEntity.State = 3; if (taskEntity.Type == 7) { var currentUser = _auth.GetCurrentUser().User; taskEntity.UserId = currentUser.Id.ToString(); taskEntity.UserName = currentUser.Name; } await uwo.WFTask.UpdateAsync(taskEntity); } } if (!string.IsNullOrEmpty(schemeCode)) { await uwo.WFProcess.InsertAsync(processEntity); } else { await uwo.WFProcess.UpdateAsync(processEntity); } myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, "create", "create"); foreach (var item in myTaskList) { if (item.Type == 7) { await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); } item.ProcessTitle = processEntity.Title; await Add(item); } WFTaskLog wfTaskLogEntity = new WFTaskLog() { OperationCode = "create", OperationName = "提交流程", TaskType = 0, IsLast = 1, Des = "提交流程", ProcessId = processId, UnitId = iWFEngine.StartNode.Id, UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name }; await AddLog(wfTaskLogEntity); flag = uwo.Commit(); } var respone = new Response(); if (flag) { var scriptResults = new List(); // 脚本执行 var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); foreach (var item in scriptTaskList) { var result = await ExecuteScript(item, "create", processId, "", "",iWFEngine.CreateUser, iWFEngine, null, ""); scriptResults.Add(result); } if (scriptResults.Contains(false)) { respone.Result = false; respone.Message = "流程信息存储成功,但脚本执行失败"; } else { respone.Result = true; respone.Message = "success"; } } else { respone.Result = false; respone.Message = "error"; } return respone; } /// /// 重新创建流程 /// /// 流程实例主键 /// 备注 /// public async Task> CreateAgain(string processId, string des) { var flag = false; var iWFEngine = await Bootstraper("", processId, null, null); var unList = (List)await GetUnFinishTaskList(processId); var taskEntity = unList.Find(t => t.State == 1 && t.UnitId == iWFEngine.StartNode.Id); if (taskEntity == null) { throw (new Exception("找不到重新提交流程任务!")); } // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(iWFEngine.StartNode.Id); // 处理任务并更新数据 List myTaskList; using (var uwo = UnitWork.CreateContext()) { await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess() { IsCancel = 1, IsAgain = 0 }, a => a.Id == processId); await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask() { State = 3 }, a => a.Id == taskEntity.Id); // 更新上一个流转过来的任务,提示他无法被撤销 await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId); myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, taskEntity.Token, taskEntity.Id); foreach (var item in myTaskList) { if (item.Type == 7) { await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); } await Add(item); } await CreateTaskLog(taskEntity, "", "重新提交", des, ""); //await _imMsgIBLL.VirtualDeleteByContentId(taskEntity.Token); // 更新消息 flag = uwo.Commit(); } var respone = new Response(); if (flag) { var scriptResults = new List(); // 脚本执行 var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); foreach (var item in scriptTaskList) { var result = await ExecuteScript(item, "createAgain", processId, "", "",iWFEngine.CreateUser, iWFEngine, null, ""); scriptResults.Add(result); } if (scriptResults.Contains(false)) { respone.Result = false; respone.Message = "流程信息存储成功,但脚本执行失败"; } else { respone.Result = true; respone.Message = "success"; } } else { respone.Result = false; respone.Message = "error"; } return respone; } /// /// 撤销流程(只有在该流程未被处理的情况下) /// /// 流程进程主键 public async Task RevokeFlow(string processId) { var iWFEngine = await Bootstraper(string.Empty, processId, null, null); if (iWFEngine.Config.Params.IsStart != 1) { // 获取脚本任务 var scriptList = (List)await GetList(processId, 10, "create"); foreach (var item in scriptList) { await ExecuteRevokeScript(item.UnitId, item.UnitName, processId, iWFEngine.CreateUser, iWFEngine); } using (var uwo = UnitWork.CreateContext()) { await uwo.WFTask.DeleteAsync(a => a.ProcessId == processId); await uwo.WFTaskLog.DeleteAsync(a => a.ProcessId == processId); await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 2 }, a => a.Id == processId); uwo.Commit(); } await ExecuteScript(processId, "RevokeFlow", iWFEngine.CreateUser, iWFEngine.WFScheme.UndoType, iWFEngine.WFScheme.UndoDbCode, iWFEngine.WFScheme.UndoDbSQL, iWFEngine.WFScheme.UndoUrl, iWFEngine.WFScheme.UndoIOCName); return true; } return false; } /// /// 催办流程 /// /// 流程进程主键 public async Task> UrgeFlow(string processId) { // var userInfo = await this.CurrentUser(); var iWFEngine = await Bootstraper(string.Empty, processId, null, null); // 获取未完成的任务 var taskList = await GetUnFinishTaskList(processId); using (var uwo = UnitWork.CreateContext()) { foreach (var item in taskList) { if (item.Type == 1 || item.Type == 3 || item.Type == 5 || item.Type == 6 || item.Type == 7) { item.IsUrge = 1; item.UrgeTime = DateTime.Now; // 发送消息 var msg = $"【审核】【催办】{item.ProcessTitle},{item.UnitName}"; var userList = new List(); // todo 单体任务处理 userList.Add(item.UserId); var node = iWFEngine.GetNode(item.UnitId); //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, item.F_Token); await uwo.WFTask.UpdateAsync(item); } } //await wfProcessSerive.Update(new WFProcessEntity() { F_IsUrge = 1, F_Id = processId }); WFTaskLog wfTaskLogEntity = new WFTaskLog() { Des = "催办审核", TaskType = 98, ProcessId = processId, UnitId = iWFEngine.StartNode.Id, UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name }; wfTaskLogEntity.CreateDate = DateTime.Now; wfTaskLogEntity.UserId = _auth.GetUserId(); wfTaskLogEntity.UserName = _auth.GetUserNickName(); wfTaskLogEntity.Id = Guid.NewGuid().ToString(); await uwo.WFTaskLog.InsertAsync(wfTaskLogEntity); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } } /// /// 审批流程 /// /// 流程任务主键 /// 流程审批操作码agree 同意 disagree 不同意 lrtimeout 超时 /// 流程审批操名称 /// 审批意见 /// 下一节点指定审核人 /// 盖章图片 /// 盖章图片密码 /// 下一个审核节点 public async Task AuditFlow(string taskId, string code, string name, string des, Dictionary nextUsers, string stampImg, string stampPassWord, string nextId) { var taskEntiy = await client.Queryable().Where(a => a.Id == taskId).FirstAsync(); if (taskEntiy == null) { throw (new Exception("找不到对应流程任务!")); } else if (taskEntiy.State != 1) { if (taskEntiy.State == 3 || taskEntiy.State == 4) { throw (new Exception("该任务已完成!")); } else { throw (new Exception("该任务未被激活!")); } } //后期改 stampImg = ""; //stampImg = await _wFStampIBLL.ToWfImg(stampImg, stampPassWord); var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null, nextUsers); // 1.判断任务类型 1 普通任务 5 会签任务 if (taskEntiy.Type == 1||taskEntiy.Type==7) { await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg, nextId); } else if (taskEntiy.Type == 5) { await AuditNodeByCountersign(iWFEngine, taskEntiy, code, name, des, stampImg); } else { throw (new Exception("该任务无法审核!")); } //await _imMsgIBLL.VirtualDeleteByContentId(taskEntiy.F_Token); // 更新消息 // 发送消息 var msg = $"【提醒】{iWFEngine.Config.Params.Title},{taskEntiy.UnitName}已被处理"; var userList = new List(); userList.Add(iWFEngine.CreateUser.Id); var node = iWFEngine.StartNode; //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, iWFEngine.Config.Params.ProcessId); } /// /// 批量审核(只有同意和不同意) /// /// 操作码 /// 任务id串 public async Task AuditFlows(string code, List taskIdList) { foreach (var taskId in taskIdList) { string operationName = code == "agree" ? "同意" : "不同意"; await AuditFlow(taskId, code, operationName, "批量审核", null, "", "", ""); } } /// /// 撤销审核 /// /// /// 流程任务主键 /// public async Task> RevokeAudit(string processId, string taskId) { var iWFEngine = await Bootstraper(string.Empty, processId, null, null); WFTask taskEntity; WFProcess processEntity; if (string.IsNullOrEmpty(taskId)) { //撤销重新提交任务 processEntity = await GetEntity(processId); if (processEntity.IsCancel != 1) { throw (new Exception("当前流程无法撤销!")); } var myTaskList = (List)await GetLastTaskList(processId, iWFEngine.StartNode.Id); taskEntity = myTaskList[0]; processEntity.IsAgain = 1; processEntity.IsCancel = 0; } else { taskEntity = await client.Queryable().Where(a => a.Id == taskId).FirstAsync(); if (taskEntity.State == 1) { throw (new Exception("当前任务无法撤销!")); } var taskLogEntity = await GetLogEntity(taskId); if (taskLogEntity == null || taskLogEntity.IsCancel != 1) { throw (new Exception("当前任务无法撤销!")); } processEntity = new WFProcess() { Id = processId }; processEntity.IsFinished = 0; processEntity.IsAgain = 0; } using (var uwo = UnitWork.CreateContext()) { // 获取脚本任务 var scriptList = await GetList(processId, 10, taskEntity.Id); foreach (var item in scriptList) { await ExecuteRevokeScript(item.UnitId, item.UnitName, processId, iWFEngine.CreateUser, iWFEngine); // 删除脚本任务执行日志 await DeleteLogByTaskId(item.Id); } // 删除所有生成的任务 await Delete(processId, taskEntity.Id); // 如果是加签审核的,关闭最早的任务 if (taskEntity.Type == 6) { var myTaskEntiy = await GetTaskEntity(taskEntity.FirstId); // 原始审核任务 myTaskEntiy.State = 5; await uwo.WFTask.UpdateAsync(myTaskEntiy); } // 如果是撤销转移任务 if (taskEntity.State == 6) { // 删除转移任务 await DeleteByFirstId(taskEntity.Id); } // 删除所有生成的日志 await DeleteLog(processId, taskEntity.Id); // 更新等待任务状态 await OpenTask(processId, taskEntity.UnitId, 21, taskEntity.Id); taskEntity.State = 1; await uwo.WFTask.UpdateAsync(taskEntity); await uwo.Db.Updateable(processEntity) .IgnoreColumns(ignoreAllNullColumns: true) .ExecuteCommandAsync(); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } } /// /// 流程加签 /// /// 流程任务主键 /// 加签人员 /// 加签说明 public async Task> SignFlow(string taskId, string userId, string des) { var taskEntiy = await GetTaskEntity(taskId); if (taskEntiy == null) { throw (new Exception("找不到对应流程任务!")); } else if (taskEntiy.State != 1) { if (taskEntiy.State == 3 || taskEntiy.State == 4) { throw (new Exception("该任务已完成!")); } else { throw (new Exception("该任务未被激活!")); } } using (var uwo = UnitWork.CreateContext()) { // 更新任务状态 taskEntiy.State = 5; await uwo.WFTask.UpdateAsync(taskEntiy); // 更新上一个流转过来的任务,提示他无法被撤销 await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); // 填写日志 await CreateTaskLog(taskEntiy, "sign", "加签", des, ""); if (taskEntiy.Type != 6) { taskEntiy.FirstId = taskEntiy.Id; } var userInfo = await uwo.User.GetByIdAsync(userId); // 添加加签任务 taskEntiy.PrevTaskId = taskEntiy.Id; //taskEntiy.UserCompanyId = userInfo.CompanyId; //taskEntiy.UserDepartmentId = userInfo.DepartmentId; taskEntiy.UserId = userInfo.Id.ToString(); taskEntiy.UserName = userInfo.Name; taskEntiy.Type = 6; taskEntiy.State = 1; await uwo.WFTask.InsertAsync(taskEntiy); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } } /// /// 流程加签审核 /// /// 流程任务主键 /// 操作码 /// 流程审批操名称 /// 审批意见 /// public async Task> SignAudit(string taskId, string code, string name, string des) { var taskEntiy = await GetTaskEntity(taskId); if (taskEntiy == null) { throw (new Exception("找不到对应流程任务!")); } else if (taskEntiy.State != 1) { if (taskEntiy.State == 3 || taskEntiy.State == 4) { throw (new Exception("该任务已完成!")); } else { throw (new Exception("该任务未被激活!")); } } using (var uwo = UnitWork.CreateContext()) { var myTaskEntiy = await GetTaskEntity(taskEntiy.FirstId); // 原始审核任务 myTaskEntiy.IsLast = 0; await uwo.WFTask.UpdateAsync(myTaskEntiy); myTaskEntiy.State = 1; myTaskEntiy.IsLast = 1; await Add(myTaskEntiy); // 更新任务状态 taskEntiy.State = 3; if (taskEntiy.Type == 7) { var currentUser = _auth.GetCurrentUser().User; taskEntiy.UserId = currentUser.Id.ToString(); taskEntiy.UserName = currentUser.Name; } await uwo.WFTask.UpdateAsync(taskEntiy); // 填写日志 await CreateTaskLog(taskEntiy, code, name, des, ""); // 更新上一个流转过来的任务,提示他无法被撤销 await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } } /// /// 确认阅读 /// /// 流程任务主键 public async Task> ReadFlow(string taskId) { var taskEntiy = await GetTaskEntity(taskId); if (taskEntiy == null) { throw (new Exception("找不到对应流程任务!")); } else if (taskEntiy.State == 1) { using (var uwo = UnitWork.CreateContext()) { taskEntiy.State = 3; await uwo.WFTask.UpdateAsync(taskEntiy); WFTaskLog wfTaskLogEntity = new WFTaskLog() { TaskType = taskEntiy.Type, ProcessId = taskEntiy.ProcessId, UnitId = taskEntiy.UnitId, UnitName = taskEntiy.UnitName, IsAgree = taskEntiy.IsAgree, OperationCode = "read", OperationName = "已阅", Token = taskEntiy.Token, PrevUnitId = taskEntiy.PrevUnitId, PrevUnitName = taskEntiy.PrevUnitName, TaskId = taskEntiy.Id, IsCancel = 0 }; await AddLog(wfTaskLogEntity); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } } else { return new Response { Result = false, Message = "error" }; } } /// /// 转移流程 /// /// 任务id /// 转移人用户id /// 说明 /// public async Task> TransferUser(string taskId, string userId, string des) { var taskEntiy = await GetTaskEntity(taskId); if (taskEntiy == null) { throw (new Exception("找不到对应流程任务!")); } else if (taskEntiy.State == 1) { using (var uwo = UnitWork.CreateContext()) { var userInfo = await uwo.User.GetByIdAsync(userId); // 更新任务状态 taskEntiy.State = 6; await uwo.WFTask.UpdateAsync(taskEntiy); // 更新流程 WFProcess processEntity = new WFProcess() { Id = taskEntiy.ProcessId, IsStart = 1, IsCancel = 0, }; await uwo.WFProcess.UpdateAsync(processEntity); // 填写日志 await CreateTaskLog(taskEntiy, "transfer", "转移", des, ""); // 更新上一个流转过来的任务,提示他无法被撤销 await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); // 新建任务 var newTask = taskEntiy; //.ToJson().ToObject(); newTask.State = 1; newTask.PrevTaskId = taskEntiy.Id; //newTask.UserCompanyId = userInfo.F_CompanyId; //newTask.UserDepartmentId = userInfo.F_DepartmentId; newTask.UserId = userInfo.Id.ToString(); newTask.UserName = userInfo.Name; await uwo.WFTask.InsertAsync(newTask); // 发送消息 var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null); var msg = $"【审核】{taskEntiy.ProcessTitle},{taskEntiy.UnitName}"; var userList = new List(); userList.Add(userInfo.Id.ToString()); var node = iWFEngine.GetNode(taskEntiy.UnitId); //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, newTask.F_Token); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag == true ? "success" : "error" }; } } else { return new Response { Result = false, Message = "error" }; } } /// /// 获取下一节点审核人 /// /// 流程模板编码 /// 流程进程主键 /// 流程节点Id /// 流程操作代码 /// 创建人 /// public async Task>> GetNextAuditors(string code, string processId, string nodeId, string operationCode, string userId) { Dictionary> res = new Dictionary>(); var userInfo = await client.Queryable().Where(a => a.Id.ToString() == userId).FirstAsync(); var iWFEngine = await Bootstraper(code, processId, userInfo); // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(nodeId, operationCode); foreach (var item in taskList) { if ((item.Type == 1 || item.Type == 3 || item.Type == 5||item.Type==7) && item.User.IsNew) { if (!res.ContainsKey(item.UnitId)) { res.Add(item.UnitId, new List()); } res[item.UnitId].Add(item.User); } } return res; } /// /// 作废流程 /// /// 流程进程主键 /// public async Task> DeleteProcess(string processId) { var flag = false; var iWFEngine = await Bootstraper(string.Empty, processId, null); using (var uwo = UnitWork.CreateContext()) { // 更新流程状态 WFProcess processEntity = new WFProcess() { Id = processId, }; await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 3 }, a => a.Id == processId); await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask { State = 7 }, a => a.ProcessId == processId && a.State == 1); flag = uwo.Commit(); } var response = new Response(); if (flag) { var scriptResult = await ExecuteScript(processId, "delete", iWFEngine.CreateUser, iWFEngine.WFScheme.DeleteType, iWFEngine.WFScheme.DeleteDbCode, iWFEngine.WFScheme.DeleteDbSQL, iWFEngine.WFScheme.DeleteUrl, iWFEngine.WFScheme.DeleteIOCName); if (scriptResult) { response.Result = true; response.Message = "success"; } else { response.Result = false; response.Message = "流程状态更新成功,但脚本执行失败"; } } else { response.Result = false; response.Message = "error"; } return response; } /// /// 流程还原 /// /// 流程进程主键 /// public async Task> RecoverProcess(string processId) { var flag = false; var iWFEngine = await Bootstraper(string.Empty, processId, null); using (var uwo = UnitWork.CreateContext()) { // 更新流程状态 WFProcess processEntity = new WFProcess() { Id = processId, }; await uwo.WFProcess.UpdateSetColumnsTrueAsync(a => new WFProcess { EnabledMark = 1 }, a => a.Id == processId); await uwo.WFTask.UpdateSetColumnsTrueAsync(a => new WFTask { State = 1 }, a => a.ProcessId == processId && a.State == 7); flag = uwo.Commit(); } var response = new Response(); if (flag) { response.Result = true; response.Message = "success"; } else { response.Result = false; response.Message = "error"; } return response; } /// /// 指派流程审核人 /// /// 流程进程主键 /// 流程指派人信息 /// public async Task> PointUser(string processId, List pointList) { var list = await GetUnFinishTaskList(processId); Dictionary> map = new Dictionary>(); foreach (var item in list) { if (!map.ContainsKey(item.UnitId)) { map.Add(item.UnitId, new List()); } map[item.UnitId].Add(item); } var addList = new List(); var iWFEngine = await Bootstraper("", processId, null); using (var uwo = UnitWork.CreateContext()) { foreach (var item in pointList) { if (map.ContainsKey(item.UnitId)) { await CloseTask(processId, map[item.UnitId][0].Token, ""); var userIdList = item.UserIds.Split(","); foreach (var userId in userIdList) { var addItem = Newtonsoft.Json.JsonConvert.SerializeObject(map[item.UnitId][0]).ToObject(); addItem.State = 1; if (addItem.Type == 6) { addItem.Type = 1; } var userEntity = _auth.GetCurrentUser().User; addItem.UserId = userId; addItem.UserName = userEntity.Name; //addItem.UserCompanyId = userEntity.F_CompanyId; //addItem.UserDepartmentId = userEntity.F_DepartmentId; // 发送消息 var msg = $"【审核】{addItem.ProcessTitle},{addItem.UnitName}"; var userList = new List(); userList.Add(userId); var node = iWFEngine.GetNode(addItem.UnitId); //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, addItem.F_Token); addList.Add(addItem); } } else { throw (new Exception("找不到指派任务节点!")); } } foreach (var item in addList) { await Add(item); } var flag = uwo.Commit(); return new Response() { Result = flag, Message = flag == true ? "success" : "error" }; } } #endregion #region /// /// 流程模板初始化 /// /// 流程模板 /// 流程实例 /// 提交人用户信息 /// 下一个节点审核人 /// private async Task Bootstraper(string code, string processId, SysUser userInfo, Dictionary nextUsers = null) { WFEngineConfig wfEngineConfig = new WFEngineConfig(); WFParams wfParams = new WFParams(); wfEngineConfig.Params = wfParams; var currentUser = _auth.GetCurrentUser().User; wfParams.CurrentUser = new WFUserInfo() { Id = currentUser.Id.ToString(), Account = currentUser.Account, Name = currentUser.Name //CompanyId = currentUser.F_CompanyId, //DepartmentId = currentUser.F_DepartmentId }; if (!string.IsNullOrEmpty(code)) { var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == code); if (schemeInfo != null) { var data = await client.Queryable().FirstAsync(a => a.Id == schemeInfo.SchemeId); if (data != null) { wfParams.Scheme = data.Content; wfParams.SchemeCode = code; wfParams.SchemeId = schemeInfo.SchemeId; wfParams.SchemeName = schemeInfo.Name; wfParams.ProcessId = processId; wfParams.HasInstance = false; wfParams.CreateUser = new WFUserInfo() { Id = userInfo.Id.ToString(), Account = userInfo.Account, Name = userInfo.Name //CompanyId = userInfo.F_CompanyId, //DepartmentId = userInfo.F_DepartmentId }; } else { throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); } } else { throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); } } else if (!string.IsNullOrEmpty(processId)) { var processEntity = await GetEntity(processId); if (processEntity != null) { var data = await client.Queryable().FirstAsync(a => a.Id == processEntity.SchemeId); if (data != null) { wfParams.Scheme = data.Content; wfParams.SchemeCode = processEntity.SchemeCode; wfParams.SchemeId = processEntity.SchemeId; wfParams.SchemeName = processEntity.SchemeName; wfParams.IsChild = processEntity.IsChild == 1; wfParams.ParentProcessId = processEntity.ParentProcessId; wfParams.ParentTaskId = processEntity.ParentTaskId; wfParams.ParentNodeId = processEntity.ParentNodeId; wfParams.ProcessId = processId; wfParams.HasInstance = true; wfParams.IsStart = processEntity.IsStart == 1 ? 1 : 0; wfParams.Title = processEntity.Title; wfParams.CreateUser = new WFUserInfo() { Id = processEntity.CreateUserId, Account = processEntity.CreateUserAccount, Name = processEntity.CreateUserName, CompanyId = processEntity.CreateUserCompanyId, DepartmentId = processEntity.CreateUserDepartmentId }; } else { throw new Exception(string.Format("无法获取流程模板【{0}】", processEntity.SchemeId)); } } else if (string.IsNullOrEmpty(wfParams.Scheme)) { throw new Exception(string.Format("无法获取实例数据【{0}】", processId)); } } wfParams.NextUsers = nextUsers; // 注册委托方法 wfEngineConfig.GetAwaitTaskList = GetAwaitTaskList; wfEngineConfig.GetUserList = GetUserList; wfEngineConfig.GetSystemUserList = GetSystemUserList; wfEngineConfig.GetPrevTaskUserList = GetPrevTaskUserList; wfEngineConfig.IsCountersignAgree = IsCountersignAgree; wfEngineConfig.GetPrevUnitId = GetPrevUnitId; IWFEngine iwfEngine = new WFEngine(wfEngineConfig, client); return iwfEngine; } /// /// 流程模板初始化 /// /// 流程模板 /// 流程实例 /// 提交人用户信息 /// 下一个节点审核人 /// private async Task BootstraperWithUser(string code, string processId, SysUser userInfo, Dictionary nextUsers = null) { WFEngineConfig wfEngineConfig = new WFEngineConfig(); WFParams wfParams = new WFParams(); wfEngineConfig.Params = wfParams; var currentUser = userInfo; wfParams.CurrentUser = new WFUserInfo() { Id = currentUser.Id.ToString(), Account = currentUser.Account, Name = currentUser.Name //CompanyId = currentUser.F_CompanyId, //DepartmentId = currentUser.F_DepartmentId }; if (!string.IsNullOrEmpty(code)) { var schemeInfo = await client.Queryable().FirstAsync(a => a.Code == code); if (schemeInfo != null) { var data = await client.Queryable().FirstAsync(a => a.Id == schemeInfo.SchemeId); if (data != null) { wfParams.Scheme = data.Content; wfParams.SchemeCode = code; wfParams.SchemeId = schemeInfo.SchemeId; wfParams.SchemeName = schemeInfo.Name; wfParams.ProcessId = processId; wfParams.HasInstance = false; wfParams.CreateUser = new WFUserInfo() { Id = userInfo.Id.ToString(), Account = userInfo.Account, Name = userInfo.Name //CompanyId = userInfo.F_CompanyId, //DepartmentId = userInfo.F_DepartmentId }; } else { throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); } } else { throw new Exception(string.Format("无法获取对应的流程模板【{0}】", code)); } } else if (!string.IsNullOrEmpty(processId)) { var processEntity = await GetEntity(processId); if (processEntity != null) { var data = await client.Queryable().FirstAsync(a => a.Id == processEntity.SchemeId); if (data != null) { wfParams.Scheme = data.Content; wfParams.SchemeCode = processEntity.SchemeCode; wfParams.SchemeId = processEntity.SchemeId; wfParams.SchemeName = processEntity.SchemeName; wfParams.IsChild = processEntity.IsChild == 1; wfParams.ParentProcessId = processEntity.ParentProcessId; wfParams.ParentTaskId = processEntity.ParentTaskId; wfParams.ParentNodeId = processEntity.ParentNodeId; wfParams.ProcessId = processId; wfParams.HasInstance = true; wfParams.IsStart = processEntity.IsStart == 1 ? 1 : 0; wfParams.Title = processEntity.Title; wfParams.CreateUser = new WFUserInfo() { Id = processEntity.CreateUserId, Account = processEntity.CreateUserAccount, Name = processEntity.CreateUserName, CompanyId = processEntity.CreateUserCompanyId, DepartmentId = processEntity.CreateUserDepartmentId }; } else { throw new Exception(string.Format("无法获取流程模板【{0}】", processEntity.SchemeId)); } } else if (string.IsNullOrEmpty(wfParams.Scheme)) { throw new Exception(string.Format("无法获取实例数据【{0}】", processId)); } } wfParams.NextUsers = nextUsers; // 注册委托方法 wfEngineConfig.GetAwaitTaskList = GetAwaitTaskList; wfEngineConfig.GetUserList = GetUserList; wfEngineConfig.GetSystemUserList = GetSystemUserList; wfEngineConfig.GetPrevTaskUserList = GetPrevTaskUserList; wfEngineConfig.IsCountersignAgree = IsCountersignAgree; wfEngineConfig.GetPrevUnitId = GetPrevUnitId; IWFEngine iwfEngine = new WFEngine(wfEngineConfig, client); return iwfEngine; } /// /// 获取等待任务 /// /// 流程进程ID /// 流程单元ID /// private async Task> GetAwaitTaskList(string processId, string unitId) { List res = new List(); var list = await client.Queryable().Where(t => t.ProcessId == processId && t.UnitId == unitId && t.Type == 21 && t.State == 1).ToListAsync(); foreach (var item in list) { res.Add(GetWFTask(item)); } return res; } /// /// 获取设置人员 /// /// 人员配置信息 /// 流程发起人 /// 流程进程实例ID /// 开始节点 /// private async Task> GetUserList(List auditorList, WFUserInfo createUser, string processId, WFUnit startNode) { var res = new List(); List userIds = new List(); foreach (var item in auditorList) { switch (item.Type) { //岗位 case "1": var rlist = await userManager.UserIdsByPosition("", item.Id); foreach (var ritem in rlist) { userIds.Add(ritem); } break; //角色 case "2": var rlist2 = await userManager.UserIdsByRole(item.Id); List userIds2 = new List(); foreach (var ritem2 in rlist2) { userIds2.Add(ritem2); } var userList2 = await GetListByKeyValues(userIds2.ToArray()); var userOrgs = await userManager.UserOrgsByUserIds(userIds2); foreach (var userOrg in userOrgs) { var user2 = userList2.FirstOrDefault(a => a.Id.ToString() == userOrg.Key); switch (item.Condition) { case "1": if ((userOrg.Value as List).Contains(createUser.DepartmentId)) { res.Add(GetWFUserInfo(user2)); } break; //case "2": // if (user2.CompanyId == createUser.CompanyId) // { // res.Add(GetWFUserInfo(user2)); // } // break; case "3": //// 获取当前用户的岗位 var postList1 = await userManager.PositonsByUser(createUser.Id);// 发起人岗位 var postList2 = await userManager.PositonsByUser(user2.Id.ToString());// 节点审核人岗位 //if (await _postIBLL.IsUp(postList1, postList2)) if (await positionManager.IsUp(postList1, postList2)) { res.Add(GetWFUserInfo(user2)); } break; case "4": // 获取当前用户的岗位 var postList3 = await userManager.PositonsByUser(createUser.Id);// 发起人岗位 var postList4 = await userManager.PositonsByUser(user2.Id.ToString());// 节点审核人岗位 if (await positionManager.IsDown(postList3, postList4)) { res.Add(GetWFUserInfo(user2)); } break; default: res.Add(GetWFUserInfo(user2)); break; } } break; //用户 case "3": userIds.Add(item.Id); break; //上下级 case "4": var postIds = await userManager.PositonsByUser(createUser.Id);// 发起人岗位 int level = Convert.ToInt32(item.Id); List postList; if (level < 6) { postList = (await positionManager.GetUpIdList(postIds, level)).ToList(); } else { level = level - 5; postList = (await positionManager.GetDownIdList(postIds, level)).ToList(); } var userRelationList4 = await userManager.UserIdsByPositions(postList); userIds.AddRange(userRelationList4); break; //节点执行人 case "5": if (item.Id == startNode.Id) { res.Add(createUser); } else { var taskList = await GetLastFinishTaskList(item.Id, processId); foreach (var task in taskList) { userIds.Add(task.UserId); } } break; //数据库表字段 case "6": using (var db = this.CodeClient(item.DbCode, _configuration)) { DataTable dt = await db.Ado.GetDataTableAsync(string.Format("select {0} from {1} where {2} = @processId ", item.AuditorField, item.Table, item.Rfield), new { processId }); foreach (DataRow row in dt.Rows) { var userIdString = row[0].ToString(); if (!string.IsNullOrEmpty(userIdString)) { var userIdList = userIdString.Split(","); foreach (var userIdItem in userIdList) { userIds.Add(userIdItem); } } } break; } //数据库表字段 case "7": using (var db = this.CodeClient(item.DbCode, _configuration)) { //获取数据id var process = await client.Queryable().FirstAsync(a => a.Id == processId); WFInstanceInfo instanceInfo = null; if (process != null) { // instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(process.InstanceInfo); instanceInfo = process.InstanceInfo; } DataTable dt = await db.Ado.GetDataTableAsync(string.Format(item.Sql), new { pkeyValue = instanceInfo.pkeyValue }); foreach (DataRow row in dt.Rows) { var userIdString = row[0].ToString(); if (!string.IsNullOrEmpty(userIdString)) { var userIdList = userIdString.Split(","); foreach (var userIdItem in userIdList) { userIds.Add(userIdItem); } } } break; } } } var userList = await GetListByKeyValues(userIds.ToArray()); foreach (var user in userList) { res.Add(GetWFUserInfo(user)); } return res; } /// /// 获取单元上一次的审核人 /// /// 流程进程ID /// 流程单元ID /// private async Task> GetPrevTaskUserList(string processId, string unitId) { var res = new List(); var list = await GetLastTaskList(processId, unitId); foreach (var item in list) { if (!string.IsNullOrEmpty(item.UserId)) { res.Add(new WFUserInfo() { Id = item.UserId, Name = item.UserName, CompanyId = item.UserCompanyId, DepartmentId = item.UserDepartmentId, IsAgree = item.IsAgree == 1, //Sort = item, State = (int)item.State }); } } return res; } /// /// 获取系统管理员 /// /// private async Task> GetSystemUserList() { var res = new List(); var user = new SysUser { Id = -1, Account = Define.SYSTEM_USERNAME, Name = "超级管理员" }; res.Add(GetWFUserInfo(user)); return res; } /// /// 判断会签是否通过 /// /// 流程进程ID /// 流程单元ID /// private async Task IsCountersignAgree(string processId, string unitId) { var list = (List)await GetLogList(processId, unitId); if (list.Count == 0) { return false; } return list[0].IsAgree == 1; } /// /// 获取上一个流入节点(不是驳回流入的) /// /// /// /// private async Task GetPrevUnitId(string processId, string unitId) { var data = await GetLastNotRejectTask(processId, unitId); if (data != null) { return data.PrevUnitId; } else { return string.Empty; } } /// /// 获取流程任务数据 /// /// /// private WorkFlow.WFTask GetWFTask(WFTask wfTaskEntity) { var res = new WorkFlow.WFTask() { UnitId = wfTaskEntity.UnitId, Name = wfTaskEntity.UnitName, PrevUnitId = wfTaskEntity.PrevUnitId, PrevUnitName = wfTaskEntity.PrevUnitName, Token = wfTaskEntity.Token, Type = (int)wfTaskEntity.Type }; return res; } /// /// 获取用户 /// /// /// private WFUserInfo GetWFUserInfo(SysUser userEntity) { var res = new WFUserInfo() { Id = userEntity.Id.ToString(), Name = userEntity.Name, Account = userEntity.Account, //DepartmentId = userEntity.F_DepartmentId, //CompanyId = userEntity.F_CompanyId, IsNew = true }; return res; } /// /// 获取流程实例 /// /// 流程运行参数 /// 标题 /// private WFProcess GetWFProcessEntity(WFParams myParams, string title) { WFProcess wfProcessEntity = new WFProcess() { Id = myParams.ProcessId, SchemeCode = myParams.SchemeCode, SchemeId = myParams.SchemeId, SchemeName = myParams.SchemeName, Title = title, EnabledMark = 1, IsAgain = 0, IsFinished = 0, IsChild = myParams.IsChild ? 1 : 0, IsStart = 0, IsCancel = 1, ParentNodeId = myParams.ParentNodeId, ParentProcessId = myParams.ParentProcessId, ParentTaskId = myParams.ParentTaskId, CreateUserId = myParams.CreateUser.Id, CreateUserName = myParams.CreateUser.Name, CreateUserAccount = myParams.CreateUser.Account, CreateUserCompanyId = myParams.CreateUser.CompanyId, CreateUserDepartmentId = myParams.CreateUser.DepartmentId, UserId = _auth.GetUserId() }; return wfProcessEntity; } /// /// 处理任务 /// /// 任务列表 /// /// 流程进程实例 /// 任务Token /// 任务id /// private async Task> ExecuteWFTaskEntity(List list, IWFEngine iWFEngine, string processId, string prevToken, string taskId = "") { var res = new List(); //单任务审核 var tlist = list.Where(r => r.Type == 7).ToList(); if (tlist.Count > 0) { var group = tlist.GroupBy(r => r.UnitId).ToList(); foreach (var item in group) { var taskuser = new List(); var users = tlist.Where(r => r.UnitId == item.Key).ToList(); var userTask = new WFTask { Id = Guid.NewGuid().ToString(), Type = users[0].Type, ProcessId = processId, Token = users[0].Token, UnitId = users[0].UnitId, UnitName = users[0].Name, PrevUnitId = users[0].PrevUnitId, PrevUnitName = users[0].PrevUnitName, PrevToken = prevToken, PrevTaskId = taskId, UserId = users[0].User.Id, UserName = users[0].User.Name, UserDepartmentId = users[0].User.DepartmentId, UserCompanyId = users[0].User.CompanyId, State = users[0].User.IsAwait ? 2 : 1, Sort = users[0].User.Sort, IsReject = users[0].IsReject ? 1 : 0, ChildProcessId = users[0].ChildSchemeInfoId, TimeoutInterval = users[0].OvertimeMessageInterval, TimeoutStrategy = users[0].OvertimeMessageType, IsBatchAudit = users[0].IsBatchAudit ? 1 : 0, ProcessUserId = iWFEngine.CreateUser.Id, ProcessUserName = iWFEngine.CreateUser.Name, ProcessCode = iWFEngine.Config.Params.SchemeCode, ProcessTitle = iWFEngine.Config.Params.Title, IsRetract=0 }; if (users[0].IsOvertimeMessage) { if (users[0].OvertimeGo > 0) { userTask.TimeoutAction = DateTime.Now.AddHours(users[0].OvertimeGo); } if (users[0].OvertimeMessageStart > 0) { userTask.TimeoutNotice = DateTime.Now.AddHours(users[0].OvertimeMessageStart); } } foreach (var ts in users) { WFTaskUser tu = new WFTaskUser(); tu.UserId = ts.User.Id; tu.TaskId = userTask.Id; taskuser.Add(tu); } userTask.WFTaskUser = taskuser; res.Add(userTask); } } foreach (var item in list) { if (!string.IsNullOrEmpty(item.MessageType)) { // 发送消息 var taskType = ""; switch (item.Type) { case 1: case 5: case 7: taskType = "审核"; break; case 2: taskType = "查阅"; break; case 3: taskType = "提交"; break; case 4: taskType = "重新提交"; break; } if (!string.IsNullOrEmpty(taskType)) { var msg = $"【{taskType}】{iWFEngine.Config.Params.Title},{item.Name}"; var userList = new List(); userList.Add(item.User.Id); //await _imMsgIBLL.SendMsg("IMWF", userList, msg, item.MessageType, item.Token); } } string childSchemeInfoCode = ""; if (item.Type == 3) { var schemeInfo = await this.Repository.ChangeRepository>().GetByIdAsync(item.ChildSchemeInfoId); if (schemeInfo != null) { childSchemeInfoCode = schemeInfo.Code; } } switch (item.Type) { case 1: case 2: case 3: case 4: case 5: var userTask = new WFTask { Type = item.Type, ProcessId = processId, Token = item.Token, UnitId = item.UnitId, UnitName = item.Name, PrevUnitId = item.PrevUnitId, PrevUnitName = item.PrevUnitName, PrevToken = prevToken, PrevTaskId = taskId, UserId = item.User.Id, UserName = item.User.Name, UserDepartmentId = item.User.DepartmentId, UserCompanyId = item.User.CompanyId, State = item.User.IsAwait ? 2 : 1, Sort = item.User.Sort, IsReject = item.IsReject ? 1 : 0, ChildProcessId = item.ChildSchemeInfoId, ChildSchemeInfoCode = childSchemeInfoCode, TimeoutInterval = item.OvertimeMessageInterval, TimeoutStrategy = item.OvertimeMessageType, IsBatchAudit = item.IsBatchAudit ? 1 : 0, ProcessUserId = iWFEngine.CreateUser.Id, ProcessUserName = iWFEngine.CreateUser.Name, ProcessCode = iWFEngine.Config.Params.SchemeCode, ProcessTitle = iWFEngine.Config.Params.Title, IsRetract=0 }; if (item.IsOvertimeMessage) { if (item.OvertimeGo > 0) { userTask.TimeoutAction = DateTime.Now.AddHours(item.OvertimeGo); } if (item.OvertimeMessageStart > 0) { userTask.TimeoutNotice = DateTime.Now.AddHours(item.OvertimeMessageStart); } } res.Add(userTask); break; case 10: // 执行脚本 res.Add(new WFTask { Type = item.Type, ProcessId = processId, Token = item.Token, UnitId = item.UnitId, UnitName = item.Name, PrevUnitId = item.PrevUnitId, PrevUnitName = item.PrevUnitName, PrevToken = prevToken }); break; case 21: res.Add(new WFTask { Type = item.Type, ProcessId = processId, Token = item.Token, UnitId = item.UnitId, UnitName = item.Name, PrevUnitId = item.PrevUnitId, PrevUnitName = item.PrevUnitName, PrevToken = prevToken, State = 1, }); break; case 22: await CloseTask(processId, item.UnitId, 21, taskId); break; case 23: case 24: WFTaskLog wfTaskLogEntity = new WFTaskLog() { Des = "系统任务", TaskType = item.Type, Token = item.Token, ProcessId = processId, UnitId = item.UnitId, UnitName = item.Name, PrevUnitId = item.PrevUnitId, PrevUnitName = item.PrevUnitName }; await AddLog(wfTaskLogEntity); break; case 26: // 更新任务状态 await Update(processId, item.UnitId); break; } } return res; } public void AddOpenJob(WFTask task, DateTime outtime, DateTime overtime) { try { AddOrUpdateOpenJobReq req = new AddOrUpdateOpenJobReq(); req.JobName = $"超时通知 {task.Id}"; req.JobType = 0; req.JobCallParams = "{\"TaskId\":\"" + task.Id + "\"}"; req.JobCall = "OpenAuth.App.BaseApp.Jobs.TaskTimeoutJob"; req.Status = 1; req.Cron = GetCorn(outtime); req.Remark = $"{task.ProcessUserId}--{task.UnitName}"; _job.AddStart(req); AddOrUpdateOpenJobReq req1 = new AddOrUpdateOpenJobReq(); req1.JobName = $"严重超时通知 {task.Id}"; req1.JobType = 0; req1.JobCallParams = "{\"TaskId\":\"" + task.Id + "\"}"; req1.JobCall = "OpenAuth.App.BaseApp.Jobs.TaskOverTimeJob"; req1.Status = 1; req1.Cron = GetCorn(overtime); req1.Remark = $"{task.ProcessUserId}--{task.UnitName}"; _job.AddStart(req1); } catch { return; } } public string GetCorn(DateTime time) { StringBuilder sb = new StringBuilder(); sb.Append(time.Second.ToString()); sb.Append(" "); sb.Append(time.Minute.ToString()); sb.Append(" "); sb.Append(time.Hour.ToString()); sb.Append(" "); sb.Append(time.Day.ToString()); sb.Append(" "); sb.Append(time.Month.ToString()); sb.Append(" "); sb.Append("?"); sb.Append(" "); sb.Append(time.Year.ToString()); return sb.ToString(); } /// /// 执行脚本 /// /// 脚本任务 /// /// /// /// /// /// /// private async Task ExecuteScript(WFTask task, string code, string processId, string prevTaskId,string nextid, WFUserInfo createUser, IWFEngine iWFEngine, WFTask preTask,string des) { SysUser userInfo; if (preTask == null) { userInfo = new SysUser() { Id = long.Parse(createUser.Id), Account = createUser.Account, //CompanyId = createUser.CompanyId, //F_DepartmentId = createUser.DepartmentId }; } else { //userInfo = await this.CurrentUser(preTask.F_UserId); userInfo = _auth.GetCurrentUser().User; } string nextnode = ""; if (!string.IsNullOrEmpty(nextid)) { nextnode = iWFEngine.GetNode(nextid).Name; } var process = await client.Queryable().FirstAsync(a => a.Id == processId); WFInstanceInfo instanceInfo = null; if (process != null) { // instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(process.InstanceInfo); instanceInfo = process.InstanceInfo; } var param = new { processId, userId = createUser.Id, userAccount = createUser.Account, companyId = createUser.CompanyId, departmentId = createUser.DepartmentId, userName2 = userInfo.Name, userId2 = userInfo.Id.ToString(), userAccount2 = userInfo.Account, //companyId2 = userInfo.F_CompanyId, //departmentId2 = userInfo.F_DepartmentId, code, nodeName=nextnode, pkeyValue = instanceInfo == null ? "" : instanceInfo.pkeyValue, des=des }; try { var node = iWFEngine.GetNode(task.UnitId); switch (node.ExecuteType) { case "1": if (!string.IsNullOrEmpty(node.SqlDb) && !string.IsNullOrEmpty(node.SqlStr)) { await client.Ado.ExecuteCommandAsync(node.SqlStr, param); } break; case "2": if (!string.IsNullOrEmpty(node.Ioc) && IocManager.Instance.IsRegistered(node.Ioc)) { WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService(node.Ioc); WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter() { ProcessId = processId, UnitName = task.UnitName, TaskId = prevTaskId, Code = code, UserId = createUser.Id, UserAccount = createUser.Account, CompanyId = createUser.CompanyId, DepartmentId = createUser.DepartmentId }; await iWorkFlowMethod.Execute(wfMethodParameter); } break; case "3": if (!string.IsNullOrEmpty(node.ApiUrl)) { await HttpMethods.Post(node.ApiUrl, Json.ToJson(param)); } break; } /*脚本执行成功*/ WFTaskLog wfTaskLogEntity = new WFTaskLog() { Des = "脚本执行成功", TaskType = 99, ProcessId = processId, TaskId = task.Id, UnitId = task.UnitId, UnitName = task.UnitName }; await AddLog(wfTaskLogEntity); return true; } catch (Exception ex) { WFTaskLog wfTaskLogEntity = new WFTaskLog() { Des = string.Format("脚本执行异常:{0}", ex.Message), TaskType = 99, ProcessId = processId, TaskId = task.Id, UnitId = task.UnitId, UnitName = task.UnitName }; await AddLog(wfTaskLogEntity); return false; } } /// /// 执行脚本 /// /// /// /// /// /// /// /// /// /// private async Task ExecuteScript(string processId, string code, WFUserInfo createUser, string executeType, string sqlDb, string sqlStr, string apiUrl, string iocName) { var param = new { processId, userId = createUser.Id, userAccount = createUser.Account, companyId = createUser.CompanyId, departmentId = createUser.DepartmentId, code }; try { switch (executeType) { case "1": if (!string.IsNullOrEmpty(sqlDb) && !string.IsNullOrEmpty(sqlStr)) { //await wfProcessSerive.BaseRepository(sqlDb).ExecuteSql(sqlStr, param); await client.Ado.ExecuteCommandAsync(sqlStr, param); } break; case "2": if (!string.IsNullOrEmpty(iocName) && IocManager.Instance.IsRegistered(iocName)) { WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService(iocName); WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter() { ProcessId = processId, Code = code, UserId = createUser.Id, UserAccount = createUser.Account, CompanyId = createUser.CompanyId, DepartmentId = createUser.DepartmentId }; await iWorkFlowMethod.Execute(wfMethodParameter); } break; case "3": if (!string.IsNullOrEmpty(apiUrl)) { await HttpMethods.Post(apiUrl, Json.ToJson(param)); } break; } return true; } catch (Exception ex) { return false; } } /// /// 执行脚本(撤销) /// /// /// /// /// /// /// private async Task ExecuteRevokeScript(string unitId, string unitName, string processId, WFUserInfo createUser, IWFEngine iWFEngine) { var param = new { processId, userId = createUser.Id, userAccount = createUser.Account, companyId = createUser.CompanyId, departmentId = createUser.DepartmentId, code = "revoke", }; try { var node = iWFEngine.GetNode(unitId); switch (node.ExecuteType) { case "1": if (!string.IsNullOrEmpty(node.SqlDb) && !string.IsNullOrEmpty(node.SqlStrRevoke)) { //await wfProcessSerive.BaseRepository(node.SqlDb).ExecuteSql(node.SqlStrRevoke, param); await client.Ado.ExecuteCommandAsync(node.SqlStrRevoke, param); } break; case "2": if (!string.IsNullOrEmpty(node.IocRevoke) && IocManager.Instance.IsRegistered(node.IocRevoke)) { WorkFlow.IWorkFlowMethod iWorkFlowMethod = IocManager.Instance.GetService(node.IocRevoke); WorkFlow.WfMethodParameter wfMethodParameter = new WorkFlow.WfMethodParameter() { ProcessId = processId, UnitName = unitName, Code = "revoke", UserId = createUser.Id, UserAccount = createUser.Account, CompanyId = createUser.CompanyId, DepartmentId = createUser.DepartmentId }; await iWorkFlowMethod.Execute(wfMethodParameter); } break; case "3": if (!string.IsNullOrEmpty(node.ApiUrlRevoke)) { await HttpMethods.Post(node.ApiUrlRevoke, Json.ToJson(param)); } break; } } catch (Exception ex) { WFTaskLog wfTaskLogEntity = new WFTaskLog() { Des = string.Format("脚本执行异常:{0}", ex.Message), TaskType = 99, ProcessId = processId, UnitId = unitId, UnitName = $"{unitName}-撤销" }; await AddLog(wfTaskLogEntity); } } /// /// 普通审核 /// /// /// /// /// /// 下一个节点 /// /// /// private async Task AuditNode(IWFEngine iWFEngine, WFTask taskEntity, string code, string name, string des, string stampImg, string nextId = "") { // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(taskEntity.UnitId, code, nextId); if (taskList.FindAll(t => t.Type != 10).Count == 0) { throw (new Exception("找不到下一个流转节点!")); } List myTaskList; // 处理任务并更新数据 using (var uwo = UnitWork.CreateContext()) { var process = await uwo.WFProcess.GetByIdAsync(taskEntity.ProcessId); await uwo.Db.Updateable() .SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 }) .SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1) .SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1) .Where(p => p.Id == taskEntity.ProcessId) .ExecuteCommandAsync(); if (taskList.FindIndex(t => t.Type == 100) != -1) { if (process.IsChild == 1) { await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId); } } // 更新任务状态 taskEntity.IsAgree = code == "disagree" ? 0 : 1; taskEntity.State = 3; if (taskEntity.Type == 7) { var currentUser = _auth.GetCurrentUser().User; taskEntity.UserId = currentUser.Id.ToString(); taskEntity.UserName = currentUser.Name; } await uwo.WFTask.UpdateAsync(taskEntity); // 更新上一个流转过来的任务,提示他无法被撤销 await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId); // 关闭同一个节点,其他人的任务 await CloseTask(taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); foreach (var item in myTaskList) { if (item.Type == 7) { await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); } await Add(item); } await CreateTaskLog(taskEntity, code, name, des, stampImg); uwo.Commit(); } // 脚本执行 var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); foreach (var item in scriptTaskList) { await ExecuteScript(item, code, taskEntity.ProcessId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity,des); } } /// /// 子流程结束,获取父流程下一任务 /// /// 父流程id /// 父流程的节点id /// 上一任务code(类似agress,degress) /// 任务 /// 下一节点 /// private async Task ChildrenEndTask(string processId, string unitId, string code, WFTask taskEntity, string nextId = "") { var process = await GetEntity(processId); var iWFEngine = await Bootstraper("", processId, null, null); // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(unitId, code, nextId); if (taskList.FindAll(t => t.Type != 10).Count == 0) { throw (new Exception("找不到下一个流转节点!")); } // 处理任务并更新数据 //wfProcessSerive.BeginTrans(); List myTaskList; using (var uwo = UnitWork.CreateContext()) { try { // 更新流程状态 await uwo.Db.Updateable() .SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 }) .SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1) .SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1) .Where(p => p.Id == processId) .ExecuteCommandAsync(); if (taskList.FindIndex(t => t.Type == 100) != -1) { if (process.IsChild == 1) { await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId); } } myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, processId, taskEntity.Token, taskEntity.Id); foreach (var item in myTaskList) { if (item.Type == 7) { await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); } await Add(item); } } catch { throw; } uwo.Commit(); } // 脚本执行 var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); foreach (var item in scriptTaskList) { await ExecuteScript(item, code, processId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity,""); } } private async Task AuditNodeByCountersign(IWFEngine iWFEngine, WFTask taskEntiy, string code, string name, string des, string stampImg) { taskEntiy.IsAgree = code == "disagree" ? 0 : 1; var node = iWFEngine.GetNode(taskEntiy.UnitId); var list = (List)await GetLastTaskList(taskEntiy.ProcessId, taskEntiy.UnitId); var myIndex = list.FindIndex(t => t.Id == taskEntiy.Id); if (myIndex == -1) { throw (new Exception("会签任务记录异常无法审核!")); } if (taskEntiy.IsAgree == 0) { if (node.CountersignType == "1") { // 并行 if (node.IsCountersignAll) { // 等待 if (list.FindIndex(t => t.Id != taskEntiy.Id && t.State == 1) != -1) { // 表示还有人没有审核 // 表示还有任务没有完成 using (var uwo = UnitWork.CreateContext()) { WFProcess processEntity = new WFProcess() { Id = taskEntiy.ProcessId, IsStart = 1, IsCancel = 0, }; await uwo.WFProcess.UpdateAsync(processEntity); taskEntiy.State = 3; await uwo.WFTask.UpdateAsync(taskEntiy); await CreateTaskLog(taskEntiy, code, name, des, stampImg); uwo.Commit(); } } else { var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count + 1; if ((num - fnum) * 100 / num >= node.CountersignAllType) { await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg); } else { await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); } } } else { // 不等待,每次都需要计算通过率 var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count + 1; if ((num - fnum) * 100 / num >= node.CountersignAllType)// 表示还有通过的希望 { using (var uwo = UnitWork.CreateContext()) { WFProcess processEntity = new WFProcess() { Id = taskEntiy.ProcessId, IsStart = 1, IsCancel = 0, }; await uwo.WFProcess.UpdateAsync(processEntity); taskEntiy.State = 3; await uwo.WFTask.UpdateAsync(taskEntiy); await CreateTaskLog(taskEntiy, code, name, des, stampImg); uwo.Commit(); } } else { await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); } } } else { // 串行 await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); } } else { if (node.CountersignType == "1") { // 并行 // 如果不等待,不同意直接跳转 if (node.IsCountersignAll) { if (list.FindIndex(t => t.Id != taskEntiy.Id && t.State == 1) != -1) // 表示还有人没有处理完 { // 表示还有任务没有完成 using (var uwo = UnitWork.CreateContext()) { WFProcess processEntity = new WFProcess() { Id = taskEntiy.ProcessId, IsStart = 1, IsCancel = 0, }; await uwo.WFProcess.UpdateAsync(processEntity); taskEntiy.State = 3; await uwo.WFTask.UpdateAsync(taskEntiy); await CreateTaskLog(taskEntiy, code, name, des, stampImg); uwo.Commit(); } } else { var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); var fnum = list.FindAll(t => t.State == 3 && t.IsAgree == 0).Count; if ((num - fnum) * 100 / num >= node.CountersignAllType) { await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg); } else { await AuditNode(iWFEngine, taskEntiy, "disagree", "不同意", des, stampImg); } } } else { var num = await GetTaskUserMaxNum(taskEntiy.ProcessId, taskEntiy.UnitId); var snum = list.FindAll(t => t.State == 3 && t.IsAgree == 1).Count; if (snum * 100 / num >= node.CountersignAllType) { await AuditNode(iWFEngine, taskEntiy, "agree", "同意", des, stampImg); } else { using (var uwo = UnitWork.CreateContext()) { WFProcess processEntity = new WFProcess() { Id = taskEntiy.ProcessId, IsStart = 1, IsCancel = 0, }; await uwo.WFProcess.UpdateAsync(processEntity); taskEntiy.State = 3; await uwo.WFTask.UpdateAsync(taskEntiy); await CreateTaskLog(taskEntiy, code, name, des, stampImg); uwo.Commit(); } } } } else { // 串行 if (myIndex == list.Count - 1) // 表示最后一个人审核完成,然后往下执行 { await AuditNode(iWFEngine, taskEntiy, code, name, des, stampImg); } else { // 表示还有任务没有完成 using (var uwo = UnitWork.CreateContext()) { WFProcess processEntity = new WFProcess() { Id = taskEntiy.ProcessId, IsStart = 1, IsCancel = 0, }; await uwo.WFProcess.UpdateAsync(processEntity); taskEntiy.State = 3; await uwo.WFTask.UpdateAsync(taskEntiy); await CreateTaskLog(taskEntiy, code, name, des, stampImg); if (node.CountersignType == "2") { // 串行,更新上一个任务的撤销操作,开启下一个任务 if (myIndex == 0) { await CloseTaskLogCancel(taskEntiy.ProcessId, taskEntiy.PrevTaskId); } else { await CloseTaskLogCancel(list[myIndex - 1].Id); } await uwo.WFTask.UpdateAsync(new WFTask { Id = list[myIndex + 1].Id, State = 1 }); } var flag = uwo.Commit(); } } } } } /// /// 创建日志 /// /// /// /// /// /// /// private async Task CreateTaskLog(WFTask taskEntiy, string code, string name, string des, string stampImg) { WFTaskLog wfTaskLogEntity = new WFTaskLog() { Des = $"【{name}】{des}", TaskType = taskEntiy.Type, ProcessId = taskEntiy.ProcessId, UnitId = taskEntiy.UnitId, UnitName = taskEntiy.UnitName, IsAgree = taskEntiy.IsAgree, OperationCode = code, OperationName = name, Token = taskEntiy.Token, PrevUnitId = taskEntiy.PrevUnitId, PrevUnitName = taskEntiy.PrevUnitName, TaskId = taskEntiy.Id, StampImg = stampImg, IsCancel = 1, IsLast = 1 }; await UpdateLog(taskEntiy.ProcessId, taskEntiy.UnitId); await AddLog(wfTaskLogEntity); } #endregion public async Task> Supervise(string processId,int supervise = 1) { // todo 实现督办 var iWFEngine = await Bootstraper(string.Empty, processId, null, null); // 获取未完成的任务 var taskList = await GetUnFinishTaskList(processId); using (var uwo = UnitWork.CreateContext()) { foreach (var item in taskList) { if (item.Type == 1 || item.Type == 3 || item.Type == 5 || item.Type == 6 || item.Type == 7) { // 督办时间督办标志 item.IsSupervise = supervise; item.SuperviseTime = DateTime.Now; item.SuperviseId = _auth.GetCurrentUser().User.Id; // 发送消息 var msg = $"【审核】【督办】{item.ProcessTitle},{item.UnitName}"; var userList = new List(); // todo 单体任务处理 userList.Add(item.UserId); var node = iWFEngine.GetNode(item.UnitId); //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, item.F_Token); await uwo.WFTask.UpdateAsync(item); } } //await wfProcessSerive.Update(new WFProcessEntity() { F_IsUrge = 1, F_Id = processId }); var wfTaskLogEntity = new WFTaskLog { Des = "督办审核", TaskType = 98, ProcessId = processId, UnitId = iWFEngine.StartNode.Id, UnitName = string.IsNullOrEmpty(iWFEngine.StartNode.Name) ? "开始节点" : iWFEngine.StartNode.Name, CreateDate = DateTime.Now, UserId = _auth.GetUserId(), UserName = _auth.GetUserNickName(), Id = Guid.NewGuid().ToString() }; await uwo.WFTaskLog.InsertAsync(wfTaskLogEntity); var flag = uwo.Commit(); return new Response { Result = flag, Message = flag ? "success" : "error" }; } } #region 撤回 /// /// 撤回流程 /// /// 流程任务主键 /// 流程审批操作码agree 同意 disagree 不同意 lrtimeout 超时 /// 流程审批操名称 /// 审批意见 /// 下一节点指定审核人 /// 盖章图片 /// 盖章图片密码 /// 下一个审核节点 public async Task RetractFlow(string taskId, string code, string name, string des, Dictionary nextUsers, string stampImg, string stampPassWord, string nextId) { var taskEntiy = await client.Queryable().Where(a => a.Id == taskId).FirstAsync(); if (taskEntiy == null) { throw (new Exception("找不到对应流程任务!")); } else if (taskEntiy.State != 3&& taskEntiy.State != 4) { throw (new Exception("该任务未完成!")); } //后期改 stampImg = ""; //stampImg = await _wFStampIBLL.ToWfImg(stampImg, stampPassWord); var iWFEngine = await Bootstraper("", taskEntiy.ProcessId, null, nextUsers); // 1.判断任务类型 1 普通任务 5 会签任务 if (taskEntiy.Type == 1 || taskEntiy.Type == 7) { await RetractNode(iWFEngine, taskEntiy, code, name, des, stampImg, nextId); } else { throw (new Exception("该任务无法审核!")); } //await _imMsgIBLL.VirtualDeleteByContentId(taskEntiy.F_Token); // 更新消息 // 发送消息 var msg = $"【提醒】{iWFEngine.Config.Params.Title},{taskEntiy.UnitName}已被撤回"; var userList = new List(); userList.Add(iWFEngine.CreateUser.Id); var node = iWFEngine.StartNode; //await _imMsgIBLL.SendMsg("IMWF", userList, msg, node.MessageType, iWFEngine.Config.Params.ProcessId); } /// /// 撤回 /// /// /// /// /// /// 下一个节点 /// /// /// private async Task RetractNode(IWFEngine iWFEngine, WFTask taskEntity, string code, string name, string des, string stampImg, string nextId = "") { // 下一部需要执行的任务 var taskList = await iWFEngine.GetTask(taskEntity.UnitId, code, nextId); List myTaskList; //修改原有任务的IsLast状态 await client.Updateable() .SetColumns(t => new WFTask() { IsLast = 0 }) .Where(t => t.Id==taskEntity.Id) .ExecuteCommandAsync(); //删除该节点之后生成的所有任务 var dellist=client.Queryable().Where(r=>r.CreateDate>taskEntity.CreateDate&&r.ProcessId==taskEntity.ProcessId).ToList(); await client.Deleteable(dellist).ExecuteCommandAsync(); // 处理任务并更新数据 using (var uwo = UnitWork.CreateContext()) { var process = await uwo.WFProcess.GetByIdAsync(taskEntity.ProcessId); await uwo.Db.Updateable() .SetColumns(p => new WFProcess { IsStart = 1, IsCancel = 0 }) .SetColumns(p=>p.IsFinished==0) .SetColumnsIF(taskList.FindIndex(t => t.Type == 100) != -1, p => p.IsFinished == 1) .SetColumnsIF(taskList.FindIndex(t => t.Type == 4) != -1, p => p.IsAgain == 1) .Where(p => p.Id == taskEntity.ProcessId) .ExecuteCommandAsync(); if (taskList.FindIndex(t => t.Type == 100) != -1) { if (process.IsChild == 1) { await ChildrenEndTask(process.ParentProcessId, process.ParentNodeId, code, taskEntity, nextId); } } var newTask = new WFTask { Id = Guid.NewGuid().ToString(), Type = taskEntity.Type, ProcessId = taskEntity.ProcessId, Token = Guid.NewGuid().ToString(), UnitId = taskEntity.UnitId, UnitName = taskEntity.UnitName, PrevUnitId = taskEntity.PrevUnitId, PrevUnitName = taskEntity.PrevUnitName, PrevToken = taskEntity.Token, PrevTaskId = taskEntity.Id, UserId = taskEntity.UserId, UserName = taskEntity.UserName, UserDepartmentId = taskEntity.UserDepartmentId, UserCompanyId = taskEntity.UserCompanyId, State = 1, Sort = taskEntity.Sort, IsReject = 0, ChildProcessId = taskEntity.ChildProcessId, ChildSchemeInfoCode = taskEntity.ChildSchemeInfoCode, TimeoutInterval = taskEntity.TimeoutInterval, TimeoutStrategy = taskEntity.TimeoutStrategy, IsBatchAudit = taskEntity.IsBatchAudit, ProcessUserId = iWFEngine.CreateUser.Id, ProcessUserName = iWFEngine.CreateUser.Name, ProcessCode = iWFEngine.Config.Params.SchemeCode, ProcessTitle = iWFEngine.Config.Params.Title, CreateDate = DateTime.Now, CreateUserId = _auth.GetUserId(), CreateUserName = _auth.GetUserName(), IsLast=1, IsRetract=1 }; await uwo.WFTask.InsertAsync(newTask); // 更新上一个流转过来的任务,提示他无法被撤销 await CloseTaskLogCancel(taskEntity.ProcessId, taskEntity.PrevTaskId); // 关闭同一个节点,其他人的任务 await CloseTask(taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); myTaskList = await ExecuteWFTaskEntity(taskList, iWFEngine, taskEntity.ProcessId, taskEntity.Token, taskEntity.Id); foreach (var item in myTaskList) { if (item.Type == 7) { await uwo.WFTaskUser.InsertRangeAsync(item.WFTaskUser); } await Add(item); } await CreateTaskLog(taskEntity, code, name, des, stampImg); uwo.Commit(); } // 脚本执行 var scriptTaskList = myTaskList.FindAll(t => t.Type == 10); foreach (var item in scriptTaskList) { await ExecuteScript(item, code, taskEntity.ProcessId, taskEntity.Id, nextId, iWFEngine.CreateUser, iWFEngine, taskEntity, des); } } #endregion } }