Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
C
chatGLM
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
刘坚-丰林-DEV
chatGLM
Commits
4b431dc7
Commit
4b431dc7
authored
Apr 16, 2023
by
littleforest
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://gitlab.baibaomen.com/jian.liu/chatgml
parents
ce56df68
06cce791
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
441 additions
and
419 deletions
+441
-419
answer.component.tsx
src/components/newSession/answer.component.tsx
+42
-51
index.less
src/components/newSession/index.less
+31
-12
index.tsx
src/components/newSession/index.tsx
+10
-6
issue.component.tsx
src/components/newSession/issue.component.tsx
+9
-13
global.less
src/global.less
+5
-0
content.less
src/pages/Chat/components/content.less
+0
-3
content.tsx
src/pages/Chat/components/content.tsx
+50
-94
productionCard.less
src/pages/Chat/components/productionCard.less
+53
-47
productionCard.tsx
src/pages/Chat/components/productionCard.tsx
+32
-31
index.less
src/pages/Chat/index.less
+24
-7
index.tsx
src/pages/Chat/index.tsx
+143
-136
api.ts
src/services/chatGLM/api.ts
+42
-19
No files found.
src/components/newSession/answer.component.tsx
View file @
4b431dc7
import
logoSvg
from
'../../assets/logo.svg'
;
import
copySvg
from
'../../assets/copy.svg'
;
import
{
Button
,
Grid
}
from
'antd'
;
import
{
Button
,
Col
,
Grid
,
Row
}
from
'antd'
;
import
styles
from
'./index.less'
;
import
classNames
from
'classnames'
;
interface
IAnswerProps
{
answerValue
:
string
;
...
...
@@ -17,60 +18,50 @@ const Answer = (props: IAnswerProps) => {
const
isMobile
=
screens
.
xs
;
return
(
<
div
>
<
p
className=
{
styles
.
question
}
style=
{
{
marginTop
:
isMobile
?
'20px'
:
'40px'
}
}
>
<
img
src=
{
logoSvg
}
alt=
""
className=
{
styles
.
question_img
}
/>
<
span
className=
{
styles
.
question_span
}
style=
{
{
marginLeft
:
isMobile
?
'8px'
:
'16px'
,
fontSize
:
isMobile
?
'18px'
:
'20px'
,
}
}
>
回答如下:
</
span
>
</
p
>
<
div
className=
{
styles
.
chat
}
>
<
div
className=
{
styles
.
answer
}
style=
{
{
width
:
isMobile
?
'316px'
:
'900px'
,
fontSize
:
isMobile
?
'16px'
:
'18px'
,
lineHeight
:
isMobile
?
'28px'
:
'32px'
,
}
}
>
{
!
isMobile
&&
<
p
className=
{
styles
.
copyAnswer
}
onClick=
{
()
=>
{
}
}
>
<
Col
span=
{
24
}
>
<
Row
>
<
Col
span=
{
24
}
>
<
p
className=
{
styles
.
question
}
style=
{
{
marginTop
:
isMobile
?
'20px'
:
'40px'
}
}
>
<
img
src=
{
logoSvg
}
alt=
""
className=
{
styles
.
question_img
}
/>
<
span
className=
{
classNames
(
isMobile
&&
styles
.
mobile_question_span
,
styles
.
question_span
)
}
style=
{
{
marginLeft
:
isMobile
?
'8px'
:
'16px'
}
}
>
回答如下:
</
span
>
</
p
>
</
Col
>
<
Col
span=
{
24
}
className=
{
styles
.
chat
}
>
<
div
className=
{
classNames
(
styles
.
answer
,
isMobile
&&
styles
.
mobile_answer
)
}
>
<
div
className=
{
styles
.
answer
}
>
{
!
answerValue
?
(
<
p
style=
{
{
color
:
'#666666'
}
}
>
请耐心等待3-5秒~
</
p
>
)
:
(
<
p
dangerouslySetInnerHTML=
{
{
__html
:
answerValue
}
}
></
p
>
)
}
</
div
>
{
!
isMobile
&&
answerValue
&&
(
<
p
className=
{
styles
.
copyAnswer
}
onClick=
{
()
=>
{}
}
>
<
img
src=
{
copySvg
}
alt=
""
/>
<
span
>
复制回答
</
span
>
</
p
>
}
{
!
answerValue
?
(
<
p
className=
{
styles
.
answerValue
}
>
请耐心等待3-5秒~
</
p
>
)
:
(
<
p
className=
{
styles
.
answerValue
}
dangerouslySetInnerHTML=
{
{
__html
:
answerValue
}
}
></
p
>
)
}
</
div
>
{
isShowRetry
&&
!
isMobile
&&
<
Button
className=
{
styles
.
chat_retry
}
>
重试
</
Button
>
}
</
Col
>
<
Col
>
{
isMobile
&&
answerValue
&&
(
<
Row
justify=
{
'center'
}
className=
{
styles
.
mobile_button
}
>
<
Button
className=
{
styles
.
mobile_copyAnswer
}
>
<
img
src=
{
copySvg
}
alt=
""
/>
<
span
>
复制回答
</
span
>
</
Button
>
<
Button
className=
{
styles
.
mobile_chat_retry
}
>
重试
</
Button
>
</
Row
>
)
}
</
div
>
{
isShowRetry
&&
!
isMobile
&&
<
Button
className=
{
styles
.
chat_retry
}
>
重试
</
Button
>
}
</
div
>
{
isMobile
&&
<
div
className=
{
styles
.
mobile_button
}
>
<
Button
className=
{
styles
.
mobile_copyAnswer
}
>
<
img
src=
{
copySvg
}
alt=
""
/>
<
span
>
复制回答
</
span
>
</
Button
>
<
Button
className=
{
styles
.
mobile_chat_retry
}
>
重试
</
Button
>
</
div
>
}
</
div
>
</
Col
>
</
Row
>
</
Col
>
);
};
...
...
src/components/newSession/index.less
View file @
4b431dc7
@import (reference) '~antd/es/style/themes/index';
.mobile_newSession {
width: 100% !important;
margin-top: 24px !important;
padding: 48px 16px 16px;
}
.mobile_question_span {
font-size: 18px !important;
}
.mobile_answer {
// width: 316px !important;
font-size: 16px !important;
line-height: 28px !important;
}
.newSession {
width: 1000px;
margin-top: 40px;
margin-top: 0px;
.question {
display: flex;
align-items: flex-start;
...
...
@@ -20,25 +35,28 @@
.chat {
display: flex;
width: 100vw;
padding-left: 28px;
// justify-content: center;
.answer {
position: relative;
width: 900px;
min-height: 268px;
margin-left: 28px;
width: 100%;
padding: 4px 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 1
8
px;
font-size: 1
6
px;
line-height: 32px;
white-space: pre-wrap;
word-wrap: break-word;
background: #f0f3f6;
border-radius: 4px;
.copyAnswer {
position: absolute;
right: 16px;
bottom: 0;
z-index: 2;
padding-right: 16px;
text-align: right;
cursor: pointer;
img {
width: 24px;
height: 24px;
padding-left: 2px;
}
span {
height: 24px;
...
...
@@ -55,7 +73,7 @@
.chat_retry {
width: 90px;
height: 48px;
margin-left: 10px;
//
margin-left: 10px;
background: #ffffff;
border: 1px solid #009b95;
border-radius: 6px;
...
...
@@ -74,7 +92,7 @@
display: flex;
justify-content: space-around;
margin-top: 16px;
margin-left: 2
4
px;
margin-left: 2
8
px;
.mobile_copyAnswer {
width: 151px;
height: 40px;
...
...
@@ -94,6 +112,7 @@
.mobile_chat_retry {
width: 151px;
height: 40px;
margin-left: 12px;
color: #009b95;
background: #ffffff;
border: 1px solid #009b95;
...
...
src/components/newSession/index.tsx
View file @
4b431dc7
import
styles
from
'./index.less'
;
import
Issue
from
'./issue.component'
;
import
Answer
from
'./answer.component'
;
import
{
Grid
}
from
'antd'
;
import
{
Grid
,
Row
}
from
'antd'
;
import
classNames
from
'classnames'
;
interface
INewSessionProps
{
questionValue
:
string
;
...
...
@@ -17,13 +18,16 @@ const NewSession = (props: INewSessionProps) => {
const
isMobile
=
screens
.
xs
;
return
(
<
div
className=
{
styles
.
newSession
}
style=
{
{
padding
:
isMobile
?
'4px 16px 16px'
:
'0'
,
width
:
isMobile
?
'100%'
:
'1000px'
}
}
>
<
Row
style=
{
{
padding
:
isMobile
?
''
:
'0 0 0 72px !important'
,
width
:
isMobile
?
'100vw'
:
'calc(100vw - 240px - 144px)'
,
}
}
className=
{
classNames
(
isMobile
&&
styles
.
mobile_newSession
,
styles
.
newSession
)
}
>
<
Issue
questionValue=
{
questionValue
}
/>
<
Answer
answerValue=
{
answerValue
}
/>
</
div
>
</
Row
>
);
};
...
...
src/components/newSession/issue.component.tsx
View file @
4b431dc7
import
classNames
from
'classnames'
;
import
userSvg
from
'../../assets/user.svg'
;
import
styles
from
'./index.less'
;
import
{
Grid
}
from
'antd'
;
import
{
Col
,
Grid
}
from
'antd'
;
interface
IIssueProps
{
questionValue
:
string
;
...
...
@@ -10,7 +10,6 @@ interface IIssueProps {
const
{
useBreakpoint
}
=
Grid
;
const
Issue
=
(
props
:
IIssueProps
)
=>
{
const
{
questionValue
}
=
props
;
const
screens
=
useBreakpoint
();
...
...
@@ -19,19 +18,16 @@ const Issue = (props: IIssueProps) => {
console
.
log
(
'isMobile'
,
isMobile
);
return
(
<
div
className=
{
styles
.
question
}
style=
{
{
marginTop
:
isMobile
?
'20px'
:
'40px'
}
}
>
<
img
src=
{
userSvg
}
alt=
""
className=
{
styles
.
question_img
}
/>
<
span
className=
{
styles
.
question_span
}
style=
{
{
marginLeft
:
isMobile
?
'8px'
:
'16px'
,
fontSize
:
isMobile
?
'18px'
:
'20px'
,
}
}
<
Col
span=
{
24
}
className=
{
styles
.
question
}
style=
{
{
marginTop
:
isMobile
?
'0px'
:
'40px'
}
}
>
<
img
src=
{
userSvg
}
alt=
""
className=
{
styles
.
question_img
}
/>
<
span
className=
{
classNames
(
isMobile
&&
styles
.
mobile_question_span
,
styles
.
question_span
)
}
style=
{
{
marginLeft
:
isMobile
?
'8px'
:
'16px'
}
}
>
{
questionValue
}
</
span
>
</
div
>
</
Col
>
);
}
}
;
export
default
Issue
;
\ No newline at end of file
export
default
Issue
;
src/global.less
View file @
4b431dc7
...
...
@@ -12,6 +12,11 @@ body,
height: 100%;
}
body {
margin: 0;
padding: 0;
}
.colorWeak {
filter: invert(80%);
}
...
...
src/pages/Chat/components/content.less
View file @
4b431dc7
...
...
@@ -2,8 +2,5 @@
padding: 8px;
}
.CardContent {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 150px;
}
src/pages/Chat/components/content.tsx
View file @
4b431dc7
import
{
Row
,
Col
,
Grid
}
from
'antd'
;
import
type
{
FC
}
from
'react'
;
import
styles
from
'./content.less'
;
import
ProductionCard
from
'./productionCard'
;
const
{
useBreakpoint
}
=
Grid
;
interface
ChatFirstContentProps
{
onChange
?:
(
text
:
string
)
=>
void
;
}
const
ChatFirstContent
:
FC
<
ChatFirstContentProps
>
=
(
props
)
=>
{
const
{
onChange
}
=
props
;
const
screen
=
useBreakpoint
();
const
isMobile
=
screen
.
xs
;
const
cardList
=
[
{
title
:
'市场营销'
,
content
:
'请为我编写一个杨过大战钢铁侠的额电影脚本,要足够精彩,细节丰富,好像好莱坞大片,有场景有对话,叨叨剧本要求'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
title
:
'技术文档'
,
content
:
'请为我们的新款智能手表撰写一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
title
:
'灵感提示'
,
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
{
content
:
'请为我们的新款智能手表一份产品说明书,包括功能,使用方法和注意事项'
,
onclick
:
(
text
:
string
)
=>
{
onChange
&&
onChange
(
text
);
},
},
];
return
(
<
div
className=
{
styles
.
CardContent
}
>
<
Row
gutter=
{
1
}
>
{
cardList
.
map
((
item
,
index
)
=>
{
return
(
<
Col
lg=
{
8
}
md=
{
12
}
span=
{
8
}
xs=
{
24
}
sm=
{
16
}
key=
{
`${item.title}-card-${index}`
}
>
<
Row
justify=
{
isMobile
&&
'center'
}
className=
{
styles
.
cardPadding
}
>
<
ProductionCard
title=
{
item
.
title
}
content=
{
item
.
content
}
onChange=
{
item
.
onclick
}
/>
</
Row
>
</
Col
>
);
})
}
</
Row
>
</
div
>
);
};
export
default
ChatFirstContent
;
import
{
Row
,
Col
,
Grid
}
from
'antd'
;
import
type
{
FC
}
from
'react'
;
import
styles
from
'./content.less'
;
import
ProductionCard
from
'./productionCard'
;
import
{
IPromptWord
}
from
'@/services/chatGLM/api'
;
const
{
useBreakpoint
}
=
Grid
;
interface
ChatFirstContentProps
{
list
:
IPromptWord
[];
onChange
?:
(
text
:
string
)
=>
void
;
}
const
ChatFirstContent
:
FC
<
ChatFirstContentProps
>
=
(
props
)
=>
{
const
{
onChange
,
list
}
=
props
;
return
(
<
div
className=
{
styles
.
CardContent
}
>
<
Row
>
{
list
.
map
((
item
,
index
)
=>
{
return
(
<
Col
lg=
{
12
}
md=
{
12
}
span=
{
8
}
xs=
{
24
}
sm=
{
12
}
xl=
{
8
}
xxl=
{
8
}
key=
{
`${item.title}-card-${index}`
}
>
<
Row
justify=
{
'start'
}
style=
{
{
marginBottom
:
16
,
minWidth
:
306
}
}
>
<
ProductionCard
index=
{
index
}
title=
{
item
.
title
}
content=
{
item
.
content
}
onChange=
{
()
=>
{
onChange
&&
onChange
(
item
.
content
);
}
}
/>
</
Row
>
</
Col
>
);
})
}
</
Row
>
</
div
>
);
};
export
default
ChatFirstContent
;
src/pages/Chat/components/productionCard.less
View file @
4b431dc7
.CardWrapper {
width: 306px;
cursor: pointer;
&:hover .CardContent {
background-color: #0a7a73;
&:hover .content {
color: white;
}
&:hover .button {
color: #0a7a73;
background-color: white;
border: solid 1px white;
}
}
.title {
padding: 5px;
color: #333333;
font-weight: 600;
font-size: 22px;
line-height: 26px;
text-align: center;
}
.CardContent {
padding: 16px 24px;
background-color: #f8f9fb;
border-radius: 5px;
transition: all 0.25s;
.content {
height: 204px;
padding: 12px 8px;
color: #666666;
font-weight: 400;
font-size: 14px;
line-height: 28px;
}
.button {
width: 180px;
margin: 0 auto;
padding: 6px 24px;
color: #0a7a73;
font-size: 16px;
text-align: center;
border: solid 1px #0a7a73;
border-radius: 5px;
}
}
}
.CardWrapper {
width: 100%;
padding: 0 16px;
cursor: pointer;
&:hover .CardContent {
background-color: #0a7a73;
&:hover .content {
color: white;
}
&:hover .button {
color: #0a7a73;
background-color: white;
border: solid 1px white;
}
}
.title {
padding-bottom: 10px;
color: #333333;
font-weight: 600;
font-size: 20px;
text-align: center;
}
.CardContent {
padding: 16px 16px;
background-color: #f8f9fb;
border-radius: 5px;
transition: all 0.25s;
.content {
display: -webkit-box;
height: 202px;
overflow: hidden;
color: #666666;
font-weight: 400;
font-size: 18px;
line-height: 28px;
white-space: normal;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 7;
}
.button {
width: 180px;
margin: 0 auto;
padding: 6px 24px;
color: #0a7a73;
font-weight: 500;
font-size: 16px;
text-align: center;
border: solid 1px #0a7a73;
border-radius: 5px;
}
}
}
src/pages/Chat/components/productionCard.tsx
View file @
4b431dc7
import
type
{
ReactNode
}
from
'react'
;
import
styles
from
'./productionCard.less'
;
import
classnames
from
'classnames'
;
interface
ProductionCardProps
{
title
?:
string
;
content
:
ReactNode
;
onChange
:
(
content
:
string
)
=>
void
;
}
const
ProductionCard
=
(
props
:
ProductionCardProps
)
=>
{
const
{
title
,
content
,
onChange
}
=
props
;
const
handleClick
=
()
=>
{
onChange
&&
onChange
(
content
);
};
return
(
<
div
className=
{
classnames
(
styles
.
CardWrapper
)
}
>
<
div
className=
{
styles
.
title
}
>
{
title
}
</
div
>
<
div
className=
{
styles
.
CardContent
}
>
<
div
className=
{
styles
.
content
}
>
{
content
}
</
div
>
<
div
className=
{
styles
.
button
}
onClick=
{
handleClick
}
>
试一下看看
</
div
>
</
div
>
</
div
>
);
};
export
default
ProductionCard
;
import
type
{
ReactNode
}
from
'react'
;
import
styles
from
'./productionCard.less'
;
import
classnames
from
'classnames'
;
interface
ProductionCardProps
{
index
:
number
;
title
?:
string
;
content
:
ReactNode
;
onChange
:
(
content
:
string
)
=>
void
;
}
const
ProductionCard
=
(
props
:
ProductionCardProps
)
=>
{
const
{
index
,
title
,
content
,
onChange
}
=
props
;
const
handleClick
=
()
=>
{
onChange
&&
onChange
(
content
);
};
return
(
<
div
className=
{
classnames
(
styles
.
CardWrapper
)
}
>
<
div
className=
{
styles
.
title
}
>
{
title
}
</
div
>
<
div
className=
{
styles
.
CardContent
}
>
<
div
className=
{
styles
.
content
}
>
{
content
}
</
div
>
<
div
className=
{
styles
.
button
}
onClick=
{
handleClick
}
>
试一下看看
</
div
>
</
div
>
</
div
>
);
};
export
default
ProductionCard
;
src/pages/Chat/index.less
View file @
4b431dc7
...
...
@@ -3,16 +3,15 @@
.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%;
...
...
@@ -26,12 +25,13 @@
}
}
.header {
margin-top: 68px;
margin-top: 80px;
margin-bottom: 40px;
color: #333;
font-size: 32px;
line-height: 45px;
text-align: center;
.subTitle {
margin-bottom: 0;
color: #999999;
font-weight: 400;
}
...
...
@@ -68,11 +68,28 @@
}
}
.chatFooter {
position: fixed;
bottom: 0;
left: 0;
width: 240px;
width: 100%;
margin-bottom: 52px;
}
.chatFooterItem {
margin-left: 64px;
padding: 19px 0px;
color: #ffffff;
font-size: 18px;
line-height: 25px;
}
.footer {
position: fixed;
bottom: 0;
left: 0;
z-index: 1
0
;
z-index: 1
2
;
width: 100%;
height: 150px;
padding: 16px;
...
...
@@ -80,7 +97,7 @@
background-color: white;
box-shadow: 0 2px 8px #f0f1f2;
.chatWrapper {
padding: 0 16px 0 50
px;
border-radius: 4
px;
:global {
.ant-input:focus,
.ant-input:hover,
...
...
@@ -94,10 +111,10 @@
}
}
.outputButtonWrapper {
width: 120px;
:global(.ant-btn-primary) {
background: #009b95;
border: solid 1px #009b95;
border-radius: 6px !important;
}
}
}
...
...
src/pages/Chat/index.tsx
View file @
4b431dc7
/* eslint-disable @typescript-eslint/no-unused-expressions */
import
{
Form
,
Button
,
Col
,
Row
,
Input
,
Typography
,
Grid
,
message
}
from
'antd'
;
import
{
Form
,
Button
,
Col
,
Row
,
Input
,
Typography
,
Grid
,
message
,
Space
}
from
'antd'
;
import
React
,
{
useState
,
useEffect
,
useRef
,
useMemo
}
from
'react'
;
import
styles
from
'./index.less'
;
import
ChatFirstContent
from
'./components/content'
;
import
{
FieldTimeOutlined
,
LoadingOutlined
,
MenuOutlined
,
PlusOutlined
,
SettingOutlined
,
...
...
@@ -16,7 +17,7 @@ import { history } from 'umi';
import
LoginModal
from
'@/components/loginModal'
;
import
NewSession
from
'@/components/newSession'
;
import
{
useWebSocket
,
useRequest
}
from
'ahooks'
;
import
{
GetChatGLMToken
}
from
'@/services/chatGLM/api'
;
import
{
GetChatGLMToken
,
GetPromptList
}
from
'@/services/chatGLM/api'
;
import
{
useAccess
}
from
'umi'
;
const
{
useBreakpoint
}
=
Grid
;
...
...
@@ -37,6 +38,8 @@ const Chat: React.FC = () => {
const
[
form
]
=
Form
.
useForm
();
const
[
selectSiderTabs
,
setSelectSiderTabs
]
=
useState
(
''
);
const
{
data
:
glmToken
}
=
useRequest
(
GetChatGLMToken
);
const
{
data
:
promptList
,
loading
:
promptLoading
}
=
useRequest
(
GetPromptList
);
const
[
answer
,
setAnswer
]
=
useState
(
''
);
const
[
loading
,
setLoading
]
=
useState
(
true
);
const
[
open
,
setOpen
]
=
useState
(
false
);
...
...
@@ -48,11 +51,13 @@ const Chat: React.FC = () => {
const
{
sendMessage
}
=
useWebSocket
(
'wss://glm-api.baibaomen.com/ws'
,
{
onMessage
:
(
event
)
=>
{
const
text
=
event
.
data
;
console
.
log
(
text
);
if
(
text
==
'{{BBMCPLT}}'
)
{
setLoading
(
false
);
}
else
{
setAnswer
(
text
);
window
.
scrollTo
(
0
,
document
.
body
.
scrollHeight
);
console
.
log
(
text
);
}
},
onOpen
:
()
=>
{
...
...
@@ -71,6 +76,7 @@ const Chat: React.FC = () => {
return
messageHistory
.
current
;
},
[
answer
]);
async
function
handleSendMessage
()
{
messageHistory
.
current
.
push
({
prompt
:
chat
,
answer
:
''
});
setLoading
(
true
);
sendMessage
&&
sendMessage
(
...
...
@@ -83,13 +89,12 @@ const Chat: React.FC = () => {
token
:
glmToken
,
}),
);
messageHistory
.
current
.
push
({
prompt
:
chat
,
answer
:
''
});
}
console
.
log
(
'access'
,
access
);
useEffect
(()
=>
{
if
(
access
?.
token
)
{
if
(
access
?.
token
)
{
setOpen
(
false
);
}
else
{
setOpen
(
true
);
...
...
@@ -112,45 +117,19 @@ const Chat: React.FC = () => {
value
?.
firstInput
&&
setInput
(
value
);
};
const
siderTabsList
=
[
{
icons
:
<
SettingOutlined
/>,
text
:
'后台'
,
checked
:
'gotoAdmin'
,
},
{
icons
:
<
WechatOutlined
/>,
text
:
'活动交流群'
,
checked
:
'wechat'
,
},
{
icons
:
<
UserOutlined
/>,
text
:
'游客登录'
,
checked
:
'noMentionLogin'
,
},
];
const
selectSliderTabsHandleClick
=
(
value
:
string
)
=>
{
setSelectSiderTabs
(
value
);
if
(
value
===
'gotoAdmin'
)
{
history
.
push
(
'/admin/user'
);
}
};
const
renderMobileHeader
=
()
=>
{
return
(
<
Row
align=
{
'middle'
}
justify=
"space-between"
gutter=
{
1
}
className=
{
styles
.
mobileHeader
}
>
<
Col
push=
{
1
}
>
<
MenuOutlined
onClick=
{
()
=>
{
console
.
log
(
showSider
);
setShowSider
(
!
showSider
);
}
}
/>
</
Col
>
<
Col
>
AI改变世界
</
Col
>
<
Col
pull=
{
1
}
>
<
FieldTimeOutlined
/>
</
Col
>
<
Col
pull=
{
1
}
>
{
/* <FieldTimeOutlined /> */
}
</
Col
>
</
Row
>
);
};
...
...
@@ -160,121 +139,149 @@ const Chat: React.FC = () => {
<
LoginModal
open=
{
open
}
setOpen=
{
setOpen
}
/>
{
isMobile
&&
renderMobileHeader
()
}
<
Row
>
{
tabShow
&&
(
<
Col
span=
{
4
}
sm=
{
10
}
md=
{
7
}
xs=
{
12
}
lg=
{
5
}
className=
{
styles
.
siderWrapper
}
>
<
div
style=
{
{
top
:
isMobile
&&
'44px'
}
}
className=
{
styles
.
sider
}
>
{
(
showSider
||
!
isMobile
)
&&
(
<
Col
className=
{
`${styles.siderWrapper}`
}
>
<
div
style=
{
{
top
:
isMobile
&&
'44px'
,
zIndex
:
isMobile
?
13
:
10
}
}
className=
{
`${styles.sider}`
}
>
<
div
className=
{
styles
.
siderChatContent
}
>
<
Button
size=
"large"
block
type=
"primary"
icon=
{
<
PlusOutlined
/>
}
>
新建对话
</
Button
>
<
div
style=
{
{
padding
:
'30px 20px 0 20px'
}
}
>
<
Button
size=
"large"
block
type=
"primary"
icon=
{
<
PlusOutlined
/>
}
>
新建对话
</
Button
>
</
div
>
</
div
>
<
div
className=
{
styles
.
chatFooter
}
>
<
Row
style=
{
{
width
:
'240px'
}
}
justify=
{
'center'
}
align=
{
'middle'
}
>
<
Col
span=
{
24
}
className=
{
styles
.
chatFooterItem
}
>
<
Space
wrap
onClick=
{
()
=>
{
history
.
push
(
'/admin/user'
);
}
}
>
<
SettingOutlined
/>
后台管理
</
Space
>
</
Col
>
<
Col
span=
{
24
}
className=
{
styles
.
chatFooterItem
}
style=
{
{
color
:
'#009B95'
}
}
>
<
Space
wrap
>
<
UserOutlined
/>
游客登录
</
Space
>
</
Col
>
</
Row
>
</
div
>
<
Row
>
{
siderTabsList
.
map
((
item
)
=>
{
return
(
<
Col
key=
{
item
.
text
}
>
<
div
className=
{
styles
.
chatSiderChatTabsCard
}
onClick=
{
()
=>
{
selectSliderTabsHandleClick
(
item
.
checked
);
}
}
>
<
div
className=
{
classNames
(
styles
.
chatSiderChatTabsCardIcons
,
selectSiderTabs
===
item
.
checked
&&
styles
.
checkedChatSiderChatTabsCardIcons
,
)
}
>
{
item
.
icons
}
</
div
>
<
div
className=
{
classNames
(
styles
.
chatSiderChatTabsCardText
,
selectSiderTabs
===
item
.
checked
&&
styles
.
checkedChatSiderChatTabsCardText
,
)
}
>
{
item
.
text
}
</
div
>
</
div
>
</
Col
>
);
})
}
</
Row
>
</
div
>
</
Col
>
)
}
<
Col
className=
{
styles
.
chatContent
}
span=
{
20
}
lg=
{
19
}
sm=
{
14
}
md=
{
17
}
xs=
{
isMobile
?
24
:
12
}
<
Form
form=
{
form
}
initialValues=
{
{
chatInput
:
chat
}
}
name=
"chat"
onValuesChange=
{
onChange
}
onFinish=
{
onSend
}
>
{
!
isMobile
&&
(
<
div
className=
{
styles
.
header
}
hidden=
{
firstChat
}
>
<
Row
>
<
Col
span=
{
24
}
>
<
Title
level=
{
1
}
>
产品名称
</
Title
>
</
Col
>
<
Col
span=
{
24
}
>
<
Title
level=
{
5
}
className=
{
styles
.
subTitle
}
>
AI改变世界
</
Title
>
</
Col
>
</
Row
>
</
div
>
)
}
<
Form
form=
{
form
}
initialValues=
{
{
chatInput
:
chat
}
}
name=
"chat"
onValuesChange=
{
onChange
}
onFinish=
{
onSend
}
<
Col
className=
{
styles
.
chatContent
}
style=
{
{
marginLeft
:
isMobile
?
0
:
240
,
width
:
isMobile
?
'calc(100vw)'
:
'calc(100vw - 240px)'
,
}
}
>
{
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"
<
Row
justify=
{
'center'
}
>
<
Col
span=
{
'24'
}
>
{
!
isMobile
&&
(
<
div
className=
{
styles
.
header
}
hidden=
{
firstChat
}
>
<
Row
>
<
Col
span=
{
24
}
>
<
Title
level=
{
2
}
style=
{
{
marginBottom
:
8
,
fontSize
:
32
}
}
>
产品名称
</
Title
>
</
Col
>
<
Col
span=
{
24
}
>
<
Title
level=
{
5
}
className=
{
styles
.
subTitle
}
>
AI改变世界
</
Title
>
</
Col
>
</
Row
>
</
div
>
)
}
</
Col
>
<
Col
span=
{
'24'
}
style=
{
{
padding
:
isMobile
?
''
:
'0 100px'
}
}
>
{
firstChat
?
(
<
div
style=
{
{
marginBottom
:
150
}
}
>
{
messageHistory
.
current
.
map
((
item
,
index
)
=>
(
<
NewSession
key=
{
'new'
+
index
}
questionValue=
{
item
.
prompt
}
answerValue=
{
item
.
answer
}
/>
</
Item
>
))
}
</
div
>
</
Col
>
<
Col
span=
{
4
}
push=
{
isMobile
?
0
:
4
}
>
<
div
className=
{
styles
.
outputButtonWrapper
}
>
<
Item
name=
"outputButton"
>
<
Button
htmlType=
"submit"
type=
"primary"
size=
"large"
loading=
{
loading
}
>
发送
</
Button
>
)
:
(
<
div
className=
{
classNames
(
isMobile
&&
styles
.
mobileContent
)
}
>
<
Item
name=
"firstInput"
>
<
ChatFirstContent
list=
{
promptList
?.
items
||
[]
}
/>
</
Item
>
</
div
>
</
Col
>
</
Row
>
</
div
>
</
Form
>
</
Col
>
)
}
</
Col
>
<
div
className=
{
styles
.
footer
}
style=
{
{
marginLeft
:
isMobile
?
0
:
'240px'
,
height
:
isMobile
?
'100px'
:
'120px'
,
width
:
isMobile
?
'100vw'
:
'calc(100vw - 240px)'
,
}
}
>
<
Row
justify=
{
'center'
}
align=
{
'middle'
}
style=
{
{
textAlign
:
'center'
}
}
>
<
Col
span=
{
24
}
style=
{
{
textAlign
:
'center'
}
}
>
<
Space
style=
{
{
textAlign
:
'center'
}
}
>
<
div
className=
{
styles
.
chatWrapper
}
style=
{
{
marginLeft
:
firstChat
&&
!
isMobile
?
'82px'
:
0
,
width
:
isMobile
?
'calc(100vw - 108px)'
:
firstChat
?
'calc(100vw - 482px)'
:
'calc(100vw - 550px)'
,
}
}
>
<
Item
name=
"chatInput"
>
<
Input
required
placeholder=
"在这里输入你想知道的问题,给我几句提示,我来帮你回答"
size=
"large"
/>
</
Item
>
</
div
>
<
div
className=
{
styles
.
outputButtonWrapper
}
>
<
Item
name=
"outputButton"
>
<
Button
htmlType=
"submit"
type=
"primary"
size=
"large"
disabled=
{
loading
}
>
{
loading
?
(
<>
<
LoadingOutlined
/>
</>
)
:
(
'发送'
)
}
</
Button
>
</
Item
>
</
div
>
</
Space
>
</
Col
>
</
Row
>
</
div
>
</
Row
>
</
Col
>
</
Form
>
</
Row
>
</>
);
...
...
src/services/chatGLM/api.ts
View file @
4b431dc7
...
...
@@ -10,10 +10,10 @@ const request = extend({});
request
.
interceptors
.
request
.
use
((
url
,
options
)
=>
{
const
token
=
JSON
.
parse
(
localStorage
.
getItem
(
'user'
)
||
'{}'
)?.
token
;
const
authHeader
=
{
const
authHeader
=
{
Authorization
:
`Bearer
${
token
||
''
}
`
,
'Content-Type'
:
'application/json'
,
'__tenant'
:
'3a0a90fe-9a0d-70f4-200d-a80a41fb6195'
__tenant
:
'3a0a90fe-9a0d-70f4-200d-a80a41fb6195'
,
};
return
{
url
:
url
,
...
...
@@ -21,19 +21,18 @@ request.interceptors.request.use((url, options) => {
};
});
request
.
interceptors
.
response
.
use
(
async
(
response
):
Promise
<
any
>
=>
{
console
.
log
(
'response'
,
response
);
if
(
response
.
status
===
401
)
{
if
(
response
.
status
===
401
)
{
localStorage
.
removeItem
(
'user'
);
history
.
push
(
'/chat'
);
}
else
if
(
response
.
status
===
200
)
{
}
else
if
(
response
.
status
===
200
)
{
return
response
;
}
else
{
message
.
error
(
'请求失败,请重试! '
)
message
.
error
(
'请求失败,请重试! '
)
;
return
Promise
.
reject
(
response
.
statusText
);
}
})
})
;
export
function
loginChatGLM
(
options
:
ILoginParams
)
{
return
request
(
'https://glm-mangement-api.baibaomen.com/api/app/account/login'
,
{
...
...
@@ -42,34 +41,58 @@ export function loginChatGLM(options: ILoginParams) {
});
}
export
interface
IPromptWord
{
title
:
string
;
content
:
string
;
}
export
function
GetChatGLMToken
():
Promise
<
string
>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/user/token'
,
{
method
:
'POST'
,
});
}
export
function
GetPromptList
():
Promise
<
{
items
:
IPromptWord
[]
}
>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/promptwords/page'
,
{
method
:
'POST'
,
headers
:
{
Authorization
:
'Bearer '
+
JSON
.
parse
(
localStorage
.
getItem
(
'user'
)
||
''
)?.
token
,
'Content-Type'
:
'application/json'
,
},
body
:
JSON
.
stringify
({
pageIndex
:
0
,
pageSize
:
10
}),
});
}
type
History
=
[
string
,
string
];
interface
ITalkParams
{
prompt
:
string
;
history
:
History
[];
max_length
?:
number
;
top_p
?:
number
;
temperature
?:
number
;
}
export
const
CreatedAccount
=
(
params
:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/create'
,
{
method
:
'POST'
,
params
params
,
});
}
}
;
export
const
getRole
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/roles'
,
{
method
:
'POST'
,
params
})
}
params
,
})
;
}
;
export
const
getUserMessage
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/page'
,
{
method
:
'POST'
,
data
:
params
data
:
params
,
});
}
}
;
export
const
postDeleteUser
=
(
params
?:
any
):
Promise
<
string
>=>
{
export
const
postDeleteUser
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/delete'
,
{
method
:
'POST'
,
params
...
...
@@ -79,6 +102,6 @@ export const postDeleteUser = (params?: any): Promise<string>=> {
export
const
postResetUser
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/delete'
,
{
method
:
'POST'
,
data
:
params
})
}
\ No newline at end of file
data
:
params
,
});
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment