feat:【antd】【ai】chat 的样式 review
This commit is contained in:
@@ -564,6 +564,7 @@ onMounted(async () => {
|
|||||||
<Layout.Header
|
<Layout.Header
|
||||||
class="!bg-card border-border flex !h-12 items-center justify-between border-b"
|
class="!bg-card border-border flex !h-12 items-center justify-between border-b"
|
||||||
>
|
>
|
||||||
|
<!-- TODO @AI:距离左侧的间距有点大 -->
|
||||||
<div class="text-lg font-bold">
|
<div class="text-lg font-bold">
|
||||||
{{ activeConversation?.title ? activeConversation?.title : '对话' }}
|
{{ activeConversation?.title ? activeConversation?.title : '对话' }}
|
||||||
<span v-if="activeMessageList.length > 0">
|
<span v-if="activeMessageList.length > 0">
|
||||||
@@ -571,6 +572,7 @@ onMounted(async () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- TODO @AI:距离右侧的间距有点大 -->
|
||||||
<div class="flex w-72 justify-end" v-if="activeConversation">
|
<div class="flex w-72 justify-end" v-if="activeConversation">
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -621,6 +623,7 @@ onMounted(async () => {
|
|||||||
</div>
|
</div>
|
||||||
</Layout.Content>
|
</Layout.Content>
|
||||||
|
|
||||||
|
<!-- TODO @AI:宽度没满 -->
|
||||||
<Layout.Footer class="!bg-card m-0 flex flex-col p-0">
|
<Layout.Footer class="!bg-card m-0 flex flex-col p-0">
|
||||||
<form class="border-border m-2 flex flex-col rounded-xl border p-2">
|
<form class="border-border m-2 flex flex-col rounded-xl border p-2">
|
||||||
<textarea
|
<textarea
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const [Form, formApi] = useVbenForm({
|
|||||||
class: 'w-full',
|
class: 'w-full',
|
||||||
},
|
},
|
||||||
formItemClass: 'col-span-2',
|
formItemClass: 'col-span-2',
|
||||||
labelWidth: 140,
|
labelWidth: 110,
|
||||||
},
|
},
|
||||||
layout: 'horizontal',
|
layout: 'horizontal',
|
||||||
schema: useFormSchema(),
|
schema: useFormSchema(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { computed, nextTick, onMounted, ref, toRefs } from 'vue';
|
|||||||
import { IconifyIcon, SvgGptIcon } from '@vben/icons';
|
import { IconifyIcon, SvgGptIcon } from '@vben/icons';
|
||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
import { useUserStore } from '@vben/stores';
|
import { useUserStore } from '@vben/stores';
|
||||||
import { formatDate } from '@vben/utils';
|
import { formatDateTime } from '@vben/utils';
|
||||||
|
|
||||||
import { useClipboard } from '@vueuse/core';
|
import { useClipboard } from '@vueuse/core';
|
||||||
import { Avatar, Button, message } from 'ant-design-vue';
|
import { Avatar, Button, message } from 'ant-design-vue';
|
||||||
@@ -50,14 +50,15 @@ const { list } = toRefs(props); // 定义 emits
|
|||||||
// ============ 处理对话滚动 ==============
|
// ============ 处理对话滚动 ==============
|
||||||
|
|
||||||
/** 滚动到底部 */
|
/** 滚动到底部 */
|
||||||
const scrollToBottom = async (isIgnore?: boolean) => {
|
async function scrollToBottom(isIgnore?: boolean) {
|
||||||
// 注意要使用 nextTick 以免获取不到 dom
|
// 注意要使用 nextTick 以免获取不到 dom
|
||||||
await nextTick();
|
await nextTick();
|
||||||
if (isIgnore || !isScrolling.value) {
|
if (isIgnore || !isScrolling.value) {
|
||||||
messageContainer.value.scrollTop =
|
messageContainer.value.scrollTop =
|
||||||
messageContainer.value.scrollHeight - messageContainer.value.offsetHeight;
|
messageContainer.value.scrollHeight - messageContainer.value.offsetHeight;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
function handleScroll() {
|
function handleScroll() {
|
||||||
const scrollContainer = messageContainer.value;
|
const scrollContainer = messageContainer.value;
|
||||||
const scrollTop = scrollContainer.scrollTop;
|
const scrollTop = scrollContainer.scrollTop;
|
||||||
@@ -124,12 +125,13 @@ onMounted(async () => {
|
|||||||
<Avatar
|
<Avatar
|
||||||
v-if="conversation.roleAvatar"
|
v-if="conversation.roleAvatar"
|
||||||
:src="conversation.roleAvatar"
|
:src="conversation.roleAvatar"
|
||||||
|
:size="28"
|
||||||
/>
|
/>
|
||||||
<SvgGptIcon v-else class="size-8" />
|
<SvgGptIcon v-else class="size-7" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-4 flex flex-col text-left">
|
<div class="mx-4 flex flex-col text-left">
|
||||||
<div class="text-left leading-10">
|
<div class="text-left leading-10">
|
||||||
{{ formatDate(item.createTime) }}
|
{{ formatDateTime(item.createTime) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="relative flex flex-col break-words rounded-lg bg-gray-100 p-2.5 pb-1 pt-2.5 shadow-sm"
|
class="relative flex flex-col break-words rounded-lg bg-gray-100 p-2.5 pb-1 pt-2.5 shadow-sm"
|
||||||
@@ -172,11 +174,11 @@ onMounted(async () => {
|
|||||||
<!-- 右侧消息:user -->
|
<!-- 右侧消息:user -->
|
||||||
<div v-else class="flex flex-row-reverse justify-start">
|
<div v-else class="flex flex-row-reverse justify-start">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
<Avatar :src="userAvatar" />
|
<Avatar :src="userAvatar" :size="28" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mx-4 flex flex-col text-left">
|
<div class="mx-4 flex flex-col text-left">
|
||||||
<div class="text-left leading-8">
|
<div class="text-left leading-8">
|
||||||
{{ formatDate(item.createTime) }}
|
{{ formatDateTime(item.createTime) }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="item.attachmentUrls && item.attachmentUrls.length > 0"
|
v-if="item.attachmentUrls && item.attachmentUrls.length > 0"
|
||||||
|
|||||||
Reference in New Issue
Block a user