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

add websocket

parent b2203c5d
......@@ -50,6 +50,7 @@
"@ant-design/icons": "^4.7.0",
"@ant-design/pro-components": "1.1.1",
"@umijs/route-utils": "^2.0.0",
"ahooks": "^3.7.6",
"antd": "^4.20.0",
"classnames": "^2.3.0",
"lodash": "^4.17.0",
......@@ -100,4 +101,4 @@
"engines": {
"node": ">=12.0.0"
}
}
\ No newline at end of file
}
......@@ -6,13 +6,13 @@ import classNames from 'classnames';
interface IAnswerProps {
answerValue: string;
loading: boolean
isShowRetry?: boolean;
}
const { useBreakpoint } = Grid;
const Answer = (props: IAnswerProps) => {
<<<<<<< Updated upstream
const { answerValue, loading, isShowRetry } = props
......@@ -20,6 +20,9 @@ const Answer = (props: IAnswerProps) => {
const isMobile = screens.xs;
console.log('isMobile', isMobile)
=======
const { answerValue, isShowRetry } = props;
>>>>>>> Stashed changes
return (
<div>
......@@ -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>
</p>
<div className={styles.chat}>
<<<<<<< Updated upstream
<div className={classNames(styles.answer, isMobile && styles.mobile_answer)}>
{
!isMobile &&
......@@ -46,6 +50,23 @@ const Answer = (props: IAnswerProps) => {
{
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>
{
isMobile &&
......@@ -63,6 +84,6 @@ const Answer = (props: IAnswerProps) => {
}
</div>
);
}
};
export default Answer;
\ No newline at end of file
export default Answer;
......@@ -17,6 +17,7 @@
.newSession {
width: 1000px;
margin-top: 40px;
.question {
display: flex;
align-items: flex-start;
......@@ -24,11 +25,21 @@
width: 26px;
height: 26px;
}
<<<<<<< Updated upstream
.question_span {
font-size: 20px;
font-weight: 600;
line-height: 26px;
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 @@
min-height: 268px;
.copyAnswer {
position: absolute;
bottom: 0;
right: 16px;
bottom: 0;
z-index: 2;
cursor: pointer;
img {
......@@ -55,35 +66,51 @@
height: 24px;
}
span {
color: #009B95;
line-height: 20px;
height: 24px;
color: #009b95;
font-size: 14px;
line-height: 20px;
}
}
<<<<<<< Updated upstream
.answerValue {
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 {
width: 90px;
height: 48px;
background: #FFFFFF;
border-radius: 6px;
border: 1px solid #009B95;
margin-left: 10px;
background: #ffffff;
border: 1px solid #009b95;
border-radius: 6px;
span {
width: 40px;
height: 28px;
color: #009b95;
font-weight: 400;
font-size: 20px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #009B95;
line-height: 28px;
}
}
}
<<<<<<< Updated upstream
.mobile_button {
display: flex;
justify-content: space-around;
......@@ -114,4 +141,7 @@
color: #009B95;
}
}
}
\ No newline at end of file
}
=======
}
>>>>>>> Stashed changes
......@@ -12,13 +12,13 @@ interface INewSessionProps {
const { useBreakpoint } = Grid;
const NewSession = (props: INewSessionProps) => {
const { questionValue, answerValue } = props;
const screens = useBreakpoint();
const isMobile = screens.xs;
return (
<<<<<<< Updated upstream
<div className={classNames(isMobile && styles.mobile_newSession, styles.newSession)}>
<Issue
questionValue={questionValue}
......@@ -48,8 +48,13 @@ const NewSession = (props: INewSessionProps) => {
answerValue={answerValue}
loading
/>
=======
<div className={styles.newSession}>
<Issue questionValue={questionValue} />
<Answer answerValue={answerValue} />
>>>>>>> Stashed changes
</div>
);
}
};
export default NewSession;
\ No newline at end of file
export default NewSession;
......@@ -61,3 +61,9 @@ ol {
min-height: 100vh;
}
}
::-webkit-scrollbar {
width: 2px !important;
background-color: #009b95 !important;
border-radius: 4px;
}
export default {
'menu.chat': 'ChatGLM',
'menu.welcome': '欢迎',
'menu.more-blocks': '更多区块',
'menu.home': '首页',
......
@import (reference) '~antd/es/style/themes/index';
.chatContent {
background: white !important;
}
.siderWrapper {
background: white;
.sider {
position: fixed;
top: 0;
left: 0;
z-index: 100;
width: 240px;
min-height: 100vh;
padding: 30px 20px;
background-color: #001529;
.siderChatContent {
height: 70%;
min-height: 400px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
border-radius: 2px;
}
}
}
}
.header {
margin-top: 68px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
color: #999999;
font-weight: 400;
}
}
.chatSiderChatTabsCard {
display: flex;
margin-top: 40px;
color: white;
font-size: 18px;
cursor: pointer;
transition: all 0.15s;
.chatSiderChatTabsCardIcons {
width: 18px;
height: 18px;
margin-right: 12px;
}
.checkedChatSiderChatTabsCardIcons {
svg {
color: #009b95 !important;
}
}
.checkedChatSiderChatTabsCardText {
color: #009b95 !important;
}
.chatSiderChatTabsCardText {
flex: 1;
width: 108px;
height: 26px;
color: #ffffff;
font-weight: 400;
font-size: 18px;
font-family: PingFangSC-Regular, PingFang SC;
}
}
.footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 150px;
padding: 16px;
background-color: white;
box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper {
padding: 0 16px 0 50px;
:global {
.ant-input:focus,
.ant-input:hover,
.ant-input-focused {
border-color: #009b95;
}
.ant-input:focus,
.ant-input-focused {
box-shadow: 0 0 0 2px #009b95;
}
}
}
.outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
}
}
}
.mobileHeader {
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100%;
height: 44px;
color: white;
font-size: 15px;
background-color: #009b95;
}
.mobileContent {
padding-top: 68px;
}
@import (reference) '~antd/es/style/themes/index';
.chatContent {
background: white !important;
}
.siderWrapper {
background: white;
.sider {
position: fixed;
top: 0;
left: 0;
z-index: 100;
width: 240px;
min-height: 100vh;
padding: 30px 20px;
background-color: #001529;
.siderChatContent {
height: 70%;
min-height: 400px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
border-radius: 2px;
}
}
}
}
.header {
margin-top: 68px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
color: #999999;
font-weight: 400;
}
}
.chatSiderChatTabsCard {
display: flex;
margin-top: 40px;
color: white;
font-size: 18px;
cursor: pointer;
transition: all 0.15s;
.chatSiderChatTabsCardIcons {
width: 18px;
height: 18px;
margin-right: 12px;
}
.checkedChatSiderChatTabsCardIcons {
svg {
color: #009b95 !important;
}
}
.checkedChatSiderChatTabsCardText {
color: #009b95 !important;
}
.chatSiderChatTabsCardText {
flex: 1;
width: 108px;
height: 26px;
color: #ffffff;
font-weight: 400;
font-size: 18px;
font-family: PingFangSC-Regular, PingFang SC;
}
}
.footer {
position: fixed;
bottom: 0;
left: 0;
z-index: 10;
width: 100%;
height: 150px;
padding: 16px;
overflow: hidden;
background-color: white;
box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper {
padding: 0 16px 0 50px;
:global {
.ant-input:focus,
.ant-input:hover,
.ant-input-focused {
border-color: #009b95;
}
.ant-input:focus,
.ant-input-focused {
box-shadow: 0 0 0 2px #009b95;
}
}
}
.outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
}
}
}
.mobileHeader {
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100%;
height: 44px;
color: white;
font-size: 15px;
background-color: #009b95;
}
.mobileContent {
padding-top: 68px;
}
This diff is collapsed.
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 {
// if (null === token) {
// token = '';
// }
// const authHeader = {
// const authHeader = {
// Authorization: `Bearer ${token}`,
// 'Content-Type': 'application/json',
// '__tenant': '3a0a90fe-9a0d-70f4-200d-a80a41fb6195' // 用户id
......@@ -26,10 +26,17 @@ export function loginChatGLM(options: ILoginParams) {
method: 'POST',
headers: {
'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];
......@@ -52,4 +59,4 @@ interface ITalkParams {
// 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