refactor(@vben/web-antd): 重构 PPT 页面布局和样式

- 改进消息列表和输入框的展示方式
This commit is contained in:
Kven 2025-06-27 00:05:54 +08:00
parent 655eca8e4d
commit dae6d9abb8
3 changed files with 48 additions and 138 deletions

View File

@ -130,7 +130,7 @@ watch(
.menu {
background: #ffffff;
width: 200px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
@ -146,54 +146,6 @@ watch(
overflow-y: auto;
}
.chat {
height: 100%;
width: 100%;
max-width: 1000px;
max-height: 900px;
margin: 0 auto;
box-sizing: border-box;
display: flex;
flex-direction: column;
padding: 12px;
gap: 16px;
}
.placeholder {
padding-top: 32px;
text-align: left;
flex: 1;
}
.sender {
background: #ffffff;
width: 100%;
box-shadow: v-deep(var(--ant-box-shadow));
}
.logo {
display: flex;
height: 72px;
align-items: center;
justify-content: start;
padding: 0 24px;
box-sizing: border-box;
}
.logo-img {
width: 24px;
height: 24px;
display: inline-block;
}
.logo-span {
display: inline-block;
margin: 0 8px;
font-weight: bold;
color: v-deep(var(--ant-color-text));
font-size: 16px;
}
.addBtn {
float: left;
//border: 1px solid #1677ff34;

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import type { AttachmentsProps, BubbleListProps } from 'ant-design-x-vue';
import type { BubbleListProps } from 'ant-design-x-vue';
import type { DrawerPlacement } from '@vben/common-ui';
@ -10,12 +10,8 @@ import { h, ref, watch } from 'vue';
import { useVbenDrawer } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';
import {
CloudUploadOutlined,
PaperClipOutlined,
UserOutlined,
} from '@ant-design/icons-vue';
import { Badge, Button, Flex, Space, Typography } from 'ant-design-vue';
import { UserOutlined } from '@ant-design/icons-vue';
import { Button, Flex, Space } from 'ant-design-vue';
import { Attachments, Bubble, Sender, Welcome } from 'ant-design-x-vue';
import PptPreview from './ppt-preview.vue';
@ -24,7 +20,12 @@ defineOptions({ name: 'PptWorkView' });
const props = withDefaults(defineProps<PropsWork>(), {
itemMessage: () => null,
item: () => null,
item: () => {
return {
id: '',
name: '',
};
},
runWorkflow: () => async () => ({
data: {
outputs: {
@ -79,9 +80,7 @@ const roles: BubbleListProps['roles'] = {
};
// ==================== State ====================
const headerOpen = ref(false);
const content = ref('');
const attachedFiles = ref<AttachmentsProps['items']>([]);
const agentRequestLoading = ref(false);
const fetchStatus = ref('');
const resultItems = ref<ResultItem[]>([]);
@ -100,10 +99,6 @@ function openPreviewDrawer(
}
// ==================== Event ====================
const handleFileChange: AttachmentsProps['onChange'] = (info) =>
(attachedFiles.value = info.fileList);
// .pptx URL
// function isPptxURL(str: string): boolean {
// return str.endsWith('.pptx');
@ -147,7 +142,6 @@ const startFetching = async () => {
h(
Button,
{
size: 'nomarl',
type: 'primary',
onClick: () => {
openPreviewDrawer('right', files.url);
@ -158,7 +152,6 @@ const startFetching = async () => {
h(
Button,
{
size: 'nomarl',
type: 'primary',
style: {
marginLeft: '10px',
@ -212,7 +205,6 @@ watch(
h(
Button,
{
size: 'nomarl',
type: 'primary',
onClick: () => {
openPreviewDrawer('right', msg.content.url);
@ -223,7 +215,6 @@ watch(
h(
Button,
{
size: 'normal',
type: 'primary',
style: {
marginLeft: '10px',
@ -254,11 +245,29 @@ watch(
<div class="layout">
<PreviewDrawer />
<div class="chat">
<div class="chat-left">
<!-- 🌟 输入框 -->
<Sender
:value="content"
class="sender"
placeholder="科研申报文档"
:auto-size="{ minRows: 6, maxRows: 18 }"
:loading="agentRequestLoading"
:disabled="agentRequestLoading"
@submit="startFetching"
@change="(value) => (content = value)"
>
<template #header>
<Sender.Header :open="true" :title="props.item?.name || ''" />
</template>
</Sender>
</div>
<Space
v-if="resultItems.length === 0"
direction="vertical"
size:16
style="flex: 1; padding-top: 20px"
style="width: 60%; padding: 20px 0 0 12px"
>
<Welcome
variant="borderless"
@ -270,73 +279,12 @@ watch(
<!-- 🌟 消息列表 -->
<Bubble.List
v-else
style="width: 60%; padding: 12px"
variant="shadow"
:typing="true"
:items="resultItems"
:roles="roles"
style="flex: 1; padding: 10px 10px 0"
/>
<!-- 🌟 输入框 -->
<Sender
:value="content"
class="sender"
:loading="agentRequestLoading"
:disabled="agentRequestLoading"
@submit="startFetching"
@change="(value) => (content = value)"
>
<template #prefix>
<Badge :dot="attachedFiles.length > 0 && !headerOpen">
<Button type="text" @click="() => (headerOpen = !headerOpen)">
<template #icon>
<PaperClipOutlined />
</template>
</Button>
</Badge>
</template>
<template #header>
<Sender.Header
title="Attachments"
:open="headerOpen"
:styles="{ content: { padding: 0 } }"
@open-change="(open) => (headerOpen = open)"
>
<Attachments
:before-upload="() => false"
:items="attachedFiles"
@change="handleFileChange"
>
<template #placeholder="type">
<Flex
v-if="type && type.type === 'inline'"
align="center"
justify="center"
vertical
gap="2"
>
<Typography.Text style="font-size: 30px; line-height: 1">
<CloudUploadOutlined />
</Typography.Text>
<Typography.Title
:level="5"
style="margin: 0; font-size: 14px; line-height: 1.5"
>
Upload files
</Typography.Title>
<Typography.Text type="secondary">
Click or drag files to this area to upload
</Typography.Text>
</Flex>
<Typography.Text v-if="type && type.type === 'drop'">
Drop file here
</Typography.Text>
</template>
</Attachments>
</Sender.Header>
</template>
</Sender>
</div>
</div>
</template>
@ -344,10 +292,12 @@ watch(
<style scoped lang="less">
.layout {
width: 100%;
min-width: 1400px;
//min-width: 1400px;
max-height: 100vh;
display: flex;
flex-direction: column;
padding: 0;
margin: 0 auto;
background: hsl(216deg 21.74% 95.49%);
font-family: AlibabaPuHuiTi, v-deep(var(--ant-font-family)), sans-serif;
border-radius: v-deep(var(--ant-border-radius));
@ -356,14 +306,20 @@ watch(
.chat {
width: 100%;
height: 100%;
max-height: 88vh;
max-width: 1000px;
margin: 0 auto;
//max-height: 88vh;
//margin: 0 auto;
box-sizing: border-box;
display: flex;
flex-direction: column;
padding: 12px;
gap: 16px;
//flex-direction: column;
padding: 0 12px 0 12px;
}
.chat-left {
width: 40%;
height: 100%;
background: #ffffff;
//margin: 0 auto;
box-sizing: border-box;
padding: 12px 12px 0 12px;
}
.placeholder {
@ -375,6 +331,7 @@ watch(
.sender {
background: #ffffff;
width: 100%;
min-height: 100px;
box-shadow: v-deep(var(--ant-box-shadow));
}
</style>

View File

@ -108,9 +108,10 @@ onMounted(() => {
<style scoped lang="less">
.layout {
width: 100%;
min-width: 1400px;
//min-width: 1400px;
height: 100%;
display: flex;
padding: 0;
background: hsl(216deg 21.74% 95.49%);
font-family: AlibabaPuHuiTi, v-deep(var(--ant-font-family)), sans-serif;
border-radius: v-deep(var(--ant-border-radius));