taotaogo1980 发表于 2013-2-3 11:25:32

移动审批工作流设计与实现

<p style="text-indent: 2em; margin: 1em 0px; color: #000;">移动审批,通过手机方便快捷地登陆企业内部网及互联网,即使处于无线的状态下,也能进行远程办公,以此来提高对于突发事件的反应能力,提升企业竞争力。

这篇文章我将使用iPhone作为移动终端进行设计与实现,iPhone引入了基于大型多触点显示屏和领先性新软件的全新用户界面,让用户用手指即可控制iPhone。iPhone还开创了移动设备软件尖端功能的新纪元,重新定义了移动电话的功能。iPhone开发中,除了比较复杂的游戏开发,还有一种就是跟数据库打交道的应用程序,这可以在本文中得到体现。

WF4.0是微软提供的一套工作流开发框架,里面包含:流程设计器,各种类型封装好的工作流活动,持久化服务,WCF服务等功能。这篇文章我将结合iPhone+WF4.0实现移动审批工作流。通过一个简单的例子你可以清楚的看到与数据库相关的iPhone应用程序的开发,以及使用iPhone+WCF+WF实现移动审批的各种关键技术的使用。

设计架构图:
由于是使用了WCF的restful服务,所以其它手机平台也会很方便使用此工作流服务。

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050722032129.png" alt="">

iPhone客户端的表单可以通过从服务端设计的表单结构的XML动态产生。

下面通过一个简单的请假流程说明如何实现:

用例流程图:


<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721304048.png" alt="">

上面的流程大致为:申请人在iPhone上打开请假流程,填写姓名和请假天数,点击提交,这个流程将走到他的上级,上级进行审批,并将审批结果通过短信知道申请者。

参考上图,通过WF4.0设计器设计一个流程,如下图:


<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721322245.png" alt="">

下面我使用WCF将此流程封装到restful服务中。

wcf restful服务设计如下:


<div class="cnblogs_code">
<pre><div>
<span style="color: #000000;"> <textarea cols="50" rows="15" name="code" class="c-sharp">
    public interface IRestServiceImpl
    {
      
      [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "getleavelist")]
      List<Leave> GetLeaveList();

      
      [WebInvoke(Method = "POST",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "createleave/{name}/{day}")]
      string CreateLeave(string name, string day);


      
      [WebInvoke(Method = "POST",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "auditingleave/{id}/{comment}")]
      string AuditingLeave(string id, string comment);
    }</textarea></span>


</pre>

数据库设计:


1、WF持久化数据表:使用WF自带的数据表。

</strong>


2、业务数据表:请假单,设计如下:

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050816575847.png" alt="">


WF流程启动和运行代码:



<div class="cnblogs_code">
<pre><div><textarea cols="50" rows="15" name="code" class="c-sharp">publicclass WorkFlowProcess
    {
      static AutoResetEvent instanceUnloaded = new AutoResetEvent(false);

      static Hashtable InstanceHashtable = new Hashtable();

      public static string RunInstance(Guid ID,string Comment)
      {
            SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore("Data Source=PC-ZHUQL//ZHUQL;Initial Catalog=TestDB;Integrated Security=True;Pooling=False");
            WorkflowApplication application1 = new WorkflowApplication(new LeaveProcess());
            application1.InstanceStore = instanceStore;
            application1.Completed = (workflowApplicationCompletedEventArgs) =>
            {
                Console.WriteLine("/nWorkflowApplication has Completed in the {0} state.", workflowApplicationCompletedEventArgs.CompletionState);
            };
            application1.Unloaded = (workflowApplicationEventArgs) =>
            {
                Console.WriteLine("WorkflowApplication has Unloaded/n");
                instanceUnloaded.Set();
            };
            application1.Load(ID);
            application1.ResumeBookmark("Check", Comment);
            instanceUnloaded.WaitOne();
            return "success";
      }

      // creates a workflow application, binds parameters, links extensions and run it
      public static string CreateAndRun(string LeaveName, int LeaveDay)
      {
            SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore("Data Source=PC-ZHUQL//ZHUQL;Initial Catalog=TestDB;Integrated Security=True;Pooling=False");

            InstanceView view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));

            instanceStore.DefaultInstanceOwner = view.InstanceOwner;

            IDictionary<string, object> input = new Dictionary<string, object>
            {
                { "LeaveName" , LeaveName },
                { "LeaveDay" , LeaveDay }
            };

            WorkflowApplication application = new WorkflowApplication(new LeaveProcess(), input);

            application.InstanceStore = instanceStore;

            application.PersistableIdle = (e) =>
            {
                instanceUnloaded.Set();
                return PersistableIdleAction.Unload;

            };

            application.Unloaded = (e) =>
            {

                instanceUnloaded.Set();

            };
            application.OnUnhandledException = (ex) =>
            {
                Console.Write("Exception");
                return UnhandledExceptionAction.Terminate;
            };
         Guid id = application.Id;
         application.Run();
         instanceUnloaded.WaitOne();
         return "success";
      }

      // executed when instance is persisted
      public static void OnWorkflowCompleted(WorkflowApplicationCompletedEventArgs e)
      {
      }

      // executed when instance goes idle
      public static void OnIdle(WorkflowApplicationIdleEventArgs e)
      {
      }

      public static PersistableIdleAction OnIdleAndPersistable(WorkflowApplicationIdleEventArgs e)
      {
            return PersistableIdleAction.Persist;
      }
    }</textarea>

</pre>

iPhone客户端调用:


在前一篇文章:<a id="homepage1_HomePageDays_DaysList_DayItem_1_DayList_1_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/zhuqil/archive/2011/04/26/iphone-restful-wcf.html"><span style="color: #6466b3;">iPhone中调用WCF RESTFUL Service</span>
</a>
,讲解了iPhone中如何调用WCF restful服务,下面用启动流程为例说明:

<div class="cnblogs_code">
<pre><div><textarea cols="50" rows="15" name="code" class="c-sharp">-(IBAction) btnSender:(id)sender
{
NSString * urlString =@"http://10.5.23.117:8008/RestServiceImpl.svc/createleave/%@/%@";
   NSURL *url = ];
ASIHTTPRequest *request = ;
;
;
NSError *error = ;
if (!error) {
NSString *response = ;
UIAlertView *alertView = [ initWithTitle:@"杩斿洖缁撴灉"
message:@"鎻愪氦鎴愬姛"
   delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
;
;
}
}</textarea>

</pre>

iPhone界面设计:


1、启动流程界面:

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721501281.png" alt="">

2、填写表单信息:

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721505228.png" alt="">

3、启动流程

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721511861.png" alt="">

4、待审核列表:

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721521142.png" alt="">

5、审核界面:

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721530411.png" alt="">

6、审核结果:

<img src="http://pic002.cnblogs.com/images/2011/38542/2011050721534593.png" alt="">

这里是个简单的demo,界面非常的简陋。

总结:
本文通过一个简单的用例来说明了移动审批流程的各个层面的各种技术的实现。使用这些技术实现一个工作流服务以及工作流客户端界面将非常简单。

代码:<a href="http://http//files.cnblogs.com/zhuqil/RestService.rar%0D%0A%0D%0A"><span style="color: #6466b3;">服务端</span>
</a>

<strong>,<a href="http://files.cnblogs.com/zhuqil/iPhoneView.zip%0D%0A%0D%0A"><span style="color: #6466b3;">iPhone客户端</span>
</a>
页: [1]
查看完整版本: 移动审批工作流设计与实现