From 5da6f7ee5d1ee132d9dffa7009c3641c4f5b8793 Mon Sep 17 00:00:00 2001 From: chenxing Date: Tue, 8 Sep 2026 10:51:52 +0800 Subject: [PATCH] =?UTF-8?q?fix(W3):=20=E9=A2=84=E8=A7=88=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E5=89=8D=E7=BC=80=E6=8B=BC=20request.getCont?= =?UTF-8?q?extPath(/yschcms=20=E4=B8=8B=20CSS=20404=20=E8=A3=B8=20HTML),T-?= =?UTF-8?q?W3-01..04=20=E5=85=A8=E7=BB=BF+=E5=85=A8=E9=87=8F=20264/264?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yunhai/cms/utils/PortalUrlHelper.java | 8 +++-- .../com/yunhai/cms/theme/PreviewApiIT.java | 11 +++++++ .../yunhai/cms/utils/PortalUrlHelperTest.java | 31 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/yunhai/cms/utils/PortalUrlHelper.java b/src/main/java/com/yunhai/cms/utils/PortalUrlHelper.java index 6cb088a..d34f0ee 100644 --- a/src/main/java/com/yunhai/cms/utils/PortalUrlHelper.java +++ b/src/main/java/com/yunhai/cms/utils/PortalUrlHelper.java @@ -57,8 +57,12 @@ public class PortalUrlHelper { */ public static PortalUrlHelper forPreview(HttpServletRequest request, String siteCode, String theme) { PortalUrlHelper base = fromRequest(request, siteCode, theme); - // 显式走 5 参构造:第 4 参是 base-origin,代理前缀必须落第 5 参(避免误绑 4 参重载) - return new PortalUrlHelper(base.baseUrl, siteCode, theme, null, "/api/theme/" + theme + "/asset/"); + // 显式走 5 参构造:第 4 参是 base-origin,代理前缀必须落第 5 参(避免误绑 4 参重载)。 + // W3(方案 §7.4):前缀拼 request.getContextPath()——base/prod 上下文 /yschcms 下 + // 不拼会导致 iframe 内 CSS/JS 链接打到网关根 404(预览裸 HTML); + // 空上下文(dev)退化为根相对 /api/theme/…,dev 形态不回归(T-W3-02)。 + return new PortalUrlHelper(base.baseUrl, siteCode, theme, null, + request.getContextPath() + "/api/theme/" + theme + "/asset/"); } /** diff --git a/src/test/java/com/yunhai/cms/theme/PreviewApiIT.java b/src/test/java/com/yunhai/cms/theme/PreviewApiIT.java index c24184d..b5816a8 100644 --- a/src/test/java/com/yunhai/cms/theme/PreviewApiIT.java +++ b/src/test/java/com/yunhai/cms/theme/PreviewApiIT.java @@ -137,6 +137,17 @@ class PreviewApiIT extends CmsIntegrationTestBase { assertThat(body(result)).contains("/api/theme/t-demo-red/asset/css/main.css"); } + @Test + @DisplayName("T-W3-04: 端到端回归:contextPath=/yschcms 时预览资产 href 带上下文前缀") + void previewAssetHrefCarriesContextPathEndToEnd() throws Exception { + MvcResult result = standalone.perform(get("/yschcms/api/theme/preview") + .contextPath("/yschcms") + .param("siteCode", "demo").param("theme", "t-demo-red")) + .andExpect(status().isOk()).andReturn(); + assertThat(body(result)) + .contains("href=\"/yschcms/api/theme/t-demo-red/asset/css/main.css\""); + } + @Test @DisplayName("T26: 预览响应 no-store(不进缓存/CDN)") void previewNoStore() throws Exception { diff --git a/src/test/java/com/yunhai/cms/utils/PortalUrlHelperTest.java b/src/test/java/com/yunhai/cms/utils/PortalUrlHelperTest.java index 0c3e9c3..30f1e25 100644 --- a/src/test/java/com/yunhai/cms/utils/PortalUrlHelperTest.java +++ b/src/test/java/com/yunhai/cms/utils/PortalUrlHelperTest.java @@ -149,6 +149,37 @@ class PortalUrlHelperTest { assertThat(url.rewriteUploadUrls(null)).isNull(); } + // ===== forPreview 预览资产前缀(W3:context-path 修复,方案 §7.3)===== + + @Test + @DisplayName("T-W3-01: forPreview 带上下文:资产前缀含 contextPath") + void forPreview_assetPrefixCarriesContextPath() { + PortalUrlHelper url = PortalUrlHelper.forPreview( + request("http", "base.yunhaixingtong.com", 80, "/yschcms"), "demo", "scholar-blue"); + assertThat(url.asset("css/main.css")) + .isEqualTo("/yschcms/api/theme/scholar-blue/asset/css/main.css"); + } + + @Test + @DisplayName("T-W3-02: forPreview 空上下文退化:前缀 /api/theme/…(dev 形态不回归)") + void forPreview_emptyContextFallsBackToRootPrefix() { + PortalUrlHelper url = PortalUrlHelper.forPreview( + request("http", "localhost", 8072, ""), "demo", "t-demo-red"); + assertThat(url.asset("css/main.css")) + .isEqualTo("/api/theme/t-demo-red/asset/css/main.css"); + } + + @Test + @DisplayName("T-W3-03: forPreview 站内链接不受资产前缀串味(home/category 仍指真实门户)") + void forPreview_homeStaysRealPortal() { + PortalUrlHelper url = PortalUrlHelper.forPreview( + request("http", "base.yunhaixingtong.com", 80, "/yschcms"), "demo", "scholar-blue"); + assertThat(url.home()).isEqualTo("http://base.yunhaixingtong.com/yschcms/portal/demo/"); + assertThat(url.category(3)).isEqualTo("http://base.yunhaixingtong.com/yschcms/portal/demo/c/3"); + assertThat(url.search("x", null)) + .isEqualTo("http://base.yunhaixingtong.com/yschcms/portal/demo/search?q=x"); + } + // ===== siteHome 分支(B-4:学校域形态下未配域子站不再退化为 "/")===== @Test