feat: 管理后台目录树支持折叠/展开
- 有子节点的目录前显示折叠箭头, 点击折叠/展开子目录 - 折叠状态持久化到 localStorage, 刷新后保留 - 与前台目录树折叠行为一致
This commit is contained in:
+51
-2
@@ -120,6 +120,27 @@
|
||||
}
|
||||
.tree-item .actions button:hover { background: #e8eaed; }
|
||||
.tree-children { padding-left: 20px; }
|
||||
.tree-item .toggle {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
color: #888;
|
||||
flex-shrink: 0;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
.tree-item .toggle svg { width: 14px; height: 14px; fill: currentColor; }
|
||||
.tree-item .toggle.collapsed { transform: rotate(-90deg); }
|
||||
.tree-item .toggle:hover { color: #1a73e8; }
|
||||
.tree-children { display: block; }
|
||||
.tree-children.hidden { display: none; }
|
||||
|
||||
|
||||
/* 右侧内容区 - 左右分栏 */
|
||||
.content {
|
||||
@@ -900,6 +921,15 @@
|
||||
const API = '/api';
|
||||
const ADMIN_API = '/admin/api';
|
||||
let treeData = [];
|
||||
// 折叠的目录 id 集合(持久化到 localStorage,按用户隔离)
|
||||
let collapsedFolders = new Set();
|
||||
try {
|
||||
const saved = JSON.parse(localStorage.getItem('noteManagerCollapsedFolders') || '[]');
|
||||
collapsedFolders = new Set(Array.isArray(saved) ? saved : []);
|
||||
} catch (e) { collapsedFolders = new Set(); }
|
||||
function saveCollapsedFolders() {
|
||||
try { localStorage.setItem('noteManagerCollapsedFolders', JSON.stringify([...collapsedFolders])); } catch (e) {}
|
||||
}
|
||||
let currentItem = null;
|
||||
let isFolderMode = false;
|
||||
let editId = null; // 当前打开的笔记 id
|
||||
@@ -1135,10 +1165,17 @@
|
||||
const children = treeData.filter(c => c.parent_id === item.id);
|
||||
const hasChildren = children.length > 0;
|
||||
const isActive = currentItem && currentItem.id === item.id;
|
||||
|
||||
|
||||
if (item.is_folder) {
|
||||
// 目录折叠状态:默认展开;在 collapsedFolders 中则折叠
|
||||
const isCollapsed = collapsedFolders.has(item.id);
|
||||
return `
|
||||
<div class="tree-item folder ${isActive ? 'active' : ''}" onclick="selectItem(${item.id})">
|
||||
${hasChildren ? `
|
||||
<button class="toggle ${isCollapsed ? 'collapsed' : ''}" title="${isCollapsed ? '展开' : '折叠'}" onclick="event.stopPropagation(); toggleFolder(${item.id})">
|
||||
<svg viewBox="0 0 24 24"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6z"/></svg>
|
||||
</button>` : `
|
||||
<span class="toggle" style="visibility:hidden;"><svg viewBox="0 0 24 24"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6z"/></svg></span>`}
|
||||
<span class="icon">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="${isActive ? '#1a73e8' : '#fbbc04'}">
|
||||
<path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>
|
||||
@@ -1150,11 +1187,12 @@
|
||||
<button onclick="event.stopPropagation(); showNewNoteModal(${item.id})">+笔记</button>
|
||||
</div>
|
||||
</div>
|
||||
${hasChildren ? `<div class="tree-children">${renderTreeItems(children)}</div>` : ''}
|
||||
${hasChildren ? `<div class="tree-children ${isCollapsed ? 'hidden' : ''}">${renderTreeItems(children)}</div>` : ''}
|
||||
`;
|
||||
} else {
|
||||
return `
|
||||
<div class="tree-item ${isActive ? 'active' : ''}" onclick="selectItem(${item.id})">
|
||||
<span class="toggle" style="visibility:hidden;"><svg viewBox="0 0 24 24"><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6z"/></svg></span>
|
||||
<span class="icon">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="#666">
|
||||
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/>
|
||||
@@ -1167,6 +1205,17 @@
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// 折叠/展开目录
|
||||
function toggleFolder(id) {
|
||||
if (collapsedFolders.has(id)) {
|
||||
collapsedFolders.delete(id);
|
||||
} else {
|
||||
collapsedFolders.add(id);
|
||||
}
|
||||
saveCollapsedFolders();
|
||||
renderTree();
|
||||
}
|
||||
|
||||
// 选择项目
|
||||
async function selectItem(id) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user