From 362f28675972a8677cb267fc25e660abe8d401aa Mon Sep 17 00:00:00 2001
From: 14651 <14651@LAPTOP-TBEHTBNC>
Date: Thu, 14 Aug 2025 00:36:04 +0800
Subject: [PATCH] =?UTF-8?q?AI=E8=81=8A=E5=A4=A9=E6=9B=B4=E6=96=B0=E5=8E=86?=
=?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.trae/TODO.md | 7 +
api/aiChat/ai_index.js | 72 +-
components/aiChat/HistoryDrawer.vue | 624 ++++++++-------
pages/aiChat/ai_index.vue | 1106 ++++++++++++++++++---------
static/scss/ai_index.css | 32 +-
utils/ai_request.js | 6 +-
utils/ai_stream.js | 36 +-
7 files changed, 1181 insertions(+), 702 deletions(-)
create mode 100644 .trae/TODO.md
diff --git a/.trae/TODO.md b/.trae/TODO.md
new file mode 100644
index 0000000..3846d80
--- /dev/null
+++ b/.trae/TODO.md
@@ -0,0 +1,7 @@
+# TODO:
+
+- [x] 1: 分析控制台输出,确定API返回数据的正确结构 (priority: High)
+- [x] 2: 修复initChat方法中AI消息内容的数据映射 (priority: High)
+- [x] 3: 修复loadMoreHistory方法中的数据映射 (priority: High)
+- [x] 4: 移除调试代码,恢复正常UI显示 (priority: Medium)
+- [x] 5: 测试修复后的AI消息显示功能 (priority: Medium)
diff --git a/api/aiChat/ai_index.js b/api/aiChat/ai_index.js
index 9a813c5..0391abe 100644
--- a/api/aiChat/ai_index.js
+++ b/api/aiChat/ai_index.js
@@ -1,38 +1,78 @@
-// src/api/index.js
+// src/api/ai_index.js
// import request from '@/utils/ai_request.js'
-import request from "../../utils/ai_request";
+import request from "@/utils/ai_request.js";
// 获取历史
export const getHistory = ({
conversationId,
user,
- limit = 20
+ limit = 20,
+ beforeId
}) => {
+ const params = {
+ conversationId,
+ user,
+ limit
+ };
+
+ // 如果有beforeId参数,添加到请求中
+ if (beforeId) {
+ params.beforeId = beforeId;
+ }
+
return request({
url: '/aitutor/aichat/getMessagesToUser',
method: 'get',
- params: {
- conversationId,
- user,
- limit
- }
- // headers: {
- // Authorization: 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjBmMTY3NmY2LTgwOGMtNGUwMC04NDJjLWIwNmY1ZTM5NzJlNCJ9.VVc6OwQ-Xn9pxzYbPhlCpvDp6TwESS00gJi9IXUEIbFw4RFACZDmYCYjQ7voTM4fppy9SAMJCWT-L7Uy-K1eqw'
- // }
+ params
});
};
+
+// export const getHistory = ({
+// conversationId,
+// user,
+// limit = 20
+// }) => {
+// return request({
+// url: '/aitutor/aichat/getMessagesToUser',
+// method: 'get',
+// params: {
+// conversationId,
+// user,
+// limit
+// }
+// // headers: {
+// // Authorization: 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjBmMTY3NmY2LTgwOGMtNGUwMC04NDJjLWIwNmY1ZTM5NzJlNCJ9.VVc6OwQ-Xn9pxzYbPhlCpvDp6TwESS00gJi9IXUEIbFw4RFACZDmYCYjQ7voTM4fppy9SAMJCWT-L7Uy-K1eqw'
+// // }
+// });
+// };
+
// 点赞/点踩 action: 1 点赞 0 点踩
export const sendFeedback = ({
messageId,
- action
+ action,
+ user
}) => {
return request({
- url: '/api/chat/feedback',
+ url: '/aitutor/aichat/feedback',
method: 'post',
data: {
- messageId,
- action
+ message_id: messageId,
+ rating: action === 1 ? 'like' : 'dislike', // 添加rating参数
+ user
}
});
-};
\ No newline at end of file
+};
+// export const sendFeedback = ({
+// messageId,
+// action
+// }) => {
+// return request({
+// url: '/api/chat/feedback',
+// method: 'post',
+// data: {
+// messageId,
+// action
+// }
+// });
+// };
\ No newline at end of file
diff --git a/components/aiChat/HistoryDrawer.vue b/components/aiChat/HistoryDrawer.vue
index d8bd244..294c588 100644
--- a/components/aiChat/HistoryDrawer.vue
+++ b/components/aiChat/HistoryDrawer.vue
@@ -50,362 +50,350 @@
\ No newline at end of file
diff --git a/pages/aiChat/ai_index.vue b/pages/aiChat/ai_index.vue
index eb85b4b..51c19b0 100644
--- a/pages/aiChat/ai_index.vue
+++ b/pages/aiChat/ai_index.vue
@@ -1,8 +1,5 @@
-
-
-
@@ -14,16 +11,23 @@
智水AI辅导员
-
-
-
-
-
-
-
+
+
+
+ 正在加载历史记录...
+
+
+
+
+ 没有更多历史记录了
+
+
+
+
@@ -34,30 +38,30 @@
{{ item.content }}
+
-
- 引用来源:
-
-
-
-
- {{ ref.document_name }}
-
+ 引用来源:
+
+
+
+
+ {{ ref.document_name }}
+
-
-
- {{ ref.name }}({{ ref.document_name }})
- {{ ref.content }}
-
+
+
+ {{ ref.name }}({{ ref.document_name }})
+ {{ ref.content }}
+
回答由AI生成
@@ -97,361 +101,775 @@
\ No newline at end of file
diff --git a/static/scss/ai_index.css b/static/scss/ai_index.css
index b3da404..ef69e80 100644
--- a/static/scss/ai_index.css
+++ b/static/scss/ai_index.css
@@ -8,7 +8,7 @@
width: 100%;
overflow: hidden;
position: relative;
- background-color: #F5F5F5;
+ background-color: #f5f5f5;
padding-top: 10px;
/* 为固定导航栏预留空间 */
box-sizing: border-box;
@@ -45,6 +45,7 @@
color: #333;
text-align: center;
flex: 1;
+ margin-right: 45px;
}
.nav-icon {
@@ -166,7 +167,7 @@
background-color: #fff;
border-top: 1px solid #eee;
position: fixed;
- bottom: 0;
+ bottom: -1px;
left: 0;
width: 100%;
z-index: 10;
@@ -260,10 +261,9 @@
padding-left: 1em;
}
-
/* 可点击文档名 */
.doc-name-link {
- color: #007AFF;
+ color: #007aff;
text-decoration: underline;
margin-right: 16rpx;
font-size: 10rpx;
@@ -301,7 +301,7 @@
}
.doc-name-link {
- color: #007AFF;
+ color: #007aff;
text-decoration: underline;
margin-right: 16rpx;
font-size: clamp(13px, 3vw, 15px);
@@ -344,6 +344,28 @@
transform: scale(0.95);
}
+.loading-history {
+ text-align: center;
+ padding: 20rpx;
+ color: #999;
+ font-size: 28rpx;
+}
+
+.no-more-history {
+ text-align: center;
+ padding: 20rpx;
+ color: #ccc;
+ font-size: 24rpx;
+}
+
+.debug-info {
+ color: #888;
+ font-size: 12px;
+ margin-top: 5px;
+ border-top: 1px dashed #eee;
+ padding-top: 5px;
+}
+
/* ============= 小屏设备适配 ============= */
@media (max-width: 600px) {
.message-content {
diff --git a/utils/ai_request.js b/utils/ai_request.js
index 35b6a55..6ed62ee 100644
--- a/utils/ai_request.js
+++ b/utils/ai_request.js
@@ -6,9 +6,13 @@ import {
const service = axios.create({
// baseURL: 'http://localhost:9090/dev-api/aitutor/aichat',
- baseURL: 'http://localhost:8088/aitutor/aichat',
+ // baseURL: 'http://localhost:8088/aitutor/aichat',
// baseURL: 'http://localhost:8080/aitutor/aichat',
+ baseURL: 'http://localhost:8088',
timeout: 15000,
+ headers: {
+ 'Content-Type': 'application/json'
+ }
})
// 请求拦截器:统一加 token
diff --git a/utils/ai_stream.js b/utils/ai_stream.js
index e42ab93..ea8fd00 100644
--- a/utils/ai_stream.js
+++ b/utils/ai_stream.js
@@ -1,4 +1,4 @@
-// src/utils/ai_stream.js (H5 优化版)
+// src/utils/ai_stream.js
import {
getToken
} from '@/utils/auth';
@@ -23,7 +23,6 @@ export function createChatStream(params) {
const fetchPromise = fetch(url, {
method: 'POST',
headers: {
- 'Accept': 'text/event-stream',
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
'X-Request-ID': requestId
@@ -32,26 +31,27 @@ export function createChatStream(params) {
query: params.prompt,
user_id: params.userId,
user_name: params.userName,
- user_token: params.user_token || '123',
+ user_token: params.user_token || '123',
user_role: 'student',
- conversation_id: params.conversationId || null,
+ conversation_id: params.conversationId || null,
}),
signal: controller.signal
})
- .then(resp => {
- if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
- if (!resp.body) throw new Error('Response body is null');
- return resp.body;
+ .then(response => {
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
+ if (!response.body) throw new Error('Response body is null');
+ return {
+ reader: response.body.getReader(),
+ decoder: new TextDecoder('utf-8')
+ };
});
- return fetchPromise.then(body => ({
- stream: Promise.resolve({
- reader: body.getReader(),
- decoder: new TextDecoder('utf-8')
- }),
- cancel: reason => !controller.signal.aborted && controller.abort(reason)
- })).catch(err => ({
- stream: Promise.reject(err),
- cancel: () => {}
- }));
+ return {
+ stream: fetchPromise,
+ cancel: (reason) => {
+ if (!controller.signal.aborted) {
+ controller.abort(reason);
+ }
+ }
+ };
}
\ No newline at end of file