feat(chat): 添加转人工客服功能
This commit is contained in:
parent
909cf26549
commit
fc97ec241c
|
|
@ -245,6 +245,9 @@ const install = (Vue, vm) => {
|
||||||
// 删除会话
|
// 删除会话
|
||||||
let DeleteDialogueApi = (params = {}) =>
|
let DeleteDialogueApi = (params = {}) =>
|
||||||
vm.$u.post("api/Dialogue/DeleteDialogue", params);
|
vm.$u.post("api/Dialogue/DeleteDialogue", params);
|
||||||
|
// 转人工服务
|
||||||
|
let TransferToALiveAgentApi = (params = {}) =>
|
||||||
|
vm.$u.post("api/Dialogue/TransferToALiveAgent", params);
|
||||||
|
|
||||||
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
|
// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
|
||||||
vm.$u.api = {
|
vm.$u.api = {
|
||||||
|
|
@ -314,6 +317,7 @@ const install = (Vue, vm) => {
|
||||||
OverheadOneDialogueApi,
|
OverheadOneDialogueApi,
|
||||||
ReadMessageApi,
|
ReadMessageApi,
|
||||||
DeleteDialogueApi,
|
DeleteDialogueApi,
|
||||||
|
TransferToALiveAgentApi,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,11 +136,77 @@
|
||||||
{{ message.displayTime }}
|
{{ message.displayTime }}
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 转人工选择卡片(独立消息,不属于AI回复,不展示头像/反馈) -->
|
||||||
|
<view
|
||||||
|
class="message-transfer"
|
||||||
|
v-if="message.customType === 'transferCard'"
|
||||||
|
:id="'msg-' + message.id"
|
||||||
|
>
|
||||||
|
<view class="transfer-card">
|
||||||
|
<view class="transfer-card-title">
|
||||||
|
请选择您要咨询的类型,以便系统为您转接对应的客服
|
||||||
|
</view>
|
||||||
|
<view class="transfer-card-options">
|
||||||
|
<view
|
||||||
|
class="transfer-option"
|
||||||
|
:class="{
|
||||||
|
selected: message.selectedConsultationType === 1,
|
||||||
|
disabled:
|
||||||
|
isTransferSubmitting ||
|
||||||
|
message.transferStatus === 'done',
|
||||||
|
}"
|
||||||
|
@click.stop="handleTransferTypeSelect(1)"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
name="account"
|
||||||
|
size="44"
|
||||||
|
:color="
|
||||||
|
message.selectedConsultationType === 1
|
||||||
|
? '#4A6CF7'
|
||||||
|
: '#C0C4CC'
|
||||||
|
"
|
||||||
|
></u-icon>
|
||||||
|
<text class="transfer-option-text">招生咨询</text>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="transfer-option"
|
||||||
|
:class="{
|
||||||
|
selected: message.selectedConsultationType === 0,
|
||||||
|
disabled:
|
||||||
|
isTransferSubmitting ||
|
||||||
|
message.transferStatus === 'done',
|
||||||
|
}"
|
||||||
|
@click.stop="handleTransferTypeSelect(0)"
|
||||||
|
>
|
||||||
|
<u-icon
|
||||||
|
name="account"
|
||||||
|
size="44"
|
||||||
|
:color="
|
||||||
|
message.selectedConsultationType === 0
|
||||||
|
? '#4A6CF7'
|
||||||
|
: '#C0C4CC'
|
||||||
|
"
|
||||||
|
></u-icon>
|
||||||
|
<text class="transfer-option-text">迎新咨询</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="transfer-card-status"
|
||||||
|
v-if="
|
||||||
|
isTransferSubmitting ||
|
||||||
|
!!message.transferTipText
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{ getTransferCardTip(message) }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 用户消息 -->
|
<!-- 用户消息 -->
|
||||||
<!-- 0 用户消息 -->
|
<!-- 0 用户消息 -->
|
||||||
<view
|
<view
|
||||||
class="message-right"
|
class="message-right"
|
||||||
v-if="message.interactMode === 0"
|
v-else-if="message.interactMode === 0"
|
||||||
:id="'msg-' + message.id"
|
:id="'msg-' + message.id"
|
||||||
>
|
>
|
||||||
<view class="message-content">
|
<view class="message-content">
|
||||||
|
|
@ -157,7 +223,9 @@
|
||||||
<!-- 1 Ai回复 3 热门回复 -->
|
<!-- 1 Ai回复 3 热门回复 -->
|
||||||
<view
|
<view
|
||||||
class="message-left"
|
class="message-left"
|
||||||
v-if="message.interactMode === 1 || message.interactMode === 3"
|
v-else-if="
|
||||||
|
message.interactMode === 1 || message.interactMode === 3
|
||||||
|
"
|
||||||
:id="'msg-' + message.id"
|
:id="'msg-' + message.id"
|
||||||
>
|
>
|
||||||
<image
|
<image
|
||||||
|
|
@ -306,6 +374,8 @@ export default {
|
||||||
isChat: false,
|
isChat: false,
|
||||||
currentConversationId: "", // 当前对话的ID
|
currentConversationId: "", // 当前对话的ID
|
||||||
currentDMid: "", // 当前对话的DMId
|
currentDMid: "", // 当前对话的DMId
|
||||||
|
activeTransferCardId: "", // 当前选中的转人工卡片ID
|
||||||
|
isTransferSubmitting: false, // 转人工请求中(用于失败时不改messageGroups)
|
||||||
advicePhoneShow: false,
|
advicePhoneShow: false,
|
||||||
perfectInfoShow: false,
|
perfectInfoShow: false,
|
||||||
isLoading: false, // loadingMore
|
isLoading: false, // loadingMore
|
||||||
|
|
@ -566,6 +636,11 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.title === "转人工") {
|
||||||
|
this.handleTransferEntryClick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (item.title === "电话咨询") {
|
if (item.title === "电话咨询") {
|
||||||
this.advicePhoneShow = true;
|
this.advicePhoneShow = true;
|
||||||
return;
|
return;
|
||||||
|
|
@ -584,6 +659,126 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createLocalUserTextMessage(messageText) {
|
||||||
|
return {
|
||||||
|
id: Math.random().toString(36).substring(2, 15),
|
||||||
|
message: messageText,
|
||||||
|
sendDate: "",
|
||||||
|
isSend: true,
|
||||||
|
isRead: false,
|
||||||
|
interactMode: 0,
|
||||||
|
messageType: 0,
|
||||||
|
timeLabel: 0,
|
||||||
|
displayTime: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
createTransferCardMessage() {
|
||||||
|
return {
|
||||||
|
id: "transfer_" + Math.random().toString(36).substring(2, 15),
|
||||||
|
message: "",
|
||||||
|
sendDate: "",
|
||||||
|
isSend: true,
|
||||||
|
isRead: false,
|
||||||
|
interactMode: 1,
|
||||||
|
messageType: 0,
|
||||||
|
timeLabel: 0,
|
||||||
|
displayTime: "",
|
||||||
|
customType: "transferCard",
|
||||||
|
transferStatus: "idle",
|
||||||
|
selectedConsultationType: null,
|
||||||
|
transferTipText: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTransferEntryClick() {
|
||||||
|
if (!this.isChat) {
|
||||||
|
this.resetChatState();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isLoadingMore = false;
|
||||||
|
this.isTransferSubmitting = false;
|
||||||
|
|
||||||
|
this.messageGroups = (this.messageGroups || []).filter(
|
||||||
|
(m) => !(m && m.customType === "transferCard")
|
||||||
|
);
|
||||||
|
|
||||||
|
this.messageGroups.push(this.createLocalUserTextMessage("转人工"));
|
||||||
|
const card = this.createTransferCardMessage();
|
||||||
|
this.activeTransferCardId = card.id;
|
||||||
|
this.messageGroups.push(card);
|
||||||
|
},
|
||||||
|
|
||||||
|
getTransferCardTip(message) {
|
||||||
|
if (!message) return "";
|
||||||
|
if (this.isTransferSubmitting) return "正在为您转接人工客服,请稍等...";
|
||||||
|
if (message.transferTipText) return message.transferTipText;
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTransferTypeSelect(consultationType) {
|
||||||
|
const cardId = this.activeTransferCardId;
|
||||||
|
const findCardIndex = () => {
|
||||||
|
if (cardId) {
|
||||||
|
const byId = this.messageGroups.findIndex(
|
||||||
|
(m) => m && m.id === cardId
|
||||||
|
);
|
||||||
|
if (byId >= 0) return byId;
|
||||||
|
}
|
||||||
|
return this.messageGroups.findIndex(
|
||||||
|
(m) => m && m.customType === "transferCard"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const idx = findCardIndex();
|
||||||
|
if (idx < 0) return;
|
||||||
|
|
||||||
|
const current = this.messageGroups[idx] || {};
|
||||||
|
if (this.isTransferSubmitting || current.transferStatus === "done") return;
|
||||||
|
|
||||||
|
const next = {
|
||||||
|
...current,
|
||||||
|
transferStatus: "idle",
|
||||||
|
selectedConsultationType: consultationType,
|
||||||
|
transferTipText: "",
|
||||||
|
};
|
||||||
|
this.$set(this.messageGroups, idx, next);
|
||||||
|
this.isTransferSubmitting = true;
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
consultationType,
|
||||||
|
message: "转人工",
|
||||||
|
ip: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.currentDMid) {
|
||||||
|
params.dialogueManagementId = this.currentDMid;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$u.api.TransferToALiveAgentApi(params).then((res) => {
|
||||||
|
this.isTransferSubmitting = false;
|
||||||
|
const nextIdx = findCardIndex();
|
||||||
|
if (nextIdx < 0) return;
|
||||||
|
const succeed = res && res.succeed !== false;
|
||||||
|
const serverTip =
|
||||||
|
(res && res.data && res.data.message) || (res && res.error) || "";
|
||||||
|
if (!succeed) {
|
||||||
|
const updated = {
|
||||||
|
...this.messageGroups[nextIdx],
|
||||||
|
transferStatus: "idle",
|
||||||
|
transferTipText: serverTip,
|
||||||
|
};
|
||||||
|
this.$set(this.messageGroups, nextIdx, updated);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const updated = {
|
||||||
|
...this.messageGroups[nextIdx],
|
||||||
|
transferStatus: "done",
|
||||||
|
transferTipText: serverTip,
|
||||||
|
};
|
||||||
|
this.$set(this.messageGroups, nextIdx, updated);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// 修改发送消息的方法
|
// 修改发送消息的方法
|
||||||
sendMessageFn() {
|
sendMessageFn() {
|
||||||
if (!this.messageValue) {
|
if (!this.messageValue) {
|
||||||
|
|
@ -1449,6 +1644,79 @@ export default {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-transfer {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-card {
|
||||||
|
width: 100%;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 40rpx 36rpx;
|
||||||
|
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-card-title {
|
||||||
|
padding: 0 16rpx;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-card-options {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
// padding: 24rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
// background-color: #f6f8ff;
|
||||||
|
display: flex;
|
||||||
|
gap: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-option {
|
||||||
|
flex: 1;
|
||||||
|
height: 112rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background-color: #f6f8fa;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-option.selected {
|
||||||
|
background-color: #eef0fe;
|
||||||
|
border-color: #dbe3ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-option.disabled {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-option-text {
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-option.selected .transfer-option-text {
|
||||||
|
color: #4a6cf7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transfer-card-status {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-footer {
|
.chat-footer {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ const store = new Vuex.Store({
|
||||||
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : "",
|
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : "",
|
||||||
// 如果vuex_version无需保存到本地永久存储,无需lifeData.vuex_version方式
|
// 如果vuex_version无需保存到本地永久存储,无需lifeData.vuex_version方式
|
||||||
vuex_version: "1.0.0",
|
vuex_version: "1.0.0",
|
||||||
|
vuex_aiMessageGroups: [],
|
||||||
// 当前聊天窗口消息列表(数组
|
// 当前聊天窗口消息列表(数组
|
||||||
vuex_msgList: [],
|
vuex_msgList: [],
|
||||||
// 最近联系人/会话列表
|
// 最近联系人/会话列表
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue