### What problem does this PR solve? fix: reference file with 'docx' type can not open #844 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)tags/v0.9.0
| import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg'; | import { ReactComponent as AssistantIcon } from '@/assets/svg/assistant.svg'; | ||||
| import { MessageType } from '@/constants/chat'; | import { MessageType } from '@/constants/chat'; | ||||
| import { useTranslate } from '@/hooks/common-hooks'; | import { useTranslate } from '@/hooks/common-hooks'; | ||||
| import { useGetDocumentUrl } from '@/hooks/document-hooks'; | |||||
| import { useSelectFileThumbnails } from '@/hooks/knowledge-hooks'; | import { useSelectFileThumbnails } from '@/hooks/knowledge-hooks'; | ||||
| import { IReference, Message } from '@/interfaces/database/chat'; | import { IReference, Message } from '@/interfaces/database/chat'; | ||||
| import { IChunk } from '@/interfaces/database/knowledge'; | import { IChunk } from '@/interfaces/database/knowledge'; | ||||
| import { useMemo } from 'react'; | import { useMemo } from 'react'; | ||||
| import MarkdownContent from '@/pages/chat/markdown-content'; | import MarkdownContent from '@/pages/chat/markdown-content'; | ||||
| import { getExtension, isPdf } from '@/utils/documentUtils'; | |||||
| import { getExtension } from '@/utils/documentUtils'; | |||||
| import { Avatar, Flex, List } from 'antd'; | import { Avatar, Flex, List } from 'antd'; | ||||
| import NewDocumentLink from '../new-document-link'; | import NewDocumentLink from '../new-document-link'; | ||||
| import SvgIcon from '../svg-icon'; | import SvgIcon from '../svg-icon'; | ||||
| const isAssistant = item.role === MessageType.Assistant; | const isAssistant = item.role === MessageType.Assistant; | ||||
| const { t } = useTranslate('chat'); | const { t } = useTranslate('chat'); | ||||
| const fileThumbnails = useSelectFileThumbnails(); | const fileThumbnails = useSelectFileThumbnails(); | ||||
| const getDocumentUrl = useGetDocumentUrl(); | |||||
| const referenceDocumentList = useMemo(() => { | const referenceDocumentList = useMemo(() => { | ||||
| return reference?.doc_aggs ?? []; | return reference?.doc_aggs ?? []; | ||||
| )} | )} | ||||
| <NewDocumentLink | <NewDocumentLink | ||||
| link={getDocumentUrl(item.doc_id)} | |||||
| preventDefault={!isPdf(item.doc_name)} | |||||
| documentId={item.doc_id} | |||||
| documentName={item.doc_name} | |||||
| prefix="document" | |||||
| > | > | ||||
| {item.doc_name} | {item.doc_name} | ||||
| </NewDocumentLink> | </NewDocumentLink> | 
| import { | |||||
| getExtension, | |||||
| isSupportedPreviewDocumentType, | |||||
| } from '@/utils/documentUtils'; | |||||
| import React from 'react'; | import React from 'react'; | ||||
| interface IProps extends React.PropsWithChildren { | interface IProps extends React.PropsWithChildren { | ||||
| link: string; | |||||
| link?: string; | |||||
| preventDefault?: boolean; | preventDefault?: boolean; | ||||
| color?: string; | color?: string; | ||||
| documentName: string; | |||||
| documentId?: string; | |||||
| prefix?: string; | |||||
| } | } | ||||
| const NewDocumentLink = ({ | const NewDocumentLink = ({ | ||||
| link, | link, | ||||
| preventDefault = false, | preventDefault = false, | ||||
| color = 'rgb(15, 79, 170)', | color = 'rgb(15, 79, 170)', | ||||
| documentId, | |||||
| documentName, | |||||
| prefix = 'file', | |||||
| }: IProps) => { | }: IProps) => { | ||||
| let nextLink = link; | |||||
| const extension = getExtension(documentName); | |||||
| if (!link) { | |||||
| nextLink = `/document/${documentId}?ext=${extension}&prefix=${prefix}`; | |||||
| } | |||||
| return ( | return ( | ||||
| <a | <a | ||||
| target="_blank" | target="_blank" | ||||
| onClick={!preventDefault ? undefined : (e) => e.preventDefault()} | |||||
| href={link} | |||||
| onClick={ | |||||
| !preventDefault || isSupportedPreviewDocumentType(extension) | |||||
| ? undefined | |||||
| : (e) => e.preventDefault() | |||||
| } | |||||
| href={nextLink} | |||||
| rel="noreferrer" | rel="noreferrer" | ||||
| style={{ color, wordBreak: 'break-all' }} | style={{ color, wordBreak: 'break-all' }} | ||||
| > | > | 
| import { ReactComponent as NavigationPointerIcon } from '@/assets/svg/navigation-pointer.svg'; | |||||
| import NewDocumentLink from '@/components/new-document-link'; | import NewDocumentLink from '@/components/new-document-link'; | ||||
| import { useGetDocumentUrl } from '@/hooks/document-hooks'; | |||||
| import { useTranslate } from '@/hooks/common-hooks'; | |||||
| import { ITestingDocument } from '@/interfaces/database/knowledge'; | import { ITestingDocument } from '@/interfaces/database/knowledge'; | ||||
| import { isPdf } from '@/utils/documentUtils'; | |||||
| import { Table, TableProps } from 'antd'; | |||||
| import { EyeOutlined } from '@ant-design/icons'; | |||||
| import { Button, Table, TableProps, Tooltip } from 'antd'; | |||||
| import { useDispatch, useSelector } from 'umi'; | import { useDispatch, useSelector } from 'umi'; | ||||
| interface IProps { | interface IProps { | ||||
| const documents: ITestingDocument[] = useSelector( | const documents: ITestingDocument[] = useSelector( | ||||
| (state: any) => state.testingModel.documents, | (state: any) => state.testingModel.documents, | ||||
| ); | ); | ||||
| const { t } = useTranslate('fileManager'); | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const getDocumentUrl = useGetDocumentUrl(); | |||||
| const columns: TableProps<ITestingDocument>['columns'] = [ | const columns: TableProps<ITestingDocument>['columns'] = [ | ||||
| { | { | ||||
| width: 50, | width: 50, | ||||
| render: (_, { doc_id, doc_name }) => ( | render: (_, { doc_id, doc_name }) => ( | ||||
| <NewDocumentLink | <NewDocumentLink | ||||
| link={getDocumentUrl(doc_id)} | |||||
| preventDefault={!isPdf(doc_name)} | |||||
| documentName={doc_name} | |||||
| documentId={doc_id} | |||||
| prefix="document" | |||||
| > | > | ||||
| <NavigationPointerIcon /> | |||||
| <Tooltip title={t('preview')}> | |||||
| <Button type="text"> | |||||
| <EyeOutlined size={20} /> | |||||
| </Button> | |||||
| </Tooltip> | |||||
| </NewDocumentLink> | </NewDocumentLink> | ||||
| ), | ), | ||||
| }, | }, | 
| const DocumentViewer = () => { | const DocumentViewer = () => { | ||||
| const { id: documentId } = useParams(); | const { id: documentId } = useParams(); | ||||
| const api = `${api_host}/file/get/${documentId}`; | |||||
| const [currentQueryParameters] = useSearchParams(); | const [currentQueryParameters] = useSearchParams(); | ||||
| const ext = currentQueryParameters.get('ext'); | const ext = currentQueryParameters.get('ext'); | ||||
| const prefix = currentQueryParameters.get('prefix'); | |||||
| const api = `${api_host}/${prefix || 'file'}/get/${documentId}`; | |||||
| return ( | return ( | ||||
| <section className={styles.viewerWrapper}> | <section className={styles.viewerWrapper}> | 
| import { useHandleDeleteFile } from '../hooks'; | import { useHandleDeleteFile } from '../hooks'; | ||||
| import NewDocumentLink from '@/components/new-document-link'; | import NewDocumentLink from '@/components/new-document-link'; | ||||
| import { SupportedPreviewDocumentTypes } from '@/constants/common'; | |||||
| import { getExtension } from '@/utils/documentUtils'; | |||||
| import { | |||||
| getExtension, | |||||
| isSupportedPreviewDocumentType, | |||||
| } from '@/utils/documentUtils'; | |||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| const isSupportedPreviewDocumentType = (fileExtension: string) => { | |||||
| return SupportedPreviewDocumentTypes.includes(fileExtension); | |||||
| }; | |||||
| interface IProps { | interface IProps { | ||||
| record: IFile; | record: IFile; | ||||
| setCurrentRecord: (record: any) => void; | setCurrentRecord: (record: any) => void; | ||||
| )} | )} | ||||
| {isSupportedPreviewDocumentType(extension) && ( | {isSupportedPreviewDocumentType(extension) && ( | ||||
| <NewDocumentLink | <NewDocumentLink | ||||
| documentId={documentId} | |||||
| documentName={record.name} | |||||
| color="black" | color="black" | ||||
| link={`/document/${documentId}?ext=${extension}`} | |||||
| > | > | ||||
| <Tooltip title={t('preview')}> | <Tooltip title={t('preview')}> | ||||
| <Button type="text" className={styles.iconButton}> | <Button type="text" className={styles.iconButton}> | 
| import { SupportedPreviewDocumentTypes } from '@/constants/common'; | |||||
| import { IChunk } from '@/interfaces/database/knowledge'; | import { IChunk } from '@/interfaces/database/knowledge'; | ||||
| import { UploadFile } from 'antd'; | import { UploadFile } from 'antd'; | ||||
| import { v4 as uuid } from 'uuid'; | import { v4 as uuid } from 'uuid'; | ||||
| export const getUnSupportedFilesCount = (message: string) => { | export const getUnSupportedFilesCount = (message: string) => { | ||||
| return message.split('\n').length; | return message.split('\n').length; | ||||
| }; | }; | ||||
| export const isSupportedPreviewDocumentType = (fileExtension: string) => { | |||||
| return SupportedPreviewDocumentTypes.includes(fileExtension); | |||||
| }; |