增加用户反馈功能
This commit is contained in:
parent
f6258c970b
commit
8094d5e128
@ -1,33 +1,26 @@
|
||||
import type { FC } from 'react'
|
||||
import {
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useAsyncEffect } from 'ahooks'
|
||||
import { useThemeContext } from '@/app/components/chat/embedded-chatbot/theme/theme-context'
|
||||
import {
|
||||
ChatWithHistoryContext,
|
||||
useChatWithHistoryContext,
|
||||
} from './context'
|
||||
import { useChatWithHistory } from './hooks'
|
||||
import Sidebar from './sidebar'
|
||||
import HeaderInMobile from './header-in-mobile'
|
||||
import ConfigPanel from './config-panel'
|
||||
import ChatWrapper from './chat-wrapper'
|
||||
import type { InstalledApp } from '@/models/explore'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import AppUnavailable from '@/app/components/base/app-unavailable'
|
||||
import type { FC } from "react";
|
||||
import "antd/dist/reset.css"; // 引入 antd 的样式
|
||||
import { useEffect, useState } from "react";
|
||||
import { useAsyncEffect } from "ahooks";
|
||||
import { useThemeContext } from "@/app/components/chat/embedded-chatbot/theme/theme-context";
|
||||
import { ChatWithHistoryContext, useChatWithHistoryContext } from "./context";
|
||||
import { useChatWithHistory } from "./hooks";
|
||||
import Sidebar from "./sidebar";
|
||||
import HeaderInMobile from "./header-in-mobile";
|
||||
import ConfigPanel from "./config-panel";
|
||||
import ChatWrapper from "./chat-wrapper";
|
||||
import type { InstalledApp } from "@/models/explore";
|
||||
import Loading from "@/app/components/base/loading";
|
||||
import useBreakpoints, { MediaType } from "@/hooks/use-breakpoints";
|
||||
import { useRouter } from "next/navigation";
|
||||
import AppUnavailable from "@/app/components/base/app-unavailable";
|
||||
|
||||
type ChatWithHistoryProps = {
|
||||
className?: string
|
||||
userStr?: string
|
||||
}
|
||||
const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
||||
className,
|
||||
userStr,
|
||||
}) => {
|
||||
className?: string;
|
||||
userStr?: string;
|
||||
};
|
||||
|
||||
const ChatWithHistory: FC<ChatWithHistoryProps> = ({ className, userStr }) => {
|
||||
const {
|
||||
appInfoError,
|
||||
appData,
|
||||
@ -38,82 +31,78 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
||||
chatShouldReloadKey,
|
||||
isMobile,
|
||||
themeBuilder,
|
||||
} = useChatWithHistoryContext()
|
||||
} = useChatWithHistoryContext();
|
||||
|
||||
const chatReady = (!showConfigPanelBeforeChat || !!appPrevChatTree.length)
|
||||
const customConfig = appData?.custom_config
|
||||
const site = appData?.site
|
||||
const chatReady = !showConfigPanelBeforeChat || !!appPrevChatTree.length;
|
||||
const customConfig = appData?.custom_config;
|
||||
const site = appData?.site;
|
||||
|
||||
useEffect(() => {
|
||||
themeBuilder?.buildTheme(site?.chat_color_theme, site?.chat_color_theme_inverted)
|
||||
themeBuilder?.buildTheme(
|
||||
site?.chat_color_theme,
|
||||
site?.chat_color_theme_inverted
|
||||
);
|
||||
if (site) {
|
||||
if (customConfig)
|
||||
document.title = `${site.title}`
|
||||
else
|
||||
document.title = `${site.title} - Powered by Dify`
|
||||
if (customConfig) document.title = `${site.title}`;
|
||||
else document.title = `${site.title} - Powered by Dify`;
|
||||
}
|
||||
}, [site, customConfig, themeBuilder])
|
||||
}, [site, customConfig, themeBuilder]);
|
||||
|
||||
if (appInfoLoading) {
|
||||
return (
|
||||
<Loading type='app' />
|
||||
)
|
||||
return <Loading type="app" />;
|
||||
}
|
||||
|
||||
if (appInfoError) {
|
||||
return (
|
||||
<AppUnavailable />
|
||||
)
|
||||
return <AppUnavailable />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`h-full flex bg-white ${className} ${isMobile && 'flex-col'}`}>
|
||||
{
|
||||
!isMobile && (
|
||||
<Sidebar userStr={userStr} />
|
||||
)
|
||||
}
|
||||
{
|
||||
isMobile && (
|
||||
<HeaderInMobile />
|
||||
)
|
||||
}
|
||||
<div className={`grow overflow-hidden ${showConfigPanelBeforeChat && !appPrevChatTree.length && 'flex items-center justify-center'}`}>
|
||||
{
|
||||
showConfigPanelBeforeChat && !appChatListDataLoading && !appPrevChatTree.length && (
|
||||
<div className={`flex w-full items-center justify-center h-full ${isMobile && 'px-4'}`}>
|
||||
<div
|
||||
className={`h-full flex bg-white ${className} ${isMobile && "flex-col"}`}
|
||||
>
|
||||
{!isMobile && <Sidebar userStr={userStr} />}
|
||||
{isMobile && <HeaderInMobile />}
|
||||
<div
|
||||
className={`grow overflow-hidden ${
|
||||
showConfigPanelBeforeChat &&
|
||||
!appPrevChatTree.length &&
|
||||
"flex items-center justify-center"
|
||||
}`}
|
||||
>
|
||||
{showConfigPanelBeforeChat &&
|
||||
!appChatListDataLoading &&
|
||||
!appPrevChatTree.length && (
|
||||
<div
|
||||
className={`flex w-full items-center justify-center h-full ${
|
||||
isMobile && "px-4"
|
||||
}`}
|
||||
>
|
||||
<ConfigPanel />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
appChatListDataLoading && chatReady && (
|
||||
<Loading type='app' />
|
||||
)
|
||||
}
|
||||
{
|
||||
chatReady && !appChatListDataLoading && (
|
||||
<ChatWrapper key={chatShouldReloadKey} />
|
||||
)
|
||||
}
|
||||
)}
|
||||
{appChatListDataLoading && chatReady && <Loading type="app" />}
|
||||
{chatReady && !appChatListDataLoading && (
|
||||
<ChatWrapper key={chatShouldReloadKey} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export type ChatWithHistoryWrapProps = {
|
||||
installedAppInfo?: InstalledApp
|
||||
className?: string
|
||||
userStr?: string
|
||||
}
|
||||
installedAppInfo?: InstalledApp;
|
||||
className?: string;
|
||||
userStr?: string;
|
||||
};
|
||||
|
||||
const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
||||
installedAppInfo,
|
||||
className,
|
||||
userStr,
|
||||
}) => {
|
||||
const media = useBreakpoints()
|
||||
const isMobile = media === MediaType.mobile
|
||||
const themeBuilder = useThemeContext()
|
||||
const media = useBreakpoints();
|
||||
const isMobile = media === MediaType.mobile;
|
||||
const themeBuilder = useThemeContext();
|
||||
|
||||
const {
|
||||
appInfoError,
|
||||
@ -146,93 +135,99 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
||||
appId,
|
||||
handleFeedback,
|
||||
currentChatInstanceRef,
|
||||
} = useChatWithHistory(installedAppInfo)
|
||||
feedbackModal,
|
||||
} = useChatWithHistory(installedAppInfo);
|
||||
|
||||
return (
|
||||
<ChatWithHistoryContext.Provider value={{
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appData,
|
||||
appParams,
|
||||
appMeta,
|
||||
appChatListDataLoading,
|
||||
currentConversationId,
|
||||
currentConversationItem,
|
||||
appPrevChatTree,
|
||||
pinnedConversationList,
|
||||
conversationList,
|
||||
showConfigPanelBeforeChat,
|
||||
newConversationInputs,
|
||||
newConversationInputsRef,
|
||||
handleNewConversationInputsChange,
|
||||
inputsForms,
|
||||
handleNewConversation,
|
||||
handleStartChat,
|
||||
handleChangeConversation,
|
||||
handlePinConversation,
|
||||
handleUnpinConversation,
|
||||
handleDeleteConversation,
|
||||
conversationRenaming,
|
||||
handleRenameConversation,
|
||||
handleNewConversationCompleted,
|
||||
chatShouldReloadKey,
|
||||
isMobile,
|
||||
isInstalledApp,
|
||||
appId,
|
||||
handleFeedback,
|
||||
currentChatInstanceRef,
|
||||
themeBuilder,
|
||||
}}>
|
||||
<ChatWithHistoryContext.Provider
|
||||
value={{
|
||||
appInfoError,
|
||||
appInfoLoading,
|
||||
appData,
|
||||
appParams,
|
||||
appMeta,
|
||||
appChatListDataLoading,
|
||||
currentConversationId,
|
||||
currentConversationItem,
|
||||
appPrevChatTree,
|
||||
pinnedConversationList,
|
||||
conversationList,
|
||||
showConfigPanelBeforeChat,
|
||||
newConversationInputs,
|
||||
newConversationInputsRef,
|
||||
handleNewConversationInputsChange,
|
||||
inputsForms,
|
||||
handleNewConversation,
|
||||
handleStartChat,
|
||||
handleChangeConversation,
|
||||
handlePinConversation,
|
||||
handleUnpinConversation,
|
||||
handleDeleteConversation,
|
||||
conversationRenaming,
|
||||
handleRenameConversation,
|
||||
handleNewConversationCompleted,
|
||||
chatShouldReloadKey,
|
||||
isMobile,
|
||||
isInstalledApp,
|
||||
appId,
|
||||
handleFeedback,
|
||||
currentChatInstanceRef,
|
||||
themeBuilder,
|
||||
}}
|
||||
>
|
||||
<ChatWithHistory className={className} userStr={userStr} />
|
||||
{feedbackModal} {/* 确保 feedbackModal 正确渲染 */}
|
||||
</ChatWithHistoryContext.Provider>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const ChatWithHistoryWrapWithCheckToken: FC<ChatWithHistoryWrapProps> = ({
|
||||
installedAppInfo,
|
||||
className,
|
||||
}) => {
|
||||
const [initialized, setInitialized] = useState(false)
|
||||
const [appUnavailable, setAppUnavailable] = useState<boolean>(false)
|
||||
const [resCode, setResCode] = useState<number>(200)
|
||||
const router = useRouter()
|
||||
const [userName, setUserName] = useState('')
|
||||
const [nickName, setNickName] = useState('')
|
||||
const [initialized, setInitialized] = useState(false);
|
||||
const [appUnavailable, setAppUnavailable] = useState<boolean>(false);
|
||||
const [resCode, setResCode] = useState<number>(200);
|
||||
const router = useRouter();
|
||||
const [userName, setUserName] = useState("");
|
||||
const [nickName, setNickName] = useState("");
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
if (!initialized) {
|
||||
if (!installedAppInfo) {
|
||||
const accessToken = localStorage.getItem('token')
|
||||
const accessToken = localStorage.getItem("token");
|
||||
if (!accessToken) {
|
||||
router.replace('/login')
|
||||
router.replace("/login");
|
||||
} else {
|
||||
fetch(`${process.env.NEXT_PUBLIC_BASE_API_URL}/getInfo`, {
|
||||
method: 'GET',
|
||||
method: "GET",
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
}).then(res => res.json()).then(data => {
|
||||
if (data.code !== 200) {
|
||||
localStorage.removeItem('token')
|
||||
router.replace('/login')
|
||||
} else {
|
||||
setUserName(data.user.userName)
|
||||
setNickName(data.user.nickName)
|
||||
}
|
||||
}).catch(() => {
|
||||
setResCode(500)
|
||||
setAppUnavailable(true)
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
if (data.code !== 200) {
|
||||
localStorage.removeItem("token");
|
||||
router.replace("/login");
|
||||
} else {
|
||||
setUserName(data.user.userName);
|
||||
setNickName(data.user.nickName);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setResCode(500);
|
||||
setAppUnavailable(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
setInitialized(true)
|
||||
setInitialized(true);
|
||||
}
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
if (!initialized)
|
||||
return null
|
||||
if (!initialized) return null;
|
||||
|
||||
if (appUnavailable)
|
||||
return <AppUnavailable code={resCode} />
|
||||
if (appUnavailable) return <AppUnavailable code={resCode} />;
|
||||
|
||||
return (
|
||||
<ChatWithHistoryWrap
|
||||
@ -240,7 +235,7 @@ const ChatWithHistoryWrapWithCheckToken: FC<ChatWithHistoryWrapProps> = ({
|
||||
className={className}
|
||||
userStr={`${nickName}[${userName}]`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatWithHistoryWrapWithCheckToken
|
||||
export default ChatWithHistoryWrapWithCheckToken;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user