From 24681c81c09022f584a57006f2534b5f74723414 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 30 六月 2026 09:27:31 +0800
Subject: [PATCH] 初始化项目

---
 yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java
index f8cd1c4..3b0b533 100644
--- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java
+++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/utils/FileTypeUtils.java
@@ -85,9 +85,9 @@
         // 璁剧疆鍐呭鏄剧ず銆佷笅杞芥枃浠跺悕锛歨ttps://www.cnblogs.com/wq-9/articles/12165056.html
         if (isImage(mineType)) {
             // 鍙傝 https://github.com/YunaiV/ruoyi-vue-pro/issues/692 璁ㄨ
-            response.setHeader("Content-Disposition", "inline;filename=" + HttpUtils.encodeUtf8(filename));
+            response.setHeader("Content-Disposition", buildContentDisposition("inline", filename));
         } else {
-            response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename));
+            response.setHeader("Content-Disposition", buildContentDisposition("attachment", filename));
         }
         // 閽堝 video 鐨勭壒娈婂鐞嗭紝瑙e喅瑙嗛鍦板潃鍦ㄧЩ鍔ㄧ鎾斁鐨勫吋瀹规�ч棶棰�
         if (StrUtil.containsIgnoreCase(mineType, "video")) {
@@ -98,6 +98,29 @@
         IoUtil.write(response.getOutputStream(), false, content);
     }
 
+    private static String buildContentDisposition(String dispositionType, String filename) {
+        return StrUtil.format("{};filename=\"{}\";filename*=UTF-8''{}",
+                dispositionType, buildFallbackFilename(filename), HttpUtils.encodeUrlPathSegment(filename));
+    }
+
+    private static String buildFallbackFilename(String filename) {
+        if (StrUtil.isEmpty(filename)) {
+            return "download";
+        }
+        StringBuilder result = new StringBuilder(filename.length());
+        for (int i = 0; i < filename.length(); i++) {
+            char ch = filename.charAt(i);
+            if (ch == '"' || ch == '\\') {
+                result.append('\\').append(ch);
+            } else if (ch >= 0x20 && ch <= 0x7E) {
+                result.append(ch);
+            } else {
+                result.append('_');
+            }
+        }
+        return result.toString();
+    }
+
     /**
      * 鍒ゆ柇鏄惁鏄浘鐗�
      *

--
Gitblit v1.9.3