From be46ed8865738f1001f7f7b5273b676e1bf39c83 Mon Sep 17 00:00:00 2001 From: zhaoying Date: Wed, 18 Mar 2026 20:55:31 +0800 Subject: [PATCH] feat(web): chart content support files --- web/src/components/Chat/ChatContent.tsx | 54 ++++++++++++++++--- web/src/components/Chat/types.ts | 8 +-- web/src/views/ApplicationConfig/Cluster.tsx | 4 +- .../ApplicationConfig/TestChat/index.tsx | 14 +++-- .../ApplicationConfig/components/Chat.tsx | 8 +-- .../FeaturesConfig/FileUploadSettingModal.tsx | 10 ++-- .../Conversation/components/FileUpload.tsx | 15 +++++- web/src/views/Conversation/index.tsx | 8 +-- .../views/Workflow/components/Chat/Chat.tsx | 7 ++- 9 files changed, 101 insertions(+), 27 deletions(-) diff --git a/web/src/components/Chat/ChatContent.tsx b/web/src/components/Chat/ChatContent.tsx index 15dcd496..2f2552db 100644 --- a/web/src/components/Chat/ChatContent.tsx +++ b/web/src/components/Chat/ChatContent.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2025-12-10 16:46:17 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-17 14:11:24 + * @Last Modified time: 2026-03-18 20:48:03 */ import { type FC, useRef, useEffect, useState } from 'react' import clsx from 'clsx' @@ -33,7 +33,7 @@ const ChatContent: FC = ({ const audioRef = useRef(null) const [playingIndex, setPlayingIndex] = useState(null) - const handlePlay = (index: number, audioUrl: string) => { + const handlePlay = (index: number, audio_url: string) => { if (playingIndex === index) { audioRef.current?.pause() setPlayingIndex(null) @@ -42,7 +42,7 @@ const ChatContent: FC = ({ if (audioRef.current) { audioRef.current.pause() } - const audio = new Audio(audioUrl) + const audio = new Audio(audio_url) audioRef.current = audio audio.play() setPlayingIndex(index) @@ -108,6 +108,48 @@ const ChatContent: FC = ({ {labelFormat(item)} } + {item.meta_data?.files && item.meta_data?.files.length > 0 &&
+ {item.meta_data?.files?.map((file) => { + if (file.type.includes('image')) { + return ( +
+ {file.name} +
+ ) + } + if (file.type.includes('video')) { + return ( +
+
+ ) + } + if (file.type.includes('audio')) { + return ( +
+
+ ) + } + return ( +
+ {(file.type.includes('doc') || file.type.includes('docx') || file.type.includes('word') || file.type.includes('wordprocessingml.document')) &&
} + {(file.type.includes('pdf')) &&
} + {(file.type.includes('excel') || file.type.includes('spreadsheetml.sheet') || file.type.includes('csv')) &&
} +
+
{file.name}
+
{file.type} ยท {file.size}
+
+
+ ) + })} +
} {/* Message bubble */}
= ({ {/* Render message content using Markdown component */} - {item.audioUrl && <> + {item.meta_data?.audio_url && <> {playingIndex !== index - ? handlePlay(index, item.audioUrl!)} /> + ? handlePlay(index, item.meta_data?.audio_url!)} /> :
handlePlay(index, item.audioUrl!)} + onClick={() => handlePlay(index, item.meta_data?.audio_url!)} /> } diff --git a/web/src/components/Chat/types.ts b/web/src/components/Chat/types.ts index 9fb77ed7..a1d0a7e1 100644 --- a/web/src/components/Chat/types.ts +++ b/web/src/components/Chat/types.ts @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2025-12-10 16:45:54 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-17 13:46:24 + * @Last Modified time: 2026-03-18 20:47:42 */ import { type ReactNode } from 'react' @@ -22,9 +22,11 @@ export interface ChatItem { created_at?: number | string; status?: string; subContent?: Record[]; - files?: any[]; error?: string; - audioUrl?: string; + meta_data?: { + audio_url?: string; + files?: any[]; + }, } /** diff --git a/web/src/views/ApplicationConfig/Cluster.tsx b/web/src/views/ApplicationConfig/Cluster.tsx index 94023f0b..f4dd5a26 100644 --- a/web/src/views/ApplicationConfig/Cluster.tsx +++ b/web/src/views/ApplicationConfig/Cluster.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:29:33 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-18 19:37:15 + * @Last Modified time: 2026-03-18 19:49:09 */ import { useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react' import { useTranslation } from 'react-i18next' @@ -295,6 +295,7 @@ const Cluster = forwardRef } diff --git a/web/src/views/ApplicationConfig/TestChat/index.tsx b/web/src/views/ApplicationConfig/TestChat/index.tsx index b7ce167e..ad7931e2 100644 --- a/web/src/views/ApplicationConfig/TestChat/index.tsx +++ b/web/src/views/ApplicationConfig/TestChat/index.tsx @@ -1,3 +1,9 @@ +/* + * @Author: ZhaoYing + * @Date: 2026-03-13 17:27:52 + * @Last Modified by: ZhaoYing + * @Last Modified time: 2026-03-18 20:54:35 + */ import { type FC, useState, useRef, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { App } from 'antd' @@ -116,7 +122,9 @@ const TestChat: FC = ({ role: 'user', content: message, created_at: Date.now(), - files + meta_data: { + files + }, }]) } @@ -136,7 +144,7 @@ const TestChat: FC = ({ const lastMsg = newList[newList.length - 1] if (lastMsg.role === 'assistant') { lastMsg.content += content; - lastMsg.audioUrl = audio_url + lastMsg.meta_data = {audio_url} } return newList }) @@ -428,7 +436,7 @@ const TestChat: FC = ({ status, error, content: newList[lastIndex].content === '' ? null : newList[lastIndex].content, - audioUrl: audio_url + meta_data: { audio_url: audio_url } } } return newList diff --git a/web/src/views/ApplicationConfig/components/Chat.tsx b/web/src/views/ApplicationConfig/components/Chat.tsx index b8fba5a6..ee5bc53a 100644 --- a/web/src/views/ApplicationConfig/components/Chat.tsx +++ b/web/src/views/ApplicationConfig/components/Chat.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:27:39 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-17 15:27:57 + * @Last Modified time: 2026-03-18 20:52:33 */ /** * Chat debugging component for application testing @@ -92,7 +92,9 @@ const Chat: FC = ({ role: 'user', content: message, created_at: Date.now(), - files + meta_data: { + files + }, }; updateChatList(prev => prev.map(item => ({ ...item, @@ -142,7 +144,7 @@ const Chat: FC = ({ { ...lastMsg, content: lastMsg.content + (content || ''), - audioUrl: audio_url + meta_data: { audio_url } } ] } diff --git a/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx b/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx index 1d4e2a12..eae1a5a5 100644 --- a/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx +++ b/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-03-05 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-18 19:35:57 + * @Last Modified time: 2026-03-18 20:29:28 */ import { forwardRef, useImperativeHandle, useState } from 'react'; import { Form, InputNumber, Flex, Switch, Row, Col, Radio } from 'antd'; @@ -27,22 +27,22 @@ const fileTypeOptions = [ { type: 'document', icon:
, - formats: 'TXT, MD, MDX, MARKDOWN, PDF, DOC, DOCX', + formats: 'TXT, PDF, DOC, DOCX, XLSX, CSV, JSON', }, { type: 'image', icon:
, - formats: 'JPG, JPEG, PNG, GIF, WEBP, SVG', + formats: 'JPG, JPEG, PNG, GIF, WEBP', }, { type: 'audio', icon:
, - formats: 'MP3, M4A, WAV, AMR, MPGA', + formats: 'MP3, M4A, WAV, OGG, FLAC', }, { type: 'video', icon:
, - formats: 'MP4, MOV, MPEG, WEBM', + formats: 'MP4, MOV, AVI, WEBM', }, ]; diff --git a/web/src/views/Conversation/components/FileUpload.tsx b/web/src/views/Conversation/components/FileUpload.tsx index 6aeb2dd5..48370fcc 100644 --- a/web/src/views/Conversation/components/FileUpload.tsx +++ b/web/src/views/Conversation/components/FileUpload.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-06 21:09:42 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-17 14:42:31 + * @Last Modified time: 2026-03-18 20:32:54 */ /** * File Upload Component @@ -71,6 +71,12 @@ const transform_file_type = { 'application/vnd.ms-powerpoint': 'document/ppt', 'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'document/pptx', + + 'application/vnd.ms-excel': 'document/xls', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'document/xlsx', + 'text/csv': 'document/csv', + + 'application/json': 'document/json' } // Mapping of file extensions to MIME types const ALL_FILE_TYPE: { @@ -88,6 +94,13 @@ const ALL_FILE_TYPE: { ppt: 'application/vnd.ms-powerpoint', pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + xls: 'application/vnd.ms-excel', + xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + + csv: 'text/csv', + + json: 'application/json', + jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', diff --git a/web/src/views/Conversation/index.tsx b/web/src/views/Conversation/index.tsx index e120af49..9774a8df 100644 --- a/web/src/views/Conversation/index.tsx +++ b/web/src/views/Conversation/index.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:58:03 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-18 15:35:05 + * @Last Modified time: 2026-03-18 20:54:00 */ /** * Conversation Page @@ -160,7 +160,9 @@ const Conversation: FC = () => { role: 'user', content: message, created_at: Date.now(), - files + meta_data: { + files + }, }]) } @@ -185,7 +187,7 @@ const Conversation: FC = () => { { ...lastMsg, content: lastMsg.content + content, - audioUrl: audio_url + meta_data: { audio_url } } ] } diff --git a/web/src/views/Workflow/components/Chat/Chat.tsx b/web/src/views/Workflow/components/Chat/Chat.tsx index 1e3a1b4a..ad46d2dc 100644 --- a/web/src/views/Workflow/components/Chat/Chat.tsx +++ b/web/src/views/Workflow/components/Chat/Chat.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-06 21:10:56 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-18 19:31:28 + * @Last Modified time: 2026-03-18 20:46:35 */ /** * Workflow Chat Component @@ -151,10 +151,14 @@ const Chat = forwardRef [...prev, { role: 'user', content: message, created_at: Date.now(), + meta_data: { + files + }, }]) setChatList(prev => [...prev, { role: 'assistant', @@ -338,7 +342,6 @@ const Chat = forwardRef