mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-29 09:44:47 +00:00
add app
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { GET, POST, DELETE, PUT } from './request';
|
||||
import type { AppSchema } from '@/types/mongoSchema';
|
||||
import type { AppUpdateParams } from '@/types/app';
|
||||
import type { AppModuleItemType, AppUpdateParams } from '@/types/app';
|
||||
import { RequestPaging } from '../types/index';
|
||||
import type { AppListResponse } from './response/app';
|
||||
import type { Props as CreateAppProps } from '@/pages/api/app/create';
|
||||
|
||||
/**
|
||||
* 获取模型列表
|
||||
@@ -12,7 +13,7 @@ export const getMyModels = () => GET<AppListResponse>('/app/list');
|
||||
/**
|
||||
* 创建一个模型
|
||||
*/
|
||||
export const postCreateModel = (data: { name: string }) => POST<string>('/app/create', data);
|
||||
export const postCreateApp = (data: CreateAppProps) => POST<string>('/app/create', data);
|
||||
|
||||
/**
|
||||
* 根据 ID 删除模型
|
||||
|
@@ -20,8 +20,8 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
|
||||
{
|
||||
label: '应用',
|
||||
icon: 'tabbarModel',
|
||||
link: `/model`,
|
||||
activeLink: ['/model'],
|
||||
link: `/app/list`,
|
||||
activeLink: ['/app/list'],
|
||||
unread: 0
|
||||
},
|
||||
{
|
||||
|
22
client/src/components/PageContainer/index.tsx
Normal file
22
client/src/components/PageContainer/index.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Box, useTheme, type BoxProps } from '@chakra-ui/react';
|
||||
|
||||
const PageContainer = ({ children, ...props }: BoxProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Box bg={'myGray.100'} h={'100%'} p={[0, 5]} {...props}>
|
||||
<Box
|
||||
flex={1}
|
||||
h={'100%'}
|
||||
bg={'white'}
|
||||
borderRadius={['', '2xl']}
|
||||
border={['', theme.borders.lg]}
|
||||
overflowY={'auto'}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageContainer;
|
@@ -42,20 +42,19 @@ const SlideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) =
|
||||
px={3}
|
||||
mb={2}
|
||||
alignItems={'center'}
|
||||
_hover={{
|
||||
bg: 'myWhite.600'
|
||||
}}
|
||||
{...(activeId === item.id
|
||||
? {
|
||||
// backgroundImage: 'linear-gradient(to right, #85b1ff 0%, #EBF7FD 100%)',
|
||||
bg: ' myBlue.300',
|
||||
bg: ' myBlue.300 !important',
|
||||
fontWeight: 'bold',
|
||||
color: 'myBlue.700',
|
||||
color: 'myBlue.700 ',
|
||||
cursor: 'default'
|
||||
}
|
||||
: {
|
||||
cursor: 'pointer'
|
||||
})}
|
||||
_hover={{
|
||||
bg: 'myWhite.600'
|
||||
}}
|
||||
onClick={() => {
|
||||
if (activeId === item.id) return;
|
||||
onChange(item.id);
|
||||
|
@@ -4,7 +4,7 @@ import { useRouter } from 'next/router';
|
||||
const NonePage = () => {
|
||||
const router = useRouter();
|
||||
useEffect(() => {
|
||||
router.push('/model');
|
||||
router.push('/app/list');
|
||||
}, [router]);
|
||||
|
||||
return <div></div>;
|
||||
|
@@ -50,10 +50,10 @@ function App({ Component, pageProps }: AppProps) {
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<Script src="/js/particles.js"></Script>
|
||||
<Script src="/js/qrcode.min.js" strategy="afterInteractive"></Script>
|
||||
<Script src="/js/pdf.js" strategy="afterInteractive"></Script>
|
||||
<Script src="/js/html2pdf.bundle.min.js" strategy="afterInteractive"></Script>
|
||||
{baiduTongji && <Script src="/js/baidutongji.js" strategy="afterInteractive"></Script>}
|
||||
<Script src="/js/qrcode.min.js" strategy="lazyOnload"></Script>
|
||||
<Script src="/js/pdf.js" strategy="lazyOnload"></Script>
|
||||
<Script src="/js/html2pdf.bundle.min.js" strategy="lazyOnload"></Script>
|
||||
{baiduTongji && <Script src="/js/baidutongji.js" strategy="lazyOnload"></Script>}
|
||||
{googleVerKey && (
|
||||
<>
|
||||
<Script
|
||||
|
@@ -4,14 +4,19 @@ import { jsonRes } from '@/service/response';
|
||||
import { connectToDatabase } from '@/service/mongo';
|
||||
import { authUser } from '@/service/utils/auth';
|
||||
import { App } from '@/service/models/app';
|
||||
import { AppModuleItemType } from '@/types/app';
|
||||
|
||||
export type Props = {
|
||||
name: string;
|
||||
avatar?: string;
|
||||
modules: AppModuleItemType[];
|
||||
};
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
try {
|
||||
const { name } = req.body as {
|
||||
name: string;
|
||||
};
|
||||
const { name, avatar, modules } = req.body as Props;
|
||||
|
||||
if (!name) {
|
||||
if (!name || !Array.isArray(modules)) {
|
||||
throw new Error('缺少参数');
|
||||
}
|
||||
|
||||
@@ -30,8 +35,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
|
||||
// 创建模型
|
||||
const response = await App.create({
|
||||
avatar,
|
||||
name,
|
||||
userId
|
||||
userId,
|
||||
modules
|
||||
});
|
||||
|
||||
jsonRes(res, {
|
||||
|
@@ -20,8 +20,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const { Loading, setIsLoading } = useLoading();
|
||||
const { userInfo, appDetail, myApps, loadAppDetail, refreshModel, setLastModelId } =
|
||||
useUserStore();
|
||||
const { userInfo, appDetail, myApps, loadAppDetail, setLastModelId } = useUserStore();
|
||||
const { File, onOpen: onOpenSelectFile } = useSelectFile({
|
||||
fileType: '.jpg,.png',
|
||||
multiple: false
|
||||
@@ -61,8 +60,6 @@ const Settings = ({ modelId }: { modelId: string }) => {
|
||||
chat: data.chat,
|
||||
share: data.share
|
||||
});
|
||||
|
||||
refreshModel.updateModelDetail(data);
|
||||
} catch (err: any) {
|
||||
toast({
|
||||
title: err?.message || '更新失败',
|
||||
@@ -71,7 +68,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
|
||||
}
|
||||
setBtnLoading(false);
|
||||
},
|
||||
[refreshModel, toast]
|
||||
[toast]
|
||||
);
|
||||
// 提交保存表单失败
|
||||
const saveSubmitError = useCallback(() => {
|
||||
@@ -106,8 +103,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
|
||||
title: '删除成功',
|
||||
status: 'success'
|
||||
});
|
||||
refreshModel.removeModelDetail(appDetail._id);
|
||||
router.replace(`/model?modelId=${myApps[1]?._id}`);
|
||||
router.replace(`/app/list`);
|
||||
} catch (err: any) {
|
||||
toast({
|
||||
title: err?.message || '删除失败',
|
||||
@@ -115,7 +111,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
|
||||
});
|
||||
}
|
||||
setIsLoading(false);
|
||||
}, [appDetail, setIsLoading, toast, refreshModel, router, myApps]);
|
||||
}, [appDetail, setIsLoading, toast, router]);
|
||||
|
||||
const onSelectFile = useCallback(
|
||||
async (e: File[]) => {
|
||||
@@ -152,7 +148,6 @@ const Settings = ({ modelId }: { modelId: string }) => {
|
||||
status: 'error'
|
||||
});
|
||||
setLastModelId('');
|
||||
refreshModel.freshMyModels();
|
||||
router.replace('/model');
|
||||
}
|
||||
});
|
||||
|
@@ -9,6 +9,7 @@ import SlideTabs from '@/components/SlideTabs';
|
||||
import Settings from './components/Settings';
|
||||
import { defaultApp } from '@/constants/model';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import PageContainer from '@/components/PageContainer';
|
||||
|
||||
const EditApp = dynamic(() => import('./components/edit'), {
|
||||
ssr: false
|
||||
@@ -78,14 +79,8 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
}, [appId, loadAppDetail]);
|
||||
|
||||
return (
|
||||
<Flex flexDirection={'column'} bg={'myGray.100'} h={'100%'} p={[0, 5]}>
|
||||
<Box
|
||||
display={['block', 'flex']}
|
||||
flex={1}
|
||||
bg={'white'}
|
||||
borderRadius={['', '2xl']}
|
||||
border={['', theme.borders.lg]}
|
||||
>
|
||||
<PageContainer>
|
||||
<Box display={['block', 'flex']} h={'100%'}>
|
||||
{/* pc tab */}
|
||||
<Box display={['none', 'block']} p={4} w={'200px'} borderRight={theme.borders.base}>
|
||||
<Flex mb={4}>
|
||||
@@ -141,7 +136,7 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||
{currentTab === TabEnum.share && <Share modelId={appId} />}
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
217
client/src/pages/app/list/component/CreateModal.tsx
Normal file
217
client/src/pages/app/list/component/CreateModal.tsx
Normal file
@@ -0,0 +1,217 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
Button,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalFooter,
|
||||
ModalBody,
|
||||
Input,
|
||||
Grid,
|
||||
useTheme,
|
||||
Card
|
||||
} from '@chakra-ui/react';
|
||||
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { compressImg } from '@/utils/file';
|
||||
import { getErrText } from '@/utils/tools';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import { postCreateApp } from '@/api/app';
|
||||
import { useRouter } from 'next/router';
|
||||
import { chatAppDemo } from '@/constants/app';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import MyIcon from '@/components/Icon';
|
||||
|
||||
type FormType = {
|
||||
avatar: string;
|
||||
name: string;
|
||||
templateId: number;
|
||||
};
|
||||
|
||||
const templates = [
|
||||
{
|
||||
id: 0,
|
||||
icon: 'settings',
|
||||
name: '简单的对话',
|
||||
intro: '一个极其简单的 AI 对话应用',
|
||||
modules: chatAppDemo.modules
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
icon: 'settings',
|
||||
name: '基础知识库',
|
||||
intro: '每次提问时进行一次知识库搜索,将搜索结果注入 LLM 模型进行参考回答',
|
||||
modules: chatAppDemo.modules
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
icon: 'settings',
|
||||
name: '问答前引导',
|
||||
intro: '可以在每次对话开始前提示用户填写一些内容,作为本次对话的永久内容',
|
||||
modules: chatAppDemo.modules
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: 'settings',
|
||||
name: '意图识别 + 知识库',
|
||||
intro: '先对用户的问题进行分类,再根据不同类型问题,执行不同的操作',
|
||||
modules: chatAppDemo.modules
|
||||
}
|
||||
];
|
||||
|
||||
const CreateModal = ({ onClose, onSuccess }: { onClose: () => void; onSuccess: () => void }) => {
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [creating, setCreating] = useState(false);
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const theme = useTheme();
|
||||
const { register, setValue, getValues, handleSubmit } = useForm<FormType>({
|
||||
defaultValues: {
|
||||
avatar: '/icon/logo.png',
|
||||
name: '',
|
||||
templateId: 0
|
||||
}
|
||||
});
|
||||
|
||||
const { File, onOpen: onOpenSelectFile } = useSelectFile({
|
||||
fileType: '.jpg,.png',
|
||||
multiple: false
|
||||
});
|
||||
|
||||
const onSelectFile = useCallback(
|
||||
async (e: File[]) => {
|
||||
const file = e[0];
|
||||
if (!file) return;
|
||||
try {
|
||||
const src = await compressImg({
|
||||
file,
|
||||
maxW: 100,
|
||||
maxH: 100
|
||||
});
|
||||
setValue('avatar', src);
|
||||
setRefresh((state) => !state);
|
||||
} catch (err: any) {
|
||||
toast({
|
||||
title: getErrText(err, '头像选择异常'),
|
||||
status: 'warning'
|
||||
});
|
||||
}
|
||||
},
|
||||
[setValue, toast]
|
||||
);
|
||||
|
||||
const onclickCreate = useCallback(
|
||||
async (data: FormType) => {
|
||||
setCreating(true);
|
||||
try {
|
||||
const id = await postCreateApp({
|
||||
avatar: data.avatar,
|
||||
name: data.name,
|
||||
modules: templates.find((item) => item.id === data.templateId)?.modules || []
|
||||
});
|
||||
toast({
|
||||
title: '创建成功',
|
||||
status: 'success'
|
||||
});
|
||||
router.push(`/app/detail?appId=${id}`);
|
||||
onClose();
|
||||
onSuccess();
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: getErrText(error, '创建应用异常'),
|
||||
status: 'error'
|
||||
});
|
||||
}
|
||||
setCreating(false);
|
||||
},
|
||||
[onClose, onSuccess, router, toast]
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal isOpen onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent w={'700px'} maxW={'90vw'}>
|
||||
<ModalHeader fontSize={'2xl'}>开始创建你的 AI 应用</ModalHeader>
|
||||
<ModalBody>
|
||||
<Box color={'myGray.800'}>取个响亮的名字</Box>
|
||||
<Flex mt={3} alignItems={'center'}>
|
||||
<Avatar
|
||||
src={getValues('avatar')}
|
||||
w={['32px', '36px']}
|
||||
h={['32px', '36px']}
|
||||
cursor={'pointer'}
|
||||
title={'点击选择头像'}
|
||||
borderRadius={'md'}
|
||||
onClick={onOpenSelectFile}
|
||||
/>
|
||||
<Input
|
||||
ml={4}
|
||||
bg={'myWhite.600'}
|
||||
{...register('name', {
|
||||
required: '应用名不能为空~'
|
||||
})}
|
||||
/>
|
||||
</Flex>
|
||||
<Box mt={7} mb={3} color={'myGray.800'}>
|
||||
从模板中选择
|
||||
</Box>
|
||||
<Grid
|
||||
userSelect={'none'}
|
||||
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)']}
|
||||
gridGap={4}
|
||||
>
|
||||
{templates.map((item) => (
|
||||
<Card
|
||||
key={item.id}
|
||||
border={theme.borders.base}
|
||||
p={3}
|
||||
borderRadius={'md'}
|
||||
cursor={'pointer'}
|
||||
boxShadow={'sm'}
|
||||
{...(getValues('templateId') === item.id
|
||||
? {
|
||||
bg: 'myBlue.300'
|
||||
}
|
||||
: {
|
||||
_hover: {
|
||||
boxShadow: 'md'
|
||||
}
|
||||
})}
|
||||
onClick={() => {
|
||||
setValue('templateId', item.id);
|
||||
setRefresh((state) => !state);
|
||||
}}
|
||||
>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon name={'apikey'} w={'16px'} />
|
||||
<Box ml={3} fontWeight={'bold'}>
|
||||
{item.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box fontSize={'sm'} mt={4}>
|
||||
{item.intro}
|
||||
</Box>
|
||||
</Card>
|
||||
))}
|
||||
</Grid>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button variant={'base'} mr={3} onClick={onClose}>
|
||||
取消
|
||||
</Button>
|
||||
<Button isLoading={creating} onClick={handleSubmit(onclickCreate)}>
|
||||
确认创建
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
|
||||
<File onSelect={onSelectFile} />
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateModal;
|
@@ -1,29 +1,76 @@
|
||||
import React from 'react';
|
||||
import { Box, Grid, Card, useTheme, Flex, IconButton, Button } from '@chakra-ui/react';
|
||||
import React, { useCallback } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Grid,
|
||||
Card,
|
||||
useTheme,
|
||||
Flex,
|
||||
IconButton,
|
||||
Button,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useUserStore } from '@/store/user';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import Avatar from '@/components/Avatar';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { AddIcon } from '@chakra-ui/icons';
|
||||
import { delModelById } from '@/api/app';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import { useConfirm } from '@/hooks/useConfirm';
|
||||
import dynamic from 'next/dynamic';
|
||||
|
||||
import MyIcon from '@/components/Icon';
|
||||
import PageContainer from '@/components/PageContainer';
|
||||
import Avatar from '@/components/Avatar';
|
||||
const CreateModal = dynamic(() => import('./component/CreateModal'));
|
||||
import styles from './index.module.scss';
|
||||
|
||||
const MyApps = () => {
|
||||
const { toast } = useToast();
|
||||
const theme = useTheme();
|
||||
const router = useRouter();
|
||||
const { myApps, loadMyModels } = useUserStore();
|
||||
const { openConfirm, ConfirmChild } = useConfirm({
|
||||
title: '删除提示',
|
||||
content: '确认删除该应用所有信息?'
|
||||
});
|
||||
const {
|
||||
isOpen: isOpenCreateModal,
|
||||
onOpen: onOpenCreateModal,
|
||||
onClose: onCloseCreateModal
|
||||
} = useDisclosure();
|
||||
|
||||
/* 点击删除 */
|
||||
const onclickDelApp = useCallback(
|
||||
async (id: string) => {
|
||||
try {
|
||||
await delModelById(id);
|
||||
toast({
|
||||
title: '删除成功',
|
||||
status: 'success'
|
||||
});
|
||||
loadMyModels();
|
||||
} catch (err: any) {
|
||||
toast({
|
||||
title: err?.message || '删除失败',
|
||||
status: 'error'
|
||||
});
|
||||
}
|
||||
},
|
||||
[toast, loadMyModels]
|
||||
);
|
||||
|
||||
/* 加载模型 */
|
||||
useQuery(['loadModels'], () => loadMyModels(false));
|
||||
useQuery(['loadModels'], loadMyModels, {
|
||||
refetchOnMount: true
|
||||
});
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Flex py={3} px={5} borderBottom={theme.borders.base} alignItems={'center'}>
|
||||
<PageContainer>
|
||||
<Flex pt={3} px={5} alignItems={'center'}>
|
||||
<Box flex={1} className="textlg" letterSpacing={1} fontSize={'24px'} fontWeight={'bold'}>
|
||||
我的应用
|
||||
</Box>
|
||||
<Button leftIcon={<AddIcon />} variant={'base'}>
|
||||
<Button leftIcon={<AddIcon />} variant={'base'} onClick={onOpenCreateModal}>
|
||||
新建
|
||||
</Button>
|
||||
</Flex>
|
||||
@@ -43,8 +90,7 @@ const MyApps = () => {
|
||||
boxShadow={'none'}
|
||||
userSelect={'none'}
|
||||
_hover={{
|
||||
boxShadow: 'xl',
|
||||
transform: 'scale(1.03)',
|
||||
boxShadow: '1px 1px 10px rgba(0,0,0,0.2)',
|
||||
borderColor: 'transparent',
|
||||
'& .delete': {
|
||||
display: 'block'
|
||||
@@ -64,10 +110,14 @@ const MyApps = () => {
|
||||
variant={'base'}
|
||||
borderRadius={'md'}
|
||||
aria-label={'delete'}
|
||||
display={'none'}
|
||||
display={['', 'none']}
|
||||
_hover={{
|
||||
bg: 'myGray.100'
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
openConfirm(() => onclickDelApp(app._id))();
|
||||
}}
|
||||
/>
|
||||
</Flex>
|
||||
<Box className={styles.intro} py={2} fontSize={'sm'} color={'myGray.600'}>
|
||||
@@ -76,7 +126,9 @@ const MyApps = () => {
|
||||
</Card>
|
||||
))}
|
||||
</Grid>
|
||||
</Box>
|
||||
<ConfirmChild />
|
||||
{isOpenCreateModal && <CreateModal onClose={onCloseCreateModal} onSuccess={loadMyModels} />}
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -94,7 +94,7 @@ const PcSliderBar = ({
|
||||
[isPc]
|
||||
);
|
||||
|
||||
useQuery(['loadModels'], () => loadMyModels(false));
|
||||
useQuery(['loadModels'], loadMyModels);
|
||||
|
||||
const { isLoading: isLoadingHistory } = useQuery(['loadingHistory'], () =>
|
||||
loadHistory({ pageNum: 1 })
|
||||
|
@@ -39,7 +39,7 @@ const PhoneSliderBar = ({
|
||||
const { isOpen: isOpenWx, onOpen: onOpenWx, onClose: onCloseWx } = useDisclosure();
|
||||
|
||||
const models = useMemo(() => [...myApps, ...myCollectionApps], [myCollectionApps, myApps]);
|
||||
useQuery(['loadModels'], () => loadMyModels(false));
|
||||
useQuery(['loadModels'], loadMyModels);
|
||||
|
||||
const { history, loadHistory } = useChatStore();
|
||||
useQuery(['loadingHistory'], () => loadHistory({ pageNum: 1 }));
|
||||
|
@@ -106,7 +106,7 @@ const Chat = () => {
|
||||
const { copyData } = useCopyData();
|
||||
const { isPc } = useGlobalStore();
|
||||
const { Loading, setIsLoading } = useLoading();
|
||||
const { userInfo, loadMyModels } = useUserStore();
|
||||
const { userInfo } = useUserStore();
|
||||
const { isOpen: isOpenSlider, onClose: onCloseSlider, onOpen: onOpenSlider } = useDisclosure();
|
||||
|
||||
// close contextMenu
|
||||
@@ -232,7 +232,6 @@ const Chat = () => {
|
||||
setTimeout(() => {
|
||||
generatingMessage();
|
||||
loadHistory({ pageNum: 1, init: true });
|
||||
loadMyModels(true);
|
||||
}, 100);
|
||||
|
||||
if (errMsg) {
|
||||
@@ -252,7 +251,6 @@ const Chat = () => {
|
||||
chatData.systemPrompt,
|
||||
chatData.limitPrompt,
|
||||
loadHistory,
|
||||
loadMyModels,
|
||||
toast
|
||||
]
|
||||
);
|
||||
|
@@ -205,7 +205,7 @@ const Home = () => {
|
||||
fontSize={['xl', '3xl']}
|
||||
h={'auto'}
|
||||
py={[2, 3]}
|
||||
onClick={() => router.push(`/model`)}
|
||||
onClick={() => router.push(`/app/list`)}
|
||||
>
|
||||
立即开始
|
||||
</Button>
|
||||
|
@@ -7,7 +7,8 @@ import { useSendCode } from '@/hooks/useSendCode';
|
||||
import type { ResLogin } from '@/api/response/user';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import { useRouter } from 'next/router';
|
||||
import { postCreateModel } from '@/api/app';
|
||||
import { postCreateApp } from '@/api/app';
|
||||
import { chatAppDemo } from '@/constants/app';
|
||||
|
||||
interface Props {
|
||||
loginSuccess: (e: ResLogin) => void;
|
||||
@@ -64,8 +65,9 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
status: 'success'
|
||||
});
|
||||
// aut register a model
|
||||
postCreateModel({
|
||||
name: '应用1'
|
||||
postCreateApp({
|
||||
name: '应用1',
|
||||
modules: chatAppDemo.modules
|
||||
});
|
||||
} catch (error: any) {
|
||||
toast({
|
||||
|
@@ -17,7 +17,7 @@ const Login = () => {
|
||||
const { lastRoute = '' } = router.query as { lastRoute: string };
|
||||
const { isPc } = useGlobalStore();
|
||||
const [pageType, setPageType] = useState<`${PageTypeEnum}`>(PageTypeEnum.login);
|
||||
const { setUserInfo, setLastModelId, loadMyModels, loadKbList, setLastKbId } = useUserStore();
|
||||
const { setUserInfo, setLastModelId, loadKbList, setLastKbId } = useUserStore();
|
||||
const { setLastChatId, setLastChatModelId, loadHistory } = useChatStore();
|
||||
|
||||
const loginSuccess = useCallback(
|
||||
@@ -27,7 +27,6 @@ const Login = () => {
|
||||
setLastModelId('');
|
||||
setLastChatModelId('');
|
||||
setLastKbId('');
|
||||
loadMyModels(true);
|
||||
loadKbList(true);
|
||||
loadHistory({ pageNum: 1, init: true });
|
||||
|
||||
@@ -40,7 +39,6 @@ const Login = () => {
|
||||
lastRoute,
|
||||
loadHistory,
|
||||
loadKbList,
|
||||
loadMyModels,
|
||||
router,
|
||||
setLastChatId,
|
||||
setLastChatModelId,
|
||||
|
@@ -22,14 +22,9 @@ type State = {
|
||||
setLastModelId: (id: string) => void;
|
||||
myApps: AppListItemType[];
|
||||
myCollectionApps: AppListItemType[];
|
||||
loadMyModels: (init?: boolean) => Promise<null>;
|
||||
loadMyModels: () => Promise<null>;
|
||||
appDetail: AppSchema;
|
||||
loadAppDetail: (id: string, init?: boolean) => Promise<AppSchema>;
|
||||
refreshModel: {
|
||||
freshMyModels(): void;
|
||||
updateModelDetail(model: AppSchema): void;
|
||||
removeModelDetail(modelId: string): void;
|
||||
};
|
||||
// kb
|
||||
lastKbId: string;
|
||||
setLastKbId: (id: string) => void;
|
||||
@@ -76,8 +71,7 @@ export const useUserStore = create<State>()(
|
||||
},
|
||||
myApps: [],
|
||||
myCollectionApps: [],
|
||||
async loadMyModels(init = false) {
|
||||
if (get().myApps.length > 0 && !init) return null;
|
||||
async loadMyModels() {
|
||||
const res = await getMyModels();
|
||||
set((state) => {
|
||||
state.myApps = res.myApps;
|
||||
@@ -95,26 +89,6 @@ export const useUserStore = create<State>()(
|
||||
});
|
||||
return res;
|
||||
},
|
||||
refreshModel: {
|
||||
freshMyModels() {
|
||||
get().loadMyModels(true);
|
||||
},
|
||||
updateModelDetail(model: AppSchema) {
|
||||
set((state) => {
|
||||
state.appDetail = model;
|
||||
});
|
||||
get().loadMyModels(true);
|
||||
},
|
||||
removeModelDetail(modelId: string) {
|
||||
if (modelId === get().appDetail._id) {
|
||||
set((state) => {
|
||||
state.appDetail = defaultApp;
|
||||
state.lastModelId = '';
|
||||
});
|
||||
}
|
||||
get().loadMyModels(true);
|
||||
}
|
||||
},
|
||||
lastKbId: '',
|
||||
setLastKbId(id: string) {
|
||||
set((state) => {
|
||||
|
Reference in New Issue
Block a user