feat(智能客服): 实现消息组列表的Vuex状态管理及页面集成
This commit is contained in:
parent
fc97ec241c
commit
f6486a69ea
|
|
@ -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.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,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(() => {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue