R39: 网页改名 MCN创意雷达 + 首页榜单行垂直居中对齐 + 下载按钮换 globe 图标浅色

- 改名 6 文件(网页显示层,不动技能注册名「短视频工作台」)

- 浏览器标题 + 面包屑 + 4 文件头注释 + server.js 启动日志

- 垂直居中:.rank-preview .recent-head .rank-tabs 局部覆盖 align-self:center margin-bottom:0(CDP 实测修复前偏上 5px)

- globe 图标三处替换 download→globe:首页 homeRankUpdate / 热点 rankUpdate / 账号 accUpdate

- #rankUpdate + .home-rank-update 常态 color:var(--dim) 浅灰,hover 继承 .btn:hover 变蓝

- 版本 style.css z→aa / app.js w→x / data-pages.js aa→ab

- CDP 冒烟 15/15 PASS(拆 3 段独立连接 a/b/c,段 B 修复 :last-of-type selector 命中按钮自身坑)

- 权威冒烟脚本 cdp-r39-brand.mjs 同步修 selector
This commit is contained in:
maogeigei committed 2026-09-03 18:21:50 +08:00
1 parent fa99a99b67
commit 291715bb27
7 files changed
+48 -17

No files matched your search

@@ -1,4 +1,4 @@
// MCN工作台 - 数据访问层(只读复用业务数据目录)
// MCN创意雷达 - 数据访问层(只读复用业务数据目录)
// 数据源:工作台目录 mcn-plugin.db(dsh 库副本,node:sqlite 只读)+ 三方数据目录 抖音榜单/*.json
// 与 dsh 原库(~/.dsh/mcn-plugin.db)隔离:两边各访问各的,互不影响
// 页面逻辑参照 dsh-plugin-mcn 重新开发,仅复用数据库 schema 与榜单文件格式
@@ -1,4 +1,4 @@
/* MCN工作台 - 前端核心(原生 JS,零依赖)
/* MCN创意雷达 - 前端核心(原生 JS,零依赖)
路由框架 + 首页 + 产出浏览 + markdown 渲染 + 复制/提示工具
数据功能页(周榜/账号/视频/脚本/复盘)见 data-pages.js */
'use strict';
@@ -174,6 +174,7 @@ const ICON_PATHS = {
'zap': '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
'user-plus': '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" x2="19" y1="8" y2="14"/><line x1="22" x2="16" y1="11" y2="11"/>',
'download': '<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',
'globe': '<circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/>',
'copy': '<rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/>',
};
@@ -327,7 +328,7 @@ function renderHome() {
<button class="rank-tab" data-rank-tab="hot" title="近7日数据" role="tab">视频热榜</button>
<button class="rank-tab" data-rank-tab="likes" title="近7日数据" role="tab">点赞榜</button>
</div>
<button class="btn btn-icon home-rank-update" id="homeRankUpdate" title="更新榜单数据:后台任务重新抓取三榜(账号周榜 5 赛道 / 视频热榜 / 点赞榜)最新一期并落盘;30 分钟内已更新会拦截防重复">${svgIcon('download', 16, 'currentColor')}</button>
<button class="btn btn-icon home-rank-update" id="homeRankUpdate" title="更新榜单数据:后台任务重新抓取三榜(账号周榜 5 赛道 / 视频热榜 / 点赞榜)最新一期并落盘;30 分钟内已更新会拦截防重复">${svgIcon('globe', 16, 'currentColor')}</button>
<div class="rank-tools" id="rankTools">
<select id="rankCat" class="input-select rank-filter" title="赛道筛选"></select>
<button class="btn btn-sm" id="rankPrevDate" title="上一期">◀</button>
@@ -728,8 +729,8 @@ function parseHash() {
function updateCrumbs(name, title) {
const c = $('#crumbs');
if (!name) { c.innerHTML = '<span class="crumb-home">MCN 工作台</span>'; return; }
c.innerHTML = `<a class="crumb-home" href="#/">MCN 工作台</a><span class="crumb-sep">/</span><span class="crumb-current">${esc(title || CRUMB_TITLES[name] || '功能页')}</span>`;
if (!name) { c.innerHTML = '<span class="crumb-home">MCN创意雷达</span>'; return; }
c.innerHTML = `<a class="crumb-home" href="#/">MCN创意雷达</a><span class="crumb-sep">/</span><span class="crumb-current">${esc(title || CRUMB_TITLES[name] || '功能页')}</span>`;
}
async function router() {
@@ -1,4 +1,4 @@
/* MCN工作台 - 数据功能页(周榜/账号/视频/脚本/复盘,只读 + prompt 触发)
/* MCN创意雷达 - 数据功能页(周榜/账号/视频/脚本/复盘,只读 + prompt 触发)
依赖 app.js 暴露的工具:esc/api/renderMarkdown/copyText/showToast/fmtSize */
'use strict';
@@ -525,7 +525,7 @@ async function renderRanking(view) {
// 09-03 page-toolbar 只放 返回+标题;rank-toolbar 恒渲染含 tab + 下载按钮(紧贴 tab 右侧)保证空态/错误态也能看到更新入口(首次抓取);筛选+翻页仅 withFilters 时出现在同行最右
const toolbar = (s, withFilters) => {
const tabsHtml = `${RANK_TABS.map(([k, label, tip]) => `<button class="rank-tab${k === tab ? ' active' : ''}" data-rank-tab="${k}"${tip ? ` title="${tip}"` : ''} role="tab">${label}</button>`).join('')}
<button class="btn btn-icon" id="rankUpdate" title="更新榜单数据:后台任务重新抓取三榜(账号周榜 5 赛道 / 视频热榜 / 点赞榜)最新一期并落盘;30 分钟内已更新会拦截防重复">${svgIcon('download', 16, 'currentColor')}</button>`;
<button class="btn btn-icon" id="rankUpdate" title="更新榜单数据:后台任务重新抓取三榜(账号周榜 5 赛道 / 视频热榜 / 点赞榜)最新一期并落盘;30 分钟内已更新会拦截防重复">${svgIcon('globe', 16, 'currentColor')}</button>`;
const filtersHtml = withFilters ? `<div class="toolbar-right">
<select id="rankCat" class="input-select" title="赛道筛选">
<option value="">全部赛道</option>
@@ -792,7 +792,7 @@ async function renderAccounts(view) {
<select id="accTrack" class="input-select"><option value="">全部赛道</option>${tracks.map((t) => `<option value="${esc(t)}" ${t === state.track ? 'selected' : ''}>${esc(t)}</option>`).join('')}</select>
<input id="accSearch" class="input" placeholder="搜索账号名 / 内容 / 赛道" value="${esc(state.search)}">
<button class="btn" id="accImport" title="添加账号数据(抖音账号信息 / 账号地址)">${svgIcon('user-plus', 15, 'currentColor')} 添加</button>
<button class="btn" id="accUpdate" title="重新抓取所有已关注账号(⭐)的最新账号数据与视频列表(后台任务逐个执行)">${svgIcon('download', 15, 'currentColor')} 更新</button>
<button class="btn" id="accUpdate" title="重新抓取所有已关注账号(⭐)的最新账号数据与视频列表(后台任务逐个执行)">${svgIcon('globe', 15, 'currentColor')} 更新</button>
</div>
</div>
<div class="table-wrap">
@@ -3,8 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MCN工作台</title>
<link rel="stylesheet" href="style.css?v=20260903z">
<title>MCN创意雷达</title>
<link rel="stylesheet" href="style.css?v=20260903aa">
<script src="vendor/echarts.min.js"></script>
</head>
<body>
@@ -41,7 +41,7 @@
</div>
</div>
<script src="app.js?v=20260903w"></script>
<script src="data-pages.js?v=20260903aa"></script>
<script src="app.js?v=20260903x"></script>
<script src="data-pages.js?v=20260903ab"></script>
</body>
</html>
@@ -1,4 +1,4 @@
/* MCN工作台样式 - 亮色主题 */
/* MCN创意雷达样式 - 亮色主题 */
:root {
--bg: #f5f6f8;
--panel: #ffffff;
@@ -427,9 +427,9 @@ main#view { height: calc(100vh - 55px); overflow: auto; } /* 55px=topbar 实际
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-busy { background: var(--primary-soft) !important; color: var(--primary) !important; border-color: var(--primary) !important; opacity: .8; }
.btn-icon { padding: 5px 9px; display: inline-flex; align-items: center; justify-content: center; } /* 纯图标按钮(09-03:榜单更新等) */
#rankUpdate { padding-left: 11.5px; padding-right: 11.5px; background: transparent; border-color: transparent; } /* 09-03 更新按钮加宽 5px(icon 16 + 左右 padding 9→11.5),更易点中;去白底/边框只显 icon */
#rankUpdate { padding-left: 11.5px; padding-right: 11.5px; background: transparent; border-color: transparent; color: var(--dim); } /* 09-03 更新按钮加宽 5px(icon 16 + 左右 padding 9→11.5),更易点中;去白底/边框只显 icon,常态浅灰 hover 蓝(.btn:hover) */
#rankUpdate:hover { background: transparent; border-color: transparent; } /* 覆盖 .btn:hover 默认主色边框 */
.home-rank-update { background: transparent; border-color: transparent; padding-left: 11.5px; padding-right: 11.5px; } /* 09-03 首页榜单下载按钮:去白底只显 icon,padding 与榜单 #rankUpdate 对齐 */
.home-rank-update { background: transparent; border-color: transparent; padding-left: 11.5px; padding-right: 11.5px; color: var(--dim); } /* 09-03 首页榜单下载按钮:去白底只显 icon,padding 与榜单 #rankUpdate 对齐,常态浅灰 */
.home-rank-update:hover { background: transparent; border-color: transparent; }
.btn-busy .ic { animation: req-spin 1s linear infinite; } /* busy 态图标旋转(复用弹窗 spinner 动画) */
.btn-sm { padding: 3px 10px; font-size: 14px; border-radius: 6px; }
@@ -599,6 +599,8 @@ td.td-title { max-width: 240px; }
/* ================= 首页 账号周榜 预览 ================= */
.rank-preview { margin: 4px 0 20px; }
.rank-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); padding-bottom: 0; margin-bottom: 10px; align-self: stretch; }
/* 首页预览:tab 组与 ⬇/筛选同行需垂直居中对齐——全局 .rank-tabs 的 stretch+margin-bottom 会使 tab 组相对兄弟控件偏上 ~5px */
.rank-preview .recent-head .rank-tabs { align-self: center; margin-bottom: 0; }
.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); }
@@ -1,4 +1,4 @@
// MCN工作台 - 本地 Web 服务(零依赖 Node 实现)
// MCN创意雷达 - 本地 Web 服务(零依赖 Node 实现)
// 启动: node server.js [端口] → http://localhost:8900(默认;可传参指定端口,如 node server.js 9000)
// 功能: 技能导航 + 产出内容浏览(默认读桌面 MCNSkill项目)+ dsh 数据功能页(账号/视频/脚本/复盘/周榜,只读)
'use strict';
@@ -971,7 +971,7 @@ function listen(port) {
}
});
server.listen(port, '127.0.0.1', () => {
log('MCN工作台已启动: http://localhost:' + port);
log('MCN创意雷达已启动: http://localhost:' + port);
log('默认项目地址: ' + DEFAULT_ROOT + (fs.existsSync(DEFAULT_ROOT) ? '' : '(不存在)'));
log('按 Ctrl+C 停止服务');
});