zoukankan      html  css  js  c++  java
  • 介绍一下我设计的工作流引擎,欢迎拍砖仍鸡蛋

    前言

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

    本工作流基于了自主研发的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

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

  • 相关阅读:
    java环境变量配置
    线性表基本操作(没实现)
    请求路径问题(视频学习)
    SpringMVC_关于<url-pattern>
    SpringMVC_第一个程序
    Spring与Web
    Spring与MyBatis整合上_Mapper动态代理方式
    Spring_Spring与DAO_Spring的事务管理
    Spring_Spring与DAO_Spring的Jdbc模板
    Spring_Spring与AOP_AspectJ基于XML的实现
  • 原文地址:https://www.cnblogs.com/zc22/p/1597472.html
Copyright © 2011-2022 走看看