You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
673 lines
22 KiB
673 lines
22 KiB
<template>
|
|
<el-dialog
|
|
title="编辑航线"
|
|
:visible.sync="visible"
|
|
width="560px"
|
|
:close-on-click-modal="false"
|
|
append-to-body
|
|
custom-class="blue-dialog route-edit-dialog"
|
|
>
|
|
<div class="route-edit-tab-bar">
|
|
<button type="button" class="tab-bar-item" :class="{ active: activeTab === 'basic' }" @click="activeTab = 'basic'">基础</button>
|
|
<button type="button" class="tab-bar-item" :class="{ active: activeTab === 'platform' }" @click="activeTab = 'platform'">平台</button>
|
|
</div>
|
|
<div v-show="activeTab === 'basic'" class="tab-pane-wrap">
|
|
<div class="tab-pane-body basic-tab-content">
|
|
<el-form :model="form" label-width="88px" size="small" class="route-edit-form style-form" @submit.native.prevent>
|
|
<div class="form-section">
|
|
<div class="form-section-label">基本信息</div>
|
|
<el-form-item label="航线名称">
|
|
<el-input v-model="form.name" placeholder="请输入航线名称" clearable />
|
|
</el-form-item>
|
|
</div>
|
|
<div class="form-section">
|
|
<div class="form-section-label">航点样式</div>
|
|
<div class="form-row two-col">
|
|
<el-form-item label="大小" class="col-item">
|
|
<el-input-number v-model="styleForm.waypoint.pixelSize" :min="4" :max="20" :step="1" size="small" controls-position="right" style="width: 100%" />
|
|
</el-form-item>
|
|
<el-form-item label="边框粗细" class="col-item">
|
|
<el-input-number v-model="styleForm.waypoint.outlineWidth" :min="1" :max="5" :step="1" size="small" controls-position="right" style="width: 100%" />
|
|
</el-form-item>
|
|
</div>
|
|
<div class="form-row two-col">
|
|
<el-form-item label="填充颜色" class="col-item">
|
|
<div class="color-picker-wrap">
|
|
<el-color-picker v-model="styleForm.waypoint.color" size="small" :predefine="presetColors" />
|
|
<span class="color-value">{{ styleForm.waypoint.color }}</span>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item label="边框颜色" class="col-item">
|
|
<div class="color-picker-wrap">
|
|
<el-color-picker v-model="styleForm.waypoint.outlineColor" size="small" :predefine="presetColors" />
|
|
<span class="color-value">{{ styleForm.waypoint.outlineColor }}</span>
|
|
</div>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
<div class="form-section">
|
|
<div class="form-section-label">航线样式</div>
|
|
<div class="form-row two-col">
|
|
<el-form-item label="线段样式" class="col-item">
|
|
<el-select v-model="styleForm.line.style" placeholder="请选择" style="width: 100%">
|
|
<el-option label="实线" value="solid" />
|
|
<el-option label="虚线" value="dash" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="线宽" class="col-item">
|
|
<el-input-number v-model="styleForm.line.width" :min="2" :max="12" :step="1" size="small" controls-position="right" style="width: 100%" />
|
|
</el-form-item>
|
|
</div>
|
|
<div class="form-row two-col">
|
|
<el-form-item label="线条颜色" class="col-item">
|
|
<div class="color-picker-wrap">
|
|
<el-color-picker v-model="styleForm.line.color" size="small" :predefine="presetColors" />
|
|
<span class="color-value">{{ styleForm.line.color }}</span>
|
|
</div>
|
|
</el-form-item>
|
|
<el-form-item v-if="styleForm.line.style === 'dash'" label="间隔颜色" class="col-item">
|
|
<div class="color-picker-wrap">
|
|
<el-color-picker v-model="styleForm.line.gapColor" size="small" :predefine="presetColors" />
|
|
<span class="color-value">{{ styleForm.line.gapColor }}</span>
|
|
</div>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
<div v-show="activeTab === 'platform'" class="tab-pane-wrap">
|
|
<div class="tab-pane-body platform-tab-content">
|
|
<div v-if="platformLoading" class="platform-loading">加载中...</div>
|
|
<template v-else>
|
|
<div class="platform-segmented">
|
|
<button
|
|
type="button"
|
|
class="seg-item"
|
|
:class="{ active: platformCategory === 'Air' }"
|
|
@click="platformCategory = 'Air'"
|
|
>
|
|
<i class="seg-icon seg-icon-air"></i>
|
|
<span>空中</span>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="seg-item"
|
|
:class="{ active: platformCategory === 'Sea' }"
|
|
@click="platformCategory = 'Sea'"
|
|
>
|
|
<i class="seg-icon seg-icon-sea"></i>
|
|
<span>海上</span>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="seg-item"
|
|
:class="{ active: platformCategory === 'Ground' }"
|
|
@click="platformCategory = 'Ground'"
|
|
>
|
|
<i class="seg-icon seg-icon-ground"></i>
|
|
<span>地面</span>
|
|
</button>
|
|
</div>
|
|
<div v-show="platformCategory === 'Air'" class="platform-list">
|
|
<div
|
|
v-for="platform in airPlatforms"
|
|
:key="platform.id"
|
|
class="platform-card"
|
|
>
|
|
<div class="platform-card-icon">
|
|
<img v-if="isImg(platform.imageUrl)" :src="formatImg(platform.imageUrl)" class="platform-img" alt="" />
|
|
<i v-else class="card-icon-placeholder el-icon-s-promotion"></i>
|
|
</div>
|
|
<div class="platform-card-info">
|
|
<div class="platform-card-name">{{ platform.name }}</div>
|
|
<div class="platform-card-desc">{{ platformTypeLabel(platform.type) }}</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
class="platform-card-btn"
|
|
:class="{ selected: selectedPlatformId === platform.id }"
|
|
@click="selectPlatform(platform)"
|
|
>
|
|
<i :class="selectedPlatformId === platform.id ? 'el-icon-check' : 'el-icon-plus'"></i>
|
|
{{ selectedPlatformId === platform.id ? '已选择' : '选择' }}
|
|
</button>
|
|
</div>
|
|
<div v-if="airPlatforms.length === 0" class="empty-tip">暂无空中平台</div>
|
|
</div>
|
|
<div v-show="platformCategory === 'Sea'" class="platform-list">
|
|
<div
|
|
v-for="platform in seaPlatforms"
|
|
:key="platform.id"
|
|
class="platform-card"
|
|
>
|
|
<div class="platform-card-icon">
|
|
<img v-if="isImg(platform.imageUrl)" :src="formatImg(platform.imageUrl)" class="platform-img" alt="" />
|
|
<i v-else class="card-icon-placeholder el-icon-s-flag"></i>
|
|
</div>
|
|
<div class="platform-card-info">
|
|
<div class="platform-card-name">{{ platform.name }}</div>
|
|
<div class="platform-card-desc">{{ platformTypeLabel(platform.type) }}</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
class="platform-card-btn"
|
|
:class="{ selected: selectedPlatformId === platform.id }"
|
|
@click="selectPlatform(platform)"
|
|
>
|
|
<i :class="selectedPlatformId === platform.id ? 'el-icon-check' : 'el-icon-plus'"></i>
|
|
{{ selectedPlatformId === platform.id ? '已选择' : '选择' }}
|
|
</button>
|
|
</div>
|
|
<div v-if="seaPlatforms.length === 0" class="empty-tip">暂无海上平台</div>
|
|
</div>
|
|
<div v-show="platformCategory === 'Ground'" class="platform-list">
|
|
<div
|
|
v-for="platform in groundPlatforms"
|
|
:key="platform.id"
|
|
class="platform-card"
|
|
>
|
|
<div class="platform-card-icon">
|
|
<img v-if="isImg(platform.imageUrl)" :src="formatImg(platform.imageUrl)" class="platform-img" alt="" />
|
|
<i v-else class="card-icon-placeholder el-icon-van"></i>
|
|
</div>
|
|
<div class="platform-card-info">
|
|
<div class="platform-card-name">{{ platform.name }}</div>
|
|
<div class="platform-card-desc">{{ platformTypeLabel(platform.type) }}</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
class="platform-card-btn"
|
|
:class="{ selected: selectedPlatformId === platform.id }"
|
|
@click="selectPlatform(platform)"
|
|
>
|
|
<i :class="selectedPlatformId === platform.id ? 'el-icon-check' : 'el-icon-plus'"></i>
|
|
{{ selectedPlatformId === platform.id ? '已选择' : '选择' }}
|
|
</button>
|
|
</div>
|
|
<div v-if="groundPlatforms.length === 0" class="empty-tip">暂无地面平台</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<span slot="footer" class="dialog-footer">
|
|
<el-button size="mini" @click="visible = false">取 消</el-button>
|
|
<el-button type="primary" size="mini" class="blue-btn" @click="handleSave">确 定</el-button>
|
|
</span>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script>
|
|
import { listLib } from '@/api/system/lib'
|
|
|
|
export default {
|
|
name: 'RouteEditDialog',
|
|
props: {
|
|
value: { type: Boolean, default: false },
|
|
route: { type: Object, default: () => ({}) }
|
|
},
|
|
data() {
|
|
return {
|
|
activeTab: 'basic',
|
|
platformCategory: 'Air',
|
|
platformLoading: false,
|
|
airPlatforms: [],
|
|
seaPlatforms: [],
|
|
groundPlatforms: [],
|
|
selectedPlatformId: null,
|
|
selectedPlatform: null,
|
|
form: {
|
|
id: '',
|
|
name: ''
|
|
},
|
|
// 与地图默认、新建航线入库一致:紫色实线线宽3;仅当 attributes 为空时用于表单回退
|
|
defaultStyle: {
|
|
waypoint: { pixelSize: 7, color: '#ffffff', outlineColor: '#0078FF', outlineWidth: 2 },
|
|
line: { style: 'solid', width: 3, color: '#800080', gapColor: '#000000', dashLength: 20 }
|
|
},
|
|
styleForm: {
|
|
waypoint: { pixelSize: 7, color: '#ffffff', outlineColor: '#0078FF', outlineWidth: 2 },
|
|
line: { style: 'solid', width: 3, color: '#800080', gapColor: '#000000', dashLength: 20 }
|
|
},
|
|
presetColors: [
|
|
'#ffffff', '#000000', '#0078FF', '#409EFF', '#67C23A', '#E6A23C', '#F56C6C',
|
|
'#909399', '#303133', '#00CED1', '#FF1493', '#FFD700', '#4B0082', '#00FF00', '#FF4500'
|
|
]
|
|
}
|
|
},
|
|
computed: {
|
|
visible: {
|
|
get() { return this.value },
|
|
set(val) { this.$emit('input', val) }
|
|
}
|
|
},
|
|
watch: {
|
|
route: {
|
|
handler(val) {
|
|
if (val) {
|
|
this.form = {
|
|
id: val.id,
|
|
name: val.name,
|
|
attributes: val.attributes != null ? val.attributes : ''
|
|
}
|
|
this.selectedPlatformId = val.platformId || null
|
|
this.selectedPlatform = val.platform ? { ...val.platform } : null
|
|
this.parseStyleFromRoute(val)
|
|
}
|
|
},
|
|
immediate: true,
|
|
deep: true
|
|
},
|
|
visible(val) {
|
|
if (val && this.activeTab === 'platform') {
|
|
this.loadPlatforms()
|
|
}
|
|
},
|
|
activeTab(val) {
|
|
if (val === 'platform' && this.visible) {
|
|
this.loadPlatforms()
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
loadPlatforms() {
|
|
this.platformLoading = true
|
|
listLib().then(res => {
|
|
const allData = res.rows || []
|
|
this.airPlatforms = []
|
|
this.seaPlatforms = []
|
|
this.groundPlatforms = []
|
|
allData.forEach(item => {
|
|
const platform = {
|
|
id: item.id,
|
|
name: item.name,
|
|
type: item.type,
|
|
imageUrl: item.iconUrl || '',
|
|
icon: item.iconUrl ? '' : 'el-icon-picture-outline'
|
|
}
|
|
if (item.type === 'Air') this.airPlatforms.push(platform)
|
|
else if (item.type === 'Sea') this.seaPlatforms.push(platform)
|
|
else if (item.type === 'Ground') this.groundPlatforms.push(platform)
|
|
})
|
|
}).catch(() => {
|
|
this.$message.error('加载平台列表失败')
|
|
}).finally(() => {
|
|
this.platformLoading = false
|
|
})
|
|
},
|
|
isImg(path) {
|
|
if (!path) return false
|
|
return path.includes('/') || path.includes('data:image')
|
|
},
|
|
formatImg(url) {
|
|
if (!url) return ''
|
|
const cleanPath = url.replace(/\/+/g, '/')
|
|
const backendUrl = process.env.VUE_APP_BACKEND_URL || ''
|
|
return backendUrl + cleanPath
|
|
},
|
|
platformTypeLabel(type) {
|
|
const map = { Air: '空中平台', Sea: '海上平台', Ground: '地面平台' }
|
|
return map[type] || type || ''
|
|
},
|
|
selectPlatform(platform) {
|
|
this.selectedPlatformId = platform.id
|
|
this.selectedPlatform = { id: platform.id, name: platform.name, imageUrl: platform.imageUrl }
|
|
},
|
|
parseStyleFromRoute(route) {
|
|
const def = this.defaultStyle
|
|
try {
|
|
const attrs = typeof route.attributes === 'string' ? JSON.parse(route.attributes || '{}') : (route.attributes || {})
|
|
const wp = attrs.waypointStyle || {}
|
|
const ln = attrs.lineStyle || {}
|
|
this.styleForm = {
|
|
waypoint: {
|
|
pixelSize: wp.pixelSize != null ? wp.pixelSize : def.waypoint.pixelSize,
|
|
color: wp.color || def.waypoint.color,
|
|
outlineColor: wp.outlineColor || def.waypoint.outlineColor,
|
|
outlineWidth: wp.outlineWidth != null ? wp.outlineWidth : def.waypoint.outlineWidth
|
|
},
|
|
line: {
|
|
style: ln.style || def.line.style,
|
|
width: ln.width != null ? ln.width : def.line.width,
|
|
color: ln.color || def.line.color,
|
|
gapColor: ln.gapColor != null ? ln.gapColor : def.line.gapColor,
|
|
dashLength: ln.dashLength != null ? ln.dashLength : def.line.dashLength
|
|
}
|
|
}
|
|
} catch (_) {
|
|
this.styleForm = {
|
|
waypoint: { ...def.waypoint },
|
|
line: { ...def.line }
|
|
}
|
|
}
|
|
},
|
|
getAttributesForSave() {
|
|
const attrs = {}
|
|
try {
|
|
const existing = typeof this.form.attributes === 'string' ? JSON.parse(this.form.attributes || '{}') : (this.form.attributes || {})
|
|
Object.assign(attrs, existing)
|
|
} catch (_) {}
|
|
attrs.waypointStyle = { ...this.styleForm.waypoint }
|
|
attrs.lineStyle = { ...this.styleForm.line }
|
|
return JSON.stringify(attrs)
|
|
},
|
|
handleSave() {
|
|
const payload = {
|
|
...this.form,
|
|
attributes: this.getAttributesForSave(),
|
|
platformId: this.selectedPlatformId,
|
|
platform: this.selectedPlatform,
|
|
routeStyle: {
|
|
waypoint: { ...this.styleForm.waypoint },
|
|
line: { ...this.styleForm.line }
|
|
}
|
|
}
|
|
this.$emit('save', payload)
|
|
this.visible = false
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
/* 航线编辑标题:加粗加黑 */
|
|
.route-edit-dialog .el-dialog__title { font-weight: 700; color: #303133; }
|
|
.route-edit-dialog .el-dialog__header { padding: 14px 20px 12px; }
|
|
/* 弹窗固定于视口正中间,不随页面滚动 */
|
|
.route-edit-dialog.el-dialog {
|
|
position: fixed !important;
|
|
top: 50% !important;
|
|
left: 50% !important;
|
|
margin: 0 !important;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
/* 弹窗内容区固定高度,切换基础/平台时大小不变 */
|
|
.route-edit-dialog .el-dialog__body {
|
|
padding-top: 12px;
|
|
height: 420px;
|
|
min-height: 420px;
|
|
overflow: hidden;
|
|
box-sizing: border-box;
|
|
}
|
|
</style>
|
|
<style scoped>
|
|
.route-edit-tab-bar {
|
|
display: flex;
|
|
gap: 24px;
|
|
margin-bottom: 0;
|
|
padding-bottom: 12px;
|
|
border-bottom: 1px solid #e4e7ed;
|
|
}
|
|
.tab-bar-item {
|
|
padding: 0;
|
|
border: none;
|
|
background: none;
|
|
font-size: 14px;
|
|
color: #909399;
|
|
cursor: pointer;
|
|
position: relative;
|
|
padding-bottom: 12px;
|
|
margin-bottom: -12px;
|
|
outline: none;
|
|
}
|
|
.tab-bar-item:hover {
|
|
color: #606266;
|
|
}
|
|
.tab-bar-item.active {
|
|
color: #165dff;
|
|
font-weight: 500;
|
|
}
|
|
.tab-bar-item.active::after {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
height: 2px;
|
|
background: #165dff;
|
|
}
|
|
.tab-pane-wrap {
|
|
padding-top: 4px;
|
|
height: 384px;
|
|
min-height: 384px;
|
|
overflow: hidden;
|
|
box-sizing: border-box;
|
|
}
|
|
.tab-pane-body {
|
|
height: 380px;
|
|
min-height: 380px;
|
|
max-height: 380px;
|
|
box-sizing: border-box;
|
|
}
|
|
.basic-tab-content {
|
|
padding: 0 16px;
|
|
height: 380px;
|
|
overflow-y: auto;
|
|
box-sizing: border-box;
|
|
}
|
|
/* 基础页区块:与平台卡片同风格,白底 + 柔和阴影,左右留白可展示阴影 */
|
|
.form-section {
|
|
background: #fff;
|
|
border-radius: 8px;
|
|
padding: 12px 14px;
|
|
margin-bottom: 14px;
|
|
border: none;
|
|
box-shadow:
|
|
0 1px 3px rgba(0, 0, 0, 0.04),
|
|
0 4px 12px rgba(0, 0, 0, 0.05);
|
|
transition: box-shadow 0.25s ease;
|
|
}
|
|
.form-section:hover {
|
|
box-shadow:
|
|
0 2px 8px rgba(0, 0, 0, 0.06),
|
|
0 8px 20px rgba(0, 0, 0, 0.06);
|
|
}
|
|
.form-section:last-of-type {
|
|
margin-bottom: 0;
|
|
}
|
|
.form-section-label {
|
|
font-size: 13px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
margin-bottom: 10px;
|
|
padding-left: 2px;
|
|
}
|
|
.basic-tab-content .form-row {
|
|
display: flex;
|
|
gap: 16px;
|
|
margin-bottom: 0;
|
|
}
|
|
.basic-tab-content .form-row.two-col .col-item {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
.basic-tab-content .form-row .el-form-item {
|
|
margin-bottom: 14px;
|
|
}
|
|
.basic-tab-content .form-row.two-col .el-form-item {
|
|
margin-bottom: 14px;
|
|
}
|
|
.basic-tab-content .form-section .el-form-item:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
.color-picker-wrap {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
.route-edit-form .color-value {
|
|
font-size: 12px;
|
|
color: #909399;
|
|
vertical-align: middle;
|
|
}
|
|
.route-edit-form .el-slider {
|
|
margin-right: 12px;
|
|
}
|
|
|
|
/* 平台页:分段选择(样图风格 - 独立圆角矩形,与上方基础/平台有间距) */
|
|
.platform-tab-content {
|
|
min-height: 380px;
|
|
max-height: 380px;
|
|
overflow-y: auto;
|
|
background: #fff;
|
|
padding: 0 16px;
|
|
}
|
|
.platform-segmented {
|
|
display: inline-flex;
|
|
gap: 8px;
|
|
margin-top: 16px;
|
|
margin-bottom: 16px;
|
|
}
|
|
.seg-item {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
padding: 5px 22px;
|
|
border: 1px solid #e4e7ed;
|
|
border-radius: 20px;
|
|
font-size: 13px;
|
|
color: #606266;
|
|
background: #f5f5f5;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
.seg-item:hover {
|
|
border-color: #dcdfe6;
|
|
color: #303133;
|
|
}
|
|
.seg-item.active {
|
|
background: #165dff;
|
|
border-color: #165dff;
|
|
color: #fff;
|
|
font-weight: 500;
|
|
}
|
|
.seg-icon {
|
|
width: 18px;
|
|
height: 18px;
|
|
display: inline-block;
|
|
background-size: contain;
|
|
background-repeat: no-repeat;
|
|
background-position: center;
|
|
opacity: 0.9;
|
|
}
|
|
.seg-item.active .seg-icon {
|
|
opacity: 1;
|
|
filter: brightness(0) invert(1);
|
|
}
|
|
.seg-icon-air {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23606266'%3E%3Cpath d='M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z'/%3E%3C/svg%3E");
|
|
}
|
|
.seg-icon-sea {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23606266'%3E%3Cpath d='M20 21c-1.39 0-2.78-.47-4-1.32-2.44 1.71-5.56 1.71-8 0C6.78 20.53 5.39 21 4 21H2v2h2c1.38 0 2.74-.35 4-.99 2.52 1.29 5.48 1.29 8 0 1.26.65 2.62.99 4 .99h2v-2h-2zM3.95 19H4c1.6 0 3.02-.88 4-2 .98 1.12 2.4 2 4 2h.05l1.89-6.68c.08-.26.06-.54-.06-.78-.12-.24-.32-.42-.57-.5L20 10.62V6c0-1.1-.9-2-2-2h-3V1H9v3H6c-1.1 0-2 .9-2 2v4.62l-1.29.42c-.25.08-.45.26-.57.5-.12.24-.14.52-.06.78L3.95 19zM6 6h12v3.97L12 8 6 9.97V6z'/%3E%3C/svg%3E");
|
|
}
|
|
.seg-icon-ground {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23606266'%3E%3Cpath d='M20 8h-3V4H3c-1.1 0-2 .9-2 2v11h2c0 1.66 1.34 3 3 3s3-1.34 3-3h6c0 1.66 1.34 3 3 3s3-1.34 3-3h2v-5l-3-4zM6 18.5c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5zm13.5-9l1.96 2.5H17V9.5h2.5zm-1.5 9c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z'/%3E%3C/svg%3E");
|
|
}
|
|
|
|
/* 平台卡片列表(与页面同背景色 + 阴影框) */
|
|
.platform-loading,
|
|
.empty-tip {
|
|
padding: 20px;
|
|
color: #909399;
|
|
text-align: center;
|
|
font-size: 13px;
|
|
}
|
|
.platform-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
/* 平台卡片:无硬边框,用柔和阴影做过渡,不死板(参考右侧样图) */
|
|
.platform-card {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 12px 14px;
|
|
background: #fff;
|
|
border-radius: 8px;
|
|
border: none;
|
|
box-shadow:
|
|
0 1px 3px rgba(0, 0, 0, 0.04),
|
|
0 4px 12px rgba(0, 0, 0, 0.05);
|
|
transition: box-shadow 0.25s ease;
|
|
}
|
|
.platform-card:hover {
|
|
box-shadow:
|
|
0 2px 8px rgba(0, 0, 0, 0.06),
|
|
0 8px 20px rgba(0, 0, 0, 0.06);
|
|
}
|
|
.platform-card-icon {
|
|
width: 44px;
|
|
height: 44px;
|
|
min-width: 44px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 12px;
|
|
background: #e0f0ff;
|
|
border-radius: 50%;
|
|
}
|
|
.platform-card-icon .platform-img {
|
|
width: 28px;
|
|
height: 28px;
|
|
object-fit: contain;
|
|
}
|
|
.platform-card-icon .card-icon-placeholder {
|
|
font-size: 22px;
|
|
color: #165dff;
|
|
}
|
|
.platform-card-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
.platform-card-name {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
color: #303133;
|
|
margin-bottom: 2px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.platform-card-desc {
|
|
font-size: 12px;
|
|
color: #909399;
|
|
}
|
|
/* 选择按钮:样图风格圆角矩形(胶囊形) */
|
|
.platform-card-btn {
|
|
flex-shrink: 0;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 6px 16px;
|
|
border-radius: 20px;
|
|
font-size: 13px;
|
|
border: 1px solid #dcdfe6;
|
|
background: #fff;
|
|
color: #606266;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
.platform-card-btn:hover {
|
|
border-color: #165dff;
|
|
color: #165dff;
|
|
}
|
|
.platform-card-btn.selected {
|
|
background: #165dff;
|
|
border-color: #165dff;
|
|
color: #fff;
|
|
}
|
|
.platform-card-btn i {
|
|
font-size: 12px;
|
|
}
|
|
|
|
.blue-btn {
|
|
background: #165dff;
|
|
border-color: #165dff;
|
|
}
|
|
.blue-btn:hover {
|
|
background: #165dff;
|
|
border-color: #165dff;
|
|
}
|
|
</style>
|
|
|