介绍一下我设计的工作流引擎,欢迎拍砖仍鸡蛋

前言

代码源码不重要,重要的是思想!

本工作流基于了自主研发的ORM层、数据库同步层;实现了分布式环境下的工作流协同操作。

本工作流设计遵循以下原则:

1. 工作流基于.net DataTable模型,一切围绕这个DataTable展开;因为。net在界面很多的绑定都支持了datatable。

2. 工作流模型只负责状态的维护,不负责状态的扭转。即:每天下午4点新建订单转为失效订单 这种处理不属于工作流范畴,而是属于业务调度系统,是另外一个框架。

Pixysoft.Framework.Workflow 正文

ER图:

工作流框架包括了 工作流设计对象工作流实例对象 两大类。

1. 工作流设计对象 帮助用户自行设计一套包含表单所有状态状态默认扭转关系的对象。

2. 工作流实例对象 是根据用户设计好的工作流去生成实例调用。

同时说明一些设计要点:

1. WfFormSchema是表单设计对象,支持主从表的设计(就是一种自引用)

2. WfStatus是状态设计对象,包含了用户自定义的各种状态。

3. WfProjectHistory是记录工作流实例对象 状态扭转 的历史记录。

代码演示

创建一个工作流:

//新建工作流的主表单schema
DataTable maintb = new DataTable("POS_ITEMDISTRIBUTION");
maintb.Columns.Add(
"BILLCODE");
maintb.Columns.Add(
"CREATEDATE");
maintb.Columns.Add(
"MERCHANTCODE");
maintb.Columns.Add(
"BOXLOCATIONCODE");
maintb.Columns.Add(
"USRBOXCODE");
maintb.Columns.Add(
"STATUS");
maintb.Columns.Add(
"SHOPCODE");

//新建工作流的子表单 schema
DataTable subtb = new DataTable("POS_ITEMDISTRIBUTIONDETAIL");
subtb.Columns.Add(
"BILLCODE");
subtb.Columns.Add(
"ITEMTYPENAME");
subtb.Columns.Add(
"INPUTPRICE");
subtb.Columns.Add(
"INPUTQTY");
subtb.Columns.Add(
"REMARK");
subtb.Columns.Add(
"ITEMNAME");
subtb.Columns.Add(
"ITEMTYPECODE");
subtb.Columns.Add(
"BARCODE");
subtb.Columns.Add(
"ISNEW");
subtb.Columns.Add(
"ITEMCODE");
subtb.Columns.Add(
"COMMISSION");
subtb.Columns.Add(
"STAFFCOMMISSION");
subtb.Columns.Add(
"ID");

//获取工作流对象
IWorkflowManager manager = WorkflowManager.Instance;

//获取设计对象
IWorkflowDesigner designer = manager.GetDesigner();

//创建一个名为POS_ITEMDISTRIBUTION的工作流(配货单)主表单为上文主表
WfProjectSchema project = designer.CreateProject("POS_ITEMDISTRIBUTION""POS_ITEMDISTRIBUTION""BILLCODE", maintb);

//工作流主表配置自定义搜索的关键字
designer.AddFormKeyValue(project.FormSchema, "BILLCODE");
designer.AddFormKeyValue(project.FormSchema, 
"MERCHANTCODE");
designer.AddFormKeyValue(project.FormSchema, 
"USRBOXCODE");

//根据上文schema创建工作流的子表单
WfFormSchema subform = designer.CreateSubForm(project.FormSchema, "POS_ITEMDISTRIBUTIONDETAIL""ID", subtb);

//创建工作流的状态
WfStatus a001 = designer.CreateStartStatus(project, "NEW");
WfStatus a002 
= designer.CreateNextStatus(project, a001, "CHECKED");
WfStatus a003 
= designer.CreateNextStatus(project, a002, "ABNOMITY");
WfStatus a004 
= designer.CreateNextStatus(project, a003, "REJECTED");
WfStatus a005 
= designer.CreateNextStatus(project, a004, "PROCESSED");
WfStatus a006 
= designer.CreateNextStatus(project, a005, "PASSED");

//确认设计
designer.Commit();

新建工作流实例代码:

//获取工作流管理者

IWorkflowManager manager 
= WorkflowManager.Instance;

//获取表单的对象
DataTable table = manager.GetProjectTable("POS_ITEMDISTRIBUTION");

//获取子表单对象
DataTable subtable = manager.GetProjectSubTable("POS_ITEMDISTRIBUTION");

//处理表单数据
DataRow row = table.NewRow();
row[
"CREATEDATE"= DateTime.Now;
row[
"MERCHANTCODE"= "123123123";
row[
"BOXLOCATIONCODE"= "I0506";
row[
"USRBOXCODE"= "00154";
row[
"STATUS"= "NEW";
row[
"SHOPCODE"= "001";
table.Rows.Add(row);

//处理子表单数据
DataRow subrow = subtable.NewRow();
subrow[
"INPUTPRICE"= 100;
subrow[
"INPUTQTY"= 1;
subrow[
"ITEMNAME"= "hello";
subrow[
"ITEMTYPECODE"= "12312";
subrow[
"BARCODE"= "101540001125";
subrow[
"ISNEW"= false;
subrow[
"ITEMCODE"= "123123123";
subrow[
"COMMISSION"= 0.02;
subrow[
"STAFFCOMMISSION"= 0.02;
subtable.Rows.Add(subrow);


//根据工作流名称创建一个新的工作流
IWorkflowProject project = manager.CreateProject("POS_ITEMDISTRIBUTION");

//根据已经输入的表单创建工作流的表单
IWorkflowForm form = project.CreateForm(table);

//根据已经输入的子表单创建工作流的子表单
IWfFormCollection subforms = form.CreateSubForms(subtable);

//工作流确认
project.Commit();

工作流状态扭转:

IWorkflowManager manager = WorkflowManager.Instance;

//搜索状态为new的工作流
IWfProjectCollection projects = manager.SearchProjects("POS_ITEMDISTRIBUTION""NEW");

if (projects.Count == 0)
    
return;

//工作流对象转化为Datatable
DataTable projecttb = projects.ToTable();

//获取第0行的工作流对象的datarow
DataRow projectrow = projecttb.Rows[0];

//根据datarow获取对应的工作流
IWorkflowProject project = projects[projecttb.Rows.IndexOf(projectrow)];

//状态扭转
while (project.HasNext())
{
    
//获取工作流的表单
    IWorkflowForm form = project.GetForm();

    
//获取工作流表单对应的datatable
    DataTable maintb = form.ToTable();

    
//可以自行修改表单数据 例如绑定界面等



    
//更新表单数据
    form.Update(maintb);


    
//获取表单对应的子表单
    IWfFormCollection subforms = form.GetSubForms();

    
//获取子表单对应的datatable
    DataTable subformtables = subforms.ToTables();


    
//可以自行修改子表单数据 例如绑定界面等



    
//更新子表单数据
    subforms.Update(subformtables);

    
//转移到默认下个状态
    project.ToNext(null);
}

//确认操作
project.Commit();

后续

本工作流技术算是比较落后,不支持众多牛人关于扭转的算法。

个人觉得,状态扭转用代码实现是最方便的。当然,部分扭转是可以抽象成为一定的框架,例如BPEL之类的规范;变成各种时间调度、事件驱动调度等算法。但是这个如果和工作流本身的状态管理绑定在一起,就非常的不方便。

我相信用过所谓开源、0代码工作流的兄弟,一定厌倦那种xml的描述、厌倦用界面拖拖拉拉写企业代码。程序员怎么就变成了个二流的操作人员?这个是个误区,是过份夸大了xml的误区。

微软的workflow foundation是个不错的升华,重新把企业编程的权利转移给了程序员。

至于刚才所说的BPEL、时间调度算法等,我会在下一个框架实现,基于了本工作流的模型,下一个框架就叫

Pixysoft.Framework.Schedular

最后说一句,设计任何框架的目的:当然是以易用为主

原文地址:https://www.cnblogs.com/zc22/p/1597472.html