2 Commits fd0e2a9ab3 ... 8d1f762dc9

Auteur SHA1 Bericht Datum
  hizhangling 8d1f762dc9 [feat][ai问答][实现fetch请求流式输出] 3 weken geleden
  hizhangling 87485ddebd [feat][ai问答][增加页面] 3 weken geleden

+ 9 - 0
src/api/xjc-integratedmachine/common/aiChat.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+export function getAiChatRecordList(data) {
+    return request({
+        url: '/ai/chat/list',
+        method: 'get',
+        params : data
+    })
+}

+ 2 - 1
src/router/index.js

@@ -6,6 +6,7 @@ import router_cognize from '@/router/router_cognize.js'
 import router_decision from '@/router/router_decision.js'
 import router_environment from '@/router/router_environment.js'
 import router_plan from '@/router/router_plan.js'
+import router_common from '@/router/router_common.js'
 
 // 公共路由
 export const constantRoutes = [
@@ -180,7 +181,7 @@ export const dynamicRoutes = [
     }
 ]
 const routerArrs = [...router_wakeup.router, ...router_cognize.router, ...router_decision.router,
-    ...router_environment.router, ...router_plan.router, ...constantRoutes]
+    ...router_environment.router, ...router_plan.router, ...router_common.router, ...constantRoutes]
 
 /**
  * Note: 路由配置项

+ 1 - 1
src/router/router_common.js

@@ -1,7 +1,7 @@
 const router = [
     //AI智能问答
     {
-        path: '/xjc-integratedmachine/common/ai_chat',
+        path: '/xjc-integratedmachine/common/ai/chat',
         component: () => import('@/views/xjc-integratedmachine/common/ai/chat.vue'),
     },
 

+ 117 - 2
src/views/xjc-integratedmachine/common/ai/chat.vue

@@ -1,7 +1,102 @@
 <template>
-    
+    <div>
+        <div class="content-box">
+            <pre>{{ streamData }}</pre>
+            <span class="dot"></span>
+            <span class="dot"></span>
+        </div>
+
+        <el-button @click="stopMessage">停止回答</el-button>
+    </div>
 </template>
 
+<script setup>
+    import {getAiChatRecordList} from '@/api/xjc-integratedmachine/common/aiChat.js'
+    import { getToken } from '@/utils/auth'
+
+    let data = ref()
+    const streamData = ref(''); // 存储流式数据
+    const isLoading = ref(false); // 加载状态
+    let reader = null; // 读取器实例
+    let controller = null; // AbortController用于中止请求
+
+
+    // 查看所有聊天记录
+    list();
+    function list() {
+        getAiChatRecordList().then(resp =>{
+            console.log(resp)
+            data.value = resp;
+        })
+    }
+
+    const sendMessage = async() => {
+        try{
+            isLoading.value = true;
+            streamData.value = ''; // 清空之前的数据
+
+            // 创建AbortController以便可以中止请求
+            controller = new AbortController();
+
+            // 请求体
+            let form = {
+                "content": "你是谁?"
+            }
+            // 发送fetch请求
+            const response = await fetch('/dev-api/ai/chat/stream', {
+                method: 'POST',
+                headers: {
+                    'Content-Type': 'application/json',
+                    'Authorization': 'Bearer ' + getToken()
+                },
+                body: JSON.stringify(form)
+            });
+
+            // 获取可读流的读取器
+            reader = response.body.getReader();
+            const decoder = new TextDecoder('utf-8');
+
+            // 循环读取流数据
+            while (true) {
+                const { done, value } = await reader.read();
+                if (done) break; // 如果流读取完成则退出循环
+
+                // 解码并追加数据
+                let chunk = decoder.decode(value, { stream: true });
+                chunk = chunk.replace(/\n/g, '').replace(/data:/g, '')
+                streamData.value += chunk;
+            }
+        }catch (error) {
+            // 如果是手动中止,不显示错误
+            if (error.name !== 'AbortError') {
+                console.error('流式读取失败:', error);
+                streamData.value = 'Error: ' + error.message;
+            }
+        } finally {
+            isLoading.value = false;
+        }
+    }
+
+    const stopMessage = () => {
+        if (reader) {
+            // 取消读取
+            reader.cancel().catch(() => {});
+            reader = null;
+        }
+        if (controller) {
+            // 中止请求
+            controller.abort();
+            controller = null;
+        }
+        isLoading.value = false;
+    }
+
+    onMounted(()=>{
+        sendMessage()
+    })
+
+</script>
+
 <script>
     export default {
         name: "chat"
@@ -9,5 +104,25 @@
 </script>
 
 <style scoped>
-
+    .content-box {
+        max-height: 300px;
+        overflow-y: auto;
+        border: 1px solid #eee;
+        padding: 10px;
+        margin-top: 10px;
+        background: #f9f9f9;
+    }
+    pre {
+        white-space: pre-wrap;
+        word-wrap: break-word;
+    }
+    .dot {
+        display: inline-block;
+        margin-left: 5px;
+        width: 8px;
+        height: 8px;
+        background-color: #000000;
+        border-radius: 50%;
+        animation: pulse 1.2s infinite ease-in-out both;
+    }
 </style>