fix(file-upload): 优化文件上传逻辑并防止重复添加

- 更新服务器端文件上传处理逻辑,避免重复发送事件
- 客户端优化文件上传组件,防止重复添加文件
- 调整文件列表更新策略,支持文件更新
- 优化上传区域样式,提升用户体验
This commit is contained in:
LittleBoy 2025-08-01 18:13:16 +08:00
parent ac081dd134
commit b01ce4d2c9
5 changed files with 25 additions and 9 deletions

View File

@ -85,19 +85,19 @@ io.on('connection', (socket) => {
io.emit('user:count', userCount); io.emit('user:count', userCount);
console.log(`User connected. Total users: ${userCount}`); console.log(`User connected. Total users: ${userCount}`);
// Handle file upload events // Handle file upload events (from client)
socket.on('file:upload', (data) => { socket.on('file:upload', (data) => {
socket.broadcast.emit('file:uploaded', data); socket.broadcast.emit('file:uploaded', data);
console.log('File uploaded:', data.filename); console.log('File uploaded:', data.filename);
}); });
// Handle file delete events // Handle file delete events (from client)
socket.on('file:delete', (data) => { socket.on('file:delete', (data) => {
socket.broadcast.emit('file:deleted', data); socket.broadcast.emit('file:deleted', data);
console.log('File deleted:', data.id); console.log('File deleted:', data.id);
}); });
// Handle file visibility toggle events // Handle file visibility toggle events (from client)
socket.on('file:toggle:visibility', (data) => { socket.on('file:toggle:visibility', (data) => {
socket.broadcast.emit('file:visibility:changed', data); socket.broadcast.emit('file:visibility:changed', data);
console.log('File visibility changed:', data.id, data.isVisible); console.log('File visibility changed:', data.id, data.isVisible);

View File

@ -64,7 +64,7 @@
} }
.upload-area { .upload-area {
@apply flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-muted-foreground/25 bg-muted/50 p-8 text-center transition-colors hover:border-muted-foreground/50 hover:bg-muted/75; @apply flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-muted-foreground/25 bg-muted/50 p-8 text-center transition-colors hover:border-primary/80 hover:bg-muted/75;
} }
.upload-area.drag-over { .upload-area.drag-over {

View File

@ -22,6 +22,8 @@ export const FileUpload: React.FC<FileUploadProps> = ({ onUploadComplete }) => {
const handleFileSelect = useCallback(async (file: File) => { const handleFileSelect = useCallback(async (file: File) => {
const response = await uploadFile(file); const response = await uploadFile(file);
if (response.success) { if (response.success) {
// Don't call onUploadComplete here as the socket event will handle the update
// This prevents duplicate files from being added
onUploadComplete?.(); onUploadComplete?.();
} }
}, [uploadFile, onUploadComplete]); }, [uploadFile, onUploadComplete]);
@ -120,7 +122,9 @@ export const FileUpload: React.FC<FileUploadProps> = ({ onUploadComplete }) => {
<Lock className="w-6 h-6 text-orange-600" /> <Lock className="w-6 h-6 text-orange-600" />
</div> </div>
)} )}
<Upload className={`w-12 h-12 ${!isAuthenticated ? 'text-orange-600' : 'text-muted-foreground'}`} /> <div className="flex justify-center">
<Upload className={`w-12 h-12 ${!isAuthenticated ? 'text-orange-600' : 'text-muted-foreground/70'}`} />
</div>
<div className="space-y-2"> <div className="space-y-2">
<p className="text-lg font-medium"> <p className="text-lg font-medium">
{isAuthenticated ? '拖拽文件到此处上传' : '需要登录后才能上传文件'} {isAuthenticated ? '拖拽文件到此处上传' : '需要登录后才能上传文件'}

View File

@ -109,7 +109,20 @@ export const useFiles = (initialParams?: FileQueryParams): UseFilesReturn => {
if (!socket) return; if (!socket) return;
const handleFileUploaded = (newFile: File) => { const handleFileUploaded = (newFile: File) => {
setFiles(prev => [newFile, ...prev]); setFiles(prev => {
// Check if file already exists by ID
const existingFileIndex = prev.findIndex(file => file.id === newFile.id);
if (existingFileIndex >= 0) {
// File exists, replace it with the new one (in case of updates)
const updatedFiles = [...prev];
updatedFiles[existingFileIndex] = newFile;
return updatedFiles;
} else {
// File doesn't exist, add it to the beginning
return [newFile, ...prev];
}
});
}; };
const handleFileDeleted = (data: { id: number }) => { const handleFileDeleted = (data: { id: number }) => {

View File

@ -58,9 +58,8 @@ export const useUpload = (): UseUploadReturn => {
const response = await uploadPromise; const response = await uploadPromise;
if (response.success && socket) { // The socket server will emit the file:uploaded event via HTTP request
socket.emit('file:upload', response.file); // No need to emit it here to avoid duplicates
}
return response; return response;
} catch (err) { } catch (err) {