/** * Conversation Sidebar Component * 类似ChatGPT的会话侧边栏组件 */ const ConversationSidebar = { template: `
今天
{{ conv.title }}
{{ conv.gene_family }} {{ conv.message_count }}条消息
{{ conv.last_message }}
昨天
{{ conv.title }}
{{ conv.gene_family }} {{ conv.message_count }}条
过去7天
{{ conv.title }}
{{ conv.gene_family }}

暂无会话

点击上方"New Chat"开始新的基因家族分析

`, props: { userId: { type: String, default: 'xia-lab' }, apiBaseUrl: { type: String, default: 'http://localhost:8000/api' } }, data() { return { isCollapsed: false, searchQuery: '', conversations: [], currentConversationId: null, loading: false, // 图标 Plus: ElementPlusIconsVue.Plus, ArrowLeft: ElementPlusIconsVue.ArrowLeft, ArrowRight: ElementPlusIconsVue.ArrowRight, ChatDotRound: ElementPlusIconsVue.ChatDotRound, ChatLineRound: ElementPlusIconsVue.ChatLineRound, More: ElementPlusIconsVue.More, Edit: ElementPlusIconsVue.Edit, Folder: ElementPlusIconsVue.Folder, Delete: ElementPlusIconsVue.Delete, UserFilled: ElementPlusIconsVue.UserFilled, } }, computed: { filteredConversations() { if (!this.searchQuery) return this.conversations; const query = this.searchQuery.toLowerCase(); return this.conversations.filter(conv => conv.title.toLowerCase().includes(query) || (conv.gene_family && conv.gene_family.toLowerCase().includes(query)) || conv.last_message.toLowerCase().includes(query) ); }, todayConversations() { const today = new Date().toDateString(); return this.filteredConversations.filter(conv => { const convDate = new Date(conv.updated_at).toDateString(); return convDate === today; }); }, yesterdayConversations() { const yesterday = new Date(Date.now() - 86400000).toDateString(); return this.filteredConversations.filter(conv => { const convDate = new Date(conv.updated_at).toDateString(); return convDate === yesterday; }); }, olderConversations() { const yesterday = new Date(Date.now() - 86400000).toDateString(); return this.filteredConversations.filter(conv => { const convDate = new Date(conv.updated_at).toDateString(); return convDate < yesterday; }); } }, mounted() { this.loadConversations(); // 定时刷新 this.refreshInterval = setInterval(() => { this.loadConversations(); }, 30000); // 30秒刷新一次 }, beforeUnmount() { if (this.refreshInterval) { clearInterval(this.refreshInterval); } }, methods: { async loadConversations() { try { this.loading = true; const response = await fetch(`${this.apiBaseUrl}/conversations/list/${this.userId}`); if (response.ok) { const data = await response.json(); this.conversations = data.conversations || []; } } catch (error) { console.error('Failed to load conversations:', error); // 使用模拟数据 this.conversations = this.getMockConversations(); } finally { this.loading = false; } }, getMockConversations() { // 模拟数据,用于测试 return [ { conversation_id: 'conv_001', title: 'At.WRKY基因家族分析', gene_family: 'WRKY', species: 'At', message_count: 12, last_message: '系统发育树已生成完成', updated_at: new Date().toISOString() }, { conversation_id: 'conv_002', title: 'Os.TCP进化分析', gene_family: 'TCP', species: 'Os', message_count: 5, last_message: '正在构建进化树...', updated_at: new Date(Date.now() - 3600000).toISOString() }, { conversation_id: 'conv_003', title: 'HMMER参数配置咨询', message_count: 8, last_message: 'E-value建议设置为1e-5', updated_at: new Date(Date.now() - 86400000).toISOString() } ]; }, toggleSidebar() { this.isCollapsed = !this.isCollapsed; this.$emit('toggle', this.isCollapsed); }, async createNewConversation() { try { const response = await fetch(`${this.apiBaseUrl}/conversations/create`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user_id: this.userId, title: '新会话 ' + new Date().toLocaleTimeString() }) }); if (response.ok) { const data = await response.json(); this.currentConversationId = data.conversation_id; this.$emit('new-conversation', data); await this.loadConversations(); } } catch (error) { console.error('Failed to create conversation:', error); // 创建本地会话 const newConv = { conversation_id: 'conv_' + Date.now(), title: '新会话', message_count: 0, last_message: '', updated_at: new Date().toISOString() }; this.conversations.unshift(newConv); this.currentConversationId = newConv.conversation_id; this.$emit('new-conversation', newConv); } }, selectConversation(conv) { this.currentConversationId = conv.conversation_id; this.$emit('select-conversation', conv); }, async renameConversation(conv) { const newTitle = prompt('请输入新标题:', conv.title); if (newTitle && newTitle !== conv.title) { try { await fetch(`${this.apiBaseUrl}/conversations/update-title`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ conversation_id: conv.conversation_id, title: newTitle }) }); conv.title = newTitle; } catch (error) { console.error('Failed to rename:', error); conv.title = newTitle; // 本地更新 } } }, async archiveConversation(conv) { try { await fetch(`${this.apiBaseUrl}/conversations/archive`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ conversation_id: conv.conversation_id }) }); await this.loadConversations(); } catch (error) { console.error('Failed to archive:', error); } }, async deleteConversation(conv) { if (confirm(`确定要删除会话 "${conv.title}" 吗?`)) { try { await fetch(`${this.apiBaseUrl}/conversations/delete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ conversation_id: conv.conversation_id }) }); await this.loadConversations(); if (this.currentConversationId === conv.conversation_id) { this.currentConversationId = null; this.$emit('select-conversation', null); } } catch (error) { console.error('Failed to delete:', error); } } } } }; // 导出组件 if (typeof module !== 'undefined' && module.exports) { module.exports = { ConversationSidebar }; }