Commit 7a09fd1f authored by wp song's avatar wp song

feat(push): 添加5+App推送支持并重构推送模块

扩展推送模块以支持5+App环境,包括客户端ID获取、消息监听和权限处理
重构原有uni-app推送逻辑,增加环境检测和错误处理
添加5+App原生推送API的回退方案和自定义客户端ID生成
统一推送消息处理接口,兼容两种环境的不同实现
parent 45b2ed9f
Pipeline #11063 passed with stage
...@@ -3,6 +3,7 @@ import { getCurrentInstance } from 'vue' ...@@ -3,6 +3,7 @@ import { getCurrentInstance } from 'vue'
class UniPush { class UniPush {
constructor() { constructor() {
this.isUniApp = typeof uni !== 'undefined' this.isUniApp = typeof uni !== 'undefined'
this.is5PlusApp = typeof plus !== 'undefined' && !this.isUniApp
this.clientId = null this.clientId = null
this.pushEnabled = false this.pushEnabled = false
this.forceNotificationMode = false // 是否使用 force_notification:true 模式 this.forceNotificationMode = false // 是否使用 force_notification:true 模式
...@@ -10,70 +11,197 @@ class UniPush { ...@@ -10,70 +11,197 @@ class UniPush {
} }
async init() { async init() {
if (!this.isUniApp) { if (!this.isUniApp && !this.is5PlusApp) {
console.warn('当前环境不是uni-app,无法使用uni-push功能') console.warn('当前环境不是uni-app或5+App,无法使用推送功能')
return return
} }
try { try {
// 获取客户端标识 // 获取客户端标识
const info = await this.getClientInfo() const info = await this.getClientInfo()
uni.showModal({
title: 'uni-push客户端ID', // 显示客户端ID(仅开发环境使用)
content:JSON.stringify(info), // if (process.env.NODE_ENV === 'development') {
showCancel: false if (this.isUniApp) {
}) uni.showModal({
title: 'uni-push客户端ID',
content:JSON.stringify(info),
showCancel: false
})
} else if (this.is5PlusApp && plus.nativeUI) {
plus.nativeUI.alert(JSON.stringify(info), () => {}, '5+App推送客户端ID')
}
// }
this.clientId = info.clientId this.clientId = info.clientId
console.log('uni-push客户端ID:', this.clientId) console.log('推送客户端ID:', this.clientId)
// 监听推送消息 // 监听推送消息
this.setupPushListener() this.setupPushListener()
this.pushEnabled = true this.pushEnabled = true
} catch (error) { } catch (error) {
console.error('uni-push初始化失败:', error) console.error('推送初始化失败:', error)
} }
} }
// 获取客户端信息 // 获取客户端信息
getClientInfo() { getClientInfo() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!this.isUniApp) { if (this.isUniApp) {
reject(new Error('非uni-app环境')) // uni-app 环境
return uni.getPushClientId({
} success: (res) => {
resolve({
uni.getPushClientId({ clientId: res.cid,
success: (res) => { platform: 'uniapp'
resolve({ })
clientId: res.cid },
fail: (err) => {
reject(err)
}
})
} else if (this.is5PlusApp) {
// 5+App 环境 - 优先尝试使用原生推送API
if (plus.push && typeof plus.push.getClientInfoAsync === 'function') {
plus.push.getClientInfoAsync((result) => {
if (result && result.clientid) {
// 成功获取到推送客户端ID
resolve({
clientId: result.clientid,
platform: '5plus',
appid: result.appid,
token: result.token
})
} else {
// 原生推送不可用,回退到自定义生成
this.fallbackToCustomClientId(resolve, reject)
}
}, (error) => {
// 获取失败,回退到自定义生成
console.warn('plus.push.getClientInfoAsync 失败:', error)
this.fallbackToCustomClientId(resolve, reject)
}) })
}, } else {
fail: (err) => { // 原生推送API不可用,使用自定义生成
reject(err) this.fallbackToCustomClientId(resolve, reject)
} }
}) } else {
reject(new Error('不支持的环境'))
}
}) })
} }
// 回退到自定义客户端ID生成
fallbackToCustomClientId(resolve, reject) {
try {
const deviceInfo = plus.device
const clientId = this.generate5PlusClientId()
resolve({
clientId: clientId,
platform: '5plus',
deviceId: deviceInfo.uuid || deviceInfo.imei || 'unknown',
fallback: true // 标记为回退方案
})
} catch (error) {
reject(new Error('5+App环境获取设备信息失败'))
}
}
// 设置推送监听 // 设置推送监听
setupPushListener() { setupPushListener() {
if (!this.isUniApp) return if (this.isUniApp) {
// uni-app 环境监听
uni.onPushMessage((res) => {
console.log('推送消息类型:', res.type, '内容:', res)
if (res.type === 'click') {
// 用户点击通知栏消息(在线/离线都会触发)
console.log('用户点击了推送消息:', res)
this.handlePushClick(res)
} else if (res.type === 'receive') {
// 应用在线时接收到的消息(不使用 force_notification:true 时触发)
console.log('应用在线收到推送消息:', res)
this.handlePushMessage(res)
}
})
} else if (this.is5PlusApp) {
// 5+App 环境监听 - 使用原生推送监听
this.setup5PlusPushListener()
}
}
// 设置5+App推送监听
setup5PlusPushListener() {
if (plus.push && typeof plus.push.addEventListener === 'function') {
// 监听接收消息事件
plus.push.addEventListener('receive', (msg) => {
console.log('5+App收到推送消息:', msg)
this.handle5PlusPushMessage(msg)
}, false)
// 监听点击消息事件
plus.push.addEventListener('click', (msg) => {
console.log('5+App点击推送消息:', msg)
this.handle5PlusPushClick(msg)
}, false)
} else {
console.warn('5+App原生推送监听不可用,将使用自定义消息处理')
}
}
// 处理5+App推送消息
handle5PlusPushMessage(message) {
console.log('处理5+App推送消息:', message)
// 解析消息内容
const pushData = this.parse5PlusPushData(message)
// 触发自定义事件
if (typeof this.onMessage === 'function') {
this.onMessage(pushData)
}
}
// 处理5+App推送点击
handle5PlusPushClick(message) {
console.log('处理5+App推送点击:', message)
const pushData = this.parse5PlusPushData(message)
// 根据消息内容跳转到对应页面
if (pushData.page) {
// 这里可以添加页面跳转逻辑
console.log('跳转到页面:', pushData.page)
}
}
// 统一监听推送消息(适配 force_notification:true 模式) // 解析5+App推送数据
uni.onPushMessage((res) => { parse5PlusPushData(message) {
console.log('推送消息类型:', res.type, '内容:', res) try {
// 尝试解析JSON格式的payload
let payload = {}
if (message.payload) {
payload = typeof message.payload === 'string'
? JSON.parse(message.payload)
: message.payload
}
if (res.type === 'click') { return {
// 用户点击通知栏消息(在线/离线都会触发) type: 'receive',
console.log('用户点击了推送消息:', res) data: payload,
this.handlePushClick(res) title: message.title || payload.title,
} else if (res.type === 'receive') { content: message.content || payload.content
// 应用在线时接收到的消息(不使用 force_notification:true 时触发)
console.log('应用在线收到推送消息:', res)
this.handlePushMessage(res)
} }
}) } catch (error) {
console.warn('解析5+App推送数据失败:', error)
return {
type: 'receive',
data: {},
title: message.title,
content: message.content
}
}
} }
// 处理推送消息 // 处理推送消息
...@@ -131,78 +259,131 @@ class UniPush { ...@@ -131,78 +259,131 @@ class UniPush {
// 检查推送权限 // 检查推送权限
checkPermission() { checkPermission() {
return new Promise((resolve) => { return new Promise((resolve) => {
if (!this.isUniApp) { if (this.isUniApp) {
resolve(false) uni.getPushProvider({
return success: (res) => {
} resolve(res.provider !== 'none')
},
uni.getPushProvider({ fail: () => {
success: (res) => { resolve(false)
resolve(res.provider !== 'none') }
}, })
fail: () => { } else if (this.is5PlusApp) {
// 5+App 环境检查推送服务是否可用
if (plus.push) {
resolve(true)
} else {
resolve(false) resolve(false)
} }
}) } else {
resolve(false)
}
}) })
} }
// 请求推送权限 // 请求推送权限
requestPermission() { requestPermission() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!this.isUniApp) { if (this.isUniApp) {
reject(new Error('非uni-app环境')) uni.requestPushPermission({
return success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
} else if (this.is5PlusApp) {
// 5+App 环境通常不需要额外请求权限
// 直接返回成功,实际权限由系统控制
resolve({ status: 'granted' })
} else {
reject(new Error('不支持的环境'))
} }
uni.requestPushPermission({
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
}) })
} }
// 设置推送标签 // 设置推送标签
setTags(tags) { setTags(tags) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!this.isUniApp) { if (this.isUniApp) {
reject(new Error('非uni-app环境')) uni.setPushTags({
return tags: tags,
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
} else if (this.is5PlusApp) {
// 5+App 环境暂不支持标签设置,返回成功但不执行操作
console.log('5+App环境暂不支持推送标签设置')
resolve({ success: true })
} else {
reject(new Error('不支持的环境'))
} }
uni.setPushTags({
tags: tags,
success: (res) => {
resolve(res)
},
fail: (err) => {
reject(err)
}
})
}) })
} }
// 获取推送标签 // 获取推送标签
getTags() { getTags() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!this.isUniApp) { if (this.isUniApp) {
reject(new Error('非uni-app环境')) uni.getPushTags({
return success: (res) => {
resolve(res.tags)
},
fail: (err) => {
reject(err)
}
})
} else if (this.is5PlusApp) {
// 5+App 环境暂不支持标签获取,返回空数组
resolve([])
} else {
reject(new Error('不支持的环境'))
} }
})
}
uni.getPushTags({ // 生成 5+App 客户端ID
success: (res) => { generate5PlusClientId() {
resolve(res.tags) try {
}, let clientId = null
fail: (err) => {
reject(err) // 优先尝试使用 5+App 的本地存储
if (plus.storage) {
clientId = plus.storage.getItem('5plus_client_id')
}
// 如果 5+App 存储不可用,尝试使用浏览器 localStorage
if (!clientId && typeof localStorage !== 'undefined') {
clientId = localStorage.getItem('5plus_client_id')
}
if (!clientId) {
// 生成新的客户端ID
const deviceInfo = plus.device
const timestamp = Date.now()
const random = Math.random().toString(36).substr(2, 9)
// 使用设备信息生成唯一ID
clientId = `5plus_${deviceInfo.uuid || 'unknown'}_${timestamp}_${random}`
// 存储到本地
if (plus.storage) {
plus.storage.setItem('5plus_client_id', clientId)
} else if (typeof localStorage !== 'undefined') {
localStorage.setItem('5plus_client_id', clientId)
} }
}) }
})
return clientId
} catch (error) {
// 备用方案:使用时间戳和随机数
return `5plus_fallback_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
}
} }
// 设置 force_notification 模式 // 设置 force_notification 模式
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment