refactor(@vben/web-antd): 重构 PPT 生成页面
- 更新基本表单的验证逻辑 - 优化 PPT 生成和预览流程 - 添加思维链展示功能 - 改进错误处理和用户提示 - 调整页面布局和样式
This commit is contained in:
parent
b2b6a202ea
commit
74da2052e1
@ -176,7 +176,7 @@ export function updateUser(id: any, data: UserApi.UserRecord) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function selfUpdate(data: UserApi.UserUpdateRecord) {
|
export function selfUpdate(data: UserApi.UserUpdateRecord) {
|
||||||
return requestClient.patch<UserApi.Res>(`/rest/user/self`, data);
|
return requestClient.patch<boolean>(`/rest/user/self`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取个人用户信息
|
// 获取个人用户信息
|
||||||
|
@ -27,7 +27,7 @@ const handleSubmit = async () => {
|
|||||||
email: userInfo.value.email,
|
email: userInfo.value.email,
|
||||||
address: userInfo.value.address,
|
address: userInfo.value.address,
|
||||||
});
|
});
|
||||||
if (res.code === 200) {
|
if (res) {
|
||||||
notification.success({
|
notification.success({
|
||||||
message: '修改成功',
|
message: '修改成功',
|
||||||
description: '用户信息已更新',
|
description: '用户信息已更新',
|
||||||
@ -36,7 +36,7 @@ const handleSubmit = async () => {
|
|||||||
} else {
|
} else {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: '修改失败',
|
message: '修改失败',
|
||||||
description: res.msg,
|
description: res,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,42 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { BubbleListProps } from 'ant-design-x-vue';
|
import type { ThoughtChainItem } from 'ant-design-x-vue';
|
||||||
|
|
||||||
import type { DrawerPlacement } from '@vben/common-ui';
|
import type { DrawerPlacement } from '@vben/common-ui';
|
||||||
|
|
||||||
import type { PropsWork, ResultItem } from '../typing';
|
import type { PropsWork, ResultItem } from '../typing';
|
||||||
|
|
||||||
|
import type { WorkflowResult } from '#/views/word/typing';
|
||||||
|
|
||||||
import { h, ref, watch } from 'vue';
|
import { h, ref, watch } from 'vue';
|
||||||
|
|
||||||
import { useVbenDrawer } from '@vben/common-ui';
|
import { useVbenDrawer } from '@vben/common-ui';
|
||||||
import { useUserStore } from '@vben/stores';
|
import { SvgPPT } from '@vben/icons';
|
||||||
|
import { useAccessStore, useUserStore } from '@vben/stores';
|
||||||
|
|
||||||
import { UserOutlined } from '@ant-design/icons-vue';
|
import {
|
||||||
import { Button, Flex, Space } from 'ant-design-vue';
|
Card,
|
||||||
import { Attachments, Bubble, Sender, Welcome } from 'ant-design-x-vue';
|
CardContent,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
VbenIcon,
|
||||||
|
} from '@vben-core/shadcn-ui';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CheckCircleOutlined,
|
||||||
|
InfoCircleOutlined,
|
||||||
|
LoadingOutlined,
|
||||||
|
// UserOutlined,
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
|
import { Button, notification, Space } from 'ant-design-vue';
|
||||||
|
import {
|
||||||
|
// Attachments,
|
||||||
|
Sender,
|
||||||
|
ThoughtChain,
|
||||||
|
Welcome,
|
||||||
|
XStream,
|
||||||
|
} from 'ant-design-x-vue';
|
||||||
|
|
||||||
|
import { getToken } from '#/api/csrf';
|
||||||
|
|
||||||
import PptPreview from './ppt-preview.vue';
|
import PptPreview from './ppt-preview.vue';
|
||||||
|
|
||||||
@ -41,145 +65,202 @@ const props = withDefaults(defineProps<PropsWork>(), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const roles: BubbleListProps['roles'] = {
|
// const roles: BubbleListProps['roles'] = {
|
||||||
user: {
|
// user: {
|
||||||
placement: 'end',
|
// placement: 'end',
|
||||||
typing: false,
|
// typing: false,
|
||||||
styles: {
|
// styles: {
|
||||||
content: {
|
// content: {
|
||||||
background: '#ffffff',
|
// background: '#ffffff',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
avatar: { icon: h(UserOutlined), style: { background: '#87d068' } },
|
// avatar: { icon: h(UserOutlined), style: { background: '#87d068' } },
|
||||||
},
|
// },
|
||||||
ai: {
|
// ai: {
|
||||||
placement: 'start',
|
// placement: 'start',
|
||||||
typing: false,
|
// typing: false,
|
||||||
style: {
|
// style: {
|
||||||
maxWidth: 600,
|
// maxWidth: 600,
|
||||||
marginInlineEnd: 44,
|
// marginInlineEnd: 44,
|
||||||
},
|
// },
|
||||||
styles: {
|
// styles: {
|
||||||
content: {
|
// content: {
|
||||||
background: '#ffffff',
|
// background: '#ffffff',
|
||||||
},
|
// },
|
||||||
footer: {
|
// footer: {
|
||||||
width: '100%',
|
// width: '100%',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
avatar: { icon: h(UserOutlined), style: { background: '#fde3cf' } },
|
// avatar: { icon: h(UserOutlined), style: { background: '#fde3cf' } },
|
||||||
},
|
// },
|
||||||
file: {
|
// file: {
|
||||||
placement: 'start',
|
// placement: 'start',
|
||||||
avatar: { icon: h(UserOutlined), style: { visibility: 'hidden' } },
|
// avatar: { icon: h(UserOutlined), style: { visibility: 'hidden' } },
|
||||||
variant: 'borderless',
|
// variant: 'borderless',
|
||||||
messageRender: (items: any) =>
|
// messageRender: (items: any) =>
|
||||||
h(
|
// h(
|
||||||
Flex,
|
// Flex,
|
||||||
{ vertical: true, gap: 'middle' },
|
// { vertical: true, gap: 'middle' },
|
||||||
items.map((item: any) =>
|
// items.map((item: any) =>
|
||||||
h(Attachments.FileCard, { key: item.uid, item }),
|
// h(Attachments.FileCard, { key: item.uid, item }),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
|
|
||||||
// ==================== State ====================
|
// ==================== State ====================
|
||||||
const content = ref('');
|
const content = ref('');
|
||||||
const agentRequestLoading = ref(false);
|
const agentRequestLoading = ref(false);
|
||||||
const fetchStatus = ref('');
|
const fetchStatus = ref('');
|
||||||
const resultItems = ref<ResultItem[]>([]);
|
const resultItems = ref<ResultItem[]>([]);
|
||||||
const fetchResult = ref('');
|
const accessStore = useAccessStore();
|
||||||
|
const mockServerResponseData: ThoughtChainItem[] = [];
|
||||||
|
const chainItems = ref<ThoughtChainItem[]>(mockServerResponseData);
|
||||||
|
// const fetchResult = ref('');
|
||||||
|
const pptMessage = ref('');
|
||||||
|
|
||||||
const [PreviewDrawer, previewDrawerApi] = useVbenDrawer({
|
const [PreviewDrawer, previewDrawerApi] = useVbenDrawer({
|
||||||
// 连接抽离的组件
|
// 连接抽离的组件
|
||||||
connectedComponent: PptPreview,
|
connectedComponent: PptPreview,
|
||||||
// placement: 'left',
|
// placement: 'left',
|
||||||
});
|
});
|
||||||
function openPreviewDrawer(
|
function openPreviewDrawer(placement: DrawerPlacement = 'right', file?: any) {
|
||||||
placement: DrawerPlacement = 'right',
|
previewDrawerApi.setState({ placement }).setData(file.url).open();
|
||||||
filename?: string,
|
|
||||||
) {
|
|
||||||
previewDrawerApi.setState({ placement }).setData(filename).open();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Event ====================
|
// ==================== Event ====================
|
||||||
// 判断是否是以 .pptx 结尾的 URL
|
function getStatusIcon(status: ThoughtChainItem['status']) {
|
||||||
// function isPptxURL(str: string): boolean {
|
switch (status) {
|
||||||
// return str.endsWith('.pptx');
|
case 'error': {
|
||||||
// }
|
return h(InfoCircleOutlined);
|
||||||
|
}
|
||||||
|
case 'pending': {
|
||||||
|
return h(LoadingOutlined);
|
||||||
|
}
|
||||||
|
case 'success': {
|
||||||
|
return h(CheckCircleOutlined);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadPpt(files: any) {
|
||||||
|
// 创建隐藏的 <a> 标签用于触发下载
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = files.url; // 设置下载链接
|
||||||
|
link.download = files.filename; // 设置下载文件名
|
||||||
|
document.body.append(link); // 将 <a> 标签添加到页面中
|
||||||
|
link.click(); // 触发点击事件开始下载
|
||||||
|
link.remove(); // 下载完成后移除 <a> 标签
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateChainItem(status: ThoughtChainItem['status']) {
|
||||||
|
if (mockServerResponseData.length > 0) {
|
||||||
|
mockServerResponseData[mockServerResponseData.length - 1].status = status;
|
||||||
|
mockServerResponseData[mockServerResponseData.length - 1].icon =
|
||||||
|
getStatusIcon(status);
|
||||||
|
mockServerResponseData[mockServerResponseData.length - 1].description =
|
||||||
|
`status: ${status}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseAndRenderStream(text: WorkflowResult) {
|
||||||
|
let parsedData;
|
||||||
|
try {
|
||||||
|
parsedData = JSON.parse(text?.data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to parse event data:', error);
|
||||||
|
chainItems.value = [];
|
||||||
|
notification.error({
|
||||||
|
message: '流式数据解析失败',
|
||||||
|
description: '无法解析来自服务器的数据,请检查网络连接或稍后重试。',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { event, data } = parsedData;
|
||||||
|
if (event === 'node_started' && data) {
|
||||||
|
mockServerResponseData.push({
|
||||||
|
key: data.nodeId,
|
||||||
|
title: data.title,
|
||||||
|
description: data.nodeType,
|
||||||
|
icon: getStatusIcon('pending'),
|
||||||
|
status: 'pending',
|
||||||
|
});
|
||||||
|
chainItems.value = [...mockServerResponseData];
|
||||||
|
} else if (
|
||||||
|
event === 'node_finished' &&
|
||||||
|
data &&
|
||||||
|
mockServerResponseData.length > 0
|
||||||
|
) {
|
||||||
|
updateChainItem('success');
|
||||||
|
chainItems.value = [...mockServerResponseData];
|
||||||
|
if (data.outputs.files?.length > 0) {
|
||||||
|
pptMessage.value = data.outputs.files[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const startFetching = async () => {
|
const startFetching = async () => {
|
||||||
resultItems.value = [];
|
resultItems.value = [];
|
||||||
|
pptMessage.value = '';
|
||||||
agentRequestLoading.value = true;
|
agentRequestLoading.value = true;
|
||||||
fetchStatus.value = 'fetching';
|
fetchStatus.value = 'fetching';
|
||||||
resultItems.value.push({
|
// resultItems.value.push({
|
||||||
key: resultItems.value.length + 1,
|
// key: resultItems.value.length + 1,
|
||||||
role: 'user',
|
// role: 'user',
|
||||||
content: content.value,
|
// content: content.value,
|
||||||
});
|
// });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await props.runWorkflow(props.item.id, {
|
const res = await fetch(`/api/v1/workflow/run/stream/${props.item.id}`, {
|
||||||
userId: userStore.userInfo?.userId || '',
|
method: 'POST',
|
||||||
conversationId: '',
|
body: JSON.stringify({
|
||||||
files: [],
|
userId: userStore.userInfo?.userId || '',
|
||||||
inputs: {
|
conversationId: '',
|
||||||
declarationDoc: content.value,
|
files: [],
|
||||||
|
inputs: {
|
||||||
|
declarationDoc: content.value,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Accept-Language': 'zh-CN',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': getToken() || '',
|
||||||
|
Authorization: `Bearer ${accessStore.accessToken}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const files = res.data.outputs.files[0];
|
// 实时更新 AI 消息
|
||||||
content.value = '';
|
for await (const chunk of XStream({ readableStream: res.body })) {
|
||||||
|
// console.log('chunk', chunk.data);
|
||||||
// const filename = ref('');
|
// const text = new TextDecoder().decode(chunk.data);
|
||||||
|
parseAndRenderStream(chunk);
|
||||||
// if (result && isPptxURL(result)) {
|
}
|
||||||
// filename.value = extractPptxFilename(result);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 保存抓取结果 url http://47.112.173.8:6802/static/66f3cfd95e364a239d8036390db658ae.pptx
|
|
||||||
fetchResult.value = files.url;
|
|
||||||
resultItems.value.push({
|
|
||||||
key: resultItems.value.length + 1,
|
|
||||||
role: 'ai',
|
|
||||||
content: '文档已生成',
|
|
||||||
footer: h(Flex, null, [
|
|
||||||
h(
|
|
||||||
Button,
|
|
||||||
{
|
|
||||||
type: 'primary',
|
|
||||||
onClick: () => {
|
|
||||||
openPreviewDrawer('right', files.url);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'文档预览',
|
|
||||||
),
|
|
||||||
h(
|
|
||||||
Button,
|
|
||||||
{
|
|
||||||
type: 'primary',
|
|
||||||
style: {
|
|
||||||
marginLeft: '10px',
|
|
||||||
},
|
|
||||||
onClick: () => {
|
|
||||||
// 创建隐藏的 <a> 标签用于触发下载
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = files.url; // 设置下载链接
|
|
||||||
link.download = files.filename; // 设置下载文件名
|
|
||||||
document.body.append(link); // 将 <a> 标签添加到页面中
|
|
||||||
link.click(); // 触发点击事件开始下载
|
|
||||||
link.remove(); // 下载完成后移除 <a> 标签
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'文档下载',
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error('Stream processing failed:', error);
|
||||||
|
notification.error({
|
||||||
|
message: '请求失败',
|
||||||
|
description: 'AI 回答获取失败,请稍后再试',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const res = await props.runWorkflow(props.item.id, {
|
||||||
|
// userId: userStore.userInfo?.userId || '',
|
||||||
|
// conversationId: '',
|
||||||
|
// files: [],
|
||||||
|
// inputs: {
|
||||||
|
// declarationDoc: content.value,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error(error);
|
||||||
|
// }
|
||||||
|
|
||||||
// 模拟抓取完成
|
// 模拟抓取完成
|
||||||
|
content.value = '';
|
||||||
agentRequestLoading.value = false;
|
agentRequestLoading.value = false;
|
||||||
fetchStatus.value = 'completed';
|
fetchStatus.value = 'completed';
|
||||||
};
|
};
|
||||||
@ -191,56 +272,58 @@ watch(
|
|||||||
() => props.itemMessage,
|
() => props.itemMessage,
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
resultItems.value = [];
|
resultItems.value = [];
|
||||||
|
chainItems.value = [];
|
||||||
content.value = '';
|
content.value = '';
|
||||||
if (newVal && newVal.length > 0) {
|
pptMessage.value = newVal[1]?.content;
|
||||||
newVal.forEach((msg) => {
|
// if (newVal && newVal.length > 0) {
|
||||||
if (msg.role === 'user') {
|
// newVal.forEach((msg) => {
|
||||||
resultItems.value.push({
|
// if (msg.role === 'user') {
|
||||||
key: resultItems.value.length + 1,
|
// resultItems.value.push({
|
||||||
role: msg.role, // 'user' or 'ai'
|
// key: resultItems.value.length + 1,
|
||||||
content: msg.content,
|
// role: msg.role, // 'user' or 'ai'
|
||||||
footer: msg.footer,
|
// content: msg.content,
|
||||||
});
|
// footer: msg.footer,
|
||||||
} else {
|
// });
|
||||||
resultItems.value.push({
|
// } else {
|
||||||
key: resultItems.value.length + 1,
|
// resultItems.value.push({
|
||||||
role: msg.role, // 'user' or 'ai'
|
// key: resultItems.value.length + 1,
|
||||||
content: '文档已生成',
|
// role: msg.role, // 'user' or 'ai'
|
||||||
footer: h(Flex, null, [
|
// content: '文档已生成',
|
||||||
h(
|
// footer: h(Flex, null, [
|
||||||
Button,
|
// h(
|
||||||
{
|
// Button,
|
||||||
type: 'primary',
|
// {
|
||||||
onClick: () => {
|
// type: 'primary',
|
||||||
openPreviewDrawer('right', msg.content.url);
|
// onClick: () => {
|
||||||
},
|
// openPreviewDrawer('right', msg.content.url);
|
||||||
},
|
// },
|
||||||
'文档预览',
|
// },
|
||||||
),
|
// '文档预览',
|
||||||
h(
|
// ),
|
||||||
Button,
|
// h(
|
||||||
{
|
// Button,
|
||||||
type: 'primary',
|
// {
|
||||||
style: {
|
// type: 'primary',
|
||||||
marginLeft: '10px',
|
// style: {
|
||||||
},
|
// marginLeft: '10px',
|
||||||
onClick: () => {
|
// },
|
||||||
// 创建隐藏的 <a> 标签用于触发下载
|
// onClick: () => {
|
||||||
const link = document.createElement('a');
|
// // 创建隐藏的 <a> 标签用于触发下载
|
||||||
link.href = msg.content.url; // 设置下载链接
|
// const link = document.createElement('a');
|
||||||
link.download = msg.content.filename; // 设置下载文件名
|
// link.href = msg.content.url; // 设置下载链接
|
||||||
document.body.append(link); // 将 <a> 标签添加到页面中
|
// link.download = msg.content.filename; // 设置下载文件名
|
||||||
link.click(); // 触发点击事件开始下载
|
// document.body.append(link); // 将 <a> 标签添加到页面中
|
||||||
link.remove(); // 下载完成后移除 <a> 标签
|
// link.click(); // 触发点击事件开始下载
|
||||||
},
|
// link.remove(); // 下载完成后移除 <a> 标签
|
||||||
},
|
// },
|
||||||
'文档下载',
|
// },
|
||||||
),
|
// '文档下载',
|
||||||
]),
|
// ),
|
||||||
});
|
// ]),
|
||||||
}
|
// });
|
||||||
});
|
// }
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
);
|
);
|
||||||
@ -267,29 +350,44 @@ watch(
|
|||||||
</template>
|
</template>
|
||||||
</Sender>
|
</Sender>
|
||||||
</div>
|
</div>
|
||||||
|
<Space direction="vertical" size:16 class="chat-right">
|
||||||
<Space
|
<!-- 思维链 -->
|
||||||
v-if="resultItems.length === 0"
|
<ThoughtChain size="large" :items="chainItems">
|
||||||
direction="vertical"
|
<ThoughtChainItem
|
||||||
size:16
|
v-for="item in chainItems"
|
||||||
style="width: 60%; padding: 20px 0 0 12px"
|
:key="item.key"
|
||||||
>
|
style="background: #0d0d10"
|
||||||
|
/>
|
||||||
|
</ThoughtChain>
|
||||||
<Welcome
|
<Welcome
|
||||||
|
v-if="chainItems.length <= 0 && !pptMessage"
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
icon="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp"
|
icon="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp"
|
||||||
title="欢迎使用PPT自动生成"
|
title="欢迎使用PPT自动生成"
|
||||||
description="请选择模板列表中需要生成文件的模板,输入参数后开始生成生成文件。"
|
description="请选择模板列表中需要生成文件的模板,输入参数后开始生成生成文件。"
|
||||||
/>
|
/>
|
||||||
|
<ADivider v-if="pptMessage && chainItems.length > 0" />
|
||||||
|
<Card
|
||||||
|
v-if="pptMessage"
|
||||||
|
title="PPT"
|
||||||
|
class="w-5/12 cursor-pointer hover:shadow-xl"
|
||||||
|
style="background: transparent"
|
||||||
|
>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle class="flex-start flex text-xl">
|
||||||
|
<VbenIcon :icon="SvgPPT" class="size-8 flex-shrink-0" />
|
||||||
|
PPT已生成,有效时间五分钟
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
|
||||||
|
<CardContent class="flex items-center justify-around">
|
||||||
|
<Button @click="() => openPreviewDrawer('right', pptMessage)">
|
||||||
|
预览
|
||||||
|
</Button>
|
||||||
|
<Button @click="downloadPpt(pptMessage)">下载</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
</Space>
|
</Space>
|
||||||
<!-- 🌟 消息列表 -->
|
|
||||||
<Bubble.List
|
|
||||||
v-else
|
|
||||||
style="width: 60%; padding: 12px"
|
|
||||||
variant="shadow"
|
|
||||||
:typing="true"
|
|
||||||
:items="resultItems"
|
|
||||||
:roles="roles"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -303,7 +401,6 @@ watch(
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background: hsl(216deg 21.74% 95.49%);
|
|
||||||
font-family: AlibabaPuHuiTi, v-deep(var(--ant-font-family)), sans-serif;
|
font-family: AlibabaPuHuiTi, v-deep(var(--ant-font-family)), sans-serif;
|
||||||
border-radius: v-deep(var(--ant-border-radius));
|
border-radius: v-deep(var(--ant-border-radius));
|
||||||
}
|
}
|
||||||
@ -327,6 +424,14 @@ watch(
|
|||||||
padding: 12px 12px 0 12px;
|
padding: 12px 12px 0 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chat-right {
|
||||||
|
width: 60%;
|
||||||
|
height: auto;
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
padding: 20px;
|
||||||
|
background: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
.placeholder {
|
.placeholder {
|
||||||
padding-top: 32px;
|
padding-top: 32px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -292,7 +292,8 @@ watch(
|
|||||||
<CardTitle class="text-lg">{{ title }}</CardTitle>
|
<CardTitle class="text-lg">{{ title }}</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="flex flex-wrap pt-0">
|
<CardContent class="flex flex-wrap pt-0">
|
||||||
{{ props.item ? props.item.description : '请选择左侧列表' }}
|
<!-- {{ props.item ? props.item.description : 'https://www.gzggzy.cn/' }}-->
|
||||||
|
https://www.gzggzy.cn/
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<CardFooter class="flex justify-end">
|
<CardFooter class="flex justify-end">
|
||||||
<Button :disabled="!item" type="primary" @click="startFetching">
|
<Button :disabled="!item" type="primary" @click="startFetching">
|
||||||
|
Loading…
Reference in New Issue
Block a user