fix(portal): 服务中心/指南页顶导航高亮——外链栏目匹配为当前栏目,首页不再误高亮(8 主题兜底 navServiceActive)
build / build-push (push) Successful in 1m43s

This commit is contained in:
chenxing
2026-09-17 01:10:14 +08:00
parent 649ad66264
commit 89a5a346d3
9 changed files with 75 additions and 8 deletions
@@ -343,6 +343,7 @@ public class PortalController {
}
String effectiveTheme = pageRenderer.resolveEffectiveTheme(site, "service.html");
PortalUrlHelper url = buildUrl(site, request, effectiveTheme);
applyServiceNavHighlight(site, url, model);
SvcItemPortalQuery query = new SvcItemPortalQuery();
query.setSiteId(site.getId());
@@ -442,6 +443,7 @@ public class PortalController {
}
String effectiveTheme = pageRenderer.resolveEffectiveTheme(site, "guide.html");
PortalUrlHelper url = buildUrl(site, request, effectiveTheme);
applyServiceNavHighlight(site, url, model);
model.addAttribute("svcUnavailable", svcUnavailable);
if (svcUnavailable) {
addChromeAttributes(model, site, request, effectiveTheme, url, "服务中心 - " + site.getName());
@@ -515,6 +517,71 @@ public class PortalController {
return "themes/" + effectiveTheme + "/guide";
}
/**
* 服务中心/指南页的顶导航高亮:服务中心页不是栏目页,currentCategoryId 为空会让
* 皮肤 header 的"首页"误高亮。若站点导航里存在指向本站服务中心列表页的外链栏目
* (type=3,如"服务中心"),则把它视为当前栏目——既有高亮逻辑即同时达成
* "首页不高亮 + 服务中心高亮";找不到匹配栏目时置 navServiceActive,
* 皮肤以该标记单独关闭"首页"高亮(无服务中心入口的站点保持原状)。
*/
private void applyServiceNavHighlight(PortalSiteSnapshot site, PortalUrlHelper url, Model model) {
String servicePath = pathOf(url.serviceList());
Integer matched = null;
if (servicePath != null) {
for (PortalCategory cat : site.getCategories()) {
if (isServiceNavLink(cat, servicePath)) {
matched = cat.getId();
break;
}
for (PortalCategory sub : cat.getChildren()) {
if (isServiceNavLink(sub, servicePath)) {
matched = sub.getId();
break;
}
}
if (matched != null) {
break;
}
}
}
if (matched != null) {
model.addAttribute("currentCategoryId", matched);
} else {
model.addAttribute("navServiceActive", true);
}
}
private boolean isServiceNavLink(PortalCategory cat, String servicePath) {
Integer type = cat.getType();
return type != null && type == CategoryTypeEnum.LINK.getCode()
&& servicePath.equals(pathOf(cat.getLinkUrl()));
}
/** 取 URL 的归一化路径:剥 scheme://host / query / fragment / 尾斜杠(相对链接原样返回路径) */
private static String pathOf(String url) {
if (url == null) {
return null;
}
String u = url.trim();
int hash = u.indexOf('#');
if (hash >= 0) {
u = u.substring(0, hash);
}
int query = u.indexOf('?');
if (query >= 0) {
u = u.substring(0, query);
}
while (u.endsWith("/")) {
u = u.substring(0, u.length() - 1);
}
int scheme = u.indexOf("://");
if (scheme >= 0) {
int slash = u.indexOf('/', scheme + 3);
u = slash >= 0 ? u.substring(slash) : "";
}
return u.isEmpty() ? null : u;
}
/** 门户页面公共骨架属性(P1-4 降级路径与正常路径共用;q/seoDescription 等页面特有属性由调用方补) */
private void addChromeAttributes(Model model, PortalSiteSnapshot site, HttpServletRequest request,
String effectiveTheme, PortalUrlHelper url, String pageTitle) {
@@ -29,7 +29,7 @@
</div>
<nav class="site-nav">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -39,7 +39,7 @@
<nav class="cg-nav" aria-label="栏目导航">
<ul class="cg-container">
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -30,7 +30,7 @@
</div>
<nav class="site-nav">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -43,7 +43,7 @@
<!-- 栏目导航:外链栏目直接外跳;其余进栏目页(方案 §8.1) -->
<nav class="site-nav" aria-label="栏目导航">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -37,7 +37,7 @@
</div>
<nav class="site-nav">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -31,7 +31,7 @@
</div>
<nav class="site-nav">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -61,7 +61,7 @@
<span></span><span></span><span></span>
</button>
<ul class="sp-nav-list">
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
@@ -29,7 +29,7 @@
</div>
<nav class="site-nav">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<li th:classappend="${currentCategoryId == null and navServiceActive == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"