feat: chat slider support folder (#1759)

* feat: docker-compose version

* feat: chat slider support folder

* lazy behavior

* pref: code sandbox size
This commit is contained in:
Archer
2024-06-13 23:09:36 +08:00
committed by GitHub
parent 6385794603
commit f7f4a8de4d
20 changed files with 336 additions and 152 deletions

View File

@@ -1,5 +1,5 @@
---
title: 'V4.8.4(进行中)'
title: 'V4.8.4'
description: 'FastGPT V4.8.4 更新说明'
icon: 'upgrade'
draft: false

View File

@@ -114,15 +114,15 @@ services:
# fastgpt
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.8.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.3 # 阿里云
image: ghcr.io/labring/fastgpt-sandbox:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.4 # 阿里云
networks:
- fastgpt
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.3 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.4 # 阿里云
ports:
- 3000:3000
networks:

View File

@@ -72,15 +72,15 @@ services:
# fastgpt
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.8.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.3 # 阿里云
image: ghcr.io/labring/fastgpt-sandbox:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.4 # 阿里云
networks:
- fastgpt
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.3 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.4 # 阿里云
ports:
- 3000:3000
networks:

View File

@@ -53,15 +53,15 @@ services:
wait $$!
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.8.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.3 # 阿里云
image: ghcr.io/labring/fastgpt-sandbox:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.4 # 阿里云
networks:
- fastgpt
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.3 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.4 # 阿里云
ports:
- 3000:3000
networks:

View File

@@ -51,6 +51,7 @@ export const iconPaths = {
'common/routePushLight': () => import('./icons/common/routePushLight.svg'),
'common/saveFill': () => import('./icons/common/saveFill.svg'),
'common/searchLight': () => import('./icons/common/searchLight.svg'),
'common/select': () => import('./icons/common/select.svg'),
'common/selectLight': () => import('./icons/common/selectLight.svg'),
'common/settingLight': () => import('./icons/common/settingLight.svg'),
'common/text/t': () => import('./icons/common/text/t.svg'),

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 17" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M5.42469 4.94872C5.16434 5.20906 5.16434 5.63117 5.42469 5.89152C5.68504 6.15187 6.10715 6.15187 6.3675 5.89152L8.00002 4.25901L9.63253 5.89152C9.89288 6.15187 10.315 6.15187 10.5753 5.89152C10.8357 5.63117 10.8357 5.20906 10.5753 4.94872L8.47142 2.8448C8.21107 2.58445 7.78896 2.58445 7.52861 2.8448L5.42469 4.94872ZM5.42469 10.8375C5.16434 11.0979 5.16434 11.52 5.42469 11.7803L7.52861 13.8843C7.56115 13.9168 7.59623 13.9453 7.63319 13.9697C7.89196 14.1405 8.24361 14.1121 8.47142 13.8843L10.5753 11.7803C10.8357 11.52 10.8357 11.0979 10.5753 10.8375C10.315 10.5772 9.89288 10.5772 9.63253 10.8375L8.00002 12.47L6.3675 10.8375C6.10715 10.5772 5.68504 10.5772 5.42469 10.8375Z" />
</svg>

After

Width:  |  Height:  |  Size: 823 B

View File

@@ -81,7 +81,14 @@ const MyMenu = ({
}, [offset]);
return (
<Menu offset={computeOffset} isOpen={isOpen} autoSelect={false} direction={'ltr'} isLazy>
<Menu
offset={computeOffset}
isOpen={isOpen}
autoSelect={false}
direction={'ltr'}
isLazy
lazyBehavior={'keepMounted'}
>
<Box
ref={ref}
onMouseEnter={() => {

View File

@@ -0,0 +1,48 @@
import React from 'react';
import {
Popover,
PopoverTrigger,
PopoverContent,
useDisclosure,
PlacementWithLogical
} from '@chakra-ui/react';
const MyPopover = ({
Trigger,
placement,
offset,
trigger,
children
}: {
Trigger: React.ReactNode;
placement?: PlacementWithLogical;
offset?: [number, number];
trigger?: 'hover' | 'click';
children: (e: { onClose: () => void }) => React.ReactNode;
}) => {
const firstFieldRef = React.useRef(null);
const { onOpen, onClose, isOpen } = useDisclosure();
return (
<Popover
isOpen={isOpen}
initialFocusRef={firstFieldRef}
onOpen={onOpen}
onClose={onClose}
placement={placement}
offset={offset}
closeOnBlur={false}
trigger={trigger}
openDelay={100}
closeDelay={100}
isLazy
lazyBehavior="keepMounted"
>
<PopoverTrigger>{Trigger}</PopoverTrigger>
<PopoverContent p={4}>{children({ onClose })}</PopoverContent>
</Popover>
);
};
export default MyPopover;

View File

@@ -73,6 +73,7 @@
"Last use time": "Last use time",
"Load Failed": "Load Failed",
"Loading": "Loading...",
"More": "More",
"More settings": "More settings",
"Move": "Move",
"MultipleRowSelect": {
@@ -430,6 +431,7 @@
"Quote": "Quote",
"Quote Amount": "Dataset quotes ({{amount}} items)",
"Read Mark Description": "View introduction to marking function",
"Recent use": "Recent use",
"Record": "Voice input",
"Restart": "Restart conversation",
"Select File": "Select file",

View File

@@ -73,6 +73,7 @@
"Last use time": "最后使用时间",
"Load Failed": "加载失败",
"Loading": "加载中...",
"More": "更多",
"More settings": "更多设置",
"Move": "移动",
"MultipleRowSelect": {
@@ -431,6 +432,7 @@
"Quote": "引用",
"Quote Amount": "知识库引用({{amount}}条)",
"Read Mark Description": "查看标注功能介绍",
"Recent use": "最近使用",
"Record": "语音输入",
"Restart": "重开对话",
"Select File": "选择文件",

View File

@@ -1,12 +1,17 @@
### FastGPT V4.8.2
### FastGPT V4.8.4
1. 新增 - 应用使用新权限系统。
2. 新增 - 应用支持文件夹。
3. 优化 - 文本分割增加连续换行、制表符清除,避免大文本性能问题。
4. 重要修复 - 修复系统插件运行池数据污染问题,由于从内存获取,会导致全局污染。
5. 修复 - Debug 模式下,相同 source 和 target 内容,导致连线显示异常。
6. 修复 - 定时执行初始化错误。
7. 修复 - 应用调用传参异常。
8. 修复 - ctrl + cv 复杂节点时nodeId错误。
9. 调整组件库全局theme。
------
- 新增 - 知识库重新选择向量模型重建
- 新增 - 对话框支持问题模糊检索提示,可自定义预设问题词库
- 新增 - js代码运行节点
- 新增 - 外部文件源知识库: [点击查看文档](https://doc.fastai.site/docs/course/externalfile/)
- 新增 - 内容提取节点增加完全提取成功输出
- 新增 - HTTP节点增加错误输出可以自行判断处理
- 优化 - 插件输入的 debug 模式,支持全量参数输入渲染
- [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
- [使用文档](https://doc.fastgpt.in/docs/intro/)
- [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)

View File

@@ -13,7 +13,6 @@ const Avatar = ({ w = '30px', src, ...props }: ImageProps) => {
alt=""
w={w}
h={w}
p={'1px'}
src={src || LOGO_ICON}
{...props}
/>

View File

@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Box, Flex } from '@chakra-ui/react';
import React, { useMemo, useState } from 'react';
import { Box, BoxProps, Flex } from '@chakra-ui/react';
import {
GetResourceFolderListProps,
GetResourceListItemResponse,
@@ -10,24 +10,43 @@ import Loading from '@fastgpt/web/components/common/MyLoading';
import Avatar from '@/components/Avatar';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useMemoizedFn } from 'ahooks';
import { FolderImgUrl } from '@fastgpt/global/common/file/image/constants';
import { useTranslation } from 'next-i18next';
type ResourceItemType = GetResourceListItemResponse & {
open: boolean;
children?: ResourceItemType[];
};
const rootId = 'root';
const SelectOneResource = ({
server,
value,
onSelect
onSelect,
maxH = ['80vh', '600px']
}: {
server: (e: GetResourceFolderListProps) => Promise<GetResourceListItemResponse[]>;
value?: ParentIdType;
onSelect: (e?: string) => any;
maxH?: BoxProps['maxH'];
}) => {
const { t } = useTranslation();
const [dataList, setDataList] = useState<ResourceItemType[]>([]);
const [requestingIdList, setRequestingIdList] = useState<ParentIdType[]>([]);
const concatRoot = useMemo(() => {
const root: ResourceItemType = {
id: rootId,
open: true,
avatar: FolderImgUrl,
name: t('common.folder.Root Path'),
isFolder: true,
children: dataList
};
return [root];
}, [dataList, t]);
const { runAsync: requestServer } = useRequest2((e: GetResourceFolderListProps) => {
if (requestingIdList.includes(e.parentId)) return Promise.reject(null);
@@ -59,7 +78,7 @@ const SelectOneResource = ({
alignItems={'center'}
cursor={'pointer'}
py={1}
pl={`${1.25 * index + 0.5}rem`}
pl={index === 0 ? '0.5rem' : `${1.75 * (index - 1) + 0.5}rem`}
pr={2}
borderRadius={'md'}
_hover={{
@@ -72,6 +91,7 @@ const SelectOneResource = ({
}
: {
onClick: async () => {
if (item.id === rootId) return;
// folder => open(request children) or close
if (item.isFolder) {
if (!item.children) {
@@ -90,33 +110,31 @@ const SelectOneResource = ({
}
})}
>
<Flex
alignItems={'center'}
justifyContent={'center'}
visibility={
item.isFolder && (!item.children || item.children.length > 0)
? 'visible'
: 'hidden'
}
w={'1.25rem'}
h={'1.25rem'}
cursor={'pointer'}
borderRadius={'xs'}
_hover={{
bg: 'rgba(31, 35, 41, 0.08)'
}}
>
<MyIcon
name={
requestingIdList.includes(item.id)
? 'common/loading'
: 'common/rightArrowFill'
}
w={'14px'}
color={'myGray.500'}
transform={item.open ? 'rotate(90deg)' : 'none'}
/>
</Flex>
{index !== 0 && (
<Flex
alignItems={'center'}
justifyContent={'center'}
visibility={item.isFolder ? 'visible' : 'hidden'}
w={'1.25rem'}
h={'1.25rem'}
cursor={'pointer'}
borderRadius={'xs'}
_hover={{
bg: 'rgba(31, 35, 41, 0.08)'
}}
>
<MyIcon
name={
requestingIdList.includes(item.id)
? 'common/loading'
: 'common/rightArrowFill'
}
w={'14px'}
color={'myGray.500'}
transform={item.open ? 'rotate(90deg)' : 'none'}
/>
</Flex>
)}
<Avatar ml={index !== 0 ? '0.5rem' : 0} src={item.avatar} w={'1.25rem'} />
<Box fontSize={'sm'} ml={2}>
{item.name}
@@ -134,7 +152,13 @@ const SelectOneResource = ({
}
);
return loading ? <Loading fixed={false} /> : <Render list={dataList} />;
return loading ? (
<Loading fixed={false} />
) : (
<Box maxH={maxH} overflow={'auto'}>
<Render list={concatRoot} />
</Box>
);
};
export default SelectOneResource;

View File

@@ -16,8 +16,9 @@ import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { AppDefaultPermissionVal } from '@fastgpt/global/support/permission/app/constant';
export type ListAppBody = {
parentId: ParentIdType;
parentId?: ParentIdType;
type?: AppTypeEnum;
getRecentlyChat?: boolean;
};
async function handler(
@@ -35,14 +36,23 @@ async function handler(
per: ReadPermissionVal
});
const { parentId, type } = req.body;
const { parentId, type, getRecentlyChat } = req.body;
const findAppsQuery = getRecentlyChat
? {
// get all chat app
teamId,
type: { $in: [AppTypeEnum.advanced, AppTypeEnum.simple] }
}
: {
teamId,
...(type && { type }),
...parseParentIdInMongo(parentId)
};
/* temp: get all apps and per */
const [myApps, rpList] = await Promise.all([
MongoApp.find(
{ teamId, ...(type && { type }), ...parseParentIdInMongo(parentId) },
'_id avatar type name intro tmbId defaultPermission'
)
MongoApp.find(findAppsQuery, '_id avatar type name intro tmbId defaultPermission')
.sort({
updateTime: -1
})
@@ -69,7 +79,9 @@ async function handler(
})
.filter((app) => app.permission.hasReadPer);
return filterApps.map((app) => ({
const sliceApps = getRecentlyChat ? filterApps.slice(0, 15) : filterApps;
return sliceApps.map((app) => ({
_id: app._id,
avatar: app.avatar,
type: app.type,

View File

@@ -1,15 +1,5 @@
import React, { useMemo, useState } from 'react';
import {
Box,
Button,
Flex,
useTheme,
Menu,
MenuButton,
MenuList,
MenuItem,
IconButton
} from '@chakra-ui/react';
import React, { useCallback, useMemo, useState } from 'react';
import { Box, Button, Flex, useTheme, IconButton } from '@chakra-ui/react';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useEditTitle } from '@/web/common/hooks/useEditTitle';
import { useRouter } from 'next/router';
@@ -21,10 +11,15 @@ import { useConfirm } from '@fastgpt/web/hooks/useConfirm';
import Tabs from '@/components/Tabs';
import { useUserStore } from '@/web/support/user/useUserStore';
import { AppListItemType } from '@fastgpt/global/core/app/type';
import { useQuery } from '@tanstack/react-query';
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
import { useI18n } from '@/web/context/I18n';
import MyMenu from '@fastgpt/web/components/common/MyMenu';
import SelectOneResource from '@/components/common/folder/SelectOneResource';
import {
GetResourceFolderListProps,
GetResourceListItemResponse
} from '@fastgpt/global/common/parentFolder/type';
import { getMyApps } from '@/web/core/app/api';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
type HistoryItemType = {
id: string;
@@ -34,6 +29,7 @@ type HistoryItemType = {
};
enum TabEnum {
recently = 'recently',
'app' = 'app',
'history' = 'history'
}
@@ -69,6 +65,8 @@ const ChatHistorySlider = ({
}) => {
const theme = useTheme();
const router = useRouter();
const isTeamChat = router.pathname === '/chat/team';
const { t } = useTranslation();
const { appT } = useI18n();
@@ -78,6 +76,7 @@ const ChatHistorySlider = ({
const [currentTab, setCurrentTab] = useState<`${TabEnum}`>(TabEnum.history);
const showApps = apps?.length > 0;
// custom title edit
const { onOpenModal, EditModal: EditTitleModal } = useEditTitle({
title: t('core.chat.Custom History Title'),
@@ -96,17 +95,33 @@ const ChatHistorySlider = ({
[activeChatId, history, t]
);
useQuery(['init'], () => {
if (!showApps) {
setCurrentTab(TabEnum.history);
return null;
}
return;
});
const canRouteToDetail = useMemo(
() => appId && userInfo?.team.role !== TeamMemberRoleEnum.visitor,
[appId, userInfo?.team.role]
() => appId && userInfo?.team.permission.hasWritePer,
[appId, userInfo?.team.permission.hasWritePer]
);
const getAppList = useCallback(async ({ parentId }: GetResourceFolderListProps) => {
return getMyApps({ parentId }).then((res) =>
res.map<GetResourceListItemResponse>((item) => ({
id: item._id,
name: item.name,
avatar: item.avatar,
isFolder: item.type === AppTypeEnum.folder
}))
);
}, []);
const onChangeApp = useCallback(
(appId: string) => {
router.replace({
query: {
...router.query,
chatId: '',
appId
}
});
},
[router]
);
return (
@@ -148,10 +163,11 @@ const ChatHistorySlider = ({
<Flex w={'100%'} px={[2, 5]} h={'36px'} my={5} alignItems={'center'}>
{!isPc && appId && (
<Tabs
w={'120px'}
w={'180px'}
mr={2}
list={[
{ label: 'App', id: TabEnum.app },
{ label: t('core.chat.Recent use'), id: TabEnum.recently },
{ label: t('App'), id: TabEnum.app },
{ label: t('core.chat.History'), id: TabEnum.history }
]}
activeId={currentTab}
@@ -291,7 +307,7 @@ const ChatHistorySlider = ({
))}
</>
)}
{currentTab === TabEnum.app && !isPc && (
{currentTab === TabEnum.recently && !isPc && (
<>
{Array.isArray(apps) &&
apps.map((item) => (
@@ -309,12 +325,7 @@ const ChatHistorySlider = ({
}
: {
onClick: () => {
router.replace({
query: {
...router.query,
appId: item._id
}
});
onChangeApp(item._id);
onClose();
}
})}
@@ -327,9 +338,23 @@ const ChatHistorySlider = ({
))}
</>
)}
{currentTab === TabEnum.app && !isPc && (
<>
<SelectOneResource
value={appId}
onSelect={(id) => {
if (!id) return;
onChangeApp(id);
onClose();
}}
server={getAppList}
/>
</>
)}
</Box>
{!isPc && appId && (
{/* exec */}
{!isPc && appId && !isTeamChat && (
<Flex
mt={2}
borderTop={theme.borders.base}

View File

@@ -1,27 +1,53 @@
import React from 'react';
import { Flex, Box, IconButton } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import { Flex, Box, IconButton, HStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
import Avatar from '@/components/Avatar';
import { AppListItemType } from '@fastgpt/global/core/app/type';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
import MyPopover from '@fastgpt/web/components/common/MyPopover/index';
import SelectOneResource from '@/components/common/folder/SelectOneResource';
import { getMyApps } from '@/web/core/app/api';
import {
GetResourceFolderListProps,
GetResourceListItemResponse
} from '@fastgpt/global/common/parentFolder/type';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
const SliderApps = ({
showExist = true,
apps,
activeAppId
}: {
showExist?: boolean;
apps: AppListItemType[];
activeAppId: string;
}) => {
const SliderApps = ({ apps, activeAppId }: { apps: AppListItemType[]; activeAppId: string }) => {
const { t } = useTranslation();
const router = useRouter();
const isTeamChat = router.pathname === '/chat/team';
const getAppList = useCallback(async ({ parentId }: GetResourceFolderListProps) => {
return getMyApps({ parentId }).then((res) =>
res.map<GetResourceListItemResponse>((item) => ({
id: item._id,
name: item.name,
avatar: item.avatar,
isFolder: item.type === AppTypeEnum.folder
}))
);
}, []);
const onChangeApp = useCallback(
(appId: string) => {
router.replace({
query: {
...router.query,
chatId: '',
appId
}
});
},
[router]
);
return (
<Flex flexDirection={'column'} h={'100%'}>
<Box px={5} py={4}>
{showExist && (
<Box mt={4} px={4}>
{!isTeamChat && (
<Flex
alignItems={'center'}
cursor={'pointer'}
@@ -33,7 +59,7 @@ const SliderApps = ({
>
<IconButton
mr={3}
icon={<MyIcon name={'common/backFill'} w={'18px'} color={'primary.500'} />}
icon={<MyIcon name={'common/backFill'} w={'1rem'} color={'primary.500'} />}
bg={'white'}
boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'}
size={'smSquare'}
@@ -45,7 +71,58 @@ const SliderApps = ({
)}
</Box>
<Box flex={'1 0 0'} h={0} px={5} overflow={'overlay'}>
{!isTeamChat && (
<>
<MyDivider h={2} my={1} />
<MyPopover
placement="right-start"
offset={[30, -65]}
trigger="hover"
Trigger={
<HStack
px={4}
my={2}
color={'myGray.500'}
fontSize={'sm'}
justifyContent={'space-between'}
>
<Box>{t('core.chat.Recent use')}</Box>
<HStack
spacing={0.5}
cursor={'pointer'}
px={2}
py={'0.5'}
borderRadius={'md'}
mr={-2}
userSelect={'none'}
_hover={{
bg: 'myGray.200'
}}
>
<Box>{t('common.More')}</Box>
<MyIcon name={'common/select'} w={'1rem'} />
</HStack>
</HStack>
}
>
{({ onClose }) => (
<Box minH={'200px'}>
<SelectOneResource
value={activeAppId}
onSelect={(id) => {
if (!id) return;
onChangeApp(id);
onClose();
}}
server={getAppList}
/>
</Box>
)}
</MyPopover>
</>
)}
<Box flex={'1 0 0'} px={4} h={0} overflow={'overlay'}>
{apps.map((item) => (
<Flex
key={item._id}
@@ -59,21 +136,14 @@ const SliderApps = ({
{...(item._id === activeAppId
? {
bg: 'white',
boxShadow: 'md'
boxShadow: 'md',
color: 'primary.600'
}
: {
_hover: {
bg: 'myGray.200'
},
onClick: () => {
router.replace({
query: {
...router.query,
chatId: '',
appId: item._id
}
});
}
onClick: () => onChangeApp(item._id)
})}
>
<Avatar src={item.avatar} w={'24px'} />

View File

@@ -32,11 +32,12 @@ import ChatHeader from './components/ChatHeader';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { useUserStore } from '@/web/support/user/useUserStore';
import { serviceSideProps } from '@/web/common/utils/i18n';
import { useAppStore } from '@/web/core/app/store/useAppStore';
import { checkChatSupportSelectFileByChatModels } from '@/web/core/chat/utils';
import { getChatTitleFromChatMessage } from '@fastgpt/global/core/chat/utils';
import { ChatStatusEnum } from '@fastgpt/global/core/chat/constants';
import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt';
import { getMyApps } from '@/web/core/app/api';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
const router = useRouter();
@@ -62,7 +63,6 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
setChatData,
delOneHistoryItem
} = useChatStore();
const { myApps, loadMyApps } = useAppStore();
const { userInfo } = useUserStore();
const { isPc } = useSystemStore();
@@ -128,7 +128,12 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
[appId, chatId, histories, pushHistory, router, setChatData, updateHistory]
);
useQuery(['loadModels'], () => loadMyApps());
const { data: myApps = [], runAsync: loadMyApps } = useRequest2(
() => getMyApps({ getRecentlyChat: true }),
{
manual: false
}
);
// get chat app info
const loadChatInfo = useCallback(
@@ -272,7 +277,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
onClose={onCloseSlider}
>
<DrawerOverlay backgroundColor={'rgba(255,255,255,0.5)'} />
<DrawerContent maxWidth={'250px'}>{children}</DrawerContent>
<DrawerContent maxWidth={'75vw'}>{children}</DrawerContent>
</Drawer>
);
})(

View File

@@ -274,7 +274,7 @@ const OutLink = () => {
{/* pc show myself apps */}
{isPc && (
<Box borderRight={theme.borders.base} w={'220px'} flexShrink={0}>
<SliderApps showExist={false} apps={myApps} activeAppId={appId} />
<SliderApps apps={myApps} activeAppId={appId} />
</Box>
)}

View File

@@ -1,25 +0,0 @@
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import { getMyApps } from '@/web/core/app/api';
import { AppListItemType } from '@fastgpt/global/core/app/type';
export type State = {
myApps: AppListItemType[];
loadMyApps: (...arg: Parameters<typeof getMyApps>) => Promise<AppListItemType[]>;
};
export const useAppStore = create<State>()(
devtools(
immer((set, get) => ({
myApps: [],
async loadMyApps(data) {
const res = await getMyApps(data);
set((state) => {
state.myApps = res;
});
return res;
}
}))
)
);

View File

@@ -6,7 +6,12 @@ import { HttpExceptionFilter } from './http-exception.filter';
import { ResponseInterceptor } from './response';
async function bootstrap(port: number) {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter({
bodyLimit: 50 * 1048576 // 50MB
})
);
// 使用全局异常过滤器
app.useGlobalFilters(new HttpExceptionFilter());