diff --git a/manager/LoginManager.js b/manager/LoginManager.js
index 2b66d4f..1fd4a5a 100644
--- a/manager/LoginManager.js
+++ b/manager/LoginManager.js
@@ -15,7 +15,8 @@ export async function loginAuth() {
password: 'YehdBPev'
});
if (response.access_token) {
- return response.data;
+ uni.setStorageSync('token', response.access_token)
+ return response;
} else {
throw new Error(response.message || '登录失败');
}
diff --git a/pages/chat/ChatCardAI.vue b/pages/chat/ChatCardAI.vue
index 0c14f53..cd19f2f 100644
--- a/pages/chat/ChatCardAI.vue
+++ b/pages/chat/ChatCardAI.vue
@@ -19,6 +19,7 @@
.chat-ai {
margin: 6px 12px;
padding: 16px;
+ min-width: 60px;
background: rgba(255,255,255,0.4);
box-shadow: 2px 2px 10px 0px rgba(0,0,0,0.1);
diff --git a/pages/chat/ChatMainList.vue b/pages/chat/ChatMainList.vue
index 988e6a7..5388cb9 100644
--- a/pages/chat/ChatMainList.vue
+++ b/pages/chat/ChatMainList.vue
@@ -21,20 +21,10 @@
-
-
-
-
-
-
-
+
-
-
-
-
@@ -83,6 +73,7 @@
import { MessageRole, ChatModel, MessageType } from '../../model/ChatModel';
import OneFeelMK001 from '../module/OneFeelMK001.vue';
+ import request from '../../request/base/request';
// 导航栏相关
const statusBarHeight = ref(20);
@@ -175,19 +166,8 @@
}
chatMsgList.value.push(newMsg)
-
- let type = chatMsgList.value.length % 3 === 0
-
- const newMsgAI: ChatModel = {
- msgId: `msg_${chatMsgList.value.length}`,
- msgType: MessageRole.AI,
- msg: `我是ai,你输入的内容是:${text}`,
- msgContent: {
- type: type ? MessageType.IMAGE : MessageType.TEXT,
- url: ''
- }
- }
- chatMsgList.value.push(newMsgAI)
+
+ sendChat('酒店一共有哪些温泉?')
console.log("发送的新消息:",JSON.stringify(newMsg))
}
@@ -201,6 +181,94 @@
});
}
+ let loadingTimer: any = null;
+ let typeWriterTimer: any = null;
+ let aiMsgBuffer = ''; // 全局缓冲区
+ let isTyping = false; // 是否正在打字
+
+ const sendChat = (text) => {
+
+ console.log('=============会话测试')
+ const args = {
+ conversationId: "1931957498711957505",
+ agentId: "1",
+ messageType: 0,
+ messageContent: text
+ }
+
+ // 1. 插入AI消息
+ const aiMsg: ChatModel = {
+ msgId: `msg_${chatMsgList.value.length}`,
+ msgType: MessageRole.AI,
+ msg: '加载中.',
+ msgContent: {
+ type: MessageType.TEXT,
+ url: ''
+ }
+ }
+ chatMsgList.value.push(aiMsg)
+ const aiMsgIndex = chatMsgList.value.length - 1
+
+ // 动态加载中动画
+ let dotCount = 1;
+ loadingTimer && clearInterval(loadingTimer);
+ loadingTimer = setInterval(() => {
+ dotCount = dotCount % 3 + 1;
+ chatMsgList.value[aiMsgIndex].msg = '加载中' + '.'.repeat(dotCount);
+ }, 400);
+
+ aiMsgBuffer = '';
+ isTyping = false;
+ if (typeWriterTimer) {
+ clearTimeout(typeWriterTimer);
+ typeWriterTimer = null;
+ }
+
+ // 2. 流式接收内容
+ request.getAIChatStream(args, (chunk) => {
+ console.log('分段内容:', chunk)
+ if (chunk && chunk.content) {
+ // 收到内容,停止动画
+ if (loadingTimer) {
+ clearInterval(loadingTimer);
+ loadingTimer = null;
+ }
+ // 把新内容追加到缓冲区
+ aiMsgBuffer += chunk.content;
+
+ // 启动打字机(只启动一次)
+ if (!isTyping) {
+ isTyping = true;
+ chatMsgList.value[aiMsgIndex].msg = '';
+ typeWriter();
+ }
+ }
+ if (chunk && chunk.finish) {
+ // 结尾处理:确保剩余内容全部输出
+ const finishInterval = setInterval(() => {
+ if (aiMsgBuffer.length === 0) {
+ clearInterval(finishInterval);
+ isTyping = false;
+ scrollToBottom();
+ }
+ }, 50);
+ }
+ });
+
+ // 打字机函数
+ function typeWriter() {
+ if (aiMsgBuffer.length > 0) {
+ chatMsgList.value[aiMsgIndex].msg += aiMsgBuffer[0];
+ aiMsgBuffer = aiMsgBuffer.slice(1);
+ scrollToBottom();
+ typeWriterTimer = setTimeout(typeWriter, 30);
+ } else {
+ // 等待新内容到来,不结束
+ typeWriterTimer = setTimeout(typeWriter, 30);
+ }
+ }
+ }
+
diff --git a/pages/drawer/DrawerHome.vue b/pages/drawer/DrawerHome.vue
index d9fe506..eb96131 100644
--- a/pages/drawer/DrawerHome.vue
+++ b/pages/drawer/DrawerHome.vue
@@ -6,6 +6,8 @@
+
+
{{item}}
@@ -20,6 +22,9 @@
const emits = defineEmits(['closeDrawer'])
import * as loginMnager from '@/manager/LoginManager'
+ import { getAgentChatMessage } from '@/request/api/AgentChatApi.js'
+import request from '../../request/base/request'
+
const closeDrawer = () => {
emits('closeDrawer')
console.log('=============关闭抽屉')
@@ -37,7 +42,26 @@
})
console.log('=============登录')
// 这里可以处理登录逻辑,比如调用登录接口等
- }
+ }
+
+ const sendChat = () => {
+ console.log('=============会话测试')
+
+ const args = {
+ "conversationId":"1931957498711957505",
+ "agentId":"1",
+ "messageType": 0,
+ "messageContent":"酒店一共有哪些温泉?"
+ }
+
+
+
+ request.getAIChatStream(args, (chunk) => {
+ // 每收到一段数据都会回调
+ console.log('分段内容:', chunk)
+ // 你可以在这里追加到消息列表
+ })
+ }
diff --git a/request/api/AgentChatApi.js b/request/api/AgentChatApi.js
new file mode 100644
index 0000000..d477c0a
--- /dev/null
+++ b/request/api/AgentChatApi.js
@@ -0,0 +1,19 @@
+import request from "../base/request";
+
+function getAgentChatMessage() {
+ const args = {
+ "conversationId":"1931957498711957505",
+ "agentId":"1",
+ "messageType": 0,
+ "messageContent":"酒店一共有哪些温泉?"
+ }
+ const defaultConfig = {
+ header: {
+ Accept: 'text/event-stream',
+ 'Content-Type': 'application/json'
+ },
+ };
+ return request.post('/agent/assistant/chat', args, defaultConfig);
+}
+
+export { getAgentChatMessage }
\ No newline at end of file
diff --git a/request/base/request.js b/request/base/request.js
index b1b26ce..5e2116d 100644
--- a/request/base/request.js
+++ b/request/base/request.js
@@ -14,6 +14,7 @@ function request(url, args = {}, method = 'POST', customConfig = {}) {
}
// 动态获取 token
const token = uni.getStorageSync('token');
+
let header = {
...defaultConfig.header,
...customConfig.header
@@ -23,9 +24,12 @@ function request(url, args = {}, method = 'POST', customConfig = {}) {
delete header.Authorization;
} else {
if (token) {
- header.Authorization = `Basic ${token}`;
+ header.Authorization = `Bearer ${token}`;
}
}
+
+ console.log("请求头customConfig:" + JSON.stringify(customConfig))
+
const config = {
...defaultConfig,
...customConfig,
@@ -54,8 +58,8 @@ function request(url, args = {}, method = 'POST', customConfig = {}) {
}
// 默认 POST
-request.post = function(url, args = {}) {
- return request(url, args, 'POST');
+request.post = function(url, args = {}, config = {}) {
+ return request(url, args, 'POST', config);
};
// 支持 GET
@@ -63,4 +67,77 @@ request.get = function(url, args = {}) {
return request(url, args, 'GET');
};
+/**
+ * 获取AI聊天流式信息(仅微信小程序支持)
+ * @param {Object} params 请求参数
+ * @param {Function} onChunk 回调,每收到一段数据触发
+ * @returns {Promise}
+ */
+request.getAIChatStream = function(params, onChunk) {
+ return new Promise((resolve, reject) => {
+ const token = uni.getStorageSync('token');
+
+ console.log("发送请求内容: ", params)
+ // #ifdef MP-WEIXIN
+ const requestTask = uni.request({
+ url: BASE_URL + '/agent/assistant/chat', // 替换为你的接口地址
+ method: 'POST',
+ data: params,
+ enableChunked: true,
+ header: {
+ Accept: 'text/event-stream',
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${token}`, // 如需token可加
+ },
+ responseType: 'arraybuffer',
+ success(res) {
+ resolve(res.data);
+ },
+ fail(err) {
+ reject(err);
+ }
+ });
+
+ requestTask.onHeadersReceived(res => {
+ console.log('onHeadersReceived', res);
+ });
+
+ requestTask.onChunkReceived(res => {
+ const base64 = uni.arrayBufferToBase64(res.data);
+ let data = '';
+ try {
+ data = decodeURIComponent(escape(atob(base64)));
+ } catch (e) {
+ // 某些平台可能不支持 atob,可以直接用 base64
+ data = base64;
+ }
+ const messages = parseSSEChunk(data);
+ messages.forEach(msg => {
+ if (onChunk) onChunk(msg);
+ });
+ });
+ // #endif
+ });
+}
+
+// 解析SSE分段数据
+function parseSSEChunk(raw) {
+ // 拆分为多段
+ const lines = raw.split('\n\n');
+ const results = [];
+ lines.forEach(line => {
+ // 只处理包含 data: 的行
+ const dataMatch = line.match(/data:(\{.*\})/);
+ if (dataMatch && dataMatch[1]) {
+ try {
+ const obj = JSON.parse(dataMatch[1]);
+ results.push(obj);
+ } catch (e) {
+ // 解析失败忽略
+ }
+ }
+ });
+ return results;
+}
+
export default request;
\ No newline at end of file