Fix share page feedback auth (#3284)

* fix: share page mark auth

* perf: lang check

* perf: load share
This commit is contained in:
Archer
2024-12-01 21:09:13 +08:00
committed by GitHub
parent d0e8c9c62e
commit 1cef206c13
7 changed files with 39 additions and 76 deletions

View File

@@ -1,11 +1,9 @@
export type UpdateChatFeedbackProps = { import { OutLinkChatAuthProps } from '../../support/permission/chat';
export type UpdateChatFeedbackProps = OutLinkChatAuthProps & {
appId: string; appId: string;
chatId: string; chatId: string;
dataId: string; dataId: string;
shareId?: string;
teamId?: string;
teamToken?: string;
outLinkUid?: string;
userBadFeedback?: string; userBadFeedback?: string;
userGoodFeedback?: string; userGoodFeedback?: string;
}; };

View File

@@ -4,30 +4,25 @@ import MyModal from '@fastgpt/web/components/common/MyModal';
import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { useRequest } from '@fastgpt/web/hooks/useRequest';
import { useTranslation } from 'next-i18next'; import { useTranslation } from 'next-i18next';
import { updateChatUserFeedback } from '@/web/core/chat/api'; import { updateChatUserFeedback } from '@/web/core/chat/api';
import { useContextSelector } from 'use-context-selector';
import { ChatBoxContext } from '../Provider';
const FeedbackModal = ({ const FeedbackModal = ({
appId, appId,
chatId, chatId,
dataId, dataId,
teamId,
teamToken,
shareId,
outLinkUid,
onSuccess, onSuccess,
onClose onClose
}: { }: {
appId: string; appId: string;
chatId: string; chatId: string;
dataId: string; dataId: string;
shareId?: string;
teamId?: string;
teamToken?: string;
outLinkUid?: string;
onSuccess: (e: string) => void; onSuccess: (e: string) => void;
onClose: () => void; onClose: () => void;
}) => { }) => {
const ref = useRef<HTMLTextAreaElement>(null); const ref = useRef<HTMLTextAreaElement>(null);
const { t } = useTranslation(); const { t } = useTranslation();
const outLinkAuthData = useContextSelector(ChatBoxContext, (v) => v.outLinkAuthData);
const { mutate, isLoading } = useRequest({ const { mutate, isLoading } = useRequest({
mutationFn: async () => { mutationFn: async () => {
@@ -36,11 +31,8 @@ const FeedbackModal = ({
appId, appId,
chatId, chatId,
dataId, dataId,
shareId, userBadFeedback: val,
teamId, ...outLinkAuthData
teamToken,
outLinkUid,
userBadFeedback: val
}); });
}, },
onSuccess() { onSuccess() {

View File

@@ -137,10 +137,6 @@ const ChatBox = ({
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords); const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
const setChatRecords = useContextSelector(ChatRecordContext, (v) => v.setChatRecords); const setChatRecords = useContextSelector(ChatRecordContext, (v) => v.setChatRecords);
const isChatRecordsLoaded = useContextSelector(ChatRecordContext, (v) => v.isChatRecordsLoaded); const isChatRecordsLoaded = useContextSelector(ChatRecordContext, (v) => v.isChatRecordsLoaded);
const setIsChatRecordsLoaded = useContextSelector(
ChatRecordContext,
(v) => v.setIsChatRecordsLoaded
);
const ScrollData = useContextSelector(ChatRecordContext, (v) => v.ScrollData); const ScrollData = useContextSelector(ChatRecordContext, (v) => v.ScrollData);
const appId = useContextSelector(ChatBoxContext, (v) => v.appId); const appId = useContextSelector(ChatBoxContext, (v) => v.appId);
@@ -687,12 +683,9 @@ const ChatBox = ({
updateChatUserFeedback({ updateChatUserFeedback({
appId, appId,
chatId, chatId,
teamId,
teamToken,
dataId: chat.dataId, dataId: chat.dataId,
shareId, userGoodFeedback: isGoodFeedback ? undefined : 'yes',
outLinkUid, ...outLinkAuthData
userGoodFeedback: isGoodFeedback ? undefined : 'yes'
}); });
} catch (error) {} } catch (error) {}
}; };
@@ -708,11 +701,10 @@ const ChatBox = ({
); );
updateChatUserFeedback({ updateChatUserFeedback({
appId, appId,
teamId,
teamToken,
chatId, chatId,
dataId: chat.dataId, dataId: chat.dataId,
userGoodFeedback: undefined userGoodFeedback: undefined,
...outLinkAuthData
}); });
}; };
}); });
@@ -737,10 +729,7 @@ const ChatBox = ({
appId, appId,
chatId, chatId,
dataId: chat.dataId, dataId: chat.dataId,
shareId, ...outLinkAuthData
teamId,
teamToken,
outLinkUid
}); });
} catch (error) {} } catch (error) {}
}; };
@@ -864,7 +853,6 @@ const ChatBox = ({
abortRequest(); abortRequest();
setChatRecords([]); setChatRecords([]);
setIsChatRecordsLoaded(false);
setValue('chatStarted', false); setValue('chatStarted', false);
}, },
scrollToBottom(behavior = 'auto') { scrollToBottom(behavior = 'auto') {
@@ -1040,12 +1028,8 @@ const ChatBox = ({
{!!feedbackId && chatId && ( {!!feedbackId && chatId && (
<FeedbackModal <FeedbackModal
appId={appId} appId={appId}
teamId={teamId}
teamToken={teamToken}
chatId={chatId} chatId={chatId}
dataId={feedbackId} dataId={feedbackId}
shareId={shareId}
outLinkUid={outLinkUid}
onClose={() => setFeedbackId(undefined)} onClose={() => setFeedbackId(undefined)}
onSuccess={(content: string) => { onSuccess={(content: string) => {
setChatRecords((state) => setChatRecords((state) =>

View File

@@ -50,8 +50,8 @@ const SelectUsingWayModal = ({ share, onClose }: { share: OutLinkSchema; onClose
defaultValues: { defaultValues: {
usingWay: UsingWayEnum.link, usingWay: UsingWayEnum.link,
showHistory: true, showHistory: true,
scriptIconCanDrag: true, scriptIconCanDrag: false,
scriptDefaultOpen: true, scriptDefaultOpen: false,
scriptOpenIcon: scriptOpenIcon:
'data:image/svg+xml;base64,PHN2ZyB0PSIxNjkwNTMyNzg1NjY0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQxMzIiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48cGF0aCBkPSJNNTEyIDMyQzI0Ny4wNCAzMiAzMiAyMjQgMzIgNDY0QTQxMC4yNCA0MTAuMjQgMCAwIDAgMTcyLjQ4IDc2OEwxNjAgOTY1LjEyYTI1LjI4IDI1LjI4IDAgMCAwIDM5LjA0IDIyLjRsMTY4LTExMkE1MjguNjQgNTI4LjY0IDAgMCAwIDUxMiA4OTZjMjY0Ljk2IDAgNDgwLTE5MiA0ODAtNDMyUzc3Ni45NiAzMiA1MTIgMzJ6IG0yNDQuOCA0MTZsLTM2MS42IDMwMS43NmExMi40OCAxMi40OCAwIDAgMS0xOS44NC0xMi40OGw1OS4yLTIzMy45MmgtMTYwYTEyLjQ4IDEyLjQ4IDAgMCAxLTcuMzYtMjMuMzZsMzYxLjYtMzAxLjc2YTEyLjQ4IDEyLjQ4IDAgMCAxIDE5Ljg0IDEyLjQ4bC01OS4yIDIzMy45MmgxNjBhMTIuNDggMTIuNDggMCAwIDEgOCAyMi4wOHoiIGZpbGw9IiM0ZTgzZmQiIHAtaWQ9IjQxMzMiPjwvcGF0aD48L3N2Zz4=', 'data:image/svg+xml;base64,PHN2ZyB0PSIxNjkwNTMyNzg1NjY0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQxMzIiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48cGF0aCBkPSJNNTEyIDMyQzI0Ny4wNCAzMiAzMiAyMjQgMzIgNDY0QTQxMC4yNCA0MTAuMjQgMCAwIDAgMTcyLjQ4IDc2OEwxNjAgOTY1LjEyYTI1LjI4IDI1LjI4IDAgMCAwIDM5LjA0IDIyLjRsMTY4LTExMkE1MjguNjQgNTI4LjY0IDAgMCAwIDUxMiA4OTZjMjY0Ljk2IDAgNDgwLTE5MiA0ODAtNDMyUzc3Ni45NiAzMiA1MTIgMzJ6IG0yNDQuOCA0MTZsLTM2MS42IDMwMS43NmExMi40OCAxMi40OCAwIDAgMS0xOS44NC0xMi40OGw1OS4yLTIzMy45MmgtMTYwYTEyLjQ4IDEyLjQ4IDAgMCAxLTcuMzYtMjMuMzZsMzYxLjYtMzAxLjc2YTEyLjQ4IDEyLjQ4IDAgMCAxIDE5Ljg0IDEyLjQ4bC01OS4yIDIzMy45MmgxNjBhMTIuNDggMTIuNDggMCAwIDEgOCAyMi4wOHoiIGZpbGw9IiM0ZTgzZmQiIHAtaWQ9IjQxMzMiPjwvcGF0aD48L3N2Zz4=',
scriptCloseIcon: scriptCloseIcon:
@@ -96,6 +96,7 @@ const SelectUsingWayModal = ({ share, onClose }: { share: OutLinkSchema; onClose
[UsingWayEnum.script]: { [UsingWayEnum.script]: {
blockTitle: t('common:core.app.outLink.Script block title'), blockTitle: t('common:core.app.outLink.Script block title'),
code: `<script code: `<script
type="text/javascript"
src="${baseUrl}/js/iframe.js" src="${baseUrl}/js/iframe.js"
id="chatbot-iframe" id="chatbot-iframe"
data-bot-src="${linkUrl}" data-bot-src="${linkUrl}"
@@ -104,10 +105,7 @@ const SelectUsingWayModal = ({ share, onClose }: { share: OutLinkSchema; onClose
data-open-icon="${getValues('scriptOpenIcon')}" data-open-icon="${getValues('scriptOpenIcon')}"
data-close-icon="${getValues('scriptCloseIcon')}" data-close-icon="${getValues('scriptCloseIcon')}"
defer defer
></script> ></script>`
<script>
console.log("Chat box loaded")
</script>`
} }
}; };

View File

@@ -84,10 +84,11 @@ const OutLink = (props: Props) => {
const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords); const chatRecords = useContextSelector(ChatRecordContext, (v) => v.chatRecords);
const totalRecordsCount = useContextSelector(ChatRecordContext, (v) => v.totalRecordsCount); const totalRecordsCount = useContextSelector(ChatRecordContext, (v) => v.totalRecordsCount);
const isChatRecordsLoaded = useContextSelector(ChatRecordContext, (v) => v.isChatRecordsLoaded);
const initSign = useRef(false); const initSign = useRef(false);
const [chatData, setChatData] = useState<InitChatResponse>(defaultChatData); const [chatData, setChatData] = useState<InitChatResponse>(defaultChatData);
const { loading: isLoading } = useRequest2( const { data, loading: isLoading } = useRequest2(
async () => { async () => {
const shareId = outLinkAuthData.shareId; const shareId = outLinkAuthData.shareId;
const outLinkUid = outLinkAuthData.outLinkUid; const outLinkUid = outLinkAuthData.outLinkUid;
@@ -104,19 +105,12 @@ const OutLink = (props: Props) => {
resetVariables({ resetVariables({
variables: res.variables variables: res.variables
}); });
return res;
}, },
{ {
manual: false, manual: false,
refreshDeps: [shareId, outLinkAuthData, chatId], refreshDeps: [shareId, outLinkAuthData, chatId],
onSuccess() {
// send init message
if (!initSign.current) {
initSign.current = true;
if (window !== top) {
window.top?.postMessage({ type: 'shareChatReady' }, '*');
}
}
},
onError(e: any) { onError(e: any) {
if (chatId) { if (chatId) {
onChangeChatId(''); onChangeChatId('');
@@ -127,6 +121,14 @@ const OutLink = (props: Props) => {
} }
} }
); );
useEffect(() => {
if (initSign.current === false && data && isChatRecordsLoaded) {
initSign.current = true;
if (window !== top) {
window.top?.postMessage({ type: 'shareChatReady' }, '*');
}
}
}, [data, isChatRecordsLoaded]);
const startChat = useCallback( const startChat = useCallback(
async ({ async ({
@@ -295,8 +297,6 @@ const Render = (props: Props) => {
const { localUId, loaded } = useShareChatStore(); const { localUId, loaded } = useShareChatStore();
const { source, chatId, setSource, setAppId, setOutLinkAuthData } = useChatStore(); const { source, chatId, setSource, setAppId, setOutLinkAuthData } = useChatStore();
const [isLoaded, setIsLoaded] = useState(false);
const chatHistoryProviderParams = useMemo(() => { const chatHistoryProviderParams = useMemo(() => {
return { shareId, outLinkUid: authToken || customUid || localUId }; return { shareId, outLinkUid: authToken || customUid || localUId };
}, [authToken, customUid, localUId, shareId]); }, [authToken, customUid, localUId, shareId]);
@@ -311,11 +311,8 @@ const Render = (props: Props) => {
}, [appId, chatHistoryProviderParams.outLinkUid, chatId, shareId]); }, [appId, chatHistoryProviderParams.outLinkUid, chatId, shareId]);
useMount(() => { useMount(() => {
setIsLoaded(true);
setSource('share'); setSource('share');
}); });
const systemLoaded = isLoaded && loaded && chatHistoryProviderParams.outLinkUid;
// Set outLinkAuthData // Set outLinkAuthData
useEffect(() => { useEffect(() => {

View File

@@ -22,5 +22,6 @@ export const langMap = {
}; };
export const serviceSideProps = (content: any, ns: I18nNsType = []) => { export const serviceSideProps = (content: any, ns: I18nNsType = []) => {
return serverSideTranslations(content.locale, ['common', 'error', ...ns], null, content.locales); const lang = content.req?.cookies?.NEXT_LOCALE || content.locale;
return serverSideTranslations(lang, ['common', 'error', ...ns], null, content.locales);
}; };

View File

@@ -2,7 +2,7 @@ import { getPaginationRecordsBody } from '@/pages/api/core/chat/getPaginationRec
import { ChatSiteItemType } from '@fastgpt/global/core/chat/type'; import { ChatSiteItemType } from '@fastgpt/global/core/chat/type';
import { PaginationResponse } from '@fastgpt/web/common/fetch/type'; import { PaginationResponse } from '@fastgpt/web/common/fetch/type';
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination'; import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
import React, { ReactNode, useMemo, useState } from 'react'; import React, { ReactNode, useEffect, useMemo, useState } from 'react';
import { createContext, useContextSelector } from 'use-context-selector'; import { createContext, useContextSelector } from 'use-context-selector';
import { ChatItemContext } from './chatItemContext'; import { ChatItemContext } from './chatItemContext';
import { getChatRecords } from '../api'; import { getChatRecords } from '../api';
@@ -14,7 +14,6 @@ type ChatRecordContextType = {
chatRecords: ChatSiteItemType[]; chatRecords: ChatSiteItemType[];
setChatRecords: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>; setChatRecords: React.Dispatch<React.SetStateAction<ChatSiteItemType[]>>;
isChatRecordsLoaded: boolean; isChatRecordsLoaded: boolean;
setIsChatRecordsLoaded: React.Dispatch<React.SetStateAction<boolean>>;
totalRecordsCount: number; totalRecordsCount: number;
ScrollData: ({ ScrollData: ({
children, children,
@@ -31,9 +30,7 @@ export const ChatRecordContext = createContext<ChatRecordContextType>({
throw new Error('Function not implemented.'); throw new Error('Function not implemented.');
}, },
isChatRecordsLoaded: false, isChatRecordsLoaded: false,
setIsChatRecordsLoaded: function (value: React.SetStateAction<boolean>): void {
throw new Error('Function not implemented.');
},
totalRecordsCount: 0, totalRecordsCount: 0,
ScrollData: function ({ ScrollData: function ({
children, children,
@@ -59,6 +56,10 @@ const ChatRecordContextProvider = ({
const ChatBoxRef = useContextSelector(ChatItemContext, (v) => v.ChatBoxRef); const ChatBoxRef = useContextSelector(ChatItemContext, (v) => v.ChatBoxRef);
const [isChatRecordsLoaded, setIsChatRecordsLoaded] = useState(false); const [isChatRecordsLoaded, setIsChatRecordsLoaded] = useState(false);
useEffect(() => {
setIsChatRecordsLoaded(false);
}, [params]);
const { const {
data: chatRecords, data: chatRecords,
ScrollData, ScrollData,
@@ -104,17 +105,9 @@ const ChatRecordContextProvider = ({
setChatRecords, setChatRecords,
totalRecordsCount, totalRecordsCount,
ScrollData, ScrollData,
isChatRecordsLoaded, isChatRecordsLoaded
setIsChatRecordsLoaded
}; };
}, [ }, [ScrollData, chatRecords, setChatRecords, totalRecordsCount, isChatRecordsLoaded]);
ScrollData,
chatRecords,
setChatRecords,
totalRecordsCount,
isChatRecordsLoaded,
setIsChatRecordsLoaded
]);
return <ChatRecordContext.Provider value={contextValue}>{children}</ChatRecordContext.Provider>; return <ChatRecordContext.Provider value={contextValue}>{children}</ChatRecordContext.Provider>;
}; };