flowable集成

This commit is contained in:
459816669@qq.com 2020-12-06 21:05:15 +08:00
parent 5cdbbf4550
commit 2ad99b7e2a
37 changed files with 886 additions and 319 deletions

View File

@ -1,18 +1,22 @@
package com.snow.web.controller.system;
import java.util.Date;
import java.util.List;
import java.util.Map;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ClassUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.snow.common.constant.SequenceContants;
import com.snow.common.enums.ProcessStatus;
import com.snow.common.json.JSON;
import com.snow.common.utils.StringUtils;
import com.snow.flowable.common.FlowConstants;
import com.snow.flowable.domain.CompleteTaskDTO;
import com.snow.flowable.domain.FileEntry;
import com.snow.flowable.domain.FinishTaskDTO;
import com.snow.flowable.domain.StartProcessDTO;
import com.snow.flowable.domain.*;
import com.snow.flowable.service.impl.FlowableServiceImpl;
import com.snow.framework.util.ShiroUtils;
import com.snow.system.domain.SysUser;
@ -21,6 +25,7 @@ import com.snow.system.service.impl.SysOaLeaveServiceImpl;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -107,7 +112,7 @@ public class SysOaLeaveController extends BaseController
}
/**
* 新增保存请假单
* 1.填写请假单 可修改
*/
@RequiresPermissions("system:leave:add")
@Log(title = "请假单", businessType = BusinessType.INSERT)
@ -117,7 +122,15 @@ public class SysOaLeaveController extends BaseController
public AjaxResult addSave(SysOaLeave sysOaLeave)
{
SysUser sysUser = ShiroUtils.getSysUser();
Date endTime = sysOaLeave.getEndTime();
Date startTime = sysOaLeave.getStartTime();
int compare = DateUtil.compare(startTime, endTime);
if(compare==1||compare==0){
return AjaxResult.error("请假结束时间必须大于开始时间");
}
//生成请假单
String leaveNo = sequenceService.getNewSequenceNo(SequenceContants.OA_LEAVE_SEQUENCE);
sysOaLeave.setCreateBy(sysUser.getUserName());
sysOaLeave.setLeaveNo(leaveNo);
@ -134,6 +147,8 @@ public class SysOaLeaveController extends BaseController
public String edit(@PathVariable("id") Integer id, ModelMap mmap)
{
SysOaLeave sysOaLeave = sysOaLeaveService.selectSysOaLeaveById(id);
String spendTime = DateUtil.formatBetween(sysOaLeave.getStartTime(), sysOaLeave.getEndTime(), BetweenFormater.Level.SECOND);
sysOaLeave.setLeaveTime(spendTime);
mmap.put("sysOaLeave", sysOaLeave);
return prefix + "/edit";
}
@ -154,13 +169,14 @@ public class SysOaLeaveController extends BaseController
startProcessDTO.setBusinessKey(oldSysOaLeave.getLeaveNo());
startProcessDTO.setProcessDefinitionKey(FlowConstants.SNOW_OA_LEAVE);
startProcessDTO.setStartUserId(String.valueOf(sysUser.getUserId()));
Map<String, Object> map = BeanUtil.beanToMap(sysOaLeave);
startProcessDTO.setVariables(map);
ProcessInstance processInstance = flowableService.startProcessInstanceByKey(startProcessDTO);
CompleteTaskDTO completeTaskDTO=new CompleteTaskDTO();
completeTaskDTO.setUserId(String.valueOf(sysUser.getUserId()));
Task task= flowableService.getTaskProcessInstanceById(processInstance.getProcessInstanceId());
completeTaskDTO.setTaskId(task.getId());
flowableService.completeTask(completeTaskDTO);
sysOaLeave.setProcessStatus(ProcessStatus.CHECKING.ordinal());
sysOaLeave.setCreateBy(sysUser.getUserName());
sysOaLeave.setApplyPerson(sysUser.getUserName());
BeanUtils.copyProperties(sysOaLeave,oldSysOaLeave);
@ -168,6 +184,26 @@ public class SysOaLeaveController extends BaseController
return toAjax(sysOaLeaveService.updateSysOaLeave(sysOaLeave));
}
/**
* 请假单详情
*/
@RequiresPermissions("system:leave:detail")
@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") Integer id, ModelMap mmap)
{
SysOaLeave sysOaLeave = sysOaLeaveService.selectSysOaLeaveById(id);
HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO();
historicTaskInstanceDTO.setBusinessKey(sysOaLeave.getLeaveNo());
historicTaskInstanceDTO.setProcessInstanceId(sysOaLeave.getProcessInstanceId());
historicTaskInstanceDTO.setProcessStatus(1);
List<HistoricTaskInstanceVO> historicTaskInstanceList= flowableService.getHistoricTaskInstanceNoPage(historicTaskInstanceDTO);
String spendTime = DateUtil.formatBetween(sysOaLeave.getStartTime(), sysOaLeave.getEndTime(), BetweenFormater.Level.SECOND);
sysOaLeave.setLeaveTime(spendTime);
mmap.put("sysOaLeave", sysOaLeave);
mmap.put("historicTaskInstanceList", historicTaskInstanceList);
return prefix + "/detail";
}
/**
* 删除请假单
*/

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,14 +399,14 @@
var result = [];
var key;
for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
// Don't enum bug & hidden keys
// Don't enums bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~indexOf(result, key) || result.push(key);
}
return result;
};
// IE8- don't enum bug keys
// IE8- don't enums bug keys
var enumBugKeys = [
'constructor',
'hasOwnProperty',

View File

@ -399,12 +399,12 @@ function getUniqueId(wizard)
}
/**
* Gets a valid enum value by checking a specific enum key or value.
* Gets a valid enums value by checking a specific enums key or value.
*
* @static
* @private
* @method getValidEnumValue
* @param enumType {Object} Type of enum
* @param enumType {Object} Type of enums
* @param keyOrValue {Object} Key as `String` or value as `Integer` to check for
*/
function getValidEnumValue(enumType, keyOrValue)
@ -418,7 +418,7 @@ function getValidEnumValue(enumType, keyOrValue)
var value = enumType[keyOrValue];
if (value === undefined)
{
throwError("The enum key '{0}' does not exist.", keyOrValue);
throwError("The enums key '{0}' does not exist.", keyOrValue);
}
return value;
@ -434,7 +434,7 @@ function getValidEnumValue(enumType, keyOrValue)
}
}
throwError("Invalid enum value '{0}'.", keyOrValue);
throwError("Invalid enums value '{0}'.", keyOrValue);
}
// Type is not supported
else
@ -1475,7 +1475,7 @@ $.fn.steps.skip = function (count)
};
/**
* An enum represents the different content types of a step and their loading mechanisms.
* An enums represents the different content types of a step and their loading mechanisms.
*
* @class contentMode
* @for steps
@ -1513,7 +1513,7 @@ var contentMode = $.fn.steps.contentMode = {
};
/**
* An enum represents the orientation of the steps navigation.
* An enums represents the orientation of the steps navigation.
*
* @class stepsOrientation
* @for steps
@ -1541,7 +1541,7 @@ var stepsOrientation = $.fn.steps.stepsOrientation = {
};
/**
* An enum that represents the various transition animations.
* An enums that represents the various transition animations.
*
* @class transitionEffect
* @for steps

File diff suppressed because one or more lines are too long

View File

@ -3523,8 +3523,8 @@
/**
* @class Create a virtual table to create what actions to do in change.
* @param {object} startPoint Cell selected to apply change.
* @param {enum} where Where change will be applied Row or Col. Use enum: TableResultAction.where
* @param {enum} action Action to be applied. Use enum: TableResultAction.requestAction
* @param {enums} where Where change will be applied Row or Col. Use enums: TableResultAction.where
* @param {enums} action Action to be applied. Use enums: TableResultAction.requestAction
* @param {object} domTable Dom element of table to make changes.
*/
var TableResultAction = function (startPoint, where, action, domTable) {
@ -3760,17 +3760,17 @@
};
/**
*
* Where action occours enum.
* Where action occours enums.
*/
TableResultAction.where = { 'Row': 0, 'Column': 1 };
/**
*
* Requested action to apply enum.
* Requested action to apply enums.
*/
TableResultAction.requestAction = { 'Add': 0, 'Delete': 1 };
/**
*
* Result action to be executed enum.
* Result action to be executed enums.
*/
TableResultAction.resultAction = { 'Ignore': 0, 'SubtractSpanCount': 1, 'RemoveCell': 2, 'AddCell': 3, 'SumSpanCount': 4 };
/**

View File

@ -368,22 +368,22 @@ angular.module('flowableModeler').controller('FlowableAssignmentPopupCtrl',
$scope.popup.assignmentObject.idm.assignee = undefined;
};
// Click handler for + button after enum value
// Click handler for + button after enums value
$scope.addCandidateUserValue = function(index) {
$scope.popup.assignmentObject.static.candidateUsers.splice(index + 1, 0, {value: ''});
};
// Click handler for - button after enum value
// Click handler for - button after enums value
$scope.removeCandidateUserValue = function(index) {
$scope.popup.assignmentObject.static.candidateUsers.splice(index, 1);
};
// Click handler for + button after enum value
// Click handler for + button after enums value
$scope.addCandidateGroupValue = function(index) {
$scope.popup.assignmentObject.static.candidateGroups.splice(index + 1, 0, {value: ''});
};
// Click handler for - button after enum value
// Click handler for - button after enums value
$scope.removeCandidateGroupValue = function(index) {
$scope.popup.assignmentObject.static.candidateGroups.splice(index, 1);
};

View File

@ -139,8 +139,8 @@ angular.module('flowableModeler').controller('FlowableDataPropertiesPopupCtrl',
delete $scope.selectedProperty.datePattern;
}
// Check enum. If enum, show list of options
if ($scope.selectedProperty.type === 'enum') {
// Check enums. If enums, show list of options
if ($scope.selectedProperty.type === 'enums') {
$scope.selectedProperty.enumValues = [ {id: 'value1', name: 'Value 1'}, {id: 'value2', name: 'Value 2'}];
$scope.enumValues.length = 0;
for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {

View File

@ -110,12 +110,12 @@ angular.module('flowableModeler').controller('FlowableEventListenersPopupCtrl',
});
// Click handler for + button after enum value
// Click handler for + button after enums value
$scope.addEventValue = function (index) {
$scope.selectedListener.events.splice(index + 1, 0, {event: ''});
};
// Click handler for - button after enum value
// Click handler for - button after enums value
$scope.removeEventValue = function (index) {
$scope.selectedListener.events.splice(index, 1);
$scope.listenerDetailsChanged();

View File

@ -136,8 +136,8 @@ angular.module('flowableModeler').controller('FlowableFormPropertiesPopupCtrl',
delete $scope.selectedProperty.datePattern;
}
// Check enum. If enum, show list of options
if ($scope.selectedProperty.type === 'enum') {
// Check enums. If enums, show list of options
if ($scope.selectedProperty.type === 'enums') {
$scope.selectedProperty.enumValues = [ {id: 'value1', name: 'Value 1'}, {id: 'value2', name: 'Value 2'}];
$scope.enumValues.length = 0;
for (var i = 0; i < $scope.selectedProperty.enumValues.length; i++) {

View File

@ -74,12 +74,8 @@
},
{
field: 'startUserId',
title: '流程发起人',
formatter: function(value, row, index) {
var data= $.common.getDataById('/system/user/getUserInfoById',value);
return data.userName;
}
field: 'startUserName',
title: '流程发起人'
},
{
field: 'isFinished',
@ -88,7 +84,10 @@
return $.table.selectDictLabel(processInstanceStatusDatas, value);
}
},
{
field: 'processSpendTime',
title: '流程用时'
},
{
field: 'startTime',
title: '流程创建时间'

View File

@ -11,7 +11,7 @@
<div class="form-group">
<label class="col-sm-3 control-label">请假名称:</label>
<div class="col-sm-8">
<input name="name" class="form-control" type="text">
<input name="name" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
@ -24,7 +24,7 @@
<label class="col-sm-3 control-label">开始时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="startTime" class="form-control" placeholder="yyyy-MM-dd" type="text">
<input name="startTime" class="form-control" placeholder="yyyy-MM-dd" type="text" required>
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
@ -33,17 +33,11 @@
<label class="col-sm-3 control-label">结束时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="endTime" class="form-control" placeholder="yyyy-MM-dd" type="text">
<input name="endTime" class="form-control" placeholder="yyyy-MM-dd" type="text" required>
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<!-- <div class="form-group">
<label class="col-sm-3 control-label">申请人:</label>
<div class="col-sm-8">
<input name="applyPerson" class="form-control" type="text">
</div>
</div>-->
<div class="form-group">
<label class="col-sm-3 control-label">附件:</label>
<div class="col-sm-8">

View File

@ -0,0 +1,136 @@
<!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">
<!--<div class="row">
<div class="col-sm-offset-0 col-sm-10">
<button type="button" class="btn btn-sm btn-primary" onclick="submitCheckHandler()"><i class="fa fa-check"></i>通 过</button>&nbsp;
<button type="button" class="btn btn-sm btn-danger" onclick="submitHandler()"><i class="fa fa-remove"></i>驳 回</button>&nbsp;
</div>
</div>
<br/>-->
<input class="form-control" type="hidden" name="taskId" th:value="*{taskId}"/>
<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.leaveTime}">
</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>
<div class="ibox float-e-margins">
<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.name }"></h2>
<p th:if="${task.isPass} ne ''">
<label >审批结果:</label>
<span style="color: red" th:if="${#strings.trim(task.isPass)} eq 'false'">驳回</span>
<span style="color: blue" th:if="${#strings.trim(task.isPass)} eq 'true'">通过</span>
</p>
<p><label>操作人:</label> <span th:text="${task.assigneeName}"></span></p>
<p><label>任务历时:</label> <span th:text="${task.spendTime}"></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>
</span>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: jsonview-js" />
<th:block th:include="include :: bootstrap-fileinput-js"/>
<script th:inline="javascript">
$(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');
});
function submitCheckHandler() {
if ($.validate.form()) {
var data = $("#signupForm").serializeArray();
data.push({"name": "checkStatus", "value": 0});
$.operate.saveTab("/system/leave/hrFinishTask", data);
}
}
</script>
</body>
</html>

View File

@ -9,12 +9,19 @@
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-leave-edit" th:object="${sysOaLeave}">
<input name="id" th:field="*{id}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">请假单号:</label>
<div class="col-sm-8">
<input name="name" th:field="*{leaveNo}" class="form-control" type="text" readonly>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">请假名称:</label>
<div class="col-sm-8">
<input name="name" th:field="*{name}" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">请假理由:</label>
<div class="col-sm-8">
@ -25,7 +32,7 @@
<label class="col-sm-3 control-label">开始时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="startTime" th:value="${#dates.format(sysOaLeave.startTime, 'yyyy-MM-dd HH:mm:ss')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<input name="startTime" id="startTime" th:value="${#dates.format(sysOaLeave.startTime, 'yyyy-MM-dd HH:mm:ss')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
@ -34,11 +41,19 @@
<label class="col-sm-3 control-label">结束时间:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="endTime" th:value="${#dates.format(sysOaLeave.endTime, 'yyyy-MM-dd HH:mm:ss')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<input name="endTime" id="endTime" th:value="${#dates.format(sysOaLeave.endTime, 'yyyy-MM-dd HH:mm:ss')}" class="form-control" placeholder="yyyy-MM-dd" type="text">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">请假时长:</label>
<div class="col-sm-8">
<div class="input-group date">
<input name="leaveTime" id="leaveTime" class="form-control" th:field="*{leaveTime}" type="text" readonly>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">附件:</label>
<div class="col-sm-8">
@ -92,6 +107,39 @@
})
$(this).fileinput('_initFileActions');
});
function formatBetweenTime(date1,date2) {
var date3 = date2.getTime() - date1.getTime() //时间差的毫秒数
console.log(date3)
var days=Math.floor(date3 / (24*3600*1000)) // 计算出相差天数
//计算出小时数
var leave1 = date3 % (24*3600*1000) //计算天数后剩余的毫秒数
var hours = Math.floor(leave1 / (3600*1000))
//计算出相差分钟数
var leave2 = leave1 % (3600*1000) //计算小时数后剩余的毫秒数
var minutes = Math.floor(leave2 / (60*1000))
console.log(minutes)
//计算出相差秒数
var leave3 = leave2 % (60*1000) //计算分钟数后剩余的毫秒数
var seconds = Math.round(leave3 / 1000)
return days+"天"+hours+"小时"+minutes+"分钟"+seconds+"秒";
}
</script>
<script th:inline="javascript">
$('#endTime').blur(function () {
var startTime =$("#startTime").val();
console.log(startTime)
var endTime = $("#endTime").val();
console.log(endTime)
var formatBetweenTime1 = formatBetweenTime(new Date(startTime),new Date(endTime));
$("#leaveTime").val(formatBetweenTime1);
});
</script>
</body>
</html>

View File

@ -33,14 +33,6 @@
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<!-- <li>
<label>流程实例ID</label>
<input type="text" name="processInstanceId"/>
</li>-->
<li>
<label>申请人:</label>
<input type="text" name="applyPerson"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
@ -52,14 +44,11 @@
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:leave:add">
<i class="fa fa-plus"></i> 添加
<i class="fa fa-plus"></i> 添加申请单
</a>
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:leave:edit">
<!-- <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:leave:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:leave:remove">
<i class="fa fa-remove"></i> 删除
</a>
</a>-->
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:leave:export">
<i class="fa fa-download"></i> 导出
</a>
@ -83,6 +72,7 @@
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
detailUrl:prefix + "/detail/{id}",
modalName: "请假单",
columns: [{
checkbox: true
@ -129,8 +119,14 @@
if(row.processStatus==0) {
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>发起申请</a> ');
}
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
if(row.processStatus!=0) {
actions.push('<a class="btn btn-info btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.detail(\'' + row.id + '\')"><i class="fa fa-search-plus"></i>详情</a> ');
}
if(row.processStatus==0) {
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a>');
}
return actions.join('');
}
}]
};

View File

@ -51,7 +51,7 @@
<div class="form-group">
<label class="col-sm-3 control-label">主管审批意见:</label>
<div class="col-sm-8">
<textarea name="suggestion" class="form-control"></textarea>
<textarea name="suggestion" class="form-control" required></textarea>
</div>
</div>
<div class="form-group">
@ -105,6 +105,14 @@
$.operate.saveTab("/system/leave/managerFinishTask", data);
}
}
function submitHandler() {
if ($.validate.form()) {
var data = $("#signupForm").serializeArray();
data.push({"name": "checkStatus", "value": 1});
$.operate.saveTab("/system/leave/managerFinishTask", data);
}
}
</script>
</body>
</html>

View File

@ -1,7 +1,7 @@
package com.snow.common.enums;
/**
* 操作状态
* 业务流程状态
*
* @author snow
*/

View File

@ -17,4 +17,15 @@ public class FlowConstants {
/**************************************************************************************/
/**
*流程通过变量名称
*/
public static final String IS_PASS="isPass";
/**
*comment类型---意见
*/
public static final String OPINION="OPINION";
}

View File

@ -0,0 +1,31 @@
package com.snow.flowable.domain;
import lombok.Data;
import java.io.Serializable;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-12-05 17:05
**/
@Data
public class AppForm implements Serializable {
/**
* 流程ID
*/
private String processInstanceId;
/**
* 业务参数
*/
private String businessKey;
/**
* 流程发起人
*/
private String startUserId;
}

View File

@ -0,0 +1,10 @@
package com.snow.flowable.domain;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-12-04 23:14
**/
public class HistoricTaskDTO {
}

View File

@ -1,10 +1,10 @@
package com.snow.flowable.domain;
import com.snow.flowable.enums.FlowFinishedStatusEnum;
import lombok.Data;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
/**
@ -19,83 +19,92 @@ public class HistoricTaskInstanceDTO extends FlowBaseDTO implements Serializabl
/**
* 用户ID
*/
public String userId;
public String taskDefinitionId;
public String processDefinitionId;
public String processDefinitionKey;
public String processDefinitionKeyLike;
public String processDefinitionName;
public String processDefinitionNameLike;
private String userId;
private String taskDefinitionId;
private String processDefinitionId;
private String processDefinitionKey;
private String processDefinitionKeyLike;
private String processDefinitionName;
private String processDefinitionNameLike;
public String deploymentId;
public Collection<String> deploymentIds;
public String cmmnDeploymentId;
private String deploymentId;
public String processInstanceId;
private String processInstanceId;
public String BusinessKey;
public String BusinessKeyLike;
private String BusinessKey;
private String BusinessKeyLike;
public String executionId;
public String scopeId;
public String subScopeId;
public String scopeType;
public String scopeDefinitionId;
public String propagatedStageInstanceId;
public String processInstanceIdWithChildren;
public String caseInstanceIdWithChildren;
public String caseDefinitionKey;
public String caseDefinitionKeyLike;
public String caseDefinitionKeyLikeIgnoreCase;
public String taskId;
public String taskName;
public String taskNameLike;
public String taskNameLikeIgnoreCase;
public String taskParentTaskId;
public String taskDescription;
public String taskDescriptionLike;
public String taskDescriptionLikeIgnoreCase;
public String taskDeleteReason;
public String taskDeleteReasonLike;
public String taskOwner;
public String taskOwnerLike;
public String taskOwnerLikeIgnoreCase;
public String taskAssignee;
public String taskAssigneeLike;
public String taskAssigneeLikeIgnoreCase;
public String taskDefinitionKey;
public String taskDefinitionKeyLike;
private String executionId;
private String taskId;
private String taskName;
private String taskNameLike;
private String taskNameLikeIgnoreCase;
private String taskParentTaskId;
private String taskDescription;
private String taskDescriptionLike;
private String taskDescriptionLikeIgnoreCase;
public String candidateUser;
public String candidateGroup;
private String taskOwner;
private String taskOwnerLike;
private String taskOwnerLikeIgnoreCase;
private String taskAssignee;
private String taskAssigneeLike;
private String taskAssigneeLikeIgnoreCase;
private String taskDefinitionKey;
private String taskDefinitionKeyLike;
private String candidateUser;
private String candidateGroup;
private String involvedUser;
public String involvedUser;
public boolean ignoreAssigneeValue;
public Integer taskPriority;
public Integer taskMinPriority;
public Integer taskMaxPriority;
public boolean finished;
public boolean unfinished;
/**
* 流程状态0--进行中1-结束
*/
public Integer processStatus;
private Integer processStatus;
public Date dueDate;
public Date dueAfter;
public Date dueBefore;
public boolean withoutDueDate;
public Date creationDate;
public Date creationAfterDate;
public Date creationBeforeDate;
public Date completedDate;
public Date completedAfterDate;
public Date completedBeforeDate;
public String category;
public boolean withFormKey;
public String formKey;
public String tenantId;
public String tenantIdLike;
public Integer taskVariablesLimit;
private Date dueDate;
private String category;
private String formKey;
private String tenantId;
private String tenantIdLike;
private Integer taskVariablesLimit;
}

View File

@ -1,16 +1,17 @@
package com.snow.flowable.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.snow.common.utils.StringUtils;
import com.snow.common.utils.bean.BeanUtils;
import lombok.Data;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.task.Attachment;
import org.flowable.engine.task.Comment;
import org.flowable.identitylink.api.IdentityLinkInfo;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.TaskServiceConfiguration;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@ -21,60 +22,135 @@ import java.util.stream.Collectors;
*/
@Data
public class HistoricTaskInstanceVO implements Serializable {
public String executionId;
public String processInstanceId;
/**
* 历史任务id
*/
private String id;
/**
* 流程执行ID
*/
private String executionId;
/**
* 流程实例id
*/
private String processInstanceId;
/**
*流程名称
*/
public String processName;
private String processName;
public String businessKey;
public String taskDefinitionId;
public String scopeId;
public String subScopeId;
public String scopeType;
public String scopeDefinitionId;
public String propagatedStageInstanceId;
/**
*业务参数
*/
private String businessKey;
/**
* 任务定义ID
*/
private String taskDefinitionId;
/**
* 创建时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date createTime;
private Date createTime;
/**
* 完成时间
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
public Date endTime;
private Date endTime;
/**
* 用时
*/
public String spendTime;
public String deleteReason;
public String name;
public String localizedName;
public String parentTaskId;
public String description;
public String localizedDescription;
public String owner;
private String spendTime;
/**
* 任务名称
*/
private String name;
/**
* 用户ID
*/
public String assignee;
private String assignee;
/**
* 用户名称
*/
private String assigneeName;
/**
* 任务描述
*/
private String description;
private String category;
private String isPass;
/**
* 评论
*/
private List<Comment> commentList;
/**
*附件
*/
private List<Attachment> attachmentList;
/**
* 任务变量
*/
private Map<String, Object> taskLocalVariables;
private String formKey;
/**
* 流程变量
*/
private Map<String, Object> processVariables;
private List<? extends IdentityLinkInfo> identityLinks;
/* private String scopeId;
private String subScopeId;
private String scopeType;
private String scopeDefinitionId;
private String propagatedStageInstanceId;*/
public String assigneeName;
public String taskDefinitionKey;
public String formKey;
public int priority;
public Date dueDate;
public Date claimTime;
public String category;
public String tenantId = TaskServiceConfiguration.NO_TENANT_ID;
public Date lastUpdateTime;
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;
public static List<HistoricTaskInstanceVO> warpList(List<HistoricTaskInstance> historicTaskInstanceList){
return historicTaskInstanceList.stream().map(t->{
HistoricTaskInstanceVO historicTaskInstanceVO=new HistoricTaskInstanceVO();
BeanUtils.copyProperties(t,historicTaskInstanceVO);
historicTaskInstanceVO.setTaskLocalVariables(t.getTaskLocalVariables());
historicTaskInstanceVO.setProcessVariables(t.getProcessVariables());
historicTaskInstanceVO.setIdentityLinks(t.getIdentityLinks());
return historicTaskInstanceVO;
}).collect(Collectors.toList());
}

View File

@ -15,6 +15,7 @@ import org.flowable.engine.history.HistoricProcessInstance;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@ -64,14 +65,26 @@ public class ProcessInstanceVO implements Serializable {
public Date endTime;
public String endActivityId;
/**
* 流程发起人ID
*/
public String startUserId;
/**
* 流程发起人
*/
public String startUserName;
public String startActivityId;
/**
* 删除理由
*/
public String deleteReason;
/**
* 流程用时
*/
public String processSpendTime;
/**
* 父流程ID
*/
@ -96,7 +109,7 @@ public class ProcessInstanceVO implements Serializable {
*/
public Integer isFinished;
Map<String, Object> processVariables;
public String processDefinitionCategory;
@ -109,6 +122,8 @@ public class ProcessInstanceVO implements Serializable {
}else {
processInstanceVO.setIsFinished(1);
}
Map<String, Object> processVariables = t.getProcessVariables();
processInstanceVO.setProcessVariables(processVariables);
return processInstanceVO;
}).collect(Collectors.toList());
}

View File

@ -0,0 +1,31 @@
package com.snow.flowable.enums;
/**
* 用户状态
*
* @author snow
*/
public enum FlowFinishedStatusEnum
{
FLOW_ING(0, "进行中"),
FLOW_FINISHED(1, "已完结");
private final Integer code;
private final String info;
FlowFinishedStatusEnum(Integer code, String info)
{
this.code = code;
this.info = info;
}
public Integer getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

View File

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

View File

@ -0,0 +1,33 @@
package com.snow.flowable.listener.leave;
import com.snow.common.enums.ProcessStatus;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.listener.CommonEventListener;
import com.snow.system.domain.SysOaLeave;
import com.snow.system.service.impl.SysOaLeaveServiceImpl;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-12-05 17:29
**/
@Service
public class LeaveEndListener extends CommonEventListener {
@Autowired
private SysOaLeaveServiceImpl sysOaLeaveService;
@Override
public void notify(DelegateExecution delegateExecution) {
AppForm appForm = threadLocalAppForm.get();
SysOaLeave sysOaLeave=new SysOaLeave();
sysOaLeave.setProcessStatus(ProcessStatus.PASS.ordinal());
sysOaLeave.setApplyPerson(appForm.getStartUserId());
sysOaLeave.setProcessInstanceId(appForm.getProcessInstanceId());
sysOaLeave.setLeaveNo(appForm.getBusinessKey());
sysOaLeaveService.updateSysOaLeaveByLeaveNo(sysOaLeave);
}
}

View File

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

View File

@ -0,0 +1,61 @@
package com.snow.flowable.listener.leave;
import com.snow.common.enums.ProcessStatus;
import com.snow.flowable.domain.AppForm;
import com.snow.flowable.listener.CommonEventListener;
import com.snow.flowable.service.FlowableService;
import com.snow.system.domain.SysOaLeave;
import com.snow.system.service.impl.SysOaLeaveServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* @program: snow
* @description 开始监听器
* @author: 没用的阿吉 event="end"
* @create: 2020-12-05 16:52
**/
@Service
@Slf4j
public class LeaveStartListener extends CommonEventListener implements ExecutionListener {
@Autowired
private SysOaLeaveServiceImpl sysOaLeaveService;
@Autowired
private FlowableService flowableService;
public void notify(DelegateExecution delegateExecution) {
Map<String, Object> variables = delegateExecution.getVariables();
VariableInstance variableInstance = delegateExecution.getVariableInstance(delegateExecution.getProcessInstanceId());
String leaveNo = String.valueOf(variables.get("leaveNo"));
String startUserId = String.valueOf(variables.get("startUserId"));
AppForm appForm=new AppForm();
appForm.setBusinessKey(leaveNo);
appForm.setProcessInstanceId(delegateExecution.getProcessInstanceId());
appForm.setStartUserId(startUserId);
threadLocalAppForm.set(appForm);
SysOaLeave sysOaLeave=new SysOaLeave();
sysOaLeave.setProcessStatus(ProcessStatus.CHECKING.ordinal());
sysOaLeave.setApplyPerson(appForm.getStartUserId());
sysOaLeave.setProcessInstanceId(appForm.getProcessInstanceId());
sysOaLeave.setLeaveNo(appForm.getBusinessKey());
sysOaLeaveService.updateSysOaLeaveByLeaveNo(sysOaLeave);
}
public void setAppForms(String processInstanceId){
}
}

View File

@ -126,10 +126,10 @@ public interface FlowableService {
/**
* 获取历史任务
* @param task
* @param
* @return
*/
List<HistoricTaskInstance> getHistoricTaskInstance(com.snow.flowable.domain.Task task);
List<HistoricTaskInstanceVO> getHistoricTaskInstanceNoPage(HistoricTaskInstanceDTO historicTaskInstanceDTO);
/**
* 动态获取流程节点审批信息

View File

@ -1,5 +1,6 @@
package com.snow.flowable.service.impl;
import cn.hutool.core.date.BetweenFormater;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
@ -11,7 +12,9 @@ import com.google.common.collect.Maps;
import com.snow.common.core.page.PageModel;
import com.snow.common.core.text.Convert;
import com.snow.common.exception.BusinessException;
import com.snow.flowable.common.FlowConstants;
import com.snow.flowable.domain.*;
import com.snow.flowable.enums.FlowFinishedStatusEnum;
import com.snow.flowable.service.FlowableService;
import com.snow.system.domain.ActDeModel;
import com.snow.system.domain.SysRole;
@ -33,6 +36,8 @@ import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.repository.*;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Attachment;
import org.flowable.engine.task.Comment;
import org.flowable.idm.api.User;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
@ -50,6 +55,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -88,7 +94,7 @@ public class FlowableServiceImpl implements FlowableService {
@Autowired
private HistoryService historyService;
@Autowired
@Resource
private ProcessEngine processEngine;
@Autowired
@ -97,7 +103,7 @@ public class FlowableServiceImpl implements FlowableService {
@Autowired
private ExpressionServiceImpl expressionService;
@Autowired
@Resource
private SysUserMapper sysUserMapper;
@Autowired
@ -364,7 +370,9 @@ public class FlowableServiceImpl implements FlowableService {
////设置审批人若不设置则数据表userid字段为null
Authentication.setAuthenticatedUserId(completeTaskDTO.getUserId());
if(!StringUtils.isEmpty(completeTaskDTO.getComment())){
taskService.addComment(task.getId(),task.getProcessInstanceId(),completeTaskDTO.getComment());
taskService.addComment(task.getId(),task.getProcessInstanceId(),FlowConstants.OPINION,completeTaskDTO.getComment());
}else {
taskService.addComment(task.getId(),task.getProcessInstanceId(),FlowConstants.OPINION,"");
}
List<FileEntry> files = completeTaskDTO.getFiles();
if(!CollectionUtils.isEmpty(files)){
@ -381,7 +389,8 @@ public class FlowableServiceImpl implements FlowableService {
);
}
paramMap.put(CompleteTaskDTO.IS_PASS,completeTaskDTO.getIsPass());
// taskService.claim(task.getId(),completeTaskDTO.getUserId());//claim the task当任务分配给了某一组人员时需要该组人员进行抢占抢到了就将该任务给谁处理其他人不能处理
//claim the task当任务分配给了某一组人员时需要该组人员进行抢占抢到了就将该任务给谁处理其他人不能处理认领任务
taskService.claim(task.getId(),completeTaskDTO.getUserId());
taskService.complete(task.getId(),paramMap,true);
}
@ -483,20 +492,73 @@ public class FlowableServiceImpl implements FlowableService {
}
@Override
public List<HistoricTaskInstance> getHistoricTaskInstance(com.snow.flowable.domain.Task task){
public List<HistoricTaskInstanceVO> getHistoricTaskInstanceNoPage(HistoricTaskInstanceDTO historicTaskInstanceDTO){
String userId= historicTaskInstanceDTO.getUserId();
HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
if(!StringUtils.isEmpty(task.getProcessInstanceId())){
historicTaskInstanceQuery= historicTaskInstanceQuery.processInstanceId(task.getProcessInstanceId());
}
if(!StringUtils.isEmpty(task.getTaskDefinitionKey())){
historicTaskInstanceQuery.processInstanceId(task.getTaskDefinitionKey());
}
if(!StringUtils.isEmpty(task.getAssignee())){
historicTaskInstanceQuery.taskAssignee(task.getAssignee());
}
List<HistoricTaskInstance> list = historicTaskInstanceQuery.orderByTaskCreateTime().asc().list();
return list;
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getProcessInstanceId())){
historicTaskInstanceQuery= historicTaskInstanceQuery.processInstanceId(historicTaskInstanceDTO.getProcessInstanceId());
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getTaskDefinitionKey())){
historicTaskInstanceQuery.processInstanceId(historicTaskInstanceDTO.getTaskDefinitionKey());
}
if(!StringUtils.isEmpty(userId)){
historicTaskInstanceQuery.taskAssignee(historicTaskInstanceDTO.getUserId());
//historicTaskInstanceQuery.taskCandidateUser(userId);
//historicTaskInstanceQuery.taskInvolvedUser(userId);
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getBusinessKey())){
historicTaskInstanceQuery.processInstanceBusinessKey(historicTaskInstanceDTO.getBusinessKey());
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getProcessStatus())){
Integer processStatus= historicTaskInstanceDTO.getProcessStatus();
if(processStatus==FlowFinishedStatusEnum.FLOW_ING.getCode()){
historicTaskInstanceQuery.unfinished();
}else if(processStatus==FlowFinishedStatusEnum.FLOW_FINISHED.getCode()){
historicTaskInstanceQuery.finished();
}
}
historicTaskInstanceQuery.includeTaskLocalVariables().includeProcessVariables();
List<HistoricTaskInstance> list = historicTaskInstanceQuery.orderByTaskCreateTime().asc().list();
List<HistoricTaskInstanceVO> historicTaskInstanceVOS = HistoricTaskInstanceVO.warpList(list);
setHistoricTaskInstanceVos(historicTaskInstanceVOS);
return historicTaskInstanceVOS;
}
private void setHistoricTaskInstanceVos(List<HistoricTaskInstanceVO> list){
list.parallelStream().forEach(t -> {
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<Attachment> taskAttachments = taskService.getTaskAttachments(t.getId());
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);
}
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(t.getProcessInstanceId());
t.setProcessName(historicProcessInstance.getProcessDefinitionName());
t.setBusinessKey(historicProcessInstance.getBusinessKey());
});
}
/**
@ -511,9 +573,9 @@ public class FlowableServiceImpl implements FlowableService {
.list();*/
HistoricProcessInstance processInstance= getHistoricProcessInstanceById(processInstanceId);
List<TaskVO> hisTaskVOList=Lists.newArrayList();
com.snow.flowable.domain.Task task=new com.snow.flowable.domain.Task();
task.setProcessInstanceId(processInstanceId);
List<HistoricTaskInstance> historicTaskInstance = getHistoricTaskInstance(task);
HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO();
historicTaskInstanceDTO.setProcessInstanceId(processInstanceId);
List<HistoricTaskInstanceVO> historicTaskInstance = getHistoricTaskInstanceNoPage(historicTaskInstanceDTO);
if(!CollectionUtils.isEmpty(historicTaskInstance)){
hisTaskVOList = historicTaskInstance.stream().map(t -> {
TaskVO taskVO = new TaskVO();
@ -574,6 +636,7 @@ public class FlowableServiceImpl implements FlowableService {
if(!StringUtils.isEmpty(processInstanceDTO.getStartedUserId())){
historicProcessInstanceQuery.startedBy(processInstanceDTO.getStartedUserId());
}
historicProcessInstanceQuery.includeProcessVariables();
long count = historicProcessInstanceQuery.
orderByProcessInstanceStartTime().
desc().
@ -582,13 +645,38 @@ public class FlowableServiceImpl implements FlowableService {
orderByProcessInstanceStartTime().
desc().
listPage(processInstanceDTO.getPageNum(), processInstanceDTO.getPageSize());
List<ProcessInstanceVO> processInstanceVOS = ProcessInstanceVO.warpList(historicProcessInstances);
setProcessInstanceVOs(processInstanceVOS);
PageModel<ProcessInstanceVO> pageModel = new PageModel<> ();
pageModel.setTotalCount((int)count);
pageModel.setPagedRecords(ProcessInstanceVO.warpList(historicProcessInstances));
pageModel.setPagedRecords(processInstanceVOS);
//List<ProcessInstanceVO> processInstanceVOS = com.snow.common.utils.bean.BeanUtils.transformList(pageInfo.getList(), ProcessInstanceVO.class);
return pageModel;
}
/**
* 赋值ProcessInstanceVOs
* @param processInstanceVOS
*/
public void setProcessInstanceVOs(List<ProcessInstanceVO> processInstanceVOS){
processInstanceVOS.parallelStream().forEach(t->{
Map<String, Object> processVariables = t.getProcessVariables();
t.setProcessVariables(processVariables);
//计算流程用时
if(StringUtils.isEmpty(t.getEndTime())){
String spendTime = DateUtil.formatBetween(t.getStartTime(), new Date(), BetweenFormater.Level.SECOND);
t.setProcessSpendTime(spendTime);
}else {
String spendTime = DateUtil.formatBetween(t.getStartTime(), t.getEndTime(), BetweenFormater.Level.SECOND);
t.setProcessSpendTime(spendTime);
}
String startUserId = t.getStartUserId();
SysUser sysUser = sysUserService.selectUserById(Long.parseLong(startUserId));
t.setStartUserName(sysUser.getUserName());
});
}
@Override
public PageModel<HistoricTaskInstanceVO> getHistoricTaskInstance(HistoricTaskInstanceDTO historicTaskInstanceDTO) {
HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();

View File

@ -5,6 +5,7 @@ import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.snow.common.annotation.Excel;
import com.snow.common.core.domain.BaseEntity;
import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -14,6 +15,7 @@ import org.apache.commons.lang3.builder.ToStringStyle;
* @author snow
* @date 2020-11-22
*/
@Data
public class SysOaLeave extends BaseEntity
{
private static final long serialVersionUID = 1L;
@ -60,124 +62,9 @@ public class SysOaLeave extends BaseEntity
/** 请假单号 */
@Excel(name = "请假单号")
private String leaveNo;
/**
* 请假时长
*/
private String leaveTime;
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return id;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setReason(String reason)
{
this.reason = reason;
}
public String getReason()
{
return reason;
}
public void setStartTime(Date startTime)
{
this.startTime = startTime;
}
public Date getStartTime()
{
return startTime;
}
public void setEndTime(Date endTime)
{
this.endTime = endTime;
}
public Date getEndTime()
{
return endTime;
}
public void setProcessStatus(Integer processStatus)
{
this.processStatus = processStatus;
}
public Integer getProcessStatus()
{
return processStatus;
}
public void setProcessInstanceId(String processInstanceId)
{
this.processInstanceId = processInstanceId;
}
public String getProcessInstanceId()
{
return processInstanceId;
}
public void setApplyPerson(String applyPerson)
{
this.applyPerson = applyPerson;
}
public String getApplyPerson()
{
return applyPerson;
}
public void setIsDelete(Integer isDelete)
{
this.isDelete = isDelete;
}
public Integer getIsDelete()
{
return isDelete;
}
public void setFileUrl(String fileUrl)
{
this.fileUrl = fileUrl;
}
public String getFileUrl()
{
return fileUrl;
}
public String getLeaveNo() {
return leaveNo;
}
public void setLeaveNo(String leaveNo) {
this.leaveNo = leaveNo;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("name", getName())
.append("reason", getReason())
.append("startTime", getStartTime())
.append("endTime", getEndTime())
.append("processStatus", getProcessStatus())
.append("processInstanceId", getProcessInstanceId())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateTime", getUpdateTime())
.append("updateBy", getUpdateBy())
.append("applyPerson", getApplyPerson())
.append("remark", getRemark())
.append("isDelete", getIsDelete())
.append("fileUrl", getFileUrl())
.toString();
}
}

View File

@ -50,6 +50,12 @@ public interface SysSequenceMapper
*/
public int getNextSequence(String name);
/**
* 更新下个序列值
* @param name
* @return
*/
public int updateNextSequence(String name);
/**
* 删除系统序列设置
*

View File

@ -108,6 +108,7 @@ public class SysSequenceServiceImpl implements ISysSequenceService
if(StringUtils.isNull(sysSequence)){
throw new BusinessException("该序列名称不存在");
}
sysSequenceMapper.updateNextSequence(name);
int nextSequence = sysSequenceMapper.getNextSequence(name);
String date = DateUtil.format(new Date(), "yyyyMMdd");
StringBuilder sequenceNo=new StringBuilder(name);

View File

@ -107,6 +107,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
where id = #{id}
</update>
<update id="updateSysOaLeaveByLeaveNo" parameterType="SysOaLeave">
update sys_oa_leave
<trim prefix="SET" suffixOverrides=",">

View File

@ -55,11 +55,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where name = #{name}
</update>
<update id="getNextSequence" parameterType="String">
<update id="updateNextSequence" parameterType="String">
UPDATE sys_sequence
SET current_value = current_value + increment
WHERE name = #{name}
</update>
<select id="getNextSequence" parameterType="String" resultType="integer">
select current_value
from sys_sequence
WHERE name = #{name}
</select>
<delete id="deleteSysSequenceById" parameterType="String">
delete from sys_sequence where name = #{name}
</delete>