using System; using BP.En; using BP.Web; using BP.DA; using System.Collections; using System.Data; using BP.Port; using BP.Sys; using BP.WF.Template; using BP.WF.Data; using BP.Difference; namespace BP.WF { public enum HungupSta { /// /// 申请 /// Apply, /// /// 同意 /// Agree, /// /// 拒绝 /// Reject } /// /// WF 的摘要说明。 /// 工作流 /// 这里包含了两个方面 /// 工作的信息. /// 流程的信息. /// public class WorkFlow { #region 当前工作统计信息 /// /// 正常范围的运行的个数。 /// public static int NumOfRuning(string FK_Emp) { string sql = "SELECT COUNT(*) FROM V_WF_CURRWROKS WHERE FK_Emp='" + FK_Emp + "' AND WorkTimeState=0"; return DBAccess.RunSQLReturnValInt(sql); } /// /// 进入警告期限的个数 /// public static int NumOfAlert(string FK_Emp) { string sql = "SELECT COUNT(*) FROM V_WF_CURRWROKS WHERE FK_Emp='" + FK_Emp + "' AND WorkTimeState=1"; return DBAccess.RunSQLReturnValInt(sql); } /// /// 逾期 /// public static int NumOfTimeout(string FK_Emp) { string sql = "SELECT COUNT(*) FROM V_WF_CURRWROKS WHERE FK_Emp='" + FK_Emp + "' AND WorkTimeState=2"; return DBAccess.RunSQLReturnValInt(sql); } #endregion #region 权限管理 /// /// 是不是能够作当前的工作。 /// /// 工作人员ID /// 是不是能够作当前的工作 public bool ItIsCanDoCurrentWork(string empId) { WorkNode wn = this.GetCurrentWorkNode(); return BP.WF.Dev2Interface.Flow_IsCanDoCurrentWork(wn.WorkID, empId); #region 使用dev2InterFace 中的算法 //return true; // 找到当前的工作节点 // 判断是不是开始工作节点.. if (wn.HisNode.ItIsStartNode) { // 从物理上判断是不是有这个权限。 // return WorkFlow.IsCanDoWorkCheckByEmpStation(wn.HisNode.NodeID, empId); return true; } // 判断他的工作生成的工作者. GenerWorkerLists gwls = new GenerWorkerLists(this.WorkID, wn.HisNode.NodeID); if (gwls.Count == 0) { //return true; //throw new Exception("@工作流程定义错误,没有找到能够执行此项工作的人员.相关信息:工作ID="+this.WorkID+",节点ID="+wn.HisNode.NodeID ); throw new Exception("@工作流程定义错误,没有找到能够执行此项工作的人员.相关信息:WorkID=" + this.WorkID + ",NodeID=" + wn.HisNode.NodeID); } foreach (GenerWorkerList en in gwls) { if (en.EmpNo == empId) return true; } return false; #endregion } #endregion #region 流程公共方法 /// /// 执行驳回 /// 应用场景:子流程向分合点驳回时 /// /// /// 被驳回的节点 /// /// public string DoHungupReject(Int64 fid, int fk_node, string msg) { GenerWorkerList wl = new GenerWorkerList(); int i = wl.Retrieve(GenerWorkerListAttr.FID, fid, GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, fk_node); //if (i == 0) // throw new Exception("系统错误,没有找到应该找到的数据。"); i = wl.Delete(); //if (i == 0) // throw new Exception("系统错误,没有删除应该删除的数据。"); wl = new GenerWorkerList(); i = wl.Retrieve(GenerWorkerListAttr.FID, fid, GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.IsPass, 3); //if (i == 0) // throw new Exception("系统错误,想找到退回的原始起点没有找到。"); Node nd = new Node(fk_node); // 更新当前流程管理表的设置当前的节点。 DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + fk_node + ", NodeName='" + nd.Name + "' WHERE WorkID=" + this.WorkID); wl.ItIsPass = false; wl.Update(); return "工作已经驳回到(" + wl.EmpNo + " , " + wl.EmpName + ")"; // wl.HisNode } /// /// 逻辑删除流程 /// /// 逻辑删除流程原因,可以为空。 public void DoDeleteWorkFlowByFlag(string msg) { try { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); BP.WF.Node nd = new Node(); nd.NodeID = gwf.NodeID; if (nd.RetrieveFromDBSources() == 0) { Glo.AddToTrack(ActionType.DeleteFlowByFlag, gwf.FlowNo, this.WorkID, this.FID, gwf.NodeID,gwf.NodeName, WebUser.No, WebUser.Name, gwf.NodeID, gwf.NodeName, WebUser.No, WebUser.Name, msg, null); //更新-流程数据表的状态. string sql = "UPDATE " + this.HisFlow.PTable + " SET WFState=" + (int)WFState.Delete + " WHERE OID=" + this.WorkID; DBAccess.RunSQL(sql); //删除他的工作者,不让其有待办. sql = "DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID; DBAccess.RunSQL(sql); //设置产生的工作流程为. gwf.WFState = BP.WF.WFState.Delete; gwf.Update(); } else { nd = new Node(gwf.NodeID); Work wk = nd.HisWork; wk.OID = this.WorkID; wk.RetrieveFromDBSources(); //定义workNode. WorkNode wn = new WorkNode(wk, nd); //调用结束前事件. ExecEvent.DoFlow(EventListFlow.BeforeFlowDel, wn, null); //记录日志 感谢 itdos and 888 , 提出了这个问题.. wn.AddToTrack(ActionType.DeleteFlowByFlag, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, msg); //更新-流程数据表的状态. string sql = "UPDATE " + this.HisFlow.PTable + " SET WFState=" + (int)WFState.Delete + " WHERE OID=" + this.WorkID; DBAccess.RunSQL(sql); //删除他的工作者,不让其有待办. sql = "DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID; DBAccess.RunSQL(sql); //设置产生的工作流程为. gwf.WFState = BP.WF.WFState.Delete; gwf.Update(); //调用结束后事件. ExecEvent.DoFlow(EventListFlow.AfterFlowDel, wn, null); } } catch (Exception ex) { BP.DA.Log.DebugWriteError("@逻辑删除出现错误:" + ex.Message); throw new Exception("@逻辑删除出现错误:" + ex.Message); } } /// /// 恢复逻辑删除流程 /// /// 回复原因,可以为空. public void DoUnDeleteWorkFlowByFlag(string msg) { try { DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET WFState=" + (int)WFState.Runing + " WHERE WorkID=" + this.WorkID); //设置产生的工作流程为. GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); //回复数据. BP.WF.Dev2Interface.Flow_DoRebackWorkFlow(gwf.FlowNo, gwf.WorkID, gwf.NodeID, msg); WorkNode wn = new WorkNode(WorkID, gwf.NodeID); wn.AddToTrack(ActionType.UnDeleteFlowByFlag, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, msg); } catch (Exception ex) { BP.DA.Log.DebugWriteError("@逻辑删除出现错误:" + ex.Message); throw new Exception("@逻辑删除出现错误:" + ex.Message); } } /// /// 删除已经完成的流程 /// /// 流程编号 /// 工作ID /// 是否要删除子流程 /// 删除原因 /// 删除信息 public static string DoDeleteWorkFlowAlreadyComplete(string flowNo, Int64 workID, bool isDelSubFlow, string note) { BP.DA.Log.DebugWriteInfo("开始删除流程:流程编号:" + flowNo + "-WorkID:" + workID + "-" + ". 是否要删除子流程:" + isDelSubFlow + ";删除原因:" + note); Flow fl = new Flow(flowNo); #region 记录流程删除日志 GERpt rpt = new GERpt("ND" + int.Parse(flowNo) + "Rpt"); rpt.SetValByKey(GERptAttr.OID, workID); rpt.Retrieve(); WorkFlowDeleteLog log = new WorkFlowDeleteLog(); log.OID = workID; try { log.Copy(rpt); log.DeleteDT = DataType.CurrentDateTime; log.OperDept = WebUser.DeptNo; log.OperDeptName = WebUser.DeptName; log.Oper = WebUser.No; log.DeleteNote = note; log.OID = workID; log.FlowNo = flowNo; log.FlowSortNo = fl.FlowSortNo; log.InsertAsOID(log.OID); } catch (Exception ex) { log.CheckPhysicsTable(); log.Delete(); return ex.StackTrace; } #endregion 记录流程删除日志 DBAccess.RunSQL("DELETE FROM ND" + int.Parse(flowNo) + "Track WHERE WorkID=" + workID); DBAccess.RunSQL("DELETE FROM " + fl.PTable + " WHERE OID=" + workID); DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE WorkID=" + workID); // 删除质量考核数据。 string info = ""; #region 正常的删除信息. string msg = ""; try { // 删除单据信息. DBAccess.RunSQL("DELETE FROM WF_CCList WHERE WorkID=" + workID); // 删除移交. // DBAccess.RunSQL("DELETE FROM WF_ForwardWork WHERE WorkID=" + workID); //删除它的工作. DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE (WorkID=" + workID + " OR FID=" + workID + " ) AND FK_Flow='" + flowNo + "'"); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE (WorkID=" + workID + " OR FID=" + workID + " ) AND FK_Flow='" + flowNo + "'"); //删除所有节点上的数据. Nodes nds = fl.HisNodes; foreach (Node nd in nds) { try { DBAccess.RunSQL("DELETE FROM ND" + nd.NodeID + " WHERE OID=" + workID + " OR FID=" + workID); } catch (Exception ex) { msg += "@ delete data error " + ex.Message; } } if (msg != "") { BP.DA.Log.DebugWriteInfo(msg); } } catch (Exception ex) { string err = "@删除工作流程 Err " + ex.TargetSite; BP.DA.Log.DebugWriteError(err); throw new Exception(err); } info = "@删除流程删除成功"; #endregion 正常的删除信息. #region 删除该流程下面的子流程. if (isDelSubFlow) { GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.PWorkID, workID); foreach (GenerWorkFlow item in gwfs) BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(item.WorkID, true); } #endregion 删除该流程下面的子流程. BP.DA.Log.DebugWriteInfo("@[" + fl.Name + "]流程被[" + BP.Web.WebUser.No + BP.Web.WebUser.Name + "]删除,WorkID[" + workID + "]。"); return "已经完成的流程被您删除成功."; } /// /// 执行驳回 /// 应用场景:子流程向分合点驳回时 /// /// /// 被驳回的节点 /// /// public string DoReject(Int64 fid, int fk_node, string msg) { GenerWorkerList wl = new GenerWorkerList(); int i = wl.Retrieve(GenerWorkerListAttr.FID, fid, GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, fk_node); //if (i == 0) // throw new Exception("系统错误,没有找到应该找到的数据。"); i = wl.Delete(); //if (i == 0) // throw new Exception("系统错误,没有删除应该删除的数据。"); wl = new GenerWorkerList(); i = wl.Retrieve(GenerWorkerListAttr.FID, fid, GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.IsPass, 3); //if (i == 0) // throw new Exception("系统错误,想找到退回的原始起点没有找到。"); Node nd = new Node(fk_node); // 更新当前流程管理表的设置当前的节点。 DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET FK_Node=" + fk_node + ", NodeName='" + nd.Name + "' WHERE WorkID=" + this.WorkID); wl.ItIsPass = false; wl.Update(); return "工作已经驳回到(" + wl.EmpNo + " , " + wl.EmpName + ")"; // wl.HisNode } /// /// 删除子线程 /// /// 返回删除结果. private string DoDeleteSubThread() { WorkNode wn = this.GetCurrentWorkNode(); Emp empOfWorker = new Emp(WebUser.No); #region 正常的删除信息. string msg = ""; try { Int64 workId = this.WorkID; string flowNo = this.HisFlow.No; } catch (Exception ex) { throw new Exception("获取流程的 ID 与流程编号 出现错误。" + ex.Message); } try { // 删除质量考核信息. DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE WorkID=" + this.WorkID); // 删除质量考核数据。 // 删除抄送信息. DBAccess.RunSQL("DELETE FROM WF_CCList WHERE WorkID=" + this.WorkID); // 删除移交. // DBAccess.RunSQL("DELETE FROM WF_ForwardWork WHERE WorkID=" + this.WorkID); //删除它的工作. DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE (WorkID=" + this.WorkID + " ) AND FK_Flow='" + this.HisFlow.No + "'"); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE (WorkID=" + this.WorkID + " ) AND FK_Flow='" + this.HisFlow.No + "'"); if (msg != "") BP.DA.Log.DebugWriteInfo(msg); } catch (Exception ex) { string err = "@删除工作流程[" + this.HisGenerWorkFlow.WorkID + "," + this.HisGenerWorkFlow.Title + "] Err " + ex.Message; BP.DA.Log.DebugWriteError(err); throw new Exception(err); } string info = "@删除流程删除成功"; #endregion 正常的删除信息. #region 处理分流程删除的问题完成率的问题。 if (1 == 2) { /* 目前还没有必要,因为在分流点,才有计算完成率的需求. */ string sql = ""; /* * 取出来获取停留点,没有获取到说明没有任何子线程到达合流点的位置. */ sql = "SELECT FK_Node FROM WF_GenerWorkerlist WHERE WorkID=" + this.FID + " AND IsPass=3"; int fk_node = DBAccess.RunSQLReturnValInt(sql, 0); if (fk_node != 0) { /* 说明它是待命的状态 */ Node nextNode = new Node(fk_node); if (nextNode.PassRate > 0) { /* 找到等待处理节点的上一个点 */ Nodes priNodes = nextNode.FromNodes; if (priNodes.Count != 1) throw new Exception("@没有实现子流程不同线程的需求。"); Node priNode = (Node)priNodes[0]; #region 处理完成率 sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + priNode.NodeID + " AND FID=" + this.FID + " AND IsPass=1"; decimal ok = (decimal)DBAccess.RunSQLReturnValInt(sql); sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + priNode.NodeID + " AND FID=" + this.FID; decimal all = (decimal)DBAccess.RunSQLReturnValInt(sql); if (all == 0) { /*说明:所有的子线程都被杀掉了, 就应该整个流程结束。*/ WorkFlow wf = new WorkFlow(this.HisFlow, this.FID); info += "@所有的子线程已经结束。"; info += "@结束主流程信息。"; info += "@" + wf.DoFlowOver(ActionType.FlowOver, "合流点流程结束", null, null); } decimal passRate = ok / all * 100; if (nextNode.PassRate <= passRate) { /*说明全部的人员都完成了,就让合流点显示它。*/ DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE IsPass=3 AND WorkID=" + this.FID + " AND FK_Node=" + fk_node); } #endregion 处理完成率 } } /* 结束有待命的状态判断。*/ if (fk_node == 0) { /* 说明:没有找到等待启动工作的合流节点. */ GenerWorkFlow gwf = new GenerWorkFlow(this.FID); Node fND = new Node(gwf.NodeID); switch (fND.HisNodeWorkType) { case NodeWorkType.WorkHL: /*主流程运行到合流点上了*/ break; default: ///* 解决删除最后一个子流程时要把干流程也要删除。*/ //sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" +this.HisGenerWorkFlow +" AND FID=" + this.FID; //int num = DBAccess.RunSQLReturnValInt(sql); //if (num == 0) //{ // /*说明没有子进程,就要把这个流程执行完成。*/ // WorkFlow wf = new WorkFlow(this.HisFlow, this.FID); // info += "@所有的子线程已经结束。"; // info += "@结束主流程信息。"; // info += "@" + wf.DoFlowOver(ActionType.FlowOver, "主流程结束"); //} break; } } } #endregion #region 写入删除日志. wn.AddToTrack(ActionType.DeleteSubThread, empOfWorker.UserID, empOfWorker.Name, wn.HisNode.NodeID, wn.HisNode.Name, "子线程被:" + BP.Web.WebUser.Name + "删除."); #endregion 写入删除日志. return "子线程被删除成功."; } /// /// 删除已经完成的流程 /// /// 工作ID /// 是否删除子流程 /// 删除错误会抛出异常 public static void DeleteFlowByReal(Int64 workid, bool isDelSubFlow) { //检查流程是否完成,如果没有完成就调用workflow流程删除. GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = workid; int i = gwf.RetrieveFromDBSources(); if (i == 0) throw new Exception("err@错误:该流程应不存在"); BP.WF.Flow fl = new Flow(gwf.FlowNo); string toEmps = gwf.Emps.Replace('@', ',');//流程的所有处理人 if (i != 0) { if (gwf.WFState != WFState.Complete) { WorkFlow wf = new WorkFlow(workid); //发送退回消息 PushMsgs pms1 = new PushMsgs(); pms1.Retrieve(PushMsgAttr.FK_Node, gwf.NodeID, PushMsgAttr.FK_Event, EventListFlow.AfterFlowDel); Node node = new Node(gwf.NodeID); foreach (PushMsg pm in pms1) { Work work = node.HisWork; work.OID = gwf.WorkID; work.NodeID = node.NodeID; work.SetValByKey("FK_Dept", BP.Web.WebUser.DeptNo); pm.DoSendMessage(node, work, null, null, null, toEmps); } wf.DoDeleteWorkFlowByReal(isDelSubFlow); return; } } #region 删除独立表单的数据. FrmNodes fns = new FrmNodes(); fns.Retrieve(FrmNodeAttr.FK_Flow, gwf.FlowNo); string strs = ""; foreach (FrmNode frmNode in fns) { if (strs.Contains("@" + frmNode.FK_Frm) == true) continue; strs += "@" + frmNode.FK_Frm + "@"; try { MapData md = new MapData(frmNode.FK_Frm); DBAccess.RunSQL("DELETE FROM " + md.PTable + " WHERE OID=" + workid); } catch { } } #endregion 删除独立表单的数据. //删除流程数据. DBAccess.RunSQL("DELETE FROM ND" + int.Parse(gwf.FlowNo) + "Track WHERE WorkID=" + workid); DBAccess.RunSQL("DELETE FROM " + fl.PTable + " WHERE OID=" + workid); DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE WorkID=" + workid); // 删除质量考核数据。 #region 正常的删除信息. BP.DA.Log.DebugWriteInfo("@[" + fl.Name + "]流程被[" + BP.Web.WebUser.No + BP.Web.WebUser.Name + "]删除,WorkID[" + workid + "]。"); string msg = ""; // 删除单据信息. DBAccess.RunSQL("DELETE FROM WF_CCList WHERE WorkID=" + workid); //发送退回消息 PushMsgs pms = new PushMsgs(); pms.Retrieve(PushMsgAttr.FK_Node, gwf.NodeID, PushMsgAttr.FK_Event, EventListFlow.AfterFlowDel); Node pnd = new Node(gwf.NodeID); foreach (PushMsg pm in pms) { Work work = pnd.HisWork; work.OID = gwf.WorkID; work.NodeID = pnd.NodeID; work.SetValByKey("FK_Dept", BP.Web.WebUser.DeptNo); pm.DoSendMessage(pnd, work, null, null, null, toEmps); } //删除它的工作. DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE (WorkID=" + workid + " OR FID=" + workid + " ) AND FK_Flow='" + gwf.FlowNo + "'"); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE (WorkID=" + workid + " OR FID=" + workid + " ) AND FK_Flow='" + gwf.FlowNo + "'"); //删除所有节点上的数据. Nodes nodes = new Nodes(gwf.FlowNo); // this.HisFlow.HisNodes; foreach (Node node in nodes) { try { if (DBAccess.IsExitsObject("ND" + node.NodeID) == false) continue; DBAccess.RunSQL("DELETE FROM ND" + node.NodeID + " WHERE OID=" + workid + " OR FID=" + workid); } catch (Exception ex) { msg += "@ delete data error " + ex.Message; } MapDtls dtls = new MapDtls("ND" + node.NodeID); foreach (MapDtl dtl in dtls) { try { DBAccess.RunSQL("DELETE FROM " + dtl.PTable); } catch { } } } MapDtls mydtls = new MapDtls("ND" + int.Parse(gwf.FlowNo) + "Rpt"); foreach (MapDtl dtl in mydtls) { try { DBAccess.RunSQL("DELETE FROM " + dtl.PTable); } catch { } } if (msg != "") { BP.DA.Log.DebugWriteInfo(msg); } #endregion 正常的删除信息. } /// /// 删除子线程 /// /// 删除的消息 public string DoDeleteSubThread2015() { if (this.FID == 0) throw new Exception("@该流程非子线程流程实例,不能执行该方法。"); #region 正常的删除信息. string msg = ""; try { Int64 workId = this.WorkID; string flowNo = this.HisFlow.No; } catch (Exception ex) { throw new Exception("获取流程的 ID 与流程编号 出现错误。" + ex.Message); } try { // 删除质量考核信息. DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE WorkID=" + this.WorkID); // 删除质量考核数据。 // 删除抄送信息. DBAccess.RunSQL("DELETE FROM WF_CCList WHERE WorkID=" + this.WorkID); // 删除移交. // DBAccess.RunSQL("DELETE FROM WF_ForwardWork WHERE WorkID=" + this.WorkID); //删除它的工作. DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID); if (msg != "") BP.DA.Log.DebugWriteInfo(msg); } catch (Exception ex) { string err = "@删除工作流程[" + this.HisGenerWorkFlow.WorkID + "," + this.HisGenerWorkFlow.Title + "] Err " + ex.Message; BP.DA.Log.DebugWriteError(err); throw new Exception(err); } string info = "@删除流程删除成功"; #endregion 正常的删除信息. #region 处理分流程删除的问题完成率的问题。 if (1 == 2) { /* * 开发说明: * 1,当前是删除子线程操作,当前的节点就是子线程节点. * 2, 删除子线程的动作,1,合流点。2,分流点。 * 3,这里要解决合流节点的完成率的问题. */ #warning 应该删除一个子线程后,就需要计算完成率的问题。但是目前应用到该场景极少,因为。能够看到河流点信息,说明已经到达了完成率了。 /* 目前还没有必要,因为在分流点,才有计算完成率的需求. */ string sql = ""; /* * 取出来获取停留点,没有获取到说明没有任何子线程到达合流点的位置. */ sql = "SELECT FK_Node FROM WF_GenerWorkerlist WHERE WorkID=" + this.FID + " AND IsPass=3"; int fk_node = DBAccess.RunSQLReturnValInt(sql, 0); if (fk_node != 0) { /* 说明它是待命的状态 */ Node nextNode = new Node(fk_node); if (nextNode.PassRate > 0) { /* 找到等待处理节点的上一个点 */ Nodes priNodes = nextNode.FromNodes; if (priNodes.Count != 1) throw new Exception("@没有实现子流程不同线程的需求。"); Node priNode = (Node)priNodes[0]; #region 处理完成率 sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + priNode.NodeID + " AND FID=" + this.FID + " AND IsPass=1"; decimal ok = (decimal)DBAccess.RunSQLReturnValInt(sql); sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + priNode.NodeID + " AND FID=" + this.FID; decimal all = (decimal)DBAccess.RunSQLReturnValInt(sql); if (all == 0) { /*说明:所有的子线程都被杀掉了, 就应该整个流程结束。*/ WorkFlow wf = new WorkFlow(this.HisFlow, this.FID); info += "@所有的子线程已经结束。"; info += "@结束主流程信息。"; info += "@" + wf.DoFlowOver(ActionType.FlowOver, "合流点流程结束", null, null); } decimal passRate = ok / all * 100; if (nextNode.PassRate <= passRate) { /* 说明: 全部的人员都完成了,就让合流点显示它。*/ DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE IsPass=3 AND WorkID=" + this.FID + " AND FK_Node=" + fk_node); } #endregion 处理完成率 } } /* 结束有待命的状态判断。*/ if (fk_node == 0) { /* 说明:没有找到等待启动工作的合流节点. */ GenerWorkFlow gwf = new GenerWorkFlow(this.FID); Node fND = new Node(gwf.NodeID); switch (fND.HisNodeWorkType) { case NodeWorkType.WorkHL: /*主流程运行到合流点上了*/ break; default: ///* 解决删除最后一个子流程时要把干流程也要删除。*/ //sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" +this.HisGenerWorkFlow +" AND FID=" + this.FID; //int num = DBAccess.RunSQLReturnValInt(sql); //if (num == 0) //{ // /*说明没有子进程,就要把这个流程执行完成。*/ // WorkFlow wf = new WorkFlow(this.HisFlow, this.FID); // info += "@所有的子线程已经结束。"; // info += "@结束主流程信息。"; // info += "@" + wf.DoFlowOver(ActionType.FlowOver, "主流程结束"); //} break; } } } #endregion //检查是否是最后一个子线程被删除了?如果是,就需要当分流节点产生待办. GenerWorkFlow gwfMain = new GenerWorkFlow(this.FID); /*说明仅仅停留在分流节点,还没有到合流节点上去. * 删除子线程的时候,判断是否是最后一个子线程,如果是,就要把他设置为待办状态。 * 1.首先要找到. * 2.xxxx. */ // string sql = "SELECT COUNT(*) FROM WF_GenerWorkerlist WHERE FK_Node="; string mysql = "SELECT COUNT(*) as Num FROM WF_GenerWorkerlist WHERE IsPass=0 AND FID=" + this.FID; int num = DBAccess.RunSQLReturnValInt(mysql); if (num == 0) { /* 说明当前主流程上是分流节点,但是已经没有子线程的待办了。 * 就是说,删除子流程的时候,删除到最后已经没有活动或者已经完成的子线程了. * */ GenerWorkerList gwl = new GenerWorkerList(); int i = gwl.Retrieve(GenerWorkerListAttr.FK_Node, gwfMain.NodeID, GenerWorkerListAttr.WorkID, gwfMain.WorkID, GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No); if (i == 0) { Node ndMain = new Node(gwfMain.NodeID); if (ndMain.ItIsHL == true) { /* 有可能是当前节点已经到了合流节点上去了, 要判断合流节点是否有代办?如果没有代办,就撤销到分流节点上去. * * 就要检查他是否有代办. */ mysql = "SELECT COUNT(*) as Num FROM WF_GenerWorkerlist WHERE IsPass=0 AND FK_Node=" + gwfMain.NodeID; num = DBAccess.RunSQLReturnValInt(mysql); if (num == 0) { /*如果没有待办,就说明,当前节点已经运行到合流节点,但是不符合合流节点的完成率,导致合流节点上的人员看不到待办. * 这种情况,就需要让当前分流节点产生待办. */ mysql = "SELECT FK_Node FROM WF_GenerWorkerlist WHERE FID=0 AND WorkID=" + gwfMain.WorkID + " ORDER BY RDT DESC "; int fenLiuNodeID = DBAccess.RunSQLReturnValInt(mysql); Node nd = new Node(fenLiuNodeID); if (nd.ItIsFL == false) throw new Exception("@程序错误,没有找到最近的一个分流节点."); GenerWorkerLists gwls = new GenerWorkerLists(); gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, fenLiuNodeID); foreach (GenerWorkerList item in gwls) { item.ItIsRead = false; item.PassInt = 0; item.SDT = DataType.CurrentDateTimess; item.Update(); } } } } else { gwl.ItIsRead = false; gwl.PassInt = 0; gwl.SDT = DataType.CurrentDateTimess; gwl.Update(); return "子线程被删除成功,这是最后一个删除的子线程已经为您在{" + gwfMain.NodeName + "}产生了待办,点击处理工作."; } } return "子线程被删除成功."; } /// /// 彻底的删除流程 /// /// 是否要删除子流程 /// 删除的消息 public string DoDeleteWorkFlowByReal(bool isDelSubFlow) { if (this.FID != 0) return DoDeleteSubThread2015(); GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = this.WorkID; if (gwf.RetrieveFromDBSources() == 0) return "删除成功."; string info = ""; WorkNode wn = this.GetCurrentWorkNode(); // 处理删除前事件。 ExecEvent.DoFlow(EventListFlow.BeforeFlowDel, wn, null); #region 删除独立表单的数据. FrmNodes fns = new FrmNodes(); fns.Retrieve(FrmNodeAttr.FK_Flow, this.HisFlow.No); string strs = ""; foreach (FrmNode nd in fns) { if (strs.Contains("@" + nd.FK_Frm) == true) continue; strs += "@" + nd.FK_Frm + "@"; try { MapData md = new MapData(nd.FK_Frm); DBAccess.RunSQL("DELETE FROM " + md.PTable + " WHERE OID=" + this.WorkID); } catch { } } #endregion 删除独立表单的数据. //删除流程数据. DBAccess.RunSQL("DELETE FROM ND" + int.Parse(this.HisFlow.No) + "Track WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM " + this.HisFlow.PTable + " WHERE OID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE WorkID=" + this.WorkID); // 删除质量考核数据。 #region 正常的删除信息. BP.DA.Log.DebugWriteInfo("@[" + this.HisFlow.Name + "]流程被[" + BP.Web.WebUser.No + BP.Web.WebUser.Name + "]删除,WorkID[" + this.WorkID + "]。"); string msg = ""; try { Int64 workId = this.WorkID; string flowNo = this.HisFlow.No; } catch (Exception ex) { throw new Exception("获取流程的 ID 与流程编号 出现错误。" + ex.Message); } try { // 删除单据信息. DBAccess.RunSQL("DELETE FROM WF_CCList WHERE WorkID=" + this.WorkID); //删除它的工作. DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE (WorkID=" + this.WorkID + " OR FID=" + this.WorkID + " ) AND FK_Flow='" + this.HisFlow.No + "'"); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE (WorkID=" + this.WorkID + " OR FID=" + this.WorkID + " ) AND FK_Flow='" + this.HisFlow.No + "'"); //删除所有节点上的数据. Nodes nds = this.HisFlow.HisNodes; foreach (Node nd in nds) { MapDtls dtls = new MapDtls("ND" + nd.NodeID); foreach (MapDtl dtl in dtls) { try { DBAccess.RunSQL("DELETE FROM " + dtl.PTable + " WHERE RefPk = " + this.WorkID); } catch { } } try { if (DBAccess.IsExitsObject("ND" + nd.NodeID) == false) continue; DBAccess.RunSQL("DELETE FROM ND" + nd.NodeID + " WHERE OID=" + this.WorkID + " OR FID=" + this.WorkID); } catch (Exception ex) { msg += "@ delete data error " + ex.Message; } } if (msg != "") { BP.DA.Log.DebugWriteInfo(msg); } } catch (Exception ex) { string err = "@删除工作流程[" + this.HisGenerWorkFlow.WorkID + "," + this.HisGenerWorkFlow.Title + "] Err " + ex.Message; BP.DA.Log.DebugWriteError(err); throw new Exception(err); } info = "@删除流程删除成功"; #endregion 正常的删除信息. #region 处理分流程删除的问题完成率的问题。 if (this.FID != 0) { string sql = ""; /* * 取出来获取停留点,没有获取到说明没有任何子线程到达合流点的位置. */ sql = "SELECT FK_Node FROM WF_GenerWorkerlist WHERE WorkID=" + wn.HisWork.FID + " AND IsPass=3"; int fk_node = DBAccess.RunSQLReturnValInt(sql, 0); if (fk_node != 0) { /* 说明它是待命的状态 */ Node nextNode = new Node(fk_node); if (nextNode.PassRate > 0) { /* 找到等待处理节点的上一个点 */ Nodes priNodes = nextNode.FromNodes; if (priNodes.Count != 1) throw new Exception("@没有实现子流程不同线程的需求。"); Node priNode = (Node)priNodes[0]; #region 处理完成率 sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + priNode.NodeID + " AND FID=" + wn.HisWork.FID + " AND IsPass=1"; decimal ok = (decimal)DBAccess.RunSQLReturnValInt(sql); sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + priNode.NodeID + " AND FID=" + wn.HisWork.FID; decimal all = (decimal)DBAccess.RunSQLReturnValInt(sql); if (all == 0) { /*说明:所有的子线程都被杀掉了, 就应该整个流程结束。*/ WorkFlow wf = new WorkFlow(this.HisFlow, this.FID); info += "@所有的子线程已经结束。"; info += "@结束主流程信息。"; info += "@" + wf.DoFlowOver(ActionType.FlowOver, "合流点流程结束", null, null); } decimal passRate = ok / all * 100; if (nextNode.PassRate <= passRate) { /*说明全部的人员都完成了,就让合流点显示它。*/ DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE IsPass=3 AND WorkID=" + wn.HisWork.FID + " AND FK_Node=" + fk_node); } #endregion 处理完成率 } } /* 结束有待命的状态判断。*/ if (fk_node == 0) { /* 说明:没有找到等待启动工作的合流节点. */ gwf = new GenerWorkFlow(this.FID); Node fND = new Node(gwf.NodeID); switch (fND.HisNodeWorkType) { case NodeWorkType.WorkHL: /*主流程运行到合流点上了*/ break; default: /* 解决删除最后一个子流程时要把干流程也要删除。*/ sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE FK_Node=" + wn.HisNode.NodeID + " AND FID=" + wn.HisWork.FID; int num = DBAccess.RunSQLReturnValInt(sql); if (num == 0) { /*说明没有子进程,就要把这个流程执行完成。*/ WorkFlow wf = new WorkFlow(this.HisFlow, this.FID); info += "@所有的子线程已经结束。"; info += "@结束主流程信息。"; info += "@" + wf.DoFlowOver(ActionType.FlowOver, "主流程结束", null, null); } break; } } } #endregion #region 删除该流程下面的子流程. if (isDelSubFlow) { GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.PWorkID, this.WorkID); foreach (GenerWorkFlow item in gwfs) BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(item.WorkID, true); } #endregion 删除该流程下面的子流程. // 处理删除hou事件。 ExecEvent.DoFlow(EventListFlow.AfterFlowDel, wn, null); return info; } /// /// 删除工作流程记录日志,并保留运动轨迹. /// /// 是否要删除子流程 /// public string DoDeleteWorkFlowByWriteLog(string info, bool isDelSubFlow) { GERpt rpt = new GERpt("ND" + int.Parse(this.HisFlow.No) + "Rpt", this.WorkID); WorkFlowDeleteLog log = new WorkFlowDeleteLog(); log.OID = this.WorkID; try { log.Copy(rpt); log.DeleteDT = DataType.CurrentDateTime; log.OperDept = WebUser.DeptNo; log.OperDeptName = WebUser.DeptName; log.Oper = WebUser.No; log.DeleteNote = info; log.OID = this.WorkID; log.FlowNo = this.HisFlow.No; log.InsertAsOID(log.OID); return DoDeleteWorkFlowByReal(isDelSubFlow); } catch (Exception ex) { log.CheckPhysicsTable(); log.Delete(); throw new Exception(ex.StackTrace); } } #region 流程的强制终止\删除 或者恢复使用流程, /// /// 恢复流程. /// /// 回复流程的原因 public void DoComeBackWorkFlow(string msg) { try { //设置产生的工作流程为 GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); gwf.WFState = WFState.Runing; gwf.DirectUpdate(); // 增加消息 WorkNode wn = this.GetCurrentWorkNode(); GenerWorkerLists wls = new GenerWorkerLists(wn.HisWork.OID, wn.HisNode.NodeID); if (wls.Count == 0) throw new Exception("@恢复流程出现错误,产生的工作者列表"); foreach (GenerWorkerList item in wls) BP.WF.Dev2Interface.Port_SendMsg(item.EmpNo, "流程恢复通知:" + gwf.Title, "该流程[" + gwf.Title + "],请打开待办处理.", "rback"); } catch (Exception ex) { BP.DA.Log.DebugWriteError("@恢复流程出现错误." + ex.Message); throw new Exception("@恢复流程出现错误." + ex.Message); } } #endregion /// /// 得到当前的进行中的工作。 /// /// public WorkNode GetCurrentWorkNode() { int currNodeID = 0; GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = this.WorkID; if (gwf.RetrieveFromDBSources() == 0) { this.DoFlowOver(ActionType.FlowOver, "非正常结束,没有找到当前的流程记录。", null, null); throw new Exception("@" + string.Format("工作流程{0}已经完成。", this.HisGenerWorkFlow.Title)); } Node nd = new Node(gwf.NodeID); Work work = nd.HisWork; work.OID = this.WorkID; work.NodeID = nd.NodeID; work.SetValByKey("FK_Dept", BP.Web.WebUser.DeptNo); if (work.RetrieveFromDBSources() == 0) { BP.DA.Log.DebugWriteError("@WorkID=" + this.WorkID + ",FK_Node=" + gwf.NodeID + ".不应该出现查询不出来工作."); // 没有找到当前的工作节点的数据,流程出现未知的异常。 work.Rec = BP.Web.WebUser.No; try { work.Insert(); } catch (Exception ex) { BP.DA.Log.DebugWriteError("@没有找到当前的工作节点的数据,流程出现未知的异常" + ex.Message + ",不应该出现"); // 没有找到当前的工作节点的数据 } } work.FID = gwf.FID; WorkNode wn = new WorkNode(work, nd); return wn; } /// /// 结束分流的节点 /// /// /// public string DoFlowOverFeiLiu(GenerWorkFlow gwf) { // 查询出来有少没有完成的流程。 int i = DBAccess.RunSQLReturnValInt("SELECT COUNT(*) FROM WF_GenerWorkFlow WHERE FID=" + gwf.FID + " AND WFState!=1"); switch (i) { case 0: throw new Exception("@不应该的错误。"); case 1: DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE FID=" + gwf.FID + " OR WorkID=" + gwf.FID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE FID=" + gwf.FID + " OR WorkID=" + gwf.FID); Work wk = this.HisFlow.HisStartNode.HisWork; wk.OID = gwf.FID; wk.Update(); return "@当前的工作已经完成,该流程上所有的工作都已经完成。"; default: DBAccess.RunSQL("UPDATE WF_GenerWorkFlow SET WFState=1 WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=1 WHERE WorkID=" + this.WorkID); return "@当前的工作已经完成。"; } } /// /// 处理子线程完成. /// /// public string DoFlowThreadOver() { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); Node nd = new Node(gwf.NodeID); //DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID); string sql = "SELECT count(*) FROM WF_GenerWorkerlist WHERE FID=" + this.FID; int num = DBAccess.RunSQLReturnValInt(sql); if (DBAccess.RunSQLReturnValInt(sql) == 0) { /*说明这是最后一个*/ WorkFlow wf = new WorkFlow(this.FID); wf.DoFlowOver(ActionType.FlowOver, "子线程结束", null, null); return "@当前子线程已完成,干流程已完成。"; } else { return "@当前子线程已完成,干流程还有(" + num + ")个子线程未完成。"; } } /// /// 执行流程完成 /// /// /// /// /// /// 结束类型:自定义参数 /// /// /// public string DoFlowOver(ActionType at, string stopMsg, Node currNode, GERpt rpt, int stopFlowType = 1, string empNo = "", string empName = "") { if (null == currNode) return "err@当前节点为空.."; if (DataType.IsNullOrEmpty(stopMsg)) stopMsg += "流程结束"; //获得当前的节点. WorkNode wn = this.GetCurrentWorkNode(); wn.rptGe = rpt; //调用结束前事件. string mymsg = ExecEvent.DoFlow(EventListFlow.FlowOverBefore, wn, null); //string mymsg = this.HisFlow.DoFlowEventEntity(EventListFlow.FlowOverBefore, currNode, rpt, null); if (mymsg != null) stopMsg += "@" + mymsg; string exp = currNode.FocusField; if (DataType.IsNullOrEmpty(exp) == false && exp.Length > 1) { if (rpt != null) stopMsg += Glo.DealExp(exp, rpt, null); } //IsMainFlow== false 这个位置是子线程 if (this.ItIsMainFlow == false) { /* 处理子线程完成*/ stopMsg += this.DoFlowThreadOver(); } #region 处理明细表的汇总. this._IsComplete = 1; #endregion 处理明细表的汇总. #region 处理后续的业务. string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; Paras ps = new Paras(); if (1 == 2) { // 是否删除流程注册表的数据? ps = new Paras(); ps.SQL = "DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + dbstr + "WorkID1 OR FID=" + dbstr + "WorkID2 "; ps.Add("WorkID1", this.WorkID); ps.Add("WorkID2", this.WorkID); DBAccess.RunSQL(ps); } // 删除子线程产生的 流程注册信息. if (this.FID == 0) { ps = new Paras(); ps.SQL = "DELETE FROM WF_GenerWorkFlow WHERE FID=" + dbstr + "WorkID"; ps.Add("WorkID", this.WorkID); DBAccess.RunSQL(ps); } // 清除工作者. ps = new Paras(); ps.SQL = "DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + dbstr + "WorkID1 OR FID=" + dbstr + "WorkID2 "; ps.Add("WorkID1", this.WorkID); ps.Add("WorkID2", this.WorkID); DBAccess.RunSQL(ps); //把当前的人员字符串加入到参与人里面去,以方便查询. string emps = WebUser.No + "," + WebUser.Name + "@"; // 设置流程完成状态. ps = new Paras(); if (BP.Difference.SystemConfig.AppCenterDBType == DBType.Oracle || BP.Difference.SystemConfig.AppCenterDBType == DBType.KingBaseR3 || BP.Difference.SystemConfig.AppCenterDBType == DBType.KingBaseR6 || BP.Difference.SystemConfig.AppCenterDBType == DBType.PostgreSQL || BP.Difference.SystemConfig.AppCenterDBType == DBType.HGDB || BP.Difference.SystemConfig.AppCenterDBType == DBType.UX) ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET FlowEmps= FlowEmps ||'" + emps + "', WFState=:WFState,WFSta=:WFSta WHERE OID=" + dbstr + "OID"; else if (BP.Difference.SystemConfig.AppCenterDBType == DBType.MySQL) ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET FlowEmps= CONCAT(FlowEmps ,'" + emps + "'), WFState=" + dbstr + "WFState,WFSta=" + dbstr + "WFSta WHERE OID=" + dbstr + "OID"; else ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET FlowEmps= FlowEmps + '" + emps + "', WFState=" + dbstr + "WFState,WFSta=" + dbstr + "WFSta WHERE OID=" + dbstr + "OID"; ps.Add("WFState", (int)WFState.Complete); ps.Add("WFSta", (int)WFSta.Complete); ps.Add("OID", this.WorkID); DBAccess.RunSQL(ps); //加入轨迹. if (DataType.IsNullOrEmpty(empNo) == true) { empNo = WebUser.No; empName = WebUser.Name; } wn.AddToTrack(at, empNo, empName, wn.HisNode.NodeID, wn.HisNode.Name, stopMsg); //执行流程结束. GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); //增加参与的人员 if (gwf.Emps.Contains("@" + WebUser.No + ",") == false) gwf.Emps += "@" + WebUser.No + "," + WebUser.Name; gwf.WFState = WFState.Complete; gwf.SetPara("StopFlowType", stopFlowType); //结束流程类型. gwf.Update(); //生成关键字. this.GenerSKeyWords(gwf, wn.rptGe); //流程发送成功事件 string sendSuccess = ExecEvent.DoNode(EventListNode.SendSuccess, wn); //调用结束后事件. string result = ExecEvent.DoFlow(EventListFlow.FlowOverAfter, wn, null); if (result != null) stopMsg += result; #endregion 处理后续的业务. //执行最后一个子流程发送后的检查,不管是否成功,都要结束该流程。 stopMsg += WorkNodePlus.SubFlowEvent(wn); //string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; #region 处理审核问题,更新审核组件插入的审核意见中的 到节点,到人员。 ps = new Paras(); ps.SQL = "UPDATE ND" + int.Parse(currNode.FlowNo) + "Track SET NDTo=" + dbstr + "NDTo,NDToT=" + dbstr + "NDToT,EmpTo=" + dbstr + "EmpTo,EmpToT=" + dbstr + "EmpToT WHERE NDFrom=" + dbstr + "NDFrom AND EmpFrom=" + dbstr + "EmpFrom AND WorkID=" + dbstr + "WorkID AND ActionType=" + (int)ActionType.WorkCheck; ps.Add(TrackAttr.NDTo, currNode.NodeID); ps.Add(TrackAttr.NDToT, ""); ps.Add(TrackAttr.EmpTo, ""); ps.Add(TrackAttr.EmpToT, ""); ps.Add(TrackAttr.NDFrom, currNode.NodeID); ps.Add(TrackAttr.EmpFrom, WebUser.No); ps.Add(TrackAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); #endregion 处理审核问题. //如果存在 BillState列,执行更新, 让其可见. if (rpt.EnMap.Attrs.Contains("BillState") == true) { rpt.SetValByKey("BillState", 100); } else { string ptable = "ND" + int.Parse(gwf.FlowNo) + "Rpt"; if (rpt.EnMap.PhysicsTable.Equals(ptable) == false && DBAccess.IsExitsTableCol(rpt.EnMap.PhysicsTable, "BillState") == true) DBAccess.RunSQL("UPDATE " + rpt.EnMap.PhysicsTable + " SET BillState=100 WHERE OID=" + this.WorkID); } if (sendSuccess != null) return "@"+sendSuccess+stopMsg; return stopMsg; } /// /// 归档关键字查询 /// /// /// public void GenerSKeyWords(GenerWorkFlow gwf, Entity en) { //获取WF_GenerWorkFlow的关键字. string keyworkd = gwf.Title + gwf.TodoEmps + "," + gwf.FlowName; foreach (Attr item in en.EnMap.Attrs) { if (item.UIContralType == UIContralType.DDL) continue; if (item.MyDataType == DataType.AppString && item.MaxLength <= 100) { keyworkd += en.GetValStrByKey(item.Key)+","; continue; } keyworkd += en.GetValStrByKey(item.Key)+","; } if (DBAccess.IsExitsTableCol("WF_GenerWorkFlow", "SKeyWords") == false) return; Paras pa = new Paras(); pa.SQL = "UPDATE WF_GenerWorkFlow SET SKeyWords=" + SystemConfig.AppCenterDBVarStr + "SKeyWords WHERE WorkID=" + this.WorkID; pa.Add("SKeyWords", keyworkd); DBAccess.RunSQL(pa); } public string GenerFHStartWorkInfo() { string msg = ""; DataTable dt = DBAccess.RunSQLReturnTable("SELECT Title,RDT,Rec,OID FROM ND" + this.StartNodeID + " WHERE FID=" + this.FID); switch (dt.Rows.Count) { case 0: Node nd = new Node(this.StartNodeID); throw new Exception("@没有找到他们开始节点的数据,流程异常。FID=" + this.FID + ",节点:" + nd.Name + "节点ID:" + nd.NodeID); case 1: msg = string.Format("@发起人: {0} 日期:{1} 发起的流程 标题:{2} ,已经成功完成。", dt.Rows[0]["Rec"].ToString(), dt.Rows[0]["RDT"].ToString(), dt.Rows[0]["Title"].ToString()); break; default: msg = "@下列(" + dt.Rows.Count + ")位人员发起的流程已经完成。"; foreach (DataRow dr in dt.Rows) { msg += "
发起人:" + dr["Rec"] + " 发起日期:" + dr["RDT"] + " 标题:" + dr["Title"] + "详细..."; } break; } return msg; } public int StartNodeID { get { return int.Parse(this.HisFlow.No + "01"); } } /// /// 执行冻结 /// /// 冻结原因 public string DoFix(string fixMsg) { if (this.HisGenerWorkFlow.WFState == WFState.Fix) throw new Exception("@当前已经是冻结的状态您不能执行再冻结."); if (DataType.IsNullOrEmpty(fixMsg)) fixMsg = "无"; /* 获取它的工作者,向他们发送消息。*/ GenerWorkerLists wls = new GenerWorkerLists(this.WorkID, this.HisFlow.No); string emps = ""; foreach (GenerWorkerList wl in wls) { if (wl.ItIsEnable == false) continue; //不发送给禁用的人。 emps += wl.EmpNo + "," + wl.EmpName + ";"; //写入消息。 BP.WF.Dev2Interface.Port_SendMsg(wl.EmpNo, this.HisGenerWorkFlow.Title, fixMsg, "Fix" + wl.WorkID, "Fix", wl.FlowNo, wl.NodeID, wl.WorkID, wl.FID); } /* 执行 WF_GenerWorkFlow 冻结. */ int sta = (int)WFState.Fix; string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; Paras ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkFlow SET WFState=" + dbstr + "WFState WHERE WorkID=" + dbstr + "WorkID"; ps.Add(GenerWorkFlowAttr.WFState, sta); ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkerlist SET IsPass=" + dbstr + "IsPass WHERE WorkID=" + dbstr + "WorkID AND FK_Node=" + this.HisGenerWorkFlow.NodeID; ps.Add(GenerWorkerListAttr.IsPass, 9); ps.Add(GenerWorkerListAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); // 更新流程报表的状态。 ps = new Paras(); ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET WFState=" + dbstr + "WFState WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.WFState, sta); ps.Add(GERptAttr.OID, this.WorkID); DBAccess.RunSQL(ps); // 记录日志.. //WorkNode wn = new WorkNode(this.WorkID, this.HisGenerWorkFlow.NodeID); //wn.AddToTrack(ActionType.Info, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, fixMsg,); return this.WorkID + "-" + this.HisFlow.Name + "已经成功执行冻结"; } /// /// 执行解除冻结 /// /// 冻结原因 public string DoUnFix(string unFixMsg) { if (this.HisGenerWorkFlow.WFState != WFState.Fix) throw new Exception("@当前非冻结的状态您不能执行解除冻结."); if (DataType.IsNullOrEmpty(unFixMsg)) unFixMsg = "无"; ///* 获取它的工作者,向他们发送消息。*/ //GenerWorkerLists wls = new GenerWorkerLists(this.WorkID, this.HisFlow.No); //string url = Glo.ServerIP + "/" + this.VirPath + this.AppType + "/WorkOpt/OneWork/OneWork.htm?CurrTab=Track&FK_Flow=" + this.HisFlow.No + "&WorkID=" + this.WorkID + "&FID=" + this.HisGenerWorkFlow.FID + "&FK_Node=" + this.HisGenerWorkFlow.NodeID; //string mailDoc = "详细信息:打开流程轨迹."; //string title = "工作:" + this.HisGenerWorkFlow.Title + " 被" + WebUser.Name + "冻结" + unFixMsg; //string emps = ""; //foreach (GenerWorkerList wl in wls) //{ // if (wl.ItIsEnable == false) // continue; //不发送给禁用的人。 // emps += wl.EmpNo + "," + wl.EmpName + ";"; // //写入消息。 // BP.WF.Dev2Interface.Port_SendMsg(wl.EmpNo, title, mailDoc, "Fix" + wl.WorkID, BP.Sys.SMSMsgType.Self, wl.FK_Flow, wl.NodeID, wl.WorkID, wl.FID); //} /* 执行 WF_GenerWorkFlow 冻结. */ int sta = (int)WFState.Runing; string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; Paras ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkFlow SET WFState=" + dbstr + "WFState WHERE WorkID=" + dbstr + "WorkID"; ps.Add(GenerWorkFlowAttr.WFState, sta); ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); // 更新流程报表的状态。 ps = new Paras(); ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET WFState=" + dbstr + "WFState WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.WFState, sta); ps.Add(GERptAttr.OID, this.WorkID); DBAccess.RunSQL(ps); // 记录日志.. WorkNode wn = new WorkNode(this.WorkID, this.HisGenerWorkFlow.NodeID); //wn.AddToTrack(ActionType.Info, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, unFixMsg); return "已经成功执行解除冻结:"; } #endregion #region 基本属性 /// /// 他的节点 /// private Nodes _HisNodes = null; /// /// 节点s /// public Nodes HisNodes { get { if (this._HisNodes == null) this._HisNodes = this.HisFlow.HisNodes; return this._HisNodes; } } /// /// 工作节点s(普通的工作节点) /// private WorkNodes _HisWorkNodesOfWorkID = null; /// /// 工作节点s /// public WorkNodes HisWorkNodesOfWorkID { get { if (this._HisWorkNodesOfWorkID == null) { this._HisWorkNodesOfWorkID = new WorkNodes(); this._HisWorkNodesOfWorkID.GenerByWorkID(this.HisFlow, this.WorkID); } return this._HisWorkNodesOfWorkID; } } /// /// 工作节点s /// private WorkNodes _HisWorkNodesOfFID = null; /// /// 工作节点s /// public WorkNodes HisWorkNodesOfFID { get { if (this._HisWorkNodesOfFID == null) { this._HisWorkNodesOfFID = new WorkNodes(); this._HisWorkNodesOfFID.GenerByFID(this.HisFlow, this.FID); } return this._HisWorkNodesOfFID; } } /// /// 工作流程 /// private Flow _HisFlow = null; /// /// 工作流程 /// public Flow HisFlow { get { return this._HisFlow; } } private GenerWorkFlow _HisGenerWorkFlow = null; public GenerWorkFlow HisGenerWorkFlow { get { if (_HisGenerWorkFlow == null) _HisGenerWorkFlow = new GenerWorkFlow(this.WorkID); return _HisGenerWorkFlow; } set { _HisGenerWorkFlow = value; } } /// /// 工作ID /// private Int64 _WorkID = 0; /// /// 工作ID /// public Int64 WorkID { get { return this._WorkID; } } /// /// 工作ID /// private Int64 _FID = 0; /// /// 工作ID /// public Int64 FID { get { return this._FID; } set { this._FID = value; } } /// /// 是否是干流 /// public bool ItIsMainFlow { get { if (this.FID != 0 && this.FID != this.WorkID) return false; else return true; } } #endregion #region 构造方法 public WorkFlow(Int64 wkid) { this.HisGenerWorkFlow = new GenerWorkFlow(); this.HisGenerWorkFlow.RetrieveByAttr(GenerWorkerListAttr.WorkID, wkid); this._FID = this.HisGenerWorkFlow.FID; if (wkid == 0) throw new Exception("@没有指定工作ID, 不能创建工作流程."); Flow flow = new Flow(this.HisGenerWorkFlow.FlowNo); this._HisFlow = flow; this._WorkID = wkid; } public WorkFlow(Flow flow, Int64 wkid) { GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = wkid; gwf.RetrieveFromDBSources(); this._FID = gwf.FID; if (wkid == 0) throw new Exception("@没有指定工作ID, 不能创建工作流程."); //Flow flow= new Flow(FlowNo); this._HisFlow = flow; this._WorkID = wkid; } /// /// 建立一个工作流事例 /// /// 流程No /// 工作ID public WorkFlow(Flow flow, Int64 wkid, Int64 fid) { this._FID = fid; if (wkid == 0) throw new Exception("@没有指定工作ID, 不能创建工作流程."); //Flow flow= new Flow(FlowNo); this._HisFlow = flow; this._WorkID = wkid; } public WorkFlow(string FK_flow, Int64 wkid, Int64 fid) { this._FID = fid; Flow flow = new Flow(FK_flow); if (wkid == 0) throw new Exception("@没有指定工作ID, 不能创建工作流程."); //Flow flow= new Flow(FlowNo); this._HisFlow = flow; this._WorkID = wkid; } #endregion #region 运算属性 public int _IsComplete = -1; /// /// 是不是完成 /// public bool ItIsComplete { get { // bool s = !DBAccess.IsExits("select workid from WF_GenerWorkFlow WHERE WorkID=" + this.WorkID + " AND FK_Flow='" + this.HisFlow.No + "'"); GenerWorkFlow generWorkFlow = new GenerWorkFlow(this.WorkID); if (generWorkFlow.WFState == WFState.Complete) return true; else return false; } } /// /// 是不是完成 /// public string IsCompleteStr { get { if (this.ItIsComplete) return "已"; else return "未"; } } #endregion #region 静态方法 /// /// 是否这个工作人员能执行这个工作 /// /// 节点 /// 工作人员 /// 能不能执行 public static bool IsCanDoWorkCheckByEmpStation(int nodeId, string empId) { bool isCan = false; // 判断角色对应关系是不是能够执行. string sql = "SELECT a.FK_Node FROM WF_NodeStation a, Port_DeptEmpStation b WHERE (a.FK_Station=b.FK_Station) AND (a.FK_Node=" + nodeId + " AND b.FK_Emp='" + empId + "' )"; isCan = DBAccess.IsExits(sql); if (isCan) return true; // 判断他的主要工作角色能不能执行它. sql = "select FK_Node from WF_NodeStation WHERE FK_Node=" + nodeId + " AND ( FK_Station in (select FK_Station from Port_DeptEmpStation WHERE FK_Emp='" + empId + "') ) "; return DBAccess.IsExits(sql); } /// /// 是否这个工作人员能执行这个工作 /// /// 节点 /// 工作人员 /// 能不能执行 public static bool IsCanDoWorkCheckByEmpDuty(int nodeId, string dutyNo) { string sql = "SELECT a.FK_Node FROM WF_NodeDuty a, Port_EmpDuty b WHERE (a.FK_Duty=b.FK_Duty) AND (a.FK_Node=" + nodeId + " AND b.FK_Duty=" + dutyNo + ")"; if (DBAccess.RunSQLReturnTable(sql).Rows.Count == 0) return false; else return true; } /// /// 在物理上能构作这项工作的人员。 /// /// 节点ID /// public static DataTable CanDoWorkEmps(int nodeId) { string sql = "select a.FK_Node, b.EmpID from WF_NodeStation a, Port_DeptEmpStation b WHERE (a.FK_Station=b.FK_Station) AND (a.FK_Node=" + nodeId + " )"; return DBAccess.RunSQLReturnTable(sql); } /// /// GetEmpsBy /// /// /// public Emps GetEmpsBy(DataTable dt) { // 形成能够处理这件事情的用户几何。 Emps emps = new Emps(); foreach (DataRow dr in dt.Rows) { emps.AddEntity(new Emp(dr["EmpID"].ToString())); } return emps; } #endregion #region 流程方法 private string _AppType = null; /// /// 虚拟目录的路径 /// public string AppType { get { if (_AppType == null) { if (BP.Difference.SystemConfig.isBSsystem == false) { _AppType = "WF"; } else { _AppType = "WF"; } } return _AppType; } } private string _VirPath = null; /// /// 虚拟目录的路径 /// public string VirPath { get { if (_VirPath == null) { if (BP.Difference.SystemConfig.isBSsystem) _VirPath = HttpContextHelper.RequestApplicationPath; // _VirPath = BP.Sys.Base.Glo.Request.ApplicationPath; else _VirPath = ""; } return _VirPath; } } /// /// 撤销挂起 /// /// public string DoHungupWork_Un() { string checker = this.HisGenerWorkFlow.GetParaString("HungupChecker"); //删除领导审核的数据. DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE FK_Node=" + this.HisGenerWorkFlow.NodeID + " AND FK_Emp='" + checker + "' AND WorkID=" + this.HisGenerWorkFlow.WorkID); this.HisGenerWorkFlow.HungupTime = DataType.CurrentDateTime; this.HisGenerWorkFlow.WFState = WFState.Runing; this.HisGenerWorkFlow.Update(); string ptable = this.HisFlow.PTable; // 记录日志.. WorkNode wn = new WorkNode(this.WorkID, this.HisGenerWorkFlow.NodeID); wn.AddToTrack(ActionType.UnHungup, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, "撤销挂起"); return "成功撤销."; } /// /// 执行挂起 /// /// 挂起方式 /// 释放日期 /// 挂起原因 /// public string DoHungup(HungupWay way, string relData, string hungNote) { if (this.HisGenerWorkFlow.WFState == WFState.Hungup) return "err@当前已经是挂起的状态您不能执行在挂起."; if (DataType.IsNullOrEmpty(hungNote) == true) hungNote = "无"; if (way == HungupWay.SpecDataRel) { try { DateTime d = DataType.ParseSysDate2DateTime(relData); } catch (Exception ex) { throw new Exception("err@解除挂起的日期[" + relData + "]不正确" + ex.Message); } } if (relData == null) relData = ""; /* 获取它的工作者,向他们发送消息。*/ GenerWorkerLists wls = new GenerWorkerLists(this.WorkID, this.HisFlow.No); //string mailDoc = "详细信息:打开流程轨迹."; string title = "工作:" + this.HisGenerWorkFlow.Title + " 被" + WebUser.Name + "挂起" + hungNote; string emps = ""; GenerWorkerList gwl = null; foreach (GenerWorkerList wl in wls) { if (wl.ItIsEnable == false) continue; //不发送给禁用的人。 //BP.WF.Port.WFEmp emp = new BP.Port.WFEmp(wl.EmpNo); emps += wl.EmpNo + "," + wl.EmpName + ";"; gwl = wl; //写入消息。 BP.WF.Dev2Interface.Port_SendMsg(wl.EmpNo, title, title, "Hungup" + wl.WorkID, BP.WF.SMSMsgType.Hungup, wl.FlowNo, wl.NodeID, wl.WorkID, wl.FID); } /* 执行 WF_GenerWorkFlow 挂起. */ int hungSta = (int)WFState.Hungup; string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; //发送人. string[] sender = this.HisGenerWorkFlow.Sender.Split(','); gwl.EmpNo = sender[0]; gwl.EmpName= sender[1]; gwl.WorkID = this.HisGenerWorkFlow.WorkID; gwl.NodeID = this.HisGenerWorkFlow.NodeID; gwl.PassInt = 0; gwl.ItIsRead = false; gwl.SDT = "2030-01-01 10:00"; gwl.RDT = DataType.CurrentDateTimess; // gwl.FID = this.HisGenerWorkFlow.FID; gwl.Save(); //更新挂起状态. this.HisGenerWorkFlow.WFState = WFState.Hungup; this.HisGenerWorkFlow.SetPara("Hunguper", BP.Web.WebUser.No); this.HisGenerWorkFlow.SetPara("HunguperName", BP.Web.WebUser.Name); this.HisGenerWorkFlow.SetPara("HungupWay", (int)way); this.HisGenerWorkFlow.SetPara("HungupRelDate", relData); this.HisGenerWorkFlow.SetPara("HungupNote", hungNote); this.HisGenerWorkFlow.SetPara("HungupSta", (int)HungupSta.Apply); //设置申请状态. this.HisGenerWorkFlow.SetPara("HungupChecker", gwl.EmpNo); //要审批的人. this.HisGenerWorkFlow.HungupTime = DataType.CurrentDateTime; this.HisGenerWorkFlow.Update(); // 更新流程报表的状态。 Paras ps = new Paras(); ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET WFState=" + dbstr + "WFState WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.WFState, hungSta); ps.Add(GERptAttr.OID, this.WorkID); DBAccess.RunSQL(ps); // 记录日志.. WorkNode wn = new WorkNode(this.WorkID, this.HisGenerWorkFlow.NodeID); wn.AddToTrack(ActionType.Hungup, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, hungNote); return "已经成功执行挂起,并且已经通知给:" + emps; } /// /// 同意挂起 /// /// public string HungupWorkAgree() { if (this.HisGenerWorkFlow.WFState != WFState.Hungup) throw new Exception("@非挂起状态,您不能解除挂起."); this.HisGenerWorkFlow.SetPara("HungupSta", (int)HungupSta.Agree); //同意. this.HisGenerWorkFlow.SetPara("HungupChecker", BP.Web.WebUser.No); this.HisGenerWorkFlow.SetPara("HungupCheckerName", BP.Web.WebUser.Name); this.HisGenerWorkFlow.SetPara("HungupCheckRDT", DataType.CurrentDateTime); this.HisGenerWorkFlow.Update(); //如果是按照指定的日期解除挂起. int way = this.HisGenerWorkFlow.GetParaInt("HungupWay"); if (way == 1) { string relDT = this.HisGenerWorkFlow.GetParaString("HungupRelDate"); DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET SDT='" + relDT + "' WHERE WorkID=" + this.WorkID + " AND FK_Node=" + this.HisGenerWorkFlow.NodeID); } //删除当前的待办. GenerWorkerList gwl = new GenerWorkerList(); gwl.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.HisGenerWorkFlow.NodeID, GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No); //更新业务表的状态. DBAccess.RunSQL("UPDATE " + this.HisFlow.PTable + " SET WFState=" + (int)WFState.Hungup + " WHERE OID=" + this.WorkID); return "已经同意挂起."; } /// /// 新增取消挂起的API /// /// /// public string CancelHungupWork() { if (this.HisGenerWorkFlow.WFState != WFState.Hungup) throw new Exception("@非挂起状态,您不能取消挂起."); /* 执行解除挂起. */ this.HisGenerWorkFlow.WFState = WFState.Runing; //这里仅仅更新大的状态就好,不在处理AtPara的参数状态. this.HisGenerWorkFlow.Update(); // 更新流程报表的状态。 string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; Paras ps = new Paras(); ps = new Paras(); ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET WFState=2 WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.OID, this.WorkID); DBAccess.RunSQL(ps); // 更新工作者的挂起时间。 ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkerlist SET DTOfUnHungup=" + dbstr + "DTOfUnHungup WHERE FK_Node=" + dbstr + "FK_Node AND WorkID=" + dbstr + "WorkID"; ps.Add(GenerWorkerListAttr.DTOfUnHungup, DataType.CurrentDateTime); ps.Add(GenerWorkerListAttr.FK_Node, this.HisGenerWorkFlow.NodeID); ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); // 记录日志.. WorkNode wn = new WorkNode(this.WorkID, this.HisGenerWorkFlow.NodeID); wn.AddToTrack(ActionType.UnHungup, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, ""); return "您已经取消挂起,该流程实例已经进入了正常运行状态."; } /// /// 拒绝挂起 @wwh /// /// public string HungupWorkReject(string msg) { if (this.HisGenerWorkFlow.WFState != WFState.Hungup) throw new Exception("@非挂起状态,您不能解除挂起."); /* 执行解除挂起. */ this.HisGenerWorkFlow.WFState = WFState.Hungup; this.HisGenerWorkFlow.SetPara("HungupSta", (int)HungupSta.Reject); //不同意. this.HisGenerWorkFlow.SetPara("HungupNodeID", this.HisGenerWorkFlow.NodeID); //不同意. this.HisGenerWorkFlow.SetPara("HungupCheckMsg", msg); //拒绝原因. this.HisGenerWorkFlow.Update(); // 更新流程报表的状态。 string dbstr = BP.Difference.SystemConfig.AppCenterDBVarStr; Paras ps = new Paras(); ps = new Paras(); ps.SQL = "UPDATE " + this.HisFlow.PTable + " SET WFState=4 WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.OID, this.WorkID); DBAccess.RunSQL(ps); // 更新工作者的挂起时间。 ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkerlist SET DTOfUnHungup=" + dbstr + "DTOfUnHungup WHERE FK_Node=" + dbstr + "FK_Node AND WorkID=" + dbstr + "WorkID"; ps.Add(GenerWorkerListAttr.DTOfUnHungup, DataType.CurrentDateTime); ps.Add(GenerWorkerListAttr.FK_Node, this.HisGenerWorkFlow.NodeID); ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); /* 获取它的工作者,向他们发送消息。*/ GenerWorkerLists wls = new GenerWorkerLists(this.WorkID); wls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.HisGenerWorkFlow.NodeID); //string url = Glo.ServerIP + "/" + this.VirPath + this.AppType + "/MyFlow.htm?FK_Flow=" + this.HisFlow.No + "&WorkID=" + this.WorkID + "&FID=" + this.HisGenerWorkFlow.FID + "&FK_Node=" + this.HisGenerWorkFlow.NodeID; //string mailDoc = "详细信息:打开流程."; //mailDoc += " 拒绝原因:" + msg; string title = "工作:" + this.HisGenerWorkFlow.Title + " 被" + WebUser.Name + "拒绝挂起."; string emps = ""; foreach (GenerWorkerList wl in wls) { if (wl.ItIsEnable == false) continue; //不发送给禁用的人。 emps += wl.EmpNo + "," + wl.EmpName + ";"; //写入消息。 BP.WF.Dev2Interface.Port_SendMsg(wl.EmpNo, title, msg, "RejectHungup" + wl.NodeID + this.WorkID, BP.WF.SMSMsgType.RejectHungup, HisGenerWorkFlow.FlowNo, HisGenerWorkFlow.NodeID, this.WorkID, this.FID); } // 记录日志.. WorkNode wn = new WorkNode(this.WorkID, this.HisGenerWorkFlow.NodeID); wn.AddToTrack(ActionType.UnHungup, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, "拒绝挂起,通知给:" + emps); //删除当前的待办(当前人是,审核人.) GenerWorkerList gwl = new GenerWorkerList(); gwl.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.HisGenerWorkFlow.NodeID, GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No); //更新业务表的状态. DBAccess.RunSQL("UPDATE " + this.HisFlow.PTable + " SET WFState=" + (int)WFState.Runing + " WHERE OID=" + this.WorkID); return "您不同意对方挂起,该流程实例已经进入了正常运行状态."; } #endregion } /// /// 工作流程集合. /// public class WorkFlows : CollectionBase { #region 构造 /// /// 工作流程集合 /// public WorkFlows() { } /// /// 工作流程集合 /// /// 流程 /// 工作ID public WorkFlows(Flow flow, int flowState) { //StartWorks ens = (StartWorks)flow.HisStartNode.HisWorks; //QueryObject qo = new QueryObject(ens); //qo.AddWhere(GERptAttr.WFState, flowState); //qo.DoQuery(); //foreach (StartWork sw in ens) //{ // this.Add(new WorkFlow(flow, sw.OID, sw.FID)); //} } #endregion #region 方法 /// /// 增加一个工作流程 /// /// 工作流程 public void Add(WorkFlow wn) { this.InnerList.Add(wn); } /// /// 根据位置取得数据 /// public WorkFlow this[int index] { get { return (WorkFlow)this.InnerList[index]; } } #endregion #region 关于调度的自动方法 /// /// 清除死节点。 /// 死节点的产生,就是用户非法的操作,或者系统出现存储故障,造成的流程中的当前工作节点没有工作人员,从而不能正常的运行下去。 /// 清除死节点,就是把他们放到死节点工作集合里面。 /// /// public static string ClearBadWorkNode() { string infoMsg = "清除死节点的信息:"; string errMsg = "清除死节点的错误信息:"; return infoMsg + errMsg; } #endregion } }