mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-24 13:53:50 +00:00
perf: 对话框优化;feat: 模糊搜索
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
## 常见问题
|
||||
### 常见问题
|
||||
**请求次数太多了**
|
||||
一般是因为自己的 openai 账号异常。请先检查自己的账号是否正常使用。
|
||||
**内容长度**
|
||||
chatgpt 上下文最长 4096 tokens, 上下文超长时会报错。
|
||||
|
||||
**删除和复制**
|
||||
点击对话头像,可以选择复制或删除该条内容。
|
||||
|
||||
电脑端:聊天内容右侧有复制和删除的图标。
|
||||
移动端:点击对话头像,可以选择复制或删除该条内容。
|
||||
**代理出错**
|
||||
服务器代理不稳定,可以过一会儿再尝试。
|
||||
服务器代理不稳定,可以过一会儿再尝试。 或者可以访问国外服务器: [FastGpt](https://fastgpt.run/)
|
@@ -1,3 +1,5 @@
|
||||
## Fast GPT V2.7
|
||||
* FastGpt Api 允许你将 Fast Gpt 的部分功能通过 api 的形式,将知识库接入到自己的应用中,例如:飞书、企业微信、客服助手.
|
||||
* 通过 csv 文件导入和导出你的问答对。你可以将你的 csv 文件放置在飞书文档上,以便团队共享。
|
||||
### Fast GPT V2.8.1
|
||||
* 优化 - 知识库升级,内容条数不上限!
|
||||
* 优化 - 导入去重效果,可防止导出后的 csv 重复导入。
|
||||
* 优化 - 聊天框,电脑端复制删除图标。
|
||||
* 优化 - 聊天框,生成内容时,如果滚动条触底,则会自动向下滚动,不需要手动下滑。
|
1
src/components/Icon/icons/delete.svg
Normal file
1
src/components/Icon/icons/delete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1681997838051" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4520" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M898 178.7H665.3c4.3-9.8 6.7-20.6 6.7-32 0-44-36-80-80-80H432c-44 0-80 36-80 80 0 11.4 2.4 22.2 6.7 32H126c-13.2 0-24 10.8-24 24s10.8 24 24 24h772c13.2 0 24-10.8 24-24s-10.8-24-24-24z m-466 0c-8.5 0-16.5-3.4-22.6-9.4-6.1-6.1-9.4-14.1-9.4-22.6s3.4-16.5 9.4-22.6c6.1-6.1 14.1-9.4 22.6-9.4h160c8.5 0 16.5 3.4 22.6 9.4 6.1 6.1 9.4 14.1 9.4 22.6 0 8.5-3.4 16.5-9.4 22.6-6.1 6.1-14.1 9.4-22.6 9.4H432zM513 774.7c18.1 0 33-14.8 33-33v-334c0-18.1-14.9-33-33-33h-2c-18.1 0-33 14.8-33 33v334c0 18.2 14.8 33 33 33h2zM363 774.7c18.1 0 33-14.8 33-33v-334c0-18.1-14.9-33-33-33h-2c-18.1 0-33 14.8-33 33v334c0 18.2 14.8 33 33 33h2zM663 774.7c18.1 0 33-14.8 33-33v-334c0-18.1-14.9-33-33-33h-2c-18.1 0-33 14.8-33 33v334c0 18.2 14.8 33 33 33h2z" p-id="4521"></path><path d="M812 280.7c-13.3 0-24 10.7-24 24v530c0 41.9-34.1 76-76 76H312c-41.9 0-76-34.1-76-76v-530c0-13.3-10.7-24-24-24s-24 10.7-24 24v530c0 68.4 55.6 124 124 124h400c68.4 0 124-55.6 124-124v-530c0-13.2-10.7-24-24-24z" p-id="4522"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
@@ -13,14 +13,23 @@ const map = {
|
||||
board: require('./icons/board.svg').default,
|
||||
develop: require('./icons/develop.svg').default,
|
||||
user: require('./icons/user.svg').default,
|
||||
chatting: require('./icons/chatting.svg').default
|
||||
chatting: require('./icons/chatting.svg').default,
|
||||
delete: require('./icons/delete.svg').default
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof map;
|
||||
|
||||
const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconName } & IconProps) => {
|
||||
return map[name] ? (
|
||||
<Icon as={map[name]} w={w} h={h} boxSizing={'content-box'} verticalAlign={'top'} {...props} />
|
||||
<Icon
|
||||
as={map[name]}
|
||||
w={w}
|
||||
h={h}
|
||||
boxSizing={'content-box'}
|
||||
verticalAlign={'top'}
|
||||
fill={'currentcolor'}
|
||||
{...props}
|
||||
/>
|
||||
) : null;
|
||||
};
|
||||
|
||||
|
@@ -13,8 +13,8 @@ import styles from './index.module.scss';
|
||||
import { codeLight } from './codeLight';
|
||||
|
||||
const Markdown = ({ source, isChatting = false }: { source: string; isChatting?: boolean }) => {
|
||||
const formatSource = useMemo(() => source, [source]);
|
||||
const { copyData } = useCopyData();
|
||||
const formatSource = useMemo(() => source, [source]);
|
||||
|
||||
return (
|
||||
<ReactMarkdown
|
||||
|
@@ -36,9 +36,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
|
||||
await connectToDatabase();
|
||||
|
||||
const where: any = [
|
||||
['user_id', userId],
|
||||
'AND',
|
||||
['model_id', modelId],
|
||||
...(searchText ? ['AND', `(q LIKE '%${searchText}%' OR a LIKE '%${searchText}%')`] : [])
|
||||
];
|
||||
|
||||
const searchRes = await PgClient.select<PgModelDataItemType>('modelData', {
|
||||
fields: ['id', 'q', 'a', 'status'],
|
||||
where: [['user_id', userId], 'AND', ['model_id', modelId]],
|
||||
where,
|
||||
order: [{ field: 'id', mode: 'DESC' }],
|
||||
limit: pageSize,
|
||||
offset: pageSize * (pageNum - 1)
|
||||
@@ -50,7 +57,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
||||
pageSize,
|
||||
data: searchRes.rows,
|
||||
total: await PgClient.count('modelData', {
|
||||
where: [['user_id', userId], 'AND', ['model_id', modelId]]
|
||||
where
|
||||
})
|
||||
}
|
||||
});
|
||||
|
@@ -28,7 +28,8 @@ import { useChatStore } from '@/store/chat';
|
||||
import { useCopyData } from '@/utils/tools';
|
||||
import { streamFetch } from '@/api/fetch';
|
||||
import Icon from '@/components/Icon';
|
||||
import { modelList } from '@/constants/model';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { throttle } from 'lodash';
|
||||
|
||||
const SlideBar = dynamic(() => import('./components/SlideBar'));
|
||||
const Empty = dynamic(() => import('./components/Empty'));
|
||||
@@ -73,16 +74,28 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
const { pushChatHistory } = useChatStore();
|
||||
|
||||
// 滚动到底部
|
||||
const scrollToBottom = useCallback(() => {
|
||||
setTimeout(() => {
|
||||
ChatBox.current &&
|
||||
ChatBox.current.scrollTo({
|
||||
top: ChatBox.current.scrollHeight,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}, 100);
|
||||
const scrollToBottom = useCallback((behavior: 'smooth' | 'auto' = 'smooth') => {
|
||||
if (!ChatBox.current) return;
|
||||
ChatBox.current.scrollTo({
|
||||
top: ChatBox.current.scrollHeight,
|
||||
behavior
|
||||
});
|
||||
}, []);
|
||||
|
||||
// 聊天信息生成中……获取当前滚动条位置,判断是否需要滚动到底部
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const generatingMessage = useCallback(
|
||||
throttle(() => {
|
||||
if (!ChatBox.current) return;
|
||||
const isBottom =
|
||||
ChatBox.current.scrollTop + ChatBox.current.clientHeight + 50 >=
|
||||
ChatBox.current.scrollHeight;
|
||||
|
||||
isBottom && scrollToBottom('auto');
|
||||
}, 100),
|
||||
[]
|
||||
);
|
||||
|
||||
// 重置输入内容
|
||||
const resetInputVal = useCallback((val: string) => {
|
||||
setInputVal(val);
|
||||
@@ -141,6 +154,7 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
};
|
||||
})
|
||||
}));
|
||||
generatingMessage();
|
||||
},
|
||||
abortSignal: controller.current
|
||||
});
|
||||
@@ -178,7 +192,7 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
})
|
||||
}));
|
||||
},
|
||||
[chatData.modelName, chatId, toast]
|
||||
[chatData.modelName, chatId, generatingMessage, toast]
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -226,7 +240,9 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
|
||||
// 清空输入内容
|
||||
resetInputVal('');
|
||||
scrollToBottom();
|
||||
setTimeout(() => {
|
||||
scrollToBottom();
|
||||
}, 100);
|
||||
|
||||
try {
|
||||
await gptChatPrompt(newChatList[newChatList.length - 2]);
|
||||
@@ -313,8 +329,8 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
});
|
||||
if (res.history.length > 0) {
|
||||
setTimeout(() => {
|
||||
scrollToBottom();
|
||||
}, 500);
|
||||
scrollToBottom('auto');
|
||||
}, 2000);
|
||||
}
|
||||
},
|
||||
onError(e: any) {
|
||||
@@ -340,6 +356,7 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
controller.current?.abort();
|
||||
};
|
||||
}, [chatId]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
h={'100%'}
|
||||
@@ -433,6 +450,29 @@ const Chat = ({ chatId }: { chatId: string }) => {
|
||||
<Box whiteSpace={'pre-wrap'}>{item.value}</Box>
|
||||
)}
|
||||
</Box>
|
||||
{isPc && (
|
||||
<Flex h={'100%'} flexDirection={'column'} ml={2} w={'14px'} height={'100%'}>
|
||||
<Box minH={'40px'} flex={1}>
|
||||
<MyIcon
|
||||
name="copy"
|
||||
w={'14px'}
|
||||
cursor={'pointer'}
|
||||
color={'alphaBlack.400'}
|
||||
onClick={() => onclickCopy(item.value)}
|
||||
/>
|
||||
</Box>
|
||||
<MyIcon
|
||||
name="delete"
|
||||
w={'14px'}
|
||||
cursor={'pointer'}
|
||||
color={'alphaBlack.400'}
|
||||
_hover={{
|
||||
color: 'red.600'
|
||||
}}
|
||||
onClick={() => delChatRecord(index)}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</Box>
|
||||
))}
|
||||
|
Reference in New Issue
Block a user