惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
AI
AI
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
Scott Helme
Scott Helme
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Engineering at Meta
Engineering at Meta
博客园 - 叶小钗
The GitHub Blog
The GitHub Blog
Microsoft Azure Blog
Microsoft Azure Blog
N
News and Events Feed by Topic
Cloudbric
Cloudbric
B
Blog
Cisco Talos Blog
Cisco Talos Blog
V
Vulnerabilities – Threatpost
N
News and Events Feed by Topic
V
Visual Studio Blog
A
Arctic Wolf
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
U
Unit 42
S
Security @ Cisco Blogs
博客园 - 聂微东
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
Y
Y Combinator Blog
G
GRAHAM CLULEY
L
LINUX DO - 热门话题
量子位
NISL@THU
NISL@THU
Webroot Blog
Webroot Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Troy Hunt's Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
T
Tenable Blog
月光博客
月光博客
S
Security Affairs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Hacker News
The Hacker News
Spread Privacy
Spread Privacy
D
Docker
www.infosecurity-magazine.com
www.infosecurity-magazine.com
雷峰网
雷峰网
博客园 - 司徒正美
T
The Exploit Database - CXSecurity.com
Hugging Face - Blog
Hugging Face - Blog
Help Net Security
Help Net Security
D
DataBreaches.Net

博客园 - 信息化建设

SAP 开发环境搭建入门 老程序员转测试 配置测试环境设置共享文件 提高团队效率 Visual Studio 2017十五项新功能体验 管理软件公司与互联网公司的区别 ERP程序开发中遇到的六种错误 ERP软件的价格设计 设计C/S架构应用程序的并发功能 C/S架构应用程序开发培训笔记 Enterprise Solution 进销存管理软件 C/S架构,支持64位系统 物流,资金流,信息流全面集成 Enterprise Solution 企业资源计划管理软件 C/S架构,支持64位系统,企业全面应用集成,制造业信息化 Enterprise Solution 3.1 企业应用开发框架 .NET ERP/CRM/MIS 开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms .NET 程序集单元测试工具 SmokeTest 应用指南 LLBL Gen Pro 5.0 企业应用开发入门 CRM/ERP 企业管理软件中常见的七种程序设计模式 解析大型.NET ERP系统 电子邮件系统帐户集成 财务模块功能中的凭证预览功能 通用附件管理功能改善 规范数据库表字段大小写 小写字段名全部更改为大写 Enterprise Solution 虚拟测试环境
工作流系统中的语法标记系统
信息化建设 · 2016-05-09 · via 博客园 - 信息化建设

以微软的WF为基础,为达到ERP中的批核与通知目的,参考现有系统中的技术,在此分享其中的技巧。

先来看最终的结果,也就是下图中的工作流宿主。

image

在上面的工作流定义中,除工作流宿主(rehost)技术外,还需要解决规则表达式的解析难题。

.NET WF提供的规则编辑器是基于代码的,但对于一个无代码的开发环境,需要找到一种表达式的设计,解析规范。

比如,在运行时,我们需要根据当前的运行参数解析出以上表达式的分支,最终流向哪个批核结点。

经过摸索,我提供现有系统中已经应用的三种方案,供读者参考。

1 查询表达式

比如一个费用报销流程,当报销金额小于1000元时,可由部门主管直接批核。用SQL语句表达如下:

SELECT AMOUNT  FROM dbo.ICMOVH WHERE AMOUNT <1000  
AND REF_NO='<%InventoryMovementEntity.RefNo%>‘
 
<% 标记表示当前正在运行的业务对象,<%InventoryMovementEntity.RefNo%> 这一句可取到当前业务对象的标识值。再与金额条件Amount(小于等于1000)组合,当存在这样的单据时,即为满足分支条件,由部门主管批核。
 

2 查询语句

查询语句的作用是为了发送消息通知,将SQL命令通过参数化的方式封装,达到运行时获取数据的目的。
比如一个安全库存报警,当物料安全库存变动时,物料的库存余额小于当前物料设定的安全库存。
image 
为了查询数据,设计出一种新语法标记,例子如下:
<%RepeatEachRecord_Begin.SqlQuery1%> 
Job No: <%SqlQuery1.job_no%>
<%RepeatEachRecord_End.SqlQuery1%>

通过上图的界面设计中可看出,一个消息通知可包含很多个SQL命名查询,每个SQL命名查询可返回一个或多个数据行,我们在消息文本中用特定的语法,解析出命名查询中字段,即可达到获取数据的目的。

3 常量

工作流中的活动可理解为一个封装的独立的代码片段,为了与外界通信,必须向活动传递参数。有时候参数是固定的值,比如当前的报销单据,在前面我们用到过<%InventoryMovementEntity.RefNo%>表示报销单据编号。

若是要取到当前登录系统的用户,可用<%SessionEntity.UserId%>来获取。

比如给仓库单据增加一个验证,取出当前用户创建的引用(Reference)为空的参考编号。可通过下面的SQL语句实现:

SELECT RefNo  FROM dbo.ICMOVH WHERE REFERENCE IS NULL 
AND CREATED_BY='<%SessionEntity.UserId%>‘
 

4 调用程序代码

在一套业务工作流系统中调用代码实在是无奈之举。如果发生的业务很有规律,可考虑封装为活动以方便重用。

代码活动的表达方式如下:

image

我用了三行标记为的是表示一个.NET方法:
assembly=Microsoft.Workflow
class=Microsoft.Workflow.Extension
method=Microsoft.Workflow.Extension.VoucherPost
如果你熟悉.NET反射,很快能写出调用这个方法的代码。
Assembly assembly = null;
Type type = null;
string method = string.Empty;
List<string> format = new List<string>() { "assembly", "class", "method" };
string[] codes = Regex.Split(this.Code, ";");
foreach (string code in codes)
{
   if (string.IsNullOrWhiteSpace(code))
                    continue;
   string[] segments = Regex.Split(code, "=");
   if (Microsoft.Common.Shared.StringCompare(segments[0].ToUpper(), "assembly".ToUpper()) == 0)
         assembly = Assembly.Load(segments[1]);
   if (Microsoft.Common.Shared.StringCompare(segments[0].ToUpper(), "class".ToUpper()) == 0)
         type = assembly.GetType(segments[1]);
   if (Microsoft.Common.Shared.StringCompare(segments[0].ToUpper(), "method".ToUpper()) == 0)
        method = segments[1];
}
type.GetMethod(method, BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
从最后一段代码中可以看出,上面标记的方法必须是静态(static,非实例)方法。
 
最后,我将前三种情况附加到程序中,以帮助对话框的形式提供给工作流开发人员。
image 
 
我这里所提到的工作流是以微软的WF为基础开发的一套工作流系统,如果你需要自定义一套工作流设计,业务开发,表达式解析等功能,文中的标记技术可供您参考。