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
06cce791
Commit
06cce791
authored
Apr 16, 2023
by
文旺-丰林-DEV
Browse files
Options
Browse Files
Download
Plain Diff
update ui
parents
6a27fa97
0bc59ceb
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
724 additions
and
428 deletions
+724
-428
.gitignore
.gitignore
+1
-0
access.ts
src/access.ts
+4
-4
app.tsx
src/app.tsx
+5
-3
index.tsx
src/components/loginModal/index.tsx
+3
-12
answer.component.tsx
src/components/newSession/answer.component.tsx
+42
-38
index.less
src/components/newSession/index.less
+17
-13
index.tsx
src/components/newSession/index.tsx
+9
-3
issue.component.tsx
src/components/newSession/issue.component.tsx
+12
-8
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
+13
-5
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
+147
-148
index.less
src/pages/UserManage/index.less
+18
-0
index.tsx
src/pages/UserManage/index.tsx
+276
-73
api.ts
src/services/chatGLM/api.ts
+63
-33
No files found.
.gitignore
View file @
06cce791
...
...
@@ -38,3 +38,4 @@ screenshot
.eslintcache
build
node_modules
src/access.ts
View file @
06cce791
/**
* @see https://umijs.org/zh-CN/plugins/plugin-access
* */
export
default
function
access
(
initialState
:
{
currentUser
?:
API
.
CurrentUser
}
|
undefined
)
{
console
.
log
(
initialState
)
const
{
currentUser
}
=
initialState
??
{};
export
default
function
access
(
initialState
:
{
userInfo
:
{
token
:
''
};
}
)
{
console
.
log
(
'initialState'
,
initialState
)
const
{
token
}
=
initialState
.
userInfo
??
{};
return
{
canAdmin
:
currentUser
&&
currentUser
.
access
===
'admin'
,
token
};
}
src/app.tsx
View file @
06cce791
...
...
@@ -13,15 +13,17 @@ export const initialStateConfig = {
/**
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
* */
export
async
function
getInitialState
()
{
const
user
Message
=
JSON
.
parse
(
localStorage
.
getItem
(
'user'
)
);
const
user
Info
=
JSON
.
parse
(
localStorage
.
getItem
(
'user'
)
||
'{}'
);
if
(
isEmpty
(
user
Message
))
{
if
(
isEmpty
(
user
Info
))
{
history
.
push
(
loginPath
);
return
{};
}
return
{
user
Message
};
return
{
user
Info
};
}
// ProLayout 支持的api https://procomponents.ant.design/components/layout
...
...
src/components/loginModal/index.tsx
View file @
06cce791
import
styles
from
'./index.less'
;
import
{
Button
,
Checkbox
,
Form
,
Input
,
Modal
,
message
}
from
'antd'
;
import
{
Button
,
Checkbox
,
Form
,
Input
,
Modal
}
from
'antd'
;
import
{
LockOutlined
,
UserOutlined
}
from
'@ant-design/icons'
;
import
logoSvg
from
'../../assets/logo.svg'
;
import
{
useState
}
from
'react'
;
import
{
loginChatGLM
}
from
'@/services/chatGLM/api'
;
import
{
useIntl
}
from
'react-intl'
;
interface
ILoginModalProps
{
open
:
boolean
;
setOpen
:
(
value
:
boolean
)
=>
void
;
...
...
@@ -14,7 +12,6 @@ interface ILoginModalProps {
const
LoginModal
=
(
props
:
ILoginModalProps
)
=>
{
const
{
open
,
setOpen
}
=
props
;
const
intl
=
useIntl
();
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
...
...
@@ -31,17 +28,11 @@ const LoginModal = (props: ILoginModalProps) => {
name
:
username
,
password
,
});
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
result
||
{}));
console
.
log
(
'result'
,
result
);
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
result
));
setLoading
(
false
);
reset
();
}
catch
(
error
)
{
const
defaultLoginFailureMessage
=
intl
.
formatMessage
({
id
:
'pages.login.failure'
,
defaultMessage
:
'登录失败,请重试!'
,
});
message
.
error
(
defaultLoginFailureMessage
);
setLoading
(
false
);
}
};
...
...
src/components/newSession/answer.component.tsx
View file @
06cce791
...
...
@@ -17,47 +17,51 @@ const Answer = (props: IAnswerProps) => {
const
screens
=
useBreakpoint
();
const
isMobile
=
screens
.
xs
;
console
.
log
(
'isMobile'
,
isMobile
);
return
(
<
div
>
<
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
>
<
div
className=
{
styles
.
chat
}
>
<
div
className=
{
classNames
(
styles
.
answer
,
isMobile
&&
styles
.
mobile_answer
)
}
>
{
!
isMobile
&&
(
<
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
>
<
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
>
)
}
</
div
>
</
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
>
{
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
>
)
}
</
Col
>
</
Row
>
</
Col
>
);
};
...
...
src/components/newSession/index.less
View file @
06cce791
...
...
@@ -2,6 +2,7 @@
.mobile_newSession {
width: 100% !important;
margin-top: 24px !important;
padding: 48px 16px 16px;
}
...
...
@@ -10,14 +11,13 @@
}
.mobile_answer {
width: 316px !important;
//
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;
...
...
@@ -35,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;
...
...
@@ -70,7 +73,7 @@
.chat_retry {
width: 90px;
height: 48px;
margin-left: 10px;
//
margin-left: 10px;
background: #ffffff;
border: 1px solid #009b95;
border-radius: 6px;
...
...
@@ -89,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;
...
...
@@ -109,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 @
06cce791
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
{
...
...
@@ -18,10 +18,16 @@ const NewSession = (props: INewSessionProps) => {
const
isMobile
=
screens
.
xs
;
return
(
<
div
className=
{
classNames
(
isMobile
&&
styles
.
mobile_newSession
,
styles
.
newSession
)
}
>
<
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 @
06cce791
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,11 +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=
{
classNames
(
isMobile
&&
styles
.
mobile_question_span
,
styles
.
question_span
)
}
style=
{
{
marginLeft
:
isMobile
?
'8px'
:
'16px'
}
}
>
{
questionValue
}
</
span
>
</
div
>
<
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
>
</
Col
>
);
}
}
;
export
default
Issue
;
\ No newline at end of file
export
default
Issue
;
src/global.less
View file @
06cce791
...
...
@@ -12,6 +12,11 @@ body,
height: 100%;
}
body {
margin: 0;
padding: 0;
}
.colorWeak {
filter: invert(80%);
}
...
...
src/pages/Chat/components/content.less
View file @
06cce791
...
...
@@ -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 @
06cce791
...
...
@@ -13,17 +13,25 @@ interface ChatFirstContentProps {
const
ChatFirstContent
:
FC
<
ChatFirstContentProps
>
=
(
props
)
=>
{
const
{
onChange
,
list
}
=
props
;
const
screen
=
useBreakpoint
();
const
isMobile
=
screen
.
xs
;
return
(
<
div
className=
{
styles
.
CardContent
}
>
<
Row
gutter=
{
1
}
>
<
Row
>
{
list
.
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
}
>
<
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=
{
()
=>
{
...
...
src/pages/Chat/components/productionCard.less
View file @
06cce791
.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 @
06cce791
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 @
06cce791
...
...
@@ -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 @
06cce791
This diff is collapsed.
Click to expand it.
src/pages/UserManage/index.less
0 → 100644
View file @
06cce791
.isActive {
display: inline-flex;
align-items: center;
justify-content: center;
}
.dot {
display: inline-block;
width: 6px;
height: 6px;
margin-right: 5px;
border-radius: 50%;
}
.green {
background-color: #52c41a;
}
.red {
background-color: #f5222d;
}
src/pages/UserManage/index.tsx
View file @
06cce791
import
{
CreatedAccount
,
getRole
,
getUserMessage
,
postDelete
,
postDeleteUser
,
}
from
'@/services/chatGLM/api'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
type
{
ActionType
}
from
'@ant-design/pro-components'
;
import
{
PageContainer
}
from
'@ant-design/pro-components'
;
import
{
ProTable
}
from
'@ant-design/pro-components'
;
import
{
Button
}
from
'antd'
;
import
{
useRef
}
from
'react'
;
import
request
from
'umi-request'
;
import
{
Button
,
Col
,
Divider
,
Form
,
Input
,
Modal
,
Radio
,
Row
,
Switch
,
message
}
from
'antd'
;
import
classNames
from
'classnames'
;
import
{
isEmpty
}
from
'lodash'
;
import
{
useRef
,
useState
}
from
'react'
;
import
styles
from
'./index.less'
;
const
columns
:
any
[]
=
[
{
title
:
'用户'
,
dataIndex
:
'name'
,
ellipsis
:
true
,
},
{
title
:
'用户账号'
,
dataIndex
:
'username'
,
ellipsis
:
true
,
},
{
title
:
'角色'
,
dataIndex
:
'role'
,
hideInSearch
:
true
,
ellipsis
:
true
,
},
{
title
:
'账号状态'
,
dataIndex
:
'iaActive'
,
hideInSearch
:
true
,
},
{
title
:
'创建时间'
,
dataIndex
:
'creationTime'
,
hideInSearch
:
true
,
valueType
:
'date'
,
},
{
title
:
'备注'
,
hideInSearch
:
true
,
dataIndex
:
'creationTime'
,
valueType
:
'date'
,
},
{
title
:
'操作'
,
valueType
:
'option'
,
key
:
'option'
,
render
:
(
text
,
record
,
_
,
action
)
=>
[
<
a
key=
"editable"
onClick=
{
()
=>
{
action
?.
startEditable
?.(
record
.
id
);
}
}
>
编辑
</
a
>,
<
a
href=
{
record
.
url
}
target=
"_blank"
rel=
"noopener noreferrer"
key=
"view"
>
重置
</
a
>,
<
a
href=
{
record
.
url
}
target=
"_blank"
rel=
"noopener noreferrer"
key=
"view"
>
删除
</
a
>,
],
},
];
const
{
Item
}
=
Form
;
const
UserManage
=
()
=>
{
const
actionRef
=
useRef
<
ActionType
>
();
const
[
isModalAccountOpen
,
setIsModalAccountOpen
]
=
useState
(
false
);
const
[
roles
,
setRoles
]
=
useState
([]);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
accountModalName
,
setAccountModalName
]
=
useState
(
'新建账号'
);
const
[
accountForm
]
=
Form
.
useForm
();
const
layout
=
{
labelCol
:
{
span
:
4
},
wrapperCol
:
{
span
:
18
},
};
const
showModal
=
()
=>
{
getRole
()
.
then
((
res
)
=>
{
if
(
!
isEmpty
(
res
))
{
setRoles
(
res
);
setIsModalAccountOpen
(
true
);
}
})
.
catch
((
err
)
=>
{
message
.
error
(
'获取用户权限失败,请重试'
);
});
};
const
columns
:
any
[]
=
[
{
title
:
'用户'
,
dataIndex
:
'name'
,
ellipsis
:
true
,
},
{
title
:
'用户账号'
,
dataIndex
:
'userName'
,
ellipsis
:
true
,
},
{
title
:
'角色'
,
dataIndex
:
'roles'
,
hideInSearch
:
true
,
ellipsis
:
true
,
},
{
title
:
'账号状态'
,
dataIndex
:
'iaActive'
,
hideInSearch
:
true
,
render
(
text
,
record
)
{
return
(
<
div
className=
{
styles
.
isActive
}
>
<
span
className=
{
classNames
(
styles
.
dot
,
record
.
isActive
?
styles
.
green
:
styles
.
red
)
}
/>
<
div
>
{
record
.
isActive
?
'启动'
:
'禁用'
}
</
div
>
</
div
>
);
},
},
{
title
:
'创建时间'
,
dataIndex
:
'creationTime'
,
hideInSearch
:
true
,
valueType
:
'date'
,
},
{
title
:
'备注'
,
hideInSearch
:
true
,
dataIndex
:
'creationTime'
,
valueType
:
'date'
,
},
{
title
:
'操作'
,
valueType
:
'option'
,
key
:
'option'
,
render
:
(
text
,
record
,
_
,
action
)
=>
[
<
a
key=
"editable"
onClick=
{
()
=>
{
setAccountModalName
(
'编辑账号'
);
showModal
();
const
data
=
{
id
:
record
.
id
,
Name
:
record
.
userName
,
Phone
:
record
.
phoneNumber
,
Role
:
record
.
roles
,
isActive
:
record
.
isActive
,
};
accountForm
.
setFieldsValue
(
data
);
console
.
log
(
data
);
}
}
>
编辑
</
a
>,
<
a
onClick=
{
()
=>
{
// postDeleteUser(
{
// id: record.id,
// Password:
//
});
}
}
key=
"reset"
>
重置
</
a
>,
<
a
key=
"remove"
onClick=
{
()
=>
{
postDeleteUser
({
id
:
record
.
id
,
});
}
}
>
删除
</
a
>,
],
},
];
const
handleOk
=
()
=>
{
setIsModalAccountOpen
(
false
);
};
const
handleModalCancel
=
()
=>
{
accountForm
.
resetFields
();
setIsModalAccountOpen
(
false
);
};
const
createdAccount
=
(
values
:
any
)
=>
{
setLoading
(
true
);
const
data
=
{
role
:
values
.
roles
,
Phone
:
values
.
phoneNumber
,
Password
:
values
,
};
CreatedAccount
(
values
)
.
then
((
res
)
=>
{
setLoading
(
false
);
})
.
catch
((
error
)
=>
{
setLoading
(
false
);
});
};
const
editAccountFinish
=
(
values
:
any
)
=>
{
setLoading
(
true
);
};
const
onHandleClickAccountFinish
=
(
values
:
any
)
=>
{
if
(
accountModalName
===
'添加账号'
)
{
createdAccount
(
values
);
}
if
(
accountModalName
===
'编辑账号'
)
{
editAccountFinish
(
values
);
}
};
const
onHandleClickAccountChange
=
(
values
:
any
)
=>
{
console
.
log
(
values
);
};
const
validatePhoneNumber
=
(
_
,
value
:
any
)
=>
{
const
phoneNumberRegex
=
/^1
[
3456789
]\d{9}
$/
;
if
(
!
value
||
phoneNumberRegex
.
test
(
value
))
{
return
Promise
.
resolve
();
}
return
Promise
.
reject
(
new
Error
(
'请输入有效的手机号码!'
));
};
const
validatePassword
=
(
_
,
value
:
any
)
=>
{
const
letterNumberRegex
=
/^
(?=
.*
[
0-9
])(?=
.*
[
a-zA-Z
])(?=
.*
[^
0-9a-zA-Z
])([
a-zA-Z0-9
\S]
+
)
$/
;
const
lowercaseRegex
=
/
[
a-z
]
/
;
const
uppercaseRegex
=
/
[
A-Z
]
/
;
const
specialCharacterRegex
=
/
[^
0-9a-zA-Z
]
/
;
if
(
letterNumberRegex
.
test
(
value
)
&&
lowercaseRegex
.
test
(
value
)
&&
uppercaseRegex
.
test
(
value
)
&&
specialCharacterRegex
.
test
(
value
)
)
{
return
Promise
.
resolve
();
}
return
Promise
.
reject
(
new
Error
(
'密码格式不正确!'
));
};
return
(
<
PageContainer
>
<
Modal
title=
{
`${accountModalName}`
}
open=
{
isModalAccountOpen
}
onOk=
{
handleOk
}
onCancel=
{
handleModalCancel
}
footer=
{
null
}
maskClosable=
{
false
}
>
<
Form
{
...
layout
}
form=
{
accountForm
}
onFinish=
{
onHandleClickAccountFinish
}
onValuesChange=
{
onHandleClickAccountChange
}
labelAlign=
"right"
name=
"accountSetting"
>
<
Item
name=
{
'Phone'
}
label=
"用户账号"
rules=
{
[
{
required
:
true
,
message
:
'请输入手机号!'
},
{
validator
:
validatePhoneNumber
},
]
}
>
<
Input
/>
</
Item
>
{
accountModalName
===
'添加账号'
&&
(
<
Item
name=
{
'Password'
}
label=
"密码"
rules=
{
[{
required
:
true
,
message
:
'请输入密码!'
},
{
validator
:
validatePassword
}]
}
>
<
Input
/>
</
Item
>
)
}
<
Item
name=
{
'Role'
}
label=
"角色"
rules=
{
[{
required
:
true
,
message
:
'请设置你的角色'
}]
}
>
<
Radio
.
Group
>
{
roles
.
map
((
item
)
=>
{
return
(
<
Radio
key=
{
item
}
value=
{
`${item}`
}
>
{
item
}
</
Radio
>
);
})
}
</
Radio
.
Group
>
</
Item
>
<
Item
name=
{
'Name'
}
label=
"姓名"
rules=
{
[{
required
:
true
,
message
:
'请输入你的姓名'
}]
}
>
<
Input
placeholder=
"请输入(必填)"
/>
</
Item
>
<
Item
name=
{
'isActive'
}
label=
"是否启用"
>
<
Switch
/>
</
Item
>
<
Divider
/>
<
Row
justify=
{
'end'
}
gutter=
{
8
}
>
<
Col
>
<
Item
key=
{
'cancelButton'
}
noStyle=
{
true
}
>
<
Button
key=
"back"
onClick=
{
handleModalCancel
}
>
取消
</
Button
>
</
Item
>
</
Col
>
<
Col
>
<
Item
key=
{
'saveButton'
}
noStyle=
{
true
}
>
<
Button
key=
"submit"
type=
"primary"
loading=
{
loading
}
htmlType=
"submit"
>
保存
</
Button
>
</
Item
>
</
Col
>
</
Row
>
</
Form
>
</
Modal
>
<
ProTable
columns=
{
columns
}
actionRef=
{
actionRef
}
cardBordered
request=
{
async
(
params
=
{},
sort
,
filter
)
=>
{
const
defaultParams
=
{
name
:
''
,
Enabled
:
false
,
PageSize
:
9
,
PageIndex
:
1
,
Name
:
null
,
Enabled
:
null
,
PageSize
:
10
,
PageIndex
:
0
,
};
const
response
=
await
getUserMessage
(
defaultParams
);
return
{
data
:
response
.
items
,
total
:
response
.
totalCount
,
success
:
true
,
};
return
request
<
{
data
:
any
[];
}
>
(
'https://glm-mangement-api.baibaomen.com/User/page'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
,
__tenant
:
'3a0a90fe-9a0d-70f4-200d-a80a41fb6195'
,
},
data
:
defaultParams
,
});
}
}
rowKey=
"id"
pagination=
{
{
...
...
@@ -102,6 +303,8 @@ const UserManage = () => {
key=
"button"
icon=
{
<
PlusOutlined
/>
}
onClick=
{
()
=>
{
setAccountModalName
(
'添加账号'
);
showModal
();
actionRef
.
current
?.
reload
();
}
}
type=
"primary"
...
...
src/services/chatGLM/api.ts
View file @
06cce791
import
request
from
'umi-request'
;
import
{
extend
}
from
'umi-request'
;
import
{
history
}
from
'umi'
;
import
{
message
}
from
'antd'
;
interface
ILoginParams
{
name
:
string
;
password
:
string
;
}
const
request
=
extend
({});
// request.interceptors.request.use((url, options) => {
// let { token } = JSON.parse(localStorage.getItem('user') || '');
// if (null === token) {
// token = '';
// }
// const authHeader = {
// Authorization: `Bearer ${token}`,
// 'Content-Type': 'application/json',
// '__tenant': '3a0a90fe-9a0d-70f4-200d-a80a41fb6195' // 用户id
// };
// return {
// url: url,
// options: { ...options, interceptors: true, headers: authHeader },
// };
// });
request
.
interceptors
.
request
.
use
((
url
,
options
)
=>
{
const
token
=
JSON
.
parse
(
localStorage
.
getItem
(
'user'
)
||
'{}'
)?.
token
;
const
authHeader
=
{
Authorization
:
`Bearer
${
token
||
''
}
`
,
'Content-Type'
:
'application/json'
,
__tenant
:
'3a0a90fe-9a0d-70f4-200d-a80a41fb6195'
,
};
return
{
url
:
url
,
options
:
{
...
options
,
interceptors
:
true
,
headers
:
authHeader
},
};
});
request
.
interceptors
.
response
.
use
(
async
(
response
):
Promise
<
any
>
=>
{
console
.
log
(
'response'
,
response
);
if
(
response
.
status
===
401
)
{
localStorage
.
removeItem
(
'user'
);
history
.
push
(
'/chat'
);
}
else
if
(
response
.
status
===
200
)
{
return
response
;
}
else
{
message
.
error
(
'请求失败,请重试! '
);
return
Promise
.
reject
(
response
.
statusText
);
}
});
export
function
loginChatGLM
(
options
:
ILoginParams
)
{
return
request
(
'https://glm-mangement-api.baibaomen.com/api/app/account/login'
,
{
method
:
'POST'
,
headers
:
{
'Content-Type'
:
'application/json'
,
__tenant
:
'3a0a90fe-9a0d-70f4-200d-a80a41fb6195'
,
},
data
:
options
,
});
}
...
...
@@ -39,7 +48,6 @@ export interface IPromptWord {
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
},
});
}
...
...
@@ -63,15 +71,37 @@ interface ITalkParams {
temperature
?:
number
;
}
// export function talkChatGLM({ prompt, history, max_length = 2000, top_p = 0.9, temperature = 0.8 }: ITalkParams) {
// return request('https://glm-mangement-api.baibaomen.com/', {
// method: 'POST',
// data: {
// prompt,
// history,
// max_length,
// top_p,
// temperature
// }
// })
// }
export
const
CreatedAccount
=
(
params
:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/create'
,
{
method
:
'POST'
,
params
,
});
};
export
const
getRole
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/roles'
,
{
method
:
'POST'
,
params
,
});
};
export
const
getUserMessage
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/page'
,
{
method
:
'POST'
,
data
:
params
,
});
};
export
const
postDeleteUser
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/delete'
,
{
method
:
'POST'
,
data
:
params
,
});
};
export
const
postResetUser
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/delete'
,
{
method
:
'POST'
,
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