阅读 188

使用 RulesEngine 实现基础购买获得积分

上一篇文章中我们已经实现了注册送积分,其实参与事件获得积分都可以通过相似的规则进行实现。

今天我们要实现购买获得积分的规则,这是最常用的积分获取方式。它与之前的参与事件获取积分最大的不同在于通过购买获得的积分是基于付款金额/积分比率的,虽然大部分情况下这个比率是一个固定数值,但由于购买金额是一个变量,因此通过购买获得的积分也不是一个固定的数值,不能像参与事件获得积分一样将最终获得的积分直接写在规则中,而是要通过为变量的付款金额带入一个简单的计算公式才能获得。

添加规则

{
    "WorkflowName": "Payment",
    "Rules": [
        {
            "RuleName": "GivePointsByPayment",
            "SuccessEvent": "Pay success and earn {0} points",
            "RuleExpressionType": "LambdaExpression",
            "Expression": "true",
            "Actions": {
                "OnSuccess": {
                    "Name": "OutputExpression",
                    "Context": {
                        "Expression": "subtotal * 0.5"
                    }
                }
            }
        }
    ]
}
复制代码

相比于注册送积分,这个新的规则有以下需要注意的地方:

  1. WorkflowName,RulesEngine 触发规则的标识符,一定要和之前不同,且在之后会被用到。
  2. SuccessEvent,因为获取的积分并不是一个固定数值,所以具体的积分在这里还是一个变量。
  3. Actions,新引入的参数,在满足特定情况的时候可以触发的活动,这里因为只考虑程序主逻辑,所以只写了 OnSuccess
    1. 在该活动的 ContextExpression 中写入了这个规则的具体计算公式 subtotal * 0.5
      1. 其中 subtotal 为付款金额的变量名,之后我们会演示如何使用它。复杂类型还可以写作 object.field 这样的格式。
      2. 0.5 是付款金额/积分比率,我们这里可以将其固定为每 1 块钱可以获得 0.5 积分。

可以看出相比注册送积分,购买获得积分的规则在结果中多出了变量,而变量是由公式计算获得,而公式本身又有变量存在。那我们接下来看看如何使用这个规则。

使用规则

public async Task<RuleResponse> Verify(string workFlowName, JsonElement args)
{
    var input = new List<RuleParameter>();
    switch (workFlowName)
    {
        case "Payment":
            input.Add(new RuleParameter("subtotal", args.GetProperty("subtotal").GetDecimal());
            break;
    }

    RuleResponse response = null;
    var resultList = await _engine.ExecuteAllRulesAsync(workFlowName, input.ToArray());

    resultList.OnSuccess(message =>
    {
        var actionResult = resultList
            .FirstOrDefault(ruleResult => ruleResult.ActionResult != null)
            ?.ActionResult.Output;
        response = new RuleResponse() {message = string.Format(message, actionResult)};
    });

    return response;
}
复制代码

我们对 Verify 函数进行了改动,重点在以下地方:

  1. 返回值改成了 RuleResponse,现在它至于一个 string 型的成员 message,准备在之后对其进行扩展。
  2. 接收参数 string workFlowNameJsonElement args
    1. 其中 workFlowName 标识准备触发的规则的名称,我们现在有多个规则,所以需要将其进行参数化。
    2. argsJSON 格式的相关参数,不同的规则对其处理会不一致。
  3. 在进行规则匹配前需要将规则中用到的参数放入规则引擎中,具体做法是构造一个 RuleParameter 其中需要传入两个参数。
    1. 第一个参数是规则中的变量名,表明这个参数要替换的规则中的变量的名字。
    2. 第二个参数是给该变量的赋值。这里是从 Json 中取出 subtotal,并将其转变为 C# 中的 Decimal 类型。
  4. 最后在 OnSuccess 时通过 ActionResult.Output 取出通过积分公式计算获得的结果,再通过 string.Format 将其替换规则中 SuccessEvent 的变量,获得最终结果。

代码上的实现就是这两个部分,下面看看效果。

调用调试

注册获得积分

注册.png

购买获得积分 购买.png

至此,最基础的购买获得积分也完成了。

文章分类
后端
文章标签