Conflicts:
	pom.xml
main
wenbaoquan 2 years ago
commit 09b0125780
  1. 25
      .gitignore
  2. 20
      pom.xml
  3. 198
      src/main/java/com/zilber/boot/activiti/controller/BpmnController.java
  4. 23
      src/main/java/com/zilber/boot/activiti/dto/DeploymentDTO.java
  5. 33
      src/main/java/com/zilber/boot/activiti/dto/InstanceDTO.java
  6. 23
      src/main/java/com/zilber/boot/activiti/dto/PageQueryDTO.java
  7. 30
      src/main/java/com/zilber/boot/activiti/dto/TaskCompleteDTO.java
  8. 22
      src/main/java/com/zilber/boot/activiti/dto/TaskQueryDTO.java
  9. 17
      src/main/java/com/zilber/boot/activiti/listen/ApplyListener.java
  10. 23
      src/main/java/com/zilber/boot/activiti/listen/ApplyTaskListener.java
  11. 164
      src/main/java/com/zilber/boot/activiti/service/DefinitionService.java
  12. 54
      src/main/java/com/zilber/boot/activiti/service/HistoryService.java
  13. 167
      src/main/java/com/zilber/boot/activiti/service/InstanceService.java
  14. 124
      src/main/java/com/zilber/boot/activiti/service/TaskService.java
  15. 34
      src/main/java/com/zilber/boot/activiti/vo/DefinitionVO.java
  16. 74
      src/main/java/com/zilber/boot/activiti/vo/HistoricTaskVO.java
  17. 54
      src/main/java/com/zilber/boot/activiti/vo/InstanceProgressVO.java
  18. 48
      src/main/java/com/zilber/boot/activiti/vo/InstanceVO.java
  19. 43
      src/main/java/com/zilber/boot/activiti/vo/SimpleTaskVO.java
  20. 62
      src/main/java/com/zilber/boot/activiti/vo/TaskVO.java
  21. 10
      src/main/java/com/zilber/boot/framework/config/MyBatisConfig.java
  22. 57
      src/main/java/com/zilber/boot/framework/config/MybatisPlusConfig.java
  23. 2
      src/main/java/com/zilber/boot/framework/config/SecurityConfig.java
  24. 4
      src/main/resources/application-druid.yml
  25. 11
      src/main/resources/application.yml
  26. 24
      src/main/resources/banner.txt
  27. 170
      src/main/resources/bpmn/daily.bpmn20.xml
  28. 40
      src/main/resources/bpmn/leave.bpmn20.xml

25
.gitignore vendored

@ -0,0 +1,25 @@
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
target
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
*.iml
.idea
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

@ -35,6 +35,7 @@
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<activiti.version></activiti.version>
</properties>
<dependencies>
@ -155,6 +156,18 @@
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot.version}</version>
</dependency>-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- pagehelper 分页插件 -->
@ -241,6 +254,13 @@
<version>${jwt.version}</version>
</dependency>
<!-- 工作流-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>

@ -0,0 +1,198 @@
package com.zilber.boot.activiti.controller;
import com.github.pagehelper.PageInfo;
import com.zilber.boot.activiti.dto.*;
import com.zilber.boot.activiti.service.*;
import com.zilber.boot.activiti.vo.DefinitionVO;
import com.zilber.boot.activiti.vo.HistoricTaskVO;
import com.zilber.boot.activiti.vo.InstanceVO;
import com.zilber.boot.activiti.vo.TaskVO;
import com.zilber.boot.utils.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
@Validated
@RestController
@RequestMapping("/bpmn")
@Api(tags = "工作流接口")
@Slf4j
public class BpmnController {
@Resource
private DefinitionService definitionService;
@Resource
private InstanceService instanceService;
@Resource
private TaskService taskService;
@Resource
private HistoryService historyService;
@PostMapping("/definition/upload")
@ApiOperation("上传流程图")
public AjaxResult uploadAndDeployment(
@RequestParam @ApiParam("名称") String name,
@RequestParam @ApiParam("上传的文件") MultipartFile file) {
definitionService.uploadAndDeployment(name, file);
return AjaxResult.success();
}
@PostMapping("/definition")
@ApiOperation("保存流程图")
public AjaxResult saveAndDeployment(@RequestBody @Valid DeploymentDTO dto) {
definitionService.saveAndDeployment(dto.getName(), dto.getXml());
return AjaxResult.success();
}
@GetMapping("/definition/page")
@ApiOperation("查询流程定义列表")
public AjaxResult getDefinitionPage(@Valid PageQueryDTO dto) {
PageInfo<DefinitionVO> page = new PageInfo<>(definitionService.getDefinitionPage(dto));
return AjaxResult.success(page);
}
@GetMapping("/definition/list/by/{key}")
@ApiOperation("查询指定Key的流程定义所有列表")
public AjaxResult getVersionList(
@PathVariable @NotBlank String key) {
return AjaxResult.success(definitionService.getVersionList(key));
}
@GetMapping("/definition/by/key/{key}")
@ApiOperation("查询流程图,XML字符串格式")
public AjaxResult getDeploymentXMLByKey(
@PathVariable @ApiParam("流程定义Key") @NotBlank String key) {
String xmlString = definitionService.getDeploymentXML(key);
HashMap<String, String> map = new HashMap<>();
map.put("xml", xmlString);
return AjaxResult.success(map);
}
@GetMapping("/definition/by/{id}")
@ApiOperation("查询流程图,XML字符串格式")
public AjaxResult getDeploymentXML(
@PathVariable @ApiParam("流程部署ID") @NotBlank String id,
@RequestParam @ApiParam("资源文件名") @NotBlank String name) {
String xmlString = definitionService.getDeploymentXML(id, name);
HashMap<String, String> map = new HashMap<>();
map.put("xml", xmlString);
return AjaxResult.success(map);
}
@GetMapping("/definition/file/{id}")
@ApiOperation("查询流程图,XML文件格式")
public void getDeploymentFile(
HttpServletResponse response,
@PathVariable @ApiParam("流程部署ID") @NotBlank String id,
@RequestParam @ApiParam("资源文件名") @NotBlank String name) {
InputStream is = definitionService.getDeploymentStream(id, name);
OutputStream os;
try {
os = response.getOutputStream();
IOUtils.copy(is, os);
is.close();
os.close();
} catch (IOException e) {
log.error("查看流程文件失败", e);
}
}
@DeleteMapping("/definition/by/{id}")
@ApiOperation("删除流程定义")
public AjaxResult deleteDefinitionById(
@PathVariable @ApiParam("流程部署ID") @NotBlank String id) {
definitionService.deleteById(id);
return AjaxResult.success();
}
@GetMapping("/instance/page")
@ApiOperation("查询流程实例列表")
public AjaxResult getInstancePage(@Valid PageQueryDTO dto) {
PageInfo<InstanceVO> page = new PageInfo<>(instanceService.getInstancePage(dto));
return AjaxResult.success(page);
}
@PostMapping("/instance")
@ApiOperation("启动流程实例")
public AjaxResult startInstance(@RequestBody @Valid InstanceDTO dto) {
instanceService.start(dto);
return AjaxResult.success();
}
@PutMapping("/instance/suspend/by/{id}")
@ApiOperation("挂起流程实例")
public AjaxResult suspendInstance(@PathVariable @ApiParam("流程实例ID") @NotBlank String id) {
instanceService.suspend(id);
return AjaxResult.success();
}
@PutMapping("/instance/resume/by/{id}")
@ApiOperation("激活/重启流程实例")
public AjaxResult resumeInstance(@PathVariable @ApiParam("流程实例ID") @NotBlank String id) {
instanceService.resume(id);
return AjaxResult.success();
}
@DeleteMapping("/instance/by/{id}")
@ApiOperation("取消流程实例")
public AjaxResult deleteInstanceById(@PathVariable @ApiParam("流程实例ID") @NotBlank String id) {
instanceService.cancelById(id);
return AjaxResult.success();
}
@GetMapping("/instance/variables/by/{id}")
@ApiOperation("查询流程参数")
public AjaxResult instanceVariables(@PathVariable @ApiParam("流程实例ID") @NotBlank String id) {
return AjaxResult.success(instanceService.getVariables(id));
}
@GetMapping("/task/page")
@ApiOperation("查看待办任务")
public AjaxResult taskPage(@Valid TaskQueryDTO dto) {
PageInfo<TaskVO> page = new PageInfo<>(taskService.taskPage(dto));
return AjaxResult.success(page);
}
@PutMapping("/task/{id}")
@ApiOperation("完成任务")
public AjaxResult completeTask(
@PathVariable @NotBlank @ApiParam("流程任务ID") String id,
@RequestBody @Valid TaskCompleteDTO dto) {
taskService.complete(dto.getUserCode(), id, dto);
return AjaxResult.success();
}
@GetMapping("/historic/task/page")
@ApiOperation("查看历史任务")
public AjaxResult historicTaskPage(@Valid TaskQueryDTO dto) {
PageInfo<HistoricTaskVO> page = new PageInfo<>(historyService.historicTaskPage(dto));
return AjaxResult.success(page);
}
@GetMapping("/historic/task/list")
@ApiOperation("任务实例历史")
public List<HistoricTaskVO> getHistoryListByInstanceId(
@RequestParam @ApiParam("流程实例ID") @NotBlank String instanceId) {
return historyService.getListOfInstance(instanceId);
}
}

@ -0,0 +1,23 @@
package com.zilber.boot.activiti.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
@Getter
@Setter
@ApiModel("流程部署提交")
public class DeploymentDTO {
@NotBlank(message = "名称不能为空")
@ApiModelProperty(value = "名称", required = true)
private String name;
@NotBlank(message = "bpmn文件xml不能为空")
@ApiModelProperty(value = "bpmn文件xml", required = true)
private String xml;
}

@ -0,0 +1,33 @@
package com.zilber.boot.activiti.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Map;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ApiModel("启动流程实例")
public class InstanceDTO {
@NotBlank
@ApiModelProperty(value = "流程定义Key")
@Length(max = 32)
private String procDefKey;
@Length(max = 24)
@ApiModelProperty(value = "发起人")
private String createBy;
@ApiModelProperty(value = "流程变量")
private Map<String,Object> variables;
}

@ -0,0 +1,23 @@
package com.zilber.boot.activiti.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.Max;
import javax.validation.constraints.Positive;
import javax.validation.constraints.PositiveOrZero;
import java.io.Serializable;
@Getter
@Setter
public class PageQueryDTO implements Serializable {
@ApiModelProperty("每页记录数")
@Positive(message = "分页数量必须为正整数")
private Integer pageSize = 20;
@ApiModelProperty("当前页数")
@PositiveOrZero(message = "分页数不正确")
private Integer pageNo = 0;
}

@ -0,0 +1,30 @@
package com.zilber.boot.activiti.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
import java.util.Map;
@Getter
@Setter
@ApiModel("完成流程任务")
public class TaskCompleteDTO {
@NotNull(message = "请选择审批结果")
@ApiModelProperty("审批状态:1-通过 0-拒绝")
private Integer status;
@Length(max = 512)
@ApiModelProperty("意见")
private String remark;
@ApiModelProperty(value = "流程变量")
private Map<String, Object> variables;
@ApiModelProperty("用户")
private String userCode;
}

@ -0,0 +1,22 @@
package com.zilber.boot.activiti.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@ApiModel("任务查询")
public class TaskQueryDTO extends PageQueryDTO {
@ApiModelProperty("流程定义Key")
private String procDefKey;
@ApiModelProperty("任务执行人")
private String assignee;
@ApiModelProperty("流程实例ID")
private String procInstId;
}

@ -0,0 +1,17 @@
package com.zilber.boot.activiti.listen;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
public class ApplyListener implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) {
String eventName = execution.getEventName();
if ("start".endsWith(eventName)) {
System.out.println("流程 start===");
} else if ("end".endsWith(eventName)) {
System.out.println("流程 end===");
}
}
}

@ -0,0 +1,23 @@
package com.zilber.boot.activiti.listen;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
public class ApplyTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("===========进来了==============");
String eventName = delegateTask.getEventName();
if ("create".endsWith(eventName)) {
System.out.println("任务create===" + delegateTask.getName());
} else if ("complete".endsWith(eventName)) {
System.out.println("任务task complete===" + delegateTask.getName());
} else if ("delete".endsWith(eventName)) {
System.out.println("任务task delete===" + delegateTask.getName());
} else if ("assignment".endsWith(eventName)) {
System.out.println("任务task assignment===" + delegateTask.getName());
}
}
}

@ -0,0 +1,164 @@
package com.zilber.boot.activiti.service;
import com.zilber.boot.activiti.dto.PageQueryDTO;
import com.zilber.boot.activiti.vo.DefinitionVO;
import com.zilber.boot.exception.ServiceException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;
@Service
public class DefinitionService {
@Autowired
private RepositoryService repositoryService;
/**
* 上传并部署流程定义
*
* @param name 流程定义名称
* @param file 上传的文件
*/
public void uploadAndDeployment(String name, MultipartFile file) {
try {
String filename = file.getOriginalFilename();
String extension = FilenameUtils.getExtension(filename);
InputStream fileInputStream = file.getInputStream();
if ("zip".equals(extension)) {
ZipInputStream zip = new ZipInputStream(fileInputStream);
repositoryService.createDeployment()
.addZipInputStream(zip)
.name(name)
.deploy();
} else {
repositoryService.createDeployment()
.addInputStream(filename, fileInputStream)
.name(name)
.deploy();
}
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
}
public List<DefinitionVO> getDefinitionPage(PageQueryDTO dto) {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
.latestVersion().listPage(dto.getPageNo() * dto.getPageSize(), dto.getPageSize());
list.sort((y, x) -> x.getVersion() - y.getVersion());
return list.stream().map(processDefinition -> {
DefinitionVO vo = new DefinitionVO();
BeanUtils.copyProperties(processDefinition, vo);
return vo;
}).collect(Collectors.toList());
}
/**
* 根据流程定义Key获取历史版本
*
* @param key 流程定义Key
* @return 历史版本列表
*/
public List<DefinitionVO> getVersionList(String key) {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(key)
.orderByProcessDefinitionVersion().desc()
.list();
return list.stream().map(processDefinition -> {
DefinitionVO vo = new DefinitionVO();
BeanUtils.copyProperties(processDefinition, vo);
return vo;
}).collect(Collectors.toList());
}
/**
* 在线绘制流程图保存
*
* @param name 流程名称
* @param xml xml数据
*/
public void saveAndDeployment(String name, String xml) {
repositoryService.createDeployment()
.addString("bpmnjs.bpmn", xml)
.name(name)
.deploy();
}
/**
* 获取流程图
*
* @param deploymentId 流程部署ID
* @param resourceName 资源文件名称
* @return 数据流
*/
public InputStream getDeploymentStream(String deploymentId, String resourceName) {
return repositoryService.getResourceAsStream(deploymentId, resourceName);
}
/**
* 获取流程图xml
*
* @param definitionKey 流程定义Key
* @return xml字符串
*/
public String getDeploymentXML(String definitionKey) {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(definitionKey)
.latestVersion()
.singleResult();
return getDeploymentXML(processDefinition.getDeploymentId(), processDefinition.getResourceName());
}
/**
* 获取流程图xml
*
* @param deploymentId 流程部署ID
* @param resourceName 资源文件名称
* @return xml字符串
*/
public String getDeploymentXML(String deploymentId, String resourceName) {
try {
InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, StandardCharsets.UTF_8.name());
return writer.toString();
} catch (IOException e) {
throw new ServiceException(e.getMessage());
}
}
/**
* 获取流程定义
*
* @param processDefinitionId 流程定义ID
* @return
*/
public ProcessDefinition getById(String processDefinitionId) {
return repositoryService.createProcessDefinitionQuery()
.processDefinitionId(processDefinitionId)
.singleResult();
}
/**
* 根据流程定义id删除流程定义
*
* @param id 流程定义id
*/
public void deleteById(String id) {
repositoryService.deleteDeployment(id);
}
}

@ -0,0 +1,54 @@
package com.zilber.boot.activiti.service;
import com.zilber.boot.activiti.dto.TaskQueryDTO;
import com.zilber.boot.activiti.vo.HistoricTaskVO;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Service(value = "HistoryService_")
public class HistoryService {
@Resource
private org.activiti.engine.HistoryService historyService;
public List<HistoricTaskVO> historicTaskPage(TaskQueryDTO dto) {
HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
.finished()
.orderByHistoricTaskInstanceEndTime()
.desc();
if (!StringUtils.isEmpty(dto.getAssignee())) {
taskInstanceQuery.taskAssignee(dto.getAssignee());
}
if (!StringUtils.isEmpty(dto.getProcDefKey())) {
taskInstanceQuery.processDefinitionKey(dto.getProcDefKey());
}
if (!StringUtils.isEmpty(dto.getProcInstId())) {
taskInstanceQuery.processInstanceId(dto.getProcInstId());
}
List<HistoricTaskInstance> tasks = taskInstanceQuery.listPage(dto.getPageNo() * dto.getPageSize(), dto.getPageSize());
return HistoricTaskVO.merge(tasks);
}
public List<HistoricTaskVO> getListOfInstance(String instanceId) {
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
.orderByHistoricTaskInstanceStartTime()
.asc()
.processInstanceId(instanceId)
.list();
return list.stream()
.map(HistoricTaskVO::merge)
.collect(Collectors.toList());
}
}

@ -0,0 +1,167 @@
package com.zilber.boot.activiti.service;
import com.zilber.boot.activiti.dto.InstanceDTO;
import com.zilber.boot.activiti.dto.PageQueryDTO;
import com.zilber.boot.activiti.vo.InstanceProgressVO;
import com.zilber.boot.activiti.vo.InstanceVO;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.persistence.entity.EntityManager;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class InstanceService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
public ProcessInstance getById(String processInstanceId) {
return runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
}
public List<InstanceVO> getInstancePage(PageQueryDTO dto) {
ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery();
return InstanceVO.merge(query.listPage(dto.getPageNo() * dto.getPageSize(), dto.getPageSize()));
}
/**
* 启动流程实例并完成第一个任务
*
* @param dto 启动流程实例必要参数
*/
public void start(InstanceDTO dto) {
Map<String, Object> variables = dto.getVariables();
if (variables == null) {
variables = new HashMap<>();
}
// 设置默认的流程变量
variables.put("assignee0", dto.getCreateBy());
//variables.put("procDefKey", dto.getProcDefKey());
// 启动流程实例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
dto.getProcDefKey(), /*dto.getBusinessId() +*/ "", variables);
// 执行第一个任务
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
if (task != null) {
if (task.getAssignee() == null) {
taskService.claim(task.getId(), dto.getCreateBy());
}
taskService.complete(task.getId());
}
}
/**
* 查询指定流程进度
*
* @param instanceId 流程实例ID
* @return 进度列表
*/
public List<InstanceProgressVO> getInstanceProgress(String instanceId) {
String sql = "select\n" +
" t1.ACT_ID_ as actId,\n" +
" t1.TASK_ID_ as taskId,\n" +
" t1.ACT_NAME_ as actName,\n" +
" t1.ACT_TYPE_ as actType,\n" +
" t1.PROC_INST_ID_ as procInstId,\n" +
" t1.DURATION_ as duration,\n" +
" t1.ACT_INST_STATE_ as state,\n" +
" t1.START_TIME_ as startTime,\n" +
" t1.END_TIME_ as endTime,\n" +
" t1.ASSIGNEE_ as assignee,\n" +
" t2.MESSAGE_ as remark,\n" +
" t3.TEXT_ as operators\n" +
"from ACT_HI_ACTINST as t1\n" +
" left join ACT_HI_COMMENT as t2 on t1.TASK_ID_ = t2.TASK_ID_\n" +
" left join ACT_HI_VARINST as t3 on t1.ID_ = t3.ACT_INST_ID_ and t3.NAME_ = ?2\n" +
"where t1.PROC_INST_ID_ = ?1\n" +
" " +
"and t1.ACT_TYPE_ = 'userTask'\n" +
"order by t1.START_TIME_ desc, NOT ISNULL(t1.END_TIME_), t1" +
".END_TIME_ desc";
/*Query nativeQuery = entityManager.createNativeQuery(sql);
nativeQuery.setParameter(1, instanceId);
nativeQuery.setParameter(2, CamundaConstants.OPERATORS);
return nativeQuery
.unwrap(NativeQueryImpl.class)
.setResultTransformer(Transformers.aliasToBean(InstanceProgressVO.class))
.list();*/
return null;
}
/**
* 挂起流程实例
*
* @param id 流程实例id
*/
public void suspend(String id) {
runtimeService.suspendProcessInstanceById(id);
}
/**
* 激活流程实例
*
* @param id 流程实例id
*/
public void resume(String id) {
runtimeService.activateProcessInstanceById(id);
}
/**
* 结束流程实例审批失败
*
* @param id 流程实例id
* @param reason 失败原因
*/
public void failEndById(String id, String reason) {
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(id).singleResult();
if (processInstance != null) {
// 审批失败,状态为 INTERNALLY_TERMINATED
runtimeService.deleteProcessInstance(processInstance.getId(), reason);
}
}
/**
* 取消流程实例
*
* @param id 流程实例id
*/
public void cancelById(String id) {
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(id).singleResult();
if (processInstance != null) {
// 手动取消,状态为 EXTERNALLY_TERMINATED
runtimeService.deleteProcessInstance(processInstance.getId(), "手动取消");
}
}
/**
* 获取流程变量
*
* @param id 流程实例id
* @return 流程变量map
*/
public Map<String, Object> getVariables(String id) {
return runtimeService.getVariables(id);
}
}

@ -0,0 +1,124 @@
package com.zilber.boot.activiti.service;
import com.zilber.boot.activiti.dto.TaskCompleteDTO;
import com.zilber.boot.activiti.dto.TaskQueryDTO;
import com.zilber.boot.activiti.vo.TaskVO;
import com.zilber.boot.exception.ServiceException;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service(value = "TaskService_")
public class TaskService {
@Resource
private org.activiti.engine.TaskService taskService;
@Resource
private InstanceService instanceService;
public List<TaskVO> taskPage(TaskQueryDTO dto) {
TaskQuery taskQuery = taskService.createTaskQuery()
.active()
.orderByTaskCreateTime()
.desc();
if (!StringUtils.isEmpty(dto.getAssignee())) {
taskQuery.taskAssignee(dto.getAssignee());
}
if (!StringUtils.isEmpty(dto.getProcDefKey())) {
taskQuery.processDefinitionKey(dto.getProcDefKey());
}
if (!StringUtils.isEmpty(dto.getProcInstId())) {
taskQuery.processInstanceId(dto.getProcInstId());
}
List<Task> tasks = taskQuery.listPage(dto.getPageNo() * dto.getPageSize(), dto.getPageSize());
return TaskVO.merge(tasks);
}
public void complete(String userCode, String taskId, TaskCompleteDTO dto) {
Task task = taskService.createTaskQuery()
.taskAssignee(userCode)
.taskId(taskId)
.singleResult();
if (task == null) {
throw new ServiceException("没有任务");
}
if (task.getAssignee() == null) {
taskService.claim(taskId, userCode);
}
if (!StringUtils.isEmpty(dto.getRemark())) {
//taskService.createComment(taskId, task.getProcessInstanceId(), dto.getRemark());
taskService.addComment(taskId, task.getProcessInstanceId(), dto.getRemark());
}
Map<String, Object> variables = dto.getVariables();
if (dto.getVariables() == null) {
variables = new HashMap<>();
}
if (dto.getStatus() == 0) {
// TODO: 多实例并行任务,需要按照业务处理,是否一个人审批不通过,就都不通过
taskService.setVariable(taskId, "status", 0);
instanceService.failEndById(task.getProcessInstanceId(), dto.getRemark());
} else {
variables.put("status", dto.getStatus());
taskService.complete(taskId, variables);
}
}
/*public List<io.izn.iec.camunda.vo.SimpleTaskVO> getSimpleTasks(List<Integer> businessIds, DefinitionKey definitionKey) {
String sql = "SELECT\n" +
" t2.ID_ as taskId,\n" +
" t2.NAME_ as taskName,\n" +
" t2.DESCRIPTION_ as taskDescription,\n" +
" t2.TASK_DEF_KEY_ as taskDefinitionKey,\n" +
" t2.ASSIGNEE_ as assignee,\n" +
" t2.CREATE_TIME_ as taskTime,\n" +
" t2.PRIORITY_ as priority,\n" +
" t2.SUSPENSION_STATE_ as suspensionState,\n" +
" t1.business_id as businessId\n" +
"FROM bpm_business as t1\n" +
" LEFT JOIN ACT_RU_TASK as t2 on t1.proc_inst_id = t2.PROC_INST_ID_\n" +
"WHERE t1.business_id in (?1) and t1.proc_def_key = ?2";
Query nativeQuery = entityManager.createNativeQuery(sql);
nativeQuery.setParameter(1, businessIds);
nativeQuery.setParameter(2, definitionKey.getValue());
return nativeQuery
.unwrap(NativeQueryImpl.class)
.setResultTransformer(Transformers.aliasToBean(io.izn.iec.camunda.vo.SimpleTaskVO.class))
.list();
}
public List<io.izn.iec.camunda.vo.SimpleTaskVO> getSimpleTasks(List<Integer> businessIds, List<DefinitionKey> definitionKey) {
List<String> collect = definitionKey.stream().map(DefinitionKey::getValue).collect(Collectors.toList());
String sql = "SELECT\n" +
" t2.ID_ as taskId,\n" +
" t2.NAME_ as taskName,\n" +
" t2.DESCRIPTION_ as taskDescription,\n" +
" t2.TASK_DEF_KEY_ as taskDefinitionKey,\n" +
" t2.ASSIGNEE_ as assignee,\n" +
" t2.CREATE_TIME_ as taskTime,\n" +
" t2.PRIORITY_ as priority,\n" +
" t2.SUSPENSION_STATE_ as suspensionState,\n" +
" t1.business_id as businessId\n" +
"FROM bpm_business as t1\n" +
" LEFT JOIN ACT_RU_TASK as t2 on t1.proc_inst_id = t2.PROC_INST_ID_\n" +
"WHERE t1.business_id in (?1) and t1.proc_def_key in (?2)";
Query nativeQuery = entityManager.createNativeQuery(sql);
nativeQuery.setParameter(1, businessIds);
nativeQuery.setParameter(2, collect);
return nativeQuery
.unwrap(NativeQueryImpl.class)
.setResultTransformer(Transformers.aliasToBean(io.izn.iec.camunda.vo.SimpleTaskVO.class))
.list();
}*/
}

@ -0,0 +1,34 @@
package com.zilber.boot.activiti.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@ApiModel("流程定义")
public class DefinitionVO {
@ApiModelProperty("流程定义ID")
private String id;
@ApiModelProperty("流程定义名称")
private String name;
@ApiModelProperty("流程定义描述")
private String description;
@ApiModelProperty("流程定义Key")
private String key;
@ApiModelProperty("流程定义资源名称")
private String resourceName;
@ApiModelProperty("流程部署ID")
private String deploymentId;
@ApiModelProperty("版本号")
private Integer version;
}

@ -0,0 +1,74 @@
package com.zilber.boot.activiti.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.activiti.engine.history.HistoricTaskInstance;
import org.springframework.beans.BeanUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Getter
@Setter
@ApiModel("历史任务")
public class HistoricTaskVO {
@ApiModelProperty("任务ID")
private String taskId;
@ApiModelProperty("任务名称")
private String taskName;
@ApiModelProperty("任务描述")
private String taskDescription;
@ApiModelProperty("任务定义Key")
private String taskDefinitionKey;
@ApiModelProperty("执行人")
private String assignee;
@ApiModelProperty("任务开始时间")
private Date startTime;
@ApiModelProperty("任务结束时间")
private Date endTime;
@ApiModelProperty("任务优先级")
private Integer priority;
@ApiModelProperty("任务执行时长")
private Long duration;
@ApiModelProperty("任务删除原因")
private String deleteReason;
public static List<HistoricTaskVO> merge(List<HistoricTaskInstance> tasks) {
return tasks.stream()
.map(HistoricTaskVO::merge)
.collect(Collectors.toList());
}
public static HistoricTaskVO merge(HistoricTaskInstance task) {
HistoricTaskVO vo = new HistoricTaskVO();
vo.setTaskId(task.getId());
vo.setTaskName(task.getName());
vo.setTaskDescription(task.getDescription());
vo.setTaskDefinitionKey(task.getTaskDefinitionKey());
vo.setAssignee(task.getAssignee());
vo.setStartTime(task.getStartTime());
vo.setEndTime(task.getEndTime());
vo.setPriority(task.getPriority());
vo.setDuration(task.getDurationInMillis());
vo.setDeleteReason(task.getDeleteReason());
return vo;
}
}

@ -0,0 +1,54 @@
package com.zilber.boot.activiti.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Date;
@Getter
@Setter
@ApiModel("审批进度")
public class InstanceProgressVO implements Serializable {
@ApiModelProperty("活动ID")
private String actId;
@ApiModelProperty("任务ID")
private String taskId;
@ApiModelProperty("活动名称")
private String actName;
// 'userTask', 'startEvent', 'noneEndEvent'
@ApiModelProperty("活动类型")
private String actType;
@ApiModelProperty("流程实例ID")
private String procInstId;
@ApiModelProperty("任务执行时长")
private BigInteger duration;
// ActivityInstanceState
@ApiModelProperty("活动状态:0-default 1-scopeComplete 2-canceled 3-starting 4-ending")
private Integer state;
@ApiModelProperty("开始时间")
private Date startTime;
@ApiModelProperty("结束时间")
private Date endTime;
@ApiModelProperty("执行人")
private String assignee;
@ApiModelProperty("审批意见")
private String remark;
@ApiModelProperty("额外操作项")
private String operators;
}

@ -0,0 +1,48 @@
package com.zilber.boot.activiti.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.activiti.engine.runtime.ProcessInstance;
import java.util.List;
import java.util.stream.Collectors;
@Getter
@Setter
@ApiModel("流程实例")
public class InstanceVO {
@ApiModelProperty("是否挂起:1-正常 2-挂起")
private Integer suspensionState;
@ApiModelProperty("流程定义Key")
private String procDefKey;
@ApiModelProperty("流程定义ID")
private String procDefId;
@ApiModelProperty("流程实例ID")
private String procInstId;
@ApiModelProperty("备注")
private String remark;
@ApiModelProperty("发起人")
private String createBy;
public static List<InstanceVO> merge(List<ProcessInstance> instances) {
return instances.stream().map(instance -> {
InstanceVO vo = new InstanceVO();
vo.setSuspensionState(instance.isSuspended() ? 2 : 1);
vo.setProcDefKey(instance.getProcessDefinitionKey());
vo.setProcDefId(instance.getProcessDefinitionId());
vo.setProcInstId(instance.getProcessInstanceId());
vo.setCreateBy(instance.getStartUserId());
return vo;
}).collect(Collectors.toList());
}
}

@ -0,0 +1,43 @@
package com.zilber.boot.activiti.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.util.Date;
@Getter
@Setter
@ApiModel("流程任务(简单数据结构)")
public class SimpleTaskVO implements Serializable {
@ApiModelProperty("任务ID")
private String taskId;
@ApiModelProperty("任务名称")
private String taskName;
@ApiModelProperty("任务描述")
private String taskDescription;
@ApiModelProperty("任务定义Key")
private String taskDefinitionKey;
@ApiModelProperty("执行人")
private String assignee;
@ApiModelProperty("任务开始时间")
private Date taskTime;
@ApiModelProperty("任务优先级")
private Integer priority;
@ApiModelProperty("是否为挂起状态:1-否 2-是")
private Integer suspensionState;
@ApiModelProperty("业务ID")
private Integer businessId;
}

@ -0,0 +1,62 @@
package com.zilber.boot.activiti.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Getter
@Setter
@ApiModel("流程任务")
public class TaskVO {
@ApiModelProperty("任务ID")
private String taskId;
@ApiModelProperty("任务名称")
private String taskName;
@ApiModelProperty("任务描述")
private String taskDescription;
@ApiModelProperty("任务定义Key")
private String taskDefinitionKey;
@ApiModelProperty("执行人")
private String assignee;
@ApiModelProperty("任务开始时间")
private Date taskTime;
@ApiModelProperty("任务优先级")
private Integer priority;
@ApiModelProperty("是否为挂起状态:1-否 2-是")
private Integer suspensionState;
public static List<TaskVO> merge(List<Task> tasks) {
return tasks.stream().map(task -> {
TaskVO vo = new TaskVO();
vo.setTaskId(task.getId());
vo.setTaskName(task.getName());
vo.setTaskDescription(task.getDescription());
vo.setTaskDefinitionKey(task.getTaskDefinitionKey());
vo.setAssignee(task.getAssignee());
vo.setTaskTime(task.getCreateTime());
vo.setPriority(task.getPriority());
vo.setSuspensionState(task.isSuspended() ? 2 : 1);
return vo;
}).collect(Collectors.toList());
}
}

@ -30,15 +30,15 @@ import java.util.List;
*
* @author lsc
*/
@Configuration
//@Configuration
public class MyBatisConfig
{
@Autowired
private Environment env;
/* @Autowired
private Environment env;*/
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
public static String setTypeAliasesPackage(String typeAliasesPackage)
/* public static String setTypeAliasesPackage(String typeAliasesPackage)
{
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
@ -129,5 +129,5 @@ public class MyBatisConfig
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject();
}
}*/
}

@ -0,0 +1,57 @@
package com.zilber.boot.framework.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor()
{
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(paginationInnerInterceptor());
// 乐观锁插件
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
// 阻断插件
interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
return interceptor;
}
/**
* 分页插件自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
*/
public PaginationInnerInterceptor paginationInnerInterceptor()
{
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
// 设置数据库类型为mysql
paginationInnerInterceptor.setDbType(DbType.MYSQL);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInnerInterceptor.setMaxLimit(-1L);
return paginationInnerInterceptor;
}
/**
* 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
*/
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor()
{
return new OptimisticLockerInnerInterceptor();
}
/**
* 如果是对全表的删除或更新操作就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
*/
public BlockAttackInnerInterceptor blockAttackInnerInterceptor()
{
return new BlockAttackInnerInterceptor();
}
}

@ -112,7 +112,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
.antMatchers("/login", "/register", "/captchaImage").anonymous()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js","/**/*.jpg","/**/*.png","/zilbervue/admin/", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html","/swagger-ui", "/v3","/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
.antMatchers("/bpmn/**","/swagger-ui.html","/swagger-ui", "/v3","/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and()

@ -6,9 +6,9 @@ spring:
druid:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/zilberboot?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://39.100.74.100:3306/zilberboot?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
password: root@123456
# 从库数据源
slave:
# 从数据源开关/默认关闭

@ -68,13 +68,13 @@ spring:
# redis 配置
redis:
# 地址
host: localhost
host: 39.100.74.100
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 密码
password:
password: redis@ly1234
# 连接超时时间
timeout: 10s
lettuce:
@ -87,6 +87,11 @@ spring:
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
activiti:
history-level: full
db-history-used: true
check-process-definitions: false
deployment-mode: never-fail
# token配置
token:
@ -98,7 +103,7 @@ token:
expireTime: 30
# MyBatis配置
mybatis:
mybatis-plus:
# 搜索指定包别名
typeAliasesPackage: com.zilber.boot.**.pojo
# 配置mapper的扫描,找到所有的mapper.xml映射文件

@ -1,24 +0,0 @@
Application Version: ${zilberboot.version}
Spring Boot Version: ${spring-boot.version}
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////

@ -0,0 +1,170 @@
<?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/processdef">
<process id="daily" name="daily" isExecutable="true">
<extensionElements>
<activiti:executionListener class="com.zilber.boot.activiti.listen.ApplyListener" event="start" />
<activiti:executionListener class="com.zilber.boot.activiti.listen.ApplyListener" event="end" />
</extensionElements>
<startEvent id="Event_0w0afi8" name="开始">
<outgoing>Flow_1jlgqlw</outgoing>
</startEvent>
<sequenceFlow id="Flow_1jlgqlw" sourceRef="Event_0w0afi8" targetRef="Activity_144t788" />
<userTask id="Activity_144t788" name="请假申请" activiti:assignee="${ower}">
<extensionElements>
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="complete" />
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="create" />
</extensionElements>
<incoming>Flow_1jlgqlw</incoming>
<outgoing>Flow_0ul7x96</outgoing>
</userTask>
<exclusiveGateway id="Gateway_0de3wfg">
<incoming>Flow_0ul7x96</incoming>
<outgoing>Flow_0v4r83w</outgoing>
<outgoing>Flow_1gr0gbv</outgoing>
</exclusiveGateway>
<sequenceFlow id="Flow_0ul7x96" sourceRef="Activity_144t788" targetRef="Gateway_0de3wfg" />
<sequenceFlow id="Flow_0v4r83w" sourceRef="Gateway_0de3wfg" targetRef="Activity_1p56jq4">
<conditionExpression xsi:type="tFormalExpression">${day&gt;3}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_1gr0gbv" sourceRef="Gateway_0de3wfg" targetRef="Activity_1ygbeoa">
<conditionExpression xsi:type="tFormalExpression">${day&lt;=3}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_0kudbee" sourceRef="Activity_1ygbeoa" targetRef="Activity_13m5c8m">
<conditionExpression xsi:type="tFormalExpression">${status== 1}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_09xp52x" sourceRef="Activity_1p56jq4" targetRef="Activity_13m5c8m">
<conditionExpression xsi:type="tFormalExpression">${status==1}</conditionExpression>
</sequenceFlow>
<endEvent id="Event_16bkb2x" name="结束">
<incoming>Flow_0f94ru3</incoming>
</endEvent>
<sequenceFlow id="Flow_0f94ru3" sourceRef="Activity_13m5c8m" targetRef="Event_16bkb2x" />
<endEvent id="Event_1bn5u87" name="结束">
<incoming>Flow_1s5r7c7</incoming>
</endEvent>
<sequenceFlow id="Flow_1s5r7c7" sourceRef="Activity_1ygbeoa" targetRef="Event_1bn5u87">
<conditionExpression xsi:type="tFormalExpression">${status==0}</conditionExpression>
</sequenceFlow>
<endEvent id="Event_04eisc3" name="结束">
<incoming>Flow_0vre5aw</incoming>
</endEvent>
<sequenceFlow id="Flow_0vre5aw" sourceRef="Activity_1p56jq4" targetRef="Event_04eisc3">
<conditionExpression xsi:type="tFormalExpression">${status==0}</conditionExpression>
</sequenceFlow>
<userTask id="Activity_1ygbeoa" name="人事审批" activiti:assignee="${hr}">
<extensionElements>
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="complete" />
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="create" />
</extensionElements>
<incoming>Flow_1gr0gbv</incoming>
<outgoing>Flow_0kudbee</outgoing>
<outgoing>Flow_1s5r7c7</outgoing>
</userTask>
<userTask id="Activity_1p56jq4" name="经理审批" activiti:assignee="${manger}">
<extensionElements>
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="complete" />
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="create" />
</extensionElements>
<incoming>Flow_0v4r83w</incoming>
<outgoing>Flow_09xp52x</outgoing>
<outgoing>Flow_0vre5aw</outgoing>
</userTask>
<userTask id="Activity_13m5c8m" name="总经理审批" activiti:assignee="${ceo}">
<extensionElements>
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="create" />
<activiti:taskListener class="com.zilber.boot.activiti.listen.ApplyTaskListener" event="complete" />
</extensionElements>
<incoming>Flow_0kudbee</incoming>
<incoming>Flow_09xp52x</incoming>
<outgoing>Flow_0f94ru3</outgoing>
</userTask>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_daily">
<bpmndi:BPMNPlane id="BPMNPlane_daily" bpmnElement="daily">
<bpmndi:BPMNShape id="Event_0w0afi8_di" bpmnElement="Event_0w0afi8">
<omgdc:Bounds x="442" y="102" width="36" height="36" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="449" y="78" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0atbqot_di" bpmnElement="Activity_144t788">
<omgdc:Bounds x="410" y="180" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Gateway_0de3wfg_di" bpmnElement="Gateway_0de3wfg" isMarkerVisible="true">
<omgdc:Bounds x="435" y="315" width="50" height="50" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_16bkb2x_di" bpmnElement="Event_16bkb2x">
<omgdc:Bounds x="442" y="752" width="36" height="36" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="449" y="795" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1bn5u87_di" bpmnElement="Event_1bn5u87">
<omgdc:Bounds x="152" y="472" width="36" height="36" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="159" y="515" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_04eisc3_di" bpmnElement="Event_04eisc3">
<omgdc:Bounds x="752" y="472" width="36" height="36" />
<bpmndi:BPMNLabel>
<omgdc:Bounds x="759" y="515" width="22" height="14" />
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1ceyxkn_di" bpmnElement="Activity_1ygbeoa">
<omgdc:Bounds x="270" y="450" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_16971ee_di" bpmnElement="Activity_1p56jq4">
<omgdc:Bounds x="580" y="450" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1cupe7b_di" bpmnElement="Activity_13m5c8m">
<omgdc:Bounds x="410" y="560" width="100" height="80" />
<bpmndi:BPMNLabel />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1jlgqlw_di" bpmnElement="Flow_1jlgqlw">
<omgdi:waypoint x="460" y="138" />
<omgdi:waypoint x="460" y="180" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0ul7x96_di" bpmnElement="Flow_0ul7x96">
<omgdi:waypoint x="460" y="260" />
<omgdi:waypoint x="460" y="315" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0v4r83w_di" bpmnElement="Flow_0v4r83w">
<omgdi:waypoint x="460" y="365" />
<omgdi:waypoint x="460" y="390" />
<omgdi:waypoint x="630" y="390" />
<omgdi:waypoint x="630" y="450" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1gr0gbv_di" bpmnElement="Flow_1gr0gbv">
<omgdi:waypoint x="460" y="365" />
<omgdi:waypoint x="460" y="390" />
<omgdi:waypoint x="320" y="390" />
<omgdi:waypoint x="320" y="450" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0kudbee_di" bpmnElement="Flow_0kudbee">
<omgdi:waypoint x="320" y="530" />
<omgdi:waypoint x="320" y="600" />
<omgdi:waypoint x="410" y="600" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_09xp52x_di" bpmnElement="Flow_09xp52x">
<omgdi:waypoint x="630" y="530" />
<omgdi:waypoint x="630" y="600" />
<omgdi:waypoint x="510" y="600" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0f94ru3_di" bpmnElement="Flow_0f94ru3">
<omgdi:waypoint x="460" y="640" />
<omgdi:waypoint x="460" y="752" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1s5r7c7_di" bpmnElement="Flow_1s5r7c7">
<omgdi:waypoint x="270" y="490" />
<omgdi:waypoint x="188" y="490" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0vre5aw_di" bpmnElement="Flow_0vre5aw">
<omgdi:waypoint x="680" y="490" />
<omgdi:waypoint x="752" y="490" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

@ -0,0 +1,40 @@
<?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:camunda="http://camunda.org/schema/1.0/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/processdef">
<process id="leave" name="请假流程申请" isExecutable="true">
<startEvent id="sid-6917af13-104c-4397-bc24-41be0852b5b0"/>
<userTask id="sid-21d6407f-8525-4d7c-83f9-b74583e82d17" name="创建申请" camunda:assignee="${assignee0}"/>
<userTask id="sid-ae1aab6d-f664-4972-836b-e9dca7f27a7d" name="申请审批" camunda:assignee="${assignee1}"/>
<endEvent id="sid-9240f252-fad0-4602-a421-81f3be7a4fab"/>
<sequenceFlow id="sid-d58f155a-9628-4f66-bca4-258850dde7ba" sourceRef="sid-6917af13-104c-4397-bc24-41be0852b5b0" targetRef="sid-21d6407f-8525-4d7c-83f9-b74583e82d17"/>
<sequenceFlow id="sid-59fc43aa-9454-4f21-93af-3d8662aa2b69" sourceRef="sid-21d6407f-8525-4d7c-83f9-b74583e82d17" targetRef="sid-ae1aab6d-f664-4972-836b-e9dca7f27a7d"/>
<sequenceFlow id="sid-79fbf181-c4b6-4e1e-a91d-46807ce280b6" sourceRef="sid-ae1aab6d-f664-4972-836b-e9dca7f27a7d" targetRef="sid-9240f252-fad0-4602-a421-81f3be7a4fab"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_leave">
<bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave">
<bpmndi:BPMNShape id="shape-b91f6a90-4767-4a01-821a-3dc8585bfc17" bpmnElement="sid-6917af13-104c-4397-bc24-41be0852b5b0">
<omgdc:Bounds x="140.0" y="-125.0" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-6c1a4a42-3efd-43ed-a244-dde11e4b9779" bpmnElement="sid-21d6407f-8525-4d7c-83f9-b74583e82d17">
<omgdc:Bounds x="110.0" y="-60.0" width="95.0" height="60.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-10fd4ccb-b8db-4b5b-9fab-3b1fc85d0f53" bpmnElement="sid-ae1aab6d-f664-4972-836b-e9dca7f27a7d">
<omgdc:Bounds x="107.5" y="45.0" width="100.0" height="60.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-97a99905-c6c6-4ba6-a327-8c29b56002d8" bpmnElement="sid-9240f252-fad0-4602-a421-81f3be7a4fab">
<omgdc:Bounds x="150.0" y="195.0" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-8eaecd6b-2a86-4aa0-8646-d07f9ab6ba1e" bpmnElement="sid-d58f155a-9628-4f66-bca4-258850dde7ba">
<omgdi:waypoint x="155.00002" y="-95.00001"/>
<omgdi:waypoint x="157.5" y="-60.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-34937420-c07a-4415-a0e7-56744488092f" bpmnElement="sid-59fc43aa-9454-4f21-93af-3d8662aa2b69">
<omgdi:waypoint x="157.5" y="0.0"/>
<omgdi:waypoint x="157.5" y="45.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-0a5523af-0f81-4d43-9c5e-f7f6c71ae866" bpmnElement="sid-79fbf181-c4b6-4e1e-a91d-46807ce280b6">
<omgdi:waypoint x="157.5" y="105.0"/>
<omgdi:waypoint x="165.0" y="195.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
Loading…
Cancel
Save