Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
c9915a6b
authored
Apr 15, 2026
by
DigHuang
Committed by
GitHub
Apr 15, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(sandbox): xlsx/avi 等不可预览文件走兜底 (#6754)
parent
b35288fe
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
30 additions
and
11 deletions
+30
-11
projects/app/src/pageComponents/chat/SandboxEditor/Editor.tsx
+21
-10
projects/app/src/pageComponents/chat/SandboxEditor/components/EditorContent.tsx
+5
-0
projects/app/src/pageComponents/chat/SandboxEditor/components/FileTabs.tsx
+2
-0
projects/app/src/pageComponents/chat/SandboxEditor/utils.tsx
+2
-1
No files found.
projects/app/src/pageComponents/chat/SandboxEditor/Editor.tsx
View file @
c9915a6b
...
...
@@ -81,19 +81,29 @@ const SandboxEditor = ({ appId, chatId, outLinkAuthData }: Props) => {
// 初始加载根目录的 loading 状态
const
[
loadingRoot
,
setLoadingRoot
]
=
useState
(
false
);
// 读取文件内容 - 根据 language 来决定解码策略
// 读取文件内容 - 根据 language 决定解码策略
// - 媒体(image/audio/video)→ blob URL
// - 其他 → 严格 UTF-8 解码;解不出来视为不可预览(如 xlsx/zip 等真二进制)
const
{
runAsync
:
loadFile
,
loading
:
loadingFile
}
=
useRequest
(
async
(
filePath
:
string
,
language
:
string
):
Promise
<
string
>
=>
{
async
(
filePath
:
string
,
language
:
string
):
Promise
<
{
content
:
string
;
isUnknown
:
boolean
}
>
=>
{
const
response
=
await
getSandboxFile
({
appId
,
chatId
,
outLinkAuthData
,
path
:
filePath
});
const
isBinary
=
getIsBinaryByLanguage
(
language
);
if
(
isBinary
)
{
const
blob
=
await
response
.
blob
();
return
URL
.
createObjectURL
(
blob
);
}
else
{
const
content
=
await
response
.
text
();
return
content
;
return
{
content
:
URL
.
createObjectURL
(
blob
),
isUnknown
:
false
};
}
const
buffer
=
await
response
.
arrayBuffer
();
try
{
const
content
=
new
TextDecoder
(
'utf-8'
,
{
fatal
:
true
}).
decode
(
buffer
);
return
{
content
,
isUnknown
:
false
};
}
catch
{
return
{
content
:
''
,
isUnknown
:
true
};
}
},
{
manual
:
true
}
...
...
@@ -106,7 +116,7 @@ const SandboxEditor = ({ appId, chatId, outLinkAuthData }: Props) => {
if
(
!
targetPath
)
return
;
const
targetFile
=
openedFiles
.
find
((
f
)
=>
f
.
path
===
targetPath
);
if
(
!
targetFile
||
targetFile
.
isBinary
)
return
;
if
(
!
targetFile
||
targetFile
.
isBinary
||
targetFile
.
isUnknown
)
return
;
await
writeSandboxFile
({
appId
,
...
...
@@ -160,7 +170,7 @@ const SandboxEditor = ({ appId, chatId, outLinkAuthData }: Props) => {
const
language
=
getLanguageByFileName
(
fileName
);
const
isBinary
=
getIsBinaryByLanguage
(
language
);
const
content
=
await
loadFile
(
filePath
,
language
);
const
{
content
,
isUnknown
}
=
await
loadFile
(
filePath
,
language
);
const
newFile
:
OpenedFile
=
{
path
:
filePath
,
...
...
@@ -168,7 +178,8 @@ const SandboxEditor = ({ appId, chatId, outLinkAuthData }: Props) => {
content
,
language
,
isBinary
,
isDirty
:
false
isDirty
:
false
,
isUnknown
};
setOpenedFiles
((
prev
)
=>
[...
prev
,
newFile
]);
...
...
@@ -214,7 +225,7 @@ const SandboxEditor = ({ appId, chatId, outLinkAuthData }: Props) => {
// 当切换 tab 时,更新编辑器内容
useEffect
(()
=>
{
if
(
!
editorRef
.
current
||
!
activeFilePath
||
!
activeFile
)
return
;
if
(
activeFile
.
isBinary
)
return
;
if
(
activeFile
.
isBinary
||
activeFile
.
isUnknown
)
return
;
// 使用 ref 标记防止循环更新
isUpdatingRef
.
current
=
true
;
...
...
projects/app/src/pageComponents/chat/SandboxEditor/components/EditorContent.tsx
View file @
c9915a6b
...
...
@@ -88,6 +88,11 @@ const EditorContent = ({
const
renderFileContent
=
()
=>
{
if
(
!
activeFile
)
return
null
;
// 非媒体文件 UTF-8 解码失败 → 走兜底(如 xlsx/zip 等真二进制)
if
(
activeFile
.
isUnknown
)
{
return
t
(
'chat:sandbox_binary_file_no_preview'
);
}
// 二进制文件预览 (图片/音频/视频)
if
(
activeFile
.
isBinary
)
{
const
{
language
,
content
,
name
}
=
activeFile
;
...
...
projects/app/src/pageComponents/chat/SandboxEditor/components/FileTabs.tsx
View file @
c9915a6b
...
...
@@ -10,6 +10,8 @@ export type OpenedFile = {
language
:
string
;
isBinary
:
boolean
;
isDirty
:
boolean
;
// 非媒体文件 UTF-8 解码失败时为 true,前端走「无法预览」兜底
isUnknown
?:
boolean
;
};
type
Props
=
{
...
...
projects/app/src/pageComponents/chat/SandboxEditor/utils.tsx
View file @
c9915a6b
...
...
@@ -80,7 +80,8 @@ const extensionToLang: Record<string, string[]> = {
svg
:
[
'svg'
],
pdf
:
[
'pdf'
],
audio
:
[
'mp3'
,
'wav'
,
'm4a'
,
'flac'
,
'ogg'
],
video
:
[
'avi'
,
'mp4'
,
'webm'
,
'mov'
,
'm4v'
]
// 仅保留浏览器 <video> 原生可解码的容器;avi/mkv/wmv/flv/mov/m4v 等走兜底
video
:
[
'mp4'
,
'webm'
]
};
const
langMap
=
Object
.
entries
(
extensionToLang
).
reduce
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment