flowable集成
This commit is contained in:
parent
d7a1af6d84
commit
8ff2486ac1
|
@ -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<ProcessInstanceVO> 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<HistoricTaskInstanceVO> 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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除发布
|
||||
*/
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
/**
|
||||
* 删除请假单
|
||||
*/
|
||||
|
|
76
snow-admin/src/main/resources/static/ruoyi/js/jquery-ajax-blob-arraybuffer.js
vendored
Normal file
76
snow-admin/src/main/resources/static/ruoyi/js/jquery-ajax-blob-arraybuffer.js
vendored
Normal file
|
@ -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);
|
|
@ -41,6 +41,8 @@
|
|||
<script th:inline="javascript">
|
||||
var removeFlag = [[${@permission.hasPermi('system:flow:remove')}]];
|
||||
|
||||
var detailFlag = [[${@permission.hasPermi('system:flow:myStartProcessDetail')}]];
|
||||
|
||||
var processInstanceStatusDatas = [[${@dict.getType('process_instance_status')}]];
|
||||
var prefix = ctx + "modeler";
|
||||
var prefixFlow = ctx + "flow";
|
||||
|
@ -55,7 +57,6 @@
|
|||
showColumns: false, // 是否显示隐藏某列下拉框
|
||||
showToggle: false,
|
||||
showSearch: false, // 是否显示检索信息
|
||||
// rowStyle:rowStyle,//通过自定义函数设置行样式
|
||||
columns: [
|
||||
{
|
||||
title: '序号',
|
||||
|
@ -70,8 +71,11 @@
|
|||
|
||||
{
|
||||
field: 'businessKey',
|
||||
title: '单号'
|
||||
|
||||
title: '单号',
|
||||
formatter: function(value, row, index) {
|
||||
var fromDetailUrl= row.fromDetailUrl;
|
||||
return '<a class="success" href="' + fromDetailUrl+ '" >'+value+'</a> ';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'startUserName',
|
||||
|
@ -102,7 +106,7 @@
|
|||
align: 'center',
|
||||
formatter: function(value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="getProcessDiagram(\'' + row.id + '\')"><i class="fa fa-eye"></i>流程图</a>');
|
||||
actions.push('<a class="btn btn-info btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick="getProcessDiagram(\'' + row.id + '\')"><i class="fa fa-eye"></i>详情</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
|
@ -111,19 +115,10 @@
|
|||
});
|
||||
|
||||
function getProcessDiagram(processInstanceId) {
|
||||
var preViewUrl=prefixFlow+'/myStartProcessDetail?processInstanceId='+processInstanceId;
|
||||
$.modal.openTab("详情", preViewUrl);
|
||||
}
|
||||
|
||||
var preViewUrl=prefix+'/getProcessDiagram?processInstanceId='+processInstanceId;
|
||||
$.modal.openTab("流程图", preViewUrl);
|
||||
}
|
||||
function rowStyle(row, index) {
|
||||
var classes = [ 'success', 'info', 'warning', 'danger'];
|
||||
if (index % 2 === 0 && index / 2 < classes.length) {
|
||||
return {
|
||||
classes: classes[index / 2]
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
|
||||
<head>
|
||||
<th:block th:include="include :: header('我发起的流程详情')" />
|
||||
</head>
|
||||
<body class="white-bg">
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-sequence-edit" >
|
||||
<input name="processInstanceId" id="processInstanceId" th:value="${processInstanceId}" type="hidden" >
|
||||
|
||||
<input name="busVarUrl" id="busVarUrl" th:value="${busVarUrl}" type="hidden" >
|
||||
<div class="ibox float-e-margins">
|
||||
<h4 class="form-header h4">流程图</h4>
|
||||
<div class="vertical-timeline-block" >
|
||||
<img class="imgcode" width="85%"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ibox float-e-margins form-horizontal">
|
||||
<h4 class="form-header h4">审批节点</h4>
|
||||
<div id="ibox-content">
|
||||
<div id="vertical-timeline" class="vertical-container light-timeline light-dark">
|
||||
<div class="vertical-timeline-block" th:each="task,iterStat : ${historicTaskInstanceList}">
|
||||
<div class="vertical-timeline-icon navy-bg">
|
||||
<i class="fa fa-tasks"></i>
|
||||
</div>
|
||||
<div class="vertical-timeline-content ">
|
||||
<h2 th:text="${task.taskName }"></h2>
|
||||
<br class="form-group">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<label >审批结果:</label>
|
||||
<label th:switch="${task.isPass}">
|
||||
<span class="btn-outline btn-danger" th:case="'false'">驳回</span>
|
||||
<span class="btn-outline btn-success" th:case="'true'">通过</span>
|
||||
<span class="btn-outline btn-info" th:case=" ''">待审核</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-md-4" th:if="${task.assigneeName} != null">
|
||||
<label >审批人:</label>
|
||||
<span th:text="${task.assigneeName}"></span>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4" th:if="${task.handleTaskTime} != null">
|
||||
<label>任务历时:</label>
|
||||
<label>
|
||||
<span th:text="${task.handleTaskTime}"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</br>
|
||||
<div class="row" >
|
||||
<div class="col-md-12">
|
||||
<label>可审批人:</label>
|
||||
<span th:each="userName:${task.handleUserList}">
|
||||
<label th:if="${userName} ne ''">  
|
||||
<span th:text="${userName}"></span>
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</br>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<span class="vertical-date">
|
||||
<label>任务时间:</label> <small th:text="${#dates.format(task.startTime, 'yyyy-MM-dd HH:mm:ss')}"></small>
|
||||
<label>~</label> <small th:text="${#dates.format(task.completeTime, 'yyyy-MM-dd HH:mm:ss')}"></small>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</br>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div th:each="comment:${task.commentList}">
|
||||
<label>审批意见:</label>
|
||||
<label th:if="${comment.fullMessage} ne ''">
|
||||
<span th:text="${comment.fullMessage}"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox float-e-margins">
|
||||
<h4 class="form-header h4">业务数据</h4>
|
||||
<p>
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-1 col-sm-10">
|
||||
<a class="btn btn-info btn-large" href="javascript:void(0)" onclick="getProcessDiagram()"><i class="fa fa-eye"></i>获取业务单</a>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
|
||||
$(function () {
|
||||
var processInstanceId= $("#processInstanceId").val();
|
||||
var url ="/modeler/getProcessDiagram?processInstanceId="+processInstanceId;
|
||||
$(".imgcode").attr("src", url);
|
||||
});
|
||||
|
||||
function getProcessDiagram() {
|
||||
var processInstanceId= $("#processInstanceId").val();
|
||||
var busVarUrl= $("#busVarUrl").val();
|
||||
$.modal.open('业务单', busVarUrl+"?processInstanceId="+processInstanceId);
|
||||
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -41,6 +41,10 @@
|
|||
<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
|
||||
</div>
|
||||
|
||||
<!--图片显示JS-->
|
||||
<div th:fragment="jquery-ajax-blob-arraybuffer">
|
||||
<script th:href="@{/ruoyi/js/jquery-ajax-blob-arraybuffer.js}" ></script>
|
||||
</div>
|
||||
<!-- ztree树插件 -->
|
||||
<div th:fragment="ztree-css">
|
||||
<link th:href="@{/ajax/libs/jquery-ztree/3.5/css/metro/zTreeStyle.css}" rel="stylesheet"/>
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
|
||||
<div class="vertical-timeline-content">
|
||||
|
||||
<h2 th:text="${task.name }"></h2>
|
||||
<h2 th:text="${task.taskName }"></h2>
|
||||
<p th:if="${task.isPass} ne ''">
|
||||
<label >审批结果:</label>
|
||||
<span style="color: red" th:if="${#strings.trim(task.isPass)} eq 'false'">驳回</span>
|
||||
|
@ -74,15 +74,15 @@
|
|||
</p>
|
||||
|
||||
<p><label>操作人:</label> <span th:text="${task.assigneeName}"></span></p>
|
||||
<p><label>任务历时:</label> <span th:text="${task.spendTime}"></span></p>
|
||||
<p><label>任务历时:</label> <span th:text="${task.handleTaskTime}"></span></p>
|
||||
<div th:each="comment:${task.commentList}">
|
||||
<p th:if="${comment.fullMessage} ne ''">
|
||||
<label>审批意见:</label> <span th:text="${comment.fullMessage}"></span>
|
||||
</p>
|
||||
</div>
|
||||
<span class="vertical-date">
|
||||
<label>时间:</label> <small th:text="${#dates.format(task.createTime, 'yyyy-MM-dd HH:mm:ss')}"></small>
|
||||
<label>~</label> <small th:text="${#dates.format(task.endTime, 'yyyy-MM-dd HH:mm:ss')}"></small>
|
||||
<label>时间:</label> <small th:text="${#dates.format(task.startTime, 'yyyy-MM-dd HH:mm:ss')}"></small>
|
||||
<label>~</label> <small th:text="${#dates.format(task.completeTime, 'yyyy-MM-dd HH:mm:ss')}"></small>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<!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-t" id="signupForm">
|
||||
<input class="form-control" type="hidden" name="businessKey" th:value="${sysOaLeave.leaveNo}"/>
|
||||
<h4 class="form-header h4">请假信息</h4>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">单号:</label>
|
||||
<div class="form-control-static" th:text="${sysOaLeave.leaveNo}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">标题:</label>
|
||||
<div class="form-control-static" th:text="${sysOaLeave.name}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">请假理由:</label>
|
||||
<div class="form-control-static"><pre id="reason"></pre></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">开始时间:</label>
|
||||
<div class="form-control-static" th:text="${#dates.format(sysOaLeave.startTime, 'yyyy-MM-dd hh:mm:ss')}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">结束时间:</label>
|
||||
<div class="form-control-static" th:text="${#dates.format(sysOaLeave.endTime, 'yyyy-MM-dd HH:mm:ss')}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">申请人:</label>
|
||||
<div class="form-control-static" th:text="${sysOaLeave.applyPerson}">
|
||||
</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">
|
||||
$(function() {
|
||||
var reason = [[${sysOaLeave.reason}]];
|
||||
console.log(reason);
|
||||
if ($.common.isNotEmpty(reason) && reason.length < 2000) {
|
||||
$("#reason").text(reason);
|
||||
} else {
|
||||
$("#reason").text(reason);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$(".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');
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -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<TaskVO> dynamicFlowNodeInfo = flowableService.getDynamicFlowNodeInfo("38505061-2d6b-11eb-b0ec-040e3c9c6b2f");
|
||||
log.info(JSON.toJSONString(dynamicFlowNodeInfo));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTaskList(){
|
||||
TaskQuery taskQuery = taskService.createTaskQuery().processInstanceId("1337010679969882112");
|
||||
List<Task> list = taskQuery.list();
|
||||
list.forEach(task -> {
|
||||
List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
|
||||
flowableService.getIdentityLinksForTask(task.getId(),"");
|
||||
log.info(JSON.toJSONString(identityLinksForTask));
|
||||
});
|
||||
|
||||
|
||||
log.info(JSON.toJSONString(list));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
/**
|
||||
* 当前类的包名
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 流程申请单需实现此方法,返回申请单对应的流程定义.
|
||||
|
|
|
@ -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<Attachment> attachmentList;
|
||||
|
||||
/**
|
||||
* 任务变量
|
||||
* 任务节点变量
|
||||
*/
|
||||
private Map<String, Object> taskLocalVariables;
|
||||
|
||||
|
||||
private String formKey;
|
||||
|
||||
/**
|
||||
* 流程变量
|
||||
|
@ -115,30 +85,23 @@ public class HistoricTaskInstanceVO implements Serializable {
|
|||
private Map<String, Object> 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());
|
||||
|
|
|
@ -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<String, Object> processVariables;
|
||||
/**
|
||||
* 业务流程参数
|
||||
*/
|
||||
@JsonIgnoreProperties
|
||||
private AppForm appForm;
|
||||
|
||||
public String processDefinitionCategory;
|
||||
private Map<String, Object> processVariables;
|
||||
|
||||
private String processDefinitionCategory;
|
||||
|
||||
public static List<ProcessInstanceVO> warpList(List<HistoricProcessInstance> historicProcessInstanceList){
|
||||
return historicProcessInstanceList.stream().map(t->{
|
||||
|
|
|
@ -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<String> handleNameList;
|
||||
private List<String> handleUserList;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,6 @@ public abstract class AbstractExecutionListener<T extends AppForm> implements Ex
|
|||
private ThreadLocal<T> appFormLocal = new ThreadLocal<>();
|
||||
|
||||
private ThreadLocal<DelegateExecution> delegateExecutionLocal=new ThreadLocal();
|
||||
@Autowired
|
||||
private FlowableService flowableService;
|
||||
|
||||
@Autowired
|
||||
private SysUserServiceImpl sysUserService;
|
||||
|
@ -129,11 +127,9 @@ public abstract class AbstractExecutionListener<T extends AppForm> 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;
|
||||
|
|
|
@ -11,4 +11,14 @@ import com.snow.flowable.domain.AppForm;
|
|||
public interface AppFormService {
|
||||
<A extends AppForm> A getAppFrom(String classInfoJson,String className);
|
||||
<A extends AppForm> A getAppFrom(String classInfoJson,Class<A> className);
|
||||
|
||||
/**
|
||||
* 从流程中获取表单数据
|
||||
* @param processInstanceId
|
||||
* @param <A>
|
||||
* @return
|
||||
*/
|
||||
<A extends AppForm> A getAppFromBySerializable(String processInstanceId);
|
||||
|
||||
<A extends AppForm> A getAppFrom(String processInstanceId);
|
||||
}
|
||||
|
|
|
@ -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<TaskVO> findTasksByUserId(String userId,TaskBaseDTO taskBaseDTO);
|
||||
|
||||
/**
|
||||
* 根据任务ID获取关联待办人活着待办组的人
|
||||
* @param taskId
|
||||
* @return
|
||||
*/
|
||||
Set<SysUser> getIdentityLinksForTask(String taskId,String type);
|
||||
|
||||
/**
|
||||
* 获取历史的
|
||||
* @param taskId
|
||||
* @return
|
||||
*/
|
||||
Set<SysUser> getHistoricIdentityLinksForTask(String taskId);
|
||||
|
||||
/**
|
||||
* 完成任务
|
||||
* @param completeTaskDTO
|
||||
|
@ -108,6 +124,7 @@ public interface FlowableService {
|
|||
* @param httpServletResponse
|
||||
* @param processId
|
||||
*/
|
||||
@Deprecated
|
||||
void getProcessDiagram(HttpServletResponse httpServletResponse, String processId);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 extends AppForm> 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 extends AppForm> A getAppFromBySerializable(String processInstanceId) {
|
||||
HistoricProcessInstance historicProcessInstance=flowableService.getHistoricProcessInstanceById(processInstanceId);
|
||||
return getVariable(historicProcessInstance, FlowConstants.APP_FORM);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public <A extends AppForm> 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 <V>
|
||||
* @return
|
||||
*/
|
||||
protected <V> V getVariable(HistoricProcessInstance historicProcessInstance,String key){
|
||||
return (V)historicProcessInstance.getProcessVariables().get(key);
|
||||
}
|
||||
|
||||
private <A> Class<A> getFormClass(String className) {
|
||||
try {
|
||||
return (Class<A>) 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<SysOaLeave> sysOaLeaveClass = SysOaLeave.class;
|
||||
Class<?> sysOaLeaveForm = Class.forName("com.snow.flowable.domain.leave.SysOaLeaveForm");
|
||||
System.out.println(sysOaLeaveForm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String, Object> 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<SysUser> getIdentityLinksForTask(String taskId,String type){
|
||||
Set<SysUser> userList=new HashSet<>();
|
||||
List<IdentityLink> 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<SysUser> 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<SysUser> getHistoricIdentityLinksForTask(String taskId){
|
||||
Set<SysUser> userList=new HashSet<>();
|
||||
List<HistoricIdentityLink> 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<SysUser> 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<HistoricTaskInstance> list = historicTaskInstanceQuery.orderByTaskCreateTime().asc().list();
|
||||
List<HistoricTaskInstanceVO> historicTaskInstanceVOS = HistoricTaskInstanceVO.warpList(list);
|
||||
setHistoricTaskInstanceVos(historicTaskInstanceVOS);
|
||||
|
@ -547,28 +611,33 @@ public class FlowableServiceImpl implements FlowableService {
|
|||
private void setHistoricTaskInstanceVos(List<HistoricTaskInstanceVO> list){
|
||||
|
||||
list.parallelStream().forEach(t -> {
|
||||
//保存待办人
|
||||
Set<SysUser> identityLinksForTask = getHistoricIdentityLinksForTask(t.getTaskId());
|
||||
Optional.ofNullable(identityLinksForTask).ifPresent(m->{
|
||||
List<String> 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> comment = taskService.getTaskComments(t.getId(), FlowConstants.OPINION);
|
||||
List<Comment> comment = taskService.getTaskComments(t.getTaskId(), FlowConstants.OPINION);
|
||||
|
||||
List<Attachment> taskAttachments = taskService.getTaskAttachments(t.getId());
|
||||
List<Attachment> 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<TaskVO> futureTask = getFutureTask(processInstance);
|
||||
for(int i=0;i<hisTaskVOList.size();i++){
|
||||
for(int j=0;j<futureTask.size();j++){
|
||||
if(hisTaskVOList.get(i).getTaskName().equals(futureTask.get(j).getTaskName())&&CollectionUtils.isEmpty(futureTask.get(j).getHandleNameList())){
|
||||
if(hisTaskVOList.get(i).getTaskName().equals(futureTask.get(j).getTaskName())&&CollectionUtils.isEmpty(futureTask.get(j).getHandleUserList())){
|
||||
futureTask.remove(j);
|
||||
}
|
||||
}
|
||||
|
@ -677,8 +746,12 @@ public class FlowableServiceImpl implements FlowableService {
|
|||
processInstanceVOS.parallelStream().forEach(t->{
|
||||
|
||||
Map<String, Object> 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());
|
||||
|
|
|
@ -19,6 +19,12 @@ public interface SysOaLeaveMapper
|
|||
*/
|
||||
public SysOaLeave selectSysOaLeaveById(Integer id);
|
||||
|
||||
/**
|
||||
* 查询请求单
|
||||
* @param leaveNo
|
||||
* @return
|
||||
*/
|
||||
public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo);
|
||||
/**
|
||||
* 查询请假单列表
|
||||
*
|
||||
|
|
|
@ -19,6 +19,13 @@ public interface ISysOaLeaveService
|
|||
*/
|
||||
public SysOaLeave selectSysOaLeaveById(Integer id);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param leaveNo
|
||||
* @return
|
||||
*/
|
||||
public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo);
|
||||
|
||||
/**
|
||||
* 查询请假单列表
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询请假单列表
|
||||
*
|
||||
|
|
|
@ -47,6 +47,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<include refid="selectSysOaLeaveVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectSysOaLeaveByLeaveNo" parameterType="String" resultMap="SysOaLeaveResult">
|
||||
<include refid="selectSysOaLeaveVo"/>
|
||||
where leave_no = #{leaveNo}
|
||||
</select>
|
||||
|
||||
<insert id="insertSysOaLeave" parameterType="SysOaLeave" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into sys_oa_leave
|
||||
|
|
Loading…
Reference in New Issue