1. 程式人生 > 其它 >CCFLOW原始碼解讀系列01-----發起流程

CCFLOW原始碼解讀系列01-----發起流程

1、發起流程

發起流程時主要做了兩件事:一是寫入業務資料表,二是新建一條審批流程記錄。

發起流程的方法

        public static Int64 Node_CreateStartNodeWork(string flowNo, Hashtable htWork = null, DataSet workDtls = null,
            string flowStarter = null, string title = null, Int64 parentWorkID = 0, string parentFlowNo = null, int parentNDFrom = 0
)

系統中一般這樣呼叫

Hashtable ht = new Hashtable();
long startFlowId = Dev2Interface.Node_CreateStartNodeWork(fk_Flow, ht, null, currentUserName, title);

傳入的主要引數有

流程的編號fk_Flow,編號是從001開始的,工作流系統中有一個預設的流程,編號是001,你可以在上面修改,也可以新建,新建後的流程編號是002.

鍵值對,ht主要是用於修改業務表。

currentUserName使用者名稱,主要用於初始化發起人資訊,如果傳NULL,則會預設用當前登入使用者。

titile流程名,如果傳Null,則會預設生成一條流程。

進入方法,會看到初始化了幾個例項 :

一是流程物件 Flow 記錄了流程的編號、建立時間、名稱,

 Flow fl = new Flow(flowNo);
/// <summary>
        /// 流程
        /// </summary>
        /// <param name="_No">編號</param>
        public Flow(string _No)
        {
            this.No = _No;
            if (SystemConfig.IsDebug)
            {
                
int i = this.RetrieveFromDBSources(); if (i == 0) throw new Exception("流程編號不存在"); } else { this.Retrieve(); } }

二是節點物件Node存放每個節點的資訊,通過流程的開始節點ID初始化節點類

Node nd = new Node(fl.StartNodeID);

讓我們看看流程開始節點是如何找到的,如下,開始節點等於流程號+01再轉成Int 也就是說流程編號為002的開始節點為201

public int StartNodeID
        {
            get
            {
                return int.Parse(this.No + "01");
                
            }
        }

三是操作員Emp

Emp emp = new Emp(flowStarter);
 /// <summary>
        /// 操作員
        /// </summary>
        /// <param name="no">編號</param>
        public Emp(string no)
        {
            if (no == null || no.Length == 0)
                throw new Exception("@要查詢的操作員編號為空。");

            this.No = no.Trim();
           
                this.Retrieve();
            
        }

三是工作物件work 隨著該物件被建立,物件GenerWorkFlow也被創建出來,對應的表wf_generworkflow中增加了一條記錄

Work wk = fl.NewWork(flowStarter);
public Work NewWork(string empNo)
        {
            Emp emp = new Emp(empNo);
            return NewWork(emp, null);
        }
        /// <summary>
        /// 產生一個開始節點的新工作
        /// </summary>
        /// <param name="emp">發起人</param>
        /// <param name="paras">引數集合,如果是CS呼叫,要發起子流程,要從其他table裡copy資料,就不能從request裡面取,可以傳遞為null.</param>
        /// <returns>返回的Work.</returns>
        public Work NewWork(Emp emp, Hashtable paras)
        {
            // 檢查是否可以發起該流程?
            if (Glo.CheckIsCanStartFlow_InitStartFlow(this) == false)
                throw new Exception("err@您違反了該流程的【" + this.StartLimitRole + "】限制規則。" + this.StartLimitAlert);

            GenerWorkFlow gwf = new GenerWorkFlow();

........................

wf_generworkflow表中修改的欄位如下,WorkID是啟動流程的唯一標識,也是最終要返回的ID,可以繫結在業務表上的。設定了當前流程的狀態:WFState.Blank

     #region 給 generworkflow 初始化資料. add 2015-08-06

            gwf.FK_Flow = this.No;
            gwf.FK_FlowSort = this.FK_FlowSort;
            gwf.SysType = this.SysType;
            gwf.FK_Node = nd.NodeID;
            gwf.WorkID = wk.OID;
            gwf.WFState = WFState.Blank;
            gwf.FlowName = this.Name;

            gwf.FK_Node = nd.NodeID;
            gwf.NodeName = nd.Name;
            gwf.Starter = WebUser.No;
            gwf.StarterName = WebUser.Name;
            gwf.FK_Dept = BP.Web.WebUser.FK_Dept;
            gwf.DeptName = BP.Web.WebUser.FK_DeptName;

接下來又對GenerWorkerList物件進行了修正,

 #region 為開始工作建立待辦
            GenerWorkFlow gwf = new GenerWorkFlow();
            gwf.WorkID = wk.OID;
            int i = gwf.RetrieveFromDBSources();

            gwf.FlowName = fl.Name;
            gwf.FK_Flow = flowNo;
            gwf.FK_FlowSort = fl.FK_FlowSort;
            gwf.SysType = fl.SysType;

            gwf.FK_Dept = emp.FK_Dept;
            gwf.DeptName = emp.FK_DeptText;
            gwf.FK_Node = fl.StartNodeID;

            gwf.NodeName = nd.Name;

            //預設是空白流程
            //gwf.WFSta = WFSta.Etc;
            gwf.WFState = WFState.Blank;
            //儲存到草稿
            if (fl.DraftRole == DraftRole.SaveToDraftList)
            {
                gwf.WFState = WFState.Draft;
            }
            else if (fl.DraftRole == DraftRole.SaveToTodolist)
            {
                //儲存到待辦
                //  gwf.WFSta = WFSta.Runing;
                gwf.WFState = WFState.Runing;
            }

            if (DataType.IsNullOrEmpty(title))
            {
                gwf.Title = BP.WF.WorkFlowBuessRole.GenerTitle(fl, wk);
            }
            else
            {
                gwf.Title = title;
            }

            gwf.Starter = emp.No;
            gwf.StarterName = emp.Name;
            gwf.RDT = DataType.CurrentDataTime;

            if (htWork != null && htWork.ContainsKey("PRI") == true)
            {
                gwf.PRI = int.Parse(htWork["PRI"].ToString());
            }

            if (htWork != null && htWork.ContainsKey("SDTOfNode") == true)
            {
                /*節點應完成時間*/
                gwf.SDTOfNode = htWork["SDTOfNode"].ToString();
            }

            if (htWork != null && htWork.ContainsKey("SDTOfFlow") == true)
            {
                /*流程應完成時間*/
                gwf.SDTOfNode = htWork["SDTOfFlow"].ToString();
            }

            gwf.PWorkID = parentWorkID;
            gwf.PFlowNo = parentFlowNo;
            gwf.PNodeID = parentNDFrom;
            if (i == 0)
            {
                gwf.Insert();
            }
            else
            {
                gwf.Update();
            }

四是建立了工作者列表GenerWorkerList,寫入的表是wf_generworkerlist

// 產生工作列表.
            GenerWorkerList gwl = new GenerWorkerList();
            gwl.WorkID = wk.OID;
            if (gwl.RetrieveFromDBSources() == 0)
            {
                gwl.FK_Emp = emp.No;
                gwl.FK_EmpText = emp.Name;

                gwl.FK_Node = nd.NodeID;
                gwl.FK_NodeText = nd.Name;
                gwl.FID = 0;

                gwl.FK_Flow = fl.No;
                gwl.FK_Dept = emp.FK_Dept;
                gwl.FK_DeptT = emp.FK_DeptText;


                gwl.SDT = "";
                gwl.DTOfWarning = DataType.CurrentDataTime;
                gwl.IsEnable = true;

                gwl.IsPass = false;
                //     gwl.Sender = WebUser.No;
                gwl.PRI = gwf.PRI;
                gwl.Insert();
            }

最後,整個啟動流程的方法會將OID返回

return wk.OID;

可以返回的ID繫結在自定義的業務表中。