在工作流处理表中,首先我们区分流程模板和流程实例两个部分,这个其实就是类似模板和具体文档的概念,我们一份模板可以创建很多个类似的文档,文档样式结构类似的。同理,流程模板实例为流程实例后,就是具体的一个流程表单信息了,其中流程模板和流程实例表单都包括了各个流程步骤。在流程实例的层次上,我们运行的时候,需要记录一些日志方便跟踪,如流程步骤的处理日志,流程实例表单的处理日志等这些信息。

一旦流程实例根据模板创建后,流程先根据模板初始化后,在处理过程还可以动态增加一些审批步骤,使得我们的处理更加弹性化。如下所示。

我们在系统中动态定义很多业务表单,因此需要动态展示创建表单的入口;另外每种业务表单的创建和查看也需要实现动态的构建,才能更好的实现我们业务流程的处理规则。

1、动态显示流程业务入口

我们在工作流模块中,有一个统一的业务创建入口,方便用户的使用,我们需要创建什么类型的业务表单,从中选择创建接口,是一个便利的入口。

我们实现这个展示会相对比较简单,但是创建业务表单的入口需要动态的处理,是根据用户配置的参数进行动态的处理的。

上述的界面是通过在数据库里面动态获取信息,并创建不同的按钮的,因此可以实现流程入口的动态显示,不需要硬编码带来后期的修改。实现的逻辑就是在右侧内容区域的流布局区域,根据表单信息动态创建按钮,并实现对应的事件响应即可,实现代码如下所示。

        /// <summary>
/// 绑定表单列表的展示
/// </summary>
private void BindData()
{
//使用流布局,清空
this.flowLayoutPanel1.Controls.Clear(); //根据条件获取表单列表,并动态创建按钮
string where = GetConditionSql();
List<FormInfo> list = BLLFactory<BLL.Form>.Instance.Find(where);
int i = ;
foreach (FormInfo info in list)
{
//在流布局中动态加入按钮
SimpleButton button = CreateButton(info, i++);
this.flowLayoutPanel1.Controls.Add(button);
}
}
/// <summary>
/// 根据流程模板的表单信息,动态创建入口按钮
/// </summary>
/// <param name="info">模板的表单信息</param>
/// <param name="imageIndex">图标</param>
/// <returns></returns>
private SimpleButton CreateButton(FormInfo info, int imageIndex)
{
//定义按钮,在流布局的图标、位置、偏移空间、字体颜色等
SimpleButton button = new SimpleButton();
button.ImageList = this.imageCollection1;
button.ImageLocation = ImageLocation.TopCenter;
button.Padding = new Padding(, , , );
button.Size = new Size(, );
button.Margin = new Padding(, , , );
button.ImageIndex = imageIndex;
button.Font = new Font("宋体", 9f, FontStyle.Bold);
button.ForeColor = Color.Blue;
button.Text = info.FormName;
button.Tag = info.ID;
if (!string.IsNullOrEmpty(info.Remark))
{
button.ToolTip = info.Remark;
button.ToolTipIconType = DevExpress.Utils.ToolTipIconType.Information;
}
//所有按钮统一处理事件
button.Click += new EventHandler(button_Click); return button;
}

按钮的处理有一个统一的事件实现新建业务表单的赋值和显示窗体。实现的代码如下所示。

        /// <summary>
/// 单击某个动态生成的按钮,触发的申请表单创建界面
/// </summary>
void button_Click(object sender, EventArgs e)
{
SimpleButton button = sender as SimpleButton;
if (button != null)
{
//获取模板表单必要的信息
var formId = button.Tag.ToString();
var formInfo = BLLFactory<BLL.Form>.Instance.FindByID(formId);
if (formInfo != null && !string.IsNullOrEmpty(formInfo.ApplyWin))
{
try
{
//动态构建创建申请单的界面窗体并赋值
var dlg = Assembly.GetExecutingAssembly().CreateInstance(formInfo.ApplyWin) as FrmAddApply;
dlg.FormID = button.Tag.ToString();
dlg.ShowDialog();
}
catch(Exception ex)
{
LogHelper.Error(ex);
MessageDxUtil.ShowError(ex.Message);
}
}
else
{
MessageDxUtil.ShowTips(button.Text + "暂未开通");
}
}
}

2、动态显示和创建业务表单的处理

有了上面动态列表的显示,以及统一的按钮处理,事情就好办很多。

我们刚才也涉及到了业务表单的创建调用,是通过反射处理实现业务表单创建窗口的赋值和显示的。

    //动态构建创建申请单的界面窗体并赋值
var dlg = Assembly.GetExecutingAssembly().CreateInstance(formInfo.ApplyWin) as FrmAddApply;
dlg.FormID = button.Tag.ToString();
dlg.ShowDialog();

这其中涉及的配置信息就是我们创建一个业务窗口所需要的参数的,如下数据表所示。

其实通过创建这些业务表,我们在封装继承上也做了很多工作,以极大简化业务表单的处理,以下是业务表单新建、编辑、查看的处理操作,它们已经继承自各自的处理类,因此在反射的时候,统一转换为基类即可实现处理。

首先我们来了解一下业务表单的对应关系,一般创建一个业务流程处理,都需要有一个具体的创建业务表单的界面,以及一个查看处理表单的界面。

为了方便,我们尽可能减少代码编写,我们需要把大多数的逻辑处理放在基类实现,这样我们在新增一个业务表单的时候就可以减少很多代码编写及维护了。

例如对于请假申请的业务表单,它们的窗体定义如下所示。

而查看请假申请的业务表单则是如下。

从上面关系我们可以看到,其中对于工作流业务表单的窗体界面都可以实现标准的处理了,继承自某个基类,然后整合相关的数据处理规则即可。

那么我们提炼业务信息后,可以使用代码生成工具快速生成,这样可以极大提高我们的开发效率。

下面就是使用我们定制的框架代码生成工具 Database2Sharp,就可以极大简化工作流业务表单的生成处理了。

3、查看申请单的处理动态化

在我的待办业务列表里面,就可以看到刚才的表单了,双击可以进行查看,以及相关的审批处理工作。

对于一个流程处理操作,我们知道一般有审批通过、拒绝、退回到某步骤、转发到内部阅读、阅读等处理步骤,以及包括起草者能撤销表单呢等操作,当然如果还有一些具体的业务,可能还会有一些流程的处理才操作,不过基本上也可以归结为上面几种,只是他们每步处理的数据内容不同而已。因此审批的操作步骤分类如下所示。

除了上面这些基础的表单处理动作,有时候还会定义多个处理人共同处理的会签步骤,只有全部通过才算通过的处理流程。

会签是指创建一个或多个子流程供相关人员进行审批,等待全部人员完成处理后再次回到主流程上,然后决定是否继续流转到下一个流程步骤上去,一般的申请单的主流程如下所示。

这里设置的会签处理就是其中一个步骤,一旦会签处理步骤发起会签,就会构建多个可供审批的子流程了,如下所示。

针对上面的业务介绍,那么显示申请单的处理就必须处理这些步骤是否可用,或者决定进入哪一个流程步骤的了。

对于审批性质的表单,如下是界面的审批操作

而如果是发起【发起会签】的处理操作,那么则是把相关的投票权发送给处理人进行会签处理。

以上就是工作流表单里面设计到的几个动态处理的业务场景,同时我们通过利用动态的信息处理,可以减少硬编码的可能性,同时增加系统的弹性处理,非常方便,由于相关工作流的基类设计较为合理,因此在代码生成的时候,只需要关注简单的界面展示调整即可,通过这种处理方式,可以在多个层面降低开发工作流界面的复杂度,同时系统又增加了很多可扩展性的处理,如可以动态增加表单、动态增加流程步骤、动态指定不同的业务处理类型等等。

通过这些的介绍,我们就是系统在开发的时候,尽可能提取不变的内容或者规则,从而在实际增量开发的过程中降低开发的时间,减少难度,同时统一处理做法,既可以提高效率,又可以提高稳定性和统一性。

Winform开发框架中工作流模块的动态处理的更多相关文章

  1. Winform开发框架中工作流模块之申请单草稿处理

    在我们开发工作流模块的时候,有时候填写申请单过程中,暂时不想提交审批,那么可以暂存为草稿,以供下次继续填写或者提交处理,那么这个草稿的功能是比较实用的,否则对于一些填写内容比较多的申请单,每次要重填写 ...

  2. 参照企业微信审批业务,在Winform开发框架中工作流模块的实现业务审批

    目前微信的企业号已经切换到企业微信里面,这个是一个APP程序,提供了很丰富的企业应用,其中包括了业务审批处理,审批业务包括请假.报销.费用.出差等很多个审批场景,在Winform开发框架中工作流模块这 ...

  3. Winform开发框架中工作流模块之审批会签操作(2)

    前面随笔介绍了请假申请单和报销申请单两个不同的业务表单的流程处理,一个是单表信息,一个包含明细的主从表信息,后者包含了条件流程的处理,在流程审批中,一般还有一种流程处理就是会签的操作,会签处理是几个审 ...

  4. Winform开发框架中工作流模块之审批会签操作

    在前面介绍了框架中工作流的几个开发过程,本篇随笔重点介绍一下日常审批环节中的具体处理过程,从开始创建表单,以及各个审批.会签过程的流转过程,希望大家对其中流程的处理有一个大概的印象. 1.请假申请表单 ...

  5. Winform开发框架中工作流模块的业务表单开发

    在我们开发工作流的时候,往往需要设计到具体业务表单信息的编辑,有些是采用动态编辑的,有些则是在开发过程中处理的,各有各的优点,动态编辑的则方便维护各种各样的表单,但是数据的绑定及处理则比较麻烦,而自定 ...

  6. Winform开发框架中工作流模块的表设计分析

    在较早博客随笔里面写过文章<Winform开发框架之简易工作流设计>之后,很久没有对工作流部分进行详细的介绍了,本篇继续这个主题,详细介绍其中的设计.实现及效果给大家,这个工作流在好几年前 ...

  7. 在Winform开发框架中,利用DevExpress控件实现数据的快速录入和选择

    在实际的项目开发过程中,有好的控件或者功能模块,我都是想办法尽可能集成到我的WInform开发框架中,这样后面开发项目起来,就可以节省很多研究时间,并能重复使用,非常高效方便.在我很早之前的一篇博客& ...

  8. 在Winform开发框架中实现对数据库的加密支持

    在很多情况下,我们需要对数据库进行加密,特别是Access数据库.Sqlite数据库,这些直接部署在客户端的数据,因为数据也是客户的资产,数据库总是存在很多相关的秘密或者重要的业务数据,所以一般来说, ...

  9. Winform开发框架中的综合案例Demo

    在实际的系统开发中,我们往往需要一些简单的的案例代码,基于此目的我把Winform开发框架中各种闪光点和不错的功能,有些是我们对功能模块的简单封装,而有些则是引入了一些应用广泛的开源组件进行集成使用, ...

随机推荐

  1. 监控mysql

    Mysql服务器监控 管理MySql服务器属于应用程序监控范畴.这是因为绝大多数性能参数是有MySql软件产生的,而不属于主操作系统的一部分. 如当前所提到的,应该总是先监控基础操作系统,然后监控My ...

  2. Docker系列06—基于容器制作镜像并上传到Docker Registry

    本文收录在容器技术学习系列文章总目录 1.制作镜像 1.1 镜像的生成途径 基于容器制作 dockerfile,docker build 本篇主要详细讲解基于容器制作镜像:基于dockerfile 制 ...

  3. windows资源管理器多标签打开 windows文件夹多标签浏览 浏览器tab页面一样浏览文件夹 clover win8 win10 报错 无响应问题怎么解决 clover卡死 clover怎么换皮肤

    大家都知道,我们打开一堆文件夹的时候,是什么样子 “厚厚的一叠”图标堆叠在一起的,非常的不方便 那么,是不是可以像浏览器一样的tab页面展示呢? 答案是可以的 安装好就是这样子的 是不是方便漂亮了很多 ...

  4. Spring Boot 系列总目录

    一.Spring Boot 系列诞生原因 上学那会主要学的是 Java 和 .Net 两种语言,当时对于语言分类这事儿没什么概念,恰好在2009年毕业那会阴差阳错的先找到了 .Net 的工作,此后就开 ...

  5. Spring框架浅析

    一.一个简单的示例 1.引入依赖和配置 pom.xml <?xml version="1.0" encoding="UTF-8"?> <pro ...

  6. Java AQS 概述

    AQS 概述 AQS(队列同步器,AbstractQueuedSynchronizer),是用来构建锁或其他同步组件的核心基础框架(比如 ReentrantLock.ReentrantReadWrit ...

  7. 【阿里云】在 Windows Server 2016 下使用 FileZilla Server 安装搭建 FTP 服务

     Windows Server 2016 下使用 FileZilla Server 安装搭建 FTP 服务 一.安装 Filezilla Server 下载最新版本的 Filezilla Server ...

  8. LayoutInflater.inflate()方法两个参数和三个参数

    转载请标明出处:https://www.cnblogs.com/tangZH/p/7074853.html  很多人都用过LayoutInflater(布局填充器) 对于我来说通常使用下面两种:Lay ...

  9. 四、View的工作原理

    1.ViewRoot和DecorView ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完 ...

  10. H-ui框架信息图标点击跳出页面问题

    在html中为消息a标签添加id: 在static/h-ui/js/H-ui.min.js添加事件: