feat(@vben/common-ui): 重构 PPT、Spider 和 Word 组件

This commit is contained in:
Kven 2025-05-26 19:28:44 +08:00
parent 26651e0b20
commit 2911293bc8
10 changed files with 22 additions and 220 deletions

View File

@ -1,4 +1,2 @@
export { default as PptHistoryView } from './ppt-history-view.vue';
export { default as PptListView } from './ppt-list-view.vue';
export { default as PptWorkView } from './ppt-work-view.vue';
export type * from './typing';

View File

@ -1,22 +1,15 @@
<script setup lang="ts">
import type { ConversationsProps } from 'ant-design-x-vue';
import type { PptHistoryItem } from './typing';
import type { Props } from '../typing';
import { computed, ref } from 'vue';
// import { Card, CardContent, CardHeader, CardTitle } from '@vben-core/shadcn-ui';
import { Menu } from 'ant-design-vue';
import { Conversations } from 'ant-design-x-vue';
interface Props {
items?: PptHistoryItem[];
title: string;
loading: boolean;
}
defineOptions({
name: 'WordListView',
name: 'PptListView',
});
const props = withDefaults(defineProps<Props>(), {
@ -42,16 +35,6 @@ const itemsData = ref([
},
]);
// const items2: ItemType[] = reactive([
// getItem(
// '',
// 'grp',
// null,
// [getItem('', 'baca08c1-e92b-4dc9-a445-3584803f54d4')],
// 'group',
// ),
// ]);
const handleMenuClick = (item: { key: string }) => {
const selectedItem = itemsData.value.find((i) => i.key === item.key);
if (selectedItem) {
@ -75,20 +58,6 @@ const onConversationClick: ConversationsProps['onActiveChange'] = (key) => {
}
};
// const menuConfig: ConversationsProps['menu'] = (conversation) => ({
// items: [
// {
// label: '',
// key: conversation.key,
// icon: h(DeleteOutlined),
// danger: true,
// },
// ],
// onClick: (menuInfo) => {
// emit('delete', menuInfo.key)
// },
// });
const selectedKeys = ref([]);
const openKeys = ref([]);
</script>
@ -104,11 +73,8 @@ const openKeys = ref([]);
:items="itemsData"
@click="handleMenuClick"
/>
<!-- 🌟 添加会话 -->
<!-- <Button type="link" class="addBtn">会话</Button>-->
<div class="addBtn">会话</div>
<!-- 🌟 添加会话 -->
<div class="addBtn">会话</div>
<!-- 🌟 会话管理 -->
<Conversations
:items="conversationsItems"
@ -161,10 +127,6 @@ const openKeys = ref([]);
gap: 16px;
}
//.messages {
// flex: 1;
//}
.placeholder {
padding-top: 32px;
text-align: left;

View File

@ -1,13 +1,14 @@
<script setup lang="ts">
import type { AttachmentsProps, BubbleListProps } from 'ant-design-x-vue';
import type { DrawerPlacement } from '@vben-core/popup-ui';
import type { DrawerPlacement } from '@vben/common-ui';
import type { PPTTempItem } from './typing';
import type { PropsWork, ResultItem } from '../typing';
import { h, ref, watch } from 'vue';
import { useVbenDrawer } from '@vben-core/popup-ui';
import { useVbenDrawer } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';
import {
CloudUploadOutlined,
@ -17,39 +18,11 @@ import {
import { Badge, Button, Flex, Space, Typography } from 'ant-design-vue';
import { Attachments, Bubble, Sender, Welcome } from 'ant-design-x-vue';
import PptPreview from './ppt-perview.vue';
import PptPreview from './ppt-preview.vue';
interface ResultItem {
key: number;
role: 'ai' | 'user';
content: string;
footer?: any;
}
defineOptions({ name: 'PptWorkView' });
interface WorkflowContext {
userId: string;
conversationId: string;
files: unknown[];
inputs: Record<string, unknown>;
}
interface WorkflowResult {
data: {
outputs: {
result: string;
};
};
}
interface Props {
itemMessage?: ResultItem;
item?: PPTTempItem;
runWorkflow?: (context: WorkflowContext) => Promise<WorkflowResult>;
}
defineOptions({ name: 'PlaygroundIndependentSetup' });
const props = withDefaults(defineProps<Props>(), {
const props = withDefaults(defineProps<PropsWork>(), {
itemMessage: () => null,
item: () => null,
runWorkflow: () => async () => ({
@ -61,8 +34,7 @@ const props = withDefaults(defineProps<Props>(), {
}),
});
// const { token } = theme.useToken();
const userStore = useUserStore();
const roles: BubbleListProps['roles'] = {
user: {
placement: 'end',
@ -158,7 +130,7 @@ const startFetching = async () => {
try {
const res = await props.runWorkflow({
userId: '1562',
userId: userStore.userInfo?.userId || '',
conversationId: '',
files: [],
inputs: {
@ -232,12 +204,6 @@ watch(
resultItems.value = [];
if (newVal && newVal.length > 0) {
newVal.forEach((msg) => {
// resultItems.value.push({
// key: resultItems.value.length + 1,
// role: msg.role, // 'user' or 'ai'
// content: msg.content,
// footer: msg.footer,
// });
if (msg.role === 'user') {
resultItems.value.push({
key: resultItems.value.length + 1,

View File

@ -1,4 +1,2 @@
export type * from './typing';
export { default as WordHistoryView } from './word-history-view.vue';
export { default as WordListView } from './word-list-view.vue';
export { default as WordWorkView } from './word-work-view.vue';

View File

@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ConversationsProps } from 'ant-design-x-vue';
import type { WordHistoryItem } from './typing';
import type { PropsHistory } from '../typing';
import { computed, h, ref } from 'vue';
@ -10,17 +10,11 @@ import { DeleteOutlined } from '@ant-design/icons-vue';
import { Menu } from 'ant-design-vue';
import { Conversations } from 'ant-design-x-vue';
interface Props {
items?: WordHistoryItem[];
title: string;
loading: boolean;
}
defineOptions({
name: 'WordListView',
});
const props = withDefaults(defineProps<Props>(), {
const props = withDefaults(defineProps<PropsHistory>(), {
items: () => [],
});
const emit = defineEmits(['click', 'clickMode', 'delete']);

View File

@ -5,13 +5,14 @@ import type {
PromptsProps,
} from 'ant-design-x-vue';
import type { DrawerPlacement } from '@vben-core/popup-ui';
import type { DrawerPlacement } from '@vben/common-ui';
import type { WordTempItem } from './typing';
import type { Props, ResultItem } from '../typing';
import { computed, h, ref, watch } from 'vue';
import { useVbenDrawer } from '@vben-core/popup-ui';
import { useVbenDrawer } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';
import {
EditOutlined,
@ -38,46 +39,13 @@ import {
Bubble,
Prompts,
Sender,
useXAgent,
useXChat,
Welcome,
} from 'ant-design-x-vue';
import markdownit from 'markdown-it';
import WordPreview from './word-preview.vue';
interface ResultItem {
key: number;
role: 'ai' | 'user';
content: string;
footer?: any;
}
interface WorkflowContext {
userId: string;
conversationId: string;
content: string;
inputs: {
[key: string]: any;
};
files: [];
}
interface WorkflowResult {
conversationId: string;
answer: {};
data: {
outputs: {
result: string;
};
};
}
interface Props {
itemMessage?: ResultItem;
item?: WordTempItem;
paramsData?: {};
runChatflow?: (context: WorkflowContext) => Promise<WorkflowResult>;
}
defineOptions({ name: 'PlaygroundIndependentSetup' });
defineOptions({ name: 'WordWorkView' });
const props = withDefaults(defineProps<Props>(), {
item: () => null,
@ -92,8 +60,6 @@ const props = withDefaults(defineProps<Props>(), {
}),
});
// const { token } = theme.useToken();
// markdown
const md = markdownit({ html: true, breaks: true });
@ -112,23 +78,7 @@ const renderMarkdown: BubbleListProps['roles'][string]['messageRender'] = (
]);
};
const sleep = () => new Promise((resolve) => setTimeout(resolve, 500));
// function renderTitle(icon: VNode, title: string) {
// return h(Space, { align: 'start' }, [icon, h('span', title)]);
// }
const defaultConversationsItems = [
{
key: '0',
label: 'What is Ant Design X?',
},
];
// {
// key: '1',
// description: '',
// icon: h(ReadOutlined, { style: { color: '#FF4D4F' } }),
// },
// const sleep = () => new Promise((resolve) => setTimeout(resolve, 500));
const senderPromptsItems = computed(() => {
if (typeof props.paramsData !== 'object' || props.paramsData === null)
@ -192,10 +142,10 @@ const roles: BubbleListProps['roles'] = {
};
// ==================== State ====================
const userStore = useUserStore();
const headerOpen = ref(false);
const content = ref('');
// const conversationsItems = ref(defaultConversationsItems);
const activeKey = ref(defaultConversationsItems[0].key);
const attachedFiles = ref<AttachmentsProps['items']>([]);
const agentRequestLoading = ref(false);
const projectInfo = ref({
@ -215,14 +165,6 @@ const layout = {
wrapperCol: { span: 16 },
};
// ==================== Runtime ====================
const [agent] = useXAgent({
request: async ({ message }, { onSuccess }) => {
agentRequestLoading.value = true;
await sleep();
agentRequestLoading.value = false;
onSuccess(`Mock success return. You said: ${message}`);
},
});
const [PreviewDrawer, previewDrawerApi] = useVbenDrawer({
//
@ -237,20 +179,6 @@ function openPreviewDrawer(
previewDrawerApi.setState({ placement }).setData(fileData).open();
}
const { setMessages } = useXChat({
agent: agent.value,
});
watch(
activeKey,
() => {
if (activeKey.value !== undefined) {
setMessages([]);
}
},
{ immediate: true },
);
// ==================== Event ====================
// .docx URL
@ -290,7 +218,7 @@ const startFetching = async () => {
try {
const res = await props.runChatflow({
userId: '1562',
userId: userStore.userInfo?.userId || '',
conversationId: conversationId.value,
files: [],
inputs: {
@ -370,9 +298,6 @@ const onPromptsItemClick: PromptsProps['onItemClick'] = (info) => {
content.value = info.data.description;
};
// const handleFileChange: AttachmentsProps['onChange'] = (info) =>
// (attachedFiles.value = info.fileList);
// itemMessage resultItems
watch(
() => props.itemMessage,
@ -528,47 +453,6 @@ watch(
</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>