完善OA流程列表功能

This commit is contained in:
wanggeng 2022-04-21 12:03:21 +08:00
parent ac362230d5
commit 82e1d3cad2
9 changed files with 138 additions and 188 deletions

View File

@ -1,40 +0,0 @@
package ink.wgink.module.activiti.controller.api;
import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.activiti.service.activiti.IActivitiUserTaskService;
import ink.wgink.pojo.result.SuccessResult;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
;
/**
* When you feel like quitting. Think about why you started
* 当你想要放弃的时候想想当初你为何开始
*
* @ClassName: ActivitiUserTaskController
* @Description: 流程用户任务
* @Author: WangGeng
* @Date: 2021/7/12 21:56
* @Version: 1.0
**/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "流程用户任务接口")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/activiti/user-task")
public class ActivitiUserTaskController extends DefaultBaseController {
@Autowired
private IActivitiUserTaskService activitiUserTaskService;
@GetMapping("get-next-user-task/{userTaskId}")
public SuccessResult getNextUserTask(@PathVariable("userTaskId") String userTaskId) {
activitiUserTaskService.getNextUserTask(userTaskId);
return new SuccessResult();
}
}

View File

@ -37,4 +37,10 @@ public class OaRouteController extends DefaultBaseController {
return mv;
}
@GetMapping("list-log")
public ModelAndView listLog() {
ModelAndView mv = new ModelAndView("oa/list-log");
return mv;
}
}

View File

@ -1,14 +0,0 @@
package ink.wgink.module.activiti.service.activiti;
/**
* @ClassName: IActivitiUserTaskService
* @Description: 流程用户任务
* @Author: wanggeng
* @Date: 2022/3/29 17:43
* @Version: 1.0
*/
public interface IActivitiUserTaskService {
void getNextUserTask(String userTaskId);
}

View File

@ -1,115 +0,0 @@
package ink.wgink.module.activiti.service.activiti.impl;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.module.activiti.service.activiti.IActivitiUserTaskService;
import org.activiti.bpmn.model.*;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName: ActivitiUserTaskServiceImpl
* @Description: 流程用户任务
* @Author: wanggeng
* @Date: 2022/3/29 17:44
* @Version: 1.0
*/
@Service
public class ActivitiUserTaskServiceImpl extends DefaultBaseService implements IActivitiUserTaskService {
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private RepositoryService repositoryService;
@Override
public void getNextUserTask(String userTaskId) {
Task task = taskService.createTaskQuery().taskId(userTaskId).singleResult();
String taskDefinitionKey = task.getTaskDefinitionKey();
String processInstanceId = task.getProcessInstanceId();
String processDefinitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(taskDefinitionKey);
// 流入线
List<SequenceFlow> incomingFlows = flowNode.getIncomingFlows();
// 流出线
List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
HashMap<String, Object> vars = new HashMap<>();
vars.put("message", "");
for (SequenceFlow outgoingFlow : outgoingFlows) {
//获取输出节点元素
FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
//排除非用户任务接点
if (targetFlowElement instanceof UserTask) {
LOG.debug("UserTask");
UserTask userTask = (UserTask) targetFlowElement;
System.out.println(userTask);
//判断输出节点的el表达式
// if (isCondition(outgoingFlow.getConditionExpression(), vars)) {
// //true 获取输出节点名称
// // nameList.add(outgoingFlow.getTargetFlowElement().getName());
// }
} else if (targetFlowElement instanceof ExclusiveGateway) {
LOG.debug("排他网关");
} else if (targetFlowElement instanceof ParallelGateway) {
LOG.debug("并行网关");
}
}
System.out.println(flowNode);
}
/**
* el表达式判断
*
* @param expression
* @param vars
* @return
*/
private static boolean isCondition(String expression, Map<String, Object> vars) {
if (expression == null || expression == "") {
return false;
}
//分割表达式
String[] exprArr = expression.split("[{}$&]");
for (String expr : exprArr) {
//是否包含键message
if (expr.contains("message")) {
if (!vars.containsKey("message")) {
continue;
}
if (expr.contains("==")) {
String[] primes = expr.split("==");
String valExpr = primes[1].trim();
if (valExpr.startsWith("'")) {
valExpr = valExpr.substring(1);
}
if (valExpr.endsWith("'")) {
valExpr = valExpr.substring(0, valExpr.length() - 1);
}
if (primes.length == 2 && valExpr.equals(vars.get("message"))) {
return true;
}
}
}
}
return false;
}
}

View File

@ -80,17 +80,7 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
List<ConfirmAssigneeVO> confirmAssigneeVOs = listConfirmAssignee(deploymentId, firstUserTask);
model.put("confirmAssignees", JSON.toJSONString(confirmAssigneeVOs));
LOG.debug("查询节点字段信息");
List<NodeFieldDTO> nodeFieldDTOs = nodeFieldService.listByDeploymentIdAndNodeId(deploymentId, firstUserTask.getId());
List<FieldVO> fieldVOs = nodeFieldDTOs.stream().map(nodeFieldDTO -> {
FieldVO fieldVO = new FieldVO();
fieldVO.setFieldName(nodeFieldDTO.getFieldName());
fieldVO.setIsEditable(nodeFieldDTO.getIsEditable());
fieldVO.setIsVisible(nodeFieldDTO.getIsVisible());
return fieldVO;
}).collect(Collectors.toList());
model.put("fields", JSONObject.toJSONString(fieldVOs));
setPageFields(deploymentId, firstUserTask, model);
formReportRouteService.save(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
@ -117,6 +107,7 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
List<ConfirmAssigneeVO> confirmAssigneeVOs = listConfirmAssignee(deploymentId, currentUserTask);
model.put("confirmAssignees", JSON.toJSONString(confirmAssigneeVOs));
setPageFields(deploymentId, currentUserTask, model);
// 设置代理人
formReportRouteService.update(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
@ -148,6 +139,25 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
formReportRouteService.appShow(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
/**
* 设置页面字段
*
* @param deploymentId
* @param userTask
* @param model
*/
private void setPageFields(String deploymentId, UserTask userTask, Map<String, Object> model) {
LOG.debug("查询节点字段信息");
List<NodeFieldDTO> nodeFieldDTOs = nodeFieldService.listByDeploymentIdAndNodeId(deploymentId, userTask.getId());
List<FieldVO> fieldVOs = nodeFieldDTOs.stream().map(nodeFieldDTO -> {
FieldVO fieldVO = new FieldVO();
fieldVO.setFieldName(nodeFieldDTO.getFieldName());
fieldVO.setIsEditable(nodeFieldDTO.getIsEditable());
fieldVO.setIsVisible(nodeFieldDTO.getIsVisible());
return fieldVO;
}).collect(Collectors.toList());
model.put("fields", JSONObject.toJSONString(fieldVOs));
}
/**
* 确认代理人列表
@ -245,7 +255,7 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
for (int i = 0; i < userTasks.size(); i++) {
UserTask userTask = userTasks.get(i);
boolean isExist = false;
for (int j = 1; j < userTasks.size(); j++) {
for (int j = i + 1; j < userTasks.size(); j++) {
if (StringUtils.equals(userTask.getId(), userTasks.get(j).getId())) {
isExist = true;
userTasks.remove(i);

View File

@ -65,7 +65,7 @@ public class OaServiceImpl extends DefaultBaseService implements IOaService {
@Override
public SuccessResultList<List<OaProcdefDTO>> listPageProcdef(int page, int rows) {
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> processDefinitions = processDefinitionQuery.listPage(page - 1, rows);
List<ProcessDefinition> processDefinitions = processDefinitionQuery.latestVersion().listPage(page - 1, rows);
List<OaProcdefDTO> oaProcdefDTOs = listOaProcdef(processDefinitions);
return new SuccessResultList<>(oaProcdefDTOs, page, processDefinitionQuery.count());
}
@ -89,6 +89,7 @@ public class OaServiceImpl extends DefaultBaseService implements IOaService {
oaProcdefDTO.setDeploymentId(processDefinition.getDeploymentId());
oaProcdefDTO.setName(processDefinition.getName());
oaProcdefDTO.setProcessDefinitionId(processDefinition.getId());
oaProcdefDTO.setVersion(processDefinition.getVersion());
oaProcdefDTO.setFormKey(formKey);
oaProcdefDTOs.add(oaProcdefDTO);
if (StringUtils.isBlank(formKey)) {

View File

@ -75,11 +75,10 @@
return rowData;
}
},
{field: 'form', width: 150, title: '操作', align:'center', fixed: 'right',
{field: 'form', width: 100, title: '操作', align:'center', fixed: 'right',
templet: function(row) {
return '<div class="layui-btn-group">' +
'<button class="layui-btn layui-btn-xs" lay-event="logEvent">流转日志</button>'+
'<button class="layui-btn layui-btn-xs" lay-event="logImageEvent">流转图</button>'+
'</div>';
}
}
@ -126,9 +125,9 @@
var layEvent = obj.event;
if(layEvent === 'logEvent') {
top.dialog.open({
url: top.restAjax.path('route/oa-form-report/update/task-id/{taskId}/code/{formCode}/version/{formVersion}/is-need-claim/{isNeedClaim}?uid={reportUid}', [data.taskId, data.formCode, data.formVersion, data.isNeedClaim, data.reportUid]),
title: '编辑',
width: '500px',
url: top.restAjax.path('route/oa/list-log?processInstanceId={processInstanceId}', [data.processInstanceId]),
title: '流转日志',
width: '800px',
height: '80%',
onClose: function() {}
});

View File

@ -0,0 +1,101 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<base th:href="${#request.getContextPath() + '/'}">
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="stylesheet" href="assets/fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" href="assets/layuiadmin/layui/css/layui.css" media="all">
<link rel="stylesheet" href="assets/layuiadmin/style/admin.css" media="all">
<link rel="stylesheet" type="text/css" href="assets/js/vendor/viewer/viewer.min.css">
</head>
<body>
<div class="layui-anim layui-anim-fadein">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">流转日志</li>
<li>流转图</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<ul class="layui-timeline">
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
<div class="layui-timeline-content layui-text">
<h3 class="layui-timeline-title">8月18日</h3>
<p>
layui 2.0 的一切准备工作似乎都已到位。发布之弦,一触即发。
<br>不枉近百个日日夜夜与之为伴。因小而大,因弱而强。
<br>无论它能走多远,抑或如何支撑?至少我曾倾注全心,无怨无悔 <i class="layui-icon"></i>
</p>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
<div class="layui-timeline-content layui-text">
<h3 class="layui-timeline-title">8月16日</h3>
<p>杜甫的思想核心是儒家的仁政思想,他有“<em>致君尧舜上,再使风俗淳</em>”的宏伟抱负。个人最爱的名篇有:</p>
<ul>
<li>《登高》</li>
<li>《茅屋为秋风所破歌》</li>
</ul>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
<div class="layui-timeline-content layui-text">
<h3 class="layui-timeline-title">8月15日</h3>
<p>
中国人民抗日战争胜利72周年
<br>常常在想,尽管对这个国家有这样那样的抱怨,但我们的确生在了最好的时代
<br>铭记、感恩
<br>所有为中华民族浴血奋战的英雄将士
<br>永垂不朽
</p>
</div>
</li>
<li class="layui-timeline-item">
<i class="layui-icon layui-timeline-axis">&#xe63f;</i>
<div class="layui-timeline-content layui-text">
<div class="layui-timeline-title">过去</div>
</div>
</li>
</ul>
</div>
<div class="layui-tab-item">
<div>
<img id="runtimeProcessImage" alt="流转图" style="width: 100%"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="assets/js/vendor/viewer/viewer.min.js"></script>
<script src="assets/layuiadmin/layui/layui.js"></script>
<script>
layui.config({
base: 'assets/layuiadmin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'laydate'], function(){
var $ = layui.$;
var win = $(window)
var params = top.restAjax.params(window.location.href);
var processInstanceId = params.processInstanceId;
function init() {
$('#runtimeProcessImage').attr('src', 'route/activiti/model/get-runtime-process-image/'+ processInstanceId);
new Viewer(document.getElementById('runtimeProcessImage'));
}
init();
});
</script>
</body>
</html>

View File

@ -132,7 +132,9 @@
title: '编辑',
width: '500px',
height: '80%',
onClose: function() {}
onClose: function() {
reloadTable();
}
});
}
});