Winform開發框架中工作流模塊的動態處理


在工作流處理表中,首先我們區分流程模板和流程實例兩個部分,這個其實就是類似模板和具體文檔的概念,我們一份模板可以創建很多個類似的文檔,文檔樣式結構類似的。同理,流程模板實例為流程實例后,就是具體的一個流程表單信息了,其中流程模板和流程實例表單都包括了各個流程步驟。在流程實例的層次上,我們運行的時候,需要記錄一些日志方便跟蹤,如流程步驟的處理日志,流程實例表單的處理日志等這些信息。

一旦流程實例根據模板創建后,流程先根據模板初始化后,在處理過程還可以動態增加一些審批步驟,使得我們的處理更加彈性化。如下所示。

我們在系統中動態定義很多業務表單,因此需要動態展示創建表單的入口;另外每種業務表單的創建和查看也需要實現動態的構建,才能更好的實現我們業務流程的處理規則。

1、動態顯示流程業務入口

我們在工作流模塊中,有一個統一的業務創建入口,方便用戶的使用,我們需要創建什么類型的業務表單,從中選擇創建接口,是一個便利的入口。

我們實現這個展示會相對比較簡單,但是創建業務表單的入口需要動態的處理,是根據用戶配置的參數進行動態的處理的。

 

上述的界面是通過在數據庫里面動態獲取信息,並創建不同的按鈕的,因此可以實現流程入口的動態顯示,不需要硬編碼帶來后期的修改。實現的邏輯就是在右側內容區域的流布局區域,根據表單信息動態創建按鈕,並實現對應的事件響應即可,實現代碼如下所示。

        /// <summary>
        /// 綁定表單列表的展示
        /// </summary>
        private void BindData()
        {
            //使用流布局,清空
            this.flowLayoutPanel1.Controls.Clear();

            //根據條件獲取表單列表,並動態創建按鈕
            string where = GetConditionSql();
            List<FormInfo> list = BLLFactory<BLL.Form>.Instance.Find(where);
            int i = 0;
            foreach (FormInfo info in list)
            {
                //在流布局中動態加入按鈕
                SimpleButton button = CreateButton(info, i++);
                this.flowLayoutPanel1.Controls.Add(button);
            }            
        }
        /// <summary>
        /// 根據流程模板的表單信息,動態創建入口按鈕
        /// </summary>
        /// <param name="info">模板的表單信息</param>
        /// <param name="imageIndex">圖標</param>
        /// <returns></returns>
        private SimpleButton CreateButton(FormInfo info, int imageIndex)
        {
            //定義按鈕,在流布局的圖標、位置、偏移空間、字體顏色等
            SimpleButton button = new SimpleButton();
            button.ImageList = this.imageCollection1;
            button.ImageLocation = ImageLocation.TopCenter;
            button.Padding = new Padding(10, 10, 10, 10);
            button.Size = new Size(102, 114);
            button.Margin = new Padding(10, 10, 10, 10);
            button.ImageIndex = imageIndex;
            button.Font = new Font("宋體", 9f, FontStyle.Bold);
            button.ForeColor = Color.Blue;
            button.Text = info.FormName;
            button.Tag = info.ID;
            if (!string.IsNullOrEmpty(info.Remark))
            {
                button.ToolTip = info.Remark;
                button.ToolTipIconType = DevExpress.Utils.ToolTipIconType.Information;
            }
            //所有按鈕統一處理事件
            button.Click += new EventHandler(button_Click);

            return button;
        }

按鈕的處理有一個統一的事件實現新建業務表單的賦值和顯示窗體。實現的代碼如下所示。

        /// <summary>
        /// 單擊某個動態生成的按鈕,觸發的申請表單創建界面
        /// </summary>
        void button_Click(object sender, EventArgs e)
        {
            SimpleButton button = sender as SimpleButton;
            if (button != null)
            {
                //獲取模板表單必要的信息
                var formId = button.Tag.ToString();
                var formInfo = BLLFactory<BLL.Form>.Instance.FindByID(formId);
                if (formInfo != null && !string.IsNullOrEmpty(formInfo.ApplyWin))
                {
                    try
                    {
                        //動態構建創建申請單的界面窗體並賦值
                        var dlg = Assembly.GetExecutingAssembly().CreateInstance(formInfo.ApplyWin) as FrmAddApply;
                        dlg.FormID = button.Tag.ToString();
                        dlg.ShowDialog();
                    }
                    catch(Exception ex)
                    {
                        LogHelper.Error(ex);
                        MessageDxUtil.ShowError(ex.Message);
                    }
                }
                else
                {
                    MessageDxUtil.ShowTips(button.Text + "暫未開通");
                }
            }
        }

2、動態顯示和創建業務表單的處理

有了上面動態列表的顯示,以及統一的按鈕處理,事情就好辦很多。

我們剛才也涉及到了業務表單的創建調用,是通過反射處理實現業務表單創建窗口的賦值和顯示的。

    //動態構建創建申請單的界面窗體並賦值
    var dlg = Assembly.GetExecutingAssembly().CreateInstance(formInfo.ApplyWin) as FrmAddApply;
    dlg.FormID = button.Tag.ToString();
    dlg.ShowDialog();

這其中涉及的配置信息就是我們創建一個業務窗口所需要的參數的,如下數據表所示。

 

其實通過創建這些業務表,我們在封裝繼承上也做了很多工作,以極大簡化業務表單的處理,以下是業務表單新建、編輯、查看的處理操作,它們已經繼承自各自的處理類,因此在反射的時候,統一轉換為基類即可實現處理。

首先我們來了解一下業務表單的對應關系,一般創建一個業務流程處理,都需要有一個具體的創建業務表單的界面,以及一個查看處理表單的界面。

為了方便,我們盡可能減少代碼編寫,我們需要把大多數的邏輯處理放在基類實現,這樣我們在新增一個業務表單的時候就可以減少很多代碼編寫及維護了。

 

 例如對於請假申請的業務表單,它們的窗體定義如下所示。

 而查看請假申請的業務表單則是如下。

從上面關系我們可以看到,其中對於工作流業務表單的窗體界面都可以實現標准的處理了,繼承自某個基類,然后整合相關的數據處理規則即可。

那么我們提煉業務信息后,可以使用代碼生成工具快速生成,這樣可以極大提高我們的開發效率。

下面就是使用我們定制的框架代碼生成工具 Database2Sharp,就可以極大簡化工作流業務表單的生成處理了。

 

3、查看申請單的處理動態化

在我的待辦業務列表里面,就可以看到剛才的表單了,雙擊可以進行查看,以及相關的審批處理工作。

對於一個流程處理操作,我們知道一般有審批通過、拒絕、退回到某步驟、轉發到內部閱讀、閱讀等處理步驟,以及包括起草者能撤銷表單呢等操作,當然如果還有一些具體的業務,可能還會有一些流程的處理才操作,不過基本上也可以歸結為上面幾種,只是他們每步處理的數據內容不同而已。因此審批的操作步驟分類如下所示。

除了上面這些基礎的表單處理動作,有時候還會定義多個處理人共同處理的會簽步驟,只有全部通過才算通過的處理流程。

會簽是指創建一個或多個子流程供相關人員進行審批,等待全部人員完成處理后再次回到主流程上,然后決定是否繼續流轉到下一個流程步驟上去,一般的申請單的主流程如下所示。

這里設置的會簽處理就是其中一個步驟,一旦會簽處理步驟發起會簽,就會構建多個可供審批的子流程了,如下所示。

 針對上面的業務介紹,那么顯示申請單的處理就必須處理這些步驟是否可用,或者決定進入哪一個流程步驟的了。

對於審批性質的表單,如下是界面的審批操作

而如果是發起【發起會簽】的處理操作,那么則是把相關的投票權發送給處理人進行會簽處理。

 

以上就是工作流表單里面設計到的幾個動態處理的業務場景,同時我們通過利用動態的信息處理,可以減少硬編碼的可能性,同時增加系統的彈性處理,非常方便,由於相關工作流的基類設計較為合理,因此在代碼生成的時候,只需要關注簡單的界面展示調整即可,通過這種處理方式,可以在多個層面降低開發工作流界面的復雜度,同時系統又增加了很多可擴展性的處理,如可以動態增加表單、動態增加流程步驟、動態指定不同的業務處理類型等等。

通過這些的介紹,我們就是系統在開發的時候,盡可能提取不變的內容或者規則,從而在實際增量開發的過程中降低開發的時間,減少難度,同時統一處理做法,既可以提高效率,又可以提高穩定性和統一性。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM