增加候选人策略

This commit is contained in:
zhouhao
2018-06-22 16:01:25 +08:00
parent 8f70138aaa
commit 5a14497dfd
9 changed files with 296 additions and 15 deletions

View File

@@ -1,6 +1,5 @@
package org.hswebframework.web.workflow.dimension;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
@@ -12,7 +11,6 @@ public interface CandidateDimension {
List<String> getCandidateUserIdList();
CandidateDimension empty = Collections::emptyList;
}

View File

@@ -6,15 +6,16 @@ import io.vavr.Lazy;
import org.apache.commons.collections.CollectionUtils;
import org.hswebframework.web.workflow.dimension.parser.CandidateDimensionParserStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class DefaultCandidateDimensionParser implements CandidateDimensionParser {
@Autowired(required = false)
private List<CandidateDimensionParserStrategy> strategies;
@@ -22,20 +23,29 @@ public class DefaultCandidateDimensionParser implements CandidateDimensionParser
public CandidateDimension parse(String jsonConfig) {
JSONObject jsonObject = JSON.parseObject(jsonConfig);
String type = jsonObject.getString("type");
List<String> ids = jsonObject.getJSONArray("list").toJavaList(String.class);
CandidateDimensionParserStrategy.StrategyConfig config = jsonObject
.toJavaObject(CandidateDimensionParserStrategy.StrategyConfig.class);
if (config.getConfig() == null) {
config.setConfig(jsonObject);
}
if (StringUtils.isEmpty(type) || CollectionUtils.isEmpty(strategies) || CollectionUtils.isEmpty(ids)) {
if (StringUtils.isEmpty(type)
|| CollectionUtils.isEmpty(strategies)
|| CollectionUtils.isEmpty(config.getIdList())) {
return CandidateDimension.empty;
}
return Lazy.val(() ->
(CandidateDimension) () -> strategies
.stream()
.filter(strategy -> strategy.support(type))
.map(strategy -> strategy.parse(ids))
.filter(CollectionUtils::isNotEmpty)
.flatMap(Collection::stream)
.collect(Collectors.toList()), CandidateDimension.class);
return Lazy.val(() -> {
List<String> list = strategies
.stream()
.filter(strategy -> strategy.support(type))
.map(strategy -> strategy.parse(config))
.filter(CollectionUtils::isNotEmpty)
.flatMap(Collection::stream)
.collect(Collectors.toList());
return (CandidateDimension) () -> list;
}
, CandidateDimension.class);
}
}

View File

@@ -1,9 +1,32 @@
package org.hswebframework.web.workflow.dimension.parser;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public interface CandidateDimensionParserStrategy {
boolean support(String type);
String DIMENSION_USER = "user";
String DIMENSION_ROLE = "role";
String DIMENSION_POSITION = "position";
String DIMENSION_DEPARTMENT = "department";
String DIMENSION_ORG = "org";
List<String> parse(List<String> ids);
boolean support(String dimension);
List<String> parse(StrategyConfig config);
@Getter
@Setter
class StrategyConfig {
private List<String> idList;
private Map<String, Object> config;
public Optional<Object> getConfig(String name) {
return config == null ? Optional.empty() : Optional.ofNullable(config.get(name));
}
}
}

View File

@@ -0,0 +1,46 @@
package org.hswebframework.web.workflow.dimension.parser;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.service.authorization.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
import static org.hswebframework.web.commons.entity.param.QueryParamEntity.empty;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@ConditionalOnBean(UserService.class)
public class DepartmentCandidateDimensionParserStrategy implements CandidateDimensionParserStrategy {
@Autowired(required = false)
private UserService userService;
@Override
public boolean support(String dimension) {
return DIMENSION_DEPARTMENT.equals(dimension) && userService != null;
}
@Override
public List<String> parse(StrategyConfig config) {
String type = config.getConfig("tree")
.map(String::valueOf)
.map("-"::concat)
.orElse("");
return userService.select(
empty().noPaging()
//https://github.com/hs-web/hsweb-framework/tree/master/hsweb-system/hsweb-system-organizational#sql条件
.where("id", "user-in-department" + type, config.getIdList()))
.stream()
.map(UserEntity::getId)
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,44 @@
package org.hswebframework.web.workflow.dimension.parser;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.service.authorization.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
import static org.hswebframework.web.commons.entity.param.QueryParamEntity.empty;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@ConditionalOnBean(UserService.class)
public class OrgCandidateDimensionParserStrategy implements CandidateDimensionParserStrategy {
@Autowired(required = false)
private UserService userService;
@Override
public boolean support(String dimension) {
return DIMENSION_ORG.equals(dimension) && userService != null;
}
@Override
public List<String> parse(StrategyConfig config) {
String type = config.getConfig("tree")
.map(String::valueOf)
.map("-"::concat)
.orElse("");
return userService.select(
empty().noPaging()
//https://github.com/hs-web/hsweb-framework/tree/master/hsweb-system/hsweb-system-organizational#sql条件
.where("id", "user-in-org" + type, config.getIdList()))
.stream()
.map(UserEntity::getId)
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,44 @@
package org.hswebframework.web.workflow.dimension.parser;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.service.authorization.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
import static org.hswebframework.web.commons.entity.param.QueryParamEntity.*;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@ConditionalOnBean(UserService.class)
public class PositionCandidateDimensionParserStrategy implements CandidateDimensionParserStrategy {
@Autowired(required = false)
private UserService userService;
@Override
public boolean support(String dimension) {
return DIMENSION_POSITION.equals(dimension) && userService != null;
}
@Override
public List<String> parse(StrategyConfig config) {
String type = config.getConfig("tree")
.map(String::valueOf)
.map("-"::concat)
.orElse("");
return userService.select(
empty().noPaging()
//https://github.com/hs-web/hsweb-framework/tree/master/hsweb-system/hsweb-system-organizational#sql条件
.where("id", "user-in-position"+type, config.getIdList()))
.stream()
.map(UserEntity::getId)
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,37 @@
package org.hswebframework.web.workflow.dimension.parser;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.service.authorization.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@ConditionalOnBean(UserService.class)
public class RoleCandidateDimensionParserStrategy implements CandidateDimensionParserStrategy {
@Autowired(required = false)
private UserService userService;
@Override
public boolean support(String dimension) {
return DIMENSION_ROLE.equals(dimension) && userService != null;
}
@Override
public List<String> parse(StrategyConfig config) {
return userService.selectByUserByRole(config.getIdList())
.stream()
.map(UserEntity::getId)
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,23 @@
package org.hswebframework.web.workflow.dimension.parser;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
public class UserCandidateDimensionParserStrategy implements CandidateDimensionParserStrategy {
@Override
public boolean support(String dimension) {
return DIMENSION_USER.equals(dimension);
}
@Override
public List<String> parse(StrategyConfig config) {
return config.getIdList();
}
}

View File

@@ -0,0 +1,56 @@
package org.hswebframework.web.workflow.dimension
import org.hswebframework.web.workflow.flowable.TestApplication
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ContextConfiguration
import org.springframework.test.context.web.WebAppConfiguration
import spock.lang.Specification
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@WebAppConfiguration
@ContextConfiguration
@SpringBootTest(classes = [TestApplication.class], properties = ["classpath:application.yml"])
class DefaultCandidateDimensionParserTest extends Specification {
@Autowired
private CandidateDimensionParser parser;
def "Test Parse User"() {
setup:
def config = """ {"type":"user","idList":["admin"]} """
and:
def dimension = parser.parse(config)
expect:
dimension != null
dimension.getCandidateUserIdList() != null
!dimension.getCandidateUserIdList().isEmpty()
dimension.getCandidateUserIdList().get(0) == "admin"
}
def "Test Parse Role"() {
setup:
def config = """ {"type":"role","idList":["admin"]} """
and:
def dimension = parser.parse(config)
expect:
dimension != null
dimension.getCandidateUserIdList() != null
dimension != CandidateDimension.empty
}
def "Test Parse Position"() {
setup:
def config = """ {"type":"position","idList":["test"],"tree":"parent"} """
and:
def dimension = parser.parse(config)
expect:
dimension != null
dimension.getCandidateUserIdList() != null
dimension != CandidateDimension.empty
}
}