mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-28 00:56:26 +00:00
perf: 懒加载和动态加载优化
This commit is contained in:
@@ -25,10 +25,10 @@ const Auth = ({ children }: { children: JSX.Element }) => {
|
||||
useQuery(
|
||||
[router.pathname, userInfo],
|
||||
() => {
|
||||
setLoading(true);
|
||||
if (unAuthPage[router.pathname] === true || userInfo) {
|
||||
return setLoading(false);
|
||||
} else {
|
||||
setLoading(true);
|
||||
return getTokenLogin();
|
||||
}
|
||||
},
|
||||
|
@@ -43,15 +43,13 @@ const navbarList = [
|
||||
const Layout = ({ children }: { children: JSX.Element }) => {
|
||||
const { isPc } = useScreen();
|
||||
const router = useRouter();
|
||||
const { Loading } = useLoading({
|
||||
defaultLoading: true
|
||||
});
|
||||
const { Loading } = useLoading({ defaultLoading: true });
|
||||
const { loading } = useGlobalStore();
|
||||
|
||||
return (
|
||||
<>
|
||||
{!unShowLayoutRoute[router.pathname] ? (
|
||||
<Box data-test="ss" h={'100%'} backgroundColor={'gray.100'} overflow={'auto'}>
|
||||
<Box h={'100%'} backgroundColor={'gray.100'} overflow={'auto'}>
|
||||
{isPc ? (
|
||||
<>
|
||||
<Box h={'100%'} position={'fixed'} left={0} top={0} w={'80px'}>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useState, memo } from 'react';
|
||||
import { Spinner, Flex } from '@chakra-ui/react';
|
||||
|
||||
export const useLoading = (props?: { defaultLoading: boolean }) => {
|
||||
@@ -31,6 +31,6 @@ export const useLoading = (props?: { defaultLoading: boolean }) => {
|
||||
return {
|
||||
isLoading,
|
||||
setIsLoading,
|
||||
Loading
|
||||
Loading: memo(Loading)
|
||||
};
|
||||
};
|
||||
|
@@ -11,6 +11,6 @@ export function useScreen() {
|
||||
isPc,
|
||||
mediaLgMd: useMemo(() => (isPc ? 'lg' : 'md'), [isPc]),
|
||||
mediaMdSm: useMemo(() => (isPc ? 'md' : 'sm'), [isPc]),
|
||||
media: (pc: number | string, phone: number | string) => (isPc ? pc : phone)
|
||||
media: (pc: any, phone: any) => (isPc ? pc : phone)
|
||||
};
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ export default function App({ Component, pageProps }: AppProps) {
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<Script src="/iconfont.js" strategy="afterInteractive"></Script>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ChakraProvider theme={theme}>
|
||||
<Layout>
|
||||
@@ -45,7 +46,6 @@ export default function App({ Component, pageProps }: AppProps) {
|
||||
</Layout>
|
||||
</ChakraProvider>
|
||||
</QueryClientProvider>
|
||||
<Script src="/iconfont.js"></Script>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@@ -13,10 +13,13 @@ import { Textarea, Box, Flex, Button } from '@chakra-ui/react';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import Icon from '@/components/Icon';
|
||||
import { useScreen } from '@/hooks/useScreen';
|
||||
import Markdown from '@/components/Markdown';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useLoading } from '@/hooks/useLoading';
|
||||
import { OpenAiModelEnum } from '@/constants/model';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
|
||||
const Markdown = dynamic(() => import('@/components/Markdown'));
|
||||
|
||||
const textareaMinH = '22px';
|
||||
|
||||
@@ -34,7 +37,7 @@ const Chat = () => {
|
||||
|
||||
const isChatting = useMemo(() => chatList[chatList.length - 1]?.status === 'loading', [chatList]);
|
||||
const lastWordHuman = useMemo(() => chatList[chatList.length - 1]?.obj === 'Human', [chatList]);
|
||||
const { Loading, setIsLoading } = useLoading({ defaultLoading: true });
|
||||
const { setLoading } = useGlobalStore();
|
||||
|
||||
// 滚动到底部
|
||||
const scrollToBottom = useCallback(() => {
|
||||
@@ -49,32 +52,40 @@ const Chat = () => {
|
||||
}, []);
|
||||
|
||||
// 初始化聊天框
|
||||
useQuery([chatId, windowId], () => (chatId ? getInitChatSiteInfo(chatId, windowId) : null), {
|
||||
cacheTime: 5 * 60 * 1000,
|
||||
onSuccess(res) {
|
||||
if (!res) return;
|
||||
router.replace(`/chat?chatId=${chatId}&windowId=${res.windowId}`);
|
||||
|
||||
setChatSiteData(res.chatSite);
|
||||
setChatList(
|
||||
res.history.map((item) => ({
|
||||
...item,
|
||||
status: 'finish'
|
||||
}))
|
||||
);
|
||||
scrollToBottom();
|
||||
setIsLoading(false);
|
||||
useQuery(
|
||||
[chatId, windowId],
|
||||
() => {
|
||||
if (!chatId) return null;
|
||||
setLoading(true);
|
||||
return getInitChatSiteInfo(chatId, windowId);
|
||||
},
|
||||
onError() {
|
||||
toast({
|
||||
title: '初始化异常,请刷新',
|
||||
status: 'error',
|
||||
isClosable: true,
|
||||
duration: 5000
|
||||
});
|
||||
setIsLoading(false);
|
||||
{
|
||||
cacheTime: 5 * 60 * 1000,
|
||||
onSuccess(res) {
|
||||
if (!res) return;
|
||||
router.replace(`/chat?chatId=${chatId}&windowId=${res.windowId}`);
|
||||
|
||||
setChatSiteData(res.chatSite);
|
||||
setChatList(
|
||||
res.history.map((item) => ({
|
||||
...item,
|
||||
status: 'finish'
|
||||
}))
|
||||
);
|
||||
scrollToBottom();
|
||||
setLoading(false);
|
||||
},
|
||||
onError() {
|
||||
toast({
|
||||
title: '初始化异常,请刷新',
|
||||
status: 'error',
|
||||
isClosable: true,
|
||||
duration: 5000
|
||||
});
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
// gpt3 方法
|
||||
const gpt3ChatPrompt = useCallback(
|
||||
@@ -293,7 +304,7 @@ const Chat = () => {
|
||||
alt="/imgs/modelAvatar.png"
|
||||
width={30}
|
||||
height={30}
|
||||
></Image>
|
||||
/>
|
||||
</Box>
|
||||
<Box flex={'1 0 0'} w={0} overflowX={'auto'}>
|
||||
{item.obj === 'AI' ? (
|
||||
@@ -393,7 +404,6 @@ const Chat = () => {
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Loading />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@@ -1,12 +1,9 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Card, Text, Box, Heading, Flex } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import { Card } from '@chakra-ui/react';
|
||||
import Markdown from '@/components/Markdown';
|
||||
import { introPage } from '@/constants/common';
|
||||
|
||||
const Home = () => {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Card p={5} lineHeight={2}>
|
||||
<Markdown source={introPage} isChatting={false} />
|
||||
|
@@ -1,15 +1,17 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import React, { useState, useCallback, useMemo } from 'react';
|
||||
import styles from './index.module.scss';
|
||||
import { Box, Flex, Image } from '@chakra-ui/react';
|
||||
import { PageTypeEnum } from '@/constants/user';
|
||||
import LoginForm from './components/LoginForm';
|
||||
import RegisterForm from './components/RegisterForm';
|
||||
import ForgetPasswordForm from './components/ForgetPasswordForm';
|
||||
import { useScreen } from '@/hooks/useScreen';
|
||||
import type { ResLogin } from '@/api/response/user';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useUserStore } from '@/store/user';
|
||||
|
||||
import dynamic from 'next/dynamic';
|
||||
const LoginForm = dynamic(() => import('./components/LoginForm'));
|
||||
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
||||
const ForgetPasswordForm = dynamic(() => import('./components/ForgetPasswordForm'));
|
||||
|
||||
const Login = () => {
|
||||
const router = useRouter();
|
||||
const { isPc } = useScreen();
|
||||
@@ -24,20 +26,17 @@ const Login = () => {
|
||||
[router, setUserInfo]
|
||||
);
|
||||
|
||||
const map = {
|
||||
[PageTypeEnum.login]: {
|
||||
Component: <LoginForm setPageType={setPageType} loginSuccess={loginSuccess} />,
|
||||
img: '/icon/loginLeft.svg'
|
||||
},
|
||||
[PageTypeEnum.register]: {
|
||||
Component: <RegisterForm setPageType={setPageType} loginSuccess={loginSuccess} />,
|
||||
img: '/icon/loginLeft.svg'
|
||||
},
|
||||
[PageTypeEnum.forgetPassword]: {
|
||||
Component: <ForgetPasswordForm setPageType={setPageType} loginSuccess={loginSuccess} />,
|
||||
img: '/icon/loginLeft.svg'
|
||||
}
|
||||
};
|
||||
function DynamicComponent({ type }: { type: `${PageTypeEnum}` }) {
|
||||
const TypeMap = {
|
||||
[PageTypeEnum.login]: LoginForm,
|
||||
[PageTypeEnum.register]: RegisterForm,
|
||||
[PageTypeEnum.forgetPassword]: ForgetPasswordForm
|
||||
};
|
||||
|
||||
const Component = TypeMap[type];
|
||||
|
||||
return <Component setPageType={setPageType} loginSuccess={loginSuccess} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box className={styles.loginPage} h={'100%'} p={isPc ? '10vh 10vw' : 0}>
|
||||
@@ -54,7 +53,7 @@ const Login = () => {
|
||||
>
|
||||
{isPc && (
|
||||
<Image
|
||||
src={map[pageType].img}
|
||||
src={'/icon/loginLeft.svg'}
|
||||
order={pageType === PageTypeEnum.login ? 0 : 2}
|
||||
flex={'1 0 0'}
|
||||
w="0"
|
||||
@@ -76,7 +75,7 @@ const Login = () => {
|
||||
px={10}
|
||||
borderRadius={isPc ? 'md' : 'none'}
|
||||
>
|
||||
{map[pageType].Component}
|
||||
<DynamicComponent type={pageType} />
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
@@ -25,11 +25,9 @@ interface CreateFormType {
|
||||
}
|
||||
|
||||
const CreateModel = ({
|
||||
isOpen,
|
||||
setCreateModelOpen,
|
||||
onSuccess
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
setCreateModelOpen: Dispatch<boolean>;
|
||||
onSuccess: Dispatch<ModelType>;
|
||||
}) => {
|
||||
@@ -72,7 +70,7 @@ const CreateModel = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal isOpen={isOpen} onClose={() => setCreateModelOpen(false)}>
|
||||
<Modal isOpen={true} onClose={() => setCreateModelOpen(false)}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>创建模型</ModalHeader>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { Grid, Box, Card, Flex, Button, FormControl, Input, Textarea } from '@chakra-ui/react';
|
||||
import type { ModelType } from '@/types/model';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -7,17 +7,17 @@ import { putModelById } from '@/api/model';
|
||||
import { useScreen } from '@/hooks/useScreen';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
|
||||
const ModelEditForm = ({ model }: { model: ModelType }) => {
|
||||
const ModelEditForm = ({ model }: { model?: ModelType }) => {
|
||||
const isInit = useRef(false);
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
reset,
|
||||
formState: { errors }
|
||||
} = useForm<ModelType>({
|
||||
defaultValues: model
|
||||
});
|
||||
} = useForm<ModelType>();
|
||||
const { setLoading } = useGlobalStore();
|
||||
const { toast } = useToast();
|
||||
const { isPc } = useScreen();
|
||||
const { media } = useScreen();
|
||||
|
||||
const onclickSave = useCallback(
|
||||
async (data: ModelType) => {
|
||||
@@ -61,8 +61,16 @@ const ModelEditForm = ({ model }: { model: ModelType }) => {
|
||||
});
|
||||
}, [errors, toast]);
|
||||
|
||||
/* model 只会改变一次 */
|
||||
useEffect(() => {
|
||||
if (model && !isInit.current) {
|
||||
reset(model);
|
||||
isInit.current = true;
|
||||
}
|
||||
}, [model, reset]);
|
||||
|
||||
return (
|
||||
<Grid gridTemplateColumns={isPc ? '1fr 1fr' : '1fr'} gridGap={5}>
|
||||
<Grid gridTemplateColumns={media('1fr 1fr', '1fr')} gridGap={5}>
|
||||
<Card p={4}>
|
||||
<Flex justifyContent={'space-between'} alignItems={'center'}>
|
||||
<Box fontWeight={'bold'} fontSize={'lg'}>
|
||||
@@ -83,7 +91,7 @@ const ModelEditForm = ({ model }: { model: ModelType }) => {
|
||||
<FormControl mt={5}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'}>对话模型:</Box>
|
||||
<Box>{model.service.modelName}</Box>
|
||||
<Box>{model?.service.modelName}</Box>
|
||||
</Flex>
|
||||
</FormControl>
|
||||
<FormControl mt={5}>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useCallback, useState } from 'react';
|
||||
import { Box, Card, TableContainer, Table, Thead, Tbody, Tr, Th, Td } from '@chakra-ui/react';
|
||||
import { Box, TableContainer, Table, Thead, Tbody, Tr, Th, Td } from '@chakra-ui/react';
|
||||
import { ModelType } from '@/types/model';
|
||||
import { getModelTrainings } from '@/api/model';
|
||||
import type { TrainingItemType } from '@/types/training';
|
||||
@@ -38,7 +38,7 @@ const Training = ({ model }: { model: ModelType }) => {
|
||||
}, [loadTrainingRecords, model]);
|
||||
|
||||
return (
|
||||
<Card p={4} h={'100%'}>
|
||||
<>
|
||||
<Box fontWeight={'bold'} fontSize={'lg'}>
|
||||
训练记录: {model.trainingTimes}次
|
||||
</Box>
|
||||
@@ -63,7 +63,7 @@ const Training = ({ model }: { model: ModelType }) => {
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -11,12 +11,14 @@ import { useGlobalStore } from '@/store/global';
|
||||
import { useScreen } from '@/hooks/useScreen';
|
||||
import ModelEditForm from './components/ModelEditForm';
|
||||
import Icon from '@/components/Icon';
|
||||
import Training from './components/Training';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const Training = dynamic(() => import('./components/Training'));
|
||||
|
||||
const ModelDetail = () => {
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const { isPc } = useScreen();
|
||||
const { isPc, media } = useScreen();
|
||||
const { setLoading } = useGlobalStore();
|
||||
const { openConfirm, ConfirmChild } = useConfirm({
|
||||
content: '确认删除该模型?'
|
||||
@@ -128,114 +130,114 @@ const ModelDetail = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{!!model && (
|
||||
<>
|
||||
{/* 头部 */}
|
||||
<Card px={6} py={3}>
|
||||
{isPc ? (
|
||||
<Flex alignItems={'center'}>
|
||||
<Box fontSize={'xl'} fontWeight={'bold'}>
|
||||
{model.name} 配置
|
||||
</Box>
|
||||
<Tag
|
||||
ml={2}
|
||||
variant="solid"
|
||||
colorScheme={formatModelStatus[model.status].colorTheme}
|
||||
cursor={model.status === ModelStatusEnum.training ? 'pointer' : 'default'}
|
||||
onClick={handleClickUpdateStatus}
|
||||
>
|
||||
{/* 头部 */}
|
||||
<Card px={6} py={3}>
|
||||
{isPc ? (
|
||||
<Flex alignItems={'center'}>
|
||||
<Box fontSize={'xl'} fontWeight={'bold'}>
|
||||
{model?.name || '模型'} 配置
|
||||
</Box>
|
||||
{!!model && (
|
||||
<Tag
|
||||
ml={2}
|
||||
variant="solid"
|
||||
colorScheme={formatModelStatus[model.status].colorTheme}
|
||||
cursor={model.status === ModelStatusEnum.training ? 'pointer' : 'default'}
|
||||
onClick={handleClickUpdateStatus}
|
||||
>
|
||||
{formatModelStatus[model.status].text}
|
||||
</Tag>
|
||||
)}
|
||||
<Box flex={1} />
|
||||
<Button variant={'outline'} onClick={handlePreviewChat}>
|
||||
对话体验
|
||||
</Button>
|
||||
</Flex>
|
||||
) : (
|
||||
<>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box as={'h3'} fontSize={'xl'} fontWeight={'bold'} flex={1}>
|
||||
{model?.name || '模型'} 配置
|
||||
</Box>
|
||||
{!!model && (
|
||||
<Tag ml={2} colorScheme={formatModelStatus[model.status].colorTheme}>
|
||||
{formatModelStatus[model.status].text}
|
||||
</Tag>
|
||||
<Box flex={1} />
|
||||
<Button variant={'outline'} onClick={handlePreviewChat}>
|
||||
对话体验
|
||||
</Button>
|
||||
</Flex>
|
||||
) : (
|
||||
<>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box as={'h3'} fontSize={'xl'} fontWeight={'bold'} flex={1}>
|
||||
{model.name} 配置
|
||||
</Box>
|
||||
<Tag ml={2} colorScheme={formatModelStatus[model.status].colorTheme}>
|
||||
{formatModelStatus[model.status].text}
|
||||
</Tag>
|
||||
</Flex>
|
||||
<Box mt={4} textAlign={'right'}>
|
||||
<Button variant={'outline'} onClick={handlePreviewChat}>
|
||||
对话体验
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
{/* 基本信息编辑 */}
|
||||
<Box mt={5}>
|
||||
<ModelEditForm model={model} />
|
||||
)}
|
||||
</Flex>
|
||||
<Box mt={4} textAlign={'right'}>
|
||||
<Button variant={'outline'} onClick={handlePreviewChat}>
|
||||
对话体验
|
||||
</Button>
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
{/* 基本信息编辑 */}
|
||||
<Box mt={5}>
|
||||
<ModelEditForm model={model} />
|
||||
</Box>
|
||||
{/* 其他配置 */}
|
||||
<Grid mt={5} gridTemplateColumns={media('1fr 1fr', '1fr')} gridGap={5}>
|
||||
<Card p={4}>{!!model && <Training model={model} />}</Card>
|
||||
<Card p={4}>
|
||||
<Box fontWeight={'bold'} fontSize={'lg'}>
|
||||
神奇操作
|
||||
</Box>
|
||||
{/* 其他配置 */}
|
||||
<Grid mt={5} gridTemplateColumns={isPc ? '1fr 1fr' : '1fr'} gridGap={5}>
|
||||
<Training model={model} />
|
||||
<Card h={'100%'} p={4}>
|
||||
<Box fontWeight={'bold'} fontSize={'lg'}>
|
||||
神奇操作
|
||||
</Box>
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'}>模型微调:</Box>
|
||||
<Button
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
SelectFileDom.current?.click();
|
||||
}}
|
||||
title={!canTrain ? '' : '模型不支持微调'}
|
||||
isDisabled={!canTrain}
|
||||
>
|
||||
上传微调数据集
|
||||
</Button>
|
||||
<Flex
|
||||
as={'a'}
|
||||
href="/TrainingTemplate.jsonl"
|
||||
download
|
||||
ml={5}
|
||||
cursor={'pointer'}
|
||||
alignItems={'center'}
|
||||
color={'blue.500'}
|
||||
>
|
||||
<Icon name={'icon-yunxiazai'} color={'#3182ce'} />
|
||||
下载模板
|
||||
</Flex>
|
||||
</Flex>
|
||||
{/* 提示 */}
|
||||
<Box mt={3} py={3} color={'blackAlpha.500'}>
|
||||
<Box as={'li'} lineHeight={1.9}>
|
||||
每行包括一个 prompt 和一个 completion
|
||||
</Box>
|
||||
<Box as={'li'} lineHeight={1.9}>
|
||||
prompt 必须以 \n\n###\n\n 结尾,且尽量保障每个 prompt
|
||||
内容不都是同一个标点结尾,可以加一个空格打断相同性,
|
||||
</Box>
|
||||
<Box as={'li'} lineHeight={1.9}>
|
||||
completion 开头必须有一个空格,末尾必须以 ### 结尾,同样的不要都是同一个标点结尾。
|
||||
</Box>
|
||||
</Box>
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'}>删除模型:</Box>
|
||||
<Button
|
||||
colorScheme={'red'}
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
openConfirm(() => {
|
||||
handleDelModel();
|
||||
});
|
||||
}}
|
||||
>
|
||||
删除模型
|
||||
</Button>
|
||||
</Flex>
|
||||
</Card>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'}>模型微调:</Box>
|
||||
<Button
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
SelectFileDom.current?.click();
|
||||
}}
|
||||
title={!canTrain ? '' : '模型不支持微调'}
|
||||
isDisabled={!canTrain}
|
||||
>
|
||||
上传微调数据集
|
||||
</Button>
|
||||
<Flex
|
||||
as={'a'}
|
||||
href="/TrainingTemplate.jsonl"
|
||||
download
|
||||
ml={5}
|
||||
cursor={'pointer'}
|
||||
alignItems={'center'}
|
||||
color={'blue.500'}
|
||||
>
|
||||
<Icon name={'icon-yunxiazai'} color={'#3182ce'} />
|
||||
下载模板
|
||||
</Flex>
|
||||
</Flex>
|
||||
{/* 提示 */}
|
||||
<Box mt={3} py={3} color={'blackAlpha.500'}>
|
||||
<Box as={'li'} lineHeight={1.9}>
|
||||
每行包括一个 prompt 和一个 completion
|
||||
</Box>
|
||||
<Box as={'li'} lineHeight={1.9}>
|
||||
prompt 必须以 \n\n###\n\n 结尾,且尽量保障每个 prompt
|
||||
内容不都是同一个标点结尾,可以加一个空格打断相同性,
|
||||
</Box>
|
||||
<Box as={'li'} lineHeight={1.9}>
|
||||
completion 开头必须有一个空格,末尾必须以 ### 结尾,同样的不要都是同一个标点结尾。
|
||||
</Box>
|
||||
</Box>
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 80px'}>删除模型:</Box>
|
||||
<Button
|
||||
colorScheme={'red'}
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
openConfirm(() => {
|
||||
handleDelModel();
|
||||
});
|
||||
}}
|
||||
>
|
||||
删除模型
|
||||
</Button>
|
||||
</Flex>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Box position={'absolute'} w={0} h={0} overflow={'hidden'}>
|
||||
<input ref={SelectFileDom} type="file" accept=".jsonl" onChange={startTraining} />
|
||||
</Box>
|
||||
|
@@ -1,15 +1,17 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { Box, Button, Flex, Card } from '@chakra-ui/react';
|
||||
import { getMyModels } from '@/api/model';
|
||||
import { getChatSiteId } from '@/api/chat';
|
||||
import { ModelType } from '@/types/model';
|
||||
import CreateModel from './components/CreateModel';
|
||||
import { useRouter } from 'next/router';
|
||||
import ModelTable from './components/ModelTable';
|
||||
import ModelPhoneList from './components/ModelPhoneList';
|
||||
import { useScreen } from '@/hooks/useScreen';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useLoading } from '@/hooks/useLoading';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
const CreateModel = dynamic(() => import('./components/CreateModel'));
|
||||
|
||||
const ModelList = () => {
|
||||
const { isPc } = useScreen();
|
||||
@@ -72,11 +74,10 @@ const ModelList = () => {
|
||||
)}
|
||||
</Box>
|
||||
{/* 创建弹窗 */}
|
||||
<CreateModel
|
||||
isOpen={openCreateModel}
|
||||
setCreateModelOpen={setOpenCreateModel}
|
||||
onSuccess={createModelSuccess}
|
||||
/>
|
||||
{openCreateModel && (
|
||||
<CreateModel setCreateModelOpen={setOpenCreateModel} onSuccess={createModelSuccess} />
|
||||
)}
|
||||
|
||||
<Loading loading={isLoading} />
|
||||
</Box>
|
||||
);
|
||||
|
Reference in New Issue
Block a user