Files
yu-zhi-ran/platform/frontend/navigation-component.js
T
lt 526278589b feat: 完善前端页面 - 新增数据分析、素材库、创作任务、平台配置页面
- 新增 metrics.html: 数据分析页面 (Dashboard, 趋势图, 平台对比, 选题推荐)
- 新增 assets.html: 素材库页面 (上传/管理/预览/标签)
- 新增 tasks.html: 创作任务页面 (任务列表/进度/详情)
- 新增 platforms.html: 平台配置页面 (知乎/微信/小红书格式规则)
- 更新导航组件: 添加新页面入口, 适配 H5 底部导航
- 修复 calendar.html: 使用本地 Vue/ElementPlus 资源
- 修复 assets.py: db.func.count -> sqlalchemy.func.count
- 新增 test_api_unit.py: 后端 API 单元测试
- 新增 test_frontend.sh: 前端页面完整性测试

PC/H5 双端适配, 所有页面统一使用 navbar + navigation 组件
2026-05-08 23:35:26 +08:00

122 lines
7.0 KiB
JavaScript

// 纯DOM导航 - 通过 installNavigation 直接插入
(function() {
console.log('[Nav] 脚本加载');
function injectStyles() {
if (document.getElementById('navigation-styles')) return;
const styles = `
.navigation-wrapper .sidebar { position: fixed; top: 60px; left: 0; bottom: 0; width: 180px; background: #fff; padding: 12px; box-shadow: 2px 0 8px rgba(0,0,0,0.1); overflow-y: auto; z-index: 99999; border-right: 1px solid #ebeef5; }
.navigation-wrapper .sidebar-header { padding: 12px 8px 16px; border-bottom: 1px solid #ebeef5; margin-bottom: 12px; }
.navigation-wrapper .sidebar-header h3 { margin: 0; font-size: 16px; font-weight: 600; color: #303133; }
.navigation-wrapper .sidebar-btn { width: 100%; text-align: left; padding: 10px 12px; border: none; background: transparent; border-radius: 8px; margin-bottom: 6px; cursor: pointer; transition: all 0.3s; color: #606266; font-size: 14px; display: flex; align-items: center; gap: 6px; }
.navigation-wrapper .sidebar-btn:hover { background: #f5f7fa; color: #409eff; }
.navigation-wrapper .sidebar-btn.active { background: #ecf5ff; color: #409eff; font-weight: 600 !important; }
.navigation-wrapper .mobile-nav { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: #1890ff; box-shadow: 0 -2px 8px rgba(0,0,0,0.2); padding: 8px 0; z-index: 99999; justify-content: space-around; }
.navigation-wrapper .mobile-nav-btn { flex: 1; border: none; background: transparent; padding: 10px 4px; text-align: center; font-size: 12px; color: white !important; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.navigation-wrapper .mobile-nav-btn:hover { background: rgba(255,255,255,0.2); }
.navigation-wrapper .mobile-nav-btn.active { background: rgba(255,255,255,0.3); font-weight: 600 !important; }
@media (max-width: 768px) { .navigation-wrapper .sidebar { display: none !important; } .navigation-wrapper .mobile-nav { display: flex !important; } }
body > #app > .main-content { margin-left: 180px !important; padding-top: 60px !important; }
@media (max-width: 768px) { body > #app > .main-content { margin-left: 0 !important; padding-bottom: 60px !important; } }
`;
document.head.appendChild(Object.assign(document.createElement('style'), { id: 'navigation-styles', textContent: styles }));
console.log('[Nav] 样式已注入');
}
function createNavigation(currentPage, isAdmin, onNavigate) {
const wrapper = document.createElement('div');
wrapper.className = 'navigation-wrapper';
// 侧边栏
const sidebar = document.createElement('aside');
sidebar.className = 'sidebar';
sidebar.innerHTML = `
<div class="sidebar-header"><h3>宇之然平台</h3></div>
<nav class="sidebar-nav">
<button class="sidebar-btn ${currentPage==='dashboard'?'active':''}" data-page="/">📊 系统概览</button>
<button class="sidebar-btn ${currentPage==='topics'?'active':''}" data-page="topics.html">📋 选题管理</button>
<button class="sidebar-btn ${currentPage==='metrics'?'active':''}" data-page="metrics.html">📊 数据分析</button>
<button class="sidebar-btn ${currentPage==='calendar'?'active':''}" data-page="calendar.html">📅 内容日历</button>
<button class="sidebar-btn ${currentPage==='assets'?'active':''}" data-page="assets.html">🖼️ 素材库</button>
<button class="sidebar-btn ${currentPage==='tasks'?'active':''}" data-page="tasks.html">🚀 创作任务</button>
<button class="sidebar-btn ${currentPage==='platforms'?'active':''}" data-page="platforms.html">🌐 平台配置</button>
<button class="sidebar-btn ${currentPage==='logs'?'active':''}" data-page="logs.html">📄 系统日志</button>
${isAdmin ? `<button class="sidebar-btn ${currentPage==='users'?'active':''}" data-page="users.html">👥 用户管理</button>` : ''}
${isAdmin ? `<button class="sidebar-btn ${currentPage==='admin'?'active':''}" data-page="admin.html">⚙️ 系统管理</button>` : ''}
</nav>
`;
// 移动端底部导航
const mobileNav = document.createElement('nav');
mobileNav.className = 'mobile-nav';
mobileNav.innerHTML = `
<button class="mobile-nav-btn ${currentPage==='dashboard'?'active':''}" data-page="/">📊</button>
<button class="mobile-nav-btn ${currentPage==='topics'?'active':''}" data-page="topics.html">📋</button>
<button class="mobile-nav-btn ${currentPage==='metrics'?'active':''}" data-page="metrics.html">📊</button>
<button class="mobile-nav-btn ${currentPage==='assets'?'active':''}" data-page="assets.html">🖼️</button>
<button class="mobile-nav-btn ${currentPage==='tasks'?'active':''}" data-page="tasks.html">🚀</button>
`;
wrapper.appendChild(sidebar);
wrapper.appendChild(mobileNav);
// 绑定点击事件
wrapper.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
const page = btn.getAttribute('data-page');
console.log('[Nav] 导航到:', page);
if (onNavigate) onNavigate(page);
});
});
return wrapper;
}
// 新的 installNavigation 接口:接收 app 对象(为了兼容),但实际不注册组件
window.installNavigation = function(app, options = {}) {
console.log('[Nav] installNavigation called (DOM mode)');
injectStyles();
// 延迟执行,确保DOM就绪
const init = () => {
const container = document.getElementById('app');
if (!container) {
console.warn('[Nav] #app 未找到,等待');
setTimeout(init, 100);
return;
}
// 尝试从 Vue 实例获取 isAdmin 和 currentPage
let isAdmin = false;
let currentPage = 'dashboard';
let redirectToPage = null;
// 尝试从 Vue 实例提取数据
if (app && app._instance && app._instance.proxy) {
const proxy = app._instance.proxy;
if (proxy.isAdmin !== undefined) isAdmin = proxy.isAdmin;
if (proxy.currentPage !== undefined) currentPage = proxy.currentPage;
if (proxy.redirectToPage) redirectToPage = proxy.redirectToPage;
} else if (window.Vue && Vue.app && Vue.app._instance && Vue.app._instance.proxy) {
const proxy = Vue.app._instance.proxy;
if (proxy.isAdmin !== undefined) isAdmin = proxy.isAdmin;
if (proxy.currentPage !== undefined) currentPage = proxy.currentPage;
if (proxy.redirectToPage) redirectToPage = proxy.redirectToPage;
}
// 移除旧的导航容器(如果有)
const oldNav = container.querySelector('.navigation-wrapper');
if (oldNav) oldNav.remove();
const nav = createNavigation(currentPage, isAdmin, redirectToPage || ((page) => { window.location.href = page; }));
container.insertBefore(nav, container.firstChild);
console.log('[Nav] 导航已插入');
};
init();
return app;
};
console.log('[Nav] 脚本已加载(纯DOM版)');
})();