fix: share page data;Adapt findLastIndex api (#3147)

* perf: share page data

* perf: adapt findLastIndex
This commit is contained in:
Archer
2024-11-13 13:08:34 +08:00
committed by GitHub
parent 519b519458
commit c3cc51c9a0
9 changed files with 100 additions and 56 deletions

View File

@@ -78,11 +78,15 @@ export const getHistoryPreview = (
}; };
export const filterPublicNodeResponseData = ({ export const filterPublicNodeResponseData = ({
flowResponses = [] flowResponses = [],
responseDetail = false
}: { }: {
flowResponses?: ChatHistoryItemResType[]; flowResponses?: ChatHistoryItemResType[];
responseDetail?: boolean;
}) => { }) => {
const filedList = ['quoteList', 'moduleType', 'pluginOutput', 'runningTime']; const filedList = responseDetail
? ['quoteList', 'moduleType', 'pluginOutput', 'runningTime']
: ['moduleType', 'pluginOutput', 'runningTime'];
const filterModuleTypeList: any[] = [ const filterModuleTypeList: any[] = [
FlowNodeTypeEnum.pluginModule, FlowNodeTypeEnum.pluginModule,
FlowNodeTypeEnum.datasetSearchNode, FlowNodeTypeEnum.datasetSearchNode,

View File

@@ -65,6 +65,18 @@ export async function dispatchDatasetSearch(
} }
if (!userChatInput) { if (!userChatInput) {
return {
quoteQA: [],
[DispatchNodeResponseKeyEnum.nodeResponse]: {
totalPoints: 0,
query: '',
limit,
searchMode
},
nodeDispatchUsages: [],
[DispatchNodeResponseKeyEnum.toolResponses]: []
};
return Promise.reject(i18nT('common:core.chat.error.User input empty')); return Promise.reject(i18nT('common:core.chat.error.User input empty'));
} }

View File

@@ -11,11 +11,14 @@ export const useWidthVariable = <T = any>({
}) => { }) => {
const value = useMemo(() => { const value = useMemo(() => {
// 根据 width 计算,找到第一个大于 width 的值 // 根据 width 计算,找到第一个大于 width 的值
const index = widthList.findLastIndex((item) => width > item); const reversedWidthList = [...widthList].reverse();
const reversedList = [...list].reverse();
const index = reversedWidthList.findIndex((item) => width > item);
if (index === -1) { if (index === -1) {
return list[0]; return reversedList[0];
} }
return list[index]; return reversedList[index];
}, [list, width, widthList]); }, [list, width, widthList]);
return value; return value;

View File

@@ -30,6 +30,7 @@ const ResponseTags = ({
const { t } = useTranslation(); const { t } = useTranslation();
const quoteListRef = React.useRef<HTMLDivElement>(null); const quoteListRef = React.useRef<HTMLDivElement>(null);
const dataId = historyItem.dataId; const dataId = historyItem.dataId;
const { const {
totalQuoteList: quoteList = [], totalQuoteList: quoteList = [],
llmModuleAccount = 0, llmModuleAccount = 0,

View File

@@ -6,11 +6,15 @@ import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
const isLLMNode = (item: ChatHistoryItemResType) => const isLLMNode = (item: ChatHistoryItemResType) =>
item.moduleType === FlowNodeTypeEnum.chatNode || item.moduleType === FlowNodeTypeEnum.tools; item.moduleType === FlowNodeTypeEnum.chatNode || item.moduleType === FlowNodeTypeEnum.tools;
export function transformPreviewHistories(histories: ChatItemType[]): ChatItemType[] { export function transformPreviewHistories(
histories: ChatItemType[],
responseDetail: boolean
): ChatItemType[] {
return histories.map((item) => { return histories.map((item) => {
return { return {
...addStatisticalDataToHistoryItem(item), ...addStatisticalDataToHistoryItem(item),
responseData: undefined responseData: undefined,
...(responseDetail ? {} : { totalQuoteList: undefined })
}; };
}); });
} }
@@ -18,6 +22,7 @@ export function transformPreviewHistories(histories: ChatItemType[]): ChatItemTy
export function addStatisticalDataToHistoryItem(historyItem: ChatItemType) { export function addStatisticalDataToHistoryItem(historyItem: ChatItemType) {
if (historyItem.obj !== ChatRoleEnum.AI) return historyItem; if (historyItem.obj !== ChatRoleEnum.AI) return historyItem;
if (historyItem.totalQuoteList !== undefined) return historyItem; if (historyItem.totalQuoteList !== undefined) return historyItem;
if (!historyItem.responseData) return historyItem;
// Flat children // Flat children
const flatResData: ChatHistoryItemResType[] = const flatResData: ChatHistoryItemResType[] =

View File

@@ -82,11 +82,16 @@ async function handler(
limit: pageSize limit: pageSize
}); });
const responseDetail = !shareChat || shareChat.responseDetail;
// Remove important information // Remove important information
if (shareChat && app.type !== AppTypeEnum.plugin) { if (shareChat && app.type !== AppTypeEnum.plugin) {
histories.forEach((item) => { histories.forEach((item) => {
if (item.obj === ChatRoleEnum.AI) { if (item.obj === ChatRoleEnum.AI) {
item.responseData = filterPublicNodeResponseData({ flowResponses: item.responseData }); item.responseData = filterPublicNodeResponseData({
flowResponses: item.responseData,
responseDetail
});
if (shareChat.showNodeStatus === false) { if (shareChat.showNodeStatus === false) {
item.value = item.value.filter((v) => v.type !== ChatItemValueTypeEnum.tool); item.value = item.value.filter((v) => v.type !== ChatItemValueTypeEnum.tool);
@@ -96,7 +101,7 @@ async function handler(
} }
return { return {
list: isPlugin ? histories : transformPreviewHistories(histories), list: isPlugin ? histories : transformPreviewHistories(histories, responseDetail),
total total
}; };
} }

View File

@@ -11,6 +11,7 @@ import { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type';
import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat'; import { OutLinkChatAuthProps } from '@fastgpt/global/support/permission/chat';
import { authApp } from '@fastgpt/service/support/permission/app/auth'; import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils'; import { filterPublicNodeResponseData } from '@fastgpt/global/core/chat/utils';
import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';
export type getResDataQuery = OutLinkChatAuthProps & { export type getResDataQuery = OutLinkChatAuthProps & {
chatId?: string; chatId?: string;
@@ -26,15 +27,16 @@ async function handler(
req: ApiRequestProps<getResDataBody, getResDataQuery>, req: ApiRequestProps<getResDataBody, getResDataQuery>,
res: ApiResponseType<any> res: ApiResponseType<any>
): Promise<getResDataResponse> { ): Promise<getResDataResponse> {
const { appId, chatId, dataId } = req.query; const { appId, chatId, dataId, shareId } = req.query;
if (!appId || !chatId || !dataId) { if (!appId || !chatId || !dataId) {
return {}; return {};
} }
// 1. Un login api: share chat, team chat // 1. Un login api: share chat, team chat
// 2. Login api: account chat, chat log // 2. Login api: account chat, chat log
const authData = await (() => {
try { try {
await authChatCrud({ return authChatCrud({
req, req,
authToken: true, authToken: true,
authApiKey: true, authApiKey: true,
@@ -42,7 +44,7 @@ async function handler(
per: ReadPermissionVal per: ReadPermissionVal
}); });
} catch (error) { } catch (error) {
await authApp({ return authApp({
req, req,
authToken: true, authToken: true,
authApiKey: true, authApiKey: true,
@@ -50,20 +52,32 @@ async function handler(
per: ManagePermissionVal per: ManagePermissionVal
}); });
} }
})();
const chatData = await MongoChatItem.findOne( const [chatData] = await Promise.all([
MongoChatItem.findOne(
{ {
appId, appId,
chatId, chatId,
dataId dataId
}, },
'obj responseData' 'obj responseData'
).lean(); ).lean(),
shareId ? MongoOutLink.findOne({ shareId }).lean() : Promise.resolve(null)
]);
if (chatData?.obj === ChatRoleEnum.AI) { if (chatData?.obj !== ChatRoleEnum.AI) {
const data = chatData.responseData || {}; return {};
return req.query.shareId ? filterPublicNodeResponseData(data) : data; }
} else return {};
const flowResponses = chatData.responseData ?? {};
return req.query.shareId
? filterPublicNodeResponseData({
// @ts-ignore
responseDetail: authData.responseDetail,
flowResponses: chatData.responseData
})
: flowResponses;
} }
export default NextAPI(handler); export default NextAPI(handler);

View File

@@ -363,7 +363,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
/* select fe response field */ /* select fe response field */
const feResponseData = canWrite const feResponseData = canWrite
? flowResponses ? flowResponses
: filterPublicNodeResponseData({ flowResponses }); : filterPublicNodeResponseData({ flowResponses, responseDetail });
if (stream) { if (stream) {
workflowResponseWrite({ workflowResponseWrite({
@@ -380,13 +380,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
}); });
if (detail) { if (detail) {
if (responseDetail || isPlugin) {
workflowResponseWrite({ workflowResponseWrite({
event: SseResponseEventEnum.flowResponses, event: SseResponseEventEnum.flowResponses,
data: feResponseData data: feResponseData
}); });
} }
}
res.end(); res.end();
} else { } else {

View File

@@ -42,18 +42,19 @@ export async function authChatCrud({
chat?: ChatSchema; chat?: ChatSchema;
isOutLink: boolean; isOutLink: boolean;
uid?: string; uid?: string;
responseDetail: boolean;
}> { }> {
const isOutLink = Boolean((shareId || spaceTeamId) && outLinkUid); const isOutLink = Boolean((shareId || spaceTeamId) && outLinkUid);
if (!chatId) return { isOutLink, uid: outLinkUid }; if (!chatId) return { isOutLink, uid: outLinkUid, responseDetail: true };
const chat = await MongoChat.findOne({ appId, chatId }).lean(); const chat = await MongoChat.findOne({ appId, chatId }).lean();
const { uid } = await (async () => { const { uid, responseDetail } = await (async () => {
// outLink Auth // outLink Auth
if (shareId && outLinkUid) { if (shareId && outLinkUid) {
const { uid } = await authOutLink({ shareId, outLinkUid }); const { uid, shareChat } = await authOutLink({ shareId, outLinkUid });
if (!chat || (chat.shareId === shareId && chat.outLinkUid === uid)) { if (!chat || (chat.shareId === shareId && chat.outLinkUid === uid)) {
return { uid }; return { uid, responseDetail: shareChat.responseDetail };
} }
return Promise.reject(ChatErrEnum.unAuthChat); return Promise.reject(ChatErrEnum.unAuthChat);
} }
@@ -62,12 +63,12 @@ export async function authChatCrud({
const { uid } = await authTeamSpaceToken({ teamId: spaceTeamId, teamToken }); const { uid } = await authTeamSpaceToken({ teamId: spaceTeamId, teamToken });
addLog.debug('Auth team token', { uid, spaceTeamId, teamToken, chatUid: chat?.outLinkUid }); addLog.debug('Auth team token', { uid, spaceTeamId, teamToken, chatUid: chat?.outLinkUid });
if (!chat || (String(chat.teamId) === String(spaceTeamId) && chat.outLinkUid === uid)) { if (!chat || (String(chat.teamId) === String(spaceTeamId) && chat.outLinkUid === uid)) {
return { uid }; return { uid, responseDetail: true };
} }
return Promise.reject(ChatErrEnum.unAuthChat); return Promise.reject(ChatErrEnum.unAuthChat);
} }
if (!chat) return { id: outLinkUid }; if (!chat) return { id: outLinkUid, responseDetail: true };
// auth req // auth req
const { teamId, tmbId, permission } = await authApp({ const { teamId, tmbId, permission } = await authApp({
@@ -80,18 +81,19 @@ export async function authChatCrud({
if (String(teamId) !== String(chat.teamId)) return Promise.reject(ChatErrEnum.unAuthChat); if (String(teamId) !== String(chat.teamId)) return Promise.reject(ChatErrEnum.unAuthChat);
if (permission.hasManagePer) return { uid: outLinkUid }; if (permission.hasManagePer) return { uid: outLinkUid, responseDetail: true };
if (String(tmbId) === String(chat.tmbId)) return { uid: outLinkUid }; if (String(tmbId) === String(chat.tmbId)) return { uid: outLinkUid, responseDetail: true };
return Promise.reject(ChatErrEnum.unAuthChat); return Promise.reject(ChatErrEnum.unAuthChat);
})(); })();
if (!chat) return { isOutLink, uid }; if (!chat) return { isOutLink, uid, responseDetail };
return { return {
chat, chat,
isOutLink, isOutLink,
uid uid,
responseDetail
}; };
} }