system commit
This commit is contained in:
50
frontend/src/components/ConversationList.vue
Normal file
50
frontend/src/components/ConversationList.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div class="conv-list">
|
||||
<div class="header">
|
||||
<span>历史会话</span>
|
||||
<button type="button" @click="$emit('new')">新建</button>
|
||||
<button v-if="authed" type="button" @click="refresh">⟳</button>
|
||||
</div>
|
||||
<div v-if="!authed" class="hint">登录后可保存会话</div>
|
||||
<div v-else class="items" v-loading="loading">
|
||||
<div v-for="c in list" :key="c._id" :class="['item', currentId===c._id && 'active']" @click="select(c._id)">
|
||||
<div class="title">{{ c.title || '未命名' }}</div>
|
||||
<div class="meta">{{ c.modelId }} · {{ formatTime(c.updatedAt) }}</div>
|
||||
<button class="del" @click.stop="remove(c._id)">删除</button>
|
||||
</div>
|
||||
<div v-if="!list.length && !loading" class="empty">暂无会话</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useConversationStore } from '@/stores/conversationStore';
|
||||
import { useAuthStore } from '@/stores/authStore';
|
||||
|
||||
const convStore = useConversationStore();
|
||||
const auth = useAuthStore();
|
||||
const list = computed(()=>convStore.list);
|
||||
const loading = computed(()=>convStore.loading);
|
||||
const currentId = computed(()=>convStore.currentId);
|
||||
const authed = computed(()=>auth.isAuthed);
|
||||
const router = useRouter();
|
||||
|
||||
function refresh() { convStore.fetchList(); }
|
||||
function select(id: string) { convStore.loadConversation(id); router.push('/chat'); }
|
||||
function formatTime(t: string) { return new Date(t).toLocaleString(); }
|
||||
function remove(id: string) { convStore.deleteConversation(id); }
|
||||
</script>
|
||||
<style scoped>
|
||||
.conv-list { display:flex; flex-direction:column; gap:8px; }
|
||||
.header { display:flex; gap:8px; align-items:center; font-size:13px; }
|
||||
.header button { background:var(--button-bg); color:#fff; border:none; padding:4px 8px; border-radius:4px; cursor:pointer; }
|
||||
.hint { font-size:12px; opacity:.6; }
|
||||
.items { display:flex; flex-direction:column; gap:4px; max-height:260px; overflow:auto; }
|
||||
.item { padding:6px 8px; border-radius:6px; cursor:pointer; background:var(--input-bg); display:flex; flex-direction:column; gap:2px; }
|
||||
.item.active { outline:2px solid var(--button-bg); }
|
||||
.title { font-size:13px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
|
||||
.meta { font-size:11px; opacity:.5; }
|
||||
.del { margin-left:auto; margin-top:6px; background:transparent; color:var(--text-color); border:1px solid var(--input-border); padding:4px 8px; border-radius:6px; cursor:pointer; }
|
||||
.empty { font-size:12px; opacity:.5; text-align:center; padding:12px 0; }
|
||||
</style>
|
Reference in New Issue
Block a user