From caaa5e759746873e356eb5658eb4db024b9b2a65 Mon Sep 17 00:00:00 2001 From: wangdan-fit2cloud Date: Thu, 5 Nov 2026 16:21:39 +0800 Subject: [PATCH] feat: share chat --- ui/src/components/COMPONENT_README.md | 6 ++ .../components/content/index.vue | 2 +- .../content/items/question/QuestionEditor.vue | 46 +++++++++++++++ .../{question.vue => question/index.vue} | 56 ++++++++++++++++--- .../components/message-input/index.ts | 1 - .../portal-conversation-list/index.ts | 30 ++++++++++ .../portal-conversation-list/index.vue | 39 +++++++++++-- ui/src/views/chat/share/index.vue | 2 +- 8 files changed, 166 insertions(+), 16 deletions(-) create mode 100644 ui/src/conversation-panel/components/content/items/question/QuestionEditor.vue rename ui/src/conversation-panel/components/content/items/{question.vue => question/index.vue} (71%) diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index a8f53d81721..30869b079dc 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -979,6 +979,12 @@ Workspace API 内部使用 `getWorkspaceId()`,System 共享 API 不接收工 `hasMore`。首页失败后通过重新加载首页重试,不从下一页继续。 Chat、Portal 和 Display 面板直接放置消息列表,并以当前会话 ID 为 `key`,不再包裹额外滚动层。 +### Question(对话模块) + +`conversation-panel/components/content/items/question/index.vue` 负责提问展示、附件和操作入口。 +同目录 `QuestionEditor.vue` 接收 `content`、`disabled`,维护本次编辑草稿,通过 `cancel` 和 +`send(question)` 通知入口组件;进入时挂载并聚焦,退出时卸载。入口组件负责发送能力与附件传递。 + ### SharePanel(对话模块) `conversation-panel/main/share-panel/index.vue` 展示只读问答,通过 `useSharePanelContentStore()` diff --git a/ui/src/conversation-panel/components/content/index.vue b/ui/src/conversation-panel/components/content/index.vue index 1710f0fdb32..f332688b098 100644 --- a/ui/src/conversation-panel/components/content/index.vue +++ b/ui/src/conversation-panel/components/content/index.vue @@ -9,7 +9,7 @@ import GroupToolItem from './items/group-tool/index.vue' import GroupItem from './items/group/index.vue' import FormItem from './items/form.vue' import FailureItem from './items/failure.vue' -import QuestionItem from './items/question.vue' +import QuestionItem from './items/question/index.vue' defineOptions({ name: 'ConversationContent' }) diff --git a/ui/src/conversation-panel/components/content/items/question/QuestionEditor.vue b/ui/src/conversation-panel/components/content/items/question/QuestionEditor.vue new file mode 100644 index 00000000000..9194cb988a6 --- /dev/null +++ b/ui/src/conversation-panel/components/content/items/question/QuestionEditor.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/ui/src/conversation-panel/components/content/items/question.vue b/ui/src/conversation-panel/components/content/items/question/index.vue similarity index 71% rename from ui/src/conversation-panel/components/content/items/question.vue rename to ui/src/conversation-panel/components/content/items/question/index.vue index d20c617ba09..1138b1ff2a5 100644 --- a/ui/src/conversation-panel/components/content/items/question.vue +++ b/ui/src/conversation-panel/components/content/items/question/index.vue @@ -1,5 +1,7 @@ + + diff --git a/ui/src/conversation-panel/components/message-input/index.ts b/ui/src/conversation-panel/components/message-input/index.ts index 6a256ddab3f..4bacae9da06 100644 --- a/ui/src/conversation-panel/components/message-input/index.ts +++ b/ui/src/conversation-panel/components/message-input/index.ts @@ -80,7 +80,6 @@ export function createMessageInputStore(deps: MessageInputDeps) { const maxFiles = 10 const maxSizeMB = 50 - // TODO 格式 不行 const acceptList = [...IMAGE_EXTENSIONS, ...DOCUMENT_EXTENSIONS, ...VIDEO_EXTENSIONS, ...AUDIO_EXTENSIONS].map((e) => `.${e}`).join(',') // 语音输入:智能体开启语音转文字且当前模式提供接口时可用 diff --git a/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.ts b/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.ts index 0c947175549..4e17d7d931e 100644 --- a/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.ts +++ b/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.ts @@ -85,6 +85,35 @@ export function createPortalConversationListStore(deps: PortalConversationListDe } } + // 先查询全部分组和会话,再删除,避免边删除边翻页造成记录遗漏。 + const clearConversations = async (onRemoved: (applicationId: string, chatId: string) => void) => { + const applicationIds = new Set() + for (let page = 1; ; page++) { + const response = await pageApplicationConversations(page, APPLICATION_PAGE_SIZE) + const records = response.records ?? [] + records.forEach((application) => applicationIds.add(application.id)) + if (records.length < APPLICATION_PAGE_SIZE) break + } + + const pendingConversations: { applicationId: string; chatId: string }[] = [] + for (const applicationId of applicationIds) { + for (let page = 1; ; page++) { + const response = await pageGroupConversations(applicationId, page, APPLICATION_PAGE_SIZE) + // 查询失败不得当作空页继续删除。 + if (!response) throw new Error('获取历史对话失败') + const records = response.records ?? [] + records.forEach((conversation) => pendingConversations.push({ applicationId, chatId: conversation.id })) + if (records.length < APPLICATION_PAGE_SIZE) break + } + } + + for (const { applicationId, chatId } of pendingConversations) { + await deleteGroupConversation(applicationId, chatId) + onRemoved(applicationId, chatId) + } + await loadApplicationGroups() + } + // 按名称查询可访问的智能体,全部智能体页与选择智能体抽屉各自维护搜索条件与结果 const fetchApplications = (keyword: string) => pageApplications(1, APPLICATION_PAGE_SIZE, keyword.trim()).then((response) => response.records ?? []) @@ -116,6 +145,7 @@ export function createPortalConversationListStore(deps: PortalConversationListDe loadApplicationGroups, toggleGroup, deleteGroupConversation, + clearConversations, applications, applicationKeyword, isApplicationsLoading, diff --git a/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.vue b/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.vue index 525e1ff4cb5..ab3b2ca06d7 100644 --- a/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.vue +++ b/ui/src/conversation-panel/left-sidebar/portal-conversation-list/index.vue @@ -1,5 +1,6 @@