
56 changed files with 8832 additions and 0 deletions
@ -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; |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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},<!–sid–> |
||||
|
#{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> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
}*/ |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
File diff suppressed because it is too large
@ -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()); |
||||
|
} |
||||
|
} |
@ -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. 我只用到了UserTask、ExclusiveGateway、ParallelGateway,所以代码里只列举了这三种,如果用到了其他的,可以再自己补充 |
||||
|
*/ |
||||
|
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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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("操作成功"); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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; |
||||
|
} |
||||
|
|
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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(); |
||||
|
} |
||||
|
} |
@ -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("查询不到数据"); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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> |
@ -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;
|
||||
|
// }
|
||||
|
} |
@ -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"; |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
|
||||
|
} |
||||
|
} |
@ -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("宋体"); |
||||
|
} |
||||
|
|
||||
|
} |
@ -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) + ";" : ""; |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -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(); |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
@ -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("入账申请审批通过后,自动生成车辆库存台账"); |
||||
|
|
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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()); |
||||
|
} |
||||
|
});*/ |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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(); |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
@ -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…
Reference in new issue