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.

1107 lines
44 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 Infrastructure;
using Infrastructure.Extensions;
using Newtonsoft.Json;
using OpenAuth.App.Config;
using OpenAuth.Repository.Domain;
using SqlSugar;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OpenAuth.App
{
public class WFEngine : IWFEngine
{
ISqlSugarClient client;
//private RepositoryFactory dbFactory { get; set; }
/// <summary>
/// 流程配置信息
/// </summary>
private WFEngineConfig _config { get; set; }
/// <summary>
/// 流程模板
/// </summary>
private WorkFlow.WFScheme _wfScheme { get; set; }
/// <summary>
/// 流程单元对应字典
/// </summary>
private Dictionary<string, WFUnit> _dicUnit { get; set; }
/// <summary>
/// 开始节点
/// </summary>
private WFUnit _startNode { get; set; }
/// <summary>
/// 线条集合
/// </summary>
private List<WFUnit> _lines { get; set; }
#region 构造函数
/// <summary>
/// 构造方法
/// </summary>
/// <param name="config">流程参数</param>
public WFEngine(WFEngineConfig config, ISqlSugarClient sqlSugarClient)
{
// 初始化模板数据
_config = config;
_wfScheme = ToObject<WorkFlow.WFScheme>(_config.Params.Scheme);
//_wfScheme = Newtonsoft.Json.JsonConvert.DeserializeObject<WorkFlow.WFScheme>(_config.Params.Scheme);
//_wfScheme = ExtensionsJson.ToObject<WorkFlow.WFScheme>(_config.Params.Scheme);
_dicUnit = new Dictionary<string, WFUnit>();
_lines = new List<WFUnit>();
foreach (var unit in _wfScheme.WfData)
{
if (!_dicUnit.ContainsKey(unit.Id))
{
_dicUnit.Add(unit.Id, unit);
}
else
{
continue;
}
if (unit.Type == NodeTypeEnum.startEvent.GetDescription())
{
_startNode = unit;
}
else if (unit.Type == NodeTypeEnum.myline.GetDescription())
{
_lines.Add(unit);
}
}
client = sqlSugarClient;
//dbFactory = new RepositoryFactory();
}
#endregion
public T ToObject<T>(string Json)
{
return (T)((Json == null) ? ((object)default(T)) : ((object)JsonConvert.DeserializeObject<T>(Json)));
}
/// <summary>
/// 流程运行参数
/// </summary>
public WFEngineConfig Config => _config;
/// <summary>
/// 开始节点
/// </summary>
public WFUnit StartNode => _startNode;
/// <summary>
/// 流程发起用户
/// </summary>
public WFUserInfo CreateUser => _config.Params.CreateUser;
/// <summary>
/// 流程发起用户
/// </summary>
public WFUserInfo CurrentUser => _config.Params.CurrentUser;
/// <summary>
/// 流程配置信息
/// </summary>
public WorkFlow.WFScheme WFScheme => _wfScheme;
/// <summary>
/// 获取流程单元信息
/// </summary>
/// <param name="id">id</param>
/// <returns>流程单元信息</returns>
public WFUnit GetNode(string id)
{
if (_dicUnit.ContainsKey(id))
{
return _dicUnit[id];
}
else
{
return null;
}
}
/// <summary>
/// 获取下一节点集合
/// </summary>
/// <param name="startId">开始节点</param>
/// <param name="code">执行动作编码</param>
/// <returns></returns>
public List<WFUnit> GetNextUnits(string startId, string code = "")
{
List<WFUnit> nextUnits = new List<WFUnit>();
// 找到与当前节点相连的线条
foreach (var line in _lines)
{
if (line.From == startId)
{
// 获取连接到开始节点的线条
bool isOk = false;
if (string.IsNullOrEmpty(line.LineConditions))
{
isOk = true;
}
else if (!string.IsNullOrEmpty(code))
{
var codeList = line.LineConditions.Split(',');
foreach (string _code in codeList)
{
if (_code == code)
{
isOk = true;
break;
}
}
}
else
{ //没有执行码就是全部执行
isOk = true;
}
// 获取到流入节点
if (isOk)
{
if (_dicUnit.ContainsKey(line.To) && nextUnits.Find(t => t.Id == line.To) == null)
{
nextUnits.Add(_dicUnit[line.To]);
}
}
}
}
return nextUnits;
}
/// <summary>
/// 获取下一节点集合
/// </summary>
/// <param name="startId">开始节点</param>
/// <param name="codeList">条件编码</param>
/// <returns></returns>
public List<WFUnit> GetNextUnits(string startId, List<string> codeList)
{
List<WFUnit> nextUnits = new List<WFUnit>();
// 找到与当前节点相连的线条
foreach (var line in _lines)
{
if (line.From == startId)
{
// 获取连接到开始节点的线条
bool isOk = false;
if (codeList.Count > 0 && !string.IsNullOrEmpty(line.LineConditions))
{
var codeList2 = line.LineConditions.Split(',');
foreach (string _code in codeList2)
{
if (codeList.FindIndex(t => t == _code) != -1)
{
isOk = true;
break;
}
}
}
// 获取到流入节点
if (isOk)
{
if (_dicUnit.ContainsKey(line.To) && nextUnits.Find(t => t.Id == line.To) == null)
{
nextUnits.Add(_dicUnit[line.To]);
}
}
}
}
return nextUnits;
}
/// <summary>
/// 获取下一节点集合(流转条件为空的情况)
/// </summary>
/// <param name="startId">开始节点</param>
/// <returns></returns>
public List<WFUnit> GetNextUnitsNoSet(string startId)
{
List<WFUnit> nextUnits = new List<WFUnit>();
// 找到与当前节点相连的线条
foreach (var line in _lines)
{
if (line.From == startId)
{
// 获取到流入节点
if (string.IsNullOrEmpty(line.LineConditions))
{
if (_dicUnit.ContainsKey(line.To) && nextUnits.Find(t => t.Id == line.To) == null)
{
nextUnits.Add(_dicUnit[line.To]);
}
}
}
}
return nextUnits;
}
/// <summary>
/// 获取上一单元ID列表
/// </summary>
/// <param name="myUnitId">当前节点Id</param>
/// <returns></returns>
public List<string> GetPreUnitIds(string myUnitId)
{
List<string> list = new List<string>();
// 找到与当前节点相连的线条
foreach (var line in _lines)
{
if (line.To == myUnitId && list.Find(t => t == line.From) == null)
{
list.Add(line.From);
}
}
return list;
}
/// <summary>
/// 获取任务
/// </summary>
/// <param name="startId">开始节点</param>
/// <param name="code">执行动作编码</param>
/// <param name="toUnitId">下一个指定节点</param>
/// <returns></returns>
public async Task<List<WorkFlow.WFTask>> GetTask(string startId, string code = "", string toUnitId = "")
{
bool isIsReject = code == "disagree";
var nextUnits = GetNextUnits(startId, code);
if (!string.IsNullOrEmpty(toUnitId))
{
nextUnits = nextUnits.FindAll(t => t.Type == "bpmn:ScriptTask");// 只保留脚本节点
nextUnits.Add(GetNode(toUnitId));
}
// 如果无法获取下一个审核任务且是驳回操作,就返回到之前流转过来的任务(除去通过驳回流转过来的)(需要过滤掉脚本节点)
if (nextUnits.FindAll(t => t.Type != "bpmn:ScriptTask").Count == 0 && isIsReject)
{
// 获取当前节点的
var prevUnitId = await Config.GetPrevUnitId(Config.Params.ProcessId, startId);
if (!string.IsNullOrEmpty(prevUnitId))
{
nextUnits.Add(GetNode(prevUnitId));
}
}
var list = await GetTask(nextUnits, isIsReject, startId);
foreach (var item in list)
{
item.PrevUnitId = startId;
}
return list;
}
/// <summary>
/// 获取任务
/// </summary>
/// <param name="nextUnits">下一个节点集合</param>
/// <param name="isReject">是否驳回</param>
/// <param name="startId">开始节点</param>
/// <returns></returns>
public async Task<List<WorkFlow.WFTask>> GetTask(List<WFUnit> nextUnits, bool isReject, string startId)
{
WFUnit startUnit = _dicUnit[startId];
if (startUnit.Type == NodeTypeEnum.startEvent.GetDescription() && string.IsNullOrEmpty(startUnit.Name))
{
startUnit.Name = "开始节点";
}
List<WorkFlow.WFTask> taskList = new List<WorkFlow.WFTask>();
foreach (var unit in nextUnits)
{
switch (unit.Type)
{
//case "startEvent":// 开始节点
case "bpmn:StartEvent":// 开始节点
taskList.Add(GetStartTask(unit, isReject, startId, startUnit.Name));
break;
//case "gatewayAnd":
case "bpmn:ParallelGateway":
// 并行网关会等待所有分支汇入才往下执行,所有出口分支都会被执行
// 判断是否所有分支都被执行了
// 1.或去此节点所有上节点
// 2.生成一个等待任务
// 3.获取所有该节点当前等待任务
// 4.判断是否完成获取下一节点
var preIdList = GetPreUnitIds(unit.Id);
if (preIdList.Count <= 1)
{
taskList.AddRange(await GetTask(unit.Id));
}
else
{
var awaitTaskList = await Config.GetAwaitTaskList(Config.Params.ProcessId, unit.Id);
var awaitTaskList2 = awaitTaskList.FindAll(t => t.PrevUnitId != startId); // 排除当前等待任务的所有等待任务
if (awaitTaskList2.Count + 1 >= preIdList.Count)
{
// 如果所有支路都被执行了就生成一个取消所有等待任务的命令
taskList.Add(GetDeleteAwaitTask(unit, isReject, startId, startUnit.Name));
taskList.AddRange(await GetTask(unit.Id));
}
else
{
taskList.Add(GetAwaitTask(unit, isReject, startId, startUnit.Name));
}
}
break;
//case "gatewayXor":
case "bpmn:ExclusiveGateway":
// 排他网关不会等待所有分支汇入才往下执行只要有分支汇入就会往下执行出口分支只会执行一条条件为true如果多条出口分支条件为true也执行一条
// 1.获取当前节点的true条件如果成立条件为0就执行人默认没有条件的线条
// 2.获取下一个节点
var conditionCodes = await GetConditionIds(unit.Conditions);
var nextUnits2 = GetNextUnits(unit.Id, conditionCodes);
if (nextUnits2.Count == 0)
{
nextUnits2 = GetNextUnitsNoSet(unit.Id);
}
if (nextUnits2.Count == 0)
{
throw new Exception(string.Format("无法获取下一节点【{0}】", unit.Id));
}
else
{
var nextUnits3 = new List<WFUnit>();
nextUnits3.Add(nextUnits2[0]);
taskList.AddRange(await GetTask(nextUnits3, isReject, unit.Id));
}
break;
//case "gatewayInclusive":
case "bpmn:InclusiveGateway":
// 包容网关会等待所有分支汇入才往下执行出口分支能执行多条条件为true
bool isNext = false;
var preIdList2 = GetPreUnitIds(unit.Id);
if (preIdList2.Count <= 1)
{
isNext = true;
}
else
{
var awaitTaskList = await Config.GetAwaitTaskList(Config.Params.ProcessId, unit.Id);
var awaitTaskList2 = awaitTaskList.FindAll(t => t.PrevUnitId != startId); // 排除当前等待任务的所有等待任务
if (awaitTaskList2.Count + 1 >= preIdList2.Count)
{
// 如果所有支路都被执行了就生成一个取消所有等待任务的命令
taskList.Add(GetDeleteAwaitTask(unit, isReject, startId, startUnit.Name));
isNext = true;
}
else
{
taskList.Add(GetAwaitTask(unit, isReject, startId, startUnit.Name));
}
}
if (isNext)
{
var conditionCodes2 = await GetConditionIds(unit.Conditions);
var nextUnits3 = GetNextUnits(unit.Id, conditionCodes2);
nextUnits3.AddRange(GetNextUnitsNoSet(unit.Id));
taskList.AddRange(await GetTask(nextUnits3, isReject, unit.Id));
}
break;
//case "userTask":// 审批节点
case "bpmn:Task":// 审批节点
// 1.获取节点上一次的请求人
var preAuditUsers = await Config.GetPrevTaskUserList(Config.Params.ProcessId, unit.Id);
if (preAuditUsers.FindIndex(t => t.State == 1) != -1)
{
// 如果此节点被激活不需要审核
break;
}
var auditUsers = new List<WFUserInfo>();
if (preAuditUsers.Count == 0)
{
// 表示此节点未被处理过
// 获取审核人
if (Config.Params.NextUsers != null && Config.Params.NextUsers.ContainsKey(unit.Id))
{
var auditUserList = new List<WFAuditor>();
var strAuditUser = Config.Params.NextUsers[unit.Id];
var strAuditUserList = strAuditUser.Split(",");
foreach (var id in strAuditUserList)
{
auditUserList.Add(new WFAuditor()
{
Type = "3",
Id = id
});
}
auditUsers = await Config.GetUserList(auditUserList, CreateUser, Config.Params.ProcessId, _startNode);
}
else
{
auditUsers = await Config.GetUserList(unit.AuditUsers, CreateUser, Config.Params.ProcessId, _startNode);
}
// 添加传阅任务,节点第一次执行的时候触发
var lookUsers = await Config.GetUserList(unit.LookUsers, CreateUser, Config.Params.ProcessId, _startNode);
taskList.AddRange(GetLookUserTaskList(unit, lookUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString()));
}
else
{
// 添加一条任务用于更新之前任务状态(将之前的任务设置成不是最近的一次任务)
taskList.Add(GetUpdateTask(unit));
}
// 表示找不到审核人
if (preAuditUsers.Count == 0 && auditUsers.Count == 0)
{
switch (unit.NoAuditor)
{
case "1":
taskList.AddRange(GetUserTaskList(unit, await Config.GetSystemUserList(), isReject, startId, startUnit.Name, Guid.NewGuid().ToString()));
break;
case "2":
// 流转到下一个节点
taskList.Add(GetSkipTask(unit, isReject, startId, startUnit.Name));
taskList.AddRange(await GetTask(unit.Id));
break;
case "3":
throw new Exception(string.Format("【{0}{1}】找不到审核人,无法提交", unit.Name, unit.Id));
}
}
// 1.需要先判断是否是会签
if (unit.IsCountersign)
{
// 之前有人处理过
if (preAuditUsers.Count > 0)
{
// 驳回处理,重新开启审核
if (isReject)
{
taskList.AddRange(GetCountersignTask(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType));
}
else
// 1.判断之前的会签策略是否通过
if (await Config.IsCountersignAgree(Config.Params.ProcessId, unit.Id))
{
// 判断自动同意规则会签状态下只有3有效
if (unit.AutoAgree.IndexOf("3") != -1)
{
taskList.AddRange(await GetTask(unit.Id));// 自动审核,流转到下一节点
}
else
{
taskList.AddRange(GetCountersignTask(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType));
}
}
else
{
taskList.AddRange(GetCountersignTask(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType, unit.CountersignAgian));
}
}
// 第一次处理
else
{
taskList.AddRange(GetCountersignTask(unit, auditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString(), unit.CountersignType));
}
}
else
{
// 之前有人处理过
if (preAuditUsers.Count > 0)
{
if (IsAtuoAgree(preAuditUsers, unit.AutoAgree.Split(','), isReject))
{
taskList.AddRange(await GetTask(unit.Id, "agree"));
}
else
{
// 判断是否有完成任务的人
if (preAuditUsers.FindIndex(t => t.State == 3) != -1)
{
taskList.AddRange(GetUserTaskList(unit, preAuditUsers.FindAll(t => t.State == 3), isReject, startId, startUnit.Name, Guid.NewGuid().ToString()));
}
else
{
taskList.AddRange(GetUserTaskList(unit, preAuditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString()));
}
}
}
else
{
if (IsAtuoAgree(auditUsers, unit.AutoAgree.Split(','), isReject))
{
taskList.Add(GetAutoSkipTask(unit, isReject, startId, startUnit.Name));// 作为日志记录
taskList.AddRange(await GetTask(unit.Id, "agree"));
}
else
{
taskList.AddRange(GetUserTaskList(unit, auditUsers, isReject, startId, startUnit.Name, Guid.NewGuid().ToString()));
}
}
}
break;
case "bpmn:ScriptTask":// 脚本节点
taskList.Add(GetScriptTaskList(unit, isReject, startId, startUnit.Name, Guid.NewGuid().ToString()));
taskList.AddRange(await GetTask(unit.Id));
break;
//case "subprocess":// 暂时不支持
case "bpmn:SubProcess":
taskList.Add(GetSubprocessTask(unit, startId, startUnit.Name));
break;
//case "endEvent":// 结束节点
case "bpmn:EndEvent":// 结束节点
taskList.Add(GetEndTask(unit, startId, startUnit.Name));
break;
}
}
return taskList;
}
#region 私有方法
/// <summary>
/// 获取开始任务
/// </summary>
/// <param name="unit"></param>
/// <param name="IsReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <returns></returns>
private WorkFlow.WFTask GetStartTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = "重新创建",
Token = Guid.NewGuid().ToString(),
Type = 4,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = IsReject,
MessageType = unit.MessageType,
User = _config.Params.CreateUser
};
return task;
}
private WorkFlow.WFTask GetEndTask(WFUnit unit, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = "流程结束",
Token = Guid.NewGuid().ToString(),
Type = 100,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
};
return task;
}
/// <summary>
/// 获取一个等待任务
/// </summary>
/// <param name="unit"></param>
/// <param name="IsReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <returns></returns>
private WorkFlow.WFTask GetAwaitTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = "等待其它支路完成",
Type = 21,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = IsReject
};
return task;
}
/// <summary>
/// 获取一个更新任务
/// </summary>
/// <param name="unit"></param>
/// <returns></returns>
private WorkFlow.WFTask GetUpdateTask(WFUnit unit)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Type = 26,
};
return task;
}
/// <summary>
/// 获取一个找不到审核人直接跳过任务
/// </summary>
/// <param name="unit"></param>
/// <param name="IsReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <returns></returns>
private WorkFlow.WFTask GetSkipTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = "当前任务找不到审核人直接跳过",
Type = 23,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = IsReject
};
return task;
}
/// <summary>
/// 获取一个找不到审核人直接跳过任务
/// </summary>
/// <param name="unit"></param>
/// <param name="IsReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <returns></returns>
private WorkFlow.WFTask GetAutoSkipTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = "自动审核规则跳过",
Type = 24,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = IsReject
};
return task;
}
/// <summary>
/// 获取一个取消等待任务
/// </summary>
/// <param name="unit"></param>
/// <param name="IsReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <returns></returns>
private WorkFlow.WFTask GetDeleteAwaitTask(WFUnit unit, bool IsReject, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = "取消等待任务",
Type = 22,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = IsReject
};
return task;
}
/// <summary>
/// 获取审批任务
/// </summary>
/// <param name="unit"></param>
/// <param name="userList"></param>
/// <param name="isReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <param name="token"></param>
/// <returns></returns>
private List<WorkFlow.WFTask> GetUserTaskList(WFUnit unit, List<WFUserInfo> userList, bool isReject, string preUnitId, string preUnitName, string token)
{
List<WorkFlow.WFTask> list = new List<WorkFlow.WFTask>();
int type = 1;
if (unit!=null&&unit.IsSingleTask)
{
type = 7;
}
foreach (var user in userList)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = unit.Name,
Type = type,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = isReject,
Token = token,
MessageType = unit.MessageType,
// 超时设置
IsOvertimeMessage = unit.IsOvertimeMessage,
OvertimeMessageStart = unit.OvertimeMessageStart,
OvertimeMessageInterval = unit.OvertimeMessageInterval,
OvertimeGo = unit.OvertimeGo,
OvertimeMessageType = unit.OvertimeMessageType,
IsBatchAudit = unit.IsBatchAudit,
// 处理人
User = user
};
if (string.IsNullOrEmpty(task.Name))
{
task.Name = "审核处理";
}
list.Add(task);
}
return list;
}
/// <summary>
/// 获取传阅任务
/// </summary>
/// <param name="unit"></param>
/// <param name="userList"></param>
/// <param name="isReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <param name="token"></param>
/// <returns></returns>
private List<WorkFlow.WFTask> GetLookUserTaskList(WFUnit unit, List<WFUserInfo> userList, bool isReject, string preUnitId, string preUnitName, string token)
{
List<WorkFlow.WFTask> list = new List<WorkFlow.WFTask>();
foreach (var user in userList)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = unit.Name,
Type = 2,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = isReject,
Token = token,
MessageType = unit.MessageType,
// 处理人
User = user
};
if (string.IsNullOrEmpty(task.Name))
{
task.Name = "查看";
}
list.Add(task);
}
return list;
}
/// <summary>
/// 获取会签审批任务
/// </summary>
/// <param name="unit"></param>
/// <param name="userList"></param>
/// <param name="isReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <param name="token"></param>
/// <param name="countersignType">审核方式 1.并行 2.串行</param>
/// <param name="countersignAgian">再次审核 1.已同意不需要审核 2.已同意需要审核</param>
/// <returns></returns>
private List<WorkFlow.WFTask> GetCountersignTask(WFUnit unit, List<WFUserInfo> userList, bool isReject, string preUnitId, string preUnitName, string token, string countersignType, string countersignAgian = "2")
{
List<WorkFlow.WFTask> list = new List<WorkFlow.WFTask>();
int num = 1;
foreach (var user in userList)
{
if (countersignAgian == "1" && user.IsAgree)
{
continue;
}
user.IsAwait = countersignType == "1" ? false : true;
user.Sort = num;
if (num == 1)
{
user.IsAwait = false;
}
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = unit.Name,
Type = 5,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = isReject,
Token = token,
MessageType = unit.MessageType,
// 超时设置
IsOvertimeMessage = unit.IsOvertimeMessage,
OvertimeMessageStart = unit.OvertimeMessageStart,
OvertimeMessageInterval = unit.OvertimeMessageInterval,
OvertimeGo = unit.OvertimeGo,
OvertimeMessageType = unit.OvertimeMessageType,
IsBatchAudit = unit.IsBatchAudit,
// 处理人
User = user,
};
if (string.IsNullOrEmpty(task.Name))
{
task.Name = "审核处理";
}
list.Add(task);
num++;
}
return list;
}
/// <summary>
/// 获取脚本执行任务
/// </summary>
/// <param name="unit"></param>
/// <param name="isReject"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <param name="token"></param>
/// <returns></returns>
private WorkFlow.WFTask GetScriptTaskList(WFUnit unit, bool isReject, string preUnitId, string preUnitName, string token)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
UnitId = unit.Id,
Name = unit.Name,
Type = 10,
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
IsReject = isReject,
Token = token,
ExecuteType = unit.ExecuteType,
SqlDb = unit.SqlDb,
SqlStr = unit.SqlStr,
SqlStrRevoke = unit.SqlStrRevoke,
ApiUrl = unit.ApiUrl,
ApiUrlRevoke = unit.ApiUrlRevoke,
Ioc = unit.Ioc,
IocRevoke = unit.IocRevoke,
};
if (string.IsNullOrEmpty(task.Name))
{
task.Name = "脚本执行";
}
return task;
}
/// <summary>
/// 获取成立的条件ID
/// </summary>
/// <param name="conditions">条件列表</param>
/// <returns></returns>
private async Task<List<string>> GetConditionIds(List<WFCondition> conditions)
{
List<string> list = new List<string>();
foreach (var condition in conditions)
{
//获取数据id
var process = await client.Queryable<WFProcess>().FirstAsync(a => a.Id == _config.Params.ProcessId);
WFInstanceInfo instanceInfo = null;
if (process != null)
{
// instanceInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<WFInstanceInfo>(process.InstanceInfo);
instanceInfo = process.InstanceInfo;
}
if (condition.Type == "1")// 字段比较
{
string sql = string.Format("select \"{0}\" from \"{1}\" where \"{2}\" = @processId ", condition.Cfield, condition.Table, condition.Rfield, condition.Rfield);
//var dt = await dbFactory.BaseRepository(condition.DbCode).FindTable(sql, new { processId = _config.Params.ProcessId });
var pars = client.Ado.GetParameters(new { processId = instanceInfo.pkeyValue });
var dt = await client.Ado.GetDataTableAsync(sql, pars);
if (dt.Rows.Count > 0)
{
var value = dt.Rows[0][condition.Cfield.ToLower()].ToString();
switch (condition.CompareType)
{
case "1":
if (value == condition.Value)
{
list.Add(condition.Code);
}
break;
case "2":
if (value != condition.Value)
{
list.Add(condition.Code);
}
break;
case "3":
if (Convert.ToDecimal(value) > Convert.ToDecimal(condition.Value))
{
list.Add(condition.Code);
}
break;
case "4":
if (Convert.ToDecimal(value) >= Convert.ToDecimal(condition.Value))
{
list.Add(condition.Code);
}
break;
case "5":
if (Convert.ToDecimal(value) < Convert.ToDecimal(condition.Value))
{
list.Add(condition.Code);
}
break;
case "6":
if (Convert.ToDecimal(value) <= Convert.ToDecimal(condition.Value))
{
list.Add(condition.Code);
}
break;
case "7":
if (value.IndexOf(condition.Value) != -1)
{
list.Add(condition.Code);
}
break;
case "8":
if (value.IndexOf(condition.Value) == -1)
{
list.Add(condition.Code);
}
break;
case "9":
if (condition.Value.IndexOf(value) != -1)
{
list.Add(condition.Code);
}
break;
case "10":
if (condition.Value.IndexOf(value) == -1)
{
list.Add(condition.Code);
}
break;
}
}
}
else
{// sql语句
//var dt = await dbFactory.BaseRepository(condition.DbCode).FindTable(condition.Sql, new { processId = _config.Params.ProcessId, userId = CreateUser.Id, userAccount = CreateUser.Account, companyId = CreateUser.CompanyId, departmentId = CreateUser.DepartmentId });
//var pars = client.Ado.GetParameters(new { processId = _config.Params.ProcessId, userId = CreateUser.Id, userAccount = CreateUser.Account, companyId = CreateUser.CompanyId, departmentId = CreateUser.DepartmentId });
var pars = client.Ado.GetParameters(new { processId = instanceInfo.pkeyValue, userId = CreateUser.Id, userAccount = CreateUser.Account, companyId = CreateUser.CompanyId, departmentId = CreateUser.DepartmentId });
var dt = await client.Ado.GetDataTableAsync(condition.Sql, pars);
if (dt.Rows.Count > 0)
{
list.Add(condition.Code);
}
}
}
return list;
}
/// <summary>
/// 判断是否自动同意
/// </summary>
/// <param name="auditUsers">审核处理人</param>
/// <param name="atuoAgrees">自动同意策略1.处理人就是提交人 2.处理人和上一步的处理人相同 3.处理人审批过</param>
/// <param name="isReject">是否是驳回</param>
/// <returns></returns>
private bool IsAtuoAgree(List<WFUserInfo> auditUsers, string[] atuoAgrees, bool isReject)
{
if (isReject)
{
return false;
}
bool res = false;
if (auditUsers.Count == 0 || atuoAgrees.Length == 0)
{
return res;
}
foreach (var item in atuoAgrees)
{
switch (item)
{
case "1":
if (auditUsers.FindIndex(t => t.Id == CreateUser.Id) != -1)
{
res = true;
}
break;
case "2":
if (auditUsers.FindIndex(t => t.Id == CurrentUser.Id) != -1)
{
res = true;
}
break;
case "3":
if (auditUsers.FindIndex(t => t.IsAgree) != -1 && !isReject)
{
res = true;
}
break;
}
}
return res;
}
/// <summary>
/// 获取子流程任务
/// </summary>
/// <param name="unit"></param>
/// <param name="preUnitId"></param>
/// <param name="preUnitName"></param>
/// <returns></returns>
private WorkFlow.WFTask GetSubprocessTask(WFUnit unit, string preUnitId, string preUnitName)
{
WorkFlow.WFTask task = new WorkFlow.WFTask()
{
Type = 3,
UnitId = unit.Id,
Name = "子流程",
Token = Guid.NewGuid().ToString(),
PrevUnitId = preUnitId,
PrevUnitName = preUnitName,
ChildSchemeInfoId = unit.WfschemeId,
User = _config.Params.CreateUser
};
return task;
}
#endregion
}
}