业务模块使用工作流程审批
# 业务模块使用工作流程审批
# 背景
在IoTCenter平台中,我们开发各种各样的应用插件,如WMS,访客等模块,经常都会遇到一些涉及流程上的审核功能,如入库申请审核,访客审核等业务,以往的实现方式为在各自的应用中设计一个审核流程,虽然也都能满足需求,确认也存在重复开发的情况,而且也无法满足负责的业务场景。
# 解决办法
从IoTCenter6.1版本开始,平台中增加了工作流程模块,可以设计业务模块间的流程审批。实现了对流程的自定义设计,支持多人审批、多审批节点、节点事件与设备命令执行的相关配置,如当前节点审批通过后控制设备执行某个命令。在审核流程中可以非常方便的查看待审核内容,已审核内容等。在跨模块间也提供的支持,通过IoTCenter内部的事件发布订阅机制,实现发起审批申请,订阅审核结果等。以下内容为新模块中如何使用审批流程代码实现方式。
# 实现步骤
# 业务架构
通过应用商店安装低代码平台
应用
# 代码实现
# 一、构造发起审批请求和订阅审批结果的模型
在你的应用模块中增加如下Model类。
FlowEventBaseModel
类,工作流程模型基础类库,BusinessTypeCode
为当前业务流程的编码属性,一般类业务流程就定义一个业务编码,如何访客审批。BusinessId
为当前业务数据的唯一标识,在接收审核结果时也会回传,接收到审核结果后你业务模块中根据业务编码,找到业务表数据进行处理。
using System.Collections.Generic;
namespace Ganweisoft.IoTCenter.Module.Industry.WMS.Models;
public class FlowEventBaseModel
{
/// <summary>
/// 业务类型编码:VisitorFlow
/// 传参约束,同一类审批使用相同的编码及名称
/// </summary>
public string BusinessTypeCode { get; set; }
/// <summary>
/// 业务类型名称,如访客审批流程
/// 传参约束,同一类审批使用相同的编码及名称
/// </summary>
public string BusinessTypeName { get; set; }
/// <summary>
/// 业务数据Id,如访客申请记录Id
/// </summary>
public string BusinessId { get; set; }
}
FlowSubcribeRequest
类,用于你的应用发起审批时的传参模型。
using EventBus;
using System.Collections.Generic;
namespace Ganweisoft.IoTCenter.Module.Industry.WMS.Models;
/// <summary>
/// 跨库订阅请求模型
/// 事件名称 : Ganweisoft.IoTCenter.Module.LowCodeFormFlow.FlowSubcribeRequest
/// </summary>
[EventName("Ganweisoft.IoTCenter.Module.LowCodeFormFlow.FlowSubcribeRequest",true)]
public class FlowSubcribeRequest: FlowEventBaseModel
{
/// <summary>
/// 业务表单数据,用于审批时显示表单的内容
/// </summary>
public List<BusinessFormLabel> FormLabels { get; set; }
}
BusinessFormLabel
类,业务表单数据,发起流程审批时,向流程中心构造易于阅读的表单数据
namespace Ganweisoft.IoTCenter.Module.LowCodeFormFlow.Models;
public class BusinessFormLabel
{
/// <summary>
/// 表单标签编码
/// </summary>
public string LabelCode { get; set; }
/// <summary>
/// 表单标签名称
/// </summary>
public string LabelName { get; set; }
/// <summary>
/// 表单标签值
/// </summary>
public string LabelValue { get; set; }
}
FlowSubcribeResponse
类,用于订阅工作流程审核返回的模型。
using EventBus;
using System;
namespace Ganweisoft.IoTCenter.Module.Industry.WMS.Models;
/// <summary>
/// 跨库订阅响应模型
/// 事件名称 : Ganweisoft.IoTCenter.Module.LowCodeFormFlow.FlowSubcribeResponse
/// </summary>
[EventName("Ganweisoft.IoTCenter.Module.LowCodeFormFlow.FlowSubcribeResponse", true)]
public class FlowSubcribeResponse : FlowEventBaseModel
{
/// <summary>
/// 流程Id
/// </summary>
public string FlowId { get; set; }
/// <summary>
/// 审核时间
/// </summary>
public DateTime FlowAuditDate { get; set; }
/// <summary>
/// 审核状态
/// </summary>
public int FlowAuditStatus { get; set; }
/// <summary>
/// 审核流程是否完成
/// </summary>
public bool FlowCompleted { get; set; }
/// <summary>
/// 审核流程各个节点数据
/// </summary>
public string FlowAuditData { get; set; }
}
WmsBusinessType
类,你的应用发起审批的业务编码,一个业务类型一个编码,此处以WMS应用为例,因为考虑到多语言中文转换,并未使用枚举值的方式定义。
namespace Ganweisoft.IoTCenter.Module.Industry.WMS.Models;
public class WmsBusinessType
{
/// <summary>
/// InboundApplication 入库申请审批,注意:不同的应用自行定义好名称
/// </summary>
public static WmsBusinessType InboundApplication { get; } =
new WmsBusinessType(1, "InboundApplication", "入库申请审批");
/// <summary>
/// OutboundApplication 出库申请审批,注意:不同的应用自行定义好名称
/// </summary>
public static WmsBusinessType OutboundApplication { get; } =
new WmsBusinessType(2, "OutboundApplication", "出库申请审批");
public static IEnumerable<WmsBusinessType> List()
{
return new[] { InboundApplication, OutboundApplication };
}
#region MyRegion
public string Name { get; private set; }
public string Code { get; private set; }
public int Value { get; private set; }
private WmsBusinessType(int val, string code, string name)
{
Value = val;
Name = name;
Code = code;
}
public static WmsBusinessType FromNameString(string nameString)
{
return List().Single(r => String.Equals(r.Name, nameString, StringComparison.OrdinalIgnoreCase));
}
public static WmsBusinessType FromCodeString(string codeString)
{
return List().Single(r => String.Equals(r.Code, codeString, StringComparison.OrdinalIgnoreCase));
}
public static WmsBusinessType FromValue(int value)
{
return List().Single(r => r.Value == value);
}
#endregion
}
# 二、应用发起流程审批请求
在数据保存成功后,发起流程审批,如下为入库申请存储后发起审批代码:
bool result = _stockinRepository.AddStockins(wms_Stockin, materials);
if (result)
{
var eventRequest = new FlowSubcribeRequest()
{
BusinessId = wms_Stockin.StockInId.ToString(),
BusinessTypeCode = WmsBusinessType.InboundApplication.Code,
BusinessTypeName = WmsBusinessType.InboundApplication.Name,
};
eventRequest.FormLabels.Add(new BusinessFormLabel()
{
LabelCode = "StockInNo",
LabelName = "入库单号",
LabelValue = wms_Stockin.StockInNo
});
//TODO 继续构造表单
_localEvent.PublishAsync<FlowSubcribeRequest>(eventRequest);
return OperateResult.SuccessedWithMessage("添加成功");
}
三、应用订阅流程审批结果
首先需要在你应用的Startup
类中Configure
方法中增加事件订阅的代码,其中FlowSubcribeHandler
类需要实现订阅接收数据后的处理流程。
public override void Configure(IApplicationBuilder builder, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
{
//注入处理审批结果的服务
services.AddScoped<FlowSubcribeResponseHandlerServiceImpl>();
}
public override void ConfigureServices(IServiceCollection services)
{
//自动创建升级表
builder.UseAutoMigrator<IndustryWMSGWDbContext>();
//订阅事件
builder.ApplicationServices.GetRequiredService<ILocalEventBus>()
.Subscribe<FlowSubcribeResponse, FlowSubcribeHandler>();
routes.MapDefaultControllerRoute();
}
FlowSubcribeHandler
类的实现如下
using Ganweisoft.IoTCenter.Module.Industry.WMS.Models;
using Ganweisoft.IoTCenter.Module.Industry.WMS.ServiceImpl;
using IoTCenterCore.Environment.Shell.Scope;
using IoTCenterCore.EventBus;
using Microsoft.Extensions.DependencyInjection;
namespace Ganweisoft.IoTCenter.Module.Industry.WMS
{
internal class FlowSubcribeHandler : ILocalEventHandler<FlowSubcribeResponse>
{
public async Task HandleEventAsync(FlowSubcribeResponse eventData)
{
Console.WriteLine("接收到审批结果的数据,你可以在这里处理你的审核逻辑啦");
//构造作用域,可以调用已注入的各种服务
using var scope = ShellScope.Context.CreateScope();
/*你也可以直接此处处理审核结果的逻辑,以下为WMS实现自己的业务流程,*/
//获取你的服务,通常为处理审核的服务,该服务必须要先在Startup进行注入
var service = scope.ServiceProvider.GetRequiredService<FlowSubcribeResponseHandlerServiceImpl>();
//调用你服务的实现方法,该方法可能需要修改数据的审核状态,自行根据业务场景更新数据即可
await service.HandleFlowSubcribeRequest(eventData);
}
}
}