|
@@ -0,0 +1,207 @@
|
|
|
|
+import {
|
|
|
|
+ Bubble,
|
|
|
|
+ Conversations,
|
|
|
|
+ Prompts,
|
|
|
|
+ Sender,
|
|
|
|
+ Suggestion,
|
|
|
|
+ ThoughtChain,
|
|
|
|
+ XProvider,
|
|
|
|
+ useXAgent,
|
|
|
|
+ useXChat,
|
|
|
|
+ Welcome,
|
|
|
|
+} from "@ant-design/x";
|
|
|
|
+
|
|
|
|
+import { Card, Divider, Flex, Radio, Typography, App } from "antd";
|
|
|
|
+import React from "react";
|
|
|
|
+
|
|
|
|
+import {
|
|
|
|
+ BulbOutlined,
|
|
|
|
+ SmileOutlined,
|
|
|
|
+ UserOutlined,
|
|
|
|
+ CoffeeOutlined,
|
|
|
|
+ FireOutlined,
|
|
|
|
+ EditOutlined,
|
|
|
|
+ DeleteOutlined,
|
|
|
|
+ MessageOutlined,
|
|
|
|
+} from "@ant-design/icons";
|
|
|
|
+import type { GetProp } from "antd";
|
|
|
|
+import type { PromptsProps, ConversationsProps } from "@ant-design/x";
|
|
|
|
+
|
|
|
|
+const promptsItems: PromptsProps["items"] = [
|
|
|
|
+ {
|
|
|
|
+ key: "1",
|
|
|
|
+ icon: <CoffeeOutlined style={{ color: "#964B00" }} />,
|
|
|
|
+ description: "怎么创建我的应用?",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ key: "2",
|
|
|
|
+ icon: <SmileOutlined style={{ color: "#FAAD14" }} />,
|
|
|
|
+ description: "页面设计器如何使用?",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ key: "3",
|
|
|
|
+ icon: <FireOutlined style={{ color: "#FF4D4F" }} />,
|
|
|
|
+ description: "如何生成页面SQL?",
|
|
|
|
+ },
|
|
|
|
+];
|
|
|
|
+
|
|
|
|
+const roles: GetProp<typeof Bubble.List, "roles"> = {
|
|
|
|
+ assient: {
|
|
|
|
+ placement: "start",
|
|
|
|
+ avatar: {
|
|
|
|
+ icon: <i className="iconfont icon-AI1" />,
|
|
|
|
+ style: { background: "#fde3cf" },
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ user: {
|
|
|
|
+ placement: "end",
|
|
|
|
+ avatar: { icon: <UserOutlined />, style: { background: "#87d068" } },
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+export default () => {
|
|
|
|
+ const [value, setValue] = React.useState("");
|
|
|
|
+ const { message } = App.useApp();
|
|
|
|
+
|
|
|
|
+ const [agent] = useXAgent<{role: string, content: string}>({
|
|
|
|
+ baseURL: "http://localhost:3000/ai/chat",
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const { onRequest, messages } = useXChat({ agent });
|
|
|
|
+
|
|
|
|
+ const menuConfig: ConversationsProps["menu"] = (conversation) => ({
|
|
|
|
+ items: [
|
|
|
|
+ {
|
|
|
|
+ label: "修改对话名称",
|
|
|
|
+ key: "operation1",
|
|
|
|
+ icon: <EditOutlined />,
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "删除对话",
|
|
|
|
+ key: "operation3",
|
|
|
|
+ icon: <DeleteOutlined />,
|
|
|
|
+ danger: true,
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ onClick: (menuInfo) => {
|
|
|
|
+ message.info(`Click ${conversation.key} - ${menuInfo.key}`);
|
|
|
|
+ },
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const submitMessage = (message: string) => {
|
|
|
|
+ onRequest({role: "user", content: message});
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const handlePromptItem = (item: any) => {
|
|
|
|
+ onRequest({role: "user", content: item.data.description});
|
|
|
|
+ };
|
|
|
|
+ console.log(messages)
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <Card
|
|
|
|
+ className="w-full h-full"
|
|
|
|
+ styles={{
|
|
|
|
+ body: {
|
|
|
|
+ height: "calc(100% - 48px)",
|
|
|
|
+ },
|
|
|
|
+ }}
|
|
|
|
+ title={
|
|
|
|
+ <span>
|
|
|
|
+ <em-emoji id="*️⃣"></em-emoji>综合助手
|
|
|
|
+ </span>
|
|
|
|
+ }
|
|
|
|
+ >
|
|
|
|
+ <XProvider direction="ltr">
|
|
|
|
+ <Flex style={{ height: "100%" }} gap={12}>
|
|
|
|
+ <Conversations
|
|
|
|
+ style={{ width: 200 }}
|
|
|
|
+ defaultActiveKey="1"
|
|
|
|
+ menu={menuConfig}
|
|
|
|
+ items={[
|
|
|
|
+ {
|
|
|
|
+ key: "1",
|
|
|
|
+ label: "新的对话",
|
|
|
|
+ icon: <MessageOutlined />,
|
|
|
|
+ },
|
|
|
|
+ ]}
|
|
|
|
+ />
|
|
|
|
+ <Divider type="vertical" style={{ height: "100%" }} />
|
|
|
|
+ <Flex vertical style={{ flex: 1 }} gap={8}>
|
|
|
|
+ <div className="flex-1">
|
|
|
|
+ {!messages.length ? (
|
|
|
|
+ <>
|
|
|
|
+ <Welcome
|
|
|
|
+ icon="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp"
|
|
|
|
+ title="你好!我是易码工坊AI助手"
|
|
|
|
+ description="关于易码工坊的所有问题,你都可以向我咨询~"
|
|
|
|
+ className="mt-20 mb-10"
|
|
|
|
+ />
|
|
|
|
+ <Prompts
|
|
|
|
+ title="✨ 你可以这样问我:"
|
|
|
|
+ items={promptsItems}
|
|
|
|
+ wrap
|
|
|
|
+ onItemClick={handlePromptItem}
|
|
|
|
+ />
|
|
|
|
+ </>
|
|
|
|
+ ) : (
|
|
|
|
+ <Bubble.List
|
|
|
|
+ autoScroll
|
|
|
|
+ roles={roles}
|
|
|
|
+ items={
|
|
|
|
+ []
|
|
|
|
+ // messages.map(({ id, message, status }) => ({
|
|
|
|
+ // key: id,
|
|
|
|
+ // loading: status === "loading",
|
|
|
|
+ // role: status === "user" ? "local" : "ai",
|
|
|
|
+ // content: message,
|
|
|
|
+ // }))
|
|
|
|
+ }
|
|
|
|
+ />
|
|
|
|
+ )}
|
|
|
|
+ </div>
|
|
|
|
+ <Prompts
|
|
|
|
+ items={[
|
|
|
|
+ {
|
|
|
|
+ key: "1",
|
|
|
|
+ icon: <BulbOutlined style={{ color: "#FFD700" }} />,
|
|
|
|
+ label: "Ignite Your Creativity",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ key: "2",
|
|
|
|
+ icon: <SmileOutlined style={{ color: "#52C41A" }} />,
|
|
|
|
+ label: "Tell me a Joke",
|
|
|
|
+ },
|
|
|
|
+ ]}
|
|
|
|
+ onItemClick={handlePromptItem}
|
|
|
|
+ />
|
|
|
|
+
|
|
|
|
+ <Suggestion
|
|
|
|
+ items={[{ label: "写一个应用介绍", value: "report" }]}
|
|
|
|
+ onSelect={submitMessage}
|
|
|
|
+ >
|
|
|
|
+ {({ onTrigger, onKeyDown }) => {
|
|
|
|
+ return (
|
|
|
|
+ <Sender
|
|
|
|
+ value={value}
|
|
|
|
+ onChange={(nextVal) => {
|
|
|
|
+ if (nextVal === "/") {
|
|
|
|
+ onTrigger();
|
|
|
|
+ } else if (!nextVal) {
|
|
|
|
+ onTrigger(false);
|
|
|
|
+ }
|
|
|
|
+ setValue(nextVal);
|
|
|
|
+ }}
|
|
|
|
+ onKeyDown={onKeyDown}
|
|
|
|
+ placeholder='输入/获取快捷提示'
|
|
|
|
+ onSubmit={submitMessage}
|
|
|
|
+ />
|
|
|
|
+ );
|
|
|
|
+ }}
|
|
|
|
+ </Suggestion>
|
|
|
|
+ </Flex>
|
|
|
|
+ </Flex>
|
|
|
|
+ </XProvider>
|
|
|
|
+ </Card>
|
|
|
|
+ </>
|
|
|
|
+ );
|
|
|
|
+};
|