diff --git a/docs/api_kefu.md b/docs/api_kefu.md index 646d59a3d..7059b4f56 100644 --- a/docs/api_kefu.md +++ b/docs/api_kefu.md @@ -2,7 +2,7 @@ ## 一、接口说明 -本接口用于连接微信小程序与Dify聊天机器人,实现智能客服功能。所有接口都采用事件驱动架构,支持高并发和模块化扩展。 +本接口用于连接微信小程序与Dify聊天机器人,实现智能客服功能。支持流式和非流式两种响应模式,具备完整的事务保护、数据一致性和状态管理功能。 ## 二、配置说明 @@ -30,14 +30,14 @@ ### 1. 系统健康检查 -**接口地址**:`/api/kefu/health` +**接口地址**:/api/kefu/health -**请求方式**:GET +**请求方式**:POST **请求参数**: | 参数名 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | +| ------ | ---- | ---- | ---- | | uniacid | int | 是 | 站点ID | | check_type | string | 否 | 检查类型:full(完整)、basic(基础)、ai_service(AI服务),默认full | @@ -46,56 +46,25 @@ ```json { "code": 0, - "message": "healthy", + "message": "success", "data": { "status": "healthy", - "check_id": "health_63a8f9c1234abcd", + "check_id": "health_56789", "timestamp": "2023-12-25 10:30:45", - "total_checks": 4, - "passed_checks": 4, + "total_checks": 2, + "passed_checks": 2, "failed_checks": 0, - "response_time_ms": 156.78, + "response_time_ms": 170, "components": { + "ai_service": { + "status": "healthy", + "message": "AI服务正常", + "response_time_ms": 150 + }, "database": { "status": "healthy", "message": "数据库连接正常", - "response_time_ms": 12.34, - "details": { - "connection": "success", - "query_test": "passed" - } - }, - "ai_service_config": { - "status": "healthy", - "message": "AI服务配置正常", - "response_time_ms": 8.56, - "details": { - "configured": true, - "complete": true, - "enabled": true, - "base_url": "https://api.example.com" - } - }, - "ai_service_connection": { - "status": "healthy", - "message": "AI服务连接正常", - "response_time_ms": 45.67, - "details": { - "http_status": 200, - "url": "https://api.example.com" - } - }, - "system_resources": { - "status": "healthy", - "message": "系统资源正常", - "response_time_ms": 2.34, - "details": { - "php_version": "8.1.0", - "memory_usage": "45.67 MB", - "memory_limit": "512.00 MB", - "memory_usage_percent": "8.92%", - "max_execution_time": "30s" - } + "response_time_ms": 20 } }, "warnings": [], @@ -106,15 +75,15 @@ ### 2. 获取服务配置信息 -**接口地址**:`/api/kefu/info` +**接口地址**:/api/kefu/info -**请求方式**:GET +**请求方式**:POST **请求参数**: | 参数名 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| uniacid | int | 否 | 站点ID | +| ------ | ---- | ---- | ---- | +| uniacid | int | 是 | 站点ID | | member_id | int | 否 | 会员ID | | token | string | 否 | 访问令牌 | @@ -125,56 +94,8 @@ "code": 0, "message": "success", "data": { - "service_info": { - "name": "智能客服", - "version": "1.0.0", - "enabled": true, - "status": "enabled" - }, - "features": { - "chat": true, - "chat_stream": true, - "conversation_management": true, - "history_management": true - }, - "limits": { - "max_message_length": 4000, - "max_conversation_history": 100, - "rate_limit": { - "requests_per_minute": 60, - "requests_per_hour": 1000 - } - }, - "endpoints": { - "chat": "/api/kefu/chat", - "chat_stream": "/api/kefu/chatStream", - "create_conversation": "/api/kefu/createConversation", - "get_history": "/api/kefu/getHistory", - "clear_conversation": "/api/kefu/clearConversation", - "health": "/api/kefu/health", - "info": "/api/kefu/info" - }, - "api_config": { - "base_url": "https://api.dify.ai/v1", - "chat_endpoint": "/chat-messages", - "supports_streaming": true, - "authentication": "bearer_token" - }, - "client_info": { - "user_agent": "Mozilla/5.0...", - "ip": "192.168.1.100", - "timestamp": 1703505845 - }, - "server_info": { - "php_version": "8.1.0", - "server_time": "2023-12-25 10:30:45", - "timezone": "Asia/Shanghai" - }, - "user_stats": { - "can_use_service": true, - "member_id": 123, - "site_id": 1 - } + "enabled": true, + "status": "enabled" } } ``` @@ -183,29 +104,30 @@ **接口地址**:`/api/kefu/chat` -**请求方式**:POST +**请求方式**:POST 或 GET(流式模式支持EventSource) **请求参数**: | 参数名 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| uniacid | int | 是 | 站点ID | -| message | string | 是 | 用户输入的消息内容 | +| ------ | ---- | ---- | ---- | +| query | string | 是 | 用户输入的消息内容 | | user_id | string | 否 | 用户ID,默认使用当前登录会员ID | | conversation_id | string | 否 | 会话ID,第一次聊天可不传,系统会自动创建 | | stream | bool | 否 | 是否使用流式响应,默认false | -| member_id | int | 否 | 会员ID | -| token | string | 否 | 访问令牌 | +| response_mode | string | 否 | 响应模式:streaming(流式)、blocking(阻塞),默认streaming | +| uniacid | int | 是 | 站点ID | **响应示例**: +#### 非流式响应(stream=false 或 response_mode=blocking) + ```json { "code": 0, "message": "success", "data": { "conversation_id": "conv_123456789", - "reply": "您好,我是智能客服,有什么可以帮助您的?", + "answer": "您好,我是智能客服,有什么可以帮助您的?", "message_id": "msg_123456789", "finish_reason": "stop", "usage": { @@ -217,110 +139,36 @@ } ``` -### 4. 智能客服流式聊天接口 - -**接口地址**:`/api/kefu/chatStream` - -**请求方式**:POST - -**请求参数**:同 `/api/kefu/chat` 接口 +#### 流式响应(stream=true 或 response_mode=streaming) **响应格式**:Server-Sent Events (SSE) **响应示例**: ```javascript -// 开始事件 -event: start -data: { - "id": "unique_id", - "event": "start", - "timestamp": 1703505845, - "data": { - "request_id": "stream_123", - "message": "开始处理请求" - } -} +data: {"event":"message","answer":"您好","conversation_id":"conv_123456789","message_id":"msg_123456789"} -// 内容块事件 -event: message -data: { - "id": "unique_id", - "event": "message", - "timestamp": 1703505845, - "data": { - "content": "您", - "conversation_id": "conv_123", - "finished": false - } -} +data: {"event":"message","answer":",我是智能客服,","conversation_id":"conv_123456789","message_id":"msg_123456789"} -// 完成事件 -event: complete -data: { - "id": "unique_id", - "event": "complete", - "timestamp": 1703505845, - "data": { - "conversation_id": "conv_123", - "message_id": "msg_456", - "usage": {}, - "finish_reason": "stop" - } -} +data: {"event":"message","answer":"有什么可以帮助您的?","conversation_id":"conv_123456789","message_id":"msg_123456789"} -// 结束事件 -event: end -data: { - "id": "unique_id", - "event": "end", - "timestamp": 1703505845, - "data": { - "request_id": "stream_123", - "status": "completed" - } -} +data: {"event":"message_end","conversation_id":"conv_123456789","message_id":"msg_123456789"} + +data: {"event":"done","data":{"conversation_id":"conv_123456789","message_id":"msg_123456789","content":"您好,我是智能客服,有什么可以帮助您的?"}} + +data: {"event":"close","data":{"conversation_id":"conv_123456789","message_id":"msg_123456789"}} ``` -### 5. 创建新会话 +### 4. 获取会话历史 -**接口地址**:`/api/kefu/createConversation` +**接口地址**:/api/kefu/getHistory **请求方式**:POST **请求参数**: | 参数名 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | -| uniacid | int | 是 | 站点ID | -| user_id | string | 否 | 用户ID,默认使用当前登录会员ID | -| member_id | int | 否 | 会员ID | -| token | string | 否 | 访问令牌 | - -**响应示例**: - -```json -{ - "code": 0, - "message": "success", - "data": { - "conversation_id": "conv_123456789", - "name": "智能客服会话", - "created_at": "2023-12-25 10:30:45" - } -} -``` - -### 6. 获取会话历史 - -**接口地址**:`/api/kefu/getHistory` - -**请求方式**:POST - -**请求参数**: - -| 参数名 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | +| ------ | ---- | ---- | ---- | | uniacid | int | 是 | 站点ID | | conversation_id | string | 是 | 会话ID | | user_id | string | 否 | 用户ID,默认使用当前登录会员ID | @@ -338,26 +186,28 @@ data: { "data": { "messages": [ { - "id": 1, + "id": "msg_123456789", "role": "user", - "content": "你好", - "create_time": "2023-12-25 10:30:45" + "content": "您好", + "create_time": 1703505845 }, { - "id": 2, + "id": "msg_123456790", "role": "assistant", "content": "您好,我是智能客服,有什么可以帮助您的?", - "create_time": "2023-12-25 10:30:46" + "create_time": 1703505846 } ], "total": 2, - "limit": 20, - "offset": 0 + "page_info": { + "limit": 20, + "offset": 0 + } } } ``` -### 7. 清除会话历史 +### 5. 清除会话历史 **接口地址**:`/api/kefu/clearConversation` @@ -366,10 +216,10 @@ data: { **请求参数**: | 参数名 | 类型 | 必填 | 说明 | -| --- | --- | --- | --- | +| ------ | ---- | ---- | ---- | | uniacid | int | 是 | 站点ID | -| conversation_id | string | 否 | 会话ID(与user_id二选一) | -| user_id | string | 否 | 用户ID,用于清除该用户所有会话(与conversation_id二选一) | +| conversation_id | string | 否(与user_id二选一) | 会话ID(与user_id二选一) | +| user_id | string | 否(与conversation_id二选一) | 用户ID,默认使用当前登录会员ID(与conversation_id二选一) | | member_id | int | 否 | 会员ID | | token | string | 否 | 访问令牌 | @@ -379,65 +229,262 @@ data: { { "code": 0, "message": "success", - "data": { - "deleted_messages": 15, - "deleted_conversations": 3 - } + "data": {} } ``` ## 四、前端调用示例 -### Uniapp调用示例 +### 1. 非流式聊天(Fetch API) ```javascript -// 引入请求封装(根据项目实际情况调整) -import { request } from '@/utils/request'; - -// 1. 获取服务配置信息 -async function getAIInfo() { +// 非流式聊天 +async function chatWithAI(message, conversationId = '') { try { - const res = await request({ - url: '/api/kefu/info', - method: 'GET', - data: { - uniacid: 1 - } + const formData = new FormData(); + formData.append('query', message); + formData.append('uniacid', '1'); + formData.append('stream', 'false'); + formData.append('response_mode', 'blocking'); + + if (conversationId) { + formData.append('conversation_id', conversationId); + } + + const response = await fetch('/api/kefu/chat', { + method: 'POST', + body: formData }); - if (res.code === 0) { - console.log('AI服务状态:', res.data.service_info); - console.log('可用功能:', res.data.features); - return res.data; + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const result = await response.json(); + + if (result.code === 0) { + return result.data; } else { - console.error('获取配置失败:', res.message); + console.error('聊天失败:', result.message); return null; } } catch (error) { - console.error('获取配置请求失败:', error); + console.error('聊天请求失败:', error); return null; } } +``` -// 2. 智能客服聊天(普通模式) -async function chatWithAI(message, conversationId = '') { +### 2. 流式聊天(EventSource) + +```javascript +// EventSource 流式聊天 +function chatWithAIEventSource(message, conversationId = '', onMessage, onComplete, onError) { + // 关闭之前的连接 + if (window.currentEventSource) { + window.currentEventSource.close(); + } + + // 构建请求参数 + const params = new URLSearchParams({ + uniacid: '1', + user_id: '123456', + query: message, + conversation_id: conversationId || '', + stream: 'true' + }); + + const url = `/api/kefu/chat?${params.toString()}`; + try { - const res = await request({ - url: '/api/kefu/chat', - method: 'POST', - data: { - uniacid: 1, - message: message, - conversation_id: conversationId - // user_id: 'your-user-id', // 可选 - // stream: false // 可选 + const eventSource = new EventSource(url); + window.currentEventSource = eventSource; + + let aiMessage = ''; + + // 监听消息事件 + eventSource.addEventListener('message', (event) => { + try { + const data = JSON.parse(event.data); + + if (data.event === 'message') { + // 更新 AI 消息 + aiMessage += data.answer || ''; + if (onMessage) onMessage(data.answer || ''); + } + + if (data.event === 'message_end') { + // 对话完成 + if (onComplete) onComplete({ + conversation_id: data.conversation_id, + message: aiMessage + }); + } + + if (data.conversation_id) { + conversationId = data.conversation_id; + } + } catch (error) { + console.error('解析消息失败:', error); } }); - if (res.code === 0) { - return res.data; + // 监听完成事件 + eventSource.addEventListener('done', (event) => { + try { + const data = JSON.parse(event.data); + if (onComplete) onComplete(data); + } catch (error) { + console.error('解析完成事件失败:', error); + } + }); + + // 监听关闭事件 + eventSource.addEventListener('close', (event) => { + try { + const data = JSON.parse(event.data); + console.log('连接正常结束:', data); + } catch (error) { + console.error('解析关闭事件失败:', error); + } + window.currentEventSource = null; + }); + + // 监听错误事件 + eventSource.addEventListener('error', (error) => { + console.error('EventSource错误:', error); + if (onError) onError({ error: 'EventSource连接错误' }); + window.currentEventSource = null; + }); + + return eventSource; + + } catch (error) { + console.error('创建EventSource失败:', error); + if (onError) onError({ error: error.message }); + return null; + } +} +``` + +### 3. 流式聊天(Fetch API) + +```javascript +// Fetch API 流式聊天 +async function chatWithAIFetchStream(message, conversationId = '', onMessage, onComplete, onError) { + try { + // 构建请求体 + const formData = new FormData(); + formData.append('uniacid', '1'); + formData.append('user_id', '123456'); + formData.append('query', message); + formData.append('conversation_id', conversationId || ''); + formData.append('stream', 'true'); + + const response = await fetch('/api/kefu/chat', { + method: 'POST', + body: formData, + headers: { + 'Accept': 'text/event-stream' + } + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + if (!response.body) { + throw new Error('响应体不可用'); + } + + const reader = response.body.getReader(); + const decoder = new TextDecoder('utf-8'); + let buffer = ''; + let aiMessage = ''; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + // 解码新接收的数据 + buffer += decoder.decode(value, { stream: true }); + + // 处理缓冲的数据,按行分割 + let lineEnd; + while ((lineEnd = buffer.indexOf('\n')) !== -1) { + const line = buffer.substring(0, lineEnd); + buffer = buffer.substring(lineEnd + 1); + + if (line.startsWith('data: ')) { + try { + const data = JSON.parse(line.substring(6)); + + if (data.event === 'message') { + aiMessage += data.answer || ''; + if (onMessage) onMessage(data.answer || ''); + } else if (data.event === 'message_end') { + if (onComplete) onComplete({ + conversation_id: data.conversation_id, + message: aiMessage + }); + } else if (data.event === 'done' && onComplete) { + onComplete(data); + } else if (data.event === 'error' && onError) { + onError(data); + } + + if (data.conversation_id) { + conversationId = data.conversation_id; + } + } catch (e) { + console.warn('解析流式数据失败:', e); + } + } + } + } + + // 处理剩余的缓冲数据 + if (buffer.startsWith('data: ')) { + try { + const data = JSON.parse(buffer.substring(6)); + if (data.event === 'message' && onMessage) { + onMessage(data.answer || ''); + } else if (data.event === 'done' && onComplete) { + onComplete(data); + } + } catch (e) { + console.warn('解析剩余数据失败:', e); + } + } + + } catch (error) { + console.error('Fetch流式聊天请求失败:', error); + if (onError) onError({ error: error.message }); + } +} +``` + +### 4. Uniapp调用示例 + +```javascript +// Uniapp 非流式调用 +async function chatWithAI(message, conversationId = '') { + try { + const res = await uni.request({ + url: '/api/kefu/chat', + method: 'POST', + data: { + query: message, + uniacid: 1, + conversation_id: conversationId, + response_mode: 'blocking' + } + }); + + if (res[1].data.code === 0) { + return res[1].data.data; } else { - console.error('聊天失败:', res.message); + console.error('聊天失败:', res[1].data.message); return null; } } catch (error) { @@ -446,74 +493,10 @@ async function chatWithAI(message, conversationId = '') { } } -// 3. 智能客服聊天(流式模式) -async function chatWithAIStream(message, conversationId = '', onMessage, onComplete, onError) { - try { - const response = await uni.request({ - url: '/api/kefu/chatStream', - method: 'POST', - data: { - uniacid: 1, - message: message, - conversation_id: conversationId - }, - responseType: 'text' - }); - - // 处理流式响应 - if (response.statusCode === 200) { - const lines = response.data.split('\n'); - for (const line of lines) { - if (line.startsWith('data: ')) { - try { - const data = JSON.parse(line.substring(6)); - if (data.event === 'message' && onMessage) { - onMessage(data.data); - } else if (data.event === 'complete' && onComplete) { - onComplete(data.data); - } else if (data.event === 'error' && onError) { - onError(data.data); - } - } catch (e) { - console.warn('解析流式数据失败:', e); - } - } - } - } - } catch (error) { - console.error('流式聊天请求失败:', error); - if (onError) onError({ error: error.message }); - } -} - -// 4. 创建新会话 -async function createNewConversation() { - try { - const res = await request({ - url: '/api/kefu/createConversation', - method: 'POST', - data: { - uniacid: 1 - // user_id: 'your-user-id', // 可选 - } - }); - - if (res.code === 0) { - return res.data.conversation_id; - } else { - console.error('创建会话失败:', res.message); - return null; - } - } catch (error) { - console.error('创建会话请求失败:', error); - return null; - } -} - -// 5. 获取会话历史 +// Uniapp 获取历史记录 async function getChatHistory(conversationId, limit = 20, offset = 0) { try { - const res = await request({ + const res = await uni.request({ url: '/api/kefu/getHistory', method: 'POST', data: { @@ -521,14 +504,13 @@ async function getChatHistory(conversationId, limit = 20, offset = 0) { conversation_id: conversationId, limit: limit, offset: offset - // user_id: 'your-user-id', // 可选 } }); - if (res.code === 0) { - return res.data; + if (res[1].data.code === 0) { + return res[1].data.data; } else { - console.error('获取历史记录失败:', res.message); + console.error('获取历史记录失败:', res[1].data.message); return null; } } catch (error) { @@ -537,47 +519,22 @@ async function getChatHistory(conversationId, limit = 20, offset = 0) { } } -// 6. 清除会话历史 -async function clearConversation(conversationId = '', userId = '') { - try { - const res = await request({ - url: '/api/kefu/clearConversation', - method: 'POST', - data: { - uniacid: 1, - conversation_id: conversationId, - user_id: userId - } - }); - - if (res.code === 0) { - return res.data; - } else { - console.error('清除会话失败:', res.message); - return null; - } - } catch (error) { - console.error('清除会话请求失败:', error); - return null; - } -} - -// 7. 健康检查 +// Uniapp 健康检查 async function checkHealth(checkType = 'full') { try { - const res = await request({ + const res = await uni.request({ url: '/api/kefu/health', - method: 'GET', + method: 'POST', data: { uniacid: 1, check_type: checkType } }); - if (res.code === 0) { - return res.data; + if (res[1].data.code === 0) { + return res[1].data.data; } else { - console.error('健康检查失败:', res.message); + console.error('健康检查失败:', res[1].data.message); return null; } } catch (error) { @@ -590,40 +547,65 @@ async function checkHealth(checkType = 'full') { ## 五、使用流程 1. **初始化检查**:小程序端启动时,调用`health`和`info`接口检查服务状态 -2. **创建会话**:进入客服页面时,调用`createConversation`接口创建新会话,或使用本地存储的会话ID -3. **发送消息**:用户输入消息后,调用`chat`或`chatStream`接口发送消息,获取机器人回复 +2. **获取会话**:进入客服页面时,系统会自动创建或使用已有会话 +3. **发送消息**:用户输入消息后,调用`chat`接口发送消息,获取机器人回复 4. **显示消息**:将用户消息和机器人回复显示在聊天界面 5. **加载历史记录**:需要时调用`getHistory`接口加载历史消息 6. **维护会话**:保持会话ID,用于后续消息交流 7. **清理数据**:根据用户需求调用`clearConversation`接口清理历史数据 -## 六、注意事项 +## 六、数据存储机制 + +### 1. 存储状态 + +| 状态值 | 含义 | 说明 | +|--------|------|------| +| `streaming` | 流式中 | 正在进行流式输出的临时数据 | +| `completed` | 已完成 | 正常完成的对话数据 | +| `failed` | 失败 | 流式过程中发生失败的数据 | + +### 2. 事务保护 + +- **流式对话**:使用临时会话ID机制,失败时自动回滚 +- **非流式对话**:完整的事务保护,确保数据一致性 +- **重复检查**:避免重复存储相同消息 + +### 3. 数据一致性 + +- 用户消息和助手消息通过`conversation_id`关联 +- 会话状态实时更新,便于管理和监控 +- 详细的日志记录,便于问题排查 + +## 七、注意事项 1. **必填参数**:所有接口都需要`uniacid`(站点ID)参数 -2. **事件驱动**:后端采用事件驱动架构,所有业务逻辑通过事件处理器执行 -3. **安全性**:请确保Dify API密钥的安全性,不要泄露给前端 -4. **用户标识**:建议对用户ID进行加密处理,避免直接使用敏感信息 -5. **流式支持**:推荐使用`chatStream`接口获得更好的用户体验 -6. **会话管理**:建议实现会话管理机制,定期清理过期会话 -7. **频率限制**:建议添加请求频率限制,防止恶意请求 -8. **生产环境**:在生产环境中,建议关闭DEBUG模式 +2. **参数更新**:新版本使用`query`替代`message`,使用`uniacid`替代`site_id` +3. **事件驱动**:后端采用事件驱动架构,所有业务逻辑通过事件处理器执行 +4. **安全性**:请确保Dify API密钥的安全性,不要泄露给前端 +5. **用户标识**:建议对用户ID进行加密处理,避免直接使用敏感信息 +6. **流式体验**:推荐使用`stream: true`参数获得更好的用户体验 +7. **会话管理**:建议实现会话管理机制,定期清理过期会话 +8. **频率限制**:建议添加请求频率限制,防止恶意请求 +9. **生产环境**:在生产环境中,建议关闭DEBUG模式 +10. **数据完整性**:系统已内置事务保护和重复检查机制 -## 七、测试建议 +## 八、测试建议 1. **基础检查**:首先调用`health`接口检查系统状态 2. **配置验证**:调用`info`接口验证配置信息 3. **接口测试**:使用Postman或类似工具测试各个API接口 -4. **流式测试**:测试`chatStream`接口的流式响应 +4. **流式测试**:测试`chat`接口的流式响应功能 5. **完整流程**:在小程序端集成并测试完整流程 6. **边界测试**:模拟不同场景下的用户输入,测试机器人回复效果 7. **压力测试**:测试接口在高并发情况下的表现 +8. **数据验证**:检查非流式对话的存储完整性和一致性 -## 八、常见问题 +## 九、常见问题 ### 1. 接口返回400错误 **原因**:缺少必填参数`uniacid`或参数格式错误 -**解决方法**:确保请求中包含有效的站点ID +**解决方法**:确保请求中包含有效的站点ID,参数名已更新为`uniacid` ### 2. 健康检查返回503错误 @@ -648,18 +630,31 @@ async function checkHealth(checkType = 'full') { ### 6. 流式响应无法解析 **原因**:客户端不支持SSE或解析方式错误 -**解决方法**:使用正确的方式解析Server-Sent Events格式 +**解决方法**:使用正确的方式解析Server-Sent Events格式,参考前端示例代码 ### 7. 会话ID无效 **原因**:会话已过期或不存在 **解决方法**:创建新会话,获取新的会话ID -## 九、性能优化建议 +### 8. 参数不匹配 + +**原因**:使用了旧版本的参数名称 +**解决方法**:更新参数:`message` → `query`,`site_id` → `uniacid` + +## 十、性能优化建议 1. **缓存配置**:可对`info`接口返回的配置信息进行客户端缓存 2. **连接复用**:HTTP请求使用连接池,减少建立连接的开销 3. **压缩传输**:启用gzip压缩减少传输数据量 4. **分页加载**:历史记录使用分页加载,避免一次性加载大量数据 5. **CDN加速**:静态资源使用CDN加速访问 -6. **监控告警**:建立接口性能监控和告警机制 \ No newline at end of file +6. **监控告警**:建立接口性能监控和告警机制 +7. **数据清理**:定期清理过期和失败状态的垃圾数据 +8. **索引优化**:为常用查询字段添加数据库索引 + +--- + +**文档更新时间**:2025-12-10 +**版本**:v2.1 +**兼容性**:向后兼容,推荐使用标准的`uniacid`参数 \ No newline at end of file diff --git a/src/addon/aikefu/api/controller/Kefu.php b/src/addon/aikefu/api/controller/Kefu.php index b315d3731..ce93901a8 100644 --- a/src/addon/aikefu/api/controller/Kefu.php +++ b/src/addon/aikefu/api/controller/Kefu.php @@ -6,6 +6,7 @@ use addon\aikefu\model\Config as KefuConfigModel; use addon\aikefu\model\Conversation as KefuConversationModel; use addon\aikefu\model\Message as KefuMessageModel; use app\api\controller\BaseApi; +use think\facade\Db as Db; class Kefu extends BaseApi