08-12-周三_14-20-35

This commit is contained in:
AaronXu
2026-08-12 14:20:36 +08:00
parent 977f7eec96
commit 56dd5b5adf
16 changed files with 1867 additions and 4 deletions
@@ -0,0 +1,249 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>后台管理 - 笔记小站</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<nav class="navbar">
<a class="navbar-brand" href="index.html"><span class="logo-icon">📝</span> 笔记小站</a>
<div class="navbar-actions" id="navbarActions"></div>
</nav>
<div class="container" id="app">
<div class="admin-header">
<h1>⚙️ 后台管理</h1>
</div>
<div class="admin-tabs">
<button class="admin-tab" data-tab="categories">📂 分类管理</button>
<button class="admin-tab" data-tab="notes">📝 笔记管理</button>
<button class="admin-tab" data-tab="comments">💬 评论管理</button>
<button class="admin-tab" data-tab="users">👥 用户管理</button>
</div>
<div id="tabContent"></div>
</div>
<div class="toast-container" id="toastContainer"></div>
<script src="js/data.js"></script>
<script src="js/common.js"></script>
<script>
(function () {
var activeTab = getUrlParam('tab') || 'categories';
var tabs = document.querySelectorAll('.admin-tab');
tabs.forEach(function (t) {
if (t.dataset.tab === activeTab) t.classList.add('active');
t.addEventListener('click', function () {
history.replaceState(null, '', '?tab=' + this.dataset.tab);
activeTab = this.dataset.tab;
tabs.forEach(function (x) { x.classList.remove('active'); });
this.classList.add('active');
renderTab();
});
});
renderTab();
function renderTab() {
var content = document.getElementById('tabContent');
if (activeTab === 'categories') content.innerHTML = renderCategories();
else if (activeTab === 'notes') content.innerHTML = renderNotes();
else if (activeTab === 'comments') content.innerHTML = renderComments();
else if (activeTab === 'users') content.innerHTML = renderUsers();
}
/* ============ Categories ============ */
function renderCategories() {
var h = '<div class="section-header">';
h += '<h2>分类列表</h2>';
h += '<button class="btn btn-primary" onclick="openCategoryModal()">+ 新增分类</button>';
h += '</div>';
h += '<div class="data-table">';
h += '<table><thead><tr><th>ID</th><th>图标</th><th>名称</th><th>颜色</th><th>操作</th></tr></thead><tbody>';
DATA.categories.forEach(function (c) {
h += '<tr><td>' + c.id + '</td><td>' + c.icon + '</td><td>' + c.name + '</td>';
h += '<td><span class="color-dot" style="background:' + c.color + '"></span> ' + c.color + '</td>';
h += '<td><button class="btn btn-sm" onclick="openCategoryModal(' + c.id + ')">编辑</button> ';
h += '<button class="btn btn-sm btn-danger" onclick="deleteCategory(' + c.id + ')">删除</button></td></tr>';
});
h += '</tbody></table></div>';
return h;
}
window.openCategoryModal = function (id) {
var cat = id ? findById(DATA.categories, id) : null;
var title = cat ? '编辑分类' : '新增分类';
var h = '<div class="form-group"><label>名称</label><input type="text" id="fname" value="' + (cat ? cat.name : '') + '"></div>';
h += '<div class="form-group"><label>图标</label><input type="text" id="ficon" value="' + (cat ? cat.icon : '📁') + '"></div>';
h += '<div class="form-group"><label>颜色</label><input type="color" id="fcolor" value="' + (cat ? cat.color : '#6366f1') + '"></div>';
h += '<div class="form-actions"><button class="btn" onclick="closeModal()">取消</button>';
h += '<button class="btn btn-primary" onclick="saveCategory(' + (cat ? cat.id : 0) + ')">保存</button></div>';
renderModal(title, h);
};
window.saveCategory = function (id) {
var name = document.getElementById('fname').value.trim();
var icon = document.getElementById('ficon').value.trim();
var color = document.getElementById('fcolor').value.trim();
if (!name) { showToast('请输入名称', 'error'); return; }
if (id) {
var c = findById(DATA.categories, id);
if (c) { c.name = name; c.icon = icon; c.color = color; }
} else {
DATA.categories.push({ id: DATA.categories.length + 1, name: name, icon: icon, color: color });
}
closeModal(); renderTab(); showToast('保存成功', 'success');
};
window.deleteCategory = function (id) {
DATA.categories = DATA.categories.filter(function (c) { return c.id !== id; });
renderTab(); showToast('已删除', 'info');
};
/* ============ Notes ============ */
function renderNotes() {
var h = '<div class="section-header">';
h += '<h2>笔记列表</h2>';
h += '<button class="btn btn-primary" onclick="openNoteModal()">+ 新增笔记</button>';
h += '</div><div class="data-table"><table><thead><tr><th>ID</th><th>标题</th><th>分类</th><th>作者</th><th>时间</th><th>操作</th></tr></thead><tbody>';
DATA.notes.forEach(function (n) {
var cat = findById(DATA.categories, n.categoryId);
var author = findById(DATA.users, n.userId);
h += '<tr><td>' + n.id + '</td><td>' + n.title + '</td>';
h += '<td>' + (cat ? cat.icon + ' ' + cat.name : '-') + '</td>';
h += '<td>' + (author ? author.nickname : '-') + '</td><td>' + n.createdAt + '</td>';
h += '<td><button class="btn btn-sm" onclick="openNoteModal(' + n.id + ')">编辑</button> ';
h += '<button class="btn btn-sm btn-danger" onclick="deleteNote(' + n.id + ')">删除</button></td></tr>';
});
h += '</tbody></table></div>';
return h;
}
window.openNoteModal = function (id) {
var note = id ? findById(DATA.notes, id) : null;
var title = note ? '编辑笔记' : '新增笔记';
var h = '<div class="form-group"><label>标题</label><input type="text" id="ftitle" value="' + (note ? note.title : '') + '"></div>';
h += '<div class="form-group"><label>分类</label><select id="fcat">';
DATA.categories.forEach(function (c) {
h += '<option value="' + c.id + '"' + (note && note.categoryId === c.id ? ' selected' : '') + '>' + c.icon + ' ' + c.name + '</option>';
});
h += '</select></div>';
h += '<div class="form-group"><label>内容</label><textarea id="fcontent" rows="6">' + (note ? note.content : '') + '</textarea></div>';
h += '<div class="form-actions"><button class="btn" onclick="closeModal()">取消</button>';
h += '<button class="btn btn-primary" onclick="saveNote(' + (note ? note.id : 0) + ')">保存</button></div>';
renderModal(title, h);
};
window.saveNote = function (id) {
var title = document.getElementById('ftitle').value.trim();
var catId = parseInt(document.getElementById('fcat').value);
var content = document.getElementById('fcontent').value.trim();
if (!title || !content) { showToast('请填写标题和内容', 'error'); return; }
if (id) {
var n = findById(DATA.notes, id);
if (n) { n.title = title; n.categoryId = catId; n.content = content; }
} else {
DATA.notes.push({
id: DATA.notes.length + 1,
title: title,
categoryId: catId,
content: content,
userId: 1,
createdAt: new Date().toISOString().slice(0, 10),
summary: content.slice(0, 100) + (content.length > 100 ? '...' : '')
});
}
closeModal(); renderTab(); showToast('保存成功', 'success');
};
window.deleteNote = function (id) {
DATA.notes = DATA.notes.filter(function (n) { return n.id !== id; });
DATA.comments = DATA.comments.filter(function (c) { return c.noteId !== id; });
renderTab(); showToast('已删除', 'info');
};
/* ============ Comments ============ */
function renderComments() {
var h = '<div class="section-header"><h2>评论列表</h2></div><div class="data-table"><table><thead><tr><th>ID</th><th>笔记</th><th>用户</th><th>内容</th><th>时间</th><th>操作</th></tr></thead><tbody>';
DATA.comments.forEach(function (c) {
var note = findById(DATA.notes, c.noteId);
var user = findById(DATA.users, c.userId);
h += '<tr><td>' + c.id + '</td><td>' + (note ? note.title : '已删除') + '</td>';
h += '<td>' + (user ? user.nickname : (c.author || '游客')) + '</td><td>' + c.content + '</td><td>' + c.createdAt + '</td>';
h += '<td><button class="btn btn-sm btn-danger" onclick="deleteComment(' + c.id + ')">删除</button></td></tr>';
});
h += '</tbody></table></div>';
return h;
}
window.deleteComment = function (id) {
DATA.comments = DATA.comments.filter(function (c) { return c.id !== id; });
renderTab(); showToast('已删除', 'info');
};
/* ============ Users ============ */
function renderUsers() {
var h = '<div class="section-header">';
h += '<h2>用户列表</h2>';
h += '<button class="btn btn-primary" onclick="openUserModal()">+ 新增用户</button>';
h += '</div><div class="data-table"><table><thead><tr><th>ID</th><th>头像</th><th>用户名</th><th>昵称</th><th>角色</th><th>时间</th><th>操作</th></tr></thead><tbody>';
DATA.users.forEach(function (u) {
h += '<tr><td>' + u.id + '</td><td>' + u.avatar + '</td><td>' + u.username + '</td><td>' + u.nickname + '</td>';
h += '<td><span class="badge badge-' + u.role + '">' + (u.role === 'admin' ? '管理员' : '普通用户') + '</span></td>';
h += '<td>' + u.createdAt + '</td>';
h += '<td><button class="btn btn-sm" onclick="openUserModal(' + u.id + ')">编辑</button> ';
h += '<button class="btn btn-sm btn-danger" onclick="deleteUser(' + u.id + ')">删除</button></td></tr>';
});
h += '</tbody></table></div>';
return h;
}
window.openUserModal = function (id) {
var u = id ? findById(DATA.users, id) : null;
var title = u ? '编辑用户' : '新增用户';
var h = '<div class="form-group"><label>用户名</label><input type="text" id="fname" value="' + (u ? u.username : '') + '"></div>';
h += '<div class="form-group"><label>昵称</label><input type="text" id="fnick" value="' + (u ? u.nickname : '') + '"></div>';
h += '<div class="form-group"><label>角色</label><select id="frole">';
h += '<option value="user"' + (u && u.role === 'user' ? ' selected' : '') + '>普通用户</option>';
h += '<option value="admin"' + (u && u.role === 'admin' ? ' selected' : '') + '>管理员</option>';
h += '</select></div>';
h += '<div class="form-actions"><button class="btn" onclick="closeModal()">取消</button>';
h += '<button class="btn btn-primary" onclick="saveUser(' + (u ? u.id : 0) + ')">保存</button></div>';
renderModal(title, h);
};
window.saveUser = function (id) {
var username = document.getElementById('fname').value.trim();
var nickname = document.getElementById('fnick').value.trim();
var role = document.getElementById('frole').value;
if (!username || !nickname) { showToast('请填写用户名和昵称', 'error'); return; }
if (id) {
var u = findById(DATA.users, id);
if (u) { u.username = username; u.nickname = nickname; u.role = role; }
} else {
DATA.users.push({
id: DATA.users.length + 1,
username: username, password: '123456',
nickname: nickname, avatar: '😊', role: role,
createdAt: new Date().toISOString().slice(0, 10)
});
}
closeModal(); renderTab(); showToast('保存成功', 'success');
};
window.deleteUser = function (id) {
DATA.users = DATA.users.filter(function (u) { return u.id !== id; });
renderTab(); showToast('已删除', 'info');
};
/* Helper */
function findById(arr, id) {
for (var i = 0; i < arr.length; i++) { if (arr[i].id === id) return arr[i]; }
return null;
}
})();
</script>
</body>
</html>