feat(push-config): 厂商凭据与 Profiles 分别独立保存

- 厂商凭据卡片 header 右侧增加「保存凭据」按钮
- Profiles 卡片底部保留「保存 Profiles」按钮
- 拆分 saving 为 savingVendors / savingProfiles,加载状态独立

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
XuqmGroup 2026-06-26 14:27:06 +08:00
父节点 ccb3591b9b
当前提交 0b0e004c2e

查看文件

@ -34,7 +34,12 @@
</el-card> </el-card>
<el-card style="margin-bottom:16px"> <el-card style="margin-bottom:16px">
<template #header>厂商凭据</template> <template #header>
<div style="display:flex;justify-content:space-between;align-items:center">
<span>厂商凭据</span>
<el-button type="primary" size="small" :loading="savingVendors" @click="saveVendors">保存凭据</el-button>
</div>
</template>
<div class="vendor-grid"> <div class="vendor-grid">
<el-card v-for="vendor in filteredVendorDefs" :key="vendor.key" shadow="never" class="vendor-card"> <el-card v-for="vendor in filteredVendorDefs" :key="vendor.key" shadow="never" class="vendor-card">
<template #header>{{ vendor.label }}</template> <template #header>{{ vendor.label }}</template>
@ -194,7 +199,7 @@
<div class="toolbar"> <div class="toolbar">
<el-button @click="reloadConfig" :loading="loading">刷新</el-button> <el-button @click="reloadConfig" :loading="loading">刷新</el-button>
<el-button type="primary" @click="saveConfig" :loading="saving">保存配置</el-button> <el-button type="primary" @click="saveProfiles" :loading="savingProfiles">保存 Profiles</el-button>
</div> </div>
</el-card> </el-card>
</div> </div>
@ -261,7 +266,8 @@ const route = useRoute()
const app = ref<App | null>(null) const app = ref<App | null>(null)
const services = ref<FeatureService[]>([]) const services = ref<FeatureService[]>([])
const loading = ref(false) const loading = ref(false)
const saving = ref(false) const savingVendors = ref(false)
const savingProfiles = ref(false)
const isMobile = ref(window.innerWidth < 768) const isMobile = ref(window.innerWidth < 768)
const selectedPlatform = ref<'ANDROID' | 'IOS' | 'HARMONY'>('ANDROID') const selectedPlatform = ref<'ANDROID' | 'IOS' | 'HARMONY'>('ANDROID')
@ -535,11 +541,8 @@ function applySelectedPlatformConfig() {
replaceState(parseConfig(raw)) replaceState(parseConfig(raw))
} }
async function saveConfig() { function buildPayload(): PushServiceConfig {
if (!app.value) return return {
saving.value = true
try {
const payload: PushServiceConfig = {
schemaVersion: 2, schemaVersion: 2,
updatedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
vendors: { vendors: {
@ -553,13 +556,33 @@ async function saveConfig() {
}, },
profiles: pushConfig.profiles.map(profile => normalizeProfile(profile)), profiles: pushConfig.profiles.map(profile => normalizeProfile(profile)),
} }
await appApi.updateServiceConfig(app.value.appKey, selectedPlatform.value, 'PUSH', { pushConfig: payload }) }
ElMessage.success('推送配置已保存')
async function saveVendors() {
if (!app.value) return
savingVendors.value = true
try {
await appApi.updateServiceConfig(app.value.appKey, selectedPlatform.value, 'PUSH', { pushConfig: buildPayload() })
ElMessage.success('厂商凭据已保存')
await loadData() await loadData()
} catch { } catch {
ElMessage.error('保存失败') ElMessage.error('保存失败')
} finally { } finally {
saving.value = false savingVendors.value = false
}
}
async function saveProfiles() {
if (!app.value) return
savingProfiles.value = true
try {
await appApi.updateServiceConfig(app.value.appKey, selectedPlatform.value, 'PUSH', { pushConfig: buildPayload() })
ElMessage.success('Profiles 已保存')
await loadData()
} catch {
ElMessage.error('保存失败')
} finally {
savingProfiles.value = false
} }
} }