"use strict";
const common_vendor = require("../../common/vendor.js");
const pages_api_ai = require("../api/ai.js");
const pages_api_config = require("../api/config.js");
const common_assets = require("../../common/assets.js");
const _sfc_main = {
data() {
return {
inputMessage: "",
messages: [],
isLoading: false,
scrollTop: 0,
maxLength: 300,
userId: "user_123",
// 模拟用户ID
sessionId: "",
eventSource: null,
// SSE连接对象
pollingInterval: null,
// 轮询定时器
isConnected: false,
// SSE连接状态
isDevelopment: true,
// 控制测试按钮显示
// 快捷问题
quickQuestions: {
"重庆深度5日游": {
destination: "重庆",
days: 5,
budget: 3e3,
preferences: ["景点", "美食", "文化"],
transportation: "公共交通"
},
"推荐几个热门旅游城市": {
requestType: "recommendation",
preferences: ["热门", "旅游城市"]
},
"旅游注意事项有哪些": {
requestType: "travelTips",
preferences: ["安全", "注意事项"]
}
}
};
},
computed: {
// 用于显示除欢迎消息外的其他消息
displayMessages() {
if (this.messages.length === 0 || this.messages.length === 1 && this.messages[0].type === "ai") {
return [];
}
if (this.messages.length > 1 && this.messages[0].type === "ai") {
return this.messages.slice(1);
}
return this.messages;
}
},
onLoad(options) {
if (typeof __wxConfig !== "undefined") {
this.isDevelopment = __wxConfig.envVersion === "develop" || __wxConfig.envVersion === "trial";
}
try {
const savedMessages = common_vendor.index.getStorageSync("chat_messages");
if (savedMessages) {
this.messages = JSON.parse(savedMessages);
} else {
this.addMessage("您好,欢迎遇见Gooh旅记旅行规划师!我将为您设计专属行程,解答旅途中的各类问题,让旅行无忧。有任何想法,请随时告诉我~", "ai");
}
} catch (e) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:296", "加载消息历史失败:", e);
this.addMessage("您好,欢迎遇见Gooh旅记旅行规划师!我将为您设计专属行程,解答旅途中的各类问题,让旅行无忧。有任何想法,请随时告诉我~", "ai");
}
this.startSession();
},
onUnload() {
try {
common_vendor.index.setStorageSync("chat_messages", JSON.stringify(this.messages));
} catch (e) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:309", "保存消息历史失败:", e);
}
if (this.eventSource) {
this.eventSource.close();
}
this.stopPolling();
},
methods: {
// 返回旅游规划页面
goBack() {
common_vendor.index.switchTab({
url: "/pages/planning/index"
});
},
// 创建新对话
async createNewChat() {
if (this.eventSource) {
try {
this.eventSource.close();
this.eventSource = null;
} catch (e) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:337", "关闭SSE连接失败:", e);
}
}
if (this.pollingInterval) {
clearInterval(this.pollingInterval);
this.pollingInterval = null;
}
this.messages = [];
this.inputMessage = "";
this.sessionId = "";
await this.startSession();
common_vendor.index.showToast({
title: "已创建新对话",
icon: "none"
});
},
// 开始新会话
async startSession() {
try {
const response = await pages_api_ai.startAISession();
if (response && response.code === 200 && response.sessionId) {
this.sessionId = response.sessionId;
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:368", "会话创建成功,sessionId:", this.sessionId);
if (response.msg && this.messages.length === 0) {
this.addMessage(response.msg, "ai");
}
if (this.sessionId) {
await this.setupWebSocket();
} else {
throw new Error("未获取到有效的sessionId");
}
} else {
throw new Error((response == null ? void 0 : response.msg) || "创建会话失败");
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:386", "创建会话失败:", error);
common_vendor.index.showToast({
title: error.message || "连接失败,请重试",
icon: "none"
});
}
},
// 设置SSE连接
async setupWebSocket() {
if (!this.sessionId) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:397", "无法建立SSE连接:sessionId不存在");
return;
}
const url = pages_api_ai.getSSEUrl(this.sessionId);
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:403", "尝试连接SSE:", url);
if (this.eventSource) {
try {
this.eventSource.close();
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:409", "已关闭旧的SSE连接");
} catch (e) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:411", "关闭旧SSE连接失败:", e);
}
this.eventSource = null;
}
return new Promise((resolve, reject) => {
try {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:418", "开始创建SSE连接...");
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:465", "在小程序环境下使用替代方法连接SSE");
this.isConnected = true;
this.setupPolling();
resolve();
setTimeout(() => {
if (!this.isConnected) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:476", "SSE连接超时");
reject(new Error("SSE连接超时"));
}
}, 1e4);
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:488", "创建SSE连接时发生错误:", error);
reject(error);
}
});
},
// 处理WebSocket消息
handleSocketMessage(res) {
try {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:497", "开始处理WebSocket消息:", res.data);
let data;
try {
data = JSON.parse(res.data);
} catch (parseError) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:505", "WebSocket数据不是JSON格式,尝试作为纯文本处理");
data = {
type: "message",
content: res.data
};
}
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:512", "处理后的WebSocket消息数据:", data);
if (!data.type && data.content) {
data.type = "message";
}
switch (data.type) {
case "start":
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:521", "收到start类型消息");
if (this.messages.length > 0 && this.messages[this.messages.length - 1].type === "user") {
this.addMessage("AI正在思考...", "ai", true);
}
this.setupPolling();
break;
case "message":
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:532", "收到message类型消息:", data.content);
if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
this.messages.pop();
}
if (data.content) {
const isPlanContent = this.checkIfTravelPlanContent(data.content);
if (isPlanContent) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:540", "检测到旅游行程信息,解析为卡片显示");
const planData = this.parseTravelPlanContent(data.content);
this.addTravelPlanMessage(planData);
} else {
let formattedContent = this.formatAIResponse(data.content);
this.addMessage(formattedContent, "ai");
}
}
break;
case "done":
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:550", "收到done类型消息");
if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
this.messages.pop();
}
this.isLoading = false;
this.stopPolling();
break;
case "error":
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:561", "收到error类型消息:", data.content);
if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
this.messages.pop();
}
this.addMessage(`错误: ${data.content}`, "ai");
this.isLoading = false;
common_vendor.index.showToast({
title: "发生错误,请重试",
icon: "none"
});
this.stopPolling();
break;
default:
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:577", "收到未知类型消息:", data);
if (data.content || typeof data === "string" && data) {
const content = data.content || data;
if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
this.messages.pop();
}
let formattedContent = this.formatAIResponse(content);
this.addMessage(formattedContent, "ai");
}
break;
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:590", "处理WebSocket消息失败:", error);
this.isLoading = false;
try {
let content = res.data;
if (typeof content === "string" && content.length > 0) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:598", "尝试直接显示原始消息内容");
if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
this.messages.pop();
}
let formattedContent = this.formatAIResponse(content);
this.addMessage(formattedContent, "ai");
return;
}
} catch (e) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:607", "尝试直接显示消息内容也失败:", e);
}
if (this.messages.length > 0 && this.messages[this.messages.length - 1].isThinking) {
this.messages.pop();
}
this.addMessage("消息处理出错,请重试", "ai");
}
},
// 设置轮询 - 仅当需要时才开始轮询,有结果就停止
setupPolling() {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:619", "设置轮询检查");
this.stopPolling();
this.pollingCount = 0;
const maxPollingCount = 20;
this.pollingInterval = setInterval(async () => {
try {
this.pollingCount++;
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:631", `第${this.pollingCount}次轮询检查`);
if (!this.isLoading || this.pollingCount > maxPollingCount) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:635", "条件不满足,停止轮询:", {
isLoading: this.isLoading,
pollingCount: this.pollingCount
});
this.stopPolling();
return;
}
const response = await pages_api_ai.getLastAIReply(this.sessionId);
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:645", "轮询结果:", response);
if (response && response.code === 200 && response.reply) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:649", "轮询发现新消息");
this.handleSocketMessage({
data: JSON.stringify({
type: "message",
content: response.reply
})
});
setTimeout(() => {
this.handleSocketMessage({
data: JSON.stringify({
type: "done"
})
});
}, 500);
this.stopPolling();
}
} catch (err) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:670", "轮询出错:", err);
this.pollingErrorCount = (this.pollingErrorCount || 0) + 1;
if (this.pollingErrorCount > 3) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:675", "轮询错误太多,停止轮询");
this.stopPolling();
}
}
}, 3e3);
},
// 停止轮询
stopPolling() {
if (this.pollingInterval) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:685", "停止轮询");
clearInterval(this.pollingInterval);
this.pollingInterval = null;
this.pollingCount = 0;
this.pollingErrorCount = 0;
}
},
// 发送消息
async sendMessage() {
if (!this.inputMessage.trim() || this.isLoading)
return;
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:697", "准备发送消息:", this.inputMessage);
if (!this.sessionId) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:701", "sessionId不存在,先创建新会话");
try {
const response = await pages_api_ai.startAISession();
if (response && response.code === 200 && response.sessionId) {
this.sessionId = response.sessionId;
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:706", "新会话创建成功,sessionId:", this.sessionId);
} else {
throw new Error("创建会话失败");
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:711", "创建会话失败:", error);
common_vendor.index.showToast({
title: "创建会话失败,请重试",
icon: "none"
});
return;
}
}
if (this.inputMessage.length > this.maxLength) {
common_vendor.index.showToast({
title: `消息不能超过${this.maxLength}字`,
icon: "none"
});
return;
}
const messageToSend = this.inputMessage.trim();
this.inputMessage = "";
this.addMessage(messageToSend, "user");
this.isLoading = true;
try {
if (!this.isConnected) {
common_vendor.index.__f__("warn", "at pages/ai-assistant/index.vue:741", "SSE未连接,尝试重新连接");
await this.setupWebSocket();
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:743", "SSE重连状态:", this.isConnected ? "已连接" : "未连接");
}
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:747", "发送消息到服务器:", {
sessionId: this.sessionId,
message: messageToSend
});
const response = await pages_api_ai.chatWithAI(this.sessionId, messageToSend);
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:754", "服务器响应:", response);
if (response.code === 200) {
if (response.msg) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:759", "服务器返回的消息:", response.msg);
let formattedContent = this.formatAIResponse(response.msg);
this.addMessage(formattedContent, "ai");
} else {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:764", "服务器未返回消息,等待WebSocket响应");
}
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:769", "小程序环境中启动轮询检查");
this.setupPolling();
} else if (response.code === 404) {
common_vendor.index.__f__("warn", "at pages/ai-assistant/index.vue:773", "会话不存在,尝试重新开始会话");
const newSessionResponse = await pages_api_ai.startAISession();
if (newSessionResponse && newSessionResponse.code === 200 && newSessionResponse.sessionId) {
this.sessionId = newSessionResponse.sessionId;
const retryResponse = await pages_api_ai.chatWithAI(this.sessionId, messageToSend);
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:779", "重试响应:", retryResponse);
if (retryResponse.code === 200) {
if (retryResponse.msg) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:784", "重试后服务器返回的消息:", retryResponse.msg);
let formattedContent = this.formatAIResponse(retryResponse.msg);
this.addMessage(formattedContent, "ai");
}
} else {
throw new Error(retryResponse.msg || "重试发送失败");
}
} else {
throw new Error("重新创建会话失败");
}
} else {
throw new Error(response.msg || "发送失败");
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:798", "发送消息失败:", error);
common_vendor.index.showToast({
title: error.message || "发送失败,请重试",
icon: "none"
});
this.addMessage("抱歉,发送消息失败,请重试。", "ai");
} finally {
this.isLoading = false;
}
},
// 处理快捷问题
async handleQuickQuestion(question) {
if (this.isLoading)
return;
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:813", "处理快捷问题:", question);
this.isLoading = true;
try {
if (!this.sessionId) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:819", "sessionId不存在,先创建新会话");
try {
const response2 = await pages_api_ai.startAISession();
if (response2 && response2.code === 200 && response2.sessionId) {
this.sessionId = response2.sessionId;
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:824", "新会话创建成功,sessionId:", this.sessionId);
} else {
throw new Error("创建会话失败");
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:829", "创建会话失败:", error);
common_vendor.index.showToast({
title: "创建会话失败,请重试",
icon: "none"
});
this.isLoading = false;
return;
}
}
this.addMessage(question, "user");
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:843", "发送快捷问题到服务器:", {
sessionId: this.sessionId,
message: question
});
const response = await pages_api_ai.chatWithAI(this.sessionId, question);
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:849", "快捷问题服务器响应:", response);
if (response.code === 200) {
if (response.msg) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:854", "服务器返回的消息:", response.msg);
let formattedContent = this.formatAIResponse(response.msg);
this.addMessage(formattedContent, "ai");
} else {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:859", "服务器未返回消息,等待WebSocket响应");
}
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:864", "小程序环境中启动轮询检查");
this.setupPolling();
} else if (response.code === 404) {
common_vendor.index.__f__("warn", "at pages/ai-assistant/index.vue:868", "会话不存在,尝试重新开始会话");
this.addMessage("会话已过期,正在重新创建会话...", "system");
const newSessionResponse = await pages_api_ai.startAISession();
if (newSessionResponse && newSessionResponse.code === 200 && newSessionResponse.sessionId) {
this.sessionId = newSessionResponse.sessionId;
this.handleQuickQuestion(question);
} else {
throw new Error("重新创建会话失败");
}
} else {
throw new Error(response.msg || "发送失败");
}
} catch (error) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:883", "处理快捷问题失败:", error);
common_vendor.index.showToast({
title: error.message || "发送失败,请重试",
icon: "none"
});
this.addMessage("抱歉,处理问题失败,请重试。", "ai");
} finally {
this.isLoading = false;
}
},
// 添加消息
addMessage(content, type, isThinking = false) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:896", "添加新消息:", { content, type, isThinking });
if (type === "user") {
content = content.replace(//g, ">");
}
const message = {
type,
content,
isThinking,
timestamp: Date.now()
};
if (!isThinking && this.messages.length > 0) {
const lastMessage = this.messages[this.messages.length - 1];
if (lastMessage.isThinking && lastMessage.type === type) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:914", "替换思考状态消息");
this.messages.splice(-1, 1);
}
}
this.messages.push(message);
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:920", "当前消息列表:", this.messages);
try {
common_vendor.index.setStorageSync("chat_messages", JSON.stringify(this.messages));
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:925", "消息已保存到本地存储");
} catch (e) {
common_vendor.index.__f__("error", "at pages/ai-assistant/index.vue:927", "保存消息到本地存储失败:", e);
}
this.$nextTick(() => {
this.scrollToBottom();
});
},
// 滚动到底部
scrollToBottom() {
const query = common_vendor.index.createSelectorQuery().in(this);
query.select(".message-list").boundingClientRect((data) => {
if (data) {
this.scrollTop = data.height;
}
}).exec();
},
// 格式化时间
formatTime(timestamp) {
if (!timestamp)
return "";
const date = new Date(timestamp);
const hours = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
return `${hours}:${minutes}`;
},
// 加载更多消息
loadMoreMessages() {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:958", "加载更多消息");
},
// 格式化AI响应的方法增加日志
formatAIResponse(content) {
common_vendor.index.__f__("log", "at pages/ai-assistant/index.vue:963", "开始格式化AI响应:", content);
content = content.replace(/\d+e\d+;margin:[\s\d]+px[\s\d]+px[\s\d]+;"/g, '"');
content = content.replace(/\n/g, "
");
content = content.replace(/最佳旅行时间[::]/g, '