Web: Fixed the download and preview file not authorized. (#3652)

https://github.com/infiniflow/ragflow/issues/3651

### What problem does this PR solve?

_Briefly describe what this PR aims to solve. Include background context
that will help reviewers understand the purpose of the PR._

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
Fachuan Bai 2024-12-04 11:48:06 +08:00 committed by GitHub
parent efae7afd62
commit fc38afcec4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 1124 additions and 1034 deletions

View File

@ -323,7 +323,7 @@ def rename():
@manager.route('/get/<file_id>', methods=['GET']) @manager.route('/get/<file_id>', methods=['GET'])
# @login_required @login_required
def get(file_id): def get(file_id):
try: try:
e, file = FileService.get_by_id(file_id) e, file = FileService.get_by_id(file_id)

View File

@ -20,6 +20,7 @@
"@ant-design/icons": "^5.2.6", "@ant-design/icons": "^5.2.6",
"@ant-design/pro-components": "^2.6.46", "@ant-design/pro-components": "^2.6.46",
"@ant-design/pro-layout": "^7.17.16", "@ant-design/pro-layout": "^7.17.16",
"@antv/g": "^6.1.11",
"@antv/g6": "^5.0.10", "@antv/g6": "^5.0.10",
"@hookform/resolvers": "^3.9.1", "@hookform/resolvers": "^3.9.1",
"@js-preview/excel": "^1.7.8", "@js-preview/excel": "^1.7.8",
@ -72,6 +73,7 @@
"react-i18next": "^14.0.0", "react-i18next": "^14.0.0",
"react-infinite-scroll-component": "^6.1.0", "react-infinite-scroll-component": "^6.1.0",
"react-markdown": "^9.0.1", "react-markdown": "^9.0.1",
"react-pdf": "^9.1.1",
"react-pdf-highlighter": "^6.1.0", "react-pdf-highlighter": "^6.1.0",
"react-string-replace": "^1.1.1", "react-string-replace": "^1.1.1",
"react-syntax-highlighter": "^15.5.0", "react-syntax-highlighter": "^15.5.0",

View File

@ -123,6 +123,6 @@ export {
NavigationMenuLink, NavigationMenuLink,
NavigationMenuList, NavigationMenuList,
NavigationMenuTrigger, NavigationMenuTrigger,
NavigationMenuViewport,
navigationMenuTriggerStyle, navigationMenuTriggerStyle,
NavigationMenuViewport,
}; };

View File

@ -2,6 +2,7 @@ import { ResponseType } from '@/interfaces/database/base';
import { IFolder } from '@/interfaces/database/file-manager'; import { IFolder } from '@/interfaces/database/file-manager';
import { IConnectRequestBody } from '@/interfaces/request/file-manager'; import { IConnectRequestBody } from '@/interfaces/request/file-manager';
import fileManagerService from '@/services/file-manager-service'; import fileManagerService from '@/services/file-manager-service';
import { downloadFileFromBlob } from '@/utils/file-util';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { PaginationProps, UploadFile, message } from 'antd'; import { PaginationProps, UploadFile, message } from 'antd';
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
@ -114,6 +115,39 @@ export const useDeleteFile = () => {
return { data, loading, deleteFile: mutateAsync }; return { data, loading, deleteFile: mutateAsync };
}; };
export const useDownloadFile = () => {
const {
data,
isPending: loading,
mutateAsync,
} = useMutation({
mutationKey: ['downloadFile'],
mutationFn: async (params: { id: string; filename?: string }) => {
const response = await fileManagerService.getFile({}, params.id);
const blob = new Blob([response.data], { type: response.data.type });
downloadFileFromBlob(blob, params.filename);
},
});
return { data, loading, downloadFile: mutateAsync };
};
export const useLoadFile = () => {
const {
data,
isPending: loading,
mutateAsync,
error,
} = useMutation({
mutationKey: ['downloadFile'],
mutationFn: async (params: { id: string }) => {
const response = await fileManagerService.getFile({}, params.id);
const blob = new Blob([response.data], { type: response.data.type });
return blob;
},
});
return { data, loading, loadFile: mutateAsync, error };
};
export const useRenameFile = () => { export const useRenameFile = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { t } = useTranslation(); const { t } = useTranslation();

View File

@ -231,7 +231,8 @@ export default {
maxTokensMessage: 'El máximo de tokens es obligatorio', maxTokensMessage: 'El máximo de tokens es obligatorio',
maxTokensTip: maxTokensTip:
'Esto establece la longitud máxima de la salida del modelo, medida en el número de tokens (palabras o piezas de palabras).', 'Esto establece la longitud máxima de la salida del modelo, medida en el número de tokens (palabras o piezas de palabras).',
maxTokensInvalidMessage: 'Por favor, ingresa un número válido para Max Tokens.', maxTokensInvalidMessage:
'Por favor, ingresa un número válido para Max Tokens.',
maxTokensMinMessage: 'Max Tokens no puede ser menor que 0.', maxTokensMinMessage: 'Max Tokens no puede ser menor que 0.',
quote: 'Mostrar cita', quote: 'Mostrar cita',
quoteTip: '¿Debe mostrarse la fuente del texto original?', quoteTip: '¿Debe mostrarse la fuente del texto original?',
@ -284,7 +285,8 @@ export default {
maxTokensMessage: 'El máximo de tokens es obligatorio', maxTokensMessage: 'El máximo de tokens es obligatorio',
maxTokensTip: maxTokensTip:
'Esto establece la longitud máxima de la salida del modelo, medida en el número de tokens (palabras o piezas de palabras).', 'Esto establece la longitud máxima de la salida del modelo, medida en el número de tokens (palabras o piezas de palabras).',
maxTokensInvalidMessage: 'Por favor, ingresa un número válido para Max Tokens.', maxTokensInvalidMessage:
'Por favor, ingresa un número válido para Max Tokens.',
maxTokensMinMessage: 'Max Tokens no puede ser menor que 0.', maxTokensMinMessage: 'Max Tokens no puede ser menor que 0.',
password: 'Contraseña', password: 'Contraseña',
passwordDescription: passwordDescription:

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,7 @@
import { useShowDeleteConfirm, useTranslate } from '@/hooks/common-hooks'; import { useShowDeleteConfirm, useTranslate } from '@/hooks/common-hooks';
import { useRemoveNextDocument } from '@/hooks/document-hooks'; import { useRemoveNextDocument } from '@/hooks/document-hooks';
import { IDocumentInfo } from '@/interfaces/database/document'; import { IDocumentInfo } from '@/interfaces/database/document';
import { api_host } from '@/utils/api'; import { downloadDocument } from '@/utils/file-util';
import { downloadFile } from '@/utils/file-util';
import { import {
DeleteOutlined, DeleteOutlined,
DownloadOutlined, DownloadOutlined,
@ -40,8 +39,8 @@ const ParsingActionCell = ({
}; };
const onDownloadDocument = () => { const onDownloadDocument = () => {
downloadFile({ downloadDocument({
url: `${api_host}/document/get/${documentId}`, id: documentId,
filename: record.name, filename: record.name,
}); });
}; };

View File

@ -1,3 +1,5 @@
import { Authorization } from '@/constants/authorization';
import { getAuthorization } from '@/utils/authorization-util';
import jsPreviewExcel from '@js-preview/excel'; import jsPreviewExcel from '@js-preview/excel';
import axios from 'axios'; import axios from 'axios';
import mammoth from 'mammoth'; import mammoth from 'mammoth';
@ -23,7 +25,12 @@ export const useCatchError = (api: string) => {
export const useFetchDocument = () => { export const useFetchDocument = () => {
const fetchDocument = useCallback(async (api: string) => { const fetchDocument = useCallback(async (api: string) => {
const ret = await axios.get(api, { responseType: 'arraybuffer' }); const ret = await axios.get(api, {
headers: {
[Authorization]: getAuthorization(),
},
responseType: 'arraybuffer',
});
return ret; return ret;
}, []); }, []);
@ -64,30 +71,34 @@ export const useFetchExcel = (filePath: string) => {
export const useFetchDocx = (filePath: string) => { export const useFetchDocx = (filePath: string) => {
const [succeed, setSucceed] = useState(true); const [succeed, setSucceed] = useState(true);
const [error, setError] = useState<string>();
const { fetchDocument } = useFetchDocument(); const { fetchDocument } = useFetchDocument();
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const { error } = useCatchError(filePath);
const fetchDocumentAsync = useCallback(async () => { const fetchDocumentAsync = useCallback(async () => {
const jsonFile = await fetchDocument(filePath); try {
mammoth const jsonFile = await fetchDocument(filePath);
.convertToHtml( mammoth
{ arrayBuffer: jsonFile.data }, .convertToHtml(
{ includeDefaultStyleMap: true }, { arrayBuffer: jsonFile.data },
) { includeDefaultStyleMap: true },
.then((result) => { )
setSucceed(true); .then((result) => {
const docEl = document.createElement('div'); setSucceed(true);
docEl.className = 'document-container'; const docEl = document.createElement('div');
docEl.innerHTML = result.value; docEl.className = 'document-container';
const container = containerRef.current; docEl.innerHTML = result.value;
if (container) { const container = containerRef.current;
container.innerHTML = docEl.outerHTML; if (container) {
} container.innerHTML = docEl.outerHTML;
}) }
.catch(() => { })
setSucceed(false); .catch(() => {
}); setSucceed(false);
});
} catch (error: any) {
setError(error.toString());
}
}, [filePath, fetchDocument]); }, [filePath, fetchDocument]);
useEffect(() => { useEffect(() => {

View File

@ -1,7 +1,14 @@
import { Authorization } from '@/constants/authorization';
import { getAuthorization } from '@/utils/authorization-util';
import { Skeleton } from 'antd'; import { Skeleton } from 'antd';
import { PdfHighlighter, PdfLoader } from 'react-pdf-highlighter'; import { PdfHighlighter, PdfLoader } from 'react-pdf-highlighter';
import FileError from '../file-error'; import FileError from '../file-error';
import { useCatchError } from '../hooks'; import { useCatchError } from '../hooks';
type PdfLoaderProps = React.ComponentProps<typeof PdfLoader> & {
httpHeaders?: Record<string, string>;
};
const Loader = PdfLoader as React.ComponentType<PdfLoaderProps>;
interface IProps { interface IProps {
url: string; url: string;
@ -10,11 +17,14 @@ interface IProps {
const PdfPreviewer = ({ url }: IProps) => { const PdfPreviewer = ({ url }: IProps) => {
const { error } = useCatchError(url); const { error } = useCatchError(url);
const resetHash = () => {}; const resetHash = () => {};
const httpHeaders = {
[Authorization]: getAuthorization(),
};
return ( return (
<div style={{ width: '100%', height: '100%' }}> <div style={{ width: '100%', height: '100%' }}>
<PdfLoader <Loader
url={url} url={url}
httpHeaders={httpHeaders}
beforeLoad={<Skeleton active />} beforeLoad={<Skeleton active />}
workerSrc="/pdfjs-dist/pdf.worker.min.js" workerSrc="/pdfjs-dist/pdf.worker.min.js"
errorMessage={<FileError>{error}</FileError>} errorMessage={<FileError>{error}</FileError>}
@ -37,7 +47,7 @@ const PdfPreviewer = ({ url }: IProps) => {
/> />
); );
}} }}
</PdfLoader> </Loader>
</div> </div>
); );
}; };

View File

@ -1,13 +1,12 @@
import NewDocumentLink from '@/components/new-document-link'; import NewDocumentLink from '@/components/new-document-link';
import SvgIcon from '@/components/svg-icon'; import SvgIcon from '@/components/svg-icon';
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { useDownloadFile } from '@/hooks/file-manager-hooks';
import { IFile } from '@/interfaces/database/file-manager'; import { IFile } from '@/interfaces/database/file-manager';
import { api_host } from '@/utils/api';
import { import {
getExtension, getExtension,
isSupportedPreviewDocumentType, isSupportedPreviewDocumentType,
} from '@/utils/document-util'; } from '@/utils/document-util';
import { downloadFile } from '@/utils/file-util';
import { import {
DeleteOutlined, DeleteOutlined,
DownloadOutlined, DownloadOutlined,
@ -42,12 +41,13 @@ const ActionCell = ({
[documentId], [documentId],
setSelectedRowKeys, setSelectedRowKeys,
); );
const { downloadFile, loading } = useDownloadFile();
const extension = getExtension(record.name); const extension = getExtension(record.name);
const isKnowledgeBase = record.source_type === 'knowledgebase'; const isKnowledgeBase = record.source_type === 'knowledgebase';
const onDownloadDocument = () => { const onDownloadDocument = () => {
downloadFile({ downloadFile({
url: `${api_host}/file/get/${documentId}`, id: documentId,
filename: record.name, filename: record.name,
}); });
}; };
@ -106,7 +106,12 @@ const ActionCell = ({
)} )}
{record.type !== 'folder' && ( {record.type !== 'folder' && (
<Tooltip title={t('download', { keyPrefix: 'common' })}> <Tooltip title={t('download', { keyPrefix: 'common' })}>
<Button type="text" disabled={beingUsed} onClick={onDownloadDocument}> <Button
type="text"
disabled={beingUsed}
loading={loading}
onClick={onDownloadDocument}
>
<DownloadOutlined size={20} /> <DownloadOutlined size={20} />
</Button> </Button>
</Tooltip> </Tooltip>

View File

@ -40,7 +40,7 @@
word-break: break-all; word-break: break-all;
} }
.description{ .description {
margin-top: 4px; margin-top: 4px;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Flex, Form, Input, Modal, Select, Space, InputNumber } from 'antd'; import { Flex, Form, Input, Modal, Select, Space } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
@ -30,7 +30,7 @@ const TencentCloudModal = ({
...omit(values), ...omit(values),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:16000, max_tokens: 16000,
}; };
console.info(data); console.info(data);

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Form, Input, Modal, Select, Switch, InputNumber } from 'antd'; import { Form, Input, InputNumber, Modal, Select, Switch } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
@ -33,7 +33,7 @@ const AzureOpenAIModal = ({
...omit(values, ['vision']), ...omit(values, ['vision']),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
console.info(data); console.info(data);

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Flex, Form, Input, Modal, Select, Space, InputNumber } from 'antd'; import { Flex, Form, Input, InputNumber, Modal, Select, Space } from 'antd';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { BedrockRegionList } from '../constant'; import { BedrockRegionList } from '../constant';
@ -34,7 +34,7 @@ const BedrockModal = ({
const data = { const data = {
...values, ...values,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
onOk?.(data); onOk?.(data);
@ -136,7 +136,6 @@ const BedrockModal = ({
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Flex, Form, Input, Modal, Select, Space, InputNumber } from 'antd'; import { Flex, Form, Input, InputNumber, Modal, Select, Space } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
@ -30,7 +30,7 @@ const FishAudioModal = ({
...omit(values), ...omit(values),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
console.info(data); console.info(data);
@ -118,7 +118,6 @@ const FishAudioModal = ({
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Form, Input, Modal, Select, InputNumber } from 'antd'; import { Form, Input, InputNumber, Modal, Select } from 'antd';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
google_project_id: string; google_project_id: string;
@ -27,7 +27,7 @@ const GoogleModal = ({
const data = { const data = {
...values, ...values,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
onOk?.(data); onOk?.(data);
@ -112,7 +112,6 @@ const GoogleModal = ({
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Form, Input, Modal, Select} from 'antd'; import { Form, Input, Modal, Select } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {

View File

@ -1,7 +1,16 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Flex, Form, Input, Modal, Select, Space, Switch, InputNumber } from 'antd'; import {
Flex,
Form,
Input,
InputNumber,
Modal,
Select,
Space,
Switch,
} from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { vision: boolean }; type FieldType = IAddLlmRequestBody & { vision: boolean };
@ -45,7 +54,7 @@ const OllamaModal = ({
...omit(values, ['vision']), ...omit(values, ['vision']),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
console.info(data); console.info(data);

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Form, Input, Modal, Select, InputNumber } from 'antd'; import { Form, Input, InputNumber, Modal, Select } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
@ -36,7 +36,7 @@ const SparkModal = ({
...omit(values, ['vision']), ...omit(values, ['vision']),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
console.info(data); console.info(data);
@ -80,52 +80,56 @@ const SparkModal = ({
<Form.Item noStyle dependencies={['model_type']}> <Form.Item noStyle dependencies={['model_type']}>
{({ getFieldValue }) => {({ getFieldValue }) =>
getFieldValue('model_type') === 'chat' && ( getFieldValue('model_type') === 'chat' && (
<Form.Item<FieldType> <Form.Item<FieldType>
label={t('addSparkAPIPassword')} label={t('addSparkAPIPassword')}
name="spark_api_password" name="spark_api_password"
rules={[{ required: true, message: t('SparkAPIPasswordMessage') }]} rules={[
> { required: true, message: t('SparkAPIPasswordMessage') },
<Input placeholder={t('SparkAPIPasswordMessage')} /> ]}
</Form.Item> >
<Input placeholder={t('SparkAPIPasswordMessage')} />
</Form.Item>
) )
} }
</Form.Item> </Form.Item>
<Form.Item noStyle dependencies={['model_type']}> <Form.Item noStyle dependencies={['model_type']}>
{({ getFieldValue }) => {({ getFieldValue }) =>
getFieldValue('model_type') === 'tts' && ( getFieldValue('model_type') === 'tts' && (
<Form.Item<FieldType> <Form.Item<FieldType>
label={t('addSparkAPPID')} label={t('addSparkAPPID')}
name="spark_app_id" name="spark_app_id"
rules={[{ required: true, message: t('SparkAPPIDMessage') }]} rules={[{ required: true, message: t('SparkAPPIDMessage') }]}
> >
<Input placeholder={t('SparkAPPIDMessage')} /> <Input placeholder={t('SparkAPPIDMessage')} />
</Form.Item> </Form.Item>
) )
} }
</Form.Item> </Form.Item>
<Form.Item noStyle dependencies={['model_type']}> <Form.Item noStyle dependencies={['model_type']}>
{({ getFieldValue }) => {({ getFieldValue }) =>
getFieldValue('model_type') === 'tts' && ( getFieldValue('model_type') === 'tts' && (
<Form.Item<FieldType> <Form.Item<FieldType>
label={t('addSparkAPISecret')} label={t('addSparkAPISecret')}
name="spark_api_secret" name="spark_api_secret"
rules={[{ required: true, message: t('SparkAPISecretMessage') }]} rules={[
> { required: true, message: t('SparkAPISecretMessage') },
<Input placeholder={t('SparkAPISecretMessage')} /> ]}
</Form.Item> >
<Input placeholder={t('SparkAPISecretMessage')} />
</Form.Item>
) )
} }
</Form.Item> </Form.Item>
<Form.Item noStyle dependencies={['model_type']}> <Form.Item noStyle dependencies={['model_type']}>
{({ getFieldValue }) => {({ getFieldValue }) =>
getFieldValue('model_type') === 'tts' && ( getFieldValue('model_type') === 'tts' && (
<Form.Item<FieldType> <Form.Item<FieldType>
label={t('addSparkAPIKey')} label={t('addSparkAPIKey')}
name="spark_api_key" name="spark_api_key"
rules={[{ required: true, message: t('SparkAPIKeyMessage') }]} rules={[{ required: true, message: t('SparkAPIKeyMessage') }]}
> >
<Input placeholder={t('SparkAPIKeyMessage')} /> <Input placeholder={t('SparkAPIKeyMessage')} />
</Form.Item> </Form.Item>
) )
} }
</Form.Item> </Form.Item>
@ -153,7 +157,6 @@ const SparkModal = ({
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Flex, Form, Input, Modal, Select, Space, Switch, InputNumber } from 'antd'; import { Flex, Form, Input, InputNumber, Modal, Select, Space } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
@ -36,7 +36,7 @@ const VolcEngineModal = ({
...omit(values, ['vision']), ...omit(values, ['vision']),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
console.info(data); console.info(data);
@ -128,7 +128,6 @@ const VolcEngineModal = ({
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -1,7 +1,7 @@
import { useTranslate } from '@/hooks/common-hooks'; import { useTranslate } from '@/hooks/common-hooks';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { IAddLlmRequestBody } from '@/interfaces/request/llm'; import { IAddLlmRequestBody } from '@/interfaces/request/llm';
import { Form, Input, Modal, Select, InputNumber } from 'antd'; import { Form, Input, InputNumber, Modal, Select } from 'antd';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
type FieldType = IAddLlmRequestBody & { type FieldType = IAddLlmRequestBody & {
@ -34,7 +34,7 @@ const YiyanModal = ({
...omit(values, ['vision']), ...omit(values, ['vision']),
model_type: modelType, model_type: modelType,
llm_factory: llmFactory, llm_factory: llmFactory,
max_tokens:values.max_tokens, max_tokens: values.max_tokens,
}; };
console.info(data); console.info(data);

View File

@ -45,11 +45,16 @@ const methods = {
url: connectFileToKnowledge, url: connectFileToKnowledge,
method: 'post', method: 'post',
}, },
getDocumentFile: { getFile: {
url: getFile, url: getFile,
method: 'get', method: 'get',
responseType: 'blob', responseType: 'blob',
}, },
getDocumentFile: {
url: get_document_file,
method: 'get',
responseType: 'blob',
},
moveFile: { moveFile: {
url: moveFile, url: moveFile,
method: 'post', method: 'post',

View File

@ -1,3 +1,4 @@
import fileManagerService from '@/services/file-manager-service';
import { UploadFile } from 'antd'; import { UploadFile } from 'antd';
export const transformFile2Base64 = (val: any): Promise<any> => { export const transformFile2Base64 = (val: any): Promise<any> => {
@ -100,29 +101,41 @@ export const getBase64FromUploadFileList = async (fileList?: UploadFile[]) => {
return ''; return '';
}; };
export const downloadFile = ({ export const downloadFileFromBlob = (blob: Blob, name?: string) => {
url, const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
if (name) {
a.download = name;
}
a.click();
window.URL.revokeObjectURL(url);
};
export const downloadFile = async ({
id,
filename, filename,
target, target,
}: { }: {
url: string; id: string;
filename?: string; filename?: string;
target?: string; target?: string;
}) => { }) => {
console.log('downloadFile', url); const response = await fileManagerService.getFile({}, id);
const downloadElement = document.createElement('a'); const blob = new Blob([response.data], { type: response.data.type });
downloadElement.style.display = 'none'; downloadFileFromBlob(blob, filename);
downloadElement.href = url; };
if (target) {
downloadElement.target = '_blank'; export const downloadDocument = async ({
} id,
downloadElement.rel = 'noopener noreferrer'; filename,
if (filename) { }: {
downloadElement.download = filename; id: string;
} filename?: string;
document.body.appendChild(downloadElement); }) => {
downloadElement.click(); const response = await fileManagerService.getDocumentFile({}, id);
document.body.removeChild(downloadElement); const blob = new Blob([response.data], { type: response.data.type });
downloadFileFromBlob(blob, filename);
}; };
const Units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const Units = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];