mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-29 18:51:53 +08:00
修改流程图的高亮实现,采用 activity 替代 task 作为数据源
This commit is contained in:
parent
676e4f29d9
commit
8e18a63d34
@ -1,7 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmActivityService;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@ -15,6 +17,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Api(tags = "流程活动实例")
|
||||
@RestController
|
||||
@ -25,11 +30,20 @@ public class BpmActivityController {
|
||||
@Resource
|
||||
private BpmActivityService activityService;
|
||||
|
||||
// TODO 芋艿:注解、权限、validtion
|
||||
// TODO 芋艿:权限
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation(value = "生成指定流程实例的高亮流程图",
|
||||
notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")
|
||||
@ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
|
||||
public CommonResult<List<BpmActivityRespVO>> getActivityList(
|
||||
@RequestParam("processInstanceId") String processInstanceId) {
|
||||
return success(activityService.getActivityListByProcessInstanceId(processInstanceId));
|
||||
}
|
||||
|
||||
@GetMapping("/generate-highlight-diagram")
|
||||
@ApiOperation(value = "生成指定流程实例的高亮流程图",
|
||||
notes = "只高亮进行中的任务。不过要注意,该接口暂时没用,通过前端的 ProcessViewer.vue 界面的 highlightDiagram 方法生成")
|
||||
@ApiImplicitParam(name = "id", value = "流程实例的编号", required = true, dataTypeClass = String.class)
|
||||
public void generateHighlightDiagram(@RequestParam("processInstanceId") String processInstanceId,
|
||||
HttpServletResponse response) throws IOException {
|
||||
|
@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel("流程活动的 Response VO")
|
||||
@Data
|
||||
public class BpmActivityRespVO {
|
||||
|
||||
@ApiModelProperty(value = "流程活动的标识", required = true, example = "1024")
|
||||
private String key;
|
||||
@ApiModelProperty(value = "流程活动的类型", required = true, example = "StartEvent")
|
||||
private String type;
|
||||
|
||||
@ApiModelProperty(value = "流程活动的开始时间", required = true)
|
||||
private Date startTime;
|
||||
@ApiModelProperty(value = "流程活动的结束时间", required = true)
|
||||
private Date endTime;
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.convert.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
import org.activiti.engine.history.HistoricActivityInstance;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 活动 Convert
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface BpmActivityConvert {
|
||||
|
||||
BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);
|
||||
|
||||
List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "activityId", target = "key"),
|
||||
@Mapping(source = "activityType", target = "type")
|
||||
})
|
||||
BpmActivityRespVO convert(HistoricActivityInstance bean);
|
||||
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 活动实例 Service 接口
|
||||
*
|
||||
@ -7,6 +11,14 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
|
||||
*/
|
||||
public interface BpmActivityService {
|
||||
|
||||
/**
|
||||
* 获得指定流程实例的活动实例列表
|
||||
*
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return 活动实例列表
|
||||
*/
|
||||
List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId);
|
||||
|
||||
/**
|
||||
* 生成指定流程实例的高亮流程图,只高亮进行中的任务
|
||||
*
|
||||
@ -17,7 +29,7 @@ public interface BpmActivityService {
|
||||
*
|
||||
* 如果你想实现高亮已完成的任务,可参考 https://blog.csdn.net/qiuxinfa123/article/details/119579863 博客。不过测试下来,貌似不太对~
|
||||
*
|
||||
* @param processInstanceId 实例Id
|
||||
* @param processInstanceId 流程实例的编号
|
||||
* @return 图的字节数组
|
||||
*/
|
||||
byte[] generateHighlightDiagram(String processInstanceId);
|
||||
|
@ -1,6 +1,9 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmActivityConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmActivityService;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService;
|
||||
@ -11,6 +14,7 @@ import org.activiti.bpmn.model.BpmnModel;
|
||||
import org.activiti.engine.HistoryService;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.RuntimeService;
|
||||
import org.activiti.engine.history.HistoricActivityInstance;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.activiti.image.ProcessDiagramGenerator;
|
||||
@ -22,8 +26,7 @@ import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_BPMN_MODEL_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
|
||||
/**
|
||||
@ -40,6 +43,8 @@ public class BpmActivityServiceImpl implements BpmActivityService {
|
||||
|
||||
@Resource
|
||||
private ProcessDiagramGenerator processDiagramGenerator;
|
||||
@Resource
|
||||
private HistoryService historyService;
|
||||
|
||||
@Resource
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
@ -48,6 +53,13 @@ public class BpmActivityServiceImpl implements BpmActivityService {
|
||||
@Resource
|
||||
private BpmTaskService taskService;
|
||||
|
||||
@Override
|
||||
public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) {
|
||||
List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery()
|
||||
.processInstanceId(processInstanceId).list();
|
||||
return BpmActivityConvert.INSTANCE.convertList(activityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] generateHighlightDiagram(String processInstanceId) {
|
||||
// 获得流程实例
|
||||
|
9
yudao-admin-ui/src/api/bpm/activity.js
Normal file
9
yudao-admin-ui/src/api/bpm/activity.js
Normal file
@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getActivityList(query) {
|
||||
return request({
|
||||
url: '/bpm/activity/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
@ -82,24 +82,27 @@ export default {
|
||||
},
|
||||
/* 高亮流程图 */
|
||||
async highlightDiagram() {
|
||||
if (this.tasks.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!this.bpmnModeler.getDefinitions().rootElements[0].flowElements) {
|
||||
// let tasks = this.tasks.filter(task => {
|
||||
// if (task.type !== 'sequenceFlow') { // 去除连线元素
|
||||
// return true;
|
||||
// }
|
||||
// });
|
||||
let tasks = this.tasks;
|
||||
if (tasks.length === 0) {
|
||||
return;
|
||||
}
|
||||
// 参考自 https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-ui/src/components/Process/index.vue#L222 实现
|
||||
let canvas = this.bpmnModeler.get('canvas');
|
||||
this.bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach(n => {
|
||||
let completeTask = this.tasks.find(m => m.definitionKey === n.id)
|
||||
let todoTask = this.tasks.find(m => !m.endTime)
|
||||
let endTask = this.tasks[this.tasks.length - 1]
|
||||
let completeTask = tasks.find(m => m.key === n.id)
|
||||
let todoTask = tasks.find(m => !m.endTime)
|
||||
let endTask = tasks[tasks.length - 1]
|
||||
if (n.$type === 'bpmn:UserTask') { // 用户任务
|
||||
if (completeTask) {
|
||||
canvas.addMarker(n.id, completeTask.endTime ? 'highlight' : 'highlight-todo');
|
||||
// console.log(n.id + ' : ' + (completeTask.endTime ? 'highlight' : 'highlight-todo'));
|
||||
n.outgoing?.forEach(nn => {
|
||||
let targetTask = this.tasks.find(m => m.definitionKey === nn.targetRef.id)
|
||||
let targetTask = tasks.find(m => m.key === nn.targetRef.id)
|
||||
if (targetTask) {
|
||||
canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo');
|
||||
} else if (nn.targetRef.$type === 'bpmn:ExclusiveGateway') {
|
||||
@ -107,7 +110,7 @@ export default {
|
||||
canvas.addMarker(nn.id, completeTask.endTime ? 'highlight' : 'highlight-todo');
|
||||
canvas.addMarker(nn.targetRef.id, completeTask.endTime ? 'highlight' : 'highlight-todo');
|
||||
} else if (nn.targetRef.$type === 'bpmn:EndEvent') {
|
||||
if (!todoTask && endTask.definitionKey === n.id) {
|
||||
if (!todoTask && endTask.key === n.id) {
|
||||
canvas.addMarker(nn.id, 'highlight');
|
||||
canvas.addMarker(nn.targetRef.id, 'highlight');
|
||||
}
|
||||
@ -120,7 +123,7 @@ export default {
|
||||
}
|
||||
} else if (n.$type === 'bpmn:ExclusiveGateway') { // 排它网关
|
||||
n.outgoing?.forEach(nn => {
|
||||
let targetTask = this.tasks.find(m => m.definitionKey === nn.targetRef.id)
|
||||
let targetTask = tasks.find(m => m.key === nn.targetRef.id)
|
||||
if (targetTask) {
|
||||
canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo');
|
||||
}
|
||||
@ -129,7 +132,7 @@ export default {
|
||||
if (completeTask) {
|
||||
canvas.addMarker(n.id, completeTask.endTime ? 'highlight' : 'highlight-todo')
|
||||
n.outgoing?.forEach(nn => {
|
||||
const targetTask = this.taskList.find(m => m.definitionKey === nn.targetRef.id)
|
||||
const targetTask = this.taskList.find(m => m.key === nn.targetRef.id)
|
||||
if (targetTask) {
|
||||
canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo')
|
||||
canvas.addMarker(nn.targetRef.id, targetTask.endTime ? 'highlight' : 'highlight-todo')
|
||||
@ -138,7 +141,7 @@ export default {
|
||||
}
|
||||
} else if (n.$type === 'bpmn:StartEvent') { // 开始节点
|
||||
n.outgoing?.forEach(nn => {
|
||||
let completeTask = this.tasks.find(m => m.definitionKey === nn.targetRef.id)
|
||||
let completeTask = tasks.find(m => m.key === nn.targetRef.id)
|
||||
if (completeTask) {
|
||||
canvas.addMarker(nn.id, 'highlight');
|
||||
canvas.addMarker(n.id, 'highlight');
|
||||
@ -146,7 +149,7 @@ export default {
|
||||
}
|
||||
});
|
||||
} else if (n.$type === 'bpmn:EndEvent') { // 结束节点
|
||||
if (endTask.definitionKey === n.id && endTask.endTime) {
|
||||
if (endTask.key === n.id && endTask.endTime) {
|
||||
canvas.addMarker(n.id, 'highlight')
|
||||
return
|
||||
}
|
||||
|
@ -73,7 +73,7 @@
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="el-icon-picture-outline">流程图</span>
|
||||
</div>
|
||||
<my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" :taskData="tasks" />
|
||||
<my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" :taskData="activityList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 对话框(转派审批人) -->
|
||||
@ -103,6 +103,7 @@ import {createProcessInstance, getProcessInstance} from "@/api/bpm/processInstan
|
||||
import {approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee} from "@/api/bpm/task";
|
||||
import {getDate} from "@/utils/dateUtils";
|
||||
import {listSimpleUsers} from "@/api/system/user";
|
||||
import {getActivityList} from "@/api/bpm/activity";
|
||||
|
||||
// 流程实例的详情页,可用于审批
|
||||
export default {
|
||||
@ -128,6 +129,7 @@ export default {
|
||||
bpmnControlForm: {
|
||||
prefix: "activiti"
|
||||
},
|
||||
activityList: [],
|
||||
|
||||
// 审批记录
|
||||
tasksLoad: true,
|
||||
@ -196,12 +198,18 @@ export default {
|
||||
if (val) {
|
||||
item.__config__.defaultValue = val
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 加载流程图
|
||||
getProcessDefinitionBpmnXML(this.processInstance.processDefinition.id).then(response => {
|
||||
this.bpmnXML = response.data
|
||||
})
|
||||
});
|
||||
// 加载活动列表
|
||||
getActivityList({
|
||||
processInstanceId: this.processInstance.id
|
||||
}).then(response => {
|
||||
this.activityList = response.data;
|
||||
});
|
||||
|
||||
// 取消加载中
|
||||
this.processInstanceLoading = false;
|
||||
|
Loading…
Reference in New Issue
Block a user