418 lines
13 KiB
HTML
418 lines
13 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="theme-color" content="#10b981">
|
||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||
<meta name="apple-mobile-web-app-title" content="萌芽导航管理">
|
||
<title>萌芽导航-后台管理</title>
|
||
<link rel="manifest" href="/manifest.webmanifest">
|
||
<link rel="icon" href="/favicon.ico" sizes="any">
|
||
<link rel="icon" href="/logo.png" type="image/png">
|
||
<link rel="apple-touch-icon" href="/logo.png">
|
||
<link rel="stylesheet" href="styles.css">
|
||
<script src="config.js"></script>
|
||
<script src="apply-config.js"></script>
|
||
<style>
|
||
.login-container {
|
||
max-width: 480px;
|
||
margin: 80px auto;
|
||
padding: 32px;
|
||
background: white;
|
||
border-radius: 12px;
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
||
text-align: center;
|
||
}
|
||
|
||
.no-permission h2 {
|
||
color: #64748b;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.no-permission p {
|
||
color: #94a3b8;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.admin-container {
|
||
display: none;
|
||
}
|
||
|
||
.admin-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
padding: 15px 20px;
|
||
background: white;
|
||
border-radius: 10px;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.logout-btn {
|
||
background: #dc2626;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 16px;
|
||
border-radius: 50px;
|
||
cursor: pointer;
|
||
font-weight: 600;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.logout-btn:hover {
|
||
background: #b91c1c;
|
||
}
|
||
|
||
.exit-btn {
|
||
background: #64748b;
|
||
color: white;
|
||
border: none;
|
||
padding: 8px 16px;
|
||
border-radius: 50px;
|
||
cursor: pointer;
|
||
font-weight: 600;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.exit-btn:hover {
|
||
background: #475569;
|
||
}
|
||
|
||
.sites-table {
|
||
background: white;
|
||
border-radius: 10px;
|
||
padding: 20px;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||
overflow-x: auto;
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
th, td {
|
||
padding: 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid #f1f5f9;
|
||
}
|
||
|
||
th {
|
||
background: #f8fafc;
|
||
font-weight: 600;
|
||
color: #1e293b;
|
||
}
|
||
|
||
.action-btns {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
.btn-edit, .btn-delete {
|
||
padding: 6px 12px;
|
||
border: none;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
font-size: 0.85rem;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.btn-edit {
|
||
background: #3b82f6;
|
||
color: white;
|
||
}
|
||
|
||
.btn-edit:hover {
|
||
background: #2563eb;
|
||
}
|
||
|
||
.btn-delete {
|
||
background: #ef4444;
|
||
color: white;
|
||
}
|
||
|
||
.btn-delete:hover {
|
||
background: #dc2626;
|
||
}
|
||
|
||
.modal-overlay {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
z-index: 9999;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.modal-overlay.active {
|
||
display: flex;
|
||
}
|
||
|
||
.error-message {
|
||
color: #dc2626;
|
||
margin-top: 10px;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.success-message {
|
||
color: #059669;
|
||
margin-top: 10px;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.tag-display {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 4px;
|
||
}
|
||
|
||
.tag-display .tag {
|
||
background: #e0e7ff;
|
||
color: #4338ca;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
font-size: 0.75rem;
|
||
}
|
||
|
||
.categories-panel {
|
||
background: white;
|
||
border-radius: 10px;
|
||
padding: 16px 20px;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.categories-panel .panel-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.category-add {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.category-add input {
|
||
padding: 8px 10px;
|
||
border: 1px solid #e2e8f0;
|
||
border-radius: 8px;
|
||
font-size: 0.9rem;
|
||
min-width: 160px;
|
||
}
|
||
|
||
.category-list {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
.category-item {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
background: #f8fafc;
|
||
border: 1px solid #e2e8f0;
|
||
padding: 6px 10px;
|
||
border-radius: 20px;
|
||
font-size: 0.85rem;
|
||
}
|
||
|
||
.category-item .category-actions button {
|
||
border: none;
|
||
background: transparent;
|
||
color: #475569;
|
||
cursor: pointer;
|
||
font-size: 0.85rem;
|
||
padding: 0 2px;
|
||
}
|
||
|
||
.category-item .category-actions button:hover {
|
||
color: #1d4ed8;
|
||
}
|
||
|
||
.sites-table-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.sites-table-header h2 {
|
||
margin: 0;
|
||
}
|
||
|
||
.sites-filter {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.sites-filter label {
|
||
font-size: 0.9rem;
|
||
color: #64748b;
|
||
}
|
||
|
||
#site-category-filter {
|
||
padding: 6px 12px;
|
||
border: 1px solid #e2e8f0;
|
||
border-radius: 8px;
|
||
font-size: 0.9rem;
|
||
min-width: 160px;
|
||
background: white;
|
||
cursor: pointer;
|
||
}
|
||
|
||
#site-category-filter:focus {
|
||
outline: none;
|
||
border-color: #3b82f6;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<!-- 无 token 或 token 错误时显示 -->
|
||
<div class="login-container" id="no-permission">
|
||
<h2>⚠️ 无法进入后台</h2>
|
||
<p>请使用带 token 的链接访问,例如:</p>
|
||
<p style="margin-top: 8px; word-break: break-all; color: #1e293b; font-size: 0.85rem;"><strong>/admin.html?token=管理员密钥</strong></p>
|
||
<p style="margin-top: 16px;">链接中的 token 需为后端 Worker 配置的管理员密钥(ADMIN_PASSWORD)。</p>
|
||
</div>
|
||
|
||
<!-- 管理界面(仅 token 正确时显示) -->
|
||
<div class="admin-container" id="admin-container">
|
||
<div class="admin-header">
|
||
<h1 id="admin-title">萌芽导航-管理后台</h1>
|
||
<button class="exit-btn" id="logout-btn">退出</button>
|
||
</div>
|
||
|
||
<div class="categories-panel">
|
||
<div class="panel-header">
|
||
<h2>📁 分类管理</h2>
|
||
<div class="category-add">
|
||
<input type="text" id="new-category-name" placeholder="新增分类">
|
||
<button class="btn-edit" id="add-category-btn">添加分类</button>
|
||
</div>
|
||
</div>
|
||
<div class="category-list" id="category-list">
|
||
<!-- 分类标签 -->
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 20px;">
|
||
<button class="add-site-btn" id="add-new-site">✚ 添加新网站</button>
|
||
</div>
|
||
|
||
<div class="sites-table">
|
||
<div class="sites-table-header">
|
||
<h2>网站列表</h2>
|
||
<div class="sites-filter">
|
||
<label for="site-category-filter">按分类筛选:</label>
|
||
<select id="site-category-filter" title="选择分类可快速筛选网站">
|
||
<option value="">全部</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<table id="sites-table">
|
||
<thead>
|
||
<tr>
|
||
<th>名称</th>
|
||
<th>URL</th>
|
||
<th>分类</th>
|
||
<th>描述</th>
|
||
<th>标签</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="sites-tbody">
|
||
<!-- 动态加载 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 编辑/添加网站模态框 -->
|
||
<div class="modal-overlay" id="edit-modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h2 id="modal-title">添加网站</h2>
|
||
<button class="close-modal" id="close-edit-modal">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<form id="edit-site-form">
|
||
<input type="hidden" id="edit-site-id">
|
||
<div class="form-group">
|
||
<label for="edit-site-name">网站名称 *</label>
|
||
<input type="text" id="edit-site-name" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="edit-site-url">网站地址 *</label>
|
||
<input type="url" id="edit-site-url" required>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="edit-site-description">网站描述</label>
|
||
<textarea id="edit-site-description"></textarea>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="edit-site-category">网站分类 *</label>
|
||
<select id="edit-site-category" required>
|
||
<option value="">选择分类</option>
|
||
<option value="常用">常用</option>
|
||
<option value="工作">工作</option>
|
||
<option value="学习">学习</option>
|
||
<option value="娱乐">娱乐</option>
|
||
<option value="社交">社交</option>
|
||
<option value="工具">工具</option>
|
||
<option value="新闻">新闻</option>
|
||
<option value="购物">购物</option>
|
||
<option value="其他">其他</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="edit-site-tags">网站标签</label>
|
||
<input type="text" id="edit-site-tags" placeholder="用逗号分隔">
|
||
</div>
|
||
</div>
|
||
<button type="submit" class="submit-btn">保存</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toast" id="toast">
|
||
<span class="toast-icon">✅</span>
|
||
<span class="toast-message">操作成功</span>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="admin.js"></script>
|
||
<script>
|
||
// 注册 Service Worker
|
||
if ('serviceWorker' in navigator) {
|
||
window.addEventListener('load', () => {
|
||
navigator.serviceWorker.register('/sw.js')
|
||
.then(registration => {
|
||
console.log('✅ Service Worker 注册成功:', registration.scope);
|
||
})
|
||
.catch(error => {
|
||
console.error('❌ Service Worker 注册失败:', error);
|
||
});
|
||
});
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|