Skip to content

Commit 348aa47

Browse files
committed
fix: normalize search site selection
1 parent 6e6819a commit 348aa47

1 file changed

Lines changed: 41 additions & 22 deletions

File tree

src/components/dialog/SearchSiteDialog.vue

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const props = defineProps({
1010
type: Array as PropType<Site[]>,
1111
required: true,
1212
},
13-
selected: Array as PropType<Number[]>,
13+
selected: Array as PropType<number[]>,
1414
})
1515
1616
// 定义事件
@@ -20,38 +20,66 @@ const emit = defineEmits(['close', 'search', 'reload'])
2020
const siteFilter = ref('')
2121
2222
// 已选择站点
23-
const selectedSites = ref<any[]>(props.selected || [])
23+
const selectedSites = ref<number[]>([])
2424
25-
watch(
26-
() => props.selected,
27-
value => {
28-
if (selectedSites.value.length == 0 && value) {
29-
selectedSites.value = value
25+
// 根据当前可用站点清理选中项,避免停用或已删除站点参与计数。
26+
function normalizeSelectedSites(selectedSiteIds: number[] = []) {
27+
const availableSiteIds = new Set(props.sites.map((site: Site) => site.id))
28+
const normalizedSiteIds: number[] = []
29+
30+
selectedSiteIds.forEach(siteId => {
31+
if (availableSiteIds.has(siteId) && !normalizedSiteIds.includes(siteId)) {
32+
normalizedSiteIds.push(siteId)
3033
}
34+
})
35+
36+
return normalizedSiteIds
37+
}
38+
39+
watch(
40+
[() => props.selected, () => props.sites],
41+
([value]) => {
42+
selectedSites.value = normalizeSelectedSites(value || [])
3143
},
44+
{ immediate: true },
3245
)
3346
3447
// 全选/全不选按钮文字
3548
const checkAllText = computed(() => {
36-
return selectedSites.value.length < props.sites?.length
49+
return selectedSites.value.length < props.sites.length
3750
? t('dialog.searchSite.selectAll')
3851
: t('dialog.searchSite.deselectAll')
3952
})
4053
4154
// 全选/全不选
4255
const checkAllSitesorNot = () => {
43-
if (selectedSites.value.length < props.sites?.length) {
44-
selectedSites.value = props.sites?.map((item: Site) => item.id)
56+
if (selectedSites.value.length < props.sites.length) {
57+
selectedSites.value = props.sites.map((item: Site) => item.id)
4558
} else {
4659
selectedSites.value = []
4760
}
4861
}
4962
63+
// 切换单个站点的选择状态。
64+
function toggleSiteSelection(siteId: number) {
65+
const index = selectedSites.value.indexOf(siteId)
66+
if (index === -1) {
67+
selectedSites.value.push(siteId)
68+
} else {
69+
selectedSites.value.splice(index, 1)
70+
}
71+
}
72+
73+
// 确认搜索时只提交当前可用站点。
74+
function confirmSearch() {
75+
emit('search', normalizeSelectedSites(selectedSites.value))
76+
}
77+
5078
// 根据筛选条件过滤站点
5179
const filteredSites = computed(() => {
5280
if (!siteFilter.value) return props.sites
5381
const filter = siteFilter.value.toLowerCase()
54-
return props.sites?.filter((site: Site) => site.name.toLowerCase().includes(filter))
82+
return props.sites.filter((site: Site) => site.name.toLowerCase().includes(filter))
5583
})
5684
</script>
5785
<template>
@@ -107,16 +135,7 @@ const filteredSites = computed(() => {
107135
'site-hover': isHovering && !selectedSites.includes(site.id),
108136
},
109137
]"
110-
@click="
111-
() => {
112-
const index = selectedSites.indexOf(site.id)
113-
if (index === -1) {
114-
selectedSites.push(site.id)
115-
} else {
116-
selectedSites.splice(index, 1)
117-
}
118-
}
119-
"
138+
@click="toggleSiteSelection(site.id)"
120139
>
121140
<VIcon
122141
:icon="selectedSites.includes(site.id) ? 'mdi-check-circle' : 'mdi-checkbox-blank-circle-outline'"
@@ -161,7 +180,7 @@ const filteredSites = computed(() => {
161180
<VBtn
162181
color="primary"
163182
:disabled="selectedSites.length === 0"
164-
@click="emit('search', selectedSites)"
183+
@click="confirmSearch"
165184
prepend-icon="mdi-magnify"
166185
class="d-flex align-center justify-center px-5"
167186
>

0 commit comments

Comments
 (0)