Explorar o código

第一版改动

李富豪 hai 3 meses
pai
achega
45e5d5d3b0

+ 4 - 4
app/client/api.ts

@@ -31,11 +31,11 @@ export interface MultimodalContent {
 export interface RequestMessage {
   role: MessageRole;
   content: string | MultimodalContent[];
-  document?: {
+  documents?: {
     id: string,
     name: string,
     url: string,
-  }
+  }[],
 }
 
 export interface LLMConfig {
@@ -244,11 +244,11 @@ export function getHeaders() {
     apiKey,
     isEnabledAccessControl,
   } = getConfig();
-  
+
   function getAuthHeader(): string {
     return isAzure ? "api-key" : "Authorization";
   }
-  
+
   // when using baidu api in app, not set auth header
   if (isBaidu && clientConfig?.isApp) return headers;
 

+ 1 - 7
app/client/platforms/bigModel.ts

@@ -216,7 +216,6 @@ export class BigModelApi implements LLMApi {
               date: item.date,
               role: item.role,
               content: item.content,
-              sliceInfo: item.sliceInfo,
             })),
           };
           const messages = session.messages.slice();
@@ -230,12 +229,7 @@ export class BigModelApi implements LLMApi {
               }
             });
           }
-          const chatMode = useChatStore.getState().chatMode;
-          if (chatMode === 'LOCAL') {
-            await api.post('deepseek/api/dialog/save', data);
-          } else {
-            await api.post('bigmodel/api/dialog/save', data);
-          }
+          await api.post('deepseek/api/dialog/save', data);
         },
         onerror(e) {
           options.onError?.(e);

+ 5 - 20
app/client/platforms/deepSeek.ts

@@ -26,25 +26,11 @@ export class DeepSeekApi implements LLMApi {
   }
 
   async chat(options: ChatOptions) {
-    const list: ChatOptions['messages'] = JSON.parse(JSON.stringify(options.messages)) || [];
-
-    const backList = list.reverse();
-    const item = backList.find((item) => {
-      if (item.document) {
-        if (item.document.id) {
-          return true;
-        } else {
-          return false;
-        }
-      } else {
-        return false;
-      }
-    });
-
     const messages = options.messages.map((item) => {
       return {
         role: item.role,
         content: getMessageTextContent(item),
+        documents: item.documents,
       }
     });
 
@@ -54,6 +40,7 @@ export class DeepSeekApi implements LLMApi {
       userMessages.unshift({
         role: "user",
         content: "⠀",
+        documents: undefined,
       });
     }
 
@@ -66,7 +53,6 @@ export class DeepSeekApi implements LLMApi {
       enable_think: isDeepThink,
       messages: userMessages,
       stream: true,
-      document_id: (item && item.document) ? item.document.id : undefined,
       // 进阶配置
       max_tokens: undefined,
       temperature: undefined,
@@ -219,7 +205,7 @@ export class DeepSeekApi implements LLMApi {
           const dialogName = item ? item.content : '新的聊天';
           const data = {
             id: session.id,
-            appId: '1881269958412521255',
+            appId: '2924812721300312064',
             userId: undefined,
             dialogName: dialogName,
             messages: session.messages.map(item => ({
@@ -227,11 +213,10 @@ export class DeepSeekApi implements LLMApi {
               date: item.date,
               role: item.role,
               content: item.content,
-              document: item.document,
-              networkInfo: item.networkInfo,
+              documents: item.documents,
             })),
           };
-          await api.post('bigmodel/api/dialog/save', data);
+          await api.post('deepseek/api/dialog/save', data);
         },
         onerror(e) {
           options.onError?.(e);

+ 71 - 86
app/components/DeekSeekHome.tsx

@@ -1,24 +1,25 @@
 import * as React from 'react';
 import { useNavigate } from "react-router-dom";
-import { Dropdown, Spin, Input, Button, Space } from 'antd';
+import { Dropdown, Spin, Input, Button, Space, UploadProps } from 'antd';
 import { Chat } from './DeepSeekChat';
 import whiteLogo from "../icons/whiteLogo.png";
 import jkxz from "../icons/jkxz.png";
-import { useChatStore } from "../store";
+import { useChatStore, useGlobalStore } from "../store";
 import { useMobileScreen } from '../utils';
 import api from "@/app/api/api";
-import { SideBar } from './sidebar';
 import './deepSeekHome.scss';
+import { message, Upload } from 'antd';
+import { InboxOutlined } from '@ant-design/icons';
 
-const { TextArea } = Input;
-
+const { Dragger } = Upload;
 const DeekSeek: React.FC = () => {
     const chatStore = useChatStore();
+    const globalStore = useGlobalStore();
+    useGlobalStore((state) => state.setIsChatActive);
     const isMobileScreen = useMobileScreen();
     const navigate = useNavigate();
 
     const [listLoading, setListLoading] = React.useState(false);
-    const [isChatActive, setIsChatActive] = React.useState(false); // 新增状态:聊天是否激活
     const [userInput, setUserInput] = React.useState(''); // 新增状态:用户输入
 
     type List = {
@@ -55,97 +56,89 @@ const DeekSeek: React.FC = () => {
         }
     }, []);
 
-    // 处理发送消息
-    const handleSend = () => {
-        if (userInput.trim()) {
-            setIsChatActive(true);
-            // 这里可以添加发送消息的逻辑
-            console.log('发送消息:', userInput);
-        }
-    };
+    React.useEffect(() => {
+        globalStore.setDocuments([]);
+        globalStore.setIsChatActive(false);
+        setFileList([]);
+    }, []);
 
-    // 处理输入框点击,激活聊天界面
-    const handleInputClick = () => {
-        setIsChatActive(true);
-    };
+    const [fileList, setFileList] = React.useState<any[]>([]);
 
-    // 重置到初始状态
-    const resetToHome = () => {
-        setIsChatActive(false);
-        setUserInput('');
+    const props: UploadProps = {
+        action: '/deepseek-api' + '/upload/file',
+        method: 'POST',
+        accept: ['.docx'].join(','),
+        multiple: true,
+        maxCount: 5,
+        fileList: fileList,
+        onChange(info) {
+            const fileList = info.fileList.map((file) => {
+                const data = file.response;
+                return {
+                    ...file,
+                    documentId: data?.document_id || '',
+                    name: file.name,
+                    url: data?.document_url || file.url,
+                }
+            });
+            setFileList(fileList);
+            if (info.file.status === 'done') {// 上传成功
+                const { code, message: msg } = info.file.response;
+                if (code === 200) {
+                    message.success('上传成功');
+                } else {
+                    message.error(msg);
+                }
+            } else if (info.file.status === 'error') {// 上传失败
+                message.error('上传失败');
+            }
+        },
+        onDrop(e) {
+            console.log('Dropped files', e.dataTransfer.files);
+        },
     };
 
     return (
         <Spin spinning={listLoading}>
             <div className='deekSeek'>
-                {/* 左侧 Sidebar */}
-                <SideBar />
-                
                 {/* 主要区域 */}
                 <div className='deekSeek-main'>
-                    {!isChatActive ? (
+                    {!globalStore.isChatActive ? (
                         // 未交互状态:显示简化对话框
                         <div className='deekSeek-content'>
                             <div className='deekSeek-content-title'>
                                 <img src={jkxz.src} />
                             </div>
-                            <div className='deekSeek-content-title-sm' style={{ marginBottom: isMobileScreen ? 14 : 20 }}>
+                            <div className='deekSeek-content-title-sm' style={{ marginBottom: 40 }}>
                                 您好, 我是小智文件处理助手!
                             </div>
-                            
                             {/* 输入区域 */}
                             <div className='deekSeek-input-section'>
-                                <div className='deekSeek-input-tabs'>
-                                    <Button className='deekSeek-tab-button active'>
-                                        <span className='deekSeek-tab-icon'>⚛️</span>
-                                        DeepSeek-R1
-                                    </Button>
-                                    <Button className='deekSeek-tab-button'>
-                                        <span className='deekSeek-tab-icon'>🌐</span>
-                                        联网搜索
-                                    </Button>
-                                </div>
-                                
-                                <div className='deekSeek-input-container' onClick={handleInputClick}>
-                                    <TextArea
-                                        value={userInput}
-                                        onChange={(e) => setUserInput(e.target.value)}
-                                        placeholder="输入您的问题或需求, Control+Enter换行"
-                                        className='deekSeek-main-input'
-                                        autoSize={{ minRows: 3, maxRows: 6 }}
-                                        onKeyDown={(e) => {
-                                            if (e.ctrlKey && e.key === 'Enter') {
-                                                handleSend();
+                                <Dragger {...props}>
+                                    <p className="ant-upload-drag-icon">
+                                        <InboxOutlined />
+                                    </p>
+                                    <p className="ant-upload-text">请上传.docx格式文件</p>
+                                </Dragger>
+                            </div>
+                            <div style={{ margin: 5 }}>
+                                <Button
+                                    type='primary'
+                                    onClick={() => {
+                                        globalStore.setDocuments(fileList.map(item => {
+                                            return {
+                                                id: item.documentId,
+                                                name: item.name,
+                                                url: item.url,
                                             }
-                                        }}
-                                        onClick={(e) => e.stopPropagation()} // 阻止事件冒泡
-                                    />
-                                    
-                                    <div className='deekSeek-input-actions'>
-                                        <Button 
-                                            type='text' 
-                                            className='deekSeek-clear-button'
-                                            onClick={(e) => {
-                                                e.stopPropagation();
-                                                setUserInput('');
-                                            }}
-                                        >
-                                            ✕
-                                        </Button>
-                                        <Button 
-                                            type='primary' 
-                                            className='deekSeek-send-button'
-                                            onClick={(e) => {
-                                                e.stopPropagation();
-                                                handleSend();
-                                            }}
-                                        >
-                                            ✈️
-                                        </Button>
-                                    </div>
-                                </div>
+                                        }));
+                                        globalStore.setIsChatActive(true);
+                                    }}
+                                    disabled={fileList.filter(item => item.documentId).length === 0}
+                                >
+                                    开始解析
+                                </Button>
                             </div>
-                            
                             {/* 底部提示 */}
                             <div className='deekSeek-footer-text'>
                                 内容由AI生成,仅供参考
@@ -163,19 +156,11 @@ const DeekSeek: React.FC = () => {
                             <div className={isMobileScreen ? 'deekSeek-content-mobile' : 'deekSeek-content-pc'}>
                                 <Chat />
                             </div>
-                            {/* 返回按钮 */}
-                            <Button 
-                                className='deekSeek-back-button'
-                                onClick={resetToHome}
-                                style={{ marginTop: 20 }}
-                            >
-                                返回首页
-                            </Button>
                         </div>
                     )}
                 </div>
             </div>
-        </Spin>
+        </Spin >
     );
 };
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 693 - 689
app/components/DeepSeekChat.tsx


+ 0 - 1
app/components/deepSeekHome.scss

@@ -1,7 +1,6 @@
 .deekSeek {
   width: 100%;
   height: 100vh;
-  display: flex;
   background: #ffffff; /* 移除渐变背景,改为纯白色 */
 
   /* 主要区域 */

+ 3 - 5
app/components/home.tsx

@@ -228,17 +228,15 @@ function Screen() {
   const renderContent = () => {
     return (
       <>
-        {
-          location.pathname !== '/' &&
-          <SideBar className={styles["sidebar-show"]} />
-        }
+        <SideBar className={styles["sidebar-show"]} />
         <WindowContent>
           <Routes>
             <Route path='/' element={<HomeApp />} />
+            {/* <Route path='/' element={<DeepSeekChat />} /> */}
             <Route path='/knowledgeChat' element={<Chat />} />
             <Route path='/newChat' element={<Chat />} />
             <Route path='/deepseekChat' element={<DeepSeekChat />} />
-            <Route path='/newDeepseekChat' element={<DeepSeekChat />} />
+            <Route path='/newDeepseekChat' element={<HomeApp />} />
             {/* 关闭以下入口  后续有需求再开启*/}
             {/* <Route path='/settings' element={<Settings />} /> */}
             {/* <Route path='/mask-chat' element={<MaskChat />} /> */}

+ 20 - 107
app/components/sidebar.tsx

@@ -233,7 +233,7 @@ const AppDrawer: React.FC<AppDrawerProps> = (props) => {
       const res = await api.get(`/deepseek/api/project/app`);
       // 确保 res.data 是数组,如果不是则设为空数组
       const data = Array.isArray(res.data) ? res.data : [];
-      
+
       if (type === 'all') {
         setList(data);
       } else {
@@ -386,20 +386,8 @@ export const SideBar = (props: { className?: string }) => {
   // 获取聊天列表
   const fetchChatList = async (chatMode?: 'ONLINE' | 'LOCAL') => {
     try {
-      let url = '';
-      if (getType() === 'bigModel') {
-        const appId = globalStore.selectedAppId;
-        if (appId) {
-          if (chatMode === 'LOCAL') {
-            url = `/deepseek/api/dialog/list/${appId}`;
-          } else {
-            url = `/bigmodel/api/dialog/list/${appId}`;
-          }
-        }
-      } else {
-        const appId = '1881269958412521255';
-        url = `/bigmodel/api/dialog/list/${appId}`;
-      }
+      const appId = '2924812721300312064';
+      const url = `/deepseek/api/dialog/list/${appId}`;
       const res = await api.get(url);
       const list = res.data.map((item: any) => {
         return {
@@ -426,15 +414,7 @@ export const SideBar = (props: { className?: string }) => {
                   <a onClick={async () => {
                     try {
                       let blob = null;
-                      if (getType() === 'bigModel') {
-                        if (chatMode === 'LOCAL') {
-                          blob = await api.post(`/deepseek/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
-                        } else {
-                          blob = await api.post(`/bigmodel/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
-                        }
-                      } else {
-                        blob = await api.post(`/bigmodel/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
-                      }
+                      blob = await api.post(`/deepseek/api/dialog/export/${child.key}`, {}, { responseType: 'blob' });
                       const fileName = `${child.label}.xlsx`;
                       downloadFile(blob, fileName);
                     } catch (error) {
@@ -450,18 +430,8 @@ export const SideBar = (props: { className?: string }) => {
                 label: (
                   <a onClick={async () => {
                     try {
-                      if (getType() === 'bigModel') {
-                        if (chatMode === 'LOCAL') {
-                          await api.delete(`/deepseek/api/dialog/del/${child.key}`);
-                          await fetchChatList(chatMode);
-                        } else {
-                          await api.delete(`/bigmodel/api/dialog/del/${child.key}`);
-                          await fetchChatList();
-                        }
-                      } else {
-                        await api.delete(`/bigmodel/api/dialog/del/${child.key}`);
-                        await fetchChatList();
-                      }
+                      await api.delete(`/deepseek/api/dialog/del/${child.key}`);
+                      await fetchChatList(chatMode);
                       chatStore.clearSessions();
                       useChatStore.setState({
                         message: {
@@ -570,6 +540,7 @@ export const SideBar = (props: { className?: string }) => {
                 onClick={() => {
                   navigate({ pathname: '/' });
                 }}
+                disabled
               >
                 回到首页
               </Button>
@@ -580,14 +551,12 @@ export const SideBar = (props: { className?: string }) => {
                   chatStore.updateCurrentSession((value) => {
                     value.appId = globalStore.selectedAppId;
                   });
+                  globalStore.setIsChatActive(false);
+                  globalStore.setDocuments([]);
                   if (isMobileScreen) {
                     globalStore.setShowMenu(false);
                   }
-                  if (getType() === 'bigModel') {
-                    navigate({ pathname: '/newChat' });
-                  } else {
-                    navigate({ pathname: '/newDeepseekChat' });
-                  }
+                  navigate({ pathname: '/newDeepseekChat' });
                   if (getType() === 'bigModel') {
                     if (chatStore.chatMode === 'LOCAL') {
                       await fetchChatList(chatStore.chatMode);
@@ -602,28 +571,6 @@ export const SideBar = (props: { className?: string }) => {
                 新建对话
               </Button>
             </div>
-            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 10 }}>
-              <Button
-                style={{ width: '48%' }}
-                type="primary"
-                onClick={() => {
-                  setDrawerType('all');
-                  setDrawerOpen(true);
-                }}
-              >
-                我的应用
-              </Button>
-              <Button
-                style={{ width: '48%' }}
-                type="primary"
-                onClick={() => {
-                  setDrawerType('collect');
-                  setDrawerOpen(true);
-                }}
-              >
-                我的收藏
-              </Button>
-            </div>
           </SideBarHeader>
           <Menu
             style={{ border: 'none' }}
@@ -636,15 +583,7 @@ export const SideBar = (props: { className?: string }) => {
                 globalStore.setShowMenu(false);
               }
               let url = ``;
-              if (getType() === 'bigModel') {
-                if (chatStore.chatMode === 'LOCAL') {
-                  url = `/deepseek/api/dialog/detail/${key}`;
-                } else {
-                  url = `/bigmodel/api/dialog/detail/${key}`;
-                }
-              } else {
-                url = `/bigmodel/api/dialog/detail/${key}`;
-              }
+              url = `/deepseek/api/dialog/detail/${key}`;
               const res = await api.get(url);
               const list = res.data.map(((item: any) => {
                 return {
@@ -652,9 +591,7 @@ export const SideBar = (props: { className?: string }) => {
                   role: item.type,
                   date: item.create_time,
                   content: item.content,
-                  document: item.document ? item.document : undefined,
-                  sliceInfo: item.sliceInfo ? item.sliceInfo : undefined,
-                  networkInfo: item.networkInfo ? item.networkInfo : undefined,
+                  documents: item.documents ? item.documents : undefined,
                 }
               }))
               const session = {
@@ -663,6 +600,8 @@ export const SideBar = (props: { className?: string }) => {
                 id: res.data.length ? res.data[0].id : '',
                 messages: list,
               }
+              globalStore.setIsChatActive(true);
+              globalStore.setDocuments([]);
               globalStore.setCurrentSession(session);
               chatStore.clearSessions();
               chatStore.updateCurrentSession((value) => {
@@ -671,17 +610,7 @@ export const SideBar = (props: { className?: string }) => {
                 value.id = session.id;
                 value.messages = list;
               });
-              if (getType() === 'bigModel') {
-                const search = `?showMenu=${showMenu}&chatMode=${chatMode}&appId=${appId}`;
-                if (appId) {
-                  navigate({
-                    pathname: '/knowledgeChat',
-                    search: search,
-                  })
-                }
-              } else {
-                navigate({ pathname: '/newDeepseekChat' });
-              }
+              navigate({ pathname: '/newDeepseekChat' });
             }}
             mode="inline"
             items={menuList}
@@ -695,27 +624,11 @@ export const SideBar = (props: { className?: string }) => {
               form.validateFields().then(async (values) => {
                 setModalOpen(false);
                 try {
-                  if (getType() === 'bigModel') {
-                    if (chatStore.chatMode === 'LOCAL') {
-                      await api.put(`/deepseek/api/dialog/update`, {
-                        id: values.dialogId,
-                        dialogName: values.dialogName
-                      });
-                      await fetchChatList(chatStore.chatMode);
-                    } else {
-                      await api.put(`/bigmodel/api/dialog/update`, {
-                        id: values.dialogId,
-                        dialogName: values.dialogName
-                      });
-                      await fetchChatList();
-                    }
-                  } else {
-                    await api.put(`/bigmodel/api/dialog/update`, {
-                      id: values.dialogId,
-                      dialogName: values.dialogName
-                    });
-                    await fetchChatList();
-                  }
+                  await api.put(`/deepseek/api/dialog/update`, {
+                    id: values.dialogId,
+                    dialogName: values.dialogName
+                  });
+                  await fetchChatList(chatStore.chatMode);
                   chatStore.updateCurrentSession((value) => {
                     value.topic = values.dialogName;
                   });

+ 9 - 16
app/store/chat.ts

@@ -34,10 +34,11 @@ export type ChatMessage = RequestMessage & {
   isError?: boolean;
   id: string;
   model?: ModelType;
-  document?: {
+  documents?: {
     id: string,
+    name: string,
     url: string,
-  },
+  }[],
   sliceInfo?: {
     knowledge_id: string,
     doc: any[],
@@ -346,7 +347,11 @@ export const useChatStore = createPersistStore(
         get().summarizeSession();
       },
 
-      async onUserInput(fileList: any[], content: string, attachImages?: string[]) {
+      async onUserInput(documents: {
+        id: string,
+        name: string,
+        url: string,
+      }[], content: string, attachImages?: string[]) {
         const session = get().currentSession();
         const modelConfig = session.mask.modelConfig;
 
@@ -374,22 +379,10 @@ export const useChatStore = createPersistStore(
           );
         }
 
-        const document = {
-          id: '',
-          name: '',
-          url: '',
-        }
-
-        if (fileList.length) {
-          document.id = fileList[0].documentId;
-          document.name = fileList[0].name;
-          document.url = fileList[0].url;
-        }
-
         let userMessage: ChatMessage = createMessage({
           role: "user",
           content: mContent,
-          document: document,
+          documents: documents,
         });
 
         const botMessage: ChatMessage = createMessage({

+ 16 - 0
app/store/global.ts

@@ -1,6 +1,12 @@
 import { createPersistStore } from "../utils/store";
 
 const state = {
+  documents: [] as {
+    id: string,
+    name: string,
+    url: string,
+  }[],
+  isChatActive: true,
   showMenu: false,
   selectedAppId: "",
   currentSession: {
@@ -14,6 +20,16 @@ const state = {
 export const useGlobalStore = createPersistStore(
   { ...state },
   (set, get) => ({
+    setDocuments(list: {
+      id: string,
+      name: string,
+      url: string,
+    }[]) {
+      set({ documents: list });
+    },
+    setIsChatActive(status: boolean) {
+      set({ isChatActive: status });
+    },
     setShowMenu(status: boolean) {
       set({ showMenu: status });
     },

+ 2 - 2
next.config.mjs

@@ -92,11 +92,11 @@ if (mode !== "export") {
       },
       {
         source: "/bigmodel-api/:path*",
-        destination: "http://192.168.3.3:8091/:path*",
-        // destination: "http://192.168.3.123:8091/:path*",
+        destination: "http://192.168.3.123:8091/:path*",
       },
       {
         source: "/deepseek-api/:path*",
+        // destination: "http://xia0miduo.gicp.net:8000/:path*",
         destination: "http://192.168.3.209:18078/:path*",
       },
     ];

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio