system commit

This commit is contained in:
2025-08-22 14:22:43 +08:00
parent bf6f910db1
commit a1537e3f9f
36 changed files with 1311 additions and 0 deletions

View 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>