refactor(消息列表): 重构消息处理逻辑,统一ID生成和排序

将消息处理逻辑提取为独立函数,统一处理ID生成和内容解析
添加消息排序功能,确保消息按ID正确排序
移除硬编码的ID生成方式,优先使用服务器返回的ID
This commit is contained in:
邹方成 2025-10-31 00:07:08 +08:00
parent 3c82008e2e
commit 7209e5a815
2 changed files with 82 additions and 22 deletions

View File

@ -62,18 +62,17 @@ Page({
page: that.data.page, page: that.data.page,
page_size: that.data.page_size, page_size: that.data.page_size,
}).then(res => { }).then(res => {
// generate stable ids across pages so we can prepend without collisions // 处理消息列表,使用统一的消息处理函数
const base = (that.data.page - 1) * that.data.page_size; const list = that.processMessages(res.list);
const list = res.list.map((item, index) => {
item.id = 'm' + (base + index); // 根据ID进行排序确保ID最大的最新的消息在最后
item.content = JSON.parse(item.content); const sortedList = that.sortMessagesByID(list);
return item;
});
that.setData({ that.setData({
messages: list, messages: sortedList,
total: res.total, total: res.total,
// only auto-scroll if user is at bottom // only auto-scroll if user is at bottom
scrollToId: that.data.isAtBottom ? (list[list.length - 1] ? list[list.length - 1].id : '') : that.data.scrollToId scrollToId: that.data.isAtBottom ? (sortedList[sortedList.length - 1] ? sortedList[sortedList.length - 1].id : '') : that.data.scrollToId
}); });
}) })
}, },
@ -101,19 +100,17 @@ Page({
page: nextPage, page: nextPage,
page_size: this.data.page_size, page_size: this.data.page_size,
}).then(res => { }).then(res => {
// map with stable ids based on nextPage // 处理新加载的消息,使用统一的消息处理函数
const base = (nextPage - 1) * that.data.page_size; const newList = that.processMessages(res.list);
const newList = res.list.map((item, index) => {
item.id = 'm' + (base + index);
item.content = JSON.parse(item.content);
return item;
});
// prepend older messages // 合并新消息和现有消息
const combined = newList.concat(that.data.messages); const combined = newList.concat(that.data.messages);
// 根据ID进行排序确保ID最大的最新的消息在最后
const sortedCombined = that.sortMessagesByID(combined);
that.setData({ that.setData({
messages: combined, messages: sortedCombined,
page: nextPage, page: nextPage,
total: res.total, total: res.total,
}, () => { }, () => {
@ -128,6 +125,63 @@ Page({
that.setData({ loadingMore: false }); that.setData({ loadingMore: false });
}); });
}, },
// 统一的消息处理函数
processMessages(messageList) {
return messageList.map((item, index) => {
// 优先使用服务器返回的ID如果没有则使用创建时间戳
if (item.id && !item.id.toString().startsWith('m') && !item.id.toString().startsWith('u')) {
item.id = 'm' + item.id;
} else if (item.create_time) {
// 使用创建时间的时间戳作为ID
item.id = 'm' + new Date(item.create_time).getTime();
} else if (!item.id) {
// 兜底方案:使用当前时间戳 + 索引
item.id = 'm' + (Date.now() + index);
}
// 解析消息内容
if (typeof item.content === 'string') {
try {
item.content = JSON.parse(item.content);
} catch (e) {
console.warn('消息内容解析失败:', item.content);
item.content = { messages: item.content };
}
}
return item;
});
},
// 消息排序函数
sortMessagesByID(messages) {
return messages.sort((a, b) => {
// 提取ID的数字部分
const getNumericId = (id) => {
if (id.startsWith('u')) {
// 用户消息:使用时间戳
return parseInt(id.replace('u', '')) || 0;
} else if (id.startsWith('m')) {
// 服务器消息:如果是时间戳格式(长度>10直接使用否则转换为时间戳格式
const numId = parseInt(id.replace('m', '')) || 0;
// 如果是小数字比如1,2,3可能是服务器的序号ID需要转换为可比较的时间戳
// 这里假设小于1000000000000约2001年的都是序号ID
if (numId < 1000000000000) {
// 将小的序号ID映射到一个较早的时间范围确保它们排在用户消息之前
return numId + 1000000000; // 加上一个基数,但仍然小于用户消息的时间戳
}
return numId;
}
return 0;
};
const idA = getNumericId(a.id);
const idB = getNumericId(b.id);
return idA - idB;
});
},
// 静默登录方法只需要appid和js_code // 静默登录方法只需要appid和js_code
silentLogin() { silentLogin() {
const that = this; const that = this;
@ -262,9 +316,13 @@ Page({
sender_id: this.data.userInfo.openid, sender_id: this.data.userInfo.openid,
sender_name: this.data.userInfo.user_name sender_name: this.data.userInfo.user_name
}; };
// 添加新消息并重新排序
const newMessages = this.data.messages.concat(msg); const newMessages = this.data.messages.concat(msg);
const sortedMessages = this.sortMessagesByID(newMessages);
this.setData({ this.setData({
messages: newMessages, messages: sortedMessages,
inputText: '' inputText: ''
}); });
const accountInfo = wx.getAccountInfoSync(); const accountInfo = wx.getAccountInfoSync();
@ -280,8 +338,10 @@ Page({
}) })
// 等待渲染,确保 scroll-into-view 生效 // 等待渲染,确保 scroll-into-view 生效
setTimeout(() => { setTimeout(() => {
// 滚动到最新的消息(排序后的最后一条)
const latestMessage = sortedMessages[sortedMessages.length - 1];
this.setData({ this.setData({
scrollToId: id scrollToId: latestMessage ? latestMessage.id : id
}); });
}, 50); }, 50);

View File

@ -30,8 +30,8 @@
"launchMode": "default" "launchMode": "default"
}, },
{ {
"name": "pages/contact/index", "name": "pages/index/detail",
"pathName": "pages/contact/index", "pathName": "pages/index/detail",
"query": "", "query": "",
"launchMode": "default", "launchMode": "default",
"scene": null "scene": null