/// <summary> /// Runs the specified work on a custom call stack, which is not limited to 1 MB as the standard call stack is. /// See remarks for details.</summary> /// <typeparam name="T"> /// Type of result to compute.</typeparam> /// <param name="node"> /// Work to be executed.</param> /// <returns> /// The result of the computation.</returns> /// <remarks> /// <para> /// <see cref="CustomCallStack.Run{T}"/> expects a delegate that is structured in such a way that it:</para> /// <list type="bullet"> /// <item><description> /// always knows at what state in the computation it is each time it is called;</description></item> /// <item><description> /// returns a <see cref="WorkStep{T}.Call"/> each time it requires some other value to be computed, and /// then expects that resulting value to come in through the parameter next time it is called;</description></item> /// <item><description> /// returns a <see cref="WorkStep{T}.Return"/> when it is done. At this point the delegate is not called /// again.</description></item> /// <item><description> /// The delegate may return <c>null</c> to indicate the same as a <see cref="WorkStep{T}.Return"/> /// containing a <c>default(T)</c> value.</description></item></list> /// <para> /// CustomCallStack works as follows:</para> /// <list type="bullet"> /// <item><description> /// The first time the specified delegate is called, its parameter receives <c>default(T)</c>.</description></item> /// <item><description> /// If the value returned by the delegate is a <see cref="WorkStep{T}.Return"/>, the work is done and the /// result is returned.</description></item> /// <item><description> /// If the value returned is a <see cref="WorkStep{T}.Call"/>, this is treated similarly to a method call. /// The old delegate is pushed on a stack and the new delegate is executed according to the same rules /// until it returns a <see cref="WorkStep{T}.Return"/>. Once it does so, the original delegate is popped /// from the stack and then called with the result passed into its parameter.</description></item></list> /// <para> /// There are deliberately no safeguards in this algorithm; it will allow you to grow the stack indefinitely /// and not generate an equivalent to the <see cref="StackOverflowException"/>. This means that if your /// delegates always return a <see cref="WorkStep{T}.Call"/>, they will consume memory rampantly and never /// finish.</para></remarks> public static T Run <T>(WorkNode <T> node) { var evaluationStack = new Stack <WorkNode <T> >(); var prevResult = default(T); while (true) { var nextStep = node(prevResult); if (nextStep is WorkStep <T> .Call call) { evaluationStack.Push(node); node = call.Callee; prevResult = default(T); } else { prevResult = nextStep == null ? default(T) : ((WorkStep <T> .Return)nextStep).Result; if (evaluationStack.Count == 0) { return(prevResult); } node = evaluationStack.Pop(); } } }
protected void Page_Load(object sender, EventArgs e) { this.Page.Title = "Deal Work"; this.ToolBar1.Add("<input class=Btn type=button onclick=\"javascript:window.location.href='ReturnWorkSmall.aspx?WorkID=" + this.WorkID + "&FK_Flow=" + this.FK_Flow + "&FK_Node=" + this.FK_Node + "&FID=" + this.FID + "'\" value='退回' >"); this.ToolBar1.AddBtn("Btn_Del", "终止"); this.ToolBar1.AddBtn("Btn_Close", "关闭"); this.Btn_Close.OnClientClick = "window.close();"; this.Btn_Del.OnClientClick = "return confirm('are you sure?')"; this.Btn_Del.Click += new EventHandler(Btn_Del_Click); GenerWorkFlow gwf = new GenerWorkFlow(this.FID); WorkFlow wf = new WorkFlow(this.FK_Flow, this.FID); WorkNode wn = new WorkNode(this.FID, gwf.FK_Node); WorkNode wnPri = wn.GetPreviousWorkNode_FHL(this.WorkID); // 他的上一个节点. try { this.UCEn1.BindColumn4(wnPri.HisWork, "ND" + wnPri.HisNode.NodeID); this.UCEn1.Add(wnPri.HisWork.WorkEndInfo); } catch { this.WinCloseWithMsg("此工作已经终止或者被删除。"); } }
void btn_Click(object sender, EventArgs e) { string sql = "SELECT Title,RDT,ADT,SDT,FID,WorkID,Starter FROM WF_EmpWorks WHERE FK_Emp='" + WebUser.No + "'"; DataTable dt = BP.DA.DBAccess.RunSQLReturnTable(sql); string msg = ""; foreach (DataRow dr in dt.Rows) { Int64 workid = Int64.Parse(dr["WorkID"].ToString()); CheckBox cb = this.GetCBByID("CB_" + workid); if (cb.Checked == false) { return; } msg += "@对工作(" + dr["Title"] + ")处理情况如下。<br>"; WorkNode wn = new WorkNode(workid, this.FK_Node); msg += wn.NodeSend().ToMsgOfHtml(); msg += "<hr>"; } if (msg == "") { this.Alert("您没有选择工作."); } else { this.Clear(); msg += "<a href='Batch" + BP.WF.Glo.FromPageType + ".aspx'>返回...</a>"; this.AddMsgOfInfo("批量处理信息", msg); } }
private DataSet AccepterOfDeptStationOfCurrentOper(int nodeID, Entity en) { // 定义数据容器. DataSet ds = new DataSet(); //部门. string sql = ""; sql = "SELECT d.No,d.Name,d.ParentNo FROM Port_DeptEmp de,port_dept as d where de.FK_Dept = d.No and de.FK_Emp = '" + BP.Web.WebUser.No + "'"; DataTable dt = BP.DA.DBAccess.RunSQLReturnTable(sql); //人员. if (SystemConfig.AppCenterDBType == DBType.Oracle) { sql = "SELECT * FROM (SELECT distinct a.No,a.Name, a.FK_Dept FROM Port_Emp a, WF_NodeStation b, Port_DeptEmpStation c WHERE a.No=c.FK_Emp AND B.FK_Station=C.FK_Station AND C.FK_Dept='" + WebUser.FK_Dept + "' AND b.FK_Node=" + nodeID + ") "; } else { sql = "SELECT distinct a.No,a.Name, a.FK_Dept FROM Port_Emp a, WF_NodeStation b, Port_DeptEmpStation c WHERE a.No=c.FK_Emp AND C.FK_Dept='" + WebUser.FK_Dept + "' AND B.FK_Station=C.FK_Station AND b.FK_Node=" + nodeID; } DataTable dtEmp = BP.DA.DBAccess.RunSQLReturnTable(sql); if (dtEmp.Rows.Count > 0) { dt.TableName = "Depts"; ds.Tables.Add(dt); dtEmp.TableName = "Emps"; ds.Tables.Add(dtEmp); } else //如果没人,就查询父级 { //查询当前节点的workdID long workID = long.Parse(en.GetValStringByKey("OID")); BP.WF.WorkNode node = new WorkNode(workID, nodeID); sql = " select No,Name, ParentNo from port_dept where no in ( select ParentNo from port_dept where no in" + "( SELECT FK_Dept FROM WF_GenerWorkerlist WHERE WorkID ='" + workID + "' ))"; dt = BP.DA.DBAccess.RunSQLReturnTable(sql); dt.TableName = "Depts"; ds.Tables.Add(dt); // 如果当前的节点不是开始节点, 从轨迹里面查询。 sql = "SELECT DISTINCT b.No,b.Name,b.FK_Dept FROM " + BP.WF.Glo.EmpStation + " a,Port_Emp b WHERE FK_Station IN " + "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + nodeID + ") " + "AND a.FK_Dept IN (SELECT ParentNo FROM Port_Dept WHERE No in (SELECT FK_DEPT FROM WF_GenerWorkerlist WHERE WorkID=" + workID + "))" + " AND a.FK_Emp = b.No "; sql += " ORDER BY b.No "; dtEmp = DBAccess.RunSQLReturnTable(sql); dtEmp.TableName = "Emps"; ds.Tables.Add(dtEmp); } return(ds); }
/// <summary> /// 重新产生标题,根据新的规则. /// </summary> public string DoGenerTitle() { if (WebUser.No != "admin") { return("非admin用户不能执行。"); } Flow fl = new Flow(this.No); Node nd = fl.HisStartNode; Works wks = nd.HisWorks; wks.RetrieveAllFromDBSource(WorkAttr.Rec); string table = nd.HisWork.EnMap.PhysicsTable; string tableRpt = "ND" + int.Parse(this.No) + "Rpt"; Sys.MapData md = new Sys.MapData(tableRpt); foreach (Work wk in wks) { if (wk.Rec != WebUser.No) { BP.Web.WebUser.Exit(); try { Emp emp = new Emp(wk.Rec); BP.Web.WebUser.SignInOfGener(emp); } catch { continue; } } string sql = ""; string title = WorkNode.GenerTitle(fl, wk); Paras ps = new Paras(); ps.Add("Title", title); ps.Add("OID", wk.OID); ps.SQL = "UPDATE " + table + " SET Title=" + SystemConfig.AppCenterDBVarStr + "Title WHERE OID=" + SystemConfig.AppCenterDBVarStr + "OID"; DBAccess.RunSQL(ps); ps.SQL = "UPDATE " + md.PTable + " SET Title=" + SystemConfig.AppCenterDBVarStr + "Title WHERE OID=" + SystemConfig.AppCenterDBVarStr + "OID"; DBAccess.RunSQL(ps); ps.SQL = "UPDATE WF_GenerWorkFlow SET Title=" + SystemConfig.AppCenterDBVarStr + "Title WHERE WorkID=" + SystemConfig.AppCenterDBVarStr + "OID"; DBAccess.RunSQL(ps); ps.SQL = "UPDATE WF_GenerFH SET Title=" + SystemConfig.AppCenterDBVarStr + "Title WHERE FID=" + SystemConfig.AppCenterDBVarStr + "OID"; DBAccess.RunSQLs(sql); } Emp emp1 = new Emp("admin"); BP.Web.WebUser.SignInOfGener(emp1); return("全部生成成功,影响数据(" + wks.Count + ")条"); }
protected void Page_Load(object sender, EventArgs e) { // 退回流程. this.ToolBar1.Add("<input class=Btn type=button onclick=\"javascript:window.location.href='ReturnWork.aspx?FromUrl=FHLFlow&WorkID=" + this.WorkID + "&FK_Flow=" + this.FK_Flow + "&FK_Node=" + this.FK_Node + "&FID=" + this.FID + "'\" value='退回' >"); // 关闭. this.ToolBar1.AddBtn("Btn_Close", "关闭"); this.Btn_Close.OnClientClick = "window.close();"; //this.Btn_Del.OnClientClick = "return confirm('are you sure?')"; //this.Btn_Del.Click += new EventHandler(Btn_Del_Click); GenerWorkFlow gwf = new GenerWorkFlow(this.FID); WorkFlow wf = new WorkFlow(this.FK_Flow, this.FID); WorkNode wn = new WorkNode(this.FID, gwf.FK_Node); WorkNode wnPri = wn.GetPreviousWorkNode_FHL(this.WorkID); // 他的上一个节点. BP.WF.Node ndPri = wnPri.HisNode; try { //根据不同的表单类型展示不同的表单. if (ndPri.HisFormType == NodeFormType.FixForm) { this.UCEn1.BindColumn4(wnPri.HisWork, "ND" + wnPri.HisNode.NodeID); this.UCEn1.Add(wnPri.HisWork.WorkEndInfo); } else if (ndPri.HisFormType == NodeFormType.FreeForm) { this.UCEn1.BindCCForm(wnPri.HisWork, "ND" + wnPri.HisNode.NodeID, true, 0, false); } else if (ndPri.HisFormType == NodeFormType.SDKForm) { string url = "&FK_Flow=" + this.FK_Flow + "&FK_Node=" + ndPri.NodeID + "&WorkID=" + this.WorkID + "&FID=" + this.FID; string src = ndPri.FormUrl; if (src.Contains("?")) { src = src + "&IsReadonly=1&FK" + url; } else { src = src + "?1=2&IsReadonly=1" + url; } this.Add("<iframe ID='Ff' src='" + src + "' frameborder=0 style='width:100%; height:900px;text-align: left;' leftMargin='0' topMargin='0' scrolling=auto />"); this.Add("</iframe>"); } } catch { this.WinCloseWithMsg("此工作已经终止或者被删除。"); } }
/// <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); }
public void InitNodeIsCurr() { // 获取. Node nd = new Node(this.CurrNodeIDOfFlow); if (nd.IsStartNode) { /* 开始节点允许删除流程 */ this.Btn_DelFlow = true; this.Btn_Send = true; this.Btn_Save = true; return; } #region 判断是否可以撤销发送. WorkNode wn = new WorkNode(this.WorkID, this.CurrNodeIDOfFlow); WorkNode wnPri = wn.GetPreviousWorkNode(); // 判断它是否可以处理上一步工作. GenerWorkerList wl = new GenerWorkerList(); int num = wl.Retrieve(GenerWorkerListAttr.FK_Emp, Web.WebUser.No, GenerWorkerListAttr.FK_Node, wnPri.HisNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID); if (num >= 1) { /*如果能够处理上一步工作*/ } else { /*不能处理上一步工作, 就可以让其退回*/ this.Btn_Return = nd.IsCanReturn; this.Btn_Send = true; this.Btn_Save = true; } #endregion }
public void DoSend() { // 以下代码是从 MyFlow.aspx Send 方法copy 过来的,需要保持业务逻辑的一致性,所以代码需要保持一致. BP.WF.Node nd = new BP.WF.Node(this.FK_Node); Work wk = nd.HisWork; wk.OID = this.WorkID; wk.Retrieve(); WorkNode firstwn = new WorkNode(wk, nd); string msg = ""; try { msg = firstwn.NodeSend().ToMsgOfHtml(); } catch (Exception exSend) { this.Pub1.AddFieldSetGreen("错误"); this.Pub1.Add(exSend.Message.Replace("@@", "@").Replace("@", "<BR>@")); this.Pub1.AddFieldSetEnd(); return; } #region 处理通用的发送成功后的业务逻辑方法,此方法可能会抛出异常. try { //处理通用的发送成功后的业务逻辑方法,此方法可能会抛出异常. BP.WF.Glo.DealBuinessAfterSendWork(this.FK_Flow, this.WorkID, this.DoFunc, WorkIDs); } catch (Exception ex) { this.ToMsg(msg, ex.Message); return; } #endregion 处理通用的发送成功后的业务逻辑方法,此方法可能会抛出异常. /*处理转向问题.*/ switch (firstwn.HisNode.HisTurnToDeal) { case TurnToDeal.SpecUrl: string myurl = firstwn.HisNode.TurnToDealDoc.Clone().ToString(); if (myurl.Contains("?") == false) { myurl += "?1=1"; } Attrs myattrs = firstwn.HisWork.EnMap.Attrs; Work hisWK = firstwn.HisWork; foreach (Attr attr in myattrs) { if (myurl.Contains("@") == false) { break; } myurl = myurl.Replace("@" + attr.Key, hisWK.GetValStrByKey(attr.Key)); } if (myurl.Contains("@")) { throw new Exception("流程设计错误,在节点转向url中参数没有被替换下来。Url:" + myurl); } myurl += "&FromFlow=" + this.FK_Flow + "&FromNode=" + this.FK_Node + "&PWorkID=" + this.WorkID + "&UserNo=" + WebUser.No + "&SID=" + WebUser.SID; this.Response.Redirect(myurl, true); return; case TurnToDeal.TurnToByCond: TurnTos tts = new TurnTos(this.FK_Flow); if (tts.Count == 0) { throw new Exception("@您没有设置节点完成后的转向条件。"); } foreach (TurnTo tt in tts) { tt.HisWork = firstwn.HisWork; if (tt.IsPassed == true) { string url = tt.TurnToURL.Clone().ToString(); if (url.Contains("?s") == false) { url += "?1=1"; } Attrs attrs = firstwn.HisWork.EnMap.Attrs; Work hisWK1 = firstwn.HisWork; foreach (Attr attr in attrs) { if (url.Contains("@") == false) { break; } url = url.Replace("@" + attr.Key, hisWK1.GetValStrByKey(attr.Key)); } if (url.Contains("@")) { throw new Exception("流程设计错误,在节点转向url中参数没有被替换下来。Url:" + url); } url += "&PFlowNo=" + this.FK_Flow + "&FromNode=" + this.FK_Node + "&PWorkID=" + this.WorkID + "&UserNo=" + WebUser.No + "&SID=" + WebUser.SID; this.Response.Redirect(url, true); return; } } #warning 为上海修改了如果找不到路径就让它按系统的信息提示。 this.ToMsg(msg, "info"); //throw new Exception("您定义的转向条件不成立,没有出口。"); break; default: this.ToMsg(msg, "info"); break; } return; }
/// <summary> /// 自动计算未来处理人(该方法在发送成功后执行.) /// </summary> /// <param name="CurrWorkNode">当前的节点</param> /// <param name="nd"></param> /// <param name="toND"></param> public FullSA(WorkNode currWorkNode) { //如果当前不需要计算未来处理人. if (currWorkNode.HisFlow.IsFullSA == false && currWorkNode.IsSkip == false) { return; } //如果到达最后一个节点,就不处理了。 if (currWorkNode.HisNode.IsEndNode) { return; } //初始化一些变量. this.HisCurrWorkNode = currWorkNode; Node currND = currWorkNode.HisNode; Int64 workid = currWorkNode.HisWork.OID; //查询出来所有的节点. Nodes nds = new Nodes(this.HisCurrWorkNode.HisFlow.No); // 开始节点需要特殊处理》 /* 如果启用了要计算未来的处理人 */ SelectAccper sa = new SelectAccper(); //首先要清除以前的计算,重新计算。 sa.Delete(SelectAccperAttr.WorkID, workid); //求出已经路过的节点. DataTable dt = DBAccess.RunSQLReturnTable("SELECT FK_Node FROM WF_GenerWorkerList WHERE WorkID=" + BP.Sys.SystemConfig.AppCenterDBVarStr + "WorkID", "WorkID", workid); string passedNodeIDs = ""; foreach (DataRow item in dt.Rows) { passedNodeIDs += item[0].ToString() + ","; } //遍历当前的节点。 foreach (Node item in nds) { if (item.IsStartNode == true) { continue; } //如果已经包含了,就说明该节点已经经过了,就不处理了。 if (passedNodeIDs.Contains(item.NodeID + ",") == true) { continue; } //如果按照岗位计算(默认的第一个规则.) if (item.HisDeliveryWay == DeliveryWay.ByStation) { string sql = "SELECT No, Name FROM Port_Emp WHERE No IN (SELECT A.FK_Emp FROM " + BP.WF.Glo.EmpStation + " A, WF_NodeStation B WHERE A.FK_Station=B.FK_Station AND B.FK_Node=" + item.NodeID + ")"; dt = BP.DA.DBAccess.RunSQLReturnTable(sql); if (dt.Rows.Count != 1) { continue; } string no = dt.Rows[0][0].ToString(); string name = dt.Rows[0][1].ToString(); // sa.Delete(SelectAccperAttr.FK_Node,item.NodeID, SelectAccperAttr.WorkID, workid); //删除已经存在的数据. sa.FK_Emp = no; sa.EmpName = name; sa.FK_Node = item.NodeID; sa.WorkID = workid; sa.Info = "无"; sa.AccType = 0; sa.ResetPK(); if (sa.IsExits) { continue; } //计算接受任务时间与应该完成任务时间. InitDT(sa, item); sa.Insert(); continue; } //处理与指定节点相同的人员. if (item.HisDeliveryWay == DeliveryWay.BySpecNodeEmp && item.DeliveryParas == currND.NodeID.ToString()) { sa.FK_Emp = WebUser.No; sa.FK_Node = item.NodeID; sa.WorkID = workid; sa.Info = "无"; sa.AccType = 0; sa.EmpName = WebUser.Name; sa.ResetPK(); if (sa.IsExits) { continue; } //计算接受任务时间与应该完成任务时间. InitDT(sa, item); sa.Insert(); continue; } //处理绑定的节点人员.. if (item.HisDeliveryWay == DeliveryWay.ByBindEmp) { NodeEmps nes = new NodeEmps(); nes.Retrieve(NodeEmpAttr.FK_Node, item.NodeID); foreach (NodeEmp ne in nes) { sa.FK_Emp = ne.FK_Emp; sa.FK_Node = item.NodeID; sa.WorkID = workid; sa.Info = "无"; sa.AccType = 0; sa.EmpName = ne.FK_EmpT; sa.ResetPK(); if (sa.IsExits) { continue; } //计算接受任务时间与应该完成任务时间. InitDT(sa, item); sa.Insert(); } } //按照节点的 岗位与部门的交集计算. #region 部门与岗位的交集计算. if (item.HisDeliveryWay == DeliveryWay.ByDeptAndStation) { string dbStr = BP.Sys.SystemConfig.AppCenterDBVarStr; string sql = string.Empty; //added by liuxc,2015.6.30. //区别集成与BPM模式 if (BP.WF.Glo.OSModel == BP.Sys.OSModel.OneOne) { sql = "SELECT No FROM Port_Emp WHERE No IN "; sql += "(SELECT No as FK_Emp FROM Port_Emp WHERE FK_Dept IN "; sql += "( SELECT FK_Dept FROM WF_NodeDept WHERE FK_Node=" + dbStr + "FK_Node1)"; sql += ")"; sql += "AND No IN "; sql += "("; sql += "SELECT FK_Emp FROM " + BP.WF.Glo.EmpStation + " WHERE FK_Station IN "; sql += "( SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + dbStr + "FK_Node1 )"; sql += ") ORDER BY No "; Paras ps = new Paras(); ps.Add("FK_Node1", item.NodeID); ps.Add("FK_Node2", item.NodeID); ps.SQL = sql; dt = DBAccess.RunSQLReturnTable(ps); } else { sql = "SELECT pdes.FK_Emp AS No" + " FROM Port_DeptEmpStation pdes" + " INNER JOIN WF_NodeDept wnd" + " ON wnd.FK_Dept = pdes.FK_Dept" + " AND wnd.FK_Node = " + item.NodeID + " INNER JOIN WF_NodeStation wns" + " ON wns.FK_Station = pdes.FK_Station" + " AND wnd.FK_Node =" + item.NodeID + " ORDER BY" + " pdes.FK_Emp"; dt = DBAccess.RunSQLReturnTable(sql); } foreach (DataRow dr in dt.Rows) { Emp emp = new Emp(dr[0].ToString()); sa.FK_Emp = emp.No; sa.FK_Node = item.NodeID; sa.DeptName = emp.FK_DeptText; sa.WorkID = workid; sa.Info = "无"; sa.AccType = 0; sa.EmpName = emp.Name; sa.ResetPK(); if (sa.IsExits) { continue; } //计算接受任务时间与应该完成任务时间. InitDT(sa, item); sa.Insert(); } } #endregion 部门与岗位的交集计算. } //预制当前节点到达节点的数据。 Nodes toNDs = currND.HisToNodes; foreach (Node item in toNDs) { if (item.HisDeliveryWay == DeliveryWay.ByStation || item.HisDeliveryWay == DeliveryWay.FindSpecDeptEmpsInStationlist) { /*如果按照岗位访问*/ #region 最后判断 - 按照岗位来执行。 string dbStr = BP.Sys.SystemConfig.AppCenterDBVarStr; string sql = ""; Paras ps = new Paras(); /* 如果执行节点 与 接受节点岗位集合不一致 */ /* 没有查询到的情况下, 先按照本部门计算。*/ if (this.HisCurrWorkNode.HisFlow.FlowAppType == FlowAppType.Normal) { switch (BP.Sys.SystemConfig.AppCenterDBType) { case DBType.MySQL: case DBType.MSSQL: if (Glo.OSModel == Sys.OSModel.OneOne) { sql = "select x.No from Port_Emp x inner join (select FK_Emp from " + BP.WF.Glo.EmpStation + " a inner join WF_NodeStation b "; sql += " on a.FK_Station=b.FK_Station where FK_Node=" + dbStr + "FK_Node) as y on x.No=y.FK_Emp inner join Port_Emp z on"; sql += " x.No=z.No where z.FK_Dept =" + dbStr + "FK_Dept order by x.No"; } else { sql = "select x.No from Port_Emp x inner join (select FK_Emp from " + BP.WF.Glo.EmpStation + " a inner join WF_NodeStation b "; sql += " on a.FK_Station=b.FK_Station where FK_Node=" + dbStr + "FK_Node) as y on x.No=y.FK_Emp inner join Port_DeptEmp z on"; sql += " x.No=z.FK_Emp where z.FK_Dept =" + dbStr + "FK_Dept order by x.No"; } break; default: if (Glo.OSModel == Sys.OSModel.OneOne) { sql = "SELECT No FROM Port_Emp WHERE NO IN " + "(SELECT FK_Emp FROM " + BP.WF.Glo.EmpStation + " WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + dbStr + "FK_Node) )" + " AND NO IN " + "(SELECT No as FK_Emp FROM Port_Emp WHERE FK_Dept =" + dbStr + "FK_Dept)"; sql += " ORDER BY No "; } else { sql = "SELECT No FROM Port_Emp WHERE NO IN " + "(SELECT FK_Emp FROM " + BP.WF.Glo.EmpStation + " WHERE FK_Station IN (SELECT FK_Station FROM WF_NodeStation WHERE FK_Node=" + dbStr + "FK_Node) )" + " AND NO IN " + "(SELECT FK_Emp FROM Port_DeptEmp WHERE FK_Dept =" + dbStr + "FK_Dept)"; sql += " ORDER BY No "; } break; } ps = new Paras(); ps.SQL = sql; ps.Add("FK_Node", item.NodeID); ps.Add("FK_Dept", WebUser.FK_Dept); } dt = DBAccess.RunSQLReturnTable(ps); foreach (DataRow dr in dt.Rows) { Emp emp = new Emp(dr[0].ToString()); sa.FK_Emp = emp.No; sa.FK_Node = item.NodeID; sa.DeptName = emp.FK_DeptText; sa.WorkID = workid; sa.Info = "无"; sa.AccType = 0; sa.EmpName = emp.Name; sa.ResetPK(); if (sa.IsExits) { continue; } //计算接受任务时间与应该完成任务时间. InitDT(sa, item); sa.Insert(); } #endregion 照岗位来执行。 } } }
void btn_Click(object sender, EventArgs e) { Button btn = (Button)sender; if (btn.ID == "Btn_Cancel") { string url = "../MyFlow.aspx?FK_Flow=" + this.FK_Flow + "&FK_Node=" + this.FK_Node + "&WorkID=" + this.WorkID + "&FID=" + this.FID; this.Response.Redirect(url, true); return; } #region 计算出来到达的节点. //获得当前节点到达的节点. Nodes nds = new Nodes(); if (this.ToNodes != null) { /*解决跳转问题.*/ string[] mytoNodes = this.ToNodes.Split(','); foreach (string str in mytoNodes) { if (string.IsNullOrEmpty(str) == true) { continue; } nds.AddEntity(new Node(int.Parse(str))); } } else { nds = BP.WF.Dev2Interface.WorkOpt_GetToNodes(this.FK_Flow, this.FK_Node, this.WorkID, this.FID); } // 首先到非异表单去找. string toNodes = ""; foreach (Node mynd in nds) { if (mynd.HisRunModel == RunModel.SubThread && mynd.HisSubThreadType == SubThreadType.UnSameSheet) { continue; //如果是子线程节点. } if (mynd.NodeID == 0) { continue; } BP.Web.Controls.RadioBtn rb = this.Pub1.GetRadioBtnByID("RB_" + mynd.NodeID); if (rb.Checked == false) { continue; } toNodes = mynd.NodeID.ToString(); break; } if (toNodes == "") { // 如果在非异表单没有找到,就到异表单集合去找。 检查是否具有异表单的子线程. bool isHave = false; foreach (Node mynd in nds) { if (mynd.NodeID == 0) { isHave = true; } } if (isHave) { /*增加异表单的子线程*/ foreach (Node mynd in nds) { if (mynd.HisSubThreadType != SubThreadType.UnSameSheet) { continue; } CheckBox cb = this.Pub1.GetCBByID("CB_" + mynd.NodeID); if (cb == null) { continue; } if (cb.Checked == true) { toNodes += "," + mynd.NodeID; } } } } #endregion 计算出来选择的到达节点. if (toNodes == "") { this.Pub1.AddFieldSetRed("发送出现错误", "您没有选择到达的节点。"); return; } // 执行发送. string msg = ""; Node nd = new Node(this.FK_Node); Work wk = nd.HisWork; wk.OID = this.WorkID; wk.Retrieve(); try { string toNodeStr = int.Parse(FK_Flow) + "01"; //如果为开始节点 if (toNodeStr == toNodes) { //把参数更新到数据库里面. GenerWorkFlow gwf = new GenerWorkFlow(); gwf.WorkID = this.WorkID; gwf.RetrieveFromDBSources(); gwf.Paras_ToNodes = toNodes; gwf.Save(); WorkNode firstwn = new WorkNode(wk, nd); Node toNode = new Node(toNodeStr); msg = firstwn.NodeSend(toNode, gwf.Starter).ToMsgOfHtml(); } else { msg = BP.WF.Dev2Interface.WorkOpt_SendToNodes(this.FK_Flow, this.FK_Node, this.WorkID, this.FID, toNodes).ToMsgOfHtml(); } } catch (Exception ex) { this.Pub1.AddFieldSetRed("发送出现错误", ex.Message); return; } #region 处理通用的发送成功后的业务逻辑方法,此方法可能会抛出异常. try { //处理通用的发送成功后的业务逻辑方法,此方法可能会抛出异常. Glo.DealBuinessAfterSendWork(this.FK_Flow, this.WorkID, this.DoFunc, WorkIDs, this.CFlowNo, 0, null); } catch (Exception ex) { this.ToMsg(msg, ex.Message); return; } #endregion 处理通用的发送成功后的业务逻辑方法,此方法可能会抛出异常. /*处理转向问题.*/ switch (nd.HisTurnToDeal) { case TurnToDeal.SpecUrl: string myurl = nd.TurnToDealDoc.Clone().ToString(); if (myurl.Contains("&") == false) { myurl += "?1=1"; } myurl = BP.WF.Glo.DealExp(myurl, wk, null); myurl += "&FromFlow=" + this.FK_Flow + "&FromNode=" + this.FK_Node + "&PWorkID=" + this.WorkID + "&UserNo=" + WebUser.No + "&SID=" + WebUser.SID; this.Response.Redirect(myurl, true); return; case TurnToDeal.TurnToByCond: TurnTos tts = new TurnTos(this.FK_Flow); if (tts.Count == 0) { throw new Exception("@您没有设置节点完成后的转向条件。"); } foreach (TurnTo tt in tts) { tt.HisWork = wk; if (tt.IsPassed == true) { string url = tt.TurnToURL.Clone().ToString(); if (url.Contains("&") == false) { url += "?1=1"; } url = BP.WF.Glo.DealExp(url, wk, null); url += "&PFlowNo=" + this.FK_Flow + "&FromNode=" + this.FK_Node + "&PWorkID=" + this.WorkID + "&UserNo=" + WebUser.No + "&SID=" + WebUser.SID; this.Response.Redirect(url, true); return; } } #warning 为上海修改了如果找不到路径就让它按系统的信息提示。 this.ToMsg(msg, "info"); //throw new Exception("您定义的转向条件不成立,没有出口。"); break; default: this.ToMsg(msg, "info"); break; } return; }
/// <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> /// <returns>返回执行结果</returns> public override object Do() { #region 找到要逾期的数据. DataTable generTab = null; string sql = "SELECT a.FK_Flow,a.WorkID,a.Title,a.FK_Node,a.SDTOfNode,a.Starter,a.TodoEmps "; sql += "FROM WF_GenerWorkFlow a, WF_Node b"; sql += " WHERE a.SDTOfNode<='" + DataType.CurrentDataTime + "' "; sql += " AND WFState=2 and b.OutTimeDeal!=0"; sql += " AND a.FK_Node=b.NodeID"; generTab = DBAccess.RunSQLReturnTable(sql); #endregion 找到要逾期的数据. // 遍历循环,逾期表进行处理. string msg = ""; string info = ""; foreach (DataRow row in generTab.Rows) { string fk_flow = row["FK_Flow"] + ""; int fk_node = int.Parse(row["FK_Node"] + ""); long workid = long.Parse(row["WorkID"] + ""); string title = row["Title"] + ""; string compleateTime = row["SDTOfNode"] + ""; string starter = row["Starter"] + ""; GenerWorkerLists gwls = new GenerWorkerLists(); gwls.Retrieve(GenerWorkerListAttr.WorkID, workid, GenerWorkerListAttr.FK_Node, fk_node); bool isLogin = false; foreach (GenerWorkerList item in gwls) { if (item.IsEnable == false) { continue; } BP.Port.Emp emp = new Emp(item.FK_Emp); BP.Web.WebUser.SignInOfGener(emp); isLogin = true; } if (isLogin == false) { BP.Port.Emp emp = new Emp("admin"); BP.Web.WebUser.SignInOfGener(emp); } try { Node node = new Node(fk_node); if (node.IsStartNode) { continue; } //获得该节点的处理内容. string doOutTime = node.GetValStrByKey(NodeAttr.DoOutTime); switch (node.HisOutTimeDeal) { case OutTimeDeal.None: //逾期不处理. continue; case OutTimeDeal.AutoJumpToSpecNode: //跳转到指定的节点. try { //if (doOutTime.Contains(",") == false) // throw new Exception("@系统设置错误,不符合设置规范,格式为: NodeID,EmpNo 现在设置的为:"+doOutTime); int jumpNode = int.Parse(doOutTime); Node jumpToNode = new Node(jumpNode); //设置默认同意. BP.WF.Dev2Interface.WriteTrackWorkCheck(jumpToNode.FK_Flow, node.NodeID, workid, 0, "同意(预期自动审批)", null); //执行发送. info = BP.WF.Dev2Interface.Node_SendWork(fk_flow, workid, null, null, jumpToNode.NodeID, null).ToMsgOfText(); // info = BP.WF.Dev2Interface.Flow_Schedule(workid, jumpToNode.NodeID, emp.No); msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'自动跳转'," + info; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); } catch (Exception ex) { msg = "流程 '" + node.FlowName + "',WorkID=" + workid + ",标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'自动跳转',跳转异常:" + ex.Message; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); } break; case OutTimeDeal.AutoShiftToSpecUser: //走动移交给. // 判断当前的处理人是否是. Emp empShift = new Emp(doOutTime); try { BP.WF.Dev2Interface.Node_Shift(fk_flow, fk_node, workid, 0, empShift.No, "流程节点已经逾期,系统自动移交"); msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'移交到指定的人',已经自动移交给'" + empShift.Name + "."; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); } catch (Exception ex) { msg = "流程 '" + node.FlowName + "' ,标题:'" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'移交到指定的人',移交异常:" + ex.Message; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); } break; case OutTimeDeal.AutoTurntoNextStep: try { GenerWorkerList workerList = new GenerWorkerList(); workerList.RetrieveByAttrAnd(GenerWorkerListAttr.WorkID, workid, GenerWorkFlowAttr.FK_Node, fk_node); BP.Web.WebUser.SignInOfGener(workerList.HisEmp); WorkNode firstwn = new WorkNode(workid, fk_node); string sendIfo = firstwn.NodeSend().ToMsgOfText(); msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'自动发送到下一节点',发送消息为:" + sendIfo; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); } catch (Exception ex) { msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'自动发送到下一节点',发送异常:" + ex.Message; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); } break; case OutTimeDeal.DeleteFlow: info = BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(fk_flow, workid, true); msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'删除流程'," + info; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); break; case OutTimeDeal.RunSQL: try { BP.WF.Work wk = node.HisWork; wk.OID = workid; wk.Retrieve(); doOutTime = BP.WF.Glo.DealExp(doOutTime, wk, null); //替换字符串 doOutTime.Replace("@OID", workid + ""); doOutTime.Replace("@FK_Flow", fk_flow); doOutTime.Replace("@FK_Node", fk_node.ToString()); doOutTime.Replace("@Starter", starter); if (doOutTime.Contains("@")) { msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'执行SQL'.有未替换的SQL变量."; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); break; } //执行sql. DBAccess.RunSQL(doOutTime); } catch (Exception ex) { msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'执行SQL'.运行SQL出现异常:" + ex.Message; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); } break; case OutTimeDeal.SendMsgToSpecUser: try { Emp myemp = new Emp(doOutTime); bool boo = BP.WF.Dev2Interface.WriteToSMS(myemp.No, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "系统发送逾期消息", "您的流程:'" + title + "'的完成时间应该为'" + compleateTime + "',流程已经逾期,请及时处理!", "系统消息"); if (boo) { msg = "'" + title + "'逾期消息已经发送给:'" + myemp.Name + "'"; } else { msg = "'" + title + "'逾期消息发送未成功,发送人为:'" + myemp.Name + "'"; } SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); } catch (Exception ex) { msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'执行SQL'.运行SQL出现异常:" + ex.Message; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); } break; default: msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'没有找到相应的超时处理规则."; SetText(msg); BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); break; } } catch (Exception ex) { SetText("流程逾期出现异常:" + ex.Message); BP.DA.Log.DefaultLogWriteLine(LogType.Error, ex.ToString()); } } return(generInfo); }
/// <summary> /// 执行自动启动流程任务 WF_Task /// </summary> public void DoTask() { string sql = "SELECT * FROM WF_Task WHERE TaskSta=0 ORDER BY Starter"; DataTable dt = null; try { dt = DBAccess.RunSQLReturnTable(sql); } catch { Task ta = new Task(); ta.CheckPhysicsTable(); dt = DBAccess.RunSQLReturnTable(sql); } if (dt.Rows.Count == 0) { return; } #region 自动启动流程 foreach (DataRow dr in dt.Rows) { string mypk = dr["MyPK"].ToString(); string taskSta = dr["TaskSta"].ToString(); string paras = dr["Paras"].ToString(); string starter = dr["Starter"].ToString(); string fk_flow = dr["FK_Flow"].ToString(); string startDT = dr[TaskAttr.StartDT].ToString(); if (string.IsNullOrEmpty(startDT) == false) { /*如果设置了发起时间,就检查当前时间是否与现在的时间匹配.*/ if (DateTime.Now.ToString("yyyy-MM-dd HH:mm").Contains(startDT) == false) { continue; } } Flow fl = new Flow(fk_flow); this.SetText("开始执行(" + starter + ")发起(" + fl.Name + ")流程."); try { string fTable = "ND" + int.Parse(fl.No + "01").ToString(); MapData md = new MapData(fTable); sql = ""; // sql = "SELECT * FROM " + md.PTable + " WHERE MainPK='" + mypk + "' AND WFState=1"; try { if (DBAccess.RunSQLReturnTable(sql).Rows.Count != 0) { continue; } } catch { this.SetText("开始节点表单表:" + fTable + "没有设置的默认字段MainPK. " + sql); continue; } if (BP.Web.WebUser.No != starter) { BP.Web.WebUser.Exit(); BP.Port.Emp empadmin = new BP.Port.Emp(starter); BP.Web.WebUser.SignInOfGener(empadmin); } Work wk = fl.NewWork(); string[] strs = paras.Split('@'); foreach (string str in strs) { if (string.IsNullOrEmpty(str)) { continue; } if (str.Contains("=") == false) { continue; } string[] kv = str.Split('='); wk.SetValByKey(kv[0], kv[1]); } wk.SetValByKey("MainPK", mypk); wk.Update(); WorkNode wn = new WorkNode(wk, fl.HisStartNode); string msg = wn.NodeSend().ToMsgOfText(); msg = msg.Replace("'", "~"); DBAccess.RunSQL("UPDATE WF_Task SET TaskSta=1,Msg='" + msg + "' WHERE MyPK='" + mypk + "'"); } catch (Exception ex) { //如果发送错误。 this.SetText(ex.Message); string msg = ex.Message; try { DBAccess.RunSQL("UPDATE WF_Task SET TaskSta=2,Msg='" + msg + "' WHERE MyPK='" + mypk + "'"); } catch { Task TK = new Task(); TK.CheckPhysicsTable(); } } } #endregion 自动启动流程 }
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> /// <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("@撤消执行成功."); } }
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> /// <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); } }
protected void Page_Load(object sender, EventArgs e) { #region 找到可以退回的节点. DataTable dt = null; if (this.IsPostBack == false) { dt = BP.WF.Dev2Interface.DB_GenerWillReturnNodes(this.FK_Node, this.WorkID, this.FID); if (dt.Rows.Count == 0) { this.Pub1.Clear(); this.Pub1.AddFieldSet("退回错误", "系统没有找到可以退回的节点."); return; } } #endregion 找到可以退回的节点. this.Page.Title = "工作退回"; BP.WF.Node nd = new BP.WF.Node(this.FK_Node); this.ToolBar1.Add("<b>退回到:</b>"); this.ToolBar1.AddDDL("DDL1"); this.DDL1.Attributes["onchange"] = "OnChange(this);"; this.ToolBar1.AddBtn("Btn_OK", "确定"); this.ToolBar1.GetBtnByID("Btn_OK").Attributes["onclick"] = " return confirm('您确定要执行吗?');"; this.ToolBar1.GetBtnByID("Btn_OK").Click += new EventHandler(ReturnWork_Click); // if (this.Request.QueryString["IsEUI"] == null) //{ this.ToolBar1.AddBtn("Btn_Cancel", "取消"); this.ToolBar1.GetBtnByID("Btn_Cancel").Click += new EventHandler(ReturnWork_Click); //} string appPath = this.Request.ApplicationPath; if (nd.IsBackTracking) { /*如果允许原路退回*/ CheckBox cb = new CheckBox(); cb.ID = "CB_IsBackTracking"; cb.Text = "退回后是否要原路返回?"; this.ToolBar1.Add(cb); } TextBox tb = new TextBox(); tb.TextMode = TextBoxMode.MultiLine; tb.ID = "TB_Doc"; tb.Rows = 12; tb.Columns = 60; this.Pub1.Add(tb); //新增 this.Pub1.Add("<div style='float:left;display:block;width:100%'><a href=javascript:TBHelp('Return_Doc','" + "ND" + FK_Node + "'" + ")><img src='" + BP.WF.Glo.CCFlowAppPath + "WF/Img/Emps.gif' align='middle' border=0 />选择词汇</a> </div>"); if (this.IsPostBack == false) { foreach (DataRow dr in dt.Rows) { this.DDL1.Items.Add(new ListItem(dr["RecName"] + "=>" + dr["Name"].ToString(), dr["No"].ToString() + "@" + dr["Rec"].ToString())); } WorkNode wn = new WorkNode(this.WorkID, this.FK_Node); WorkNode pwn = wn.GetPreviousWorkNode(); this.DDL1.SetSelectItem(pwn.HisNode.NodeID); this.DDL1.Enabled = true; Work wk = pwn.HisWork; if (this.Info != null) { this.TB1.Text = this.Info; //不能把审核信息保存到表单里,因为下次他的审核就不是这个信息了. //string sql = "UPDATE "+wn.HisWork.EnMap.PhysicsTable+" SET "+; } else { /*检查是否启用了审核组件,看看审核信息里填写了什么?*/ BP.Sys.FrmWorkCheck fwc = new FrmWorkCheck(this.FK_Node); if (fwc.HisFrmWorkCheckSta == FrmWorkCheckSta.Enable) { this.TB1.Text = BP.WF.Dev2Interface.GetCheckInfo(this.FK_Flow, this.WorkID, this.FK_Node); if (tb.Text == "同意") { tb.Text = ""; } } else { string info = this.DDL1.SelectedItem.Text; string recName = info.Substring(0, info.IndexOf('=')); string nodeName = info.Substring(info.IndexOf('>') + 1); this.TB1.Text = string.Format("{0}同志: \n 您处理的“{1}”工作有错误,需要您重新办理.\n\n此致!!! \n\n {2}", recName, nodeName, WebUser.Name + "\n " + BP.DA.DataType.CurrentDataTime); } } } }
/// <summary> /// 特殊处理天津的流程 /// 当指定的节点,到了10号,15号自动向下发送. /// </summary> private void DoTianJinSpecFunc() { if (DateTime.Now.Day == 10 || DateTime.Now.Day == 15) { /* 一个是10号自动审批,一个是15号自动审批. */ } else { return; } #region 找到要逾期的数据. DataTable generTab = null; string sql = "SELECT a.FK_Flow,a.WorkID,a.Title,a.FK_Node,a.SDTOfNode,a.Starter,a.TodoEmps "; sql += "FROM WF_GenerWorkFlow a, WF_Node b"; sql += " WHERE "; sql += " a.FK_Node=b.NodeID "; if (DateTime.Now.Day == 10) { sql += " AND b.NodeID=13304 "; } if (DateTime.Now.Day == 15) { sql += "AND b.NodeID=13302 "; } generTab = DBAccess.RunSQLReturnTable(sql); #endregion 找到要逾期的数据. // 遍历循环,逾期表进行处理. string msg = ""; foreach (DataRow row in generTab.Rows) { string fk_flow = row["FK_Flow"] + ""; string fk_node = row["FK_Node"] + ""; long workid = long.Parse(row["WorkID"] + ""); string title = row["Title"] + ""; string compleateTime = row["SDTOfNode"] + ""; string starter = row["Starter"] + ""; try { Node node = new Node(int.Parse(fk_node)); try { GenerWorkerList workerList = new GenerWorkerList(); workerList.RetrieveByAttrAnd(GenerWorkerListAttr.WorkID, workid, GenerWorkFlowAttr.FK_Node, fk_node); WebUser.SignInOfGener(workerList.HisEmp); WorkNode firstwn = new WorkNode(workid, int.Parse(fk_node)); string sendIfo = firstwn.NodeSend().ToMsgOfText(); msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'自动发送到下一节点',发送消息为:" + sendIfo; //输出消息. BP.DA.Log.DefaultLogWriteLine(LogType.Info, msg); } catch (Exception ex) { msg = "流程 '" + node.FlowName + "',标题: '" + title + "'的应该完成时间为'" + compleateTime + "',当前节点'" + node.Name + "'超时处理规则为'自动发送到下一节点',发送异常:" + ex.Message; BP.DA.Log.DefaultLogWriteLine(LogType.Error, msg); } } catch (Exception ex) { BP.DA.Log.DefaultLogWriteLine(LogType.Error, ex.ToString()); } } BP.DA.Log.DefaultLogWriteLine(LogType.Info, "结束扫描逾期流程数据."); }
/// <summary> /// 恢复已完成的流程数据到指定的节点,如果节点为0就恢复到最后一个完成的节点上去. /// </summary> /// <param name="workid">要恢复的workid</param> /// <param name="backToNodeID">恢复到的节点编号,如果是0,标示回复到流程最后一个节点上去.</param> /// <param name="note"></param> /// <returns></returns> public string DoRebackFlowData(Int64 workid, int backToNodeID, string note) { if (note.Length <= 2) { return("请填写恢复已完成的流程原因."); } Flow fl = new Flow(this.No); GERpt rpt = new GERpt("ND" + int.Parse(this.No) + "Rpt"); rpt.OID = workid; int i = rpt.RetrieveFromDBSources(); if (i == 0) { throw new Exception("@错误,流程数据丢失。"); } if (backToNodeID == 0) { backToNodeID = rpt.FlowEndNode; } Emp empStarter = new Emp(rpt.FlowStarter); // 最后一个节点. Node endN = new Node(backToNodeID); GenerWorkFlow gwf = null; try { #region 创建流程引擎主表数据. gwf = new GenerWorkFlow(); gwf.WorkID = workid; if (gwf.RetrieveFromDBSources() == 1) { throw new Exception("@当前工作ID为:" + workid + "的流程没有结束,不能采用此方法恢复。"); } gwf.FK_Flow = this.No; gwf.FlowName = this.Name; gwf.WorkID = workid; gwf.PWorkID = rpt.PWorkID; gwf.PFlowNo = rpt.PFlowNo; gwf.FK_Node = backToNodeID; gwf.NodeName = endN.Name; gwf.Starter = rpt.FlowStarter; gwf.StarterName = empStarter.Name; gwf.FK_FlowSort = fl.FK_FlowSort; gwf.Title = rpt.Title; gwf.WFState = WFState.ReturnSta; /*设置为退回的状态*/ gwf.FK_Dept = rpt.FK_Dept; Dept dept = new Dept(empStarter.FK_Dept); gwf.DeptName = dept.Name; gwf.PRI = 1; DateTime dttime = DateTime.Now; dttime = dttime.AddDays(3); gwf.SDTOfNode = dttime.ToString("yyyy-MM-dd"); gwf.SDTOfFlow = dttime.ToString("yyyy-MM-dd"); gwf.Insert(); /*插入流程引擎数据.*/ #endregion 创建流程引擎主表数据 int startNode = int.Parse(this.No + "01"); string ndTrack = "ND" + int.Parse(this.No) + "Track"; string actionType = (int)ActionType.Forward + "," + (int)ActionType.FlowOver + "," + (int)ActionType.ForwardFL + "," + (int)ActionType.ForwardHL; // string actionType = " NDFrom=" + (int)ActionType.Forward + " OR NDFrom=" + (int)ActionType.FlowOver + " OR NDFrom=" + (int)ActionType.ForwardFL + " OR NDFrom=" + (int)ActionType.ForwardHL; string sql = "SELECT * FROM " + ndTrack + " WHERE ActionType IN (" + actionType + ") and WorkID=" + workid + " ORDER BY RDT DESC, NDFrom "; System.Data.DataTable dt = DBAccess.RunSQLReturnTable(sql); if (dt.Rows.Count == 0) { throw new Exception("@工作ID为:" + workid + "的数据不存在."); } string starter = ""; bool isMeetSpecNode = false; GenerWorkerList currWl = new GenerWorkerList(); foreach (DataRow dr in dt.Rows) { int ndFrom = int.Parse(dr["NDFrom"].ToString()); Node nd = new Node(ndFrom); string ndFromT = dr["NDFromT"].ToString(); string EmpFrom = dr[TrackAttr.EmpFrom].ToString(); string EmpFromT = dr[TrackAttr.EmpFromT].ToString(); // 增加上 工作人员的信息. GenerWorkerList gwl = new GenerWorkerList(); gwl.WorkID = workid; gwl.FK_Flow = this.No; gwl.FK_Node = ndFrom; gwl.FK_NodeText = ndFromT; if (gwl.FK_Node == backToNodeID) { gwl.IsPass = false; currWl = gwl; } gwl.FK_Emp = EmpFrom; gwl.FK_EmpText = EmpFromT; if (gwl.IsExits) { continue; /*有可能是反复退回的情况.*/ } Emp emp = new Emp(gwl.FK_Emp); gwl.FK_Dept1 = emp.FK_Dept; gwl.RDT = dr["RDT"].ToString(); gwl.SDT = dr["RDT"].ToString(); gwl.DTOfWarning = gwf.SDTOfNode; gwl.WarningDays = nd.WarningDays; gwl.IsEnable = true; gwl.WhoExeIt = nd.WhoExeIt; gwl.Insert(); } #region 加入退回信息, 让接受人能够看到退回原因. ReturnWork rw = new ReturnWork(); rw.WorkID = workid; rw.ReturnNode = backToNodeID; rw.ReturnNodeName = endN.Name; rw.Returner = WebUser.No; rw.ReturnerName = WebUser.Name; rw.ReturnToNode = currWl.FK_Node; rw.ReturnToEmp = currWl.FK_Emp; rw.Note = note; rw.RDT = DataType.CurrentDataTime; rw.IsBackTracking = false; rw.MyPK = BP.DA.DBAccess.GenerGUID(); #endregion 加入退回信息, 让接受人能够看到退回原因. //更新流程表的状态. rpt.FlowEnder = currWl.FK_Emp; rpt.WFState = WFState.ReturnSta; /*设置为退回的状态*/ rpt.FlowEndNode = currWl.FK_Node; rpt.Update(); // 向接受人发送一条消息. BP.WF.Dev2Interface.Port_SendMail(currWl.FK_Emp, "工作恢复:" + gwf.Title, "工作被:" + WebUser.No + " 恢复." + note, "ReBack" + workid, this.No, int.Parse(this.No + "01"), workid, 0); //写入该日志. WorkNode wn = new WorkNode(workid, currWl.FK_Node); wn.AddToTrack(ActionType.RebackOverFlow, currWl.FK_Emp, currWl.FK_EmpText, currWl.FK_Node, currWl.FK_NodeText, note); return("@已经还原成功,现在的流程已经复原到(" + currWl.FK_NodeText + "). @当前工作处理人为(" + currWl.FK_Emp + " , " + currWl.FK_EmpText + ") @请通知他处理工作."); } catch (Exception ex) { gwf.Delete(); GenerWorkerList wl = new GenerWorkerList(); wl.Delete(GenerWorkerListAttr.WorkID, workid); string sqls = ""; sqls += "@UPDATE " + fl.PTable + " SET WFState=" + (int)WFState.Complete + " WHERE OID=" + workid; DBAccess.RunSQLs(sqls); return("<font color=red>会滚期间出现错误</font><hr>" + ex.Message); } }
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> /// 创建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) { //转化成编号. flowNo = TurnFlowMarkToFlowNo(flowNo); //转化成编号 parentFlowNo = TurnFlowMarkToFlowNo(parentFlowNo); string dbstr = SystemConfig.AppCenterDBVarStr; Flow fl = new Flow(flowNo); Node nd = new Node(fl.StartNodeID); Emp empStarter = new Emp(BP.Web.WebUser.No); //把一些其他的参数也增加里面去,传递给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); } 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 (string.IsNullOrEmpty(title) == false) { if (fl.TitleRole != "@OutPara") { fl.TitleRole = "@OutPara"; fl.Update(); } 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, WorkNode.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, parentFlowNo, parentWorkID, parentNodeID, parentEmp); } return(wk.OID); }
/// <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> /// 执行 /// </summary> /// <returns>返回执行结果</returns> public override object Do() { string info = ""; string sql = "SELECT * FROM WF_Task WHERE TaskSta=0 ORDER BY Starter"; DataTable dt = null; try { dt = DBAccess.RunSQLReturnTable(sql); } catch { Task ta = new Task(); ta.CheckPhysicsTable(); dt = DBAccess.RunSQLReturnTable(sql); } if (dt.Rows.Count == 0) { return("无任务"); } #region 自动启动流程 foreach (DataRow dr in dt.Rows) { string mypk = dr["MyPK"].ToString(); string taskSta = dr["TaskSta"].ToString(); string paras = dr["Paras"].ToString(); string starter = dr["Starter"].ToString(); string fk_flow = dr["FK_Flow"].ToString(); //获得到达的节点,与接受人。 string toEmps = dr["ToEmps"].ToString(); if (DataType.IsNullOrEmpty(toEmps)) { toEmps = null; } string toNodeStr = dr["ToNode"].ToString(); int toNodeID = 0; if (DataType.IsNullOrEmpty(toNodeStr) == false) { toNodeID = int.Parse(toNodeStr); } string startDT = dr[TaskAttr.StartDT].ToString(); if (string.IsNullOrEmpty(startDT) == false) { /*如果设置了发起时间,就检查当前时间是否与现在的时间匹配.*/ if (DateTime.Now < DateTime.Parse(startDT)) { continue; } } Flow fl = new Flow(fk_flow); if (fl.HisFlowAppType == FlowAppType.PRJ) { if (paras.Contains("PrjNo=") == false || paras.Contains("PrjName=") == false) { info += "err@工程类的流程,没有PrjNo,PrjName参数:" + fl.Name; DBAccess.RunSQL("UPDATE WF_Task SET TaskSta=2,Msg='" + info + "' WHERE MyPK='" + mypk + "'"); continue; } } Int64 workID = 0; try { string fTable = "ND" + int.Parse(fl.No + "01").ToString(); MapData md = new MapData(fTable); //sql = ""; sql = "SELECT * FROM " + md.PTable + " WHERE MainPK='" + mypk + "' AND WFState=1"; try { if (DBAccess.RunSQLReturnTable(sql).Rows.Count != 0) { continue; } } catch { info += "开始节点表单表:" + fTable + "没有设置的默认字段MainPK. " + sql; continue; } if (BP.Web.WebUser.No != starter) { BP.Web.WebUser.Exit(); BP.Port.Emp empadmin = new BP.Port.Emp(starter); BP.Web.WebUser.SignInOfGener(empadmin); } Work wk = fl.NewWork(); workID = wk.OID; string[] strs = paras.Split('@'); foreach (string str in strs) { if (string.IsNullOrEmpty(str)) { continue; } if (str.Contains("=") == false) { continue; } string[] kv = str.Split('='); wk.SetValByKey(kv[0], kv[1]); } wk.SetValByKey("MainPK", mypk); wk.Update(); if (fl.HisFlowAppType == FlowAppType.PRJ) { string prjNo = wk.GetValStrByKey("PrjNo"); if (DataType.IsNullOrEmpty(prjNo) == true) { info += "err@没有找到工程编号:MainPK" + mypk; DBAccess.RunSQL("UPDATE WF_Task SET TaskSta=2,Msg='" + info + "' WHERE MyPK='" + mypk + "'"); continue; } } WorkNode wn = new WorkNode(wk, fl.HisStartNode); string msg = ""; if (toNodeID == 0) { msg = wn.NodeSend(null, toEmps).ToMsgOfText(); } else { msg = wn.NodeSend(new Node(toNodeID), toEmps).ToMsgOfText(); } msg = msg.Replace("'", "~"); DBAccess.RunSQL("UPDATE WF_Task SET TaskSta=1,Msg='" + msg + "' WHERE MyPK='" + mypk + "'"); } catch (Exception ex) { //删除流程数据 if (workID != 0) { BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(fk_flow, workID); } //如果发送错误。 info += ex.Message; string msg = ex.Message; try { DBAccess.RunSQL("UPDATE WF_Task SET TaskSta=2,Msg='" + msg + "' WHERE MyPK='" + mypk + "'"); } catch { Task TK = new Task(); TK.CheckPhysicsTable(); } } } #endregion 自动启动流程 return(info); }
/// <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> /// 检查节点是否是启用接收人选择器 /// </summary> /// <returns></returns> private string CheckAccepterOper() { int tempToNodeID = 0; //获取到当前节点 Node _HisNode = new Node(this.FK_Node); /*如果到达的点为空 */ Nodes nds = _HisNode.HisToNodes; if (nds.Count == 0) { //当前点是最后的一个节点,不能使用此功能 return("end"); } else if (nds.Count == 1) { BP.WF.Node toND = nds[0] as BP.WF.Node; tempToNodeID = toND.NodeID; } else { foreach (BP.WF.Node mynd in nds) { //if (mynd.HisDeliveryWay != DeliveryWay.BySelected) // continue; GERpt _wk = _HisNode.HisFlow.HisGERpt; _wk.OID = this.WorkID; _wk.Retrieve(); _wk.ResetDefaultVal(); #region 过滤不能到达的节点. Cond cond = new Cond(); int i = cond.Retrieve(CondAttr.FK_Node, _HisNode.NodeID, CondAttr.ToNodeID, mynd.NodeID); if (i == 0) { continue; // 没有设置方向条件,就让它跳过去。 } cond.WorkID = this.WorkID; cond.en = _wk; if (cond.IsPassed == false) { continue; } #endregion 过滤不能到达的节点. tempToNodeID = mynd.NodeID; } } //不存在下一个节点,检查是否配置了有用户选择节点 if (tempToNodeID == 0) { try { //检查必填项 BP.WF.WorkNode workeNode = new WorkNode(this.WorkID, this.FK_Node); workeNode.CheckFrmIsNotNull(); } catch (Exception ex) { return("error:" + ex.Message); } //按照用户选择计算 if (_HisNode.CondModel == CondModel.ByUserSelected) { return("byuserselected"); } return("notonode"); } //判断到达的节点是否是按接受人选择 Node toNode = new Node(tempToNodeID); if (toNode.HisDeliveryWay == DeliveryWay.BySelected) { return("byselected"); } return("nodata"); }
/// <summary> /// 构造 /// </summary> /// <param name="wn"></param> public CCWork(WorkNode wn) { this.HisWorkNode = wn; AutoCC(); CCByEmps(); }
public void DTS_Flow(BP.WF.Flow fl) { #region 读取数据. BP.Sys.MapExt me = new MapExt(); me.MyPK = "ND" + int.Parse(fl.No) + "01" + "_" + MapExtXmlList.StartFlow; int i = me.RetrieveFromDBSources(); if (i == 0) { BP.DA.Log.DefaultLogWriteLineError("没有为流程(" + fl.Name + ")的开始节点设置发起数据,请参考说明书解决."); return; } if (string.IsNullOrEmpty(me.Tag)) { BP.DA.Log.DefaultLogWriteLineError("没有为流程(" + fl.Name + ")的开始节点设置发起数据,请参考说明书解决."); return; } // 获取从表数据. DataSet ds = new DataSet(); string[] dtlSQLs = me.Tag1.Split('*'); foreach (string sql in dtlSQLs) { if (string.IsNullOrEmpty(sql)) { continue; } string[] tempStrs = sql.Split('='); string dtlName = tempStrs[0]; DataTable dtlTable = BP.DA.DBAccess.RunSQLReturnTable(sql.Replace(dtlName + "=", "")); dtlTable.TableName = dtlName; ds.Tables.Add(dtlTable); } #endregion 读取数据. #region 检查数据源是否正确. string errMsg = ""; // 获取主表数据. DataTable dtMain = BP.DA.DBAccess.RunSQLReturnTable(me.Tag); if (dtMain.Rows.Count == 0) { BP.DA.Log.DefaultLogWriteLineError("流程(" + fl.Name + ")此时无任务."); this.SetText("流程(" + fl.Name + ")此时无任务."); return; } this.SetText("@查询到(" + dtMain.Rows.Count + ")条任务."); if (dtMain.Columns.Contains("Starter") == false) { errMsg += "@配值的主表中没有Starter列."; } if (dtMain.Columns.Contains("MainPK") == false) { errMsg += "@配值的主表中没有MainPK列."; } if (errMsg.Length > 2) { this.SetText(errMsg); BP.DA.Log.DefaultLogWriteLineError("流程(" + fl.Name + ")的开始节点设置发起数据,不完整." + errMsg); return; } #endregion 检查数据源是否正确. #region 处理流程发起. string nodeTable = "ND" + int.Parse(fl.No) + "01"; int idx = 0; foreach (DataRow dr in dtMain.Rows) { idx++; string mainPK = dr["MainPK"].ToString(); string sql = "SELECT OID FROM " + nodeTable + " WHERE MainPK='" + mainPK + "'"; if (DBAccess.RunSQLReturnTable(sql).Rows.Count != 0) { this.SetText("@" + fl.Name + ",第" + idx + "条,此任务在之前已经完成。"); continue; /*说明已经调度过了*/ } string starter = dr["Starter"].ToString(); if (WebUser.No != starter) { BP.Web.WebUser.Exit(); BP.Port.Emp emp = new BP.Port.Emp(); emp.No = starter; if (emp.RetrieveFromDBSources() == 0) { this.SetText("@" + fl.Name + ",第" + idx + "条,设置的发起人员:" + emp.No + "不存在."); BP.DA.Log.DefaultLogWriteLineInfo("@数据驱动方式发起流程(" + fl.Name + ")设置的发起人员:" + emp.No + "不存在。"); continue; } WebUser.SignInOfGener(emp); } #region 给值. //System.Collections.Hashtable ht = new Hashtable(); Work wk = fl.NewWork(); string err = ""; #region 检查用户拼写的sql是否正确? foreach (DataColumn dc in dtMain.Columns) { string f = dc.ColumnName.ToLower(); switch (f) { case "starter": case "mainpk": case "refmainpk": case "tonode": break; default: bool isHave = false; foreach (Attr attr in wk.EnMap.Attrs) { if (attr.Key.ToLower() == f) { isHave = true; break; } } if (isHave == false) { err += " " + f + " "; } break; } } if (string.IsNullOrEmpty(err) == false) { throw new Exception("您设置的字段:" + err + "不存在开始节点的表单中,设置的sql:" + me.Tag); } #endregion 检查用户拼写的sql是否正确? foreach (DataColumn dc in dtMain.Columns) { wk.SetValByKey(dc.ColumnName, dr[dc.ColumnName].ToString()); } if (ds.Tables.Count != 0) { // MapData md = new MapData(nodeTable); MapDtls dtls = new MapDtls(nodeTable); foreach (MapDtl dtl in dtls) { foreach (DataTable dt in ds.Tables) { if (dt.TableName != dtl.No) { continue; } //删除原来的数据。 GEDtl dtlEn = dtl.HisGEDtl; dtlEn.Delete(GEDtlAttr.RefPK, wk.OID.ToString()); // 执行数据插入。 foreach (DataRow drDtl in dt.Rows) { if (drDtl["RefMainPK"].ToString() != mainPK) { continue; } dtlEn = dtl.HisGEDtl; foreach (DataColumn dc in dt.Columns) { dtlEn.SetValByKey(dc.ColumnName, drDtl[dc.ColumnName].ToString()); } dtlEn.RefPK = wk.OID.ToString(); dtlEn.OID = 0; dtlEn.Insert(); } } } } #endregion 给值. int toNodeID = 0; try { toNodeID = int.Parse(dr["ToNode"].ToString()); } catch { /*有可能在4.5以前的版本中没有tonode这个约定.*/ } // 处理发送信息. // Node nd =new Node(); string msg = ""; try { if (toNodeID == 0) { WorkNode wn = new WorkNode(wk, fl.HisStartNode); msg = wn.NodeSend().ToMsgOfText(); } if (toNodeID == fl.StartNodeID) { /* 发起后让它停留在开始节点上,就是为开始节点创建一个待办。*/ Int64 workID = BP.WF.Dev2Interface.Node_CreateStartNodeWork(fl.No, null, null, WebUser.No, null); if (workID != wk.OID) { throw new Exception("@异常信息:不应该不一致的workid."); } else { wk.Update(); } msg = "已经为(" + WebUser.No + ") 创建了开始工作节点. "; } BP.DA.Log.DefaultLogWriteLineInfo(msg); this.SetText("@" + fl.Name + ",第" + idx + "条,发起人员:" + WebUser.No + "-" + WebUser.Name + "已完成.\r\n" + msg); } catch (Exception ex) { this.SetText("@" + fl.Name + ",第" + idx + "条,发起人员:" + WebUser.No + "-" + WebUser.Name + "发起时出现错误.\r\n" + ex.Message); BP.DA.Log.DefaultLogWriteLineWarning(ex.Message); } } #endregion 处理流程发起. }
/// <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); }