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

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

时间:2022-11-11 14:05:08浏览次数:55  
标签:erp string int 流程 业务流程 oa 任务 UserInfo net

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

背景

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

架构概要图

 

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


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

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

  示例模型定义图形:

   

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

 

  示例模型定义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>

 

 

  常规界面如下:

 

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

 


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

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


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

/// <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等进行数据报表等分析。开发,维护复杂度等都会提升。
  结论:如果不是做大型产品或服务,不会进行分布式架构。

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

开源是一种态度,分享是一种精神,学习仍需坚持,进步仍需努力,.net生态圈因你我更加美好。



标签:erp,string,int,流程,业务流程,oa,任务,UserInfo,net
From: https://blog.51cto.com/chejiangyi/5844798

相关文章

  • .net 分布式架构之分布式缓存中间件
    便实现缓存的分布式,集群,负载均衡,故障自动转移,并兼容多种缓存存储的.net分布式缓存中间件。分布式缓存中间件 方便实现缓存的分布式,集群,负载均衡,故......
  • .net 分布式架构之配置中心
    .net统一配置中心,用于所有项目统一的配置集中管理,简化运维和项目部署,具备高灵活性,高性能,高稳定性,高及时性。同时具备配置项的负载均衡和故障转移,从......
  • .net 分布式架构之分布式锁实现
    .net分布式锁,包括redis分布式锁和zookeeper分布式锁的.net实现。分布式锁在解决分布式环境下的业务一致性是非常有用的。分布式锁经常用于在解决......
  • .net 分布式架构之任务调度平台
    .net简单任务调度平台,用于.netdll,exe的任务的挂载,任务的隔离,调度执行,访问权限控制,监控,管理,日志,错误预警,性能分析等。.net任务调度平台用于.net......
  • .net 分布式架构之业务消息队列
    .net业务消息队列是应用于业务的解耦和分离,应具备分布式,高可靠性,高性能,高实时性,高稳定性,高扩展性等特性。大量的业务消息堆积能力;无单点故障及故障监控......
  • .net 任务调度平台
    .net简单任务调度平台,用于.netdll,exe的任务的挂载,任务的隔离,调度执行,访问权限控制,监控,管理,日志,错误预警,性能分析等。.net任务调度平台用于.net......
  • 乘风破浪,遇见新一代工业互联网(Industrial Internet)之自主移动机器人(AMR)、自动导航
    什么是自主移动机器人(AMR)从工厂车间的重复性工作到农业、物流、酒店等领域的活动,自主移动机器人的使用正在改变业务的运营方式。自主移动机器人(AutonomousMobile......
  • asp.net中updatepanel控件向外传值
    .aspx代码如下:<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="UpdatePanel控件传值.aspx.cs"Inherits="UpdatePanel控件传值"%><!DOCTYPEhtmlPUBLIC"-//W3......
  • asp.net中FileUpload控件研究汇总
    .aspx代码如下:<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="文件上传.aspx.cs"Inherits="文件上传"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transi......
  • asp.net中MultiView和View
    小例子.aspx代码如下:<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="2_MultiView.aspx.cs"Inherits="_2_MultiView"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHT......