diff --git a/api/ai-agent/src/main/java/cn/qihangerp/erp/controller/SseController.java b/api/ai-agent/src/main/java/cn/qihangerp/erp/controller/SseController.java index 74c85647..5523c787 100644 --- a/api/ai-agent/src/main/java/cn/qihangerp/erp/controller/SseController.java +++ b/api/ai-agent/src/main/java/cn/qihangerp/erp/controller/SseController.java @@ -72,8 +72,17 @@ public class SseController { // 使用AiService处理消息,传递模型参数 String response = aiService.processMessage(message, model); log.info("==========AI回复:{}",response); - // 将响应消息包装成JSON格式 - String jsonResponse = String.format("{\"text\": \"%s\"}", response.replace("\"", "\\\"").replace("\n", "\\n")); + + // 检查响应是否已经是JSON格式(以{开头) + String jsonResponse; + if (response.trim().startsWith("{")) { + // 如果是JSON格式,直接使用 + jsonResponse = response; + } else { + // 否则包装成JSON格式 + jsonResponse = String.format("{\"text\": \"%s\"}", response.replace("\"", "\\\"").replace("\n", "\\n")); + } + // 发送JSON格式的消息 emitter.send(SseEmitter.event() .name("message") diff --git a/api/ai-agent/src/main/java/cn/qihangerp/erp/serviceImpl/AiService.java b/api/ai-agent/src/main/java/cn/qihangerp/erp/serviceImpl/AiService.java index d2410140..f966ddc1 100644 --- a/api/ai-agent/src/main/java/cn/qihangerp/erp/serviceImpl/AiService.java +++ b/api/ai-agent/src/main/java/cn/qihangerp/erp/serviceImpl/AiService.java @@ -29,6 +29,11 @@ public class AiService { */ public String processMessage(String message, String model) { try { + // 检查是否包含打开页面的指令 + if (message.contains("打开店铺管理") || message.contains("进入店铺管理") || message.contains("前往店铺管理")) { + return "{\"action\": \"navigate\", \"route\": \"/shop/shop_list\", \"message\": \"正在跳转到店铺管理页面\"}"; + } + // 获取当前日期 String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); diff --git a/vue/src/views/index.vue b/vue/src/views/index.vue index 416e1981..b6212b66 100644 --- a/vue/src/views/index.vue +++ b/vue/src/views/index.vue @@ -222,89 +222,6 @@ export default { }, 1000); }); - // 处理消息缓冲区 - this.processMessageBuffer = function() { - // 清除超时定时器 - if (this.messageTimeout) { - clearTimeout(this.messageTimeout); - this.messageTimeout = null; - } - - // 移除所有data:前缀 - let messageContent = this.messageBuffer.replace(/^data:/gm, ''); - // 移除末尾的空行 - messageContent = messageContent.trim(); - - // 只有当消息内容不为空时才处理 - if (messageContent) { - try { - // 解析JSON数据 - const jsonData = JSON.parse(messageContent); - let textContent = jsonData.text || messageContent; - - // 检查是否包含订单信息,转换为表格格式 - if (textContent.includes('订单号:') || textContent.includes('订单详情')) { - // 提取订单信息并转换为表格 - textContent = this.convertOrderToTable(textContent); - } - - // 移除正在思考的消息 - if (this.isLoading) { - this.messages = this.messages.filter(msg => !msg.isLoading); - this.isLoading = false; - } - - // 使用markdown-it将markdown格式转换为HTML - const htmlContent = this.md.render(textContent); - this.messages.push({ - content: htmlContent, - time: this.formatTime(new Date()), - isMe: false, - avatar: '' - }); - this.scrollToBottom(); - } catch (e) { - console.error('解析SSE消息失败:', e); - // 移除正在思考的消息 - if (this.isLoading) { - this.messages = this.messages.filter(msg => !msg.isLoading); - this.isLoading = false; - } - - // 使用markdown-it将markdown格式转换为HTML - const htmlContent = this.md.render(messageContent); - this.messages.push({ - content: htmlContent, - time: this.formatTime(new Date()), - isMe: false, - avatar: '' - }); - this.scrollToBottom(); - } - } - - // 清空缓冲区 - this.messageBuffer = ''; - }; - - // 将订单信息转换为markdown表格 - this.convertOrderToTable = function(text) { - // 提取订单信息 - const orderMatches = text.match(/订单号:\s*(\S+)/); - const dateMatches = text.match(/日期:\s*(\S+)/); - const customerMatches = text.match(/客户:\s*(\S+)/); - const amountMatches = text.match(/金额:\s*(\S+)/); - const statusMatches = text.match(/状态:\s*(\S+)/); - - if (orderMatches && dateMatches && customerMatches && amountMatches && statusMatches) { - // 构建markdown表格 - return `| 订单号 | 日期 | 客户 | 金额 | 状态 | -| --- | --- | --- | --- | --- | -| ${orderMatches[1]} | ${dateMatches[1]} | ${customerMatches[1]} | ${amountMatches[1]} | ${statusMatches[1]} |`; - } - return text; - }; - // 监听心跳 this.sse.addEventListener('heartbeat', (event) => { console.log('收到心跳:', event.data); @@ -418,6 +335,122 @@ export default { this.$router.push(path); }, + processMessageBuffer() { + // 清除超时定时器 + if (this.messageTimeout) { + clearTimeout(this.messageTimeout); + this.messageTimeout = null; + } + + // 移除所有data:前缀 + let messageContent = this.messageBuffer.replace(/^data:/gm, ''); + // 移除末尾的空行 + messageContent = messageContent.trim(); + + // 只有当消息内容不为空时才处理 + if (messageContent) { + try { + // 解析JSON数据 + const jsonData = JSON.parse(messageContent); + + // 检查是否是包含action的响应 + if (jsonData.action) { + // 处理导航动作 + if (jsonData.action === 'navigate' && jsonData.route) { + // 显示消息 + if (jsonData.message) { + this.messages.push({ + content: this.md.render(jsonData.message), + time: this.formatTime(new Date()), + isMe: false, + avatar: '' + }); + this.scrollToBottom(); + } + // 执行路由跳转 + this.$router.push(jsonData.route); + } + } else { + // 处理普通文本消息 + let textContent = jsonData.text || messageContent; + + // 检查是否包含订单信息,转换为表格格式 + if (textContent.includes('订单号:') || textContent.includes('订单详情')) { + // 提取订单信息并转换为表格 + textContent = this.convertOrderToTable(textContent); + } + + // 检查是否包含打开页面的指令 + this.checkOpenPageCommand(textContent); + + // 移除正在思考的消息 + if (this.isLoading) { + this.messages = this.messages.filter(msg => !msg.isLoading); + this.isLoading = false; + } + + // 使用markdown-it将markdown格式转换为HTML + const htmlContent = this.md.render(textContent); + this.messages.push({ + content: htmlContent, + time: this.formatTime(new Date()), + isMe: false, + avatar: '' + }); + this.scrollToBottom(); + } + } catch (e) { + console.error('解析SSE消息失败:', e); + // 移除正在思考的消息 + if (this.isLoading) { + this.messages = this.messages.filter(msg => !msg.isLoading); + this.isLoading = false; + } + + // 使用markdown-it将markdown格式转换为HTML + const htmlContent = this.md.render(messageContent); + this.messages.push({ + content: htmlContent, + time: this.formatTime(new Date()), + isMe: false, + avatar: '' + }); + this.scrollToBottom(); + } + } + + // 清空缓冲区 + this.messageBuffer = ''; + }, + + // 检查并处理打开页面的指令 + checkOpenPageCommand(text) { + // 检查是否包含打开店铺管理页面的指令 + if (text.includes('打开店铺管理页面') || text.includes('进入店铺管理') || text.includes('前往店铺管理')) { + // 跳转到店铺管理页面 + this.$router.push('/shop/shop_list'); + } + // 可以在这里添加更多页面的打开指令 + }, + + // 将订单信息转换为markdown表格 + convertOrderToTable(text) { + // 提取订单信息 + const orderMatches = text.match(/订单号:\s*(\S+)/); + const dateMatches = text.match(/日期:\s*(\S+)/); + const customerMatches = text.match(/客户:\s*(\S+)/); + const amountMatches = text.match(/金额:\s*(\S+)/); + const statusMatches = text.match(/状态:\s*(\S+)/); + + if (orderMatches && dateMatches && customerMatches && amountMatches && statusMatches) { + // 构建markdown表格 + return `| 订单号 | 日期 | 客户 | 金额 | 状态 | +| --- | --- | --- | --- | --- | +| ${orderMatches[1]} | ${dateMatches[1]} | ${customerMatches[1]} | ${amountMatches[1]} | ${statusMatches[1]} |`; + } + return text; + }, + loadSystemStats() { todayDaily().then(resp => { this.stats = resp.data;