Commit 1425f7dfcc9c1fa7bf767387a5b369b00bf03090
1 parent
8e18a63d
优化 ProcessViewer.vue 展示流程图的效果,增加红色、绿色、灰色、橙色
Showing
8 changed files
with
204 additions
and
70 deletions
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/controller/task/vo/activity/BpmActivityRespVO.java
| @@ -20,4 +20,20 @@ public class BpmActivityRespVO { | @@ -20,4 +20,20 @@ public class BpmActivityRespVO { | ||
| 20 | @ApiModelProperty(value = "流程活动的结束时间", required = true) | 20 | @ApiModelProperty(value = "流程活动的结束时间", required = true) |
| 21 | private Date endTime; | 21 | private Date endTime; |
| 22 | 22 | ||
| 23 | + /** | ||
| 24 | + * 关联的流程任务,只有 UserTask 类型才有 | ||
| 25 | + */ | ||
| 26 | + private Task task; | ||
| 27 | + | ||
| 28 | + @ApiModel(value = "流程任务") | ||
| 29 | + @Data | ||
| 30 | + public static class Task { | ||
| 31 | + | ||
| 32 | + @ApiModelProperty(value = "关联的流程任务的编号", required = true, example = "2048") | ||
| 33 | + private String id; | ||
| 34 | + @ApiModelProperty(value = "关联的流程任务的结果", required = true, example = "2", notes = "参见 bpm_process_instance_result 枚举") | ||
| 35 | + private Integer result; | ||
| 36 | + | ||
| 37 | + } | ||
| 38 | + | ||
| 23 | } | 39 | } |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/convert/task/BpmActivityConvert.java
| 1 | package cn.iocoder.yudao.adminserver.modules.bpm.convert.task; | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.convert.task; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO; | 3 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO; |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | ||
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 4 | import org.activiti.engine.history.HistoricActivityInstance; | 6 | import org.activiti.engine.history.HistoricActivityInstance; |
| 5 | import org.mapstruct.Mapper; | 7 | import org.mapstruct.Mapper; |
| 6 | import org.mapstruct.Mapping; | 8 | import org.mapstruct.Mapping; |
| @@ -8,6 +10,7 @@ import org.mapstruct.Mappings; | @@ -8,6 +10,7 @@ import org.mapstruct.Mappings; | ||
| 8 | import org.mapstruct.factory.Mappers; | 10 | import org.mapstruct.factory.Mappers; |
| 9 | 11 | ||
| 10 | import java.util.List; | 12 | import java.util.List; |
| 13 | +import java.util.Map; | ||
| 11 | 14 | ||
| 12 | /** | 15 | /** |
| 13 | * BPM 活动 Convert | 16 | * BPM 活动 Convert |
| @@ -19,7 +22,16 @@ public interface BpmActivityConvert { | @@ -19,7 +22,16 @@ public interface BpmActivityConvert { | ||
| 19 | 22 | ||
| 20 | BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class); | 23 | BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class); |
| 21 | 24 | ||
| 22 | - List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list); | 25 | + default List<BpmActivityRespVO> convertList(List<HistoricActivityInstance> list, Map<String, BpmTaskExtDO> taskExtMap) { |
| 26 | + return CollectionUtils.convertList(list, bean -> { | ||
| 27 | + BpmActivityRespVO respVO = convert(bean); | ||
| 28 | + BpmTaskExtDO taskExt = taskExtMap.get(bean.getTaskId()); | ||
| 29 | + if (taskExt != null) { | ||
| 30 | + respVO.setTask(new BpmActivityRespVO.Task().setId(taskExt.getTaskId()).setResult(taskExt.getResult())); | ||
| 31 | + } | ||
| 32 | + return respVO; | ||
| 33 | + }); | ||
| 34 | + } | ||
| 23 | 35 | ||
| 24 | @Mappings({ | 36 | @Mappings({ |
| 25 | @Mapping(source = "activityId", target = "key"), | 37 | @Mapping(source = "activityId", target = "key"), |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/dataobject/task/BpmTaskExtDO.java
| @@ -46,6 +46,12 @@ public class BpmTaskExtDO extends BaseDO { | @@ -46,6 +46,12 @@ public class BpmTaskExtDO extends BaseDO { | ||
| 46 | * 关联 {@link Task#getId()} | 46 | * 关联 {@link Task#getId()} |
| 47 | */ | 47 | */ |
| 48 | private String taskId; | 48 | private String taskId; |
| 49 | +// /** | ||
| 50 | +// * 任务的标识 | ||
| 51 | +// * | ||
| 52 | +// * 关联 {@link Task#getTaskDefinitionKey()} | ||
| 53 | +// */ | ||
| 54 | +// private String definitionKey; | ||
| 49 | /** | 55 | /** |
| 50 | * 任务的结果 | 56 | * 任务的结果 |
| 51 | * | 57 | * |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/dal/mysql/task/BpmTaskExtMapper.java
| @@ -19,4 +19,7 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> { | @@ -19,4 +19,7 @@ public interface BpmTaskExtMapper extends BaseMapperX<BpmTaskExtDO> { | ||
| 19 | return selectList("task_id", taskIds); | 19 | return selectList("task_id", taskIds); |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | + default List<BpmTaskExtDO> selectListByProcessInstanceId(String processInstanceId) { | ||
| 23 | + return selectList("process_instance_id", processInstanceId); | ||
| 24 | + } | ||
| 22 | } | 25 | } |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/BpmTaskService.java
| 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task; | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; | 3 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; |
| 4 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 6 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 6 | import org.activiti.engine.task.Task; | 7 | import org.activiti.engine.task.Task; |
| @@ -139,4 +140,12 @@ public interface BpmTaskService { | @@ -139,4 +140,12 @@ public interface BpmTaskService { | ||
| 139 | */ | 140 | */ |
| 140 | void updateTaskExtComplete(org.activiti.api.task.model.Task task); | 141 | void updateTaskExtComplete(org.activiti.api.task.model.Task task); |
| 141 | 142 | ||
| 143 | + /** | ||
| 144 | + * 获得流程实例对应的 Task 拓展列表 | ||
| 145 | + * | ||
| 146 | + * @param processInstanceId 流程实例的编号 | ||
| 147 | + * @return Task 拓展列表 | ||
| 148 | + */ | ||
| 149 | + List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId); | ||
| 150 | + | ||
| 142 | } | 151 | } |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmActivityServiceImpl.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.io.IoUtil; | @@ -4,6 +4,7 @@ import cn.hutool.core.io.IoUtil; | ||
| 4 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO; | 4 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.activity.BpmActivityRespVO; |
| 5 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmActivityConvert; | 5 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmActivityConvert; |
| 6 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert; | 6 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert; |
| 7 | +import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmTaskExtDO; | ||
| 7 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; | 8 | import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmProcessDefinitionService; |
| 8 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmActivityService; | 9 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmActivityService; |
| 9 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; | 10 | import cn.iocoder.yudao.adminserver.modules.bpm.service.task.BpmProcessInstanceService; |
| @@ -25,9 +26,11 @@ import javax.annotation.Resource; | @@ -25,9 +26,11 @@ import javax.annotation.Resource; | ||
| 25 | import java.io.InputStream; | 26 | import java.io.InputStream; |
| 26 | import java.util.Collections; | 27 | import java.util.Collections; |
| 27 | import java.util.List; | 28 | import java.util.List; |
| 29 | +import java.util.Map; | ||
| 28 | 30 | ||
| 29 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; | 31 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; |
| 30 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 32 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 33 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 31 | 34 | ||
| 32 | /** | 35 | /** |
| 33 | * BPM 活动实例 Service 实现类 | 36 | * BPM 活动实例 Service 实现类 |
| @@ -57,7 +60,10 @@ public class BpmActivityServiceImpl implements BpmActivityService { | @@ -57,7 +60,10 @@ public class BpmActivityServiceImpl implements BpmActivityService { | ||
| 57 | public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) { | 60 | public List<BpmActivityRespVO> getActivityListByProcessInstanceId(String processInstanceId) { |
| 58 | List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery() | 61 | List<HistoricActivityInstance> activityList = historyService.createHistoricActivityInstanceQuery() |
| 59 | .processInstanceId(processInstanceId).list(); | 62 | .processInstanceId(processInstanceId).list(); |
| 60 | - return BpmActivityConvert.INSTANCE.convertList(activityList); | 63 | + // 拼接数据 |
| 64 | + List<BpmTaskExtDO> taskExts = taskService.getTaskExtListByProcessInstanceId(processInstanceId); | ||
| 65 | + Map<String, BpmTaskExtDO> taskExtMap = convertMap(taskExts, BpmTaskExtDO::getTaskId); | ||
| 66 | + return BpmActivityConvert.INSTANCE.convertList(activityList, taskExtMap); | ||
| 61 | } | 67 | } |
| 62 | 68 | ||
| 63 | @Override | 69 | @Override |
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/bpm/service/task/impl/BpmTaskServiceImpl.java
| 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl; | 1 | package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | -import cn.hutool.core.io.IoUtil; | ||
| 5 | import cn.hutool.core.util.StrUtil; | 4 | import cn.hutool.core.util.StrUtil; |
| 6 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; | 5 | import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.task.*; |
| 7 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert; | 6 | import cn.iocoder.yudao.adminserver.modules.bpm.convert.task.BpmTaskConvert; |
| @@ -16,36 +15,23 @@ import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | @@ -16,36 +15,23 @@ import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | ||
| 16 | import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | 15 | import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; |
| 17 | import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; | 16 | import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; |
| 18 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 17 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 19 | -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 20 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | 18 | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; |
| 21 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; | 19 | import cn.iocoder.yudao.framework.common.util.object.PageUtils; |
| 22 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
| 23 | -import org.activiti.bpmn.constants.BpmnXMLConstants; | ||
| 24 | -import org.activiti.bpmn.model.BpmnModel; | ||
| 25 | -import org.activiti.bpmn.model.FlowNode; | ||
| 26 | -import org.activiti.bpmn.model.SequenceFlow; | ||
| 27 | import org.activiti.engine.HistoryService; | 21 | import org.activiti.engine.HistoryService; |
| 28 | -import org.activiti.engine.RepositoryService; | ||
| 29 | -import org.activiti.engine.RuntimeService; | ||
| 30 | import org.activiti.engine.TaskService; | 22 | import org.activiti.engine.TaskService; |
| 31 | -import org.activiti.engine.history.HistoricActivityInstance; | ||
| 32 | import org.activiti.engine.history.HistoricProcessInstance; | 23 | import org.activiti.engine.history.HistoricProcessInstance; |
| 33 | import org.activiti.engine.history.HistoricTaskInstance; | 24 | import org.activiti.engine.history.HistoricTaskInstance; |
| 34 | import org.activiti.engine.history.HistoricTaskInstanceQuery; | 25 | import org.activiti.engine.history.HistoricTaskInstanceQuery; |
| 35 | -import org.activiti.engine.repository.ProcessDefinition; | ||
| 36 | import org.activiti.engine.runtime.ProcessInstance; | 26 | import org.activiti.engine.runtime.ProcessInstance; |
| 37 | import org.activiti.engine.task.Task; | 27 | import org.activiti.engine.task.Task; |
| 38 | import org.activiti.engine.task.TaskQuery; | 28 | import org.activiti.engine.task.TaskQuery; |
| 39 | -import org.activiti.image.ProcessDiagramGenerator; | ||
| 40 | import org.springframework.context.annotation.Lazy; | 29 | import org.springframework.context.annotation.Lazy; |
| 41 | import org.springframework.stereotype.Service; | 30 | import org.springframework.stereotype.Service; |
| 42 | import org.springframework.transaction.annotation.Transactional; | 31 | import org.springframework.transaction.annotation.Transactional; |
| 43 | -import org.springframework.util.ObjectUtils; | ||
| 44 | 32 | ||
| 45 | import javax.annotation.Resource; | 33 | import javax.annotation.Resource; |
| 46 | import javax.validation.Valid; | 34 | import javax.validation.Valid; |
| 47 | -import java.io.IOException; | ||
| 48 | -import java.io.InputStream; | ||
| 49 | import java.util.*; | 35 | import java.util.*; |
| 50 | 36 | ||
| 51 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; | 37 | import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*; |
| @@ -307,4 +293,9 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -307,4 +293,9 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 307 | taskExtMapper.updateByTaskId(taskExtDO); | 293 | taskExtMapper.updateByTaskId(taskExtDO); |
| 308 | } | 294 | } |
| 309 | 295 | ||
| 296 | + @Override | ||
| 297 | + public List<BpmTaskExtDO> getTaskExtListByProcessInstanceId(String processInstanceId) { | ||
| 298 | + return taskExtMapper.selectListByProcessInstanceId(processInstanceId); | ||
| 299 | + } | ||
| 300 | + | ||
| 310 | } | 301 | } |
yudao-admin-ui/src/components/bpmnProcessDesigner/package/designer/ProcessViewer.vue
| @@ -82,55 +82,63 @@ export default { | @@ -82,55 +82,63 @@ export default { | ||
| 82 | }, | 82 | }, |
| 83 | /* 高亮流程图 */ | 83 | /* 高亮流程图 */ |
| 84 | async highlightDiagram() { | 84 | async highlightDiagram() { |
| 85 | - // let tasks = this.tasks.filter(task => { | ||
| 86 | - // if (task.type !== 'sequenceFlow') { // 去除连线元素 | ||
| 87 | - // return true; | ||
| 88 | - // } | ||
| 89 | - // }); | ||
| 90 | - let tasks = this.tasks; | ||
| 91 | - if (tasks.length === 0) { | 85 | + let activityList = this.tasks; |
| 86 | + if (activityList.length === 0) { | ||
| 92 | return; | 87 | return; |
| 93 | } | 88 | } |
| 94 | // 参考自 https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-ui/src/components/Process/index.vue#L222 实现 | 89 | // 参考自 https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-ui/src/components/Process/index.vue#L222 实现 |
| 90 | + // 再次基础上,增加不同审批结果的颜色等等 | ||
| 95 | let canvas = this.bpmnModeler.get('canvas'); | 91 | let canvas = this.bpmnModeler.get('canvas'); |
| 92 | + let todoActivity = activityList.find(m => !m.endTime) // 找到待办的任务 | ||
| 93 | + let endActivity = activityList[activityList.length - 1] // 找到结束任务 | ||
| 96 | this.bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach(n => { | 94 | this.bpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach(n => { |
| 97 | - let completeTask = tasks.find(m => m.key === n.id) | ||
| 98 | - let todoTask = tasks.find(m => !m.endTime) | ||
| 99 | - let endTask = tasks[tasks.length - 1] | 95 | + let activity = activityList.find(m => m.key === n.id) // 找到对应的活动 |
| 100 | if (n.$type === 'bpmn:UserTask') { // 用户任务 | 96 | if (n.$type === 'bpmn:UserTask') { // 用户任务 |
| 101 | - if (completeTask) { | ||
| 102 | - canvas.addMarker(n.id, completeTask.endTime ? 'highlight' : 'highlight-todo'); | ||
| 103 | - // console.log(n.id + ' : ' + (completeTask.endTime ? 'highlight' : 'highlight-todo')); | ||
| 104 | - n.outgoing?.forEach(nn => { | ||
| 105 | - let targetTask = tasks.find(m => m.key === nn.targetRef.id) | ||
| 106 | - if (targetTask) { | ||
| 107 | - canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo'); | ||
| 108 | - } else if (nn.targetRef.$type === 'bpmn:ExclusiveGateway') { | ||
| 109 | - // canvas.addMarker(nn.id, 'highlight'); | ||
| 110 | - canvas.addMarker(nn.id, completeTask.endTime ? 'highlight' : 'highlight-todo'); | ||
| 111 | - canvas.addMarker(nn.targetRef.id, completeTask.endTime ? 'highlight' : 'highlight-todo'); | ||
| 112 | - } else if (nn.targetRef.$type === 'bpmn:EndEvent') { | ||
| 113 | - if (!todoTask && endTask.key === n.id) { | ||
| 114 | - canvas.addMarker(nn.id, 'highlight'); | ||
| 115 | - canvas.addMarker(nn.targetRef.id, 'highlight'); | ||
| 116 | - } | ||
| 117 | - if (!completeTask.endTime) { | ||
| 118 | - canvas.addMarker(nn.id, 'highlight-todo'); | ||
| 119 | - canvas.addMarker(nn.targetRef.id, 'highlight-todo'); | ||
| 120 | - } | ||
| 121 | - } | ||
| 122 | - }); | 97 | + if (!activity) { |
| 98 | + return; | ||
| 123 | } | 99 | } |
| 100 | + if (activity.task) { | ||
| 101 | + const result = activity.task.result; | ||
| 102 | + if (result === 1) { | ||
| 103 | + canvas.addMarker(n.id, 'highlight-todo'); | ||
| 104 | + } else if (result === 2) { | ||
| 105 | + canvas.addMarker(n.id, 'highlight'); | ||
| 106 | + } else if (result === 3) { | ||
| 107 | + canvas.addMarker(n.id, 'highlight-reject'); | ||
| 108 | + } else if (result === 4) { | ||
| 109 | + canvas.addMarker(n.id, 'highlight-cancel'); | ||
| 110 | + } | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + n.outgoing?.forEach(nn => { | ||
| 114 | + let targetTask = activityList.find(m => m.key === nn.targetRef.id) | ||
| 115 | + if (targetTask) { | ||
| 116 | + canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo'); | ||
| 117 | + } else if (nn.targetRef.$type === 'bpmn:ExclusiveGateway') { | ||
| 118 | + // canvas.addMarker(nn.id, 'highlight'); | ||
| 119 | + canvas.addMarker(nn.id, activity.endTime ? 'highlight' : 'highlight-todo'); | ||
| 120 | + canvas.addMarker(nn.targetRef.id, activity.endTime ? 'highlight' : 'highlight-todo'); | ||
| 121 | + } else if (nn.targetRef.$type === 'bpmn:EndEvent') { | ||
| 122 | + if (!todoActivity && endActivity.key === n.id) { | ||
| 123 | + canvas.addMarker(nn.id, 'highlight'); | ||
| 124 | + canvas.addMarker(nn.targetRef.id, 'highlight'); | ||
| 125 | + } | ||
| 126 | + if (!activity.endTime) { | ||
| 127 | + canvas.addMarker(nn.id, 'highlight-todo'); | ||
| 128 | + canvas.addMarker(nn.targetRef.id, 'highlight-todo'); | ||
| 129 | + } | ||
| 130 | + } | ||
| 131 | + }); | ||
| 124 | } else if (n.$type === 'bpmn:ExclusiveGateway') { // 排它网关 | 132 | } else if (n.$type === 'bpmn:ExclusiveGateway') { // 排它网关 |
| 125 | n.outgoing?.forEach(nn => { | 133 | n.outgoing?.forEach(nn => { |
| 126 | - let targetTask = tasks.find(m => m.key === nn.targetRef.id) | 134 | + let targetTask = activityList.find(m => m.key === nn.targetRef.id) |
| 127 | if (targetTask) { | 135 | if (targetTask) { |
| 128 | canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo'); | 136 | canvas.addMarker(nn.id, targetTask.endTime ? 'highlight' : 'highlight-todo'); |
| 129 | } | 137 | } |
| 130 | }) | 138 | }) |
| 131 | } else if (n.$type === 'bpmn:ParallelGateway') { // 并行网关 | 139 | } else if (n.$type === 'bpmn:ParallelGateway') { // 并行网关 |
| 132 | - if (completeTask) { | ||
| 133 | - canvas.addMarker(n.id, completeTask.endTime ? 'highlight' : 'highlight-todo') | 140 | + if (activity) { |
| 141 | + canvas.addMarker(n.id, activity.endTime ? 'highlight' : 'highlight-todo') | ||
| 134 | n.outgoing?.forEach(nn => { | 142 | n.outgoing?.forEach(nn => { |
| 135 | const targetTask = this.taskList.find(m => m.key === nn.targetRef.id) | 143 | const targetTask = this.taskList.find(m => m.key === nn.targetRef.id) |
| 136 | if (targetTask) { | 144 | if (targetTask) { |
| @@ -140,18 +148,21 @@ export default { | @@ -140,18 +148,21 @@ export default { | ||
| 140 | }) | 148 | }) |
| 141 | } | 149 | } |
| 142 | } else if (n.$type === 'bpmn:StartEvent') { // 开始节点 | 150 | } else if (n.$type === 'bpmn:StartEvent') { // 开始节点 |
| 143 | - n.outgoing?.forEach(nn => { | ||
| 144 | - let completeTask = tasks.find(m => m.key === nn.targetRef.id) | ||
| 145 | - if (completeTask) { | 151 | + n.outgoing?.forEach(nn => { // outgoing 例如说【bpmn:SequenceFlow】连线 |
| 152 | + let fromTask = activityList.find(m => m.key === nn.targetRef.id) | ||
| 153 | + if (fromTask) { | ||
| 146 | canvas.addMarker(nn.id, 'highlight'); | 154 | canvas.addMarker(nn.id, 'highlight'); |
| 147 | canvas.addMarker(n.id, 'highlight'); | 155 | canvas.addMarker(n.id, 'highlight'); |
| 148 | - return | ||
| 149 | } | 156 | } |
| 150 | }); | 157 | }); |
| 151 | } else if (n.$type === 'bpmn:EndEvent') { // 结束节点 | 158 | } else if (n.$type === 'bpmn:EndEvent') { // 结束节点 |
| 152 | - if (endTask.key === n.id && endTask.endTime) { | ||
| 153 | - canvas.addMarker(n.id, 'highlight') | ||
| 154 | - return | 159 | + if (endActivity.key !== n.id) { // 保证 endActivity 就是 EndEvent |
| 160 | + return; | ||
| 161 | + } | ||
| 162 | + // 在并行网关后,跟着多个任务,如果其中一个任务完成,endActivity 的 endTime 就会存在值 | ||
| 163 | + // 所以,通过 todoActivity 在做一次判断 | ||
| 164 | + if (endActivity.endTime && !todoActivity) { | ||
| 165 | + canvas.addMarker(n.id, 'highlight'); | ||
| 155 | } | 166 | } |
| 156 | } | 167 | } |
| 157 | }) | 168 | }) |
| @@ -162,6 +173,7 @@ export default { | @@ -162,6 +173,7 @@ export default { | ||
| 162 | 173 | ||
| 163 | <style> | 174 | <style> |
| 164 | 175 | ||
| 176 | +/** 通过 */ | ||
| 165 | .highlight.djs-shape .djs-visual > :nth-child(1) { | 177 | .highlight.djs-shape .djs-visual > :nth-child(1) { |
| 166 | fill: green !important; | 178 | fill: green !important; |
| 167 | stroke: green !important; | 179 | stroke: green !important; |
| @@ -179,18 +191,6 @@ export default { | @@ -179,18 +191,6 @@ export default { | ||
| 179 | stroke: green !important; | 191 | stroke: green !important; |
| 180 | } | 192 | } |
| 181 | 193 | ||
| 182 | -.highlight-todo.djs-connection > .djs-visual > path { | ||
| 183 | - stroke: orange !important; | ||
| 184 | - stroke-dasharray: 4px !important; | ||
| 185 | - fill-opacity: 0.2 !important; | ||
| 186 | -} | ||
| 187 | -.highlight-todo.djs-shape .djs-visual > :nth-child(1) { | ||
| 188 | - fill: orange !important; | ||
| 189 | - stroke: orange !important; | ||
| 190 | - stroke-dasharray: 4px !important; | ||
| 191 | - fill-opacity: 0.2 !important; | ||
| 192 | -} | ||
| 193 | - | ||
| 194 | .highlight:not(.djs-connection) .djs-visual > :nth-child(1) { | 194 | .highlight:not(.djs-connection) .djs-visual > :nth-child(1) { |
| 195 | fill: green !important; /* color elements as green */ | 195 | fill: green !important; /* color elements as green */ |
| 196 | } | 196 | } |
| @@ -211,6 +211,20 @@ export default { | @@ -211,6 +211,20 @@ export default { | ||
| 211 | /deep/.highlight.djs-connection > .djs-visual > path { | 211 | /deep/.highlight.djs-connection > .djs-visual > path { |
| 212 | stroke: green !important; | 212 | stroke: green !important; |
| 213 | } | 213 | } |
| 214 | + | ||
| 215 | +/** 处理中 */ | ||
| 216 | +.highlight-todo.djs-connection > .djs-visual > path { | ||
| 217 | + stroke: orange !important; | ||
| 218 | + stroke-dasharray: 4px !important; | ||
| 219 | + fill-opacity: 0.2 !important; | ||
| 220 | +} | ||
| 221 | +.highlight-todo.djs-shape .djs-visual > :nth-child(1) { | ||
| 222 | + fill: orange !important; | ||
| 223 | + stroke: orange !important; | ||
| 224 | + stroke-dasharray: 4px !important; | ||
| 225 | + fill-opacity: 0.2 !important; | ||
| 226 | +} | ||
| 227 | + | ||
| 214 | /deep/.highlight-todo.djs-connection > .djs-visual > path { | 228 | /deep/.highlight-todo.djs-connection > .djs-visual > path { |
| 215 | stroke: orange !important; | 229 | stroke: orange !important; |
| 216 | stroke-dasharray: 4px !important; | 230 | stroke-dasharray: 4px !important; |
| @@ -224,4 +238,81 @@ export default { | @@ -224,4 +238,81 @@ export default { | ||
| 224 | fill-opacity: 0.2 !important; | 238 | fill-opacity: 0.2 !important; |
| 225 | } | 239 | } |
| 226 | 240 | ||
| 241 | +/** 不通过 */ | ||
| 242 | +.highlight-reject.djs-shape .djs-visual > :nth-child(1) { | ||
| 243 | + fill: red !important; | ||
| 244 | + stroke: red !important; | ||
| 245 | + fill-opacity: 0.2 !important; | ||
| 246 | +} | ||
| 247 | +.highlight-reject.djs-shape .djs-visual > :nth-child(2) { | ||
| 248 | + fill: red !important; | ||
| 249 | +} | ||
| 250 | +.highlight-reject.djs-shape .djs-visual > path { | ||
| 251 | + fill: red !important; | ||
| 252 | + fill-opacity: 0.2 !important; | ||
| 253 | + stroke: red !important; | ||
| 254 | +} | ||
| 255 | +.highlight-reject.djs-connection > .djs-visual > path { | ||
| 256 | + stroke: red !important; | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +.highlight-reject:not(.djs-connection) .djs-visual > :nth-child(1) { | ||
| 260 | + fill: red !important; /* color elements as green */ | ||
| 261 | +} | ||
| 262 | + | ||
| 263 | +/deep/.highlight-reject.djs-shape .djs-visual > :nth-child(1) { | ||
| 264 | + fill: red !important; | ||
| 265 | + stroke: red !important; | ||
| 266 | + fill-opacity: 0.2 !important; | ||
| 267 | +} | ||
| 268 | +/deep/.highlight-reject.djs-shape .djs-visual > :nth-child(2) { | ||
| 269 | + fill: red !important; | ||
| 270 | +} | ||
| 271 | +/deep/.highlight-reject.djs-shape .djs-visual > path { | ||
| 272 | + fill: red !important; | ||
| 273 | + fill-opacity: 0.2 !important; | ||
| 274 | + stroke: red !important; | ||
| 275 | +} | ||
| 276 | +/deep/.highlight-reject.djs-connection > .djs-visual > path { | ||
| 277 | + stroke: red !important; | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +/** 已取消 */ | ||
| 281 | +.highlight-cancel.djs-shape .djs-visual > :nth-child(1) { | ||
| 282 | + fill: grey !important; | ||
| 283 | + stroke: grey !important; | ||
| 284 | + fill-opacity: 0.2 !important; | ||
| 285 | +} | ||
| 286 | +.highlight-cancel.djs-shape .djs-visual > :nth-child(2) { | ||
| 287 | + fill: grey !important; | ||
| 288 | +} | ||
| 289 | +.highlight-cancel.djs-shape .djs-visual > path { | ||
| 290 | + fill: grey !important; | ||
| 291 | + fill-opacity: 0.2 !important; | ||
| 292 | + stroke: grey !important; | ||
| 293 | +} | ||
| 294 | +.highlight-cancel.djs-connection > .djs-visual > path { | ||
| 295 | + stroke: grey !important; | ||
| 296 | +} | ||
| 297 | + | ||
| 298 | +.highlight-cancel:not(.djs-connection) .djs-visual > :nth-child(1) { | ||
| 299 | + fill: grey !important; /* color elements as green */ | ||
| 300 | +} | ||
| 301 | + | ||
| 302 | +/deep/.highlight-cancel.djs-shape .djs-visual > :nth-child(1) { | ||
| 303 | + fill: grey !important; | ||
| 304 | + stroke: grey !important; | ||
| 305 | + fill-opacity: 0.2 !important; | ||
| 306 | +} | ||
| 307 | +/deep/.highlight-cancel.djs-shape .djs-visual > :nth-child(2) { | ||
| 308 | + fill: grey !important; | ||
| 309 | +} | ||
| 310 | +/deep/.highlight-cancel.djs-shape .djs-visual > path { | ||
| 311 | + fill: grey !important; | ||
| 312 | + fill-opacity: 0.2 !important; | ||
| 313 | + stroke: grey !important; | ||
| 314 | +} | ||
| 315 | +/deep/.highlight-cancel.djs-connection > .djs-visual > path { | ||
| 316 | + stroke: grey !important; | ||
| 317 | +} | ||
| 227 | </style> | 318 | </style> |