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
5539db75
Commit
5539db75
authored
Apr 16, 2023
by
Ylg
Browse files
Options
Browse Files
Download
Plain Diff
feat: working on the prompt page
parents
8f0fc1f4
232e6205
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1351 additions
and
671 deletions
+1351
-671
defaultSettings.ts
config/defaultSettings.ts
+2
-3
logo.png
public/logo.png
+0
-0
access.ts
src/access.ts
+5
-6
index.less
src/components/EditAndAddPromptModal/index.less
+19
-0
index.tsx
src/components/EditAndAddPromptModal/index.tsx
+108
-0
index.tsx
src/components/Footer/index.tsx
+2
-27
Icons.tsx
src/components/Icons/Icons.tsx
+33
-0
exclamation-circle
src/components/Icons/exclamation-circle
+0
-0
index.less
src/components/deletePromptModal/index.less
+25
-0
index.tsx
src/components/deletePromptModal/index.tsx
+39
-4
index.tsx
src/components/loginModal/index.tsx
+41
-20
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
+24
-0
zh-CN.ts
src/locales/zh-CN.ts
+1
-1
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
-9
index.tsx
src/pages/Chat/index.tsx
+162
-143
index.tsx
src/pages/PromptWord/index.tsx
+196
-61
index.less
src/pages/UserManage/index.less
+52
-0
index.tsx
src/pages/UserManage/index.tsx
+322
-121
api.ts
src/services/chatGLM/api.ts
+69
-19
No files found.
config/defaultSettings.ts
View file @
5539db75
...
...
@@ -5,16 +5,15 @@ const Settings: LayoutSettings & {
logo
?:
string
;
}
=
{
navTheme
:
'light'
,
// 拂晓蓝
primaryColor
:
'#009B95'
,
layout
:
'mix'
,
contentWidth
:
'Fluid'
,
fixedHeader
:
false
,
fixSiderbar
:
true
,
colorWeak
:
false
,
title
:
'Ant Design Pro'
,
pwa
:
false
,
logo
:
'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg'
,
logo
:
'/logo.png'
,
title
:
''
,
iconfontUrl
:
''
,
};
...
...
public/logo.png
0 → 100644
View file @
5539db75
24.3 KB
src/access.ts
View file @
5539db75
/**
* @see https://umijs.org/zh-CN/plugins/plugin-access
* */
export
default
function
access
(
initialState
:
{
userInfo
:
{
token
:
''
};
})
{
console
.
log
(
'initialState'
,
initialState
)
const
{
token
}
=
initialState
.
userInfo
??
{};
return
{
token
};
export
default
function
access
(
initialState
:
{
userInfo
:
{
token
:
''
;
roles
:
[];
name
:
''
;
userName
:
''
};
})
{
console
.
log
(
'initialState'
,
initialState
);
return
initialState
.
userInfo
??
{};
}
src/components/EditAndAddPromptModal/index.less
0 → 100644
View file @
5539db75
.edit_type {
display: flex;
align-items: center;
span {
width: 70px;
margin-right: 10px;
}
}
.edit_prompt {
display: flex;
align-items: flex-start;
span {
width: 70px;
margin-right: 10px;
}
}
\ No newline at end of file
src/components/
edit
PromptModal/index.tsx
→
src/components/
EditAndAdd
PromptModal/index.tsx
View file @
5539db75
import
{
Form
,
Modal
,
Select
}
from
"antd"
;
import
TextArea
from
"antd/lib/input/TextArea"
;
import
{
useState
}
from
"react"
;
import
{
use
Effect
,
use
State
}
from
"react"
;
import
styles
from
'./index.less'
;
import
{
CloseOutlined
}
from
"@ant-design/icons
"
;
import
{
IFormValue
}
from
"@/pages/PromptWord
"
;
interface
IEditPromptModalProps
{
open
:
boolean
;
setOpen
:
(
value
:
boolean
)
=>
void
;
types
:
string
[];
modalType
:
'create'
|
'edit'
|
''
;
handleEditPrompt
:
(
value
:
IFormValue
)
=>
void
;
oldRow
:
IFormValue
;
loading
?:
boolean
;
handleCreatePrompt
:
(
value
:
IFormValue
)
=>
void
;
}
const
EditPromptModal
=
(
props
:
IEditPromptModalProps
)
=>
{
const
{
open
,
setOpen
,
types
}
=
props
;
const
{
open
,
setOpen
,
types
,
modalType
,
handleEditPrompt
,
loading
,
oldRow
,
handleCreatePrompt
}
=
props
;
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
currentSelectValue
,
setCurrentSelectValue
]
=
useState
<
string
|
null
>
(
"请选择"
);
const
[
textAreaValue
,
setTextAreaValue
]
=
useState
(
''
);
useEffect
(()
=>
{
if
(
modalType
===
'create'
)
{
setTextAreaValue
(
''
);
setCurrentSelectValue
(
''
);
}
else
{
setTextAreaValue
(
oldRow
.
content
);
setCurrentSelectValue
(
oldRow
.
type
||
'请选择'
);
}
},
[
open
])
const
handleSavePrompt
=
()
=>
{
if
(
modalType
===
'create'
)
{
handleCreatePrompt
({
type
:
currentSelectValue
,
content
:
textAreaValue
,
});
}
if
(
modalType
===
'edit'
)
{
handleEditPrompt
({
type
:
currentSelectValue
,
content
:
textAreaValue
,
})
}
setOpen
(
false
);
};
const
layout
=
{
labelCol
:
{
span
:
3
},
};
return
(
...
...
@@ -25,31 +59,45 @@ const EditPromptModal = (props: IEditPromptModalProps) => {
centered
confirmLoading=
{
loading
}
wrapClassName=
{
styles
.
modal
}
title=
'编辑提示词语'
title=
{
modalType
===
'create'
?
'新增提示用语'
:
'编辑提示用语'
}
okText=
'保存'
onOk=
{
handleSavePrompt
}
onCancel=
{
()
=>
{
setCurrentSelectValue
(
'请选择'
);
setOpen
(
false
);
}
}
width=
{
574
}
bodyStyle=
{
{
padding
:
'20px'
}
}
>
<
Form
>
<
Form
.
Item
>
<
span
>
类型
</
span
>
<
Form
labelAlign=
"right"
{
...
layout
}
>
<
Form
.
Item
label=
"类型:"
>
<
Select
onChange=
{
(
value
:
string
)
=>
{
console
.
log
(
value
);
}
}
value=
{
'市场营销'
}
>
onChange=
{
(
value
:
string
)
=>
{
setCurrentSelectValue
(
value
);
}
}
value=
{
currentSelectValue
}
>
{
types
.
map
(
item
=>
<
Select
.
Option
value=
{
item
}
key=
{
item
}
>
{
item
}
</
Select
.
Option
>)
}
</
Select
>
</
Form
.
Item
>
<
Form
.
Item
>
<
span
>
提示词语
</
span
>
<
Form
.
Item
label=
"提示词语"
>
<
TextArea
autoSize
style=
{
{
height
:
200
}
}
style=
{
{
height
:
'200px'
}
}
value=
{
textAreaValue
}
onChange=
{
(
e
)
=>
{
setTextAreaValue
(
e
.
target
.
value
);
}
}
/>
</
Form
.
Item
>
</
Form
>
...
...
src/components/Footer/index.tsx
View file @
5539db75
import
{
GithubOutlined
}
from
'@ant-design/icons'
;
import
{
DefaultFooter
}
from
'@ant-design/pro-components'
;
import
{
useIntl
}
from
'umi'
;
...
...
@@ -6,36 +5,12 @@ const Footer: React.FC = () => {
const
intl
=
useIntl
();
const
defaultMessage
=
intl
.
formatMessage
({
id
:
'app.copyright.produced'
,
defaultMessage
:
'
蚂蚁集团体验技术部出品
'
,
defaultMessage
:
'
2023 长沙振升集团有限公司
'
,
});
const
currentYear
=
new
Date
().
getFullYear
();
return
(
<
DefaultFooter
copyright=
{
`${currentYear} ${defaultMessage}`
}
links=
{
[
{
key
:
'Ant Design Pro'
,
title
:
'Ant Design Pro'
,
href
:
'https://pro.ant.design'
,
blankTarget
:
true
,
},
{
key
:
'github'
,
title
:
<
GithubOutlined
/>,
href
:
'https://github.com/ant-design/ant-design-pro'
,
blankTarget
:
true
,
},
{
key
:
'Ant Design'
,
title
:
'Ant Design'
,
href
:
'https://ant.design'
,
blankTarget
:
true
,
},
]
}
/>
);
return
<
DefaultFooter
copyright=
{
`${currentYear} ${defaultMessage}`
}
/>;
};
export
default
Footer
;
src/components/Icons/Icons.tsx
0 → 100644
View file @
5539db75
import
Icon
from
'@ant-design/icons'
;
const
ExclamtionSvg
=
()
=>
(
<
svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
>
<
title
>
exclamation-circle
</
title
>
<
g
id=
"页面-1"
stroke=
"none"
strokeWidth=
"1"
fill=
"none"
fillRule=
"evenodd"
opacity=
"0.65"
>
<
g
id=
"10-3-删除账号"
transform=
"translate(-542.000000, -405.000000)"
fill=
"#FF8F00"
fillRule=
"nonzero"
>
<
g
id=
"编辑账号"
transform=
"translate(470.000000, 321.000000)"
>
<
g
id=
"exclamation-circle"
transform=
"translate(72.000000, 84.000000)"
>
<
path
d=
"M12,0 C5.371875,0 0,5.371875 0,12 C0,18.628125 5.371875,24 12,24 C18.628125,24 24,18.628125 24,12 C24,5.371875 18.628125,0 12,0 Z M11.0625,5.4140625 C11.0625,4.89609375 11.4820312,4.4765625 12,4.4765625 C12.5179688,4.4765625 12.9375,4.89609375 12.9375,5.4140625 L12.9375,14.0625 C12.9375,14.5804688 12.5179688,15 12,15 C11.4820312,15 11.0625,14.5804688 11.0625,14.0625 L11.0625,5.4140625 Z M12,18.609375 C11.4164063,18.609375 10.9453125,18.1382812 10.9453125,17.5546875 C10.9453125,16.9710938 11.4164063,16.5 12,16.5 C12.5835937,16.5 13.0546875,16.9710938 13.0546875,17.5546875 C13.0546875,18.1359375 12.5835937,18.609375 12,18.609375 Z"
id=
"Shape"
/>
</
g
>
</
g
>
</
g
>
</
g
>
</
svg
>
);
export
const
Exclamtion
=
(
props
:
any
)
=>
{
return
<
Icon
component=
{
ExclamtionSvg
}
{
...
props
}
/>;
};
src/components/
editPromptModal/index.less
→
src/components/
Icons/exclamation-circle
View file @
5539db75
File moved
src/components/deletePromptModal/index.less
View file @
5539db75
.deleteTitle {
display: flex;
height: 22px;
margin-bottom: 10px;
color: rgba(0, 0, 0, 0.85);
font-weight: 600;
font-size: 16px;
font-family: PingFangSC-Semibold, PingFang SC;
line-height: 22px;
& svg {
width: 24px;
height: 24px;
margin-right: 10px;
}
}
.deleteContent {
width: 322px;
height: 44px;
margin-left: 34px;
color: rgba(0, 0, 0, 0.65);
font-weight: 400;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
line-height: 22px;
}
\ No newline at end of file
src/components/deletePromptModal/index.tsx
View file @
5539db75
import
{
Modal
}
from
"antd"
;
import
styles
from
'./index.less'
;
import
{
Exclamtion
}
from
"../Icons/Icons"
;
interface
IDeletePromptModalProps
{
title
:
string
;
open
:
boolean
;
setOpen
:
(
value
:
boolean
)
=>
void
;
tip
:
string
;
content
:
string
;
handleDeletePrompt
:
()
=>
void
;
loading
?:
boolean
;
}
const
DeletePromptModal
=
(
props
:
IDeletePromptModalProps
)
=>
{
const
{
title
,
open
,
setOpen
,
tip
,
content
,
loading
,
}
=
props
;
const
handleDeletePrompt
=
()
=>
{
handleDeletePrompt
();
}
const
DeletePromptModal
=
()
=>
{
return
(
<
Modal
title=
{
title
}
okText=
'确认'
open=
{
open
}
onOk=
{
handleDeletePrompt
}
onCancel=
{
()
=>
{
setOpen
(
false
);
}
}
confirmLoading=
{
loading
}
>
<
div
className=
{
styles
.
deleteTitle
}
>
<
Exclamtion
/>
{
tip
}
</
div
>
<
div
className=
{
styles
.
deleteContent
}
>
{
content
}
</
div
>
</
Modal
>
)
}
...
...
src/components/loginModal/index.tsx
View file @
5539db75
...
...
@@ -2,8 +2,9 @@ import styles from './index.less';
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
{
use
Effect
,
useRef
,
use
State
}
from
'react'
;
import
{
loginChatGLM
}
from
'@/services/chatGLM/api'
;
import
{
useModel
}
from
'umi'
;
interface
ILoginModalProps
{
open
:
boolean
;
setOpen
:
(
value
:
boolean
)
=>
void
;
...
...
@@ -11,14 +12,28 @@ interface ILoginModalProps {
const
LoginModal
=
(
props
:
ILoginModalProps
)
=>
{
const
{
open
,
setOpen
}
=
props
;
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
{
initialState
,
setInitialState
}
=
useModel
(
'@@initialState'
);
const
[
form
]
=
Form
.
useForm
();
const
submitRef
=
useRef
<
HTMLButtonElement
>
(
null
);
const
reset
=
()
=>
{
setOpen
(
false
);
form
.
resetFields
();
};
};
useEffect
(()
=>
{
if
(
open
)
{
const
account
=
localStorage
.
getItem
(
'account'
);
localStorage
.
removeItem
(
'account'
);
if
(
account
)
{
setTimeout
(()
=>
{
submitRef
.
current
?.
click
();
},
300
);
}
}
},
[
open
]);
const
handleSubmit
=
async
(
values
:
any
)
=>
{
setLoading
(
true
);
...
...
@@ -28,14 +43,23 @@ const LoginModal = (props: ILoginModalProps) => {
name
:
username
,
password
,
});
if
(
checked
)
{
localStorage
.
setItem
(
'account'
,
JSON
.
stringify
({
username
,
password
,
checked
}));
}
setInitialState
({
...
initialState
,
userInfo
:
result
});
localStorage
.
setItem
(
'user'
,
JSON
.
stringify
(
result
));
setLoading
(
false
);
reset
();
}
catch
(
error
)
{
}
catch
(
error
)
{
setLoading
(
false
);
}
};
function
getAccount
()
{
const
account
=
localStorage
.
getItem
(
'account'
);
return
JSON
.
parse
(
account
||
JSON
.
stringify
({
username
:
''
,
password
:
''
,
checked
:
false
}));
}
return
(
<
Modal
open=
{
open
}
...
...
@@ -57,31 +81,28 @@ const LoginModal = (props: ILoginModalProps) => {
</
div
>
<
p
className=
{
styles
.
modal_tip
}
>
账户密码登录
</
p
>
<
Form
initialValues=
{
getAccount
()
}
name=
"normal_login"
initialValues=
{
{
remember
:
true
}
}
onFinish=
{
handleSubmit
}
onValuesChange=
{
(
value
)
=>
{
console
.
log
(
value
);
}
}
className=
{
styles
.
modal_form
}
>
<
Form
.
Item
name=
"username"
rules=
{
[{
required
:
true
,
message
:
'请输入你的账户!'
}]
}
>
<
Input
prefix=
{
<
UserOutlined
/>
}
placeholder=
"账户"
/>
<
Form
.
Item
name=
"username"
rules=
{
[{
required
:
true
,
message
:
'请输入你的账户!'
}]
}
>
<
Input
prefix=
{
<
UserOutlined
/>
}
placeholder=
"账户"
value=
{
''
}
/>
</
Form
.
Item
>
<
Form
.
Item
name=
"password"
rules=
{
[{
required
:
true
,
message
:
'请输入你的密码!'
}]
}
>
<
Input
prefix=
{
<
LockOutlined
/>
}
type=
"password"
placeholder=
"密码"
/>
<
Form
.
Item
name=
"password"
rules=
{
[{
required
:
true
,
message
:
'请输入你的密码!'
}]
}
>
<
Input
prefix=
{
<
LockOutlined
/>
}
type=
"password"
placeholder=
"密码"
value=
{
''
}
/>
</
Form
.
Item
>
<
Form
.
Item
name=
"
remember
"
valuePropName=
"checked"
className=
{
styles
.
modal_checked
}
>
<
Form
.
Item
name=
"
checked
"
valuePropName=
"checked"
className=
{
styles
.
modal_checked
}
>
<
Checkbox
>
自动登录
</
Checkbox
>
</
Form
.
Item
>
<
Form
.
Item
>
<
Button
type=
"primary"
htmlType=
"submit"
className=
{
styles
.
modal_button
}
loading=
{
loading
}
>
<
Button
ref=
{
submitRef
}
type=
"primary"
htmlType=
"submit"
className=
{
styles
.
modal_button
}
loading=
{
loading
}
>
登录
</
Button
>
</
Form
.
Item
>
...
...
src/components/newSession/answer.component.tsx
View file @
5539db75
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 @
5539db75
@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 @
5539db75
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 @
5539db75
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 @
5539db75
...
...
@@ -6,12 +6,36 @@
@colorMainDefault: #999999;
@colorMainSubDefault: #666666;
.ant-btn-primary {
color: #fff;
background-color: #009b95;
border-color: #009b95;
border-radius: 2px;
}
: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;
}
}
html,
body,
#root {
height: 100%;
}
body {
margin: 0;
padding: 0;
}
.colorWeak {
filter: invert(80%);
}
...
...
src/locales/zh-CN.ts
View file @
5539db75
...
...
@@ -11,7 +11,7 @@ export default {
'layout.user.link.help'
:
'帮助'
,
'layout.user.link.privacy'
:
'隐私'
,
'layout.user.link.terms'
:
'条款'
,
'app.copyright.produced'
:
'
蚂蚁集团体验技术部出品
'
,
'app.copyright.produced'
:
'
长沙振升集团有限公司
'
,
'app.preview.down.block'
:
'下载此页面到本地项目'
,
'app.welcome.link.fetch-blocks'
:
'获取全部区块'
,
'app.welcome.link.block-list'
:
'基于 block 开发,快速构建标准页面'
,
...
...
src/pages/Chat/components/content.less
View file @
5539db75
...
...
@@ -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 @
5539db75
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 @
5539db75
.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 @
5539db75
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 @
5539db75
...
...
@@ -3,35 +3,33 @@
.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;
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 +66,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 +95,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 +109,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 @
5539db75
/* 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,8 +17,9 @@ 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'
;
import
{
PageLoading
}
from
'@ant-design/pro-layout'
;
const
{
useBreakpoint
}
=
Grid
;
const
{
Title
}
=
Typography
;
...
...
@@ -35,24 +37,29 @@ const Chat: React.FC = () => {
const
[
showSider
,
setShowSider
]
=
useState
(
true
);
const
[
firstChat
,
setFirstChat
]
=
useState
(
false
);
const
[
form
]
=
Form
.
useForm
();
const
[
selectSiderTabs
,
setSelectSiderTabs
]
=
useState
(
''
);
const
{
data
:
glmToken
}
=
useRequest
(
GetChatGLMToken
);
const
{
data
:
glmToken
,
run
:
getChatGLMToken
}
=
useRequest
(
GetChatGLMToken
,
{
manual
:
true
});
const
{
data
:
promptList
,
loading
:
promptLoading
,
run
:
getPromptList
,
}
=
useRequest
(
GetPromptList
,
{
manual
:
true
});
const
[
answer
,
setAnswer
]
=
useState
(
''
);
const
[
loading
,
setLoading
]
=
useState
(
true
);
const
[
open
,
setOpen
]
=
useState
(
false
);
const
tabShow
=
showSider
&&
!
isMobile
;
const
[
loginModalOpen
,
setLoginModalOpen
]
=
useState
(
false
);
const
access
=
useAccess
();
const
messageHistory
=
useRef
<
IHistory
[]
>
([]);
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 +78,7 @@ const Chat: React.FC = () => {
return
messageHistory
.
current
;
},
[
answer
]);
async
function
handleSendMessage
()
{
messageHistory
.
current
.
push
({
prompt
:
chat
,
answer
:
''
});
setLoading
(
true
);
sendMessage
&&
sendMessage
(
...
...
@@ -83,14 +91,15 @@ const Chat: React.FC = () => {
token
:
glmToken
,
}),
);
messageHistory
.
current
.
push
({
prompt
:
chat
,
answer
:
''
});
}
useEffect
(()
=>
{
if
(
access
?.
token
)
{
setOpen
(
false
);
if
(
access
?.
token
)
{
getChatGLMToken
();
getPromptList
();
setLoginModalOpen
(
false
);
}
else
{
setOpen
(
true
);
set
LoginModal
Open
(
true
);
}
},
[
access
]);
...
...
@@ -110,169 +119,179 @@ 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
>
);
};
return
(
<>
<
LoginModal
open=
{
open
}
setOpen=
{
set
Open
}
/>
<
LoginModal
open=
{
loginModalOpen
}
setOpen=
{
setLoginModal
Open
}
/>
{
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
}
hidden=
{
!
access
.
roles
?.
find
((
x
)
=>
[
'管理员'
,
'admin'
].
includes
(
x
))
}
>
<
Space
wrap
onClick=
{
()
=>
{
history
.
push
(
'/admin/user'
);
}
}
>
<
SettingOutlined
/>
后台管理
</
Space
>
</
Col
>
<
Col
span=
{
24
}
className=
{
styles
.
chatFooterItem
}
style=
{
{
color
:
'#009B95'
}
}
>
<
Space
wrap
>
<
UserOutlined
/>
{
access
?.
name
||
'请先登录'
}
</
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
className=
{
styles
.
chatContent
}
style=
{
{
marginLeft
:
isMobile
?
0
:
240
,
width
:
isMobile
?
'calc(100vw)'
:
'calc(100vw - 240px)'
,
}
}
>
<
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
>
{
promptLoading
&&
(
<
Col
span=
{
24
}
>
<
Title
level=
{
5
}
className=
{
styles
.
subTitle
}
>
AI改变世界
</
Title
>
<
PageLoading
></
PageLoading
>
</
Col
>
</
Row
>
</
div
>
)
}
<
Form
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"
)
}
<
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/pages/PromptWord/index.tsx
View file @
5539db75
...
...
@@ -2,56 +2,49 @@ import { DeleteOutlined, EditOutlined, 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
,
Col
,
Divider
,
Form
,
Input
,
Modal
,
Radio
,
Row
,
Switch
,
message
}
from
'antd'
;
import
{
Button
,
Col
,
Divider
,
Form
,
Input
,
Modal
,
Radio
,
Row
,
S
elect
,
S
witch
,
message
}
from
'antd'
;
import
{
isEmpty
}
from
'lodash'
;
import
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
SetStateAction
,
useEffect
,
useRef
,
useState
}
from
'react'
;
import
styles
from
'./index.less'
;
import
EditPromptModal
from
'@/components/editPromptModal'
;
import
{
pagePromptWords
,
createPromptWords
,
updatePromptWords
,
deletePromptWords
}
from
'@/services/chatGLM/api'
;
import
EditPromptModal
from
'@/components/EditAndAddPromptModal'
;
import
DeletePromptModal
from
'@/components/DeletePromptModal'
;
import
{
pagePromptWords
,
createPromptWords
,
updatePromptWords
,
deletePromptWords
,
typePromptWords
}
from
'@/services/chatGLM/api'
;
const
{
Item
}
=
Form
;
interface
DataType
{
key
:
string
;
sequenceNumber
:
number
;
promptWord
:
string
;
interface
IPromptList
{
id
:
string
;
title
?:
string
;
content
:
string
;
type
:
string
;
creationTime
:
string
;
sequenceNumber
:
number
;
}
const
data
:
DataType
[]
=
[
{
key
:
'1'
,
sequenceNumber
:
0
,
type
:
'会议记录'
,
promptWord
:
'请根据以下简要说明,为我撰写一份关于新员'
,
creationTime
:
'2023-03-21 09:12:00'
},
{
key
:
'2'
,
sequenceNumber
:
1
,
type
:
'会议记录'
,
promptWord
:
'请根据以下简要说明,为我撰写一份关于新员'
,
creationTime
:
'2023-03-21 09:12:00'
},
{
key
:
'3'
,
sequenceNumber
:
2
,
type
:
'会议记录'
,
promptWord
:
'请根据以下简要说明,为我撰写一份关于新员'
,
creationTime
:
'2023-03-21 09:12:00'
},
];
export
interface
IFormValue
{
type
:
string
|
null
;
content
:
string
;
}
const
PromptWord
=
()
=>
{
const
actionRef
=
useRef
<
ActionType
>
();
interface
ILoading
{
editModalLoading
:
boolean
;
createModalLoading
:
boolean
;
deleteModalLoading
:
boolean
;
listLoading
:
boolean
;
}
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
editModalOpen
,
setEditModalOpen
]
=
useState
(
false
);
const
PromptWord
=
()
=>
{
const
[
allLoading
,
setAllLoading
]
=
useState
<
ILoading
>
({
editModalLoading
:
false
,
createModalLoading
:
false
,
deleteModalLoading
:
false
,
listLoading
:
false
});
const
[
editAndAddModalOpen
,
setEditAndDeleteModalOpen
]
=
useState
(
false
);
const
[
deleteModalOpen
,
setDeleteModalOpen
]
=
useState
(
false
);
const
[
promptList
,
setPromptList
]
=
useState
([]);
const
[
promptList
,
setPromptList
]
=
useState
<
IPromptList
[]
>
([]);
const
[
form
]
=
Form
.
useForm
();
const
[
modalType
,
setModalType
]
=
useState
<
'create'
|
'edit'
|
''
>
(
''
);
const
[
types
,
setTypes
]
=
useState
<
string
[]
>
([]);
const
[
currentRow
,
setCurrentRaw
]
=
useState
({}
as
IPromptList
);
const
columns
:
any
[]
=
[
{
...
...
@@ -66,22 +59,31 @@ const PromptWord = () => {
width
:
'15%'
,
key
:
'type'
,
dataIndex
:
'type'
,
search
:
false
,
valueType
:
'select'
,
order
:
1
,
fieldProps
:
{
options
:
types
.
map
((
type
)
=>
{
return
{
label
:
type
,
value
:
type
}
})
}
},
{
title
:
'提示词语'
,
width
:
'
50
%'
,
width
:
'
45
%'
,
key
:
'promptWord'
,
dataIndex
:
'
promptWord
'
,
dataIndex
:
'
content
'
,
ellipsis
:
true
,
search
:
false
,
search
:
true
,
order
:
2
},
{
title
:
'创建时间'
,
width
:
'1
0
%'
,
width
:
'1
5
%'
,
key
:
'creationTime'
,
dataIndex
:
'creationTime'
,
valueType
:
'date'
,
search
:
false
,
},
{
...
...
@@ -89,17 +91,27 @@ const PromptWord = () => {
valueType
:
'option'
,
width
:
'15%'
,
key
:
'option'
,
render
:
(
_
:
unknown
,
record
:
any
)
=>
(
render
:
(
_
:
unknown
,
record
:
IPromptList
)
=>
(
<
div
className=
{
styles
.
table_action
}
>
<
div
className=
{
styles
.
table_action_edit
}
onClick=
{
()
=>
setEditModalOpen
(
true
)
}
onClick=
{
()
=>
{
setCurrentRaw
(
record
);
setEditAndDeleteModalOpen
(
true
);
setModalType
(
'edit'
);
}
}
>
<
EditOutlined
/>
<
span
>
编辑
</
span
>
</
div
>
<
span
style=
{
{
margin
:
'0 9px'
}
}
>
|
</
span
>
<
div
className=
{
styles
.
table_action_delete
}
>
<
div
className=
{
styles
.
table_action_delete
}
onClick=
{
()
=>
{
setDeleteModalOpen
(
true
);
setCurrentRaw
(
record
);
}
}
>
<
DeleteOutlined
/>
<
span
>
删除
</
span
>
</
div
>
...
...
@@ -109,39 +121,160 @@ const PromptWord = () => {
];
const
fetchPromptList
=
async
()
=>
{
const
data
=
await
createPromptWords
({
setAllLoading
({
...
allLoading
,
listLoading
:
true
,
})
try
{
const
response
=
await
pagePromptWords
({
filter
:
''
,
type
:
''
,
pageIndex
:
0
,
pageSize
:
10
})
setAllLoading
({
...
allLoading
,
listLoading
:
false
,
})
const
dataSource
:
IPromptList
[]
=
response
.
items
.
map
((
item
:
IPromptList
)
=>
{
return
{
...
item
,
}
})
setPromptList
(
dataSource
);
}
catch
(
error
)
{
setAllLoading
({
...
allLoading
,
listLoading
:
false
,
})
message
.
error
(
'请求列表失败,请重试!'
)
}
};
const
fetchTypes
=
async
()
=>
{
const
data
=
await
typePromptWords
();
setTypes
(
data
);
};
useEffect
(()
=>
{
fetchPromptList
();
fetchTypes
();
},
[]);
const
layout
=
{
labelCol
:
{
span
:
4
},
wrapperCol
:
{
span
:
18
},
const
handleEditPrompt
=
async
(
editValue
:
IFormValue
)
=>
{
setAllLoading
({
...
allLoading
,
editModalLoading
:
true
,
})
try
{
await
updatePromptWords
({
id
:
currentRow
.
id
,
content
:
editValue
.
content
,
type
:
editValue
.
type
});
setAllLoading
({
...
allLoading
,
editModalLoading
:
false
,
})
fetchPromptList
();
}
catch
(
error
)
{
setAllLoading
({
...
allLoading
,
editModalLoading
:
false
,
})
message
.
error
(
'编辑提示用语失败,请重试!'
)
}
};
const
handleCreatePrompt
=
async
(
createValue
:
IFormValue
)
=>
{
setAllLoading
({
...
allLoading
,
createModalLoading
:
true
,
})
try
{
await
createPromptWords
({
content
:
createValue
.
content
,
type
:
createValue
.
type
})
setAllLoading
({
...
allLoading
,
createModalLoading
:
false
,
})
fetchPromptList
();
}
catch
(
error
)
{
setAllLoading
({
...
allLoading
,
createModalLoading
:
false
,
})
message
.
error
(
'新增提示用语失败,请重试!'
)
}
};
const
showModal
=
()
=>
{
const
handleDeletePrompt
=
async
()
=>
{
setAllLoading
({
...
allLoading
,
deleteModalLoading
:
true
,
})
try
{
await
deletePromptWords
({
id
:
currentRow
.
id
});
setAllLoading
({
...
allLoading
,
deleteModalLoading
:
false
,
})
fetchPromptList
();
}
catch
(
error
)
{
setAllLoading
({
...
allLoading
,
deleteModalLoading
:
false
,
})
message
.
error
(
'删除提示用语失败,请重试!'
)
}
};
return
(
<
PageContainer
>
<
DeletePromptModal
open=
{
deleteModalOpen
}
setOpen=
{
setDeleteModalOpen
}
title=
'删除提示用语'
tip=
'确定要删除这段提示词语吗?'
content=
'一旦删除后,用户无法看到这一条提示词,建议谨慎操作。'
handleDeletePrompt=
{
handleDeletePrompt
}
loading=
{
allLoading
.
deleteModalLoading
}
/>
<
EditPromptModal
open=
{
editModalOpen
}
setOpen=
{
setEditModalOpen
}
types=
{
[
'会议记录'
,
'技术文档'
]
}
open=
{
editAndAddModalOpen
}
setOpen=
{
setEditAndDeleteModalOpen
}
types=
{
types
}
modalType=
{
modalType
}
handleEditPrompt=
{
handleEditPrompt
}
oldRow=
{
currentRow
}
handleCreatePrompt=
{
handleCreatePrompt
}
loading=
{
modalType
===
'create'
?
allLoading
.
createModalLoading
:
allLoading
.
editModalLoading
}
/>
<
ProTable
dataSource=
{
data
}
dataSource=
{
promptList
}
columns=
{
columns
}
actionRef=
{
actionRef
}
cardBordered
rowKey=
"id"
pagination=
{
{
pageSize
:
5
,
onChange
:
(
page
)
=>
{},
onChange
:
(
page
)
=>
{
},
}
}
search=
{
{
labelWidth
:
'auto'
,
className
:
styles
.
search
,
optionRender
:
()
=>
{
return
[
<
Button
type=
'default'
key=
'2'
>
重置
</
Button
>,
<
Button
type=
'primary'
key=
'3'
>
查询
</
Button
>
]
}
}
}
options=
{
false
}
dateFormatter=
"string"
...
...
@@ -151,13 +284,15 @@ const PromptWord = () => {
key=
"button"
icon=
{
<
PlusOutlined
/>
}
onClick=
{
()
=>
{
setEditAndDeleteModalOpen
(
true
);
setModalType
(
'create'
);
}
}
type=
"primary"
>
添加提示语
</
Button
>,
]
}
loading=
{
allLoading
.
listLoading
}
/>
</
PageContainer
>
);
...
...
src/pages/UserManage/index.less
0 → 100644
View file @
5539db75
.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;
}
.deleteTitle {
display: flex;
height: 22px;
margin-bottom: 10px;
color: rgba(0, 0, 0, 0.85);
font-weight: 600;
font-size: 16px;
font-family: PingFangSC-Semibold, PingFang SC;
line-height: 22px;
& svg {
width: 24px;
height: 24px;
margin-right: 10px;
}
}
.deleteContent {
width: 322px;
height: 44px;
margin-left: 34px;
color: rgba(0, 0, 0, 0.65);
font-weight: 400;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
line-height: 22px;
}
.footer {
height: 20px;
color: rgba(0, 0, 0, 0.45);
font-weight: 400;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
line-height: 20px;
text-align: center;
}
src/pages/UserManage/index.tsx
View file @
5539db75
import
{
CreatedAccount
,
getRole
,
getUserMessage
}
from
'@/services/chatGLM/api'
;
import
{
CreatedAccount
,
getRole
,
getUserMessage
,
postDeleteUser
,
postResetUser
,
postEditUser
,
}
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
,
Col
,
Divider
,
Form
,
Input
,
Modal
,
Radio
,
Row
,
Switch
,
message
}
from
'antd'
;
import
{
Button
,
Col
,
Divider
,
Form
,
Input
,
Modal
,
Radio
,
Row
,
Select
,
Switch
,
message
,
}
from
'antd'
;
import
classNames
from
'classnames'
;
import
{
isEmpty
}
from
'lodash'
;
import
{
useRef
,
useState
}
from
'react'
;
import
request
from
'umi-request'
;
import
styles
from
'./index.less'
;
import
{
Exclamtion
}
from
'@/components/Icons/Icons'
;
const
{
Item
}
=
Form
;
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
layout
=
{
labelCol
:
{
span
:
4
},
wrapperCol
:
{
span
:
18
},
};
const
resetLayout
=
{
labelCol
:
{
span
:
6
},
wrapperCol
:
{
span
:
16
},
};
const
UserManage
=
()
=>
{
const
actionRef
=
useRef
<
ActionType
>
();
const
[
isModalOpen
,
setIsModalOpen
]
=
useState
(
false
);
const
[
accountForm
]
=
useState
({
const
[
isModalAccountOpen
,
setIsModalAccountOpen
]
=
useState
(
false
);
const
[
isModalDeleteAccountOpen
,
setIsModalDeleteAccountOpen
]
=
useState
(
false
);
const
[
editMessage
,
setEditMessage
]
=
useState
({
id
:
''
,
});
const
[
deleteMessage
,
setDeleteMessage
]
=
useState
({
name
:
''
,
id
:
' '
,
});
const
[
isModalResetPassword
,
setIsModalResetPassword
]
=
useState
(
false
);
const
[
resetPassword
,
setResetPassword
]
=
useState
({
id
:
''
,
Name
:
''
,
Phone
:
''
,
Role
:
''
,
IsActive
:
true
,
Password
:
''
,
});
const
[
roles
,
setRoles
]
=
useState
([]);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
ressetLoading
,
setResetLoading
]
=
useState
(
false
);
const
[
accountModalName
,
setAccountModalName
]
=
useState
(
'新建账号'
);
const
[
form
]
=
Form
.
useForm
();
const
layout
=
{
labelCol
:
{
span
:
4
},
wrapperCol
:
{
span
:
18
},
};
const
[
accountForm
]
=
Form
.
useForm
();
const
isActiveSelectOption
=
[
{
label
:
'启用'
,
value
:
true
},
{
label
:
'禁用'
,
value
:
false
},
];
const
showModal
=
()
=>
{
getRole
()
.
then
((
res
)
=>
{
console
.
log
(
res
);
if
(
!
isEmpty
(
res
))
{
setRoles
(
res
);
setIsModalOpen
(
true
);
}
})
.
catch
((
err
)
=>
{
message
.
error
(
'获取用户权限失败,请重试'
);
});
getRole
().
then
((
res
)
=>
{
if
(
!
isEmpty
(
res
))
{
setRoles
(
res
);
setIsModalAccountOpen
(
true
);
}
});
};
const
columns
:
any
[]
=
[
{
title
:
'用户'
,
dataIndex
:
'name'
,
ellipsis
:
true
,
},
{
title
:
'用户账号'
,
dataIndex
:
'userName'
,
hideInSearch
:
true
,
ellipsis
:
true
,
},
{
title
:
'角色'
,
dataIndex
:
'roles'
,
hideInSearch
:
true
,
ellipsis
:
true
,
},
{
title
:
'账号状态'
,
dataIndex
:
'isActive'
,
valueType
:
'select'
,
valueEnum
:
{
true
:
{
text
:
'启用'
,
status
:
'Success'
,
},
false
:
{
text
:
'禁用'
,
status
:
'Error'
,
},
},
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
(
'编辑账号'
);
setEditMessage
({
id
:
record
.
id
});
const
data
=
{
id
:
record
.
id
,
Name
:
record
.
name
,
UserName
:
record
.
userName
,
Role
:
record
.
roles
,
isActive
:
record
.
isActive
,
};
accountForm
.
setFieldsValue
(
data
);
showModal
();
}
}
>
编辑
</
a
>,
<
a
onClick=
{
()
=>
{
setResetPassword
({
id
:
record
.
id
,
});
setIsModalResetPassword
(
true
);
}
}
key=
"reset"
>
重置
</
a
>,
<
a
key=
"remove"
onClick=
{
()
=>
{
setDeleteMessage
(
record
);
setIsModalDeleteAccountOpen
(
true
);
}
}
>
删除
</
a
>,
],
},
];
const
handleOk
=
()
=>
{
setIsModalOpen
(
false
);
setIsModal
Account
Open
(
false
);
};
const
handleModalCancel
=
()
=>
{
f
orm
.
resetFields
();
setIsModalOpen
(
false
);
accountF
orm
.
resetFields
();
setIsModal
Account
Open
(
false
);
};
const
createdAccount
=
(
values
:
any
)
=>
{
...
...
@@ -119,6 +193,26 @@ const UserManage = () => {
CreatedAccount
(
values
)
.
then
((
res
)
=>
{
setLoading
(
false
);
setIsModalAccountOpen
(
false
);
actionRef
.
current
?.
reload
();
})
.
catch
((
error
)
=>
{
setLoading
(
false
);
});
};
const
editAccountFinish
=
(
values
:
any
)
=>
{
setLoading
(
true
);
const
data
=
{
...
values
,
id
:
editMessage
.
id
,
};
postEditUser
(
data
)
.
then
((
res
)
=>
{
setLoading
(
false
);
setIsModalAccountOpen
(
false
);
message
.
success
(
'编辑成功'
);
actionRef
.
current
?.
reload
();
})
.
catch
((
error
)
=>
{
setLoading
(
false
);
...
...
@@ -129,10 +223,9 @@ const UserManage = () => {
if
(
accountModalName
===
'添加账号'
)
{
createdAccount
(
values
);
}
};
const
onHandleClickAccountChange
=
(
values
:
any
)
=>
{
console
.
log
(
values
);
if
(
accountModalName
===
'编辑账号'
)
{
editAccountFinish
(
values
);
}
};
const
validatePhoneNumber
=
(
_
,
value
:
any
)
=>
{
...
...
@@ -159,42 +252,145 @@ const UserManage = () => {
return
Promise
.
reject
(
new
Error
(
'密码格式不正确!'
));
};
const
handleClickOpenModalDelete
=
()
=>
{
postDeleteUser
({
id
:
deleteMessage
.
id
,
})
.
then
((
res
)
=>
{
setIsModalDeleteAccountOpen
(
false
);
actionRef
.
current
?.
reload
();
message
.
success
(
'删除成功'
);
})
.
catch
((
err
)
=>
{
setIsModalDeleteAccountOpen
(
false
);
});
};
const
handleClickOpenModalReset
=
(
values
:
any
)
=>
{
setResetLoading
(
true
);
const
data
=
{
id
:
resetPassword
.
id
,
Password
:
values
?.
newPassword
,
};
postResetUser
(
data
)
.
then
((
res
)
=>
{
setResetLoading
(
false
);
setIsModalResetPassword
(
false
);
actionRef
.
current
?.
reload
();
message
.
success
(
'重置成功'
);
})
.
catch
((
err
)
=>
{
setResetLoading
(
false
);
});
};
return
(
<
PageContainer
>
<
Modal
title=
"删除账号"
destroyOnClose=
{
true
}
open=
{
isModalDeleteAccountOpen
}
onOk=
{
handleClickOpenModalDelete
}
onCancel=
{
()
=>
{
setIsModalDeleteAccountOpen
(
false
);
}
}
>
<
div
className=
{
styles
.
deleteTitle
}
>
<
Exclamtion
/>
确定要删除
{
deleteMessage
.
name
}
的账号吗?
</
div
>
<
div
className=
{
styles
.
deleteContent
}
>
一旦删除账号,则无法再使用且该账号下所有信息会被清除,请谨慎操作。
</
div
>
</
Modal
>
<
Modal
closable=
{
true
}
title=
"重置密码"
destroyOnClose=
{
true
}
open=
{
isModalResetPassword
}
onCancel=
{
()
=>
{
setIsModalResetPassword
(
false
);
}
}
footer=
{
null
}
>
<
Form
{
...
resetLayout
}
onFinish=
{
handleClickOpenModalReset
}
name=
"resetPassword"
>
<
Item
name=
{
'newPassword'
}
label=
{
'新密码'
}
rules=
{
[{
required
:
true
,
message
:
'请输入密码!'
},
{
validator
:
validatePassword
}]
}
>
<
Input
placeholder=
"请输入6-12位的数字或者字母"
/>
</
Item
>
<
Item
name=
{
'confirmNewPassword'
}
label=
{
'确认新密码'
}
rules=
{
[
{
required
:
true
,
message
:
'请确认你的密码'
,
},
({
getFieldValue
})
=>
({
validator
(
_
,
value
)
{
if
(
!
value
||
getFieldValue
(
'newPassword'
)
===
value
)
{
return
Promise
.
resolve
();
}
return
Promise
.
reject
(
new
Error
(
'两次密码输入不一致!'
));
},
}),
]
}
>
<
Input
placeholder=
"请确认你的新密码"
/>
</
Item
>
<
Divider
/>
<
Row
justify=
{
'center'
}
>
<
Col
>
<
Item
key=
{
'saveButton'
}
noStyle=
{
true
}
>
<
Button
key=
"submit"
type=
"primary"
loading=
{
ressetLoading
}
htmlType=
"submit"
>
重置
</
Button
>
</
Item
>
</
Col
>
</
Row
>
</
Form
>
</
Modal
>
<
Modal
title=
{
`${accountModalName}`
}
open=
{
isModalOpen
}
open=
{
isModal
Account
Open
}
onOk=
{
handleOk
}
onCancel=
{
handleModalCancel
}
footer=
{
null
}
maskClosable=
{
false
}
destroyOnClose=
{
true
}
>
<
Form
{
...
layout
}
form=
{
f
orm
}
form=
{
accountF
orm
}
onFinish=
{
onHandleClickAccountFinish
}
onValuesChange=
{
onHandleClickAccountChange
}
labelAlign=
"right"
name=
"accountSetting"
initialValues=
{
accountForm
}
>
<
Item
name=
{
'Phone'
}
label=
"用户账号"
rules=
{
[
{
required
:
true
,
message
:
'请输入手机号!'
},
{
validator
:
validatePhoneNumber
},
]
}
>
<
Input
/>
</
Item
>
<
Item
name=
{
'Password'
}
label=
"密码"
rules=
{
[{
required
:
true
,
message
:
'请输入密码!'
},
{
validator
:
validatePassword
}]
}
>
<
Input
/>
</
Item
>
{
accountModalName
===
'添加账号'
&&
(
<>
<
Item
name=
{
'UserName'
}
label=
"用户账号"
rules=
{
[
{
required
:
true
,
message
:
'请输入手机号!'
},
{
validator
:
validatePhoneNumber
},
]
}
>
<
Input
/>
</
Item
>
<
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
)
=>
{
...
...
@@ -209,8 +405,8 @@ const UserManage = () => {
<
Item
name=
{
'Name'
}
label=
"姓名"
rules=
{
[{
required
:
true
,
message
:
'请输入你的姓名'
}]
}
>
<
Input
placeholder=
"请输入(必填)"
/>
</
Item
>
<
Item
name=
{
'isActive'
}
label=
"是否启用
"
>
<
Switch
/>
<
Item
label=
"是否启用"
name=
{
'isActive'
}
valuePropName=
"checked
"
>
<
Switch
checked
/>
</
Item
>
<
Divider
/>
<
Row
justify=
{
'end'
}
gutter=
{
8
}
>
...
...
@@ -235,14 +431,20 @@ const UserManage = () => {
columns=
{
columns
}
actionRef=
{
actionRef
}
cardBordered
request=
{
async
(
params
=
{},
sort
,
filter
)
=>
{
request=
{
async
(
params
=
{
pageSize
:
10
,
current
:
0
},
sort
,
filter
)
=>
{
console
.
log
(
sort
,
filter
,
params
);
const
defaultParams
=
{
Name
:
''
,
Enabled
:
null
,
PageSize
:
10
,
PageIndex
:
1
,
Name
:
!
isEmpty
(
params
?.
name
)
?
params
?.
name
:
null
,
Enabled
:
!
isEmpty
(
params
?.
isActive
)
?
params
?.
isActive
:
null
,
PageSize
:
params
.
pageSize
,
PageIndex
:
params
?.
current
-
1
,
};
const
response
=
await
getUserMessage
(
defaultParams
);
return
{
data
:
response
.
items
,
total
:
response
.
totalCount
,
success
:
!
isEmpty
(
response
),
};
return
getUserMessage
(
defaultParams
);
}
}
rowKey=
"id"
pagination=
{
{
...
...
@@ -259,7 +461,6 @@ const UserManage = () => {
onClick=
{
()
=>
{
setAccountModalName
(
'添加账号'
);
showModal
();
actionRef
.
current
?.
reload
();
}
}
type=
"primary"
>
...
...
src/services/chatGLM/api.ts
View file @
5539db75
...
...
@@ -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,57 +41,108 @@ 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
body
:
JSON
.
stringify
(
params
),
});
}
}
;
export
const
getRole
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/roles'
,
{
method
:
'POST'
,
params
})
}
body
:
JSON
.
stringify
(
params
),
})
;
}
;
export
const
getUserMessage
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/page'
,
{
method
:
'POST'
,
data
:
params
body
:
JSON
.
stringify
(
params
),
});
}
}
;
export
const
createPromptWords
=
(
params
:
any
):
Promise
<
string
>
=>
{
export
const
createPromptWords
=
(
params
:
any
):
Promise
<
any
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/PromptWords/create'
,
{
method
:
'POST'
,
data
:
params
})
}
export
const
updatePromptWords
=
(
params
:
any
):
Promise
<
string
>
=>
{
export
const
updatePromptWords
=
(
params
:
any
):
Promise
<
any
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/PromptWords/update'
,
{
method
:
'POST'
,
data
:
params
})
}
export
const
deletePromptWords
=
(
params
:
any
):
Promise
<
string
>
=>
{
export
const
deletePromptWords
=
(
params
:
any
):
Promise
<
any
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/PromptWords/delete'
,
{
method
:
'POST'
,
data
:
params
})
}
export
const
pagePromptWords
=
(
params
:
any
):
Promise
<
string
>
=>
{
export
const
pagePromptWords
=
(
params
:
any
):
Promise
<
any
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/PromptWords/page'
,
{
method
:
'POST'
,
data
:
params
})
}
export
const
typePromptWords
=
():
Promise
<
any
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/PromptWords/type'
,
{
method
:
'POST'
,
})
}
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/reset'
,
{
method
:
'POST'
,
body
:
JSON
.
stringify
(
params
),
});
};
export
const
postEditUser
=
(
params
?:
any
):
Promise
<
string
>
=>
{
return
request
(
'https://glm-mangement-api.baibaomen.com/User/update'
,
{
method
:
'POST'
,
body
:
JSON
.
stringify
(
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