refactor(ui): 账号改为平台→账号→资产三层交互(平台卡片入口+展开看名下资产,移除平铺账号区)

This commit is contained in:
gouki
2026-08-08 22:16:14 +00:00
parent 1c93ac00eb
commit fcb3153c50
5 changed files with 101 additions and 29 deletions
+7 -28
View File
@@ -9,28 +9,7 @@ const ProvidersView = {
<div class="flex gap-2">
<button @click="seed" class="text-sm px-3 py-1.5 rounded-lg border border-slate-300 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800">初始化预设平台</button>
<button @click="create" class="text-sm px-3 py-1.5 rounded-lg bg-blue-600 text-white hover:bg-blue-700">+ 自定义平台</button>
<button @click="addAccount" class="text-sm px-3 py-1.5 rounded-lg border border-blue-300 dark:border-blue-700 text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20">+ 账号</button>
</div>
<!-- 账号管理:同一平台多账号时区分资产归属,资产表单「所属账号」引用此处 -->
<div class="bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 p-4">
<div class="flex justify-between items-center mb-2">
<h3 class="font-semibold text-sm">👤 我的账号({{ store.accounts.length }}</h3>
<button @click="addAccount" class="text-xs text-blue-600 dark:text-blue-400">+ 新增账号</button>
</div>
<p v-if="!store.accounts.length" class="text-xs text-slate-400">暂无账号。添加后,可在资产表单「所属账号」中快速选择,区分同一平台下的多个账号。</p>
<div v-else class="divide-y divide-slate-100 dark:divide-slate-800">
<div v-for="a in store.accounts" :key="a.id" class="py-2 flex items-center gap-2">
<div class="flex-1 min-w-0">
<div class="text-sm truncate">{{ a.remark || a.name }}
<span v-if="a.platform" class="text-xs text-slate-400">@ {{ platformName(a.platform) }}</span>
</div>
<div class="text-xs text-slate-400 truncate"><span v-if="a.remark">{{ a.name }} · </span>关联 {{ a.asset_count }} 个资产</div>
</div>
<button @click="editAccount(a)" class="text-xs text-blue-600 dark:text-blue-400">编辑</button>
<button @click="delAccount(a)" class="text-xs text-red-600 dark:text-red-400">删除</button>
</div>
</div>
<button @click="manageAccounts" class="text-sm px-3 py-1.5 rounded-lg border border-blue-300 dark:border-blue-700 text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20">👤 账号管理</button>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
<div v-for="p in store.providers" :key="p.id" class="bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 p-4">
@@ -49,6 +28,7 @@ const ProvidersView = {
<div v-if="p.console_url"><a :href="p.console_url" target="_blank" class="text-blue-600 dark:text-blue-400 hover:underline">管理面板 ↗</a></div>
<div class="flex items-center gap-2 mt-1">
<span class="text-slate-500">📎 关联 {{ countOf(p) }} 个资产</span>
<button @click="openAccounts(p)" class="text-slate-500 hover:text-blue-600 dark:hover:text-blue-400">👤 账号 {{ accountsCountOf(p) }}</button>
<span v-if="p.has_api_config" class="text-emerald-600 dark:text-emerald-400">已配置 API</span>
<span v-else class="text-slate-400">未配置 API</span>
<span :class="p.enabled ? 'text-emerald-600 dark:text-emerald-400' : 'text-slate-400'">{{ p.enabled ? '启用' : '停用' }}</span>
@@ -83,14 +63,13 @@ const ProvidersView = {
function countOf(p) {
return (assetCounts.value['id:' + p.id] || 0) + (assetCounts.value['p:' + p.slug] || 0) + (assetCounts.value['p:' + p.name] || 0);
}
// 平台名下账号数(账号按 platform slug 归属平台)
function accountsCountOf(p) {
return store.accounts.filter(a => a.platform === p.slug).length;
}
function serviceList(p) {
return (p.services || '').split(',').map(s => s.trim()).filter(Boolean);
}
// 账号所属平台显示名:platform 存的是 slug,回退显示原值
function platformName(slug) {
const p = store.providers.find(x => x.slug === slug);
return p ? p.name : slug;
}
Vue.onMounted(async () => {
try { const r = await Api.get('/providers/adapters'); supported.value = r.supported_types || []; capabilities.value = r.capabilities || {}; } catch (e) { /* ignore */ }
});
@@ -123,6 +102,6 @@ const ProvidersView = {
} catch (e) { results[p.id] = { ok: false, text: '✗ ' + e.message }; }
finally { syncing[p.id] = false; }
}
return { store, Fmt, testing, syncing, results, countOf, serviceList, platformName, isSupported, canSync, fmtTime, test, sync, seed: seedProviders, create: openProviderCreate, edit: openProviderEdit, del: deleteProvider, addAccount: () => openAccountCreate(''), editAccount: openAccountEdit, delAccount: deleteAccount };
return { store, Fmt, testing, syncing, results, countOf, accountsCountOf, serviceList, isSupported, canSync, fmtTime, test, sync, seed: seedProviders, create: openProviderCreate, edit: openProviderEdit, del: deleteProvider, openAccounts: (p) => openAccountsView(p.slug), manageAccounts: () => openAccountsView(null) };
},
};