From 5053d396f86e63c546314c001eb8886976642eeb Mon Sep 17 00:00:00 2001 From: gaoxq <376340421@qq.com> Date: Thu, 2 Apr 2026 12:52:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=91=E6=96=87=E4=BB=B6=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=B8=8A=E4=BC=A0=E7=BB=84=E4=BB=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/filesystem/config/SecurityConfig.java | 7 ++++++ .../java/com/filesystem/config/WebConfig.java | 15 +++++++++++++ .../controller/IndexController.java | 19 ++++++++++++++++ .../security/JwtAuthenticationFilter.java | 10 ++++++++- web-vue/src/views/files/index.vue | 22 ++++++++++++------- web-vue/vite.config.js | 9 ++++++++ 6 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/filesystem/controller/IndexController.java diff --git a/src/main/java/com/filesystem/config/SecurityConfig.java b/src/main/java/com/filesystem/config/SecurityConfig.java index 8b2da7e..986ff0c 100644 --- a/src/main/java/com/filesystem/config/SecurityConfig.java +++ b/src/main/java/com/filesystem/config/SecurityConfig.java @@ -50,6 +50,13 @@ public class SecurityConfig { .requestMatchers("/files/avatar/**").permitAll() .requestMatchers("/api/files/avatar/**").permitAll() .requestMatchers("/api/messages/file/**").permitAll() + .requestMatchers("/webapp/**").permitAll() + .requestMatchers("/assets/**").permitAll() + .requestMatchers("/login", "/register").permitAll() + .requestMatchers("/").permitAll() + .requestMatchers("/desktop").permitAll() + .requestMatchers("/desktop/**").permitAll() + .requestMatchers("/favicon.ico").permitAll() .anyRequest().authenticated() ) .exceptionHandling(exception -> exception diff --git a/src/main/java/com/filesystem/config/WebConfig.java b/src/main/java/com/filesystem/config/WebConfig.java index 58c1d0c..cfeaa40 100644 --- a/src/main/java/com/filesystem/config/WebConfig.java +++ b/src/main/java/com/filesystem/config/WebConfig.java @@ -2,11 +2,13 @@ package com.filesystem.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; +import org.springframework.http.CacheControl; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.nio.file.Paths; +import java.util.concurrent.TimeUnit; @Configuration public class WebConfig implements WebMvcConfigurer { @@ -24,7 +26,20 @@ public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { + // 上传文件目录 registry.addResourceHandler("/uploads/**") .addResourceLocations("file:" + Paths.get(uploadDir).toAbsolutePath() + "/"); + + // 前端静态资源(webapp 目录) + registry.addResourceHandler("/webapp/**") + .addResourceLocations("classpath:/webapp/") + .setCacheControl(CacheControl.noCache().mustRevalidate()); + + registry.addResourceHandler("/assets/**") + .addResourceLocations("classpath:/webapp/assets/") + .setCacheControl(CacheControl.noCache().mustRevalidate()); + + registry.addResourceHandler("/favicon.ico") + .addResourceLocations("classpath:/webapp/"); } } diff --git a/src/main/java/com/filesystem/controller/IndexController.java b/src/main/java/com/filesystem/controller/IndexController.java new file mode 100644 index 0000000..db34845 --- /dev/null +++ b/src/main/java/com/filesystem/controller/IndexController.java @@ -0,0 +1,19 @@ +package com.filesystem.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class IndexController { + + @GetMapping({"/", "/login", "/register"}) + public String forward() { + return "forward:/webapp/index.html"; + } + + // 捕获所有前端路由,返回 index.html 让 Vue Router 处理 + @GetMapping("/desktop/**") + public String desktop() { + return "forward:/webapp/index.html"; + } +} \ No newline at end of file diff --git a/src/main/java/com/filesystem/security/JwtAuthenticationFilter.java b/src/main/java/com/filesystem/security/JwtAuthenticationFilter.java index 052a034..c1df7a3 100644 --- a/src/main/java/com/filesystem/security/JwtAuthenticationFilter.java +++ b/src/main/java/com/filesystem/security/JwtAuthenticationFilter.java @@ -32,7 +32,15 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { new AntPathRequestMatcher("/api/files/test"), new AntPathRequestMatcher("/ws/**"), new AntPathRequestMatcher("/api/files/avatar/**"), - new AntPathRequestMatcher("/api/messages/file/**") + new AntPathRequestMatcher("/api/messages/file/**"), + new AntPathRequestMatcher("/webapp/**"), + new AntPathRequestMatcher("/assets/**"), + new AntPathRequestMatcher("/favicon.ico"), + new AntPathRequestMatcher("/login"), + new AntPathRequestMatcher("/register"), + new AntPathRequestMatcher("/"), + new AntPathRequestMatcher("/desktop"), + new AntPathRequestMatcher("/desktop/**") ); @Override diff --git a/web-vue/src/views/files/index.vue b/web-vue/src/views/files/index.vue index dc74878..78a9120 100644 --- a/web-vue/src/views/files/index.vue +++ b/web-vue/src/views/files/index.vue @@ -821,22 +821,22 @@ const getFileIconColor = (file) => { .grid-view { display: grid; - grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); - gap: 24px; - padding: 24px; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 16px; + padding: 16px; align-content: start; } .file-card { display: flex; flex-direction: column; - padding: 24px; + padding: 16px; border: 1px solid #e4e7ed; border-radius: 8px; cursor: pointer; transition: all 0.2s; background: #fff; - min-height: 180px; + min-height: 140px; } .file-card:hover { @@ -876,17 +876,23 @@ const getFileIconColor = (file) => { .file-card-actions { display: flex; - flex-wrap: nowrap; - gap: 6px; + gap: 4px; justify-content: center; + overflow: hidden; } .file-card-actions .el-button { font-size: 12px; + padding: 4px 8px; + min-width: 0; +} + +.file-card-actions .el-button + .el-button { + margin-left: 0; } .file-card-actions .el-button span { - margin-left: 2px; + display: inline; } .pagination-wrapper { diff --git a/web-vue/vite.config.js b/web-vue/vite.config.js index cc60065..c9e84bc 100644 --- a/web-vue/vite.config.js +++ b/web-vue/vite.config.js @@ -1,6 +1,10 @@ import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' +import { fileURLToPath } from 'url' +import { dirname, resolve } from 'path' + +const __dirname = dirname(fileURLToPath(import.meta.url)) export default defineConfig({ plugins: [vue()], @@ -9,6 +13,11 @@ export default defineConfig({ '@': path.resolve(__dirname, 'src') } }, + base: '/', // 绝对路径,打包后 HTML 引用 /assets/... + build: { + outDir: resolve(__dirname, '../src/main/resources/webapp'), + emptyOutDir: true + }, server: { port: 5173, proxy: {