Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
52a752da
authored
Mar 05, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: 懒加载和动态加载优化
parent
78903bae
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
203 additions
and
192 deletions
+203
-192
public/icon/menu-left.svg
+0
-2
src/components/Layout/auth.tsx
+1
-1
src/components/Layout/index.tsx
+2
-4
src/hooks/useLoading.tsx
+2
-2
src/hooks/useScreen.ts
+1
-1
src/pages/_app.tsx
+1
-1
src/pages/chat/index.tsx
+38
-28
src/pages/index.tsx
+2
-5
src/pages/login/index.tsx
+19
-20
src/pages/model/components/CreateModel.tsx
+1
-3
src/pages/model/components/ModelEditForm.tsx
+16
-8
src/pages/model/components/Training.tsx
+3
-3
src/pages/model/detail.tsx
+109
-107
src/pages/model/list.tsx
+8
-7
No files found.
public/icon/menu-left.svg
deleted
100644 → 0
View file @
78903bae
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"17"
height=
"12"
viewBox=
"0 0 17 12"
fill=
"none"
><g
opacity=
"1"
transform=
"translate(0.70001220703125 0.2001953125) rotate(0 7.5 5.5)"
><path
id=
"Path"
style=
"stroke:#A0A5BA; stroke-width:1.4; stroke-opacity:1; stroke-dasharray:0 0"
transform=
"translate(0 5) rotate(0 7.5 0.5)"
d=
"M0,0.5L15,0.5 "
/><path
id=
"Path"
style=
"stroke:#A0A5BA; stroke-width:1.4; stroke-opacity:1; stroke-dasharray:0 0"
transform=
"translate(0 0) rotate(0 7.5 0.5)"
d=
"M0,0.5L15,0.5 "
/><path
id=
"Path"
style=
"stroke:#A0A5BA; stroke-width:1.4; stroke-opacity:1; stroke-dasharray:0 0"
transform=
"translate(7 10) rotate(0 4 0.5)"
d=
"M0,0.5L8,0.5 "
/></g></svg>
\ No newline at end of file
src/components/Layout/auth.tsx
View file @
52a752da
...
@@ -25,10 +25,10 @@ const Auth = ({ children }: { children: JSX.Element }) => {
...
@@ -25,10 +25,10 @@ const Auth = ({ children }: { children: JSX.Element }) => {
useQuery
(
useQuery
(
[
router
.
pathname
,
userInfo
],
[
router
.
pathname
,
userInfo
],
()
=>
{
()
=>
{
setLoading
(
true
);
if
(
unAuthPage
[
router
.
pathname
]
===
true
||
userInfo
)
{
if
(
unAuthPage
[
router
.
pathname
]
===
true
||
userInfo
)
{
return
setLoading
(
false
);
return
setLoading
(
false
);
}
else
{
}
else
{
setLoading
(
true
);
return
getTokenLogin
();
return
getTokenLogin
();
}
}
},
},
...
...
src/components/Layout/index.tsx
View file @
52a752da
...
@@ -43,15 +43,13 @@ const navbarList = [
...
@@ -43,15 +43,13 @@ const navbarList = [
const
Layout
=
({
children
}:
{
children
:
JSX
.
Element
})
=>
{
const
Layout
=
({
children
}:
{
children
:
JSX
.
Element
})
=>
{
const
{
isPc
}
=
useScreen
();
const
{
isPc
}
=
useScreen
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
{
Loading
}
=
useLoading
({
const
{
Loading
}
=
useLoading
({
defaultLoading
:
true
});
defaultLoading
:
true
});
const
{
loading
}
=
useGlobalStore
();
const
{
loading
}
=
useGlobalStore
();
return
(
return
(
<>
<>
{
!
unShowLayoutRoute
[
router
.
pathname
]
?
(
{
!
unShowLayoutRoute
[
router
.
pathname
]
?
(
<
Box
data
-
test=
"ss"
h=
{
'100%'
}
backgroundColor=
{
'gray.100'
}
overflow=
{
'auto'
}
>
<
Box
h=
{
'100%'
}
backgroundColor=
{
'gray.100'
}
overflow=
{
'auto'
}
>
{
isPc
?
(
{
isPc
?
(
<>
<>
<
Box
h=
{
'100%'
}
position=
{
'fixed'
}
left=
{
0
}
top=
{
0
}
w=
{
'80px'
}
>
<
Box
h=
{
'100%'
}
position=
{
'fixed'
}
left=
{
0
}
top=
{
0
}
w=
{
'80px'
}
>
...
...
src/hooks/useLoading.tsx
View file @
52a752da
import
{
useState
}
from
'react'
;
import
{
useState
,
memo
}
from
'react'
;
import
{
Spinner
,
Flex
}
from
'@chakra-ui/react'
;
import
{
Spinner
,
Flex
}
from
'@chakra-ui/react'
;
export
const
useLoading
=
(
props
?:
{
defaultLoading
:
boolean
})
=>
{
export
const
useLoading
=
(
props
?:
{
defaultLoading
:
boolean
})
=>
{
...
@@ -31,6 +31,6 @@ export const useLoading = (props?: { defaultLoading: boolean }) => {
...
@@ -31,6 +31,6 @@ export const useLoading = (props?: { defaultLoading: boolean }) => {
return
{
return
{
isLoading
,
isLoading
,
setIsLoading
,
setIsLoading
,
Loading
Loading
:
memo
(
Loading
)
};
};
};
};
src/hooks/useScreen.ts
View file @
52a752da
...
@@ -11,6 +11,6 @@ export function useScreen() {
...
@@ -11,6 +11,6 @@ export function useScreen() {
isPc
,
isPc
,
mediaLgMd
:
useMemo
(()
=>
(
isPc
?
'lg'
:
'md'
),
[
isPc
]),
mediaLgMd
:
useMemo
(()
=>
(
isPc
?
'lg'
:
'md'
),
[
isPc
]),
mediaMdSm
:
useMemo
(()
=>
(
isPc
?
'md'
:
'sm'
),
[
isPc
]),
mediaMdSm
:
useMemo
(()
=>
(
isPc
?
'md'
:
'sm'
),
[
isPc
]),
media
:
(
pc
:
number
|
string
,
phone
:
number
|
string
)
=>
(
isPc
?
pc
:
phone
)
media
:
(
pc
:
any
,
phone
:
any
)
=>
(
isPc
?
pc
:
phone
)
};
};
}
}
src/pages/_app.tsx
View file @
52a752da
...
@@ -38,6 +38,7 @@ export default function App({ Component, pageProps }: AppProps) {
...
@@ -38,6 +38,7 @@ export default function App({ Component, pageProps }: AppProps) {
/>
/>
<
link
rel=
"icon"
href=
"/favicon.ico"
/>
<
link
rel=
"icon"
href=
"/favicon.ico"
/>
</
Head
>
</
Head
>
<
Script
src=
"/iconfont.js"
strategy=
"afterInteractive"
></
Script
>
<
QueryClientProvider
client=
{
queryClient
}
>
<
QueryClientProvider
client=
{
queryClient
}
>
<
ChakraProvider
theme=
{
theme
}
>
<
ChakraProvider
theme=
{
theme
}
>
<
Layout
>
<
Layout
>
...
@@ -45,7 +46,6 @@ export default function App({ Component, pageProps }: AppProps) {
...
@@ -45,7 +46,6 @@ export default function App({ Component, pageProps }: AppProps) {
</
Layout
>
</
Layout
>
</
ChakraProvider
>
</
ChakraProvider
>
</
QueryClientProvider
>
</
QueryClientProvider
>
<
Script
src=
"/iconfont.js"
></
Script
>
</>
</>
);
);
}
}
...
...
src/pages/chat/index.tsx
View file @
52a752da
...
@@ -13,10 +13,13 @@ import { Textarea, Box, Flex, Button } from '@chakra-ui/react';
...
@@ -13,10 +13,13 @@ import { Textarea, Box, Flex, Button } from '@chakra-ui/react';
import
{
useToast
}
from
'@/hooks/useToast'
;
import
{
useToast
}
from
'@/hooks/useToast'
;
import
Icon
from
'@/components/Icon'
;
import
Icon
from
'@/components/Icon'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
Markdown
from
'@/components/Markdown'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
import
{
OpenAiModelEnum
}
from
'@/constants/model'
;
import
{
OpenAiModelEnum
}
from
'@/constants/model'
;
import
dynamic
from
'next/dynamic'
;
import
{
useGlobalStore
}
from
'@/store/global'
;
const
Markdown
=
dynamic
(()
=>
import
(
'@/components/Markdown'
));
const
textareaMinH
=
'22px'
;
const
textareaMinH
=
'22px'
;
...
@@ -34,7 +37,7 @@ const Chat = () => {
...
@@ -34,7 +37,7 @@ const Chat = () => {
const
isChatting
=
useMemo
(()
=>
chatList
[
chatList
.
length
-
1
]?.
status
===
'loading'
,
[
chatList
]);
const
isChatting
=
useMemo
(()
=>
chatList
[
chatList
.
length
-
1
]?.
status
===
'loading'
,
[
chatList
]);
const
lastWordHuman
=
useMemo
(()
=>
chatList
[
chatList
.
length
-
1
]?.
obj
===
'Human'
,
[
chatList
]);
const
lastWordHuman
=
useMemo
(()
=>
chatList
[
chatList
.
length
-
1
]?.
obj
===
'Human'
,
[
chatList
]);
const
{
Loading
,
setIsLoading
}
=
useLoading
({
defaultLoading
:
true
}
);
const
{
setLoading
}
=
useGlobalStore
(
);
// 滚动到底部
// 滚动到底部
const
scrollToBottom
=
useCallback
(()
=>
{
const
scrollToBottom
=
useCallback
(()
=>
{
...
@@ -49,32 +52,40 @@ const Chat = () => {
...
@@ -49,32 +52,40 @@ const Chat = () => {
},
[]);
},
[]);
// 初始化聊天框
// 初始化聊天框
useQuery
([
chatId
,
windowId
],
()
=>
(
chatId
?
getInitChatSiteInfo
(
chatId
,
windowId
)
:
null
),
{
useQuery
(
cacheTime
:
5
*
60
*
1000
,
[
chatId
,
windowId
],
onSuccess
(
res
)
{
()
=>
{
if
(
!
res
)
return
;
if
(
!
chatId
)
return
null
;
router
.
replace
(
`/chat?chatId=
${
chatId
}
&windowId=
${
res
.
windowId
}
`
);
setLoading
(
true
);
return
getInitChatSiteInfo
(
chatId
,
windowId
);
setChatSiteData
(
res
.
chatSite
);
setChatList
(
res
.
history
.
map
((
item
)
=>
({
...
item
,
status
:
'finish'
}))
);
scrollToBottom
();
setIsLoading
(
false
);
},
},
onError
()
{
{
toast
({
cacheTime
:
5
*
60
*
1000
,
title
:
'初始化异常,请刷新'
,
onSuccess
(
res
)
{
status
:
'error'
,
if
(
!
res
)
return
;
isClosable
:
true
,
router
.
replace
(
`/chat?chatId=
${
chatId
}
&windowId=
${
res
.
windowId
}
`
);
duration
:
5000
});
setChatSiteData
(
res
.
chatSite
);
setIsLoading
(
false
);
setChatList
(
res
.
history
.
map
((
item
)
=>
({
...
item
,
status
:
'finish'
}))
);
scrollToBottom
();
setLoading
(
false
);
},
onError
()
{
toast
({
title
:
'初始化异常,请刷新'
,
status
:
'error'
,
isClosable
:
true
,
duration
:
5000
});
setLoading
(
false
);
}
}
}
}
);
);
// gpt3 方法
// gpt3 方法
const
gpt3ChatPrompt
=
useCallback
(
const
gpt3ChatPrompt
=
useCallback
(
...
@@ -293,7 +304,7 @@ const Chat = () => {
...
@@ -293,7 +304,7 @@ const Chat = () => {
alt=
"/imgs/modelAvatar.png"
alt=
"/imgs/modelAvatar.png"
width=
{
30
}
width=
{
30
}
height=
{
30
}
height=
{
30
}
></
Image
>
/
>
</
Box
>
</
Box
>
<
Box
flex=
{
'1 0 0'
}
w=
{
0
}
overflowX=
{
'auto'
}
>
<
Box
flex=
{
'1 0 0'
}
w=
{
0
}
overflowX=
{
'auto'
}
>
{
item
.
obj
===
'AI'
?
(
{
item
.
obj
===
'AI'
?
(
...
@@ -393,7 +404,6 @@ const Chat = () => {
...
@@ -393,7 +404,6 @@ const Chat = () => {
</
Box
>
</
Box
>
)
}
)
}
</
Box
>
</
Box
>
<
Loading
/>
</
Flex
>
</
Flex
>
);
);
};
};
...
...
src/pages/index.tsx
View file @
52a752da
import
React
,
{
useEffect
}
from
'react'
;
import
React
from
'react'
;
import
{
useRouter
}
from
'next/router'
;
import
{
Card
}
from
'@chakra-ui/react'
;
import
{
Card
,
Text
,
Box
,
Heading
,
Flex
}
from
'@chakra-ui/react'
;
import
Markdown
from
'@/components/Markdown'
;
import
Markdown
from
'@/components/Markdown'
;
import
{
introPage
}
from
'@/constants/common'
;
import
{
introPage
}
from
'@/constants/common'
;
const
Home
=
()
=>
{
const
Home
=
()
=>
{
const
router
=
useRouter
();
return
(
return
(
<
Card
p=
{
5
}
lineHeight=
{
2
}
>
<
Card
p=
{
5
}
lineHeight=
{
2
}
>
<
Markdown
source=
{
introPage
}
isChatting=
{
false
}
/>
<
Markdown
source=
{
introPage
}
isChatting=
{
false
}
/>
...
...
src/pages/login/index.tsx
View file @
52a752da
import
React
,
{
useState
,
useCallback
}
from
'react'
;
import
React
,
{
useState
,
useCallback
,
useMemo
}
from
'react'
;
import
styles
from
'./index.module.scss'
;
import
styles
from
'./index.module.scss'
;
import
{
Box
,
Flex
,
Image
}
from
'@chakra-ui/react'
;
import
{
Box
,
Flex
,
Image
}
from
'@chakra-ui/react'
;
import
{
PageTypeEnum
}
from
'@/constants/user'
;
import
{
PageTypeEnum
}
from
'@/constants/user'
;
import
LoginForm
from
'./components/LoginForm'
;
import
RegisterForm
from
'./components/RegisterForm'
;
import
ForgetPasswordForm
from
'./components/ForgetPasswordForm'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
type
{
ResLogin
}
from
'@/api/response/user'
;
import
type
{
ResLogin
}
from
'@/api/response/user'
;
import
{
useRouter
}
from
'next/router'
;
import
{
useRouter
}
from
'next/router'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
dynamic
from
'next/dynamic'
;
const
LoginForm
=
dynamic
(()
=>
import
(
'./components/LoginForm'
));
const
RegisterForm
=
dynamic
(()
=>
import
(
'./components/RegisterForm'
));
const
ForgetPasswordForm
=
dynamic
(()
=>
import
(
'./components/ForgetPasswordForm'
));
const
Login
=
()
=>
{
const
Login
=
()
=>
{
const
router
=
useRouter
();
const
router
=
useRouter
();
const
{
isPc
}
=
useScreen
();
const
{
isPc
}
=
useScreen
();
...
@@ -24,20 +26,17 @@ const Login = () => {
...
@@ -24,20 +26,17 @@ const Login = () => {
[
router
,
setUserInfo
]
[
router
,
setUserInfo
]
);
);
const
map
=
{
function
DynamicComponent
({
type
}:
{
type
:
`
${
PageTypeEnum
}
`
})
{
[
PageTypeEnum
.
login
]:
{
const
TypeMap
=
{
Component
:
<
LoginForm
setPageType=
{
setPageType
}
loginSuccess=
{
loginSuccess
}
/>,
[
PageTypeEnum
.
login
]:
LoginForm
,
img
:
'/icon/loginLeft.svg'
[
PageTypeEnum
.
register
]:
RegisterForm
,
},
[
PageTypeEnum
.
forgetPassword
]:
ForgetPasswordForm
[
PageTypeEnum
.
register
]:
{
};
Component
:
<
RegisterForm
setPageType=
{
setPageType
}
loginSuccess=
{
loginSuccess
}
/>,
img
:
'/icon/loginLeft.svg'
const
Component
=
TypeMap
[
type
];
},
[
PageTypeEnum
.
forgetPassword
]:
{
return
<
Component
setPageType=
{
setPageType
}
loginSuccess=
{
loginSuccess
}
/>;
Component
:
<
ForgetPasswordForm
setPageType=
{
setPageType
}
loginSuccess=
{
loginSuccess
}
/>,
}
img
:
'/icon/loginLeft.svg'
}
};
return
(
return
(
<
Box
className=
{
styles
.
loginPage
}
h=
{
'100%'
}
p=
{
isPc
?
'10vh 10vw'
:
0
}
>
<
Box
className=
{
styles
.
loginPage
}
h=
{
'100%'
}
p=
{
isPc
?
'10vh 10vw'
:
0
}
>
...
@@ -54,7 +53,7 @@ const Login = () => {
...
@@ -54,7 +53,7 @@ const Login = () => {
>
>
{
isPc
&&
(
{
isPc
&&
(
<
Image
<
Image
src=
{
map
[
pageType
].
img
}
src=
{
'/icon/loginLeft.svg'
}
order=
{
pageType
===
PageTypeEnum
.
login
?
0
:
2
}
order=
{
pageType
===
PageTypeEnum
.
login
?
0
:
2
}
flex=
{
'1 0 0'
}
flex=
{
'1 0 0'
}
w=
"0"
w=
"0"
...
@@ -76,7 +75,7 @@ const Login = () => {
...
@@ -76,7 +75,7 @@ const Login = () => {
px=
{
10
}
px=
{
10
}
borderRadius=
{
isPc
?
'md'
:
'none'
}
borderRadius=
{
isPc
?
'md'
:
'none'
}
>
>
{
map
[
pageType
].
Component
}
<
DynamicComponent
type=
{
pageType
}
/>
</
Box
>
</
Box
>
</
Flex
>
</
Flex
>
</
Box
>
</
Box
>
...
...
src/pages/model/components/CreateModel.tsx
View file @
52a752da
...
@@ -25,11 +25,9 @@ interface CreateFormType {
...
@@ -25,11 +25,9 @@ interface CreateFormType {
}
}
const
CreateModel
=
({
const
CreateModel
=
({
isOpen
,
setCreateModelOpen
,
setCreateModelOpen
,
onSuccess
onSuccess
}:
{
}:
{
isOpen
:
boolean
;
setCreateModelOpen
:
Dispatch
<
boolean
>
;
setCreateModelOpen
:
Dispatch
<
boolean
>
;
onSuccess
:
Dispatch
<
ModelType
>
;
onSuccess
:
Dispatch
<
ModelType
>
;
})
=>
{
})
=>
{
...
@@ -72,7 +70,7 @@ const CreateModel = ({
...
@@ -72,7 +70,7 @@ const CreateModel = ({
return
(
return
(
<>
<>
<
Modal
isOpen=
{
isOpen
}
onClose=
{
()
=>
setCreateModelOpen
(
false
)
}
>
<
Modal
isOpen=
{
true
}
onClose=
{
()
=>
setCreateModelOpen
(
false
)
}
>
<
ModalOverlay
/>
<
ModalOverlay
/>
<
ModalContent
>
<
ModalContent
>
<
ModalHeader
>
创建模型
</
ModalHeader
>
<
ModalHeader
>
创建模型
</
ModalHeader
>
...
...
src/pages/model/components/ModelEditForm.tsx
View file @
52a752da
import
React
,
{
useCallback
}
from
'react'
;
import
React
,
{
useCallback
,
useEffect
,
useRef
}
from
'react'
;
import
{
Grid
,
Box
,
Card
,
Flex
,
Button
,
FormControl
,
Input
,
Textarea
}
from
'@chakra-ui/react'
;
import
{
Grid
,
Box
,
Card
,
Flex
,
Button
,
FormControl
,
Input
,
Textarea
}
from
'@chakra-ui/react'
;
import
type
{
ModelType
}
from
'@/types/model'
;
import
type
{
ModelType
}
from
'@/types/model'
;
import
{
useForm
}
from
'react-hook-form'
;
import
{
useForm
}
from
'react-hook-form'
;
...
@@ -7,17 +7,17 @@ import { putModelById } from '@/api/model';
...
@@ -7,17 +7,17 @@ import { putModelById } from '@/api/model';
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useGlobalStore
}
from
'@/store/global'
;
import
{
useGlobalStore
}
from
'@/store/global'
;
const
ModelEditForm
=
({
model
}:
{
model
:
ModelType
})
=>
{
const
ModelEditForm
=
({
model
}:
{
model
?:
ModelType
})
=>
{
const
isInit
=
useRef
(
false
);
const
{
const
{
register
,
register
,
handleSubmit
,
handleSubmit
,
reset
,
formState
:
{
errors
}
formState
:
{
errors
}
}
=
useForm
<
ModelType
>
({
}
=
useForm
<
ModelType
>
();
defaultValues
:
model
});
const
{
setLoading
}
=
useGlobalStore
();
const
{
setLoading
}
=
useGlobalStore
();
const
{
toast
}
=
useToast
();
const
{
toast
}
=
useToast
();
const
{
isPc
}
=
useScreen
();
const
{
media
}
=
useScreen
();
const
onclickSave
=
useCallback
(
const
onclickSave
=
useCallback
(
async
(
data
:
ModelType
)
=>
{
async
(
data
:
ModelType
)
=>
{
...
@@ -61,8 +61,16 @@ const ModelEditForm = ({ model }: { model: ModelType }) => {
...
@@ -61,8 +61,16 @@ const ModelEditForm = ({ model }: { model: ModelType }) => {
});
});
},
[
errors
,
toast
]);
},
[
errors
,
toast
]);
/* model 只会改变一次 */
useEffect
(()
=>
{
if
(
model
&&
!
isInit
.
current
)
{
reset
(
model
);
isInit
.
current
=
true
;
}
},
[
model
,
reset
]);
return
(
return
(
<
Grid
gridTemplateColumns=
{
isPc
?
'1fr 1fr'
:
'1fr'
}
gridGap=
{
5
}
>
<
Grid
gridTemplateColumns=
{
media
(
'1fr 1fr'
,
'1fr'
)
}
gridGap=
{
5
}
>
<
Card
p=
{
4
}
>
<
Card
p=
{
4
}
>
<
Flex
justifyContent=
{
'space-between'
}
alignItems=
{
'center'
}
>
<
Flex
justifyContent=
{
'space-between'
}
alignItems=
{
'center'
}
>
<
Box
fontWeight=
{
'bold'
}
fontSize=
{
'lg'
}
>
<
Box
fontWeight=
{
'bold'
}
fontSize=
{
'lg'
}
>
...
@@ -83,7 +91,7 @@ const ModelEditForm = ({ model }: { model: ModelType }) => {
...
@@ -83,7 +91,7 @@ const ModelEditForm = ({ model }: { model: ModelType }) => {
<
FormControl
mt=
{
5
}
>
<
FormControl
mt=
{
5
}
>
<
Flex
alignItems=
{
'center'
}
>
<
Flex
alignItems=
{
'center'
}
>
<
Box
flex=
{
'0 0 80px'
}
>
对话模型:
</
Box
>
<
Box
flex=
{
'0 0 80px'
}
>
对话模型:
</
Box
>
<
Box
>
{
model
.
service
.
modelName
}
</
Box
>
<
Box
>
{
model
?
.
service
.
modelName
}
</
Box
>
</
Flex
>
</
Flex
>
</
FormControl
>
</
FormControl
>
<
FormControl
mt=
{
5
}
>
<
FormControl
mt=
{
5
}
>
...
...
src/pages/model/components/Training.tsx
View file @
52a752da
import
React
,
{
useEffect
,
useCallback
,
useState
}
from
'react'
;
import
React
,
{
useEffect
,
useCallback
,
useState
}
from
'react'
;
import
{
Box
,
Card
,
TableContainer
,
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
Td
}
from
'@chakra-ui/react'
;
import
{
Box
,
TableContainer
,
Table
,
Thead
,
Tbody
,
Tr
,
Th
,
Td
}
from
'@chakra-ui/react'
;
import
{
ModelType
}
from
'@/types/model'
;
import
{
ModelType
}
from
'@/types/model'
;
import
{
getModelTrainings
}
from
'@/api/model'
;
import
{
getModelTrainings
}
from
'@/api/model'
;
import
type
{
TrainingItemType
}
from
'@/types/training'
;
import
type
{
TrainingItemType
}
from
'@/types/training'
;
...
@@ -38,7 +38,7 @@ const Training = ({ model }: { model: ModelType }) => {
...
@@ -38,7 +38,7 @@ const Training = ({ model }: { model: ModelType }) => {
},
[
loadTrainingRecords
,
model
]);
},
[
loadTrainingRecords
,
model
]);
return
(
return
(
<
Card
p=
{
4
}
h=
{
'100%'
}
>
<>
<
Box
fontWeight=
{
'bold'
}
fontSize=
{
'lg'
}
>
<
Box
fontWeight=
{
'bold'
}
fontSize=
{
'lg'
}
>
训练记录:
{
model
.
trainingTimes
}
次
训练记录:
{
model
.
trainingTimes
}
次
</
Box
>
</
Box
>
...
@@ -63,7 +63,7 @@ const Training = ({ model }: { model: ModelType }) => {
...
@@ -63,7 +63,7 @@ const Training = ({ model }: { model: ModelType }) => {
</
Tbody
>
</
Tbody
>
</
Table
>
</
Table
>
</
TableContainer
>
</
TableContainer
>
</
Card
>
</>
);
);
};
};
...
...
src/pages/model/detail.tsx
View file @
52a752da
...
@@ -11,12 +11,14 @@ import { useGlobalStore } from '@/store/global';
...
@@ -11,12 +11,14 @@ import { useGlobalStore } from '@/store/global';
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
ModelEditForm
from
'./components/ModelEditForm'
;
import
ModelEditForm
from
'./components/ModelEditForm'
;
import
Icon
from
'@/components/Icon'
;
import
Icon
from
'@/components/Icon'
;
import
Training
from
'./components/Training'
;
import
dynamic
from
'next/dynamic'
;
const
Training
=
dynamic
(()
=>
import
(
'./components/Training'
));
const
ModelDetail
=
()
=>
{
const
ModelDetail
=
()
=>
{
const
{
toast
}
=
useToast
();
const
{
toast
}
=
useToast
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
{
isPc
}
=
useScreen
();
const
{
isPc
,
media
}
=
useScreen
();
const
{
setLoading
}
=
useGlobalStore
();
const
{
setLoading
}
=
useGlobalStore
();
const
{
openConfirm
,
ConfirmChild
}
=
useConfirm
({
const
{
openConfirm
,
ConfirmChild
}
=
useConfirm
({
content
:
'确认删除该模型?'
content
:
'确认删除该模型?'
...
@@ -128,114 +130,114 @@ const ModelDetail = () => {
...
@@ -128,114 +130,114 @@ const ModelDetail = () => {
return
(
return
(
<>
<>
{
!!
model
&&
(
{
/* 头部 */
}
<>
<
Card
px=
{
6
}
py=
{
3
}
>
{
/* 头部 */
}
{
isPc
?
(
<
Card
px=
{
6
}
py=
{
3
}
>
<
Flex
alignItems=
{
'center'
}
>
{
isPc
?
(
<
Box
fontSize=
{
'xl'
}
fontWeight=
{
'bold'
}
>
<
Flex
alignItems=
{
'center'
}
>
{
model
?.
name
||
'模型'
}
配置
<
Box
fontSize=
{
'xl'
}
fontWeight=
{
'bold'
}
>
</
Box
>
{
model
.
name
}
配置
{
!!
model
&&
(
</
Box
>
<
Tag
<
Tag
ml=
{
2
}
ml=
{
2
}
variant=
"solid"
variant=
"solid"
colorScheme=
{
formatModelStatus
[
model
.
status
].
colorTheme
}
colorScheme=
{
formatModelStatus
[
model
.
status
].
colorTheme
}
cursor=
{
model
.
status
===
ModelStatusEnum
.
training
?
'pointer'
:
'default'
}
cursor=
{
model
.
status
===
ModelStatusEnum
.
training
?
'pointer'
:
'default'
}
onClick=
{
handleClickUpdateStatus
}
onClick=
{
handleClickUpdateStatus
}
>
>
{
formatModelStatus
[
model
.
status
].
text
}
</
Tag
>
)
}
<
Box
flex=
{
1
}
/>
<
Button
variant=
{
'outline'
}
onClick=
{
handlePreviewChat
}
>
对话体验
</
Button
>
</
Flex
>
)
:
(
<>
<
Flex
alignItems=
{
'center'
}
>
<
Box
as=
{
'h3'
}
fontSize=
{
'xl'
}
fontWeight=
{
'bold'
}
flex=
{
1
}
>
{
model
?.
name
||
'模型'
}
配置
</
Box
>
{
!!
model
&&
(
<
Tag
ml=
{
2
}
colorScheme=
{
formatModelStatus
[
model
.
status
].
colorTheme
}
>
{
formatModelStatus
[
model
.
status
].
text
}
{
formatModelStatus
[
model
.
status
].
text
}
</
Tag
>
</
Tag
>
<
Box
flex=
{
1
}
/>
)
}
<
Button
variant=
{
'outline'
}
onClick=
{
handlePreviewChat
}
>
</
Flex
>
对话体验
<
Box
mt=
{
4
}
textAlign=
{
'right'
}
>
</
Button
>
<
Button
variant=
{
'outline'
}
onClick=
{
handlePreviewChat
}
>
</
Flex
>
对话体验
)
:
(
</
Button
>
<>
</
Box
>
<
Flex
alignItems=
{
'center'
}
>
</>
<
Box
as=
{
'h3'
}
fontSize=
{
'xl'
}
fontWeight=
{
'bold'
}
flex=
{
1
}
>
)
}
{
model
.
name
}
配置
</
Card
>
</
Box
>
{
/* 基本信息编辑 */
}
<
Tag
ml=
{
2
}
colorScheme=
{
formatModelStatus
[
model
.
status
].
colorTheme
}
>
<
Box
mt=
{
5
}
>
{
formatModelStatus
[
model
.
status
].
text
}
<
ModelEditForm
model=
{
model
}
/>
</
Tag
>
</
Box
>
</
Flex
>
{
/* 其他配置 */
}
<
Box
mt=
{
4
}
textAlign=
{
'right'
}
>
<
Grid
mt=
{
5
}
gridTemplateColumns=
{
media
(
'1fr 1fr'
,
'1fr'
)
}
gridGap=
{
5
}
>
<
Button
variant=
{
'outline'
}
onClick=
{
handlePreviewChat
}
>
<
Card
p=
{
4
}
>
{
!!
model
&&
<
Training
model=
{
model
}
/>
}
</
Card
>
对话体验
<
Card
p=
{
4
}
>
</
Button
>
<
Box
fontWeight=
{
'bold'
}
fontSize=
{
'lg'
}
>
</
Box
>
神奇操作
</>
)
}
</
Card
>
{
/* 基本信息编辑 */
}
<
Box
mt=
{
5
}
>
<
ModelEditForm
model=
{
model
}
/>
</
Box
>
</
Box
>
{
/* 其他配置 */
}
<
Flex
mt=
{
5
}
alignItems=
{
'center'
}
>
<
Grid
mt=
{
5
}
gridTemplateColumns=
{
isPc
?
'1fr 1fr'
:
'1fr'
}
gridGap=
{
5
}
>
<
Box
flex=
{
'0 0 80px'
}
>
模型微调:
</
Box
>
<
Training
model=
{
model
}
/>
<
Button
<
Card
h=
{
'100%'
}
p=
{
4
}
>
size=
{
'sm'
}
<
Box
fontWeight=
{
'bold'
}
fontSize=
{
'lg'
}
>
onClick=
{
()
=>
{
神奇操作
SelectFileDom
.
current
?.
click
();
</
Box
>
}
}
<
Flex
mt=
{
5
}
alignItems=
{
'center'
}
>
title=
{
!
canTrain
?
''
:
'模型不支持微调'
}
<
Box
flex=
{
'0 0 80px'
}
>
模型微调:
</
Box
>
isDisabled=
{
!
canTrain
}
<
Button
>
size=
{
'sm'
}
上传微调数据集
onClick=
{
()
=>
{
</
Button
>
SelectFileDom
.
current
?.
click
();
<
Flex
}
}
as=
{
'a'
}
title=
{
!
canTrain
?
''
:
'模型不支持微调'
}
href=
"/TrainingTemplate.jsonl"
isDisabled=
{
!
canTrain
}
download
>
ml=
{
5
}
上传微调数据集
cursor=
{
'pointer'
}
</
Button
>
alignItems=
{
'center'
}
<
Flex
color=
{
'blue.500'
}
as=
{
'a'
}
>
href=
"/TrainingTemplate.jsonl"
<
Icon
name=
{
'icon-yunxiazai'
}
color=
{
'#3182ce'
}
/>
download
下载模板
ml=
{
5
}
</
Flex
>
cursor=
{
'pointer'
}
</
Flex
>
alignItems=
{
'center'
}
{
/* 提示 */
}
color=
{
'blue.500'
}
<
Box
mt=
{
3
}
py=
{
3
}
color=
{
'blackAlpha.500'
}
>
>
<
Box
as=
{
'li'
}
lineHeight=
{
1.9
}
>
<
Icon
name=
{
'icon-yunxiazai'
}
color=
{
'#3182ce'
}
/>
每行包括一个 prompt 和一个 completion
下载模板
</
Box
>
</
Flex
>
<
Box
as=
{
'li'
}
lineHeight=
{
1.9
}
>
</
Flex
>
prompt 必须以 \n\n###\n\n 结尾,且尽量保障每个 prompt
{
/* 提示 */
}
内容不都是同一个标点结尾,可以加一个空格打断相同性,
<
Box
mt=
{
3
}
py=
{
3
}
color=
{
'blackAlpha.500'
}
>
</
Box
>
<
Box
as=
{
'li'
}
lineHeight=
{
1.9
}
>
<
Box
as=
{
'li'
}
lineHeight=
{
1.9
}
>
每行包括一个 prompt 和一个 completion
completion 开头必须有一个空格,末尾必须以 ### 结尾,同样的不要都是同一个标点结尾。
</
Box
>
</
Box
>
<
Box
as=
{
'li'
}
lineHeight=
{
1.9
}
>
</
Box
>
prompt 必须以 \n\n###\n\n 结尾,且尽量保障每个 prompt
<
Flex
mt=
{
5
}
alignItems=
{
'center'
}
>
内容不都是同一个标点结尾,可以加一个空格打断相同性,
<
Box
flex=
{
'0 0 80px'
}
>
删除模型:
</
Box
>
</
Box
>
<
Button
<
Box
as=
{
'li'
}
lineHeight=
{
1.9
}
>
colorScheme=
{
'red'
}
completion 开头必须有一个空格,末尾必须以 ### 结尾,同样的不要都是同一个标点结尾。
size=
{
'sm'
}
</
Box
>
onClick=
{
()
=>
{
</
Box
>
openConfirm
(()
=>
{
<
Flex
mt=
{
5
}
alignItems=
{
'center'
}
>
handleDelModel
();
<
Box
flex=
{
'0 0 80px'
}
>
删除模型:
</
Box
>
});
<
Button
}
}
colorScheme=
{
'red'
}
>
size=
{
'sm'
}
删除模型
onClick=
{
()
=>
{
</
Button
>
openConfirm
(()
=>
{
</
Flex
>
handleDelModel
();
</
Card
>
});
</
Grid
>
}
}
>
删除模型
</
Button
>
</
Flex
>
</
Card
>
</
Grid
>
</>
)
}
<
Box
position=
{
'absolute'
}
w=
{
0
}
h=
{
0
}
overflow=
{
'hidden'
}
>
<
Box
position=
{
'absolute'
}
w=
{
0
}
h=
{
0
}
overflow=
{
'hidden'
}
>
<
input
ref=
{
SelectFileDom
}
type=
"file"
accept=
".jsonl"
onChange=
{
startTraining
}
/>
<
input
ref=
{
SelectFileDom
}
type=
"file"
accept=
".jsonl"
onChange=
{
startTraining
}
/>
</
Box
>
</
Box
>
...
...
src/pages/model/list.tsx
View file @
52a752da
import
React
,
{
useState
,
use
Effect
,
use
Callback
}
from
'react'
;
import
React
,
{
useState
,
useCallback
}
from
'react'
;
import
{
Box
,
Button
,
Flex
,
Card
}
from
'@chakra-ui/react'
;
import
{
Box
,
Button
,
Flex
,
Card
}
from
'@chakra-ui/react'
;
import
{
getMyModels
}
from
'@/api/model'
;
import
{
getMyModels
}
from
'@/api/model'
;
import
{
getChatSiteId
}
from
'@/api/chat'
;
import
{
getChatSiteId
}
from
'@/api/chat'
;
import
{
ModelType
}
from
'@/types/model'
;
import
{
ModelType
}
from
'@/types/model'
;
import
CreateModel
from
'./components/CreateModel'
;
import
{
useRouter
}
from
'next/router'
;
import
{
useRouter
}
from
'next/router'
;
import
ModelTable
from
'./components/ModelTable'
;
import
ModelTable
from
'./components/ModelTable'
;
import
ModelPhoneList
from
'./components/ModelPhoneList'
;
import
ModelPhoneList
from
'./components/ModelPhoneList'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
import
dynamic
from
'next/dynamic'
;
const
CreateModel
=
dynamic
(()
=>
import
(
'./components/CreateModel'
));
const
ModelList
=
()
=>
{
const
ModelList
=
()
=>
{
const
{
isPc
}
=
useScreen
();
const
{
isPc
}
=
useScreen
();
...
@@ -72,11 +74,10 @@ const ModelList = () => {
...
@@ -72,11 +74,10 @@ const ModelList = () => {
)
}
)
}
</
Box
>
</
Box
>
{
/* 创建弹窗 */
}
{
/* 创建弹窗 */
}
<
CreateModel
{
openCreateModel
&&
(
isOpen=
{
openCreateModel
}
<
CreateModel
setCreateModelOpen=
{
setOpenCreateModel
}
onSuccess=
{
createModelSuccess
}
/>
setCreateModelOpen=
{
setOpenCreateModel
}
)
}
onSuccess=
{
createModelSuccess
}
/>
<
Loading
loading=
{
isLoading
}
/>
<
Loading
loading=
{
isLoading
}
/>
</
Box
>
</
Box
>
);
);
...
...
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