Web优化 2

This commit is contained in:
2026-06-12 14:36:41 +08:00
parent 7e9df04bf8
commit 61a1a4d368
31 changed files with 551 additions and 918 deletions
+11 -41
View File
@@ -3,13 +3,7 @@
<div class="flex h-[calc(100vh-8rem)] -m-6">
<!-- 左侧会话列表 -->
<div class="w-72 border-r overflow-y-auto p-2 flex flex-col gap-1">
<NButton
block
class="mb-2"
@click="showCreate = true"
>
+ 新建对话
</NButton>
<NButton block class="mb-2" @click="showCreate = true"> + 新建对话 </NButton>
<div
v-for="c in chat.conversations"
:key="c.id"
@@ -27,10 +21,7 @@
{{ formatTime(c.updated_at) }}
</div>
</div>
<NPopconfirm
:show-icon="false"
@positive-click="chat.deleteConversation(c.id)"
>
<NPopconfirm :show-icon="false" @positive-click="chat.deleteConversation(c.id)">
<template #trigger>
<NButton
text
@@ -43,15 +34,10 @@
</template>
</NButton>
</template>
<template #default>
删除后无法恢复确定删除此会话
</template>
<template #default> 删除后无法恢复确定删除此会话 </template>
</NPopconfirm>
</div>
<div
v-if="chat.conversations.length === 0"
class="text-xs text-neutral-400 px-2"
>
<div v-if="chat.conversations.length === 0" class="text-xs text-neutral-400 px-2">
暂无对话
</div>
</div>
@@ -70,30 +56,19 @@
<div class="text-sm font-medium truncate flex-1">
{{ chat.currentConversation.title || '(未命名)' }}
</div>
<NPopconfirm
:show-icon="false"
@positive-click="deleteCurrentConversation"
>
<NPopconfirm :show-icon="false" @positive-click="deleteCurrentConversation">
<template #trigger>
<NButton
text
size="small"
>
<NButton text size="small">
<template #icon>
<NIcon><TrashOutline /></NIcon>
</template>
删除
</NButton>
</template>
<template #default>
删除后无法恢复确定删除此会话
</template>
<template #default> 删除后无法恢复确定删除此会话 </template>
</NPopconfirm>
</div>
<div
ref="scrollEl"
class="flex-1 overflow-y-auto p-4 space-y-3"
>
<div ref="scrollEl" class="flex-1 overflow-y-auto p-4 space-y-3">
<MessageBubble
v-for="m in chat.messages"
:key="m.id"
@@ -125,13 +100,7 @@
>
发送
</NButton>
<NButton
v-else
type="warning"
@click="chat.cancelMessage"
>
中断
</NButton>
<NButton v-else type="warning" @click="chat.cancelMessage"> 中断 </NButton>
</div>
</div>
</template>
@@ -154,6 +123,7 @@ import { TrashOutline } from '@vicons/ionicons5'
import AppShell from '@/layouts/AppShell.vue'
import { useChatStore } from '@/stores/chat'
import { formatDateTime } from '@/utils/date'
const MessageBubble = defineAsyncComponent(() => import('./components/MessageBubble.vue'))
import AttachmentUploader from './components/AttachmentUploader.vue'
const ConversationCreateModal = defineAsyncComponent(() => import('./ConversationCreateModal.vue'))
@@ -271,6 +241,6 @@ async function deleteCurrentConversation() {
}
function formatTime(iso: string) {
return new Date(iso).toLocaleString('zh-CN', { hour12: false })
return formatDateTime(iso)
}
</script>
@@ -1,13 +1,7 @@
<template>
<div class="flex gap-2 items-center flex-wrap">
<NUpload
:custom-request="upload"
:show-file-list="false"
multiple
>
<NButton size="small">
添加附件
</NButton>
<NUpload :custom-request="upload" :show-file-list="false" multiple>
<NButton size="small"> 添加附件 </NButton>
</NUpload>
<div
v-for="a in attachments"
@@ -15,13 +9,7 @@
class="text-xs px-2 py-1 bg-neutral-100 rounded flex items-center gap-1"
>
<span>{{ a.filename }} ({{ Math.round(a.size_bytes / 1024) }} KB)</span>
<NButton
text
size="tiny"
@click="remove(a.id)"
>
×
</NButton>
<NButton text size="tiny" @click="remove(a.id)"> × </NButton>
</div>
</div>
</template>
@@ -41,6 +29,9 @@ const emit = defineEmits<{ change: [ids: string[]] }>()
const attachments = ref<Attachment[]>([])
const msg = useMessage()
const MAX_ATTACHMENT_SIZE_MB = 20
const MAX_ATTACHMENT_SIZE_BYTES = MAX_ATTACHMENT_SIZE_MB * 1024 * 1024
async function upload(opts: UploadCustomRequestOptions) {
const f = opts.file.file
if (!f) {
@@ -62,8 +53,8 @@ async function upload(opts: UploadCustomRequestOptions) {
opts.onError()
return
}
if (f.size > 20 * 1024 * 1024) {
msg.error('单文件不能超过 20 MB')
if (f.size > MAX_ATTACHMENT_SIZE_BYTES) {
msg.error(`单文件不能超过 ${MAX_ATTACHMENT_SIZE_MB} MB`)
opts.onError()
return
}
@@ -83,7 +74,11 @@ function remove(id: string) {
watch(
() => attachments.value.map((a) => a.id),
() => emit('change', attachments.value.map((a) => a.id)),
() =>
emit(
'change',
attachments.value.map((a) => a.id),
),
)
defineExpose({