fix: 修复SEO工具页面模板继承错误,改为独立完整HTML页面

- 将seo_tools.html从继承admin/master.html改为独立完整HTML
- 从master.html中移除SEO工具菜单项,避免url_for错误
- 修复本地UndefinedError: 'admin_view' is undefined错误
This commit is contained in:
Jowe
2026-01-03 23:26:25 +08:00
parent c74b115ac0
commit c68d846daa
2 changed files with 408 additions and 256 deletions

View File

@@ -79,12 +79,6 @@
<div class="nav-section"> <div class="nav-section">
<div class="nav-section-title">系统</div> <div class="nav-section-title">系统</div>
<ul class="nav-menu"> <ul class="nav-menu">
<li class="nav-item">
<a href="{{ url_for('seo_tools') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">search</span>
<span class="nav-text">SEO工具</span>
</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a href="{{ url_for('batch_import') }}" class="nav-link"> <a href="{{ url_for('batch_import') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">upload_file</span> <span class="material-symbols-outlined nav-icon">upload_file</span>

View File

@@ -1,17 +1,158 @@
{% extends 'admin/master.html' %} <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SEO工具管理 - ZJPB - 自己品吧</title>
{% block head_css %} <!-- Google Fonts -->
<!-- Font Awesome for icons --> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
{% endblock %} <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Noto+Sans:wght@400;500;700&display=swap" rel="stylesheet">
{% block body %} <!-- Google Material Symbols -->
<div class="container-fluid"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<div class="row">
<div class="col-md-12"> <!-- Font Awesome for icons -->
<h1 class="mb-4"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom Admin Theme -->
<link href="{{ url_for('static', filename='css/admin-sidebar.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/admin-actions.css') }}" rel="stylesheet">
</head>
<body class="admin-sidebar-layout">
<!-- 左侧菜单栏 -->
<aside class="admin-sidebar">
<!-- Logo -->
<div class="sidebar-logo">
<span class="material-symbols-outlined logo-icon">blur_on</span>
<span class="logo-text">ZJPB - 自己品吧</span>
</div>
<!-- 主菜单 -->
<nav class="sidebar-nav">
<div class="nav-section">
<div class="nav-section-title">主菜单</div>
<ul class="nav-menu">
<li class="nav-item">
<a href="{{ url_for('admin.index') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">dashboard</span>
<span class="nav-text">控制台</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('site.index_view') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">public</span>
<span class="nav-text">网站管理</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('tag.index_view') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">label</span>
<span class="nav-text">标签管理</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('news.index_view') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">newspaper</span>
<span class="nav-text">新闻管理</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('admin_users.index_view') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">admin_panel_settings</span>
<span class="nav-text">管理员</span>
</a>
</li>
</ul>
</div>
<!-- 系统菜单 -->
<div class="nav-section">
<div class="nav-section-title">系统</div>
<ul class="nav-menu">
<li class="nav-item active">
<a href="{{ url_for('seo_tools') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">search</span>
<span class="nav-text">SEO工具</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('batch_import') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">upload_file</span>
<span class="nav-text">批量导入</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('change_password') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">lock_reset</span>
<span class="nav-text">修改密码</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('index') }}" class="nav-link" target="_blank">
<span class="material-symbols-outlined nav-icon">open_in_new</span>
<span class="nav-text">查看网站</span>
</a>
</li>
<li class="nav-item">
<a href="{{ url_for('admin_logout') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">logout</span>
<span class="nav-text">退出登录</span>
</a>
</li>
</ul>
</div>
</nav>
<!-- 用户信息 -->
<div class="sidebar-user">
<div class="user-avatar">
<span class="material-symbols-outlined">account_circle</span>
</div>
<div class="user-info">
<div class="user-name">{{ current_user.username }}</div>
<div class="user-email">{{ current_user.email or 'admin@zjpb.com' }}</div>
</div>
</div>
</aside>
<!-- 右侧主内容区 -->
<div class="admin-main">
<!-- 顶部导航栏 -->
<header class="admin-header">
<div class="header-breadcrumb">
<a href="{{ url_for('admin.index') }}" class="breadcrumb-link">控制台</a>
<span class="breadcrumb-separator">/</span>
<span class="breadcrumb-current">SEO工具管理</span>
</div>
<div class="header-actions">
<div class="search-box">
<span class="material-symbols-outlined search-icon">search</span>
<input type="text" placeholder="全局搜索..." class="search-input">
</div>
<button class="header-btn">
<span class="material-symbols-outlined">notifications</span>
</button>
<button class="header-btn">
<span class="material-symbols-outlined">settings</span>
</button>
</div>
</header>
<!-- 页面内容 -->
<main class="admin-content">
<div class="page-header">
<div>
<h1 class="page-title">
<i class="fa fa-search"></i> SEO工具管理 <i class="fa fa-search"></i> SEO工具管理
</h1> </h1>
<p class="page-description">管理sitemap、通知搜索引擎更新</p>
</div>
</div>
<!-- Sitemap状态卡片 --> <!-- Sitemap状态卡片 -->
<div class="row mb-4"> <div class="row mb-4">
@@ -130,26 +271,42 @@
</div> </div>
</div> </div>
</main>
</div> </div>
</div>
</div>
<style> <!-- Bootstrap JS -->
.card { <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"></script>
<style>
.page-title {
font-size: 24px;
font-weight: 600;
margin-bottom: 8px;
}
.page-description {
color: #666;
margin-bottom: 24px;
}
.card {
box-shadow: 0 2px 4px rgba(0,0,0,0.1); box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin-bottom: 20px; margin-bottom: 20px;
} border-radius: 8px;
border: 1px solid #e0e0e0;
}
.btn-lg { .btn-lg {
padding: 12px 24px; padding: 12px 24px;
font-size: 16px; font-size: 16px;
} }
#resultArea { #resultArea {
animation: slideDown 0.3s ease-out; animation: slideDown 0.3s ease-out;
} }
@keyframes slideDown { @keyframes slideDown {
from { from {
opacity: 0; opacity: 0;
transform: translateY(-10px); transform: translateY(-10px);
@@ -158,64 +315,64 @@
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
} }
} }
.result-item { .result-item {
padding: 12px; padding: 12px;
border-left: 4px solid #ddd; border-left: 4px solid #ddd;
margin-bottom: 10px; margin-bottom: 10px;
background: #f8f9fa; background: #f8f9fa;
} }
.result-item.success { .result-item.success {
border-left-color: #28a745; border-left-color: #28a745;
background: #d4edda; background: #d4edda;
} }
.result-item.error { .result-item.error {
border-left-color: #dc3545; border-left-color: #dc3545;
background: #f8d7da; background: #f8d7da;
} }
.result-item.warning { .result-item.warning {
border-left-color: #ffc107; border-left-color: #ffc107;
background: #fff3cd; background: #fff3cd;
} }
</style> </style>
<script> <script>
// 复制到剪贴板 // 复制到剪贴板
function copyToClipboard(text) { function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => { navigator.clipboard.writeText(text).then(() => {
alert('已复制到剪贴板!'); alert('已复制到剪贴板!');
}); });
} }
// 禁用按钮 // 禁用按钮
function disableButtons() { function disableButtons() {
document.querySelectorAll('#generateSitemapBtn, #notifyEnginesBtn, #doAllBtn').forEach(btn => { document.querySelectorAll('#generateSitemapBtn, #notifyEnginesBtn, #doAllBtn').forEach(btn => {
btn.disabled = true; btn.disabled = true;
}); });
} }
// 启用按钮 // 启用按钮
function enableButtons() { function enableButtons() {
document.querySelectorAll('#generateSitemapBtn, #notifyEnginesBtn, #doAllBtn').forEach(btn => { document.querySelectorAll('#generateSitemapBtn, #notifyEnginesBtn, #doAllBtn').forEach(btn => {
btn.disabled = false; btn.disabled = false;
}); });
} }
// 显示结果 // 显示结果
function showResult(html) { function showResult(html) {
const resultArea = document.getElementById('resultArea'); const resultArea = document.getElementById('resultArea');
const resultContent = document.getElementById('resultContent'); const resultContent = document.getElementById('resultContent');
resultContent.innerHTML = html; resultContent.innerHTML = html;
resultArea.style.display = 'block'; resultArea.style.display = 'block';
resultArea.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); resultArea.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
} }
// 生成静态sitemap // 生成静态sitemap
document.getElementById('generateSitemapBtn').addEventListener('click', async function() { document.getElementById('generateSitemapBtn').addEventListener('click', async function() {
disableButtons(); disableButtons();
const originalText = this.innerHTML; const originalText = this.innerHTML;
this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> 生成中...'; this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> 生成中...';
@@ -263,10 +420,10 @@ document.getElementById('generateSitemapBtn').addEventListener('click', async fu
this.innerHTML = originalText; this.innerHTML = originalText;
enableButtons(); enableButtons();
} }
}); });
// 通知搜索引擎 // 通知搜索引擎
document.getElementById('notifyEnginesBtn').addEventListener('click', async function() { document.getElementById('notifyEnginesBtn').addEventListener('click', async function() {
disableButtons(); disableButtons();
const originalText = this.innerHTML; const originalText = this.innerHTML;
this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> 通知中...'; this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> 通知中...';
@@ -320,10 +477,10 @@ document.getElementById('notifyEnginesBtn').addEventListener('click', async func
this.innerHTML = originalText; this.innerHTML = originalText;
enableButtons(); enableButtons();
} }
}); });
// 一键生成并通知 // 一键生成并通知
document.getElementById('doAllBtn').addEventListener('click', async function() { document.getElementById('doAllBtn').addEventListener('click', async function() {
disableButtons(); disableButtons();
const originalText = this.innerHTML; const originalText = this.innerHTML;
this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> 处理中...'; this.innerHTML = '<i class="fa fa-spinner fa-spin"></i> 处理中...';
@@ -411,6 +568,7 @@ document.getElementById('doAllBtn').addEventListener('click', async function() {
this.innerHTML = originalText; this.innerHTML = originalText;
enableButtons(); enableButtons();
} }
}); });
</script> </script>
{% endblock %} </body>
</html>