zoukankan      html  css  js  c++  java
  • .net之工作流工程展示及代码分享(四)主控制类

    现在应该讲主控制类了,为了不把系统弄得太复杂,所以就用一个类作为主要控制类(服务类),作为前端、后端、业务逻辑的控制类。

    WorkflowService类的类图如下:

    该类的构造函数:

    1         public WorkflowService(IWorkflowDB workflowDb, IWorkflowMethods workflowMethods)
    2         {
    3             _iWorkflowDb = workflowDb;
    4             _iWorkflowMethods = workflowMethods;
    5         }

    通过简单工厂方法返回类的实例:

     1         /// <summary>
     2         /// 程序主调用方法
     3         /// </summary>
     4         /// <returns></returns>
     5         public static WorkflowService GetWorkflowService()
     6         {
     7             IWorkflowDB iWorkflowDb;
     8             try
     9             {
    10             string dbSavingProvider = WorkFlowUtility.GetConfiguration("DataBaseProvider").ToLower();
    11                 switch (dbSavingProvider)
    12                 {
    13                     case "oracle":
    14                         iWorkflowDb = new OracleWorkFlowDBUtility();
    15                         break;
    16                     case "sqlserver":
    17                         //iWorkflowDb = new SqlServerWorkFlowDBUtility();
    18                         //break;
    19                     default:
    20                         iWorkflowDb = (IWorkflowDB) Assembly.Load(dbSavingProvider).CreateInstance(dbSavingProvider);
    21                         break;
    22                 }
    23 
    24             }
    25             catch (Exception)
    26             {
    27                 throw new WorkFlowConfigurationNotImplementException("数据库配置失败!");
    28             }
    29 
    30                 IWorkflowMethods iWorkflowMethods;
    31             try
    32             {
    33                 string dbInterface = WorkFlowUtility.GetConfiguration("WorkflowConfigurationNameSpace");
    34                 iWorkflowMethods = (IWorkflowMethods)Assembly.Load(dbInterface).CreateInstance(dbInterface + ".WorkflowConfiguration");
    35             }
    36             catch (Exception ex)
    37             {
    38                 throw new WorkFlowConfigurationNotImplementException("应用程序实例配置失败!");
    39             }
    40 
    41             return new WorkflowService(iWorkflowDb, iWorkflowMethods);
    42         }
    View Code

    所有方法返回的类型都是WorkflowServiceResponse类型,该类定义如下:

     1     public class WorkflowServiceResponse
     2     {
     3         public WorkflowServiceResponse()
     4         {
     5             Success = false;
     6         }
     7         public bool Success { get; set; } 
     8         public string Message { get; set; }
     9         public dynamic ReturnEntity { get; set; }
    10     }

    使用了Request-Response模式,其中返回的实体使用了.net4.0新增的Dynamic类型,这样就不用做抽象类,然后各种不同的返回类型来继承基类了。

    调用的方法如下:

    1             var wfs = WorkflowService.GetWorkflowService();
    2             var wfsr = wfs.GetFlowById(flowId);
    3             if (!wfsr.Success)
    4             {
    5                 this.ShowAndRedirects("参数错误", "FlowManager.aspx");
    6                 return;
    7             }
    8             var flow = wfsr.ReturnEntity as Flow;
    9 .......

    那GetFlowById是怎么写的呢?

     1         /// <summary>
     2         /// 根据流程Id得到一个流程的情况
     3         /// </summary>
     4         /// <param name="flowId"></param>
     5         /// <returns></returns>
     6         public WorkflowServiceResponse GetFlowById(Guid flowId)
     7         {
     8             var wfsr = new WorkflowServiceResponse();
     9             try
    10             {
    11                 var flow = _iWorkflowDb.GetFlows().SingleOrDefault(f => f.FlowId == flowId);
    12                 if (flow != null)
    13                 {
    14                     wfsr.ReturnEntity = flow;
    15                     wfsr.Success = true;
    16                 }
    17             }
    18             catch (Exception ex)
    19             {
    20                 wfsr.Message = ex.ToString();
    21             }
    22             return wfsr;
    23         }

    这样前后端都串起来了。

    在IWorkflowDB接口定义里,GetFlows返回的是List<Flow>对象,所以这么做数据接口存在一定的性能问题,如果改成IQueryable<Flow>就能够返回Linq表达式,实现Lazy-Loaing的模式,但是Oracle不支持Linq查询,以后换EF看看......

    大家注意到了WorkflowService类里面还有个IWorkflowMethods接口。对了,这个接口就是和其它系统交互的关键,定义如下:

    1     public interface IWorkflowMethods
    2     {
    3         Person GetCurrentLoginPerson();
    4         IList<Person> GetPersonByCondition(SearchCriteria searchCriteria);
    5         bool SendMail(Person person, string message);
    6         bool SendMessage(Person person, string message);
    7         string GetAutoCompleteValueByType(string autoCompleteType);
    8         IList<string> GetUserRoleGroupNames(Person person);
    9     }

    这些方法分别是获取当前登录用户、根据条件获取应该审核流程的用户、调用原系统方法法邮件、发短信,用于表单处理中的自动填入用户姓名、职务等,获取用户所在的组(有些流程只有特定组可以申请)。

    在其中一个系统中的实现方法如下:

     1         public IList<Person> GetPersonByCondition(SearchCriteria searchCriteria)
     2         {
     3             var flowLaunchPerson = searchCriteria.FlowLaunchPerson;
     4             string sql = string.Empty;
     5             IList<Person> persons = new List<Person>();
     6             switch (searchCriteria.NextPersonWorkGroupName)
     7             {
     8                 case ".....":
     9                     break;
    10                 case "xxx审核":
    11                 {
    12                     sql = string.Format(" jsgh in (select gh from VM_TUAN....ERGR where zbid in" +
    13                                         " (select zbid from TUA....ELATIONSHIP where gh = '{0}' or xh = '{0}')" +
    14                                         " and lv = 4 and zwname = '辅导员)')  ", flowLaunchPerson.PersonId);
    15                     break;
    16                 }
    17                 case ".....审核":
    18                 {
    19                     sql = string.Format(" jsgh in (select gh from VM.....HERGR where zbid in" +
    20                                         " (select zbid from TUA....IONSHIP where gh = '{0}' or xh = '{0}')" +
    21                                         " and lv = 4 and zwname = '...')  ", flowLaunchPerson.PersonId); 
    22                     break;
    23                 };
    24                  case ".....审核":
    25                   ........
    26                   break;
    27                 default:
    28                     break;
    29             }
    30 
    31             var teachers = new B.....GetModelList(sql);
    32 
    33             if (teachers.Count > 0)
    34             {
    35                 foreach (var teacher in teachers)
    36                 {
    37                     Person person = new Person()
    38                     {
    39                         PersonId = teacher.....,
    40                         PersonName = teacher.J....,
    41                         PersonEmail = teacher.E....,
    42                     };
    43                     persons.Add(person);
    44                 }
    45             }
    46             else
    47             {
    48                 throw new WorkFlowAuditPersonNotFoundException("没有找到审核对象!");
    49             }
    50             return persons;
    51         }
    View Code

    最后分享服务类中两个核心的方法

    新建流程:

     1         /// <summary>
     2         /// 根据流程Id建立新的流程
     3         /// </summary>
     4         /// <param name="workflowAddStepParameter"></param>
     5         /// <returns></returns>
     6         public WorkflowServiceResponse CreateNewFlowInstance(WorkflowAddStepParameter workflowAddStepParameter)
     7         {
     8             var wfsr = new WorkflowServiceResponse();
     9             string message = string.Empty;
    10 
    11             if (workflowAddStepParameter.Flow == null)
    12             {
    13                 wfsr.Message = "参数错误!";
    14             }
    15             else
    16             {
    17                 var person = GetCurrentLoginPerson();
    18                 
    19                 var flowInstance = new FlowInstance();
    20                 flowInstance.FlowInstantId = Guid.NewGuid();
    21                 flowInstance.Flow = workflowAddStepParameter.Flow;
    22                 flowInstance.Creator = person;
    23                 flowInstance.CreateDate = DateTime.Now;
    24 
    25                 var flowInstanceStep = new FlowInstanceStep();
    26                 flowInstanceStep.StepInstanceId = Guid.NewGuid();
    27                 flowInstanceStep.PersonSignatures = new List<WorkflowPersonSignature>()
    28                 {
    29                     new WorkflowPersonSignature()
    30                     {
    31                         Person = person,
    32                         SignatureDate = DateTime.Now,
    33                         SignatureStatus = WorkflowConstant.SignatureStatus.Start,
    34                     }
    35                 };
    36                 flowInstanceStep.FlowStep = workflowAddStepParameter.Flow.FlowSteps.Single(s => s.IsStartStep);
    37 
    38                 flowInstanceStep.WriteValues = workflowAddStepParameter.WritedValues;
    39                 flowInstanceStep.CreateDate = DateTime.Now;
    40                 flowInstanceStep.ProcessDate = DateTime.Now;
    41                 flowInstanceStep.FileList = workflowAddStepParameter.AttachFiles;
    42 
    43                 var flowInstanceStep2 = new FlowInstanceStep();
    44                 flowInstanceStep2.CreateDate = DateTime.Now;
    45                 flowInstanceStep2.FlowStep =
    46                     workflowAddStepParameter.Flow.FlowSteps.Single(
    47                         f => f.PreviousStepId == workflowAddStepParameter.Flow.FlowSteps.Single(p => p.IsStartStep).StepId);
    48                 flowInstanceStep2.StepInstanceId = Guid.NewGuid();
    49                 flowInstanceStep2.StepStatus = WorkflowConstant.SignatureStatus.Undeal;
    50 
    51                 var flowProcessPersons =
    52                     _iWorkflowMethods.GetPersonByCondition(new SearchCriteria()
    53                     {
    54                         CurrentLoginPerson = person,
    55                         FlowLaunchPerson = person,
    56                         NextPersonWorkGroupName = flowInstanceStep2.FlowStep.RightGroupTitle,
    57                     });
    58 
    59                 var personSignatures = new List<WorkflowPersonSignature>();
    60 
    61                 if (flowProcessPersons.Count == 0)
    62                 {
    63                     throw new WorkFlowAuditPersonNotFoundException();
    64                 }
    65                 foreach (var flowProcessPerson in flowProcessPersons)
    66                 {
    67                     personSignatures.Add(
    68                         new WorkflowPersonSignature()
    69                         {
    70                             Person = flowProcessPerson,
    71                             SignatureStatus = WorkflowConstant.SignatureStatus.Undeal,
    72                         });
    73                     SendMessages(person, flowProcessPerson, WorkflowConstant.SignatureStatus.Undeal);
    74                 }
    75                 flowInstanceStep2.PersonSignatures = personSignatures;
    76                 flowInstance.FlowStepInstances = new List<FlowInstanceStep>()
    77                 {
    78                     flowInstanceStep,
    79                     flowInstanceStep2
    80                 };
    81 
    82                 try
    83                 {
    84                     wfsr.Success = _iWorkflowDb.SaveFlowInstance(flowInstance);
    85                     wfsr.ReturnEntity = flowInstance;
    86                 }
    87                 catch (Exception ex)
    88                 {
    89                     wfsr.Message = ex.ToString();
    90                 }
    91             }
    92             return wfsr;
    93         }
    View Code

    增加流程步骤:

      1         public WorkflowServiceResponse AddFlowInstanceStep(WorkflowAddStepParameter workflowAddStepParameter)
      2         {
      3             var wfsr = new WorkflowServiceResponse();
      4             var flowInstance = workflowAddStepParameter.CurrentInstance;
      5 
      6             if (flowInstance != null)
      7             {
      8                 try
      9                 {
     10                     var person = GetCurrentLoginPerson();
     11                     var currentStepIndex = flowInstance.FlowStepInstances.Count - 1 ;
     12                     //idempotent check
     13                     var flowInstanceInDb = GetFlowInstanceByInstanceId(flowInstance.FlowInstantId).ReturnEntity as FlowInstance;
     14                     if (flowInstanceInDb.FlowStepInstances.Count != flowInstance.FlowStepInstances.Count)
     15                     {
     16                         wfsr.Message = "您已经处理过该流程,请不要重复提交(或者该流程已经由其他老师处理完成)";
     17                         return wfsr;
     18                     }
     19 
     20                     var currentPersonSignatures = flowInstance.FlowStepInstances[currentStepIndex].PersonSignatures;
     21                     //idempotent check
     22                     bool deal = false;
     23                     for (int i = 0; i < currentPersonSignatures.Count; i++)
     24                     {
     25                         if (currentPersonSignatures[i].Person.PersonId == person.PersonId)
     26                         {
     27                             if (currentPersonSignatures[i].SignatureStatus != WorkflowConstant.SignatureStatus.Undeal)
     28                             {
     29                                 wfsr.Message = "该流程已经处理过";
     30                                 return wfsr;
     31                             }
     32                             flowInstance.FlowStepInstances[currentStepIndex].PersonSignatures[i].SignatureDate =
     33                                 DateTime.Now;
     34                             flowInstance.FlowStepInstances[currentStepIndex].PersonSignatures[i].SignatureStatus =
     35                                 workflowAddStepParameter.SignatureStatus;
     36                             flowInstance.FlowStepInstances[currentStepIndex].PersonSignatures[i].Memo = workflowAddStepParameter.Memo;
     37                             deal = true;
     38                         }
     39                     }
     40                     if (!deal)
     41                     {
     42                         wfsr.Message = "您已经处理过该流程,请不要重复提交(或者该流程已经由其他老师处理完成)";
     43                         return wfsr;
     44                     }
     45 
     46                     flowInstance.FlowStepInstances[currentStepIndex].WriteValues = workflowAddStepParameter.WritedValues;
     47                     flowInstance.FlowStepInstances[currentStepIndex].ProcessDate = DateTime.Now;
     48                     
     49                     switch (workflowAddStepParameter.SignatureStatus)
     50                     {
     51                         case WorkflowConstant.SignatureStatus.Passed:
     52                         {
     53                             if (flowInstance.FlowStepInstances[currentStepIndex].FlowStep.CounterSignatureMode ==
     54                                 WorkflowConstant.CounterSignatureMode.OneApprove)
     55                             {
     56                                 flowInstance.FlowStepInstances[currentStepIndex].StepStatus =
     57                                     WorkflowConstant.SignatureStatus.Passed;
     58                             }
     59                             else if (flowInstance.FlowStepInstances[currentStepIndex].FlowStep.CounterSignatureMode ==
     60                                      WorkflowConstant.CounterSignatureMode.AllApprove)
     61                             {
     62                                 if (
     63                                     flowInstance.FlowStepInstances[currentStepIndex].PersonSignatures.All(
     64                                         s => s.SignatureStatus == WorkflowConstant.SignatureStatus.Passed))
     65                                 {
     66                                     flowInstance.FlowStepInstances[currentStepIndex].StepStatus =
     67                                         WorkflowConstant.SignatureStatus.Passed;
     68                                 }
     69                                 else
     70                                 {
     71                                     flowInstance.FlowStepInstances[currentStepIndex].StepStatus =
     72                                         WorkflowConstant.SignatureStatus.PartialPassed;
     73                                 }
     74                             }
     75                             if (flowInstance.FlowStepInstances[currentStepIndex].StepStatus ==
     76                                 WorkflowConstant.SignatureStatus.Passed)
     77                             {
     78                                 if (flowInstance.FlowStepInstances[currentStepIndex].FlowStep.IsLastStep)
     79                                 {
     80                                     flowInstance.FlowStatus = WorkflowConstant.SignatureStatus.Finish;
     81                                     var lastStep = new FlowInstanceStep();
     82                                     lastStep.StepInstanceId = Guid.NewGuid();
     83                                     lastStep.CreateDate = DateTime.Now;
     84                                     lastStep.FlowStep = new FlowStep()
     85                                     {
     86                                         StepName = "流程结束",
     87                                     };
     88                                     lastStep.ProcessDate = DateTime.Now;
     89                                     lastStep.StepStatus = WorkflowConstant.SignatureStatus.Finish;
     90                                     flowInstance.FlowStepInstances.Add(lastStep);
     91                                 }
     92                                 else
     93                                 {
     94                                     var nextStep = new FlowInstanceStep();
     95                                     nextStep.StepInstanceId = Guid.NewGuid();
     96                                     nextStep.CreateDate = DateTime.Now;
     97                                     nextStep.FlowStep =
     98                                         flowInstance.Flow.FlowSteps.Single(
     99                                             f =>
    100                                                 f.PreviousStepId ==
    101                                                 flowInstance.FlowStepInstances[currentStepIndex].FlowStep.StepId);
    102                                     nextStep.StepStatus = WorkflowConstant.SignatureStatus.Undeal;
    103 
    104                                     var flowProcessPersons =
    105                                         _iWorkflowMethods.GetPersonByCondition(new SearchCriteria()
    106                                         {
    107                                             CurrentLoginPerson = _iWorkflowMethods.GetCurrentLoginPerson(),
    108                                             FlowLaunchPerson = flowInstance.Creator,
    109                                             NextPersonWorkGroupName = nextStep.FlowStep.RightGroupTitle,
    110                                         });
    111 
    112                                     var personSignatures = new List<WorkflowPersonSignature>();
    113 
    114                                     if (flowProcessPersons.Count == 0)
    115                                     {
    116                                         throw new WorkFlowAuditPersonNotFoundException();
    117                                     }
    118                                     foreach (var flowProcessPerson in flowProcessPersons)
    119                                     {
    120                                         personSignatures.Add(
    121                                             new WorkflowPersonSignature()
    122                                             {
    123                                                 Person = flowProcessPerson,
    124                                                 SignatureStatus = WorkflowConstant.SignatureStatus.Undeal,
    125                                             });
    126                                     }
    127                                     nextStep.PersonSignatures = personSignatures;
    128                                     flowInstance.FlowStepInstances.Add(nextStep);
    129                                 }
    130                             }
    131 
    132                             break;
    133                         }
    134                         case WorkflowConstant.SignatureStatus.Stopped:
    135                             flowInstance.FlowStepInstances[currentStepIndex].StepStatus =
    136                                 WorkflowConstant.SignatureStatus.Stopped;
    137                             flowInstance.FlowStatus = WorkflowConstant.SignatureStatus.Stopped;
    138 
    139                             break;
    140                         case WorkflowConstant.SignatureStatus.RejectToFirstStep:
    141                         {
    142                             flowInstance.FlowStepInstances[currentStepIndex].StepStatus =
    143                                 WorkflowConstant.SignatureStatus.RejectToFirstStep;
    144                             var nextStep = new FlowInstanceStep();
    145                             nextStep.StepInstanceId = Guid.NewGuid();
    146                             nextStep.CreateDate = DateTime.Now;
    147                             nextStep.FlowStep =
    148                                 flowInstance.Flow.FlowSteps.Single(
    149                                     f => f.IsStartStep);
    150                             nextStep.StepStatus = WorkflowConstant.SignatureStatus.Undeal;
    151 
    152                             var personSignatures = new List<WorkflowPersonSignature>();
    153                             personSignatures.Add(new WorkflowPersonSignature()
    154                             {
    155                                 Person =
    156                                     flowInstance.FlowStepInstances.Single(f => f.FlowStep.IsStartStep)
    157                                     .PersonSignatures[0].Person,
    158                                 SignatureStatus = WorkflowConstant.SignatureStatus.Undeal
    159                             });
    160 
    161                             nextStep.PersonSignatures = personSignatures;
    162                             flowInstance.FlowStepInstances.Add(nextStep);
    163 
    164                             break;
    165                         }
    166                         case WorkflowConstant.SignatureStatus.RejectToPreviousStep:
    167                         {
    168                             flowInstance.FlowStepInstances[currentStepIndex].StepStatus =
    169                                 WorkflowConstant.SignatureStatus.RejectToPreviousStep;
    170 
    171                             var nextStep = new FlowInstanceStep();
    172                             nextStep.StepInstanceId = Guid.NewGuid();
    173                             nextStep.CreateDate = DateTime.Now;
    174                             nextStep.FlowStep =
    175                                 flowInstance.Flow.FlowSteps.Single(
    176                                     f =>
    177                                         f.StepId ==
    178                                         flowInstance.FlowStepInstances[currentStepIndex].FlowStep.PreviousStepId);
    179                             nextStep.StepStatus = WorkflowConstant.SignatureStatus.Undeal;
    180 
    181                             var flowProcessPersons =
    182                                 _iWorkflowMethods.GetPersonByCondition(new SearchCriteria()
    183                                 {
    184                                     CurrentLoginPerson = _iWorkflowMethods.GetCurrentLoginPerson(),
    185                                     FlowLaunchPerson = flowInstance.Creator,
    186                                     NextPersonWorkGroupName = nextStep.FlowStep.RightGroupTitle,
    187                                 });
    188 
    189                             var personSignatures = new List<WorkflowPersonSignature>();
    190 
    191                             if (flowProcessPersons.Count == 0)
    192                             {
    193                                 throw new WorkFlowAuditPersonNotFoundException();
    194                             }
    195                             foreach (var flowProcessPerson in flowProcessPersons)
    196                             {
    197                                 personSignatures.Add(
    198                                     new WorkflowPersonSignature()
    199                                     {
    200                                         Person = flowProcessPerson,
    201                                         SignatureStatus = WorkflowConstant.SignatureStatus.Undeal,
    202                                     });
    203                             }
    204                             nextStep.PersonSignatures = personSignatures;
    205                             flowInstance.FlowStepInstances.Add(nextStep);
    206 
    207                             break;
    208                         }
    209                         default:
    210                             break;
    211 
    212                     }
    213 
    214                     flowInstance.LastDealDate = DateTime.Now;
    215 
    216                     wfsr.Success = _iWorkflowDb.SaveFlowInstance(flowInstance);
    217                     wfsr.ReturnEntity = flowInstance;
    218                 }
    219                 catch (Exception ex)
    220                 {
    221                     wfsr.Message = ex.ToString();
    222                 }
    223             }
    224             return wfsr;
    225 
    226         }
    View Code

    感觉用DDD的思想写程序还是蛮舒服的。(感谢Steven的指出,操纵流程类并没体现DDD思想。在操纵Form类里面的有的,代码没贴出)

    下回讲一下前端。

    谢谢大家!

    本系列导航:

    1. .net之工作流工程展示及代码分享(预告)
    2. .net之工作流工程展示及代码分享(一)工作流表单
    3. .net之工作流工程展示及代码分享(二)工作流引擎
    4. .net之工作流工程展示及代码分享(三)数据存储引擎
    5. .net之工作流工程展示及代码分享(四)主控制类
    6. .net之工作流工程展示及代码分享(五)前端交互
  • 相关阅读:
    J.U.C AQS(abstractqueuedssynchronizer--同步器)
    垃圾收集器与内存分配策略---内存的分配与回收
    16.合并两个排序的链表
    15.反转链表
    14.链表中倒数第k个节点
    15.Subtree of Another Tree(判断一棵树是否为另一颗树的子树)
    flask 学习app代码备份
    TCSRM5961000
    URAL1291. Gear-wheels
    hdu4422The Little Girl who Picks Mushrooms
  • 原文地址:https://www.cnblogs.com/thanks/p/4310750.html
Copyright © 2011-2022 走看看