编辑 | blame | 历史 | 原始文档

消息TabBar徽标显示功能实现说明

功能描述

在App底部TabBar的消息图标上显示未读消息数量徽标和红点,实时更新未读消息数量。

实现方案

1. App.vue全局监听

在应用启动和显示时自动获取并更新未读消息数量:

// app/App.vue
import { getUnreadCount } from '@/api/message'

export default {
  onLaunch() {
    // 应用启动时
    if (getToken()) {
      this.updateUnreadMessageBadge()
      this.startMessagePolling() // 启动30秒轮询
    }
  },
  
  onShow() {
    // 应用从后台切回前台时
    if (getToken()) {
      this.updateUnreadMessageBadge()
    }
  },
  
  methods: {
    // 更新未读消息徽标
    updateUnreadMessageBadge() {
      getUnreadCount().then(response => {
        const count = response.data || 0
        if (count > 0) {
          uni.setTabBarBadge({
            index: 3, // 消息页面在tabBar中的索引
            text: count > 99 ? '99+' : count.toString()
          })
        } else {
          uni.removeTabBarBadge({ index: 3 })
        }
      })
    },
    
    // 启动消息轮询(每30秒)
    startMessagePolling() {
      this.messagePollingTimer = setInterval(() => {
        if (getToken()) {
          this.updateUnreadMessageBadge()
        } else {
          this.stopMessagePolling()
        }
      }, 30000)
    }
  }
}

2. 消息页面实时更新

在消息页面标记消息为已读后立即更新徽标:

// app/pages/message/index.vue
export default {
  onShow() {
    this.loadMessages()
    this.updateTabBarBadge() // 进入页面时更新
  },
  
  methods: {
    async viewMessageDetail(message) {
      // 标记为已读
      if (message.isRead === '0') {
        await markAsRead(message.messageId)
        message.isRead = '1'
        this.updateTabBarBadge() // 标记后立即更新
      }
      // ... 跳转逻辑
    },
    
    updateTabBarBadge() {
      const unreadCount = this.messages.filter(msg => msg.isRead === '0').length
      if (unreadCount > 0) {
        uni.setTabBarBadge({
          index: 3,
          text: unreadCount > 99 ? '99+' : unreadCount.toString()
        })
      } else {
        uni.removeTabBarBadge({ index: 3 })
      }
    }
  }
}

3. 首页消息入口

首页也会加载并显示未读消息数量:

// app/pages/index.vue
export default {
  onShow() {
    this.loadUnreadMessageCount() // 刷新未读数量
  },
  
  methods: {
    loadUnreadMessageCount() {
      getUnreadCount().then(response => {
        if (response.code === 200) {
          this.unreadMessageCount = response.data || 0
          this.updateTabBarBadge(this.unreadMessageCount)
        }
      })
    },
    
    updateTabBarBadge(count) {
      if (count > 0) {
        uni.setTabBarBadge({
          index: 3,
          text: count > 99 ? '99+' : count.toString()
        })
      } else {
        uni.removeTabBarBadge({ index: 3 })
      }
    }
  }
}

TabBar索引说明

根据 pages.json 中的配置,tabBar的索引顺序为:

索引 页面 文本
0 pages/index 首页
1 pages/task/index 任务
2 pages/task/create 创建任务
3 pages/message/index 消息
4 pages/mine/index 我的

因此消息页面的索引是 3

徽标显示规则

1. 数字显示规则

  • 1-99: 显示实际数字(如 "1", "5", "25")
  • ≥100: 显示 "99+"

2. 显示/隐藏规则

  • 有未读消息: 显示红色徽标 + 数字
  • 无未读消息: 隐藏徽标

3. 更新时机

  • ✅ App启动时
  • ✅ App从后台切回前台
  • ✅ 每30秒自动轮询
  • ✅ 进入消息页面时
  • ✅ 标记消息为已读后
  • ✅ 进入首页时

API调用

获取未读消息数量

import { getUnreadCount } from '@/api/message'

getUnreadCount().then(response => {
  const count = response.data || 0
  // 使用count更新徽标
})

后端接口: GET /system/message/unread/count

返回格式:
json { "code": 200, "data": 5, // 未读消息数量 "msg": "查询成功" }

uni-app API说明

设置TabBar徽标

uni.setTabBarBadge({
  index: 3,                    // TabBar索引
  text: '5'                    // 显示文本(字符串类型)
})

移除TabBar徽标

uni.removeTabBarBadge({
  index: 3                     // TabBar索引
})

实现效果

有未读消息

┌─────────┐
│  消息   │
│  [🔴3]  │  ← 红色徽标显示未读数量
└─────────┘

无未读消息

┌─────────┐
│  消息   │
│         │  ← 无徽标
└─────────┘

超过99条

┌─────────┐
│  消息   │
│ [🔴99+] │  ← 显示99+
└─────────┘

性能优化

1. 轮询机制

  • 使用30秒间隔轮询
  • 避免频繁请求消耗资源
  • 用户登出时自动停止轮询

2. 按需更新

  • 只在必要时更新徽标
  • 避免重复的API调用
  • 使用本地缓存优先

3. 错误处理

  • API失败时不影响其他功能
  • 静默失败,记录日志
  • 下次轮询时重试

测试场景

1. 正常流程测试

  • ✅ 启动应用,显示未读数量
  • ✅ 进入消息页面,点击消息
  • ✅ 标记为已读后,徽标数量减1
  • ✅ 全部已读后,徽标消失

2. 边界情况测试

  • ✅ 0条未读:不显示徽标
  • ✅ 1条未读:显示"1"
  • ✅ 99条未读:显示"99"
  • ✅ 100+条未读:显示"99+"

3. 异常情况测试

  • ✅ 网络断开:使用上次缓存数据
  • ✅ API失败:不影响其他功能
  • ✅ 登出状态:停止轮询和显示

相关文件

前端文件

  • app/App.vue - 全局轮询和更新
  • app/pages/index.vue - 首页消息入口
  • app/pages/message/index.vue - 消息列表页
  • app/api/message.js - 消息API
  • app/pages.json - TabBar配置

后端文件

  • SysMessageController.java - 消息控制器
  • SysMessageService.java - 消息服务
  • SysMessageMapper.xml - 消息数据查询

注意事项

  1. ⚠️ TabBar索引: 必须确保索引正确(消息页为3)
  2. ⚠️ 文本类型: uni.setTabBarBadge 的text参数必须是字符串
  3. ⚠️ 轮询清理: 确保在适当时机清理定时器
  4. ⚠️ 登录状态: 只在已登录状态下轮询
  5. 用户体验: 实时更新,无需手动刷新

扩展功能建议

1. 消息推送集成

  • 集成uni-push
  • 接收服务器推送
  • 实时更新徽标

2. 分类统计

  • 系统消息数量
  • 任务通知数量
  • 按类型显示不同颜色

3. 消息提示音

  • 新消息到达时播放提示音
  • 支持震动提醒
  • 用户可自定义设置

实现时间: 2025-10-26
实现人: AI Assistant
状态: ✅ 已完成
版本: v1.0