当前位置: 首页 > 编程日记 > 正文

.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>ddd</Key><Title>新建模型</Title><Description>发起人</Description><CreateTime>0001-01-01T00:00:00</CreateTime><Author><StaffNo>34</StaffNo><UserName>车江毅1</UserName></Author><Type>Common</Type><Compilation>Debug</Compilation></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><![CDATA[myValue4=='true']]></Code><RouteScripts /></Route><Route To="人工2" Text="线" Location="0 0"><Code><![CDATA[myValue4=='false']]></Code><RouteScripts /></Route></Routes><BeginScripts /><EndScripts /><Scripts><Script><Code><![CDATA[api.Forword('http://webservice.webxml.com.cn/webservices/ChinaTVprogramWebService.asmx','getTVstationDataSet','theAreaID:2')]]></Code></Script><Script><Code><![CDATA[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><![CDATA[]]></Code><RouteScripts /></Route></Routes><BeginScripts /><EndScripts /><Participants><Participant Mode="Code"><Code><![CDATA[api.Split('034','#')]]></Code></Participant><Participant Mode="Variable"><Code><![CDATA[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><![CDATA[]]></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><![CDATA[]]></Code><RouteScripts /></Route><Route To="人工4" Text="线" Location="0 0"><Code><![CDATA[]]></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><![CDATA[]]></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><![CDATA[]]></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><![CDATA[]]></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><![CDATA[]]></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><![CDATA[]]></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><![CDATA[]]></Code><RouteScripts /></Route></Routes><BeginScripts /><EndScripts /><Participants /><MessageVariables /><TemplateKey>0</TemplateKey><TemplateName /></BaseNode></Nodes>
</ProcessModel>


  常规界面如下:
  
 

流程管理平台
  包含:流程模型管理,流程管理,流程任务管理,流程操作记录,流程服务接口日志查询,流程异常查询,流程流转调试日志查询,开发者用户管理等。
  可以管理流程模型历史版本及版本切换,流程异常时候的流程节点切换,流程任务的转交等。
 界面如下:

 

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

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

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

分布式架构概想
  分布式拆库方案:流程维度和用户维度,流程维度数据库按照流程定义模型的唯一标识hash,来拆分到不同的数据库。所有流程创建和流程任务的创建都在不同的数据库中。用户维度数据库按照用户标识hash,来拆分到不同的数据库。
  拆库优点:数据被拆分,不影响同一个业务流程流转,性能会得到提升。
  拆库缺点:采用异步消息通知,做用户代办任务和完成任务冗余及同步。采用BI工具或者hadoop等进行数据报表等分析。开发,维护复杂度等都会提升。
  结论:如果不是做大型产品或服务,不会进行分布式架构。

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

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

相关文章:

数据分析-pca协方差

协方差是反映的变量之间的二阶统计特性&#xff0c;如果随机向量的不同分量之间的相关性很小&#xff0c;则所得的协方差矩阵几乎是一个对角矩阵。转载于:https://www.cnblogs.com/erweiyang/archive/2012/09/08/2676997.html

在javascript中判断类型

String 一个字符串始终是一个字符串&#xff0c;所以这一块是很容易。除非使用new&#xff08;new String&#xff09;调用&#xff0c;否则typeof将返回“object”。所以也要包含那些可以使用的字符串instanceof。 // Returns if a value is a string function isString (valu…

mysql中日期判断的函数_MySql判断汉字、日期、数字的函数

几个平常用的mysql函数 /***************************************************** 1.判断字符串是否为汉字 返回值&#xff1a;1-汉字 0-非汉字 *****************************************************/ DROP FUNCTION IF EXISTS fc_is_hanzi; CREATE FUNCTION fc_is_h几个平常…

c#.net调用pdf2swf.exe将pdf文件转换为swf,vs中运行正常,布署IIS服务器部署转换后文字部分为空白...

这个是权限问题&#xff0c; 需要在应用程序池中高级设置&#xff0c;将标识改为LocalSystem 转载于:https://www.cnblogs.com/shy1766IT/p/5114971.html

云计算开发要学习哪些东西?云计算开发的内容

云计算是一种基于互联网的计算方式&#xff0c;要实现云计算则需要一整套的技术架构去实施&#xff0c;包括网络、服务器、存储、虚拟化等等。 云计算目前分为公有云和私有云。两者的区别只是提供的服务的对象不同&#xff0c;一个是企业内部使用&#xff0c;一个则是面向公众。…

XHTML+CSS3(Chapter 1)

HTML5 Reference document: http://www.w3school.com.cn/html5/html_5_intro.asp 1. Use <video> to display some video in html (mp4. ogg.) <video src"movie.ogg" controls"controls"> </video> 2. Use <audio> to play …

oracle重建实例_记一次误删Oracle控制文件并恢复过程

概述当你在数据库运行时误删除了控制文件怎么办&#xff1f;很不幸有一次我就有这个情况,虽然是测试环境&#xff0c;这里因为我有事先把控制文件分别备份&#xff0c;所以恢复还是比较简单的。下面简单记录下怎么恢复。问题控制文件版本不一致一般是因为在实例运行时删除了控制…

成都Uber优步司机奖励政策(1月9日)

1月9日 奖励政策滴快车单单2.5倍&#xff0c;注册地址&#xff1a;http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单&#xff1a;http://www.cnblogs.com/mfryf/p/4612609.html 优步奖励低/不挣钱/怎么办?看这里&#xff1a;http://www.c…

vim-map

vim-map 软件版本&#xff1a;  ubuntu10.04  Linux version 2.6.32-42-generic  VIM - Vi IMproved 7.2目录&#xff1a; 1. 简介  2. 映射与运行模式的关系  3. 例子  4. 其他 1. 简介 如果想让 vim 成为你手中的利器&#xff0c;vim 的 map 功能就不得不学&…

Java并发面试,幸亏有点道行,不然又被忽悠了

2019独角兽企业重金招聘Python工程师标准>>> 前言 面试Java&#xff0c;必然要被问Java内存模型和Java并发开发。我被问到的时候&#xff0c;心里慌得一批&#xff0c;“额&#xff0c;是在《Thinking in Java》里面写的吗&#xff1f;果然每天增删改太low了” 要了…

mysql减少锁等待_降低锁竞争 减少MySQL用户等待时间

【IT168 技术】通过锁机制&#xff0c;可以实现多线程同时对某个表进行操作。如下图所示&#xff0c;在某个时刻&#xff0c;用户甲、用户乙、用户丙可能会同时或者先后(前面一个作业还没有完成)对数据表A进行查询或者更新的操作。当某个线程涉及到更新操作时&#xff0c;就需要…

UML中的六种关系的比较与学习

通过不断的学习并绘制UML图&#xff0c;整个画图的过程中深刻体会到其核心部分还是理解事物之间的关系&#xff0c;总结六大关系来深入学习&#xff0c;主要关系有六种&#xff1a;继承、实现、依赖、关联、聚合、组合。 区别于联系&#xff1a; 1.继承&#xff08;泛华&#x…

spark—3(Spark Scheduler)

2019独角兽企业重金招聘Python工程师标准>>> Spark的核心是根据RDD来实现的&#xff0c;Spark Scheduler则为Spark核心实现的重要一环&#xff0c;其作用就是任务调度。Spark的任务调度就是如何组织任务去处理RDD中每个分区的数据&#xff0c;根据RDD的依赖关系构建…

Tomcat手动配置简述【查询留存】

一、设置JAVA的环境变量JAVA_HOME 略 二、设置Tomcat的环境变量 一次性全配置了 Tomcat的根目录&#xff0c;例如【E:\tomcat-6.0.35】 创建下列环境变量&#xff1a; CATALINA_HOME: E:\tomcat-6.0.35 CATALINA_BASE: E:\tomcat-6.0.35 TOMCAT_HOME: E:\tomcat-6.0.35 然后修改…

linux mysql 不稳定_linux,mysql:今天写出一个十分弱智的bug!

今天写出一个十分弱智的bug&#xff0c;记录一下&#xff0c;提醒自己以后别这种犯错&#xff0c;不怕丢人哈~在写一个分页查询记录的sql时&#xff0c;要根据添加的时间逆序分页输出&#xff0c;之前的写法是酱紫&#xff1a;selectrecord.a, y.c from ( selecta,b from xorde…

IOS XML解析

<?xml version "1.0" encoding "utf-8"?> <video>小黄人</video> <video></video> <video/> <videos> <video> </video> </videos> 不能相互嵌套。 xml中的所有空格和空行都会当成字符来…

BAT架构师分享之:大型网站技术架构

早期的网站为了节省成本一般会设计成集中式系统&#xff0c;应用程序、数据库等都部署在一台服务器上。 但随着业务的快速度发展&#xff0c;逐渐出现瓶颈&#xff0c;按一定原则**&#xff08;应用拆分、服务拆分、数据拆分、应用解耦&#xff09;**&#xff0c;向分布式系统转…

mysql isreg_`Innodb` MySQL中如何优雅的删除大表跑路

最近很想写写MySQL相关的内容&#xff0c;就从这个话题出发吧有人说删MySQL表谁不会不就是drop table TABLENAME如果在生产环境中&#xff0c;你对一张TB级别的大表&#xff0c;敲下这行命令那么你的主管&#xff0c;大主管&#xff0c;隔壁的大主管 就会气势汹汹的冲向你其原因…

常用正则表达式集锦

链接地址&#xff1a;http://blog.csdn.net/tjcyjd/article/details/48416405 验证数字&#xff1a;^[0-9]*$验证n位的数字&#xff1a;^\d{n}$验证至少n位数字&#xff1a;^\d{n,}$验证m-n位的数字&#xff1a;^\d{m,n}$验证零和非零开头的数字&#xff1a;^(0|[1-9][0-9]*)$验…

C(第一个C程序) 和 C++ (第一个C++程序)对比碰撞

个人博客首页&#xff08;点击查看详情&#xff09; -- https://blog.51cto.com/11495268 1、简介 C 是对 C 的继承、扩展&#xff0c;但从语言角度来说&#xff0c;这是 两种变成语言&#xff0c;就一定存在不同&#xff0c;本文 就借助于 C、C 的 最精简标准程序 进行对比…

java的byte与C#的异同引起的字符处理问题。

java的byte是有符号类型(java就没有无符号类型的数据)&#xff0c;值域&#xff1a;-0128~127 c#的byte是无符号类型数值&#xff0c;值域&#xff1a;0~255 这在依赖字符编码处理程序中&#xff0c;两者源代码就不能通用了。 知道原因结局办法就容易多了。 1.使用&与运算 …

exec不同文件l怎么汇总_ABAQUS常见问题汇总 - 2.0版.doc

您所在位置&#xff1a;网站首页 > 海量文档&nbsp>&nbsp计算机&nbsp>&nbspC/C资料ABAQUS常见问题汇总 - 2.0版.doc154页本文档一共被下载&#xff1a;次,您可全文免费在线阅读后下载本文档。下载提示1.本站不保证该用户上传的文档完整性&#xff0c…

1月12号 UIView

UIView 1.为什么要UIView .可以用UIView作为容器&#xff0c;存放子视图 .管理事件UIEvent 2.ios坐标系 以左上角为坐标原点&#xff0c;向右边是x的正方向&#xff0c;向下是y的正向方 bounds: 相对于视图本身而言&#xff08;0&#xff0c;0&#xff0c;w, h&#xff09; fra…

小虎计算器-技术支持

2019独角兽企业重金招聘Python工程师标准>>> 最简单的计算器&#xff0c;包含历史记录 转载于:https://my.oschina.net/u/1405818/blog/3050764

jquery即时搜索查询插件jquery.search.js

jquery.search.js搜索插件是一款基于jquery的插件,任何一个input输入款均可即时转为查询框,可分为前台数据直接显示和后台传输数据显示两种方案! 文档说明:http://www.sameus.com 代码下载地址: http://code.google.com/p/17sameus/downloads/list 使用方式 jquery.search.js插…

node mysql 批量写入_请问如何使用node.js在MySQL中进行批量插入

catspeake我四处寻找关于批量插入对象的答案。Ragnar123的回答使我得出了这样的结论&#xff1a;function bulkInsert(connection, table, objectArray, callback) {let keys Object.keys(objectArray[0]);let values objectArray.map( obj > keys.map( key > obj[key]…

win10 UWP 应用设置

win10 UWP 应用设置 简单的把设置需要的&#xff0c;放到微软自带的LocalSettings LocalSettings.Values可以存放几乎所有数据 如果需要存放复合数据&#xff0c;一个设置项是由多个值组成&#xff0c;可以使用ApplicationDataCompositeValue将多个合并。 存放一个string strin…

通过loganalyzer展示数据库中的日志

目的&#xff1a;通过loganalyzer展示数据库中的日志 准备环境&#xff1a; CentOS7_1&#xff1a;用来生成日志 CentOS7_2&#xff1a;用来存放日志的数据库 CentOS7_3&#xff1a;LAP服务器 第一步&#xff1a;在CentOS7_2安装mysql数据库 此处使用二进制安装mariadb…

libmemcached 1.0.11 发布

libmemcached 1.0.11 删除了 memcached 的定制版本&#xff0c;更新了硬化(hardening)规则&#xff0c;修复了 socket 连接返回错误的问题。 libmemcached是C客户端到memcached服 务器的接口库。具有低内存占用率、线程安全、并提供对memcached功能的全面支持。它还采用多种命令…

python描述器做权限控制_Python装饰器14-描述器

描述器这是Python一个重要的概念,英文名&#xff1a;Descriptordescriptor是对象的一个属性&#xff0c;只不过它存在于类的dict中并且有特殊方法get(可能还有set和__delete)而具有一点特别的功能&#xff0c;为了方便指代这样的属性&#xff0c;我们给它起了个名字叫descripto…