前言
2007年底,微軟終於推出了第一個可以在.NET上執行的WorkFlow引擎,Windows Workflow Foundation(簡稱WF),他提供了一個可以整合在VS2005或VS2008之下的程式開發環境與相關的工具,讓程式開發人員可以利用WF來建構工作流程管理系統,程式人員可以自由開發屬於自己的「流程活動元件」(Activity),並整合其他現成可用的Web Service與其他外部的程式,可應用到各種不同的企業領域中。 EEP Workflow Foundation,採用Microsoft .NET 3.0 Workflow Foundation為核心技術,整合快速的EEP電子表單工具,可以輕易與企業的ERP等資訊系統整合,讓企業流程與單據在可靠且穩定的Workflow 環境下落實BPM管理制度,改善企業流程,讓企業大幅提作業效率與監督控管能力,以e化提升企業經營競爭力。 但是,單純指可透過EEP的系統使用EEP WorkFlow Foundation這樣的機制,必不能滿足廣大程式師的需求。因此,EEP WorkFlow Foundation的如果擴大使用範圍,成為我們思考的焦點,因此,EEP WorkFlow API的問世,為大眾提供了解決方案。它將透過WebService的方式,讓不是使用EEP架構的Web應用程式,同樣也可使用EEP WorkFlow Foundation來做為系統的流程引擎,並且相互整合。
何謂 Web Service & API
WebService是建立可互操作的分佈式應用程式的平臺,它擁有自己的一套標準,定義了應用程式如何在Web上實現互操作與呼叫的功能。它向外界暴露出一個能夠通過Web進行呼叫的API。這就是說,你能夠用寫程式的方式透過Web來呼叫這個應用程式。 API 就是應用程式的一個介面。它是能用來操作元件、或後端應用程式或者作業系統的一組函數。典型的情況下,API 由一個或多個提供某種特殊功能的 DLL 組成。 EEP WorkFlow Foundation API就是通過將我們提供的接口以WebService的形式,發佈到IIS,這樣Web的所有應用程式就可以自由的呼叫WebService衆多提供的方法。從而實現EEP WorkFlow Foundation在各個應用程式中來被使用。
EEP Work Flow API 架構
透過下圖我們可以發現,在整個EEP WorkFlow API的核心部分,依然為EEP WorkFlow Foundation的核心内容,並架構在EEPNetServer上,透過EEP FLDesigner設計完成的工作流程將存成XOML檔案,存放在EEPNetServer的指定目錄上。EEP WF Activity為常用的工作流程活動元件。EEP WF Core為EEP的基本類型與基本相互溝通的核心程式庫,用來溝通FLTools的元件與FLRunTime以及FLDesigner所共同的元件類型與程式接口。EEP WF RunTime用來實際執行每個工作流程實例,與控制整個執行時期的狀態。由下圖可以發現在圖的左側部分就是EEP WorkFlow API(即FLService)。通過此Service就可以讓你用其他ASP寫的或ASP .net所寫的Web Page來呼叫此API的Service,來達到實現工作流程功能。
EEP WorkFlow API提供方法
在EEP WorkFlow API中,我們提供了23個Web Service接口,分別用來實現 上呈(Submit)、審核(Approve)、取回與退回(Return)、通知(Notify)以及列出該用戶的經辦、待辦、通知、逾時等查詢功能,如下圖的Web Service:
現將常用的幾個介面簡要說明如下:
1. ApproveForAllPlatform(string securityKey, string listId, string flowPath, int important, int urgent, string remark, string roleId, string orgKid, string attachments)
用來審核單據所使用,該單據必須已經存在流程引擎當中,利用此API來讓流程往下進行一步。
2. SubmitForAllPlatform(string securityKey, string xomlFile, int important, int urgent, string remark, string roleId, string provider, string orgKid, string attachments, string keys, string keyValues)
用來上呈單據所使用,當流程的第一步,必須使用這個API來建立一個新的流程實例,並存在流程引擎中,一直到該流程結案或者作廢為止。
3. GetNotifyForAllPlatform(string securityKey)
取得當前User的通知事項,會傳回通知事項的DataSet,可以用GridView來顯示。
4. GetRunOverForAllPlateform(string securityKey, string userId)
取得當前User的逾時事項,會傳回逾時事項的DataSet,可以用GridView來顯示。
5. GetToDoHisForAllPlatform(string securityKey)
取得當前User的經辦事項,會傳回經辦事項的DataSet,可以用GridView來顯示。
6. GetToDoListForAllPlatform(string securityKey)
取得當前User的待辦事項,會傳回待辦事項的DataSet,可以用GridView來顯示。
API應用實例的規劃
這裡,我們要以C#為語言設計一個簡單的實例,來說明EEP Workflow Foundation API 的應用。在此之前,我們必須先設計一個最簡單的工作流程,如下圖:
以EEP所提供的兩種Activity(流程活動元件),來實現流程的功能,第一關為客戶申請,第二關主管審核,主管審核可以設定多級審核,在此我只設定了一級主管的審核即可。
接著,我們實際來設計三個網頁,分別用於Login與瀏覽待辦與經辦,客戶的資料申請輸入,申請表單的訊息說明與與審核訊息等頁面。
1. 第一個主頁面用來Login登錄與瀏覽待辦,如下圖。
在這個頁面可以點擊『待辦』、『經辦』、『逾時』、『通知』按鈕,取得目前登錄的User的相關資料。在此我們設計一個『客戶申請』按鈕,來新增並申請客戶資料。如果是第二關以後,我們則先選擇一筆待辦,並設計一個『客戶審核』按鈕來進行審核的工作。
2. 第二個頁面為客戶資料的編輯畫面,用來輸入申請客戶的資料,如下:
畫面中,我們設計了一個『Submit』按鈕來完成該客戶的申請作業,用『Approve』按鈕來完成客戶的審核。
3. 第三個頁面為流程上呈的共用畫面,用戶可以輸入上呈或審核的訊息,或選用角色(因為一個User可能扮演多個角色),最後設計一個『確認』按鈕來實際上呈。
API應用實例的開發
下面我們將前面的設計畫面,套上EEP所提供的Workflow API,來實例開發,如下:注意:使用 標記的内容為FLService的重要方法。
1. 主頁面(Default.aspx):
因為API中必須對AP Server來登入,並需記住Login用戶的認證Key值與一些基本訊息,所以我們必須
使用Session方式記錄下來,這樣每個頁面就可以透過這些認證Key值,持續對API呼叫使用。
由按鈕觸發的程式:
protected void btLogin_Click(object sender, ImageClickEventArgs e) { FLService.FLService service = new FLService.FLService(); //以下訊息都是登陸EEPNetServer的必要內容 string UserID, Password, LoginDB, SolutionID, Language, RoleID = ""; UserID = tbUserID.Text == "" ? "U03" : tbUserID.Text;//登陸的UserID Password = tbPassword.Text; //登陸的密碼 LoginDB = tbLoginDB.Text == "" ? "ERPS" : tbLoginDB.Text; //EEPNetServer上的DB Alias SolutionID = tbSolutionID.Text == "" ? "Solution1" : tbSolutionID.Text; //SolutionID(不一定有) Language = tbLanguage.Text == "" ? "0" : tbLanguage.Text; //設定語言別,0~7依次為:英文,中文繁體,中文簡體等等 string key = service.LoginForAllPlatform(UserID, Password, LoginDB, SolutionID, Convert.ToInt16(Language)); //登陸EEPNetServer,並提供各方法需要的securityKey參數 if (key == string.Empty) { lbMessage.Text = "用戶:" + UserID + "沒有登陸成功!"; return; } if (Session.Count == 0) { object[] flow = new object[] { "workflow\\fl\\CUSTOMERS.XOML", "", "", "", "0", "CustomerID", "" }; //Flow相關的訊息,依次流程文件,流程ID,流程路徑,Server端DLL,組織代號,鍵值欄位,鍵值內容;
.......
由『』,『』,『』,『 』四個Button共用的程式。依據點擊的Button,分別獲得『待辦』,『經辦』,『逾時』,『通知』事項,並在Gridview中顯示出來,在此我們只列出『待辦』與『經辦』,其餘為相似與雷同。
protected void btList_Click(object sender, ImageClickEventArgs e) { FLService.FLService service = new FLService.FLService(); if (Session.Count == 0) //如果沒有登陸,需要提醒User先登陸到EEPNetServer { lbMessage.Text = "請先登陸!"; return; } btApprove.Enabled = false; DataSet ds = null; string Id = (sender as ImageButton).ID; switch (Id) { case "btList": { ds = service.GetToDoListForAllAllPlatform2(Session["FlowKey"].ToString(), Session["UserID"].ToString()); //取得經辦的Service方法 if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { btApprove.Enabled = true; } lbTitle.Text = "待辦事項:"; } break; case "btHist": { ds = service.GetToDoHisForAllAllPlatform2(Session["FlowKey"].ToString(), Session["UserID"].ToString()); //取得待辦的Service方法 lbTitle.Text = "經辦事項:"; } break; case .... (通知與逾時省略.. ) } if (ds.Tables.Count > 0) { gvList.DataSource = ds.Tables[0]; gvList.DataMember = ds.Tables[0].TableName; gvList.DataBind(); //將取得的資料放入 gvList的GridView中 } }
2. 客戶申請頁面(Customers.aspx):
為了配合流程的應用,一般的資料輸入網頁是必須要配合一些狀態的,例如,打開業面時,請增加類似”Action=btAdd”這種參數,來代表是『客戶申請』則進入新增狀態,其他的如『客戶審核』則需要過濾資料,請增加”Key=”將鍵值傳入,並只顯示要審核的資料等,如下:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { string KeyValue = ""; if (this.Request["Action"].ToString() == "btAdd") //如果為客戶申請狀態下 { fvMaster.ChangeMode(FormViewMode.Insert); btSubmit.Enabled = false; // 控制Button的狀態 btApprove.Enabled = false; } else { // 利用CustomerID=傳入鍵值 KeyValue = ((object[])Session["FlowItems"])[6].ToString().Replace("CustomerID='",""); KeyValue = KeyValue.Substring(0, KeyValue.Length - 1); btSubmit.Enabled = false; // 控制Button的狀態 btApprove.Enabled = true; } //Session["CustomerID"]是用於記錄Where條件,以免在其他的Post操作後導致所有的資料都顯示出來。 HttpContext.Current.Session["CustomerID"] = KeyValue; } }
在新增後需要修改條件為剛剛新增的一筆資料,
protected void sdsMaster_Inserted(object sender, SqlDataSourceStatusEventArgs e) { Session["CustomerID"] = (fvMaster.FindControl("CustomerIDTextBox") as TextBox).Text; btSubmit.Enabled = true; //設定允許Submit }
接著,往下設計 上呈『Submit』提交後,去打開另一個共用的上呈頁面,如下:
protected void btSubmit_Click(object sender, ImageClickEventArgs e) { if (fvMaster.CurrentMode != FormViewMode.ReadOnly) { lbMessage.Text = "請先保存資料!"; return; } /*傳3個參數到開啓的Web中: 1. Button的名字,可以區別是Submit還是Approve操作; 2. Submit操作需要傳當前資料的key欄位;Approve操作因爲參數都放置在Session中,可以不用傳遞 3. key欄位的值,格式為:FieldName=FieldValue,比如:CustomerID=''A001'',這裏還需要說明,在sqlserver中,如果是字符型欄位,請使用兩個單引號 4. 第2和第3個參數是Submit和Appove的方法需要使用; */ string btstring = (sender as ImageButton).ID; if (btstring == "btSubmit") { object[] flow = (object[])Session["FlowItems"]; flow[6] = "CustomerID='"+fvMaster.SelectedValue.ToString()+"'"; Session["FlowItems"] = flow; } string str = "<script>window.open('WebMSSet.aspx?Active=" + btstring + "','','left=200,top=200,width=500,height=400,scrollbars=no,resizable=no,toolbar=no,menubar=no,location=no,status=no')</script>"; // 用Java Script 去打開WebMSSet.aspx並傳遞參數過去, 好處理流程上呈 Page.ClientScript.RegisterStartupScript(typeof(string), Guid.NewGuid().ToString(), str); }
3. 流程上呈頁面(WebMSSet.aspx):
根據頁面,來設計最重要的上呈或審核的共用頁面,如下:
protected void btOk_Click(object sender, ImageClickEventArgs e) { if ((sender as ImageButton).ID == "btOK") { FLService.FLService service = new FLService.FLService(); //取得Flow的相關信息 string FLActive = this.Request["Active"].ToString(); string FlowKey = Session["FlowKey"].ToString(); object[] flow = (object[])Session["FlowItems"]; object[] ret = new object[] { 0, "OK" }; if (FLActive == "btSubmit") { //參數依次為:安全Key,流程文件,是否重要,是否緊急,意見說明,發送者角色,使用的EEPServer的InfoCommand名字(例如:S001.Master),組織代號,上傳檔案名稱,Key欄位名字,當前的Key(例如:CustomerID='A001') ret = service.SubmitForAllPlatform(FlowKey, flow[0].ToString(), Convert.ToInt16(cbImportant.Checked), Convert.ToInt16(cbUrgent.Checked), tbRemark.Text, ddRole.SelectedItem.ToString(), flow[3].ToString(), flow[4].ToString(), string.Empty, flow[5].ToString(), flow[6].ToString().Replace("'", "''")) } else { //參數依次為:安全Key,流程的ID,Flow路徑(系統記錄流程的相關信息可在待辦等中取得),是否重要,是否緊急,意見說明,發送者角色,組織代號,上傳檔案名稱 ret = service.ApproveForAllPlatform(FlowKey, flow[1].ToString(), flow[2].ToString(), Convert.ToInt16(cbImportant.Checked), Convert.ToInt16(cbUrgent.Checked), tbRemark.Text, ddRole.SelectedItem.ToString(), flow[4].ToString(), string.Empty); } if (ret[0].ToString() != "0") { Label1.Text = ret[1].ToString(); return; } } ClosePage(); }
API應用實例的結果
接著我們要來執行上面所設計的結果:
1. 打開EEPNetServer.exe後,打開Default.aspx頁面,如圖,我們每一個User帳後,如”003”去Login後,出現畫面如下:
2. 點選「客戶申請」項目,打開畫面中,新增一筆客戶資料,然後選擇Insert將該筆資料新增到資料庫中。
3. 然後按下「Submit」,將會出現以下的上呈確認畫面。我們使用了角色R01(業務)上呈,依組織設定其主管為R02(業務經理)。
4. 接著,我們以”005”這個User來Login,依設定,005扮演R02(業務經理)的角色,在主畫面中的待辦事項中找到R02業務經理的所有待辦資料,也就是剛剛那筆客戶資料,接著我們可以選中C001這個客戶單據,選擇「客戶審核」打開此待辦單據,如圖:
5. 在此我們按下「Approve」後,同樣會出現如圖的確認畫面,請同樣加註意見於「意見說明」欄位中,最後按下「確認」,因為本流程在「主管審核」活動後面並沒有其他的活動,因此,該流程已經確定結案。如下圖:
結語
通過上面簡單的介紹,想必您已經對EEP WorkFlow Foundation API有了一個初步的認識。有了API所提供的方法,對於非EEP環境下實現工作流程已經變得更加容易,可以想像在API的方法下,將現成的Web網頁整合進入工作流程領域中的開發門檻,將會大大降低,進而強化企業的自動化流程與BPM的管理,提升企業運作績效。 (完) |