diff --git a/public/icon/human.png b/public/icon/human.png index 639c38755..b3c43de0a 100644 Binary files a/public/icon/human.png and b/public/icon/human.png differ diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 085198336..016b5c445 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -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 Navbar from './navbar'; import NavbarPhone from './navbarPhone'; @@ -11,6 +11,9 @@ import { useGlobalStore } from '@/store/global'; const pcUnShowLayoutRoute: Record = { '/login': true }; +const phoneUnShowLayoutRoute: Record = { + '/login': true +}; const Layout = ({ children, isPcDevice }: { children: JSX.Element; isPcDevice: boolean }) => { 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 } = useGlobalStore(); + const isChatPage = useMemo( + () => router.pathname === '/chat' && Object.values(router.query).join('').length !== 0, + [router.pathname, router.query] + ); + useEffect(() => { if (colorMode === 'dark' && router.pathname !== '/chat') { setColorMode('light'); } }, [colorMode, router.pathname, setColorMode]); - const RenderPc = useCallback( - () => - pcUnShowLayoutRoute[router.pathname] ? ( - {children} - ) : ( - <> - - - - - {children} - - - ), - [children, router.pathname] - ); - - const RenderPhone = useCallback(() => { - const phoneUnShowLayoutRoute: Record = { - '/login': true - }; - - const isChatPage = - router.pathname === '/chat' && Object.values(router.query).join('').length !== 0; - - if (phoneUnShowLayoutRoute[router.pathname] || isChatPage) { - return {children}; - } - return ( - - - {children} - - - - - - ); - }, [children, router]); - return ( <> - {isPc ? : } + {isPc ? ( + pcUnShowLayoutRoute[router.pathname] ? ( + {children} + ) : ( + <> + + + + + {children} + + + ) + ) : phoneUnShowLayoutRoute[router.pathname] || isChatPage ? ( + {children} + ) : ( + + + {children} + + + + + + )} {loading && } diff --git a/src/pages/api/model/data/splitData.ts b/src/pages/api/model/data/splitData.ts index a99c6682d..9836adb7a 100644 --- a/src/pages/api/model/data/splitData.ts +++ b/src/pages/api/model/data/splitData.ts @@ -1,7 +1,7 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; 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 { generateQA } from '@/service/events/generateQA'; import { PgClient } from '@/service/pg'; @@ -23,15 +23,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const userId = await authToken(req); // 验证是否是该用户的 model - const model = await Model.findOne({ - _id: modelId, + await authModel({ + modelId, userId }); - if (!model) { - throw new Error('无权操作该模型'); - } - if (mode === 'qa') { // 批量QA拆分插入数据 await SplitData.create({ diff --git a/src/pages/api/model/list.ts b/src/pages/api/model/list.ts index a34dab18c..5887809bf 100644 --- a/src/pages/api/model/list.ts +++ b/src/pages/api/model/list.ts @@ -22,9 +22,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse< ).sort({ _id: -1 }), - Collection.find({ - userId - }).populate('modelId', '_id avatar name chat.systemPrompt') + Collection.find({ userId }) + .populate({ + path: 'modelId', + select: '_id avatar name chat.systemPrompt', + match: { 'share.isShare': true } + }) + .then((res) => res.filter((item) => item.modelId)) ]); jsonRes(res, { diff --git a/src/pages/chat/components/Empty.tsx b/src/pages/chat/components/Empty.tsx index da481b5ab..ccde333a5 100644 --- a/src/pages/chat/components/Empty.tsx +++ b/src/pages/chat/components/Empty.tsx @@ -28,7 +28,13 @@ const Empty = ({ > - {''} + {''} {name} diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index 85ff6beb9..f6caa882a 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -488,9 +488,6 @@ const Chat = ({ modelId && setLastChatModelId(modelId); setLastChatId(chatId); - // focus scroll bottom - chatId && scrollToBottom('auto'); - /* get mode and chat into ↓ */ // phone: history page @@ -640,7 +637,7 @@ const Chat = ({ /> - {chatData.model.canUse && ( + {chatData.model.canUse && item.obj === 'AI' && ( router.push(`/model?modelId=${chatData.modelId}`)}> AI助手详情 @@ -675,6 +672,7 @@ const Chat = ({ )} + {/* copy and clear icon */} {isPc && ( @@ -815,8 +813,6 @@ const Chat = ({ ); }; -export default Chat; - Chat.getInitialProps = ({ query, req }: any) => { return { modelId: query?.modelId || '', @@ -824,3 +820,5 @@ Chat.getInitialProps = ({ query, req }: any) => { isPcDevice: !/Mobile/.test(req ? req.headers['user-agent'] : navigator.userAgent) }; }; + +export default Chat; diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 1a5f25748..fab7d2c60 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -6,6 +6,7 @@ import { useScreen } from '@/hooks/useScreen'; import type { ResLogin } from '@/api/response/user'; import { useRouter } from 'next/router'; import { useUserStore } from '@/store/user'; +import { useChatStore } from '@/store/chat'; import LoginForm from './components/LoginForm'; import dynamic from 'next/dynamic'; const RegisterForm = dynamic(() => import('./components/RegisterForm')); @@ -16,16 +17,33 @@ const Login = ({ isPcDevice }: { isPcDevice: boolean }) => { const { lastRoute = '' } = router.query as { lastRoute: string }; const { isPc } = useScreen({ defaultIsPc: isPcDevice }); const [pageType, setPageType] = useState<`${PageTypeEnum}`>(PageTypeEnum.login); - const { setUserInfo } = useUserStore(); + const { setUserInfo, setLastModelId, loadMyModels } = useUserStore(); + const { setLastChatId, setLastChatModelId, loadHistory } = useChatStore(); const loginSuccess = useCallback( (res: ResLogin) => { + // init store + setLastChatId(''); + setLastModelId(''); + setLastChatModelId(''); + loadMyModels(true); + loadHistory({ pageNum: 1, init: true }); + setUserInfo(res.user); setTimeout(() => { router.push(lastRoute ? decodeURIComponent(lastRoute) : '/model'); }, 100); }, - [lastRoute, router, setUserInfo] + [ + lastRoute, + loadHistory, + loadMyModels, + router, + setLastChatId, + setLastChatModelId, + setLastModelId, + setUserInfo + ] ); function DynamicComponent({ type }: { type: `${PageTypeEnum}` }) { diff --git a/src/pages/model/components/detail/components/ModelEditForm.tsx b/src/pages/model/components/detail/components/ModelEditForm.tsx index 46924482f..bb4464461 100644 --- a/src/pages/model/components/detail/components/ModelEditForm.tsx +++ b/src/pages/model/components/detail/components/ModelEditForm.tsx @@ -55,8 +55,8 @@ const ModelEditForm = ({ try { const base64 = await compressImg({ file, - maxW: 40, - maxH: 60 + maxW: 100, + maxH: 100 }); setValue('avatar', base64); setRefresh((state) => !state); diff --git a/src/pages/number/index.tsx b/src/pages/number/index.tsx index b003e440f..e7b5b2074 100644 --- a/src/pages/number/index.tsx +++ b/src/pages/number/index.tsx @@ -57,8 +57,8 @@ const NumberSetting = () => { try { const base64 = await compressImg({ file, - maxW: 40, - maxH: 60 + maxW: 100, + maxH: 100 }); onclickSave({ ...userInfo, @@ -100,8 +100,8 @@ const NumberSetting = () => { src={userInfo?.avatar} alt={'avatar'} w={['28px', '36px']} - h={['28px', '36px']} - objectFit={'cover'} + maxH={'40px'} + objectFit={'contain'} cursor={'pointer'} title={'点击切换头像'} onClick={onOpenSelectFile} diff --git a/src/service/errorCode.ts b/src/service/errorCode.ts index 3c5d7f71f..e0f41ec9e 100644 --- a/src/service/errorCode.ts +++ b/src/service/errorCode.ts @@ -36,7 +36,8 @@ export const proxyError: Record = { export enum ERROR_ENUM { unAuthorization = 'unAuthorization', - insufficientQuota = 'insufficientQuota' + insufficientQuota = 'insufficientQuota', + unAuthModel = 'unAuthModel' } export const ERROR_RESPONSE: Record< any, @@ -58,5 +59,11 @@ export const ERROR_RESPONSE: Record< statusText: ERROR_ENUM.insufficientQuota, message: '账号余额不足', data: null + }, + [ERROR_ENUM.unAuthModel]: { + code: 511, + statusText: ERROR_ENUM.unAuthModel, + message: '无权使用该模型', + data: null } }; diff --git a/src/service/utils/auth.ts b/src/service/utils/auth.ts index 30803e00d..217b3ef65 100644 --- a/src/service/utils/auth.ts +++ b/src/service/utils/auth.ts @@ -114,7 +114,7 @@ export const authModel = async ({ 2. authUser = false and share, anyone can use */ if ((authOwner || (authUser && !model.share.isShare)) && userId !== String(model.userId)) { - return Promise.reject('无权操作该模型'); + return Promise.reject(ERROR_ENUM.unAuthModel); } // do not share detail info