feat(push): 添加推送服务功能支持
- 新增推送相关的类型定义,包括消息类型、聊天类型、推送配置等接口 - 实现 HarmonyOS 推送 SDK,集成 HarmonyOS NEXT Push Kit 服务 - 实现 iOS 推送 SDK,支持 APNS 推送注册和消息接收 - 添加服务器端 APNS 推送提供商,支持 JWT 认证和推送消息发送 - 添加服务器端 HarmonyOS 推送提供商基础框架 - 集成推送配置加载和路由功能,支持多渠道推送分类管理
这个提交包含在:
父节点
60171ed90c
当前提交
6c11380a36
2
.hvigor/cache/file-cache.json
vendored
2
.hvigor/cache/file-cache.json
vendored
文件差异因一行或多行过长而隐藏
2
.hvigor/cache/task-cache.json
vendored
2
.hvigor/cache/task-cache.json
vendored
文件差异因一行或多行过长而隐藏
@ -32,20 +32,20 @@
|
|||||||
"IS_HVIGORFILE_TYPE_CHECK": false,
|
"IS_HVIGORFILE_TYPE_CHECK": false,
|
||||||
"TASK_TIME": {
|
"TASK_TIME": {
|
||||||
"923fe53966c6cd9343e11af776cd4b05be315ea4b200b02e4d5dfb0f929b73bf": {
|
"923fe53966c6cd9343e11af776cd4b05be315ea4b200b02e4d5dfb0f929b73bf": {
|
||||||
"CreateModuleInfo": 299292,
|
"CreateModuleInfo": 293166,
|
||||||
"PreCheckSyscap": 126000,
|
"PreCheckSyscap": 112917,
|
||||||
"ProcessIntegratedHsp": 331000,
|
"ProcessIntegratedHsp": 261375,
|
||||||
"SyscapTransform": 7137708,
|
"SyscapTransform": 11097875,
|
||||||
"ProcessStartupConfig": 783208,
|
"ProcessStartupConfig": 704125,
|
||||||
"ConfigureCmake": 53875,
|
"ConfigureCmake": 54750,
|
||||||
"BuildNativeWithCmake": 53292,
|
"BuildNativeWithCmake": 55208,
|
||||||
"BuildNativeWithNinja": 121458,
|
"BuildNativeWithNinja": 126708,
|
||||||
"BuildJS": 653333
|
"BuildJS": 622708
|
||||||
},
|
},
|
||||||
"77aabe6c19463543339f337db9c84e4d10fd2f56ea0aedaf85a0214d59e93ec4": {
|
"77aabe6c19463543339f337db9c84e4d10fd2f56ea0aedaf85a0214d59e93ec4": {
|
||||||
"ConfigureCmake": 76458,
|
"ConfigureCmake": 67416,
|
||||||
"BuildNativeWithCmake": 126167,
|
"BuildNativeWithCmake": 116292,
|
||||||
"BuildNativeWithNinja": 223750
|
"BuildNativeWithNinja": 239792
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"APIS": [
|
"APIS": [
|
||||||
@ -56,157 +56,157 @@
|
|||||||
"ENABLE_CPP_FUNCTION_LEVEL_INCREMENTAL": false
|
"ENABLE_CPP_FUNCTION_LEVEL_INCREMENTAL": false
|
||||||
},
|
},
|
||||||
"CONFIG_PROPERTIES": {},
|
"CONFIG_PROPERTIES": {},
|
||||||
"BUILD_ID": "202605051732210700",
|
"BUILD_ID": "202605052221561580",
|
||||||
"ERROR_MESSAGE": [
|
"ERROR_MESSAGE": [
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605040",
|
"CODE": "10605040",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605040",
|
"CODE": "10605040",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605008",
|
"CODE": "10605008",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605008",
|
"CODE": "10605008",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605008",
|
"CODE": "10605008",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605008",
|
"CODE": "10605008",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605008",
|
"CODE": "10605008",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605040",
|
"CODE": "10605040",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10605038",
|
"CODE": "10605038",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10505001",
|
"CODE": "10505001",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CODE": "10505001",
|
"CODE": "10505001",
|
||||||
"TIMESTAMP": "1777973544163"
|
"TIMESTAMP": "1777990919564"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"TOTAL_TIME": 3094060000
|
"TOTAL_TIME": 3406688333
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,3 +176,30 @@ export interface PushTokenInfo {
|
|||||||
token: string
|
token: string
|
||||||
platform: string
|
platform: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PushNotificationChannelConfig {
|
||||||
|
key: string
|
||||||
|
channelId: string
|
||||||
|
version: number
|
||||||
|
name: string
|
||||||
|
description?: string
|
||||||
|
importance: string
|
||||||
|
sound: boolean
|
||||||
|
vibration: boolean
|
||||||
|
badge: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PushNotificationRouteConfig {
|
||||||
|
channel: string
|
||||||
|
category: string
|
||||||
|
priority: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PushServiceConfig {
|
||||||
|
channels?: PushNotificationChannelConfig[]
|
||||||
|
routing?: Record<string, PushNotificationRouteConfig>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SdkConfigData {
|
||||||
|
pushConfig?: PushServiceConfig
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { pushService } from '@kit.PushKit'
|
import { pushService } from '@kit.PushKit'
|
||||||
import { HttpClient } from '../core/HttpClient'
|
import { HttpClient } from '../core/HttpClient'
|
||||||
import { SDKContext } from '../core/SDKContext'
|
import { SDKContext } from '../core/SDKContext'
|
||||||
|
import type { PushNotificationRouteConfig, PushServiceConfig, SdkConfigData } from '../core/Types'
|
||||||
|
|
||||||
const HARMONY_PUSH_VENDOR = 'HARMONY'
|
const HARMONY_PUSH_VENDOR = 'HARMONY'
|
||||||
const HARMONY_PLATFORM = 'HARMONY'
|
const HARMONY_PLATFORM = 'HARMONY'
|
||||||
@ -13,6 +14,9 @@ class PushRegisterBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PushSDK {
|
export class PushSDK {
|
||||||
|
private static pushConfig: PushServiceConfig | null = null
|
||||||
|
private static configLoadedAt: number = 0
|
||||||
|
|
||||||
async initPush(imUserId?: string): Promise<void> {
|
async initPush(imUserId?: string): Promise<void> {
|
||||||
await PushSDK.initPush(imUserId)
|
await PushSDK.initPush(imUserId)
|
||||||
}
|
}
|
||||||
@ -37,6 +41,7 @@ export class PushSDK {
|
|||||||
*/
|
*/
|
||||||
static async initPush(imUserId?: string): Promise<void> {
|
static async initPush(imUserId?: string): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
await PushSDK.applyTenantConfiguration()
|
||||||
const token: string = await pushService.getToken()
|
const token: string = await pushService.getToken()
|
||||||
if (token && token.length > 0) {
|
if (token && token.length > 0) {
|
||||||
await PushSDK.registerToken(token, imUserId)
|
await PushSDK.registerToken(token, imUserId)
|
||||||
@ -60,6 +65,7 @@ export class PushSDK {
|
|||||||
*/
|
*/
|
||||||
static async registerToken(token: string, imUserId?: string): Promise<void> {
|
static async registerToken(token: string, imUserId?: string): Promise<void> {
|
||||||
const config = SDKContext.getConfig()
|
const config = SDKContext.getConfig()
|
||||||
|
await PushSDK.applyTenantConfiguration()
|
||||||
const userId = imUserId ?? SDKContext.getUserId()
|
const userId = imUserId ?? SDKContext.getUserId()
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
console.warn('[XuqmSDK] Push registration skipped: IM user id is empty.')
|
console.warn('[XuqmSDK] Push registration skipped: IM user id is empty.')
|
||||||
@ -98,6 +104,47 @@ export class PushSDK {
|
|||||||
await HttpClient.delete<void>('/api/push/unregister', query)
|
await HttpClient.delete<void>('/api/push/unregister', query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async applyTenantConfiguration(force: boolean = false): Promise<void> {
|
||||||
|
const now = Date.now()
|
||||||
|
if (!force && PushSDK.pushConfig && now - PushSDK.configLoadedAt < 5 * 60 * 1000) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const config = SDKContext.getConfig()
|
||||||
|
const query = PushSDK.queryString([
|
||||||
|
new QueryItem('appId', config.appKey),
|
||||||
|
new QueryItem('platform', HARMONY_PLATFORM),
|
||||||
|
])
|
||||||
|
try {
|
||||||
|
const data = await HttpClient.get<SdkConfigData>('/api/sdk/config', query)
|
||||||
|
PushSDK.pushConfig = data?.pushConfig ?? null
|
||||||
|
PushSDK.configLoadedAt = now
|
||||||
|
PushSDK.persistRouteChannels()
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('[XuqmSDK] Push config load failed:', JSON.stringify(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static routeOptions(routeType: string): PushNotificationRouteConfig | null {
|
||||||
|
return PushSDK.pushConfig?.routing?.[routeType] ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
private static persistRouteChannels(): void {
|
||||||
|
const config = PushSDK.pushConfig
|
||||||
|
if (!config?.channels || !config.routing) return
|
||||||
|
const channelByKey: Record<string, string> = {}
|
||||||
|
for (const channel of config.channels) {
|
||||||
|
const version = Math.max(channel.version ?? 1, 1)
|
||||||
|
channelByKey[channel.key] = `${channel.channelId}_v${version}`
|
||||||
|
}
|
||||||
|
for (const routeType of Object.keys(config.routing)) {
|
||||||
|
const route = config.routing[routeType]
|
||||||
|
const channelId = channelByKey[route.channel] ?? ''
|
||||||
|
if (channelId.length > 0) {
|
||||||
|
console.info(`[XuqmSDK] Push route ${routeType} uses channel ${channelId}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static queryString(items: QueryItem[]): string {
|
private static queryString(items: QueryItem[]): string {
|
||||||
const parts: string[] = []
|
const parts: string[] = []
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户