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
Unverified
Commit
a02a5287
authored
Jun 19, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: my models
parent
dd4ca27d
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
78 additions
and
94 deletions
+78
-94
client/src/components/ScrollData/index.tsx
+0
-76
client/src/hooks/usePagination.tsx
+63
-2
client/src/pages/api/model/create.ts
+2
-2
client/src/pages/api/model/list.ts
+4
-4
client/src/pages/model/components/ModelList.tsx
+4
-6
client/src/pages/model/components/detail/components/Settings.tsx
+4
-3
client/src/types/model.d.ts
+1
-1
No files found.
client/src/components/ScrollData/index.tsx
deleted
100644 → 0
View file @
dd4ca27d
import
React
,
{
useRef
,
useEffect
,
useMemo
}
from
'react'
;
import
type
{
BoxProps
}
from
'@chakra-ui/react'
;
import
{
Box
}
from
'@chakra-ui/react'
;
import
{
throttle
}
from
'lodash'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
interface
Props
extends
BoxProps
{
nextPage
:
()
=>
void
;
isLoadAll
:
boolean
;
requesting
:
boolean
;
children
:
React
.
ReactNode
;
initRequesting
?:
boolean
;
}
const
ScrollData
=
({
children
,
nextPage
,
isLoadAll
,
requesting
,
initRequesting
,
...
props
}:
Props
)
=>
{
const
{
Loading
}
=
useLoading
({
defaultLoading
:
true
});
const
elementRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
loadText
=
useMemo
(()
=>
{
if
(
requesting
)
return
'请求中……'
;
if
(
isLoadAll
)
return
'已加载全部'
;
return
'点击加载更多'
;
},
[
isLoadAll
,
requesting
]);
useEffect
(()
=>
{
if
(
!
elementRef
.
current
)
return
;
const
scrolling
=
throttle
((
e
:
Event
)
=>
{
const
element
=
e
.
target
as
HTMLDivElement
;
if
(
!
element
)
return
;
// 当前滚动位置
const
scrollTop
=
element
.
scrollTop
;
// 可视高度
const
clientHeight
=
element
.
clientHeight
;
// 内容总高度
const
scrollHeight
=
element
.
scrollHeight
;
// 判断是否滚动到底部
if
(
scrollTop
+
clientHeight
+
100
>=
scrollHeight
)
{
nextPage
();
}
},
100
);
elementRef
.
current
.
addEventListener
(
'scroll'
,
scrolling
);
return
()
=>
{
// eslint-disable-next-line react-hooks/exhaustive-deps
elementRef
.
current
?.
removeEventListener
(
'scroll'
,
scrolling
);
};
},
[
elementRef
,
nextPage
]);
return
(
<
Box
{
...
props
}
ref=
{
elementRef
}
overflowY=
{
'auto'
}
position=
{
'relative'
}
>
{
children
}
<
Box
mt=
{
2
}
fontSize=
{
'xs'
}
color=
{
'blackAlpha.500'
}
textAlign=
{
'center'
}
cursor=
{
loadText
===
'点击加载更多'
?
'pointer'
:
'default'
}
onClick=
{
()
=>
{
if
(
loadText
!==
'点击加载更多'
)
return
;
nextPage
();
}
}
>
{
loadText
}
</
Box
>
{
initRequesting
&&
<
Loading
fixed=
{
false
}
/>
}
</
Box
>
);
};
export
default
ScrollData
;
client/src/hooks/usePagination.tsx
View file @
a02a5287
import
{
use
State
,
useCallback
,
useMemo
,
useEffect
}
from
'react'
;
import
{
use
Ref
,
useState
,
useCallback
,
useLayoutEffect
,
useMemo
,
useEffect
}
from
'react'
;
import
type
{
PagingData
}
from
'../types/index'
;
import
type
{
PagingData
}
from
'../types/index'
;
import
{
IconButton
,
Flex
,
Box
,
Input
}
from
'@chakra-ui/react'
;
import
{
IconButton
,
Flex
,
Box
,
Input
}
from
'@chakra-ui/react'
;
import
{
ArrowBackIcon
,
ArrowForwardIcon
}
from
'@chakra-ui/icons'
;
import
{
ArrowBackIcon
,
ArrowForwardIcon
}
from
'@chakra-ui/icons'
;
import
{
useMutation
}
from
'@tanstack/react-query'
;
import
{
useMutation
}
from
'@tanstack/react-query'
;
import
{
useToast
}
from
'./useToast'
;
import
{
useToast
}
from
'./useToast'
;
import
{
throttle
}
from
'lodash'
;
const
thresholdVal
=
100
;
export
const
usePagination
=
<
T
=
any
,
>
(
{
export
const
usePagination
=
<
T
=
any
,
>
(
{
api
,
api
,
pageSize
=
10
,
pageSize
=
10
,
params
=
{},
params
=
{},
defaultRequest
=
true
defaultRequest
=
true
,
type
=
'button'
}
:
{
}
:
{
api
:
(
data
:
any
)
=>
any
;
api
:
(
data
:
any
)
=>
any
;
pageSize
?:
number
;
pageSize
?:
number
;
params
?:
Record
<
string
,
any
>
;
params
?:
Record
<
string
,
any
>
;
defaultRequest
?:
boolean
;
defaultRequest
?:
boolean
;
type
?:
'button'
|
'scroll'
;
}
) =
>
{
}
) =
>
{
const
elementRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
{
toast
}
=
useToast
();
const
{
toast
}
=
useToast
();
const
[
pageNum
,
setPageNum
]
=
useState
(
1
);
const
[
pageNum
,
setPageNum
]
=
useState
(
1
);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
total
,
setTotal
]
=
useState
(
0
);
...
@@ -108,6 +114,60 @@ export const usePagination = <T = any,>({
...
@@ -108,6 +114,60 @@ export const usePagination = <T = any,>({
);
);
},
[
isLoading
,
maxPage
,
mutate
,
pageNum
]);
},
[
isLoading
,
maxPage
,
mutate
,
pageNum
]);
const
ScrollData
=
useCallback
(
({
children
,
...
props
}:
{
children
:
React
.
ReactNode
})
=>
{
const
loadText
=
useMemo
(()
=>
{
if
(
isLoading
)
return
'请求中……'
;
if
(
total
<=
data
.
length
)
return
'已加载全部'
;
return
'点击加载更多'
;
},
[]);
return
(
<
Box
{
...
props
}
ref=
{
elementRef
}
overflow=
{
'overlay'
}
>
{
children
}
<
Box
mt=
{
2
}
fontSize=
{
'xs'
}
color=
{
'blackAlpha.500'
}
textAlign=
{
'center'
}
cursor=
{
loadText
===
'点击加载更多'
?
'pointer'
:
'default'
}
onClick=
{
()
=>
{
if
(
loadText
!==
'点击加载更多'
)
return
;
mutate
(
pageNum
+
1
);
}
}
>
{
loadText
}
</
Box
>
</
Box
>
);
},
[
data
.
length
,
isLoading
,
mutate
,
pageNum
,
total
]
);
useLayoutEffect
(()
=>
{
if
(
!
elementRef
.
current
||
type
!==
'scroll'
)
return
;
const
scrolling
=
throttle
((
e
:
Event
)
=>
{
const
element
=
e
.
target
as
HTMLDivElement
;
if
(
!
element
)
return
;
// 当前滚动位置
const
scrollTop
=
element
.
scrollTop
;
// 可视高度
const
clientHeight
=
element
.
clientHeight
;
// 内容总高度
const
scrollHeight
=
element
.
scrollHeight
;
// 判断是否滚动到底部
if
(
scrollTop
+
clientHeight
+
thresholdVal
>=
scrollHeight
)
{
mutate
(
pageNum
+
1
);
}
},
100
);
elementRef
.
current
.
addEventListener
(
'scroll'
,
scrolling
);
return
()
=>
{
// eslint-disable-next-line react-hooks/exhaustive-deps
elementRef
.
current
?.
removeEventListener
(
'scroll'
,
scrolling
);
};
},
[
elementRef
,
mutate
,
pageNum
,
type
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
defaultRequest
&&
mutate
(
1
);
defaultRequest
&&
mutate
(
1
);
},
[]);
},
[]);
...
@@ -119,6 +179,7 @@ export const usePagination = <T = any,>({
...
@@ -119,6 +179,7 @@ export const usePagination = <T = any,>({
data
,
data
,
isLoading
,
isLoading
,
Pagination
,
Pagination
,
ScrollData
,
getData
:
mutate
getData
:
mutate
};
};
}
;
}
;
client/src/pages/api/model/create.ts
View file @
a02a5287
...
@@ -24,8 +24,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
...
@@ -24,8 +24,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const
authCount
=
await
Model
.
countDocuments
({
const
authCount
=
await
Model
.
countDocuments
({
userId
userId
});
});
if
(
authCount
>=
3
0
)
{
if
(
authCount
>=
5
0
)
{
throw
new
Error
(
'上限
3
0 个应用'
);
throw
new
Error
(
'上限
5
0 个应用'
);
}
}
// 创建模型
// 创建模型
...
...
client/src/pages/api/model/list.ts
View file @
a02a5287
...
@@ -18,14 +18,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
...
@@ -18,14 +18,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
{
{
userId
userId
},
},
'_id avatar name
chat.systemPrompt
'
'_id avatar name
intro
'
).
sort
({
).
sort
({
updateTime
:
-
1
updateTime
:
-
1
}),
}),
Collection
.
find
({
userId
})
Collection
.
find
({
userId
})
.
populate
({
.
populate
({
path
:
'modelId'
,
path
:
'modelId'
,
select
:
'_id avatar name
chat.systemPrompt
'
,
select
:
'_id avatar name
intro
'
,
match
:
{
'share.isShare'
:
true
}
match
:
{
'share.isShare'
:
true
}
})
})
.
then
((
res
)
=>
res
.
filter
((
item
)
=>
item
.
modelId
))
.
then
((
res
)
=>
res
.
filter
((
item
)
=>
item
.
modelId
))
...
@@ -37,14 +37,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
...
@@ -37,14 +37,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
_id
:
item
.
_id
,
_id
:
item
.
_id
,
name
:
item
.
name
,
name
:
item
.
name
,
avatar
:
item
.
avatar
,
avatar
:
item
.
avatar
,
systemPrompt
:
item
.
chat
.
systemPrompt
intro
:
item
.
intro
})),
})),
myCollectionModels
:
myCollections
myCollectionModels
:
myCollections
.
map
((
item
:
any
)
=>
({
.
map
((
item
:
any
)
=>
({
_id
:
item
.
modelId
?.
_id
,
_id
:
item
.
modelId
?.
_id
,
name
:
item
.
modelId
?.
name
,
name
:
item
.
modelId
?.
name
,
avatar
:
item
.
modelId
?.
avatar
,
avatar
:
item
.
modelId
?.
avatar
,
systemPrompt
:
item
.
modelId
?.
chat
.
systemPrompt
intro
:
item
.
modelId
?.
intro
}))
}))
.
filter
((
item
)
=>
!
myModels
.
find
((
model
)
=>
String
(
model
.
_id
)
===
String
(
item
.
_id
)))
// 去重
.
filter
((
item
)
=>
!
myModels
.
find
((
model
)
=>
String
(
model
.
_id
)
===
String
(
item
.
_id
)))
// 去重
}
}
...
...
client/src/pages/model/components/ModelList.tsx
View file @
a02a5287
import
React
,
{
useCallback
,
useMemo
,
use
Ref
,
use
State
}
from
'react'
;
import
React
,
{
useCallback
,
useMemo
,
useState
}
from
'react'
;
import
{
Box
,
Flex
,
Input
,
IconButton
,
Tooltip
,
Tab
,
useTheme
}
from
'@chakra-ui/react'
;
import
{
Box
,
Flex
,
Input
,
IconButton
,
Tooltip
,
useTheme
}
from
'@chakra-ui/react'
;
import
{
AddIcon
}
from
'@chakra-ui/icons'
;
import
{
AddIcon
}
from
'@chakra-ui/icons'
;
import
{
useRouter
}
from
'next/router'
;
import
{
useRouter
}
from
'next/router'
;
import
MyIcon
from
'@/components/Icon'
;
import
MyIcon
from
'@/components/Icon'
;
...
@@ -55,14 +55,12 @@ const ModelList = ({ modelId }: { modelId: string }) => {
...
@@ -55,14 +55,12 @@ const ModelList = ({ modelId }: { modelId: string }) => {
const
currentModels
=
useMemo
(()
=>
{
const
currentModels
=
useMemo
(()
=>
{
const
map
=
{
const
map
=
{
[
MyModelsTypeEnum
.
my
]:
{
[
MyModelsTypeEnum
.
my
]:
{
list
:
myModels
.
filter
((
item
)
=>
list
:
myModels
.
filter
((
item
)
=>
new
RegExp
(
searchText
,
'ig'
).
test
(
item
.
name
+
item
.
intro
)),
new
RegExp
(
searchText
,
'ig'
).
test
(
item
.
name
+
item
.
systemPrompt
)
),
emptyText
:
'还没有 AI 应用~\n快来创建一个吧'
emptyText
:
'还没有 AI 应用~\n快来创建一个吧'
},
},
[
MyModelsTypeEnum
.
collection
]:
{
[
MyModelsTypeEnum
.
collection
]:
{
list
:
myCollectionModels
.
filter
((
item
)
=>
list
:
myCollectionModels
.
filter
((
item
)
=>
new
RegExp
(
searchText
,
'ig'
).
test
(
item
.
name
+
item
.
systemPrompt
)
new
RegExp
(
searchText
,
'ig'
).
test
(
item
.
name
+
item
.
intro
)
),
),
emptyText
:
'收藏的 AI 应用为空~\n快去市场找一个吧'
emptyText
:
'收藏的 AI 应用为空~\n快去市场找一个吧'
}
}
...
...
client/src/pages/model/components/detail/components/Settings.tsx
View file @
a02a5287
...
@@ -24,7 +24,8 @@ const Settings = ({ modelId }: { modelId: string }) => {
...
@@ -24,7 +24,8 @@ const Settings = ({ modelId }: { modelId: string }) => {
const
{
toast
}
=
useToast
();
const
{
toast
}
=
useToast
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
{
Loading
,
setIsLoading
}
=
useLoading
();
const
{
Loading
,
setIsLoading
}
=
useLoading
();
const
{
userInfo
,
modelDetail
,
loadModelDetail
,
refreshModel
,
setLastModelId
}
=
useUserStore
();
const
{
userInfo
,
modelDetail
,
myModels
,
loadModelDetail
,
refreshModel
,
setLastModelId
}
=
useUserStore
();
const
{
File
,
onOpen
:
onOpenSelectFile
}
=
useSelectFile
({
const
{
File
,
onOpen
:
onOpenSelectFile
}
=
useSelectFile
({
fileType
:
'.jpg,.png'
,
fileType
:
'.jpg,.png'
,
multiple
:
false
multiple
:
false
...
@@ -119,7 +120,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
...
@@ -119,7 +120,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
status
:
'success'
status
:
'success'
});
});
refreshModel
.
removeModelDetail
(
modelDetail
.
_id
);
refreshModel
.
removeModelDetail
(
modelDetail
.
_id
);
router
.
replace
(
'/model'
);
router
.
replace
(
`/model?modelId=
${
myModels
[
1
]?.
_id
}
`
);
} catch (err: any) {
} catch (err: any) {
toast({
toast({
title: err?.message || '删除失败',
title: err?.message || '删除失败',
...
@@ -127,7 +128,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
...
@@ -127,7 +128,7 @@ const Settings = ({ modelId }: { modelId: string }) => {
});
});
}
}
setIsLoading(false);
setIsLoading(false);
},
[
modelDetail
,
setIsLoading
,
toast
,
refreshModel
,
router
]);
}, [modelDetail, setIsLoading, toast, refreshModel, router
, myModels
]);
const onSelectFile = useCallback(
const onSelectFile = useCallback(
async (e: File[]) => {
async (e: File[]) => {
...
...
client/src/types/model.d.ts
View file @
a02a5287
...
@@ -5,7 +5,7 @@ export type ModelListItemType = {
...
@@ -5,7 +5,7 @@ export type ModelListItemType = {
_id
:
string
;
_id
:
string
;
name
:
string
;
name
:
string
;
avatar
:
string
;
avatar
:
string
;
systemPrompt
:
string
;
intro
:
string
;
};
};
export
interface
ModelUpdateParams
{
export
interface
ModelUpdateParams
{
...
...
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