Commit ed83b912e40b2ce45c0c57297ec30fc02ed6eff3

Authored by YunaiV
1 parent d5e28d4c

BPM:新增流程分类表,替代现有的 `bpm_category` 数据字典

Showing 47 changed files with 1074 additions and 510 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java
... ... @@ -65,7 +65,12 @@ public interface ErrorCodeConstants {
65 65 ErrorCode FORM_FIELD_REPEAT = new ErrorCode(1_009_010_001, "表单项({}) 和 ({}) 使用了相同的字段名({})");
66 66  
67 67 // ========== 用户组模块 1-009-011-000 ==========
68   - ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1_009_011_000, "用户组不存在");
69   - ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1_009_011_001, "名字为【{}】的用户组已被禁用");
  68 + ErrorCode USER_GROUP_NOT_EXISTS = new ErrorCode(1_009_011_000, "用户分组不存在");
  69 + ErrorCode USER_GROUP_IS_DISABLE = new ErrorCode(1_009_011_001, "名字为【{}】的用户分组已被禁用");
  70 +
  71 + // ========== 用户组模块 1-009-012-000 ==========
  72 + ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1_009_012_000, "流程分类不存在");
  73 + ErrorCode CATEGORY_NAME_DUPLICATE = new ErrorCode(1_009_012_001, "流程分类名字【{}】重复");
  74 + ErrorCode CATEGORY_CODE_DUPLICATE = new ErrorCode(1_009_012_002, "流程分类编码【{}】重复");
70 75  
71 76 }
... ...
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceStatusEnum.java
1 1 package cn.iocoder.yudao.module.bpm.enums.task;
2 2  
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
3 4 import lombok.AllArgsConstructor;
4 5 import lombok.Getter;
5 6  
  7 +import java.util.Arrays;
  8 +
6 9 /**
7 10 * 流程实例 ProcessInstance 的状态
8 11 *
... ... @@ -10,13 +13,15 @@ import lombok.Getter;
10 13 */
11 14 @Getter
12 15 @AllArgsConstructor
13   -public enum BpmProcessInstanceStatusEnum {
  16 +public enum BpmProcessInstanceStatusEnum implements IntArrayValuable {
14 17  
15 18 RUNNING(1, "审批中"),
16 19 APPROVE(2, "审批通过"),
17 20 REJECT(3, "审批不通过"),
18 21 CANCEL(4, "已取消");
19 22  
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmProcessInstanceStatusEnum::getStatus).toArray();
  24 +
20 25 /**
21 26 * 状态
22 27 */
... ... @@ -26,4 +31,9 @@ public enum BpmProcessInstanceStatusEnum {
26 31 */
27 32 private final String desc;
28 33  
  34 + @Override
  35 + public int[] array() {
  36 + return new int[0];
  37 + }
  38 +
29 39 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/pom.xml
... ... @@ -70,5 +70,9 @@
70 70 <artifactId>yudao-spring-boot-starter-flowable</artifactId>
71 71 <version>${revision}</version>
72 72 </dependency>
  73 + <dependency>
  74 + <groupId>cn.iocoder.boot</groupId>
  75 + <artifactId>yudao-spring-boot-starter-excel</artifactId>
  76 + </dependency>
73 77 </dependencies>
74 78 </project>
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmCategoryController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
  8 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryRespVO;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  11 +import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.Parameter;
  14 +import io.swagger.v3.oas.annotations.tags.Tag;
  15 +import jakarta.annotation.Resource;
  16 +import jakarta.validation.Valid;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.*;
  20 +
  21 +import java.util.Comparator;
  22 +import java.util.List;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  26 +
  27 +@Tag(name = "管理后台 - BPM 流程分类")
  28 +@RestController
  29 +@RequestMapping("/bpm/category")
  30 +@Validated
  31 +public class BpmCategoryController {
  32 +
  33 + @Resource
  34 + private BpmCategoryService categoryService;
  35 +
  36 + @PostMapping("/create")
  37 + @Operation(summary = "创建流程分类")
  38 + @PreAuthorize("@ss.hasPermission('bpm:category:create')")
  39 + public CommonResult<Long> createCategory(@Valid @RequestBody BpmCategorySaveReqVO createReqVO) {
  40 + return success(categoryService.createCategory(createReqVO));
  41 + }
  42 +
  43 + @PutMapping("/update")
  44 + @Operation(summary = "更新流程分类")
  45 + @PreAuthorize("@ss.hasPermission('bpm:category:update')")
  46 + public CommonResult<Boolean> updateCategory(@Valid @RequestBody BpmCategorySaveReqVO updateReqVO) {
  47 + categoryService.updateCategory(updateReqVO);
  48 + return success(true);
  49 + }
  50 +
  51 + @DeleteMapping("/delete")
  52 + @Operation(summary = "删除流程分类")
  53 + @Parameter(name = "id", description = "编号", required = true)
  54 + @PreAuthorize("@ss.hasPermission('bpm:category:delete')")
  55 + public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) {
  56 + categoryService.deleteCategory(id);
  57 + return success(true);
  58 + }
  59 +
  60 + @GetMapping("/get")
  61 + @Operation(summary = "获得流程分类")
  62 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  63 + @PreAuthorize("@ss.hasPermission('bpm:category:query')")
  64 + public CommonResult<BpmCategoryRespVO> getCategory(@RequestParam("id") Long id) {
  65 + BpmCategoryDO category = categoryService.getCategory(id);
  66 + return success(BeanUtils.toBean(category, BpmCategoryRespVO.class));
  67 + }
  68 +
  69 + @GetMapping("/page")
  70 + @Operation(summary = "获得流程分类分页")
  71 + @PreAuthorize("@ss.hasPermission('bpm:category:query')")
  72 + public CommonResult<PageResult<BpmCategoryRespVO>> getCategoryPage(@Valid BpmCategoryPageReqVO pageReqVO) {
  73 + PageResult<BpmCategoryDO> pageResult = categoryService.getCategoryPage(pageReqVO);
  74 + return success(BeanUtils.toBean(pageResult, BpmCategoryRespVO.class));
  75 + }
  76 +
  77 + @GetMapping("/simple-list")
  78 + @Operation(summary = "获取流程分类的精简信息列表", description = "只包含被开启的分类,主要用于前端的下拉选项")
  79 + public CommonResult<List<BpmCategoryRespVO>> getCategorySimpleList() {
  80 + List<BpmCategoryDO> list = categoryService.getCategoryListByStatus(CommonStatusEnum.ENABLE.getStatus());
  81 + list.sort(Comparator.comparingInt(BpmCategoryDO::getSort));
  82 + return success(convertList(list, category -> new BpmCategoryRespVO().setId(category.getId())
  83 + .setName(category.getName()).setCode(category.getCode())));
  84 + }
  85 +
  86 +}
0 87 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 7 import cn.iocoder.yudao.framework.common.util.io.IoUtils;
  8 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
6 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
7 10 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  12 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  13 +import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
  14 +import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
8 15 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
  16 +import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
  17 +import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
9 18 import io.swagger.v3.oas.annotations.Operation;
10 19 import io.swagger.v3.oas.annotations.Parameter;
11 20 import io.swagger.v3.oas.annotations.tags.Tag;
12 21 import jakarta.annotation.Resource;
13 22 import jakarta.validation.Valid;
  23 +import org.flowable.engine.repository.Deployment;
  24 +import org.flowable.engine.repository.Model;
  25 +import org.flowable.engine.repository.ProcessDefinition;
14 26 import org.springframework.security.access.prepost.PreAuthorize;
15 27 import org.springframework.validation.annotation.Validated;
16 28 import org.springframework.web.bind.annotation.*;
17 29  
18 30 import java.io.IOException;
  31 +import java.util.HashSet;
  32 +import java.util.List;
  33 +import java.util.Map;
  34 +import java.util.Set;
19 35  
20 36 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  37 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  38 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
21 39  
22 40 @Tag(name = "管理后台 - 流程模型")
23 41 @RestController
... ... @@ -27,11 +45,39 @@ public class BpmModelController {
27 45  
28 46 @Resource
29 47 private BpmModelService modelService;
  48 + @Resource
  49 + private BpmFormService formService;
  50 + @Resource
  51 + private BpmCategoryService categoryService;
  52 + @Resource
  53 + private BpmProcessDefinitionService processDefinitionService;
30 54  
31 55 @GetMapping("/page")
32 56 @Operation(summary = "获得模型分页")
33   - public CommonResult<PageResult<BpmModelPageItemRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
34   - return success(modelService.getModelPage(pageVO));
  57 + public CommonResult<PageResult<BpmModelRespVO>> getModelPage(BpmModelPageReqVO pageVO) {
  58 + PageResult<Model> pageResult = modelService.getModelPage(pageVO);
  59 + if (CollUtil.isEmpty(pageResult.getList())) {
  60 + return success(PageResult.empty(pageResult.getTotal()));
  61 + }
  62 +
  63 + // 拼接数据
  64 + // 获得 Form 表单
  65 + Set<Long> formIds = convertSet(pageResult.getList(), model -> {
  66 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  67 + return metaInfo != null ? metaInfo.getFormId() : null;
  68 + });
  69 + Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
  70 + // 获得 Category Map
  71 + Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
  72 + convertSet(pageResult.getList(), Model::getCategory));
  73 + // 获得 Deployment Map
  74 + Set<String> deploymentIds = new HashSet<>();
  75 + pageResult.getList().forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
  76 + Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
  77 + // 获得 ProcessDefinition Map
  78 + List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
  79 + Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
  80 + return success(BpmModelConvert.INSTANCE.buildModelPage(pageResult, formMap, categoryMap, deploymentMap, processDefinitionMap));
35 81 }
36 82  
37 83 @GetMapping("/get")
... ... @@ -39,8 +85,12 @@ public class BpmModelController {
39 85 @Parameter(name = "id", description = "编号", required = true, example = "1024")
40 86 @PreAuthorize("@ss.hasPermission('bpm:model:query')")
41 87 public CommonResult<BpmModelRespVO> getModel(@RequestParam("id") String id) {
42   - BpmModelRespVO model = modelService.getModel(id);
43   - return success(model);
  88 + Model model = modelService.getModel(id);
  89 + if (model == null) {
  90 + return null;
  91 + }
  92 + byte[] bpmnBytes = modelService.getModelBpmnXML(id);
  93 + return success(BpmModelConvert.INSTANCE.buildModel(model, bpmnBytes));
44 94 }
45 95  
46 96 @PostMapping("/create")
... ... @@ -93,4 +143,5 @@ public class BpmModelController {
93 143 modelService.deleteModel(id);
94 144 return success(true);
95 145 }
  146 +
96 147 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmProcessDefinitionController.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.definition;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
7 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
8 7 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  8 +import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
  9 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
  12 +import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
  13 +import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
9 14 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
10   -import io.swagger.v3.oas.annotations.tags.Tag;
11   -import io.swagger.v3.oas.annotations.Parameter;
12 15 import io.swagger.v3.oas.annotations.Operation;
  16 +import io.swagger.v3.oas.annotations.Parameter;
  17 +import io.swagger.v3.oas.annotations.tags.Tag;
  18 +import jakarta.annotation.Resource;
  19 +import org.flowable.engine.repository.Deployment;
  20 +import org.flowable.engine.repository.ProcessDefinition;
13 21 import org.springframework.security.access.prepost.PreAuthorize;
14 22 import org.springframework.validation.annotation.Validated;
15 23 import org.springframework.web.bind.annotation.GetMapping;
... ... @@ -17,11 +25,12 @@ import org.springframework.web.bind.annotation.RequestMapping;
17 25 import org.springframework.web.bind.annotation.RequestParam;
18 26 import org.springframework.web.bind.annotation.RestController;
19 27  
20   -import jakarta.annotation.Resource;
21   -
  28 +import java.util.Collections;
22 29 import java.util.List;
  30 +import java.util.Map;
23 31  
24 32 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  33 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
25 34  
26 35 @Tag(name = "管理后台 - 流程定义")
27 36 @RestController
... ... @@ -30,22 +39,54 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
30 39 public class BpmProcessDefinitionController {
31 40  
32 41 @Resource
33   - private BpmProcessDefinitionService bpmDefinitionService;
  42 + private BpmProcessDefinitionService processDefinitionService;
  43 + @Resource
  44 + private BpmFormService formService;
  45 + @Resource
  46 + private BpmCategoryService categoryService;
34 47  
35 48 @GetMapping("/page")
36 49 @Operation(summary = "获得流程定义分页")
37 50 @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
38   - public CommonResult<PageResult<BpmProcessDefinitionPageItemRespVO>> getProcessDefinitionPage(
  51 + public CommonResult<PageResult<BpmProcessDefinitionRespVO>> getProcessDefinitionPage(
39 52 BpmProcessDefinitionPageReqVO pageReqVO) {
40   - return success(bpmDefinitionService.getProcessDefinitionPage(pageReqVO));
  53 + PageResult<ProcessDefinition> pageResult = processDefinitionService.getProcessDefinitionPage(pageReqVO);
  54 + if (CollUtil.isEmpty(pageResult.getList())) {
  55 + return success(PageResult.empty(pageResult.getTotal()));
  56 + }
  57 +
  58 + // 获得 Category Map
  59 + Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
  60 + convertSet(pageResult.getList(), ProcessDefinition::getCategory));
  61 + // 获得 Deployment Map
  62 + Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(
  63 + convertSet(pageResult.getList(), ProcessDefinition::getDeploymentId));
  64 + // 获得 BpmProcessDefinitionInfoDO Map
  65 + Map<String, BpmProcessDefinitionInfoDO> processDefinitionMap = processDefinitionService.getProcessDefinitionInfoMap(
  66 + convertSet(pageResult.getList(), ProcessDefinition::getId));
  67 + // 获得 Form Map
  68 + Map<Long, BpmFormDO> formMap = formService.getFormMap(
  69 + convertSet(processDefinitionMap.values(), BpmProcessDefinitionInfoDO::getFormId));
  70 + return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinitionPage(
  71 + pageResult, deploymentMap, processDefinitionMap, formMap, categoryMap));
41 72 }
42 73  
43 74 @GetMapping ("/list")
44 75 @Operation(summary = "获得流程定义列表")
  76 + @Parameter(name = "suspensionState", description = "挂起状态", required = true, example = "1") // 参见 Flowable SuspensionState 枚举
45 77 @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
46 78 public CommonResult<List<BpmProcessDefinitionRespVO>> getProcessDefinitionList(
47   - BpmProcessDefinitionListReqVO listReqVO) {
48   - return success(bpmDefinitionService.getProcessDefinitionList(listReqVO));
  79 + @RequestParam("suspensionState") Integer suspensionState) {
  80 + List<ProcessDefinition> list = processDefinitionService.getProcessDefinitionListBySuspensionState(suspensionState);
  81 + if (CollUtil.isEmpty(list)) {
  82 + return success(Collections.emptyList());
  83 + }
  84 +
  85 + // 获得 BpmProcessDefinitionInfoDO Map
  86 + Map<String, BpmProcessDefinitionInfoDO> processDefinitionMap = processDefinitionService.getProcessDefinitionInfoMap(
  87 + convertSet(list, ProcessDefinition::getId));
  88 + return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinitionList(
  89 + list, null, processDefinitionMap, null, null));
49 90 }
50 91  
51 92 @GetMapping ("/get-bpmn-xml")
... ... @@ -53,7 +94,8 @@ public class BpmProcessDefinitionController {
53 94 @Parameter(name = "id", description = "编号", required = true, example = "1024")
54 95 @PreAuthorize("@ss.hasPermission('bpm:process-definition:query')")
55 96 public CommonResult<String> getProcessDefinitionBpmnXML(@RequestParam("id") String id) {
56   - String bpmnXML = bpmDefinitionService.getProcessDefinitionBpmnXML(id);
  97 + String bpmnXML = processDefinitionService.getProcessDefinitionBpmnXML(id);
57 98 return success(bpmnXML);
58 99 }
  100 +
59 101 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategoryPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +import org.springframework.format.annotation.DateTimeFormat;
  11 +
  12 +import java.time.LocalDateTime;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  15 +
  16 +@Schema(description = "管理后台 - BPM 流程分类分页 Request VO")
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +public class BpmCategoryPageReqVO extends PageParam {
  21 +
  22 + @Schema(description = "分类名", example = "王五")
  23 + private String name;
  24 +
  25 + @Schema(description = "分类标志", example = "OA")
  26 + private String code;
  27 +
  28 + @Schema(description = "分类状态", example = "1")
  29 + @InEnum(CommonStatusEnum.class)
  30 + private Integer status;
  31 +
  32 + @Schema(description = "创建时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] createTime;
  35 +
  36 +}
0 37 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategoryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "管理后台 - BPM 流程分类 Response VO")
  9 +@Data
  10 +public class BpmCategoryRespVO {
  11 +
  12 + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
  13 + private Long id;
  14 +
  15 + @Schema(description = "分类名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
  16 + private String name;
  17 +
  18 + @Schema(description = "分类标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "OA")
  19 + private String code;
  20 +
  21 + @Schema(description = "分类描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
  22 + private String description;
  23 +
  24 + @Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  25 + private Integer status;
  26 +
  27 + @Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + private Integer sort;
  29 +
  30 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private LocalDateTime createTime;
  32 +
  33 +}
0 34 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/category/BpmCategorySaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import jakarta.validation.constraints.NotEmpty;
  7 +import jakarta.validation.constraints.NotNull;
  8 +import lombok.Data;
  9 +
  10 +@Schema(description = "管理后台 - BPM 流程分类新增/修改 Request VO")
  11 +@Data
  12 +public class BpmCategorySaveReqVO {
  13 +
  14 + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
  15 + private Long id;
  16 +
  17 + @Schema(description = "分类名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
  18 + @NotEmpty(message = "分类名不能为空")
  19 + private String name;
  20 +
  21 + @Schema(description = "分类标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "OA")
  22 + @NotEmpty(message = "分类标志不能为空")
  23 + private String code;
  24 +
  25 + @Schema(description = "分类状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + @NotNull(message = "分类状态不能为空")
  27 + @InEnum(CommonStatusEnum.class)
  28 + private Integer status;
  29 +
  30 + @Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + @NotNull(message = "分类排序不能为空")
  32 + private Integer sort;
  33 +
  34 +}
0 35 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelBaseVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
2   -import io.swagger.v3.oas.annotations.media.Schema;
3   -import lombok.Data;
4   -
5   -import jakarta.validation.constraints.NotEmpty;
6   -
7   -/**
8   -* 流程模型 Base VO,提供给添加、修改、详细的子 VO 使用
9   -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
10   -*/
11   -@Data
12   -public class BpmModelBaseVO {
13   -
14   - @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "process_yudao")
15   - @NotEmpty(message = "流程标识不能为空")
16   - private String key;
17   -
18   - @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
19   - @NotEmpty(message = "流程名称不能为空")
20   - private String name;
21   -
22   - @Schema(description = "流程描述", example = "我是描述")
23   - private String description;
24   -
25   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
26   - @NotEmpty(message = "流程分类不能为空")
27   - private String category;
28   -
29   - @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
30   - private Integer formType;
31   - @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
32   - private Long formId;
33   - @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
34   - example = "/bpm/oa/leave/create")
35   - private String formCustomCreatePath;
36   - @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
37   - example = "/bpm/oa/leave/view")
38   - private String formCustomViewPath;
39   -
40   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageItemRespVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7   -
8   -import java.time.LocalDateTime;
9   -
10   -@Schema(description = "管理后台 - 流程模型的分页的每一项 Response VO")
11   -@Data
12   -@EqualsAndHashCode(callSuper = true)
13   -@ToString(callSuper = true)
14   -public class BpmModelPageItemRespVO extends BpmModelBaseVO {
15   -
16   - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17   - private String id;
18   -
19   - @Schema(description = "表单名字", example = "请假表单")
20   - private String formName;
21   -
22   - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
23   - private LocalDateTime createTime;
24   -
25   - /**
26   - * 最新部署的流程定义
27   - */
28   - private ProcessDefinition processDefinition;
29   -
30   - @Schema(description = "流程定义")
31   - @Data
32   - public static class ProcessDefinition {
33   -
34   - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
35   - private String id;
36   -
37   - @Schema(description = "版本", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
38   - private Integer version;
39   -
40   - @Schema(description = "部署时间", requiredMode = Schema.RequiredMode.REQUIRED)
41   - private LocalDateTime deploymentTime;
42   -
43   - @Schema(description = "中断状态-参见 SuspensionState 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
44   - private Integer suspensionState;
45   -
46   - }
47   -
48   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelPageReqVO.java
... ... @@ -13,13 +13,13 @@ import lombok.ToString;
13 13 @ToString(callSuper = true)
14 14 public class BpmModelPageReqVO extends PageParam {
15 15  
16   - @Schema(description = "标识-精准匹配", example = "process1641042089407")
  16 + @Schema(description = "标识,精准匹配", example = "process1641042089407")
17 17 private String key;
18 18  
19   - @Schema(description = "名字-模糊匹配", example = "芋道")
  19 + @Schema(description = "名字,模糊匹配", example = "芋道")
20 20 private String name;
21 21  
22   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
  22 + @Schema(description = "流程分类", example = "1")
23 23 private String category;
24 24  
25 25 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelRespVO.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model;
2 2  
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
3 4 import io.swagger.v3.oas.annotations.media.Schema;
4 5 import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7 6  
8 7 import java.time.LocalDateTime;
9 8  
10   -@Schema(description = "管理后台 - 流程模型的创建 Request VO")
  9 +@Schema(description = "管理后台 - 流程模型 Response VO")
11 10 @Data
12   -@EqualsAndHashCode(callSuper = true)
13   -@ToString(callSuper = true)
14   -public class BpmModelRespVO extends BpmModelBaseVO {
  11 +public class BpmModelRespVO {
15 12  
16 13 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
17 14 private String id;
18 15  
19   - @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
20   - private String bpmnXml;
  16 + @Schema(description = "流程标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "process_yudao")
  17 + private String key;
  18 +
  19 + @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
  20 + private String name;
  21 +
  22 + @Schema(description = "流程描述", example = "我是描述")
  23 + private String description;
  24 +
  25 + @Schema(description = "流程分类编码", example = "1")
  26 + private String category;
  27 + @Schema(description = "流程分类名字", example = "请假")
  28 + private String categoryName;
  29 +
  30 + @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
  31 + private Integer formType;
  32 +
  33 + @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
  34 + private Long formId;
  35 + @Schema(description = "表单名字", example = "请假表单")
  36 + private String formName;
  37 +
  38 + @Schema(description = "自定义表单的提交路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
  39 + example = "/bpm/oa/leave/create")
  40 + private String formCustomCreatePath;
  41 + @Schema(description = "自定义表单的查看路径,使用 Vue 的路由地址-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空",
  42 + example = "/bpm/oa/leave/view")
  43 + private String formCustomViewPath;
21 44  
22 45 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
23 46 private LocalDateTime createTime;
24 47  
  48 + @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
  49 + private String bpmnXml;
  50 +
  51 + /**
  52 + * 最新部署的流程定义
  53 + */
  54 + private BpmProcessDefinitionRespVO processDefinition;
  55 +
25 56 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateReqVO.java
... ... @@ -19,7 +19,7 @@ public class BpmModelUpdateReqVO {
19 19 @Schema(description = "流程描述", example = "我是描述")
20 20 private String description;
21 21  
22   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
  22 + @Schema(description = "流程分类", example = "1")
23 23 private String category;
24 24  
25 25 @Schema(description = "BPMN XML", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelUpdateStateReqVO.java
... ... @@ -13,8 +13,8 @@ public class BpmModelUpdateStateReqVO {
13 13 @NotNull(message = "编号不能为空")
14 14 private String id;
15 15  
16   - @Schema(description = "状态-见 SuspensionState 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
17 17 @NotNull(message = "状态不能为空")
18   - private Integer state;
  18 + private Integer state; // 参见 Flowable SuspensionState 枚举
19 19  
20 20 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionListReqVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageParam;
4   -import io.swagger.v3.oas.annotations.media.Schema;
5   -import lombok.Data;
6   -import lombok.EqualsAndHashCode;
7   -import lombok.ToString;
8   -
9   -@Schema(description = "管理后台 - 流程定义列表 Request VO")
10   -@Data
11   -@ToString(callSuper = true)
12   -@EqualsAndHashCode(callSuper = true)
13   -public class BpmProcessDefinitionListReqVO extends PageParam {
14   -
15   - @Schema(description = "中断状态-参见 SuspensionState 枚举", example = "1")
16   - private Integer suspensionState;
17   -
18   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionPageItemRespVO.java deleted
1   -package cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -import lombok.EqualsAndHashCode;
6   -import lombok.ToString;
7   -
8   -import java.time.LocalDateTime;
9   -
10   -@Schema(description = "管理后台 - 流程定义的分页的每一项 Response VO")
11   -@Data
12   -@EqualsAndHashCode(callSuper = true)
13   -@ToString(callSuper = true)
14   -public class BpmProcessDefinitionPageItemRespVO extends BpmProcessDefinitionRespVO {
15   -
16   - @Schema(description = "表单名字", example = "请假表单")
17   - private String formName;
18   -
19   - @Schema(description = "部署时间", requiredMode = Schema.RequiredMode.REQUIRED)
20   - private LocalDateTime deploymentTime;
21   -
22   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/process/BpmProcessDefinitionRespVO.java
... ... @@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6 6 import jakarta.validation.constraints.NotEmpty;
  7 +
  8 +import java.time.LocalDateTime;
7 9 import java.util.List;
8 10  
9 11 @Schema(description = "管理后台 - 流程定义 Response VO")
... ... @@ -23,14 +25,17 @@ public class BpmProcessDefinitionRespVO {
23 25 @Schema(description = "流程描述", example = "我是描述")
24 26 private String description;
25 27  
26   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
27   - @NotEmpty(message = "流程分类不能为空")
  28 + @Schema(description = "流程分类", example = "1")
28 29 private String category;
  30 + @Schema(description = "流程分类名字", example = "请假")
  31 + private String categoryName;
29 32  
30 33 @Schema(description = "表单类型-参见 bpm_model_form_type 数据字典", example = "1")
31 34 private Integer formType;
32 35 @Schema(description = "表单编号-在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", example = "1024")
33 36 private Long formId;
  37 + @Schema(description = "表单名字", example = "请假表单")
  38 + private String formName;
34 39 @Schema(description = "表单的配置-JSON 字符串。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", requiredMode = Schema.RequiredMode.REQUIRED)
35 40 private String formConf;
36 41 @Schema(description = "表单项的数组-JSON 字符串的数组。在表单类型为 {@link BpmModelFormTypeEnum#CUSTOM} 时,必须非空", requiredMode = Schema.RequiredMode.REQUIRED)
... ... @@ -45,4 +50,7 @@ public class BpmProcessDefinitionRespVO {
45 50 @Schema(description = "中断状态-参见 SuspensionState 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
46 51 private Integer suspensionState;
47 52  
  53 + @Schema(description = "部署时间", requiredMode = Schema.RequiredMode.REQUIRED)
  54 + private LocalDateTime deploymentTime; // 需要从对应的 Deployment 读取
  55 +
48 56 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java
... ... @@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
7 7 import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
  8 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  9 +import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
8 10 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
9 11 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
10 12 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
... ... @@ -40,6 +42,8 @@ public class BpmProcessInstanceController {
40 42 private BpmTaskService taskService;
41 43 @Resource
42 44 private BpmProcessDefinitionService processDefinitionService;
  45 + @Resource
  46 + private BpmCategoryService categoryService;
43 47  
44 48 @GetMapping("/my-page")
45 49 @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用")
... ... @@ -56,7 +60,9 @@ public class BpmProcessInstanceController {
56 60 convertList(pageResult.getList(), HistoricProcessInstance::getId));
57 61 Map<String, ProcessDefinition> processDefinitionMap = processDefinitionService.getProcessDefinitionMap(
58 62 convertSet(pageResult.getList(), HistoricProcessInstance::getProcessDefinitionId));
59   - return success(BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, processDefinitionMap, taskMap));
  63 + Map<String, BpmCategoryDO> categoryMap = categoryService.getCategoryMap(
  64 + convertSet(processDefinitionMap.values(), ProcessDefinition::getCategory));
  65 + return success(BpmProcessInstanceConvert.INSTANCE.convertPage(pageResult, processDefinitionMap, categoryMap, taskMap));
60 66 }
61 67  
62 68 @PostMapping("/create")
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceCopyController.java
... ... @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.date.DateUtils;
8 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 9 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.cc.BpmProcessInstanceCopyRespVO;
10 10 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
11   -import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
12 12 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceCopyService;
13 13 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
14 14 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
... ... @@ -44,7 +44,7 @@ public class BpmProcessInstanceCopyController {
44 44 @Resource
45 45 private BpmProcessInstanceService processInstanceService;
46 46 @Resource
47   - private BpmTaskService bpmTaskService;
  47 + private BpmTaskService taskService;
48 48  
49 49 @Resource
50 50 private AdminUserApi adminUserApi;
... ... @@ -61,7 +61,7 @@ public class BpmProcessInstanceCopyController {
61 61 }
62 62  
63 63 // 拼接返回
64   - Map<String, String> taskNameMap = bpmTaskService.getTaskNameByTaskIds(
  64 + Map<String, String> taskNameMap = taskService.getTaskNameByTaskIds(
65 65 convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getTaskId));
66 66 Map<String, HistoricProcessInstance> processInstanceMap = processInstanceService.getHistoricProcessInstanceMap(
67 67 convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId));
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceMyPageReqVO.java
1 1 package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum;
4 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -23,13 +25,11 @@ public class BpmProcessInstanceMyPageReqVO extends PageParam {
23 25 @Schema(description = "流程定义的编号", example = "2048")
24 26 private String processDefinitionId;
25 27  
26   - @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", example = "1")
  28 + @Schema(description = "流程实例的状态", example = "1")
  29 + @InEnum(BpmProcessInstanceStatusEnum.class)
27 30 private Integer status;
28 31  
29   - @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", example = "2")
30   - private Integer result;
31   -
32   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", example = "1")
  32 + @Schema(description = "流程分类", example = "1")
33 33 private String category;
34 34  
35 35 @Schema(description = "创建时间")
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstancePageItemRespVO.java
... ... @@ -6,6 +6,7 @@ import lombok.Data;
6 6 import java.time.LocalDateTime;
7 7 import java.util.List;
8 8  
  9 +// TODO @芋艿:是不是要融合?
9 10 @Schema(description = "管理后台 - 流程实例的分页 Item Response VO")
10 11 @Data
11 12 public class BpmProcessInstancePageItemRespVO {
... ... @@ -19,10 +20,12 @@ public class BpmProcessInstancePageItemRespVO {
19 20 @Schema(description = "流程定义的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
20 21 private String processDefinitionId;
21 22  
22   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  23 + @Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
23 24 private String category;
  25 + @Schema(description = "流程分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "请假")
  26 + private String categoryName;
24 27  
25   - @Schema(description = "流程实例的状态-参见 bpm_process_instance_status", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  28 + @Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
26 29 private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
27 30  
28 31 @Schema(description = "提交时间", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceRespVO.java
... ... @@ -17,15 +17,12 @@ public class BpmProcessInstanceRespVO {
17 17 @Schema(description = "流程名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
18 18 private String name;
19 19  
20   - @Schema(description = "流程分类-参见 bpm_model_category 数据字典", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  20 + @Schema(description = "流程分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
21 21 private String category;
22 22  
23 23 @Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
24 24 private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
25 25  
26   - @Schema(description = "流程实例的结果-参见 bpm_process_instance_result", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
27   - private Integer result;
28   -
29 26 @Schema(description = "提交时间", requiredMode = Schema.RequiredMode.REQUIRED)
30 27 private LocalDateTime createTime;
31 28  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
1 1 package cn.iocoder.yudao.module.bpm.convert.definition;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5 6 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
6 7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
7   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModeImportReqVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelCreateReqVO;
  11 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelRespVO;
  12 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelUpdateReqVO;
  13 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  14 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
8 15 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
9 16 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
10 17 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
... ... @@ -30,57 +37,61 @@ public interface BpmModelConvert {
30 37  
31 38 BpmModelConvert INSTANCE = Mappers.getMapper(BpmModelConvert.class);
32 39  
33   - default List<BpmModelPageItemRespVO> convertList(List<Model> list, Map<Long, BpmFormDO> formMap,
34   - Map<String, Deployment> deploymentMap,
35   - Map<String, ProcessDefinition> processDefinitionMap) {
36   - return CollectionUtils.convertList(list, model -> {
  40 + default PageResult<BpmModelRespVO> buildModelPage(PageResult<Model> pageResult,
  41 + Map<Long, BpmFormDO> formMap,
  42 + Map<String, BpmCategoryDO> categoryMap, Map<String, Deployment> deploymentMap,
  43 + Map<String, ProcessDefinition> processDefinitionMap) {
  44 + List<BpmModelRespVO> list = CollectionUtils.convertList(pageResult.getList(), model -> {
37 45 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
38 46 BpmFormDO form = metaInfo != null ? formMap.get(metaInfo.getFormId()) : null;
  47 + BpmCategoryDO category = categoryMap.get(model.getCategory());
39 48 Deployment deployment = model.getDeploymentId() != null ? deploymentMap.get(model.getDeploymentId()) : null;
40 49 ProcessDefinition processDefinition = model.getDeploymentId() != null ? processDefinitionMap.get(model.getDeploymentId()) : null;
41   - return convert(model, form, deployment, processDefinition);
  50 + return buildModel0(model, metaInfo, form, category, deployment, processDefinition);
42 51 });
  52 + return new PageResult<>(list, pageResult.getTotal());
43 53 }
44 54  
45   - default BpmModelPageItemRespVO convert(Model model, BpmFormDO form, Deployment deployment, ProcessDefinition processDefinition) {
46   - BpmModelPageItemRespVO modelRespVO = new BpmModelPageItemRespVO();
47   - modelRespVO.setId(model.getId());
48   - modelRespVO.setCreateTime(DateUtils.of(model.getCreateTime()));
49   - // 通用 copy
50   - copyTo(model, modelRespVO);
  55 + default BpmModelRespVO buildModel(Model model,
  56 + byte[] bpmnBytes) {
  57 + BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
  58 + BpmModelRespVO modelVO = buildModel0(model, metaInfo, null, null, null, null);
  59 + modelVO.setBpmnXml(new String(bpmnBytes));
  60 + return modelVO;
  61 + }
  62 +
  63 + default BpmModelRespVO buildModel0(Model model,
  64 + BpmModelMetaInfoRespDTO metaInfo, BpmFormDO form, BpmCategoryDO category,
  65 + Deployment deployment, ProcessDefinition processDefinition) {
  66 + BpmModelRespVO modelRespVO = new BpmModelRespVO().setId(model.getId()).setName(model.getName())
  67 + .setKey(model.getKey()).setCategory(model.getCategory())
  68 + .setCreateTime(DateUtils.of(model.getCreateTime()));
51 69 // Form
  70 + if (metaInfo != null) {
  71 + modelRespVO.setFormType(metaInfo.getFormType()).setFormId(metaInfo.getFormId())
  72 + .setFormCustomCreatePath(metaInfo.getFormCustomCreatePath())
  73 + .setFormCustomViewPath(metaInfo.getFormCustomViewPath());
  74 + modelRespVO.setDescription(metaInfo.getDescription());
  75 + }
52 76 if (form != null) {
53   - modelRespVO.setFormId(form.getId());
54   - modelRespVO.setFormName(form.getName());
  77 + modelRespVO.setFormId(form.getId()).setFormName(form.getName());
  78 + }
  79 + // Category
  80 + if (category != null) {
  81 + modelRespVO.setCategoryName(category.getName());
55 82 }
56 83 // ProcessDefinition
57   - modelRespVO.setProcessDefinition(this.convert(processDefinition));
58   - if (modelRespVO.getProcessDefinition() != null) {
  84 + if (processDefinition != null) {
  85 + modelRespVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class));
59 86 modelRespVO.getProcessDefinition().setSuspensionState(processDefinition.isSuspended() ?
60 87 SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
61   - modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
  88 + if (deployment != null) {
  89 + modelRespVO.getProcessDefinition().setDeploymentTime(DateUtils.of(deployment.getDeploymentTime()));
  90 + }
62 91 }
63 92 return modelRespVO;
64 93 }
65 94  
66   - default BpmModelRespVO convert(Model model) {
67   - BpmModelRespVO modelRespVO = new BpmModelRespVO();
68   - modelRespVO.setId(model.getId());
69   - modelRespVO.setCreateTime(DateUtils.of(model.getCreateTime()));
70   - // 通用 copy
71   - copyTo(model, modelRespVO);
72   - return modelRespVO;
73   - }
74   -
75   - default void copyTo(Model model, BpmModelBaseVO to) {
76   - to.setName(model.getName());
77   - to.setKey(model.getKey());
78   - to.setCategory(model.getCategory());
79   - // metaInfo
80   - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
81   - copyTo(metaInfo, to);
82   - }
83   -
84 95 BpmModelCreateReqVO convert(BpmModeImportReqVO bean);
85 96  
86 97 default BpmProcessDefinitionCreateReqDTO convert2(Model model, BpmFormDO form) {
... ... @@ -102,18 +113,14 @@ public interface BpmModelConvert {
102 113  
103 114 void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmProcessDefinitionCreateReqDTO to);
104 115  
105   - void copyTo(BpmModelMetaInfoRespDTO from, @MappingTarget BpmModelBaseVO to);
106   -
107   - BpmModelPageItemRespVO.ProcessDefinition convert(ProcessDefinition bean);
108   -
109   - default void copy(Model model, BpmModelCreateReqVO bean) {
  116 + default void copyToCreateModel(Model model, BpmModelCreateReqVO bean) {
110 117 model.setName(bean.getName());
111 118 model.setKey(bean.getKey());
112 119 model.setMetaInfo(buildMetaInfoStr(null, bean.getDescription(), null, null,
113 120 null, null));
114 121 }
115 122  
116   - default void copy(Model model, BpmModelUpdateReqVO bean) {
  123 + default void copyToUpdateModel(Model model, BpmModelUpdateReqVO bean) {
117 124 model.setName(bean.getName());
118 125 model.setCategory(bean.getCategory());
119 126 model.setMetaInfo(buildMetaInfoStr(JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class),
... ... @@ -138,4 +145,5 @@ public interface BpmModelConvert {
138 145 }
139 146 return JsonUtils.toJsonString(metaInfo);
140 147 }
  148 +
141 149 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmProcessDefinitionConvert.java
1 1 package cn.iocoder.yudao.module.bpm.convert.definition;
2 2  
3 3 import cn.hutool.core.date.LocalDateTimeUtil;
  4 +import cn.hutool.core.map.MapUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5   -import cn.iocoder.yudao.framework.common.util.date.DateUtils;
6   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 9 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
8 11 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
9   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  12 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
10 13 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
11 14 import org.flowable.common.engine.impl.db.SuspensionState;
12 15 import org.flowable.engine.repository.Deployment;
... ... @@ -14,7 +17,6 @@ import org.flowable.engine.repository.ProcessDefinition;
14 17 import org.mapstruct.Mapper;
15 18 import org.mapstruct.Mapping;
16 19 import org.mapstruct.MappingTarget;
17   -import org.mapstruct.Named;
18 20 import org.mapstruct.factory.Mappers;
19 21  
20 22 import java.util.List;
... ... @@ -30,55 +32,46 @@ public interface BpmProcessDefinitionConvert {
30 32  
31 33 BpmProcessDefinitionConvert INSTANCE = Mappers.getMapper(BpmProcessDefinitionConvert.class);
32 34  
33   - BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean);
34 35  
35   - BpmProcessDefinitionExtDO convert2(BpmProcessDefinitionCreateReqDTO bean);
36   -
37   - default List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list, Map<String, Deployment> deploymentMap,
38   - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap, Map<Long, BpmFormDO> formMap) {
39   - return CollectionUtils.convertList(list, definition -> {
40   - Deployment deployment = definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId()) : null;
41   - BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());
42   - BpmFormDO form = definitionDO != null ? formMap.get(definitionDO.getFormId()) : null;
43   - return convert(definition, deployment, definitionDO, form);
44   - });
  36 + default PageResult<BpmProcessDefinitionRespVO> buildProcessDefinitionPage(PageResult<ProcessDefinition> page,
  37 + Map<String, Deployment> deploymentMap,
  38 + Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap,
  39 + Map<Long, BpmFormDO> formMap,
  40 + Map<String, BpmCategoryDO> categoryMap) {
  41 + List<BpmProcessDefinitionRespVO> list = buildProcessDefinitionList(page.getList(), deploymentMap, processDefinitionInfoMap, formMap, categoryMap);
  42 + return new PageResult<>(list, page.getTotal());
45 43 }
46 44  
47   - default List<BpmProcessDefinitionRespVO> convertList3(List<ProcessDefinition> list,
48   - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap) {
49   - return CollectionUtils.convertList(list, processDefinition -> {
50   - BpmProcessDefinitionRespVO respVO = convert3(processDefinition);
51   - BpmProcessDefinitionExtDO processDefinitionExtDO = processDefinitionDOMap.get(processDefinition.getId());
52   - // 复制通用属性
53   - copyTo(processDefinitionExtDO, respVO);
  45 + default List<BpmProcessDefinitionRespVO> buildProcessDefinitionList(List<ProcessDefinition> list,
  46 + Map<String, Deployment> deploymentMap,
  47 + Map<String, BpmProcessDefinitionInfoDO> processDefinitionInfoMap,
  48 + Map<Long, BpmFormDO> formMap,
  49 + Map<String, BpmCategoryDO> categoryMap) {
  50 + return CollectionUtils.convertList(list, definition -> {
  51 + BpmProcessDefinitionRespVO respVO = BeanUtils.toBean(definition, BpmProcessDefinitionRespVO.class);
  52 + respVO.setSuspensionState(definition.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
  53 + // Deployment
  54 + MapUtils.findAndThen(deploymentMap, definition.getDeploymentId(),
  55 + deployment -> respVO.setDeploymentTime(LocalDateTimeUtil.of(deployment.getDeploymentTime())));
  56 + // BpmProcessDefinitionInfoDO
  57 + BpmProcessDefinitionInfoDO processDefinitionInfo = MapUtil.get(processDefinitionInfoMap, definition.getId(), BpmProcessDefinitionInfoDO.class);
  58 + if (processDefinitionInfo != null) {
  59 + copyTo(processDefinitionInfo, respVO);
  60 + // Form
  61 + BpmFormDO form = MapUtil.get(formMap, processDefinitionInfo.getFormId(), BpmFormDO.class);
  62 + if (form != null) {
  63 + respVO.setFormName(form.getName());
  64 + }
  65 + }
  66 + // Category
  67 + MapUtils.findAndThen(categoryMap, definition.getCategory(), category -> respVO.setCategoryName(category.getName()));
54 68 return respVO;
55 69 });
56 70 }
57 71  
58   - @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
59   - BpmProcessDefinitionRespVO convert3(ProcessDefinition bean);
60   -
61   - @Named("convertSuspendedToSuspensionState")
62   - default Integer convertSuspendedToSuspensionState(boolean suspended) {
63   - return suspended ? SuspensionState.SUSPENDED.getStateCode() :
64   - SuspensionState.ACTIVE.getStateCode();
65   - }
66   -
67   - default BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
68   - BpmProcessDefinitionExtDO processDefinitionExtDO, BpmFormDO form) {
69   - BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
70   - respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode() : SuspensionState.ACTIVE.getStateCode());
71   - if (deployment != null) {
72   - respVO.setDeploymentTime(LocalDateTimeUtil.of(deployment.getDeploymentTime()));
73   - }
74   - if (form != null) {
75   - respVO.setFormName(form.getName());
76   - }
77   - // 复制通用属性
78   - copyTo(processDefinitionExtDO, respVO);
79   - return respVO;
80   - }
  72 + BpmProcessDefinitionInfoDO convert2(BpmProcessDefinitionCreateReqDTO bean);
81 73  
82 74 @Mapping(source = "from.id", target = "to.id", ignore = true)
83   - void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessDefinitionRespVO to);
  75 + void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to);
  76 +
84 77 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
... ... @@ -7,7 +7,8 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
7 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
9 9 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
10   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
11 12 import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceResultEvent;
12 13 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
13 14 import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
... ... @@ -38,6 +39,7 @@ public interface BpmProcessInstanceConvert {
38 39  
39 40 default PageResult<BpmProcessInstancePageItemRespVO> convertPage(PageResult<HistoricProcessInstance> pageResult,
40 41 Map<String, ProcessDefinition> processDefinitionMap,
  42 + Map<String, BpmCategoryDO> categoryMap,
41 43 Map<String, List<Task>> taskMap) {
42 44 PageResult<BpmProcessInstancePageItemRespVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstancePageItemRespVO.class);
43 45 for (int i = 0; i < pageResult.getList().size(); i++) {
... ... @@ -45,13 +47,14 @@ public interface BpmProcessInstanceConvert {
45 47 respVO.setStatus((Integer) pageResult.getList().get(i).getProcessVariables().get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS));
46 48 MapUtils.findAndThen(processDefinitionMap, respVO.getProcessDefinitionId(),
47 49 processDefinition -> respVO.setCategory(processDefinition.getCategory()));
  50 + MapUtils.findAndThen(categoryMap, respVO.getCategory(), category -> respVO.setCategoryName(category.getName()));
48 51 respVO.setTasks(BeanUtils.toBean(taskMap.get(respVO.getId()), BpmProcessInstancePageItemRespVO.Task.class));
49 52 }
50 53 return vpPageResult;
51 54 }
52 55  
53 56 default BpmProcessInstanceRespVO convert2(HistoricProcessInstance processInstance,
54   - ProcessDefinition processDefinition, BpmProcessDefinitionExtDO processDefinitionExt,
  57 + ProcessDefinition processDefinition, BpmProcessDefinitionInfoDO processDefinitionExt,
55 58 String bpmnXml, AdminUserRespDTO startUser, DeptRespDTO dept) {
56 59 BpmProcessInstanceRespVO respVO = convert2(processInstance);
57 60 respVO.setStatus((Integer) processInstance.getProcessVariables().get(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS));
... ... @@ -75,7 +78,7 @@ public interface BpmProcessInstanceConvert {
75 78 BpmProcessInstanceRespVO.ProcessDefinition convert2(ProcessDefinition bean);
76 79  
77 80 @Mapping(source = "from.id", target = "to.id", ignore = true)
78   - void copyTo(BpmProcessDefinitionExtDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
  81 + void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessInstanceRespVO.ProcessDefinition to);
79 82  
80 83 BpmProcessInstanceRespVO.User convert2(AdminUserRespDTO bean);
81 84  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmCategoryDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.time.LocalDateTime;
  6 +import java.time.LocalDateTime;
  7 +import com.baomidou.mybatisplus.annotation.*;
  8 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  9 +
  10 +/**
  11 + * BPM 流程分类 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("bpm_category")
  16 +@KeySequence("bpm_category_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class BpmCategoryDO extends BaseDO {
  24 +
  25 + /**
  26 + * 分类编号
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 分类名
  32 + */
  33 + private String name;
  34 + /**
  35 + * 分类标志
  36 + */
  37 + private String code;
  38 + /**
  39 + * 分类描述
  40 + */
  41 + private String description;
  42 + /**
  43 + * 分类状态
  44 + *
  45 + * 枚举 {@link TODO common_status 对应的类}
  46 + */
  47 + private Integer status;
  48 + /**
  49 + * 分类排序
  50 + */
  51 + private Integer sort;
  52 +
  53 +}
0 54 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionExtDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java
... ... @@ -11,19 +11,19 @@ import lombok.*;
11 11 import java.util.List;
12 12  
13 13 /**
14   - * Bpm 流程定义的拓展表
15   - * 主要解决 Activiti {@link ProcessDefinition} 不支持拓展字段,所以新建拓展表
  14 + * Bpm 流程定义的拓信息
  15 + * 主要解决 Flowable {@link org.flowable.engine.repository.ProcessDefinition} 不支持拓展字段,所以新建该表
16 16 *
17 17 * @author 芋道源码
18 18 */
19   -@TableName(value = "bpm_process_definition_ext", autoResultMap = true)
  19 +@TableName(value = "bpm_process_definition_info", autoResultMap = true)
20 20 @Data
21 21 @EqualsAndHashCode(callSuper = true)
22 22 @ToString(callSuper = true)
23 23 @Builder
24 24 @NoArgsConstructor
25 25 @AllArgsConstructor
26   -public class BpmProcessDefinitionExtDO extends BaseDO {
  26 +public class BpmProcessDefinitionInfoDO extends BaseDO {
27 27  
28 28 /**
29 29 * 编号
... ... @@ -86,5 +86,4 @@ public class BpmProcessDefinitionExtDO extends BaseDO {
86 86 */
87 87 private String formCustomViewPath;
88 88  
89   -
90 89 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmProcessInstanceCopyDO.java
1   -package cn.iocoder.yudao.module.bpm.dal.dataobject.cc;
  1 +package cn.iocoder.yudao.module.bpm.dal.dataobject.task;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import com.baomidou.mybatisplus.annotation.TableId;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/category/BpmCategoryMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.mysql.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
  7 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * BPM 流程分类 Mapper
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Mapper
  19 +public interface BpmCategoryMapper extends BaseMapperX<BpmCategoryDO> {
  20 +
  21 + default PageResult<BpmCategoryDO> selectPage(BpmCategoryPageReqVO reqVO) {
  22 + return selectPage(reqVO, new LambdaQueryWrapperX<BpmCategoryDO>()
  23 + .likeIfPresent(BpmCategoryDO::getName, reqVO.getName())
  24 + .eqIfPresent(BpmCategoryDO::getCode, reqVO.getCode())
  25 + .eqIfPresent(BpmCategoryDO::getStatus, reqVO.getStatus())
  26 + .betweenIfPresent(BpmCategoryDO::getCreateTime, reqVO.getCreateTime())
  27 + .orderByAsc(BpmCategoryDO::getSort));
  28 + }
  29 +
  30 + default BpmCategoryDO selectByName(String name) {
  31 + return selectOne(BpmCategoryDO::getName, name);
  32 + }
  33 +
  34 + default BpmCategoryDO selectByCode(String code) {
  35 + return selectOne(BpmCategoryDO::getCode, code);
  36 + }
  37 +
  38 + default List<BpmCategoryDO> selectListByCode(Collection<String> codes) {
  39 + return selectList(BpmCategoryDO::getCode, codes);
  40 + }
  41 +
  42 + default List<BpmCategoryDO> selectListByStatus(Integer status) {
  43 + return selectList(BpmCategoryDO::getStatus, status);
  44 + }
  45 +
  46 +}
0 47 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionExtMapper.java deleted
1   -package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
2   -
3   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
4   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
5   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6   -import org.apache.ibatis.annotations.Mapper;
7   -
8   -import java.util.Collection;
9   -import java.util.List;
10   -
11   -@Mapper
12   -public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
13   -
14   - default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
15   - return selectList("process_definition_id", processDefinitionIds);
16   - }
17   -
18   - default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
19   - return selectOne("process_definition_id", processDefinitionId);
20   - }
21   -
22   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/definition/BpmProcessDefinitionInfoMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.dal.mysql.definition;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +@Mapper
  11 +public interface BpmProcessDefinitionInfoMapper extends BaseMapperX<BpmProcessDefinitionInfoDO> {
  12 +
  13 + default List<BpmProcessDefinitionInfoDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
  14 + return selectList(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionIds);
  15 + }
  16 +
  17 + default BpmProcessDefinitionInfoDO selectByProcessDefinitionId(String processDefinitionId) {
  18 + return selectOne(BpmProcessDefinitionInfoDO::getProcessDefinitionId, processDefinitionId);
  19 + }
  20 +
  21 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmProcessInstanceCopyMapper.java
1   -package cn.iocoder.yudao.module.bpm.dal.mysql.cc;
  1 +package cn.iocoder.yudao.module.bpm.dal.mysql.task;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
7   -import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
  7 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
8 8 import org.apache.ibatis.annotations.Mapper;
9 9  
10 10 @Mapper
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.Collection;
  10 +import java.util.List;
  11 +import java.util.Map;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  14 +
  15 +/**
  16 + * BPM 流程分类 Service 接口
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +public interface BpmCategoryService {
  21 +
  22 + /**
  23 + * 创建流程分类
  24 + *
  25 + * @param createReqVO 创建信息
  26 + * @return 编号
  27 + */
  28 + Long createCategory(@Valid BpmCategorySaveReqVO createReqVO);
  29 +
  30 + /**
  31 + * 更新流程分类
  32 + *
  33 + * @param updateReqVO 更新信息
  34 + */
  35 + void updateCategory(@Valid BpmCategorySaveReqVO updateReqVO);
  36 +
  37 + /**
  38 + * 删除流程分类
  39 + *
  40 + * @param id 编号
  41 + */
  42 + void deleteCategory(Long id);
  43 +
  44 + /**
  45 + * 获得流程分类
  46 + *
  47 + * @param id 编号
  48 + * @return BPM 流程分类
  49 + */
  50 + BpmCategoryDO getCategory(Long id);
  51 +
  52 + /**
  53 + * 获得流程分类分页
  54 + *
  55 + * @param pageReqVO 分页查询
  56 + * @return 流程分类分页
  57 + */
  58 + PageResult<BpmCategoryDO> getCategoryPage(BpmCategoryPageReqVO pageReqVO);
  59 +
  60 + /**
  61 + * 获得流程分类 Map,基于指定编码
  62 + *
  63 + * @param codes 编号数组
  64 + * @return 流程分类 Map
  65 + */
  66 + default Map<String, BpmCategoryDO> getCategoryMap(Collection<String> codes) {
  67 + return convertMap(getCategoryListByCode(codes), BpmCategoryDO::getCode);
  68 + }
  69 +
  70 + /**
  71 + * 获得流程分类列表,基于指定编码
  72 + *
  73 + * @return 流程分类列表
  74 + */
  75 + List<BpmCategoryDO> getCategoryListByCode(Collection<String> codes);
  76 +
  77 + /**
  78 + * 获得流程分类列表,基于指定状态
  79 + *
  80 + * @param status 状态
  81 + * @return 流程分类列表
  82 + */
  83 + List<BpmCategoryDO> getCategoryListByStatus(Integer status);
  84 +
  85 +}
0 86 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmCategoryServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.definition;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
  5 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
  6 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
  7 +import org.springframework.stereotype.Service;
  8 +import jakarta.annotation.Resource;
  9 +import org.springframework.validation.annotation.Validated;
  10 +
  11 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  12 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  13 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  14 +
  15 +import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;
  16 +
  17 +import java.util.Collection;
  18 +import java.util.Collections;
  19 +import java.util.List;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  22 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  23 +
  24 +/**
  25 + * BPM 流程分类 Service 实现类
  26 + *
  27 + * @author 芋道源码
  28 + */
  29 +@Service
  30 +@Validated
  31 +public class BpmCategoryServiceImpl implements BpmCategoryService {
  32 +
  33 + @Resource
  34 + private BpmCategoryMapper bpmCategoryMapper;
  35 +
  36 + @Override
  37 + public Long createCategory(BpmCategorySaveReqVO createReqVO) {
  38 + // 校验唯一
  39 + validateCategoryNameUnique(createReqVO);
  40 + validateCategoryCodeUnique(createReqVO);
  41 + // 插入
  42 + BpmCategoryDO category = BeanUtils.toBean(createReqVO, BpmCategoryDO.class);
  43 + bpmCategoryMapper.insert(category);
  44 + return category.getId();
  45 + }
  46 +
  47 + @Override
  48 + public void updateCategory(BpmCategorySaveReqVO updateReqVO) {
  49 + // 校验存在
  50 + validateCategoryExists(updateReqVO.getId());
  51 + validateCategoryNameUnique(updateReqVO);
  52 + validateCategoryCodeUnique(updateReqVO);
  53 + // 更新
  54 + BpmCategoryDO updateObj = BeanUtils.toBean(updateReqVO, BpmCategoryDO.class);
  55 + bpmCategoryMapper.updateById(updateObj);
  56 + }
  57 +
  58 + private void validateCategoryNameUnique(BpmCategorySaveReqVO updateReqVO) {
  59 + BpmCategoryDO category = bpmCategoryMapper.selectByName(updateReqVO.getName());
  60 + if (category == null
  61 + || ObjUtil.equal(category.getId(), updateReqVO.getId())) {
  62 + return;
  63 + }
  64 + throw exception(CATEGORY_NAME_DUPLICATE, updateReqVO.getName());
  65 + }
  66 +
  67 + private void validateCategoryCodeUnique(BpmCategorySaveReqVO updateReqVO) {
  68 + BpmCategoryDO category = bpmCategoryMapper.selectByCode(updateReqVO.getCode());
  69 + if (category == null
  70 + || ObjUtil.equal(category.getId(), updateReqVO.getId())) {
  71 + return;
  72 + }
  73 + throw exception(CATEGORY_CODE_DUPLICATE, updateReqVO.getCode());
  74 + }
  75 +
  76 + @Override
  77 + public void deleteCategory(Long id) {
  78 + // 校验存在
  79 + validateCategoryExists(id);
  80 + // 删除
  81 + bpmCategoryMapper.deleteById(id);
  82 + }
  83 +
  84 + private void validateCategoryExists(Long id) {
  85 + if (bpmCategoryMapper.selectById(id) == null) {
  86 + throw exception(CATEGORY_NOT_EXISTS);
  87 + }
  88 + }
  89 +
  90 + @Override
  91 + public BpmCategoryDO getCategory(Long id) {
  92 + return bpmCategoryMapper.selectById(id);
  93 + }
  94 +
  95 + @Override
  96 + public PageResult<BpmCategoryDO> getCategoryPage(BpmCategoryPageReqVO pageReqVO) {
  97 + return bpmCategoryMapper.selectPage(pageReqVO);
  98 + }
  99 +
  100 + @Override
  101 + public List<BpmCategoryDO> getCategoryListByCode(Collection<String> codes) {
  102 + if (CollUtil.isEmpty(codes)) {
  103 + return Collections.emptyList();
  104 + }
  105 + return bpmCategoryMapper.selectListByCode(codes);
  106 + }
  107 +
  108 + @Override
  109 + public List<BpmCategoryDO> getCategoryListByStatus(Integer status) {
  110 + return bpmCategoryMapper.selectListByStatus(status);
  111 + }
  112 +
  113 +}
0 114 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormService.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 5 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormCreateReqVO;
5 6 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormPageReqVO;
6 7 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.form.BpmFormUpdateReqVO;
7 8 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
8   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
9   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
10   -
11 9 import jakarta.validation.Valid;
  10 +
12 11 import java.util.Collection;
13   -import java.util.Collections;
14 12 import java.util.List;
15 13 import java.util.Map;
16 14  
... ... @@ -74,9 +72,6 @@ public interface BpmFormService {
74 72 * @return 动态表单 Map
75 73 */
76 74 default Map<Long, BpmFormDO> getFormMap(Collection<Long> ids) {
77   - if (CollUtil.isEmpty(ids)) {
78   - return Collections.emptyMap();
79   - }
80 75 return CollectionUtils.convertMap(this.getFormList(ids), BpmFormDO::getId);
81 76 }
82 77  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmFormServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.lang.Assert;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 6 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
... ... @@ -80,6 +81,9 @@ public class BpmFormServiceImpl implements BpmFormService {
80 81  
81 82 @Override
82 83 public List<BpmFormDO> getFormList(Collection<Long> ids) {
  84 + if (CollUtil.isEmpty(ids)) {
  85 + return Collections.emptyList();
  86 + }
83 87 return formMapper.selectBatchIds(ids);
84 88 }
85 89  
... ... @@ -88,7 +92,7 @@ public class BpmFormServiceImpl implements BpmFormService {
88 92 return formMapper.selectPage(pageReqVO);
89 93 }
90 94  
91   -
  95 + // TODO @芋艿:这里没搞完!
92 96 @Override
93 97 public BpmFormDO checkFormConfig(String configStr) {
94 98 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(configStr, BpmModelMetaInfoRespDTO.class);
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
5 5 import jakarta.validation.Valid;
6 6 import org.flowable.bpmn.model.BpmnModel;
  7 +import org.flowable.engine.repository.Model;
7 8  
8 9 /**
9 10 * Flowable流程模型接口
... ... @@ -18,7 +19,7 @@ public interface BpmModelService {
18 19 * @param pageVO 分页查询
19 20 * @return 流程模型分页
20 21 */
21   - PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO);
  22 + PageResult<Model> getModelPage(BpmModelPageReqVO pageVO);
22 23  
23 24 /**
24 25 * 创建流程模型
... ... @@ -35,7 +36,15 @@ public interface BpmModelService {
35 36 * @param id 编号
36 37 * @return 流程模型
37 38 */
38   - BpmModelRespVO getModel(String id);
  39 + Model getModel(String id);
  40 +
  41 + /**
  42 + * 获得流程模型的 BPMN XML
  43 + *
  44 + * @param id 编号
  45 + * @return BPMN XML
  46 + */
  47 + byte[] getModelBpmnXML(String id);
39 48  
40 49 /**
41 50 * 修改流程模型
... ... @@ -67,14 +76,6 @@ public interface BpmModelService {
67 76 void updateModelState(String id, Integer state);
68 77  
69 78 /**
70   - * 获得流程模型编号对应的 BPMN Model
71   - *
72   - * @param id 流程模型编号
73   - * @return BPMN Model
74   - */
75   - BpmnModel getBpmnModel(String id);
76   -
77   - /**
78 79 * 获得流程定义编号对应的 BPMN Model
79 80 *
80 81 * @param processDefinitionId 流程定义编号
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
... ... @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
7 6 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
8 7 import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
9   -import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
10 8 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
11   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.*;
  9 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelCreateReqVO;
  10 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelPageReqVO;
  11 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelUpdateReqVO;
12 12 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
13 13 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
14 14 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
... ... @@ -21,7 +21,6 @@ import lombok.extern.slf4j.Slf4j;
21 21 import org.flowable.bpmn.model.BpmnModel;
22 22 import org.flowable.common.engine.impl.db.SuspensionState;
23 23 import org.flowable.engine.RepositoryService;
24   -import org.flowable.engine.repository.Deployment;
25 24 import org.flowable.engine.repository.Model;
26 25 import org.flowable.engine.repository.ModelQuery;
27 26 import org.flowable.engine.repository.ProcessDefinition;
... ... @@ -30,10 +29,10 @@ import org.springframework.transaction.annotation.Transactional;
30 29 import org.springframework.util.ObjectUtils;
31 30 import org.springframework.validation.annotation.Validated;
32 31  
33   -import java.util.*;
  32 +import java.util.List;
  33 +import java.util.Objects;
34 34  
35 35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
36   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
37 36 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
38 37  
39 38 /**
... ... @@ -60,7 +59,7 @@ public class BpmModelServiceImpl implements BpmModelService {
60 59 private BpmTaskCandidateInvoker taskCandidateInvoker;
61 60  
62 61 @Override
63   - public PageResult<BpmModelPageItemRespVO> getModelPage(BpmModelPageReqVO pageVO) {
  62 + public PageResult<Model> getModelPage(BpmModelPageReqVO pageVO) {
64 63 ModelQuery modelQuery = repositoryService.createModelQuery();
65 64 if (StrUtil.isNotBlank(pageVO.getKey())) {
66 65 modelQuery.modelKey(pageVO.getKey());
... ... @@ -72,34 +71,21 @@ public class BpmModelServiceImpl implements BpmModelService {
72 71 modelQuery.modelCategory(pageVO.getCategory());
73 72 }
74 73 // 执行查询
75   - List<Model> models = modelQuery.modelTenantId(TenantContextHolder.getTenantIdStr())
  74 + long count = modelQuery.count();
  75 + if (count == 0) {
  76 + return PageResult.empty(count);
  77 + }
  78 + List<Model> models = modelQuery
  79 + .modelTenantId(TenantContextHolder.getTenantIdStr())
76 80 .orderByCreateTime().desc()
77 81 .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
78   -
79   - // 获得 Form Map
80   - Set<Long> formIds = CollectionUtils.convertSet(models, model -> {
81   - BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(model.getMetaInfo(), BpmModelMetaInfoRespDTO.class);
82   - return metaInfo != null ? metaInfo.getFormId() : null;
83   - });
84   - Map<Long, BpmFormDO> formMap = bpmFormService.getFormMap(formIds);
85   -
86   - // 获得 Deployment Map
87   - Set<String> deploymentIds = new HashSet<>();
88   - models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
89   - Map<String, Deployment> deploymentMap = processDefinitionService.getDeploymentMap(deploymentIds);
90   - // 获得 ProcessDefinition Map
91   - List<ProcessDefinition> processDefinitions = processDefinitionService.getProcessDefinitionListByDeploymentIds(deploymentIds);
92   - Map<String, ProcessDefinition> processDefinitionMap = convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
93   -
94   - // 拼接结果
95   - long modelCount = modelQuery.count();
96   - return new PageResult<>(BpmModelConvert.INSTANCE.convertList(models, formMap, deploymentMap, processDefinitionMap), modelCount);
  82 + return new PageResult<>(models, count);
97 83 }
98 84  
99 85 @Override
100 86 @Transactional(rollbackFor = Exception.class)
101 87 public String createModel(@Valid BpmModelCreateReqVO createReqVO, String bpmnXml) {
102   - checkKeyNCName(createReqVO.getKey());
  88 + validateKeyNCName(createReqVO.getKey());
103 89 // 校验流程标识已经存在
104 90 Model keyModel = getModelByKey(createReqVO.getKey());
105 91 if (keyModel != null) {
... ... @@ -108,7 +94,7 @@ public class BpmModelServiceImpl implements BpmModelService {
108 94  
109 95 // 创建流程定义
110 96 Model model = repositoryService.newModel();
111   - BpmModelConvert.INSTANCE.copy(model, createReqVO);
  97 + BpmModelConvert.INSTANCE.copyToCreateModel(model, createReqVO);
112 98 model.setTenantId(TenantContextHolder.getTenantIdStr());
113 99 // 保存流程定义
114 100 repositoryService.saveModel(model);
... ... @@ -117,34 +103,17 @@ public class BpmModelServiceImpl implements BpmModelService {
117 103 return model.getId();
118 104 }
119 105  
120   - private Model getModelByKey(String key) {
121   - return repositoryService.createModelQuery().modelKey(key).singleResult();
122   - }
123   -
124   - @Override
125   - public BpmModelRespVO getModel(String id) {
126   - Model model = repositoryService.getModel(id);
127   - if (model == null) {
128   - return null;
129   - }
130   - BpmModelRespVO modelRespVO = BpmModelConvert.INSTANCE.convert(model);
131   - // 拼接 bpmn XML
132   - byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
133   - modelRespVO.setBpmnXml(StrUtil.utf8Str(bpmnBytes));
134   - return modelRespVO;
135   - }
136   -
137 106 @Override
138 107 @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
139 108 public void updateModel(@Valid BpmModelUpdateReqVO updateReqVO) {
140 109 // 校验流程模型存在
141   - Model model = repositoryService.getModel(updateReqVO.getId());
  110 + Model model = getModel(updateReqVO.getId());
142 111 if (model == null) {
143 112 throw exception(MODEL_NOT_EXISTS);
144 113 }
145 114  
146 115 // 修改流程定义
147   - BpmModelConvert.INSTANCE.copy(model, updateReqVO);
  116 + BpmModelConvert.INSTANCE.copyToUpdateModel(model, updateReqVO);
148 117 // 更新模型
149 118 repositoryService.saveModel(model);
150 119 // 更新 BPMN XML
... ... @@ -155,18 +124,18 @@ public class BpmModelServiceImpl implements BpmModelService {
155 124 @Transactional(rollbackFor = Exception.class) // 因为进行多个操作,所以开启事务
156 125 public void deployModel(String id) {
157 126 // 1.1 校验流程模型存在
158   - Model model = repositoryService.getModel(id);
  127 + Model model = getModel(id);
159 128 if (ObjectUtils.isEmpty(model)) {
160 129 throw exception(MODEL_NOT_EXISTS);
161 130 }
162 131 // 1.2 校验流程图
163 132 // TODO 芋艿:校验流程图的有效性;例如说,是否有开始的元素,是否有结束的元素;
164   - byte[] bpmnBytes = repositoryService.getModelEditorSource(model.getId());
  133 + byte[] bpmnBytes = getModelBpmnXML(model.getId());
165 134 if (bpmnBytes == null) {
166 135 throw exception(MODEL_NOT_EXISTS);
167 136 }
168 137 // 1.3 校验表单已配
169   - BpmFormDO form = checkFormConfig(model.getMetaInfo());
  138 + BpmFormDO form = validateFormConfig(model.getMetaInfo());
170 139 // 1.4 校验任务分配规则已配置
171 140 taskCandidateInvoker.validateBpmnConfig(bpmnBytes);
172 141  
... ... @@ -194,7 +163,7 @@ public class BpmModelServiceImpl implements BpmModelService {
194 163 @Transactional(rollbackFor = Exception.class)
195 164 public void deleteModel(String id) {
196 165 // 校验流程模型存在
197   - Model model = repositoryService.getModel(id);
  166 + Model model = getModel(id);
198 167 if (model == null) {
199 168 throw exception(MODEL_NOT_EXISTS);
200 169 }
... ... @@ -206,33 +175,27 @@ public class BpmModelServiceImpl implements BpmModelService {
206 175  
207 176 @Override
208 177 public void updateModelState(String id, Integer state) {
209   - // 校验流程模型存在
210   - Model model = repositoryService.getModel(id);
  178 + // 1.1 校验流程模型存在
  179 + Model model = getModel(id);
211 180 if (model == null) {
212 181 throw exception(MODEL_NOT_EXISTS);
213 182 }
214   - // 校验流程定义存在
  183 + // 1.2 校验流程定义存在
215 184 ProcessDefinition definition = processDefinitionService.getProcessDefinitionByDeploymentId(model.getDeploymentId());
216 185 if (definition == null) {
217 186 throw exception(PROCESS_DEFINITION_NOT_EXISTS);
218 187 }
219 188  
220   - // 更新状态
  189 + // 2. 更新状态
221 190 processDefinitionService.updateProcessDefinitionState(definition.getId(), state);
222 191 }
223 192  
224 193 @Override
225   - public BpmnModel getBpmnModel(String id) {
226   - byte[] bpmnBytes = repositoryService.getModelEditorSource(id);
227   - return BpmnModelUtils.getBpmnModel(bpmnBytes);
228   - }
229   -
230   - @Override
231 194 public BpmnModel getBpmnModelByDefinitionId(String processDefinitionId) {
232 195 return repositoryService.getBpmnModel(processDefinitionId);
233 196 }
234 197  
235   - private void checkKeyNCName(String key) {
  198 + private void validateKeyNCName(String key) {
236 199 if (!ValidationUtils.isXmlNCName(key)) {
237 200 throw exception(MODEL_KEY_VALID);
238 201 }
... ... @@ -244,7 +207,7 @@ public class BpmModelServiceImpl implements BpmModelService {
244 207 * @param metaInfoStr 流程模型 metaInfo 字段
245 208 * @return 流程表单
246 209 */
247   - private BpmFormDO checkFormConfig(String metaInfoStr) {
  210 + private BpmFormDO validateFormConfig(String metaInfoStr) {
248 211 BpmModelMetaInfoRespDTO metaInfo = JsonUtils.parseObject(metaInfoStr, BpmModelMetaInfoRespDTO.class);
249 212 if (metaInfo == null || metaInfo.getFormType() == null) {
250 213 throw exception(MODEL_DEPLOY_FAIL_FORM_NOT_CONFIG);
... ... @@ -282,4 +245,18 @@ public class BpmModelServiceImpl implements BpmModelService {
282 245 processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
283 246 }
284 247  
  248 + private Model getModelByKey(String key) {
  249 + return repositoryService.createModelQuery().modelKey(key).singleResult();
  250 + }
  251 +
  252 + @Override
  253 + public Model getModel(String id) {
  254 + return repositoryService.getModel(id);
  255 + }
  256 +
  257 + @Override
  258 + public byte[] getModelBpmnXML(String id) {
  259 + return repositoryService.getModelEditorSource(id);
  260 + }
  261 +
285 262 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionService.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
5   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
6 4 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
7   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
8   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
  5 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
9 6 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
10 7 import jakarta.validation.Valid;
11   -import org.flowable.bpmn.model.BpmnModel;
12 8 import org.flowable.engine.repository.Deployment;
13 9 import org.flowable.engine.repository.ProcessDefinition;
14 10  
  11 +import java.util.Collection;
15 12 import java.util.List;
16 13 import java.util.Map;
17 14 import java.util.Set;
... ... @@ -33,15 +30,15 @@ public interface BpmProcessDefinitionService {
33 30 * @param pageReqVO 分页入参
34 31 * @return 流程定义 Page
35 32 */
36   - PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
  33 + PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageReqVO);
37 34  
38 35 /**
39 36 * 获得流程定义列表
40 37 *
41   - * @param listReqVO 列表入参
  38 + * @param suspensionState 中断状态
42 39 * @return 流程定义列表
43 40 */
44   - List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO);
  41 + List<ProcessDefinition> getProcessDefinitionListBySuspensionState(Integer suspensionState);
45 42  
46 43 /**
47 44 * 创建流程定义
... ... @@ -68,20 +65,24 @@ public interface BpmProcessDefinitionService {
68 65 String getProcessDefinitionBpmnXML(String id);
69 66  
70 67 /**
71   - * 获得需要创建的流程定义,是否和当前激活的流程定义相等
  68 + * 获得流程定义的信息
72 69 *
73   - * @param createReqDTO 创建信息
74   - * @return 是否相等
  70 + * @param id 流程定义编号
  71 + * @return 流程定义信息
75 72 */
76   - boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO);
  73 + BpmProcessDefinitionInfoDO getProcessDefinitionInfo(String id);
77 74  
78 75 /**
79   - * 获得编号对应的 BpmProcessDefinitionExtDO
  76 + * 获得流程定义的信息 List
80 77 *
81   - * @param id 编号
82   - * @return 流程定义拓展
  78 + * @param ids 流程定义编号数组
  79 + * @return 流程额定义信息数组
83 80 */
84   - BpmProcessDefinitionExtDO getProcessDefinitionExt(String id);
  81 + List<BpmProcessDefinitionInfoDO> getProcessDefinitionInfoList(Collection<String> ids);
  82 +
  83 + default Map<String, BpmProcessDefinitionInfoDO> getProcessDefinitionInfoMap(Set<String> ids) {
  84 + return convertMap(getProcessDefinitionInfoList(ids), BpmProcessDefinitionInfoDO::getProcessDefinitionId);
  85 + }
85 86  
86 87 /**
87 88 * 获得编号对应的 ProcessDefinition
... ... @@ -153,11 +154,4 @@ public interface BpmProcessDefinitionService {
153 154 */
154 155 Deployment getDeployment(String id);
155 156  
156   - /**
157   - * 获得 Bpmn 模型
158   - *
159   - * @param processDefinitionId 流程定义的编号
160   - * @return Bpmn 模型
161   - */
162   - BpmnModel getBpmnModel(String processDefinitionId);
163 157 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
1 1 package cn.iocoder.yudao.module.bpm.service.definition;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.util.ObjectUtil;
5 4 import cn.hutool.core.util.StrUtil;
6 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 6 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
8   -import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
9   -import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
10 7 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
11   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionListReqVO;
12   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageItemRespVO;
13 8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
14   -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
15 9 import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
16   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
17   -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO;
18   -import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionExtMapper;
  10 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
  11 +import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmProcessDefinitionInfoMapper;
  12 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
19 13 import cn.iocoder.yudao.module.bpm.service.definition.dto.BpmProcessDefinitionCreateReqDTO;
20 14 import jakarta.annotation.Resource;
21 15 import jakarta.validation.Valid;
... ... @@ -33,7 +27,7 @@ import org.springframework.validation.annotation.Validated;
33 27 import java.util.*;
34 28  
35 29 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
36   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.addIfNotNull;
37 31 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
38 32 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
39 33 import static java.util.Collections.emptyList;
... ... @@ -55,10 +49,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
55 49 private RepositoryService repositoryService;
56 50  
57 51 @Resource
58   - private BpmProcessDefinitionExtMapper processDefinitionMapper;
59   -
60   - @Resource
61   - private BpmFormService formService;
  52 + private BpmProcessDefinitionInfoMapper processDefinitionMapper;
62 53  
63 54 @Override
64 55 public ProcessDefinition getProcessDefinition(String id) {
... ... @@ -112,11 +103,6 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
112 103 }
113 104  
114 105 @Override
115   - public BpmnModel getBpmnModel(String processDefinitionId) {
116   - return repositoryService.getBpmnModel(processDefinitionId);
117   - }
118   -
119   - @Override
120 106 public String createProcessDefinition(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) {
121 107 // 创建 Deployment 部署
122 108 Deployment deploy = repositoryService.createDeployment()
... ... @@ -141,7 +127,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
141 127 }
142 128  
143 129 // 插入拓展表
144   - BpmProcessDefinitionExtDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO)
  130 + BpmProcessDefinitionInfoDO definitionDO = BpmProcessDefinitionConvert.INSTANCE.convert2(createReqDTO)
145 131 .setProcessDefinitionId(definition.getId());
146 132 processDefinitionMapper.insert(definitionDO);
147 133 return definition.getId();
... ... @@ -175,101 +161,43 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
175 161 }
176 162  
177 163 @Override
178   - public boolean isProcessDefinitionEquals(@Valid BpmProcessDefinitionCreateReqDTO createReqDTO) {
179   - // 校验 name、description 是否更新
180   - ProcessDefinition oldProcessDefinition = getActiveProcessDefinition(createReqDTO.getKey());
181   - if (oldProcessDefinition == null) {
182   - return false;
183   - }
184   - BpmProcessDefinitionExtDO oldProcessDefinitionExt = getProcessDefinitionExt(oldProcessDefinition.getId());
185   - if (!StrUtil.equals(createReqDTO.getName(), oldProcessDefinition.getName())
186   - || !StrUtil.equals(createReqDTO.getDescription(), oldProcessDefinitionExt.getDescription())
187   - || !StrUtil.equals(createReqDTO.getCategory(), oldProcessDefinition.getCategory())) {
188   - return false;
189   - }
190   - // 校验 form 信息是否更新
191   - if (!ObjectUtil.equal(createReqDTO.getFormType(), oldProcessDefinitionExt.getFormType())
192   - || !ObjectUtil.equal(createReqDTO.getFormId(), oldProcessDefinitionExt.getFormId())
193   - || !ObjectUtil.equal(createReqDTO.getFormConf(), oldProcessDefinitionExt.getFormConf())
194   - || !ObjectUtil.equal(createReqDTO.getFormFields(), oldProcessDefinitionExt.getFormFields())
195   - || !ObjectUtil.equal(createReqDTO.getFormCustomCreatePath(), oldProcessDefinitionExt.getFormCustomCreatePath())
196   - || !ObjectUtil.equal(createReqDTO.getFormCustomViewPath(), oldProcessDefinitionExt.getFormCustomViewPath())) {
197   - return false;
198   - }
199   - // 校验 BPMN XML 信息
200   - BpmnModel newModel = BpmnModelUtils.getBpmnModel(createReqDTO.getBpmnBytes());
201   - BpmnModel oldModel = getBpmnModel(oldProcessDefinition.getId());
202   - // 对比字节变化
203   - if (!BpmnModelUtils.equals(oldModel, newModel)) {
204   - return false;
205   - }
206   - // 最终发现都一致,则返回 true
207   - return true;
  164 + public BpmProcessDefinitionInfoDO getProcessDefinitionInfo(String id) {
  165 + return processDefinitionMapper.selectByProcessDefinitionId(id);
208 166 }
209 167  
210 168 @Override
211   - public BpmProcessDefinitionExtDO getProcessDefinitionExt(String id) {
212   - return processDefinitionMapper.selectByProcessDefinitionId(id);
  169 + public List<BpmProcessDefinitionInfoDO> getProcessDefinitionInfoList(Collection<String> ids) {
  170 + return processDefinitionMapper.selectListByProcessDefinitionIds(ids);
213 171 }
214 172  
215 173 @Override
216   - public List<BpmProcessDefinitionRespVO> getProcessDefinitionList(BpmProcessDefinitionListReqVO listReqVO) {
217   - // 拼接查询条件
218   - ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
219   - if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), listReqVO.getSuspensionState())) {
220   - definitionQuery.suspended();
221   - } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), listReqVO.getSuspensionState())) {
222   - definitionQuery.active();
  174 + public PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
  175 + ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
  176 + if (StrUtil.isNotBlank(pageVO.getKey())) {
  177 + query.processDefinitionKey(pageVO.getKey());
223 178 }
224 179 // 执行查询
225   - definitionQuery.processDefinitionTenantId(TenantContextHolder.getTenantIdStr());
226   - List<ProcessDefinition> processDefinitions = definitionQuery.list();
227   - if (CollUtil.isEmpty(processDefinitions)) {
228   - return Collections.emptyList();
  180 + long count = query.count();
  181 + if (count == 0) {
  182 + return PageResult.empty(count);
229 183 }
230   -
231   - // 获得 BpmProcessDefinitionDO Map
232   - List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
233   - convertList(processDefinitions, ProcessDefinition::getId));
234   - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
235   - BpmProcessDefinitionExtDO::getProcessDefinitionId);
236   - // 执行查询,并返回
237   - return BpmProcessDefinitionConvert.INSTANCE.convertList3(processDefinitions, processDefinitionDOMap);
  184 + List<ProcessDefinition> list = query.orderByProcessDefinitionVersion().desc()
  185 + .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
  186 + return new PageResult<>(list, count);
238 187 }
239 188  
240 189 @Override
241   - public PageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
242   - ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
243   - if (StrUtil.isNotBlank(pageVO.getKey())) {
244   - definitionQuery.processDefinitionKey(pageVO.getKey());
  190 + public List<ProcessDefinition> getProcessDefinitionListBySuspensionState(Integer suspensionState) {
  191 + // 拼接查询条件
  192 + ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
  193 + if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), suspensionState)) {
  194 + query.suspended();
  195 + } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), suspensionState)) {
  196 + query.active();
245 197 }
246   -
247 198 // 执行查询
248   - List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion().desc()
249   - .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
250   -
251   - if (CollUtil.isEmpty(processDefinitions)) {
252   - return new PageResult<>(emptyList(), definitionQuery.count());
253   - }
254   - // 获得 Deployment Map
255   - Set<String> deploymentIds = new HashSet<>();
256   - processDefinitions.forEach(definition -> addIfNotNull(deploymentIds, definition.getDeploymentId()));
257   - Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
258   -
259   - // 获得 BpmProcessDefinitionDO Map
260   - List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionMapper.selectListByProcessDefinitionIds(
261   - convertList(processDefinitions, ProcessDefinition::getId));
262   - Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
263   - BpmProcessDefinitionExtDO::getProcessDefinitionId);
264   -
265   - // 获得 Form Map
266   - Set<Long> formIds = convertSet(processDefinitionDOs, BpmProcessDefinitionExtDO::getFormId);
267   - Map<Long, BpmFormDO> formMap = formService.getFormMap(formIds);
268   -
269   - // 拼接结果
270   - long definitionCount = definitionQuery.count();
271   - return new PageResult<>(BpmProcessDefinitionConvert.INSTANCE.convertList(processDefinitions, deploymentMap,
272   - processDefinitionDOMap, formMap), definitionCount);
  199 + query.processDefinitionTenantId(TenantContextHolder.getTenantIdStr());
  200 + return query.list();
273 201 }
274 202  
275 203 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/dto/BpmProcessDefinitionCreateReqDTO.java
... ... @@ -40,7 +40,6 @@ public class BpmProcessDefinitionCreateReqDTO {
40 40 private String description;
41 41 /**
42 42 * 流程分类
43   - * 参见 bpm_model_category 数据字典
44 43 */
45 44 @NotEmpty(message = "流程分类不能为空")
46 45 private String category;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyService.java
... ... @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.task;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
5   -import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
  5 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
6 6  
7 7 import java.util.Collection;
8 8  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceCopyServiceImpl.java
... ... @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.bpm.service.task;
3 3 import cn.hutool.core.util.ObjectUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCopyPageReqVO;
6   -import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO;
7   -import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper;
  6 +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceCopyDO;
  7 +import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmProcessInstanceCopyMapper;
8 8 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
9 9 import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
10 10 import jakarta.annotation.Resource;
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
1   -package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; import cn.iocoder.yudao.framework.flowable.core.context.FlowableContextHolder; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionExtDO; import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import jakarta.annotation.Resource; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private HistoryService historyService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private BpmMessageService messageService; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery() .includeProcessVariables() .processInstanceId(id) .singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<HistoricProcessInstance> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery().includeProcessVariables() .startedBy(String.valueOf(userId)) .orderByProcessInstanceStartTime().desc(); if (StrUtil.isNotEmpty(pageReqVO.getName())) { processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionId())) { processInstanceQuery.processDefinitionId("%" + pageReqVO.getProcessDefinitionId() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getCategory())) { processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory()); } if (pageReqVO.getStatus() != null) { processInstanceQuery.variableValueEquals(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, pageReqVO.getStatus()); } if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) { processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0])); processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1])); } // 查询数量 long processInstanceCount = processInstanceQuery.count(); if (processInstanceCount == 0) { return PageResult.empty(processInstanceCount); } // 查询列表 List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), pageReqVO.getPageSize()); return new PageResult<>(processInstanceList, processInstanceCount); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null, createReqVO.getAssignee()); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey(), createReqDTO.getAssignee()); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey, Map<String, List<Long>> assignee) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 设置上下文信息 // TODO @hai:要不往 variables 存到一个全局固定 key 里,减少对上下文的依赖 FlowableContextHolder.setAssignee(assignee); // 创建流程实例 variables.put(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中 BpmProcessInstanceStatusEnum.RUNNING.getStatus()); ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); return instance.getId(); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionExtDO processDefinitionExt = processDefinitionService.getProcessDefinitionExt( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 1.1 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 1.2 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 2. 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmDeleteReasonEnum.CANCEL_PROCESS_INSTANCE.format(cancelReqVO.getReason())); // 3. 进一步的处理,交给 updateProcessInstanceCancel 方法 } @Override public void updateProcessInstanceWhenCancel(FlowableCancelledEvent event) { // 1. 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceReject 方法(审批不通过),已经进行更新了 if (BpmDeleteReasonEnum.isRejectReason((String) event.getCause())) { return; } // 2. 更新流程实例 status runtimeService.setVariable(event.getProcessInstanceId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.CANCEL.getStatus()); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.CANCEL.getStatus())); } @Override public void updateProcessInstanceWhenApprove(ProcessInstance instance) { // 1. 更新流程实例 status runtimeService.setVariable(instance.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.APPROVE.getStatus()); // 2. 发送流程被【通过】的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.APPROVE.getStatus())); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceReject(String id, String reason) { // 1. 更新流程实例 status runtimeService.setVariable(id, BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.REJECT.getStatus()); // 2. 删除流程实例,以实现驳回任务时,取消整个审批流程 ProcessInstance processInstance = getProcessInstance(id); deleteProcessInstance(id, StrUtil.format(BpmDeleteReasonEnum.REJECT_TASK.format(reason))); // 3. 发送流程被【不通过】的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 4. 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.REJECT.getStatus())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } @Override public List<Long> getAssigneeByProcessInstanceIdAndTaskDefinitionKey(String processInstanceId, String taskDefinitionKey) { // 1. 先从上下文获取,首次提交数据库中查询不到 List<Long> result = FlowableContextHolder.getAssigneeByTaskDefinitionKey(taskDefinitionKey); if (CollUtil.isNotEmpty(result)) { return result; } // 2. 从数据库中获取 // TODO @芋艿:指定审批人,这里的存储方案有问题,后续优化下 // BpmProcessInstanceExtDO instance = processInstanceExtMapper.selectByProcessInstanceId(processInstanceId); // if (instance == null) { // throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); // } // if (CollUtil.isNotEmpty(instance.getAssignee())) { // return instance.getAssignee().get(taskDefinitionKey); // } return Collections.emptyList(); } }
2 1 \ No newline at end of file
  2 +package cn.iocoder.yudao.module.bpm.service.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.PageUtils; import cn.iocoder.yudao.framework.flowable.core.context.FlowableContextHolder; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCancelReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.enums.task.BpmDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum; import cn.iocoder.yudao.module.bpm.framework.bpm.core.event.BpmProcessInstanceResultEventPublisher; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants; import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import jakarta.annotation.Resource; import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.event.FlowableCancelledEvent; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** * 流程实例 Service 实现类 * * ProcessDefinition & ProcessInstance & Execution & Task 的关系: * 1. <a href="https://blog.csdn.net/bobozai86/article/details/105210414" /> * * HistoricProcessInstance & ProcessInstance 的关系: * 1. <a href=" https://my.oschina.net/843294669/blog/71902" /> * * 简单来说,前者 = 历史 + 运行中的流程实例,后者仅是运行中的流程实例 * * @author 芋道源码 */ @Service @Validated @Slf4j public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService { @Resource private RuntimeService runtimeService; @Resource private HistoryService historyService; @Resource private BpmProcessDefinitionService processDefinitionService; @Resource private BpmMessageService messageService; @Resource private BpmProcessInstanceResultEventPublisher processInstanceResultEventPublisher; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @Override public ProcessInstance getProcessInstance(String id) { return runtimeService.createProcessInstanceQuery() .includeProcessVariables() .processInstanceId(id) .singleResult(); } @Override public List<ProcessInstance> getProcessInstances(Set<String> ids) { return runtimeService.createProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public HistoricProcessInstance getHistoricProcessInstance(String id) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(id).includeProcessVariables().singleResult(); } @Override public List<HistoricProcessInstance> getHistoricProcessInstances(Set<String> ids) { return historyService.createHistoricProcessInstanceQuery().processInstanceIds(ids).list(); } @Override public PageResult<HistoricProcessInstance> getMyProcessInstancePage(Long userId, BpmProcessInstanceMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 HistoricProcessInstanceQuery processInstanceQuery = historyService.createHistoricProcessInstanceQuery().includeProcessVariables() .startedBy(String.valueOf(userId)) .orderByProcessInstanceStartTime().desc(); if (StrUtil.isNotEmpty(pageReqVO.getName())) { processInstanceQuery.processInstanceNameLike("%" + pageReqVO.getName() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getProcessDefinitionId())) { processInstanceQuery.processDefinitionId("%" + pageReqVO.getProcessDefinitionId() + "%"); } if (StrUtil.isNotEmpty(pageReqVO.getCategory())) { processInstanceQuery.processDefinitionCategory(pageReqVO.getCategory()); } if (pageReqVO.getStatus() != null) { processInstanceQuery.variableValueEquals(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, pageReqVO.getStatus()); } if (ArrayUtil.isNotEmpty(pageReqVO.getCreateTime())) { processInstanceQuery.startedAfter(DateUtils.of(pageReqVO.getCreateTime()[0])); processInstanceQuery.startedBefore(DateUtils.of(pageReqVO.getCreateTime()[1])); } // 查询数量 long processInstanceCount = processInstanceQuery.count(); if (processInstanceCount == 0) { return PageResult.empty(processInstanceCount); } // 查询列表 List<HistoricProcessInstance> processInstanceList = processInstanceQuery.listPage(PageUtils.getStart(pageReqVO), pageReqVO.getPageSize()); return new PageResult<>(processInstanceList, processInstanceCount); } @Override @Transactional(rollbackFor = Exception.class) public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getProcessDefinition(createReqVO.getProcessDefinitionId()); // 发起流程 return createProcessInstance0(userId, definition, createReqVO.getVariables(), null, createReqVO.getAssignee()); } @Override public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO createReqDTO) { // 获得流程定义 ProcessDefinition definition = processDefinitionService.getActiveProcessDefinition(createReqDTO.getProcessDefinitionKey()); // 发起流程 return createProcessInstance0(userId, definition, createReqDTO.getVariables(), createReqDTO.getBusinessKey(), createReqDTO.getAssignee()); } private String createProcessInstance0(Long userId, ProcessDefinition definition, Map<String, Object> variables, String businessKey, Map<String, List<Long>> assignee) { // 校验流程定义 if (definition == null) { throw exception(PROCESS_DEFINITION_NOT_EXISTS); } if (definition.isSuspended()) { throw exception(PROCESS_DEFINITION_IS_SUSPENDED); } // 设置上下文信息 // TODO @hai:要不往 variables 存到一个全局固定 key 里,减少对上下文的依赖 FlowableContextHolder.setAssignee(assignee); // 创建流程实例 variables.put(BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, // 流程实例状态:审批中 BpmProcessInstanceStatusEnum.RUNNING.getStatus()); ProcessInstance instance = runtimeService.createProcessInstanceBuilder() .processDefinitionId(definition.getId()) .businessKey(businessKey) .name(definition.getName().trim()) .variables(variables) .start(); return instance.getId(); } @Override public BpmProcessInstanceRespVO getProcessInstanceVO(String id) { // 获得流程实例 HistoricProcessInstance processInstance = getHistoricProcessInstance(id); if (processInstance == null) { return null; } // 获得流程定义 ProcessDefinition processDefinition = processDefinitionService .getProcessDefinition(processInstance.getProcessDefinitionId()); Assert.notNull(processDefinition, "流程定义({}) 不存在", processInstance.getProcessDefinitionId()); BpmProcessDefinitionInfoDO processDefinitionExt = processDefinitionService.getProcessDefinitionInfo( processInstance.getProcessDefinitionId()); Assert.notNull(processDefinitionExt, "流程定义拓展({}) 不存在", id); String bpmnXml = processDefinitionService.getProcessDefinitionBpmnXML(processInstance.getProcessDefinitionId()); // 获得 User AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId())); DeptRespDTO dept = null; if (startUser != null) { dept = deptApi.getDept(startUser.getDeptId()); } // 拼接结果 return BpmProcessInstanceConvert.INSTANCE.convert2(processInstance, processDefinition, processDefinitionExt, bpmnXml, startUser, dept); } @Override public void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO) { // 1.1 校验流程实例存在 ProcessInstance instance = getProcessInstance(cancelReqVO.getId()); if (instance == null) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); } // 1.2 只能取消自己的 if (!Objects.equals(instance.getStartUserId(), String.valueOf(userId))) { throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_SELF); } // 2. 通过删除流程实例,实现流程实例的取消, // 删除流程实例,正则执行任务 ACT_RU_TASK. 任务会被删除。通过历史表查询 deleteProcessInstance(cancelReqVO.getId(), BpmDeleteReasonEnum.CANCEL_PROCESS_INSTANCE.format(cancelReqVO.getReason())); // 3. 进一步的处理,交给 updateProcessInstanceCancel 方法 } @Override public void updateProcessInstanceWhenCancel(FlowableCancelledEvent event) { // 1. 判断是否为 Reject 不通过。如果是,则不进行更新. // 因为,updateProcessInstanceReject 方法(审批不通过),已经进行更新了 if (BpmDeleteReasonEnum.isRejectReason((String) event.getCause())) { return; } // 2. 更新流程实例 status runtimeService.setVariable(event.getProcessInstanceId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.CANCEL.getStatus()); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(event.getProcessInstanceId()); // 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.CANCEL.getStatus())); } @Override public void updateProcessInstanceWhenApprove(ProcessInstance instance) { // 1. 更新流程实例 status runtimeService.setVariable(instance.getId(), BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.APPROVE.getStatus()); // 2. 发送流程被【通过】的消息 messageService.sendMessageWhenProcessInstanceApprove(BpmProcessInstanceConvert.INSTANCE.convert2ApprovedReq(instance)); // 3. 发送流程实例的状态事件 // 注意:此时如果去查询 ProcessInstance 的话,字段是不全的,所以去查询了 HistoricProcessInstance HistoricProcessInstance processInstance = getHistoricProcessInstance(instance.getId()); processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.APPROVE.getStatus())); } @Override @Transactional(rollbackFor = Exception.class) public void updateProcessInstanceReject(String id, String reason) { // 1. 更新流程实例 status runtimeService.setVariable(id, BpmConstants.PROCESS_INSTANCE_VARIABLE_STATUS, BpmProcessInstanceStatusEnum.REJECT.getStatus()); // 2. 删除流程实例,以实现驳回任务时,取消整个审批流程 ProcessInstance processInstance = getProcessInstance(id); deleteProcessInstance(id, StrUtil.format(BpmDeleteReasonEnum.REJECT_TASK.format(reason))); // 3. 发送流程被【不通过】的消息 messageService.sendMessageWhenProcessInstanceReject(BpmProcessInstanceConvert.INSTANCE.convert2RejectReq(processInstance, reason)); // 4. 发送流程实例的状态事件 processInstanceResultEventPublisher.sendProcessInstanceResultEvent( BpmProcessInstanceConvert.INSTANCE.convert(this, processInstance, BpmProcessInstanceStatusEnum.REJECT.getStatus())); } private void deleteProcessInstance(String id, String reason) { runtimeService.deleteProcessInstance(id, reason); } @Override public List<Long> getAssigneeByProcessInstanceIdAndTaskDefinitionKey(String processInstanceId, String taskDefinitionKey) { // 1. 先从上下文获取,首次提交数据库中查询不到 List<Long> result = FlowableContextHolder.getAssigneeByTaskDefinitionKey(taskDefinitionKey); if (CollUtil.isNotEmpty(result)) { return result; } // 2. 从数据库中获取 // TODO @芋艿:指定审批人,这里的存储方案有问题,后续优化下 // BpmProcessInstanceExtDO instance = processInstanceExtMapper.selectByProcessInstanceId(processInstanceId); // if (instance == null) { // throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS); // } // if (CollUtil.isNotEmpty(instance.getAssignee())) { // return instance.getAssignee().get(taskDefinitionKey); // } return Collections.emptyList(); } }
3 3 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/category/BpmCategoryMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
0 13 \ No newline at end of file
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/category/BpmCategoryServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.category;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategoryPageReqVO;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.category.BpmCategorySaveReqVO;
  5 +import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryServiceImpl;
  6 +import org.junit.jupiter.api.Disabled;
  7 +import org.junit.jupiter.api.Test;
  8 +
  9 +import jakarta.annotation.Resource;
  10 +
  11 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  12 +
  13 +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
  14 +import cn.iocoder.yudao.module.bpm.dal.mysql.category.BpmCategoryMapper;
  15 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  16 +
  17 +import org.springframework.context.annotation.Import;
  18 +
  19 +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
  20 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
  21 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  22 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*;
  23 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
  24 +import static org.junit.jupiter.api.Assertions.*;
  25 +
  26 +/**
  27 + * {@link BpmCategoryServiceImpl} 的单元测试类
  28 + *
  29 + * @author 芋道源码
  30 + */
  31 +@Import(BpmCategoryServiceImpl.class)
  32 +public class BpmCategoryServiceImplTest extends BaseDbUnitTest {
  33 +
  34 + @Resource
  35 + private BpmCategoryServiceImpl categoryService;
  36 +
  37 + @Resource
  38 + private BpmCategoryMapper categoryMapper;
  39 +
  40 + @Test
  41 + public void testCreateCategory_success() {
  42 + // 准备参数
  43 + BpmCategorySaveReqVO createReqVO = randomPojo(BpmCategorySaveReqVO.class).setId(null);
  44 +
  45 + // 调用
  46 + Long categoryId = categoryService.createCategory(createReqVO);
  47 + // 断言
  48 + assertNotNull(categoryId);
  49 + // 校验记录的属性是否正确
  50 + BpmCategoryDO category = categoryMapper.selectById(categoryId);
  51 + assertPojoEquals(createReqVO, category, "id");
  52 + }
  53 +
  54 + @Test
  55 + public void testUpdateCategory_success() {
  56 + // mock 数据
  57 + BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);
  58 + categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
  59 + // 准备参数
  60 + BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class, o -> {
  61 + o.setId(dbCategory.getId()); // 设置更新的 ID
  62 + });
  63 +
  64 + // 调用
  65 + categoryService.updateCategory(updateReqVO);
  66 + // 校验是否更新正确
  67 + BpmCategoryDO category = categoryMapper.selectById(updateReqVO.getId()); // 获取最新的
  68 + assertPojoEquals(updateReqVO, category);
  69 + }
  70 +
  71 + @Test
  72 + public void testUpdateCategory_notExists() {
  73 + // 准备参数
  74 + BpmCategorySaveReqVO updateReqVO = randomPojo(BpmCategorySaveReqVO.class);
  75 +
  76 + // 调用, 并断言异常
  77 + assertServiceException(() -> categoryService.updateCategory(updateReqVO), CATEGORY_NOT_EXISTS);
  78 + }
  79 +
  80 + @Test
  81 + public void testDeleteCategory_success() {
  82 + // mock 数据
  83 + BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class);
  84 + categoryMapper.insert(dbCategory);// @Sql: 先插入出一条存在的数据
  85 + // 准备参数
  86 + Long id = dbCategory.getId();
  87 +
  88 + // 调用
  89 + categoryService.deleteCategory(id);
  90 + // 校验数据不存在了
  91 + assertNull(categoryMapper.selectById(id));
  92 + }
  93 +
  94 + @Test
  95 + public void testDeleteCategory_notExists() {
  96 + // 准备参数
  97 + Long id = randomLongId();
  98 +
  99 + // 调用, 并断言异常
  100 + assertServiceException(() -> categoryService.deleteCategory(id), CATEGORY_NOT_EXISTS);
  101 + }
  102 +
  103 + @Test
  104 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  105 + public void testGetCategoryPage() {
  106 + // mock 数据
  107 + BpmCategoryDO dbCategory = randomPojo(BpmCategoryDO.class, o -> { // 等会查询到
  108 + o.setName(null);
  109 + o.setCode(null);
  110 + o.setStatus(null);
  111 + o.setCreateTime(null);
  112 + });
  113 + categoryMapper.insert(dbCategory);
  114 + // 测试 name 不匹配
  115 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setName(null)));
  116 + // 测试 code 不匹配
  117 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCode(null)));
  118 + // 测试 status 不匹配
  119 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setStatus(null)));
  120 + // 测试 createTime 不匹配
  121 + categoryMapper.insert(cloneIgnoreId(dbCategory, o -> o.setCreateTime(null)));
  122 + // 准备参数
  123 + BpmCategoryPageReqVO reqVO = new BpmCategoryPageReqVO();
  124 + reqVO.setName(null);
  125 + reqVO.setCode(null);
  126 + reqVO.setStatus(null);
  127 + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  128 +
  129 + // 调用
  130 + PageResult<BpmCategoryDO> pageResult = categoryService.getCategoryPage(reqVO);
  131 + // 断言
  132 + assertEquals(1, pageResult.getTotal());
  133 + assertEquals(1, pageResult.getList().size());
  134 + assertPojoEquals(dbCategory, pageResult.getList().get(0));
  135 + }
  136 +
  137 +}
0 138 \ No newline at end of file
... ...