refactor(消息列表): 重构消息处理逻辑,统一ID生成和排序
将消息处理逻辑提取为独立函数,统一处理ID生成和内容解析 添加消息排序功能,确保消息按ID正确排序 移除硬编码的ID生成方式,优先使用服务器返回的ID
This commit is contained in:
parent
3c82008e2e
commit
7209e5a815
@ -62,18 +62,17 @@ Page({
|
||||
page: that.data.page,
|
||||
page_size: that.data.page_size,
|
||||
}).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 = res.list.map((item, index) => {
|
||||
item.id = 'm' + (base + index);
|
||||
item.content = JSON.parse(item.content);
|
||||
return item;
|
||||
});
|
||||
// 处理消息列表,使用统一的消息处理函数
|
||||
const list = that.processMessages(res.list);
|
||||
|
||||
// 根据ID进行排序,确保ID最大的(最新的)消息在最后
|
||||
const sortedList = that.sortMessagesByID(list);
|
||||
|
||||
that.setData({
|
||||
messages: list,
|
||||
messages: sortedList,
|
||||
total: res.total,
|
||||
// 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_size: this.data.page_size,
|
||||
}).then(res => {
|
||||
// map with stable ids based on nextPage
|
||||
const base = (nextPage - 1) * that.data.page_size;
|
||||
const newList = res.list.map((item, index) => {
|
||||
item.id = 'm' + (base + index);
|
||||
item.content = JSON.parse(item.content);
|
||||
return item;
|
||||
});
|
||||
// 处理新加载的消息,使用统一的消息处理函数
|
||||
const newList = that.processMessages(res.list);
|
||||
|
||||
// prepend older messages
|
||||
// 合并新消息和现有消息
|
||||
const combined = newList.concat(that.data.messages);
|
||||
|
||||
// 根据ID进行排序,确保ID最大的(最新的)消息在最后
|
||||
const sortedCombined = that.sortMessagesByID(combined);
|
||||
|
||||
that.setData({
|
||||
messages: combined,
|
||||
messages: sortedCombined,
|
||||
page: nextPage,
|
||||
total: res.total,
|
||||
}, () => {
|
||||
@ -128,6 +125,63 @@ Page({
|
||||
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
|
||||
silentLogin() {
|
||||
const that = this;
|
||||
@ -262,9 +316,13 @@ Page({
|
||||
sender_id: this.data.userInfo.openid,
|
||||
sender_name: this.data.userInfo.user_name
|
||||
};
|
||||
|
||||
// 添加新消息并重新排序
|
||||
const newMessages = this.data.messages.concat(msg);
|
||||
const sortedMessages = this.sortMessagesByID(newMessages);
|
||||
|
||||
this.setData({
|
||||
messages: newMessages,
|
||||
messages: sortedMessages,
|
||||
inputText: ''
|
||||
});
|
||||
const accountInfo = wx.getAccountInfoSync();
|
||||
@ -280,8 +338,10 @@ Page({
|
||||
})
|
||||
// 等待渲染,确保 scroll-into-view 生效
|
||||
setTimeout(() => {
|
||||
// 滚动到最新的消息(排序后的最后一条)
|
||||
const latestMessage = sortedMessages[sortedMessages.length - 1];
|
||||
this.setData({
|
||||
scrollToId: id
|
||||
scrollToId: latestMessage ? latestMessage.id : id
|
||||
});
|
||||
}, 50);
|
||||
|
||||
|
||||
@ -30,8 +30,8 @@
|
||||
"launchMode": "default"
|
||||
},
|
||||
{
|
||||
"name": "pages/contact/index",
|
||||
"pathName": "pages/contact/index",
|
||||
"name": "pages/index/detail",
|
||||
"pathName": "pages/index/detail",
|
||||
"query": "",
|
||||
"launchMode": "default",
|
||||
"scene": null
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user