瀏覽代碼

补全预览聊天

李富豪 3 月之前
父節點
當前提交
1c571cec9a
共有 2 個文件被更改,包括 158 次插入122 次删除
  1. 49 23
      src/components/chat/index.tsx
  2. 109 99
      src/pages/deepseek/questionAnswer/info/index.tsx

+ 49 - 23
src/components/chat/index.tsx

@@ -1,11 +1,12 @@
 import React, { useEffect, useRef, useState } from 'react';
-import { Button, GetProp, GetRef, Popover, Space, Spin, message } from 'antd';
+import { Button, GetProp, GetRef, Popover, Space, Spin, Tooltip, message } from 'antd';
 import {
     CloseOutlined,
     CloudUploadOutlined,
     CommentOutlined,
     OpenAIFilled,
     PlusOutlined,
+    RedoOutlined,
 } from '@ant-design/icons';
 import {
     Attachments,
@@ -142,6 +143,7 @@ const useCopilotStyle = createStyles(({ token, css }) => {
 interface CopilotProps {
     copilotOpen: boolean;
     setCopilotOpen: (open: boolean) => void;
+    appId: string,
 }
 
 const Copilot = (props: CopilotProps) => {
@@ -184,47 +186,44 @@ const Copilot = (props: CopilotProps) => {
             };
         },
         transformMessage: (info) => {
+            console.log(info, '回复消息');
+
             const { originMessage, chunk } = info || {};
+
             let currentContent = '';
-            let currentThink = '';
+
             try {
-                if (chunk?.data && !chunk?.data.includes('DONE')) {
+                if (chunk?.data) {
                     const message = JSON.parse(chunk?.data);
-                    currentThink = message?.choices?.[0]?.delta?.reasoning_content || '';
-                    currentContent = message?.choices?.[0]?.delta?.content || '';
+                    // 根据实际返回结构调整字段访问路径
+                    if (message.event !== 'finish') {
+                        currentContent = message?.data || '';
+                    }
                 }
             } catch (error) {
                 console.error(error);
             }
 
-            let content = '';
-
-            if (!originMessage?.content && currentThink) {
-                content = `<think>${currentThink}`;
-            } else if (
-                originMessage?.content?.includes('<think>') &&
-                !originMessage?.content.includes('</think>') &&
-                currentContent
-            ) {
-                content = `${originMessage?.content}</think>${currentContent}`;
-            } else {
-                content = `${originMessage?.content || ''}${currentThink}${currentContent}`;
-            }
+            // 简化内容拼接逻辑
+            const content = `${originMessage?.content || ''}${currentContent}`;
 
             return {
                 content: content,
                 role: 'assistant',
             };
+
         },
         resolveAbortController: (controller) => {
             abortController.current = controller;
         },
     });
+
     // ==================== Event ====================
+
     const handleUserSubmit = (val: string) => {
         onRequest({
             message: { content: val, role: 'user' },
-            appId: '2942534530212696064',
+            appId: props.appId,
             // 进阶配置
             request_id: undefined,
             returnType: undefined,
@@ -420,11 +419,34 @@ const Copilot = (props: CopilotProps) => {
                         // }
                         onPasteFile={onPasteFile}
                         actions={(_, info) => {
-                            const { SendButton, LoadingButton, SpeechButton } = info.components;
+                            const { SendButton, LoadingButton, SpeechButton, ClearButton } = info.components;
                             return (
                                 <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
                                     {/* <SpeechButton className={styles.speechButton} /> */}
-                                    {loading ? <LoadingButton type="default" /> : <SendButton type="primary" />}
+                                    <Tooltip title={loading ? '停止' : '发送'}>
+                                        {loading ? <LoadingButton type="default" /> : <SendButton type="primary" />}
+                                    </Tooltip>
+                                    <Tooltip title="重新开始">
+                                        <Button
+                                            type="primary"
+                                            shape="circle"
+                                            icon={<RedoOutlined />}
+                                            onClick={() => {
+                                                const timeNow = dayjs().valueOf().toString();
+                                                abortController.current?.abort();
+
+                                                // 确保异步操作完成后清空消息
+                                                setTimeout(() => {
+                                                    setSessionList([
+                                                        { key: timeNow, label: 'New session', group: 'Today' },
+                                                        ...sessionList,
+                                                    ]);
+                                                    setCurSession(timeNow);
+                                                    setMessages([]);
+                                                }, 100);
+                                            }}
+                                        />
+                                    </Tooltip>
                                 </div>
                             );
                         }}
@@ -521,13 +543,17 @@ const useWorkareaStyle = createStyles(({ token, css }) => {
     };
 });
 
-const Chat: React.FC = () => {
+const Chat: React.FC<{ appId: string }> = (props) => {
     const { styles: workareaStyles } = useWorkareaStyle();
     const [copilotOpen, setCopilotOpen] = useState(true);
 
     return (
         <div className={workareaStyles.copilotWrapper}>
-            <Copilot copilotOpen={copilotOpen} setCopilotOpen={setCopilotOpen} />
+            <Copilot
+                copilotOpen={copilotOpen}
+                setCopilotOpen={setCopilotOpen}
+                appId={props.appId}
+            />
         </div>
     );
 };

+ 109 - 99
src/pages/deepseek/questionAnswer/info/index.tsx

@@ -131,6 +131,7 @@ const QuestionAnswerInfo: React.FC = () => {
     const [createFlag, setCreateFlag] = React.useState<boolean>();
     const [appProjectList, setAppProjectList] = React.useState<AppTypeList>([]);
     const [isAppPro, setIsAppPro] = React.useState<boolean>(false);
+    const [appId, setAppId] = React.useState<string>('');
 
     const style: React.CSSProperties = {
         display: 'flex',
@@ -234,6 +235,8 @@ const QuestionAnswerInfo: React.FC = () => {
 
                 const info = res.data.detail;
 
+                setAppId(info.appId);
+
                 setTopPValue(info.topP as number);
                 setTempValue(info.temperature as number);
                 setName(info.name);
@@ -284,7 +287,7 @@ const QuestionAnswerInfo: React.FC = () => {
                     setIsDeepThinkVisible(false);
                 }
 
-                console.log(info.knowledgeIds,'info.knowledgeIds')
+                console.log(info.knowledgeIds, 'info.knowledgeIds')
                 form.setFieldsValue({
                     id: info.id,
                     name: info.name,  //应用名称
@@ -335,7 +338,7 @@ const QuestionAnswerInfo: React.FC = () => {
                         value: item.knowledgeId,
                     }
                 });
-                console.log(list,'list')
+                console.log(list, 'list')
 
 
                 setKnowledgeList(list);
@@ -402,13 +405,99 @@ const QuestionAnswerInfo: React.FC = () => {
         }
     }
 
-    // const [modelValue, setModelValue] = useState('');
-    //
-    // // 监听表单中模型值的变化
-    // useEffect(() => {
-    //     const currentModel = form.getFieldValue('model');
-    //     setModelValue(currentModel);
-    // }, [form]); // 依赖表单实例,当表单值变化时重新执行
+    const saveConfig = (type: 'SAVE' | 'SUBMIT') => {
+        form.validateFields().then(async (values) => {
+            const data = values;
+            console.log(values, 'values');
+            // 问题列表
+            const question: string[] = [];
+            if (inputs) {
+                inputs.map((item, index) => {
+                    question.push(item.value);
+                });
+            }
+            console.log(question, 'question');
+            interface Item {
+                index_type_id: number,
+                knowledge_id: string
+            }
+            const indexTypeList: Item[] = [];
+            if (values.knowledge_ids && values.knowledge_ids.length > 0) {
+                console.log("knowledge_ids", values.knowledge_ids);
+                const index_type: Item = {
+                    index_type_id: 0,
+                    knowledge_id: values.knowledge_ids
+                };
+                indexTypeList.push(index_type);
+            }
+            const userInfo = LocalStorage.getUserInfo();
+            const userId = (userInfo?.id ?? '').toString();
+
+            const data_info = {
+                param_desc: values.param_desc, //回答风格
+                show_recall_result: values.show_recall_result, //是否展示召回结果
+                recall_method: values.recall_method, //召回方式
+                rerank_status: values.rerank_status, //开启rerank
+                rerank_model_name: values.rerank_model_name, //模型名称
+                slice_config_type: values.slice_config_type, // 召回切片数量
+                slice_count: values.slice_count, // 切片数量
+                recall_slice_splicing_method: values.recall_slice_splicing_method, // 切片内容
+                rerank_index_type_list: values.rerank_status === true ? indexTypeList : [], //知识库id
+                recall_index_type_list: values.recall_method === 'embedding' || 'mixed' ? indexTypeList : []
+                // rerank_status = 1 rerank_index_type_list
+                // recall_method = 'embedding' || 'embedding'  recall_index_type_list
+            };
+            // const knowledgeIds: string[] = [];
+            // knowledgeIds.push(values.knowledge_ids);
+            const info = {
+                id: values.id,
+                name: values.name,  //应用名称
+                desc: values.desc,  //应用描述
+                prompt: values.prompt, //应用提示语
+                top_p: topPValue.toString(), //topP
+                temperature: tempValue.toString(), //温度
+                knowledge_ids: values.knowledge_ids,
+                slice_count: values.slice_count,
+                model: values.model,
+                isDeepThink: values.isDeepThink,
+                icon_color: values.icon_color,
+                icon_type: values.icon_type,
+                questionList: question,
+                knowledge_info: JSON.stringify(data_info),
+                max_token: values.max_token, //应用最大token
+                typeId: values.typeId, // 应用类型
+                appProId: values.appProId,// 项目
+                userId: userId, // 用户id
+            };
+            console.log(info, 'info data');
+            const id = location?.state?.id;
+            let res = null;
+            if (id) {
+                // 编辑应用
+                res = await apis.modifyTakaiApplicationApi(id, info);
+            } else {
+                // 创建应用
+                res = await await apis.createTakaiApplicationApi(info);
+            }
+            console.log(res, 'create or modify');
+            if (res.data === 9) {
+                message.error('没有配置审核人,请联系管理员');
+            } else if (res.data === 1) {
+                message.success('操作成功')
+            } else {
+                message.error('操作失败');
+            }
+            if (type === 'SUBMIT') {
+                router.navigate({ pathname: '/deepseek/questionAnswer' });
+            }
+        }).catch((error) => {
+            console.error(error);
+            error.errorFields && error.errorFields.map((item: any) => {
+                console.log(item, 'item');
+                message.error(`字段 ${item.name} ${item.errors[0]}`);
+            });
+        });
+    }
 
     return (
         <div className='questionAnswerInfo'>
@@ -548,99 +637,20 @@ const QuestionAnswerInfo: React.FC = () => {
                                 >
                                     取消
                                 </Button>
+                                <Button
+                                    type='primary'
+                                    className='btn-cancel'
+                                    onClick={() => {
+                                        saveConfig('SAVE');
+                                    }}
+                                >
+                                    保存
+                                </Button>
                                 {createFlag && (
                                     <Button
                                         type='primary'
                                         onClick={() => {
-                                            form.validateFields().then(async (values) => {
-                                                const data = values;
-                                                console.log(values, 'values');
-                                                // 问题列表
-                                                const question: string[] = [];
-                                                if (inputs) {
-                                                    inputs.map((item, index) => {
-                                                        question.push(item.value);
-                                                    });
-                                                }
-                                                console.log(question, 'question');
-                                                interface Item {
-                                                    index_type_id: number,
-                                                    knowledge_id: string
-                                                }
-                                                const indexTypeList: Item[] = [];
-                                                if (values.knowledge_ids && values.knowledge_ids.length > 0) {
-                                                    console.log("knowledge_ids",values.knowledge_ids);
-                                                    const index_type: Item = {
-                                                        index_type_id: 0,
-                                                        knowledge_id: values.knowledge_ids
-                                                    };
-                                                    indexTypeList.push(index_type);
-                                                }
-                                                const userInfo = LocalStorage.getUserInfo();
-                                                const userId = (userInfo?.id ?? '').toString();
-
-                                                const data_info = {
-                                                    param_desc: values.param_desc, //回答风格
-                                                    show_recall_result: values.show_recall_result, //是否展示召回结果
-                                                    recall_method: values.recall_method, //召回方式
-                                                    rerank_status: values.rerank_status, //开启rerank
-                                                    rerank_model_name: values.rerank_model_name, //模型名称
-                                                    slice_config_type: values.slice_config_type, // 召回切片数量
-                                                    slice_count: values.slice_count, // 切片数量
-                                                    recall_slice_splicing_method: values.recall_slice_splicing_method, // 切片内容
-                                                    rerank_index_type_list: values.rerank_status === true ? indexTypeList : [], //知识库id
-                                                    recall_index_type_list: values.recall_method === 'embedding' || 'mixed' ? indexTypeList : []
-                                                    // rerank_status = 1 rerank_index_type_list
-                                                    // recall_method = 'embedding' || 'embedding'  recall_index_type_list
-                                                };
-                                                // const knowledgeIds: string[] = [];
-                                                // knowledgeIds.push(values.knowledge_ids);
-                                                const info = {
-                                                    id: values.id,
-                                                    name: values.name,  //应用名称
-                                                    desc: values.desc,  //应用描述
-                                                    prompt: values.prompt, //应用提示语
-                                                    top_p: topPValue.toString(), //topP
-                                                    temperature: tempValue.toString(), //温度
-                                                    knowledge_ids: values.knowledge_ids,
-                                                    slice_count: values.slice_count,
-                                                    model: values.model,
-                                                    isDeepThink: values.isDeepThink,
-                                                    icon_color: values.icon_color,
-                                                    icon_type: values.icon_type,
-                                                    questionList: question,
-                                                    knowledge_info: JSON.stringify(data_info),
-                                                    max_token: values.max_token, //应用最大token
-                                                    typeId: values.typeId, // 应用类型
-                                                    appProId: values.appProId,// 项目
-                                                    userId: userId, // 用户id
-                                                };
-                                                console.log(info, 'info data');
-                                                const id = location?.state?.id;
-                                                let res = null;
-                                                if (id) {
-                                                    // 编辑应用
-                                                    res = await apis.modifyTakaiApplicationApi(id, info);
-                                                } else {
-                                                    // 创建应用
-                                                    res = await await apis.createTakaiApplicationApi(info);
-                                                }
-                                                console.log(res, 'create or modify');
-                                                if (res.data === 9) {
-                                                    message.error('没有配置审核人,请联系管理员');
-                                                } else if (res.data === 1) {
-                                                    message.success('操作成功')
-                                                } else {
-                                                    message.error('操作失败');
-                                                }
-                                                router.navigate({ pathname: '/deepseek/questionAnswer' });
-                                            }).catch((error) => {
-                                                console.error(error);
-                                                error.errorFields && error.errorFields.map((item: any) => {
-                                                    console.log(item, 'item');
-                                                    message.error(`字段 ${item.name} ${item.errors[0]}`);
-                                                });
-                                            });
+                                            saveConfig('SUBMIT');
                                         }}
                                     >
                                         提交应用
@@ -985,7 +995,7 @@ const QuestionAnswerInfo: React.FC = () => {
                                 </div>
                             </Splitter.Panel>
                             <Splitter.Panel defaultSize="30%">
-                                <Chat />
+                                <Chat appId={appId} />
                             </Splitter.Panel>
                         </Splitter>
                     </div>