feat(steady): 实现台账指标树默认选中及图标展示功能
- 添加findFirstSelectableLedgerNode和findFirstLeafIndicator工具函数 - 实现台账树首次加载后默认选中第一个可查询监测点 - 实现指标树首次加载后默认选中第一个叶子指标 - 添加台账层级图标展示及样式配置 - 集成defaultCheckedKeys属性到台账和指标树组件 - 更新趋势查询参数移除bucket字段 - 修复数据质量标识默认值设置问题
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
:key="selectorResetKey"
|
||||
:tree-data="treeData"
|
||||
:loading="loading"
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
@refresh="emit('refresh')"
|
||||
@change="emit('change', $event)"
|
||||
/>
|
||||
@@ -39,6 +40,7 @@ defineProps<{
|
||||
collapsed: boolean
|
||||
treeData: SteadyDataView.SteadyIndicatorNode[]
|
||||
loading: boolean
|
||||
defaultCheckedKeys: string[]
|
||||
selectorResetKey: number
|
||||
}>()
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
node-key="treeKey"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:expand-on-click-node="false"
|
||||
:props="{ label: 'name', children: 'children' }"
|
||||
@check="handleCheck"
|
||||
@@ -29,7 +30,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import type { TreeInstance } from 'element-plus'
|
||||
import type { SteadyDataView } from '@/api/steady/steadyDataView/interface'
|
||||
@@ -42,6 +43,7 @@ defineOptions({
|
||||
const props = defineProps<{
|
||||
treeData: SteadyDataView.SteadyIndicatorNode[]
|
||||
loading: boolean
|
||||
defaultCheckedKeys: string[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -70,6 +72,19 @@ const handleCheck = () => {
|
||||
const checkedNodes = (treeRef.value?.getCheckedNodes(false, false) || []) as SteadyDataView.SteadyIndicatorNode[]
|
||||
emit('change', collectLeafIndicators(checkedNodes))
|
||||
}
|
||||
|
||||
const applyDefaultCheckedKeys = async () => {
|
||||
await nextTick()
|
||||
treeRef.value?.setCheckedKeys(props.defaultCheckedKeys, false)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [normalizedTreeData.value, props.defaultCheckedKeys],
|
||||
() => {
|
||||
applyDefaultCheckedKeys()
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -20,13 +20,19 @@
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
default-expand-all
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:expand-on-click-node="false"
|
||||
:props="{ label: 'name', children: 'children' }"
|
||||
@check="handleCheck"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<div class="tree-node">
|
||||
<span class="node-name">{{ data.name }}</span>
|
||||
<span class="node-main">
|
||||
<el-icon :class="['node-icon', `is-level-${normalizeLedgerLevel(data.level)}`]">
|
||||
<component :is="resolveLedgerIcon(data.level)" />
|
||||
</el-icon>
|
||||
<span class="node-name">{{ data.name }}</span>
|
||||
</span>
|
||||
<span class="node-count">
|
||||
<template v-if="Number(data.deviceCount) || Number(data.lineCount)">
|
||||
{{ Number(data.deviceCount || 0) }} / {{ Number(data.lineCount || 0) }}
|
||||
@@ -40,8 +46,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import { nextTick, ref, watch } from 'vue'
|
||||
import type { Component } from 'vue'
|
||||
import { Folder, Location, Monitor, OfficeBuilding, Refresh } from '@element-plus/icons-vue'
|
||||
import type { TreeInstance } from 'element-plus'
|
||||
import type { SteadyDataView } from '@/api/steady/steadyDataView/interface'
|
||||
|
||||
@@ -49,10 +56,11 @@ defineOptions({
|
||||
name: 'SteadyLedgerTree'
|
||||
})
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
treeData: SteadyDataView.SteadyLedgerNode[]
|
||||
loading: boolean
|
||||
keyword: string
|
||||
defaultCheckedKeys: string[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -62,6 +70,26 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const treeRef = ref<TreeInstance>()
|
||||
type LedgerLevel = SteadyDataView.SteadyLedgerNode['level']
|
||||
const ledgerIcons: Record<LedgerLevel, Component> = {
|
||||
0: OfficeBuilding,
|
||||
1: Folder,
|
||||
2: Monitor,
|
||||
3: Location
|
||||
}
|
||||
|
||||
const normalizeLedgerLevel = (value: unknown): LedgerLevel => {
|
||||
const level = Number(value)
|
||||
if (level === 0 || level === 1 || level === 2 || level === 3) {
|
||||
return level
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
const resolveLedgerIcon = (value: unknown) => {
|
||||
return ledgerIcons[normalizeLedgerLevel(value)]
|
||||
}
|
||||
|
||||
const handleKeywordChange = (value: string) => {
|
||||
emit('search', value)
|
||||
@@ -70,6 +98,19 @@ const handleKeywordChange = (value: string) => {
|
||||
const handleCheck = () => {
|
||||
emit('change', (treeRef.value?.getCheckedNodes(false, false) || []) as SteadyDataView.SteadyLedgerNode[])
|
||||
}
|
||||
|
||||
const applyDefaultCheckedKeys = async () => {
|
||||
await nextTick()
|
||||
treeRef.value?.setCheckedKeys(props.defaultCheckedKeys, false)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [props.treeData, props.defaultCheckedKeys],
|
||||
() => {
|
||||
applyDefaultCheckedKeys()
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -105,6 +146,35 @@ const handleCheck = () => {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.node-main {
|
||||
display: inline-flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.node-icon {
|
||||
flex: none;
|
||||
font-size: 15px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.node-icon.is-level-0 {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.node-icon.is-level-1 {
|
||||
color: var(--el-color-success);
|
||||
}
|
||||
|
||||
.node-icon.is-level-2 {
|
||||
color: var(--el-color-warning);
|
||||
}
|
||||
|
||||
.node-icon.is-level-3 {
|
||||
color: var(--el-color-info);
|
||||
}
|
||||
|
||||
.node-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@@ -25,17 +25,6 @@
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-field">
|
||||
<span class="toolbar-field__label">粒度:</span>
|
||||
<el-select
|
||||
:model-value="modelValue.bucket"
|
||||
placeholder="选择时间粒度"
|
||||
@update:model-value="updateField('bucket', $event)"
|
||||
>
|
||||
<el-option v-for="item in bucketOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-field">
|
||||
<span class="toolbar-field__label">数据:</span>
|
||||
<el-select
|
||||
@@ -44,8 +33,8 @@
|
||||
placeholder="选择数据质量"
|
||||
@update:model-value="updateField('qualityFlag', $event)"
|
||||
>
|
||||
<el-option label="仅有效数据" :value="1" />
|
||||
<el-option label="仅无效数据" :value="0" />
|
||||
<el-option label="仅有效数据" :value="0" />
|
||||
<el-option label="仅无效数据" :value="1" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
@@ -93,13 +82,6 @@ const emit = defineEmits<{
|
||||
reset: []
|
||||
}>()
|
||||
|
||||
const bucketOptions = [
|
||||
{ label: '1分钟', value: '1m' },
|
||||
{ label: '5分钟', value: '5m' },
|
||||
{ label: '10分钟', value: '10m' },
|
||||
{ label: '30分钟', value: '30m' },
|
||||
{ label: '1小时', value: '1h' }
|
||||
]
|
||||
const harmonicOrderOptions = Array.from({ length: 49 }, (_item, index) => index + 2)
|
||||
const statLabelMap: Record<SteadyDataView.SteadyTrendStatType, string> = {
|
||||
AVG: '平均值',
|
||||
@@ -136,7 +118,7 @@ const handleTimeBaseDateChange = (value: Date) => {
|
||||
<style scoped lang="scss">
|
||||
.trend-toolbar {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(312px, 1.4fr) repeat(3, minmax(178px, 0.8fr)) auto;
|
||||
grid-template-columns: minmax(312px, 1.4fr) repeat(2, minmax(178px, 0.8fr)) auto;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
:tree-data="ledgerTree"
|
||||
:loading="loading.ledger"
|
||||
:keyword="ledgerKeyword"
|
||||
:default-checked-keys="defaultLedgerCheckedKeys"
|
||||
@refresh="emit('refreshLedger')"
|
||||
@search="emit('ledgerSearch', $event)"
|
||||
@change="emit('ledgerChange', $event)"
|
||||
@@ -30,6 +31,7 @@
|
||||
:selector-reset-key="selectorResetKey"
|
||||
:tree-data="indicatorTree"
|
||||
:loading="loading.indicator"
|
||||
:default-checked-keys="defaultIndicatorCheckedKeys"
|
||||
@refresh="emit('refreshIndicator')"
|
||||
@change="emit('indicatorChange', $event)"
|
||||
/>
|
||||
@@ -63,6 +65,8 @@ const props = defineProps<{
|
||||
trend: boolean
|
||||
}
|
||||
ledgerKeyword: string
|
||||
defaultLedgerCheckedKeys: string[]
|
||||
defaultIndicatorCheckedKeys: string[]
|
||||
indicatorPanelCollapsed: boolean
|
||||
selectorResetKey: number
|
||||
}>()
|
||||
|
||||
Reference in New Issue
Block a user