You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

510 lines
20 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Data;
using BP.DA;
using BP.Web;
using BP.En;
using BP.Sys;
namespace BP.WF.DTS
{
/// <summary>
/// Method 的摘要说明
/// </summary>
public class AutoRunStratFlows : Method
{
/// <summary>
/// 不带有参数的方法
/// </summary>
public AutoRunStratFlows()
{
this.Title = "自动启动流程";
this.Help = "在流程属性上配置的信息,自动发起流程,按照时间规则....";
this.GroupName = "流程自动执行定时任务";
}
/// <summary>
/// 设置执行变量
/// </summary>
/// <returns></returns>
public override void Init()
{
}
/// <summary>
/// 当前的操纵员是否可以执行这个方法
/// </summary>
public override bool IsCanDo
{
get
{
return true;
}
}
/// <summary>
/// 执行
/// </summary>
/// <returns>返回执行结果</returns>
public override object Do()
{
BP.WF.Flows fls = new Flows();
fls.RetrieveAll();
string msg = "开始执行自动发起流程 :" + DataType.CurrentDateTimess;
DateTime dt = DateTime.Now;
int week = (int)dt.DayOfWeek;
week++;
#region 自动启动流程
foreach (BP.WF.Flow fl in fls)
{
if (fl.HisFlowRunWay == BP.WF.FlowRunWay.HandWork)
continue;
msg += "<br>扫描:" + fl.Name;
#region 高级设置模式,是否达到启动的时间点?
if (fl.HisFlowRunWay == FlowRunWay.SpecEmpAdv || fl.HisFlowRunWay == FlowRunWay.SpecEmp)
{
string currTime = DataType.CurrentDateTime; //2022-09-01 09:10
string[] strs = null;
if (fl.HisFlowRunWay == FlowRunWay.SpecEmp)
strs = fl.RunObj.Split('@');
if (fl.HisFlowRunWay == FlowRunWay.SpecEmpAdv)
strs = fl.StartGuidePara2.Split('@'); //@11:15@12:15
bool isHave = false; //是否可以执行.
foreach (string s in strs)
{
if (DataType.IsNullOrEmpty(s) == true)
continue;
// 去除首尾空格
string str = s.Trim().Clone() as string;
//如果有周.
if (str.Contains("Week.") == true)
{
if (str.Contains("Week.1") == true && dt.DayOfWeek != DayOfWeek.Monday)
continue;
if (str.Contains("Week.2") == true && dt.DayOfWeek != DayOfWeek.Tuesday)
continue;
if (str.Contains("Week.3") == true && dt.DayOfWeek != DayOfWeek.Wednesday)
continue;
if (str.Contains("Week.4") == true && dt.DayOfWeek != DayOfWeek.Thursday)
continue;
if (str.Contains("Week.5") == true && dt.DayOfWeek != DayOfWeek.Friday)
continue;
if (str.Contains("Week.6") == true && dt.DayOfWeek != DayOfWeek.Saturday)
continue;
if (str.Contains("Week.7") == true && dt.DayOfWeek != DayOfWeek.Sunday)
continue;
str = str.Replace("Week.1", "");
str = str.Replace("Week.2", "");
str = str.Replace("Week.3", "");
str = str.Replace("Week.4", "");
str = str.Replace("Week.5", "");
str = str.Replace("Week.6", "");
str = str.Replace("Week.7", "");
str = str.Trim();
}
//是否每月的最后一天?
if (str.Contains("LastDayOfMonth") == true)
{
//获得当前月份有多少天.
int days = DateTime.DaysInMonth(dt.Year, dt.Month);
if (dt.Day != days)
continue;
str = str.Replace("LastDayOfMonth", "").Trim();
}
//如果自动发起流程过多,会延迟判断时间点,要补偿自动发起
if (!str.Contains(":"))
continue;
// 逻辑修正, 不包含: 不执行,不用再判断:
//是不是到时间了?
//if (str.Contains(":"))
//{
int i = str.Length;
string currTime01 = currTime.Substring(currTime.Length - i);
DateTime dt1 = Convert.ToDateTime(str);
DateTime dt2 = Convert.ToDateTime(currTime01);
if (DateTime.Compare(dt1, dt2) > 0) continue;
//}
//记录执行过的时间点,如果有该时间点,就不要在执行了。
// 这里的时间点是有问题的,之前是根据当前时刻计算,其实是不对的。
// 应该根据设定的时间保存时刻。
string pkval = "";
//是按照一天的时间点计算的.
if (s.Contains("LastDayOfMonth")) // 月度任务
pkval = "AutoFlow_" + fl.No + "_" + dt1.ToString("yyyyMM") + str;
else if (s.Contains("Week.")) //按周计算.
pkval = "AutoFlow_" + fl.No + "_" + dt1.ToString("yyyyMMdd") + dt.DayOfWeek + str;
else if (str.Length <= 6)
pkval = "AutoFlow_" + fl.No + "_" + dt1.ToString("yyyyMMdd") + str;
else
BP.DA.Log.DebugWriteError("不合法的发起规则: " + s);
BP.Sys.GloVar gv = new GloVar
{
No = pkval
};
if (gv.RetrieveFromDBSources() == 0)
{
gv.Name = fl.Name + "自动发起.";
gv.GroupKey = "AutoStartFlow";
gv.Insert();
BP.DA.Log.DebugWriteInfo("任务发起:" + gv.Name + ", No: " + gv.No);
isHave = true; //可以执行.
break;
}
}
if (isHave == false)
continue;
}
#endregion 高级设置模式,是否达到启动的时间点?
// 以此用户进入.
switch (fl.HisFlowRunWay)
{
case BP.WF.FlowRunWay.SpecEmp: //指定人员按时运行。
msg += "<br>触发了:指定人员按时运行.";
this.SpecEmp(fl);
continue;
case BP.WF.FlowRunWay.SelectSQLModel: //按数据集合驱动的模式执行。
this.SelectSQLModel(fl);
continue;
case BP.WF.FlowRunWay.WF_TaskTableInsertModel: //按数据集合驱动的模式执行。
this.WF_TaskTableInsertModel(fl);
continue;
case BP.WF.FlowRunWay.SpecEmpAdv: //指定人员按时运行 高级模式.。
msg += "<br>触发了:指定人员按时运行 高级模式.";
msg += this.SpecEmpAdv(fl);
continue;
case BP.WF.FlowRunWay.LetAdminSendSpecEmp: //让admin发送给指定的人员.。
msg += "<br>触发了:指定人员按时运行 高级模式.";
msg += this.LetAdminSendSpecEmp(fl);
continue;
default:
break;
}
}
if (BP.Web.WebUser.No != "admin")
{
BP.Port.Emp empadmin = new BP.Port.Emp("admin");
BP.Web.WebUser.SignInOfGener(empadmin);
}
#endregion 发送消息
return msg;
}
public void SpecEmp(Flow fl)
{
string RunObj = fl.RunObj;
string fk_emp = RunObj.Substring(0, RunObj.IndexOf('@'));
BP.Port.Emp emp = new BP.Port.Emp();
emp.UserID = fk_emp;
if (emp.RetrieveFromDBSources() == 0)
{
BP.DA.Log.DebugWriteError("启动自动启动流程错误:发起人(" + fk_emp + ")不存在。");
return;
}
try
{
//让 userNo 登录.
BP.WF.Dev2Interface.Port_Login(emp.UserID);
//创建空白工作, 发起开始节点.
Int64 workID = BP.WF.Dev2Interface.Node_CreateBlankWork(fl.No);
//执行发送.
SendReturnObjs objs = BP.WF.Dev2Interface.Node_SendWork(fl.No, workID);
//string info_send= BP.WF.Dev2Interface.Node_StartWork(fl.No,);
BP.DA.Log.DebugWriteInfo("流程:" + fl.No + fl.Name + "的定时任务\t\n -------------- \t\n" + objs.ToMsgOfText());
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError("流程:" + fl.No + fl.Name + "自动发起错误:\t\n -------------- \t\n" + ex.Message);
}
}
public string LetAdminSendSpecEmp(Flow fl)
{
string empsExp = fl.StartGuidePara1; //获得人员信息。
if (DataType.IsNullOrEmpty(empsExp) == true)
return "配置的表达式错误:StartGuidePara1人员信息不能为空。";
#region 获得人员集合.
string[] emps = null;
if (empsExp.ToUpper().Contains("SELECT") == true)
{
string strs = "";
empsExp = BP.WF.Glo.DealExp(empsExp, null, null);
DataTable dt = DBAccess.RunSQLReturnTable(empsExp);
foreach (DataRow dr in dt.Rows)
{
strs += dr[0].ToString() + ";";
}
emps = strs.Split(';');
}
else
{
empsExp = empsExp.Replace("@", ";");
empsExp = empsExp.Replace(",", ";");
empsExp = empsExp.Replace("、", ";");
empsExp = empsExp.Replace("", ";");
emps = empsExp.Split(';');
}
#endregion 获得人员集合.
//让admin登录发送.
BP.WF.Dev2Interface.Port_Login("admin");
string msg = "";
try
{
//创建空白工作, 发起开始节点.
Int64 workID = BP.WF.Dev2Interface.Node_CreateBlankWork(fl.No);
BP.WF.Dev2Interface.Node_SendWork(fl.No, workID, 0, empsExp);
string info = "流程:【" + fl.No + fl.Name + "】的定时任务 \t\n -------------- \t\n 已经启动,待办:" + empsExp + " , " + workID;
BP.DA.Log.DebugWriteInfo(info);
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError("流程:" + fl.No + fl.Name + "自动发起错误:\t\n -------------- \t\n" + ex.Message);
}
return msg;
}
/// <summary>
/// 指定人员按时启动高级模式
/// </summary>
/// <param name="fl">流程</param>
/// <returns></returns>
public string SpecEmpAdv(Flow fl)
{
string empsExp = fl.StartGuidePara1; //获得人员信息。
if (DataType.IsNullOrEmpty(empsExp) == true)
return "配置的表达式错误:StartGuidePara1人员信息不能为空。";
#region 获得人员集合.
string[] emps = null;
if (empsExp.ToUpper().Contains("SELECT") == true)
{
string strs = "";
empsExp = BP.WF.Glo.DealExp(empsExp, null, null);
DataTable dt = DBAccess.RunSQLReturnTable(empsExp);
foreach (DataRow dr in dt.Rows)
{
strs += dr[0].ToString() + ";";
}
emps = strs.Split(';');
BP.DA.Log.DebugWriteInfo("strs:" + strs);
}
else
{
empsExp = empsExp.Replace("@", ";");
empsExp = empsExp.Replace(",", ";");
empsExp = empsExp.Replace("、", ";");
empsExp = empsExp.Replace("", ";");
emps = empsExp.Split(';');
}
#endregion 获得人员集合.
string msg = "";
int idx = 0;
foreach (string emp in emps)
{
if (DataType.IsNullOrEmpty(emp) == true)
continue;
try
{
//让 emp 登录.
BP.WF.Dev2Interface.Port_Login(emp);
//创建空白工作, 发起开始节点.
Int64 workID = BP.WF.Dev2Interface.Node_CreateBlankWork(fl.No);
//执行发送.
SendReturnObjs objs = BP.WF.Dev2Interface.Node_SendWork(fl.No, workID);
string info = "流程:" + fl.No + fl.Name + "的定时任务\t\n -------------- \t\n 已经启动,待办:" + emp + " , " + workID;
BP.DA.Log.DebugWriteInfo(info);
idx++;
msg += "<br/>第" + idx + "条:" + info;
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError("流程:" + fl.No + fl.Name + "自动发起错误:\t\n -------------- \t\n" + ex.Message);
}
}
return msg;
}
/// <summary>
/// 触发模式
/// </summary>
/// <param name="fl"></param>
public void WF_TaskTableInsertModel(BP.WF.Flow fl)
{
}
public void SelectSQLModel(BP.WF.Flow fl)
{
#region 读取数据.
BP.Sys.MapExt me = new MapExt();
me.setMyPK(MapExtXmlList.StartFlow + "_ND" + int.Parse(fl.No) + "01");
int i = me.RetrieveFromDBSources();
if (i == 0)
return;
if (BP.DA.DataType.IsNullOrEmpty(me.Tag))
{
BP.DA.Log.DebugWriteError("没有为流程(" + fl.Name + ")的开始节点设置发起数据,请参考说明书解决.");
return;
}
#endregion 读取数据.
#region 检查数据源是否正确.
string errMsg = "";
// 获取主表数据.
DataTable dtMain = DBAccess.RunSQLReturnTable(me.Tag);
if (dtMain.Rows.Count == 0)
{
BP.DA.Log.DebugWriteError("流程(" + fl.Name + ")此时无任务.");
return;
}
if (dtMain.Columns.Contains("Starter") == false)
errMsg += "@配值的主表中没有Starter列.";
if (dtMain.Columns.Contains("MainPK") == false)
errMsg += "@配值的主表中没有MainPK列.";
if (errMsg.Length > 2)
{
BP.DA.Log.DebugWriteError("流程(" + fl.Name + ")的开始节点设置发起数据,不完整." + errMsg);
return;
}
#endregion 检查数据源是否正确.
#region 处理流程发起.
string frmID = "ND" + int.Parse(fl.No) + "01";
string err = "";
int idx = 0;
foreach (DataRow dr in dtMain.Rows)
{
idx++;
string mainPK = dr["MainPK"].ToString();
string sql = "SELECT OID FROM " + fl.PTable + " WHERE MainPK='" + mainPK + "'";
if (DBAccess.RunSQLReturnTable(sql).Rows.Count != 0)
{
continue; /*说明已经调度过了*/
}
string starter = dr["Starter"].ToString();
if (WebUser.No != starter)
{
BP.Web.WebUser.Exit();
BP.Port.Emp emp = new BP.Port.Emp();
emp.UserID = starter;
if (emp.RetrieveFromDBSources() == 0)
{
BP.DA.Log.DebugWriteInfo("@数据驱动方式发起流程(" + fl.Name + ")设置的发起人员:" + starter + "不存在。");
continue;
}
WebUser.SignInOfGener(emp);
}
#region 给值.
//System.Collections.Hashtable ht = new Hashtable();
//创建workid.
Int64 workID = BP.WF.Dev2Interface.Node_CreateBlankWork(fl.No, null, null, starter, null);
//创建工作.
GEEntity wk = new GEEntity(frmID, workID);
// Work wk = fl.NewWork();
//给主表赋值.
foreach (DataColumn dc in dtMain.Columns)
wk.SetValByKey(dc.ColumnName, dr[dc.ColumnName].ToString());
// 获取从表数据.
DataSet ds = new DataSet();
string[] dtlSQLs = me.Tag1.Split('*');
foreach (string sqlDtl in dtlSQLs)
{
if (DataType.IsNullOrEmpty(sqlDtl))
continue;
//替换变量.
string mySqlDtl = sqlDtl.Replace("@MainPK", mainPK);
string[] tempStrs = mySqlDtl.Split('=');
string dtlName = tempStrs[0];
DataTable dtlTable = DBAccess.RunSQLReturnTable(mySqlDtl.Replace(dtlName + "=", ""));
dtlTable.TableName = dtlName;
ds.Tables.Add(dtlTable);
}
#endregion 给值.
#region 取出约定的到达人员.
int toNodeID = 0;
try
{
toNodeID = int.Parse(dr["ToNode"].ToString());
}
catch
{
/*有可能在4.5以前的版本中没有tonode这个约定.*/
}
string toEmps = null;
try
{
toEmps = dr["ToEmps"].ToString();
}
catch
{
/*有可能在4.5以前的版本中没有tonode这个约定.*/
}
#endregion 取出约定的到达人员.
// 处理发送信息.
// Node nd =new Node();
string msg = "";
try
{
//执行发送到下一个节点.
SendReturnObjs objs = BP.WF.Dev2Interface.Node_SendWork(fl.No, workID, wk.Row, ds, toNodeID, toEmps);
msg = "@自动发起:" + mainPK + "第" + idx + "条: - " + objs.MsgOfText;
BP.DA.Log.DebugWriteInfo(msg);
}
catch (Exception ex)
{
BP.DA.Log.DebugWriteError("@" + fl.Name + ",第" + idx + "条,发起人员:" + WebUser.No + "-" + WebUser.Name + "发起时出现错误.\r\n" + ex.Message);
}
}
#endregion 处理流程发起.
}
}
}