temp
This commit is contained in:
parent
be69cfb966
commit
7529f51e72
@ -45,8 +45,13 @@ const Button = defineStyleConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
outline: {
|
white: {
|
||||||
borderWidth: '1.5px'
|
color: '#fff',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
border: '1px solid #ffffff',
|
||||||
|
_hover: {
|
||||||
|
backgroundColor: 'rgba(255,255,255,0.1)'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
defaultProps: {
|
defaultProps: {
|
||||||
|
|||||||
@ -103,9 +103,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
try {
|
||||||
for await (const chunk of chatResponse.data as any) {
|
for await (const chunk of chatResponse.data as any) {
|
||||||
const parser = createParser(onParse);
|
const parser = createParser(onParse);
|
||||||
parser.feed(decodeURIComponent(chunk));
|
parser.feed(decoder.decode(chunk));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('pipe error', error);
|
||||||
}
|
}
|
||||||
pass.push(null);
|
pass.push(null);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|||||||
19
src/pages/chat/components/SlideBar.tsx
Normal file
19
src/pages/chat/components/SlideBar.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box, Button } from '@chakra-ui/react';
|
||||||
|
import { AddIcon } from '@chakra-ui/icons';
|
||||||
|
|
||||||
|
const SlideBar = ({ resetChat }: { resetChat: () => void }) => {
|
||||||
|
return (
|
||||||
|
<Box flex={'0 0 250px'} p={3} backgroundColor={'blackAlpha.800'} color={'white'}>
|
||||||
|
{/* 新对话 */}
|
||||||
|
<Button w={'100%'} variant={'white'} h={'40px'} leftIcon={<AddIcon />} onClick={resetChat}>
|
||||||
|
新对话
|
||||||
|
</Button>
|
||||||
|
{/* 我的模型 */}
|
||||||
|
|
||||||
|
{/* 历史记录 */}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SlideBar;
|
||||||
@ -12,12 +12,21 @@ import { OpenAiModelEnum } from '@/constants/model';
|
|||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useGlobalStore } from '@/store/global';
|
import { useGlobalStore } from '@/store/global';
|
||||||
import { streamFetch } from '@/api/fetch';
|
import { streamFetch } from '@/api/fetch';
|
||||||
|
import SlideBar from './components/SlideBar';
|
||||||
|
|
||||||
const Markdown = dynamic(() => import('@/components/Markdown'));
|
const Markdown = dynamic(() => import('@/components/Markdown'));
|
||||||
|
|
||||||
const textareaMinH = '22px';
|
const textareaMinH = '22px';
|
||||||
|
|
||||||
const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
const Chat = ({
|
||||||
|
chatId,
|
||||||
|
windowId,
|
||||||
|
timeStamp
|
||||||
|
}: {
|
||||||
|
chatId: string;
|
||||||
|
windowId?: string;
|
||||||
|
timeStamp: string;
|
||||||
|
}) => {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { isPc, media } = useScreen();
|
const { isPc, media } = useScreen();
|
||||||
@ -45,7 +54,7 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
|
|
||||||
// 初始化聊天框
|
// 初始化聊天框
|
||||||
useQuery(
|
useQuery(
|
||||||
['initData'],
|
['initData', timeStamp],
|
||||||
() => {
|
() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
return getInitChatSiteInfo(chatId, windowId);
|
return getInitChatSiteInfo(chatId, windowId);
|
||||||
@ -53,7 +62,7 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
{
|
{
|
||||||
onSuccess(res) {
|
onSuccess(res) {
|
||||||
// 可能没有 windowId,给它设置一下
|
// 可能没有 windowId,给它设置一下
|
||||||
router.replace(`/chat?chatId=${chatId}&windowId=${res.windowId}`);
|
router.replace(`/chat?chatId=${chatId}&windowId=${res.windowId}&timeStamp=${timeStamp}`);
|
||||||
|
|
||||||
setChatSiteData(res.chatSite);
|
setChatSiteData(res.chatSite);
|
||||||
setChatList(
|
setChatList(
|
||||||
@ -92,8 +101,8 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
|
|
||||||
// 重载对话
|
// 重载对话
|
||||||
const resetChat = useCallback(() => {
|
const resetChat = useCallback(() => {
|
||||||
window.open(`/chat?chatId=${chatId}`, '_self');
|
router.push(`/chat?chatId=${chatId}&timeStamp=${Date.now()}`);
|
||||||
}, [chatId]);
|
}, [chatId, router]);
|
||||||
|
|
||||||
// gpt3 方法
|
// gpt3 方法
|
||||||
const gpt3ChatPrompt = useCallback(
|
const gpt3ChatPrompt = useCallback(
|
||||||
@ -270,35 +279,11 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
}, [chatList, resetInputVal, windowId]);
|
}, [chatList, resetInputVal, windowId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex height={'100%'} flexDirection={'column'}>
|
<Flex h={'100%'}>
|
||||||
{/* 头部 */}
|
<SlideBar resetChat={resetChat} />
|
||||||
<Flex
|
<Flex flex={1} h={'100%'} flexDirection={'column'}>
|
||||||
px={4}
|
|
||||||
h={'50px'}
|
|
||||||
alignItems={'center'}
|
|
||||||
backgroundColor={'white'}
|
|
||||||
boxShadow={'0 5px 10px rgba(0,0,0,0.1)'}
|
|
||||||
zIndex={1}
|
|
||||||
>
|
|
||||||
<Box flex={1}>{chatSiteData?.name}</Box>
|
|
||||||
{/* 滚动到底部按键 */}
|
|
||||||
{ChatBox.current && ChatBox.current.scrollHeight > 2 * ChatBox.current.clientHeight && (
|
|
||||||
<Box mr={10} cursor={'pointer'} onClick={scrollToBottom}>
|
|
||||||
<Icon
|
|
||||||
name={'icon-xiangxiazhankai-xianxingyuankuang'}
|
|
||||||
width={25}
|
|
||||||
height={25}
|
|
||||||
color={'#718096'}
|
|
||||||
></Icon>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
{/* 重置按键 */}
|
|
||||||
<Button size={'sm'} colorScheme={'gray'} onClick={resetChat}>
|
|
||||||
新对话
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
{/* 聊天内容 */}
|
{/* 聊天内容 */}
|
||||||
<Box ref={ChatBox} flex={'1 0 0'} h={0} w={'100%'} px={0} pb={10} overflowY={'auto'}>
|
<Box ref={ChatBox} flex={'1 0 0'} h={0} w={'100%'} overflowY={'auto'}>
|
||||||
{chatList.map((item, index) => (
|
{chatList.map((item, index) => (
|
||||||
<Box
|
<Box
|
||||||
key={index}
|
key={index}
|
||||||
@ -307,7 +292,7 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
backgroundColor={index % 2 === 0 ? 'rgba(247,247,248,1)' : '#fff'}
|
backgroundColor={index % 2 === 0 ? 'rgba(247,247,248,1)' : '#fff'}
|
||||||
borderBottom={'1px solid rgba(0,0,0,0.1)'}
|
borderBottom={'1px solid rgba(0,0,0,0.1)'}
|
||||||
>
|
>
|
||||||
<Flex maxW={'800px'} m={'auto'} alignItems={'flex-start'}>
|
<Flex maxW={'750px'} m={'auto'} alignItems={'flex-start'}>
|
||||||
<Box mr={media(4, 1)}>
|
<Box mr={media(4, 1)}>
|
||||||
<Image
|
<Image
|
||||||
src={item.obj === 'Human' ? '/icon/human.png' : '/icon/logo.png'}
|
src={item.obj === 'Human' ? '/icon/human.png' : '/icon/logo.png'}
|
||||||
@ -330,20 +315,11 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
{/* 空内容提示 */}
|
{/* 发送区 */}
|
||||||
{/* {
|
|
||||||
chatList.length === 0 && (
|
|
||||||
<>
|
|
||||||
<Card>
|
|
||||||
内容太长
|
|
||||||
</Card>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
} */}
|
|
||||||
<Box
|
<Box
|
||||||
m={media('20px auto', '0 auto')}
|
m={media('20px auto', '0 auto')}
|
||||||
w={media('100vw', '100%')}
|
w={media('100vw', '100%')}
|
||||||
maxW={media('800px', 'auto')}
|
maxW={media('750px', 'auto')}
|
||||||
boxShadow={'0 -14px 30px rgba(255,255,255,0.6)'}
|
boxShadow={'0 -14px 30px rgba(255,255,255,0.6)'}
|
||||||
borderTop={media('none', '1px solid rgba(0,0,0,0.1)')}
|
borderTop={media('none', '1px solid rgba(0,0,0,0.1)')}
|
||||||
>
|
>
|
||||||
@ -421,6 +397,7 @@ const Chat = ({ chatId, windowId }: { chatId: string; windowId?: string }) => {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -429,8 +406,9 @@ export default Chat;
|
|||||||
export async function getServerSideProps(context: any) {
|
export async function getServerSideProps(context: any) {
|
||||||
const chatId = context.query?.chatId || '';
|
const chatId = context.query?.chatId || '';
|
||||||
const windowId = context.query?.windowId || '';
|
const windowId = context.query?.windowId || '';
|
||||||
|
const timeStamp = context.query?.timeStamp || `${Date.now()}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: { chatId, windowId }
|
props: { chatId, windowId, timeStamp }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import React, { useState, useCallback } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import { Box, Button, Flex, Card } from '@chakra-ui/react';
|
import { Box, Button, Flex, Card } from '@chakra-ui/react';
|
||||||
import { getMyModels } from '@/api/model';
|
|
||||||
import { getChatSiteId } from '@/api/chat';
|
import { getChatSiteId } from '@/api/chat';
|
||||||
import { ModelType } from '@/types/model';
|
import { ModelType } from '@/types/model';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
@ -11,6 +10,7 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { useLoading } from '@/hooks/useLoading';
|
import { useLoading } from '@/hooks/useLoading';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
|
import { useUserStore } from '@/store/user';
|
||||||
|
|
||||||
const CreateModel = dynamic(() => import('./components/CreateModel'));
|
const CreateModel = dynamic(() => import('./components/CreateModel'));
|
||||||
|
|
||||||
@ -18,22 +18,20 @@ const ModelList = () => {
|
|||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { isPc } = useScreen();
|
const { isPc } = useScreen();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [models, setModels] = useState<ModelType[]>([]);
|
const { myModels, setMyModels, getMyModels } = useUserStore();
|
||||||
const [openCreateModel, setOpenCreateModel] = useState(false);
|
const [openCreateModel, setOpenCreateModel] = useState(false);
|
||||||
const { Loading, setIsLoading } = useLoading();
|
const { Loading, setIsLoading } = useLoading();
|
||||||
|
|
||||||
/* 加载模型 */
|
/* 加载模型 */
|
||||||
const { isLoading } = useQuery(['loadModels'], () => getMyModels(), {
|
const { isLoading } = useQuery(['loadModels'], getMyModels);
|
||||||
onSuccess(res) {
|
|
||||||
if (!res) return;
|
|
||||||
setModels(res);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/* 创建成功回调 */
|
/* 创建成功回调 */
|
||||||
const createModelSuccess = useCallback((data: ModelType) => {
|
const createModelSuccess = useCallback(
|
||||||
setModels((state) => [data, ...state]);
|
(data: ModelType) => {
|
||||||
}, []);
|
setMyModels([data, ...myModels]);
|
||||||
|
},
|
||||||
|
[myModels, setMyModels]
|
||||||
|
);
|
||||||
|
|
||||||
/* 点前往聊天预览页 */
|
/* 点前往聊天预览页 */
|
||||||
const handlePreviewChat = useCallback(
|
const handlePreviewChat = useCallback(
|
||||||
@ -74,9 +72,9 @@ const ModelList = () => {
|
|||||||
{/* 表单 */}
|
{/* 表单 */}
|
||||||
<Box mt={5} position={'relative'}>
|
<Box mt={5} position={'relative'}>
|
||||||
{isPc ? (
|
{isPc ? (
|
||||||
<ModelTable models={models} handlePreviewChat={handlePreviewChat} />
|
<ModelTable models={myModels} handlePreviewChat={handlePreviewChat} />
|
||||||
) : (
|
) : (
|
||||||
<ModelPhoneList models={models} handlePreviewChat={handlePreviewChat} />
|
<ModelPhoneList models={myModels} handlePreviewChat={handlePreviewChat} />
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
{/* 创建弹窗 */}
|
{/* 创建弹窗 */}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ export const jsonRes = (
|
|||||||
} else if (openaiError[error?.response?.statusText]) {
|
} else if (openaiError[error?.response?.statusText]) {
|
||||||
msg = openaiError[error.response.statusText];
|
msg = openaiError[error.response.statusText];
|
||||||
}
|
}
|
||||||
|
// console.log(error?.response)
|
||||||
console.log('error->', error.code, error?.response?.statusText, msg);
|
console.log('error->', error.code, error?.response?.statusText, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,25 +2,30 @@ import { create } from 'zustand';
|
|||||||
import { devtools } from 'zustand/middleware';
|
import { devtools } from 'zustand/middleware';
|
||||||
import { immer } from 'zustand/middleware/immer';
|
import { immer } from 'zustand/middleware/immer';
|
||||||
import type { UserType, UserUpdateParams } from '@/types/user';
|
import type { UserType, UserUpdateParams } from '@/types/user';
|
||||||
|
import type { ModelType } from '@/types/model';
|
||||||
import { setToken } from '@/utils/user';
|
import { setToken } from '@/utils/user';
|
||||||
|
import { getMyModels } from '@/api/model';
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
userInfo: UserType | null;
|
userInfo: UserType | null;
|
||||||
setUserInfo: (user: UserType, token?: string) => void;
|
setUserInfo: (user: UserType, token?: string) => void;
|
||||||
updateUserInfo: (user: UserUpdateParams) => void;
|
updateUserInfo: (user: UserUpdateParams) => void;
|
||||||
|
myModels: ModelType[];
|
||||||
|
getMyModels: () => void;
|
||||||
|
setMyModels: (data: ModelType[]) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUserStore = create<State>()(
|
export const useUserStore = create<State>()(
|
||||||
devtools(
|
devtools(
|
||||||
immer((set, get) => ({
|
immer((set, get) => ({
|
||||||
userInfo: null,
|
userInfo: null,
|
||||||
setUserInfo: (user: UserType, token?: string) => {
|
setUserInfo(user: UserType, token?: string) {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.userInfo = user;
|
state.userInfo = user;
|
||||||
});
|
});
|
||||||
token && setToken(token);
|
token && setToken(token);
|
||||||
},
|
},
|
||||||
updateUserInfo: (user: UserUpdateParams) => {
|
updateUserInfo(user: UserUpdateParams) {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
if (!state.userInfo) return;
|
if (!state.userInfo) return;
|
||||||
state.userInfo = {
|
state.userInfo = {
|
||||||
@ -28,6 +33,20 @@ export const useUserStore = create<State>()(
|
|||||||
...user
|
...user
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
myModels: [],
|
||||||
|
getMyModels: () =>
|
||||||
|
getMyModels().then((res) => {
|
||||||
|
set((state) => {
|
||||||
|
state.myModels = res;
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}),
|
||||||
|
setMyModels(data: ModelType[]) {
|
||||||
|
set((state) => {
|
||||||
|
state.myModels = data;
|
||||||
|
});
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user