0

我的工作流程是在这样的信号上触发的:

public async Task<IActionResult> StartApprovalProcess([FromBody] long requestId)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Get data object
    var payload = await _mainService.GetBudgetReleaseRequestPayload(requestId);

    var input = new Variables();

    input.SetVariable("Payload", payload);

    // Signal the workflow to start
    await _workflowInvoker.TriggerSignalAsync("StartApprovalPhase", input);

    return Ok("BRR registered");
}

这是我的有效负载类:

public class BudgetReleaseRequestApprovalPhasePayloadModel
{
    public BudgetReleaseRequestApprovalPhasePayloadModel(BudgetReleaseRequestApprovalPhasePayloadDto model)
    {
        Id                 = model.Id;
        Description        = model.Description;
        Amount             = model.Amount;
        RequesterId        = model.RequesterId;
        SubmissionDate     = model.SubmissionDate;
        CostCenterName     = model.CostCenterName;
        ExpenseTypeName    = model.ExpenseTypeName;
        RequestTypeName    = model.RequestTypeName;
        AccountCode        = model.AccountCode;
        AccountName        = model.AccountName;
        BpsReferenceNumber = model.BpsReferenceNumber;

        ApproversList = new List<BudgetReleaseRequestApproverViewModel>();

        foreach (var budgetReleaseRequestApprover in model.ApproversList)
        {
            ApproversList.Add(new BudgetReleaseRequestApproverViewModel(budgetReleaseRequestApprover));
        }
    }

    public long     Id                 { get; set; }
    public string   Description        { get; set; }
    public decimal  Amount             { get; set; }
    public string   RequesterId        { get; set; }
    public DateTime SubmissionDate     { get; set; }
    public string   CostCenterName     { get; set; }
    public string   ExpenseTypeName    { get; set; }
    public string   RequestTypeName    { get; set; }
    public string   AccountCode        { get; set; }
    public string   AccountName        { get; set; }
    public string   BpsReferenceNumber { get; set; }

    public string AmountFormatted   => $"{Amount:N2} AED";
    public string DateFormatted     => $"{SubmissionDate:dd-MMM-yyyy}";
    public string CostCenterAndType => $"{CostCenterName}/{ExpenseTypeName}";
    public string AccountDetail     => $"{AccountCode} - {AccountName}";
    public int    ApproversCount    => ApproversList.Count;

    public IList<BudgetReleaseRequestApproverViewModel> ApproversList { get; set; }
}

这是充当集合的类:

public class BudgetReleaseRequestApproverViewModel
{
    public BudgetReleaseRequestApproverViewModel(BudgetReleaseRequestApprover model)
    {
        RequestId         = model.RequestId;
        RequestApproverId = model.RequestApproverId;
        ApproverId        = model.ApproverId;
        RequesterId       = model.RequesterId;
        ApproverSequence  = model.ApproverSequence;
        ActionId          = model.ActionId;
        RequestActionId   = model.RequestActionId;
    }

    public long   RequestId         { get; set; }
    public byte   RequestApproverId { get; set; }
    public string ApproverId        { get; set; }
    public string RequesterId       { get; set; }
    public byte   ApproverSequence  { get; set; }
    public Guid?  ActionId          { get; set; }
    public byte?  RequestActionId   { get; set; }

}

我遵循了主要指南(https://sipkeschoorstra.medium.com/building-workflow-driven-net-core-applications-with-elsa-139523aa4c50)并且知道我们需要实现一个处理程序才能在其中包含液体表达式这两种模型的工作流程:

public class LiquidConfigurationHandler : INotificationHandler<EvaluatingLiquidExpression>
{
    public Task Handle(EvaluatingLiquidExpression notification, CancellationToken cancellationToken)
    {
        var context = notification.TemplateContext;
        context.MemberAccessStrategy.Register<BudgetReleaseRequestApprovalPhasePayloadModel>();
        context.MemberAccessStrategy.Register<BudgetReleaseRequestApproverViewModel>();

        return Task.CompletedTask;
    }
}

这是我的测试工作流程:

{
    "activities": [{
            "id": "abc63216-76e7-42b2-ab7b-5cdb6bbc3ed9",
            "type": "Signaled",
            "left": 122,
            "top": 365,
            "state": {
                "signal": {
                    "expression": "StartApprovalPhase",
                    "syntax": "Literal"
                },
                "name": "",
                "title": "Signal: Start Approval Phase",
                "description": "Trigger the workflow when this signal is received."
            },
            "blocking": false,
            "executed": false,
            "faulted": false
        }, {
            "id": "ac7669d6-b7e6-4139-825e-5f2b9c1dbdb8",
            "type": "SendEmail",
            "left": 553,
            "top": 379,
            "state": {
                "from": {
                    "expression": "my.email@acme.co",
                    "syntax": "Literal"
                },
                "to": {
                    "expression": "my.email@acme.co",
                    "syntax": "Literal"
                },
                "subject": {
                    "expression": "Workflow Testing",
                    "syntax": "Literal"
                },
                "body": {
                    "expression": "<p>BRR #{{ Input.Payload.Id }}</p>\r\n<p>Name: {{ Input.Payload.Description }}</p>\r\n<p>Amount: {{ Input.Payload.AmountFormatted }}</p>\r\n<p>Date: {{ Input.Payload.DateFormatted }}</p>\r\n<br />\r\n<p>Approvers: {{ Input.Payload.ApproversCount }}</p>",
                    "syntax": "Liquid"
                },
                "name": "",
                "title": "Email: Test",
                "description": ""
            },
            "blocking": false,
            "executed": false,
            "faulted": false
        }, {
            "id": "2efcffa9-8e18-45cf-aac8-fcfdc8846df8",
            "type": "ForEach",
            "left": 867,
            "top": 474,
            "state": {
                "collectionExpression": {
                    "expression": "{{ Input.Payload.ApproversList }}",
                    "syntax": "Liquid"
                },
                "iteratorName": "",
                "name": "",
                "title": "",
                "description": ""
            },
            "blocking": false,
            "executed": false,
            "faulted": false
        }, {
            "id": "7966b931-f683-4b81-aad4-ad0f6c628191",
            "type": "SendEmail",
            "left": 1042,
            "top": 675,
            "state": {
                "from": {
                    "expression": "my.email@acme.co",
                    "syntax": "Literal"
                },
                "to": {
                    "expression": "my.email@acme.co",
                    "syntax": "Literal"
                },
                "subject": {
                    "expression": "Looping #",
                    "syntax": "Literal"
                },
                "body": {
                    "expression": "Loop Details",
                    "syntax": "Literal"
                },
                "name": "",
                "title": "",
                "description": ""
            },
            "blocking": false,
            "executed": false,
            "faulted": false
        }, {
            "id": "5f246eda-271d-46ed-8efe-df0f26d542be",
            "type": "SendEmail",
            "left": 1163,
            "top": 325,
            "state": {
                "name": "",
                "from": {
                    "expression": "my.email@acme.co",
                    "syntax": "Literal"
                },
                "to": {
                    "expression": "my.email@acme.co",
                    "syntax": "Literal"
                },
                "subject": {
                    "expression": "Loop Over",
                    "syntax": "Literal"
                },
                "body": {
                    "expression": "Loop Finished",
                    "syntax": "Literal"
                },
                "title": "",
                "description": ""
            },
            "blocking": false,
            "executed": false,
            "faulted": false
        }
    ],
    "connections": [{
            "sourceActivityId": "2efcffa9-8e18-45cf-aac8-fcfdc8846df8",
            "destinationActivityId": "5f246eda-271d-46ed-8efe-df0f26d542be",
            "outcome": "Done"
        }, {
            "sourceActivityId": "abc63216-76e7-42b2-ab7b-5cdb6bbc3ed9",
            "destinationActivityId": "ac7669d6-b7e6-4139-825e-5f2b9c1dbdb8",
            "outcome": "Done"
        }, {
            "sourceActivityId": "ac7669d6-b7e6-4139-825e-5f2b9c1dbdb8",
            "destinationActivityId": "2efcffa9-8e18-45cf-aac8-fcfdc8846df8",
            "outcome": "Done"
        }, {
            "sourceActivityId": "2efcffa9-8e18-45cf-aac8-fcfdc8846df8",
            "destinationActivityId": "7966b931-f683-4b81-aad4-ad0f6c628191",
            "outcome": "Iterate"
        }, {
            "sourceActivityId": "7966b931-f683-4b81-aad4-ad0f6c628191",
            "destinationActivityId": "2efcffa9-8e18-45cf-aac8-fcfdc8846df8",
            "outcome": "Done"
        }
    ]
}

视觉的: Elsa-工作流程

这是我的结果:

  • 信号:工作
  • 第一封电子邮件: 作品:

电子邮件样本

  • ForEach 失败,我在调试中发现了这个:

    失败:Elsa.Expressions.WorkflowExpressionEvaluator[0] 评估 JavaScript 表达式“{{ Input.Payload.ApproversList }}”时出错。消息:未定义输入 ReferenceError:未定义输入失败:Elsa.Services.ActivityInvoker[0] 调用工作流 de8e12d4645e4480abccbbe562b48448 Elsa.Exceptions.WorkflowException 的活动 2efcffa9-8e18-45cf-aac8-fcfdc8846df8 时出错:评估 JavaScript 表达式时出错“ {{ Input.Payload.ApproversList }}”。消息:未定义输入 ---> ReferenceError:未定义输入 --- 内部异常堆栈跟踪结束 --- 在 Elsa.Expressions.WorkflowExpressionEvaluator.EvaluateAsync(IWorkflowExpression expression, Type type, WorkflowExecutionContext workflowExecutionContext, CancellationToken cancelToken) 在Elsa.Extensions.WorkflowExpressionEvaluatorExtensions。1 expression, WorkflowExecutionContext workflowExecutionContext, CancellationToken cancellationToken) at Elsa.Activities.ControlFlow.Activities.ForEach.OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken) at Elsa.Services.ActivityInvoker.InvokeAsync(WorkflowExecutionContext workflowContext, IActivity activity, Func2 调用动作)

    失败:Elsa.Services.WorkflowInvoker[0] DbUpdateException 从 Elsa.WorkflowEventHandlers.PersistenceWorkflowEventHandler 引发的 IWorkflowEventHandler Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> Newtonsoft.Json.JsonSerializationException:为“Jint.Engine”类型的属性“Engine”检测到自引用循环。路径'Exception.InnerException.Error.Engine.Global'。

我需要迭代 a BudgetReleaseRequestApproverViewModel,发送电子邮件,等待操作,重复,但我无法弄清楚循环。

4

1 回答 1

1

这个答案基于我在GitHub 问题上提供的评论,这是对 OP 问题的重复。为了完整起见,我提供以下内容。

尝试使用ForEachinput活动的函数(确保所选语法是 JavaScript):

input('PayLoad').ApproverList

这将获得名为 的输入"PayLoad"

我不知道Liquid是否应该工作。从用户体验的角度来看,我们应该确保它这样做,或者如果没有,甚至不允许该选项。

于 2021-03-03T19:40:43.643 回答