using Learun.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace Learun.Workflow.Engine
{
///
/// 版 本 Learun-ADMS V7.0.3 力软敏捷开发框架
/// Copyright (c) 2013-2018 上海力软信息技术有限公司
/// 创建人:力软-框架开发组
/// 日 期:2018.12.10
/// 描 述:工作流引擎
///
public class NWFEngine : NWFIEngine
{
#region 构造函数
public NWFEngine(NWFEngineConfig nWFEngineConfig)
{
// 初始化模板数据
config = nWFEngineConfig;
wfScheme = config.ParamConfig.Scheme.ToObject();
nodesMap = new Dictionary();
foreach (var node in wfScheme.nodes)
{
if (!nodesMap.ContainsKey(node.id))
{
nodesMap.Add(node.id, node);
}
if (node.type == "startround")
{
startNode = node;
}
if (node.type == "endround")
{
endNode = node;
}
}
}
#endregion
#region 模板数据信息
private NWFEngineConfig config;
private NWFScheme wfScheme = null;
private Dictionary nodesMap = null;
private NWFNodeInfo startNode = null;
private NWFNodeInfo endNode = null;
#endregion
#region 私有方法
///
/// 计算条件
///
/// 节点信息
///
private bool CalcCondition(NWFNodeInfo node)
{
bool res = true;
if (node.conditions.Count > 0)
{
#region 字段条件判断
foreach (var condition in node.conditions)
{
if (!string.IsNullOrEmpty(condition.dbId) && !string.IsNullOrEmpty(condition.table) && !string.IsNullOrEmpty(condition.field1) && !string.IsNullOrEmpty(condition.field2))
{
string sql = "select " + condition.field2 + " from " + condition.table + " where " + condition.field1 + " =@processId ";
DataTable dataTable = config.DbFindTable(condition.dbId, sql, new { processId = config.ParamConfig.ProcessId });
if (dataTable.Rows.Count > 0)
{
string value = dataTable.Rows[0][0].ToString();
if (string.IsNullOrEmpty(value))
{
return false;
}
switch (condition.compareType)//比较类型1.等于2.不等于3.大于4.大于等于5.小于6.小于等于7.包含8.不包含9.包含于10.不包含于
{
case 1:// 等于
if (value != condition.value)
{
res = false;
}
break;
case 2:// 不等于
if (value == condition.value)
{
res = false;
}
break;
case 3:// 大于
if (Convert.ToDecimal(value) <= Convert.ToDecimal(condition.value))
{
res = false;
}
break;
case 4:// 大于等于
if (Convert.ToDecimal(value) < Convert.ToDecimal(condition.value))
{
res = false;
}
break;
case 5:// 小于
if (Convert.ToDecimal(value) >= Convert.ToDecimal(condition.value))
{
res = false;
}
break;
case 6:// 小于等于
if (Convert.ToDecimal(value) > Convert.ToDecimal(condition.value))
{
res = false;
}
break;
case 7:// 包含
if (!value.Contains(condition.value))
{
res = false;
}
break;
case 8:// 不包含
if (value.Contains(condition.value))
{
res = false;
}
break;
case 9:// 包含于
if (!condition.value.Contains(value))
{
res = false;
}
break;
case 10:// 不包含于
if (condition.value.Contains(value))
{
res = false;
}
break;
}
}
else
{
res = false;
}
}
if (!res)
{
break;
}
}
#endregion
}
else if (!string.IsNullOrEmpty(node.conditionSql))
{
// 流程进程ID
string conditionSql = node.conditionSql.Replace("{processId}", "@processId");
// 流程创建人用户
conditionSql = conditionSql.Replace("{userId}", "@userId");
conditionSql = conditionSql.Replace("{userAccount}", "@userAccount");
conditionSql = conditionSql.Replace("{companyId}", "@companyId");
conditionSql = conditionSql.Replace("{departmentId}", "@departmentId");
var param = new
{
processId = config.ParamConfig.ProcessId,
userId = config.ParamConfig.CreateUser.Id,
userAccount = config.ParamConfig.CreateUser.Account,
companyId = config.ParamConfig.CreateUser.CompanyId,
departmentId = config.ParamConfig.CreateUser.DepartmentId,
};
DataTable dataTable = config.DbFindTable(node.dbConditionId, conditionSql, param);
if (dataTable.Rows.Count > 0)
{
res = true;
}
}
else
{
res = true;
}
return res;
}
///
/// 计算会签
///
/// 节点信息
/// 上一节点Id
/// 同意
/// 0 不做处理 1 通过 -1 不通过
private int CalcConfluence(NWFNodeInfo wfNodeInfo, string preNodeId, bool isAgree)
{
int res = 0;
int agreeNum = config.GetAgreeNum(config.ParamConfig.ProcessId, wfNodeInfo.id);
int disAgreeNum = config.GetDisAgreeNum(config.ParamConfig.ProcessId, wfNodeInfo.id);
List preNodeList = GetPreNodes(wfNodeInfo.id);
switch (wfNodeInfo.confluenceType)//会签策略1-所有步骤通过,2-一个步骤通过即可,3-按百分比计算
{
case 1://所有步骤通过
if (isAgree)
{
if (preNodeList.Count == agreeNum + 1)
{
res = 1;
}
}
else
{
res = -1;
}
break;
case 2:
if (isAgree)
{
res = 1;
}
else if (preNodeList.Count == disAgreeNum + 1)
{
res = -1;
}
break;
case 3:
if (isAgree)
{
if ((agreeNum + 1) * 100 / preNodeList.Count >= Convert.ToDecimal(wfNodeInfo.confluenceRate))
{
res = 1;
}
}
else
{
if ((preNodeList.Count - disAgreeNum - 1) * 100 / preNodeList.Count < Convert.ToDecimal(wfNodeInfo.confluenceRate))
{
res = -1;
}
}
break;
}
return res;
}
#endregion
#region 流程模板操作方法
///
/// 获取流程模板
///
///
public string GetScheme()
{
return config.ParamConfig.Scheme;
}
///
/// 获取流程模板
///
///
public NWFScheme GetSchemeObj()
{
return wfScheme;
}
///
/// 获取开始节点
///
/// 节点信息
public NWFNodeInfo GetStartNode()
{
return startNode;
}
///
/// 获取节点
///
/// 流程处理节点ID
/// 节点信息
public NWFNodeInfo GetNode(string nodeId)
{
if (nodesMap.ContainsKey(nodeId))
{
return nodesMap[nodeId];
}
else
{
return null;
}
}
///
/// 获取下一节点
///
/// 当前节点Id
/// 节点操作码 agree 同意 disagree 不同意 lrtimeout 超时
/// 节点信息列表
public List GetNextNodes(string nodeId, string code, List lineList, bool overFW = false)
{
List nextNodes = new List();
//如果lastNode 不为空,直接执行最后一条线的绑定方法 并终止任务
List lineList1=new List();
if (overFW)
{
lineList1.Add(wfScheme.lines.Last());
}
else
{
lineList1 = wfScheme.lines;
}
// 找到与当前节点相连的线条
foreach (var line in lineList1)
{
if (line.from == nodeId)
{
bool isOk = false;
if (string.IsNullOrEmpty(line.strategy) || line.strategy == "1")
{
isOk = true;
}
else
{
var codeList = line.agreeList.Split(',');
foreach (string _code in codeList)
{
if (_code == code)
{
isOk = true;
break;
}
}
}
if (isOk)
{
if (nodesMap.ContainsKey(line.to))
{
nextNodes.Add(nodesMap[line.to]);
switch (line.operationType)
{// 绑定的操作类型
case "sql": // sql 语句
if (!string.IsNullOrEmpty(line.dbId) && !string.IsNullOrEmpty(line.strSql))
{
lineList.Add(line);
}
break;
case "interface": // interface 接口
if (!string.IsNullOrEmpty(line.strInterface))
{
lineList.Add(line);
}
break;
case "ioc": // 依赖注入
if (!string.IsNullOrEmpty(line.iocName))
{
lineList.Add(line);
}
break;
}
}
}
}
}
return nextNodes;
}
///
/// 获取上一节点列表
///
/// 当前节点Id
///
public List GetPreNodes(string nodeId)
{
List list = new List();
// 找到与当前节点相连的线条
foreach (var line in wfScheme.lines)
{
if (line.to == nodeId)
{
list.Add(line.from);
}
}
return list;
}
///
/// 判断两节点是否连接
///
/// 开始节点
/// 结束节点
///
public bool IsToNode(string formNodeId, string toNodeId)
{
bool res = false;
foreach (var line in wfScheme.lines)
{
if (line.from == formNodeId)
{
if (line.to == toNodeId)
{
res = true;
break;
}
else
{
if (line.to == formNodeId || nodesMap[line.to] == null || nodesMap[line.to].type == "endround")
{
break;
}
else
{
if (IsToNode(line.to, toNodeId))
{
res = true;
break;
}
}
}
}
}
return res;
}
#endregion
#region 流程运行操作方法
///
/// 获取配置参数信息
///
///
public NWFEngineParamConfig GetConfig()
{
return config.ParamConfig;
}
///
/// 获取接下来的任务节点信息
///
/// 起始节点
/// 节点操作码 agree 同意 disagree 不同意 lrtimeout 超时
/// 是否获取下一节点审核人
/// 经过的线段需要执行操作的
///
public List GetNextTaskNode(NWFNodeInfo beginNode, string code, bool isGetAuditors, List lineList, bool overWF = false)
{
List list = new List();
List nextNodeList = new List();
nextNodeList = GetNextNodes(beginNode.id, code, lineList, overWF);
Dictionary auditers = null;
if (!string.IsNullOrEmpty(config.ParamConfig.Auditers))
{
auditers = config.ParamConfig.Auditers.ToObject>();
}
foreach (var node in nextNodeList)
{
if (auditers != null && auditers.ContainsKey(node.id))
{
node.auditors = new List();
node.auditors.Add(new NWFAuditor()
{
type = 3,
auditorId = auditers[node.id]
});
}
switch (node.type)
{
case "conditionnode": // 条件节点
if (!isGetAuditors)
{
if (CalcCondition(node))
{
list.AddRange(GetNextTaskNode(node, "agree", isGetAuditors, lineList));
}
else
{
list.AddRange(GetNextTaskNode(node, "disagree", isGetAuditors, lineList));
}
}
else
{
list.AddRange(GetNextTaskNode(node, "agree", isGetAuditors, lineList));
list.AddRange(GetNextTaskNode(node, "disagree", isGetAuditors, lineList));
}
break;
case "confluencenode":// 会签节点
if (!isGetAuditors)
{
int confluenceRes;
if (code == "agree")
{
confluenceRes = CalcConfluence(node, beginNode.id, true);
}
else
{
confluenceRes = CalcConfluence(node, beginNode.id, false);
}
if (confluenceRes == 1)// 会签审核通过
{
list.AddRange(GetNextTaskNode(node, "agree", false, lineList));
}
else if (confluenceRes == -1)// 会签审核不通过
{
list.AddRange(GetNextTaskNode(node, "disagree", false, lineList));
}
node.confluenceRes = confluenceRes;
list.Add(node);
}
break;
case "auditornode":// 传阅节点
list.Add(node);
break;
case "childwfnode":// 子流程节点
list.Add(node);
if (node.childType == "2")
{ // 异步的情况下直接往下走
list.AddRange(GetNextTaskNode(node, "agree", isGetAuditors, lineList));
}
break;
case "startround":// 开始节点 需要重新审核
list.Add(node);
config.ParamConfig.State = 1;
break;
case "endround":// 结束节点
config.ParamConfig.State = 2;
break;
default: // 默认一般审核界定啊
list.Add(node);
break;
}
}
return list;
}
///
/// 获取上一步的任务节点信息(只有审批操作码为back(退回至上一个审核节点)情况下执行)【暂定】
///
/// 起始节点
/// 节点操作码 agree 同意 disagree 不同意 lrtimeout 超时 back 退回至上一个审核节点
/// 是否获取下一节点审核人
/// 经过的线段需要执行操作的
///
public List GetPrevTaskNode(NWFNodeInfo beginNode, string code, bool isGetAuditors, List lineList, bool overWF = false)
{
List list = new List();
List nextNodeList = new List();
//nextNodeList = GetNextNodes(beginNode.id, code, lineList, overWF);
var prevNodes = GetPreNodes(beginNode.id);
foreach (var item in prevNodes)
{
var prevNode = GetNode(item);
nextNodeList.Add(prevNode);
}
Dictionary auditers = null;
if (!string.IsNullOrEmpty(config.ParamConfig.Auditers))
{
auditers = config.ParamConfig.Auditers.ToObject>();
}
foreach (var node in nextNodeList)
{
if (auditers != null && auditers.ContainsKey(node.id))
{
node.auditors = new List();
node.auditors.Add(new NWFAuditor()
{
type = 3,
auditorId = auditers[node.id]
});
}
switch (node.type)
{
case "conditionnode": // 条件节点
if (!isGetAuditors)
{
if (CalcCondition(node))
{
list.AddRange(GetPrevTaskNode(node, "agree", isGetAuditors, lineList));
}
else
{
list.AddRange(GetPrevTaskNode(node, "disagree", isGetAuditors, lineList));
}
}
else
{
list.AddRange(GetPrevTaskNode(node, "agree", isGetAuditors, lineList));
list.AddRange(GetPrevTaskNode(node, "disagree", isGetAuditors, lineList));
}
break;
case "confluencenode":// 会签节点
if (!isGetAuditors)
{
int confluenceRes;
if (code == "agree")
{
confluenceRes = CalcConfluence(node, beginNode.id, true);
}
else
{
confluenceRes = CalcConfluence(node, beginNode.id, false);
}
if (confluenceRes == 1)// 会签审核通过
{
list.AddRange(GetPrevTaskNode(node, "agree", false, lineList));
}
else if (confluenceRes == -1)// 会签审核不通过
{
list.AddRange(GetPrevTaskNode(node, "disagree", false, lineList));
}
node.confluenceRes = confluenceRes;
list.Add(node);
}
break;
case "auditornode":// 传阅节点
list.Add(node);
break;
case "childwfnode":// 子流程节点
list.Add(node);
if (node.childType == "2")
{ // 异步的情况下直接往下走
list.AddRange(GetPrevTaskNode(node, "agree", isGetAuditors, lineList));
}
break;
case "startround":// 开始节点 需要重新审核
list.Add(node);
config.ParamConfig.State = 1;
break;
case "endround":// 结束节点
config.ParamConfig.State = 2;
break;
default: // 默认一般审核界定啊
list.Add(node);
break;
}
}
return list;
}
#endregion
}
}