| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- using Abp;
- using Abp.Dependency;
- using Abp.Domain.Repositories;
- using Abp.Domain.Services;
- using Abp.Domain.Uow;
- using Abp.Json;
- using Abp.UI;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using VberZero.Workflow.DesignInfo;
- using VberZero.Workflow.StepBodies;
- using WorkflowCore.Interface;
- using WorkflowCore.Models;
- using WorkflowCore.Models.DefinitionStorage.v1;
- using WorkflowCore.Services.DefinitionStorage;
- namespace VberZero.Workflow;
- public class VberWorkflowManager : DomainService, IVberWorkflowManager, ITransientDependency
- {
- protected readonly WorkflowStepBodyManager _workflowStepBodyManager;
- protected IWorkflowHost _workflowHost;
- protected readonly IWorkflowController _workflowService;
- protected readonly IWorkflowRegistry _registry;
- public IVberPersistenceProvider PersistenceProvider { get; }
- protected readonly ISearchIndex _searchService;
- protected readonly IDefinitionLoader _definitionLoader;
- protected readonly IRepository<WorkflowDefinitionInfo, string> _workflowDefinitionRepository;
- protected IReadOnlyCollection<VberWorkflowStepBody> _stepBodies;
- public IQueryable<WorkflowDefinitionInfo> WorkflowDefinitions => _workflowDefinitionRepository.GetAll();
- public VberWorkflowManager(WorkflowStepBodyManager workflowStepBodyManager, IWorkflowHost workflowHost, IWorkflowController workflowService, IWorkflowRegistry registry, IVberPersistenceProvider workflowStore, ISearchIndex searchService, IDefinitionLoader definitionLoader, IRepository<WorkflowDefinitionInfo, string> workflowDefinitionRepository
- )
- {
- _workflowStepBodyManager = workflowStepBodyManager;
- _workflowHost = workflowHost;
- _workflowService = workflowService;
- _registry = registry;
- PersistenceProvider = workflowStore;
- _searchService = searchService;
- _definitionLoader = definitionLoader;
- _workflowDefinitionRepository = workflowDefinitionRepository;
- _stepBodies = _workflowStepBodyManager.GetAllStepBodies();
- }
- /// <summary>
- /// 终止流程
- /// </summary>
- /// <param name="workflowId"></param>
- /// <returns></returns>
- public virtual async Task<bool> TerminateWorkflow(string workflowId)
- {
- return await _workflowService.TerminateWorkflow(workflowId);
- }
- public virtual WorkflowDefinition GetDefinition(string workflowId, int? version = null)
- {
- return _registry.GetDefinition(workflowId, version);
- }
- /// <summary>
- /// 初始化注册流程
- /// </summary>
- internal void Initialize()
- {
- using (UnitOfWorkManager.Begin())
- {
- using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant))
- {
- var definitions = WorkflowDefinitions.ToList();
- foreach (var workflow in definitions)
- {
- LoadDefinition(workflow);
- }
- }
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public virtual IEnumerable<VberWorkflowStepBody> GetAllStepBodies()
- {
- return _stepBodies;
- }
- public virtual async Task PublishEventAsync(string eventName, string eventKey, object eventData)
- {
- await _workflowHost.PublishEvent(eventName, eventKey, eventData);
- }
- /// <summary>
- /// 创建流程
- /// </summary>
- /// <param name="entity"></param>
- /// <returns></returns>
- [UnitOfWork]
- public virtual async Task CreateAsync(WorkflowDefinitionInfo entity)
- {
- LoadDefinition(entity);
- await _workflowDefinitionRepository.InsertAsync(entity);
- }
- /// <summary>
- /// 删除指定版本
- /// </summary>
- /// <param name="id"></param>
- /// <param name="version"></param>
- /// <returns></returns>
- [UnitOfWork]
- public virtual async Task DeleteAsync(string id, int version)
- {
- var entity = await _workflowDefinitionRepository.FirstOrDefaultAsync(a => a.Id == id && a.Version == version);
- var all = await PersistenceProvider.GetAllRunnablePersistedWorkflow(entity.Id, entity.Version);
- if (all.Any())
- {
- throw new UserFriendlyException($"编号:{entity.Id},版本:{entity.Version}的流程无法删除!还有没有执行完的流程!");
- }
- if (_registry.IsRegistered(entity.Id, entity.Version))
- {
- _registry.DeregisterWorkflow(entity.Id, entity.Version);
- }
- await _workflowDefinitionRepository.DeleteAsync(entity);
- }
- /// <summary>
- /// 删除全部版本
- /// </summary>
- /// <param name="id"></param>
- /// <returns></returns>
- [UnitOfWork]
- public virtual async Task DeleteAsync(string id)
- {
- var entities = await _workflowDefinitionRepository.GetAllListAsync(a => a.Id == id);
- foreach (var entity in entities)
- {
- await DeleteAsync(entity.Id, entity.Version);
- }
- }
- /// <summary>
- /// 更新
- /// </summary>
- /// <param name="entity"></param>
- /// <returns></returns>
- [UnitOfWork]
- public virtual async Task UpdateAsync(WorkflowDefinitionInfo entity)
- {
- if (_registry.IsRegistered(entity.Id, entity.Version))
- {
- _registry.DeregisterWorkflow(entity.Id, entity.Version);
- }
- LoadDefinition(entity);
- await _workflowDefinitionRepository.UpdateAsync(entity);
- }
- /// <summary>
- /// 启动工作流
- /// </summary>
- /// <returns></returns>
- public virtual async Task<string> StartWorkflow(string id, int version, Dictionary<string, object> inputs, string reference = null)
- {
- if (!_registry.IsRegistered(id, version))
- {
- throw new UserFriendlyException("工作流未定义!");
- }
- return await _workflowHost.StartWorkflow(id, version, inputs, reference);
- }
- /// <summary>
- /// 注册工作流
- /// </summary>
- /// <param name="input"></param>
- /// <returns></returns>
- internal WorkflowDefinition LoadDefinition(WorkflowDefinitionInfo input)
- {
- if (_registry.IsRegistered(input.Id, input.Version))
- {
- throw new AbpException($"工作流[{input.Id}]已定义 ");
- }
- var source = new DefinitionSourceV1
- {
- Id = input.Id,
- Version = input.Version,
- Description = input.Title,
- DataType = $"{typeof(Dictionary<string, object>).FullName}, {typeof(Dictionary<string, object>).Assembly.FullName}"
- };
- BuildWorkflow(input.Nodes, source, _stepBodies, input.Nodes.First(u => u.Key.ToLower().StartsWith("start")));
- var json = source.ToJsonString();
- Logger.DebugFormat("Workflow Json:{0}", json);
- var def = _definitionLoader.LoadDefinition(json, Deserializers.Json);
- return def;
- }
- protected virtual void BuildWorkflow(IEnumerable<WorkflowNode> allNodes, DefinitionSourceV1 source, IEnumerable<VberWorkflowStepBody> stepBodies, WorkflowNode node)
- {
- if (source.Steps.Any(u => u.Id == node.Key))
- {
- return;
- }
- var stepSource = new StepSourceV1
- {
- Id = node.Key,
- Name = node.Key
- };
- VberWorkflowStepBody stepBody = stepBodies.FirstOrDefault(u => node.StepBody != null && u.Name == node.StepBody.Name) ?? new VberWorkflowStepBody() { StepBodyType = typeof(NullStepBody) };
- stepSource.StepType = $"{stepBody.StepBodyType.FullName}, {stepBody.StepBodyType.Assembly.FullName}";
- foreach (var input in stepBody.Inputs)
- {
- var value = input.Value.Value;
- var key = FirstToLower(input.Key);
- if (node.StepBody.Inputs.ContainsKey(key))
- {
- value = node.StepBody.Inputs[key].Value;
- }
- if (!(value is IDictionary<string, object> || value is IDictionary<object, object>))
- {
- value = $"\"{value}\"";
- }
- stepSource.Inputs.TryAdd(input.Key, value);
- }
- source.Steps.Add(stepSource);
- BuildBranching(allNodes, source, stepSource, stepBodies, node.NextNodes);
- }
- protected virtual void BuildBranching(IEnumerable<WorkflowNode> allNodes, DefinitionSourceV1 source, StepSourceV1 stepSource, IEnumerable<VberWorkflowStepBody> stepBodies, IEnumerable<WorkflowConditionNode> nodes)
- {
- foreach (var nextNode in nodes)
- {
- var node = allNodes.First(u => u.Key == nextNode.NodeId);
- stepSource.SelectNextStep[nextNode.NodeId] = "1==1";
- if (nextNode.Conditions.Any())
- {
- List<string> expList = new List<string>();
- foreach (var cond in nextNode.Conditions)
- {
- if (cond.Value is string && (!decimal.TryParse(cond.Value.ToString(), out _)))
- {
- if (cond.Operator != "==" && cond.Operator != "!=")
- {
- throw new AbpException($" if {cond.Field} is type of 'String', the Operator must be \"==\" or \"!=\"");
- }
- expList.Add($"data[\"{cond.Field}\"].ToString() {cond.Operator} \"{cond.Value}\"");
- continue;
- }
- expList.Add($"decimal.Parse(data[\"{cond.Field}\"].ToString()) {cond.Operator} {cond.Value}");
- }
- stepSource.SelectNextStep[nextNode.NodeId] = string.Join(" && ", expList);
- }
- BuildWorkflow(allNodes, source, stepBodies, node);
- }
- }
- private string FirstToLower(string str)
- {
- return str.Substring(0, 1).ToLower() + str.Substring(1);
- }
- }
|