159 lines
3.6 KiB
JavaScript
159 lines
3.6 KiB
JavaScript
/**
|
||
* 消息轮询工具
|
||
* 用于定期检查未读消息数量并更新TabBar角标
|
||
*/
|
||
import request from './request'
|
||
|
||
class MessagePolling {
|
||
constructor() {
|
||
this.timer = null
|
||
this.interval = 30000 // 30秒轮询一次
|
||
this.isPolling = false
|
||
this.tabBarIndex = 3 // 消息中心Tab索引(根据实际情况调整)
|
||
this.tabBarRoutes = [
|
||
'pages/index/index',
|
||
'pages/service/list',
|
||
'pages/booking/quick-booking',
|
||
'pages/order/list',
|
||
'pages/user/index'
|
||
]
|
||
}
|
||
|
||
updateTabBarBadge(totalCount) {
|
||
if (typeof uni?.setTabBarBadge !== 'function' || typeof uni?.removeTabBarBadge !== 'function') {
|
||
return
|
||
}
|
||
|
||
if (totalCount > 0) {
|
||
uni.setTabBarBadge({
|
||
index: this.tabBarIndex,
|
||
text: totalCount > 99 ? '99+' : totalCount.toString(),
|
||
fail: (err) => {
|
||
if (err?.errMsg && err.errMsg.indexOf('not TabBar page') !== -1) {
|
||
return
|
||
}
|
||
console.warn('[MessagePolling] setTabBarBadge failed:', err)
|
||
}
|
||
})
|
||
} else {
|
||
uni.removeTabBarBadge({
|
||
index: this.tabBarIndex,
|
||
fail: (err) => {
|
||
if (err?.errMsg && err.errMsg.indexOf('not TabBar page') !== -1) {
|
||
return
|
||
}
|
||
console.warn('[MessagePolling] removeTabBarBadge failed:', err)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 开始轮询
|
||
*/
|
||
start() {
|
||
if (this.isPolling) {
|
||
console.log('[MessagePolling] 轮询已在运行中')
|
||
return
|
||
}
|
||
|
||
console.log('[MessagePolling] 开始轮询')
|
||
this.isPolling = true
|
||
|
||
// 立即执行一次
|
||
this.poll()
|
||
|
||
// 定时轮询
|
||
this.timer = setInterval(() => {
|
||
this.poll()
|
||
}, this.interval)
|
||
}
|
||
|
||
/**
|
||
* 停止轮询
|
||
*/
|
||
stop() {
|
||
if (this.timer) {
|
||
clearInterval(this.timer)
|
||
this.timer = null
|
||
}
|
||
this.isPolling = false
|
||
console.log('[MessagePolling] 停止轮询')
|
||
}
|
||
|
||
/**
|
||
* 执行一次轮询
|
||
*/
|
||
async poll() {
|
||
try {
|
||
const userInfo = uni.getStorageSync('userInfo')
|
||
const userId = userInfo?.id || userInfo?.userId
|
||
const res = await request.get('/api/message/unread-count', { userId })
|
||
|
||
if (res.code === 200) {
|
||
const totalCount = typeof res.data === 'number'
|
||
? res.data
|
||
: (res.data?.total || 0)
|
||
|
||
console.log('[MessagePolling] 未读消息数:', totalCount)
|
||
|
||
// 更新TabBar角标
|
||
this.updateTabBarBadge(totalCount)
|
||
|
||
// 触发全局事件,通知其他页面更新
|
||
uni.$emit('unreadCountUpdate', {
|
||
total: totalCount,
|
||
detail: res.data
|
||
})
|
||
}
|
||
} catch (e) {
|
||
console.error('[MessagePolling] 轮询失败:', e)
|
||
// 轮询失败不影响主流程,只记录日志
|
||
}
|
||
}
|
||
|
||
isTabBarPage() {
|
||
try {
|
||
const pages = getCurrentPages()
|
||
const currentPage = pages && pages.length ? pages[pages.length - 1] : null
|
||
const route = currentPage && currentPage.route ? currentPage.route : ''
|
||
return !!route && this.tabBarRoutes.includes(route)
|
||
} catch (e) {
|
||
return false
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 设置TabBar索引
|
||
*/
|
||
setTabBarIndex(index) {
|
||
this.tabBarIndex = index
|
||
}
|
||
|
||
/**
|
||
* 设置轮询间隔(毫秒)
|
||
*/
|
||
setInterval(interval) {
|
||
this.interval = interval
|
||
|
||
// 如果正在轮询,重启以应用新间隔
|
||
if (this.isPolling) {
|
||
this.stop()
|
||
this.start()
|
||
}
|
||
}
|
||
}
|
||
|
||
// 导出单例
|
||
const messagePolling = new MessagePolling()
|
||
|
||
export function startMessagePolling() {
|
||
messagePolling.start()
|
||
}
|
||
|
||
export function stopMessagePolling() {
|
||
messagePolling.stop()
|
||
}
|
||
|
||
export default messagePolling
|