From ea4e36d759eeff77f8e66e547081c8259f349a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Mon, 11 Aug 2025 18:06:27 +0800 Subject: [PATCH] =?UTF-8?q?FEAT=20=3D>=20=E6=9C=AC=E6=AC=A1=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=A1=B9=E7=9B=AE=E4=B8=BA=EF=BC=9A=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E7=BB=84=E4=BB=B6=E7=9A=84=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3=EF=BC=8C=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=A3=8E=E6=A0=BC=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=8A=9F=E8=83=BD=E6=8F=8F=E8=BF=B0=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E5=88=A0=E9=99=A4=E4=B8=8D=E5=86=8D=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=A0=B7=E5=BC=8F=E5=92=8C=E7=BB=84=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E6=8F=90=E5=8D=87=E4=BB=A3=E7=A0=81=E7=9A=84=E5=8F=AF?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4=E6=80=A7=E5=92=8C=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Upload/ChatFileUpload/example.tsx | 254 +++++++++++++++++ .../Upload/ChatFileUpload/index.module.scss | 48 ++++ .../Upload/ChatFileUpload/index.tsx | 189 +++++++++++++ .../components/Upload/ChatFileUpload/test.tsx | 65 +++++ nkebao/src/components/Upload/README.md | 226 +++++++++++++-- .../{ => ChatWindow}/ChatWindow.module.scss | 96 ++++++- .../{ChatWindow.tsx => ChatWindow/index.tsx} | 259 ++++++++++++++++-- .../{ => ContactList}/ContactList.module.scss | 0 .../index.tsx} | 2 +- .../{ => MessageList}/MessageList.module.scss | 0 .../index.tsx} | 0 nkebao/src/pages/pc/ckbox/index.tsx | 6 +- 12 files changed, 1085 insertions(+), 60 deletions(-) create mode 100644 nkebao/src/components/Upload/ChatFileUpload/example.tsx create mode 100644 nkebao/src/components/Upload/ChatFileUpload/index.module.scss create mode 100644 nkebao/src/components/Upload/ChatFileUpload/index.tsx create mode 100644 nkebao/src/components/Upload/ChatFileUpload/test.tsx rename nkebao/src/pages/pc/ckbox/components/{ => ChatWindow}/ChatWindow.module.scss (79%) rename nkebao/src/pages/pc/ckbox/components/{ChatWindow.tsx => ChatWindow/index.tsx} (59%) rename nkebao/src/pages/pc/ckbox/components/{ => ContactList}/ContactList.module.scss (100%) rename nkebao/src/pages/pc/ckbox/components/{ContactList.tsx => ContactList/index.tsx} (97%) rename nkebao/src/pages/pc/ckbox/components/{ => MessageList}/MessageList.module.scss (100%) rename nkebao/src/pages/pc/ckbox/components/{MessageList.tsx => MessageList/index.tsx} (100%) diff --git a/nkebao/src/components/Upload/ChatFileUpload/example.tsx b/nkebao/src/components/Upload/ChatFileUpload/example.tsx new file mode 100644 index 000000000..9795e00be --- /dev/null +++ b/nkebao/src/components/Upload/ChatFileUpload/example.tsx @@ -0,0 +1,254 @@ +import React, { useState } from "react"; +import { Input, Button, Card, Space, Typography, Divider } from "antd"; +import { SendOutlined } from "@ant-design/icons"; +import ChatFileUpload from "./index"; + +const { TextArea } = Input; +const { Text } = Typography; + +interface ChatMessage { + id: string; + type: "text" | "file"; + content: string; + timestamp: Date; + fileInfo?: { + url: string; + name: string; + type: string; + size: number; + }; +} + +const ChatFileUploadExample: React.FC = () => { + const [messages, setMessages] = useState([]); + const [inputValue, setInputValue] = useState(""); + + // 处理文件上传 + const handleFileUploaded = (fileInfo: { + url: string; + name: string; + type: string; + size: number; + }) => { + const newMessage: ChatMessage = { + id: Date.now().toString(), + type: "file", + content: `文件: ${fileInfo.name}`, + timestamp: new Date(), + fileInfo, + }; + + setMessages(prev => [...prev, newMessage]); + }; + + // 处理文本发送 + const handleSendText = () => { + if (!inputValue.trim()) return; + + const newMessage: ChatMessage = { + id: Date.now().toString(), + type: "text", + content: inputValue, + timestamp: new Date(), + }; + + setMessages(prev => [...prev, newMessage]); + setInputValue(""); + }; + + // 格式化文件大小 + const formatFileSize = (bytes: number) => { + if (bytes === 0) return "0 B"; + const k = 1024; + const sizes = ["B", "KB", "MB", "GB"]; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; + }; + + // 获取文件类型图标 + const getFileTypeIcon = (type: string, name: string) => { + const lowerType = type.toLowerCase(); + const lowerName = name.toLowerCase(); + + if (lowerType.startsWith("image/")) { + return "🖼️"; + } else if (lowerType.startsWith("video/")) { + return "🎥"; + } else if (lowerType.startsWith("audio/")) { + return "🎵"; + } else if (lowerType === "application/pdf") { + return "📄"; + } else if (lowerName.endsWith(".doc") || lowerName.endsWith(".docx")) { + return "📝"; + } else if (lowerName.endsWith(".xls") || lowerName.endsWith(".xlsx")) { + return "📊"; + } else if (lowerName.endsWith(".ppt") || lowerName.endsWith(".pptx")) { + return "📈"; + } else { + return "📎"; + } + }; + + return ( +
+ + + 功能特点: +
    +
  • 点击文件按钮直接唤醒文件选择框
  • +
  • 选择文件后自动上传
  • +
  • 上传成功后自动发送到聊天框
  • +
  • 支持各种文件类型和大小限制
  • +
  • 显示文件图标和大小信息
  • +
+
+
+ + {/* 聊天消息区域 */} + + {messages.length === 0 ? ( +
+ 暂无消息,开始聊天吧! +
+ ) : ( +
+ {messages.map(message => ( +
+
+ {message.type === "text" ? ( +
{message.content}
+ ) : ( +
+
+ + {getFileTypeIcon( + message.fileInfo!.type, + message.fileInfo!.name, + )} + + {message.fileInfo!.name} +
+
+ 大小: {formatFileSize(message.fileInfo!.size)} +
+
+ 类型: {message.fileInfo!.type} +
+ + 查看文件 + +
+ )} +
+ {message.timestamp.toLocaleTimeString()} +
+
+
+ ))} +
+ )} +
+ + {/* 输入区域 */} + + +