2026-04-21 22:07:29 +08:00
|
|
|
<template>
|
|
|
|
|
<div v-if="app">
|
|
|
|
|
<el-page-header @back="$router.back()" :content="app.name" style="margin-bottom:24px" />
|
|
|
|
|
|
|
|
|
|
<el-card style="margin-bottom:16px">
|
|
|
|
|
<el-descriptions :column="2" border>
|
|
|
|
|
<el-descriptions-item label="应用名称">{{ app.name }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="包名">{{ app.packageName }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="AppKey">
|
|
|
|
|
<el-text class="mono">{{ app.appKey }}</el-text>
|
|
|
|
|
<el-button link @click="copy(app.appKey)"><el-icon><CopyDocument /></el-icon></el-button>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="AppSecret">
|
|
|
|
|
<el-text class="mono">{{ app.appSecret }}</el-text>
|
|
|
|
|
<el-button link @click="copy(app.appSecret)"><el-icon><CopyDocument /></el-icon></el-button>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="简述" :span="2">{{ app.description ?? '-' }}</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
<el-card>
|
|
|
|
|
<template #header>功能服务配置</template>
|
|
|
|
|
<el-tabs v-model="activePlatform">
|
|
|
|
|
<el-tab-pane label="Android" name="ANDROID" />
|
|
|
|
|
<el-tab-pane label="iOS" name="IOS" />
|
|
|
|
|
<el-tab-pane label="鸿蒙" name="HARMONY" />
|
|
|
|
|
</el-tabs>
|
|
|
|
|
|
|
|
|
|
<div class="service-grid">
|
|
|
|
|
<el-card v-for="svcType in ['IM', 'PUSH', 'UPDATE']" :key="svcType" class="service-card">
|
|
|
|
|
<div class="service-header">
|
|
|
|
|
<span class="service-name">{{ serviceLabel(svcType) }}</span>
|
|
|
|
|
<el-switch
|
|
|
|
|
:model-value="isEnabled(activePlatform, svcType)"
|
|
|
|
|
@change="(val: boolean) => toggleService(activePlatform, svcType, val)"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<template v-if="isEnabled(activePlatform, svcType)">
|
|
|
|
|
<div class="key-row">
|
|
|
|
|
<span class="key-label">SecretKey</span>
|
|
|
|
|
<el-text class="mono key-value" size="small">
|
|
|
|
|
{{ getService(activePlatform, svcType)?.secretKey }}
|
|
|
|
|
</el-text>
|
|
|
|
|
<el-button link size="small" @click="copy(getService(activePlatform, svcType)?.secretKey ?? '')">
|
|
|
|
|
<el-icon><CopyDocument /></el-icon>
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button link size="small" type="warning"
|
|
|
|
|
@click="regenerate(getService(activePlatform, svcType)?.id ?? '')">
|
|
|
|
|
重新生成
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
2026-04-24 16:16:54 +08:00
|
|
|
<div style="margin-top:10px">
|
|
|
|
|
<el-button
|
|
|
|
|
v-if="svcType === 'IM'"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="$router.push(`/apps/${route.params.id}/im`)">
|
|
|
|
|
即时通讯管理 →
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button
|
|
|
|
|
v-if="svcType === 'UPDATE'"
|
|
|
|
|
size="small"
|
|
|
|
|
@click="$router.push(`/apps/${route.params.id}/update`)">
|
|
|
|
|
版本管理 →
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
2026-04-21 22:07:29 +08:00
|
|
|
</template>
|
|
|
|
|
</el-card>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { ref, onMounted } from 'vue'
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
import { appApi, type App, type FeatureService } from '@/api/app'
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
const app = ref<App | null>(null)
|
|
|
|
|
const services = ref<FeatureService[]>([])
|
|
|
|
|
const activePlatform = ref<'ANDROID' | 'IOS' | 'HARMONY'>('ANDROID')
|
|
|
|
|
|
|
|
|
|
function isEnabled(platform: string, svcType: string) {
|
|
|
|
|
return services.value.some(
|
|
|
|
|
s => s.platform === platform && s.serviceType === svcType && s.enabled
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getService(platform: string, svcType: string) {
|
|
|
|
|
return services.value.find(s => s.platform === platform && s.serviceType === svcType)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function serviceLabel(type: string) {
|
|
|
|
|
return { IM: '即时通讯 (IM)', PUSH: '离线推送', UPDATE: '版本管理' }[type] ?? type
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function loadData() {
|
|
|
|
|
const id = route.params.id as string
|
|
|
|
|
const [appRes, svcRes] = await Promise.all([
|
|
|
|
|
appApi.get(id), appApi.getServices(id),
|
|
|
|
|
])
|
|
|
|
|
app.value = appRes.data.data
|
|
|
|
|
services.value = svcRes.data.data
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function toggleService(platform: string, svcType: string, enable: boolean) {
|
|
|
|
|
await appApi.toggleService(route.params.id as string, platform, svcType, enable)
|
|
|
|
|
ElMessage.success(enable ? '已开启' : '已关闭')
|
|
|
|
|
loadData()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function regenerate(serviceId: string) {
|
|
|
|
|
await appApi.regenerateKey(route.params.id as string, serviceId)
|
|
|
|
|
ElMessage.success('密钥已重新生成')
|
|
|
|
|
loadData()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function copy(text: string) {
|
|
|
|
|
navigator.clipboard.writeText(text)
|
|
|
|
|
ElMessage.success('已复制')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(loadData)
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.mono { font-family: monospace; font-size: 12px; }
|
|
|
|
|
.service-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 16px; }
|
|
|
|
|
.service-card { border: 1px solid #e8e8e8; }
|
|
|
|
|
.service-header { display: flex; justify-content: space-between; align-items: center; font-weight: 500; margin-bottom: 12px; }
|
|
|
|
|
.service-name { font-size: 15px; }
|
|
|
|
|
.key-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
|
|
|
.key-label { font-size: 12px; color: #888; }
|
|
|
|
|
.key-value { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
</style>
|