11 KiB
11 KiB
前端红点功能接口文档
一、功能概述
消息红点功能用于提示用户有未读的评论/回复和新增关注消息。
红点显示条件:
- 有别人回复给我的评论/回复未读
- 有新用户关注我未读
二、接口列表
| 接口 | 用途 |
|---|---|
POST /api/message/reddot_info |
获取红点信息(数量统计) |
POST /api/message/mark_as_read |
标记消息已读(统一接口) |
POST /api/comments/my_activities |
获取评论/回复消息列表 |
POST /api/user_follow/new_fans_list |
获取新增关注列表 |
三、核心接口详情
1. 获取红点信息 ⭐
接口: POST /api/message/reddot_info
请求参数: 无
响应示例:
{
"code": 200,
"message": "获取成功",
"data": {
"comment_unread_count": 5, // 评论/回复未读数量
"follow_unread_count": 3, // 新增关注未读数量
"total_unread_count": 8, // 总未读数量
"has_reddot": true // 是否显示红点
}
}
字段说明:
comment_unread_count: Number,评论/回复未读数量follow_unread_count: Number,新增关注未读数量total_unread_count: Number,总未读数量has_reddot: Boolean,是否显示红点true: 有未读消息,显示红点false: 无未读消息,隐藏红点
使用场景:
- TabBar 显示红点和未读数
- 消息页面显示各类消息的未读数
- 应用启动时检查红点状态
2. 标记消息已读 ⭐
接口: POST /api/message/mark_as_read
请求参数:
{
"type": "comment", // 消息类型: comment-评论, follow-关注, all-全部
"ids": [123, 456, 789] // 消息ID数组(type为all时可不传)
}
type 参数说明:
"comment": 标记指定评论/回复为已读,需传ids(评论ID数组)"follow": 标记指定关注为已读,需传ids(关注者用户ID数组)"all": 标记所有未读消息为已读,不需要传ids
响应示例:
{
"code": 200,
"message": "获取成功",
"data": {
"updated_count": 8, // 总更新数量
"detail": {
"comment_count": 5, // 评论更新数量
"follow_count": 3 // 关注更新数量
},
"message": "标记成功"
}
}
使用示例:
- 标记指定评论为已读:
{
"type": "comment",
"ids": [123, 456]
}
- 标记指定关注为已读:
{
"type": "follow",
"ids": [789, 012]
}
- 标记全部消息为已读:
{
"type": "all"
}
四、辅助接口
3. 获取评论/回复消息列表
接口: POST /api/comments/my_activities
请求参数:
{
"page": 1,
"pageSize": 20
}
响应示例:
{
"code": 200,
"message": "获取成功",
"data": {
"rows": [
{
"id": 456,
"type": "reply",
"activity_type": "received_reply",
"content": "回复内容",
"create_time": "2025-11-20 10:00:00",
"is_read": 0, // 👈 0-未读, 1-已读
"user": {
"id": 789,
"nickname": "回复者昵称",
"avatar_url": "头像地址"
},
"game": {
"id": 101,
"title": "球局标题"
}
}
],
"count": 50
}
}
字段说明:
is_read: 0-未读, 1-已读activity_type:"my_activity"- 我发表的"received_reply"- 别人回复我的(需要处理的)
4. 获取新增关注列表
接口: POST /api/user_follow/new_fans_list
请求参数:
{
"page": 1,
"page_size": 20
}
响应示例:
{
"code": 200,
"message": "获取成功",
"data": {
"list": [
{
"id": 123,
"nickname": "粉丝昵称",
"avatar_url": "头像地址",
"follow_time": "2025-11-20 09:00:00",
"is_mutual": false,
"is_read": 0 // 👈 0-未读, 1-已读
}
],
"total": 30
}
}
五、前端使用示例
1. 显示 TabBar 红点
// app.js 或全局方法
async function checkAndShowReddot() {
const res = await request({
url: '/api/message/reddot_info',
method: 'POST'
})
const { has_reddot, total_unread_count } = res.data
if (has_reddot) {
// 显示红点和数字
wx.setTabBarBadge({
index: 2, // 消息Tab的索引
text: total_unread_count > 99 ? '99+' : String(total_unread_count)
})
} else {
// 隐藏红点
wx.removeTabBarBadge({
index: 2
})
}
}
// App 启动时检查
App({
onLaunch() {
this.checkReddot()
},
checkReddot() {
checkAndShowReddot()
}
})
2. 消息页面显示分类红点
// pages/message/message.js
Page({
data: {
commentUnreadCount: 0,
followUnreadCount: 0
},
onShow() {
this.loadReddotInfo()
},
async loadReddotInfo() {
const res = await request({
url: '/api/message/reddot_info',
method: 'POST'
})
this.setData({
commentUnreadCount: res.data.comment_unread_count,
followUnreadCount: res.data.follow_unread_count
})
}
})
<!-- pages/message/message.wxml -->
<view class="message-page">
<!-- 评论消息入口 -->
<view class="menu-item" bindtap="goToComments">
<text>评论与回复</text>
<view wx:if="{{commentUnreadCount > 0}}" class="badge">
{{commentUnreadCount}}
</view>
</view>
<!-- 关注消息入口 -->
<view class="menu-item" bindtap="goToFollows">
<text>新增关注</text>
<view wx:if="{{followUnreadCount > 0}}" class="badge">
{{followUnreadCount}}
</view>
</view>
</view>
3. 评论消息列表(进入时自动标记已读)
// pages/message/comment-list.js
Page({
data: {
commentList: []
},
async onLoad() {
await this.loadComments()
await this.markAllAsRead()
},
// 加载评论列表
async loadComments() {
const res = await request({
url: '/api/comments/my_activities',
method: 'POST',
data: { page: 1, pageSize: 20 }
})
// 筛选出别人回复给我的
const receivedReplies = res.data.rows.filter(
item => item.activity_type === 'received_reply'
)
this.setData({ commentList: receivedReplies })
},
// 标记所有评论为已读
async markAllAsRead() {
const unreadIds = this.data.commentList
.filter(item => item.is_read === 0)
.map(item => item.id)
if (unreadIds.length > 0) {
await request({
url: '/api/message/mark_as_read',
method: 'POST',
data: {
type: 'comment',
ids: unreadIds
}
})
}
},
onUnload() {
// 离开页面时刷新红点
getApp().checkReddot()
}
})
4. 关注消息列表(进入时自动标记已读)
// pages/message/follow-list.js
Page({
data: {
fansList: []
},
async onLoad() {
await this.loadFans()
await this.markAllAsRead()
},
async loadFans() {
const res = await request({
url: '/api/user_follow/new_fans_list',
method: 'POST',
data: { page: 1, page_size: 20 }
})
this.setData({ fansList: res.data.list })
},
async markAllAsRead() {
const unreadFanIds = this.data.fansList
.filter(item => item.is_read === 0)
.map(item => item.id)
if (unreadFanIds.length > 0) {
await request({
url: '/api/message/mark_as_read',
method: 'POST',
data: {
type: 'follow',
ids: unreadFanIds
}
})
}
},
onUnload() {
getApp().checkReddot()
}
})
5. 一键清空所有未读
// 清空所有未读消息
async function markAllMessagesAsRead() {
wx.showLoading({ title: '处理中...' })
try {
await request({
url: '/api/message/mark_as_read',
method: 'POST',
data: { type: 'all' }
})
wx.showToast({ title: '已全部标记为已读', icon: 'success' })
// 刷新红点
getApp().checkReddot()
} catch (err) {
wx.showToast({ title: '操作失败', icon: 'none' })
} finally {
wx.hideLoading()
}
}
六、最佳实践
1. 红点刷新时机
// 推荐刷新时机
const REFRESH_TIMING = {
onLaunch: true, // App启动时
onShow: true, // App从后台进入前台
onTabSwitch: true, // 切换到消息Tab
afterMarkRead: true, // 标记已读后
onPullRefresh: true // 下拉刷新
}
2. 防抖优化
// utils/debounce.js
let timer = null
export function debounceCheckReddot() {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
getApp().checkReddot()
}, 300)
}
3. 错误处理
async function safeMarkAsRead(type, ids) {
try {
await request({
url: '/api/message/mark_as_read',
method: 'POST',
data: { type, ids }
})
} catch (err) {
// 标记已读失败不影响用户体验,静默处理
console.warn('标记已读失败:', err)
}
}
七、完整流程图
用户打开App
↓
调用 /message/reddot_info
↓
获取红点数据
↓
┌─────────────────┐
│ has_reddot? │
└────┬────────┬───┘
│ │
true false
↓ ↓
显示红点 隐藏红点
带数字
│
│ 用户点击
↓
进入消息页面
↓
显示各分类未读数
│
│ 点击某分类
↓
加载消息列表
↓
标记已读
↓
┌─────────────────┐
│ 选择标记方式 │
└─┬─────────┬─────┘
│ │
按ID 全部
标记 标记
↓ ↓
调用 mark_as_read
type=comment/follow
ids=[...]
│ │
└────┬────┘
↓
标记成功
↓
刷新红点
八、接口对比说明
旧方案 vs 新方案
| 功能 | 旧方案 | 新方案 |
|---|---|---|
| 获取红点 | /api/user/detail |
/api/message/reddot_info |
| 标记评论已读 | /api/comments/mark_as_read |
/api/message/mark_as_read (type=comment) |
| 标记关注已读 | /api/user_follow/mark_as_read |
/api/message/mark_as_read (type=follow) |
| 标记全部已读 | ❌ 无 | /api/message/mark_as_read (type=all) |
新方案优势:
- ✅ 统一的接口设计
- ✅ 减少接口数量
- ✅ 支持一键清空所有未读
- ✅ 返回详细的未读数统计
- ✅ 更清晰的职责划分
九、注意事项
- 权限控制: 只能标记属于自己的消息
- 分页处理: 翻页时注意标记已读
- 实时性: 标记后刷新红点状态
- 错误处理: 标记失败可静默处理
- type 参数: 必须是
comment、follow或all
十、联系后端
相关文件:
- 消息接口:
api/controller_front/msg_message.js⭐ - 评论接口:
api/controller_front/gme_comments.js - 关注接口:
api/controller_front/user_follow.js