Commit bd718020 authored by 文旺-丰林-DEV's avatar 文旺-丰林-DEV

add websocket

parent b2203c5d
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
"@ant-design/icons": "^4.7.0", "@ant-design/icons": "^4.7.0",
"@ant-design/pro-components": "1.1.1", "@ant-design/pro-components": "1.1.1",
"@umijs/route-utils": "^2.0.0", "@umijs/route-utils": "^2.0.0",
"ahooks": "^3.7.6",
"antd": "^4.20.0", "antd": "^4.20.0",
"classnames": "^2.3.0", "classnames": "^2.3.0",
"lodash": "^4.17.0", "lodash": "^4.17.0",
...@@ -100,4 +101,4 @@ ...@@ -100,4 +101,4 @@
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
} }
} }
\ No newline at end of file
...@@ -6,13 +6,13 @@ import classNames from 'classnames'; ...@@ -6,13 +6,13 @@ import classNames from 'classnames';
interface IAnswerProps { interface IAnswerProps {
answerValue: string; answerValue: string;
loading: boolean
isShowRetry?: boolean; isShowRetry?: boolean;
} }
const { useBreakpoint } = Grid; const { useBreakpoint } = Grid;
const Answer = (props: IAnswerProps) => { const Answer = (props: IAnswerProps) => {
<<<<<<< Updated upstream
const { answerValue, loading, isShowRetry } = props const { answerValue, loading, isShowRetry } = props
...@@ -20,6 +20,9 @@ const Answer = (props: IAnswerProps) => { ...@@ -20,6 +20,9 @@ const Answer = (props: IAnswerProps) => {
const isMobile = screens.xs; const isMobile = screens.xs;
console.log('isMobile', isMobile) console.log('isMobile', isMobile)
=======
const { answerValue, isShowRetry } = props;
>>>>>>> Stashed changes
return ( return (
<div> <div>
...@@ -28,6 +31,7 @@ const Answer = (props: IAnswerProps) => { ...@@ -28,6 +31,7 @@ const Answer = (props: IAnswerProps) => {
<span className={classNames(isMobile && styles.mobile_question_span, styles.question_span)} style={{ marginLeft: isMobile ? '8px' : '16px' }}>回答如下:</span> <span className={classNames(isMobile && styles.mobile_question_span, styles.question_span)} style={{ marginLeft: isMobile ? '8px' : '16px' }}>回答如下:</span>
</p> </p>
<div className={styles.chat}> <div className={styles.chat}>
<<<<<<< Updated upstream
<div className={classNames(styles.answer, isMobile && styles.mobile_answer)}> <div className={classNames(styles.answer, isMobile && styles.mobile_answer)}>
{ {
!isMobile && !isMobile &&
...@@ -46,6 +50,23 @@ const Answer = (props: IAnswerProps) => { ...@@ -46,6 +50,23 @@ const Answer = (props: IAnswerProps) => {
{ {
isShowRetry && !isMobile && <Button className={styles.chat_retry}>重试</Button> isShowRetry && !isMobile && <Button className={styles.chat_retry}>重试</Button>
} }
=======
<div>
<p className={styles.copyAnswer} onClick={() => {}}>
<img src={copySvg} alt="" />
<span>复制回答</span>
</p>
<div className={styles.answer}>
{!answerValue ? (
<p>请耐心等待3-5秒~</p>
) : (
<p dangerouslySetInnerHTML={{ __html: answerValue }}></p>
)}
</div>
</div>
{isShowRetry && <Button>重试</Button>}
>>>>>>> Stashed changes
</div> </div>
{ {
isMobile && isMobile &&
...@@ -63,6 +84,6 @@ const Answer = (props: IAnswerProps) => { ...@@ -63,6 +84,6 @@ const Answer = (props: IAnswerProps) => {
} }
</div> </div>
); );
} };
export default Answer; export default Answer;
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
.newSession { .newSession {
width: 1000px; width: 1000px;
margin-top: 40px;
.question { .question {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
...@@ -24,11 +25,21 @@ ...@@ -24,11 +25,21 @@
width: 26px; width: 26px;
height: 26px; height: 26px;
} }
<<<<<<< Updated upstream
.question_span { .question_span {
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
line-height: 26px; line-height: 26px;
color: #333333; color: #333333;
=======
span {
height: 28px;
margin-left: 16px;
color: #333333;
font-weight: 600;
font-size: 20px;
line-height: 26px;
>>>>>>> Stashed changes
} }
} }
...@@ -46,8 +57,8 @@ ...@@ -46,8 +57,8 @@
min-height: 268px; min-height: 268px;
.copyAnswer { .copyAnswer {
position: absolute; position: absolute;
bottom: 0;
right: 16px; right: 16px;
bottom: 0;
z-index: 2; z-index: 2;
cursor: pointer; cursor: pointer;
img { img {
...@@ -55,35 +66,51 @@ ...@@ -55,35 +66,51 @@
height: 24px; height: 24px;
} }
span { span {
color: #009B95;
line-height: 20px;
height: 24px; height: 24px;
color: #009b95;
font-size: 14px; font-size: 14px;
line-height: 20px;
} }
} }
<<<<<<< Updated upstream
.answerValue { .answerValue {
padding: 16px; padding: 16px;
=======
.answer {
width: 900px;
min-height: 268px;
margin-left: 28px;
color: rgba(0, 0, 0, 0.85);
font-size: 18px;
line-height: 32px;
background: #f0f3f6;
border-radius: 4px;
p {
padding: 16px;
}
>>>>>>> Stashed changes
} }
} }
.chat_retry { .chat_retry {
width: 90px; width: 90px;
height: 48px; height: 48px;
background: #FFFFFF;
border-radius: 6px;
border: 1px solid #009B95;
margin-left: 10px; margin-left: 10px;
background: #ffffff;
border: 1px solid #009b95;
border-radius: 6px;
span { span {
width: 40px; width: 40px;
height: 28px; height: 28px;
color: #009b95;
font-weight: 400;
font-size: 20px; font-size: 20px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #009B95;
line-height: 28px; line-height: 28px;
} }
} }
} }
<<<<<<< Updated upstream
.mobile_button { .mobile_button {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
...@@ -114,4 +141,7 @@ ...@@ -114,4 +141,7 @@
color: #009B95; color: #009B95;
} }
} }
} }
\ No newline at end of file =======
}
>>>>>>> Stashed changes
...@@ -12,13 +12,13 @@ interface INewSessionProps { ...@@ -12,13 +12,13 @@ interface INewSessionProps {
const { useBreakpoint } = Grid; const { useBreakpoint } = Grid;
const NewSession = (props: INewSessionProps) => { const NewSession = (props: INewSessionProps) => {
const { questionValue, answerValue } = props; const { questionValue, answerValue } = props;
const screens = useBreakpoint(); const screens = useBreakpoint();
const isMobile = screens.xs; const isMobile = screens.xs;
return ( return (
<<<<<<< Updated upstream
<div className={classNames(isMobile && styles.mobile_newSession, styles.newSession)}> <div className={classNames(isMobile && styles.mobile_newSession, styles.newSession)}>
<Issue <Issue
questionValue={questionValue} questionValue={questionValue}
...@@ -48,8 +48,13 @@ const NewSession = (props: INewSessionProps) => { ...@@ -48,8 +48,13 @@ const NewSession = (props: INewSessionProps) => {
answerValue={answerValue} answerValue={answerValue}
loading loading
/> />
=======
<div className={styles.newSession}>
<Issue questionValue={questionValue} />
<Answer answerValue={answerValue} />
>>>>>>> Stashed changes
</div> </div>
); );
} };
export default NewSession; export default NewSession;
\ No newline at end of file
...@@ -61,3 +61,9 @@ ol { ...@@ -61,3 +61,9 @@ ol {
min-height: 100vh; min-height: 100vh;
} }
} }
::-webkit-scrollbar {
width: 2px !important;
background-color: #009b95 !important;
border-radius: 4px;
}
export default { export default {
'menu.chat': 'ChatGLM',
'menu.welcome': '欢迎', 'menu.welcome': '欢迎',
'menu.more-blocks': '更多区块', 'menu.more-blocks': '更多区块',
'menu.home': '首页', 'menu.home': '首页',
......
@import (reference) '~antd/es/style/themes/index'; @import (reference) '~antd/es/style/themes/index';
.chatContent { .chatContent {
background: white !important; background: white !important;
} }
.siderWrapper { .siderWrapper {
background: white; background: white;
.sider { .sider {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
z-index: 100; z-index: 100;
width: 240px; width: 240px;
min-height: 100vh; min-height: 100vh;
padding: 30px 20px; padding: 30px 20px;
background-color: #001529; background-color: #001529;
.siderChatContent { .siderChatContent {
height: 70%; height: 70%;
min-height: 400px; min-height: 400px;
:global(.ant-btn-primary) { :global(.ant-btn-primary) {
background: #009b95; background: #009b95;
border: solid 1px #009b95; border: solid 1px #009b95;
border-radius: 2px; border-radius: 2px;
} }
} }
} }
} }
.header { .header {
margin-top: 68px; margin-top: 68px;
color: #333; color: #333;
font-size: 32px; font-size: 32px;
line-height: 45px; line-height: 45px;
text-align: center; text-align: center;
.subTitle { .subTitle {
color: #999999; color: #999999;
font-weight: 400; font-weight: 400;
} }
} }
.chatSiderChatTabsCard { .chatSiderChatTabsCard {
display: flex; display: flex;
margin-top: 40px; margin-top: 40px;
color: white; color: white;
font-size: 18px; font-size: 18px;
cursor: pointer; cursor: pointer;
transition: all 0.15s; transition: all 0.15s;
.chatSiderChatTabsCardIcons { .chatSiderChatTabsCardIcons {
width: 18px; width: 18px;
height: 18px; height: 18px;
margin-right: 12px; margin-right: 12px;
} }
.checkedChatSiderChatTabsCardIcons { .checkedChatSiderChatTabsCardIcons {
svg { svg {
color: #009b95 !important; color: #009b95 !important;
} }
} }
.checkedChatSiderChatTabsCardText { .checkedChatSiderChatTabsCardText {
color: #009b95 !important; color: #009b95 !important;
} }
.chatSiderChatTabsCardText { .chatSiderChatTabsCardText {
flex: 1; flex: 1;
width: 108px; width: 108px;
height: 26px; height: 26px;
color: #ffffff; color: #ffffff;
font-weight: 400; font-weight: 400;
font-size: 18px; font-size: 18px;
font-family: PingFangSC-Regular, PingFang SC; font-family: PingFangSC-Regular, PingFang SC;
} }
} }
.footer { .footer {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; z-index: 10;
height: 150px; width: 100%;
padding: 16px; height: 150px;
background-color: white; padding: 16px;
box-shadow: 0 2px 8px #f0f1f2; overflow: hidden;
.chatWrapper { background-color: white;
padding: 0 16px 0 50px; box-shadow: 0 2px 8px #f0f1f2;
:global { .chatWrapper {
.ant-input:focus, padding: 0 16px 0 50px;
.ant-input:hover, :global {
.ant-input-focused { .ant-input:focus,
border-color: #009b95; .ant-input:hover,
} .ant-input-focused {
.ant-input:focus, border-color: #009b95;
.ant-input-focused { }
box-shadow: 0 0 0 2px #009b95; .ant-input:focus,
} .ant-input-focused {
} box-shadow: 0 0 0 2px #009b95;
} }
.outputButtonWrapper { }
width: 120px; }
:global(.ant-btn-primary) { .outputButtonWrapper {
background: #009b95; width: 120px;
border: solid 1px #009b95; :global(.ant-btn-primary) {
} background: #009b95;
} border: solid 1px #009b95;
} }
}
.mobileHeader { }
position: fixed;
top: 0; .mobileHeader {
left: 0; position: fixed;
z-index: 99; top: 0;
width: 100%; left: 0;
height: 44px; z-index: 99;
color: white; width: 100%;
font-size: 15px; height: 44px;
background-color: #009b95; color: white;
} font-size: 15px;
.mobileContent { background-color: #009b95;
padding-top: 68px; }
} .mobileContent {
padding-top: 68px;
}
/* eslint-disable @typescript-eslint/no-unused-expressions */ /* eslint-disable @typescript-eslint/no-unused-expressions */
import { Form, Button, Col, Row, Input, Typography, Grid } from 'antd'; import { Form, Button, Col, Row, Input, Typography, Grid, message } from 'antd';
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, useRef, useMemo } from 'react';
import styles from './index.less'; import styles from './index.less';
import ChatFirstContent from './components/content'; import ChatFirstContent from './components/content';
import { import {
FieldTimeOutlined, FieldTimeOutlined,
MenuOutlined, MenuOutlined,
PlusOutlined, PlusOutlined,
SettingOutlined, SettingOutlined,
UserOutlined, UserOutlined,
WechatOutlined, WechatOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import classNames from 'classnames'; import classNames from 'classnames';
import { history } from 'umi'; import { history } from 'umi';
import LoginModal from '@/components/loginModal'; import LoginModal from '@/components/loginModal';
import NewSession from '@/components/newSession'; import NewSession from '@/components/newSession';
import { useWebSocket, useRequest } from 'ahooks';
const { useBreakpoint } = Grid; import { GetChatGLMToken } from '@/services/chatGLM/api';
const { Title } = Typography;
const { Item } = Form; const { useBreakpoint } = Grid;
const { Title } = Typography;
const Chat: React.FC = () => { const { Item } = Form;
const screens = useBreakpoint();
const isMobile = screens.xs; interface IHistory {
const [chat, setChat] = useState(''); prompt: string;
const [showSider, setShowSider] = useState(true); answer: string;
const [firstChat, setFirstChat] = useState(false); }
const [form] = Form.useForm();
const [selectSiderTabs, setSelectSiderTabs] = useState(''); const Chat: React.FC = () => {
const screens = useBreakpoint();
const [open, setOpen] = useState(false); const isMobile = screens.xs;
const tabShow = showSider; const [chat, setChat] = useState('');
const [showSider, setShowSider] = useState(true);
const questionValue = form.getFieldValue('chatInput'); const [firstChat, setFirstChat] = useState(false);
const [form] = Form.useForm();
useEffect(() => { const [selectSiderTabs, setSelectSiderTabs] = useState('');
if (!isMobile) { const { data: glmToken } = useRequest(GetChatGLMToken);
setShowSider(true); const [answer, setAnswer] = useState('');
} const messageHistory = useRef<IHistory[]>([]);
}, [isMobile]); const { sendMessage } = useWebSocket('wss://glm-api.baibaomen.com/ws', {
onMessage: (event) => {
let token = ''; const text = event.data;
useEffect(() => { if (text == '{{BBMCPLT}}') {
if (localStorage.getItem('user')) { } else {
token = JSON.parse(localStorage.user)?.token; setAnswer(text);
} window.scrollTo(0, document.body.scrollHeight);
if (token) { }
setOpen(false); },
} else { onOpen: () => {
setOpen(true); console.log('连接成功!');
} },
}, []); onError: () => {
message.error('连接失败了,请稍后再试!');
const onSend = () => { },
form.setFieldValue('chatInput', ''); });
setFirstChat(true);
}; messageHistory.current = useMemo(() => {
if (messageHistory.current.length > 0)
const setInput = (value: any) => { messageHistory.current[messageHistory.current.length - 1].answer += answer;
setChat(value?.firstInput); return messageHistory.current;
form.setFieldValue('chatInput', value?.firstInput); }, [answer]);
}; async function handleSendMessage() {
sendMessage &&
const onChange = (value: any) => { sendMessage(
value?.chatInput && setChat(value?.chatInput); JSON.stringify({
value?.firstInput && setInput(value); prompt: chat,
}; max_length: 2048,
top_p: 0.7,
const siderTabsList = [ temperature: 0.95,
{ history: [messageHistory.current.map((h) => h.prompt)],
icons: <SettingOutlined />, token: glmToken,
text: '后台', }),
checked: 'gotoAdmin', );
}, messageHistory.current.push({ prompt: chat, answer: '' });
{ }
icons: <WechatOutlined />,
text: '活动交流群', const [open, setOpen] = useState(false);
checked: 'wechat', const tabShow = showSider;
},
{ useEffect(() => {
icons: <UserOutlined />, if (!isMobile) {
text: '游客登录', setShowSider(true);
checked: 'noMentionLogin', }
}, }, [isMobile]);
];
let token = '';
const selectSliderTabsHandleClick = (value: string) => { useEffect(() => {
setSelectSiderTabs(value); if (localStorage.getItem('user')) {
if (value === 'gotoAdmin') { token = JSON.parse(localStorage.user)?.token;
history.push('/admin/user'); }
} if (token) {
}; setOpen(false);
} else {
const renderMobileHeader = () => { setOpen(true);
return ( }
<Row align={'middle'} justify="space-between" gutter={1} className={styles.mobileHeader}> }, []);
<Col push={1}>
<MenuOutlined const onSend = () => {
onClick={() => { form.setFieldValue('chatInput', '');
setShowSider(!showSider); setFirstChat(true);
}} handleSendMessage();
/> };
</Col>
<Col>AI改变世界</Col> const setInput = (value: any) => {
<Col pull={1}> setChat(value?.firstInput);
<FieldTimeOutlined /> form.setFieldValue('chatInput', value?.firstInput);
</Col> };
</Row>
); const onChange = (value: any) => {
}; value?.chatInput && setChat(value?.chatInput);
value?.firstInput && setInput(value);
return ( };
<>
<LoginModal open={open} setOpen={setOpen} /> const siderTabsList = [
{isMobile && renderMobileHeader()} {
<Row> icons: <SettingOutlined />,
{tabShow && ( text: '后台',
<Col span={4} sm={10} md={7} xs={12} lg={5} className={styles.siderWrapper}> checked: 'gotoAdmin',
<div style={{ top: isMobile && '44px' }} className={styles.sider}> },
<div className={styles.siderChatContent}> {
<Button size="large" block type="primary" icon={<PlusOutlined />}> icons: <WechatOutlined />,
新建对话 text: '活动交流群',
</Button> checked: 'wechat',
</div> },
<Row> {
{siderTabsList.map((item) => { icons: <UserOutlined />,
return ( text: '游客登录',
<Col key={item.text}> checked: 'noMentionLogin',
<div },
className={styles.chatSiderChatTabsCard} ];
onClick={() => {
selectSliderTabsHandleClick(item.checked); const selectSliderTabsHandleClick = (value: string) => {
}} setSelectSiderTabs(value);
> if (value === 'gotoAdmin') {
<div history.push('/admin/user');
className={classNames( }
styles.chatSiderChatTabsCardIcons, };
selectSiderTabs === item.checked &&
styles.checkedChatSiderChatTabsCardIcons, const renderMobileHeader = () => {
)} return (
> <Row align={'middle'} justify="space-between" gutter={1} className={styles.mobileHeader}>
{item.icons} <Col push={1}>
</div> <MenuOutlined
<div onClick={() => {
className={classNames( setShowSider(!showSider);
styles.chatSiderChatTabsCardText, }}
selectSiderTabs === item.checked && />
styles.checkedChatSiderChatTabsCardText, </Col>
)} <Col>AI改变世界</Col>
> <Col pull={1}>
{item.text} <FieldTimeOutlined />
</div> </Col>
</div> </Row>
</Col> );
); };
})}
</Row> return (
</div> <>
</Col> <LoginModal open={open} setOpen={setOpen} />
)} {isMobile && renderMobileHeader()}
<Col <Row>
className={styles.chatContent} {tabShow && (
span={20} <Col span={4} sm={10} md={7} xs={12} lg={5} className={styles.siderWrapper}>
lg={19} <div style={{ top: isMobile && '44px' }} className={styles.sider}>
sm={14} <div className={styles.siderChatContent}>
md={17} <Button size="large" block type="primary" icon={<PlusOutlined />}>
xs={isMobile ? 24 : 12} 新建对话
> </Button>
{!isMobile && ( </div>
<div className={styles.header}> <Row>
<Row> {siderTabsList.map((item) => {
<Col span={24}> return (
<Title level={1}>产品名称</Title> <Col key={item.text}>
</Col> <div
<Col span={24}> className={styles.chatSiderChatTabsCard}
<Title level={5} className={styles.subTitle}> onClick={() => {
AI改变世界 selectSliderTabsHandleClick(item.checked);
</Title> }}
</Col> >
</Row> <div
</div> className={classNames(
)} styles.chatSiderChatTabsCardIcons,
<Form selectSiderTabs === item.checked &&
form={form} styles.checkedChatSiderChatTabsCardIcons,
initialValues={{ chatInput: chat }} )}
name="chat" >
onValuesChange={onChange} {item.icons}
onFinish={onSend} </div>
> <div
{firstChat ? ( className={classNames(
<NewSession questionValue={chat} answerValue="" /> styles.chatSiderChatTabsCardText,
) : ( selectSiderTabs === item.checked &&
<div className={classNames(isMobile && styles.mobileContent)}> styles.checkedChatSiderChatTabsCardText,
<Item name="firstInput"> )}
<ChatFirstContent /> >
</Item> {item.text}
</div> </div>
)} </div>
<div className={styles.footer}> </Col>
<Row> );
<Col span={isMobile ? 20 : 16} push={isMobile ? 0 : 4}> })}
<div style={{ paddingLeft: isMobile && 0 }} className={styles.chatWrapper}> </Row>
<Item name="chatInput"> </div>
<Input </Col>
placeholder="在这里输入你想知道的问题,给我几句提示,我来帮你回答" )}
size="large" <Col
/> className={styles.chatContent}
</Item> span={20}
</div> lg={19}
</Col> sm={14}
<Col span={4} push={isMobile ? 0 : 4}> md={17}
<div className={styles.outputButtonWrapper}> xs={isMobile ? 24 : 12}
<Item name="outputButton"> >
<Button htmlType="submit" type="primary" size="large"> {!isMobile && (
发送 <div className={styles.header} hidden={firstChat}>
</Button> <Row>
</Item> <Col span={24}>
</div> <Title level={1}>产品名称</Title>
</Col> </Col>
</Row> <Col span={24}>
</div> <Title level={5} className={styles.subTitle}>
</Form> AI改变世界
</Col> </Title>
</Row> </Col>
</> </Row>
); </div>
}; )}
<Form
export default Chat; form={form}
initialValues={{ chatInput: chat }}
name="chat"
onValuesChange={onChange}
onFinish={onSend}
>
{firstChat ? (
<div style={{ overflowY: 'scroll', marginBottom: 150 }}>
{messageHistory.current.map((item, index) => (
<NewSession
key={'new' + index}
questionValue={item.prompt}
answerValue={item.answer}
/>
))}
</div>
) : (
<div className={classNames(isMobile && styles.mobileContent)}>
<Item name="firstInput">
<ChatFirstContent />
</Item>
</div>
)}
<div className={styles.footer}>
<Row>
<Col span={isMobile ? 20 : 16} push={isMobile ? 0 : 4}>
<div style={{ paddingLeft: isMobile && 0 }} className={styles.chatWrapper}>
<Item name="chatInput">
<Input
placeholder="在这里输入你想知道的问题,给我几句提示,我来帮你回答"
size="large"
/>
</Item>
</div>
</Col>
<Col span={4} push={isMobile ? 0 : 4}>
<div className={styles.outputButtonWrapper}>
<Item name="outputButton">
<Button htmlType="submit" type="primary" size="large">
发送
</Button>
</Item>
</div>
</Col>
</Row>
</div>
</Form>
</Col>
</Row>
</>
);
};
export default Chat;
import { useWebSocket } from 'ahooks';
import { Button, Col, Row, message } from 'antd';
import Input from 'rc-input';
import { useMemo, useRef, useEffect, useState } from 'react';
enum ReadyState {
Connecting = 0,
Open = 1,
Closing = 2,
Closed = 3,
}
interface IHistory {
prompt: string;
answer: string;
}
const Test = () => {
const [prompt, setPrompt] = useState<string>('你好');
const [loading, setLoading] = useState(true);
const [answer, setAnswer] = useState('');
const messageHistory = useRef<IHistory[]>([]);
const { sendMessage } = useWebSocket('wss://glm-api.baibaomen.com/ws', {
onMessage: (event) => {
const text = event.data;
if (text == '{{BBMCPLT}}') {
} else {
setAnswer(text);
}
},
onOpen: () => {
setLoading(false);
console.log('连接成功!');
},
onError: (e) => {
message.error('连接失败了,请稍后再试!');
},
});
// useEffect(() => {
// console.log(readyState);
// if (readyState !== ReadyState.Open) {
// connect && connect();
// }
// return () => {
// disconnect && disconnect();
// };
// }, []);
messageHistory.current = useMemo(() => {
if (messageHistory.current.length > 0)
messageHistory.current[messageHistory.current.length - 1].answer += answer;
console.log(messageHistory.current);
return messageHistory.current;
}, [answer]);
function handleSendMessage() {
sendMessage &&
sendMessage(
JSON.stringify({
prompt: prompt,
max_length: 2048,
top_p: 0.7,
temperature: 0.95,
history: [messageHistory.current.map((h) => h.prompt)],
token: 'Uicm6VMjVPdzepbqnwNvpl25xJjRxFekMV8QZdeTLTwacNBl',
}),
);
messageHistory.current.push({ prompt: prompt, answer: '' });
}
return (
<>
<Input
placeholder=""
value={prompt}
onChange={(e) => {
setPrompt(e.target.value);
}}
/>
<Button onClick={handleSendMessage} loading={loading}>
发送
</Button>
{messageHistory.current.map((item, index) => (
<Row key={'message-' + index}>
<Col span={24}>{item.prompt}</Col>
<Col span={24} dangerouslySetInnerHTML={{ __html: item.answer }}></Col>
</Row>
))}
</>
);
};
export default Test;
...@@ -10,7 +10,7 @@ interface ILoginParams { ...@@ -10,7 +10,7 @@ interface ILoginParams {
// if (null === token) { // if (null === token) {
// token = ''; // token = '';
// } // }
// const authHeader = { // const authHeader = {
// Authorization: `Bearer ${token}`, // Authorization: `Bearer ${token}`,
// 'Content-Type': 'application/json', // 'Content-Type': 'application/json',
// '__tenant': '3a0a90fe-9a0d-70f4-200d-a80a41fb6195' // 用户id // '__tenant': '3a0a90fe-9a0d-70f4-200d-a80a41fb6195' // 用户id
...@@ -26,10 +26,17 @@ export function loginChatGLM(options: ILoginParams) { ...@@ -26,10 +26,17 @@ export function loginChatGLM(options: ILoginParams) {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'__tenant': '3a0a90fe-9a0d-70f4-200d-a80a41fb6195' __tenant: '3a0a90fe-9a0d-70f4-200d-a80a41fb6195',
}, },
data: options data: options,
}) });
}
export function GetChatGLMToken(): Promise<string> {
return request('https://glm-mangement-api.baibaomen.com/user/token', {
method: 'POST',
headers: { Authorization: 'Bearer ' + JSON.parse(localStorage.getItem('user') || '')?.token },
});
} }
type History = [string, string]; type History = [string, string];
...@@ -52,4 +59,4 @@ interface ITalkParams { ...@@ -52,4 +59,4 @@ interface ITalkParams {
// temperature // temperature
// } // }
// }) // })
// } // }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment