CCFLOW原始碼解讀系列01-----發起流程
阿新 • • 發佈:2021-07-20
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繫結在自定義的業務表中。