SpringBoot_工作流_Activiti

简述

工作流:通过计算机对业务流程进行自动化管理,实现多个参与者按照预定义的流程去自动执行业务流程。

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;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值