refactor(chat): 将消息处理和格式化功能提取到工具类中
This commit is contained in:
parent
9e10f6788d
commit
5780461fa4
|
|
@ -374,13 +374,6 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 格式化时间
|
|
||||||
formatTime(date) {
|
|
||||||
const hours = date.getHours().toString().padStart(2, "0");
|
|
||||||
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
||||||
return `${hours}:${minutes}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 是否显示时间
|
// 是否显示时间
|
||||||
isShowTime(index) {
|
isShowTime(index) {
|
||||||
return shouldShowTime(this.vuex_msgList, index);
|
return shouldShowTime(this.vuex_msgList, index);
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,11 @@ import AdvicePhone from "@/components/AdvicePhone.vue";
|
||||||
import PerfectInfo from "@/components/PerfectInfo.vue";
|
import PerfectInfo from "@/components/PerfectInfo.vue";
|
||||||
import ChatHistory from "@/components/ChatHistory.vue"; // 导入新组件
|
import ChatHistory from "@/components/ChatHistory.vue"; // 导入新组件
|
||||||
import HeaderBar from "@/components/HeaderBar.vue"; // 导入头部组件
|
import HeaderBar from "@/components/HeaderBar.vue"; // 导入头部组件
|
||||||
|
import {
|
||||||
|
processChatMessageContent,
|
||||||
|
scrollToBottomByContentHeight,
|
||||||
|
sortChatMessages,
|
||||||
|
} from "@/utils/chat.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -550,28 +555,9 @@ export default {
|
||||||
// 新建对话时不执行滚动
|
// 新建对话时不执行滚动
|
||||||
if (this.isLoadingMore) return;
|
if (this.isLoadingMore) return;
|
||||||
|
|
||||||
// 使用nextTick确保DOM已更新
|
scrollToBottomByContentHeight(this, {
|
||||||
this.$nextTick(() => {
|
selector: ".chat-content",
|
||||||
// setTimeout(() => {
|
extraOffset: 200,
|
||||||
const query = uni.createSelectorQuery().in(this);
|
|
||||||
query
|
|
||||||
.select(".chat-content")
|
|
||||||
.boundingClientRect((data) => {
|
|
||||||
if (data) {
|
|
||||||
console.log("chat-content高度:", data.height);
|
|
||||||
|
|
||||||
// 同时设置scrollTop和scrollToView
|
|
||||||
this.scrollTop = data.height + 200;
|
|
||||||
// if (this.messageGroups.length > 0) {
|
|
||||||
// const lastMessage =
|
|
||||||
// this.messageGroups[this.messageGroups.length - 1];
|
|
||||||
// this.scrollToView = "msg-" + lastMessage.id;
|
|
||||||
// console.log("设置scrollToView:", this.scrollToView);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.exec();
|
|
||||||
// }, 300);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleFeatureClick(item) {
|
handleFeatureClick(item) {
|
||||||
|
|
@ -825,13 +811,6 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 格式化时间的辅助方法
|
|
||||||
formatTime(date) {
|
|
||||||
const hours = date.getHours().toString().padStart(2, "0");
|
|
||||||
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
||||||
return `${hours}:${minutes}`;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 处理选中的对话
|
// 处理选中的对话
|
||||||
handleSelectConversation(data) {
|
handleSelectConversation(data) {
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
|
|
@ -859,52 +838,12 @@ export default {
|
||||||
|
|
||||||
// 处理消息内容,如果是JSON格式则解析并格式化
|
// 处理消息内容,如果是JSON格式则解析并格式化
|
||||||
processMessageContent(message) {
|
processMessageContent(message) {
|
||||||
try {
|
return processChatMessageContent(message);
|
||||||
// 尝试解析 JSON
|
|
||||||
const parsed = JSON.parse(message);
|
|
||||||
|
|
||||||
// 如果是对象且包含特定字段,进行格式化
|
|
||||||
if (typeof parsed === "object" && parsed !== null) {
|
|
||||||
let content = "";
|
|
||||||
|
|
||||||
// 提取字段
|
|
||||||
const { answerTypeLabel, imageUrl, nearbyPaths } = parsed;
|
|
||||||
|
|
||||||
// 拼接内容,如果有值则添加并换行
|
|
||||||
if (answerTypeLabel) content += `${answerTypeLabel}\n`;
|
|
||||||
if (imageUrl) content += `${imageUrl}\n`;
|
|
||||||
if (nearbyPaths) content += `${nearbyPaths}\n`;
|
|
||||||
|
|
||||||
// 如果提取到了内容,返回处理后的文本;否则返回原文本(避免误判)
|
|
||||||
// 去除末尾多余的换行符
|
|
||||||
return content ? content.trim() : message;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// 解析失败,说明不是JSON格式,直接返回原消息
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 公共排序:按时间升序;时间相同,用户消息(interactMode=0)在前
|
// 公共排序:按时间升序;时间相同,用户消息(interactMode=0)在前
|
||||||
sortMessages(list = []) {
|
sortMessages(list = []) {
|
||||||
const processedList = (list || []).map((item) => {
|
return sortChatMessages(list);
|
||||||
// 对每条消息进行处理
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
message: this.processMessageContent(item.message),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// console.log("processedList", processedList);
|
|
||||||
|
|
||||||
return processedList.sort((a, b) => {
|
|
||||||
const timeA = new Date(a.sendDate).getTime();
|
|
||||||
const timeB = new Date(b.sendDate).getTime();
|
|
||||||
if (timeA === timeB) return a.interactMode - b.interactMode;
|
|
||||||
return timeA - timeB;
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 刷新当前对话的消息详情
|
// 刷新当前对话的消息详情
|
||||||
|
|
@ -1020,18 +959,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将消息按sendDate升序排列,时间相同时用户消息(interactMode=0)排在前面
|
// 将消息按sendDate升序排列,时间相同时用户消息(interactMode=0)排在前面
|
||||||
const nextPageMessageGroups = res.item2.sort((a, b) => {
|
const nextPageMessageGroups = sortChatMessages(res.item2 || []);
|
||||||
const timeA = new Date(a.sendDate).getTime();
|
|
||||||
const timeB = new Date(b.sendDate).getTime();
|
|
||||||
|
|
||||||
// 如果时间相同,按interactMode排序(0排在前,1排在后)
|
|
||||||
if (timeA === timeB) {
|
|
||||||
return a.interactMode - b.interactMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 否则按时间升序排列
|
|
||||||
return timeA - timeB;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.messageGroups = [
|
this.messageGroups = [
|
||||||
...nextPageMessageGroups,
|
...nextPageMessageGroups,
|
||||||
|
|
|
||||||
|
|
@ -123,3 +123,67 @@ export function scrollToBottomByContentHeight(
|
||||||
.exec();
|
.exec();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理聊天消息内容:若内容为 JSON 字符串且符合预期结构,则提取并拼接为可读文本。
|
||||||
|
*
|
||||||
|
* 说明:
|
||||||
|
* - 首页对话存在部分消息内容为 JSON 字符串的情况(如包含 `answerTypeLabel/imageUrl/nearbyPaths`)
|
||||||
|
* - 这里做“尽量解析、解析失败回退原文”的处理,避免误伤普通文本消息
|
||||||
|
*
|
||||||
|
* @param {string} message - 原始消息文本
|
||||||
|
* @returns {string} - 处理后的文本
|
||||||
|
*/
|
||||||
|
export function processChatMessageContent(message) {
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(message);
|
||||||
|
if (typeof parsed === "object" && parsed !== null) {
|
||||||
|
let content = "";
|
||||||
|
const { answerTypeLabel, imageUrl, nearbyPaths } = parsed;
|
||||||
|
|
||||||
|
if (answerTypeLabel) content += `${answerTypeLabel}\n`;
|
||||||
|
if (imageUrl) content += `${imageUrl}\n`;
|
||||||
|
if (nearbyPaths) content += `${nearbyPaths}\n`;
|
||||||
|
|
||||||
|
return content ? content.trim() : message;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聊天消息排序:按 `sendDate` 升序;时间相同时,用户消息(`interactMode=0`)排在前面。
|
||||||
|
* 同时会对每条消息的 `message` 字段进行 `processChatMessageContent` 处理。
|
||||||
|
*
|
||||||
|
* @param {Array<any>} list - 会话详情接口返回的消息列表
|
||||||
|
* @returns {Array<any>} - 处理并排序后的新数组
|
||||||
|
*/
|
||||||
|
export function sortChatMessages(list = []) {
|
||||||
|
const processedList = (list || []).map((item) => ({
|
||||||
|
...item,
|
||||||
|
message: processChatMessageContent(item && item.message),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return processedList.sort((a, b) => {
|
||||||
|
const timeA = new Date(a && a.sendDate).getTime();
|
||||||
|
const timeB = new Date(b && b.sendDate).getTime();
|
||||||
|
if (timeA === timeB) return (a && a.interactMode) - (b && b.interactMode);
|
||||||
|
return timeA - timeB;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将 Date 格式化为 `HH:mm`。
|
||||||
|
*
|
||||||
|
* @param {Date} date - 时间对象
|
||||||
|
* @returns {string} - 格式化字符串
|
||||||
|
*/
|
||||||
|
export function formatHHmm(date) {
|
||||||
|
if (!(date instanceof Date) || Number.isNaN(date.getTime())) return "";
|
||||||
|
const hours = date.getHours().toString().padStart(2, "0");
|
||||||
|
const minutes = date.getMinutes().toString().padStart(2, "0");
|
||||||
|
return `${hours}:${minutes}`;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue