C# .NET 6 使用WorkFlow Core 创建工作审批流

news/2025/3/15 7:25:36/文章来源:https://www.cnblogs.com/chinasoft/p/18234893

1,背景

  工作流思想在上世纪60年代就有人提出过;70年代就有人开始尝试,但是由于当时许多的限制,工作流一直没有成功的被实现;80年代才出现第一批成功的工作流系统;90年代工作流技术走向了第一个发展高峰期;90年代后至今工作流出现了很多版本,但是主旨还是不变的,为了使我们的工作变得更加高效。

  通俗点,我们经常使用的OA系统上。关于一个材料的申报,又或者个人的请假。这些流程就属于工作流(工作审批流)。其中对于审批人和各个节点是可以动态操作的。

  工作流可以通过数据库设计的形式实现,也可以使用第三方的框架Elsa,Workflow Core。本文使用第二种,并详细的介绍一下代码实现和json实现工作流程。

2,安装

  使用Nuget包管理工具安装以下的包:  

    Workflow Core 3.10.0          核心包不解释

    WorkflowCore.DSL 3.10.0        json或者yaml注入需要

    WorkflowCore.Persistence.MySQL    持久化

3,文档

  JSON / YAML Definitions - Workflow Core (workflow-core.readthedocs.io)

 

  WorkFlowCore 加载Json文件 - 编程代码 (cscoder.cn)

 

4,例子

1,创建项目

  控制台或者WebApi项目均可,这里拿WebApi项目举例。(版本用的是.net 6)

2,添加工步

  工步文件需要继承StepBody。现在添加一个Hello.cs和Goodbye的工步,代码如下:

复制代码
using WorkflowCore.Interface;
using WorkflowCore.Models;namespace WorkFlowCore_Test.WorkFlows.HelloWord.Steps
{public class Hello : StepBody{public override ExecutionResult Run(IStepExecutionContext context){Console.WriteLine("Hello World!");return ExecutionResult.Next();}}
}
复制代码

 

复制代码
using WorkflowCore.Interface;
using WorkflowCore.Models;namespace WorkFlowCore_Test.WorkFlows.HelloWord.Steps
{public class Goodbye : StepBody{public override ExecutionResult Run(IStepExecutionContext context){Console.WriteLine("Goodbye World!");return ExecutionResult.Next();}}
}
复制代码

3,添加工作流文件

  工作流文件需要继承IWorkflow。现在开始添加:

复制代码
using WorkflowCore.Interface;
using WorkFlowCore_Test.WorkFlows.HelloWord.Steps;namespace WorkFlowCore_Test.WorkFlows.HelloWord
{public class HelloWorldWorkflow : IWorkflow{public string Id => "HelloWorld";public int Version => 1;public void Build(IWorkflowBuilder<object> builder){builder.StartWith<Hello>().Then<Goodbye>();}}
}
复制代码

4,配置和启动

  基本数据都准备好了之后,在项目启动文件进行一下配置。代码如下:

复制代码
using Microsoft.AspNetCore.Mvc;
using System.Xml.Linq;
using WorkflowCore.Interface;
using WorkflowCore.Services;
using WorkflowCore.Services.DefinitionStorage;
using WorkFlowCore_Test.Utils;
using WorkFlowCore_Test.WorkFlows.AskForLeave.Model;
using WorkFlowCore_Test.WorkFlows.AskForLeave;
using WorkFlowCore_Test.WorkFlows.HelloWord;
using WorkFlowCore_Test.WorkFlows.IfStatement;
using WorkFlowCore_Test.WorkFlows.IfStatement.Model;
using WorkFlowCore_Test.WorkFlows.Json.Steps;
using WorkFlowCore_Test.WorkFlows.SimpleDecision;namespace WorkFlowCore_Test
{public class Program{public static void Main(string[] args){var builder = WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddAuthorization();builder.Services.AddControllers();builder.Services.AddLogging(); // WorkflowCore需要用到logging service//持久化builder.Services.AddWorkflow(cfg =>{cfg.UseMySQL("server=127.0.0.1;Database=Workflow;Uid=root;Pwd=xunpai123.", true, true);});builder.Services.AddWorkflowDSL();//用来注入json和yamlvar app = builder.Build();//核心注入方法UseWorkflow(app);app.UseAuthorization();app.MapControllers();app.Run();}public static void UseWorkflow(WebApplication app){var host = app.Services.GetService<IWorkflowHost>();#region 工步注册//c#代码注册host?.RegisterWorkflow<HelloWorldWorkflow>();//json注册#endregionhost?.Start();// 通过DI获取IHostApplicationLifetime实例var applicationLifetime = app.Services.GetService(typeof(IHostApplicationLifetime)) as IHostApplicationLifetime;applicationLifetime?.ApplicationStopping.Register(() =>{host?.Stop();});}}
}
复制代码

 

  这个时候我们添加api控制器进行调用这个helloworld的流程。代码如下:

复制代码
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Diagnostics;
using System.Net.Http.Json;
using System.Text.Json.Nodes;
using WorkflowCore.Interface;
using WorkflowCore.Models;
using WorkflowCore.Services;
using WorkflowCore.Services.DefinitionStorage;
using WorkFlowCore_Test.Utils;
using WorkFlowCore_Test.WorkFlows.AskForLeave.Model;
using WorkFlowCore_Test.WorkFlows.SimpleDecision;namespace WorkFlowCore_Test.Controllers
{[Route("api/[controller]")][ApiController]public class TestApiController : ControllerBase{private IWorkflowController WorkflowService;private IWorkflowHost WorkflowHost;public TestApiController(IWorkflowController workflowService, IWorkflowHost workflowHost){WorkflowService = workflowService;WorkflowHost = workflowHost;}[Route("WorkFlowCoreTestDemo")][HttpGet]public string WorkFlowCoreTestDemo(){//var initialData = new LeaveRequestData//{//    RequestId = "11111",//    RequestMsg = "开始请假"//};//WorkflowHost.StartWorkflow("LeaveRequestWorkflow", 1, initialData);WorkflowService.StartWorkflow("HelloWorld");return "true";}}
}
复制代码

5,效果展示

  启动后调用我们的控制器方法,然后观看console 的变化,如图:

 

6,请假单流程

  请假单的流程创建的话需要用到等待的函数,等待管理员进行审核后进行下一步的操作。请假单的流程代码如下:

复制代码
    public class LeaveRequestData{public string RequestId { get; set; }public bool ManagerApproved { get; set; }public bool HRApproved { get; set; }public string RequestMsg { get; set; }}
复制代码
复制代码
using WorkflowCore.Interface;
using WorkFlowCore_Test.WorkFlows.AskForLeave.Model;
using WorkFlowCore_Test.WorkFlows.AskForLeave.Steps;
using WorkFlowCore_Test.WorkFlows.SimpleDecision.Steps;namespace WorkFlowCore_Test.WorkFlows.AskForLeave
{public class AskForLeaveWorkflow : IWorkflow<LeaveRequestData>{public string Id => "LeaveRequestWorkflow";public int Version => 1;public void Build(IWorkflowBuilder<LeaveRequestData> builder){builder.StartWith(context => Console.WriteLine("提交请假申请")).Activity("manage-audit", (data) => data.RequestMsg).Output(data => data.ManagerApproved, step => step.Result).Then<ManagerApprovalStep>().Input(step => step.AuditDataInfo, data => data).If(data => data.ManagerApproved).Do(then => then.StartWith(context => Console.WriteLine("经理审核")));}}
}
复制代码

  然后创建好之后,在启动文件进行注册一下:

            host?.RegisterWorkflow<AskForLeaveWorkflow, LeaveRequestData>();

  好了,接下来我们就可以用接口的形式进行模拟了。首先我们新增一个接口用来模拟申请请求代码如下:

复制代码
        [Route("WorkFlowCoreTestDemo")][HttpGet]public string WorkFlowCoreTestDemo(){var initialData = new LeaveRequestData{RequestId = "11111",RequestMsg = "开始请假"};WorkflowHost.StartWorkflow("LeaveRequestWorkflow", 1, initialData);//WorkflowService.StartWorkflow("HelloWorld");return "true";}
复制代码

  然后创建一个管理员的审批方法,用来审核通过或者拒绝。代码如下:

复制代码
        [Route("WorkFlowCoreTestDemo4")][HttpGet]public async Task<string> WorkFlowCoreTestDemo4(){//获取待决活动var approval = await WorkflowHost.GetPendingActivity("manage-audit", "worker1");if (approval != null){Console.WriteLine("需要批准的" + approval.Parameters);//提交活动成功await WorkflowHost.SubmitActivitySuccess(approval.Token, true);//true,代表审批通过。逻辑验证在步骤里面}return "请假工作流";}
复制代码

  好了,这样就形成闭环了。大家可以在postman上请求测试一下,观察console的变化了。

7,json注入

  最后就是json注入的方式了,这种方式也是目前我比较倾向的方式,和前端对接就很方便的。前端按照固定的格式给后端传入json数据,后端根据json数据解析工步进行开启工作流。

  首先需要创建一个json文件,json文件代码如下:

复制代码
{"Id": "HelloWorldJson","Version": 1,"Steps": [{"Id": "Hello","StepType": "","NextStepId": "Bye"},{"Id": "Bye","StepType": ""}]
}
复制代码

  然后在启动文件配置,注入一下json工作流:

复制代码
//json注册
var loader = app.Services.GetService<IDefinitionLoader>();     
var json = System.IO.File.ReadAllText("WorkFlows/Json/JsonYaml.json");// 假设文件位于程序运行目录
// 【json注入时候,stepType写这个程序集的类名】获取并打印全限定名,包括程序集名称
//Type myClassType = typeof(HelloWorldStep);
//string fullAssemblyClassName = myClassType.AssemblyQualifiedName;
loader?.LoadDefinition(json, Deserializers.Json);
复制代码

  到这里就可以了,创建一个api方法来调用看看:

复制代码
        [Route("WorkFlowCoreTestDemo6")][HttpGet]public string WorkFlowCoreTestDemo6(){WorkflowHost.StartWorkflow("HelloWorldJson", 1, null);return "";}
复制代码

  到这里就可以实现json注入工作流了。不过细心的朋友就发现了,我给的json文件中的step的type为什么是空的呢?是因为StepType取的是项目程序集工步的类名称,因为我的电脑项目和你们的项目不一样,所以这里没有写。大家可以自行百度搜搜看,我这里还是放一下我的json例子吧。

复制代码
{"Id": "HelloWorldJson","Version": 1,"Steps": [{"Id": "Hello","StepType": "WorkFlowCore_Test.WorkFlows.Json.Steps.HelloWorldStep, WorkFlowCore-Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","NextStepId": "Bye"},{"Id": "Bye","StepType": "WorkFlowCore_Test.WorkFlows.Json.Steps.HelloWorldStep, WorkFlowCore-Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}]
}
复制代码

 

5,结语

  例子备注写的比较多,就不多赘述了。有问题的话就留言吧,感谢观看~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/720884.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单实现Viper配置管理

本文由 ChatMoney团队出品简介 前面实现的一个简易suno-api。是使用cookie来获取suno-token发起请求的。当时并没有通过配置的方式来获取cookie,而是直接在代码中写死了cookie的值,这种做法并不好,所以现在打算把cookie值改造为一个配置,通过viper来读取。 什么是viper Vipe…

全局 type 类型的寻找 typescript 类型 - fabric.Canvas

全局 type类型的寻找 typescript 类型 - fabric.Canvas declare type ExtCanvas = fabric.Canvas & {isDragging: boolean;lastPosX: number;lastPosY: number; };这个代码 没有定义 fabric.Canvas,然后看看提示说在namespace定义了。这个是子项目,没有type定义,上父项目…

Linux中sed命令b选项屏蔽指定的处理区域

001、Linux中sed命令b选项屏蔽指定的处理区域[root@pc1 test2]# ls a.txt [root@pc1 test2]# cat a.txt ## 测试数据 1 01 02 a 2 03 04 a 3 05 06 a 4 07 08 5 09 10 k 6 11 12 a 7 13 14 8 15 a i 9 17 18 a [root@pc1 test2]# sed 1,3b; s/a/Q/ a.tx…

SwiftUI 热门开源库推荐第1期 - 凡人程序猿 - iOS开发

大家好,我是凡人程序猿。周末给大家分享几个我在用已久的 GitHub 开源库,这些开源库使用简单,功能强大,使用好它们能够为我们节省大量的开发时间。大家好,周末给大家分享几个我在用已久的 GitHub 开源库,这些开源库使用简单,功能强大,使用好它们能够为我们节省大量的开…

初探堆栈欺骗之静态欺骗

本文首发先知社区:https://xz.aliyun.com/t/14487 首先介绍一下堆栈欺骗的场景,当我们用一个基本的 shellcode loader 加载 cs 的 shellcode,在没有对堆栈做任何事情时,我们的堆栈是不干净的,我们去看一下堆栈时会发现有很多没有被解析的地址在其中,这显然是不正常的,因…

LLM 扩展开发工具

参考知乎: 大模型Agent智能体25款产品、商业案例随笔记(一) 、 基于大模型的AI搜索15款产品随笔记(二) LLM 扩展开发工具: 1、开源且无需编码(No-Code)的 LLM 应用构建工具: https://flowiseai.com/ ,将永远免费供商业和个人使用。代码库: https://github.com/Flow…

Linux 提权-Cron Jobs

本文通过 Google 翻译 Cron Jobs – Linux Privilege Escalation - Juggernaut-Sec 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。导航0 前言 1 什么是 Cron Job?1.1 了解 Crontabs 和 Cron 目录 1.2 如何在 Crontab 文件中读取 Cron 作…

Spring Boot heapdump泄露内存分析方法

一、查看加密星号信息(适用于数据库密码、ftp、ssh) 1.首先访问地址:http://url/actuator/env 出现一些配置信息,搜索带有******可以看到ftp的ip,username,password 2.接着访问http://url/actuator/heapdump 下载下来heapdump文件 使用java自带的工具进行分析 位置:C:\Pro…

计算机简史-概述

讲解计算机发展的历史,人类如何从手工计算,发明工具,最后演变成如今的计算机。讲解计算机发展的历史,人类如何从手工计算,发明工具,最后演变成如今的计算机。 ‍ 为什么要了解计算机发展历史 简单说说我的看法:了解计算机发展历史,对我们掌握计算机底层的原理是非常有帮…

使用 Hugging Face 推理终端搭建强大的“语音识别 + 说话人分割 + 投机解码”工作流

Whisper 是当前最先进的开源语音识别模型之一,毫无疑问,也是应用最广泛的模型。如果你想部署 Whisper 模型,Hugging Face 推理终端 能够让你开箱即用地轻松部署任何 Whisper 模型。但是,如果你还想叠加其它功能,如用于分辨不同说话人的说话人分割,或用于投机解码的辅助生…

2024年离职和后续发展

目录前言个人情况2023年底2024年初,找工作失败2024年2月,计划开公司家里关系开公司原因2024年4月,说明我要离职的想法5月,开始办理公司6月,开始准备资料,提离职 前言 最近我也快离职回家了,简单说一下最近发送的事情好了,这里按照时间的顺序 个人情况 2022年毕业,来到…

华为matebook 14s笔记本,Chrome浏览器开启硬件加速,屏幕闪屏,黑框,页面屏幕卡死,解决办法

解决办法使用了 https://zhuanlan.zhihu.com/p/644296061 这个连接下的最后一个折中办法解决! 一、现象 Chrome开启“硬件加速模式”后,在观看视频时,尤其是全屏时,会出现短暂黑屏或黑块或闪屏。如果关闭“硬件加速”,则会造成播放某些高清视频(例如HEVC)视频或弹幕卡顿(…