feat(push): 添加推送服务功能支持
- 新增推送相关的类型定义,包括消息类型、聊天类型、推送配置等接口 - 实现 HarmonyOS 推送 SDK,集成 HarmonyOS NEXT Push Kit 服务 - 实现 iOS 推送 SDK,支持 APNS 推送注册和消息接收 - 添加服务器端 APNS 推送提供商,支持 JWT 认证和推送消息发送 - 添加服务器端 HarmonyOS 推送提供商基础框架 - 集成推送配置加载和路由功能,支持多渠道推送分类管理
这个提交包含在:
父节点
edfb3bac2e
当前提交
0f57fe3b71
1
tenant-platform/components.d.ts
vendored
1
tenant-platform/components.d.ts
vendored
@ -46,6 +46,7 @@ declare module 'vue' {
|
||||
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElSegmented: typeof import('element-plus/es')['ElSegmented']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSlider: typeof import('element-plus/es')['ElSlider']
|
||||
ElSpace: typeof import('element-plus/es')['ElSpace']
|
||||
|
||||
@ -77,6 +77,7 @@ export interface PushServiceConfig {
|
||||
oppo?: PushVendorConfig
|
||||
vivo?: PushVendorConfig
|
||||
honor?: PushVendorConfig
|
||||
harmony?: PushVendorConfig
|
||||
apns?: PushVendorConfig
|
||||
fcm?: PushVendorConfig
|
||||
channels?: PushNotificationChannelConfig[]
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
<el-descriptions-item label="服务状态">
|
||||
<el-tag :type="pushEnabled ? 'success' : 'info'">{{ pushEnabled ? '已开通' : '未开通' }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="配置平台">
|
||||
<el-segmented v-model="selectedPlatform" :options="platformOptions" @change="applySelectedPlatformConfig" />
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div class="push-switch-row">
|
||||
<el-switch :model-value="pushEnabled" @change="(val: boolean) => onTogglePushService(val)" />
|
||||
@ -176,6 +179,12 @@ const services = ref<FeatureService[]>([])
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const isMobile = ref(window.innerWidth < 768)
|
||||
const selectedPlatform = ref<'ANDROID' | 'IOS' | 'HARMONY'>('ANDROID')
|
||||
const platformOptions = [
|
||||
{ label: 'Android', value: 'ANDROID' },
|
||||
{ label: 'iOS', value: 'IOS' },
|
||||
{ label: '鸿蒙', value: 'HARMONY' },
|
||||
]
|
||||
|
||||
function updateViewport() {
|
||||
isMobile.value = window.innerWidth < 768
|
||||
@ -187,6 +196,7 @@ const pushConfig = reactive<Required<PushServiceConfig>>({
|
||||
oppo: { appId: '', appKey: '', masterSecret: '' },
|
||||
vivo: { appId: '', appKey: '', appSecret: '' },
|
||||
honor: { appId: '', clientId: '', clientSecret: '' },
|
||||
harmony: { appId: '', appSecret: '' },
|
||||
apns: { teamId: '', keyId: '', bundleId: '', keyPath: '', sandbox: false },
|
||||
fcm: { serviceAccountJson: '' },
|
||||
channels: defaultChannels(),
|
||||
@ -263,6 +273,15 @@ const vendorDefs: VendorDef[] = [
|
||||
{ key: 'clientSecret', label: 'ClientSecret' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'harmony',
|
||||
label: '鸿蒙 Push Kit',
|
||||
hint: '填写 HarmonyOS Push Kit AppId / AppSecret。',
|
||||
fields: [
|
||||
{ key: 'appId', label: 'AppId' },
|
||||
{ key: 'appSecret', label: 'AppSecret' },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'apns',
|
||||
label: 'APNs(iOS)',
|
||||
@ -277,8 +296,10 @@ const vendorDefs: VendorDef[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const pushEnabled = computed(() => services.value.some(s => s.serviceType === 'PUSH' && s.enabled))
|
||||
const servicePlatform = computed(() => services.value.find(s => s.serviceType === 'PUSH')?.platform ?? 'ANDROID')
|
||||
const pushEnabled = computed(() => services.value.some(
|
||||
s => s.serviceType === 'PUSH' && s.platform === selectedPlatform.value && s.enabled,
|
||||
))
|
||||
const servicePlatform = computed(() => selectedPlatform.value)
|
||||
|
||||
async function loadData() {
|
||||
const id = route.params.appId as string
|
||||
@ -288,16 +309,28 @@ async function loadData() {
|
||||
])
|
||||
app.value = appRes.data.data
|
||||
services.value = svcRes.data.data
|
||||
applyConfig(services.value.find(s => s.serviceType === 'PUSH')?.config)
|
||||
const firstPushService = services.value.find(s => s.serviceType === 'PUSH')
|
||||
if (firstPushService && !services.value.some(s => s.serviceType === 'PUSH' && s.platform === selectedPlatform.value)) {
|
||||
selectedPlatform.value = firstPushService.platform
|
||||
}
|
||||
applySelectedPlatformConfig()
|
||||
}
|
||||
|
||||
function applySelectedPlatformConfig() {
|
||||
applyConfig(services.value.find(
|
||||
s => s.serviceType === 'PUSH' && s.platform === selectedPlatform.value,
|
||||
)?.config)
|
||||
}
|
||||
|
||||
function applyConfig(raw?: string | null) {
|
||||
resetPushConfig()
|
||||
const parsed = parseConfig(raw)
|
||||
pushConfig.huawei = { ...pushConfig.huawei, ...parsed.huawei }
|
||||
pushConfig.xiaomi = { ...pushConfig.xiaomi, ...parsed.xiaomi }
|
||||
pushConfig.oppo = { ...pushConfig.oppo, ...parsed.oppo }
|
||||
pushConfig.vivo = { ...pushConfig.vivo, ...parsed.vivo }
|
||||
pushConfig.honor = { ...pushConfig.honor, ...parsed.honor }
|
||||
pushConfig.harmony = { ...pushConfig.harmony, ...parsed.harmony }
|
||||
pushConfig.apns = { ...pushConfig.apns, ...parsed.apns }
|
||||
pushConfig.fcm = { ...pushConfig.fcm, ...parsed.fcm }
|
||||
pushConfig.channels = normalizeChannels(parsed.channels)
|
||||
@ -305,6 +338,19 @@ function applyConfig(raw?: string | null) {
|
||||
originalChannels.value = pushConfig.channels.map(channel => ({ ...channel }))
|
||||
}
|
||||
|
||||
function resetPushConfig() {
|
||||
pushConfig.huawei = { appId: '', appSecret: '' }
|
||||
pushConfig.xiaomi = { appId: '', appKey: '', appSecret: '' }
|
||||
pushConfig.oppo = { appId: '', appKey: '', masterSecret: '' }
|
||||
pushConfig.vivo = { appId: '', appKey: '', appSecret: '' }
|
||||
pushConfig.honor = { appId: '', clientId: '', clientSecret: '' }
|
||||
pushConfig.harmony = { appId: '', appSecret: '' }
|
||||
pushConfig.apns = { teamId: '', keyId: '', bundleId: '', keyPath: '', sandbox: false }
|
||||
pushConfig.fcm = { serviceAccountJson: '' }
|
||||
pushConfig.channels = defaultChannels()
|
||||
pushConfig.routing = defaultRouting()
|
||||
}
|
||||
|
||||
function parseConfig(raw?: string | null): PushServiceConfig {
|
||||
if (!raw) return {}
|
||||
try {
|
||||
@ -345,6 +391,8 @@ function toPushConfigRequest(): Record<string, unknown> {
|
||||
honorAppId: pushConfig.honor.appId ?? '',
|
||||
honorClientId: pushConfig.honor.clientId ?? '',
|
||||
honorClientSecret: pushConfig.honor.clientSecret ?? '',
|
||||
harmonyAppId: pushConfig.harmony.appId ?? '',
|
||||
harmonyAppSecret: pushConfig.harmony.appSecret ?? '',
|
||||
apnsTeamId: pushConfig.apns.teamId ?? '',
|
||||
apnsKeyId: pushConfig.apns.keyId ?? '',
|
||||
apnsBundleId: pushConfig.apns.bundleId ?? '',
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户