feat(聊天): 添加自动发送欢迎消息功能并优化滚动逻辑

- 新增首次进入聊天页面自动发送"你好"消息功能
- 使用本地存储确保每个用户只发送一次欢迎消息
- 优化智能滚动逻辑,保持用户浏览位置
- 支持静默登录和已登录用户两种场景
This commit is contained in:
邹方成 2025-10-31 00:44:58 +08:00
parent 0af7fc4ec5
commit 908502d5c1
2 changed files with 164 additions and 16 deletions

View File

@ -10,7 +10,7 @@ Page({
messages: [], messages: [],
inputText: '', inputText: '',
scrollToId: '', scrollToId: '',
// 使用本地头像 // 头像
userAvatar: '/static/user.png', userAvatar: '/static/user.png',
serviceAvatar: '/static/contact.png', serviceAvatar: '/static/contact.png',
showGetUser: false, showGetUser: false,
@ -20,14 +20,16 @@ Page({
page_size: 100, page_size: 100,
openid: '', openid: '',
total: 0, total: 0,
// 是否滚动在底部 // 滚动状态
isAtBottom: true, isAtBottom: true,
// 正在加载更多(顶部分页) // 加载状态
loadingMore: false, loadingMore: false,
// 新消息提醒相关状态 // 新消息提醒
showNewMessageTip: false, // 是否显示新消息提醒 showNewMessageTip: false, // 是否显示新消息提醒
newMessageCount: 0, // 新消息数量 newMessageCount: 0, // 新消息数量
lastMessageId: '', // 最后一条消息的ID用于检测新消息 lastMessageId: '', // 最后一条消息的ID用于检测新消息
// 欢迎消息标记
hasWelcomeMessageSent: false, // 是否已发送欢迎消息
}, },
/** /**
@ -45,7 +47,10 @@ Page({
showGetUser: false, showGetUser: false,
userInfo: wx.getStorageSync('user_info'), userInfo: wx.getStorageSync('user_info'),
}); });
this.getMessages() this.getMessages().then(() => {
// 在获取消息完成后发送欢迎消息
this.sendWelcomeMessage();
});
// start polling when page loads and user is present // start polling when page loads and user is present
this.startPolling(); this.startPolling();
} else { } else {
@ -262,7 +267,10 @@ Page({
"user_id": resp.openid, "user_id": resp.openid,
"user_name": resp.user_name || '微信用户' "user_name": resp.user_name || '微信用户'
}).then(resp => { }).then(resp => {
that.getMessages() that.getMessages().then(() => {
// 在获取消息完成后发送欢迎消息
that.sendWelcomeMessage();
});
// start polling once user info exists // start polling once user info exists
that.startPolling(); that.startPolling();
}); });
@ -373,6 +381,82 @@ Page({
}); });
}, },
// 发送欢迎消息
sendWelcomeMessage() {
// 检查用户信息是否存在
if (!this.data.userInfo || !this.data.userInfo.openid) {
console.log('用户信息不存在,无法发送欢迎消息');
return;
}
// 使用用户ID作为标记检查是否已经发送过欢迎消息
const welcomeKey = `welcome_sent_${this.data.userInfo.openid}`;
const hasWelcomeSent = wx.getStorageSync(welcomeKey);
if (hasWelcomeSent) {
console.log('该用户的欢迎消息已发送过,跳过');
this.setData({ hasWelcomeMessageSent: true });
return;
}
const welcomeText = '你好';
const now = new Date();
const id = 'welcome_' + Date.now();
const msg = {
id,
content: {
messages: welcomeText
},
"msg_type": 1,
receiver_id: '',
send_time: "刚刚",
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: sortedMessages,
hasWelcomeMessageSent: true // 标记已发送欢迎消息
});
const accountInfo = wx.getAccountInfoSync();
const userInfo = wx.getStorageSync('user_info');
console.log('发送欢迎消息:', welcomeText);
// 发送到服务器
request('app/send_message', 'POST', {
"app_id": accountInfo.miniProgram.appId,
"content": JSON.stringify({
messages: welcomeText
}),
"from_user_id": userInfo.openid,
"from_user_name": userInfo.user_name,
"msg_type": 1
}).then(() => {
console.log('欢迎消息发送成功');
// 保存标记到本地存储,表示该用户已发送过欢迎消息
wx.setStorageSync(welcomeKey, true);
}).catch(err => {
console.error('欢迎消息发送失败:', err);
// 如果发送失败,不保存标记,下次还可以重试
});
// 等待渲染,确保 scroll-into-view 生效
setTimeout(() => {
// 滚动到最新的消息(排序后的最后一条)
const latestMessage = sortedMessages[sortedMessages.length - 1];
this.setData({
scrollToId: latestMessage ? latestMessage.id : id
});
}, 50);
},
sendText() { sendText() {
const text = this.data.inputText && this.data.inputText.trim(); const text = this.data.inputText && this.data.inputText.trim();
if (!text) return; if (!text) return;

View File

@ -1,16 +1,27 @@
# 自动滚动修复测试说明 # 聊天功能测试说明
## 修复内容 ## 功能更新内容
### 1. 自动滚动修复
已修复聊天页面自动刷新后自动滚动到底部的问题,现在实现智能滚动: 已修复聊天页面自动刷新后自动滚动到底部的问题,现在实现智能滚动:
### 修复的问题 #### 修复的问题
- ✅ 轮询刷新时不再强制滚动到底部 - ✅ 轮询刷新时不再强制滚动到底部
- ✅ 用户在底部时,新消息会自动滚动显示 - ✅ 用户在底部时,新消息会自动滚动显示
- ✅ 用户在上方浏览历史消息时,保持当前位置 - ✅ 用户在上方浏览历史消息时,保持当前位置
- ✅ 添加了延迟处理确保滚动生效 - ✅ 添加了延迟处理确保滚动生效
### 2. 自动发送欢迎消息 🆕
用户进入聊天页面时会自动发送"你好"消息给服务器:
#### 新增功能
- ✅ 用户首次进入聊天页面时自动发送"你好"消息
- ✅ 使用本地存储确保每个用户只发送一次欢迎消息
- ✅ 支持静默登录和已登录用户两种场景
- ✅ 发送失败时不保存标记,下次可重试
### 修改的文件 ### 修改的文件
- `pages/contact/index.js` - 修改了 `getMessages()` 函数的滚动逻辑 - `pages/contact/index.js` - 修改了滚动逻辑和添加了欢迎消息功能
## 测试步骤 ## 测试步骤
@ -20,13 +31,29 @@
### 2. 测试场景 ### 2. 测试场景
#### 场景1用户在底部时的自动滚动 #### 场景1首次进入自动发送欢迎消息 🆕
1. 清除小程序缓存(开发者工具 -> 清缓存 -> 清除数据缓存)
2. 重新进入聊天页面
3. **预期结果**
- 页面加载完成后自动发送"你好"消息
- 控制台显示"发送欢迎消息: 你好"
- 消息列表中出现"你好"消息
- 消息自动滚动到视图中
#### 场景2重复进入不发送欢迎消息
1. 在已发送过欢迎消息的情况下
2. 退出聊天页面再重新进入
3. **预期结果**
- 不会再次发送"你好"消息
- 控制台显示"该用户的欢迎消息已发送过,跳过"
#### 场景3用户在底部时的自动滚动
1. 进入聊天页面 1. 进入聊天页面
2. 滚动到最底部 2. 滚动到最底部
3. 等待新消息到达(轮询刷新) 3. 等待新消息到达(轮询刷新)
4. **预期结果**:新消息自动滚动到视图中 4. **预期结果**:新消息自动滚动到视图中
#### 场景2用户在上方时保持位置 #### 场景4:用户在上方时保持位置
1. 进入聊天页面 1. 进入聊天页面
2. 向上滚动查看历史消息 2. 向上滚动查看历史消息
3. 等待新消息到达(轮询刷新) 3. 等待新消息到达(轮询刷新)
@ -35,7 +62,7 @@
- 显示新消息提醒气泡 - 显示新消息提醒气泡
- 点击气泡可滚动到最新消息 - 点击气泡可滚动到最新消息
#### 场景3:用户发送消息时的自动滚动 #### 场景5:用户发送消息时的自动滚动
1. 在聊天页面发送文本或图片消息 1. 在聊天页面发送文本或图片消息
2. **预期结果**:自动滚动到刚发送的消息 2. **预期结果**:自动滚动到刚发送的消息
@ -44,16 +71,26 @@
- 滚动状态变化 - 滚动状态变化
- 自动滚动触发情况 - 自动滚动触发情况
- scrollToId 设置情况 - scrollToId 设置情况
- 欢迎消息发送状态 🆕
### 4. 关键日志信息 ### 4. 关键日志信息
#### 滚动相关日志
- `用户在底部准备自动滚动到消息ID: xxx` - 触发自动滚动 - `用户在底部准备自动滚动到消息ID: xxx` - 触发自动滚动
- `用户不在底部或无消息,保持当前位置` - 保持位置 - `用户不在底部或无消息,保持当前位置` - 保持位置
- `用户向上滚动设置isAtBottom为false` - 状态变化 - `用户向上滚动设置isAtBottom为false` - 状态变化
- `用户滚动到底部当前isAtBottom状态: xxx` - 到达底部 - `用户滚动到底部当前isAtBottom状态: xxx` - 到达底部
#### 欢迎消息相关日志 🆕
- `发送欢迎消息: 你好` - 开始发送欢迎消息
- `欢迎消息发送成功` - 欢迎消息发送到服务器成功
- `欢迎消息发送失败: xxx` - 欢迎消息发送失败
- `该用户的欢迎消息已发送过,跳过` - 重复进入时跳过发送
- `用户信息不存在,无法发送欢迎消息` - 用户信息异常
## 技术实现 ## 技术实现
### 核心逻辑 ### 1. 智能滚动逻辑
```javascript ```javascript
// 智能滚动:先更新数据,再延迟设置滚动 // 智能滚动:先更新数据,再延迟设置滚动
that.setData(updateData); that.setData(updateData);
@ -67,7 +104,34 @@ if (that.data.isAtBottom && sortedList.length > 0) {
} }
``` ```
### 状态管理 ### 2. 欢迎消息发送逻辑 🆕
```javascript
// 检查是否已发送过欢迎消息
const welcomeKey = `welcome_sent_${this.data.userInfo.openid}`;
const hasWelcomeSent = wx.getStorageSync(welcomeKey);
if (!hasWelcomeSent) {
// 发送欢迎消息到服务器
request('app/send_message', 'POST', {
"app_id": accountInfo.miniProgram.appId,
"content": JSON.stringify({ messages: '你好' }),
"from_user_id": userInfo.openid,
"from_user_name": userInfo.user_name,
"msg_type": 1
}).then(() => {
// 成功后保存标记
wx.setStorageSync(welcomeKey, true);
});
}
```
### 3. 状态管理
- `isAtBottom`: 标记用户是否在聊天底部 - `isAtBottom`: 标记用户是否在聊天底部
- `scrollToId`: 控制滚动到指定消息 - `scrollToId`: 控制滚动到指定消息
- `hasWelcomeMessageSent`: 当前会话是否已发送欢迎消息
- `welcome_sent_${openid}`: 本地存储标记,确保每个用户只发送一次
- 延迟50ms确保DOM更新后再滚动 - 延迟50ms确保DOM更新后再滚动
### 4. 触发时机
- **已登录用户**: 在 `onLoad` 中调用 `getMessages().then(() => sendWelcomeMessage())`
- **静默登录用户**: 在 `silentLogin` 成功后调用 `getMessages().then(() => sendWelcomeMessage())`