diff --git a/pages/contact/index.js b/pages/contact/index.js index 5184e89..90c9476 100644 --- a/pages/contact/index.js +++ b/pages/contact/index.js @@ -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); diff --git a/project.private.config.json b/project.private.config.json index 5ace58a..be03d0b 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -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