/* 平台管理视图 */ const ProvidersView = { template: `
🏢 平台 = 资产的服务商(Vultr / 新网 / OpenAI…)。在「资产」中添加项目时选择归属平台;支持 API 对接的平台配置好密钥后,可「测试连接」或「同步资产」拉取真实数据。
{{ p.name }}
{{ p.slug }}
{{ Fmt.SERVICES_LABELS[s] || s }}
{{ Fmt.CATEGORY_LABELS[p.category] }}
API 对接: {{ p.sdk_type }}
管理面板 ↗
📎 关联 {{ countOf(p) }} 个资产 已配置 API 未配置 API {{ p.enabled ? '启用' : '停用' }}
最后同步:{{ fmtTime(p.last_synced_at) }}
{{ results[p.id].text }}
`, setup() { const testing = Vue.reactive({}); const syncing = Vue.reactive({}); const results = Vue.reactive({}); const supported = Vue.ref([]); const capabilities = Vue.ref({}); // 平台关联资产数:优先按 provider_id 归并,其次按资产里填的平台名/slug const assetCounts = Vue.computed(() => { const m = {}; for (const a of store.assets) { if (a.provider_id) m['id:' + a.provider_id] = (m['id:' + a.provider_id] || 0) + 1; else if (a.provider) m['p:' + a.provider] = (m['p:' + a.provider] || 0) + 1; } return m; }); function countOf(p) { return (assetCounts.value['id:' + p.id] || 0) + (assetCounts.value['p:' + p.slug] || 0) + (assetCounts.value['p:' + p.name] || 0); } function serviceList(p) { return (p.services || '').split(',').map(s => s.trim()).filter(Boolean); } Vue.onMounted(async () => { try { const r = await Api.get('/providers/adapters'); supported.value = r.supported_types || []; capabilities.value = r.capabilities || {}; } catch (e) { /* ignore */ } }); function isSupported(t) { return !!t && supported.value.includes(t); } function canSync(t) { const c = capabilities.value[t]; return !!(c && (c.list_vps || c.list_domains)); } function fmtTime(iso) { if (!iso) return ''; return new Date(iso).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } async function test(p) { testing[p.id] = true; delete results[p.id]; try { const r = await Api.post('/providers/' + p.id + '/test', {}); results[p.id] = { ok: r.ok, text: (r.ok ? '✓ ' : '✗ ') + r.message }; } catch (e) { results[p.id] = { ok: false, text: '✗ ' + e.message }; } finally { testing[p.id] = false; } } async function sync(p) { syncing[p.id] = true; delete results[p.id]; try { const r = await Api.post('/providers/' + p.id + '/sync', {}); const parts = []; if (r.vps) parts.push('VPS 新增' + r.vps.created + '/更新' + r.vps.updated); if (r.domains) parts.push('域名 新增' + r.domains.created + '/更新' + r.domains.updated); if (r.vps_error) parts.push('VPS错误:' + r.vps_error); if (r.domains_error) parts.push('域名错误:' + r.domains_error); if (r.account && r.account.balance !== null && r.account.balance !== undefined) parts.push('余额 ' + r.account.balance); results[p.id] = { ok: true, text: '✓ 同步完成:' + (parts.join(',') || '无变化') }; await loadAll(); } catch (e) { results[p.id] = { ok: false, text: '✗ ' + e.message }; } finally { syncing[p.id] = false; } } return { store, Fmt, testing, syncing, results, countOf, serviceList, isSupported, canSync, fmtTime, test, sync, seed: seedProviders, create: openProviderCreate, edit: openProviderEdit, del: deleteProvider }; }, };