diff --git a/pages/home/index/index.vue b/pages/home/index/index.vue index 16c9692..44b0b90 100644 --- a/pages/home/index/index.vue +++ b/pages/home/index/index.vue @@ -128,7 +128,7 @@ @@ -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.cn)或者直接联系招生办(电话:0790-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,29 +737,52 @@ export default { 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) { + this.$u.api + .TransferToALiveAgentApi(params) + .then((res) => { + this.isTransferSubmitting = false; + 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) || + ""; + if (!succeed) { + const updated = { + ...latestList[nextIdx], + transferStatus: "idle", + transferTipText: serverTip, + }; + const updatedList = latestList.slice(); + updatedList.splice(nextIdx, 1, updated); + this.$store.commit("push_AiMsgList", updatedList); + return; + } const updated = { - ...this.messageGroups[nextIdx], - transferStatus: "idle", + ...latestList[nextIdx], + transferStatus: "done", transferTipText: serverTip, }; - this.$set(this.messageGroups, nextIdx, updated); - return; - } - const updated = { - ...this.messageGroups[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(() => { diff --git a/store/index.js b/store/index.js index 154ba01..ab7363e 100644 --- a/store/index.js +++ b/store/index.js @@ -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) => {