chore: sync local changes

这个提交包含在:
XuqmGroup 2026-05-07 19:39:47 +08:00
父节点 f36d657bba
当前提交 6eeea6f268
共有 17 个文件被更改,包括 239 次插入239 次删除

查看文件

@ -41,7 +41,7 @@ export interface Statistics {
export interface ServiceRequest { export interface ServiceRequest {
id: string id: string
appId: string appKey: string
platform: string platform: string
serviceType: string serviceType: string
status: 'PENDING' | 'APPROVED' | 'REJECTED' status: 'PENDING' | 'APPROVED' | 'REJECTED'
@ -69,7 +69,7 @@ export interface AppItem {
export interface FeatureServiceItem { export interface FeatureServiceItem {
id: string id: string
appId: string appKey: string
platform: string platform: string
serviceType: string serviceType: string
enabled: boolean enabled: boolean
@ -148,7 +148,7 @@ export interface PushDeviceInfo {
export interface PushDiagnostics { export interface PushDiagnostics {
tokenType: 'PUSH' | 'IM' | 'UNKNOWN' tokenType: 'PUSH' | 'IM' | 'UNKNOWN'
appId?: string appKey?: string
userId?: string userId?: string
online: boolean online: boolean
lastSeenAt: number lastSeenAt: number
@ -160,7 +160,7 @@ export interface PushDiagnostics {
export interface PushDeviceLog { export interface PushDeviceLog {
id: string id: string
appId: string appKey: string
userId: string userId: string
vendor: string vendor: string
tokenPreview: string tokenPreview: string
@ -182,7 +182,7 @@ export interface PushDeviceLogPage {
} }
export interface PushTestResult { export interface PushTestResult {
appId: string appKey: string
userId: string userId: string
sent: boolean sent: boolean
targetCount: number targetCount: number
@ -248,12 +248,12 @@ export const opsApi = {
deleteSensitiveWord: (id: string) => deleteSensitiveWord: (id: string) =>
client.delete(`/ops/risk/sensitive-words/${id}`), client.delete(`/ops/risk/sensitive-words/${id}`),
searchPushByToken: (token: string, appId = '') => searchPushByToken: (token: string, appKey = '') =>
client.get<{ data: PushDiagnostics }>('/ops/push/search', { params: { token, appId } }), client.get<{ data: PushDiagnostics }>('/ops/push/search', { params: { token, appKey } }),
listPushDeviceLogs: (appId: string, userId: string, page = 0, size = 20) => listPushDeviceLogs: (appKey: string, userId: string, page = 0, size = 20) =>
client.get<{ data: PushDeviceLogPage }>('/ops/push/device-logs', { params: { appId, userId, page, size } }), client.get<{ data: PushDeviceLogPage }>('/ops/push/device-logs', { params: { appKey, userId, page, size } }),
sendPushTestOffline: (payload: { appId: string; userId: string; title: string; body: string; payload?: string }) => sendPushTestOffline: (payload: { appKey: string; userId: string; title: string; body: string; payload?: string }) =>
client.post<{ data: PushTestResult }>('/ops/push/test-offline', payload), client.post<{ data: PushTestResult }>('/ops/push/test-offline', payload),
} }

查看文件

@ -9,7 +9,7 @@
{{ diagnostics.online ? '用户在线' : '用户离线' }} {{ diagnostics.online ? '用户在线' : '用户离线' }}
</el-tag> </el-tag>
<el-button <el-button
v-if="diagnostics?.appId && diagnostics?.userId" v-if="diagnostics?.appKey && diagnostics?.userId"
type="primary" type="primary"
:disabled="!diagnostics.deliverableDevices?.length" :disabled="!diagnostics.deliverableDevices?.length"
:loading="testLoading" :loading="testLoading"
@ -32,7 +32,7 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="AppId"> <el-form-item label="AppId">
<el-input v-model="form.appId" placeholder="可选;push token 无法解析 AppId 时使用" clearable /> <el-input v-model="form.appKey" placeholder="可选;push token 无法解析 AppId 时使用" clearable />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" :loading="loading" @click="search">查询</el-button> <el-button type="primary" :loading="loading" @click="search">查询</el-button>
@ -101,7 +101,7 @@
<template #header> <template #header>
<div class="header-row"> <div class="header-row">
<span>历史登录设备日志</span> <span>历史登录设备日志</span>
<el-button :disabled="!diagnostics.appId || !diagnostics.userId" :loading="logsLoading" @click="loadLogs"> <el-button :disabled="!diagnostics.appKey || !diagnostics.userId" :loading="logsLoading" @click="loadLogs">
刷新 刷新
</el-button> </el-button>
</div> </div>
@ -141,7 +141,7 @@ import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { opsApi, type PushDeviceInfo, type PushDeviceLog, type PushDiagnostics } from '@/api/ops' import { opsApi, type PushDeviceInfo, type PushDeviceLog, type PushDiagnostics } from '@/api/ops'
const form = reactive({ token: '', appId: '' }) const form = reactive({ token: '', appKey: '' })
const loading = ref(false) const loading = ref(false)
const logsLoading = ref(false) const logsLoading = ref(false)
const testLoading = ref(false) const testLoading = ref(false)
@ -158,12 +158,12 @@ async function search() {
} }
loading.value = true loading.value = true
try { try {
const res = await opsApi.searchPushByToken(form.token.trim(), form.appId.trim()) const res = await opsApi.searchPushByToken(form.token.trim(), form.appKey.trim())
diagnostics.value = res.data.data diagnostics.value = res.data.data
logs.value = [] logs.value = []
logTotal.value = 0 logTotal.value = 0
logPage.value = 0 logPage.value = 0
if (diagnostics.value.appId && diagnostics.value.userId) { if (diagnostics.value.appKey && diagnostics.value.userId) {
await loadLogs() await loadLogs()
} }
} finally { } finally {
@ -172,11 +172,11 @@ async function search() {
} }
async function loadLogs() { async function loadLogs() {
if (!diagnostics.value?.appId || !diagnostics.value?.userId) return if (!diagnostics.value?.appKey || !diagnostics.value?.userId) return
logsLoading.value = true logsLoading.value = true
try { try {
const res = await opsApi.listPushDeviceLogs( const res = await opsApi.listPushDeviceLogs(
diagnostics.value.appId, diagnostics.value.appKey,
diagnostics.value.userId, diagnostics.value.userId,
logPage.value, logPage.value,
logSize, logSize,
@ -194,11 +194,11 @@ function changeLogPage(page: number) {
} }
async function sendTestOffline() { async function sendTestOffline() {
if (!diagnostics.value?.appId || !diagnostics.value?.userId) return if (!diagnostics.value?.appKey || !diagnostics.value?.userId) return
testLoading.value = true testLoading.value = true
try { try {
const res = await opsApi.sendPushTestOffline({ const res = await opsApi.sendPushTestOffline({
appId: diagnostics.value.appId, appKey: diagnostics.value.appKey,
userId: diagnostics.value.userId, userId: diagnostics.value.userId,
title: 'XuqmGroup Push 测试', title: 'XuqmGroup Push 测试',
body: `离线推送测试 ${new Date().toLocaleString('zh-CN')}`, body: `离线推送测试 ${new Date().toLocaleString('zh-CN')}`,

查看文件

@ -10,7 +10,7 @@
</div> </div>
<el-table :data="requests" v-loading="loading"> <el-table :data="requests" v-loading="loading">
<el-table-column prop="appId" label="AppID" width="180" /> <el-table-column prop="appKey" label="AppID" width="180" />
<el-table-column prop="platform" label="平台" width="100"> <el-table-column prop="platform" label="平台" width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-tag size="small">{{ row.platform }}</el-tag> <el-tag size="small">{{ row.platform }}</el-tag>

查看文件

@ -25,7 +25,7 @@ export interface CreateAppRequest {
export interface FeatureService { export interface FeatureService {
id: string id: string
appId: string appKey: string
platform: 'ANDROID' | 'IOS' | 'HARMONY' platform: 'ANDROID' | 'IOS' | 'HARMONY'
serviceType: 'IM' | 'PUSH' | 'UPDATE' serviceType: 'IM' | 'PUSH' | 'UPDATE'
enabled: boolean enabled: boolean
@ -121,11 +121,11 @@ export const appApi = {
delete: (id: string) => client.delete(`/apps/${id}`), delete: (id: string) => client.delete(`/apps/${id}`),
getServices: (appId: string) => getServices: (appKey: string) =>
client.get<{ data: FeatureService[] }>(`/apps/${appId}/services`), client.get<{ data: FeatureService[] }>(`/apps/${appKey}/services`),
getService: async (appId: string, platform: string, serviceType: string) => { getService: async (appKey: string, platform: string, serviceType: string) => {
const res = await client.get<{ data: FeatureService[] }>(`/apps/${appId}/services`) const res = await client.get<{ data: FeatureService[] }>(`/apps/${appKey}/services`)
const service = res.data.data.find(item => item.platform === platform && item.serviceType === serviceType) const service = res.data.data.find(item => item.platform === platform && item.serviceType === serviceType)
if (!service) { if (!service) {
throw new Error('服务不存在') throw new Error('服务不存在')
@ -136,29 +136,29 @@ export const appApi = {
} as typeof res & { data: { data: FeatureService } } } as typeof res & { data: { data: FeatureService } }
}, },
toggleService: (appId: string, platform: string, serviceType: string, enable: boolean) => toggleService: (appKey: string, platform: string, serviceType: string, enable: boolean) =>
client.post<{ data: FeatureService }>(`/apps/${appId}/services/toggle`, null, { client.post<{ data: FeatureService }>(`/apps/${appKey}/services/toggle`, null, {
params: { platform, serviceType, enable }, params: { platform, serviceType, enable },
}), }),
updateServiceConfig: ( updateServiceConfig: (
appId: string, appKey: string,
platform: string, platform: string,
serviceType: string, serviceType: string,
config: Partial<ImServiceConfig> & Partial<UpdateServiceConfig> & Partial<PushServiceConfig> | Record<string, unknown>, config: Partial<ImServiceConfig> & Partial<UpdateServiceConfig> & Partial<PushServiceConfig> | Record<string, unknown>,
) => ) =>
client.put<{ data: FeatureService }>(`/apps/${appId}/services/config`, config, { client.put<{ data: FeatureService }>(`/apps/${appKey}/services/config`, config, {
params: { platform, serviceType }, params: { platform, serviceType },
}), }),
requestSecretVerify: (appId: string, purpose: 'REVEAL_SECRET' | 'RESET_SECRET') => requestSecretVerify: (appKey: string, purpose: 'REVEAL_SECRET' | 'RESET_SECRET') =>
client.post<{ data: null }>(`/apps/${appId}/request-secret-verify`, null, { client.post<{ data: null }>(`/apps/${appKey}/request-secret-verify`, null, {
params: { purpose }, params: { purpose },
}), }),
revealSecret: (appId: string, code: string) => revealSecret: (appKey: string, code: string) =>
client.post<{ data: { appSecret: string } }>(`/apps/${appId}/reveal-secret`, { code }), client.post<{ data: { appSecret: string } }>(`/apps/${appKey}/reveal-secret`, { code }),
resetSecret: (appId: string, code: string) => resetSecret: (appKey: string, code: string) =>
client.post<{ data: { appSecret: string } }>(`/apps/${appId}/reset-secret`, { code }), client.post<{ data: { appSecret: string } }>(`/apps/${appKey}/reset-secret`, { code }),
} }

查看文件

@ -68,7 +68,7 @@ imClient.interceptors.response.use(
export interface ImUser { export interface ImUser {
id: string id: string
appId: string appKey: string
userId: string userId: string
nickname: string nickname: string
avatar?: string avatar?: string
@ -79,7 +79,7 @@ export interface ImUser {
export interface ImProfile { export interface ImProfile {
id?: string id?: string
appId?: string appKey?: string
userId: string userId: string
nickname?: string | null nickname?: string | null
avatar?: string | null avatar?: string | null
@ -90,7 +90,7 @@ export interface ImProfile {
export interface ImGroup { export interface ImGroup {
id: string id: string
appId: string appKey: string
name: string name: string
creatorId: string creatorId: string
groupType?: string | null groupType?: string | null
@ -102,7 +102,7 @@ export interface ImGroup {
export interface ImMessage { export interface ImMessage {
id: string id: string
appId: string appKey: string
fromUserId: string fromUserId: string
toId: string toId: string
chatType: 'SINGLE' | 'GROUP' chatType: 'SINGLE' | 'GROUP'
@ -131,7 +131,7 @@ export interface ImStats {
export interface OperationLog { export interface OperationLog {
id: string id: string
appId: string appKey: string
operatorId: string operatorId: string
action: string action: string
resourceType: string resourceType: string
@ -142,7 +142,7 @@ export interface OperationLog {
export interface KeywordFilter { export interface KeywordFilter {
id: string id: string
appId: string appKey: string
pattern: string pattern: string
replacement?: string | null replacement?: string | null
action: 'REPLACE' | 'BLOCK' action: 'REPLACE' | 'BLOCK'
@ -152,7 +152,7 @@ export interface KeywordFilter {
export interface GlobalMute { export interface GlobalMute {
id: string id: string
appId: string appKey: string
enabled: boolean enabled: boolean
createdAt: number createdAt: number
updatedAt: number updatedAt: number
@ -160,7 +160,7 @@ export interface GlobalMute {
export interface WebhookConfig { export interface WebhookConfig {
id: string id: string
appId: string appKey: string
url: string url: string
secret?: string | null secret?: string | null
enabled: boolean enabled: boolean
@ -177,7 +177,7 @@ export interface WebhookConfigForm {
export interface WebhookDelivery { export interface WebhookDelivery {
id: string id: string
appId: string appKey: string
callbackId: string callbackId: string
callbackEvent: string callbackEvent: string
url: string url: string
@ -191,7 +191,7 @@ export interface WebhookDelivery {
export interface WebhookAlert { export interface WebhookAlert {
id: string id: string
appId: string appKey: string
webhookId: string webhookId: string
webhookUrl: string webhookUrl: string
alertType: string alertType: string
@ -203,7 +203,7 @@ export interface WebhookAlert {
export interface GroupJoinRequest { export interface GroupJoinRequest {
id: string id: string
appId: string appKey: string
groupId: string groupId: string
requesterId: string requesterId: string
remark?: string | null remark?: string | null
@ -213,192 +213,192 @@ export interface GroupJoinRequest {
} }
export const imAdminApi = { export const imAdminApi = {
listUsers(appId: string, page = 0, size = 20) { listUsers(appKey: string, page = 0, size = 20) {
return imClient.get<{ data: PagedResult<ImUser> }>( return imClient.get<{ data: PagedResult<ImUser> }>(
'/api/im/admin/users', { params: { appId, page, size } }, '/api/im/admin/users', { params: { appKey, page, size } },
) )
}, },
updateUserStatus(appId: string, userId: string, status: 'ACTIVE' | 'BANNED') { updateUserStatus(appKey: string, userId: string, status: 'ACTIVE' | 'BANNED') {
return imClient.put(`/api/im/admin/users/${encodeURIComponent(userId)}/status`, { status }, { params: { appId } }) return imClient.put(`/api/im/admin/users/${encodeURIComponent(userId)}/status`, { status }, { params: { appKey } })
}, },
listGroups(appId: string) { listGroups(appKey: string) {
return imClient.get<{ data: ImGroup[] }>('/api/im/admin/groups', { params: { appId } }) return imClient.get<{ data: ImGroup[] }>('/api/im/admin/groups', { params: { appKey } })
}, },
getStats(appId: string) { getStats(appKey: string) {
return imClient.get<{ data: ImStats }>('/api/im/admin/stats', { params: { appId } }) return imClient.get<{ data: ImStats }>('/api/im/admin/stats', { params: { appKey } })
}, },
getOperationLogs(appId: string, page = 0, size = 20) { getOperationLogs(appKey: string, page = 0, size = 20) {
return imClient.get<{ data: PagedResult<OperationLog> }>('/api/im/admin/operation-logs', { return imClient.get<{ data: PagedResult<OperationLog> }>('/api/im/admin/operation-logs', {
params: { appId, page, size }, params: { appKey, page, size },
}) })
}, },
listWebhooks(appId: string) { listWebhooks(appKey: string) {
return imClient.get<{ data: WebhookConfig[] }>('/api/im/admin/webhooks', { return imClient.get<{ data: WebhookConfig[] }>('/api/im/admin/webhooks', {
params: { appId }, params: { appKey },
}) })
}, },
createWebhook(appId: string, form: WebhookConfigForm) { createWebhook(appKey: string, form: WebhookConfigForm) {
return imClient.post<{ data: WebhookConfig }>('/api/im/admin/webhooks', form, { return imClient.post<{ data: WebhookConfig }>('/api/im/admin/webhooks', form, {
params: { appId }, params: { appKey },
}) })
}, },
updateUser( updateUser(
appId: string, appKey: string,
userId: string, userId: string,
form: { nickname?: string; avatar?: string; gender?: string; status?: string }, form: { nickname?: string; avatar?: string; gender?: string; status?: string },
) { ) {
return imClient.put<{ data: ImUser }>( return imClient.put<{ data: ImUser }>(
`/api/im/admin/users/${encodeURIComponent(userId)}`, `/api/im/admin/users/${encodeURIComponent(userId)}`,
form, form,
{ params: { appId } }, { params: { appKey } },
) )
}, },
updateWebhook(appId: string, webhookId: string, form: WebhookConfigForm) { updateWebhook(appKey: string, webhookId: string, form: WebhookConfigForm) {
return imClient.put<{ data: WebhookConfig }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}`, form, { return imClient.put<{ data: WebhookConfig }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}`, form, {
params: { appId }, params: { appKey },
}) })
}, },
deleteWebhook(appId: string, webhookId: string) { deleteWebhook(appKey: string, webhookId: string) {
return imClient.delete<{ data: null }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}`, { return imClient.delete<{ data: null }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}`, {
params: { appId }, params: { appKey },
}) })
}, },
listKeywordFilters(appId: string) { listKeywordFilters(appKey: string) {
return imClient.get<{ data: KeywordFilter[] }>('/api/im/admin/keyword-filters', { return imClient.get<{ data: KeywordFilter[] }>('/api/im/admin/keyword-filters', {
params: { appId }, params: { appKey },
}) })
}, },
createKeywordFilter( createKeywordFilter(
appId: string, appKey: string,
form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean }, form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean },
) { ) {
return imClient.post<{ data: KeywordFilter }>('/api/im/admin/keyword-filters', form, { return imClient.post<{ data: KeywordFilter }>('/api/im/admin/keyword-filters', form, {
params: { appId }, params: { appKey },
}) })
}, },
updateKeywordFilter( updateKeywordFilter(
appId: string, appKey: string,
filterId: string, filterId: string,
form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean }, form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean },
) { ) {
return imClient.put<{ data: KeywordFilter }>(`/api/im/admin/keyword-filters/${encodeURIComponent(filterId)}`, form, { return imClient.put<{ data: KeywordFilter }>(`/api/im/admin/keyword-filters/${encodeURIComponent(filterId)}`, form, {
params: { appId }, params: { appKey },
}) })
}, },
deleteKeywordFilter(appId: string, filterId: string) { deleteKeywordFilter(appKey: string, filterId: string) {
return imClient.delete<{ data: null }>(`/api/im/admin/keyword-filters/${encodeURIComponent(filterId)}`, { return imClient.delete<{ data: null }>(`/api/im/admin/keyword-filters/${encodeURIComponent(filterId)}`, {
params: { appId }, params: { appKey },
}) })
}, },
getGlobalMute(appId: string) { getGlobalMute(appKey: string) {
return imClient.get<{ data: GlobalMute }>('/api/im/admin/global-mute', { return imClient.get<{ data: GlobalMute }>('/api/im/admin/global-mute', {
params: { appId }, params: { appKey },
}) })
}, },
setGlobalMute(appId: string, enabled: boolean) { setGlobalMute(appKey: string, enabled: boolean) {
return imClient.put<{ data: GlobalMute }>('/api/im/admin/global-mute', null, { return imClient.put<{ data: GlobalMute }>('/api/im/admin/global-mute', null, {
params: { appId, enabled }, params: { appKey, enabled },
}) })
}, },
listGroupMembers(appId: string, groupId: string) { listGroupMembers(appKey: string, groupId: string) {
return imClient.get<{ data: ImUser[] }>( return imClient.get<{ data: ImUser[] }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/members`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/members`,
{ params: { appId } }, { params: { appKey } },
) )
}, },
searchGroupMembers(appId: string, groupId: string, keyword: string, size = 20) { searchGroupMembers(appKey: string, groupId: string, keyword: string, size = 20) {
return imClient.get<{ data: ImUser[] }>( return imClient.get<{ data: ImUser[] }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/members/search`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/members/search`,
{ params: { appId, keyword, size } }, { params: { appKey, keyword, size } },
) )
}, },
addGroupMember(appId: string, groupId: string, userId: string) { addGroupMember(appKey: string, groupId: string, userId: string) {
return imClient.post<{ data: ImGroup }>( return imClient.post<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/members`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/members`,
{ userId }, { userId },
{ params: { appId } }, { params: { appKey } },
) )
}, },
removeGroupMember(appId: string, groupId: string, userId: string) { removeGroupMember(appKey: string, groupId: string, userId: string) {
return imClient.delete<{ data: ImGroup }>( return imClient.delete<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/members/${encodeURIComponent(userId)}`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/members/${encodeURIComponent(userId)}`,
{ params: { appId } }, { params: { appKey } },
) )
}, },
setGroupRole(appId: string, groupId: string, userId: string, role: 'ADMIN' | 'MEMBER') { setGroupRole(appKey: string, groupId: string, userId: string, role: 'ADMIN' | 'MEMBER') {
return imClient.post<{ data: ImGroup }>( return imClient.post<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/roles`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/roles`,
{ userId, role }, { userId, role },
{ params: { appId } }, { params: { appKey } },
) )
}, },
muteGroupMember(appId: string, groupId: string, userId: string, minutes: number) { muteGroupMember(appKey: string, groupId: string, userId: string, minutes: number) {
return imClient.post<{ data: ImGroup }>( return imClient.post<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/mute`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/mute`,
{ userId, minutes }, { userId, minutes },
{ params: { appId } }, { params: { appKey } },
) )
}, },
listGroupJoinRequests(appId: string, groupId: string) { listGroupJoinRequests(appKey: string, groupId: string) {
return imClient.get<{ data: GroupJoinRequest[] }>( return imClient.get<{ data: GroupJoinRequest[] }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests`,
{ params: { appId } }, { params: { appKey } },
) )
}, },
sendGroupJoinRequest(appId: string, groupId: string, remark?: string) { sendGroupJoinRequest(appKey: string, groupId: string, remark?: string) {
return imClient.post<{ data: GroupJoinRequest }>( return imClient.post<{ data: GroupJoinRequest }>(
`/api/im/groups/${encodeURIComponent(groupId)}/join-requests`, `/api/im/groups/${encodeURIComponent(groupId)}/join-requests`,
null, null,
{ {
params: { params: {
appId, appKey,
...(remark ? { remark } : {}), ...(remark ? { remark } : {}),
}, },
}, },
) )
}, },
acceptGroupJoinRequest(appId: string, groupId: string, requestId: string) { acceptGroupJoinRequest(appKey: string, groupId: string, requestId: string) {
return imClient.post<{ data: GroupJoinRequest }>( return imClient.post<{ data: GroupJoinRequest }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/accept`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/accept`,
null, null,
{ params: { appId } }, { params: { appKey } },
) )
}, },
rejectGroupJoinRequest(appId: string, groupId: string, requestId: string) { rejectGroupJoinRequest(appKey: string, groupId: string, requestId: string) {
return imClient.post<{ data: GroupJoinRequest }>( return imClient.post<{ data: GroupJoinRequest }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/reject`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/reject`,
null, null,
{ params: { appId } }, { params: { appKey } },
) )
}, },
getMessages( getMessages(
appId: string, appKey: string,
userA: string, userA: string,
userB: string, userB: string,
page = 0, page = 0,
@ -412,7 +412,7 @@ export const imAdminApi = {
) { ) {
return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages', { return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages', {
params: { params: {
appId, appKey,
userA, userA,
userB, userB,
page, page,
@ -425,20 +425,20 @@ export const imAdminApi = {
}) })
}, },
revokeMessage(appId: string, messageId: string) { revokeMessage(appKey: string, messageId: string) {
return imClient.post<{ data: ImMessage }>( return imClient.post<{ data: ImMessage }>(
`/api/im/admin/messages/${encodeURIComponent(messageId)}/revoke`, `/api/im/admin/messages/${encodeURIComponent(messageId)}/revoke`,
{}, {},
{ params: { appId } }, { params: { appKey } },
) )
}, },
dismissGroup(appId: string, groupId: string) { dismissGroup(appKey: string, groupId: string) {
return imClient.delete<{ data: null }>(`/api/im/admin/groups/${encodeURIComponent(groupId)}`, { params: { appId } }) return imClient.delete<{ data: null }>(`/api/im/admin/groups/${encodeURIComponent(groupId)}`, { params: { appKey } })
}, },
registerUser( registerUser(
appId: string, appKey: string,
userId: string, userId: string,
nickname?: string, nickname?: string,
avatar?: string, avatar?: string,
@ -454,12 +454,12 @@ export const imAdminApi = {
...(gender ? { gender } : {}), ...(gender ? { gender } : {}),
...(status ? { status } : {}), ...(status ? { status } : {}),
}, },
{ params: { appId } }, { params: { appKey } },
) )
}, },
createGroup( createGroup(
appId: string, appKey: string,
name: string, name: string,
creatorId: string, creatorId: string,
memberIds: string[], memberIds: string[],
@ -475,31 +475,31 @@ export const imAdminApi = {
...(groupType ? { groupType } : {}), ...(groupType ? { groupType } : {}),
...(announcement ? { announcement } : {}), ...(announcement ? { announcement } : {}),
}, },
{ params: { appId } }, { params: { appKey } },
) )
}, },
updateGroup( updateGroup(
appId: string, appKey: string,
groupId: string, groupId: string,
form: { name?: string; groupType?: string; announcement?: string }, form: { name?: string; groupType?: string; announcement?: string },
) { ) {
return imClient.put<{ data: ImGroup }>( return imClient.put<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}`, `/api/im/admin/groups/${encodeURIComponent(groupId)}`,
form, form,
{ params: { appId } }, { params: { appKey } },
) )
}, },
searchUsers(appId: string, keyword: string, size = 20) { searchUsers(appKey: string, keyword: string, size = 20) {
return imClient.get<{ data: ImUser[] }>( return imClient.get<{ data: ImUser[] }>(
'/api/im/admin/users/search', '/api/im/admin/users/search',
{ params: { appId, keyword, size } }, { params: { appKey, keyword, size } },
) )
}, },
searchMessages( searchMessages(
appId: string, appKey: string,
filters: { filters: {
keyword?: string keyword?: string
chatType?: string chatType?: string
@ -512,7 +512,7 @@ export const imAdminApi = {
) { ) {
return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages/search', { return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages/search', {
params: { params: {
appId, appKey,
...(filters.keyword ? { keyword: filters.keyword } : {}), ...(filters.keyword ? { keyword: filters.keyword } : {}),
...(filters.chatType ? { chatType: filters.chatType } : {}), ...(filters.chatType ? { chatType: filters.chatType } : {}),
...(filters.msgType ? { msgType: filters.msgType } : {}), ...(filters.msgType ? { msgType: filters.msgType } : {}),
@ -524,20 +524,20 @@ export const imAdminApi = {
}) })
}, },
getProfile(appId: string, userId: string) { getProfile(appKey: string, userId: string) {
return imClient.get<{ data: ImProfile }>( return imClient.get<{ data: ImProfile }>(
`/api/im/accounts/${encodeURIComponent(userId)}`, `/api/im/accounts/${encodeURIComponent(userId)}`,
{ params: { appId } }, { params: { appKey } },
) )
}, },
updateProfile(appId: string, userId: string, nickname?: string, avatar?: string, gender?: string) { updateProfile(appKey: string, userId: string, nickname?: string, avatar?: string, gender?: string) {
return imClient.put<{ data: ImProfile }>( return imClient.put<{ data: ImProfile }>(
`/api/im/accounts/${encodeURIComponent(userId)}`, `/api/im/accounts/${encodeURIComponent(userId)}`,
{}, {},
{ {
params: { params: {
appId, appKey,
...(nickname ? { nickname } : {}), ...(nickname ? { nickname } : {}),
...(avatar ? { avatar } : {}), ...(avatar ? { avatar } : {}),
...(gender ? { gender } : {}), ...(gender ? { gender } : {}),
@ -546,39 +546,39 @@ export const imAdminApi = {
) )
}, },
transferGroupOwner(appId: string, groupId: string, newOwnerId: string) { transferGroupOwner(appKey: string, groupId: string, newOwnerId: string) {
return imClient.post<{ data: ImGroup }>( return imClient.post<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/owner`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/owner`,
{ newOwnerId }, { newOwnerId },
{ params: { appId } }, { params: { appKey } },
) )
}, },
updateGroupAttributes(appId: string, groupId: string, attributes: Record<string, unknown>) { updateGroupAttributes(appKey: string, groupId: string, attributes: Record<string, unknown>) {
return imClient.put<{ data: ImGroup }>( return imClient.put<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes`,
{ attributes }, { attributes },
{ params: { appId } }, { params: { appKey } },
) )
}, },
removeGroupAttributes(appId: string, groupId: string, keys: string[]) { removeGroupAttributes(appKey: string, groupId: string, keys: string[]) {
return imClient.post<{ data: ImGroup }>( return imClient.post<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes/delete`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes/delete`,
{ keys }, { keys },
{ params: { appId } }, { params: { appKey } },
) )
}, },
getGroupReadReceipts(appId: string, groupId: string, messageIds?: string[]) { getGroupReadReceipts(appKey: string, groupId: string, messageIds?: string[]) {
return imClient.post<{ data: Array<{ messageId: string; readCount: number; readUserIds: string[] }> }>( return imClient.post<{ data: Array<{ messageId: string; readCount: number; readUserIds: string[] }> }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/read-receipts`, `/api/im/admin/groups/${encodeURIComponent(groupId)}/read-receipts`,
{ messageIds }, { messageIds },
{ params: { appId } }, { params: { appKey } },
) )
}, },
queryUserState(appId: string, userIds: string[]) { queryUserState(appKey: string, userIds: string[]) {
return imClient.get<{ data: Record<string, { online: boolean; lastSeenAt: number }> }>( return imClient.get<{ data: Record<string, { online: boolean; lastSeenAt: number }> }>(
'/api/im/admin/users/state', '/api/im/admin/users/state',
{ params: { userIds: userIds.join(',') } }, { params: { userIds: userIds.join(',') } },
@ -586,32 +586,32 @@ export const imAdminApi = {
}, },
listWebhookDeliveries( listWebhookDeliveries(
appId: string, appKey: string,
params: { callbackEvent?: string; success?: boolean; page?: number; size?: number } = {}, params: { callbackEvent?: string; success?: boolean; page?: number; size?: number } = {},
) { ) {
return imClient.get<{ data: PagedResult<WebhookDelivery> }>('/api/im/admin/webhook-deliveries', { return imClient.get<{ data: PagedResult<WebhookDelivery> }>('/api/im/admin/webhook-deliveries', {
params: { appId, ...params }, params: { appKey, ...params },
}) })
}, },
listWebhookAlerts( listWebhookAlerts(
appId: string, appKey: string,
params: { acknowledged?: boolean; page?: number; size?: number } = {}, params: { acknowledged?: boolean; page?: number; size?: number } = {},
) { ) {
return imClient.get<{ data: PagedResult<WebhookAlert> }>('/api/im/admin/webhook-alerts', { return imClient.get<{ data: PagedResult<WebhookAlert> }>('/api/im/admin/webhook-alerts', {
params: { appId, ...params }, params: { appKey, ...params },
}) })
}, },
acknowledgeWebhookAlert(appId: string, alertId: string) { acknowledgeWebhookAlert(appKey: string, alertId: string) {
return imClient.post<{ data: WebhookAlert }>( return imClient.post<{ data: WebhookAlert }>(
`/api/im/admin/webhook-alerts/${encodeURIComponent(alertId)}/acknowledge`, `/api/im/admin/webhook-alerts/${encodeURIComponent(alertId)}/acknowledge`,
null, null,
{ params: { appId } }, { params: { appKey } },
) )
}, },
getWebhookHealth(appId: string, webhookId: string) { getWebhookHealth(appKey: string, webhookId: string) {
return imClient.get<{ return imClient.get<{
data: { data: {
webhookId: string webhookId: string
@ -621,6 +621,6 @@ export const imAdminApi = {
lastFailureAt: number | null lastFailureAt: number | null
unacknowledgedAlerts: number unacknowledgedAlerts: number
} }
}>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}/health`, { params: { appId } }) }>(`/api/im/admin/webhooks/${encodeURIComponent(webhookId)}/health`, { params: { appKey } })
}, },
} }

查看文件

@ -17,7 +17,7 @@ export interface DeviceInfo {
export interface UserPushStatus { export interface UserPushStatus {
tokenType: string tokenType: string
appId: string appKey: string
userId: string userId: string
online: boolean online: boolean
lastSeenAt: number lastSeenAt: number
@ -29,7 +29,7 @@ export interface UserPushStatus {
export interface DeviceLoginLog { export interface DeviceLoginLog {
id: string id: string
appId: string appKey: string
userId: string userId: string
vendor: string vendor: string
deviceId: string | null deviceId: string | null
@ -48,7 +48,7 @@ export interface PagedLogs {
} }
export interface TestPushResult { export interface TestPushResult {
appId: string appKey: string
userId: string userId: string
sent: boolean sent: boolean
targetCount: number targetCount: number
@ -56,21 +56,21 @@ export interface TestPushResult {
} }
export const pushAdminApi = { export const pushAdminApi = {
getUserStatus(appId: string, userId: string) { getUserStatus(appKey: string, userId: string) {
return client.get<{ data: UserPushStatus }>('/push/admin/user-status', { return client.get<{ data: UserPushStatus }>('/push/admin/user-status', {
params: { appId, userId }, params: { appKey, userId },
}) })
}, },
getDeviceLogs(appId: string, userId: string, page = 0, size = 20) { getDeviceLogs(appKey: string, userId: string, page = 0, size = 20) {
return client.get<{ data: PagedLogs }>('/push/admin/device-logs', { return client.get<{ data: PagedLogs }>('/push/admin/device-logs', {
params: { appId, userId, page, size }, params: { appKey, userId, page, size },
}) })
}, },
testOffline(appId: string, userId: string, title: string, body: string, payload?: string) { testOffline(appKey: string, userId: string, title: string, body: string, payload?: string) {
return client.post<{ data: TestPushResult }>('/push/admin/test-offline', { return client.post<{ data: TestPushResult }>('/push/admin/test-offline', {
appId, appKey,
userId, userId,
title, title,
body, body,

查看文件

@ -87,14 +87,14 @@ export type GraySelectionSource = 'LOCAL' | 'CALLBACK'
export interface PublishConfig { export interface PublishConfig {
id: string id: string
appId: string appKey: string
configJson?: string configJson?: string
updatedAt: string updatedAt: string
} }
export interface OperationLog { export interface OperationLog {
id: string id: string
appId: string appKey: string
resourceType: string resourceType: string
resourceId: string resourceId: string
action: string action: string
@ -119,7 +119,7 @@ export interface GrayMemberGroup {
export interface StoreConfig { export interface StoreConfig {
id: string id: string
appId: string appKey: string
storeType: StoreType storeType: StoreType
configJson?: string configJson?: string
enabled: boolean enabled: boolean
@ -128,7 +128,7 @@ export interface StoreConfig {
export interface AppVersion { export interface AppVersion {
id: string id: string
appId: string appKey: string
platform: 'ANDROID' | 'IOS' | 'HARMONY' platform: 'ANDROID' | 'IOS' | 'HARMONY'
versionName: string versionName: string
versionCode: number versionCode: number
@ -164,7 +164,7 @@ export interface AppPackageInspectResult {
export interface RnBundle { export interface RnBundle {
id: string id: string
appId: string appKey: string
moduleId: string moduleId: string
platform: 'ANDROID' | 'IOS' | 'HARMONY' platform: 'ANDROID' | 'IOS' | 'HARMONY'
version: string version: string
@ -221,9 +221,9 @@ export interface UnifiedReleaseManifest {
} }
export const updateAdminApi = { export const updateAdminApi = {
listAppVersions(appId: string, platform: 'ANDROID' | 'IOS' | 'HARMONY') { listAppVersions(appKey: string, platform: 'ANDROID' | 'IOS' | 'HARMONY') {
return updateClient.get<{ data: AppVersion[] }>('/api/v1/updates/app/list', { return updateClient.get<{ data: AppVersion[] }>('/api/v1/updates/app/list', {
params: { appId, platform }, params: { appKey, platform },
}) })
}, },
@ -255,9 +255,9 @@ export const updateAdminApi = {
}) })
}, },
listRnBundles(appId: string, moduleId?: string, platform?: string) { listRnBundles(appKey: string, moduleId?: string, platform?: string) {
return updateClient.get<{ data: RnBundle[] }>('/api/v1/rn/list', { return updateClient.get<{ data: RnBundle[] }>('/api/v1/rn/list', {
params: { appId, ...(moduleId && { moduleId }), ...(platform && { platform }) }, params: { appKey, ...(moduleId && { moduleId }), ...(platform && { platform }) },
}) })
}, },
@ -293,20 +293,20 @@ export const updateAdminApi = {
// ── Store config ──────────────────────────────────────────────────────── // ── Store config ────────────────────────────────────────────────────────
getStoreConfigs(appId: string) { getStoreConfigs(appKey: string) {
return updateClient.get<{ data: StoreConfig[] }>('/api/v1/updates/store/configs', { params: { appId } }) return updateClient.get<{ data: StoreConfig[] }>('/api/v1/updates/store/configs', { params: { appKey } })
}, },
saveStoreConfig(appId: string, storeType: StoreType, configJson: string, enabled: boolean) { saveStoreConfig(appKey: string, storeType: StoreType, configJson: string, enabled: boolean) {
return updateClient.put<{ data: StoreConfig }>( return updateClient.put<{ data: StoreConfig }>(
`/api/v1/updates/store/configs/${storeType}`, `/api/v1/updates/store/configs/${storeType}`,
{ configJson, enabled }, { configJson, enabled },
{ params: { appId } }, { params: { appKey } },
) )
}, },
deleteStoreConfig(appId: string, storeType: StoreType) { deleteStoreConfig(appKey: string, storeType: StoreType) {
return updateClient.delete(`/api/v1/updates/store/configs/${storeType}`, { params: { appId } }) return updateClient.delete(`/api/v1/updates/store/configs/${storeType}`, { params: { appKey } })
}, },
executeSubmitToStores( executeSubmitToStores(
@ -329,29 +329,29 @@ export const updateAdminApi = {
) )
}, },
getPublishConfig(appId: string) { getPublishConfig(appKey: string) {
return updateClient.get<{ data: PublishConfig }>('/api/v1/updates/publish/config', { params: { appId } }) return updateClient.get<{ data: PublishConfig }>('/api/v1/updates/publish/config', { params: { appKey } })
}, },
savePublishConfig(appId: string, config: Record<string, unknown>) { savePublishConfig(appKey: string, config: Record<string, unknown>) {
return updateClient.put<{ data: PublishConfig }>('/api/v1/updates/publish/config', config, { params: { appId } }) return updateClient.put<{ data: PublishConfig }>('/api/v1/updates/publish/config', config, { params: { appKey } })
}, },
listOperationLogs(appId: string, limit = 100) { listOperationLogs(appKey: string, limit = 100) {
return updateClient.get<{ data: OperationLog[] }>('/api/v1/updates/ops/logs', { return updateClient.get<{ data: OperationLog[] }>('/api/v1/updates/ops/logs', {
params: { appId, limit }, params: { appKey, limit },
}) })
}, },
listGrayMembers(appId: string, keyword?: string, groupName?: string) { listGrayMembers(appKey: string, keyword?: string, groupName?: string) {
return updateClient.get<{ data: GrayMemberGroup[] }>('/api/v1/updates/gray/members', { return updateClient.get<{ data: GrayMemberGroup[] }>('/api/v1/updates/gray/members', {
params: { appId, ...(keyword && { keyword }), ...(groupName && { groupName }) }, params: { appKey, ...(keyword && { keyword }), ...(groupName && { groupName }) },
}) })
}, },
syncGrayMembers(appId: string) { syncGrayMembers(appKey: string) {
return updateClient.post<{ data: GrayMemberGroup[] }>('/api/v1/updates/gray/members/sync', null, { return updateClient.post<{ data: GrayMemberGroup[] }>('/api/v1/updates/gray/members/sync', null, {
params: { appId }, params: { appKey },
}) })
}, },
} }

查看文件

@ -50,47 +50,47 @@ const router = createRouter({
component: () => import('@/views/apps/AppDetailView.vue'), component: () => import('@/views/apps/AppDetailView.vue'),
}, },
{ {
path: 'apps/:appId/im-config', path: 'apps/:appKey/im-config',
component: () => import('@/views/im/ImConfigView.vue'), component: () => import('@/views/im/ImConfigView.vue'),
}, },
{ {
path: 'apps/:appId/push-config', path: 'apps/:appKey/push-config',
component: () => import('@/views/push/PushConfigView.vue'), component: () => import('@/views/push/PushConfigView.vue'),
}, },
{ {
path: 'apps/:appId/push-management', path: 'apps/:appKey/push-management',
component: () => import('@/views/push/PushManagementView.vue'), component: () => import('@/views/push/PushManagementView.vue'),
}, },
{ {
path: 'apps/:appId/im-webhooks', path: 'apps/:appKey/im-webhooks',
component: () => import('@/views/im/ImWebhookView.vue'), component: () => import('@/views/im/ImWebhookView.vue'),
}, },
{ {
path: 'apps/:appId/im-webhooks/:webhookId/deliveries', path: 'apps/:appKey/im-webhooks/:webhookId/deliveries',
component: () => import('@/views/im/WebhookDeliveryLogView.vue'), component: () => import('@/views/im/WebhookDeliveryLogView.vue'),
}, },
{ {
path: 'apps/:appId/im-webhook-alerts', path: 'apps/:appKey/im-webhook-alerts',
component: () => import('@/views/im/WebhookAlertView.vue'), component: () => import('@/views/im/WebhookAlertView.vue'),
}, },
{ {
path: 'apps/:appId/im', path: 'apps/:appKey/im',
component: () => import('@/views/im/ImManagementView.vue'), component: () => import('@/views/im/ImManagementView.vue'),
}, },
{ {
path: 'apps/:appId/update', path: 'apps/:appKey/update',
component: () => import('@/views/update/VersionManagementView.vue'), component: () => import('@/views/update/VersionManagementView.vue'),
}, },
{ {
path: 'services/im/:appId?', path: 'services/im/:appKey?',
component: () => import('@/views/im/ImManagementView.vue'), component: () => import('@/views/im/ImManagementView.vue'),
}, },
{ {
path: 'services/push/:appId?', path: 'services/push/:appKey?',
component: () => import('@/views/push/PushManagementView.vue'), component: () => import('@/views/push/PushManagementView.vue'),
}, },
{ {
path: 'services/update/:appId?', path: 'services/update/:appKey?',
component: () => import('@/views/update/VersionManagementView.vue'), component: () => import('@/views/update/VersionManagementView.vue'),
}, },
{ {

查看文件

@ -24,10 +24,10 @@
</div> </div>
<div style="margin-top:10px;display:flex;gap:8px;flex-wrap:wrap"> <div style="margin-top:10px;display:flex;gap:8px;flex-wrap:wrap">
<!-- 服务配置页使用的是租户应用主键 app.idIM 管理页才带 appKey --> <!-- 服务配置页使用的是租户应用主键 app.idIM 管理页才带 appKey -->
<el-button size="small" @click="$router.push({ path: `/apps/${route.params.appId}/im`, query: { appKey: app.appKey } })"> <el-button size="small" @click="$router.push({ path: `/apps/${route.params.appKey}/im`, query: { appKey: app.appKey } })">
即时通讯管理 即时通讯管理
</el-button> </el-button>
<el-button size="small" @click="$router.push(`/apps/${route.params.appId}`)"> <el-button size="small" @click="$router.push(`/apps/${route.params.appKey}`)">
返回详情 返回详情
</el-button> </el-button>
</div> </div>
@ -243,7 +243,7 @@ function normalizeFriendRequestMode(
} }
async function loadData() { async function loadData() {
const id = route.params.appId as string const id = route.params.appKey as string
const [appRes, svcRes] = await Promise.all([ const [appRes, svcRes] = await Promise.all([
appApi.get(id), appApi.get(id),
appApi.getServices(id), appApi.getServices(id),
@ -265,7 +265,7 @@ async function onToggleImService(enable: boolean) {
confirmButtonText: '确认关闭', confirmButtonText: '确认关闭',
cancelButtonText: '取消', cancelButtonText: '取消',
}) })
await appApi.toggleService(route.params.appId as string, imServicePlatform(), 'IM', false) await appApi.toggleService(route.params.appKey as string, imServicePlatform(), 'IM', false)
ElMessage.success('已关闭') ElMessage.success('已关闭')
loadData() loadData()
} }
@ -275,7 +275,7 @@ async function onToggleImConfig(patch: Partial<ImServiceConfig>) {
...imConfig.value, ...imConfig.value,
...patch, ...patch,
} }
await appApi.updateServiceConfig(route.params.appId as string, imServicePlatform(), 'IM', nextConfig) await appApi.updateServiceConfig(route.params.appKey as string, imServicePlatform(), 'IM', nextConfig)
ElMessage.success('IM 配置已更新') ElMessage.success('IM 配置已更新')
loadData() loadData()
} }

查看文件

@ -699,8 +699,8 @@
<el-descriptions :column="1" border> <el-descriptions :column="1" border>
<el-descriptions-item label="调用方式">POST 到你配置的回调地址`Content-Type: application/json`</el-descriptions-item> <el-descriptions-item label="调用方式">POST 到你配置的回调地址`Content-Type: application/json`</el-descriptions-item>
<el-descriptions-item label="请求头">`X-App-Id``X-App-Timestamp``X-App-Nonce``X-App-Signature`</el-descriptions-item> <el-descriptions-item label="请求头">`X-App-Id``X-App-Timestamp``X-App-Nonce``X-App-Signature`</el-descriptions-item>
<el-descriptions-item label="请求体">统一 envelope`callbackId``callbackType``callbackEvent``requestTime``payload``appId`</el-descriptions-item> <el-descriptions-item label="请求体">统一 envelope`callbackId``callbackType``callbackEvent``requestTime``payload``appKey`</el-descriptions-item>
<el-descriptions-item label="签名">`HMAC-SHA256(appSecret, appId + '\\n' + timestamp + '\\n' + nonce + '\\n' + sha256(body))`</el-descriptions-item> <el-descriptions-item label="签名">`HMAC-SHA256(appSecret, appKey + '\\n' + timestamp + '\\n' + nonce + '\\n' + sha256(body))`</el-descriptions-item>
<el-descriptions-item label="失败处理">回调发送失败只记录日志不会中断消息发送撤回等主流程</el-descriptions-item> <el-descriptions-item label="失败处理">回调发送失败只记录日志不会中断消息发送撤回等主流程</el-descriptions-item>
<el-descriptions-item label="幂等建议">接收方建议按 `callbackId` 去重</el-descriptions-item> <el-descriptions-item label="幂等建议">接收方建议按 `callbackId` 去重</el-descriptions-item>
</el-descriptions> </el-descriptions>
@ -779,7 +779,7 @@ const appKey = computed(() => {
if (typeof queryAppKey === 'string' && queryAppKey.trim()) { if (typeof queryAppKey === 'string' && queryAppKey.trim()) {
return queryAppKey.trim() return queryAppKey.trim()
} }
return String(route.params['appId'] ?? '') return String(route.params['appKey'] ?? '')
}) })
const genderLabel: Record<string, string> = { const genderLabel: Record<string, string> = {

查看文件

@ -30,7 +30,7 @@
<el-descriptions :column="1" border> <el-descriptions :column="1" border>
<el-descriptions-item label="调用方式">服务端以 `POST` 方式推送到你配置的回调地址</el-descriptions-item> <el-descriptions-item label="调用方式">服务端以 `POST` 方式推送到你配置的回调地址</el-descriptions-item>
<el-descriptions-item label="签名头">`X-App-Id``X-App-Timestamp``X-App-Nonce``X-App-Signature`</el-descriptions-item> <el-descriptions-item label="签名头">`X-App-Id``X-App-Timestamp``X-App-Nonce``X-App-Signature`</el-descriptions-item>
<el-descriptions-item label="验签公式">`HMAC-SHA256(appSecret, appId + '\\n' + timestamp + '\\n' + nonce + '\\n' + sha256(body))`</el-descriptions-item> <el-descriptions-item label="验签公式">`HMAC-SHA256(appSecret, appKey + '\\n' + timestamp + '\\n' + nonce + '\\n' + sha256(body))`</el-descriptions-item>
<el-descriptions-item label="幂等建议">接收方建议按 `callbackId` 去重</el-descriptions-item> <el-descriptions-item label="幂等建议">接收方建议按 `callbackId` 去重</el-descriptions-item>
</el-descriptions> </el-descriptions>
<el-table :data="webhookEvents" border stripe style="margin-top:16px"> <el-table :data="webhookEvents" border stripe style="margin-top:16px">
@ -44,7 +44,7 @@
<template #header> <template #header>
<div class="toolbar toolbar-space-between"> <div class="toolbar toolbar-space-between">
<span>回调地址</span> <span>回调地址</span>
<el-button link type="primary" @click="$router.push({ path: `/apps/${appId}/im-webhook-alerts` })"> <el-button link type="primary" @click="$router.push({ path: `/apps/${appKey}/im-webhook-alerts` })">
查看告警 查看告警
</el-button> </el-button>
</div> </div>
@ -86,7 +86,7 @@
<el-table-column label="操作" width="220" fixed="right"> <el-table-column label="操作" width="220" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-button link type="primary" size="small" @click="openEditWebhookDialog(row)">编辑</el-button> <el-button link type="primary" size="small" @click="openEditWebhookDialog(row)">编辑</el-button>
<el-button link type="info" size="small" @click="$router.push({ path: `/apps/${appId}/im-webhooks/${row.id}/deliveries` })">日志</el-button> <el-button link type="info" size="small" @click="$router.push({ path: `/apps/${appKey}/im-webhooks/${row.id}/deliveries` })">日志</el-button>
<el-button link type="danger" size="small" @click="deleteWebhook(row)">删除</el-button> <el-button link type="danger" size="small" @click="deleteWebhook(row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -139,7 +139,7 @@ const webhookForm = ref<WebhookConfigForm & { enabled: boolean }>({
enabled: true, enabled: true,
}) })
const appId = computed(() => route.params.appId as string) const appKey = computed(() => route.params.appKey as string)
const webhookEvents = [ const webhookEvents = [
{ event: 'message.sent', payload: 'ImMessageEntity', description: '消息发送成功后触发。' }, { event: 'message.sent', payload: 'ImMessageEntity', description: '消息发送成功后触发。' },
@ -157,14 +157,14 @@ const webhookEvents = [
] ]
async function loadApp() { async function loadApp() {
const res = await appApi.get(appId.value) const res = await appApi.get(appKey.value)
app.value = res.data.data app.value = res.data.data
} }
async function loadWebhooks() { async function loadWebhooks() {
loadingWebhooks.value = true loadingWebhooks.value = true
try { try {
const res = await imAdminApi.listWebhooks(appId.value) const res = await imAdminApi.listWebhooks(appKey.value)
webhooks.value = res.data.data webhooks.value = res.data.data
} finally { } finally {
loadingWebhooks.value = false loadingWebhooks.value = false
@ -208,9 +208,9 @@ async function submitWebhookForm() {
payload.secret = secret payload.secret = secret
} }
if (editingWebhookId.value) { if (editingWebhookId.value) {
await imAdminApi.updateWebhook(appId.value, editingWebhookId.value, payload) await imAdminApi.updateWebhook(appKey.value, editingWebhookId.value, payload)
} else { } else {
await imAdminApi.createWebhook(appId.value, payload) await imAdminApi.createWebhook(appKey.value, payload)
} }
ElMessage.success('回调配置已保存') ElMessage.success('回调配置已保存')
showWebhookDialog.value = false showWebhookDialog.value = false
@ -226,7 +226,7 @@ async function deleteWebhook(row: WebhookConfig) {
confirmButtonText: '确认删除', confirmButtonText: '确认删除',
cancelButtonText: '取消', cancelButtonText: '取消',
}) })
await imAdminApi.deleteWebhook(appId.value, row.id) await imAdminApi.deleteWebhook(appKey.value, row.id)
ElMessage.success('已删除') ElMessage.success('已删除')
await loadWebhooks() await loadWebhooks()
} }

查看文件

@ -78,7 +78,7 @@ import { imAdminApi, type WebhookAlert } from '@/api/im'
const route = useRoute() const route = useRoute()
const app = ref<App | null>(null) const app = ref<App | null>(null)
const appId = computed(() => route.params.appId as string) const appKey = computed(() => route.params.appKey as string)
const alerts = ref<WebhookAlert[]>([]) const alerts = ref<WebhookAlert[]>([])
const loading = ref(false) const loading = ref(false)
@ -89,7 +89,7 @@ const filterAcknowledged = ref<boolean | ''>('')
const unacknowledgedCount = ref(0) const unacknowledgedCount = ref(0)
async function loadApp() { async function loadApp() {
const res = await appApi.get(appId.value) const res = await appApi.get(appKey.value)
app.value = res.data.data app.value = res.data.data
} }
@ -98,7 +98,7 @@ async function loadAlerts() {
try { try {
const params: Record<string, unknown> = { page: page.value - 1, size: size.value } const params: Record<string, unknown> = { page: page.value - 1, size: size.value }
if (filterAcknowledged.value !== '') params.acknowledged = filterAcknowledged.value if (filterAcknowledged.value !== '') params.acknowledged = filterAcknowledged.value
const res = await imAdminApi.listWebhookAlerts(appId.value, params) const res = await imAdminApi.listWebhookAlerts(appKey.value, params)
alerts.value = res.data.data.content alerts.value = res.data.data.content
total.value = res.data.data.totalElements total.value = res.data.data.totalElements
} finally { } finally {
@ -107,12 +107,12 @@ async function loadAlerts() {
} }
async function loadUnacknowledgedCount() { async function loadUnacknowledgedCount() {
const res = await imAdminApi.listWebhookAlerts(appId.value, { acknowledged: false, size: 1 }) const res = await imAdminApi.listWebhookAlerts(appKey.value, { acknowledged: false, size: 1 })
unacknowledgedCount.value = Number(res.data.data.totalElements) unacknowledgedCount.value = Number(res.data.data.totalElements)
} }
async function acknowledge(row: WebhookAlert) { async function acknowledge(row: WebhookAlert) {
await imAdminApi.acknowledgeWebhookAlert(appId.value, row.id) await imAdminApi.acknowledgeWebhookAlert(appKey.value, row.id)
ElMessage.success('已确认') ElMessage.success('已确认')
await loadAlerts() await loadAlerts()
await loadUnacknowledgedCount() await loadUnacknowledgedCount()

查看文件

@ -66,7 +66,7 @@ import { imAdminApi, type WebhookDelivery } from '@/api/im'
const route = useRoute() const route = useRoute()
const app = ref<App | null>(null) const app = ref<App | null>(null)
const appId = computed(() => route.params.appId as string) const appKey = computed(() => route.params.appKey as string)
const webhookId = computed(() => route.params.webhookId as string) const webhookId = computed(() => route.params.webhookId as string)
const webhookUrl = ref('') const webhookUrl = ref('')
@ -79,12 +79,12 @@ const filterEvent = ref('')
const filterSuccess = ref<boolean | ''>('') const filterSuccess = ref<boolean | ''>('')
async function loadApp() { async function loadApp() {
const res = await appApi.get(appId.value) const res = await appApi.get(appKey.value)
app.value = res.data.data app.value = res.data.data
} }
async function loadWebhook() { async function loadWebhook() {
const res = await imAdminApi.listWebhooks(appId.value) const res = await imAdminApi.listWebhooks(appKey.value)
const wh = res.data.data.find((w) => w.id === webhookId.value) const wh = res.data.data.find((w) => w.id === webhookId.value)
if (wh) webhookUrl.value = wh.url if (wh) webhookUrl.value = wh.url
} }
@ -95,7 +95,7 @@ async function loadDeliveries() {
const params: Record<string, unknown> = { page: page.value - 1, size: size.value } const params: Record<string, unknown> = { page: page.value - 1, size: size.value }
if (filterEvent.value) params.callbackEvent = filterEvent.value if (filterEvent.value) params.callbackEvent = filterEvent.value
if (filterSuccess.value !== '') params.success = filterSuccess.value if (filterSuccess.value !== '') params.success = filterSuccess.value
const res = await imAdminApi.listWebhookDeliveries(appId.value, params) const res = await imAdminApi.listWebhookDeliveries(appKey.value, params)
deliveries.value = res.data.data.content deliveries.value = res.data.data.content
total.value = res.data.data.totalElements total.value = res.data.data.totalElements
} finally { } finally {

查看文件

@ -321,7 +321,7 @@ const pushEnabled = computed(() => services.value.some(
const servicePlatform = computed(() => selectedPlatform.value) const servicePlatform = computed(() => selectedPlatform.value)
async function loadData() { async function loadData() {
const id = route.params.appId as string const id = route.params.appKey as string
const [appRes, svcRes] = await Promise.all([ const [appRes, svcRes] = await Promise.all([
appApi.get(id), appApi.get(id),
appApi.getServices(id), appApi.getServices(id),

查看文件

@ -2,14 +2,14 @@
<div> <div>
<div v-if="isServicesPortal" class="portal-bar"> <div v-if="isServicesPortal" class="portal-bar">
<span class="portal-bar-title">离线推送管理</span> <span class="portal-bar-title">离线推送管理</span>
<el-select :model-value="appId" placeholder="选择应用" style="width:220px" @change="switchApp"> <el-select :model-value="appKey" placeholder="选择应用" style="width:220px" @change="switchApp">
<el-option v-for="a in portalApps" :key="a.appKey" :label="a.name" :value="a.appKey" /> <el-option v-for="a in portalApps" :key="a.appKey" :label="a.name" :value="a.appKey" />
</el-select> </el-select>
</div> </div>
<el-page-header v-else @back="$router.back()" content="推送管理" style="margin-bottom:24px" /> <el-page-header v-else @back="$router.back()" content="推送管理" style="margin-bottom:24px" />
<el-empty v-if="isServicesPortal && !appId" description="请选择一个应用" style="margin-top:80px" /> <el-empty v-if="isServicesPortal && !appKey" description="请选择一个应用" style="margin-top:80px" />
<template v-if="!isServicesPortal || appId"> <template v-if="!isServicesPortal || appKey">
<el-card style="margin-bottom:16px"> <el-card style="margin-bottom:16px">
<template #header>用户设备状态查询</template> <template #header>用户设备状态查询</template>
<el-form inline @submit.prevent="queryUser"> <el-form inline @submit.prevent="queryUser">
@ -156,7 +156,7 @@ import { pushAdminApi, type DeviceLoginLog, type TestPushResult, type UserPushSt
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const appId = route.params.appId as string const appKey = route.params.appKey as string
const isServicesPortal = computed(() => route.path.startsWith('/services/')) const isServicesPortal = computed(() => route.path.startsWith('/services/'))
const portalApps = ref<App[]>([]) const portalApps = ref<App[]>([])
@ -192,7 +192,7 @@ async function queryUser() {
querying.value = true querying.value = true
testResult.value = null testResult.value = null
try { try {
const res = await pushAdminApi.getUserStatus(appId, uid) const res = await pushAdminApi.getUserStatus(appKey, uid)
userStatus.value = res.data.data userStatus.value = res.data.data
logsUserId.value = uid logsUserId.value = uid
logsPage.value = 1 logsPage.value = 1
@ -210,7 +210,7 @@ async function sendTestPush() {
testResult.value = null testResult.value = null
try { try {
const res = await pushAdminApi.testOffline( const res = await pushAdminApi.testOffline(
appId, appKey,
userStatus.value.userId, userStatus.value.userId,
testForm.title, testForm.title,
testForm.body, testForm.body,
@ -229,7 +229,7 @@ async function loadLogs() {
if (!uid) return if (!uid) return
logsLoading.value = true logsLoading.value = true
try { try {
const res = await pushAdminApi.getDeviceLogs(appId, uid, logsPage.value - 1, logsPageSize) const res = await pushAdminApi.getDeviceLogs(appKey, uid, logsPage.value - 1, logsPageSize)
const d = res.data.data const d = res.data.data
logs.value = d.content logs.value = d.content
logsTotal.value = d.total logsTotal.value = d.total

查看文件

@ -1,6 +1,6 @@
<template> <template>
<div class="store-guide-page"> <div class="store-guide-page">
<el-page-header @back="$router.back()" :content="`应用配置指引 — ${appId}`" /> <el-page-header @back="$router.back()" :content="`应用配置指引 — ${appKey}`" />
<el-alert <el-alert
title="这里是应用商店配置的独立指引页。建议先完成凭据配置和市场跳转页,再回到版本管理页提交审核。Harmony 应用仅跳转应用市场,不做本地安装。" title="这里是应用商店配置的独立指引页。建议先完成凭据配置和市场跳转页,再回到版本管理页提交审核。Harmony 应用仅跳转应用市场,不做本地安装。"
@ -72,7 +72,7 @@ import vivoGuideImage from '@/assets/update-store/vivo/01.png'
import honorGuideImage from '@/assets/update-store/honor/01.png' import honorGuideImage from '@/assets/update-store/honor/01.png'
const route = useRoute() const route = useRoute()
const appId = route.params.appId as string const appKey = route.params.appKey as string
interface StoreGuide { interface StoreGuide {
type: string type: string

查看文件

@ -2,14 +2,14 @@
<div> <div>
<div v-if="isServicesPortal" class="portal-bar"> <div v-if="isServicesPortal" class="portal-bar">
<span class="portal-bar-title">版本管理</span> <span class="portal-bar-title">版本管理</span>
<el-select :model-value="appId" placeholder="选择应用" style="width:220px" @change="switchApp"> <el-select :model-value="appKey" placeholder="选择应用" style="width:220px" @change="switchApp">
<el-option v-for="a in portalApps" :key="a.id" :label="a.name" :value="a.id" /> <el-option v-for="a in portalApps" :key="a.id" :label="a.name" :value="a.id" />
</el-select> </el-select>
</div> </div>
<el-page-header v-else @back="$router.back()" :content="`版本管理 — ${pageTitle}`" style="margin-bottom:20px" /> <el-page-header v-else @back="$router.back()" :content="`版本管理 — ${pageTitle}`" style="margin-bottom:20px" />
<el-empty v-if="isServicesPortal && !appId" description="请选择一个应用" style="margin-top:80px" /> <el-empty v-if="isServicesPortal && !appKey" description="请选择一个应用" style="margin-top:80px" />
<template v-if="!isServicesPortal || appId"> <template v-if="!isServicesPortal || appKey">
<el-card> <el-card>
<el-tabs v-model="activeTab"> <el-tabs v-model="activeTab">
<!-- App Versions --> <!-- App Versions -->
@ -649,11 +649,11 @@ import honorGuideImage from '@/assets/update-store/honor/01.png'
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const appId = route.params.appId as string const appKey = route.params.appKey as string
const isServicesPortal = computed(() => route.path.startsWith('/services/')) const isServicesPortal = computed(() => route.path.startsWith('/services/'))
const portalApps = ref<App[]>([]) const portalApps = ref<App[]>([])
const app = ref<App | null>(null) const app = ref<App | null>(null)
const pageTitle = computed(() => app.value?.name ?? appId) const pageTitle = computed(() => app.value?.name ?? appKey)
const isMobile = ref(false) const isMobile = ref(false)
const dialogWidth = computed(() => (isMobile.value ? 'calc(100vw - 24px)' : '920px')) const dialogWidth = computed(() => (isMobile.value ? 'calc(100vw - 24px)' : '920px'))
@ -691,7 +691,7 @@ const rnInspectUploadProgress = ref(0)
const rnBundleUploadProgress = ref(0) const rnBundleUploadProgress = ref(0)
const operationLogs = ref<{ const operationLogs = ref<{
id: string id: string
appId: string appKey: string
resourceType: string resourceType: string
resourceId: string resourceId: string
action: string action: string
@ -762,7 +762,7 @@ const STORE_DEFS: StoreDef[] = [
{ title: '打开自动发布接口', description: '下载公钥文件并准备私钥。' }, { title: '打开自动发布接口', description: '下载公钥文件并准备私钥。' },
{ title: '录入用户名和私钥', description: '这里保存的是服务端上传所需凭据。' }, { title: '录入用户名和私钥', description: '这里保存的是服务端上传所需凭据。' },
], ],
jumpLinkHint: '小米应用商店详情页可从应用的商店公开链接或发布页面复制,通常包含 appId 或 package 信息。', jumpLinkHint: '小米应用商店详情页可从应用的商店公开链接或发布页面复制,通常包含 appKey 或 package 信息。',
guideHint: '当前字段为 username / publicKey / privateKey,与后端服务一致。', guideHint: '当前字段为 username / publicKey / privateKey,与后端服务一致。',
guideImage: miGuideImage, guideImage: miGuideImage,
}, },
@ -918,7 +918,7 @@ async function toggleStore(type: StoreType, enabled: boolean) {
const cfg = getStoreConfig(type) const cfg = getStoreConfig(type)
if (!cfg) return if (!cfg) return
try { try {
await updateAdminApi.saveStoreConfig(appId, type, cfg.configJson ?? '{}', enabled) await updateAdminApi.saveStoreConfig(appKey, type, cfg.configJson ?? '{}', enabled)
await loadStoreConfigs() await loadStoreConfigs()
} catch { } catch {
ElMessage.error('操作失败') ElMessage.error('操作失败')
@ -927,7 +927,7 @@ async function toggleStore(type: StoreType, enabled: boolean) {
async function loadStoreConfigs() { async function loadStoreConfigs() {
try { try {
const res = await updateAdminApi.getStoreConfigs(appId) const res = await updateAdminApi.getStoreConfigs(appKey)
storeConfigs.value = res.data.data storeConfigs.value = res.data.data
} catch { } catch {
storeConfigs.value = [] storeConfigs.value = []
@ -939,7 +939,7 @@ function switchApp(val: string) {
} }
async function loadApp() { async function loadApp() {
const res = await appApi.get(appId) const res = await appApi.get(appKey)
app.value = res.data.data app.value = res.data.data
} }
@ -978,7 +978,7 @@ async function saveStoreConfig() {
savingStoreConfig.value = true savingStoreConfig.value = true
try { try {
await updateAdminApi.saveStoreConfig( await updateAdminApi.saveStoreConfig(
appId, appKey,
currentStoreDef.value.type, currentStoreDef.value.type,
JSON.stringify(storeConfigForm.value.values), JSON.stringify(storeConfigForm.value.values),
storeConfigForm.value.enabled, storeConfigForm.value.enabled,
@ -996,7 +996,7 @@ async function saveStoreConfig() {
async function removeStoreConfig(type: StoreType) { async function removeStoreConfig(type: StoreType) {
await ElMessageBox.confirm('确认删除此应用商店凭据?', '提示', { type: 'warning' }) await ElMessageBox.confirm('确认删除此应用商店凭据?', '提示', { type: 'warning' })
try { try {
await updateAdminApi.deleteStoreConfig(appId, type) await updateAdminApi.deleteStoreConfig(appKey, type)
ElMessage.success('已删除') ElMessage.success('已删除')
await loadStoreConfigs() await loadStoreConfigs()
} catch { } catch {
@ -1036,7 +1036,7 @@ function parsePublishConfig(config?: string | null) {
async function loadPublishConfig() { async function loadPublishConfig() {
loadingPublishConfig.value = true loadingPublishConfig.value = true
try { try {
const res = await updateAdminApi.getPublishConfig(appId) const res = await updateAdminApi.getPublishConfig(appKey)
publishConfigForm.value = parsePublishConfig(res.data.data.configJson) publishConfigForm.value = parsePublishConfig(res.data.data.configJson)
if (publishConfigForm.value.grayMode === 'MEMBERS' && !hasAnyGrayCallback.value) { if (publishConfigForm.value.grayMode === 'MEMBERS' && !hasAnyGrayCallback.value) {
publishConfigForm.value.grayMode = 'PERCENT' publishConfigForm.value.grayMode = 'PERCENT'
@ -1068,7 +1068,7 @@ async function savePublishConfig() {
if (payload.grayMode === 'MEMBERS' && !hasGrayDirectorySyncCallback.value) { if (payload.grayMode === 'MEMBERS' && !hasGrayDirectorySyncCallback.value) {
payload.graySelectionSource = 'CALLBACK' payload.graySelectionSource = 'CALLBACK'
} }
await updateAdminApi.savePublishConfig(appId, payload) await updateAdminApi.savePublishConfig(appKey, payload)
ElMessage.success('发布配置已保存') ElMessage.success('发布配置已保存')
} catch { } catch {
ElMessage.error('保存失败') ElMessage.error('保存失败')
@ -1155,7 +1155,7 @@ async function loadGrayMembers() {
if (!showGray.value || !hasGrayDirectorySyncCallback.value) return if (!showGray.value || !hasGrayDirectorySyncCallback.value) return
loadingGrayMembers.value = true loadingGrayMembers.value = true
try { try {
const res = await updateAdminApi.listGrayMembers(appId, grayMemberKeyword.value || undefined, grayMemberGroupFilter.value || undefined) const res = await updateAdminApi.listGrayMembers(appKey, grayMemberKeyword.value || undefined, grayMemberGroupFilter.value || undefined)
grayMembers.value = res.data.data grayMembers.value = res.data.data
} catch { } catch {
grayMembers.value = [] grayMembers.value = []
@ -1171,7 +1171,7 @@ async function syncGrayMembers() {
} }
loadingGrayMembers.value = true loadingGrayMembers.value = true
try { try {
const res = await updateAdminApi.syncGrayMembers(appId) const res = await updateAdminApi.syncGrayMembers(appKey)
grayMembers.value = res.data.data grayMembers.value = res.data.data
ElMessage.success('成员已同步') ElMessage.success('成员已同步')
} catch { } catch {
@ -1345,7 +1345,7 @@ async function submitAppUpload() {
appVersionUploadProgress.value = 0 appVersionUploadProgress.value = 0
try { try {
const fd = new FormData() const fd = new FormData()
fd.append('appId', appId) fd.append('appKey', appKey)
fd.append('platform', f.platform) fd.append('platform', f.platform)
fd.append('versionName', f.versionName) fd.append('versionName', f.versionName)
fd.append('versionCode', String(f.versionCode)) fd.append('versionCode', String(f.versionCode))
@ -1439,7 +1439,7 @@ async function submitRnUpload() {
rnBundleUploadProgress.value = 0 rnBundleUploadProgress.value = 0
try { try {
const fd = new FormData() const fd = new FormData()
fd.append('appId', appId) fd.append('appKey', appKey)
fd.append('moduleId', f.moduleId) fd.append('moduleId', f.moduleId)
fd.append('platform', f.platform) fd.append('platform', f.platform)
fd.append('version', f.version) fd.append('version', f.version)
@ -1463,7 +1463,7 @@ async function submitRnUpload() {
async function loadAppVersions() { async function loadAppVersions() {
loadingApp.value = true loadingApp.value = true
try { try {
const res = await updateAdminApi.listAppVersions(appId, appPlatform.value) const res = await updateAdminApi.listAppVersions(appKey, appPlatform.value)
appVersions.value = res.data.data appVersions.value = res.data.data
} catch { } catch {
ElMessage.error('加载失败') ElMessage.error('加载失败')
@ -1475,7 +1475,7 @@ async function loadAppVersions() {
async function loadRnBundles() { async function loadRnBundles() {
loadingRn.value = true loadingRn.value = true
try { try {
const res = await updateAdminApi.listRnBundles(appId, rnModuleFilter.value || undefined, rnPlatform.value || undefined) const res = await updateAdminApi.listRnBundles(appKey, rnModuleFilter.value || undefined, rnPlatform.value || undefined)
rnBundles.value = res.data.data rnBundles.value = res.data.data
} catch { } catch {
ElMessage.error('加载失败') ElMessage.error('加载失败')
@ -1654,7 +1654,7 @@ function updateViewport() {
async function loadOperationLogs() { async function loadOperationLogs() {
loadingOperationLogs.value = true loadingOperationLogs.value = true
try { try {
const res = await updateAdminApi.listOperationLogs(appId, 100) const res = await updateAdminApi.listOperationLogs(appKey, 100)
operationLogs.value = res.data.data operationLogs.value = res.data.data
} catch { } catch {
operationLogs.value = [] operationLogs.value = []
@ -1718,7 +1718,7 @@ onMounted(() => {
window.addEventListener('resize', updateViewport) window.addEventListener('resize', updateViewport)
if (isServicesPortal.value) { if (isServicesPortal.value) {
appApi.list().then(res => { portalApps.value = res.data.data }) appApi.list().then(res => { portalApps.value = res.data.data })
if (!appId) return if (!appKey) return
} }
loadApp() loadApp()
loadAppVersions() loadAppVersions()