diff --git a/web/src/components/rename-modal/index.tsx b/web/src/components/rename-modal/index.tsx new file mode 100644 index 00000000..ba902c57 --- /dev/null +++ b/web/src/components/rename-modal/index.tsx @@ -0,0 +1,78 @@ +import { Form, Input, Modal } from 'antd'; +import { useEffect } from 'react'; +import { IModalManagerChildrenProps } from '../modal-manager'; + +interface IProps extends Omit { + loading: boolean; + initialName: string; + onOk: (name: string) => void; + showModal?(): void; +} + +const RenameModal = ({ + visible, + hideModal, + loading, + initialName, + onOk, +}: IProps) => { + const [form] = Form.useForm(); + + type FieldType = { + name?: string; + }; + + const handleOk = async () => { + const ret = await form.validateFields(); + + return onOk(ret.name); + }; + + const handleCancel = () => { + hideModal(); + }; + + const onFinish = (values: any) => { + console.log('Success:', values); + }; + + const onFinishFailed = (errorInfo: any) => { + console.log('Failed:', errorInfo); + }; + + useEffect(() => { + form.setFieldValue('name', initialName); + }, [initialName, form]); + + return ( + +
+ + label="Name" + name="name" + rules={[{ required: true, message: 'Please input name!' }]} + > + + + +
+ ); +}; + +export default RenameModal; diff --git a/web/src/hooks/knowledgeHook.ts b/web/src/hooks/knowledgeHook.ts index 9ad41f5a..21678152 100644 --- a/web/src/hooks/knowledgeHook.ts +++ b/web/src/hooks/knowledgeHook.ts @@ -150,3 +150,34 @@ export const useFetchKnowledgeList = ( return list; }; + +export const useSelectFileThumbnails = () => { + const fileThumbnails: Record = useSelector( + (state: any) => state.kFModel.fileThumbnails, + ); + + return fileThumbnails; +}; + +export const useFetchFileThumbnails = (docIds?: Array) => { + const dispatch = useDispatch(); + const fileThumbnails = useSelectFileThumbnails(); + + const fetchFileThumbnails = useCallback( + (docIds: Array) => { + dispatch({ + type: 'kFModel/fetch_document_thumbnails', + payload: { doc_ids: docIds.join(',') }, + }); + }, + [dispatch], + ); + + useEffect(() => { + if (docIds) { + fetchFileThumbnails(docIds); + } + }, [docIds, fetchFileThumbnails]); + + return { fileThumbnails, fetchFileThumbnails }; +}; diff --git a/web/src/pages/add-knowledge/components/knowledge-file/index.less b/web/src/pages/add-knowledge/components/knowledge-file/index.less index 52e89559..40229974 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/index.less +++ b/web/src/pages/add-knowledge/components/knowledge-file/index.less @@ -20,9 +20,11 @@ } .img { - height: 16px; - width: 16px; - margin-right: 6px; + height: 24px; + width: 24px; + margin-right: 10px; + display: inline-block; + vertical-align: middle; } .column { diff --git a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx index a61d8fc5..eafed785 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-file/index.tsx @@ -22,7 +22,7 @@ import { } from 'antd'; import type { ColumnsType } from 'antd/es/table'; import { PaginationProps } from 'antd/lib'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Link, useDispatch, useNavigate, useSelector } from 'umi'; import CreateEPModal from './createEFileModal'; import styles from './index.less'; @@ -46,7 +46,7 @@ const KnowledgeFile = () => { const [parser_id, setParserId] = useState('0'); let navigate = useNavigate(); - const getKfList = () => { + const getKfList = useCallback(() => { const payload = { kb_id: knowledgeBaseId, }; @@ -55,7 +55,7 @@ const KnowledgeFile = () => { type: 'kFModel/getKfList', payload, }); - }; + }, [dispatch, knowledgeBaseId]); const throttledGetDocumentList = () => { dispatch({ @@ -64,23 +64,29 @@ const KnowledgeFile = () => { }); }; - const setPagination = (pageNumber = 1, pageSize?: number) => { - const pagination: Pagination = { - current: pageNumber, - } as Pagination; - if (pageSize) { - pagination.pageSize = pageSize; - } - dispatch({ - type: 'kFModel/setPagination', - payload: pagination, - }); - }; + const setPagination = useCallback( + (pageNumber = 1, pageSize?: number) => { + const pagination: Pagination = { + current: pageNumber, + } as Pagination; + if (pageSize) { + pagination.pageSize = pageSize; + } + dispatch({ + type: 'kFModel/setPagination', + payload: pagination, + }); + }, + [dispatch], + ); - const onPageChange: PaginationProps['onChange'] = (pageNumber, pageSize) => { - setPagination(pageNumber, pageSize); - getKfList(); - }; + const onPageChange: PaginationProps['onChange'] = useCallback( + (pageNumber: number, pageSize: number) => { + setPagination(pageNumber, pageSize); + getKfList(); + }, + [getKfList, setPagination], + ); const pagination: PaginationProps = useMemo(() => { return { @@ -92,7 +98,7 @@ const KnowledgeFile = () => { pageSizeOptions: [1, 2, 10, 20, 50, 100], onChange: onPageChange, }; - }, [total, kFModel.pagination]); + }, [total, kFModel.pagination, onPageChange]); useEffect(() => { if (knowledgeBaseId) { @@ -107,7 +113,7 @@ const KnowledgeFile = () => { type: 'kFModel/pollGetDocumentList-stop', }); }; - }, [knowledgeBaseId]); + }, [knowledgeBaseId, dispatch, getKfList]); const handleInputChange = ( e: React.ChangeEvent, @@ -129,14 +135,14 @@ const KnowledgeFile = () => { }); }; - const showCEFModal = () => { + const showCEFModal = useCallback(() => { dispatch({ type: 'kFModel/updateState', payload: { isShowCEFwModal: true, }, }); - }; + }, [dispatch]); const actionItems: MenuProps['items'] = useMemo(() => { return [ @@ -169,7 +175,7 @@ const KnowledgeFile = () => { // disabled: true, }, ]; - }, []); + }, [knowledgeBaseId, showCEFModal]); const toChunk = (id: string) => { navigate( @@ -187,13 +193,9 @@ const KnowledgeFile = () => { title: 'Name', dataIndex: 'name', key: 'name', - render: (text: any, { id }) => ( + render: (text: any, { id, thumbnail }) => (
toChunk(id)}> - + {text}
), diff --git a/web/src/pages/add-knowledge/components/knowledge-file/model.ts b/web/src/pages/add-knowledge/components/knowledge-file/model.ts index ac7f0e38..53f11679 100644 --- a/web/src/pages/add-knowledge/components/knowledge-file/model.ts +++ b/web/src/pages/add-knowledge/components/knowledge-file/model.ts @@ -16,6 +16,7 @@ export interface KFModelState extends BaseState { data: IKnowledgeFile[]; total: number; currentRecord: Nullable; + fileThumbnails: Record; } const model: DvaModel = { @@ -34,6 +35,7 @@ const model: DvaModel = { current: 1, pageSize: 10, }, + fileThumbnails: {} as Record, }, reducers: { updateState(state, { payload }) { @@ -54,6 +56,9 @@ const model: DvaModel = { setPagination(state, { payload }) { return { ...state, pagination: { ...state.pagination, ...payload } }; }, + setFileThumbnails(state, { payload }) { + return { ...state, fileThumbnails: payload }; + }, }, effects: { *createKf({ payload = {} }, { call }) { @@ -201,6 +206,12 @@ const model: DvaModel = { } return retcode; }, + *fetch_document_thumbnails({ payload = {} }, { call, put }) { + const { data } = yield call(kbService.document_thumbnails, payload); + if (data.retcode === 0) { + yield put({ type: 'setFileThumbnails', payload: data.data }); + } + }, }, }; export default model; diff --git a/web/src/pages/chat/chat-container/index.less b/web/src/pages/chat/chat-container/index.less index 1eba20a5..ac42b3ef 100644 --- a/web/src/pages/chat/chat-container/index.less +++ b/web/src/pages/chat/chat-container/index.less @@ -47,3 +47,7 @@ .referenceChunkImage { width: 10vw; } + +.referenceImagePreview { + width: 600px; +} diff --git a/web/src/pages/chat/chat-container/index.tsx b/web/src/pages/chat/chat-container/index.tsx index 4c0704f7..9d33d5c0 100644 --- a/web/src/pages/chat/chat-container/index.tsx +++ b/web/src/pages/chat/chat-container/index.tsx @@ -3,21 +3,12 @@ import { MessageType } from '@/constants/chat'; import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; import { useSelectUserInfo } from '@/hooks/userSettingHook'; import { IReference, Message } from '@/interfaces/database/chat'; -import { - Avatar, - Button, - Flex, - Input, - List, - Popover, - Space, - Typography, -} from 'antd'; +import { Avatar, Button, Flex, Input, List, Popover, Space } from 'antd'; import classNames from 'classnames'; import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; import reactStringReplace from 'react-string-replace'; import { - useFetchConversation, + useFetchConversationOnMount, useGetFileIcon, useScrollToBottom, useSendMessage, @@ -26,6 +17,7 @@ import { IClientConversation } from '../interface'; import Image from '@/components/image'; import NewDocumentLink from '@/components/new-document-link'; +import { useSelectFileThumbnails } from '@/hooks/knowledgeHook'; import { InfoCircleOutlined } from '@ant-design/icons'; import Markdown from 'react-markdown'; import { visitParents } from 'unist-util-visit-parents'; @@ -56,11 +48,10 @@ const MessageItem = ({ reference: IReference; }) => { const userInfo = useSelectUserInfo(); + const fileThumbnails = useSelectFileThumbnails(); const isAssistant = item.role === MessageType.Assistant; - const getFileIcon = useGetFileIcon(); - const getPopoverContent = useCallback( (chunkIndex: number) => { const chunks = reference?.chunks ?? []; @@ -75,22 +66,35 @@ const MessageItem = ({ gap={10} className={styles.referencePopoverWrapper} > - + + } + > + +
{chunkItem?.content_with_weight}
{documentId && ( - - {document?.doc_name} - + + + + {document?.doc_name} + + )}
); }, - [reference], + [reference, fileThumbnails], ); const renderReference = useCallback( @@ -163,12 +167,13 @@ const MessageItem = ({ dataSource={referenceDocumentList} renderItem={(item) => ( - - {/* */} - - - {item.doc_name} - + {/* */} + + + + {item.doc_name} + + )} /> @@ -182,11 +187,10 @@ const MessageItem = ({ const ChatContainer = () => { const [value, setValue] = useState(''); - const conversation: IClientConversation = useFetchConversation(); + const conversation: IClientConversation = useFetchConversationOnMount(); const { sendMessage } = useSendMessage(); const loading = useOneNamespaceEffectsLoading('chatModel', [ 'completeConversation', - 'getConversation', ]); const ref = useScrollToBottom(); useGetFileIcon(); diff --git a/web/src/pages/chat/hooks.ts b/web/src/pages/chat/hooks.ts index a3edde05..69859e8e 100644 --- a/web/src/pages/chat/hooks.ts +++ b/web/src/pages/chat/hooks.ts @@ -1,6 +1,8 @@ import showDeleteConfirm from '@/components/deleting-confirm'; import { MessageType } from '@/constants/chat'; import { fileIconMap } from '@/constants/common'; +import { useSetModalState } from '@/hooks/commonHooks'; +import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; import { IConversation, IDialog } from '@/interfaces/database/chat'; import { getFileExtension } from '@/utils'; import omit from 'lodash/omit'; @@ -14,7 +16,7 @@ import { VariableTableDataType, } from './interface'; import { ChatModelState } from './model'; -import { isConversationIdNotExist } from './utils'; +import { isConversationIdExist } from './utils'; export const useFetchDialogList = () => { const dispatch = useDispatch(); @@ -204,6 +206,24 @@ export const useSelectFirstDialogOnMount = () => { return dialogList; }; +export const useHandleItemHover = () => { + const [activated, setActivated] = useState(''); + + const handleItemEnter = (id: string) => { + setActivated(id); + }; + + const handleItemLeave = () => { + setActivated(''); + }; + + return { + activated, + handleItemEnter, + handleItemLeave, + }; +}; + //#region conversation export const useCreateTemporaryConversation = () => { @@ -374,30 +394,50 @@ export const useSetConversation = () => { return { setConversation }; }; -export const useFetchConversation = () => { - const dispatch = useDispatch(); - const { conversationId } = useGetChatSearchParams(); - const conversation = useSelector( +export const useSelectCurrentConversation = () => { + const conversation: IClientConversation = useSelector( (state: any) => state.chatModel.currentConversation, ); - const setCurrentConversation = useSetCurrentConversation(); - const fetchConversation = useCallback(() => { - if (isConversationIdNotExist(conversationId)) { - dispatch({ + return conversation; +}; + +export const useFetchConversation = () => { + const dispatch = useDispatch(); + + const fetchConversation = useCallback( + (conversationId: string, needToBeSaved = true) => { + return dispatch({ type: 'chatModel/getConversation', payload: { + needToBeSaved, conversation_id: conversationId, }, }); + }, + [dispatch], + ); + + return fetchConversation; +}; + +export const useFetchConversationOnMount = () => { + const { conversationId } = useGetChatSearchParams(); + const conversation = useSelectCurrentConversation(); + const setCurrentConversation = useSetCurrentConversation(); + const fetchConversation = useFetchConversation(); + + const fetchConversationOnMount = useCallback(() => { + if (isConversationIdExist(conversationId)) { + fetchConversation(conversationId); } else { setCurrentConversation({} as IClientConversation); } - }, [dispatch, conversationId, setCurrentConversation]); + }, [fetchConversation, setCurrentConversation, conversationId]); useEffect(() => { - fetchConversation(); - }, [fetchConversation]); + fetchConversationOnMount(); + }, [fetchConversationOnMount]); return conversation; }; @@ -477,4 +517,83 @@ export const useGetFileIcon = () => { return getFileIcon; }; +export const useRemoveConversation = () => { + const dispatch = useDispatch(); + const { dialogId } = useGetChatSearchParams(); + const { handleClickConversation } = useClickConversationCard(); + + const removeConversation = (conversationIds: Array) => async () => { + const ret = await dispatch({ + type: 'chatModel/removeConversation', + payload: { + dialog_id: dialogId, + conversation_ids: conversationIds, + }, + }); + + if (ret === 0) { + handleClickConversation(''); + } + + return ret; + }; + + const onRemoveConversation = (conversationIds: Array) => { + showDeleteConfirm({ onOk: removeConversation(conversationIds) }); + }; + + return { onRemoveConversation }; +}; + +export const useRenameConversation = () => { + const dispatch = useDispatch(); + const [conversation, setConversation] = useState( + {} as IClientConversation, + ); + const fetchConversation = useFetchConversation(); + const { + visible: conversationRenameVisible, + hideModal: hideConversationRenameModal, + showModal: showConversationRenameModal, + } = useSetModalState(); + + const onConversationRenameOk = useCallback( + async (name: string) => { + const ret = await dispatch({ + type: 'chatModel/setConversation', + payload: { ...conversation, conversation_id: conversation.id, name }, + }); + + if (ret.retcode === 0) { + hideConversationRenameModal(); + } + }, + [dispatch, conversation, hideConversationRenameModal], + ); + + const loading = useOneNamespaceEffectsLoading('chatModel', [ + 'setConversation', + ]); + + const handleShowConversationRenameModal = useCallback( + async (conversationId: string) => { + const ret = await fetchConversation(conversationId, false); + if (ret.retcode === 0) { + setConversation(ret.data); + } + showConversationRenameModal(); + }, + [showConversationRenameModal, fetchConversation], + ); + + return { + conversationRenameLoading: loading, + initialConversationName: conversation.name, + onConversationRenameOk, + conversationRenameVisible, + hideConversationRenameModal, + showConversationRenameModal: handleShowConversationRenameModal, + }; +}; + //#endregion diff --git a/web/src/pages/chat/index.tsx b/web/src/pages/chat/index.tsx index 4e3124f3..e4d7a37f 100644 --- a/web/src/pages/chat/index.tsx +++ b/web/src/pages/chat/index.tsx @@ -11,8 +11,9 @@ import { Space, Tag, } from 'antd'; +import { MenuItemProps } from 'antd/lib/menu/MenuItem'; import classNames from 'classnames'; -import { useCallback, useState } from 'react'; +import { useCallback } from 'react'; import ChatConfigurationModal from './chat-configuration-modal'; import ChatContainer from './chat-container'; import { @@ -21,42 +22,88 @@ import { useFetchConversationList, useFetchDialog, useGetChatSearchParams, + useHandleItemHover, + useRemoveConversation, useRemoveDialog, + useRenameConversation, useSelectConversationList, useSelectFirstDialogOnMount, useSetCurrentDialog, } from './hooks'; +import RenameModal from '@/components/rename-modal'; import styles from './index.less'; const Chat = () => { const dialogList = useSelectFirstDialogOnMount(); - const [activated, setActivated] = useState(''); const { visible, hideModal, showModal } = useSetModalState(); const { setCurrentDialog, currentDialog } = useSetCurrentDialog(); const { onRemoveDialog } = useRemoveDialog(); + const { onRemoveConversation } = useRemoveConversation(); const { handleClickDialog } = useClickDialogCard(); const { handleClickConversation } = useClickConversationCard(); const { dialogId, conversationId } = useGetChatSearchParams(); const { list: conversationList, addTemporaryConversation } = useSelectConversationList(); + const { activated, handleItemEnter, handleItemLeave } = useHandleItemHover(); + const { + activated: conversationActivated, + handleItemEnter: handleConversationItemEnter, + handleItemLeave: handleConversationItemLeave, + } = useHandleItemHover(); + const { + conversationRenameLoading, + initialConversationName, + onConversationRenameOk, + conversationRenameVisible, + hideConversationRenameModal, + showConversationRenameModal, + } = useRenameConversation(); useFetchDialog(dialogId, true); const handleAppCardEnter = (id: string) => () => { - setActivated(id); + handleItemEnter(id); }; - const handleAppCardLeave = () => { - setActivated(''); + const handleConversationCardEnter = (id: string) => () => { + handleConversationItemEnter(id); }; - const handleShowChatConfigurationModal = (dialogId?: string) => () => { - if (dialogId) { - setCurrentDialog(dialogId); - } - showModal(); - }; + const handleShowChatConfigurationModal = + (dialogId?: string): any => + (info: any) => { + info?.domEvent?.preventDefault(); + info?.domEvent?.stopPropagation(); + if (dialogId) { + setCurrentDialog(dialogId); + } + showModal(); + }; + + const handleRemoveDialog = + (dialogId: string): MenuItemProps['onClick'] => + ({ domEvent }) => { + domEvent.preventDefault(); + domEvent.stopPropagation(); + onRemoveDialog([dialogId]); + }; + + const handleRemoveConversation = + (conversationId: string): MenuItemProps['onClick'] => + ({ domEvent }) => { + domEvent.preventDefault(); + domEvent.stopPropagation(); + onRemoveConversation([conversationId]); + }; + + const handleShowConversationRenameModal = + (conversationId: string): MenuItemProps['onClick'] => + ({ domEvent }) => { + domEvent.preventDefault(); + domEvent.stopPropagation(); + showConversationRenameModal(conversationId); + }; const handleDialogCardClick = (dialogId: string) => () => { handleClickDialog(dialogId); @@ -97,7 +144,35 @@ const Chat = () => { { type: 'divider' }, { key: '2', - onClick: () => onRemoveDialog([dialogId]), + onClick: handleRemoveDialog(dialogId), + label: ( + + + Delete chat + + ), + }, + ]; + + return appItems; + }; + + const buildConversationItems = (conversationId: string) => { + const appItems: MenuProps['items'] = [ + { + key: '1', + onClick: handleShowConversationRenameModal(conversationId), + label: ( + + + Edit + + ), + }, + { type: 'divider' }, + { + key: '2', + onClick: handleRemoveConversation(conversationId), label: ( @@ -129,7 +204,7 @@ const Chat = () => { [styles.chatAppCardSelected]: dialogId === x.id, })} onMouseEnter={handleAppCardEnter(x.id)} - onMouseLeave={handleAppCardLeave} + onMouseLeave={handleItemLeave} onClick={handleDialogCardClick(x.id)} > @@ -176,11 +251,22 @@ const Chat = () => { key={x.id} hoverable onClick={handleConversationCardClick(x.id)} + onMouseEnter={handleConversationCardEnter(x.id)} + onMouseLeave={handleConversationItemLeave} className={classNames(styles.chatTitleCard, { [styles.chatTitleCardSelected]: x.id === conversationId, })} > -
{x.name}
+ +
{x.name}
+ {conversationActivated === x.id && x.id !== '' && ( +
+ + + +
+ )} +
))}
@@ -194,6 +280,13 @@ const Chat = () => { hideModal={hideModal} id={currentDialog.id} > + ); }; diff --git a/web/src/pages/chat/model.ts b/web/src/pages/chat/model.ts index 040959ff..659fc3da 100644 --- a/web/src/pages/chat/model.ts +++ b/web/src/pages/chat/model.ts @@ -4,6 +4,7 @@ import { message } from 'antd'; import { DvaModel } from 'umi'; import { v4 as uuid } from 'uuid'; import { IClientConversation, IMessage } from './interface'; +import { getDocumentIdsFromConversionReference } from './utils'; export interface ChatModelState { name: string; @@ -109,11 +110,19 @@ const model: DvaModel = { return data.retcode; }, *getConversation({ payload }, { call, put }) { - const { data } = yield call(chatService.getConversation, payload); - if (data.retcode === 0) { + const { data } = yield call(chatService.getConversation, { + conversation_id: payload.conversation_id, + }); + if (data.retcode === 0 && payload.needToBeSaved) { + yield put({ + type: 'kFModel/fetch_document_thumbnails', + payload: { + doc_ids: getDocumentIdsFromConversionReference(data.data), + }, + }); yield put({ type: 'setCurrentConversation', payload: data.data }); } - return data.retcode; + return data; }, *setConversation({ payload }, { call, put }) { const { data } = yield call(chatService.setConversation, payload); @@ -138,6 +147,19 @@ const model: DvaModel = { }); } }, + *removeConversation({ payload }, { call, put }) { + const { data } = yield call(chatService.removeConversation, { + conversation_ids: payload.conversation_ids, + }); + if (data.retcode === 0) { + yield put({ + type: 'listConversation', + payload: { dialog_id: payload.dialog_id }, + }); + message.success('Deleted successfully !'); + } + return data.retcode; + }, }, }; diff --git a/web/src/pages/chat/utils.ts b/web/src/pages/chat/utils.ts index cbec9e2c..7c3fe80c 100644 --- a/web/src/pages/chat/utils.ts +++ b/web/src/pages/chat/utils.ts @@ -1,3 +1,4 @@ +import { IConversation, IReference } from '@/interfaces/database/chat'; import { EmptyConversationId, variableEnabledFieldMap } from './constants'; export const excludeUnEnabledVariables = (values: any) => { @@ -11,6 +12,23 @@ export const excludeUnEnabledVariables = (values: any) => { ); }; -export const isConversationIdNotExist = (conversationId: string) => { +export const isConversationIdExist = (conversationId: string) => { return conversationId !== EmptyConversationId && conversationId !== ''; }; + +export const getDocumentIdsFromConversionReference = (data: IConversation) => { + const documentIds = data.reference.reduce( + (pre: Array, cur: IReference) => { + cur.doc_aggs + .map((x) => x.doc_id) + .forEach((x) => { + if (pre.every((y) => y !== x)) { + pre.push(x); + } + }); + return pre; + }, + [], + ); + return documentIds.join(','); +}; diff --git a/web/src/services/chatService.ts b/web/src/services/chatService.ts index 946de86a..e2d8d378 100644 --- a/web/src/services/chatService.ts +++ b/web/src/services/chatService.ts @@ -11,6 +11,7 @@ const { setConversation, completeConversation, listConversation, + removeConversation, } = api; const methods = { @@ -46,6 +47,10 @@ const methods = { url: completeConversation, method: 'post', }, + removeConversation: { + url: removeConversation, + method: 'post', + }, } as const; const chatService = registerServer(methods, request); diff --git a/web/src/services/kbService.ts b/web/src/services/kbService.ts index ca25bc44..bf2b0eb8 100644 --- a/web/src/services/kbService.ts +++ b/web/src/services/kbService.ts @@ -13,6 +13,7 @@ const { document_rm, document_create, document_change_parser, + document_thumbnails, chunk_list, create_chunk, set_chunk, @@ -75,6 +76,10 @@ const methods = { url: document_change_parser, method: 'post', }, + document_thumbnails: { + url: document_thumbnails, + method: 'get', + }, // chunk管理 chunk_list: { url: chunk_list, diff --git a/web/src/utils/api.ts b/web/src/utils/api.ts index 777c413f..3a1169e9 100644 --- a/web/src/utils/api.ts +++ b/web/src/utils/api.ts @@ -42,6 +42,7 @@ export default { document_create: `${api_host}/document/create`, document_run: `${api_host}/document/run`, document_change_parser: `${api_host}/document/change_parser`, + document_thumbnails: `${api_host}/document/thumbnails`, setDialog: `${api_host}/dialog/set`, getDialog: `${api_host}/dialog/get`,