报表基础模块:springbean数据源列表、加载bean数据源类方法接口实现

This commit is contained in:
gaoqr
2024-07-12 14:45:24 +08:00
parent 96906201be
commit e9b8db8d04
8 changed files with 229 additions and 0 deletions
@@ -2,6 +2,7 @@ package com.cf.imes.module.report.controller.admin.datasource;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
@@ -77,4 +78,18 @@ public class ReportDatasourceController {
ReportDatasourceReqVO reqVO = new ReportDatasourceReqVO(reportId, name, type);
return success(BeanUtils.toBean(datasourceService.getTemplateDatasourceList(reqVO), ReportDatasourceRespVO.class));
}
@GetMapping("/datasource/beans")
@Operation(summary = "获取springbean数据源列表")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<List<ReportBeanDatasourceRespVO>> getBeanDatasourceList() {
return success(datasourceService.getBeanDatasourceList());
}
@GetMapping("/datasource/bean/methods")
@Operation(summary = "获取springbean数据源方法类表")
@PreAuthorize("@ss.hasPermission('report:datasource:query')")
public CommonResult<List<String>> getBeanDatasourceList(@RequestParam(value = "beanId") String beanId) {
return success(datasourceService.loadBeanMethods(beanId));
}
}
@@ -0,0 +1,22 @@
package com.cf.imes.module.report.controller.admin.datasource.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Gqr
* @since 2024/7/11 18:02
*/
@Schema(description = "管理后台 - 报表springbean数据源 Response VO")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ReportBeanDatasourceRespVO {
private String value;
private String name;
}
@@ -0,0 +1,32 @@
package com.cf.imes.module.report.framework.ureport.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 晨丰报表springbean数据源注解
*
* @author Gqr
* @since 2024/7/11 17:01
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CfReportSpringbeanDatasource {
/**
* beanid
*
* @return
*/
String value();
/**
* bean说明
*
* @return
*/
String name();
}
@@ -0,0 +1,29 @@
package com.cf.imes.module.report.framework.ureport.bean;
import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Gqr
* @since 2024/7/11 17:15
*/
@CfReportSpringbeanDatasource(value = "MockBeanDatasource", name = "模拟bean数据源")
public class MockBeanDatasource {
public List<Map<String, Object>> mockList(String dsName, String datasetName, Map<String, Object> parameters) {
List<Map<String, Object>> testList = new ArrayList<>();
testList.add(new HashMap<String, Object>() {{
put("a", "11111");
put("b", "一一一一一一");
}});
testList.add(new HashMap<String, Object>() {{
put("a", "22222");
put("b", "二二二二二二");
}});
return testList;
}
}
@@ -0,0 +1,48 @@
package com.cf.imes.module.report.framework.ureport.config;
import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.StringUtils;
import java.util.Map;
import java.util.Set;
/**
* 扫描com.cf.imes.module.report.framework.ureport.bean下的类,带有CfReportSpringbeanDatasource的类注入到spring中
*
* @author Gqr
* @since 2024/7/11 17:21
*/
public class CfReportSpringbeanRegistrar implements ImportBeanDefinitionRegistrar {
private static final TypeFilter cfReportSpringBeanDatasourceFilter = (metadataReader, metadataReaderFactory) -> metadataReader.getAnnotationMetadata().hasAnnotation(CfReportSpringbeanDatasource.class.getName());
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
scanner.addIncludeFilter(cfReportSpringBeanDatasourceFilter); // 添加自定义的过滤器
Set<BeanDefinition> candidates = scanner.findCandidateComponents("com.cf.imes.module.report.framework.ureport.bean");
for (BeanDefinition candidate : candidates) {
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition beanDef = (AnnotatedBeanDefinition) candidate;
Map<String, Object> attributes = beanDef.getMetadata().getAnnotationAttributes(CfReportSpringbeanDatasource.class.getName());
if (attributes != null) {
String value = (String) attributes.get("value");
if (!StringUtils.hasText(value)) {
throw new IllegalArgumentException("@CfReportSpringbean requires a non-empty 'value' attribute.");
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(candidate.getBeanClassName());
registry.registerBeanDefinition(value, builder.getBeanDefinition());
}
}
}
}
}
@@ -0,0 +1,13 @@
package com.cf.imes.module.report.framework.ureport.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author Gqr
* @since 2024/7/11 17:30
*/
@Configuration
@Import(CfReportSpringbeanRegistrar.class)
public class ReportConfig {
}
@@ -1,5 +1,6 @@
package com.cf.imes.module.report.service.datasource;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
@@ -52,5 +53,18 @@ public interface ReportDatasourceService {
*/
List<ReportDatasourceDO> getTemplateDatasourceList(ReportDatasourceReqVO reqVO);
/**
* 获取springbean数据源列表
*
* @return
*/
List<ReportBeanDatasourceRespVO> getBeanDatasourceList();
/**
* 获取bean方法
*
* @param beanId
* @return
*/
List<String> loadBeanMethods(String beanId);
}
@@ -1,16 +1,23 @@
package com.cf.imes.module.report.service.datasource;
import cn.hutool.core.annotation.AnnotationUtil;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportBeanDatasourceRespVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceReqVO;
import com.cf.imes.module.report.controller.admin.datasource.vo.ReportDatasourceSaveReqVO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import com.cf.imes.module.report.dal.mysql.datasource.ReportDatasourceMapper;
import com.cf.imes.module.report.framework.ureport.annotation.CfReportSpringbeanDatasource;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_NOT_EXISTS;
@@ -27,6 +34,12 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService {
@Resource
private ReportDatasourceMapper datasourceMapper;
private final ApplicationContext applicationContext;
public ReportDatasourceServiceImpl(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public Long createDatasource(ReportDatasourceSaveReqVO createReqVO) {
// 插入
@@ -77,4 +90,47 @@ public class ReportDatasourceServiceImpl implements ReportDatasourceService {
.eqIfPresent(ReportDatasourceDO::getType, reqVO.getType())
.orderByDesc(ReportDatasourceDO::getCreateTime));
}
@Override
public List<ReportBeanDatasourceRespVO> getBeanDatasourceList() {
Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(CfReportSpringbeanDatasource.class);
List<ReportBeanDatasourceRespVO> beanDatasourceRespVOList = new ArrayList<>();
for (Map.Entry<String, Object> entry : beansWithAnnotation.entrySet()) {
Class<?> beanClass = entry.getValue().getClass();
ReportBeanDatasourceRespVO respVO = ReportBeanDatasourceRespVO.builder()
.value(AnnotationUtil.getAnnotationValue(beanClass, CfReportSpringbeanDatasource.class, "value").toString())
.name(AnnotationUtil.getAnnotationValue(beanClass, CfReportSpringbeanDatasource.class, "name").toString()).build();
beanDatasourceRespVOList.add(respVO);
}
return beanDatasourceRespVOList;
}
@Override
public List<String> loadBeanMethods(String beanId) {
Object obj = applicationContext.getBean(beanId);
Class<?> clazz = obj.getClass();
Method[] methods = clazz.getMethods();
List<String> result = new ArrayList<String>();
// ureport的springbean方法必须满足(String dsName, String datasetName, Map<String, Object> parameters
for (Method method : methods) {
Class<?>[] types = method.getParameterTypes();
if (types.length != 3) {
continue;
}
Class<?> typeClass1 = types[0];
Class<?> typeClass2 = types[1];
Class<?> typeClass3 = types[2];
if (!String.class.isAssignableFrom(typeClass1)) {
continue;
}
if (!String.class.isAssignableFrom(typeClass2)) {
continue;
}
if (!Map.class.isAssignableFrom(typeClass3)) {
continue;
}
result.add(method.getName());
}
return result;
}
}