chore:把 message替换成 query

This commit is contained in:
2025-12-11 09:42:28 +08:00
parent 2750d8012f
commit f0d3d1986f

View File

@@ -1,349 +1,250 @@
import http from './http.js'
import store from '@/store/index.js'
export default {
/**
* 发送消息到Dify API
* @param {string} message 用户消息内容
* @param {Object} options 配置选项
* @returns {Promise}
*/
async sendMessage(message, options = {}) {
try {
// 获取AI配置
const aiConfig = store.getters.globalAIKefuConfig
// const new_conversationId = await this.generateConversationId()
// 构建Dify API请求参数
const params = {
url: '/api/kefu/chat', // 后端代理接口
data: {
message: message,
// conversation_id: options.conversationId ?? new_conversationId,
user_id: store.state.memberInfo?.id || 'anonymous',
stream: options.stream || false, // 是否流式响应
// Dify API参数
inputs: {},
query: message,
response_mode: options.stream ? 'streaming' : 'blocking',
user: store.state.memberInfo?.id || 'anonymous'
},
header: {
'Content-Type': 'application/json'
}
}
// 发送请求
const response = await http.sendRequest({
...params,
async: false // 使用Promise方式
})
return this.handleResponse(response, options)
} catch (error) {
console.error('Dify API请求失败:', error)
throw new Error('AI服务暂时不可用请稍后重试')
}
},
/**
* 流式消息处理
* @param {string} message 用户消息
* @param {Function} onChunk 流式数据回调
* @param {Function} onComplete 完成回调
*/
async sendStreamMessage(message, onChunk, onComplete) {
try {
// 使用HTTP流式请求
return this.sendHttpStream(message, onChunk, onComplete)
} catch (error) {
console.error('流式消息发送失败:', error)
throw error
}
},
/**
* WebSocket连接
*/
connectWebSocket(message, onChunk, onComplete) {
return new Promise((resolve, reject) => {
const aiConfig = store.getters.globalAIKefuConfig
const wsUrl = aiConfig.difyWsUrl
if (!wsUrl) {
reject(new Error('未配置WebSocket地址'))
return
}
// #ifdef H5
const ws = new WebSocket(wsUrl)
ws.onopen = () => {
// 发送消息
ws.send(JSON.stringify({
message: message,
user_id: store.state.memberInfo?.id || 'anonymous',
conversation_id: this.generateConversationId()
}))
}
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data)
if (data.type === 'chunk' && onChunk) {
onChunk(data.content)
} else if (data.type === 'complete' && onComplete) {
onComplete(data.content)
ws.close()
resolve(data.content)
}
} catch (e) {
console.error('WebSocket消息解析失败:', e)
}
}
ws.onerror = (error) => {
console.error('WebSocket连接错误:', error)
reject(error)
}
ws.onclose = () => {
console.log('WebSocket连接关闭')
}
// #endif
// #ifdef MP-WEIXIN || APP-PLUS
// 小程序和APP使用uni.connectSocket
uni.connectSocket({
url: wsUrl,
success: () => {
uni.onSocketOpen(() => {
uni.sendSocketMessage({
data: JSON.stringify({
message: message,
user_id: store.state.memberInfo?.id || 'anonymous',
conversation_id: this.generateConversationId()
})
})
})
uni.onSocketMessage((res) => {
try {
const data = JSON.parse(res.data)
if (data.type === 'chunk' && onChunk) {
onChunk(data.content)
} else if (data.type === 'complete' && onComplete) {
onComplete(data.content)
uni.closeSocket()
resolve(data.content)
}
} catch (e) {
console.error('WebSocket消息解析失败:', e)
}
})
uni.onSocketError((error) => {
console.error('WebSocket连接错误:', error)
reject(error)
})
},
fail: (error) => {
reject(error)
}
})
// #endif
})
},
/**
* HTTP流式请求
*/
async sendHttpStream(message, onChunk, onComplete) {
const aiConfig = store.getters.globalAIKefuConfig
const params = {
url: '/api/kefu/chat-stream',
data: {
message: message,
conversation_id: this.generateConversationId(),
user_id: store.state.memberInfo?.id || 'anonymous',
stream: true
},
header: {
'Content-Type': 'application/json'
}
}
if (aiConfig?.difyApiKey) {
params.header['Authorization'] = `Bearer ${aiConfig.difyApiKey}`
}
// 使用fetch API进行流式请求H5环境
// #ifdef H5
try {
const response = await fetch(`/api/kefu/chat-messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputs: {},
query: message,
response_mode: 'streaming',
user: store.state.memberInfo?.id || 'anonymous'
})
})
const reader = response.body.getReader()
const decoder = new TextDecoder()
let content = ''
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
const lines = chunk.split('\n')
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6))
if (data.event === 'text_message' && data.text) {
content += data.text
if (onChunk) onChunk(data.text)
}
} catch (e) {
// 忽略解析错误
}
}
}
}
if (onComplete) onComplete(content)
return content
} catch (error) {
console.error('HTTP流式请求失败:', error)
throw error
}
// #endif
// 非H5环境使用普通请求模拟流式效果
// #ifndef H5
const response = await http.sendRequest({
...params,
async: false
})
// 模拟流式效果
if (response.success && response.data) {
const content = response.data
const chunkSize = 3
let index = 0
const streamInterval = setInterval(() => {
if (index < content.length) {
const chunk = content.substring(index, index + chunkSize)
index += chunkSize
if (onChunk) onChunk(chunk)
} else {
clearInterval(streamInterval)
if (onComplete) onComplete(content)
}
}, 100)
}
// #endif
},
/**
* 处理API响应
*/
handleResponse(response, options) {
if (response.code === 0 || response.success) {
return {
success: true,
content: response.data?.answer || response.data?.content || response.data?.reply|| response.data,
conversationId: response.data?.conversation_id,
messageId: response.data?.message_id
}
} else {
throw new Error(response.message || 'AI服务返回错误')
}
},
/**
* 生成会话ID
*/
async generateConversationId() {
// 构建Dify API请求参数
const params = {
url: '/api/kefu/createConversation', // 后端代理接口
data: {
uniacid: store.state.uniacid,
user_id: store.state.memberInfo?.id || 'anonymous',
member_id: store.state.memberInfo?.id || '',
},
header: {
'Content-Type': 'application/json'
}
}
// 发送请求
const response = await http.sendRequest({
...params,
async: false // 使用Promise方式
})
return this.handleResponse(response, options)
},
/**
* 获取AI服务状态
*/
async getServiceStatus() {
try {
// 简单的健康检查
const response = await http.sendRequest({
url: '/api/kefu/health',
async: false,
data: {}
})
const available = [response?.data?.status, response?.data?.components?.ai_service_config?.status].filter(item => item === 'healthy').length > 0;
return {
available,
reason: available ? '服务正常' : '服务异常'
}
} catch (error) {
return {
available: false,
reason: '服务检查失败'
}
}
},
/**
* 清除会话历史
*/
async clearConversation(conversationId) {
try {
const response = await http.sendRequest({
url: '/api/kefu/clear-conversation',
data: { conversation_id: conversationId },
async: false
})
return response.success
} catch (error) {
console.error('清除会话失败:', error)
return false
}
}
import http from './http.js'
import store from '@/store/index.js'
export default {
/**
* 发送消息到Dify API
* @param {string} message 用户消息内容
* @param {Object} options 配置选项
* @returns {Promise}
*/
async sendMessage(message, options = {}) {
try {
// 获取AI配置
const aiConfig = store.getters.globalAIKefuConfig
// const new_conversationId = await this.generateConversationId()
// 构建Dify API请求参数
const params = {
url: '/api/kefu/chat', // 后端代理接口
data: {
// conversation_id: options.conversationId ?? new_conversationId,
user_id: store.state.memberInfo?.id || 'anonymous',
stream: false,
// Dify API参数
inputs: {},
query: message,
response_mode: options.stream ? 'streaming' : 'blocking',
user: store.state.memberInfo?.id || 'anonymous'
},
header: {
'Content-Type': 'application/json'
}
}
// 发送请求
const response = await http.sendRequest({
...params,
async: false // 使用Promise方式
})
return this.handleResponse(response, options)
} catch (error) {
console.error('Dify API请求失败:', error)
throw new Error('AI服务暂时不可用请稍后重试')
}
},
/**
* 流式消息处理
* @param {string} message 用户消息
* @param {Function} onChunk 流式数据回调
* @param {Function} onComplete 完成回调
*/
async sendStreamMessage(message, onChunk, onComplete) {
try {
// 使用HTTP流式请求
return this.sendHttpStream(message, onChunk, onComplete)
} catch (error) {
console.error('流式消息发送失败:', error)
throw error
}
},
/**
* HTTP流式请求
*/
async sendHttpStream(message, onChunk, onComplete) {
const params = {
url: '/api/kefu/chat',
data: {
query: message,
conversation_id: this.generateConversationId(),
user_id: store.state.memberInfo?.id || 'anonymous',
stream: true,
uniacid: store.state.uniacid, // 保留必填参数
},
header: {
'Content-Type': 'application/json'
}
}
// 使用fetch API进行流式请求H5环境
// #ifdef H5
try {
const response = await fetch(`/api/kefu/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputs: {},
query: message,
response_mode: 'streaming',
user: store.state.memberInfo?.id || 'anonymous'
})
})
const reader = response.body.getReader()
const decoder = new TextDecoder()
let content = ''
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
const lines = chunk.split('\n')
for (const line of lines) {
if (line.startsWith('data: ')) {
try {
const data = JSON.parse(line.slice(6))
if (data.event === 'text_message' && data.text) {
content += data.text
if (onChunk) onChunk(data.text)
}
} catch (e) {
// 忽略解析错误
}
}
}
}
if (onComplete) onComplete(content)
return content
} catch (error) {
console.error('HTTP流式请求失败:', error)
throw error
}
// #endif
// 非H5环境使用普通请求模拟流式效果
// #ifndef H5
const response = await http.sendRequest({
...params,
async: false
})
// 模拟流式效果
if (response.success && response.data) {
const content = response.data
const chunkSize = 3
let index = 0
const streamInterval = setInterval(() => {
if (index < content.length) {
const chunk = content.substring(index, index + chunkSize)
index += chunkSize
if (onChunk) onChunk(chunk)
} else {
clearInterval(streamInterval)
if (onComplete) onComplete(content)
}
}, 100)
}
// #endif
},
/**
* 处理API响应
*/
handleResponse(response, options) {
if (response.code === 0 || response.success) {
return {
success: true,
content: response.data?.answer || response.data?.content || response.data?.reply|| response.data,
conversationId: response.data?.conversation_id,
messageId: response.data?.message_id
}
} else {
throw new Error(response.message || 'AI服务返回错误')
}
},
/**
* 生成会话ID
*/
async generateConversationId() {
// 构建Dify API请求参数
const params = {
url: '/api/kefu/createConversation', // 后端代理接口
data: {
uniacid: store.state.uniacid,
user_id: store.state.memberInfo?.id || 'anonymous',
member_id: store.state.memberInfo?.id || '',
},
header: {
'Content-Type': 'application/json'
}
}
// 发送请求
const response = await http.sendRequest({
...params,
async: false // 使用Promise方式
})
return this.handleResponse(response, options)
},
/**
* 获取AI服务状态
*/
async getServiceStatus() {
try {
// 简单的健康检查
const response = await http.sendRequest({
url: '/api/kefu/health',
async: false,
data: {}
})
const available = [response?.data?.status, response?.data?.components?.ai_service_config?.status].filter(item => item === 'healthy').length > 0;
return {
available,
reason: available ? '服务正常' : '服务异常'
}
} catch (error) {
return {
available: false,
reason: '服务检查失败'
}
}
},
/**
* 清除会话历史
*/
async clearConversation(conversationId) {
try {
const response = await http.sendRequest({
url: '/api/kefu/clear-conversation',
data: { conversation_id: conversationId },
async: false
})
return response.success
} catch (error) {
console.error('清除会话失败:', error)
return false
}
}
}