Exemple #1
0
 private FinishRule GetFinishRule(Client.AppendHumanSetting setting)
 {
     return(!string.IsNullOrWhiteSpace(setting.FinishRuleName) &&
            !string.IsNullOrWhiteSpace(setting.FinishRuleBody)
         ? new FinishRule(new Dictionary <string, string>()
     {
         { setting.FinishRuleName, setting.FinishRuleBody }
     })
         : null);
 }
Exemple #2
0
        private Client.AppendHumanSetting CreateAppendHumanSetting(Client.AppendHumanMode mode)
        {
            var setting = new Client.AppendHumanSetting();

            setting.ActionerRule        = new string[] { "'houkun'", "'xuanfang'" };
            setting.Actions             = new string[] { this._action1, this._action2 };
            setting.ActivityName        = this._dynamicActivityName;
            setting.EnterAction         = this._enterAction;
            setting.EnterFinishRuleName = this._enterAction;
            if (mode == Client.AppendHumanMode.Continues)
            {
                setting.FinishRuleName = "动态节点执行完成";
                setting.FinishRuleBody = string.Format("all('{0}')", _action1);
            }
            setting.Url = "aspx";
            return(setting);
        }
 private Client.AppendHumanSetting CreateAppendHumanSetting(Client.AppendHumanMode mode)
 {
     var setting = new Client.AppendHumanSetting();
     setting.ActionerRule = new string[] { "'houkun'", "'xuanfang'" };
     setting.Actions = new string[] { this._action1, this._action2 };
     setting.ActivityName = this._dynamicActivityName;
     setting.EnterAction = this._enterAction;
     setting.EnterFinishRuleName = this._enterAction;
     if (mode == Client.AppendHumanMode.Continues)
     {
         setting.FinishRuleName = "动态节点执行完成";
         setting.FinishRuleBody = string.Format("all('{0}')", _action1);
     }
     setting.Url = "aspx";
     return setting;
 }
Exemple #4
0
        public void AppendHumanActivity(Guid processId, Client.AppendHumanMode mode, Client.AppendHumanSetting appendHumanSetting)
        {
            //HACK:动态节点出于重复考虑,总是会先移除重名的节点,此设计会存在意外的情况

            string       reason;
            HumanSetting currentHumanSetting;

            if (!this.CanAppendHumanActivity(processId, mode, appendHumanSetting.ActivityName, out currentHumanSetting, out reason))
            {
                throw new InvalidOperationException(reason);
            }
            if (appendHumanSetting == null)
            {
                throw new ArgumentNullException("humanSetting");
            }

            var process            = this.GetProcessById(processId);
            var currentProcessType = process.ProcessType;
            //获取所有节点设置的副本
            var clonedSettings             = new List <ActivitySetting>(currentProcessType.ActivitySettings.Select(o => o.Clone()));
            var workflow                   = this._workflowParser.Parse(currentProcessType.Workflow.Serialized, clonedSettings);
            var originalWorkflowDefinition = currentProcessType.Workflow.Serialized;

            #region 查找节点信息
            var currentNode    = this.GetFlowStep(workflow, currentHumanSetting.ActivityName);
            var currentSetting = clonedSettings.FirstOrDefault(o => o.ActivityName == currentNode.Action.DisplayName) as HumanSetting;
            var nextNode       = this.GetNextFlowStep(workflow, currentNode);
            if (currentNode == null || currentSetting == null)
            {
                throw new InvalidOperationException(string.Format(
                                                        "没有在流程中找到节点“{0}”的定义", currentHumanSetting.ActivityName));
            }
            #endregion

            #region 修改当前节点
            clonedSettings.Remove(currentSetting);
            var finishRule = currentSetting.FinishRule.Scripts;
            //总是先移除避免多次重复追加
            finishRule.Remove(appendHumanSetting.EnterFinishRuleName);
            //新增完成规则用于满足后进入新节点
            //必须将新规则插入在第一个规则位置,避免原有规则的影响 用atMostOf?该细节不能出现在Model层
            finishRule = new Dictionary <string, string>()
            {
                { appendHumanSetting.EnterFinishRuleName, string.Format("all('{0}')", appendHumanSetting.EnterAction) }
            }
            .Concat(finishRule)
            .ToDictionary(o => o.Key, o => o.Value);
            currentSetting = new HumanSetting(currentSetting.FlowNodeIndex
                                              , currentSetting.ActivityName
                                              , currentSetting.Actions
                                              , currentSetting.SlotCount
                                              , currentSetting.SlotMode
                                              , currentSetting.Url
                                              , currentSetting.StartRule
                                              , currentSetting.ActionerRule
                                              , new FinishRule(finishRule)
                                              , currentSetting.EscalationRule
                                              , currentSetting.IsChildOfActivity);
            clonedSettings.Add(currentSetting);
            #endregion

            #region 新增节点设置
            var newHumanSetting = new HumanSetting(0//此时无需设置实际值,最终创建流程类型时会由转换器填充实际值
                                                   , appendHumanSetting.ActivityName
                                                   , appendHumanSetting.Actions
                                                   , appendHumanSetting.SlotCount
                                                   , (HumanSetting.SlotDistributionMode)(int) appendHumanSetting.SlotMode
                                                   , appendHumanSetting.Url
                                                   , null
                                                   , new HumanActionerRule(appendHumanSetting.ActionerRule)
                                                   , this.GetFinishRule(appendHumanSetting)
                                                   , null
                                                   , false);
            clonedSettings.Add(newHumanSetting);
            #endregion

            #region 将新节点与左右节点连接
            FlowStep newNode = null;
            if (mode == Client.AppendHumanMode.Wait)
            {
                newNode = WorkflowBuilder.CreateHuman(newHumanSetting
                                                      , newHumanSetting.ActivityName
                                                      , new GetUsers(appendHumanSetting.ActionerRule)
                                                      , null
                                                      , null
                                                      , currentNode);//总是返回当前节点
            }
            else if (mode == Client.AppendHumanMode.Continues)
            {
                newNode = WorkflowBuilder.CreateHuman(newHumanSetting
                                                      , newHumanSetting.ActivityName
                                                      , new GetUsers(appendHumanSetting.ActionerRule)
                                                      , workflow.CustomActivityResult
                                                      , nextNode == null
                    ? null
                                                      //HACK:下一节点的进入与否将根据新节点的完成规则而定,若满足则继续,若不满足则流程结束,常见于加签的情况
                    : new Dictionary <string, FlowNode>()
                {
                    { appendHumanSetting.FinishRuleName, nextNode }
                }
                                                      , null);
            }
            //总是先移除避免多次重复追加
            (currentNode.Next as FlowSwitch <string>).Cases.Remove(appendHumanSetting.EnterFinishRuleName);
            (currentNode.Next as FlowSwitch <string>).Cases.Add(appendHumanSetting.EnterFinishRuleName, newNode);
            //总是先移除避免多次重复追加
            workflow.Body.Nodes.Remove(this.GetFlowStep(workflow, newHumanSetting.ActivityName));
            //由于解析需要应同时补充此元数据
            workflow.Body.Nodes.Add(newNode);
            #endregion

            //创建新流程定义,动态变更
            this._processService.DynamicChangeProcessType(process
                                                          , this.CreateProcessType(currentProcessType.Name
                                                                                   , this._workflowParser.Parse(workflow, originalWorkflowDefinition)
                                                                                   , this._workflowParser.Parse(clonedSettings)
                                                                                   , currentProcessType.Description
                                                                                   , currentProcessType.Group
                                                                                   , false));
        }