feat(portal): 门户左侧栏目导航+首页视觉升级+主题正名批次-PortalSideNav模型+attachCategoryNavigation注入doCategory/doArticle三件套categoryPath/navTopId/sideNav(站点快照树推导零新增查询,home/search不注入);7主题侧栏两栏markup+窄屏横滚+顶导航祖先高亮+二级下拉当前项高亮+面包屑全路径;cms_category.home_style全链路(news_grid 16条8x2日期前缀/media_focus形态)+PortalListData.Item补source来源徽标四处装配;Banner机制gallery展示位→galleryBanners四列大图轮播(自由字符串零DDL);页脚config 12新键(footer_addresses多校区/qr_*/social_*含URL校验,footerAddressLines由PortalSiteSnapshot.of拆行派生);新增展示型皮肤包campus-glow;fresh-mint2正名fresh-mint(theme.json/头注释同步);AttachmentService scene白名单加category(单页富文本贴图免清孤儿);新增PortalSideNavIT 8+PortalHomeBlocksIT 3,CategoryServiceIT/SiteServiceIT/PortalSsrIT/ThemeContractIT等单类独跑全绿;附sql/clear_cms_data.sql全量清库脚本(清cms_*六表留平台账号/主题包/上传文件,测试数据重走用)
build / build-push (push) Successful in 1m47s

This commit is contained in:
chenxing
2026-09-10 11:10:48 +08:00
parent f4b1749377
commit 98d640faba
77 changed files with 2564 additions and 175 deletions
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!-- 公共头部:细线顶栏 + 居中品牌行(左:专业院系 / 中:品牌 / 右:站内搜索)+ 栏目导航(《院系子站方案》) -->
<header class="site-header" th:fragment="header">
<div class="header-inner">
<!-- 左:专业院系下拉;顶层站取其子站、院系子站取兄弟站(含自身);无子站不渲染;文案经 config_json.colleges_label 覆盖 -->
<div class="header-aside header-aside-left">
<div class="site-colleges" th:if="${!site.colleges.isEmpty()}"
th:with="collegesLabel=${site.config['colleges_label'] ?: '专业院系'}">
<span class="colleges-toggle">
<a href="javascript:void(0)" th:text="${collegesLabel}">专业院系</a>
<i class="colleges-arrow">▾</i>
</span>
<ul class="colleges-menu">
<li th:each="col : ${site.colleges}" th:classappend="${col.path == site.path} ? 'active'">
<a th:href="${url.siteHome(col.path, col.publicBaseUrl)}"
th:title="${col.name}" th:text="${col.name}">学院名称</a>
</li>
</ul>
</div>
</div>
<!-- 中:居中品牌(logo + 站名) -->
<div class="site-brand">
<img th:if="${site.config['logo'] != null}" class="site-logo"
th:src="${url.upload(site.config['logo'])}" th:alt="${site.name}">
<a class="site-name" th:href="${url.home()}" th:text="${site.name}">站点名称</a>
</div>
<!-- 右:站内搜索 -->
<div class="header-aside header-aside-right">
<form class="site-search" th:action="${url.search('', null)}" method="get">
<input type="text" name="q" placeholder="站内搜索" aria-label="站内搜索">
<button type="submit">搜索</button>
</form>
</div>
</div>
<nav class="site-nav">
<ul>
<li th:classappend="${currentCategoryId == null} ? 'active'">
<a th:href="${url.home()}">首页</a>
</li>
<li th:each="cat : ${navCategories}"
th:classappend="${((currentCategoryId == cat.id or navTopId == cat.id) ? 'active' : '') + (!cat.children.isEmpty() ? ' has-sub' : '')}">
<!-- 外链栏目直接外跳;其余进栏目页(方案 §8.1) -->
<a th:if="${cat.type == 3}" th:href="${cat.linkUrl}" target="_blank" rel="noopener"
th:text="${cat.name}">栏目</a>
<a th:unless="${cat.type == 3}" th:href="${url.category(cat.id)}" th:text="${cat.name}">栏目</a>
<!-- 二级下拉:悬停展开(样式见 assets/css/main.css .sub-nav) -->
<ul class="sub-nav" th:if="${!cat.children.isEmpty()}">
<li th:each="sub : ${cat.children}"
th:classappend="${sub.id == currentCategoryId} ? 'active'">
<a th:if="${sub.type == 3}" th:href="${sub.linkUrl}" target="_blank" rel="noopener"
th:text="${sub.name}">子栏目</a>
<a th:unless="${sub.type == 3}" th:href="${url.category(sub.id)}" th:text="${sub.name}">子栏目</a>
</li>
</ul>
</li>
</ul>
</nav>
</header>
</html>