chore(addon/aikefu): 更新获取配置及保存逻辑
This commit is contained in:
266
docs/api_kefu.md
Normal file
266
docs/api_kefu.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# 智能客服API接口文档
|
||||
|
||||
## 一、接口说明
|
||||
|
||||
本接口用于连接微信小程序与Dify聊天机器人,实现智能客服功能。
|
||||
|
||||
## 二、配置说明
|
||||
|
||||
### 1. 安装插件
|
||||
|
||||
在ThinkPHP后台的插件管理页面中,找到智能客服插件(aikefu)并点击安装按钮。
|
||||
|
||||
### 2. 配置插件
|
||||
|
||||
1. 进入智能客服配置页面
|
||||
2. 输入从Dify平台获取的API密钥
|
||||
3. 配置API基础地址(默认:https://api.dify.ai/v1)
|
||||
4. 配置聊天接口端点(默认:/chat-messages)
|
||||
5. 启用智能客服功能
|
||||
|
||||
### 3. 获取Dify API密钥
|
||||
|
||||
1. 登录Dify平台
|
||||
2. 进入工作台
|
||||
3. 选择您的聊天机器人项目
|
||||
4. 点击"发布"按钮
|
||||
5. 在API访问页面获取API密钥
|
||||
|
||||
## 三、接口列表
|
||||
|
||||
### 1. 智能客服聊天接口
|
||||
|
||||
**接口地址**:`/api/kefu/chat`
|
||||
|
||||
**请求方式**:POST
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| message | string | 是 | 用户输入的消息内容 |
|
||||
| user_id | string | 否 | 用户ID,默认使用当前登录会员ID |
|
||||
| conversation_id | string | 否 | 会话ID,第一次聊天可不传,系统会自动创建 |
|
||||
| stream | bool | 否 | 是否使用流式响应,默认false |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"conversation_id": "conv_123456789",
|
||||
"reply": "您好,我是智能客服,有什么可以帮助您的?",
|
||||
"message_id": "msg_123456789",
|
||||
"finish_reason": "stop",
|
||||
"usage": {
|
||||
"prompt_tokens": 10,
|
||||
"completion_tokens": 20,
|
||||
"total_tokens": 30
|
||||
}
|
||||
},
|
||||
"timestamp": 1640995200
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 获取会话历史
|
||||
|
||||
**接口地址**:`/api/kefu/getHistory`
|
||||
|
||||
**请求方式**:POST
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| conversation_id | string | 是 | 会话ID |
|
||||
| user_id | string | 否 | 用户ID,默认使用当前登录会员ID |
|
||||
| limit | int | 否 | 每页条数,默认20 |
|
||||
| offset | int | 否 | 偏移量,默认0 |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"messages": [
|
||||
{
|
||||
"id": "msg_123456789",
|
||||
"role": "user",
|
||||
"content": "你好",
|
||||
"created_at": "2023-01-01T00:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "msg_987654321",
|
||||
"role": "assistant",
|
||||
"content": "您好,我是智能客服,有什么可以帮助您的?",
|
||||
"created_at": "2023-01-01T00:00:01Z"
|
||||
}
|
||||
],
|
||||
"total": 2,
|
||||
"limit": 20,
|
||||
"offset": 0
|
||||
},
|
||||
"timestamp": 1640995200
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 创建新会话
|
||||
|
||||
**接口地址**:`/api/kefu/createConversation`
|
||||
|
||||
**请求方式**:POST
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| user_id | string | 否 | 用户ID,默认使用当前登录会员ID |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"conversation_id": "conv_123456789",
|
||||
"name": "智能客服会话",
|
||||
"created_at": "2023-01-01T00:00:00Z"
|
||||
},
|
||||
"timestamp": 1640995200
|
||||
}
|
||||
```
|
||||
|
||||
## 四、前端调用示例
|
||||
|
||||
### Uniapp调用示例
|
||||
|
||||
```javascript
|
||||
// 引入请求封装(根据项目实际情况调整)
|
||||
import { request } from '@/utils/request';
|
||||
|
||||
// 智能客服聊天
|
||||
async function chatWithAI(message, conversationId = '') {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/kefu/chat',
|
||||
method: 'POST',
|
||||
data: {
|
||||
message: message,
|
||||
conversation_id: conversationId,
|
||||
// user_id: 'your-user-id', // 可选
|
||||
// stream: false // 可选
|
||||
}
|
||||
});
|
||||
|
||||
if (res.code === 0) {
|
||||
return res.data;
|
||||
} else {
|
||||
console.error('聊天失败:', res.message);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('聊天请求失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取会话历史
|
||||
async function getChatHistory(conversationId, limit = 20, offset = 0) {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/kefu/getHistory',
|
||||
method: 'POST',
|
||||
data: {
|
||||
conversation_id: conversationId,
|
||||
limit: limit,
|
||||
offset: offset
|
||||
// user_id: 'your-user-id', // 可选
|
||||
}
|
||||
});
|
||||
|
||||
if (res.code === 0) {
|
||||
return res.data;
|
||||
} else {
|
||||
console.error('获取历史记录失败:', res.message);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取历史记录请求失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 创建新会话
|
||||
async function createNewConversation() {
|
||||
try {
|
||||
const res = await request({
|
||||
url: '/api/kefu/createConversation',
|
||||
method: 'POST',
|
||||
data: {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 五、使用流程
|
||||
|
||||
1. **初始化会话**:小程序端进入客服页面时,调用`createConversation`接口创建新会话,或使用本地存储的会话ID
|
||||
2. **发送消息**:用户输入消息后,调用`chat`接口发送消息,获取机器人回复
|
||||
3. **显示消息**:将用户消息和机器人回复显示在聊天界面
|
||||
4. **加载历史记录**:需要时调用`getHistory`接口加载历史消息
|
||||
5. **维护会话**:保持会话ID,用于后续消息交流
|
||||
|
||||
## 六、注意事项
|
||||
|
||||
1. 请确保Dify API密钥的安全性,不要泄露给前端
|
||||
2. 建议对用户ID进行加密处理,避免直接使用敏感信息
|
||||
3. 对于大量用户的场景,建议实现会话管理机制,定期清理过期会话
|
||||
4. 建议添加请求频率限制,防止恶意请求
|
||||
5. 在生产环境中,建议关闭DEBUG模式
|
||||
|
||||
## 七、测试建议
|
||||
|
||||
1. 首先在Dify平台测试聊天机器人功能是否正常
|
||||
2. 在后端配置正确的API密钥
|
||||
3. 使用Postman或类似工具测试后端API接口
|
||||
4. 在小程序端集成并测试完整流程
|
||||
5. 模拟不同场景下的用户输入,测试机器人回复效果
|
||||
|
||||
## 八、常见问题
|
||||
|
||||
### 1. 接口返回401错误
|
||||
|
||||
**原因**:Dify API密钥无效或过期
|
||||
**解决方法**:重新获取有效的API密钥并更新插件配置
|
||||
|
||||
### 2. 接口返回500错误
|
||||
|
||||
**原因**:后端服务器错误或Dify API服务异常
|
||||
**解决方法**:查看服务器日志,检查Dify API服务状态
|
||||
|
||||
### 3. 机器人回复为空
|
||||
|
||||
**原因**:Dify聊天机器人配置问题或请求参数错误
|
||||
**解决方法**:检查Dify机器人配置,验证请求参数是否正确
|
||||
|
||||
### 4. 会话ID无效
|
||||
|
||||
**原因**:会话已过期或不存在
|
||||
**解决方法**:创建新会话,获取新的会话ID
|
||||
@@ -12,37 +12,31 @@ class Kefu extends BaseShop
|
||||
{
|
||||
/**
|
||||
* 智能客服配置页
|
||||
* @return \think\response\View
|
||||
* @return \think\response\View|\think\response\Json
|
||||
*/
|
||||
public function config()
|
||||
{
|
||||
$kefu_config_model = new KefuConfigModel();
|
||||
$config_info = $kefu_config_model->getConfigInfo([['site_id', '=', $this->site_id]]);
|
||||
|
||||
View::assign('config_info', $config_info);
|
||||
return View::fetch('kefu/config');
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存智能客服配置
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function saveConfig()
|
||||
{
|
||||
$params = $this->request->post();
|
||||
|
||||
$kefu_config_model = new KefuConfigModel();
|
||||
|
||||
$data = [
|
||||
'api_key' => $params['api_key'] ?? '',
|
||||
'base_url' => $params['base_url'] ?? 'https://api.dify.ai/v1',
|
||||
'chat_endpoint' => $params['chat_endpoint'] ?? '/chat-messages',
|
||||
'status' => $params['status'] ?? 0,
|
||||
];
|
||||
|
||||
$result = $kefu_config_model->setConfig($data, $this->site_id);
|
||||
|
||||
return $this->success($result);
|
||||
if ($this->request->isJson()) {
|
||||
// 保存配置
|
||||
$params = $this->request->post();
|
||||
|
||||
$data = [
|
||||
'api_key' => $params['api_key'] ?? '',
|
||||
'base_url' => $params['base_url'] ?? 'https://api.dify.ai/v1',
|
||||
'chat_endpoint' => $params['chat_endpoint'] ?? '/chat-messages',
|
||||
'status' => $params['status'] ?? 0,
|
||||
];
|
||||
|
||||
$result = $kefu_config_model->setConfig($data, $this->site_id);
|
||||
return $result;
|
||||
} else {
|
||||
// 获取配置
|
||||
$config_info = $kefu_config_model->getConfig($this->site_id);
|
||||
$this->assign('config_info', $config_info);
|
||||
return $this->fetch('kefu/config');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,43 +59,43 @@
|
||||
form.render();
|
||||
|
||||
/**
|
||||
* 监听提交
|
||||
*/
|
||||
form.on('submit(save)', function(data) {
|
||||
if (repeat_flag) return false;
|
||||
repeat_flag = true;
|
||||
|
||||
$.ajax({
|
||||
url: ns.url("aikefu://shop/kefu/saveConfig"),
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
repeat_flag = false;
|
||||
if (res.code === 0) {
|
||||
layer.confirm('保存成功', {
|
||||
title: '操作提示',
|
||||
btn: ['返回列表', '继续编辑'],
|
||||
yes: function(index, layero) {
|
||||
location.reload();
|
||||
layer.close(index);
|
||||
},
|
||||
btn2: function(index, layero) {
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.message, {icon: 2});
|
||||
* 监听提交
|
||||
*/
|
||||
form.on('submit(save)', function(data) {
|
||||
if (repeat_flag) return false;
|
||||
repeat_flag = true;
|
||||
|
||||
$.ajax({
|
||||
url: ns.url("aikefu://shop/kefu/config"),
|
||||
type: 'POST',
|
||||
data: data.field,
|
||||
dataType: 'json',
|
||||
success: function(res) {
|
||||
repeat_flag = false;
|
||||
if (res.code === 0) {
|
||||
layer.confirm('保存成功', {
|
||||
title: '操作提示',
|
||||
btn: ['返回列表', '继续编辑'],
|
||||
yes: function(index, layero) {
|
||||
location.reload();
|
||||
layer.close(index);
|
||||
},
|
||||
btn2: function(index, layero) {
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.message, {icon: 2});
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
repeat_flag = false;
|
||||
layer.msg('请求失败,请稍后重试', {icon: 2});
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
repeat_flag = false;
|
||||
layer.msg('请求失败,请稍后重试', {icon: 2});
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
function back() {
|
||||
|
||||
Reference in New Issue
Block a user