/// <summary> /// 返回子线程启动的子流程对应的父流程ID /// </summary> /// <param name="userNo"></param> /// <param name="workId"></param> /// <returns></returns> /// <remarks> 2015-9-25 </remarks> public static long GetFatherIDOfSubFlow(string userNo, long workId) { UserLogin(userNo); BP.WF.GenerWorkFlow gwf = new BP.WF.GenerWorkFlow(workId); return(gwf.PFID); }
public static string GetFlowIdentification(string userNo, long workId) { UserLogin(userNo); BP.WF.GenerWorkFlow gwf = new BP.WF.GenerWorkFlow(workId); return(gwf.Paras_GroupMark); }
/// <summary> /// 运行中 0 /// 已完成 1 /// 其他 2 /// </summary> /// <param name="userNo"></param> /// <param name="workId"></param> /// <returns></returns> public static GenerWorkFlow GetGenerWorkFlow(string userNo, long workId) { UserLogin(userNo); try { BP.WF.GenerWorkFlow gwf = new BP.WF.GenerWorkFlow(workId); return(gwf); } catch { return(null); } }
/// <summary> /// 得到当前的进行中的工作。 /// </summary> /// <returns></returns> public WorkNode GetCurrentWorkNode() { int currNodeID = 0; GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); gwf.WorkID = this.WorkID; if (gwf.RetrieveFromDBSources() == 0) { // this.DoFlowOver(ActionType.FlowOver, "非正常结束,没有找到当前的流程记录。"); throw new Exception("@" + string.Format("工作流程{0}已经完成。", this.WorkID)); } Node nd = new Node(gwf.FK_Node); Work work = nd.HisWork; work.OID = this.WorkID; work.NodeID = nd.NodeID; work.SetValByKey("FK_Dept", BP.Web.WebUser.FK_Dept); if (work.RetrieveFromDBSources() == 0) { Log.DefaultLogWriteLineError("@WorkID=" + this.WorkID + ",FK_Node=" + gwf.FK_Node + ".不应该出现查询不出来工作."); // 没有找到当前的工作节点的数据,流程出现未知的异常。 work.Rec = BP.Web.WebUser.No; try { work.Insert(); } catch (Exception ex) { Log.DefaultLogWriteLineError("@没有找到当前的工作节点的数据,流程出现未知的异常" + ex.Message + ",不应该出现"); // 没有找到当前的工作节点的数据 } } work.FID = gwf.FID; WorkNode wn = new WorkNode(work, nd); return(wn); }
/// <summary> /// 执行子线程的撤销. /// </summary> /// <returns></returns> private string DoThreadUnSend() { //定义当前的节点. WorkNode wn = this.GetCurrentWorkNode(); GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); Node nd = new Node(gwf.FK_Node); #region 求的撤销的节点. int cancelToNodeID = 0; if (nd.HisCancelRole == CancelRole.SpecNodes) { /*1.指定的节点可以撤销,首先判断是否设置指定的节点.*/ // NodeCancels ncs = new NodeCancels(); ncs.Retrieve(NodeCancelAttr.FK_Node, wn.HisNode.NodeID); if (ncs.Count == 0) { throw new Exception("@流程设计错误, 您设置了当前节点(" + wn.HisNode.Name + ")可以让指定的节点人员撤销,但是您没有设置指定的节点."); } //获取Track表 string truckTable = "ND" + int.Parse(wn.HisNode.FK_Flow) + "Track"; //获取到当前节点走过的节点 与 设定可撤销节点的交集 string sql = "SELECT DISTINCT(FK_Node) FROM WF_GenerWorkerlist WHERE "; sql += " FK_Node IN(SELECT CancelTO FROM WF_NodeCancel WHERE FK_Node=" + wn.HisNode.NodeID + ") AND FK_Emp='" + WebUser.No + "'"; string nds = DBAccess.RunSQLReturnString(sql); if (DataType.IsNullOrEmpty(nds)) { throw new Exception("@您不能执行撤消发送,两种原因:1,你不具备撤销该节点的功能;2.流程设计错误,你指定的可以撤销的节点不在流程运转中走过的节点."); } //获取可以删除到的节点 cancelToNodeID = int.Parse(nds.Split(',')[0]); } if (nd.HisCancelRole == CancelRole.OnlyNextStep) { /*如果仅仅允许撤销上一步骤.*/ WorkNode wnPri = wn.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID); if (num == 0) { throw new Exception("@您不能执行撤消发送,因为当前工作不是您发送的或下一步工作已处理。"); } cancelToNodeID = wnPri.HisNode.NodeID; } if (cancelToNodeID == 0) { throw new Exception("@没有求出要撤销到的节点."); } #endregion 求的撤销的节点. /********** 开始执行撤销. **********************/ Node cancelToNode = new Node(cancelToNodeID); switch (cancelToNode.HisNodeWorkType) { case NodeWorkType.StartWorkFL: case NodeWorkType.WorkFHL: case NodeWorkType.WorkFL: // 调用撤消发送前事件。 nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wn.HisWork, null); BP.WF.Dev2Interface.Node_FHL_KillSubFlow(cancelToNode.FK_Flow, this.FID, this.WorkID); //杀掉子线程. // 调用撤消发送前事件。 nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wn.HisWork, null); return("KillSubThared@子线程撤销成功."); default: break; } // if (cancelToNode.HisNodeWorkType == NodeWorkType.StartWorkFL) WorkNode wnOfCancelTo = new WorkNode(this.WorkID, cancelToNodeID); // 调用撤消发送前事件。 string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wn.HisWork, null); #region 除当前节点数据。 // 删除产生的工作列表。 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node); // 删除工作信息,如果是按照ccflow格式存储的。 if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } // 删除附件信息。 DBAccess.RunSQL("DELETE FROM Sys_FrmAttachmentDB WHERE FK_MapData='ND" + gwf.FK_Node + "' AND RefPKVal='" + this.WorkID + "'"); #endregion 除当前节点数据。 // 更新. gwf.FK_Node = cancelToNode.NodeID; gwf.NodeName = cancelToNode.Name; //如果不启动自动记忆,删除tonodes,用于 选择节点发送。撤消后,可重新选择节点发送 if (cancelToNode.IsRememberMe == false) { gwf.Paras_ToNodes = ""; } if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { gwf.TaskSta = TaskSta.Takeback; } else { gwf.TaskSta = TaskSta.None; } gwf.TodoEmps = WebUser.No + "," + WebUser.Name + ";"; gwf.Update(); if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { //设置全部的人员不可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=-1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); //设置当前人员可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND FK_Emp='" + WebUser.No + "'"); } else { BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); } //更新当前节点,到rpt里面。 BP.DA.DBAccess.RunSQL("UPDATE " + this.HisFlow.PTable + " SET FlowEndNode=" + gwf.FK_Node + " WHERE OID=" + this.WorkID); // 记录日志.. wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, cancelToNode.NodeID, cancelToNode.Name, "无"); // 删除数据. if (wn.HisNode.IsStartNode) { DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID); } if (wn.HisNode.IsEval) { /*如果是质量考核节点,并且撤销了。*/ DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.WorkID); } #region 恢复工作轨迹,解决工作抢办。 if (cancelToNode.IsStartNode == false && cancelToNode.IsEnableTaskPool == false) { WorkNode ppPri = wnOfCancelTo.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); wl.Retrieve(GenerWorkerListAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.WorkID); RememberMe rm = new RememberMe(); rm.Retrieve(RememberMeAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, RememberMeAttr.FK_Emp, ppPri.HisWork.Rec); string[] empStrs = rm.Objs.Split('@'); foreach (string s in empStrs) { if (s == "" || s == null) { continue; } if (s == wl.FK_Emp) { continue; } GenerWorkerList wlN = new GenerWorkerList(); wlN.Copy(wl); wlN.FK_Emp = s; WF.Port.WFEmp myEmp = new Port.WFEmp(s); wlN.FK_EmpText = myEmp.Name; wlN.Insert(); } } #endregion 恢复工作轨迹,解决工作抢办。 #region 如果是开始节点, 检查此流程是否有子线程,如果有则删除它们。 if (nd.IsStartNode) { /*要检查一个是否有 子流程,如果有,则删除它们。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.PWorkID, this.WorkID); if (gwfs.Count > 0) { foreach (GenerWorkFlow item in gwfs) { /*删除每个子线程.*/ BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(item.FK_Flow, item.WorkID, true); } } } #endregion #region 计算完成率。 bool isSetEnable = false; //是否关闭合流节点待办. string mysql = "SELECT COUNT(DISTINCT WorkID) FROM WF_GenerWorkerlist WHERE FID=" + this.FID + " AND IsPass=1 AND FK_Node IN (SELECT Node FROM WF_Direction WHERE ToNode=" + wn.HisNode.NodeID + ")"; decimal numOfPassed = DBAccess.RunSQLReturnValDecimal(mysql, 0, 1); if (nd.PassRate == 100) { isSetEnable = true; } else { mysql = "SELECT COUNT(DISTINCT WorkID) FROM WF_GenerWorkFlow WHERE FID=" + this.FID; decimal numOfAll = DBAccess.RunSQLReturnValDecimal(mysql, 0, 1); decimal rate = numOfPassed / numOfAll * 100; if (nd.PassRate > rate) { isSetEnable = true; } } GenerWorkFlow maingwf = new GenerWorkFlow(this.FID); maingwf.SetPara("ThreadCount", numOfPassed.ToString()); maingwf.Update(); //是否关闭合流节点待办. if (isSetEnable == true) { DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=3 WHERE WorkID=" + this.FID + " AND FK_Node=" + wn.HisNode.NodeID); } #endregion //调用撤消发送后事件。 msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wn.HisWork, null); if (wnOfCancelTo.HisNode.IsStartNode) { return("@撤消执行成功. " + msg); } else { return("@撤消执行成功. " + msg); } return("工作已经被您撤销到:" + cancelToNode.Name); }
public string DoUnSendSubFlow(GenerWorkFlow gwf) { WorkNode wn = this.GetCurrentWorkNode(); WorkNode wnPri = wn.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID); if (num == 0) { return("@您不能执行撤消发送,因为当前工作不是您发送的。"); } // 处理事件。 string msg = wn.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, wn.HisNode, wn.HisWork, null); // 删除工作者。 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node.ToString()); if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } gwf.FK_Node = wnPri.HisNode.NodeID; gwf.NodeName = wnPri.HisNode.Name; gwf.Update(); BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); ShiftWorks fws = new ShiftWorks(); fws.Delete(ShiftWorkAttr.FK_Node, wn.HisNode.NodeID.ToString(), ShiftWorkAttr.WorkID, this.WorkID.ToString()); #region 判断撤消的百分比条件的临界点条件 if (wn.HisNode.PassRate != 0) { decimal all = (decimal)BP.DA.DBAccess.RunSQLReturnValInt("SELECT COUNT(*) NUM FROM WF_GenerWorkerList WHERE FID=" + this.FID + " AND FK_Node=" + wnPri.HisNode.NodeID); decimal ok = (decimal)BP.DA.DBAccess.RunSQLReturnValInt("SELECT COUNT(*) NUM FROM WF_GenerWorkerList WHERE FID=" + this.FID + " AND IsPass=1 AND FK_Node=" + wnPri.HisNode.NodeID); decimal rate = ok / all * 100; if (wn.HisNode.PassRate <= rate) { DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.FID); } else { DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=3 WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.FID); } } #endregion // 处理事件。 msg += wn.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, wn.HisNode, wn.HisWork, null); // 记录日志.. wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, "无"); return("@撤消执行成功." + msg); }
/// <summary> /// 合流点向子线程退回 /// </summary> private string ExeReturn3_4() { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); gwf.FK_Node = this.ReurnToNode.NodeID; gwf.WFState = WFState.Runing; gwf.Update(); string info = "@工作已经成功的退回到(" + ReurnToNode.Name + ")退回给:"; GenerWorkerLists gwls = new GenerWorkerLists(); gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.ReurnToNode.NodeID); string toEmp = ""; string toEmpName = ""; foreach (GenerWorkerList item in gwls) { item.IsPass = false; item.IsRead = false; item.Update(); info += item.FK_Emp + "," + item.FK_EmpText; toEmp = item.FK_Emp; toEmpName = item.FK_EmpText; } //删除已经发向合流点的汇总数据. MapDtls dtls = new MapDtls("ND" + this.HisNode.NodeID); foreach (MapDtl dtl in dtls) { /*如果是合流数据*/ if (dtl.IsHLDtl) { BP.DA.DBAccess.RunSQL("DELETE " + dtl.PTable + " WHERE OID=" + this.WorkID); } } // 记录退回轨迹。 ReturnWork rw = new ReturnWork(); rw.WorkID = this.WorkID; rw.ReturnToNode = this.ReurnToNode.NodeID; rw.ReturnNodeName = this.ReurnToNode.Name; rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点. rw.ReturnToEmp = toEmp; //退回给。 rw.MyPK = DBAccess.GenerOIDByGUID().ToString(); rw.Note = Msg; rw.IsBackTracking = this.IsBackTrack; rw.Insert(); // 加入track. this.AddToTrack(ActionType.Return, toEmp, toEmpName, this.ReurnToNode.NodeID, this.ReurnToNode.Name, Msg); // 返回退回信息. return(info); }
/// <summary> /// 普通节点到普通节点的退回 /// </summary> /// <returns></returns> private string ExeReturn1_1() { //退回前事件 string atPara = "@ToNode=" + this.ReturnToNode.NodeID; string msg = this.HisNode.HisFlow.DoFlowEventEntity(EventListOfNode.ReturnBefore, this.HisNode, this.HisWork, atPara); if (this.HisNode.FocusField != "") { try { string focusField = ""; string[] focusFields = this.HisNode.FocusField.Split('@'); if (focusFields.Length >= 2) { focusField = focusFields[1]; } else { focusField = focusFields[0]; } // 把数据更新它。 this.HisWork.Update(focusField, ""); } catch (Exception ex) { Log.DefaultLogWriteLineError("退回时更新焦点字段错误:" + ex.Message); } } // 改变当前待办工作节点。 Paras ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkFlow SET WFState=" + dbStr + "WFState,FK_Node=" + dbStr + "FK_Node,NodeName=" + dbStr + "NodeName WHERE WorkID=" + dbStr + "WorkID"; ps.Add(GenerWorkFlowAttr.WFState, (int)WFState.ReturnSta); ps.Add(GenerWorkFlowAttr.FK_Node, this.ReturnToNode.NodeID); ps.Add(GenerWorkFlowAttr.NodeName, this.ReturnToNode.Name); ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkerList SET IsPass=0,IsRead=0 WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID"; ps.Add("FK_Node", this.ReturnToNode.NodeID); ps.Add("WorkID", this.WorkID); DBAccess.RunSQL(ps); //更新流程报表数据. ps = new Paras(); ps.SQL = "UPDATE " + this.HisNode.HisFlow.PTable + " SET WFState=" + dbStr + "WFState, FlowEnder=" + dbStr + "FlowEnder, FlowEndNode=" + dbStr + "FlowEndNode WHERE OID=" + dbStr + "OID"; ps.Add("WFState", (int)WFState.ReturnSta); ps.Add("FlowEnder", WebUser.No); ps.Add("FlowEndNode", ReturnToNode.NodeID); ps.Add("OID", this.WorkID); DBAccess.RunSQL(ps); //从工作人员列表里找到被退回人的接受人. GenerWorkerList gwl = new GenerWorkerList(); gwl.Retrieve(GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // 记录退回轨迹。 ReturnWork rw = new ReturnWork(); rw.WorkID = this.WorkID; rw.ReturnToNode = this.ReturnToNode.NodeID; rw.ReturnNodeName = this.ReturnToNode.Name; rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点. rw.ReturnToEmp = gwl.FK_Emp; //退回给。 rw.Note = Msg; if (this.HisNode.TodolistModel == TodolistModel.Order || this.HisNode.TodolistModel == TodolistModel.Sharing || this.HisNode.TodolistModel == TodolistModel.Teamup) { rw.IsBackTracking = true; /*如果是共享,顺序,协作模式,都必须是退回并原路返回.*/ // 需要更新当前人待办的状态, 把1000作为特殊标记,让其发送时可以找到他. string sql = "UPDATE WF_GenerWorkerlist SET IsPass=1000 WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID + " AND FK_Emp='" + WebUser.No + "'"; if (BP.DA.DBAccess.RunSQL(sql) == 0) { throw new Exception("@退回错误,没有找到要更新的目标数据.技术信息:" + sql); } } else { rw.IsBackTracking = this.IsBackTrack; //调用删除GenerWorkerList数据,不然会导致两个节点之间有垃圾数据,特别遇到中间有分合流时候。 this.DeleteSpanNodesGenerWorkerListData(); } rw.MyPK = DBAccess.GenerOIDByGUID().ToString(); rw.Insert(); // 加入track. this.AddToTrack(ActionType.Return, gwl.FK_Emp, gwl.FK_EmpText, this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg); try { // 记录退回日志. this.HisNode, this.ReturnToNode ReorderLog(this.ReturnToNode, this.HisNode, rw); } catch (Exception ex) { Log.DebugWriteWarning(ex.Message); } // 以退回到的节点向前数据用递归删除它。 if (IsBackTrack == false) { /*如果退回不需要原路返回,就删除中间点的数据。*/ #warning 没有考虑两种流程数据存储模式。 //DeleteToNodesData(this.ReturnToNode.HisToNodes); } // 向他发送消息。 if (Glo.IsEnableSysMessage == true) { // WF.Port.WFEmp wfemp = new Port.WFEmp(wnOfBackTo.HisWork.Rec); string title = string.Format("工作退回:流程:{0}.工作:{1},退回人:{2},需您处理", this.HisNode.FlowName, this.ReturnToNode.Name, WebUser.Name); BP.WF.Dev2Interface.Port_SendMsg(gwl.FK_Emp, title, Msg, "RE" + this.HisNode.NodeID + this.WorkID, BP.WF.SMSMsgType.ToDo, ReturnToNode.FK_Flow, ReturnToNode.NodeID, this.WorkID, this.FID); } string text = this.HisNode.HisFlow.DoFlowEventEntity(EventListOfNode.ReturnAfter, this.HisNode, this.HisWork, atPara); if (text != null && text.Length > 1000) { text = "退回事件:无返回信息."; } // 返回退回信息. if (this.ReturnToNode.IsGuestNode) { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); return("工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + gwf.GuestNo + "," + gwf.GuestName + ").\n\r" + text); } else { return("工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + gwl.FK_Emp + "," + gwl.FK_EmpText + ").\n\r" + text); } }
/// <summary> /// 队列节点上一个人退回另外一个人. /// </summary> /// <returns></returns> public string DoOrderReturn() { //退回前事件 string atPara = "@ToNode=" + this.ReturnToNode.NodeID; string msg = this.HisNode.HisFlow.DoFlowEventEntity(EventListOfNode.ReturnBefore, this.HisNode, this.HisWork, atPara); if (this.HisNode.FocusField != "") { try { string focusField = ""; string[] focusFields = this.HisNode.FocusField.Split('@'); if (focusFields.Length >= 2) { focusField = focusFields[1]; } else { focusField = focusFields[0]; } // 把数据更新它。 this.HisWork.Update(focusField, ""); } catch (Exception ex) { Log.DefaultLogWriteLineError("退回时更新焦点字段错误:" + ex.Message); } } //退回到人. Emp returnToEmp = new Emp(this.ReturnToEmp); // 退回状态。 Paras ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkFlow SET WFState=" + dbStr + "WFState,FK_Node=" + dbStr + "FK_Node,NodeName=" + dbStr + "NodeName,TodoEmps=" + dbStr + "TodoEmps, TodoEmpsNum=0 WHERE WorkID=" + dbStr + "WorkID"; ps.Add(GenerWorkFlowAttr.WFState, (int)WFState.ReturnSta); ps.Add(GenerWorkFlowAttr.FK_Node, this.ReturnToNode.NodeID); ps.Add(GenerWorkFlowAttr.NodeName, this.ReturnToNode.Name); ps.Add(GenerWorkFlowAttr.TodoEmps, returnToEmp.No + "," + returnToEmp.Name + ";"); ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID); DBAccess.RunSQL(ps); ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkerList SET IsPass=0,IsRead=0 WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID AND FK_Emp=" + dbStr + "FK_Emp "; ps.Add("FK_Node", this.ReturnToNode.NodeID); ps.Add("WorkID", this.WorkID); ps.Add("FK_Emp", this.ReturnToEmp); DBAccess.RunSQL(ps); ps = new Paras(); ps.SQL = "UPDATE WF_GenerWorkerList SET IsPass=1000,IsRead=0 WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID AND FK_Emp=" + dbStr + "FK_Emp "; ps.Add("FK_Node", this.HisNode.NodeID); ps.Add("WorkID", this.WorkID); ps.Add("FK_Emp", WebUser.No); DBAccess.RunSQL(ps); //更新流程报表数据. ps = new Paras(); ps.SQL = "UPDATE " + this.HisNode.HisFlow.PTable + " SET WFState=" + dbStr + "WFState, FlowEnder=" + dbStr + "FlowEnder, FlowEndNode=" + dbStr + "FlowEndNode WHERE OID=" + dbStr + "OID"; ps.Add("WFState", (int)WFState.ReturnSta); ps.Add("FlowEnder", WebUser.No); ps.Add("FlowEndNode", ReturnToNode.NodeID); ps.Add("OID", this.WorkID); DBAccess.RunSQL(ps); ////从工作人员列表里找到被退回人的接受人. //GenerWorkerList gwl = new GenerWorkerList(); //gwl.Retrieve(GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // 记录退回轨迹。 ReturnWork rw = new ReturnWork(); rw.WorkID = this.WorkID; rw.ReturnToNode = this.ReturnToNode.NodeID; rw.ReturnNodeName = this.ReturnToNode.Name; rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点. rw.ReturnToEmp = this.ReturnToEmp; //退回给。 rw.Note = Msg; rw.MyPK = DBAccess.GenerOIDByGUID().ToString(); rw.Insert(); // 加入track. this.AddToTrack(ActionType.Return, returnToEmp.No, returnToEmp.Name, this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg); try { // 记录退回日志. ReorderLog(this.HisNode, this.ReturnToNode, rw); } catch (Exception ex) { Log.DebugWriteWarning(ex.Message); } // 以退回到的节点向前数据用递归删除它。 if (IsBackTrack == false) { /*如果退回不需要原路返回,就删除中间点的数据。*/ #warning 没有考虑两种流程数据存储模式。 //DeleteToNodesData(this.ReturnToNode.HisToNodes); } // 向他发送消息。 if (Glo.IsEnableSysMessage == true) { // WF.Port.WFEmp wfemp = new Port.WFEmp(wnOfBackTo.HisWork.Rec); string title = string.Format("工作退回:流程:{0}.工作:{1},退回人:{2},需您处理", this.HisNode.FlowName, this.ReturnToNode.Name, WebUser.Name); BP.WF.Dev2Interface.Port_SendMsg(returnToEmp.No, title, Msg, "RE" + this.HisNode.NodeID + this.WorkID, BP.WF.SMSMsgType.ToDo, ReturnToNode.FK_Flow, ReturnToNode.NodeID, this.WorkID, this.FID); } //退回后事件 string text = this.HisNode.HisFlow.DoFlowEventEntity(EventListOfNode.ReturnAfter, this.HisNode, this.HisWork, atPara); if (text != null && text.Length > 1000) { text = "退回事件:无返回信息."; } // 返回退回信息. if (this.ReturnToNode.IsGuestNode) { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); return("工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + gwf.GuestNo + "," + gwf.GuestName + ").\n\r" + text); } else { return("工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + returnToEmp.No + "," + returnToEmp.Name + ").\n\r" + text); } }
public string DoUnSendSubFlow(GenerWorkFlow gwf) { WorkNode wn = this.GetCurrentWorkNode(); WorkNode wnPri = wn.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID); if (num == 0) { return("@您不能执行撤消发送,因为当前工作不是您发送的。"); } // 处理事件。 string msg = wn.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, wn.HisNode, wn.HisWork, null); // 删除工作者。 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node.ToString()); if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } gwf.FK_Node = wnPri.HisNode.NodeID; gwf.NodeName = wnPri.HisNode.Name; gwf.Update(); BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); ShiftWorks fws = new ShiftWorks(); fws.Delete(ShiftWorkAttr.FK_Node, wn.HisNode.NodeID.ToString(), ShiftWorkAttr.WorkID, this.WorkID.ToString()); #region 判断撤消的百分比条件的临界点条件 if (wn.HisNode.PassRate != 0) { decimal all = (decimal)BP.DA.DBAccess.RunSQLReturnValInt("SELECT COUNT(*) NUM FROM dbo.WF_GenerWorkerList WHERE FID=" + this.FID + " AND FK_Node=" + wnPri.HisNode.NodeID); decimal ok = (decimal)BP.DA.DBAccess.RunSQLReturnValInt("SELECT COUNT(*) NUM FROM dbo.WF_GenerWorkerList WHERE FID=" + this.FID + " AND IsPass=1 AND FK_Node=" + wnPri.HisNode.NodeID); decimal rate = ok / all * 100; if (wn.HisNode.PassRate <= rate) { DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.FID); } else { DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=3 WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.FID); } } #endregion // 处理事件。 msg += wn.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, wn.HisNode, wn.HisWork, null); // 记录日志.. wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, wn.HisNode.NodeID, wn.HisNode.Name, "无"); if (wnPri.HisNode.IsStartNode) { if (BP.Web.WebUser.IsWap) { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=" + gwf.FID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + VirPath + "WF/MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } else { if (this.HisFlow.FK_FlowSort != "00") { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=" + gwf.FID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + VirPath + "WF/MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=" + gwf.FID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + VirPath + "WF/Do.aspx?ActionType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } } } else { // 更新是否显示。 // DBAccess.RunSQL("UPDATE WF_ForwardWork SET IsRead=1 WHERE WORKID=" + this.WorkID + " AND FK_Node=" + wnPri.HisNode.NodeID); if (BP.Web.WebUser.IsWap == false) { if (this.HisFlow.FK_FlowSort != "00") { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=" + gwf.FID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。" + msg); } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=" + gwf.FID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。" + msg); } } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=" + gwf.FID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。" + msg); } } }
/// <summary> /// 执行撤销发送 /// </summary> /// <param name="gwf"></param> /// <returns></returns> public string DoUnSendHeiLiu_Main(GenerWorkFlow gwf) { Node currNode = new Node(gwf.FK_Node); Node priFLNode = currNode.HisPriFLNode; GenerWorkerList wl = new GenerWorkerList(); int i = wl.Retrieve(GenerWorkerListAttr.FK_Node, priFLNode.NodeID, GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No); if (i == 0) { return("@不是您把工作发送到当前节点上,所以您不能撤消。"); } WorkNode wn = this.GetCurrentWorkNode(); WorkNode wnPri = new WorkNode(this.WorkID, priFLNode.NodeID); // 记录日志.. wnPri.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, wnPri.HisNode.NodeID, wnPri.HisNode.Name, "无"); GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node.ToString()); if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } gwf.FK_Node = wnPri.HisNode.NodeID; gwf.NodeName = wnPri.HisNode.Name; gwf.Update(); BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); BP.DA.DBAccess.RunSQL("UPDATE WF_GenerFH SET FK_Node=" + gwf.FK_Node + " WHERE FID=" + this.WorkID); ShiftWorks fws = new ShiftWorks(); fws.Delete(ShiftWorkAttr.FK_Node, wn.HisNode.NodeID.ToString(), ShiftWorkAttr.WorkID, this.WorkID.ToString()); #region 恢复工作轨迹,解决工作抢办。 if (wnPri.HisNode.IsStartNode == false) { WorkNode ppPri = wnPri.GetPreviousWorkNode(); wl = new GenerWorkerList(); wl.Retrieve(GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.WorkID); RememberMe rm = new RememberMe(); rm.Retrieve(RememberMeAttr.FK_Node, wnPri.HisNode.NodeID, RememberMeAttr.FK_Emp, ppPri.HisWork.Rec); string[] empStrs = rm.Objs.Split('@'); foreach (string s in empStrs) { if (s == "" || s == null) { continue; } if (s == wl.FK_Emp) { continue; } GenerWorkerList wlN = new GenerWorkerList(); wlN.Copy(wl); wlN.FK_Emp = s; WF.Port.WFEmp myEmp = new Port.WFEmp(s); wlN.FK_EmpText = myEmp.Name; wlN.Insert(); } } #endregion 恢复工作轨迹,解决工作抢办。 // 删除以前的节点数据. wnPri.DeleteToNodesData(priFLNode.HisToNodes); if (wnPri.HisNode.IsStartNode) { if (BP.Web.WebUser.IsWap) { if (wnPri.HisNode.HisFormType != NodeFormType.SDKForm) { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + this.VirPath + this.AppType + "/MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。"); } else { return("@撤销成功."); } } else { if (wnPri.HisNode.HisFormType != NodeFormType.SDKForm) { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + this.VirPath + this.AppType + "/MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。"); } else { return("@撤销成功."); } } } else { // 更新是否显示。 #warning // DBAccess.RunSQL("UPDATE WF_ForwardWork SET IsRead=1 WHERE WORKID=" + this.WorkID + " AND FK_Node=" + wnPri.HisNode.NodeID); if (BP.Web.WebUser.IsWap == false) { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。"); } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。"); } } }
/// <summary> /// 撤消分流点 /// </summary> /// <param name="gwf"></param> /// <returns></returns> private string DoUnSendFeiLiu_bak(GenerWorkFlow gwf) { //首先要检查,当前的处理人是否是分流节点的处理人?如果是,就要把,未走完的所有子线程都删除掉。 GenerWorkerList gwl = new GenerWorkerList(); string sql = "SELECT FK_Node FROM WF_GenerWorkerList WHERE WorkID=" + this.WorkID + " AND FK_Emp='" + BP.Web.WebUser.No + "' AND FK_Node=" + gwf.FK_Node; DataTable dt = DBAccess.RunSQLReturnTable(sql); if (dt.Rows.Count == 0) { return("@您不能执行撤消发送,因为当前工作不是您发送的。"); } //处理事件. Node nd = new Node(gwf.FK_Node); Work wk = nd.HisWork; wk.OID = gwf.WorkID; wk.RetrieveFromDBSources(); string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wk, null); // 记录日志.. WorkNode wn = new WorkNode(wk, nd); wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, gwf.FK_Node, gwf.NodeName, ""); // 删除分合流记录。 if (nd.IsStartNode) { DBAccess.RunSQL("DELETE FROM WF_GenerFH WHERE FID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE FID=" + this.WorkID); } //删除上一个节点的数据。 foreach (Node ndNext in nd.HisToNodes) { int i = DBAccess.RunSQL("DELETE FROM WF_GenerWorkerList WHERE FID=" + this.WorkID + " AND FK_Node=" + ndNext.NodeID); if (i == 0) { continue; } // 删除工作记录。 Works wks = ndNext.HisWorks; if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wks.Delete(GenerWorkerListAttr.FID, this.WorkID); } // 删除已经发起的流程。 DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE FID=" + this.WorkID + " AND FK_Node=" + ndNext.NodeID); } //设置当前节点。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND IsPass=1"); BP.DA.DBAccess.RunSQL("UPDATE WF_GenerFH SET FK_Node=" + gwf.FK_Node + " WHERE FID=" + this.WorkID); // 设置当前节点的状态. Node cNode = new Node(gwf.FK_Node); Work cWork = cNode.HisWork; cWork.OID = this.WorkID; msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wk, null); if (cNode.IsStartNode) { if (BP.Web.WebUser.IsWap) { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=0&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + cWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } else { if (this.HisFlow.FK_FlowSort != "00") { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=0&FK_Node=" + gwf.FK_Node + "' ><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + cWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=0&FK_Node=" + gwf.FK_Node + "' ><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='Do.aspx?ActionType=DeleteFlow&WorkID=" + cWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } } } else { // 更新是否显示。 // DBAccess.RunSQL("UPDATE WF_ForwardWork SET IsRead=1 WHERE WORKID=" + this.WorkID + " AND FK_Node=" + cNode.NodeID); if (BP.Web.WebUser.IsWap == false) { if (this.HisFlow.FK_FlowSort != "00") { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=0&FK_Node=" + gwf.FK_Node + "' ><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。" + msg); } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=0&FK_Node=" + gwf.FK_Node + "' ><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。" + msg); } } else { return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FID=0&FK_Node=" + gwf.FK_Node + "' ><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A>。" + msg); } } }
/// <summary> /// 执行撤消 /// </summary> public string DoUnSend() { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); if (gwf.FID != 0) { /* * 说明该流程是一个子线程,如果子线程的撤销,就需要删除该子线程。 */ BP.WF.Dev2Interface.Flow_DeleteSubThread(this.FlowNo, this.WorkID, "撤销方式删除"); return("@子线程已经被删除."); } // 如果停留的节点是分合流。 Node nd = new Node(gwf.FK_Node); if (nd.HisCancelRole == CancelRole.None) { /*该节点不允许退回.*/ throw new Exception("当前节点,不允许撤销。"); } switch (nd.HisNodeWorkType) { case NodeWorkType.WorkFHL: throw new Exception("分合流点不允许撤消。"); case NodeWorkType.WorkFL: /*判断权限,当前的发送人是谁,如果是自己,就可以撤销.*/ if (gwf.Sender != WebUser.No) { throw new Exception("@分流点不是您发送的,您不能执行撤销。"); } return(this.DoUnSendFeiLiu(gwf)); case NodeWorkType.StartWorkFL: return(this.DoUnSendFeiLiu(gwf)); case NodeWorkType.WorkHL: if (this.IsMainFlow) { /* 首先找到与他最近的一个分流点,并且判断当前的操作员是不是分流点上的工作人员。*/ return(this.DoUnSendHeiLiu_Main(gwf)); } else { return(this.DoUnSendSubFlow(gwf)); //是子流程时. } break; case NodeWorkType.SubThreadWork: break; default: break; } if (nd.IsStartNode) { throw new Exception("当前节点是开始节点,所以您不能撤销。"); } //定义当前的节点. WorkNode wn = this.GetCurrentWorkNode(); #region 求的撤销的节点. int cancelToNodeID = 0; if (nd.HisCancelRole == CancelRole.SpecNodes) { /*指定的节点可以撤销,首先判断当前人员是否有权限.*/ NodeCancels ncs = new NodeCancels(); ncs.Retrieve(NodeCancelAttr.FK_Node, wn.HisNode.NodeID); if (ncs.Count == 0) { throw new Exception("@流程设计错误, 您设置了当前节点(" + wn.HisNode.Name + ")可以让指定的节点人员撤销,但是您没有设置指定的节点."); } /* 查询出来. */ string sql = "SELECT FK_Node FROM WF_GenerWorkerList WHERE FK_Emp='" + WebUser.No + "' AND IsPass=1 AND IsEnable=1 AND WorkID=" + wn.HisWork.OID + " ORDER BY RDT DESC "; DataTable dt = DBAccess.RunSQLReturnTable(sql); if (dt.Rows.Count == 0) { throw new Exception("@撤销流程错误,您没有权限执行撤销发送."); } // 找到将要撤销到的NodeID. foreach (DataRow dr in dt.Rows) { foreach (NodeCancel nc in ncs) { if (nc.CancelTo == int.Parse(dr[0].ToString())) { cancelToNodeID = nc.CancelTo; break; } } if (cancelToNodeID != 0) { break; } } if (cancelToNodeID == 0) { throw new Exception("@撤销流程错误,您没有权限执行撤销发送,没有找到可以撤销的节点."); } } if (nd.HisCancelRole == CancelRole.OnlyNextStep) { /*如果仅仅允许撤销上一步骤.*/ WorkNode wnPri = wn.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID); if (num == 0) { throw new Exception("@您不能执行撤消发送,因为当前工作不是您发送的或下一步工作已处理。"); } cancelToNodeID = wnPri.HisNode.NodeID; } if (cancelToNodeID == 0) { throw new Exception("@没有求出要撤销到的节点."); } #endregion 求的撤销的节点. /********** 开始执行撤销. **********************/ Node cancelToNode = new Node(cancelToNodeID); WorkNode wnOfCancelTo = new WorkNode(this.WorkID, cancelToNodeID); // 调用撤消发送前事件。 string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wn.HisWork, null); #region 除当前节点数据。 // 删除产生的工作列表。 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node); // 删除工作信息,如果是按照ccflow格式存储的。 if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } // 删除附件信息。 DBAccess.RunSQL("DELETE FROM Sys_FrmAttachmentDB WHERE FK_MapData='ND" + gwf.FK_Node + "' AND RefPKVal='" + this.WorkID + "'"); #endregion 除当前节点数据。 // 更新. gwf.FK_Node = cancelToNode.NodeID; gwf.NodeName = cancelToNode.Name; if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { gwf.TaskSta = TaskSta.Takeback; } else { gwf.TaskSta = TaskSta.None; } gwf.TodoEmps = WebUser.No + "," + WebUser.Name; gwf.Update(); if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { //设置全部的人员不可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=-1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); //设置当前人员可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND FK_Emp='" + WebUser.No + "'"); } else { BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); } //更新当前节点,到rpt里面。 BP.DA.DBAccess.RunSQL("UPDATE " + this.HisFlow.PTable + " SET FlowEndNode=" + gwf.FK_Node + " WHERE OID=" + this.WorkID); // 记录日志.. wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, cancelToNode.NodeID, cancelToNode.Name, "无"); // 删除数据. if (wn.HisNode.IsStartNode) { DBAccess.RunSQL("DELETE FROM WF_GenerFH WHERE FID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID); } if (wn.HisNode.IsEval) { /*如果是质量考核节点,并且撤销了。*/ DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.WorkID); } #region 恢复工作轨迹,解决工作抢办。 if (cancelToNode.IsStartNode == false && cancelToNode.IsEnableTaskPool == false) { WorkNode ppPri = wnOfCancelTo.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); wl.Retrieve(GenerWorkerListAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.WorkID); RememberMe rm = new RememberMe(); rm.Retrieve(RememberMeAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, RememberMeAttr.FK_Emp, ppPri.HisWork.Rec); string[] empStrs = rm.Objs.Split('@'); foreach (string s in empStrs) { if (s == "" || s == null) { continue; } if (s == wl.FK_Emp) { continue; } GenerWorkerList wlN = new GenerWorkerList(); wlN.Copy(wl); wlN.FK_Emp = s; WF.Port.WFEmp myEmp = new Port.WFEmp(s); wlN.FK_EmpText = myEmp.Name; wlN.Insert(); } } #endregion 恢复工作轨迹,解决工作抢办。 #region 如果是开始节点, 检查此流程是否有子线程,如果有则删除它们。 if (nd.IsStartNode) { /*要检查一个是否有 子流程,如果有,则删除它们。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.PWorkID, this.WorkID); if (gwfs.Count > 0) { foreach (GenerWorkFlow item in gwfs) { /*删除每个子线程.*/ BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(item.FK_Flow, item.WorkID, true); } } } #endregion //调用撤消发送后事件。 msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wn.HisWork, null); if (wnOfCancelTo.HisNode.IsStartNode) { if (BP.Web.WebUser.IsWap) { if (wnOfCancelTo.HisNode.HisFormType != NodeFormType.SDKForm) { return("@撤消发送执行成功,您可以点这里<a href='" + VirPath + "WF/Wap/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + VirPath + "WF/Wap/MyFlowInfo.aspx?DoType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); } else { return("@撤销成功." + msg); } } else { switch (wnOfCancelTo.HisNode.HisFormType) { case NodeFormType.FixForm: case NodeFormType.FreeForm: return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> , <a href='" + this.VirPath + this.AppType + "/Do.aspx?ActionType=DeleteFlow&WorkID=" + wn.HisWork.OID + "&FK_Flow=" + this.FlowNo + "' /><img src='" + VirPath + "WF/Img/Btn/Delete.gif' border=0/>此流程已经完成(删除它)</a>。" + msg); break; default: return("撤销成功" + msg); break; } } } else { // 更新是否显示。 // DBAccess.RunSQL("UPDATE WF_ForwardWork SET IsRead=1 WHERE WORKID=" + this.WorkID + " AND FK_Node=" + cancelToNode.NodeID); switch (wnOfCancelTo.HisNode.HisFormType) { case NodeFormType.FixForm: case NodeFormType.FreeForm: return("@撤消执行成功,您可以点这里<a href='" + this.VirPath + this.AppType + "/MyFlow.aspx?FK_Flow=" + this.FlowNo + "&WorkID=" + this.WorkID + "&FK_Node=" + gwf.FK_Node + "'><img src='" + VirPath + "WF/Img/Btn/Do.gif' border=0/>执行工作</A> . " + msg); break; default: return("撤销成功:" + msg); break; } } return("工作已经被您撤销到:" + cancelToNode.Name); }
/// <summary> /// 执行撤消 /// </summary> private string DoUnSendIt() { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); if (gwf.WFState == WFState.Complete) { return("err@该流程已经完成,您不能撤销。"); } // 如果停留的节点是分合流。 Node nd = new Node(gwf.FK_Node); /*该节点不允许退回.*/ if (nd.HisCancelRole == CancelRole.None) { throw new Exception("当前节点,不允许撤销。"); } if (nd.IsStartNode && nd.HisNodeWorkType != NodeWorkType.StartWorkFL) { throw new Exception("当前节点是开始节点,所以您不能撤销。"); } //如果撤销到的节点和当前流程运行到的节点相同,则是分流、或者分河流 if (this.UnSendToNode == nd.NodeID) { //如果当前节点是分流、分合流节点则可以撤销 if (nd.HisNodeWorkType == NodeWorkType.StartWorkFL || nd.HisNodeWorkType == NodeWorkType.WorkFL || nd.HisNodeWorkType == NodeWorkType.WorkFHL) { //获取当前节点的子线程 string truckTable = "ND" + int.Parse(nd.FK_Flow) + "Track"; string threadSQL = "SELECT FK_Node,WorkID FROM WF_GenerWorkFlow WHERE FID=" + this.WorkID + " AND FK_Node" + " IN(SELECT DISTINCT(NDTo) FROM " + truckTable + " WHERE ActionType=" + (int)ActionType.ForwardFL + " AND WorkID=" + this.WorkID + " AND NDFrom='" + nd.NodeID + "'" + " ) "; DataTable dt = DBAccess.RunSQLReturnTable(threadSQL); if (dt == null || dt.Rows.Count == 0) { throw new Exception("err@流程运行错误:当不存在子线程时,改过程应该处于待办状态"); } foreach (DataRow dr in dt.Rows) { Node threadnd = new Node(dr["FK_Node"].ToString()); // 调用撤消发送前事件。 nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, nd.HisWork, null); BP.WF.Dev2Interface.Node_FHL_KillSubFlow(threadnd.FK_Flow, this.WorkID, long.Parse(dr["WorkID"].ToString())); //杀掉子线程. // 调用撤消发送前事件。 nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, nd.HisWork, null); } return("撤销成功"); } } //如果启用了对方已读,就不能撤销. if (nd.CancelDisWhenRead == true) { //撤销到的节点是干流程节点/子线程撤销到子线程 int i = DBAccess.RunSQLReturnValInt("SELECT SUM(IsRead) AS Num FROM WF_GenerWorkerList WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node, 0); if (i >= 1) { return("err@当前待办已经有[" + i + "]个工作人员打开了该工作,您不能执行撤销."); } else { //干流节点撤销到子线程 i = DBAccess.RunSQLReturnValInt("SELECT SUM(IsRead) AS Num FROM WF_GenerWorkerList WHERE WorkID=" + this.FID + " AND FK_Node=" + gwf.FK_Node, 0); if (i >= 1) { return("err@当前待办已经有[" + i + "]个工作人员打开了该工作,您不能执行撤销."); } } } #region 如果是越轨流程状态 @fanleiwei. string sql = "SELECT COUNT(*) AS Num FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND IsPass=80"; if (DBAccess.RunSQLReturnValInt(sql, 0) != 0) { //求出来越轨子流程workid并把它删除掉. GenerWorkFlow gwfSubFlow = new GenerWorkFlow(); int i = gwfSubFlow.Retrieve(GenerWorkFlowAttr.PWorkID, this.WorkID); if (i == 1) { BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(gwfSubFlow.FK_Flow, gwfSubFlow.WorkID, true); } //执行回复当前节点待办.. sql = "UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE IsPass=80 AND FK_Node=" + gwf.FK_Node + " AND WorkID=" + this.WorkID; DBAccess.RunSQL(sql); return("撤销延续流程执行成功,撤销到[" + gwf.NodeName + "],撤销给[" + gwf.TodoEmps + "]"); } #endregion 如果是越轨流程状态 . if (BP.WF.Dev2Interface.Flow_IsCanDoCurrentWork(this.WorkID, WebUser.No) == true) { return("info@您有处理当前工作的权限,可能您已经执行了撤销,请使用退回或者发送功能."); } #region 判断是否是会签状态,是否是会签人做的撤销. 主持人是不能撤销的. if (gwf.HuiQianTaskSta != HuiQianTaskSta.None) { string IsEnableUnSendWhenHuiQian = SystemConfig.AppSettings["IsEnableUnSendWhenHuiQian"]; if (DataType.IsNullOrEmpty(IsEnableUnSendWhenHuiQian) == false && IsEnableUnSendWhenHuiQian.Equals("0")) { return("info@当前节点是会签状态,您不能执行撤销."); } GenerWorkerList gwl = new GenerWorkerList(); int numOfmyGwl = gwl.Retrieve(GenerWorkerListAttr.FK_Emp, WebUser.No, GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node); //如果没有找到当前会签人. if (numOfmyGwl == 0) { return("err@当前节点[" + gwf.NodeName + "]是会签状态,[" + gwf.TodoEmps + "]在执行会签,您不能执行撤销."); } if (gwl.IsHuiQian == true) { } //如果是会签人,就让其显示待办. gwl.IsPassInt = 0; gwl.IsEnable = true; gwl.Update(); // 在待办人员列表里加入他. 要判断当前人员是否是主持人,如果是主持人的话,主持人是否在发送的时候, // 就选择方向与接受人. if (gwf.HuiQianZhuChiRen == WebUser.No) { gwf.TodoEmps = WebUser.No + "," + BP.Web.WebUser.Name + ";" + gwf.TodoEmps; } else { gwf.TodoEmps = gwf.TodoEmps + BP.Web.WebUser.Name + ";"; } gwf.Update(); return("会签人撤销成功."); } #endregion 判断是否是会签状态,是否是会签人做的撤销. if (gwf.FID != 0) { //执行子线程的撤销. return(DoThreadUnSend()); } //定义当前的节点. WorkNode wn = this.GetCurrentWorkNode(); #region 求的撤销的节点. int cancelToNodeID = 0; if (nd.HisCancelRole == CancelRole.SpecNodes) { /*指定的节点可以撤销,首先判断当前人员是否有权限.*/ NodeCancels ncs = new NodeCancels(); ncs.Retrieve(NodeCancelAttr.FK_Node, wn.HisNode.NodeID); if (ncs.Count == 0) { throw new Exception("@流程设计错误, 您设置了当前节点(" + wn.HisNode.Name + ")可以让指定的节点人员撤销,但是您没有设置指定的节点."); } /* 查询出来. */ sql = "SELECT FK_Node FROM WF_GenerWorkerList WHERE FK_Emp='" + WebUser.No + "' AND IsPass=1 AND IsEnable=1 AND WorkID=" + wn.HisWork.OID + " ORDER BY RDT DESC "; DataTable dt = DBAccess.RunSQLReturnTable(sql); if (dt.Rows.Count == 0) { throw new Exception("err@撤销流程错误,您没有权限执行撤销发送."); } // 找到将要撤销到的NodeID. foreach (DataRow dr in dt.Rows) { foreach (NodeCancel nc in ncs) { if (nc.CancelTo == int.Parse(dr[0].ToString())) { cancelToNodeID = nc.CancelTo; break; } } if (cancelToNodeID != 0) { break; } } if (cancelToNodeID == 0) { throw new Exception("@撤销流程错误,您没有权限执行撤销发送,当前节点不可以执行撤销."); } } if (nd.HisCancelRole == CancelRole.OnlyNextStep) { /*如果仅仅允许撤销上一步骤.*/ WorkNode wnPri = wn.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); if (num == 0) { throw new Exception("err@您不能执行撤消发送,因为当前工作不是您发送的或下一步工作已处理。"); } cancelToNodeID = wnPri.HisNode.NodeID; } if (cancelToNodeID == 0) { throw new Exception("err@没有求出要撤销到的节点."); } #endregion 求的撤销的节点. if (this.UnSendToNode != 0 && gwf.FK_Node != this.UnSendToNode) { Node toNode = new Node(this.UnSendToNode); /* 要撤销的节点是分流节点,并且当前节点不在分流节点而是在合流节点的情况, for:华夏银行. * 1, 分流节点发送给n个人. * 2, 其中一个人发送到合流节点,另外一个人退回给分流节点。 * 3,现在分流节点的人接收到一个待办,并且需要撤销整个分流节点的发送. * 4, UnSendToNode 这个时间没有值,并且当前干流节点的停留的节点与要撤销到的节点不一致。 */ if (toNode.HisNodeWorkType == NodeWorkType.WorkFL && nd.HisNodeWorkType == NodeWorkType.WorkHL) { return(DoUnSendInFeiLiuHeiliu(gwf)); } } #region 判断当前节点的模式. switch (nd.HisNodeWorkType) { case NodeWorkType.WorkFHL: return(this.DoUnSendFeiLiu(gwf)); case NodeWorkType.WorkFL: case NodeWorkType.StartWorkFL: break; case NodeWorkType.WorkHL: if (this.IsMainFlow) { /* 首先找到与他最近的一个分流点,并且判断当前的操作员是不是分流点上的工作人员。*/ return(this.DoUnSendHeiLiu_Main(gwf)); } else { return(this.DoUnSendSubFlow(gwf)); //是子流程时. } break; case NodeWorkType.SubThreadWork: break; default: break; } #endregion 判断当前节点的模式. /********** 开始执行撤销. **********************/ Node cancelToNode = new Node(cancelToNodeID); #region 如果撤销到的节点是普通的节点,并且当前的节点是分流(分流)节点,并且分流(分流)节点已经发送下去了,就不允许撤销了. if (cancelToNode.HisRunModel == RunModel.Ordinary && nd.HisRunModel == RunModel.HL && nd.HisRunModel == RunModel.FHL && nd.HisRunModel == RunModel.FL) { /* 检查一下是否还有没有完成的子线程,如果有就抛出不允许撤销的异常。 */ sql = "SELECT COUNT(*) as NUM FROM WF_GenerWorkerList WHERE FID=" + this.WorkID + " AND IsPass=0"; if (BP.DA.DBAccess.RunSQLReturnValInt(sql) != 0) { return("err@不允许撤销,因为有未完成的子线程."); } // return this.DoUnSendHeiLiu_Main(gwf); } #endregion 如果撤销到的节点是普通的节点,并且当前的节点是分流节点,并且分流节点已经发送下去了. #region 如果当前是协作组长模式,就要考虑当前是否是会签节点,如果是会签节点,就要处理。 if (cancelToNode.TodolistModel == TodolistModel.TeamupGroupLeader || cancelToNode.TodolistModel == TodolistModel.Teamup) { sql = "SELECT ActionType FROM ND" + int.Parse(this.FlowNo) + "Track WHERE NDFrom=" + cancelToNodeID + " AND EmpFrom='" + WebUser.No + "' AND WorkID=" + this.WorkID; DataTable dt = DBAccess.RunSQLReturnTable(sql); foreach (DataRow dr in dt.Rows) { int ac = int.Parse(dr[0].ToString()); ActionType at = (ActionType)ac; if (at == ActionType.TeampUp) { /*如果是写作人员,就不允许他撤销 */ throw new Exception("@您是节点[" + cancelToNode.Name + "]的会签人,您不能执行撤销。"); } } } #endregion 如果当前是协作组长模式 WorkNode wnOfCancelTo = new WorkNode(this.WorkID, cancelToNodeID); // 调用撤消发送前事件。 string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wn.HisWork, null); #region 除当前节点数据。 // 删除产生的工作列表。 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node); // 删除工作信息,如果是按照ccflow格式存储的。 if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } // 删除附件信息。 DBAccess.RunSQL("DELETE FROM Sys_FrmAttachmentDB WHERE FK_MapData='ND" + gwf.FK_Node + "' AND RefPKVal='" + this.WorkID + "'"); #endregion 除当前节点数据。 // 更新. gwf.FK_Node = cancelToNode.NodeID; gwf.NodeName = cancelToNode.Name; //恢复上一步发送人 DataTable dtPrevTrack = Dev2Interface.Flow_GetPreviousNodeTrack(this.WorkID, cancelToNode.NodeID); if (dtPrevTrack != null && dtPrevTrack.Rows.Count > 0) { gwf.Sender = dtPrevTrack.Rows[0]["EmpFrom"].ToString(); } if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { gwf.TaskSta = TaskSta.Takeback; } else { gwf.TaskSta = TaskSta.None; } gwf.TodoEmps = WebUser.No + "," + WebUser.Name + ";"; gwf.Update(); if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { //设置全部的人员不可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=-1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); //设置当前人员可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND FK_Emp='" + WebUser.No + "'"); } else { BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND FK_Emp='" + WebUser.No + "'"); } //更新当前节点,到rpt里面。 BP.DA.DBAccess.RunSQL("UPDATE " + this.HisFlow.PTable + " SET FlowEndNode=" + gwf.FK_Node + " WHERE OID=" + this.WorkID); // 记录日志.. wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, cancelToNode.NodeID, cancelToNode.Name, "无"); //删除审核组件设置“协作模式下操作员显示顺序”为“按照接受人员列表先后顺序(官职大小)”,而生成的待审核轨迹信息 FrmWorkCheck fwc = new FrmWorkCheck(nd.NodeID); if (fwc.FWCSta == FrmWorkCheckSta.Enable && fwc.FWCOrderModel == FWCOrderModel.SqlAccepter) { BP.DA.DBAccess.RunSQL("DELETE FROM ND" + int.Parse(nd.FK_Flow) + "Track WHERE WorkID = " + this.WorkID + " AND ActionType = " + (int)ActionType.WorkCheck + " AND NDFrom = " + nd.NodeID + " AND NDTo = " + nd.NodeID + " AND (Msg = '' OR Msg IS NULL)"); } // 删除数据. if (wn.HisNode.IsStartNode) { DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID); } else { DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID); } //首先删除当前节点的,审核意见. string delTrackSQl = "DELETE FROM ND" + int.Parse(nd.FK_Flow) + "Track WHERE WorkID=" + this.WorkID + " AND NDFrom=" + nd.NodeID + " AND ActionType =22 "; DBAccess.RunSQL(delTrackSQl); if (wn.HisNode.IsEval) { /*如果是质量考核节点,并且撤销了。*/ DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.WorkID); } #region 恢复工作轨迹,解决工作抢办。 if (cancelToNode.IsStartNode == false && cancelToNode.IsEnableTaskPool == false) { WorkNode ppPri = wnOfCancelTo.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); wl.Retrieve(GenerWorkerListAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.WorkID); RememberMe rm = new RememberMe(); rm.Retrieve(RememberMeAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, RememberMeAttr.FK_Emp, ppPri.HisWork.Rec); string[] empStrs = rm.Objs.Split('@'); foreach (string s in empStrs) { if (s == "" || s == null) { continue; } if (s == wl.FK_Emp) { continue; } GenerWorkerList wlN = new GenerWorkerList(); wlN.Copy(wl); wlN.FK_Emp = s; WF.Port.WFEmp myEmp = new Port.WFEmp(s); wlN.FK_EmpText = myEmp.Name; wlN.Insert(); } } #endregion 恢复工作轨迹,解决工作抢办。 #region 如果是开始节点, 检查此流程是否有子流程,如果有则删除它们。 if (nd.IsStartNode) { /*要检查一个是否有 子流程,如果有,则删除它们。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.PWorkID, this.WorkID); if (gwfs.Count > 0) { foreach (GenerWorkFlow item in gwfs) { /*删除每个子线程.*/ BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(item.FK_Flow, item.WorkID, true); } } } #endregion //调用撤消发送后事件。 msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wn.HisWork, null); if (wnOfCancelTo.HisNode.IsStartNode) { switch (wnOfCancelTo.HisNode.HisFormType) { case NodeFormType.FoolForm: case NodeFormType.FreeForm: return("@撤消执行成功." + msg); break; default: return("@撤销成功." + msg); break; } } else { // 更新是否显示。 // DBAccess.RunSQL("UPDATE WF_ForwardWork SET IsRead=1 WHERE WORKID=" + this.WorkID + " AND FK_Node=" + cancelToNode.NodeID); switch (wnOfCancelTo.HisNode.HisFormType) { case NodeFormType.FoolForm: case NodeFormType.FreeForm: return("@撤消执行成功. " + msg); break; default: return("撤销成功:" + msg); break; } } return("工作已经被您撤销到:" + cancelToNode.Name); }
/// <summary> /// 产生一个WorkNode /// </summary> /// <param name="fk_flow">流程编号</param> /// <param name="fk_node">节点ID</param> /// <param name="workID">工作ID</param> /// <param name="fid">FID</param> /// <param name="userNo">用户编号</param> /// <returns>返回dataset</returns> public static DataSet GenerWorkNode(string fk_flow, int fk_node, Int64 workID, Int64 fid, string userNo, string fromWorkOpt = "0") { //节点. if (fk_node == 0) { fk_node = int.Parse(fk_flow + "01"); } if (workID == 0) { workID = BP.WF.Dev2Interface.Node_CreateBlankWork(fk_flow, null, null, userNo, null); } Node nd = new Node(fk_node); try { nd.WorkID = workID; //为获取表单ID提供参数. MapData md = new MapData(); md.No = nd.NodeFrmID; if (md.RetrieveFromDBSources() == 0) { throw new Exception("装载错误,该表单ID=" + md.No + "丢失,请修复一次流程重新加载一次."); } Work wk = nd.HisWork; wk.OID = workID; wk.RetrieveFromDBSources(); wk.ResetDefaultVal(); // 第1.2: 调用,处理用户定义的业务逻辑. string sendWhen = nd.HisFlow.DoFlowEventEntity(EventListOfNode.FrmLoadBefore, nd, wk, null); //获得表单模版. DataSet myds = BP.Sys.CCFormAPI.GenerHisDataSet(md.No, nd.Name); //移除MapAttr myds.Tables.Remove("Sys_MapAttr"); //移除. //获取表单的mapAttr //求出集合. MapAttrs mattrs = new MapAttrs(md.No); if (fk_node != null) { /*处理表单权限控制方案*/ FrmNode frmNode = new FrmNode(); int count = frmNode.Retrieve(FrmNodeAttr.FK_Frm, md.No, FrmNodeAttr.FK_Node, fk_node); if (count != 0 && frmNode.FrmSln != 0) { FrmFields fls = new FrmFields(md.No, frmNode.FK_Node); foreach (FrmField item in fls) { foreach (MapAttr attr in mattrs) { if (attr.KeyOfEn != item.KeyOfEn) { continue; } if (item.IsSigan) { item.UIIsEnable = false; } attr.UIIsEnable = item.UIIsEnable; attr.UIVisible = item.UIVisible; attr.IsSigan = item.IsSigan; attr.DefValReal = item.DefVal; } } } } DataTable Sys_MapAttr = mattrs.ToDataTableField("Sys_MapAttr"); myds.Tables.Add(Sys_MapAttr); //把流程信息表发送过去. GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = workID; gwf.RetrieveFromDBSources(); //加入WF_Node. DataTable WF_Node = nd.ToDataTableField("WF_Node"); myds.Tables.Add(WF_Node); #region 加入组件的状态信息, 在解析表单的时候使用. BP.WF.Template.FrmNodeComponent fnc = new FrmNodeComponent(nd.NodeID); nd.WorkID = workID; //为获取表单ID提供参数. if (nd.NodeFrmID != "ND" + nd.NodeID && nd.HisFormType != NodeFormType.RefOneFrmTree) { /*说明这是引用到了其他节点的表单,就需要把一些位置元素修改掉.*/ int refNodeID = int.Parse(nd.NodeFrmID.Replace("ND", "")); BP.WF.Template.FrmNodeComponent refFnc = new FrmNodeComponent(refNodeID); fnc.SetValByKey(FrmWorkCheckAttr.FWC_H, refFnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_H)); fnc.SetValByKey(FrmWorkCheckAttr.FWC_W, refFnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_W)); fnc.SetValByKey(FrmWorkCheckAttr.FWC_X, refFnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_X)); fnc.SetValByKey(FrmWorkCheckAttr.FWC_Y, refFnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_Y)); if (fnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_H) <= 10) { fnc.SetValByKey(FrmWorkCheckAttr.FWC_H, 500); } if (fnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_W) <= 10) { fnc.SetValByKey(FrmWorkCheckAttr.FWC_W, 600); } if (fnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_X) <= 10) { fnc.SetValByKey(FrmWorkCheckAttr.FWC_X, 200); } if (fnc.GetValFloatByKey(FrmWorkCheckAttr.FWC_Y) <= 10) { fnc.SetValByKey(FrmWorkCheckAttr.FWC_Y, 200); } fnc.SetValByKey(FrmSubFlowAttr.SF_H, refFnc.GetValFloatByKey(FrmSubFlowAttr.SF_H)); fnc.SetValByKey(FrmSubFlowAttr.SF_W, refFnc.GetValFloatByKey(FrmSubFlowAttr.SF_W)); fnc.SetValByKey(FrmSubFlowAttr.SF_X, refFnc.GetValFloatByKey(FrmSubFlowAttr.SF_X)); fnc.SetValByKey(FrmSubFlowAttr.SF_Y, refFnc.GetValFloatByKey(FrmSubFlowAttr.SF_Y)); fnc.SetValByKey(FrmThreadAttr.FrmThread_H, refFnc.GetValFloatByKey(FrmThreadAttr.FrmThread_H)); fnc.SetValByKey(FrmThreadAttr.FrmThread_W, refFnc.GetValFloatByKey(FrmThreadAttr.FrmThread_W)); fnc.SetValByKey(FrmThreadAttr.FrmThread_X, refFnc.GetValFloatByKey(FrmThreadAttr.FrmThread_X)); fnc.SetValByKey(FrmThreadAttr.FrmThread_Y, refFnc.GetValFloatByKey(FrmThreadAttr.FrmThread_Y)); fnc.SetValByKey(FrmTrackAttr.FrmTrack_H, refFnc.GetValFloatByKey(FrmTrackAttr.FrmTrack_H)); fnc.SetValByKey(FrmTrackAttr.FrmTrack_W, refFnc.GetValFloatByKey(FrmTrackAttr.FrmTrack_W)); fnc.SetValByKey(FrmTrackAttr.FrmTrack_X, refFnc.GetValFloatByKey(FrmTrackAttr.FrmTrack_X)); fnc.SetValByKey(FrmTrackAttr.FrmTrack_Y, refFnc.GetValFloatByKey(FrmTrackAttr.FrmTrack_Y)); fnc.SetValByKey(FTCAttr.FTC_H, refFnc.GetValFloatByKey(FTCAttr.FTC_H)); fnc.SetValByKey(FTCAttr.FTC_W, refFnc.GetValFloatByKey(FTCAttr.FTC_W)); fnc.SetValByKey(FTCAttr.FTC_X, refFnc.GetValFloatByKey(FTCAttr.FTC_X)); fnc.SetValByKey(FTCAttr.FTC_Y, refFnc.GetValFloatByKey(FTCAttr.FTC_Y)); #region 没有审核组件分组就增加上审核组件分组. @杜需要翻译&测试. if (md.HisFrmType == FrmType.FoolForm) { //判断是否是傻瓜表单,如果是,就要判断该傻瓜表单是否有审核组件groupfield ,没有的话就增加上. DataTable gf = myds.Tables["Sys_GroupField"]; bool isHave = false; foreach (DataRow dr in gf.Rows) { string cType = dr["CtrlType"] as string; if (cType == null) { continue; } if (cType.Equals("FWC") == true) { isHave = true; } } if (isHave == false) { DataRow dr = gf.NewRow(); nd.WorkID = workID; //为获取表单ID提供参数. dr[GroupFieldAttr.OID] = 100; dr[GroupFieldAttr.FrmID] = nd.NodeFrmID; dr[GroupFieldAttr.CtrlType] = "FWC"; dr[GroupFieldAttr.CtrlID] = "FWCND" + nd.NodeID; dr[GroupFieldAttr.Idx] = 100; dr[GroupFieldAttr.Lab] = "审核信息"; gf.Rows.Add(dr); myds.Tables.Remove("Sys_GroupField"); myds.Tables.Add(gf); //执行更新,就自动生成那个丢失的字段分组. refFnc.Update(); /* * //丢失了就插入新的. * BP.Sys.GroupField gfEn = new GroupField(); * gfEn.FrmID = nd.NodeFrmID; * gfEn.CtrlType = "FWC"; * gfEn.CtrlID = "FWCND" + nd.NodeID; * gfEn.Idx = 100; * gfEn.Lab = "审核信息"; * gfEn.Insert(); */ } } #endregion 没有审核组件分组就增加上审核组件分组. } #region 没有审核组件分组就增加上审核组件分组. @杜需要翻译&测试. if (nd.NodeFrmID == "ND" + nd.NodeID && nd.HisFormType != NodeFormType.RefOneFrmTree) { // Work wk1 = nd.HisWork; if (nd.FormType == NodeFormType.FoolForm) { //判断是否是傻瓜表单,如果是,就要判断该傻瓜表单是否有审核组件groupfield ,没有的话就增加上. DataTable gf = myds.Tables["Sys_GroupField"]; bool isHave = false; foreach (DataRow dr in gf.Rows) { string cType = dr["CtrlType"] as string; if (cType == null) { continue; } if (cType.Equals("FWC") == true) { isHave = true; } } if (isHave == false) { DataRow dr = gf.NewRow(); nd.WorkID = workID; //为获取表单ID提供参数. dr[GroupFieldAttr.OID] = 100; dr[GroupFieldAttr.FrmID] = nd.NodeFrmID; dr[GroupFieldAttr.CtrlType] = "FWC"; dr[GroupFieldAttr.CtrlID] = "FWCND" + nd.NodeID; dr[GroupFieldAttr.Idx] = 100; dr[GroupFieldAttr.Lab] = "审核信息"; gf.Rows.Add(dr); myds.Tables.Remove("Sys_GroupField"); myds.Tables.Add(gf); //更新,为了让其自动增加审核分组. BP.WF.Template.FrmNodeComponent refFnc = new FrmNodeComponent(nd.NodeID); refFnc.Update(); } } } #endregion 没有审核组件分组就增加上审核组件分组. myds.Tables.Add(fnc.ToDataTableField("WF_FrmNodeComponent")); #endregion 加入组件的状态信息, 在解析表单的时候使用. #region 增加 groupfields if (nd.FormType == NodeFormType.FoolTruck && nd.IsStartNode == false && DataType.IsNullOrEmpty(wk.HisPassedFrmIDs) == false) { #region 处理字段分组排序. //查询所有的分组, 如果是查看表单的方式,就不应该把当前的表单显示出来. string myFrmIDs = ""; if (fromWorkOpt.Equals("1") == true) { if (gwf.WFState == WFState.Complete) { myFrmIDs = wk.HisPassedFrmIDs + ",'ND" + fk_node + "'"; } else { myFrmIDs = wk.HisPassedFrmIDs; //流程未完成并且是查看表单的情况. } } else { myFrmIDs = wk.HisPassedFrmIDs + ",'ND" + fk_node + "'"; } GroupFields gfs = new GroupFields(); gfs.RetrieveIn(GroupFieldAttr.FrmID, "(" + myFrmIDs + ")"); //按照时间的顺序查找出来 ids . string sqlOrder = "SELECT OID FROM Sys_GroupField WHERE FrmID IN (" + myFrmIDs + ")"; if (BP.Sys.SystemConfig.AppCenterDBType == DBType.Oracle) { myFrmIDs = myFrmIDs.Replace("'", ""); sqlOrder += " ORDER BY INSTR('" + myFrmIDs + "',FrmID) , Idx"; } if (BP.Sys.SystemConfig.AppCenterDBType == DBType.MSSQL) { myFrmIDs = myFrmIDs.Replace("'", ""); sqlOrder += " ORDER BY CHARINDEX(FrmID, '" + myFrmIDs + "'), Idx"; } if (BP.Sys.SystemConfig.AppCenterDBType == DBType.MySQL) { myFrmIDs = myFrmIDs.Replace("'", ""); sqlOrder += " ORDER BY INSTR('" + myFrmIDs + "', FrmID ), Idx"; } DataTable dtOrder = DBAccess.RunSQLReturnTable(sqlOrder); //创建容器,把排序的分组放入这个容器. GroupFields gfsNew = new GroupFields(); //遍历查询出来的分组. foreach (DataRow dr in dtOrder.Rows) { string pkOID = dr[0].ToString(); var mygf = gfs.GetEntityByKey(pkOID); gfsNew.AddEntity(mygf); //把分组字段加入里面去. } DataTable dtGF = gfsNew.ToDataTableField("Sys_GroupField"); myds.Tables.Remove("Sys_GroupField"); myds.Tables.Add(dtGF); #endregion 处理字段分组排序. #region 处理 mapattrs //求当前表单的字段集合. MapAttrs attrs = new MapAttrs(); QueryObject qo = new QueryObject(attrs); qo.AddWhere(MapAttrAttr.FK_MapData, "ND" + nd.NodeID); qo.addOrderBy(MapAttrAttr.Idx); qo.DoQuery(); //计算累加的字段集合. MapAttrs attrsLeiJia = new MapAttrs(); qo = new QueryObject(attrsLeiJia); qo.AddWhere(MapAttrAttr.FK_MapData, " IN ", "(" + wk.HisPassedFrmIDs + ")"); qo.addOrderBy(MapAttrAttr.Idx); qo.DoQuery(); //把两个集合接起来. foreach (MapAttr item in attrsLeiJia) { item.UIIsEnable = false; //设置为只读的. attrs.AddEntity(item); } //替换掉现有的. myds.Tables.Remove("Sys_MapAttr"); //移除. myds.Tables.Add(attrs.ToDataTableField("Sys_MapAttr")); //增加. #endregion 处理mapattrs #region 把枚举放入里面去. myds.Tables.Remove("Sys_Enum"); myFrmIDs = wk.HisPassedFrmIDs + ",'ND" + fk_node + "'"; SysEnums enums = new SysEnums(); enums.RetrieveInSQL(SysEnumAttr.EnumKey, "SELECT UIBindKey FROM Sys_MapAttr WHERE FK_MapData in(" + myFrmIDs + ")"); // 加入最新的枚举. myds.Tables.Add(enums.ToDataTableField("Sys_Enum")); #endregion 把枚举放入里面去. #region MapExt . myds.Tables.Remove("Sys_MapExt"); // 把扩展放入里面去. myFrmIDs = wk.HisPassedFrmIDs + ",'ND" + fk_node + "'"; BP.Sys.MapExts exts = new MapExts(); qo = new QueryObject(exts); qo.AddWhere(MapExtAttr.FK_MapData, " IN ", "(" + myFrmIDs + ")"); qo.DoQuery(); // 加入最新的MapExt. myds.Tables.Add(exts.ToDataTableField("Sys_MapExt")); #endregion MapExt . } #endregion 增加 groupfields #region 流程设置信息. if (nd.IsStartNode == false) { BP.WF.Dev2Interface.Node_SetWorkRead(fk_node, workID); // @杜. if (gwf.TodoEmps.Contains(BP.Web.WebUser.Name + ";") == false) { gwf.TodoEmps += BP.Web.WebUser.No + "," + BP.Web.WebUser.Name; gwf.Update(); } } //增加转向下拉框数据. if (nd.CondModel == CondModel.SendButtonSileSelect) { if (nd.IsStartNode == true || gwf.TodoEmps.Contains(WebUser.No + ",") == true) { /*如果当前不是主持人,如果不是主持人,就不让他显示下拉框了.*/ /*如果当前节点,是可以显示下拉框的.*/ Nodes nds = nd.HisToNodes; DataTable dtToNDs = new DataTable(); dtToNDs.TableName = "ToNodes"; dtToNDs.Columns.Add("No", typeof(string)); //节点ID. dtToNDs.Columns.Add("Name", typeof(string)); //到达的节点名称. dtToNDs.Columns.Add("IsSelectEmps", typeof(string)); //是否弹出选择人的对话框? dtToNDs.Columns.Add("IsSelected", typeof(string)); //是否选择? #region 增加到达延续子流程节点。 NodeYGFlows ygflows = new NodeYGFlows(fk_node.ToString()); if (ygflows.Count > 1 && SystemConfig.CustomerNo.Equals("CZBank") == true) { dtToNDs.Rows.Clear(); //为浙商银行做的特殊判断,如果配置了延续流程,就不让其走分支节点. } foreach (NodeYGFlow item in ygflows) { DataRow dr = dtToNDs.NewRow(); dr["No"] = item.FK_Flow + "01"; dr["Name"] = "启动:" + item.FlowName; //if (item.HisDeliveryWay == DeliveryWay.BySelected) dr["IsSelectEmps"] = "1"; //else // dr["IsSelectEmps"] = "0"; //是不是,可以选择接受人. //设置默认选择的节点. //if (defalutSelectedNodeID == item.NodeID) // dr["IsSelected"] = "1"; //else // dr["IsSelected"] = "0"; dr["IsSelected"] = "0"; dtToNDs.Rows.Add(dr); } #endregion 增加到达延续子流程节点。 #region 到达其他节点. //上一次选择的节点. int defalutSelectedNodeID = 0; if (nds.Count > 1) { string mysql = ""; // 找出来上次发送选择的节点. if (SystemConfig.AppCenterDBType == DBType.MSSQL) { mysql = "SELECT top 1 NDTo FROM ND" + int.Parse(nd.FK_Flow) + "Track A WHERE A.NDFrom=" + fk_node + " AND ActionType=1 ORDER BY WorkID DESC"; } else if (SystemConfig.AppCenterDBType == DBType.Oracle) { mysql = "SELECT * FROM ( SELECT NDTo FROM ND" + int.Parse(nd.FK_Flow) + "Track A WHERE A.NDFrom=" + fk_node + " AND ActionType=1 ORDER BY WorkID DESC ) WHERE ROWNUM =1"; } else if (SystemConfig.AppCenterDBType == DBType.MySQL) { mysql = "SELECT NDTo FROM ND" + int.Parse(nd.FK_Flow) + "Track A WHERE A.NDFrom=" + fk_node + " AND ActionType=1 ORDER BY WorkID DESC limit 1,1"; } //获得上一次发送到的节点. defalutSelectedNodeID = DBAccess.RunSQLReturnValInt(mysql, 0); } #region 为天业集团做一个特殊的判断. if (SystemConfig.CustomerNo == "TianYe" && nd.Name.Contains("董事长") == true) { /*如果是董事长节点, 如果是下一个节点默认的是备案. */ foreach (Node item in nds) { if (item.Name.Contains("备案") == true && item.Name.Contains("待") == false) { defalutSelectedNodeID = item.NodeID; break; } } } #endregion 为天业集团做一个特殊的判断. foreach (Node item in nds) { DataRow dr = dtToNDs.NewRow(); dr["No"] = item.NodeID; dr["Name"] = item.Name; //if (item.hissel if (item.HisDeliveryWay == DeliveryWay.BySelected) { dr["IsSelectEmps"] = "1"; } else { dr["IsSelectEmps"] = "0"; //是不是,可以选择接受人. } //设置默认选择的节点. if (defalutSelectedNodeID == item.NodeID) { dr["IsSelected"] = "1"; } else { dr["IsSelected"] = "0"; } dtToNDs.Rows.Add(dr); } #endregion 到达其他节点。 //增加一个下拉框, 对方判断是否有这个数据. myds.Tables.Add(dtToNDs); } } // 节点数据. //string sql = "SELECT * FROM WF_Node WHERE NodeID=" + fk_node; //DataTable dt = BP.DA.DBAccess.RunSQLReturnTable(sql); //dt.TableName = "WF_NodeBar"; //myds.Tables.Add(dt); //// 流程数据. //Flow fl = new Flow(fk_flow); //myds.Tables.Add(fl.ToDataTableField("WF_Flow")); #endregion 流程设置信息. #region 把主从表数据放入里面. //.工作数据放里面去, 放进去前执行一次装载前填充事件. //重设默认值. wk.ResetDefaultVal(); //@樊雷伟 把这部分代码搬到jflow上去. CCFlowAPI. 114行出. if (BP.Sys.SystemConfig.IsBSsystem == true) { // 处理传递过来的参数。 foreach (string k in System.Web.HttpContext.Current.Request.QueryString.AllKeys) { if (DataType.IsNullOrEmpty(k) == true) { continue; } wk.SetValByKey(k, System.Web.HttpContext.Current.Request.QueryString[k]); } // 处理传递过来的frm参数。 foreach (string k in System.Web.HttpContext.Current.Request.Form.AllKeys) { if (DataType.IsNullOrEmpty(k) == true) { continue; } wk.SetValByKey(k, System.Web.HttpContext.Current.Request.Form[k]); } //更新到数据库里. wk.DirectUpdate(); } // 执行表单事件.. string msg = md.DoEvent(FrmEventList.FrmLoadBefore, wk); if (DataType.IsNullOrEmpty(msg) == false) { throw new Exception("err@错误:" + msg); } // 执行FEE事件. string msgOfLoad = nd.HisFlow.DoFlowEventEntity(EventListOfNode.FrmLoadBefore, nd, wk, null); if (msgOfLoad != null) { wk.RetrieveFromDBSources(); } //执行装载填充. MapExt me = new MapExt(); if (me.Retrieve(MapExtAttr.ExtType, MapExtXmlList.PageLoadFull, MapExtAttr.FK_MapData, wk.NodeFrmID) == 1) { //执行通用的装载方法. MapAttrs attrs = new MapAttrs(wk.NodeFrmID); MapDtls dtls = new MapDtls(wk.NodeFrmID); wk = BP.WF.Glo.DealPageLoadFull(wk, me, attrs, dtls) as Work; } //如果是累加表单,就把整个rpt数据都放入里面去. if (nd.FormType == NodeFormType.FoolTruck && nd.IsStartNode == false && DataType.IsNullOrEmpty(wk.HisPassedFrmIDs) == false) { GERpt rpt = new GERpt("ND" + int.Parse(nd.FK_Flow) + "Rpt", workID); // nd.HisFlow.HisGERpt; rpt.ResetDefaultVal(); //rpt.Copy(wk); //加入后就出现了错误. myds.Tables.Add(rpt.ToDataTableField("MainTable")); // myds.WriteXml("C:\\XX.xml"); } else { DataTable mainTable = wk.ToDataTableField(md.No); mainTable.TableName = "MainTable"; myds.Tables.Add(mainTable); } string sql = ""; DataTable dt = null; #endregion #region 把外键表加入DataSet DataTable dtMapAttr = myds.Tables["Sys_MapAttr"]; MapExts mes = md.MapExts; foreach (DataRow dr in dtMapAttr.Rows) { string lgType = dr["LGType"].ToString(); string uiBindKey = dr["UIBindKey"].ToString(); if (DataType.IsNullOrEmpty(uiBindKey) == true) { continue; //为空就continue. } if (lgType.Equals("1") == true) { continue; //枚举值就continue; } string uiIsEnable = dr["UIIsEnable"].ToString(); if (uiIsEnable.Equals("0") == true && lgType.Equals("1") == true) { continue; //如果是外键,并且是不可以编辑的状态. } if (uiIsEnable.Equals("1") == true && lgType.Equals("0") == true) { continue; //如果是外部数据源,并且是不可以编辑的状态. } // 检查是否有下拉框自动填充。 string keyOfEn = dr["KeyOfEn"].ToString(); string fk_mapData = dr["FK_MapData"].ToString(); #region 处理下拉框数据范围. for 小杨. me = mes.GetEntityByKey(MapExtAttr.ExtType, MapExtXmlList.AutoFullDLL, MapExtAttr.AttrOfOper, keyOfEn) as MapExt; if (me != null) { string fullSQL = me.Doc.Clone() as string; fullSQL = fullSQL.Replace("~", ","); fullSQL = BP.WF.Glo.DealExp(fullSQL, wk, null); dt = DBAccess.RunSQLReturnTable(fullSQL); //重构新表 DataTable dt_FK_Dll = new DataTable(); dt_FK_Dll.TableName = keyOfEn;//可能存在隐患,如果多个字段,绑定同一个表,就存在这样的问题. dt_FK_Dll.Columns.Add("No", typeof(string)); dt_FK_Dll.Columns.Add("Name", typeof(string)); foreach (DataRow dllRow in dt.Rows) { DataRow drDll = dt_FK_Dll.NewRow(); drDll["No"] = dllRow["No"]; drDll["Name"] = dllRow["Name"]; dt_FK_Dll.Rows.Add(drDll); } myds.Tables.Add(dt_FK_Dll); continue; } #endregion 处理下拉框数据范围. // 判断是否存在. if (myds.Tables.Contains(uiBindKey) == true) { continue; } if (BP.Sys.PubClass.GetDataTableByUIBineKey(uiBindKey) != null) { myds.Tables.Add(BP.Sys.PubClass.GetDataTableByUIBineKey(uiBindKey)); } } #endregion End把外键表加入DataSet #region 处理流程-消息提示. DataTable dtAlert = new DataTable(); dtAlert.TableName = "AlertMsg"; dtAlert.Columns.Add("Title", typeof(string)); dtAlert.Columns.Add("Msg", typeof(string)); dtAlert.Columns.Add("URL", typeof(string)); // string msg = ""; switch (gwf.WFState) { case WFState.AskForReplay: // 返回加签的信息. string mysql = "SELECT * FROM ND" + int.Parse(fk_flow) + "Track WHERE WorkID=" + workID + " AND " + TrackAttr.ActionType + "=" + (int)ActionType.ForwardAskfor; DataTable mydt = BP.DA.DBAccess.RunSQLReturnTable(mysql); foreach (DataRow dr in mydt.Rows) { string msgAskFor = dr[TrackAttr.Msg].ToString(); string worker = dr[TrackAttr.EmpFrom].ToString(); string workerName = dr[TrackAttr.EmpFromT].ToString(); string rdt = dr[TrackAttr.RDT].ToString(); DataRow drMsg = dtAlert.NewRow(); drMsg["Title"] = worker + "," + workerName + "回复信息:"; drMsg["Msg"] = DataType.ParseText2Html(msgAskFor) + "<br>" + rdt; dtAlert.Rows.Add(drMsg); } break; case WFState.Askfor: //加签. sql = "SELECT * FROM ND" + int.Parse(fk_flow) + "Track WHERE WorkID=" + workID + " AND " + TrackAttr.ActionType + "=" + (int)ActionType.AskforHelp; dt = BP.DA.DBAccess.RunSQLReturnTable(sql); foreach (DataRow dr in dt.Rows) { string msgAskFor = dr[TrackAttr.Msg].ToString(); string worker = dr[TrackAttr.EmpFrom].ToString(); string workerName = dr[TrackAttr.EmpFromT].ToString(); string rdt = dr[TrackAttr.RDT].ToString(); DataRow drMsg = dtAlert.NewRow(); drMsg["Title"] = worker + "," + workerName + "请求加签:"; drMsg["Msg"] = DataType.ParseText2Html(msgAskFor) + "<br>" + rdt + "<a href='./WorkOpt/AskForRe.htm?FK_Flow=" + fk_flow + "&FK_Node=" + fk_node + "&WorkID=" + workID + "&FID=" + fid + "' >回复加签意见</a> --"; dtAlert.Rows.Add(drMsg); //提示信息. // this.FlowMsg.AlertMsg_Info(worker + "," + workerName + "请求加签:", // DataType.ParseText2Html(msgAskFor) + "<br>" + rdt + " --<a href='./WorkOpt/AskForRe.aspx?FK_Flow=" + this.FK_Flow + "&FK_Node=" + this.FK_Node + "&WorkID=" + this.WorkID + "&FID=" + this.FID + "' >回复加签意见</a> --"); } // isAskFor = true; break; case WFState.ReturnSta: /* 如果工作节点退回了*/ ReturnWorks rws = new ReturnWorks(); rws.Retrieve(ReturnWorkAttr.ReturnToNode, fk_node, ReturnWorkAttr.WorkID, workID, ReturnWorkAttr.RDT); if (rws.Count != 0) { //string msgInfo = ""; //foreach (BP.WF.ReturnWork rw in rws) //{ // DataRow drMsg = dtAlert.NewRow(); // //drMsg["Title"] = "来自节点:" + rw.ReturnNodeName + " 退回人:" + rw.ReturnerName + " " + rw.RDT + " <a href='/DataUser/ReturnLog/" + fk_flow + "/" + rw.MyPK + ".htm' target=_blank>工作日志</a>"; // drMsg["Title"] = "来自节点:" + rw.ReturnNodeName + " 退回人:" + rw.ReturnerName + " " + rw.RDT; // drMsg["Msg"] = rw.BeiZhuHtml; // dtAlert.Rows.Add(drMsg); //} string msgInfo = ""; foreach (BP.WF.ReturnWork rw in rws) { //drMsg["Title"] = "来自节点:" + rw.ReturnNodeName + " 退回人:" + rw.ReturnerName + " " + rw.RDT + " <a href='/DataUser/ReturnLog/" + fk_flow + "/" + rw.MyPK + ".htm' target=_blank>工作日志</a>"; msgInfo += "\t\n来自节点:" + rw.ReturnNodeName + " 退回人:" + rw.ReturnerName + " " + rw.RDT; msgInfo += rw.BeiZhuHtml; } string str = nd.ReturnAlert; if (str != "") { str = str.Replace("~", "'"); str = str.Replace("@PWorkID", workID.ToString()); str = str.Replace("@PNodeID", nd.NodeID.ToString()); str = str.Replace("@FK_Node", nd.NodeID.ToString()); str = str.Replace("@PFlowNo", fk_flow); str = str.Replace("@FK_Flow", fk_flow); str = str.Replace("@PWorkID", workID.ToString()); str = str.Replace("@WorkID", workID.ToString()); str = str.Replace("@OID", workID.ToString()); DataRow drMsg = dtAlert.NewRow(); drMsg["Title"] = "退回信息"; drMsg["Msg"] = msgInfo + "\t\n" + str; dtAlert.Rows.Add(drMsg); } else { DataRow drMsg = dtAlert.NewRow(); drMsg["Title"] = "退回信息"; drMsg["Msg"] = msgInfo + "\t\n" + str; dtAlert.Rows.Add(drMsg); } } break; case WFState.Shift: /* 判断移交过来的。 */ ShiftWorks fws = new ShiftWorks(); BP.En.QueryObject qo = new QueryObject(fws); qo.AddWhere(ShiftWorkAttr.WorkID, workID); qo.addAnd(); qo.AddWhere(ShiftWorkAttr.FK_Node, fk_node); qo.addOrderBy(ShiftWorkAttr.RDT); qo.DoQuery(); if (fws.Count >= 1) { DataRow drMsg = dtAlert.NewRow(); drMsg["Title"] = "移交历史信息"; msg = ""; foreach (ShiftWork fw in fws) { string temp = "@移交人[" + fw.FK_Emp + "," + fw.FK_EmpName + "]。@接受人:" + fw.ToEmp + "," + fw.ToEmpName + "。<br>移交原因:-------------" + fw.NoteHtml; if (fw.FK_Emp == WebUser.No) { temp = "<b>" + temp + "</b>"; } temp = temp.Replace("@", "<br>@"); msg += temp + "<hr/>"; } drMsg["Msg"] = msg; dtAlert.Rows.Add(drMsg); } break; default: break; } #endregion #region 增加流程节点表单绑定信息. if (nd.HisFormType == NodeFormType.RefOneFrmTree) { /* 独立流程节点表单. */ nd.WorkID = workID; //为获取表单ID ( NodeFrmID )提供参数. FrmNode fn = new FrmNode(); fn.MyPK = nd.NodeFrmID + "_" + nd.NodeID + "_" + nd.FK_Flow; fn.Retrieve(); myds.Tables.Add(fn.ToDataTableField("FrmNode")); } #endregion 增加流程节点表单绑定信息. myds.Tables.Add(dtAlert); return(myds); } catch (Exception ex) { Log.DebugWriteError(ex.StackTrace); throw new Exception(ex.Message); } }
/// <summary> /// 撤消分流点 /// 1, 把分流节点的人员设置成待办。 /// 2,删除所有该分流点发起的子线程。 /// </summary> /// <param name="gwf"></param> /// <returns></returns> private string DoUnSendFeiLiu(GenerWorkFlow gwf) { //首先要检查,当前的处理人是否是分流节点的处理人?如果是,就要把,未走完的所有子线程都删除掉。 GenerWorkerList gwl = new GenerWorkerList(); int i = gwl.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node, GenerWorkerListAttr.FK_Emp, WebUser.No); if (i == 0) { throw new Exception("@您不能执行撤消发送,因为当前工作不是您发送的。"); } //处理事件. Node nd = new Node(gwf.FK_Node); Work wk = nd.HisWork; wk.OID = gwf.WorkID; wk.RetrieveFromDBSources(); string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wk, null); // 记录日志.. WorkNode wn = new WorkNode(wk, nd); wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, gwf.FK_Node, gwf.NodeName, ""); //删除上一个节点的数据。 foreach (Node ndNext in nd.HisToNodes) { i = DBAccess.RunSQL("DELETE FROM WF_GenerWorkerList WHERE FID=" + this.WorkID + " AND FK_Node=" + ndNext.NodeID); if (i == 0) { continue; } if (ndNext.HisRunModel == RunModel.SubThread) { /*如果到达的节点是子线程,就查询出来发起的子线程。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.FID, this.WorkID); foreach (GenerWorkFlow en in gwfs) { BP.WF.Dev2Interface.Flow_DeleteSubThread(gwf.FK_Flow, en.WorkID, "合流节点撤销发送前,删除子线程."); } continue; } // 删除工作记录。 Works wks = ndNext.HisWorks; if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wks.Delete(GenerWorkerListAttr.FID, this.WorkID); } } //设置当前节点。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND IsPass=1"); // 设置当前节点的状态. Node cNode = new Node(gwf.FK_Node); Work cWork = cNode.HisWork; cWork.OID = this.WorkID; msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wk, null); return("@撤消执行成功." + msg); }
/// <summary> /// 产生一个WorkNode /// </summary> /// <param name="fk_flow">流程编号</param> /// <param name="fk_node">节点ID</param> /// <param name="workID">工作ID</param> /// <param name="fid">FID</param> /// <param name="userNo">用户编号</param> /// <returns>返回dataset</returns> public static DataSet GenerWorkNodeForAndroid(string fk_flow, int fk_node, Int64 workID, Int64 fid, string userNo) { if (fk_node == 0) { fk_node = int.Parse(fk_flow + "01"); } if (workID == 0) { workID = BP.WF.Dev2Interface.Node_CreateBlankWork(fk_flow, null, null, userNo, null); } try { Emp emp = new Emp(userNo); BP.Web.WebUser.SignInOfGener(emp); MapData md = new MapData(); md.No = "ND" + fk_node; if (md.RetrieveFromDBSources() == 0) { throw new Exception("装载错误,该表单ID=" + md.No + "丢失,请修复一次流程重新加载一次."); } //表单模版. DataSet myds = BP.Sys.CCFormAPI.GenerHisDataSet(md.No); return(myds); #region 流程设置信息. Node nd = new Node(fk_node); if (nd.IsStartNode == false) { BP.WF.Dev2Interface.Node_SetWorkRead(fk_node, workID); } // 节点数据. string sql = "SELECT * FROM WF_Node WHERE NodeID=" + fk_node; DataTable dt = BP.DA.DBAccess.RunSQLReturnTable(sql); dt.TableName = "WF_NodeBar"; myds.Tables.Add(dt); // 流程数据. Flow fl = new Flow(fk_flow); myds.Tables.Add(fl.ToDataTableField("WF_Flow")); #endregion 流程设置信息. #region 把主从表数据放入里面. //.工作数据放里面去, 放进去前执行一次装载前填充事件. BP.WF.Work wk = nd.HisWork; wk.OID = workID; wk.RetrieveFromDBSources(); // 处理传递过来的参数。 foreach (string k in System.Web.HttpContext.Current.Request.QueryString.AllKeys) { wk.SetValByKey(k, System.Web.HttpContext.Current.Request.QueryString[k]); } // 执行一次装载前填充. string msg = md.DoEvent(FrmEventList.FrmLoadBefore, wk); if (DataType.IsNullOrEmpty(msg) == false) { throw new Exception("错误:" + msg); } wk.ResetDefaultVal(); myds.Tables.Add(wk.ToDataTableField(md.No)); //把附件的数据放入. if (md.FrmAttachments.Count > 0) { sql = "SELECT * FROM Sys_FrmAttachmentDB where RefPKVal=" + workID + " AND FK_MapData='ND" + fk_node + "'"; dt = BP.DA.DBAccess.RunSQLReturnTable(sql); dt.TableName = "Sys_FrmAttachmentDB"; myds.Tables.Add(dt); } // 图片附件数据放入 if (md.FrmImgAths.Count > 0) { sql = "SELECT * FROM Sys_FrmImgAthDB where RefPKVal=" + workID + " AND FK_MapData='ND" + fk_node + "'"; dt = BP.DA.DBAccess.RunSQLReturnTable(sql); dt.TableName = "Sys_FrmImgAthDB"; myds.Tables.Add(dt); } //把从表的数据放入. if (md.MapDtls.Count > 0) { foreach (MapDtl dtl in md.MapDtls) { GEDtls dtls = new GEDtls(dtl.No); QueryObject qo = null; try { qo = new QueryObject(dtls); switch (dtl.DtlOpenType) { case DtlOpenType.ForEmp: // 按人员来控制. qo.AddWhere(GEDtlAttr.RefPK, workID); qo.addAnd(); qo.AddWhere(GEDtlAttr.Rec, WebUser.No); break; case DtlOpenType.ForWorkID: // 按工作ID来控制 qo.AddWhere(GEDtlAttr.RefPK, workID); break; case DtlOpenType.ForFID: // 按流程ID来控制. qo.AddWhere(GEDtlAttr.FID, workID); break; } } catch { dtls.GetNewEntity.CheckPhysicsTable(); } DataTable dtDtl = qo.DoQueryToTable(); // 为明细表设置默认值. MapAttrs dtlAttrs = new MapAttrs(dtl.No); foreach (MapAttr attr in dtlAttrs) { //处理它的默认值. if (attr.DefValReal.Contains("@") == false) { continue; } foreach (DataRow dr in dtDtl.Rows) { dr[attr.KeyOfEn] = attr.DefVal; } } dtDtl.TableName = dtl.No; //修改明细表的名称. myds.Tables.Add(dtDtl); //加入这个明细表, 如果没有数据,xml体现为空. } } #endregion #region 把外键表加入DataSet DataTable dtMapAttr = myds.Tables["Sys_MapAttr"]; foreach (DataRow dr in dtMapAttr.Rows) { string lgType = dr["LGType"].ToString(); if (lgType.Equals("2") == false) { continue; } string UIIsEnable = dr["UIIsEnable"].ToString(); if (UIIsEnable.Equals("0") == true) { continue; } string uiBindKey = dr["UIBindKey"].ToString(); if (DataType.IsNullOrEmpty(uiBindKey) == true) { string myPK = dr["MyPK"].ToString(); /*如果是空的*/ throw new Exception("@属性字段数据不完整,流程:" + fl.No + fl.Name + ",节点:" + nd.NodeID + nd.Name + ",属性:" + myPK + ",的UIBindKey IsNull "); } // 判断是否存在. if (myds.Tables.Contains(uiBindKey) == true) { continue; } myds.Tables.Add(BP.Sys.PubClass.GetDataTableByUIBineKey(uiBindKey)); } #endregion End把外键表加入DataSet #region 把流程信息放入里面. //把流程信息表发送过去. GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = workID; gwf.RetrieveFromDBSources(); myds.Tables.Add(gwf.ToDataTableField("WF_GenerWorkFlow")); if (gwf.WFState == WFState.Shift) { //如果是转发. BP.WF.ShiftWorks fws = new ShiftWorks(); fws.Retrieve(ShiftWorkAttr.WorkID, workID, ShiftWorkAttr.FK_Node, fk_node); myds.Tables.Add(fws.ToDataTableField("WF_ShiftWork")); } if (gwf.WFState == WFState.ReturnSta) { //如果是退回. ReturnWorks rts = new ReturnWorks(); rts.Retrieve(ReturnWorkAttr.WorkID, workID, ReturnWorkAttr.ReturnToNode, fk_node, ReturnWorkAttr.RDT); myds.Tables.Add(rts.ToDataTableField("WF_ReturnWork")); } if (gwf.WFState == WFState.HungUp) { //如果是挂起. HungUps hups = new HungUps(); hups.Retrieve(HungUpAttr.WorkID, workID, HungUpAttr.FK_Node, fk_node); myds.Tables.Add(hups.ToDataTableField("WF_HungUp")); } //if (gwf.WFState == WFState.Askfor) //{ // //如果是加签. // BP.WF.ShiftWorks fws = new ShiftWorks(); // fws.Retrieve(ShiftWorkAttr.WorkID, workID, ShiftWorkAttr.FK_Node, fk_node); // myds.Tables.Add(fws.ToDataTableField("WF_ShiftWork")); //} Int64 wfid = workID; if (fid != 0) { wfid = fid; } //放入track信息. Paras ps = new Paras(); ps.SQL = "SELECT * FROM ND" + int.Parse(fk_flow) + "Track WHERE WorkID=" + BP.Sys.SystemConfig.AppCenterDBVarStr + "WorkID"; ps.Add("WorkID", wfid); DataTable dtNode = DBAccess.RunSQLReturnTable(ps); dtNode.TableName = "Track"; myds.Tables.Add(dtNode); //工作人员列表,用于审核组件. ps = new Paras(); ps.SQL = "SELECT * FROM WF_GenerWorkerlist WHERE WorkID=" + BP.Sys.SystemConfig.AppCenterDBVarStr + "WorkID"; ps.Add("WorkID", wfid); DataTable dtGenerWorkerlist = DBAccess.RunSQLReturnTable(ps); dtGenerWorkerlist.TableName = "WF_GenerWorkerlist"; myds.Tables.Add(dtGenerWorkerlist); //放入CCList信息. 用于审核组件. ps = new Paras(); ps.SQL = "SELECT * FROM WF_CCList WHERE WorkID=" + BP.Sys.SystemConfig.AppCenterDBVarStr + "WorkID"; ps.Add("WorkID", wfid); DataTable dtCCList = DBAccess.RunSQLReturnTable(ps); dtCCList.TableName = "WF_CCList"; myds.Tables.Add(dtCCList); //放入WF_SelectAccper信息. 用于审核组件. ps = new Paras(); ps.SQL = "SELECT * FROM WF_SelectAccper WHERE WorkID=" + BP.Sys.SystemConfig.AppCenterDBVarStr + "WorkID"; ps.Add("WorkID", wfid); DataTable dtSelectAccper = DBAccess.RunSQLReturnTable(ps); dtSelectAccper.TableName = "WF_SelectAccper"; myds.Tables.Add(dtSelectAccper); //放入所有的节点信息. 用于审核组件. ps = new Paras(); ps.SQL = "SELECT * FROM WF_Node WHERE FK_Flow=" + BP.Sys.SystemConfig.AppCenterDBVarStr + "FK_Flow ORDER BY " + NodeAttr.Step; ps.Add("FK_Flow", fk_flow); DataTable dtNodes = DBAccess.RunSQLReturnTable(ps); dtNodes.TableName = "Nodes"; myds.Tables.Add(dtNodes); #endregion 把流程信息放入里面. return(myds); } catch (Exception ex) { Log.DebugWriteError(ex.StackTrace); throw new Exception(ex.Message); } }
/// <summary> /// 子线程退回给分流点 /// </summary> /// <returns></returns> private string ExeReturn5_2() { GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); gwf.FK_Node = this.ReturnToNode.NodeID; string info = "@工作已经成功的退回到(" + ReturnToNode.Name + ")退回给:"; //查询退回到的工作人员列表. GenerWorkerLists gwls = new GenerWorkerLists(); gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID); string toEmp = ""; string toEmpName = ""; if (gwls.Count == 1) { /*有可能多次退回的情况,表示曾经退回过n次。*/ foreach (GenerWorkerList item in gwls) { item.IsPass = false; // 显示待办, 这个是合流节点的工作人员. item.IsRead = false; // item.Update(); info += item.FK_Emp + "," + item.FK_EmpText; toEmp = item.FK_Emp; toEmpName = item.FK_EmpText; info += "(" + item.FK_Emp + "," + item.FK_EmpText + ")"; } } else { // 找到合流点的发送人. Nodes nds = this.HisNode.FromNodes; gwls = new GenerWorkerLists(); GenerWorkerList gwl = new GenerWorkerList(); foreach (Node nd in nds) { gwls.Retrieve(GenerWorkerListAttr.WorkID, this.FID, GenerWorkerListAttr.FK_Node, nd.NodeID, GenerWorkerListAttr.IsPass, 1); if (gwls.Count == 0) { continue; } if (gwls.Count != 1) { throw new Exception("@应该只有一个记录,现在有多个,可能错误。"); } //求出分流节点的发送人. gwl = (GenerWorkerList)gwls[0]; toEmp = gwl.FK_Emp; toEmpName = gwl.FK_EmpText; info += "(" + toEmp + "," + toEmpName + ")"; } if (string.IsNullOrEmpty(toEmp) == true) { throw new Exception("@在退回时出现错误,没有找到分流节点的发送人。"); } // 插入一条数据, 行程一个工作人员记录,这个记录就是子线程的延长点. 给合流点上的接受人设置待办. gwl.WorkID = this.WorkID; gwl.FID = this.FID; gwl.IsPass = false; if (gwl.IsExits == false) { gwl.Insert(); } else { gwl.Update(); } } // 记录退回轨迹。 ReturnWork rw = new ReturnWork(); rw.WorkID = this.WorkID; rw.ReturnToNode = this.ReturnToNode.NodeID; rw.ReturnNodeName = this.ReturnToNode.Name; rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点. rw.ReturnToEmp = toEmp; //退回给。 rw.MyPK = DBAccess.GenerOIDByGUID().ToString(); rw.Note = Msg; rw.IsBackTracking = this.IsBackTrack; rw.Insert(); // 加入track. this.AddToTrack(ActionType.Return, toEmp, toEmpName, this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg); gwf.WFState = WFState.ReturnSta; gwf.FK_Node = this.ReturnToNode.NodeID; gwf.NodeName = this.ReturnToNode.Name; gwf.Starter = toEmp; gwf.StarterName = toEmpName; gwf.Update(); //找到当前的工作数据. GenerWorkerList currWorker = new GenerWorkerList(); int i = currWorker.Retrieve(GenerWorkerListAttr.FK_Emp, WebUser.No, GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.HisNode.NodeID); if (i != 1) { throw new Exception("@当前的工作人员列表数据丢失了,流程引擎错误."); } //设置当前的工作数据为退回状态,让其不能看到待办, 这个是约定的值. currWorker.IsPassInt = (int)WFState.ReturnSta; currWorker.Update(); // 返回退回信息. return(info); }
/// <summary> /// 分合流的撤销发送. /// </summary> /// <param name="gwf"></param> /// <returns></returns> private string DoUnSendInFeiLiuHeiliu(GenerWorkFlow gwf) { //首先要检查,当前的处理人是否是分流节点的处理人?如果是,就要把,未走完的所有子线程都删除掉。 GenerWorkerList gwl = new GenerWorkerList(); //删除合流节点的处理人. gwl.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node); //查询已经走得分流节点待办. int i = gwl.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.UnSendToNode, GenerWorkerListAttr.FK_Emp, WebUser.No); if (i == 0) { throw new Exception("@您不能执行撤消发送,因为当前分流工作不是您发送的。"); } // 更新分流节点,让其出现待办. gwl.IsPassInt = 0; gwl.IsRead = false; gwl.SDT = BP.DA.DataType.CurrentDataTime; //这里计算时间有问题. gwl.Update(); // 把设置当前流程运行到分流流程上. gwf.FK_Node = this.UnSendToNode; Node nd = new Node(this.UnSendToNode); gwf.NodeName = nd.Name; gwf.Sender = BP.Web.WebUser.No; gwf.SendDT = BP.DA.DataType.CurrentDataTimess; gwf.Update(); Work wk = nd.HisWork; wk.OID = gwf.WorkID; wk.RetrieveFromDBSources(); string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wk, null); // 记录日志.. WorkNode wn = new WorkNode(wk, nd); wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, gwf.FK_Node, gwf.NodeName, ""); //删除上一个节点的数据。 foreach (Node ndNext in nd.HisToNodes) { i = DBAccess.RunSQL("DELETE FROM WF_GenerWorkerList WHERE FID=" + this.WorkID + " AND FK_Node=" + ndNext.NodeID); if (i == 0) { continue; } if (ndNext.HisRunModel == RunModel.SubThread) { /*如果到达的节点是子线程,就查询出来发起的子线程。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.FID, this.WorkID); foreach (GenerWorkFlow en in gwfs) { BP.WF.Dev2Interface.Flow_DeleteSubThread(gwf.FK_Flow, en.WorkID, "合流节点撤销发送前,删除子线程."); } continue; } // 删除工作记录。 Works wks = ndNext.HisWorks; if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wks.Delete(GenerWorkerListAttr.FID, this.WorkID); } } // 设置当前节点的状态. Node cNode = new Node(gwf.FK_Node); Work cWork = cNode.HisWork; cWork.OID = this.WorkID; msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wk, null); if (cNode.IsStartNode) { return("@撤消执行成功." + msg); } else { return("@撤消执行成功." + msg); } }
/// <summary> /// 创建WorkID /// </summary> /// <param name="flowNo">流程编号</param> /// <param name="ht">表单参数,可以为null。</param> /// <param name="workDtls">明细表参数,可以为null。</param> /// <param name="starter">流程的发起人</param> /// <param name="title">创建工作时的标题,如果为null,就按设置的规则生成。</param> /// <param name="parentWorkID">父流程的WorkID,如果没有父流程就传入为0.</param> /// <param name="parentFlowNo">父流程的流程编号,如果没有父流程就传入为null.</param> /// <returns>为开始节点创建工作后产生的WorkID.</returns> public static Int64 Node_CreateBlankWork(string flowNo, Hashtable ht, DataSet workDtls, string guestNo, string title, Int64 parentWorkID, string parentFlowNo, int parentNodeID, string parentEmp) { //if (BP.Web.WebUser.No != "Guest") // throw new Exception("@必须是Guest登陆才能发起."); string dbstr = SystemConfig.AppCenterDBVarStr; Flow fl = new Flow(flowNo); Node nd = new Node(fl.StartNodeID); //把一些其他的参数也增加里面去,传递给ccflow. Hashtable htPara = new Hashtable(); if (parentWorkID != 0) { htPara.Add(StartFlowParaNameList.PWorkID, parentWorkID); } if (parentFlowNo != null) { htPara.Add(StartFlowParaNameList.PFlowNo, parentFlowNo); } if (parentNodeID != 0) { htPara.Add(StartFlowParaNameList.PNodeID, parentNodeID); } if (parentEmp != null) { htPara.Add(StartFlowParaNameList.PEmp, parentEmp); } Emp empStarter = new Emp(BP.Web.WebUser.No); Work wk = fl.NewWork(empStarter, htPara); Int64 workID = wk.OID; #region 给各个属性-赋值 if (ht != null) { foreach (string str in ht.Keys) { wk.SetValByKey(str, ht[str]); } } wk.OID = workID; if (workDtls != null) { //保存从表 foreach (DataTable dt in workDtls.Tables) { foreach (MapDtl dtl in wk.HisMapDtls) { if (dt.TableName != dtl.No) { continue; } //获取dtls GEDtls daDtls = new GEDtls(dtl.No); daDtls.Delete(GEDtlAttr.RefPK, wk.OID); // 清除现有的数据. GEDtl daDtl = daDtls.GetNewEntity as GEDtl; daDtl.RefPK = wk.OID.ToString(); // 为从表复制数据. foreach (DataRow dr in dt.Rows) { daDtl.ResetDefaultVal(); daDtl.RefPK = wk.OID.ToString(); //明细列. foreach (DataColumn dc in dt.Columns) { //设置属性. daDtl.SetValByKey(dc.ColumnName, dr[dc.ColumnName]); } daDtl.InsertAsOID(DBAccess.GenerOID("Dtl")); //插入数据. } } } } #endregion 赋值 Paras ps = new Paras(); // 执行对报表的数据表WFState状态的更新,让它为runing的状态. if (DataType.IsNullOrEmpty(title) == false) { ps = new Paras(); ps.SQL = "UPDATE " + fl.PTable + " SET WFState=" + dbstr + "WFState,Title=" + dbstr + "Title WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.WFState, (int)WFState.Blank); ps.Add(GERptAttr.Title, title); ps.Add(GERptAttr.OID, wk.OID); DBAccess.RunSQL(ps); } else { ps = new Paras(); ps.SQL = "UPDATE " + fl.PTable + " SET WFState=" + dbstr + "WFState,FK_Dept=" + dbstr + "FK_Dept,Title=" + dbstr + "Title WHERE OID=" + dbstr + "OID"; ps.Add(GERptAttr.WFState, (int)WFState.Blank); ps.Add(GERptAttr.FK_Dept, empStarter.FK_Dept); ps.Add(GERptAttr.Title, BP.WF.WorkFlowBuessRole.GenerTitle(fl, wk)); ps.Add(GERptAttr.OID, wk.OID); DBAccess.RunSQL(ps); } // 删除有可能产生的垃圾数据,比如上一次没有发送成功,导致数据没有清除. ps = new Paras(); ps.SQL = "DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + dbstr + "WorkID1 OR FID=" + dbstr + "WorkID2"; ps.Add("WorkID1", wk.OID); ps.Add("WorkID2", wk.OID); DBAccess.RunSQL(ps); ps = new Paras(); ps.SQL = "DELETE FROM WF_GenerWorkerList WHERE WorkID=" + dbstr + "WorkID1 OR FID=" + dbstr + "WorkID2"; ps.Add("WorkID1", wk.OID); ps.Add("WorkID2", wk.OID); DBAccess.RunSQL(ps); // 设置流程信息 if (parentWorkID != 0) { BP.WF.Dev2Interface.SetParentInfo(flowNo, workID, parentWorkID); } #region 处理generworkid // 设置父流程信息. GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = wk.OID; int i = gwf.RetrieveFromDBSources(); //将流程信息提前写入wf_GenerWorkFlow,避免查询不到 gwf.FlowName = fl.Name; gwf.FK_Flow = flowNo; gwf.FK_FlowSort = fl.FK_FlowSort; gwf.SysType = fl.SysType; gwf.FK_Dept = WebUser.FK_Dept; gwf.DeptName = WebUser.FK_DeptName; gwf.FK_Node = fl.StartNodeID; gwf.NodeName = nd.Name; gwf.WFState = WFState.Runing; if (DataType.IsNullOrEmpty(title)) { gwf.Title = BP.WF.WorkFlowBuessRole.GenerTitle(fl, wk); } else { gwf.Title = title; } gwf.Starter = WebUser.No; gwf.StarterName = WebUser.Name; gwf.RDT = DataType.CurrentDataTimess; gwf.PWorkID = parentWorkID; // gwf.PFID = parentFID; gwf.PFlowNo = parentFlowNo; gwf.PNodeID = parentNodeID; if (i == 0) { gwf.Insert(); } else { gwf.Update(); } //插入待办. GenerWorkerList gwl = new GenerWorkerList(); gwl.WorkID = wk.OID; gwl.FK_Node = nd.NodeID; gwl.FK_Emp = WebUser.No; i = gwl.RetrieveFromDBSources(); gwl.FK_EmpText = WebUser.Name; gwl.FK_NodeText = nd.Name; gwl.FID = 0; gwl.FK_Flow = fl.No; gwl.FK_Dept = WebUser.FK_Dept; gwl.FK_DeptT = WebUser.FK_DeptName; gwl.SDT = "无"; gwl.DTOfWarning = DataType.CurrentDataTime; gwl.IsEnable = true; gwl.IsPass = false; gwl.PRI = gwf.PRI; if (i == 0) { gwl.Insert(); } else { gwl.Update(); } #endregion return(wk.OID); }
/// <summary> /// 执行撤销发送 /// </summary> /// <param name="gwf"></param> /// <returns></returns> public string DoUnSendHeiLiu_Main(GenerWorkFlow gwf) { Node currNode = new Node(gwf.FK_Node); Node priFLNode = currNode.HisPriFLNode; GenerWorkerList wl = new GenerWorkerList(); //判断改操作人员是否是分流节点上的人员. int i = wl.Retrieve(GenerWorkerListAttr.FK_Node, priFLNode.NodeID, GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No); if (i == 0) { return("@不是您把工作发送到当前节点上,所以您不能撤消。"); } WorkNode wn = this.GetCurrentWorkNode(); WorkNode wnPri = new WorkNode(this.WorkID, priFLNode.NodeID); // 记录日志.. wnPri.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, wnPri.HisNode.NodeID, wnPri.HisNode.Name, "无"); //删除当前节点的流程 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node.ToString()); if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } //更改流程信息 gwf.FK_Node = wnPri.HisNode.NodeID; gwf.NodeName = wnPri.HisNode.Name; gwf.Update(); BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); //删除子线程的功能 foreach (Node ndNext in wnPri.HisNode.HisToNodes) { i = DBAccess.RunSQL("DELETE FROM WF_GenerWorkerList WHERE FID=" + this.WorkID + " AND FK_Node=" + ndNext.NodeID); if (i == 0) { continue; } if (ndNext.HisRunModel == RunModel.SubThread) { /*如果到达的节点是子线程,就查询出来发起的子线程。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.FID, this.WorkID); foreach (GenerWorkFlow en in gwfs) { BP.WF.Dev2Interface.Flow_DeleteSubThread(gwf.FK_Flow, en.WorkID, "合流节点撤销发送前,删除子线程."); } continue; } // 删除工作记录。 Works wks = ndNext.HisWorks; if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wks.Delete(GenerWorkerListAttr.FID, this.WorkID); } } ShiftWorks fws = new ShiftWorks(); fws.Delete(ShiftWorkAttr.FK_Node, wn.HisNode.NodeID.ToString(), ShiftWorkAttr.WorkID, this.WorkID.ToString()); #region 恢复工作轨迹,解决工作抢办。 if (wnPri.HisNode.IsStartNode == false) { WorkNode ppPri = wnPri.GetPreviousWorkNode(); wl = new GenerWorkerList(); wl.Retrieve(GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); RememberMe rm = new RememberMe(); rm.Retrieve(RememberMeAttr.FK_Node, wnPri.HisNode.NodeID, RememberMeAttr.FK_Emp, ppPri.HisWork.Rec); string[] empStrs = rm.Objs.Split('@'); foreach (string s in empStrs) { if (s == "" || s == null) { continue; } if (s == wl.FK_Emp) { continue; } GenerWorkerList wlN = new GenerWorkerList(); wlN.Copy(wl); wlN.FK_Emp = s; WF.Port.WFEmp myEmp = new Port.WFEmp(s); wlN.FK_EmpText = myEmp.Name; wlN.Insert(); } } #endregion 恢复工作轨迹,解决工作抢办。 // 删除以前的节点数据. wnPri.DeleteToNodesData(priFLNode.HisToNodes); if (wnPri.HisNode.IsStartNode) { if (wnPri.HisNode.HisFormType != NodeFormType.SDKForm) { return("@撤消执行成功."); } else { return("@撤销成功."); } } else { return("@撤消执行成功."); } }
private WorkNode DoReturnSubFlow(int backtoNodeID, string msg, bool isHiden) { Node nd = new Node(backtoNodeID); ps = new Paras(); ps.SQL = "DELETE FROM WF_GenerWorkerList WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID AND FID=" + dbStr + "FID"; ps.Add("FK_Node", backtoNodeID); ps.Add("WorkID", this.HisWork.OID); ps.Add("FID", this.HisWork.FID); BP.DA.DBAccess.RunSQL(ps); // 找出分合流点处理的人员. ps = new Paras(); ps.SQL = "SELECT FK_Emp FROM WF_GenerWorkerList WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "FID"; ps.Add("FID", this.HisWork.FID); ps.Add("FK_Node", backtoNodeID); DataTable dt = DBAccess.RunSQLReturnTable(ps); if (dt.Rows.Count != 1) { throw new Exception("@ system error , this values must be =1"); } string FK_Emp = dt.Rows[0][0].ToString(); // 获取当前工作的信息. GenerWorkerList wl = new GenerWorkerList(this.HisWork.FID, this.HisNode.NodeID, FK_Emp); Emp emp = new Emp(FK_Emp); // 改变部分属性让它适应新的数据,并显示一条新的待办工作让用户看到。 wl.IsPass = false; wl.WorkID = this.HisWork.OID; wl.FID = this.HisWork.FID; wl.RDT = DataType.CurrentDataTime; wl.FK_Emp = FK_Emp; wl.FK_EmpText = emp.Name; wl.FK_Node = backtoNodeID; wl.FK_NodeText = nd.Name; wl.WarningDays = nd.WarningDays; wl.FK_Dept1 = emp.FK_Dept; DateTime dtNew = DateTime.Now; dtNew = dtNew.AddDays(nd.WarningDays); wl.SDT = dtNew.ToString(DataType.SysDataFormat); // DataType.CurrentDataTime; wl.FK_Flow = this.HisNode.FK_Flow; wl.Insert(); GenerWorkFlow gwf = new GenerWorkFlow(this.HisWork.OID); gwf.FK_Node = backtoNodeID; gwf.NodeName = nd.Name; gwf.DirectUpdate(); ps = new Paras(); ps.Add("FK_Node", backtoNodeID); ps.Add("WorkID", this.HisWork.OID); ps.SQL = "UPDATE WF_GenerWorkerList SET IsPass=3 WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID"; BP.DA.DBAccess.RunSQL(ps); /* 如果是隐性退回。*/ BP.WF.ReturnWork rw = new ReturnWork(); rw.WorkID = wl.WorkID; rw.ReturnToNode = wl.FK_Node; rw.ReturnNode = this.HisNode.NodeID; rw.ReturnNodeName = this.HisNode.Name; rw.ReturnToEmp = FK_Emp; rw.Note = msg; try { rw.MyPK = rw.ReturnToNode + "_" + rw.WorkID + "_" + DateTime.Now.ToString("yyyyMMddhhmmss"); rw.Insert(); } catch { rw.MyPK = rw.ReturnToNode + "_" + rw.WorkID + "_" + BP.DA.DBAccess.GenerOID(); rw.Insert(); } // 加入track. this.AddToTrack(ActionType.Return, FK_Emp, emp.Name, backtoNodeID, nd.Name, msg); WorkNode wn = new WorkNode(this.HisWork.FID, backtoNodeID); if (Glo.IsEnableSysMessage) { // WF.Port.WFEmp wfemp = new Port.WFEmp(wn.HisWork.Rec); string title = string.Format("工作退回:流程:{0}.工作:{1},退回人:{2},需您处理", wn.HisNode.FlowName, wn.HisNode.Name, WebUser.Name); BP.WF.Dev2Interface.Port_SendMail(wn.HisWork.Rec, title, msg, "RESub" + backtoNodeID + "_" + this.WorkID, nd.FK_Flow, nd.NodeID, this.WorkID, this.FID); } return(wn); }
/// <summary> /// 执行子线程的撤销. /// </summary> /// <returns></returns> private string DoThreadUnSend() { //定义当前的节点. WorkNode wn = this.GetCurrentWorkNode(); GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID); Node nd = new Node(gwf.FK_Node); #region 求的撤销的节点. int cancelToNodeID = 0; if (nd.HisCancelRole == CancelRole.SpecNodes) { /*指定的节点可以撤销,首先判断当前人员是否有权限.*/ NodeCancels ncs = new NodeCancels(); ncs.Retrieve(NodeCancelAttr.FK_Node, wn.HisNode.NodeID); if (ncs.Count == 0) { throw new Exception("@流程设计错误, 您设置了当前节点(" + wn.HisNode.Name + ")可以让指定的节点人员撤销,但是您没有设置指定的节点."); } /* 查询出来. */ string sql = "SELECT FK_Node FROM WF_GenerWorkerList WHERE FK_Emp='" + WebUser.No + "' AND IsPass=1 AND IsEnable=1 AND WorkID=" + wn.HisWork.OID + " ORDER BY RDT DESC "; DataTable dt = DBAccess.RunSQLReturnTable(sql); if (dt.Rows.Count == 0) { throw new Exception("@撤销流程错误,您没有权限执行撤销发送."); } // 找到将要撤销到的NodeID. foreach (DataRow dr in dt.Rows) { foreach (NodeCancel nc in ncs) { if (nc.CancelTo == int.Parse(dr[0].ToString())) { cancelToNodeID = nc.CancelTo; break; } } if (cancelToNodeID != 0) { break; } } if (cancelToNodeID == 0) { throw new Exception("@撤销流程错误,您没有权限执行撤销发送,没有找到可以撤销的节点."); } } if (nd.HisCancelRole == CancelRole.OnlyNextStep) { /*如果仅仅允许撤销上一步骤.*/ WorkNode wnPri = wn.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID); if (num == 0) { throw new Exception("@您不能执行撤消发送,因为当前工作不是您发送的或下一步工作已处理。"); } cancelToNodeID = wnPri.HisNode.NodeID; } if (cancelToNodeID == 0) { throw new Exception("@没有求出要撤销到的节点."); } #endregion 求的撤销的节点. /********** 开始执行撤销. **********************/ Node cancelToNode = new Node(cancelToNodeID); WorkNode wnOfCancelTo = new WorkNode(this.WorkID, cancelToNodeID); // 调用撤消发送前事件。 string msg = nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneBefore, nd, wn.HisWork, null); #region 除当前节点数据。 // 删除产生的工作列表。 GenerWorkerLists wls = new GenerWorkerLists(); wls.Delete(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, gwf.FK_Node); // 删除工作信息,如果是按照ccflow格式存储的。 if (this.HisFlow.HisDataStoreModel == BP.WF.Template.DataStoreModel.ByCCFlow) { wn.HisWork.Delete(); } // 删除附件信息。 DBAccess.RunSQL("DELETE FROM Sys_FrmAttachmentDB WHERE FK_MapData='ND" + gwf.FK_Node + "' AND RefPKVal='" + this.WorkID + "'"); #endregion 除当前节点数据。 // 更新. gwf.FK_Node = cancelToNode.NodeID; gwf.NodeName = cancelToNode.Name; //如果不启动自动记忆,删除tonodes,用于 选择节点发送。撤消后,可重新选择节点发送 if (cancelToNode.IsRememberMe == false) { gwf.Paras_ToNodes = ""; } if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { gwf.TaskSta = TaskSta.Takeback; } else { gwf.TaskSta = TaskSta.None; } gwf.TodoEmps = WebUser.No + "," + WebUser.Name + ";"; gwf.Update(); if (cancelToNode.IsEnableTaskPool && Glo.IsEnableTaskPool) { //设置全部的人员不可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=-1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); //设置当前人员可用。 BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0, IsEnable=1 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node + " AND FK_Emp='" + WebUser.No + "'"); } else { BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerlist SET IsPass=0 WHERE WorkID=" + this.WorkID + " AND FK_Node=" + gwf.FK_Node); } //更新当前节点,到rpt里面。 BP.DA.DBAccess.RunSQL("UPDATE " + this.HisFlow.PTable + " SET FlowEndNode=" + gwf.FK_Node + " WHERE OID=" + this.WorkID); // 记录日志.. wn.AddToTrack(ActionType.UnSend, WebUser.No, WebUser.Name, cancelToNode.NodeID, cancelToNode.Name, "无"); // 删除数据. if (wn.HisNode.IsStartNode) { DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE WorkID=" + this.WorkID); DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE WorkID=" + this.WorkID + " AND FK_Node=" + nd.NodeID); } if (wn.HisNode.IsEval) { /*如果是质量考核节点,并且撤销了。*/ DBAccess.RunSQL("DELETE FROM WF_CHEval WHERE FK_Node=" + wn.HisNode.NodeID + " AND WorkID=" + this.WorkID); } #region 恢复工作轨迹,解决工作抢办。 if (cancelToNode.IsStartNode == false && cancelToNode.IsEnableTaskPool == false) { WorkNode ppPri = wnOfCancelTo.GetPreviousWorkNode(); GenerWorkerList wl = new GenerWorkerList(); wl.Retrieve(GenerWorkerListAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); // BP.DA.DBAccess.RunSQL("UPDATE WF_GenerWorkerList SET IsPass=0 WHERE FK_Node=" + backtoNodeID + " AND WorkID=" + this.WorkID); RememberMe rm = new RememberMe(); rm.Retrieve(RememberMeAttr.FK_Node, wnOfCancelTo.HisNode.NodeID, RememberMeAttr.FK_Emp, ppPri.HisWork.Rec); string[] empStrs = rm.Objs.Split('@'); foreach (string s in empStrs) { if (s == "" || s == null) { continue; } if (s == wl.FK_Emp) { continue; } GenerWorkerList wlN = new GenerWorkerList(); wlN.Copy(wl); wlN.FK_Emp = s; WF.Port.WFEmp myEmp = new Port.WFEmp(s); wlN.FK_EmpText = myEmp.Name; wlN.Insert(); } } #endregion 恢复工作轨迹,解决工作抢办。 #region 如果是开始节点, 检查此流程是否有子线程,如果有则删除它们。 if (nd.IsStartNode) { /*要检查一个是否有 子流程,如果有,则删除它们。*/ GenerWorkFlows gwfs = new GenerWorkFlows(); gwfs.Retrieve(GenerWorkFlowAttr.PWorkID, this.WorkID); if (gwfs.Count > 0) { foreach (GenerWorkFlow item in gwfs) { /*删除每个子线程.*/ BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(item.FK_Flow, item.WorkID, true); } } } #endregion //调用撤消发送后事件。 msg += nd.HisFlow.DoFlowEventEntity(EventListOfNode.UndoneAfter, nd, wn.HisWork, null); if (wnOfCancelTo.HisNode.IsStartNode) { return("@撤消执行成功. " + msg); } else { return("@撤消执行成功. " + msg); } return("工作已经被您撤销到:" + cancelToNode.Name); }