Files
zjpb.net/templates/admin/master.html
Jowe c74b115ac0 feat: 添加SEO工具管理页面 - v2.4.1
新增功能:
1. 后台SEO工具管理页面 (/admin/seo-tools)
   - 显示sitemap状态(是否存在、最后更新时间、文件大小)
   - 显示动态sitemap URL并支持一键复制

2. 生成静态sitemap.xml文件 (/api/generate-static-sitemap)
   - 将动态sitemap生成为static/sitemap.xml静态文件
   - 支持手动触发更新
   - 返回URL数量统计信息

3. 通知搜索引擎功能 (/api/notify-search-engines)
   - 支持向Google、Baidu、Bing提交sitemap更新通知
   - 使用各搜索引擎的ping接口
   - 返回每个搜索引擎的提交状态

4. 一键操作
   - 提供"一键生成并通知"功能
   - 自动执行生成sitemap + 通知搜索引擎两个步骤
   - 适合日常SEO维护使用

技术实现:
- 使用Flask路由和@login_required装饰器保护后台接口
- AJAX + fetch API实现前端交互
- Bootstrap 4卡片式UI设计
- 实时显示操作结果,颜色区分成功/失败状态

用户价值:
- 无需手动登录各搜索引擎后台提交sitemap
- 支持批量更新和通知,提升SEO工作效率
- 可视化状态展示,便于监控sitemap更新情况

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-03 17:29:14 +08:00

189 lines
9.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% import 'admin/layout.html' as layout with context -%}
{% import 'admin/static.html' as admin_static with context %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% if admin_view.category %}{{ admin_view.category }} - {% endif %}{{ admin_view.name }} - {{ admin_view.admin.name }}{% endblock %}</title>
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<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">
<!-- Google Material Symbols -->
<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" />
<!-- 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">
<!-- 暂时禁用中文化CSS等待精确调整 -->
<!-- <link href="{{ url_for('static', filename='css/admin-i18n.css') }}" rel="stylesheet"> -->
{% block head_css %}{% endblock %}
</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">
{% set active_category = admin_view.category if admin_view.category else '' %}
{% set active_name = admin_view.name if admin_view.name else '' %}
{% for item in admin_view.admin._menu %}
{% if item.is_category() %}
{# 分类菜单 #}
{% for child in item.get_children() %}
{% set is_active = (child.name == active_name) %}
<li class="nav-item {% if is_active %}active{% endif %}">
<a href="{{ child.get_url() }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">
{% if '网站' in child.name %}public
{% elif '标签' in child.name %}label
{% elif '新闻' in child.name %}newspaper
{% elif '管理员' in child.name %}admin_panel_settings
{% else %}circle{% endif %}
</span>
<span class="nav-text">{{ child.name }}</span>
</a>
</li>
{% endfor %}
{% else %}
{# 单独菜单项 #}
{% set is_active = (item.name == active_name) %}
<li class="nav-item {% if is_active %}active{% endif %}">
<a href="{{ item.get_url() }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">dashboard</span>
<span class="nav-text">{{ item.name }}</span>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
<!-- 系统菜单 -->
<div class="nav-section">
<div class="nav-section-title">系统</div>
<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">
<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">{{ admin_view.name }}</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">
{% block page_body %}
<div class="page-header">
<div>
<h1 class="page-title">{% block brand %}{{ admin_view.name }}{% endblock %}</h1>
{% if admin_view.name == '网站管理' %}
<p class="page-description">管理和维护AI工具导航平台的所有工具。</p>
{% elif admin_view.name == '标签管理' %}
<p class="page-description">管理工具分类标签,优化内容组织。</p>
{% elif admin_view.name == '新闻管理' %}
<p class="page-description">管理工具相关新闻和更新动态。</p>
{% elif admin_view.name == '管理员' %}
<p class="page-description">管理后台管理员账号和权限。</p>
{% else %}
<p class="page-description">{{ admin_view.category or '' }}</p>
{% endif %}
</div>
{% block page_actions %}{% endblock %}
</div>
{% block messages %}
{{ layout.messages() }}
{% endblock %}
{% block body %}{% endblock %}
{% endblock %}
</main>
</div>
<!-- Bootstrap JS -->
<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>
{% block tail_js %}{% endblock %}
{% block tail %}{% endblock %}
</body>
</html>