1、发起流程

发起流程时主要做了两件事:一是写入业务数据表,二是新建一条审批流程记录。

发起流程的方法

        public static Int64 Node_CreateStartNodeWork(string flowNo, Hashtable htWork = null, DataSet workDtls = null,
string flowStarter = null, string title = null, Int64 parentWorkID = 0, string parentFlowNo = null, int parentNDFrom = 0)

系统中一般这样调用

Hashtable ht = new Hashtable();
long startFlowId = Dev2Interface.Node_CreateStartNodeWork(fk_Flow, ht, null, currentUserName, title);

传入的主要参数有

流程的编号fk_Flow,编号是从001开始的,工作流系统中有一个默认的流程,编号是001,你可以在上面修改,也可以新建,新建后的流程编号是002.

键值对,ht主要是用于修改业务表。

currentUserName 用户名,主要用于初始化发起人信息,如果传NULL,则会默认用当前登录用户。

titile 流程名,如果传Null,则会默认生成一条流程。

进入方法,会看到初始化了几个实例 :

一是流程对象 Flow  记录了流程的编号、创建时间、名称,

 Flow fl = new Flow(flowNo);
/// <summary>
/// 流程
/// </summary>
/// <param name="_No">编号</param>
public Flow(string _No)
{
this.No = _No;
if (SystemConfig.IsDebug)
{
int i = this.RetrieveFromDBSources();
if (i == 0)
throw new Exception("流程编号不存在");
}
else
{
this.Retrieve();
}
}

二是 节点对象 Node 存放每个节点的信息,通过流程的开始节点ID初始化节点类

Node nd = new Node(fl.StartNodeID);

让我们看看流程开始节点是如何找到的,如下,开始节点等于流程号+01 再转成Int  也就是说流程编号为002的开始节点为201

public int StartNodeID
{
get
{
return int.Parse(this.No + "01"); }
}

三是操作员 Emp

Emp emp = new Emp(flowStarter);
 /// <summary>
/// 操作员
/// </summary>
/// <param name="no">编号</param>
public Emp(string no)
{
if (no == null || no.Length == 0)
throw new Exception("@要查询的操作员编号为空。"); this.No = no.Trim(); this.Retrieve(); }

三是工作对象 work  随着该对象被创建,对象GenerWorkFlow也被创建出来,对应的表wf_generworkflow 中增加了一条记录

Work wk = fl.NewWork(flowStarter);
public Work NewWork(string empNo)
{
Emp emp = new Emp(empNo);
return NewWork(emp, null);
}
/// <summary>
/// 产生一个开始节点的新工作
/// </summary>
/// <param name="emp">发起人</param>
/// <param name="paras">参数集合,如果是CS调用,要发起子流程,要从其他table里copy数据,就不能从request里面取,可以传递为null.</param>
/// <returns>返回的Work.</returns>
public Work NewWork(Emp emp, Hashtable paras)
{
// 检查是否可以发起该流程?
if (Glo.CheckIsCanStartFlow_InitStartFlow(this) == false)
throw new Exception("err@您违反了该流程的【" + this.StartLimitRole + "】限制规则。" + this.StartLimitAlert); GenerWorkFlow gwf = new GenerWorkFlow(); ........................

wf_generworkflow表中修改的字段如下,WorkID是启动流程的唯一标识,也是最终要返回的ID,可以绑定在业务表上的。设置了当前流程的状态:WFState.Blank

     #region 给 generworkflow 初始化数据. add 2015-08-06

            gwf.FK_Flow = this.No;
gwf.FK_FlowSort = this.FK_FlowSort;
gwf.SysType = this.SysType;
gwf.FK_Node = nd.NodeID;
gwf.WorkID = wk.OID;
gwf.WFState = WFState.Blank;
gwf.FlowName = this.Name; gwf.FK_Node = nd.NodeID;
gwf.NodeName = nd.Name;
gwf.Starter = WebUser.No;
gwf.StarterName = WebUser.Name;
gwf.FK_Dept = BP.Web.WebUser.FK_Dept;
gwf.DeptName = BP.Web.WebUser.FK_DeptName;

接下来又对 GenerWorkerList对象进行了修正,

 #region 为开始工作创建待办
GenerWorkFlow gwf = new GenerWorkFlow();
gwf.WorkID = wk.OID;
int i = gwf.RetrieveFromDBSources(); gwf.FlowName = fl.Name;
gwf.FK_Flow = flowNo;
gwf.FK_FlowSort = fl.FK_FlowSort;
gwf.SysType = fl.SysType; gwf.FK_Dept = emp.FK_Dept;
gwf.DeptName = emp.FK_DeptText;
gwf.FK_Node = fl.StartNodeID; gwf.NodeName = nd.Name; //默认是空白流程
//gwf.WFSta = WFSta.Etc;
gwf.WFState = WFState.Blank;
//保存到草稿
if (fl.DraftRole == DraftRole.SaveToDraftList)
{
gwf.WFState = WFState.Draft;
}
else if (fl.DraftRole == DraftRole.SaveToTodolist)
{
//保存到待办
// gwf.WFSta = WFSta.Runing;
gwf.WFState = WFState.Runing;
} if (DataType.IsNullOrEmpty(title))
{
gwf.Title = BP.WF.WorkFlowBuessRole.GenerTitle(fl, wk);
}
else
{
gwf.Title = title;
} gwf.Starter = emp.No;
gwf.StarterName = emp.Name;
gwf.RDT = DataType.CurrentDataTime; if (htWork != null && htWork.ContainsKey("PRI") == true)
{
gwf.PRI = int.Parse(htWork["PRI"].ToString());
} if (htWork != null && htWork.ContainsKey("SDTOfNode") == true)
{
/*节点应完成时间*/
gwf.SDTOfNode = htWork["SDTOfNode"].ToString();
} if (htWork != null && htWork.ContainsKey("SDTOfFlow") == true)
{
/*流程应完成时间*/
gwf.SDTOfNode = htWork["SDTOfFlow"].ToString();
} gwf.PWorkID = parentWorkID;
gwf.PFlowNo = parentFlowNo;
gwf.PNodeID = parentNDFrom;
if (i == 0)
{
gwf.Insert();
}
else
{
gwf.Update();
}

四是创建了工作者列表GenerWorkerList,写入的表是wf_generworkerlist

// 产生工作列表.
GenerWorkerList gwl = new GenerWorkerList();
gwl.WorkID = wk.OID;
if (gwl.RetrieveFromDBSources() == 0)
{
gwl.FK_Emp = emp.No;
gwl.FK_EmpText = emp.Name; gwl.FK_Node = nd.NodeID;
gwl.FK_NodeText = nd.Name;
gwl.FID = 0; gwl.FK_Flow = fl.No;
gwl.FK_Dept = emp.FK_Dept;
gwl.FK_DeptT = emp.FK_DeptText; gwl.SDT = "无";
gwl.DTOfWarning = DataType.CurrentDataTime;
gwl.IsEnable = true; gwl.IsPass = false;
// gwl.Sender = WebUser.No;
gwl.PRI = gwf.PRI;
gwl.Insert();
}

最后,整个启动流程的方法会将OID返回

return wk.OID;

可以返回的ID绑定在自定义的业务表中。

CCFLOW源码解读系列01-----发起流程的更多相关文章

  1. Alamofire源码解读系列(十)之序列化(ResponseSerialization)

    本篇主要讲解Alamofire中如何把服务器返回的数据序列化 前言 和前边的文章不同, 在这一篇中,我想从程序的设计层次上解读ResponseSerialization这个文件.更直观的去探讨该功能是 ...

  2. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  3. Laravel 源码解读系列第四篇-Auth 机制

    前言 Laravel有一个神器: php artisan make:auth 能够快速的帮我们完成一套注册和登录的认证机制,但是这套机制具体的是怎么跑起来的呢?我们不妨来一起看看他的源码.不过在这篇文 ...

  4. swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?

    date: 2018-8-01 14:22:17title: swoft| 源码解读系列二: 启动阶段, swoft 都干了些啥?description: 阅读 sowft 框架源码, 了解 sowf ...

  5. Hadoop源码解读系列目录

    Hadoop源码解读系列 1.hadoop源码|common模块-configuration详解2.hadoop源码|core模块-序列化与压缩详解3.hadoop源码|core模块-远程调用与NIO ...

  6. Alamofire源码解读系列(二)之错误处理(AFError)

    本篇主要讲解Alamofire中错误的处理机制 前言 在开发中,往往最容易被忽略的内容就是对错误的处理.有经验的开发者,能够对自己写的每行代码负责,而且非常清楚自己写的代码在什么时候会出现异常,这样就 ...

  7. Alamofire源码解读系列(四)之参数编码(ParameterEncoding)

    本篇讲解参数编码的内容 前言 我们在开发中发的每一个请求都是通过URLRequest来进行封装的,可以通过一个URL生成URLRequest.那么如果我有一个参数字典,这个参数字典又是如何从客户端传递 ...

  8. Alamofire源码解读系列(三)之通知处理(Notification)

    本篇讲解swift中通知的用法 前言 通知作为传递事件和数据的载体,在使用中是不受限制的.由于忘记移除某个通知的监听,会造成很多潜在的问题,这些问题在测试中是很难被发现的.但这不是我们这篇文章探讨的主 ...

  9. Alamofire源码解读系列(五)之结果封装(Result)

    本篇讲解Result的封装 前言 有时候,我们会根据现实中的事物来对程序中的某个业务关系进行抽象,这句话很难理解.在Alamofire中,使用Response来描述请求后的结果.我们都知道Alamof ...

  10. Alamofire源码解读系列(六)之Task代理(TaskDelegate)

    本篇介绍Task代理(TaskDelegate.swift) 前言 我相信可能有80%的同学使用AFNetworking或者Alamofire处理网络事件,并且这两个框架都提供了丰富的功能,我也相信很 ...

随机推荐

  1. 十问ByteHouse:如何基于ClickHouse玩转向量检索?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 向量检索被广泛使用于以图搜图.内容推荐以及大模型推理等场景.随着业务升级与 AI 技术的广泛使用,用户期望处理的向 ...

  2. 字节跳动基于 ClickHouse 优化实践之“查询优化器”

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 相信大家都对大名鼎鼎的 ClickHouse 有一定的了解了,它强大的数据分析性能让人印象深刻.但在字节大量生产使 ...

  3. 火山引擎 DataLeap 构建Data Catalog系统的实践(一):背景与调研思路

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 摘要 Data Catalog 产品,通过汇总技术和业务元数据,解决大数据生产者组织梳理数据.数据消费者找数和理解 ...

  4. Apache Pulsar 在火山引擎 EMR 的集成与场景

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近年来,基于云原生架构的新一代消息队列和流处理引擎 Apache Pulsar 在大数据领域发挥着愈发重要的作用, ...

  5. Nginx log 日志文件较大,按日期生成 实现日志的切割

    Nginx日志不处理的话,会一直追加,文件会变得很大,所以理想做法是按天对 Nginx日志进行分割 方法1:给日志文件名加上日期 推荐 log_format access-upstream '$tim ...

  6. Spring Boot Admin 授权配置

    Admin 服务端配置 添加 POM 引用 <dependency> <groupId>org.springframework.boot</groupId> < ...

  7. explain分析

    explain分析字段:id.select_type.type.partitions.type.possible_keys.key.key_len.ref.rows.rows.filtered.ext ...

  8. GitLab--简单使用

    1 创建项目组 项目组说明 Private 私有 只有所有者 组内成员或已分配的用户有查看权限(同GitHub收费版的私有仓库) Internal 内部 拥有GitLab账号的成员可以查看 无账号用户 ...

  9. Educational Codeforces Round 110 (Rated for Div. 2) (AB签到,C题双指针,D题DP好题)

    补题链接:Here 1535A. Fair Playoff 四名选手参加了季后赛.比赛按以下方案进行:第一名选手与第二名选手比赛,第三名选手与第四名选手比赛,然后两人中的获胜者进入决赛. 众所周知,在 ...

  10. L2-014 列车调度 (25 分)(set容器应用)

    L2-014 列车调度 (25 分) 火车站的列车调度铁轨的结构如下图所示. 两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道.每趟列车从入口可以选择任意 ...