houzhongjian
2024-08-02 4a47e4b93f62b5e636ac0e76f3e4ee98e2b83154
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.bpm.service.definition;
H 2
3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.StrUtil;
5 import com.iailab.framework.common.pojo.PageResult;
6 import com.iailab.framework.common.util.object.BeanUtils;
7 import com.iailab.framework.common.util.object.PageUtils;
8 import com.iailab.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
9 import com.iailab.module.bpm.dal.dataobject.definition.BpmFormDO;
10 import com.iailab.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
11 import com.iailab.module.bpm.dal.mysql.definition.BpmProcessDefinitionInfoMapper;
12 import com.iailab.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
13 import com.iailab.module.bpm.framework.flowable.core.util.FlowableUtils;
14 import com.iailab.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
15 import lombok.extern.slf4j.Slf4j;
16 import org.flowable.bpmn.model.BpmnModel;
17 import org.flowable.common.engine.impl.db.SuspensionState;
18 import org.flowable.engine.RepositoryService;
19 import org.flowable.engine.repository.Deployment;
20 import org.flowable.engine.repository.Model;
21 import org.flowable.engine.repository.ProcessDefinition;
22 import org.flowable.engine.repository.ProcessDefinitionQuery;
23 import org.springframework.stereotype.Service;
24 import org.springframework.validation.annotation.Validated;
25
26 import javax.annotation.Resource;
27 import java.util.*;
28
29 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
30 import static com.iailab.framework.common.util.collection.CollectionUtils.addIfNotNull;
31 import static com.iailab.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
32 import static com.iailab.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
33 import static java.util.Collections.emptyList;
34
35 /**
36  * 流程定义实现
37  * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护
38  *
39  * @author yunlongn
40  * @author ZJQ
41  * @author iailab
42  */
43 @Service
44 @Validated
45 @Slf4j
46 public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionService {
47
48     @Resource
49     private RepositoryService repositoryService;
50
51     @Resource
52     private BpmProcessDefinitionInfoMapper processDefinitionMapper;
53
54     @Override
55     public ProcessDefinition getProcessDefinition(String id) {
56         return repositoryService.getProcessDefinition(id);
57     }
58
59     @Override
60     public List<ProcessDefinition> getProcessDefinitionList(Set<String> ids) {
61         return repositoryService.createProcessDefinitionQuery().processDefinitionIds(ids).list();
62     }
63
64     @Override
65     public ProcessDefinition getProcessDefinitionByDeploymentId(String deploymentId) {
66         if (StrUtil.isEmpty(deploymentId)) {
67             return null;
68         }
69         return repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
70     }
71
72     @Override
73     public List<ProcessDefinition> getProcessDefinitionListByDeploymentIds(Set<String> deploymentIds) {
74         if (CollUtil.isEmpty(deploymentIds)) {
75             return emptyList();
76         }
77         return repositoryService.createProcessDefinitionQuery().deploymentIds(deploymentIds).list();
78     }
79
80     @Override
81     public ProcessDefinition getActiveProcessDefinition(String key) {
82         return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult();
83     }
84
85     @Override
86     public List<Deployment> getDeploymentList(Set<String> ids) {
87         if (CollUtil.isEmpty(ids)) {
88             return emptyList();
89         }
90         List<Deployment> list = new ArrayList<>(ids.size());
91         for (String id : ids) {
92             addIfNotNull(list, getDeployment(id));
93         }
94         return list;
95     }
96
97     @Override
98     public Deployment getDeployment(String id) {
99         if (StrUtil.isEmpty(id)) {
100             return null;
101         }
102         return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
103     }
104
105     @Override
106     public String createProcessDefinition(Model model, BpmModelMetaInfoRespDTO modelMetaInfo,
107                                           byte[] bpmnBytes, BpmFormDO form) {
108         // 创建 Deployment 部署
109         Deployment deploy = repositoryService.createDeployment()
110                 .key(model.getKey()).name(model.getName()).category(model.getCategory())
111                 .addBytes(model.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, bpmnBytes)
112                 .tenantId(FlowableUtils.getTenantId())
113                 .disableSchemaValidation() // 禁用 XML Schema 验证,因为有自定义的属性
114                 .deploy();
115
116         // 设置 ProcessDefinition 的 category 分类
117         ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
118                 .deploymentId(deploy.getId()).singleResult();
119         repositoryService.setProcessDefinitionCategory(definition.getId(), model.getCategory());
120         // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定
121         // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。
122         //          否则,会导致 ProcessDefinition 的分页无法查询到。
123         if (!Objects.equals(definition.getKey(), model.getKey())) {
124             throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, model.getKey(), definition.getKey());
125         }
126         if (!Objects.equals(definition.getName(), model.getName())) {
127             throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, model.getName(), definition.getName());
128         }
129
130         // 插入拓展表
131         BpmProcessDefinitionInfoDO definitionDO = BeanUtils.toBean(modelMetaInfo, BpmProcessDefinitionInfoDO.class)
132                 .setModelId(model.getId()).setProcessDefinitionId(definition.getId());
133         if (form != null) {
134             definitionDO.setFormFields(form.getFields()).setFormConf(form.getConf());
135         }
136         processDefinitionMapper.insert(definitionDO);
137         return definition.getId();
138     }
139
140     @Override
141     public void updateProcessDefinitionState(String id, Integer state) {
142         // 激活
143         if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
144             repositoryService.activateProcessDefinitionById(id, false, null);
145             return;
146         }
147         // 挂起
148         if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
149             // suspendProcessInstances = false,进行中的任务,不进行挂起。
150             // 原因:只要新的流程不允许发起即可,老流程继续可以执行。
151             repositoryService.suspendProcessDefinitionById(id, false, null);
152             return;
153         }
154         log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
155     }
156
157     @Override
158     public BpmnModel getProcessDefinitionBpmnModel(String id) {
159         return repositoryService.getBpmnModel(id);
160     }
161
162     @Override
163     public BpmProcessDefinitionInfoDO getProcessDefinitionInfo(String id) {
164         return processDefinitionMapper.selectByProcessDefinitionId(id);
165     }
166
167     @Override
168     public List<BpmProcessDefinitionInfoDO> getProcessDefinitionInfoList(Collection<String> ids) {
169         return processDefinitionMapper.selectListByProcessDefinitionIds(ids);
170     }
171
172     @Override
173     public PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
174         ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
175         if (StrUtil.isNotBlank(pageVO.getKey())) {
176             query.processDefinitionKey(pageVO.getKey());
177         }
178         // 执行查询
179         long count = query.count();
180         if (count == 0) {
181             return PageResult.empty(count);
182         }
183         List<ProcessDefinition> list = query.orderByProcessDefinitionVersion().desc()
184                 .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
185         return new PageResult<>(list, count);
186     }
187
188     @Override
189     public List<ProcessDefinition> getProcessDefinitionListBySuspensionState(Integer suspensionState) {
190         // 拼接查询条件
191         ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
192         if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), suspensionState)) {
193             query.suspended();
194         } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), suspensionState)) {
195             query.active();
196         }
197         // 执行查询
4a47e4 198         // 关闭多租户查询,不添加tenantId条件
H 199         if (StrUtil.isNotBlank(FlowableUtils.getTenantId())) {
200             query.processDefinitionTenantId(FlowableUtils.getTenantId());
201         } else {
202             query.processDefinitionWithoutTenantId();
203         }
e7c126 204         return query.list();
H 205     }
206
207 }