diff --git a/sql/mall.sql b/sql/optional/mall/mall.sql similarity index 100% rename from sql/mall.sql rename to sql/optional/mall/mall.sql diff --git a/sql/jimureport.mysql5.7.create.sql b/sql/optional/visualization/jimureport.mysql5.7.create.sql similarity index 100% rename from sql/jimureport.mysql5.7.create.sql rename to sql/optional/visualization/jimureport.mysql5.7.create.sql diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java index e11a3236a..872e66423 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java @@ -115,7 +115,7 @@ public class WebFrameworkUtils { return (CommonResult) request.getAttribute(REQUEST_ATTRIBUTE_COMMON_RESULT); } - private static HttpServletRequest getRequest() { + public static HttpServletRequest getRequest() { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); if (!(requestAttributes instanceof ServletRequestAttributes)) { return null; diff --git a/yudao-module-visualization/yudao-module-visualization-biz/pom.xml b/yudao-module-visualization/yudao-module-visualization-biz/pom.xml index 478079e28..142012940 100644 --- a/yudao-module-visualization/yudao-module-visualization-biz/pom.xml +++ b/yudao-module-visualization/yudao-module-visualization-biz/pom.xml @@ -14,7 +14,8 @@ ${project.artifactId} - visualization 模块,主要实现数据可视化报表等功能。 + visualization 模块,主要实现数据可视化报表等功能: + 1. 基于「积木报表」实现,打印设计、报表设计、图形设计、大屏设计等。 @@ -62,7 +63,13 @@ org.jeecgframework.jimureport jimureport-spring-boot-starter + + + mongodb-driver-sync + org.mongodb + + - \ No newline at end of file + diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/config/JimuReportTokenService.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/config/JimuReportTokenService.java deleted file mode 100644 index 9463e75f8..000000000 --- a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/config/JimuReportTokenService.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.visualization.config; - -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; -import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; -import cn.iocoder.yudao.module.system.service.user.AdminUserService; -import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class JimuReportTokenService implements JmReportTokenServiceI { - @Autowired - private OAuth2TokenApi oauth2TokenApi; - - @Autowired - private AdminUserService adminUserService; - - @Override - public String getUsername(String token) { - if (StrUtil.isNotEmpty(token)) { - OAuth2AccessTokenCheckRespDTO accessToken = oauth2TokenApi.checkAccessToken(token); - if (accessToken != null) { - Long userId = accessToken.getUserId(); - System.out.println(userId); - AdminUserDO user = adminUserService.getUser(userId); - if (user != null) { - return user.getUsername(); - } - } - } - return null; - } - - @Override - public Boolean verifyToken(String token) { - if (StrUtil.isNotEmpty(token)) { - OAuth2AccessTokenCheckRespDTO accessToken = oauth2TokenApi.checkAccessToken(token); - return accessToken != null; - } - return false; - } -} \ No newline at end of file diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java new file mode 100644 index 000000000..3819c5194 --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/config/JmReportConfiguration.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.visualization.framework.jmreport.config; + +import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; +import cn.iocoder.yudao.module.visualization.framework.jmreport.core.service.JmReportTokenServiceImpl; +import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 积木报表的配置类 + * + * @author 芋道源码 + */ +@Configuration +public class JmReportConfiguration { + + @Bean + @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") + public JmReportTokenServiceI jmReportTokenService(OAuth2TokenApi oAuth2TokenApi) { + return new JmReportTokenServiceImpl(oAuth2TokenApi); + } + +} diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java new file mode 100644 index 000000000..511465786 --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/service/JmReportTokenServiceImpl.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.visualization.framework.jmreport.core.service; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.framework.security.core.LoginUser; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; +import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; +import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO; +import lombok.RequiredArgsConstructor; +import org.jeecg.modules.jmreport.api.JmReportTokenServiceI; + +/** + * {@link JmReportTokenServiceI} 实现类,提供积木报表的 Token 校验、用户信息的查询等功能 + * + * @author 随心 + */ +@RequiredArgsConstructor +public class JmReportTokenServiceImpl implements JmReportTokenServiceI { + + private final OAuth2TokenApi oauth2TokenApi; + + /** + * 校验 Token 是否有效,即验证通过 + * + * @param token JmReport 前端传递的 token + * @return 是否认证通过 + */ + @Override + public Boolean verifyToken(String token) { + if (StrUtil.isEmpty(token)) { + return false; + } + // TODO 如下的实现不算特别优雅,主要咱是不想搞的太复杂,所以参考对应的 Filter 先实现了 + + // ① 参考 TokenAuthenticationFilter 的认证逻辑(Security 的上下文清理,交给 Spring Security 完成) + // 目的:实现基于 JmReport 前端传递的 token,实现认证 + TenantContextHolder.setIgnore(true); // 忽略租户,保证可查询到 token 信息 + LoginUser user = null; + try { + OAuth2AccessTokenCheckRespDTO accessToken = oauth2TokenApi.checkAccessToken(token); + if (accessToken == null) { + return false; + } + user = new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType()) + .setTenantId(accessToken.getTenantId()).setScopes(accessToken.getScopes()); + } catch (ServiceException ignored) { + // do nothing:如果报错,说明认证失败,则返回 false 即可 + } + if (user == null) { + return false; + } + SecurityFrameworkUtils.setLoginUser(user, WebFrameworkUtils.getRequest()); + + // ② 参考 TenantContextWebFilter 实现(Tenant 的上下文清理,交给 TenantContextWebFilter 完成) + // 目的:基于 LoginUser 获得到的租户编号,设置到 Tenant 上下文,避免查询数据库时的报错 + TenantContextHolder.setIgnore(false); + TenantContextHolder.setTenantId(user.getTenantId()); + return true; + } + + /** + * 获得用户编号 + * + * 虽然方法名获得的是 username,实际对应到项目中是用户编号 + * + * @param token JmReport 前端传递的 token + * @return 用户编号 + */ + @Override + public String getUsername(String token) { + Long userId = SecurityFrameworkUtils.getLoginUserId(); + return userId != null ? String.valueOf(userId) : null; + } + +} diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/web/package-info.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/web/package-info.java new file mode 100644 index 000000000..140fce2a2 --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/jmreport/core/web/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位,后续会基于 Filter 实现积木报表的认证等功能,替代 {@link cn.iocoder.yudao.module.visualization.framework.jmreport.core.service.JmReportTokenServiceImpl} + */ +package cn.iocoder.yudao.module.visualization.framework.jmreport.core.web; diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/package-info.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/package-info.java new file mode 100644 index 000000000..af863b522 --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/package-info.java @@ -0,0 +1,6 @@ +/** + * 属于 visualization 模块的 framework 封装 + * + * @author 芋道源码 + */ +package cn.iocoder.yudao.module.visualization.framework; diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/security/config/SecurityConfiguration.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/security/config/SecurityConfiguration.java new file mode 100644 index 000000000..7e1567dff --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/security/config/SecurityConfiguration.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.visualization.framework.security.config; + +import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer; + +/** + * Visualization 模块的 Security 配置 + */ +@Configuration("visualizationSecurityConfiguration") +public class SecurityConfiguration { + + @Bean("visualizationAuthorizeRequestsCustomizer") + public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() { + return new AuthorizeRequestsCustomizer() { + + @Override + public void customize(ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry registry) { + //积木报表 + registry.antMatchers("/jmreport/**").permitAll(); + } + + }; + } + +} diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/security/core/package-info.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/security/core/package-info.java new file mode 100644 index 000000000..21585321c --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/security/core/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.visualization.framework.security.core; diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/ureport/package-info.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/ureport/package-info.java new file mode 100644 index 000000000..1d825674b --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/framework/ureport/package-info.java @@ -0,0 +1,7 @@ +/** + * ureport2:https://github.com/youseries/ureport + * + * ureport2 和 jimurepot 是相同类型的产品,不过停更了,最好发布时间是 2018 年。 + * 它们之间的功能对比,可见 https://juejin.cn/post/6939836480269320200 地址 + */ +package cn.iocoder.yudao.module.visualization.framework.ureport; diff --git a/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/package-info.java b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/package-info.java new file mode 100644 index 000000000..cc501dcb8 --- /dev/null +++ b/yudao-module-visualization/yudao-module-visualization-biz/src/main/java/cn/iocoder/yudao/module/visualization/package-info.java @@ -0,0 +1,9 @@ +/** + * visualization 模块,主要实现数据可视化报表等功能: + * 1. 基于「积木报表」实现,打印设计、报表设计、图形设计、大屏设计等。URL 前缀是 /jmreport,表名前缀是 jimu_ + * + * 由于「积木报表」的大屏设计器需要收费,后续会自研,对应的是: + * 1. Controller URL:以 /visualization/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 visualization_ 开头,方便在数据库中区分 + */ +package cn.iocoder.yudao.module.visualization; diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 4c242eeb0..a35f5f9f6 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -58,11 +58,11 @@ ${revision} - - cn.iocoder.boot - yudao-module-bpm-biz - ${revision} - + + + + + diff --git a/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java b/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java index d695a2598..b6bd16a22 100644 --- a/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java +++ b/yudao-server/src/main/java/cn/iocoder/yudao/server/YudaoServerApplication.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.server; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; /** * 项目的启动类 @@ -14,7 +13,7 @@ import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; * @author 芋道源码 */ @SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package} -@SpringBootApplication(exclude = MongoAutoConfiguration.class, scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module", "org.jeecg.modules.jmreport"}) +@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module", "org.jeecg.modules.jmreport"}) public class YudaoServerApplication { public static void main(String[] args) { diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 5b4c550ea..6de6ae46d 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -96,7 +96,8 @@ yudao: - /admin-api/infra/file/*/get/** # 获取图片,和租户无关 - /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号 - /app-api/pay/order/notify/* # 支付回调通知,不携带租户编号 - - /jmreport/list +# - /jmreport/list + - /jmreport/* ignore-tables: - system_tenant - system_tenant_package @@ -148,4 +149,4 @@ debug: false #积木报表配置 minidao : base-package: org.jeecg.modules.jmreport.desreport.dao* - db-type: mysql \ No newline at end of file + db-type: mysql