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
6ac7119e
authored
Jun 12, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: kb UI
parent
daf1148b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
117 additions
and
93 deletions
+117
-93
README.md
+1
-1
client/src/components/Tag/index.tsx
+3
-3
client/src/constants/theme.ts
+2
-2
client/src/hooks/usePagination.tsx
+3
-1
client/src/pages/api/plugins/kb/data/getDataList.ts
+1
-0
client/src/pages/kb/components/DataCard.tsx
+0
-0
client/src/pages/kb/components/Detail.tsx
+29
-10
client/src/pages/kb/components/Info.tsx
+74
-73
client/src/pages/kb/components/KbList.tsx
+2
-2
client/src/pages/number/index.tsx
+2
-1
No files found.
README.md
View file @
6ac7119e
...
@@ -37,8 +37,8 @@ Fast GPT 允许你使用自己的 openai API KEY 来快速的调用 openai 接
...
@@ -37,8 +37,8 @@ Fast GPT 允许你使用自己的 openai API KEY 来快速的调用 openai 接
## 👀 其他
## 👀 其他
-
[
FastGpt 常见问题
](
https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh
)
-
[
FastGpt 常见问题
](
https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh
)
-
[
docker 部署教程
](
https://www.bilibili.com/video/BV1jo4y147fT/
)
-
[
公众号接入
](
https://www.bilibili.com/video/BV1xh4y1t7fy/
)
-
[
公众号接入
](
https://www.bilibili.com/video/BV1xh4y1t7fy/
)
-
[
FastGpt + Laf 最佳实践,将知识库装入公众号,点击去 Laf 公众号体验效果
](
https://b4jky7-fastgpt.oss.laf.run/lafercode.png
)
-
[
FastGpt V3.4 更新集合
](
https://www.bilibili.com/video/BV1Lo4y147Qh/?vd_source=92041a1a395f852f9d89158eaa3f61b4
)
-
[
FastGpt V3.4 更新集合
](
https://www.bilibili.com/video/BV1Lo4y147Qh/?vd_source=92041a1a395f852f9d89158eaa3f61b4
)
-
[
FastGpt 知识库演示
](
https://www.bilibili.com/video/BV1Wo4y1p7i1/
)
-
[
FastGpt 知识库演示
](
https://www.bilibili.com/video/BV1Wo4y1p7i1/
)
...
...
client/src/components/Tag/index.tsx
View file @
6ac7119e
...
@@ -29,11 +29,11 @@ const Tag = ({ children, colorSchema = 'blue', ...props }: Props) => {
...
@@ -29,11 +29,11 @@ const Tag = ({ children, colorSchema = 'blue', ...props }: Props) => {
},
[
colorSchema
]);
},
[
colorSchema
]);
return
(
return
(
<
Box
<
Box
as=
{
'span
'
}
display=
{
'inline-block
'
}
border=
{
'1px solid'
}
border=
{
'1px solid'
}
px=
{
2
}
px=
{
2
}
lineHeight=
{
0
}
lineHeight=
{
1
}
py=
{
'
1
px'
}
py=
{
'
2
px'
}
borderRadius=
{
'md'
}
borderRadius=
{
'md'
}
fontSize=
{
'xs'
}
fontSize=
{
'xs'
}
{
...
theme
}
{
...
theme
}
...
...
client/src/constants/theme.ts
View file @
6ac7119e
...
@@ -249,8 +249,8 @@ export const theme = extendTheme({
...
@@ -249,8 +249,8 @@ export const theme = extendTheme({
'2xl'
:
'2100px'
'2xl'
:
'2100px'
},
},
lgColor
:
{
lgColor
:
{
activeBlueGradient
:
'linear-gradient(
120deg
, #d6e8ff 0%, #f0f7ff 100%)'
,
activeBlueGradient
:
'linear-gradient(
to bottom right
, #d6e8ff 0%, #f0f7ff 100%)'
,
hoverBlueGradient
:
'linear-gradient(
60deg, #f0f7ff 0%, #d6e8
ff 100%)'
,
hoverBlueGradient
:
'linear-gradient(
to top left, #d6e8ff 0%, #f0f7
ff 100%)'
,
primary
:
'linear-gradient(to bottom right, #2152d9 0%,#3370ff 40%, #4e83fd 100%)'
,
primary
:
'linear-gradient(to bottom right, #2152d9 0%,#3370ff 40%, #4e83fd 100%)'
,
primary2
:
'linear-gradient(to bottom right, #2152d9 0%,#3370ff 30%,#4e83fd 80%, #85b1ff 100%)'
primary2
:
'linear-gradient(to bottom right, #2152d9 0%,#3370ff 30%,#4e83fd 80%, #85b1ff 100%)'
},
},
...
...
client/src/hooks/usePagination.tsx
View file @
6ac7119e
...
@@ -54,6 +54,7 @@ export const usePagination = <T = any,>({
...
@@ -54,6 +54,7 @@ export const usePagination = <T = any,>({
size=
{
'sm'
}
size=
{
'sm'
}
w=
{
'28px'
}
w=
{
'28px'
}
h=
{
'28px'
}
h=
{
'28px'
}
isLoading=
{
isLoading
}
onClick=
{
()
=>
mutate
(
pageNum
-
1
)
}
onClick=
{
()
=>
mutate
(
pageNum
-
1
)
}
/>
/>
<
Flex
mx=
{
2
}
alignItems=
{
'center'
}
>
<
Flex
mx=
{
2
}
alignItems=
{
'center'
}
>
...
@@ -84,13 +85,14 @@ export const usePagination = <T = any,>({
...
@@ -84,13 +85,14 @@ export const usePagination = <T = any,>({
icon=
{
<
ArrowForwardIcon
/>
}
icon=
{
<
ArrowForwardIcon
/>
}
aria
-
label=
{
'left'
}
aria
-
label=
{
'left'
}
size=
{
'sm'
}
size=
{
'sm'
}
isLoading=
{
isLoading
}
w=
{
'28px'
}
w=
{
'28px'
}
h=
{
'28px'
}
h=
{
'28px'
}
onClick=
{
()
=>
mutate
(
pageNum
+
1
)
}
onClick=
{
()
=>
mutate
(
pageNum
+
1
)
}
/>
/>
</
Flex
>
</
Flex
>
);
);
},
[
maxPage
,
mutate
,
pageNum
]);
},
[
isLoading
,
maxPage
,
mutate
,
pageNum
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
defaultRequest
&&
mutate
(
1
);
defaultRequest
&&
mutate
(
1
);
...
...
client/src/pages/api/plugins/kb/data/getDataList.ts
View file @
6ac7119e
...
@@ -26,6 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
...
@@ -26,6 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
await
connectToDatabase
();
await
connectToDatabase
();
searchText
=
searchText
.
replace
(
/'/g
,
''
);
const
where
:
any
=
[
const
where
:
any
=
[
[
'user_id'
,
userId
],
[
'user_id'
,
userId
],
...
...
client/src/pages/kb/components/DataCard.tsx
View file @
6ac7119e
This diff is collapsed.
Click to expand it.
client/src/pages/kb/components/Detail.tsx
View file @
6ac7119e
import
React
,
{
useRef
}
from
'react'
;
import
React
,
{
useRef
,
useState
}
from
'react'
;
import
{
useRouter
}
from
'next/router'
;
import
{
useRouter
}
from
'next/router'
;
import
{
Card
,
Box
}
from
'@chakra-ui/react'
;
import
{
Box
}
from
'@chakra-ui/react'
;
import
{
useToast
}
from
'@/hooks/useToast'
;
import
{
useToast
}
from
'@/hooks/useToast'
;
import
{
useForm
}
from
'react-hook-form'
;
import
{
useForm
}
from
'react-hook-form'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
{
useUserStore
}
from
'@/store/user'
;
import
{
KbItemType
}
from
'@/types/plugin'
;
import
{
KbItemType
}
from
'@/types/plugin'
;
import
{
useScreen
}
from
'@/hooks/useScreen'
;
import
DataCard
from
'./DataCard'
;
import
DataCard
from
'./DataCard'
;
import
{
getErrText
}
from
'@/utils/tools'
;
import
{
getErrText
}
from
'@/utils/tools'
;
import
Info
,
{
type
ComponentRef
}
from
'./Info'
;
import
Info
,
{
type
ComponentRef
}
from
'./Info'
;
import
Tabs
from
'@/components/Tabs'
;
enum
TabEnum
{
data
=
'data'
,
test
=
'test'
,
info
=
'info'
}
const
Detail
=
({
kbId
}:
{
kbId
:
string
})
=>
{
const
Detail
=
({
kbId
}:
{
kbId
:
string
})
=>
{
const
{
toast
}
=
useToast
();
const
{
toast
}
=
useToast
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
{
isPc
}
=
useScreen
();
const
BasicInfo
=
useRef
<
ComponentRef
>
(
null
);
const
BasicInfo
=
useRef
<
ComponentRef
>
(
null
);
const
{
setLastKbId
,
kbDetail
,
getKbDetail
,
loadKbList
,
myKbList
}
=
useUserStore
();
const
{
setLastKbId
,
kbDetail
,
getKbDetail
,
loadKbList
,
myKbList
}
=
useUserStore
();
const
[
currentTab
,
setCurrentTab
]
=
useState
(
TabEnum
.
data
);
const
form
=
useForm
<
KbItemType
>
({
const
form
=
useForm
<
KbItemType
>
({
defaultValues
:
kbDetail
defaultValues
:
kbDetail
...
@@ -42,13 +51,23 @@ const Detail = ({ kbId }: { kbId: string }) => {
...
@@ -42,13 +51,23 @@ const Detail = ({ kbId }: { kbId: string }) => {
});
});
return
(
return
(
<
Box
h=
{
'100%'
}
p=
{
5
}
overflow=
{
'overlay'
}
position=
{
'relative'
}
>
<
Box
bg=
{
'#fcfcfc'
}
h=
{
'100%'
}
p=
{
5
}
overflow=
{
'overlay'
}
position=
{
'relative'
}
>
<
Card
p=
{
6
}
>
<
Box
mb=
{
5
}
>
<
Info
ref=
{
BasicInfo
}
kbId=
{
kbId
}
form=
{
form
}
/>
<
Tabs
</
Card
>
m=
{
'auto'
}
<
Card
p=
{
6
}
mt=
{
5
}
>
w=
{
'260px'
}
<
DataCard
kbId=
{
kbId
}
/>
size=
{
isPc
?
'md'
:
'sm'
}
</
Card
>
list=
{
[
{
id
:
TabEnum
.
data
,
label
:
'数据管理'
},
{
id
:
TabEnum
.
test
,
label
:
'搜索测试'
},
{
id
:
TabEnum
.
info
,
label
:
'基本信息'
}
]
}
activeId=
{
currentTab
}
onChange=
{
(
e
:
any
)
=>
setCurrentTab
(
e
)
}
/>
</
Box
>
{
currentTab
===
TabEnum
.
data
&&
<
DataCard
kbId=
{
kbId
}
/>
}
{
currentTab
===
TabEnum
.
info
&&
<
Info
ref=
{
BasicInfo
}
kbId=
{
kbId
}
form=
{
form
}
/>
}
</
Box
>
</
Box
>
);
);
};
};
...
...
client/src/pages/kb/components/Info.tsx
View file @
6ac7119e
...
@@ -140,88 +140,89 @@ const Info = (
...
@@ -140,88 +140,89 @@ const Info = (
}));
}));
return (
return (
<Box>
<Flex flexDirection={'column'} alignItems={'center'}>
<Flex>
<Flex mt={5} w={'100%'} maxW={'350px'} alignItems={'center'}>
<Box fontWeight={'bold'} fontSize={'2xl'} flex={1}>
<Box flex={'0 0 90px'} w={0}>
知识库信息
知识库头像
</Box>
<Box flex={1}>
<Avatar
m={'auto'}
src={getValues('avatar')}
w={['32px', '40px']}
h={['32px', '40px']}
cursor={'pointer'}
title={'点击切换头像'}
onClick={onOpenSelectFile}
/>
</Box>
</Box>
{kbDetail._id && (
<>
<Button
isLoading={btnLoading}
mr={3}
onClick={handleSubmit(saveSubmitSuccess, saveSubmitError)}
>
保存
</Button>
<IconButton
isLoading={btnLoading}
icon={<DeleteIcon />}
aria-label={''}
variant={'solid'}
colorScheme={'red'}
onClick={openConfirm(onclickDelKb)}
/>
</>
)}
</Flex>
</Flex>
<F
lex mt={5
} alignItems={'center'}>
<F
ormControl mt={8} w={'100%'} maxW={'350px'} display={'flex'
} alignItems={'center'}>
<Box flex={'0 0
6
0px'} w={0}>
<Box flex={'0 0
9
0px'} w={0}>
头像
知识库名称
</Box>
</Box>
<Avatar
<Input
src={getValues('avatar')}
flex={1}
w={['28px', '36px']}
{...register('name', {
h={['28px', '36px']}
required: '知识库名称不能为空'
cursor={'pointer'}
})}
title={'点击切换头像'}
onClick={onOpenSelectFile}
/>
/>
</Flex>
<FormControl mt={5}>
<Flex alignItems={'center'} maxW={'350px'}>
<Box flex={'0 0 60px'} w={0}>
名称
</Box>
<Input
{...register('name', {
required: '知识库名称不能为空'
})}
/>
</Flex>
</FormControl>
</FormControl>
<Box>
<Flex mt={8} alignItems={'center'} w={'100%'} maxW={'350px'} flexWrap={'wrap'}>
<Flex mt={5} alignItems={'center'} maxW={'350px'} flexWrap={'wrap'}>
<Box flex={'0 0 90px'} w={0}>
<Box flex={'0 0 60px'} w={0}>
分类标签
标签
<Tooltip label={'用空格隔开多个标签,便于搜索'}>
<Tooltip label={'仅用于记忆,用空格隔开多个标签'}>
<QuestionOutlineIcon ml={1} />
<QuestionOutlineIcon ml={1} />
</Tooltip>
</Tooltip>
</Box>
</Box>
<Input
<Input
flex={1}
flex={1}
maxW={'300px'}
ref={InputRef}
ref={InputRef}
placeholder={'标签,使用空格分割。'}
placeholder={'标签,使用空格分割。'}
onChange={(e) => {
maxLength={30}
setValue('tags', e.target.value);
onChange={(e) => {
setRefresh(!refresh);
setValue('tags', e.target.value);
}}
setRefresh(!refresh);
}}
/>
<Box mt={2} w="100%">
{getValues('tags')
.split(' ')
.filter((item) => item)
.map((item, i) => (
<Tag mr={2} mb={2} key={i} whiteSpace={'nowrap'}>
{item}
</Tag>
))}
</Box>
</Flex>
{kbDetail._id && (
<Flex mt={5} w={'100%'} maxW={'350px'} alignItems={'flex-end'}>
<Box flex={'0 0 90px'} w={0}></Box>
<Button
isLoading={btnLoading}
mr={4}
w={'100px'}
onClick={handleSubmit(saveSubmitSuccess, saveSubmitError)}
>
保存
</Button>
<IconButton
isLoading={btnLoading}
icon={<DeleteIcon />}
aria-label={''}
variant={'outline'}
size={'sm'}
colorScheme={'red'}
color={'red.500'}
onClick={openConfirm(onclickDelKb)}
/>
/>
<Box pl={'60px'} mt={2} w="100%">
{getValues('tags')
.split(' ')
.filter((item) => item)
.map((item, i) => (
<Tag mr={2} mb={2} key={i}>
{item}
</Tag>
))}
</Box>
</Flex>
</Flex>
</Box>
)}
<File onSelect={onSelectFile} />
<File onSelect={onSelectFile} />
<ConfirmChild />
<ConfirmChild />
</
Bo
x>
</
Fle
x>
);
);
};
};
...
...
client/src/pages/kb/components/KbList.tsx
View file @
6ac7119e
...
@@ -119,12 +119,12 @@ const KbList = ({ kbId }: { kbId: string }) => {
...
@@ -119,12 +119,12 @@ const KbList = ({ kbId }: { kbId: string }) => {
{
item
.
name
}
{
item
.
name
}
</
Box
>
</
Box
>
{
/* tags */
}
{
/* tags */
}
<
Box
c
lassName=
"textEllipsis"
color=
{
'myGray.400'
}
py=
{
1
}
>
<
Box
c
olor=
{
'myGray.400'
}
py=
{
1
}
fontSize=
{
'sm'
}
>
{
!
item
.
tags
?
(
{
!
item
.
tags
?
(
<>
{
item
.
tags
||
'你还没设置标签~'
}
</>
<>
{
item
.
tags
||
'你还没设置标签~'
}
</>
)
:
(
)
:
(
item
.
tags
.
split
(
' '
).
map
((
item
,
i
)
=>
(
item
.
tags
.
split
(
' '
).
map
((
item
,
i
)
=>
(
<
Tag
key=
{
i
}
mr=
{
2
}
mb=
{
2
}
>
<
Tag
key=
{
i
}
mr=
{
1
}
mb=
{
1
}
>
{
item
}
{
item
}
</
Tag
>
</
Tag
>
))
))
...
...
client/src/pages/number/index.tsx
View file @
6ac7119e
...
@@ -245,13 +245,14 @@ const NumberSetting = ({ tableType }: { tableType: `${TableEnum}` }) => {
...
@@ -245,13 +245,14 @@ const NumberSetting = ({ tableType }: { tableType: `${TableEnum}` }) => {
<
Card
mt=
{
4
}
px=
{
[
3
,
6
]
}
py=
{
4
}
>
<
Card
mt=
{
4
}
px=
{
[
3
,
6
]
}
py=
{
4
}
>
<
Tabs
<
Tabs
m=
{
'auto'
}
w=
{
'200px'
}
w=
{
'200px'
}
list=
{
tableList
.
current
}
list=
{
tableList
.
current
}
activeId=
{
currentTab
}
activeId=
{
currentTab
}
size=
{
'sm'
}
size=
{
'sm'
}
onChange=
{
(
id
:
any
)
=>
setCurrentTab
(
id
)
}
onChange=
{
(
id
:
any
)
=>
setCurrentTab
(
id
)
}
/>
/>
<
Box
>
<
Box
minH=
{
'300px'
}
>
{
(()
=>
{
{
(()
=>
{
const
item
=
tableList
.
current
.
find
((
item
)
=>
item
.
id
===
currentTab
);
const
item
=
tableList
.
current
.
find
((
item
)
=>
item
.
id
===
currentTab
);
...
...
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