Files
2026-08-14 10:55:06 +08:00

105 lines
4.5 KiB
PHP

<?php
if (!defined('IN_APP')) {
http_response_code(403);
exit('Forbidden');
}
function adminHeader($title = '', $active = '') {
$staff = currentStaff();
if (!$staff) {
// 未登录(理论上 requireStaff 已拦截,这里兜底)
redirect('login.php');
}
$isAdmin = (int) $staff['is_admin'] === 1;
$roleLabel = $isAdmin ? '管理员' : '客服';
if ($title) {
$pageTitle = $title . ' - ' . getSiteName();
} else {
$pageTitle = getSiteName() . ' - 后台';
}
$cssVer = file_exists(__DIR__ . '/../assets/style.css') ? filemtime(__DIR__ . '/../assets/style.css') : time();
// 后台导航定义
$navAll = [
'index' => ['url' => './', 'label' => '<i class="fas fa-dashboard"></i> 仪表盘'],
'products' => ['url' => 'products', 'label' => '<i class="fas fa-box"></i> 商品管理'],
'groups' => ['url' => 'groups', 'label' => '<i class="fas fa-tags"></i> 商品分组'],
'orders' => ['url' => 'orders', 'label' => '<i class="fas fa-receipt"></i> 订单管理'],
'tickets' => ['url' => 'tickets', 'label' => '<i class="fas fa-ticket-alt"></i> 工单管理'],
'departments' => ['url' => 'departments','label' => '<i class="fas fa-sitemap"></i> 工单部门'],
'announcements' => ['url' => 'announcements', 'label' => '<i class="fas fa-bullhorn"></i> 公告中心'],
'users' => ['url' => 'users', 'label' => '<i class="fas fa-users"></i> 用户管理'],
'admins' => ['url' => 'admins', 'label' => '<i class="fas fa-user-shield"></i> 管理员'],
'settings' => ['url' => 'settings', 'label' => '<i class="fas fa-cog"></i> 设置'],
'logs' => ['url' => 'logs', 'label' => '<i class="fas fa-scroll"></i> 系统日志'],
];
// 管理员与客服均可见全部导航(客服为只读/受限操作,在各页面内单独控制)
$nav = $navAll;
$theme = currentTheme() === 'dark' ? 'dark' : 'light';
?>
<!DOCTYPE html>
<html lang="zh-CN" data-theme="<?= $theme ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= h($pageTitle) ?></title>
<?php
$favicon = getSetting('favicon', '');
if (!empty($favicon) && file_exists(__DIR__ . '/../' . $favicon)) {
echo '<link rel="icon" href="../' . h($favicon) . '?v=' . filemtime(__DIR__ . '/../' . $favicon) . '">' . "\n ";
}
?>
<link rel="stylesheet" href="../assets/vendor/fontawesome/all.min.css">
<link rel="stylesheet" href="../assets/style.css?v=<?= $cssVer ?>">
</head>
<body>
<header class="admin-bar">
<div class="container nav">
<a href="/" class="btn btn-ghost"><i class="fas fa-arrow-left"></i></a>
<a href="./" class="brand"><i class="fas fa-store"></i></a>
<button class="nav-toggle" onclick="toggleAdminNav()">
<i class="fas fa-bars"></i>
</button>
<nav class="nav-links" id="adminNavLinks">
<?php foreach ($nav as $k => $n): ?>
<a href="<?= $n['url'] ?>" class="<?= $k === $active ? 'active' : '' ?>"><?= $n['label'] ?></a>
<?php endforeach; ?>
</nav>
<div class="nav-actions">
<span class="admin-user" title="当前登录身份"><i class="fas fa-<?= $isAdmin ? 'user-shield' : 'headset' ?>"></i> <?= h($staff['username']) ?> · <?= $roleLabel ?></span>
<a href="logout" class="btn btn-ghost"><i class="fas fa-sign-out-alt"></i></a>
</div>
</div>
</header>
<main class="container admin-main">
<?php
}
function adminFooter()
{
?>
</main>
<footer class="admin-footer">
<div class="container">
<p>&copy; <?= date('Y') ?> <?= h(getSiteName()) ?> · 后台管理</p>
</div>
</footer>
<script>
function toggleAdminNav() {
var nav = document.getElementById('adminNavLinks');
nav.classList.toggle('open');
}
document.addEventListener('click', function(e) {
var nav = document.getElementById('adminNavLinks');
var toggle = document.querySelector('.admin-bar .nav-toggle');
if (nav && toggle) {
if (!nav.contains(e.target) && !toggle.contains(e.target)) {
nav.classList.remove('open');
}
}
});
</script>
</body>
</html>
<?php
}