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

查看文件

@ -9,7 +9,7 @@
{{ diagnostics.online ? '用户在线' : '用户离线' }}
</el-tag>
<el-button
v-if="diagnostics?.appId && diagnostics?.userId"
v-if="diagnostics?.appKey && diagnostics?.userId"
type="primary"
:disabled="!diagnostics.deliverableDevices?.length"
:loading="testLoading"
@ -32,7 +32,7 @@
/>
</el-form-item>
<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-button type="primary" :loading="loading" @click="search">查询</el-button>
@ -101,7 +101,7 @@
<template #header>
<div class="header-row">
<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>
</div>
@ -141,7 +141,7 @@ import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
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 logsLoading = ref(false)
const testLoading = ref(false)
@ -158,12 +158,12 @@ async function search() {
}
loading.value = true
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
logs.value = []
logTotal.value = 0
logPage.value = 0
if (diagnostics.value.appId && diagnostics.value.userId) {
if (diagnostics.value.appKey && diagnostics.value.userId) {
await loadLogs()
}
} finally {
@ -172,11 +172,11 @@ async function search() {
}
async function loadLogs() {
if (!diagnostics.value?.appId || !diagnostics.value?.userId) return
if (!diagnostics.value?.appKey || !diagnostics.value?.userId) return
logsLoading.value = true
try {
const res = await opsApi.listPushDeviceLogs(
diagnostics.value.appId,
diagnostics.value.appKey,
diagnostics.value.userId,
logPage.value,
logSize,
@ -194,11 +194,11 @@ function changeLogPage(page: number) {
}
async function sendTestOffline() {
if (!diagnostics.value?.appId || !diagnostics.value?.userId) return
if (!diagnostics.value?.appKey || !diagnostics.value?.userId) return
testLoading.value = true
try {
const res = await opsApi.sendPushTestOffline({
appId: diagnostics.value.appId,
appKey: diagnostics.value.appKey,
userId: diagnostics.value.userId,
title: 'XuqmGroup Push 测试',
body: `离线推送测试 ${new Date().toLocaleString('zh-CN')}`,

查看文件

@ -10,7 +10,7 @@
</div>
<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">
<template #default="{ row }">
<el-tag size="small">{{ row.platform }}</el-tag>

查看文件

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

查看文件

@ -68,7 +68,7 @@ imClient.interceptors.response.use(
export interface ImUser {
id: string
appId: string
appKey: string
userId: string
nickname: string
avatar?: string
@ -79,7 +79,7 @@ export interface ImUser {
export interface ImProfile {
id?: string
appId?: string
appKey?: string
userId: string
nickname?: string | null
avatar?: string | null
@ -90,7 +90,7 @@ export interface ImProfile {
export interface ImGroup {
id: string
appId: string
appKey: string
name: string
creatorId: string
groupType?: string | null
@ -102,7 +102,7 @@ export interface ImGroup {
export interface ImMessage {
id: string
appId: string
appKey: string
fromUserId: string
toId: string
chatType: 'SINGLE' | 'GROUP'
@ -131,7 +131,7 @@ export interface ImStats {
export interface OperationLog {
id: string
appId: string
appKey: string
operatorId: string
action: string
resourceType: string
@ -142,7 +142,7 @@ export interface OperationLog {
export interface KeywordFilter {
id: string
appId: string
appKey: string
pattern: string
replacement?: string | null
action: 'REPLACE' | 'BLOCK'
@ -152,7 +152,7 @@ export interface KeywordFilter {
export interface GlobalMute {
id: string
appId: string
appKey: string
enabled: boolean
createdAt: number
updatedAt: number
@ -160,7 +160,7 @@ export interface GlobalMute {
export interface WebhookConfig {
id: string
appId: string
appKey: string
url: string
secret?: string | null
enabled: boolean
@ -177,7 +177,7 @@ export interface WebhookConfigForm {
export interface WebhookDelivery {
id: string
appId: string
appKey: string
callbackId: string
callbackEvent: string
url: string
@ -191,7 +191,7 @@ export interface WebhookDelivery {
export interface WebhookAlert {
id: string
appId: string
appKey: string
webhookId: string
webhookUrl: string
alertType: string
@ -203,7 +203,7 @@ export interface WebhookAlert {
export interface GroupJoinRequest {
id: string
appId: string
appKey: string
groupId: string
requesterId: string
remark?: string | null
@ -213,192 +213,192 @@ export interface GroupJoinRequest {
}
export const imAdminApi = {
listUsers(appId: string, page = 0, size = 20) {
listUsers(appKey: string, page = 0, size = 20) {
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') {
return imClient.put(`/api/im/admin/users/${encodeURIComponent(userId)}/status`, { status }, { params: { appId } })
updateUserStatus(appKey: string, userId: string, status: 'ACTIVE' | 'BANNED') {
return imClient.put(`/api/im/admin/users/${encodeURIComponent(userId)}/status`, { status }, { params: { appKey } })
},
listGroups(appId: string) {
return imClient.get<{ data: ImGroup[] }>('/api/im/admin/groups', { params: { appId } })
listGroups(appKey: string) {
return imClient.get<{ data: ImGroup[] }>('/api/im/admin/groups', { params: { appKey } })
},
getStats(appId: string) {
return imClient.get<{ data: ImStats }>('/api/im/admin/stats', { params: { appId } })
getStats(appKey: string) {
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', {
params: { appId, page, size },
params: { appKey, page, size },
})
},
listWebhooks(appId: string) {
listWebhooks(appKey: string) {
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, {
params: { appId },
params: { appKey },
})
},
updateUser(
appId: string,
appKey: string,
userId: string,
form: { nickname?: string; avatar?: string; gender?: string; status?: string },
) {
return imClient.put<{ data: ImUser }>(
`/api/im/admin/users/${encodeURIComponent(userId)}`,
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, {
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)}`, {
params: { appId },
params: { appKey },
})
},
listKeywordFilters(appId: string) {
listKeywordFilters(appKey: string) {
return imClient.get<{ data: KeywordFilter[] }>('/api/im/admin/keyword-filters', {
params: { appId },
params: { appKey },
})
},
createKeywordFilter(
appId: string,
appKey: string,
form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean },
) {
return imClient.post<{ data: KeywordFilter }>('/api/im/admin/keyword-filters', form, {
params: { appId },
params: { appKey },
})
},
updateKeywordFilter(
appId: string,
appKey: string,
filterId: string,
form: { pattern: string; replacement?: string; action: 'REPLACE' | 'BLOCK'; enabled: boolean },
) {
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)}`, {
params: { appId },
params: { appKey },
})
},
getGlobalMute(appId: string) {
getGlobalMute(appKey: string) {
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, {
params: { appId, enabled },
params: { appKey, enabled },
})
},
listGroupMembers(appId: string, groupId: string) {
listGroupMembers(appKey: string, groupId: string) {
return imClient.get<{ data: ImUser[] }>(
`/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[] }>(
`/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 }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/members`,
{ userId },
{ params: { appId } },
{ params: { appKey } },
)
},
removeGroupMember(appId: string, groupId: string, userId: string) {
removeGroupMember(appKey: string, groupId: string, userId: string) {
return imClient.delete<{ data: ImGroup }>(
`/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 }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/roles`,
{ 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 }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/mute`,
{ userId, minutes },
{ params: { appId } },
{ params: { appKey } },
)
},
listGroupJoinRequests(appId: string, groupId: string) {
listGroupJoinRequests(appKey: string, groupId: string) {
return imClient.get<{ data: GroupJoinRequest[] }>(
`/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 }>(
`/api/im/groups/${encodeURIComponent(groupId)}/join-requests`,
null,
{
params: {
appId,
appKey,
...(remark ? { remark } : {}),
},
},
)
},
acceptGroupJoinRequest(appId: string, groupId: string, requestId: string) {
acceptGroupJoinRequest(appKey: string, groupId: string, requestId: string) {
return imClient.post<{ data: GroupJoinRequest }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/accept`,
null,
{ params: { appId } },
{ params: { appKey } },
)
},
rejectGroupJoinRequest(appId: string, groupId: string, requestId: string) {
rejectGroupJoinRequest(appKey: string, groupId: string, requestId: string) {
return imClient.post<{ data: GroupJoinRequest }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/join-requests/${encodeURIComponent(requestId)}/reject`,
null,
{ params: { appId } },
{ params: { appKey } },
)
},
getMessages(
appId: string,
appKey: string,
userA: string,
userB: string,
page = 0,
@ -412,7 +412,7 @@ export const imAdminApi = {
) {
return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages', {
params: {
appId,
appKey,
userA,
userB,
page,
@ -425,20 +425,20 @@ export const imAdminApi = {
})
},
revokeMessage(appId: string, messageId: string) {
revokeMessage(appKey: string, messageId: string) {
return imClient.post<{ data: ImMessage }>(
`/api/im/admin/messages/${encodeURIComponent(messageId)}/revoke`,
{},
{ params: { appId } },
{ params: { appKey } },
)
},
dismissGroup(appId: string, groupId: string) {
return imClient.delete<{ data: null }>(`/api/im/admin/groups/${encodeURIComponent(groupId)}`, { params: { appId } })
dismissGroup(appKey: string, groupId: string) {
return imClient.delete<{ data: null }>(`/api/im/admin/groups/${encodeURIComponent(groupId)}`, { params: { appKey } })
},
registerUser(
appId: string,
appKey: string,
userId: string,
nickname?: string,
avatar?: string,
@ -454,12 +454,12 @@ export const imAdminApi = {
...(gender ? { gender } : {}),
...(status ? { status } : {}),
},
{ params: { appId } },
{ params: { appKey } },
)
},
createGroup(
appId: string,
appKey: string,
name: string,
creatorId: string,
memberIds: string[],
@ -475,31 +475,31 @@ export const imAdminApi = {
...(groupType ? { groupType } : {}),
...(announcement ? { announcement } : {}),
},
{ params: { appId } },
{ params: { appKey } },
)
},
updateGroup(
appId: string,
appKey: string,
groupId: string,
form: { name?: string; groupType?: string; announcement?: string },
) {
return imClient.put<{ data: ImGroup }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}`,
form,
{ params: { appId } },
{ params: { appKey } },
)
},
searchUsers(appId: string, keyword: string, size = 20) {
searchUsers(appKey: string, keyword: string, size = 20) {
return imClient.get<{ data: ImUser[] }>(
'/api/im/admin/users/search',
{ params: { appId, keyword, size } },
{ params: { appKey, keyword, size } },
)
},
searchMessages(
appId: string,
appKey: string,
filters: {
keyword?: string
chatType?: string
@ -512,7 +512,7 @@ export const imAdminApi = {
) {
return imClient.get<{ data: PagedResult<ImMessage> }>('/api/im/admin/messages/search', {
params: {
appId,
appKey,
...(filters.keyword ? { keyword: filters.keyword } : {}),
...(filters.chatType ? { chatType: filters.chatType } : {}),
...(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 }>(
`/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 }>(
`/api/im/accounts/${encodeURIComponent(userId)}`,
{},
{
params: {
appId,
appKey,
...(nickname ? { nickname } : {}),
...(avatar ? { avatar } : {}),
...(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 }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/owner`,
{ 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 }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/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 }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/attributes/delete`,
{ 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[] }> }>(
`/api/im/admin/groups/${encodeURIComponent(groupId)}/read-receipts`,
{ 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 }> }>(
'/api/im/admin/users/state',
{ params: { userIds: userIds.join(',') } },
@ -586,32 +586,32 @@ export const imAdminApi = {
},
listWebhookDeliveries(
appId: string,
appKey: string,
params: { callbackEvent?: string; success?: boolean; page?: number; size?: number } = {},
) {
return imClient.get<{ data: PagedResult<WebhookDelivery> }>('/api/im/admin/webhook-deliveries', {
params: { appId, ...params },
params: { appKey, ...params },
})
},
listWebhookAlerts(
appId: string,
appKey: string,
params: { acknowledged?: boolean; page?: number; size?: number } = {},
) {
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 }>(
`/api/im/admin/webhook-alerts/${encodeURIComponent(alertId)}/acknowledge`,
null,
{ params: { appId } },
{ params: { appKey } },
)
},
getWebhookHealth(appId: string, webhookId: string) {
getWebhookHealth(appKey: string, webhookId: string) {
return imClient.get<{
data: {
webhookId: string
@ -621,6 +621,6 @@ export const imAdminApi = {
lastFailureAt: number | null
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 {
tokenType: string
appId: string
appKey: string
userId: string
online: boolean
lastSeenAt: number
@ -29,7 +29,7 @@ export interface UserPushStatus {
export interface DeviceLoginLog {
id: string
appId: string
appKey: string
userId: string
vendor: string
deviceId: string | null
@ -48,7 +48,7 @@ export interface PagedLogs {
}
export interface TestPushResult {
appId: string
appKey: string
userId: string
sent: boolean
targetCount: number
@ -56,21 +56,21 @@ export interface TestPushResult {
}
export const pushAdminApi = {
getUserStatus(appId: string, userId: string) {
getUserStatus(appKey: string, userId: string) {
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', {
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', {
appId,
appKey,
userId,
title,
body,

查看文件

@ -87,14 +87,14 @@ export type GraySelectionSource = 'LOCAL' | 'CALLBACK'
export interface PublishConfig {
id: string
appId: string
appKey: string
configJson?: string
updatedAt: string
}
export interface OperationLog {
id: string
appId: string
appKey: string
resourceType: string
resourceId: string
action: string
@ -119,7 +119,7 @@ export interface GrayMemberGroup {
export interface StoreConfig {
id: string
appId: string
appKey: string
storeType: StoreType
configJson?: string
enabled: boolean
@ -128,7 +128,7 @@ export interface StoreConfig {
export interface AppVersion {
id: string
appId: string
appKey: string
platform: 'ANDROID' | 'IOS' | 'HARMONY'
versionName: string
versionCode: number
@ -164,7 +164,7 @@ export interface AppPackageInspectResult {
export interface RnBundle {
id: string
appId: string
appKey: string
moduleId: string
platform: 'ANDROID' | 'IOS' | 'HARMONY'
version: string
@ -221,9 +221,9 @@ export interface UnifiedReleaseManifest {
}
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', {
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', {
params: { appId, ...(moduleId && { moduleId }), ...(platform && { platform }) },
params: { appKey, ...(moduleId && { moduleId }), ...(platform && { platform }) },
})
},
@ -293,20 +293,20 @@ export const updateAdminApi = {
// ── Store config ────────────────────────────────────────────────────────
getStoreConfigs(appId: string) {
return updateClient.get<{ data: StoreConfig[] }>('/api/v1/updates/store/configs', { params: { appId } })
getStoreConfigs(appKey: string) {
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 }>(
`/api/v1/updates/store/configs/${storeType}`,
{ configJson, enabled },
{ params: { appId } },
{ params: { appKey } },
)
},
deleteStoreConfig(appId: string, storeType: StoreType) {
return updateClient.delete(`/api/v1/updates/store/configs/${storeType}`, { params: { appId } })
deleteStoreConfig(appKey: string, storeType: StoreType) {
return updateClient.delete(`/api/v1/updates/store/configs/${storeType}`, { params: { appKey } })
},
executeSubmitToStores(
@ -329,29 +329,29 @@ export const updateAdminApi = {
)
},
getPublishConfig(appId: string) {
return updateClient.get<{ data: PublishConfig }>('/api/v1/updates/publish/config', { params: { appId } })
getPublishConfig(appKey: string) {
return updateClient.get<{ data: PublishConfig }>('/api/v1/updates/publish/config', { params: { appKey } })
},
savePublishConfig(appId: string, config: Record<string, unknown>) {
return updateClient.put<{ data: PublishConfig }>('/api/v1/updates/publish/config', config, { params: { appId } })
savePublishConfig(appKey: string, config: Record<string, unknown>) {
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', {
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', {
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, {
params: { appId },
params: { appKey },
})
},
}

查看文件

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

查看文件

@ -24,10 +24,10 @@
</div>
<div style="margin-top:10px;display:flex;gap:8px;flex-wrap:wrap">
<!-- 服务配置页使用的是租户应用主键 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 size="small" @click="$router.push(`/apps/${route.params.appId}`)">
<el-button size="small" @click="$router.push(`/apps/${route.params.appKey}`)">
返回详情
</el-button>
</div>
@ -243,7 +243,7 @@ function normalizeFriendRequestMode(
}
async function loadData() {
const id = route.params.appId as string
const id = route.params.appKey as string
const [appRes, svcRes] = await Promise.all([
appApi.get(id),
appApi.getServices(id),
@ -265,7 +265,7 @@ async function onToggleImService(enable: boolean) {
confirmButtonText: '确认关闭',
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('已关闭')
loadData()
}
@ -275,7 +275,7 @@ async function onToggleImConfig(patch: Partial<ImServiceConfig>) {
...imConfig.value,
...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 配置已更新')
loadData()
}

查看文件

@ -699,8 +699,8 @@
<el-descriptions :column="1" border>
<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="请求体">统一 envelope`callbackId``callbackType``callbackEvent``requestTime``payload``appId`</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="请求体">统一 envelope`callbackId``callbackType``callbackEvent``requestTime``payload``appKey`</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="幂等建议">接收方建议按 `callbackId` 去重</el-descriptions-item>
</el-descriptions>
@ -779,7 +779,7 @@ const appKey = computed(() => {
if (typeof queryAppKey === 'string' && queryAppKey.trim()) {
return queryAppKey.trim()
}
return String(route.params['appId'] ?? '')
return String(route.params['appKey'] ?? '')
})
const genderLabel: Record<string, string> = {

查看文件

@ -30,7 +30,7 @@
<el-descriptions :column="1" border>
<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="验签公式">`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>
<el-table :data="webhookEvents" border stripe style="margin-top:16px">
@ -44,7 +44,7 @@
<template #header>
<div class="toolbar toolbar-space-between">
<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>
</div>
@ -86,7 +86,7 @@
<el-table-column label="操作" width="220" fixed="right">
<template #default="{ row }">
<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>
</template>
</el-table-column>
@ -139,7 +139,7 @@ const webhookForm = ref<WebhookConfigForm & { enabled: boolean }>({
enabled: true,
})
const appId = computed(() => route.params.appId as string)
const appKey = computed(() => route.params.appKey as string)
const webhookEvents = [
{ event: 'message.sent', payload: 'ImMessageEntity', description: '消息发送成功后触发。' },
@ -157,14 +157,14 @@ const webhookEvents = [
]
async function loadApp() {
const res = await appApi.get(appId.value)
const res = await appApi.get(appKey.value)
app.value = res.data.data
}
async function loadWebhooks() {
loadingWebhooks.value = true
try {
const res = await imAdminApi.listWebhooks(appId.value)
const res = await imAdminApi.listWebhooks(appKey.value)
webhooks.value = res.data.data
} finally {
loadingWebhooks.value = false
@ -208,9 +208,9 @@ async function submitWebhookForm() {
payload.secret = secret
}
if (editingWebhookId.value) {
await imAdminApi.updateWebhook(appId.value, editingWebhookId.value, payload)
await imAdminApi.updateWebhook(appKey.value, editingWebhookId.value, payload)
} else {
await imAdminApi.createWebhook(appId.value, payload)
await imAdminApi.createWebhook(appKey.value, payload)
}
ElMessage.success('回调配置已保存')
showWebhookDialog.value = false
@ -226,7 +226,7 @@ async function deleteWebhook(row: WebhookConfig) {
confirmButtonText: '确认删除',
cancelButtonText: '取消',
})
await imAdminApi.deleteWebhook(appId.value, row.id)
await imAdminApi.deleteWebhook(appKey.value, row.id)
ElMessage.success('已删除')
await loadWebhooks()
}

查看文件

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

查看文件

@ -66,7 +66,7 @@ import { imAdminApi, type WebhookDelivery } from '@/api/im'
const route = useRoute()
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 webhookUrl = ref('')
@ -79,12 +79,12 @@ const filterEvent = ref('')
const filterSuccess = ref<boolean | ''>('')
async function loadApp() {
const res = await appApi.get(appId.value)
const res = await appApi.get(appKey.value)
app.value = res.data.data
}
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)
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 }
if (filterEvent.value) params.callbackEvent = filterEvent.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
total.value = res.data.data.totalElements
} finally {

查看文件

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

查看文件

@ -2,14 +2,14 @@
<div>
<div v-if="isServicesPortal" class="portal-bar">
<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-select>
</div>
<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">
<template #header>用户设备状态查询</template>
<el-form inline @submit.prevent="queryUser">
@ -156,7 +156,7 @@ import { pushAdminApi, type DeviceLoginLog, type TestPushResult, type UserPushSt
const route = useRoute()
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 portalApps = ref<App[]>([])
@ -192,7 +192,7 @@ async function queryUser() {
querying.value = true
testResult.value = null
try {
const res = await pushAdminApi.getUserStatus(appId, uid)
const res = await pushAdminApi.getUserStatus(appKey, uid)
userStatus.value = res.data.data
logsUserId.value = uid
logsPage.value = 1
@ -210,7 +210,7 @@ async function sendTestPush() {
testResult.value = null
try {
const res = await pushAdminApi.testOffline(
appId,
appKey,
userStatus.value.userId,
testForm.title,
testForm.body,
@ -229,7 +229,7 @@ async function loadLogs() {
if (!uid) return
logsLoading.value = true
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
logs.value = d.content
logsTotal.value = d.total

查看文件

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

查看文件

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