diff --git a/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowController.java b/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowController.java index a7bae4c..4b7381c 100644 --- a/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowController.java +++ b/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowController.java @@ -1,17 +1,22 @@ package com.snow.web.controller.flowable; +import com.alibaba.fastjson.JSON; import com.snow.common.core.controller.BaseController; import com.snow.common.core.domain.AjaxResult; import com.snow.common.core.page.PageModel; import com.snow.common.core.page.TableDataInfo; import com.snow.common.exception.BusinessException; import com.snow.common.utils.StringUtils; +import com.snow.flowable.common.constants.FlowConstants; import com.snow.flowable.domain.*; +import com.snow.flowable.domain.leave.SysOaLeaveForm; +import com.snow.flowable.service.AppFormService; import com.snow.flowable.service.impl.FlowableServiceImpl; import com.snow.framework.util.ShiroUtils; import com.snow.system.domain.SysOaLeave; import com.snow.system.domain.SysUser; import com.snow.system.service.ISysOaLeaveService; +import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.task.api.Task; @@ -33,6 +38,7 @@ import java.util.List; **/ @Controller @RequestMapping("/flow") +@Slf4j public class FlowController extends BaseController { private String prefix = "flow"; @@ -40,6 +46,8 @@ public class FlowController extends BaseController { private ISysOaLeaveService sysOaLeaveService; @Autowired private FlowableServiceImpl flowableService; + @Autowired + private AppFormService appFormService; /** @@ -97,9 +105,31 @@ public class FlowController extends BaseController { SysUser sysUser = ShiroUtils.getSysUser(); processInstanceDTO.setStartedUserId(String.valueOf(sysUser.getUserId())); PageModel historicProcessInstance = flowableService.getHistoricProcessInstance(processInstanceDTO); + log.info(JSON.toJSONString(historicProcessInstance.getPagedRecords())); return getFlowDataTable(historicProcessInstance); } + + + /** + * 跳转我发起的流程详情 + */ + @GetMapping("/myStartProcessDetail") + @RequiresPermissions("system:flow:myStartProcessDetail") + public String myStartProcessDetail(String processInstanceId,ModelMap modelMap) + { + //已审批的 + HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO(); + historicTaskInstanceDTO.setProcessInstanceId(processInstanceId); + //historicTaskInstanceDTO.setProcessStatus(1); + List historicTaskInstanceList= flowableService.getHistoricTaskInstanceNoPage(historicTaskInstanceDTO); + AppForm appFrom = appFormService.getAppFromBySerializable(processInstanceId); + modelMap.put("historicTaskInstanceList",historicTaskInstanceList); + modelMap.put("processInstanceId",processInstanceId); + modelMap.put("busVarUrl",appFrom.getBusVarUrl()); + return prefix +"/myStartProcessDetail"; + } + @RequiresPermissions("flow:process:getMyTakePartInProcess") @GetMapping("/toMyTakePartInProcess") public String getMyTakePartInProcess() diff --git a/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowModelerController.java b/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowModelerController.java index 3f84613..eb81338 100644 --- a/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowModelerController.java +++ b/snow-admin/src/main/java/com/snow/web/controller/flowable/FlowModelerController.java @@ -125,12 +125,10 @@ public class FlowModelerController extends BaseController */ @RequiresPermissions("modeler:flow:getProcessDiagram") @GetMapping("/getProcessDiagram") - @ResponseBody - public void getProcessDiagram(String processInstanceId,HttpServletResponse response) + public void getProcessDiagram(String processInstanceId,HttpServletResponse response,ModelMap modelMap) { - flowableService.getFlowableProcessImage(processInstanceId,response); + flowableService.getFlowableProcessImage(processInstanceId, response); } - /** * 删除发布 */ diff --git a/snow-admin/src/main/java/com/snow/web/controller/system/SysOaLeaveController.java b/snow-admin/src/main/java/com/snow/web/controller/system/SysOaLeaveController.java index f3a1c8a..5606163 100644 --- a/snow-admin/src/main/java/com/snow/web/controller/system/SysOaLeaveController.java +++ b/snow-admin/src/main/java/com/snow/web/controller/system/SysOaLeaveController.java @@ -10,13 +10,12 @@ 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.utils.StringUtils; 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.AppFormService; import com.snow.flowable.service.impl.FlowableServiceImpl; import com.snow.framework.util.ShiroUtils; import com.snow.system.domain.SysUser; @@ -29,11 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.transaction.annotation.Transactional; import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import com.snow.common.annotation.Log; import com.snow.common.enums.BusinessType; import com.snow.system.domain.SysOaLeave; @@ -63,6 +58,9 @@ public class SysOaLeaveController extends BaseController @Autowired private ISysSequenceService sequenceService; + @Autowired + private AppFormService appFormService; + @RequiresPermissions("system:leave:view") @GetMapping() @@ -174,8 +172,9 @@ public class SysOaLeaveController extends BaseController BeanUtils.copyProperties(sysOaLeave,sysOaLeaveForm); sysOaLeaveForm.setBusinessKey(newSysOaLeave.getLeaveNo()); sysOaLeaveForm.setStartUserId(String.valueOf(sysUser.getUserId())); - sysOaLeaveForm.setBusVarJson(com.alibaba.fastjson.JSON.toJSONString(newSysOaLeave)); + sysOaLeaveForm.setBusVarJson(com.alibaba.fastjson.JSON.toJSONString(sysOaLeaveForm)); sysOaLeaveForm.setClassPackName(SysOaLeaveForm.class.getCanonicalName()); + sysOaLeaveForm.setBusVarUrl("/system/leave/leaveDetail"); ProcessInstance processInstance = flowableService.startProcessInstanceByAppForm(sysOaLeaveForm); //提交 CompleteTaskDTO completeTaskDTO=new CompleteTaskDTO(); @@ -207,6 +206,16 @@ public class SysOaLeaveController extends BaseController return prefix + "/detail"; } + /** + * 请假单详情 + */ + @GetMapping("/leaveDetail") + public String leaveDetail(@RequestParam("processInstanceId") String processInstanceId, ModelMap mmap) + { + SysOaLeaveForm appFrom = appFormService.getAppFromBySerializable(processInstanceId); + mmap.put("sysOaLeave", appFrom); + return prefix + "/leaveDetail"; + } /** * 删除请假单 */ diff --git a/snow-admin/src/main/resources/static/ruoyi/js/jquery-ajax-blob-arraybuffer.js b/snow-admin/src/main/resources/static/ruoyi/js/jquery-ajax-blob-arraybuffer.js new file mode 100644 index 0000000..a38d9b2 --- /dev/null +++ b/snow-admin/src/main/resources/static/ruoyi/js/jquery-ajax-blob-arraybuffer.js @@ -0,0 +1,76 @@ +(function ($) { + /** + * Register ajax transports for blob send/recieve and array buffer send/receive via XMLHttpRequest Level 2 + * within the comfortable framework of the jquery ajax request, with full support for promises. + * + * Notice the +* in the dataType string? The + indicates we want this transport to be prepended to the list + * of potential transports (so it gets first dibs if the request passes the conditions within to provide the + * ajax transport, preventing the standard transport from hogging the request), and the * indicates that + * potentially any request with any dataType might want to use the transports provided herein. + * + * Remember to specify 'processData:false' in the ajax options when attempting to send a blob or arraybuffer - + * otherwise jquery will try (and fail) to convert the blob or buffer into a query string. + * + * This revision now includes sending headers, resolves the stack overflow in abort(), and sets the status text + * into the response if the request is unsuccessful. + */ + $.ajaxTransport("+*", function (options, originalOptions, jqXHR) { + // Test for the conditions that mean we can/want to send/receive blobs or arraybuffers - we need XMLHttpRequest + // level 2 (so feature-detect against window.FormData), feature detect against window.Blob or window.ArrayBuffer, + // and then check to see if the dataType is blob/arraybuffer or the data itself is a Blob/ArrayBuffer + if (window.FormData && ((options.dataType && (options.dataType == 'blob' || options.dataType == 'arraybuffer')) || + (options.data && ((window.Blob && options.data instanceof Blob) || + (window.ArrayBuffer && options.data instanceof ArrayBuffer))) + )) { + var xhr; + + return { + /** + * Return a transport capable of sending and/or receiving blobs - in this case, we instantiate + * a new XMLHttpRequest and use it to actually perform the request, and funnel the result back + * into the jquery complete callback (such as the success function, done blocks, etc.) + * + * @param headers + * @param completeCallback + */ + send: function (headers, completeCallback) { + var url = options.url || window.location.href, + type = options.type || 'GET', + dataType = options.dataType || 'text', + data = options.data || null, + async = options.async || true; + + xhr = new XMLHttpRequest(); + xhr.addEventListener('load', function () { + var res = {}, + success = xhr.status >= 200 && xhr.status < 300 || xhr.status === 304; + + if (success) { + res[dataType] = xhr.response; + } else { + res.text = xhr.statusText; + } + + completeCallback(xhr.status, xhr.statusText, res, xhr.getAllResponseHeaders()); + }); + + xhr.open(type, url, async); + xhr.responseType = dataType; + + for (var key in headers) { + if (headers.hasOwnProperty(key)) { + xhr.setRequestHeader(key, headers[key]); + } + } + + xhr.send(data); + }, + abort: function () { + if (xhr) { + xhr.abort(); + } + } + }; + } + }); +})(jQuery); \ No newline at end of file diff --git a/snow-admin/src/main/resources/templates/flow/myStartProcess.html b/snow-admin/src/main/resources/templates/flow/myStartProcess.html index 66c67f9..c82258a 100644 --- a/snow-admin/src/main/resources/templates/flow/myStartProcess.html +++ b/snow-admin/src/main/resources/templates/flow/myStartProcess.html @@ -41,6 +41,8 @@ \ No newline at end of file diff --git a/snow-admin/src/main/resources/templates/flow/myStartProcessDetail.html b/snow-admin/src/main/resources/templates/flow/myStartProcessDetail.html new file mode 100644 index 0000000..3c0e873 --- /dev/null +++ b/snow-admin/src/main/resources/templates/flow/myStartProcessDetail.html @@ -0,0 +1,122 @@ + + + + + + +
+
+ + + +
+

流程图

+
+ +
+
+ +
+

审批节点

+
+
+
+ +
+

+
+
+
+ + +
+
+ + +
+ +
+ + +
+
+ +
+
+
+ + + + +
+
+
+
+
+ + + + +
+
+ +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+

业务数据

+

+

+ +
+

+ + +
+ + +
+
+ + + + \ No newline at end of file diff --git a/snow-admin/src/main/resources/templates/include.html b/snow-admin/src/main/resources/templates/include.html index 836847c..95411e7 100644 --- a/snow-admin/src/main/resources/templates/include.html +++ b/snow-admin/src/main/resources/templates/include.html @@ -41,6 +41,10 @@ + +
+ +
diff --git a/snow-admin/src/main/resources/templates/system/leave/detail.html b/snow-admin/src/main/resources/templates/system/leave/detail.html index 555f586..c8c8061 100644 --- a/snow-admin/src/main/resources/templates/system/leave/detail.html +++ b/snow-admin/src/main/resources/templates/system/leave/detail.html @@ -66,7 +66,7 @@
-

+

驳回 @@ -74,15 +74,15 @@

-

+

- - + +
diff --git a/snow-admin/src/main/resources/templates/system/leave/leaveDetail.html b/snow-admin/src/main/resources/templates/system/leave/leaveDetail.html new file mode 100644 index 0000000..d235a17 --- /dev/null +++ b/snow-admin/src/main/resources/templates/system/leave/leaveDetail.html @@ -0,0 +1,80 @@ + + + + + + + + +
+ +
+ +

请假信息

+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+ + +
+
+ + + + + + \ No newline at end of file diff --git a/snow-admin/src/test/java/com.snow/flowable/FlowableServiceTests.java b/snow-admin/src/test/java/com.snow/flowable/FlowableServiceTests.java index 1185e98..aadaf06 100644 --- a/snow-admin/src/test/java/com.snow/flowable/FlowableServiceTests.java +++ b/snow-admin/src/test/java/com.snow/flowable/FlowableServiceTests.java @@ -1,20 +1,26 @@ package com.snow.flowable; import com.alibaba.fastjson.JSON; -import com.fasterxml.jackson.annotation.JsonFormat; import com.google.common.collect.Maps; import com.snow.JunitTestApplication; import com.snow.flowable.domain.DeploymentQueryDTO; import com.snow.flowable.domain.StartProcessDTO; import com.snow.flowable.domain.TaskVO; import com.snow.flowable.service.FlowableService; +import com.snow.system.domain.SysUser; import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.TaskService; import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.identitylink.api.IdentityLink; +import org.flowable.identitylink.api.IdentityLinkInfo; +import org.flowable.task.api.Task; +import org.flowable.task.api.TaskQuery; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author qimingjin @@ -26,6 +32,8 @@ import java.util.Map; public class FlowableServiceTests extends JunitTestApplication { @Autowired private FlowableService flowableService; + @Autowired + private TaskService taskService; @Test public void startProcessInstanceByKey(){ @@ -52,4 +60,20 @@ public class FlowableServiceTests extends JunitTestApplication { List dynamicFlowNodeInfo = flowableService.getDynamicFlowNodeInfo("38505061-2d6b-11eb-b0ec-040e3c9c6b2f"); log.info(JSON.toJSONString(dynamicFlowNodeInfo)); } + + @Test + public void getTaskList(){ + TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId("1337010679969882112"); + List list = taskQuery.list(); + list.forEach(task -> { + List identityLinksForTask = taskService.getIdentityLinksForTask(task.getId()); + flowableService.getIdentityLinksForTask(task.getId(),""); + log.info(JSON.toJSONString(identityLinksForTask)); + }); + + + log.info(JSON.toJSONString(list)); + } + + } diff --git a/snow-flowable/src/main/java/com/snow/flowable/common/constants/FlowConstants.java b/snow-flowable/src/main/java/com/snow/flowable/common/constants/FlowConstants.java index 6f0cf63..5c11fa6 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/common/constants/FlowConstants.java +++ b/snow-flowable/src/main/java/com/snow/flowable/common/constants/FlowConstants.java @@ -34,6 +34,15 @@ public class FlowConstants { * 业务参数常量 */ public static final String BUS_VAR="bus_var_json"; + /** + * 表单数据 + */ + public static final String APP_FORM="appForm"; + + /** + * 跳转数据详情页 + */ + public static final String BUS_VAR_URL="busVarUrl"; /** * 当前类的包名 */ diff --git a/snow-flowable/src/main/java/com/snow/flowable/domain/AppForm.java b/snow-flowable/src/main/java/com/snow/flowable/domain/AppForm.java index f17a5c4..e993ebc 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/domain/AppForm.java +++ b/snow-flowable/src/main/java/com/snow/flowable/domain/AppForm.java @@ -15,6 +15,7 @@ import java.io.Serializable; @Data public abstract class AppForm implements Serializable { + private static final long serialVersionUID = -4544643731565791031L; /** * 流程发起人 */ @@ -28,6 +29,7 @@ public abstract class AppForm implements Serializable { @NotBlank(message = "业务参数不能为空") private String businessKey; + /** * 业务数据json */ @@ -38,6 +40,10 @@ public abstract class AppForm implements Serializable { @NotBlank(message = "当前类的包名称不能为空") private String classPackName; + /** + * 业务参数URL + */ + private String busVarUrl; /** * 流程申请单需实现此方法,返回申请单对应的流程定义. diff --git a/snow-flowable/src/main/java/com/snow/flowable/domain/HistoricTaskInstanceVO.java b/snow-flowable/src/main/java/com/snow/flowable/domain/HistoricTaskInstanceVO.java index fb4f944..c5df429 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/domain/HistoricTaskInstanceVO.java +++ b/snow-flowable/src/main/java/com/snow/flowable/domain/HistoricTaskInstanceVO.java @@ -21,56 +21,30 @@ import java.util.stream.Collectors; * @date 2020/11/26 16:41 */ @Data -public class HistoricTaskInstanceVO implements Serializable { - /** - * 历史任务id - */ - private String id; +public class HistoricTaskInstanceVO extends TaskVO implements Serializable { + /** * 流程执行ID */ private String executionId; - /** - * 流程实例id - */ - private String processInstanceId; + /** *流程名称 */ private String processName; - /** - *业务参数 - */ - private String businessKey; + /** * 任务定义ID */ private String taskDefinitionId; - /** - * 创建时间 - */ - @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") - private Date createTime; - /** - * 完成时间 - */ - @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") - private Date endTime; - /** - * 用时 - */ - private String spendTime; - /** - * 任务名称 - */ - private String name; + /** * 用户ID */ @@ -82,13 +56,10 @@ public class HistoricTaskInstanceVO implements Serializable { */ private String assigneeName; + /** - * 任务描述 + * 是否通过驳回 */ - private String description; - - private String category; - private String isPass; /** @@ -102,12 +73,11 @@ public class HistoricTaskInstanceVO implements Serializable { private List attachmentList; /** - * 任务变量 + * 任务节点变量 */ private Map taskLocalVariables; - private String formKey; /** * 流程变量 @@ -115,30 +85,23 @@ public class HistoricTaskInstanceVO implements Serializable { private Map processVariables; -/* private String scopeId; - private String subScopeId; - private String scopeType; - private String scopeDefinitionId; - private String propagatedStageInstanceId;*/ - private String deleteReason; - private String localizedName; - private String parentTaskId; - private String localizedDescription; + private String owner; - private String taskDefinitionKey; private int priority; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date dueDate; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date claimTime; @@ -148,7 +111,11 @@ public class HistoricTaskInstanceVO implements Serializable { HistoricTaskInstanceVO historicTaskInstanceVO=new HistoricTaskInstanceVO(); BeanUtils.copyProperties(t,historicTaskInstanceVO); historicTaskInstanceVO.setTaskLocalVariables(t.getTaskLocalVariables()); - + historicTaskInstanceVO.setTaskId(t.getId()); + historicTaskInstanceVO.setTaskName(t.getName()); + //老的createTime底层换成了time getCreateTime + historicTaskInstanceVO.setStartTime(t.getTime()); + historicTaskInstanceVO.setCompleteTime(t.getEndTime()); historicTaskInstanceVO.setProcessVariables(t.getProcessVariables()); return historicTaskInstanceVO; }).collect(Collectors.toList()); diff --git a/snow-flowable/src/main/java/com/snow/flowable/domain/ProcessInstanceVO.java b/snow-flowable/src/main/java/com/snow/flowable/domain/ProcessInstanceVO.java index 930dd64..789568a 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/domain/ProcessInstanceVO.java +++ b/snow-flowable/src/main/java/com/snow/flowable/domain/ProcessInstanceVO.java @@ -1,6 +1,8 @@ package com.snow.flowable.domain; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.snow.common.utils.StringUtils; import com.snow.common.utils.bean.BeanUtils; import com.snow.common.utils.spring.SpringUtils; @@ -35,83 +37,92 @@ public class ProcessInstanceVO implements Serializable { /** * 流程定义ID */ - public String processDefinitionId; + private String processDefinitionId; /** * 流程定义名称 */ - public String processDefinitionName; + private String processDefinitionName; /** * 流程定义key */ - public String processDefinitionKey; + private String processDefinitionKey; /** * 流程版本号 */ - public Integer processDefinitionVersion; + private Integer processDefinitionVersion; /** * 发布ID */ - public String deploymentId; + private String deploymentId; /** * 开始时间 */ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") - public Date startTime; + private Date startTime; /** * 结束时间 */ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") - public Date endTime; + private Date endTime; - public String endActivityId; + private String endActivityId; /** * 流程发起人ID */ - public String startUserId; + private String startUserId; /** * 流程发起人 */ - public String startUserName; + private String startUserName; - public String startActivityId; + private String startActivityId; /** * 删除理由 */ - public String deleteReason; + private String deleteReason; /** * 流程用时 */ - public String processSpendTime; + private String processSpendTime; /** * 父流程ID */ - public String superProcessInstanceId; + private String superProcessInstanceId; - public String tenantId; + private String tenantId; - public String description; + private String description; - public String callbackId; - - public String callbackType; + private String callbackId; + private String callbackType; + /** + * 表单详情URL + */ + private String fromDetailUrl; /** * 业务参数 */ - public String businessKey; + private String businessKey; /** * 是否结束(0--进行中,1--结束) */ - public Integer isFinished; + private Integer isFinished; - Map processVariables; + /** + * 业务流程参数 + */ + @JsonIgnoreProperties + private AppForm appForm; - public String processDefinitionCategory; + private Map processVariables; + + private String processDefinitionCategory; public static List warpList(List historicProcessInstanceList){ return historicProcessInstanceList.stream().map(t->{ diff --git a/snow-flowable/src/main/java/com/snow/flowable/domain/TaskVO.java b/snow-flowable/src/main/java/com/snow/flowable/domain/TaskVO.java index 467a4c7..c4ab70d 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/domain/TaskVO.java +++ b/snow-flowable/src/main/java/com/snow/flowable/domain/TaskVO.java @@ -1,6 +1,7 @@ package com.snow.flowable.domain; import com.fasterxml.jackson.annotation.JsonFormat; +import com.snow.system.domain.SysUser; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,6 +10,7 @@ import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; import java.util.List; +import java.util.Set; /** * @author qimingjin @@ -27,37 +29,79 @@ import java.util.List; @NoArgsConstructor public class TaskVO implements Serializable { + /** + * 任务ID + */ private String taskId; + /** + * 任务名称 + */ private String taskName; + /** + * 流程定义名称 + */ private String processDefinitionName; + /** + * 任务描述 + */ private String description; + /** + * 委托人 + */ private String owner; + /** + * 父任务ID + */ private String parentTaskId; + /** + * 租户ID + */ private String tenantId; /** * 任务处理人 */ private String Assignee; + /** + * 任务创建时间 + */ @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date createDate; + /** + * 分类 + */ private String category; + /** + * fromKey + */ private String formKey; + /** + * 流程实例id + */ private String processInstanceId; + /** + * 流程发起人id + */ private String startUserId; + /** + * 发起人名称 + */ private String startUserName; + /** + * 业务主键 + */ private String businessKey; /** * 任务发起时间 @@ -90,6 +134,6 @@ public class TaskVO implements Serializable { /** * 任务待处理人 */ - private List handleNameList; + private List handleUserList; } diff --git a/snow-flowable/src/main/java/com/snow/flowable/listener/AbstractExecutionListener.java b/snow-flowable/src/main/java/com/snow/flowable/listener/AbstractExecutionListener.java index f05334f..a7fb6f4 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/listener/AbstractExecutionListener.java +++ b/snow-flowable/src/main/java/com/snow/flowable/listener/AbstractExecutionListener.java @@ -27,8 +27,6 @@ public abstract class AbstractExecutionListener implements Ex private ThreadLocal appFormLocal = new ThreadLocal<>(); private ThreadLocal delegateExecutionLocal=new ThreadLocal(); - @Autowired - private FlowableService flowableService; @Autowired private SysUserServiceImpl sysUserService; @@ -129,11 +127,9 @@ public abstract class AbstractExecutionListener implements Ex * @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)); + appFormLocal.set(appFormService.getAppFrom(getProcessInstanceId())); t=appFormLocal.get(); } return t; diff --git a/snow-flowable/src/main/java/com/snow/flowable/service/AppFormService.java b/snow-flowable/src/main/java/com/snow/flowable/service/AppFormService.java index 66a67d1..cf72c8e 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/service/AppFormService.java +++ b/snow-flowable/src/main/java/com/snow/flowable/service/AppFormService.java @@ -11,4 +11,14 @@ import com.snow.flowable.domain.AppForm; public interface AppFormService { A getAppFrom(String classInfoJson,String className); A getAppFrom(String classInfoJson,Class className); + + /** + * 从流程中获取表单数据 + * @param processInstanceId + * @param + * @return + */ + A getAppFromBySerializable(String processInstanceId); + + A getAppFrom(String processInstanceId); } diff --git a/snow-flowable/src/main/java/com/snow/flowable/service/FlowableService.java b/snow-flowable/src/main/java/com/snow/flowable/service/FlowableService.java index 7ba8a45..58ef09b 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/service/FlowableService.java +++ b/snow-flowable/src/main/java/com/snow/flowable/service/FlowableService.java @@ -3,6 +3,7 @@ package com.snow.flowable.service; import com.snow.common.core.page.PageModel; import com.snow.flowable.domain.*; import com.snow.system.domain.ActDeModel; +import com.snow.system.domain.SysUser; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.Model; import org.flowable.engine.runtime.ProcessInstance; @@ -12,6 +13,7 @@ import org.flowable.task.api.history.HistoricTaskInstance; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; +import java.util.Set; /** * @author qimingjin @@ -97,6 +99,20 @@ public interface FlowableService { */ PageModel findTasksByUserId(String userId,TaskBaseDTO taskBaseDTO); + /** + * 根据任务ID获取关联待办人活着待办组的人 + * @param taskId + * @return + */ + Set getIdentityLinksForTask(String taskId,String type); + + /** + * 获取历史的 + * @param taskId + * @return + */ + Set getHistoricIdentityLinksForTask(String taskId); + /** * 完成任务 * @param completeTaskDTO @@ -108,6 +124,7 @@ public interface FlowableService { * @param httpServletResponse * @param processId */ + @Deprecated void getProcessDiagram(HttpServletResponse httpServletResponse, String processId); /** diff --git a/snow-flowable/src/main/java/com/snow/flowable/service/impl/AppFormServiceImpl.java b/snow-flowable/src/main/java/com/snow/flowable/service/impl/AppFormServiceImpl.java index e54afb9..2615570 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/service/impl/AppFormServiceImpl.java +++ b/snow-flowable/src/main/java/com/snow/flowable/service/impl/AppFormServiceImpl.java @@ -2,12 +2,19 @@ package com.snow.flowable.service.impl; import com.alibaba.fastjson.JSON; +import com.snow.flowable.common.constants.FlowConstants; import com.snow.flowable.domain.AppForm; import com.snow.flowable.service.AppFormService; +import com.snow.flowable.service.FlowableService; import com.snow.system.domain.SysOaLeave; import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.HistoryService; +import org.flowable.engine.history.HistoricProcessInstance; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Map; + /** * @author qimingjin * @Title: @@ -18,6 +25,10 @@ import org.springframework.stereotype.Service; @Slf4j public class AppFormServiceImpl implements AppFormService { + @Autowired + private FlowableService flowableService; + + @Override public A getAppFrom(String classInfoJson,String className) { return JSON.parseObject(classInfoJson, getFormClass(className)); @@ -28,6 +39,34 @@ public class AppFormServiceImpl implements AppFormService { return JSON.parseObject(classInfoJson, className); } + + @Override + public A getAppFromBySerializable(String processInstanceId) { + HistoricProcessInstance historicProcessInstance=flowableService.getHistoricProcessInstanceById(processInstanceId); + return getVariable(historicProcessInstance, FlowConstants.APP_FORM); + + } + + + + @Override + public A getAppFrom(String processInstanceId) { + HistoricProcessInstance historicProcessInstance=flowableService.getHistoricProcessInstanceById(processInstanceId); + String classInfoJson = getVariable(historicProcessInstance, FlowConstants.BUS_VAR); + String classPackName = getVariable(historicProcessInstance, FlowConstants.CLASS_PACK_NAME); + return getAppFrom(classInfoJson, classPackName); + } + + /** + * 获取流程变量 + * @param key + * @param + * @return + */ + protected V getVariable(HistoricProcessInstance historicProcessInstance,String key){ + return (V)historicProcessInstance.getProcessVariables().get(key); + } + private Class getFormClass(String className) { try { return (Class) Class.forName(className); @@ -35,10 +74,4 @@ public class AppFormServiceImpl implements AppFormService { throw new RuntimeException(e); } } - - public static void main(String[] args) throws Exception{ - Class sysOaLeaveClass = SysOaLeave.class; - Class sysOaLeaveForm = Class.forName("com.snow.flowable.domain.leave.SysOaLeaveForm"); - System.out.println(sysOaLeaveForm); - } } diff --git a/snow-flowable/src/main/java/com/snow/flowable/service/impl/FlowableServiceImpl.java b/snow-flowable/src/main/java/com/snow/flowable/service/impl/FlowableServiceImpl.java index aee7f0b..00d445c 100644 --- a/snow-flowable/src/main/java/com/snow/flowable/service/impl/FlowableServiceImpl.java +++ b/snow-flowable/src/main/java/com/snow/flowable/service/impl/FlowableServiceImpl.java @@ -39,6 +39,8 @@ 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.identitylink.api.IdentityLink; +import org.flowable.identitylink.api.history.HistoricIdentityLink; import org.flowable.image.ProcessDiagramGenerator; import org.flowable.task.api.Task; import org.flowable.task.api.TaskQuery; @@ -55,6 +57,7 @@ import org.springframework.util.StringUtils; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.Size; import java.awt.*; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -292,6 +295,7 @@ public class FlowableServiceImpl implements FlowableService { Map paramMap = BeanUtil.beanToMap(appForm); paramMap.remove("busVarJson"); identityService.setAuthenticatedUserId(startUserId); + paramMap.put(FlowConstants.APP_FORM,appForm); paramMap.put(FlowConstants.BUS_VAR,appForm.getBusVarJson()); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(appForm.getFlowDef().getCode(),appForm.getBusinessKey(),paramMap); @@ -371,8 +375,62 @@ public class FlowableServiceImpl implements FlowableService { return pageModel; } + @Override + public Set getIdentityLinksForTask(String taskId,String type){ + Set userList=new HashSet<>(); + List identityLinksForTask = taskService.getIdentityLinksForTask(taskId); + if(!CollectionUtils.isEmpty(identityLinksForTask)){ + identityLinksForTask.stream().filter(identityLink -> + !StringUtils.isEmpty(identityLink.getGroupId()) + &&identityLink.getType().equals(type) + ) + .forEach(identityLink -> { + String groupId = identityLink.getGroupId(); + List sysUsers = sysUserMapper.selectUserListByRoleId(groupId); + userList.addAll(sysUsers); + }); + identityLinksForTask.stream().filter(identityLink -> + !StringUtils.isEmpty(identityLink.getUserId()) + &&identityLink.getType().equals(type) + ) + .forEach(identityLink -> { + String userId = identityLink.getUserId(); + SysUser sysUsers = sysUserMapper.selectUserById(Long.parseLong(userId)); + userList.add(sysUsers); + }); + } + return userList; + } - + /** + * starter,USER_ID与PROC_INST_ID_,记录流程的发起者 + * candidate,USER_ID_ 或 GROUP_ID_ 其中一个必须有值、TASK_ID_有值,记录当前任务的指派人与指派组。 + * participant, USER_ID与PROC_INST_ID_有值,记录流程任务的参与者。 + * @param taskId + * @return + */ + @Override + public Set getHistoricIdentityLinksForTask(String taskId){ + Set userList=new HashSet<>(); + List historicIdentityLinksForTask = historyService.getHistoricIdentityLinksForTask(taskId); + if(!CollectionUtils.isEmpty(historicIdentityLinksForTask)){ + historicIdentityLinksForTask.stream().filter(identityLink -> !StringUtils.isEmpty(identityLink.getGroupId()) + &&identityLink.getType().equals("candidate")) + .forEach(identityLink -> { + String groupId = identityLink.getGroupId(); + List sysUsers = sysUserMapper.selectUserListByRoleId(groupId); + userList.addAll(sysUsers); + }); + historicIdentityLinksForTask.stream().filter(identityLink -> !StringUtils.isEmpty(identityLink.getUserId()) + &&identityLink.getType().equals("candidate")) + .forEach(identityLink -> { + String userId = identityLink.getUserId(); + SysUser sysUsers = sysUserMapper.selectUserById(Long.parseLong(userId)); + userList.add(sysUsers); + }); + } + return userList; + } @Override @Transactional(rollbackFor = Exception.class) public void completeTask(CompleteTaskDTO completeTaskDTO) { @@ -496,13 +554,19 @@ public class FlowableServiceImpl implements FlowableService { public HistoricProcessInstance getHistoricProcessInstanceById(String id){ return historyService.createHistoricProcessInstanceQuery() .processInstanceId(id) + //标识查询的时候返回流程变量参数,不然取不到 + .includeProcessVariables() .singleResult(); } + @Override public Task getTaskProcessInstanceById(String id){ return taskService.createTaskQuery() .processInstanceId(id) + .includeTaskLocalVariables() + .includeIdentityLinks() + .includeProcessVariables() .singleResult(); } @@ -537,7 +601,7 @@ public class FlowableServiceImpl implements FlowableService { historicTaskInstanceQuery.finished(); } } - historicTaskInstanceQuery.includeTaskLocalVariables().includeProcessVariables(); + historicTaskInstanceQuery.includeTaskLocalVariables().includeProcessVariables().includeIdentityLinks(); List list = historicTaskInstanceQuery.orderByTaskCreateTime().asc().list(); List historicTaskInstanceVOS = HistoricTaskInstanceVO.warpList(list); setHistoricTaskInstanceVos(historicTaskInstanceVOS); @@ -547,28 +611,33 @@ public class FlowableServiceImpl implements FlowableService { private void setHistoricTaskInstanceVos(List list){ list.parallelStream().forEach(t -> { + //保存待办人 + Set identityLinksForTask = getHistoricIdentityLinksForTask(t.getTaskId()); + Optional.ofNullable(identityLinksForTask).ifPresent(m->{ + List userNameList = identityLinksForTask.stream().map(SysUser::getUserName).collect(Collectors.toList()); + t.setHandleUserList(userNameList); + }); + if (!StringUtils.isEmpty(t.getAssignee())) { SysUser sysUser = sysUserService.selectUserById(Long.parseLong(t.getAssignee())); t .setAssigneeName(sysUser.getUserName()); - }else { - //下个节点 - } Optional.ofNullable( t.getTaskLocalVariables()).ifPresent(u->{ Object isPass =Optional.ofNullable(u.get(FlowConstants.IS_PASS)).orElse(""); + //处理审核条件 t.setIsPass(String.valueOf(isPass)); }); - List comment = taskService.getTaskComments(t.getId(), FlowConstants.OPINION); + List comment = taskService.getTaskComments(t.getTaskId(), FlowConstants.OPINION); - List taskAttachments = taskService.getTaskAttachments(t.getId()); + List taskAttachments = taskService.getTaskAttachments(t.getTaskId()); t.setCommentList(comment); t.setAttachmentList(taskAttachments); //计算任务历时 - if(!StringUtils.isEmpty(t.getEndTime())){ - String spendTime = DateUtil.formatBetween(DateUtil.between(t.getCreateTime(), t.getEndTime(), DateUnit.SECOND)); - t.setSpendTime(spendTime); + if(!StringUtils.isEmpty(t.getCompleteTime())){ + String spendTime = DateUtil.formatBetween(DateUtil.between(t.getStartTime(), t.getCompleteTime(), DateUnit.SECOND)); + t.setHandleTaskTime(spendTime); } HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(t.getProcessInstanceId()); t.setProcessName(historicProcessInstance.getProcessDefinitionName()); @@ -594,16 +663,16 @@ public class FlowableServiceImpl implements FlowableService { if(!CollectionUtils.isEmpty(historicTaskInstance)){ hisTaskVOList = historicTaskInstance.stream().map(t -> { TaskVO taskVO = new TaskVO(); - taskVO.setTaskName(t.getName()); + taskVO.setTaskName(t.getTaskName()); taskVO.setProcessInstanceId(t.getProcessInstanceId()); taskVO.setStartUserId(processInstance.getStartUserId()); taskVO.setStartUserName(getUserNameById(processInstance.getStartUserId())); taskVO.setTaskDefinitionKey(t.getTaskDefinitionKey()); - if (!StringUtils.isEmpty(t.getCreateTime())) { - taskVO.setCreateDate(t.getCreateTime()); + if (!StringUtils.isEmpty(t.getStartTime())) { + taskVO.setCreateDate(t.getStartTime()); } - if (!StringUtils.isEmpty(t.getEndTime())) { - taskVO.setCompleteTime(t.getEndTime()); + if (!StringUtils.isEmpty(t.getCompleteTime())) { + taskVO.setCompleteTime(t.getCompleteTime()); } if (!StringUtils.isEmpty(t.getAssignee())) { @@ -618,7 +687,7 @@ public class FlowableServiceImpl implements FlowableService { List futureTask = getFutureTask(processInstance); for(int i=0;i{ Map processVariables = t.getProcessVariables(); - - t.setProcessVariables(processVariables); + String url= Optional.ofNullable(String.valueOf(processVariables.get(FlowConstants.BUS_VAR_URL))).orElse(""); + if(!StringUtils.isEmpty(url)){ + t.setFromDetailUrl(url+"?processInstanceId="+t.getId()); + } + AppForm appForm=(AppForm)processVariables.get(FlowConstants.APP_FORM); + t.setAppForm(appForm); //计算流程用时 if(StringUtils.isEmpty(t.getEndTime())){ String spendTime = DateUtil.formatBetween(t.getStartTime(), new Date(), BetweenFormater.Level.SECOND); @@ -722,8 +795,8 @@ public class FlowableServiceImpl implements FlowableService { SysUser sysUser = sysUserService.selectUserById(Long.parseLong(t.getAssignee())); historicTaskInstanceVO.setAssignee(sysUser.getUserName()); } - String spendTime = DateUtil.formatBetween(DateUtil.between(t.getCreateTime(), t.getEndTime(), DateUnit.MS)); - historicTaskInstanceVO.setSpendTime(spendTime); + String spendTime = DateUtil.formatBetween(DateUtil.between(t.getCreateTime(), t.getEndTime(), DateUnit.SECOND)); + historicTaskInstanceVO.setHandleTaskTime(spendTime); HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(t.getProcessInstanceId()); historicTaskInstanceVO.setProcessName(historicProcessInstance.getProcessDefinitionName()); historicTaskInstanceVO.setBusinessKey(historicProcessInstance.getBusinessKey()); @@ -783,7 +856,7 @@ public class FlowableServiceImpl implements FlowableService { } } TaskVO.TaskVOBuilder taskVOBuilder = TaskVO.builder().taskName(userTask.getName()). - handleNameList(handleNameList). + handleUserList(handleNameList). taskDefinitionKey(userTask.getId()). startUserId(processInstance.getStartUserId()); @@ -826,7 +899,7 @@ public class FlowableServiceImpl implements FlowableService { } } TaskVO.TaskVOBuilder taskVOBuilder = TaskVO.builder().taskName(userTask.getName()). - handleNameList(handleNameList). + handleUserList(handleNameList). taskDefinitionKey(userTask.getId()). startUserId(processInstance.getStartUserId()); @@ -863,7 +936,7 @@ public class FlowableServiceImpl implements FlowableService { System.out.println(JSON.toJSON(values)); } TaskVO.TaskVOBuilder taskVOBuilder = TaskVO.builder().taskName(userTask.getName()). - handleNameList(handleNameList). + handleUserList(handleNameList). taskDefinitionKey(userTask.getId()). startUserId(processInstance.getStartUserId()); @@ -940,10 +1013,12 @@ public class FlowableServiceImpl implements FlowableService { while ((bytesRead = imageStream.read(buffer, 0, 8192)) != -1) { os.write(buffer, 0, bytesRead); } - os.close(); - imageStream.close(); + log.info("[完成]-获取流程图图像"); + + os.close(); + imageStream.close(); } - log.info("[完成]-获取流程图图像"); + } catch (Exception e) { log.error("【异常】-获取流程图失败!" + e.getMessage()); throw new BusinessException("获取流程图失败!" + e.getMessage()); diff --git a/snow-system/src/main/java/com/snow/system/mapper/SysOaLeaveMapper.java b/snow-system/src/main/java/com/snow/system/mapper/SysOaLeaveMapper.java index 4f7ff13..f562ac1 100644 --- a/snow-system/src/main/java/com/snow/system/mapper/SysOaLeaveMapper.java +++ b/snow-system/src/main/java/com/snow/system/mapper/SysOaLeaveMapper.java @@ -19,6 +19,12 @@ public interface SysOaLeaveMapper */ public SysOaLeave selectSysOaLeaveById(Integer id); + /** + * 查询请求单 + * @param leaveNo + * @return + */ + public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo); /** * 查询请假单列表 * diff --git a/snow-system/src/main/java/com/snow/system/service/ISysOaLeaveService.java b/snow-system/src/main/java/com/snow/system/service/ISysOaLeaveService.java index eb5aca4..1f4e1eb 100644 --- a/snow-system/src/main/java/com/snow/system/service/ISysOaLeaveService.java +++ b/snow-system/src/main/java/com/snow/system/service/ISysOaLeaveService.java @@ -19,6 +19,13 @@ public interface ISysOaLeaveService */ public SysOaLeave selectSysOaLeaveById(Integer id); + /** + * + * @param leaveNo + * @return + */ + public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo); + /** * 查询请假单列表 * diff --git a/snow-system/src/main/java/com/snow/system/service/impl/SysOaLeaveServiceImpl.java b/snow-system/src/main/java/com/snow/system/service/impl/SysOaLeaveServiceImpl.java index 259b1aa..bca1866 100644 --- a/snow-system/src/main/java/com/snow/system/service/impl/SysOaLeaveServiceImpl.java +++ b/snow-system/src/main/java/com/snow/system/service/impl/SysOaLeaveServiceImpl.java @@ -33,6 +33,16 @@ public class SysOaLeaveServiceImpl implements ISysOaLeaveService return sysOaLeaveMapper.selectSysOaLeaveById(id); } + /** + * + * @param leaveNo + * @return + */ + @Override + public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo) { + return sysOaLeaveMapper.selectSysOaLeaveByLeaveNo(leaveNo); + } + /** * 查询请假单列表 * diff --git a/snow-system/src/main/resources/mapper/system/SysOaLeaveMapper.xml b/snow-system/src/main/resources/mapper/system/SysOaLeaveMapper.xml index b799d61..e8f374b 100644 --- a/snow-system/src/main/resources/mapper/system/SysOaLeaveMapper.xml +++ b/snow-system/src/main/resources/mapper/system/SysOaLeaveMapper.xml @@ -47,6 +47,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where id = #{id} + + insert into sys_oa_leave