潘志宝
9 天以前 9d5be382e52f9ac57199d5ef75cc23f925a4cdb0
提交 | 用户 | 时间
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;
bb2880 8 import com.iailab.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
e7c126 9 import com.iailab.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionPageReqVO;
H 10 import com.iailab.module.bpm.dal.dataobject.definition.BpmFormDO;
11 import com.iailab.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
12 import com.iailab.module.bpm.dal.mysql.definition.BpmProcessDefinitionInfoMapper;
13 import com.iailab.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
14 import com.iailab.module.bpm.framework.flowable.core.util.FlowableUtils;
15 import com.iailab.module.bpm.service.definition.dto.BpmModelMetaInfoRespDTO;
16 import lombok.extern.slf4j.Slf4j;
bb2880 17 import org.apache.commons.lang3.ObjectUtils;
e7c126 18 import org.flowable.bpmn.model.BpmnModel;
H 19 import org.flowable.common.engine.impl.db.SuspensionState;
20 import org.flowable.engine.RepositoryService;
21 import org.flowable.engine.repository.Deployment;
22 import org.flowable.engine.repository.Model;
23 import org.flowable.engine.repository.ProcessDefinition;
24 import org.flowable.engine.repository.ProcessDefinitionQuery;
25 import org.springframework.stereotype.Service;
26 import org.springframework.validation.annotation.Validated;
27
28 import javax.annotation.Resource;
29 import java.util.*;
30
31 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
32 import static com.iailab.framework.common.util.collection.CollectionUtils.addIfNotNull;
33 import static com.iailab.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_KEY_NOT_MATCH;
34 import static com.iailab.module.bpm.enums.ErrorCodeConstants.PROCESS_DEFINITION_NAME_NOT_MATCH;
35 import static java.util.Collections.emptyList;
36
37 /**
38  * 流程定义实现
39  * 主要进行 Flowable {@link ProcessDefinition} 和 {@link Deployment} 的维护
40  *
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) {
bb2880 82         return repositoryService.createProcessDefinitionQuery()
H 83                 .processDefinitionTenantId(FlowableUtils.getTenantId())
84                 .processDefinitionKey(key).active().singleResult();
85     }
86
87     @Override
88     public boolean canUserStartProcessDefinition(BpmProcessDefinitionInfoDO processDefinition, Long userId) {
89         if (processDefinition == null) {
90             return false;
91         }
92         // 为空,则所有人都可以发起
93         if (CollUtil.isEmpty(processDefinition.getStartUserIds())) {
94             return true;
95         }
96         // 不为空,则需要存在里面
97         return processDefinition.getStartUserIds().contains(userId);
e7c126 98     }
H 99
100     @Override
101     public List<Deployment> getDeploymentList(Set<String> ids) {
102         if (CollUtil.isEmpty(ids)) {
103             return emptyList();
104         }
105         List<Deployment> list = new ArrayList<>(ids.size());
106         for (String id : ids) {
107             addIfNotNull(list, getDeployment(id));
108         }
109         return list;
110     }
111
112     @Override
113     public Deployment getDeployment(String id) {
114         if (StrUtil.isEmpty(id)) {
115             return null;
116         }
117         return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
118     }
119
120     @Override
bb2880 121     public String createProcessDefinition(Model model, BpmModelMetaInfoVO modelMetaInfo,
H 122                                           byte[] bpmnBytes, String simpleJson, BpmFormDO form) {
e7c126 123         // 创建 Deployment 部署
H 124         Deployment deploy = repositoryService.createDeployment()
125                 .key(model.getKey()).name(model.getName()).category(model.getCategory())
126                 .addBytes(model.getKey() + BpmnModelConstants.BPMN_FILE_SUFFIX, bpmnBytes)
127                 .tenantId(FlowableUtils.getTenantId())
128                 .disableSchemaValidation() // 禁用 XML Schema 验证,因为有自定义的属性
129                 .deploy();
130
131         // 设置 ProcessDefinition 的 category 分类
132         ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
133                 .deploymentId(deploy.getId()).singleResult();
134         repositoryService.setProcessDefinitionCategory(definition.getId(), model.getCategory());
135         // 注意 1,ProcessDefinition 的 key 和 name 是通过 BPMN 中的 <bpmn2:process /> 的 id 和 name 决定
136         // 注意 2,目前该项目的设计上,需要保证 Model、Deployment、ProcessDefinition 使用相同的 key,保证关联性。
137         //          否则,会导致 ProcessDefinition 的分页无法查询到。
138         if (!Objects.equals(definition.getKey(), model.getKey())) {
139             throw exception(PROCESS_DEFINITION_KEY_NOT_MATCH, model.getKey(), definition.getKey());
140         }
141         if (!Objects.equals(definition.getName(), model.getName())) {
142             throw exception(PROCESS_DEFINITION_NAME_NOT_MATCH, model.getName(), definition.getName());
143         }
144
145         // 插入拓展表
146         BpmProcessDefinitionInfoDO definitionDO = BeanUtils.toBean(modelMetaInfo, BpmProcessDefinitionInfoDO.class)
bb2880 147                 .setModelId(model.getId()).setProcessDefinitionId(definition.getId())
H 148                 .setModelType(modelMetaInfo.getType()).setSimpleModel(simpleJson);
149
e7c126 150         if (form != null) {
H 151             definitionDO.setFormFields(form.getFields()).setFormConf(form.getConf());
152         }
153         processDefinitionMapper.insert(definitionDO);
154         return definition.getId();
155     }
156
157     @Override
158     public void updateProcessDefinitionState(String id, Integer state) {
159         // 激活
160         if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), state)) {
161             repositoryService.activateProcessDefinitionById(id, false, null);
162             return;
163         }
164         // 挂起
165         if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), state)) {
166             // suspendProcessInstances = false,进行中的任务,不进行挂起。
167             // 原因:只要新的流程不允许发起即可,老流程继续可以执行。
168             repositoryService.suspendProcessDefinitionById(id, false, null);
169             return;
170         }
171         log.error("[updateProcessDefinitionState][流程定义({}) 修改未知状态({})]", id, state);
172     }
173
174     @Override
bb2880 175     public void updateProcessDefinitionSortByModelId(String modelId, Long sort) {
H 176         processDefinitionMapper.updateByModelId(modelId, new BpmProcessDefinitionInfoDO().setSort(sort));
177     }
178
179     @Override
e7c126 180     public BpmnModel getProcessDefinitionBpmnModel(String id) {
H 181         return repositoryService.getBpmnModel(id);
182     }
183
184     @Override
185     public BpmProcessDefinitionInfoDO getProcessDefinitionInfo(String id) {
186         return processDefinitionMapper.selectByProcessDefinitionId(id);
187     }
188
189     @Override
190     public List<BpmProcessDefinitionInfoDO> getProcessDefinitionInfoList(Collection<String> ids) {
191         return processDefinitionMapper.selectListByProcessDefinitionIds(ids);
192     }
193
194     @Override
195     public PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
196         ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
bb2880 197         query.processDefinitionTenantId(FlowableUtils.getTenantId());
e7c126 198         if (StrUtil.isNotBlank(pageVO.getKey())) {
H 199             query.processDefinitionKey(pageVO.getKey());
200         }
201         // 执行查询
202         long count = query.count();
203         if (count == 0) {
204             return PageResult.empty(count);
205         }
206         List<ProcessDefinition> list = query.orderByProcessDefinitionVersion().desc()
207                 .listPage(PageUtils.getStart(pageVO), pageVO.getPageSize());
208         return new PageResult<>(list, count);
209     }
210
211     @Override
bb2880 212     public List<ProcessDefinition> getProcessDefinitionListBySuspensionState(Integer suspensionState, String categoryId) {
e7c126 213         // 拼接查询条件
H 214         ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
215         if (Objects.equals(SuspensionState.SUSPENDED.getStateCode(), suspensionState)) {
216             query.suspended();
217         } else if (Objects.equals(SuspensionState.ACTIVE.getStateCode(), suspensionState)) {
218             query.active();
219         }
bb2880 220         if(ObjectUtils.isNotEmpty(categoryId)) {
H 221             query.processDefinitionCategory(categoryId);
4a47e4 222         }
bb2880 223         // 执行查询
H 224         query.processDefinitionTenantId(FlowableUtils.getTenantId());
e7c126 225         return query.list();
H 226     }
227
228 }