560 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Learun.Util;
using System;
using System.Collections.Generic;
using System.Data;
namespace Learun.Workflow.Engine
{
/// <summary>
/// 版 本 PIT-ADMS V7.0.3 敏捷开发框架
/// Copyright (c) 2013-2018 Hexagon PPM
/// 创建人:研发部
/// 日 期2018.12.10
/// 描 述:工作流引擎
/// </summary>
public class NWFEngine : NWFIEngine
{
#region
public NWFEngine(NWFEngineConfig nWFEngineConfig)
{
// 初始化模板数据
config = nWFEngineConfig;
wfScheme = config.ParamConfig.Scheme.ToObject<NWFScheme>();
nodesMap = new Dictionary<string, NWFNodeInfo>();
foreach (var node in wfScheme.nodes)
{
if (!nodesMap.ContainsKey(node.id))
{
nodesMap.Add(node.id, node);
}
if (node.type == "startround")
{
startNode = node;
}
}
}
#endregion
#region
private NWFEngineConfig config;
private NWFScheme wfScheme = null;
private Dictionary<string, NWFNodeInfo> nodesMap = null;
private NWFNodeInfo startNode = null;
#endregion
#region
/// <summary>
/// 计算条件
/// </summary>
/// <param name="node">节点信息</param>
/// <returns></returns>
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))
{
res = false;
// 流程进程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;
}
/// <summary>
/// 计算会签
/// </summary>
/// <param name="wfNodeInfo">节点信息</param>
/// <param name="preNodeId">上一节点Id</param>
/// <param name="isAgree">同意</param>
/// <returns>0 不做处理 1 通过 -1 不通过</returns>
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<string> 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
/// <summary>
/// 获取流程模板
/// </summary>
/// <returns></returns>
public string GetScheme()
{
return config.ParamConfig.Scheme;
}
/// <summary>
/// 获取流程模板
/// </summary>
/// <returns></returns>
public NWFScheme GetSchemeObj()
{
return wfScheme;
}
/// <summary>
/// 获取开始节点
/// </summary>
/// <returns>节点信息</returns>
public NWFNodeInfo GetStartNode()
{
return startNode;
}
/// <summary>
/// 获取节点
/// </summary>
/// <param name="nodeId">流程处理节点ID</param>
/// <returns>节点信息</returns>
public NWFNodeInfo GetNode(string nodeId)
{
if (nodesMap.ContainsKey(nodeId))
{
return nodesMap[nodeId];
}
else {
return null;
}
}
/// <summary>
/// 获取两节点间的线条
/// </summary>
/// <param name="fromNodeId">开始节点</param>
/// <param name="toNodeId">结束节点</param>
/// <param name="list">线条列表</param>
public bool GetLines(string fromNodeId, string toNodeId, List<NWFLineInfo> list, Dictionary<string, string> nodes = null)
{
bool res = false;
if (nodes == null) {
nodes = new Dictionary<string, string>();
}
foreach (var line in wfScheme.lines)
{
if (line.from == fromNodeId)
{
if (line.to == toNodeId)
{
list.Add(line);
return true;
}
else
{
if (line.to == fromNodeId || nodesMap[line.to] == null || nodesMap[line.to].type == "endround")
{
}
else if (!nodes.ContainsKey(line.to))
{
nodes.Add(line.to,"1");
res = GetLines(line.to, toNodeId, list, nodes);
}
}
if (res) {
list.Add(line);
return true;
}
}
}
return res;
}
/// <summary>
/// 获取下一节点
/// </summary>
/// <param name="nodeId">当前节点Id</param>
/// <param name="code">节点操作码 agree 同意 disagree 不同意 lrtimeout 超时</param>
/// <returns>节点信息列表</returns>
public List<NWFNodeInfo> GetNextNodes(string nodeId, string code, List<NWFLineInfo> lineList)
{
List<NWFNodeInfo> nextNodes = new List<NWFNodeInfo>();
// 找到与当前节点相连的线条
foreach (var line in wfScheme.lines)
{
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;
}
/// <summary>
/// 获取上一节点列表
/// </summary>
/// <param name="nodeId">当前节点Id</param>
/// <returns></returns>
public List<string> GetPreNodes(string nodeId)
{
List<string> list = new List<string>();
// 找到与当前节点相连的线条
foreach (var line in wfScheme.lines)
{
if (line.to == nodeId)
{
list.Add(line.from);
}
}
return list;
}
/// <summary>
/// 判断两节点是否连接
/// </summary>
/// <param name="formNodeId">开始节点</param>
/// <param name="toNodeId">结束节点</param>
/// <returns></returns>
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
/// <summary>
/// 获取配置参数信息
/// </summary>
/// <returns></returns>
public NWFEngineParamConfig GetConfig()
{
return config.ParamConfig;
}
/// <summary>
/// 获取接下来的任务节点信息
/// </summary>
/// <param name="beginNode">起始节点</param>
/// <param name="code">节点操作码 agree 同意 disagree 不同意 lrtimeout 超时</param>
/// <param name="isGetAuditors">是否获取下一节点审核人</param>
/// <param name="lineList">经过的线段需要执行操作的</param>
/// <returns></returns>
public List<NWFNodeInfo> GetNextTaskNode(NWFNodeInfo beginNode, string code, bool isGetAuditors, List<NWFLineInfo> lineList)
{
List<NWFNodeInfo> list = new List<NWFNodeInfo>();
List<NWFNodeInfo> nextNodeList = GetNextNodes(beginNode.id, code, lineList);
Dictionary<string, string> auditers = null;
if (!string.IsNullOrEmpty(config.ParamConfig.Auditers))
{
auditers = config.ParamConfig.Auditers.ToObject<Dictionary<string, string>>();
}
foreach (var node in nextNodeList)
{
if (auditers != null && auditers.ContainsKey(node.id))
{
node.auditors = new List<NWFAuditor>();
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;
}
#endregion
}
}