存在本 bean 即满足 {@code yh-env-config-spring-boot-starter} 的自动装配条件(聚合 starter 已携带该模块), + * 自动注册免登录 {@code GET /api/env-config?target=front}:EnvConfigSsoBypassFilter(HIGHEST+3) + * 抢在 yh-auth 的 CAS 过滤链(yh.sso.url-pattern=/api/*,HIGHEST+4 起)之前 forward 旁路,SPA 登录前可拉。 + */ +@Service +public class PropertyEnvConfigSource implements EnvConfigSource { + + private static final String KEY_PREFIX = "yh.env-config.source."; + + private final Environment environment; + + public PropertyEnvConfigSource(Environment environment) { + this.environment = environment; + } + + @Override + public String get(String target) { + return environment.getProperty(KEY_PREFIX + target); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 204e0ab..3e3a7c5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -70,3 +70,12 @@ yh: user-center-url: http://base.yunhaixingtong.com/userbase # 班级管理(userclass)服务基址(原 bschclass 路由已下线) userclass: http://base.yunhaixingtong.com/userclass + # env-config 前端运行时配置(免登录 GET /api/env-config?target=front,数据源见 + # config/PropertyEnvConfigSource:聚合 starter 自动装配,有 bean 即注册端点)。 + # 本地无需配值(前端 dev 走 .env.dev);线上值经环境变量 YH_ENV_CONFIG_SOURCE_FRONT + # 或同名键 yh.env-config.source.front 注入(projman 配置管理维护),未配置时端点返回 {}, + # 前端走同域推导兜底(serviceHost/baseHost 正确,ssoHost 为空登出跳转不可用)。 + # 如需本地联调可打开: + # env-config: + # source: + # front: '{"baseHost":"http://base.yunhaixingtong.com","ssoHost":"http://sso.yunhaixingtong.com","serviceHost":"http://localhost:8101","relayConf":{"ziyuankuHost":"https://base.bestsch.com/BschZyk","zhuanxiangHost":"https://base.bestsch.com/BschZncpd"}}' diff --git a/src/test/java/com/yunhai/notice/config/EnvConfigApiIT.java b/src/test/java/com/yunhai/notice/config/EnvConfigApiIT.java new file mode 100644 index 0000000..85d45e1 --- /dev/null +++ b/src/test/java/com/yunhai/notice/config/EnvConfigApiIT.java @@ -0,0 +1,51 @@ +package com.yunhai.notice.config; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * env-config 端点契约(Cms/UserHome 同款机制,前端 SPA 运行时配置来源)。 + * 必须起真实端口:端点靠平台 EnvConfigSsoBypassFilter(HIGHEST+3)forward 旁路 CAS 过滤链 + * (yh.sso.url-pattern=/api/*),MockMvc 的模拟 RequestDispatcher 不执行 forward 派发, + * 只有真实 Tomcat 上才能验证「匿名 GET 直达 Controller 而非 302 登录页」。 + * 本用例同时是平台 starter 的回归哨兵:envConfigSsoBypassFilter 的 + * {@code @ConditionalOnMissingBean} 曾因 FilterRegistrationBean 泛型擦除误判跳过(平台已修)。 + * + *
数据源 PropertyEnvConfigSource 读键 yh.env-config.source.<target>,本类注入 front 值
+ * (前端部署目录名 front,生产由 projman 配置管理维护);未配置的 target 由平台
+ * EnvConfigService 归一为 "{}" 返回(接口恒 200,前端走同域推导兜底)。
+ */
+@DisplayName("EnvConfigApi - /api/env-config 免登录运行时配置端点(真实端口)")
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
+ "yh.env-config.source.front={\"baseHost\":\"http://base.yunhaixingtong.com\",\"ssoHost\":\"http://sso.yunhaixingtong.com\",\"serviceHost\":\"/notice\"}",
+ // 专属测试库(仿 Cms bsch_cms_test):本机无开发库 bsch_notice 也能起上下文,且不碰开发库;
+ // createDatabaseIfNotExist 首次运行自动建库,表结构由 ddl-auto=update 生成
+ "spring.datasource.url=jdbc:mysql://localhost:3306/bsch_notice_test?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8&connectionCollation=utf8mb4_general_ci&serverTimezone=Asia/Shanghai"})
+class EnvConfigApiIT {
+
+ @Autowired
+ private TestRestTemplate rest;
+
+ @Test
+ @DisplayName("target=front 已配置:旁路 CAS 匿名 200,返回注入的 JSON 原文(无 {code,msg,data} 包装)")
+ void configuredTarget_bypassesCasAndReturnsInjectedJson() {
+ ResponseEntity