wip(strategy-map): V1+V3 合版 + v2/v3 口径(完备度/C1 hold/57 归档组)
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<div class="map-editbar">
|
||||
<div class="eb-left">
|
||||
<el-input
|
||||
:model-value="search"
|
||||
class="eb-search"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="搜索目标 / 负责人 / KPI"
|
||||
@update:model-value="(v: string) => $emit('update:search', v)"
|
||||
>
|
||||
<template #prefix>
|
||||
<svg class="eb-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
|
||||
<circle cx="11" cy="11" r="7" /><path d="M20 20l-3.5-3.5" />
|
||||
</svg>
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<div class="eb-chips" role="group" aria-label="状态筛选">
|
||||
<button
|
||||
v-for="opt in filterOptions"
|
||||
:key="opt.value"
|
||||
type="button"
|
||||
class="eb-chip"
|
||||
:class="{ on: filter === opt.value }"
|
||||
@click="$emit('update:filter', opt.value)"
|
||||
>{{ opt.label }}</button>
|
||||
</div>
|
||||
|
||||
<div class="eb-chips eb-layers" role="group" aria-label="层筛选">
|
||||
<button
|
||||
v-for="cfg in layerConfigs"
|
||||
:key="cfg.key"
|
||||
type="button"
|
||||
class="eb-chip layer-chip"
|
||||
:class="{ off: !visibleLayers[cfg.key] }"
|
||||
:title="visibleLayers[cfg.key] ? '隐藏该层' : '显示该层'"
|
||||
@click="$emit('toggle-layer', cfg.key)"
|
||||
>
|
||||
<span class="layer-dot" :style="{ background: cfg.color }"></span>
|
||||
{{ cfg.short }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="eb-right">
|
||||
<el-dropdown trigger="click" @command="onAdd">
|
||||
<el-button size="small" type="primary" plain>
|
||||
<svg class="eb-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M12 5v14M5 12h14" />
|
||||
</svg>
|
||||
加目标
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="cfg in layerConfigs" :key="cfg.key" :command="cfg.key">
|
||||
<span class="dd-dot" :style="{ background: cfg.color }"></span>{{ cfg.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
<el-button size="small" @click="$emit('connect')">
|
||||
<svg class="eb-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
|
||||
<path d="M10 13a5 5 0 0 0 7 0l2-2a5 5 0 0 0-7-7l-1 1" />
|
||||
<path d="M14 11a5 5 0 0 0-7 0l-2 2a5 5 0 0 0 7 7l1-1" />
|
||||
</svg>
|
||||
连因果
|
||||
</el-button>
|
||||
|
||||
<el-button size="small" :disabled="!canUndo" @click="$emit('undo')" title="撤销上一步画布编辑">
|
||||
<svg class="eb-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
|
||||
<path d="M9 14L4 9l5-5" /><path d="M4 9h10a6 6 0 0 1 0 12h-3" />
|
||||
</svg>
|
||||
撤销
|
||||
</el-button>
|
||||
|
||||
<el-button size="small" @click="$emit('completeness')" title="数据完备度与清单(口径:地图65·23KPI判据)">
|
||||
<svg class="eb-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
|
||||
<path d="M4 19V5" /><path d="M4 19h16" /><rect x="7" y="11" width="3" height="6" rx=".5" />
|
||||
<rect x="12" y="7" width="3" height="10" rx=".5" /><rect x="17" y="13" width="3" height="4" rx=".5" />
|
||||
</svg>
|
||||
数据完备度
|
||||
</el-button>
|
||||
|
||||
<el-button size="small" @click="$emit('fit')" title="缩放到适合窗口">
|
||||
<svg class="eb-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true">
|
||||
<path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5" />
|
||||
</svg>
|
||||
回全景
|
||||
</el-button>
|
||||
|
||||
<el-button size="small" text @click="$emit('toggle-tree')">
|
||||
{{ treeOpen ? '收起目标树' : '展开目标树' }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
search: string
|
||||
filter: 'all' | 'risk' | 'nodata'
|
||||
visibleLayers: Record<string, boolean>
|
||||
layerConfigs: { key: string; label: string; short: string; color: string }[]
|
||||
canUndo: boolean
|
||||
treeOpen: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:search', v: string): void
|
||||
(e: 'update:filter', v: 'all' | 'risk' | 'nodata'): void
|
||||
(e: 'toggle-layer', key: string): void
|
||||
(e: 'add-objective', key: string): void
|
||||
(e: 'connect'): void
|
||||
(e: 'undo'): void
|
||||
(e: 'fit'): void
|
||||
(e: 'toggle-tree'): void
|
||||
(e: 'completeness'): void
|
||||
}>()
|
||||
|
||||
const filterOptions: { value: 'all' | 'risk' | 'nodata'; label: string }[] = [
|
||||
{ value: 'all', label: '全部' },
|
||||
{ value: 'risk', label: '只看风险' },
|
||||
{ value: 'nodata', label: '只看无数据' },
|
||||
]
|
||||
|
||||
function onAdd(key: string) {
|
||||
emit('add-objective', key)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.map-editbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
flex-shrink: 0;
|
||||
padding: 8px 10px;
|
||||
margin-bottom: 10px;
|
||||
background: var(--bh-bg-card, #fff);
|
||||
border: 1px solid var(--bh-border, #E5E7EB);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.eb-left, .eb-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.eb-search { width: 220px; }
|
||||
.eb-ico { width: 14px; height: 14px; vertical-align: -2px; }
|
||||
.eb-chips { display: inline-flex; align-items: center; gap: 4px; padding: 2px; background: #F6F7F9; border: 1px solid #E5E7EB; border-radius: 6px; }
|
||||
.eb-chip {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #475569;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
transition: background .15s, color .15s;
|
||||
}
|
||||
.eb-chip:hover { color: #635BFF; }
|
||||
.eb-chip.on { background: #635BFF; color: #fff; }
|
||||
.eb-chip.off { color: #94A3B8; text-decoration: line-through; }
|
||||
.layer-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }
|
||||
.dd-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 6px; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user