74 lines
2.3 KiB
Vue
74 lines
2.3 KiB
Vue
<script setup lang="ts">
|
||
import { ref } from "vue";
|
||
|
||
import type { ChatSession } from "../types/api";
|
||
|
||
defineProps<{
|
||
open: boolean;
|
||
sessions: ChatSession[];
|
||
activeSessionId: number | null;
|
||
}>();
|
||
|
||
const emit = defineEmits<{
|
||
close: [];
|
||
select: [sessionId: number];
|
||
create: [];
|
||
rename: [sessionId: number, title: string];
|
||
delete: [sessionId: number];
|
||
}>();
|
||
|
||
const editingId = ref<number | null>(null);
|
||
const editingTitle = ref("");
|
||
|
||
function startEdit(session: ChatSession) {
|
||
editingId.value = session.id;
|
||
editingTitle.value = session.title;
|
||
}
|
||
|
||
function submitEdit(sessionId: number) {
|
||
const title = editingTitle.value.trim();
|
||
if (title) emit("rename", sessionId, title);
|
||
editingId.value = null;
|
||
editingTitle.value = "";
|
||
}
|
||
|
||
function confirmDelete(session: ChatSession) {
|
||
const ok = window.confirm(`确定删除会话「${session.title}」吗?`);
|
||
if (ok) emit("delete", session.id);
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="drawer-mask" :class="{ show: open }" @click="emit('close')"></div>
|
||
<aside class="session-drawer" :class="{ open }">
|
||
<div class="drawer-head">
|
||
<strong>历史会话</strong>
|
||
<button type="button" class="icon-btn" @click="emit('close')">×</button>
|
||
</div>
|
||
<button type="button" class="new-session-btn" @click="emit('create')">+ 新聊天</button>
|
||
<div class="session-list">
|
||
<div
|
||
v-for="session in sessions"
|
||
:key="session.id"
|
||
class="session-item"
|
||
:class="{ active: session.id === activeSessionId }"
|
||
>
|
||
<form v-if="editingId === session.id" class="session-edit" @submit.prevent="submitEdit(session.id)">
|
||
<input v-model="editingTitle" maxlength="100" @keydown.escape="editingId = null" />
|
||
<button type="submit">保存</button>
|
||
</form>
|
||
<template v-else>
|
||
<button type="button" class="session-main" @click="emit('select', session.id)">
|
||
<span>{{ session.title }}</span>
|
||
<small>{{ session.messageCount }} 条消息</small>
|
||
</button>
|
||
<div class="session-actions">
|
||
<button type="button" @click="startEdit(session)">改名</button>
|
||
<button type="button" @click="confirmDelete(session)">删除</button>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</template>
|