修复群文件上传不传file_type,图片/视频/语音群文件全部显示成通用文件图标

根因:POST /groups/{topic}/files 的 file_type 是客户端登记时自己声明的字段(im-api.js的
addGroupFile早就留了这个参数),不是服务端拿mime_type反推的——实测:上传一张mime_type
正确记成"image/png"的图片,只要请求体不带file_type,服务端就把它落成字面量"file"(不是
留空)。GroupFiles的onFile上传流程一直没传这个字段,导致FILE_TYPE_META准备好的
image/video/audio/document四种彩色图标从未被真正用上,所有群文件不分类型清一色显示灰色
通用文件图标。

修复:新增fileTypeFromMime辅助函数(与content-library-view.jsx的同名函数用同一套mime前缀
优先、扩展名兜底文档类型的判断口径),上传时算出分类一起传给addGroupFile。

验证:真实浏览器上传一张PNG,接口返回file_type从"file"变成"image",列表图标从灰色通用
文件图标变成绿色图片图标;对照同一会话里upload-fix之前的旧文件,图标仍是灰色(存量数据
不受影响,符合预期,不需要也没有接口能批量回填旧记录)。
This commit is contained in:
Your Name
2026-09-06 13:47:19 +08:00
parent ddf23d40b2
commit fa2288c497
+17 -1
View File
@@ -967,6 +967,21 @@ const FILE_TYPE_META = {
image: ['image', '#3ba55c'], video: ['videocam', '#3b82c4'], audio: ['audiotrack', '#8b5cf6'],
document: ['description', '#e05d44'], file: ['insert_drive_file', '#8a8f98']
};
const DOCUMENT_EXT = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'];
// POST /groups/{topic}/files 的 file_type 字段是客户端在登记时自己声明的(addGroupFile 的
// im-api.js 签名早就留了这个参数),不是服务端拿 mime_type 反推的——实测:即使 mime_type 正确
// 存成 "image/png",只要请求体没带 file_type,服务端就把它落成字面量 "file"(不是留空)。这里
// 的 onFile 上传流程原来完全没传这个字段,导致真实是图片/视频/语音的群文件在列表里全部显示成
// 灰色通用文件图标,跟 FILE_TYPE_META 已经准备好的 image/video/audio/document 四种彩色图标从未
// 对应起来过。跟 content-library-view.jsx 的 fileTypeFromMime 用的是同一套判断(mime 前缀优先,
// 帶附件扩展名兜底文档类型),保持两处"什么算图片/视频/文档"的口径一致。
function fileTypeFromMime(mime, name) {
const prefix = (mime || '').split('/')[0];
if (prefix === 'image' || prefix === 'video' || prefix === 'audio') return prefix;
const ext = (/\.([a-zA-Z0-9]+)$/.exec(name || '') || [])[1];
if (mime === 'application/pdf' || DOCUMENT_EXT.includes((ext || '').toLowerCase())) return 'document';
return 'file';
}
function GroupFiles({topic, tinode, onToast}) {
const [queryInput, setQueryInput] = React.useState('');
@@ -1016,7 +1031,8 @@ function GroupFiles({topic, tinode, onToast}) {
if (!file || !tinode) return;
setUploading({name: file.name, progress: 0});
uploadLargeFile(tinode, file, frac => setUploading(u => u ? {...u, progress: Math.round(frac * 100)} : u))
.then(({fileId}) => addGroupFile(topic, {fileId, fileName: file.name, mimeType: file.type, fileSize: file.size}))
.then(({fileId}) => addGroupFile(topic, {fileId, fileName: file.name, mimeType: file.type, fileSize: file.size,
fileType: fileTypeFromMime(file.type, file.name)}))
.then(() => { setUploading(null); load(); })
.catch(err => { setUploading(null); onToast(err.message || '上传失败'); });
};