Browse Source

flowable后端

master
yxt_djz 2 years ago
parent
commit
ab17b1339f
  1. 44
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/CodeMsgEnum.java
  2. 27
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/FlowableApplication.java
  3. 18
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableMapper.java
  4. 63
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableMapper.xml
  5. 447
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableRest.java
  6. 276
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableService.java
  7. 143
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowdefinition/FlowDefinitionRest.java
  8. 273
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowdefinition/FlowDefinitionService.java
  9. 71
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowinstance/FlowInstanceRest.java
  10. 106
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowinstance/FlowInstanceService.java
  11. 331
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskController.java
  12. 46
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskMapper.java
  13. 236
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskMapper.xml
  14. 2079
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskService.java
  15. 47
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/process/ExpressionCmd.java
  16. 162
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/process/ProcessService.java
  17. 72
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentMapper.java
  18. 20
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentMapper.xml
  19. 105
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentRest.java
  20. 135
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentService.java
  21. 364
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/service/impl/FlowTaskServiceImpl.java
  22. 74
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysdeployform/SysDeployFormMapper.java
  23. 66
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysdeployform/SysDeployFormMapper.xml
  24. 94
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysdeployform/SysDeployFormService.java
  25. 108
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormController.java
  26. 77
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormMapper.java
  27. 34
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormMapper.xml
  28. 130
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormService.java
  29. 37
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkMapper.java
  30. 16
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkMapper.xml
  31. 59
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkRest.java
  32. 80
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkService.java
  33. 128
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlController.java
  34. 93
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlMapper.java
  35. 135
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlMapper.xml
  36. 206
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlService.java
  37. 65
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/systaskform/SysTaskFormMapper.java
  38. 61
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/systaskform/SysTaskFormMapper.xml
  39. 62
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/common/EnumResultBean.java
  40. 73
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/common/ProcessConstants.java
  41. 342
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/DefaultProcessDiagramCanvasExt.java
  42. 397
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/DefaultProcessDiagramGeneratorExt.java
  43. 47
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/DiRemoteAccountResource.java
  44. 22
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/FlowableConfig.java
  45. 25
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/P6spySqlFormatConfig.java
  46. 212
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/ProcessEngineConfig.java
  47. 36
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/Swagger2Config.java
  48. 41
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/factory/FlowServiceFactory.java
  49. 23
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/listener/BaseVehicleExecutionListener.java
  50. 21
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/listener/ManagerEndExecutionListener.java
  51. 101
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/listener/ManagerTaskListener.java
  52. 53
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/controller/HolidayTestController.java
  53. 41
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/controller/TestController.java
  54. 39
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/service/IHolidayTestService.java
  55. 149
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/service/impl/HolidayTestService.java
  56. 620
      yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/utils/FlowableUtils.java

44
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/CodeMsgEnum.java

@ -0,0 +1,44 @@
package com.yxt.anrui.flowable;
import com.yxt.common.core.result.IResultCodeMsg;
/**
* 统一返回信息的code和msg需要更新并安装yxt-common-core项目
*/
public enum CodeMsgEnum implements IResultCodeMsg {
/**
* 返回正常
*/
HTML200("200", "返回正常"),
/**
* 页面不存在
*/
HTML404("404", "页面不存在"),
/**
* 服务器错误
*/
HTML500("500", "服务器错误"),
/**
* 用户名不存在
*/
AF_U_5001("af_u_5001", "用户名不存在");
private String code;
private String msg;
private CodeMsgEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public String getMsg() {
return msg;
}
@Override
public String getCode() {
return code;
}
}

27
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/FlowableApplication.java

@ -0,0 +1,27 @@
package com.yxt.anrui.flowable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author dimengzhe
*/
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
//如果自定义了安全配置,请检查是否需要排除下面ManagementWebSecurityAutoConfiguration配置
//org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration.class
}, scanBasePackages = {
"com.yxt.common.base.config",
"org.flowable.ui.modeler", "org.flowable.ui.common","com.yxt.anrui.flowable.*"
})
@EnableDiscoveryClient
@EnableFeignClients(basePackages = {"com.yxt.anrui.*","com.yxt.supervise.*"})
public class FlowableApplication {
public static void main(String[] args) {
SpringApplication.run(FlowableApplication.class, args);
}
}

18
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableMapper.java

@ -0,0 +1,18 @@
package com.yxt.anrui.flowable.biz.flow;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.flow.FlowProcinst;
import com.yxt.anrui.flowable.api.flow.Flowable;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Map;
@Mapper
public interface FlowableMapper extends BaseMapper<Flowable> {
void insetFlowableTask(Map<String,Object> params);
FlowProcinst getFlowProcinstById(@Param("id") String id);
@Select("select * from act_hi_procinst where proc_inst_id_=#{id}")
Map<String, String> getProcessInstanceById(@Param("id") String procInsId);
}

63
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableMapper.xml

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.flow.FlowableMapper">
<insert id="insetFlowableTask" parameterType="com.yxt.anrui.flowable.api.flow.Flowable">
insert into `act_ru_task` ( `days`, `zd`,initiator,outcome)
VALUES
(
#{days,jdbcType=VARCHAR},
#{zd,jdbcType=VARCHAR}
#{initiator,jdbcType=VARCHAR}
#{outcome,jdbcType=VARCHAR}
)
</insert>
<select id="getFlowProcinstById" resultType="com.yxt.anrui.flowable.api.flow.FlowProcinst">
select * from act_hi_procinst where ID_=#{id}
</select>
<!--
<insert id="insetFlowableTask">
insert into `act_ru_task` (`REV`, `EXECUTION_ID`, `PROC_INST_ID`, `PROC_DEF_ID`,
`TASK_DEF_ID`, `SCOPE_ID`, `SUB_SCOPE_ID`, `SCOPE_TYPE`, `SCOPE_DEFINITION_ID`,
`PROPAGATED_STAGE_INST_ID`, `NAME`, `PARENT_TASK_ID`, `DESCRIPTION`,
`TASK_DEF_KEY`, `OWNER`, `ASSIGNEE`, `DELEGATION`, `PRIORITY`,
`CREATE_TIME`, `DUE_DATE`, `CATEGORY`, `SUSPENSION_STATE`, `TENANT_ID`,
`FORM_KEY`, `CLAIM_TIME`, `IS_COUNT_ENABLED`, `VAR_COUNT`, `ID_LINK_COUNT`,
`SUB_TASK_COUNT`, `days`, `reason`)
VALUES
(
#{item.modelSid,jdbcType=VARCHAR},&lt;!&ndash;sid&ndash;&gt;
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR},
#{item.modelSid,jdbcType=VARCHAR}
)
</insert>
-->
</mapper>

447
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableRest.java

@ -0,0 +1,447 @@
/*********************************************************
*********************************************************
******************** *******************
************* ************
******* _oo0oo_ *******
*** o8888888o ***
* 88" . "88 *
* (| -_- |) *
* 0\ = /0 *
* ___/`---'\___ *
* .' \\| |// '. *
* / \\||| : |||// \ *
* / _||||| -:- |||||- \ *
* | | \\\ - /// | | *
* | \_| ''\---/'' |_/ | *
* \ .-\__ '-' ___/-. / *
* ___'. .' /--.--\ `. .'___ *
* ."" '< `.___\_<|>_/___.' >' "". *
* | | : `- \`.;`\ _ /`;.`/ - ` : | | *
* \ \ `_. \_ __\ /__ _/ .-` / / *
* =====`-.____`.___ \_____/___.-`___.-'===== *
* `=---=' *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
*********__佛祖保佑__永无BUG__验收通过__钞票多多__*********
*********************************************************/
package com.yxt.anrui.flowable.biz.flow;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yxt.anrui.flowable.api.flow.*;
import com.yxt.anrui.flowable.api.flowcomment.FlowComment;
import com.yxt.anrui.flowable.api.flowtask.LatestTaskVo;
import com.yxt.anrui.flowable.biz.flowtask.FlowTaskService;
import com.yxt.anrui.flowable.biz.process.ProcessService;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables;
import com.yxt.common.base.utils.StringUtils;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import com.yxt.supervise.system.sysuser.SysUserFeign;
import com.yxt.supervise.system.sysuser.SysUserVo;
import com.yxt.supervise.system.sysuser.UserQuery;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.TaskService;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.*;
/**
* Project: anrui-parent <br/>
* File: FlowableRest.java <br/>
* Class: com.yxt.anrui.portal.biz.flow.FlowableRest <br/>
* Description: <描述类的功能>. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2021/10/23 上午11:13 <br/>
*
* @author popo
* @version 1.0
* @since 1.0
*/
@RestController
@RequestMapping("v1/flow")
@Api(tags = "业务系统中业务和工作流相关操作")
public class FlowableRest implements FlowableFeign {
@Autowired
private FlowableService flowableService;
@Autowired
private FlowTaskService flowtaskService;
@Autowired
private SysUserFeign sysUserFeign;
@Resource
protected TaskService taskService;
@Resource
private ProcessService processService;
@Override
public ResultBean businessStart(BusinessVariables bv) {
return flowableService.businessStart( bv);
}
@Override
public ResultBean processPagerList(@ApiParam(value = "当前页码", required = true) @RequestParam("pageNum") Integer pageNum,
@ApiParam(value = "每页条数", required = true) @RequestParam("pageSize") Integer pageSize) {
return flowableService.processPagerList(pageNum, pageSize);
}
@Override
public ResultBean myprocess(@ApiParam(value = "用户sid") @PathVariable(value = "userSid") String userSid,
@ApiParam(value = "变量集合,json对象") @RequestBody PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
return flowableService.myprocess(userSid, taskQueryPagerQuery);
}
@Override
public ResultBean stopProcess(FlowTaskVo flowTaskVo) {
flowableService.stopProcess(flowTaskVo);
return ResultBean.fireSuccess();
}
@Override
public ResultBean deleteProcess(String procInsId) {
flowableService.deleteProcess(procInsId);
return ResultBean.fireSuccess();
}
@Override
public ResultBean<UserAndOrgPath> getNextNodeUserSidsOfCreate(BusinessVariables bv) {
//根据业务参数取流程流转的环节 信息
return flowtaskService.getNextNodeUserSidsOfCreate(bv) ;
}
@Override
public ResultBean<UserAndOrgPath> getNextNodeUserSidsOfSubmit(BusinessVariables bv) {
ResultBean<UserAndOrgPath> rb = ResultBean.fireSuccess();
String orgSidPath=bv.getOrgSidPath();
String taskDefKey=bv.getTaskDefKey();
//根据业务参数取流程流转的环节 信息
List<Map<String, Object>> list = (List<Map<String, Object>>)
flowtaskService.getProcessCirculationNodesByMap(bv).getData();
Map<String, Object> task_map=new HashMap<>();
//取第二个环节的配置角色
boolean endTask=true;
for (int i=0;i< list.size();i++){
String id=list.get(i).get("id").toString();
if(id.equals(taskDefKey)&&i+1<list.size()){
task_map=list.get(i+1);
endTask=false;
}
}
if(endTask){
task_map.put("name","结束");
return rb.setData(new UserAndOrgPath());
}else{
Object o = task_map.get("candidateGroups");
return flowtaskService.getNextUserSids(rb, orgSidPath, o);
}
}
@Override
public ResultBean<UpdateFlowFieldVo> startProcess(BusinessVariables dto) {
log.info("startProcess.dto:{}",dto);
ResultBean rb = ResultBean.fireFail();
if (StringUtils.isBlank(dto.getBusinessSid())) {
return rb.setMsg("businessSid 不能为空!");
}
if(dto.getFormVariables()==null)
dto.setFormVariables(new HashMap<String, Object>());
Map<String, Object> formVariables = dto.getFormVariables();
if(StringUtils.isNotBlank(dto.getOrgSidPath())){
String orgPath=dto.getOrgSidPath();
formVariables.put("createrOrgPath",orgPath);//发起人的组织结构sid
//dto.setFormVariables(formVariables);
}
dto.getFormVariables().put("businessSid",dto.getBusinessSid());
String nextNodeUserSids_ = dto.getNextNodeUserSids();
if(StringUtils.isBlank(nextNodeUserSids_)){
ResultBean<UserAndOrgPath> nextNodeUserSidsOfCreate = getNextNodeUserSidsOfCreate(dto);
boolean success = nextNodeUserSidsOfCreate.getSuccess();
if(!success){
return rb.setMsg(nextNodeUserSidsOfCreate.getMsg());
}
nextNodeUserSids_=nextNodeUserSidsOfCreate.getData().getUserSid();
dto.getFormVariables().put(BusinessVariables.ORGPATH,nextNodeUserSidsOfCreate.getData().getOrgPath());
}
dto.setNextNodeUserSids(nextNodeUserSids_);
ResultBean resultBean1 = flowableService.businessStart(dto);
UpdateFlowFieldVo vo = new UpdateFlowFieldVo();
if (resultBean1.getSuccess() && resultBean1.getData() != null) {
vo.setSid("" + dto.getBusinessSid());
Map<String, String> map = (Map<String, String>) resultBean1.getData();
vo.setProcDefId(dto.getModelId());
vo.setNodeState(map.get("nodeState"));
vo.setProcInsId(map.get("procInsId"));
vo.setTaskDefKey(map.get("taskDefKey"));
vo.setTaskId(map.get("taskId"));
vo.setNextNodeUserSids(nextNodeUserSids_);
}
return rb.success().setData(vo);
}
Logger log= LoggerFactory.getLogger(FlowableRest.class);
@Override
public ResultBean<UpdateFlowFieldVo> handleProsess(BusinessVariables dto) {
return handleProsess(dto,true);
}
/**
*
* @param dto
* @param b 是否连续跳转环节
* @return
*/
public ResultBean<UpdateFlowFieldVo> handleProsess(BusinessVariables dto,boolean b) {
log.info("BusinessVariables:{}", JSONObject.toJSONString(dto));
log.info("b:{}", b);
UpdateFlowFieldVo vo = new UpdateFlowFieldVo();
ResultBean rb = ResultBean.fireFail();
// Map<String, Object> formVariables = dto.getFormVariables();
String taskId = dto.getTaskId();
if (StringUtils.isBlank(taskId)) {
return rb.setMsg("taskId 不能为空!");
}
if (StringUtils.isBlank(dto.getBusinessSid())) {
return rb.setMsg("businessSid 不能为空!");
}
/*if(formVariables==null){
return rb.setMsg("业务参数集合 不能为空!");
}*/
if(dto.getFormVariables()==null)
dto.setFormVariables(new HashMap<String, Object>());
Map<String, Object> formVariables = dto.getFormVariables();
formVariables.put("businessSid",dto.getBusinessSid());
String nextUserSid = dto.getNextNodeUserSids();
if(StringUtils.isBlank(nextUserSid)){
ResultBean<UserAndOrgPath> nextNodeUserSidsOfSubmit = getNextNodeUserSidsOfSubmit(dto);
if (!nextNodeUserSidsOfSubmit.getSuccess()) {
return rb.setMsg("nextUserSid 不能为空!");
}
nextUserSid=nextNodeUserSidsOfSubmit.getData().getUserSid();
formVariables.put(BusinessVariables.ORGPATH,nextNodeUserSidsOfSubmit.getData().getOrgPath());
}
String comment = dto.getComment();
if (StringUtils.isBlank(comment)) {
comment="";
//return rb.setMsg("comment 不能为空!");
}
String instanceId = dto.getInstanceId();
if (StringUtils.isBlank(instanceId)) {
return rb.setMsg("instanceId 不能为空!");
}
String userSid = dto.getUserSid();
if (StringUtils.isBlank(userSid)) {
return rb.setMsg("userSid 不能为空!");
}
String businessSid =dto.getBusinessSid();
if (StringUtils.isBlank(businessSid)) {
return rb.setMsg("业务sid 不能为空!");
}
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (Objects.isNull(task)) {
return rb.setMsg("任务不存在");
}
String assignee = task.getAssignee();
if(b&&(StringUtils.isNotBlank(assignee)&& assignee.indexOf(userSid)<0)){
return rb.setMsg("当前用户不是环节的待办人,不能进行办理操作!");
}
String nodeState = "";
String taskDefKey = "";
vo.setSid(businessSid);
if (DelegationState.PENDING.equals(task.getDelegationState())) {
taskService.addComment(taskId, instanceId,
FlowComment.DELEGATE.getType(), comment);
// Map<String,Object> values =(Map<String,Object>) formVariables.get("values");
taskService.resolveTask(taskId, formVariables);
} else {
taskService.addComment(taskId, instanceId, FlowComment.NORMAL.getType(), comment);
log.error("taskid:{},userSid:{}",taskId, userSid);
log.error("formVariables:{}",JSON.toJSONString(formVariables));
taskService.setAssignee(taskId, userSid);
//formVariables.remove("userSid");
/*for(Map.Entry<String, Object> entry:formVariables.entrySet()){
taskService.setVariable(taskId,entry.getKey(),entry.getValue());
System.out.println(entry.getKey()+"--->"+entry.getValue());
}*/
taskService.complete(taskId, formVariables);
//根据流程实例的id取最新的待办环节,给环节设置上用户sid
ResultBean<List<LatestTaskVo>> ll = flowtaskService.getLatestTasksNew(instanceId);
if (ll.getData().size() > 0) {
LatestTaskVo latestTaskVo = ll.getData().get(0);
String id_ = latestTaskVo.getId_();
taskService.setAssignee(id_, nextUserSid);
vo.setTaskId(id_);
/* for(Map.Entry<String, Object> entry:formVariables.entrySet()){
taskService.setVariable(id_,entry.getKey(),entry.getValue());
taskService.setVariableLocal(id_,entry.getKey(),entry.getValue());
System.out.println(entry.getKey()+"--->"+entry.getValue());
}*/
// taskService.setVariables(id_,formVariables);
//在act_ru_variable表中增加环节上的业务参数的变量
taskService.setVariablesLocal(id_,formVariables);
nodeState = latestTaskVo.getName_();
taskDefKey = latestTaskVo.getTask_def_key_();
} else {
nodeState = FlowComment.SETTLE.getRemark();
taskDefKey = "Event_end";
vo.setNodeState(FlowComment.SETTLE.getRemark());
}
}
//ResultBean<FlowRecordVo> flowRecordVoResultBean = flowableService.flowRecord(dto.getInstanceId(), dto.getModelId());
List<FlowElement> flowElements = processService.calApprovePath(dto.getModelId(), dto.getModelId(),
dto.getFormVariables());
boolean contains=false;
for(int i=0;i<flowElements.size();i++){
FlowElement flowElement = flowElements.get(i);
String id = flowElement.getId();
if(taskDefKey.equals(id)&&i+1<flowElements.size()){
FlowElement flowElement1 = flowElements.get(i + 1);
if(flowElement1 instanceof UserTask){
UserTask userTask=(UserTask)flowElement1;
List<String> candidateGroups = userTask.getCandidateGroups();
List<SysUserVo> sysUserVoLists=new ArrayList<>();
//根据角色查询用户
for(String roleSid:candidateGroups){
UserQuery userQuery = new UserQuery();
userQuery.setRoleSid(roleSid);
userQuery.setOrgSidPath(dto.getOrgSidPath());
ResultBean<List<SysUserVo>> userByRole = sysUserFeign.getUserByRole(userQuery);
boolean success = userByRole.getSuccess();
if(!success){
continue;
}
sysUserVoLists.addAll(userByRole.getData());
}
//当前环节运营部总经理 刘丽艳 点击同意 下一环节 事业部副总经理 (nextUserSid) 和事业部总经理(sysUserVoLists.get(0).getSid())
//判断查询回来的用户的集合size是1 并且用户的sid和下一环节的用户的sid相同。
if(sysUserVoLists.size()==1&&sysUserVoLists.get(0).getSid().equals(nextUserSid)){
contains=true;
break;
}
}
}
if(contains){
break;
}
}
if(contains){
dto.setUserSid(nextUserSid);
dto.setTaskId(vo.getTaskId());
dto.setTaskDefKey(taskDefKey);
return handleProsess(dto,false);
}
vo.setProcInsId(instanceId);
vo.setProcDefId(task.getProcessDefinitionId());
vo.setNodeState(nodeState);
vo.setTaskDefKey(taskDefKey);
vo.setNextNodeUserSids(nextUserSid);
return rb.success().setData(vo);
}
@Override
public ResultBean<UpdateFlowFieldVo> revokeProcess(com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl) {
ResultBean rb = ResultBean.fireFail();
if (StringUtils.isBlank(fl.getBusinessSid())) {
return rb.setMsg("businessSid 不能为空!");
}
if( fl.getValues()==null){
fl.setValues(new HashMap<String,Object>());
}
fl.getValues().put("businessSid",fl.getBusinessSid());
UpdateFlowFieldVo vo = new UpdateFlowFieldVo();
ResultBean<FlowProcinst> flowProcinstById = flowableService.getFlowProcinstById(fl.getInstanceId());
if(!StringUtils.isBlank(flowProcinstById.getData().getEND_TIME_())){
return rb.setMsg("撤回失败,流程已办结或终止");
}
ResultBean<List<LatestTaskVo>> resultBean = flowtaskService.revokeProcess(fl);
if (!resultBean.getSuccess()) {
return rb.setMsg(resultBean.getMsg());
}
String nodeState = resultBean.getData().get(0).getName_();
String taskDefKey = resultBean.getData().get(0).getTask_def_key_();
String incomingSourceRef = resultBean.getData().get(0).getIncomingSourceRef();
vo.setSid(fl.getBusinessSid());
vo.setTaskId(resultBean.getData().get(0).getId_());
if (incomingSourceRef.contains("start")) {
vo.setNodeState(nodeState);
vo.setTaskDefKey(taskDefKey);
} else {
vo.setNodeState( nodeState);
vo.setTaskDefKey( taskDefKey);
}
return rb.success().setData(vo);
}
@Override
public ResultBean<UpdateFlowFieldVo> taskReject(com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl) {
ResultBean rb = ResultBean.fireFail();
UpdateFlowFieldVo vo = new UpdateFlowFieldVo();
if (StringUtils.isBlank(fl.getBusinessSid())) {
return rb.setMsg("businessSid 不能为空!");
}
if( fl.getValues()==null){
fl.setValues(new HashMap<String,Object>());
}
fl.getValues().put("businessSid",fl.getBusinessSid());
ResultBean<List<LatestTaskVo>> resultBean = flowtaskService.taskReject(fl);
if (!resultBean.getSuccess()) {
return rb.setMsg(resultBean.getMsg());
}
String orgPath = resultBean.getData().get(0).getOrgPath();
String nodeState = resultBean.getData().get(0).getName_();
String taskDefKey = resultBean.getData().get(0).getTask_def_key_();
String incomingSourceRef = resultBean.getData().get(0).getIncomingSourceRef();
String taskId = resultBean.getData().get(0).getId_();
vo.setSid(fl.getBusinessSid());
vo.setNodeState( nodeState);
vo.setTaskDefKey( taskDefKey);
vo.setTaskId(taskId);
/* if (incomingSourceRef.contains("start")) {
vo.setNodeState( SysFormLinkFlowStateEnum.REJECT.getCode());
}*/
Map<String, Object> formVariables=new HashMap<>();
formVariables.put(BusinessVariables.ORGPATH,orgPath);
//在act_ru_variable表中增加环节上的业务参数的变量
taskService.setVariablesLocal(taskId,formVariables);
ResultBean resultBean1 = ResultBean.fireSuccess();
return resultBean1.success().setData(vo);
}
@Override
public ResultBean<UpdateFlowFieldVo> breakProcess(com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl) {
ResultBean<UpdateFlowFieldVo> rb = ResultBean.fireFail();
if (StringUtils.isBlank(fl.getBusinessSid())) {
return rb.setMsg("businessSid 不能为空!");
}
if( fl.getValues()==null){
fl.setValues(new HashMap<String,Object>());
}
fl.getValues().put("businessSid",fl.getBusinessSid());
UpdateFlowFieldVo vo = new UpdateFlowFieldVo();
ResultBean<UpdateFlowFieldVo> resultBean = flowableService.breakProcess(fl);
if (!resultBean.getSuccess()) {
return resultBean;
}
vo.setSid(fl.getBusinessSid());
vo.setNodeState(resultBean.getData().getNodeState());
vo.setTaskDefKey( "Event_end");
return rb.success().setData(vo);
}
}

276
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flow/FlowableService.java

@ -0,0 +1,276 @@
package com.yxt.anrui.flowable.biz.flow;
import cn.hutool.core.bean.BeanUtil;
import com.yxt.anrui.flowable.api.flow.*;
import com.yxt.anrui.flowable.api.flowtask.FlowTask;
import com.yxt.anrui.flowable.api.flowtask.FlowTaskVo;
import com.yxt.anrui.flowable.api.flowtask.LatestTaskVo;
import com.yxt.anrui.flowable.api.utils.ProcessStateEnum;
import com.yxt.anrui.flowable.biz.flowdefinition.FlowDefinitionService;
import com.yxt.anrui.flowable.biz.flowtask.FlowTaskService;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessTaskParam;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessTaskQuery;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables;
import com.yxt.anrui.flowable.sqloperationsymbol.SQLOperationSymbol;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.base.utils.StringUtils;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import org.flowable.engine.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class FlowableService extends MybatisBaseService<FlowableMapper, Flowable> {
@Autowired
private FlowDefinitionService flowDefinitionService;
@Autowired
private FlowTaskService flowTaskService;
@Autowired
private TaskService taskService;
public ResultBean<FlowProcinst> getFlowProcinstById(String id) {
ResultBean<FlowProcinst> rb = ResultBean.fireFail();
FlowProcinst fp=baseMapper.getFlowProcinstById(id);
if(fp==null){
return rb;
}
return rb.success().setData(fp);
}
public ResultBean businessStart(BusinessVariables bv) {
if (StringUtils.isBlank(bv.getBusinessSid())) {
return ResultBean.fireFail().setMsg("businessSid 不能为空!");
}
/*if(bv.getFormVariables()==null){
return ResultBean.fireFail().setMsg("业务参数集合 不能为空!");
}*/
if(bv.getFormVariables()==null)
bv.setFormVariables(new HashMap<String, Object>());
bv.getFormVariables().put("businessSid",bv.getBusinessSid());
ResultBean<FlowTask> rb = flowDefinitionService.businessStart(bv);
if (!rb.getSuccess()) {
return rb;
}
String procId = rb.getData().getProcInsId();
List<LatestTaskVo> list = flowTaskService.getLatestTasks(procId);
String nodeState = list.get(0).getName_();
String task_def_key_ = list.get(0).getTask_def_key_();
Map<String, String> map = new HashMap<>();
map.put("sid", bv.getBusinessSid());
map.put("nodeState", nodeState);
map.put("procInsId", rb.getData().getProcInsId());
map.put("taskDefKey", task_def_key_);
map.put("taskId",list.get(0).getId_());
taskService.setVariablesLocal(list.get(0).getId_(),bv.getFormVariables());
return new ResultBean().success().setData(map);
}
public ResultBean myprocess(String userSid, PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
PagerQuery<BusinessTaskQuery> pq = new PagerQuery<>();
String days = taskQueryPagerQuery.getParams().getDays();
String zd = taskQueryPagerQuery.getParams().getZd();
pq.setCurrent(taskQueryPagerQuery.getCurrent());
pq.setSize(taskQueryPagerQuery.getSize());
BusinessTaskQuery businessTaskQuery = BusinessTaskQuery.create();
if (StringUtils.isNotBlank(zd)) {
BusinessTaskParam businessTaskParam = new BusinessTaskParam();
businessTaskParam.setField("zd");
businessTaskParam.setSqlOperationSymbol(SQLOperationSymbol.LIKE);
businessTaskParam.setValue(zd);
businessTaskQuery.add(businessTaskParam);
}
if (StringUtils.isNotBlank(days)) {
BusinessTaskParam businessTaskParam = new BusinessTaskParam();
businessTaskParam.setField("days");
businessTaskParam.setSqlOperationSymbol(SQLOperationSymbol.EQUAL);
businessTaskParam.setValue(days);
businessTaskQuery.add(businessTaskParam);
}
pq.setParams(businessTaskQuery);
return flowTaskService.businessMyprocessNew(userSid, pq);
}
public ResultBean processPagerList(Integer pageNum, Integer pageSize) {
return flowDefinitionService.pagerListNew(pageNum, pageSize);
}
public ResultBean todoTaskList(String userSid, PagerQuery<TaskQuery> pQuery) {
TaskQuery params = pQuery.getParams();
if (StringUtils.isBlank(userSid)) {
return ResultBean.fireFail().setMsg("用户SID为空");
}
PagerQuery<BusinessTaskQuery> taskQueryPagerQuery = new PagerQuery<>();
taskQueryPagerQuery.setCurrent(pQuery.getCurrent()).setSize(pQuery.getSize());
String days = params.getDays();
String processDefinitionId = params.getProcessDefinitionId();
String startTime = params.getStartTime();
BusinessTaskQuery taskQuery = new BusinessTaskQuery();
List<BusinessTaskParam> taskParamList = new ArrayList<>();
if (StringUtils.isNotBlank(days)) {
BusinessTaskParam taskParam = new BusinessTaskParam();
taskParam.setField("zd1");
taskParam.setValue(days);
taskParam.setSqlOperationSymbol(SQLOperationSymbol.EQUAL);
taskParamList.add(taskParam);
}
if (StringUtils.isNotBlank(startTime)) {
BusinessTaskParam taskParam = new BusinessTaskParam();
taskParam.setField("startTime");
taskParam.setValue(startTime);
taskParam.setSqlOperationSymbol(SQLOperationSymbol.EQUAL);
taskParamList.add(taskParam);
}
if (StringUtils.isNotBlank(processDefinitionId)) {
BusinessTaskParam taskParam = new BusinessTaskParam();
taskParam.setField("processDefinitionId");
taskParam.setSqlOperationSymbol(SQLOperationSymbol.NONE);
taskParam.setValue(processDefinitionId);
taskParamList.add(taskParam);
}
taskQuery.setFields(taskParamList);
taskQueryPagerQuery.setParams(taskQuery);
return flowTaskService.businessTodoListNew(userSid, taskQueryPagerQuery);
}
public ResultBean doneTaskList(String userSid, PagerQuery<TaskQuery> pQuery) {
TaskQuery params = pQuery.getParams();
if (StringUtils.isBlank(userSid)) {
return ResultBean.fireFail().setMsg("用户SID为空");
}
PagerQuery<BusinessTaskQuery> taskQueryPagerQuery = new PagerQuery<>();
taskQueryPagerQuery.setCurrent(pQuery.getCurrent()).setSize(pQuery.getSize());
String zd1 = params.getZd1();
String processDefinitionId = params.getProcessDefinitionId();
String startTime = params.getStartTime();
BusinessTaskQuery taskQuery = new BusinessTaskQuery();
List<BusinessTaskParam> taskParamList = new ArrayList<>();
if (StringUtils.isNotBlank(zd1)) {
BusinessTaskParam taskParam = new BusinessTaskParam();
taskParam.setField("zd1");
taskParam.setValue(zd1);
taskParam.setSqlOperationSymbol(SQLOperationSymbol.EQUAL);
taskParamList.add(taskParam);
}
if (StringUtils.isNotBlank(startTime)) {
BusinessTaskParam taskParam = new BusinessTaskParam();
taskParam.setField("startTime");
taskParam.setValue(startTime);
taskParam.setSqlOperationSymbol(SQLOperationSymbol.EQUAL);
taskParamList.add(taskParam);
}
if (StringUtils.isNotBlank(processDefinitionId)) {
BusinessTaskParam taskParam = new BusinessTaskParam();
taskParam.setField("processDefinitionId");
taskParam.setSqlOperationSymbol(SQLOperationSymbol.NONE);
taskParam.setValue(processDefinitionId);
taskParamList.add(taskParam);
}
taskQuery.setFields(taskParamList);
taskQueryPagerQuery.setParams(taskQuery);
return flowTaskService.businessDoneListNew(userSid, taskQueryPagerQuery);
}
/**
* 取消
*
* @param variables
* @return
*/
public ResultBean complete(Map<String, Object> variables) {
BusinessVariables bv = BusinessVariables.builder().build();
bv.setFormVariables(variables);
ResultBean<FlowTask> resultBean = flowTaskService.businessComplete(bv);
if (!resultBean.getSuccess()) {
return resultBean;
}
String nodeState = "";
if (resultBean.getData() != null) {
ResultBean<List<LatestTaskVo>> listResultBean = flowTaskService.getLatestTasksNew(resultBean.getData().getProcInsId());
if (listResultBean.getSuccess() && listResultBean.getData() != null && listResultBean.getData().size() != 0) {
nodeState = listResultBean.getData().get(0).getName_();
} else {
nodeState = ProcessStateEnum.FINISHED.getStateName();
}
}
Map<String, String> map = new HashMap<>();
map.put("nodeState", nodeState);
return new ResultBean().success().setData(map);
}
/**
* 撤回
*
* @param userSid
* @param flowTaskVo
* @return
*/
public ResultBean revokeProcess(String userSid, FlowTaskVo flowTaskVo) {
com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl = new com.yxt.anrui.flowable.api.flowtask.FlowTaskVo();
BeanUtil.copyProperties(flowTaskVo, fl);
fl.setUserSid(userSid);
ResultBean<List<LatestTaskVo>> resultBean = flowTaskService.revokeProcess(fl);
if (!resultBean.getSuccess()) {
return resultBean;
}
String nodeState = resultBean.getData().get(0).getName_();
Map<String, String> map = new HashMap<>();
map.put("nodeState", nodeState);
return new ResultBean().success().setData(map);
}
public ResultBean flowRecord(String procInsId, String deployId) {
return flowTaskService.businessFlowRecord(procInsId);
}
public ResultBean taskReject(FlowTaskVo flowTaskVo) {
com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl = new com.yxt.anrui.flowable.api.flowtask.FlowTaskVo();
BeanUtil.copyProperties(flowTaskVo, fl);
ResultBean<List<LatestTaskVo>> resultBean = flowTaskService.taskReject(fl);
if (!resultBean.getSuccess()) {
return resultBean;
}
String nodeState = resultBean.getData().get(0).getName_();
Map<String, String> map = new HashMap<>();
map.put("nodeState", nodeState);
return new ResultBean().success().setData(map);
}
/**
* 终止流程
*
* @param flowTaskVo
* @return
*/
public ResultBean<UpdateFlowFieldVo> breakProcess(com.yxt.anrui.flowable.api.flowtask.FlowTaskVo flowTaskVo) {
/* com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl = new com.yxt.anrui.flowable.api.flowtask.FlowTaskVo();
BeanUtil.copyProperties(flowTaskVo, fl);*/
ResultBean<UpdateFlowFieldVo> resultBean = flowTaskService.breakProcess(flowTaskVo);
if (!resultBean.getSuccess()) {
return resultBean;
}
UpdateFlowFieldVo vo=new UpdateFlowFieldVo();
vo.setNodeState(String.valueOf(resultBean.getData()));
return resultBean.success().setData(vo);
}
public void stopProcess(com.yxt.anrui.flowable.api.flow.FlowTaskVo flowTaskVo) {
com.yxt.anrui.flowable.api.flowtask.FlowTaskVo fl = new com.yxt.anrui.flowable.api.flowtask.FlowTaskVo();
BeanUtil.copyProperties(flowTaskVo, fl);
flowTaskService.stopProcess(flowTaskVo.getUserSid(), fl);
}
public void deleteProcess(String procInsId) {
flowTaskService.deleteProcessNew(procInsId);
}
public Map<String, String> getProcessInstanceById(String procInsId) {
return baseMapper.getProcessInstanceById(procInsId);
}
}

143
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowdefinition/FlowDefinitionRest.java

@ -0,0 +1,143 @@
package com.yxt.anrui.flowable.biz.flowdefinition;
import com.yxt.anrui.flowable.api.flowdefinition.FlowDefinitionFeign;
import com.yxt.anrui.flowable.api.flowdefinition.FlowSaveXmlQuery;
import com.yxt.anrui.flowable.api.flowdefinition.SysUser;
import com.yxt.common.core.result.ResultBean;
import com.yxt.supervise.system.sysrole.SysRoleFeign;
import com.yxt.supervise.system.sysrole.SysRoleVo;
import com.yxt.supervise.system.sysuser.SysUserFeign;
import com.yxt.supervise.system.sysuser.SysUserVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
/**
* @author dimengzhe
* @date 2021/6/16 17:14
* @description 流程定义
*/
@Api(tags = "流程定义")
@Controller
@RequestMapping("/v1/flowable/definition")
public class FlowDefinitionRest implements FlowDefinitionFeign {
private static final Logger log = LoggerFactory.getLogger(FlowDefinitionRest.class);
@Autowired
private FlowDefinitionService flowDefinitionService;
@Autowired
private SysUserFeign sysUserFeign;
@Autowired
private SysRoleFeign sysRoleFeign;
@Override
public ResultBean importFile(String name, String category, MultipartFile file) {
InputStream in = null;
try {
in = file.getInputStream();
flowDefinitionService.importFile(name, category, in);
} catch (Exception e) {
log.error("导入失败:", e);
return ResultBean.fireFail().setMsg(e.getMessage());
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
log.error("关闭输入流出错", e);
}
}
return ResultBean.fireSuccess().setMsg("导入成功");
}
@Override
public ResultBean pagerList(Integer pageNum, Integer pageSize) {
return flowDefinitionService.pagerListNew(pageNum, pageSize);
}
@Override
public ResultBean updateState(Integer state, String deployId) {
flowDefinitionService.updateState(state, deployId);
return ResultBean.fireSuccess();
}
@Override
public ResultBean delete(String deployId) {
flowDefinitionService.delete(deployId);
return ResultBean.fireSuccess();
}
@Override
public ResultBean save(FlowSaveXmlQuery flowSaveXmlQuery) {
InputStream in = null;
try {
in = new ByteArrayInputStream(flowSaveXmlQuery.getXml().getBytes(StandardCharsets.UTF_8));
flowDefinitionService.importFile(flowSaveXmlQuery.getName(), flowSaveXmlQuery.getCategory(), in);
} catch (Exception e) {
log.error("导入失败:", e);
return ResultBean.fireFail().setMsg(e.getMessage());
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
log.error("关闭输入流出错", e);
}
}
return ResultBean.fireSuccess().setMsg("导入成功");
}
@Override
public ResultBean readXml(String deployId) {
try {
return flowDefinitionService.readXml(deployId);
} catch (Exception e) {
e.printStackTrace();
return ResultBean.fireFail().setMsg("加载xml文件异常");
}
}
@Override
public ResultBean userList(SysUser user) {
ResultBean<List<SysUserVo>> list = sysUserFeign.list();
return list;
}
@Override
public ResultBean roleList() {
ResultBean<List<SysRoleVo>> list = sysRoleFeign.list();
return list;
}
@Override
public ResultBean start(@ApiParam(value = "流程定义id") @PathVariable(value = "procDefId") String procDefId,
@ApiParam(value = "变量集合,json对象") @RequestBody Map<String, Object> variables) {
return flowDefinitionService.startProcessInstanceById(procDefId, variables);
}
/* @Override
public ResultBean<FlowTask> businessStart(@ApiParam(value = "变量集合") @RequestBody BusinessVariables dto) {
return flowDefinitionService.businessStart(dto);
}*/
}

273
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowdefinition/FlowDefinitionService.java

@ -0,0 +1,273 @@
package com.yxt.anrui.flowable.biz.flowdefinition;
/**
* @author dimengzhe
* @date 2021/6/16 17:19
* @description 流程定义
*/
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yxt.anrui.flowable.api.flowdefinition.FlowDefinitionVo;
import com.yxt.anrui.flowable.api.flowtask.FlowTask;
import com.yxt.anrui.flowable.api.flowtask.LatestTaskVo;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.biz.flow.FlowableService;
import com.yxt.anrui.flowable.biz.flowtask.FlowTaskService;
import com.yxt.anrui.flowable.biz.sysdeployform.SysDeployFormService;
import com.yxt.anrui.flowable.api.flowcomment.FlowComment;
import com.yxt.anrui.flowable.common.ProcessConstants;
import com.yxt.anrui.flowable.factory.FlowServiceFactory;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables;
import com.yxt.common.base.utils.JPushServer;
import com.yxt.common.base.utils.StringUtils;
import com.yxt.common.core.result.ResultBean;
import com.yxt.supervise.system.sysuser.SysUser;
import com.yxt.supervise.system.sysuser.SysUserFeign;
import com.yxt.supervise.system.sysuser.SysUserVo;
import org.apache.commons.io.IOUtils;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Service
public class FlowDefinitionService extends FlowServiceFactory {
private static final String BPMN_FILE_SUFFIX = ".bpmn";
@Autowired
private SysDeployFormService sysDeployFormService;
@Autowired
private SysUserFeign sysUserFeign;
@Autowired
private FlowableService flowableService;
/**
* 导入流程文件
*
* @param name
* @param category
* @param in
*/
public void importFile(String name, String category, InputStream in) {
Deployment deploy = repositoryService.createDeployment().addInputStream(name + BPMN_FILE_SUFFIX, in).name(name).category(category).deploy();
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();
repositoryService.setProcessDefinitionCategory(definition.getId(), category);
}
public Page<FlowDefinitionVo> list(Integer pageNum, Integer pageSize) {
Page<FlowDefinitionVo> page = new Page<>();
// 流程定义列表数据查询
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery()
.orderByProcessDefinitionKey().asc();
page.setTotal(processDefinitionQuery.count());
List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage((pageNum - 1) * pageSize, pageSize);
List<FlowDefinitionVo> dataList = new ArrayList<>();
for (ProcessDefinition processDefinition : processDefinitionList) {
String deploymentId = processDefinition.getDeploymentId();
Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
FlowDefinitionVo reProcDef = new FlowDefinitionVo();
BeanUtils.copyProperties(processDefinition, reProcDef);
SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(deploymentId);
if (Objects.nonNull(sysForm)) {
reProcDef.setFormName(sysForm.getFormName());
reProcDef.setFormId(Long.valueOf(sysForm.getId()));
}
// 流程定义时间
reProcDef.setDeploymentTime(deployment.getDeploymentTime());
dataList.add(reProcDef);
}
page.setRecords(dataList);
return page;
}
/**
* 激活或挂起流程定义
*
* @param state 状态
* @param deployId 流程部署ID
*/
public void updateState(Integer state, String deployId) {
ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
// 激活
if (state == 1) {
repositoryService.activateProcessDefinitionById(procDef.getId(), true, null);
}
// 挂起
if (state == 2) {
repositoryService.suspendProcessDefinitionById(procDef.getId(), true, null);
}
}
/**
* 删除流程定义
*
* @param deployId 流程部署ID act_ge_bytearray 表中 deployment_id值
*/
public void delete(String deployId) {
// true 允许级联删除 ,不设置会导致数据库外键关联异常
repositoryService.deleteDeployment(deployId, true);
}
public ResultBean readXml(String deployId) throws IOException {
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName());
String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
return ResultBean.fireSuccess().setData(result);
}
/**
* 根据流程定义ID启动流程实例
*
* @param procDefId 流程定义Id
* @param variables 流程变量
* @return
*/
public ResultBean startProcessInstanceById(String procDefId, Map<String, Object> variables) {
try {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId)
.latestVersion().singleResult();
if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
return ResultBean.fireFail().setMsg("流程已被挂起,请先激活流程");
}
// variables.put("skip", true);
// variables.put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);
// 设置流程发起人Id到流程中
SysUser sysUser = new SysUser();//SecurityUtils.getLoginUser().getUser();
sysUser.setSid("0d8d8119-d476-47ce-89c2-075cd809dda6");
identityService.setAuthenticatedUserId(sysUser.getSid().toString());
variables.put(ProcessConstants.PROCESS_INITIATOR, "");
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
// 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题?
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
if (Objects.nonNull(task)) {
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.START.getType(), sysUser.getUserName() + "发起流程申请");
// taskService.setAssignee(task.getId(), sysUser.getUserId().toString());
taskService.complete(task.getId(), variables);
}
return ResultBean.fireSuccess().setMsg("流程启动成功");
} catch (Exception e) {
e.printStackTrace();
return ResultBean.fireFail().setMsg("流程启动错误");
}
}
@Autowired
private FlowTaskService flowTaskService;
/**
* 根据流程定义ID启动流程实例
*
* @param procDefId 流程定义Id
* @param userSid 发起人sid
* @param variables 流程变量
* @return
*/
public ResultBean<FlowTask> businessStartProcessInstanceById(String procDefId, String userSid, String nextNodeUserSids, Map<String, Object> variables) {
try {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId)
.latestVersion().singleResult();
if (Objects.nonNull(processDefinition) && processDefinition.isSuspended()) {
ResultBean rb = ResultBean.fireFail();
return rb.setData(new FlowTask()).setMsg("流程已被挂起,请先激活流程");
}
// 设置流程发起人Id到流程中
ResultBean<SysUserVo> sysUserVoResultBean = sysUserFeign.fetchBySid(userSid);
SysUserVo sysUser = sysUserVoResultBean.getData();
identityService.setAuthenticatedUserId(sysUser.getSid());
variables.put(ProcessConstants.PROCESS_INITIATOR, userSid);
variables.put(ProcessConstants.USER_TYPE_ASSIGNEE, userSid);
ProcessInstance processInstance = runtimeService.startProcessInstanceById(procDefId, variables);
// 给第一步申请人节点设置任务执行人和意见 todo:第一个节点不设置为申请人节点有点问题?
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
/* for(Map.Entry<String, Object> entry:variables.entrySet()){
taskService.setVariable(task.getId(),entry.getKey(),entry.getValue());
System.out.println(entry.getKey()+"--->"+entry.getValue());
}*/
if (Objects.nonNull(task)) {
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.START.getType(),
sysUser.getName() + "发起流程申请");
taskService.setAssignee(task.getId(), userSid);
taskService.setVariablesLocal(task.getId(),variables);
taskService.complete(task.getId(), variables);
}
ResultBean<List<LatestTaskVo>> latestTasksNew = flowTaskService.getLatestTasksNew(processInstance.getId());
List<LatestTaskVo> data = latestTasksNew.getData();
LatestTaskVo latestTaskVo = data.get(0);
String id_ = latestTaskVo.getId_();
taskService.setAssignee(id_,nextNodeUserSids);
ResultBean<FlowTask> rb = new ResultBean<>();
FlowTask flowTask = new FlowTask();
flowTask.setTaskId(task.getId());
flowTask.setTaskName(task.getName());
flowTask.setProcInsId(task.getProcessInstanceId());
return rb.success().setData(flowTask).setMsg("流程启动成功");
} catch (Exception e) {
e.printStackTrace();
ResultBean rb = ResultBean.fireFail();
return rb.setData(new FlowTask()).setMsg("流程启动错误");
}
}
/**
* 向下一环节待办人发出推送
*
* @param taskId
*/
private void sendPush(String taskId) {
ResultBean nextTasks = flowTaskService.getNextTasks(taskId);
System.out.println(nextTasks.getData());
String assignee = ((HashMap) ((ArrayList) nextTasks.getData()).get(0)).get("assignee").toString();
String name = ((HashMap) ((ArrayList) nextTasks.getData()).get(0)).get("name").toString();
System.out.println("assignee:" + assignee);
Integer id = sysUserFeign.fetchBySid(assignee).getData().getId();
System.out.println("id:" + id);
JPushServer.sendPushAlias(name, name, "msg_type", "系统消息", id.toString());
}
public ResultBean<FlowTask> businessStart(BusinessVariables dto) {
ResultBean<FlowTask> resultBean = new ResultBean<>();
Map<String, Object> variables = dto.getFormVariables();
variables.put(BusinessVariables.ORGPATH,dto.getOrgSidPath());
Object procDefId_obj = dto.getModelId();
Object userSid_obj = dto.getUserSid();
String procDefId = null;
String userSid = null;
if (procDefId_obj == null) {
return resultBean.fail().setData(new FlowTask()).setMsg("procDefId 不能为空");
} else {
procDefId = (String) procDefId_obj;
if (StringUtils.isBlank(procDefId)) {
resultBean.fail().setData(new FlowTask()).setMsg("procDefId 不能为空");
return resultBean;
}
}
if (userSid_obj == null) {
resultBean.fail().setData(new FlowTask()).setMsg("userSid 不能为空");
return resultBean;
} else {
userSid = (String) userSid_obj;
if (StringUtils.isBlank(userSid)) {
resultBean.fail().setData(new FlowTask()).setMsg("userSid 不能为空");
return resultBean;
}
}
resultBean = businessStartProcessInstanceById(procDefId, userSid,dto.getNextNodeUserSids(), variables);
return resultBean;
}
public ResultBean pagerListNew(Integer pageNum, Integer pageSize) {
Page<FlowDefinitionVo> pageList = list(pageNum, pageSize);
return ResultBean.fireSuccess().setData(pageList);
}
}

71
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowinstance/FlowInstanceRest.java

@ -0,0 +1,71 @@
package com.yxt.anrui.flowable.biz.flowinstance;
/**
* @author dimengzhe
* @date 2021/6/16 9:10
* @description
*/
import com.yxt.anrui.flowable.api.flowdefinition.FlowInstanceDto;
import com.yxt.anrui.flowable.api.flowinstance.FlowInstanceFeign;
import com.yxt.anrui.flowable.api.flowinstance.FlowInstanceVo;
import com.yxt.common.core.result.ResultBean;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Api(tags = "工作流流程实例管理")
@RequestMapping("v1/flowable/instance")
@Controller
public class FlowInstanceRest implements FlowInstanceFeign {
@Autowired
private FlowInstanceService flowInstanceService;
@Override
public ResultBean<FlowInstanceVo> startProcess(FlowInstanceDto flowTaskDto) {
FlowInstanceVo flowTaskVo = new FlowInstanceVo();
ResultBean<FlowInstanceVo> resultBean = ResultBean.fireFail();
if (flowTaskDto == null) {
return resultBean.setData(flowTaskVo);
}
flowTaskVo = flowInstanceService.startProcess(flowTaskDto);
if (null == flowTaskVo) {
return resultBean.setData(flowTaskVo);
}
return resultBean.success().setData(flowTaskVo);
}
/**
* 根据流程定义id启动流程实例
*
* @param procDefId 流程定义id
* @return
*/
@Override
public ResultBean startById(String procDefId) {
return flowInstanceService.startProcessInstanceById(procDefId);
}
/**
* 删除流程实例
*
* @param instanceId 流程实例ID
* @param deleteReason 删除原因
* @return
*/
@Override
public ResultBean delete(String instanceId, String deleteReason) {
flowInstanceService.delete(instanceId, deleteReason);
return ResultBean.fireSuccess();
}
@Override
public ResultBean updateState(Integer state, String instanceId) {
flowInstanceService.updateState(state, instanceId);
return ResultBean.fireSuccess();
}
}

106
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowinstance/FlowInstanceService.java

@ -0,0 +1,106 @@
package com.yxt.anrui.flowable.biz.flowinstance;
import com.yxt.anrui.flowable.api.flowdefinition.FlowInstanceDto;
import com.yxt.anrui.flowable.api.flowinstance.FlowInstanceVo;
import com.yxt.anrui.flowable.factory.FlowServiceFactory;
import com.yxt.common.core.result.ResultBean;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
/**
* @author dimengzhe
* @date 2021/6/16 10:18
* @description 工作流流程实例管理
*/
@Service
public class FlowInstanceService extends FlowServiceFactory {
/**
* 根据流程定义ID启动流程实例
*
* @param procDefId 流程定义Id
* @return
*/
public ResultBean startProcessInstanceById(String procDefId) {
try {
runtimeService.startProcessInstanceById(procDefId);
} catch (Exception e) {
e.printStackTrace();
return ResultBean.fireFail().setMsg("流程启动错误");
}
return ResultBean.fireSuccess().setMsg("流程启动成功");
}
/**
* 删除流程实例ID
*
* @param instanceId 流程实例ID
* @param deleteReason 删除原因
*/
@Transactional(rollbackFor = Exception.class)
public void delete(String instanceId, String deleteReason) {
// 查询历史数据
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
if (historicProcessInstance.getEndTime() != null) {
historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
return;
}
// 删除流程实例
runtimeService.deleteProcessInstance(instanceId, deleteReason);
// 删除历史流程实例
historyService.deleteHistoricProcessInstance(instanceId);
}
/**
* 激活或挂起流程实例
*
* @param state 状态
* @param instanceId 流程实例ID
*/
public void updateState(Integer state, String instanceId) {
// 激活
if (state == 1) {
runtimeService.activateProcessInstanceById(instanceId);
}
// 挂起
if (state == 2) {
runtimeService.suspendProcessInstanceById(instanceId);
}
}
/**
* 根据实例ID查询历史实例数据
*
* @param processInstanceId
* @return
*/
public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
HistoricProcessInstance historicProcessInstance =
historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if (Objects.isNull(historicProcessInstance)) {
throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
}
return historicProcessInstance;
}
public FlowInstanceVo startProcess(FlowInstanceDto flowTaskDto) {
//流程定义id
String processDefinitionId = flowTaskDto.getProcessId();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
FlowInstanceVo flowTaskVo = new FlowInstanceVo();
//流程实例id
flowTaskVo.setInstanceId(processInstance.getId());
return flowTaskVo;
}
}

331
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskController.java

@ -0,0 +1,331 @@
package com.yxt.anrui.flowable.biz.flowtask;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yxt.anrui.flowable.api.flow.UserAndOrgPath;
import com.yxt.anrui.flowable.api.flowtask.*;
import com.yxt.anrui.flowable.api.utils.RecordQuery;
import com.yxt.anrui.flowable.biz.process.ProcessService;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessTaskParam;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessTaskQuery;
import com.yxt.anrui.flowable.sqloperationsymbol.BusinessVariables;
import com.yxt.anrui.flowable.test.StartProcessInstanceQuery;
import com.yxt.anrui.flowable.utils.FlowableUtils;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>工作流任务管理<p>
*
* @author XuanXuan
* @date 2021-04-03
*/
@Api(tags = "工作流流程任务管理")
@RestController
@RequestMapping("/v1/flowable/task")
public class FlowTaskController implements FlowTaskFeign {
@Autowired
private FlowTaskService flowTaskService;
@Resource
protected HistoryService historyService;
@Resource
protected RepositoryService repositoryService;
@Resource
protected TaskService taskService;
@Resource
private ProcessService processService;
@Override
public ResultBean<String> startProcessInstanceByKey(StartProcessInstanceQuery startProcessInstanceQuery) {
return null;
}
@Override
public ResultBean<FlowTask> businessComplete(@RequestBody BusinessVariables dto) {
return flowTaskService.businessComplete(dto);
}
@Override
public ResultBean<String> complete(@RequestBody FlowTaskVo flowTaskVo) {
return flowTaskService.complete(flowTaskVo);
}
@Override
public ResultBean todoList(PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
int size = Integer.valueOf(taskQueryPagerQuery.getSize() + "");
int current = Integer.valueOf(taskQueryPagerQuery.getCurrent() + "");
ResultBean<Page<FlowTaskDto>> resultBean = flowTaskService.todoList(current, size);
return resultBean;
}
@Override
public ResultBean<Page<FlowTaskDto>> businessTodoList(String userSid, PagerQuery<BusinessTaskQuery> businessTaskQuery) {
int size = Integer.valueOf(businessTaskQuery.getSize() + "");
int current = Integer.valueOf(businessTaskQuery.getCurrent() + "");
List<BusinessTaskParam> fields = businessTaskQuery.getParams().getFields();
/* AtomicReference<String> orgPath= new AtomicReference<>("");
fields.forEach(f->{
if(f.getField().equals(BusinessVariables.ORGPATH))
orgPath.set(f.getValue());
});*/
String orgPath=null;
for(BusinessTaskParam b: fields){
if(b.getField().equals(BusinessVariables.ORGPATH)) {
orgPath=b.getValue();
}
}
ResultBean<Page<FlowTaskDto>> resultBean = flowTaskService.businessTodoList(userSid, orgPath, fields, current, size);
return resultBean;
}
@Override
public ResultBean<Page<FlowTaskDto>> businessTodoListForApp(String userSid, PagerQuery<BusinessTaskQuery> businessTaskQuery) {
int size = Integer.valueOf(businessTaskQuery.getSize() + "");
int current = Integer.valueOf(businessTaskQuery.getCurrent() + "");
List<BusinessTaskParam> fields = businessTaskQuery.getParams().getFields();
String companySid="";
if(fields.size()>0){
for(BusinessTaskParam b:fields){
if(b.getField().equals(BusinessVariables.ORGPATH)){
companySid=b.getValue();
}
}
}
ResultBean<Page<FlowTaskDto>> resultBean = flowTaskService.businessTodoListForApp(userSid,companySid, fields, current, size);
return resultBean;
}
@Override
public ResultBean<Integer> getTodoNum(String userSid) {
return flowTaskService.getTodoNum(userSid,null);
}
@Override
public ResultBean<Integer> getTodoNum(UserAndOrgPath uaop) {
String userSid=uaop.getUserSid();
String orgPath=uaop.getOrgPath();
return flowTaskService.getTodoNum(userSid,orgPath);
}
@Override
public ResultBean doneList(PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
int size = Integer.valueOf(taskQueryPagerQuery.getSize() + "");
int current = Integer.valueOf(taskQueryPagerQuery.getCurrent() + "");
return flowTaskService.finishedList(current, size);
}
@Override
public ResultBean businessDoneList(String userSid, PagerQuery<BusinessTaskQuery> taskQueryPagerQuery) {
return flowTaskService.businessDoneListNew(userSid, taskQueryPagerQuery);
}
@Override
public ResultBean<Page<FlowTaskDto>> businessDoneListForApp(String userSid, PagerQuery<BusinessTaskQuery> taskQueryPagerQuery) {
return flowTaskService.businessDoneListNewForApp(userSid, taskQueryPagerQuery);
}
@Override
public ResultBean flowRecord(RecordQuery recordQuery) {
String deployId = recordQuery.getDeployId();
String procInsId = recordQuery.getProcInsId();
return flowTaskService.flowRecord(procInsId, deployId);
}
@Override
public ResultBean stopProcess(String userSid, FlowTaskVo flowTaskVo) {
return flowTaskService.stopProcessNew(userSid, flowTaskVo);
}
@Override
public ResultBean myprocess(PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
FlowTaskQuery params = taskQueryPagerQuery.getParams();
String userSid = params.getUserSid();
if (StringUtils.isBlank(userSid))
return ResultBean.fireFail().setMsg("用户SID不可为空~");
int currentPage = (int) (taskQueryPagerQuery.getCurrent() - 1);
Page<FlowTaskDto> page = new Page<>();
// Long userId =5001L;// SecurityUtils.getLoginUser().getUser().getUserId();
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
.startedBy(userSid)
.orderByProcessInstanceStartTime()
.desc();
List<HistoricProcessInstance> historicProcessInstances = query
.listPage(currentPage, 10);
page.setTotal(query.count());
List<FlowTaskDto> flowList = new ArrayList<>();
for (HistoricProcessInstance hisIns : historicProcessInstances) {
FlowTaskDto flowTask = new FlowTaskDto();
flowTask.setCreateTime(hisIns.getStartTime());
flowTask.setFinishTime(hisIns.getEndTime());
flowTask.setProcInsId(hisIns.getId());
// 计算耗时
if (Objects.nonNull(hisIns.getEndTime())) {
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
flowTask.setDuration(FlowableUtils.getDate(time));
} else {
long time = System.currentTimeMillis() - hisIns.getStartTime().getTime();
flowTask.setDuration(FlowableUtils.getDate(time));
}
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(hisIns.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());
flowTask.setProcDefName(pd.getName());
flowTask.setProcDefVersion(pd.getVersion());
flowTask.setCategory(pd.getCategory());
flowTask.setProcDefVersion(pd.getVersion());
// 当前所处流程
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list();
if (CollectionUtils.isNotEmpty(taskList)) {
flowTask.setTaskId(taskList.get(0).getId());
} else {
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
flowTask.setTaskId(historicTaskInstance.get(0).getId());
}
flowList.add(flowTask);
}
page.setRecords(flowList);
return ResultBean.fireSuccess().setData(page);
}
@Override
public ResultBean businessMyprocess(String userSid, PagerQuery<BusinessTaskQuery> businessTaskQuery) {
return flowTaskService.businessMyprocessNew(userSid, businessTaskQuery);
}
@Override
public ResultBean processVariables(String taskId) {
return flowTaskService.processVariables(taskId);
}
@Override
public ResultBean getFlowViewer(String procInsId) {
return flowTaskService.getFlowViewer(procInsId);
}
@Override
public ResultBean findReturnTaskList(FlowTaskVo flowTaskVo) {
return flowTaskService.findReturnTaskList(flowTaskVo);
}
@Override
public ResultBean taskReturn(@RequestBody FlowTaskVo flowTaskVo) {
flowTaskService.taskReturn(flowTaskVo);
return ResultBean.fireSuccess();
}
@Override
public ResultBean<List<LatestTaskVo>> taskReject(FlowTaskVo flowTaskVo) {
return flowTaskService.taskReject(flowTaskVo);
}
@Override
public ResultBean<List<LatestTaskVo>> revokeProcess(@RequestBody FlowTaskVo flowTaskVo) {
return flowTaskService.revokeProcess(flowTaskVo);
}
@Override
public ResultBean breakProcess(FlowTaskVo flowTaskVo) {
return flowTaskService.breakProcess(flowTaskVo);
}
@Override
public ResultBean flowRecord(String procInsId, String deployId) {
return flowTaskService.flowRecord(procInsId, deployId);
}
@Override
public ResultBean<FlowRecordVo> businessFlowRecord(String procInsId) {
return flowTaskService.businessFlowRecord(procInsId);
}
@Override
public ResultBean deleteProcess(String procInsId) {
return flowTaskService.deleteProcessNew(procInsId);
}
@Override
public ResultBean getNextTasks(String taskId) {
return flowTaskService.getNextTasks(taskId);
}
@Override
public ResultBean<List<LatestTaskVo>> getLatestTasks(String procId) {
return flowTaskService.getLatestTasksNew(procId);
}
@Override
public ResultBean<List<FlowElement>> getProcessCirculationNodes(String procId,
String modelId,
String k,
String v, String outcome) {
Map<String, Object> map = new HashMap<>();
map.put(k, v);
map.put("outcome", outcome);
List<FlowElement> flowElements = processService.calApprovePath(procId, modelId, map);
List<FlowElement> collect = flowElements.stream().filter(item -> item.getId().length() > 0).collect(Collectors.toList());
for (int i = 0; i < collect.size(); i++) {
if (collect.get(i).getId().equals(modelId)) {
FlowElement item = collect.get(i + 1);
String s = JSON.toJSONString(item);
JSONObject jsonObject = JSONObject.parseObject(s);
Object candidateGroups = jsonObject.get("candidateGroups");
JSONArray candidateGroups_arr = new JSONArray();
if (candidateGroups != null) {
candidateGroups_arr = JSONArray.parseArray(candidateGroups.toString());
}
if (candidateGroups_arr.size() > 0) {
}
}
}
ResultBean<List<FlowElement>> rb = new ResultBean<List<FlowElement>>();
return rb.setData(flowElements);
}
@Override
public ResultBean getProcessCirculationNodesByMap(BusinessVariables bv) {
return flowTaskService.getProcessCirculationNodesByMap(bv);
}
@Override
public ResultBean readXml(String deployId) {
return flowTaskService.readXml(deployId);
}
@Override
public ResultBean getNextNodesForSubmit(BusinessVariables bv) {
return flowTaskService.getNextNodesForSubmit(bv);
}
@Override
public ResultBean getPreviousNodesForReject(BusinessVariables bv) {
return flowTaskService.getPreviousNodesForReject(bv);
}
}

46
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskMapper.java

@ -0,0 +1,46 @@
package com.yxt.anrui.flowable.biz.flowtask;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yxt.anrui.flowable.api.flowtask.FlowTask;
import com.yxt.anrui.flowable.api.flowtask.LatestTaskVo;
import com.yxt.anrui.flowable.api.flowtask.TaskQueryParamsVo;
import com.yxt.anrui.flowable.api.flowtask.TaskVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.flowable.task.api.history.HistoricTaskInstance;
import java.util.List;
import java.util.Map;
/**
* 流程任务关联单Mapper接口
*
* @author XuanXuan Xuan
* @date 2021-04-03
*/
@Mapper
public interface FlowTaskMapper extends BaseMapper<FlowTask> {
IPage<TaskVo> getApplyedTasksPagerModel(IPage<TaskVo> page, @Param("params") TaskQueryParamsVo params);
/*取消*/
List<Map<String,Object>> finishedList(@Param("userSid")String userSid,
@Param("list")List<Map<String,Object>> list, @Param("page")int page, @Param("size")int size);
List<Map<String,Object>> finishedList1(Map<String, Object> map);
int finishedListCount(Map<String, Object> map);
/**
* 根据流程实例的id查询最新的待办环节
* @param procId
* @return
*/
List<LatestTaskVo> getLatestTasks(@Param("procId")String procId);
Map<String,Object> getHistTaskByID(@Param("procId")String procId,@Param("taskId")String id);
Map<String, Object> getTaskByDefKey(@Param("procId")String processInstanceId, @Param("taskId")String id);
Map<String, Object> getActHiVarinstForOrgPath(@Param("taskId")String taskId);
}

236
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskMapper.xml

@ -0,0 +1,236 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.flowtask.FlowTaskMapper">
<resultMap id="TaskVoMap" type="com.yxt.anrui.flowable.api.flowtask.TaskVo">
<id column="ID_" property="taskId" jdbcType="VARCHAR"/>
<result column="NAME_" property="name" jdbcType="VARCHAR"/>
<result column="ASSIGNEE_" property="assignee" jdbcType="VARCHAR"/>
<result column="PROC_INST_ID_" property="processInstanceId" jdbcType="VARCHAR"/>
<result column="PARENT_ID_" property="parentId" jdbcType="VARCHAR"/>
<result column="model_key" property="processDefinitionKey" jdbcType="VARCHAR"/>
<result column="BUSINESS_KEY_" property="businessKey" jdbcType="VARCHAR"/>
<result column="proc_inst_name" property="formName" jdbcType="VARCHAR"/>
<result column="CATEGORY_" property="taskType" jdbcType="VARCHAR"/>
<result column="END_TIME_" property="finishedTime" jdbcType="TIMESTAMP"/>
<result column="START_TIME_" property="startTime" jdbcType="TIMESTAMP"/>
<result column="CREATE_TIME_" property="createTime" jdbcType="TIMESTAMP"/>
<result column="TASK_END_TIME_" property="endTime" jdbcType="TIMESTAMP"/>
<result column="start_person" property="startPersonName" jdbcType="VARCHAR"/>
<result column="app_name" property="appName" jdbcType="VARCHAR"/>
<result column="form_type" property="formType" jdbcType="INTEGER"/>
<result column="PROC_DEF_ID_" property="processDefinitionId" jdbcType="VARCHAR"/>
<result column="start_person_code" property="startPersonCode" jdbcType="VARCHAR"/>
<result column="applied_range" property="processDefinitionType" jdbcType="INTEGER"/>
<result column="process_status" property="processStatus" jdbcType="VARCHAR"/>
<result column="form_name" property="formName" jdbcType="VARCHAR"/>
<result column="TASK_DEF_KEY_" property="taskDefKey" jdbcType="VARCHAR"/>
<result column="end_act_id_" property="endActId" jdbcType="VARCHAR"/>
<result column="end_time_" property="endTime" jdbcType="VARCHAR"/>
</resultMap>
<select id="getApplyedTasksPagerModel" resultMap="TaskVoMap">
SELECT DISTINCT
t1.ID_,
t1.NAME_,
t1.START_TIME_ as CREATE_TIME_,
t1.ASSIGNEE_,
t1.DESCRIPTION_,
t1.TASK_DEF_KEY_,
t1.DURATION_,
t2.BUSINESS_KEY_,
t2.PROC_INST_ID_,
t2.PROC_DEF_ID_,
t2.NAME_ AS proc_inst_name,
t2.START_TIME_,
t2.END_TIME_
FROM act_hi_taskinst t1
INNER JOIN act_hi_procinst t2
ON t1.PROC_INST_ID_ = t2.PROC_INST_ID_
INNER JOIN act_re_procdef t8 ON t2.PROC_DEF_ID_=t8.ID_
LEFT JOIN act_hi_identitylink t6
ON t6.TASK_ID_ = t1.ID_
<where>
<if test="params.userCode!=null and params.userCode!=''">
AND (
t1.ASSIGNEE_ = #{params.userCode,jdbcType=VARCHAR}
OR (
(
t1.ASSIGNEE_ IS NULL
OR t1.ASSIGNEE_ = ''
)
AND (
t6.USER_ID_ = #{params.userCode,jdbcType=VARCHAR}
OR t6.GROUP_ID_ IN (
SELECT
g.group_id_
FROM
act_id_membership g
WHERE
g.user_id_ = #{params.userCode,jdbcType=VARCHAR})
)
)
)
</if>
<if test="params.keyword!=null and params.keyword!=''">
AND t2.NAME_ LIKE CONCAT('%',#{params.keyword},'%')
</if>
<if test="params.startTime!=null and params.startTime!=''">
AND t2.START_TIME_ <![CDATA[ >= ]]> #{params.startTime}
</if>
<if test="params.endTime!=null and params.endTime!=''">
AND t2.START_TIME_ <![CDATA[ <= ]]> #{params.endTime}
</if>
<if test="params.businessKey!=null and params.businessKey!=''">
AND t2.BUSINESS_KEY_ LIKE CONCAT('%',#{params.businessKey},'%')
</if>
</where>
ORDER BY t1.START_TIME_ DESC
</select>
<select id="finishedList" resultType="java.util.Map">
SELECT * FROM (
SELECT DISTINCT
ahti.ID_,
ahti.NAME_,
ahti.ASSIGNEE_,
ahti.START_TIME_,
ahpi.END_ACT_ID_,
ahpi.END_TIME_,
ahpi.PROC_DEF_ID_,
ahpi.PROC_INST_ID_,
arpd.KEY_ AS PROC_DEF_KEY_,
arpd.NAME_ AS PROC_DEF_NAME_,
arpd.VERSION_ AS PROC_DEF_VERSION_,
arpd.DEPLOYMENT_ID_ AS DEPLOYMENT_ID_
FROM ACT_HI_PROCINST ahpi
INNER JOIN (SELECT PROC_INST_ID_ from ACT_HI_TASKINST WHERE ASSIGNEE_=#{userSid} AND END_TIME_ IS NOT NULL)
temp ON ahpi.PROC_INST_ID_=temp.PROC_INST_ID_
LEFT JOIN ACT_HI_TASKINST ahti on ahti.PROC_INST_ID_=temp.PROC_INST_ID_
INNER JOIN `ACT_HI_VARINST` A0 ON ahpi.PROC_INST_ID_ = A0.PROC_INST_ID_
LEFT JOIN ACT_RE_PROCDEF arpd ON ahpi.PROC_DEF_ID_ = arpd.ID_
<where>
<foreach item="item" index="index" collection="list" separator=",">
<if test="item.symbol != null and item.symbol != ''">
AND a0.name_= #{item.filed} AND a0.text_ = #{item.value}
</if>
</foreach>
</where>
ORDER BY ahti.START_TIME_ DESC
) flow
GROUP BY flow.PROC_INST_ID_
LIMIT #{page},#{size}
</select>
<select id="finishedList1" parameterType="java.util.Map" resultType="java.util.Map">
SELECT * FROM (
SELECT DISTINCT
ahti.ID_,
ahti.NAME_,
ahti.ASSIGNEE_,
ahti.START_TIME_,
ahti.TASK_DEF_KEY_ taskDefKey,
ahpi.START_USER_ID_,
ahpi.END_ACT_ID_,
ahpi.END_TIME_,
ahpi.PROC_DEF_ID_,
ahpi.PROC_INST_ID_,
ahpi.START_TIME_ processCreateTime,
arpd.KEY_ AS PROC_DEF_KEY_,
arpd.NAME_ AS PROC_DEF_NAME_,
arpd.VERSION_ AS PROC_DEF_VERSION_,
arpd.DEPLOYMENT_ID_ AS DEPLOYMENT_ID_
/*sfl.taskDefKey AS taskDefKey,*/
/*sfl.nodeState NAME_*/
FROM ACT_HI_PROCINST ahpi
INNER JOIN (SELECT PROC_INST_ID_ from ACT_HI_TASKINST WHERE ASSIGNEE_=#{userSid} AND END_TIME_ IS NOT NULL)
temp ON ahpi.PROC_INST_ID_=temp.PROC_INST_ID_
/*LEFT JOIN ACT_HI_TASKINST ahti on ahti.PROC_INST_ID_=temp.PROC_INST_ID_*/
LEFT JOIN (SELECT * FROM (SELECT DISTINCT(ID_) ID_,NAME_,ASSIGNEE_,START_TIME_,TASK_DEF_KEY_,PROC_INST_ID_ FROM ACT_HI_TASKINST ORDER BY START_TIME_ DESC) t1 GROUP BY t1.PROC_INST_ID_) ahti ON ahti.PROC_INST_ID_ = temp.PROC_INST_ID_
INNER JOIN `ACT_HI_VARINST` A0 ON ahpi.PROC_INST_ID_ = A0.PROC_INST_ID_
LEFT JOIN ACT_RE_PROCDEF arpd ON ahpi.PROC_DEF_ID_ = arpd.ID_
LEFT JOIN sys_form_link sfl ON ahpi.PROC_INST_ID_ = sfl.procInsId
<where>
<if test="proDefName != null and proDefName != ''">
AND arpd.NAME_ LIKE concat('%',#{proDefName},'%')
</if>
<if test="startDate != null and startDate != ''">
AND ahpi.START_TIME_ <![CDATA[ >= ]]> #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND ahpi.START_TIME_ <![CDATA[ <= ]]> #{endDate}
</if>
</where>
) flow
GROUP BY flow.PROC_INST_ID_
ORDER BY flow.START_TIME_ DESC
LIMIT #{page},#{size}
</select>
<select id="finishedListCount" parameterType="java.util.Map" resultType="int">
SELECT COUNT(DISTINCT ahpi.PROC_INST_ID_)
FROM ACT_HI_PROCINST ahpi
INNER JOIN ( SELECT PROC_INST_ID_ FROM ACT_HI_TASKINST WHERE ASSIGNEE_ =#{userSid} AND END_TIME_ IS NOT NULL ) temp ON ahpi.PROC_INST_ID_ = temp.PROC_INST_ID_
LEFT JOIN ACT_HI_TASKINST ahti ON ahti.PROC_INST_ID_ = temp.PROC_INST_ID_
INNER JOIN `ACT_HI_VARINST` A0 ON ahpi.PROC_INST_ID_ = A0.PROC_INST_ID_
LEFT JOIN ACT_RE_PROCDEF arpd ON ahpi.PROC_DEF_ID_ = arpd.ID_
<where>
<if test="proDefName != null and proDefName != ''">
AND arpd.NAME_ LIKE concat('%',#{proDefName},'%')
</if>
<if test="startDate != null and startDate != ''">
AND ahpi.START_TIME_ <![CDATA[ >= ]]> #{startDate}
</if>
<if test="endDate != null and endDate != ''">
AND ahpi.START_TIME_ <![CDATA[ <= ]]> #{endDate}
</if>
</where>
</select>
<select id="getLatestTasks" resultType="com.yxt.anrui.flowable.api.flowtask.LatestTaskVo">
SELECT
task.name_ ,
task.task_def_key_ ,
task.id_,
task.ASSIGNEE_,
a.TEXT_ orgpath
FROM
act_ru_task task
LEFT JOIN `act_ru_variable` a ON task.id_= a.task_id_ AND a.name_='orgPath'
WHERE
task.proc_inst_id_= #{procId}
</select>
<select id="getHistTaskByID" resultType="java.util.Map">
SELECT
task.name_ ,
task.task_def_key_ ,
task.id_,
task.ASSIGNEE_
FROM
act_hi_taskinst task
WHERE
task.task_def_key_= #{taskId} and task.PROC_INST_ID_= #{procId} order by task.id_ desc limit 1,1
</select>
<select id="getTaskByDefKey" resultType="java.util.Map">
SELECT
task.name_ ,
task.task_def_key_ ,
task.id_,
task.ASSIGNEE_,
arv.text_ orgPath
FROM
act_ru_task task
left join act_ru_variable arv on task.id_=arv.task_id_ and arv.name_="orgPath"
WHERE
task.task_def_key_= #{taskId} and task.PROC_INST_ID_= #{procId} order by task.id_ desc limit 0,1
</select>
<select id="getActHiVarinstForOrgPath" resultType="java.util.Map">
SELECT
ahv.*
FROM
act_hi_varinst ahv
WHERE
ahv.task_id_= #{taskId} and ahv.name_="orgPath" order by ahv.id_ desc limit 0,1
</select>
</mapper>

2079
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/flowtask/FlowTaskService.java

File diff suppressed because it is too large

47
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/process/ExpressionCmd.java

@ -0,0 +1,47 @@
package com.yxt.anrui.flowable.biz.process;
import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import java.io.Serializable;
import java.util.Map;
public class ExpressionCmd implements Command<Boolean>, Serializable {
protected RuntimeService runtimeService;
protected ProcessEngineConfigurationImpl processEngineConfiguration;
protected String processInstanceId;
protected String exp;
protected Map<String, Object> variableMap;
public ExpressionCmd(RuntimeService runtimeService, ProcessEngineConfigurationImpl processEngineConfiguration, String processInstanceId, String exp, Map<String, Object> variableMap) {
this.runtimeService = runtimeService;
this.processEngineConfiguration = processEngineConfiguration;
this.processInstanceId = processInstanceId;
this.exp = exp;
this.variableMap = variableMap;
}
@Override
public Boolean execute(CommandContext commandContext) {
Expression expression = processEngineConfiguration.getExpressionManager().createExpression(this.exp);
ExecutionEntity executionEntity;
if(StringUtils.isNotBlank(this.processInstanceId)){
executionEntity = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(this.processInstanceId).includeProcessVariables().singleResult();
}else {
executionEntity = new ExecutionEntityImpl();
executionEntity.setVariables(variableMap);
}
Object value = expression.getValue(executionEntity);
return value != null && "true".equals(value.toString());
}
}

162
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/process/ProcessService.java

@ -0,0 +1,162 @@
package com.yxt.anrui.flowable.biz.process;
import com.yxt.anrui.flowable.biz.flow.FlowableService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.*;
import org.flowable.engine.ManagementService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.ui.modeler.domain.Model;
import org.flowable.ui.modeler.serviceapi.ModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Slf4j
@Service
public class ProcessService {
@Autowired
RuntimeService runtimeService;
@Autowired
RepositoryService repositoryService;
@Autowired
ModelService modelService;
@Autowired
ManagementService managementService;
@Autowired
ProcessEngineConfigurationImpl processEngineConfiguration;
@Autowired
FlowableService flowableService;
/**
* 1. 首先拿到BpmnModel所有流程定义信息都可以通过BpmnModel获取若流程尚未发起则用modelId查询最新部署的流程定义数据
* 若流程已经发起可以通过流程实例的processDefinitionId查询流程定义的历史数据
* @param variableMap 流程变量用于计算条件分支
*/
public List<FlowElement> calApprovePath(String processInstanceId, String modelId, Map<String, Object> variableMap){
BpmnModel bpmnModel=repositoryService.getBpmnModel(modelId);
// BpmnModel bpmnModel2 =repositoryService.getBpmnModel(processInstanceId);
/*if(StringUtils.isNotBlank(processInstanceId)){
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
}else {
Model model = modelService.getModel(modelId);
bpmnModel = modelService.getBpmnModel(model);
}*/
Collection<FlowElement> flowElements =new ArrayList<>();
Collection<FlowElement> flowElements2 = bpmnModel.getMainProcess().getFlowElements();
flowElements.addAll(flowElements2);
List<FlowElement> passElements = new ArrayList<>();
dueStartElement(passElements, flowElements, variableMap);
return passElements;
}
/**
* 2. 找到开始节点通过它的目标节点然后再不断往下找
*/
private void dueStartElement(List<FlowElement> passElements, Collection<FlowElement> flowElements, Map<String, Object> variableMap){
Optional<FlowElement> startElementOpt = flowElements.stream().filter(flowElement -> flowElement instanceof StartEvent).findFirst();
startElementOpt.ifPresent(startElement -> {
flowElements.remove(startElement);
List<SequenceFlow> outgoingFlows = ((StartEvent) startElement).getOutgoingFlows();
String targetRef = outgoingFlows.get(0).getTargetRef();
// 根据ID找到FlowElement
FlowElement targetElementOfStartElement = getFlowElement(flowElements, targetRef);
if (targetElementOfStartElement instanceof UserTask) {
this.getPassElementList(passElements, flowElements, targetElementOfStartElement, variableMap);
}
});
}
/**
* 3. 我只用到了UserTaskExclusiveGatewayParallelGateway所以代码里只列举了这三种如果用到了其他的可以再自己补充
*/
private void getPassElementList(List<FlowElement> passElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap){
// 任务节点
if (curFlowElement instanceof UserTask) {
this.dueUserTaskElement(passElements, flowElements, curFlowElement, variableMap);
return;
}
// 排他网关
if (curFlowElement instanceof ExclusiveGateway) {
this.dueExclusiveGateway(passElements, flowElements, curFlowElement, variableMap);
return;
}
// 并行网关
if(curFlowElement instanceof ParallelGateway){
this.dueParallelGateway(passElements, flowElements, curFlowElement, variableMap);
}
}
private void dueUserTaskElement(List<FlowElement> passElements, Collection<FlowElement> flowElements,
FlowElement curFlowElement, Map<String, Object> variableMap){
passElements.add(curFlowElement);
List<SequenceFlow> outgoingFlows = ((UserTask) curFlowElement).getOutgoingFlows();
String targetRef = outgoingFlows.get(0).getTargetRef();
if (outgoingFlows.size() > 1) {
// 找到表达式成立的sequenceFlow
SequenceFlow sequenceFlow = getSequenceFlow(variableMap, outgoingFlows);
targetRef = sequenceFlow.getTargetRef();
}
// 根据ID找到FlowElement
FlowElement targetElement = getFlowElement(flowElements, targetRef);
this.getPassElementList(passElements, flowElements, targetElement, variableMap);
}
private void dueExclusiveGateway(List<FlowElement> passElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap){
// 获取符合条件的sequenceFlow的目标FlowElement
List<SequenceFlow> exclusiveGatewayOutgoingFlows = ((ExclusiveGateway) curFlowElement).getOutgoingFlows();
flowElements.remove(curFlowElement);
// 找到表达式成立的sequenceFlow
SequenceFlow sequenceFlow = getSequenceFlow(variableMap, exclusiveGatewayOutgoingFlows);
// 根据ID找到FlowElement
FlowElement targetElement = getFlowElement(flowElements, sequenceFlow.getTargetRef());
this.getPassElementList(passElements, flowElements, targetElement, variableMap);
}
private void dueParallelGateway(List<FlowElement> passElements, Collection<FlowElement> flowElements, FlowElement curFlowElement, Map<String, Object> variableMap){
FlowElement targetElement;
List<SequenceFlow> parallelGatewayOutgoingFlows = ((ParallelGateway) curFlowElement).getOutgoingFlows();
for(SequenceFlow sequenceFlow : parallelGatewayOutgoingFlows){
targetElement = getFlowElement(flowElements, sequenceFlow.getTargetRef());
this.getPassElementList(passElements, flowElements, targetElement, variableMap);
}
}
private FlowElement getFlowElement(Collection<FlowElement> flowElements, String targetRef) {
return flowElements.stream().filter(flowElement -> targetRef.equals(flowElement.getId())).findFirst().orElse(null);
}
/**
* 4. 根据传入的变量计算出表达式成立的那一条SequenceFlow
* @param variableMap
* @param outgoingFlows
* @return
*/
private SequenceFlow getSequenceFlow(Map<String, Object> variableMap, List<SequenceFlow> outgoingFlows) {
Optional<SequenceFlow> sequenceFlowOpt = outgoingFlows.stream().filter(item -> {
try {
return this.getElValue(item.getConditionExpression(), variableMap);
} catch (Exception e) {
return false;
}
}).findFirst();
return sequenceFlowOpt.orElse(outgoingFlows.get(0));
}
private boolean getElValue(String exp, Map<String, Object> variableMap){
return managementService.executeCommand(new ExpressionCmd(runtimeService, processEngineConfiguration, null, exp, variableMap));
}
public Map<String, String> getProcessInstanceById(String procInsId) {
return flowableService.getProcessInstanceById(procInsId);
}
}

72
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentMapper.java

@ -0,0 +1,72 @@
/*********************************************************
*********************************************************
******************** *******************
************* ************
******* _oo0oo_ *******
*** o8888888o ***
* 88" . "88 *
* (| -_- |) *
* 0\ = /0 *
* ___/`---'\___ *
* .' \\| |// '. *
* / \\||| : |||// \ *
* / _||||| -:- |||||- \ *
* | | \\\ - /// | | *
* | \_| ''\---/'' |_/ | *
* \ .-\__ '-' ___/-. / *
* ___'. .' /--.--\ `. .'___ *
* ."" '< `.___\_<|>_/___.' >' "". *
* | | : `- \`.;`\ _ /`;.`/ - ` : | | *
* \ \ `_. \_ __\ /__ _/ .-` / / *
* =====`-.____`.___ \_____/___.-`___.-'===== *
* `=---=' *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
*********__佛祖保佑__永无BUG__验收通过__钞票多多__*********
*********************************************************/
package com.yxt.anrui.flowable.biz.processcomment;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.yxt.anrui.flowable.api.processcomment.ProcessComment;
import com.yxt.anrui.flowable.api.processcomment.ProcessCommentDto;
import com.yxt.anrui.flowable.api.processcomment.ProcessCommentVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* Project: processcomment(流程评论) <br/>
* File: ProcessCommentMapper.java <br/>
* Class: com.yxt.anrui.flowable.api.processcomment.biz.processcomment.ProcessCommentMapper <br/>
* Description: process_comment. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2023-01-30 14:40:37 <br/>
*
* @author liupopo
* @version 1.0
* @since 1.0
*/
@Mapper
public interface ProcessCommentMapper extends BaseMapper<ProcessComment> {
//@Update("update process_comment set name=#{msg} where id=#{id}")
//IPage<ProcessCommentVo> voPage(IPage<ProcessComment> page, @Param(Constants.WRAPPER) QueryWrapper<ProcessComment> qw);
IPage<ProcessCommentVo> selectPageVo(IPage<ProcessComment> page, @Param(Constants.WRAPPER) Wrapper<ProcessComment> qw);
List<ProcessCommentVo> selectListAllVo(@Param(Constants.WRAPPER) Wrapper<ProcessComment> qw);
@Select("select * from process_comment")
List<ProcessCommentVo> selectListVo();
List<ProcessCommentVo> getCommentList(@Param("processId")String processId);
@Select("select * from process_comment where sid=#{sid}")
ProcessComment fetchBySid(@Param("sid")String sid);
void insertByDto(ProcessCommentDto dto);
}

20
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentMapper.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.processcomment.ProcessCommentMapper">
<!-- <where> ${ew.sqlSegment} </where>-->
<!-- ${ew.customSqlSegment} -->
<select id="selectPageVo" resultType="com.yxt.anrui.flowable.api.processcomment.ProcessCommentVo">
SELECT * FROM process_comment <where> ${ew.sqlSegment} </where>
</select>
<select id="selectListAllVo" resultType="com.yxt.anrui.flowable.api.processcomment.ProcessCommentVo">
SELECT * FROM process_comment <where> ${ew.sqlSegment} </where>
</select>
<select id="getCommentList" resultType="com.yxt.anrui.flowable.api.processcomment.ProcessCommentVo">
select * from process_comment where processId=#{processId}
</select>
<insert id="insertByDto" parameterType="com.yxt.anrui.flowable.api.processcomment.ProcessCommentDto">
insert into `process_comment` ( `sid`, `reviewer`, `reviewerSid`, `time`, `content`, `processId`, `processInstSid`)
values(#{sid},#{reviewer},#{reviewerSid},#{time},#{content},#{processId},#{processInstSid});
</insert>
</mapper>

105
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentRest.java

@ -0,0 +1,105 @@
/*********************************************************
*********************************************************
******************** *******************
************* ************
******* _oo0oo_ *******
*** o8888888o ***
* 88" . "88 *
* (| -_- |) *
* 0\ = /0 *
* ___/`---'\___ *
* .' \\| |// '. *
* / \\||| : |||// \ *
* / _||||| -:- |||||- \ *
* | | \\\ - /// | | *
* | \_| ''\---/'' |_/ | *
* \ .-\__ '-' ___/-. / *
* ___'. .' /--.--\ `. .'___ *
* ."" '< `.___\_<|>_/___.' >' "". *
* | | : `- \`.;`\ _ /`;.`/ - ` : | | *
* \ \ `_. \_ __\ /__ _/ .-` / / *
* =====`-.____`.___ \_____/___.-`___.-'===== *
* `=---=' *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
*********__佛祖保佑__永无BUG__验收通过__钞票多多__*********
*********************************************************/
package com.yxt.anrui.flowable.biz.processcomment;
import com.yxt.anrui.flowable.api.processcomment.*;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import com.yxt.common.core.vo.PagerVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* Project: processcomment(流程评论) <br/>
* File: ProcessCommentFeignFallback.java <br/>
* Class: com.yxt.anrui.flowable.api.processcomment.biz.processcomment.ProcessCommentRest <br/>
* Description: process_comment. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2023-01-30 14:40:37 <br/>
*
* @author liupopo
* @version 1.0
* @since 1.0
*/
@Api(tags = "process_comment")
@RestController
@RequestMapping("v1/processcomment")
public class ProcessCommentRest implements ProcessCommentFeign {
@Autowired
private ProcessCommentService processCommentService;
@Override
@ApiOperation("根据条件分页查询数据的列表")
@PostMapping("/listPage")
public ResultBean<PagerVo<ProcessCommentVo>> listPage(@RequestBody PagerQuery<ProcessCommentQuery> pq){
ResultBean rb = ResultBean.fireFail();
PagerVo<ProcessCommentVo> pv = processCommentService.listPageVo(pq);
return rb.success().setData(pv);
}
@Override
@ApiOperation("新增或修改")
@PostMapping("/save")
public ResultBean save(@RequestBody ProcessCommentDto dto){
ResultBean rb = ResultBean.fireFail();
dto.setTime(new Date());
processCommentService.saveOrUpdateDto(dto);
return rb.success();
}
@Override
@ApiOperation("根据sid批量删除")
@PostMapping("/delBySids")
public ResultBean delBySids(@RequestBody String[] sids){
ResultBean rb = ResultBean.fireFail();
processCommentService.delBySids(sids);
return rb.success();
}
@Override
@ApiOperation("根据SID获取一条记录")
@GetMapping("/fetchDetailsBySid/{sid}")
public ResultBean<ProcessCommentDetailsVo> fetchDetailsBySid(@PathVariable("sid") String sid){
ResultBean rb = ResultBean.fireFail();
ProcessCommentDetailsVo vo = processCommentService.fetchDetailsVoBySid(sid);
return rb.success().setData(vo);
}
@Override
public ResultBean<List<ProcessCommentVo>> getCommentList(String processId) {
ResultBean rb = ResultBean.fireFail();
List<ProcessCommentVo> vo = processCommentService.getCommentList(processId);
return rb.success().setData(vo);
}
}

135
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/processcomment/ProcessCommentService.java

@ -0,0 +1,135 @@
/*********************************************************
*********************************************************
******************** *******************
************* ************
******* _oo0oo_ *******
*** o8888888o ***
* 88" . "88 *
* (| -_- |) *
* 0\ = /0 *
* ___/`---'\___ *
* .' \\| |// '. *
* / \\||| : |||// \ *
* / _||||| -:- |||||- \ *
* | | \\\ - /// | | *
* | \_| ''\---/'' |_/ | *
* \ .-\__ '-' ___/-. / *
* ___'. .' /--.--\ `. .'___ *
* ."" '< `.___\_<|>_/___.' >' "". *
* | | : `- \`.;`\ _ /`;.`/ - ` : | | *
* \ \ `_. \_ __\ /__ _/ .-` / / *
* =====`-.____`.___ \_____/___.-`___.-'===== *
* `=---=' *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
*********__佛祖保佑__永无BUG__验收通过__钞票多多__*********
*********************************************************/
package com.yxt.anrui.flowable.biz.processcomment;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yxt.anrui.flowable.api.flowtask.AppUserVo;
import com.yxt.anrui.flowable.api.flowtask.TaskUserInfo;
import com.yxt.anrui.flowable.api.processcomment.*;
import com.yxt.common.base.config.component.FileUploadComponent;
import com.yxt.supervise.system.sysuser.SysUserFeign;
import com.yxt.supervise.system.sysuser.SysUserVo;
import org.apache.commons.lang3.StringUtils;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.base.utils.PagerUtil;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import com.yxt.common.core.vo.PagerVo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Project: processcomment(流程评论) <br/>
* File: ProcessCommentService.java <br/>
* Class: com.yxt.anrui.flowable.api.processcomment.biz.processcomment.ProcessCommentService <br/>
* Description: process_comment 业务逻辑. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2023-01-30 14:40:37 <br/>
*
* @author liupopo
* @version 1.0
* @since 1.0
*/
@Service
public class ProcessCommentService extends MybatisBaseService<ProcessCommentMapper, ProcessComment> {
@Resource
private SysUserFeign sysUserFeign;
@Resource
private FileUploadComponent fileUploadComponent;
private QueryWrapper<ProcessComment> createQueryWrapper(ProcessCommentQuery query) {
// todo: 这里根据具体业务调整查询条件
// 多字段Like示例:qw.and(wrapper -> wrapper.like("name", query.getName()).or().like("remark", query.getName()));
QueryWrapper<ProcessComment> qw = new QueryWrapper<>();
return qw;
}
public PagerVo<ProcessCommentVo> listPageVo(PagerQuery<ProcessCommentQuery> pq) {
ProcessCommentQuery query = pq.getParams();
QueryWrapper<ProcessComment> qw = createQueryWrapper(query);
IPage<ProcessComment> page = PagerUtil.queryToPage(pq);
IPage<ProcessCommentVo> pagging = baseMapper.selectPageVo(page, qw);
PagerVo<ProcessCommentVo> p = PagerUtil.pageToVo(pagging, null);
return p;
}
public void saveOrUpdateDto(ProcessCommentDto dto){
String dtoSid = dto.getSid();
if (StringUtils.isBlank(dtoSid)) {
dto.setSid(UUID.randomUUID().toString());
baseMapper.insertByDto(dto);
return;
}
this.updateByDto(dto);
}
public void insertByDto(ProcessCommentDto dto){
ProcessComment entity = new ProcessComment();
BeanUtil.copyProperties(dto, entity, "id", "sid");
baseMapper.insert(entity);
}
public void updateByDto(ProcessCommentDto dto){
String dtoSid = dto.getSid();
if (StringUtils.isBlank(dtoSid)) {
return;
}
ProcessComment entity = fetchBySid(dtoSid);
BeanUtil.copyProperties(dto, entity, "id", "sid");
baseMapper.updateById(entity);
}
public ProcessCommentDetailsVo fetchDetailsVoBySid(String sid){
ProcessComment entity = fetchBySid(sid);
ProcessCommentDetailsVo vo = new ProcessCommentDetailsVo();
BeanUtil.copyProperties(entity, vo);
return vo;
}
public List<ProcessCommentVo> getCommentList(String processId) {
List<ProcessCommentVo> commentList = baseMapper.getCommentList(processId);
for(ProcessCommentVo histIns:commentList){
ResultBean<List<SysUserVo>> sysUserVoResultBean = sysUserFeign.fetchBySids(histIns.getReviewerSid());// sysUserService.selectUserById(Long.parseLong(histIns.getAssignee()));
List<SysUserVo> data1 = sysUserVoResultBean.getData();
for( SysUserVo data:data1){
AppUserVo taskUserInfo=new AppUserVo();
taskUserInfo.setAssigneeName(data.getName());
if(!com.yxt.common.base.utils.StringUtils.isBlank(data.getHeadImage())){
taskUserInfo.setAssigneeHeadImage(fileUploadComponent.getUrlPrefix() +data.getHeadImage());
}
histIns.setTaskUserInfo(taskUserInfo);
}
}
return commentList;
}
}

364
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/service/impl/FlowTaskServiceImpl.java

@ -0,0 +1,364 @@
package com.yxt.anrui.flowable.biz.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.yxt.anrui.flowable.api.flowcomment.FlowCommentDto;
import com.yxt.anrui.flowable.api.flowtask.FlowTaskDto;
import com.yxt.anrui.flowable.api.flowtask.CompleteTaskQuery;
import com.yxt.anrui.flowable.api.flowtask.FlowTaskQuery;
import com.yxt.anrui.flowable.api.flowtask.FlowTaskQueryOne;
import com.yxt.anrui.flowable.api.flowcomment.FlowComment;
import com.yxt.anrui.flowable.factory.FlowServiceFactory;
import com.yxt.anrui.flowable.test.StartProcessInstanceQuery;
import com.yxt.anrui.flowable.utils.FlowableUtils;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import com.yxt.supervise.system.sysuser.SysUserFeign;
import com.yxt.supervise.system.sysuser.SysUserVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.history.HistoricIdentityLink;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author dimengzhe
* @date 2021/7/29 15:33
* @description
*/
@Service
public class FlowTaskServiceImpl extends FlowServiceFactory {
@Autowired
private SysUserFeign sysUserFeign;
public ResultBean<ProcessInstance> startProcessInstanceByKey(StartProcessInstanceQuery params) {
ResultBean<ProcessInstance> returnVo = ResultBean.fireSuccess();
if (StringUtils.isNotBlank(params.getProcessDefinitionId())) {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(params.getProcessDefinitionId())
.latestVersion().singleResult();
if (processDefinition != null && processDefinition.isSuspended()) {
returnVo = new ResultBean<ProcessInstance>().fail().setMsg("此流程已经挂起,请联系系统管理员!");
return returnVo;
}
ResultBean<SysUserVo> user = sysUserFeign.fetchBySid(params.getUserSid());
if (!user.getSuccess()) {
returnVo = new ResultBean<ProcessInstance>().fail().setMsg("当前发起人不存在,请确认");
return returnVo;
}
identityService.setAuthenticatedUserId(params.getUserSid());
ProcessInstance processInstance = runtimeService.startProcessInstanceById(params.getProcessDefinitionId(), params.getVariables());
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
if (Objects.nonNull(task)) {
taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.START.getType(), params.getUserSid() + "发起流程申请");
taskService.complete(task.getId(), params.getVariables());
}
returnVo.setData(processInstance);
} else {
returnVo = new ResultBean<ProcessInstance>().fail().setMsg("Parameters should not be null");
}
return returnVo;
}
public ResultBean todoList(PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
int pageNum = (int) taskQueryPagerQuery.getCurrent();//当前页
int pageSize = (int) taskQueryPagerQuery.getSize();//每页条数
String userSid = taskQueryPagerQuery.getParams().getUserSid();
Page<FlowTaskDto> page = new Page<>();
TaskQuery taskQuery = taskService.createTaskQuery()
.processVariableValueEquals("zd","12")
// .taskVariableValueEquals("zd","12")
.active()
.includeProcessVariables()
.taskAssignee(userSid)
.orderByTaskCreateTime().desc();
page.setTotal(taskQuery.count());
List<Task> taskList = taskQuery.listPage(pageNum - 1, pageSize);
List<FlowTaskDto> flowList = new ArrayList<>();
for (Task task : taskList) {
FlowTaskDto flowTask = new FlowTaskDto();
// 当前流程信息
flowTask.setTaskId(task.getId());//任务编号
flowTask.setTaskDefKey(task.getTaskDefinitionKey());//任务定义key
flowTask.setCreateTime(task.getCreateTime());//任务创建时间
flowTask.setProcDefId(task.getProcessDefinitionId());//流程id
flowTask.setTaskName(task.getName());//任务名称
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(task.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());//流程部署编号
flowTask.setProcDefName(pd.getName());//流程定义名称
flowTask.setProcDefVersion(pd.getVersion());//流程定义内置使用版本
flowTask.setProcInsId(task.getProcessInstanceId());//流程实例ID
// 流程发起人信息
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.singleResult();
ResultBean<SysUserVo> startUser = sysUserFeign.fetchBySid(historicProcessInstance.getStartUserId());
if (!startUser.getSuccess()) {
return ResultBean.fireFail().setMsg("当前流程发起人不存在");
}
flowTask.setStartUserSid(startUser.getData().getSid());
flowTask.setStartUserName(startUser.getData().getName());
flowList.add(flowTask);
}
page.setRecords(flowList);
return ResultBean.fireSuccess().setData(page);
}
public ResultBean doneList(PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
int pageNum = (int) taskQueryPagerQuery.getCurrent();//当前页
int pageSize = (int) taskQueryPagerQuery.getSize();//每页条数
String userSid = taskQueryPagerQuery.getParams().getUserSid();
Page<FlowTaskDto> page = new Page<>();
HistoricTaskInstanceQuery taskInstanceQuery = historyService.createHistoricTaskInstanceQuery()
.includeProcessVariables()
.finished()
.taskAssignee(userSid)
.orderByHistoricTaskInstanceEndTime()
.desc();
List<HistoricTaskInstance> historicTaskInstanceList = taskInstanceQuery.listPage(pageNum - 1, pageSize);
List<FlowTaskDto> hisTaskList = Lists.newArrayList();
for (HistoricTaskInstance histTask : historicTaskInstanceList) {
FlowTaskDto flowTask = new FlowTaskDto();
// 当前流程信息
flowTask.setTaskId(histTask.getId());
// 审批人员信息
flowTask.setCreateTime(histTask.getCreateTime());
flowTask.setFinishTime(histTask.getEndTime());
flowTask.setDuration(FlowableUtils.getDate(histTask.getDurationInMillis()));
flowTask.setProcDefId(histTask.getProcessDefinitionId());
flowTask.setTaskDefKey(histTask.getTaskDefinitionKey());
flowTask.setTaskName(histTask.getName());
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(histTask.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());
flowTask.setProcDefName(pd.getName());
flowTask.setProcDefVersion(pd.getVersion());
flowTask.setProcInsId(histTask.getProcessInstanceId());
flowTask.setHisProcInsId(histTask.getProcessInstanceId());
// 流程发起人信息
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(histTask.getProcessInstanceId())
.singleResult();
ResultBean<SysUserVo> startUser = sysUserFeign.fetchBySid(historicProcessInstance.getStartUserId());
if (!startUser.getSuccess()) {
return ResultBean.fireFail().setMsg("当前流程发起人不存在");
}
flowTask.setStartUserSid(startUser.getData().getSid());
flowTask.setStartUserName(startUser.getData().getName());
hisTaskList.add(flowTask);
}
page.setTotal(hisTaskList.size());
page.setRecords(hisTaskList);
return ResultBean.fireSuccess().setData(page);
}
public ResultBean complete(CompleteTaskQuery completeTaskQuery) {
Task task = taskService.createTaskQuery().taskId(completeTaskQuery.getTaskId()).singleResult();
if (Objects.isNull(task)) {
return ResultBean.fireFail().setMsg("任务不存在");
}
if (DelegationState.PENDING.equals(task.getDelegationState())) {
taskService.addComment(completeTaskQuery.getTaskId(), completeTaskQuery.getInstanceId(), FlowComment.DELEGATE.getType(), completeTaskQuery.getComment());
taskService.resolveTask(completeTaskQuery.getTaskId(), completeTaskQuery.getVariables());
} else {
taskService.addComment(completeTaskQuery.getTaskId(), completeTaskQuery.getInstanceId(), FlowComment.NORMAL.getType(), completeTaskQuery.getComment());
ResultBean<SysUserVo> startUser = sysUserFeign.fetchBySid(completeTaskQuery.getUserSid());
if (!startUser.getSuccess()) {
return ResultBean.fireFail().setMsg("当前流程发起人不存在");
}
taskService.setAssignee(completeTaskQuery.getTaskId(), startUser.getData().getSid());
taskService.complete(completeTaskQuery.getTaskId(), completeTaskQuery.getVariables());
}
return ResultBean.fireSuccess();
}
public ResultBean flowRecord(String procInsId, String deployId) {
Map<String, Object> map = new HashMap();
if (org.apache.commons.lang3.StringUtils.isNotBlank(procInsId)) {
List<HistoricActivityInstance> list = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(procInsId)
.orderByHistoricActivityInstanceStartTime()
.desc().list();
List<FlowTaskDto> hisFlowList = new ArrayList<>();
for (HistoricActivityInstance histIns : list) {
if (StringUtils.isNotBlank(histIns.getTaskId())) {
FlowTaskDto flowTask = new FlowTaskDto();
flowTask.setTaskId(histIns.getTaskId());
flowTask.setTaskName(histIns.getActivityName());
flowTask.setCreateTime(histIns.getStartTime());
flowTask.setFinishTime(histIns.getEndTime());
if (StringUtils.isNotBlank(histIns.getAssignee())) {
ResultBean<SysUserVo> sysUser = sysUserFeign.fetchBySid(histIns.getAssignee());
if (!sysUser.getSuccess()) {
return ResultBean.fireFail().setMsg("当前流程发起人不存在");
}
flowTask.setAssigneeSid(sysUser.getData().getSid());
flowTask.setAssigneeName(sysUser.getData().getName());
flowTask.setDeptName(sysUser.getData().getDepartmentName());
}
// 展示审批人员
List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(histIns.getTaskId());
StringBuilder stringBuilder = new StringBuilder();
for (HistoricIdentityLink identityLink : linksForTask) {
if ("candidate".equals(identityLink.getType())) {
if (StringUtils.isNotBlank(identityLink.getUserId())) {
ResultBean<SysUserVo> sysUser = sysUserFeign.fetchBySid(identityLink.getUserId());
stringBuilder.append(sysUser.getData().getName()).append(",");
}
}
}
if (org.apache.commons.lang3.StringUtils.isNotBlank(stringBuilder)) {
flowTask.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
}
flowTask.setDuration(histIns.getDurationInMillis() == null || histIns.getDurationInMillis() == 0 ? null :FlowableUtils.getDate(histIns.getDurationInMillis()));
// 获取意见评论内容
List<Comment> commentList = taskService.getProcessInstanceComments(histIns.getProcessInstanceId());
commentList.forEach(comment -> {
if (histIns.getTaskId().equals(comment.getTaskId())) {
flowTask.setComment(FlowCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
}
});
hisFlowList.add(flowTask);
}
}
map.put("flowList", hisFlowList);
}
// 第一次申请获取初始化表单
/* if (StringUtils.isNotBlank(deployId)) {
SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId);
if (Objects.isNull(sysForm)) {
return AjaxResult.error("请先配置流程表单");
}
map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));
}*/
return ResultBean.fireSuccess().setData(map);
}
public ResultBean stopProcess(FlowTaskQueryOne flowTaskQueryOne) {
List<Task> task = taskService.createTaskQuery().processInstanceId(flowTaskQueryOne.getInstanceId()).list();
if (CollectionUtils.isEmpty(task)) {
return ResultBean.fireFail().setMsg("流程未启动或已执行完成,取消申请失败");
}
ResultBean<SysUserVo> sysUserVoResultBean = sysUserFeign.fetchBySid(flowTaskQueryOne.getUserSid());
if (!sysUserVoResultBean.getSuccess()) {
return ResultBean.fireFail().setMsg("该申请的申请人不存在");
}
ProcessInstance processInstance =
runtimeService.createProcessInstanceQuery().processInstanceId(flowTaskQueryOne.getInstanceId()).singleResult();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
if (Objects.nonNull(bpmnModel)) {
Process process = bpmnModel.getMainProcess();
List<EndEvent> endNodes = process.findFlowElementsOfType(EndEvent.class, false);
if (CollectionUtils.isNotEmpty(endNodes)) {
Authentication.setAuthenticatedUserId(sysUserVoResultBean.getData().getSid());
String endId = endNodes.get(0).getId();
List<Execution> executions =
runtimeService.createExecutionQuery().parentId(processInstance.getProcessInstanceId()).list();
List<String> executionIds = new ArrayList<>();
executions.forEach(execution -> executionIds.add(execution.getId()));
runtimeService.createChangeActivityStateBuilder().moveExecutionsToSingleActivityId(executionIds,
endId).changeState();
}
}
return ResultBean.fireSuccess();
}
public ResultBean myprocess(PagerQuery<FlowTaskQuery> taskQueryPagerQuery) {
int pageNum = (int) taskQueryPagerQuery.getCurrent();//当前页
int pageSize = (int) taskQueryPagerQuery.getSize();//每页条数
String userSid = taskQueryPagerQuery.getParams().getUserSid();
Page<FlowTaskDto> page = new Page<>();
List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery()
.startedBy(userSid)
.orderByProcessInstanceStartTime()
.desc()
.listPage(pageNum - 1, pageSize);
page.setTotal(historicProcessInstances.size());
List<FlowTaskDto> flowList = new ArrayList<>();
for (HistoricProcessInstance hisIns : historicProcessInstances) {
FlowTaskDto flowTask = new FlowTaskDto();
flowTask.setCreateTime(hisIns.getStartTime());
flowTask.setFinishTime(hisIns.getEndTime());
flowTask.setProcInsId(hisIns.getId());
// 计算耗时
if (Objects.nonNull(hisIns.getEndTime())) {
long time = hisIns.getEndTime().getTime() - hisIns.getStartTime().getTime();
flowTask.setDuration(FlowableUtils.getDate(time));
} else {
long time = System.currentTimeMillis() - hisIns.getStartTime().getTime();
flowTask.setDuration(FlowableUtils.getDate(time));
}
// 流程定义信息
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(hisIns.getProcessDefinitionId())
.singleResult();
flowTask.setDeployId(pd.getDeploymentId());
flowTask.setProcDefName(pd.getName());
flowTask.setProcDefVersion(pd.getVersion());
flowTask.setCategory(pd.getCategory());
flowTask.setProcDefVersion(pd.getVersion());
// 当前所处流程
List<Task> taskList = taskService.createTaskQuery().processInstanceId(hisIns.getId()).list();
if (CollectionUtils.isNotEmpty(taskList)) {
flowTask.setTaskId(taskList.get(0).getId());
} else {
List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(hisIns.getId()).orderByHistoricTaskInstanceEndTime().desc().list();
flowTask.setTaskId(historicTaskInstance.get(0).getId());
}
flowList.add(flowTask);
}
page.setRecords(flowList);
return ResultBean.fireSuccess().setData(page);
}
public ResultBean processVariables(String taskId) {
HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().includeProcessVariables().finished().taskId(taskId).singleResult();
if (Objects.nonNull(historicTaskInstance)) {
return ResultBean.fireSuccess().setData(historicTaskInstance.getProcessVariables());
} else {
Map<String, Object> variables = taskService.getVariables(taskId);
return ResultBean.fireSuccess().setData(variables);
}
}
public ResultBean getNextFlowNode(FlowTaskQueryOne flowTaskQueryOne) {
return null;
}
}

74
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysdeployform/SysDeployFormMapper.java

@ -0,0 +1,74 @@
package com.yxt.anrui.flowable.biz.sysdeployform;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 流程实例关联表单Mapper接口
*
* @author XuanXuan Xuan
* @date 2021-03-30
*/
@Mapper
public interface SysDeployFormMapper extends BaseMapper<SysDeployForm> {
/**
* 查询流程实例关联表单
*
* @param id 流程实例关联表单ID
* @return 流程实例关联表单
*/
public SysDeployForm selectSysDeployFormById(Long id);
/**
* 查询流程实例关联表单列表
*
* @param SysDeployForm 流程实例关联表单
* @return 流程实例关联表单集合
*/
public List<SysDeployForm> selectSysDeployFormList(SysDeployForm SysDeployForm);
/**
* 新增流程实例关联表单
*
* @param SysDeployForm 流程实例关联表单
* @return 结果
*/
public int insertSysDeployForm(SysDeployForm SysDeployForm);
/**
* 修改流程实例关联表单
*
* @param SysDeployForm 流程实例关联表单
* @return 结果
*/
public int updateSysDeployForm(SysDeployForm SysDeployForm);
/**
* 删除流程实例关联表单
*
* @param id 流程实例关联表单ID
* @return 结果
*/
public int deleteSysDeployFormById(Long id);
/**
* 批量删除流程实例关联表单
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteSysDeployFormByIds(Long[] ids);
/**
* 查询流程挂着的表单
* @param deployId
* @return
*/
SysForm selectSysDeployFormByDeployId(String deployId);
}

66
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysdeployform/SysDeployFormMapper.xml

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.sysdeployform.SysDeployFormMapper">
<resultMap type="com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm" id="SysDeployFormResult">
<result property="id" column="id" />
<result property="formId" column="form_id" />
<result property="deployId" column="deploy_id" />
</resultMap>
<sql id="selectSysDeployFormVo">
select id, form_id, deploy_id from sys_deploy_form
</sql>
<select id="selectSysDeployFormList" parameterType="com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm" resultMap="SysDeployFormResult">
<include refid="selectSysDeployFormVo"/>
<where>
<if test="formId != null "> and form_id = #{formId}</if>
<if test="deployId != null and deployId != ''"> and deploy_id = #{deployId}</if>
</where>
</select>
<select id="selectSysDeployFormById" parameterType="Long" resultMap="SysDeployFormResult">
<include refid="selectSysDeployFormVo"/>
where id = #{id}
</select>
<select id="selectSysDeployFormByDeployId" resultType="com.yxt.anrui.flowable.api.sysform.SysForm">
select t1.form_content as formContent,t1.form_name as formName,t1.id as id from sys_form t1 left join sys_deploy_form t2 on t1.id = t2.form_id
where t2.deploy_id = #{deployId}
</select>
<insert id="insertSysDeployForm" parameterType="com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm" useGeneratedKeys="true" keyProperty="id">
insert into sys_deploy_form
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="formId != null">form_id,</if>
<if test="deployId != null">deploy_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="formId != null">#{formId},</if>
<if test="deployId != null">#{deployId},</if>
</trim>
</insert>
<update id="updateSysDeployForm" parameterType="com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm">
update sys_deploy_form
<trim prefix="SET" suffixOverrides=",">
<if test="formId != null">form_id = #{formId},</if>
<if test="deployId != null">deploy_id = #{deployId},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSysDeployFormById" parameterType="Long">
delete from sys_deploy_form where id = #{id}
</delete>
<delete id="deleteSysDeployFormByIds" parameterType="String">
delete from sys_deploy_form where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

94
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysdeployform/SysDeployFormService.java

@ -0,0 +1,94 @@
package com.yxt.anrui.flowable.biz.sysdeployform;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm;
import com.yxt.common.base.service.MybatisBaseService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 流程实例关联表单Service业务层处理
*
* @author XuanXuan Xuan
* @date 2021-04-03
*/
@Service
public class SysDeployFormService extends MybatisBaseService<SysDeployFormMapper, SysDeployForm> {
/**
* 查询流程实例关联表单
*
* @param id 流程实例关联表单ID
* @return 流程实例关联表单
*/
public SysDeployForm selectSysDeployFormById(Long id)
{
return baseMapper.selectSysDeployFormById(id);
}
/**
* 查询流程实例关联表单列表
*
* @param sysDeployForm 流程实例关联表单
* @return 流程实例关联表单
*/
public List<SysDeployForm> selectSysDeployFormList(SysDeployForm sysDeployForm)
{
return baseMapper.selectSysDeployFormList(sysDeployForm);
}
/**
* 新增流程实例关联表单
*
* @param sysDeployForm 流程实例关联表单
* @return 结果
*/
public int insertSysDeployForm(SysDeployForm sysDeployForm)
{
return baseMapper.insertSysDeployForm(sysDeployForm);
}
/**
* 修改流程实例关联表单
*
* @param sysDeployForm 流程实例关联表单
* @return 结果
*/
public int updateSysDeployForm(SysDeployForm sysDeployForm)
{
return baseMapper.updateSysDeployForm(sysDeployForm);
}
/**
* 批量删除流程实例关联表单
*
* @param ids 需要删除的流程实例关联表单ID
* @return 结果
*/
public int deleteSysDeployFormByIds(Long[] ids)
{
return baseMapper.deleteSysDeployFormByIds(ids);
}
/**
* 删除流程实例关联表单信息
*
* @param id 流程实例关联表单ID
* @return 结果
*/
public int deleteSysDeployFormById(Long id)
{
return baseMapper.deleteSysDeployFormById(id);
}
/**
* 查询流程挂着的表单
*
* @param deployId
* @return
*/
public SysForm selectSysDeployFormByDeployId(String deployId) {
return baseMapper.selectSysDeployFormByDeployId(deployId);
}
}

108
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormController.java

@ -0,0 +1,108 @@
package com.yxt.anrui.flowable.biz.sysform;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yxt.anrui.flowable.api.sysform.SysFormFeign;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.api.sysform.SysFormQuery;
import com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm;
import com.yxt.anrui.flowable.api.sysform.SysFormVo;
import com.yxt.anrui.flowable.biz.sysdeployform.SysDeployFormService;
import com.yxt.common.base.utils.PagerUtil;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import com.yxt.common.core.vo.PagerVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 流程表单Controller
*
* @author XuanXuan
* @date 2021-04-03
*/
@RestController
@RequestMapping("v1/flowable/form")
public class SysFormController implements SysFormFeign {
@Autowired
private SysFormService sysFormService;
@Autowired
private SysDeployFormService sysDeployFormService;
/* @Autowired
private ISysDeployFormService sysDeployFormService;*/
/**
* 查询流程表单列表
*/
@Override
public ResultBean<PagerVo<SysFormVo>> list(PagerQuery<SysFormQuery> pq) {
ResultBean<PagerVo<SysFormVo>> rb = ResultBean.fireFail();
IPage<SysFormVo> page = sysFormService.selectSysFormList(pq);
PagerVo<SysFormVo> pv = new PagerVo<>();
PagerVo<SysFormVo> pv1 = PagerUtil.pageToVo(page, pv);
return rb.success().setData(pv1);
}
/**
* 导出流程表单列表
*/
@GetMapping("/export")
public ResultBean<String> export(SysForm sysForm) {
/*List<SysForm> list = SysFormService.selectSysFormList(sysForm);
ExcelUtil<SysForm> util = new ExcelUtil<SysForm>(SysForm.class);
return util.exportExcel(list, "form");*/
return null;
}
/**
* 获取流程表单详细信息
*/
@GetMapping(value = "/{formId}")
public String getInfo(@PathVariable("formId") Long formId) {
SysForm sysForm = sysFormService.selectSysFormById(formId);
return JSON.toJSONString(sysForm);
}
/**
* 新增流程表单
*/
@Override
public ResultBean<String> add(@RequestBody SysForm sysForm) {
int i = sysFormService.insertSysForm(sysForm);
ResultBean<String> rb = ResultBean.fireFail();
return rb.success().setMsg("操作成功");
}
/**
* 修改流程表单
*/
@PutMapping
public ResultBean<String> edit(@RequestBody SysForm sysForm) {
// return toAjax(SysFormService.updateSysForm(sysForm));
return null;
}
/**
* 删除流程表单
*/
@DeleteMapping("/{formIds}")
public ResultBean<String> remove(@PathVariable Long[] formIds) {
sysFormService.deleteSysFormByIds(formIds);
ResultBean<String> rb = ResultBean.fireFail();
return rb.success().setMsg("操作成功");
// return null;
}
/**
* 挂载流程表单
*/
@PostMapping("/addDeployForm")
public ResultBean<String> addDeployForm(@RequestBody SysDeployForm sysDeployForm) {
sysDeployFormService.insertSysDeployForm(sysDeployForm);
ResultBean<String> rb = ResultBean.fireFail();
return rb.success().setMsg("操作成功");
}
}

77
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormMapper.java

@ -0,0 +1,77 @@
package com.yxt.anrui.flowable.biz.sysform;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.api.sysform.SysFormVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 流程表单Mapper接口
*
* @author XuanXuan Xuan
* @date 2021-03-30
*/
@Mapper
public interface SysFormMapper extends BaseMapper<SysForm> {
/**
* 查询流程表单
*
* @param formId 流程表单ID
* @return 流程表单
*/
public SysForm selectSysFormById(Long formId);
/**
* 查询流程表单列表
*
* @return 流程表单集合
*/
// public IPage<SysFormVo> selectSysFormVo(IPage<SysFormQuery> page, @Param(Constants.WRAPPER) Wrapper<SysFormVo> qw);
List<SysFormVo> getSysFormVoList(IPage<SysFormVo> page, @Param(Constants.WRAPPER) Wrapper<SysFormVo> qw);
/**
* 新增流程表单
*
* @param sysForm 流程表单
* @return 结果
*/
public int insertSysForm(SysForm sysForm);
/**
* 修改流程表单
*
* @param sysForm 流程表单
* @return 结果
*/
public int updateSysForm(SysForm sysForm);
/**
* 删除流程表单
*
* @param formId 流程表单ID
* @return 结果
*/
public int deleteSysFormById(Long formId);
/**
* 批量删除流程表单
*
* @param formIds 需要删除的数据ID
* @return 结果
*/
public int deleteSysFormByIds(Long[] formIds);
@Select("SELECT id AS formId, form_name AS formName, form_content AS formContent FROM sys_form ")
List<SysFormVo> selectListVo();
int getSysFormVoTotal(IPage<SysFormVo> page, QueryWrapper<SysFormVo> qw);
}

34
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormMapper.xml

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.sysform.SysFormMapper">
<select id="getSysFormVoList" resultType="com.yxt.anrui.flowable.api.sysform.SysForm">
select id as formId, form_name as formName, form_content as formContent
from sys_form
</select>
<select id="getSysFormVoTotal" resultType="int">
select count(*) as total from sys_form
</select>
<insert id="insertSysForm" parameterType="com.yxt.anrui.flowable.api.sysform.SysForm" useGeneratedKeys="true" keyProperty="formId">
insert into sys_form
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="formName != null">form_name,</if>
<if test="formContent != null">form_content,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="formName != null">#{formName},</if>
<if test="formContent != null">#{formContent},</if>
</trim>
</insert>
<delete id="deleteSysFormByIds" parameterType="String">
delete from sys_form where id in
<foreach item="formId" collection="array" open="(" separator="," close=")">
#{formId}
</foreach>
</delete>
<select id="selectSysFormById" parameterType="Long" resultType="com.yxt.anrui.flowable.api.sysform.SysForm">
select id as formId, form_name as formName, form_content as formContent, remark as remarks from sys_form
where id = #{formId}
</select>
</mapper>

130
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysform/SysFormService.java

@ -0,0 +1,130 @@
package com.yxt.anrui.flowable.biz.sysform;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.api.sysform.SysFormQuery;
import com.yxt.anrui.flowable.api.sysform.SysFormVo;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.core.query.PagerQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* 流程表单Service业务层处理
*
* @author XuanXuan Xuan
* @date 2021-04-03
*/
@Service
//@Transactional
public class SysFormService extends MybatisBaseService<SysFormMapper, SysForm> {
/**
* 查询流程表单
*
* @param formId 流程表单ID
* @return 流程表单
*/
public SysForm selectSysFormById(Long formId)
{
return baseMapper.selectSysFormById(formId);
}
/**
* 查询流程表单列表
*
* @return 流程表单
*/
// public PagerVo<SysFormVo> selectSysFormList(PagerQuery<SysFormQuery> pq)
// {
// /* List<SysFormVo> sysForms = baseMapper.selectListVo();
// int size = sysForms.size();
// SysFormQuery query = pq.getParams();
// QueryWrapper<SysFormVo> qw = createQueryWrapper(query);
// IPage<SysFormVo> page = PagerUtil.queryToPage(pq);
// IPage<SysFormVo> pigging = baseMapper.selectSysFormVo(page,qw);
// PagerVo<SysFormVo> p = PagerUtil.pageToVo(pigging, null);*/
// IPage<SysFormQuery> page = PagerUtil.queryToPage(pq);
// QueryWrapper<SysFormVo> qw = createQueryWrapper(pq.getParams());
// baseMapper.selectSysFormVo(page, qw);
// return null;
// }
public IPage<SysFormVo> selectSysFormList(PagerQuery<SysFormQuery> pagerQuery) {
List<SysFormVo> sysForms = baseMapper.selectListVo();
IPage<SysFormVo> page =new Page<>();// PagerUtil.queryToPage(pagerQuery);
QueryWrapper<SysFormVo> qw = createQueryWrapper(pagerQuery.getParams());
List<SysFormVo> sysFormVoList = baseMapper.getSysFormVoList(page, qw);
int total = baseMapper.getSysFormVoTotal(page, qw);
page.setTotal(total);
page.setRecords(sysFormVoList);
return page;
}
/**
* 新增流程表单
*
* @param sysForm 流程表单
* @return 结果
*/
public int insertSysForm(SysForm sysForm)
{
sysForm.setCreateTime(new Date());
return baseMapper.insertSysForm(sysForm);
}
/**
* 修改流程表单
*
* @param sysForm 流程表单
* @return 结果
*/
public int updateSysForm(SysForm sysForm)
{
// sysForm.setUpdateTime(new Date());
return 0;//sysFormMapper.updateSysForm(sysForm);
}
/**
* 批量删除流程表单
*
* @param formIds 需要删除的流程表单ID
* @return 结果
*/
public int deleteSysFormByIds(Long[] formIds)
{
return baseMapper.deleteSysFormByIds(formIds);
}
/**
* 删除流程表单信息
*
* @param formId 流程表单ID
* @return 结果
*/
public int deleteSysFormById(Long formId)
{
return 0;// sysFormMapper.deleteSysFormById(formId);
}
private QueryWrapper<SysFormVo> createQueryWrapper(SysFormQuery query) {
// todo: 这里根据具体业务调整查询条件
// 多字段Like示例:qw.and(wrapper -> wrapper.like("name", query.getName()).or().like("remark", query.getName()));
QueryWrapper<SysFormVo> qw = new QueryWrapper<>();
if (StringUtils.isNotBlank(query.getFormName())) {
qw.like("form_name", query.getFormName());
}
if (StringUtils.isNotBlank(query.getFormContent())) {
qw.eq("form_content", query.getFormContent());
}
return qw;
}
}

37
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkMapper.java

@ -0,0 +1,37 @@
package com.yxt.anrui.flowable.biz.sysformlink;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.sysformlink.SysFormLink;
import com.yxt.anrui.flowable.api.sysformlink.SysFormStateVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Map;
/**
* Project: anrui-flowable(流程引擎) <br/>
* File: SysFormLinkMapper.java <br/>
* Class: com.yxt.anrui.flowable.biz.sysformlink.SysFormLinkMapper <br/>
* Description: 流程业务关联表. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2022-03-15 16:55:39 <br/>
*
* @author liupopo
* @version 1.0
* @since 1.0
*/
@Mapper
public interface SysFormLinkMapper extends BaseMapper<SysFormLink> {
int save(SysFormLink sysFormLink);
@Select("select nodeState,flowState from sys_form_link where businessSid=#{businessSid}")
SysFormStateVo selectStateByBusinessSid(@Param("businessSid") String businessSid);
int updateFiled(Map<String, Object> map);
@Select("select count(1) from sys_form_link where businessSid=#{businessSid}")
int selectByBusinessSid(@Param("businessSid") String businessSid);
}

16
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkMapper.xml

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.sysformlink.SysFormLinkMapper">
<insert id="save" parameterType="com.yxt.anrui.flowable.api.sysformlink.SysFormLink">
insert into sys_form_link(sid, businessSid, procInsId, taskDefKey, nodeState, flowState, formType)
values (#{sid},#{businessSid},#{procInsId},#{taskDefKey},#{nodeState},#{flowState},#{formType})
</insert>
<update id="updateFiled" parameterType="java.util.Map">
UPDATE sys_form_link SET nodeState=#{nodeState}, taskDefKey=#{taskDefKey}
<if test="flowState != null and flowState !=''">
, flowState=#{flowState}
</if>
WHERE businessSid=#{businessSid}
</update>
</mapper>

59
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkRest.java

@ -0,0 +1,59 @@
package com.yxt.anrui.flowable.biz.sysformlink;
import com.yxt.anrui.flowable.api.sysformlink.SysFormLinkDto;
import com.yxt.anrui.flowable.api.sysformlink.SysFormLinkFeign;
import com.yxt.anrui.flowable.api.sysformlink.SysFormStateVo;
import com.yxt.common.core.result.ResultBean;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* Project: anrui-flowable(流程引擎) <br/>
* File: SysFormLinkFeignFallback.java <br/>
* Class: com.yxt.anrui.flowable.biz.sysformlink.SysFormLinkRest <br/>
* Description: 流程业务关联表. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2022-03-15 16:55:39 <br/>
*
* @author liupopo
* @version 1.0
* @since 1.0
*/
@Api(tags = "流程业务关联表")
@RestController
@RequestMapping("v1/sysformlink")
public class SysFormLinkRest implements SysFormLinkFeign {
@Autowired
private SysFormLinkService sysFormLinkService;
@Override
public ResultBean save(SysFormLinkDto dto) {
return sysFormLinkService.save(dto);
}
@Override
public ResultBean<SysFormStateVo> selectStateByBusinessSid(String businessSid) {
return sysFormLinkService.selectStateByBusinessSid(businessSid);
}
@Override
public ResultBean updateFiled(Map<String, Object> map) {
ResultBean<Object> resultBean = ResultBean.fireFail();
int i = sysFormLinkService.updateFiled(map);
if (i == 0) {
return resultBean.setMsg("更新失败");
}
return resultBean.success().setMsg("更新成功");
}
@Override
public ResultBean selectByBusinessSid(String sid) {
return sysFormLinkService.selectByBusinessSid(sid);
}
}

80
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysformlink/SysFormLinkService.java

@ -0,0 +1,80 @@
package com.yxt.anrui.flowable.biz.sysformlink;
import com.yxt.anrui.flowable.api.sysformlink.SysFormLink;
import com.yxt.anrui.flowable.api.sysformlink.SysFormLinkDto;
import com.yxt.anrui.flowable.api.sysformlink.SysFormStateVo;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.core.result.ResultBean;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.UUID;
/**
* Project: anrui-flowable(流程引擎) <br/>
* File: SysFormLinkService.java <br/>
* Class: com.yxt.anrui.flowable.biz.sysformlink.SysFormLinkService <br/>
* Description: 流程业务关联表 业务逻辑. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2022-03-15 16:55:39 <br/>
*
* @author liupopo
* @version 1.0
* @since 1.0
*/
@Service
public class SysFormLinkService extends MybatisBaseService<SysFormLinkMapper, SysFormLink> {
/**
* 保存流程业务关联表
* @param dto
* @return
*/
public ResultBean save(SysFormLinkDto dto) {
ResultBean<Object> resultBean = ResultBean.fireFail();
SysFormLink sysFormLink = new SysFormLink();
dto.fillEntity(sysFormLink);
sysFormLink.setSid(UUID.randomUUID().toString());
int i = baseMapper.save(sysFormLink);
if (i == 0) {
return resultBean.setMsg("保存失败");
}
return resultBean.success().setMsg("保存成功");
}
/**
* 根据业务sid查询节点状态
* @param business
* @return
*/
public ResultBean<SysFormStateVo> selectStateByBusinessSid(String business) {
SysFormStateVo sysFormStateVo = baseMapper.selectStateByBusinessSid(business);
if (sysFormStateVo == null) {
return new ResultBean<SysFormStateVo>().fail().setData(new SysFormStateVo());
}
return new ResultBean<SysFormStateVo>().success().setData(sysFormStateVo);
}
/**
* 更新关联表节点状态属性
* @param map
* @return
*/
public int updateFiled(Map<String, Object> map) {
return baseMapper.updateFiled(map);
}
/**
*
* @param businessSid
* @return
*/
public ResultBean selectByBusinessSid(String businessSid) {
int i = baseMapper.selectByBusinessSid(businessSid);
if (i == 0) {
return new ResultBean().fail().setMsg("查询此消息");
}
return new ResultBean().success();
}
}

128
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlController.java

@ -0,0 +1,128 @@
package com.yxt.anrui.flowable.biz.sysprourl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yxt.anrui.flowable.api.sysdeployform.SysDeployForm;
import com.yxt.anrui.flowable.api.sysform.SysForm;
import com.yxt.anrui.flowable.api.sysprourl.*;
import com.yxt.anrui.flowable.biz.sysdeployform.SysDeployFormService;
import com.yxt.common.base.utils.PagerUtil;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import com.yxt.common.core.vo.PagerVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 流程表单Controller
*
* @author XuanXuan
* @date 2021-04-03
*/
@RestController
@RequestMapping("v1/flowable/proUrl")
public class SysProUrlController implements SysProUrlFeign {
@Autowired
private SysProUrlService sysProUrlService;
@Autowired
private SysDeployFormService sysDeployFormService;
/**
* 查询流程表单列表
*/
@Override
public ResultBean<PagerVo<SysProUrlVo>> list(PagerQuery<SysProUrlQuery> pq) {
ResultBean<PagerVo<SysProUrlVo>> rb = ResultBean.fireFail();
IPage<SysProUrlVo> page = sysProUrlService.selectSysProUrlList(pq);
PagerVo<SysProUrlVo> pv = new PagerVo<>();
PagerVo<SysProUrlVo> pv1 = PagerUtil.pageToVo(page, pv);
return rb.success().setData(pv1);
}
@Override
public ResultBean getSysProUrl(int formId) {
ResultBean<SysProUrl> rb = ResultBean.fireFail();
SysProUrl sysProUrl = sysProUrlService.selectSysProUrlById(formId);
return rb.success().setData(sysProUrl);
}
@Override
public ResultBean getForm(String proId) {
ResultBean<SysForm> rb = ResultBean.fireFail();
SysForm sysForm = sysDeployFormService.selectSysDeployFormByDeployId(proId);
return rb.success().setData(sysForm);
}
/**
* 新增流程表单
*/
@Override
public ResultBean<String> add(SysProUrlDto dto) {
return sysProUrlService.add(dto);
}
/**
* 删除流程表单
*/
@DeleteMapping("/{formIds}")
@Override
public ResultBean<String> remove(@PathVariable Long[] formIds) {
sysProUrlService.deleteSysProUrlByIds(formIds);
ResultBean<String> rb = ResultBean.fireFail();
return rb.success().setMsg("操作成功");
}
/**
* 挂载流程表单
*/
@PostMapping("/addDeployForm")
public ResultBean<String> addDeployForm(@RequestBody SysDeployForm sysDeployForm) {
sysDeployFormService.insertSysDeployForm(sysDeployForm);
ResultBean<String> rb = ResultBean.fireFail();
return rb.success().setMsg("操作成功");
}
@Override
public ResultBean<PcUrlVo> selectPcUrlByTaskDefKey(SysProUrlQuery query) {
PcUrlVo urlVo = sysProUrlService.selectPcUrlByTaskDefKey(query);
if (urlVo == null) {
return new ResultBean<PcUrlVo>().fail().setData(new PcUrlVo());
}
return new ResultBean<PcUrlVo>().success().setData(urlVo);
}
@Override
public ResultBean<AppUrlVo> selectAppUrlByTaskDefKey(AppSysProUrlQuery query) {
AppUrlVo appUrlVo = sysProUrlService.selectAppUrlByTaskDefKey(query);
if (appUrlVo == null) {
return new ResultBean<AppUrlVo>().fail().setData(new AppUrlVo());
}
return new ResultBean<AppUrlVo>().success().setData(appUrlVo);
}
@Override
public ResultBean<List<SysProUrlVo>> selectUrlByKey(String procDefId, String taskDefKey, String type) {
return sysProUrlService.selectUrlByKey(procDefId, taskDefKey, type,null);
}
/**
* pc根据流程定义id节点id终端及类型查询流程与业务表单url
*
* @param procDefId 流程定义id
* @param taskDefKey 节点id
* @param type 类型1办理2详情
* @return
*/
@Override
public ResultBean<SysProUrlVo> selectUrlByKey(String procDefId, String taskDefKey, String type,String terminal) {
ResultBean<SysProUrlVo> rb= ResultBean.fireFail();
ResultBean<List<SysProUrlVo>> listResultBean = sysProUrlService.selectUrlByKey(procDefId, taskDefKey, type, terminal);
if(listResultBean.getData().size()==1){
SysProUrlVo sysProUrlVo = listResultBean.getData().get(0);
return new ResultBean<SysProUrlVo>().success().setData(sysProUrlVo);
}
return rb.setMsg("查询不到数据");
}
}

93
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlMapper.java

@ -0,0 +1,93 @@
package com.yxt.anrui.flowable.biz.sysprourl;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.yxt.anrui.flowable.api.sysprourl.SysProUrl;
import com.yxt.anrui.flowable.api.sysprourl.SysProUrlQuery;
import com.yxt.anrui.flowable.api.sysprourl.SysProUrlVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 流程表单Mapper接口
*
* @author XuanXuan Xuan
* @date 2021-03-30
*/
@Mapper
public interface SysProUrlMapper extends BaseMapper<SysProUrl> {
/**
* 查询流程表单
*
* @param formId 流程表单ID
* @return 流程表单
*/
public SysProUrl selectSysProUrlById(int formId);
/**
* 查询流程表单列表
*
* @return 流程表单集合
*/
// public IPage<SysProUrlVo> selectSysProUrlVo(IPage<SysProUrlQuery> page, @Param(Constants.WRAPPER) Wrapper<SysProUrlVo> qw);
List<SysProUrlVo> getSysProUrlVoList(IPage<SysProUrlVo> page, @Param(Constants.WRAPPER) Wrapper<SysProUrlVo> qw);
/**
* 新增流程表单
*
* @param SysProUrl 流程表单
* @return 结果
*/
public int insertSysProUrl(SysProUrl SysProUrl);
/**
* 修改流程表单
*
* @param SysProUrl 流程表单
* @return 结果
*/
public int updateSysProUrl(SysProUrl SysProUrl);
/**
* 删除流程表单
*
* @param formId 流程表单ID
* @return 结果
*/
public int deleteSysProUrlById(Long formId);
/**
* 批量删除流程表单
*
* @param formIds 需要删除的数据ID
* @return 结果
*/
public int deleteSysProUrlByIds(Long[] formIds);
@Select("SELECT id AS formId, form_name AS formName, form_content AS formContent FROM sys_form ")
List<SysProUrlVo> selectListVo();
int getSysProUrlVoTotal(IPage<SysProUrlVo> page, QueryWrapper<SysProUrlVo> qw);
List<SysProUrlVo> selectListByProcDefId(@Param("proc_def_id") String proc_def_id, @Param("taskDefKey") String taskDefKey);
SysProUrlVo selectUniByTaskDefKey(SysProUrlQuery query);
/**
* pc根据流程定义id节点id终端及类型查询流程与业务表单url
*
* @param procDefId 流程id
* @param taskDefKey 节点iD
* @param type 类型1办理2详情
* @return
*/
List<SysProUrlVo> selectUrlByKey(@Param("procDefId") String procDefId, @Param("taskDefKey") String taskDefKey,
@Param("type") String type,@Param("terminal") String terminal);
}

135
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlMapper.xml

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.sysprourl.SysProUrlMapper">
<select id="getSysProUrlVoList" resultType="com.yxt.anrui.flowable.api.sysprourl.SysProUrl">
select id as id, url as url, type as type, terminal as terminal, formId as formId, title as title
from sys_pro_url
</select>
<select id="getSysProUrlVoTotal" resultType="int">
select count(*) as total
from sys_pro_url
</select>
<insert id="insertSysProUrl" parameterType="com.yxt.anrui.flowable.api.sysprourl.SysProUrl" useGeneratedKeys="true"
keyProperty="sid">
insert into sys_pro_url
<trim prefix="(" suffix=")" suffixOverrides=",">
sid,
<if test="url != null">
url,
</if>
<if test="type != null">
type,
</if>
<if test="terminal != null">
terminal,
</if>
<if test="formId != null">
formId,
</if>
<if test="title != null">
title,
</if>
<if test="proc_def_id != null">
proc_def_id,
</if>
<if test="taskDefKey != null">
taskDefKey,
</if>
<if test="modulePluginName != null">
modulePluginName,
</if>
<if test="taskName != null">
taskName
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
UUID(),
<if test="url != null">
#{url},
</if>
<if test="type != null">
#{type},
</if>
<if test="terminal != null">
#{terminal},
</if>
<if test="formId != null">
#{formId},
</if>
<if test="title != null">
#{title},
</if>
<if test="proc_def_id != null">
#{proc_def_id},
</if>
<if test="taskDefKey != null">
#{taskDefKey},
</if>
<if test="modulePluginName != null">
#{modulePluginName},
</if>
<if test="taskName != null">
#{taskName}
</if>
</trim>
</insert>
<delete id="deleteSysProUrlByIds" parameterType="String">
delete
from sys_pro_url where sid in
<foreach item="formId" collection="array" open="(" separator="," close=")">
#{sid}
</foreach>
</delete>
<select id="selectSysProUrlById" parameterType="Integer"
resultType="com.yxt.anrui.flowable.api.sysprourl.SysProUrl">
select id as id, url as url, type as type, terminal as terminal, formId as formId, title as title
from sys_pro_url
where formId = #{formId}
</select>
<select id="selectListByProcDefId" resultType="com.yxt.anrui.flowable.api.sysprourl.SysProUrlVo">
SELECT url,
type,
terminal,
formId,
title,
proc_def_id,
taskDefKey,
modulePluginName
FROM sys_pro_url
WHERE proc_def_id = #{proc_def_id}
AND (taskDefKey = #{taskDefKey} OR taskDefKey IS NULL OR taskDefKey = '')
ORDER BY terminal DESC, id ASC
</select>
<select id="selectUniByTaskDefKey" parameterType="com.yxt.anrui.flowable.api.sysprourl.SysProUrlQuery"
resultType="com.yxt.anrui.flowable.api.sysprourl.SysProUrlVo">
SELECT url, modulePluginName
FROM sys_pro_url
WHERE proc_def_id = #{proc_def_id}
AND type = #{type}
AND terminal = #{terminal}
AND taskDefKey = #{taskDefKey}
</select>
<select id="selectUrlByKey" resultType="com.yxt.anrui.flowable.api.sysprourl.SysProUrlVo">
select *
from sys_pro_url
where proc_def_id = #{procDefId}
and type = #{type}
and taskDefKey = #{taskDefKey}
<if test="terminal != null">
and terminal = #{terminal}
</if>
</select>
<!--<select id="selectUrlByKey">
select url
from sys_pro_url
where proc_def_id = #{procDefId}
and type = #{type}
and taskDefKey = #{taskDefKey}
and terminal = 1
</select>-->
</mapper>

206
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/sysprourl/SysProUrlService.java

@ -0,0 +1,206 @@
package com.yxt.anrui.flowable.biz.sysprourl;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yxt.anrui.flowable.api.sysprourl.*;
import com.yxt.common.base.service.MybatisBaseService;
import com.yxt.common.core.query.PagerQuery;
import com.yxt.common.core.result.ResultBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* 流程表单Service业务层处理
*
* @author XuanXuan Xuan
* @date 2021-04-03
*/
@Service
//@Transactional
public class SysProUrlService extends MybatisBaseService<SysProUrlMapper, SysProUrl> {
/* @Resource
private AppSubsetVersionFeign appSubsetVersionFeign;*/
/**
* 查询流程表单
*
* @param formId 流程表单ID
* @return 流程表单
*/
public SysProUrl selectSysProUrlById(int formId) {
return baseMapper.selectSysProUrlById(formId);
}
public IPage<SysProUrlVo> selectSysProUrlList(PagerQuery<SysProUrlQuery> pagerQuery) {
List<SysProUrlVo> SysProUrls = baseMapper.selectListVo();
IPage<SysProUrlVo> page = new Page<>();// PagerUtil.queryToPage(pagerQuery);
QueryWrapper<SysProUrlVo> qw = createQueryWrapper(pagerQuery.getParams());
List<SysProUrlVo> SysProUrlVoList = baseMapper.getSysProUrlVoList(page, qw);
int total = baseMapper.getSysProUrlVoTotal(page, qw);
page.setTotal(total);
page.setRecords(SysProUrlVoList);
return page;
}
/**
* 修改流程表单
*
* @param SysProUrl 流程表单
* @return 结果
*/
public int updateSysProUrl(SysProUrl SysProUrl) {
return 0;//SysProUrlMapper.updateSysProUrl(SysProUrl);
}
/**
* 批量删除流程表单
*
* @param formIds 需要删除的流程表单ID
* @return 结果
*/
public int deleteSysProUrlByIds(Long[] formIds) {
return baseMapper.deleteSysProUrlByIds(formIds);
}
/**
* 删除流程表单信息
*
* @param formId 流程表单ID
* @return 结果
*/
public int deleteSysProUrlById(Long formId) {
return 0;// SysProUrlMapper.deleteSysProUrlById(formId);
}
private QueryWrapper<SysProUrlVo> createQueryWrapper(SysProUrlQuery query) {
// todo: 这里根据具体业务调整查询条件
// 多字段Like示例:qw.and(wrapper -> wrapper.like("name", query.getName()).or().like("remark", query.getName()));
QueryWrapper<SysProUrlVo> qw = new QueryWrapper<>();
if (StringUtils.isNotBlank(query.getType())) {
qw.like("type", query.getType());
}
if (StringUtils.isNotBlank(query.getTerminal())) {
qw.eq("teminal", query.getTerminal());
}
return qw;
}
/**
* 根据流程id及终端查询url
*
* @param proc_def_id
* @return
*/
public List<SysProUrlVo> selectListByProcDefId(String proc_def_id, String taskDefKey) {
return baseMapper.selectListByProcDefId(proc_def_id, taskDefKey);
}
/**
* 根据流程定义id节点id终端及类型查询流程与业务表单url
*
* @param query
* @return
*/
public PcUrlVo selectPcUrlByTaskDefKey(SysProUrlQuery query) {
PcUrlVo urlVo = new PcUrlVo();
query.setTerminal("1");
SysProUrlVo sysProUrlVo = baseMapper.selectUniByTaskDefKey(query);
BeanUtil.copyProperties(sysProUrlVo, urlVo);
return urlVo;
}
/**
* app根据流程定义id节点id终端及类型查询流程与业务表单url
*
* @param query
* @return
*/
public AppUrlVo selectAppUrlByTaskDefKey(AppSysProUrlQuery query) {
AppUrlVo appUrlVo = new AppUrlVo();
query.setTerminal("2");
SysProUrlVo sysProUrlVo = baseMapper.selectUniByTaskDefKey(query);
appUrlVo.setModuleAction(sysProUrlVo.getUrl());
appUrlVo.setModulePluginName(sysProUrlVo.getModulePluginName());
/* ResultBean<AppSubsetVersionVo> resultBean = appSubsetVersionFeign.getLastBymodulePluginName(sysProUrlVo.getModulePluginName());
if (resultBean.getSuccess() && resultBean.getData() != null) {
AppSubsetVersionVo subsetVersionVo = resultBean.getData();
appUrlVo.setMsgSid("");
appUrlVo.setType("2");
appUrlVo.setPath(subsetVersionVo.getUpdateUrl());
appUrlVo.setModuleVersion(subsetVersionVo.getVersionCode());
appUrlVo.setModuleSid("");
JSONObject json = new JSONObject();
json.put("businessSid", query.getBusinessSid());
json.put("taskId", query.getTaskId());
json.put("deployId", query.getDeployId());
json.put("procInsId", query.getProcInsId());
appUrlVo.setJson(json.toJSONString());
}*/
return appUrlVo;
}
/**
* pc根据流程定义id节点id终端及类型查询流程与业务表单url
*
* @param procDefId 流程id
* @param taskDefKey 节点iD
* @param type 类型1办理2详情
* @param terminal 终端的类型
* @return
*/
public ResultBean<List<SysProUrlVo>> selectUrlByKey(String procDefId, String taskDefKey,
String type,
String terminal) {
ResultBean<List<SysProUrlVo>> rb = ResultBean.fireFail();
//验证参数
if (StringUtils.isBlank(procDefId)) {
return rb.setMsg("流程定义id不能为空");
}
if (StringUtils.isBlank(taskDefKey)) {
return rb.setMsg("节点id不能为空");
}
if (StringUtils.isBlank(type)) {
return rb.setMsg("请指定要操作的类型");
}
List<SysProUrlVo> url = baseMapper.selectUrlByKey(procDefId, taskDefKey, type,terminal);
if(url!=null&&url.size()>0){
return rb.success().setData(url);
}
return rb.setMsg("查询不到数据");
}
public ResultBean<String> add(SysProUrlDto dto) {
ResultBean<String> rb = ResultBean.fireFail();
String sid = dto.getSid();
if (StringUtils.isBlank(sid)) {//新增
SysProUrl sysProUrl = new SysProUrl();
BeanUtil.copyProperties(dto, sysProUrl, "sid");
int i = baseMapper.insertSysProUrl(sysProUrl);
if (i == 0) {
return rb.setMsg("新增失败");
}
sid = sysProUrl.getSid();
} else {//修改
SysProUrl sysProUrl = fetchBySid(sid);
if (sysProUrl == null) {
return rb.setMsg("该url不存在");
}
BeanUtil.copyProperties(dto, sysProUrl);
int i = baseMapper.updateById(sysProUrl);
if (i == 0) {
return rb.setMsg("修改失败");
}
}
return rb.success().setData(sid);
}
}

65
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/systaskform/SysTaskFormMapper.java

@ -0,0 +1,65 @@
package com.yxt.anrui.flowable.biz.systaskform;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yxt.anrui.flowable.api.sysform.SysTaskForm;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 流程任务关联单Mapper接口
*
* @author XuanXuan Xuan
* @date 2021-04-03
*/
@Mapper
public interface SysTaskFormMapper extends BaseMapper<SysTaskForm> {
/**
* 查询流程任务关联单
*
* @param id 流程任务关联单ID
* @return 流程任务关联单
*/
public SysTaskForm selectSysTaskFormById(Long id);
/**
* 查询流程任务关联单列表
*
* @param sysTaskForm 流程任务关联单
* @return 流程任务关联单集合
*/
public List<SysTaskForm> selectSysTaskFormList(SysTaskForm sysTaskForm);
/**
* 新增流程任务关联单
*
* @param sysTaskForm 流程任务关联单
* @return 结果
*/
public int insertSysTaskForm(SysTaskForm sysTaskForm);
/**
* 修改流程任务关联单
*
* @param sysTaskForm 流程任务关联单
* @return 结果
*/
public int updateSysTaskForm(SysTaskForm sysTaskForm);
/**
* 删除流程任务关联单
*
* @param id 流程任务关联单ID
* @return 结果
*/
public int deleteSysTaskFormById(Long id);
/**
* 批量删除流程任务关联单
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteSysTaskFormByIds(Long[] ids);
}

61
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/biz/systaskform/SysTaskFormMapper.xml

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yxt.anrui.flowable.biz.systaskform.SysTaskFormMapper">
<resultMap type="com.yxt.anrui.flowable.api.sysform.SysTaskForm" id="SysTaskFormResult">
<result property="id" column="id" />
<result property="formId" column="form_id" />
<result property="taskId" column="task_id" />
</resultMap>
<sql id="selectSysTaskFormVo">
select id, form_id, task_id from sys_task_form
</sql>
<select id="selectSysTaskFormList" parameterType="com.yxt.anrui.flowable.api.sysform.SysTaskForm" resultMap="SysTaskFormResult">
<include refid="selectSysTaskFormVo"/>
<where>
<if test="formId != null "> and form_id = #{formId}</if>
<if test="taskId != null and taskId != ''"> and task_id = #{taskId}</if>
</where>
</select>
<select id="selectSysTaskFormById" parameterType="Long" resultMap="SysTaskFormResult">
<include refid="selectSysTaskFormVo"/>
where id = #{id}
</select>
<insert id="insertSysTaskForm" parameterType="com.yxt.anrui.flowable.api.sysform.SysTaskForm" useGeneratedKeys="true" keyProperty="id">
insert into sys_task_form
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="formId != null">form_id,</if>
<if test="taskId != null">task_id,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="formId != null">#{formId},</if>
<if test="taskId != null">#{taskId},</if>
</trim>
</insert>
<update id="updateSysTaskForm" parameterType="com.yxt.anrui.flowable.api.sysform.SysTaskForm">
update sys_task_form
<trim prefix="SET" suffixOverrides=",">
<if test="formId != null">form_id = #{formId},</if>
<if test="taskId != null">task_id = #{taskId},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteSysTaskFormById" parameterType="Long">
delete from sys_task_form where id = #{id}
</delete>
<delete id="deleteSysTaskFormByIds" parameterType="String">
delete from sys_task_form where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

62
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/common/EnumResultBean.java

@ -0,0 +1,62 @@
/*********************************************************
*********************************************************
******************** *******************
************* ************
******* _oo0oo_ *******
*** o8888888o ***
* 88" . "88 *
* (| -_- |) *
* 0\ = /0 *
* ___/`---'\___ *
* .' \\| |// '. *
* / \\||| : |||// \ *
* / _||||| -:- |||||- \ *
* | | \\\ - /// | | *
* | \_| ''\---/'' |_/ | *
* \ .-\__ '-' ___/-. / *
* ___'. .' /--.--\ `. .'___ *
* ."" '< `.___\_<|>_/___.' >' "". *
* | | : `- \`.;`\ _ /`;.`/ - ` : | | *
* \ \ `_. \_ __\ /__ _/ .-` / / *
* =====`-.____`.___ \_____/___.-`___.-'===== *
* `=---=' *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
*********__佛祖保佑__永无BUG__验收通过__钞票多多__*********
*********************************************************/
package com.yxt.anrui.flowable.common;
import com.yxt.common.core.constant.HttpStatus;
import com.yxt.common.core.result.ResultBean;
/**
* Project: anrui-parent <br/>
* File: EnumResultBean.java <br/>
* Class: com.yxt.anrui.flowable.common.EnumResultBean <br/>
* Description: <描述类的功能>. <br/>
* Copyright: Copyright (c) 2011 <br/>
* Company: https://gitee.com/liuzp315 <br/>
* Makedate: 2021/9/11 下午10:18 <br/>
*
* @author popo
* @version 1.0
* @since 1.0
*/
public class EnumResultBean<T> extends ResultBean<T> {
public static <T> EnumResultBean<T> fireSuccess() {
EnumResultBean<T> rb = new EnumResultBean<T>();
rb.setSuccess(true);
rb.setCode(String.valueOf(HttpStatus.SUCCESS));
rb.setMsg("操作成功!");
return rb;
}
// public static <T> EnumResultBean<T> fireFail() {
// EnumResultBean<T> rb = new EnumResultBean<T>();
// rb.setSuccess(false);
// rb.setCode(String.valueOf(HttpStatus.ERROR));
// rb.setMsg("操作失败!");
// return rb;
// }
}

73
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/common/ProcessConstants.java

@ -0,0 +1,73 @@
package com.yxt.anrui.flowable.common;
/**
* @author dimengzhe
* @date 2021/6/16 9:03
* @description 流程常量信息
*/
public class ProcessConstants {
/**
* 动态数据
*/
public static final String DATA_TYPE = "dynamic";
/**
* 单个审批人
*/
public static final String USER_TYPE_ASSIGNEE = "assignee";
/**
* 候选人
*/
public static final String USER_TYPE_USERS = "candidateUsers";
/**
* 审批组
*/
public static final String USER_TYPE_ROUPS = "candidateGroups";
/**
* 单个审批人
*/
public static final String PROCESS_APPROVAL = "approval";
/**
* 会签人员
*/
public static final String PROCESS_MULTI_INSTANCE_USER = "userList";
/**
* nameapace
*/
public static final String NAMASPASE = "http://flowable.org/bpmn";
/**
* 会签节点
*/
public static final String PROCESS_MULTI_INSTANCE = "multiInstance";
/**
* 自定义属性 dataType
*/
public static final String PROCESS_CUSTOM_DATA_TYPE = "dataType";
/**
* 自定义属性 userType
*/
public static final String PROCESS_CUSTOM_USER_TYPE = "userType";
/**
* 初始化人员
*/
public static final String PROCESS_INITIATOR = "INITIATOR";
/**
* 流程跳过
*/
public static final String FLOWABLE_SKIP_EXPRESSION_ENABLED = "_FLOWABLE_SKIP_EXPRESSION_ENABLED";
}

342
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/DefaultProcessDiagramCanvasExt.java

@ -0,0 +1,342 @@
package com.yxt.anrui.flowable.config;
import org.flowable.bpmn.model.AssociationDirection;
import org.flowable.bpmn.model.GraphicInfo;
import org.flowable.image.impl.DefaultProcessDiagramCanvas;
import org.flowable.image.util.ReflectUtil;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
/**
* @author dimengzhe
* @date 2021/6/18 10:02
* @description 自定义已经走过的流程高亮连接线和高亮图标, 重写DefaultProcessDiagramCanvas方法
*/
public class DefaultProcessDiagramCanvasExt extends DefaultProcessDiagramCanvas {
//定义走过流程连线颜色为绿色
protected static Color HIGHLIGHT_SequenceFlow_COLOR = Color.GREEN;
//设置未走过流程的连接线颜色
protected static Color CONNECTION_COLOR = Color.BLACK;
//设置flows连接线字体颜色red
protected static Color LABEL_COLOR = new Color(0, 0, 0);
//高亮显示task框颜色
protected static Color HIGHLIGHT_COLOR = Color.GREEN;
protected static Color HIGHLIGHT_COLOR1 = Color.RED;
protected static Color EVENT_COLOR = new Color(255, 255, 255);
public DefaultProcessDiagramCanvasExt(int width, int height, int minX, int minY, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
super(width, height, minX, minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
this.initialize(imageType);
}
/**
* 重写绘制连线的方式,设置绘制颜色
*/
@Override
public void drawConnection(int[] xPoints, int[] yPoints, boolean conditional, boolean isDefault, String connectionType, AssociationDirection associationDirection, boolean highLighted, double scaleFactor) {
Paint originalPaint = this.g.getPaint();
Stroke originalStroke = this.g.getStroke();
this.g.setPaint(CONNECTION_COLOR);
if (connectionType.equals("association")) {
this.g.setStroke(ASSOCIATION_STROKE);
} else if (highLighted) {
this.g.setPaint(HIGHLIGHT_SequenceFlow_COLOR);
this.g.setStroke(HIGHLIGHT_FLOW_STROKE);
}
for (int i = 1; i < xPoints.length; ++i) {
Integer sourceX = xPoints[i - 1];
Integer sourceY = yPoints[i - 1];
Integer targetX = xPoints[i];
Integer targetY = yPoints[i];
java.awt.geom.Line2D.Double line = new java.awt.geom.Line2D.Double((double) sourceX, (double) sourceY, (double) targetX, (double) targetY);
this.g.draw(line);
}
java.awt.geom.Line2D.Double line;
if (isDefault) {
line = new java.awt.geom.Line2D.Double((double) xPoints[0], (double) yPoints[0], (double) xPoints[1], (double) yPoints[1]);
this.drawDefaultSequenceFlowIndicator(line, scaleFactor);
}
if (conditional) {
line = new java.awt.geom.Line2D.Double((double) xPoints[0], (double) yPoints[0], (double) xPoints[1], (double) yPoints[1]);
this.drawConditionalSequenceFlowIndicator(line, scaleFactor);
}
if (associationDirection.equals(AssociationDirection.ONE) || associationDirection.equals(AssociationDirection.BOTH)) {
line = new java.awt.geom.Line2D.Double((double) xPoints[xPoints.length - 2], (double) yPoints[xPoints.length - 2], (double) xPoints[xPoints.length - 1], (double) yPoints[xPoints.length - 1]);
this.drawArrowHead(line, scaleFactor);
}
if (associationDirection.equals(AssociationDirection.BOTH)) {
line = new java.awt.geom.Line2D.Double((double) xPoints[1], (double) yPoints[1], (double) xPoints[0], (double) yPoints[0]);
this.drawArrowHead(line, scaleFactor);
}
this.g.setPaint(originalPaint);
this.g.setStroke(originalStroke);
}
//设置字体大小图标颜色
@Override
public void initialize(String imageType) {
if ("png".equalsIgnoreCase(imageType)) {
this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 2);
} else {
this.processDiagram = new BufferedImage(this.canvasWidth, this.canvasHeight, 1);
}
this.g = this.processDiagram.createGraphics();
if (!"png".equalsIgnoreCase(imageType)) {
this.g.setBackground(new Color(255, 255, 255, 0));
this.g.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
}
this.g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//修改图标颜色,修改图标字体大小
this.g.setPaint(Color.black);
Font font = new Font(this.activityFontName, 10, 14);
this.g.setFont(font);
this.fontMetrics = this.g.getFontMetrics();
//修改连接线字体大小
LABEL_FONT = new Font(this.labelFontName, 10, 15);
ANNOTATION_FONT = new Font(this.annotationFontName, 0, 11);
try {
USERTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/userTask.png", this.customClassLoader));
SCRIPTTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/scriptTask.png", this.customClassLoader));
SERVICETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/serviceTask.png", this.customClassLoader));
RECEIVETASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/receiveTask.png", this.customClassLoader));
SENDTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/sendTask.png", this.customClassLoader));
MANUALTASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/manualTask.png", this.customClassLoader));
BUSINESS_RULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/businessRuleTask.png", this.customClassLoader));
SHELL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/shellTask.png", this.customClassLoader));
DMN_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/dmnTask.png", this.customClassLoader));
CAMEL_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/camelTask.png", this.customClassLoader));
MULE_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/muleTask.png", this.customClassLoader));
HTTP_TASK_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/httpTask.png", this.customClassLoader));
TIMER_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/timer.png", this.customClassLoader));
COMPENSATE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/compensate-throw.png", this.customClassLoader));
COMPENSATE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/compensate.png", this.customClassLoader));
ERROR_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/error-throw.png", this.customClassLoader));
ERROR_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/error.png", this.customClassLoader));
MESSAGE_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/message-throw.png", this.customClassLoader));
MESSAGE_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/message.png", this.customClassLoader));
SIGNAL_THROW_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/signal-throw.png", this.customClassLoader));
SIGNAL_CATCH_IMAGE = ImageIO.read(ReflectUtil.getResource("org/flowable/icons/signal.png", this.customClassLoader));
} catch (IOException var4) {
LOGGER.warn("Could not load image for process diagram creation: {}", var4.getMessage());
}
}
/**
* 设置连接线字体
*
* @param text
* @param graphicInfo
* @param centered
*/
@Override
public void drawLabel(String text, GraphicInfo graphicInfo, boolean centered) {
float interline = 1.0f;
// text
if (text != null && text.length() > 0) {
Paint originalPaint = g.getPaint();
Font originalFont = g.getFont();
g.setPaint(LABEL_COLOR);
g.setFont(LABEL_FONT);
int wrapWidth = 100;
int textY = (int) graphicInfo.getY();
AttributedString as = new AttributedString(text);
as.addAttribute(TextAttribute.FOREGROUND, g.getPaint());
as.addAttribute(TextAttribute.FONT, g.getFont());
AttributedCharacterIterator aci = as.getIterator();
FontRenderContext frc = new FontRenderContext(null, true, false);
LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
while (lbm.getPosition() < text.length()) {
TextLayout tl = lbm.nextLayout(wrapWidth);
textY += tl.getAscent();
Rectangle2D bb = tl.getBounds();
double tX = graphicInfo.getX();
if (centered) {
tX += (int) (graphicInfo.getWidth() / 2 - bb.getWidth() / 2);
}
tl.draw(g, (float) tX, textY);
textY += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent();
}
// restore originals
g.setFont(originalFont);
g.setPaint(originalPaint);
}
}
/**
* 高亮显示task框完成的
*
* @param x
* @param y
* @param width
* @param height
*/
@Override
public void drawHighLight(int x, int y, int width, int height) {
Paint originalPaint = g.getPaint();
Stroke originalStroke = g.getStroke();
g.setPaint(HIGHLIGHT_COLOR);
g.setStroke(THICK_TASK_BORDER_STROKE);
RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
g.draw(rect);
g.setPaint(originalPaint);
g.setStroke(originalStroke);
}
/**
* 自定义task框当前的位置
*
* @param x
* @param y
* @param width
* @param height
*/
public void drawHighLight1(int x, int y, int width, int height) {
Paint originalPaint = g.getPaint();
Stroke originalStroke = g.getStroke();
g.setPaint(HIGHLIGHT_COLOR1);
g.setStroke(THICK_TASK_BORDER_STROKE);
RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, 20, 20);
g.draw(rect);
g.setPaint(originalPaint);
g.setStroke(originalStroke);
}
/**
* task框自定义文字
*
* @param name
* @param graphicInfo
* @param thickBorder
* @param scaleFactor
*/
@Override
protected void drawTask(String name, GraphicInfo graphicInfo, boolean thickBorder, double scaleFactor) {
Paint originalPaint = g.getPaint();
int x = (int) graphicInfo.getX();
int y = (int) graphicInfo.getY();
int width = (int) graphicInfo.getWidth();
int height = (int) graphicInfo.getHeight();
// Create a new gradient paint for every task box, gradient depends on x and y and is not relative
g.setPaint(TASK_BOX_COLOR);
int arcR = 6;
if (thickBorder) {
arcR = 3;
}
// shape
RoundRectangle2D rect = new RoundRectangle2D.Double(x, y, width, height, arcR, arcR);
g.fill(rect);
g.setPaint(TASK_BORDER_COLOR);
if (thickBorder) {
Stroke originalStroke = g.getStroke();
g.setStroke(THICK_TASK_BORDER_STROKE);
g.draw(rect);
g.setStroke(originalStroke);
} else {
g.draw(rect);
}
g.setPaint(originalPaint);
// text
if (scaleFactor == 1.0 && name != null && name.length() > 0) {
int boxWidth = width - (2 * TEXT_PADDING);
int boxHeight = height - 16 - ICON_PADDING - ICON_PADDING - MARKER_WIDTH - 2 - 2;
int boxX = x + width / 2 - boxWidth / 2;
int boxY = y + height / 2 - boxHeight / 2 + ICON_PADDING + ICON_PADDING - 2 - 2;
drawMultilineCentredText(name, boxX, boxY, boxWidth, boxHeight);
}
}
/**
* 重写开始事件
*
* @param graphicInfo
* @param image
* @param scaleFactor
*/
@Override
public void drawStartEvent(GraphicInfo graphicInfo, BufferedImage image, double scaleFactor) {
Paint originalPaint = g.getPaint();
g.setPaint(EVENT_COLOR);
Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(),
graphicInfo.getWidth(), graphicInfo.getHeight());
g.fill(circle);
g.setPaint(EVENT_BORDER_COLOR);
g.draw(circle);
g.setPaint(originalPaint);
if (image != null) {
// calculate coordinates to center image
int imageX = (int) Math.round(graphicInfo.getX() + (graphicInfo.getWidth() / 2) - (image.getWidth() / (2 * scaleFactor)));
int imageY = (int) Math.round(graphicInfo.getY() + (graphicInfo.getHeight() / 2) - (image.getHeight() / (2 * scaleFactor)));
g.drawImage(image, imageX, imageY,
(int) (image.getWidth() / scaleFactor), (int) (image.getHeight() / scaleFactor), null);
}
}
/**
* 重写结束事件
*
* @param graphicInfo
* @param scaleFactor
*/
@Override
public void drawNoneEndEvent(GraphicInfo graphicInfo, double scaleFactor) {
Paint originalPaint = g.getPaint();
Stroke originalStroke = g.getStroke();
g.setPaint(EVENT_COLOR);
Ellipse2D circle = new Ellipse2D.Double(graphicInfo.getX(), graphicInfo.getY(),
graphicInfo.getWidth(), graphicInfo.getHeight());
g.fill(circle);
g.setPaint(EVENT_BORDER_COLOR);
if (scaleFactor == 1.0) {
g.setStroke(END_EVENT_STROKE);
} else {
g.setStroke(new BasicStroke(2.0f));
}
g.draw(circle);
g.setStroke(originalStroke);
g.setPaint(originalPaint);
}
}

397
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/DefaultProcessDiagramGeneratorExt.java

@ -0,0 +1,397 @@
package com.yxt.anrui.flowable.config;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.image.impl.DefaultProcessDiagramCanvas;
import org.flowable.image.impl.DefaultProcessDiagramGenerator;
import java.util.Iterator;
import java.util.List;
/**
* @author dimengzhe
* @date 2021/6/18 10:09
* @description
*/
public class DefaultProcessDiagramGeneratorExt extends DefaultProcessDiagramGenerator {
@Override
protected DefaultProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType, List<String> highLightedActivities, List<String> highLightedFlows, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, boolean drawSequenceFlowNameWithNoLabelDI) {
this.prepareBpmnModel(bpmnModel);
DefaultProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
Iterator var13 = bpmnModel.getPools().iterator();
while (var13.hasNext()) {
Pool process = (Pool) var13.next();
GraphicInfo subProcesses = bpmnModel.getGraphicInfo(process.getId());
processDiagramCanvas.drawPoolOrLane(process.getName(), subProcesses, scaleFactor);
}
var13 = bpmnModel.getProcesses().iterator();
Process process1;
Iterator subProcesses1;
while (var13.hasNext()) {
process1 = (Process) var13.next();
subProcesses1 = process1.getLanes().iterator();
while (subProcesses1.hasNext()) {
Lane artifact = (Lane) subProcesses1.next();
GraphicInfo subProcess = bpmnModel.getGraphicInfo(artifact.getId());
processDiagramCanvas.drawPoolOrLane(artifact.getName(), subProcess, scaleFactor);
}
}
var13 = bpmnModel.getProcesses().iterator();
while (var13.hasNext()) {
process1 = (Process) var13.next();
subProcesses1 = process1.findFlowElementsOfType(FlowNode.class).iterator();
while (subProcesses1.hasNext()) {
FlowNode artifact1 = (FlowNode) subProcesses1.next();
if (!this.isPartOfCollapsedSubProcess(artifact1, bpmnModel)) {
this.drawActivity(processDiagramCanvas, bpmnModel, artifact1, highLightedActivities, highLightedFlows, scaleFactor, Boolean.valueOf(drawSequenceFlowNameWithNoLabelDI));
}
}
}
var13 = bpmnModel.getProcesses().iterator();
label75:
while (true) {
List subProcesses2;
do {
if (!var13.hasNext()) {
return processDiagramCanvas;
}
process1 = (Process) var13.next();
subProcesses1 = process1.getArtifacts().iterator();
while (subProcesses1.hasNext()) {
Artifact artifact2 = (Artifact) subProcesses1.next();
this.drawArtifact(processDiagramCanvas, bpmnModel, artifact2);
}
subProcesses2 = process1.findFlowElementsOfType(SubProcess.class, true);
} while (subProcesses2 == null);
Iterator artifact3 = subProcesses2.iterator();
while (true) {
GraphicInfo graphicInfo;
SubProcess subProcess1;
do {
do {
if (!artifact3.hasNext()) {
continue label75;
}
subProcess1 = (SubProcess) artifact3.next();
graphicInfo = bpmnModel.getGraphicInfo(subProcess1.getId());
} while (graphicInfo != null && graphicInfo.getExpanded() != null && !graphicInfo.getExpanded().booleanValue());
} while (this.isPartOfCollapsedSubProcess(subProcess1, bpmnModel));
Iterator var19 = subProcess1.getArtifacts().iterator();
while (var19.hasNext()) {
Artifact subProcessArtifact = (Artifact) var19.next();
this.drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact);
}
}
}
}
protected static DefaultProcessDiagramCanvas initProcessDiagramCanvas(BpmnModel bpmnModel, String imageType, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader) {
double minX = 1.7976931348623157E308D;
double maxX = 0.0D;
double minY = 1.7976931348623157E308D;
double maxY = 0.0D;
GraphicInfo nrOfLanes;
for (Iterator flowNodes = bpmnModel.getPools().iterator(); flowNodes.hasNext(); maxY = nrOfLanes.getY() + nrOfLanes.getHeight()) {
Pool artifacts = (Pool) flowNodes.next();
nrOfLanes = bpmnModel.getGraphicInfo(artifacts.getId());
minX = nrOfLanes.getX();
maxX = nrOfLanes.getX() + nrOfLanes.getWidth();
minY = nrOfLanes.getY();
}
List var23 = gatherAllFlowNodes(bpmnModel);
Iterator var24 = var23.iterator();
label155:
while (var24.hasNext()) {
FlowNode var26 = (FlowNode) var24.next();
GraphicInfo artifact = bpmnModel.getGraphicInfo(var26.getId());
if (artifact.getX() + artifact.getWidth() > maxX) {
maxX = artifact.getX() + artifact.getWidth();
}
if (artifact.getX() < minX) {
minX = artifact.getX();
}
if (artifact.getY() + artifact.getHeight() > maxY) {
maxY = artifact.getY() + artifact.getHeight();
}
if (artifact.getY() < minY) {
minY = artifact.getY();
}
Iterator process = var26.getOutgoingFlows().iterator();
while (true) {
List l;
do {
if (!process.hasNext()) {
continue label155;
}
SequenceFlow graphicInfoList = (SequenceFlow) process.next();
l = bpmnModel.getFlowLocationGraphicInfo(graphicInfoList.getId());
} while (l == null);
Iterator graphicInfo = l.iterator();
while (graphicInfo.hasNext()) {
GraphicInfo graphicInfo1 = (GraphicInfo) graphicInfo.next();
if (graphicInfo1.getX() > maxX) {
maxX = graphicInfo1.getX();
}
if (graphicInfo1.getX() < minX) {
minX = graphicInfo1.getX();
}
if (graphicInfo1.getY() > maxY) {
maxY = graphicInfo1.getY();
}
if (graphicInfo1.getY() < minY) {
minY = graphicInfo1.getY();
}
}
}
}
List var25 = gatherAllArtifacts(bpmnModel);
Iterator var27 = var25.iterator();
GraphicInfo var37;
while (var27.hasNext()) {
Artifact var29 = (Artifact) var27.next();
GraphicInfo var31 = bpmnModel.getGraphicInfo(var29.getId());
if (var31 != null) {
if (var31.getX() + var31.getWidth() > maxX) {
maxX = var31.getX() + var31.getWidth();
}
if (var31.getX() < minX) {
minX = var31.getX();
}
if (var31.getY() + var31.getHeight() > maxY) {
maxY = var31.getY() + var31.getHeight();
}
if (var31.getY() < minY) {
minY = var31.getY();
}
}
List var33 = bpmnModel.getFlowLocationGraphicInfo(var29.getId());
if (var33 != null) {
Iterator var35 = var33.iterator();
while (var35.hasNext()) {
var37 = (GraphicInfo) var35.next();
if (var37.getX() > maxX) {
maxX = var37.getX();
}
if (var37.getX() < minX) {
minX = var37.getX();
}
if (var37.getY() > maxY) {
maxY = var37.getY();
}
if (var37.getY() < minY) {
minY = var37.getY();
}
}
}
}
int var28 = 0;
Iterator var30 = bpmnModel.getProcesses().iterator();
while (var30.hasNext()) {
Process var32 = (Process) var30.next();
Iterator var34 = var32.getLanes().iterator();
while (var34.hasNext()) {
Lane var36 = (Lane) var34.next();
++var28;
var37 = bpmnModel.getGraphicInfo(var36.getId());
if (var37.getX() + var37.getWidth() > maxX) {
maxX = var37.getX() + var37.getWidth();
}
if (var37.getX() < minX) {
minX = var37.getX();
}
if (var37.getY() + var37.getHeight() > maxY) {
maxY = var37.getY() + var37.getHeight();
}
if (var37.getY() < minY) {
minY = var37.getY();
}
}
}
if (var23.isEmpty() && bpmnModel.getPools().isEmpty() && var28 == 0) {
minX = 0.0D;
minY = 0.0D;
}
return new DefaultProcessDiagramCanvasExt((int) maxX + 10, (int) maxY + 10, (int) minX, (int) minY, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader);
}
private static void drawHighLight(DefaultProcessDiagramCanvas processDiagramCanvas, GraphicInfo graphicInfo) {
processDiagramCanvas.drawHighLight((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());
}
private static void drawHighLigh1(DefaultProcessDiagramCanvasExt processDiagramCanvas, GraphicInfo graphicInfo) {
processDiagramCanvas.drawHighLight1((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight());
}
@Override
protected void drawActivity(DefaultProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel,
FlowNode flowNode, List<String> highLightedActivities, List<String> highLightedFlows, double scaleFactor, Boolean drawSequenceFlowNameWithNoLabelDI) {
DefaultProcessDiagramGenerator.ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass());
if (drawInstruction != null) {
drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode);
// Gather info on the multi instance marker
boolean multiInstanceSequential = false;
boolean multiInstanceParallel = false;
boolean collapsed = false;
if (flowNode instanceof Activity) {
Activity activity = (Activity) flowNode;
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
if (multiInstanceLoopCharacteristics != null) {
multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential();
multiInstanceParallel = !multiInstanceSequential;
}
}
// Gather info on the collapsed marker
GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId());
if (flowNode instanceof SubProcess) {
collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded();
} else if (flowNode instanceof CallActivity) {
collapsed = true;
}
if (scaleFactor == 1.0) {
// Actually draw the markers
processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(), (int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(),
multiInstanceSequential, multiInstanceParallel, collapsed);
}
// Draw highlighted activities
if (highLightedActivities.contains(flowNode.getId())) {
if (highLightedActivities.get(highLightedActivities.size() - 1).equals(flowNode.getId())
&& !flowNode.getId().equals("endenv")) {
//更改源码没有走的红色表示
drawHighLigh1((DefaultProcessDiagramCanvasExt) processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
} else {
drawHighLight(processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()));
}
}
}
// Outgoing transitions of activity
for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) {
boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId()));
String defaultFlow = null;
if (flowNode instanceof Activity) {
defaultFlow = ((Activity) flowNode).getDefaultFlow();
} else if (flowNode instanceof Gateway) {
defaultFlow = ((Gateway) flowNode).getDefaultFlow();
}
boolean isDefault = false;
if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) {
isDefault = true;
}
boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway);
String sourceRef = sequenceFlow.getSourceRef();
String targetRef = sequenceFlow.getTargetRef();
FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef);
FlowElement targetElement = bpmnModel.getFlowElement(targetRef);
List<GraphicInfo> graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId());
if (graphicInfoList != null && graphicInfoList.size() > 0) {
graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList);
int xPoints[] = new int[graphicInfoList.size()];
int yPoints[] = new int[graphicInfoList.size()];
for (int i = 1; i < graphicInfoList.size(); i++) {
GraphicInfo graphicInfo = graphicInfoList.get(i);
GraphicInfo previousGraphicInfo = graphicInfoList.get(i - 1);
if (i == 1) {
xPoints[0] = (int) previousGraphicInfo.getX();
yPoints[0] = (int) previousGraphicInfo.getY();
}
xPoints[i] = (int) graphicInfo.getX();
yPoints[i] = (int) graphicInfo.getY();
}
processDiagramCanvas.drawSequenceflow(xPoints, yPoints, drawConditionalIndicator, isDefault, highLighted, scaleFactor);
// Draw sequenceflow label
GraphicInfo labelGraphicInfo = bpmnModel.getLabelGraphicInfo(sequenceFlow.getId());
if (labelGraphicInfo != null) {
processDiagramCanvas.drawLabel(sequenceFlow.getName(), labelGraphicInfo, false);
} else {
if (drawSequenceFlowNameWithNoLabelDI) {
GraphicInfo lineCenter = getLineCenter(graphicInfoList);
processDiagramCanvas.drawLabel(sequenceFlow.getName(), lineCenter, false);
}
}
}
}
// Nested elements
if (flowNode instanceof FlowElementsContainer) {
for (FlowElement nestedFlowElement : ((FlowElementsContainer) flowNode).getFlowElements()) {
if (nestedFlowElement instanceof FlowNode && !isPartOfCollapsedSubProcess(nestedFlowElement, bpmnModel)) {
drawActivity(processDiagramCanvas, bpmnModel, (FlowNode) nestedFlowElement,
highLightedActivities, highLightedFlows, scaleFactor, drawSequenceFlowNameWithNoLabelDI);
}
}
}
}
}

47
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/DiRemoteAccountResource.java

@ -0,0 +1,47 @@
package com.yxt.anrui.flowable.config;
import org.flowable.idm.engine.impl.persistence.entity.UserEntityImpl;
import org.flowable.ui.common.model.UserRepresentation;
import org.flowable.ui.common.security.SecurityUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author dimengzhe
* @date 2021/6/17 14:26
* @description 内置用户登录
*/
@RestController
@RequestMapping("/di")
public class DiRemoteAccountResource {
/**
* GET /rest/account -> get the current user.
*/
@GetMapping(value = "/rest/account", produces = "application/json")
public UserRepresentation getAccount() {
UserEntityImpl userEntity = new UserEntityImpl();
userEntity.setId("dimengzhe");
SecurityUtils.assumeUser(userEntity);
UserRepresentation userRepresentation = new UserRepresentation();
userRepresentation.setId("tpp-flowable");
userRepresentation.setFirstName("底");
userRepresentation.setLastName("孟哲");
List<String> privileges = new ArrayList<>();
privileges.add("flowable-idm");
privileges.add("flowable-modeler");
privileges.add("flowable-admin");
privileges.add("flowable-task");
privileges.add("flowable-rest");
userRepresentation.setPrivileges(privileges);
return userRepresentation;
}
}

22
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/FlowableConfig.java

@ -0,0 +1,22 @@
package com.yxt.anrui.flowable.config;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.context.annotation.Configuration;
/**
*flowable配置----为放置生成的流程图中中文乱码
* @author dimengzhe
*/
@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
@Override
public void configure(SpringProcessEngineConfiguration engineConfiguration) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>> 配置已经加载 >>>>>>>>>>>>>>>>>>>>>>>");
engineConfiguration.setActivityFontName("宋体");
engineConfiguration.setLabelFontName("宋体");
engineConfiguration.setAnnotationFontName("宋体");
}
}

25
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/P6spySqlFormatConfig.java

@ -0,0 +1,25 @@
package com.yxt.anrui.flowable.config;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;
import com.yxt.common.base.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Date;
/**
* @author dimengzhe
* @date 2021/10/11 21:02
* @description 自定义 p6spy sql输出格式
*/
public class P6spySqlFormatConfig implements MessageFormattingStrategy {
/**
* 过滤掉定时任务的 SQL
*/
@Override
public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared, String sql, String url) {
return StringUtils.isNotBlank(sql) ? DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date())
+ " | 耗时 " + elapsed + " ms | SQL 语句:" + StringUtils.LF + sql.replaceAll("[\\s]+", StringUtils.SPACE) + ";" : "";
}
}

212
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/ProcessEngineConfig.java

@ -0,0 +1,212 @@
package com.yxt.anrui.flowable.config;
import liquibase.Liquibase;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.DatabaseException;
import liquibase.resource.ClassLoaderResourceAccessor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.ProcessEngine;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.ui.common.service.exception.InternalServerErrorException;
import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Properties;
/**
* @author dimengzhe
* @date 2021/6/17 14:24
* @description 构造流程引擎配置类
*/
@Configuration
public class ProcessEngineConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(ProcessEngine.class);
@Autowired
protected ResourceLoader resourceLoader;
protected static final String LIQUIBASE_CHANGELOG_PREFIX = "ACT_DE_";
@Autowired
private DataSource dataSource;
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
return dataSourceTransactionManager;
}
@Bean
public SpringProcessEngineConfiguration springProcessEngineConfiguration() {
SpringProcessEngineConfiguration springProcessEngineConfiguration = new SpringProcessEngineConfiguration();
springProcessEngineConfiguration.setDataSource(dataSource);
springProcessEngineConfiguration.setDatabaseSchemaUpdate("true");
springProcessEngineConfiguration.setTransactionManager(dataSourceTransactionManager(dataSource));
return springProcessEngineConfiguration;
}
@Primary
@Bean
public SqlSessionTemplate SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
String databaseType = initDatabaseType(dataSource);
if (databaseType == null) {
throw new FlowableException("couldn't deduct database type");
}
try {
Properties properties = new Properties();
properties.put("prefix", "");
properties.put("blobType", "BLOB");
properties.put("boolValue", "TRUE");
properties.load(this.getClass().getClassLoader().getResourceAsStream("properties/" + databaseType + ".properties"));
sqlSessionFactoryBean.setConfigurationProperties(properties);
sqlSessionFactoryBean
.setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath:/META-INF/modeler-mybatis-mappings/*.xml"));
sqlSessionFactoryBean.afterPropertiesSet();
return sqlSessionFactoryBean.getObject();
} catch (Exception e) {
throw new FlowableException("Could not create sqlSessionFactory", e);
}
}
protected String initDatabaseType(DataSource dataSource) {
String databaseType = null;
Connection connection = null;
try {
connection = dataSource.getConnection();
DatabaseMetaData databaseMetaData = connection.getMetaData();
String databaseProductName = databaseMetaData.getDatabaseProductName();
LOGGER.info("database product name: '{}'", databaseProductName);
databaseType = databaseTypeMappings.getProperty(databaseProductName);
if (databaseType == null) {
throw new FlowableException("couldn't deduct database type from database product name '" + databaseProductName + "'");
}
LOGGER.info("using database type: {}", databaseType);
} catch (SQLException e) {
LOGGER.error("Exception while initializing Database connection", e);
} finally {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
LOGGER.error("Exception while closing the Database connection", e);
}
}
return databaseType;
}
protected static Properties databaseTypeMappings = getDefaultDatabaseTypeMappings();
public static final String DATABASE_TYPE_H2 = "h2";
public static final String DATABASE_TYPE_HSQL = "hsql";
public static final String DATABASE_TYPE_MYSQL = "mysql";
public static final String DATABASE_TYPE_ORACLE = "oracle";
public static final String DATABASE_TYPE_POSTGRES = "postgres";
public static final String DATABASE_TYPE_MSSQL = "mssql";
public static final String DATABASE_TYPE_DB2 = "db2";
public static Properties getDefaultDatabaseTypeMappings() {
Properties databaseTypeMappings = new Properties();
databaseTypeMappings.setProperty("H2", DATABASE_TYPE_H2);
databaseTypeMappings.setProperty("HSQL Database Engine", DATABASE_TYPE_HSQL);
databaseTypeMappings.setProperty("MySQL", DATABASE_TYPE_MYSQL);
databaseTypeMappings.setProperty("MariaDB", DATABASE_TYPE_MYSQL);
databaseTypeMappings.setProperty("Oracle", DATABASE_TYPE_ORACLE);
databaseTypeMappings.setProperty("PostgreSQL", DATABASE_TYPE_POSTGRES);
databaseTypeMappings.setProperty("Microsoft SQL Server", DATABASE_TYPE_MSSQL);
databaseTypeMappings.setProperty(DATABASE_TYPE_DB2, DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/NT", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/NT64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDP", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUX", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUX390", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXX8664", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXZ64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/LINUXPPC64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/400 SQL", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/6000", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDB iSeries", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/AIX64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/HPUX", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/HP64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/SUN", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/SUN64", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/PTX", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2/2", DATABASE_TYPE_DB2);
databaseTypeMappings.setProperty("DB2 UDB AS400", DATABASE_TYPE_DB2);
return databaseTypeMappings;
}
@Bean
public FlowableModelerAppProperties flowableModelerAppProperties() {
return new FlowableModelerAppProperties();
}
@Bean
public Liquibase liquibase(DataSource dataSource) {
LOGGER.info("Configuring Liquibase");
Liquibase liquibase = null;
try {
DatabaseConnection connection = new JdbcConnection(dataSource.getConnection());
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
database.setDatabaseChangeLogTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogTableName());
database.setDatabaseChangeLogLockTableName(LIQUIBASE_CHANGELOG_PREFIX + database.getDatabaseChangeLogLockTableName());
liquibase = new Liquibase("META-INF/liquibase/flowable-modeler-app-db-changelog.xml", new ClassLoaderResourceAccessor(), database);
liquibase.update("flowable");
return liquibase;
} catch (Exception e) {
throw new InternalServerErrorException("Error creating liquibase database", e);
} finally {
closeDatabase(liquibase);
}
}
private void closeDatabase(Liquibase liquibase) {
if (liquibase != null) {
Database database = liquibase.getDatabase();
if (database != null) {
try {
database.close();
} catch (DatabaseException e) {
LOGGER.warn("Error closing database", e);
}
}
}
}
}

36
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/config/Swagger2Config.java

@ -0,0 +1,36 @@
package com.yxt.anrui.flowable.config;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author dimengzhe
* @date 2020/9/9 16:42
* @description
*/
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.basePackage("com.yxt"))
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("安瑞/工作流").description("工作流接口").version("1.0")
.build();
}
}

41
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/factory/FlowServiceFactory.java

@ -0,0 +1,41 @@
package com.yxt.anrui.flowable.factory;
import org.flowable.engine.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author dimengzhe
* @date 2021/6/16 10:41
* @description flowable 引擎注入封装
*/
@Component
public class FlowServiceFactory {
@Resource
protected RepositoryService repositoryService;
@Resource
protected RuntimeService runtimeService;
@Resource
protected IdentityService identityService;
@Resource
protected TaskService taskService;
@Resource
protected FormService formService;
@Resource
protected HistoryService historyService;
@Resource
protected ManagementService managementService;
@Qualifier("processEngine")
@Resource
protected ProcessEngine processEngine;
}

23
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/listener/BaseVehicleExecutionListener.java

@ -0,0 +1,23 @@
package com.yxt.anrui.flowable.listener;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.stereotype.Component;
/**
* @author liuguohui
* @version 1.0
* @description 建立车辆库存台账
* @date 2022/04/11
*/
@Component
public class BaseVehicleExecutionListener implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) {
// 入账申请审批通过后,自动生成车辆库存台账
// TODO
System.out.println("入账申请审批通过后,自动生成车辆库存台账");
}
}

21
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/listener/ManagerEndExecutionListener.java

@ -0,0 +1,21 @@
package com.yxt.anrui.flowable.listener;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.stereotype.Component;
/**
* @Description 执行监听器监听流程实例结束事件抄送等
* @Author liuguohui
* @Date 2022/2/8
*/
@Component
public class ManagerEndExecutionListener implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) {
System.out.println("执行监听器:" + "抄送");
String processInstanceId = execution.getProcessInstanceId();
System.out.println(execution);
}
}

101
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/listener/ManagerTaskListener.java

@ -0,0 +1,101 @@
package com.yxt.anrui.flowable.listener;
import com.alibaba.fastjson.JSONObject;
import com.yxt.common.base.utils.JPushServer;
import com.yxt.common.core.result.ResultBean;
import com.yxt.supervise.system.sysuserrole.SysUserRoleFeign;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @Description 监听任务器监听各个环节发出推送等消息
* @Author liuguohui
* @Date 2022/2/7
*/
@Component
public class ManagerTaskListener implements TaskListener {
private static ManagerTaskListener taskListener;
@Autowired
private SysUserRoleFeign sysUserRoleFeign;
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
/**
* 监听器中无法获取spring bean配置
* 注意调用方式taskListener.sysUserRoleFeign
*/
@PostConstruct
public void init() {
taskListener = this;
taskListener.sysUserRoleFeign = this.sysUserRoleFeign;
}
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("任务监听");
// String assignee = delegateTask.getAssignee();
Set<IdentityLink> set = delegateTask.getCandidates();
List<String> groupIdList = set.stream().filter(item -> StringUtils.isNotBlank(item.getGroupId())).map(item -> item.getGroupId()).collect(Collectors.toList());
JSONObject jsonObject = new JSONObject();
jsonObject.put("msgType", "花花");
// jsonObject.put("assignee", assignee);
// jsonObject.put("groupIdList", groupIdList);
send(jsonObject.toString());
// if (StringUtils.isBlank(assignee)) {
// Set<IdentityLink> set = delegateTask.getCandidates();
// List<String> groupIdList = set.stream().filter(item -> StringUtils.isNotBlank(item.getGroupId())).map(item -> item.getGroupId()).collect(Collectors.toList());
// if (CollectionUtils.isNotEmpty(groupIdList)) {
// ResultBean<List<String>> resultBean = taskListener.sysUserRoleFeign.getUserIdListByRoleSid(groupIdList);
// if (resultBean.getSuccess() && resultBean.getData() != null) {
// List<String> list = resultBean.getData();
// // 保存消息体、保存消息列表
//
// // TODO 与kafka集成
// JPushServer.sendPushAlias("标题", "内容 ", "msg_type", "销售订单", list.toArray(list.toArray(new String[list.size()])));
// }
// }
// } else {
// JPushServer.sendPushAlias("标题", "内容 ", "msg_type", "销售订单", assignee);
// }
}
public void send(String obj2String) {
// String obj2String = JSONObject.toJSONString(obj);
//发送消息
/* ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send("aaa", obj2String);
future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {
@Override
public void onFailure(Throwable throwable) {
//发送失败的处理
log.info("aaa" + " - 生产者 发送消息失败:" + throwable.getMessage());
}
@Override
public void onSuccess(SendResult<String, Object> stringObjectSendResult) {
//成功的处理
log.info("aaa" + " - 生产者 发送消息成功:" + stringObjectSendResult.toString());
}
});*/
}
}

53
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/controller/HolidayTestController.java

@ -0,0 +1,53 @@
package com.yxt.anrui.flowable.test.controller;
import com.yxt.anrui.flowable.test.HolidayTestApi;
import com.yxt.anrui.flowable.test.HolidayVo;
import com.yxt.anrui.flowable.test.service.IHolidayTestService;
import com.yxt.common.core.result.ResultBean;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
/**
* @author dimengzhe
* @date 2021/6/18 10:36
* @description 公司请假流程测试
*/
@Api(tags = "公司请假流程测试")
@Controller
@RequestMapping("v1/flowable/holidaytest")
public class HolidayTestController implements HolidayTestApi {
@Autowired
private IHolidayTestService holidayTestService;
/**
* 提交请假
*
* @param taskUser 申请人
* @param day 申请天数
* @return
*/
@Override
public ResultBean<HolidayVo> submit(String taskUser, Integer day) {
if (day == null || "".equals(day)) {
return new ResultBean<HolidayVo>().fail().setMsg("请写入请假天数.........");
}
HolidayVo holidayVo = holidayTestService.submit(taskUser, day);
return new ResultBean<HolidayVo>().setData(holidayVo);
}
/**
* 生成图片
*
* @param httpServletResponse
* @param processId 流程实例ID
*/
@Override
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) {
holidayTestService.genProcessDiagram(httpServletResponse, processId);
}
}

41
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/controller/TestController.java

@ -0,0 +1,41 @@
package com.yxt.anrui.flowable.test.controller;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
/**
* @author dimengzhe
* @date 2021/6/11 9:30
* @description
*/
public class TestController {
/**
* @author dimengzhe
* @description 生成数据库表
* @date 2021/6/11 9:47
**/
// @Test
public void test1() {
//1.创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("flowable.cfg.xml");
//2.创建ProcessEngine对象
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println(processEngine);
}
// @Test
public void test2() {
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
.setJdbcUrl("jdbc:mysql://localhost:3306/anrui_flowable?serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
.setJdbcUsername("root")
.setJdbcPassword("root")
.setJdbcDriver("com.mysql.jdbc.Driver")
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
ProcessEngine processEngine = cfg.buildProcessEngine();
}
}

39
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/service/IHolidayTestService.java

@ -0,0 +1,39 @@
package com.yxt.anrui.flowable.test.service;
import com.yxt.anrui.flowable.test.HolidayVo;
import javax.servlet.http.HttpServletResponse;
/**
* @author dimengzhe
* @date 2021/6/18 10:44
* @description
*/
public interface IHolidayTestService {
/**
* 提交请假申请
*
* @param taskUser 申请人
* @param day 天数
* @return
*/
HolidayVo submit(String taskUser, Integer day);
/**
* 生成图片
*
* @param httpServletResponse
* @param processId 流程实例ID
*/
void genProcessDiagram(HttpServletResponse httpServletResponse, String processId);
/**
* 流程是否完成功能
*
* @param processInstanceId 流程实例id
* @return
*/
boolean isFinished(String processInstanceId);
}

149
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/test/service/impl/HolidayTestService.java

@ -0,0 +1,149 @@
package com.yxt.anrui.flowable.test.service.impl;
import com.yxt.anrui.flowable.CodeMsgEnum;
import com.yxt.anrui.flowable.config.DefaultProcessDiagramGeneratorExt;
import com.yxt.anrui.flowable.factory.FlowServiceFactory;
import com.yxt.anrui.flowable.test.HolidayVo;
import com.yxt.anrui.flowable.test.service.IHolidayTestService;
import com.yxt.common.core.result.ResultBean;
import org.apache.commons.io.IOUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* @author dimengzhe
* @date 2021/6/18 10:45
* @description
*/
@Service
public class HolidayTestService extends FlowServiceFactory implements IHolidayTestService {
/**
* 提交请假申请
*
* @param taskUser 申请人
* @param day 天数
* @return
*/
@Override
public HolidayVo submit(String taskUser, Integer day) {
List<Task> tasks = taskService.createTaskQuery().taskAssignee(taskUser).orderByTaskCreateTime().desc().list();
//启动流程
HashMap<String, Object> map = new HashMap<>();
map.put("taskUser", taskUser);
map.put("user1", "mg");
map.put("user2", "boss");
ProcessInstance pi = runtimeService.startProcessInstanceByKey("holiday_test", map);
//过排他网关
Task task = taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).singleResult();
taskService.setVariable(task.getId(), "day", day);
taskService.complete(task.getId());
//老板或经理审批根据请假天数
Task task2 = taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).singleResult();
if ("boss".equals(task2.getAssignee())) {
taskService.setVariable(task2.getId(), "outcome", "驳回");
taskService.complete(task2.getId());
} else {
taskService.setVariable(task2.getId(), "outcome", "通过");
taskService.complete(task2.getId());
}
HolidayVo holidayVo = new HolidayVo();
holidayVo.setDay(day);
holidayVo.setTaskUser(taskUser);
holidayVo.setId(pi.getId());
// String data = "{进程实例id:" + "\"" + pi.getId() + "\"" + "," + "请假申请人:" + "\"" + taskUser + "\"" + "," + "请假天数:" + "\"" + day + "\"" + "}";
return holidayVo;
}
/**
* 生成图片
*
* @param httpServletResponse
* @param processId 流程实例id
*/
@Override
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) {
/**
* 获得当前活动的节点
*/
String processDefinitionId = "";
if (this.isFinished(processId)) {// 如果流程已经结束,则得到结束节点
HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
processDefinitionId = pi.getProcessDefinitionId();
} else {// 如果流程没有结束,则取当前活动节点
// 根据流程实例ID获得当前处于活动状态的ActivityId合集
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
processDefinitionId = pi.getProcessDefinitionId();
}
List<String> highLightedActivitis = new ArrayList<String>();
/**
* 获得活动的节点
*/
List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
//高亮节点
for (HistoricActivityInstance tempActivity : highLightedActivitList) {
String activityId = tempActivity.getActivityId();
highLightedActivitis.add(activityId);
}
List<String> highLightedflows = new ArrayList<>();
//高亮线
for (HistoricActivityInstance tempActivity : highLightedActivitList) {
if ("sequenceFlow".equals(tempActivity.getActivityType())) {
highLightedflows.add(tempActivity.getActivityId());
}
}
//获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
//获取自定义图片生成器
ProcessDiagramGenerator diagramGenerator = new DefaultProcessDiagramGeneratorExt();
InputStream in = diagramGenerator.generateDiagram(bpmnModel, "bmp", highLightedActivitis, highLightedflows, engconf.getActivityFontName(),
engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, true);
OutputStream out = null;
byte[] buf = new byte[1024];
int legth = 0;
try {
out = httpServletResponse.getOutputStream();
while ((legth = in.read(buf)) != -1) {
out.write(buf, 0, legth);
}
} catch (IOException e) {
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(in);
}
}
@Override
public boolean isFinished(String processInstanceId) {
return historyService.createHistoricProcessInstanceQuery().finished()
.processInstanceId(processInstanceId).count() > 0;
}
public ResultBean doResultEnum() {
ResultBean rb = ResultBean.fireFail();
return rb.fail().setCode(CodeMsgEnum.AF_U_5001);
}
}

620
yxt_supervise/supervise-flowable/supervise-flowable-biz/src/main/java/com/yxt/anrui/flowable/utils/FlowableUtils.java

@ -0,0 +1,620 @@
package com.yxt.anrui.flowable.utils;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.*;
import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* @author XuanXuan
* @date 2021-04-03 23:57
*/
@Slf4j
public class FlowableUtils {
private static final Logger log = LoggerFactory.getLogger(FlowableUtils.class);
/**
* 根据节点获取入口连线
* @param source
* @return
*/
public static List<SequenceFlow> getElementIncomingFlows(FlowElement source) {
List<SequenceFlow> sequenceFlows = null;
if (source instanceof FlowNode) {
sequenceFlows = ((FlowNode) source).getIncomingFlows();
} else if (source instanceof Gateway) {
sequenceFlows = ((Gateway) source).getIncomingFlows();
} else if (source instanceof SubProcess) {
sequenceFlows = ((SubProcess) source).getIncomingFlows();
} else if (source instanceof StartEvent) {
sequenceFlows = ((StartEvent) source).getIncomingFlows();
} else if (source instanceof EndEvent) {
sequenceFlows = ((EndEvent) source).getIncomingFlows();
}
return sequenceFlows;
}
/**
* 根据节点获取出口连线
* @param source
* @return
*/
public static List<SequenceFlow> getElementOutgoingFlows(FlowElement source) {
List<SequenceFlow> sequenceFlows = null;
if (source instanceof FlowNode) {
sequenceFlows = ((FlowNode) source).getOutgoingFlows();
} else if (source instanceof Gateway) {
sequenceFlows = ((Gateway) source).getOutgoingFlows();
} else if (source instanceof SubProcess) {
sequenceFlows = ((SubProcess) source).getOutgoingFlows();
} else if (source instanceof StartEvent) {
sequenceFlows = ((StartEvent) source).getOutgoingFlows();
} else if (source instanceof EndEvent) {
sequenceFlows = ((EndEvent) source).getOutgoingFlows();
}
return sequenceFlows;
}
/**
* 获取全部节点列表包含子流程节点
* @param flowElements
* @param allElements
* @return
*/
public static Collection<FlowElement> getAllElements(Collection<FlowElement> flowElements, Collection<FlowElement> allElements) {
allElements = allElements == null ? new ArrayList<>() : allElements;
for (FlowElement flowElement : flowElements) {
allElements.add(flowElement);
if (flowElement instanceof SubProcess) {
// 继续深入子流程,进一步获取子流程
allElements = FlowableUtils.getAllElements(((SubProcess) flowElement).getFlowElements(), allElements);
}
}
return allElements;
}
/**
* 迭代获取父级任务节点列表向前找
* @param source 起始节点
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param userTaskList 已找到的用户任务节点
* @return
*/
public static List<UserTask> iteratorFindParentUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
if (source instanceof StartEvent && source.getSubProcess() != null) {
userTaskList = iteratorFindParentUserTasks(source.getSubProcess(), hasSequenceFlow, userTaskList);
}
// 根据类型,获取入口连线
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (sequenceFlows != null) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 类型为用户节点,则新增父级节点
if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
userTaskList.add((UserTask) sequenceFlow.getSourceFlowElement());
continue;
}
// 类型为子流程,则添加子流程开始节点出口处相连的节点
if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
// 获取子流程用户任务节点
List<UserTask> childUserTaskList = findChildProcessUserTasks((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, null);
// 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
if (childUserTaskList != null && childUserTaskList.size() > 0) {
userTaskList.addAll(childUserTaskList);
continue;
}
}
// 继续迭代
userTaskList = iteratorFindParentUserTasks(sequenceFlow.getSourceFlowElement(), hasSequenceFlow, userTaskList);
}
}
return userTaskList;
}
/**
* 根据正在运行的任务节点迭代获取子级任务节点列表向后找
* @param source 起始节点
* @param runTaskKeyList 正在运行的任务 Key用于校验任务节点是否是正在运行的节点
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param userTaskList 需要撤回的用户任务列表
* @return
*/
public static List<UserTask> iteratorFindChildUserTasks(FlowElement source, List<String> runTaskKeyList, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
if (source instanceof EndEvent && source.getSubProcess() != null) {
userTaskList = iteratorFindChildUserTasks(source.getSubProcess(), runTaskKeyList, hasSequenceFlow, userTaskList);
}
// 根据类型,获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (sequenceFlows != null) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
if (sequenceFlow.getTargetFlowElement() instanceof UserTask && runTaskKeyList.contains((sequenceFlow.getTargetFlowElement()).getId())) {
userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
continue;
}
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
List<UserTask> childUserTaskList = iteratorFindChildUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), runTaskKeyList, hasSequenceFlow, null);
// 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
if (childUserTaskList != null && childUserTaskList.size() > 0) {
userTaskList.addAll(childUserTaskList);
continue;
}
}
// 继续迭代
userTaskList = iteratorFindChildUserTasks(sequenceFlow.getTargetFlowElement(), runTaskKeyList, hasSequenceFlow, userTaskList);
}
}
return userTaskList;
}
/**
* 迭代获取子流程用户任务节点
* @param source 起始节点
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param userTaskList 需要撤回的用户任务列表
* @return
*/
public static List<UserTask> findChildProcessUserTasks(FlowElement source, Set<String> hasSequenceFlow, List<UserTask> userTaskList) {
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
userTaskList = userTaskList == null ? new ArrayList<>() : userTaskList;
// 根据类型,获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (sequenceFlows != null) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 如果为用户任务类型,且任务节点的 Key 正在运行的任务中存在,添加
if (sequenceFlow.getTargetFlowElement() instanceof UserTask) {
userTaskList.add((UserTask) sequenceFlow.getTargetFlowElement());
continue;
}
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
List<UserTask> childUserTaskList = findChildProcessUserTasks((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, null);
// 如果找到节点,则说明该线路找到节点,不继续向下找,反之继续
if (childUserTaskList != null && childUserTaskList.size() > 0) {
userTaskList.addAll(childUserTaskList);
continue;
}
}
// 继续迭代
userTaskList = findChildProcessUserTasks(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, userTaskList);
}
}
return userTaskList;
}
/**
* 从后向前寻路获取所有脏线路上的点
* @param source 起始节点
* @param passRoads 已经经过的点集合
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param targets 目标脏线路终点
* @param dirtyRoads 确定为脏数据的点因为不需要重复因此使用 set 存储
* @return
*/
public static Set<String> iteratorFindDirtyRoads(FlowElement source, List<String> passRoads, Set<String> hasSequenceFlow, List<String> targets, Set<String> dirtyRoads) {
passRoads = passRoads == null ? new ArrayList<>() : passRoads;
dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads;
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
if (source instanceof StartEvent && source.getSubProcess() != null) {
dirtyRoads = iteratorFindDirtyRoads(source.getSubProcess(), passRoads, hasSequenceFlow, targets, dirtyRoads);
}
// 根据类型,获取入口连线
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (sequenceFlows != null) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 新增经过的路线
passRoads.add(sequenceFlow.getSourceFlowElement().getId());
// 如果此点为目标点,确定经过的路线为脏线路,添加点到脏线路中,然后找下个连线
if (targets.contains(sequenceFlow.getSourceFlowElement().getId())) {
dirtyRoads.addAll(passRoads);
continue;
}
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
if (sequenceFlow.getSourceFlowElement() instanceof SubProcess) {
dirtyRoads = findChildProcessAllDirtyRoad((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, dirtyRoads);
// 是否存在子流程上,true 是,false 否
Boolean isInChildProcess = dirtyTargetInChildProcess((StartEvent) ((SubProcess) sequenceFlow.getSourceFlowElement()).getFlowElements().toArray()[0], null, targets, null);
if (isInChildProcess) {
// 已在子流程上找到,该路线结束
continue;
}
}
// 继续迭代
dirtyRoads = iteratorFindDirtyRoads(sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, targets, dirtyRoads);
}
}
return dirtyRoads;
}
/**
* 迭代获取子流程脏路线
* 说明假如回退的点就是子流程那么也肯定会回退到子流程最初的用户任务节点因此子流程中的节点全是脏路线
* @param source 起始节点
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param dirtyRoads 确定为脏数据的点因为不需要重复因此使用 set 存储
* @return
*/
public static Set<String> findChildProcessAllDirtyRoad(FlowElement source, Set<String> hasSequenceFlow, Set<String> dirtyRoads) {
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
dirtyRoads = dirtyRoads == null ? new HashSet<>() : dirtyRoads;
// 根据类型,获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (sequenceFlows != null) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 添加脏路线
dirtyRoads.add(sequenceFlow.getTargetFlowElement().getId());
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
dirtyRoads = findChildProcessAllDirtyRoad((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, dirtyRoads);
}
// 继续迭代
dirtyRoads = findChildProcessAllDirtyRoad(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, dirtyRoads);
}
}
return dirtyRoads;
}
/**
* 判断脏路线结束节点是否在子流程上
* @param source 起始节点
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param targets 判断脏路线节点是否存在子流程上只要存在一个说明脏路线只到子流程为止
* @param inChildProcess 是否存在子流程上true false
* @return
*/
public static Boolean dirtyTargetInChildProcess(FlowElement source, Set<String> hasSequenceFlow, List<String> targets, Boolean inChildProcess) {
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
inChildProcess = inChildProcess == null ? false : inChildProcess;
// 根据类型,获取出口连线
List<SequenceFlow> sequenceFlows = getElementOutgoingFlows(source);
if (sequenceFlows != null && !inChildProcess) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 如果发现目标点在子流程上存在,说明只到子流程为止
if (targets.contains(sequenceFlow.getTargetFlowElement().getId())) {
inChildProcess = true;
break;
}
// 如果节点为子流程节点情况,则从节点中的第一个节点开始获取
if (sequenceFlow.getTargetFlowElement() instanceof SubProcess) {
inChildProcess = dirtyTargetInChildProcess((FlowElement) (((SubProcess) sequenceFlow.getTargetFlowElement()).getFlowElements().toArray()[0]), hasSequenceFlow, targets, inChildProcess);
}
// 继续迭代
inChildProcess = dirtyTargetInChildProcess(sequenceFlow.getTargetFlowElement(), hasSequenceFlow, targets, inChildProcess);
}
}
return inChildProcess;
}
/**
* 迭代从后向前扫描判断目标节点相对于当前节点是否是串行
* 不存在直接回退到子流程中的情况但存在从子流程出去到父流程情况
* @param source 起始节点
* @param isSequential 是否串行
* @param hasSequenceFlow 已经经过的连线的 ID用于判断线路是否重复
* @param targetKsy 目标节点
* @return
*/
public static Boolean iteratorCheckSequentialReferTarget(FlowElement source, String targetKsy, Set<String> hasSequenceFlow, Boolean isSequential) {
isSequential = isSequential == null ? true : isSequential;
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
if (source instanceof StartEvent && source.getSubProcess() != null) {
isSequential = iteratorCheckSequentialReferTarget(source.getSubProcess(), targetKsy, hasSequenceFlow, isSequential);
}
// 根据类型,获取入口连线
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (sequenceFlows != null) {
// 循环找到目标元素
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 如果目标节点已被判断为并行,后面都不需要执行,直接返回
if (isSequential == false) {
break;
}
// 这条线路存在目标节点,这条线路完成,进入下个线路
if (targetKsy.equals(sequenceFlow.getSourceFlowElement().getId())) {
continue;
}
if (sequenceFlow.getSourceFlowElement() instanceof StartEvent) {
isSequential = false;
break;
}
// 否则就继续迭代
isSequential = iteratorCheckSequentialReferTarget(sequenceFlow.getSourceFlowElement(), targetKsy, hasSequenceFlow, isSequential);
}
}
return isSequential;
}
/**
* 从后向前寻路获取到达节点的所有路线
* 不存在直接回退到子流程但是存在回退到父级流程的情况
* @param source 起始节点
* @param passRoads 已经经过的点集合
* @param roads 路线
* @return
*/
public static List<List<UserTask>> findRoad(FlowElement source, List<UserTask> passRoads, Set<String> hasSequenceFlow, List<List<UserTask>> roads) {
passRoads = passRoads == null ? new ArrayList<>() : passRoads;
roads = roads == null ? new ArrayList<>() : roads;
hasSequenceFlow = hasSequenceFlow == null ? new HashSet<>() : hasSequenceFlow;
// 如果该节点为开始节点,且存在上级子节点,则顺着上级子节点继续迭代
if (source instanceof StartEvent && source.getSubProcess() != null) {
roads = findRoad(source.getSubProcess(), passRoads, hasSequenceFlow, roads);
}
// 根据类型,获取入口连线
List<SequenceFlow> sequenceFlows = getElementIncomingFlows(source);
if (sequenceFlows != null && sequenceFlows.size() != 0) {
for (SequenceFlow sequenceFlow: sequenceFlows) {
// 如果发现连线重复,说明循环了,跳过这个循环
if (hasSequenceFlow.contains(sequenceFlow.getId())) {
continue;
}
// 添加已经走过的连线
hasSequenceFlow.add(sequenceFlow.getId());
// 添加经过路线
if (sequenceFlow.getSourceFlowElement() instanceof UserTask) {
passRoads.add((UserTask) sequenceFlow.getSourceFlowElement());
}
// 继续迭代
roads = findRoad(sequenceFlow.getSourceFlowElement(), passRoads, hasSequenceFlow, roads);
}
} else {
// 添加路线
roads.add(passRoads);
}
return roads;
}
/**
* 历史节点数据清洗清洗掉又回滚导致的脏数据
* @param allElements 全部节点信息
* @param historicTaskInstanceList 历史任务实例信息数据采用开始时间升序
* @return
*/
public static List<String> historicTaskInstanceClean(Collection<FlowElement> allElements, List<HistoricTaskInstance> historicTaskInstanceList) {
// 会签节点收集
List<String> multiTask = new ArrayList<>();
allElements.forEach(flowElement -> {
if (flowElement instanceof UserTask) {
// 如果该节点的行为为会签行为,说明该节点为会签节点
if (((UserTask) flowElement).getBehavior() instanceof ParallelMultiInstanceBehavior || ((UserTask) flowElement).getBehavior() instanceof SequentialMultiInstanceBehavior) {
multiTask.add(flowElement.getId());
}
}
});
// 循环放入栈,栈 LIFO:后进先出
Stack<HistoricTaskInstance> stack = new Stack<>();
historicTaskInstanceList.forEach(item -> stack.push(item));
// 清洗后的历史任务实例
List<String> lastHistoricTaskInstanceList = new ArrayList<>();
// 网关存在可能只走了部分分支情况,且还存在跳转废弃数据以及其他分支数据的干扰,因此需要对历史节点数据进行清洗
// 临时用户任务 key
StringBuilder userTaskKey = null;
// 临时被删掉的任务 key,存在并行情况
List<String> deleteKeyList = new ArrayList<>();
// 临时脏数据线路
List<Set<String>> dirtyDataLineList = new ArrayList<>();
// 由某个点跳到会签点,此时出现多个会签实例对应 1 个跳转情况,需要把这些连续脏数据都找到
// 会签特殊处理下标
int multiIndex = -1;
// 会签特殊处理 key
StringBuilder multiKey = null;
// 会签特殊处理操作标识
boolean multiOpera = false;
while (!stack.empty()) {
// 从这里开始 userTaskKey 都还是上个栈的 key
// 是否是脏数据线路上的点
final boolean[] isDirtyData = {false};
for (Set<String> oldDirtyDataLine : dirtyDataLineList) {
if (oldDirtyDataLine.contains(stack.peek().getTaskDefinitionKey())) {
isDirtyData[0] = true;
}
}
// 删除原因不为空,说明从这条数据开始回跳或者回退的
// MI_END:会签完成后,其他未签到节点的删除原因,不在处理范围内
if (stack.peek().getDeleteReason() != null && !stack.peek().getDeleteReason().equals("MI_END")) {
// 可以理解为脏线路起点
String dirtyPoint = "";
if (stack.peek().getDeleteReason().indexOf("Change activity to ") >= 0) {
dirtyPoint = stack.peek().getDeleteReason().replace("Change activity to ", "");
}
// 会签回退删除原因有点不同
if (stack.peek().getDeleteReason().indexOf("Change parent activity to ") >= 0) {
dirtyPoint = stack.peek().getDeleteReason().replace("Change parent activity to ", "");
}
FlowElement dirtyTask = null;
// 获取变更节点的对应的入口处连线
// 如果是网关并行回退情况,会变成两条脏数据路线,效果一样
for (FlowElement flowElement : allElements) {
if (flowElement.getId().equals(stack.peek().getTaskDefinitionKey())) {
dirtyTask = flowElement;
}
}
// 获取脏数据线路
Set<String> dirtyDataLine = FlowableUtils.iteratorFindDirtyRoads(dirtyTask, null, null, Arrays.asList(dirtyPoint.split(",")), null);
// 自己本身也是脏线路上的点,加进去
dirtyDataLine.add(stack.peek().getTaskDefinitionKey());
log.info(stack.peek().getTaskDefinitionKey() + "点脏路线集合:" + dirtyDataLine);
// 是全新的需要添加的脏线路
boolean isNewDirtyData = true;
for (int i = 0; i < dirtyDataLineList.size(); i++) {
// 如果发现他的上个节点在脏线路内,说明这个点可能是并行的节点,或者连续驳回
// 这时,都以之前的脏线路节点为标准,只需合并脏线路即可,也就是路线补全
if (dirtyDataLineList.get(i).contains(userTaskKey.toString())) {
isNewDirtyData = false;
dirtyDataLineList.get(i).addAll(dirtyDataLine);
}
}
// 已确定时全新的脏线路
if (isNewDirtyData) {
// deleteKey 单一路线驳回到并行,这种同时生成多个新实例记录情况,这时 deleteKey 其实是由多个值组成
// 按照逻辑,回退后立刻生成的实例记录就是回退的记录
// 至于驳回所生成的 Key,直接从删除原因中获取,因为存在驳回到并行的情况
deleteKeyList.add(dirtyPoint + ",");
dirtyDataLineList.add(dirtyDataLine);
}
// 添加后,现在这个点变成脏线路上的点了
isDirtyData[0] = true;
}
// 如果不是脏线路上的点,说明是有效数据,添加历史实例 Key
if (!isDirtyData[0]) {
lastHistoricTaskInstanceList.add(stack.peek().getTaskDefinitionKey());
}
// 校验脏线路是否结束
for (int i = 0; i < deleteKeyList.size(); i ++) {
// 如果发现脏数据属于会签,记录下下标与对应 Key,以备后续比对,会签脏数据范畴开始
if (multiKey == null && multiTask.contains(stack.peek().getTaskDefinitionKey())
&& deleteKeyList.get(i).contains(stack.peek().getTaskDefinitionKey())) {
multiIndex = i;
multiKey = new StringBuilder(stack.peek().getTaskDefinitionKey());
}
// 会签脏数据处理,节点退回会签清空
// 如果在会签脏数据范畴中发现 Key改变,说明会签脏数据在上个节点就结束了,可以把会签脏数据删掉
if (multiKey != null && !multiKey.toString().equals(stack.peek().getTaskDefinitionKey())) {
deleteKeyList.set(multiIndex , deleteKeyList.get(multiIndex).replace(stack.peek().getTaskDefinitionKey() + ",", ""));
multiKey = null;
// 结束进行下校验删除
multiOpera = true;
}
// 其他脏数据处理
// 发现该路线最后一条脏数据,说明这条脏数据线路处理完了,删除脏数据信息
// 脏数据产生的新实例中是否包含这条数据
if (multiKey == null && deleteKeyList.get(i).contains(stack.peek().getTaskDefinitionKey())) {
// 删除匹配到的部分
deleteKeyList.set(i , deleteKeyList.get(i).replace(stack.peek().getTaskDefinitionKey() + ",", ""));
}
// 如果每组中的元素都以匹配过,说明脏数据结束
if ("".equals(deleteKeyList.get(i))) {
// 同时删除脏数据
deleteKeyList.remove(i);
dirtyDataLineList.remove(i);
break;
}
}
// 会签数据处理需要在循环外处理,否则可能导致溢出
// 会签的数据肯定是之前放进去的所以理论上不会溢出,但还是校验下
if (multiOpera && deleteKeyList.size() > multiIndex && "".equals(deleteKeyList.get(multiIndex))) {
// 同时删除脏数据
deleteKeyList.remove(multiIndex);
dirtyDataLineList.remove(multiIndex);
multiIndex = -1;
multiOpera = false;
}
// pop() 方法与 peek() 方法不同,在返回值的同时,会把值从栈中移除
// 保存新的 userTaskKey 在下个循环中使用
userTaskKey = new StringBuilder(stack.pop().getTaskDefinitionKey());
}
log.info("清洗后的历史节点数据:" + lastHistoricTaskInstanceList);
return lastHistoricTaskInstanceList;
}
/**
* 流程完成时间处理
*
* @param ms
* @return
*/
public static String getDate(long ms) {
long day = ms / (24 * 60 * 60 * 1000);
long hour = (ms / (60 * 60 * 1000) - day * 24);
long minute = ((ms / (60 * 1000)) - day * 24 * 60 - hour * 60);
long second = (ms / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);
if (day > 0) {
return day + "天" + hour + "小时" + minute + "分钟";
}
if (hour > 0) {
return hour + "小时" + minute + "分钟";
}
if (minute > 0) {
return minute + "分钟";
}
if (second > 0) {
return second + "秒";
} else {
return 0 + "秒";
}
}
}
Loading…
Cancel
Save