diff --git a/applications/view/public/nav.py b/applications/view/public/nav.py index 3e09f1c..e2ed7b7 100644 --- a/applications/view/public/nav.py +++ b/applications/view/public/nav.py @@ -85,9 +85,38 @@ def _render_index(): total=total, site_name='旺珂 · 导航', cat_meta=_category_meta(), + top_navs=_top_navs(12), ) +def _top_navs(limit: int = 12) -> "list[dict]": + """跨分类聚合:返回点击数 TOP N 的有效 nav 列表(按点击数降序)。 + + - 复用 get_nav_visit_counts() 的 60s 进程内缓存 + - 0 点击时返回空列表(调用方负责隐藏整个分类块) + - 同一个 nav 不可能重复出现(按 nav.id 维度) + """ + counts = get_nav_visit_counts() + if not counts: + return [] + # 取点击数最高的 N 个 nav_id(点击数相同的按 id asc 稳定排序) + top_ids = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))[:limit] + nav_ids = [nid for nid, _ in top_ids] + rows = ( + Nav.query + .filter(Nav.id.in_(nav_ids), Nav.enable == 1) + .all() + ) + by_id = {n.id: n.to_dict() for n in rows} + out = [] + for nid in nav_ids: + if nid in by_id: + d = by_id[nid] + d['visit_count'] = counts.get(nid, 0) + out.append(d) + return out + + def _grouped_navs() -> "OrderedDict[str, list]": """按 category 分组,组内按 sort asc 排序;分组顺序优先按 NavCategory.sort 排列""" # 先取启用的分类,按 sort 排好序 diff --git a/templates/public/base.html b/templates/public/base.html index e205724..9632571 100644 --- a/templates/public/base.html +++ b/templates/public/base.html @@ -396,6 +396,32 @@ border-color: var(--brand); } .card:active { transform: translateY(0); } + + /* ===== 热门网址卡片:与普通卡片区分 ===== */ + .section-hot { margin-top: 8px; } + .section-hot .section-header h2 i { color: #ff6b35; margin-right: 2px; } + .card-top { + border-color: rgba(22, 186, 170, 0.35); + background: linear-gradient(135deg, var(--card-bg) 0%, rgba(22, 186, 170, 0.05) 100%); + position: relative; + } + .card-top::before { + content: ''; + position: absolute; top: 0; left: 0; + width: 3px; height: 100%; + background: var(--brand); + border-radius: 10px 0 0 10px; + } + .card-top:hover { + border-color: var(--brand); + box-shadow: 0 6px 20px rgba(22, 186, 170, 0.18); + } + + .cat-nav-inner a.cat-nav-hot { + color: #ff6b35; + font-weight: 600; + } + .card .icon-wrap { width: 42px; height: 42px; background: rgba(22, 186, 170, 0.1); @@ -770,6 +796,22 @@ + {# 热门网址入口(仅首页,且首页必须传 top_navs 才渲染)#} + {% if top_navs is defined and top_navs %} +