完善监听器

This commit is contained in:
jinqiming 2020-12-07 18:31:33 +08:00
parent fd02d3bee3
commit c13f146814
20 changed files with 799 additions and 164 deletions

View File

@ -4,28 +4,26 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ClassUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.snow.common.constant.SequenceContants;
import com.snow.common.enums.ProcessStatus;
import com.snow.common.json.JSON;
import com.snow.common.utils.StringUtils;
import com.snow.flowable.common.FlowConstants;
import com.snow.flowable.common.constants.FlowConstants;
import com.snow.flowable.common.enums.FlowDefEnum;
import com.snow.flowable.domain.*;
import com.snow.flowable.domain.leave.LeaveFinishTaskDTO;
import com.snow.flowable.domain.leave.SysOaLeaveForm;
import com.snow.flowable.service.impl.FlowableServiceImpl;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.SysUser;
import com.snow.system.service.ISysSequenceService;
import com.snow.system.service.impl.SysOaLeaveServiceImpl;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -163,25 +161,26 @@ public class SysOaLeaveController extends BaseController
public AjaxResult editSave(SysOaLeave sysOaLeave)
{
SysUser sysUser = ShiroUtils.getSysUser();
SysOaLeave oldSysOaLeave = sysOaLeaveService.selectSysOaLeaveById(sysOaLeave.getId());
sysOaLeave.setApplyPerson(sysUser.getUserName());
int i = sysOaLeaveService.updateSysOaLeave(sysOaLeave);
SysOaLeave newSysOaLeave = sysOaLeaveService.selectSysOaLeaveById(sysOaLeave.getId());
//发起审批
StartProcessDTO startProcessDTO=new StartProcessDTO();
startProcessDTO.setBusinessKey(oldSysOaLeave.getLeaveNo());
startProcessDTO.setProcessDefinitionKey(FlowConstants.SNOW_OA_LEAVE);
startProcessDTO.setStartUserId(String.valueOf(sysUser.getUserId()));
Map<String, Object> map = BeanUtil.beanToMap(sysOaLeave);
startProcessDTO.setVariables(map);
ProcessInstance processInstance = flowableService.startProcessInstanceByKey(startProcessDTO);
SysOaLeaveForm sysOaLeaveForm=new SysOaLeaveForm();
BeanUtils.copyProperties(sysOaLeave,sysOaLeaveForm);
sysOaLeaveForm.setBusinessKey(newSysOaLeave.getLeaveNo());
sysOaLeaveForm.setStartUserId(String.valueOf(sysUser.getUserId()));
sysOaLeaveForm.setClassInfoJson(com.alibaba.fastjson.JSON.toJSONString(newSysOaLeave));
sysOaLeaveForm.setClassPackName(SysOaLeaveForm.class.getCanonicalName());
ProcessInstance processInstance = flowableService.startProcessInstanceByAppForm(sysOaLeaveForm);
//提交
CompleteTaskDTO completeTaskDTO=new CompleteTaskDTO();
completeTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
Task task= flowableService.getTaskProcessInstanceById(processInstance.getProcessInstanceId());
completeTaskDTO.setTaskId(task.getId());
completeTaskDTO.setIsPass(true);
flowableService.completeTask(completeTaskDTO);
sysOaLeave.setCreateBy(sysUser.getUserName());
sysOaLeave.setApplyPerson(sysUser.getUserName());
BeanUtils.copyProperties(sysOaLeave,oldSysOaLeave);
sysOaLeave.setProcessInstanceId(processInstance.getProcessInstanceId());
return toAjax(sysOaLeaveService.updateSysOaLeave(sysOaLeave));
return toAjax(i);
}
/**
@ -282,4 +281,36 @@ public class SysOaLeaveController extends BaseController
int i = sysOaLeaveService.updateSysOaLeaveByLeaveNo(sysOaLeave);
return toAjax(i);
}
/**
* 重新发起申请
*/
@Log(title = "重新发起申请", businessType = BusinessType.UPDATE)
@PostMapping("/reStartTask")
@ResponseBody
public AjaxResult reStartTask(LeaveFinishTaskDTO sysOaLeave)
{
SysUser sysUser = ShiroUtils.getSysUser();
sysOaLeave.setApplyPerson(sysUser.getUserName());
int i = sysOaLeaveService.updateSysOaLeave(sysOaLeave);
SysOaLeave newSysOaLeave = sysOaLeaveService.selectSysOaLeaveById(sysOaLeave.getId());
String leaveString= JSON.toJSONString(newSysOaLeave);
//提交
CompleteTaskDTO completeTaskDTO=new CompleteTaskDTO();
completeTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
completeTaskDTO.setTaskId(sysOaLeave.getTaskId());
completeTaskDTO.setComment(sysOaLeave.getSuggestion());
Integer checkStatus = sysOaLeave.getCheckStatus();
if(checkStatus==0){
completeTaskDTO.setIsPass(true);
}else {
completeTaskDTO.setIsPass(false);
}
Map<String, Object> map=Maps.newHashMap();
map.put(FlowConstants.BUS_VAR,leaveString);
completeTaskDTO.setParamMap(map);
flowableService.completeTask(completeTaskDTO);
return toAjax(i);
}
}

View File

@ -0,0 +1,126 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('人事审批')" />
<th:block th:include="include :: jsonview-css" />
<th:block th:include="include :: bootstrap-fileinput-css"/>
</head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="signupForm" th:object="${sysOaLeave}">
<div class="row">
<div class="col-sm-offset-0 col-sm-10">
<button type="button" class="btn btn-sm btn-primary" onclick="submitCheckHandler()"><i class="fa fa-check"></i>重新申请</button>&nbsp;
<button type="button" class="btn btn-sm btn-danger" onclick="submitHandler()"><i class="fa fa-remove"></i>删除</button>&nbsp;
</div>
</div>
<br/>
<h4 class="form-header h4">请假信息</h4>
<input name="id" th:field="*{id}" type="hidden">
<input class="form-control" type="hidden" name="taskId" th:value="${taskId}"/>
<div class="form-group">
<label class="col-sm-3 control-label">请假单号:</label>
<div class="col-sm-8">
<input name="name" th:field="*{leaveNo}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">请假名称:</label>
<div class="col-sm-8">
<input name="name" th:field="*{name}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">请假理由:</label>
<div class="col-sm-8">
<textarea name="reason" class="form-control">[[*{reason}]]</textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">开始时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="startTime" id="startTime" th:value="${#dates.format(sysOaLeave.startTime, 'yyyy-MM-dd HH:mm:ss')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">结束时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="endTime" id="endTime" th:value="${#dates.format(sysOaLeave.endTime, 'yyyy-MM-dd HH:mm:ss')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">附件:</label>
<div class="col-sm-8">
<input type="hidden" name="fileUrl" th:field="*{fileUrl}">
<div class="file-loading">
<input class="form-control file-upload" id="fileUrl" name="file" type="file">
</div>
</div>
</div>
<h4 class="form-header h4">填写信息</h4>
<div class="form-group">
<label class="col-sm-3 control-label">重新申请说明:</label>
<div class="col-sm-8">
<textarea name="suggestion" class="form-control"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">审批附件:</label>
<div class="col-sm-8">
<input type="hidden" name="suggestionFileUrl" >
<div class="file-loading">
<input class="form-control file-upload" id="suggestionFileUrl" name="file" type="file">
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: jsonview-js" />
<th:block th:include="include :: bootstrap-fileinput-js"/>
<script th:inline="javascript">
$(".file-upload").each(function (i) {
var val = $("input[name='" + this.id + "']").val();
$(this).fileinput({
'uploadUrl': '/common/upload',
initialPreviewAsData: true,
initialPreview: [val],
maxFileCount: 1,
autoReplace: true
}).on('fileuploaded', function (event, data, previewId, index) {
$("input[name='" + event.currentTarget.id + "']").val(data.response.url)
}).on('fileremoved', function (event, id, index) {
$("input[name='" + event.currentTarget.id + "']").val('')
})
$(this).fileinput('_initFileActions');
});
$("#signupForm").validate({
focusCleanup: true
});
function submitCheckHandler() {
if ($.validate.form()) {
var data = $("#signupForm").serializeArray();
data.push({"name": "checkStatus", "value": 0});
$.operate.saveTab("/system/leave/reStartTask", data);
}
}
function submitHandler() {
if ($.validate.form()) {
var data = $("#signupForm").serializeArray();
data.push({"name": "checkStatus", "value": 1});
$.operate.saveTab("/system/leave/reStartTask", data);
}
}
</script>
</body>
</html>

View File

@ -23,5 +23,9 @@ public enum ProcessStatus
/**
* 审批驳回
*/
REJECT
REJECT,
/**
* 取消
*/
CANCEL
}

View File

@ -1,4 +1,4 @@
package com.snow.flowable.common;
package com.snow.flowable.common.constants;
/**
* @author qimingjin
@ -28,4 +28,17 @@ public class FlowConstants {
*/
public static final String OPINION="OPINION";
/**
* 业务参数常量
*/
public static final String BUS_VAR="bus_var";
/**
* 当前类的包名
*/
public static final String CLASS_PACK_NAME="classPackName";
/**
* 流程开始用户标识
*/
public static final String START_USER_ID="startUserId";
}

View File

@ -0,0 +1,41 @@
package com.snow.flowable.common.enums;
/**
* @author qimingjin
* @Title: 流程定义枚举
* @Description:
* @date 2020/12/7 15:54
*/
public enum FlowDefEnum {
SNOW_OA_LEAVE("snow_oa_leave", "请假申请流程"),
NO_FINISHED("", "");
private final String code;
private final String info;
FlowDefEnum(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
public static FlowDefEnum getByCode(String code) {
for (FlowDefEnum value : FlowDefEnum.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
}

View File

@ -1,8 +1,12 @@
package com.snow.flowable.domain;
import com.snow.flowable.common.enums.FlowDefEnum;
import lombok.Data;
import org.json.JSONObject;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Map;
/**
* @program: snow
@ -11,21 +15,36 @@ import java.io.Serializable;
* @create: 2020-12-05 17:05
**/
@Data
public class AppForm implements Serializable {
/**
* 流程ID
*/
private String processInstanceId;
/**
* 业务参数
*/
private String businessKey;
public abstract class AppForm implements Serializable {
/**
* 流程发起人
*/
@NotBlank(message = "流程发起人不能为空")
private String startUserId;
/**
* 流程申请单需实现此方法,返回申请单对应的流程定义.
* 一个流程对应一个申请单.(暂时)
*
* @return 流程定义
*/
public abstract FlowDefEnum getFlowDef();
/**
* 业务参数
*/
@NotBlank(message = "业务参数不能为空")
private String businessKey;
/**
* 业务数据JSOn
*/
private String classInfoJson;
/**
* 当前类的包名称
*/
@NotBlank(message = "当前类的包名称不能为空")
private String classPackName;
}

View File

@ -0,0 +1,37 @@
package com.snow.flowable.domain.leave;
import com.snow.system.domain.SysOaLeave;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-11-23 22:13
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LeaveFinishTaskDTO extends SysOaLeave implements Serializable {
private String taskId;
private String suggestion;
private String suggestionFileUrl;
/**
* 0通过1--驳回
*/
private Integer checkStatus;
/**
* 业务参数
*/
private String businessKey;
}

View File

@ -0,0 +1,57 @@
package com.snow.flowable.domain.leave;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.snow.flowable.common.enums.FlowDefEnum;
import com.snow.flowable.domain.AppForm;
import lombok.Data;
import java.util.Date;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2020/12/7 11:12
*/
@Data
public class SysOaLeaveForm extends AppForm {
/** id */
private Integer id;
/** 请假名称 */
private String name;
/** 请假理由 */
private String reason;
/** 开始时间 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
/** 结束时间 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
/** 流程状态0--待审批1-审批中2--审批通过3--已驳回) */
private Integer processStatus;
/** 流程实例ID */
private String processInstanceId;
/** 申请人 */
private String applyPerson;
/** 附件 */
private String fileUrl;
/** 请假单号 */
private String leaveNo;
@Override
public FlowDefEnum getFlowDef() {
return FlowDefEnum.SNOW_OA_LEAVE;
}
}

View File

@ -0,0 +1,32 @@
package com.snow.flowable.listener;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
/**
* @author qimingjin
* @Title:
* @Description: 全局事件监听
* @date 2020/12/7 18:13
*/
public class AbstartctEventListener implements FlowableEventListener {
@Override
public void onEvent(FlowableEvent flowableEvent) {
}
@Override
public boolean isFailOnException() {
return false;
}
@Override
public boolean isFireOnTransactionLifecycleEvent() {
return false;
}
@Override
public String getOnTransaction() {
return null;
}
}

View File

@ -0,0 +1,144 @@
package com.snow.flowable.listener;
import com.snow.flowable.common.constants.FlowConstants;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.service.FlowableService;
import com.snow.flowable.service.impl.AppFormServiceImpl;
import com.snow.system.service.impl.SysUserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
/**
* @program: snow
* @description 执行监听器
* @author: 没用的阿吉
* @create: 2020-12-05 16:59
**/
@Slf4j
public abstract class AbstractExecutionListener<T extends AppForm> implements ExecutionListener {
private ThreadLocal<T> appFormLocal = new ThreadLocal<>();
private ThreadLocal<DelegateExecution> delegateExecutionLocal=new ThreadLocal();
@Autowired
private FlowableService flowableService;
@Autowired
private SysUserServiceImpl sysUserService;
@Autowired
private AppFormServiceImpl appFormService;
@Override
@Transactional
public void notify(DelegateExecution delegateExecution) {
try {
delegateExecutionLocal.set(delegateExecution);
execute();
} finally {
//移除threadLocal变量保证数据唯一
appFormLocal.remove();
delegateExecutionLocal.remove();
}
}
protected void execute() {
try {
process();
} catch (RuntimeException e) {
log.error("执行任务异常", e);
throw e;
}
}
/**
* 抽象需要执行的程序类
*/
protected abstract void process();
protected DelegateExecution getExecution() {
return delegateExecutionLocal.get();
}
/**
* 设置流程节点的变量
*
* @param key 变量名
* @param value 变量值
*/
protected void setVariable(String key, Object value) {
getExecution().setVariable(key, value);
}
/**
* 设置节点本地变量
*
* @param key 变量名
* @param value 变量值
*/
protected void setVariableLocal(String key, Object value) {
getExecution().setVariableLocal(key, value);
}
/**
* 获取流程变量
*/
@SuppressWarnings("unchecked")
protected <V> V getVariable(String key) {
return (V) getExecution().getVariable(key);
}
/**
* 获取流程节点本地变量
*/
protected <V> V getVariableLocal(String key) {
return (V) getExecution().getVariableLocal(key);
}
/**
* 流程对应的业务主键
*/
protected String getBusinessKey() {
return getExecution().getProcessInstanceBusinessKey();
}
/**
* 流程实例ID
*/
protected String getProcessInstanceId() {
return getExecution().getProcessInstanceId();
}
/**
* 获取流程开始用户
* @return
*/
protected String getStartUserName() {
String startUserId =getVariable(FlowConstants.START_USER_ID);
log.info("获取到的开始人startUserId:{}",startUserId);
return Optional.ofNullable(sysUserService.selectUserById(Long.parseLong(startUserId)).getUserName()).orElse("");
}
/**
* 获取表单数据
* @return
*/
public T getAppForms(){
String busVar = getVariable(FlowConstants.BUS_VAR);
String classPackName = getVariable(FlowConstants.CLASS_PACK_NAME);
T t = appFormLocal.get();
if(t==null){
appFormLocal.set(appFormService.getAppFrom(busVar,classPackName));
t=appFormLocal.get();
}
return t;
}
}

View File

@ -0,0 +1,122 @@
package com.snow.flowable.listener;
import com.snow.flowable.common.constants.FlowConstants;
import com.snow.flowable.domain.CompleteTaskDTO;
import com.snow.flowable.service.FlowableService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2020/12/7 16:39
*/
@Slf4j
public abstract class AbstractTaskListener<T extends CompleteTaskDTO> implements TaskListener {
@Autowired
private FlowableService flowableService;
private ThreadLocal<T> threadLocal=new ThreadLocal();
private ThreadLocal<DelegateTask> delegateTaskThreadLocal=new ThreadLocal<>();
@Override
public void notify(DelegateTask delegateTask) {
try {
delegateTaskThreadLocal.set(delegateTask);
processTask();
} finally {
delegateTaskThreadLocal.remove();
}
}
protected abstract void processTask();
/**
* 设置流程节点的变量
*
* @param key 变量名
* @param value 变量值
*/
protected void setVariable(String key, Object value) {
getDelegateTask().setVariable(key, value);
}
/**
* 设置节点本地变量
*
* @param key 变量名
* @param value 变量值
*/
protected void setVariableLocal(String key, Object value) {
getDelegateTask().setVariableLocal(key, value);
}
/**
* 根据key获取节点本地变量
* @param key
* @param <V>
* @return
*/
protected <V> V getVariableLocal(String key){
return (V)getDelegateTask().getVariableLocal(key);
}
/**
* 获取流程变量
* @param key
* @param <V>
* @return
*/
protected <V> V getVariable(String key){
return (V)getDelegateTask().getVariable(key);
}
protected <V> V getVariable(String key, Class<V> varClass) {
return getDelegateTask().getVariable(key, varClass);
}
protected DelegateTask getDelegateTask(){
return delegateTaskThreadLocal.get();
}
/**
* 获取审批结果
* @return
*/
protected Boolean getApprovalResult(){
return getVariable(FlowConstants.IS_PASS);
}
/**
* 流程实例ID
*/
protected String getProcessInstanceId() {
return getDelegateTask().getProcessInstanceId();
}
/**
* 流程对应的业务主键
*/
protected String getBusinessKey() {
ProcessInstance processInstance = flowableService.getProcessInstanceById(getProcessInstanceId());
return processInstance.getBusinessKey();
}
/**
* 获取流程发起人
* @return
*/
protected String getStartUserId() {
ProcessInstance processInstance = flowableService.getProcessInstanceById(getProcessInstanceId());
return processInstance.getStartUserId();
}
/**
* 获取节点名称
*/
protected String getTaskName() {
return getDelegateTask().getName();
}
}

View File

@ -1,58 +0,0 @@
package com.snow.flowable.listener;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.service.FlowableService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @program: snow
* @description 执行监听器
* @author: 没用的阿吉
* @create: 2020-12-05 16:59
**/
@Component
@Slf4j
public class CommonEventListener implements ExecutionListener {
public ThreadLocal<AppForm> threadLocalAppForm=new ThreadLocal();
@Autowired
private FlowableService flowableService;
@Override
public void notify(DelegateExecution delegateExecution) {
Map<String, Object> variables = delegateExecution.getVariables();
String processInstanceId = delegateExecution.getProcessInstanceId();
log.info("===================>{}",processInstanceId);
setAppForms(processInstanceId);
}
public void setAppForms(String processInstanceId){
HistoricProcessInstance historicProcessInstance = flowableService.getHistoricProcessInstanceById(processInstanceId);
AppForm appForm=new AppForm();
appForm.setBusinessKey(historicProcessInstance.getBusinessKey());
appForm.setProcessInstanceId(historicProcessInstance.getId());
appForm.setStartUserId(historicProcessInstance.getStartUserId());
threadLocalAppForm.set(appForm);
}
public Object getVariable(String variableName){
return null;
}
}

View File

@ -1,11 +1,11 @@
package com.snow.flowable.listener.leave;
import com.snow.common.enums.ProcessStatus;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.listener.CommonEventListener;
import com.snow.flowable.domain.leave.SysOaLeaveForm;
import com.snow.flowable.listener.AbstractExecutionListener;
import com.snow.system.domain.SysOaLeave;
import com.snow.system.service.impl.SysOaLeaveServiceImpl;
import org.flowable.engine.delegate.DelegateExecution;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -16,18 +16,18 @@ import org.springframework.stereotype.Service;
* @create: 2020-12-05 17:29
**/
@Service
public class LeaveEndListener extends CommonEventListener {
@Slf4j
public class LeaveEndListener extends AbstractExecutionListener<SysOaLeaveForm> {
@Autowired
private SysOaLeaveServiceImpl sysOaLeaveService;
@Override
public void notify(DelegateExecution delegateExecution) {
AppForm appForm = threadLocalAppForm.get();
protected void process() {
SysOaLeaveForm appForms = getAppForms();
String businessKey= getBusinessKey();
SysOaLeave sysOaLeave=new SysOaLeave();
sysOaLeave.setProcessStatus(ProcessStatus.PASS.ordinal());
sysOaLeave.setApplyPerson(appForm.getStartUserId());
sysOaLeave.setProcessInstanceId(appForm.getProcessInstanceId());
sysOaLeave.setLeaveNo(appForm.getBusinessKey());
sysOaLeave.setLeaveNo(businessKey);
sysOaLeaveService.updateSysOaLeaveByLeaveNo(sysOaLeave);
}
}

View File

@ -1,24 +0,0 @@
package com.snow.flowable.listener.leave;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-12-06 12:01
**/
@Service("leaveManagerTaskListener")
public class LeaveManagerTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
Map<String, Object> variables = delegateTask.getVariables();
Map<String, Object> variablesLocal = delegateTask.getVariablesLocal();
String assignee = delegateTask.getAssignee();
}
}

View File

@ -2,22 +2,14 @@ package com.snow.flowable.listener.leave;
import com.snow.common.enums.ProcessStatus;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.listener.CommonEventListener;
import com.snow.flowable.service.FlowableService;
import com.snow.flowable.domain.leave.SysOaLeaveForm;
import com.snow.flowable.listener.AbstractExecutionListener;
import com.snow.system.domain.SysOaLeave;
import com.snow.system.service.impl.SysOaLeaveServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @program: snow
* @description 开始监听器
@ -26,36 +18,21 @@ import java.util.Map;
**/
@Service
@Slf4j
public class LeaveStartListener extends CommonEventListener implements ExecutionListener {
public class LeaveStartListener extends AbstractExecutionListener<SysOaLeaveForm> {
@Autowired
private SysOaLeaveServiceImpl sysOaLeaveService;
@Autowired
private FlowableService flowableService;
protected void process() {
public void notify(DelegateExecution delegateExecution) {
Map<String, Object> variables = delegateExecution.getVariables();
VariableInstance variableInstance = delegateExecution.getVariableInstance(delegateExecution.getProcessInstanceId());
String leaveNo = String.valueOf(variables.get("leaveNo"));
String startUserId = String.valueOf(variables.get("startUserId"));
AppForm appForm=new AppForm();
appForm.setBusinessKey(leaveNo);
appForm.setProcessInstanceId(delegateExecution.getProcessInstanceId());
appForm.setStartUserId(startUserId);
threadLocalAppForm.set(appForm);
String processInstanceId = getProcessInstanceId();
String businessKey= getBusinessKey();
SysOaLeave sysOaLeave=new SysOaLeave();
sysOaLeave.setProcessStatus(ProcessStatus.CHECKING.ordinal());
sysOaLeave.setApplyPerson(appForm.getStartUserId());
sysOaLeave.setProcessInstanceId(appForm.getProcessInstanceId());
sysOaLeave.setLeaveNo(appForm.getBusinessKey());
sysOaLeave.setApplyPerson(getStartUserName());
sysOaLeave.setProcessInstanceId(processInstanceId);
sysOaLeave.setLeaveNo(businessKey);
sysOaLeaveService.updateSysOaLeaveByLeaveNo(sysOaLeave);
}
public void setAppForms(String processInstanceId){
}
}

View File

@ -0,0 +1,41 @@
package com.snow.flowable.listener.leave;
import com.snow.common.enums.ProcessStatus;
import com.snow.flowable.listener.AbstractTaskListener;
import com.snow.system.domain.SysOaLeave;
import com.snow.system.service.ISysOaLeaveService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-12-06 12:01
**/
@Service("leaveStartTaskListener")
@Slf4j
public class LeaveStartTaskListener extends AbstractTaskListener {
@Autowired
private ISysOaLeaveService sysOaLeaveService;
@Override
protected void processTask() {
SysOaLeave sysOaLeave=new SysOaLeave();
Boolean approvalResult = getApprovalResult();
String businessKey = getBusinessKey();
sysOaLeave.setLeaveNo(businessKey);
if(!approvalResult){
sysOaLeave.setProcessStatus(ProcessStatus.CANCEL.ordinal());
}else {
sysOaLeave.setProcessStatus(ProcessStatus.CHECKING.ordinal());
}
sysOaLeaveService.updateSysOaLeaveByLeaveNo(sysOaLeave);
}
}

View File

@ -0,0 +1,14 @@
package com.snow.flowable.service;
import com.snow.flowable.domain.AppForm;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2020/12/7 10:19
*/
public interface AppFormService {
<A extends AppForm> A getAppFrom(String classInfoJson,String className);
<A extends AppForm> A getAppFrom(String classInfoJson,Class<A> className);
}

View File

@ -75,6 +75,13 @@ public interface FlowableService {
*/
ProcessInstance startProcessInstanceByKey(StartProcessDTO startProcessDTO);
/**
* APP开启流程
* @param appForm
* @return
*/
ProcessInstance startProcessInstanceByAppForm(AppForm appForm);
/**
* 根据任务ID获取代办
* @param taskId

View File

@ -0,0 +1,44 @@
package com.snow.flowable.service.impl;
import com.alibaba.fastjson.JSON;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.service.AppFormService;
import com.snow.system.domain.SysOaLeave;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author qimingjin
* @Title:
* @Description:
* @date 2020/12/7 10:20
*/
@Service
@Slf4j
public class AppFormServiceImpl implements AppFormService {
@Override
public <A extends AppForm> A getAppFrom(String classInfoJson,String className) {
return JSON.parseObject(classInfoJson, getFormClass(className));
}
@Override
public <A extends AppForm> A getAppFrom(String classInfoJson,Class<A> className) {
return JSON.parseObject(classInfoJson, className);
}
private <A> Class<A> getFormClass(String className) {
try {
return (Class<A>) Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception{
Class<SysOaLeave> sysOaLeaveClass = SysOaLeave.class;
Class<?> sysOaLeaveForm = Class.forName("com.snow.flowable.domain.leave.SysOaLeaveForm");
System.out.println(sysOaLeaveForm);
}
}

View File

@ -1,10 +1,10 @@
package com.snow.flowable.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.Lists;
@ -12,7 +12,7 @@ import com.google.common.collect.Maps;
import com.snow.common.core.page.PageModel;
import com.snow.common.core.text.Convert;
import com.snow.common.exception.BusinessException;
import com.snow.flowable.common.FlowConstants;
import com.snow.flowable.common.constants.FlowConstants;
import com.snow.flowable.domain.*;
import com.snow.flowable.enums.FlowFinishedStatusEnum;
import com.snow.flowable.service.FlowableService;
@ -24,12 +24,10 @@ import com.snow.system.service.ISysRoleService;
import com.snow.system.service.impl.SysUserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
@ -38,16 +36,13 @@ import org.flowable.engine.repository.*;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Attachment;
import org.flowable.engine.task.Comment;
import org.flowable.idm.api.User;
import org.flowable.image.ProcessDiagramGenerator;
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.flowable.ui.modeler.domain.Model;
import org.flowable.ui.modeler.repository.ModelRepository;
import org.flowable.ui.modeler.service.ModelServiceImpl;
import org.flowable.ui.modeler.serviceapi.ModelService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -272,7 +267,7 @@ public class FlowableServiceImpl implements FlowableService {
identityService.setAuthenticatedUserId(startUserId);
}
Map<String, Object> paramMap =CollectionUtils.isEmpty(startProcessDTO.getVariables())?Maps.newHashMap():startProcessDTO.getVariables();
paramMap.put("startUserId",startUserId);
paramMap.put(FlowConstants.START_USER_ID,startUserId);
if(!CollectionUtils.isEmpty(paramMap)){
processInstance = runtimeService.startProcessInstanceByKey(startProcessDTO.getProcessDefinitionKey(),startProcessDTO.getBusinessKey(),paramMap);
@ -284,7 +279,19 @@ public class FlowableServiceImpl implements FlowableService {
return processInstance;
}
@Override
public ProcessInstance startProcessInstanceByAppForm(AppForm appForm) {
String startUserId=appForm.getStartUserId();
//业务参数转成map
Map<String, Object> paramMap = BeanUtil.beanToMap(appForm);
identityService.setAuthenticatedUserId(startUserId);
paramMap.put(FlowConstants.BUS_VAR,appForm.getClassInfoJson());
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(appForm.getFlowDef().getCode(),appForm.getBusinessKey(),paramMap);
//这个方法最终使用一个ThreadLocal类型的变量进行存储也就是与当前的线程绑定所以流程实例启动完毕之后需要设置为null防止多线程的时候出问题
identityService.setAuthenticatedUserId(null);
return processInstance;
}
@Override
@ -389,6 +396,7 @@ public class FlowableServiceImpl implements FlowableService {
);
}
paramMap.put(CompleteTaskDTO.IS_PASS,completeTaskDTO.getIsPass());
//claim the task当任务分配给了某一组人员时需要该组人员进行抢占抢到了就将该任务给谁处理其他人不能处理认领任务
taskService.claim(task.getId(),completeTaskDTO.getUserId());
taskService.complete(task.getId(),paramMap,true);