Browse Source

feat: BPM-更多设置-流程编码

Lesan 6 months ago
parent
commit
daa718a444

+ 27 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/BpmModelMetaInfoVO.java

@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
@@ -65,4 +66,30 @@ public class BpmModelMetaInfoVO {
     @Schema(description = "允许撤销审批中的申请", example = "true")
     private Boolean allowCancelRunningProcess;
 
+    @Schema(description = "流程 Id 规则", example = "{}")
+    private ProcessIdRule processIdRule;
+
+    @Schema(description = "流程 Id 规则")
+    @Data
+    @Valid
+    public static class ProcessIdRule {
+
+        @Schema(description = "是否启用", example = "false")
+        @NotNull(message = "是否启用不能为空")
+        private Boolean enable;
+
+        @Schema(description = "前缀", example = "xx")
+        private String prefix;
+
+        @Schema(description = "前缀", example = "20250120")
+        private String infix;
+
+        @Schema(description = "前缀", example = "xx")
+        private String postfix;
+
+        @Schema(description = "序列长度", example = "5")
+        @NotNull(message = "序列长度不能为空")
+        private Integer length;
+    }
+
 }

+ 7 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmProcessDefinitionInfoDO.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
 import cn.iocoder.yudao.framework.mybatis.core.type.StringListTypeHandler;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -155,4 +156,10 @@ public class BpmProcessDefinitionInfoDO extends BaseDO {
      */
     private Boolean allowCancelRunningProcess;
 
+    /**
+     * 流程 Id 规则
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private BpmModelMetaInfoVO.ProcessIdRule processIdRule;
+
 }

+ 54 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/redis/BpmProcessIdRedisDAO.java

@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.module.bpm.dal.redis;
+
+import cn.hutool.core.date.DateUtil;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
+import jakarta.annotation.Resource;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Repository;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+/**
+ * BPM 流程 Id 编码的 Redis DAO
+ *
+ * @author Lesan
+ */
+@Repository
+public class BpmProcessIdRedisDAO {
+
+    public static final String BPM_PROCESS_ID_PREFIX = "BPMPID";
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+    /**
+     * 生成序号,使用定义的 processIdRule 规则生成
+     *
+     * @param processIdRule 规则
+     * @return 序号
+     */
+    public String generate(BpmModelMetaInfoVO.ProcessIdRule processIdRule) {
+        String infix = "";
+        switch (processIdRule.getInfix()) {
+            case "DAY":
+                infix = DateUtil.format(LocalDateTime.now(), "yyyyMMDD");
+                break;
+            case "HOUR":
+                infix = DateUtil.format(LocalDateTime.now(), "yyyyMMDDHH");
+                break;
+            case "MINUTE":
+                infix = DateUtil.format(LocalDateTime.now(), "yyyyMMDDHHmm");
+                break;
+            case "SECOND":
+                infix = DateUtil.format(LocalDateTime.now(), "yyyyMMDDHHmmss");
+                break;
+        }
+        String noPrefix = processIdRule.getPrefix() + infix + processIdRule.getPostfix();
+        String key = BPM_PROCESS_ID_PREFIX + noPrefix;
+        Long no = stringRedisTemplate.opsForValue().increment(key);
+        stringRedisTemplate.expire(key, Duration.ofDays(1L));
+        return noPrefix + String.format("%0" + processIdRule.getLength() + "d", no);
+    }
+
+}

+ 16 - 3
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java

@@ -12,12 +12,14 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.framework.common.util.object.PageUtils;
 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
+import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ActivityNodeTask;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
 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.dal.redis.BpmProcessIdRedisDAO;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelTypeEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType;
@@ -50,6 +52,7 @@ 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.flowable.engine.runtime.ProcessInstanceBuilder;
 import org.flowable.task.api.history.HistoricTaskInstance;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -109,6 +112,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
     @Resource
     private BpmTaskCandidateInvoker taskCandidateInvoker;
 
+    @Resource
+    private BpmProcessIdRedisDAO processIdRedisDAO;
+
     // ========== Query 查询相关方法 ==========
 
     @Override
@@ -599,12 +605,19 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
         if (CollUtil.isNotEmpty(startUserSelectAssignees)) {
             variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, startUserSelectAssignees);
         }
-        ProcessInstance instance = runtimeService.createProcessInstanceBuilder()
+
+        // 3. 流程 Id
+        ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder()
                 .processDefinitionId(definition.getId())
                 .businessKey(businessKey)
                 .name(definition.getName().trim())
-                .variables(variables)
-                .start();
+                .variables(variables);
+        BpmModelMetaInfoVO.ProcessIdRule processIdRule = processDefinitionInfo.getProcessIdRule();
+        if (processIdRule != null && processIdRule.getEnable()) {
+            String id = processIdRedisDAO.generate(processIdRule);
+            processInstanceBuilder.predefineProcessInstanceId(id);
+        }
+        ProcessInstance instance = processInstanceBuilder.start();
         return instance.getId();
     }