From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001
From: wwf <yearningwang@iqtogether.com>
Date: 星期三, 04 六月 2025 15:17:49 +0800
Subject: [PATCH] 初始化

---
 app/components/base/chat/embedded-chatbot/chat-wrapper.tsx |  177 +++++++++++++---------------------------------------------
 1 files changed, 41 insertions(+), 136 deletions(-)

diff --git a/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx b/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx
index a06930c..8d0af02 100644
--- a/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx
+++ b/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useMemo, useState } from 'react'
+import { useCallback, useEffect, useMemo } from 'react'
 import Chat from '../chat'
 import type {
   ChatConfig,
@@ -9,22 +9,16 @@
 import { useChat } from '../chat/hooks'
 import { getLastAnswer, isValidGeneratedAnswer } from '../utils'
 import { useEmbeddedChatbotContext } from './context'
+import ConfigPanel from './config-panel'
 import { isDify } from './utils'
-import { InputVarType } from '@/app/components/workflow/types'
-import { TransferMethod } from '@/types/app'
-import InputsForm from '@/app/components/base/chat/embedded-chatbot/inputs-form'
+import cn from '@/utils/classnames'
 import {
   fetchSuggestedQuestions,
   getUrl,
   stopChatMessageResponding,
 } from '@/service/share'
-import AppIcon from '@/app/components/base/app-icon'
 import LogoAvatar from '@/app/components/base/logo/logo-embedded-chat-avatar'
 import AnswerIcon from '@/app/components/base/answer-icon'
-import SuggestedQuestions from '@/app/components/base/chat/chat/answer/suggested-questions'
-import { Markdown } from '@/app/components/base/markdown'
-import cn from '@/utils/classnames'
-import type { FileEntity } from '../../file-uploader/types'
 
 const ChatWrapper = () => {
   const {
@@ -33,10 +27,8 @@
     appPrevChatList,
     currentConversationId,
     currentConversationItem,
-    currentConversationInputs,
     inputsForms,
     newConversationInputs,
-    newConversationInputsRef,
     handleNewConversationCompleted,
     isMobile,
     isInstalledApp,
@@ -45,9 +37,6 @@
     handleFeedback,
     currentChatInstanceRef,
     themeBuilder,
-    clearChatList,
-    setClearChatList,
-    setIsResponding,
   } = useEmbeddedChatbotContext()
   const appConfig = useMemo(() => {
     const config = appParams || {}
@@ -67,65 +56,28 @@
     setTargetMessageId,
     handleSend,
     handleStop,
-    isResponding: respondingState,
+    isResponding,
     suggestedQuestions,
   } = useChat(
     appConfig,
     {
-      inputs: (currentConversationId ? currentConversationInputs : newConversationInputs) as any,
+      inputs: (currentConversationId ? currentConversationItem?.inputs : newConversationInputs) as any,
       inputsForm: inputsForms,
     },
     appPrevChatList,
     taskId => stopChatMessageResponding('', taskId, isInstalledApp, appId),
-    clearChatList,
-    setClearChatList,
   )
-  const inputsFormValue = currentConversationId ? currentConversationInputs : newConversationInputsRef?.current
-  const inputDisabled = useMemo(() => {
-    let hasEmptyInput = ''
-    let fileIsUploading = false
-    const requiredVars = inputsForms.filter(({ required }) => required)
-    if (requiredVars.length) {
-      requiredVars.forEach(({ variable, label, type }) => {
-        if (hasEmptyInput)
-          return
-
-        if (fileIsUploading)
-          return
-
-        if (!inputsFormValue?.[variable])
-          hasEmptyInput = label as string
-
-        if ((type === InputVarType.singleFile || type === InputVarType.multiFiles) && inputsFormValue?.[variable]) {
-          const files = inputsFormValue[variable]
-          if (Array.isArray(files))
-            fileIsUploading = files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId)
-          else
-            fileIsUploading = files.transferMethod === TransferMethod.local_file && !files.uploadedId
-        }
-      })
-    }
-    if (hasEmptyInput)
-      return true
-
-    if (fileIsUploading)
-      return true
-    return false
-  }, [inputsFormValue, inputsForms])
 
   useEffect(() => {
     if (currentChatInstanceRef.current)
       currentChatInstanceRef.current.handleStop = handleStop
   }, [currentChatInstanceRef, handleStop])
-  useEffect(() => {
-    setIsResponding(respondingState)
-  }, [respondingState, setIsResponding])
 
   const doSend: OnSend = useCallback((message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => {
     const data: any = {
       query: message,
       files,
-      inputs: currentConversationId ? currentConversationInputs : newConversationInputs,
+      inputs: currentConversationId ? currentConversationItem?.inputs : newConversationInputs,
       conversation_id: currentConversationId,
       parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || null,
     }
@@ -139,83 +91,43 @@
         isPublicAPI: !isInstalledApp,
       },
     )
-  }, [currentConversationId, currentConversationInputs, newConversationInputs, chatList, handleSend, isInstalledApp, appId, handleNewConversationCompleted])
+  }, [
+    chatList,
+    handleNewConversationCompleted,
+    handleSend,
+    currentConversationId,
+    currentConversationItem,
+    newConversationInputs,
+    isInstalledApp,
+    appId,
+  ])
 
-  const doRegenerate = useCallback((chatItem: ChatItemInTree, editedQuestion?: { message: string, files?: FileEntity[] }) => {
-    const question = editedQuestion ? chatItem : chatList.find(item => item.id === chatItem.parentMessageId)!
+  const doRegenerate = useCallback((chatItem: ChatItemInTree) => {
+    const question = chatList.find(item => item.id === chatItem.parentMessageId)!
     const parentAnswer = chatList.find(item => item.id === question.parentMessageId)
-    doSend(editedQuestion ? editedQuestion.message : question.content,
-      editedQuestion ? editedQuestion.files : question.message_files,
-      true,
-      isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null,
-    )
+    doSend(question.content, question.message_files, true, isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null)
   }, [chatList, doSend])
 
-  const messageList = useMemo(() => {
-    if (currentConversationId)
-      return chatList
-    return chatList.filter(item => !item.isOpeningStatement)
-  }, [chatList, currentConversationId])
-
-  const [collapsed, setCollapsed] = useState(!!currentConversationId)
-
   const chatNode = useMemo(() => {
-    if (!inputsForms.length)
-      return null
-    if (isMobile) {
-      if (!currentConversationId)
-        return <InputsForm collapsed={collapsed} setCollapsed={setCollapsed} />
-      return <div className='mb-4'></div>
-    }
-    else {
-      return <InputsForm collapsed={collapsed} setCollapsed={setCollapsed} />
-    }
-  }, [inputsForms.length, isMobile, currentConversationId, collapsed])
-
-  const welcome = useMemo(() => {
-    const welcomeMessage = chatList.find(item => item.isOpeningStatement)
-    if (respondingState)
-      return null
-    if (currentConversationId)
-      return null
-    if (!welcomeMessage)
-      return null
-    if (!collapsed && inputsForms.length > 0)
-      return null
-    if (welcomeMessage.suggestedQuestions && welcomeMessage.suggestedQuestions?.length > 0) {
+    if (inputsForms.length) {
       return (
-        <div className={cn('flex items-center justify-center px-4 py-12', isMobile ? 'min-h-[30vh] py-0' : 'h-[50vh]')}>
-          <div className='flex max-w-[720px] grow gap-4'>
-            <AppIcon
-              size='xl'
-              iconType={appData?.site.icon_type}
-              icon={appData?.site.icon}
-              background={appData?.site.icon_background}
-              imageUrl={appData?.site.icon_url}
-            />
-            <div className='body-lg-regular grow rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary'>
-              <Markdown content={welcomeMessage.content} />
-              <SuggestedQuestions item={welcomeMessage} />
+        <>
+          {!currentConversationId && (
+            <div className={cn('mx-auto w-full max-w-full tablet:px-4', isMobile && 'px-4')}>
+              <div className='mb-6' />
+              <ConfigPanel />
+              <div
+                className='my-6 h-[1px]'
+                style={{ background: 'linear-gradient(90deg, rgba(242, 244, 247, 0.00) 0%, #F2F4F7 49.17%, rgba(242, 244, 247, 0.00) 100%)' }}
+              />
             </div>
-          </div>
-        </div>
+          )}
+        </>
       )
     }
-    return (
-      <div className={cn('flex h-[50vh] flex-col items-center justify-center gap-3 py-12', isMobile ? 'min-h-[30vh] py-0' : 'h-[50vh]')}>
-        <AppIcon
-          size='xl'
-          iconType={appData?.site.icon_type}
-          icon={appData?.site.icon}
-          background={appData?.site.icon_background}
-          imageUrl={appData?.site.icon_url}
-        />
-        <div className='max-w-[768px] px-4'>
-          <Markdown className='!body-2xl-regular !text-text-tertiary' content={welcomeMessage.content} />
-        </div>
-      </div>
-    )
-  }, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, currentConversationId, inputsForms.length, respondingState])
+
+    return null
+  }, [currentConversationId, inputsForms, isMobile])
 
   const answerIcon = isDify()
     ? <LogoAvatar className='relative shrink-0' />
@@ -232,22 +144,17 @@
     <Chat
       appData={appData}
       config={appConfig}
-      chatList={messageList}
-      isResponding={respondingState}
-      chatContainerInnerClassName={cn('mx-auto w-full max-w-full pt-4 tablet:px-4', isMobile && 'px-4')}
-      chatFooterClassName={cn('pb-4', !isMobile && 'rounded-b-2xl')}
-      chatFooterInnerClassName={cn('mx-auto w-full max-w-full px-4', isMobile && 'px-2')}
+      chatList={chatList}
+      isResponding={isResponding}
+      chatContainerInnerClassName={cn('mx-auto w-full max-w-full tablet:px-4', isMobile && 'px-4')}
+      chatFooterClassName='pb-4'
+      chatFooterInnerClassName={cn('mx-auto w-full max-w-full tablet:px-4', isMobile && 'px-4')}
       onSend={doSend}
-      inputs={currentConversationId ? currentConversationInputs as any : newConversationInputs}
+      inputs={currentConversationId ? currentConversationItem?.inputs as any : newConversationInputs}
       inputsForm={inputsForms}
       onRegenerate={doRegenerate}
       onStopResponding={handleStop}
-      chatNode={
-        <>
-          {chatNode}
-          {welcome}
-        </>
-      }
+      chatNode={chatNode}
       allToolIcons={appMeta?.tool_icons || {}}
       onFeedback={handleFeedback}
       suggestedQuestions={suggestedQuestions}
@@ -255,8 +162,6 @@
       hideProcessDetail
       themeBuilder={themeBuilder}
       switchSibling={siblingMessageId => setTargetMessageId(siblingMessageId)}
-      inputDisabled={inputDisabled}
-      isMobile={isMobile}
     />
   )
 }

--
Gitblit v1.8.0