From f60a4dfa6b241c0526abaf1c38770666d4572425 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 25 Jan 2025 10:24:34 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0Task=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E7=90=86=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java | 1 + .../module/bpm/service/definition/BpmModelServiceImpl.java | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java index 5ea8c41871..d41c0c3133 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmReasonEnum.java @@ -32,6 +32,7 @@ public enum BpmReasonEnum { ASSIGN_EMPTY_REJECT("审批人为空,自动不通过"), APPROVE_TYPE_AUTO_APPROVE("非人工审核,自动通过"), APPROVE_TYPE_AUTO_REJECT("非人工审核,自动不通过"), + CANCEL_BY_PROCESS_CLEAN("进程清理自动取消"), ; private final String reason; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java index 603ddd7ca4..23bff80df7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java @@ -288,8 +288,7 @@ public class BpmModelServiceImpl implements BpmModelService { // 2.3 清理所有 Task List tasks = taskService.createTaskQuery() .processDefinitionKey(model.getKey()).list(); - // TODO @lesan:貌似传递一个 reason 会好点! - tasks.forEach(task -> taskService.deleteTask(task.getId())); + tasks.forEach(task -> taskService.deleteTask(task.getId(),BpmReasonEnum.CANCEL_BY_PROCESS_CLEAN.getReason())); } @Override From 0ef8467546ed18c60d13833fc431dd55e3e7ceda Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 25 Jan 2025 10:26:41 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=91=98=E8=A6=81=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E4=BB=A3=E7=A0=81=E8=AF=84=E5=AE=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/task/vo/task/BpmTaskRespVO.java | 7 +- .../bpm/convert/task/BpmTaskConvert.java | 4 +- .../flowable/core/util/FlowableUtils.java | 85 ++++++++----------- 3 files changed, 41 insertions(+), 55 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java index f31c1bdcc9..83812ee1ab 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskRespVO.java @@ -85,10 +85,6 @@ public class BpmTaskRespVO { @Schema(description = "是否填写审批意见", example = "false") private Boolean reasonRequire; - // TODO @lesan:要不放到 processInstance 里面?因为摘要是流程实例的,不是流程任务的 - @Schema(description = "流程摘要", example = "[]") - private List> summary; // 只有流程表单,才有摘要! - @Data @Schema(description = "流程实例") public static class ProcessInstance { @@ -105,6 +101,9 @@ public class BpmTaskRespVO { @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") private String processDefinitionId; + @Schema(description = "流程摘要", example = "[]") + private List> summary; // 只有流程表单,才有摘要! + /** * 发起人的用户信息 */ diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java index ac6b91bbd7..2fce9ef0dc 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java @@ -54,7 +54,7 @@ public interface BpmTaskConvert { AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); // 摘要 - taskVO.setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), + taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), processInstance.getProcessVariables())); }); } @@ -80,7 +80,7 @@ public interface BpmTaskConvert { taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskRespVO.ProcessInstance.class)); taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); // 摘要 - taskVO.setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), + taskVO.getProcessInstance().setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), processInstance.getProcessVariables())); } return taskVO; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java index e80bba5029..305380158c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java @@ -27,6 +27,8 @@ import org.flowable.task.api.TaskInfo; import java.util.*; import java.util.concurrent.Callable; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; + /** * Flowable 相关的工具方法 * @@ -193,7 +195,6 @@ public class FlowableUtils { BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES); } - // TODO @lesan:如果值是 null 的情况,可能要调研下飞书、钉钉,是不是不返回哈! /** * 获得流程实例的摘要 * @@ -206,53 +207,39 @@ public class FlowableUtils { */ public static List> getSummary(BpmProcessDefinitionInfoDO processDefinitionInfo, Map processVariables) { - // TODO @lesan:建议 if return,减少 { 层级 - if (ObjectUtil.isNotNull(processDefinitionInfo) - && BpmModelFormTypeEnum.NORMAL.getType().equals(processDefinitionInfo.getFormType())) { - List> summaryList = new ArrayList<>(); - // TODO @lesan:可以使用 CollUtils.convertMap 简化工作量哈。 - Map formFieldsMap = new HashMap<>(); - processDefinitionInfo.getFormFields().forEach(formFieldStr -> { - BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class); - if (formField != null) { - formFieldsMap.put(formField.getField(), formField); - } - }); - - // TODO @lesan:这里也可以 if return,还是为了减少括号哈。这样,就可以写注释,情况一:;情况二: - if (ObjectUtil.isNotNull(processDefinitionInfo.getSummarySetting()) - && Boolean.TRUE.equals(processDefinitionInfo.getSummarySetting().getEnable())) { - // TODO @lesan:这里,也可以通过 CollUtils.convertList 简化哈。 - for (String item : processDefinitionInfo.getSummarySetting().getSummary()) { - BpmFormFieldVO formField = formFieldsMap.get(item); - if (formField != null) { - summaryList.add(new KeyValue<>(formField.getTitle(), - processVariables.getOrDefault(item, "").toString())); - } - } - } else { - // 默认展示前三个 - /* TODO @lesan:stream 简化 - * summaryList.addAll(formFieldsMap.entrySet().stream() - * .limit(3) - * .map(entry -> new KeyValue<>(entry.getValue().getTitle(), - * processVariables.getOrDefault(entry.getValue().getField(), "").toString())) - * .collect(Collectors.toList())); - */ - int j = 0; - for (Map.Entry entry : formFieldsMap.entrySet()) { - BpmFormFieldVO formField = entry.getValue(); - if (j > 2) { - break; - } - summaryList.add(new KeyValue<>(formField.getTitle(), - processVariables.getOrDefault(formField.getField(), "").toString())); - j++; - } - } - return summaryList; + // 只有流程表单才会显示摘要! + if (ObjectUtil.isNull(processDefinitionInfo) + || !BpmModelFormTypeEnum.NORMAL.getType().equals(processDefinitionInfo.getFormType())) { + return null; } - return null; + List> summaryList; + Map formFieldsMap = new HashMap<>(); + processDefinitionInfo.getFormFields().forEach(formFieldStr -> { + BpmFormFieldVO formField = JsonUtils.parseObject(formFieldStr, BpmFormFieldVO.class); + if (formField != null) { + formFieldsMap.put(formField.getField(), formField); + } + }); + if (ObjectUtil.isNotNull(processDefinitionInfo.getSummarySetting()) + && Boolean.TRUE.equals(processDefinitionInfo.getSummarySetting().getEnable())) { + // 情况一:当自定义了摘要 + summaryList = convertList(processDefinitionInfo.getSummarySetting().getSummary(), item -> { + BpmFormFieldVO formField = formFieldsMap.get(item); + if (formField != null) { + return new KeyValue(formField.getTitle(), + processVariables.getOrDefault(item, "").toString()); + } + return null; + }); + } else { + // 情况二:默认摘要展示前三个表单字段 + summaryList = new ArrayList<>(formFieldsMap.entrySet().stream() + .limit(3) + .map(entry -> new KeyValue<>(entry.getValue().getTitle(), + processVariables.getOrDefault(entry.getValue().getField(), "").toString())) + .toList()); + } + return summaryList; } // ========== Task 相关的工具方法 ========== @@ -317,9 +304,9 @@ public class FlowableUtils { private static Object getExpressionValue(VariableContainer variableContainer, String expressionString, ProcessEngineConfigurationImpl processEngineConfiguration) { - assert processEngineConfiguration!= null; + assert processEngineConfiguration != null; ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager(); - assert expressionManager!= null; + assert expressionManager != null; Expression expression = expressionManager.createExpression(expressionString); return expression.getValue(variableContainer); } From f409a67d2f74f4e351af7d11682c1b3ee09708a9 Mon Sep 17 00:00:00 2001 From: LesanOuO <1960681385@qq.com> Date: Sat, 25 Jan 2025 10:41:27 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=8A=84=E9=80=81=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=91=98=E8=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/BpmProcessInstanceCopyController.java | 14 +++++++++++++- .../task/vo/cc/BpmProcessInstanceCopyRespVO.java | 5 +++++ .../dataobject/task/BpmProcessInstanceCopyDO.java | 6 ++++++ .../task/BpmProcessInstanceCopyServiceImpl.java | 3 ++- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java index e8e2f9c71a..89bba8ecc3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java @@ -9,7 +9,10 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc.BpmProcessInstanceCopyRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceCopyService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -42,6 +45,8 @@ public class BpmProcessInstanceCopyController { private BpmProcessInstanceCopyService processInstanceCopyService; @Resource private BpmProcessInstanceService processInstanceService; + @Resource + private BpmProcessDefinitionService processDefinitionService; @Resource private AdminUserApi adminUserApi; @@ -62,6 +67,8 @@ public class BpmProcessInstanceCopyController { convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId)); Map userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(), copy -> Stream.of(copy.getStartUserId(), Long.parseLong(copy.getCreator())))); + Map processDefinitionInfoMap = processDefinitionService.getProcessDefinitionInfoMap( + convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessDefinitionId)); return success(convertPage(pageResult, copy -> { BpmProcessInstanceCopyRespVO copyVO = BeanUtils.toBean(copy, BpmProcessInstanceCopyRespVO.class); MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()), @@ -69,7 +76,12 @@ public class BpmProcessInstanceCopyController { MapUtils.findAndThen(userMap, copy.getStartUserId(), user -> copyVO.setCreateUser(BeanUtils.toBean(user, UserSimpleBaseVO.class))); MapUtils.findAndThen(processInstanceMap, copyVO.getProcessInstanceId(), - processInstance -> copyVO.setProcessInstanceStartTime(DateUtils.of(processInstance.getStartTime()))); + processInstance -> { + copyVO.setSummary(FlowableUtils.getSummary( + processDefinitionInfoMap.get(processInstance.getProcessDefinitionId()), + processInstance.getProcessVariables())); + copyVO.setProcessInstanceStartTime(DateUtils.of(processInstance.getStartTime())); + }); return copyVO; })); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java index b087c3a441..a7e194b168 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/cc/BpmProcessInstanceCopyRespVO.java @@ -1,10 +1,12 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc; +import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; +import java.util.List; @Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO") @Data @@ -40,4 +42,7 @@ public class BpmProcessInstanceCopyRespVO { @Schema(description = "抄送时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; + @Schema(description = "流程摘要", example = "[]") + private List> summary; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java index 96939f83d2..07f2df6417 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java @@ -49,6 +49,12 @@ public class BpmProcessInstanceCopyDO extends BaseDO { * 关联 ProcessInstance 的 id 属性 */ private String processInstanceId; + /** + * 流程实例的流程定义编号 + * + * 关联 ProcessInstance 的 processDefinitionId 属性 + */ + private String processDefinitionId; /** * 流程分类 * diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java index 1f90888c48..ed89cfe9db 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java @@ -77,7 +77,8 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy .setUserId(userId).setReason(reason).setStartUserId(Long.valueOf(processInstance.getStartUserId())) .setProcessInstanceId(processInstanceId).setProcessInstanceName(processInstance.getName()) .setCategory(processDefinition.getCategory()).setTaskId(taskId) - .setActivityId(activityId).setActivityName(activityName)); + .setActivityId(activityId).setActivityName(activityName) + .setProcessDefinitionId(processInstance.getProcessDefinitionId())); processInstanceCopyMapper.insertBatch(copyList); }