|
|
|
@ -291,57 +291,167 @@ export default { |
|
|
|
(item) => item.replyTitle === replyTitle |
|
|
|
); |
|
|
|
if (!autoReply) return; |
|
|
|
|
|
|
|
|
|
|
|
// 检查是否被封禁 |
|
|
|
if (this.isBanned) { |
|
|
|
this.showBannedTip(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let msgInfo = { |
|
|
|
|
|
|
|
// ========== 第一步:用户发送问题(replyTitle) ========== |
|
|
|
let userMsgInfo = { |
|
|
|
tmpId: this.generateId(), |
|
|
|
receipt: this.isReceipt, |
|
|
|
type: this.$enums.MESSAGE_TYPE.TEXT, |
|
|
|
content: autoReply.replyTitle, |
|
|
|
receipt: this.isReceipt |
|
|
|
}; |
|
|
|
|
|
|
|
if (autoReply.replyType === 0) { |
|
|
|
// 文本 |
|
|
|
msgInfo.type = this.$enums.MESSAGE_TYPE.TEXT; |
|
|
|
msgInfo.content = autoReply.replyContent; |
|
|
|
} else if (autoReply.replyType === 1) { |
|
|
|
// 图片 |
|
|
|
msgInfo.type = this.$enums.MESSAGE_TYPE.IMAGE; |
|
|
|
msgInfo.content = JSON.stringify({ |
|
|
|
originUrl: autoReply.replyContent, |
|
|
|
thumbUrl: autoReply.replyContent, |
|
|
|
}); |
|
|
|
} else { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
this.fillTargetId(msgInfo, this.chat.targetId); |
|
|
|
|
|
|
|
this.fillTargetId(userMsgInfo, this.chat.targetId); |
|
|
|
const chat = this.chat; |
|
|
|
if (!chat) return; |
|
|
|
|
|
|
|
let tmpMessage = this.buildTmpMessage(msgInfo); |
|
|
|
this.chatStore.insertMessage(tmpMessage, chat); |
|
|
|
|
|
|
|
let tmpUserMessage = this.buildTmpMessage(userMsgInfo); |
|
|
|
this.chatStore.insertMessage(tmpUserMessage, chat); |
|
|
|
this.moveChatToTop(); |
|
|
|
|
|
|
|
this.sendMessageRequest(msgInfo) |
|
|
|
|
|
|
|
// 发送用户消息 |
|
|
|
this.sendMessageRequest(userMsgInfo) |
|
|
|
.then((m) => { |
|
|
|
tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); |
|
|
|
tmpMessage.id = m.id; |
|
|
|
tmpMessage.status = m.status; |
|
|
|
this.chatStore.updateMessage(tmpMessage, chat); |
|
|
|
tmpUserMessage = JSON.parse(JSON.stringify(tmpUserMessage)); |
|
|
|
tmpUserMessage.id = m.id; |
|
|
|
tmpUserMessage.status = m.status; |
|
|
|
this.chatStore.updateMessage(tmpUserMessage, chat); |
|
|
|
|
|
|
|
// ========== 第二步:调用后端接口发送客服回复 ========== |
|
|
|
this.triggerAutoReply(autoReply); |
|
|
|
|
|
|
|
this.scrollToBottom(); |
|
|
|
this.isReceipt = false; |
|
|
|
}) |
|
|
|
.catch(() => { |
|
|
|
tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); |
|
|
|
tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; |
|
|
|
this.chatStore.updateMessage(tmpMessage, chat); |
|
|
|
tmpUserMessage = JSON.parse(JSON.stringify(tmpUserMessage)); |
|
|
|
tmpUserMessage.status = this.$enums.MESSAGE_STATUS.FAILED; |
|
|
|
this.chatStore.updateMessage(tmpUserMessage, chat); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 触发客服自动回复 |
|
|
|
triggerAutoReply(autoReply) { |
|
|
|
// 生成临时ID用于追踪 |
|
|
|
let tmpId = this.generateId(); |
|
|
|
|
|
|
|
// 构建客服回复消息 |
|
|
|
let replyMsgInfo = { |
|
|
|
tmpId: tmpId, // 添加 tmpId |
|
|
|
sendId: this.chat.targetId, // 客服ID作为发送者 |
|
|
|
recvId: this.mine.id, // 当前用户作为接收者 |
|
|
|
type: autoReply.replyType, // 回复类型 |
|
|
|
receipt: false |
|
|
|
}; |
|
|
|
|
|
|
|
// 根据类型设置内容 |
|
|
|
if (autoReply.replyType === 0) { |
|
|
|
// 文本回复 |
|
|
|
replyMsgInfo.content = autoReply.replyContent; |
|
|
|
} else if (autoReply.replyType === 1) { |
|
|
|
// 图片回复 |
|
|
|
replyMsgInfo.content = JSON.stringify({ |
|
|
|
originUrl: autoReply.replyContent, |
|
|
|
thumbUrl: autoReply.replyContent, |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 可选:先在前端显示一条临时的"客服正在输入"消息 |
|
|
|
let typingMessage = { |
|
|
|
id: this.generateId(), |
|
|
|
tmpId: tmpId, |
|
|
|
sendId: this.chat.targetId, |
|
|
|
recvId: this.mine.id, |
|
|
|
selfSend: false, |
|
|
|
sendTime: new Date().getTime(), |
|
|
|
type: this.$enums.MESSAGE_TYPE.TIP_TEXT, |
|
|
|
content: "客服正在输入...", |
|
|
|
status: this.$enums.MESSAGE_STATUS.SENDING |
|
|
|
}; |
|
|
|
|
|
|
|
this.chatStore.insertMessage(typingMessage, this.chat); |
|
|
|
|
|
|
|
// 调用发送消息接口 |
|
|
|
this.$http({ |
|
|
|
url: "/message/private/send", |
|
|
|
method: "post", |
|
|
|
data: replyMsgInfo |
|
|
|
}).then(res => { |
|
|
|
console.log("自动回复发送成功", res); |
|
|
|
|
|
|
|
// 删除"正在输入"的临时消息 |
|
|
|
this.chatStore.deleteMessage(typingMessage, this.chat); |
|
|
|
|
|
|
|
// 消息会通过 WebSocket 推送过来,前端会自动接收并显示 |
|
|
|
// 或者如果接口直接返回消息体,可以手动插入 |
|
|
|
if (res && res.id) { |
|
|
|
let replyMessage = { |
|
|
|
id: res.id, |
|
|
|
tmpId: tmpId, |
|
|
|
sendId: this.chat.targetId, |
|
|
|
recvId: this.mine.id, |
|
|
|
selfSend: false, |
|
|
|
sendTime: new Date().getTime(), |
|
|
|
type: autoReply.replyType, |
|
|
|
content: replyMsgInfo.content, |
|
|
|
status: this.$enums.MESSAGE_STATUS.SENDED |
|
|
|
}; |
|
|
|
|
|
|
|
this.chatStore.insertMessage(replyMessage, this.chat); |
|
|
|
this.scrollToBottom(); |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.error("自动回复发送失败", err); |
|
|
|
|
|
|
|
// 删除"正在输入"的临时消息 |
|
|
|
this.chatStore.deleteMessage(typingMessage, this.chat); |
|
|
|
|
|
|
|
// 可选:显示发送失败提示 |
|
|
|
uni.showToast({ |
|
|
|
title: "自动回复失败", |
|
|
|
icon: "none" |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// 新增方法:触发客服自动回复(调用后端接口) |
|
|
|
// triggerAutoReply(autoReply) { |
|
|
|
// // 构建客服回复消息,关键是要传入 sendId |
|
|
|
// let replyMsgInfo = { |
|
|
|
// sendId: this.chat.targetId, // 客服ID作为发送者 |
|
|
|
// recvId: this.mine.id, // 当前用户作为接收者 |
|
|
|
// type: autoReply.replyType, // 回复类型 |
|
|
|
// }; |
|
|
|
// console.log(replyMsgInfo) |
|
|
|
// // 根据类型设置内容 |
|
|
|
// if (autoReply.replyType === 0) { |
|
|
|
// // 文本回复 |
|
|
|
// replyMsgInfo.content = autoReply.replyContent; |
|
|
|
// } else if (autoReply.replyType === 1) { |
|
|
|
// // 图片回复 |
|
|
|
// replyMsgInfo.content = JSON.stringify({ |
|
|
|
// originUrl: autoReply.replyContent, |
|
|
|
// thumbUrl: autoReply.replyContent, |
|
|
|
// }); |
|
|
|
// } |
|
|
|
|
|
|
|
// // 调用发送消息接口 |
|
|
|
// this.$http({ |
|
|
|
// url: "/message/private/send", |
|
|
|
// method: "post", |
|
|
|
// data: replyMsgInfo |
|
|
|
// }).then(res => { |
|
|
|
// console.log("自动回复发送成功", res); |
|
|
|
// // 消息会通过 WebSocket 推送过来,前端会自动接收并显示 |
|
|
|
// }).catch(err => { |
|
|
|
// console.error("自动回复发送失败", err); |
|
|
|
// }); |
|
|
|
// }, |
|
|
|
onRecorderInput() { |
|
|
|
this.showRecord = true; |
|
|
|
this.switchChatTabBox("none"); |
|
|
|
@ -1070,6 +1180,7 @@ export default { |
|
|
|
sendMessageRequest(msgInfo) { |
|
|
|
return new Promise((resolve, reject) => { |
|
|
|
// 请求入队列,防止请求"后发先至",导致消息错序 |
|
|
|
|
|
|
|
this.reqQueue.push({ msgInfo, resolve, reject }); |
|
|
|
this.processReqQueue(); |
|
|
|
}); |
|
|
|
@ -1078,6 +1189,7 @@ export default { |
|
|
|
if (this.reqQueue.length && !this.isSending) { |
|
|
|
this.isSending = true; |
|
|
|
const reqData = this.reqQueue.shift(); |
|
|
|
console.log(reqData.msgInfo); |
|
|
|
this.$http({ |
|
|
|
url: this.messageAction, |
|
|
|
method: "post", |
|
|
|
|