From e09b8c6b9d89c87db3cadf2d76b4901c09bd52e5 Mon Sep 17 00:00:00 2001 From: aikai Date: Tue, 1 Jul 2025 14:09:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(bpm):=20=E6=B7=BB=E5=8A=A0=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=E6=98=A0=E5=B0=84=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增流程映射配置表和相关 SQL - 实现流程映射配置的 CRUD 接口和服务 - 添加流程数据动态查询功能 - 采用二级缓存架构(内存 + Redis)提高查询性能 --- sql/mysql/bmp_process_mapping_config.sql | 26 +++ .../module/bpm/enums/ErrorCodeConstants.java | 4 + .../BpmProcessMappingConfigController.java | 89 ++++++++ .../BpmProcessQueryController.java | 46 ++++ .../BpmProcessMappingConfigCreateReqVO.java | 47 ++++ .../vo/BpmProcessMappingConfigPageReqVO.java | 41 ++++ .../vo/BpmProcessMappingConfigRespVO.java | 30 +++ .../BpmProcessMappingConfigUpdateReqVO.java | 25 +++ .../vo/ProcessDataQueryReqVO.java | 34 +++ .../BpmProcessMappingConfigMapper.java | 32 +++ .../ProcessMappingConfigService.java | 69 ++++++ .../ProcessMappingConfigServiceImpl.java | 200 ++++++++++++++++++ .../processmapping/ProcessQueryService.java | 20 ++ .../ProcessQueryServiceImpl.java | 66 ++++++ 14 files changed, 729 insertions(+) create mode 100644 sql/mysql/bmp_process_mapping_config.sql create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessMappingConfigController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessQueryController.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigCreateReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigPageReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigRespVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigUpdateReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/ProcessDataQueryReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/processmapping/BpmProcessMappingConfigMapper.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryServiceImpl.java diff --git a/sql/mysql/bmp_process_mapping_config.sql b/sql/mysql/bmp_process_mapping_config.sql new file mode 100644 index 00000000..1f890e04 --- /dev/null +++ b/sql/mysql/bmp_process_mapping_config.sql @@ -0,0 +1,26 @@ +-- 流程映射配置表 +CREATE TABLE `bpm_process_mapping_config` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `process_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '流程唯一标识(如:ORDER,PAYMENT)', + `process_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '流程显示名称', + `table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '物理表名(如:order_info)', + `entity_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '实体类全限定名(如:com.example.order.OrderDO)', + `mapper_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Mapper接口全限定名(如:com.example.order.OrderMapper)', + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '流程描述', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_process_code` (`process_code`, `deleted`) COMMENT '流程代码唯一索引', + KEY `idx_tenant_id` (`tenant_id`) COMMENT '租户ID索引' +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='流程映射配置表'; + +-- 插入示例数据 +INSERT INTO `bpm_process_mapping_config` +(`process_code`, `process_name`, `table_name`, `entity_class`, `mapper_class`, `description`, `creator`, `tenant_id`) +VALUES +('LEAVE', '请假流程', 'bpm_oa_leave', 'cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOALeaveDO', 'cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOALeaveMapper', '员工请假申请流程配置', 'system', 0), +('REIMBURSEMENT', '报销流程', 'bpm_oa_reimbursement', 'cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO', 'cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAReimbursementMapper', '员工报销申请流程配置', 'system', 0); \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java index 62f4ccfe..8b228989 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ErrorCodeConstants.java @@ -129,4 +129,8 @@ public interface ErrorCodeConstants { ErrorCode BPM_SYSTEM_BUG = new ErrorCode(1_009_012_001, "系统问题,请联系管理员"); + + // ========== 流程映射配置模块 1-009-014-000 ========== + ErrorCode PROCESS_MAPPING_CONFIG_NOT_EXISTS = new ErrorCode(1_009_014_001, "流程映射配置不存在"); + ErrorCode PROCESS_MAPPING_CONFIG_CODE_DUPLICATE = new ErrorCode(1_009_014_002, "流程代码已存在,不允许重复"); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessMappingConfigController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessMappingConfigController.java new file mode 100644 index 00000000..c1d9ebdb --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessMappingConfigController.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigUpdateReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.processmapping.BpmProcessMappingConfigDO; +import cn.iocoder.yudao.module.bpm.service.processmapping.ProcessMappingConfigService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * 管理后台 - 流程映射配置 + * + * @author 系统 + */ +@Tag(name = "管理后台 - 流程映射配置") +@RestController +@RequestMapping("/bpm/process-mapping-config") +@Validated +@Slf4j +public class BpmProcessMappingConfigController { + + @Resource + private ProcessMappingConfigService processMappingConfigService; + + @PostMapping("/create") + @Operation(summary = "创建流程映射配置") + @PreAuthorize("@ss.hasPermission('bpm:process-mapping-config:create')") + public CommonResult createProcessMappingConfig(@Valid @RequestBody BpmProcessMappingConfigCreateReqVO createReqVO) { + return success(processMappingConfigService.createProcessMappingConfig(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新流程映射配置") + @PreAuthorize("@ss.hasPermission('bmp:process-mapping-config:update')") + public CommonResult updateProcessMappingConfig(@Valid @RequestBody BpmProcessMappingConfigUpdateReqVO updateReqVO) { + processMappingConfigService.updateProcessMappingConfig(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除流程映射配置") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('bpm:process-mapping-config:delete')") + public CommonResult deleteProcessMappingConfig(@RequestParam("id") Long id) { + processMappingConfigService.deleteProcessMappingConfig(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得流程映射配置") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('bpm:process-mapping-config:query')") + public CommonResult getProcessMappingConfig(@RequestParam("id") Long id) { + BpmProcessMappingConfigDO config = processMappingConfigService.getProcessMappingConfig(id); + return success(BeanUtils.toBean(config, BpmProcessMappingConfigRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得流程映射配置分页") + @PreAuthorize("@ss.hasPermission('bpm:process-mapping-config:query')") + public CommonResult> getProcessMappingConfigPage(@Valid BpmProcessMappingConfigPageReqVO pageReqVO) { + PageResult pageResult = processMappingConfigService.getProcessMappingConfigPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, BpmProcessMappingConfigRespVO.class)); + } + + @PostMapping("/refresh-cache") + @Operation(summary = "刷新流程映射配置缓存") + @PreAuthorize("@ss.hasPermission('bpm:process-mapping-config:update')") + public CommonResult refreshCache() { + processMappingConfigService.refreshCache(); + return success(true); + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessQueryController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessQueryController.java new file mode 100644 index 00000000..f523f0b0 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/BpmProcessQueryController.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.bpm.service.processmapping.ProcessQueryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.io.Serializable; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * 管理后台 - 流程数据查询 + * + * @author 系统 + */ +@Tag(name = "管理后台 - 流程数据查询") +@RestController +@RequestMapping("/bpm/process-query") +@Validated +@Slf4j +public class BpmProcessQueryController { + + @Resource + private ProcessQueryService processQueryService; + + @GetMapping("/data") + @Operation(summary = "根据流程代码和ID查询数据") + @Parameter(name = "processCode", description = "流程代码", required = true, example = "ORDER") + @Parameter(name = "id", description = "数据ID", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('bpm:process-query:data')") + public CommonResult getProcessData(@RequestParam("processCode") String processCode, + @RequestParam("id") Serializable id) { + Object result = processQueryService.queryById(processCode, id); + return success(result); + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigCreateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigCreateReqVO.java new file mode 100644 index 00000000..a45a1d81 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigCreateReqVO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +/** + * 流程映射配置创建 Request VO + * + * @author 系统 + */ +@Schema(description = "管理后台 - 流程映射配置创建 Request VO") +@Data +public class BpmProcessMappingConfigCreateReqVO { + + @Schema(description = "流程唯一标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "ORDER") + @NotBlank(message = "流程代码不能为空") + @Size(max = 64, message = "流程代码长度不能超过64个字符") + private String processCode; + + @Schema(description = "流程显示名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单流程") + @NotBlank(message = "流程名称不能为空") + @Size(max = 128, message = "流程名称长度不能超过128个字符") + private String processName; + + @Schema(description = "物理表名", requiredMode = Schema.RequiredMode.REQUIRED, example = "order_info") + @NotBlank(message = "表名不能为空") + @Size(max = 64, message = "表名长度不能超过64个字符") + private String tableName; + + @Schema(description = "实体类全限定名", requiredMode = Schema.RequiredMode.REQUIRED, example = "com.example.order.OrderDO") + @NotBlank(message = "实体类不能为空") + @Size(max = 255, message = "实体类长度不能超过255个字符") + private String entityClass; + + @Schema(description = "Mapper接口全限定名", requiredMode = Schema.RequiredMode.REQUIRED, example = "com.example.order.OrderMapper") + @NotBlank(message = "Mapper类不能为空") + @Size(max = 255, message = "Mapper类长度不能超过255个字符") + private String mapperClass; + + @Schema(description = "流程描述", example = "订单相关的业务流程") + @Size(max = 255, message = "描述长度不能超过255个字符") + private String description; + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigPageReqVO.java new file mode 100644 index 00000000..a3fd41de --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigPageReqVO.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 流程映射配置分页 Request VO + * + * @author 系统 + */ +@Schema(description = "管理后台 - 流程映射配置分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmProcessMappingConfigPageReqVO extends PageParam { + + @Schema(description = "流程代码", example = "ORDER") + private String processCode; + + @Schema(description = "流程名称", example = "订单流程") + private String processName; + + @Schema(description = "表名", example = "order_info") + private String tableName; + + @Schema(description = "实体类", example = "com.example.order.OrderDO") + private String entityClass; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigRespVO.java new file mode 100644 index 00000000..12936f8e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigRespVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.time.LocalDateTime; + +/** + * 流程映射配置 Response VO + * + * @author 系统 + */ +@Schema(description = "管理后台 - 流程映射配置 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmProcessMappingConfigRespVO extends BpmProcessMappingConfigCreateReqVO { + + @Schema(description = "配置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime updateTime; + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigUpdateReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigUpdateReqVO.java new file mode 100644 index 00000000..4d1cdb86 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/BpmProcessMappingConfigUpdateReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +/** + * 流程映射配置更新 Request VO + * + * @author 系统 + */ +@Schema(description = "管理后台 - 流程映射配置更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmProcessMappingConfigUpdateReqVO extends BpmProcessMappingConfigCreateReqVO { + + @Schema(description = "配置ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "配置ID不能为空") + private Long id; + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/ProcessDataQueryReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/ProcessDataQueryReqVO.java new file mode 100644 index 00000000..694e2846 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/processmapping/vo/ProcessDataQueryReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotBlank; +import java.io.Serializable; +import java.util.Map; + +/** + * 流程数据查询 Request VO + * + * @author 系统 + */ +@Schema(description = "管理后台 - 流程数据查询 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProcessDataQueryReqVO extends PageParam { + + @Schema(description = "流程代码", requiredMode = Schema.RequiredMode.REQUIRED, example = "ORDER") + @NotBlank(message = "流程代码不能为空") + private String processCode; + + @Schema(description = "数据ID", example = "1024") + private Serializable id; + + @Schema(description = "查询条件", example = "{\"status\": 1, \"name\": \"测试\"}") + private Map queryParams; + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/processmapping/BpmProcessMappingConfigMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/processmapping/BpmProcessMappingConfigMapper.java new file mode 100644 index 00000000..b88d8569 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/processmapping/BpmProcessMappingConfigMapper.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.bpm.dal.mysql.processmapping; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigPageReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.processmapping.BpmProcessMappingConfigDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 流程映射配置 Mapper + * + * @author 系统 + */ +@Mapper +public interface BpmProcessMappingConfigMapper extends BaseMapperX { + + default PageResult selectPage(BpmProcessMappingConfigPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(BpmProcessMappingConfigDO::getProcessCode, reqVO.getProcessCode()) + .likeIfPresent(BpmProcessMappingConfigDO::getProcessName, reqVO.getProcessName()) + .likeIfPresent(BpmProcessMappingConfigDO::getTableName, reqVO.getTableName()) + .likeIfPresent(BpmProcessMappingConfigDO::getEntityClass, reqVO.getEntityClass()) + .betweenIfPresent(BpmProcessMappingConfigDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(BpmProcessMappingConfigDO::getId)); + } + + default BpmProcessMappingConfigDO selectByProcessCode(String processCode) { + return selectOne(BpmProcessMappingConfigDO::getProcessCode, processCode); + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigService.java new file mode 100644 index 00000000..947d9ea2 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigService.java @@ -0,0 +1,69 @@ +package cn.iocoder.yudao.module.bpm.service.processmapping; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigUpdateReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.processmapping.BpmProcessMappingConfigDO; + +import javax.validation.Valid; + +/** + * 流程映射配置 Service 接口 + * + * @author 系统 + */ +public interface ProcessMappingConfigService { + + /** + * 创建流程映射配置 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createProcessMappingConfig(@Valid BpmProcessMappingConfigCreateReqVO createReqVO); + + /** + * 更新流程映射配置 + * + * @param updateReqVO 更新信息 + */ + void updateProcessMappingConfig(@Valid BpmProcessMappingConfigUpdateReqVO updateReqVO); + + /** + * 删除流程映射配置 + * + * @param id 编号 + */ + void deleteProcessMappingConfig(Long id); + + /** + * 获得流程映射配置 + * + * @param id 编号 + * @return 流程映射配置 + */ + BpmProcessMappingConfigDO getProcessMappingConfig(Long id); + + /** + * 根据流程代码获取配置 + * + * @param processCode 流程代码 + * @return 流程映射配置 + */ + BpmProcessMappingConfigDO getProcessMappingConfigByCode(String processCode); + + /** + * 获得流程映射配置分页 + * + * @param pageReqVO 分页查询 + * @return 流程映射配置分页 + */ + PageResult getProcessMappingConfigPage(BpmProcessMappingConfigPageReqVO pageReqVO); + + /** + * 刷新缓存 + */ + void refreshCache(); + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigServiceImpl.java new file mode 100644 index 00000000..4917cb4c --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessMappingConfigServiceImpl.java @@ -0,0 +1,200 @@ +package cn.iocoder.yudao.module.bpm.service.processmapping; + +import cn.hutool.core.bean.BeanUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.cache.CacheUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigCreateReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.processmapping.vo.BpmProcessMappingConfigUpdateReqVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.processmapping.BpmProcessMappingConfigDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.processmapping.BpmProcessMappingConfigMapper; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.Duration; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_MAPPING_CONFIG_NOT_EXISTS; + +/** + * 流程映射配置 Service 实现类 + * + * 使用二级缓存架构: + * 1. 一级缓存(内存):Google Guava LoadingCache,10分钟过期 + * 2. 二级缓存(Redis):Spring Cache,1小时过期 + * 3. 数据库:MySQL + * + * @author 系统 + */ +@Service +@Validated +@Slf4j +public class ProcessMappingConfigServiceImpl implements ProcessMappingConfigService { + + private static final String CACHE_KEY_PREFIX = "process_mapping_config"; + + @Resource + private BpmProcessMappingConfigMapper processMappingConfigMapper; + + /** + * 一级缓存(内存)- Google Guava LoadingCache + * 缓存key为processCode,缓存时间10分钟 + */ + @Getter + private final LoadingCache localCache = CacheUtils.buildAsyncReloadingCache( + Duration.ofMinutes(10L), + new CacheLoader() { + @Override + public BpmProcessMappingConfigDO load(String processCode) { + log.info("[load][一级缓存miss,从二级缓存加载] processCode={}", processCode); + // 从二级缓存(Redis)加载 + BpmProcessMappingConfigDO config = getFromRedisCache(processCode); + return config != null ? config : new BpmProcessMappingConfigDO(); // 避免缓存穿透 + } + }); + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createProcessMappingConfig(BpmProcessMappingConfigCreateReqVO createReqVO) { + // 校验processCode唯一性 + validateProcessCodeUnique(null, createReqVO.getProcessCode()); + + // 插入 + BpmProcessMappingConfigDO config = BeanUtil.toBean(createReqVO, BpmProcessMappingConfigDO.class); + processMappingConfigMapper.insert(config); + + // 清除缓存 + evictCache(createReqVO.getProcessCode()); + + return config.getId(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void updateProcessMappingConfig(BpmProcessMappingConfigUpdateReqVO updateReqVO) { + // 校验存在 + BpmProcessMappingConfigDO oldConfig = validateProcessMappingConfigExists(updateReqVO.getId()); + + // 校验processCode唯一性 + if (!oldConfig.getProcessCode().equals(updateReqVO.getProcessCode())) { + validateProcessCodeUnique(updateReqVO.getId(), updateReqVO.getProcessCode()); + } + + // 更新 + BpmProcessMappingConfigDO updateObj = BeanUtil.toBean(updateReqVO, BpmProcessMappingConfigDO.class); + processMappingConfigMapper.updateById(updateObj); + + // 清除缓存 + evictCache(oldConfig.getProcessCode()); + if (!oldConfig.getProcessCode().equals(updateReqVO.getProcessCode())) { + evictCache(updateReqVO.getProcessCode()); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteProcessMappingConfig(Long id) { + // 校验存在 + BpmProcessMappingConfigDO config = validateProcessMappingConfigExists(id); + + // 删除 + processMappingConfigMapper.deleteById(id); + + // 清除缓存 + evictCache(config.getProcessCode()); + } + + @Override + public BpmProcessMappingConfigDO getProcessMappingConfig(Long id) { + return processMappingConfigMapper.selectById(id); + } + + @Override + public BpmProcessMappingConfigDO getProcessMappingConfigByCode(String processCode) { + try { + // 先从一级缓存(内存)获取 + BpmProcessMappingConfigDO config = localCache.get(processCode); + if (config != null && config.getId() != null) { + log.debug("[getProcessMappingConfigByCode][一级缓存命中] processCode={}", processCode); + return config; + } + return null; + } catch (Exception e) { + log.error("[getProcessMappingConfigByCode][缓存异常] processCode={}", processCode, e); + // 缓存异常时直接查询数据库 + return processMappingConfigMapper.selectByProcessCode(processCode); + } + } + + /** + * 从二级缓存(Redis)获取配置 + * 使用Spring Cache注解,自动管理Redis缓存 + */ + @Cacheable(value = CACHE_KEY_PREFIX + "#1h", key = "#processCode", unless = "#result == null") + public BpmProcessMappingConfigDO getFromRedisCache(String processCode) { + log.info("[getFromRedisCache][二级缓存miss,从数据库加载] processCode={}", processCode); + // 从数据库查询 + return processMappingConfigMapper.selectByProcessCode(processCode); + } + + @Override + public PageResult getProcessMappingConfigPage(BpmProcessMappingConfigPageReqVO pageReqVO) { + return processMappingConfigMapper.selectPage(pageReqVO); + } + + @Override + public void refreshCache() { + // 清空一级缓存 + localCache.invalidateAll(); + log.info("[refreshCache][已清空一级缓存]"); + + // 清空二级缓存(通过Spring Cache管理) + // 注意:这里需要具体实现清空所有Redis缓存的逻辑 + } + + /** + * 清除指定processCode的缓存 + */ + @CacheEvict(value = CACHE_KEY_PREFIX + "#1h", key = "#processCode") + public void evictCache(String processCode) { + // 清除一级缓存 + localCache.invalidate(processCode); + log.info("[evictCache][已清除缓存] processCode={}", processCode); + // 清除二级缓存由@CacheEvict注解自动处理 + } + + private void validateProcessCodeUnique(Long id, String processCode) { + BpmProcessMappingConfigDO config = processMappingConfigMapper.selectByProcessCode(processCode); + if (config == null) { + return; + } + // 如果 id 为空,说明不用比较是否为相同 id 的配置 + if (id == null) { + throw exception(PROCESS_MAPPING_CONFIG_NOT_EXISTS); + } + if (!config.getId().equals(id)) { + throw exception(PROCESS_MAPPING_CONFIG_NOT_EXISTS); + } + } + + private BpmProcessMappingConfigDO validateProcessMappingConfigExists(Long id) { + if (id == null) { + return null; + } + BpmProcessMappingConfigDO config = processMappingConfigMapper.selectById(id); + if (config == null) { + throw exception(PROCESS_MAPPING_CONFIG_NOT_EXISTS); + } + return config; + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryService.java new file mode 100644 index 00000000..7efb1aa0 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryService.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.bpm.service.processmapping; + +import java.io.Serializable; + +/** + * 流程动态查询 Service 接口 + * + * @author 系统 + */ +public interface ProcessQueryService { + + /** + * 根据流程代码和ID查询数据 + * + * @param processCode 流程标识(如"ORDER") + * @param id 数据主键 + * @return 对应的实体对象 + */ + Object queryById(String processCode, Serializable id); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryServiceImpl.java new file mode 100644 index 00000000..9ada60ea --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/processmapping/ProcessQueryServiceImpl.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.bpm.service.processmapping; + +import cn.hutool.core.util.ClassUtil; +import cn.hutool.extra.spring.SpringUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.module.bpm.dal.dataobject.processmapping.BpmProcessMappingConfigDO; +import cn.iocoder.yudao.module.bpm.framework.core.util.ReflectionInvoker; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.io.Serializable; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_MAPPING_CONFIG_NOT_EXISTS; + +/** + * 流程动态查询 Service 实现类 + * + * @author 系统 + */ +@Service +@Validated +@Slf4j +public class ProcessQueryServiceImpl implements ProcessQueryService { + + @Resource + private ProcessMappingConfigService processMappingConfigService; + + @Override + public Object queryById(String processCode, Serializable id) { + // 1. 获取流程配置 + BpmProcessMappingConfigDO config = getProcessMappingConfig(processCode); + + // 2. 动态获取Mapper实例 + Object mapperBean = getMapperBean(config.getMapperClass()); + + // 3. 调用selectById方法 + return ReflectionInvoker.invokeMapperMethod(mapperBean, "selectById", Serializable.class, id); + } + + /** + * 获取流程映射配置 + */ + private BpmProcessMappingConfigDO getProcessMappingConfig(String processCode) { + BpmProcessMappingConfigDO config = processMappingConfigService.getProcessMappingConfigByCode(processCode); + if (config == null) { + throw exception(PROCESS_MAPPING_CONFIG_NOT_EXISTS); + } + return config; + } + + /** + * 动态获取Mapper Bean实例 + */ + private Object getMapperBean(String mapperClassName) { + try { + Class mapperClass = ClassUtil.loadClass(mapperClassName); + return SpringUtil.getBean(mapperClass); + } catch (Exception e) { + log.error("[getMapperBean][获取Mapper实例失败] mapperClassName={}", mapperClassName, e); + throw new ServiceException(500, String.format("获取Mapper实例失败: %s", e.getMessage())); + } + } +}