2026-02-06 03:34:50 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="resource-topology-demo">
|
|
|
|
|
|
<div class="controls">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<el-radio-group
|
|
|
|
|
|
v-model="viewMode"
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-radio-button label="overview">
|
|
|
|
|
|
全景视图
|
|
|
|
|
|
</el-radio-button>
|
|
|
|
|
|
<el-radio-button label="compute">
|
|
|
|
|
|
计算视角
|
|
|
|
|
|
</el-radio-button>
|
|
|
|
|
|
<el-radio-button label="network">
|
|
|
|
|
|
网络视角
|
|
|
|
|
|
</el-radio-button>
|
|
|
|
|
|
<el-radio-button label="storage">
|
|
|
|
|
|
存储视角
|
|
|
|
|
|
</el-radio-button>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</el-radio-group>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
ref="topologyRef"
|
|
|
|
|
|
class="topology-container"
|
|
|
|
|
|
>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<!-- 云服务商层 -->
|
|
|
|
|
|
<div class="layer cloud-provider">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div class="layer-title">
|
|
|
|
|
|
☁️ 云服务商
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="provider-grid">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-for="provider in providers"
|
|
|
|
|
|
:key="provider.name"
|
|
|
|
|
|
class="provider-card"
|
|
|
|
|
|
:class="{ active: selectedProvider === provider.name }"
|
|
|
|
|
|
@click="selectProvider(provider.name)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="provider-icon">
|
|
|
|
|
|
{{ provider.icon }}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="provider-name">
|
|
|
|
|
|
{{ provider.name }}
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 连接箭头 -->
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div class="connection-arrow">
|
|
|
|
|
|
⬇️
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 地域/可用区层 -->
|
|
|
|
|
|
<div class="layer region-layer">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div class="layer-title">
|
|
|
|
|
|
🌍 地域 & 可用区
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="region-grid">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-for="region in regions"
|
|
|
|
|
|
:key="region.id"
|
|
|
|
|
|
class="region-card"
|
|
|
|
|
|
:class="{ active: selectedRegion === region.id }"
|
|
|
|
|
|
@click="selectRegion(region.id)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="region-name">
|
|
|
|
|
|
{{ region.name }}
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="region-azs">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<span
|
|
|
|
|
|
v-for="az in region.azs"
|
|
|
|
|
|
:key="az"
|
|
|
|
|
|
class="az-badge"
|
|
|
|
|
|
>{{ az }}</span>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 连接箭头 -->
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div class="connection-arrow">
|
|
|
|
|
|
⬇️
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 资源拓扑层 -->
|
|
|
|
|
|
<div class="layer resource-layer">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div class="layer-title">
|
|
|
|
|
|
🎯 资源拓扑
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="resource-grid">
|
|
|
|
|
|
<!-- 计算资源 -->
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="resource-category"
|
|
|
|
|
|
:class="{ highlight: viewMode === 'compute' || viewMode === 'overview' }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="category-title">
|
|
|
|
|
|
💻 计算
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="resource-list">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-for="item in computeResources"
|
|
|
|
|
|
:key="item.name"
|
|
|
|
|
|
class="resource-item"
|
|
|
|
|
|
>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<span class="resource-icon">{{ item.icon }}</span>
|
|
|
|
|
|
<span class="resource-name">{{ item.name }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 网络资源 -->
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="resource-category"
|
|
|
|
|
|
:class="{ highlight: viewMode === 'network' || viewMode === 'overview' }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="category-title">
|
|
|
|
|
|
🌐 网络
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="resource-list">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-for="item in networkResources"
|
|
|
|
|
|
:key="item.name"
|
|
|
|
|
|
class="resource-item"
|
|
|
|
|
|
>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<span class="resource-icon">{{ item.icon }}</span>
|
|
|
|
|
|
<span class="resource-name">{{ item.name }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 存储资源 -->
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
class="resource-category"
|
|
|
|
|
|
:class="{ highlight: viewMode === 'storage' || viewMode === 'overview' }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="category-title">
|
|
|
|
|
|
💾 存储
|
|
|
|
|
|
</div>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="resource-list">
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-for="item in storageResources"
|
|
|
|
|
|
:key="item.name"
|
|
|
|
|
|
class="resource-item"
|
|
|
|
|
|
>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<span class="resource-icon">{{ item.icon }}</span>
|
|
|
|
|
|
<span class="resource-name">{{ item.name }}</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 信息面板 -->
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<div
|
|
|
|
|
|
v-if="showInfo"
|
|
|
|
|
|
class="info-panel"
|
|
|
|
|
|
>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
<div class="info-header">
|
|
|
|
|
|
<h4>💡 拓扑说明</h4>
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<el-button
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
@click="showInfo = false"
|
|
|
|
|
|
>
|
|
|
|
|
|
关闭
|
|
|
|
|
|
</el-button>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-content">
|
|
|
|
|
|
<p><strong>当前视图:</strong>{{ viewModeText }}</p>
|
|
|
|
|
|
<p><strong>选中云商:</strong>{{ selectedProvider || '未选择' }}</p>
|
|
|
|
|
|
<p><strong>选中地域:</strong>{{ selectedRegion || '未选择' }}</p>
|
2026-02-18 17:38:10 +08:00
|
|
|
|
<p class="tip">
|
|
|
|
|
|
💡 提示:点击云服务商和地域可以查看不同组合的资源拓扑
|
|
|
|
|
|
</p>
|
2026-02-06 03:34:50 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref, computed } from 'vue'
|
|
|
|
|
|
|
|
|
|
|
|
const viewMode = ref('overview')
|
|
|
|
|
|
const selectedProvider = ref('阿里云')
|
|
|
|
|
|
const selectedRegion = ref('cn-beijing')
|
|
|
|
|
|
const showInfo = ref(true)
|
|
|
|
|
|
|
|
|
|
|
|
const providers = [
|
|
|
|
|
|
{ name: '阿里云', icon: '☁️' },
|
|
|
|
|
|
{ name: '腾讯云', icon: '🌟' },
|
|
|
|
|
|
{ name: '华为云', icon: '🔥' },
|
|
|
|
|
|
{ name: 'AWS', icon: '📦' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const regions = [
|
|
|
|
|
|
{ id: 'cn-beijing', name: '华北2 (北京)', azs: ['A', 'B', 'C', 'D', 'E'] },
|
|
|
|
|
|
{ id: 'cn-shanghai', name: '华东2 (上海)', azs: ['A', 'B', 'C', 'D', 'E', 'F'] },
|
|
|
|
|
|
{ id: 'cn-shenzhen', name: '华南1 (深圳)', azs: ['A', 'B', 'C', 'D'] },
|
|
|
|
|
|
{ id: 'cn-hangzhou', name: '华东1 (杭州)', azs: ['A', 'B', 'C', 'D', 'E', 'F', 'G'] }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const computeResources = [
|
|
|
|
|
|
{ name: '云服务器 ECS', icon: '🖥️' },
|
|
|
|
|
|
{ name: '容器服务 K8s', icon: '📦' },
|
|
|
|
|
|
{ name: '函数计算 FC', icon: '⚡' },
|
|
|
|
|
|
{ name: '裸金属服务器', icon: '🔧' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const networkResources = [
|
|
|
|
|
|
{ name: '专有网络 VPC', icon: '🕸️' },
|
|
|
|
|
|
{ name: '负载均衡 SLB', icon: '⚖️' },
|
|
|
|
|
|
{ name: '弹性公网 IP', icon: '🌍' },
|
|
|
|
|
|
{ name: 'VPN 网关', icon: '🔒' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const storageResources = [
|
|
|
|
|
|
{ name: '对象存储 OSS', icon: '🪣' },
|
|
|
|
|
|
{ name: '块存储 EBS', icon: '💽' },
|
|
|
|
|
|
{ name: '文件存储 NAS', icon: '📁' },
|
|
|
|
|
|
{ name: '日志服务 SLS', icon: '📋' }
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
const viewModeText = computed(() => {
|
|
|
|
|
|
const map = {
|
|
|
|
|
|
overview: '全景视图 - 查看完整资源拓扑',
|
|
|
|
|
|
compute: '计算视角 - 聚焦计算资源',
|
|
|
|
|
|
network: '网络视角 - 聚焦网络资源',
|
|
|
|
|
|
storage: '存储视角 - 聚焦存储资源'
|
|
|
|
|
|
}
|
|
|
|
|
|
return map[viewMode.value]
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
const selectProvider = (name) => {
|
|
|
|
|
|
selectedProvider.value = name
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const selectRegion = (id) => {
|
|
|
|
|
|
selectedRegion.value = id
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.resource-topology-demo {
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background: #f5f7fa;
|
2026-02-14 20:23:34 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.controls {
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.topology-container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.layer {
|
|
|
|
|
|
background: white;
|
|
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.layer-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #303133;
|
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
|
padding-bottom: 8px;
|
|
|
|
|
|
border-bottom: 2px solid #e4e7ed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.connection-arrow {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 24px;
|
|
|
|
|
|
color: #909399;
|
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Provider Grid */
|
|
|
|
|
|
.provider-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.provider-card {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
border: 2px solid #e4e7ed;
|
2026-02-14 20:23:34 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.provider-card:hover {
|
|
|
|
|
|
border-color: #409eff;
|
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.provider-card.active {
|
|
|
|
|
|
border-color: #409eff;
|
|
|
|
|
|
background: #ecf5ff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.provider-icon {
|
|
|
|
|
|
font-size: 32px;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.provider-name {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Region Grid */
|
|
|
|
|
|
.region-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
|
|
|
|
|
gap: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.region-card {
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
border: 2px solid #e4e7ed;
|
2026-02-14 20:23:34 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.region-card:hover {
|
|
|
|
|
|
border-color: #67c23a;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.region-card.active {
|
|
|
|
|
|
border-color: #67c23a;
|
|
|
|
|
|
background: #f0f9eb;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.region-name {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #303133;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.region-azs {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
gap: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.az-badge {
|
|
|
|
|
|
padding: 2px 6px;
|
|
|
|
|
|
background: #e4e7ed;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.region-card.active .az-badge {
|
|
|
|
|
|
background: #67c23a;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Resource Grid */
|
|
|
|
|
|
.resource-grid {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
|
gap: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-category {
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
border: 2px solid #e4e7ed;
|
2026-02-14 20:23:34 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
transition: all 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-category.highlight {
|
|
|
|
|
|
border-color: #409eff;
|
|
|
|
|
|
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.category-title {
|
|
|
|
|
|
font-size: 15px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #303133;
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
padding-bottom: 8px;
|
|
|
|
|
|
border-bottom: 1px solid #e4e7ed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-list {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-item {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
padding: 8px;
|
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-item:hover {
|
|
|
|
|
|
background: #ecf5ff;
|
|
|
|
|
|
transform: translateX(4px);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-icon {
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-name {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Info Panel */
|
|
|
|
|
|
.info-panel {
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
background: #f0f9eb;
|
2026-02-14 20:23:34 +08:00
|
|
|
|
border-radius: 6px;
|
2026-02-06 03:34:50 +08:00
|
|
|
|
border-left: 4px solid #67c23a;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-header h4 {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
color: #67c23a;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-content p {
|
|
|
|
|
|
margin: 8px 0;
|
|
|
|
|
|
color: #606266;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-content .tip {
|
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
|
padding-top: 12px;
|
|
|
|
|
|
border-top: 1px dashed #dcdfe6;
|
|
|
|
|
|
color: #909399;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
|
.provider-grid,
|
|
|
|
|
|
.region-grid {
|
|
|
|
|
|
grid-template-columns: repeat(2, 1fr);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.resource-grid {
|
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|