功能开发

This commit is contained in:
lvshaohua 2023-06-29 15:07:16 +08:00
parent 394e0449e8
commit bc1e15fff0
5 changed files with 314 additions and 4 deletions

View File

@ -0,0 +1,171 @@
package cn.axzo.workflow.core.common.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.ImmutableMap;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class BpmCollectionUtils {
public static boolean containsAny(Object source, Object... targets) {
return Arrays.asList(targets).contains(source);
}
public static boolean isAnyEmpty(Collection<?>... collections) {
return Arrays.stream(collections).anyMatch(CollectionUtil::isEmpty);
}
public static boolean isAnyEmpty(Map<?,?>... maps) {
return Arrays.stream(maps).anyMatch(Map::isEmpty);
}
public static <T> List<T> filterList(Collection<T> from, Predicate<T> predicate) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return from.stream().filter(predicate).collect(Collectors.toList());
}
public static <T, R> List<T> distinct(Collection<T> from, Function<T, R> keyMapper) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return distinct(from, keyMapper, (t1, t2) -> t1);
}
public static <T, R> List<T> distinct(Collection<T> from, Function<T, R> keyMapper, BinaryOperator<T> cover) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return new ArrayList<>(convertMap(from, keyMapper, Function.identity(), cover).values());
}
public static <T, U> List<U> convertList(Collection<T> from, Function<T, U> func) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toList());
}
public static <T, U> Set<U> convertSet(Collection<T> from, Function<T, U> func) {
if (CollUtil.isEmpty(from)) {
return new HashSet<>();
}
return from.stream().map(func).filter(Objects::nonNull).collect(Collectors.toSet());
}
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return convertMap(from, keyFunc, Function.identity());
}
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc, Supplier<? extends Map<K, T>> supplier) {
if (CollUtil.isEmpty(from)) {
return supplier.get();
}
return convertMap(from, keyFunc, Function.identity(), supplier);
}
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return convertMap(from, keyFunc, valueFunc, (v1, v2) -> v1);
}
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc, BinaryOperator<V> mergeFunction) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return convertMap(from, keyFunc, valueFunc, mergeFunction, HashMap::new);
}
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc, Supplier<? extends Map<K, V>> supplier) {
if (CollUtil.isEmpty(from)) {
return supplier.get();
}
return convertMap(from, keyFunc, valueFunc, (v1, v2) -> v1, supplier);
}
public static <T, K, V> Map<K, V> convertMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc, BinaryOperator<V> mergeFunction, Supplier<? extends Map<K, V>> supplier) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return from.stream().collect(Collectors.toMap(keyFunc, valueFunc, mergeFunction, supplier));
}
public static <T, K> Map<K, List<T>> convertMultiMap(Collection<T> from, Function<T, K> keyFunc) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(t -> t, Collectors.toList())));
}
public static <T, K, V> Map<K, List<V>> convertMultiMap(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return from.stream()
.collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toList())));
}
// 暂时没想好名字先以 2 结尾噶
public static <T, K, V> Map<K, Set<V>> convertMultiMap2(Collection<T> from, Function<T, K> keyFunc, Function<T, V> valueFunc) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
}
return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toSet())));
}
public static <T, K> Map<K, T> convertImmutableMap(Collection<T> from, Function<T, K> keyFunc) {
if (CollUtil.isEmpty(from)) {
return Collections.emptyMap();
}
ImmutableMap.Builder<K, T> builder = ImmutableMap.builder();
from.forEach(item -> builder.put(keyFunc.apply(item), item));
return builder.build();
}
public static boolean containsAny(Collection<?> source, Collection<?> candidates) {
return org.springframework.util.CollectionUtils.containsAny(source, candidates);
}
public static <T> T getFirst(List<T> from) {
return !CollectionUtil.isEmpty(from) ? from.get(0) : null;
}
public static <T> T findFirst(List<T> from, Predicate<T> predicate) {
if (CollUtil.isEmpty(from)) {
return null;
}
return from.stream().filter(predicate).findFirst().orElse(null);
}
public static <T, V extends Comparable<? super V>> V getMaxValue(List<T> from, Function<T, V> valueFunc) {
if (CollUtil.isEmpty(from)) {
return null;
}
assert from.size() > 0; // 断言避免告警
T t = from.stream().max(Comparator.comparing(valueFunc)).get();
return valueFunc.apply(t);
}
public static <T> void addIfNotNull(Collection<T> coll, T item) {
if (item == null) {
return;
}
coll.add(item);
}
public static <T> Collection<T> singleton(T deptId) {
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
}
}

View File

@ -3,6 +3,16 @@ package cn.axzo.workflow.core.repository.mapper;
import cn.axzo.workflow.core.repository.entity.BpmProcessDefinitionExtDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
@Mapper
public interface BpmProcessDefinitionExtMapper extends BaseMapperX<BpmProcessDefinitionExtDO> {
default List<BpmProcessDefinitionExtDO> selectListByProcessDefinitionIds(Collection<String> processDefinitionIds) {
return selectList("process_definition_id", processDefinitionIds);
}
default BpmProcessDefinitionExtDO selectByProcessDefinitionId(String processDefinitionId) {
return selectOne("process_definition_id", processDefinitionId);
}
}

View File

@ -0,0 +1,63 @@
package cn.axzo.workflow.core.service.converter;
import cn.axzo.workflow.core.common.utils.BpmCollectionUtils;
import cn.axzo.workflow.core.repository.entity.BpmProcessDefinitionExtDO;
import cn.axzo.workflow.core.service.dto.response.process.BpmProcessDefinitionPageItemRespVO;
import org.flowable.common.engine.impl.db.SuspensionState;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class BpmProcessDefinitionConvert {
public static List<BpmProcessDefinitionPageItemRespVO> convertList(List<ProcessDefinition> list,
Map<String, Deployment> deploymentMap,
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap,
Integer version) {
return BpmCollectionUtils.convertList(list, definition -> {
Deployment deployment =
definition.getDeploymentId() != null ? deploymentMap.get(definition.getDeploymentId())
: null;
BpmProcessDefinitionExtDO definitionDO = processDefinitionDOMap.get(definition.getId());
return convert(definition, deployment, definitionDO, version);
});
}
public static BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean, Deployment deployment,
BpmProcessDefinitionExtDO processDefinitionExtDO, Integer version) {
BpmProcessDefinitionPageItemRespVO respVO = convert(bean);
if (Objects.nonNull(version) && bean.getVersion() > version) {
respVO.setSyncModelPool(false);
} else {
respVO.setSyncModelPool(true);
}
respVO.setSuspensionState(bean.isSuspended() ? SuspensionState.SUSPENDED.getStateCode()
: SuspensionState.ACTIVE.getStateCode());
if (deployment != null) {
respVO.setDeploymentTime(deployment.getDeploymentTime());
}
BeanUtils.copyProperties(processDefinitionExtDO, respVO);
return respVO;
}
public static BpmProcessDefinitionPageItemRespVO convert(ProcessDefinition bean) {
if ( bean == null ) {
return null;
}
BpmProcessDefinitionPageItemRespVO bpmProcessDefinitionPageItemRespVO = new BpmProcessDefinitionPageItemRespVO();
bpmProcessDefinitionPageItemRespVO.setId( bean.getId() );
bpmProcessDefinitionPageItemRespVO.setVersion( bean.getVersion() );
bpmProcessDefinitionPageItemRespVO.setName( bean.getName() );
bpmProcessDefinitionPageItemRespVO.setDescription( bean.getDescription() );
bpmProcessDefinitionPageItemRespVO.setCategory( bean.getCategory() );
return bpmProcessDefinitionPageItemRespVO;
}
}

View File

@ -2,7 +2,9 @@ package cn.axzo.workflow.core.service.dto.request.process;
import cn.axzo.workflow.core.service.dto.request.BpmPageParam;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class BpmProcessDefinitionPageDTO extends BpmPageParam {
@ApiModelProperty(value = "流程标识,传了精准匹配")

View File

@ -1,11 +1,16 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.core.common.utils.BpmCollectionUtils;
import cn.axzo.workflow.core.repository.entity.BpmProcessDefinitionExtDO;
import cn.axzo.workflow.core.repository.mapper.BpmProcessDefinitionExtMapper;
import cn.axzo.workflow.core.service.converter.BpmProcessDefinitionConvert;
import cn.axzo.workflow.core.service.dto.request.process.BpmProcessDefinitionPageDTO;
import cn.axzo.workflow.core.service.dto.response.BpmPageResult;
import cn.axzo.workflow.core.service.dto.response.process.BpmProcessDefinitionPageItemRespVO;
import cn.axzo.workflow.core.service.BpmProcessDefinitionService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.impl.db.SuspensionState;
@ -13,15 +18,17 @@ import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.Model;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.*;
import static cn.axzo.workflow.core.common.enums.BpmErrorCode.*;
import static cn.axzo.workflow.core.common.utils.BpmCollectionUtils.*;
import static java.util.Collections.emptyList;
@Service
@Slf4j
@ -90,7 +97,42 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
@Override
public BpmPageResult<BpmProcessDefinitionPageItemRespVO> getProcessDefinitionPage(BpmProcessDefinitionPageDTO request) {
return null;
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
if (StrUtil.isNotBlank(request.getKey())) {
definitionQuery.processDefinitionKey(request.getKey());
}
// 执行查询
List<ProcessDefinition> processDefinitions = definitionQuery.orderByProcessDefinitionVersion()
.desc()
.listPage((request.getPageNo() - 1) * request.getPageSize(), request.getPageSize());
if (CollUtil.isEmpty(processDefinitions)) {
return new BpmPageResult<>(emptyList(), definitionQuery.count());
}
// 获得 Deployment Map
Set<String> deploymentIds = new HashSet<>();
processDefinitions.forEach(
definition -> addIfNotNull(deploymentIds, definition.getDeploymentId()));
Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
// 获得 BpmProcessDefinitionDO Map
List<BpmProcessDefinitionExtDO> processDefinitionDOs = processDefinitionExtMapper.selectListByProcessDefinitionIds(
convertList(processDefinitions, ProcessDefinition::getId));
Map<String, BpmProcessDefinitionExtDO> processDefinitionDOMap = convertMap(processDefinitionDOs,
BpmProcessDefinitionExtDO::getProcessDefinitionId);
List<Model> list = repositoryService.createModelQuery().modelKey(request.getKey()).list();
Integer version = null;
if (!BpmCollectionUtils.isAnyEmpty(list)) {
version = list.get(0).getVersion();
}
// 拼接结果
long definitionCount = definitionQuery.count();
return new BpmPageResult<>(
BpmProcessDefinitionConvert.convertList(processDefinitions, deploymentMap,
processDefinitionDOMap, version), definitionCount);
}
@Override
@ -130,4 +172,26 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
return list.get(0).getId();
}
}
private Map<String, Deployment> getDeploymentMap(Set<String> ids) {
return convertMap(getDeployments(ids), Deployment::getId);
}
private List<Deployment> getDeployments(Set<String> ids) {
if (CollUtil.isEmpty(ids)) {
return emptyList();
}
List<Deployment> list = new ArrayList<>(ids.size());
for (String id : ids) {
addIfNotNull(list, getDeployment(id));
}
return list;
}
private Deployment getDeployment(String id) {
if (StrUtil.isEmpty(id)) {
return null;
}
return repositoryService.createDeploymentQuery().deploymentId(id).singleResult();
}
}