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