平台配置页改造
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { RefreshRight } from '@element-plus/icons-vue'
|
||||
|
||||
import AdminPlatformAgisoSection from '@/components/admin/AdminPlatformAgisoSection.vue'
|
||||
import AdminPlatformCloudtentaclesSection from '@/components/admin/AdminPlatformCloudtentaclesSection.vue'
|
||||
@@ -20,7 +21,6 @@ import {
|
||||
fetchAdminScheduledJobsConfig,
|
||||
} from '@/services/admin'
|
||||
import { hasAdminRole } from '@/utils/admin-auth'
|
||||
import '@/styles/admin-platform-shops.css'
|
||||
|
||||
const loading = ref(true)
|
||||
const isDevMode = import.meta.env.DEV
|
||||
@@ -189,287 +189,317 @@ async function loadConfigs() {
|
||||
}
|
||||
}
|
||||
|
||||
function switchPlatform(platform: PlatformTab) {
|
||||
activePlatform.value = platform
|
||||
}
|
||||
|
||||
async function saveAgisoConfigs() {
|
||||
await persistAgisoConfigs(loadConfigs)
|
||||
}
|
||||
|
||||
function switchTab(tab: string) {
|
||||
activePlatform.value = tab as PlatformTab
|
||||
}
|
||||
|
||||
onMounted(loadConfigs)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="admin-panel admin-platform-shops">
|
||||
<header class="hero-card">
|
||||
<div class="hero-copy">
|
||||
<div class="platform-page">
|
||||
<!-- 页面头部 -->
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<h1>平台配置</h1>
|
||||
<p>按平台分别管理来源接入、凭据与店铺能力。Agiso 负责 webhook / 店铺消息配置,91卡券负责新订单来源,快手小店核销负责独立券核销调试,cloudtentacles 负责外部履约平台登录。</p>
|
||||
<p>按平台分别管理来源接入、凭据与店铺能力。</p>
|
||||
</div>
|
||||
<div class="hero-actions">
|
||||
<el-button round @click="loadConfigs">刷新全部配置</el-button>
|
||||
<el-button v-if="activePlatform === 'agiso'" round type="primary" @click="addShop">新增 Agiso 店铺</el-button>
|
||||
<div class="header-actions">
|
||||
<el-button circle title="刷新全部配置" @click="loadConfigs">
|
||||
<template #icon><el-icon><RefreshRight /></el-icon></template>
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="activePlatform === 'agiso'"
|
||||
type="primary"
|
||||
@click="addShop"
|
||||
>
|
||||
新增 Agiso 店铺
|
||||
</el-button>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div v-if="!hasAdminRole('admin')" class="empty-block">仅管理员可以维护平台配置。</div>
|
||||
<!-- 权限不足 -->
|
||||
<el-result
|
||||
v-if="!hasAdminRole('admin')"
|
||||
icon="warning"
|
||||
title="仅管理员可以维护平台配置"
|
||||
sub-title="请切换管理员账号登录"
|
||||
/>
|
||||
|
||||
<template v-else>
|
||||
<p v-if="errorMessage" class="error-copy">{{ errorMessage }}</p>
|
||||
<div v-if="loading" class="empty-block">平台配置加载中</div>
|
||||
<!-- 错误提示 -->
|
||||
<el-alert
|
||||
v-if="errorMessage"
|
||||
:title="errorMessage"
|
||||
type="error"
|
||||
show-icon
|
||||
:closable="false"
|
||||
style="margin-bottom: 16px"
|
||||
/>
|
||||
|
||||
<!-- 加载态 -->
|
||||
<el-skeleton v-if="loading" :rows="8" animated />
|
||||
|
||||
<template v-else>
|
||||
<section class="overview-grid">
|
||||
<button
|
||||
type="button"
|
||||
:class="['platform-overview-card', { 'is-active': activePlatform === 'agiso' }]"
|
||||
@click="switchPlatform('agiso')"
|
||||
<!-- 概览卡片 -->
|
||||
<div class="overview-grid">
|
||||
<el-card
|
||||
v-for="card in [
|
||||
{ key: 'agiso', label: 'Agiso', tag: 'Webhook / 店铺', value: agisoStats.configuredShopCount, unit: '已配置店铺', meta: `识别到 ${agisoStats.observedShopCount} 家 · 待补 ${agisoStats.pendingObservedCount} 家` },
|
||||
{ key: 'notifications', label: '内部通知', tag: 'Bark / 值班', value: notificationStats.enabledRecipientCount, unit: '启用接收人', meta: `配置 ${notificationStats.configuredRecipientCount} 人 · 最近成功 ${notificationStats.lastSuccessCount} 个` },
|
||||
{ key: 'ninetyone', label: '91卡券', tag: '接入 / 待补全', value: ninetyoneStats.pendingCount, unit: '待补全订单', meta: `当前 ${ninetyoneStats.currentCount} 条 · 已生成任务 ${ninetyoneStats.taskReadyCount} 条` },
|
||||
{ key: 'kuaishouEticket', label: '快手小店核销', tag: 'Cookie / 券核销', value: kuaishouEticketStats.configuredShopCount, unit: '已配置店铺', meta: `Cookie 就绪 ${kuaishouEticketStats.cookieReadyCount} 家 · 当前店铺 ${kuaishouEticketStats.selectedShopReady ? '可调试' : '待补全'}` },
|
||||
...(isDevMode ? [{ key: 'cloudtentacles', label: 'cloudtentacles', tag: '履约 / 登录', value: cloudtentaclesStats.hasCredential ? '已配置' : '未配置', unit: '履约凭据', meta: `短信 ${cloudtentaclesStats.smsSent ? '已发送' : '未发送'} · 会话 ${cloudtentaclesStats.validated ? '已验证' : '未验证'}` }] : []),
|
||||
]"
|
||||
:key="card.key"
|
||||
:class="['overview-card', { 'is-active': activePlatform === card.key }]"
|
||||
:body-style="{ padding: '18px', cursor: 'pointer' }"
|
||||
shadow="hover"
|
||||
@click="switchTab(card.key)"
|
||||
>
|
||||
<div class="platform-head">
|
||||
<span class="platform-badge">Agiso</span>
|
||||
<span class="platform-tag">Webhook / 店铺</span>
|
||||
<div class="card-head">
|
||||
<el-tag size="small" type="primary">{{ card.label }}</el-tag>
|
||||
<el-tag size="small">{{ card.tag }}</el-tag>
|
||||
</div>
|
||||
<strong>{{ agisoStats.configuredShopCount }}</strong>
|
||||
<span>已配置店铺</span>
|
||||
<div class="platform-metrics">
|
||||
<span>识别到 {{ agisoStats.observedShopCount }} 家</span>
|
||||
<span>待补 {{ agisoStats.pendingObservedCount }} 家</span>
|
||||
</div>
|
||||
</button>
|
||||
<div class="card-value">{{ card.value }}</div>
|
||||
<div class="card-unit">{{ card.unit }}</div>
|
||||
<div class="card-meta">{{ card.meta }}</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
:class="['platform-overview-card', { 'is-active': activePlatform === 'notifications' }]"
|
||||
@click="switchPlatform('notifications')"
|
||||
>
|
||||
<div class="platform-head">
|
||||
<span class="platform-badge">内部通知</span>
|
||||
<span class="platform-tag">Bark / 值班</span>
|
||||
</div>
|
||||
<strong>{{ notificationStats.enabledRecipientCount }}</strong>
|
||||
<span>启用接收人</span>
|
||||
<div class="platform-metrics">
|
||||
<span>配置 {{ notificationStats.configuredRecipientCount }} 人</span>
|
||||
<span>最近成功 {{ notificationStats.lastSuccessCount }} 个</span>
|
||||
</div>
|
||||
</button>
|
||||
<!-- 平台切换 Tab -->
|
||||
<el-tabs v-model="activePlatform" type="card" class="platform-tabs">
|
||||
<el-tab-pane label="Agiso 店铺与消息" name="agiso">
|
||||
<AdminPlatformAgisoSection
|
||||
:agiso-file-path="agisoFilePath"
|
||||
:defaults="defaults"
|
||||
:shops="shops"
|
||||
:observed-shops="observedShops"
|
||||
:saving="saving"
|
||||
:is-shop-expanded="isShopExpanded"
|
||||
:toggle-shop="toggleShop"
|
||||
:expand-all-shops="expandAllShops"
|
||||
:collapse-all-shops="collapseAllShops"
|
||||
:describe-shop="describeShop"
|
||||
:remove-shop="removeShop"
|
||||
:import-observed-shop="importObservedShop"
|
||||
:save-agiso-configs="saveAgisoConfigs"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
:class="['platform-overview-card', { 'is-active': activePlatform === 'ninetyone' }]"
|
||||
@click="switchPlatform('ninetyone')"
|
||||
>
|
||||
<div class="platform-head">
|
||||
<span class="platform-badge">91卡券</span>
|
||||
<span class="platform-tag">接入 / 待补全</span>
|
||||
</div>
|
||||
<strong>{{ ninetyoneStats.pendingCount }}</strong>
|
||||
<span>待补全订单</span>
|
||||
<div class="platform-metrics">
|
||||
<span>当前 {{ ninetyoneStats.currentCount }} 条</span>
|
||||
<span>已生成任务 {{ ninetyoneStats.taskReadyCount }} 条</span>
|
||||
</div>
|
||||
</button>
|
||||
<el-tab-pane label="91卡券接入" name="ninetyone">
|
||||
<AdminPlatformNinetyoneSection
|
||||
:ninetyone-loading="ninetyoneLoading"
|
||||
:ninetyone-action-loading-id="ninetyoneActionLoadingId"
|
||||
:ninetyone-result-error="ninetyoneResultError"
|
||||
:ninetyone-status="ninetyoneStatus"
|
||||
:ninetyone-orders="ninetyoneOrders"
|
||||
:ninetyone-stats="ninetyoneStats"
|
||||
:load-ninetyone-orders="loadNinetyoneOrders"
|
||||
:handle-ninetyone-status-change="handleNinetyoneStatusChange"
|
||||
:handle-ninetyone-retry-order="handleNinetyoneRetryOrder"
|
||||
:handle-ninetyone-fail-order="handleNinetyoneFailOrder"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
:class="['platform-overview-card', { 'is-active': activePlatform === 'kuaishouEticket' }]"
|
||||
@click="switchPlatform('kuaishouEticket')"
|
||||
>
|
||||
<div class="platform-head">
|
||||
<span class="platform-badge">快手小店核销</span>
|
||||
<span class="platform-tag">Cookie / 券核销</span>
|
||||
</div>
|
||||
<strong>{{ kuaishouEticketStats.configuredShopCount }}</strong>
|
||||
<span>已配置店铺</span>
|
||||
<div class="platform-metrics">
|
||||
<span>Cookie 就绪 {{ kuaishouEticketStats.cookieReadyCount }} 家</span>
|
||||
<span>当前店铺 {{ kuaishouEticketStats.selectedShopReady ? '可调试' : '待补全' }}</span>
|
||||
</div>
|
||||
</button>
|
||||
<el-tab-pane label="内部通知" name="notifications">
|
||||
<AdminPlatformNotificationSection
|
||||
:notification-file-path="notificationFilePath"
|
||||
:notification-form="notificationForm"
|
||||
:notification-recipients="notificationRecipients"
|
||||
:notification-saving="notificationSaving"
|
||||
:notification-testing="notificationTesting"
|
||||
:notification-result-error="notificationResultError"
|
||||
:notification-test-result="notificationTestResult"
|
||||
:scheduled-jobs-file-path="scheduledJobsFilePath"
|
||||
:scheduled-jobs-form="scheduledJobsForm"
|
||||
:scheduled-jobs="scheduledJobs"
|
||||
:scheduled-job-runtime="scheduledJobRuntime"
|
||||
:scheduled-jobs-saving="scheduledJobsSaving"
|
||||
:scheduled-job-running-id="scheduledJobRunningId"
|
||||
:notification-stats="notificationStats"
|
||||
:add-notification-recipient="addNotificationRecipient"
|
||||
:remove-notification-recipient="removeNotificationRecipient"
|
||||
:handle-notification-save-config="handleNotificationSaveConfig"
|
||||
:handle-notification-test="handleNotificationTest"
|
||||
:handle-scheduled-jobs-save-config="handleScheduledJobsSaveConfig"
|
||||
:handle-scheduled-job-run-now="handleScheduledJobRunNow"
|
||||
:get-scheduled-job-runtime="getScheduledJobRuntime"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
:class="['platform-overview-card', { 'is-active': activePlatform === 'cloudtentacles' }]"
|
||||
@click="switchPlatform('cloudtentacles')"
|
||||
<el-tab-pane label="快手小店核销" name="kuaishouEticket">
|
||||
<AdminPlatformKuaishouEticketSection
|
||||
:kuaishou-eticket-file-path="kuaishouEticketFilePath"
|
||||
:kuaishou-eticket-shops="kuaishouEticketShops"
|
||||
:kuaishou-eticket-form="kuaishouEticketForm"
|
||||
:kuaishou-eticket-saving="kuaishouEticketSaving"
|
||||
:kuaishou-eticket-resolving-shop-id="kuaishouEticketResolvingShopId"
|
||||
:kuaishou-eticket-detailing="kuaishouEticketDetailing"
|
||||
:kuaishou-eticket-consuming="kuaishouEticketConsuming"
|
||||
:kuaishou-eticket-result-error="kuaishouEticketResultError"
|
||||
:kuaishou-eticket-shop-info-result="kuaishouEticketShopInfoResult"
|
||||
:kuaishou-eticket-detail-result="kuaishouEticketDetailResult"
|
||||
:kuaishou-eticket-consume-result="kuaishouEticketConsumeResult"
|
||||
:active-kuaishou-eticket-shop="activeKuaishouEticketShop"
|
||||
:kuaishou-eticket-stats="kuaishouEticketStats"
|
||||
:add-kuaishou-eticket-shop="addKuaishouEticketShop"
|
||||
:remove-kuaishou-eticket-shop="removeKuaishouEticketShop"
|
||||
:is-kuaishou-eticket-shop-expanded="isKuaishouEticketShopExpanded"
|
||||
:toggle-kuaishou-eticket-shop="toggleKuaishouEticketShop"
|
||||
:expand-all-kuaishou-eticket-shops="expandAllKuaishouEticketShops"
|
||||
:collapse-all-kuaishou-eticket-shops="collapseAllKuaishouEticketShops"
|
||||
:set-kuaishou-eticket-debug-shop="setKuaishouEticketDebugShop"
|
||||
:describe-kuaishou-eticket-shop="describeKuaishouEticketShop"
|
||||
:get-kuaishou-eticket-shop-initial="getKuaishouEticketShopInitial"
|
||||
:handle-kuaishou-eticket-resolve-shop-info="handleKuaishouEticketResolveShopInfo"
|
||||
:handle-kuaishou-eticket-save-source="handleKuaishouEticketSaveSource"
|
||||
:handle-kuaishou-eticket-query-detail="handleKuaishouEticketQueryDetail"
|
||||
:handle-kuaishou-eticket-consume="handleKuaishouEticketConsume"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="isDevMode"
|
||||
label="cloudtentacles 履约平台"
|
||||
name="cloudtentacles"
|
||||
>
|
||||
<div class="platform-head">
|
||||
<span class="platform-badge">cloudtentacles</span>
|
||||
<span class="platform-tag">履约 / 登录</span>
|
||||
</div>
|
||||
<strong>{{ cloudtentaclesStats.hasCredential ? '已配置' : '未配置' }}</strong>
|
||||
<span>履约凭据</span>
|
||||
<div class="platform-metrics">
|
||||
<span>短信 {{ cloudtentaclesStats.smsSent ? '已发送' : '未发送' }}</span>
|
||||
<span>会话 {{ cloudtentaclesStats.validated ? '已验证' : '未验证' }}</span>
|
||||
</div>
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section class="platform-switcher">
|
||||
<button
|
||||
type="button"
|
||||
:class="['switch-chip', { 'is-active': activePlatform === 'agiso' }]"
|
||||
@click="switchPlatform('agiso')"
|
||||
>
|
||||
Agiso 店铺与消息
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="['switch-chip', { 'is-active': activePlatform === 'ninetyone' }]"
|
||||
@click="switchPlatform('ninetyone')"
|
||||
>
|
||||
91卡券接入
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="['switch-chip', { 'is-active': activePlatform === 'notifications' }]"
|
||||
@click="switchPlatform('notifications')"
|
||||
>
|
||||
内部通知
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="['switch-chip', { 'is-active': activePlatform === 'kuaishouEticket' }]"
|
||||
@click="switchPlatform('kuaishouEticket')"
|
||||
>
|
||||
快手小店核销
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
:class="['switch-chip', { 'is-active': activePlatform === 'cloudtentacles' }]"
|
||||
@click="switchPlatform('cloudtentacles')"
|
||||
v-if="isDevMode"
|
||||
>
|
||||
cloudtentacles 履约平台
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<AdminPlatformAgisoSection
|
||||
v-if="activePlatform === 'agiso'"
|
||||
:agiso-file-path="agisoFilePath"
|
||||
:defaults="defaults"
|
||||
:shops="shops"
|
||||
:observed-shops="observedShops"
|
||||
:saving="saving"
|
||||
:is-shop-expanded="isShopExpanded"
|
||||
:toggle-shop="toggleShop"
|
||||
:expand-all-shops="expandAllShops"
|
||||
:collapse-all-shops="collapseAllShops"
|
||||
:describe-shop="describeShop"
|
||||
:remove-shop="removeShop"
|
||||
:import-observed-shop="importObservedShop"
|
||||
:save-agiso-configs="saveAgisoConfigs"
|
||||
/>
|
||||
|
||||
<AdminPlatformNinetyoneSection
|
||||
v-else-if="activePlatform === 'ninetyone'"
|
||||
:ninetyone-loading="ninetyoneLoading"
|
||||
:ninetyone-action-loading-id="ninetyoneActionLoadingId"
|
||||
:ninetyone-result-error="ninetyoneResultError"
|
||||
:ninetyone-status="ninetyoneStatus"
|
||||
:ninetyone-orders="ninetyoneOrders"
|
||||
:ninetyone-stats="ninetyoneStats"
|
||||
:load-ninetyone-orders="loadNinetyoneOrders"
|
||||
:handle-ninetyone-status-change="handleNinetyoneStatusChange"
|
||||
:handle-ninetyone-retry-order="handleNinetyoneRetryOrder"
|
||||
:handle-ninetyone-fail-order="handleNinetyoneFailOrder"
|
||||
/>
|
||||
|
||||
<AdminPlatformNotificationSection
|
||||
v-else-if="activePlatform === 'notifications'"
|
||||
:notification-file-path="notificationFilePath"
|
||||
:notification-form="notificationForm"
|
||||
:notification-recipients="notificationRecipients"
|
||||
:notification-saving="notificationSaving"
|
||||
:notification-testing="notificationTesting"
|
||||
:notification-result-error="notificationResultError"
|
||||
:notification-test-result="notificationTestResult"
|
||||
:scheduled-jobs-file-path="scheduledJobsFilePath"
|
||||
:scheduled-jobs-form="scheduledJobsForm"
|
||||
:scheduled-jobs="scheduledJobs"
|
||||
:scheduled-job-runtime="scheduledJobRuntime"
|
||||
:scheduled-jobs-saving="scheduledJobsSaving"
|
||||
:scheduled-job-running-id="scheduledJobRunningId"
|
||||
:notification-stats="notificationStats"
|
||||
:add-notification-recipient="addNotificationRecipient"
|
||||
:remove-notification-recipient="removeNotificationRecipient"
|
||||
:handle-notification-save-config="handleNotificationSaveConfig"
|
||||
:handle-notification-test="handleNotificationTest"
|
||||
:handle-scheduled-jobs-save-config="handleScheduledJobsSaveConfig"
|
||||
:handle-scheduled-job-run-now="handleScheduledJobRunNow"
|
||||
:get-scheduled-job-runtime="getScheduledJobRuntime"
|
||||
/>
|
||||
|
||||
<AdminPlatformKuaishouEticketSection
|
||||
v-else-if="activePlatform === 'kuaishouEticket'"
|
||||
:kuaishou-eticket-file-path="kuaishouEticketFilePath"
|
||||
:kuaishou-eticket-shops="kuaishouEticketShops"
|
||||
:kuaishou-eticket-form="kuaishouEticketForm"
|
||||
:kuaishou-eticket-saving="kuaishouEticketSaving"
|
||||
:kuaishou-eticket-resolving-shop-id="kuaishouEticketResolvingShopId"
|
||||
:kuaishou-eticket-detailing="kuaishouEticketDetailing"
|
||||
:kuaishou-eticket-consuming="kuaishouEticketConsuming"
|
||||
:kuaishou-eticket-result-error="kuaishouEticketResultError"
|
||||
:kuaishou-eticket-shop-info-result="kuaishouEticketShopInfoResult"
|
||||
:kuaishou-eticket-detail-result="kuaishouEticketDetailResult"
|
||||
:kuaishou-eticket-consume-result="kuaishouEticketConsumeResult"
|
||||
:active-kuaishou-eticket-shop="activeKuaishouEticketShop"
|
||||
:kuaishou-eticket-stats="kuaishouEticketStats"
|
||||
:add-kuaishou-eticket-shop="addKuaishouEticketShop"
|
||||
:remove-kuaishou-eticket-shop="removeKuaishouEticketShop"
|
||||
:is-kuaishou-eticket-shop-expanded="isKuaishouEticketShopExpanded"
|
||||
:toggle-kuaishou-eticket-shop="toggleKuaishouEticketShop"
|
||||
:expand-all-kuaishou-eticket-shops="expandAllKuaishouEticketShops"
|
||||
:collapse-all-kuaishou-eticket-shops="collapseAllKuaishouEticketShops"
|
||||
:set-kuaishou-eticket-debug-shop="setKuaishouEticketDebugShop"
|
||||
:describe-kuaishou-eticket-shop="describeKuaishouEticketShop"
|
||||
:get-kuaishou-eticket-shop-initial="getKuaishouEticketShopInitial"
|
||||
:handle-kuaishou-eticket-resolve-shop-info="handleKuaishouEticketResolveShopInfo"
|
||||
:handle-kuaishou-eticket-save-source="handleKuaishouEticketSaveSource"
|
||||
:handle-kuaishou-eticket-query-detail="handleKuaishouEticketQueryDetail"
|
||||
:handle-kuaishou-eticket-consume="handleKuaishouEticketConsume"
|
||||
/>
|
||||
|
||||
<AdminPlatformCloudtentaclesSection
|
||||
v-else-if="isDevMode"
|
||||
:cloudtentacles-file-path="cloudtentaclesFilePath"
|
||||
:cloudtentacles-session-file-path="cloudtentaclesSessionFilePath"
|
||||
:cloudtentacles-form="cloudtentaclesForm"
|
||||
:cloudtentacles-saving="cloudtentaclesSaving"
|
||||
:cloudtentacles-sending-sms="cloudtentaclesSendingSms"
|
||||
:cloudtentacles-testing="cloudtentaclesTesting"
|
||||
:cloudtentacles-validating="cloudtentaclesValidating"
|
||||
:cloudtentacles-result-error="cloudtentaclesResultError"
|
||||
:cloudtentacles-sms-result="cloudtentaclesSmsResult"
|
||||
:cloudtentacles-login-result="cloudtentaclesLoginResult"
|
||||
:cloudtentacles-validate-result="cloudtentaclesValidateResult"
|
||||
:cloudtentacles-debug-loading="cloudtentaclesDebugLoading"
|
||||
:cloudtentacles-debug-result="cloudtentaclesDebugResult"
|
||||
:cloudtentacles-persisted-session="cloudtentaclesPersistedSession"
|
||||
:cloudtentacles-stats="cloudtentaclesStats"
|
||||
:handle-cloudtentacles-save-source="handleCloudtentaclesSaveSource"
|
||||
:handle-cloudtentacles-send-sms-code="handleCloudtentaclesSendSmsCode"
|
||||
:handle-cloudtentacles-test-login="handleCloudtentaclesTestLogin"
|
||||
:handle-cloudtentacles-validate-session="handleCloudtentaclesValidateSession"
|
||||
:handle-cloudtentacles-fetch-asset="handleCloudtentaclesFetchAsset"
|
||||
:handle-cloudtentacles-fetch-categories="handleCloudtentaclesFetchCategories"
|
||||
:handle-cloudtentacles-fetch-sku-list="handleCloudtentaclesFetchSkuList"
|
||||
:handle-cloudtentacles-buy-sku="handleCloudtentaclesBuySku"
|
||||
:handle-cloudtentacles-use-sku="handleCloudtentaclesUseSku"
|
||||
:handle-cloudtentacles-fetch-knapsack="handleCloudtentaclesFetchKnapsack"
|
||||
:handle-cloudtentacles-fetch-vn-list="handleCloudtentaclesFetchVnList"
|
||||
:handle-cloudtentacles-appoint-vn="handleCloudtentaclesAppointVn"
|
||||
:handle-cloudtentacles-generate-vn-login-code="handleCloudtentaclesGenerateVnLoginCode"
|
||||
:handle-cloudtentacles-fetch-vn-code="handleCloudtentaclesFetchVnCode"
|
||||
:handle-cloudtentacles-verify-vn-code="handleCloudtentaclesVerifyVnCode"
|
||||
:handle-cloudtentacles-fetch-bind-url="handleCloudtentaclesFetchBindUrl"
|
||||
:handle-cloudtentacles-back-vn="handleCloudtentaclesBackVn"
|
||||
:handle-cloudtentacles-run-full-flow="handleCloudtentaclesRunFullFlow"
|
||||
/>
|
||||
<AdminPlatformCloudtentaclesSection
|
||||
:cloudtentacles-file-path="cloudtentaclesFilePath"
|
||||
:cloudtentacles-session-file-path="cloudtentaclesSessionFilePath"
|
||||
:cloudtentacles-form="cloudtentaclesForm"
|
||||
:cloudtentacles-saving="cloudtentaclesSaving"
|
||||
:cloudtentacles-sending-sms="cloudtentaclesSendingSms"
|
||||
:cloudtentacles-testing="cloudtentaclesTesting"
|
||||
:cloudtentacles-validating="cloudtentaclesValidating"
|
||||
:cloudtentacles-result-error="cloudtentaclesResultError"
|
||||
:cloudtentacles-sms-result="cloudtentaclesSmsResult"
|
||||
:cloudtentacles-login-result="cloudtentaclesLoginResult"
|
||||
:cloudtentacles-validate-result="cloudtentaclesValidateResult"
|
||||
:cloudtentacles-debug-loading="cloudtentaclesDebugLoading"
|
||||
:cloudtentacles-debug-result="cloudtentaclesDebugResult"
|
||||
:cloudtentacles-persisted-session="cloudtentaclesPersistedSession"
|
||||
:cloudtentacles-stats="cloudtentaclesStats"
|
||||
:handle-cloudtentacles-save-source="handleCloudtentaclesSaveSource"
|
||||
:handle-cloudtentacles-send-sms-code="handleCloudtentaclesSendSmsCode"
|
||||
:handle-cloudtentacles-test-login="handleCloudtentaclesTestLogin"
|
||||
:handle-cloudtentacles-validate-session="handleCloudtentaclesValidateSession"
|
||||
:handle-cloudtentacles-fetch-asset="handleCloudtentaclesFetchAsset"
|
||||
:handle-cloudtentacles-fetch-categories="handleCloudtentaclesFetchCategories"
|
||||
:handle-cloudtentacles-fetch-sku-list="handleCloudtentaclesFetchSkuList"
|
||||
:handle-cloudtentacles-buy-sku="handleCloudtentaclesBuySku"
|
||||
:handle-cloudtentacles-use-sku="handleCloudtentaclesUseSku"
|
||||
:handle-cloudtentacles-fetch-knapsack="handleCloudtentaclesFetchKnapsack"
|
||||
:handle-cloudtentacles-fetch-vn-list="handleCloudtentaclesFetchVnList"
|
||||
:handle-cloudtentacles-appoint-vn="handleCloudtentaclesAppointVn"
|
||||
:handle-cloudtentacles-generate-vn-login-code="handleCloudtentaclesGenerateVnLoginCode"
|
||||
:handle-cloudtentacles-fetch-vn-code="handleCloudtentaclesFetchVnCode"
|
||||
:handle-cloudtentacles-verify-vn-code="handleCloudtentaclesVerifyVnCode"
|
||||
:handle-cloudtentacles-fetch-bind-url="handleCloudtentaclesFetchBindUrl"
|
||||
:handle-cloudtentacles-back-vn="handleCloudtentaclesBackVn"
|
||||
:handle-cloudtentacles-run-full-flow="handleCloudtentaclesRunFullFlow"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</template>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.platform-page {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
/* 页面头部 */
|
||||
.page-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.page-header h1 {
|
||||
margin: 0;
|
||||
font-size: var(--text-3xl);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
margin: var(--space-2) 0 0;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 概览卡片网格 */
|
||||
.overview-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.overview-card {
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.overview-card.is-active {
|
||||
border-color: var(--border-hover);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.card-head {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
margin-bottom: var(--space-3);
|
||||
}
|
||||
|
||||
.card-value {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.card-unit {
|
||||
color: var(--text-muted);
|
||||
font-size: var(--text-sm);
|
||||
margin-top: var(--space-1);
|
||||
}
|
||||
|
||||
.card-meta {
|
||||
color: var(--text-secondary);
|
||||
font-size: var(--text-xs);
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
/* Tab 切换 */
|
||||
.platform-tabs {
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.page-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.overview-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.overview-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user