SpringBoot_工作流_Activiti
- 简述
- 表结构
- 对象
- RepositoryService仓储服务
- RuntimeService运行时服务
- TaskService任务服务
- HistoryService历史服务
- 开发步骤
- 依赖
- 配置文件
- 请假bpmn
- 配置源码
- 流程部署
- 流程部署列表查询
- 流程删除
- 发起流程
- 在运行的流程基本信息列表查询
- 高级经理流程待办任务列表查询
- 高级经理任务办理
- 获取流程流转图
- 部门经理拒绝,申请人待办列表查询
- 发起人重新提交
- 人事流程待办任务列表查询
- 发起人流程待办任务列表查询(销假)
- 发起人销假任务办理
- 发起人流程办结列表查询
- 流程节点流程信息查询
简述
工作流:通过计算机对业务流程进行自动化管理,实现多个参与者按照预定义的流程去自动执行业务流程。
Activiti:一个工作流的引擎,开源的架构,基本 bpmn2.0 标准进行流程定义,它的是前身是 jbpm。Activiti 通过是要嵌入到业务系统开发使用。
表结构
ACT_RE_: 'RE’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
ACT_RU_: 'RU’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
ACT_ID_: 'ID’表示identity。 这些表包含身份信息,比如用户,组等等。
ACT_HI_: 'HI’表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
ACT_GE_: 通用数据, 用于不同场景下。
ACT_EVT_: EVT表示EVENT,目前只有一张表ACT_EVT_LOG,存储事件处理日志,方便管理员跟踪处理。
对象
ProcessEngineConfiguration 流程引擎配置信息对象
ProcessEngine 流程引擎
RepositoryService 仓储服务
RuntimeService 运行时服务
TaskService 任务服务
IdentityService 身份管理服务
HistoryService 历史服务
FormService 表单数据服务
ManagementService 管理服务
RepositoryService仓储服务
– act_ge_bytearray
– act_re_deployment
– act_re_procdef
– act_ge_property
完成的功能:
– 流程部署
– 流程部署查询
– 删除流程部署
– 流程定义查询
– 查询流程定义资源文件(BpmnModel)
– 查询流程定义资源图片(InputStream)
RuntimeService运行时服务
– act_ru_execution
– act_ru_event_subscr
– act_ru_job
– act_ru_task
– act_ru_variable
完成的功能:
– 开启流程实例.
– 查询流程实例.
– 删除流程实例.
– 触发走一步.signal
– 获取当前活动的节点.
TaskService任务服务
– act_ru_task
完成的功能:
– 查询任务.
– 完成任务.
HistoryService历史服务
– act_hi_procinst
– act_hi_taskinst
完成的功能:
– 查询历史流程实例
– 查询历史任务实例
开发步骤
1、创建业务表(对应每个流程),u-r-p表;
2、设计流程,IDE插件创建等方式;
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>1.5.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.5.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.10.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.10.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>5.22.0</version>
</dependency>
配置文件
server.port=8087
#mybatis
mybatis.config-location=classpath:mybatis-config.xml
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=boot.spring.po
#logs
logging.path=/var/log/
#root level
logging.level.root=INFO
#package level
logging.level.boot.spring.controller=DEBUG
#datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/activiti5.22?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=qwe123
#activiti default configuration 系统创建自动25张创建流程表
spring.activiti.database-schema-update = true
#关闭流程自动部署,通过上传方式部署
spring.activiti.check-process-definitions = false
#spring.activiti.process-definition-location-prefix = classpath:/process/
#process-definition-location-suffixes:
#- **.bpmn
#- **.bpmn20.xml
spring.activiti.history-level = full
请假bpmn
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="leave" name="My process" isExecutable="true">
<userTask id="deptleaderaudit" name="部门领导审批" activiti:candidateGroups="部门经理"></userTask>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<userTask id="hraudit" name="人事审批" activiti:candidateGroups="人事"></userTask>
<sequenceFlow id="flow3" name="同意" sourceRef="exclusivegateway1" targetRef="hraudit">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptleaderapprove=='true'}]]></conditionExpression>
</sequenceFlow>
<userTask id="modifyapply" name="调整申请" activiti:assignee="${applyuserid}"></userTask>
<sequenceFlow id="flow4" name="拒绝" sourceRef="exclusivegateway1" targetRef="modifyapply">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptleaderapprove=='false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow6" sourceRef="deptleaderaudit" targetRef="exclusivegateway1"></sequenceFlow>
<exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow7" sourceRef="modifyapply" targetRef="exclusivegateway2"></sequenceFlow>
<sequenceFlow id="flow8" name="重新申请" sourceRef="exclusivegateway2" targetRef="deptleaderaudit">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply=='true'}]]></conditionExpression>
</sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow9" name="结束流程" sourceRef="exclusivegateway2" targetRef="endevent1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${reapply=='false'}]]></conditionExpression>
</sequenceFlow>
<exclusiveGateway id="exclusivegateway3" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow10" sourceRef="hraudit" targetRef="exclusivegateway3"></sequenceFlow>
<sequenceFlow id="flow11" name="拒绝" sourceRef="exclusivegateway3" targetRef="modifyapply">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrapprove=='false'}]]></conditionExpression>
</sequenceFlow>
<userTask id="reportback" name="销假" activiti:assignee="${applyuserid}"></userTask>
<sequenceFlow id="flow12" name="同意" sourceRef="exclusivegateway3" targetRef="reportback">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${hrapprove=='true'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow13" sourceRef="reportback" targetRef="endevent1"></sequenceFlow>
<startEvent id="startevent1" name="Start" activiti:initiator="${applyuserid}"></startEvent>
<sequenceFlow id="flow14" sourceRef="startevent1" targetRef="deptleaderaudit"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_leave">
<bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave">
<bpmndi:BPMNShape bpmnElement="deptleaderaudit" id="BPMNShape_deptleaderaudit">
<omgdc:Bounds height="55.0" width="105.0" x="250.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="535.0" y="227.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="hraudit" id="BPMNShape_hraudit">
<omgdc:Bounds height="55.0" width="105.0" x="620.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="modifyapply" id="BPMNShape_modifyapply">
<omgdc:Bounds height="55.0" width="105.0" x="503.0" y="310.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
<omgdc:Bounds height="40.0" width="40.0" x="535.0" y="410.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="890.0" y="413.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway3" id="BPMNShape_exclusivegateway3">
<omgdc:Bounds height="40.0" width="40.0" x="770.0" y="228.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="reportback" id="BPMNShape_reportback">
<omgdc:Bounds height="55.0" width="105.0" x="855.0" y="221.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="140.0" y="230.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="575.0" y="247.0"></omgdi:waypoint>
<omgdi:waypoint x="620.0" y="247.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="575.0" y="247.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="555.0" y="267.0"></omgdi:waypoint>
<omgdi:waypoint x="555.0" y="310.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="555.0" y="267.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="355.0" y="247.0"></omgdi:waypoint>
<omgdi:waypoint x="535.0" y="247.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">
<omgdi:waypoint x="555.0" y="365.0"></omgdi:waypoint>
<omgdi:waypoint x="555.0" y="410.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
<omgdi:waypoint x="535.0" y="430.0"></omgdi:waypoint>
<omgdi:waypoint x="302.0" y="429.0"></omgdi:waypoint>
<omgdi:waypoint x="302.0" y="275.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="361.0" y="438.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
<omgdi:waypoint x="575.0" y="430.0"></omgdi:waypoint>
<omgdi:waypoint x="890.0" y="430.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="48.0" x="659.0" y="437.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
<omgdi:waypoint x="725.0" y="247.0"></omgdi:waypoint>
<omgdi:waypoint x="770.0" y="248.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
<omgdi:waypoint x="790.0" y="268.0"></omgdi:waypoint>
<omgdi:waypoint x="789.0" y="337.0"></omgdi:waypoint>
<omgdi:waypoint x="608.0" y="337.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="672.0" y="319.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
<omgdi:waypoint x="810.0" y="248.0"></omgdi:waypoint>
<omgdi:waypoint x="855.0" y="248.0"></omgdi:waypoint>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="14.0" width="24.0" x="810.0" y="248.0"></omgdc:Bounds>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow13" id="BPMNEdge_flow13">
<omgdi:waypoint x="907.0" y="276.0"></omgdi:waypoint>
<omgdi:waypoint x="907.0" y="413.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow14" id="BPMNEdge_flow14">
<omgdi:waypoint x="175.0" y="247.0"></omgdi:waypoint>
<omgdi:waypoint x="250.0" y="247.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
配置源码
流程部署
//流程部署
@RequestMapping(value="/uploadworkflow")
public String fileupload(@RequestParam MultipartFile uploadfile,HttpServletRequest request){
try{
MultipartFile file=uploadfile;
String filename=file.getOriginalFilename();//流程文件id最后不要一样---------参考截图------------
InputStream is=file.getInputStream();
repositoryService.createDeployment().addInputStream(filename, is).deploy();
}catch(Exception e){
e.printStackTrace();
}
return "index";
}
流程部署列表查询
@RequestMapping(value="/getprocesslists")
@ResponseBody
public DataGrid<Process> getlist(@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
int firstrow=(current-1)*rowCount;
List<ProcessDefinition> list=repositoryService.createProcessDefinitionQuery().listPage(firstrow, rowCount);
int total=repositoryService.createProcessDefinitionQuery().list().size();
List<Process> mylist=new ArrayList<Process>();
for(int i=0;i<list.size();i++)
{
Process p=new Process();
p.setDeploymentId(list.get(i).getDeploymentId()); //部署id
p.setId(list.get(i).getId());
p.setKey(list.get(i).getKey());
p.setName(list.get(i).getName());
p.setResourceName(list.get(i).getResourceName());
p.setDiagramresourcename(list.get(i).getDiagramResourceName());
mylist.add(p);
}
//响应对象封装
DataGrid<Process> grid=new DataGrid<Process>();
grid.setCurrent(current);
grid.setRowCount(rowCount);
grid.setRows(mylist);
grid.setTotal(total);
return grid;
}
流程删除
@RequestMapping(value="/deletedeploy")
public String deletedeploy(@RequestParam("deployid") String deployid) throws Exception{
repositoryService.deleteDeployment(deployid,true);//删除给定的部署并将删除级联到流程实例、历史流程实例和作业
return "activiti/processlist";
}
发起流程
如下图,变量名为applyuserid会影响整个流程。
也就是开始发起赋值后,后面节点配置了该变量名都会赋值。
//1、定义业务流程表
@ApiModel("请假表")
@Data
public class LeaveApply implements Serializable{
@ApiModelProperty("主键")
int id;
@ApiModelProperty("流程实例id")
String process_instance_id;
@ApiModelProperty("用户名")
String user_id;
@ApiModelProperty("请假起始时间")
String start_time;
@ApiModelProperty("请假结束时间")
String end_time;
@ApiModelProperty("请假类型")
String leave_type;
@ApiModelProperty("请假原因")
String reason;
@ApiModelProperty("申请时间")
String apply_time;
@ApiModelProperty("实际请假起始时间")
String reality_start_time;
@ApiModelProperty("实际请假结束时间")
String reality_end_time;
Task task;
}
//2、API
@RequestMapping(value="/startleave",method=RequestMethod.POST)
@ResponseBody
public String start_leave(LeaveApply apply,HttpSession session){
String userid=(String) session.getAttribute("username");
Map<String,Object> variables=new HashMap<String, Object>();
variables.put("applyuserid", userid);
ProcessInstance ins=leaveservice.startWorkflow(apply, userid, variables);
System.out.println("流程id"+ins.getId()+"已启动");
return JSON.toJSONString("sucess");
}
//3、具体实现
public ProcessInstance startWorkflow(LeaveApply apply, String userid, Map<String, Object> variables) {
apply.setApply_time(new Date().toString());
apply.setUser_id(userid);
leavemapper.save(apply); //请假数据保存,返回主键
String businesskey=String.valueOf(apply.getId());//使用leaveapply表的主键作为businesskey,连接业务数据和流程数据
identityservice.setAuthenticatedUserId(userid);
//开启实例,实例的buskey为对应请假表的主键id值,variables包含applyuserid变量,--------------参考截图-----------
ProcessInstance instance=runtimeservice.startProcessInstanceByKey("leave",businesskey,variables);
System.out.println(businesskey);
//发起请假流程的实例id,唯一
String instanceid=instance.getId();
apply.setProcess_instance_id(instanceid);
leavemapper.update(apply);//更新请假表数据
return instance;
}
在运行的流程基本信息列表查询
//正在运行的流程
@Data
public class RunningProcess {
String executionid;//执行ID
String processInstanceid;//流程实例ID
String businesskey;//业务号
String activityid;//当前节点信息
}
//========查询本人发起的=========
@RequestMapping(value="setupprocess",method = RequestMethod.POST)
@ResponseBody
public DataGrid<RunningProcess> setupprocess(HttpSession session,@RequestParam("current") int current,@RequestParam("rowCount") int rowCount){
int firstrow=(current-1)*rowCount;
String userid=(String) session.getAttribute("username");
System.out.print(userid);
ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
//int total= (int) query.count(); //查询出所有创建的流程实例数据
long total= query.processDefinitionKey("leave").involvedUser(userid).count();
List<ProcessInstance> a = query.processDefinitionKey("leave").involvedUser(userid).listPage(firstrow, rowCount);//查询出指定人发起的请假流程实例数据
List<RunningProcess> list=new ArrayList<RunningProcess>();
for(ProcessInstance p:a){
RunningProcess process=new RunningProcess();
process.setActivityid(p.getActivityId());//当前节点 ------------(参考截图)----------
process.setBusinesskey(p.getBusinessKey());//请假表主键
process.setExecutionid(p.getId());
process.setProcessInstanceid(p.getProcessInstanceId());
LeaveApply l=leaveservice.getleave(Integer.parseInt(p.getBusinessKey()));//获取关联请假表数据,选择性展现到页面
if(l.getUser_id().equals(userid)) {
list.add(process);
}else {
continue;
}
}
//响应对象封装
DataGrid<RunningProcess> grid=new DataGrid<RunningProcess>();
grid.setCurrent(current);
grid.setRowCount(rowCount);
grid.setTotal(total);
grid.setRows(list);
return grid;
}
//===========查询本人参与的========
@RequestMapping(value = "involvedprocess") // 参与的正在运行的请假流程
@ResponseBody
public DataGrid<RunningProcess> allexeution(HttpSession session, @RequestParam("current") int current,
@RequestParam("rowCount") int rowCount) {
int firstrow = (current - 1) * rowCount;
String userid = (String) session.getAttribute("username");
ProcessInstanceQuery query = runservice.createProcessInstanceQuery();
int total = (int) query.count();
List<ProcessInstance> a = query.processDefinitionKey("leave").involvedUser(userid).listPage(firstrow, rowCount);
List<RunningProcess> list = new ArrayList<RunningProcess>();
for (ProcessInstance p : a) {
RunningProcess process = new RunningProcess();
process.setActivityid(p.getActivityId());
process.setBusinesskey(p.getBusinessKey());
process.setExecutionid(p.getId());
process.setProcessInstanceid(p.getProcessInstanceId());
list.add(process);
}
DataGrid<RunningProcess> grid = new DataGrid<RunningProcess>();
grid.setCurrent(current);
grid.setRowCount(rowCount);
grid.setTotal(total);
grid.setRows(list);
return grid;
}
高级经理流程待办任务列表查询
该节点待办人:通过查询权限表拥有(部门领导审批)权限的用户方可以进行对应分配给(部门经理)的待办任务。
//1、请假待办任务对象
@ApiModel("请假任务信息")
@Data
public class LeaveTask {
@ApiModelProperty("主键")
int id;
@ApiModelProperty("流程实例id")
String process_instance_id;
@ApiModelProperty("用户名")
String user_id;
@ApiModelProperty("请假起始时间")
String start_time;
@ApiModelProperty("请假结束时间")
String end_time;
@ApiModelProperty("请假类型")
String leave_type;
@ApiModelProperty("请假原因")
String reason;
@ApiModelProperty("申请时间")
String apply_time;
@ApiModelProperty("实际请假起始时间")
String reality_start_time;
@ApiModelProperty("实际请假结束时间")
String reality_end_time;
@ApiModelProperty("任务id")
String taskid;
@ApiModelProperty("任务名")
String taskname;
@ApiModelProperty("流程实例id")
String processinstanceid;
@ApiModelProperty("流程定义id")
String processdefid;
@ApiModelProperty("任务创建时间")
Date taskcreatetime;
}
//2、API
@ApiOperation("获取部门领导审批代办列表")
@RequestMapping(value = "/depttasklist", produces = { "application/json;charset=UTF-8" })
@ResponseBody
public DataGrid<LeaveTask> getdepttasklist(HttpSession session, @RequestParam("current") int current,
@RequestParam("rowCount") int rowCount) {
DataGrid<LeaveTask> grid = new DataGrid<LeaveTask>();
grid.setRowCount(rowCount);
grid.setCurrent(current);
grid.setTotal(0);
grid.setRows(new ArrayList<LeaveTask>());
// 先做权限检查,对于没有部门领导审批权限的用户,直接返回空
String userid = (String) session.getAttribute("username");
int uid = systemservice.getUidByusername(userid);
User user = systemservice.getUserByid(uid);
//用户管理角色(获取角色)---->角色管理权限(获取权限)
List<User_role> userroles = user.getUser_roles();
if (userroles == null)
return grid;
boolean flag = false;// 默认没有权限
for (int k = 0; k < userroles.size(); k++) {
User_role ur = userroles.get(k);
Role r = ur.getRole();
int roleid = r.getRid();
Role role = systemservice.getRolebyid(roleid);
List<Role_permission> p = role.getRole_permission();
for (int j = 0; j < p.size(); j++) {
Role_permission rp = p.get(j);
Permission permission = rp.getPermission();
if (permission.getPermissionname().equals("部门领导审批")) //当前登录人有(部门领导审批)权限
flag = true;
else
continue;
}
}
if (flag == false)// 无权限
{
return grid;//返回空
} else {
int firstrow = (current - 1) * rowCount;
List<LeaveApply> results = leaveservice.getpagedepttask(userid, firstrow, rowCount);
List<Task> taskss=taskservice.createTaskQuery().processDefinitionKey("leave").taskCandidateGroup("部门经理").list();
int totalsize = taskss.size();
List<LeaveTask> tasks = new ArrayList<LeaveTask>();
for (LeaveApply apply : results) {
LeaveTask task = new LeaveTask();
task.setApply_time(apply.getApply_time());
task.setUser_id(apply.getUser_id());
task.setEnd_time(apply.getEnd_time());
task.setId(apply.getId());
task.setLeave_type(apply.getLeave_type());
task.setProcess_instance_id(apply.getProcess_instance_id());
task.setProcessdefid(apply.getTask().getProcessDefinitionId());
task.setReason(apply.getReason());
task.setStart_time(apply.getStart_time());
task.setTaskcreatetime(apply.getTask().getCreateTime());
task.setTaskid(apply.getTask().getId());
task.setTaskname(apply.getTask().getName());
tasks.add(task);
}
grid.setRowCount(rowCount);
grid.setCurrent(current);
grid.setTotal(totalsize);
grid.setRows(tasks);
return grid;
}
}
//3、具体实现
public List<LeaveApply> getpagedepttask(String userid,int firstrow,int rowcount) {
List<LeaveApply> results=new ArrayList<LeaveApply>();
//获取请假流程候选组为(部门经理)节点的所有待办任务列表,--------------(参考截图)---------------
List<Task> tasks=taskservice.createTaskQuery().processDefinitionKey("leave").taskCandidateGroup("部门经理").listPage(firstrow, rowcount);
for(Task task:tasks){
//获取流程实例id
String instanceid=task.getProcessInstanceId();
//通过流程实例id获取流程实例数据
ProcessInstance ins=runtimeservice.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
//通过流程实例业务号获取请假数据
String businesskey=ins.getBusinessKey();
LeaveApply a=leavemapper.get(Integer.parseInt(businesskey));
//将任务对象封装到请假对象中
a.setTask(task);
results.add(a);
}
return results;
}
高级经理任务办理
@RequestMapping(value = "/task/deptcomplete/{taskid}")
@ResponseBody
public String deptcomplete(HttpSession session, @PathVariable("taskid") String taskid, HttpServletRequest req) {
String userid = (String) session.getAttribute("username");
Map<String, Object> variables = new HashMap<String, Object>();
//变量值---------------(参考截图)----------------
String approve = req.getParameter("deptleaderapprove");//获取节点变量值:true、false
variables.put("deptleaderapprove", approve);
//签收任务
taskservice.claim(taskid, userid);
//办理任务
taskservice.complete(taskid, variables);
return JSON.toJSONString("success");
}
获取流程流转图
@RequestMapping(value = "traceprocess/{executionid}")
public void traceprocess(@PathVariable("executionid") String executionid, HttpServletResponse response)
throws Exception {
ProcessInstance process = runservice.createProcessInstanceQuery().processInstanceId(executionid).singleResult();
BpmnModel bpmnmodel = rep.getBpmnModel(process.getProcessDefinitionId());
List<String> activeActivityIds = runservice.getActiveActivityIds(executionid);
DefaultProcessDiagramGenerator gen = new DefaultProcessDiagramGenerator();
// 获得历史活动记录实体(通过启动时间正序排序,不然有的线可以绘制不出来)
List<HistoricActivityInstance> historicActivityInstances = histiryservice.createHistoricActivityInstanceQuery()
.executionId(executionid).orderByHistoricActivityInstanceStartTime().asc().list();
// 计算活动线
List<String> highLightedFlows = leaveservice
.getHighLightedFlows(
(ProcessDefinitionEntity) ((RepositoryServiceImpl) rep)
.getDeployedProcessDefinition(process.getProcessDefinitionId()),
historicActivityInstances);
InputStream in = gen.generateDiagram(bpmnmodel, "png", activeActivityIds, highLightedFlows, "宋体", "宋体", null,
null, 1.0);
// InputStream in=gen.generateDiagram(bpmnmodel, "png", activeActivityIds);
ServletOutputStream output = response.getOutputStream();
IOUtils.copy(in, output);
}
部门经理拒绝,申请人待办列表查询
可以考虑和高级经理流程待办任务列表查询复用代码。
@RequestMapping(value = "/updatetasklist", produces = { "application/json;charset=UTF-8" })
@ResponseBody
public String getupdatetasklist(HttpSession session, @RequestParam("current") int current,
@RequestParam("rowCount") int rowCount) {
int firstrow = (current - 1) * rowCount;
String userid = (String) session.getAttribute("username");
List<LeaveApply> results = leaveservice.getpageupdateapplytask(userid, firstrow, rowCount);
int totalsize = taskservice.createTaskQuery().processDefinitionKey("leave").taskCandidateOrAssigned(userid).taskName("调整申请").list().size();
List<LeaveTask> tasks = new ArrayList<LeaveTask>();
for (LeaveApply apply : results) {
LeaveTask task = new LeaveTask();
task.setApply_time(apply.getApply_time());
task.setUser_id(apply.getUser_id());
task.setEnd_time(apply.getEnd_time());
task.setId(apply.getId());
task.setLeave_type(apply.getLeave_type());
task.setProcess_instance_id(apply.getProcess_instance_id());
task.setProcessdefid(apply.getTask().getProcessDefinitionId());
task.setReason(apply.getReason());
task.setStart_time(apply.getStart_time());
task.setTaskcreatetime(apply.getTask().getCreateTime());
task.setTaskid(apply.getTask().getId());
task.setTaskname(apply.getTask().getName());
tasks.add(task);
}
DataGrid<LeaveTask> grid = new DataGrid<LeaveTask>();
grid.setRowCount(rowCount);
grid.setCurrent(current);
grid.setTotal(totalsize);
grid.setRows(tasks);
return JSON.toJSONString(grid);
}
public List<LeaveApply> getpageupdateapplytask(String userid,int firstrow,int rowcount) {
List<LeaveApply> results=new ArrayList<LeaveApply>();
//查询指定用户,指定任务节点上所有待办的任务----------------(参考截图)-------------
List<Task> tasks=taskservice.createTaskQuery().taskCandidateOrAssigned(userid).taskName("调整申请").listPage(firstrow, rowcount);
for(Task task:tasks){
String instanceid=task.getProcessInstanceId();
ProcessInstance ins=runtimeservice.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
String businesskey=ins.getBusinessKey();
LeaveApply a=leavemapper.get(Integer.parseInt(businesskey));
a.setTask(task);
results.add(a);
}
return results;
}
发起人重新提交
//1、API
@RequestMapping(value = "/task/updatecomplete/{taskid}")
@ResponseBody
public String updatecomplete(@PathVariable("taskid") String taskid, @ModelAttribute("leave") LeaveApply leave,
@RequestParam("reapply") String reapply) {
leaveservice.updatecomplete(taskid, leave, reapply);
return JSON.toJSONString("success");
}
//2、具体实现
public void updatecomplete(String taskid, LeaveApply leave,String reapply) {
Task task=taskservice.createTaskQuery().taskId(taskid).singleResult();
//获取流程实例id
String instanceid=task.getProcessInstanceId();
ProcessInstance ins=runtimeservice.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
//获取业务号
String businesskey=ins.getBusinessKey();
//获取指定请假数据
LeaveApply a=leavemapper.get(Integer.parseInt(businesskey));
//更新请假数据
a.setLeave_type(leave.getLeave_type());
a.setStart_time(leave.getStart_time());
a.setEnd_time(leave.getEnd_time());
a.setReason(leave.getReason());
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("reapply", reapply);//重新提交标识:true、false
if(reapply.equals("true")){
//如果重新提交为true,更新请假数据
leavemapper.update(a);
//办理任务
taskservice.complete(taskid,variables);
}else
taskservice.complete(taskid,variables);
}
人事流程待办任务列表查询
该节点待办人:通过查询权限表拥有(人事审批)权限的用户方可以进行对应分配给(人事)的待办任务。
可以参考高级经理流程待办任务列表查询,也可以进行代码复用操作。
发起人流程待办任务列表查询(销假)
该节点待办人:一开始就指定了------发起人
可以参考高级经理流程待办任务列表查询,也可以进行代码复用操作。
@RequestMapping(value = "/xjtasklist", produces = { "application/json;charset=UTF-8" })
@ResponseBody
public String getXJtasklist(HttpSession session, @RequestParam("current") int current,
@RequestParam("rowCount") int rowCount) {
int firstrow = (current - 1) * rowCount;
String userid = (String) session.getAttribute("username");
List<LeaveApply> results = leaveservice.getpageXJtask(userid, firstrow, rowCount);
int totalsize = taskservice.createTaskQuery().processDefinitionKey("leave").taskCandidateOrAssigned(userid).taskName("销假").list().size();
List<LeaveTask> tasks = new ArrayList<LeaveTask>();
for (LeaveApply apply : results) {
LeaveTask task = new LeaveTask();
task.setApply_time(apply.getApply_time());
task.setUser_id(apply.getUser_id());
task.setEnd_time(apply.getEnd_time());
task.setId(apply.getId());
task.setLeave_type(apply.getLeave_type());
task.setProcess_instance_id(apply.getProcess_instance_id());
task.setProcessdefid(apply.getTask().getProcessDefinitionId());
task.setReason(apply.getReason());
task.setStart_time(apply.getStart_time());
task.setTaskcreatetime(apply.getTask().getCreateTime());
task.setTaskid(apply.getTask().getId());
task.setTaskname(apply.getTask().getName());
tasks.add(task);
}
DataGrid<LeaveTask> grid = new DataGrid<LeaveTask>();
grid.setRowCount(rowCount);
grid.setCurrent(current);
grid.setTotal(totalsize);
grid.setRows(tasks);
return JSON.toJSONString(grid);
}
//2、具体实现
public List<LeaveApply> getpageXJtask(String userid,int firstrow,int rowcount) {
List<LeaveApply> results=new ArrayList<LeaveApply>();
//根据分配人查询任务
List<Task> tasks=taskservice.createTaskQuery().processDefinitionKey("leave").taskCandidateOrAssigned(userid).taskName("销假").listPage(firstrow, rowcount);
for(Task task:tasks){
String instanceid=task.getProcessInstanceId();
ProcessInstance ins=runtimeservice.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
String businesskey=ins.getBusinessKey();
LeaveApply a=leavemapper.get(Integer.parseInt(businesskey));
a.setTask(task);
results.add(a);
}
return results;
}
发起人销假任务办理
//1、API
@RequestMapping(value = "/task/reportcomplete/{taskid}")
@ResponseBody
public String reportbackcomplete(@PathVariable("taskid") String taskid, HttpServletRequest req) {
String realstart_time = req.getParameter("realstart_time");
String realend_time = req.getParameter("realend_time");
leaveservice.completereportback(taskid, realstart_time, realend_time);
return JSON.toJSONString("success");
}
//2、具体实现
public void completereportback(String taskid, String realstart_time, String realend_time) {
Task task=taskservice.createTaskQuery().taskId(taskid).singleResult();
String instanceid=task.getProcessInstanceId();
ProcessInstance ins=runtimeservice.createProcessInstanceQuery().processInstanceId(instanceid).singleResult();
String businesskey=ins.getBusinessKey();
LeaveApply a=leavemapper.get(Integer.parseInt(businesskey));
a.setReality_start_time(realstart_time);
a.setReality_end_time(realend_time);
leavemapper.update(a);//更新请假表中,添加销假的时间范围
taskservice.complete(taskid);//办理任务
}
发起人流程办结列表查询
@RequestMapping(value = "/getfinishprocess")
@ResponseBody
public DataGrid<HistoryProcess> getHistory(HttpSession session, @RequestParam("current") int current,
@RequestParam("rowCount") int rowCount) {
String userid = (String) session.getAttribute("username");
//查询发起人为当前登录人的所有办结的历史数据
HistoricProcessInstanceQuery process = histiryservice.createHistoricProcessInstanceQuery()
.processDefinitionKey("leave").startedBy(userid).finished();
int total = (int) process.count();
int firstrow = (current - 1) * rowCount;
List<HistoricProcessInstance> info = process.listPage(firstrow, rowCount);
List<HistoryProcess> list = new ArrayList<HistoryProcess>();
for (HistoricProcessInstance history : info) {
HistoryProcess his = new HistoryProcess();
String bussinesskey = history.getBusinessKey();//业务号
LeaveApply apply = leaveservice.getleave(Integer.parseInt(bussinesskey));//获取对应请假数据
his.setLeaveapply(apply);
his.setBusinessKey(bussinesskey);
his.setProcessDefinitionId(history.getProcessDefinitionId());
list.add(his);
}
DataGrid<HistoryProcess> grid = new DataGrid<HistoryProcess>();
grid.setCurrent(current);
grid.setRowCount(rowCount);
grid.setTotal(total);
grid.setRows(list);
return grid;
}
流程节点流程信息查询
@RequestMapping(value = "/processinfo")
@ResponseBody
public List<HistoricActivityInstance> processinfo(@RequestParam("instanceid") String instanceid) {
//通过流程实例id获取节点信息
List<HistoricActivityInstance> his = histiryservice.createHistoricActivityInstanceQuery()
.processInstanceId(instanceid).orderByHistoricActivityInstanceStartTime().asc().list();
return his;
}