232 lines
12 KiB
HTML
232 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{% block title %}图书管理系统{% endblock %}</title>
|
|
<!-- 通用CSS -->
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
|
|
<!-- 页面特定CSS -->
|
|
{% block head %}{% endblock %}
|
|
</head>
|
|
<body>
|
|
<div class="app-container">
|
|
<!-- 侧边导航栏 -->
|
|
<nav class="sidebar">
|
|
<div class="logo-container">
|
|
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo" class="logo">
|
|
<h2>图书管理系统</h2>
|
|
</div>
|
|
<ul class="nav-links">
|
|
<li class="{% if request.path == '/' %}active{% endif %}">
|
|
<a href="{{ url_for('index') }}"><i class="fas fa-home"></i> 首页</a>
|
|
</li>
|
|
<li class="{% if '/book/list' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('book.browse_books') }}"><i class="fas fa-book"></i> 图书浏览</a>
|
|
</li>
|
|
<li class="{% if '/borrow' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('borrow.my_borrows') }}"><i class="fas fa-bookmark"></i> 我的借阅</a>
|
|
</li>
|
|
<li class="{% if '/announcement' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('announcement.announcement_list') }}"><i class="fas fa-bell"></i> 通知公告</a>
|
|
</li>
|
|
{% if current_user.is_authenticated and current_user.role_id == 1 %}
|
|
<li class="nav-category">管理功能</li>
|
|
<li class="{% if '/user/manage' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('user.user_list') }}"><i class="fas fa-users"></i> 用户管理</a>
|
|
</li>
|
|
<li class="{% if '/user/roles' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('user.role_list') }}"><i class="fas fa-user-tag"></i> 角色管理</a>
|
|
</li>
|
|
<li class="{% if '/book/admin/list' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('book.admin_book_list') }}"><i class="fas fa-layer-group"></i> 图书管理</a>
|
|
</li>
|
|
<li class="{% if '/borrow/manage' in request.path %}active{% endif %}">
|
|
{% if current_user.role_id == 1 %}
|
|
<a href="{{ url_for('borrow.manage_borrows') }}"><i class="fas fa-exchange-alt"></i> 借阅管理</a>
|
|
{% endif %}
|
|
</li>
|
|
<li class="{% if '/inventory' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('inventory.inventory_list') }}"><i class="fas fa-warehouse"></i> 库存管理</a>
|
|
</li>
|
|
<li class="{% if '/statistics' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('statistics.index') }}"><i class="fas fa-chart-bar"></i> 统计分析</a>
|
|
</li>
|
|
<li class="{% if '/log' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('log.log_list') }}"><i class="fas fa-history"></i> 日志管理</a>
|
|
</li>
|
|
<li class="{% if '/announcement/manage' in request.path %}active{% endif %}">
|
|
<a href="{{ url_for('announcement.manage_announcements') }}"><i class="fas fa-bullhorn"></i> 公告管理</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- 主内容区 -->
|
|
<main class="main-content">
|
|
<!-- 顶部导航 -->
|
|
<header class="top-bar">
|
|
<!-- 修改搜索容器为表单 -->
|
|
<form action="{{ url_for('book.browse_books') }}" method="GET" class="search-container" id="global-search-form">
|
|
<i class="fas fa-search search-icon" id="search-submit-icon"></i>
|
|
<input type="text" name="search" placeholder="搜索图书..." class="search-input" id="global-search-input">
|
|
</form>
|
|
<div class="user-menu">
|
|
<div class="notifications dropdown">
|
|
<a href="#" class="notification-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<i class="fas fa-bell"></i>
|
|
{% if current_user.is_authenticated %}
|
|
{% set unread_count = get_unread_notifications_count(current_user.id) %}
|
|
{% if unread_count > 0 %}
|
|
<span class="badge">{{ unread_count }}</span>
|
|
{% endif %}
|
|
{% endif %}
|
|
</a>
|
|
|
|
{% if current_user.is_authenticated %}
|
|
<div class="dropdown-menu notification-dropdown">
|
|
<div class="notification-header">
|
|
<h6 class="dropdown-header">通知中心</h6>
|
|
{% if unread_count > 0 %}
|
|
<a href="{{ url_for('announcement.mark_all_as_read') }}" class="mark-all-read">全部标为已读</a>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="notification-items">
|
|
{% set recent_notifications = get_recent_notifications(current_user.id, 5) %}
|
|
{% if recent_notifications %}
|
|
{% for notification in recent_notifications %}
|
|
<a class="dropdown-item notification-item {% if notification.status == 0 %}unread{% endif %}"
|
|
href="{{ url_for('announcement.view_notification', notification_id=notification.id) }}">
|
|
<div class="notification-content">
|
|
<h6 class="notification-title">{{ notification.title }}</h6>
|
|
<p class="notification-text">{{ notification.content|striptags|truncate(50) }}</p>
|
|
<span class="notification-time">{{ notification.created_at }}</span>
|
|
</div>
|
|
</a>
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="no-notifications">
|
|
<p>暂无通知</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="dropdown-divider"></div>
|
|
<a class="dropdown-item view-all" href="{{ url_for('announcement.user_notifications') }}">
|
|
查看所有通知
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% if current_user.is_authenticated %}
|
|
<div class="user-info">
|
|
<div class="user-avatar">
|
|
{{ current_user.username[0] }}
|
|
</div>
|
|
<div class="user-details">
|
|
<span class="user-name">{{ current_user.username }}</span>
|
|
<span class="user-role">{{ '管理员' if current_user.role_id == 1 else '普通用户' }}</span>
|
|
</div>
|
|
<div class="dropdown-menu">
|
|
<a href="{{ url_for('user.user_profile') }}"><i class="fas fa-user-circle"></i> 个人中心</a>
|
|
<a href="#"><i class="fas fa-cog"></i> 设置</a>
|
|
<a href="{{ url_for('user.logout') }}"><i class="fas fa-sign-out-alt"></i> 退出登录</a>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="user-info">
|
|
<a href="{{ url_for('user.login') }}" class="login-link">登录</a>
|
|
<a href="{{ url_for('user.register') }}" class="register-link">注册</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</header>
|
|
|
|
<!-- 内容区 - 这里是核心变化 -->
|
|
<div class="content-wrapper">
|
|
{% block content %}
|
|
<!-- 子模板将在这里添加内容 -->
|
|
{% endblock %}
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- 通用JavaScript -->
|
|
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 用户菜单下拉
|
|
const userInfo = document.querySelector('.user-info');
|
|
if (userInfo) {
|
|
userInfo.addEventListener('click', function(e) {
|
|
if (!e.target.classList.contains('login-link') &&
|
|
!e.target.classList.contains('register-link')) {
|
|
userInfo.classList.toggle('active');
|
|
}
|
|
});
|
|
|
|
// 点击其他区域关闭下拉菜单
|
|
document.addEventListener('click', function(e) {
|
|
if (!userInfo.contains(e.target)) {
|
|
userInfo.classList.remove('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
// 搜索功能
|
|
const searchForm = document.getElementById('global-search-form');
|
|
const searchInput = document.getElementById('global-search-input');
|
|
const searchIcon = document.getElementById('search-submit-icon');
|
|
|
|
if (searchForm && searchInput && searchIcon) {
|
|
// 智能判断搜索提交目标 - 根据当前页面设置合适的搜索结果页
|
|
function updateSearchFormAction() {
|
|
const currentPath = window.location.pathname;
|
|
if (currentPath.includes('/book/admin/list')) {
|
|
searchForm.action = "{{ url_for('book.admin_book_list') }}";
|
|
} else if (currentPath.includes('/book/list')) {
|
|
searchForm.action = "{{ url_for('book.book_list') }}";
|
|
} else if (currentPath.includes('/book/browse')) {
|
|
searchForm.action = "{{ url_for('book.browse_books') }}";
|
|
} else {
|
|
searchForm.action = "{{ url_for('book.browse_books') }}";
|
|
}
|
|
}
|
|
|
|
updateSearchFormAction();
|
|
|
|
// 点击搜索图标时提交表单
|
|
searchIcon.addEventListener('click', function() {
|
|
if (searchInput.value.trim() !== '') {
|
|
updateSearchFormAction();
|
|
searchForm.submit();
|
|
}
|
|
});
|
|
|
|
// 输入框按回车键时提交表单
|
|
searchInput.addEventListener('keypress', function(e) {
|
|
if (e.key === 'Enter') {
|
|
if (searchInput.value.trim() === '') {
|
|
e.preventDefault(); // 防止空搜索提交
|
|
} else {
|
|
updateSearchFormAction();
|
|
// 表单自然会提交,不需要额外代码
|
|
}
|
|
}
|
|
});
|
|
|
|
// 添加视觉反馈,让用户知道搜索图标可点击
|
|
searchIcon.style.cursor = 'pointer';
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<!-- 页面特定JavaScript -->
|
|
{% block scripts %}{% endblock %}
|
|
</body>
|
|
</html>
|