From e8b2b253f03f14aafdb3775bd479d1474b4ce5ad Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Sun, 27 Apr 2025 18:59:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=86=20refs=20=E7=A7=BB=E5=8A=A8=E5=88=B0?= =?UTF-8?q?=E4=BE=A7=E8=BE=B9=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/package.json | 2 +- web/src/components/ChatComponent.vue | 85 ++++- web/src/components/GraphContainer.vue | 153 ++++++++- web/src/components/MessageComponent.vue | 9 +- web/src/components/RefsComponent.vue | 321 ++---------------- web/src/components/RefsSidebar.vue | 426 ++++++++++++++++++++++++ 6 files changed, 689 insertions(+), 307 deletions(-) create mode 100644 web/src/components/RefsSidebar.vue diff --git a/web/package.json b/web/package.json index 2a496842..157f14bb 100644 --- a/web/package.json +++ b/web/package.json @@ -26,7 +26,7 @@ "less": "^4.1.3", "marked": "^13.0.2", "marked-highlight": "^2.1.4", - "md-editor-v3": "^4.16.7", + "md-editor-v3": "^4.21.3", "pinia": "^2.0.32", "vue": "^3.5.13", "vue-router": "^4.1.6" diff --git a/web/src/components/ChatComponent.vue b/web/src/components/ChatComponent.vue index a4fe2578..3e1737f9 100644 --- a/web/src/components/ChatComponent.vue +++ b/web/src/components/ChatComponent.vue @@ -81,13 +81,15 @@
@@ -142,6 +144,13 @@

请注意辨别内容的可靠性 By {{ configStore.config?.model_provider }}: {{ configStore.config?.model_name }}

+ + @@ -178,6 +187,7 @@ import { useConfigStore } from '@/stores/config' import { message } from 'ant-design-vue' import MessageInputComponent from '@/components/MessageInputComponent.vue' import MessageComponent from '@/components/MessageComponent.vue' +import RefsSidebar from '@/components/RefsSidebar.vue' const props = defineProps({ conv: Object, @@ -222,6 +232,41 @@ const meta = reactive(JSON.parse(localStorage.getItem('meta')) || { wideScreen: false, }) +// 添加全局refs状态 +const refsSidebarVisible = ref(false) +const currentRefs = ref({}) + +// 处理打开refs侧边栏 +const handleOpenRefs = ({ type, refs }) => { + console.log('ChatComponent handleOpenRefs called with type:', type); + console.log('Refs data structure:', JSON.stringify(refs)); + + // 先更新引用数据,确保数据在设置标签页之前已更新 + currentRefs.value = Object.assign({}, refs); + + // 强制在下一个tick更新,确保数据已经被正确应用 + nextTick(() => { + // 显示抽屉 + refsSidebarVisible.value = true; + + // 再次检查引用是否正确 + console.log('Updated refs data:', JSON.stringify(currentRefs.value)); + + // 根据type自动选择标签页 + if (refsSidebarRef.value) { + console.log('Setting active tab to:', type); + // 延迟50毫秒设置标签页,确保抽屉已打开 + setTimeout(() => { + refsSidebarRef.value.setActiveTab(type); + }, 50); + } else { + console.error('refsSidebarRef is not available'); + } + }); +} + +// 添加对RefsSidebar的ref +const refsSidebarRef = ref(null) const consoleMsg = (msg) => console.log(msg) onClickOutside(panel, () => setTimeout(() => opts.showPanel = false, 30)) @@ -358,6 +403,11 @@ const updateMessage = (info) => { propertiesToUpdate.forEach(prop => { if (info[prop] != null && (typeof info[prop] !== 'string' || info[prop] !== '')) { msg[prop] = info[prop]; + + // 如果更新了refs,同时更新全局refs + if (prop === 'refs' && info.refs) { + currentRefs.value = info.refs; + } } }); @@ -446,6 +496,12 @@ const fetchChatResponse = (user_input, cur_res_id) => { console.log(msg) groupRefs(cur_res_id); updateMessage({showThinking: "no", id: cur_res_id}); + // 更新全局refs为最新消息的refs + if (msg && msg.refs) { + // 深拷贝refs以确保不会出现引用问题 + currentRefs.value = JSON.parse(JSON.stringify(msg.refs)); + console.log('Updated currentRefs on response completion:', currentRefs.value); + } isStreaming.value = false; if (conv.value.messages.length === 2) { renameTitle(); } return; @@ -571,6 +627,11 @@ onMounted(() => { const parsedMeta = JSON.parse(storedMeta); Object.assign(meta, parsedMeta); } + + // 检查refsSidebarRef是否正确挂载 + nextTick(() => { + console.log('Is refsSidebarRef mounted?', !!refsSidebarRef.value); + }); }); onUnmounted(() => { @@ -642,6 +703,26 @@ const selectModel = (provider, name) => { configStore.setConfigValue('model_name', name) // message.success(`已切换到模型: ${name} | ${provider}`) } + +// 判断是否是最新的助手消息 +const isLatestMessage = (index) => { + // 找到最后一条助手消息的索引 + const lastAssistantMsgIndex = findLastIndex(conv.value.messages, + msg => (msg.role === 'received' || msg.role === 'assistant') && msg.status === 'finished'); + + // 如果当前索引等于最后一条助手消息的索引,则为最新消息 + return index === lastAssistantMsgIndex; +} + +// 辅助函数:从后向前查找满足条件的元素索引 +const findLastIndex = (array, predicate) => { + for (let i = array.length - 1; i >= 0; i--) { + if (predicate(array[i])) { + return i; + } + } + return -1; +} \ No newline at end of file diff --git a/web/src/components/RefsSidebar.vue b/web/src/components/RefsSidebar.vue new file mode 100644 index 00000000..773b684e --- /dev/null +++ b/web/src/components/RefsSidebar.vue @@ -0,0 +1,426 @@ + + + + + \ No newline at end of file