Camunda只是工作流引擎,并不是一套完整的工作流产品。尽管自带了一套管理界面,可以从web登录后进行流程建模和流程管理,但界面太粗糙,不可能用于生产环境的。
因此需要基于Camunda的API,通过集成和定制的方式,来实现工作流辅助功能。
这里的辅助功能,主要是指以下几项:
下面来具体展开说说。
我的待办是用户待他处理的任务列表,可进行任务查看与办理。
常用的技术实现方式有两种,一是直接使用官方API中的方法,适合比较简单的场景;二是使用官方API中提供的native查询,通过sql语句来处理多表关联问题。
native查询方式虽然可以通过编写sql语句来处理多表关联问题,但是……查询结果仍然要映射到预设的对象中,以待办任务查询为例,查询结果对应Task接口,可以获取到任务名称(环节名称)、处理人账号、任务归属人,这些是可以用的,但是需要给用户显示流程类型名称、业务单据号,只能通过Task接口对应的标识、流程定义标识、流程实例标识来再进行一次甚至多次查询。这就尴尬了……这种native查询方式,适合过滤数据,即关联多表,把过滤条件传进去,但无法解决查询结果来源于多表的问题。
这时候就需要使用基于Mybatis的CustomSql方式来查询了,自定义mapper来实现。
实际执行过程中,发现Camunda根本就没有activiti中ManagementService下的executeCustomSQL方法,囧……
最后完全基于Mybatis了,自己写mapper.xml、mapper接口、service层,即读取activiti工作流引擎的库表,关联查询,返回数据,映射到自定义的对象上,实际开发通过,开发工作量比直接使用官方API要大一点,但想取数据可以直接通过关联表的方式直接取到,不用受官方api的条条框框约束,先把主表对象取回来,再去其他表里取数据,多次查询。这样要方便很多,性能上也大大提升。
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.abc.platform.workflow.mapper.ProcessTaskMapper">
<sql id="query">select * from (
select t1.ID_ AS id, #任务标识
t1.NAME_ as node_name, #环节名称
t1.CREATE_TIME_ as create_time, #任务创建时间
t1.ASSIGNEE_ as assignee, #处理人
t5.name as assignee_name, #处理人姓名
t1.TASK_DEF_KEY_ as task_definition_key, #任务定义标识
t1.OWNER_ as owner, #任务拥有者
t1.PROC_INST_ID_ AS process_instance_id, #流程实例标识
t3.PROC_DEF_ID_ as process_definition_id, #流程定义标识
t2.NAME_ as process_definition_name, #流程名称
t3.PROC_DEF_KEY_ as process_definition_key, #流程编码
t3.START_USER_ID_ as process_apply_id, #申请人id
t4.name as process_apply_name, #申请人姓名
t3.BUSINESS_KEY_ as business_no, #单号
t1.DELEGATION_ as delegation, #委派状态
t1.EXECUTION_ID_ as execution_id #执行流标识
from act_ru_task t1
LEFT JOIN act_re_procdef t2
on t1.PROC_DEF_ID_=t2.id_
LEFT JOIN act_hi_procinst t3
on t1.PROC_INST_ID_=t3.PROC_INST_ID_
LEFT JOIN sys_user t4
on t3.START_USER_ID_=t4.id
LEFT JOIN sys_user t5
on t1.ASSIGNEE_=t5.id
) t
${ew.customSqlSegment}
sql>
<resultMap id="resultMap" type="tech.abc.platform.workflow.entity.ProcessTask">
<id property="id" column="id"/>
<result property="nodeName" column="node_name"/>
<result property="createTime" column="create_time"/>
<result property="assignee" column="assignee"/>
<result property="assigneeName" column="assignee_name"/>
<result property="taskDefinitionKey" column="task_definition_key"/>
<result property="owner" column="owner"/>
<result property="processInstanceId" column="process_instance_id"/>
<result property="processDefinitionId" column="process_definition_id"/>
<result property="processDefinitionName" column="process_definition_name"/>
<result property="processDefinitionKey" column="process_definition_key"/>
<result property="processApplyId" column="process_apply_id"/>
<result property="processApplyName" column="process_apply_name"/>
<result property="businessNo" column="business_no"/>
<result property="delegation" column="delegation"/>
<result property="executionId" column="execution_id"/>
resultMap>
<sql id="toTodoTaskQuery">select * from (
select t1.ID_ AS id, #任务标识
t1.NAME_ as node_name, #环节名称
t1.CREATE_TIME_ as create_time, #任务创建时间
t1.ASSIGNEE_ as assignee, #处理人
t5.name as assignee_name, #处理人姓名
t1.TASK_DEF_KEY_ as task_definition_key, #任务定义标识
t1.OWNER_ as owner, #任务拥有者
t1.PROC_INST_ID_ AS process_instance_id, #流程实例标识
t3.PROC_DEF_ID_ as process_definition_id, #流程定义标识
t2.NAME_ as process_definition_name, #流程名称
t3.PROC_DEF_KEY_ as process_definition_key, #流程编码
t3.START_USER_ID_ as process_apply_id, #申请人id
t4.name as process_apply_name, #申请人姓名
t3.BUSINESS_KEY_ as business_no, #单号
t1.DELEGATION_ as delegation, #委派状态
t8.user_id as candidate_user, # 候选人
t1.EXECUTION_ID_ as execution_id #执行流标识
from act_ru_task t1
LEFT JOIN act_re_procdef t2
on t1.PROC_DEF_ID_=t2.id_
LEFT JOIN act_hi_procinst t3
on t1.PROC_INST_ID_=t3.PROC_INST_ID_
LEFT JOIN sys_user t4
on t3.START_USER_ID_=t4.id
LEFT JOIN sys_user t5
on t1.ASSIGNEE_=t5.id
LEFT JOIN act_ru_identitylink t6
on t1.ID_=t6.TASK_ID_
LEFT JOIN sys_user_group t7
on t7.ID=t6.GROUP_ID_
LEFT JOIN sys_group_user t8
on t8.group_id=t7.id
) t
${ew.customSqlSegment}
sql>
<resultMap id="toTodoTaskResultMap" type="tech.abc.platform.workflow.entity.ProcessTask">
<id property="id" column="id"/>
<result property="nodeName" column="node_name"/>
<result property="createTime" column="create_time"/>
<result property="assignee" column="assignee"/>
<result property="assigneeName" column="assignee_name"/>
<result property="taskDefinitionKey" column="task_definition_key"/>
<result property="owner" column="owner"/>
<result property="processInstanceId" column="process_instance_id"/>
<result property="processDefinitionId" column="process_definition_id"/>
<result property="processDefinitionName" column="process_definition_name"/>
<result property="processDefinitionKey" column="process_definition_key"/>
<result property="processApplyId" column="process_apply_id"/>
<result property="processApplyName" column="process_apply_name"/>
<result property="businessNo" column="business_no"/>
<result property="delegation" column="delegation"/>
<result property="candidateUser" column="candidate_user"/>
<result property="executionId" column="execution_id"/>
resultMap>
<select id="customPage" resultMap="resultMap">
<include refid="query">include>
select>
<select id="get" resultMap="resultMap">
<include refid="query">include>
select>
<select id="todoTask" resultMap="toTodoTaskResultMap">
<include refid="toTodoTaskQuery">include>
select>
mapper>
我的申请是用户方便快捷查看自己发起的流程列表,关注尚未结束流程的当前进度,如当前环节、当前处理人等,以及已经结束的流程,历史单据信息和审批信息。
一种设计方案,是将这部分单据按照是否结束拆分成两个菜单,称为我的申请和结束单据。这种方案,对于用户来说并不太友好,比如,一些临近结束或已经结束的流程,用户并不清楚处理进度,可能需要去两个菜单里都找一下。因此,还是采用1个菜单,用户在这个菜单下可以找到所有数据,更人性化一些。
基于上面的功能设计,官方的api返回的字段信息太有限了,还得通过类似查询我的待办的实现方式,自定义sql关联表来实现。
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.abc.platform.workflow.mapper.ProcessInstanceMapper">
<sql id="query"> select * from (
select t1.PROC_INST_ID_ AS id, #流程实例标识
t1.BUSINESS_KEY_ as business_no, #单号
t1.PROC_DEF_ID_ as process_definition_id, #流程定义标识
t1.PROC_DEF_KEY_ as process_definition_key, #流程编码
t2.NAME_ as process_definition_name, #流程名称
t1.START_TIME_ as start_time, #启动时间
t1.END_TIME_ as end_time, #结束时间
t1.STATE_ as state, #状态
t1.START_USER_ID_ as process_apply_id, #申请人id
t4.NAME as process_apply_name, #申请人姓名
t3.NAME_ as node_name, #环节名称
t3.ASSIGNEE_ as node_assignee, #环节处理人
t5.NAME as node_assignee_name #环节处理人姓名
from act_hi_procinst t1
LEFT JOIN act_re_procdef t2
on t1.PROC_DEF_ID_=t2.id_
LEFT JOIN act_ru_task t3
on t1.PROC_INST_ID_=t3.PROC_INST_ID_
LEFT JOIN sys_user t4
on t1.START_USER_ID_=t4.id
LEFT JOIN sys_user t5
on t3.ASSIGNEE_=t5.id
) t
${ew.customSqlSegment}sql>
<resultMap id="resultMap" type="tech.abc.platform.workflow.entity.ProcessInstance">
<id property="id" column="id"/>
<result property="businessNo" column="business_no"/>
<result property="processDefinitionId" column="process_definition_id"/>
<result property="processDefinitionKey" column="process_definition_key"/>
<result property="processDefinitionName" column="process_definition_name"/>
<result property="startTime" column="start_time"/>
<result property="endTime" column="end_time"/>
<result property="state" column="state"/>
<result property="processApplyId" column="process_apply_id"/>
<result property="processApplyName" column="process_apply_name"/>
<result property="nodeName" column="node_name"/>
<result property="nodeAssignee" column="node_assignee"/>
<result property="nodeAssigneeName" column="node_assignee_name"/>
resultMap>
<select id="customPage" resultMap="resultMap">
<include refid="query">include>
select>
<select id="get" resultMap="resultMap">
<include refid="query">include>
select>
mapper>
我的已办是查询当前人员处理过的所有流程
实现参照我的待办和我的申请,通过自定义sql方式实现。因activiti审批意见功能不完善,通过自定义表实现了,但该表同样没有保存任务标识(保存了也没用,对于委托、转办等功能,activiti共用同一条任务,任务标识是同一个),因此,在我的已办列表中无法显示当时的审批意见(实际也并不需要),点击详情后加载审批历史可以看到。
同时,如一个人在某条审批流程中多个环节或同一环节多次处理(如回退引发),在我的已办中会显示多条,不会也不应该按流程合并。
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tech.abc.platform.workflow.mapper.ProcessHistoricTaskMapper">
<sql id="query">
select * from (
select t1.ID_ AS id, #任务标识
t1.NAME_ as node_name, #环节名称
t1.START_TIME_ as start_time, #任务开始时间
t1.END_TIME_ as end_time, #任务结束时间
t1.DELETE_REASON_ as delete_reason, #任务移除原因
t1.ASSIGNEE_ as assignee, #处理人
t5.name as assignee_name, #处理人姓名
t1.TASK_DEF_KEY_ as task_definition_key, #任务定义标识
t1.OWNER_ as owner, #任务拥有者
t1.PROC_INST_ID_ AS process_instance_id, #流程实例标识
t3.PROC_DEF_ID_ as process_definition_id, #流程定义标识
t2.NAME_ as process_definition_name, #流程名称
t3.PROC_DEF_KEY_ as process_definition_key, #流程编码
t3.START_USER_ID_ as process_apply_id, #申请人id
t4.name as process_apply_name, #申请人姓名
t3.BUSINESS_KEY_ as business_no #单号
from act_hi_taskinst t1
LEFT JOIN act_re_procdef t2
on t1.PROC_DEF_ID_=t2.id_
LEFT JOIN act_hi_procinst t3
on t1.PROC_INST_ID_=t3.PROC_INST_ID_
LEFT JOIN sys_user t4
on t3.START_USER_ID_=t4.id
LEFT JOIN sys_user t5
on t1.ASSIGNEE_=t5.id
) t
${ew.customSqlSegment}
sql>
<resultMap id="resultMap" type="tech.abc.platform.workflow.entity.ProcessHistoricTask">
<id property="id" column="id"/>
<result property="nodeName" column="node_name"/>
<result property="startTime" column="start_time"/>
<result property="endTime" column="end_time"/>
<result property="deleteReason" column="delete_reason"/>
<result property="assignee" column="assignee"/>
<result property="assigneeName" column="assignee_name"/>
<result property="taskDefinitionKey" column="task_definition_key"/>
<result property="owner" column="owner"/>
<result property="processInstanceId" column="process_instance_id"/>
<result property="processDefinitionId" column="process_definition_id"/>
<result property="processDefinitionName" column="process_definition_name"/>
<result property="processDefinitionKey" column="process_definition_key"/>
<result property="processApplyId" column="process_apply_id"/>
<result property="processApplyName" column="process_apply_name"/>
<result property="businessNo" column="business_no"/>
resultMap>
<select id="customPage" resultMap="resultMap">
<include refid="query">include>
select>
<select id="get" resultMap="resultMap">
<include refid="query">include>
select>
mapper>
平台名称:一二三开发平台
简介: 企业级通用开发平台
设计资料:csdn专栏
开源地址:Gitee
开源协议:MIT
开源不易,欢迎收藏、点赞、评论。