diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java index 63c9955f3..4f89c8be2 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/ReportDatasourceController.java @@ -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> getBeanDatasourceList() { + return success(datasourceService.getBeanDatasourceList()); + } + + @GetMapping("/datasource/bean/methods") + @Operation(summary = "获取springbean数据源方法类表") + @PreAuthorize("@ss.hasPermission('report:datasource:query')") + public CommonResult> getBeanDatasourceList(@RequestParam(value = "beanId") String beanId) { + return success(datasourceService.loadBeanMethods(beanId)); + } } diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/vo/ReportBeanDatasourceRespVO.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/vo/ReportBeanDatasourceRespVO.java new file mode 100644 index 000000000..bb7e69351 --- /dev/null +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/controller/admin/datasource/vo/ReportBeanDatasourceRespVO.java @@ -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; +} diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/annotation/CfReportSpringbeanDatasource.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/annotation/CfReportSpringbeanDatasource.java new file mode 100644 index 000000000..aac8bb3da --- /dev/null +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/annotation/CfReportSpringbeanDatasource.java @@ -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(); +} diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/bean/MockBeanDatasource.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/bean/MockBeanDatasource.java new file mode 100644 index 000000000..c02c33568 --- /dev/null +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/bean/MockBeanDatasource.java @@ -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> mockList(String dsName, String datasetName, Map parameters) { + List> testList = new ArrayList<>(); + testList.add(new HashMap() {{ + put("a", "11111"); + put("b", "一一一一一一"); + }}); + testList.add(new HashMap() {{ + put("a", "22222"); + put("b", "二二二二二二"); + }}); + return testList; + } +} diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/config/CfReportSpringbeanRegistrar.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/config/CfReportSpringbeanRegistrar.java new file mode 100644 index 000000000..907477896 --- /dev/null +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/config/CfReportSpringbeanRegistrar.java @@ -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 candidates = scanner.findCandidateComponents("com.cf.imes.module.report.framework.ureport.bean"); + + for (BeanDefinition candidate : candidates) { + if (candidate instanceof AnnotatedBeanDefinition) { + AnnotatedBeanDefinition beanDef = (AnnotatedBeanDefinition) candidate; + Map 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()); + } + } + } + } +} diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/config/ReportConfig.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/config/ReportConfig.java new file mode 100644 index 000000000..e5f7b56dc --- /dev/null +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/framework/ureport/config/ReportConfig.java @@ -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 { +} \ No newline at end of file diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java index 153fd6b03..a2ea0a14b 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceService.java @@ -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 getTemplateDatasourceList(ReportDatasourceReqVO reqVO); + /** + * 获取springbean数据源列表 + * + * @return + */ + List getBeanDatasourceList(); + /** + * 获取bean方法 + * + * @param beanId + * @return + */ + List loadBeanMethods(String beanId); } diff --git a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java index cd7544378..dad1f6368 100644 --- a/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java +++ b/cf-module-report/cf-module-report-biz/src/main/java/com/cf/imes/module/report/service/datasource/ReportDatasourceServiceImpl.java @@ -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 getBeanDatasourceList() { + Map beansWithAnnotation = applicationContext.getBeansWithAnnotation(CfReportSpringbeanDatasource.class); + List beanDatasourceRespVOList = new ArrayList<>(); + for (Map.Entry 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 loadBeanMethods(String beanId) { + Object obj = applicationContext.getBean(beanId); + Class clazz = obj.getClass(); + Method[] methods = clazz.getMethods(); + List result = new ArrayList(); + // ureport的springbean方法必须满足(String dsName, String datasetName, Map 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; + } }