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: 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);
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user