热点数据 UI:首页入口改名+页内 tab 与赛道/时间筛选同行
- 首页入口卡「账号周榜」→「热点数据」(desc=账号周榜 · 视频热榜 · 点赞榜);CRUMB_TITLES ranking 同步 - #/ranking 页 rank-tabs 并入 page-toolbar 同一行(返回|标题|三榜tab|赛道下拉+期数切换),空/错误态仍可切 tab - CSS .page-toolbar .rank-tabs 行内化;index.html 静态资源加 ?v=20260903 版本参数防缓存
This commit is contained in:
1 parent
052550e0c0
commit
acb4c3ea3c
5 files changed
+23
-13
No files matched your search
@@ -161,3 +161,10 @@
|
||||
- **口径**:与账号周榜 douyin-top-account 保留 5 赛道一致;**账号榜 type=生活vlog / 作品榜条目 category=生活记录**(两套枚举),白名单取并集 RANK_KEEP=['生活记录','生活vlog','小剧场','亲子','美食','旅行'](dsh-data.js)
|
||||
- **实现**:collectCategories 白名单∩实际出现(按 RANK_KEEP 顺序);getRanking hot/likes 条目无条件白名单过滤(「全部」也只留白名单)+ 请求赛道过滤;week 不受影响
|
||||
- **验证**(服务 5500):week 下拉 5 赛道/250 条不变;hot 下拉[生活记录,小剧场,亲子,美食]全部 29 条;likes 下拉[生活记录,小剧场,亲子,旅行]全部 28 条;当期 0 条赛道(hot 旅行/likes 美食)不进下拉
|
||||
|
||||
## 热点数据 UI:入口改名 + tab/筛选同行(09-03 15:10)
|
||||
- 入口卡(首页 data-card)title「账号周榜」→「热点数据」,desc→「账号周榜 · 视频热榜 · 点赞榜」;CRUMB_TITLES ranking 同步改「热点数据」(原与 page-title 不一致)
|
||||
- data-pages.js renderRanking:tabs 并入 toolbar 一行(返回|标题|三榜tab|右侧赛道下拉+◀日期▶),删独立 tabs() 输出 3 处;错误/空态也带 tab 可切换
|
||||
- CSS:.page-toolbar .rank-tabs 行内化(border-bottom none、margin 0、center)
|
||||
- index.html 静态引用加 ?v=20260903 版本参数(防缓存旧 js/css;今后改动记得 bump)
|
||||
- 服务无需重启(静态),curl 资源全 200
|
||||
@@ -299,7 +299,7 @@ const FUNC_GROUPS = [
|
||||
/* ================= 首页 ================= */
|
||||
function renderHome() {
|
||||
const cards = [
|
||||
{ icon: 'trending-up', title: '账号周榜', desc: '三方数据 · 赛道/日期筛选', hash: '#/ranking' },
|
||||
{ icon: 'trending-up', title: '热点数据', desc: '账号周榜 · 视频热榜 · 点赞榜', hash: '#/ranking' },
|
||||
{ icon: 'users', title: '账号列表', desc: '关注的账号 + 视频列表', hash: '#/accounts' },
|
||||
{ icon: 'pen', title: 'AI写脚本', desc: 'AI脚本+分镜提示词', hash: '#/rewrites' },
|
||||
{ icon: 'flask', title: 'AI脚本诊断', desc: '检查清单+复盘报告', hash: '#/reviews' },
|
||||
@@ -702,7 +702,7 @@ function openSettings() { renderRootList(); $('#settingsModal').hidden = false;
|
||||
function closeSettings() { $('#settingsModal').hidden = true; }
|
||||
|
||||
/* ================= 路由 ================= */
|
||||
const CRUMB_TITLES = { 'ranking': '账号周榜', 'accounts': '账号列表', 'rewrites': 'AI写脚本', 'reviews': 'AI脚本诊断' };
|
||||
const CRUMB_TITLES = { 'ranking': '热点数据', 'accounts': '账号列表', 'rewrites': 'AI写脚本', 'reviews': 'AI脚本诊断' };
|
||||
|
||||
function parseHash() {
|
||||
const h = (location.hash || '#/').replace(/^#/, '');
|
||||
|
||||
@@ -515,14 +515,14 @@ async function renderRanking(view) {
|
||||
const st = { week: mkState(), hot: mkState(), likes: mkState() };
|
||||
let tab = 'week';
|
||||
const tabLabel = () => { const t = RANK_TABS.find(([k]) => k === tab); return t ? t[1] : ''; };
|
||||
const tabs = () => `
|
||||
<div class="rank-tabs" role="tablist">
|
||||
${RANK_TABS.map(([k, label]) => `<button class="rank-tab${k === tab ? ' active' : ''}" data-rank-tab="${k}" role="tab">${label}</button>`).join('')}
|
||||
</div>`;
|
||||
// tab 切换 + 赛道选择 + 时间切换 同一行(page-toolbar:返回 | 标题 | tabs | 筛选右;空/错误态不渲染筛选)
|
||||
const toolbar = (s, withFilters) => `
|
||||
<div class="page-toolbar">
|
||||
${toolbarBack()}
|
||||
<span class="page-title">热点数据</span>
|
||||
<div class="rank-tabs" role="tablist">
|
||||
${RANK_TABS.map(([k, label]) => `<button class="rank-tab${k === tab ? ' active' : ''}" data-rank-tab="${k}" role="tab">${label}</button>`).join('')}
|
||||
</div>
|
||||
${withFilters ? `<div class="toolbar-right">
|
||||
<select id="rankCat" class="input-select" title="赛道筛选">
|
||||
<option value="">全部赛道</option>
|
||||
@@ -601,7 +601,7 @@ async function renderRanking(view) {
|
||||
async function loadMeta() {
|
||||
if (metas[tab]) return metas[tab];
|
||||
const m = await api('/api/dsh/ranking?board=' + tab + '&pageSize=20').catch((e) => ({ ok: false, error: e.message }));
|
||||
if (!m.ok) { view.innerHTML = `<div class="page"><div class="page-toolbar">${toolbarBack()}<span class="page-title">热点数据</span></div><div class="empty">${esc(m.error || '加载失败')}</div></div>`; bindBack(view); return null; }
|
||||
if (!m.ok) { view.innerHTML = `<div class="page">${toolbar(st[tab], false)}<div class="empty">${esc(m.error || '加载失败')}</div></div>`; bindShell(); return null; }
|
||||
metas[tab] = m;
|
||||
const s = st[tab];
|
||||
s.dates = m.dates || []; s.categories = m.categories || [];
|
||||
@@ -618,18 +618,18 @@ async function renderRanking(view) {
|
||||
const m = await loadMeta();
|
||||
if (!m) return;
|
||||
if (!s.dates.length) {
|
||||
view.innerHTML = `<div class="page">${toolbar(s, false)}${tabs()}<div class="empty">「${esc(tabLabel())}」暂无本地数据文件,先运行 mcn-data-insight 抓取技能落盘</div></div>`;
|
||||
view.innerHTML = `<div class="page">${toolbar(s, false)}<div class="empty">「${esc(tabLabel())}」暂无本地数据文件,先运行 mcn-data-insight 抓取技能落盘</div></div>`;
|
||||
bindShell(); return;
|
||||
}
|
||||
const d = await api(apiUrl).catch((e) => ({ ok: false, error: e.message }));
|
||||
if (!d.ok) { view.innerHTML = `<div class="page">${toolbar(s, true)}${tabs()}<div class="empty">${esc(d.error || '加载失败')}</div></div>`; bindShell(); return; }
|
||||
if (!d.ok) { view.innerHTML = `<div class="page">${toolbar(s, true)}<div class="empty">${esc(d.error || '加载失败')}</div></div>`; bindShell(); return; }
|
||||
const di = s.dates.indexOf(s.date);
|
||||
const curKey = s.sortBy || col.defKey;
|
||||
const srt = (key, label) => `<th class="sortable${SORT_NUM.has(key) ? ' th-wide' : ''}" data-sort="${key}">${label}${curKey === key ? (s.order === 'asc' ? ' ↑' : ' ↓') : ''}</th>`;
|
||||
const rows = (d.items || []).map((r) => col.row(r)).join('');
|
||||
view.innerHTML = `
|
||||
<div class="page">
|
||||
${toolbar(s, true)}${tabs()}
|
||||
${toolbar(s, true)}
|
||||
<div class="table-wrap">
|
||||
<table class="table table-rank${tab === 'week' ? '' : ' rank-video'}">
|
||||
<thead><tr>${col.head(s, srt)}</tr></thead>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MCN工作台</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link rel="stylesheet" href="style.css?v=20260903">
|
||||
<script src="vendor/echarts.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -41,7 +41,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="app.js"></script>
|
||||
<script src="data-pages.js"></script>
|
||||
<script src="app.js?v=20260903"></script>
|
||||
<script src="data-pages.js?v=20260903"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -585,6 +585,9 @@ td.td-title { max-width: 240px; }
|
||||
.rank-tab { border: none; background: transparent; color: var(--dim); padding: 6px 12px 4px; border-radius: 8px 8px 0 0; cursor: pointer; font-size: 14px; border-bottom: 2px solid transparent; }
|
||||
.rank-tab:hover { color: var(--primary); background: var(--primary-soft); }
|
||||
.rank-tab.active { color: var(--primary); font-weight: 600; background: var(--primary-soft); border-bottom: 2px solid var(--primary); }
|
||||
/* 热点数据页:tab 并入 page-toolbar 同一行(与赛道/时间筛选同行),去整行分隔条 */
|
||||
.page-toolbar .rank-tabs { border-bottom: none; margin-bottom: 0; align-self: center; }
|
||||
.page-toolbar .rank-tab { padding: 4px 10px 3px; font-size: 13px; }
|
||||
.rank-placeholder { border: 1px dashed var(--border); border-radius: 10px; padding: 36px 12px; text-align: center; color: var(--dim); background: var(--panel); font-size: 14px; }
|
||||
.rank-tools { display: flex; align-items: center; gap: 6px; margin-left: auto; }
|
||||
.rank-filter { padding: 3px 6px; font-size: 14px; max-width: 110px; }
|
||||
|
||||
Reference in new issue
Block a user