首页 > .net erp(办公oa)开发平台架构之流程服务概要介绍

.net erp(办公oa)开发平台架构之流程服务概要介绍

背景

搭建一个适合公司erp业务的开发平台。

架构概要图

 

 

流程引擎开发平台

  包含流程引擎设计器,流程管理平台,流程引擎服务。目前只使用单个数据库进行管理。

  流程引擎设计器

   采用silverlight进行开发,本质是对流程模型进行设计,并生成xml。包含:人工节点,自动节点,并行开始节点,并行结束节点,消息节点,文本节点。

  示例模型定义图形:

    

  示例模型定义xml:

xml version="1.0" encoding="gb2312"?>
<ProcessModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><BaseInfo><Key>dddKey><Title>新建模型Title><Description>发起人Description><CreateTime>0001-01-01T00:00:00CreateTime><Author><StaffNo>34StaffNo><UserName>车江毅1UserName>Author><Type>CommonType><Compilation>DebugCompilation>BaseInfo><Variables><Variable Name="myValue1" Value="今天天气好晴朗" Mode="Flow" /><Variable Name="myValue2" Value="v2" Mode="Flow" /><Variable Name="myValue3" Value="v3" Mode="Flow" /><Variable Name="myValue4" Value="true" Mode="Flow" />Variables><Nodes><BaseNode xsi:type="StartNode" Key="start1" Text="开始" Location="236 10"><Routes><Route To="auto1" Text="" Location="0 0"><RouteScripts />Route>Routes><BeginScripts /><EndScripts />BaseNode><BaseNode xsi:type="AutoNode" Key="auto1" Text="系统判断" Location="236 95"><Routes><Route To="man1" Text="线1" Location="0 0"><Code>myValue4=='true']]>Code><RouteScripts />Route><Route To="人工2" Text="线" Location="0 0"><Code>myValue4=='false']]>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Scripts><Script><Code>api.Forword('http://webservice.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx','getTVstationDataSet','theAreaID:2')]]>Code>Script><Script><Code>api.UpdateVariable('063550')]]>Code>Script>Scripts>BaseNode><BaseNode xsi:type="ManNode" Key="man1" Text="人工1" Location="167 205"><Routes><Route To="并行开始1" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Participants><Participant Mode="Code"><Code>api.Split('034','#')]]>Code>Participant><Participant Mode="Variable"><Code>myValue3]]>Code>Participant>Participants><Solt OrderCount="2" Mode="Once" /><Decisions><Decision Text="同意" /><Decision Text="不同意" />Decisions>BaseNode><BaseNode xsi:type="EndNode" Key="结束" Text="结束" Location="238 732"><Routes /><BeginScripts /><EndScripts />BaseNode><BaseNode xsi:type="ManNode" Key="人工2" Text="人工2" Location="324 203"><Routes><Route To="并行开始1" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Participants /><Decisions />BaseNode><BaseNode xsi:type="ParallelBeginNode" Key="并行开始1" Text="并行签入" Location="237.047607421875 312"><Routes><Route To="人工3" Text="线" Location="0 0"><Code>Code><RouteScripts />Route><Route To="人工4" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts />BaseNode><BaseNode xsi:type="ParallelFinishNode" Key="并行结束1" Text="并行结束1" Location="240 571"><Routes><Route To="消息1" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts />BaseNode><BaseNode xsi:type="ManNode" Key="人工3" Text="人工3" Location="95 378"><Routes><Route To="自动1" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Participants /><Decisions />BaseNode><BaseNode xsi:type="ManNode" Key="人工4" Text="人工4" Location="392 379"><Routes><Route To="自动2" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Participants /><Decisions />BaseNode><BaseNode xsi:type="AutoNode" Key="自动1" Text="自动1" Location="98 483"><Routes><Route To="并行结束1" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Scripts />BaseNode><BaseNode xsi:type="AutoNode" Key="自动2" Text="自动2" Location="394.714294433594 474.952362060547"><Routes><Route To="并行结束1" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Scripts />BaseNode><BaseNode xsi:type="MessageNode" Key="消息1" Text="消息1" Location="239 656"><Routes><Route To="结束" Text="线" Location="0 0"><Code>Code><RouteScripts />Route>Routes><BeginScripts /><EndScripts /><Participants /><MessageVariables /><TemplateKey>0TemplateKey><TemplateName />BaseNode>Nodes>
ProcessModel>

 

 



  常规界面如下:

  

 

流程管理平台

  包含:流程模型管理,流程管理,流程任务管理,流程操作记录,流程服务接口日志查询,流程异常查询,流程流转调试日志查询,开发者用户管理等。

  可以管理流程模型历史版本及版本切换,流程异常时候的流程节点切换,流程任务的转交等。

 界面如下:

 

流程服务

  包含:流程接口和流程任务接口。

   
/// /// 业务流程服务接口/// public interface IProcessService{/// /// 获取业务流程/// /// 业务流程ID
        ProcessInfo GetProcessById(Guid guid);/// /// 批量获取业务流程/// /// 多个业务流程IDProcessListInfo GetProcessesByIds(List guids);/// /// 根据流程发布者,获取业务流程列表/// /// 用户的信息 参看UserInfo对象注释/// 模型key  可选(多个)/// 关键词(标题) 可选/// /// /// ProcessListInfo GetProcessListByOriginator(UserInfo user, List<string> modelkeys, string keyword, int pageIndex, int pageSize);/// /// 根据流程参与者,获取业务流程列表/// /// 用户的信息 参看UserInfo对象注释/// 模型key 可选(多个)/// 关键词(标题) 可选/// 任务所在节点key 可选/// 任务完成状态/// /// /// ProcessListInfo GetProcessListByParticipant(UserInfo user, List<string> modelkeys, string keyword, string nodekey, EnumTaskStateQuery state, int pageIndex, int pageSize);/// /// 根据模型keys, 获取业务流程列表/// /// 模型关键词 (多个)/// 关键词(标题) 可选/// /// /// ProcessListInfo GetProcessListByModel(List<string> modelkeys, string keyword, int pageIndex, int pageSize);/// /// 创建业务流程/// /// 业务流程对应的模型key/// 业务流程标题/// 业务流程描述/// 业务流程使用变量 可选/// 业务流程发起人 参看UserInfo对象注释/// 操作记录 可选/// ProcessInfo CreateProcess(string modelkey, string title, string description, List variables, UserInfo user, OperationRecordInfoArgs operationArgs);/// /// 更新业务流程/// /// 业务流程的ID/// 业务流程的标题/// 业务流程的描述/// 业务员流程的变量 可选void UpdateProcess(Guid guid, string title, string description, List variables);/// /// 结束业务流程/// /// 业务流程的IDvoid FinishProcess(Guid guid, UserInfo user, OperationRecordInfoArgs operationArgs);/// /// 创建流程操作记录/// /// 操作用户不能为空/// 操作记录不能为空void CreateProcessOperationRecord(Guid guid, UserInfo user, OperationRecordInfoArgs operationArgs);}

 

 

   /// /// 任务服务接口/// public interface ITaskService{/// /// 根据任务id,获取任务/// /// 任务id/// TaskInfo GetTaskByID(string id);/// /// 根据任务id,批量获取任务/// /// 多个任务id/// TaskListInfo GetTasksByIDs(List<string> ids);/// /// 根据业务流程id,获取任务信息列表/// /// 任务状态/// 业务流程id/// 
        TaskListInfo GetTaskListByProcessID(EnumTaskStateQuery state, Guid processId);/// /// 根据用户,获取任务信息列表/// /// 用户的信息 参看UserInfo对象注释/// 任务状态/// /// /// TaskListInfo GetTaskListByUser(UserInfo user, EnumTaskStateQuery state, int pageIndex, int pageSize);/// /// 根据用户和流程,获取任务信息列表/// /// 用户的信息 参看UserInfo对象注释/// 业务流程id/// 当前活动节点key 可选/// 任务状态/// /// /// TaskListInfo GetTaskListByUserAndProcess(UserInfo user, Guid processId, string nodekey,EnumTaskStateQuery state, int pageIndex, int pageSize);/// /// 根据业务流程模型key,获取任务信息列表/// /// 用户的信息 参看UserInfo对象注释/// 业务模型key 可选(多个)/// 当前活动节点key 可选/// 任务状态/// /// /// TaskListInfo GetTaskListByUserAndModel(UserInfo user, List<string> modelkeys, string nodekey, EnumTaskStateQuery state, int pageIndex, int pageSize);/// /// 执行任务/// /// 任务id/// 任务的动作 例如:“同意”“不同意”/// 流程参数 可选/// 操作信息 必填TaskInfo ExecuteTask(string id, string action, List variables, OperationRecordInfoArgs operationArgs);/// /// 转交任务/// /// 任务id/// 任务转交人信息 参看UserInfo对象注释/// 操作信息 传null则无转交操作记录TaskInfo TransferTaskWithOperationRecordInfoArgs(string id, UserInfo toUser, OperationRecordInfoArgs operationArgs);

 

 

 

分布式架构概想

  分布式拆库方案:流程维度和用户维度,流程维度数据库按照流程定义模型的唯一标识hash,来拆分到不同的数据库。所有流程创建和流程任务的创建都在不同的数据库中。用户维度数据库按照用户标识hash,来拆分到不同的数据库。

  拆库优点:数据被拆分,不影响同一个业务流程流转,性能会得到提升。

  拆库缺点:采用异步消息通知,做用户代办任务和完成任务冗余及同步。采用BI工具或者hadoop等进行数据报表等分析。开发,维护复杂度等都会提升。

  结论:如果不是做大型产品或服务,不会进行分布式架构。

(此文只做阶段性的总结,也许对同样做流程引擎的人有些启发,也欢迎交流。分布式相关架构可以参考本人其他文章)

转载于:https://www.cnblogs.com/chejiangyi/p/5113358.html

更多相关:

  • 有时候我们项目,在执行某个操作后,会生成一些数据结果,如报表一类的东西,我们需要对结果进行保存,甚至是生成word文档。 那么首先获取到控件快照就最基本的条件。 生成快照的静态方法类 using System; using System.Collections.Generic; using System.Drawing; using...

  • 作用批量执行sql语句 表达式.RunSQL(SQLStatement,UseTransaction) 表达式.一个代表DoCmd对象的变量。 注释:sqlstatement参数的最大长度为 32,768 个字符(而"宏"窗口中的 SQL 语句操作参数的最大长度为 256 个字符)。      官方说仅能用于Microsoft Acc...

  • 前戏:针对上一篇列出来的功能点,今天和大家分享下这个自定义的公式是怎么设计的,由于我的第一篇博客在首页被管理员移走了,大家可以点击这里来跳转,看下第一篇的目录结构。本人作为老菜鸟,和大家分享的也是一些老菜鸟的想法,大神千万别喷我.   设计背景:当初为什么要设计这个自定义的计算公式呢,原因就是,这个价格是不确定的,计算方式也是不确定的...

  • using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml;using System.Web; namespace BLL{    public  class XmlDoc    {       ...

  • 引言 在这个-SLAM建图和导航仿真实例-项目中,主要分为三个部分,分别是 (一)模型构建(二)根据已知地图进行定位和导航(三)使用RTAB-MAP进行建图和导航 该项目的slam_bot已经上传我的Github。 这是第三部分,完成效果如下 图1 建图和导航 三、使用RTAB-Map进行建图和导航 1. rtab...

  • 引言 在这个-SLAM建图和导航仿真实例-项目中,主要分为三个部分,分别是 (一)模型构建(二)根据已知地图进行定位和导航(三)使用RTAB-MAP进行建图和导航 该项目的slam_bot已经上传我的Github。 由于之前的虚拟机性能限制,我在这个项目中使用了新的ubantu 16.04环境,虚拟机配置 内存 8GCPU...

  • [{name:1},{name:2}].forEach((v,i,ar) => {console.log(v,i,ar)});//基础遍历[{name:1},{name:2}].map((v) => v.name);//[1,2]返回对象数组中指定字段值的一位数组(不改变原始数组)[{name:1},{name:2},{name:3}...

  • 体验内容 使用gmapping方法利用turtlebot底盘移动信息和激光雷达数据进行建图。 1. 安装一些依赖包 sudo apt-get install ros-melodic-move-base* sudo apt-get install ros-melodic-map-server* sudo apt-get insta...

  • 前言 我们知道Java/Python这种语言能够很好得 支持反射。反射机制 就是一种用户输入的字符串到对应实现方法的映射,比如http接口中 用户传入了url,我们需要调用该url对应的方法/函数对象 从而做出对应的操作。 而C++ 并没有友好得支持这样的操作,而最近工作中需要通过C++实现http接口,这个过程想要代码实现得优雅...

  • 关于Graphics也有了基本了解下面想说的的是学这个东东干什么呢,到底如何应用目前常见应用1、验证码(参照网上的)2、打印排版(会提到关于条形码大小设置)3、自定义控件 一、验证码 1 class ValidateCode 2 { 3 #region 定义和初始化配置字段 4...

  •   最近公司在做一个医疗项目,使用WinForm界面作为客户端交互界面。在整个客户端解决方案中。使用了MVP模式实现。由于之前没有接触过该设计模式,所以在项目完成到某个阶段时,将使用MVP的体会写在博客里面。   所谓的MVP指的是Model,View,Presenter。对于一个UI模块来说,它的所有功能被分割为三个部分,分别通过M...

  • 关于具体需求,请看前面的博文:DDD领域驱动设计实践篇之如何提取模型,下面是具体的实体、聚合、值对象的代码,不想多说什么是实体、聚合等概念,相信理论的东西大家已经知晓了。本人对DDD表示好奇,没有在真正项目实践过,甚至也没有看过真正的DDD实践的项目源码,处于极度纠结状态,甚至无法自拔,所以告诫DDD爱好者们,如果要在项目里面实践DD...

  • TPL Dataflow是微软面向高并发应用而推出的新程序库。借助于异步消息传递与管道,它可以提供比线程池更好的控制。本身TPL库在DataflowBlock类中提供了不少扩展函数,用起来还是非常方便的,但感觉还是不够全(当然,MS没必要设计大而全的接口),前段时间写个小程序的时候用到了它,当时顺便写了几个扩展函数,这里记录一下,如果...

  • 前言       写系列文章的时候[前言]部分变得无言了,可能来得顺利了点吧: ) 本章中提供的封装均是我用笨办法从<>和<>中拷贝出来并参照VC++代码进行整理的,主要是针对HikServ...