@ai-group/chat-sdk 3.6.3 → 3.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/cjs/components/FileGallery/index.d.ts +0 -30
  2. package/dist/cjs/components/FileGallery/index.js +287 -209
  3. package/dist/cjs/components/FileGallery/index.js.map +2 -2
  4. package/dist/cjs/components/FileGallery/styles.d.ts +5 -0
  5. package/dist/cjs/components/FileGallery/styles.js +106 -0
  6. package/dist/cjs/components/FileGallery/styles.js.map +2 -2
  7. package/dist/cjs/components/XAdkProvider/compound/Sender.js +3 -2
  8. package/dist/cjs/components/XAdkProvider/compound/Sender.js.map +2 -2
  9. package/dist/cjs/components/XAdkSender/index.js +1 -0
  10. package/dist/cjs/components/XAdkSender/index.js.map +2 -2
  11. package/dist/cjs/hooks/useADKChat.js +347 -156
  12. package/dist/cjs/hooks/useADKChat.js.map +3 -3
  13. package/dist/cjs/types/FileGallery.d.ts +41 -0
  14. package/dist/cjs/types/FileGallery.js.map +1 -1
  15. package/dist/cjs/types/XAdkProvider.d.ts +4 -0
  16. package/dist/cjs/types/XAdkProvider.js.map +1 -1
  17. package/dist/esm/components/FileGallery/index.d.ts +0 -30
  18. package/dist/esm/components/FileGallery/index.js +362 -364
  19. package/dist/esm/components/FileGallery/index.js.map +1 -1
  20. package/dist/esm/components/FileGallery/styles.d.ts +5 -0
  21. package/dist/esm/components/FileGallery/styles.js +10 -2
  22. package/dist/esm/components/FileGallery/styles.js.map +1 -1
  23. package/dist/esm/components/XAdkProvider/compound/Sender.js +5 -3
  24. package/dist/esm/components/XAdkProvider/compound/Sender.js.map +1 -1
  25. package/dist/esm/components/XAdkSender/index.js +1 -0
  26. package/dist/esm/components/XAdkSender/index.js.map +1 -1
  27. package/dist/esm/hooks/useADKChat.js +300 -129
  28. package/dist/esm/hooks/useADKChat.js.map +1 -1
  29. package/dist/esm/types/FileGallery.d.ts +41 -0
  30. package/dist/esm/types/FileGallery.js.map +1 -1
  31. package/dist/esm/types/XAdkProvider.d.ts +4 -0
  32. package/dist/esm/types/XAdkProvider.js.map +1 -1
  33. package/dist/umd/chat-sdk.min.js +1 -1
  34. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/FileGallery/index.tsx"],
4
- "sourcesContent": ["import React, { useState, useEffect } from \"react\";\nimport { Image, Tooltip, Progress } from \"antd\";\nimport {\n FileOutlined,\n FilePdfOutlined,\n FileWordOutlined,\n FileExcelOutlined,\n FilePptOutlined,\n FileImageOutlined,\n CloseOutlined,\n AudioOutlined,\n FileZipOutlined,\n VideoCameraOutlined,\n FileMarkdownOutlined,\n} from \"@ant-design/icons\";\nimport { FileItem, FileGalleryProps } from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\n/**\n * 获取文件名\n */\nconst getFileName = (file: FileItem): string => {\n return file.displayName || file.name || \"\";\n};\n\n/**\n * 获取文件大小\n */\nconst getFileSize = (file: FileItem): number => {\n return file.size || 0;\n};\n\n/**\n * 获取文件 MIME 类型\n */\nconst getMimeType = (file: FileItem): string => {\n return file.mimeType || file.type || \"\";\n};\n\n/**\n * 获取文件 URL\n */\nconst getFileUrl = (file: FileItem): string => {\n return (\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\"\n );\n};\n\n/**\n * 获取文件唯一标识\n */\nconst getFileId = (file: FileItem): string => {\n return file.id || file.uid || \"\";\n};\n\n/**\n * 判断是否是图片文件\n */\nconst isImageFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"image/\")) return true;\n\n const fileName = getFileName(file);\n if (fileName && fileName.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i))\n return true;\n\n const url = getFileUrl(file);\n if (url && url.match(/\\.(jpg|jpeg|png|gif|webp|bmp|svg)(\\?.*)?$/i))\n return true;\n\n return false;\n};\n\n/**\n * 判断是否是音频文件\n */\nconst isAudioFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"audio/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp3|wav|m4a|aac|ogg|flac)$/i);\n};\n\n/**\n * 判断是否是视频文件\n */\nconst isVideoFile = (file: FileItem): boolean => {\n const mimeType = getMimeType(file);\n if (mimeType && mimeType.startsWith(\"video/\")) return true;\n\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(mp4|mov|webm|mkv|avi)$/i);\n};\n\n/**\n * 判断是否是压缩包文件\n */\nconst isZipFile = (file: FileItem): boolean => {\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(zip|rar|7z|tar|gz|bz2|xz|tgz)$/i);\n};\n\n/**\n * 判断是否是 Markdown 文件\n */\nconst isMarkdownFile = (file: FileItem): boolean => {\n const fileName = getFileName(file);\n return !!fileName?.match(/\\.(md|markdown)$/i);\n};\n\n/**\n * 获取文件扩展名\n */\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\n/**\n * 获取文件图标和颜色\n */\nconst getFileIcon = (\n file: FileItem,\n): { icon: React.ReactNode; color: string } => {\n const ext = getFileExtension(getFileName(file));\n\n // PDF\n if (ext === \"pdf\") {\n return { icon: <FilePdfOutlined />, color: \"#ff4d4f\" };\n }\n\n // Word\n if ([\"doc\", \"docx\"].includes(ext)) {\n return { icon: <FileWordOutlined />, color: \"#1677ff\" };\n }\n\n // Excel\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) {\n return { icon: <FileExcelOutlined />, color: \"#22b35e\" };\n }\n\n // PPT\n if ([\"ppt\", \"pptx\"].includes(ext)) {\n return { icon: <FilePptOutlined />, color: \"#ff6e31\" };\n }\n\n // Audio\n if ([\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"].includes(ext)) {\n return { icon: <AudioOutlined />, color: \"#722ed1\" };\n }\n\n // Video\n if ([\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"].includes(ext)) {\n return { icon: <VideoCameraOutlined />, color: \"#fa8c16\" };\n }\n\n // 压缩包\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\", \"bz2\", \"xz\", \"tgz\"].includes(ext)) {\n return { icon: <FileZipOutlined />, color: \"#eb2f96\" };\n }\n\n // Markdown\n if ([\"md\", \"markdown\"].includes(ext)) {\n return { icon: <FileMarkdownOutlined />, color: \"#13c2c2\" };\n }\n\n // 图片\n if (isImageFile(file)) {\n return { icon: <FileImageOutlined />, color: \"#8c8c8c\" };\n }\n\n // 默认\n return { icon: <FileOutlined />, color: \"#8c8c8c\" };\n};\n\n/**\n * 格式化文件大小\n */\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return bytes + \" B\";\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\";\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\";\n};\n\nconst styles = useStyles();\n\n/**\n * FileGallery - 单文件展示组件\n *\n * 功能特性:\n * - 📁 支持多种文件类型展示 (图片、音频、视频、文档等)\n * - 🖼️ 图片支持预览和缩略图\n * - 🎵 音频文件支持内联播放\n * - 🎬 视频文件支持内联播放\n * - 📊 显示文件大小、类型图标\n * - 🗑️ 支持删除操作\n * - 📤 支持上传进度显示\n * - 🎨 支持卡片内部布局控制(align:图标和信息的排列方式)\n *\n * @example\n * // XAdkSender 场景 - 可删除的本地文件\n * {files.map(file => (\n * <FileGallery\n * key={file.id}\n * file={file}\n * removable\n * onRemove={handleRemove}\n * />\n * ))}\n *\n * @example\n * // XadkChatbot 场景 - 只读的远程文件\n * {files.map(file => (\n * <FileGallery key={file.id} file={file} />\n * ))}\n */\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n onClick,\n}) => {\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file?.file) return;\n\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n\n return () => URL.revokeObjectURL(url);\n }, [file?.file]);\n\n if (!file) return null;\n\n const isImage = isImageFile(file);\n const isAudio = isAudioFile(file);\n const isVideo = isVideoFile(file);\n const isZip = isZipFile(file);\n const isMarkdown = isMarkdownFile(file);\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 图片文件\n if (isImage) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n {/* 图片缩略图 */}\n <div className={styles.imageThumbnail}>\n <Image\n src={url}\n alt={fileName}\n fallback=\"data:image/png;base64,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\"\n preview={onClick ? false : { src: url }}\n />\n\n {/* 上传进度遮罩 */}\n {file.status === \"uploading\" && (\n <div className={styles.imageOverlay}>\n <Progress\n type=\"circle\"\n percent={file.progress}\n size={30}\n strokeColor=\"#1677ff\"\n />\n </div>\n )}\n </div>\n\n {/* 文件信息 */}\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n {Number(file?.size) > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )}\n </div>\n\n {/* 删除按钮 */}\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 音频文件\n if (isAudio) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#722ed1\" }}>\n <AudioOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <audio\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 28 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 视频文件\n if (isVideo) {\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={style}\n >\n <div className={styles.fileIcon} style={{ color: \"#fa8c16\" }}>\n <VideoCameraOutlined />\n </div>\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>{fileName}</div>\n </Tooltip>\n\n <video\n src={url}\n controls\n className={styles.mediaWrapper}\n style={{ width: \"100%\", height: 40 }}\n />\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n }\n\n // 其他文件\n const { icon, color } = getFileIcon(file);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl && !onClick ? (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.fileLink}\n >\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n </a>\n ) : (\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n )}\n\n {file.status === \"uploading\" ? (\n <Progress\n percent={file.progress}\n size=\"small\"\n showInfo={false}\n strokeColor=\"#1677ff\"\n className={styles.progress}\n />\n ) : (\n fileSize > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{\n fontSize: \"11px\",\n color: \"#ff4d4f\",\n marginTop: \"2px\",\n }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {removable && (\n <button\n className={styles.fileRemoveBtn}\n onClick={() => onRemove(fileId)}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n )}\n </div>\n );\n};\n\nexport default FileGallery;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA2C;AAC3C,kBAAyC;AACzC,mBAYO;AAEP,oBAA0B;AAuHP;AAhHnB,IAAM,cAAc,CAAC,SAA2B;AAC9C,SAAO,KAAK,eAAe,KAAK,QAAQ;AAC1C;AAKA,IAAM,cAAc,CAAC,SAA2B;AAC9C,SAAO,KAAK,QAAQ;AACtB;AAKA,IAAM,cAAc,CAAC,SAA2B;AAC9C,SAAO,KAAK,YAAY,KAAK,QAAQ;AACvC;AAKA,IAAM,aAAa,CAAC,SAA2B;AA5C/C;AA6CE,SACE,KAAK,aACL,UAAK,aAAL,mBAAe,cACf,UAAK,aAAL,mBAAe,YACf,KAAK,WACL;AAEJ;AAKA,IAAM,YAAY,CAAC,SAA2B;AAC5C,SAAO,KAAK,MAAM,KAAK,OAAO;AAChC;AAKA,IAAM,cAAc,CAAC,SAA4B;AAC/C,QAAM,WAAW,YAAY,IAAI;AACjC,MAAI,YAAY,SAAS,WAAW,QAAQ;AAAG,WAAO;AAEtD,QAAM,WAAW,YAAY,IAAI;AACjC,MAAI,YAAY,SAAS,MAAM,qCAAqC;AAClE,WAAO;AAET,QAAM,MAAM,WAAW,IAAI;AAC3B,MAAI,OAAO,IAAI,MAAM,4CAA4C;AAC/D,WAAO;AAET,SAAO;AACT;AAKA,IAAM,cAAc,CAAC,SAA4B;AAC/C,QAAM,WAAW,YAAY,IAAI;AACjC,MAAI,YAAY,SAAS,WAAW,QAAQ;AAAG,WAAO;AAEtD,QAAM,WAAW,YAAY,IAAI;AACjC,SAAO,CAAC,EAAC,qCAAU,MAAM;AAC3B;AAKA,IAAM,cAAc,CAAC,SAA4B;AAC/C,QAAM,WAAW,YAAY,IAAI;AACjC,MAAI,YAAY,SAAS,WAAW,QAAQ;AAAG,WAAO;AAEtD,QAAM,WAAW,YAAY,IAAI;AACjC,SAAO,CAAC,EAAC,qCAAU,MAAM;AAC3B;AAKA,IAAM,YAAY,CAAC,SAA4B;AAC7C,QAAM,WAAW,YAAY,IAAI;AACjC,SAAO,CAAC,EAAC,qCAAU,MAAM;AAC3B;AAKA,IAAM,iBAAiB,CAAC,SAA4B;AAClD,QAAM,WAAW,YAAY,IAAI;AACjC,SAAO,CAAC,EAAC,qCAAU,MAAM;AAC3B;AAKA,IAAM,mBAAmB,CAAC,aAA6B;AACrD,QAAM,MAAM,SAAS,MAAM,GAAG,EAAE,IAAI;AACpC,SAAO,MAAM,IAAI,YAAY,IAAI;AACnC;AAKA,IAAM,cAAc,CAClB,SAC6C;AAC7C,QAAM,MAAM,iBAAiB,YAAY,IAAI,CAAC;AAG9C,MAAI,QAAQ,OAAO;AACjB,WAAO,EAAE,MAAM,4CAAC,gCAAgB,GAAI,OAAO,UAAU;AAAA,EACvD;AAGA,MAAI,CAAC,OAAO,MAAM,EAAE,SAAS,GAAG,GAAG;AACjC,WAAO,EAAE,MAAM,4CAAC,iCAAiB,GAAI,OAAO,UAAU;AAAA,EACxD;AAGA,MAAI,CAAC,OAAO,QAAQ,KAAK,EAAE,SAAS,GAAG,GAAG;AACxC,WAAO,EAAE,MAAM,4CAAC,kCAAkB,GAAI,OAAO,UAAU;AAAA,EACzD;AAGA,MAAI,CAAC,OAAO,MAAM,EAAE,SAAS,GAAG,GAAG;AACjC,WAAO,EAAE,MAAM,4CAAC,gCAAgB,GAAI,OAAO,UAAU;AAAA,EACvD;AAGA,MAAI,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,MAAM,EAAE,SAAS,GAAG,GAAG;AAC7D,WAAO,EAAE,MAAM,4CAAC,8BAAc,GAAI,OAAO,UAAU;AAAA,EACrD;AAGA,MAAI,CAAC,OAAO,OAAO,QAAQ,OAAO,KAAK,EAAE,SAAS,GAAG,GAAG;AACtD,WAAO,EAAE,MAAM,4CAAC,oCAAoB,GAAI,OAAO,UAAU;AAAA,EAC3D;AAGA,MAAI,CAAC,OAAO,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,EAAE,SAAS,GAAG,GAAG;AACvE,WAAO,EAAE,MAAM,4CAAC,gCAAgB,GAAI,OAAO,UAAU;AAAA,EACvD;AAGA,MAAI,CAAC,MAAM,UAAU,EAAE,SAAS,GAAG,GAAG;AACpC,WAAO,EAAE,MAAM,4CAAC,qCAAqB,GAAI,OAAO,UAAU;AAAA,EAC5D;AAGA,MAAI,YAAY,IAAI,GAAG;AACrB,WAAO,EAAE,MAAM,4CAAC,kCAAkB,GAAI,OAAO,UAAU;AAAA,EACzD;AAGA,SAAO,EAAE,MAAM,4CAAC,6BAAa,GAAI,OAAO,UAAU;AACpD;AAKA,IAAM,iBAAiB,CAAC,UAA0B;AAChD,MAAI,QAAQ;AAAM,WAAO,QAAQ;AACjC,MAAI,QAAQ,OAAO;AAAM,YAAQ,QAAQ,MAAM,QAAQ,CAAC,IAAI;AAC5D,UAAQ,SAAS,OAAO,OAAO,QAAQ,CAAC,IAAI;AAC9C;AAEA,IAAM,aAAS,yBAAU;AAgCzB,IAAM,cAA0C,CAAC;AAAA,EAC/C;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,WAAW,MAAM;AAAA,EAAC;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,EAAE;AAE7C,8BAAU,MAAM;AACd,QAAI,EAAC,6BAAM;AAAM;AAEjB,UAAMA,OAAM,IAAI,gBAAgB,KAAK,IAAI;AACzC,iBAAaA,IAAG;AAEhB,WAAO,MAAM,IAAI,gBAAgBA,IAAG;AAAA,EACtC,GAAG,CAAC,6BAAM,IAAI,CAAC;AAEf,MAAI,CAAC;AAAM,WAAO;AAElB,QAAM,UAAU,YAAY,IAAI;AAChC,QAAM,UAAU,YAAY,IAAI;AAChC,QAAM,UAAU,YAAY,IAAI;AAChC,QAAM,QAAQ,UAAU,IAAI;AAC5B,QAAM,aAAa,eAAe,IAAI;AACtC,QAAM,WAAW,YAAY,IAAI;AACjC,QAAM,WAAW,YAAY,IAAI;AACjC,QAAM,SAAS,UAAU,IAAI;AAC7B,QAAM,MAAM,WAAW,IAAI,KAAK;AAGhC,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,OAAO,YAAY,UAAU,UAAU,gBAAgB,MAAM,aAAa;AAAA,QACxF,OAAO,EAAE,GAAG,OAAO,QAAQ,UAAU,YAAY,OAAU;AAAA,QAC3D,SAAS,MAAM,mCAAU;AAAA,QAGzB;AAAA,uDAAC,SAAI,WAAW,OAAO,gBACrB;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,KAAK;AAAA,gBACL,UAAS;AAAA,gBACT,SAAS,UAAU,QAAQ,EAAE,KAAK,IAAI;AAAA;AAAA,YACxC;AAAA,YAGC,KAAK,WAAW,eACf,4CAAC,SAAI,WAAW,OAAO,cACrB;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAS,KAAK;AAAA,gBACd,MAAM;AAAA,gBACN,aAAY;AAAA;AAAA,YACd,GACF;AAAA,aAEJ;AAAA,UAGA,6CAAC,SAAI,WAAW,OAAO,UACrB;AAAA,wDAAC,uBAAQ,OAAO,UACd,sDAAC,SAAI,WAAW,OAAO,UACpB,mBAAS,SAAS,KACf,GAAG,SAAS,UAAU,GAAG,EAAE,SAC3B,UACN,GACF;AAAA,YACC,OAAO,6BAAM,IAAI,IAAI,KACpB,4CAAC,SAAI,WAAW,OAAO,UAAW,yBAAe,QAAQ,GAAE;AAAA,aAE/D;AAAA,UAGC,aACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,OAAO;AAAA,cAClB,SAAS,MAAM,SAAS,MAAM;AAAA,cAC9B,UAAU,KAAK,WAAW;AAAA,cAC1B,cAAW;AAAA,cAEX,sDAAC,8BAAc;AAAA;AAAA,UACjB;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AAGA,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,OAAO,YAAY,UAAU,UAAU,gBAAgB,MAAM,aAAa;AAAA,QACxF;AAAA,QAEA;AAAA,sDAAC,SAAI,WAAW,OAAO,UAAU,OAAO,EAAE,OAAO,UAAU,GACzD,sDAAC,8BAAc,GACjB;AAAA,UAEA,6CAAC,SAAI,WAAW,OAAO,UACrB;AAAA,wDAAC,uBAAQ,OAAO,UACd,sDAAC,SAAI,WAAW,OAAO,UAAW,oBAAS,GAC7C;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,UAAQ;AAAA,gBACR,WAAW,OAAO;AAAA,gBAClB,OAAO,EAAE,OAAO,QAAQ,QAAQ,GAAG;AAAA;AAAA,YACrC;AAAA,aACF;AAAA,UAEC,aACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,OAAO;AAAA,cAClB,SAAS,MAAM,SAAS,MAAM;AAAA,cAC9B,UAAU,KAAK,WAAW;AAAA,cAC1B,cAAW;AAAA,cAEX,sDAAC,8BAAc;AAAA;AAAA,UACjB;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AAGA,MAAI,SAAS;AACX,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,OAAO,YAAY,UAAU,UAAU,gBAAgB,MAAM,aAAa;AAAA,QACxF;AAAA,QAEA;AAAA,sDAAC,SAAI,WAAW,OAAO,UAAU,OAAO,EAAE,OAAO,UAAU,GACzD,sDAAC,oCAAoB,GACvB;AAAA,UAEA,6CAAC,SAAI,WAAW,OAAO,UACrB;AAAA,wDAAC,uBAAQ,OAAO,UACd,sDAAC,SAAI,WAAW,OAAO,UAAW,oBAAS,GAC7C;AAAA,YAEA;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK;AAAA,gBACL,UAAQ;AAAA,gBACR,WAAW,OAAO;AAAA,gBAClB,OAAO,EAAE,OAAO,QAAQ,QAAQ,GAAG;AAAA;AAAA,YACrC;AAAA,aACF;AAAA,UAEC,aACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,OAAO;AAAA,cAClB,SAAS,MAAM,SAAS,MAAM;AAAA,cAC9B,UAAU,KAAK,WAAW;AAAA,cAC1B,cAAW;AAAA,cAEX,sDAAC,8BAAc;AAAA;AAAA,UACjB;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AAGA,QAAM,EAAE,MAAM,MAAM,IAAI,YAAY,IAAI;AACxC,QAAM,gBAAgB,OAAO,IAAI,WAAW,MAAM;AAElD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,OAAO,YAAY,UAAU,UAAU,gBAAgB,MAAM,aAAa;AAAA,MACxF,OAAO,EAAE,GAAG,OAAO,QAAQ,UAAU,YAAY,OAAU;AAAA,MAC3D,SAAS,MAAM,mCAAU;AAAA,MAEzB;AAAA,oDAAC,SAAI,WAAW,OAAO,UAAU,OAAO,EAAE,MAAM,GAC7C,gBACH;AAAA,QAEA,6CAAC,SAAI,WAAW,OAAO,UACpB;AAAA,2BAAiB,CAAC,UACjB;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,WAAW,OAAO;AAAA,cAElB,sDAAC,uBAAQ,OAAO,UACd,sDAAC,SAAI,WAAW,OAAO,UACpB,mBAAS,SAAS,KACf,GAAG,SAAS,UAAU,GAAG,EAAE,SAC3B,UACN,GACF;AAAA;AAAA,UACF,IAEA,4CAAC,uBAAQ,OAAO,UACd,sDAAC,SAAI,WAAW,OAAO,UACpB,mBAAS,SAAS,KACf,GAAG,SAAS,UAAU,GAAG,EAAE,SAC3B,UACN,GACF;AAAA,UAGD,KAAK,WAAW,cACf;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,KAAK;AAAA,cACd,MAAK;AAAA,cACL,UAAU;AAAA,cACV,aAAY;AAAA,cACZ,WAAW,OAAO;AAAA;AAAA,UACpB,IAEA,WAAW,KACT,4CAAC,SAAI,WAAW,OAAO,UAAW,yBAAe,QAAQ,GAAE;AAAA,UAI9D,KAAK,WAAW,WAAW,KAAK,gBAC/B;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,OAAO;AAAA,gBACP,WAAW;AAAA,cACb;AAAA,cAEC,eAAK;AAAA;AAAA,UACR;AAAA,WAEJ;AAAA,QAEC,aACC;AAAA,UAAC;AAAA;AAAA,YACC,WAAW,OAAO;AAAA,YAClB,SAAS,MAAM,SAAS,MAAM;AAAA,YAC9B,UAAU,KAAK,WAAW;AAAA,YAC1B,cAAW;AAAA,YAEX,sDAAC,8BAAc;AAAA;AAAA,QACjB;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEA,IAAO,sBAAQ;",
4
+ "sourcesContent": ["import React, { useState, useEffect, useMemo } from \"react\";\nimport { Image, Tooltip, Progress } from \"antd\";\nimport {\n FileOutlined,\n FilePdfOutlined,\n FileWordOutlined,\n FileExcelOutlined,\n FilePptOutlined,\n FileImageOutlined,\n CloseOutlined,\n AudioOutlined,\n FileZipOutlined,\n VideoCameraOutlined,\n FileMarkdownOutlined,\n PictureOutlined,\n} from \"@ant-design/icons\";\nimport {\n FileItem,\n FileGalleryProps,\n FileIconType,\n ImageDisplayMode,\n FileCardType,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\n\n// ==================== 工具函数 ====================\n\nconst getFileName = (file: FileItem): string =>\n file.displayName || file.name || \"\";\n\nconst getFileSize = (file: FileItem): number => file.size || 0;\n\nconst getMimeType = (file: FileItem): string =>\n file.mimeType || file.type || \"\";\n\nconst getFileUrl = (file: FileItem): string =>\n file.fileUri ||\n file.response?.fileUrl ||\n file.response?.tempUrl ||\n file.tempUrl ||\n \"\";\n\nconst getFileId = (file: FileItem): string => file.id || file.uid || \"\";\n\nconst getFileExtension = (filename: string): string => {\n const ext = filename.split(\".\").pop();\n return ext ? ext.toLowerCase() : \"\";\n};\n\nconst IMAGE_EXTS = [\"jpg\", \"jpeg\", \"png\", \"gif\", \"webp\", \"bmp\", \"svg\"];\nconst AUDIO_EXTS = [\"mp3\", \"wav\", \"m4a\", \"aac\", \"ogg\", \"flac\"];\nconst VIDEO_EXTS = [\"mp4\", \"mov\", \"webm\", \"mkv\", \"avi\"];\n\n/** 自动推断文件卡片类型 */\nconst inferFileType = (file: FileItem): FileCardType => {\n const mimeType = getMimeType(file);\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n if (mimeType.startsWith(\"video/\")) return \"video\";\n\n const ext = getFileExtension(getFileName(file));\n if (IMAGE_EXTS.includes(ext)) return \"image\";\n if (AUDIO_EXTS.includes(ext)) return \"audio\";\n if (VIDEO_EXTS.includes(ext)) return \"video\";\n\n // URL 扩展名兜底\n const url = getFileUrl(file);\n const urlExtMatch = url.match(/\\.(\\w+)(\\?.*)?$/);\n if (urlExtMatch) {\n const urlExt = urlExtMatch[1].toLowerCase();\n if (IMAGE_EXTS.includes(urlExt)) return \"image\";\n if (AUDIO_EXTS.includes(urlExt)) return \"audio\";\n if (VIDEO_EXTS.includes(urlExt)) return \"video\";\n }\n\n return \"file\";\n};\n\n/** 根据扩展名获取文件图标类型 key */\nconst getFileIconType = (file: FileItem): FileIconType => {\n const ext = getFileExtension(getFileName(file));\n if (ext === \"pdf\") return \"pdf\";\n if ([\"doc\", \"docx\"].includes(ext)) return \"word\";\n if ([\"xls\", \"xlsx\", \"csv\"].includes(ext)) return \"excel\";\n if ([\"ppt\", \"pptx\"].includes(ext)) return \"ppt\";\n if (AUDIO_EXTS.includes(ext)) return \"audio\";\n if (VIDEO_EXTS.includes(ext)) return \"video\";\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\", \"bz2\", \"xz\", \"tgz\"].includes(ext))\n return \"zip\";\n if ([\"md\", \"markdown\"].includes(ext)) return \"markdown\";\n if (IMAGE_EXTS.includes(ext)) return \"image\";\n return \"default\";\n};\n\n/** 默认图标映射 */\nconst DEFAULT_ICON_MAP: Record<\n FileIconType,\n { icon: React.ReactNode; color: string }\n> = {\n pdf: { icon: <FilePdfOutlined />, color: \"#ff4d4f\" },\n word: { icon: <FileWordOutlined />, color: \"#1677ff\" },\n excel: { icon: <FileExcelOutlined />, color: \"#22b35e\" },\n ppt: { icon: <FilePptOutlined />, color: \"#ff6e31\" },\n audio: { icon: <AudioOutlined />, color: \"#722ed1\" },\n video: { icon: <VideoCameraOutlined />, color: \"#fa8c16\" },\n zip: { icon: <FileZipOutlined />, color: \"#eb2f96\" },\n markdown: { icon: <FileMarkdownOutlined />, color: \"#13c2c2\" },\n image: { icon: <FileImageOutlined />, color: \"#8c8c8c\" },\n default: { icon: <FileOutlined />, color: \"#8c8c8c\" },\n};\n\nconst formatFileSize = (bytes: number): string => {\n if (bytes < 1024) return bytes + \" B\";\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + \" KB\";\n return (bytes / (1024 * 1024)).toFixed(1) + \" MB\";\n};\n\nconst FALLBACK_IMAGE =\n \"data:image/png;base64,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\";\n\n// ==================== 子组件:图片加载状态管理 ====================\n\nconst ImageWithLoading: React.FC<{\n src: string;\n alt: string;\n width?: number | string;\n height?: number | string;\n loading?: \"lazy\" | \"eager\";\n preview?: false | { src: string };\n fallback?: string;\n displayMode: ImageDisplayMode;\n styles: ReturnType<typeof useStyles>;\n}> = ({\n src,\n alt,\n width,\n height,\n loading,\n preview,\n fallback,\n displayMode,\n styles,\n}) => {\n const [loadState, setLoadState] = useState<\n \"loading\" | \"loaded\" | \"error\"\n >(\"loading\");\n\n useEffect(() => {\n setLoadState(\"loading\");\n }, [src]);\n\n const modeClass =\n displayMode === \"full\"\n ? styles.imageFullMode\n : displayMode === \"preview\"\n ? styles.imagePreviewMode\n : styles.imageThumbnail;\n\n const containerStyle: React.CSSProperties = {};\n if (width)\n containerStyle.width = typeof width === \"number\" ? `${width}px` : width;\n if (height)\n containerStyle.height = typeof height === \"number\" ? `${height}px` : height;\n\n return (\n <div className={modeClass} style={containerStyle}>\n {loadState === \"loading\" && (\n <div className={styles.imageLoadingSkeleton}>\n <PictureOutlined style={{ fontSize: 20, color: \"#d9d9d9\" }} />\n </div>\n )}\n\n {loadState === \"error\" && (\n <div className={styles.imageErrorFallback}>\n <PictureOutlined />\n <span>加载失败</span>\n </div>\n )}\n\n <Image\n src={src}\n alt={alt}\n fallback={fallback}\n preview={preview}\n loading={loading}\n style={{\n display: loadState === \"error\" ? \"none\" : \"block\",\n opacity: loadState === \"loading\" ? 0 : 1,\n transition: \"opacity 0.3s ease\",\n ...(displayMode === \"thumbnail\"\n ? { width: \"100%\", height: \"100%\", objectFit: \"cover\" }\n : { maxWidth: \"100%\", objectFit: \"contain\" }),\n }}\n onLoad={() => setLoadState(\"loaded\")}\n onError={() => setLoadState(\"error\")}\n />\n </div>\n );\n};\n\n// ==================== 主组件 ====================\n\nconst FileGallery: React.FC<FileGalleryProps> = ({\n file,\n align = \"left\",\n removable = false,\n onRemove = () => {},\n className,\n style,\n onClick,\n type: customType,\n // 图片相关\n imageDisplayMode = \"thumbnail\",\n imageWidth,\n imageHeight,\n imageLoading = \"eager\",\n imageAlt,\n // 音视频相关\n mediaAutoPlay = false,\n mediaLoop = false,\n mediaMuted = false,\n mediaPoster,\n videoProps,\n audioProps,\n // 自定义图标\n iconMap,\n customIcon,\n}) => {\n const styles = useStyles();\n const [objectUrl, setObjectUrl] = useState(\"\");\n\n useEffect(() => {\n if (!file?.file) return;\n const url = URL.createObjectURL(file.file);\n setObjectUrl(url);\n return () => URL.revokeObjectURL(url);\n }, [file?.file]);\n\n if (!file) return null;\n\n const fileName = getFileName(file);\n const fileSize = getFileSize(file);\n const fileId = getFileId(file);\n const url = getFileUrl(file) || objectUrl;\n\n // 核心逻辑:type prop 决定渲染方式(参考 file-card)\n // - 不传 type:自动推断,图片/音频/视频用原生渲染\n // - type=\"file\":强制附件卡片(音视频不可播放)\n // - type=\"image\"/\"audio\"/\"video\":强制指定类型\n const fileType = useMemo<FileCardType>(\n () => customType || inferFileType(file),\n [customType, file],\n );\n\n /** 获取图标(支持自定义) */\n const getIcon = (\n iconType: FileIconType,\n ): { icon: React.ReactNode; color: string } => {\n if (customIcon) return { icon: customIcon, color: \"inherit\" };\n if (iconMap?.[iconType])\n return { icon: iconMap[iconType]!, color: \"inherit\" };\n return DEFAULT_ICON_MAP[iconType];\n };\n\n // ==================== 渲染删除按钮 ====================\n const renderRemoveBtn = () =>\n removable ? (\n <button\n className={styles.fileRemoveBtn}\n onClick={(e) => {\n e.stopPropagation();\n onRemove(fileId);\n }}\n disabled={file.status === \"uploading\"}\n aria-label=\"删除文件\"\n >\n <CloseOutlined />\n </button>\n ) : null;\n\n // ==================== 渲染上传进度遮罩 ====================\n const renderUploadOverlay = () =>\n file.status === \"uploading\" ? (\n <div className={styles.imageOverlay}>\n <Progress\n type=\"circle\"\n percent={file.progress}\n size={30}\n strokeColor=\"#1677ff\"\n />\n </div>\n ) : null;\n\n // ==================== 附件卡片渲染(type=\"file\" 或普通文档) ====================\n const renderFileCard = () => {\n const iconType = getFileIconType(file);\n const { icon, color } = getIcon(iconType);\n const isExternalUrl = url && url.startsWith(\"http\");\n\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <div className={styles.fileIcon} style={{ color }}>\n {icon}\n </div>\n\n <div className={styles.fileInfo}>\n {isExternalUrl && !onClick ? (\n <a\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={styles.fileLink}\n >\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n </a>\n ) : (\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n )}\n\n {file.status === \"uploading\" ? (\n <Progress\n percent={file.progress}\n size=\"small\"\n showInfo={false}\n strokeColor=\"#1677ff\"\n className={styles.progress}\n />\n ) : (\n fileSize > 0 && (\n <div className={styles.fileSize}>\n {formatFileSize(fileSize)}\n </div>\n )\n )}\n\n {file.status === \"error\" && file.errorMessage && (\n <div\n style={{ fontSize: \"11px\", color: \"#ff4d4f\", marginTop: \"2px\" }}\n >\n {file.errorMessage}\n </div>\n )}\n </div>\n\n {renderRemoveBtn()}\n </div>\n );\n };\n\n // ==================== 图片渲染 ====================\n if (fileType === \"image\") {\n // full / preview 模式:独立展示\n if (imageDisplayMode === \"full\" || imageDisplayMode === \"preview\") {\n const containerStyle: React.CSSProperties = { ...style };\n if (imageWidth)\n containerStyle.width =\n typeof imageWidth === \"number\" ? `${imageWidth}px` : imageWidth;\n if (imageHeight)\n containerStyle.height =\n typeof imageHeight === \"number\" ? `${imageHeight}px` : imageHeight;\n\n return (\n <div\n className={`${imageDisplayMode === \"full\" ? styles.imageFullMode : styles.imagePreviewMode} ${className || \"\"}`}\n style={containerStyle}\n >\n <ImageWithLoading\n src={url}\n alt={imageAlt || fileName}\n displayMode={imageDisplayMode}\n loading={imageLoading}\n preview={onClick ? false : { src: url }}\n fallback={FALLBACK_IMAGE}\n styles={styles}\n />\n {renderUploadOverlay()}\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // thumbnail 模式:卡片形式\n return (\n <div\n className={`${styles.fileCard} ${align === \"right\" ? \"align-right\" : \"\"} ${className || \"\"}`}\n style={{ ...style, cursor: onClick ? \"pointer\" : undefined }}\n onClick={() => onClick?.(file)}\n >\n <ImageWithLoading\n src={url}\n alt={imageAlt || fileName}\n width={imageWidth}\n height={imageHeight}\n displayMode=\"thumbnail\"\n loading={imageLoading}\n preview={onClick ? false : { src: url }}\n fallback={FALLBACK_IMAGE}\n styles={styles}\n />\n {renderUploadOverlay()}\n\n <div className={styles.fileInfo}>\n <Tooltip title={fileName}>\n <div className={styles.fileName}>\n {fileName.length > 15\n ? `${fileName.substring(0, 15)}...`\n : fileName}\n </div>\n </Tooltip>\n {Number(file?.size) > 0 && (\n <div className={styles.fileSize}>{formatFileSize(fileSize)}</div>\n )}\n </div>\n\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 音频渲染(原生播放器,无卡片包裹) ====================\n if (fileType === \"audio\") {\n return (\n <div\n className={`file-gallery-audio ${className || \"\"}`}\n style={{ position: \"relative\", width: 268, ...style }}\n >\n <audio\n src={url}\n controls\n autoPlay={mediaAutoPlay}\n loop={mediaLoop}\n muted={mediaMuted}\n style={{ width: \"100%\" }}\n {...audioProps}\n />\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 视频渲染(原生播放器,无卡片包裹) ====================\n if (fileType === \"video\") {\n return (\n <div\n className={`file-gallery-video ${className || \"\"}`}\n style={{ position: \"relative\", width: 268, ...style }}\n >\n <video\n src={url}\n controls\n autoPlay={mediaAutoPlay}\n loop={mediaLoop}\n muted={mediaMuted}\n poster={mediaPoster}\n style={{\n width: \"100%\",\n aspectRatio: \"16 / 9\",\n borderRadius: 8,\n background: \"#000\",\n }}\n {...videoProps}\n />\n {renderRemoveBtn()}\n </div>\n );\n }\n\n // ==================== 其他文件(附件卡片) ====================\n return renderFileCard();\n};\n\nexport default FileGallery;\n"],
5
+ "mappings": "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",
6
6
  "names": ["url"]
7
7
  }
@@ -12,6 +12,11 @@ export declare const useStyles: () => {
12
12
  fileRemoveBtn: string;
13
13
  fileLink: string;
14
14
  mediaWrapper: string;
15
+ imagePreviewMode: string;
16
+ imageFullMode: string;
17
+ imageLoadingSkeleton: string;
18
+ imageErrorFallback: string;
19
+ mediaCardPlayIcon: string;
15
20
  } & {
16
21
  w: (width: string | number) => string;
17
22
  h: (height: string | number) => string;
@@ -184,6 +184,112 @@ var useStyles = (0, import_common.withBasicStyles)(() => ({
184
184
  `,
185
185
  mediaWrapper: import_css.css`
186
186
  margin-top: 6px;
187
+
188
+ audio {
189
+ width: 100%;
190
+ height: 32px;
191
+ outline: none;
192
+ }
193
+
194
+ video {
195
+ width: 100%;
196
+ max-height: 240px;
197
+ border-radius: 4px;
198
+ outline: none;
199
+ background: #000;
200
+ }
201
+ `,
202
+ // ========== 图片展示模式 ==========
203
+ imagePreviewMode: import_css.css`
204
+ position: relative;
205
+ border-radius: 8px;
206
+ overflow: hidden;
207
+ background-color: #f5f5f5;
208
+ border: 1px solid rgba(0, 0, 0, 0.06);
209
+
210
+ .ant-image {
211
+ display: flex !important;
212
+ justify-content: center;
213
+ align-items: center;
214
+ }
215
+
216
+ img {
217
+ display: block !important;
218
+ object-fit: contain !important;
219
+ }
220
+ `,
221
+ imageFullMode: import_css.css`
222
+ position: relative;
223
+ border-radius: 8px;
224
+ overflow: hidden;
225
+ background-color: #f5f5f5;
226
+ border: 1px solid rgba(0, 0, 0, 0.06);
227
+ width: 100%;
228
+
229
+ .ant-image {
230
+ width: 100% !important;
231
+ display: flex !important;
232
+ }
233
+
234
+ img {
235
+ width: 100% !important;
236
+ display: block !important;
237
+ object-fit: contain !important;
238
+ }
239
+ `,
240
+ // ========== 图片加载状态 ==========
241
+ imageLoadingSkeleton: import_css.css`
242
+ width: 100%;
243
+ height: 100%;
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: center;
247
+ background: linear-gradient(90deg, #f5f5f5 25%, #e8e8e8 50%, #f5f5f5 75%);
248
+ background-size: 200% 100%;
249
+ animation: shimmer 1.5s infinite;
250
+
251
+ @keyframes shimmer {
252
+ 0% {
253
+ background-position: 200% 0;
254
+ }
255
+ 100% {
256
+ background-position: -200% 0;
257
+ }
258
+ }
259
+ `,
260
+ imageErrorFallback: import_css.css`
261
+ width: 100%;
262
+ height: 100%;
263
+ display: flex;
264
+ flex-direction: column;
265
+ align-items: center;
266
+ justify-content: center;
267
+ background: #fafafa;
268
+ color: #bfbfbf;
269
+ font-size: 20px;
270
+ gap: 4px;
271
+
272
+ span {
273
+ font-size: 11px;
274
+ color: #bfbfbf;
275
+ }
276
+ `,
277
+ // ========== Media Card 模式 ==========
278
+ mediaCardPlayIcon: import_css.css`
279
+ position: absolute;
280
+ top: 50%;
281
+ left: 50%;
282
+ transform: translate(-50%, -50%);
283
+ width: 28px;
284
+ height: 28px;
285
+ border-radius: 50%;
286
+ background: rgba(0, 0, 0, 0.5);
287
+ color: #fff;
288
+ display: flex;
289
+ align-items: center;
290
+ justify-content: center;
291
+ font-size: 12px;
292
+ z-index: 2;
187
293
  `
188
294
  }));
189
295
  var styles_default = useStyles;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/FileGallery/styles.tsx"],
4
- "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n container: css`\n padding: 12px 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n &.align-right {\n align-items: flex-end;\n }\n `,\n\n fileList: css`\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n `,\n\n fileCard: css`\n position: relative;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n margin: 8px 0;\n background: #fafafa;\n border: 1px solid #f0f0f0;\n border-radius: 8px;\n min-width: 260px;\n max-width: 280px;\n min-height: 64px;\n transition: all 0.2s ease;\n\n &:hover {\n background: #f5f5f5;\n border-color: #e0e0e0;\n }\n\n /* align=right 时图标在右侧 */\n &.align-right {\n flex-direction: row-reverse;\n }\n `,\n\n imageThumbnail: css`\n position: relative;\n width: 44px;\n height: 44px;\n flex-shrink: 0;\n border-radius: 4px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n width: 100% !important;\n height: 100% !important;\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n width: 100% !important;\n height: 100% !important;\n object-fit: cover !important;\n display: block !important;\n }\n `,\n\n imageOverlay: css`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.05);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n `,\n\n fileIcon: css`\n font-size: 24px;\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n `,\n\n fileInfo: css`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n `,\n\n fileName: css`\n font-size: 13px;\n font-weight: 500;\n color: #262626;\n margin-bottom: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n\n fileSize: css`\n font-size: 11px;\n color: #8c8c8c;\n `,\n\n progress: css`\n margin-top: 4px;\n\n .ant-progress-inner {\n height: 4px !important;\n }\n\n .ant-progress-bg {\n height: 4px !important;\n }\n `,\n\n fileRemoveBtn: css`\n position: absolute;\n top: -6px;\n right: -6px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 1;\n padding: 0;\n font-size: 10px;\n transition: all 0.2s ease;\n\n &:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: scale(1.1);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n\n fileLink: css`\n display: flex;\n align-items: center;\n gap: 8px;\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n font-size: 13px;\n\n &:hover {\n color: #1677ff;\n }\n `,\n\n mediaWrapper: css`\n margin-top: 6px;\n `,\n}));\n\nexport default useStyles;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWX,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BV,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BhB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAad,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUV,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYV,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8Bf,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaV,cAAc;AAAA;AAAA;AAGhB,EAAE;AAEF,IAAO,iBAAQ;",
4
+ "sourcesContent": ["import { css } from \"@emotion/css\";\nimport { withBasicStyles } from \"@/styles/common\";\n\nexport const useStyles = withBasicStyles(() => ({\n container: css`\n padding: 12px 0;\n display: flex;\n flex-direction: column;\n gap: 12px;\n\n &.align-right {\n align-items: flex-end;\n }\n `,\n\n fileList: css`\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n `,\n\n fileCard: css`\n position: relative;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 12px;\n margin: 8px 0;\n background: #fafafa;\n border: 1px solid #f0f0f0;\n border-radius: 8px;\n min-width: 260px;\n max-width: 280px;\n min-height: 64px;\n transition: all 0.2s ease;\n\n &:hover {\n background: #f5f5f5;\n border-color: #e0e0e0;\n }\n\n /* align=right 时图标在右侧 */\n &.align-right {\n flex-direction: row-reverse;\n }\n `,\n\n imageThumbnail: css`\n position: relative;\n width: 44px;\n height: 44px;\n flex-shrink: 0;\n border-radius: 4px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n width: 100% !important;\n height: 100% !important;\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n width: 100% !important;\n height: 100% !important;\n object-fit: cover !important;\n display: block !important;\n }\n `,\n\n imageOverlay: css`\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.05);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n `,\n\n fileIcon: css`\n font-size: 24px;\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n `,\n\n fileInfo: css`\n flex: 1;\n min-width: 0;\n overflow: hidden;\n `,\n\n fileName: css`\n font-size: 13px;\n font-weight: 500;\n color: #262626;\n margin-bottom: 4px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n `,\n\n fileSize: css`\n font-size: 11px;\n color: #8c8c8c;\n `,\n\n progress: css`\n margin-top: 4px;\n\n .ant-progress-inner {\n height: 4px !important;\n }\n\n .ant-progress-bg {\n height: 4px !important;\n }\n `,\n\n fileRemoveBtn: css`\n position: absolute;\n top: -6px;\n right: -6px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.75);\n color: #fff;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n z-index: 1;\n padding: 0;\n font-size: 10px;\n transition: all 0.2s ease;\n\n &:hover {\n background: rgba(0, 0, 0, 0.9);\n transform: scale(1.1);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n `,\n\n fileLink: css`\n display: flex;\n align-items: center;\n gap: 8px;\n color: rgba(0, 0, 0, 0.85);\n text-decoration: none;\n font-size: 13px;\n\n &:hover {\n color: #1677ff;\n }\n `,\n\n mediaWrapper: css`\n margin-top: 6px;\n\n audio {\n width: 100%;\n height: 32px;\n outline: none;\n }\n\n video {\n width: 100%;\n max-height: 240px;\n border-radius: 4px;\n outline: none;\n background: #000;\n }\n `,\n\n // ========== 图片展示模式 ==========\n imagePreviewMode: css`\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n\n .ant-image {\n display: flex !important;\n justify-content: center;\n align-items: center;\n }\n\n img {\n display: block !important;\n object-fit: contain !important;\n }\n `,\n\n imageFullMode: css`\n position: relative;\n border-radius: 8px;\n overflow: hidden;\n background-color: #f5f5f5;\n border: 1px solid rgba(0, 0, 0, 0.06);\n width: 100%;\n\n .ant-image {\n width: 100% !important;\n display: flex !important;\n }\n\n img {\n width: 100% !important;\n display: block !important;\n object-fit: contain !important;\n }\n `,\n\n // ========== 图片加载状态 ==========\n imageLoadingSkeleton: css`\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(90deg, #f5f5f5 25%, #e8e8e8 50%, #f5f5f5 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n\n @keyframes shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\n }\n `,\n\n imageErrorFallback: css`\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n color: #bfbfbf;\n font-size: 20px;\n gap: 4px;\n\n span {\n font-size: 11px;\n color: #bfbfbf;\n }\n `,\n\n // ========== Media Card 模式 ==========\n mediaCardPlayIcon: css`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.5);\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n z-index: 2;\n `,\n}));\n\nexport default useStyles;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAoB;AACpB,oBAAgC;AAEzB,IAAM,gBAAY,+BAAgB,OAAO;AAAA,EAC9C,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWX,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BV,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BhB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAad,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUV,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYV,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8Bf,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaV,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBd,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBlB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBf,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBtB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBpB,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBrB,EAAE;AAEF,IAAO,iBAAQ;",
6
6
  "names": []
7
7
  }
@@ -44,12 +44,13 @@ var Sender = (0, import_react.forwardRef)((props, ref) => {
44
44
  import_XAdkSender.default,
45
45
  {
46
46
  ref,
47
+ ...props,
47
48
  loading,
49
+ disabled: loading || props.disabled,
48
50
  onSubmit: chat,
49
51
  onStop: stopChat,
50
52
  onClear: clearChat,
51
- uploadRequest,
52
- ...props
53
+ uploadRequest
53
54
  }
54
55
  );
55
56
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/components/XAdkProvider/compound/Sender.tsx"],
4
- "sourcesContent": ["import React, { forwardRef } from 'react';\nimport XAdkSender from '@/components/XAdkSender';\nimport { useChatState } from '../context/ChatStateContext';\nimport { useChatActions } from '../context/ChatActionContext';\nimport type { XAdkSenderProps, XAdkSenderHandle } from '@/types';\n\n/**\n * XAdkProvider.Sender - 输入框组件\n *\n * 从 Context 获取聊天动作并提供输入界面\n * 基于 XAdkSender 组件实现\n *\n * @example\n * ```tsx\n * <XAdkProvider url=\"...\" token=\"...\">\n * <XAdkProvider.Sender\n * allowUpload={true}\n * clearBtnShow={true}\n * uploadRequest={myUploadHandler}\n * />\n * </XAdkProvider>\n * ```\n */\nexport interface XAdkSenderCompoundProps extends Partial<Omit<XAdkSenderProps, 'loading' | 'onSubmit' | 'onStop' | 'onClear'>> {\n /** 额外的样式 */\n style?: React.CSSProperties;\n /** 额外的类名 */\n className?: string;\n}\n\nconst Sender = forwardRef<XAdkSenderHandle, XAdkSenderCompoundProps>((props, ref) => {\n const { loading, uploadRequest } = useChatState();\n const { chat, stopChat, clearChat } = useChatActions();\n\n return (\n <XAdkSender\n ref={ref}\n loading={loading}\n onSubmit={chat}\n onStop={stopChat}\n onClear={clearChat}\n uploadRequest={uploadRequest}\n {...props}\n />\n );\n});\n\nSender.displayName = 'XAdkProvider.Sender';\n\nexport default Sender;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,wBAAuB;AACvB,8BAA6B;AAC7B,+BAA+B;AAgC3B;AALJ,IAAM,aAAS,yBAAsD,CAAC,OAAO,QAAQ;AACnF,QAAM,EAAE,SAAS,cAAc,QAAI,sCAAa;AAChD,QAAM,EAAE,MAAM,UAAU,UAAU,QAAI,yCAAe;AAErD,SACE;AAAA,IAAC,kBAAAA;AAAA,IAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;AAED,OAAO,cAAc;AAErB,IAAO,iBAAQ;",
4
+ "sourcesContent": ["import React, { forwardRef } from 'react';\nimport XAdkSender from '@/components/XAdkSender';\nimport { useChatState } from '../context/ChatStateContext';\nimport { useChatActions } from '../context/ChatActionContext';\nimport type { XAdkSenderProps, XAdkSenderHandle } from '@/types';\n\n/**\n * XAdkProvider.Sender - 输入框组件\n *\n * 从 Context 获取聊天动作并提供输入界面\n * 基于 XAdkSender 组件实现\n *\n * @example\n * ```tsx\n * <XAdkProvider url=\"...\" token=\"...\">\n * <XAdkProvider.Sender\n * allowUpload={true}\n * clearBtnShow={true}\n * uploadRequest={myUploadHandler}\n * />\n * </XAdkProvider>\n * ```\n */\nexport interface XAdkSenderCompoundProps extends Partial<Omit<XAdkSenderProps, 'loading' | 'onSubmit' | 'onStop' | 'onClear'>> {\n /** 额外的样式 */\n style?: React.CSSProperties;\n /** 额外的类名 */\n className?: string;\n}\n\nconst Sender = forwardRef<XAdkSenderHandle, XAdkSenderCompoundProps>((props, ref) => {\n const { loading, uploadRequest } = useChatState();\n const { chat, stopChat, clearChat } = useChatActions();\n\n return (\n <XAdkSender\n ref={ref}\n {...props}\n loading={loading}\n disabled={loading || props.disabled}\n onSubmit={chat}\n onStop={stopChat}\n onClear={clearChat}\n uploadRequest={uploadRequest}\n />\n );\n});\n\nSender.displayName = 'XAdkProvider.Sender';\n\nexport default Sender;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAkC;AAClC,wBAAuB;AACvB,8BAA6B;AAC7B,+BAA+B;AAgC3B;AALJ,IAAM,aAAS,yBAAsD,CAAC,OAAO,QAAQ;AACnF,QAAM,EAAE,SAAS,cAAc,QAAI,sCAAa;AAChD,QAAM,EAAE,MAAM,UAAU,UAAU,QAAI,yCAAe;AAErD,SACE;AAAA,IAAC,kBAAAA;AAAA,IAAA;AAAA,MACC;AAAA,MACC,GAAG;AAAA,MACJ;AAAA,MACA,UAAU,WAAW,MAAM;AAAA,MAC3B,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA;AAAA,EACF;AAEJ,CAAC;AAED,OAAO,cAAc;AAErB,IAAO,iBAAQ;",
6
6
  "names": ["XAdkSender"]
7
7
  }
@@ -403,6 +403,7 @@ var XAdkSender = (0, import_react.forwardRef)(({
403
403
  import_FileGallery.default,
404
404
  {
405
405
  file,
406
+ type: "file",
406
407
  removable: true,
407
408
  onRemove: handleRemoveFile
408
409
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/XAdkSender/index.tsx"],
4
- "sourcesContent": ["import React, { useState, useRef, useCallback, forwardRef, useImperativeHandle } from \"react\";\nimport { Popconfirm, message, Tooltip, Input, Modal } from \"antd\";\nimport {\n ClearOutlined,\n LoadingOutlined,\n ArrowUpOutlined,\n PaperClipOutlined,\n} from \"@ant-design/icons\";\nimport {\n XAdkSenderProps,\n XAdkSenderHandle,\n ServerFile,\n LocalFile,\n ActionsComponents,\n FileValidator,\n UploadFileResult,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\nimport FileGallery from \"../FileGallery\";\nimport { getExt } from \"@/utils/file\";\n\nconst XAdkSender = forwardRef<XAdkSenderHandle, XAdkSenderProps>(({\n clearBtnShow = true,\n allowUpload = false,\n draggable = true,\n showMask = true,\n loading = false,\n disabled = false,\n value: controlledValue,\n defaultValue = \"\",\n uploadRequest = () => {},\n onClear,\n onChange,\n onSubmit,\n onStop,\n onFilesChange,\n onUploadSuccess,\n onUploadError,\n maxFileSize = 10,\n validators: customValidators = [],\n // allowedFileTypes = [\n // \"image/*\",\n // \"audio/*\",\n // \"video/*\",\n // \"application/pdf\",\n // \"text/plain\",\n // \".doc\",\n // \".docx\",\n // \".xls\",\n // \".xlsx\",\n // \".ppt\",\n // \".pptx\",\n // \"\",\n // ],\n allowedFileTypes = [],\n maxFiles = Infinity,\n sendButtonRender,\n suffix,\n header,\n prefix,\n footer,\n}, ref) => {\n const styles = useStyles();\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<string>(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const setValue = (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n const [files, setFiles] = useState<LocalFile[]>([]);\n const [isDragOver, setIsDragOver] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // 生成唯一ID\n const generateId = () => {\n return Date.now().toString(36) + Math.random().toString(36).substr(2);\n };\n\n const normalizeUploadResponse = (response: any): UploadFileResult => {\n const data = response?.data ?? response;\n return (Array.isArray(data) ? data[0] : data) ?? {};\n };\n\n // 检查文件类型\n const checkFileType = (file: File): boolean => {\n if (allowedFileTypes?.length > 0) {\n const ext = getExt(file);\n\n return allowedFileTypes.some((type) => {\n // 1️⃣ MIME 校验\n if (type.includes(\"/\")) {\n if (type.endsWith(\"/*\")) {\n return file.type.startsWith(type.split(\"/\")[0]);\n }\n return file.type === type;\n }\n\n if (type.startsWith(\".\")) {\n return ext === type.slice(1);\n }\n\n return false;\n });\n }\n return true;\n };\n\n // 检查文件大小\n const checkFileSize = (file: File): boolean => {\n const maxSize = maxFileSize * 1024 * 1024;\n return file.size <= maxSize;\n };\n\n // 重复文件检测\n const isDuplicateFile = (file: File, files: LocalFile[]) => {\n return files.some((f) => f.name === file.name && f.size === file.size);\n };\n\n // 内置校验器集合\n const builtInValidators: FileValidator[] = [\n // 数量校验(修复批量 bug)\n (_file, { files }) => {\n if (files.length >= maxFiles) {\n return `最多只能上传 ${maxFiles} 个文件`;\n }\n return null;\n },\n\n // 大小校验\n (file) => {\n const maxSize = maxFileSize * 1024 * 1024;\n if (file.size > maxSize) {\n return `文件大小不能超过 ${maxFileSize}MB`;\n }\n return null;\n },\n\n // 类型校验\n (file) => {\n if (!checkFileType(file)) {\n return \"不支持的文件类型\";\n }\n return null;\n },\n\n // ⭐ 新增:去重校验\n (file, { files }) => {\n if (isDuplicateFile(file, files)) {\n return \"文件已存在\";\n }\n return null;\n },\n ];\n\n const allValidators = [...builtInValidators, ...customValidators];\n\n // 验证文件\n const validateFile = (file: File): { valid: boolean; message?: string } => {\n for (const validator of allValidators) {\n const error = validator(file, { files });\n if (error) {\n return { valid: false, message: error };\n }\n }\n return { valid: true };\n };\n\n // 处理文件选择\n const handleFileSelect = useCallback(\n (selectedFiles: File[]) => {\n const fileArray = Array.from(selectedFiles);\n\n if (files.length + fileArray.length > maxFiles) {\n message.error(`最多只能上传 ${maxFiles} 个文件`);\n return;\n }\n\n const validFiles: LocalFile[] = [];\n\n fileArray.forEach((file) => {\n const validation = validateFile(file);\n\n if (validation.valid) {\n validFiles.push({\n id: generateId(),\n uid: generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n file,\n progress: 0,\n status: \"pending\",\n response: null,\n });\n } else {\n message.error(validation.message);\n }\n });\n\n if (validFiles.length > 0) {\n setFiles((prev) => {\n const next = [...prev, ...validFiles];\n onFilesChange?.(next);\n return next;\n });\n uploadFiles(validFiles);\n }\n },\n [files, maxFiles, maxFileSize, allowedFileTypes],\n );\n\n // 暴露 addFiles 方法供外层(如 DefaultLayout 拖拽上传)调用\n useImperativeHandle(ref, () => ({\n addFiles: (rawFiles: File[]) => {\n handleFileSelect(rawFiles);\n },\n }), [handleFileSelect]);\n\n // 上传文件\n const uploadFiles = async (fileList: LocalFile[]) => {\n for (const localFile of fileList) {\n // 开始上传\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, status: \"uploading\" } : f,\n ),\n );\n\n try {\n await uploadRequest({\n file: localFile.file,\n onProgress: (e) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, progress: e.percent } : f,\n ),\n );\n },\n onSuccess: (response) => {\n const responseData = normalizeUploadResponse(response);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"success\",\n progress: 100,\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url,\n }\n : f,\n ),\n );\n\n onUploadSuccess?.({\n ...localFile,\n status: \"success\",\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl || responseData.fileUrl || responseData.url,\n });\n },\n onError: (error) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage: error.message,\n }\n : f,\n ),\n );\n onUploadError?.(localFile, error);\n },\n });\n } catch (error) {\n console.error(\"上传处理错误:\", error);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage:\n error instanceof Error ? error.message : \"上传处理失败\",\n }\n : f,\n ),\n );\n message.error(`${localFile.name} 上传失败`);\n }\n }\n };\n\n // 删除文件\n const handleRemoveFile = (id: string) => {\n setFiles((prev) => {\n const next = prev.filter((file) => file.id !== id);\n\n onFilesChange?.(next);\n\n return next;\n });\n };\n\n // 触发文件选择\n const triggerFileSelect = () => {\n if (fileInputRef.current) {\n fileInputRef.current.click();\n }\n };\n\n // 处理拖拽事件\n const handleDragOver = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (allowUpload) {\n setIsDragOver(true);\n }\n },\n [allowUpload],\n );\n\n const handleDragLeave = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (allowUpload) {\n setIsDragOver(false);\n }\n },\n [allowUpload],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n\n if (\n allowUpload &&\n e.dataTransfer.files &&\n e.dataTransfer.files.length > 0\n ) {\n handleFileSelect(Array.from(e.dataTransfer.files));\n }\n },\n [allowUpload, handleFileSelect],\n );\n\n // 处理提交\n const handleSubmit = () => {\n if (!value.trim() && files.length === 0) {\n message.warning(\"请输入消息或选择文件\");\n return;\n }\n\n const successFiles = files.filter((file) => file.status === \"success\");\n const uploadingFiles = files.filter((file) => file.status === \"uploading\");\n\n if (uploadingFiles.length > 0) {\n Modal.confirm({\n title: \"文件上传中\",\n content: `还有 ${uploadingFiles.length} 个文件正在上传,是否继续发送?`,\n okText: \"发送已完成的\",\n cancelText: \"等待全部完成\",\n onOk: () => {\n const formattedFiles = formatFilesForServer(successFiles);\n if (onSubmit) {\n onSubmit({\n text: value,\n files: formattedFiles,\n });\n }\n\n setValue(\"\");\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n },\n onCancel: () => {\n message.info(\"请等待文件上传完成后再发送\");\n },\n });\n } else {\n const formattedFiles = formatFilesForServer(successFiles);\n\n if (onSubmit) {\n onSubmit({\n text: value,\n files: formattedFiles,\n });\n }\n\n setValue(\"\");\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n }\n };\n\n // 格式化文件列表为服务端格式\n const formatFilesForServer = (fileList: LocalFile[]): ServerFile[] => {\n return fileList\n .filter((file) => file.status === \"success\" && file.response)\n .map((file) => {\n const responseData = normalizeUploadResponse(file.response);\n\n return {\n fileName: responseData.fileName || file.name,\n fileId: responseData.fileId || responseData.id || \"\",\n tempUrl:\n responseData.tempUrl || responseData.fileUrl || responseData.url || \"\",\n type: responseData.fileType || responseData.type || getExt(file),\n size: responseData.fileSize || responseData.size || file.size,\n mimeType: responseData.mimeType || file.type,\n raw: {\n ...responseData,\n },\n };\n });\n };\n\n // 处理输入框变化\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setValue(newValue);\n };\n\n // 处理回车键\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n // 渲染文件列表 - 使用新的 FileGallery 组件\n const renderFileList = () => {\n if (files.length === 0) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n padding: \"12px 0\",\n }}\n >\n {files.map((file) => (\n <FileGallery\n key={file.id}\n file={file}\n removable\n onRemove={handleRemoveFile}\n />\n ))}\n </div>\n );\n };\n\n const containerClass = `${styles.container} ${isDragOver ? \"drag-over\" : \"\"} ${showMask ? 'show-mask' : ''}`;\n const uploading = files.some((f) => f.status === \"uploading\");\n const isDisabled = disabled || uploading || loading;\n const hasContent = value.trim().length > 0;\n const hasFiles = files.some((f) => f.status === \"success\");\n const canSend = hasContent || hasFiles;\n\n // 定义按钮组件(供外部 slot 函数通过 actionsComponents 使用)\n // 注意:sendButtonRender 的结果直接内联到 defaultSuffix 中,避免组件引用变化导致闪烁\n const SendButton = (props: any) => {\n if (sendButtonRender) {\n return (\n <>\n {sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })}\n </>\n );\n }\n return (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n {...props}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n );\n };\n\n const UploadButton = (props: any) => (\n <Tooltip title=\"上传文件\">\n <button\n className={`${styles.iconButton} ${styles.uploadButton}`}\n onClick={triggerFileSelect}\n disabled={isDisabled}\n aria-label=\"上传文件\"\n {...props}\n >\n <PaperClipOutlined />\n </button>\n </Tooltip>\n );\n\n const ClearButton = (props: any) => (\n <Popconfirm\n title=\"确定要清空聊天记录吗?\"\n onConfirm={onClear}\n placement=\"top\"\n okText=\"确定\"\n cancelText=\"取消\"\n disabled={isDisabled}\n >\n <button\n className={`${styles.iconButton} ${styles.clearButton}`}\n disabled={isDisabled}\n aria-label=\"清空聊天记录\"\n {...props}\n >\n <ClearOutlined />\n </button>\n </Popconfirm>\n );\n\n const actionsComponents: ActionsComponents = {\n SendButton,\n UploadButton,\n ClearButton,\n };\n\n // 渲染插槽内容\n const renderSlot = (\n slot:\n | React.ReactNode\n | false\n | ((\n oriNode: React.ReactNode,\n info: { components: ActionsComponents },\n ) => React.ReactNode | false)\n | undefined,\n oriNode: React.ReactNode,\n ): React.ReactNode | null => {\n if (slot === false) return null;\n if (slot === undefined) return oriNode;\n if (typeof slot === \"function\") {\n const result = slot(oriNode, { components: actionsComponents });\n return result === false ? null : result;\n }\n return slot;\n };\n\n // 默认的后缀内容(操作按钮组) - 直接内联渲染避免组件引用变化导致 unmount/remount\n const defaultSuffix = (\n <div className={styles.buttonGroup}>\n {allowUpload && (\n <Tooltip title=\"上传文件\">\n <button\n className={`${styles.iconButton} ${styles.uploadButton}`}\n onClick={triggerFileSelect}\n disabled={isDisabled}\n aria-label=\"上传文件\"\n >\n <PaperClipOutlined />\n </button>\n </Tooltip>\n )}\n {sendButtonRender ? (\n sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })\n ) : (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n )}\n </div>\n );\n\n return (\n <div\n ref={containerRef}\n className={containerClass}\n onDragOver={allowUpload && draggable ? handleDragOver : undefined}\n onDragLeave={allowUpload && draggable ? handleDragLeave : undefined}\n onDrop={allowUpload && draggable ? handleDrop : undefined}\n >\n {/* 头部插槽 */}\n {renderSlot(header, false)}\n\n {allowUpload && files.length > 0 && renderFileList()}\n\n {/* 隐藏的原生 file input */}\n {allowUpload && (\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept={allowedFileTypes.join(\",\")}\n style={{ display: \"none\" }}\n onChange={(e) => {\n if (e.target.files) {\n handleFileSelect(Array.from(e.target.files));\n e.target.value = \"\";\n }\n }}\n />\n )}\n\n <div className={styles.mainArea}>\n <div className={styles.senderWrap}>\n <div className={styles.inputAndButtons}>\n {/* 清除按钮 */}\n {clearBtnShow && <ClearButton />}\n {/* 前缀插槽 */}\n {renderSlot(prefix, false)}\n\n <div className={styles.textAreaWrapper}>\n <Input.TextArea\n className={styles.textArea}\n value={value}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n placeholder=\"请输入消息...\"\n disabled={isDisabled}\n autoSize={{ minRows: 1, maxRows: 4 }}\n style={{\n border: \"none\",\n boxShadow: \"none\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n\n {/* 后缀插槽(默认显示操作按钮) */}\n {renderSlot(suffix, defaultSuffix)}\n </div>\n\n {/* 底部插槽(默认显示提示文字) */}\n {renderSlot(\n footer,\n <div className={styles.tip}>\n 内容由AI生成,无法确保真实准确,仅供参考\n </div>,\n )}\n </div>\n </div>\n </div>\n );\n});\n\nXAdkSender.displayName = 'XAdkSender';\n\nimport XAdkSenderSwitch from \"./Switch\";\n\ntype XAdkSenderComponent = typeof XAdkSender & {\n Switch: typeof XAdkSenderSwitch;\n};\n\nconst CompoundSender = XAdkSender as XAdkSenderComponent;\nCompoundSender.Switch = XAdkSenderSwitch;\n\nexport default CompoundSender;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import React, { useState, useRef, useCallback, forwardRef, useImperativeHandle } from \"react\";\nimport { Popconfirm, message, Tooltip, Input, Modal } from \"antd\";\nimport {\n ClearOutlined,\n LoadingOutlined,\n ArrowUpOutlined,\n PaperClipOutlined,\n} from \"@ant-design/icons\";\nimport {\n XAdkSenderProps,\n XAdkSenderHandle,\n ServerFile,\n LocalFile,\n ActionsComponents,\n FileValidator,\n UploadFileResult,\n} from \"@/types\";\nimport { useStyles } from \"./styles\";\nimport FileGallery from \"../FileGallery\";\nimport { getExt } from \"@/utils/file\";\n\nconst XAdkSender = forwardRef<XAdkSenderHandle, XAdkSenderProps>(({\n clearBtnShow = true,\n allowUpload = false,\n draggable = true,\n showMask = true,\n loading = false,\n disabled = false,\n value: controlledValue,\n defaultValue = \"\",\n uploadRequest = () => {},\n onClear,\n onChange,\n onSubmit,\n onStop,\n onFilesChange,\n onUploadSuccess,\n onUploadError,\n maxFileSize = 10,\n validators: customValidators = [],\n // allowedFileTypes = [\n // \"image/*\",\n // \"audio/*\",\n // \"video/*\",\n // \"application/pdf\",\n // \"text/plain\",\n // \".doc\",\n // \".docx\",\n // \".xls\",\n // \".xlsx\",\n // \".ppt\",\n // \".pptx\",\n // \"\",\n // ],\n allowedFileTypes = [],\n maxFiles = Infinity,\n sendButtonRender,\n suffix,\n header,\n prefix,\n footer,\n}, ref) => {\n const styles = useStyles();\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState<string>(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const setValue = (newValue: string) => {\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(newValue);\n };\n const [files, setFiles] = useState<LocalFile[]>([]);\n const [isDragOver, setIsDragOver] = useState(false);\n const containerRef = useRef<HTMLDivElement>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n // 生成唯一ID\n const generateId = () => {\n return Date.now().toString(36) + Math.random().toString(36).substr(2);\n };\n\n const normalizeUploadResponse = (response: any): UploadFileResult => {\n const data = response?.data ?? response;\n return (Array.isArray(data) ? data[0] : data) ?? {};\n };\n\n // 检查文件类型\n const checkFileType = (file: File): boolean => {\n if (allowedFileTypes?.length > 0) {\n const ext = getExt(file);\n\n return allowedFileTypes.some((type) => {\n // 1️⃣ MIME 校验\n if (type.includes(\"/\")) {\n if (type.endsWith(\"/*\")) {\n return file.type.startsWith(type.split(\"/\")[0]);\n }\n return file.type === type;\n }\n\n if (type.startsWith(\".\")) {\n return ext === type.slice(1);\n }\n\n return false;\n });\n }\n return true;\n };\n\n // 检查文件大小\n const checkFileSize = (file: File): boolean => {\n const maxSize = maxFileSize * 1024 * 1024;\n return file.size <= maxSize;\n };\n\n // 重复文件检测\n const isDuplicateFile = (file: File, files: LocalFile[]) => {\n return files.some((f) => f.name === file.name && f.size === file.size);\n };\n\n // 内置校验器集合\n const builtInValidators: FileValidator[] = [\n // 数量校验(修复批量 bug)\n (_file, { files }) => {\n if (files.length >= maxFiles) {\n return `最多只能上传 ${maxFiles} 个文件`;\n }\n return null;\n },\n\n // 大小校验\n (file) => {\n const maxSize = maxFileSize * 1024 * 1024;\n if (file.size > maxSize) {\n return `文件大小不能超过 ${maxFileSize}MB`;\n }\n return null;\n },\n\n // 类型校验\n (file) => {\n if (!checkFileType(file)) {\n return \"不支持的文件类型\";\n }\n return null;\n },\n\n // ⭐ 新增:去重校验\n (file, { files }) => {\n if (isDuplicateFile(file, files)) {\n return \"文件已存在\";\n }\n return null;\n },\n ];\n\n const allValidators = [...builtInValidators, ...customValidators];\n\n // 验证文件\n const validateFile = (file: File): { valid: boolean; message?: string } => {\n for (const validator of allValidators) {\n const error = validator(file, { files });\n if (error) {\n return { valid: false, message: error };\n }\n }\n return { valid: true };\n };\n\n // 处理文件选择\n const handleFileSelect = useCallback(\n (selectedFiles: File[]) => {\n const fileArray = Array.from(selectedFiles);\n\n if (files.length + fileArray.length > maxFiles) {\n message.error(`最多只能上传 ${maxFiles} 个文件`);\n return;\n }\n\n const validFiles: LocalFile[] = [];\n\n fileArray.forEach((file) => {\n const validation = validateFile(file);\n\n if (validation.valid) {\n validFiles.push({\n id: generateId(),\n uid: generateId(),\n name: file.name,\n size: file.size,\n type: file.type,\n file,\n progress: 0,\n status: \"pending\",\n response: null,\n });\n } else {\n message.error(validation.message);\n }\n });\n\n if (validFiles.length > 0) {\n setFiles((prev) => {\n const next = [...prev, ...validFiles];\n onFilesChange?.(next);\n return next;\n });\n uploadFiles(validFiles);\n }\n },\n [files, maxFiles, maxFileSize, allowedFileTypes],\n );\n\n // 暴露 addFiles 方法供外层(如 DefaultLayout 拖拽上传)调用\n useImperativeHandle(ref, () => ({\n addFiles: (rawFiles: File[]) => {\n handleFileSelect(rawFiles);\n },\n }), [handleFileSelect]);\n\n // 上传文件\n const uploadFiles = async (fileList: LocalFile[]) => {\n for (const localFile of fileList) {\n // 开始上传\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, status: \"uploading\" } : f,\n ),\n );\n\n try {\n await uploadRequest({\n file: localFile.file,\n onProgress: (e) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id ? { ...f, progress: e.percent } : f,\n ),\n );\n },\n onSuccess: (response) => {\n const responseData = normalizeUploadResponse(response);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"success\",\n progress: 100,\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl ||\n responseData.fileUrl ||\n responseData.url,\n }\n : f,\n ),\n );\n\n onUploadSuccess?.({\n ...localFile,\n status: \"success\",\n response,\n fileId: responseData.fileId || responseData.id,\n tempUrl:\n responseData.tempUrl || responseData.fileUrl || responseData.url,\n });\n },\n onError: (error) => {\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage: error.message,\n }\n : f,\n ),\n );\n onUploadError?.(localFile, error);\n },\n });\n } catch (error) {\n console.error(\"上传处理错误:\", error);\n setFiles((prev) =>\n prev.map((f) =>\n f.id === localFile.id\n ? {\n ...f,\n status: \"error\",\n errorMessage:\n error instanceof Error ? error.message : \"上传处理失败\",\n }\n : f,\n ),\n );\n message.error(`${localFile.name} 上传失败`);\n }\n }\n };\n\n // 删除文件\n const handleRemoveFile = (id: string) => {\n setFiles((prev) => {\n const next = prev.filter((file) => file.id !== id);\n\n onFilesChange?.(next);\n\n return next;\n });\n };\n\n // 触发文件选择\n const triggerFileSelect = () => {\n if (fileInputRef.current) {\n fileInputRef.current.click();\n }\n };\n\n // 处理拖拽事件\n const handleDragOver = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (allowUpload) {\n setIsDragOver(true);\n }\n },\n [allowUpload],\n );\n\n const handleDragLeave = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (allowUpload) {\n setIsDragOver(false);\n }\n },\n [allowUpload],\n );\n\n const handleDrop = useCallback(\n (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n\n if (\n allowUpload &&\n e.dataTransfer.files &&\n e.dataTransfer.files.length > 0\n ) {\n handleFileSelect(Array.from(e.dataTransfer.files));\n }\n },\n [allowUpload, handleFileSelect],\n );\n\n // 处理提交\n const handleSubmit = () => {\n if (!value.trim() && files.length === 0) {\n message.warning(\"请输入消息或选择文件\");\n return;\n }\n\n const successFiles = files.filter((file) => file.status === \"success\");\n const uploadingFiles = files.filter((file) => file.status === \"uploading\");\n\n if (uploadingFiles.length > 0) {\n Modal.confirm({\n title: \"文件上传中\",\n content: `还有 ${uploadingFiles.length} 个文件正在上传,是否继续发送?`,\n okText: \"发送已完成的\",\n cancelText: \"等待全部完成\",\n onOk: () => {\n const formattedFiles = formatFilesForServer(successFiles);\n if (onSubmit) {\n onSubmit({\n text: value,\n files: formattedFiles,\n });\n }\n\n setValue(\"\");\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n },\n onCancel: () => {\n message.info(\"请等待文件上传完成后再发送\");\n },\n });\n } else {\n const formattedFiles = formatFilesForServer(successFiles);\n\n if (onSubmit) {\n onSubmit({\n text: value,\n files: formattedFiles,\n });\n }\n\n setValue(\"\");\n setFiles((prev) => prev.filter((f) => f.status !== \"success\"));\n }\n };\n\n // 格式化文件列表为服务端格式\n const formatFilesForServer = (fileList: LocalFile[]): ServerFile[] => {\n return fileList\n .filter((file) => file.status === \"success\" && file.response)\n .map((file) => {\n const responseData = normalizeUploadResponse(file.response);\n\n return {\n fileName: responseData.fileName || file.name,\n fileId: responseData.fileId || responseData.id || \"\",\n tempUrl:\n responseData.tempUrl || responseData.fileUrl || responseData.url || \"\",\n type: responseData.fileType || responseData.type || getExt(file),\n size: responseData.fileSize || responseData.size || file.size,\n mimeType: responseData.mimeType || file.type,\n raw: {\n ...responseData,\n },\n };\n });\n };\n\n // 处理输入框变化\n const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setValue(newValue);\n };\n\n // 处理回车键\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n // 渲染文件列表 - 使用新的 FileGallery 组件\n const renderFileList = () => {\n if (files.length === 0) return null;\n\n return (\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"8px\",\n padding: \"12px 0\",\n }}\n >\n {files.map((file) => (\n <FileGallery\n key={file.id}\n file={file}\n type=\"file\"\n removable\n onRemove={handleRemoveFile}\n />\n ))}\n </div>\n );\n };\n\n const containerClass = `${styles.container} ${isDragOver ? \"drag-over\" : \"\"} ${showMask ? 'show-mask' : ''}`;\n const uploading = files.some((f) => f.status === \"uploading\");\n const isDisabled = disabled || uploading || loading;\n const hasContent = value.trim().length > 0;\n const hasFiles = files.some((f) => f.status === \"success\");\n const canSend = hasContent || hasFiles;\n\n // 定义按钮组件(供外部 slot 函数通过 actionsComponents 使用)\n // 注意:sendButtonRender 的结果直接内联到 defaultSuffix 中,避免组件引用变化导致闪烁\n const SendButton = (props: any) => {\n if (sendButtonRender) {\n return (\n <>\n {sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })}\n </>\n );\n }\n return (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n {...props}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n );\n };\n\n const UploadButton = (props: any) => (\n <Tooltip title=\"上传文件\">\n <button\n className={`${styles.iconButton} ${styles.uploadButton}`}\n onClick={triggerFileSelect}\n disabled={isDisabled}\n aria-label=\"上传文件\"\n {...props}\n >\n <PaperClipOutlined />\n </button>\n </Tooltip>\n );\n\n const ClearButton = (props: any) => (\n <Popconfirm\n title=\"确定要清空聊天记录吗?\"\n onConfirm={onClear}\n placement=\"top\"\n okText=\"确定\"\n cancelText=\"取消\"\n disabled={isDisabled}\n >\n <button\n className={`${styles.iconButton} ${styles.clearButton}`}\n disabled={isDisabled}\n aria-label=\"清空聊天记录\"\n {...props}\n >\n <ClearOutlined />\n </button>\n </Popconfirm>\n );\n\n const actionsComponents: ActionsComponents = {\n SendButton,\n UploadButton,\n ClearButton,\n };\n\n // 渲染插槽内容\n const renderSlot = (\n slot:\n | React.ReactNode\n | false\n | ((\n oriNode: React.ReactNode,\n info: { components: ActionsComponents },\n ) => React.ReactNode | false)\n | undefined,\n oriNode: React.ReactNode,\n ): React.ReactNode | null => {\n if (slot === false) return null;\n if (slot === undefined) return oriNode;\n if (typeof slot === \"function\") {\n const result = slot(oriNode, { components: actionsComponents });\n return result === false ? null : result;\n }\n return slot;\n };\n\n // 默认的后缀内容(操作按钮组) - 直接内联渲染避免组件引用变化导致 unmount/remount\n const defaultSuffix = (\n <div className={styles.buttonGroup}>\n {allowUpload && (\n <Tooltip title=\"上传文件\">\n <button\n className={`${styles.iconButton} ${styles.uploadButton}`}\n onClick={triggerFileSelect}\n disabled={isDisabled}\n aria-label=\"上传文件\"\n >\n <PaperClipOutlined />\n </button>\n </Tooltip>\n )}\n {sendButtonRender ? (\n sendButtonRender({\n loading,\n disabled: uploading || disabled,\n canSend,\n onSend: handleSubmit,\n onStop,\n })\n ) : (\n <Tooltip title={loading ? \"停止生成\" : \"发送消息\"}>\n <button\n className={`${styles.iconButton} ${styles.sendButton} ${loading ? \"stop\" : \"\"}`}\n onClick={loading ? onStop : handleSubmit}\n disabled={uploading || disabled}\n aria-label={loading ? \"停止生成\" : \"发送消息\"}\n >\n {loading ? <LoadingOutlined spin /> : <ArrowUpOutlined />}\n </button>\n </Tooltip>\n )}\n </div>\n );\n\n return (\n <div\n ref={containerRef}\n className={containerClass}\n onDragOver={allowUpload && draggable ? handleDragOver : undefined}\n onDragLeave={allowUpload && draggable ? handleDragLeave : undefined}\n onDrop={allowUpload && draggable ? handleDrop : undefined}\n >\n {/* 头部插槽 */}\n {renderSlot(header, false)}\n\n {allowUpload && files.length > 0 && renderFileList()}\n\n {/* 隐藏的原生 file input */}\n {allowUpload && (\n <input\n ref={fileInputRef}\n type=\"file\"\n multiple\n accept={allowedFileTypes.join(\",\")}\n style={{ display: \"none\" }}\n onChange={(e) => {\n if (e.target.files) {\n handleFileSelect(Array.from(e.target.files));\n e.target.value = \"\";\n }\n }}\n />\n )}\n\n <div className={styles.mainArea}>\n <div className={styles.senderWrap}>\n <div className={styles.inputAndButtons}>\n {/* 清除按钮 */}\n {clearBtnShow && <ClearButton />}\n {/* 前缀插槽 */}\n {renderSlot(prefix, false)}\n\n <div className={styles.textAreaWrapper}>\n <Input.TextArea\n className={styles.textArea}\n value={value}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n placeholder=\"请输入消息...\"\n disabled={isDisabled}\n autoSize={{ minRows: 1, maxRows: 4 }}\n style={{\n border: \"none\",\n boxShadow: \"none\",\n outline: \"none\",\n padding: 0,\n }}\n />\n </div>\n\n {/* 后缀插槽(默认显示操作按钮) */}\n {renderSlot(suffix, defaultSuffix)}\n </div>\n\n {/* 底部插槽(默认显示提示文字) */}\n {renderSlot(\n footer,\n <div className={styles.tip}>\n 内容由AI生成,无法确保真实准确,仅供参考\n </div>,\n )}\n </div>\n </div>\n </div>\n );\n});\n\nXAdkSender.displayName = 'XAdkSender';\n\nimport XAdkSenderSwitch from \"./Switch\";\n\ntype XAdkSenderComponent = typeof XAdkSender & {\n Switch: typeof XAdkSenderSwitch;\n};\n\nconst CompoundSender = XAdkSender as XAdkSenderComponent;\nCompoundSender.Switch = XAdkSenderSwitch;\n\nexport default CompoundSender;\n"],
5
+ "mappings": "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",
6
6
  "names": ["files", "FileGallery", "XAdkSenderSwitch"]
7
7
  }