A:调整文件夹

This commit is contained in:
jimmy committed 2025-09-30 21:58:22 +08:00
1 parent 7af4f31538
commit bf5e44dca3
6 files changed
+372 -163

No files matched your search

@@ -54,10 +54,17 @@
<button
:class="['btn-layout', { active: layoutMode === 'horizontal' }]"
@click="layoutMode = 'horizontal'"
title="横向双面板"
title="左右双面板"
>
▭
</button>
<button
:class="['btn-layout', { active: layoutMode === 'vertical' }]"
@click="layoutMode = 'vertical'"
title="上下双面板"
>
▯
</button>
</div>
</div>
</div>
@@ -73,13 +80,13 @@
/>
<div
v-if="layoutMode === 'horizontal'"
class="splitter"
v-if="layoutMode === 'horizontal' || layoutMode === 'vertical'"
:class="['splitter', layoutMode === 'vertical' ? 'splitter-vertical' : '']"
@mousedown="handleSplitterMouseDown"
></div>
<FilePane
v-if="layoutMode === 'horizontal'"
v-if="layoutMode === 'horizontal' || layoutMode === 'vertical'"
pane-id="right"
:view-mode="viewMode"
:thumbnail-size="thumbnailSize"
@@ -105,7 +112,8 @@ const isDraggingSplitter = ref(false)
function handleSplitterMouseDown(event: MouseEvent) {
isDraggingSplitter.value = true
document.body.style.cursor = 'col-resize'
const isVertical = layoutMode.value === 'vertical'
document.body.style.cursor = isVertical ? 'row-resize' : 'col-resize'
document.body.style.userSelect = 'none'
const mainContent = document.querySelector('.main-content') as HTMLElement
@@ -115,11 +123,21 @@ function handleSplitterMouseDown(event: MouseEvent) {
if (!isDraggingSplitter.value) return
const rect = mainContent.getBoundingClientRect()
const x = e.clientX - rect.left
const percentage = (x / rect.width) * 100
if (percentage > 20 && percentage < 80) {
mainContent.style.gridTemplateColumns = `${percentage}% 4px 1fr`
if (isVertical) {
const y = e.clientY - rect.top
const percentage = (y / rect.height) * 100
if (percentage > 20 && percentage < 80) {
mainContent.style.gridTemplateRows = `${percentage}% 4px 1fr`
}
} else {
const x = e.clientX - rect.left
const percentage = (x / rect.width) * 100
if (percentage > 20 && percentage < 80) {
mainContent.style.gridTemplateColumns = `${percentage}% 4px 1fr`
}
}
}
@@ -140,7 +158,7 @@ function handleSplitterMouseDown(event: MouseEvent) {
.file-manager {
display: flex;
flex-direction: column;
height: 100vh;
height: 100%;
background: #f9fafb;
}
@@ -235,11 +253,20 @@ function handleSplitterMouseDown(event: MouseEvent) {
grid-template-columns: 1fr 4px 1fr;
}
.main-content.layout-vertical {
display: grid;
grid-template-rows: 1fr 4px 1fr;
}
.splitter {
background: #d1d5db;
cursor: col-resize;
}
.splitter.splitter-vertical {
cursor: row-resize;
}
.splitter:hover {
background: #9ca3af;
}
@@ -70,7 +70,7 @@
@drop="handlePaneDrop"
>
<!-- Grid View -->
<div v-if="viewMode === 'grid'" :class="['file-grid', `grid-${thumbnailSize}`]">
<div v-if="viewMode === 'grid'" :class="['file-grid', `grid-${thumbnailSize}`]" :style="gridItemSize">
<div
v-for="(item, index) in visibleItems"
:key="item.name"
@@ -211,6 +211,7 @@ const selection = useFileSelection()
const searchQuery = ref('')
const pathEditMode = ref(false)
const pathEditValue = ref('')
const zoomLevel = ref(100) // 缩放级别:50-200%
// Context Menu state
const contextMenu = ref({
@@ -237,7 +238,8 @@ const dragSelection = ref({
currentX: 0,
currentY: 0,
initialSelections: new Set<string>(),
ctrlKey: false
ctrlKey: false,
justFinished: false
})
// Auto scroll state
@@ -486,13 +488,28 @@ function handleMouseDown(event: MouseEvent) {
currentX: event.clientX - rect.left + scrollEl.scrollLeft,
currentY: event.clientY - rect.top + scrollEl.scrollTop,
initialSelections: new Set(selection.selectedItems.value),
ctrlKey: event.ctrlKey || event.metaKey
ctrlKey: event.ctrlKey || event.metaKey,
justFinished: false
}
if (!dragSelection.value.ctrlKey) {
selection.clearSelection()
}
// 在 document 级别监听 mousemove 和 mouseup
const onDocumentMouseMove = (e: MouseEvent) => {
handleMouseMove(e)
}
const onDocumentMouseUp = (e: MouseEvent) => {
handleMouseUp()
document.removeEventListener('mousemove', onDocumentMouseMove)
document.removeEventListener('mouseup', onDocumentMouseUp)
}
document.addEventListener('mousemove', onDocumentMouseMove)
document.addEventListener('mouseup', onDocumentMouseUp)
event.preventDefault()
}
@@ -503,8 +520,27 @@ function handleMouseMove(event: MouseEvent) {
if (!rect) return
const scrollEl = contentAreaRef.value!
dragSelection.value.currentX = event.clientX - rect.left + scrollEl.scrollLeft
dragSelection.value.currentY = event.clientY - rect.top + scrollEl.scrollTop
// 计算鼠标相对于内容区域的位置(包含滚动偏移)
// 鼠标在视口中的位置 + 滚动偏移 = 在文档中的绝对位置
const rawX = event.clientX - rect.left + scrollEl.scrollLeft
const rawY = event.clientY - rect.top + scrollEl.scrollTop
// 限制坐标在合理范围内
// 当鼠标超出边界时,坐标应该停留在边界上,而不是继续增长
const maxScrollLeft = Math.max(0, scrollEl.scrollWidth - scrollEl.clientWidth)
const maxScrollTop = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight)
// 最大坐标 = 可见区域大小 + 最大滚动距离
const maxX = scrollEl.clientWidth + maxScrollLeft
const maxY = scrollEl.clientHeight + maxScrollTop
const relativeX = Math.max(0, Math.min(rawX, maxX))
const relativeY = Math.max(0, Math.min(rawY, maxY))
// 存储坐标
dragSelection.value.currentX = relativeX
dragSelection.value.currentY = relativeY
// 自动滚动检测
checkAutoScroll(event)
@@ -521,6 +557,12 @@ function handleMouseUp() {
dragSelection.value.isSelecting = false
autoScroll.value.isScrolling = false
// 标记刚完成拖拽,防止 handleContentClick 清除选择
dragSelection.value.justFinished = true
setTimeout(() => {
dragSelection.value.justFinished = false
}, 100)
// 设置焦点到最后选中的项
if (selection.selectedItems.value.size > 0) {
const lastSelected = Array.from(selection.selectedItems.value).pop()!
@@ -537,21 +579,45 @@ function checkAutoScroll(event: MouseEvent) {
if (!contentAreaRef.value) return
const rect = contentAreaRef.value.getBoundingClientRect()
const scrollEl = contentAreaRef.value
const threshold = 50
const baseScrollSpeed = 10
let dx = 0
let dy = 0
if (event.clientY < rect.top + threshold) {
dy = -5
// 检查垂直滚动
if (event.clientY < rect.top) {
dy = -baseScrollSpeed
} else if (event.clientY < rect.top + threshold) {
const distance = event.clientY - rect.top
const ratio = 1 - distance / threshold
dy = -Math.max(3, baseScrollSpeed * ratio)
} else if (event.clientY > rect.bottom) {
dy = baseScrollSpeed
} else if (event.clientY > rect.bottom - threshold) {
dy = 5
const distance = rect.bottom - event.clientY
const ratio = 1 - distance / threshold
dy = Math.max(3, baseScrollSpeed * ratio)
}
if (event.clientX < rect.left + threshold) {
dx = -5
} else if (event.clientX > rect.right - threshold) {
dx = 5
// 检查水平滚动 - 只在确实有横向滚动空间时才启用
const hasHorizontalScroll = scrollEl.scrollWidth > scrollEl.clientWidth
if (hasHorizontalScroll) {
if (event.clientX < rect.left) {
dx = -baseScrollSpeed
} else if (event.clientX < rect.left + threshold) {
const distance = event.clientX - rect.left
const ratio = 1 - distance / threshold
dx = -Math.max(3, baseScrollSpeed * ratio)
} else if (event.clientX > rect.right) {
dx = baseScrollSpeed
} else if (event.clientX > rect.right - threshold) {
const distance = rect.right - event.clientX
const ratio = 1 - distance / threshold
dx = Math.max(3, baseScrollSpeed * ratio)
}
}
if (dx !== 0 || dy !== 0) {
@@ -569,23 +635,56 @@ function checkAutoScroll(event: MouseEvent) {
// 开始自动滚动
function startAutoScroll() {
let frameId: number | null = null
function scroll() {
if (!autoScroll.value.isScrolling || !contentAreaRef.value) return
if (!autoScroll.value.isScrolling || !contentAreaRef.value) {
if (frameId !== null) {
cancelAnimationFrame(frameId)
frameId = null
}
return
}
contentAreaRef.value.scrollLeft += autoScroll.value.direction.x
contentAreaRef.value.scrollTop += autoScroll.value.direction.y
const scrollEl = contentAreaRef.value
// 更新拖拽坐标
const rect = contentAreaRef.value.getBoundingClientRect()
dragSelection.value.currentX += autoScroll.value.direction.x
dragSelection.value.currentY += autoScroll.value.direction.y
// 计算新的滚动位置,并限制在有效范围内
const maxScrollLeft = Math.max(0, scrollEl.scrollWidth - scrollEl.clientWidth)
const maxScrollTop = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight)
updateDragSelection()
let newScrollLeft = scrollEl.scrollLeft + autoScroll.value.direction.x
let newScrollTop = scrollEl.scrollTop + autoScroll.value.direction.y
requestAnimationFrame(scroll)
// 限制滚动范围
newScrollLeft = Math.max(0, Math.min(newScrollLeft, maxScrollLeft))
newScrollTop = Math.max(0, Math.min(newScrollTop, maxScrollTop))
// 计算实际滚动距离
const actualDx = newScrollLeft - scrollEl.scrollLeft
const actualDy = newScrollTop - scrollEl.scrollTop
// 应用滚动
scrollEl.scrollLeft = newScrollLeft
scrollEl.scrollTop = newScrollTop
// 更新拖拽坐标(只在实际发生滚动时更新)
if (actualDx !== 0 || actualDy !== 0) {
dragSelection.value.currentX += actualDx
dragSelection.value.currentY += actualDy
// 确保坐标不超出内容范围
const maxX = scrollEl.clientWidth + maxScrollLeft
const maxY = scrollEl.clientHeight + maxScrollTop
dragSelection.value.currentX = Math.max(0, Math.min(dragSelection.value.currentX, maxX))
dragSelection.value.currentY = Math.max(0, Math.min(dragSelection.value.currentY, maxY))
updateDragSelection()
}
frameId = requestAnimationFrame(scroll)
}
requestAnimationFrame(scroll)
frameId = requestAnimationFrame(scroll)
}
// 更新框选的项
@@ -645,6 +744,11 @@ function updateDragSelection() {
}
function handleContentClick(event: MouseEvent) {
// 如果刚完成拖拽选择,不要清除选择
if (dragSelection.value.justFinished) {
return
}
const target = event.target as HTMLElement
if (!target.closest('.file-item') && !target.closest('.list-item')) {
if (!event.ctrlKey) {
@@ -712,8 +816,14 @@ function handleContextMenuAction(action: string, params?: any) {
// Tooltip 处理
function handleItemMouseEnter(event: MouseEvent, item: FileItem) {
if (dragState.value.isDragging) return
const tooltip = `名称: ${item.name}\n类型: ${item.type === 'folder' ? '文件夹' : '文件'}\n${item.size ? '大小: ' + item.size : ''}\n${item.date ? '日期: ' + item.date : ''}`
tooltipRef.value?.show(tooltip.trim(), event.clientX, event.clientY)
const lines: string[] = []
lines.push(`类型: ${item.type === 'folder' ? '文件夹' : '文件'}`)
if (item.size) lines.push(`大小: ${item.size}`)
if (item.date) lines.push(`修改日期: ${item.date}`)
const tooltip = lines.join('\n')
tooltipRef.value?.show(tooltip, event.clientX, event.clientY)
}
function handleItemMouseLeave() {
@@ -893,22 +1003,56 @@ function getGridColumns(): number {
return 1
}
// 处理Ctrl+滚轮缩放
function handleWheel(event: WheelEvent) {
if (!event.ctrlKey) return
event.preventDefault()
const delta = event.deltaY > 0 ? -10 : 10
const newZoom = Math.max(50, Math.min(200, zoomLevel.value + delta))
zoomLevel.value = newZoom
}
// 计算动态网格大小
const gridItemSize = computed(() => {
if (props.viewMode !== 'grid') return {}
const baseSize = props.thumbnailSize === 'small' ? 80 :
props.thumbnailSize === 'medium' ? 100 : 130
const size = Math.round(baseSize * (zoomLevel.value / 100))
return {
'--grid-item-size': `${size}px`
}
})
// 监听搜索变化清除选择
watch(searchQuery, () => {
selection.clearSelection()
})
// 关闭breadcrumb dropdown
// 关闭breadcrumb dropdown 和 添加滚轮监听
onMounted(() => {
document.addEventListener('click', () => {
const closeDropdown = () => {
breadcrumbDropdown.value.visible = false
})
}
document.addEventListener('click', closeDropdown)
if (contentAreaRef.value) {
contentAreaRef.value.addEventListener('wheel', handleWheel, { passive: false })
}
})
onUnmounted(() => {
document.removeEventListener('click', () => {
breadcrumbDropdown.value.visible = false
})
if (contentAreaRef.value) {
contentAreaRef.value.removeEventListener('wheel', handleWheel)
}
})
// 键盘导航
@@ -972,6 +1116,8 @@ useKeyboardNav({
flex-direction: column;
background: white;
transition: opacity 0.15s;
height: 100%;
overflow: hidden;
}
.file-pane.inactive {
@@ -1232,6 +1378,7 @@ useKeyboardNav({
/* Content Area */
.content-area {
flex: 1;
min-height: 0;
padding: 16px;
overflow: auto;
position: relative;
@@ -1247,44 +1394,46 @@ useKeyboardNav({
/* Grid View */
.file-grid {
display: grid;
gap: 16px;
gap: 8px;
--grid-item-size: 100px; /* 默认值,会被动态覆盖 */
}
.file-grid.grid-small {
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(var(--grid-item-size, 80px), 1fr));
}
.file-grid.grid-medium {
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(var(--grid-item-size, 100px), 1fr));
}
.file-grid.grid-large {
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(var(--grid-item-size, 130px), 1fr));
}
.file-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 12px;
justify-content: center;
padding: 8px;
background: white;
border: 2px solid #e5e7eb;
border-radius: 8px;
border: 1px solid #e5e7eb;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s;
user-select: none;
aspect-ratio: 1 / 1;
position: relative;
}
.file-item:hover {
background: #f9fafb;
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
background: #f3f4f6;
border-color: #d1d5db;
}
.file-item.selected {
background: #dbeafe;
border-color: #3b82f6;
box-shadow: 0 0 0 1px #3b82f6;
}
.file-item.focused {
@@ -1305,16 +1454,23 @@ useKeyboardNav({
}
.file-icon {
font-size: 32px;
margin-bottom: 8px;
font-size: 40px;
margin-bottom: 4px;
flex-shrink: 0;
}
.file-name {
font-size: 13px;
font-size: 12px;
text-align: center;
word-break: break-word;
font-weight: 500;
color: #374151;
line-height: 1.3;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.file-name :deep(mark) {
@@ -1326,36 +1482,37 @@ useKeyboardNav({
}
.file-size {
font-size: 11px;
color: #9ca3af;
margin-top: 4px;
display: none;
}
/* List View */
.file-list {
display: flex;
flex-direction: column;
gap: 1px;
gap: 0;
}
.list-item {
display: grid;
grid-template-columns: 40px 1fr 100px 120px;
grid-template-columns: 32px 1fr 100px 140px;
align-items: center;
padding: 10px 12px;
padding: 4px 8px;
background: white;
border-bottom: 1px solid #f3f4f6;
border: 1px solid transparent;
cursor: pointer;
transition: background 0.15s;
transition: background 0.1s;
user-select: none;
min-height: 32px;
}
.list-item:hover {
background: #f9fafb;
background: #f3f4f6;
border-color: #e5e7eb;
}
.list-item.selected {
background: #dbeafe;
background: #cce8ff;
border-color: #99d1ff;
}
.list-item.drop-target {
@@ -1370,12 +1527,15 @@ useKeyboardNav({
}
.list-icon {
font-size: 20px;
font-size: 18px;
}
.list-name {
font-size: 14px;
color: #374151;
font-size: 13px;
color: #1f2937;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.list-name :deep(mark) {
@@ -1387,7 +1547,7 @@ useKeyboardNav({
}
.list-size, .list-date {
font-size: 13px;
font-size: 12px;
color: #6b7280;
}
@@ -18,7 +18,7 @@ const content = ref('')
const position = ref({ x: 0, y: 0 })
const timeout = ref<number>()
function show(text: string, x: number, y: number, delay = 500) {
function show(text: string, x: number, y: number, delay = 1000) {
clearTimeout(timeout.value)
timeout.value = window.setTimeout(() => {
@@ -42,16 +42,17 @@ defineExpose({
<style scoped>
.tooltip {
position: fixed;
background: rgba(0, 0, 0, 0.85);
color: white;
padding: 6px 10px;
border-radius: 6px;
background: white;
color: #374151;
padding: 8px 12px;
border: 1px solid #d1d5db;
border-radius: 4px;
font-size: 12px;
pointer-events: none;
z-index: 100;
white-space: nowrap;
max-width: 300px;
word-wrap: break-word;
white-space: normal;
white-space: pre-line;
max-width: 280px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
line-height: 1.5;
}
</style>
@@ -5,103 +5,126 @@ export const mockFolderStructure: FolderStructure = {
Home: {
name: 'Home',
type: 'folder',
children: {
'My Photos': {
name: 'My Photos',
type: 'folder',
children: {
'Vacation 2023': {
name: 'Vacation 2023',
type: 'folder',
children: {
Beach: {
name: 'Beach',
type: 'folder',
children: {
'photo1.jpg': { name: 'photo1.jpg', type: 'photo', size: '2.4 MB', date: '2023-07-15' },
'photo2.jpg': { name: 'photo2.jpg', type: 'photo', size: '3.1 MB', date: '2023-07-15' },
'photo3.jpg': { name: 'photo3.jpg', type: 'photo', size: '2.8 MB', date: '2023-07-16' },
'beach_sunset.jpg': { name: 'beach_sunset.jpg', type: 'photo', size: '5.2 MB', date: '2023-07-17' },
'waves.jpg': { name: 'waves.jpg', type: 'photo', size: '3.8 MB', date: '2023-07-18' }
}
},
Mountains: {
name: 'Mountains',
type: 'folder',
children: {
'sunrise.jpg': { name: 'sunrise.jpg', type: 'photo', size: '4.2 MB', date: '2023-07-20' },
'peak_view.jpg': { name: 'peak_view.jpg', type: 'photo', size: '6.1 MB', date: '2023-07-21' }
children: (() => {
const homeItems: Record<string, any> = {
'My Photos': {
name: 'My Photos',
type: 'folder',
children: {
'Vacation 2023': {
name: 'Vacation 2023',
type: 'folder',
children: {
Beach: {
name: 'Beach',
type: 'folder',
children: {
'photo1.jpg': { name: 'photo1.jpg', type: 'photo', size: '2.4 MB', date: '2023-07-15' },
'photo2.jpg': { name: 'photo2.jpg', type: 'photo', size: '3.1 MB', date: '2023-07-15' },
'photo3.jpg': { name: 'photo3.jpg', type: 'photo', size: '2.8 MB', date: '2023-07-16' },
'beach_sunset.jpg': { name: 'beach_sunset.jpg', type: 'photo', size: '5.2 MB', date: '2023-07-17' },
'waves.jpg': { name: 'waves.jpg', type: 'photo', size: '3.8 MB', date: '2023-07-18' }
}
},
Mountains: {
name: 'Mountains',
type: 'folder',
children: {
'sunrise.jpg': { name: 'sunrise.jpg', type: 'photo', size: '4.2 MB', date: '2023-07-20' },
'peak_view.jpg': { name: 'peak_view.jpg', type: 'photo', size: '6.1 MB', date: '2023-07-21' }
}
}
}
}
},
Family: {
name: 'Family',
type: 'folder',
children: {
'dinner.jpg': { name: 'dinner.jpg', type: 'photo', size: '2.2 MB', date: '2023-08-15' },
'family_portrait.jpg': { name: 'family_portrait.jpg', type: 'photo', size: '4.1 MB', date: '2023-08-20' }
}
}
}
},
'Camera Roll': {
name: 'Camera Roll',
type: 'folder',
children: (() => {
const items: Record<string, any> = {
Recent: {
name: 'Recent',
type: 'folder',
children: {}
},
Favorites: {
name: 'Favorites',
Family: {
name: 'Family',
type: 'folder',
children: {}
children: {
'dinner.jpg': { name: 'dinner.jpg', type: 'photo', size: '2.2 MB', date: '2023-08-15' },
'family_portrait.jpg': { name: 'family_portrait.jpg', type: 'photo', size: '4.1 MB', date: '2023-08-20' }
}
}
}
// 生成100张照片
for (let i = 1; i <= 100; i++) {
const size = (Math.random() * 3 + 1).toFixed(1)
const day = Math.floor(Math.random() * 30) + 1
items[`IMG_${String(i).padStart(4, '0')}.jpg`] = {
name: `IMG_${String(i).padStart(4, '0')}.jpg`,
type: 'photo',
size: `${size} MB`,
date: `2023-09-${String(day).padStart(2, '0')}`
},
'Camera Roll': {
name: 'Camera Roll',
type: 'folder',
children: (() => {
const items: Record<string, any> = {
Recent: {
name: 'Recent',
type: 'folder',
children: {}
},
Favorites: {
name: 'Favorites',
type: 'folder',
children: {}
}
}
}
// Recent文件夹添加照片
for (let i = 1; i <= 30; i++) {
const size = (Math.random() * 3 + 1).toFixed(1)
items.Recent.children[`Recent_${String(i).padStart(3, '0')}.jpg`] = {
name: `Recent_${String(i).padStart(3, '0')}.jpg`,
type: 'photo',
size: `${size} MB`,
date: `2023-12-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`
// 生成100张照片
for (let i = 1; i <= 100; i++) {
const size = (Math.random() * 3 + 1).toFixed(1)
const day = Math.floor(Math.random() * 30) + 1
items[`IMG_${String(i).padStart(4, '0')}.jpg`] = {
name: `IMG_${String(i).padStart(4, '0')}.jpg`,
type: 'photo',
size: `${size} MB`,
date: `2023-09-${String(day).padStart(2, '0')}`
}
}
}
return items
})()
},
'Work Projects': {
name: 'Work Projects',
type: 'folder',
children: {
Screenshots: {
name: 'Screenshots',
type: 'folder',
children: {
'design1.png': { name: 'design1.png', type: 'photo', size: '1.2 MB', date: '2023-09-01' },
'design2.png': { name: 'design2.png', type: 'photo', size: '1.5 MB', date: '2023-09-02' }
// Recent文件夹添加照片
for (let i = 1; i <= 30; i++) {
const size = (Math.random() * 3 + 1).toFixed(1)
items.Recent.children[`Recent_${String(i).padStart(3, '0')}.jpg`] = {
name: `Recent_${String(i).padStart(3, '0')}.jpg`,
type: 'photo',
size: `${size} MB`,
date: `2023-12-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`
}
}
return items
})()
},
'Work Projects': {
name: 'Work Projects',
type: 'folder',
children: {
Screenshots: {
name: 'Screenshots',
type: 'folder',
children: {
'design1.png': { name: 'design1.png', type: 'photo', size: '1.2 MB', date: '2023-09-01' },
'design2.png': { name: 'design2.png', type: 'photo', size: '1.5 MB', date: '2023-09-02' }
}
}
}
}
}
}
// 在Home文件夹添加更多文件夹和文件,确保有足够内容触发滚动
for (let i = 1; i <= 50; i++) {
homeItems[`Folder_${String(i).padStart(2, '0')}`] = {
name: `Folder_${String(i).padStart(2, '0')}`,
type: 'folder',
children: {}
}
}
for (let i = 1; i <= 50; i++) {
const size = (Math.random() * 5 + 1).toFixed(1)
homeItems[`File_${String(i).padStart(2, '0')}.jpg`] = {
name: `File_${String(i).padStart(2, '0')}.jpg`,
type: 'photo',
size: `${size} MB`,
date: `2024-01-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`
}
}
return homeItems
})()
}
}
@@ -298,15 +298,13 @@ const handleMenuSelect = (key: string) => {
.layout-content {
height: 100%;
overflow: auto;
overflow: hidden;
flex: 1;
background-color: var(--content-bg);
}
.content-wrapper {
padding: 24px;
height: 100%;
min-height: calc(100vh - 64px);
box-sizing: border-box;
}
@@ -11,7 +11,7 @@ import FileManager from '@/components/FileManager/FileManager.vue'
<style scoped>
.field-view {
width: 100%;
height: 100vh;
height: 100%;
overflow: hidden;
}
</style>