add: 新增通用attachMore接口
This commit is contained in:
parent
993cb2e527
commit
1a4d50a25e
|
@ -31,6 +31,11 @@ public class CoreProperties {
|
|||
*/
|
||||
private boolean initSql = true;
|
||||
|
||||
/**
|
||||
* kv查询的长度
|
||||
*/
|
||||
private Integer kvLimitCount = 100;
|
||||
|
||||
public boolean isInitSql() {
|
||||
return initSql;
|
||||
}
|
||||
|
@ -38,4 +43,12 @@ public class CoreProperties {
|
|||
public void setInitSql(boolean initSql) {
|
||||
this.initSql = initSql;
|
||||
}
|
||||
|
||||
public Integer getKvLimitCount() {
|
||||
return kvLimitCount;
|
||||
}
|
||||
|
||||
public void setKvLimitCount(Integer kvLimitCount) {
|
||||
this.kvLimitCount = kvLimitCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@ public class ParserCache {
|
|||
* entity类-表名的缓存
|
||||
*/
|
||||
private static Map<String, String> entityClassTableCacheMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* entity类小驼峰-entity类
|
||||
*/
|
||||
private static Map<String, Class<?>> entityLowerCaseCamelEntityClassCacheMap = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* dto类-BindQuery注解的缓存
|
||||
*/
|
||||
|
@ -117,6 +121,7 @@ public class ParserCache {
|
|||
Class<?> entityClass = Class.forName(entityClassName);
|
||||
TableLinkage linkage = new TableLinkage(entityClass, m);
|
||||
tableToLinkageCacheMap.put(linkage.getTable(), linkage);
|
||||
entityLowerCaseCamelEntityClassCacheMap.put(entityClass.getSimpleName(), entityClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +174,16 @@ public class ParserCache {
|
|||
return tableName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据类的entity小驼峰获取EntityClass
|
||||
* @return
|
||||
*/
|
||||
public static Class<?> getEntityClassByEntityLowerCaseCamel(String table){
|
||||
initTableToLinkageCacheMap();
|
||||
return entityLowerCaseCamelEntityClassCacheMap.get(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前DTO是否有Join绑定
|
||||
* @param dto dto对象
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package com.diboot.core.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.diboot.core.binding.parser.ParserCache;
|
||||
import com.diboot.core.config.BaseConfig;
|
||||
import com.diboot.core.dto.AttachMoreDTO;
|
||||
import com.diboot.core.entity.Dictionary;
|
||||
import com.diboot.core.entity.ValidList;
|
||||
import com.diboot.core.service.BaseService;
|
||||
import com.diboot.core.service.DictionaryService;
|
||||
import com.diboot.core.util.BeanUtils;
|
||||
import com.diboot.core.util.ContextHelper;
|
||||
import com.diboot.core.util.S;
|
||||
import com.diboot.core.util.V;
|
||||
import com.diboot.core.vo.JsonResult;
|
||||
import com.diboot.core.vo.KeyValue;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 获取附加属性的通用接口
|
||||
*
|
||||
* @author : uu
|
||||
* @version : v2.0
|
||||
* @Date 2020/6/11 16:02
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/attachMore")
|
||||
public class AttachMoreController {
|
||||
|
||||
@Autowired
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(AttachMoreController.class);
|
||||
|
||||
/**
|
||||
* 获取kvList的通用接口
|
||||
*
|
||||
* @param attachMoreDTOList
|
||||
* @return
|
||||
*/
|
||||
@PostMapping
|
||||
public JsonResult attachMore(@Valid @RequestBody ValidList<AttachMoreDTO> attachMoreDTOList) {
|
||||
Map<String, Object> result = new HashMap<>(16);
|
||||
String kvLimitCountStr = BaseConfig.getProperty("diboot.core.kv-limit-count", "100");
|
||||
Integer kvLimitCount = 100;
|
||||
try {
|
||||
kvLimitCount = Integer.valueOf(kvLimitCountStr);
|
||||
} catch (Exception e) {
|
||||
log.warn("diboot.core.kvLimitCount配置只能为整数,当前使用默认配置长度【100】", e);
|
||||
}
|
||||
for (AttachMoreDTO attachMoreDTO : attachMoreDTOList) {
|
||||
AttachMoreDTO.REF_TYPE type = attachMoreDTO.getType();
|
||||
if (type.equals(AttachMoreDTO.REF_TYPE.D)) {
|
||||
List<KeyValue> keyValueList = dictionaryService.getKeyValueList(
|
||||
Wrappers.query()
|
||||
.select(S.toSnakeCase(BeanUtils.convertToFieldName(Dictionary::getItemName)), S.toSnakeCase(BeanUtils.convertToFieldName(Dictionary::getItemValue)))
|
||||
.eq(S.toSnakeCase(BeanUtils.convertToFieldName(Dictionary::getType)), attachMoreDTO.getTarget())
|
||||
.gt(S.toSnakeCase(BeanUtils.convertToFieldName(Dictionary::getParentId)), 0)
|
||||
.last("limit " + kvLimitCount)
|
||||
);
|
||||
result.put(S.toLowerCaseCamel(attachMoreDTO.getTarget()) + "KvList", keyValueList);
|
||||
} else if (type.equals(AttachMoreDTO.REF_TYPE.T)) {
|
||||
String lowerCaseCamelEntityName = attachMoreDTO.getTarget();
|
||||
String entityClassName = S.capFirst(lowerCaseCamelEntityName);
|
||||
Class<?> entityClass = ParserCache.getEntityClassByEntityLowerCaseCamel(entityClassName);
|
||||
if (V.isEmpty(entityClass)) {
|
||||
log.warn("传递错误的实体类型:{}", attachMoreDTO.getTarget());
|
||||
continue;
|
||||
}
|
||||
String value = V.isEmpty(attachMoreDTO.getValue()) ? ContextHelper.getPrimaryKey(entityClass) : attachMoreDTO.getValue();
|
||||
String key = attachMoreDTO.getKey();
|
||||
if (V.isEmpty(key)) {
|
||||
for (Field field : entityClass.getDeclaredFields()) {
|
||||
if (V.equals(field.getType().getName(), String.class.getName())) {
|
||||
key = field.getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BaseService baseService = ContextHelper.getBaseServiceByEntity(entityClass);
|
||||
List<KeyValue> keyValueList = baseService.getKeyValueList(
|
||||
Wrappers.query()
|
||||
.select(key, value)
|
||||
.last("limit " + kvLimitCount)
|
||||
);
|
||||
result.put(lowerCaseCamelEntityName + "KvList", keyValueList);
|
||||
} else {
|
||||
log.error("错误的加载绑定类型:{}", attachMoreDTO.getType());
|
||||
}
|
||||
}
|
||||
return JsonResult.OK(result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.diboot.core.dto;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* attachMore 根据传递的格式,自动加载相关的kvList
|
||||
* <p>
|
||||
* [{type: 'T', target: 'category', value: 'id', key: 'name’}, {type: 'D', target: 'GENDER'}]
|
||||
*
|
||||
* @author : uu
|
||||
* @version : v2.0
|
||||
* @Date 2020/6/11 15:42
|
||||
*/
|
||||
public class AttachMoreDTO implements Serializable {
|
||||
/**
|
||||
* 关联类型
|
||||
*/
|
||||
public enum REF_TYPE {
|
||||
/**
|
||||
* 绑定的是对象
|
||||
*/
|
||||
T,
|
||||
/**
|
||||
* 绑定的是字典
|
||||
*/
|
||||
D
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联的类型
|
||||
*/
|
||||
@NotNull(message = "绑定类型不能为空,且只能为:T或D类型!")
|
||||
private REF_TYPE type;
|
||||
|
||||
/**
|
||||
* 指向的实体类 或者 字典的type
|
||||
* <p>
|
||||
* 当{@link REF_TYPE#T} target指向实体的小驼峰命名
|
||||
* 当{@link REF_TYPE#D} target指向{@link com.diboot.core.entity.Dictionary#type}
|
||||
*/
|
||||
@NotNull(message = "查询类型不能为空!")
|
||||
private String target;
|
||||
|
||||
/**
|
||||
* 需要的key字段
|
||||
* 当{@link REF_TYPE#T} key为表中字段名称
|
||||
* 当{@link REF_TYPE#D} key为表中{@link com.diboot.core.entity.Dictionary#itemName}
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 需要查询的value字段
|
||||
* 当{@link REF_TYPE#T} key为表中字段名称
|
||||
* 当{@link REF_TYPE#D} key为表中{@link com.diboot.core.entity.Dictionary#itemValue}
|
||||
*/
|
||||
private String value;
|
||||
|
||||
public REF_TYPE getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(REF_TYPE type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(String target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -447,6 +447,10 @@ public class BaseServiceImpl<M extends BaseCrudMapper<T>, T> extends ServiceImpl
|
|||
String[] keyValueArray = sqlSelect.split(Cons.SEPARATOR_COMMA);
|
||||
List<KeyValue> keyValueList = new ArrayList<>(mapList.size());
|
||||
for(Map<String, Object> map : mapList){
|
||||
// 如果key和value的的值都为null的时候map也为空,则不处理此项
|
||||
if (V.isEmpty(map)) {
|
||||
continue;
|
||||
}
|
||||
String key = keyValueArray[0], value = keyValueArray[1], ext = null;
|
||||
// 兼容oracle大写
|
||||
if(map.containsKey(key) == false && map.containsKey(key.toUpperCase())){
|
||||
|
|
|
@ -23,13 +23,16 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.apache.shiro.mgt.SessionsSecurityManager;
|
||||
import org.apache.shiro.realm.Realm;
|
||||
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
|
||||
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
@ -38,7 +41,8 @@ import java.util.Map;
|
|||
|
||||
/**
|
||||
* IAM自动配置类
|
||||
* @author : wee
|
||||
*
|
||||
* @author : uu
|
||||
* @version : v2.0
|
||||
* @Date 2019-10-11 10:54
|
||||
*/
|
||||
|
@ -46,7 +50,7 @@ import java.util.Map;
|
|||
@Configuration
|
||||
@EnableConfigurationProperties({IamBaseProperties.class})
|
||||
@ComponentScan(basePackages = {"com.diboot.iam"})
|
||||
@MapperScan(basePackages={"com.diboot.iam.mapper"})
|
||||
@MapperScan(basePackages = {"com.diboot.iam.mapper"})
|
||||
@Order(10)
|
||||
public class IamBaseAutoConfig {
|
||||
|
||||
|
@ -55,7 +59,7 @@ public class IamBaseAutoConfig {
|
|||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(IamBasePluginManager.class)
|
||||
public IamBasePluginManager iamBasePluginManager(){
|
||||
public IamBasePluginManager iamBasePluginManager() {
|
||||
IamBasePluginManager pluginManager = new IamBasePluginManager();
|
||||
pluginManager.initPlugin(iamBaseProperties);
|
||||
System.out.println(iamBaseProperties);
|
||||
|
@ -64,19 +68,19 @@ public class IamBaseAutoConfig {
|
|||
|
||||
/**
|
||||
* 根据用户配置的缓存类初始化CacheManager,默认为Shiro内存缓存MemoryConstrainedCacheManager
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CacheManager.class)
|
||||
public CacheManager cacheManager() {
|
||||
String className = iamBaseProperties.getCacheManagerClass();
|
||||
if(V.isEmpty(className)){
|
||||
if (V.isEmpty(className)) {
|
||||
return null;
|
||||
}
|
||||
try{
|
||||
try {
|
||||
return (CacheManager) Class.forName(className).newInstance();
|
||||
}
|
||||
catch (Exception e){
|
||||
} catch (Exception e) {
|
||||
log.warn("无法初始化CacheManager,请检查配置: diboot.iam.cacheManagerClass");
|
||||
return null;
|
||||
}
|
||||
|
@ -84,21 +88,26 @@ public class IamBaseAutoConfig {
|
|||
|
||||
@Bean
|
||||
@DependsOn({"cacheManager"})
|
||||
public Realm realm(){
|
||||
public Realm realm() {
|
||||
BaseJwtRealm realm = new BaseJwtRealm();
|
||||
CacheManager cacheManager = cacheManager();
|
||||
if(cacheManager != null){
|
||||
if (cacheManager != null) {
|
||||
realm.setCachingEnabled(true);
|
||||
realm.setCacheManager(cacheManager);
|
||||
}
|
||||
return realm;
|
||||
}
|
||||
|
||||
//TODO 支持无状态
|
||||
@Bean
|
||||
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SessionsSecurityManager securityManager) {
|
||||
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
|
||||
advisor.setSecurityManager(securityManager);
|
||||
return advisor;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
protected ShiroFilterFactoryBean shiroFilterFactoryBean(SessionsSecurityManager securityManager){
|
||||
protected ShiroFilterFactoryBean shiroFilterFactoryBean(SessionsSecurityManager securityManager) {
|
||||
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
|
||||
// 设置过滤器
|
||||
Map<String, Filter> filters = new LinkedHashMap<>();
|
||||
|
@ -120,20 +129,19 @@ public class IamBaseAutoConfig {
|
|||
|
||||
boolean allAnon = false;
|
||||
String anonUrls = iamBaseProperties.getAnonUrls();
|
||||
if(V.notEmpty(anonUrls)){
|
||||
for(String url : anonUrls.split(Cons.SEPARATOR_COMMA)){
|
||||
if (V.notEmpty(anonUrls)) {
|
||||
for (String url : anonUrls.split(Cons.SEPARATOR_COMMA)) {
|
||||
filterChainDefinitionMap.put(url, "anon");
|
||||
if(url.equals("/**")){
|
||||
if (url.equals("/**")) {
|
||||
allAnon = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
filterChainDefinitionMap.put("/login", "authc");
|
||||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
if(allAnon && iamBaseProperties.isEnablePermissionCheck() == false){
|
||||
if (allAnon && iamBaseProperties.isEnablePermissionCheck() == false) {
|
||||
filterChainDefinitionMap.put("/**", "anon");
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
filterChainDefinitionMap.put("/**", "jwt");
|
||||
}
|
||||
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
|
||||
|
|
|
@ -18,11 +18,15 @@ package com.diboot.iam.starter;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.*;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
/**
|
||||
* Shiro代理相关配置类(单独定义以避免Properties无法注入的问题)
|
||||
* @author : wee
|
||||
*
|
||||
* @author : uu
|
||||
* @version : v2.0
|
||||
* @Date 2019-10-11 10:54
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue