using Ewide.Core; using Ewide.RoadFlowLite.Utility; using Furion; using Furion.DependencyInjection; using Furion.DynamicApiController; using Furion.FriendlyException; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json.Linq; using RoadFlow.Data; using RoadFlow.Utility; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Ewide.RoadFlowLite.Serivce.FlowRun { [Route("/api/roadflow/FlowRun/")] [ApiDescriptionSettings("RoadFlow")] public class FlowRunService : IFlowRunService, IDynamicApiController, ITransient { private readonly IUserManager _userManager; private readonly IDictionary _dictionary; private readonly IApplibrary _appLibrary; private readonly IFlowTask _flowTask; private readonly IFlow _flow; private readonly IUserDummy _userDummy; private readonly IFlowButton _flowButton; private readonly IFlowComment _flowComment; private readonly IForm _form; private readonly ILog _log; private readonly IFlowDynamic _dynamic; private readonly IFlowArchive _flowArchive; private readonly IOrganize _organize; private readonly IProgram _program; public FlowRunService( IUserManager userManager, IDictionary dictionary, IApplibrary appLibrary, IFlow flow, IFlowTask flowTask, IUserDummy userDummy, IFlowButton flowButton, IFlowComment flowComment, IForm form, ILog log, IFlowDynamic dynam, IFlowArchive flowArchive, IOrganize organize, IProgram program ) { _userManager = userManager; _dictionary = dictionary; _appLibrary = appLibrary; _flow = flow; _flowTask = flowTask; _userDummy = userDummy; _flowButton = flowButton; _flowComment = flowComment; _form = form; _log = log; _dynamic = dynam; _flowArchive = flowArchive; _organize = organize; _program = program; } [HttpGet("hello")] [AllowAnonymous] public dynamic Hello() { string hello = "hello".DESEncrypt(); return hello + ":" + hello.DESDecrypt(); } #region 流程处理 /// /// 得到可以发起的流程 /// /// [HttpGet("GetStartFlows")] [AllowAnonymous] public dynamic GetStartFlows(string keyWord) { //string keyWord = args.GetJsonValue("keyword");//搜索关键字 string userId = _userManager.UserId; var types = _dictionary.GetAllChilds("system_applibrarytype_flow", true); var allFlows = _flow.GetStartFlows(userId); var flows = !keyWord.IsNullOrWhiteSpace() ? allFlows.Where(p => p.Name.ContainsIgnoreCase(keyWord)).GroupBy(p => p.Type) : allFlows.GroupBy(p => p.Type); JArray jArray = new JArray(); foreach (var type in types) { var typeFlows = flows.Where(p => p.Key.ToString() == type.Id); if (!typeFlows.Any()) { continue; } JObject jObject = new JObject() { { "type", type.Title } }; JArray jArray1 = new JArray(); foreach (var flow in typeFlows) { foreach (var flowModel in flow.OrderBy(p => p.Name)) { var appModel = _appLibrary.GetByCode(flowModel.Id.ToString()); if (appModel == null) { continue; } jArray1.Add(new JObject() { { "id", flowModel.Id }, { "name", flowModel.Name }, { "ico", flowModel.Ico }, { "color", flowModel.Color }, { "openModel", appModel.OpenMode },//打开方式 { "url", appModel.Address }, }); } } jObject.Add("childs", jArray1); jArray.Add(jObject); } return jArray;// RoadFlowCommon.Tools.GetReturnJsonString(jArray: jArray); } /// /// 得到流程运行时加载的数据 /// /// [HttpPost("GetRun")] [AllowAnonymous] public dynamic GetRun([FromBody] JObject args) { string flowId = args.GetJsonValue("flowid"); string stepId = args.GetJsonValue("stepid"); string groupId = args.GetJsonValue("groupid"); string taskId = args.GetJsonValue("taskid"); bool isDisplay = "1".Equals(args.GetJsonValue("display")); bool isMobile = "1".Equals(args.GetJsonValue("ismobile")) || "1".Equals(args.GetJsonValue("mobile")); bool isCompleted = "1".Equals(args.GetJsonValue("completed")) || "1".Equals(args.GetJsonValue("iscompleted"));//是否是查看已完成,已完成要显示,催办,收回等按钮。 int ismobile = args.GetJsonValue("ismobile").ToInt(0);//客户端类型 0:PC 1:移动端 if (!flowId.IsGuid(out Guid flowGuid)) { throw Oops.Oh("流程ID错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } var (dynamicTaskModel, flowTaskModel, groupTasks) = _flowTask.GetDynamicTask(groupId, taskId); var flowRunModel = _flow.GetFlowRunModel(flowId, true, dynamicTaskModel); if (null == flowRunModel) { throw Oops.Oh("未找到流程"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowRunModel"].Value); } SysUser userModel = _userManager.User; string userId = userModel == null ? string.Empty : userModel.Id; var taskModel = flowTaskModel == null ? taskId.IsGuid() ? _flowTask.GetOneById(taskId) : null : flowTaskModel; if (_flowTask.IsOpenTask(userId, taskModel, flowRunModel) == -1) { throw Oops.Oh("您不能处理当前步骤"); //判断当前人员是否可以处理当前任务 //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["YourCannotHandleTask"].Value); } if (taskModel != null && taskModel.Status == 2) { //如果任务已经完成,则设置为只读 isDisplay = true; } if (!stepId.IsGuid(out Guid stepGuid)) { //第一步,新发起判断流程是否可以发起 if (taskModel == null && flowRunModel.Status != 1) { throw Oops.Oh("流程状态错误,不能开始"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["CannotStart"].Value + flowRunModel.Name + localizer["CannotStartFlow"].Value); } //如果没有步骤id则从taskModel中取,没有taskModel则取流程第一步 stepGuid = taskModel == null ? flowRunModel.FirstStepId : taskModel.StepId.ToGuid(); } var stepModel = flowRunModel.Steps.Find(p => p.Id == stepGuid); if (null == stepModel) { throw Oops.Oh("未找到当前步骤"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowStep"].Value); } //检查并发 if (stepModel.StepBase.ConcurrentModel == 1 && null != taskModel && taskModel.TaskType != 5 && taskModel.TaskType != 11) { //2021-3-25修改,增加了检查并发时要判断策略分组 groupTasks = groupTasks != null ? groupTasks : _flowTask.GetListByGroupId(taskModel.GroupId); IEnumerable openTasks; if (stepModel.StepBase.HanlderModelGroup == 2) { openTasks = groupTasks.Where(p => p.TaskType != 5 && p.TaskType != 11 && p.OtherType == taskModel.OtherType && p.Status == 1 && p.ReceiveId != userId && p.PrevId == taskModel.PrevId); } else { openTasks = groupTasks.Where(p => p.TaskType != 5 && p.TaskType != 11 && p.Status == 1 && p.ReceiveId != userId && p.PrevId == taskModel.PrevId); } if (openTasks.Any()) { throw Oops.Oh("当前流程正由 " + openTasks.FirstOrDefault().ReceiveName + " 操作中,请稍后再试"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["CurrentStepHandleing"].Value + openTasks.FirstOrDefault().ReceiveName + localizer["CurrentStepHandleingWait"].Value); } } //如果是流程第一步判断是否有权限发起 if (taskModel == null && stepModel.Id == flowRunModel.FirstStepId && !stepModel.StepBase.DefaultHandler.IsNullOrWhiteSpace() && !_userDummy.IsIn(userId.ToString(), stepModel.StepBase.DefaultHandler)) { throw Oops.Oh("不能发起流程"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["CannotStartCurrentFlow"].Value); } //更新任务状态为处理中 if (null != taskModel && taskModel.Status == 0) { _flowTask.UpdateStatus(taskModel.Id, 1, 1, taskModel.OpenTime.HasValue ? new DateTime?() : DateExtensions.Now); } string flowTaskNote = string.Empty;//要显示的备注信息 string lang = RoadFlow.Utility.Tools.GetCurrentLanguage(App.HttpContext);//当前语言 #region 组织流程相关配置 JObject flowObject = new JObject(); #region 组织流程按钮 //RoadFlow.Business.FlowButton flowButton = new RoadFlow.Business.FlowButton(); var flowButtons = _flowButton.GetAll(); JArray buttonsArray = new JArray(); //是否是抄送任务 bool isCopyFor = taskModel != null && taskModel.TaskType == 5; //是否是征求意见 bool isSolicitOpition = taskModel != null && taskModel.TaskType == 11; string printButtonId = "CADD9F81-2B8C-479B-A7F1-3CEC775768FA".ToLower();//打印按钮ID if (isDisplay) { //添加打印按钮 var printButton = flowButtons.Find(p => p.Id == printButtonId); if (printButton != null) { buttonsArray.Add(new JObject() { { "id", printButton.Id }, { "title", _flowButton.GetLanguageTitle(printButton, out string note, lang) }, { "ico", printButton.Ico }, { "scripts", printButton.Script }, { "note", note }, }); } //添加处理过程按钮 var porcessButton = flowButtons.Find(p => p.Id == "D9511329-A03E-4AF2-84E5-73BEDA0D3F42".ToLower()); if (porcessButton != null) { buttonsArray.Add(new JObject() { { "id", porcessButton.Id }, { "title", _flowButton.GetLanguageTitle(porcessButton, out string note, lang) }, { "ico", porcessButton.Ico }, { "scripts", porcessButton.Script }, { "note", note }, }); } //如果可以催办,添加催办和收回按钮 if (isCompleted && taskModel != null) { bool isHasten = _flowTask.IsHasten(taskModel.Id, out bool isWithdraw); if (isHasten) { buttonsArray.Add(new JObject() { { "id", GuidExtensions.NewGuid().ToString() }, { "title", "催办" },//localizer["Urging"].Value { "ico", "icon-comment-edit-outline" }, { "scripts", "this.hasten();" }, { "note", "" }, }); } if (isWithdraw) { buttonsArray.Add(new JObject() { { "id", GuidExtensions.NewGuid().ToString() }, { "title", "撤销" },//localizer["Withdraw"].Value { "ico", "icon-format-rotate-90" }, { "scripts", "this.withdraw();" }, { "note", "" }, }); } } } else if (isCopyFor) { //抄送显示打印和已阅知按钮 var printButton = flowButtons.Find(p => p.Id == printButtonId); if (printButton != null) { buttonsArray.Add(new JObject() { { "id", printButton.Id }, { "title", _flowButton.GetLanguageTitle(printButton, out string note, lang) }, { "ico", printButton.Ico }, { "scripts", printButton.Script }, { "note", note }, }); } //已阅知按钮 var readButton = flowButtons.Find(p => p.Id == "AA27EAB5-66F0-4CDE-958F-1F28DA4B4392".ToLower()); if (readButton != null) { buttonsArray.Add(new JObject() { { "id", readButton.Id }, { "title", _flowButton.GetLanguageTitle(readButton, out string note, lang) }, { "ico", readButton.Ico }, { "scripts", readButton.Script }, { "note", note }, }); } } else if (isSolicitOpition) { if (!taskModel.Note.IsNullOrWhiteSpace()) { flowTaskNote = taskModel.Note; } var printButton = flowButtons.Find(p => p.Id == printButtonId); if (printButton != null) { buttonsArray.Add(new JObject() { { "id", printButton.Id }, { "title", _flowButton.GetLanguageTitle(printButton, out string note, lang) }, { "ico", printButton.Ico }, { "scripts", printButton.Script }, { "note", note }, }); } //回复按钮 var replyButton = flowButtons.Find(p => p.Id == "C87911A2-0846-4CC1-99A8-DFC6681E323A".ToLower()); if (replyButton != null) { buttonsArray.Add(new JObject() { { "id", replyButton.Id }, { "title", _flowButton.GetLanguageTitle(replyButton, out string note, lang) }, { "ico", replyButton.Ico }, { "scripts", replyButton.Script }, { "note", note }, }); } } else { foreach (var button in stepModel.StepButtons) { var buttonModel = flowButtons.Find(p => p.Id == button.Id.ToString()); if (buttonModel != null) { string title = _flowButton.GetLanguageTitle(buttonModel, out string note, lang); buttonsArray.Add(new JObject() { { "id", button.Id }, { "title", button.ShowTitle.IsNullOrWhiteSpace() ? title : button.ShowTitle }, { "ico", buttonModel.Ico }, { "scripts", buttonModel.Script }, { "note", button.Note.IsNullOrWhiteSpace() ? note : button.Note }, }); } } } flowObject.Add("buttons", buttonsArray); flowObject.Add("isCopyFor", isCopyFor ? 1 : 0); flowObject.Add("isDisplay", isDisplay ? 1 : 0); flowObject.Add("flowType", stepModel.StepBase.FlowType);//流转类型 #endregion //步骤意见设置 JObject signObject = new JObject { { "type", isDisplay ? 0 : isSolicitOpition ? 1 : stepModel.SignatureType },//如果是征求意见,则始终显示意见栏 { "comment", taskModel!=null ? taskModel.Comments : "" }, { "attachment", taskModel!=null ? taskModel.Attachment : ""}, { "issign", taskModel!=null ? taskModel.IsSign : 0 }, { "signsrc", _userDummy.GetSignSrcVue(userId.ToString(), userModel.Name)}, { "show", stepModel.CommentDisplay },//本步骤是否要显示意见 }; if (stepModel.SignatureType > 0 || isSolicitOpition) { //常用意见 JArray commentArray = new JArray(); var comments = _flowComment.GetListByUserId(userId); foreach (var comment in comments) { commentArray.Add(new JObject() { { "value", comment.Comments }, { "title", comment.Comments } }); } signObject.Add("commentoptions", commentArray); signObject.Add("isattachment", isSolicitOpition ? 1 : stepModel.Attachment);//如果是征求意见,则始终可以传附件 } flowObject.Add("sign", signObject); flowObject.Add("archive", stepModel.Archives);//步骤是否归档 //流程调试模式 flowObject.Add("debug", flowRunModel.Debug > 0 && flowRunModel.DebugUserIds.ContainsIgnoreCase(userId.ToString()) ? flowRunModel.Debug : 0); #endregion //添加备注 flowObject.Add("flowTaskNote", flowTaskNote); #region 组织表单 JObject formObject = new JObject(); if (stepModel != null && stepModel.StepForm != null) { int formType = ismobile; if (formType == 1 && stepModel.StepForm.MobileId.IsEmptyGuid()) { formType = 0;//如果是移动端,没有设置移动端表单,取PC端表单 } switch (formType) { //PC表单 case 0: if (stepModel.StepForm.Id.IsNotEmptyGuid()) { var appModel = _appLibrary.GetOneById(stepModel.StepForm.Id.ToString()); if (appModel != null) { if (appModel.Code.IsGuid(out Guid formId)) { formObject = _form.GetRunJObject(appModel.Code); } else { formObject.Add("form_iscustomeform", 1);//0设计表单 1自定义表单 formObject.Add("url", appModel.Address); } } } break; case 1: //移动端表单 if (stepModel.StepForm.MobileId.IsNotEmptyGuid()) { var appModel = _appLibrary.GetOneById(stepModel.StepForm.MobileId.ToString()); ; if (appModel != null) { if (appModel.Code.IsGuid(out Guid formId)) { formObject = _form.GetRunJObject(appModel.Code); } else { formObject.Add("form_iscustomeform", 1);//0设计表单 1自定义表单 formObject.Add("url", appModel.Address); } } } break; } } if (formObject.IsEmptyJObject()) { //如果没有设置表单,返回空对象,以免表单加载时报错 formObject = _form.GetRunJObject(string.Empty); } #endregion #region 表单及数据 JObject formDataObject = new JObject() { { "form_id", formObject.Value("id") }, { "form_dbconnid", formObject.Value("conn") }, { "form_dbtable", formObject.Value("table") }, { "form_dbtableprimarykey", formObject.Value("primaryKey") }, { "form_titlefield", formObject.Value("titleField") }, { "form_dbtabletitleexpression", formObject.Value("titleExpression") }, { "form_instanceid", taskModel == null ? App.HttpContext.Request.Querys("instanceid") : taskModel.InstanceId }, { "form_fieldstatus", new JObject() }, { "flowid", taskModel == null ? flowId : taskModel.FlowId.ToString() }, { "stepid", taskModel == null ? stepId : taskModel.StepId.ToString() }, { "taskid", taskId }, { "groupid", taskModel == null ? groupId : taskModel.GroupId.ToString() }, }; JObject statusObject = new JObject();//字段状态 JObject checkObject = new JObject();//字段检查 string formatJson = formObject.ContainsKey("formatJson") ? formObject.Value("formatJson").ToString(Newtonsoft.Json.Formatting.None) : "";//字段显示格式JSON JObject valueTypeObject = formObject.Value("valueTypeJson");//字段值类型JSON JObject defaultValueJson = formObject.Value("defaultValueJson");//默认值JSON //获取表单数据 JArray formDataArray = _form.GetFormData(formObject.Value("conn"), formObject.Value("table"), formObject.Value("primaryKey"), taskModel == null ? "" : taskModel.InstanceId, stepId , flowId, formatJson, out string fieldStatusJson, taskModel == null ? "" : taskModel.GroupId.ToString()).ToJArray(); foreach (JObject valueObject in formDataArray) { formDataObject.Add(valueObject.Value("name"), valueObject.Value("value")); } #region 数据表格控件数据 if (formObject.ContainsKey("datatableJson")) { foreach (JObject dtObject in formObject.Value("datatableJson")) { string id = dtObject.Value("id"); int source = dtObject.Value("source").ToInt(0); string text = dtObject.Value("text"); string conn = dtObject.Value("conn"); if (source == 0 && conn.IsGuid(out Guid connGuid))//SQL { var (rows, cols) = _form.GetDataTablJArray(conn, RoadFlow.Business.Wildcard.Filter(text, userModel, formDataObject)); formDataObject.Add(id, new JObject() { { "rows", rows }, { "cols", cols }, { "selects", new JArray() } }); } if (source == 1)//URL { JObject urlObject; try { urlObject = HttpHelper.HttpGet((App.HttpContext.Request.IsHttps ? "https://" : "http://") + App.HttpContext.Request.Host.Value + RoadFlow.Business.Wildcard.Filter(text, userModel, formDataObject)).ToJObject(); } catch { urlObject = null; } if (urlObject != null) { JArray rowsArray = new JArray(); try { rowsArray = urlObject.ContainsKey("rows") ? urlObject.Value("rows") : new JArray(); } catch { } JArray colssArray = new JArray(); try { colssArray = urlObject.ContainsKey("cols") ? urlObject.Value("cols") : new JArray(); } catch { } formDataObject.Add(id, new JObject() { { "rows", rowsArray }, { "cols", colssArray }, { "selects", new JArray() } }); } else { formDataObject.Add(id, new JObject() { { "rows", new JArray() }, { "cols", new JArray() }, { "selects", new JArray() } }); } } } } #endregion #region 子表 JArray subTableJarray = formObject.Value("subtableJson"); if (subTableJarray != null) { foreach (JObject sdtObject in subTableJarray) { string id = sdtObject.Value("id"); JArray sRows = _form.GetSubTableJarray(sdtObject, formObject.Value("conn"), taskModel == null ? "" : taskModel.InstanceId); if (formDataObject.ContainsKey(id)) { formDataObject[id] = new JObject() { { "rows", sRows } }; } else { formDataObject.Add(id, new JObject() { { "rows", sRows } }); } } //默认值 formDataObject.Add("subtableDefaultValue", _form.GetSubTableDefaultValueJArray(subTableJarray, userModel)); } #endregion JArray fieldStatusJArray = fieldStatusJson.ToJArray(); if (!fieldStatusJArray.IsEmptyJArray()) { //表单验证类型 int validatePromptType = formObject.Value("validatePromptType").ToInt(0); foreach (JObject fieldStatusObject in fieldStatusJArray) { string filed = fieldStatusObject.Value("name"); if (!statusObject.ContainsKey(filed)) { int status = fieldStatusObject.Value("status").ToInt(0); if ((isCopyFor || isSolicitOpition) && status == 0) { status = 1;//如果是抄送或者征求意见,字段是编辑则设置为只读状态。 } statusObject.Add(filed, status); } //验证json int check = fieldStatusObject.Value("check").ToInt(0); if (check > 0) { //判断是不是子表 int isSubTable = 0; string subTableId = string.Empty;//子表ID string fieldShowName = string.Empty;//子表字段的显示标题 if (!subTableJarray.IsEmptyJArray()) { foreach (JObject subTableJObject in subTableJarray) { string table = subTableJObject.Value("subTable"); if (filed.StartsWith(table.ToUpper() + "-")) { isSubTable = 1; subTableId = subTableJObject.Value("id"); string fieldName = filed.Replace(table.ToUpper() + "-", ""); //查找子表字段设置的显示名称。 foreach (JObject subTableRowJObject in subTableJObject.Value("rows")) { if (subTableRowJObject.Value("field").EqualsIgnoreCase(fieldName)) { fieldShowName = subTableRowJObject.Value("fieldName"); break; } } break; } } } //验证类型,string,decimal...... string validType = valueTypeObject.IsEmptyJObject() ? "string" : valueTypeObject.Value(filed); JObject cObject = new JObject() { { "type", validType.IsNullOrWhiteSpace() ? "string" : validType }, { "required", check == 2 }, { "title", fieldShowName }, { "msg", "" }, //{ "msg", fieldShowName + localizer["CannotbeEmpty"] }, { "showtype", validatePromptType }, { "position", isMobile ? 1 : 0 }, { "ispass", true }, { "issubtable", isSubTable }, { "subtableid", subTableId }, }; if ("ajax".Equals(validType)) { //如果是AJAX验证要添加url属性 cObject.Add("url", RoadFlow.Business.Wildcard.Filter(valueTypeObject.Value(filed + "-AJAXURL"), userModel, taskModel)); } checkObject.Add(filed, cObject); } } } //判断是否采用默认值。 if (defaultValueJson != null) { foreach (var j in defaultValueJson) { //如果数据表里已经有值,不设置默认值 if (formDataObject.ContainsKey(j.Key) && !formDataObject.Value(j.Key).IsNullOrEmpty()) { continue; } //如果是隐藏,不设置默认值 if (statusObject.ContainsKey(j.Key) && 2 == statusObject.Value(j.Key).ToInt(0)) { continue; } string defaultValue = j.Value.Value(); if (!defaultValue.IsNullOrWhiteSpace()) { //组织通配符obj参数 RoadFlow.Model.FlowRunModel.EventParam eventParam = new RoadFlow.Model.FlowRunModel.EventParam { FlowId = flowGuid, FlowRunModel = flowRunModel }; if (formDataObject.ContainsKey(j.Key)) { formDataObject[j.Key] = RoadFlow.Business.Wildcard.Filter(defaultValue, userModel, eventParam); } else { formDataObject.Add(j.Key, RoadFlow.Business.Wildcard.Filter(defaultValue, userModel, eventParam)); } } } } //移出不需要输出到客户端的数据 //formObject.Remove("validatePromptType"); //formObject.Remove("formatJson"); //formObject.Remove("valueTypeJson"); //formObject.Remove("defaultValueJson"); if (formObject.ContainsKey("data")) { formObject["data"] = formDataObject; } else { formObject.Add("data", formDataObject); } if (formObject.ContainsKey("fieldStatus")) { formObject["fieldStatus"] = statusObject; } else { formObject.Add("fieldStatus", statusObject); } if (formObject.ContainsKey("validate")) { formObject["validate"] = checkObject; } else { formObject.Add("validate", checkObject); } #endregion JObject jObject = new JObject() { { "form", formObject }, { "flow", flowObject }, }; return jObject;//RoadFlowCommon.Tools.GetReturnJsonString(true, jObject: jObject); } /// /// 得到子表数据 /// /// [HttpPost("GetSubtableData")] public dynamic GetSubtableData([FromBody] JObject args) { string subtableJson = args.GetJsonValue("subtablejson");//子表ID string instanceId = args.GetJsonValue("instanceid"); string connId = args.GetJsonValue("connid"); JObject subtableJObject = subtableJson.ToJObject(); if (subtableJObject.IsEmptyJObject() || instanceId.IsNullOrWhiteSpace() || !connId.IsGuid(out Guid connGuid)) { return new JArray(); // RoadFlowCommon.Tools.GetReturnJsonString(jArray: new JArray()); } JArray sRows = _form.GetSubTableJarray(subtableJObject, connId, instanceId); return sRows; //RoadFlowCommon.Tools.GetReturnJsonString(jArray: sRows); } /// /// 得到要发送的步骤 /// /// [HttpPost("GetSendSteps")] public dynamic GetSendSteps([FromBody] JObject args) { string flowId = args.GetJsonValue("flowid"); string stepId = args.GetJsonValue("stepid"); string taskId = args.GetJsonValue("taskid"); string groupId = args.GetJsonValue("groupid"); bool freeSend = "1".Equals(args.GetJsonValue("freesend")); if (!flowId.IsGuid(out Guid flowGuid)) { throw Oops.Oh("流程错误"); //RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } var (dynamicTask, currentTask, groupTasks) = _flowTask.GetDynamicTask(groupId, null); var flowRunModel = _flow.GetFlowRunModel(flowId, true, dynamicTask); if (null == flowRunModel) { throw Oops.Oh("找不到流程运行模块"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowRunModel"].Value); } if (!stepId.IsGuid(out Guid stepGuid)) { stepGuid = flowRunModel.FirstStepId; } var stepModel = flowRunModel.Steps.Find(p => p.Id == stepGuid); if (null == stepModel) { throw Oops.Oh("找不到流程步骤"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowStep"].Value); } string userId = _userManager.UserId; string groupGuid = groupId; string instanceId = string.Empty; RoadFlow.Model.rf_flowtask flowTaskModel = null; if (taskId.IsGuid(out Guid taskGuid)) { flowTaskModel = _flowTask.GetOneById(taskId); if (null != flowTaskModel) { groupGuid = flowTaskModel.GroupId; instanceId = flowTaskModel.InstanceId; } } var (json, msg, nextSteps) = _flowTask.GetNextSteps(flowRunModel, stepGuid, groupGuid, taskId, instanceId, userId, freeSend); //if (!msg.IsNullOrWhiteSpace()) //{ // return RoadFlowCommon.Tools.GetReturnJsonString(false, msg); //} JObject otherJSON = json.ToJObject();//返回的其他设置json JObject jObject = new JObject() { { "flowType", stepModel.StepBase.FlowType }, { "autoConfirm", stepModel.StepBase.AutoConfirm }, }; JArray jArray = new JArray(); JObject dynamicStepOject = new JObject() { { "flowtype", -1 }, { "runedit", -1 }, { "steps", new JArray() } };//动态步骤 foreach (var step in nextSteps) { #region 选择类型 JArray selectType = new JArray(); if (step.StepBase.HandlerType.ToInt(0) == 1) { selectType.Add("dept"); } else if (step.StepBase.HandlerType.ToInt(0) == 2) { selectType.Add("station"); } else if (step.StepBase.HandlerType.ToInt(0) == 3) { selectType.Add("workgroup"); } else if (step.StepBase.HandlerType.ToInt(0) == 4) { selectType.Add("user"); } else { selectType.Add("unit"); selectType.Add("dept"); selectType.Add("station"); selectType.Add("workgroup"); selectType.Add("user"); } #endregion #region 选择范围 string selectRange = step.StepBase.SelectRange; //将默认处理者设置为选择范围。 if (step.StepBase.SelectRangeForDefaultHandler >= 0) { selectRange += "," + step.RunDefaultMembers; if (step.StepBase.SelectRangeForDefaultHandler == 1)//如果是把默认处理者作为选择范围,默认不选中,则这里清空默认处理者。 { step.RunDefaultMembers = ""; } } #endregion #region 判断运行时选择 int runSelect = step.StepBase.RunSelect; if (otherJSON.ContainsKey("runselect_" + step.Id.ToLowerString())) { runSelect = otherJSON.Value("runselect_" + step.Id.ToLowerString()).ToInt(1); } #endregion JObject stepObject = new JObject() { { "id", step.Id.ToString() }, { "name", step.Name }, { "members", step.RunDefaultMembers }, //flowTaskModel != null && flowTaskModel.TaskType==6是为了判断前加签不用指定完成时间。 { "setTime", flowTaskModel != null && flowTaskModel.TaskType==6 ? 0 : step.SendSetWorkTime }, { "time", "" }, { "runSelect", runSelect }, { "rootId", selectRange }, { "dynamic", step.Dynamic }, { "parallelorserial", "0" }//默认并行审批 }; if (selectType.Count > 0) { stepObject.Add("selectType", selectType); } jArray.Add(stepObject); if (step.Dynamic == 2) { dynamicStepOject = _flowTask.GetDynamicStepFromFieldValue(flowRunModel, step, instanceId); foreach (JObject jObject1 in dynamicStepOject.Value("steps")) { jObject1.Add("runSelect", runSelect); jObject1.Add("rootId", selectRange); if (selectType.Count > 0) { jObject1.Add("selectType", selectType); } } } } jObject.Add("steps", jArray); jObject.Add("dynamicSteps", dynamicStepOject); return jObject; //return RoadFlowCommon.Tools.GetReturnJsonString(true, "", jObject: jObject); } /// /// 得到要退回的步骤 /// /// [HttpPost("GetBackSteps")] public dynamic GetBackSteps([FromBody] JObject args) { string flowid = args.GetJsonValue("flowid"); string taskid = args.GetJsonValue("taskid"); string stepid = args.GetJsonValue("stepid"); string groupid = args.GetJsonValue("groupid"); if (!flowid.IsGuid()) { throw Oops.Oh("流程id错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } if (!stepid.IsGuid()) { throw Oops.Oh("步骤id错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } var (selectUser, message, backSteps) = new FlowTask().GetBackSteps(flowid, stepid, groupid, taskid, string.Empty, _userManager.UserId); if (!message.IsNullOrWhiteSpace()) { throw Oops.Oh(message); // return RoadFlowCommon.Tools.GetReturnJsonString(false, message); } var organize = new Organize(); JObject jObject = new JObject(); JArray jArray = new JArray(); foreach (var step in backSteps) { jArray.Add(new JObject() { { "id", step.Id.ToString() }, { "name", step.Name }, { "members", step.RunDefaultMembers }, { "membernames", organize.GetNames(step.RunDefaultMembers) }, { "selectmembers", selectUser.ToInt(0) },//是否可以选择人员 }); } jObject.Add("steps", jArray); return jObject; //RoadFlowCommon.Tools.GetReturnJsonString(true, "", jObject: jObject); } /// /// 执行流程 /// /// [HttpPost("Execute")] public dynamic Execute([FromBody] JObject args) { string paramsJSON = args.GetJsonValue("params"); string issign = args.GetJsonValue("issign"); string comment = args.GetJsonValue("comment"); string attachment = args.GetJsonValue("attachment"); string flowid = args.GetJsonValue("flowid"); string instanceid = args.GetJsonValue("form_instanceid"); string taskid = args.GetJsonValue("taskid"); string stepid = args.GetJsonValue("stepid"); string groupid = args.GetJsonValue("groupid"); string ismobile = args.GetJsonValue("ismobile"); string signpassword = args.GetJsonValue("signpassword");//签章密码 bool isCustomeForm = "1".Equals(args.GetJsonValue("form_iscustomeform"));//是否是自定义表单 var currentUserModel = _userManager.User; if (currentUserModel == null) { throw Oops.Oh("用户不存在"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundUserLoginInfo"].Value); } #region 参数检查 if (paramsJSON.IsNullOrWhiteSpace()) { throw Oops.Oh("执行参数为空"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ExecPramEmpty"].Value); } if (!flowid.IsGuid()) { throw Oops.Oh("工作流错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } Flow flow = new Flow(); FlowTask flowTask = new FlowTask(); //查找当前任务是否有动态步骤,有则从动态步骤中取流程运行时 var (dynamicTaskModel, flowTaskModel, groupTasks) = flowTask.GetDynamicTask(groupid, taskid); var flowRunModel = flow.GetFlowRunModel(flowid, true, dynamicTaskModel); //================================================ if (null == flowRunModel) { throw Oops.Oh("工作流运行模块错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowRunModel"].Value); } JObject paramsObject = JObject.Parse(paramsJSON); string opation = paramsObject.Value("type"); if (opation.IsNullOrWhiteSpace()) { throw Oops.Oh("执行类型错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundExecType"].Value); } #endregion #region 组织执行参数实体 //2021-3-24增加,设置发起流程时的兼职部门关系ID // if (!taskid.IsGuid() && !groupid.IsGuid()) //{ // currentUserModel.PartTimeId = _userManager.UserId;//Current.GetPartTimeId(Request); // } //2021-3-24增加完 RoadFlow.Model.FlowRunModel.Execute executeModel = new RoadFlow.Model.FlowRunModel.Execute(); switch (opation) { case "freesubmit": //自由流程发送 executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.FreeSubmit; break; case "submit": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.Submit; break; case "save": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.Save; break; case "back": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.Back; break; case "completed": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.Completed; break; case "redirect": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.Redirect; break; case "addwrite": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.AddWrite; break; case "copyforcompleted": //抄送完成(已阅知) executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.CopyforCompleted; break; case "taskend": executeModel.ExecuteType = RoadFlow.Model.FlowRunModel.Execute.Type.TaskEnd; break; } executeModel.IsAutoSubmit = false; executeModel.Comment = comment.Trim(); executeModel.FlowId = flowid.ToGuid(); executeModel.GroupId = groupid.ToGuid(); executeModel.InstanceId = instanceid; executeModel.IsSign = issign.ToInt(0); executeModel.Note = string.Empty; executeModel.OtherType = 0; executeModel.Sender = currentUserModel; executeModel.StepId = stepid.IsGuid(out Guid stepId) ? stepId : flowRunModel.FirstStepId; executeModel.TaskId = taskid.ToGuid(); executeModel.ParamsJSON = paramsJSON; executeModel.Attachment = attachment; List<(Guid, string, Guid?, int?, List, DateTime?)> nextSteps = new List<(Guid, string, Guid?, int?, List, DateTime?)>(); var currentStepModel = flowRunModel.Steps.Find(p => p.Id == executeModel.StepId); if (null == currentStepModel) { throw Oops.Oh("未找到工作流步骤"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowStep"].Value); } JArray stepsArray = paramsObject.Value("steps"); if (null != stepsArray) { Organize organize = new Organize(); FlowEntrust flowEntrust = new FlowEntrust(); UserDummy user = new UserDummy(); List flowReceives = new List();//2021-3-15增加,记录接收人方便下次默认查找。 foreach (JObject stepObject in stepsArray) { string id = stepObject.Value("id"); string name = stepObject.Value("name");//步骤名称 string beforeStepId = stepObject.Value("beforestepid");//原步骤ID(动态步骤的原步骤ID) string parallelorserial = stepObject.Value("parallelorserial");//0并且 1串行 string member = stepObject.Value("member"); string completedTime = stepObject.Value("completedtime"); if (!id.IsGuid(out Guid nextStepId)) { continue; } var nextStepModel = flowRunModel.Steps.Find(p => p.Id == nextStepId); //2021-6-19注释掉了这里的NULL判断,因为动态步骤时这里为空。在下面的判断中再增加null判断。 //if (nextStepModel == null) //{ // continue; //} DateTime? completedDateTime = new DateTime?(); if (completedTime.IsDateTime(out DateTime cTime)) { completedDateTime = cTime; } if (executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Submit || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Back || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Redirect || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.FreeSubmit) { //var userList = organize.GetAllUsers(member); //2021-3-25修改,人员按选择的组织分组。 List userList; //2021-6-19增加了nextStepModel != null判断 if (nextStepModel != null && nextStepModel.StepBase.HanlderModelGroup == 2) { userList = new List(); foreach (string memberId in member.Split(',', StringSplitOptions.RemoveEmptyEntries)) { int userGroup = RoadFlow.Utility.Tools.GetRandomInt(1, 100000); var users = organize.GetAllUsers(memberId); foreach (var userModel in users) { var userModel1 = userModel; // userModel1.QQ = "3" + userGroup.ToString(); userList.Add(userModel1); } } } else { userList = organize.GetAllUsers(member); } //2021-3-25修改完 //2021-1-12增加判断如果发送时选择了人,这里没有获取到人,不提交。(如选择的是部门,工作组而部门或工作组下没有人的情况) if (!member.IsNullOrEmpty() && userList.Count == 0) { throw Oops.Oh("没有接收人"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, name + localizer["NoReceiver"].Value,jObject: new JObject() { { "debugMessage", name + localizer["NoReceiver"].Value } }); } nextSteps.Add((nextStepId, name, beforeStepId.IsGuid(out Guid beforeStepGuid1) ? new Guid?(beforeStepGuid1) : new Guid?(), parallelorserial.IsInt(out int parallelorserialInt1) ? new int?(parallelorserialInt1) : new int?(), userList, completedDateTime)); } //2021-3-15增加,记录接收人方便下次默认查找。 //2021-6-19增加了nextStepModel != null判断 if (nextStepModel != null && nextStepModel.StepBase.LastHadler == 1 && !member.IsNullOrWhiteSpace() && (executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Submit || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.FreeSubmit)) { flowReceives.Add(new RoadFlow.Model.rf_flowreceive() { Id = GuidExtensions.NewGuid().ToString(), FlowId = flowid, StepId = id, SenderId = currentUserModel.Id, SendTime = DateExtensions.Now, Members = member }); } } new RoadFlow.Data.FlowReceive().AddRange(flowReceives);//2021-3-15增加,记录接收人方便下次默认查找。 } executeModel.Steps = nextSteps; #endregion #region 保存业务数据 //判断抄送完成和终止任务不保存数据,如果是系统判断,在点发送时已经保存过了,这里不保存 if ((executeModel.ExecuteType != RoadFlow.Model.FlowRunModel.Execute.Type.CopyforCompleted && executeModel.ExecuteType != RoadFlow.Model.FlowRunModel.Execute.Type.TaskEnd && currentStepModel.StepBase.FlowType != 0 && currentStepModel.StepBase.FlowType != 5) || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Save) { try { var (newInstanceId, errMsg) = _form.SaveDataVue(args, null);// localizer); if (!errMsg.IsNullOrEmpty())//如果有错误信息,则返回,不提交流程。 { _log.Add("处理流程(" + flowRunModel.Name + ")保存数据时发生了错误", errMsg); throw Oops.Oh("数据保存失败"); /*return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["SaveDataError"].Value, jObject: new JObject() { { "debugMessage", errMsg }, });*/ } if (executeModel.InstanceId.IsNullOrWhiteSpace())//如果发起流程没有实例ID,则将新产生的实例ID赋值。 { executeModel.InstanceId = newInstanceId; } } catch (Exception err) { _log.Add(err, "处理流程(" + flowRunModel.Name + ")保存数据时发生了错误"); throw Oops.Oh("数据保存失败"); /* return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["SaveDataError"].Value, jObject: new JObject() { { "debugMessage", flowRunModel.Debug > 0 ? err.Message + err.StackTrace : string.Empty }, });*/ } } #endregion #region 设置任务标题 string taskTitle = string.Empty; if (isCustomeForm) { taskTitle = args.GetJsonValue("form_tasktitle"); } else { string form_dbtabletitleexpression = args.GetJsonValue("form_dbtabletitleexpression");//标题表达式 if (form_dbtabletitleexpression.IsNullOrWhiteSpace()) { taskTitle = args.GetJsonValue(args.GetJsonValue("form_dbtable") + "-" + args.GetJsonValue("form_titlefield")); } else { string tableName = args.GetJsonValue("form_dbtable"); taskTitle = _form.ReplaceTitleExpression(form_dbtabletitleexpression, tableName, executeModel.InstanceId, args); } } executeModel.Title = taskTitle; #endregion //添加动态流程步骤JSON(不是第一步时,第一步在流程提交时添加) if (RoadFlow.Utility.Config.EnableDynamicStep && executeModel.Steps.Exists(p => p.beforeStepId.IsNotEmptyGuid()) && executeModel.TaskId.IsNotEmptyGuid() && executeModel.GroupId.IsNotEmptyGuid()) { var newFlowRunModel = _dynamic.Add(executeModel, groupTasks); if (null != newFlowRunModel) { flowRunModel = newFlowRunModel; } //如果是顺序处理,要删掉后面的步骤。 executeModel.Steps.RemoveAll(p => p.parallelOrSerial.HasValue && p.parallelOrSerial == 1 && p.stepId != p.beforeStepId); } //=================== //执行流程 var executeResult = flowTask.Execute(executeModel, flowRunModel, null); //localizer); #region 提交执行后要自动提交的任务(一般是指子流程完成要自动提交主流程步骤的情况) if (executeResult != null && executeResult.AutoSubmitTasks.Count > 0) { foreach (var autoSubmitTask in executeResult.AutoSubmitTasks) { var autoSubmitResult = flowTask.AutoSubmit(autoSubmitTask.Id.ToGuid()); _log.Add("流程完成后自动提交了任务 - " + (autoSubmitResult.IsSuccess ? "成功" : "失败") + " - " + autoSubmitTask.FlowName + " - " + autoSubmitTask.StepName + " - " + autoSubmitTask.Title, _userManager.UserId, autoSubmitTask.ToString(), LogType.流程运行, others: "执行结果:" + autoSubmitResult.ToString()); } } #endregion #region 归档 if (currentStepModel.Archives == 1 && (executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Submit || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.FreeSubmit || executeModel.ExecuteType == RoadFlow.Model.FlowRunModel.Execute.Type.Completed)) { string formHtml = args.GetJsonValue("archive_formHtml"); string comments = args.GetJsonValue("archive_comments"); //var db = dbs.First(); //string formDataJson = new Business.Form().GetFormData(db.ConnectionId.ToString(), // db.Table, db.PrimaryKey, executeModel.InstanceId, executeModel.StepId.ToString(), executeModel.FlowId.ToString(), // Request.Forms("form_dataformatjson"), out string fieldStatusJSON); string formDataJson = args.GetJsonValue("archive_formDataJSON"); string executeUserId = string.Empty; string executeUserName = string.Empty; if (executeResult.CurrentTask != null) { executeUserId = !executeResult.CurrentTask.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + executeResult.CurrentTask.ReceiveOrganizeId : IOrganize.PREFIX_USER + executeResult.CurrentTask.ReceiveId.ToString(); executeUserName = executeResult.CurrentTask.ReceiveName; } else { executeUserId = IOrganize.PREFIX_USER + executeModel.Sender.Id.ToString(); executeUserName = executeModel.Sender.Name; } //加上本步骤的处理意见 if (executeResult.CurrentTask != null) { string serverUrl = args.GetJsonValue("archive_serverurl"); comments += "
" + "" + "" + (executeModel.Comment.IsNullOrEmpty() ? "" : "") + (executeModel.Attachment.IsNullOrWhiteSpace() ? "" : "") + "
" + /*localizer["Step"].Value*/"步骤" + ":" + executeResult.CurrentTask.StepName + "" + /*localizer["Handler"].Value*/"处理者" + ":" + executeResult.CurrentTask.ReceiveName + "" + //localizer["ReceiveTime"].Value "接收时间" + ":" + executeResult.CurrentTask.ReceiveTime.ToDateTimeString() + "" + "完成时间" //localizer["CompletedTime"].Value + ":" + executeResult.CurrentTask.CompletedTime1.ToDateTimeString() + "" + "处理类型" //localizer["HandleType"].Value + ":" + flowTask.GetExecuteTypeTitle(executeResult.CurrentTask.ExecuteType) + "
" + //localizer["HandleOpinion"].Value "处理选项" + ":" + executeModel.Comment + "") + (executeModel.IsSign == 1 ? "" : "") + (executeModel.Comment.IsNullOrEmpty() ? "" : "
" + "附件" //localizer["Accessories"].Value + ":" + executeModel.Attachment.ToVueFilesShowString(false, serverUrl: serverUrl) + "
"; } RoadFlow.Model.rf_flowarchive flowArchiveModel = new RoadFlow.Model.rf_flowarchive { Comments = comments.Trim(), DataJson = formDataJson, FlowId = flowRunModel.Id.ToString(), FlowName = flowRunModel.Name, Id = GuidExtensions.NewGuid().ToString(), InstanceId = executeModel.InstanceId, StepId = currentStepModel.Id.ToString(), StepName = currentStepModel.Name, TaskId = executeResult.CurrentTask == null ? executeModel.TaskId.ToString() : executeResult.CurrentTask.Id, Title = executeResult.CurrentTask == null ? executeModel.Title : executeResult.CurrentTask.Title, UserId = executeUserId, UserName = executeUserName, WriteTime = DateExtensions.Now, FormHtml = formHtml }; new FlowArchive().Add(flowArchiveModel); } #endregion _log.Add("处理了流程 " + flowRunModel.Name + "] - 步骤 " + flowTask.GetStepName(flowRunModel, executeModel.StepId) + " - 标题 " + executeModel.Title, _userManager.UserId, paramsJSON, LogType.流程运行, oldContents: "执行参数:" + executeModel.ToString(), others: "返回:" + executeResult.ToString()); //如果下一步接收者中有当前人员则直接打开 var nextTask = executeResult.NextTasks?.Find(p => p.ReceiveId == executeModel.Sender.Id && p.Status.In(0, 1)); JObject returnObject = nextTask == null ? new JObject() { { "opation", "close" } } : new JObject() { { "instanceid", nextTask.InstanceId }, { "taskid", nextTask.Id.ToString() }, { "flowid", nextTask.FlowId.ToString() }, { "stepid", nextTask.StepId.ToString() }, { "groupid", nextTask.GroupId.ToString() }, { "title", nextTask.Title }, { "debugMessage", flowRunModel.Debug > 0 ? executeResult.ToString() : string.Empty }, { "opation", "refresh" }, }; return returnObject; // RoadFlowCommon.Tools.GetReturnJsonString(executeResult.IsSuccess, executeResult.Messages, jObject: returnObject); } /// /// 抄送 /// [HttpPost("CopyFor")] public string CopyFor([FromBody] JObject args) { string taskid = args.GetJsonValue("taskId"); string user = args.GetJsonValue("receiveUserId"); var users = new Organize().GetAllUsers(user); if (users.Count == 0) { throw Oops.Oh("未找到接收人"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NoReceiver"].Value); } var taskModel = _flowTask.GetOneById(taskid); string msg = _flowTask.CopyFor(taskModel, users, null); // localizer); return msg == "1" ? "抄送成功" : msg; //return RoadFlowCommon.Tools.GetReturnJsonString("1".Equals(msg), "1".Equals(msg) ? localizer["CopyforSuccessfully"].Value : msg); } /// /// 征求意见 /// /// [HttpPost("SolicitOpinion")] public string SolicitOpinion([FromBody] JObject args) { string taskId = args.GetJsonValue("taskid"); string receiver = args.GetJsonValue("receiver");//接收人 string visibility = args.GetJsonValue("visibility");//意见可见性 string note = args.GetJsonValue("note");//意见说明 if (!taskId.IsGuid(out Guid taskGuid)) { throw Oops.Oh("未找到当前任务"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } //int i = new Business.FlowSolicitOpinion().Solicit(taskGuid, receiver, visibility.ToInt(0), note); //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); string msg = _flowTask.SolicitOpinion(_flowTask.GetOneById(taskGuid.ToString()), new Organize().GetAllUsers(receiver), visibility.ToInt(20), note, null);// localizer); ; return msg == "1" ? "已发起意见征求" : msg; // return RoadFlowCommon.Tools.GetReturnJsonString("1".Equals(msg), "1".Equals(msg) ? localizer["SolicitOpinionSuccessfully"].Value : msg); } /// /// 查询征求意见 /// /// [HttpGet("GetSolicitOpinion")] public dynamic GetSolicitOpinion(string taskId, string serverurl) { if (!taskId.IsGuid(out Guid taskGuid)) { throw Oops.Oh("任务id错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); var taskModel = _flowTask.GetOneById(taskId); if (taskModel == null) { throw Oops.Oh("未找到当前任务错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } if (taskModel.ReceiveId != _userManager.UserId) { throw Oops.Oh("权限错误,无法读取意见征询"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["CannotViewSolicitOpinion"].Value); } var opinionTasks = _flowTask.GetListByGroupId(taskModel.GroupId).FindAll(p => p.PrevId == taskModel.Id && p.TaskType == 11); JArray jArray = new JArray(); foreach (var opinionTask in opinionTasks.OrderByDescending(p => p.CompletedTime1).ThenBy(p => p.ReceiveTime)) { jArray.Add(new JObject() { { "id", opinionTask.Id }, { "name", opinionTask.ReceiveName }, { "sendTime", opinionTask.ReceiveTime.ToShortDateTimeString() }, { "isReturn", opinionTask.Status == 2 ? 1 : 0 }, { "returnTime", opinionTask.CompletedTime1.ToShortDateTimeString() }, { "returnContent", opinionTask.Comments }, { "returnFiles", opinionTask.Attachment.ToVueFilesShowString(isBr:false, serverUrl:serverurl) }, }); } return jArray; //RoadFlowCommon.Tools.GetReturnJsonString(jArray: jArray); } /// /// 验证签章密码 /// /// [HttpPost("ValidPass")] public string ValidPass([FromBody] JObject args) { string pass = args.GetJsonValue("pass"); var userModel = _userManager.User; if (userModel == null || pass.IsNullOrWhiteSpace() || !new UserDummy().GetMD5Password(userModel.Id, pass.Trim()).Equals(userModel.Password)) { throw Oops.Oh("密码错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["PasswordError"].Value); } else { return "密码正确"; //return RoadFlowCommon.Tools.GetReturnJsonString(true); } } /// /// 得到待办列表 /// /// [HttpPost("GetWait")] public dynamic GetWait([FromBody] JObject args) { string title = args.GetJsonValue("title"); string flow = args.GetJsonValue("flow"); string date1 = args.GetJsonValue("date1"); string date2 = args.GetJsonValue("date2"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); bool isMobile = "1".Equals(args.GetJsonValue("ismobile")); string userId = _userManager.UserId; if (order.IsNullOrWhiteSpace()) { order = "ReceiveTime DESC"; } var dt = _flowTask.GetWaitTask(size, number, userId, flow, title, date1, date2, order, out int total); JArray jArray = new JArray(); foreach (var dr in dt) { string status = isMobile ? "" : "" + /*localizer["Normal"].Value*/"正常" + ""; if (dr.CompletedTime != null) { DateTime nowTime = DateExtensions.Now; if (nowTime > dr.CompletedTime) { status = isMobile ? "" + /*localizer["Overdue"].Value */"逾期" + "" : "" +/*localizer["Overdue"].Value */"逾期" + ""; } else if ((dr.CompletedTime - nowTime).Value.Days < 3) { double day = Math.Ceiling((dr.CompletedTime - nowTime).Value.TotalDays); string dsystring = day == 0 ? (dr.CompletedTime - nowTime).Value.Hours + /*localizer["Hour"].Value*/"小时" : day.ToString() + /*localizer["Day"].Value*/"天"; status = isMobile ? "" + dsystring + /*localizer["Expire"].Value*/"有效期" + "" : "" + dsystring + /*localizer["Expire"].Value*/"有效期" + ""; } else { status = isMobile ? "" : "" + /*localizer["Normal"].Value*/"正常" + ""; } } //按钮组,这里用于存放要显示的按钮 JArray buttonArray = new JArray() { { /*localizer["Handle"].Value*/"处理" },{ /*localizer["Process"].Value */ "进行"} }; if (_flowTask.IsDelete(dr.Id))//第一步发起人可以作废 { buttonArray.Add(/*localizer["Nullify"].Value*/"作废"); } string taskTypeStr = _flowTask.GetTaskTypeTitle(dr.TaskType, null);// localizer); string titleNote = taskTypeStr.IsNullOrWhiteSpace() ? string.Empty : "" + taskTypeStr + "";//任务类型 JObject jObject = new JObject() { { "Id", dr.Id }, { "FlowId", dr.FlowId}, { "StepId", dr.StepId}, { "GroupId", dr.GroupId }, { "InstanceId", dr.InstanceId }, { "Title", titleNote + dr.Title }, { "FlowName", dr.FlowName }, { "StepName", dr.StepName}, { "SenderName", dr.SenderName }, { "ReceiveTime", dr.ReceiveTime.ToShortDateTimeString() }, { "CompletedTime", status }, { "Opation", new JObject(){ { "buttons", buttonArray } } }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //return RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 得到已办列表 /// /// [HttpPost("GetCompleted")] public dynamic GetCompleted([FromBody] JObject args) { string title = args.GetJsonValue("title"); string flow = args.GetJsonValue("flow"); string date1 = args.GetJsonValue("date1"); string date2 = args.GetJsonValue("date2"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); string userId = _userManager.UserId; if (order.IsNullOrWhiteSpace()) { order = "CompletedTime1 DESC"; } var dt = _flowTask.GetCompletedTask(size, number, userId, flow, title, date1, date2, order, out int total); JArray jArray = new JArray(); foreach (var dr in dt) { //按钮组,这里用于存放要显示的按钮 JArray buttonArray = new JArray() { //{ localizer["Form"].Value },{ localizer["Process"].Value } { "来自"},{ "处理"} }; bool isHasten = _flowTask.IsHasten(dr.Id, out bool isWithdraw);//是否可以催办, isWithdraw 是否可以撤回 if (isWithdraw) { buttonArray.Add("撤回"/*localizer["Withdraw"].Value*/); } if (isHasten) { buttonArray.Add("催促"/*localizer["Urging"].Value*/); } JObject jObject = new JObject() { { "Id", dr.Id }, { "FlowId", dr.FlowId }, { "StepId", dr.StepId}, { "GroupId", dr.GroupId }, { "Title", dr.Title }, { "InstanceId", dr.InstanceId }, { "FlowName", dr.FlowName }, { "StepName", dr.StepName}, { "SenderName", dr.SenderName }, { "ReceiveTime", dr.ReceiveTime.ToShortDateTimeString() }, { "CompletedTime1", dr.CompletedTime1!=null? dr.CompletedTime1.ToShortDateTimeString() : string.Empty }, { "Opation", new JObject(){ { "buttons", buttonArray } } }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 得到批量处理待办列表 /// /// [HttpPost("GetWaitBatch")] public dynamic GetWaitBatch([FromBody] JObject args) { string title = args.GetJsonValue("title"); string flow = args.GetJsonValue("flow"); string date1 = args.GetJsonValue("date1"); string date2 = args.GetJsonValue("date2"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); string userId = _userManager.UserId; if (order.IsNullOrWhiteSpace()) { order = "ReceiveTime DESC"; } var dt = _flowTask.GetWaitTask(size, number, userId, flow, title, date1, date2, order, out int total, 1); JArray jArray = new JArray(); foreach (var dr in dt) { string status = "" + /*localizer["Normal"].Value*/"正常" + ""; if (dr.CompletedTime != null) { DateTime nowTime = DateExtensions.Now; if (nowTime > dr.CompletedTime) { status = "" + /*localizer["Overdue"].Value */"逾期" + ""; } else if ((dr.CompletedTime - nowTime).Value.Days < 3) { double day = Math.Ceiling((dr.CompletedTime - nowTime).Value.TotalDays); string dsystring = day == 0 ? (dr.CompletedTime - nowTime).Value.Hours + /*localizer["Hour"].Value*/"小时" : day.ToString() + /*localizer["Day"].Value*/"天"; status = "" + dsystring + /*localizer["Expire"].Value*/"有效期" + ""; } else { status = "" + /*localizer["Normal"].Value*/"正常" + ""; } } //按钮组,这里用于存放要显示的按钮 JArray buttonArray = new JArray() { { /*localizer["Handle"].Value*/"处理" },{ /*localizer["Process"].Value */ "进行"} }; if (_flowTask.IsDelete(dr.Id))//第一步发起人可以作废 { buttonArray.Add(/*localizer["Nullify"].Value*/"作废"); } string taskTypeStr = _flowTask.GetTaskTypeTitle(dr.TaskType, null);// localizer); string titleNote = taskTypeStr.IsNullOrWhiteSpace() ? string.Empty : "" + taskTypeStr + "";//任务类型 JObject jObject = new JObject() { { "Id", dr.Id }, { "FlowId", dr.FlowId}, { "StepId", dr.StepId }, { "GroupId", dr.GroupId}, { "InstanceId", dr.InstanceId}, { "Title", titleNote + dr.Title}, { "FlowName", dr.FlowName}, { "StepName", dr.StepName }, { "SenderName", dr.SenderName }, { "ReceiveTime", dr.ReceiveTime.ToDateTimeString() }, { "CompletedTime", status }, { "Opation", new JObject(){ { "buttons", buttonArray } } }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //return RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 查询我发起的流程 /// /// [HttpPost("GetMyStart")] public dynamic GetMyStart([FromBody] JObject args) { string title = args.GetJsonValue("title"); string flow = args.GetJsonValue("flow"); string date1 = args.GetJsonValue("date1"); string date2 = args.GetJsonValue("date2"); string status = args.GetJsonValue("status"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); string userId = _userManager.UserId; if (order.IsNullOrWhiteSpace()) { order = "ReceiveTime DESC"; } var dt = _flowTask.GetMyStartList(size, number, userId, flow, title, date1, date2, status, order, out int total); JArray jArray = new JArray(); foreach (var dr in dt) { JObject jObject = new JObject() { { "Id", dr.Id}, { "FlowId", dr.FlowId}, { "StepId", dr.StepId}, { "GroupId", dr.GroupId}, { "Title", dr.Title }, { "InstanceId", dr.InstanceId}, { "FlowName", dr.FlowName}, { "ReceiveTime", dr.ReceiveTime.ToShortDateTimeString() }, { "StepName", dr.CurrentStepName.ToString().IsNullOrWhiteSpace() ? ""+ /*localizer["Completed"].Value*/"已完成" +"" : dr.CurrentStepName.ToString() }, { "Opation", "" }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 查询已委托的任务 /// /// [HttpPost("GetMyEntrust")] public dynamic GetMyEntrust([FromBody] JObject args) { string title = args.GetJsonValue("title"); string flow = args.GetJsonValue("flow"); string date1 = args.GetJsonValue("date1"); string date2 = args.GetJsonValue("date2"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); string userId = _userManager.UserId; if (order.IsNullOrWhiteSpace()) { order = "ReceiveTime DESC"; } var dt = _flowTask.GetEntrustTask(size, number, userId, flow, title, date1, date2, order, out int total); JArray jArray = new JArray(); foreach (var dr in dt) { bool isEntrustWithdraw = dr.Status < 1; //_flowTask.IsEntrustWithdraw(dr["Id"].ToString().ToGuid());//是否可以撤回 //按钮组,这里用于存放要显示的按钮 JArray buttonArray = new JArray(); if (isEntrustWithdraw) { buttonArray.Add(/*localizer["Withdraw"].Value*/"撤回"); } JObject jObject = new JObject() { { "Id", dr.Id}, { "FlowId", dr.FlowId}, { "StepId", dr.StepId }, { "GroupId", dr.GroupId }, { "Title", dr.Title}, { "FlowName", dr.FlowName }, { "StepName", dr.StepName }, { "SenderName", dr.SenderName }, { "ReceiveTime", dr.ReceiveTime.ToShortDateTimeString() }, { "ReceiveName", dr.ReceiveName }, { "Status", _flowTask.GetExecuteTypeTitle(dr.ExecuteType) }, { "Opation", new JObject(){ { "buttons", buttonArray } } }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 待办批量处理 /// /// [HttpPost("WaitBatchExecute")] public string WaitBatchExecute([FromBody] JObject args) { string[] ids = args.GetJsonValue("taskids").Split(','); string executeType = args.GetJsonValue("executeType"); string comment = args.GetJsonValue("comment"); string serverUrl = args.GetJsonValue("archive_serverurl"); bool isMobile = "1".Equals(args.GetJsonValue("ismobile")) || "1".Equals(args.GetJsonValue("ismobile")); int i = 0; var userModel = _userManager.User; foreach (string id in ids) { if (id.IsGuid(out Guid taskId)) { var executeResultModel = _flowTask.AutoSubmit(taskId, executeType.IsNullOrWhiteSpace() ? "submit" : executeType, comment); if (executeResultModel.IsSuccess) { i++; #region 归档 var currentTask = _flowTask.GetOneById(id); if (currentTask != null) { //查找当前任务是否有动态步骤,有则从动态步骤中取流程运行时 var (dynamicTaskModel, flowTaskModel, groupTasks) = _flowTask.GetDynamicTask(currentTask.GroupId, currentTask.Id); var flowRunModel = _flow.GetFlowRunModel(currentTask.FlowId, true, dynamicTaskModel); var currentStepModel = flowRunModel.Steps.Find(p => p.Id == currentTask.StepId.ToGuid()); if (currentStepModel.Archives == 1) { var dbs = flowRunModel.Databases; if (dbs.Count > 0) { StringBuilder comments = new StringBuilder(); var nowgroupTasks = _flowTask.GetListByGroupId(currentTask.GroupId).FindAll(p => p.Status == 2).OrderBy(p => p.Sort); foreach (var nowtask in nowgroupTasks) { comments.Append("
" + "" + "" + (nowtask.Comments.IsNullOrEmpty() ? "" : "") + (nowtask.Attachment.IsNullOrWhiteSpace() ? "" : "") + "
" + "步骤"/*localizer["Step"].Value*/ + ":" + nowtask.StepName + "" + /*localizer["Handler"].Value*/"处理人" + ":" + nowtask.ReceiveName + "" + /*localizer["ReceiveTime"].Value*/"接收时间" + ":" + nowtask.ReceiveTime.ToDateTimeString() + "" + /*localizer["CompletedTime"].Value*/"完成时间" + ":" + nowtask.CompletedTime1.ToDateTimeString() + "" + /*localizer["HandleType"].Value*/"处理类型" + ":" + _flowTask.GetExecuteTypeTitle(nowtask.ExecuteType) + "
" + /*localizer["HandleOpinion"].Value*/"处理意见" + ":" + nowtask.Comments + "") + (nowtask.IsSign == 1 ? "" : "") + (nowtask.Comments.IsNullOrEmpty() ? "" : "
" + /*localizer["Accessories"].Value*/"附件" + ":" + nowtask.Attachment.ToVueFilesShowString(false, serverUrl: serverUrl) + "
"); } var db = dbs.First(); string executeUserId = string.Empty; string executeUserName = string.Empty; executeUserId = !currentTask.ReceiveOrganizeId.IsNullOrWhiteSpace() ? IOrganize.PREFIX_RELATION + currentTask.ReceiveOrganizeId : IOrganize.PREFIX_USER + currentTask.ReceiveId.ToString(); executeUserName = currentTask.ReceiveName; string formHtml = string.Empty;//表单HTML string formDataJson = string.Empty;//表单数据 var applbiraryModel = _appLibrary.GetOneById(isMobile && currentStepModel.StepForm.MobileId.IsNotEmptyGuid() ? currentStepModel.StepForm.MobileId.ToString() : currentStepModel.StepForm.Id.ToString()); if (applbiraryModel != null && applbiraryModel.Code.IsGuid(out Guid formGuid)) { var formObject = _form.GetRunJObject(formGuid.ToString()); if (formObject != null) { if (formObject.ContainsKey("html")) { formHtml = formObject.Value("html"); } #region 表单数据 JObject formDataObject = new JObject() { { "form_id", formObject.Value("id") }, { "form_dbconnid", formObject.Value("conn") }, { "form_dbtable", formObject.Value("table") }, { "form_dbtableprimarykey", formObject.Value("primaryKey") }, { "form_titlefield", formObject.Value("titleField") }, { "form_dbtabletitleexpression", formObject.Value("titleExpression") }, { "form_instanceid", currentTask.InstanceId }, { "form_fieldstatus", new JObject() }, { "flowid", currentTask.FlowId.ToString() }, { "stepid", currentTask.StepId.ToString() }, { "taskid", currentTask.Id.ToString() }, { "groupid", currentTask.GroupId.ToString() }, }; string formatJson = formObject.ContainsKey("formatJson") ? formObject.Value("formatJson").ToString(Newtonsoft.Json.Formatting.None) : "";//字段显示格式JSON JObject valueTypeObject = formObject.Value("valueTypeJson");//字段值类型JSON JObject defaultValueJson = formObject.Value("defaultValueJson");//默认值JSON //获取表单数据 JArray formDataArray = _form.GetFormData(formObject.Value("conn"), formObject.Value("table"), formObject.Value("primaryKey"), currentTask.InstanceId, currentTask.StepId.ToString() , currentTask.FlowId.ToString(), formatJson, out string fieldStatusJson, currentTask.GroupId.ToString()).ToJArray(); //将归档字段状态全部设置为只读 JArray archiveFieldStatusArray = fieldStatusJson.ToJArray(); JObject archiveFieldStatusObject = new JObject(); if (archiveFieldStatusArray != null) { foreach (var jobject in archiveFieldStatusArray) { archiveFieldStatusObject.Add(jobject.Value("name"), 1); } } formDataObject.Add("archive_fieldStatus", archiveFieldStatusObject.ToString(Newtonsoft.Json.Formatting.None)); foreach (JObject valueObject in formDataArray) { formDataObject.Add(valueObject.Value("name"), valueObject.Value("value")); } if (formDataArray.IsEmptyJArray() && defaultValueJson != null)//是否是第一次加载,判断是否采用默认值。 { foreach (var j in defaultValueJson) { string defaultValue = j.Value.Value(); if (!defaultValue.IsNullOrWhiteSpace()) { //组织通配符obj参数 RoadFlow.Model.FlowRunModel.EventParam eventParam = new RoadFlow.Model.FlowRunModel.EventParam { FlowId = currentTask.FlowId.ToGuid(), FlowRunModel = flowRunModel }; formDataObject.Add(j.Key, RoadFlow.Business.Wildcard.Filter(defaultValue, userModel, eventParam)); } } } #region 数据表格控件数据 if (formObject.ContainsKey("datatableJson")) { foreach (JObject dtObject in formObject.Value("datatableJson")) { string dtId = dtObject.Value("id"); int source = dtObject.Value("source").ToInt(0); string text = dtObject.Value("text"); string conn = dtObject.Value("conn"); if (source == 0 && conn.IsGuid(out Guid connGuid))//SQL { var (rows, cols) = _form.GetDataTablJArray(connGuid.ToString(), RoadFlow.Business.Wildcard.Filter(text, userModel, formDataObject)); formDataObject.Add(dtId, new JObject() { { "rows", rows }, { "cols", cols }, { "selects", new JArray() } }); } if (source == 1)//URL { JObject urlObject; try { urlObject = HttpHelper.HttpGet((Furion.App.HttpContext.Request.IsHttps ? "https://" : "http://") + Furion.App.HttpContext.Request.Host.Value + RoadFlow.Business.Wildcard.Filter(text, userModel, formDataObject)).ToJObject(); } catch { urlObject = null; } if (urlObject != null) { JArray rowsArray = new JArray(); try { rowsArray = urlObject.ContainsKey("rows") ? urlObject.Value("rows") : new JArray(); } catch { } JArray colssArray = new JArray(); try { colssArray = urlObject.ContainsKey("cols") ? urlObject.Value("cols") : new JArray(); } catch { } formDataObject.Add(dtId, new JObject() { { "rows", rowsArray }, { "cols", colssArray }, { "selects", new JArray() } }); } else { formDataObject.Add(dtId, new JObject() { { "rows", new JArray() }, { "cols", new JArray() }, { "selects", new JArray() } }); } } } } #endregion #region 子表 JArray subTableJarray = formObject.Value("subtableJson"); if (subTableJarray != null) { foreach (JObject sdtObject in subTableJarray) { string subDtId = sdtObject.Value("id"); JArray sRows = _form.GetSubTableJarray(sdtObject, formObject.Value("conn"), currentTask.InstanceId); if (formDataObject.ContainsKey(id)) { formDataObject[subDtId] = new JObject() { { "rows", sRows } }; } else { formDataObject.Add(subDtId, new JObject() { { "rows", sRows } }); } } //默认值 formDataObject.Add("subtableDefaultValue", _form.GetSubTableDefaultValueJArray(subTableJarray, userModel)); } #endregion formDataJson = formDataObject.ToString(Newtonsoft.Json.Formatting.None); #endregion } } RoadFlow.Model.rf_flowarchive flowArchiveModel = new RoadFlow.Model.rf_flowarchive { Comments = comments.ToString(), DataJson = formDataJson, FlowId = flowRunModel.Id.ToString(), FlowName = flowRunModel.Name, Id = Guid.NewGuid().ToString(), InstanceId = currentTask.InstanceId, StepId = currentStepModel.Id.ToString(), StepName = currentStepModel.Name, TaskId = currentTask.Id, Title = currentTask.Title, UserId = executeUserId, UserName = executeUserName, WriteTime = DateExtensions.Now, FormHtml = formHtml }; _flowArchive.Add(flowArchiveModel); } } } #endregion } else { _log.Add("批量提交待办事项发生了错误 - " + executeResultModel.Messages, _userManager.UserId, executeResultModel.ToString(), LogType.流程运行); } } } return "成功处理" + i.ToString() + "条"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["HandleSuccess"].Value + i.ToString() + localizer["TodoItems"].Value); } /// /// 作废待办 /// /// [HttpGet("DeleteTask")] public string DeleteTask(string deltaskid) { if (!deltaskid.IsGuid(out Guid taskId)) { throw Oops.Oh("任务id错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } var taskModel = _flowTask.GetOneById(deltaskid); if (null == taskModel) { throw Oops.Oh("未找到当前任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["NotFoundCurrentTask"].Value); } _flowTask.DeleteByGroupId(taskModel.GroupId); var flowrunModel = _flow.GetFlowRunModel(taskModel.FlowId); if (null == flowrunModel) { throw Oops.Oh("未找到执行对象"); // return RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["NotFoundFlowRunModel"].Value); } var stepModel = flowrunModel.Steps.Find(p => p.Id == taskModel.StepId.ToGuid()); if (null == stepModel) { //return RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["NotFoundFlowStep"].Value); } var applibrary = _appLibrary.GetOneById(stepModel.StepForm.Id.ToString()); if (null != applibrary && applibrary.Code.IsGuid(out Guid formId)) { _form.DeleteFormData(formId.ToString(), taskModel.InstanceId);//, localizer: localizer); } return "成功作废"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["NullifySuccessfully"].Value); } /// /// 撤回 /// /// [HttpGet("Withdraw")] public string Withdraw(string taskId , string groupId) { if (!taskId.IsGuid(out Guid taskGuid) || !groupId.IsGuid(out Guid groupGuid)) { throw Oops.Oh("参数错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ParameterError"].Value); } var groupTasks = _flowTask.GetListByGroupId(groupId); var taskModel = groupTasks.Find(p => p.Id == taskId); if (taskModel == null) { throw Oops.Oh("未找到当前任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } if (taskModel.ReceiveId != _userManager.UserId) { throw Oops.Oh("您无权处理当前任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["YourCannotHandleTask"].Value); } var tasks = groupTasks.FindAll(p => p.PrevId == taskGuid.ToString() && p.Status <= 0); if (tasks.Count == 0) { throw Oops.Oh("不能撤销"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["CannotWithdraw"].Value); } List removeTasks = new List(); foreach (var task in tasks) { removeTasks.Add(task); } List updateTasks = new List(); var currentTask = groupTasks.Find(p => p.Id == taskGuid.ToString()); if (null == currentTask) { throw Oops.Oh("未找到当前任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } currentTask.Status = 0; currentTask.ExecuteType = 0; currentTask.Comments = ""; currentTask.IsSign = 0; currentTask.CompletedTime1 = new DateTime?(); updateTasks.Add(currentTask); #region 撤回要判断是否有步骤退回前事件 var flowRunModel = _flow.GetFlowRunModel(currentTask.FlowId); var currentStep = flowRunModel?.Steps.Find(p => p.Id == currentTask.StepId.ToGuid()); List<(string, object[], int)> executeSqls = new List<(string, object[], int)>(); RoadFlow.Model.FlowRunModel.EventParam eventParam = new RoadFlow.Model.FlowRunModel.EventParam { FlowId = currentTask.FlowId.ToGuid(), StepId = currentTask.StepId.ToGuid(), FlowRunModel = flowRunModel, GroupId = currentTask.GroupId.ToGuid(), InstanceId = currentTask.InstanceId, TaskId = currentTask.Id.ToGuid(), TaskTitle = currentTask.Title }; if (currentStep != null) { if (!currentStep.StepEvent.BackBefore.IsNullOrWhiteSpace()) { if (currentStep.StepEvent.BackBefore.Trim().StartsWith("[sql]")) { //如果是以[sql]开头,则说明是SQL语句 object[] objects = new object[] { eventParam.TaskId, eventParam.InstanceId, eventParam.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(currentStep.StepEvent.BackBefore.Trim(), null, null).TrimStart("[sql]".ToCharArray()), objects, 0)); } else { var (eventReturn, err) = RoadFlow.Utility.Tools.ExecuteMethod(currentStep.StepEvent.BackBefore.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.流程运行); } } } //退回后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, null).TrimStart("[sql]".ToCharArray()), objects, 1)); } //退回通过后sql if (!currentStep.StepEvent.BackPassAfter.IsNullOrWhiteSpace() && currentStep.StepEvent.BackPassAfter.Trim().StartsWith("[sql]")) { //如果是以[sql]开头,则说明是SQL语句 object[] objects = new object[] { eventParam.TaskId, eventParam.InstanceId, eventParam.GroupId }; executeSqls.Add((RoadFlow.Business.Wildcard.Filter(currentStep.StepEvent.BackPassAfter.Trim(), null, null).TrimStart("[sql]".ToCharArray()), objects, 1)); } } #endregion _flowTask.Update(removeTasks, updateTasks, null, executeSqls); #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.流程运行); } } //退回通过后事件 if (!currentStep.StepEvent.BackPassAfter.IsNullOrWhiteSpace() && !currentStep.StepEvent.BackPassAfter.Trim().StartsWith("[sql]")) { var (eventReturn, err) = Tools.ExecuteMethod(currentStep.StepEvent.BackPassAfter.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 return "撤回成功"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["WithdrawSuccessfully"].Value); } /// /// 撤回已委托的任务 /// /// [HttpGet("WithdrawEntrust")] public string WithdrawEntrust(string taskid) { if (!taskid.IsGuid(out Guid tid)) { throw Oops.Oh("任务id错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } var taskModel = _flowTask.GetOneById(taskid); if (null == taskModel) { throw Oops.Oh("未找到当前任务"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } if (taskModel.EntrustUserId.IsNullOrWhiteSpace()) { throw Oops.Oh("并非委托任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIsNotWtTask"].Value); } taskModel.ReceiveId = taskModel.EntrustUserId; taskModel.ReceiveName = _userDummy.Get(taskModel.EntrustUserId).Name; taskModel.EntrustUserId = new Guid?().ToString(); taskModel.Note = ""; _flowTask.Update(taskModel); return "撤回成功"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["WithdrawSuccessfully1"].Value); } /// /// 得到催办信息 /// /// [HttpGet("GetHastenInfo")] public dynamic GetHastenInfo(string taskId, string groupId) { if (!taskId.IsGuid(out Guid taskGuid) || !groupId.IsGuid(out Guid groupGuid)) { throw Oops.Oh("参数错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ParameterError"].Value); } //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); //得到可以催办的人员 var groupTasks = _flowTask.GetListByGroupId(groupId); var hastenTasks = groupTasks.FindAll(p => p.PrevId == taskId && p.Status.In(0, 1)); if (hastenTasks.Count == 0) { throw Oops.Oh("参数错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ParameterError"].Value); } JObject jObject = new JObject(); JArray jArray = new JArray(); foreach (var task in hastenTasks) { JObject jObject1 = new JObject { { "value", task.ReceiveId }, { "title", task.ReceiveName } }; if (task.Status.In(0, 1) && !jArray.Contains(jObject1)) { jArray.Add(jObject1); } } jObject.Add("users", jArray); jObject.Add("contents", /*localizer["YourHasTodoTask"].Value*/"您有待处理的任务" + hastenTasks.FirstOrDefault().Title + "你有待处理任务" /*localizer["YourHasTodoTaskHandle"].Value*/); return jObject; //return RoadFlowCommon.Tools.GetReturnJsonString(true, jObject: jObject); } /// /// 保存催办 /// /// [HttpPost("SaveHasten")] public string SaveHasten([FromBody] JObject args) { string userId = args.GetJsonValue("UserId"); string type = args.GetJsonValue("Type"); string contents = args.GetJsonValue("Contents"); string groupId = args.GetJsonValue("GropuId"); string taskId = args.GetJsonValue("TaskId"); //得到可以催办的人员 var groupTasks = _flowTask.GetListByGroupId(groupId); var hastenTasks = groupTasks.FindAll(p => p.PrevId == taskId && p.Status.In(0, 1)); List hastenTasks1 = new List(); foreach (string user in userId.Split(',')) { if (!user.IsGuid(out Guid userGuid)) { continue; } var taskModel = hastenTasks.Find(p => p.ReceiveId == user); if (taskModel != null && !hastenTasks1.Exists(p => p.ReceiveId == user)) { hastenTasks1.Add(taskModel); } } _flowTask.SendMessage(hastenTasks1, _userManager.User, type, contents); return "催办成功"; //return RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["UrgingSuccessfully"].Value); } /// /// 得到处理过程 /// /// [HttpGet("GetProcess")] public dynamic GetProcess(string groupId, string stepId, string serverurl, string stringissubflow) { bool isSubFlow = "1".Equals(stringissubflow);//是否是查看子流程 if (!groupId.IsGuid(out Guid groupGuid)) { throw Oops.Oh("参数错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ParameterError"].Value); } //Guid userId = Current.GetUserId(Request); string userId = _userManager.UserId; //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); //RoadFlow.Business.User user = new RoadFlow.Business.User(); //RoadFlow.Business.Organize organize = new RoadFlow.Business.Organize(); //RoadFlow.Business.FileManage fileManage = new RoadFlow.Business.FileManage(); List groupTasks; if (isSubFlow) { var gTasks = _flowTask.GetListByGroupId(groupId).OrderByDescending(p => p.Sort).Where(p => p.SubFlowGroupId.IsGuid() && p.StepId == stepId); groupTasks = gTasks.Any() ? _flowTask.GetListByGroupId(gTasks.FirstOrDefault().SubFlowGroupId) : new List(); } else { groupTasks = _flowTask.GetListByGroupId(groupId); } if (_flowTask.IsOpenProcess(userId, groupTasks) == -1) { throw Oops.Oh("无法查看进程"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["CannotViewProcess"].Value); } JArray jArray = new JArray(); foreach (var task in groupTasks) { //如果是征求意见并且仅征求人自己可见,则不显示。 if (task.TaskType == 11 && task.OtherType == 20 && task.SenderId != userId && task.ReceiveId != userId) { continue; } JObject jObject = new JObject() { { "Id", task.Id.ToString() }, { "FlowId", task.FlowId.ToString() }, { "StepId", task.StepId.ToString() }, { "StepName", task.StepName }, { "SenderName", task.SenderName }, { "ReceiveTime", task.ReceiveTime.ToShortDateTimeString() }, { "ReceiveName", task.ReceiveName }, { "TaskType", task.TaskType }, { "OtherType", task.OtherType }, //{ "ReceiveOrg", task.ReceiveOrganizeId.HasValue ? organize.GetParentsName(task.ReceiveOrganizeId.Value, false) : user.GetOrganizeMainShowHtml(task.ReceiveId, false) }, { "ReceiveOrg", "" }, { "CompletedTime1", task.CompletedTime1.HasValue ? task.CompletedTime1.Value.ToShortDateTimeString() : string.Empty }, { "Status", _flowTask.GetExecuteTypeTitle(task.ExecuteType,null) },// localizer) }, { "Status1", task.Status }, { "ExecuteType", task.ExecuteType }, { "Comments", task.Comments }, //{ "Attachment", task.Attachment.ToVueFilesShowString(isBr:false, serverUrl:serverurl) }, { "Attachment", "" },//fileManage.GetFileShowArray(task.Attachment, RoadFlow.Business.FileManage.RootPath, serverurl) }, { "IsSign", task.IsSign }, { "Note", task.Note }, }; if (task.IsSign == 1) { //签章图片地址 var userModel = _userDummy.Get(task.ReceiveId); jObject.Add("SignSrc", userModel == null ? "" : _userDummy.GetSignSrcVue(userModel.Id.ToString(), userModel.Name)); } jArray.Add(jObject); } //dynamicStep作为区分是否是动态步骤 的msg返回 步骤id|groupid。 var dynamicStep = groupTasks.Find(p => !p.BeforeStepId.IsNullOrWhiteSpace() && p.BeforeStepId.IsNullOrWhiteSpace()); return jArray; //return RoadFlowCommon.Tools.GetReturnJsonString(true, dynamicStep == null ? "" : dynamicStep.BeforeStepId.Value.ToString() + "|" + dynamicStep.GroupId.ToString(), jArray: jArray); } /// /// 得到一个步骤的后续步骤 /// /// [HttpGet("GetNextSteps")] public dynamic GetNextSteps(string stepId, string flowId, string taskId, string groupId) { if (!flowId.IsGuid(out Guid flowGuid)) { throw Oops.Oh("工作流ID错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } if (!taskId.IsGuid()) { throw Oops.Oh("请先保存任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FirstSaveTask"].Value); } var flowRunModel = _flow.GetFlowRunModel(flowId); if (null == flowRunModel) { throw Oops.Oh("未找到流程执行对象"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowRunModel"].Value); } if (!stepId.IsGuid(out Guid stepGuid)) { stepGuid = flowRunModel.FirstStepId; } var nextSteps = _flow.GetAllNextSteps(flowRunModel, stepGuid); JArray jArray = new JArray(); var nextStepsHandle = _flowTask.GetNextStepsHandle(_flowTask.GetListByGroupId(groupId)); foreach (var step in nextSteps) { jArray.Add(new JObject() { { "id", step.Id }, { "name", step.Name }, { "member", nextStepsHandle.ContainsKey(step.Id) ? nextStepsHandle[step.Id] : string.Empty }, //已经设置的人员 }); } return jArray; //RoadFlowCommon.Tools.GetReturnJsonString(true, jArray: jArray); } /// /// 保存指定的步骤处理人 /// /// [HttpPost("SaveStepsProcessor")] public string SaveStepsProcessor([FromBody] JObject args) { int length = args.GetJsonValue("length").ToInt(0);//("length").ToInt(0); string taskId = args.GetJsonValue("taskid"); if (!taskId.IsGuid(out Guid taskGuid)) { throw Oops.Oh("任务id错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } //Business.FlowTask flowTask = new Business.FlowTask(); var taskModel = _flowTask.GetOneById(taskId); if (null == taskModel) { throw Oops.Oh("未找到当前任务"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } JArray jArray = new JArray(); for (int i = 0; i < length; i++) { string id = args.GetJsonValue(i.ToString() + "[id]"); string member = args.GetJsonValue(i.ToString() + "[member]"); JObject jObject = new JObject { { "stepId", id }, { "handle", member } }; jArray.Add(jObject); } taskModel.NextStepsHandle = jArray.ToString(Newtonsoft.Json.Formatting.None); _flowTask.Update(taskModel); return "设置成功"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["SetSuccessfully"].Value); } /// /// 得到当前任务主流程信息 /// /// [HttpGet("GetMainFlowInfo")] public dynamic GetMainFlowInfo(string taskId) { if (!taskId.IsGuid(out Guid taskGuid)) { throw Oops.Oh("任务ID错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } // RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); var taskModel = _flowTask.GetOneById(taskId); if (taskModel == null) { throw Oops.Oh("未找到当前任务"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } var tasks = _flowTask.GetListBySubFlowGroupId(taskModel.GroupId); if (tasks.Count == 0) { throw Oops.Oh("未找到主流程"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundMainFlow"].Value); } var task = tasks.FirstOrDefault(); JObject jObject = new JObject() { { "Id", task.Id.ToString() }, { "FlowId", task.FlowId.ToString() }, { "StepId", task.StepId.ToString() }, { "InstanceId", task.InstanceId }, { "GroupId", task.GroupId } }; return jObject; //RoadFlowCommon.Tools.GetReturnJsonString(true, jObject: jObject); } #endregion #region 实例管理 /// /// 查询实例管理列表 /// /// [HttpPost("GetInstanceManage")] public dynamic GetInstanceManage([FromBody] JObject args) { string FlowId = args.GetJsonValue("FlowId"); string Title = args.GetJsonValue("Title"); string ReceiveId = args.GetJsonValue("ReceiveId"); string Date1 = args.GetJsonValue("date1"); string Date2 = args.GetJsonValue("date2"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); string userId = _userManager.UserId; if (order.IsNullOrWhiteSpace()) { order = "ReceiveTime DESC"; } if (FlowId.IsNullOrWhiteSpace()) { FlowId = _flow.GetManageInstanceFlowIds(userId).JoinSqlIn(); } var dt = _flowTask.GetInstanceList(size, number, FlowId, Title, ReceiveId.RemoveUserPrefix(), Date1, Date2, order, out int total); JArray jArray = new JArray(); foreach (var dr in dt) { JObject jObject = new JObject() { { "Id", dr.Id }, { "FlowId", dr.FlowId}, { "StepId", dr.StepId }, { "GroupId", dr.GroupId}, { "Title", dr.Title }, { "FlowName", dr.FlowName}, { "StepName", dr.StepName }, { "ReceiveName", dr.ReceiveName}, { "ReceiveTime",dr.ReceiveTime.ToShortDateTimeString() }, { "ExecuteType", _flowTask.GetExecuteTypeTitle(dr.ExecuteType) }, { "Opation", "" }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //return RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 得到实例管理的任务列表 /// /// [HttpGet("GetInstanceManageTasks")] public dynamic GetInstanceManageTasks(string groupId) { if (!groupId.IsGuid(out Guid groupGuid)) { throw Oops.Oh("参数错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ParameterError"].Value); } var groupTasks = _flowTask.GetListByGroupId(groupId); JArray jArray = new JArray(); foreach (var task in groupTasks) { //按钮组,这里用于存放要显示的按钮 JArray buttonArray = new JArray() { //{ localizer["Status"].Value },{ localizer["Process"].Value } { "状态"},{ "处理"} }; if (task.ExecuteType.In(0, 1) && 5 != task.TaskType && 11 != task.TaskType) { buttonArray.Add("设计");//localizer["TaskType_Designate"].Value); buttonArray.Add("前往");// localizer["TaskType_Goto"].Value); } buttonArray.Add("删除");// localizer["Delete"].Value); JObject jObject = new JObject() { { "Id", task.Id.ToString() }, { "StepId", task.StepId.ToString() }, { "StepName", task.StepName }, { "SenderName", task.SenderName }, { "ReceiveTime", task.ReceiveTime.ToDateTimeString() }, { "ReceiveName", task.ReceiveName }, { "CompletedTime1", task.CompletedTime1.ToDateTimeString() }, { "ExecuteType", task.ExecuteType }, { "Status", _flowTask.GetExecuteTypeTitle(task.ExecuteType) }, { "Note", task.Note }, { "Opation", new JObject(){ { "buttons", buttonArray } } }, }; jArray.Add(jObject); } return jArray; //RoadFlowCommon.Tools.GetReturnJsonString(true, jArray: jArray); } /// /// 改变任务状态 /// /// [HttpPost("ChageTaskStatus")] public string ChageTaskStatus([FromBody] JObject args) { string taskId = args.GetJsonValue("taskId"); string executeType = args.GetJsonValue("executeType"); if (!taskId.IsGuid(out Guid taskGuid) || !executeType.IsInt(out int executeTypeInt)) { throw Oops.Oh("参数错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["ParameterError"].Value); } //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); var taskModel = _flowTask.GetOneById(taskId); if (taskModel == null) { throw Oops.Oh("未找到当前任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } int oldStatus = taskModel.ExecuteType; taskModel.ExecuteType = executeTypeInt; if (executeTypeInt < 2) { taskModel.Status = executeTypeInt; } else { taskModel.Status = 2; } _flowTask.Update(taskModel); _log.Add("改变了任务状态-" + taskModel.Title,_userManager.UserId, taskModel.Id.ToString(), LogType.流程运行, "旧状态:" + oldStatus, "新状态:" + taskModel.ExecuteType); return "状态改变成功"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["StatusChangeSuccessfully"].Value); } /// /// 删除单条任务(仅删除task,不删除表单数据等其它) /// /// [HttpGet("DeleteOneTask")] public string DeleteOneTask(string deltaskid) { if (!deltaskid.IsGuid(out Guid taskId)) { throw Oops.Oh("任务ID错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); var taskModel = _flowTask.GetOneById(deltaskid); if (null == taskModel) { throw Oops.Oh("未找到当前任务"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } _flowTask.DeleteBy(x=>x.Id==deltaskid); _log.Add("管理员删除了流程任务-" + taskModel.Title + "-" + taskModel.Id,_userManager.UserId ,taskModel.ToString(), LogType.流程运行); return "删除成功"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["DeleteSuccessfully"].Value); } /// /// 指派任务 /// /// [HttpPost("DesignateTask")] public string DesignateTask([FromBody] JObject args) { string taskid = args.GetJsonValue("taskId"); string user = args.GetJsonValue("UserId"); if (!taskid.IsGuid(out Guid taskId)) { throw Oops.Oh("任务ID错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } if (user.IsNullOrWhiteSpace()) { throw Oops.Oh("未选择指派用户"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NoSelectDesignateUser"].Value); } //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); var taskModel = _flowTask.GetOneById(taskid); if (null == taskModel) { throw Oops.Oh("未找到当前用户"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } string msg = _flowTask.Designate(taskModel, _organize.GetAllUsers(user), null);//localizer); _log.Add("指派了任务-" + taskModel.Title,_userManager.UserId ,taskModel.ToString() + "-" + msg, LogType.流程运行, others: user); if (msg == "1") return "指派成功"; else throw Oops.Oh(msg); //RoadFlowCommon.Tools.GetReturnJsonString("1".Equals(msg), "1".Equals(msg) ? localizer["DesignateSuccessfully"].Value : msg); } /// /// 得到要跳转的步骤 /// /// [HttpGet("GetGotoSteps")] public dynamic GetGotoSteps(string taskid) { if (!taskid.IsGuid(out Guid taskId)) { throw Oops.Oh("任务ID错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } var taskModel = _flowTask.GetOneById(taskid); if (null == taskModel) { throw Oops.Oh("未找到当前任务"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } var flowRunModel = _flow.GetFlowRunModel(taskModel.FlowId); if (null == flowRunModel) { throw Oops.Oh("未找到当前任务步骤"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundFlowRunModel"].Value); } JArray jArray = new JArray(); foreach (var step in flowRunModel.Steps) { jArray.Add(new JObject() { { "id", step.Id }, { "name", step.Name }, { "users", "" }, }); } return jArray;// RoadFlowCommon.Tools.GetReturnJsonString(true, jArray: jArray); } /// /// 跳转任务 /// /// [HttpPost("GotoTask")] public string GotoTask([FromBody] JObject args) { string taskid = args.GetJsonValue("taskId"); string steps = args.GetJsonValue("steps"); if (!taskid.IsGuid(out Guid taskId)) { throw Oops.Oh("任务ID错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["TaskIdError"].Value); } //RoadFlow.Business.FlowTask flowTask = new RoadFlow.Business.FlowTask(); var taskModel = _flowTask.GetOneById(taskid); if (null == taskModel) { throw Oops.Oh("未找到当前任务"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundCurrentTask"].Value); } Dictionary> dicts = new Dictionary>(); JArray stepsArray = JArray.Parse(steps); foreach (JObject stepObject in stepsArray) { string stepId = stepObject.Value("id"); if (!stepId.IsGuid(out Guid stepGuid)) { continue; } string member = stepObject.Value("users"); if (member.IsNullOrWhiteSpace()) { continue; } dicts.Add(stepGuid, _organize.GetAllUsers(member)); } string msg = _flowTask.GoTo(taskModel, dicts, null);// localizer); _log.Add("跳转了任务-" + taskModel.Title,_userManager.UserId ,taskModel.ToString() + "-" + msg, LogType.流程运行, others: Newtonsoft.Json.JsonConvert.SerializeObject(dicts)); if (msg == "1") return "跳转成功"; else throw Oops.Oh(msg); //return RoadFlowCommon.Tools.GetReturnJsonString("1".Equals(msg), "1".Equals(msg) ? localizer["GotoSuccessfully"].Value : msg); } /// /// 删除实例 /// /// [HttpGet("DeleteInstance")] public string DeleteInstance(string groupId, string taskId) { if (!groupId.IsGuid(out Guid guid)) { throw Oops.Oh("组ID错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["GroupidError"].Value); } var groupTasks = _flowTask.GetListByGroupId(groupId); if (groupTasks.Count > 0) { _flowTask.DeleteByGroupId(groupId);// groupTasks.ToArray()); _log.Add("管理员删除了流程实例-" + groupTasks.First().Title,_userManager.UserId,Newtonsoft.Json.JsonConvert.SerializeObject(groupTasks), LogType.流程运行); } //删除实例对应的业务表数据 if (taskId.IsGuid(out Guid taskGuid)) { var taskModel = groupTasks.Find(p => p.Id == taskId); if (taskModel != null) { var flowrunModel = _flow.GetFlowRunModel(taskModel.FlowId); if (null == flowrunModel) { throw Oops.Oh("未找到流程模型"); // return RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["NotFoundFlowRunModel"].Value); } var stepModel = flowrunModel.Steps.Find(p => p.Id == taskModel.StepId.ToGuid()); if (null == stepModel) { //return RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["NotFoundFlowStep"].Value); } var applibrary = _appLibrary.GetOneById(stepModel.StepForm.Id.ToString()); if (null != applibrary && applibrary.Code.IsGuid(out Guid formId)) { _form.DeleteFormData(formId.ToString(), taskModel.InstanceId,null, isVue: true); //localizer: localizer, } } } return "删除成功"; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["DeleteSuccessfully"].Value); } #endregion #region 归档查询 /// /// 归档查询 /// /// [HttpPost("GetArchives")] public dynamic GetArchives([FromBody] JObject args) { string FlowId = args.GetJsonValue("FlowId"); string StepName = args.GetJsonValue("StepName"); string Title = args.GetJsonValue("Title"); string date1 = args.GetJsonValue("date1"); string date2 = args.GetJsonValue("date2"); int number = args.GetJsonValue("number").ToInt(); int size = args.GetJsonValue("size").ToInt(); string order = args.GetJsonValue("order"); if (order.IsNullOrWhiteSpace()) { order = "WriteTime DESC"; } var dt = _flowArchive.GetPagerData(out int total, size, number, FlowId, StepName, Title, date1, date2, order); JArray jArray = new JArray(); foreach (var dr in dt) { JObject jObject = new JObject() { { "Id", dr.Id }, { "Title", dr.Title}, { "FlowName", dr.FlowName}, { "StepName", dr.StepName }, { "WriteTime", dr.WriteTime.ToShortDateTimeString() }, { "UserName", dr.UserName }, { "Opation", "" }, }; jArray.Add(jObject); } JObject json = new JObject() { { "total", total } }; json.Add("rows", jArray); return json; //RoadFlowCommon.Tools.GetReturnJsonString(jObject: json); } /// /// 查询一条归档 /// /// [HttpGet("GetArchive")] public dynamic GetArchive(string archiveid) { if (!archiveid.IsGuid(out Guid archiveGuid)) { throw Oops.Oh("Id错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["IdError"].Value); } var archiveModel = _flowArchive.GetOneById(archiveid); if (archiveModel == null) { throw Oops.Oh("未找到归档"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["NotFoundArchive"].Value); } return archiveModel.ToJObject(); //RoadFlowCommon.Tools.GetReturnJsonString(true, jObject: archiveModel.ToJObject()); } #endregion #region 直接保存表单 /// /// 得到流程运行时加载的数据 /// /// [HttpPost("GetEditRun")] public dynamic GetEditRun([FromBody] JObject args) { string applibraryId = args.GetJsonValue("applibraryid"); string instanceId = args.GetJsonValue("instanceid"); string programId = args.GetJsonValue("programid"); string previewFormId = args.GetJsonValue("previewformid");//预览表单ID,预览表单时有用。 bool isDisplay = "1".Equals(args.GetJsonValue("display")); string flowId = args.GetJsonValue("flowid"); string stepId = args.GetJsonValue("stepid"); string subtableName = args.GetJsonValue("subtablelinkfield").Split('-')[0];//子表弹出编辑模式的子表名称。 bool isSubtablePopup = !subtableName.IsNullOrWhiteSpace() && !args.GetJsonValue("subtableid").IsNullOrWhiteSpace();//是否是子表弹出编辑模式 Guid previewFormGuid = previewFormId.ToGuid(); if (!applibraryId.IsGuid(out Guid applibraryGuid) && previewFormGuid.IsEmptyGuid()) { throw Oops.Oh(previewFormGuid.IsEmptyGuid() ? programId.IsGuid() ? "未设置表格" : "首次保存预览" : "Appid错误"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, previewFormGuid.IsEmptyGuid() ? programId.IsGuid() ? localizer["NoSetForm"].Value : localizer["FirstSavePreview"].Value : localizer["AppIdError"].Value); } SysUser userModel = _userManager.User; #region 组织表单 JObject formObject = new JObject(); if (previewFormGuid.IsNotEmptyGuid())//预览表单 { string attrJson = args.GetJsonValue("attrjson"); string eventJson = args.GetJsonValue("eventjson"); formObject = _form.GetRunJObject(previewFormGuid.ToString(), attrJson, eventJson); } else { var appModel = _appLibrary.GetOneById(applibraryGuid.ToString()); if (appModel != null) { if (appModel.Code.IsGuid(out Guid formId)) { formObject = _form.GetRunJObject(appModel.Code); } else { formObject.Add("form_iscustomeform", 1);//0设计表单 1自定义表单 formObject.Add("url", appModel.Address); } } } #endregion #region 表单及数据 JObject formDataObject = new JObject() { { "form_id", formObject.Value("id") }, { "form_dbconnid", formObject.Value("conn") }, { "form_dbtable", formObject.Value("table") }, { "form_dbtableprimarykey", formObject.Value("primaryKey") }, { "form_titlefield", formObject.Value("titleField") }, { "form_dbtabletitleexpression", formObject.Value("titleExpression") }, { "form_instanceid", instanceId }, { "form_fieldstatus", new JObject() }, { "applibraryid", applibraryId }, }; JObject statusObject = new JObject();//字段状态 JObject checkObject = new JObject();//字段检查 string formatJson = formObject.ContainsKey("formatJson") ? formObject.Value("formatJson").ToString(Newtonsoft.Json.Formatting.None) : "[]";//字段显示格式JSON JObject valueTypeObject = formObject.ContainsKey("valueTypeJson") ? formObject.Value("valueTypeJson") : new JObject();//字段值类型JSON JObject defaultValueJson = formObject.ContainsKey("defaultValueJson") ? formObject.Value("defaultValueJson") : new JObject();//默认值JSON //获取表单数据 JArray formDataArray = _form.GetFormData(formObject.Value("conn"), formObject.Value("table"), formObject.Value("primaryKey"), instanceId, stepId , programId.IsGuid() ? string.Empty : flowId, formatJson, out string fieldStatusJson).ToJArray(); foreach (JObject valueObject in formDataArray) { formDataObject.Add(valueObject.Value("name"), valueObject.Value("value")); } if (formDataArray.IsEmptyJArray())//是否是第一次加载,判断是否采用默认值。 { foreach (var j in defaultValueJson) { string defaultValue = j.Value.Value(); if (!defaultValue.IsNullOrWhiteSpace()) { formDataObject.Add(j.Key, RoadFlow.Business.Wildcard.Filter(defaultValue, userModel)); } } } #region 数据表格控件数据 foreach (JObject dtObject in formObject.ContainsKey("datatableJson") ? formObject.Value("datatableJson") : new JArray()) { string id = dtObject.Value("id"); int source = dtObject.Value("source").ToInt(0); string text = dtObject.Value("text"); string conn = dtObject.Value("conn"); if (source == 0 && conn.IsGuid(out Guid connGuid))//SQL { var (rows, cols) = _form.GetDataTablJArray(connGuid.ToString(), RoadFlow.Business.Wildcard.Filter(text, userModel, formDataObject)); formDataObject.Add(id, new JObject() { { "rows", rows }, { "cols", cols }, { "selects", new JArray() } }); } if (source == 1)//URL { JObject urlObject; try { urlObject = HttpHelper.HttpGet((Furion.App.HttpContext.Request.IsHttps ? "https://" : "http://") + Furion.App.HttpContext.Request.Host.Value + RoadFlow.Business.Wildcard.Filter(text, userModel, formDataObject)).ToJObject(); } catch { urlObject = null; } if (urlObject != null) { JArray rowsArray = new JArray(); try { rowsArray = urlObject.ContainsKey("rows") ? urlObject.Value("rows") : new JArray(); } catch { } JArray colssArray = new JArray(); try { colssArray = urlObject.ContainsKey("cols") ? urlObject.Value("cols") : new JArray(); } catch { } formDataObject.Add(id, new JObject() { { "rows", rowsArray }, { "cols", colssArray }, { "selects", new JArray() } }); } } } #endregion #region 子表 JArray subTableJarray = formObject.ContainsKey("subtableJson") ? formObject.Value("subtableJson") : new JArray(); foreach (JObject sdtObject in subTableJarray) { string id = sdtObject.Value("id"); JArray sRows = _form.GetSubTableJarray(sdtObject, formObject.Value("conn"), instanceId); if (formDataObject.ContainsKey(id)) { formDataObject[id] = new JObject() { { "rows", sRows } }; } else { formDataObject.Add(id, new JObject() { { "rows", sRows } }); } } //默认值 formDataObject.Add("subtableDefaultValue", _form.GetSubTableDefaultValueJArray(subTableJarray, userModel)); #endregion JArray fieldStatusJArray = fieldStatusJson.ToJArray(); if (!fieldStatusJArray.IsEmptyJArray()) { //表单验证类型 int validatePromptType = formObject.Value("validatePromptType").ToInt(0); foreach (JObject fieldStatusObject in fieldStatusJArray) { string filed = fieldStatusObject.Value("name"); if (isSubtablePopup && !filed.Split('-')[0].EqualsIgnoreCase(subtableName)) { continue;//如果是子表弹出编辑,则只取子表的字段状态 } if (!statusObject.ContainsKey(filed)) { int status = fieldStatusObject.Value("status").ToInt(0); if (isDisplay && status == 0) { status = 1;//如果是显示,字段是编辑则设置为只读状态。 } statusObject.Add(filed, status); } //验证json int check = fieldStatusObject.Value("check").ToInt(0); if (check > 0) { //判断是不是子表 int isSubTable = 0; string subTableId = string.Empty;//子表ID string fieldShowName = string.Empty;//子表字段的显示标题 foreach (JObject subTableJObject in subTableJarray) { string table = subTableJObject.Value("subTable"); if (filed.StartsWith(table.ToUpper() + "-")) { isSubTable = 1; subTableId = subTableJObject.Value("id"); string fieldName = filed.Replace(table.ToUpper() + "-", ""); //查找子表字段设置的显示名称。 foreach (JObject subTableRowJObject in subTableJObject.Value("rows")) { if (subTableRowJObject.Value("field").EqualsIgnoreCase(fieldName)) { fieldShowName = subTableRowJObject.Value("fieldName"); break; } } break; } } //验证类型,string,decimal...... string validType = valueTypeObject.IsEmptyJObject() ? "string" : valueTypeObject.Value(filed); JObject cObject = new JObject() { { "type", validType.IsNullOrWhiteSpace() ? "string" : validType }, { "required", check == 2 }, { "title", fieldShowName }, { "msg", fieldShowName + "不可为空" },//localizer["CannotbeEmpty"].Value }, { "showtype", validatePromptType }, { "position", 0 }, { "ispass", true }, { "issubtable", isSubTable }, { "subtableid", subTableId }, }; if ("ajax".Equals(validType)) { //如果是AJAX验证要添加url属性 cObject.Add("url", RoadFlow.Business.Wildcard.Filter(valueTypeObject.Value(filed + "-AJAXURL"), userModel)); } checkObject.Add(filed, cObject); } } } //移出不需要输出到客户端的数据 //formObject.Remove("validatePromptType"); //formObject.Remove("formatJson"); //formObject.Remove("valueTypeJson"); //formObject.Remove("defaultValueJson"); if (formObject.ContainsKey("data")) { formObject["data"] = formDataObject; } else { formObject.Add("data", formDataObject); } if (formObject.ContainsKey("fieldStatus")) { formObject["fieldStatus"] = statusObject; } else { formObject.Add("fieldStatus", statusObject); } if (formObject.ContainsKey("validate")) { formObject["validate"] = checkObject; } else { formObject.Add("validate", checkObject); } #endregion JObject jObject = new JObject() { { "form", formObject }, }; return jObject; //RoadFlowCommon.Tools.GetReturnJsonString(true, jObject: jObject); } /// /// 保存直接编辑的表单 /// /// [HttpPost("SaveEditData")] public dynamic SaveEditData([FromBody] JObject args) { try { var (newInstanceId, errMsg) = _form.SaveDataVue(args); JObject jObject = new JObject { { "instanceid", newInstanceId } }; #region 设计的应用程序保存时判断是否有事件 if (args.GetJsonValue("programid").IsGuid(out Guid programGuid)) { var programRunModel = _program.GetRunModel(programGuid.ToString()); if (programRunModel != null && !programRunModel.EditEvents.IsNullOrWhiteSpace()) { bool isAdd = args.GetJsonValue("instanceid").IsNullOrWhiteSpace();//是新增还是修改 Dictionary eventParams = new Dictionary { { "ProgramId", programGuid },//设计的应用程序ID { "InstanceId", newInstanceId },//删除的ID,多个逗号隔开 { "EditModel", isAdd ? 0 : 1 } //编辑方式 0 新增 1修改 2删除 }; var (_, err) = Tools.ExecuteMethod(programRunModel.EditEvents.Trim(), eventParams); if (err != null) { _log.Add(err, "执行应用程序设计数据" + (isAdd ? "新增" : "修改") + "后事件发生错误-" + programGuid + "-" + programRunModel.Name + "-" + programRunModel.EditEvents); } } } #endregion return jObject; //RoadFlowCommon.Tools.GetReturnJsonString(true, localizer["SaveSuccessfully"].Value, jObject: jObject); } catch (Exception err) { _log.Add(err, "直接保存表单数据时发生了错误"); throw Oops.Oh("保存失败"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["SaveFail"].Value); } } #endregion #region 表单直接调用API /// /// 得到步骤相关信息 /// /// [HttpGet("GetStepInfo")] public dynamic GetStepInfo(string flowId, string stepId, string instanceId, string taskId,string freesend) { bool isFreeSend = "1".Equals(freesend); if (!flowId.IsGuid(out Guid flowGuid)) { throw Oops.Oh("流程ID错误"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["FlowIdError"].Value); } RoadFlow.Model.rf_flowtask currentTaskModel = taskId.IsGuid(out Guid taskGuid) ? _flowTask.GetOneById(taskId) : null; var flowRunModel = _flow.GetFlowRunModel(flowId, true, currentTaskModel); if (flowRunModel == null) { throw Oops.Oh("未找到流程运行模型"); // return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["Execute_NotFoundFlowRunModel"].Value); } if (!stepId.IsGuid(out Guid stepGuid)) { stepGuid = flowRunModel.FirstStepId; } var stepModel = flowRunModel.Steps.Find(p => p.Id == stepGuid); if (null == stepModel) { throw Oops.Oh("未找到步骤运行模型"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["Execute_NotFoundStepRunModel"].Value); } //检查权限,如果不是任务接收者,又不是第一步处理者,不能获取信息。 string userId = _userManager.UserId; if ((currentTaskModel != null && currentTaskModel.ReceiveId != userId) || (!stepModel.StepBase.DefaultHandler.IsNullOrWhiteSpace() && !_userDummy.IsIn(userId.ToString(), stepModel.StepBase.DefaultHandler))) { throw Oops.Oh("您无权进行当前操作"); //return RoadFlowCommon.Tools.GetReturnJsonString(false, localizer["Execute_SubmitCurrentTaskCanotProcess"].Value); } //得到字段状态 JObject fieldStatusObject = new JObject(); foreach (var fieldStatus in stepModel.StepFieldStatuses) { string[] fieldArray = fieldStatus.Field.Split('.'); string table = fieldArray.Length > 1 ? fieldArray[1] : string.Empty; string field = fieldArray.Length > 2 ? fieldArray[2] : string.Empty; fieldStatusObject.Add(table.ToUpper() + "-" + field.ToUpper(), fieldStatus.Status); } var (html, msg, nextSteps) = _flowTask.GetNextSteps(flowRunModel, stepGuid, currentTaskModel == null ? string.Empty : currentTaskModel.GroupId, taskGuid.ToString(), instanceId, userId, isFreeSend, false, null, null);// localizer); JArray stepsArray = new JArray(); foreach (var nextStep in nextSteps) { stepsArray.Add(new JObject() { { "id", nextStep.Id }, { "name", nextStep.Name }, { "members", nextStep.RunDefaultMembers }, { "note", nextStep.Note } }); } JObject jObject = new JObject() { { "fieldStatus", fieldStatusObject }, { "nextSteps", stepsArray } }; return jObject; //RoadFlowCommon.Tools.GetReturnJsonString(true, jObject: jObject); } /// /// 根据json执行流程 /// /// /// {id:'任务id',flowId:'流程ID',instanceId:'实例id',title:'任务标题',comment:'处理意见',type:'处理类型',note:'备注', /// senderId:'发送人id',sign:'是否签章 0|1',steps:[{id:'接收步骤id',name:'接收步骤名称',member:'接收人',completedtime:'要求完成时间'}]} /// /// [HttpPost("ExecuteFromJSON")] public dynamic ExecuteFromJSON([FromBody] JObject args) { string json = args.GetJsonValue("json"); var executeResult = _flowTask.ExecuteFromJSON(json, null);// localizer); return executeResult.ToJObject(); //RoadFlowCommon.Tools.GetReturnJsonString(executeResult.IsSuccess, executeResult.Messages, jObject: executeResult.ToJObject()); } #endregion } }