diff --git a/src/modules/query.ts b/src/modules/query.ts index 27de975..9584cf5 100644 --- a/src/modules/query.ts +++ b/src/modules/query.ts @@ -2,7 +2,7 @@ import { Query, QueryClient } from '@kevisual/query'; import { QueryWs } from '@kevisual/query/ws'; import { modal } from './redirect-to-login'; import { create } from 'zustand'; -export const query = new Query(); +export const query = new QueryClient(); query.beforeRequest = async (config) => { if (config.headers) { const token = localStorage.getItem('token'); diff --git a/src/pages/ai-agent/index.tsx b/src/pages/ai-agent/index.tsx index 54c7e20..8451d22 100644 --- a/src/pages/ai-agent/index.tsx +++ b/src/pages/ai-agent/index.tsx @@ -12,3 +12,5 @@ export const App = () => { ); }; + +export * from './module/Select'; diff --git a/src/pages/ai-agent/module/Select.tsx b/src/pages/ai-agent/module/Select.tsx new file mode 100644 index 0000000..f730c5e --- /dev/null +++ b/src/pages/ai-agent/module/Select.tsx @@ -0,0 +1,39 @@ +import { query } from '@/modules'; +import { Select as AntSelect, message, SelectProps } from 'antd'; +import { useEffect, useState } from 'react'; + +export const Select = (props: SelectProps) => { + const [options, setOptions] = useState<{ value: string; id: string }[]>([]); + useEffect(() => { + fetch(); + }, []); + const fetch = async () => { + const res = await query.post({ + path: 'agent', + key: 'list', + }); + if (res.code !== 200) { + message.error(res.message || '获取agent列表失败'); + return; + } + const data = res.data || []; + setOptions( + data.map((item: any) => { + return { + label: item.key, + value: item.id, + }; + }), + ); + }; + return ( + { + // const labelValue = options.find((item) => item.value === e); + // props.onChange?.(e, options); + // }} + /> + ); +}; diff --git a/src/pages/ai-chat/AiModule.tsx b/src/pages/ai-chat/AiModule.tsx index 7e80aef..1c0a2f6 100644 --- a/src/pages/ai-chat/AiModule.tsx +++ b/src/pages/ai-chat/AiModule.tsx @@ -1,28 +1,180 @@ import { useShallow } from 'zustand/react/shallow'; import { useAiStore } from './store/ai-store'; -import { CloseOutlined, HistoryOutlined } from '@ant-design/icons'; -import { Button, Form, Input, Tooltip } from 'antd'; +import { CloseOutlined, HistoryOutlined, PlusOutlined } from '@ant-design/icons'; +import { Button, Dropdown, Form, Input, message, Modal, Tooltip } from 'antd'; import { useEffect } from 'react'; import { TextArea } from '../container/components/TextArea'; import clsx from 'clsx'; -import { marked } from 'marked'; +import { query } from '@/modules'; +import { nanoid } from 'nanoid'; +import { ChatMessage } from './module/ChatMessage'; +import { isObjectNull } from '@/utils/is-null'; +import { useNavigate } from 'react-router'; +const testId = '60aca66b-4be9-4266-9568-6001032c7e13'; + +type FormModalProps = { + send?: any; +}; +const FormModal = (props: FormModalProps) => { + const [form] = Form.useForm(); + const aiStore = useAiStore( + useShallow((state) => { + return { + showEdit: state.showEdit, + setShowEdit: state.setShowEdit, + formData: state.formData, + setMessage: state.setMessage, + }; + }), + ); + useEffect(() => { + const open = aiStore.showEdit; + if (open) { + const isNull = isObjectNull(aiStore.formData); + if (isNull) { + form.setFieldsValue({}); + } else form.setFieldsValue(aiStore.formData); + } + }, [aiStore.showEdit]); + const onFinish = async (values: any) => { + props.send({ + type: 'changeSession', + data: { + id: testId, + }, + }); + aiStore.setMessage([]); + }; + const onClose = () => { + aiStore.setShowEdit(false); + form.resetFields(); + }; + const isEdit = aiStore.formData.id; + return ( + aiStore.setShowEdit(false)} + destroyOnClose + footer={false} + width={800} + onCancel={onClose}> +
+ + + + + + + + +
+
+ ); +}; +export const useListenQuery = () => { + const aiStore = useAiStore( + useShallow((state) => { + return { + open: state.open, + key: state.key, + onMessage: state.onMessage, + }; + }), + ); + // TODO: Implement useEffect + useEffect(() => { + if (!aiStore.open) { + return; + } + const open = aiStore.open; + send({ + type: 'subscribe', + token: query.getToken(), + data: { + key: aiStore.key, + }, + }); + const close = query.qws.onMessage(onMessage, { + selector: (data) => { + const requestId = data.requestId; + return { + requestId, + ...data.data, + }; + }, + }); + return () => { + send({ type: 'unsubscribe' }); + close(); + }; + }, [aiStore.open, query]); + const send = async (data: any) => { + query.qws.send(data, { + wrapper: (data) => ({ + requestId: nanoid(16), + type: 'chat', + data: data, + }), + }); + }; + const onMessage = (data: any) => { + type MessageData = { + chatId: string; + chatPromptId: string; + role: string; + root: boolean; + show: boolean; + data: { + message: string; + }; + }; + if (data.code === 200 && data.type === 'messages') { + const messageData = data.data as MessageData; + aiStore.onMessage(messageData); + } + }; + return { + send, + }; +}; export const AiMoudle = () => { const [form] = Form.useForm(); + const navigate = useNavigate(); const aiStore = useAiStore( useShallow((state) => { return { open: state.open, setOpen: state.setOpen, - runAi: state.runAi, formData: state.formData, setFormData: state.setFormData, messages: state.messages, setMessages: state.setMessage, + key: state.key, + root: state.root, + setRoot: state.setRoot, + title: state.title, + setShowEdit: state.setShowEdit, + list: state.list, + getList: state.getList, }; }), ); - useEffect(() => { if (!aiStore.open) { return; @@ -37,66 +189,36 @@ export const AiMoudle = () => { useEffect(() => { if (!aiStore.open) { aiStore.setMessages([]); + } else { + aiStore.getList(); } }, [aiStore.open]); + const { send } = useListenQuery(); const onSend = () => { const data = form.getFieldsValue(); - aiStore.setFormData(data); - aiStore.runAi(); + send({ type: 'messages', data: { ...data, root: true } }); }; - return ( -
-
- -

Ai Moudle

-
- - - -
-
-
-
-
chat message
- {aiStore?.messages?.map((message, index) => { - const html = marked.parse(message?.content); - return ( -
-
{message?.role}
-
-
- ); - })} -
+ const inputs = form.getFieldValue('inputs'); + const isNotShow = inputs?.length === 0 || !inputs; + const RootForm = ( +
+
+
在当前页面,我能帮助你什么吗?
- - - {(fields, { add, remove }) => { return ( <> {fields.map((field, index) => { const key = form.getFieldValue(['inputs', index, 'key']); - console.log('key', key); - const isTitle = key === 'title'; - return (
-