feat: unify app identity on appKey in platforms
这个提交包含在:
父节点
6eeea6f268
当前提交
775e6c85e8
@ -15,7 +15,7 @@ const router = createRouter({
|
||||
{ path: 'statistics', component: () => import('@/views/statistics/StatisticsView.vue') },
|
||||
{ path: 'service-requests', component: () => import('@/views/services/ServiceRequestsView.vue') },
|
||||
{ path: 'apps', component: () => import('@/views/apps/AppListView.vue') },
|
||||
{ path: 'apps/:id', component: () => import('@/views/apps/AppDetailView.vue') },
|
||||
{ path: 'apps/:appKey', component: () => import('@/views/apps/AppDetailView.vue') },
|
||||
{ path: 'push', component: () => import('@/views/push/PushDiagnosticsView.vue') },
|
||||
{ path: 'operation-logs', component: () => import('@/views/logs/OperationLogView.vue') },
|
||||
{ path: 'risk-control', component: () => import('@/views/risk/RiskControlView.vue') },
|
||||
|
||||
@ -61,7 +61,7 @@ const route = useRoute()
|
||||
const detail = ref<AppDetail | null>(null)
|
||||
|
||||
async function loadDetail() {
|
||||
const res = await opsApi.getApp(route.params.id as string)
|
||||
const res = await opsApi.getApp(route.params.appKey as string)
|
||||
detail.value = res.data.data
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="$router.push(`/apps/${row.id}`)">
|
||||
<el-button link type="primary" @click="$router.push(`/apps/${row.appKey}`)">
|
||||
详情
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
</div>
|
||||
|
||||
<el-table :data="requests" v-loading="loading">
|
||||
<el-table-column prop="appKey" label="AppID" width="180" />
|
||||
<el-table-column prop="appKey" label="AppKey" width="180" />
|
||||
<el-table-column prop="platform" label="平台" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-tag size="small">{{ row.platform }}</el-tag>
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="$router.push(`/apps/${row.id}`)">详情</el-button>
|
||||
<el-button link type="primary" @click="$router.push(`/apps/${row.appKey}`)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
@ -46,7 +46,7 @@ const router = createRouter({
|
||||
component: () => import('@/views/logs/OperationLogView.vue'),
|
||||
},
|
||||
{
|
||||
path: 'apps/:id',
|
||||
path: 'apps/:appKey',
|
||||
component: () => import('@/views/apps/AppDetailView.vue'),
|
||||
},
|
||||
{
|
||||
|
||||
@ -36,11 +36,10 @@
|
||||
</div>
|
||||
<template v-if="imService">
|
||||
<div style="margin-top:10px;display:flex;gap:8px;flex-wrap:wrap">
|
||||
<!-- IM 管理页按 appKey 作用域查询,不能把租户 app.id 直接传进去。 -->
|
||||
<el-button size="small" @click="$router.push({ path: `/apps/${route.params.id}/im`, query: { appKey: app.appKey } })">
|
||||
<el-button size="small" @click="$router.push({ path: `/apps/${app.appKey}/im`, query: { appKey: app.appKey } })">
|
||||
即时通讯管理 →
|
||||
</el-button>
|
||||
<el-button size="small" type="primary" plain @click="$router.push(`/apps/${route.params.id}/im-config`)">
|
||||
<el-button size="small" type="primary" plain @click="$router.push(`/apps/${app.appKey}/im-config`)">
|
||||
服务配置 →
|
||||
</el-button>
|
||||
</div>
|
||||
@ -80,7 +79,7 @@
|
||||
</div>
|
||||
<div class="service-actions">
|
||||
<template v-if="isServiceEnabled('PUSH')">
|
||||
<el-button size="small" type="primary" plain @click="$router.push(`/apps/${route.params.id}/push-config`)">
|
||||
<el-button size="small" type="primary" plain @click="$router.push(`/apps/${app.appKey}/push-config`)">
|
||||
推送配置 →
|
||||
</el-button>
|
||||
<el-button size="small" @click="$router.push(`/apps/${app.appKey}/push-management`)">
|
||||
@ -118,7 +117,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="service-actions">
|
||||
<el-button v-if="isServiceEnabled('UPDATE')" size="small" type="primary" plain @click="$router.push(`/apps/${route.params.id}/update`)">
|
||||
<el-button v-if="isServiceEnabled('UPDATE')" size="small" type="primary" plain @click="$router.push(`/apps/${app.appKey}/update`)">
|
||||
版本管理 →
|
||||
</el-button>
|
||||
<el-button v-else size="small" type="primary" plain @click="openActivationRequest('UPDATE')">
|
||||
@ -222,9 +221,9 @@ function getServiceRepresentative(svcType: string) {
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
const id = route.params.id as string
|
||||
const appKey = route.params.appKey as string
|
||||
const [appRes, svcRes] = await Promise.all([
|
||||
appApi.get(id), appApi.getServices(id),
|
||||
appApi.get(appKey), appApi.getServices(appKey),
|
||||
])
|
||||
app.value = appRes.data.data
|
||||
services.value = svcRes.data.data
|
||||
@ -239,7 +238,7 @@ async function onToggleService(svcType: string, enable: boolean) {
|
||||
type: 'warning', confirmButtonText: '确认关闭', cancelButtonText: '取消',
|
||||
})
|
||||
const platform = getServiceRepresentative(svcType)?.platform ?? 'ANDROID'
|
||||
await appApi.toggleService(route.params.id as string, platform, svcType, false)
|
||||
await appApi.toggleService(app.value?.appKey ?? (route.params.appKey as string), platform, svcType, false)
|
||||
ElMessage.success('已关闭')
|
||||
loadData()
|
||||
}
|
||||
@ -256,7 +255,7 @@ async function submitActivationRequest() {
|
||||
}
|
||||
submittingActivation.value = true
|
||||
try {
|
||||
await client.post(`/apps/${route.params.id}/services/request-activation`, null, {
|
||||
await client.post(`/apps/${app.value?.appKey ?? (route.params.appKey as string)}/services/request-activation`, null, {
|
||||
params: {
|
||||
platform: activationForm.value.platform,
|
||||
serviceType: activationForm.value.serviceType,
|
||||
@ -280,7 +279,7 @@ function openVerifyDialog(purpose: 'REVEAL_SECRET' | 'RESET_SECRET') {
|
||||
async function sendVerifyCode() {
|
||||
sendingCode.value = true
|
||||
try {
|
||||
await appApi.requestSecretVerify(route.params.id as string, verifyPurpose.value)
|
||||
await appApi.requestSecretVerify(app.value?.appKey ?? (route.params.appKey as string), verifyPurpose.value)
|
||||
codeSent.value = true
|
||||
ElMessage.success('验证码已发送')
|
||||
} catch {
|
||||
@ -294,13 +293,13 @@ async function submitVerify() {
|
||||
if (verifyCode.value.length !== 6) return ElMessage.warning('请输入6位验证码')
|
||||
submittingVerify.value = true
|
||||
try {
|
||||
const id = route.params.id as string
|
||||
const appKey = app.value?.appKey ?? (route.params.appKey as string)
|
||||
if (verifyPurpose.value === 'REVEAL_SECRET') {
|
||||
const res = await appApi.revealSecret(id, verifyCode.value)
|
||||
const res = await appApi.revealSecret(appKey, verifyCode.value)
|
||||
revealedSecret.value = res.data.data.appSecret
|
||||
ElMessage.success('AppSecret 已显示,请妥善保管')
|
||||
} else {
|
||||
const res = await appApi.resetSecret(id, verifyCode.value)
|
||||
const res = await appApi.resetSecret(appKey, verifyCode.value)
|
||||
revealedSecret.value = res.data.data.appSecret
|
||||
ElMessage.success('AppSecret 已重置,旧密钥立即失效')
|
||||
}
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click="$router.push(`/apps/${row.id}`)">详情</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(row.id)">删除</el-button>
|
||||
<el-button link type="primary" @click="$router.push(`/apps/${row.appKey}`)">详情</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(row.appKey)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -93,9 +93,9 @@ async function handleCreate() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(id: string) {
|
||||
async function handleDelete(appKey: string) {
|
||||
await ElMessageBox.confirm('确定删除此应用?删除后不可恢复。', '警告', { type: 'warning' })
|
||||
await appApi.delete(id)
|
||||
await appApi.delete(appKey)
|
||||
ElMessage.success('已删除')
|
||||
loadApps()
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
<el-switch :model-value="imEnabled" @change="(val: boolean) => onToggleImService(val)" />
|
||||
</div>
|
||||
<div style="margin-top:10px;display:flex;gap:8px;flex-wrap:wrap">
|
||||
<!-- 服务配置页使用的是租户应用主键 app.id;IM 管理页才带 appKey。 -->
|
||||
<!-- 服务配置页和 IM 管理页现在都按 appKey 作为应用唯一标识。 -->
|
||||
<el-button size="small" @click="$router.push({ path: `/apps/${route.params.appKey}/im`, query: { appKey: app.appKey } })">
|
||||
即时通讯管理 →
|
||||
</el-button>
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
<el-tab-pane label="版本管理" name="UPDATE">
|
||||
<div class="toolbar responsive-toolbar">
|
||||
<el-select
|
||||
v-model="updateAppId"
|
||||
v-model="updateAppKey"
|
||||
placeholder="选择应用"
|
||||
style="width: 320px"
|
||||
filterable
|
||||
@ -67,9 +67,9 @@
|
||||
>
|
||||
<el-option
|
||||
v-for="app in apps"
|
||||
:key="app.id"
|
||||
:key="app.appKey"
|
||||
:label="`${app.name} · ${app.packageName}`"
|
||||
:value="app.id"
|
||||
:value="app.appKey"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input-number v-model="updateLimit" :min="20" :max="200" :step="10" controls-position="right" />
|
||||
@ -125,7 +125,7 @@ const updateLoading = ref(false)
|
||||
const updateLogs = ref<UpdateOperationLog[]>([])
|
||||
const updateLimit = ref(100)
|
||||
const apps = ref<App[]>([])
|
||||
const updateAppId = ref('')
|
||||
const updateAppKey = ref('')
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
@ -148,8 +148,8 @@ async function loadApps() {
|
||||
try {
|
||||
const res = await appApi.list()
|
||||
apps.value = res.data.data
|
||||
if (!updateAppId.value && apps.value.length) {
|
||||
updateAppId.value = apps.value[0].id
|
||||
if (!updateAppKey.value && apps.value.length) {
|
||||
updateAppKey.value = apps.value[0].appKey
|
||||
}
|
||||
} catch {
|
||||
// ignore; empty state will be shown in the selector
|
||||
@ -173,13 +173,13 @@ async function loadTenantLogs() {
|
||||
}
|
||||
|
||||
async function loadUpdateLogs() {
|
||||
if (!updateAppId.value) {
|
||||
if (!updateAppKey.value) {
|
||||
updateLogs.value = []
|
||||
return
|
||||
}
|
||||
updateLoading.value = true
|
||||
try {
|
||||
const res = await updateAdminApi.listOperationLogs(updateAppId.value, updateLimit.value)
|
||||
const res = await updateAdminApi.listOperationLogs(updateAppKey.value, updateLimit.value)
|
||||
updateLogs.value = res.data.data ?? []
|
||||
} finally {
|
||||
updateLoading.value = false
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户