feat(智能客服): 实现消息组列表的Vuex状态管理及页面集成

This commit is contained in:
yangzhe 2025-12-18 16:13:01 +08:00
parent fc97ec241c
commit f6486a69ea
2 changed files with 142 additions and 80 deletions

View File

@ -128,7 +128,7 @@
<!-- 消息循环渲染 -->
<block
v-for="(message, index) in messageGroups"
v-for="(message, index) in aiMessageGroups"
:key="'msg-' + index"
>
<!-- 时间 -->
@ -471,32 +471,6 @@ export default {
"我什么时候能推知道自己是否被录取?",
],
scrollToView: "",
// messageGroups
messageGroups: [
// {
// id: "9cac8661-bf09-4b63-ab15-1a0a36b921e0",
// message: "线",
// sendDate: "2025-07-10T15:11:32.886075",
// isSend: true,
// isRead: false,
// interactMode: 0,
// messageType: 0,
// timeLabel: 1,
// displayTime: "15:11",
// },
// {
// id: "02306fc3-c821-4a23-ad66-0bd77d154105",
// message:
// "2025线线2023-2024线\n\n线西www.jxnee.edu.cn0790-6764666/6765666",
// sendDate: "2025-07-10T15:11:32.88644",
// isSend: true,
// isRead: false,
// interactMode: 1,
// messageType: 0,
// timeLabel: 0,
// displayTime: "",
// },
],
scrollTop: 0,
messageValue: "", //
@ -511,11 +485,16 @@ export default {
return "/static/common/images/avatar.png";
},
aiMessageGroups() {
return Array.isArray(this.vuex_aiMessageGroups)
? this.vuex_aiMessageGroups
: [];
},
},
watch: {
//
messageGroups: {
aiMessageGroups: {
handler() {
//
if (!this.isLoadingMore) {
@ -559,7 +538,7 @@ export default {
this.isSwitchingConversation = true;
this.currentConversationId = conversationId;
this.currentDMid = dmid;
this.messageGroups = [];
this.$store.commit("push_AiMsgList", []);
this.pageQuery.PageIndex = 1;
this.isLoadingMore = false;
this.noMoreData = false;
@ -699,14 +678,15 @@ export default {
this.isLoadingMore = false;
this.isTransferSubmitting = false;
this.messageGroups = (this.messageGroups || []).filter(
const nextList = this.aiMessageGroups.filter(
(m) => !(m && m.customType === "transferCard")
);
this.messageGroups.push(this.createLocalUserTextMessage("转人工"));
nextList.push(this.createLocalUserTextMessage("转人工"));
const card = this.createTransferCardMessage();
this.activeTransferCardId = card.id;
this.messageGroups.push(card);
nextList.push(card);
this.$store.commit("push_AiMsgList", nextList);
},
getTransferCardTip(message) {
@ -718,21 +698,22 @@ export default {
handleTransferTypeSelect(consultationType) {
const cardId = this.activeTransferCardId;
const findCardIndex = () => {
const findCardIndex = (list) => {
if (cardId) {
const byId = this.messageGroups.findIndex(
const byId = list.findIndex(
(m) => m && m.id === cardId
);
if (byId >= 0) return byId;
}
return this.messageGroups.findIndex(
return list.findIndex(
(m) => m && m.customType === "transferCard"
);
};
const idx = findCardIndex();
const list = this.aiMessageGroups;
const idx = findCardIndex(list);
if (idx < 0) return;
const current = this.messageGroups[idx] || {};
const current = list[idx] || {};
if (this.isTransferSubmitting || current.transferStatus === "done") return;
const next = {
@ -741,7 +722,9 @@ export default {
selectedConsultationType: consultationType,
transferTipText: "",
};
this.$set(this.messageGroups, idx, next);
const nextList = list.slice();
nextList.splice(idx, 1, next);
this.$store.commit("push_AiMsgList", nextList);
this.isTransferSubmitting = true;
const params = {
@ -754,28 +737,51 @@ export default {
params.dialogueManagementId = this.currentDMid;
}
this.$u.api.TransferToALiveAgentApi(params).then((res) => {
this.$u.api
.TransferToALiveAgentApi(params)
.then((res) => {
this.isTransferSubmitting = false;
const nextIdx = findCardIndex();
const latestList = this.aiMessageGroups;
const nextIdx = findCardIndex(latestList);
if (nextIdx < 0) return;
const succeed = res && res.succeed !== false;
const serverTip =
(res && res.data && res.data.message) || (res && res.error) || "";
(res && res.data && res.data.message) ||
(res && res.error) ||
"";
if (!succeed) {
const updated = {
...this.messageGroups[nextIdx],
...latestList[nextIdx],
transferStatus: "idle",
transferTipText: serverTip,
};
this.$set(this.messageGroups, nextIdx, updated);
const updatedList = latestList.slice();
updatedList.splice(nextIdx, 1, updated);
this.$store.commit("push_AiMsgList", updatedList);
return;
}
const updated = {
...this.messageGroups[nextIdx],
...latestList[nextIdx],
transferStatus: "done",
transferTipText: serverTip,
};
this.$set(this.messageGroups, nextIdx, updated);
const updatedList = latestList.slice();
updatedList.splice(nextIdx, 1, updated);
this.$store.commit("push_AiMsgList", updatedList);
})
.catch(() => {
this.isTransferSubmitting = false;
const latestList = this.aiMessageGroups;
const nextIdx = findCardIndex(latestList);
if (nextIdx < 0) return;
const updated = {
...latestList[nextIdx],
transferStatus: "idle",
transferTipText: "转人工失败,请稍后重试",
};
const updatedList = latestList.slice();
updatedList.splice(nextIdx, 1, updated);
this.$store.commit("push_AiMsgList", updatedList);
});
},
@ -805,7 +811,7 @@ export default {
};
//
this.messageGroups.push(userMessage);
this.$store.commit("push_AiMsg", userMessage);
this.messageValue = "";
// AI
@ -823,7 +829,7 @@ export default {
};
//
this.messageGroups.push(loadingMessage);
this.$store.commit("push_AiMsg", loadingMessage);
const params = {
query: sendMessage,
@ -844,7 +850,7 @@ export default {
this.currentDMid = data.dmid;
//
this.messageGroups = this.messageGroups.filter(
const baseList = this.aiMessageGroups.filter(
(msg) => !msg.isLoading
);
@ -864,13 +870,13 @@ export default {
};
//
this.messageGroups.push(aiMessage);
this.$store.commit("push_AiMsgList", baseList.concat([aiMessage]));
})
.catch((error) => {
console.error("API请求失败:", error);
//
this.messageGroups = this.messageGroups.filter(
const baseList = this.aiMessageGroups.filter(
(msg) => !msg.isLoading
);
@ -887,7 +893,10 @@ export default {
displayTime: "",
};
this.messageGroups.push(errorMessage);
this.$store.commit(
"push_AiMsgList",
baseList.concat([errorMessage])
);
});
},
@ -918,7 +927,7 @@ export default {
};
//
this.messageGroups.push(userMessage);
this.$store.commit("push_AiMsg", userMessage);
// AI
const loadingMessage = {
@ -935,7 +944,7 @@ export default {
};
//
this.messageGroups.push(loadingMessage);
this.$store.commit("push_AiMsg", loadingMessage);
const params = {
id: item.id,
@ -953,7 +962,7 @@ export default {
const data = res.data.entityInfo;
//
this.messageGroups = this.messageGroups.filter(
const baseList = this.aiMessageGroups.filter(
(msg) => !msg.isLoading
);
@ -973,11 +982,15 @@ export default {
};
//
this.messageGroups.push(aiMessage);
this.$store.commit(
"push_AiMsgList",
baseList.concat([aiMessage])
);
} else {
//
this.messageGroups = this.messageGroups.filter(
(msg) => !msg.isLoading
this.$store.commit(
"push_AiMsgList",
this.aiMessageGroups.filter((msg) => !msg.isLoading)
);
}
})
@ -985,7 +998,7 @@ export default {
console.error("API请求失败:", error);
//
this.messageGroups = this.messageGroups.filter(
const baseList = this.aiMessageGroups.filter(
(msg) => !msg.isLoading
);
@ -1002,7 +1015,10 @@ export default {
displayTime: "",
};
this.messageGroups.push(errorMessage);
this.$store.commit(
"push_AiMsgList",
baseList.concat([errorMessage])
);
});
},
@ -1022,7 +1038,7 @@ export default {
this.isSwitchingConversation = true;
//
this.messageGroups = [];
this.$store.commit("push_AiMsgList", []);
this.pageQuery.PageIndex = 1;
this.isLoadingMore = false;
this.noMoreData = false;
@ -1056,7 +1072,10 @@ export default {
const currentList = res.item2 || [];
// sendDate(interactMode=0)
this.messageGroups = this.sortMessages(currentList);
this.$store.commit(
"push_AiMsgList",
this.sortMessages(currentList)
);
})
.finally(() => {
//
@ -1091,11 +1110,17 @@ export default {
})
.then((res3) => {
const prevList = res3?.item2 || [];
this.messageGroups = this.sortMessages(prevList);
this.$store.commit(
"push_AiMsgList",
this.sortMessages(prevList)
);
this.pageQuery.PageIndex = prevIndex;
});
} else {
this.messageGroups = this.sortMessages(currentList);
this.$store.commit(
"push_AiMsgList",
this.sortMessages(currentList)
);
}
});
},
@ -1156,10 +1181,10 @@ export default {
// sendDate(interactMode=0)
const nextPageMessageGroups = sortChatMessages(res.item2 || []);
this.messageGroups = [
...nextPageMessageGroups,
...this.messageGroups,
];
this.$store.commit(
"prepend_AiMsgList",
nextPageMessageGroups
);
})
.finally(() => {
setTimeout(() => {

View File

@ -43,6 +43,7 @@ const store = new Vuex.Store({
vuex_token: lifeData.vuex_token ? lifeData.vuex_token : "",
// 如果vuex_version无需保存到本地永久存储无需lifeData.vuex_version方式
vuex_version: "1.0.0",
// 智能客服消息组列表
vuex_aiMessageGroups: [],
// 当前聊天窗口消息列表(数组
vuex_msgList: [],
@ -178,6 +179,42 @@ const store = new Vuex.Store({
if (!msg) return;
state.vuex_msgList.unshift(msg);
},
// ===== 智能客服:消息组列表维护(参照 vuex_msgList 维护方式) =====
// 覆盖整个列表
push_AiMsgList(state, list) {
state.vuex_aiMessageGroups = Array.isArray(list) ? list : [];
},
// 追加历史消息到头部(分页加载)
prepend_AiMsgList(state, list) {
const prev = state.vuex_aiMessageGroups || [];
const next = Array.isArray(list) ? list : [];
const merged = [...next, ...prev];
const seen = new Set();
state.vuex_aiMessageGroups = merged.filter((item) => {
const id = item && item.id;
if (!id) return true;
if (seen.has(id)) return false;
seen.add(id);
return true;
});
},
// 推送一条新消息(去重)
push_AiMsg(state, msg) {
if (!msg || !msg.id) return;
const exists = (state.vuex_aiMessageGroups || []).some(
(item) => item && item.id === msg.id
);
if (!exists) {
state.vuex_aiMessageGroups.push(msg);
}
},
// 插入一条消息到头部
unshift_AiMsg(state, msg) {
if (!msg) return;
state.vuex_aiMessageGroups.unshift(msg);
},
// 更新置顶状态(本地)
update_TopState(state, { friendId, isTop }) {
state.vuex_userMsgList = (state.vuex_userMsgList || []).map((item) => {