feat: v3.2 - 用户管理功能和后台菜单统一

新增功能:
- 用户管理列表页面(搜索、分页)
- 用户详情页面(基本信息、收藏统计)
- 管理员重置用户密码功能
- 管理员修改用户昵称功能
- 管理后台首页添加用户统计卡片

优化改进:
- 统一后台菜单结构,创建可复用的 sidebar 组件
- 所有后台页面使用统一菜单,避免硬编码
- 优化权限配置文件,清理冗余规则

技术文档:
- 添加任务分解规则文档
- 添加后台菜单统一规则文档
- 添加数据库字段修复脚本

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jowe
2026-02-08 23:20:35 +08:00
parent c61969dfc9
commit 2eefaa8cc9
14 changed files with 2168 additions and 297 deletions

View File

@@ -0,0 +1,107 @@
<!-- 左侧菜单栏 -->
<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 {% if active_page == 'dashboard' %}active{% endif %}">
<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 {% if active_page == 'site' %}active{% endif %}">
<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 {% if active_page == 'tag' %}active{% endif %}">
<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 {% if active_page == 'news' %}active{% endif %}">
<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 {% if active_page == 'prompt' %}active{% endif %}">
<a href="{{ url_for('prompttemplate.index_view') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">psychology</span>
<span class="nav-text">Prompt管理</span>
</a>
</li>
<li class="nav-item {% if active_page == 'admin_user' %}active{% endif %}">
<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 {% if active_page == 'users' %}active{% endif %}">
<a href="{{ url_for('admin_users') }}" class="nav-link">
<span class="material-symbols-outlined nav-icon">group</span>
<span class="nav-text">用户管理</span>
</a>
</li>
<li class="nav-item {% if active_page == 'seo' %}active{% endif %}">
<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 {% if active_page == 'batch_import' %}active{% endif %}">
<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 {% if active_page == 'change_password' %}active{% endif %}">
<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>