feat: 选择上游分组弹窗支持倍率范围(大于等于/小于等于)筛选
This commit is contained in:
@@ -309,13 +309,23 @@
|
|||||||
|
|
||||||
<!-- 选择上游分组弹窗 -->
|
<!-- 选择上游分组弹窗 -->
|
||||||
<el-dialog v-model="groupSelectVisible" title="选择上游分组" width="min(85vw, 1200px)" destroy-on-close class="group-select-dialog custom-theme-dialog">
|
<el-dialog v-model="groupSelectVisible" title="选择上游分组" width="min(85vw, 1200px)" destroy-on-close class="group-select-dialog custom-theme-dialog">
|
||||||
<!-- 搜索框 -->
|
<!-- 搜索和倍率筛选条 -->
|
||||||
<div class="dialog-search-bar" style="margin-bottom: 16px;">
|
<div class="dialog-filter-bar" style="margin-bottom: 16px;">
|
||||||
<el-input v-model="groupSearchQuery" placeholder="输入分组名称、分组 ID、倍率进行过滤..." clearable class="custom-theme-search">
|
<el-input v-model="groupSearchQuery" placeholder="输入分组名称、分组 ID..." clearable class="custom-theme-search keyword-search-input">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon><Search /></el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
<div class="rate-range-inputs">
|
||||||
|
<div class="rate-input-box">
|
||||||
|
<span class="rate-input-label">倍率 >=</span>
|
||||||
|
<input type="number" step="0.01" v-model.number="groupRateMin" placeholder="不限" class="rate-number-input" />
|
||||||
|
</div>
|
||||||
|
<div class="rate-input-box">
|
||||||
|
<span class="rate-input-label">倍率 <=</span>
|
||||||
|
<input type="number" step="0.01" v-model.number="groupRateMax" placeholder="不限" class="rate-number-input" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="group-selector-layout">
|
<div class="group-selector-layout">
|
||||||
@@ -1249,6 +1259,8 @@ async function saveBinding() {
|
|||||||
// 选择上游分组弹窗相关状态与方法
|
// 选择上游分组弹窗相关状态与方法
|
||||||
const groupSelectVisible = ref(false)
|
const groupSelectVisible = ref(false)
|
||||||
const groupSearchQuery = ref('')
|
const groupSearchQuery = ref('')
|
||||||
|
const groupRateMin = ref<number | null>(null)
|
||||||
|
const groupRateMax = ref<number | null>(null)
|
||||||
const selectedUpstreamId = ref<number | ''>('')
|
const selectedUpstreamId = ref<number | ''>('')
|
||||||
const tempSelectedKeys = ref<string[]>([])
|
const tempSelectedKeys = ref<string[]>([])
|
||||||
|
|
||||||
@@ -1256,6 +1268,8 @@ function openGroupSelectModal() {
|
|||||||
tempSelectedKeys.value = [...sourceGroupKeys.value]
|
tempSelectedKeys.value = [...sourceGroupKeys.value]
|
||||||
groupSearchQuery.value = ''
|
groupSearchQuery.value = ''
|
||||||
selectedUpstreamId.value = ''
|
selectedUpstreamId.value = ''
|
||||||
|
groupRateMin.value = null
|
||||||
|
groupRateMax.value = null
|
||||||
groupSelectVisible.value = true
|
groupSelectVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1285,15 +1299,36 @@ const upstreamCounts = computed(() => {
|
|||||||
const filteredGroupsForModal = computed(() => {
|
const filteredGroupsForModal = computed(() => {
|
||||||
const query = groupSearchQuery.value.trim().toLowerCase()
|
const query = groupSearchQuery.value.trim().toLowerCase()
|
||||||
return upstreamGroupOptions.value.filter(item => {
|
return upstreamGroupOptions.value.filter(item => {
|
||||||
|
// 1. 上游站点过滤
|
||||||
if (selectedUpstreamId.value !== '' && item.source.upstream_id !== selectedUpstreamId.value) {
|
if (selectedUpstreamId.value !== '' && item.source.upstream_id !== selectedUpstreamId.value) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 关键词过滤:只匹配 group_name、group_id
|
||||||
if (query) {
|
if (query) {
|
||||||
const matchGroupName = item.source.group_name.toLowerCase().includes(query)
|
const matchGroupName = item.source.group_name.toLowerCase().includes(query)
|
||||||
const matchGroupId = String(item.source.group_id).toLowerCase().includes(query)
|
const matchGroupId = String(item.source.group_id).toLowerCase().includes(query)
|
||||||
const matchRate = String(item.rate).toLowerCase().includes(query)
|
if (!matchGroupName && !matchGroupId) {
|
||||||
return matchGroupName || matchGroupId || matchRate
|
return false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 倍率范围过滤
|
||||||
|
const min = groupRateMin.value
|
||||||
|
const max = groupRateMax.value
|
||||||
|
if (min !== null || max !== null) {
|
||||||
|
const rateVal = parseFloat(String(item.rate))
|
||||||
|
if (isNaN(rateVal)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (min !== null && rateVal < min) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (max !== null && rateVal > max) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -2337,8 +2372,87 @@ onMounted(loadAll)
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Combination Search and Filter Bar */
|
||||||
|
.dialog-filter-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.keyword-search-input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-range-inputs {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-input-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #160c0a;
|
||||||
|
border: 1px solid #3e2821;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0 10px;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-input-label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #a68d85;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-number-input {
|
||||||
|
width: 80px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: #f5ecea;
|
||||||
|
outline: none;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-number-input::placeholder {
|
||||||
|
color: rgba(166, 141, 133, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-number-input::-webkit-inner-spin-button,
|
||||||
|
.rate-number-input::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Responsive dialog styling */
|
/* Responsive dialog styling */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
.dialog-filter-bar {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-range-inputs {
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-input-box {
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rate-number-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.group-selector-layout {
|
.group-selector-layout {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
Reference in New Issue
Block a user