fix bugs
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* iOS 远程推送消息封装(原生插件:NetworkUtils-NetworkUtilsModule)
|
||||
* 对应原生方法:onPushNotificationAsync、consumePendingPushNotificationsAsync
|
||||
*/
|
||||
// #ifdef APP-PLUS
|
||||
const pushNetworkModule = uni.requireNativePlugin('NetworkUtils-NetworkUtilsModule')
|
||||
// #endif
|
||||
|
||||
let lastPushNotification = null
|
||||
const processedPushKeys = {}
|
||||
|
||||
function getPushDedupeKey(title, content) {
|
||||
return `${title || ''}|${content || ''}`
|
||||
}
|
||||
|
||||
function markPushProcessed(title, content) {
|
||||
const key = getPushDedupeKey(title, content)
|
||||
processedPushKeys[key] = true
|
||||
return key
|
||||
}
|
||||
|
||||
function isPushProcessed(title, content) {
|
||||
return !!processedPushKeys[getPushDedupeKey(title, content)]
|
||||
}
|
||||
|
||||
function dispatchPushMessage(onMessage, payload, meta = {}) {
|
||||
if (!meta.userTapped && isPushProcessed(payload.title, payload.content)) {
|
||||
console.log('[Push] skip duplicate push:', getPushDedupeKey(payload.title, payload.content))
|
||||
return
|
||||
}
|
||||
markPushProcessed(payload.title, payload.content)
|
||||
lastPushNotification = payload
|
||||
if (typeof onMessage === 'function') {
|
||||
onMessage(payload, meta)
|
||||
}
|
||||
}
|
||||
|
||||
function parseUserTappedFlag(value) {
|
||||
return value === true || value === 1 || value === '1' || value === 'true'
|
||||
}
|
||||
|
||||
function getPushConfirmNo(res = {}) {
|
||||
const confirmNo = res.ConfirmNo || res.confirmNo || res.confNo || res.raw?.ConfirmNo || res.raw?.confirmNo || res.raw?.confNo
|
||||
return confirmNo ? String(confirmNo) : ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 将原生回调数据规范化为 { title, content, body, confirmNo, userTapped, raw }
|
||||
* @param {Record<string, unknown>} res
|
||||
*/
|
||||
export function normalizePushPayload(res = {}) {
|
||||
const title = typeof res.title === 'string' ? res.title : (res.title ? String(res.title) : '')
|
||||
const body = typeof res.body === 'string' ? res.body : (res.body ? String(res.body) : '')
|
||||
const confirmNo = getPushConfirmNo(res)
|
||||
return {
|
||||
title,
|
||||
content: body,
|
||||
body,
|
||||
confirmNo,
|
||||
userTapped: parseUserTappedFlag(res.userTapped),
|
||||
raw: res
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最近一次收到的推送(内存缓存)
|
||||
*/
|
||||
export function getLastPushNotification() {
|
||||
return lastPushNotification
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取并清空 Native 侧缓存的待处理推送(后台/冷启动场景)
|
||||
* @returns {Promise<Array<{ title: string, content: string, body: string, raw: object }>>}
|
||||
*/
|
||||
export function consumePendingPushNotifications() {
|
||||
return new Promise((resolve) => {
|
||||
// #ifdef APP-PLUS
|
||||
if (!pushNetworkModule) {
|
||||
console.error('[Push] NetworkUtils 原生插件不可用')
|
||||
resolve([])
|
||||
return
|
||||
}
|
||||
if (typeof pushNetworkModule.consumePendingPushNotificationsAsync !== 'function') {
|
||||
console.warn('[Push] 原生暂不支持 consumePendingPushNotificationsAsync,跳过 Native pending 同步')
|
||||
resolve([])
|
||||
return
|
||||
}
|
||||
console.log('[Push] 调用 consumePendingPushNotificationsAsync ...')
|
||||
pushNetworkModule.consumePendingPushNotificationsAsync({}, (ret) => {
|
||||
const items = Array.isArray(ret?.items) ? ret.items : []
|
||||
console.log('[Push] consumePendingPushNotificationsAsync 返回 count=', ret?.count ?? items.length)
|
||||
resolve(items.map((item) => normalizePushPayload(item)))
|
||||
})
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
resolve([])
|
||||
// #endif
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步处理 Native 缓存的推送
|
||||
* @param {(payload: { title: string, content: string, body: string, raw: object }, meta?: object) => void} onMessage
|
||||
* @param {{ showToast?: boolean }} [options]
|
||||
*/
|
||||
export async function syncPendingPushNotifications(onMessage, options = {}) {
|
||||
console.log('[Push] syncPendingPushNotifications start')
|
||||
const pending = await consumePendingPushNotifications()
|
||||
if (!pending.length) {
|
||||
console.log('[Push] syncPendingPushNotifications: 队列为空')
|
||||
return pending
|
||||
}
|
||||
console.log('[Push] syncPendingPushNotifications count=', pending.length)
|
||||
for (const payload of pending) {
|
||||
dispatchPushMessage(onMessage, payload, {
|
||||
fromPending: true,
|
||||
userTapped: payload.userTapped === true,
|
||||
showToast: options.showToast !== false
|
||||
})
|
||||
}
|
||||
return pending
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册推送消息监听;每次收到远程推送时 callback 会被调用
|
||||
* @param {(payload: { title: string, content: string, body: string, raw: object }, meta?: object) => void} onMessage
|
||||
* @returns {() => void}
|
||||
*/
|
||||
export function listenPushNotification(onMessage) {
|
||||
// #ifdef APP-PLUS
|
||||
if (!pushNetworkModule || typeof pushNetworkModule.onPushNotificationAsync !== 'function') {
|
||||
console.warn('[Push] NetworkUtils 原生插件不可用或未注册 onPushNotificationAsync')
|
||||
return () => {}
|
||||
}
|
||||
pushNetworkModule.onPushNotificationAsync({}, (res) => {
|
||||
const payload = normalizePushPayload(res)
|
||||
console.log('[Push] 收到推送通知:', JSON.stringify(payload))
|
||||
dispatchPushMessage(onMessage, payload, {
|
||||
fromPending: !!res?.fromPending,
|
||||
userTapped: payload.userTapped === true,
|
||||
showToast: true
|
||||
})
|
||||
})
|
||||
return () => {}
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
console.warn('[Push] 非 App-PLUS 环境,跳过推送监听')
|
||||
return () => {}
|
||||
// #endif
|
||||
}
|
||||
Reference in New Issue
Block a user