using System;
using BP.En;
using BP.DA;
using System.Collections;
using System.Data;
using BP.Port;
using BP.Web;
using BP.Sys;
using BP.WF.Data;
using BP.WF.Template;
namespace BP.WF
{
///
/// 处理工作退回
///
public class WorkReturn
{
#region 变量
///
/// 从节点
///
private Node HisNode = null;
///
/// 退回到节点
///
private Node ReturnToNode = null;
///
/// 工作ID
///
private Int64 WorkID = 0;
///
/// 流程ID
///
private Int64 FID = 0;
///
/// 是否按原路返回?
///
private bool IsBackTrack = false;
///
/// 退回原因
///
private string Msg = "退回原因未填写.";
///
/// 当前节点
///
private Work HisWork = null;
///
/// 退回到节点
///
private Work ReurnToWork = null;
private string dbStr = BP.Difference.SystemConfig.AppCenterDBVarStr;
private Paras ps;
public string ReturnToEmp = null;
public int ReturnToNodeID = 0;
///
/// 退回考核规则字段
///
public string ReturnCHDatas = null;
#endregion
///
/// 工作退回
///
/// 流程编号
/// WorkID
/// 流程ID
/// 从节点
/// 退回到节点, 0表示上一个节点,或者指定的一个节点.
/// 退回到人
/// 是否需要原路返回?
/// 退回原因
public WorkReturn(string fk_flow, Int64 workID, Int64 fid, int currNodeID, int returnToNodeID, string returnToEmp, bool isBackTrack, string returnInfo, string pageData = null)
{
this.HisNode = new Node(currNodeID);
//如果退回的节点为0,就求出可以退回的唯一节点.
if (returnToNodeID == 0)
{
DataTable dt = BP.WF.Dev2Interface.DB_GenerWillReturnNodes( workID);
if (dt.Rows.Count == 0)
throw new Exception("err@当前节点不允许退回,系统根据退回规则没有找到可以退回的到的节点。");
if (dt.Rows.Count != 1)
throw new Exception("err@当前节点可以退回的节点有[" + dt.Rows.Count + "]个,您需要指定要退回的节点才能退回。");
returnToNodeID = int.Parse(dt.Rows[0][0].ToString());
if (DataType.IsNullOrEmpty(returnToEmp) == true)
returnToEmp = dt.Rows[0][2].ToString();
}
this.ReturnToNode = new Node(returnToNodeID);
this.WorkID = workID;
this.FID = fid;
this.IsBackTrack = isBackTrack;
this.Msg = returnInfo;
this.ReturnToEmp = returnToEmp;
this.ReturnToNodeID = returnToNodeID;
//当前工作.
this.HisWork = this.HisNode.HisWork;
this.HisWork.OID = workID;
this.HisWork.RetrieveFromDBSources();
//退回工作
this.ReurnToWork = this.ReturnToNode.HisWork;
this.ReurnToWork.OID = workID;
if (this.ReurnToWork.RetrieveFromDBSources() == 0)
{
this.ReurnToWork.OID = fid;
this.ReurnToWork.RetrieveFromDBSources();
}
//退回考核规则
this.ReturnCHDatas = pageData;
}
///
/// 删除两个节点之间的业务数据与流程引擎控制数据.
///
private void DeleteSpanNodesGenerWorkerListData()
{
if (this.IsBackTrack == true)
return;
Paras ps = new Paras();
string dbStr = BP.Difference.SystemConfig.AppCenterDBVarStr;
// 删除FH, 不管是否有这笔数据.
ps.Clear();
/*如果不是退回并原路返回,就需要清除 两个节点之间的数据, 包括WF_GenerWorkerlist的数据.*/
if (this.ReturnToNode.IsStartNode == true)
{
// 删除其子线程流程.
ps.Clear();
ps.SQL = "DELETE FROM WF_GenerWorkFlow WHERE FID=" + dbStr + "FID ";
ps.Add("FID", this.WorkID);
DBAccess.RunSQL(ps);
/*如果退回到了开始的节点,就删除出开始节点以外的数据,不要删除节点表单数据,这样会导致流程轨迹打不开.*/
ps.Clear();
ps.SQL = "DELETE FROM WF_GenerWorkerlist WHERE FK_Node!=" + dbStr + "FK_Node AND (WorkID=" + dbStr + "WorkID1 OR FID=" + dbStr + "WorkID2)";
ps.Add(GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID);
ps.Add("WorkID1", this.WorkID);
ps.Add("WorkID2", this.WorkID);
DBAccess.RunSQL(ps);
return;
}
/*找到发送到退回的时间点,把从这个时间点以来的数据都要删除掉.*/
ps.Clear();
ps.SQL = "SELECT RDT,ActionType,NDFrom FROM ND" + int.Parse(this.HisNode.FK_Flow) + "Track WHERE NDFrom=" + dbStr + "NDFrom AND WorkID=" + dbStr + "WorkID AND ActionType=" + (int)ActionType.Forward + " ORDER BY RDT desc ";
ps.Add("NDFrom", this.ReturnToNode.NodeID);
ps.Add("WorkID", this.WorkID);
DataTable dt = DBAccess.RunSQLReturnTable(ps);
if (dt.Rows.Count >= 1)
{
string rdt = dt.Rows[0][0].ToString();
ps.Clear();
ps.SQL = "SELECT ActionType,NDFrom FROM ND" + int.Parse(this.HisNode.FK_Flow) + "Track WHERE RDT >=" + dbStr + "RDT AND (WorkID=" + dbStr + "WorkID OR FID=" + dbStr + "FID) AND NDFrom NOT IN(SELECT NDFrom FROM ND" + int.Parse(this.HisNode.FK_Flow) + "Track WHERE RDT <" + dbStr + "RDT And ActionType IN (" + (int)ActionType.Forward + ","
+ (int)ActionType.ForwardFL + "," + (int)ActionType.ForwardHL + ") AND (WorkID=" + dbStr + "WorkID OR FID=" + dbStr + "FID)) ORDER BY RDT ";
ps.Add("RDT", rdt);
ps.Add("WorkID", this.WorkID);
ps.Add("FID", this.WorkID);
dt = DBAccess.RunSQLReturnTable(ps);
foreach (DataRow dr in dt.Rows)
{
ActionType at = (ActionType)int.Parse(dr["ActionType"].ToString());
int nodeid = int.Parse(dr["NDFrom"].ToString());
if (nodeid == this.ReturnToNode.NodeID)
continue;
//删除中间的节点.
ps.Clear();
ps.SQL = "DELETE FROM WF_GenerWorkerlist WHERE FK_Node=" + dbStr + "FK_Node AND (WorkID=" + dbStr + "WorkID1 OR FID=" + dbStr + "WorkID2) ";
ps.Add("FK_Node", nodeid);
ps.Add("WorkID1", this.WorkID);
ps.Add("WorkID2", this.WorkID);
DBAccess.RunSQL(ps);
//删除审核意见
ps.Clear();
ps.SQL = "DELETE FROM ND" + int.Parse(this.ReturnToNode.FK_Flow) + "Track WHERE NDFrom=" + dbStr + "NDFrom AND (WorkID=" + dbStr + "WorkID1 OR FID=" + dbStr + "WorkID2) AND ActionType=22";
ps.Add("NDFrom", nodeid);
ps.Add("WorkID1", this.WorkID);
ps.Add("WorkID2", this.WorkID);
DBAccess.RunSQL(ps);
}
}
//删除当前节点的数据.
ps.Clear();
ps.SQL = "DELETE FROM WF_GenerWorkerlist WHERE FK_Node=" + dbStr + "FK_Node AND (WorkID=" + dbStr + "WorkID1 OR FID=" + dbStr + "WorkID2) ";
ps.Add("FK_Node", this.HisNode.NodeID);
ps.Add("WorkID1", this.WorkID);
ps.Add("WorkID2", this.WorkID);
DBAccess.RunSQL(ps);
// string sql = "SELECT * FROM ND" + int.Parse(this.HisNode.FK_Flow) + "Track WHERE NDTo='"+this.ReturnToNode.NodeID+" AND WorkID="+this.WorkID;
// ActionType
}
///
/// 队列节点上一个人退回另外一个人.
///
///
public string DoOrderReturn()
{
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null, atPara);
if (msg != null)
return msg;
//执行退回的考核.
Glo.InitCH(this.HisNode.HisFlow, this.HisNode, this.WorkID, this.FID, this.HisNode.Name + ":退回考核.");
if (DataType.IsNullOrEmpty(this.HisNode.FocusField) == false)
{
try
{
string focusField = "";
string[] focusFields = this.HisNode.FocusField.Split('@');
if (focusFields.Length >= 2)
focusField = focusFields[1];
else
focusField = focusFields[0];
// 把数据更新它。
this.HisWork.Update(focusField, "");
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError("退回时更新焦点字段错误:" + ex.Message);
}
}
//退回到人.
Emp returnToEmp = new Emp(this.ReturnToEmp);
// 退回状态。
Paras ps = new Paras();
ps.SQL = "UPDATE WF_GenerWorkFlow SET WFState=" + dbStr + "WFState,FK_Node=" + dbStr + "FK_Node,NodeName=" + dbStr + "NodeName,TodoEmps=" + dbStr + "TodoEmps, TodoEmpsNum=0 WHERE WorkID=" + dbStr + "WorkID";
ps.Add(GenerWorkFlowAttr.WFState, (int)WFState.ReturnSta);
ps.Add(GenerWorkFlowAttr.FK_Node, this.ReturnToNode.NodeID);
ps.Add(GenerWorkFlowAttr.NodeName, this.ReturnToNode.Name);
ps.Add(GenerWorkFlowAttr.TodoEmps, returnToEmp.UserID + "," + returnToEmp.Name + ";");
ps.Add(GenerWorkFlowAttr.WorkID, this.WorkID);
DBAccess.RunSQL(ps);
ps = new Paras();
ps.SQL = "UPDATE WF_GenerWorkerlist SET IsPass=0,IsRead=0 WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID AND FK_Emp=" + dbStr + "FK_Emp ";
ps.Add("FK_Node", this.ReturnToNode.NodeID);
ps.Add("WorkID", this.WorkID);
ps.Add("FK_Emp", this.ReturnToEmp);
DBAccess.RunSQL(ps);
ps = new Paras();
ps.SQL = "UPDATE WF_GenerWorkerlist SET IsPass=1000,IsRead=0 WHERE FK_Node=" + dbStr + "FK_Node AND WorkID=" + dbStr + "WorkID AND FK_Emp=" + dbStr + "FK_Emp ";
ps.Add("FK_Node", this.HisNode.NodeID);
ps.Add("WorkID", this.WorkID);
ps.Add("FK_Emp", WebUser.No);
DBAccess.RunSQL(ps);
//更新流程报表数据.
ps = new Paras();
ps.SQL = "UPDATE " + this.HisNode.HisFlow.PTable + " SET WFState=" + dbStr + "WFState, FlowEnder=" + dbStr + "FlowEnder, FlowEndNode=" + dbStr + "FlowEndNode WHERE OID=" + dbStr + "OID";
ps.Add("WFState", (int)WFState.ReturnSta);
ps.Add("FlowEnder", WebUser.No);
ps.Add("FlowEndNode", ReturnToNode.NodeID);
ps.Add("OID", this.WorkID);
DBAccess.RunSQL(ps);
////从工作人员列表里找到被退回人的接受人.
//GenerWorkerList gwl = new GenerWorkerList();
//gwl.Retrieve(GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID, GenerWorkerListAttr.WorkID, this.WorkID);
// 记录退回轨迹。
ReturnWork rw = new ReturnWork();
rw.WorkID = this.WorkID;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnNodeName = this.HisNode.Name;
rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
rw.ReturnToEmp = this.ReturnToEmp; //退回给。
rw.BeiZhu = Msg;
rw.setMyPK(DBAccess.GenerOIDByGUID().ToString());
if (DataType.IsNullOrEmpty(this.ReturnCHDatas) == false)
{
string[] strs = this.ReturnCHDatas.Split('&');
foreach (string str in strs)
{
string[] param = str.Split('=');
if (param.Length == 2)
rw.SetValByKey(param[0].Replace("TB_", "").Replace("DDL_", "").Replace("CB_", ""), param[1]);
}
}
rw.Insert();
// 加入track.
this.AddToTrack(ActionType.Return, returnToEmp.UserID, returnToEmp.Name,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
/*try
{
// 记录退回日志.
ReorderLog(this.HisNode, this.ReturnToNode, rw);
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError(ex.Message);
}*/
// 以退回到的节点向前数据用递归删除它。
if (IsBackTrack == false)
{
/*如果退回不需要原路返回,就删除中间点的数据。*/
#warning 没有考虑两种流程数据存储模式。
//DeleteToNodesData(this.ReturnToNode.HisToNodes);
}
Work work = this.HisWork;
work.OID = this.WorkID;
work.RetrieveFromDBSources();
// 退回后发送的消息事件
PushMsgs pms = new PushMsgs();
pms.Retrieve(PushMsgAttr.FK_Node, this.ReturnToNode.NodeID, PushMsgAttr.FK_Event, EventListNode.ReturnAfter);
work.NodeID = this.HisNode.NodeID;
foreach (PushMsg pm in pms)
{
pm.DoSendMessage(this.ReturnToNode, work, null, null, null, this.ReturnToEmp);
}
//退回后事件
atPara += "@SendToEmpIDs=" + this.ReturnToEmp;
string text = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, work, null, atPara);
if (text != null && text.Length > 1000)
text = "退回事件:无返回信息.";
// 返回退回信息.
if (this.ReturnToNode.IsGuestNode)
{
GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
return "工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + gwf.GuestNo + "," + gwf.GuestName + ").\n\r" + text;
}
else
{
return "工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + returnToEmp.UserID + "," + returnToEmp.Name + ").\n\r" + text;
}
}
///
/// 要退回到父流程上去
///
///
private string ReturnToParentFlow()
{
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null, atPara);
if (msg != null)
return msg;
//当前 gwf.
GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
//设置子流程信息.
GenerWorkFlow gwfP = new GenerWorkFlow(gwf.PWorkID);
gwfP.WFState = WFState.ReturnSta;
gwfP.FK_Node = this.ReturnToNode.NodeID;
gwfP.NodeName = this.ReturnToNode.Name;
//启用待办.
GenerWorkerList gwl = new GenerWorkerList();
GenerWorkerLists gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID, GenerWorkerListAttr.WorkID, gwfP.WorkID);
string toEmps = "";
string returnEmps = "";
foreach (GenerWorkerList item in gwls)
{
item.IsPassInt = 0;
item.Update();
gwl = item;
toEmps += item.FK_Emp + "," + item.FK_EmpText + ";";
returnEmps += item.FK_Emp + ",";
}
gwfP.TodoEmps = toEmps;
gwfP.SetPara("IsBackTracking", this.IsBackTrack);
gwfP.Update();
#region 写入退回提示.
// 记录退回轨迹。
/* ReturnWork rw = new ReturnWork();
rw.WorkID = gwfP.WorkID;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnNodeName = gwfP.NodeName;
rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
rw.ReturnToEmp = gwl.FK_Emp; //退回给。
rw.BeiZhu = Msg;
rw.IsBackTracking = this.IsBackTrack;
rw.setMyPK(DBAccess.GenerOIDByGUID().ToString());
if (DataType.IsNullOrEmpty(this.ReturnCHDatas) == false)
{
string[] strs = this.ReturnCHDatas.Split('&');
foreach (string str in strs)
{
string[] param = str.Split('=');
if (param.Length == 2)
rw.SetValByKey(param[0].Replace("TB_", "").Replace("DDL_", "").Replace("CB_", ""), param[1]);
}
}
rw.Insert();*/
// 加入track.
this.AddToTrack(ActionType.Return, gwl.FK_Emp, gwl.FK_EmpText,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
#endregion
//删除当前的流程.
BP.WF.Dev2Interface.Flow_DoDeleteFlowByReal(this.WorkID, true);
//设置当前为未读的状态.
BP.WF.Dev2Interface.Node_SetWorkUnRead(gwfP.WorkID);
//退回后发送的消息事件
PushMsgs pms = new PushMsgs();
pms.Retrieve(PushMsgAttr.FK_Node, this.ReturnToNode.NodeID, PushMsgAttr.FK_Event, EventListNode.ReturnAfter);
Work work = this.HisWork;
work.OID = gwfP.WorkID;
work.RetrieveFromDBSources();
work.NodeID = this.HisNode.NodeID;
foreach (PushMsg pm in pms)
{
pm.DoSendMessage(this.ReturnToNode, work, null, null, null, returnEmps);
}
//如果事件返回的信息不是 null,就终止执行。
atPara += "@SendToEmpIDs=" + returnEmps;
msg = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, work, null, atPara);
if (String.IsNullOrEmpty(msg) == true) // 如果有消息,就返回消息.
msg = "";
//返回退回信息.
return "成功的退回到[" + gwfP.FlowName + " - " + this.ReturnToNode.Name + "],退回给[" + toEmps + "].\n\r" + msg;
}
///
/// 执行退回到分流节点,完全退回.
///
///
public string DoItOfKillEtcThread()
{
//干流程的gwf.
GenerWorkFlow gwf = new GenerWorkFlow(this.FID);
Node nd = new Node(gwf.FK_Node);
if (nd.IsFLHL == false)
throw new Exception("err@系统已经运行到合流节点,您不能在执行退回.");
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是 null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null,
atPara);
if (String.IsNullOrEmpty(msg) == false) // 2019-08-28 zl 返回空字符串表示执行成功,不应该终止。
return msg;
//查询出来所有的子线程,并删除他.
GenerWorkFlows gwfs = new GenerWorkFlows();
gwfs.Retrieve(GenerWorkFlowAttr.FID, this.FID);
string delSubThreadInfo = "\t\n";
foreach (GenerWorkFlow mygwf in gwfs)
{
BP.WF.Dev2Interface.Node_FHL_KillSubFlow(mygwf.WorkID);
delSubThreadInfo += mygwf.Title + "\t\n";
}
//更新状态.
gwf.WFState = WFState.ReturnSta;
gwf.Sender = WebUser.No + "," + WebUser.Name + ";";
gwf.FK_Node = this.ReturnToNode.NodeID;
string todoEmps = "";
//更新他的待办.
GenerWorkerLists gwls = new GenerWorkerLists(this.FID, this.ReturnToNode.NodeID);
foreach (GenerWorkerList item in gwls)
{
todoEmps += item.FK_Emp + "," + item.FK_EmpText + ";";
item.IsPassInt = 0;
item.Update();
}
gwf.SetPara("ThreadCount", 0);
gwf.TodoEmps = todoEmps;
gwf.TodoEmpsNum = gwls.Count;
gwf.SetPara("IsBackTracking", this.IsBackTrack);
gwf.Update();
//删除子线程的工作.
DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE FID=" + gwf.WorkID);
//记录退回轨迹.
/*ReturnWork rw = new ReturnWork();
rw.WorkID = gwf.WorkID;
rw.ReturnNode = this.HisNode.NodeID;
rw.ReturnNodeName = this.HisNode.Name;
rw.Returner = WebUser.No;
rw.ReturnerName = WebUser.Name;
rw.BeiZhu = this.Msg;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnToEmp = this.ReturnToEmp; //.TodoEmps;
//主键.
rw.setMyPK(BP.DA.DBAccess.GenerGUID());
rw.Insert();*/
//设置return记录. 加入track.
this.AddToTrack(ActionType.Return, WebUser.No, WebUser.Name, this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
//如果事件返回的信息不是 null,就终止执行。.
msg = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, this.HisWork, null, atPara);
if (String.IsNullOrEmpty(msg) == false) // 如果有消息,就返回消息.
return msg;
return "子线程退回成功, 一共删除了(" + gwfs.Count + ")个其他的子线程:" + delSubThreadInfo;
}
///
/// 执行退回.
///
/// 返回退回信息
public string DoIt()
{
// 增加要退回到父流程上去. by zhoupeng.
if (this.ReturnToNode.FK_Flow.Equals(this.HisNode.FK_Flow) == false)
{
/*子流程要退回到父流程的情况.*/
return ReturnToParentFlow();
}
if (this.HisNode.NodeID == this.ReturnToNode.NodeID)
{
if (this.HisNode.TodolistModel == TodolistModel.Order)
{
/*一个队列的模式,一个人退回给另外一个人 */
return DoOrderReturn();
}
}
if (this.ReturnToNode.TodolistModel == TodolistModel.Order)
{
/* 当退回到的节点是 队列模式或者是协作模式时. */
return DoOrderReturn();
}
/* 删除退回选择的信息, forzhuhai: 退回后,删除发送人上次选择的信息.
*
* 场景:
* 1, a b c d 节点 d节点退回给c 如果d的接收人是c来选择的, 他退回后要把d的选择信息删除掉.
* 2, a b c d 节点 d节点退回给a 如果 b c d 的任何一个接受人的范围是有上一步发送人来选择的,就要删除选择人的信息.
*
* */
//是否需要删除中间点.
bool isNeedDeleteSpanNodes = true;
string sql = "";
foreach (Node nd in this.ReturnToNode.HisToNodes)
{
if (nd.NodeID == this.HisNode.NodeID)
{
sql = "DELETE FROM WF_SelectAccper WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID;
DBAccess.RunSQL(sql);
isNeedDeleteSpanNodes = false;
}
}
//如果有中间步骤.
if (isNeedDeleteSpanNodes)
{
//获得可以退回的节点,这个节点是有顺序的.
DataTable dt = BP.WF.Dev2Interface.DB_GenerWillReturnNodes( this.WorkID);
bool isDelBegin = false;
foreach (DataRow dr in dt.Rows)
{
int nodeID = int.Parse(dr["No"].ToString());
if (nodeID == this.ReturnToNode.NodeID)
isDelBegin = true; /*如果等于当前的节点,就开始把他们删除掉.*/
if (isDelBegin)
{
sql = "DELETE FROM WF_SelectAccper WHERE FK_Node=" + nodeID + " AND WorkID=" + this.WorkID;
DBAccess.RunSQL(sql);
}
}
// 删除当前节点信息.
sql = "DELETE FROM WF_SelectAccper WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID;
DBAccess.RunSQL(sql);
}
//删除.
Template.NodeWorkCheck fwc = new NodeWorkCheck(this.HisNode.NodeID);
if (fwc.FWCIsShowReturnMsg == 0)
BP.WF.Dev2Interface.DeleteCheckInfo(this.HisNode.FK_Flow, this.WorkID, this.HisNode.NodeID);
//删除审核组件设置“协作模式下操作员显示顺序”为“按照接受人员列表先后顺序(官职大小)”,而生成的待审核轨迹信息
if (fwc.FWCSta == FrmWorkCheckSta.Enable && fwc.FWCOrderModel == FWCOrderModel.SqlAccepter)
{
DBAccess.RunSQL("DELETE FROM ND" + int.Parse(this.HisNode.FK_Flow) + "Track WHERE WorkID = " + this.WorkID +
" AND ActionType = " + (int)ActionType.WorkCheck + " AND NDFrom = " + this.HisNode.NodeID +
" AND NDTo = " + this.HisNode.NodeID + " AND (Msg = '' OR Msg IS NULL)");
}
switch (this.HisNode.HisRunModel)
{
case RunModel.Ordinary: /* 1: 普通节点向下发送的*/
switch (ReturnToNode.HisRunModel)
{
case RunModel.Ordinary: /*1-1 普通节to普通节点 */
return ExeReturn1_1(); //
break;
case RunModel.FL: /* 1-2 普通节to分流点 */
return ExeReturn1_1(); //
break;
case RunModel.HL: /*1-3 普通节to合流点 */
return ExeReturn1_1(); //
break;
case RunModel.FHL: /*1-4 普通节点to分合流点 */
return ExeReturn1_1();
break;
case RunModel.SubThreadSameWorkID: /*1-5 普通节to子线程点 */
case RunModel.SubThreadUnSameWorkID: /*1-5 普通节to子线程点 */
default:
throw new Exception("@退回错误:非法的设计模式或退回模式.普通节to子线程点");
break;
}
break;
case RunModel.FL: /* 2: 分流节点向下发送的*/
switch (this.ReturnToNode.HisRunModel)
{
case RunModel.Ordinary: /*2.1 分流点to普通节点 */
return ExeReturn1_1(); //
case RunModel.FL: /*2.2 分流点to分流点 */
case RunModel.HL: /*2.3 分流点to合流点,分合流点 */
case RunModel.FHL:
return ExeReturn1_1(); //
case RunModel.SubThreadSameWorkID: /* 2.4 分流点to子线程点 */
case RunModel.SubThreadUnSameWorkID: /* 2.4 分流点to子线程点 */
return ExeReturn2_4(); //
default:
throw new Exception("@没有判断的节点类型(" + ReturnToNode.Name + ")");
break;
}
break;
case RunModel.HL: /* 3: 合流节点向下退回 */
switch (this.ReturnToNode.HisRunModel)
{
case RunModel.Ordinary: /*3.1 普通工作节点 */
return ExeReturn1_1(); //
case RunModel.FL: /*3.2 合流点向分流点退回 */
return ExeReturn3_2(); //
case RunModel.HL: /*3.3 合流点 */
case RunModel.FHL:
throw new Exception("@尚未完成.");
case RunModel.SubThreadSameWorkID:/*3.4 合流点向子线程退回 */
case RunModel.SubThreadUnSameWorkID:/*3.4 合流点向子线程退回 */
return ExeReturn3_4();
default:
throw new Exception("@退回错误:非法的设计模式或退回模式.普通节to子线程点");
}
break;
case RunModel.FHL: /* 4: 分流节点向下发送的 */
switch (this.ReturnToNode.HisRunModel)
{
case RunModel.Ordinary: /*4.1 普通工作节点 */
return ExeReturn1_1();
case RunModel.FL: /*4.2 分流点 */
case RunModel.HL: /*4.3 合流点 */
case RunModel.FHL:
throw new Exception("@尚未完成.");
case RunModel.SubThreadSameWorkID:/*4.5 子线程*/
case RunModel.SubThreadUnSameWorkID:/*4.5 子线程*/
return ExeReturn3_4();
default:
throw new Exception("@没有判断的节点类型(" + this.ReturnToNode.Name + ")");
}
break;
case RunModel.SubThreadSameWorkID: /* 5: 子线程节点向下发送的 */
case RunModel.SubThreadUnSameWorkID: /* 5: 子线程节点向下发送的 */
switch (this.ReturnToNode.HisRunModel)
{
case RunModel.Ordinary: /*5.1 普通工作节点 */
throw new Exception("@非法的退回模式,,请反馈给管理员.");
case RunModel.FL: /*5.2 分流点 */
/*子线程退回给分流点.*/
return ExeReturn5_2();
case RunModel.HL: /*5.3 合流点 */
throw new Exception("@非法的退回模式,请反馈给管理员.");
case RunModel.FHL: /*5.4 分合流点 */
return ExeReturn5_2();
//throw new Exception("@目前不支持此场景下的退回,请反馈给管理员.");
case RunModel.SubThreadSameWorkID: /*5.5 子线程*/
case RunModel.SubThreadUnSameWorkID: /*5.5 子线程*/
return ExeReturn1_1();
default:
throw new Exception("@没有判断的节点类型(" + ReturnToNode.Name + ")");
}
break;
default:
throw new Exception("@没有判断的退回类型:" + this.HisNode.HisRunModel);
}
throw new Exception("@系统出现未判断的异常.");
}
///
/// 分流点退回给子线程
///
///
private string ExeReturn2_4()
{
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null, atPara);
if (msg != null)
return msg;
//更新运动到节点,但是仍然是退回状态.
GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
gwf.FK_Node = this.ReturnToNode.NodeID;
//增加参与的人员
if (gwf.Emps.Contains("@" + WebUser.No + ",") == false)
gwf.Emps += WebUser.No + "," + WebUser.Name + "@";
gwf.SetPara("IsBackTracking", this.IsBackTrack);
gwf.Update();
//更新退回到的人员信息可见.
string returnEmp = "";
GenerWorkerLists gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID);
foreach (GenerWorkerList item in gwls)
{
item.IsPassInt = 0;
item.Update();
this.ReturnToEmp = item.FK_Emp + "," + item.FK_EmpText;
returnEmp += item.FK_Emp + ",";
}
// 去掉合流节点工作人员的待办.
gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FK_Node, this.HisNode.NodeID);
foreach (GenerWorkerList item in gwls)
{
item.IsPassInt = 0;
item.IsRead = false;
item.Update();
}
//把分流节点的待办去掉.
gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FID, this.FID, GenerWorkerListAttr.FK_Emp, BP.Web.WebUser.No);
foreach (GenerWorkerList item in gwls)
{
item.IsPassInt = -2;
item.Update();
}
// 记录退回轨迹。
/*ReturnWork rw = new ReturnWork();
rw.WorkID = this.WorkID;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnNodeName = this.HisNode.Name;
rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
rw.ReturnToEmp = returnEmp; //退回给。
if (DataType.IsNullOrEmpty(this.ReturnCHDatas) == false)
{
string[] strs = this.ReturnCHDatas.Split('&');
foreach (string str in strs)
{
string[] param = str.Split('=');
if (param.Length == 2)
rw.SetValByKey(param[0].Replace("TB_", "").Replace("DDL_", "").Replace("CB_", ""), param[1]);
}
}
rw.setMyPK(DBAccess.GenerOIDByGUID().ToString());
rw.BeiZhu = Msg;
rw.IsBackTracking = this.IsBackTrack;
rw.Insert();*/
// 加入track.
this.AddToTrack(ActionType.Return, returnEmp, ReturnToEmp,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
//退回消息事件
PushMsgs pms = new PushMsgs();
pms.Retrieve(PushMsgAttr.FK_Node, this.HisNode.NodeID, PushMsgAttr.FK_Event, EventListNode.UndoneAfter);
foreach (PushMsg pm in pms)
{
pm.DoSendMessage(this.HisNode, this.HisNode.HisWork, null, null, null, returnEmp);
}
//退回后事件
atPara += "@SendToEmpIDs=" + returnEmp;
string text = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, this.HisWork, null, atPara);
if (text != null && text.Length > 1000)
text = "退回事件:无返回信息.";
if (text == null)
text = "";
return "成功的把信息退回到:" + this.ReturnToNode.Name + " , 退回给:(" + this.ReturnToEmp + ").\n\r" + text;
}
///
/// 子线程退回给分流点
///
///
private string ExeReturn5_2()
{
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null, atPara);
if (msg != null)
return msg;
GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
gwf.FK_Node = this.ReturnToNode.NodeID;
string info = "@工作已经成功的退回到(" + ReturnToNode.Name + ")退回给:";
//子线程退回应该是单线退回到干流程.
//GenerWorkerLists gwls = new GenerWorkerLists();
//gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FID, this.FID, GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID);
//查询退回到的工作人员列表.
GenerWorkerLists gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID, GenerWorkerListAttr.FID,this.FID,
GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID);
string toEmp = "";
string toEmpName = "";
GenerWorkerList gwl = null;
if (gwls.Count == 1)
{
gwl = gwls[0] as GenerWorkerList;
gwl.IsPass = false; // 显示待办, 这个是合流节点的工作人员.
gwl.IsRead = false; //
gwl.Update();
info += gwl.FK_Emp + "," + gwl.FK_EmpText;
toEmp = gwl.FK_Emp;
toEmpName = gwl.FK_EmpText;
info += "(" + gwl.FK_Emp + "," + gwl.FK_EmpText + ")";
}
else
{
/*有可能多次退回的情况,表示曾经退回过n次。*/
}
// 记录退回轨迹。
/*ReturnWork rw = new ReturnWork();
//rw.WorkID = this.FID;
rw.WorkID = this.WorkID;
rw.FID = this.FID;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnNodeName = this.HisNode.Name;
rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
rw.ReturnToEmp = toEmp; //退回给。
if (DataType.IsNullOrEmpty(this.ReturnCHDatas) == false)
{
string[] strs = this.ReturnCHDatas.Split('&');
foreach (string str in strs)
{
string[] param = str.Split('=');
if (param.Length == 2)
rw.SetValByKey(param[0].Replace("TB_", "").Replace("DDL_", "").Replace("CB_", ""), param[1]);
}
}
rw.setMyPK(DBAccess.GenerOIDByGUID().ToString());
rw.BeiZhu = Msg;
rw.IsBackTracking = this.IsBackTrack;
rw.Insert();*/
// 加入track.
this.AddToTrack(ActionType.Return, toEmp, toEmpName,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
gwf.WFState = WFState.ReturnSta;
gwf.FK_Node = this.ReturnToNode.NodeID;
gwf.NodeName = this.ReturnToNode.Name;
gwf.Starter = toEmp;
gwf.StarterName = toEmpName;
gwf.Sender = WebUser.No + "," + WebUser.Name + ";";
//增加参与的人员
string emps = gwf.Emps;
if (DataType.IsNullOrEmpty(emps) == true)
emps = "@";
if (emps.Contains("@" + WebUser.No + ",") == false)
{
emps += WebUser.No + "," + WebUser.Name + "@";
}
gwf.Emps = emps;
gwf.SetPara("IsBackTracking",this.IsBackTrack);
gwf.Update();
//更新主流程的状态
GenerWorkFlow mainGwf = new GenerWorkFlow(gwf.FID);
//mainGwf.WFState = WFState.ReturnSta;
mainGwf.FK_Node = this.ReturnToNode.NodeID;
mainGwf.Update();
//找到当前的工作数据.
GenerWorkerList currWorker = new GenerWorkerList();
int i = currWorker.Retrieve(GenerWorkerListAttr.FK_Emp, WebUser.No,
GenerWorkerListAttr.WorkID, this.WorkID,
GenerWorkerListAttr.FK_Node, this.HisNode.NodeID);
if (i != 1)
throw new Exception("@当前的工作人员列表数据丢失了,流程引擎错误.");
//设置当前的工作数据为退回状态,让其不能看到待办, 这个是约定的值.
currWorker.IsPassInt = (int)WFState.ReturnSta;
currWorker.IsRead = false;
currWorker.Update();
//退回消息事件
PushMsgs pms = new PushMsgs();
pms.Retrieve(PushMsgAttr.FK_Node, this.HisNode.NodeID, PushMsgAttr.FK_Event, EventListNode.ReturnAfter);
foreach (PushMsg pm in pms)
{
pm.DoSendMessage(this.HisNode, this.HisWork, null, null, null, toEmp);
}
//退回后事件
atPara += "@SendToEmpIDs=" + toEmp;
string text = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, this.HisWork, null, atPara);
if (text != null && text.Length > 1000)
text = "退回事件:无返回信息.";
if (text == null)
text = "";
// 返回退回信息.
return info+".\n\r" + text;
}
///
/// 合流点向子线程退回
///
private string ExeReturn3_4()
{
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null, atPara);
if (msg != null)
return msg;
GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
gwf.FK_Node = this.ReturnToNode.NodeID;
string info = "@工作已经成功的退回到(" + ReturnToNode.Name + ")退回给:";
GenerWorkerLists gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID,
GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID);
string toEmp = "";
string toEmpName = "";
foreach (GenerWorkerList item in gwls)
{
item.IsPass = false;
item.IsRead = false;
item.Update();
info += item.FK_Emp + "," + item.FK_EmpText;
toEmp = item.FK_Emp;
toEmpName = item.FK_EmpText;
}
//删除已经发向合流点的汇总数据.
MapDtls dtls = new MapDtls("ND" + this.HisNode.NodeID);
foreach (MapDtl dtl in dtls)
{
/*如果是合流数据*/
if (dtl.IsHLDtl)
DBAccess.RunSQL("DELETE FROM " + dtl.PTable + " WHERE OID=" + this.WorkID);
}
// 记录退回轨迹。
/*ReturnWork rw = new ReturnWork();
rw.WorkID = this.WorkID;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnNodeName = this.HisNode.Name;
rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
rw.ReturnToEmp = toEmp; //退回给。
if (DataType.IsNullOrEmpty(this.ReturnCHDatas) == false)
{
string[] strs = this.ReturnCHDatas.Split('&');
foreach (string str in strs)
{
string[] param = str.Split('=');
if (param.Length == 2)
rw.SetValByKey(param[0].Replace("TB_", "").Replace("DDL_", "").Replace("CB_", ""), param[1]);
}
}
rw.setMyPK(DBAccess.GenerGUID());
rw.BeiZhu = Msg;
rw.IsBackTracking = this.IsBackTrack;
rw.Insert();*/
// 加入track.
this.AddToTrack(ActionType.Return, toEmp, toEmpName,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
gwf.WFState = WFState.ReturnSta;
gwf.Sender = WebUser.No + "," + WebUser.Name + ";";
//增加参与的人员
string emps = gwf.Emps;
if (DataType.IsNullOrEmpty(emps) == true)
emps = "@";
if (emps.Contains("@" + WebUser.No) == false)
{
emps += WebUser.No + "," + WebUser.Name + "@";
}
gwf.Emps = emps;
gwf.SetPara("IsBackTracking", this.IsBackTrack);
gwf.Update();
//退回消息事件
PushMsgs pms = new PushMsgs();
pms.Retrieve(PushMsgAttr.FK_Node, this.HisNode.NodeID, PushMsgAttr.FK_Event, EventListNode.ReturnAfter);
foreach (PushMsg pm in pms)
{
pm.DoSendMessage(this.HisNode, this.HisWork, null, null, null, toEmp);
}
//退回后事件
atPara += "@SendToEmpIDs=" + toEmp;
string text = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, this.HisWork, null, atPara);
if (text != null && text.Length > 1000)
text = "退回事件:无返回信息.";
if (text == null)
text = "";
// 返回退回信息.
return info + ".\n\r" + text;
}
///
/// 合流点向分流点退回
///
private string ExeReturn3_2()
{
//删除分流点与合流点之间的子线程数据。
//if (this.ReturnToNode.IsStartNode == false)
// throw new Exception("@没有处理的模式。");
//求出来退回到的 时间点。
GenerWorkerList toWL = new GenerWorkerList();
toWL.Retrieve(GenerWorkerListAttr.WorkID, this.WorkID,
GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID);
//如果是仅仅退回,就删除子线程数据。
if (this.IsBackTrack == false)
{
//删除子线程节点数据。
GenerWorkerLists gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkFlowAttr.FID, this.WorkID);
foreach (GenerWorkerList item in gwls)
{
if (item.RDT.CompareTo(toWL.RDT) == -1)
continue;
/* 删除 子线程数据 */
if (DBAccess.IsExitsObject("ND" + item.FK_Node) == true)
DBAccess.RunSQL("DELETE FROM ND" + item.FK_Node + " WHERE OID=" + item.WorkID);
DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE FID=" + this.WorkID + " AND FK_Node=" + item.FK_Node);
}
//删除流程控制数据。
DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE FID=" + this.WorkID);
}
return ExeReturn1_1();
}
///
/// 普通节点到普通节点的退回
///
///
private string ExeReturn1_1()
{
//为软通小杨处理rpt变量不能替换的问题.
GERpt rpt = this.HisNode.HisFlow.HisGERpt;
rpt.OID = this.WorkID;
if (rpt.RetrieveFromDBSources() == 0)
{
rpt.OID = this.FID;
rpt.RetrieveFromDBSources();
}
rpt.Row.Add("ReturnMsg", Msg);
//退回前事件
string atPara = "@ToNode=" + this.ReturnToNode.NodeID;
//如果事件返回的信息不是 null,就终止执行。
string msg = ExecEvent.DoNode(EventListNode.ReturnBefore, this.HisNode, this.HisWork, null,
atPara);
if (!String.IsNullOrEmpty(msg)) // 2019-08-28 zl。原来是 if(msg!=null)。返回空字符串表示执行成功,不应该终止。
return msg;
if (this.HisNode.FocusField != "")
{
try
{
string focusField = "";
string[] focusFields = this.HisNode.FocusField.Split('@');
if (focusFields.Length >= 2)
focusField = focusFields[1];
else
focusField = focusFields[0];
// 把数据更新它。
this.HisWork.Update(focusField, "");
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError("退回时更新焦点字段错误:" + ex.Message);
}
}
// 计算出来 退回到节点的应完成时间.
GenerWorkFlow gwf = new GenerWorkFlow(this.WorkID);
DateTime dtOfShould;
//增加天数. 考虑到了节假日.
dtOfShould = Glo.AddDayHoursSpan(DateTime.Now, this.ReturnToNode.TimeLimit,
this.ReturnToNode.TimeLimitHH, this.ReturnToNode.TimeLimitMM, this.ReturnToNode.TWay);
// 应完成日期.
string sdt = dtOfShould.ToString(DataType.SysDateTimeFormat + ":ss");
// 改变当前待办工作节点
gwf.WFState = WFState.ReturnSta;
gwf.FK_Node = this.ReturnToNode.NodeID;
gwf.NodeName = this.ReturnToNode.Name;
gwf.SDTOfNode = sdt;
gwf.Sender = WebUser.No + "," + WebUser.Name + ";";
gwf.HuiQianTaskSta = HuiQianTaskSta.None;
gwf.HuiQianZhuChiRen = "";
gwf.HuiQianZhuChiRenName = "";
gwf.Paras_ToNodes = "";
//获得所有的人员集合,退回到节点的.
GenerWorkerLists gwls = new GenerWorkerLists();
gwls.Retrieve(GenerWorkerListAttr.FK_Node, this.ReturnToNode.NodeID,
GenerWorkerListAttr.WorkID, this.WorkID);
if (gwls.Count == 0)
throw new Exception("err@没有找到要退回到节点的数据,请与管理员联系[WorkID=" + this.WorkID + ",ReturnToNode.NodeID=" + this.ReturnToNode.NodeID + "]");
//退回到人.
Emp empReturn = new Emp(this.ReturnToEmp);
gwf.TodoEmps = empReturn.UserID + "," + empReturn.Name + ";";
gwf.TodoEmpsNum = 1;
gwf.SetPara("IsBackTracking", this.IsBackTrack);
gwf.Update();
//更新待办状态.
var isHave = false;// 在计算中心项目上,没有找到要更新的gwl. 出现不应该的异常.
GenerWorkerList mygwl = null;
foreach (GenerWorkerList item in gwls)
{
mygwl = item;
if (item.FK_Emp.Equals(this.ReturnToEmp) == false)
{
item.Delete();
continue;
}
item.IsPassInt = 0;
item.IsRead = false;
item.SDT = sdt;
item.RDT = DataType.CurrentDateTimess;
item.Sender = WebUser.No + "," + WebUser.Name;
item.Update();
isHave = true;
}
//这里做了补偿的措施,否则就会出现异常数据. for:计算中心.
if (isHave == false)
{
mygwl.FK_Dept = WebUser.FK_Dept;
mygwl.FK_DeptT = WebUser.FK_DeptName;
mygwl.FK_Emp = WebUser.No;
mygwl.FK_EmpText = WebUser.Name;
mygwl.IsPassInt = 0;
mygwl.IsRead = false;
mygwl.SDT = sdt;
mygwl.RDT = DataType.CurrentDateTimess;
mygwl.Sender = WebUser.No + "," + WebUser.Name;
mygwl.Insert();
}
//更新流程报表数据.
ps = new Paras();
ps.SQL = "UPDATE " + this.HisNode.HisFlow.PTable + " SET WFState=" + dbStr + "WFState, FlowEnder=" + dbStr + "FlowEnder, FlowEndNode=" + dbStr + "FlowEndNode WHERE OID=" + dbStr + "OID";
ps.Add("WFState", (int)WFState.ReturnSta);
ps.Add("FlowEnder", WebUser.No);
ps.Add("FlowEndNode", ReturnToNode.NodeID);
ps.Add("OID", this.WorkID);
DBAccess.RunSQL(ps);
// 记录退回轨迹。
/*ReturnWork rw = new ReturnWork();
rw.WorkID = this.WorkID;
rw.ReturnToNode = this.ReturnToNode.NodeID;
rw.ReturnNodeName = this.HisNode.Name;
rw.ReturnNode = this.HisNode.NodeID; // 当前退回节点.
rw.ReturnToEmp = this.ReturnToEmp; //退回给。
rw.BeiZhu = Msg;*/
//杨玉慧
if (this.HisNode.TodolistModel == TodolistModel.Order
|| this.HisNode.TodolistModel == TodolistModel.Sharing
|| this.HisNode.TodolistModel == TodolistModel.TeamupGroupLeader
|| this.HisNode.TodolistModel == TodolistModel.Teamup)
{
// 为软通小杨屏蔽, 共享,顺序,协作模式的退回并原路返回的 问题.
//rw.IsBackTracking = true; /*如果是共享,顺序,协作模式,都必须是退回并原路返回.*/
// 需要更新当前人待办的状态, 把1000作为特殊标记,让其发送时可以找到他.
string sql = "UPDATE WF_GenerWorkerlist SET IsPass=1000 WHERE FK_Node=" + this.HisNode.NodeID + " AND WorkID=" + this.WorkID + " AND FK_Emp='" + WebUser.No + "'";
if (DBAccess.RunSQL(sql) == 0 && 1 == 2)
throw new Exception("@退回错误,没有找到要更新的目标数据.技术信息:" + sql);
//杨玉慧 将流程的 任务池状态设置为 NONE
sql = "UPDATE WF_GenerWorkFlow SET TaskSta=0 WHERE WorkID=" + this.WorkID;
if (DBAccess.RunSQL(sql) == 0 && 1 == 2)
throw new Exception("@退回错误,没有找到要更新的目标数据.技术信息:" + sql);
}
// 去掉了 else .
//rw.IsBackTracking = this.IsBackTrack;
//调用删除GenerWorkerList数据,不然会导致两个节点之间有垃圾数据,特别遇到中间有分合流时候。
this.DeleteSpanNodesGenerWorkerListData();
/*if (DataType.IsNullOrEmpty(this.ReturnCHDatas) == false)
{
string[] strs = this.ReturnCHDatas.Split('&');
foreach (string str in strs)
{
string[] param = str.Split('=');
if (param.Length == 2)
rw.SetValByKey(param[0].Replace("TB_", "").Replace("DDL_", "").Replace("CB_", ""), param[1]);
}
}
rw.setMyPK(DBAccess.GenerGUID());
rw.Insert();*/
// 为电建增加一个退回并原路返回的日志类型.
if (IsBackTrack == true)
{
// 加入track.
this.AddToTrack(ActionType.ReturnAndBackWay, empReturn.UserID, empReturn.Name,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
}
else
{
// 加入track.
this.AddToTrack(ActionType.Return, empReturn.UserID, empReturn.Name,
this.ReturnToNode.NodeID, this.ReturnToNode.Name, Msg);
}
/*try
{
// 记录退回日志. this.HisNode, this.ReturnToNode
ReorderLog(this.ReturnToNode, this.HisNode, rw);
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError(ex.Message);
}*/
// 退回后发送的消息事件
PushMsgs pms = new PushMsgs();
pms.Retrieve(PushMsgAttr.FK_Node, this.ReturnToNode.NodeID, PushMsgAttr.FK_Event, EventListNode.ReturnAfter);
foreach (PushMsg pm in pms)
{
pm.DoSendMessage(this.ReturnToNode, this.HisWork, null, null, null, this.ReturnToEmp);
}
// 把消息
atPara += "@SendToEmpIDs=" + this.ReturnToEmp;
string text = ExecEvent.DoNode(EventListNode.ReturnAfter, this.HisNode, this.HisWork, null, atPara);
if (text == null)
text = "";
if (text != null && text.Length > 1000)
text = "退回事件:无返回信息.";
// 返回退回信息.
if (this.ReturnToNode.IsGuestNode)
{
return "工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + gwf.GuestNo + "," + gwf.GuestName + ").\n\r" + text;
}
else
{
return "工作已经被您退回到(" + this.ReturnToNode.Name + "),退回给(" + empReturn.UserID + "," + empReturn.Name + ").\n\r" + text;
}
}
///
/// 增加日志
///
/// 类型
/// 到人员
/// 到人员名称
/// 到节点
/// 到节点名称
/// 消息
public void AddToTrack(ActionType at, string toEmp, string toEmpName, int toNDid, string toNDName, string msg)
{
Track t = new Track();
t.WorkID = this.WorkID;
t.FK_Flow = this.HisNode.FK_Flow;
t.FID = this.FID;
t.RDT = DataType.CurrentDateTimess;
t.HisActionType = at;
t.NDFrom = this.HisNode.NodeID;
t.NDFromT = this.HisNode.Name;
t.EmpFrom = WebUser.No;
t.EmpFromT = WebUser.Name;
t.FK_Flow = this.HisNode.FK_Flow;
if (toNDid == 0)
{
toNDid = this.HisNode.NodeID;
toNDName = this.HisNode.Name;
}
t.NDTo = toNDid;
t.NDToT = toNDName;
t.EmpTo = toEmp;
t.EmpToT = toEmpName;
t.Msg = msg;
t.Insert();
}
private string infoLog = "";
private void ReorderLog(Node fromND, Node toND, ReturnWork rw)
{
string filePath = BP.Difference.SystemConfig.PathOfDataUser + "ReturnLog/" + this.HisNode.FK_Flow + "/";
if (System.IO.Directory.Exists(filePath) == false)
System.IO.Directory.CreateDirectory(filePath);
string file = filePath + "/" + rw.MyPK;
infoLog = "\r\n退回人:" + WebUser.No + "," + WebUser.Name + " \r\n退回节点:" + fromND.Name + " \r\n退回到:" + toND.Name;
infoLog += "\r\n退回时间:" + DataType.CurrentDateTime;
infoLog += "\r\n原因:" + rw.BeiZhu;
ReorderLog(fromND, toND);
DataType.WriteFile(file + ".txt", infoLog);
DataType.WriteFile(file + ".htm", infoLog.Replace("\r\n", "
"));
// this.HisWork.Delete();
}
private void ReorderLog(Node fromND, Node toND)
{
/*开始遍历到达的节点集合*/
foreach (Node nd in fromND.HisToNodes)
{
Work wk = nd.HisWork;
wk.OID = this.WorkID;
if (wk.RetrieveFromDBSources() == 0)
{
wk.FID = this.WorkID;
if (wk.Retrieve(WorkAttr.FID, this.WorkID) == 0)
continue;
}
if (nd.IsFL)
{
/* 如果是分流 */
GenerWorkerLists wls = new GenerWorkerLists();
QueryObject qo = new QueryObject(wls);
qo.AddWhere(GenerWorkerListAttr.FID, this.WorkID);
qo.addAnd();
string[] ndStrs = nd.HisToNDs.Split('@');
string inStr = "";
foreach (string s in ndStrs)
{
if (DataType.IsNullOrEmpty(s) == true)
continue;
inStr += "'" + s + "',";
}
inStr = inStr.Substring(0, inStr.Length - 1);
if (inStr.Contains(",") == false)
qo.AddWhere(GenerWorkerListAttr.FK_Node, int.Parse(inStr));
else
qo.AddWhereIn(GenerWorkerListAttr.FK_Node, "(" + inStr + ")");
qo.DoQuery();
foreach (GenerWorkerList wl in wls)
{
Node subNd = new Node(wl.FK_Node);
Work subWK = subNd.GetWork(wl.WorkID);
infoLog += "\r\n*****************************************************************************************";
infoLog += "\r\n节点ID:" + subNd.NodeID + " 工作名称:" + subWK.EnDesc;
// infoLog += "\r\n处理人:" + subWK.Rec + " , " + wk.RecOfEmp.Name;
infoLog += "\r\n ------------------------------------------------- ";
foreach (Attr attr in wk.EnMap.Attrs)
{
if (attr.UIVisible == false)
continue;
infoLog += "\r\n " + attr.Desc + ":" + subWK.GetValStrByKey(attr.Key);
}
//递归调用。 //递归调用。 先把此处注释掉 会造成死循环 杨玉慧
//ReorderLog(subNd, toND);
}
}
else
{
infoLog += "\r\n*****************************************************************************************";
infoLog += "\r\n节点ID:" + wk.NodeID + " 工作名称:" + wk.EnDesc;
// infoLog += "\r\n处理人:" + wk.Rec + " , " + wk.RecOfEmp.Name;
infoLog += "\r\n ------------------------------------------------- ";
foreach (Attr attr in wk.EnMap.Attrs)
{
if (attr.UIVisible == false)
continue;
infoLog += "\r\n" + attr.Desc + " : " + wk.GetValStrByKey(attr.Key);
}
}
/* 如果到了当前的节点 */
if (nd.NodeID == toND.NodeID)
break;
//递归调用。 先把此处注释掉 会造成死循环 杨玉慧
//ReorderLog(nd, toND);
}
}
///
/// 递归删除两个节点之间的数据
///
/// 到达的节点集合
public void DeleteToNodesData(Nodes nds)
{
/*开始遍历到达的节点集合*/
foreach (Node nd in nds)
{
Work wk = nd.HisWork;
wk.OID = this.WorkID;
if (wk.Delete() == 0)
{
wk.FID = this.WorkID;
if (wk.Delete(WorkAttr.FID, this.WorkID) == 0)
continue;
}
#region 删除当前节点数据,删除附件信息。
// 删除明细表信息。
MapDtls dtls = new MapDtls("ND" + nd.NodeID);
foreach (MapDtl dtl in dtls)
{
ps = new Paras();
ps.SQL = "DELETE FROM " + dtl.PTable + " WHERE RefPK=" + dbStr + "WorkID";
ps.Add("WorkID", this.WorkID.ToString());
DBAccess.RunSQL(ps);
}
// 删除表单附件信息。
DBAccess.RunSQL("DELETE FROM Sys_FrmAttachmentDB WHERE RefPKVal=" + dbStr + "WorkID AND FK_MapData=" + dbStr + "FK_MapData ",
"WorkID", this.WorkID.ToString(), "FK_MapData", "ND" + nd.NodeID);
// 删除签名信息。
DBAccess.RunSQL("DELETE FROM Sys_FrmEleDB WHERE RefPKVal=" + dbStr + "WorkID AND FK_MapData=" + dbStr + "FK_MapData ",
"WorkID", this.WorkID.ToString(), "FK_MapData", "ND" + nd.NodeID);
#endregion 删除当前节点数据。
/*说明:已经删除该节点数据。*/
DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE (WorkID=" + dbStr + "WorkID1 OR FID=" + dbStr + "WorkID2 ) AND FK_Node=" + dbStr + "FK_Node",
"WorkID1", this.WorkID, "WorkID2", this.WorkID, "FK_Node", nd.NodeID);
if (nd.IsFL)
{
/* 如果是分流 */
GenerWorkerLists wls = new GenerWorkerLists();
QueryObject qo = new QueryObject(wls);
qo.AddWhere(GenerWorkerListAttr.FID, this.WorkID);
qo.addAnd();
string[] ndStrs = nd.HisToNDs.Split('@');
string inStr = "";
foreach (string s in ndStrs)
{
if (DataType.IsNullOrEmpty(s) == true)
continue;
inStr += "'" + s + "',";
}
inStr = inStr.Substring(0, inStr.Length - 1);
if (inStr.Contains(",") == true)
qo.AddWhere(GenerWorkerListAttr.FK_Node, int.Parse(inStr));
else
qo.AddWhereIn(GenerWorkerListAttr.FK_Node, "(" + inStr + ")");
qo.DoQuery();
foreach (GenerWorkerList wl in wls)
{
Node subNd = new Node(wl.FK_Node);
Work subWK = subNd.GetWork(wl.WorkID);
subWK.Delete();
//删除分流下步骤的节点信息.
DeleteToNodesData(subNd.HisToNodes);
}
DBAccess.RunSQL("DELETE FROM WF_GenerWorkFlow WHERE FID=" + dbStr + "WorkID",
"WorkID", this.WorkID);
DBAccess.RunSQL("DELETE FROM WF_GenerWorkerlist WHERE FID=" + dbStr + "WorkID",
"WorkID", this.WorkID);
}
DeleteToNodesData(nd.HisToNodes);
}
}
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);
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.FK_Emp = FK_Emp;
wl.FK_EmpText = emp.Name;
wl.FK_Node = backtoNodeID;
wl.FK_NodeText = nd.Name;
// wl.WarningHour = nd.WarningHour;
wl.FK_Dept = emp.FK_Dept;
wl.FK_DeptT = emp.FK_DeptText;
DateTime dtNew = DateTime.Now;
// dtNew = dtNew.AddDays(nd.WarningHour);
wl.SDT = dtNew.ToString(DataType.SysDateTimeFormat + ":ss"); // DataType.CurrentDateTime;
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";
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.BeiZhu = msg;
try
{
rw.setMyPK(rw.ReturnToNode + "_" + rw.WorkID + "_" + DateTime.Now.ToString("yyyyMMddhhmmss"));
rw.Insert();
}
catch
{
rw.setMyPK(rw.ReturnToNode + "_" + rw.WorkID + "_" + 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 BP.Port.WFEmp(wn.HisWork.Rec);
string title = string.Format("工作退回:流程:{0}.工作:{1},退回人:{2},需您处理",
wn.HisNode.FlowName, wn.HisNode.Name, WebUser.Name);
BP.WF.Dev2Interface.Port_SendMsg(wn.HisWork.Rec, title, msg,
"RESub" + backtoNodeID + "_" + this.WorkID, BP.WF.SMSMsgType.SendSuccess, nd.FK_Flow, nd.NodeID, this.WorkID, this.FID);
}
return wn;
}
}
}