feat(上传组件): 添加SimpleFileUpload组件并集成到聊天窗口

- 创建新的SimpleFileUpload组件实现文件上传功能
- 在聊天窗口替换原有上传按钮为新的组件
- 为上传API添加调试日志
- 移除聊天窗口重复的音频图标导入
This commit is contained in:
超级老白兔
2025-09-09 16:06:59 +08:00
parent ef95bcb8bc
commit cc58e4420e
3 changed files with 120 additions and 19 deletions

View File

@@ -10,18 +10,22 @@ export async function uploadFile(
uploadUrl: string = "/v1/attachment/upload",
): Promise<string> {
try {
console.log("uploadFile 接收到的文件:", file);
console.log("上传URL:", uploadUrl);
// 创建 FormData 对象用于文件上传
const formData = new FormData();
formData.append("file", file);
// 使用 request 方法上传文件,设置正确的 Content-Type
const res = await request(uploadUrl, formData, "POST", {
headers: {
"Content-Type": "multipart/form-data",
},
});
console.log("FormData 创建完成");
console.log("FormData 内容:", formData.get("file"));
// 使用 request 方法上传文件,让浏览器自动设置 Content-Type
const res = await request(uploadUrl, formData, "POST");
console.log("上传响应:", res);
return res.url;
} catch (e: any) {
console.error("uploadFile 错误:", e);
throw new Error(e?.message || "文件上传失败");
}
}

View File

@@ -0,0 +1,97 @@
import React, { useRef, useState } from "react";
import { Button, message } from "antd";
import { FolderOutlined, LoadingOutlined } from "@ant-design/icons";
import { uploadFile } from "@/api/common";
interface SimpleFileUploadProps {
onFileUploaded?: (filePath: string) => void;
disabled?: boolean;
className?: string;
maxSize?: number; // 最大文件大小(MB)
accept?: string; // 接受的文件类型
}
const SimpleFileUpload: React.FC<SimpleFileUploadProps> = ({
onFileUploaded,
disabled = false,
className,
maxSize = 50,
accept = "*/*",
}) => {
const fileInputRef = useRef<HTMLInputElement>(null);
const [uploading, setUploading] = useState(false);
// 验证文件
const validateFile = (file: File): boolean => {
if (file.size > maxSize * 1024 * 1024) {
message.error(`文件大小不能超过 ${maxSize}MB`);
return false;
}
return true;
};
// 处理文件选择
const handleFileSelect = async (
event: React.ChangeEvent<HTMLInputElement>,
) => {
const files = event.target.files;
if (!files || files.length === 0) return;
const file = files[0];
console.log("选择的文件:", file);
console.log("文件名:", file.name);
console.log("文件大小:", file.size);
console.log("文件类型:", file.type);
if (!validateFile(file)) {
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
return;
}
setUploading(true);
try {
console.log("开始上传文件...");
const fileUrl = await uploadFile(file);
console.log("上传成功文件URL:", fileUrl);
onFileUploaded?.(fileUrl);
message.success("文件上传成功");
} catch (error: any) {
console.error("文件上传失败:", error);
message.error(error.message || "文件上传失败");
} finally {
setUploading(false);
if (fileInputRef.current) {
fileInputRef.current.value = "";
}
}
};
const handleClick = () => {
if (disabled || uploading) return;
fileInputRef.current?.click();
};
return (
<>
<input
ref={fileInputRef}
type="file"
accept={accept}
onChange={handleFileSelect}
style={{ display: "none" }}
/>
<Button
type="text"
icon={uploading ? <LoadingOutlined /> : <FolderOutlined />}
onClick={handleClick}
disabled={disabled || uploading}
className={className}
/>
</>
);
};
export default SimpleFileUpload;

View File

@@ -3,10 +3,7 @@ import { Layout, Input, Button, Dropdown, Menu, Tooltip, Modal } from "antd";
import {
ShareAltOutlined,
SendOutlined,
SmileOutlined,
FolderOutlined,
AudioOutlined,
AudioOutlined as AudioHoldOutlined,
CodeSandboxOutlined,
MessageOutlined,
EnvironmentOutlined,
@@ -16,6 +13,7 @@ import { ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
import { useWebSocketStore } from "@/store/module/websocket/websocket";
import { EmojiPicker } from "@/components/EmojiSeclection";
import { EmojiInfo } from "@/components/EmojiSeclection/wechatEmoji";
import SimpleFileUpload from "@/components/Upload/SimpleFileUpload";
import styles from "./MessageEnter.module.scss";
const { Footer } = Layout;
@@ -96,11 +94,14 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
// 处理表情选择
const handleEmojiSelect = (emoji: EmojiInfo) => {
console.log("选择表情:", emoji.name);
// 将表情插入到输入框文字的最后
setInputValue(prevValue => prevValue + `[${emoji.name}]`);
};
const handleFileUploaded = (filePath: string) => {
console.log("文件上传成功,路径:", filePath);
// 这里可以根据需要处理文件路径,比如发送文件消息
};
return (
<>
{/* 聊天输入 */}
@@ -109,13 +110,12 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
<div className={styles.inputToolbar}>
<div className={styles.leftTool}>
<EmojiPicker onEmojiSelect={handleEmojiSelect} />
<Tooltip title="上传附件">
<Button
type="text"
icon={<FolderOutlined />}
className={styles.toolbarButton}
/>
</Tooltip>
<SimpleFileUpload
onFileUploaded={handleFileUploaded}
className={styles.toolbarButton}
maxSize={50}
accept="*/*"
/>
<Tooltip title="收藏">
<Button
type="text"
@@ -140,7 +140,7 @@ const MessageEnter: React.FC<MessageEnterProps> = ({ contract }) => {
<Tooltip title="按住说话">
<Button
type="text"
icon={<AudioHoldOutlined />}
icon={<AudioOutlined />}
className={styles.toolbarButton}
style={{ position: "relative" }}
>