mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-01 20:27:45 +00:00
v4.6-3 (#471)
This commit is contained in:
@@ -9,10 +9,10 @@ import { TOKEN_ERROR_CODE } from '@fastgpt/global/common/error/errorCode';
|
||||
|
||||
interface ConfigType {
|
||||
headers?: { [key: string]: string };
|
||||
hold?: boolean;
|
||||
timeout?: number;
|
||||
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
||||
cancelToken?: AbortController;
|
||||
maxQuantity?: number;
|
||||
}
|
||||
interface ResponseDataType {
|
||||
code: number;
|
||||
@@ -20,10 +20,44 @@ interface ResponseDataType {
|
||||
data: any;
|
||||
}
|
||||
|
||||
const maxQuantityMap: Record<
|
||||
string,
|
||||
{
|
||||
amount: number;
|
||||
sign: AbortController;
|
||||
}
|
||||
> = {};
|
||||
|
||||
function requestStart({ url, maxQuantity }: { url: string; maxQuantity?: number }) {
|
||||
if (!maxQuantity) return;
|
||||
const item = maxQuantityMap[url];
|
||||
|
||||
if (item) {
|
||||
if (item.amount >= maxQuantity && item.sign) {
|
||||
item.sign.abort();
|
||||
delete maxQuantityMap[url];
|
||||
}
|
||||
} else {
|
||||
maxQuantityMap[url] = {
|
||||
amount: 1,
|
||||
sign: new AbortController()
|
||||
};
|
||||
}
|
||||
}
|
||||
function requestFinish({ url }: { url: string }) {
|
||||
const item = maxQuantityMap[url];
|
||||
if (item) {
|
||||
item.amount--;
|
||||
if (item.amount <= 0) {
|
||||
delete maxQuantityMap[url];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求开始
|
||||
*/
|
||||
function requestStart(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
|
||||
function startInterceptors(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
|
||||
if (config.headers) {
|
||||
config.headers.token = getToken();
|
||||
}
|
||||
@@ -85,14 +119,14 @@ const instance = axios.create({
|
||||
});
|
||||
|
||||
/* 请求拦截 */
|
||||
instance.interceptors.request.use(requestStart, (err) => Promise.reject(err));
|
||||
instance.interceptors.request.use(startInterceptors, (err) => Promise.reject(err));
|
||||
/* 响应拦截 */
|
||||
instance.interceptors.response.use(responseSuccess, (err) => Promise.reject(err));
|
||||
|
||||
function request(
|
||||
url: string,
|
||||
data: any,
|
||||
{ cancelToken, ...config }: ConfigType,
|
||||
{ cancelToken, maxQuantity, ...config }: ConfigType,
|
||||
method: Method
|
||||
): any {
|
||||
/* 去空 */
|
||||
@@ -102,6 +136,8 @@ function request(
|
||||
}
|
||||
}
|
||||
|
||||
requestStart({ url, maxQuantity });
|
||||
|
||||
return instance
|
||||
.request({
|
||||
baseURL: '/api',
|
||||
@@ -113,7 +149,8 @@ function request(
|
||||
...config // 用户自定义配置,可以覆盖前面的配置
|
||||
})
|
||||
.then((res) => checkRes(res.data))
|
||||
.catch((err) => responseError(err));
|
||||
.catch((err) => responseError(err))
|
||||
.finally(() => requestFinish({ url }));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React, { useRef, useCallback } from 'react';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
export const useSelectFile = (props?: { fileType?: string; multiple?: boolean }) => {
|
||||
const { t } = useTranslation();
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useToast } from './useToast';
|
||||
|
||||
/**
|
||||
|
@@ -2,7 +2,7 @@ import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import type { UseMutationOptions } from '@tanstack/react-query';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
interface Props extends UseMutationOptions<any, any, any, any> {
|
||||
successToast?: string | null;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { POST } from '../api/request';
|
||||
import { useToast } from './useToast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
|
||||
export const useSpeech = () => {
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
export const LANG_KEY = 'NEXT_LOCALE_LANG';
|
||||
export enum LangEnum {
|
||||
@@ -17,21 +16,27 @@ export const langMap = {
|
||||
}
|
||||
};
|
||||
|
||||
export const setLangStore = (value: `${LangEnum}`) => {
|
||||
return Cookies.set(LANG_KEY, value, { expires: 7, sameSite: 'None', secure: true });
|
||||
};
|
||||
|
||||
export const getLangStore = () => {
|
||||
return (Cookies.get(LANG_KEY) as `${LangEnum}`) || LangEnum.zh;
|
||||
};
|
||||
|
||||
export const serviceSideProps = (content: any) => {
|
||||
const acceptLanguage = (content.req.headers['accept-language'] as string) || '';
|
||||
const acceptLanguageList = acceptLanguage.split(/,|;/g);
|
||||
// @ts-ignore
|
||||
const firstLang = acceptLanguageList.find((lang) => langMap[lang]);
|
||||
|
||||
const language = content.req.cookies[LANG_KEY] || firstLang || 'zh';
|
||||
|
||||
return serverSideTranslations(language, undefined, null, content.locales);
|
||||
return serverSideTranslations(content.locale, undefined, null, content.locales);
|
||||
};
|
||||
|
||||
export const getLng = (lng: string) => {
|
||||
return lng.split('-')[0];
|
||||
};
|
||||
export const change2DefaultLng = (currentLng: string) => {
|
||||
if (!navigator || !localStorage) return;
|
||||
if (localStorage.getItem(LANG_KEY)) return;
|
||||
const userLang = navigator.language;
|
||||
|
||||
if (userLang.includes(currentLng)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// currentLng not in userLang
|
||||
return getLng(userLang);
|
||||
};
|
||||
|
||||
export const setLngStore = (lng: string) => {
|
||||
if (!localStorage) return;
|
||||
localStorage.setItem(LANG_KEY, lng);
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@ import {
|
||||
FlowNodeSpecialInputKeyEnum
|
||||
} from '@fastgpt/global/core/module/node/constant';
|
||||
import { SystemInputEnum } from '@/constants/app';
|
||||
import type { SelectedDatasetType } from '@/types/core/dataset';
|
||||
import type { SelectedDatasetType } from '@fastgpt/global/core/module/api.d';
|
||||
import type { FlowNodeInputItemType } from '@fastgpt/global/core/module/node/type.d';
|
||||
import type { AIChatProps } from '@/types/core/aiChat';
|
||||
import { getGuideModule, splitGuideModule } from '@/global/core/app/modules/utils';
|
||||
|
@@ -1,16 +1,20 @@
|
||||
import { GET, POST, PUT, DELETE } from '@/web/common/api/request';
|
||||
import type { DatasetItemType, DatasetPathItemType } from '@/types/core/dataset';
|
||||
import type { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type.d';
|
||||
import type { DatasetItemType } from '@fastgpt/global/core/dataset/type.d';
|
||||
import type {
|
||||
DatasetUpdateParams,
|
||||
CreateDatasetParams,
|
||||
SearchTestProps,
|
||||
GetDatasetCollectionsProps,
|
||||
PushDataProps,
|
||||
GetDatasetDataListProps,
|
||||
CreateDatasetCollectionParams,
|
||||
UpdateDatasetCollectionParams,
|
||||
SetOneDatasetDataProps
|
||||
UpdateDatasetCollectionParams
|
||||
} from '@/global/core/api/datasetReq.d';
|
||||
import type {
|
||||
PushDatasetDataProps,
|
||||
UpdateDatasetDataProps,
|
||||
CreateDatasetParams,
|
||||
InsertOneDatasetDataProps
|
||||
} from '@/global/core/dataset/api.d';
|
||||
import type { PushDataResponse } from '@/global/core/api/datasetRes.d';
|
||||
import type {
|
||||
DatasetCollectionItemType,
|
||||
@@ -20,8 +24,7 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant';
|
||||
import { getToken } from '@/web/support/user/auth';
|
||||
import download from 'downloadjs';
|
||||
import type { DatasetDataItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import { DatasetCollectionsListItemType } from '@/global/core/dataset/response';
|
||||
import type { DatasetCollectionsListItemType } from '@/global/core/dataset/type.d';
|
||||
import { PagingData } from '@/types';
|
||||
|
||||
/* ======================== dataset ======================= */
|
||||
@@ -34,7 +37,7 @@ export const getDatasets = (data: { parentId?: string; type?: `${DatasetTypeEnum
|
||||
export const getAllDataset = () => GET<DatasetItemType[]>(`/core/dataset/allDataset`);
|
||||
|
||||
export const getDatasetPaths = (parentId?: string) =>
|
||||
GET<DatasetPathItemType[]>('/core/dataset/paths', { parentId });
|
||||
GET<ParentTreePathItemType[]>('/core/dataset/paths', { parentId });
|
||||
|
||||
export const getDatasetById = (id: string) => GET<DatasetItemType>(`/core/dataset/detail?id=${id}`);
|
||||
|
||||
@@ -64,58 +67,39 @@ export const delDatasetCollectionById = (params: { collectionId: string }) =>
|
||||
DELETE(`/core/dataset/collection/delById`, params);
|
||||
|
||||
/* =============================== data ==================================== */
|
||||
|
||||
/* get dataset list */
|
||||
export const getDatasetDataList = (data: GetDatasetDataListProps) =>
|
||||
POST(`/core/dataset/data/getDataList`, data);
|
||||
|
||||
/**
|
||||
* export and download data
|
||||
*/
|
||||
export const exportDatasetData = (data: { datasetId: string }) =>
|
||||
fetch(`/api/core/dataset/data/exportAll?datasetId=${data.datasetId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
token: getToken()
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) {
|
||||
const data = await res.json();
|
||||
throw new Error(data?.message || 'Export failed');
|
||||
}
|
||||
return res.blob();
|
||||
})
|
||||
.then((blob) => download(blob, 'dataset.csv', 'text/csv'));
|
||||
|
||||
/* get length of system training queue */
|
||||
export const getTrainingQueueLen = () => GET<number>(`/core/dataset/data/getQueueLen`);
|
||||
POST(`/core/dataset/data/list`, data);
|
||||
|
||||
export const getDatasetDataItemById = (dataId: string) =>
|
||||
GET<DatasetDataItemType>(`/core/dataset/data/getDataById`, { dataId });
|
||||
GET<DatasetDataItemType>(`/core/dataset/data/detail`, { dataId });
|
||||
|
||||
/**
|
||||
* push data to training queue
|
||||
*/
|
||||
export const postChunks2Dataset = (data: PushDataProps) =>
|
||||
export const postChunks2Dataset = (data: PushDatasetDataProps) =>
|
||||
POST<PushDataResponse>(`/core/dataset/data/pushData`, data);
|
||||
|
||||
/**
|
||||
* insert one data to dataset (immediately insert)
|
||||
*/
|
||||
export const postData2Dataset = (data: SetOneDatasetDataProps) =>
|
||||
export const postInsertData2Dataset = (data: InsertOneDatasetDataProps) =>
|
||||
POST<string>(`/core/dataset/data/insertData`, data);
|
||||
|
||||
/**
|
||||
* 更新一条数据
|
||||
* update one datasetData by id
|
||||
*/
|
||||
export const putDatasetDataById = (data: SetOneDatasetDataProps) =>
|
||||
PUT('/core/dataset/data/updateData', data);
|
||||
export const putDatasetDataById = (data: UpdateDatasetDataProps) =>
|
||||
PUT('/core/dataset/data/update', data);
|
||||
/**
|
||||
* 删除一条知识库数据
|
||||
*/
|
||||
export const delOneDatasetDataById = (dataId: string) =>
|
||||
DELETE(`/core/dataset/data/delDataById?dataId=${dataId}`);
|
||||
DELETE<string>(`/core/dataset/data/delete`, { dataId });
|
||||
|
||||
/* ================ training ==================== */
|
||||
/* get length of system training queue */
|
||||
export const getTrainingQueueLen = () => GET<number>(`/core/dataset/training/getQueueLen`);
|
||||
|
||||
/* ================== file ======================== */
|
||||
export const getFileViewUrl = (fileId: string) =>
|
||||
|
@@ -10,7 +10,7 @@ import { DatasetCollectionTypeEnum } from '@fastgpt/global/core/dataset/constant
|
||||
import { getCollectionIcon } from '@fastgpt/global/core/dataset/utils';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
const SelectCollections = ({
|
||||
datasetId,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import type { DatasetItemType } from '@/types/core/dataset';
|
||||
import type { DatasetItemType } from '@fastgpt/global/core/dataset/type.d';
|
||||
import { getAllDataset, getDatasets, getDatasetById, putDatasetById } from '@/web/core/dataset/api';
|
||||
import { defaultDatasetDetail } from '@/constants/dataset';
|
||||
import type { DatasetUpdateParams } from '@/global/core/api/datasetReq.d';
|
||||
@@ -69,7 +69,7 @@ export const useDatasetStore = create<State>()(
|
||||
? {
|
||||
...item,
|
||||
...data,
|
||||
tags: data.tags || ''
|
||||
tags: data.tags || []
|
||||
}
|
||||
: item
|
||||
);
|
||||
|
@@ -1,7 +1,6 @@
|
||||
import { create } from 'zustand';
|
||||
import { devtools, persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
|
||||
export type MarkDataStore = {
|
||||
chatItemId: string;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { getFileViewUrl, postChunks2Dataset } from '@/web/core/dataset/api';
|
||||
import { TrainingModeEnum } from '@fastgpt/global/core/dataset/constant';
|
||||
import { DatasetChunkItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import { delay } from '@/utils/tools';
|
||||
import { strIsLink } from '@fastgpt/global/common/string/tools';
|
||||
import type { PushDatasetDataChunkProps } from '@fastgpt/global/core/dataset/api.d';
|
||||
|
||||
export async function chunksUpload({
|
||||
collectionId,
|
||||
@@ -15,12 +16,12 @@ export async function chunksUpload({
|
||||
collectionId: string;
|
||||
billId: string;
|
||||
mode: `${TrainingModeEnum}`;
|
||||
chunks: DatasetChunkItemType[];
|
||||
chunks: PushDatasetDataChunkProps[];
|
||||
prompt?: string;
|
||||
rate?: number;
|
||||
onUploading?: (insertLen: number, total: number) => void;
|
||||
}) {
|
||||
async function upload(data: DatasetChunkItemType[]) {
|
||||
async function upload(data: PushDatasetDataChunkProps[]) {
|
||||
return postChunks2Dataset({
|
||||
collectionId,
|
||||
data,
|
||||
@@ -51,6 +52,9 @@ export async function chunksUpload({
|
||||
}
|
||||
|
||||
export async function getFileAndOpen(fileId: string) {
|
||||
if (strIsLink(fileId)) {
|
||||
return window.open(fileId, '_blank');
|
||||
}
|
||||
const url = await getFileViewUrl(fileId);
|
||||
const asPath = `${location.origin}${url}`;
|
||||
window.open(asPath, '_blank');
|
||||
|
@@ -22,3 +22,7 @@
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
span[tabindex='0'] {
|
||||
line-height: 1;
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@ const Button = defineStyleConfig({
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
_hover: {
|
||||
filter: 'brightness(115%)'
|
||||
filter: 'brightness(120%)'
|
||||
},
|
||||
_disabled: {
|
||||
bg: '#3370ff !important'
|
||||
@@ -74,7 +74,8 @@ const Button = defineStyleConfig({
|
||||
transition: 'background 0.3s',
|
||||
_hover: {
|
||||
color: 'myBlue.600',
|
||||
bg: 'myWhite.400'
|
||||
bg: 'myWhite.400',
|
||||
boxShadow: '0 0 5px rgba(0,0,0,0.2)'
|
||||
},
|
||||
_active: {
|
||||
color: 'myBlue.700'
|
||||
|
@@ -12,7 +12,8 @@ export const sendAuthCode = (data: {
|
||||
googleToken: string;
|
||||
}) => POST(`/plusApi/support/user/inform/sendAuthCode`, data);
|
||||
|
||||
export const getTokenLogin = () => GET<UserType>('/user/account/tokenLogin');
|
||||
export const getTokenLogin = () =>
|
||||
GET<UserType>('/user/account/tokenLogin', {}, { maxQuantity: 1 });
|
||||
export const oauthLogin = (params: OauthLoginProps) =>
|
||||
POST<ResLogin>('/plusApi/support/user/account/login/oauth', params);
|
||||
|
||||
|
@@ -21,7 +21,6 @@ export const postCreateTeam = (data: CreateTeamProps) =>
|
||||
POST<string>(`/plusApi/support/user/team/create`, data);
|
||||
export const putUpdateTeam = (data: UpdateTeamProps) =>
|
||||
PUT(`/plusApi/support/user/team/update`, data);
|
||||
export const deleteTeam = (id: number) => DELETE(`/plusApi/support/user/team/delete`, { id });
|
||||
export const putSwitchTeam = (teamId: string) =>
|
||||
PUT<string>(`/plusApi/support/user/team/switch`, { teamId });
|
||||
|
||||
@@ -32,6 +31,8 @@ export const postInviteTeamMember = (data: InviteMemberProps) =>
|
||||
POST<InviteMemberResponse>(`/plusApi/support/user/team/member/invite`, data);
|
||||
export const putUpdateMember = (data: UpdateTeamMemberProps) =>
|
||||
PUT(`/plusApi/support/user/team/member/update`, data);
|
||||
export const putUpdateMemberName = (name: string) =>
|
||||
PUT(`/plusApi/support/user/team/member/updateName`, { name });
|
||||
export const delRemoveMember = (props: DelMemberProps) =>
|
||||
DELETE(`/plusApi/support/user/team/member/delete`, props);
|
||||
export const updateInviteResult = (data: UpdateInviteProps) =>
|
||||
|
Reference in New Issue
Block a user