diff --git a/frontend/app.html b/frontend/app.html index f25726c..26d2e99 100644 --- a/frontend/app.html +++ b/frontend/app.html @@ -1802,7 +1802,7 @@ - - + -
+
@@ -1909,19 +1909,22 @@
-
+
+
- -
@@ -1932,14 +1935,15 @@
+ aria-label="搜索文件或文件夹" + placeholder="搜索文件或文件夹">
- @@ -2114,6 +2118,7 @@ @touchstart.stop @touchmove.stop @touchend.stop + aria-label="更多操作" title="更多操作"> @@ -4474,9 +4479,30 @@ 删除
+ + + diff --git a/frontend/app.js b/frontend/app.js index 573b666..88e4cd8 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -12,6 +12,19 @@ createApp({ return (saved && ['overview', 'settings', 'monitor', 'users'].includes(saved)) ? saved : 'overview'; })(); + const initialFileViewMode = (() => { + try { + const saved = localStorage.getItem('fileViewMode'); + if (saved && ['grid', 'list'].includes(saved)) { + return saved; + } + } catch (error) { + console.warn('[视图] 无法读取文件视图偏好:', error); + } + + return window.matchMedia('(max-width: 768px)').matches ? 'list' : 'grid'; + })(); + return { // API配置 // API配置 - 通过nginx代理访问 @@ -29,7 +42,7 @@ createApp({ // 视图状态 currentView: 'files', isLogin: true, - fileViewMode: 'grid', // 文件显示模式: grid 大图标, list 列表 + fileViewMode: initialFileViewMode, // 移动端默认列表视图,并记住用户选择 shareViewMode: 'list', // 分享显示模式: grid 大图标, list 列表 shareResourceTab: 'shares', // 分享中心资源标签: shares / directLinks settingsTab: 'storage', // 设置中心标签: storage / appearance / security @@ -349,6 +362,7 @@ createApp({ contextMenuX: 0, contextMenuY: 0, contextMenuFile: null, + showMobileCreateSheet: false, showMobileFileActionSheet: false, mobileActionFile: null, @@ -2245,6 +2259,46 @@ handleDragLeave(e) { document.body.style.overflow = locked ? 'hidden' : ''; }, + setFileViewMode(mode) { + if (!['grid', 'list'].includes(mode)) return; + this.fileViewMode = mode; + + try { + localStorage.setItem('fileViewMode', mode); + } catch (error) { + console.warn('[视图] 无法保存文件视图偏好:', error); + } + }, + + openMobileCreateSheet(event) { + if (event) { + event.preventDefault(); + event.stopPropagation(); + } + + this.closeMobileFileActionSheet(); + this.showMobileCreateSheet = true; + this.setMobileSheetScrollLock(true); + }, + + closeMobileCreateSheet() { + this.showMobileCreateSheet = false; + this.setMobileSheetScrollLock(false); + }, + + mobileCreateAction(action) { + this.closeMobileCreateSheet(); + + if (action === 'upload') { + this.$nextTick(() => this.$refs.fileUploadInput?.click()); + return; + } + + if (action === 'folder') { + this.showCreateFolderModal = true; + } + }, + openMobileFileActionSheet(file, event) { if (event) { event.preventDefault(); @@ -5176,11 +5230,12 @@ handleDragLeave(e) { this.isDragging = false; }); - // 添加 ESC 键监听(按 ESC 关闭拖拽覆盖层) + // 添加 ESC 键监听(按 ESC 关闭当前浮层) window.addEventListener("keydown", (e) => { - if (e.key === "Escape" && this.isDragging) { - this.isDragging = false; - } + if (e.key !== "Escape") return; + if (this.isDragging) this.isDragging = false; + if (this.showMobileCreateSheet) this.closeMobileCreateSheet(); + if (this.showMobileFileActionSheet) this.closeMobileFileActionSheet(); }); // 设置axios响应拦截器,处理401错误(token过期/失效) diff --git a/frontend/workspace.css b/frontend/workspace.css index fa4cf4c..4bc9e92 100644 --- a/frontend/workspace.css +++ b/frontend/workspace.css @@ -2692,3 +2692,708 @@ body.enterprise-netdisk .settings-account-panel { display: none; } } + +/* Mobile file workspace: bottom navigation and a single-layer command surface. */ +body.enterprise-netdisk .mobile-file-create-trigger { + display: none; +} + +@keyframes ww-mobile-sheet-enter { + from { + opacity: 0; + transform: translateY(18px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@media (max-width: 768px) { + body.enterprise-netdisk { + min-width: 0; + min-height: 100vh; + min-height: 100dvh; + overflow-x: hidden; + background: #fff; + } + + body.enterprise-netdisk #app { + min-height: 100vh; + min-height: 100dvh; + } + + body.enterprise-netdisk .navbar { + position: fixed !important; + inset: auto 0 0 !important; + z-index: 80; + width: 100% !important; + height: calc(66px + env(safe-area-inset-bottom)); + min-height: calc(66px + env(safe-area-inset-bottom)); + padding: 5px 8px calc(5px + env(safe-area-inset-bottom)); + display: flex; + flex-direction: row; + align-items: center; + gap: 0; + border: 0 !important; + border-top: 1px solid rgba(214, 222, 235, 0.92) !important; + background: rgba(255, 255, 255, 0.97) !important; + box-shadow: 0 -8px 28px rgba(28, 46, 75, 0.09); + backdrop-filter: blur(18px) !important; + } + + body.enterprise-netdisk .navbar-brand, + body.enterprise-netdisk .nav-section-label, + body.enterprise-netdisk .navbar-download-btn, + body.enterprise-netdisk .user-info { + display: none !important; + } + + body.enterprise-netdisk .navbar-menu { + width: 100%; + min-width: 0; + height: 56px; + flex: 1; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-around; + gap: 4px; + overflow: visible; + } + + body.enterprise-netdisk .navbar-account { + min-width: 0; + flex: 1 1 0; + margin: 0; + padding: 0; + display: flex; + border: 0; + } + + body.enterprise-netdisk .nav-item, + body.enterprise-netdisk .navbar-logout-btn { + width: auto; + min-width: 0; + min-height: 52px; + flex: 1 1 0; + padding: 5px 4px 4px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 3px; + border: 0; + border-radius: 12px; + color: #718099; + background: transparent; + box-shadow: none; + font-size: 10px; + font-weight: 700; + line-height: 1.15; + transform: none; + } + + body.enterprise-netdisk .nav-item i, + body.enterprise-netdisk .navbar-logout-btn i { + width: auto; + color: #718099; + font-size: 18px; + line-height: 1; + } + + body.enterprise-netdisk .nav-item-label { + display: block; + font-size: 10px; + line-height: 1.15; + } + + body.enterprise-netdisk .nav-item.active { + color: var(--ww-blue); + background: var(--ww-blue-soft); + box-shadow: none; + } + + body.enterprise-netdisk .nav-item.active i { + color: var(--ww-blue); + } + + body.enterprise-netdisk .nav-item:hover, + body.enterprise-netdisk .navbar-logout-btn:hover { + color: #718099; + background: #f5f7fa; + transform: none; + } + + body.enterprise-netdisk .navbar-logout-btn, + body.enterprise-netdisk .navbar-logout-btn:hover { + width: 100%; + margin: 0; + color: #9a6570; + border-color: transparent; + } + + body.enterprise-netdisk .navbar-logout-btn i, + body.enterprise-netdisk .navbar-logout-btn:hover i { + color: #9a6570; + } + + body.enterprise-netdisk .main-container { + margin-left: 0 !important; + padding-bottom: calc(82px + env(safe-area-inset-bottom)); + } + + body.enterprise-netdisk .files-main-container { + padding: 0 0 calc(66px + env(safe-area-inset-bottom)); + } + + body.enterprise-netdisk .files-view-card { + height: auto; + min-height: calc(100vh - 66px); + min-height: calc(100dvh - 66px - env(safe-area-inset-bottom)); + border: 0; + border-radius: 0; + box-shadow: none; + } + + body.enterprise-netdisk .files-page-header { + padding: 16px 16px 14px; + display: flex; + flex-direction: column; + align-items: stretch; + gap: 11px; + border-bottom: 1px solid #edf1f6; + background: + radial-gradient(circle at 100% 0%, rgba(40, 120, 255, 0.08), transparent 14rem), + #fff; + } + + body.enterprise-netdisk .files-page-header .workspace-kicker, + body.enterprise-netdisk .files-page-header .workspace-page-heading p { + display: none; + } + + body.enterprise-netdisk .files-page-header .workspace-page-heading h1 { + margin: 0; + font-size: 24px; + line-height: 1.2; + letter-spacing: -0.02em; + } + + body.enterprise-netdisk .storage-meter-card { + width: 100%; + min-width: 0; + padding: 10px 12px 9px; + border-color: #e1e9f5; + border-radius: 12px; + background: rgba(247, 250, 255, 0.94); + } + + body.enterprise-netdisk .storage-meter-head { + gap: 9px; + } + + body.enterprise-netdisk .storage-meter-head strong { + min-width: 0; + flex: 1; + font-size: 11px; + text-align: right; + } + + body.enterprise-netdisk .files-storage-badge { + width: auto; + max-width: 58%; + flex: 0 0 auto; + padding: 3px 7px; + justify-content: flex-start; + font-size: 10px; + } + + body.enterprise-netdisk .storage-meter-track { + height: 4px; + margin: 7px 0 5px; + } + + body.enterprise-netdisk .storage-meter-foot { + font-size: 9px; + } + + body.enterprise-netdisk .breadcrumb-bar { + min-height: 40px; + margin: 10px 14px 0; + padding: 4px 6px; + gap: 5px; + overflow-x: auto; + border-radius: 10px; + white-space: nowrap; + scrollbar-width: none; + } + + body.enterprise-netdisk .breadcrumb-bar::-webkit-scrollbar { + display: none; + } + + body.enterprise-netdisk .breadcrumb-up { + position: sticky; + right: 0; + min-width: 34px; + background: var(--ww-surface-soft); + } + + body.enterprise-netdisk .files-content-shell { + min-height: 0; + padding: 12px 14px 18px; + display: flex; + flex-direction: column; + } + + body.enterprise-netdisk .files-command-bar { + min-height: 44px; + display: flex; + flex-direction: row; + align-items: center; + gap: 9px; + } + + body.enterprise-netdisk .files-command-primary-desktop { + display: none; + } + + body.enterprise-netdisk .mobile-file-create-trigger { + min-width: 0; + min-height: 44px; + flex: 1; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + border-radius: 11px; + font-size: 14px; + font-weight: 750; + box-shadow: 0 8px 18px rgba(40, 120, 255, 0.2); + } + + body.enterprise-netdisk .files-view-toggle { + width: auto; + flex: 0 0 auto; + display: flex; + grid-template-columns: none; + gap: 2px; + padding: 3px; + border-radius: 11px; + } + + body.enterprise-netdisk .files-view-toggle .btn { + width: 38px; + min-width: 38px; + min-height: 36px; + padding: 0; + display: grid; + place-items: center; + border-radius: 8px; + } + + body.enterprise-netdisk .files-view-toggle .btn span { + display: none; + } + + body.enterprise-netdisk .files-view-toggle .btn i { + margin: 0; + font-size: 14px; + } + + body.enterprise-netdisk .files-search-wrap { + margin-top: 10px; + } + + body.enterprise-netdisk .files-search-row { + padding: 0; + display: grid; + grid-template-columns: minmax(0, 1fr) 86px; + gap: 8px; + border: 0; + border-radius: 0; + background: transparent; + } + + body.enterprise-netdisk .files-search-field { + min-width: 0; + min-height: 44px; + grid-column: auto; + padding: 0 12px; + gap: 9px; + border-color: #dce4ef; + border-radius: 11px; + background: #f7f9fc; + } + + body.enterprise-netdisk .files-search-field .form-input { + min-height: 40px; + font-size: 13px; + } + + body.enterprise-netdisk .files-search-field > i { + font-size: 13px; + } + + body.enterprise-netdisk .files-search-type { + width: 86px; + min-height: 44px; + padding: 0 9px; + border-color: #dce4ef; + border-radius: 11px; + background-color: #f7f9fc; + font-size: 12px; + } + + body.enterprise-netdisk .files-search-button, + body.enterprise-netdisk .files-search-clear { + display: none; + } + + body.enterprise-netdisk .files-search-results { + inset: calc(100% + 7px) 0 auto; + max-height: min(52vh, 360px); + border-radius: 12px; + } + + body.enterprise-netdisk .files-search-result { + min-height: 56px; + padding: 10px 12px; + } + + body.enterprise-netdisk .files-list-heading { + min-height: 44px; + padding: 0 2px; + } + + body.enterprise-netdisk .files-list-heading > div { + gap: 8px; + } + + body.enterprise-netdisk .files-list-heading strong { + font-size: 15px; + } + + body.enterprise-netdisk .files-list-hint, + body.enterprise-netdisk .files-drop-hint { + display: none; + } + + body.enterprise-netdisk .files-container { + min-height: calc(100vh - 322px); + min-height: calc(100dvh - 322px - env(safe-area-inset-bottom)); + flex: 1; + padding: 0; + overflow: visible; + border: 0; + border-radius: 0; + background: #fff; + } + + body.enterprise-netdisk .files-content-shell .file-list { + overflow: visible; + border-radius: 0; + } + + body.enterprise-netdisk .file-list-table thead { + display: none; + } + + body.enterprise-netdisk .file-list-table td { + height: 66px; + padding: 8px 2px !important; + border-bottom-color: #edf1f6; + } + + body.enterprise-netdisk .file-list-row:last-child td { + border-bottom: 1px solid #edf1f6; + } + + body.enterprise-netdisk .file-list-row:active { + background: #f3f7fd; + } + + body.enterprise-netdisk .file-col-size, + body.enterprise-netdisk .file-col-time, + body.enterprise-netdisk .file-list-size-cell, + body.enterprise-netdisk .file-list-time-cell { + display: none; + } + + body.enterprise-netdisk .file-list-name-cell { + width: auto; + max-width: 0; + } + + body.enterprise-netdisk .file-list-name-wrap { + gap: 11px; + } + + body.enterprise-netdisk .file-list-name-info { + gap: 3px; + } + + body.enterprise-netdisk .file-list-name-text { + font-size: 14px; + font-weight: 700; + } + + body.enterprise-netdisk .file-list-name-meta { + display: block; + font-size: 10px; + } + + body.enterprise-netdisk .file-list-thumb, + body.enterprise-netdisk .file-list-video-icon { + width: 40px; + height: 40px; + border-radius: 9px; + } + + body.enterprise-netdisk .file-list-type-icon { + min-width: 40px; + font-size: 27px; + } + + body.enterprise-netdisk .file-list-action-col { + width: 48px; + padding-left: 4px !important; + } + + body.enterprise-netdisk .file-row-mobile-more { + width: 42px; + min-width: 42px; + min-height: 42px; + border-radius: 11px; + } + + body.enterprise-netdisk .files-content-shell .file-grid { + min-height: 0; + padding: 2px 0 10px; + grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-auto-rows: auto; + gap: 8px; + } + + body.enterprise-netdisk .files-content-shell .file-grid-item { + width: auto; + min-height: 124px; + padding: 12px 8px 10px; + justify-content: center; + border: 1px solid #e7edf5; + border-radius: 12px; + background: #fbfcfe; + } + + body.enterprise-netdisk .file-icon { + min-height: 56px; + margin-bottom: 4px; + } + + body.enterprise-netdisk .file-grid-type-icon { + font-size: 45px; + } + + body.enterprise-netdisk .file-thumbnail, + body.enterprise-netdisk .file-grid-video-icon { + width: 58px; + height: 54px; + } + + body.enterprise-netdisk .files-content-shell .file-name { + font-size: 12px; + } + + body.enterprise-netdisk .files-content-shell .file-size { + margin-top: 1px; + font-size: 10px; + } + + body.enterprise-netdisk .files-empty-state, + body.enterprise-netdisk .files-content-shell .empty-hint { + min-height: 260px; + padding: 42px 12px; + } + + body.enterprise-netdisk .files-empty-state > i { + font-size: 34px; + } + + body.enterprise-netdisk .files-empty-actions { + width: 100%; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + body.enterprise-netdisk .files-empty-actions .btn { + min-width: 0; + } + + body.enterprise-netdisk .mobile-file-sheet-overlay { + z-index: 1100; + padding: 0; + align-items: flex-end; + background: rgba(18, 31, 50, 0.38); + backdrop-filter: blur(2px); + } + + body.enterprise-netdisk .mobile-file-sheet { + width: 100%; + max-width: 560px; + max-height: 82vh; + padding: 8px 14px calc(14px + env(safe-area-inset-bottom)); + overflow-y: auto; + border: 0; + border-radius: 20px 20px 0 0; + color: var(--ww-ink); + background: #fff; + box-shadow: 0 -18px 50px rgba(21, 38, 65, 0.18); + animation: ww-mobile-sheet-enter 180ms ease-out both; + } + + body.enterprise-netdisk .mobile-file-sheet-handle { + width: 38px; + height: 4px; + margin: 2px auto 10px; + background: #d7deea; + } + + body.enterprise-netdisk .mobile-file-sheet-title { + margin-bottom: 10px; + color: var(--ww-ink); + font-size: 15px; + font-weight: 750; + } + + body.enterprise-netdisk .mobile-file-sheet-actions { + gap: 7px; + } + + body.enterprise-netdisk .mobile-file-sheet-btn { + min-height: 48px; + border-color: var(--ww-line); + color: var(--ww-text); + background: var(--ww-surface-soft); + } + + body.enterprise-netdisk .mobile-file-sheet-btn.cancel { + margin-top: 4px; + color: var(--ww-text); + background: #fff; + } + + body.enterprise-netdisk .mobile-create-sheet-title { + margin-bottom: 5px; + text-align: left; + } + + body.enterprise-netdisk .mobile-create-sheet-actions { + display: grid; + gap: 4px; + } + + body.enterprise-netdisk .mobile-create-option { + width: 100%; + min-height: 70px; + padding: 9px 4px; + display: flex; + align-items: center; + gap: 12px; + border: 0; + border-bottom: 1px solid #edf1f6; + color: var(--ww-ink); + text-align: left; + background: transparent; + } + + body.enterprise-netdisk .mobile-create-option:active { + background: #f4f8ff; + } + + body.enterprise-netdisk .mobile-create-option-icon { + width: 42px; + height: 42px; + flex: 0 0 42px; + display: grid; + place-items: center; + border-radius: 12px; + font-size: 17px; + } + + body.enterprise-netdisk .mobile-create-option-icon.upload { + color: #1763e6; + background: #eaf2ff; + } + + body.enterprise-netdisk .mobile-create-option-icon.folder { + color: #aa6d05; + background: #fff4da; + } + + body.enterprise-netdisk .mobile-create-option-copy { + min-width: 0; + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; + } + + body.enterprise-netdisk .mobile-create-option-copy strong { + font-size: 14px; + } + + body.enterprise-netdisk .mobile-create-option-copy small { + overflow: hidden; + color: var(--ww-muted); + font-size: 11px; + text-overflow: ellipsis; + white-space: nowrap; + } + + body.enterprise-netdisk .mobile-create-option-arrow { + color: #a5b0c1; + font-size: 11px; + } + + body.enterprise-netdisk .mobile-create-cancel { + width: 100%; + min-height: 46px; + margin-top: 10px; + border: 0; + border-radius: 11px; + font-weight: 700; + } + + body.enterprise-netdisk .upload-progress-panel { + right: 12px; + bottom: calc(78px + env(safe-area-inset-bottom)); + width: calc(100vw - 24px); + max-width: 360px; + } +} + +@media (max-width: 380px) { + body.enterprise-netdisk .files-page-header { + padding-inline: 13px; + } + + body.enterprise-netdisk .files-content-shell { + padding-inline: 11px; + } + + body.enterprise-netdisk .files-search-row { + grid-template-columns: minmax(0, 1fr) 78px; + gap: 6px; + } + + body.enterprise-netdisk .files-search-type { + width: 78px; + padding-inline: 6px; + } + + body.enterprise-netdisk .nav-item, + body.enterprise-netdisk .navbar-logout-btn { + padding-inline: 2px; + } +}