diff --git a/src/main/java/com/sftp/manager/config/WebConfig.java b/src/main/java/com/sftp/manager/config/WebConfig.java
index 1503732..ef92f23 100644
--- a/src/main/java/com/sftp/manager/config/WebConfig.java
+++ b/src/main/java/com/sftp/manager/config/WebConfig.java
@@ -3,6 +3,7 @@ package com.sftp.manager.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@@ -23,4 +24,10 @@ public class WebConfig implements WebMvcConfigurer {
// registry.addResourceHandler("/**")
// .addResourceLocations("classpath:/static/");
}
+
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ // 访问根路径时转发到静态首页 /static/index.html
+ registry.addViewController("/").setViewName("forward:/index.html");
+ }
}
diff --git a/src/main/resources/static/css/style.css b/src/main/resources/static/css/style.css
index ac16ec0..fd232d1 100644
--- a/src/main/resources/static/css/style.css
+++ b/src/main/resources/static/css/style.css
@@ -6,11 +6,32 @@
box-sizing: border-box;
}
+:root {
+ /* 设计令牌(简化版) */
+ --color-primary: #0d6efd;
+ --color-success: #198754;
+ --color-warning: #ffc107;
+ --color-danger: #dc3545;
+ --color-dark: #0f172a;
+ --color-gray-700: #334155;
+ --color-gray-600: #6b7280;
+ --color-gray-200: #e5e7eb;
+ --color-gray-100: #f3f4f6;
+
+ --radius-sm: 4px;
+ --radius-md: 12px;
+ --shadow-card: 0 22px 55px rgba(15, 23, 42, 0.18);
+}
+
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
font-size: 14px;
line-height: 1.5;
- background-color: #f5f5f5;
+ color: var(--color-dark);
+ background:
+ radial-gradient(circle at top left, #e0f2fe 0, transparent 55%),
+ radial-gradient(circle at bottom right, #e9d5ff 0, transparent 55%),
+ #f3f4f6;
overflow: hidden;
}
@@ -18,8 +39,13 @@ body {
.app-container {
display: flex;
flex-direction: column;
- height: 100vh;
- background-color: #fff;
+ height: calc(100vh - 32px);
+ max-width: 1220px;
+ margin: 16px auto;
+ background-color: #ffffff;
+ border-radius: var(--radius-md);
+ box-shadow: var(--shadow-card);
+ overflow: hidden;
}
/* 导航栏 */
@@ -42,6 +68,8 @@ body {
align-items: center;
gap: 8px;
min-height: 44px;
+ background-color: #f9fafb;
+ border-bottom: 1px solid #e5e7eb;
}
/* 传输进度(上传/下载/跨面板传输) */
@@ -89,6 +117,7 @@ body {
flex-direction: column;
border-right: 1px solid #dee2e6;
overflow: hidden;
+ background-color: #ffffff;
min-width: 0;
}
@@ -96,6 +125,11 @@ body {
border-right: none;
}
+/* 当前活动面板高亮 */
+.panel.active-panel {
+ box-shadow: inset 0 0 0 1px rgba(37, 99, 235, 0.4);
+}
+
/* 拖拽上传效果 */
.panel.drag-over {
background-color: #e7f3ff;
@@ -233,14 +267,45 @@ body {
color: white;
}
+.file-item.selected .file-name {
+ color: #ffffff;
+}
+
.file-icon {
margin-right: 10px;
- width: 24px;
+ width: 40px;
text-align: center;
font-size: 16px;
flex-shrink: 0;
}
+/* 文件类型徽标(替代 emoji 图标) */
+.file-type {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 34px;
+ padding: 2px 8px;
+ border-radius: 999px;
+ background-color: rgba(15, 23, 42, 0.06);
+ color: #0f172a;
+ font-size: 11px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+}
+
+.file-type-dir {
+ background-color: rgba(37, 99, 235, 0.15);
+ color: #1d4ed8;
+}
+
+.file-item.selected .file-type,
+.file-item.selected .file-type-dir {
+ background-color: rgba(15, 23, 42, 0.32);
+ color: #ffffff;
+}
+
.file-name {
flex: 1;
white-space: nowrap;
@@ -278,6 +343,8 @@ body {
padding: 4px 16px;
font-size: 12px;
color: #666;
+ background-color: #f9fafb;
+ border-top: 1px solid #e5e7eb;
}
/* 上下文菜单 */
@@ -346,6 +413,57 @@ body {
font-size: 14px;
}
+/* 页面头部信息区域 */
+.app-header {
+ padding: 12px 20px 4px;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 12px;
+ background: linear-gradient(120deg, rgba(37, 99, 235, 0.07), rgba(56, 189, 248, 0.04));
+ border-bottom: 1px solid rgba(148, 163, 184, 0.35);
+}
+
+.app-header-main {
+ max-width: 70%;
+}
+
+.app-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #0f172a;
+ margin-bottom: 4px;
+}
+
+.app-subtitle {
+ font-size: 13px;
+ color: #6b7280;
+ margin-bottom: 0;
+}
+
+.app-header-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+ justify-content: flex-end;
+}
+
+.header-tag {
+ padding: 3px 10px;
+ border-radius: 999px;
+ font-size: 11px;
+ color: #1e40af;
+ background-color: rgba(59, 130, 246, 0.08);
+ border: 1px solid rgba(59, 130, 246, 0.18);
+ white-space: nowrap;
+}
+
+/* 全局聚焦可见样式(键盘导航) */
+*:focus-visible {
+ outline: 2px solid var(--color-primary);
+ outline-offset: 2px;
+}
+
/* 响应式设计 */
@media (max-width: 768px) {
.panels-container {
@@ -382,3 +500,200 @@ body {
padding: 6px 8px;
}
}
+
+/* ============================
+ ui-ux-pro-max 主题覆盖样式
+ ============================ */
+
+/* 设计令牌(Minimal + Gold) */
+:root {
+ --color-primary: #171717;
+ --color-secondary: #404040;
+ --color-cta: #D4AF37;
+
+ --color-text: #171717;
+ --color-bg: #ffffff;
+
+ --radius-sm: 4px;
+ --radius-md: 14px;
+ --shadow-card: 0 24px 60px rgba(15, 23, 42, 0.18);
+
+ --transition-base: 150ms ease;
+}
+
+body {
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ color: var(--color-text, #171717);
+ background-color: var(--color-bg, #ffffff);
+ background-image:
+ radial-gradient(circle at top left, rgba(23, 23, 23, 0.04) 0, transparent 55%),
+ radial-gradient(circle at bottom right, rgba(64, 64, 64, 0.04) 0, transparent 55%);
+ -webkit-font-smoothing: antialiased;
+}
+
+.app-container {
+ border-radius: var(--radius-md);
+ box-shadow: var(--shadow-card);
+ border: 1px solid rgba(15, 23, 42, 0.06);
+}
+
+.navbar {
+ background-color: #171717 !important;
+ border-bottom: 1px solid #27272a;
+}
+
+.navbar-brand {
+ letter-spacing: 0.02em;
+}
+
+.navbar .btn-primary.btn-sm {
+ background-color: var(--color-cta, #D4AF37);
+ border-color: var(--color-cta, #D4AF37);
+ color: #171717;
+ font-weight: 500;
+ padding-inline: 14px;
+ border-radius: 999px;
+ transition: background-color var(--transition-base), border-color var(--transition-base), transform var(--transition-base), box-shadow var(--transition-base);
+}
+
+.navbar .btn-primary.btn-sm:hover {
+ background-color: #b48b1f;
+ border-color: #b48b1f;
+ transform: translateY(-1px);
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
+}
+
+.navbar .btn-primary.btn-sm:active {
+ transform: translateY(0);
+ box-shadow: none;
+}
+
+.toolbar {
+ background-color: #f9fafb;
+ border-bottom: 1px solid #e5e7eb;
+}
+
+.toolbar .btn-group {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+
+.toolbar .btn {
+ border-radius: 999px;
+ padding: 4px 14px;
+ font-size: 13px;
+ font-weight: 500;
+ border-width: 1px;
+ border-style: solid;
+ border-color: rgba(148, 163, 184, 0.55);
+ background-color: #ffffff;
+ color: var(--color-secondary, #404040);
+ transition: background-color var(--transition-base), color var(--transition-base), border-color var(--transition-base), box-shadow var(--transition-base), transform var(--transition-base);
+}
+
+.toolbar .btn-outline-primary {
+ border-color: rgba(148, 163, 184, 0.7);
+}
+
+.toolbar .btn-outline-primary:hover {
+ background-color: var(--color-primary);
+ color: #ffffff;
+ border-color: var(--color-primary);
+ box-shadow: 0 8px 20px rgba(15, 23, 42, 0.18);
+}
+
+.toolbar .btn-outline-secondary {
+ border-color: rgba(148, 163, 184, 0.55);
+ color: var(--color-secondary);
+ background-color: #f9fafb;
+}
+
+.toolbar .btn-outline-secondary:hover {
+ background-color: #e5e7eb;
+ border-color: #9ca3af;
+}
+
+.toolbar .btn-outline-danger {
+ border-color: rgba(220, 38, 38, 0.35);
+ color: #b91c1c;
+ background-color: #fef2f2;
+}
+
+.toolbar .btn-outline-danger:hover {
+ background-color: #dc2626;
+ border-color: #b91c1c;
+ color: #ffffff;
+}
+
+.toolbar .btn:active {
+ transform: scale(0.97);
+ box-shadow: none;
+}
+
+.panel {
+ border-right: 1px solid #e5e7eb;
+}
+
+.panel.active-panel {
+ box-shadow: inset 0 0 0 1px rgba(212, 175, 55, 0.65);
+}
+
+.panel-header {
+ background-color: #f3f4f6;
+ border-bottom: 1px solid #e5e7eb;
+}
+
+.path-bar {
+ background-color: #ffffff;
+ border-bottom: 1px solid #e5e7eb;
+}
+
+.file-item {
+ transition: background-color var(--transition-base), color var(--transition-base);
+}
+
+.app-header {
+ background: linear-gradient(120deg, rgba(23, 23, 23, 0.03), rgba(64, 64, 64, 0.02));
+}
+
+.app-title {
+ font-size: 20px;
+}
+
+.header-tag {
+ color: #404040;
+ background-color: #f4f4f5;
+ border: 1px solid #e4e4e7;
+}
+
+/* 主按钮:统一金色 CTA 风格 */
+.btn-primary {
+ background-color: var(--color-cta, #D4AF37);
+ border-color: var(--color-cta, #D4AF37);
+ color: #171717;
+ font-weight: 500;
+ transition: background-color var(--transition-base), border-color var(--transition-base), box-shadow var(--transition-base), transform var(--transition-base);
+}
+
+.btn-primary:hover {
+ background-color: #b48b1f;
+ border-color: #b48b1f;
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
+ transform: translateY(-1px);
+}
+
+.btn-primary:active {
+ transform: translateY(0);
+ box-shadow: none;
+}
+
+/* 尊重用户的「减少动态效果」系统设置 */
+@media (prefers-reduced-motion: reduce) {
+ * {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index 71354b7..facef69 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -19,6 +19,19 @@
+
+ 双面板本地 / SFTP 文件管理器,支持拖拽、键盘快捷键与批量操作。文件工作台
+