mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 21:13:50 +00:00
perf: refresh page.img mode.collection filter
This commit is contained in:
Binary file not shown.
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 56 KiB |
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import { Box, useColorMode, Flex } from '@chakra-ui/react';
|
import { Box, useColorMode, Flex } from '@chakra-ui/react';
|
||||||
import Navbar from './navbar';
|
import Navbar from './navbar';
|
||||||
import NavbarPhone from './navbarPhone';
|
import NavbarPhone from './navbarPhone';
|
||||||
@@ -11,6 +11,9 @@ import { useGlobalStore } from '@/store/global';
|
|||||||
const pcUnShowLayoutRoute: Record<string, boolean> = {
|
const pcUnShowLayoutRoute: Record<string, boolean> = {
|
||||||
'/login': true
|
'/login': true
|
||||||
};
|
};
|
||||||
|
const phoneUnShowLayoutRoute: Record<string, boolean> = {
|
||||||
|
'/login': true
|
||||||
|
};
|
||||||
|
|
||||||
const Layout = ({ children, isPcDevice }: { children: JSX.Element; isPcDevice: boolean }) => {
|
const Layout = ({ children, isPcDevice }: { children: JSX.Element; isPcDevice: boolean }) => {
|
||||||
const { isPc } = useScreen({ defaultIsPc: isPcDevice });
|
const { isPc } = useScreen({ defaultIsPc: isPcDevice });
|
||||||
@@ -19,56 +22,45 @@ const Layout = ({ children, isPcDevice }: { children: JSX.Element; isPcDevice: b
|
|||||||
const { Loading } = useLoading({ defaultLoading: true });
|
const { Loading } = useLoading({ defaultLoading: true });
|
||||||
const { loading } = useGlobalStore();
|
const { loading } = useGlobalStore();
|
||||||
|
|
||||||
|
const isChatPage = useMemo(
|
||||||
|
() => router.pathname === '/chat' && Object.values(router.query).join('').length !== 0,
|
||||||
|
[router.pathname, router.query]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (colorMode === 'dark' && router.pathname !== '/chat') {
|
if (colorMode === 'dark' && router.pathname !== '/chat') {
|
||||||
setColorMode('light');
|
setColorMode('light');
|
||||||
}
|
}
|
||||||
}, [colorMode, router.pathname, setColorMode]);
|
}, [colorMode, router.pathname, setColorMode]);
|
||||||
|
|
||||||
const RenderPc = useCallback(
|
|
||||||
() =>
|
|
||||||
pcUnShowLayoutRoute[router.pathname] ? (
|
|
||||||
<Auth>{children}</Auth>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Box h={'100%'} position={'fixed'} left={0} top={0} w={'60px'}>
|
|
||||||
<Navbar />
|
|
||||||
</Box>
|
|
||||||
<Box h={'100%'} ml={'60px'} overflow={'overlay'}>
|
|
||||||
<Auth>{children}</Auth>
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
[children, router.pathname]
|
|
||||||
);
|
|
||||||
|
|
||||||
const RenderPhone = useCallback(() => {
|
|
||||||
const phoneUnShowLayoutRoute: Record<string, boolean> = {
|
|
||||||
'/login': true
|
|
||||||
};
|
|
||||||
|
|
||||||
const isChatPage =
|
|
||||||
router.pathname === '/chat' && Object.values(router.query).join('').length !== 0;
|
|
||||||
|
|
||||||
if (phoneUnShowLayoutRoute[router.pathname] || isChatPage) {
|
|
||||||
return <Auth>{children}</Auth>;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Flex h={'100%'} flexDirection={'column'}>
|
|
||||||
<Box flex={'1 0 0'} h={0} overflow={'overlay'}>
|
|
||||||
<Auth>{children}</Auth>
|
|
||||||
</Box>
|
|
||||||
<Box h={'50px'} borderTop={'1px solid rgba(0,0,0,0.1)'}>
|
|
||||||
<NavbarPhone />
|
|
||||||
</Box>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
}, [children, router]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box h={'100%'} overflow={'overlay'} bg={'gray.100'}>
|
<Box h={'100%'} overflow={'overlay'} bg={'gray.100'}>
|
||||||
{isPc ? <RenderPc /> : <RenderPhone />}
|
{isPc ? (
|
||||||
|
pcUnShowLayoutRoute[router.pathname] ? (
|
||||||
|
<Auth>{children}</Auth>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Box h={'100%'} position={'fixed'} left={0} top={0} w={'60px'}>
|
||||||
|
<Navbar />
|
||||||
|
</Box>
|
||||||
|
<Box h={'100%'} ml={'60px'} overflow={'overlay'}>
|
||||||
|
<Auth>{children}</Auth>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
) : phoneUnShowLayoutRoute[router.pathname] || isChatPage ? (
|
||||||
|
<Auth>{children}</Auth>
|
||||||
|
) : (
|
||||||
|
<Flex h={'100%'} flexDirection={'column'}>
|
||||||
|
<Box flex={'1 0 0'} h={0} overflow={'overlay'}>
|
||||||
|
<Auth>{children}</Auth>
|
||||||
|
</Box>
|
||||||
|
<Box h={'50px'} borderTop={'1px solid rgba(0,0,0,0.1)'}>
|
||||||
|
<NavbarPhone />
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{loading && <Loading />}
|
{loading && <Loading />}
|
||||||
</>
|
</>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
import { jsonRes } from '@/service/response';
|
import { jsonRes } from '@/service/response';
|
||||||
import { connectToDatabase, SplitData, Model } from '@/service/mongo';
|
import { connectToDatabase, SplitData, Model } from '@/service/mongo';
|
||||||
import { authToken } from '@/service/utils/auth';
|
import { authModel, authToken } from '@/service/utils/auth';
|
||||||
import { generateVector } from '@/service/events/generateVector';
|
import { generateVector } from '@/service/events/generateVector';
|
||||||
import { generateQA } from '@/service/events/generateQA';
|
import { generateQA } from '@/service/events/generateQA';
|
||||||
import { PgClient } from '@/service/pg';
|
import { PgClient } from '@/service/pg';
|
||||||
@@ -23,15 +23,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
const userId = await authToken(req);
|
const userId = await authToken(req);
|
||||||
|
|
||||||
// 验证是否是该用户的 model
|
// 验证是否是该用户的 model
|
||||||
const model = await Model.findOne({
|
await authModel({
|
||||||
_id: modelId,
|
modelId,
|
||||||
userId
|
userId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!model) {
|
|
||||||
throw new Error('无权操作该模型');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode === 'qa') {
|
if (mode === 'qa') {
|
||||||
// 批量QA拆分插入数据
|
// 批量QA拆分插入数据
|
||||||
await SplitData.create({
|
await SplitData.create({
|
||||||
|
@@ -22,9 +22,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
).sort({
|
).sort({
|
||||||
_id: -1
|
_id: -1
|
||||||
}),
|
}),
|
||||||
Collection.find({
|
Collection.find({ userId })
|
||||||
userId
|
.populate({
|
||||||
}).populate('modelId', '_id avatar name chat.systemPrompt')
|
path: 'modelId',
|
||||||
|
select: '_id avatar name chat.systemPrompt',
|
||||||
|
match: { 'share.isShare': true }
|
||||||
|
})
|
||||||
|
.then((res) => res.filter((item) => item.modelId))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
jsonRes<ModelListResponse>(res, {
|
jsonRes<ModelListResponse>(res, {
|
||||||
|
@@ -28,7 +28,13 @@ const Empty = ({
|
|||||||
>
|
>
|
||||||
<Card p={4} mb={10}>
|
<Card p={4} mb={10}>
|
||||||
<Flex mb={2} alignItems={'center'} justifyContent={'center'}>
|
<Flex mb={2} alignItems={'center'} justifyContent={'center'}>
|
||||||
<Image src={avatar || LOGO_ICON} w={'32px'} h={'32px'} alt={''} />
|
<Image
|
||||||
|
src={avatar || LOGO_ICON}
|
||||||
|
w={'32px'}
|
||||||
|
maxH={'40px'}
|
||||||
|
objectFit={'contain'}
|
||||||
|
alt={''}
|
||||||
|
/>
|
||||||
<Box ml={3} fontSize={'3xl'} fontWeight={'bold'}>
|
<Box ml={3} fontSize={'3xl'} fontWeight={'bold'}>
|
||||||
{name}
|
{name}
|
||||||
</Box>
|
</Box>
|
||||||
|
@@ -488,9 +488,6 @@ const Chat = ({
|
|||||||
modelId && setLastChatModelId(modelId);
|
modelId && setLastChatModelId(modelId);
|
||||||
setLastChatId(chatId);
|
setLastChatId(chatId);
|
||||||
|
|
||||||
// focus scroll bottom
|
|
||||||
chatId && scrollToBottom('auto');
|
|
||||||
|
|
||||||
/* get mode and chat into ↓ */
|
/* get mode and chat into ↓ */
|
||||||
|
|
||||||
// phone: history page
|
// phone: history page
|
||||||
@@ -640,7 +637,7 @@ const Chat = ({
|
|||||||
/>
|
/>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<MenuList fontSize={'sm'}>
|
<MenuList fontSize={'sm'}>
|
||||||
{chatData.model.canUse && (
|
{chatData.model.canUse && item.obj === 'AI' && (
|
||||||
<MenuItem onClick={() => router.push(`/model?modelId=${chatData.modelId}`)}>
|
<MenuItem onClick={() => router.push(`/model?modelId=${chatData.modelId}`)}>
|
||||||
AI助手详情
|
AI助手详情
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
@@ -675,6 +672,7 @@ const Chat = ({
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
{/* copy and clear icon */}
|
||||||
{isPc && (
|
{isPc && (
|
||||||
<Flex h={'100%'} flexDirection={'column'} ml={2} w={'14px'} height={'100%'}>
|
<Flex h={'100%'} flexDirection={'column'} ml={2} w={'14px'} height={'100%'}>
|
||||||
<Box minH={'40px'} flex={1}>
|
<Box minH={'40px'} flex={1}>
|
||||||
@@ -815,8 +813,6 @@ const Chat = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Chat;
|
|
||||||
|
|
||||||
Chat.getInitialProps = ({ query, req }: any) => {
|
Chat.getInitialProps = ({ query, req }: any) => {
|
||||||
return {
|
return {
|
||||||
modelId: query?.modelId || '',
|
modelId: query?.modelId || '',
|
||||||
@@ -824,3 +820,5 @@ Chat.getInitialProps = ({ query, req }: any) => {
|
|||||||
isPcDevice: !/Mobile/.test(req ? req.headers['user-agent'] : navigator.userAgent)
|
isPcDevice: !/Mobile/.test(req ? req.headers['user-agent'] : navigator.userAgent)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default Chat;
|
||||||
|
@@ -6,6 +6,7 @@ import { useScreen } from '@/hooks/useScreen';
|
|||||||
import type { ResLogin } from '@/api/response/user';
|
import type { ResLogin } from '@/api/response/user';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useUserStore } from '@/store/user';
|
import { useUserStore } from '@/store/user';
|
||||||
|
import { useChatStore } from '@/store/chat';
|
||||||
import LoginForm from './components/LoginForm';
|
import LoginForm from './components/LoginForm';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
||||||
@@ -16,16 +17,33 @@ const Login = ({ isPcDevice }: { isPcDevice: boolean }) => {
|
|||||||
const { lastRoute = '' } = router.query as { lastRoute: string };
|
const { lastRoute = '' } = router.query as { lastRoute: string };
|
||||||
const { isPc } = useScreen({ defaultIsPc: isPcDevice });
|
const { isPc } = useScreen({ defaultIsPc: isPcDevice });
|
||||||
const [pageType, setPageType] = useState<`${PageTypeEnum}`>(PageTypeEnum.login);
|
const [pageType, setPageType] = useState<`${PageTypeEnum}`>(PageTypeEnum.login);
|
||||||
const { setUserInfo } = useUserStore();
|
const { setUserInfo, setLastModelId, loadMyModels } = useUserStore();
|
||||||
|
const { setLastChatId, setLastChatModelId, loadHistory } = useChatStore();
|
||||||
|
|
||||||
const loginSuccess = useCallback(
|
const loginSuccess = useCallback(
|
||||||
(res: ResLogin) => {
|
(res: ResLogin) => {
|
||||||
|
// init store
|
||||||
|
setLastChatId('');
|
||||||
|
setLastModelId('');
|
||||||
|
setLastChatModelId('');
|
||||||
|
loadMyModels(true);
|
||||||
|
loadHistory({ pageNum: 1, init: true });
|
||||||
|
|
||||||
setUserInfo(res.user);
|
setUserInfo(res.user);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.push(lastRoute ? decodeURIComponent(lastRoute) : '/model');
|
router.push(lastRoute ? decodeURIComponent(lastRoute) : '/model');
|
||||||
}, 100);
|
}, 100);
|
||||||
},
|
},
|
||||||
[lastRoute, router, setUserInfo]
|
[
|
||||||
|
lastRoute,
|
||||||
|
loadHistory,
|
||||||
|
loadMyModels,
|
||||||
|
router,
|
||||||
|
setLastChatId,
|
||||||
|
setLastChatModelId,
|
||||||
|
setLastModelId,
|
||||||
|
setUserInfo
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
function DynamicComponent({ type }: { type: `${PageTypeEnum}` }) {
|
function DynamicComponent({ type }: { type: `${PageTypeEnum}` }) {
|
||||||
|
@@ -55,8 +55,8 @@ const ModelEditForm = ({
|
|||||||
try {
|
try {
|
||||||
const base64 = await compressImg({
|
const base64 = await compressImg({
|
||||||
file,
|
file,
|
||||||
maxW: 40,
|
maxW: 100,
|
||||||
maxH: 60
|
maxH: 100
|
||||||
});
|
});
|
||||||
setValue('avatar', base64);
|
setValue('avatar', base64);
|
||||||
setRefresh((state) => !state);
|
setRefresh((state) => !state);
|
||||||
|
@@ -57,8 +57,8 @@ const NumberSetting = () => {
|
|||||||
try {
|
try {
|
||||||
const base64 = await compressImg({
|
const base64 = await compressImg({
|
||||||
file,
|
file,
|
||||||
maxW: 40,
|
maxW: 100,
|
||||||
maxH: 60
|
maxH: 100
|
||||||
});
|
});
|
||||||
onclickSave({
|
onclickSave({
|
||||||
...userInfo,
|
...userInfo,
|
||||||
@@ -100,8 +100,8 @@ const NumberSetting = () => {
|
|||||||
src={userInfo?.avatar}
|
src={userInfo?.avatar}
|
||||||
alt={'avatar'}
|
alt={'avatar'}
|
||||||
w={['28px', '36px']}
|
w={['28px', '36px']}
|
||||||
h={['28px', '36px']}
|
maxH={'40px'}
|
||||||
objectFit={'cover'}
|
objectFit={'contain'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
title={'点击切换头像'}
|
title={'点击切换头像'}
|
||||||
onClick={onOpenSelectFile}
|
onClick={onOpenSelectFile}
|
||||||
|
@@ -36,7 +36,8 @@ export const proxyError: Record<string, boolean> = {
|
|||||||
|
|
||||||
export enum ERROR_ENUM {
|
export enum ERROR_ENUM {
|
||||||
unAuthorization = 'unAuthorization',
|
unAuthorization = 'unAuthorization',
|
||||||
insufficientQuota = 'insufficientQuota'
|
insufficientQuota = 'insufficientQuota',
|
||||||
|
unAuthModel = 'unAuthModel'
|
||||||
}
|
}
|
||||||
export const ERROR_RESPONSE: Record<
|
export const ERROR_RESPONSE: Record<
|
||||||
any,
|
any,
|
||||||
@@ -58,5 +59,11 @@ export const ERROR_RESPONSE: Record<
|
|||||||
statusText: ERROR_ENUM.insufficientQuota,
|
statusText: ERROR_ENUM.insufficientQuota,
|
||||||
message: '账号余额不足',
|
message: '账号余额不足',
|
||||||
data: null
|
data: null
|
||||||
|
},
|
||||||
|
[ERROR_ENUM.unAuthModel]: {
|
||||||
|
code: 511,
|
||||||
|
statusText: ERROR_ENUM.unAuthModel,
|
||||||
|
message: '无权使用该模型',
|
||||||
|
data: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -114,7 +114,7 @@ export const authModel = async ({
|
|||||||
2. authUser = false and share, anyone can use
|
2. authUser = false and share, anyone can use
|
||||||
*/
|
*/
|
||||||
if ((authOwner || (authUser && !model.share.isShare)) && userId !== String(model.userId)) {
|
if ((authOwner || (authUser && !model.share.isShare)) && userId !== String(model.userId)) {
|
||||||
return Promise.reject('无权操作该模型');
|
return Promise.reject(ERROR_ENUM.unAuthModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not share detail info
|
// do not share detail info
|
||||||
|
Reference in New Issue
Block a user