Merge remote-tracking branch 'origin/feature/develop1.0' into feature/develop1.0

This commit is contained in:
jinqiming 2020-12-31 14:29:21 +08:00
commit 90b9bdb938
49 changed files with 1988 additions and 179 deletions

View File

@ -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()
@ -108,7 +138,7 @@ public class FlowController extends BaseController {
return prefix+"/myTakePartInProcess";
}
/**
* 获取我的流程实例
* 获取我办结的任务列表
* @param historicTaskInstanceDTO
* @return
*/

View File

@ -0,0 +1,159 @@
package com.snow.web.controller.flowable;
import java.util.List;
import com.snow.common.constant.UserConstants;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
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 com.snow.common.annotation.Log;
import com.snow.common.enums.BusinessType;
import org.springframework.stereotype.Controller;
import com.snow.system.domain.FlowGroupDO;
import com.snow.system.service.IFlowGroupDOService;
import com.snow.common.core.controller.BaseController;
import com.snow.common.core.domain.AjaxResult;
import com.snow.common.utils.poi.ExcelUtil;
import com.snow.common.utils.StringUtils;
import com.snow.common.core.domain.Ztree;
/**
* 流程组信息Controller
*
* @author snow
* @date 2020-12-19
*/
@Controller
@RequestMapping("/flow/role")
public class FlowGroupController extends BaseController
{
private String prefix = "flow/role";
@Autowired
private IFlowGroupDOService flowGroupDOService;
@RequiresPermissions("system:group:view")
@GetMapping()
public String role()
{
return prefix + "/role";
}
/**
* 查询流程组信息树列表
*/
@RequiresPermissions("system:group:list")
@PostMapping("/list")
@ResponseBody
public List<FlowGroupDO> list(FlowGroupDO flowGroupDO)
{
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<FlowGroupDO> list = flowGroupDOService.selectFlowGroupDOList(flowGroupDO);
return list;
}
/**
* 导出流程组信息列表
*/
@RequiresPermissions("system:group:export")
@Log(title = "流程组信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
@ResponseBody
public AjaxResult export(FlowGroupDO flowGroupDO)
{
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<FlowGroupDO> list = flowGroupDOService.selectFlowGroupDOList(flowGroupDO);
ExcelUtil<FlowGroupDO> util = new ExcelUtil<FlowGroupDO>(FlowGroupDO.class);
return util.exportExcel(list, "role");
}
/**
* 新增流程组信息
*/
@GetMapping(value = { "/add/{roleId}", "/add/" })
public String add(@PathVariable(value = "roleId", required = false) Long roleId, ModelMap mmap)
{
if (StringUtils.isNotNull(roleId))
{
mmap.put("flowGroupDO", flowGroupDOService.selectFlowGroupDOById(roleId));
}
return prefix + "/add";
}
/**
* 新增保存流程组信息
*/
@RequiresPermissions("system:group:add")
@Log(title = "流程组信息", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(FlowGroupDO flowGroupDO)
{
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
return toAjax(flowGroupDOService.insertFlowGroupDO(flowGroupDO));
}
/**
* 修改流程组信息
*/
@GetMapping("/edit/{roleId}")
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
FlowGroupDO flowGroupDO = flowGroupDOService.selectFlowGroupDOById(roleId);
mmap.put("flowGroupDO", flowGroupDO);
return prefix + "/edit";
}
/**
* 修改保存流程组信息
*/
@RequiresPermissions("system:group:edit")
@Log(title = "流程组信息", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(FlowGroupDO flowGroupDO)
{
return toAjax(flowGroupDOService.updateFlowGroupDO(flowGroupDO));
}
/**
* 删除
*/
@RequiresPermissions("system:group:remove")
@Log(title = "流程组信息", businessType = BusinessType.DELETE)
@GetMapping("/remove/{roleId}")
@ResponseBody
public AjaxResult remove(@PathVariable("roleId") Long roleId)
{
return toAjax(flowGroupDOService.deleteFlowGroupDOById(roleId));
}
/**
* 选择流程组信息树
*/
@GetMapping(value = { "/selectRoleTree/{roleId}", "/selectRoleTree/" })
public String selectRoleTree(@PathVariable(value = "roleId", required = false) Long roleId, ModelMap mmap)
{
if (StringUtils.isNotNull(roleId))
{
mmap.put("flowGroupDO", flowGroupDOService.selectFlowGroupDOById(roleId));
}
return prefix + "/tree";
}
/**
* 加载流程组信息树列表
*/
@GetMapping("/treeData")
@ResponseBody
public List<Ztree> treeData()
{
List<Ztree> ztrees = flowGroupDOService.selectFlowGroupDOTree();
return ztrees;
}
}

View File

@ -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);
}
/**
* 删除发布
*/

View File

@ -10,13 +10,13 @@ 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.enums.WorkRecordStatus;
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 +29,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 +59,9 @@ public class SysOaLeaveController extends BaseController
@Autowired
private ISysSequenceService sequenceService;
@Autowired
private AppFormService appFormService;
@RequiresPermissions("system:leave:view")
@GetMapping()
@ -174,8 +173,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();
@ -198,7 +198,7 @@ public class SysOaLeaveController extends BaseController
HistoricTaskInstanceDTO historicTaskInstanceDTO=new HistoricTaskInstanceDTO();
historicTaskInstanceDTO.setBusinessKey(sysOaLeave.getLeaveNo());
historicTaskInstanceDTO.setProcessInstanceId(sysOaLeave.getProcessInstanceId());
historicTaskInstanceDTO.setProcessStatus(1);
historicTaskInstanceDTO.setProcessStatus(WorkRecordStatus.FINISHED);
List<HistoricTaskInstanceVO> historicTaskInstanceList= flowableService.getHistoricTaskInstanceNoPage(historicTaskInstanceDTO);
String spendTime = DateUtil.formatBetween(sysOaLeave.getStartTime(), sysOaLeave.getEndTime(), BetweenFormater.Level.SECOND);
sysOaLeave.setLeaveTime(spendTime);
@ -207,6 +207,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";
}
/**
* 删除请假单
*/

View File

@ -58,6 +58,7 @@ public class SysRoleController extends BaseController
public List<SysRole> list(SysRole role)
{
startPage();
role.setRoleType(UserConstants.SYSTEM_ROLE_TYPE);
List<SysRole> list = roleService.selectRoleList(role);
return list;
}

View File

@ -2,6 +2,8 @@ package com.snow.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import com.snow.system.service.impl.SysSequenceServiceImpl;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -51,6 +53,9 @@ public class SysUserController extends BaseController
@Autowired
private SysPasswordService passwordService;
@Autowired
private SysSequenceServiceImpl sysSequenceService;
@RequiresPermissions("system:user:view")
@GetMapping()
public String user()
@ -107,7 +112,10 @@ public class SysUserController extends BaseController
@GetMapping("/add")
public String add(ModelMap mmap)
{
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
String jobNumber = sysSequenceService.getNewSequenceNo("SNOW");
mmap.put("jobNumber",jobNumber);
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()&&r.getRoleType()==UserConstants.SYSTEM_ROLE_TYPE).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostAll());
return prefix + "/add";
}

View 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);

View File

@ -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>

View File

@ -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 ''">&nbsp;&nbsp
<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>

View File

@ -60,13 +60,17 @@
title: '流程名称'
},
{
field: 'name',
field: 'taskName',
title: '任务名称'
},
{
field: 'businessKey',
title: '单号'
title: '单号',
formatter: function(value, row, index) {
var fromDetailUrl= row.fromDetailUrl;
return '<a class="success" href="' + fromDetailUrl+ '" target="_blank">'+value+'</a> ';
}
},
{
@ -75,11 +79,11 @@
},
{
field: 'endTime',
field: 'completeTime',
title: '完成时间'
},
{
field: 'spendTime',
field: 'handleTaskTime',
title: '任务耗时'
},

View File

@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<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-role-add">
<div class="form-group">
<label class="col-sm-3 control-label">父角色:</label>
<div class="col-sm-8">
<div class="input-group">
<input id="treeId" name="parentId" type="hidden" th:value="${flowGroupDO?.roleId}"/>
<input class="form-control" type="text" onclick="selectRoleTree()" id="treeName" readonly="true" th:value="${flowGroupDO?.roleName}">
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">角色名称:</label>
<div class="col-sm-8">
<input name="roleName" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">角色权限字符串:</label>
<div class="col-sm-8">
<input name="roleKey" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">显示顺序:</label>
<div class="col-sm-8">
<input name="roleSort" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">角色状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${'status_' + dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}" required>
<label th:for="${'status_' + dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "flow/role"
$("#form-role-add").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-role-add').serialize());
}
}
/*流程组信息-新增-选择父部门树*/
function selectRoleTree() {
var options = {
title: '流程组信息选择',
width: "380",
url: prefix + "/selectRoleTree/" + $("#treeId").val(),
callBack: doSubmit
};
$.modal.openOptions(options);
}
function doSubmit(index, layero){
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
layer.close(index);
}
</script>
</body>
</html>

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<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-role-edit" th:object="${flowGroupDO}">
<input name="roleId" th:field="*{roleId}" type="hidden">
<div class="form-group">
<label class="col-sm-3 control-label">父角色:</label>
<div class="col-sm-8">
<div class="input-group">
<input id="treeId" name="parentId" type="hidden" th:field="*{parentId}" />
<input class="form-control" type="text" onclick="selectRoleTree()" id="treeName" readonly="true" th:field="*{parentName}">
<span class="input-group-addon"><i class="fa fa-search"></i></span>
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">角色名称:</label>
<div class="col-sm-8">
<input name="roleName" th:field="*{roleName}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">角色权限字符串:</label>
<div class="col-sm-8">
<input name="roleKey" th:field="*{roleKey}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label is-required">显示顺序:</label>
<div class="col-sm-8">
<input name="roleSort" th:field="*{roleSort}" class="form-control" type="text" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">角色状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${'status_' + dict.dictCode}" name="status" th:value="${dict.dictValue}" th:field="*{status}" required>
<label th:for="${'status_' + dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var prefix = ctx + "flow/role";
$("#form-role-edit").validate({
focusCleanup: true
});
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-role-edit').serialize());
}
}
/*流程组信息-新增-选择父部门树*/
function selectRoleTree() {
var options = {
title: '流程组信息选择',
width: "380",
url: prefix + "/selectRoleTree/" + $("#treeId").val(),
callBack: doSubmit
};
$.modal.openOptions(options);
}
function doSubmit(index, layero){
var body = layer.getChildFrame('body', index);
$("#treeId").val(body.find('#treeId').val());
$("#treeName").val(body.find('#treeName').val());
layer.close(index);
}
</script>
</body>
</html>

View File

@ -0,0 +1,134 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('流程组信息列表')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 search-collapse">
<form id="formId">
<div class="select-list">
<ul>
<li>
<label>角色名称:</label>
<input type="text" name="roleName"/>
</li>
<li>
<label>角色标识:</label>
<input type="text" name="roleKey"/>
</li>
<li>
<label>角色状态:</label>
<select name="status" th:with="type=${@dict.getType('sys_show_hide')}">
<option value="">所有</option>
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option>
</select>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.treeTable.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>
</li>
</ul>
</div>
</form>
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:role:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary" onclick="$.operate.edit()" shiro:hasPermission="system:role:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-info" id="expandAllBtn">
<i class="fa fa-exchange"></i> 展开/折叠
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-tree-table"></table>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<script th:inline="javascript">
var addFlag = [[${@permission.hasPermi('system:role:add')}]];
var editFlag = [[${@permission.hasPermi('system:role:edit')}]];
var removeFlag = [[${@permission.hasPermi('system:role:remove')}]];
var statusDatas = [[${@dict.getType('sys_show_hide')}]];
var prefix = ctx + "flow/role";
$(function() {
var options = {
code: "roleId",
parentCode: "parentId",
expandColumn: "1",
uniqueId: "roleId",
url: prefix + "/list",
createUrl: prefix + "/add/{id}",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove/{id}",
exportUrl: prefix + "/export",
modalName: "流程组信息",
columns: [{
field: 'selectItem',
radio: true
},
{
field: 'roleName',
title: '角色组名称',
align: 'left'
},
{
field: 'roleKey',
title: '角色组权限标识',
align: 'left'
},/*
{
field: 'roleSort',
title: '显示顺序',
align: 'left'
},*/
{
field: 'status',
title: '角色组状态',
align: 'left',
formatter: function(value, row, index) {
return $.table.selectDictLabel(statusDatas, value);
}
},
{
field: 'remark',
title: '备注',
align: 'left'
},
{
title: '操作',
align: 'center',
align: 'left',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.roleId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-info btn-xs ' + addFlag + '" href="javascript:void(0)" onclick="$.operate.add(\'' + row.roleId + '\')"><i class="fa fa-plus"></i>新增</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.roleId + '\')"><i class="fa fa-remove"></i>删除</a> ');
actions.push("<a class='btn btn-warning btn-xs " + editFlag + "' href='javascript:void(0)' onclick='authUser(" + row.roleId + ")'><i class='fa fa-user'></i>分配用户</a>");
return actions.join('');
}
}]
};
$.treeTable.init(options);
});
/* 角色管理-分配用户 */
function authUser(roleId) {
var prefix = ctx + "system/role";
var url = prefix + '/authUser/' + roleId;
$.modal.openTab("分配用户", url);
}
</script>
</body>
</html>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('流程组信息树选择')" />
<th:block th:include="include :: ztree-css" />
</head>
<style>
body{height:auto;font-family: "Microsoft YaHei";}
button{font-family: "SimSun","Helvetica Neue",Helvetica,Arial;}
</style>
<body class="hold-transition box box-main">
<input id="treeId" name="treeId" type="hidden" th:value="${flowGroupDO?.roleId}"/>
<input id="treeName" name="treeName" type="hidden" th:value="${flowGroupDO?.roleName}"/>
<div class="wrapper"><div class="treeShowHideButton" onclick="$.tree.toggleSearch();">
<label id="btnShow" title="显示搜索" style="display:none;"></label>
<label id="btnHide" title="隐藏搜索"></label>
</div>
<div class="treeSearchInput" id="search">
<label for="keyword">关键字:</label><input type="text" class="empty" id="keyword" maxlength="50">
<button class="btn" id="btn" onclick="$.tree.searchNode()"> 搜索 </button>
</div>
<div class="treeExpandCollapse">
<a href="#" onclick="$.tree.expand()">展开</a> /
<a href="#" onclick="$.tree.collapse()">折叠</a>
</div>
<div id="tree" class="ztree treeselect"></div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: ztree-js" />
<script th:inline="javascript">
$(function() {
var url = ctx + "flow/role/treeData";
var options = {
url: url,
expandLevel: 2,
onClick : zOnClick
};
$.tree.init(options);
});
function zOnClick(event, treeId, treeNode) {
var treeId = treeNode.id;
var treeName = treeNode.name;
$("#treeId").val(treeId);
$("#treeName").val(treeName);
}
</script>
</body>
</html>

View File

@ -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"/>

View File

@ -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>

View File

@ -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>

View File

@ -57,11 +57,11 @@
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="col-sm-4 control-label is-required">工号:</label>
<label class="col-sm-4 control-label">工号:</label>
<div class="col-sm-8">
<div class="input-group">
<input id="jobnumber" name="jobnumber" placeholder="请输入工号" class="form-control" type="text" required>
<span class="input-group-addon"><i class="fa fa-mobile"></i></span>
<input id="jobnumber" name="jobnumber" th:value="${jobNumber}" class="form-control" type="text" readonly>
<span class="input-group-addon"><i class="fa fa-graduation-cap"></i></span>
</div>
</div>
</div>
@ -72,7 +72,7 @@
<div class="col-sm-8">
<div class="input-group">
<input id="workPlace" name="workPlace" class="form-control" type="text" maxlength="20" placeholder="请输入工作地点" required>
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
<span class="input-group-addon"><i class="fa fa-address-card"></i></span>
</div>
</div>
</div>
@ -84,8 +84,8 @@
<label class="col-sm-4 control-label is-required">入职时间:</label>
<div class="col-sm-8">
<div class="input-group">
<input id="hiredDate" name="hiredDate" placeholder="请输入入职时间" class="form-control" type="text" required>
<span class="input-group-addon"><i class="fa fa-mobile"></i></span>
<input id="hiredDate" name="hiredDate" type="text" class="form-control" placeholder="yyyy-MM-dd">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
@ -195,6 +195,15 @@
<th:block th:include="include :: footer" />
<th:block th:include="include :: select2-js" />
<script>
layui.use('laydate', function() {
var laydate = layui.laydate;
laydate.render({
elem: '#hiredDate',
type: 'date'
});
});
var prefix = ctx + "system/user";
$("#form-user-add").validate({
@ -274,9 +283,12 @@
var status = $("input[id='status']").is(':checked') == true ? 0 : 1;
var roleIds = $.form.selectCheckeds("role");
var postIds = $.form.selectSelects("post");
var hiredDate=$("#hiredDate").val();
var date= new Date(hiredDate);
data.push({"name": "status", "value": status});
data.push({"name": "roleIds", "value": roleIds});
data.push({"name": "postIds", "value": postIds});
data.push({"name": "hiredDate", "value": date.getTime()});
$.operate.saveTab(prefix + "/add", data);
}
}

View File

@ -1,20 +1,27 @@
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.flowable.service.impl.FlowableUserServiceImpl;
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 +33,11 @@ import java.util.Map;
public class FlowableServiceTests extends JunitTestApplication {
@Autowired
private FlowableService flowableService;
@Autowired
private TaskService taskService;
@Autowired
private FlowableUserServiceImpl flowableUserService;
@Test
public void startProcessInstanceByKey(){
@ -42,9 +54,10 @@ public class FlowableServiceTests extends JunitTestApplication {
@Test
public void getDeploymentList(){
DeploymentQueryDTO startProcessDTO=new DeploymentQueryDTO();
flowableUserService.getUserByFlowGroupId(108L);
//DeploymentQueryDTO startProcessDTO=new DeploymentQueryDTO();
flowableService.getDeploymentList(startProcessDTO);
// flowableService.getDeploymentList(startProcessDTO);
}
@Test
@ -52,4 +65,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));
}
}

View File

@ -98,6 +98,12 @@ public class UserConstants
public static final String SYSTEM_USER_TYPE = "00";
public static final String REGISTER_USER_TYPE = "01";
/**
* 用户类型
*/
public static final Integer SYSTEM_ROLE_TYPE = 1;
public static final Integer FLOW_ROLE_TYPE = 2;
/**
* 手机号码格式限制
*/

View File

@ -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";
/**
* 当前类的包名
*/

View File

@ -0,0 +1,10 @@
package com.snow.flowable.common.enums;
/**
* @program: snow
* @description
* @author: 没用的阿吉
* @create: 2020-12-13 19:54
**/
public enum FlowStatusEnum {
}

View File

@ -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;
/**
* 流程申请单需实现此方法,返回申请单对应的流程定义.

View File

@ -1,5 +1,6 @@
package com.snow.flowable.domain;
import com.snow.common.enums.WorkRecordStatus;
import com.snow.flowable.enums.FlowFinishedStatusEnum;
import lombok.Data;
@ -91,11 +92,16 @@ public class HistoricTaskInstanceDTO extends FlowBaseDTO implements Serializabl
/**
* 流程状态0--进行中1-结束
*/
private Integer processStatus;
private WorkRecordStatus processStatus;
/**
* 任务状态0--进行中1--结束
*/
private WorkRecordStatus taskStatus;
private Date dueDate;
private String category;

View File

@ -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,26 @@ 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 String fromDetailUrl;
private AppForm appForm;
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 +114,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());

View File

@ -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->{

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
/**

View File

@ -1,5 +1,7 @@
package com.snow.flowable.service;
import com.snow.system.domain.SysRole;
import com.snow.system.domain.SysUser;
import org.flowable.ui.common.model.RemoteGroup;
import org.flowable.ui.common.model.RemoteUser;
@ -19,7 +21,33 @@ public interface FlowableUserService {
*/
Map<String, Object> loginFlowable();
/**
* 获取用户组
* @param name
* @return
*/
List<RemoteUser> getFlowUserList(String name);
/**
* 获取流程角色组
* @param filter
* @return
*/
List<RemoteGroup> getFlowUserGroupList(String filter);
/**
* 根据流程组查询角色
* @param groupId
* @return
*/
List<SysUser> getUserByFlowGroupId(Long groupId);
/**
* 根据流程组查询角色
* @param userId
* @return
*/
List<SysRole> getFlowGroupByUserId(Long userId);
}

View File

@ -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);
}
}

View File

@ -11,12 +11,14 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.snow.common.core.page.PageModel;
import com.snow.common.core.text.Convert;
import com.snow.common.enums.WorkRecordStatus;
import com.snow.common.exception.BusinessException;
import com.snow.flowable.common.constants.FlowConstants;
import com.snow.flowable.config.ICustomProcessDiagramGenerator;
import com.snow.flowable.domain.*;
import com.snow.flowable.enums.FlowFinishedStatusEnum;
import com.snow.flowable.service.FlowableService;
import com.snow.flowable.service.FlowableUserService;
import com.snow.system.domain.ActDeModel;
import com.snow.system.domain.SysRole;
import com.snow.system.domain.SysUser;
@ -39,6 +41,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 +59,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;
@ -113,6 +118,9 @@ public class FlowableServiceImpl implements FlowableService {
@Autowired
private ObjectMapper objectMapper;
@Resource
private FlowableUserService flowableUserService;
@Override
public void saveModel(ActDeModel actDeModel) {
// 构建ModelEditorSource
@ -292,6 +300,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 +380,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=flowableUserService.getUserByFlowGroupId(Long.parseLong(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;
}
/**
* starterUSER_ID与PROC_INST_ID_记录流程的发起者
* candidateUSER_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=flowableUserService.getUserByFlowGroupId(Long.parseLong(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 +559,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();
}
@ -530,14 +599,15 @@ public class FlowableServiceImpl implements FlowableService {
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getProcessStatus())){
Integer processStatus= historicTaskInstanceDTO.getProcessStatus();
if(processStatus==FlowFinishedStatusEnum.FLOW_ING.getCode()){
WorkRecordStatus workRecordStatus=historicTaskInstanceDTO.getProcessStatus();
if( workRecordStatus.equals(WorkRecordStatus.NO_FINISHED)){
historicTaskInstanceQuery.unfinished();
}else if(processStatus==FlowFinishedStatusEnum.FLOW_FINISHED.getCode()){
}else if(workRecordStatus.equals(WorkRecordStatus.FINISHED)){
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 +617,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 +669,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 +693,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 +752,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);
@ -695,18 +774,42 @@ public class FlowableServiceImpl implements FlowableService {
@Override
public PageModel<HistoricTaskInstanceVO> getHistoricTaskInstance(HistoricTaskInstanceDTO historicTaskInstanceDTO) {
HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getProcessDefinitionName())){
historicTaskInstanceQuery.processDefinitionName(historicTaskInstanceDTO.getProcessDefinitionName());
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getUserId())){
historicTaskInstanceQuery.taskAssignee(historicTaskInstanceDTO.getUserId());
//只能判断null,不能判断""
Optional.ofNullable(historicTaskInstanceDTO.getUserId()).ifPresent(
userId-> {
if(!StringUtils.isEmpty(historicTaskInstanceQuery.taskAssignee(userId))){
historicTaskInstanceQuery.taskAssignee(userId);
}
}
);
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getBusinessKeyLike())){
historicTaskInstanceQuery.processInstanceBusinessKeyLike(historicTaskInstanceDTO.getBusinessKeyLike());
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getBusinessKey())){
historicTaskInstanceQuery.processInstanceBusinessKey(historicTaskInstanceDTO.getBusinessKey());
}
if(!StringUtils.isEmpty(historicTaskInstanceDTO.getBusinessKeyLike())){
historicTaskInstanceQuery.processInstanceBusinessKeyLike(historicTaskInstanceDTO.getBusinessKeyLike());
}
Optional.ofNullable(historicTaskInstanceDTO.getTaskStatus()).ifPresent(m->{
if(m.equals(WorkRecordStatus.NO_FINISHED)){
historicTaskInstanceQuery.unfinished();
}
if(m.equals(WorkRecordStatus.FINISHED)){
historicTaskInstanceQuery.finished();
}
});
Optional.ofNullable(historicTaskInstanceDTO.getProcessStatus()).ifPresent(m->{
if(m.equals(WorkRecordStatus.NO_FINISHED)){
historicTaskInstanceQuery.processUnfinished();
}
if(m.equals(WorkRecordStatus.FINISHED)){
historicTaskInstanceQuery.processFinished();
}
});
historicTaskInstanceQuery.includeIdentityLinks().includeProcessVariables().includeTaskLocalVariables();
long count = historicTaskInstanceQuery.orderByHistoricTaskInstanceStartTime().
desc().
count();
@ -722,8 +825,18 @@ 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);
Map<String, Object> processVariables = t.getProcessVariables();
String url= Optional.ofNullable(String.valueOf(processVariables.get(FlowConstants.BUS_VAR_URL))).orElse("");
if(!StringUtils.isEmpty(url)){
historicTaskInstanceVO.setFromDetailUrl(url+"?processInstanceId="+t.getProcessInstanceId());
}
AppForm appForm=(AppForm)processVariables.get(FlowConstants.APP_FORM);
historicTaskInstanceVO.setAppForm(appForm);
historicTaskInstanceVO.setCompleteTime(t.getEndTime());
String spendTime = DateUtil.formatBetween(DateUtil.between(t.getCreateTime(), t.getEndTime(), DateUnit.SECOND));
historicTaskInstanceVO.setHandleTaskTime(spendTime);
historicTaskInstanceVO.setTaskId(t.getId());
historicTaskInstanceVO.setTaskName(t.getName());
HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(t.getProcessInstanceId());
historicTaskInstanceVO.setProcessName(historicProcessInstance.getProcessDefinitionName());
historicTaskInstanceVO.setBusinessKey(historicProcessInstance.getBusinessKey());
@ -783,7 +896,7 @@ public class FlowableServiceImpl implements FlowableService {
}
}
TaskVO.TaskVOBuilder taskVOBuilder = TaskVO.builder().taskName(userTask.getName()).
handleNameList(handleNameList).
handleUserList(handleNameList).
taskDefinitionKey(userTask.getId()).
startUserId(processInstance.getStartUserId());
@ -813,7 +926,7 @@ public class FlowableServiceImpl implements FlowableService {
}else {
for (String candidateGroup:candidateGroups){
if(com.snow.common.utils.StringUtils.isNumeric(candidateGroup)){
List<SysUser> sysUsers = sysUserMapper.selectUserListByRoleId(candidateGroup);
List<SysUser> sysUsers=flowableUserService.getUserByFlowGroupId(Long.parseLong(candidateGroup));
if(!CollectionUtils.isEmpty(sysUsers)){
List<String> collect = sysUsers.stream().map(SysUser::getUserName).collect(Collectors.toList());
handleNameList.addAll(collect);
@ -826,7 +939,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 +976,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,16 +1053,25 @@ 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());
}
}
/**
* 获取高亮的线
* @param bpmnModel
* @param processDefinitionEntity
* @param historicActivityInstances
* @return
*/
private List<String> getHighLightedFlows(BpmnModel bpmnModel,ProcessDefinitionEntity processDefinitionEntity,List<HistoricActivityInstance> historicActivityInstances) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //24小时制
List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId

View File

@ -1,10 +1,13 @@
package com.snow.flowable.service.impl;
import com.google.common.collect.Lists;
import com.snow.common.constant.UserConstants;
import com.snow.common.utils.StringUtils;
import com.snow.flowable.service.FlowableUserService;
import com.snow.system.domain.FlowGroupDO;
import com.snow.system.domain.SysRole;
import com.snow.system.domain.SysUser;
import com.snow.system.service.IFlowGroupDOService;
import com.snow.system.service.ISysRoleService;
import com.snow.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
@ -12,11 +15,9 @@ import org.flowable.ui.common.model.RemoteGroup;
import org.flowable.ui.common.model.RemoteUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -29,11 +30,18 @@ import java.util.stream.Collectors;
@Slf4j
public class FlowableUserServiceImpl implements FlowableUserService {
//存放所有子几点
private static Set<Long> childFlowGroup= new HashSet<>();
//存放所有的父节点
private static Set<Long> parentFlowGroup= new HashSet<>();
@Autowired
private ISysUserService iSysUserService;
@Autowired
private ISysRoleService sysRoleService;
@Autowired
private IFlowGroupDOService flowGroupDOService;
@Override
public Map<String, Object> loginFlowable() {
Map<String, Object> map = new HashMap<>();
@ -69,7 +77,7 @@ public class FlowableUserServiceImpl implements FlowableUserService {
remoteUser.setEmail(t.getEmail());
remoteUser.setDisplayName(t.getUserName());
remoteUser.setFullName(t.getUserName());
remoteUser.setFirstName(t.getUserName());
// remoteUser.setFirstName(t.getUserName());
remoteUser.setLastName(t.getUserName());
List<SysRole> roles = t.getRoles();
@ -93,6 +101,7 @@ public class FlowableUserServiceImpl implements FlowableUserService {
public List<RemoteGroup> getFlowUserGroupList(String filter) {
SysRole sysRole=new SysRole();
sysRole.setRoleName(filter);
sysRole.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<SysRole> sysRoles = sysRoleService.selectRoleList(sysRole);
List<RemoteGroup> remoteGroupList=Lists.newArrayList();
if(!StringUtils.isEmpty(sysRoles)) {
@ -107,4 +116,66 @@ public class FlowableUserServiceImpl implements FlowableUserService {
return remoteGroupList;
}
@Override
public List<SysUser> getUserByFlowGroupId(Long groupId) {
FlowGroupDO flowGroupDO = flowGroupDOService.selectFlowGroupDOById(groupId);
//先获取所有的子组Id
Set<Long> allSonSysRoleList = getAllSonSysRoleList(groupId);
allSonSysRoleList.add(flowGroupDO.getRoleId());
//根据角色获取所有用户
List<SysUser> userList = iSysUserService.selectUserListByRoleIds( new ArrayList<>(allSonSysRoleList));
return userList;
}
@Override
public List<SysRole> getFlowGroupByUserId(Long userId) {
List<SysRole> sysRoles = sysRoleService.selectRolesByUserId(userId);
return sysRoles;
}
/**
* 获取某个父节点下面的所有子节点
* @param parentId
* @return
*/
public Set<Long> getAllSonSysRoleList(Long parentId){
FlowGroupDO sysRole=new FlowGroupDO();
sysRole.setParentId(parentId);
sysRole.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<FlowGroupDO> sysRoleList = flowGroupDOService.selectFlowGroupDOList(sysRole);
if(!CollectionUtils.isEmpty(sysRoleList)){
Set<Long> collect = sysRoleList.stream().map(FlowGroupDO::getRoleId).collect(Collectors.toSet());
childFlowGroup.addAll(collect);
for(FlowGroupDO flowGroupDO: sysRoleList){
// 不为空则递归
getAllSonSysRoleList(flowGroupDO.getRoleId());
}
}
return childFlowGroup;
}
/**
* 获取某个子节点下面的所有父节点
* @param roleId
* @return
*/
public Set<Long> getAllParentSysRoleList(Long roleId){
SysRole sysRole = sysRoleService.selectRoleById(roleId);
if(StringUtils.isNotNull(sysRole)){
FlowGroupDO flowGroupDO=new FlowGroupDO();
flowGroupDO.setRoleId(sysRole.getParentId());
flowGroupDO.setRoleType(UserConstants.FLOW_ROLE_TYPE);
List<FlowGroupDO> sysRoleList = flowGroupDOService.selectFlowGroupDOList(flowGroupDO);
Set<Long> collect = sysRoleList.stream().map(FlowGroupDO::getRoleId).collect(Collectors.toSet());
parentFlowGroup.addAll(collect);
for(Long id: collect){
// 不为空则递归
getAllParentSysRoleList(id);
}
}
return parentFlowGroup;
}
}

View File

@ -0,0 +1,138 @@
package com.snow.system.domain;
import com.snow.common.annotation.Excel;
import com.snow.common.core.domain.TreeEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 流程组信息对象 sys_role
*
* @author snow
* @date 2020-12-19
*/
public class FlowGroupDO extends TreeEntity
{
private static final long serialVersionUID = 1L;
/** 角色ID */
private Long roleId;
/** 角色名称 */
@Excel(name = "角色名称")
private String roleName;
/** 角色权限字符串 */
@Excel(name = "角色权限字符串")
private String roleKey;
/** 显示顺序 */
@Excel(name = "显示顺序")
private Integer roleSort;
/** 数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限 */
private String dataScope;
/** 角色状态0正常 1停用 */
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
/** 角色类型1--系统角色2--流程组) */
private Integer roleType;
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleName(String roleName)
{
this.roleName = roleName;
}
public String getRoleName()
{
return roleName;
}
public void setRoleKey(String roleKey)
{
this.roleKey = roleKey;
}
public String getRoleKey()
{
return roleKey;
}
public void setRoleSort(Integer roleSort)
{
this.roleSort = roleSort;
}
public Integer getRoleSort()
{
return roleSort;
}
public void setDataScope(String dataScope)
{
this.dataScope = dataScope;
}
public String getDataScope()
{
return dataScope;
}
public void setStatus(String status)
{
this.status = status;
}
public String getStatus()
{
return status;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getDelFlag()
{
return delFlag;
}
public void setRoleType(Integer roleType)
{
this.roleType = roleType;
}
public Integer getRoleType()
{
return roleType;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("roleId", getRoleId())
.append("roleName", getRoleName())
.append("roleKey", getRoleKey())
.append("roleSort", getRoleSort())
.append("dataScope", getDataScope())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("parentId", getParentId())
.append("roleType", getRoleType())
.toString();
}
}

View File

@ -57,6 +57,17 @@ public class SysRole extends BaseEntity
/** 部门组(数据权限) */
private Long[] deptIds;
public Integer getRoleType() {
return roleType;
}
public void setRoleType(Integer roleType) {
this.roleType = roleType;
}
private Integer roleType;
/** 子菜单 */
private List<SysRole> children = new ArrayList<>();

View File

@ -0,0 +1,61 @@
package com.snow.system.mapper;
import java.util.List;
import com.snow.system.domain.FlowGroupDO;
/**
* 流程组信息Mapper接口
*
* @author snow
* @date 2020-12-19
*/
public interface FlowGroupDOMapper
{
/**
* 查询流程组信息
*
* @param roleId 流程组信息ID
* @return 流程组信息
*/
public FlowGroupDO selectFlowGroupDOById(Long roleId);
/**
* 查询流程组信息列表
*
* @param flowGroupDO 流程组信息
* @return 流程组信息集合
*/
public List<FlowGroupDO> selectFlowGroupDOList(FlowGroupDO flowGroupDO);
/**
* 新增流程组信息
*
* @param flowGroupDO 流程组信息
* @return 结果
*/
public int insertFlowGroupDO(FlowGroupDO flowGroupDO);
/**
* 修改流程组信息
*
* @param flowGroupDO 流程组信息
* @return 结果
*/
public int updateFlowGroupDO(FlowGroupDO flowGroupDO);
/**
* 删除流程组信息
*
* @param roleId 流程组信息ID
* @return 结果
*/
public int deleteFlowGroupDOById(Long roleId);
/**
* 批量删除流程组信息
*
* @param roleIds 需要删除的数据ID
* @return 结果
*/
public int deleteFlowGroupDOByIds(String[] roleIds);
}

View File

@ -19,6 +19,12 @@ public interface SysOaLeaveMapper
*/
public SysOaLeave selectSysOaLeaveById(Integer id);
/**
* 查询请求单
* @param leaveNo
* @return
*/
public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo);
/**
* 查询请假单列表
*

View File

@ -1,7 +1,10 @@
package com.snow.system.mapper;
import java.util.List;
import java.util.Set;
import com.snow.system.domain.SysUser;
import org.apache.ibatis.annotations.Param;
/**
* 用户表 数据层
@ -33,6 +36,13 @@ public interface SysUserMapper
*/
public List<SysUser> selectUserListByRoleId(String roleId);
/**
*
* @param roleIds
* @return
*/
public List<SysUser> selectUserListByRoleIds(@Param("roleIds") List<Long> roleIds);
/**
* 根据条件分页查询未分配用户角色列表
*

View File

@ -0,0 +1,69 @@
package com.snow.system.service;
import java.util.List;
import com.snow.system.domain.FlowGroupDO;
import com.snow.common.core.domain.Ztree;
/**
* 流程组信息Service接口
*
* @author snow
* @date 2020-12-19
*/
public interface IFlowGroupDOService
{
/**
* 查询流程组信息
*
* @param roleId 流程组信息ID
* @return 流程组信息
*/
public FlowGroupDO selectFlowGroupDOById(Long roleId);
/**
* 查询流程组信息列表
*
* @param flowGroupDO 流程组信息
* @return 流程组信息集合
*/
public List<FlowGroupDO> selectFlowGroupDOList(FlowGroupDO flowGroupDO);
/**
* 新增流程组信息
*
* @param flowGroupDO 流程组信息
* @return 结果
*/
public int insertFlowGroupDO(FlowGroupDO flowGroupDO);
/**
* 修改流程组信息
*
* @param flowGroupDO 流程组信息
* @return 结果
*/
public int updateFlowGroupDO(FlowGroupDO flowGroupDO);
/**
* 批量删除流程组信息
*
* @param ids 需要删除的数据ID
* @return 结果
*/
public int deleteFlowGroupDOByIds(String ids);
/**
* 删除流程组信息信息
*
* @param roleId 流程组信息ID
* @return 结果
*/
public int deleteFlowGroupDOById(Long roleId);
/**
* 查询流程组信息树列表
*
* @return 所有流程组信息信息
*/
public List<Ztree> selectFlowGroupDOTree();
}

View File

@ -19,6 +19,13 @@ public interface ISysOaLeaveService
*/
public SysOaLeave selectSysOaLeaveById(Integer id);
/**
*
* @param leaveNo
* @return
*/
public SysOaLeave selectSysOaLeaveByLeaveNo(String leaveNo);
/**
* 查询请假单列表
*

View File

@ -1,6 +1,8 @@
package com.snow.system.service;
import java.util.List;
import java.util.Set;
import com.snow.system.domain.SysUser;
import com.snow.system.domain.SysUserRole;
@ -19,6 +21,13 @@ public interface ISysUserService
*/
public List<SysUser> selectUserList(SysUser user);
/**
*
* @param roleIds
* @return
*/
public List<SysUser> selectUserListByRoleIds(List<Long> roleIds);
/**
* 根据条件分页查询已分配用户角色列表
*

View File

@ -0,0 +1,121 @@
package com.snow.system.service.impl;
import java.util.List;
import java.util.ArrayList;
import com.snow.common.core.domain.Ztree;
import com.snow.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.snow.system.mapper.FlowGroupDOMapper;
import com.snow.system.domain.FlowGroupDO;
import com.snow.system.service.IFlowGroupDOService;
import com.snow.common.core.text.Convert;
/**
* 流程组信息Service业务层处理
*
* @author snow
* @date 2020-12-19
*/
@Service
public class FlowGroupDOServiceImpl implements IFlowGroupDOService
{
@Autowired
private FlowGroupDOMapper flowGroupDOMapper;
/**
* 查询流程组信息
*
* @param roleId 流程组信息ID
* @return 流程组信息
*/
@Override
public FlowGroupDO selectFlowGroupDOById(Long roleId)
{
return flowGroupDOMapper.selectFlowGroupDOById(roleId);
}
/**
* 查询流程组信息列表
*
* @param flowGroupDO 流程组信息
* @return 流程组信息
*/
@Override
public List<FlowGroupDO> selectFlowGroupDOList(FlowGroupDO flowGroupDO)
{
return flowGroupDOMapper.selectFlowGroupDOList(flowGroupDO);
}
/**
* 新增流程组信息
*
* @param flowGroupDO 流程组信息
* @return 结果
*/
@Override
public int insertFlowGroupDO(FlowGroupDO flowGroupDO)
{
flowGroupDO.setCreateTime(DateUtils.getNowDate());
return flowGroupDOMapper.insertFlowGroupDO(flowGroupDO);
}
/**
* 修改流程组信息
*
* @param flowGroupDO 流程组信息
* @return 结果
*/
@Override
public int updateFlowGroupDO(FlowGroupDO flowGroupDO)
{
flowGroupDO.setUpdateTime(DateUtils.getNowDate());
return flowGroupDOMapper.updateFlowGroupDO(flowGroupDO);
}
/**
* 删除流程组信息对象
*
* @param ids 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteFlowGroupDOByIds(String ids)
{
return flowGroupDOMapper.deleteFlowGroupDOByIds(Convert.toStrArray(ids));
}
/**
* 删除流程组信息信息
*
* @param roleId 流程组信息ID
* @return 结果
*/
@Override
public int deleteFlowGroupDOById(Long roleId)
{
return flowGroupDOMapper.deleteFlowGroupDOById(roleId);
}
/**
* 查询流程组信息树列表
*
* @return 所有流程组信息信息
*/
@Override
public List<Ztree> selectFlowGroupDOTree()
{
List<FlowGroupDO> flowGroupDOList = flowGroupDOMapper.selectFlowGroupDOList(new FlowGroupDO());
List<Ztree> ztrees = new ArrayList<Ztree>();
for (FlowGroupDO flowGroupDO : flowGroupDOList)
{
Ztree ztree = new Ztree();
ztree.setId(flowGroupDO.getRoleId());
ztree.setpId(flowGroupDO.getParentId());
ztree.setName(flowGroupDO.getRoleName());
ztree.setTitle(flowGroupDO.getRoleName());
ztrees.add(ztree);
}
return ztrees;
}
}

View File

@ -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);
}
/**
* 查询请假单列表
*

View File

@ -2,6 +2,7 @@ package com.snow.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import com.snow.common.enums.DingTalkListenerType;
import com.snow.system.domain.SysUserPost;
@ -74,6 +75,11 @@ public class SysUserServiceImpl implements ISysUserService
return userMapper.selectUserList(user);
}
@Override
public List<SysUser> selectUserListByRoleIds(List<Long> roleIds) {
return userMapper.selectUserListByRoleIds(roleIds);
}
/**
* 根据条件分页查询已分配用户角色列表
*
@ -295,7 +301,7 @@ public class SysUserServiceImpl implements ISysUserService
/**
* 新增用户角色信息
*
* @param user 用户对象
* @param userId 用户对象
*/
public void insertUserRole(Long userId, Long[] roleIds)
{

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.snow.system.mapper.FlowGroupDOMapper">
<resultMap type="FlowGroupDO" id="FlowGroupDOResult">
<result property="roleId" column="role_id" />
<result property="roleName" column="role_name" />
<result property="roleKey" column="role_key" />
<result property="roleSort" column="role_sort" />
<result property="dataScope" column="data_scope" />
<result property="status" column="status" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="parentId" column="parent_id" />
<result property="roleType" column="role_type" />
<result property="parentName" column="parent_name" />
</resultMap>
<sql id="selectFlowGroupDOVo">
select role_id, role_name, role_key, role_sort, data_scope, status, del_flag, create_by, create_time, update_by, update_time, remark, parent_id, role_type from sys_role
</sql>
<select id="selectFlowGroupDOList" parameterType="FlowGroupDO" resultMap="FlowGroupDOResult">
<include refid="selectFlowGroupDOVo"/>
<where>
<if test="roleName != null and roleName != ''"> and role_name like concat('%', #{roleName}, '%')</if>
<if test="roleKey != null and roleKey != ''"> and role_key = #{roleKey}</if>
<if test="roleSort != null "> and role_sort = #{roleSort}</if>
<if test="status != null and status != ''"> and status = #{status}</if>
<if test="roleType != null and roleType != ''"> and role_type = #{roleType}</if>
<if test="parentId != null "> and parent_id = #{parentId}</if>
</where>
order by role_sort
</select>
<select id="selectFlowGroupDOById" parameterType="Long" resultMap="FlowGroupDOResult">
select t.role_id, t.role_name, t.role_key, t.role_sort, t.data_scope, t.status, t.del_flag, t.create_by, t.create_time, t.update_by, t.update_time, t.remark, t.parent_id, t.role_type, p.role_name as parent_name
from sys_role t
left join sys_role p on p.role_id = t.parent_id
where t.role_id = #{roleId}
</select>
<insert id="insertFlowGroupDO" parameterType="FlowGroupDO" useGeneratedKeys="true" keyProperty="roleId">
insert into sys_role
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="roleName != null and roleName != ''">role_name,</if>
<if test="roleKey != null and roleKey != ''">role_key,</if>
<if test="roleSort != null">role_sort,</if>
<if test="dataScope != null">data_scope,</if>
<if test="status != null and status != ''">status,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
<if test="parentId != null">parent_id,</if>
<if test="roleType != null">role_type,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="roleName != null and roleName != ''">#{roleName},</if>
<if test="roleKey != null and roleKey != ''">#{roleKey},</if>
<if test="roleSort != null">#{roleSort},</if>
<if test="dataScope != null">#{dataScope},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
<if test="parentId != null">#{parentId},</if>
<if test="roleType != null">#{roleType},</if>
</trim>
</insert>
<update id="updateFlowGroupDO" parameterType="FlowGroupDO">
update sys_role
<trim prefix="SET" suffixOverrides=",">
<if test="roleName != null and roleName != ''">role_name = #{roleName},</if>
<if test="roleKey != null and roleKey != ''">role_key = #{roleKey},</if>
<if test="roleSort != null">role_sort = #{roleSort},</if>
<if test="dataScope != null">data_scope = #{dataScope},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="parentId != null">parent_id = #{parentId},</if>
<if test="roleType != null">role_type = #{roleType},</if>
</trim>
where role_id = #{roleId}
</update>
<delete id="deleteFlowGroupDOById" parameterType="Long">
delete from sys_role where role_id = #{roleId}
</delete>
<delete id="deleteFlowGroupDOByIds" parameterType="String">
delete from sys_role where role_id in
<foreach item="roleId" collection="array" open="(" separator="," close=")">
#{roleId}
</foreach>
</delete>
</mapper>

View File

@ -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

View File

@ -18,11 +18,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
<result property="parentId" column="parent_id" />
<result property="roleType" column="role_type"/>
</resultMap>
<sql id="selectRoleContactVo">
select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope,
r.status, r.del_flag, r.create_time, r.remark,r.parent_id
r.status, r.del_flag, r.create_time, r.remark,r.parent_id,r.role_type
from sys_role r
left join sys_user_role ur on ur.role_id = r.role_id
left join sys_user u on u.user_id = ur.user_id
@ -30,7 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</sql>
<sql id="selectRoleVo">
select r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status, r.del_flag, r.create_time, r.remark,r.parent_id
select r.role_id, r.role_name, r.role_key, r.role_sort,r.role_type, r.data_scope, r.status, r.del_flag, r.create_time, r.remark,r.parent_id
from sys_role r
</sql>
@ -43,9 +44,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">
AND r.status = #{status}
</if>
<if test="parentId != null and parentId != 0">
<if test="parentId != null and parentId != ''">
AND r.parent_id = #{parentId}
</if>
<if test="roleType != null and roleType != ''">
AND r.role_type = #{roleType}
</if>
<if test="roleKey != null and roleKey != ''">
AND r.role_key like concat('%', #{roleKey}, '%')
</if>
@ -125,6 +129,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">status,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="roleType != null and roleType != ''">
r.role_type ,
</if>
create_time
)values(
<if test="roleId != null and roleId != 0">#{roleId},</if>
@ -136,6 +143,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="status != null and status != ''">#{status},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="roleType != null and roleType != ''">
#{roleType},
</if>
sysdate()
)
</insert>

View File

@ -115,7 +115,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select distinct u.user_id, u.dept_id, u.login_name, u.user_name, u.user_type, u.email, u.avatar, u.phonenumber, u.status, u.create_time
from sys_user u
left join sys_user_role r on r.user_id = u.user_id
where u.del_flag = '0' and r.role_id = #{roleId}
where u.del_flag = '0'
and r.role_id = #{roleId}
</select>
<select id="selectUserListByRoleIds" resultMap="SysUserResult">
select distinct u.user_id, u.dept_id, u.login_name, u.user_name, u.user_type, u.email, u.avatar,
u.phonenumber, u.status, u.create_time
from sys_user u
left join sys_user_role r on r.user_id = u.user_id
where u.del_flag = '0'
<if test="roleIds!=null and roleIds.size()>0">
and r.role_id in
<foreach collection="roleIds" close=")" open="(" separator="," item="roleId">
#{roleId}
</foreach>
</if>
</select>
<select id="selectUnallocatedList" parameterType="SysUser" resultMap="SysUserResult">