using Ewide.Core; using Furion; using Furion.DependencyInjection; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Localization; using Newtonsoft.Json.Linq; using RoadFlow.Model.FlowRunModel; using RoadFlow.Utility; using SqlSugar; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RoadFlow.Data { public class FlowTask : RoadFlowRepository, IFlowTask, ITransient { private readonly IUserManager _userManager = Furion.App.GetService(); private readonly ILog _log = new Log(); // /// 根据组ID查询列表 /// /// /// public List GetListByGroupId(string groupId) { return GetListBy(p => p.GroupId == groupId).OrderBy(p => p.Sort).ThenBy(p => p.StepSort).ThenBy(p => p.ReceiveTime).ThenBy(p => p.StepName).ThenBy(p => p.ReceiveName).ToList(); } /// /// 得到获取动态步骤的任务实体 /// /// 组ID /// 当前任务ID,如果为空,则返回的Model.FlowTask当前任务实体也为空 /// (动态任务, 当前任务, 任务组List) public (Model.rf_flowtask, Model.rf_flowtask, List) GetDynamicTask(string groupId, string? taskId = null) { if (!Config.EnableDynamicStep || groupId.IsNullOrEmpty()) { return (null, !taskId.IsNullOrEmpty() ? GetOneById(taskId) : null, null); } var groupTasks = GetListByGroupId(groupId); if (groupTasks.Count == 0) { return (null, null, groupTasks); } Model.rf_flowtask dynamicTask = null; Model.rf_flowtask currentTask = null; var sortTasks = groupTasks.FindAll(p => p.BeforeStepId.IsNotEmptyGuid()).OrderByDescending(p => p.Sort); if (sortTasks.Any()) { dynamicTask = sortTasks.First(); } if (taskId.IsNotEmptyGuid()) { currentTask = groupTasks.Find(p => p.Id == taskId); } return (dynamicTask, currentTask, groupTasks); } /// /// 判断人员是否可以打开任务 /// /// /// 返回 -1表示不能打开 0任务为空 1任务处理人 2实例管理人 public int IsOpenTask(string userId, Model.rf_flowtask flowTaskModel, Model.FlowRun flowRunModel = null) { if (null == flowTaskModel) { return 0; } if (flowTaskModel.ReceiveId == userId) { return 1; } if (null == flowRunModel) { flowRunModel = null;// _flow.GetFlowRunModel(flowTaskModel.FlowId); } if (flowRunModel == null || flowRunModel.InstanceManager.IsNullOrWhiteSpace()) { return -1; } if (new UserDummy().IsIn(userId.ToString(), flowRunModel.InstanceManager)) { return 2; } return -1; } /// /// 更新状态 /// /// 任务id /// 状态 /// 处理类型 int.MinValue表示不更新 /// 打开时间 null表示不更新 /// public int UpdateStatus(string taskId, int status, int executeType = int.MinValue, DateTime? openTime = null) { var task = this.GetOneById(taskId); task.Status = status; if (executeType != int.MinValue) task.ExecuteType = executeType; if (openTime != null && openTime.HasValue) task.OpenTime = openTime.Value; return this.Update(task); /* using (var db = new DataContext()) { if (openTime != null && openTime.HasValue) { db.Execute("UPDATE RF_FLOWTASK SET Status=" + status.ToString() + (executeType != int.MinValue ? ",ExecuteType=" + executeType.ToString() : "") + ",OpenTime={0}" + " WHERE Id={1}", openTime.Value, taskId); } else { db.Execute("UPDATE RF_FLOWTASK SET Status=" + status.ToString() + (executeType != int.MinValue ? ",ExecuteType=" + executeType.ToString() : "") + " WHERE Id={0}", taskId); } return db.SaveChanges(); }*/ } /// /// 判断一个任务是否可以催办 /// /// /// 是否可以收回 /// isWithdraw 是否可以收回 public bool IsHasten(string taskId, out bool isWithdraw) { isWithdraw = false; var task = GetOneById(taskId); if (null == task) { return false; } var groupTasks = GetListByGroupId(task.GroupId); var nextTasks = groupTasks.Where(p => p.PrevId == taskId); isWithdraw = nextTasks.Any() && !nextTasks.Any(p => p.Status != 0); return groupTasks.Exists(p => p.PrevId == taskId && p.Status.In(0, 1)); } /// /// 得到流程第一步发起者ID /// /// /// 组织架构字符串 u_人员ID,r_组织架构与人员关系ID public string GetFirstSenderId(string groupId) { return GetFirstSenderId(GetListByGroupId(groupId)); } /// /// 得到流程第一步发起者ID /// /// /// public string GetFirstSenderId(List groupTasks) { if (groupTasks.Count == 0) { return string.Empty; } var task = groupTasks.Find(p => p.PrevId == string.Empty); return task == null ? string.Empty : task.SenderId; } /// /// 得到流程第一步发起者ID(判断了兼职的情况) /// /// /// 组织架构字符串 u_人员ID,r_组织架构与人员关系ID public string GetFirstSenderIdString(List groupTasks) { if (groupTasks.Count == 0) { return string.Empty; } var task = groupTasks.Find(p => p.PrevId == string.Empty); return task == null ? string.Empty : (!task.ReceiveOrganizeId.IsNullOrWhiteSpace()) ? IOrganize.PREFIX_RELATION + task.ReceiveOrganizeId : IOrganize.PREFIX_USER + task.SenderId.ToString(); } /// /// 得到前一步实例ID /// /// /// public string GetPrevInstanceID(string taskId) { if (!taskId.IsGuid()) { return string.Empty; } var taskModel = GetOneById(taskId); if (null == taskModel || taskModel.PrevId.IsNullOrWhiteSpace()) { return string.Empty; } var prevTaskModel = GetOneById(taskModel.PrevId); return null == prevTaskModel ? string.Empty : prevTaskModel.InstanceId; } /// /// 得到前一步实例标题 /// /// /// public string GetPrevTitle(string taskId) { if (!taskId.IsGuid()) { return string.Empty; } var taskModel = GetOneById(taskId); if (null == taskModel || taskModel.PrevId.IsNullOrWhiteSpace()) { return string.Empty; } var prevTaskModel = GetOneById(taskModel.PrevId); return null == prevTaskModel ? string.Empty : prevTaskModel.Title; } /// /// 得到当前任务的后续接收步骤选择HTML /// /// 流程运行时实体 /// 步骤ID /// 组ID /// 任务ID /// 实例ID /// 当前人员ID /// 可以发送的步骤 /// 是否是自由发送 /// 是否是移动端 /// 组任务集合,为空则在方法中查询 /// 多语言包 /// 步骤选择html, 提醒信息, 可以发送的步骤集合 public (string html, string message, List sendSteps) GetNextSteps(Model.FlowRun flowRunModel, Guid stepId, string groupId, string taskId, string instanceId, string userId, bool isFreeSend, bool isMobile = false, List groupTasks = null, IStringLocalizer localizer = null) { if (groupTasks == null) { groupTasks = GetListByGroupId(groupId); } var currentTask = groupTasks.Find(p => p.Id == taskId); List sendSteps = new List(); Flow flow = new Flow(); var stepModel = flowRunModel.Steps.Find(p => p.Id == stepId); if (null == stepModel) { return ("", localizer == null ? "未找到步骤运行时!" : localizer["NotFoundFlowRunModel"], sendSteps); } List<(Model.FlowRunModel.Step, string)> nextStpes = new List<(Model.FlowRunModel.Step, string)>(); bool isAddWrite = null != currentTask && currentTask.TaskType == 6;//是否是前加签 //如果是发送到退回步骤 bool isSendToBackStep = null != currentTask && currentTask.TaskType == 4 && 1 == stepModel.StepBase.SendToBackStep; if (isSendToBackStep) { string stepMembers = GetStepHandler(groupTasks, currentTask.PrevStepId); var backStep = flowRunModel.Steps.Find(p => p.Id == currentTask.PrevStepId.ToGuid()); if (null != backStep) { nextStpes.Add((backStep, stepMembers)); } } else { //如果是按选择人员顺序处理 bool isStepSort = false; int hanlderModel = stepModel.StepBase.HanlderModel; if (hanlderModel == 4) { if (null != currentTask) { var task = groupTasks.Find(p => p.StepId == stepModel.Id.ToString() && p.Sort == currentTask.Sort && p.StepSort == currentTask.StepSort + 1); if (task != null) { nextStpes.Add((stepModel, !task.ReceiveOrganizeId.IsNullOrEmpty() && task.ReceiveOrganizeId != string.Empty ? IOrganize.PREFIX_RELATION + task.ReceiveOrganizeId : IOrganize.PREFIX_USER + task.ReceiveId)); isStepSort = true; } } } if (isAddWrite) { char[] otherType = currentTask.OtherType.ToString().ToCharArray(); if (otherType.Length != 3) { return ("", localizer == null ? "加签参数错误!" : localizer["FlowSend_AddWriteParamsError"], sendSteps); } int addType = otherType[1].ToString().ToInt();//加签类型 1前加签 2后加签 3并签 int executeType = otherType[2].ToString().ToInt(); ;//处理类型 1所有人同意,2一个同意 3顺序处理 if (executeType == 3) { var task = groupTasks.Find(p => p.StepId == currentTask.StepId && p.Sort == currentTask.Sort && p.StepSort == currentTask.StepSort + 1); if (null != task) { nextStpes.Add((stepModel, !task.ReceiveOrganizeId.IsNullOrWhiteSpace() && task.ReceiveOrganizeId != string.Empty ? IOrganize.PREFIX_RELATION + task.ReceiveOrganizeId : IOrganize.PREFIX_USER + task.ReceiveId.ToString())); } } if (!nextStpes.Any())//前加签,发送给加签人 { var addWriteTaskModel = GetOneById(currentTask.PrevId); if (null != addWriteTaskModel) { nextStpes.Add((stepModel, !addWriteTaskModel.ReceiveOrganizeId.IsNullOrWhiteSpace() && addWriteTaskModel.ReceiveOrganizeId == string.Empty ? IOrganize.PREFIX_RELATION + addWriteTaskModel.ReceiveOrganizeId : IOrganize.PREFIX_USER + addWriteTaskModel.ReceiveId.ToString())); } } } if (isFreeSend)//如果是自由发送,则在本步骤循环发送 { nextStpes.Add((stepModel, string.Empty)); } if (!isStepSort && !isFreeSend && !isAddWrite) { var nextStepsFlow = flow.GetNextSteps(flowRunModel, stepId); foreach (var nextStep in nextStepsFlow) { nextStpes.Add((nextStep, string.Empty)); } } } if (nextStpes.Count == 0) { return ("", localizer == null ? "当前步骤没有后续步骤" : localizer["FlowSend_NotNextStep"], sendSteps); } #region 如果设置了跳过,要判断跳过条件 List> skipStepTuples = new List>();//2020-1-17修改,记录当前步骤要跳过时,(被跳过的步骤ID,当前步骤ID,要跳到的步骤ID) //User buser = new User(); for (int i = 0; i < nextStpes.Count; i++) { var (nextStep, members) = nextStpes[i]; //2020-7-22修改把跳过判断单独到GetSkipSteps方法中(为了解决能够连续跳过多步的问题) List skipSteps = new List(); GetSkipSteps(flowRunModel, stepModel, nextStep, isFreeSend, groupTasks, taskId, instanceId, userId, skipSteps); if (hasSkipLastStep)//最后一步也要跳过时 { return ("", localizer == null ? "当前步骤没有后续步骤" : localizer["FlowSend_NotNextStep"], sendSteps); } else if (skipSteps.Count > 0) { nextStpes.RemoveAt(i); foreach (var nStep in skipSteps) { if (!nextStpes.Exists(p => p.Item1.Id == nStep.Id)) { nextStpes.Add((nStep, string.Empty)); } skipStepTuples.Add(new Tuple(nextStep.Id, stepModel.Id, nStep.Id));//2020-1-17修改,(被跳过的步骤ID,当前步骤ID,要跳到的步骤ID) } } } #endregion Dictionary setStepsHanlde = GetNextStepsHandle(groupTasks);//得到由处理人员设置的后续步骤处理人员 StringBuilder stringBuilder = new StringBuilder(); JObject jObject = new JObject();//vue版本不返回上面的stringBuilder添加的HTML,返回一个json字符串,以便作其他用途。 //2020-7-22修改,把下面的步骤条件判断移动到这里。方法参数要用到后面符合条件的所有步骤。 List<(Model.FlowRunModel.Step, string)> nextStpes1 = new List<(Model.FlowRunModel.Step, string)>(); List nextStpes2 = new List();//记录当前步骤后面符合条件的步骤,作为方法参数 foreach (var (nextStep, members) in nextStpes) { //如果是系统控制,要判断线上的条件 //2021-6-7修改(stepModel.StepBase.HanlderModel != 4 || nextStep.Id != stepId) //增加了|| nextStep.Id != stepId条件,当处理策略为选择人员顺序处理时,最后一个人处理后没有判断策略的bug。 if (!isFreeSend && (stepModel.StepBase.HanlderModel != 4 || nextStep.Id != stepId) && stepModel.StepBase.FlowType.In(0, 5)) { //2020-1-17修改,如果有跳过的步骤,From步骤ID应该是跳至的步骤ID Guid lineFromId = stepModel.Id; if (skipStepTuples.Exists(p => p.Item2 == stepModel.Id && p.Item3 == nextStep.Id)) { lineFromId = skipStepTuples.Where(p => p.Item2 == stepModel.Id && p.Item3 == nextStep.Id).FirstOrDefault().Item1; } //2020-1-17修改完 var lineModel = flowRunModel.Lines.Find(p => p.FromId == lineFromId && p.ToId == nextStep.Id); if (lineModel != null) { bool linePass = LinePass(lineModel, flowRunModel, stepModel, groupTasks, taskId, instanceId, userId, out string lineMsg); if (!linePass) { continue; } } } nextStpes1.Add((nextStep, members)); nextStpes2.Add(nextStep); } foreach (var (nextStep, members) in nextStpes1) { string defaultHanlde = members;//默认处理人 if (setStepsHanlde.ContainsKey(nextStep.Id))//如果处理人员设置的后续步骤的默认处理人员,则这里取设置的默认处理人员 { defaultHanlde = setStepsHanlde[nextStep.Id]; jObject.Add("runselect_" + nextStep.Id.ToLowerString(), 0);//如果是前面步骤指定的处理人,这里设置不让用户选择。 } var (defaultMembers, orgSelectType, selectRange) = !defaultHanlde.IsNullOrWhiteSpace() ? (defaultHanlde, "unit='1' dept='1' station='1' workgroup='1' user='1'", defaultHanlde) : GetDefaultMember(flowRunModel, stepModel, nextStep, groupTasks, taskId, instanceId, userId, nextStpes2); //如果设置了选择范围,则选择范围为设置值 if (!nextStep.StepBase.SelectRange.IsNullOrWhiteSpace()) { selectRange = nextStep.StepBase.SelectRange + "," + selectRange; } if (nextStep.Dynamic == 2 && !nextStep.DynamicField.IsNullOrWhiteSpace() && flowRunModel.Databases.Count > 0) { stringBuilder.Append(GetDynamicFieldStepHtml(flowRunModel, nextStep, instanceId, localizer)); nextStep.RunDefaultMembers = defaultMembers.TrimStart(','); sendSteps.Add(nextStep); continue; } string inputChecked = string.Empty; string inputDisabled = stepModel.StepBase.FlowType.In(0, 4) ? " disabled=\"disbaled\"" : ""; string inputType = stepModel.StepBase.FlowType == 1 ? "radio" : "checkbox"; string memberDisabled = nextStep.StepBase.RunSelect == 0 ? " disabled=\"disbaled\"" : ""; string ischangetype = selectRange.IsNullOrWhiteSpace() ? string.Empty : " isChangeType=\"0\"";//如果有选择范围则不能切换组织机构 if (stepModel.StepBase.FlowType.In(1, 2) && nextStep.Id == nextStpes.First().Item1.Id)//如果是单选默认选中第一个 { inputChecked = " checked=\"checked\""; } else if (stepModel.StepBase.FlowType.In(0, 3, 4, 5)) { inputChecked = " checked=\"checked\""; } bool isSetTime = 1 == nextStep.SendSetWorkTime && !isAddWrite;//如果设置了在发送时指定完成时间(加签任务不指定时间) stringBuilder.Append(""); stringBuilder.Append(""); stringBuilder.Append(""); stringBuilder.Append(""); if (nextStep.Dynamic == 1)//动态步骤要加上添加步骤按钮 { stringBuilder.Append(""); stringBuilder.Append(""); stringBuilder.Append(""); } stringBuilder.Append(""); stringBuilder.Append(""); stringBuilder.Append(""); if (isSetTime)//是否需要指定时间 { stringBuilder.Append("" + (localizer == null ? "完成时间" : localizer["FlowSend_CompletedTime"]) + ":"); stringBuilder.Append(""); } stringBuilder.Append(""); nextStep.RunDefaultMembers = defaultMembers.TrimStart(','); sendSteps.Add(nextStep); } return RoadFlow.Utility.Config.IsVue ? (jObject.ToString(Newtonsoft.Json.Formatting.None), "", sendSteps) : (stringBuilder.ToString(), "", sendSteps); } /// /// 得到某一个步骤的处理者 /// /// /// /// public string GetStepHandler(List groupTasks, string stepId) { var tasks = groupTasks.FindAll(p => p.StepId == stepId && p.TaskType != 5 && p.TaskType != 11); if (!tasks.Any()) { return string.Empty; } var maxSort = tasks.Max(p => p.Sort); var tasks1 = tasks.FindAll(p => p.Sort == maxSort); StringBuilder stringBuilder = new StringBuilder(); foreach (var task in tasks1) { if (task.ReceiveOrganizeId.IsNotEmptyGuid()) { stringBuilder.Append(IOrganize.PREFIX_RELATION + task.ReceiveOrganizeId); } else { stringBuilder.Append(IOrganize.PREFIX_USER + task.ReceiveId.ToString()); } stringBuilder.Append(","); } return stringBuilder.ToString().TrimEnd(','); } private bool hasSkipLastStep = false; /// /// 得到一个步骤跳过后的步骤(递归判断可以连续跳过多个步骤) /// /// 流程运行实体 /// 当前步骤 /// 下一步骤 /// 是否自由发送 /// 任务组 /// 任务id /// 实例id /// 用户id /// 返回最终要跳到的步骤List public void GetSkipSteps(Model.FlowRun flowRunModel, Model.FlowRunModel.Step stepModel, Model.FlowRunModel.Step nextStep, bool isFreeSend, List groupTasks, string taskId, string instanceId, string userId, List skipSteps) { if (hasSkipLastStep) { return; } if (nextStep.StepBase.SkipIdenticalUser == 1 || !nextStep.StepBase.SkipMethod.IsNullOrWhiteSpace()) { bool isSkip = false; //2019-12-25修改,跳过策略也要先判断线上的条件,如果条件不满足也不能跳过 bool isJudgeLine = !isFreeSend && stepModel.StepBase.HanlderModel != 4 && stepModel.StepBase.FlowType.In(0, 5); if (isJudgeLine) { var lineModel = flowRunModel.Lines.Find(p => p.FromId == stepModel.Id && p.ToId == nextStep.Id); if (lineModel != null) { isSkip = LinePass(lineModel, flowRunModel, stepModel, groupTasks, taskId, instanceId, userId, out string lineMsg); } } //2019-12-25修改,跳过策略也要先判断线上的条件,如果条件不满足也不能跳过,添加了if条件 if (!isJudgeLine || isSkip) { if (nextStep.StepBase.SkipIdenticalUser == 1) { var (defaultMembers, orgSelectType, selectRange) = GetDefaultMember(flowRunModel, stepModel, nextStep, groupTasks, taskId, instanceId, userId); //2020-1-17修改,注释了下面的(发送人如果没有包含到处理人里面isSkip应该为false) isSkip = new UserDummy().Contains(defaultMembers, userId); //if (buser.Contains(defaultMembers, userId)) //{ // isSkip = true; //} //2020-1-17修改完 } if (!isSkip && !nextStep.StepBase.SkipMethod.IsNullOrWhiteSpace()) { Model.FlowRunModel.EventParam EventParam = new Model.FlowRunModel.EventParam(); EventParam.FlowId = flowRunModel.Id; EventParam.GroupId = groupTasks.Count > 0 ? groupTasks.FirstOrDefault().GroupId.ToGuid() : Guid.Empty; EventParam.InstanceId = instanceId; EventParam.Other = nextStep; EventParam.StepId = stepModel.Id; EventParam.TaskId = taskId.ToGuid(); EventParam.TaskTitle = string.Empty; var (obj, err) = Tools.ExecuteMethod(nextStep.StepBase.SkipMethod.Trim(), EventParam); if (obj != null && (obj.ToString().Equals("1") || obj.ToString().EqualsIgnoreCase("true"))) { isSkip = true; } } } if (isSkip) { var nextNextSteps = new Flow().GetNextSteps(flowRunModel, nextStep.Id); if (nextNextSteps.Count == 0) { skipSteps.Clear(); hasSkipLastStep = true; GetSkipSteps(flowRunModel, nextStep, nextStep, isFreeSend, groupTasks, taskId, instanceId, userId, skipSteps); } foreach (var nStep in nextNextSteps) { if (nextStep.StepBase.FlowType.In(0, 5)) { var lineModel = flowRunModel.Lines.Find(p => p.FromId == nextStep.Id && p.ToId == nStep.Id); if (lineModel != null) { bool linePass = LinePass(lineModel, flowRunModel, stepModel, groupTasks, taskId, instanceId, userId, out string lineMsg); if (!linePass) { continue; } } } skipSteps.Add(nStep); //skipStepTuples.Add(new Tuple(nextStep.Id, stepModel.Id, nStep.Id));//2020-1-17修改,(被跳过的步骤ID,当前步骤ID,要跳到的步骤ID) } if (skipSteps.Count > 0) { List skipSteps1 = new List(); foreach (var nStep in skipSteps) { skipSteps1.Add(nStep); } foreach (var nStep in skipSteps1) { List skipSteps2 = new List(); GetSkipSteps(flowRunModel, nextStep, nStep, isFreeSend, groupTasks, taskId, instanceId, userId, skipSteps2); if (skipSteps2.Count > 0) { skipSteps.Clear(); foreach (var nStep1 in skipSteps2) { skipSteps.Add(nStep1); } } } } } } } /// /// 判断线的条件是否满足 /// /// /// /// /// 当前组的任务列表 /// /// /// /// 不满足时的提示信息 /// public bool LinePass(Model.FlowRunModel.Line lineModel, Model.FlowRun flowRunModel, Model.FlowRunModel.Step currentStepModel, List groupTasks, string taskId, string instanceId, string currentUserId, out string msg) { msg = string.Empty; if (null == lineModel) { return false; } JArray orgArray; try { orgArray = JArray.Parse(lineModel.OrganizeExpression); } catch { orgArray = new JArray(); } //如果没有设置条件,直接返回true if (lineModel.SqlWhere.IsNullOrWhiteSpace() && orgArray.Count == 0 && lineModel.CustomMethod.IsNullOrWhiteSpace()) { return true; } //判断SQL条件 bool sqlWhere = LinePass_SqlWhere(lineModel.SqlWhere, flowRunModel, instanceId); //判断组织架构 bool organize = LinePass_Organize(orgArray, flowRunModel, currentStepModel, currentUserId, groupTasks); //判断自定义方法 bool method = LinePass_Method(lineModel.CustomMethod, flowRunModel, currentStepModel, groupTasks, instanceId, taskId, out msg); return lineModel.JudgeType == 1 ? sqlWhere && organize && method : (sqlWhere && !lineModel.SqlWhere.IsNullOrWhiteSpace()) || (organize && orgArray.Count > 0) || (method && !lineModel.CustomMethod.IsNullOrWhiteSpace()); } /// /// 判断线上SQL条件是否满足 /// /// sql条件字符串 /// 流程运行时 /// 当前实例ID /// private bool LinePass_SqlWhere(string sqlWhere, Model.FlowRun flowRunModel, string instanceId) { if (sqlWhere.IsNullOrWhiteSpace()) { return true; } if (flowRunModel == null || flowRunModel.Databases.Count == 0) { return false; } DbConnection dbConnection = new DbConnection(); if (null == flowRunModel.Databases.First() || flowRunModel.Databases.First().ConnectionId.IsEmptyGuid() || flowRunModel.Databases.First().Table.IsNullOrWhiteSpace() || flowRunModel.Databases.First().PrimaryKey.IsNullOrWhiteSpace()) { return false; } var dbconnModel = dbConnection.GetOneById(flowRunModel.Databases.First().ConnectionId.ToString()); if (null == dbconnModel) { return false; } string sql = "SELECT " + flowRunModel.Databases.First().PrimaryKey + " FROM " + flowRunModel.Databases.First().Table + " WHERE " + flowRunModel.Databases.First().PrimaryKey + "={0}" + (sqlWhere.Trim().ToLower().StartsWith("and") ? " " : " AND ") + sqlWhere; try { DataTable dataTable = dbConnection.GetDataTable(dbconnModel, sql, instanceId); return dataTable.Rows.Count > 0; } catch { return false; } } /// /// 判断线上设置的组织架构判断 /// /// 组织架构表达式array /// 流程运行时 /// 当前步骤实体 /// 当前用户ID /// 当前任务组 /// private bool LinePass_Organize(JArray organizeExpressionJArray, Model.FlowRun flowRunModel, Model.FlowRunModel.Step currentStepModel, string currentUserId, List groupTasks) { if (organizeExpressionJArray.Count == 0) { return true; } string senderId = currentUserId; string sponserId = GetFirstSenderId(groupTasks);//发起者ID Organize organize = new Organize(); UserDummy user = new UserDummy(); if (sponserId.IsNullOrWhiteSpace() && currentStepModel.Id == flowRunModel.FirstStepId)//如果是第一步则发起者就是发送者 { sponserId = senderId; } StringBuilder orgWheres = new StringBuilder(); foreach (JObject json in organizeExpressionJArray) { if (json.Count == 0) { continue; } string usertype = json.Value("usertype"); string in1 = json.Value("in1"); string users = json.Value("users"); string selectorganize = json.Value("selectorganize"); string tjand = json.Value("tjand"); string khleft = json.Value("khleft"); string khright = json.Value("khright"); if (usertype.IsNullOrWhiteSpace() || in1.IsNullOrWhiteSpace() || (users.IsNullOrWhiteSpace() && selectorganize.IsNullOrWhiteSpace())) { continue; } string userid = "0".Equals(usertype) ? senderId : sponserId; string memberid = ""; bool isin = false; var leader = user.GetLeader(userid.ToString()); if ("0".Equals(users)) { memberid = selectorganize; } else if ("1".Equals(users)) { memberid = leader; } else if ("2" == users) { memberid = leader; } else if (users.IsGuid()) { //如果是GUID表示是工作角色 JArray workRoleJArray = user.GetWorkRole(userid); if (workRoleJArray != null && workRoleJArray.Count > 0) { foreach (JObject jObject in workRoleJArray) { if (jObject.Value("id").EqualsIgnoreCase(users)) { memberid = jObject.Value("orgValue"); break; } } } } if ("0" == in1) { isin = user.IsIn(userid.ToString(), memberid); } else if ("1" == in1) { isin = !user.IsIn(userid.ToString(), memberid); } if (!khleft.IsNullOrEmpty()) { orgWheres.Append(khleft); } orgWheres.Append(isin ? " true " : " false "); if (!khright.IsNullOrEmpty()) { orgWheres.Append(khright); } orgWheres.Append(tjand); } if (orgWheres.Length == 0) { return true; } return (bool)Tools.ExecuteExpression(orgWheres.ToString()); } /// /// 判断线上设置的方法条件 /// /// 方法字符串 /// 流程运行时 /// 当前步骤实体 /// 当前任务组 /// 当前实例ID /// 任务ID /// 方法中返回的字符串 /// private bool LinePass_Method(string method, Model.FlowRun flowRunModel, Model.FlowRunModel.Step currentStepModel, List groupTasks, string instanceId, string taskId, out string msg) { msg = string.Empty; if (method.IsNullOrWhiteSpace()) { return true; } Model.FlowRunModel.EventParam eventParam = new Model.FlowRunModel.EventParam { FlowId = flowRunModel.Id, GroupId = groupTasks.Count > 0 ? groupTasks.First().GroupId.ToGuid() : Guid.Empty, InstanceId = instanceId, StepId = currentStepModel.Id, TaskId = taskId.ToGuid() }; var (obj, err) = Tools.ExecuteMethod(method.Trim(), eventParam); if (null == obj) { return false; } msg = obj.ToString(); return "1".Equals(msg.ToLower()) || "true".Equals(msg.ToLower()); } /// /// 得到步骤默认处理人员 /// /// /// /// /// /// /// /// /// private (string defaultMembers, string orgSelectType, string selectRange) GetDefaultMember(Model.FlowRun flowRunModel, Model.FlowRunModel.Step currentStepModel, Model.FlowRunModel.Step nextStepModel, List groupTasks, string taskId, string instanceId, string currentUserId, List nextSteps = null) { //如果是调试模式并且当前登录人员包含在调试人员中 则默认为当前人员 if (flowRunModel.Debug > 0 && flowRunModel.DebugUserIds.ContainsIgnoreCase(currentUserId)) { return (IOrganize.PREFIX_USER + currentUserId.ToString(), "", ""); } #region 判断处理者类型 string members = string.Empty, selectType = string.Empty, selectRange = string.Empty; var currentTask = groupTasks.Find(p => p.Id == taskId); var firstSenderId = GetFirstSenderIdString(groupTasks);//发起者ID var parttimeId = "";//User.GetCurrentUserParttimeId(); 框架机制中不含对应标记。 var currentUserId1 = !parttimeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + parttimeId : IOrganize.PREFIX_USER + currentUserId.ToString(); if (firstSenderId.IsNullOrWhiteSpace() && currentStepModel.Id == flowRunModel.FirstStepId)//如果发起者为空,并且当前是第一步则发起者是当前人员 { firstSenderId = currentUserId1; } UserDummy user = new UserDummy(); //2021-2-7增加if判断,判断下面else if设置了工作角色的情况。 if (nextStepModel.StepBase.HandlerType.IsInt(out int handlerTypeInt)) { switch (handlerTypeInt) { case 0: selectType = "unit='1' dept='1' station='1' workgroup='1' user='1'"; break; case 1: selectType = "unit='0' dept='1' station='0' workgroup='0' user='0'"; break; case 2: selectType = "unit='0' dept='0' station='1' workgroup='0' user='0'"; break; case 3: selectType = "unit='0' dept='0' station='0' workgroup='1' user='0'"; break; case 4: selectType = "unit='0' dept='0' station='0' workgroup='0' user='1'"; break; case 5://发起者 members = firstSenderId;//Organize.PREFIX_USER + firstSenderId.ToString(); break; case 6://前一步骤处理者 members = currentTask == null ? currentUserId1 : GetStepHandler(groupTasks, currentTask.StepId); break; case 7://某一步骤处理者 members = nextStepModel.StepBase.HandlerStepId.HasValue ? GetStepHandler(groupTasks, nextStepModel.StepBase.HandlerStepId.Value.ToString()) : string.Empty; if (members.IsNullOrWhiteSpace() && currentStepModel.Id == flowRunModel.FirstStepId)//如果是第一步就是当前人员ID { members = currentUserId1; } break; case 8://字段值 if (flowRunModel.Databases.Count > 0) { string fieldValue = string.Empty;// Tools.HttpContext.Request.Forms((flowRunModel.Databases.First().Table + "-" + nextStepModel.StepBase.ValueField).ToUpper()); members = !fieldValue.IsNullOrWhiteSpace() ? fieldValue : GetFieldValue(flowRunModel.Databases.First(), nextStepModel.StepBase.ValueField, instanceId); } break; case 9://发起者部门领导 members = user.GetLeader(firstSenderId); break; case 10://发起者分管领导 members = user.GetLeader(firstSenderId); break; case 11://前一步处理者部门领导 members = currentTask == null ? user.GetLeader(currentUserId1) : user.GetLeader(GetStepHandler(groupTasks, currentTask.StepId).Split(',').ToList()).leader; break; case 12://前一步处理者分管领导 members = currentTask == null ? user.GetLeader(currentUserId1) : user.GetLeader(GetStepHandler(groupTasks, currentTask.StepId).Split(',').ToList()).chargeLeader; break; case 13://发起者上级部门领导 members = user.GetParentLeader(firstSenderId.ToString()).leader; break; case 14://前一步处理者上级部门领导 members = currentTask == null ? user.GetParentLeader(currentUserId1).leader : user.GetParentLeader( GetStepHandler( groupTasks, currentTask.StepId) .Split(',').ToList() ).leader; break; case 15://前一步处理者部门 var currentUserDept = user.GetDept(currentUserId1); if (currentUserDept != null) { members = currentUserDept.Id.ToString(); } //2021-2-18注释掉,添加上面的直接返回部门ID,不返回部门下所有人员。 //members = currentTask == null ? user.GetUserIds(user.GetOrganizeUsers(Organize.PREFIX_USER + currentUserId)) // : user.GetUserIds(user.GetOrganizeUsers(GetStepHandler(groupTasks, currentTask.StepId).Split(',').ToList())); break; case 16://发起者部门 var userDept = user.GetDept(firstSenderId); if (userDept != null) { members = userDept.Id.ToString(); } //2021-2-18注释掉,添加上面的直接返回部门ID,不返回部门下所有人员。 //members = user.GetUserIds(user.GetOrganizeUsers(firstSenderId.ToString())); break; case 17://发起者所有上级部门领导 members = user.GetAllParentLeader(firstSenderId).leader; break; case 18://前一步处理者所有上级部门领导 members = currentTask == null ? user.GetAllParentLeader(firstSenderId).leader : user.GetAllParentLeader(GetStepHandler(groupTasks, currentTask.StepId).Split(',').ToList()).leader; break; case 19://发起者单位 var userUnit = user.GetUnit(firstSenderId); if (userUnit != null) { members = userUnit.Id.ToString(); } break; case 20://前一步处理者单位 var currnetUserUnit = user.GetUnit(currentUserId1); if (currnetUserUnit != null) { members = currnetUserUnit.Id.ToString(); } break; case 21://前一步处理者 members = currentUserId1; break; } } else if (!nextStepModel.StepBase.HandlerType.IsNullOrWhiteSpace()) { //2021-2-7增加了根据部门上设置的工作角色来判断处理人。 string[] handlerTypeArray = nextStepModel.StepBase.HandlerType.Split('|'); string workRoleId = handlerTypeArray.Length > 0 ? handlerTypeArray[0] : string.Empty; string workRoleType = handlerTypeArray.Length > 1 ? handlerTypeArray[1] : string.Empty; if (workRoleId.IsGuid() && workRoleType.IsInt(out int workRoleInt)) { string handlerId = string.Empty; switch (workRoleInt) { case 1://发起者 handlerId = firstSenderId.ToString(); break; case 2://发送者 handlerId = IOrganize.PREFIX_USER + currentUserId; break; } JArray workRoleJson = new JArray();// user.GetDept(handlerId).WorkRole.ToJArray(); foreach (JObject workRoleObject in workRoleJson) { if (workRoleId.Equals(workRoleObject.Value("id"))) { members = members + "," + workRoleObject.Value("orgValue"); } } } } #endregion #region SQL或方法 string sqlOrMethod = nextStepModel.StepBase.DefaultHandlerSqlOrMethod; if (!sqlOrMethod.IsNullOrWhiteSpace()) { //如果是以select开头说明是sql if (sqlOrMethod.Trim().StartsWith("select", StringComparison.CurrentCultureIgnoreCase)) { if (flowRunModel.Databases.Count > 0) { StringBuilder stringBuilder = new StringBuilder(); DataTable dataTable = null; try { var conn = new DbConnection(); dataTable = conn.GetDataTable(conn.GetOneById(flowRunModel.Databases.First().ConnectionId.ToString()), RoadFlow.Business.Wildcard.Filter(sqlOrMethod).FilterSelectSql()); } catch { } if (dataTable != null && dataTable.Columns.Count > 0) { foreach (DataRow dr in dataTable.Rows) { stringBuilder.Append(dr[0].ToString()); stringBuilder.Append(","); } } members = members + "," + stringBuilder.ToString().TrimEnd(','); } } else { Model.FlowRunModel.EventParam eventParam = new Model.FlowRunModel.EventParam { FlowId = flowRunModel.Id, GroupId = groupTasks.Count > 0 ? groupTasks.First().GroupId.ToGuid() : Guid.Empty, InstanceId = instanceId, StepId = currentStepModel.Id, TaskId = taskId.ToGuid(), Other = nextStepModel, //nextSteps == null ? new List() : nextSteps }; var (obj, err) = Tools.ExecuteMethod(sqlOrMethod.Trim(), eventParam); if (null != obj) { members = members + "," + obj.ToString(); } } } #endregion if (!nextStepModel.StepBase.DefaultHandler.IsNullOrWhiteSpace()) { members = members + "," + nextStepModel.StepBase.DefaultHandler; } //2021-3-15新增,如果没有默认处理人,则从上一次的发送记录中取。 if (members.IsNullOrWhiteSpace() && nextStepModel.StepBase.LastHadler == 1) { members = new RoadFlow.Data.FlowReceive().GetPrevMembers(flowRunModel.Id.ToString(), nextStepModel.Id.ToString(), currentUserId); } string members1 = members.IsNullOrWhiteSpace() ? string.Empty : members.Split(',').Distinct().ToList().JoinList();//去重 //如果设置了处理者类型,则选择范围就是处理者类型 if (nextStepModel.StepBase.HandlerType.ToInt() > 4) { selectRange = members1; } return (members1, selectType, selectRange); } /// /// 得到流程接收人为字段值时的字段值 /// /// 流程连接 /// 选择的字段 /// 主键值 /// public string GetFieldValue(Model.FlowRunModel.Database database, string fieldString, string instanceId) { if (!fieldString.IsNullOrWhiteSpace() && !instanceId.IsNullOrWhiteSpace() && database != null) { string[] dbs = fieldString.Split('.'); string linkId = string.Empty, tableName = string.Empty, field = string.Empty; if (dbs.Length > 0) { linkId = dbs[0]; } if (dbs.Length > 1) { tableName = dbs[1]; } if (dbs.Length > 2) { field = dbs[2]; } string primaryKey = database.PrimaryKey; if (!linkId.IsGuid()) { linkId = database.ConnectionId.ToString(); } if (tableName.IsNullOrWhiteSpace()) { tableName = database.Table; } if (field.IsNullOrWhiteSpace()) { field = fieldString; } if (linkId.IsGuid(out Guid linkGuid) && !tableName.IsNullOrWhiteSpace() && !field.IsNullOrWhiteSpace() && !primaryKey.IsNullOrWhiteSpace()) { return new DbConnection().GetFieldValue(linkId, tableName, field, primaryKey, instanceId); } } return string.Empty; } /// /// 得到步骤由流程处理人设置的后续步骤处理人员 /// /// 实例组列表 /// public Dictionary GetNextStepsHandle(List groupTasks) { Dictionary dict = new Dictionary(); foreach (Model.rf_flowtask flowTask in groupTasks.OrderBy(p => p.Sort)) { if (flowTask.NextStepsHandle.IsNullOrWhiteSpace()) { continue; } try { JArray jArray = JArray.Parse(flowTask.NextStepsHandle); foreach (JObject jObject in jArray) { string handle = jObject.Value("handle"); string stepId = jObject.Value("stepId"); if (!stepId.IsGuid(out Guid stepGuid) || handle.IsNullOrWhiteSpace()) { continue; } if (dict.ContainsKey(stepGuid)) { dict[stepGuid] = handle; } else { dict.Add(stepGuid, handle); } } } catch { } } return dict; } public string GetDynamicFieldStepHtml(Model.FlowRun flowRunModel, Model.FlowRunModel.Step step, string instanceId, IStringLocalizer localizer = null) { if (flowRunModel.Databases.Count == 0) { return string.Empty; } string[] fileds = step.DynamicField.Split('.'); if (fileds.Length != 3) { return string.Empty; } Guid connId = fileds[0].ToGuid(); string table = fileds[1]; string field = fileds[2]; string fieldVlaue = string.Empty; try { fieldVlaue = new DbConnection().GetFieldValue(connId.ToString(), table, field, flowRunModel.Databases.First().PrimaryKey, instanceId); } catch { } if (fieldVlaue.IsNullOrWhiteSpace()) { return string.Empty; } string[] steps = fieldVlaue.Split(','); StringBuilder stringBuilder = new StringBuilder(); int i = 0; foreach (string s in steps) { string id = GuidExtensions.NewGuid().ToString(); string stepId = i == 0 ? step.Id.ToString() : GuidExtensions.NewGuid().ToString(); string beforestepid = step.Id.ToString(); string stepName = new Organize().GetNames(s); stringBuilder.Append("" + (i == 0 ? "" : "") + "" + "" + ""); stringBuilder.Append("" + ""); if (1 == step.SendSetWorkTime) { stringBuilder.Append("" + (localizer == null ? "完成时间" : localizer["FlowSend_CompletedTime"]) + ":"); } stringBuilder.Append(""); i++; } return stringBuilder.ToString(); } /// /// 从字段值得到动态步骤 /// 字段值格式:{flowtype:0 流转类型0并且 1串行,runedit:0 是否运行时编辑,steps:[{name:'test1',members:'u_EB03262C-AB60-4BC6-A4C0-96E66A4229FE'},{name:'test2',members:'u_954DC69A-30FF-4484-9234-3C9272B6893F'}]} /// /// /// /// /// public JObject GetDynamicStepFromFieldValue(Model.FlowRun flowRunModel, Model.FlowRunModel.Step step, string instanceId) { JObject nullJObject = new JObject() { { "flowtype", -1 }, { "runedit", -1 }, { "steps", new JArray() } }; if (!Utility.Config.EnableDynamicStep || flowRunModel == null || flowRunModel.Databases.Count == 0 || step == null || instanceId.IsNullOrWhiteSpace()) { return nullJObject; } var db = flowRunModel.Databases.FirstOrDefault(); Guid connId = db.ConnectionId; string table = db.Table; string primaryKey = db.PrimaryKey; JObject jObject = new JObject(); try { string fieldValue = new DbConnection().GetFieldValue(connId.ToString(), table, step.DynamicField, primaryKey, instanceId); if (fieldValue.IsNullOrWhiteSpace()) { return nullJObject; } JObject jObject1 = fieldValue.ToJObject(); if (jObject1.IsEmptyJObject()) { return nullJObject; } int flowType = jObject1.Value("flowtype").ToInt(0); int runEdit = jObject1.Value("runedit").ToInt(0); jObject.Add("flowtype", flowType); jObject.Add("runedit", runEdit); JArray jArray = new JArray(); foreach (JObject step1 in jObject1.Value("steps")) { string stepName = step1.Value("name"); string members = step1.Value("members"); jArray.Add(new JObject() { { "id", Guid.NewGuid().ToString() }, { "name", stepName }, { "members", members }, { "setTime", step.SendSetWorkTime }, { "time", step.WorkTime > 0 ? DateExtensions.Now.AddDays((double)step.WorkTime).ToShortDateTimeString() : "" }, { "beforestepid", step.Id.ToString() }, { "parallelorserial", flowType } }); } jObject.Add("steps", jArray); return jObject; } catch (Exception err) { new Log().Add(err); return nullJObject; } } /// /// 得到退回步骤选择HTML /// /// 流程ID /// 步骤ID /// 组ID /// 任务ID /// 实例ID /// 当前人员ID /// 可以退回的步骤 /// 当前审批组任务列表,如果为空则在方法中查询 /// 多语言包 /// 步骤选择HTML(VUE版本这里返回"1"或"0"表单是否可以选择接收人),提示信息,退回的步骤集合 public (string html, string message, List backSteps) GetBackSteps(string flowId, string stepId, string groupId, string taskId, string instanceId, string userId, List groupTasks = null, IStringLocalizer localizer = null) { List backSteps = new List(); Flow flow = new Flow(); if (groupTasks == null) { groupTasks = GetListByGroupId(groupId); } var taskModel = groupTasks.Find(p => p.Id == taskId); if (taskModel == null) { return ("", localizer == null ? "未找到当前任务!" : localizer["NotFoundTask"], backSteps); } Model.rf_flowtask beforTask = null; if (Config.EnableDynamicStep && taskModel.BeforeStepId.IsNullOrWhiteSpace()) { var beforTasks = groupTasks.OrderByDescending(p => p.Sort).Where(p => p.BeforeStepId.IsNotEmptyGuid()); if (beforTasks.Any()) { beforTask = beforTasks.First(); } } var flowRunModel = flow.GetFlowRunModel(flowId, true, beforTask == null ? taskModel : beforTask); if (flowRunModel == null) { return ("", localizer == null ? "未找到流程运行时实体!" : localizer["NotFoundFlowRunModel"], backSteps); } var stepModel = flowRunModel.Steps.Find(p => p.Id == stepId.ToGuid()); if (null == stepModel) { return ("", localizer == null ? "未找到步骤运行时实体!" : localizer["NotFoundStepModel"], backSteps); } if (flowRunModel.FirstStepId == stepModel.Id) { return ("", localizer == null ? "第一步不能退回!" : localizer["FlowBack_FirstStepCanotBack"], backSteps); } int backModel = stepModel.StepBase.BackModel; if (backModel == 0) { return ("", localizer == null ? "当前步骤设置为不能退回!" : localizer["FlowBack_CurrentStepCanotBack"], backSteps); } bool isOrderBackModel = false;//是否是按顺序处理退回 bool isShowUserNames = false;//是否在退回步骤上显示用户姓名 int hanlderModel = stepModel.StepBase.HanlderModel; //如果是加签退回给加签人 //2019-12-1修改 转交退回给转交人(taskModel.TaskType.In增加条件3, 10) if (taskModel.TaskType.In(3, 6, 7, 10)) { var backTask = GetOneById(taskModel.PrevId); if (null != backTask) { stepModel.RunDefaultMembers = !backTask.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + backTask.ReceiveOrganizeId : IOrganize.PREFIX_USER + backTask.ReceiveId.ToString(); backSteps.Add(stepModel); isShowUserNames = true; } } //2019-12-1修改 转交退回给转交人(判断多级转交,查找同步骤是否有别人转交的任务) else if (taskModel.TaskType == 4 && groupTasks.Exists(p => p.ReceiveId == taskModel.ReceiveId && p.TaskType.In(3, 10) && p.StepId == taskModel.StepId)) { var prevTask1 = groupTasks.Find(p => p.ReceiveId == taskModel.ReceiveId && p.TaskType.In(3, 10) && p.StepId == taskModel.StepId); if (null != prevTask1) { var prevTask2 = groupTasks.Find(p => p.Id == prevTask1.PrevId); if (null != prevTask2) { stepModel.RunDefaultMembers = !prevTask2.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + prevTask2.ReceiveOrganizeId : IOrganize.PREFIX_USER + prevTask2.ReceiveId.ToString(); backSteps.Add(stepModel); isShowUserNames = true; } } }//2019-12-1修改完 else if (backModel == 1 && hanlderModel == 4) { var backTask = groupTasks.Find(p => p.StepId == taskModel.StepId && p.TaskType != 5 && p.TaskType != 11 && p.Sort == taskModel.Sort && p.StepSort == taskModel.StepSort - 1); if (null != backTask) { stepModel.RunDefaultMembers = !backTask.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + backTask.ReceiveOrganizeId : IOrganize.PREFIX_USER + backTask.ReceiveId.ToString(); backSteps.Add(stepModel); isOrderBackModel = true; isShowUserNames = true; } } if (!backSteps.Any()) { int backType = stepModel.StepBase.BackType; switch (backType) { case 0://退回前一步 var prevSteps = flow.GetPrevSteps(flowRunModel, taskModel.StepId); foreach (var prevStep in prevSteps) { //2020-8-27增加 prevTaskModel != null && prevTaskModel.TaskType == 3判断前一任务是转交的,退回给转交接收人。 var prevTaskModel = groupTasks.Find(p => p.Id == taskModel.PrevId); //2021-3-27在下面增加了条件 && p.Status == 2 判断只有已完成的任务才能接收退回。 var prevTasks = prevTaskModel != null && prevTaskModel.TaskType == 3 ? groupTasks.FindAll(p => p.StepId == prevStep.Id.ToString() && p.Status == 2 && p.PrevId == prevTaskModel.PrevId && p.TaskType != 5 && p.TaskType != 11) : groupTasks.FindAll(p => p.StepId == prevStep.Id.ToString() && p.Status == 2 && p.OtherType == prevTaskModel.OtherType && p.TaskType != 5 && p.TaskType != 11); if (prevTasks.Count == 0) { prevTasks = groupTasks.FindAll(p => p.StepId == prevStep.Id.ToString() && p.Status == 2 && p.TaskType != 5 && p.TaskType != 11); } if (prevTasks.Count > 0) { var prevMaxSort = prevTasks.Max(p => p.Sort); var prevTask1 = prevTasks.FindAll(p => p.Sort == prevMaxSort); if (prevTask1.Count > 0) { StringBuilder userIds = new StringBuilder(); foreach (var prevTask in prevTask1) { userIds.Append(!prevTask.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + prevTask.ReceiveOrganizeId : IOrganize.PREFIX_USER + prevTask.ReceiveId.ToString()); userIds.Append(","); } prevStep.RunDefaultMembers = userIds.ToString().TrimEnd(','); backSteps.Add(prevStep); } } } //2020-10-26增加,如果前一步没有找到接收人,则退回给前面步骤的处理人(跳过步骤的情况会出现) if (backSteps.Count == 0) { var prevTasks = groupTasks.FindAll(p => p.StepId == taskModel.PrevStepId && p.TaskType != 5 && p.TaskType != 11); var prevMaxSort = prevTasks.Max(p => p.Sort); var prevtasks1 = prevTasks.FindAll(p => p.Sort == prevMaxSort); if (prevtasks1.Count > 0) { var prevStep = flowRunModel.Steps.Find(p => p.Id == prevtasks1.FirstOrDefault().StepId.ToGuid()); if (prevStep != null) { StringBuilder userIds = new StringBuilder(); foreach (var prevTask in prevtasks1) { userIds.Append(!prevTask.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + prevTask.ReceiveOrganizeId : IOrganize.PREFIX_USER + prevTask.ReceiveId.ToString()); userIds.Append(","); } prevStep.RunDefaultMembers = userIds.ToString().TrimEnd(','); backSteps.Add(prevStep); } } } //2020-10-26增加完 break; case 1://退回第一步 var firstStep = flowRunModel.Steps.Find(p => p.Id == flowRunModel.FirstStepId); if (null != firstStep) { firstStep.RunDefaultMembers = IOrganize.PREFIX_USER + GetFirstSenderId(groupTasks).ToString(); backSteps.Add(firstStep); } break; case 2://退回某一步 if (stepModel.StepBase.BackStepId.HasValue)//如果设计时选择了退回步骤 { var step = flowRunModel.Steps.Find(p => p.Id == stepModel.StepBase.BackStepId.Value); if (null != step) { step.RunDefaultMembers = GetStepHandler(groupTasks, step.Id.ToString()); backSteps.Add(step); } } else//如果没有选,则列出步骤让用户选择 { var groupSteps = GetTaskInstanceSteps(flowRunModel, groupTasks); foreach (var step in groupSteps) { if (step.Id == taskModel.StepId.ToGuid()) { continue; } step.RunDefaultMembers = GetStepHandler(groupTasks, step.Id.ToString()); backSteps.Add(step); } } break; } } if (!backSteps.Any()) { return ("", localizer == null ? "未找到要退回的步骤!" : localizer["FlowBack_NotFoundBackStep"], backSteps); } StringBuilder stringBuilder = new StringBuilder(); int stepIndex = 0; foreach (var backStep in backSteps) { //如果退回的接收步骤是顺序处理,则只退回给顺序处理的最后一个人。 if (!isOrderBackModel && hanlderModel == 4) { var stepTasks = groupTasks.FindAll(p => p.StepId == backStep.Id.ToString() && p.TaskType != 5 && p.TaskType != 11); if (stepTasks.Count > 0) { var maxSort = stepTasks.Max(p => p.Sort); var stepTasks1 = stepTasks.FindAll(p => p.Sort == maxSort).OrderByDescending(p => p.StepSort); if (stepTasks1.Count() > 0) { backStep.RunDefaultMembers = !stepTasks1.First().ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + stepTasks1.First().ReceiveOrganizeId : IOrganize.PREFIX_USER + stepTasks1.First().ReceiveId.ToString(); } } } //2020-2-13修改增加&& !taskModel.TaskType.In(3, 4, 6, 7, 10)条件,因为转交,加签,自由发送是退回给发送者,前面已判断,所以这里排除。 else if (backModel == 4 && !taskModel.TaskType.In(3, 4, 6, 7, 10))//独立退回,只退回给发送者 { //2019-11-27修改,独立退回时步骤接收人不对的bug var stepTasks = groupTasks.FindAll(p => p.StepId == backStep.Id.ToString() && p.TaskType != 5 && p.TaskType != 11); if (stepTasks.Count > 0) { int maxSort = stepTasks.Max(p => p.Sort); var stepTasks1 = stepTasks.FindAll(p => p.Sort == maxSort); StringBuilder defaultMembers = new StringBuilder(); foreach (var task in stepTasks1) { defaultMembers.Append(!task.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + task.ReceiveOrganizeId + "," : IOrganize.PREFIX_USER + task.ReceiveId.ToString() + ","); } backStep.RunDefaultMembers = defaultMembers.ToString().TrimEnd(','); } //2019-11-27修改完 isShowUserNames = true; } string checke = stepIndex++ == 0 ? "checked=\"checked\"" : "";//默认选中第一步 stringBuilder.Append("
"); stringBuilder.Append(""); stringBuilder.Append(""); if (1 == stepModel.StepBase.BackSelectUser)//如果设置的是退回时可以选择接收人 { stringBuilder.Append("
"); stringBuilder.Append(""); stringBuilder.Append("
"); } else { stringBuilder.Append(""); stringBuilder.Append(""); } stringBuilder.Append(""); } return (RoadFlow.Utility.Config.IsVue ? stepModel.StepBase.BackSelectUser.ToString() : stringBuilder.ToString(), "", backSteps); } /// /// 得到一个实例经过的步骤 /// /// /// 组任务集合 /// public List GetTaskInstanceSteps(Model.FlowRun flowRunModel, List groupTasks) { var steps = groupTasks.OrderBy(p => p.Sort).GroupBy(p => p.StepId); List groupSteps = new List(); foreach (var step in steps) { var stepModel = flowRunModel.Steps.Find(p => p.Id == step.Key.ToGuid()); if (null != stepModel) { groupSteps.Add(stepModel); } } return groupSteps; } private Model.FlowRunModel.ExecuteResult executeResult; private List nextStepTasks; private List addTasks;//要添加的任务 private List updateTasks;//要修改的任务 private List removeTasks;//要删除的任务 private List<(string, object[], int)> executeSqls;//要执行的SQL列表(sql,参数,0提交或退回前 1提交或退回后) private static readonly object lockObj = new object();//锁对象 /// /// 执行流程 /// /// /// 流程运行时实体 /// 语言包 /// 系统类型 0:默认类型,1:VUE模式 public Model.FlowRunModel.ExecuteResult Execute(Model.FlowRunModel.Execute executeModel, Model.FlowRun flowRunModel = null, IStringLocalizer localizer = null) { if (null == flowRunModel) { Model.rf_flowtask flowTaskModel = null; if (Config.EnableDynamicStep && executeModel.GroupId.IsNotEmptyGuid()) { var beforeTasks = GetListByGroupId(executeModel.GroupId.ToString()).OrderByDescending(p => p.Sort).Where(p => p.BeforeStepId.IsNotEmptyGuid()); if (beforeTasks.Any()) { flowTaskModel = beforeTasks.First(); } } flowRunModel = new Flow().GetFlowRunModel(executeModel.FlowId.ToString(), true, flowTaskModel); } if (null == flowRunModel) { executeResult.DebugMessages = localizer == null ? "未找到流程运行时!" : localizer["Execute_NotFoundFlowRunModel"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "未找到流程运行时!" : localizer["Execute_NotFoundFlowRunModel"].Value; return executeResult; } var currentStep = flowRunModel.Steps.Find(p => p.Id == executeModel.StepId); if (null == currentStep && executeModel.ExecuteType != Model.FlowRunModel.Execute.Type.AddWrite) { executeResult.DebugMessages = localizer == null ? "未找到流程运行时步骤!" : localizer["Execute_NotFoundStepRunModel"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "未找到流程运行时步骤!" : localizer["Execute_NotFoundStepRunModel"].Value; return executeResult; } //组织事件参数 Model.FlowRunModel.EventParam eventParam = new Model.FlowRunModel.EventParam { FlowId = executeModel.FlowId, GroupId = executeModel.GroupId, InstanceId = executeModel.InstanceId, StepId = executeModel.StepId, TaskId = executeModel.TaskId, TaskTitle = executeModel.Title, FlowRunModel = flowRunModel }; lock (lockObj) { executeResult = new Model.FlowRunModel.ExecuteResult(); nextStepTasks = new List(); addTasks = new List(); updateTasks = new List(); removeTasks = new List(); executeSqls = new List<(string, object[], int)>(); #region 判断委托 //2020-6-29增加,将委托判断统一到这里判断 if (executeModel.Steps != null && executeModel.Steps.Count > 0) { FlowEntrust flowEntrust = new FlowEntrust(); UserDummy user = new UserDummy(); foreach (var (stepId, stepName, beforeStepId, parallelOrSerial, receiveUsers, completedTime) in executeModel.Steps) { if (null == receiveUsers || receiveUsers.Count == 0) { continue; } for (int j = 0; j < receiveUsers.Count; j++) { var userModel = receiveUsers[j]; //userModel.Note = ""; string entrustId = flowEntrust.GetEntrustUserId(executeModel.FlowId.ToString(), userModel); if (!entrustId.IsNullOrWhiteSpace()) { var entrustUser = user.GetFromTempCache(entrustId);// RoadFlow.Model.FlowRunModel.User.FromSysUser(user.GetFromTempCache(entrustId)); if (null != entrustUser) { userModel = entrustUser; // userModel.Note = receiveUsers[j].Id.ToString();//用这个字段来保存委托人ID,在加入任务表的时候要用到 } } receiveUsers[j] = userModel; } } } #endregion switch (executeModel.ExecuteType) { case Model.FlowRunModel.Execute.Type.Submit: case Model.FlowRunModel.Execute.Type.FreeSubmit: case Model.FlowRunModel.Execute.Type.Completed: #region 提交前事件 if (!currentStep.StepEvent.SubmitBefore.IsNullOrWhiteSpace())//加签不执行事件 { string eventName = currentStep.StepEvent.SubmitBefore.Trim(); //如果是以[sql]开头,则说明是SQL语句 if (eventName.StartsWith("[sql]")) { object[] objects = new object[] { eventParam.TaskId, eventParam.InstanceId, eventParam.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(eventName).TrimStart("[sql]".ToCharArray()), objects, 0)); } else { var (eventReturn, err) = Tools.ExecuteMethod(eventName, eventParam); string eventReturnStr = null == eventReturn ? string.Empty : eventReturn.ToString(); if (null != err) { _log.Add("执行提交前事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + currentStep.StepEvent.SubmitBefore, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } if (!eventReturnStr.IsNullOrWhiteSpace() && !"1".Equals(eventReturnStr) && !"true".EqualsIgnoreCase(eventReturnStr)) { //提交前事件,如果事件返回值不为空并且为,1或true字符串,则表示错误信息,阻止流程提交。 if ("false".EqualsIgnoreCase(eventReturnStr)) { eventReturnStr = localizer == null ? "不能提交!" : localizer["Execute_EventStepBeforeErrorCannotSubmit"].Value; } executeResult.DebugMessages = eventReturnStr; executeResult.IsSuccess = false; executeResult.Messages = eventReturnStr; return executeResult; } } } #endregion Submit(flowRunModel, executeModel, localizer); #region 提交后SQL if (!currentStep.StepEvent.SubmitAfter.IsNullOrWhiteSpace() && currentStep.StepEvent.SubmitAfter.Trim().StartsWith("[sql]")) { //第一步提交的时候taskID没有值,在这里赋值 if (null != executeResult.CurrentTask) { eventParam.TaskId = executeResult.CurrentTask.Id.ToGuid(); eventParam.GroupId = executeResult.CurrentTask.GroupId.ToGuid(); eventParam.TaskTitle = executeResult.CurrentTask.Title; if (eventParam.InstanceId.IsNullOrWhiteSpace()) { eventParam.InstanceId = executeResult.CurrentTask.InstanceId; } } //如果是以[sql]开头,则说明是SQL语句 object[] objects = new object[] { eventParam.TaskId, eventParam.InstanceId, eventParam.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(currentStep.StepEvent.SubmitAfter.Trim(), null, executeModel).TrimStart("[sql]".ToCharArray()), objects, 1)); } #endregion break; case Model.FlowRunModel.Execute.Type.Back: #region 退回前事件 if (!currentStep.StepEvent.BackBefore.IsNullOrWhiteSpace()) { string eventName = currentStep.StepEvent.BackBefore.Trim(); //如果是以[sql]开头,则说明是SQL语句 if (eventName.StartsWith("[sql]")) { object[] objects = new object[] { eventParam.TaskId, eventParam.InstanceId, eventParam.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(eventName).TrimStart("[sql]".ToCharArray()), objects, 0)); } else { var (eventReturn, err) = Tools.ExecuteMethod(eventName, eventParam); string eventReturnStr = null == eventReturn ? string.Empty : eventReturn.ToString(); if (null != err) { _log.Add("执行退回前事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + currentStep.StepEvent.SubmitBefore, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } if (!eventReturnStr.IsNullOrWhiteSpace() && !"1".Equals(eventReturnStr) && !"true".EqualsIgnoreCase(eventReturnStr)) { //退回前事件,如果事件返回值不为空并且为,1或true字符串,则表示错误信息,阻止流程提交。 if ("false".EqualsIgnoreCase(eventReturnStr)) { eventReturnStr = localizer == null ? "不能退回!" : localizer["Execute_EventStepBackBeforeErrorCannotBack"].Value; } executeResult.DebugMessages = eventReturnStr; executeResult.IsSuccess = false; executeResult.Messages = eventReturnStr; return executeResult; } } } #endregion Back(flowRunModel, executeModel, localizer); #region 退回后SQL if (!currentStep.StepEvent.BackAfter.IsNullOrWhiteSpace() && currentStep.StepEvent.BackAfter.Trim().StartsWith("[sql]")) { //如果是以[sql]开头,则说明是SQL语句 object[] objects = new object[] { eventParam.TaskId, eventParam.InstanceId, eventParam.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(currentStep.StepEvent.BackAfter.Trim(), null, executeModel).TrimStart("[sql]".ToCharArray()), objects, 1)); } #endregion break; case Model.FlowRunModel.Execute.Type.Save: Save(flowRunModel, executeModel, localizer); break; case Model.FlowRunModel.Execute.Type.Redirect: Redirect(flowRunModel, executeModel, localizer); break; case Model.FlowRunModel.Execute.Type.CopyforCompleted: CopyForCompleted(flowRunModel, executeModel, localizer); break; case Model.FlowRunModel.Execute.Type.TaskEnd: TaskEnd(flowRunModel, executeModel, localizer); break; case Model.FlowRunModel.Execute.Type.AddWrite: AddWrite(flowRunModel, executeModel, localizer); break; } //2020-03-12新增 判断流程连接和系统连接是否是一个连接 bool isSystemDbConn = true; Model.rf_dbconnection dbConnModel = null; if (executeSqls.Count > 0 && flowRunModel != null && flowRunModel.Databases.Count > 0) { //new DbConnection().IsSystemConn为同时新增方法 DbConnection dbConnection = new DbConnection(); dbConnModel = dbConnection.GetOneById(flowRunModel.Databases.FirstOrDefault().ConnectionId.ToString()); isSystemDbConn = dbConnection.IsSystemConn(dbConnModel); //如果流程库和系统不是一个库,则executeSqls里的sql在这里执行。 if (dbConnModel != null && !isSystemDbConn) { var beforeSql = executeSqls.Where(p => p.Item3 == 0); if (beforeSql.Any()) { dbConnection.executeSqlByConnection(dbConnModel, beforeSql); /* using (var db = new Mapper.DataContext(dbConnModel.ConnType, dbConnModel.ConnString)) { foreach (var (sql, objs, _) in beforeSql) { db.Execute(sql, objs);//提交前sql } db.SaveChanges(); }*/ } } } //2020-03-12新增完 int i = Update(removeTasks, updateTasks, addTasks, isSystemDbConn ? executeSqls : new List<(string, object[], int)>()); //2020-03-12新增 判断流程连接和系统连接是否是一个连接 //如果流程库和系统不是一个库,则executeSqls里的sql在这里执行。 if (dbConnModel != null && !isSystemDbConn) { var afterSql = executeSqls.Where(p => p.Item3 == 1); if (afterSql.Any()) { new DbConnection().executeSqlByConnection(dbConnModel, afterSql); /* using (var db = new Mapper.DataContext(dbConnModel.ConnType, dbConnModel.ConnString)) { foreach (var (sql, objs, _) in afterSql) { db.Execute(sql, objs);//提交后sql } db.SaveChanges(); }*/ } } //2020-03-12新增完 //处理提交后事件 switch (executeModel.ExecuteType) { case Model.FlowRunModel.Execute.Type.Submit: case Model.FlowRunModel.Execute.Type.FreeSubmit: case Model.FlowRunModel.Execute.Type.Completed: #region 提交后事件 if (!currentStep.StepEvent.SubmitAfter.IsNullOrWhiteSpace() && !currentStep.StepEvent.SubmitAfter.Trim().StartsWith("[sql]")) { //第一步提交的时候taskID没有值,在这里赋值 if (null != executeResult.CurrentTask) { eventParam.TaskId = executeResult.CurrentTask.Id.ToGuid(); eventParam.GroupId = executeResult.CurrentTask.GroupId.ToGuid(); eventParam.TaskTitle = executeResult.CurrentTask.Title; if (eventParam.InstanceId.IsNullOrWhiteSpace()) { eventParam.InstanceId = executeResult.CurrentTask.InstanceId; } } var (eventReturn, err) = Tools.ExecuteMethod(currentStep.StepEvent.SubmitAfter.Trim(), eventParam); if (null != err) { _log.Add("执行提交后事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + currentStep.StepEvent.SubmitBefore, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } #endregion #region 步骤通过后事件 if (executeResult.StepIsPass && !currentStep.StepEvent.SubmitPassAfter.IsNullOrWhiteSpace() && !currentStep.StepEvent.SubmitPassAfter.Trim().StartsWith("[sql]")) { string passEventName = currentStep.StepEvent.SubmitPassAfter.Trim(); var (eventReturn, err) = Tools.ExecuteMethod(passEventName, eventParam); if (null != err) { _log.Add("执行通过后事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + passEventName, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } #endregion break; case Model.FlowRunModel.Execute.Type.Back: #region 退回后事件 if (!currentStep.StepEvent.BackAfter.IsNullOrWhiteSpace() && !currentStep.StepEvent.BackAfter.Trim().StartsWith("[sql]")) { var (eventReturn, err) = Tools.ExecuteMethod(currentStep.StepEvent.BackAfter.Trim(), eventParam); if (null != err) { _log.Add("执行退回后事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + currentStep.StepEvent.SubmitBefore, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } #endregion #region 步骤退回通过后事件 if (executeResult.StepIsBack && !currentStep.StepEvent.BackPassAfter.IsNullOrWhiteSpace() && !currentStep.StepEvent.BackPassAfter.Trim().StartsWith("[sql]")) { string backEventName = currentStep.StepEvent.BackPassAfter.Trim(); var (eventReturn, err) = Tools.ExecuteMethod(backEventName, eventParam); if (null != err) { _log.Add("执行退回通过后事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + backEventName, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } #endregion break; } if (executeResult.DebugMessages.IsNullOrEmpty()) { executeResult.DebugMessages = (localizer == null ? "执行成功,影响的行数:" : localizer["Execute_ExecuteSuccess"].Value) + i.ToString(); } #region 流程完成后SQL或事件 //执行流程完成后事件或SQL 2020-9-5新增 if (executeResult.FlowIsCompleted) { //如果流程库和系统不是一个库,则executeSqls里的sql在这里执行。 if (dbConnModel != null && !isSystemDbConn) { var completedSql = executeSqls.Where(p => p.Item3 == 2); if (completedSql.Any()) { new DbConnection().executeSqlByConnection(dbConnModel, completedSql); /* using (var db = new Mapper.DataContext(dbConnModel.ConnType, dbConnModel.ConnString)) { foreach (var (sql, objs, _) in completedSql) { db.Execute(sql, objs);//完成后sql } db.SaveChanges(); }*/ } } #region 流程完成后事件 if (!flowRunModel.TitleField.EventCompleted.IsNullOrWhiteSpace() && !flowRunModel.TitleField.EventCompleted.Trim().StartsWith("[sql]")) { string completedEventName = flowRunModel.TitleField.EventCompleted.Trim(); var (eventReturn, err) = Tools.ExecuteMethod(completedEventName, eventParam); if (null != err) { _log.Add("执行完成后事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + completedEventName, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } #endregion } #endregion #region 流程终止后SQL或事件 if (executeResult.FlowIsStop) { //如果流程库和系统不是一个库,则executeSqls里的sql在这里执行。 if (dbConnModel != null && !isSystemDbConn) { var stopSql = executeSqls.Where(p => p.Item3 == 3); if (stopSql.Any()) { new DbConnection().executeSqlByConnection(dbConnModel, stopSql); /* using (var db = new Mapper.DataContext(dbConnModel.ConnType, dbConnModel.ConnString)) { foreach (var (sql, objs, _) in stopSql) { db.Execute(sql, objs);//终止后sql } db.SaveChanges(); }*/ } } #region 流程终止后事件 if (!flowRunModel.TitleField.EventStop.IsNullOrWhiteSpace() && !flowRunModel.TitleField.EventStop.Trim().StartsWith("[sql]")) { string stopEventName = flowRunModel.TitleField.EventStop.Trim(); var (eventReturn, err) = Tools.ExecuteMethod(stopEventName, eventParam); if (null != err) { _log.Add("执行完成后事件发生了错误-" + flowRunModel.Name + "-" + currentStep.Name + "-" + stopEventName, _userManager.UserId, "参数:" + eventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } #endregion } #endregion } if (executeResult.Messages.IsNullOrWhiteSpace()) { executeResult.Messages = GetExecuteMessage(executeResult, executeModel, currentStep, localizer); } if (executeModel.ExecuteType != Model.FlowRunModel.Execute.Type.Save) { SendMessageVue(executeResult.NextTasks, executeModel.Sender, Utility.Config.IsVue ? currentStep.StepCopyFor.SendMessageType : "0,1,2,3,4", localizer: localizer); } return executeResult; } /// /// 提交任务 /// /// /// 语言包 /// 执行参数实体 /// 当前步骤是否通过 public void Submit(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { Model.rf_flowtask currentTask; List groupTasks; //如果是第一步提交并且没有实例则先创建实例 bool isFirstTask = executeModel.StepId == flowRunModel.FirstStepId && executeModel.TaskId.IsEmptyGuid(); if (isFirstTask) { if (executeModel.Title.IsNullOrWhiteSpace()) { executeModel.Title = flowRunModel.Name + "-" + GetStepName(flowRunModel, executeModel.StepId); } currentTask = GetFirstTask(flowRunModel, executeModel); groupTasks = new List { currentTask }; executeModel.TaskId = currentTask.Id.ToGuid(); executeModel.GroupId = currentTask.GroupId.ToGuid(); //添加动态流程步骤JSON if (Config.EnableDynamicStep && executeModel.Steps.Exists(p => p.beforeStepId.IsNotEmptyGuid())) { var newFlowRunModel = new FlowDynamic().Add(executeModel, groupTasks); if (null != newFlowRunModel) { flowRunModel = newFlowRunModel; } executeModel.Steps.RemoveAll(p => p.parallelOrSerial.HasValue && p.parallelOrSerial == 1 && p.stepId != p.beforeStepId); } //================= } else { groupTasks = GetListByGroupId(executeModel.GroupId.ToString()); currentTask = groupTasks.Find(p => p.Id == executeModel.TaskId.ToString()); } //2020-6-1新增,如果是征求意见回复,直接跳转到已回复处理。 if (currentTask != null && currentTask.TaskType == 11) { SolicitCompleted(currentTask, executeModel, localizer); return; } executeResult.CurrentTask = currentTask; #region 判断是否能处理 if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } if (currentTask.ReceiveId != executeModel.Sender.Id && currentTask.IsAutoSubmit == 0) { executeResult.DebugMessages = localizer == null ? "当前任务接收人不属于当前用户!" : localizer["Execute_SubmitCurrentTaskReceiveUserError"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "您不能处理当前任务!" : localizer["Execute_SubmitCurrentTaskCanotProcess"].Value; return; } var currentStep = flowRunModel.Steps.Find(p => p.Id == currentTask.StepId.ToGuid()); if (null == currentStep) { executeResult.DebugMessages = localizer == null ? "未找到当前步骤运行时实体!" : localizer["NotFoundStepModel"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "未找到当前步骤运行时实体!" : localizer["NotFoundStepModel"].Value; return; } #endregion if (executeModel.Title.IsNullOrWhiteSpace()) { executeModel.Title = currentTask.Title; } if (currentTask.InstanceId.IsNullOrWhiteSpace() && !executeModel.InstanceId.IsNullOrWhiteSpace()) { currentTask.InstanceId = executeModel.InstanceId; } if (currentTask.TaskType == 6)//处理前加签 { BeforAddWrite(flowRunModel, executeModel, currentTask, localizer); return; } if (currentTask.OtherType == 1)//如果是子流程任务,这里要赋值,后续任务也要设置为1 { executeModel.OtherType = 1; } bool currentStepIsPass = true;//当前步骤是否通过 #region 如果当前任务是子流程任务并且是子流程完成才能提交,要判断子流程是否完成 if (!currentTask.SubFlowGroupId.IsNullOrWhiteSpace() && currentStep.StepSubFlow.SubFlowStrategy != 1) { string[] subFlowGroupIds = currentTask.SubFlowGroupId.Split(','); foreach (string subId in subFlowGroupIds) { if (subId.IsGuid(out Guid sid)) { if (GetListByGroupId(subId).Exists(p => p.Status < 2 && p.TaskType != 5 && p.TaskType != 11)) { executeResult.DebugMessages = localizer == null ? "当前步骤对应的子流程还未完成,不能提交!" : localizer["Execute_SubmitSubflowUncompleted"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前步骤对应的子流程还未完成,不能提交!" : localizer["Execute_SubmitSubflowUncompleted"].Value; return; } } } } #endregion #region 处理策略判断 int maxSort = groupTasks.FindAll(p => p.StepId == currentTask.StepId && p.TaskType != 6).Max(p => p.Sort); //2021-3-25增加,如果设置了处理策略分组,这里要按分组过滤 var levelTasks = currentStep.StepBase.HanlderModelGroup > 0 ? groupTasks.FindAll(p => p.StepId == currentTask.StepId && p.Sort == currentTask.Sort && p.TaskType != 5 && p.TaskType != 11 && p.OtherType == currentTask.OtherType) : groupTasks.FindAll(p => p.StepId == currentTask.StepId && p.Sort == maxSort && p.TaskType != 5 && p.TaskType != 11);//当前任务的同级任务 if (levelTasks.Count > 0) { int hanlderModel = currentStep.StepBase.HanlderModel; //如果是后加签策略要从加签中取 if (currentTask.TaskType == 7) { char[] otherType = currentTask.OtherType.ToString().ToCharArray(); if (otherType.Length == 3) { int addExecuteType = otherType[2].ToString().ToInt();//处理类型 1所有人同意,2一个同意 3顺序处理 if (addExecuteType == 1) { hanlderModel = 0; } else if (addExecuteType == 2) { hanlderModel = 1; } else if (addExecuteType == 3) { hanlderModel = 4; } } } switch (hanlderModel) { case 0://所有人必须处理 currentStepIsPass = !levelTasks.Exists(p => p.Status != 2 && p.Id != currentTask.Id); break; case 1://一人同意即可 foreach (var task in levelTasks)//将当前任务除外的其它任务标记为他人已处理 { if (task.Id == currentTask.Id || task.Status == 2) { continue; } var updateTask = task.Clone(); updateTask.ExecuteType = 4; updateTask.Status = 2; updateTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(updateTask); } break; case 2://依据人数比例 decimal percentage = currentStep.StepBase.Percentage; currentStepIsPass = (decimal)(levelTasks.Count(p => p.Status == 2) + 1) / (decimal)levelTasks.Count * 100 >= percentage; if (currentStepIsPass) { foreach (var task in levelTasks.FindAll(p => p.Status != 2 && p.Id != currentTask.Id)) { var updateTask = task.Clone(); updateTask.ExecuteType = 4; updateTask.Status = 2; updateTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(updateTask); } } break; case 3://独立处理 break; case 4://按钮选择人员顺序处理 //将当前任务的下一个任务标记为待处理 var nextTask = levelTasks.FindAll(p => p.StepSort > currentTask.StepSort).OrderBy(p => p.StepSort); if (nextTask.Count() > 0) { var updateTask = nextTask.First().Clone(); updateTask.ExecuteType = 0; updateTask.Status = 0; updateTasks.Add(updateTask); currentStepIsPass = false; executeResult.NextTasks.Add(updateTask); executeResult.IsSuccess = true; } break; } } #endregion #region 完成当前任务 var updateCurrentTask = currentTask.Clone(); updateCurrentTask.ExecuteType = 2; updateCurrentTask.Comments = executeModel.Comment; updateCurrentTask.CompletedTime1 = DateExtensions.Now; updateCurrentTask.IsSign = executeModel.IsSign; updateCurrentTask.Status = 2; updateCurrentTask.Attachment = executeModel.Attachment; if (isFirstTask) { addTasks.Add(updateCurrentTask); } else { updateTasks.Add(updateCurrentTask); } #endregion #region 如果当前步骤通过,则添加下一步待办 if (currentStepIsPass) { #region 完成当前步骤等待中的任务 var waitTasks = levelTasks.FindAll(p => p.Status == -1); foreach (var waitTask in waitTasks) { if (currentStep.StepBase.HanlderModel == 4)//如果是按顺序人员处理,则不能删除,因为下次退回的时候才能找到是哪些人。 { var wTask = waitTask.Clone(); wTask.ExecuteType = 4; wTask.Status = 2; wTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(wTask); } else { removeTasks.Add(waitTask); } } #endregion foreach (var (stepId, stepName, beforeStepId, parallelorserial, receiveUsers, completedTime) in executeModel.Steps) { var nextStpe = flowRunModel.Steps.Find(p => p.Id == stepId); if (null == nextStpe) { continue; } DateTime? completedTime1 = completedTime; DateTime? remindTime = new DateTime?();//提醒时间(如果任务设置了超期提示) WorkDate workDate = new WorkDate(); if (!completedTime1.HasValue && nextStpe.WorkTime > 0) { completedTime1 = workDate.GetWorkDateTime((double)nextStpe.WorkTime); } if (completedTime1.HasValue && nextStpe.ExpiredPrompt > 0) { remindTime = workDate.GetWorkDateTime((double)(nextStpe.ExpiredPromptDays - nextStpe.ExpiredPromptDays * 2), completedTime1); } #region 如果下一步有步骤会签策略,则要判断步骤是否通过 bool stepPass = true;//步骤是否通过 int countersignature = nextStpe.StepBase.Countersignature; if (countersignature != 0) { stepPass = false; var prevSteps = new Flow().GetPrevSteps(flowRunModel, nextStpe.Id.ToString()); switch (countersignature) { case 1://所有步骤同意 bool allPass = true; foreach (var prevStep in prevSteps) { if (prevStep.StepBase.HanlderModelGroup == 0) { if (prevStep.Id == currentStep.Id) { continue; } if (!StepIsPass(flowRunModel, prevStep, nextStpe, groupTasks)) { allPass = false; break; } } else //步骤设置了分组的情况 { if (prevStep.Id == currentStep.Id && prevStep.StepBase.HanlderModelGroup == 0) { continue; } int prevStepMaxSort = groupTasks.Where(p => p.StepId == prevStep.Id.ToString()).Max(p => p.Sort); var groupingTasks = groupTasks.Where(p => p.StepId == prevStep.Id.ToString() && p.Sort == prevStepMaxSort).GroupBy(p => p.OtherType); foreach (var groupingTask in groupingTasks) { var gtasks = groupingTask.ToList(); if (currentTask.OtherType == gtasks.FirstOrDefault().OtherType) { continue; } if (!StepIsPass(flowRunModel, prevStep, nextStpe, gtasks)) { allPass = false; break; } } } } stepPass = allPass; break; case 2://一个步骤同意即可 stepPass = true; foreach (var prevStep in prevSteps) { if (prevStep.StepBase.HanlderModelGroup == 0) { if (prevStep.Id == currentStep.Id) { continue; } //将同级步骤的其它步骤任务标识为他人已处理 var stepTasks = groupTasks.FindAll(p => p.Sort == currentTask.Sort && p.TaskType != 5 && p.TaskType != 11); foreach (var stepTask in stepTasks) { if (stepTask.Status == 2 || stepTask.Id == currentTask.Id || updateTasks.Exists(p => p.Id == stepTask.Id)) { continue; } var stepTask1 = stepTask.Clone(); stepTask1.Status = 2; stepTask1.ExecuteType = 4; stepTask1.CompletedTime1 = DateExtensions.Now; updateTasks.Add(stepTask1); } } else { //将当前步骤的其它任务标识为他人已处理 var stepTasks = groupTasks.FindAll(p => p.StepId == prevStep.Id.ToString() && p.TaskType != 5 && p.TaskType != 11); foreach (var stepTask in stepTasks) { if (stepTask.Status == 2 || stepTask.Id == currentTask.Id || updateTasks.Exists(p => p.Id == stepTask.Id)) { continue; } var stepTask1 = stepTask.Clone(); stepTask1.Status = 2; stepTask1.ExecuteType = 4; stepTask1.CompletedTime1 = DateExtensions.Now; updateTasks.Add(stepTask1); } } } break; case 3://步骤比例 int stepPassCount = 1; foreach (var prevStep in prevSteps) { if (StepIsPass(flowRunModel, prevStep, nextStpe, groupTasks)) { stepPassCount++; if ((decimal)stepPassCount / (decimal)prevSteps.Count * 100 >= nextStpe.StepBase.CountersignaturePercentage) { stepPass = true; break; } } } if (stepPass) { //将同级步骤的其它步骤任务标识为他人已处理 var stepTasks = groupTasks.FindAll(p => p.Sort == currentTask.Sort && p.TaskType != 5 && p.TaskType != 11); foreach (var stepTask in stepTasks) { if (stepTask.Status == 2 || stepTask.Id == currentTask.Id || updateTasks.Exists(p => p.Id == stepTask.Id)) { continue; } var stepTask1 = stepTask.Clone(); stepTask1.Status = 2; stepTask1.ExecuteType = 4; stepTask1.CompletedTime1 = DateExtensions.Now; updateTasks.Add(stepTask1); } } break; } } if (!stepPass) { executeResult.Messages = localizer == null ? "已发送,等待其他步骤处理!" : localizer["Execute_SubmitSendWaitOtherStep"].Value; continue; } #endregion #region 如果下一步是子流程步骤,则要发起子流程实例 if (nextStpe.Type == 1) { Guid subFlowId = nextStpe.StepSubFlow.SubFlowId; var subFlowRunModel = new Flow().GetFlowRunModel(subFlowId.ToString()); if (null == subFlowRunModel) { continue; } string subFlowName = subFlowRunModel.Name; var subFlowFirstStep = subFlowRunModel.Steps.Find(p => p.Id == subFlowRunModel.FirstStepId); if (null == subFlowFirstStep) { continue; } string firstStepName = subFlowFirstStep.Name; string subFlowActiveEvent = nextStpe.StepEvent.SubFlowActivationBefore; int subFlowInstanceType = nextStpe.StepSubFlow.TaskType; string subInstanceId = string.Empty;//子流程实例ID string subTaskTitle = string.Empty;//子流程任务标题 #region 执行子流程激活前事件 if (!subFlowActiveEvent.IsNullOrWhiteSpace()) { //组织事件参数 Model.FlowRunModel.EventParam eventParam = new Model.FlowRunModel.EventParam { FlowId = currentTask.FlowId.ToGuid(), GroupId = currentTask.GroupId.ToGuid(), InstanceId = currentTask.InstanceId, StepId = currentTask.StepId.ToGuid(), TaskId = currentTask.Id.ToGuid(), TaskTitle = currentTask.Title }; var (obj, err) = Tools.ExecuteMethod(subFlowActiveEvent, eventParam); if (null != obj) { //事件返回包含两个字段的JSON字符串 instanceId(子流程业务表主键值) title(子流程任务标题) try { JObject jObject = JObject.Parse(obj.ToString()); subInstanceId = jObject.Value("instanceId"); subTaskTitle = jObject.Value("title"); } catch { } } } if (subTaskTitle.IsNullOrWhiteSpace())//如果子流程标题为空,设置默认标题。 { subTaskTitle = subFlowRunModel.Name + " - " + subFlowFirstStep.Name; } #endregion #region 添加子流程第一步待办 int stepSort1 = 1; Guid subGroupId = GuidExtensions.NewGuid(); StringBuilder subGropuIdBuilder = new StringBuilder();//记录子流程GROUPID, 关联主任务的SubFlowGroupId字段 foreach (var receiveUser in receiveUsers) { Guid groupid = subFlowInstanceType == 0 ? subGroupId : GuidExtensions.NewGuid(); if (subFlowInstanceType == 1) { subGropuIdBuilder.Append(groupid); subGropuIdBuilder.Append(","); } Model.rf_flowtask task = new Model.rf_flowtask { ExecuteType = stepSort1 == 1 ? 0 : -1, FlowId = subFlowId.ToString(), FlowName = subFlowName, GroupId = groupid.ToString(), Id = GuidExtensions.NewGuid().ToString(), InstanceId = subInstanceId, IsSign = 0, PrevId = string.Empty, PrevStepId = string.Empty, ReceiveId = receiveUser.Id, ReceiveName = receiveUser.Name, ReceiveTime = DateExtensions.Now, SenderId = executeModel.Sender.Id, SenderName = executeModel.Sender.Name, Sort = 1, Status = stepSort1 == 1 ? 0 : -1, StepId = subFlowRunModel.FirstStepId.ToString(), StepName = firstStepName, StepSort = nextStpe.StepBase.HanlderModel == 4 ? stepSort1++ : stepSort1, TaskType = 0, Title = subTaskTitle, IsAutoSubmit = subFlowFirstStep.ExpiredExecuteModel, CompletedTime = completedTime1, IsBatch = subFlowFirstStep.BatchExecute, OtherType = 1 //1表示是子流程 }; /* if (!receiveUser.PartTimeId.IsNullOrWhiteSpace()) { task.ReceiveOrganizeId = receiveUser.PartTimeId; }*/ /* if (receiveUser.Note.IsGuid(out Guid entuustId))//用人员实体的NOTE字段来存放委托人ID { task.EntrustUserId = receiveUser.Note; task.Note = localizer == null ? "委托" : localizer["Execute_SubmitTaskNoteEntrust"].Value; } */ addTasks.Add(task); //executeResult.NextTasks.Add(task); } #endregion #region 给当前处理者增加待办 var addTask = currentTask.Clone(); addTask.SenderId = currentTask.ReceiveId; addTask.SenderName = currentTask.ReceiveName; addTask.Status = 0; addTask.ExecuteType = 0; addTask.Comments = ""; addTask.IsSign = 0; addTask.Sort = currentTask.Sort + 1; addTask.OpenTime = null; addTask.CompletedTime1 = null; addTask.CompletedTime = completedTime1; addTask.Id = GuidExtensions.NewGuid().ToString(); addTask.PrevId = currentTask.Id; addTask.PrevStepId = currentTask.StepId; addTask.Title = executeModel.Title; addTask.ReceiveTime = DateExtensions.Now; addTask.IsAutoSubmit = nextStpe.ExpiredExecuteModel; addTask.StepId = nextStpe.Id.ToString(); addTask.StepName = nextStpe.Name; addTask.SubFlowGroupId = subGropuIdBuilder.Length == 0 ? subGroupId.ToString() : subGropuIdBuilder.ToString().TrimEnd(','); addTask.IsBatch = nextStpe.BatchExecute; addTasks.Add(addTask); executeResult.NextTasks.Add(addTask); #endregion continue; } #endregion #region 激活下一步等待中的任务 2021-9-10增加 var nextStepWaitTasks = groupTasks.Where(p => p.Status == -1 && p.StepId == nextStpe.Id.ToString()); foreach (Model.rf_flowtask waitTaskModel in nextStepWaitTasks) { waitTaskModel.Status = 0; waitTaskModel.ExecuteType = 0; updateTasks.Add(waitTaskModel); } #endregion int stepSort = 1; foreach (var receiveUser in receiveUsers) { //判断下一步待办中没有当前接收人的待办才添加,条件currentStep.StepBase.HanlderModel != 3为独立处理不判断 //&& nextStpe.StepBase.HanlderModel != 3 2021-2-18增加,下一步是独立处理也不判断。 //&& currentStep.StepBase.HanlderModelGroup == 0 当前步骤有分组也不判断 if (currentStep.StepBase.HanlderModelGroup == 0 && currentStep.StepBase.HanlderModel != 3 && nextStpe.StepBase.HanlderModel != 3 && (addTasks.Exists(p => p.ReceiveId == receiveUser.Id && p.StepId == nextStpe.Id.ToString()) || groupTasks.Exists(p => p.ReceiveId == receiveUser.Id && p.StepId == nextStpe.Id.ToString() && p.Status != 2)) ) { continue; } Model.rf_flowtask task = new Model.rf_flowtask { ExecuteType = stepSort == 1 ? 0 : -1, FlowId = executeModel.FlowId.ToString(), FlowName = flowRunModel.Name, GroupId = currentTask.GroupId, Id = GuidExtensions.NewGuid().ToString(), InstanceId = executeModel.InstanceId, IsSign = 0, OtherType = executeModel.OtherType, PrevId = currentTask.Id, PrevStepId = currentTask.StepId, ReceiveId = receiveUser.Id, ReceiveName = receiveUser.Name, ReceiveTime = DateExtensions.Now, SenderId = executeModel.Sender.Id, SenderName = executeModel.Sender.Name, Sort = currentTask.Sort + 1, Status = stepSort == 1 ? 0 : -1, StepId = stepId.ToString(), StepName = stepName.IsNullOrWhiteSpace() ? nextStpe.Name : stepName.Trim(), StepSort = nextStpe.StepBase.HanlderModel == 4 ? stepSort++ : stepSort, //2019-12-1修改 增加自由发送TaskType为10 TaskType = executeModel.ExecuteType == Model.FlowRunModel.Execute.Type.FreeSubmit ? 10 : 0, Title = executeModel.Title, IsAutoSubmit = nextStpe.ExpiredExecuteModel, CompletedTime = completedTime1, RemindTime = remindTime, IsBatch = nextStpe.BatchExecute }; /* if (receiveUser.PartTimeId.IsNotEmptyGuid()) { task.ReceiveOrganizeId = receiveUser.PartTimeId; } if (receiveUser.Note.IsGuid(out Guid entuustId) && entuustId.IsNotEmptyGuid())//用人员实体的NOTE字段来存放委托人ID { task.EntrustUserId = receiveUser.Note; //task.TaskType = 2; task.Note = localizer == null ? "委托" : localizer["Execute_SubmitTaskNoteEntrust"].Value; }*/ if (nextStpe.DataEditModel == 1)//独立编辑这里不继承上一步实例ID { if (currentTask.TaskType == 4)//如果是退回又提交要查找退回前的实例ID { var backTask = groupTasks.Find(p => p.StepId == nextStpe.Id.ToString() && p.ReceiveId == receiveUser.Id); task.InstanceId = backTask?.InstanceId; } else { task.InstanceId = null; } } if (beforeStepId.IsNotEmptyGuid()) { task.BeforeStepId = beforeStepId.Value.ToString(); } //2021-3-25增加用OtherType字段来保存策略人员分组 if (nextStpe.StepBase.HanlderModelGroup == 1)//按发送人分组 { var otherTypeTasks = groupTasks.Where(p => p.OtherType.ToString().StartsWith('3')); int maxGroupInt = otherTypeTasks.Any() ? otherTypeTasks.Max(p => p.OtherType) + 1 : 31; if (!maxGroupInt.ToString().StartsWith('3')) { maxGroupInt = ("3" + maxGroupInt.ToString()).ToInt(); } task.OtherType = maxGroupInt; } else if (nextStpe.StepBase.HanlderModelGroup == 2)//按接收人分组 { /* if (receiveUser.QQ.IsInt(out int groupInt)) { task.OtherType = groupInt; }*/ } //2021-3-25增加完 addTasks.Add(task); executeResult.NextTasks.Add(task); } #region 步骤接收时抄送 if (nextStpe.StepCopyFor.CopyforTime == 0) { var copyForUsers = GetCopyForUsers(nextStpe, flowRunModel, executeModel, groupTasks); foreach (var copyForUser in copyForUsers) { //判断下一步待办中没有当前接收人的待办才添加 if (addTasks.Exists(p => p.ReceiveId == copyForUser.Id && p.StepId == nextStpe.Id.ToString()) || groupTasks.Exists(p => p.ReceiveId == copyForUser.Id && p.StepId == nextStpe.Id.ToString() && p.Sort == currentTask.Sort + 1)) { continue; } Model.rf_flowtask task = new Model.rf_flowtask { ExecuteType = 0, FlowId = executeModel.FlowId.ToString(), FlowName = flowRunModel.Name, GroupId = currentTask.GroupId, Id = GuidExtensions.NewGuid().ToString(), InstanceId = executeModel.InstanceId, IsSign = 0, Note = localizer == null ? "抄送" : localizer["Execute_SubmitTaskNoteCopyfor"].Value, OtherType = executeModel.OtherType, PrevId = currentTask.Id, PrevStepId = currentTask.StepId, ReceiveId = copyForUser.Id, ReceiveName = copyForUser.Name, ReceiveTime = DateExtensions.Now, SenderId = executeModel.Sender.Id, SenderName = executeModel.Sender.Name, Sort = currentTask.Sort + 1, Status = 0, StepId = stepId.ToString(), StepName = nextStpe.Name, StepSort = 1, TaskType = 5, Title = executeModel.Title, IsAutoSubmit = 0, IsBatch = nextStpe.BatchExecute }; addTasks.Add(task); executeResult.NextTasks.Add(task); } } #endregion } #region 步骤完成时抄送 if (currentStep.StepCopyFor.CopyforTime == 1) { var copyForUsers = GetCopyForUsers(currentStep, flowRunModel, executeModel, groupTasks); foreach (var copyForUser in copyForUsers) { //判断当前步骤待办中没有当前接收人的待办才添加 if (groupTasks.Exists(p => p.ReceiveId == copyForUser.Id && p.StepId == currentStep.Id.ToString())) { continue; } Model.rf_flowtask task = new Model.rf_flowtask { ExecuteType = 0, FlowId = executeModel.FlowId.ToString(), FlowName = flowRunModel.Name, GroupId = currentTask.GroupId, Id = GuidExtensions.NewGuid().ToString(), InstanceId = executeModel.InstanceId, IsSign = 0, Note = localizer == null ? "抄送" : localizer["Execute_SubmitTaskNoteCopyfor"].Value, OtherType = executeModel.OtherType, PrevId = currentTask.PrevId, PrevStepId = currentTask.PrevStepId, ReceiveId = copyForUser.Id, ReceiveName = copyForUser.Name, ReceiveTime = DateExtensions.Now, SenderId = executeModel.Sender.Id, SenderName = executeModel.Sender.Name, Sort = currentTask.Sort, Status = 0, StepId = currentStep.Id.ToString(), StepName = currentStep.Name, StepSort = 1, TaskType = 5, Title = executeModel.Title, IsAutoSubmit = 0, IsBatch = currentStep.BatchExecute }; addTasks.Add(task); //2020-6-2启用了下面一行,不然不会给抄送人的发消息。 executeResult.NextTasks.Add(task); } } #endregion #region 步骤通过后SQL if (!currentStep.StepEvent.SubmitPassAfter.IsNullOrWhiteSpace() && currentStep.StepEvent.SubmitPassAfter.Trim().StartsWith("[sql]")) { object[] objects = new object[] { currentTask.Id, currentTask.InstanceId, currentTask.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(currentStep.StepEvent.SubmitPassAfter.Trim(), null, executeModel).TrimStart("[sql]".ToCharArray()), objects, 1)); } #endregion } else { #region 如果步骤没有通过,则添加下一步等待任务,2021-9-10增加,解决会签时只记录了最后一个人发送到下一步的任务问题。 foreach (var (stepId, stepName, beforeStepId, parallelorserial, receiveUsers, completedTime) in executeModel.Steps) { int stepSort = 1; foreach (var receiveUser in receiveUsers) { var nextStpe = flowRunModel.Steps.Find(p => p.Id == stepId); if (null == nextStpe) { continue; } //判断下一步待办中没有当前接收人的待办才添加,条件currentStep.StepBase.HanlderModel != 3为独立处理不判断 //&& nextStpe.StepBase.HanlderModel != 3 2021-2-18增加,下一步是独立处理也不判断。 //&& currentStep.StepBase.HanlderModelGroup == 0 当前步骤有分组也不判断 if (currentStep.StepBase.HanlderModelGroup == 0 && currentStep.StepBase.HanlderModel != 3 && nextStpe.StepBase.HanlderModel != 3 && (addTasks.Exists(p => p.ReceiveId == receiveUser.Id && p.StepId == nextStpe.Id.ToString()) || groupTasks.Exists(p => p.ReceiveId == receiveUser.Id && p.StepId == nextStpe.Id.ToString() && p.Status != 2)) ) { continue; } Model.rf_flowtask task = new Model.rf_flowtask { ExecuteType = -1, FlowId = executeModel.FlowId.ToString(), FlowName = flowRunModel.Name, GroupId = currentTask.GroupId, Id = GuidExtensions.NewGuid().ToString(), InstanceId = executeModel.InstanceId, IsSign = 0, OtherType = executeModel.OtherType, PrevId = currentTask.Id, PrevStepId = currentTask.StepId, ReceiveId = receiveUser.Id, ReceiveName = receiveUser.Name, ReceiveTime = DateExtensions.Now, SenderId = executeModel.Sender.Id, SenderName = executeModel.Sender.Name, Sort = currentTask.Sort + 1, Status = -1, StepId = stepId.ToString(), StepName = stepName.IsNullOrWhiteSpace() ? nextStpe.Name : stepName.Trim(), StepSort = nextStpe.StepBase.HanlderModel == 4 ? stepSort++ : stepSort, //2019-12-1修改 增加自由发送TaskType为10 TaskType = executeModel.ExecuteType == Model.FlowRunModel.Execute.Type.FreeSubmit ? 10 : 0, Title = executeModel.Title, IsAutoSubmit = nextStpe.ExpiredExecuteModel, CompletedTime = null, RemindTime = null, IsBatch = nextStpe.BatchExecute }; /* if (receiveUser.PartTimeId.IsNotEmptyGuid()) { task.ReceiveOrganizeId = receiveUser.PartTimeId; } if (receiveUser.Note.IsGuid(out Guid entuustId) && entuustId.IsNotEmptyGuid())//用人员实体的NOTE字段来存放委托人ID { task.EntrustUserId = entuustId.ToString(); //task.TaskType = 2; task.Note = localizer == null ? "委托" : localizer["Execute_SubmitTaskNoteEntrust"].Value; } */ if (nextStpe.DataEditModel == 1)//独立编辑这里不继承上一步实例ID { if (currentTask.TaskType == 4)//如果是退回又提交要查找退回前的实例ID { var backTask = groupTasks.Find(p => p.StepId == nextStpe.Id.ToString() && p.ReceiveId == receiveUser.Id); task.InstanceId = backTask?.InstanceId; } else { task.InstanceId = null; } } if (beforeStepId.IsNotEmptyGuid()) { task.BeforeStepId = beforeStepId.Value.ToString(); } //2021-3-25增加用OtherType字段来保存策略人员分组 if (nextStpe.StepBase.HanlderModelGroup == 1)//按发送人分组 { var otherTypeTasks = groupTasks.Where(p => p.OtherType.ToString().StartsWith('3')); int maxGroupInt = otherTypeTasks.Any() ? otherTypeTasks.Max(p => p.OtherType) + 1 : 31; if (!maxGroupInt.ToString().StartsWith('3')) { maxGroupInt = ("3" + maxGroupInt.ToString()).ToInt(); } task.OtherType = maxGroupInt; } else if (nextStpe.StepBase.HanlderModelGroup == 2)//按接收人分组 { /* if (receiveUser.QQ.IsInt(out int groupInt)) { task.OtherType = groupInt; }*/ } //2021-3-25增加完 addTasks.Add(task); //executeResult.NextTasks.Add(task); } } #endregion } executeResult.IsSuccess = true; #endregion #region 判断整个流程是否完成 //2020-2-11 修改Exists(p => p.TaskType != 5),排除步骤提交后抄送的任务 bool flowInstanceIsCompleted = currentStepIsPass && !addTasks.Exists(p => p.TaskType != 5 && p.TaskType != 11);//当前步骤通过,并且没有新增的任务 if (flowInstanceIsCompleted) { foreach (var task in groupTasks) { if (task.Status != 2 && task.TaskType != 5 && task.TaskType != 11) { var upTask = updateTasks.Find(p => p.Id == task.Id); if (upTask == null || upTask.Status != 2) { var delTask = removeTasks.Find(p => p.Id == task.Id); if (delTask == null) { flowInstanceIsCompleted = false; break; } } } } } #region 如果是子流程任务,检查主流程是否需要自动提交 if (flowInstanceIsCompleted) { var firstTask = groupTasks.Find(p => p.PrevId == string.Empty && p.PrevStepId == string.Empty && p.StepId == flowRunModel.FirstStepId.ToString()); if (null != firstTask && firstTask.OtherType == 1) { var mainTasks = GetListBySubFlowGroupId(firstTask.GroupId); if (mainTasks.Count > 0) { var mainFlowRunModel = new Flow().GetFlowRunModel(mainTasks.First().FlowId); if (null != mainFlowRunModel) { var mainStepModel = mainFlowRunModel.Steps.Find(p => p.Id == mainTasks.First().StepId.ToGuid()); //如果主流程步骤设置为子流程完成后自动提交,则在这里提交主流程步骤 if (null != mainStepModel && mainStepModel.StepSubFlow.SubFlowStrategy == 2) { executeResult.AutoSubmitTasks.AddRange(mainTasks); } //执行子流程完成后事件 if (null != mainStepModel && !mainStepModel.StepEvent.SubFlowCompletedBefore.IsNullOrWhiteSpace()) { Model.FlowRunModel.EventParam subFlowEeventParam = new Model.FlowRunModel.EventParam(); subFlowEeventParam.FlowId = mainTasks.First().FlowId.ToGuid(); subFlowEeventParam.GroupId = mainTasks.First().GroupId.ToGuid(); subFlowEeventParam.InstanceId = mainTasks.First().InstanceId; subFlowEeventParam.StepId = mainTasks.First().StepId.ToGuid(); subFlowEeventParam.TaskId = mainTasks.First().Id.ToGuid(); subFlowEeventParam.TaskTitle = mainTasks.First().Title; var (eventReturn, err) = Tools.ExecuteMethod(mainStepModel.StepEvent.SubFlowCompletedBefore.Trim(), subFlowEeventParam); if (null != err) { _log.Add("执行子流程完成后事件发生了错误-" + mainFlowRunModel.Name + "-" + mainStepModel.Name + "-" + mainStepModel.StepEvent.SubFlowCompletedBefore, _userManager.UserId, "参数:" + subFlowEeventParam.ToString() + " 错误:" + err.Message + err.StackTrace + err.Source, LogType.流程运行); } } } } } } #endregion //2020-4-3新增判断,如果流程只有一步则直接标记为已完成 if (!flowInstanceIsCompleted && flowRunModel.Steps.Count == 1) { flowInstanceIsCompleted = true; } #region 更新完成标识 if (flowInstanceIsCompleted) { Guid connId = flowRunModel.TitleField.ConnectionId; string titleField = flowRunModel.TitleField.Field; string table = flowRunModel.TitleField.Table; string value = flowRunModel.TitleField.Value; var connModel = new DbConnection().GetOneById(connId.ToString()); if (null != connModel && !titleField.IsNullOrWhiteSpace() && !table.IsNullOrWhiteSpace()) { //这里检查一下,如果标识字段设置成了主键则不更新 var dbFirst = flowRunModel.Databases.Any() ? flowRunModel.Databases.First() : null; string table1 = string.Empty, primaryKey = string.Empty; if (dbFirst != null) { table1 = dbFirst.Table; primaryKey = dbFirst.PrimaryKey; } if (table1.EqualsIgnoreCase(table) && !primaryKey.EqualsIgnoreCase(titleField)) { string sql = "UPDATE " + table + " SET " + titleField + "={0} WHERE " + primaryKey + "={1}"; object[] parameteres = new object[] { value.IsNullOrEmpty() ? "1" : value, currentTask.InstanceId }; if (connModel.ConnString.EqualsIgnoreCase(Config.ConnectionString))//如果是使用的系统连接,则采用事务更新 { executeSqls.Add((sql, parameteres, 1)); } else { new DbConnection().executeSqlByConnection(connModel, sql, parameteres); /* using (var db = new Mapper.DataContext(connModel.ConnType, connModel.ConnString)) { db.Execute(sql, parameteres); db.SaveChanges(); }*/ } } } //移出动态步骤缓存(表rf_flowdynamic的缓存) foreach (var dynamicStep in groupTasks.Where(p => p.BeforeStepId.IsNotEmptyGuid())) { _memoryCache.Remove(new Flow().getCacheKey() + "_" + dynamicStep.BeforeStepId + "_" + dynamicStep.GroupId); } #region 流程完成后SQL if (!flowRunModel.TitleField.EventCompleted.IsNullOrWhiteSpace() && flowRunModel.TitleField.EventCompleted.Trim().StartsWith("[sql]")) { object[] objects = new object[] { currentTask.Id, currentTask.InstanceId, currentTask.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(flowRunModel.TitleField.EventCompleted.Trim(), null, executeModel).TrimStart("[sql]".ToCharArray()), objects, 2));// 0提交前SQL 1提交后SQL 2完成后SQL 3终止后SQL } #endregion } #endregion executeResult.StepIsPass = currentStepIsPass; executeResult.FlowIsCompleted = flowInstanceIsCompleted; #endregion } /// /// 退回任务 /// /// /// /// 语言包 public void Back(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { List groupTasks = GetListByGroupId(executeModel.GroupId.ToString()); Model.rf_flowtask currentTask = groupTasks.Find(p => p.Id == executeModel.TaskId.ToString()); if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } if (currentTask.ReceiveId != executeModel.Sender.Id) { executeResult.DebugMessages = localizer == null ? "当前任务接收人不属于当前用户" : localizer["Execute_SubmitCurrentTaskReceiveUserError"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "您不能处理当前任务" : localizer["Execute_SubmitCurrentTaskCanotProcess"].Value; return; } var currentStep = flowRunModel.Steps.Find(p => p.Id == currentTask.StepId.ToGuid()); if (null == currentStep) { executeResult.DebugMessages = localizer == null ? "未找到当前步骤运行时" : localizer["Execute_NotFoundStepRunModel"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "未找到当前步骤运行时" : localizer["Execute_NotFoundStepRunModel"].Value; return; } executeResult.CurrentTask = currentTask; if (executeModel.Title.IsNullOrWhiteSpace()) { executeModel.Title = currentTask.Title; } if (currentTask.OtherType == 1)//如果是子流程任务,这里要赋值,后续任务也要设置为1 { executeModel.OtherType = 1; } bool isBackPass = true;//步骤退回是否通过 int backModel = currentStep.StepBase.BackModel; int maxSort = groupTasks.FindAll(p => p.StepId == currentTask.StepId).Max(p => p.Sort); //2021-3-27增加,如果设置了处理策略分组,这里要按分组过滤 var levelTasks = currentStep.StepBase.HanlderModelGroup > 0 ? groupTasks.FindAll(p => p.StepId == currentTask.StepId && p.Sort == currentTask.Sort && p.TaskType != 5 && p.TaskType != 11 && p.OtherType == currentTask.OtherType) : groupTasks.FindAll(p => p.StepId == currentTask.StepId && p.Sort == maxSort && p.TaskType != 5 && p.TaskType != 11);//当前任务的同级任务 if (backModel == 1) { int handlerType = currentStep.StepBase.HanlderModel; switch (handlerType) { case 0://所有人必须处理 backModel = 2;//所有人必须同意,只要有一个人退回就表示不同意,相当于一人退回全部退回 break; case 1://一人同意即可 backModel = 3;//一人同意即可,则要所有人都退回才退回,相当于所有人退回才退回 break; case 2://依据人数比例 backModel = 5; break; case 3://独立处理 backModel = 4;//独立处理相当于独立退回 break; case 4://选择人员顺序处理 backModel = 6; break; } } //加签退回要从加签时选择中读取策略 if (currentTask.TaskType.In(6, 7)) { char[] otherType = currentTask.OtherType.ToString().ToCharArray(); if (otherType.Length == 3) { int executeType = otherType[2].ToString().ToInt(); ;//处理类型 1所有人同意,2一个同意 3顺序处理 if (executeType == 1) { backModel = 2; } else if (executeType == 2) { backModel = 3; } else if (executeType == 3) { backModel = 2; //backModel = 6; } } } switch (backModel) { case 0: executeResult.DebugMessages = localizer == null ? "当前步骤设置为不能退回" : localizer["Execute_BackCannotBack"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前步骤设置为不能退回" : localizer["Execute_BackCannotBack"].Value; return; case 1://根据处理策略退回 break; case 2://一人退回全部退回 foreach (var task in levelTasks) { if (task.Id == currentTask.Id || task.Status == 2) { continue; } var updateTask = task.Clone(); updateTask.ExecuteType = 5; updateTask.Status = 2; updateTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(updateTask); } break; case 3://所有人退回才退回 isBackPass = !levelTasks.Exists(p => p.Status != 2 && p.Id != currentTask.Id); break; case 4://独立退回 break; case 5://依据人数比例退回 decimal percentage = currentStep.StepBase.Percentage; isBackPass = ((levelTasks.Count(p => p.Status == 2 && p.ExecuteType == 3) + 1) / levelTasks.Count) * 100 >= percentage; if (isBackPass) { foreach (var task in levelTasks.FindAll(p => p.Status != 2 && p.Id != currentTask.Id)) { var updateTask = task.Clone(); updateTask.ExecuteType = 5; updateTask.Status = 2; updateTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(updateTask); } } break; case 6://选择人员顺序退回 if (currentTask.StepSort == 1) { } else { var prevTask = levelTasks.Find(p => p.StepSort == currentTask.StepSort - 1); if (null != prevTask) { var updateTask = prevTask.Clone(); updateTask.ExecuteType = 0; updateTask.Status = 0; updateTask.CompletedTime1 = null; updateTask.Note = currentTask.ReceiveName + (localizer == null ? "退回" : localizer["Execute_BackBack"].Value); updateTask.Comments = ""; updateTask.IsSign = 0; updateTask.OpenTime = null; updateTasks.Add(updateTask); executeResult.NextTasks.Add(updateTask); } isBackPass = false; } break; } //更新当前任务 var updateCurrentTask = currentTask.Clone(); updateCurrentTask.ExecuteType = 3; updateCurrentTask.Status = 2; updateCurrentTask.Comments = executeModel.Comment; updateCurrentTask.IsSign = executeModel.IsSign; updateCurrentTask.CompletedTime1 = DateExtensions.Now; updateCurrentTask.Attachment = executeModel.Attachment; updateTasks.Add(updateCurrentTask); if (isBackPass)//如果步骤退回通过,给退回接收人增加待办 { //如果是选择人员顺序处理,则要将当前任务后面为等待中的任务删除 if (currentStep.StepBase.HanlderModel == 4 && currentTask.StepSort == 1) { var currentTasks = groupTasks.FindAll(p => p.StepId == currentStep.Id.ToString()); if (currentTasks.Count > 0) { int currentMaxSort = currentTasks.Max(p => p.Sort); var currentTasks1 = currentTasks.FindAll(p => p.Sort == currentMaxSort && p.Id != currentTask.Id && p.Status < 2); foreach (var task in currentTasks1) { var removeTask = task.Clone(); removeTasks.Add(removeTask); } } } foreach (var (stepId, stepName, dynamicStepId, parallelorserial, receiveUsers, completedTime) in executeModel.Steps) { var nextStep = flowRunModel.Steps.Find(p => p.Id == stepId); if (null == nextStep) { continue; } if (nextStep.StepBase.HanlderModel == 4) { var nextStepTasks = groupTasks.FindAll(p => p.StepId == nextStep.Id.ToString() && p.TaskType != 5 && p.TaskType != 11); if (nextStepTasks.Count > 0) { int maxSort1 = nextStepTasks.Max(p => p.Sort); var nextStepTasks1 = nextStepTasks.FindAll(p => p.Sort == maxSort1).OrderByDescending(p => p.StepSort); foreach (var nextStepTask in nextStepTasks1) { var addTask = nextStepTask.Clone(); addTask.Id = GuidExtensions.NewGuid().ToString(); addTask.Title = executeModel.Title.IsNullOrWhiteSpace() ? currentTask.Title : executeModel.Title; addTask.ExecuteType = 0; addTask.Status = nextStepTask.Id == nextStepTasks1.First().Id ? 0 : -1; addTask.ExecuteType = addTask.Status; addTask.CompletedTime1 = null; addTask.Comments = ""; addTask.IsSign = 0; addTask.OpenTime = null; addTask.Note = localizer == null ? "退回" : localizer["Execute_BackBack"].Value; addTask.Sort = currentTask.Sort + 1; addTask.SenderId = currentTask.ReceiveId; addTask.SenderName = currentTask.ReceiveName; addTask.ReceiveTime = DateExtensions.Now; addTask.PrevId = currentTask.Id; addTask.PrevStepId = currentTask.StepId; addTask.OtherType = executeModel.OtherType; addTask.SubFlowGroupId = nextStepTask.SubFlowGroupId; addTask.TaskType = 4; addTask.CompletedTime = new DateTime?(); addTask.RemindTime = new DateTime?(); addTasks.Add(addTask); executeResult.NextTasks.Add(addTask); } } continue; } int stepSort = 1; foreach (var receiveUser in receiveUsers) { //判断下一步待办中没有当前接收人的待办才添加 if (addTasks.Exists(p => p.ReceiveId == receiveUser.Id && p.StepId == nextStep.Id.ToString()) || groupTasks.Exists(p => p.ReceiveId == receiveUser.Id && p.StepId == nextStep.Id.ToString() && p.Status != 2)) { continue; } //查找退回步骤的原始待办,确定subgroupid,子流程的情况 //2021-3-26注释了下面一行,修改成下面两行。 //var oldTask = groupTasks.Find(p => p.StepId == stepId && p.ReceiveId == receiveUser.Id && p.Sort == currentTask.Sort - 1); var oldTaskMaxSort = groupTasks.Where(p => p.StepId == stepId.ToString()).Max(p => p.Sort); var oldTask = groupTasks.Find(p => p.StepId == stepId.ToString() && p.ReceiveId == receiveUser.Id && p.Sort == oldTaskMaxSort); string subFlowGroupId = null != oldTask ? oldTask.SubFlowGroupId : string.Empty; //设置完成时间 DateTime? completedTime1 = completedTime; DateTime? remindTime = new DateTime?();//提醒时间(如果任务设置了超期提示) WorkDate workDate = new WorkDate(); if (!completedTime1.HasValue && nextStep.WorkTime > 0) { completedTime1 = workDate.GetWorkDateTime((double)nextStep.WorkTime); } if (completedTime1.HasValue && nextStep.ExpiredPrompt > 0) { remindTime = workDate.GetWorkDateTime((double)(nextStep.ExpiredPromptDays - nextStep.ExpiredPromptDays * 2), completedTime1); } Model.rf_flowtask task = new Model.rf_flowtask { ExecuteType = 0, FlowId = executeModel.FlowId.ToString(), FlowName = flowRunModel.Name, GroupId = currentTask.GroupId, Id = GuidExtensions.NewGuid().ToString(), InstanceId = oldTask != null ? oldTask.InstanceId : executeModel.InstanceId, IsSign = 0, OtherType = oldTask != null ? oldTask.OtherType : executeModel.OtherType, Note = localizer == null ? "退回" : localizer["Execute_BackBack"].Value, PrevId = currentTask.Id, PrevStepId = currentTask.StepId, ReceiveId = receiveUser.Id, ReceiveName = receiveUser.Name, ReceiveTime = DateExtensions.Now, SenderId = currentTask.ReceiveId, SenderName = currentTask.ReceiveName, Sort = currentTask.Sort + 1, Status = 0, StepId = stepId.ToString(), StepName = nextStep.Name, StepSort = stepSort, TaskType = 4, Title = executeModel.Title, IsAutoSubmit = nextStep.ExpiredExecuteModel, SubFlowGroupId = subFlowGroupId, BeforeStepId = oldTask != null ? oldTask.BeforeStepId : GuidExtensions.NewGuid().ToString(), CompletedTime = completedTime1, RemindTime = remindTime, IsBatch = nextStep.BatchExecute }; /* if (!receiveUser.PartTimeId.IsNullOrWhiteSpace()) { task.ReceiveOrganizeId = receiveUser.PartTimeId; } if (receiveUser.Note.IsGuid(out Guid entuustId))//用人员实体的NOTE字段来存放委托人ID { task.EntrustUserId = receiveUser.Note; //task.TaskType = 2; task.Note = localizer == null ? "委托" : localizer["Execute_SubmitTaskNoteEntrust"].Value; }*/ addTasks.Add(task); executeResult.NextTasks.Add(task); } } #region 步骤退回通过后SQL if (!currentStep.StepEvent.BackPassAfter.IsNullOrWhiteSpace() && currentStep.StepEvent.BackPassAfter.Trim().StartsWith("[sql]")) { object[] objects = new object[] { currentTask.Id, currentTask.InstanceId, currentTask.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(currentStep.StepEvent.BackPassAfter.Trim(), null, executeModel).TrimStart("[sql]".ToCharArray()), objects, 1)); } #endregion } executeResult.StepIsBack = isBackPass; executeResult.IsSuccess = true; } /// /// 保存任务 /// /// /// /// 语言包 public void Save(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { //如果是第一步提交并且没有实例则先创建实例 bool isFirstTask = executeModel.StepId == flowRunModel.FirstStepId && executeModel.TaskId.IsEmptyGuid(); if (isFirstTask) { var currentTask = GetFirstTask(flowRunModel, executeModel); addTasks.Add(currentTask); executeResult.NextTasks.Add(currentTask); executeResult.CurrentTask = currentTask; } else { var currentTask = GetOneById(executeModel.TaskId.ToString()); if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } if (!executeModel.Title.IsNullOrWhiteSpace()) { currentTask.Title = executeModel.Title;//更新标题 } currentTask.InstanceId = executeModel.InstanceId; currentTask.Comments = executeModel.Comment; currentTask.Attachment = executeModel.Attachment; currentTask.IsSign = executeModel.IsSign; updateTasks.Add(currentTask); executeResult.NextTasks.Add(currentTask); executeResult.CurrentTask = currentTask; } executeResult.IsSuccess = true; } /// /// 转交任务 /// /// 当前任务 /// 要转交的人员 /// 语言包 public void Redirect(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { var groupTasks = GetListByGroupId(executeModel.GroupId.ToString()); var currentTask = groupTasks.Find(p => p.Id == executeModel.TaskId.ToString()); if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } if (executeModel.Steps.Count == 0 || executeModel.Steps.First().receiveUsers.Count == 0) { executeResult.DebugMessages = localizer == null ? "要转交的步骤或接收人员为空" : localizer["Execute_RedirectStepReceiverEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "接收人员为空" : localizer["Execute_RedirectReceiverEmpty"].Value; return; } currentTask.ExecuteType = 6; currentTask.Status = 2; currentTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(currentTask); executeResult.CurrentTask = currentTask; FlowEntrust flowEntrust = new FlowEntrust(); User buser = new User(); var receiveUsers = executeModel.Steps.First().receiveUsers; for (int i = 0; i < receiveUsers.Count; i++) { var user = receiveUsers[i]; #region 判断委托 //流程处理时已经判断了委托,这里注释掉。 //string entrustId = flowEntrust.GetEntrustUserId(currentTask.FlowId, user); //bool isEntrust = !entrustId.IsNullOrWhiteSpace(); //if (isEntrust) //{ // var entrustUser = buser.Get(entrustId); // if (null != entrustUser) // { // var entrustUser1 = entrustUser.Clone(); // entrustUser1.Note = user.Id.ToString();//用这个字段来保存委托人ID,在加入任务表的时候要用到 // user = entrustUser1; // } //} #endregion //判断下一步待办中没有当前接收人的待办才添加 if (addTasks.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.TaskType != 5 && p.TaskType != 11) || groupTasks.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.Status != 2 && p.TaskType != 5 && p.TaskType != 11)) { continue; } Model.rf_flowtask task = currentTask.Clone(); task.Id = GuidExtensions.NewGuid().ToString(); task.SenderId = currentTask.ReceiveId; task.SenderName = currentTask.ReceiveName; task.ExecuteType = 0; task.Status = 0; task.Comments = ""; task.TaskType = 3;//2019-12-1新增 task.PrevId = currentTask.Id;//2019-12-1新增 task.IsSign = 0; task.ReceiveName = user.Name; task.ReceiveId = user.Id; task.CompletedTime1 = null; task.ReceiveTime = DateExtensions.Now; task.Note = localizer == null ? "转交" : localizer["Execute_Redirect"].Value; /* if (!user.PartTimeId.IsNullOrWhiteSpace()) { task.ReceiveOrganizeId = user.PartTimeId; } if (user.Note.IsGuid(out Guid entuustId))//用人员实体的NOTE字段来存放委托人ID { task.EntrustUserId = user.Note; }*/ addTasks.Add(task); executeResult.NextTasks.Add(task); } executeResult.IsSuccess = true; } /// /// 已阅知(抄送完成) /// /// /// /// 语言包 public void CopyForCompleted(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { var currentTask = GetOneById(executeModel.TaskId.ToString()); if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } currentTask.ExecuteType = 8; currentTask.Status = 2; currentTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(currentTask); executeResult.IsSuccess = true; } /// /// 终止任务 /// /// /// public void TaskEnd(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { var groupTasks = GetListByGroupId(executeModel.GroupId.ToString()); var currentTask = groupTasks.Find(p => p.Id == executeModel.TaskId.ToString()); if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } executeResult.CurrentTask = currentTask; //终止当前实例未完成的任务 var tasks = groupTasks.FindAll(p => p.Status < 2); foreach (var task in tasks) { var updateTask = task.Clone(); updateTask.ExecuteType = 12; updateTask.Status = 2; if (updateTask.Id == currentTask.Id) { updateTask.Comments = executeModel.Comment; updateTask.IsSign = executeModel.IsSign; updateTask.ExecuteType = 11; } updateTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(updateTask); } executeResult.IsSuccess = true; executeResult.FlowIsStop = true; #region 流程终止后SQL if (!flowRunModel.TitleField.EventStop.IsNullOrWhiteSpace() && flowRunModel.TitleField.EventStop.Trim().StartsWith("[sql]")) { object[] objects = new object[] { currentTask.Id, currentTask.InstanceId, currentTask.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(flowRunModel.TitleField.EventStop.Trim(), null, executeModel).TrimStart("[sql]".ToCharArray()), objects, 3));// 0提交前SQL 1提交后SQL 2完成后SQL 3终止后SQL } #endregion executeResult.Messages = localizer == null ? "已终止!" : localizer["Execute_TaskEnd"].Value; } /// /// 加签 /// /// /// /// 语言包 /// public void AddWrite(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { JObject jObject = null; try { jObject = JObject.Parse(executeModel.ParamsJSON); } catch { } if (null == jObject) { executeResult.Messages = localizer == null ? "加签参数错误!" : localizer["Execute_AddWriteParamsError"].Value; executeResult.DebugMessages = executeResult.Messages; executeResult.IsSuccess = false; return; } JObject jObject1 = jObject.Value("addwrite"); int addType = int.MinValue; int writeType = int.MinValue; string member = string.Empty; if (null != jObject1) { addType = jObject1.Value("addtype").ToInt(); writeType = jObject1.Value("writetype").ToInt(); member = jObject1.Value("member"); } if (addType == int.MinValue || writeType == int.MinValue || member.IsNullOrWhiteSpace()) { executeResult.Messages = localizer == null ? "加签参数错误!" : localizer["Execute_AddWriteParamsError"].Value; executeResult.DebugMessages = executeResult.Messages; executeResult.IsSuccess = false; return; } var currentTask = GetOneById(executeModel.TaskId.ToString()); if (null == currentTask) { executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.DebugMessages = executeResult.Messages; executeResult.IsSuccess = false; return; } if (currentTask.Status == 2) { executeResult.Messages = localizer == null ? "当前任务已完成,不能加签!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.DebugMessages = executeResult.Messages; executeResult.IsSuccess = false; return; } var users = new Organize().GetAllUsers(member); if (!users.Any()) { executeResult.Messages = localizer == null ? "没有接收人" : localizer["Execute_RedirectReceiverEmpty"].Value; executeResult.DebugMessages = executeResult.Messages; executeResult.IsSuccess = false; return; } FlowEntrust flowEntrust = new FlowEntrust(); User buser = new User(); int stepSort = 1; string stepName = currentTask.StepName + "(" + (addType == 1 ? (localizer == null ? "前加签" : localizer["Execute_AddWriteBefore"].Value) : addType == 2 ? (localizer == null ? "后加签" : localizer["Execute_AddWriteAfter"].Value) : (localizer == null ? "并签" : localizer["Execute_AddWriteAnd"].Value)) + ")"; var groupTasks = GetListByGroupId(currentTask.GroupId); for (int i = 0; i < users.Count; i++) { var user = users[i]; int sort = addType == 3 ? currentTask.Sort : currentTask.Sort + 1; //判断下一步待办中没有当前接收人的待办才添加 if (addTasks.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.Sort == sort && p.TaskType != 5 && p.TaskType != 11) || groupTasks.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.Status != 2 && p.TaskType != 5 && p.TaskType != 11)) { continue; } Model.rf_flowtask flowTaskModel = new Model.rf_flowtask(); /*if (user.Note.IsGuid(out Guid eId)) { flowTaskModel.EntrustUserId = user.Note; }*/ flowTaskModel.ExecuteType = 0; flowTaskModel.FlowId = currentTask.FlowId; flowTaskModel.FlowName = currentTask.FlowName; flowTaskModel.GroupId = currentTask.GroupId; flowTaskModel.Id = GuidExtensions.NewGuid().ToString(); flowTaskModel.InstanceId = currentTask.InstanceId; flowTaskModel.IsAutoSubmit = 0; //flowTaskModel.Note = ""; flowTaskModel.OtherType = ("1" + addType.ToString() + writeType.ToString()).ToInt(); flowTaskModel.PrevId = currentTask.Id; flowTaskModel.PrevStepId = currentTask.StepId; flowTaskModel.ReceiveId = user.Id; flowTaskModel.ReceiveName = user.Name; flowTaskModel.ReceiveOrganizeId = "";// user.PartTimeId; flowTaskModel.ReceiveTime = DateExtensions.Now; flowTaskModel.SenderId = currentTask.ReceiveId; flowTaskModel.SenderName = currentTask.ReceiveName; flowTaskModel.Sort = sort; flowTaskModel.Status = stepSort == 1 ? 0 : -1; flowTaskModel.ExecuteType = flowTaskModel.Status; flowTaskModel.StepId = currentTask.StepId; flowTaskModel.StepName = stepName; flowTaskModel.StepSort = addType == 3 ? 1 : writeType == 3 ? stepSort++ : 1;//并签不能按顺序处理 flowTaskModel.TaskType = 5 + addType; flowTaskModel.Title = currentTask.Title; flowTaskModel.IsBatch = currentTask.IsBatch; addTasks.Add(flowTaskModel); } currentTask.Status = 2; currentTask.ExecuteType = 13; currentTask.Comments = executeModel.Comment; currentTask.CompletedTime1 = DateExtensions.Now; currentTask.IsSign = executeModel.IsSign; updateTasks.Add(currentTask); executeResult.Messages = localizer == null ? "加签成功!" : localizer["Execute_AddWriteSuccess"].Value; executeResult.DebugMessages = executeResult.Messages; executeResult.IsSuccess = true; executeResult.NextTasks = addTasks; } /// /// 更新任务 /// /// 要删除的列表 /// 要更新的列表 /// 要添加的列表 /// 要执行的sql列表(sql,参数,0提交退回前 1提交退回后) /// public int Update(List removeTasks, List updateTasks, List addTasks, List<(string, object[], int)> executeSqls) { DbConnection con = new DbConnection(); // var clent = con.getClient(); // clent.BeginTran(); con.BeginTrans(); try { int count = 0; if (executeSqls != null) { List<(string, object[], int)> exec = executeSqls.Where(x => x.Item3 == 0).ToList(); count += con.executeSqlByCurrent(exec, false); } if (null != removeTasks && removeTasks.Any()) { count += this.Delete(removeTasks); } if (null != updateTasks && updateTasks.Any()) { count += this.Update(updateTasks); } if (null != addTasks && addTasks.Any()) { count += this.AddRangeList(addTasks); } if (executeSqls != null) { List<(string, object[], int)> exec = executeSqls.Where(x => x.Item3.In(1, 2, 3)).ToList(); count += con.executeSqlByCurrent(exec, false); } con.CommitTran(); return count; } catch { con.RollbackTran(); throw; } } /// /// 得到流程处理后的提示信息 /// /// /// /// /// 语言包 /// public string GetExecuteMessage(Model.FlowRunModel.ExecuteResult executeResultModel, Model.FlowRunModel.Execute executeModel, Model.FlowRunModel.Step currentStepModel, IStringLocalizer localizer = null) { if (!currentStepModel.SendShowMessage.IsNullOrWhiteSpace() && executeModel.ExecuteType == Model.FlowRunModel.Execute.Type.Submit && executeResult.StepIsPass)//如果步骤设置了发送提示语,则直接返回 { return RoadFlow.Business.Wildcard.Filter(currentStepModel.SendShowMessage); } else if (!currentStepModel.BackShowMessage.IsNullOrWhiteSpace() && executeModel.ExecuteType == Model.FlowRunModel.Execute.Type.Back && executeResult.StepIsBack)//如果步骤设置了退回提示语,则直接返回 { return RoadFlow.Business.Wildcard.Filter(currentStepModel.BackShowMessage); } string message = string.Empty; Organize organize = new Organize(); var nextTasks = executeResult.NextTasks.FindAll(p => p.TaskType != 5 && p.TaskType != 11); switch (executeModel.ExecuteType) { case Model.FlowRunModel.Execute.Type.Submit: case Model.FlowRunModel.Execute.Type.FreeSubmit: if (executeResultModel.IsSuccess && nextTasks.Count > 0) { List stepNames = new List(); foreach (var task in nextTasks.GroupBy(p => p.StepName)) { stepNames.Add(task.Key); } message = (localizer == null ? "已发送到:" : localizer["Execute_GetExecuteMessageSendTo"].Value) + stepNames.JoinList("、"); } else if (executeResult.StepIsPass && nextTasks.Count == 0 && executeResultModel.IsSuccess) { message = localizer == null ? "已完成!" : localizer["Execute_GetExecuteMessageCompleted"].Value; } else { message = localizer == null ? "已发送,等待他人处理!" : localizer["Execute_GetExecuteMessageSendWait"].Value; } break; case Model.FlowRunModel.Execute.Type.Completed: //如果是征求直接,则提示已回复。 if (executeResultModel.CurrentTask != null && executeResultModel.CurrentTask.TaskType == 11) { message = localizer == null ? "已回复!" : localizer["State_Replied"].Value; } else { message = executeResultModel.IsSuccess ? (localizer == null ? "已完成!" : localizer["Execute_GetExecuteMessageCompleted"].Value) : (localizer == null ? "已发送,等待他人处理!" : localizer["Execute_GetExecuteMessageSendWait"].Value); } break; case Model.FlowRunModel.Execute.Type.Back: if (executeResultModel.IsSuccess && nextTasks.Count > 0) { List stepNames = new List(); foreach (var task in nextTasks.GroupBy(p => p.StepName)) { stepNames.Add(task.Key); } message = (localizer == null ? "已退回到:" : localizer["Execute_GetExecuteMessageBackTo"].Value) + stepNames.JoinList("、"); } else { message = localizer == null ? "已退回,等待他人处理!" : localizer["Execute_GetExecuteMessageBackWait"].Value; } break; case Model.FlowRunModel.Execute.Type.Save: if (executeResultModel.IsSuccess) { message = localizer == null ? "已保存!" : localizer["Execute_GetExecuteMessageSaved"].Value; } break; case Model.FlowRunModel.Execute.Type.Redirect: if (executeResult.IsSuccess && nextTasks.Count > 0) { StringBuilder redirectName = new StringBuilder(); JObject paramsJSON = JObject.Parse(executeModel.ParamsJSON); foreach (JObject jObject in paramsJSON.Value("steps")) { redirectName.Append(organize.GetNames(jObject.Value("member"))); redirectName.Append("、"); } message = (localizer == null ? "已转交给:" : localizer["Execute_GetExecuteMessageRedirectTo"].Value) + redirectName.ToString().TrimEnd('、'); } else { message = localizer == null ? "没有接收人!" : localizer["Execute_RedirectReceiverEmpty"].Value; } break; case Model.FlowRunModel.Execute.Type.CopyforCompleted: if (executeResult.IsSuccess) { message = localizer == null ? "已完成!" : localizer["Execute_GetExecuteMessageCompleted"].Value; } else { message = localizer == null ? "处理失败!" : localizer["Execute_GetExecuteMessageFail"].Value; } break; } return message; } /// /// VUE模式下发送消息 /// /// /// /// 发送方式 0站内短信 1手机短信 2微信 3公众号 4邮件 /// /// 语言包 public async void SendMessageVue(List nextTasks, SysUser sender, string sendModel = "", string contents = "", IStringLocalizer localizer = null) { /* await Task.Run(() => { if (null == nextTasks || nextTasks.Count == 0 || sendModel.IsNullOrWhiteSpace()) { return; } Message message = new Message(); Utility.Mail mail = new Utility.Mail(); List mailModels = new List();//要发送的邮件 UserDummy user = new UserDummy(); var userLange = sender == null;//? null : user.GetLanguageConf(sender.Id); var userMessageLang = userLange?.GetSection("message"); foreach (var nextTask in nextTasks) { if (nextTask.Status == -1)//等待中的任务不发消息 { continue; } if (null != sender && nextTask.ReceiveId == sender.Id)//自己处理的任务不给自己发消息 { continue; } var userModel = user.Get(nextTask.ReceiveId); if (null == userModel) { continue; } //手机短信 if (("," + sendModel + ",").Contains(",1,") && !userModel.Mobile.IsNullOrWhiteSpace()) { if (contents.IsNullOrWhiteSpace()) { contents = (localizer == null ? "您有一个待办事项:" : localizer["YourHasTodoTask"].Value) + nextTask.Title + (localizer == null ? ";请尽快处理!" : localizer["YourHasTodoTaskHandle"].Value); } message.VueSend(contents, new List() { userModel }, "1", sender, 20, language: userMessageLang); } //站内消息 if (("," + sendModel + ",").Contains(",0,")) { if (contents.IsNullOrWhiteSpace()) { contents = (localizer == null ? "您有一个待办事项:" : localizer["YourHasTodoTask"].Value) + nextTask.Title + (localizer == null ? ";请尽快处理!" : localizer["YourHasTodoTaskHandle"].Value); } string url = "/flow/run/index?flowid=" + nextTask.FlowId.ToString() + "&stepid=" + nextTask.StepId.ToString() + "&taskid=" + nextTask.Id.ToString() + "&groupid=" + nextTask.GroupId.ToString() + "&instanceid=" + nextTask.InstanceId; message.VueSend(contents, new List() { userModel }, "0", sender, 20, url, userMessageLang); } //微信 if (Config.EnterpriseWeChatIsUse && ("," + sendModel + ",").Contains(",2,") && (!userModel.Mobile.IsNullOrWhiteSpace() || !userModel.Email.IsNullOrWhiteSpace())) { if (contents.IsNullOrWhiteSpace()) { contents = (localizer == null ? "您有一个待办事项:" : localizer["YourHasTodoTask"].Value) + nextTask.Title + (localizer == null ? ";请尽快处理!" : localizer["YourHasTodoTaskHandle"].Value); } string url = "/flow/run/index?flowid=" + nextTask.FlowId.ToString() + "&stepid=" + nextTask.StepId.ToString() + "&taskid=" + nextTask.Id.ToString() + "&groupid=" + nextTask.GroupId.ToString() + "&instanceid=" + nextTask.InstanceId + "&ismobile=1&ismessage=1"; message.VueSend(contents, new List() { userModel }, "2", sender, 20, url, userMessageLang); } //邮件(如果配置文件中没有配置邮件服务,帐号密码,则不发送) if (("," + sendModel + ",").Contains(",4,") && !userModel.Email.IsNullOrWhiteSpace() && !Config.MailServer.IsNullOrWhiteSpace() && !Config.MailAccount.IsNullOrWhiteSpace() && !Config.MailPassword.IsNullOrWhiteSpace()) { if (contents.IsNullOrWhiteSpace()) { contents = (localizer == null ? "您有一个待办事项:" : localizer["YourHasTodoTask"].Value) + nextTask.Title + (localizer == null ? ";请尽快处理!" : localizer["YourHasTodoTaskHandle"].Value); } //得到邮件链接处理token string token = Utility.WebApiToken.GetToken(userModel.Id, GuidExtensions.NewGuid().ToString(), DateExtensions.Now.AddDays(Utility.Config.MailTokenExpireDays), 7); string url = Utility.Config.EnterpriseWeChatWebUrl + "?loadurl=" + ("/flow/run/index?flowid=" + nextTask.FlowId.ToString() + "&stepid=" + nextTask.StepId.ToString() + "&taskid=" + nextTask.Id.ToString() + "&groupid=" + nextTask.GroupId.ToString() + "&instanceid=" + nextTask.InstanceId + "&openmode=5").UrlEncode() + "&roadflow-token=" + token; string html = contents + "点击这里处理"; //mail.Send(userModel.Name, userModel.Email, sender.Name, sender.Email, contents, html); mailModels.Add(new Utility.Mail.MailModel() { ReceiveMail = userModel.Email, ReceiverName = userModel.Name, Subject = contents, Contents = html }); } } mail.Send(mailModels); });*/ } /// /// 得到一个步骤名称 /// /// /// /// public string GetStepName(Model.FlowRun flowRunModel, Guid stepId) { if (null == flowRunModel) { return string.Empty; } var step = flowRunModel.Steps.Find(p => p.Id == stepId); return null == step ? string.Empty : step.Name; } /// /// 创建第一个任务 /// /// /// public Model.rf_flowtask GetFirstTask(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel) { var firstStep = flowRunModel.Steps.Find(p => p.Id == flowRunModel.FirstStepId); if (null == firstStep) { throw new Exception("未找到流程第一步!"); } if (executeModel.Title.IsNullOrWhiteSpace()) { executeModel.Title = flowRunModel.Name + " - " + executeModel.Sender.Name; } Model.rf_flowtask task = new Model.rf_flowtask { Comments = executeModel.Comment, ExecuteType = 1, FlowId = executeModel.FlowId.ToString(), FlowName = flowRunModel.Name, GroupId = GuidExtensions.NewGuid().ToString(), Id = GuidExtensions.NewGuid().ToString(), InstanceId = executeModel.InstanceId, IsSign = executeModel.IsSign, Note = executeModel.Note, OtherType = executeModel.OtherType, PrevId = string.Empty, PrevStepId = string.Empty, ReceiveId = executeModel.Sender.Id, ReceiveName = executeModel.Sender.Name, ReceiveTime = DateExtensions.Now, SenderId = executeModel.Sender.Id, SenderName = executeModel.Sender.Name, Sort = 1, Status = 1, StepId = flowRunModel.FirstStepId.ToString(), StepName = GetStepName(flowRunModel, executeModel.StepId), StepSort = 1, TaskType = 0, Title = executeModel.Title, IsAutoSubmit = 0, IsBatch = firstStep.BatchExecute }; //2021-3-24增加,记录发起人的兼职部门关系ID /* if (!executeModel.Sender.PartTimeId.IsNullOrEmpty() ) { task.ReceiveOrganizeId = executeModel.Sender.PartTimeId; }*/ //2021-3-24增加完 return task; } /// /// 已回复(征求意见完成) /// /// /// /// 语言包 public void SolicitCompleted(Model.rf_flowtask currentTask, Model.FlowRunModel.Execute executeModel, IStringLocalizer localizer = null) { if (null == currentTask) { executeResult.DebugMessages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "当前任务为空!" : localizer["Execute_SubmitTaskEmpty"].Value; return; } else if (currentTask.Status.In(-1, 2)) { executeResult.DebugMessages = (localizer == null ? "当前任务" : localizer["Execute_SubmitCurrentTask"].Value) + (currentTask.Status == -1 ? (localizer == null ? "等待中" : localizer["Execute_SubmitCurrentTaskWait"].Value) : (localizer == null ? "已处理" : localizer["Execute_SubmitCurrentTaskProcessed"].Value)) + "!"; executeResult.IsSuccess = false; executeResult.Messages = executeResult.DebugMessages; return; } currentTask.ExecuteType = 14; currentTask.Status = 2; currentTask.CompletedTime1 = DateExtensions.Now; currentTask.Comments = executeModel.Comment; currentTask.IsSign = executeModel.IsSign; currentTask.Attachment = executeModel.Attachment; updateTasks.Add(currentTask); executeResult.IsSuccess = true; } /// /// 处理前加签任务 /// /// /// public void BeforAddWrite(Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, Model.rf_flowtask currentTask, IStringLocalizer localizer = null) { char[] otherType = currentTask.OtherType.ToString().ToCharArray(); if (otherType.Length != 3) { executeResult.DebugMessages = localizer == null ? "加签参数错误!" : localizer["Execute_AddWriteParamError"].Value; executeResult.IsSuccess = false; executeResult.Messages = localizer == null ? "加签参数错误!" : localizer["Execute_AddWriteParamError"].Value; return; } int addType = otherType[1].ToString().ToInt();//加签类型 1前加签 2后加签 3并签 int executeType = otherType[2].ToString().ToInt(); ;//处理类型 1所有人同意,2一个同意 3顺序处理 bool addIsPass = false;//加签是否通过 var groupTasks = GetListByGroupId(currentTask.GroupId); var levelTask = groupTasks.FindAll(p => p.Sort == currentTask.Sort && p.Id != currentTask.Id); switch (executeType) { case 1://所有人同意 addIsPass = !levelTask.Exists(p => p.Status != 2); break; case 2://一人同意 addIsPass = true; foreach (var task in levelTask) { if (task.Status != 2) { task.Status = 2; task.ExecuteType = 4; updateTasks.Add(task); } } break; case 3://顺序处理 var nextTask = levelTask.Find(p => p.StepSort == currentTask.StepSort + 1); if (null != nextTask) { nextTask.Status = 0; nextTask.ExecuteType = 0; updateTasks.Add(nextTask); executeResult.NextTasks = new List() { nextTask }; } else { addIsPass = true; } break; } currentTask.Status = 2; currentTask.ExecuteType = 2; currentTask.IsSign = executeModel.IsSign; currentTask.Comments = executeModel.Comment; currentTask.ExecuteType = 2; currentTask.CompletedTime1 = DateExtensions.Now; updateTasks.Add(currentTask); executeResult.IsSuccess = true; if (addIsPass && addType == 1) { var prevTask = GetOneById(currentTask.PrevId); if (null != prevTask) { var addTask = prevTask.Clone(); addTask.Id = GuidExtensions.NewGuid().ToString(); addTask.PrevId = currentTask.Id; addTask.Status = 0; addTask.ExecuteType = 0; addTask.IsSign = 0; addTask.Comments = null; addTask.CompletedTime1 = new DateTime?(); addTask.OpenTime = new DateTime?(); addTasks.Add(addTask); executeResult.NextTasks = new List() { addTask }; } } } /// /// 判断一个步骤是否通过 /// /// /// 要判断的步骤 /// 会签步骤 /// /// private bool StepIsPass(Model.FlowRun flowRunModel, Model.FlowRunModel.Step step, Model.FlowRunModel.Step countersignatureStep, List groupTasks) { var stepTaskList = groupTasks.FindAll(p => p.StepId == step.Id.ToString() && p.TaskType != 5 && p.TaskType != 11); var maxSort = stepTaskList.Count == 0 ? -1 : stepTaskList.Max(p => p.Sort); var stepTasks = -1 == maxSort ? new List() : stepTaskList.FindAll(p => p.Sort == maxSort); if (stepTasks.Count == 0) { //这里要判断会签步骤的前一步到会签发起步骤之间有多步的情况 if (countersignatureStep.StepBase.CountersignatureStartStepId.HasValue) { var rangeSteps = new Flow().GetRangeSteps(flowRunModel, countersignatureStep.StepBase.CountersignatureStartStepId.Value, step.Id); foreach (var rangeStep in rangeSteps) { if (groupTasks.Exists(p => p.StepId == rangeStep.Id.ToString() && p.TaskType != 5 && p.TaskType != 11)) { return false; } } return true; } //如果没有设置起点步骤,则只判断会签的前一步,如果没有任务则算不通过 else { return false; } } bool isPass = true; switch (step.StepBase.HanlderModel) { case 0://所有人同意 isPass = !stepTasks.Exists(p => p.Status != 2); break; case 1://一人同意即可 isPass = stepTasks.Exists(p => p.ExecuteType == 2); break; case 2://依据人数比例 isPass = stepTasks.Count(p => p.Status == 2) / stepTasks.Count * 100 >= step.StepBase.Percentage; break; case 3://独立处理 isPass = !stepTasks.Exists(p => p.Status != 2); break; case 4://顺序处理 isPass = !stepTasks.Exists(p => p.Status != 2); break; } return isPass; } /// /// 得到要抄送的人员 /// /// /// public List GetCopyForUsers(Model.FlowRunModel.Step stepModel, Model.FlowRun flowRunModel, Model.FlowRunModel.Execute executeModel, List groupTasks) { StringBuilder members = new StringBuilder(); if (!stepModel.StepCopyFor.MemberId.IsNullOrWhiteSpace()) { members.Append(stepModel.StepCopyFor.MemberId); members.Append(","); } #region sql或方法 if (!stepModel.StepCopyFor.MethodOrSql.IsNullOrWhiteSpace()) { string methodOrSql = stepModel.StepCopyFor.MethodOrSql.Trim(); if (methodOrSql.StartsWith("select", StringComparison.CurrentCultureIgnoreCase))//sql { if (flowRunModel.Databases.Count > 0) { StringBuilder stringBuilder = new StringBuilder(); DbConnection dbconn = new DbConnection(); DataTable dataTable = dbconn.GetDataTable(dbconn.GetOneById(flowRunModel.Databases.First().ConnectionId.ToString()), RoadFlow.Business.Wildcard.Filter(methodOrSql)); foreach (DataRow dr in dataTable.Rows) { stringBuilder.Append(dr[0]); stringBuilder.Append(","); } members.Append(stringBuilder.ToString()); //members.Append(","); } } else { Model.FlowRunModel.EventParam eventParam = new Model.FlowRunModel.EventParam { FlowId = flowRunModel.Id, GroupId = executeModel.GroupId, InstanceId = executeModel.InstanceId, StepId = stepModel.Id, TaskId = executeModel.TaskId }; var (obj, err) = Tools.ExecuteMethod(methodOrSql.Trim(), eventParam); if (null != obj) { members.Append(obj.ToString()); members.Append(","); } } } #endregion #region 处理者类型 if (!stepModel.StepCopyFor.HandlerType.IsNullOrWhiteSpace()) { UserDummy user = new UserDummy(); foreach (string type in stepModel.StepCopyFor.HandlerType.Split(',')) { if (!type.IsInt(out int handlerType)) { continue; } string members1 = string.Empty; var firstSenderId = GetFirstSenderId(groupTasks); switch (handlerType) { case 0://发起者 members1 = IOrganize.PREFIX_USER + firstSenderId; break; case 1://前一步骤处理者 members1 = GetPrevStepHandler(groupTasks, executeModel.TaskId); break; case 2://发起者部门领导 members1 = user.GetLeader(firstSenderId.ToString()); break; case 3://发起者分管领导 members1 = user.GetLeader(firstSenderId.ToString()); break; case 4://发起者上级部门领导 members1 = user.GetParentLeader(firstSenderId.ToString()).leader; break; case 5://发起者部门所有成员 members1 = user.GetUserIds(user.GetOrganizeUsers(firstSenderId.ToString())); break; case 6://发起者所有上级部门领导 members1 = user.GetAllParentLeader(firstSenderId.ToString()).leader; break; } members.Append(members1); members.Append(","); } } #endregion #region 步骤 if (!stepModel.StepCopyFor.Steps.IsNullOrWhiteSpace()) { foreach (string stepId in stepModel.StepCopyFor.Steps.Split(',')) { if (stepId.IsGuid(out Guid guid)) { members.Append(GetStepHandler(groupTasks, stepId)); members.Append(","); } } } #endregion return new Organize().GetAllUsers(members.ToString().TrimEnd(',')); } /// /// 得到流程前一步处理者 /// /// /// 当前任务ID /// public string GetPrevStepHandler(List groupTasks, Guid taskId) { var currentTask = groupTasks.Find(p => p.Id == taskId.ToString()); if (null == currentTask) { return string.Empty; } var prevTask = groupTasks.Find(p => p.Id == currentTask.PrevId); if (null == prevTask) { return string.Empty; } var prevTasks = groupTasks.FindAll(p => p.PrevId == prevTask.PrevId); StringBuilder stringBuilder = new StringBuilder(); foreach (var prev in prevTasks) { if (prev.TaskType == 5 || prev.TaskType == 11)//抄送和征求意见不算 { continue; } if (!prev.ReceiveOrganizeId.IsNullOrWhiteSpace()) { stringBuilder.Append(IOrganize.PREFIX_RELATION + prev.ReceiveOrganizeId); } else { stringBuilder.Append(IOrganize.PREFIX_USER + prev.ReceiveId.ToString()); } stringBuilder.Append(","); } return stringBuilder.ToString().TrimEnd(','); } /// /// 根据子流程组ID查询主流程任务 /// /// /// public List GetListBySubFlowGroupId(string groupId) { return this.GetListBy(x => x.SubFlowGroupId.Contains(groupId.ToUpper())); /* using (var db = new DataContext()) { return db.Query("SELECT * FROM RF_FlowTask WHERE SubFlowGroupId LIKE '%" + groupId.ToString().ToUpper() + "%'"); }*/ } /// /// 自动执行一个任务 /// /// /// 执行类型 /// 处理意见 /// public Model.FlowRunModel.ExecuteResult AutoSubmit(Guid taskId, string type = "submit", string comment = "") { Model.FlowRunModel.ExecuteResult result = new Model.FlowRunModel.ExecuteResult(); var currentTask = GetOneById(taskId.ToString()); if (null == currentTask) { result.Messages = "当前任务为空!"; result.DebugMessages = result.Messages; result.IsSuccess = false; return result; } if (currentTask.TaskType == 11) { result.Messages = "征求意见不能自动处理!"; result.DebugMessages = result.Messages; result.IsSuccess = false; return result; } Flow flow = new Flow(); var flowRunModel = flow.GetFlowRunModel(currentTask.FlowId, true, currentTask); if (null == flowRunModel) { result.Messages = "未找到流程运行时实体!"; result.DebugMessages = result.Messages; result.IsSuccess = false; return result; } JArray jArray = new JArray(); switch (type.ToLower()) { case "submit": var (_, message, sendSteps) = GetNextSteps(flowRunModel, currentTask.StepId.ToGuid(), currentTask.GroupId, taskId.ToString(), currentTask.InstanceId, currentTask.ReceiveId, false); foreach (var nextStep in sendSteps) { //如果没有默认处理人员并且不是最后一步,不提交。 if (nextStep.RunDefaultMembers.IsNullOrWhiteSpace() && !flow.IsLastStep(flowRunModel, currentTask.StepId.ToGuid())) { continue; } JObject stepObject = new JObject { { "id", nextStep.Id }, { "member", nextStep.RunDefaultMembers }, { "completedtime", nextStep.WorkTime > 0 ? new WorkDate().GetWorkDateTime((double)nextStep.WorkTime).ToDateTimeString() : string.Empty } }; jArray.Add(stepObject); } //如果是提交或退回并且没有后续步骤则直接返回 if (jArray.Count == 0 && sendSteps.Count > 0 && (type.EqualsIgnoreCase("submit") || type.EqualsIgnoreCase("back"))) { return new Model.FlowRunModel.ExecuteResult() { CurrentTask = currentTask, DebugMessages = "接收步骤没有默认处理人 " + message, IsSuccess = false, Messages = "接收步骤没有默认处理人", NextTasks = new List() }; } break; case "back": var (_, message1, backSteps) = GetBackSteps(currentTask.FlowId, currentTask.StepId, currentTask.GroupId, taskId.ToString() , currentTask.InstanceId, currentTask.ReceiveId); foreach (var backStep in backSteps) { JObject stepObject = new JObject { { "id", backStep.Id }, { "member", backStep.RunDefaultMembers } }; jArray.Add(stepObject); } //如果是提交或退回并且没有后续步骤则直接返回 if (jArray.Count == 0) { return new Model.FlowRunModel.ExecuteResult() { CurrentTask = currentTask, DebugMessages = message1, IsSuccess = false, Messages = message1, NextTasks = new List() }; } break; } JObject jObject = new JObject { { "id", taskId.ToString() }, //任务ID,第一个任务为空 { "flowId", currentTask.FlowId }, //流程ID,和任务ID不能同时为空 { "instanceId", currentTask.InstanceId }, //实例ID { "title", currentTask.Title }, //任务标题 { "comment", comment }, //处理意见 { "sign", 0 }, //是否签章 { "senderId", currentTask.ReceiveId }, //发送人ID { "type", currentTask.TaskType == 5 ? "copyforcompleted" : type }, { "note", "" }, //备注 { "steps", jArray } }; var (executeModel, errMsg) = GetExecuteModel(jObject.ToString()); if (null == executeModel) { result.Messages = errMsg; result.DebugMessages = result.Messages; result.IsSuccess = false; return result; } if (currentTask.IsAutoSubmit == 1) { executeModel.IsAutoSubmit = true; } var currentUser = _userManager.User;//User.CurrentUser; if (currentUser != null) { executeModel.Sender = currentUser; } //executeModel.OtherType = 2;// OtherType 为2表示自动提交 return Execute(executeModel); } /// /// 将JSON参数转换为执行实体 /// /// /// {id:'任务id',flowId:'流程ID',instanceId:'实例id',title:'任务标题',comment:'处理意见',type:'处理类型',note:'备注', /// senderId:'发送人id',sign:'是否签章 0|1',steps:[{id:'接收步骤id',name:'接收步骤名称',member:'接收人',completedtime:'要求完成时间'}]} /// 执行实体,错误信息 public (Model.FlowRunModel.Execute, string) GetExecuteModel(string json) { if (json.IsNullOrWhiteSpace()) { return (null, "参数为空"); } JObject jObject = null; try { jObject = JObject.Parse(json); } catch { return (null, "参数解析错误"); } string taskId = jObject.Value("id"); string flowId = jObject.Value("flowId"); Guid flowGuid = Guid.Empty; if (!taskId.IsGuid(out Guid taskGuid) && !flowId.IsGuid(out flowGuid)) { return (null, "任务ID和流程ID同时为空"); } var currentTask = taskGuid.IsEmptyGuid() ? null : GetOneById(taskGuid.ToString()); if (flowGuid.IsEmptyGuid() && null != currentTask) { flowGuid = currentTask.FlowId.ToGuid(); } var flowRunModel = new Flow().GetFlowRunModel(flowGuid, true, currentTask); if (null == flowRunModel) { return (null, "流程运行时实体为空"); } string instanceId = jObject.Value("instanceId"); string title = jObject.Value("title"); string comment = jObject.Value("comment"); string type = jObject.Value("type"); string note = jObject.Value("note"); string senderId = jObject.Value("senderId"); if (!senderId.IsGuid(out Guid senderGuid)) { return (null, "发送人为空"); } var senderUser = new UserDummy().Get(senderId); if (null == senderUser) { return (null, "没有找到发送人"); } if (type.IsNullOrEmpty()) { return (null, "执行类型为空"); } int sign = jObject.Value("sign").ToInt(0); JArray stepsArray = jObject.Value("steps"); Model.FlowRunModel.Execute executeModel = new Model.FlowRunModel.Execute { Comment = comment, FlowId = currentTask == null ? flowGuid : currentTask.FlowId.ToGuid() }; executeModel.ExecuteType = GetExecuteType(type); executeModel.GroupId = currentTask == null ? Guid.Empty : currentTask.GroupId.ToGuid(); executeModel.InstanceId = currentTask == null ? string.Empty : currentTask.InstanceId; executeModel.IsSign = sign; executeModel.Note = note; executeModel.Sender = senderUser; executeModel.StepId = currentTask == null ? flowRunModel.FirstStepId : currentTask.StepId.ToGuid(); executeModel.TaskId = currentTask == null ? Guid.Empty : currentTask.Id.ToGuid(); executeModel.Title = title; List<(Guid, string, Guid?, int?, List, DateTime?)> steps = new List<(Guid, string, Guid?, int?, List, DateTime?)>(); Organize organize = new Organize(); foreach (JObject step in stepsArray) { Guid id = step.Value("id").ToGuid(); var stepModel = flowRunModel.Steps.Find(p => p.Id == id); if (null == stepModel) { continue; } string name = step.Value("name");//步骤名称 string beforeStepId = step.Value("beforestepid");//动态步骤的原步骤ID string parallelorserial = step.Value("parallelorserial");//0并且 1串行 string member = step.Value("member"); string completedtime = step.Value("completedtime"); DateTime? comTime = completedtime.IsDateTime(out DateTime dt) ? dt : stepModel.WorkTime > 0 ? DateExtensions.Now.AddDays((double)stepModel.WorkTime) : new DateTime?(); steps.Add((id, name, beforeStepId.IsGuid(out Guid beforeStepGuid) ? new Guid?(beforeStepGuid) : new Guid?(), parallelorserial.IsInt(out int parallelorserialInt) ? new int?(parallelorserialInt) : new int?(), organize.GetAllUsers(member), comTime)); } executeModel.Steps = steps; return (executeModel, string.Empty); } /// /// 根据字符串处理类型,得到枚举处理类型 /// /// /// public Model.FlowRunModel.Execute.Type GetExecuteType(string type) { if (type.IsNullOrWhiteSpace()) { return Model.FlowRunModel.Execute.Type.Save; } switch (type.ToLower()) { case "freesubmit": //自由流程发送 return Model.FlowRunModel.Execute.Type.FreeSubmit; case "submit": return Model.FlowRunModel.Execute.Type.Submit; case "save": return Model.FlowRunModel.Execute.Type.Save; case "back": return Model.FlowRunModel.Execute.Type.Back; case "completed": return Model.FlowRunModel.Execute.Type.Completed; case "redirect": return Model.FlowRunModel.Execute.Type.Redirect; case "addwrite": return Model.FlowRunModel.Execute.Type.AddWrite; case "copyforcompleted": //抄送完成(已阅知) return Model.FlowRunModel.Execute.Type.CopyforCompleted; case "taskend": return Model.FlowRunModel.Execute.Type.TaskEnd; default: return Model.FlowRunModel.Execute.Type.Save; } } /// /// 得到处理类别显示标题 /// /// /// 语言包 /// public string GetExecuteTypeTitle(int executeType, IStringLocalizer localizer = null) { string title = string.Empty; switch (executeType) { case -1: title = localizer == null ? "等待中" : localizer["State_Wait"]; break; case 0: title = localizer == null ? "未处理" : localizer["State_Untreated"]; break; case 1: title = localizer == null ? "处理中" : localizer["State_Processing"]; break; case 2: title = localizer == null ? "已完成" : localizer["State_Completed"]; break; case 3: title = localizer == null ? "已退回" : localizer["State_Back"]; break; case 4: title = localizer == null ? "他人已处理" : localizer["State_OtherProcess"]; break; case 5: title = localizer == null ? "他人已退回" : localizer["State_OtherBack"]; break; case 6: title = localizer == null ? "已转交" : localizer["State_Transferred"]; break; case 7: title = localizer == null ? "已委托" : localizer["State_Entrusted"]; break; case 8: title = localizer == null ? "已阅知" : localizer["State_Knowing"]; break; case 9: title = localizer == null ? "已指派" : localizer["State_Assigned"]; break; case 10: title = localizer == null ? "已跳转" : localizer["State_Skip"]; break; case 11: title = localizer == null ? "已终止" : localizer["State_Terminated"]; break; case 12: title = localizer == null ? "他人已终止" : localizer["State_OtherTerminated"]; break; case 13: title = localizer == null ? "已加签" : localizer["State_AddWrite"]; break; case 14: title = localizer == null ? "已回复" : localizer["State_Replied"]; break; } return title; } /// /// 抄送任务 /// /// 当前任务 /// 接收人 /// 语言包 /// 返回1表示成功,其它为错误信息 public string CopyFor(Model.rf_flowtask currentTask, List users, IStringLocalizer localizer = null) { if (null == currentTask || null == users) { return localizer == null ? "当前任务为空或已完成或当前用户为空!" : localizer["NotFoundTask"].Value; } if (currentTask.Status == 2) { return localizer == null ? "当前任务为空或已完成,不能抄送!" : localizer["NotFoundTask"].Value; } List addTaskList = new List(); var groupTasks = GetListByGroupId(currentTask.GroupId); foreach (var user in users) { //判断下一步待办中没有当前接收人的待办才添加 if (addTaskList.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId) || groupTasks.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.Status != 2)) { continue; } var task = currentTask.Clone(); task.Id = GuidExtensions.NewGuid().ToString(); task.ReceiveId = user.Id; task.ReceiveName = user.Name; task.ReceiveTime = DateExtensions.Now; task.SenderId = currentTask.ReceiveId; task.SenderName = currentTask.ReceiveName; task.CompletedTime1 = null; task.CompletedTime = null; task.RemindTime = null;//2020-8-14添加:当主任务有提醒时间时,抄送时要把提醒时间设置为空。 task.Comments = ""; task.ExecuteType = 0; task.Status = 0; task.TaskType = 5; task.Note = localizer == null ? "抄送" : localizer["Execute_SubmitTaskNoteCopyfor"].Value; task.IsSign = 0; /* if (user.PartTimeId.HasValue) { task.ReceiveOrganizeId = user.PartTimeId; }*/ addTaskList.Add(task); } string msg = Update(null, null, addTaskList, null) > 0 ? "1" : localizer == null ? "没有抄送给任何人员!" : localizer["CopyFor_NotUser"].Value; SendMessage(addTaskList, new UserDummy().Get(currentTask.ReceiveId), "0,1,2,3", localizer: localizer); return msg; } /// /// 发送待办消息 /// /// /// /// 发送方式 0站内短信 1手机短信 2微信 3公众号 4邮件 /// 消息内容 public async void SendMessage(List nextTasks, SysUser sender, string sendModel = "", string contents = "", IStringLocalizer localizer = null) { return; /* if (Config.IsVue) { SendMessageVue(nextTasks, sender, sendModel, contents, localizer); return; } var httpContext = Tools.HttpContext; string appopenmodel = null == httpContext ? "0" : httpContext.Request.Querys("rf_appopenmodel"); string appid = null == httpContext ? "" : httpContext.Request.Querys("appid"); string tabid = null == httpContext ? "" : httpContext.Request.Querys("tabid"); await Task.Run(() => { if (null == nextTasks || nextTasks.Count == 0) { return; } Message message = new Message(); User user = new User(); foreach (var nextTask in nextTasks) { if (nextTask.Status == -1)//等待中的任务不发消息 { continue; } if (null != sender && nextTask.ReceiveId == sender.Id)//自己处理的任务不给自己发消息 { continue; } var userModel = user.Get(nextTask.ReceiveId); if (null == userModel) { continue; } string url = string.Format("/RoadFlowCore/FlowRun/{0}?flowid={1}&stepid={2}&taskid={3}&groupid={4}&instanceid={5}&appid={6}&tabid={7}&rf_appopenmodel={8}", "Index", nextTask.FlowId, nextTask.StepId, nextTask.Id, nextTask.GroupId, nextTask.InstanceId, appid, tabid, appopenmodel); //手机短信 if (("," + sendModel + ",").Contains(",1,") && !userModel.Mobile.IsNullOrWhiteSpace()) { SMS.SendSMS(contents.IsNullOrWhiteSpace() ? (localizer == null ? "您有一个待办事项“" : localizer["Execute_SendMessageWait"]) + nextTask.Title + "”," + (localizer == null ? "请尽快处理!" : localizer["Execute_SendMessageProcess"]) : contents, userModel.Mobile); } //站内消息 if (("," + sendModel + ",").Contains(",0,")) { message.Send(nextTask.ReceiveId, (contents.IsNullOrWhiteSpace() ? (localizer == null ? "您有一个待办事项“" : localizer["Execute_SendMessageWait"]) + nextTask.Title + "”" : contents) + "," + (localizer == null ? "点击处理!" : localizer["Execute_SendMessageClickProcess"]) + "", "0", sender); } //微信 if (Config.Enterprise_WeiXin_IsUse && ("," + sendModel + ",").Contains(",2,") && (!userModel.Mobile.IsNullOrWhiteSpace() || !userModel.Email.IsNullOrWhiteSpace())) { JObject msgJson = new JObject { { "title", localizer == null ? "待办事项" : localizer["Execute_SendMessageToItems"] }, { "description", !contents.IsNullOrWhiteSpace() ? contents : "
" + (localizer==null?"发送人":localizer["Execute_SendMessageSender"]) + ":" + nextTask.SenderName + " 时间:"+nextTask.ReceiveTime.ToShortDateTimeString() + "
" + (contents.IsNullOrWhiteSpace() ? (localizer == null ? "您有一个待办事项“" : localizer["Execute_SendMessageWait"]) + nextTask.Title + "”," + (localizer == null ? "请尽快处理!" : localizer["Execute_SendMessageProcess"]) : contents) + "
" }, { "url", Config.Enterprise_WeiXin_WebUrl + url + "&ismobile=1" }, { "btntxt", localizer == null ? "处理" : localizer["Execute_SendMessageProcess1"] } }; EnterpriseWeiXin.Common.SendMessage(userModel, msgJson, "textcard"); } //微信公众号 if (Config.WeiXin_IsUse && ("," + sendModel + ",").Contains(",3,")) { if (!userModel.WeiXinOpenId.IsNullOrWhiteSpace()) { WeiXin.TemplateMessage.SendWaitTaskMessage(nextTask); } } } });*/ } /// /// 征求意见 /// /// /// /// 意见可见性 20自己可见 21流程参与人可见 /// 备注 /// public string SolicitOpinion(Model.rf_flowtask currentTask, List users, int visibility, string note = "", IStringLocalizer localizer = null) { if (null == currentTask || null == users) { return localizer == null ? "当前任务为空或已完成或当前用户为空!" : localizer["NotFoundTask"].Value; } if (currentTask.Status == 2) { return localizer == null ? "当前任务为空或已完成或当前用户为空!" : localizer["NotFoundTask"].Value; } List addTaskList = new List(); List updateTaskList = new List(); var groupTasks = GetListByGroupId(currentTask.GroupId); foreach (var user in users) { //判断下一步待办中没有当前接收人的待办才添加 var oldTask = addTaskList.Find(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId); if (oldTask == null) { oldTask = groupTasks.Find(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.Status != 2 && p.TaskType == 11); } bool isIn = oldTask != null; Model.rf_flowtask task; if (!isIn) { task = currentTask.Clone(); task.Id = GuidExtensions.NewGuid().ToString(); task.PrevId = currentTask.Id; } else { task = oldTask; } task.ReceiveId = user.Id; task.ReceiveName = user.Name; task.ReceiveTime = DateExtensions.Now; task.SenderId = currentTask.ReceiveId; task.SenderName = currentTask.ReceiveName; task.CompletedTime1 = null; task.CompletedTime = null; task.Comments = ""; task.ExecuteType = 0; task.Status = 0; task.TaskType = 11; task.Note = note.IsNullOrWhiteSpace() ? localizer == null ? "征求意见" : localizer["SolicitOpinions"].Value : note; task.IsSign = 0; task.OtherType = visibility; /* if (user.PartTimeId.HasValue) { task.ReceiveOrganizeId = user.PartTimeId; }*/ if (isIn) { updateTaskList.Add(task); } else { addTaskList.Add(task); } } string msg = Update(null, updateTaskList, addTaskList, null) > 0 ? "1" : localizer == null ? "没有发送给任何人员!" : localizer["CopyFor_NotUser"].Value; SendMessage(addTaskList, new UserDummy().Get(currentTask.ReceiveId), "0,1,2,3"); return msg; } /// /// 查询待办事项 /// /// /// /// /// /// 是否批量 0不是,1是 /// public List GetWaitTask(int size, int number, string userId, string flowId, string title, string startDate, string endDate, string order, out int count, int isBatch = 0) { int total = 0; var rtn = db.Queryable().Where(x => x.ReceiveId == userId) .WhereIF(isBatch != 0, x => x.IsBatch == 1 && ((new int[] { 0, 1 }).Contains(x.Status))) .WhereIF(!flowId.IsNullOrWhiteSpace() && flowId.IsGuid(), x => x.FlowId == flowId) .WhereIF(!flowId.IsNullOrWhiteSpace() && !flowId.IsGuid(), x => flowId.Split(',', StringSplitOptions.RemoveEmptyEntries).Contains(x.FlowId)) .WhereIF(!title.IsNullOrWhiteSpace(), x => x.Title.Contains(title)) .WhereIF(startDate.IsDateTime(), x => x.ReceiveTime >= startDate.ToDateTime()) .WhereIF(endDate.IsDateTime(), x => x.ReceiveTime <= endDate.ToDateTime()) .OrderByIF(!order.IsNullOrWhiteSpace(), order.FilterSelectSql()) .ToPageList(number, size, ref total) .ToList(); count = total; return rtn; } /// /// 判断一个任务是否可以作废 /// /// /// public bool IsDelete(string taskId, Model.FlowRun flowRunModel = null) { var task = GetOneById(taskId); if (null == task) { return false; } if (null == flowRunModel) { flowRunModel = new Flow().GetFlowRunModel(task.FlowId); } if (null == flowRunModel) { return false; } //如果是第一步并且当前处理者是发起者,可以作废 if (task.StepId == flowRunModel.FirstStepId.ToString() && task.ReceiveId == GetFirstSenderId(task.GroupId)) { return true; } else { return false; } } /// /// 得到任务类型标题 /// /// 任务类型 /// 语言包 /// public string GetTaskTypeTitle(int taskType, IStringLocalizer localizer = null) { switch (taskType) { case 1: return localizer == null ? "指派" : localizer["TaskType_Designate"].Value; case 2: return localizer == null ? "委托" : localizer["TaskType_Entrust"].Value; case 3: return localizer == null ? "转交" : localizer["TaskType_Transfer"].Value; case 4: return localizer == null ? "退回" : localizer["TaskType_Back"].Value; case 5: return localizer == null ? "抄送" : localizer["TaskType_Copyfor"].Value; case 6: return localizer == null ? "前加签" : localizer["TaskType_BeforeAddWrite"].Value; case 7: return localizer == null ? "后加签" : localizer["TaskType_AfterAddWrite"].Value; case 8: return localizer == null ? "并签" : localizer["TaskType_AddWrite"].Value; case 9: return localizer == null ? "跳转" : localizer["TaskType_Goto"].Value; case 11: return localizer == null ? "征求意见" : localizer["TaskType_SolicitOpinion"].Value; default: return string.Empty; } } /// /// 查询已办事项 /// /// /// /// /// /// public List GetCompletedTask(int size, int number, string userId, string flowId, string title, string startDate, string endDate, string order, out int count) { int total = 0; var rtn = db.Queryable().Where(x => x.ReceiveId == userId && x.ExecuteType > 1) .WhereIF(flowId.IsGuid(), x => x.FlowId == flowId) .WhereIF(!title.IsNullOrWhiteSpace(), x => x.Title.Contains(title)) .WhereIF(startDate.IsDateTime(out DateTime date1), x => x.CompletedTime1 > date1.GetDate()) .WhereIF(endDate.IsDateTime(out DateTime date2), x => x.CompletedTime1 < date2.AddDays(1).GetDate()) .OrderByIF(!order.IsNullOrWhiteSpace(), order.FilterSelectSql()) .ToPageList(number, size, ref total) .ToList(); count = total; return rtn; } /// /// 查询我发起的流程 /// /// /// /// /// /// ""全部 "0"未完成 "1" 已完成 /// public List GetMyStartList(int size, int number, string userId, string flowId, string title, string startDate, string endDate, string status, string order, out int count) { int total = 0; var rtn = db.Queryable().Where(x => x.SenderId == userId && x.PrevId == string.Empty) .WhereIF(flowId.IsGuid(), x => x.FlowId == flowId) .WhereIF(!title.IsNullOrWhiteSpace(), x => x.Title.Contains(title)) .WhereIF(startDate.IsDateTime(out DateTime date1), x => x.ReceiveTime >= date1.GetDate()) .WhereIF(endDate.IsDateTime(out DateTime date2), x => x.ReceiveTime < date2.GetDate()) .OrderByIF(!order.IsNullOrWhiteSpace(), order.FilterSelectSql()) .ToPageList(number,size,ref total) .ToList(); List groupIds = new List(); foreach (var t in rtn) groupIds.Add(t.GroupId); var names= db.Queryable().Where(x => groupIds.Contains(x.GroupId)&& x.Status<2).OrderBy(x=>x.ReceiveTime, OrderByType.Desc).ToList(); foreach (var r in rtn) r.CurrentStepName = names.FirstOrDefault(x => x.GroupId == r.GroupId)?.StepName; // string sql = "SELECT StepName from RF_FlowTask WHERE groupId='" + groupId.ToString() + "' AND Status<2 ORDER BY ReceiveTime DESC LIMIT 1"; count = total; return rtn; } /// /// 查询已委托事项 /// /// /// /// /// /// public List GetEntrustTask(int size, int number, string userId, string flowId, string title, string startDate, string endDate, string order, out int count) { int total = 0; var rtn = db.Queryable().Where(x => x.EntrustUserId == userId) .WhereIF(flowId.IsGuid(), x => x.FlowId == flowId) .WhereIF(!title.IsNullOrWhiteSpace(), x => x.Title == title) .WhereIF(startDate.IsDateTime(out DateTime date1), x => x.ReceiveTime >= date1.GetDate()) .WhereIF(endDate.IsDateTime(out DateTime date2), x => x.ReceiveTime < date2.AddDays(1).GetDate()) .OrderByIF(!order.IsNullOrWhiteSpace(), order).ToPageList(number, size, ref total).ToList(); count = total; return rtn; } /// /// 删除 /// /// 组id /// public int DeleteByGroupId(string groupid) { return DeleteBy(x=>x.GroupId== groupid); } /// /// 判断人员是否可以查看处理过程 /// /// /// 组任务列表 /// 返回 -1表示不能打开 1任务参与人 2实例管理人 public int IsOpenProcess(string userId, List groupTasks, Model.FlowRun flowRunModel = null) { if (null == groupTasks || groupTasks.Count == 0) { return -1; } if (groupTasks.Exists(p => p.ReceiveId == userId)) { return 1; } if (null == flowRunModel) { flowRunModel = new Flow().GetFlowRunModel(groupTasks.FirstOrDefault().FlowId); } if (flowRunModel == null || flowRunModel.InstanceManager.IsNullOrWhiteSpace()) { return -1; } if (new UserDummy().IsIn(userId.ToString(), flowRunModel.InstanceManager)) { return 2; } return -1; } /// /// 查询实例列表 /// /// /// /// /// /// /// /// /// /// /// public List GetInstanceList(int size, int number, string flowId, string title, string receiveId, string receiveDate1, string receiveDate2, string order, out int count) { int total = 0; var rtn = db.Queryable() .Select("GroupId,MAX(ReceiveTime),ReceiveTime") .WhereIF(!flowId.IsNullOrWhiteSpace()&& flowId.IsGuid(),x=>x.FlowId== flowId) .WhereIF(!flowId.IsNullOrWhiteSpace() &&!flowId.IsGuid(),x=>flowId.Split(',',StringSplitOptions.RemoveEmptyEntries).Contains(x.FlowId)) .WhereIF(!title.IsNullOrWhiteSpace(),x=>x.Title.Contains(title)) .WhereIF(receiveId.IsGuid(),x=>x.ReceiveId==receiveId) .WhereIF(receiveDate1.IsDateTime(out DateTime date1),x=>x.ReceiveTime>=date1.GetDate()) .WhereIF(receiveDate2.IsDateTime(out DateTime date2),x=>x.ReceiveTimenew { x.GroupId ,x.ReceiveTime}) .OrderBy(x=>x.ReceiveTime,OrderByType.Desc) .ToPageList(number, size, ref total) .ToList(); count = total; return rtn; } /// /// 指派任务 /// /// 当前任务 /// 要指派的人员 /// 语言包 /// 返回1表示成功,其它为错误信息 public string Designate(Model.rf_flowtask currentTask, List users, IStringLocalizer localizer = null) { currentTask.ExecuteType = 9; currentTask.Status = 2; currentTask.CompletedTime1 = DateExtensions.Now; List updateTaskList = new List { currentTask }; var groupTasks = GetListByGroupId(currentTask.GroupId); List addTaskList = new List(); FlowEntrust flowEntrust = new FlowEntrust(); UserDummy user = new UserDummy(); for (int i = 0; i < users.Count; i++) { var userModel = users[i]; #region 判断委托 string entrustId = flowEntrust.GetEntrustUserId(currentTask.FlowId, userModel); bool isEntrust = !entrustId.IsNullOrWhiteSpace(); /* if (isEntrust) { var entrustUser = user.Get(entrustId); if (null != entrustUser) { var entrustUser1 = entrustUser; entrustUser1.Note = userModel.Id.ToString();//用这个字段来保存委托人ID,在加入任务表的时候要用到 userModel = entrustUser1; } }*/ #endregion //判断下一步待办中没有当前接收人的待办才添加 if (addTaskList.Exists(p => p.ReceiveId == userModel.Id && p.StepId == currentTask.StepId && p.TaskType != 5 && p.TaskType != 11) || groupTasks.Exists(p => p.ReceiveId == userModel.Id && p.Id != currentTask.Id && p.StepId == currentTask.StepId && p.Status != 2 && p.TaskType != 5 && p.TaskType != 11)) { continue; } var newTaskModel = currentTask.Clone(); newTaskModel.Id = GuidExtensions.NewGuid().ToString(); newTaskModel.ReceiveId = userModel.Id; newTaskModel.ReceiveName = userModel.Name; /* if (userModel.PartTimeId.HasValue) { newTaskModel.ReceiveOrganizeId = userModel.PartTimeId.Value; }*/ newTaskModel.ReceiveTime = DateExtensions.Now; newTaskModel.Status = 0; newTaskModel.ExecuteType = 0; newTaskModel.TaskType = 1; newTaskModel.Note = localizer == null ? "指派" : localizer["TaskType_Designate"].Value; newTaskModel.Comments = ""; newTaskModel.IsSign = 0; /* if (userModel.PartTimeId.HasValue) { newTaskModel.ReceiveOrganizeId = userModel.PartTimeId.Value; } if (isEntrust && userModel.Note.IsGuid(out Guid entuustId))//用人员实体的NOTE字段来存放委托人ID { newTaskModel.EntrustUserId = entuustId; }*/ //newTaskModel.PrevId = currentTask.Id; addTaskList.Add(newTaskModel); } if (!addTaskList.Any())//如果没有指派给任何人,则不更新当前任务状态 { updateTaskList.Clear(); } SendMessage(addTaskList, _userManager.User);//发送待办消息 return Update(null, updateTaskList, addTaskList, null) > 0 ? "1" : localizer["Execute_NotDesignateUser"].Value; } /// /// 跳转任务 /// /// 当前任务 /// 要跳转到的步骤 /// 语言包 /// 返回1表示成功,其它为错误信息 public string GoTo(Model.rf_flowtask currentTask, Dictionary> steps, IStringLocalizer localizer = null) { if (null == currentTask) { return localizer == null ? "当前任务为空!" : localizer["ChangeStatus_NotFoundTask"].Value; } List addTaskList = new List(); List updateTaskList = new List(); var groupTasks = GetListByGroupId(currentTask.GroupId); int maxSort = groupTasks.FindAll(p => p.StepId == currentTask.StepId).Max(p => p.Sort); var levelTasks = groupTasks.FindAll(p => p.StepId == currentTask.StepId && p.Sort == maxSort); foreach (var levelTask in levelTasks)//完成当前任务的同级任务 { if (levelTask.Status != 2) { levelTask.Status = 2; levelTask.ExecuteType = 10; levelTask.CompletedTime1 = DateExtensions.Now; updateTaskList.Add(levelTask); } } var flowRunModel = new Flow().GetFlowRunModel(currentTask.FlowId, true, currentTask); if (null == flowRunModel) { return localizer == null ? "未找到流程运行时实体" : localizer["GoTo_NotFoundFlowRunModel"].Value; } FlowEntrust flowEntrust = new FlowEntrust(); UserDummy buser = new UserDummy(); foreach (var step in steps) { var currentStep = flowRunModel.Steps.Find(p => p.Id == step.Key); if (null == currentStep) { continue; } for (int i = 0; i < step.Value.Count; i++) { var user = step.Value[i]; #region 判断委托 string entrustId = flowEntrust.GetEntrustUserId(currentTask.FlowId, user); bool isEntrust = !entrustId.IsNullOrWhiteSpace(); /* if (isEntrust) { var entrustUser = buser.Get(entrustId); if (null != entrustUser) { var entrustUser1 = entrustUser; entrustUser1.Note = user.Id.ToString();//用这个字段来保存委托人ID,在加入任务表的时候要用到 user = entrustUser1; } }*/ #endregion //判断下一步待办中没有当前接收人的待办才添加 if (addTaskList.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.TaskType != 5 && p.TaskType != 11) || groupTasks.Exists(p => p.ReceiveId == user.Id && p.StepId == currentTask.StepId && p.Status != 2 && p.TaskType != 5 && p.TaskType != 11)) { continue; } Model.rf_flowtask task = new Model.rf_flowtask(); if (currentStep.WorkTime > 0) { task.CompletedTime = DateExtensions.Now.AddDays((double)currentStep.WorkTime); } /* if (user.PartTimeId.HasValue) { task.ReceiveOrganizeId = user.PartTimeId; } if (isEntrust && user.Note.IsGuid(out Guid entuustId))//用人员实体的NOTE字段来存放委托人ID { task.EntrustUserId = entuustId; }*/ task.ExecuteType = 0; task.FlowId = currentTask.FlowId; task.FlowName = currentTask.FlowName; task.GroupId = currentTask.GroupId; task.Id = GuidExtensions.NewGuid().ToString(); task.InstanceId = currentTask.InstanceId; task.IsAutoSubmit = currentStep.ExpiredExecuteModel; task.IsSign = 0; task.Note = localizer == null ? "跳转" : localizer["InstanceManage_GoTo"].Value; task.PrevId = currentTask.Id; task.PrevStepId = currentTask.StepId; task.ReceiveId = user.Id; task.ReceiveName = user.Name; task.ReceiveTime = DateExtensions.Now; task.SenderId = currentTask.ReceiveId; task.SenderName = currentTask.ReceiveName; task.Sort = currentTask.Sort + 1; task.Status = 0; task.StepId = currentStep.Id.ToString(); task.StepName = currentStep.Name; task.StepSort = 1; task.TaskType = 9; task.Title = currentTask.Title; task.OtherType = currentTask.OtherType; task.IsBatch = currentStep.BatchExecute; addTaskList.Add(task); } } SendMessage(addTaskList, _userManager.User);// User.CurrentUser);//发送待办消息 return Update(null, updateTaskList, addTaskList, null) > 0 ? "1" : (localizer == null ? "没有跳转给任何人员!" : localizer["SaveGoTo_NotUser"].Value); } /// /// 根据JSON字符串参数执行流程 /// /// /// {id:'任务id',flowId:'流程ID',instanceId:'实例id',title:'任务标题',comment:'处理意见',type:'处理类型',note:'备注', /// senderId:'发送人id',sign:'是否签章 0|1',steps:[{id:'接收步骤id',name:'接收步骤名称',member:'接收人',completedtime:'要求完成时间'}]} /// /// 语言包 /// public Model.FlowRunModel.ExecuteResult ExecuteFromJSON(string json, IStringLocalizer localizer = null) { var (executeModel, msg) = GetExecuteModel(json); if (executeModel != null && msg.IsNullOrEmpty()) { return Execute(executeModel, null, localizer); } else { return new Model.FlowRunModel.ExecuteResult() { Messages = msg, DebugMessages = msg, IsSuccess = false }; } } } }