using System.Text;
using JNPF.Common.Core.Manager;
using JNPF.Common.Extension;
using JNPF.Common.Models.WorkFlow;
using JNPF.Common.Security;
using JNPF.Extras.Thirdparty.JSEngine;
using JNPF.FriendlyException;
using JNPF.Systems.Interfaces.Permission;
using JNPF.WorkFlow.Entitys.Entity;
using JNPF.WorkFlow.Entitys.Enum;
using JNPF.WorkFlow.Entitys.Model;
using JNPF.WorkFlow.Entitys.Model.Item;
using JNPF.WorkFlow.Entitys.Model.Properties;
using JNPF.WorkFlow.Interfaces.Repository;
using Mapster;
using Newtonsoft.Json.Linq;
namespace JNPF.WorkFlow.Manager;
public class FlowTemplateUtil
{
private readonly IDataBaseManager _dataBaseManager;
private readonly IUserManager _userManager;
private readonly IFlowTaskRepository _flowTaskRepository;
private readonly IUsersService _usersService;
///
/// 可用节点.
///
public List flowTaskNodeEntityList { get; set; } = new List();
///
/// 所有节点.
///
public List taskNodeList { get; set; } = new List();
///
/// 开始节点.
///
public FlowTaskNodeEntity startNode { get; set; } = new FlowTaskNodeEntity();
///
/// 开始节点属性.
///
public StartProperties startPro { get; set; } = new StartProperties();
public FlowTemplateUtil(IDataBaseManager dataBaseManager, IUserManager userManager, IFlowTaskRepository flowTaskRepository,
IUsersService usersService)
{
_dataBaseManager = dataBaseManager;
_userManager = userManager;
_flowTaskRepository = flowTaskRepository;
_usersService = usersService;
}
///
/// 加载参数.
///
///
///
///
public void Load(FlowJsonModel flowJsonModel, string formData, string taskId, bool isDeleteCondition = true)
{
this.flowTaskNodeEntityList.Clear();
this.taskNodeList.Clear();
var flowTemplateJsonModel = flowJsonModel.flowTemplateJson.ToObject();
#region 流程模板所有节点
var flowTemplateJsonModelList = new List();
var childNodeIdList = new List();
GetChildNodeIdList(flowTemplateJsonModel, childNodeIdList);
GetFlowTemplateList(flowTemplateJsonModel, flowTemplateJsonModelList);
#endregion
GetFlowTemplateAll(flowTemplateJsonModel, this.taskNodeList, flowTemplateJsonModelList, childNodeIdList, taskId);
if (isDeleteCondition)
{
DeleteConditionTaskNodeModel(taskNodeList, formData, taskId);
var defaultFormId = this.taskNodeList.Find(m => FlowTaskNodeTypeEnum.start.ParseToString().Equals(m.type)).propertyJson.formId;
foreach (var item in this.taskNodeList)
{
var flowTaskNodeEntity = new FlowTaskNodeEntity();
flowTaskNodeEntity.Id = SnowflakeIdHelper.NextId();
flowTaskNodeEntity.CreatorTime = DateTime.Now;
flowTaskNodeEntity.TaskId = item.taskId;
flowTaskNodeEntity.NodeCode = item.nodeId;
flowTaskNodeEntity.NodeType = item.type;
flowTaskNodeEntity.Completion = FlowTaskNodeTypeEnum.start.ParseToString().Equals(item.type) ? 1 : 0;
flowTaskNodeEntity.NodeName = FlowTaskNodeTypeEnum.start.ParseToString().Equals(item.type) ? "开始" : item.propertyJson.title;
flowTaskNodeEntity.NodeUp = !FlowTaskNodeTypeEnum.approver.ParseToString().Equals(item.type) ? null : item.propertyJson.rejectStep;
flowTaskNodeEntity.NodeNext = item.nextNodeId;
flowTaskNodeEntity.NodePropertyJson = JsonHelper.ToJsonString(item.propertyJson);
flowTaskNodeEntity.State = "1";
if (FlowTaskNodeTypeEnum.subFlow.ParseToString().Equals(item.type))
{
string subFlowId = item.propertyJson.flowId;//子流程流程id
var jsonInfo = _flowTaskRepository.GetFlowTemplateJsonInfo(x => x.Id == subFlowId && x.DeleteMark == null);
flowTaskNodeEntity.FormId = jsonInfo.FlowTemplateJson.ToObject().properties.ToObject().formId;
}
else
{
string formId = item.propertyJson.formId;
flowTaskNodeEntity.FormId = formId.IsNotEmptyOrNull() ? formId : defaultFormId;
}
flowTaskNodeEntityList.Add(flowTaskNodeEntity);
}
DeleteTimerTaskNode(this.flowTaskNodeEntityList);
this.startNode = this.flowTaskNodeEntityList.Find(m => FlowTaskNodeTypeEnum.start.ParseToString().Equals(m.NodeType));
this.startPro = this.startNode.NodePropertyJson.ToObject();
}
}
///
/// 递归获取流程模板最外层childNode中所有nodeid.
///
/// 流程模板实例.
/// 子节点id.
private void GetChildNodeIdList(FlowTemplateJsonModel template, List childNodeIdList)
{
if (template.IsNotEmptyOrNull() && template.childNode.IsNotEmptyOrNull())
{
childNodeIdList.Add(template.childNode.nodeId);
GetChildNodeIdList(template.childNode, childNodeIdList);
}
}
///
/// 递归获取流程模板数组.
///
/// 流程模板.
/// 流程模板数组.
private void GetFlowTemplateList(FlowTemplateJsonModel template, List templateList)
{
if (template.IsNotEmptyOrNull())
{
var haschildNode = template.childNode.IsNotEmptyOrNull();
var hasconditionNodes = template.conditionNodes.IsNotEmptyOrNull() && template.conditionNodes.Count > 0;
templateList.Add(template);
if (hasconditionNodes)
{
foreach (var conditionNode in template.conditionNodes)
{
GetFlowTemplateList(conditionNode, templateList);
}
}
if (haschildNode)
{
GetFlowTemplateList(template.childNode, templateList);
}
}
}
///
/// 递归审批模板获取所有节点.
///
/// 当前审批流程json.
/// 流程节点数组.
/// 流程模板数组.
private void GetFlowTemplateAll(FlowTemplateJsonModel template, List nodeList, List templateList, List childNodeIdList, string taskId = "")
{
try
{
if (template.IsNotEmptyOrNull())
{
var taskNodeModel = template.Adapt();
taskNodeModel.taskId = taskId;
taskNodeModel.propertyJson = GetPropertyByType(template.type, template.properties);
if (taskNodeModel.isBranchFlow)
{
taskNodeModel.propertyJson.isBranchFlow = taskNodeModel.isBranchFlow;
}
var haschildNode = template.childNode.IsNotEmptyOrNull();
var hasconditionNodes = template.conditionNodes.IsNotEmptyOrNull() && template.conditionNodes.Count > 0;
List nextNodeIdList = new List { string.Empty };
if (templateList.Count > 1)
{
nextNodeIdList = GetNextNodeIdList(templateList, template, childNodeIdList);
}
taskNodeModel.nextNodeId = string.Join(',', nextNodeIdList.ToArray());
nodeList.Add(taskNodeModel);
if (hasconditionNodes)
{
foreach (var conditionNode in template.conditionNodes)
{
GetFlowTemplateAll(conditionNode, nodeList, templateList, childNodeIdList, taskId);
}
}
if (haschildNode)
{
taskNodeModel.childNodeId = template.childNode.nodeId;
GetFlowTemplateAll(template.childNode, nodeList, templateList, childNodeIdList, taskId);
}
}
}
catch (AppFriendlyException ex)
{
throw Oops.Oh(ex.ErrorCode);
}
}
///
/// 根据类型获取不同属性对象.
///
/// 属性类型.
/// 数据.
///
private dynamic GetPropertyByType(string type, JObject jd)
{
switch (type)
{
case "approver":
return jd.ToObject();
case "timer":
return jd.ToObject();
case "start":
return jd.ToObject();
case "condition":
return jd.ToObject();
case "subFlow":
return jd.ToObject();
default:
return jd;
}
}
///
/// 获取当前模板的下一节点
/// 下一节点数据来源:conditionNodes和childnode (conditionNodes优先级大于childnode)
/// conditionNodes非空:下一节点则为conditionNodes数组中所有nodeID
/// conditionNodes非空childNode非空:下一节点则为childNode的nodeId
/// conditionNodes空childNode空则为最终节点(两种情况:当前模板属于conditionNodes的最终节点或childNode的最终节点)
/// conditionNodes的最终节点:下一节点为与conditionNodes同级的childNode的nodeid,没有则继续递归,直到最外层的childNode
/// childNode的最终节点直接为"".
///
/// 模板数组
/// 当前模板
/// 最外层childnode的nodeid集合
///
private List GetNextNodeIdList(List templateList, FlowTemplateJsonModel template, List childNodeIdList)
{
List nextNodeIdList = new List();
if (template.conditionNodes.IsNotEmptyOrNull() && template.conditionNodes.Count > 0)
{
nextNodeIdList = template.conditionNodes.Select(x => x.nodeId).ToList();
}
else
{
if (template.childNode.IsNotEmptyOrNull())
{
nextNodeIdList.Add(template.childNode.nodeId);
}
else
{
//判断是否是最外层的节点
if (childNodeIdList.Contains(template.nodeId))
{
nextNodeIdList.Add(string.Empty);
}
else
{
//conditionNodes中最终节点
nextNodeIdList.Add(GetChildId(templateList, template, childNodeIdList));
}
}
}
return nextNodeIdList;
}
///
/// 递归获取conditionNodes最终节点下一节点.
///
/// 流程模板数组.
/// 当前模板.
/// 最外层childNode的节点数据.
///
private string GetChildId(List templateList, FlowTemplateJsonModel template, List childNodeIdList)
{
var prevModel = new FlowTemplateJsonModel();
if (template.prevId.IsNotEmptyOrNull())
{
prevModel = templateList.Find(x => x.nodeId.Equals(template.prevId));
if (prevModel.childNode.IsNotEmptyOrNull() && prevModel.childNode.nodeId != template.nodeId)
{
return prevModel.childNode.nodeId;
}
if (childNodeIdList.Contains(prevModel.nodeId))
{
return prevModel.childNode.IsNullOrEmpty() ? string.Empty : prevModel.childNode.nodeId;
}
else
{
return GetChildId(templateList, prevModel, childNodeIdList);
}
}
else
{
return string.Empty;
}
}
///
/// 删除条件节点
/// 将条件的上非条件的节点的nextnode替换成当前条件的nextnode.
///
/// 所有节点数据.
/// 填写表单数据.
/// 任务id.
///
private void DeleteConditionTaskNodeModel(List taskNodeModelList, string formDataJson, string taskId)
{
var conditionTaskNodeModelList = taskNodeModelList.FindAll(x => FlowTaskNodeTypeEnum.condition.ParseToString().Equals(x.type));
var dic = new Dictionary>();
foreach (var item in conditionTaskNodeModelList.GroupBy(x => x.upNodeId))
{
dic.Add(item.Key, taskNodeModelList.FindAll(x => x.upNodeId == item.Key && FlowTaskNodeTypeEnum.condition.ParseToString().Equals(x.type)));
}
//条件的默认情况判断(同层条件的父节点是一样的,只要非默认的匹配成功则不需要走默认的)
var isDefault = new List();
foreach (var nodeId in dic.Keys)
{
var index = 0;
foreach (var item in dic[nodeId])
{
++index;
//条件节点的父节点且为非条件的节点
var upTaskNodeModel = taskNodeModelList.Find(x => x.nodeId == nodeId);
if (FlowTaskNodeTypeEnum.condition.ParseToString().Equals(upTaskNodeModel.type))
{
// 父级条件不满足则子级条件则不需要验证
if (!upTaskNodeModel.propertyJson.isDefault && !ConditionNodeJudge(formDataJson, upTaskNodeModel.propertyJson, taskId))
{
break;
}
upTaskNodeModel = GetUpTaskNodeModelIsNotCondition(taskNodeModelList, upTaskNodeModel);
// 如果父节点下一节点存在某个审批节点则不需要判断了
if (taskNodeModelList.Where(x => upTaskNodeModel.nextNodeId.Contains(x.nodeId)).Any(y => FlowTaskNodeTypeEnum.approver.ParseToString().Equals(y.type)))
{
break;
}
}
if (!item.propertyJson.isDefault && ConditionNodeJudge(formDataJson, item.propertyJson, taskId))
{
upTaskNodeModel.nextNodeId = item.nextNodeId;
isDefault.Add(item.upNodeId);
break;
}
else
{
if (!isDefault.Contains(item.upNodeId) && item.propertyJson.isDefault)
{
upTaskNodeModel.nextNodeId = item.nextNodeId;
}
else
{
if (index == dic[nodeId].Count)
{
upTaskNodeModel.nextNodeId = upTaskNodeModel.childNodeId.IsNotEmptyOrNull() ? upTaskNodeModel.childNodeId : FlowTaskNodeTypeEnum.end.ParseToString();
}
}
}
}
}
if (formDataJson.IsNotEmptyOrNull())
{
taskNodeModelList.RemoveAll(x => FlowTaskNodeTypeEnum.condition.ParseToString().Equals(x.type));
}
}
///
/// 向上递获取非条件的节点.
///
/// 所有节点数据.
/// 当前节点.
///
private TaskNodeModel GetUpTaskNodeModelIsNotCondition(List taskNodeModelList, TaskNodeModel taskNodeModel)
{
var preTaskNodeModel = taskNodeModelList.Find(x => x.nodeId == taskNodeModel.upNodeId);
if (FlowTaskNodeTypeEnum.condition.ParseToString().Equals(preTaskNodeModel.type))
{
return GetUpTaskNodeModelIsNotCondition(taskNodeModelList, preTaskNodeModel);
}
else
{
return preTaskNodeModel;
}
}
///
/// 条件判断.
///
/// 表单填写数据.
/// 条件属性.
/// 任务id.
///
private bool ConditionNodeJudge(string formDataJson, ConditionProperties conditionPropertie, string taskId)
{
try
{
bool flag = false;
StringBuilder expression = new StringBuilder();
expression.AppendFormat("select * from base_user where ");
var formData = formDataJson.ToObject();
int i = 0;
foreach (ConditionsItem flowNodeWhereModel in conditionPropertie.conditions)
{
var logic = flowNodeWhereModel.logic;
var symbol = flowNodeWhereModel.symbol.Equals("==") ? "=" : flowNodeWhereModel.symbol;
// 条件值
var formValue = GetConditionValue(flowNodeWhereModel.fieldType.ParseToInt(), formData, flowNodeWhereModel.field, taskId, flowNodeWhereModel.jnpfKey);
// 匹配值
var value = " ";
if (flowNodeWhereModel.fieldValueType.ParseToInt() == 2)
{
//数组类型控件
var jnpfKeyList = new List() { "cascader", "comSelect", "address", "currOrganize" };
if (jnpfKeyList.Contains(flowNodeWhereModel.jnpfKey) && flowNodeWhereModel.fieldValue.Count > 0)
{
if (flowNodeWhereModel.jnpfKey.Equals("currOrganize"))
{
value = flowNodeWhereModel.fieldValue[flowNodeWhereModel.fieldValue.Count - 1];
}
else
{
value = string.Join(",", flowNodeWhereModel.fieldValue);
}
}
else
{
value = flowNodeWhereModel.fieldValue.ToString();
}
if ("currentUser".Equals(value))
{
value = _userManager.UserId;
}
if ("time".Equals(flowNodeWhereModel.jnpfKey))
{
formValue = formValue.Replace(":", string.Empty);
value = value.Replace(":", string.Empty);
}
}
else
{
value = GetConditionValue(flowNodeWhereModel.fieldValueType.ParseToInt(), formData, flowNodeWhereModel.fieldValue, taskId, flowNodeWhereModel.jnpfKey);
}
if (symbol.Equals("=") || symbol.Equals("<>"))
{
expression.AppendFormat("('{0}'{1}'{2}')", formValue, symbol, value);
}
else if (symbol.Equals("like"))
{
expression.AppendFormat("('{0}' {1} '%{2}%')", formValue, symbol, value);
}
else if (symbol.Equals("notLike"))
{
expression.AppendFormat("('{0}' {1} '%{2}%')", formValue, "not like", value);
}
else
{
if (string.IsNullOrWhiteSpace(formValue) || string.IsNullOrWhiteSpace(value))
{
expression.Append("(1=2)");
}
else
{
expression.AppendFormat("({0}{1}{2})", formValue, symbol, value);
}
}
if (logic.IsNotEmptyOrNull() && i != conditionPropertie.conditions.Count - 1)
{
expression.Append(" " + logic.Replace("&&", " and ").Replace("||", " or ") + " ");
}
i++;
}
var link = _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
flag = _dataBaseManager.WhereDynamicFilter(link, expression.ToString());
return flag;
}
catch (Exception e)
{
return false;
}
}
///
/// 获取条件匹配值.
///
/// 条件类型 1、字段 2、自定义 3、聚合函数.
/// 表单数据.
/// 关联字段.
/// 任务id.
/// 控件key.
///
private string GetConditionValue(int type, JObject formData, string field, string taskId, string jnpfKey)
{
var conditionValue = " ";
if (type == 1)
{
if (formData.ContainsKey(field))
{
if (formData[field] is JArray)
{
try
{
var jar = formData[field].ToObject>();
if (jar.Count > 0)
{
conditionValue = string.Join(",", jar);
}
}
catch (Exception e)
{
var arr = formData[field].ToObject>>();
conditionValue = string.Join(",", arr.Select(x => string.Join(",", x)).ToList());
}
}
else
{
if (formData[field].IsNotEmptyOrNull())
{
conditionValue = formData[field].ToString();
SysWidgetFormValue(taskId, jnpfKey, ref conditionValue);
}
}
}
}
else
{
// 获取聚合函数要替换的参数key
foreach (var item in field.Substring3())
{
if (formData.ContainsKey(item))
{
field = field.Replace("{" + item + "}", "'" + formData[item] + "'");
}
else if (item.Contains("tableField") && item.Contains("-"))
{
var fields = item.Split("-").ToList();
var tableField = fields[0];
var keyField = fields[1];
if (formData.ContainsKey(tableField) && formData[tableField] is JArray)
{
var jar = formData[tableField] as JArray;
var tableValue = jar.Where(x => x.ToObject().ContainsKey(keyField)).Select(x => x.ToObject()[keyField]).ToObject>();
var valueStr = string.Join("','", tableValue);
field = field.Replace("{" + item + "}", "'" + valueStr + "'");
}
}
else
{
field = field.Replace("{" + item + "}", "''");
}
}
// 执行函数获取值
conditionValue = JsEngineUtil.AggreFunction(field).ToString();
}
return conditionValue;
}
///
/// 系统控件条件匹配数据转换.
///
/// 任务id
/// 条件匹配字段类型
/// 条件匹配值
private void SysWidgetFormValue(string taskId, string jnpfKey, ref string formValue)
{
var taskEntity = _flowTaskRepository.GetTaskFirstOrDefault(taskId);
if (taskEntity.IsNotEmptyOrNull())
{
var creatorUser = _usersService.GetInfoByUserId(taskEntity.CreatorUserId);
switch (jnpfKey)
{
case "createUser":
formValue = taskEntity.CreatorUserId;
break;
case "modifyUser":
if (taskEntity.LastModifyUserId.IsNotEmptyOrNull())
{
formValue = _userManager.UserId;
}
break;
case "currOrganize":
if (creatorUser.OrganizeId.IsNotEmptyOrNull())
{
formValue = creatorUser.OrganizeId;
}
break;
case "createTime":
formValue = ((DateTime)taskEntity.CreatorTime).ParseToUnixTime().ToString();
break;
case "modifyTime":
if (taskEntity.LastModifyTime.IsNotEmptyOrNull())
{
formValue = DateTime.Now.ParseToUnixTime().ToString();
}
break;
case "currPosition":
if (creatorUser.PositionId.IsNotEmptyOrNull())
{
formValue = creatorUser.PositionId;
}
break;
}
}
else
{
switch (jnpfKey)
{
case "createUser":
formValue = _userManager.UserId;
break;
case "modifyUser":
formValue = " ";
break;
case "currOrganize":
if (_userManager.User.OrganizeId.IsNotEmptyOrNull())
{
formValue = _userManager.User.OrganizeId;
}
break;
case "createTime":
formValue = DateTime.Now.ParseToUnixTime().ToString();
break;
case "modifyTime":
formValue = "0";
break;
case "currPosition":
if (_userManager.User.PositionId.IsNotEmptyOrNull())
{
formValue = _userManager.User.PositionId;
}
break;
}
}
}
///
/// 删除定时器.
///
/// 所有节点
private void DeleteTimerTaskNode(List flowTaskNodeEntityList)
{
foreach (var item in flowTaskNodeEntityList)
{
if ("timer".Equals(item.NodeType))
{
// 下一节点为Timer类型节点的节点集合
var taskNodeList = flowTaskNodeEntityList.FindAll(x => x.NodeNext.Contains(item.NodeCode));
// Timer类型节点的下节点集合
var nextTaskNodeList = flowTaskNodeEntityList.FindAll(x => item.NodeNext.Contains(x.NodeCode));
// 保存定时器节点的上节点编码到属性中
var timerProperties = item.NodePropertyJson.ToObject();
timerProperties.upNodeCode = string.Join(",", taskNodeList.Select(x => x.NodeCode).ToArray());
item.NodePropertyJson = timerProperties.ToJsonString();
// 上节点替换NodeNext
foreach (var taskNode in taskNodeList)
{
var flowTaskNodeEntity = flowTaskNodeEntityList.Where(x => x.NodeCode == taskNode.NodeCode).FirstOrDefault();
flowTaskNodeEntity.NodeNext = item.NodeNext;
}
// 下节点添加定时器属性
nextTaskNodeList.ForEach(nextNode =>
{
var flowTaskNodeEntity = flowTaskNodeEntityList.Where(x => x.NodeCode == nextNode.NodeCode).FirstOrDefault();
if (FlowTaskNodeTypeEnum.approver.ParseToString().Equals(flowTaskNodeEntity.NodeType))
{
var properties = flowTaskNodeEntity.NodePropertyJson.ToObject();
properties.timerList.Add(item.NodePropertyJson.ToObject());
flowTaskNodeEntity.NodePropertyJson = JsonHelper.ToJsonString(properties);
}
});
}
}
flowTaskNodeEntityList.RemoveAll(x => FlowTaskNodeTypeEnum.timer.ParseToString().Equals(x.NodeType));
UpdateNodeSort(flowTaskNodeEntityList);
}
///
/// 处理并保存节点.
///
/// 节点list.
private void UpdateNodeSort(List entitys)
{
var startNodes = entitys.FindAll(x => x.NodeType.Equals("start"));
if (startNodes.Count > 0)
{
var startNode = startNodes[0].NodeCode;
long num = 0L;
long maxNum = 0L;
var max = new List();
var _treeList = new List();
NodeList(entitys, startNode, _treeList, num, max);
max.Sort();
if (max.Count > 0)
{
maxNum = max[max.Count - 1];
}
var nodeNext = "end";
foreach (var item in entitys)
{
var type = item.NodeType;
var node = _treeList.Find(x => x.NodeCode.Equals(item.NodeCode));
if (item.NodeNext.IsEmpty())
{
item.NodeNext = nodeNext;
}
if (node.IsNotEmptyOrNull())
{
item.SortCode = node.SortCode;
item.State = "0";
if (item.NodeNext.IsEmpty())
{
item.NodeNext = nodeNext;
}
}
}
entitys.Add(new FlowTaskNodeEntity()
{
Id = SnowflakeIdHelper.NextId(),
NodeCode = nodeNext,
NodeName = "结束",
Completion = 0,
CreatorTime = DateTime.Now,
SortCode = maxNum + 1,
TaskId = _treeList[0].TaskId,
NodePropertyJson = startNodes[0].NodePropertyJson,
NodeType = "endround",
State = "0"
});
}
}
///
/// 递归获取经过的节点.
///
///
///
///
///
///
private void NodeList(List dataAll, string nodeCode, List _treeList, long num, List max)
{
num++;
max.Add(num);
foreach (var item in dataAll)
{
if (item.NodeCode.Contains(nodeCode))
{
item.SortCode = num;
item.State = "0";
_treeList.Add(item);
foreach (var nodeNext in item.NodeNext.Split(","))
{
long nums = _treeList.FindAll(x => x.NodeCode.Equals(nodeNext)).Count;
if (nodeNext.IsNotEmptyOrNull() && nums == 0)
{
NodeList(dataAll, nodeNext, _treeList, num, max);
}
}
}
}
}
}