.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之工作流工程展示及代码分享(五)前端交互
原文地址:https://www.cnblogs.com/thanks/p/4310750.html