mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
perf: model provider show; perf: get init data buffer (#3459)
* pr code * perf: model table show * perf: model provider show * perf: get init data buffer * perf: get init data buffer * perf: icon
This commit is contained in:
@@ -61,7 +61,7 @@ const Layout = ({ children }: { children: JSX.Element }) => {
|
||||
// System hook
|
||||
const { data, refetch: refetchUnRead } = useQuery(['getUnreadCount'], getUnreadCount, {
|
||||
enabled: !!userInfo && !!feConfigs.isPlus,
|
||||
refetchInterval: 10000
|
||||
refetchInterval: 30000
|
||||
});
|
||||
const unread = data?.unReadCount || 0;
|
||||
const importantInforms = data?.importantInforms || [];
|
||||
|
@@ -83,9 +83,10 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
'/account/team',
|
||||
'/account/usage',
|
||||
'/account/apikey',
|
||||
'/account/individuation',
|
||||
'/account/setting',
|
||||
'/account/inform',
|
||||
'/account/promotion'
|
||||
'/account/promotion',
|
||||
'/account/model'
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@@ -55,9 +55,10 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
|
||||
'/account/team',
|
||||
'/account/usage',
|
||||
'/account/apikey',
|
||||
'/account/individuation',
|
||||
'/account/setting',
|
||||
'/account/inform',
|
||||
'/account/promotion'
|
||||
'/account/promotion',
|
||||
'/account/model'
|
||||
],
|
||||
unread
|
||||
}
|
||||
|
@@ -12,8 +12,8 @@ import { ModelProviderList } from '@fastgpt/global/core/ai/provider';
|
||||
import MultipleRowSelect from '@fastgpt/web/components/common/MySelect/MultipleRowSelect';
|
||||
import { getModelFromList } from '@fastgpt/global/core/ai/model';
|
||||
|
||||
const AiPointsModal = dynamic(() =>
|
||||
import('@/pages/price/components/Points').then((mod) => mod.AiPointsModal)
|
||||
const ModelPriceModal = dynamic(() =>
|
||||
import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal)
|
||||
);
|
||||
|
||||
type Props = SelectProps & {
|
||||
@@ -103,7 +103,7 @@ const OneRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {
|
||||
/>
|
||||
</MyTooltip>
|
||||
|
||||
{isOpenAiPointsModal && <AiPointsModal onClose={onCloseAiPointsModal} />}
|
||||
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -212,7 +212,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) =>
|
||||
/>
|
||||
</MyTooltip>
|
||||
|
||||
{isOpenAiPointsModal && <AiPointsModal onClose={onCloseAiPointsModal} />}
|
||||
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
@@ -33,8 +33,8 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import dynamic from 'next/dynamic';
|
||||
import InputSlider from '@fastgpt/web/components/common/MySlider/InputSlider';
|
||||
|
||||
const AiPointsModal = dynamic(() =>
|
||||
import('@/pages/price/components/Points').then((mod) => mod.AiPointsModal)
|
||||
const ModelPriceModal = dynamic(() =>
|
||||
import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal)
|
||||
);
|
||||
|
||||
const FlexItemStyles: FlexProps = {
|
||||
@@ -328,7 +328,7 @@ const AIChatSettingsModal = ({
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
{isOpenAiPointsModal && <AiPointsModal onClose={onCloseAiPointsModal} />}
|
||||
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
|
||||
</MyModal>
|
||||
);
|
||||
};
|
||||
|
251
projects/app/src/components/core/ai/ModelTable/index.tsx
Normal file
251
projects/app/src/components/core/ai/ModelTable/index.tsx
Normal file
@@ -0,0 +1,251 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
HStack,
|
||||
ModalBody,
|
||||
Table,
|
||||
TableContainer,
|
||||
Tbody,
|
||||
Td,
|
||||
Th,
|
||||
Thead,
|
||||
Tr
|
||||
} from '@chakra-ui/react';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
ModelProviderList,
|
||||
ModelProviderIdType,
|
||||
getModelProvider
|
||||
} from '@fastgpt/global/core/ai/provider';
|
||||
import MySelect from '@fastgpt/web/components/common/MySelect';
|
||||
import { modelTypeList, ModelTypeEnum } from '@fastgpt/global/core/ai/model';
|
||||
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||
import MyTag from '@fastgpt/web/components/common/Tag/index';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
|
||||
const ModelTable = () => {
|
||||
const { t } = useTranslation();
|
||||
const [provider, setProvider] = useState<ModelProviderIdType | ''>('');
|
||||
const providerList = useRef<{ label: any; value: ModelProviderIdType | '' }[]>([
|
||||
{ label: t('common:common.All'), value: '' },
|
||||
...ModelProviderList.map((item) => ({
|
||||
label: (
|
||||
<HStack>
|
||||
<Avatar src={item.avatar} w={'1rem'} />
|
||||
<Box>{t(item.name as any)}</Box>
|
||||
</HStack>
|
||||
),
|
||||
value: item.id
|
||||
}))
|
||||
]);
|
||||
|
||||
const [modelType, setModelType] = useState<ModelTypeEnum | ''>('');
|
||||
const selectModelTypeList = useRef<{ label: string; value: ModelTypeEnum | '' }[]>([
|
||||
{ label: t('common:common.All'), value: '' },
|
||||
...modelTypeList.map((item) => ({ label: t(item.label), value: item.value }))
|
||||
]);
|
||||
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
const { llmModelList, audioSpeechModelList, vectorModelList, whisperModel } = useSystemStore();
|
||||
|
||||
const modelList = useMemo(() => {
|
||||
const formatLLMModelList = llmModelList.map((item) => ({
|
||||
...item,
|
||||
typeLabel: t('common:model.type.chat'),
|
||||
priceLabel: (
|
||||
<Flex color={'myGray.700'}>
|
||||
<Box fontWeight={'bold'} color={'myGray.900'} mr={0.5}>
|
||||
{item.charsPointsPrice}
|
||||
</Box>
|
||||
{`${t('common:support.wallet.subscription.point')} / 1K Tokens`}
|
||||
</Flex>
|
||||
),
|
||||
tagColor: 'blue'
|
||||
}));
|
||||
const formatVectorModelList = vectorModelList.map((item) => ({
|
||||
...item,
|
||||
typeLabel: t('common:model.type.embedding'),
|
||||
priceLabel: (
|
||||
<Flex color={'myGray.700'}>
|
||||
<Box fontWeight={'bold'} color={'myGray.900'} mr={0.5}>
|
||||
{item.charsPointsPrice}
|
||||
</Box>
|
||||
{` ${t('common:support.wallet.subscription.point')} / 1K Tokens`}
|
||||
</Flex>
|
||||
),
|
||||
tagColor: 'yellow'
|
||||
}));
|
||||
const formatAudioSpeechModelList = audioSpeechModelList.map((item) => ({
|
||||
...item,
|
||||
typeLabel: t('common:model.type.tts'),
|
||||
priceLabel: (
|
||||
<Flex color={'myGray.700'}>
|
||||
<Box fontWeight={'bold'} color={'myGray.900'} mr={0.5}>
|
||||
{item.charsPointsPrice}
|
||||
</Box>
|
||||
{` ${t('common:support.wallet.subscription.point')} / 1K ${t('common:unit.character')}`}
|
||||
</Flex>
|
||||
),
|
||||
tagColor: 'green'
|
||||
}));
|
||||
const formatWhisperModel = {
|
||||
...whisperModel,
|
||||
typeLabel: t('common:model.type.stt'),
|
||||
priceLabel: (
|
||||
<Flex color={'myGray.700'}>
|
||||
<Box fontWeight={'bold'} color={'myGray.900'} mr={0.5}>
|
||||
{whisperModel.charsPointsPrice}
|
||||
</Box>
|
||||
{` ${t('common:support.wallet.subscription.point')} / 60${t('common:unit.seconds')}`}
|
||||
</Flex>
|
||||
),
|
||||
tagColor: 'purple'
|
||||
};
|
||||
|
||||
const list = (() => {
|
||||
if (modelType === ModelTypeEnum.chat) return formatLLMModelList;
|
||||
if (modelType === ModelTypeEnum.embedding) return formatVectorModelList;
|
||||
if (modelType === ModelTypeEnum.tts) return formatAudioSpeechModelList;
|
||||
if (modelType === ModelTypeEnum.stt) return [formatWhisperModel];
|
||||
|
||||
return [
|
||||
...formatLLMModelList,
|
||||
...formatVectorModelList,
|
||||
...formatAudioSpeechModelList,
|
||||
formatWhisperModel
|
||||
];
|
||||
})();
|
||||
const formatList = list.map((item) => {
|
||||
const provider = getModelProvider(item.provider);
|
||||
return {
|
||||
name: item.name,
|
||||
avatar: provider.avatar,
|
||||
providerId: provider.id,
|
||||
providerName: t(provider.name as any),
|
||||
typeLabel: item.typeLabel,
|
||||
priceLabel: item.priceLabel,
|
||||
order: provider.order,
|
||||
tagColor: item.tagColor
|
||||
};
|
||||
});
|
||||
formatList.sort((a, b) => a.order - b.order);
|
||||
|
||||
const filterList = formatList.filter((item) => {
|
||||
const providerFilter = provider ? item.providerId === provider : true;
|
||||
|
||||
const regx = new RegExp(search, 'i');
|
||||
const nameFilter = search ? regx.test(item.name) : true;
|
||||
|
||||
return providerFilter && nameFilter;
|
||||
});
|
||||
|
||||
return filterList;
|
||||
}, [
|
||||
provider,
|
||||
modelType,
|
||||
llmModelList,
|
||||
vectorModelList,
|
||||
audioSpeechModelList,
|
||||
whisperModel,
|
||||
t,
|
||||
search
|
||||
]);
|
||||
|
||||
return (
|
||||
<Flex flexDirection={'column'} h={'100%'}>
|
||||
<Flex>
|
||||
<HStack flexShrink={0}>
|
||||
<Box fontSize={'sm'} color={'myGray.900'}>
|
||||
{t('common:model.provider')}
|
||||
</Box>
|
||||
<MySelect
|
||||
w={'200px'}
|
||||
bg={'myGray.50'}
|
||||
value={provider}
|
||||
onchange={setProvider}
|
||||
list={providerList.current}
|
||||
/>
|
||||
</HStack>
|
||||
<HStack flexShrink={0} ml={6}>
|
||||
<Box fontSize={'sm'} color={'myGray.900'}>
|
||||
{t('common:model.model_type')}
|
||||
</Box>
|
||||
<MySelect
|
||||
w={'150px'}
|
||||
bg={'myGray.50'}
|
||||
value={modelType}
|
||||
onchange={setModelType}
|
||||
list={selectModelTypeList.current}
|
||||
/>
|
||||
</HStack>
|
||||
<Box flex={1} />
|
||||
<Box flex={'0 0 250px'}>
|
||||
<SearchInput
|
||||
bg={'myGray.50'}
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder={t('common:model.search_name_placeholder')}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
<TableContainer mt={5} flex={'1 0 0'} h={0} overflowY={'auto'}>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr color={'myGray.600'}>
|
||||
<Th fontSize={'xs'}>{t('common:model.name')}</Th>
|
||||
<Th fontSize={'xs'}>{t('common:model.model_type')}</Th>
|
||||
<Th fontSize={'xs'}>{t('common:model.billing')}</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{modelList.map((item) => (
|
||||
<Tr key={item.name} _hover={{ bg: 'myGray.50' }}>
|
||||
<Td fontSize={'sm'}>
|
||||
<MyTooltip title={item.providerName}>
|
||||
<HStack>
|
||||
<Avatar src={item.avatar} w={'1.2rem'} />
|
||||
<Box color={'myGray.900'}>{item.name}</Box>
|
||||
</HStack>
|
||||
</MyTooltip>
|
||||
</Td>
|
||||
<Td>
|
||||
<MyTag colorSchema={item.tagColor as any}>{item.typeLabel}</MyTag>
|
||||
</Td>
|
||||
<Td fontSize={'sm'}>{item.priceLabel}</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModelTable;
|
||||
|
||||
export const ModelPriceModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
isCentered
|
||||
iconSrc="/imgs/modal/bill.svg"
|
||||
title={t('common:support.wallet.subscription.Ai points')}
|
||||
isOpen
|
||||
onClose={onClose}
|
||||
w={'100%'}
|
||||
h={'100%'}
|
||||
maxW={'90vw'}
|
||||
maxH={'90vh'}
|
||||
>
|
||||
<ModalBody flex={'1 0 0'}>
|
||||
<ModelTable />
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
);
|
||||
};
|
@@ -8,8 +8,8 @@ import { useTranslation } from 'next-i18next';
|
||||
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const AiPointsModal = dynamic(() =>
|
||||
import('@/pages/price/components/Points').then((mod) => mod.AiPointsModal)
|
||||
const ModelPriceModal = dynamic(() =>
|
||||
import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal)
|
||||
);
|
||||
|
||||
const StandardPlanContentList = ({
|
||||
@@ -127,7 +127,7 @@ const StandardPlanContentList = ({
|
||||
<Box color={'myGray.600'}>{t('common:support.wallet.subscription.web_site_sync')}</Box>
|
||||
</Flex>
|
||||
)}
|
||||
{isOpenAiPointsModal && <AiPointsModal onClose={onCloseAiPointsModal} />}
|
||||
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
|
||||
</Grid>
|
||||
) : null;
|
||||
};
|
||||
|
@@ -2,7 +2,7 @@ import type {
|
||||
LLMModelItemType,
|
||||
VectorModelItemType,
|
||||
AudioSpeechModels,
|
||||
WhisperModelType,
|
||||
STTModelType,
|
||||
ReRankModelItemType
|
||||
} from '@fastgpt/global/core/ai/model.d';
|
||||
|
||||
@@ -10,11 +10,12 @@ import type { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types/i
|
||||
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
|
||||
|
||||
export type InitDateResponse = {
|
||||
bufferId?: string;
|
||||
llmModels: LLMModelItemType[];
|
||||
vectorModels: VectorModelItemType[];
|
||||
audioSpeechModels: AudioSpeechModels[];
|
||||
reRankModels: ReRankModelItemType[];
|
||||
whisperModel: WhisperModelType;
|
||||
whisperModel: STTModelType;
|
||||
feConfigs: FastGPTFeConfigsType;
|
||||
subPlans?: SubPlanType;
|
||||
systemVersion: string;
|
||||
|
@@ -8,9 +8,7 @@ import PageContainer from '@/components/PageContainer';
|
||||
import SideTabs from '@/components/SideTabs';
|
||||
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Script from 'next/script';
|
||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||
import { getWebReqUrl } from '@fastgpt/web/common/system/utils';
|
||||
|
||||
export enum TabEnum {
|
||||
'info' = 'info',
|
||||
@@ -18,10 +16,11 @@ export enum TabEnum {
|
||||
'usage' = 'usage',
|
||||
'bill' = 'bill',
|
||||
'inform' = 'inform',
|
||||
'individuation' = 'individuation',
|
||||
'setting' = 'setting',
|
||||
'apikey' = 'apikey',
|
||||
'loginout' = 'loginout',
|
||||
'team' = 'team'
|
||||
'team' = 'team',
|
||||
'model' = 'model'
|
||||
}
|
||||
|
||||
const AccountContainer = ({
|
||||
@@ -71,6 +70,11 @@ const AccountContainer = ({
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
icon: 'common/model',
|
||||
label: t('account:model_provider'),
|
||||
value: TabEnum.model
|
||||
},
|
||||
...(feConfigs?.show_promotion && userInfo?.team?.permission.isOwner
|
||||
? [
|
||||
{
|
||||
@@ -89,11 +93,7 @@ const AccountContainer = ({
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
icon: 'support/user/individuation',
|
||||
label: t('account:personalization'),
|
||||
value: TabEnum.individuation
|
||||
},
|
||||
|
||||
...(feConfigs.isPlus
|
||||
? [
|
||||
{
|
||||
@@ -103,6 +103,11 @@ const AccountContainer = ({
|
||||
}
|
||||
]
|
||||
: []),
|
||||
{
|
||||
icon: 'common/settingLight',
|
||||
label: t('common:common.Setting'),
|
||||
value: TabEnum.setting
|
||||
},
|
||||
{
|
||||
icon: 'support/account/loginoutLight',
|
||||
label: t('account:logout'),
|
||||
|
@@ -48,15 +48,16 @@ import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
||||
import { useRouter } from 'next/router';
|
||||
import TeamSelector from '../components/TeamSelector';
|
||||
|
||||
const StandDetailModal = dynamic(() => import('./components/standardDetailModal'));
|
||||
const StandDetailModal = dynamic(() => import('./components/standardDetailModal'), { ssr: false });
|
||||
const ConversionModal = dynamic(() => import('./components/ConversionModal'));
|
||||
const UpdatePswModal = dynamic(() => import('./components/UpdatePswModal'));
|
||||
const UpdateNotification = dynamic(() => import('./components/UpdateNotificationModal'));
|
||||
const OpenAIAccountModal = dynamic(() => import('./components/OpenAIAccountModal'));
|
||||
const LafAccountModal = dynamic(() => import('@/components/support/laf/LafAccountModal'));
|
||||
const CommunityModal = dynamic(() => import('@/components/CommunityModal'));
|
||||
const AiPointsModal = dynamic(() =>
|
||||
import('@/pages/price/components/Points').then((mod) => mod.AiPointsModal)
|
||||
|
||||
const ModelPriceModal = dynamic(() =>
|
||||
import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal)
|
||||
);
|
||||
|
||||
const Info = () => {
|
||||
@@ -583,7 +584,7 @@ const PlanUsage = () => {
|
||||
</Box>
|
||||
</Box>
|
||||
{isOpenStandardModal && <StandDetailModal onClose={onCloseStandardModal} />}
|
||||
{isOpenAiPointsModal && <AiPointsModal onClose={onCloseAiPointsModal} />}
|
||||
{isOpenAiPointsModal && <ModelPriceModal onClose={onCloseAiPointsModal} />}
|
||||
</Box>
|
||||
) : null;
|
||||
};
|
||||
|
25
projects/app/src/pages/account/model/index.tsx
Normal file
25
projects/app/src/pages/account/model/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { serviceSideProps } from '@fastgpt/web/common/system/nextjs';
|
||||
import React from 'react';
|
||||
import AccountContainer from '../components/AccountContainer';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
import ModelTable from '@/components/core/ai/ModelTable';
|
||||
|
||||
const ModelProvider = () => {
|
||||
return (
|
||||
<AccountContainer>
|
||||
<Box h={'100%'} py={4} px={6}>
|
||||
<ModelTable />
|
||||
</Box>
|
||||
</AccountContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export async function getServerSideProps(content: any) {
|
||||
return {
|
||||
props: {
|
||||
...(await serviceSideProps(content, ['account']))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default ModelProvider;
|
@@ -28,7 +28,7 @@ const Individuation = () => {
|
||||
});
|
||||
reset(data);
|
||||
toast({
|
||||
title: t('account_individuation:update_data_success'),
|
||||
title: t('account_setting:update_data_success'),
|
||||
status: 'success'
|
||||
});
|
||||
},
|
||||
@@ -39,19 +39,19 @@ const Individuation = () => {
|
||||
<AccountContainer>
|
||||
<Box py={[3, '28px']} px={['5vw', '64px']}>
|
||||
<Flex alignItems={'center'} fontSize={'lg'} h={'30px'}>
|
||||
<MyIcon mr={2} name={'support/user/individuation'} w={'20px'} />
|
||||
{t('account_individuation:personalization')}
|
||||
<MyIcon mr={2} name={'common/settingLight'} w={'20px'} />
|
||||
{t('common:common.Setting')}
|
||||
</Flex>
|
||||
|
||||
<Card mt={6} px={[3, 10]} py={[3, 7]} fontSize={'sm'}>
|
||||
<Flex alignItems={'center'} w={['85%', '350px']}>
|
||||
<Box flex={'0 0 80px'}>{t('account_individuation:language')}: </Box>
|
||||
<Box flex={'0 0 80px'}>{t('account_setting:language')}: </Box>
|
||||
<Box flex={'1 0 0'}>
|
||||
<I18nLngSelector />
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex mt={6} alignItems={'center'} w={['85%', '350px']}>
|
||||
<Box flex={'0 0 80px'}>{t('account_individuation:timezone')}: </Box>
|
||||
<Box flex={'0 0 80px'}>{t('account_setting:timezone')}: </Box>
|
||||
<TimezoneSelect
|
||||
value={userInfo?.timezone}
|
||||
onChange={(e) => {
|
||||
@@ -69,7 +69,7 @@ const Individuation = () => {
|
||||
export async function getServerSideProps(content: any) {
|
||||
return {
|
||||
props: {
|
||||
...(await serviceSideProps(content, ['account', 'account_individuation']))
|
||||
...(await serviceSideProps(content, ['account', 'account_setting']))
|
||||
}
|
||||
};
|
||||
}
|
@@ -1,33 +1,38 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import type { InitDateResponse } from '@/global/common/api/systemRes';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import type { NextApiResponse } from 'next';
|
||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||
import { NextAPI } from '@/service/middleware/entry';
|
||||
|
||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
await connectToDatabase();
|
||||
async function handler(req: ApiRequestProps<{}, { bufferId?: string }>, res: NextApiResponse) {
|
||||
const { bufferId } = req.query;
|
||||
|
||||
jsonRes<InitDateResponse>(res, {
|
||||
data: {
|
||||
feConfigs: global.feConfigs,
|
||||
subPlans: global.subPlans,
|
||||
llmModels: global.llmModels.map((model) => ({
|
||||
...model,
|
||||
customCQPrompt: '',
|
||||
customExtractPrompt: '',
|
||||
defaultSystemChatPrompt: ''
|
||||
})),
|
||||
vectorModels: global.vectorModels,
|
||||
reRankModels:
|
||||
global.reRankModels?.map((item) => ({
|
||||
...item,
|
||||
requestUrl: '',
|
||||
requestAuth: ''
|
||||
})) || [],
|
||||
whisperModel: global.whisperModel,
|
||||
audioSpeechModels: global.audioSpeechModels,
|
||||
systemVersion: global.systemVersion || '0.0.0'
|
||||
}
|
||||
});
|
||||
// If bufferId is the same as the current bufferId, return directly
|
||||
if (bufferId && global.systemInitBufferId && global.systemInitBufferId === bufferId) {
|
||||
return {
|
||||
bufferId: global.systemInitBufferId
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
bufferId: global.systemInitBufferId,
|
||||
feConfigs: global.feConfigs,
|
||||
subPlans: global.subPlans,
|
||||
llmModels: global.llmModels.map((model) => ({
|
||||
...model,
|
||||
customCQPrompt: '',
|
||||
customExtractPrompt: '',
|
||||
defaultSystemChatPrompt: ''
|
||||
})),
|
||||
vectorModels: global.vectorModels,
|
||||
reRankModels:
|
||||
global.reRankModels?.map((item) => ({
|
||||
...item,
|
||||
requestUrl: '',
|
||||
requestAuth: ''
|
||||
})) || [],
|
||||
whisperModel: global.whisperModel,
|
||||
audioSpeechModels: global.audioSpeechModels,
|
||||
systemVersion: global.systemVersion || '0.0.0'
|
||||
};
|
||||
}
|
||||
|
||||
export default handler;
|
||||
export default NextAPI(handler);
|
||||
|
@@ -109,7 +109,7 @@ const ExtraPlan = () => {
|
||||
|
||||
return (
|
||||
<Flex
|
||||
mt={['40px', '200px']}
|
||||
mt={['40px', '100px']}
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
position={'relative'}
|
||||
|
@@ -41,7 +41,7 @@ const FAQ = () => {
|
||||
|
||||
return (
|
||||
<Flex
|
||||
mt={['40px', '200px']}
|
||||
mt={['40px', '100px']}
|
||||
pb={'10vh'}
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
|
@@ -1,15 +1,15 @@
|
||||
import React from 'react';
|
||||
import { Box, Flex, Grid, Link, ModalBody } from '@chakra-ui/react';
|
||||
import { Box, Flex, Grid, Link } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||
import ModelTable from '@/components/core/ai/ModelTable';
|
||||
|
||||
const Points = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Flex
|
||||
mt={['40px', '200px']}
|
||||
mt={['40px', '100px']}
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
position={'relative'}
|
||||
@@ -17,10 +17,12 @@ const Points = () => {
|
||||
<Box id="point-card" fontWeight={'bold'} fontSize={['24px', '36px']} color={'myGray.900'}>
|
||||
{t('common:support.wallet.subscription.Ai points')}
|
||||
</Box>
|
||||
<Link href="https://tiktokenizer.vercel.app/" target="_blank" mb={['30px', 14]}>
|
||||
<Link href="https://tiktokenizer.vercel.app/" target="_blank" mb={['30px', 10]}>
|
||||
{t('common:support.wallet.subscription.token_compute')}
|
||||
</Link>
|
||||
<AiPointsTable />
|
||||
<Box p={5} w={'100%'} h={'666px'} bg={'white'} borderRadius={'lg'} boxShadow={'md'}>
|
||||
<ModelTable />
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -150,24 +152,3 @@ export const AiPointsTable = () => {
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export const AiPointsModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
isCentered
|
||||
iconSrc="/imgs/modal/bill.svg"
|
||||
title={t('common:support.wallet.subscription.Ai points')}
|
||||
isOpen
|
||||
onClose={onClose}
|
||||
w={'100%'}
|
||||
maxW={'90vw'}
|
||||
maxH={'90vh'}
|
||||
>
|
||||
<ModalBody>
|
||||
<AiPointsTable />
|
||||
</ModalBody>
|
||||
</MyModal>
|
||||
);
|
||||
};
|
||||
|
@@ -52,8 +52,7 @@ export async function getInitConfig() {
|
||||
getSystemVersion(),
|
||||
|
||||
// abandon
|
||||
getSystemPlugin(),
|
||||
getSystemPluginV1()
|
||||
getSystemPlugin()
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -79,7 +78,7 @@ const defaultFeConfigs: FastGPTFeConfigsType = {
|
||||
|
||||
export async function initSystemConfig() {
|
||||
// load config
|
||||
const [dbConfig, fileConfig] = await Promise.all([
|
||||
const [{ config: dbConfig, configId }, fileConfig] = await Promise.all([
|
||||
getFastGPTConfigFromDB(),
|
||||
readConfigData('config.json')
|
||||
]);
|
||||
@@ -106,7 +105,9 @@ export async function initSystemConfig() {
|
||||
};
|
||||
|
||||
// set config
|
||||
global.systemInitBufferId = configId;
|
||||
initFastGPTConfig(config);
|
||||
|
||||
console.log({
|
||||
feConfigs: global.feConfigs,
|
||||
systemEnv: global.systemEnv,
|
||||
@@ -162,32 +163,6 @@ function getSystemPlugin() {
|
||||
|
||||
global.communityPlugins = fileTemplates;
|
||||
}
|
||||
function getSystemPluginV1() {
|
||||
if (global.communityPluginsV1 && global.communityPluginsV1.length > 0) return;
|
||||
|
||||
const basePath =
|
||||
process.env.NODE_ENV === 'development'
|
||||
? 'data/pluginTemplates/v1'
|
||||
: '/app/data/pluginTemplates/v1';
|
||||
// read data/pluginTemplates directory, get all json file
|
||||
const files = readdirSync(basePath);
|
||||
// filter json file
|
||||
const filterFiles = files.filter((item) => item.endsWith('.json'));
|
||||
|
||||
// read json file
|
||||
const fileTemplates: (PluginTemplateType & { weight: number })[] = filterFiles.map((filename) => {
|
||||
const content = readFileSync(`${basePath}/${filename}`, 'utf-8');
|
||||
return {
|
||||
...JSON.parse(content),
|
||||
id: `${PluginSourceEnum.community}-${filename.replace('.json', '')}`,
|
||||
source: PluginSourceEnum.community
|
||||
};
|
||||
});
|
||||
|
||||
fileTemplates.sort((a, b) => b.weight - a.weight);
|
||||
|
||||
global.communityPluginsV1 = fileTemplates;
|
||||
}
|
||||
|
||||
export async function initSystemPlugins() {
|
||||
try {
|
||||
|
2
projects/app/src/types/index.d.ts
vendored
2
projects/app/src/types/index.d.ts
vendored
@@ -5,7 +5,7 @@ import {
|
||||
LLMModelItemType,
|
||||
ReRankModelItemType,
|
||||
VectorModelItemType,
|
||||
WhisperModelType
|
||||
STTModelType
|
||||
} from '@fastgpt/global/core/ai/model.d';
|
||||
import { TrackEventName } from '@/web/common/system/constants';
|
||||
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
|
||||
|
@@ -1,4 +1,7 @@
|
||||
import type { InitDateResponse } from '@/global/common/api/systemRes';
|
||||
import { GET } from '@/web/common/api/request';
|
||||
|
||||
export const getSystemInitData = () => GET<InitDateResponse>('/common/system/getInitData');
|
||||
export const getSystemInitData = (bufferId?: string) =>
|
||||
GET<InitDateResponse>('/common/system/getInitData', {
|
||||
bufferId
|
||||
});
|
||||
|
@@ -10,7 +10,7 @@ export const clientInitData = async (
|
||||
feConfigs: FastGPTFeConfigsType;
|
||||
}> => {
|
||||
try {
|
||||
const res = await getSystemInitData();
|
||||
const res = await getSystemInitData(useSystemStore.getState().initDataBufferId);
|
||||
useSystemStore.getState().initStaticData(res);
|
||||
|
||||
return {
|
||||
|
@@ -8,11 +8,12 @@ import type {
|
||||
LLMModelItemType,
|
||||
ReRankModelItemType,
|
||||
VectorModelItemType,
|
||||
WhisperModelType
|
||||
STTModelType
|
||||
} from '@fastgpt/global/core/ai/model.d';
|
||||
import { InitDateResponse } from '@/global/common/api/systemRes';
|
||||
import { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types';
|
||||
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
|
||||
import { defaultWhisperModel } from '@fastgpt/global/core/ai/model';
|
||||
|
||||
type LoginStoreType = { provider: `${OAuthEnum}`; lastRoute: string; state: string };
|
||||
|
||||
@@ -35,6 +36,7 @@ type State = {
|
||||
isNotSufficientModal: boolean;
|
||||
setIsNotSufficientModal: (val: boolean) => void;
|
||||
|
||||
initDataBufferId?: string;
|
||||
feConfigs: FastGPTFeConfigsType;
|
||||
subPlans?: SubPlanType;
|
||||
systemVersion: string;
|
||||
@@ -43,7 +45,7 @@ type State = {
|
||||
vectorModelList: VectorModelItemType[];
|
||||
audioSpeechModelList: AudioSpeechModelType[];
|
||||
reRankModelList: ReRankModelItemType[];
|
||||
whisperModel?: WhisperModelType;
|
||||
whisperModel: STTModelType;
|
||||
initStaticData: (e: InitDateResponse) => void;
|
||||
appType?: string;
|
||||
setAppType: (e?: string) => void;
|
||||
@@ -110,6 +112,7 @@ export const useSystemStore = create<State>()(
|
||||
});
|
||||
},
|
||||
|
||||
initDataBufferId: undefined,
|
||||
feConfigs: {},
|
||||
subPlans: undefined,
|
||||
systemVersion: '0.0.0',
|
||||
@@ -118,26 +121,38 @@ export const useSystemStore = create<State>()(
|
||||
vectorModelList: [],
|
||||
audioSpeechModelList: [],
|
||||
reRankModelList: [],
|
||||
whisperModel: undefined,
|
||||
whisperModel: defaultWhisperModel,
|
||||
initStaticData(res) {
|
||||
set((state) => {
|
||||
state.feConfigs = res.feConfigs || {};
|
||||
state.subPlans = res.subPlans;
|
||||
state.systemVersion = res.systemVersion;
|
||||
state.initDataBufferId = res.bufferId;
|
||||
|
||||
state.feConfigs = res.feConfigs ?? state.feConfigs;
|
||||
state.subPlans = res.subPlans ?? state.subPlans;
|
||||
state.systemVersion = res.systemVersion ?? state.systemVersion;
|
||||
|
||||
state.llmModelList = res.llmModels ?? state.llmModelList;
|
||||
state.datasetModelList = state.llmModelList.filter((item) => item.datasetProcess);
|
||||
state.vectorModelList = res.vectorModels ?? state.vectorModelList;
|
||||
state.audioSpeechModelList = res.audioSpeechModels ?? state.audioSpeechModelList;
|
||||
state.reRankModelList = res.reRankModels ?? state.reRankModelList;
|
||||
state.whisperModel = res.whisperModel;
|
||||
state.whisperModel = res.whisperModel ?? state.whisperModel;
|
||||
});
|
||||
}
|
||||
})),
|
||||
{
|
||||
name: 'globalStore',
|
||||
partialize: (state) => ({
|
||||
loginStore: state.loginStore
|
||||
loginStore: state.loginStore,
|
||||
initDataBufferId: state.initDataBufferId,
|
||||
feConfigs: state.feConfigs,
|
||||
subPlans: state.subPlans,
|
||||
systemVersion: state.systemVersion,
|
||||
llmModelList: state.llmModelList,
|
||||
datasetModelList: state.datasetModelList,
|
||||
vectorModelList: state.vectorModelList,
|
||||
audioSpeechModelList: state.audioSpeechModelList,
|
||||
reRankModelList: state.reRankModelList,
|
||||
whisperModel: state.whisperModel
|
||||
})
|
||||
}
|
||||
)
|
||||
|
@@ -5,6 +5,7 @@ import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import type { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types/index.d';
|
||||
import { useMemoizedFn, useMount } from 'ahooks';
|
||||
import { TrackEventName } from '../common/system/constants';
|
||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||
|
||||
export const useInitApp = () => {
|
||||
const router = useRouter();
|
||||
@@ -41,8 +42,6 @@ export const useInitApp = () => {
|
||||
});
|
||||
|
||||
useMount(() => {
|
||||
initFetch();
|
||||
|
||||
const errorTrack = (event: ErrorEvent) => {
|
||||
window.umami?.track(TrackEventName.windowError, {
|
||||
device: {
|
||||
@@ -62,6 +61,11 @@ export const useInitApp = () => {
|
||||
};
|
||||
});
|
||||
|
||||
useRequest2(initFetch, {
|
||||
manual: false,
|
||||
pollingInterval: 300000
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
hiId && localStorage.setItem('inviterId', hiId);
|
||||
bd_vid && sessionStorage.setItem('bd_vid', bd_vid);
|
||||
|
Reference in New Issue
Block a user