Commit 476172cd by Liu

fix:引入sdk逻辑&&向sdk传参数区分web

parent af94f1e6
...@@ -31,17 +31,28 @@ async function loadSDK(): Promise<void> { ...@@ -31,17 +31,28 @@ async function loadSDK(): Promise<void> {
const ChatSDK = (window as any).ChatSDK const ChatSDK = (window as any).ChatSDK
if (ChatSDK && ChatSDK.createChatSDK) { if (ChatSDK && ChatSDK.createChatSDK) {
const toolId = typeof window !== 'undefined' ? sessionStorage.getItem('currentToolId') : null const toolId = typeof window !== 'undefined' ? sessionStorage.getItem('currentToolId') : null
console.log('[SDK] toolId:', toolId) // 读取缓存中的待发送问题(可能是 QuestionList 点击后设置的)
const pendingQuestion = typeof window !== 'undefined'
? sessionStorage.getItem('__CHAT_SDK_PENDING_QUESTION__')
: null
const config = { const config = {
code: import.meta.env.VITE_SDK_CODE || 'default_code', code: import.meta.env.VITE_SDK_CODE || 'default_code',
channel: import.meta.env.VITE_SDK_CHANNEL || 'default_channel', channel: import.meta.env.VITE_SDK_CHANNEL || 'default_channel',
toolId, toolId,
mock: import.meta.env.VITE_SDK_MOCK === 'true', mock: import.meta.env.VITE_SDK_MOCK === 'true',
apiBaseUrl: import.meta.env.VITE_SDK_API_BASE_URL, apiBaseUrl: import.meta.env.VITE_SDK_API_BASE_URL,
initialQuestion: pendingQuestion || undefined,
clientType: import.meta.env.VITE_OUTPUT_OBJ || 'open',
} }
console.log('[SDK] [初始化] createChatSDK 配置:', JSON.stringify(config, null, 2))
try { try {
ChatSDK.createChatSDK(config) const sdkInstance = ChatSDK.createChatSDK(config)
console.log('[SDK] 初始化成功') // 缓存实例引用,方便后续复用
if (sdkInstance) {
window.__CHAT_SDK_INSTANCE__ = sdkInstance
console.log('[SDK] [初始化] SDK 实例创建成功并缓存到 window.__CHAT_SDK_INSTANCE__')
}
console.log('[SDK] [初始化] 初始化成功')
} }
catch (error) { catch (error) {
console.error('[SDK] 初始化失败:', error) console.error('[SDK] 初始化失败:', error)
......
...@@ -222,17 +222,6 @@ export const Chat: React.FC = () => { ...@@ -222,17 +222,6 @@ export const Chat: React.FC = () => {
console.debug('[Chat] 当前链接 / 缓存 toolId:', debugInfo) console.debug('[Chat] 当前链接 / 缓存 toolId:', debugInfo)
}, [debugInfo]) }, [debugInfo])
// 调试:观察 shouldSendQuestion 在对话页的变化
useEffect(() => {
console.log('[Chat] shouldSendQuestion changed 111111:', {
conversationIdFromRoute: id,
shouldSendQuestion,
currentToolId,
isLoading,
allItemsLength: allItems.length,
})
}, [id, shouldSendQuestion, currentToolId, isLoading, allItems.length])
// 历史记录点击时将 toolId 通过路由 state 传入,优先使用该值快速同步高亮 // 历史记录点击时将 toolId 通过路由 state 传入,优先使用该值快速同步高亮
useEffect(() => { useEffect(() => {
// 保存从 location.state 传递的 toolId 到 ref // 保存从 location.state 传递的 toolId 到 ref
...@@ -1103,15 +1092,6 @@ export const Chat: React.FC = () => { ...@@ -1103,15 +1092,6 @@ export const Chat: React.FC = () => {
} }
: null) : null)
if (wfAnswerForFollowUp) { if (wfAnswerForFollowUp) {
console.log('[Chat WF] 流结束准备续问', {
parsed: wfParsedCtrl,
complete: isWorkflowControlPayloadComplete(wfParsedCtrl),
willEnterSub: isWorkflowEnterSubPayload(wfParsedCtrl),
packetQuestion: wfPacketQuestion,
wfRawParseText: wfRawParseText.slice(0, 120),
hasRef: Boolean(streamSnapshotForWf),
displayAnswer: wfAnswerForFollowUp.answer,
})
processBusinessInsightWorkflowAfterStream(wfAnswerForFollowUp) processBusinessInsightWorkflowAfterStream(wfAnswerForFollowUp)
} }
else { else {
...@@ -1554,7 +1534,6 @@ export const Chat: React.FC = () => { ...@@ -1554,7 +1534,6 @@ export const Chat: React.FC = () => {
dispatch(clearShouldSendQuestion()) dispatch(clearShouldSendQuestion())
// 确保历史记录加载完成后再发送问题 // 确保历史记录加载完成后再发送问题
setTimeout(() => { setTimeout(() => {
console.log('[Chat] 执行自动发送问题:', questionToSend)
const autoExtra = buildWorkflowContinueExtraFromRef() const autoExtra = buildWorkflowContinueExtraFromRef()
handleSubmitQuestion(questionToSend, undefined, currentToolId, autoExtra) handleSubmitQuestion(questionToSend, undefined, currentToolId, autoExtra)
}, 100) }, 100)
......
...@@ -79,8 +79,25 @@ export const Home: React.FC = () => { ...@@ -79,8 +79,25 @@ export const Home: React.FC = () => {
const hasFetched = useRef(false) const hasFetched = useRef(false)
const hasCalledBusinessApis = useRef(false) // 防止业务接口重复调用 const hasCalledBusinessApis = useRef(false) // 防止业务接口重复调用
const prevPathRef = useRef<string>(location.pathname) // 记录上一次路径,用于检测从收藏页面返回 const prevPathRef = useRef<string>(location.pathname) // 记录上一次路径,用于检测从收藏页面返回
// 使用 useState // 默认 mock 数据 - 接口失败时回退到这个数据
const [otherQuestions, setOtherQuestions] = useState<any>({ content: [] }) const DEFAULT_QUESTIONS = {
content: [
'润爱家投保前需要体检吗?',
'和谐喜乐一生少儿重疾险产品特色是什么?',
'家属没有医保,是否可以投保润爱家?',
'福寿双全A01产品保费要求是什么?',
'润爱家等待期是多久?',
'润爱家保障范围包括哪些疾病?',
'定期寿险和终身寿险有什么区别?',
'如何选择适合自己的重疾险保额?',
'保险等待期内出险能理赔吗?',
'什么是百万医疗险?适合哪些人群购买?',
],
configName: '您可以试着问我',
}
// 使用 useState - 添加默认 mock 数据
const [otherQuestions, setOtherQuestions] = useState<any>(DEFAULT_QUESTIONS)
const [isToolBtnActive, setIsToolBtnActive] = useState<boolean>(false) const [isToolBtnActive, setIsToolBtnActive] = useState<boolean>(false)
const [shouldChangeStyle, setShouldChangeStyle] = useState<boolean>(true) const [shouldChangeStyle, setShouldChangeStyle] = useState<boolean>(true)
const [isBusinessInsightMode, setIsBusinessInsightMode] = useState<boolean>(false) const [isBusinessInsightMode, setIsBusinessInsightMode] = useState<boolean>(false)
...@@ -201,7 +218,8 @@ export const Home: React.FC = () => { ...@@ -201,7 +218,8 @@ export const Home: React.FC = () => {
} }
catch (error) { catch (error) {
console.error('[HomeNew] handleRefreshQuestions - 刷新问题列表失败:', error) console.error('[HomeNew] handleRefreshQuestions - 刷新问题列表失败:', error)
throw error // 抛出错误,让 QuestionList 组件处理 // 接口失败时回退到 mock 数据
setOtherQuestions(DEFAULT_QUESTIONS)
} }
finally { finally {
setIsDataLoaded(true) // 无论成功失败都标记为已加载 setIsDataLoaded(true) // 无论成功失败都标记为已加载
...@@ -265,6 +283,8 @@ export const Home: React.FC = () => { ...@@ -265,6 +283,8 @@ export const Home: React.FC = () => {
} }
catch (error) { catch (error) {
console.error('获取工具相关问题失败:', error) console.error('获取工具相关问题失败:', error)
// 接口失败时回退到 mock 数据
setOtherQuestions(DEFAULT_QUESTIONS)
} }
finally { finally {
setIsDataLoaded(true) // 无论成功失败都标记为已加载 setIsDataLoaded(true) // 无论成功失败都标记为已加载
......
...@@ -109,28 +109,12 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({ ...@@ -109,28 +109,12 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({
const handleClick = (item: string) => { const handleClick = (item: string) => {
if (checkAuth() && !isClicking) { if (checkAuth() && !isClicking) {
setIsClicking(true) setIsClicking(true)
// 获取当前的 toolId,优先从 Redux 获取,其次从 sessionStorage 获取
const toolId = currentToolId || safeSessionStorageGetItem('currentToolId') || null const toolId = currentToolId || safeSessionStorageGetItem('currentToolId') || null
// 优先使用当前会话,如果没有则使用第一个会话,如果都没有则创建新会话
const targetConversationId = currentConversationId || conversations[0]?.conversationId const targetConversationId = currentConversationId || conversations[0]?.conversationId
console.log('[QuestionList] 点击常见问题:', {
question: item,
toolId,
currentConversationId,
targetConversationId,
hasConversations: conversations.length > 0,
})
if (targetConversationId) { if (targetConversationId) {
// 使用现有会话
console.log('[QuestionList] 使用现有会话,设置 shouldSendQuestion 并导航:', {
conversationId: targetConversationId,
question: item,
toolId,
})
dispatch(setCurrentConversation(targetConversationId)) dispatch(setCurrentConversation(targetConversationId))
dispatch(setShouldSendQuestion(item)) dispatch(setShouldSendQuestion(item))
// 通过 location.state 传递 toolId,避免 Chat 页面清空 toolId
// 传递 skipHistoryLoad 标记,跳过历史记录加载,直接发送问题
navigate(`/chat/${targetConversationId}`, { navigate(`/chat/${targetConversationId}`, {
state: { state: {
toolId, toolId,
...@@ -139,8 +123,6 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({ ...@@ -139,8 +123,6 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({
}) })
} }
else { else {
// 如果没有现有会话,仍然创建新会话(向后兼容)
console.log('[QuestionList] 没有现有会话,创建新会话:', item)
dispatch( dispatch(
createConversation({ createConversation({
conversationData: {}, conversationData: {},
...@@ -149,7 +131,7 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({ ...@@ -149,7 +131,7 @@ const QuestionListBase: React.FC<QuestionListProps & WithAuthProps> = ({
}), }),
) )
} }
// 防止重复点击
setTimeout(() => { setTimeout(() => {
setIsClicking(false) setIsClicking(false)
}, 1000) }, 1000)
......
interface ChatSDKConfig {
code: string
channel: string
toolId?: string
apiBaseUrl?: string
mock?: boolean
isDesktop?: boolean
}
interface ChatSDKInstance {
speak: (text: string) => void
stopSpeak: () => void
destroy: () => void
}
let sdkInstance: ChatSDKInstance | null = null
let sdkLoadingPromise: Promise<void> | null = null
export async function loadChatSDK(config: ChatSDKConfig): Promise<ChatSDKInstance | null> {
if (sdkInstance) {
return sdkInstance
}
if (sdkLoadingPromise) {
await sdkLoadingPromise
return sdkInstance
}
sdkLoadingPromise = new Promise((resolve) => {
const script = document.createElement('script')
script.src = '/sdream-ai/sdk/index.js'
script.onload = () => {
try {
const ChatSDK = (window as any).ChatSDK
if (ChatSDK && ChatSDK.createChatSDK) {
sdkInstance = ChatSDK.createChatSDK(config)
console.log('[SDK] toolId:', config.toolId)
}
}
catch (error) {
console.error('[SDK] 初始化失败:', error)
}
resolve()
}
script.onerror = () => {
console.error('[SDK] ChatSDK 脚本加载失败')
resolve()
}
document.body.appendChild(script)
})
await sdkLoadingPromise
return sdkInstance
}
export function getSDKInstance(): ChatSDKInstance | null {
return sdkInstance
}
export function destroySDK(): void {
if (sdkInstance) {
sdkInstance.destroy()
sdkInstance = null
}
sdkLoadingPromise = null
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment